· 6 years ago · Jan 26, 2020, 12:20 AM
1-------------------- Bank Server
2
3-------------------- Params
4local filePath = "disk/"
5local modemSide = "top"
6
7local text_account_start_description = "¡Bienvenido a Mermegold!"
8local text_error_invalidamount = "Monto invalido"
9local text_error_from = "Cuenta origen inválida"
10local text_error_to = "Cuenta destino inválida"
11local text_error_account = "Cuenta inexistente"
12local text_error_same = "No se puede usar la misma cuenta como destino y origen a la vez"
13local text_error_notenoughbalance = "Balance insuficiente"
14local text_success_transaction = "Transacción exitosa"
15local text_success_update = "Actualización exitosa"
16local text_success_account = "Cuenta creada con exito. Código: "
17--------------------
18
19-------------------- Variables
20local clientData = {}
21--------------------
22
23-------------------- Funciones
24local function loadClients()
25 local f = fs.open(filePath.."clientList.txt", "r")
26 if (f ~= nil) then
27 local line = f.readLine()
28 clientData = {}
29 repeat
30 local key = line
31 clientData[key] = {}
32 local cf = fs.open(filePath.."clientData/"..key.."/info.txt", "r")
33 local cline = cf.readLine()
34 repeat
35 if (cline == "name") then
36 cline = cf.readLine()
37 clientData[key].name = cline
38 elseif (cline == "balance") then
39 cline = cf.readLine()
40 clientData[key].balance = tonumber(cline)
41 elseif (cline == "color") then
42 cline = cf.readLine()
43 clientData[key].color = tonumber(cline)
44 end
45 cline = cf.readLine()
46 until cline == nil or cline == ""
47 cf.close()
48
49 line = f.readLine()
50 until line == nil or line == ""
51 f.close()
52 end
53end
54
55local function getClientData(data)
56 loadClients()
57 return true, clientData
58end
59
60local function updateClientFile(key)
61 local f = fs.open(filePath.."clientData/"..key.."/info.txt", "w")
62 if (f == nil) then return false, text_error_account end
63
64 f.writeLine("name")
65 f.writeLine(clientData[key].name)
66 f.writeLine("balance")
67 f.writeLine(tostring(clientData[key].balance))
68 f.writeLine("color")
69 f.writeLine(tostring(clientData[key].color))
70 f.close()
71
72 return true, text_success_update
73end
74
75local function appendTransactionToLog(from, to, amount, balance, time, description)
76 local f = fs.open(filePath.."clientData/"..from.."/log.txt", "a")
77 f.writeLine("other")
78 f.writeLine(to)
79 f.writeLine("amount")
80 f.writeLine(tostring(-amount))
81 f.writeLine("balance")
82 f.writeLine(tostring(balance))
83 f.writeLine("time")
84 f.writeLine(time)
85 f.writeLine("description")
86 f.writeLine(description)
87 f.writeLine("")
88 f.close()
89end
90
91local function getCurrentTime()
92 return "--/--/---- --:--"
93end
94
95-- Move money from one account to another
96local function transaction(data) --from, to, amount, description
97 local from = data.from
98 local to = data.to
99 local amount = tonumber(data.amount)
100 local description = data.description
101
102 if (amount == 0 or amount == nil) then
103 return false, text_error_invalidamount
104 end
105
106 loadClients()
107
108 if (from == to) then
109 return false, text_error_same
110 end
111 if (not clientData[from]) then
112 return false, text_error_from.." ("..from..")"
113 end
114 if (not clientData[to]) then
115 return false, text_error_to.." ("..to..")"
116 end
117
118 local previousFromBalance = clientData[from].balance
119 local newFromBalance = previousFromBalance-amount
120
121 if (newFromBalance < 0) then
122 return false, text_error_notenoughbalance
123 end
124
125 local previousToBalance = clientData[to].balance
126 local newToBalance = previousToBalance+amount
127 local time = getCurrentTime()
128
129 clientData[from].balance = newFromBalance
130 updateClientFile(from)
131 clientData[to].balance = newToBalance
132 updateClientFile(to)
133
134 appendTransactionToLog(from, to, amount, newFromBalance, time,description)
135 appendTransactionToLog(to, from, -amount, newToBalance, time, description)
136
137 return true, text_success_transaction
138end
139
140local function deposit(data) --key, amount
141 local key = data.key
142 local amount = tonumber(data.amount)
143 local description = "Depósito"
144
145 if (amount == 0 or amount == nil) then
146 return false, text_error_invalidamount
147 end
148
149 loadClients()
150
151 if (clientData[key] == nil) then
152 return false, text_error_from.." ("..key..")"
153 end
154
155 local previousBalance = clientData[key].balance
156 local newBalance = previousBalance+amount
157
158 local time = getCurrentTime()
159
160 print(clientData[key].name.." ha depositado "..amount)
161
162 clientData[key].balance = newBalance
163 updateClientFile(key)
164
165 appendTransactionToLog(key, key, amount, newBalance, time, description)
166
167 return true, text_success_transaction
168end
169
170local function withdraw(data) --key, amount
171 local key = data.key
172 local amount = tonumber(data.amount)
173 local description = "Retiro"
174
175 if (amount == 0 or amount == nil) then
176 return false, text_error_invalidamount
177 end
178
179 loadClients()
180
181 if (key == nil or clientData[key] == nil) then
182 return false, text_error_from.." ("..tostring(key)..")"
183 end
184
185 local previousBalance = clientData[key].balance
186 local newBalance = previousBalance-amount
187
188 if (newBalance < 0) then
189 return false, text_error_notenoughbalance
190 end
191
192 local time = getCurrentTime()
193
194 clientData[key].balance = newBalance
195 updateClientFile(key)
196
197 appendTransactionToLog(key, key, -amount, newBalance, time, description)
198
199 return true, text_success_transaction
200end
201
202local function getTransactionLog(data) --key
203 local key = data.key
204
205 local log = {}
206 local logCounter = 1
207 local f = fs.open(filePath.."clientData/"..key.."/log.txt", "r")
208 local line = f.readLine()
209 while line ~= nil do
210 local lline = line
211 local other = ""
212 local amount = 0
213 local balance = 0
214 local time = ""
215 local description = ""
216
217 while lline ~= "" and lline ~= nil do
218 if (lline == "other") then
219 other = f.readLine()
220 elseif (lline == "amount") then
221 amount = f.readLine()
222 elseif (lline == "balance") then
223 balance = f.readLine()
224 elseif (lline == "time") then
225 time = f.readLine()
226 elseif (lline == "description") then
227 description = f.readLine()
228 end
229 lline = f.readLine()
230 end
231
232 log[logCounter] = {
233 ["other"] = other,
234 ["amount"] = amount,
235 ["balance"] = balance,
236 ["time"] = time,
237 ["description"] = description
238 }
239
240 logCounter = logCounter+1
241
242 line = f.readLine()
243 end
244
245 return true, log
246end
247
248-- Create a new client, with its files and folders, given a name, a starting balance and a color
249local function newClient(data) --name, balance, color
250 local name = data.name
251 local color = data.color
252
253 local bankKey = "1000"
254
255 local firstFreeClientNumber = 0
256 while firstFreeClientNumber < 9999 do
257 firstFreeClientNumber = firstFreeClientNumber+1
258 local free = true
259 for k, v in pairs(clientData) do
260 local clientNumber = tonumber(string.sub(k, 5, 8))
261 if (clientNumber == firstFreeClientNumber) then
262 free = false
263 break
264 end
265 end
266 if (free) then
267 break
268 end
269 end
270
271 local clientNumber = tostring(firstFreeClientNumber)
272 clientNumber = string.rep("0", 4-string.len(clientNumber))..clientNumber
273 local randomKey = ""
274 for i=1, 8 do
275 randomKey = randomKey..tostring(math.random(10)-1)
276 end
277 local key = bankKey..clientNumber..randomKey
278
279 local f = fs.open(filePath.."clientList.txt", "a")
280 f.writeLine(key)
281 f.close()
282
283 fs.makeDir(filePath.."clientData")
284 fs.makeDir(filePath.."clientData/"..key)
285
286 -- Create basic info
287 clientData[key] = {
288 ["name"] = name,
289 ["balance"] = 0,
290 ["color"] = color
291 }
292 updateClientFile(key)
293
294 -- Create transaction log
295 local f = fs.open(filePath.."clientData/"..key.."/log.txt", "w")
296 f.close()
297
298 return true, "Cuenta creada con exito"
299end
300
301local function deleteAccount(data) --key
302 local key = data.key
303
304 clientData[key] = nil
305 local f = fs.open(filePath.."clientList.txt", "w")
306 for k, v in pairs(clientData) do
307 f.writeLine(k)
308 end
309 f.close()
310 fs.delete(filePath.."clientData/"..key)
311 return true, "Cuenta borrada"
312end
313
314local function getAPIVersion(data)
315
316 local f = fs.open(filePath.."apiversion.txt", "r")
317 if (f == nil) then
318 return false, nil
319 end
320 local version = f.readLine()
321 local pastebin = f.readLine()
322 f.close()
323
324 return true, {["version"] = version, ["pastebin"] = pastebin}
325end
326
327local function getATMVersion(data)
328
329 local f = fs.open(filePath.."atmversion.txt", "r")
330 if (f == nil) then
331 return false, nil
332 end
333 local version = f.readLine()
334 local pastebin = f.readLine()
335 f.close()
336
337 return true, {["version"] = version, ["pastebin"] = pastebin}
338end
339
340local function processRequest(func, sender, data)
341 local success, response = func(data)
342 local message = {
343 ["success"] = success,
344 ["response"] = response
345 }
346 --print("Responding.")
347 rednet.send(sender, message, "mermegold")
348end
349
350---------------- Start
351loadClients()
352rednet.open(modemSide)
353
354while true do
355 local sender, message = rednet.receive("mermegold")
356 --term.write("#"..sender.." requested "..message.action..". ")
357
358 if (message.action == "getClientData") then --------------- Get Client Data
359 processRequest(getClientData, sender, message)
360
361 elseif (message.action == "getTransactionLog") then ------- Get Transaction Log
362 processRequest(getTransactionLog, sender, message)
363
364 elseif (message.action == "transaction") then ------------- Make a transaction
365 processRequest(transaction, sender, message)
366
367 elseif (message.action == "deposit") then ----------------- Make a deposit
368 processRequest(deposit, sender, message)
369
370 elseif (message.action == "withdraw") then ------------- Make a withdrawal
371 processRequest(withdraw, sender, message)
372
373 elseif (message.action == "new") then --------------------- Create an account
374 processRequest(newClient, sender, message)
375
376 elseif (message.action == "delete") then ------------------ Delete an account
377 processRequest(deleteAccount, sender, message)
378
379 elseif (message.action == "getAPIVersion") then ----------- Get API Version
380 processRequest(getAPIVersion, sender, message)
381
382 elseif (message.action == "getATMVersion") then ----------- Get ATM Version
383 processRequest(getATMVersion, sender, message)
384
385 else ------------------------------------------------------ Not a valid message
386 --print("No valid response.")
387 local message = {
388 ["success"] = false,
389 ["response"] = "Invalid request"
390 }
391 rednet.send(sender, message, "mermegold")
392 end
393end