SHOW:
|
|
- or go back to the newest paste.
| 1 | local chats = {}
| |
| 2 | ||
| 3 | -- File path for saving chats | |
| 4 | filePath = "chats.txt" | |
| 5 | userFilePath = "users.txt" | |
| 6 | ||
| 7 | adminu = "username" | |
| 8 | adminp = "password" | |
| 9 | ||
| 10 | local function getFirstWord(str) | |
| 11 | local firstWord = str:match("^(%S+)")
| |
| 12 | return firstWord | |
| 13 | end | |
| 14 | ||
| 15 | function twoInputStrip(str) | |
| 16 | first, second = str:match("(%S+)%s+(%S+)")
| |
| 17 | return first, second | |
| 18 | end | |
| 19 | ||
| 20 | function threeInputStrip(str) | |
| 21 | first, second, third = str:match("(%S+)%s+(%S+)%s+(%S+)")
| |
| 22 | return first, second, third | |
| 23 | end | |
| 24 | ||
| 25 | function fourInputStrip(str) | |
| 26 | local first, second, third, fourth = str:match("(%S+)%s+(%S+)%s+(%S+)%s+(.*)")
| |
| 27 | return first, second, third, fourth | |
| 28 | end | |
| 29 | ||
| 30 | local function cutSpaces(str) | |
| 31 | local substrings = {}
| |
| 32 | for substring in str:gmatch("%S+") do
| |
| 33 | table.insert(substrings, substring) | |
| 34 | end | |
| 35 | return substrings | |
| 36 | end | |
| 37 | ||
| 38 | -- Function to save chats to a file | |
| 39 | local function saveChats() | |
| 40 | local file = fs.open(filePath, "w") | |
| 41 | file.write(textutils.serialize(chats)) | |
| 42 | file.close() | |
| 43 | print("Chats saved.")
| |
| 44 | end | |
| 45 | ||
| 46 | -- Function to print the first key of each sub-array | |
| 47 | local function getChannelIds() | |
| 48 | chatnames = {}
| |
| 49 | for _, subArray in ipairs(chats) do | |
| 50 | for chatname, _ in pairs(subArray) do | |
| 51 | print(chatname) | |
| 52 | table.insert(chatnames, chatname) | |
| 53 | break -- Only print the first key | |
| 54 | end | |
| 55 | end | |
| 56 | return chatnames | |
| 57 | end | |
| 58 | ||
| 59 | -- Function to save chats to a file | |
| 60 | local function addUser(user, userID) | |
| 61 | local file = fs.open(userFilePath, "a") | |
| 62 | file.writeLine(user .. " " .. userID) | |
| 63 | file.close() | |
| 64 | print("Users saved.")
| |
| 65 | end | |
| 66 | ||
| 67 | -- Function to save chats to a file | |
| 68 | local function removeUser(user, userID) | |
| 69 | success = false | |
| 70 | if fs.exists(userFilePath) then | |
| 71 | local file = fs.open(userFilePath, "r") | |
| 72 | local line = file.readLine() | |
| 73 | while line do | |
| 74 | print(line) | |
| 75 | name = twoInputStrip(line) | |
| 76 | if name == user then | |
| 77 | success = true | |
| 78 | else | |
| 79 | table.insert(newfile, line) | |
| 80 | end | |
| 81 | line = file.readLine() | |
| 82 | end | |
| 83 | file.close() | |
| 84 | file = fs.open(userFilePath, "w") | |
| 85 | for _, line in pairs(newfile) do | |
| 86 | file.writeLine(line) | |
| 87 | end | |
| 88 | file.close() | |
| 89 | end | |
| 90 | return success | |
| 91 | end | |
| 92 | ||
| 93 | local function findUser(user) | |
| 94 | if fs.exists(userFilePath) then | |
| 95 | local file = fs.open(userFilePath, "r") | |
| 96 | if file then | |
| 97 | line = file.readLine() | |
| 98 | while line do | |
| 99 | local name, nid = twoInputStrip(line) | |
| 100 | if name ~= nil and name == user then | |
| 101 | file.close() | |
| 102 | return nid | |
| 103 | end | |
| 104 | line = file.readLine() | |
| 105 | end | |
| 106 | file.close() | |
| 107 | end | |
| 108 | end | |
| 109 | return nil | |
| 110 | end | |
| 111 | ||
| 112 | local function checkChat(chat, ruser) | |
| 113 | users = cutSpaces(chat[1]) | |
| 114 | for _, user in pairs(users) do | |
| 115 | if user == ruser then | |
| 116 | return true | |
| 117 | end | |
| 118 | end | |
| 119 | return false | |
| 120 | end | |
| 121 | ||
| 122 | local function getUsersChats(chats, newruser) | |
| 123 | userchats = {}
| |
| 124 | newid = findUser(newruser) | |
| 125 | if newid == nil then | |
| 126 | return "no" | |
| 127 | end | |
| 128 | for chatname, array in pairs(chats) do | |
| 129 | if checkChat(chats[chatname], newruser) then | |
| 130 | table.insert(userchats, chatname) | |
| 131 | end | |
| 132 | end | |
| 133 | if userchats == nil then | |
| 134 | return "none" | |
| 135 | else | |
| 136 | return userchats | |
| 137 | end | |
| 138 | return nil | |
| 139 | end | |
| 140 | ||
| 141 | local function ping(chatID) | |
| 142 | users = cutSpaces(chats[chatID][1]) | |
| 143 | for _, user in pairs(users) do | |
| 144 | userid = findUser(user) | |
| 145 | if userid ~= nil then | |
| 146 | rednet.send(tonumber(userid), "update") | |
| 147 | end | |
| 148 | end | |
| 149 | end | |
| 150 | ||
| 151 | -- Function to load chats from a file | |
| 152 | local function loadChats() | |
| 153 | if fs.exists(filePath) then | |
| 154 | local file = fs.open(filePath, "r") | |
| 155 | local content = file.readAll() | |
| 156 | chats = textutils.unserialize(content) or {}
| |
| 157 | file.close() | |
| 158 | print("Chats loaded.")
| |
| 159 | return chats | |
| 160 | else | |
| 161 | print("No saved chats found.")
| |
| 162 | return nil | |
| 163 | end | |
| 164 | end | |
| 165 | ||
| 166 | -- Function to handle creating a new chat | |
| 167 | local function handleCreateChat(chatID, username) | |
| 168 | if not chats[chatID] and username ~= nil then | |
| 169 | chats[chatID] = {username .. " "}
| |
| 170 | print("Chat " .. chatID .. " created.")
| |
| 171 | saveChats() | |
| 172 | return "true" | |
| 173 | else | |
| 174 | print("Chat " .. chatID .. " already exists.")
| |
| 175 | return "exists" | |
| 176 | end | |
| 177 | end | |
| 178 | ||
| 179 | -- Function to save chats to a file | |
| 180 | local function handleAddUser(user, chatID) | |
| 181 | if chats[chatID] then | |
| 182 | chats[chatID][1] = chats[chatID][1] .. user .. " " | |
| 183 | local wfile = fs.open(filePath, "w") | |
| 184 | wfile.write(textutils.serialize(chats)) | |
| 185 | wfile.close() | |
| 186 | return "true" | |
| 187 | end | |
| 188 | return nil | |
| 189 | end | |
| 190 | ||
| 191 | -- Function to save chats to a file | |
| 192 | local function handleRemoveUser(username, ruser, chatID) | |
| 193 | print(chats[chatID][1]) | |
| 194 | owner = getFirstWord(chats[chatID][1]) | |
| 195 | if owner ~= nil and owner == username then | |
| 196 | if chats[chatID] then | |
| 197 | users = cutSpaces(chats[chatID][1]) | |
| 198 | for _, user in pairs(users) do | |
| 199 | if user == ruser then | |
| 200 | chats[chatID][1] = chats[chatID][1]:gsub("%f[%a]" .. user .. "%f[%A]%s*", "")
| |
| 201 | local wfile = fs.open(filePath, "w") | |
| 202 | wfile.write(textutils.serialize(chats)) | |
| 203 | wfile.close() | |
| 204 | return "true" | |
| 205 | end | |
| 206 | end | |
| 207 | end | |
| 208 | end | |
| 209 | return nil | |
| 210 | end | |
| 211 | ||
| 212 | -- Function to handle deleting a chat | |
| 213 | local function handleDeleteChat(chatID, username) | |
| 214 | if chats[chatID] then | |
| 215 | owner = getFirstWord(chats[chatID][1]) | |
| 216 | if owner ~= nil and owner == username then | |
| 217 | chats[chatID] = nil | |
| 218 | print("Chat " .. chatID .. " deleted.")
| |
| 219 | saveChats() | |
| 220 | return "true" | |
| 221 | end | |
| 222 | return "denied" | |
| 223 | else | |
| 224 | print("Chat " .. chatID .. " does not exist.")
| |
| 225 | return nil | |
| 226 | end | |
| 227 | end | |
| 228 | ||
| 229 | -- Function to handle incoming messages | |
| 230 | local function handleIncomingMessage(chatID, username, text) | |
| 231 | if not chats[chatID] then | |
| 232 | print("Chat " .. chatID .. " does not exist.")
| |
| 233 | return nil | |
| 234 | end | |
| 235 | table.insert(chats[chatID], username .. ": " .. text) | |
| 236 | print("Message in chat " .. chatID .. " from " .. username .. ": " .. text)
| |
| 237 | saveChats() | |
| 238 | return "true" | |
| 239 | end | |
| 240 | ||
| 241 | -- Function to print all messages in a chat | |
| 242 | local function printChatMessages(chatID) | |
| 243 | if not chats[chatID] then | |
| 244 | print("Chat " .. chatID .. " does not exist.")
| |
| 245 | return nil | |
| 246 | end | |
| 247 | ||
| 248 | term.clear() | |
| 249 | term.setCursorPos(1, 1) | |
| 250 | for _, line in ipairs(chats[chatID]) do | |
| 251 | print(line) | |
| 252 | end | |
| 253 | return "true" | |
| 254 | end | |
| 255 | ||
| 256 | local function messageRequests() | |
| 257 | -- Main server loop | |
| 258 | while true do | |
| 259 | id, message = rednet.receive() | |
| 260 | command = twoInputStrip(message) | |
| 261 | if command == "create" then | |
| 262 | command, chatid, username = threeInputStrip(message) | |
| 263 | newid = findUser(username) | |
| 264 | if newid == nil then | |
| 265 | addUser(username, id) | |
| 266 | elseif newid ~= id then | |
| 267 | removeUser(username, newid) | |
| 268 | addUser(username, id) | |
| 269 | end | |
| 270 | success = handleCreateChat(chatid, username) | |
| 271 | rednet.send(id, success) | |
| 272 | elseif command == "add" then | |
| 273 | success = nil | |
| 274 | command, chatid, username, nusername = fourInputStrip(message) | |
| 275 | if findUser(nusername) == nil then | |
| 276 | print("User does not Exist")
| |
| 277 | end | |
| 278 | print(handleAddUser(nusername, chatid)) | |
| 279 | rednet.send(id, success) | |
| 280 | ||
| 281 | elseif command == "remove" then | |
| 282 | command, chatid, username, ruser = fourInputStrip(message) | |
| 283 | success = handleRemoveUser(username, ruser, chatid) | |
| 284 | rednet.send(id, success) | |
| 285 | ||
| 286 | elseif command == "delete" then | |
| 287 | command, chatid, username, dusername = fourInputStrip(message) | |
| 288 | success = handleDeleteChat(chatid, dusername) | |
| 289 | rednet.send(id, success) | |
| 290 | ||
| 291 | elseif command == "send" then | |
| 292 | command, chatid, username, text = fourInputStrip(message) | |
| 293 | success = handleIncomingMessage(chatid, username, text) | |
| 294 | if success == "true" then | |
| 295 | ping(chatid) | |
| 296 | end | |
| 297 | rednet.send(id, success) | |
| 298 | ||
| 299 | elseif command == "retrieve" then | |
| 300 | command, chatid, ruser = threeInputStrip(message) | |
| 301 | if chats[chatid] then | |
| 302 | rsuccess = false | |
| 303 | users = cutSpaces(chats[chatid][1]) | |
| 304 | for _, user in pairs(users) do | |
| 305 | if user == ruser then | |
| 306 | rednet.send(id, chats[chatid]) | |
| 307 | rsuccess = true | |
| 308 | break | |
| 309 | end | |
| 310 | end | |
| 311 | if not rsuccess then | |
| 312 | rednet.send(id, "false") | |
| 313 | end | |
| 314 | else | |
| 315 | rednet.send(id, nil) | |
| 316 | end | |
| 317 | elseif command == "find" then | |
| 318 | command, user = twoInputStrip(message) | |
| 319 | rednet.send(id, findUser(user)) | |
| 320 | elseif command == "chats" then | |
| 321 | command, user = twoInputStrip(message) | |
| 322 | rednet.send(id, getUsersChats(chats, user)) | |
| 323 | end | |
| 324 | end | |
| 325 | end | |
| 326 | ||
| 327 | local function displayOptions() | |
| 328 | print("1. Display ChatID's")
| |
| 329 | print("2. Display Chat")
| |
| 330 | print("3. Display Users")
| |
| 331 | print("4. Add User to Chat")
| |
| 332 | print("5. Remove User to Chat")
| |
| 333 | print("6. Get User's Chats")
| |
| 334 | print("7. Exit to Login")
| |
| 335 | print("8. Exit to OS")
| |
| 336 | end | |
| 337 | ||
| 338 | local function userSwitch(choice, chats) | |
| 339 | if choice == 1 then | |
| 340 | print("\n")
| |
| 341 | for idname, array in pairs(chats) do | |
| 342 | print(idname) | |
| 343 | end | |
| 344 | read() | |
| 345 | return 1 | |
| 346 | elseif choice == 2 then | |
| 347 | print("Input Chat ID")
| |
| 348 | newid = read() | |
| 349 | ||
| 350 | scrollPosition = 1 | |
| 351 | maxLines = 15 | |
| 352 | local startIndex = math.max(1, scrollPosition) | |
| 353 | local endIndex = math.min(#chats[newid], scrollPosition + maxLines - 1) | |
| 354 | ||
| 355 | while true do | |
| 356 | term.clear() | |
| 357 | ||
| 358 | -- Display the database content after the instruction | |
| 359 | for i = startIndex, endIndex do | |
| 360 | print(chats[newid][i]) | |
| 361 | end | |
| 362 | ||
| 363 | local event, key = os.pullEvent("key")
| |
| 364 | if key == keys.up then | |
| 365 | scrollPosition = math.max(1, scrollPosition - 1) | |
| 366 | elseif key == keys.down then | |
| 367 | scrollPosition = math.min(#chats[newid] - maxLines + 1, scrollPosition + 1) | |
| 368 | elseif key == keys.backspace then | |
| 369 | break -- Exit loop on backspace key press | |
| 370 | end | |
| 371 | ||
| 372 | startIndex = math.max(1, scrollPosition) | |
| 373 | endIndex = math.min(#chats[newid], scrollPosition + maxLines - 1) | |
| 374 | end | |
| 375 | return 2 | |
| 376 | elseif choice == 3 then | |
| 377 | if fs.exists(userFilePath) then | |
| 378 | local file = fs.open(userFilePath, "r") | |
| 379 | local line = file.readLine() | |
| 380 | while line do | |
| 381 | print(line) | |
| 382 | line = file.readLine() | |
| 383 | end | |
| 384 | end | |
| 385 | read() | |
| 386 | return 3 | |
| 387 | elseif choice == 4 then | |
| 388 | print("User to Add")
| |
| 389 | nusername = read() | |
| 390 | print("Chat ID: ")
| |
| 391 | chatid = read() | |
| 392 | print(handleAddUser(nusername, chatid)) | |
| 393 | read() | |
| 394 | return 4 | |
| 395 | elseif choice == 5 then | |
| 396 | print("User to Remove")
| |
| 397 | ruser = read() | |
| 398 | print("Chat ID: ")
| |
| 399 | chatid = read() | |
| 400 | handleRemoveUser(getFirstWord(chats[chatid][1]), ruser, chatid) | |
| 401 | read() | |
| 402 | return 5 | |
| 403 | elseif choice == 6 then | |
| 404 | print("Enter Username: ")
| |
| 405 | newruser = read() | |
| 406 | chatnames = getUsersChats(chats, newruser) | |
| 407 | if chatnames == "no" then | |
| 408 | print("No User Found")
| |
| 409 | read() | |
| 410 | elseif chatnames == "none" then | |
| 411 | print("No Chat's Found")
| |
| 412 | read() | |
| 413 | else | |
| 414 | for _, chatname in pairs(chatnames) do | |
| 415 | print(chatname) | |
| 416 | end | |
| 417 | read() | |
| 418 | end | |
| 419 | return 6 | |
| 420 | elseif choice == 7 then | |
| 421 | term.clear() | |
| 422 | return 7 | |
| 423 | elseif choice == 8 then | |
| 424 | term.clear() | |
| 425 | return 8 | |
| 426 | else | |
| 427 | print("Incorrect Input")
| |
| 428 | return -1 | |
| 429 | end | |
| 430 | end | |
| 431 | ||
| 432 | local function login(chats) | |
| 433 | while true do | |
| 434 | print("Enter Username: ")
| |
| 435 | u = read() | |
| 436 | print("Enter Password: ")
| |
| 437 | p = read('*')
| |
| 438 | if u == adminu and p == adminp then | |
| 439 | while true do | |
| 440 | displayOptions() | |
| 441 | result = tonumber(read()) | |
| 442 | userSwitch(result, chats) | |
| 443 | if result == 7 or result == 8 then | |
| 444 | break | |
| 445 | end | |
| 446 | shell.run("clear")
| |
| 447 | end | |
| 448 | if result == 8 then | |
| 449 | break | |
| 450 | end | |
| 451 | end | |
| 452 | end | |
| 453 | end | |
| 454 | ||
| 455 | shell.run("clear")
| |
| 456 | loadChats() | |
| 457 | rednet.open("top")
| |
| 458 | parallel.waitForAny( | |
| 459 | function() messageRequests() end, | |
| 460 | function() login(chats) end | |
| 461 | ) | |
| 462 | ||
| 463 |