From 37a92fd65acdc6c6ea807e4c38dcdf0d25e46d4b Mon Sep 17 00:00:00 2001 From: raymoo Date: Thu, 25 Feb 2016 22:07:57 -0800 Subject: [PATCH] Market summary --- exchange.lua | 58 ++++++++++++++++++++++++++++++++++++- exchange_machine.lua | 68 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 125 insertions(+), 1 deletion(-) diff --git a/exchange.lua b/exchange.lua index c715d3a..7072b4c 100644 --- a/exchange.lua +++ b/exchange.lua @@ -53,6 +53,32 @@ ON Inbox (Recipient); CREATE VIEW if not exists distinct_items AS SELECT DISTINCT Item FROM Orders; +CREATE VIEW if not exists market_summary AS +SELECT + distinct_items.Item, + ( + SELECT sum(Orders.Amount) FROM Orders + WHERE Orders.Item = distinct_items.Item + AND Orders.Type = "buy" + ), + ( + SELECT max(Orders.Rate) FROM Orders + WHERE Orders.Item = distinct_items.Item + AND Orders.Type = "buy" + ), + ( + SELECT sum(Orders.Amount) FROM Orders + WHERE Orders.Item = distinct_items.Item + AND Orders.Type = "sell" + ), + ( + SELECT min(Orders.Rate) FROM Orders + WHERE Orders.Item = distinct_items.Item + AND Orders.Type = "sell" + ) +FROM distinct_items; + + END TRANSACTION; ]=] @@ -192,6 +218,10 @@ DELETE FROM Inbox WHERE Id = :id; ]=] +local summary_query = [=[ +SELECT * FROM market_summary; +]=] + local ex_methods = {} local ex_meta = { __index = ex_methods } @@ -252,6 +282,7 @@ function exports.open_exchange(path) get_inbox_stmt = assert(db:prepare(get_inbox_query)), red_inbox_stmt = assert(db:prepare(red_inbox_query)), del_inbox_stmt = assert(db:prepare(del_inbox_query)), + summary_stmt = assert(db:prepare(summary_query)), } @@ -1053,7 +1084,32 @@ function ex_methods.take_inbox(self, id, amount) return true, math.min(amount, available) end - + + +-- Returns a list of tables with fields: +-- item_name: Name of the item +-- buy_volume: Number of items sought +-- buy_max: Maximum buy rate +-- sell_volume: Number of items for sale +-- sell_min: Minimum sell rate +function ex_methods.market_summary(self) + local db = self.db + local stmt = self.stmts.summary_stmt + + local res = {} + for a in stmt:rows() do + table.insert(res, { + item_name = a[1], + buy_volume = a[2], + buy_max = a[3], + sell_volume = a[4], + sell_min = a[5], + }) + end + stmt:reset() + + return res +end function exports.test() diff --git a/exchange_machine.lua b/exchange_machine.lua index b0467a8..747ca6d 100644 --- a/exchange_machine.lua +++ b/exchange_machine.lua @@ -1,6 +1,55 @@ local exchange = ... local search_cooldown = 2 +local summary_interval = 600 + +local function mk_summary_fs() + local summary = exchange:market_summary() + local res = {} + table.insert(res, "size[8,8]") + table.insert(res, "label[0,0;Updated Periodically]") + table.insert(res, "tablecolumns[text;text;text;text;text;text]") + table.insert(res, "table[0,1;8,6;summary_table;") + table.insert(res, "Item,Description,Buy Vol,Buy Max,Sell Vol,Sell Max") + + local all_items = minetest.registered_items + for i, row in ipairs(summary) do + table.insert(res, "," .. row.item_name) + local def = all_items[row.item_name] + if def then + table.insert(res, "," .. def.description) + else + table.insert(res, "," .. "Unknown Item") + end + table.insert(res, "," .. (row.buy_volume or 0)) + table.insert(res, "," .. (row.buy_max or "N/A")) + table.insert(res, "," .. (row.sell_volume or 0)) + table.insert(res, "," .. (row.sell_min or "N/A")) + end + + table.insert(res, "]") + table.insert(res, "button[3,7;2,1;back;Back]") + + return table.concat(res) +end +local summary_fs = "" +minetest.after(0, function() + summary_fs = mk_summary_fs() +end) + + +local elapsed = 0 +minetest.register_globalstep(function(dtime) + elapsed = elapsed + dtime + if elapsed >= summary_interval then + summary_fs = mk_summary_fs() + end +end) + +local summary_form = "global_exchange:summary" +local function show_summary(p_name) + minetest.show_formspec(p_name, summary_form, summary_fs) +end local main_state = {} -- ^ A per-player state for the main form. It contains these values: @@ -101,6 +150,7 @@ local function mk_main_fs(p_name, new_item, err_str, success) fs = fs .. "label[0.2,0.5;Use an ATM to make your account.]" end + fs = fs .. "button[4,0;2,1;summary;Market Summary]" fs = fs .. "button[6,0;2,1;your_orders;Your Orders]" fs = fs .. "field[0.2,1.5;3,1;item;Item: ;" .. item_def .. "]" fs = fs .. "field[3.2,1.5;3,1;amount;Amount: ;" .. amount_def .. "]" @@ -396,6 +446,10 @@ local function handle_main(player, formname, fields) show_main(p_name) end + if fields["summary"] then + show_summary(p_name) + end + if fields["your_orders"] then if not own_state[p_name] then own_state[p_name] = {} @@ -491,9 +545,23 @@ local function handle_own_orders(player, formname, fields) end +local function handle_summary(player, formname, fields) + if formname ~= summary_form then return end + + local p_name = player:get_player_name() + + if fields["back"] then + show_main(p_name) + end + + return true +end + + minetest.register_on_player_receive_fields(handle_main) minetest.register_on_player_receive_fields(handle_select) minetest.register_on_player_receive_fields(handle_own_orders) +minetest.register_on_player_receive_fields(handle_summary) minetest.register_node("global_exchange:exchange", {