Cancel remaining buy order when out of funds.

This commit is contained in:
Jesse McDonald 2017-06-03 18:12:09 -05:00
parent 808b3cbf04
commit 141de27c97
1 changed files with 113 additions and 84 deletions

View File

@ -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()