Advertisement
Guest User

server.lua

a guest
Nov 30th, 2018
177
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 7.24 KB | None | 0 0
  1. local channels = {
  2.   atm = 1,
  3.   db = 2,
  4. }
  5.  
  6. os.loadAPI("/common.lua")
  7. os.loadAPI("/sha256.lua")
  8.  
  9. local database = {}
  10. local dbpath = "/bank.db"
  11. local logpath = "/bank.log"
  12. local maintenance_pass = "test"
  13. local modem = peripheral.find("modem")
  14.  
  15. local function loadDB(path)
  16.   local ret = {}
  17.   if fs.exists(path) then
  18.     local f = fs.open(path, "r")
  19.     local c = f.readAll()
  20.     ret = textutils.unserialise(c)
  21.     if not ret then return false end
  22.   end
  23.   return ret
  24. end
  25. local function saveDB(path, db)
  26.   local f = fs.open(path, "w")
  27.   local s = textutils.serialise(db)
  28.   f.write(s)
  29.   f.close()
  30.   return true
  31. end
  32. local function printHeader(str, ny)
  33.   local w, h = term.getSize()
  34.   local x, y = term.getCursorPos()
  35.   term.setCursorPos(math.ceil(w/2) - math.floor(#str/2), ny or 1)
  36.   term.clearLine()
  37.   term.write(str)
  38.   term.setCursorPos(x, y)
  39. end
  40. local logfile = fs.open(logpath, "a")
  41. local function log(top, str, nosave)
  42.   local form = (top and ("["..top.."] ") or "")..(str)
  43.   print(form)
  44.   printHeader("Database running with "..dbpath)
  45.   if not nosave then
  46.     logfile.writeLine(form)
  47.     logfile.flush()
  48.   end
  49. end
  50.  
  51. database = loadDB(dbpath)
  52. saveDB(dbpath, database)
  53.  
  54. modem.open(channels.db)
  55. term.clear()
  56. term.setCursorPos(1,2)
  57. logfile.writeLine()
  58. log("Init", "Database started")
  59.  
  60. while true do
  61.   local event, side, chan, reply, msg = os.pullEvent()
  62.   if event == "modem_message" and chan == channels.db and reply == channels.atm and type(msg) == "table" then
  63.  
  64.     if msg[1] == "auth" then
  65.       local user = msg[2]:lower()
  66.       local userdata = database[user]
  67.       if userdata then
  68.         modem.transmit(reply, channels.db, {true, userdata.salt})
  69.         local resp = common.waitForMsg(reply, 2)
  70.         if resp and resp[1] then
  71.           local ok = resp[2] == userdata.passwd
  72.           modem.transmit(reply, channels.db, {ok, not ok and "Wrong password" or nil})
  73.           log("Auth", (ok and "Valid" or "Invalid").." auth: "..user)
  74.         else log("Auth", user.." timed out")
  75.         end
  76.       else
  77.         log("Auth", "User not found: "..user)
  78.         modem.transmit(reply, channels.db, {false, "User not found"})
  79.       end
  80.  
  81.     elseif msg[1] == "register" then
  82.       local user = msg[2]:lower()
  83.       local ok = true
  84.       if user:find("%s") then ok = false log("Register", "Tried registering with a space: "..user) modem.transmit(reply, channels.db, {false, "Username cannot contain spaces"}) end
  85.       if database[user] then ok = false log("Register", "User already exists: "..user) modem.transmit(reply, channels.db, {false, "User already exists"}) end
  86.       if ok then
  87.         local salt = common.genSalt(16)
  88.         modem.transmit(reply, channels.db, {true, salt})
  89.         local r = common.waitForMsg(reply, 2)
  90.         if r and r[1] and type(r[2]) == "string" and #r[2] == 64 then
  91.           database[user] = {}
  92.           database[user].balance = 0
  93.           database[user].passwd = r[2]
  94.           database[user].salt = salt
  95.           saveDB(dbpath, database)
  96.           log("Register", user.." created")
  97.           modem.transmit(reply, channels.db, {true})
  98.         else
  99.           log("Register", user.." timed out")
  100.         end
  101.       end
  102.  
  103.     elseif msg[1] == "balance" then
  104.       local user = msg[2]:lower()
  105.       local userdata = database[user]
  106.       if msg[3] == userdata.passwd then
  107.         modem.transmit(reply, channels.db, {true, userdata.balance})
  108.         log("Balance", "Sent balance: "..user)
  109.       else
  110.         modem.transmit(reply, channels.db, {false, "Invalid hash"})
  111.         log("Balance", "Invalid hash from: "..user)
  112.       end
  113.  
  114.     elseif msg[1] == "transfer" then
  115.       local user = msg[2]:lower()
  116.       local recip = msg[4]:lower()
  117.       local hash = msg[3]
  118.       local amt = tonumber(msg[5]) or math.huge
  119.       amt = math.abs(amt)
  120.       local userdat = database[user]
  121.       local recipdat = database[recip]
  122.       local ok = true
  123.  
  124.       if not recipdat then ok = false log("Transfer", user.." tried to send to invalid: "..recip) modem.transmit(reply, channels.db, {false, "Recipient doesn't exist"}) end
  125.       if userdat.passwd ~= hash then ok = false log("Transfer", "Invalid hash from: "..user) modem.transmit(reply, channels.db, {false, "Invalid hash"}) end
  126.       if userdat.balance < amt then ok = false log("Transfer", user.." tried to send "..amt.." but has "..userdat.balance.." to "..recip) modem.transmit(reply, channels.db, {false, "Insufficent funds"}) end
  127.       if ok then
  128.         database[user].balance = userdat.balance - amt
  129.         database[recip].balance = recipdat.balance + amt
  130.         saveDB(dbpath, database)
  131.         modem.transmit(reply, channels.db, {true, userdat.balance})
  132.         log("Transfer", user.." transfered "..amt.." to "..recip)
  133.       end
  134.     end
  135.  
  136.   elseif event == "key" and side == keys.enter then
  137.     log("Admin", "Enter password")
  138.     write("> ")
  139.     local pswd = read("*")
  140.     if pswd == maintenance_pass then
  141.       log("Admin", "Entering maintenance mode")
  142.       while true do
  143.         write("> ")
  144.         local cmd = read()
  145.         cmd = common.split(cmd, "%s")
  146.         if cmd[1] == "set" then
  147.           local user = cmd[2]:lower()
  148.           local amt = tonumber(cmd[3]) or 0
  149.           if database[user] then
  150.             database[user].balance = amt
  151.             saveDB(dbpath, database)
  152.             log("Admin", "Set "..user.." balance to "..amt)
  153.           else
  154.             log("Admin", "Cannot set balance of "..user)
  155.           end
  156.  
  157.         elseif cmd[1] == "add" then
  158.           local user = cmd[2]:lower()
  159.           local amt = tonumber(cmd[3]) or 0
  160.           if database[user] then
  161.             database[user].balance = database[user].balance + amt
  162.             saveDB(dbpath, database)
  163.             log("Admin", (amt >= 0 and "Added " or "Removed ")..amt.." to "..user.."'s balance")
  164.           else
  165.             log("Admin", "Cannot add to balance of "..user)
  166.           end
  167.  
  168.         elseif cmd[1] == "delete" then
  169.           local user = cmd[2]:lower()
  170.           if database[user] then
  171.             database[user] = nil
  172.             saveDB(dbpath, database)
  173.             log("Admin", user.." deleted from database")
  174.           else
  175.             log("Admin", "Tried to delete invalid user: "..user)
  176.           end
  177.  
  178.         elseif cmd[1] == "list" then
  179.           local users = {}
  180.           for user, userdat in pairs(database) do
  181.             log(nil, user..": "..userdat.balance, true)
  182.           end
  183.         elseif cmd[1] == "help" then
  184.           log(nil, "set <user> <balance> -- Sets a users balance", true)
  185.           log(nil, "add <user> <+/- amount> -- Add or remove from user balance", true)
  186.           log(nil, "delete <user> -- Removes an account from the database", true)
  187.           log(nil, "list -- Lists accounts", true)
  188.           log(nil, "quit -- Quits maintenance mode", true)
  189.           log(nil, "stop -- Stops the database", true)
  190.  
  191.         elseif cmd[1] == "quit" then break
  192.         elseif cmd[1] == "stop" then return
  193.  
  194.         else log("Command", "Invalid command: "..(cmd[1] or ""), true)
  195.         end
  196.         repeat event, side = os.pullEvent("key") until side == keys.enter
  197.       end
  198.       log("Admin", "Exiting maintenance")
  199.     else
  200.       log("Admin", "Wrong password")
  201.     end
  202.   end
  203. end
  204. log("Admin", "Database shutting down")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement