From c5fc45aeb2616e846f37c5fce02c3b691998281c Mon Sep 17 00:00:00 2001 From: h-v-smacker Date: Sun, 21 Jan 2018 15:55:44 +0300 Subject: introducing wire transfers --- README.md | 21 +++++ init.lua | 213 ++++++++++++++++++++++++++++++++++++++++++++++ textures/atm_front_wt.png | Bin 0 -> 356 bytes textures/atm_side_wt.png | Bin 0 -> 305 bytes 4 files changed, 234 insertions(+) create mode 100644 textures/atm_front_wt.png create mode 100644 textures/atm_side_wt.png diff --git a/README.md b/README.md index 5b28449..c3c0bd7 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,27 @@ Goes without saying, all lower tier options are also available in a higher tier If mesecons mod is not installed, then the mese wire in recipes is replaced by a copper ingot. +## Wire Transfer + +An alternative system for transfering money from one player's account to another. The terminals +provide an interface for sending a specified amount (integer number) to a player (who must +have an existing banking account) and for checking the transfers to the account of the user of +the terminal. The history of transactions can be erased completely, and it is recommended to +clean it once the stored data are no longer of any relevance. Otherwise, the transaction history +is preserved indefinitely. + +[ steel ingot, mese crystal, steel ingot ] +[ glass, mese wire, steel ingot ] +[ steel ingot, mese crystal, steel ingot ] + +To complete a wire transfer a player must provide the name of the recipient with an +existing banking account, the desired amount to be transfered, and a description of the +payment (optional, but strongly recommended). +After entering those parameters the terminal checks their validity and if there is no problem, +the player is shown the final confirmation window. If the player confirms the payment, the specified +amount will be transfered immediately. At this point the transaction is final. +If there are errors, a corresponding message is shown in the chat, and the transaction is aborted. + ## Founder This is a fork of gpcf's ATM mod: git://gpcf.eu/atm.git \ No newline at end of file diff --git a/init.lua b/init.lua index 7823617..7f4cd8a 100644 --- a/init.lua +++ b/init.lua @@ -1,6 +1,8 @@ -- Copyright (c) 2016 Gabriel PĂ©rez-Cerezo, licensed under WTFPL. atm = {} atm.balance = {} +atm.pending_transfers = {} +atm.completed_transactions = {} atm.pth = minetest.get_worldpath().."/atm_accounts" atm.pth_wt = minetest.get_worldpath().."/atm_wt_transactions" local modpath = minetest.get_modpath("atm") @@ -115,6 +117,89 @@ end +-- wire transfer interface + +function atm.showform_wt (player) + atm.readaccounts() + if not atm.balance[player:get_player_name()] then + atm.balance[player:get_player_name()] = 30 + end + local formspec = + "size[8,6]".. + default.gui_bg.. + default.gui_bg_img.. + default.gui_slots.. + "button[5.75,0;2,1;transactions;Transactions >]" .. + "label[2.5,0;Wire Transfer Terminal]" .. + "label[2,0.5;Your account balance: $".. atm.balance[player:get_player_name()].. "]" .. + "field[0.5,1.5;5,1;dstn;Recepient:;]".. + "field[6,1.5;2,1;amnt;Amount:;]".. + "field[0.5,3;7.5,1;desc;Description:;]".. + "button_exit[0.2,5;1,1;Quit;Quit]" .. + "button[4.7,5;3,1;pay;Complete the payment]" + minetest.after((0.1), function(gui) + return minetest.show_formspec(player:get_player_name(), "atm.form.wt", gui) + end, formspec) +end + +function atm.showform_wtconf (player, dstn, amnt, desc) + atm.readaccounts() + if not atm.balance[player:get_player_name()] then + atm.balance[player:get_player_name()] = 30 + end + local formspec = + "size[8,6]".. + default.gui_bg.. + default.gui_bg_img.. + default.gui_slots.. + "label[2.5,0;Wire Transfer Terminal]" .. + "label[2,0.5;Your account balance: $".. atm.balance[player:get_player_name()].. "]" .. + "label[2.5,1;TRANSACTION SUMMARY:]".. + "label[0.5,1.5;Recepient: " .. dstn .. "]".. + "label[0.5,2;Amount: " .. amnt .. "]".. + "label[0.5,2.5;Description: " .. desc .. "]".. + "button_exit[0.2,5;1,1;Quit;Quit]" .. + "button[4.7,5;3,1;cnfrm;Confirm transfer]" + minetest.after((0.1), function(gui) + return minetest.show_formspec(player:get_player_name(), "atm.form.wtc", gui) + end, formspec) +end + +function atm.showform_wtlist (player, tlist) + atm.readaccounts() + if not atm.balance[player:get_player_name()] then + atm.balance[player:get_player_name()] = 30 + end + + local textlist = '' + + if not tlist then + textlist = "no transactions registered\n" + else + for i,entry in ipairs(tlist) do + textlist = textlist .. entry.date .. " $" .. entry.sum .. " from " .. entry.from .. ": " .. entry.desc .. "\n" + end + end + + local formspec = + "size[8,6]".. + default.gui_bg.. + default.gui_bg_img.. + default.gui_slots.. + "button[5.75,0;2,1;transfer;< Transfer money]" .. + "label[2.5,0;Wire Transfer Terminal]" .. + "label[2,0.5;Your account balance: $".. atm.balance[player:get_player_name()].. "]" .. + "textarea[0.5,1.25;7.5,4;hst;Transaction list;" .. textlist .. "]" .. + "button_exit[0.2,5;1,1;Quit;Quit]" .. + "button[4.7,5;3,1;clr;Clear transactions]" + minetest.after((0.1), function(gui) + return minetest.show_formspec(player:get_player_name(), "atm.form.wtl", gui) + end, formspec) +end + + +-- banking accounts storage + function atm.readaccounts () local b = atm.balance local file = io.open(atm.pth, "r") @@ -147,10 +232,36 @@ function atm.saveaccounts() io.close(output) end + +-- wire transfer data storage + +function atm.read_transactions() + local file = io.open(atm.pth_wt, "r") + if file then + local data = file:read("*all") + atm.completed_transactions = minetest.deserialize(data) + end +end + +function atm.write_transactions() + if not atm.completed_transactions then + return + end + local file = io.open(atm.pth_wt, "w") + local data = minetest.serialize(atm.completed_transactions) + file:write(data) + io.close(file) +end + + + minetest.register_on_joinplayer(function(player) atm.readaccounts() end) + +-- ATM node definitions + minetest.register_node("atm:atm", { description = "ATM", tiles = { @@ -211,10 +322,35 @@ minetest.register_node("atm:atm3", { end, }) + +-- Wire transfer terminal node + +minetest.register_node("atm:wtt", { + description = "Wire Transfer Terminal", + tiles = { + "atm_top.png", "atm_top.png", + "atm_side_wt.png", "atm_side_wt.png", + "atm_side_wt.png", "atm_front_wt.png" + }, + paramtype2 = "facedir", + groups = {cracky=2, bank_equipment = 1}, + legacy_facedir_simple = true, + is_ground_content = false, + sounds = default.node_sound_stone_defaults(), + + can_dig = can_dig, + + on_rightclick = function(pos, node, player, itemstack, pointed_thing) + atm.showform_wt(player) + end, +}) + + -- Check the form minetest.register_on_player_receive_fields(function(player, form, pressed) + -- ATMs if form == "atm.form" or form == "atm.form2" or form == "atm.form3" then local n = player:get_player_name() local transaction = { amount = 0, denomination = 0, count = 0 } @@ -294,6 +430,75 @@ minetest.register_on_player_receive_fields(function(player, form, pressed) atm.showform3(player) end end + + -- Wire transfer terminals + elseif form == "atm.form.wt" or form == "atm.form.wtc" or form == "atm.form.wtl" then + + local n = player:get_player_name() + + if not pressed.Quit and not pressed.quit then + if form == "atm.form.wt" and pressed.transactions then + -- transaction list (can be edited in the form, but than means nothing) + atm.read_transactions() + atm.showform_wtlist(player, atm.completed_transactions[n]) + elseif form == "atm.form.wtl" and pressed.transfer then + atm.showform_wt(player) + elseif form == "atm.form.wtl" and pressed.clr then + -- clear all transactions in the player's list + atm.read_transactions() + atm.completed_transactions[n] = nil + atm.write_transactions() + minetest.chat_send_player(n, "Your transaction history has been cleared") + atm.showform_wtlist(player, atm.completed_transactions[n]) + elseif form == "atm.form.wt" and pressed.pay then + + -- perform the checks of validity for wire transfer order + -- if passed, store the data in a temporary table and show confirmation window + if not atm.balance[pressed.dstn] then + minetest.chat_send_player(n, "The recepient <" .. pressed.dstn .. "> is not registered in the banking system, aborting") + atm.showform_wt(player) + elseif not string.match(pressed.amnt, '^[0-9]+$') then + minetest.chat_send_player(n, "Invalid amount <" .. pressed.amnt .. "> : must be an integer number, aborting") + atm.showform_wt(player) + elseif atm.balance[n] < tonumber(pressed.amnt) then + minetest.chat_send_player(n, "Your account does not have enough funds to complete this transfer, aborting") + atm.showform_wt(player) + else + atm.pending_transfers[n] = {to = pressed.dstn, sum = tonumber(pressed.amnt), desc = pressed.desc} + atm.showform_wtconf(player, pressed.dstn, pressed.amnt, pressed.desc) + end + + elseif form == "atm.form.wtc" then + -- transaction processing + atm.read_transactions() + local t = atm.pending_transfers[n] + if not atm.completed_transactions[t.to] then + atm.completed_transactions[t.to] = {} + end + + if atm.balance[n] < t.sum then + -- you can never be too paranoid about the funds availaible + minetest.chat_send_player(n, "Your account does not have enough funds to complete this transfer, aborting") + atm.showform_wt(player) + end + + table.insert(atm.completed_transactions[t.to], {date=os.date("%Y-%m-%d"), from=n, sum=t.sum, desc=t.desc}) + atm.balance[n] = atm.balance[n] - t.sum + atm.balance[t.to] = atm.balance[t.to] + t.sum + atm.write_transactions() + atm.saveaccounts() + atm.pending_transfers[n] = nil + minetest.chat_send_player(n, "Payment of " .. t.sum .. " to " .. t.to .. " completed") + minetest.chat_send_player(n, n .. ", thank you for choosing the Wire Transfer system") + atm.showform_wt(player) + end + else + -- clear the pending transaction of the player, just in case + if atm.pending_transfers[n] then + atm.pending_transfers[n] = nil + end + end + end end) @@ -331,5 +536,13 @@ minetest.register_craft({ } }) +minetest.register_craft({ + output = "atm:wtt", + recipe = { + {"default:steel_ingot", "default:mese_crystal", "default:steel_ingot"}, + {"default:glass", cheaper_part, "default:steel_ingot"}, + {"default:steel_ingot", "default:mese_crystal", "default:steel_ingot"} + } +}) dofile(modpath .. "/interest.lua") diff --git a/textures/atm_front_wt.png b/textures/atm_front_wt.png new file mode 100644 index 0000000..f40e05c Binary files /dev/null and b/textures/atm_front_wt.png differ diff --git a/textures/atm_side_wt.png b/textures/atm_side_wt.png new file mode 100644 index 0000000..fba2e40 Binary files /dev/null and b/textures/atm_side_wt.png differ -- cgit v1.2.3