Advertisement
DOGGYWOOF

Doggy Chatroom v3

Dec 14th, 2024 (edited)
28
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.79 KB | None | 0 0
  1. -- Custom protocol (default)
  2. local chatProtocol = "doggyChat"
  3.  
  4. -- Function to check if a file exists
  5. local function fileExists(path)
  6. local file = fs.open(path, "r")
  7. if file then
  8. file.close()
  9. return true
  10. end
  11. return false
  12. end
  13.  
  14. -- Function to list all profiles
  15. local function listProfiles()
  16. local profilesDir = "./dogchat/profiles/"
  17. if not fs.isDir(profilesDir) then
  18. return {}
  19. end
  20.  
  21. local profiles = fs.list(profilesDir)
  22. return profiles
  23. end
  24.  
  25. -- Function to download or create the XOR.key file
  26. local function downloadOrCreateKey()
  27. local keyFilePath = "XOR.key"
  28.  
  29. if fileExists(keyFilePath) then
  30. term.setTextColor(colors.green)
  31. print("Encryption key found.")
  32. term.setTextColor(colors.white)
  33. else
  34. term.setTextColor(colors.yellow)
  35. print("Downloading encryption key...")
  36. local key = "x3A7rB8zD2L5qW4nH1"
  37. local file = fs.open(keyFilePath, "w")
  38. file.write(key)
  39. file.close()
  40. print("Encryption key downloaded and saved as XOR.key.")
  41. term.setTextColor(colors.white)
  42. end
  43.  
  44. local file = fs.open(keyFilePath, "r")
  45. local key = file.readAll()
  46. file.close()
  47.  
  48. return key
  49. end
  50.  
  51. -- XOR encryption function
  52. local function xorEncryptDecrypt(message, key)
  53. local encrypted = {}
  54. for i = 1, #message do
  55. local char = string.byte(message, i)
  56. local keyChar = string.byte(key, (i - 1) % #key + 1)
  57. table.insert(encrypted, string.char(bit.bxor(char, keyChar)))
  58. end
  59. return table.concat(encrypted)
  60. end
  61.  
  62. -- Function to create a new profile
  63. local function createProfile()
  64. term.clear()
  65. term.setCursorPos(1, 1)
  66. term.setTextColor(colors.cyan)
  67. print("Enter a username for the new profile:")
  68. term.setTextColor(colors.white)
  69. local username = read()
  70.  
  71. local profilePath = "./dogchat/profiles/" .. username
  72. if fileExists(profilePath) then
  73. term.setTextColor(colors.red)
  74. print("Profile already exists.")
  75. term.setTextColor(colors.white)
  76. return
  77. end
  78.  
  79. term.setTextColor(colors.cyan)
  80. print("Enter a password for the profile:")
  81. term.setTextColor(colors.white)
  82. local password = read("*")
  83.  
  84. local encryptionKey = downloadOrCreateKey()
  85. local hashedPassword = xorEncryptDecrypt(password, encryptionKey)
  86.  
  87. fs.makeDir(profilePath)
  88. local passwordFile = fs.open(profilePath .. "/password.txt", "w")
  89. passwordFile.write(hashedPassword)
  90. passwordFile.close()
  91.  
  92. term.setTextColor(colors.green)
  93. print("Profile created successfully.")
  94. term.setTextColor(colors.white)
  95. end
  96.  
  97. -- Function to delete a profile
  98. local function deleteProfile()
  99. term.clear()
  100. term.setCursorPos(1, 1)
  101. local profiles = listProfiles()
  102. if #profiles == 0 then
  103. term.setTextColor(colors.red)
  104. print("No profiles found.")
  105. term.setTextColor(colors.white)
  106. return
  107. end
  108.  
  109. term.setTextColor(colors.cyan)
  110. print("Select a profile to delete:")
  111. term.setTextColor(colors.white)
  112. for i, profile in ipairs(profiles) do
  113. print(i .. ". " .. profile)
  114. end
  115.  
  116. local choice = tonumber(read())
  117. if not choice or choice < 1 or choice > #profiles then
  118. term.setTextColor(colors.red)
  119. print("Invalid choice.")
  120. term.setTextColor(colors.white)
  121. return
  122. end
  123.  
  124. local username = profiles[choice]
  125. local profilePath = "./dogchat/profiles/" .. username
  126.  
  127. term.setTextColor(colors.cyan)
  128. print("Enter the password for " .. username .. " to confirm deletion:")
  129. term.setTextColor(colors.white)
  130. local password = read("*")
  131.  
  132. local encryptionKey = downloadOrCreateKey()
  133. local passwordFile = fs.open(profilePath .. "/password.txt", "r")
  134. local storedPassword = passwordFile.readAll()
  135. passwordFile.close()
  136.  
  137. if xorEncryptDecrypt(password, encryptionKey) == storedPassword then
  138. fs.delete(profilePath)
  139. term.setTextColor(colors.green)
  140. print("Profile deleted successfully.")
  141. term.setTextColor(colors.white)
  142. else
  143. term.setTextColor(colors.red)
  144. print("Incorrect password. Deletion canceled.")
  145. term.setTextColor(colors.white)
  146. end
  147. end
  148.  
  149. -- Function to load an existing profile
  150. local function loadProfile()
  151. term.clear()
  152. term.setCursorPos(1, 1)
  153. local profiles = listProfiles()
  154. if #profiles == 0 then
  155. term.setTextColor(colors.red)
  156. print("No profiles found.")
  157. term.setTextColor(colors.white)
  158. return nil
  159. end
  160.  
  161. term.setTextColor(colors.cyan)
  162. print("Select a profile to log in:")
  163. term.setTextColor(colors.white)
  164. for i, profile in ipairs(profiles) do
  165. print(i .. ". " .. profile)
  166. end
  167.  
  168. local choice = tonumber(read())
  169. if not choice or choice < 1 or choice > #profiles then
  170. term.setTextColor(colors.red)
  171. print("Invalid choice.")
  172. term.setTextColor(colors.white)
  173. return nil
  174. end
  175.  
  176. local username = profiles[choice]
  177. local profilePath = "./dogchat/profiles/" .. username
  178.  
  179. term.setTextColor(colors.cyan)
  180. print("Enter the password for " .. username .. ":")
  181. term.setTextColor(colors.white)
  182. local password = read("*")
  183.  
  184. local encryptionKey = downloadOrCreateKey()
  185. local passwordFile = fs.open(profilePath .. "/password.txt", "r")
  186. local storedPassword = passwordFile.readAll()
  187. passwordFile.close()
  188.  
  189. if xorEncryptDecrypt(password, encryptionKey) == storedPassword then
  190. term.setTextColor(colors.green)
  191. print("Login successful.")
  192. term.setTextColor(colors.white)
  193. return username
  194. else
  195. term.setTextColor(colors.red)
  196. print("Incorrect password.")
  197. term.setTextColor(colors.white)
  198. return nil
  199. end
  200. end
  201.  
  202. -- Function to manage settings
  203. local function settingsMenu()
  204. term.clear()
  205. term.setCursorPos(1, 1)
  206. while true do
  207. term.setTextColor(colors.cyan)
  208. print("Settings Menu:")
  209. term.setTextColor(colors.white)
  210. print("1. Create a new profile")
  211. print("2. Delete a profile")
  212. print("3. Back to main menu")
  213. local choice = read()
  214.  
  215. if choice == "1" then
  216. createProfile()
  217. elseif choice == "2" then
  218. deleteProfile()
  219. elseif choice == "3" then
  220. break
  221. else
  222. term.setTextColor(colors.red)
  223. print("Invalid choice. Please try again.")
  224. term.setTextColor(colors.white)
  225. end
  226. end
  227. end
  228.  
  229. -- Function to list all connected modems
  230. local function listModems()
  231. local modems = {}
  232. for _, side in ipairs(peripheral.getNames()) do
  233. if peripheral.getType(side) == "modem" then
  234. table.insert(modems, side)
  235. end
  236. end
  237. return modems
  238. end
  239.  
  240. -- Function to setup the modem
  241. local function setupModem()
  242. local modems = listModems()
  243. if #modems == 0 then
  244. term.setTextColor(colors.red)
  245. print("No modems found! Please connect a modem and restart.")
  246. term.setTextColor(colors.white)
  247. return nil
  248. end
  249.  
  250. term.setTextColor(colors.cyan)
  251. print("Connected modems:")
  252. term.setTextColor(colors.white)
  253. for i, side in ipairs(modems) do
  254. print(i .. ": " .. side)
  255. end
  256.  
  257. rednet.open(modems[1])
  258. term.setTextColor(colors.green)
  259. print("Using modem on " .. modems[1])
  260. term.setTextColor(colors.white)
  261. return modems[1]
  262. end
  263.  
  264. -- Function to display a message in the chat
  265. local function displayMessage(senderId, message, isOlderClient)
  266. term.setTextColor(colors.yellow)
  267. if isOlderClient then
  268. print("[Unknown User (" .. senderId .. ")]: " .. message)
  269. else
  270. print("[" .. senderId .. "]: " .. message)
  271. end
  272. term.setTextColor(colors.white)
  273. end
  274.  
  275. -- Function to handle incoming messages
  276. local function handleIncomingMessages(encryptionKey)
  277. while true do
  278. local senderId, encryptedMessage, protocol = rednet.receive(chatProtocol)
  279. local decryptedMessage = xorEncryptDecrypt(encryptedMessage, encryptionKey)
  280.  
  281. local username, chatMessage = decryptedMessage:match("^(.-): (.+)$")
  282. if username and chatMessage then
  283. displayMessage(username, chatMessage, false)
  284. else
  285. displayMessage(senderId, decryptedMessage, true)
  286. end
  287. end
  288. end
  289.  
  290. -- Function to send a message
  291. local function sendMessage(username, encryptionKey)
  292. while true do
  293. term.setTextColor(colors.cyan)
  294. print("Type your message (or 'exit' to quit): ")
  295. term.setTextColor(colors.white)
  296. local userInput = read()
  297. if userInput == "exit" then
  298. term.setTextColor(colors.green)
  299. print("Exiting chat...")
  300. term.setTextColor(colors.white)
  301. shell.run("/disk/os/gui")
  302. break
  303. end
  304.  
  305. local formattedMessage = username .. ": " .. userInput
  306. local encryptedMessage = xorEncryptDecrypt(formattedMessage, encryptionKey)
  307. rednet.broadcast(encryptedMessage, chatProtocol)
  308. displayMessage(username, userInput, false)
  309. end
  310. end
  311.  
  312. -- Main program
  313. term.clear()
  314. term.setCursorPos(1, 1)
  315.  
  316. term.setTextColor(colors.blue)
  317. print("Welcome to the Doggy OS Network Chatroom!")
  318. term.setTextColor(colors.white)
  319.  
  320. term.setTextColor(colors.cyan)
  321. print("1. Log in to a profile")
  322. print("2. Settings")
  323. term.setTextColor(colors.white)
  324. local mainChoice = read()
  325.  
  326. local username = nil
  327. if mainChoice == "1" then
  328. username = loadProfile()
  329. elseif mainChoice == "2" then
  330. settingsMenu()
  331. else
  332. term.setTextColor(colors.red)
  333. print("Invalid choice. Exiting.")
  334. term.setTextColor(colors.white)
  335. return
  336. end
  337.  
  338. if not username then return end
  339.  
  340. term.setTextColor(colors.cyan)
  341. print("Would you like to join a public chatroom or a private chatroom? (p for public, c for private)")
  342. term.setTextColor(colors.white)
  343. local chatroomChoice = read()
  344.  
  345. if chatroomChoice == "p" or chatroomChoice == "P" then
  346. term.setTextColor(colors.green)
  347. print("Joining public chatroom with default protocol: " .. chatProtocol)
  348. else
  349. term.setTextColor(colors.green)
  350. print("Enter a custom protocol name for the private chatroom:")
  351. chatProtocol = read()
  352. print("Using custom protocol for the private chatroom: " .. chatProtocol)
  353. end
  354.  
  355. term.setTextColor(colors.white)
  356. local encryptionKey = downloadOrCreateKey()
  357. local modemSide = setupModem()
  358. if modemSide == nil then return end
  359.  
  360. term.setTextColor(colors.cyan)
  361. print("Type 'exit' to leave the chat.")
  362. term.setTextColor(colors.white)
  363.  
  364. parallel.waitForAny(function()
  365. handleIncomingMessages(encryptionKey)
  366. end, function()
  367. sendMessage(username, encryptionKey)
  368. end)
  369.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement