forked from minetest-mods/global_exchange
Cancel remaining buy order when out of funds.
This commit is contained in:
parent
808b3cbf04
commit
141de27c97
197
exchange.lua
197
exchange.lua
@ -861,6 +861,8 @@ function ex_methods.buy(self, p_name, ex_name, item_name, wear, amount, rate)
|
|||||||
|
|
||||||
local bought = {}
|
local bought = {}
|
||||||
local remaining = amount
|
local remaining = amount
|
||||||
|
local out_of_funds = false
|
||||||
|
local last_row_rate = rate
|
||||||
|
|
||||||
local del_stmt = self.stmts.del_order_stmt
|
local del_stmt = self.stmts.del_order_stmt
|
||||||
local red_stmt = self.stmts.reduce_order_stmt
|
local red_stmt = self.stmts.reduce_order_stmt
|
||||||
@ -882,6 +884,8 @@ function ex_methods.buy(self, p_name, ex_name, item_name, wear, amount, rate)
|
|||||||
|
|
||||||
if poster ~= p_name then
|
if poster ~= p_name then
|
||||||
local can_afford = math.floor(balance / row_rate)
|
local can_afford = math.floor(balance / row_rate)
|
||||||
|
last_row_rate = row_rate
|
||||||
|
out_of_funds = row_bought < can_afford
|
||||||
row_bought = math.min(row_bought, can_afford)
|
row_bought = math.min(row_bought, can_afford)
|
||||||
-- asking prices can only increase from here
|
-- asking prices can only increase from here
|
||||||
if row_bought == 0 then break end
|
if row_bought == 0 then break end
|
||||||
@ -933,7 +937,7 @@ function ex_methods.buy(self, p_name, ex_name, item_name, wear, amount, rate)
|
|||||||
balance = balance - cost
|
balance = balance - cost
|
||||||
|
|
||||||
local log_succ, log_err =
|
local log_succ, log_err =
|
||||||
self:log(p_name .. " bought " .. row_amount .. " " ..
|
self:log(p_name .. " bought " .. row_bought .. " " ..
|
||||||
item_name .. " from you. (+" .. cost .. ")",
|
item_name .. " from you. (+" .. cost .. ")",
|
||||||
poster)
|
poster)
|
||||||
if not log_succ then
|
if not log_succ then
|
||||||
@ -943,7 +947,7 @@ function ex_methods.buy(self, p_name, ex_name, item_name, wear, amount, rate)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local log_succ, log_err =
|
local log_succ, log_err =
|
||||||
self:log("Bought " .. row_amount .. " " .. item_name ..
|
self:log("Bought " .. row_bought .. " " .. item_name ..
|
||||||
" from " .. poster .. ". (-" .. cost .. ")",
|
" from " .. poster .. ". (-" .. cost .. ")",
|
||||||
p_name)
|
p_name)
|
||||||
if not log_succ then
|
if not log_succ then
|
||||||
@ -953,7 +957,7 @@ function ex_methods.buy(self, p_name, ex_name, item_name, wear, amount, rate)
|
|||||||
end
|
end
|
||||||
else
|
else
|
||||||
local log_succ, log_err =
|
local log_succ, log_err =
|
||||||
self:log("Bought " .. row_amount .. " " ..
|
self:log("Bought " .. row_bought .. " " ..
|
||||||
item_name .. " from yourself.",
|
item_name .. " from yourself.",
|
||||||
p_name)
|
p_name)
|
||||||
if not log_succ then
|
if not log_succ then
|
||||||
@ -969,27 +973,38 @@ function ex_methods.buy(self, p_name, ex_name, item_name, wear, amount, rate)
|
|||||||
|
|
||||||
remaining = remaining - row_bought
|
remaining = remaining - row_bought
|
||||||
|
|
||||||
if remaining == 0 then break end
|
if remaining == 0 or out_of_funds then break end
|
||||||
end
|
end
|
||||||
|
|
||||||
search_stmt:reset()
|
search_stmt:reset()
|
||||||
|
|
||||||
if remaining > 0 then
|
if remaining > 0 then
|
||||||
local add_succ, add_err =
|
if out_of_funds then
|
||||||
self:add_order(p_name, ex_name, "buy", item_name, wear, remaining, rate)
|
local log_succ, log_err =
|
||||||
|
self:log("Insufficient funds to buy " .. remaining .. " " ..
|
||||||
|
item_name .. " at " .. last_row_rate .. "/ea.",
|
||||||
|
p_name)
|
||||||
|
if not log_succ then
|
||||||
|
db:exec("ROLLBACK;")
|
||||||
|
return false, log_err
|
||||||
|
end
|
||||||
|
else
|
||||||
|
local add_succ, add_err =
|
||||||
|
self:add_order(p_name, ex_name, "buy", item_name, wear, remaining, rate)
|
||||||
|
|
||||||
if not add_succ then
|
if not add_succ then
|
||||||
db:exec("ROLLBACK;")
|
db:exec("ROLLBACK;")
|
||||||
return false, add_err
|
return false, add_err
|
||||||
end
|
end
|
||||||
|
|
||||||
local log_succ, log_err =
|
local log_succ, log_err =
|
||||||
self:log("Posted buy offer for " .. remaining .. " " ..
|
self:log("Posted buy offer for " .. remaining .. " " ..
|
||||||
item_name .. " at " .. rate .. "/ea.",
|
item_name .. " at " .. rate .. "/ea.",
|
||||||
p_name)
|
p_name)
|
||||||
if not log_succ then
|
if not log_succ then
|
||||||
db:exec("ROLLBACK;")
|
db:exec("ROLLBACK;")
|
||||||
return false, log_err
|
return false, log_err
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -1039,6 +1054,8 @@ function ex_methods.sell(self, p_name, ex_name, item_name, wear, amount, rate)
|
|||||||
local row_rate = row.Rate
|
local row_rate = row.Rate
|
||||||
local row_sold = math.min(row_amount, remaining)
|
local row_sold = math.min(row_amount, remaining)
|
||||||
|
|
||||||
|
local out_of_funds = false
|
||||||
|
|
||||||
if poster ~= p_name then
|
if poster ~= p_name then
|
||||||
local bal = self:get_balance(poster)
|
local bal = self:get_balance(poster)
|
||||||
|
|
||||||
@ -1049,96 +1066,108 @@ function ex_methods.sell(self, p_name, ex_name, item_name, wear, amount, rate)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local can_afford = math.floor(bal / row_rate)
|
local can_afford = math.floor(bal / row_rate)
|
||||||
|
out_of_funds = can_afford < row_sold
|
||||||
row_sold = math.min(row_sold, can_afford)
|
row_sold = math.min(row_sold, can_afford)
|
||||||
end
|
end
|
||||||
|
|
||||||
if row_sold > 0 then
|
local red_del_stmt
|
||||||
local red_del_stmt
|
|
||||||
|
|
||||||
if row_sold < row_amount then
|
if row_sold < row_amount and not out_of_funds then
|
||||||
red_stmt:bind_names({
|
red_stmt:bind_names({
|
||||||
id = row.Id,
|
id = row.Id,
|
||||||
delta = row_sold,
|
delta = row_sold,
|
||||||
})
|
})
|
||||||
red_del_stmt = red_stmt
|
red_del_stmt = red_stmt
|
||||||
else -- row_sold == row_amount
|
else -- row_sold == row_amount or out_of_funds
|
||||||
del_stmt:bind_values(row.Id)
|
del_stmt:bind_values(row.Id)
|
||||||
red_del_stmt = del_stmt
|
red_del_stmt = del_stmt
|
||||||
end
|
end
|
||||||
|
|
||||||
local red_del_res = red_del_stmt:step()
|
local red_del_res = red_del_stmt:step()
|
||||||
red_del_stmt:reset()
|
red_del_stmt:reset()
|
||||||
if red_del_res == sqlite3.BUSY then
|
if red_del_res == sqlite3.BUSY then
|
||||||
|
search_stmt:reset()
|
||||||
|
db:exec("ROLLBACK;")
|
||||||
|
return false, "Database Busy."
|
||||||
|
elseif red_del_res ~= sqlite3.DONE then
|
||||||
|
search_stmt:reset()
|
||||||
|
sql_error(db:errmsg())
|
||||||
|
end
|
||||||
|
|
||||||
|
local in_succ, in_err =
|
||||||
|
self:put_in_inbox(poster, item_name, wear, row_sold)
|
||||||
|
if not in_succ then
|
||||||
|
search_stmt:reset()
|
||||||
|
db:exec("ROLLBACK;")
|
||||||
|
return false, in_err
|
||||||
|
end
|
||||||
|
|
||||||
|
if poster ~= p_name then
|
||||||
|
local revenue = row_sold * row_rate
|
||||||
|
|
||||||
|
local ch_succ, ch_err = self:change_balance(poster, -revenue)
|
||||||
|
if not ch_succ then
|
||||||
search_stmt:reset()
|
search_stmt:reset()
|
||||||
db:exec("ROLLBACK;")
|
db:exec("ROLLBACK;")
|
||||||
return false, "Database Busy."
|
return false, ch_err
|
||||||
elseif red_del_res ~= sqlite3.DONE then
|
|
||||||
search_stmt:reset()
|
|
||||||
sql_error(db:errmsg())
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local in_succ, in_err =
|
local ch_succ, ch_err = self:change_balance(p_name, revenue)
|
||||||
self:put_in_inbox(poster, item_name, wear, row_sold)
|
if not ch_succ then
|
||||||
if not in_succ then
|
|
||||||
search_stmt:reset()
|
search_stmt:reset()
|
||||||
db:exec("ROLLBACK;")
|
db:exec("ROLLBACK;")
|
||||||
return false, in_err
|
return false, ch_err
|
||||||
end
|
end
|
||||||
|
|
||||||
if poster ~= p_name then
|
local log_succ, log_err =
|
||||||
local revenue = row_sold * row_rate
|
self:log(p_name .. " sold " .. row_sold .. " " ..
|
||||||
|
item_name .. " to you. (-" .. revenue .. ")",
|
||||||
local ch_succ, ch_err = self:change_balance(poster, -revenue)
|
poster)
|
||||||
if not ch_succ then
|
if not log_succ then
|
||||||
search_stmt:reset()
|
search_stmt:reset()
|
||||||
db:exec("ROLLBACK;")
|
db:exec("ROLLBACK;")
|
||||||
return false, ch_err
|
return false, log_err
|
||||||
end
|
end
|
||||||
|
|
||||||
local ch_succ, ch_err = self:change_balance(p_name, revenue)
|
|
||||||
if not ch_succ then
|
|
||||||
search_stmt:reset()
|
|
||||||
db:exec("ROLLBACK;")
|
|
||||||
return false, ch_err
|
|
||||||
end
|
|
||||||
|
|
||||||
|
if out_of_funds then
|
||||||
local log_succ, log_err =
|
local log_succ, log_err =
|
||||||
self:log(p_name .. " sold " .. row_amount .. " " ..
|
self:log("Insufficient funds to buy " ..
|
||||||
item_name .. " to you. (-" .. revenue .. ")",
|
math.min(row_amount - row_sold, remaining) ..
|
||||||
|
" " .. item_name .. " from " .. p_name ..
|
||||||
|
" at " .. row_rate .. "/ea.",
|
||||||
poster)
|
poster)
|
||||||
if not log_succ then
|
if not log_succ then
|
||||||
search_stmt:reset()
|
|
||||||
db:exec("ROLLBACK;")
|
|
||||||
return false, log_err
|
|
||||||
end
|
|
||||||
|
|
||||||
local log_succ, log_err =
|
|
||||||
self:log("Sold " .. row_amount .. " " .. item_name ..
|
|
||||||
" to " .. poster .. "(+" .. revenue .. ")",
|
|
||||||
p_name)
|
|
||||||
if not log_succ then
|
|
||||||
search_stmt:reset()
|
|
||||||
db:exec("ROLLBACK;")
|
|
||||||
return false, log_err
|
|
||||||
end
|
|
||||||
else
|
|
||||||
local log_succ, log_err =
|
|
||||||
self:log("Sold " .. row_amount .. " " ..
|
|
||||||
item_name .. " to yourself.",
|
|
||||||
p_name)
|
|
||||||
if not log_succ then
|
|
||||||
search_stmt:reset()
|
|
||||||
db:exec("ROLLBACK;")
|
db:exec("ROLLBACK;")
|
||||||
return false, log_err
|
return false, log_err
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
order_book_cache(ex_name)[item_name] = nil
|
local log_succ, log_err =
|
||||||
|
self:log("Sold " .. row_sold .. " " .. item_name ..
|
||||||
remaining = remaining - row_sold
|
" to " .. poster .. "(+" .. revenue .. ")",
|
||||||
|
p_name)
|
||||||
if remaining == 0 then break end
|
if not log_succ then
|
||||||
|
search_stmt:reset()
|
||||||
|
db:exec("ROLLBACK;")
|
||||||
|
return false, log_err
|
||||||
|
end
|
||||||
|
else
|
||||||
|
local log_succ, log_err =
|
||||||
|
self:log("Sold " .. row_sold .. " " ..
|
||||||
|
item_name .. " to yourself.",
|
||||||
|
p_name)
|
||||||
|
if not log_succ then
|
||||||
|
search_stmt:reset()
|
||||||
|
db:exec("ROLLBACK;")
|
||||||
|
return false, log_err
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
order_book_cache(ex_name)[item_name] = nil
|
||||||
|
|
||||||
|
remaining = remaining - row_sold
|
||||||
|
|
||||||
|
if remaining == 0 then break end
|
||||||
end
|
end
|
||||||
|
|
||||||
search_stmt:reset()
|
search_stmt:reset()
|
||||||
|
Loading…
Reference in New Issue
Block a user