local chats = {} -- File path for saving chats filePath = "chats.txt" userFilePath = "users.txt" adminu = "username" adminp = "password" local function getFirstWord(str) local firstWord = str:match("^(%S+)") return firstWord end function twoInputStrip(str) first, second = str:match("(%S+)%s+(%S+)") return first, second end function threeInputStrip(str) first, second, third = str:match("(%S+)%s+(%S+)%s+(%S+)") return first, second, third end function fourInputStrip(str) local first, second, third, fourth = str:match("(%S+)%s+(%S+)%s+(%S+)%s+(.*)") return first, second, third, fourth end local function cutSpaces(str) local substrings = {} for substring in str:gmatch("%S+") do table.insert(substrings, substring) end return substrings end -- Function to save chats to a file local function saveChats() local file = fs.open(filePath, "w") file.write(textutils.serialize(chats)) file.close() print("Chats saved.") end -- Function to print the first key of each sub-array local function getChannelIds() chatnames = {} for _, subArray in ipairs(chats) do for chatname, _ in pairs(subArray) do print(chatname) table.insert(chatnames, chatname) break -- Only print the first key end end return chatnames end -- Function to save chats to a file local function addUser(user, userID) local file = fs.open(userFilePath, "a") file.writeLine(user .. " " .. userID) file.close() print("Users saved.") end -- Function to save chats to a file local function removeUser(user, userID) success = false if fs.exists(userFilePath) then local file = fs.open(userFilePath, "r") local line = file.readLine() while line do print(line) name = twoInputStrip(line) if name == user then success = true else table.insert(newfile, line) end line = file.readLine() end file.close() file = fs.open(userFilePath, "w") for _, line in pairs(newfile) do file.writeLine(line) end file.close() end return success end local function findUser(user) if fs.exists(userFilePath) then local file = fs.open(userFilePath, "r") if file then line = file.readLine() while line do local name, nid = twoInputStrip(line) if name ~= nil and name == user then file.close() return nid end line = file.readLine() end file.close() end end return nil end local function checkChat(chat, ruser) users = cutSpaces(chat[1]) for _, user in pairs(users) do if user == ruser then return true end end return false end local function getUsersChats(chats, newruser) userchats = {} newid = findUser(newruser) if newid == nil then return "no" end for chatname, array in pairs(chats) do if checkChat(chats[chatname], newruser) then table.insert(userchats, chatname) end end if userchats == nil then return "none" else return userchats end return nil end local function ping(chatID) users = cutSpaces(chats[chatID][1]) for _, user in pairs(users) do userid = findUser(user) if userid ~= nil then rednet.send(tonumber(userid), "update") end end end -- Function to load chats from a file local function loadChats() if fs.exists(filePath) then local file = fs.open(filePath, "r") local content = file.readAll() chats = textutils.unserialize(content) or {} file.close() print("Chats loaded.") return chats else print("No saved chats found.") return nil end end -- Function to handle creating a new chat local function handleCreateChat(chatID, username) if not chats[chatID] and username ~= nil then chats[chatID] = {username .. " "} print("Chat " .. chatID .. " created.") saveChats() return "true" else print("Chat " .. chatID .. " already exists.") return "exists" end end -- Function to save chats to a file local function handleAddUser(user, chatID) if chats[chatID] then chats[chatID][1] = chats[chatID][1] .. user .. " " local wfile = fs.open(filePath, "w") wfile.write(textutils.serialize(chats)) wfile.close() return "true" end return nil end -- Function to save chats to a file local function handleRemoveUser(username, ruser, chatID) print(chats[chatID][1]) owner = getFirstWord(chats[chatID][1]) if owner ~= nil and owner == username then if chats[chatID] then users = cutSpaces(chats[chatID][1]) for _, user in pairs(users) do if user == ruser then chats[chatID][1] = chats[chatID][1]:gsub("%f[%a]" .. user .. "%f[%A]%s*", "") local wfile = fs.open(filePath, "w") wfile.write(textutils.serialize(chats)) wfile.close() return "true" end end end end return nil end -- Function to handle deleting a chat local function handleDeleteChat(chatID, username) if chats[chatID] then owner = getFirstWord(chats[chatID][1]) if owner ~= nil and owner == username then chats[chatID] = nil print("Chat " .. chatID .. " deleted.") saveChats() return "true" end return "denied" else print("Chat " .. chatID .. " does not exist.") return nil end end -- Function to handle incoming messages local function handleIncomingMessage(chatID, username, text) if not chats[chatID] then print("Chat " .. chatID .. " does not exist.") return nil end table.insert(chats[chatID], username .. ": " .. text) print("Message in chat " .. chatID .. " from " .. username .. ": " .. text) saveChats() return "true" end -- Function to print all messages in a chat local function printChatMessages(chatID) if not chats[chatID] then print("Chat " .. chatID .. " does not exist.") return nil end term.clear() term.setCursorPos(1, 1) for _, line in ipairs(chats[chatID]) do print(line) end return "true" end local function messageRequests() -- Main server loop while true do id, message = rednet.receive() command = twoInputStrip(message) if command == "create" then command, chatid, username = threeInputStrip(message) newid = findUser(username) if newid == nil then addUser(username, id) elseif newid ~= id then removeUser(username, newid) addUser(username, id) end success = handleCreateChat(chatid, username) rednet.send(id, success) elseif command == "add" then success = nil command, chatid, username, nusername = fourInputStrip(message) if findUser(nusername) == nil then print("User does not Exist") end print(handleAddUser(nusername, chatid)) rednet.send(id, success) elseif command == "remove" then command, chatid, username, ruser = fourInputStrip(message) success = handleRemoveUser(username, ruser, chatid) rednet.send(id, success) elseif command == "delete" then command, chatid, username, dusername = fourInputStrip(message) success = handleDeleteChat(chatid, dusername) rednet.send(id, success) elseif command == "send" then command, chatid, username, text = fourInputStrip(message) success = handleIncomingMessage(chatid, username, text) if success == "true" then ping(chatid) end rednet.send(id, success) elseif command == "retrieve" then command, chatid, ruser = threeInputStrip(message) if chats[chatid] then rsuccess = false users = cutSpaces(chats[chatid][1]) for _, user in pairs(users) do if user == ruser then rednet.send(id, chats[chatid]) rsuccess = true break end end if not rsuccess then rednet.send(id, "false") end else rednet.send(id, nil) end elseif command == "find" then command, user = twoInputStrip(message) rednet.send(id, findUser(user)) elseif command == "chats" then command, user = twoInputStrip(message) rednet.send(id, getUsersChats(chats, user)) end end end local function displayOptions() print("1. Display ChatID's") print("2. Display Chat") print("3. Display Users") print("4. Add User to Chat") print("5. Remove User to Chat") print("6. Get User's Chats") print("7. Exit to Login") print("8. Exit to OS") end local function userSwitch(choice, chats) if choice == 1 then print("\n") for idname, array in pairs(chats) do print(idname) end read() return 1 elseif choice == 2 then print("Input Chat ID") newid = read() scrollPosition = 1 maxLines = 15 local startIndex = math.max(1, scrollPosition) local endIndex = math.min(#chats[newid], scrollPosition + maxLines - 1) while true do term.clear() -- Display the database content after the instruction for i = startIndex, endIndex do print(chats[newid][i]) end local event, key = os.pullEvent("key") if key == keys.up then scrollPosition = math.max(1, scrollPosition - 1) elseif key == keys.down then scrollPosition = math.min(#chats[newid] - maxLines + 1, scrollPosition + 1) elseif key == keys.backspace then break -- Exit loop on backspace key press end startIndex = math.max(1, scrollPosition) endIndex = math.min(#chats[newid], scrollPosition + maxLines - 1) end return 2 elseif choice == 3 then if fs.exists(userFilePath) then local file = fs.open(userFilePath, "r") local line = file.readLine() while line do print(line) line = file.readLine() end end read() return 3 elseif choice == 4 then print("User to Add") nusername = read() print("Chat ID: ") chatid = read() print(handleAddUser(nusername, chatid)) read() return 4 elseif choice == 5 then print("User to Remove") ruser = read() print("Chat ID: ") chatid = read() handleRemoveUser(getFirstWord(chats[chatid][1]), ruser, chatid) read() return 5 elseif choice == 6 then print("Enter Username: ") newruser = read() chatnames = getUsersChats(chats, newruser) if chatnames == "no" then print("No User Found") read() elseif chatnames == "none" then print("No Chat's Found") read() else for _, chatname in pairs(chatnames) do print(chatname) end read() end return 6 elseif choice == 7 then term.clear() return 7 elseif choice == 8 then term.clear() return 8 else print("Incorrect Input") return -1 end end local function login(chats) while true do print("Enter Username: ") u = read() print("Enter Password: ") p = read('*') if u == adminu and p == adminp then while true do displayOptions() result = tonumber(read()) userSwitch(result, chats) if result == 7 or result == 8 then break end shell.run("clear") end if result == 8 then break end end end end shell.run("clear") loadChats() rednet.open("top") parallel.waitForAny( function() messageRequests() end, function() login(chats) end )