Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- Custom protocol (default)
- local chatProtocol = "doggyChat"
- -- Function to check if a file exists
- local function fileExists(path)
- local file = fs.open(path, "r")
- if file then
- file.close()
- return true
- end
- return false
- end
- -- Function to list all profiles
- local function listProfiles()
- local profilesDir = "./dogchat/profiles/"
- if not fs.isDir(profilesDir) then
- return {}
- end
- local profiles = fs.list(profilesDir)
- return profiles
- end
- -- Function to download or create the XOR.key file
- local function downloadOrCreateKey()
- local keyFilePath = "XOR.key"
- if fileExists(keyFilePath) then
- term.setTextColor(colors.green)
- print("Encryption key found.")
- term.setTextColor(colors.white)
- else
- term.setTextColor(colors.yellow)
- print("Downloading encryption key...")
- local key = "x3A7rB8zD2L5qW4nH1"
- local file = fs.open(keyFilePath, "w")
- file.write(key)
- file.close()
- print("Encryption key downloaded and saved as XOR.key.")
- term.setTextColor(colors.white)
- end
- local file = fs.open(keyFilePath, "r")
- local key = file.readAll()
- file.close()
- return key
- end
- -- XOR encryption function
- local function xorEncryptDecrypt(message, key)
- local encrypted = {}
- for i = 1, #message do
- local char = string.byte(message, i)
- local keyChar = string.byte(key, (i - 1) % #key + 1)
- table.insert(encrypted, string.char(bit.bxor(char, keyChar)))
- end
- return table.concat(encrypted)
- end
- -- Function to create a new profile
- local function createProfile()
- term.clear()
- term.setCursorPos(1, 1)
- term.setTextColor(colors.cyan)
- print("Enter a username for the new profile:")
- term.setTextColor(colors.white)
- local username = read()
- local profilePath = "./dogchat/profiles/" .. username
- if fileExists(profilePath) then
- term.setTextColor(colors.red)
- print("Profile already exists.")
- term.setTextColor(colors.white)
- return
- end
- term.setTextColor(colors.cyan)
- print("Enter a password for the profile:")
- term.setTextColor(colors.white)
- local password = read("*")
- local encryptionKey = downloadOrCreateKey()
- local hashedPassword = xorEncryptDecrypt(password, encryptionKey)
- fs.makeDir(profilePath)
- local passwordFile = fs.open(profilePath .. "/password.txt", "w")
- passwordFile.write(hashedPassword)
- passwordFile.close()
- term.setTextColor(colors.green)
- print("Profile created successfully.")
- term.setTextColor(colors.white)
- end
- -- Function to delete a profile
- local function deleteProfile()
- term.clear()
- term.setCursorPos(1, 1)
- local profiles = listProfiles()
- if #profiles == 0 then
- term.setTextColor(colors.red)
- print("No profiles found.")
- term.setTextColor(colors.white)
- return
- end
- term.setTextColor(colors.cyan)
- print("Select a profile to delete:")
- term.setTextColor(colors.white)
- for i, profile in ipairs(profiles) do
- print(i .. ". " .. profile)
- end
- local choice = tonumber(read())
- if not choice or choice < 1 or choice > #profiles then
- term.setTextColor(colors.red)
- print("Invalid choice.")
- term.setTextColor(colors.white)
- return
- end
- local username = profiles[choice]
- local profilePath = "./dogchat/profiles/" .. username
- term.setTextColor(colors.cyan)
- print("Enter the password for " .. username .. " to confirm deletion:")
- term.setTextColor(colors.white)
- local password = read("*")
- local encryptionKey = downloadOrCreateKey()
- local passwordFile = fs.open(profilePath .. "/password.txt", "r")
- local storedPassword = passwordFile.readAll()
- passwordFile.close()
- if xorEncryptDecrypt(password, encryptionKey) == storedPassword then
- fs.delete(profilePath)
- term.setTextColor(colors.green)
- print("Profile deleted successfully.")
- term.setTextColor(colors.white)
- else
- term.setTextColor(colors.red)
- print("Incorrect password. Deletion canceled.")
- term.setTextColor(colors.white)
- end
- end
- -- Function to load an existing profile
- local function loadProfile()
- term.clear()
- term.setCursorPos(1, 1)
- local profiles = listProfiles()
- if #profiles == 0 then
- term.setTextColor(colors.red)
- print("No profiles found.")
- term.setTextColor(colors.white)
- return nil
- end
- term.setTextColor(colors.cyan)
- print("Select a profile to log in:")
- term.setTextColor(colors.white)
- for i, profile in ipairs(profiles) do
- print(i .. ". " .. profile)
- end
- local choice = tonumber(read())
- if not choice or choice < 1 or choice > #profiles then
- term.setTextColor(colors.red)
- print("Invalid choice.")
- term.setTextColor(colors.white)
- return nil
- end
- local username = profiles[choice]
- local profilePath = "./dogchat/profiles/" .. username
- term.setTextColor(colors.cyan)
- print("Enter the password for " .. username .. ":")
- term.setTextColor(colors.white)
- local password = read("*")
- local encryptionKey = downloadOrCreateKey()
- local passwordFile = fs.open(profilePath .. "/password.txt", "r")
- local storedPassword = passwordFile.readAll()
- passwordFile.close()
- if xorEncryptDecrypt(password, encryptionKey) == storedPassword then
- term.setTextColor(colors.green)
- print("Login successful.")
- term.setTextColor(colors.white)
- return username
- else
- term.setTextColor(colors.red)
- print("Incorrect password.")
- term.setTextColor(colors.white)
- return nil
- end
- end
- -- Function to manage settings
- local function settingsMenu()
- term.clear()
- term.setCursorPos(1, 1)
- while true do
- term.setTextColor(colors.cyan)
- print("Settings Menu:")
- term.setTextColor(colors.white)
- print("1. Create a new profile")
- print("2. Delete a profile")
- print("3. Back to main menu")
- local choice = read()
- if choice == "1" then
- createProfile()
- elseif choice == "2" then
- deleteProfile()
- elseif choice == "3" then
- break
- else
- term.setTextColor(colors.red)
- print("Invalid choice. Please try again.")
- term.setTextColor(colors.white)
- end
- end
- end
- -- Function to list all connected modems
- local function listModems()
- local modems = {}
- for _, side in ipairs(peripheral.getNames()) do
- if peripheral.getType(side) == "modem" then
- table.insert(modems, side)
- end
- end
- return modems
- end
- -- Function to setup the modem
- local function setupModem()
- local modems = listModems()
- if #modems == 0 then
- term.setTextColor(colors.red)
- print("No modems found! Please connect a modem and restart.")
- term.setTextColor(colors.white)
- return nil
- end
- term.setTextColor(colors.cyan)
- print("Connected modems:")
- term.setTextColor(colors.white)
- for i, side in ipairs(modems) do
- print(i .. ": " .. side)
- end
- rednet.open(modems[1])
- term.setTextColor(colors.green)
- print("Using modem on " .. modems[1])
- term.setTextColor(colors.white)
- return modems[1]
- end
- -- Function to display a message in the chat
- local function displayMessage(senderId, message, isOlderClient)
- term.setTextColor(colors.yellow)
- if isOlderClient then
- print("[Unknown User (" .. senderId .. ")]: " .. message)
- else
- print("[" .. senderId .. "]: " .. message)
- end
- term.setTextColor(colors.white)
- end
- -- Function to handle incoming messages
- local function handleIncomingMessages(encryptionKey)
- while true do
- local senderId, encryptedMessage, protocol = rednet.receive(chatProtocol)
- local decryptedMessage = xorEncryptDecrypt(encryptedMessage, encryptionKey)
- local username, chatMessage = decryptedMessage:match("^(.-): (.+)$")
- if username and chatMessage then
- displayMessage(username, chatMessage, false)
- else
- displayMessage(senderId, decryptedMessage, true)
- end
- end
- end
- -- Function to send a message
- local function sendMessage(username, encryptionKey)
- while true do
- term.setTextColor(colors.cyan)
- print("Type your message (or 'exit' to quit): ")
- term.setTextColor(colors.white)
- local userInput = read()
- if userInput == "exit" then
- term.setTextColor(colors.green)
- print("Exiting chat...")
- term.setTextColor(colors.white)
- shell.run("/disk/os/gui")
- break
- end
- local formattedMessage = username .. ": " .. userInput
- local encryptedMessage = xorEncryptDecrypt(formattedMessage, encryptionKey)
- rednet.broadcast(encryptedMessage, chatProtocol)
- displayMessage(username, userInput, false)
- end
- end
- -- Main program
- term.clear()
- term.setCursorPos(1, 1)
- term.setTextColor(colors.blue)
- print("Welcome to the Doggy OS Network Chatroom!")
- term.setTextColor(colors.white)
- term.setTextColor(colors.cyan)
- print("1. Log in to a profile")
- print("2. Settings")
- term.setTextColor(colors.white)
- local mainChoice = read()
- local username = nil
- if mainChoice == "1" then
- username = loadProfile()
- elseif mainChoice == "2" then
- settingsMenu()
- else
- term.setTextColor(colors.red)
- print("Invalid choice. Exiting.")
- term.setTextColor(colors.white)
- return
- end
- if not username then return end
- term.setTextColor(colors.cyan)
- print("Would you like to join a public chatroom or a private chatroom? (p for public, c for private)")
- term.setTextColor(colors.white)
- local chatroomChoice = read()
- if chatroomChoice == "p" or chatroomChoice == "P" then
- term.setTextColor(colors.green)
- print("Joining public chatroom with default protocol: " .. chatProtocol)
- else
- term.setTextColor(colors.green)
- print("Enter a custom protocol name for the private chatroom:")
- chatProtocol = read()
- print("Using custom protocol for the private chatroom: " .. chatProtocol)
- end
- term.setTextColor(colors.white)
- local encryptionKey = downloadOrCreateKey()
- local modemSide = setupModem()
- if modemSide == nil then return end
- term.setTextColor(colors.cyan)
- print("Type 'exit' to leave the chat.")
- term.setTextColor(colors.white)
- parallel.waitForAny(function()
- handleIncomingMessages(encryptionKey)
- end, function()
- sendMessage(username, encryptionKey)
- end)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement