-- wtm.lua (FINAL - Abgesichert gegen Race Conditions) -- Die globale pos_info wird aus den anderen Dateien mitbenutzt. local function show_wtm_statement_form(player, account_type) local player_name = player:get_player_name() local data = bank_accounts.get_account_data(player_name) local history = data.history; local lines = {}; local current_total_label = "" table.insert(lines, minetest.formspec_escape(string.format("%-11s | %-13s | %-13s | %-20s | %-20s | %s", S("Date"), S("Amount"), S("New Balance"), S("Method"), S("Purpose"), S("Partner")))) table.insert(lines, minetest.formspec_escape("-----------------------------------------------------------------------------------------")) if history then for _, t in ipairs(history) do if t.account == account_type then local parts = {}; table.insert(parts, string.format("%-11s", os.date("%Y-%m-%d", t.timestamp))); table.insert(parts, string.format("%12s", string.format("%+.2f", t.amount) .. " MG")); table.insert(parts, string.format("%12s", string.format("%.2f", t.new_total).." MG")); table.insert(parts, string.format("%-20s", S(t.type))) local purpose = t.purpose or ""; local partner = t.other or ""; if purpose ~= "" or partner ~= "" then table.insert(parts, string.format("%-20s", purpose)); if partner ~= "" then table.insert(parts, partner) end end table.insert(lines, minetest.formspec_escape(table.concat(parts, " | "))) end end end if account_type == "balance" then current_total_label = S("Current Balance: @1", string.format("%.2f", data.balance) .. " MG") else current_total_label = S("Current Credit Debt: @1", string.format("%.2f", data.credit) .. " MG") end local form_name = "bank_accounts:wtm_statement@" .. player_name local formspec = "size[13,9]".."label[0,0;"..S("Account Statement for @1", player_name).."]".."button_exit[0,0.5;2,1;view_balance;"..S("Balance").."]".."button_exit[2,0.5;2,1;view_credit;"..S("Credit").."]".."textlist[0,1.2;13,7;statement_list;"..table.concat(lines,",").."]".."label[0,8.4;"..current_total_label.."]".."button_exit[11,8.4;2,1;back;"..S("Back").."]" minetest.show_formspec(player_name, form_name, formspec) end function wtm_main_form(player, pos) local player_name = player:get_player_name() local data = bank_accounts.get_account_data(player_name) minetest.show_formspec(player_name, "bank_accounts:wtm_options", "size[8,8]" .. "button_exit[0.5,1;3.5,1;transfer_balance;"..S("Transfer from Balance").."]" .. "button_exit[0.5,2.0;3.5,1;transfer_credit;"..S("Transfer from Credit").."]" .. "button_exit[5,2.5;2.4,1;statement;"..S("Account Statement").."]" .. "label[5,1;"..S("Balance: @1", string.format("%.2f", data.balance) .. " MG").."]" .. "label[5,1.5;"..S("Credit Debt: @1", string.format("%.2f", data.credit) .. " MG").."]" .. "button_exit[0.5,6;3,1;credit_card;"..S("Get Credit Card").."]" .. "button_exit[0.5,7;3,1;debit_card;"..S("Get Debit Card").."]" .. "button_exit[5,7;2,1;exit;"..S("Close").."]") end minetest.register_node("bank_accounts:wtm", { description = S("Wire Transfer Machine"), drawtype = "mesh", mesh = "atm.obj", paramtype = "light", paramtype2 = "facedir", tiles = {"wtm_col.png"}, groups = {cracky=3, crumbly=3, oddly_breakable_by_hand=2}, on_rightclick = function(pos, node, player, itemstack, pointed_thing) pos_info = pos if itemstack:get_name() ~= "bank_accounts:atm_card" then minetest.chat_send_player(player:get_player_name(), S("[WTM] Must use ATM card.")) return end minetest.show_formspec(player:get_player_name(), "bank_accounts:wtm_home", "size[8,8]" .. "pwdfield[2,4;4,1;fourdigitpin;"..S("Four Digit Pin:").."]" .. "button_exit[5,6;2,1;enter;"..S("Enter").."]" .. "button_exit[3,6;2,1;exit;"..S("Cancel").."]") end, }) minetest.register_on_player_receive_fields(function(player, formname, fields) if not formname:find("bank_accounts:wtm") then return end local player_name = player:get_player_name() local pos = pos_info if not pos then return end if formname == "bank_accounts:wtm_home" then if fields.enter then if bank_accounts.get_pin(player_name) == fields.fourdigitpin then wtm_main_form(player, pos) else minetest.chat_send_player(player_name, S("[WTM] Invalid Pin.")) end end elseif formname == "bank_accounts:wtm_options" then if fields.statement then show_wtm_statement_form(player, "balance") elseif fields.transfer_balance or fields.transfer_credit then local source_account = fields.transfer_balance and "balance" or "credit" local source_label = "" if source_account == "balance" then source_label = S("Transfer from Balance (Available: @1 MG)", string.format("%.2f", bank_accounts.get_balance(player_name))) else source_label = S("Transfer from Credit (Debt: @1 MG)", string.format("%.2f", bank_accounts.get_credit(player_name))) end minetest.show_formspec(player_name, "bank_accounts:wtm_transfer@"..source_account, "size[8,8]" .. "label[0,0;"..source_label.."]" .. "field[0.5,1.5;7.5,1;recipient;"..S("Recipient:")..";]" .. "field[0.5,2.5;7.5,1;amount;"..S("Amount:")..";]" .. "field[0.5,3.5;7.5,1;purpose;"..S("Purpose:")..";]" .. "button_exit[4,7;2,1;send;"..S("Send").."]" .. "button_exit[2,7;2,1;cancel;"..S("Cancel").."]") elseif fields.credit_card then player:get_inventory():add_item("main", "bank_accounts:credit_card"); wtm_main_form(player, pos) elseif fields.debit_card then player:get_inventory():add_item("main", "bank_accounts:debit_card"); wtm_main_form(player, pos) end elseif formname:find("bank_accounts:wtm_transfer@") then if fields.send then -- KORREKTUR: Prüfe auf das "Schloss", bevor die Transaktion beginnt if bank_accounts.is_calculating_interest then minetest.chat_send_player(player_name, S("[Bank] System is busy, please try again in a moment.")) wtm_main_form(player, pos) return end local source_account = formname:match("bank_accounts:wtm_transfer@(.*)") local recipient = fields.recipient; local amount = normalize_and_tonumber(fields.amount); local purpose = fields.purpose if not recipient or recipient == "" or not bank_accounts.player_has_account(recipient) then minetest.chat_send_player(player_name, S("[WTM] Recipient not found or has no account.")) elseif not amount or amount <= 0 then minetest.chat_send_player(player_name, S("[WTM] Invalid amount.")) elseif source_account == "balance" and bank_accounts.get_balance(player_name) < amount then minetest.chat_send_player(player_name, S("[WTM] Insufficient funds.")) else -- Da eine Überweisung zwei Schreibvorgänge erfordert, ist es hier am sichersten, -- dass wir wissen, dass das System nicht beschäftigt ist. if source_account == "balance" then bank_accounts.add_balance(player_name, -amount, "Transfer Sent", purpose, recipient) else bank_accounts.add_credit(player_name, amount, "Transfer Sent (Credit)", purpose, recipient) end bank_accounts.add_balance(recipient, amount, "Transfer Received", purpose, player_name) minetest.chat_send_player(player_name, S("[WTM] Successfully transferred @1 MG to @2.", string.format("%.2f", amount), recipient)) minetest.chat_send_player(recipient, S("[WTM] You received a transfer of @1 MG from @2.", string.format("%.2f", amount), player_name)) end end wtm_main_form(player, pos) elseif formname:find("bank_accounts:wtm_statement@") then local target_name = formname:match("bank_accounts:wtm_statement@(.*)"); if not target_name then return end if fields.back then wtm_main_form(player, pos) else show_wtm_statement_form(player, fields.view_credit and "credit" or "balance") end end end)