Advertisement
MoonlightOwl

Finance Server

Nov 11th, 2014
179
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 7.20 KB | None | 0 0
  1. local serial = require('serialization')
  2. local event = require('event')
  3. local term = require('term')
  4. local fs = require('filesystem')
  5. local com = require('component')
  6. local mgpu = com.gpu
  7.  
  8. -- Таблица констант --
  9. PORT = 72
  10. DEFAULT_CASH = 1000000 -- $
  11. BUFFER = 5
  12.  
  13. --  Таблица цветов  --
  14. forecolor  = 0xFFFFFF
  15. backcolor  = 0x000000
  16. allowcolor = 0x00FF00
  17. errorcolor = 0xFF0000
  18. warncolor = 0xCCCC00
  19. infocolor = 0x398eb5
  20.  
  21. --  Коды операций   --
  22. CHANGE_PORT = 0x1
  23. ADD_ACCOUNT = 0x2
  24. DEL_ACCOUNT = 0x3
  25. REMITTANCE  = 0x4
  26. ACC_REQUEST = 0x5
  27. CSH_REQUEST = 0x6
  28. SET_ACCOUNT = 0x7
  29.  
  30. --   Коды ошибок    --
  31. WRONG_PORT = 0xF1
  32. ANSWER_YES = 0xF2
  33. ANSWER_NO  = 0xF3
  34. WRONG_CRED = 0xF4
  35. TOO_LITTLE = 0xF5
  36. --
  37.  
  38. function trytofind(name)
  39.   if com.isAvailable(name) then
  40.     return com.getPrimary(name)
  41.   else
  42.     return nil
  43.   end
  44. end
  45.  
  46. term.clear()
  47. function errout(message)
  48.   mgpu.setForeground(errorcolor)
  49.   print('[ERROR] '..message)
  50.   mgpu.setForeground(forecolor)
  51. end
  52. function warnout(message)
  53.   mgpu.setForeground(warncolor)
  54.   print('[WARNING] '..message)
  55.   mgpu.setForeground(forecolor)
  56. end
  57. function infout(message)
  58.   mgpu.setForeground(infocolor)
  59.   print('[INFO] '..message)
  60.   mgpu.setForeground(forecolor)
  61. end
  62. function helpout(message)
  63.   mgpu.setForeground(allowcolor)
  64.   print(message)
  65.   mgpu.setForeground(forecolor)
  66. end
  67.  
  68. local modem = trytofind('modem')
  69.  
  70. if modem == nil then
  71.   errout('Вы прикалываетесь? Финансовый сервер без модема?')
  72.   return
  73. end
  74.  
  75. -- ======================================== L I S T   M A N A G E R S ======================================== --
  76. function readList(filename)
  77.   if fs.exists(filename) then
  78.     local file = io.open(filename, "r")
  79.     local data = file:read("*a")
  80.     local list = serial.unserialize(data)
  81.     file:close()
  82.     helpout("База данных загружена.")
  83.     return list
  84.   else
  85.     warnout("Файл "..filename.." не найден, создан пустой список!")
  86.     return {}
  87.   end
  88. end
  89. function saveList(list, filename)
  90.   local file = io.open(filename, "w")
  91.   data = serial.serialize(list)
  92.   file:write(data)
  93.   file:close()
  94.   helpout("База данных сохранена.")
  95. end
  96. local opcounter = 0
  97. function toList(list, name, data)
  98.   if data == nil then data = true end
  99.   list[name] = data
  100.   -- резервное сохранение данных каждые BUFFER операций
  101.   opcounter = opcounter + 1
  102.   if opcounter > BUFFER then
  103.     saveList(database, 'database.tot')
  104.     opcounter = 0
  105.   end
  106.   return true
  107. end
  108. function fromList(list, name)
  109.   if list[name] then
  110.     list[name] = nil
  111.     -- резервное сохранение данных каждые BUFFER операций
  112.     opcounter = opcounter + 1
  113.     if opcounter > BUFFER then
  114.       saveList(database, 'database.tot')
  115.       opcounter = 0
  116.     end
  117.     return true
  118.   end
  119.   return false
  120. end
  121. function contains(list, name)
  122.   return list[name] ~= nil
  123. end
  124. function printlist(list)
  125.   if next(list) == nil then print("Таблица пуста.")
  126.   else
  127.     c = 1
  128.     for a,b in pairs(list) do
  129.       print(a, serial.serialize(b))
  130.       c = c + 1
  131.       if c > height-3 then
  132.         print("Любая клавиша для продолжения...")
  133.         event.pull('key_down')
  134.         c = 1
  135.       end
  136.     end
  137.   end
  138. end
  139.  
  140. -- ========================================= N E T   P A C K A G E S ========================================= --
  141. function send(data)
  142.   local message = data
  143.   if type(message) == 'table' then
  144.     message = serial.serialize(message)
  145.   end
  146.   if answer_address ~= nil then
  147.     modem.broadcast(current_port, message)
  148.   else
  149.     modem.send(answer_address, current_port, message)
  150.   end
  151. end
  152.  
  153. -- ==================================== F I N A N C E   F U N C T I O N S ==================================== --
  154. function addAccount(name, amount)
  155.   if name == nil then return false
  156.   elseif contains(database, name) then return false
  157.   else
  158.     local cash = amount
  159.     if cash == nil or cash < 0 then cash = DEFAULT_CASH end
  160.     toList(database, name, cash)
  161.     return true
  162.   end
  163. end
  164.  
  165.  
  166. -- Инициализация
  167. database = readList('database.tot')
  168. modem.open(PORT)
  169. current_port = PORT
  170. answer_address = nil
  171.  
  172. infout('Сервер запущен. Ожидание запросов...')
  173. --
  174. while true do
  175.   name, _, answer_address, _, _, message  = event.pull(10)
  176.   if name == 'modem_message' then
  177.     data = serial.unserialize(message)
  178.     if data.code == CHANGE_PORT then
  179.       -- изменяем рабочий порт
  180.       if data.port == nil or data.port < 1 or data.port > 65535 then
  181.         send(WRONG_PORT)
  182.       else
  183.         modem.close()
  184.         modem.open(data.port)
  185.         current_port = data.port
  186.         send(ANSWER_YES)
  187.       end
  188.     elseif data.code == ADD_ACCOUNT then
  189.       -- создаем новую запись
  190.       if addAccount(data.name, data.amount) then
  191.         send(ANSWER_YES)
  192.       else
  193.         send(WRONG_CRED)
  194.       end
  195.     elseif data.code == DEL_ACCOUNT then
  196.       -- удаляем существующую учетку
  197.       if data.name == nil or not contains(database, data.name) then
  198.         send(WRONG_CRED)
  199.       else
  200.         fromList(database, data.name)
  201.         send(ANSWER_YES)
  202.       end
  203.     elseif data.code == ACC_REQUEST then
  204.       -- запрашиваем информацию о существовании аккаунта
  205.       if data.name == nil then
  206.         send(WRONG_CRED)
  207.       else
  208.         if contains(database, data.name) then send(ANSWER_YES)
  209.         else send(ANSWER_NO) end
  210.       end
  211.     elseif data.code == REMITTANCE then
  212.       -- пересылаем деньги со счета на счет
  213.       if not contains(database, data.sender) then
  214.         addAccount(data.sender)
  215.       end
  216.       if not contains(database, data.receiver) then
  217.         addAccount(data.receiver)
  218.       end
  219.       if database[data.sender] < data.amount then
  220.         send(TOO_LITTLE)
  221.       else
  222.         toList(database, data.sender, database[data.sender] - data.amount)
  223.         toList(database, data.receiver, database[data.receiver] + data.amount)
  224.         send(ANSWER_YES)
  225.       end
  226.     elseif data.code == CSH_REQUEST then
  227.       -- запрашиваем состояние счета
  228.       if data.name == nil then
  229.         send({WRONG_CRED})
  230.       else
  231.         if not contains(database, data.name) then
  232.           addAccount(data.name)
  233.         end
  234.         send({ANSWER_YES, database[data.name]})
  235.       end
  236.     elseif data.code == SET_ACCOUNT then
  237.       -- устанавливаем состояние счета
  238.       if data.name == nil then
  239.         send(WRONG_CRED)
  240.       elseif data.amount == nil or data.amount < 0 then
  241.         send(ANSWER_NO)
  242.       else
  243.         if not contains(database, data.name) then
  244.           addAccount(data.name)
  245.         end
  246.         toList(database, data.name, data.amount)
  247.         send(ANSWER_YES)
  248.       end
  249.     end
  250.   elseif name == 'key_down' then break end
  251. end
  252.  
  253. -- Завершение
  254. saveList(database, 'database.tot')
  255. modem.close()
  256.  
  257. warnout("Сервер остановлен. Все порты закрыты.")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement