Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --Variables
- version = "0.1"
- --The 2 holy protocols
- messageProtocol = "csIRC_msg"
- authProtocol = "csIRC_auth"
- clientProtocol = "csIRC_client"
- --Client will have to use this format, otherwise the message will be discarded
- --Message protocol format: "msg:*message here*"
- --Auth protocol format: "type:*type of auth here, there are 3 possible ones: reg, login, logout*, user:*name of the user, always needed*, pass:*password of the user, not needed in logouts*"
- msgPrefix = "msg:"
- authTypePrefix = "type:"
- authUserPrefix = "user:"
- authPassPrefix = "pass:"
- authTokenPrefix = "token:"
- --Auth type prefixes
- authRegPrefix = "reg"
- authLoginPrefix = "login"
- authLogoutPrefix = "logout"
- InfoCOLOR = colors.white
- WarningCOLOR = colors.yellow
- ErrorCOLOR = colors.red
- --User file property strings
- userNameKey = "user"
- passKey = "pass"
- IDKey = "ID"
- loggingFOLDER = "serverLogs"
- loggingENABLED = true
- usersFolder = "Users"
- --The logged in users are stored in the loggedUsers 2D array (user ID/token)
- loggedUsers = {}
- --Functions
- function printMSG(message, color)
- prefixedMessage = os.time()..message
- LogMessage(prefixedMessage)
- term.setTextColor(color)
- print(prefixedMessage)
- end
- function infoMSG(message)
- printMSG("[INFO]: "..message,InfoCOLOR)
- end
- function warningMSG(message)
- printMSG("[WARNING]: "..message,WarningCOLOR)
- end
- function errorMSG(message)
- printMSG("[ERROR]: "..message,ErrorCOLOR)
- end
- function LogMessage(message)
- if loggingENABLED == true then logfileHandle.writeLine(message) end
- end
- function GetFileValue(file, key)
- if file ~= nil and key ~= nil then
- local handle = fs.open(file,"r")
- if handle ~= nil then
- while true do
- local line = handle.readLine()
- if line == nil then
- handle.close()
- return nil
- end
- if string.find(line, key) ~= nil then
- handle.close()
- return string.sub(line, string.len(key) + 2)--2 because the first is the last letter of the key and the second is the = symbol
- end
- end
- end
- end
- end
- function SetFileValue(file, key, value)
- local handle = fs.open(file,"r")
- local allLines = {}
- if handle ~= nil then
- while true do
- currentLine = handle.readLine()
- if currentLine == nil then break end
- table.insert(allLines, currentLine)
- end
- local isValueFound = false
- for i, line in ipairs(allLines) do
- if string.find(line, key) ~= nil then
- line = key.."="..value
- isValueFound = true
- end
- end
- end
- handle = fs.open(file, "w")
- if allLines ~= nil then
- for i, line in ipairs(allLines) do
- handle.writeLine(line)
- end
- end
- if isValueFound == false or isValueFound == nil then handle.writeLine(key.."="..value) end
- handle.close()
- end
- function GenerateLoginToken()
- local token
- while true do
- token = tostring(math.random(1000000,9999999))
- if FindUserByToken(token) == nil then return token end
- end
- end
- function FindUserByName(username) -- Finds the user and returns the directory of the user so that you can open a handle to it
- AllUsers = fs.find(usersFolder.."/*")
- for i, user in ipairs(AllUsers) do
- foundLine = GetFileValue(user, userNameKey)
- if foundLine ~= nil then
- if foundLine == username then return user end
- end
- end
- return nil
- end
- function FindUserByID(ID)
- AllUsers = fs.find(usersFolder.."/*")
- for i, user in ipairs(AllUsers) do
- foundLine = GetFileValue(user, IDString)
- if foundLine ~= nil then
- if foundLine == ID then return user end
- end
- end
- return nil
- end
- function FindUserByToken(token)
- for i, id in ipairs(loggedUsers) do
- if loggedUsers[i][1] == token then return FindUserByID(id) end
- end
- return nil
- end
- function CreateUser(username, password)
- if FindUserByName(username) == nil then
- if string.len(username) <= 16 then
- if password ~= nil then
- while userID == nil do
- userID = math.random(100000,999999)--Create a new id
- if FindUserByID(userID) == nil then break end
- end
- local newFile = usersFolder.."/"..tostring(math.random(0,1000000))
- SetFileValue(newFile, userNameKey, username)
- SetFileValue(newFile, passKey, password)
- SetFileValue(newFile, IDKey, userID)
- infoMSG("User created. ID: "..userID.." / Username: "..username.." / Password: "..password)
- return userID
- end
- end
- end
- return nil
- end
- function LoginUser(username, password)
- local FoundUser = FindUserByName(username)
- if FoundUser ~= nil then
- --Check password
- if password == GetFileValue(FoundUser,passKey) then
- newToken = GenerateLoginToken()
- print(#loggedUsers)
- print(#loggedUsers + 1)
- loggedUsers[#loggedUsers + 1] = {}
- loggedUsers[1] = {GetFileValue(FoundUser, IDKey), newToken}
- infoMSG("User logged in. Username: "..username.." / Token: "..newToken)
- return newToken
- end
- end
- return nil
- end
- function LogoutUser(username, token)--Token used for verification, since a single username could just log people out
- local FoundUser = FindUserByName(username)
- local userID = GetFileValue(FoundUser, IDKey)
- for i, value in ipairs(loggedUsers) do
- if userID == value then
- if loggedUsers[i][1] == token then--Token verification
- table.remove(loggedUsers, i)
- end
- end
- end
- end
- function InitLogging()
- if fs.exists(loggingFOLDER) == false then
- fs.makeDir(loggingFOLDER)
- end
- if fs.exists(loggingFOLDER.."/latest.log") == true then
- fs.move(loggingFOLDER.."/latest.log", loggingFOLDER.."/"..os.day().." "..os.time()..".log")
- end
- logfileHandle = fs.open(loggingFOLDER.."/latest.log","w")
- logfileHandle.writeLine("--Logging started--")
- infoMSG("Logger initialized")
- end
- function InitServer()
- term.clear()
- term.setCursorPos(1,1)
- if loggingENABLED == true then
- InitLogging()
- end
- local rnSides = {"top","bottom","left","right","front","back"}
- infoMSG("Checking for rednet modem")
- local rednetFoundFlag = false
- for i, side in ipairs(rnSides) do
- if rednetFoundFlag == false then
- if peripheral.getType(side) == "modem" then
- rednet.open(side)
- rednetFoundFlag = true
- infoMSG("Rednet modem turned on")
- end
- end
- end
- if rednetFoundFlag == false then
- --Error out of the program because of missing modem
- errorMSG("Modem not found")
- error()
- end
- infoMSG("Server initialized")
- infoMSG("IRC Server running on version "..version)
- end
- function ShutdownServer()
- infoMSG("Shutting down server..")
- logfileHandle.close()
- end
- --Main
- InitServer()
- while true do
- local event, p1, p2, p3 = os.pullEvent()
- if event == "key" then
- if p1 == keys.e then
- ShutdownServer()
- break
- end
- end
- if event == "rednet_message" then
- if p3 == authProtocol then
- local authPrefixStart, authPrefixEnd = string.find(p2,authTypePrefix)
- local authUserPrefixStart, authUserPrefixEnd = string.find(p2,authUserPrefix)
- if authPrefixStart ~= nil and authPrefixEnd ~= nil and authUserPrefixStart ~= nil and authUserPrefixEnd ~= nil then --Check if the prefix actually exists
- local operationType = string.sub(p2, authPrefixEnd + 1, string.find(p2, ",", authPrefixEnd) - 1)
- local authUser = string.sub(p2, authUserPrefixEnd + 1, string.find(p2, ",", authUserPrefixEnd) - 1)
- --Put the logging out here because the password is still not checked for here
- if operationType == authLogoutPrefix then
- local authTokenPrefixStart, authTokenPrefixEnd = string.find(p2, authTokenPrefix)
- if authTokenPrefixStart ~= nil and authTokenPrefixEnd ~= nil then
- local authToken = string.sub(p2, authTokenPrefixEnd + 1)
- LogoutUser(authUser, authToken)
- end
- end
- local authPassPrefixStart, authPassPrefixEnd = string.find(p2, authPassPrefix)
- if authPassPrefixStart ~= nil and authPassPrefixEnd ~= nil then
- local authPass = string.sub(p2, authPassPrefixEnd + 1)
- if operationType == authRegPrefix then
- if CreateUser(authUser, authPass) ~= nil then
- rednet.send(p1,"reg_success",clientProtocol)
- end
- end
- if operationType == authLoginPrefix then
- loginToken = LoginUser(authUser, authPass)
- print(loginToken)
- if loginToken ~= nil then
- rednet.send(p1,loginToken)
- end
- end
- end
- end
- end
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement