Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local serial = require('serialization')
- local event = require('event')
- local term = require('term')
- local fs = require('filesystem')
- local com = require('component')
- local mgpu = com.gpu
- -- Таблица констант --
- PORT = 72
- DEFAULT_CASH = 1000000 -- $
- BUFFER = 5
- -- Таблица цветов --
- forecolor = 0xFFFFFF
- backcolor = 0x000000
- allowcolor = 0x00FF00
- errorcolor = 0xFF0000
- warncolor = 0xCCCC00
- infocolor = 0x398eb5
- -- Коды операций --
- CHANGE_PORT = 0x1
- ADD_ACCOUNT = 0x2
- DEL_ACCOUNT = 0x3
- REMITTANCE = 0x4
- ACC_REQUEST = 0x5
- CSH_REQUEST = 0x6
- SET_ACCOUNT = 0x7
- -- Коды ошибок --
- WRONG_PORT = 0xF1
- ANSWER_YES = 0xF2
- ANSWER_NO = 0xF3
- WRONG_CRED = 0xF4
- TOO_LITTLE = 0xF5
- --
- function trytofind(name)
- if com.isAvailable(name) then
- return com.getPrimary(name)
- else
- return nil
- end
- end
- term.clear()
- function errout(message)
- mgpu.setForeground(errorcolor)
- print('[ERROR] '..message)
- mgpu.setForeground(forecolor)
- end
- function warnout(message)
- mgpu.setForeground(warncolor)
- print('[WARNING] '..message)
- mgpu.setForeground(forecolor)
- end
- function infout(message)
- mgpu.setForeground(infocolor)
- print('[INFO] '..message)
- mgpu.setForeground(forecolor)
- end
- function helpout(message)
- mgpu.setForeground(allowcolor)
- print(message)
- mgpu.setForeground(forecolor)
- end
- local modem = trytofind('modem')
- if modem == nil then
- errout('Вы прикалываетесь? Финансовый сервер без модема?')
- return
- end
- -- ======================================== L I S T M A N A G E R S ======================================== --
- function readList(filename)
- if fs.exists(filename) then
- local file = io.open(filename, "r")
- local data = file:read("*a")
- local list = serial.unserialize(data)
- file:close()
- helpout("База данных загружена.")
- return list
- else
- warnout("Файл "..filename.." не найден, создан пустой список!")
- return {}
- end
- end
- function saveList(list, filename)
- local file = io.open(filename, "w")
- data = serial.serialize(list)
- file:write(data)
- file:close()
- helpout("База данных сохранена.")
- end
- local opcounter = 0
- function toList(list, name, data)
- if data == nil then data = true end
- list[name] = data
- -- резервное сохранение данных каждые BUFFER операций
- opcounter = opcounter + 1
- if opcounter > BUFFER then
- saveList(database, 'database.tot')
- opcounter = 0
- end
- return true
- end
- function fromList(list, name)
- if list[name] then
- list[name] = nil
- -- резервное сохранение данных каждые BUFFER операций
- opcounter = opcounter + 1
- if opcounter > BUFFER then
- saveList(database, 'database.tot')
- opcounter = 0
- end
- return true
- end
- return false
- end
- function contains(list, name)
- return list[name] ~= nil
- end
- function printlist(list)
- if next(list) == nil then print("Таблица пуста.")
- else
- c = 1
- for a,b in pairs(list) do
- print(a, serial.serialize(b))
- c = c + 1
- if c > height-3 then
- print("Любая клавиша для продолжения...")
- event.pull('key_down')
- c = 1
- end
- end
- end
- end
- -- ========================================= N E T P A C K A G E S ========================================= --
- function send(data)
- local message = data
- if type(message) == 'table' then
- message = serial.serialize(message)
- end
- if answer_address ~= nil then
- modem.broadcast(current_port, message)
- else
- modem.send(answer_address, current_port, message)
- end
- end
- -- ==================================== F I N A N C E F U N C T I O N S ==================================== --
- function addAccount(name, amount)
- if name == nil then return false
- elseif contains(database, name) then return false
- else
- local cash = amount
- if cash == nil or cash < 0 then cash = DEFAULT_CASH end
- toList(database, name, cash)
- return true
- end
- end
- -- Инициализация
- database = readList('database.tot')
- modem.open(PORT)
- current_port = PORT
- answer_address = nil
- infout('Сервер запущен. Ожидание запросов...')
- --
- while true do
- name, _, answer_address, _, _, message = event.pull(10)
- if name == 'modem_message' then
- data = serial.unserialize(message)
- if data.code == CHANGE_PORT then
- -- изменяем рабочий порт
- if data.port == nil or data.port < 1 or data.port > 65535 then
- send(WRONG_PORT)
- else
- modem.close()
- modem.open(data.port)
- current_port = data.port
- send(ANSWER_YES)
- end
- elseif data.code == ADD_ACCOUNT then
- -- создаем новую запись
- if addAccount(data.name, data.amount) then
- send(ANSWER_YES)
- else
- send(WRONG_CRED)
- end
- elseif data.code == DEL_ACCOUNT then
- -- удаляем существующую учетку
- if data.name == nil or not contains(database, data.name) then
- send(WRONG_CRED)
- else
- fromList(database, data.name)
- send(ANSWER_YES)
- end
- elseif data.code == ACC_REQUEST then
- -- запрашиваем информацию о существовании аккаунта
- if data.name == nil then
- send(WRONG_CRED)
- else
- if contains(database, data.name) then send(ANSWER_YES)
- else send(ANSWER_NO) end
- end
- elseif data.code == REMITTANCE then
- -- пересылаем деньги со счета на счет
- if not contains(database, data.sender) then
- addAccount(data.sender)
- end
- if not contains(database, data.receiver) then
- addAccount(data.receiver)
- end
- if database[data.sender] < data.amount then
- send(TOO_LITTLE)
- else
- toList(database, data.sender, database[data.sender] - data.amount)
- toList(database, data.receiver, database[data.receiver] + data.amount)
- send(ANSWER_YES)
- end
- elseif data.code == CSH_REQUEST then
- -- запрашиваем состояние счета
- if data.name == nil then
- send({WRONG_CRED})
- else
- if not contains(database, data.name) then
- addAccount(data.name)
- end
- send({ANSWER_YES, database[data.name]})
- end
- elseif data.code == SET_ACCOUNT then
- -- устанавливаем состояние счета
- if data.name == nil then
- send(WRONG_CRED)
- elseif data.amount == nil or data.amount < 0 then
- send(ANSWER_NO)
- else
- if not contains(database, data.name) then
- addAccount(data.name)
- end
- toList(database, data.name, data.amount)
- send(ANSWER_YES)
- end
- end
- elseif name == 'key_down' then break end
- end
- -- Завершение
- saveList(database, 'database.tot')
- modem.close()
- warnout("Сервер остановлен. Все порты закрыты.")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement