A Minetest trading mod by crabman, under the original idea of Cyberpangolin.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

309 lines
10KB

  1. local states = {}
  2. --function load a player's wallet
  3. function minercantile.wallet.load_wallet(name)
  4. if minercantile.wallets[name] == nil then
  5. minercantile.wallets[name] = {}
  6. end
  7. local file, _ = io.open(minercantile.path_wallet..name, "r")
  8. if file then
  9. local data = minetest.deserialize(file:read("*all"))
  10. file:close()
  11. if data and type(data) == "table" then
  12. if data.money then
  13. minercantile.wallets[name].money = data.money
  14. else
  15. minercantile.wallets[name].money = 0
  16. end
  17. if data.transactions then
  18. minercantile.wallets[name].transactions = table.copy(data.transactions)
  19. else
  20. minercantile.wallets[name].transactions = {}
  21. end
  22. return
  23. end
  24. end
  25. --if new player then wallet is empty
  26. minercantile.wallets[name].money = 0
  27. minercantile.wallets[name].transactions = {}
  28. end
  29. function minercantile.wallet.save_wallet(name)
  30. local input, err = io.open(minercantile.path_wallet..name, "w")
  31. if input then
  32. input:write(minetest.serialize(minercantile.wallets[name]))
  33. input:close()
  34. minetest.log("info", "saved " .. minercantile.path_wallet..name)
  35. else
  36. minetest.log("error", "open(" .. minercantile.path_wallet..name .. ", 'w') failed: " .. err)
  37. end
  38. --unload wallet if player offline
  39. local connected = false
  40. for _, player in pairs(minetest.get_connected_players()) do
  41. local player_name = player:get_player_name()
  42. if player_name and player_name ~= "" and player_name == name then
  43. connected = true
  44. break
  45. end
  46. end
  47. if not connected then
  48. minercantile.wallets[name] = nil
  49. end
  50. end
  51. function minercantile.wallet.get_money(name)
  52. if minercantile.wallets[name] == nil then
  53. minercantile.wallet.load_wallet(name)
  54. end
  55. return minercantile.wallets[name].money
  56. end
  57. function minercantile.wallet.give_money(name, amount, transaction)
  58. if minercantile.wallets[name] == nil then
  59. minercantile.wallet.load_wallet(name)
  60. end
  61. minercantile.wallets[name].money = minercantile.wallet.get_money(name) + amount
  62. if transaction then
  63. local trans = os.date().. ":"..transaction
  64. minercantile.add_transactions(name, trans)
  65. end
  66. minercantile.wallet.save_wallet(name)
  67. end
  68. function minercantile.wallet.take_money(name, amount, transaction)
  69. if minercantile.wallets[name] == nil then
  70. minercantile.wallet.load_wallet(name)
  71. end
  72. minercantile.wallets[name].money = minercantile.wallet.get_money(name) - amount
  73. if transaction then
  74. local trans = os.date().. ": "..transaction
  75. minercantile.add_transactions(name, trans)
  76. end
  77. minercantile.wallet.save_wallet(name)
  78. end
  79. function minercantile.wallet.get_transactions(name)
  80. if minercantile.wallets[name] == nil then
  81. minercantile.wallet.load_wallet(name)
  82. end
  83. return minercantile.wallets[name].transactions
  84. end
  85. function minercantile.add_transactions(name, new_transaction)
  86. local old = minercantile.wallet.get_transactions(name)
  87. minercantile.wallets[name].transactions = {new_transaction}
  88. for _, trans in pairs(old) do
  89. table.insert(minercantile.wallets[name].transactions, trans)
  90. if #minercantile.wallets[name].transactions > 9 then
  91. break
  92. end
  93. end
  94. end
  95. function minercantile.send_money(sender, receiver, amount)
  96. if minercantile.wallet.get_money(sender) < amount then
  97. return false
  98. end
  99. minercantile.wallet.take_money(sender, amount, "Send "..amount.."$ to "..receiver)
  100. minercantile.wallet.give_money(receiver, amount, "Received "..amount.."$ from "..sender)
  101. return true
  102. end
  103. function minercantile.get_formspec_wallet(name)
  104. if minercantile.wallets[name] == nil then
  105. minercantile.wallet.load_wallet(name)
  106. end
  107. local formspec = {}
  108. table.insert(formspec,"size[10,9]bgcolor[#2A2A2A;]label[4.4,0;My Wallet]")
  109. table.insert(formspec,"label[0.5,1;Sold: ".. tostring(minercantile.wallet.get_money(name)) .."$]")
  110. table.insert(formspec,"label[4,2.3;10 last transactions]")
  111. local transactions = minercantile.wallet.get_transactions(name)
  112. if #transactions < 1 then
  113. table.insert(formspec,"label[3.5,4;There are no transactions]")
  114. else
  115. local y = 3
  116. for _,transac in pairs(transactions) do
  117. table.insert(formspec,"label[1.5,"..y..";".. transac .."]")
  118. y = y+0.4
  119. end
  120. end
  121. table.insert(formspec,"button[0,8.2;1.5,1;page;Transfert]")
  122. table.insert(formspec,"button_exit[8,8.2;1.5,1;close;Close]")
  123. return table.concat(formspec)
  124. end
  125. function minercantile.get_formspec_wallet_transfert(name)
  126. local money = minercantile.wallet.get_money(name)
  127. local formspec = {}
  128. table.insert(formspec,"size[10,9]bgcolor[#2A2A2A;]label[4.4,0;My Wallet]")
  129. table.insert(formspec,"label[0.5,1;Sold: ".. tostring(money) .."$]")
  130. if money < 5 then
  131. table.insert(formspec, "label[2,4.5;Sorry you can't send money, minimum amount is 5$]")
  132. else
  133. if not states[name] then
  134. states[name] = {}
  135. end
  136. if not states[name].players_list or states[name].refresh then
  137. states[name].refresh = nil
  138. states[name].players_list = {}
  139. states[name].selected_id = 0
  140. for _,player in pairs(minetest.get_connected_players()) do
  141. local player_name = player:get_player_name()
  142. if player_name and player_name ~= "" and player_name ~= name then
  143. table.insert(states[name].players_list, player_name)
  144. end
  145. end
  146. states[name]["receiver"] = nil
  147. end
  148. if not states[name].amount then
  149. states[name].amount = 5
  150. end
  151. if #states[name].players_list == 0 then
  152. table.insert(formspec, "label[2,3.6;There are no player, refresh]")
  153. table.insert(formspec,"button[6,3.4;2,1;refresh;refresh list]")
  154. else
  155. table.insert(formspec, "dropdown[3,3.5;3,1;receiver;"..table.concat(states[name].players_list, ",")..";"..states[name].selected_id.."]")
  156. table.insert(formspec, "label[3.5,6.4;Send "..states[name]["amount"].."$ to "..(states[name]["receiver"] or "").." ?]")
  157. table.insert(formspec,"button[4.1,7;1.5,1;send;send]")
  158. table.insert(formspec,"button[6,3.4;1.5,1;refresh;refresh list]")
  159. table.insert(formspec, "label[3.5,4.5;Amount to send (minimum 5$)]")
  160. table.insert(formspec, "button[1.7,5;1,1;amount;-1]")
  161. table.insert(formspec, "button[2.7,5;1,1;amount;-10]")
  162. table.insert(formspec, "button[3.7,5;1,1;amount;-100]")
  163. table.insert(formspec, "label[4.7,5.2;"..tostring(states[name]["amount"]).."]")
  164. table.insert(formspec, "button[5.4,5;1,1;amount;+100]")
  165. table.insert(formspec, "button[6.4,5;1,1;amount;+10]")
  166. table.insert(formspec, "button[7.4,5;1,1;amount;+1]")
  167. end
  168. end
  169. table.insert(formspec,"button[0,8.2;1.5,1;page;wallet]")
  170. table.insert(formspec,"button_exit[8,8.2;1.5,1;close;Close]")
  171. return table.concat(formspec)
  172. end
  173. function minercantile.get_formspec_wallet_transfert_send(name)
  174. local formspec = {"size[6,3]bgcolor[#2A2A2A;]label[2,0;Validate sending]"}
  175. table.insert(formspec, "label[2,1.2;Send "..tostring(states[name]["amount"]).."$ to ".. states[name]["receiver"] .."]")
  176. table.insert(formspec, "button_exit[1.1,2.1;1.5,1;close;Abort]")
  177. table.insert(formspec, "button[3.3,2.1;1.5,1;send;Send]")
  178. return table.concat(formspec)
  179. end
  180. minetest.register_on_player_receive_fields(function(player, formname, fields)
  181. local name = player:get_player_name()
  182. if not name or name == "" then return end
  183. if formname == "minercantile:ended" then
  184. states[name] = nil
  185. return
  186. elseif formname == "minercantile:wallet" then
  187. if fields["quit"] or fields["close"] then
  188. states[name] = nil
  189. return
  190. elseif fields["page"] then
  191. minetest.show_formspec(name, "minercantile:transfert", minercantile.get_formspec_wallet_transfert(name))
  192. return
  193. end
  194. elseif formname == "minercantile:transfert" then
  195. if fields["quit"] then
  196. states[name] = nil
  197. return
  198. elseif fields["page"] then
  199. minetest.show_formspec(name, "minercantile:wallet", minercantile.get_formspec_wallet(name))
  200. return
  201. elseif fields["refresh"] then
  202. states[name].refresh = true
  203. elseif fields["amount"] then
  204. local inc = tonumber(fields["amount"])
  205. if inc ~= nil then
  206. states[name]["amount"] = states[name]["amount"] + inc
  207. end
  208. if states[name]["amount"] > minercantile.wallet.get_money(name) then
  209. states[name]["amount"] = minercantile.wallet.get_money(name)
  210. end
  211. if states[name]["amount"] < 5 then
  212. states[name]["amount"] = 5
  213. end
  214. elseif fields["send"] then
  215. if states[name]["receiver"] and states[name]["receiver"] ~= "" then
  216. minetest.show_formspec(name, "minercantile:transfert_send", minercantile.get_formspec_wallet_transfert_send(name))
  217. return
  218. end
  219. elseif fields["receiver"] then
  220. for i, n in pairs(states[name].players_list) do
  221. if n == fields["receiver"] then
  222. states[name]["receiver"] = fields["receiver"]
  223. states[name].selected_id = i
  224. break
  225. end
  226. end
  227. end
  228. minetest.show_formspec(name, "minercantile:transfert", minercantile.get_formspec_wallet_transfert(name))
  229. elseif formname == "minercantile:transfert_send" then
  230. if fields["send"] then
  231. if minercantile.send_money( name, states[name]["receiver"], states[name]["amount"]) then
  232. minetest.show_formspec(name, "minercantile:ended", "size[5,3]bgcolor[#2A2A2A;]label[1.8,0;Validated]label[1.7,1;Money sent]button_exit[1.8,2.1;1.5,1;close;Close]")
  233. else
  234. minetest.show_formspec(name, "minercantile:ended", "size[5,3]bgcolor[#2A2A2A;]label[1.6,0;Error]label[1.6,1;Error occured]button_exit[1.8,2.1;1.5,1;close;Close]")
  235. end
  236. elseif fields["quit"] or fields["close"] then
  237. states[name] = nil
  238. return
  239. end
  240. end
  241. end)
  242. if (minetest.get_modpath("unified_inventory")) then
  243. unified_inventory.register_button("wallet", {
  244. type = "image",
  245. image = "minercantile_gold_coin.png",
  246. tooltip = "My Wallet",
  247. show_with = "interact",
  248. action = function(player)
  249. local name = player:get_player_name()
  250. if not name then return end
  251. local formspec = minercantile.get_formspec_wallet(name)
  252. minetest.show_formspec(name, "minercantile:wallet", formspec)
  253. end,
  254. })
  255. else
  256. minetest.register_chatcommand("wallet",{
  257. params = "",
  258. description = "Shows your money wallet",
  259. privs = {interact= true},
  260. func = function (name, params)
  261. local formspec = minercantile.get_formspec_wallet(name)
  262. minetest.show_formspec(name, "minercantile:wallet", formspec)
  263. end,
  264. })
  265. end
  266. minetest.register_on_joinplayer(function(player)
  267. local name = player:get_player_name()
  268. if not name or name == "" then return end
  269. minercantile.wallet.load_wallet(name)
  270. end)
  271. minetest.register_on_leaveplayer(function(player)
  272. local name = player:get_player_name()
  273. if not name or name == "" then return end
  274. minercantile.wallets[name] = nil
  275. end)