Advertisement
Guest User

server

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