Multiroom support
This commit is contained in:
		| @@ -73,17 +73,147 @@ object config { | ||||
| } | ||||
|  | ||||
| object WsSessionManager { | ||||
|     val peopleOnline = mutableListOf("") | ||||
|     val sessionsList = mutableListOf("") | ||||
|     val peopleOnline = mutableListOf<String>() | ||||
|     val sessionsList = mutableListOf<String>() | ||||
|     val sessions = ConcurrentHashMap<WsContext, String>() | ||||
|     val sessionIds = ConcurrentHashMap<String, WsContext>() | ||||
|     val userSessions = ConcurrentHashMap<String, String>() | ||||
|  | ||||
|      | ||||
|     val roomList = mutableListOf<String>() | ||||
|     val userRooms = ConcurrentHashMap<String, String>()  | ||||
|     val roomUsers = ConcurrentHashMap<String, MutableList<String>>()  | ||||
|      | ||||
|     init { | ||||
|         createRoom("general") | ||||
|          | ||||
|         fixedRateTimer("websocket-ping", period = 5000) { | ||||
|             sendPing() | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     fun createRoom(roomName: String): Boolean { | ||||
|         if (roomList.contains(roomName)) { | ||||
|             return false | ||||
|         } | ||||
|         roomList.add(roomName) | ||||
|         roomUsers[roomName] = mutableListOf() | ||||
|         return true | ||||
|     } | ||||
|      | ||||
|     fun joinRoom(username: String, roomName: String): Boolean { | ||||
|         if (!roomList.contains(roomName)) { | ||||
|             createRoom(roomName) | ||||
|         } | ||||
|          | ||||
|         val currentRoom = userRooms[username] | ||||
|         if (currentRoom != null) { | ||||
|             roomUsers[currentRoom]?.remove(username) | ||||
|              | ||||
|             val leftMessage = JSONObject().apply { | ||||
|                 put("type", "roomLeave") | ||||
|                 put("username", "system") | ||||
|                 put("room", currentRoom) | ||||
|                 put("content", "$username left the room") | ||||
|             } | ||||
|             broadcastToRoom(currentRoom, leftMessage.toString()) | ||||
|              | ||||
|             broadcastRoomUsers(currentRoom) | ||||
|         } | ||||
|          | ||||
|         userRooms[username] = roomName | ||||
|         roomUsers[roomName]?.add(username) | ||||
|          | ||||
|         broadcastRoomUsers(roomName) | ||||
|         return true | ||||
|     } | ||||
|      | ||||
|     fun getRoomUsers(roomName: String): List<String> { | ||||
|         return roomUsers[roomName] ?: listOf() | ||||
|     } | ||||
|      | ||||
|     fun broadcastRoomUsers(roomName: String) { | ||||
|         val usersInRoom = roomUsers[roomName] ?: listOf() | ||||
|         val processedData = JSONObject().apply { | ||||
|             put("type", "roomUsers") | ||||
|             put("username", "system") | ||||
|             put("room", roomName) | ||||
|             put("content", usersInRoom.joinToString(", ")) | ||||
|         } | ||||
|         broadcastToRoom(roomName, processedData.toString(), false) | ||||
|     } | ||||
|      | ||||
|     fun broadcastOnlineUsers() { | ||||
|         val processedData = JSONObject().apply { | ||||
|             put("type", "users") | ||||
|             put("username", "system") | ||||
|             put("content", peopleOnline.joinToString(", ")) | ||||
|         } | ||||
|         broadcast(processedData.toString()) | ||||
|     } | ||||
|      | ||||
|     fun broadcastToRoom(roomName: String, message: String, cleanupDeadSessions: Boolean = true) { | ||||
|         val deadSessions = mutableListOf<WsContext>() | ||||
|          | ||||
|         sessions.keys.forEach { ctx -> | ||||
|             try { | ||||
|                 if (ctx.session.isOpen) { | ||||
|                     val sessionId = sessions[ctx] | ||||
|                     if (sessionId != null) { | ||||
|                         val username = userSessions.entries.find { it.value == sessionId }?.key | ||||
|                         if (username != null && userRooms[username] == roomName) { | ||||
|                             ctx.send(message) | ||||
|                         } | ||||
|                     } | ||||
|                 } else { | ||||
|                     deadSessions.add(ctx) | ||||
|                 } | ||||
|             } catch (e: Exception) { | ||||
|                 println("Error broadcasting to session: ${e.message}") | ||||
|                 deadSessions.add(ctx) | ||||
|             } | ||||
|         } | ||||
|          | ||||
|         if (cleanupDeadSessions) { | ||||
|             deadSessions.forEach { removeSessionWithoutBroadcast(it) } | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     private fun removeSessionWithoutBroadcast(ctx: WsContext) { | ||||
|         try { | ||||
|             val sessionId = sessions[ctx] | ||||
|             if (sessionId != null) { | ||||
|                 userSessions.entries.find { it.value == sessionId }?.let { entry -> | ||||
|                     val username = entry.key | ||||
|                     val room = userRooms[username] | ||||
|                      | ||||
|                     if (room != null) { | ||||
|                         roomUsers[room]?.remove(username) | ||||
|                     } | ||||
|                      | ||||
|                     peopleOnline.remove(username) | ||||
|                     userSessions.remove(username) | ||||
|                     userRooms.remove(username) | ||||
|                 } | ||||
|  | ||||
|                 sessionsList.remove(sessionId) | ||||
|                 sessions.remove(ctx) | ||||
|                 sessionIds.remove(sessionId) | ||||
|             } | ||||
|         } catch (e: Exception) { | ||||
|             println("Error removing session without broadcast: ${e.message}") | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     fun handleUserLogin(username: String) { | ||||
|         if (!peopleOnline.contains(username)) { | ||||
|             peopleOnline.add(username) | ||||
|             if (!userRooms.containsKey(username)) { | ||||
|                 joinRoom(username, "general") | ||||
|             } | ||||
|             broadcastOnlineUsers() | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     private fun sendPing() { | ||||
|         val deadSessions = mutableListOf<WsContext>() | ||||
|  | ||||
| @@ -99,31 +229,13 @@ object WsSessionManager { | ||||
|                 deadSessions.add(ctx) | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // Clean up any dead sessions | ||||
|         deadSessions.forEach { removeSession(it) } | ||||
|     } | ||||
|  | ||||
|     fun broadcastOnlineUsers() { | ||||
|         val processedData = JSONObject().apply { | ||||
|             put("type", "users") | ||||
|             put("username", "system") | ||||
|             put("content", peopleOnline.joinToString(", ")) | ||||
|         } | ||||
|         broadcast(processedData.toString()) | ||||
|     } | ||||
|  | ||||
|     fun handleUserLogin(username: String) { | ||||
|         if (!peopleOnline.contains(username)) { | ||||
|             peopleOnline.add(username) | ||||
|             broadcastOnlineUsers() | ||||
|         } | ||||
|     } | ||||
|  | ||||
|      | ||||
|     fun addSession(ctx: WsContext) { | ||||
|         try { | ||||
|             val sessionId = UUID.randomUUID().toString() | ||||
|             sessionsList.add(sessionId)  // Changed from += to add() | ||||
|             sessionsList.add(sessionId)   | ||||
|             sessions[ctx] = sessionId | ||||
|             sessionIds[sessionId] = ctx | ||||
|         } catch (e: Exception) { | ||||
| @@ -135,10 +247,18 @@ object WsSessionManager { | ||||
|         try { | ||||
|             val sessionId = sessions[ctx] | ||||
|             if (sessionId != null) { | ||||
|                 // Find and remove the username associated with this session | ||||
|                 userSessions.entries.find { it.value == sessionId }?.let { entry -> | ||||
|                     peopleOnline.remove(entry.key) | ||||
|                     userSessions.remove(entry.key) | ||||
|                     val username = entry.key | ||||
|                     val room = userRooms[username] | ||||
|                      | ||||
|                     if (room != null) { | ||||
|                         roomUsers[room]?.remove(username) | ||||
|                         broadcastRoomUsers(room) | ||||
|                     } | ||||
|                      | ||||
|                     peopleOnline.remove(username) | ||||
|                     userSessions.remove(username) | ||||
|                     userRooms.remove(username) | ||||
|                 } | ||||
|  | ||||
|                 sessionsList.remove(sessionId) | ||||
| @@ -157,7 +277,7 @@ object WsSessionManager { | ||||
|             userSessions[username] = sessionId | ||||
|         } | ||||
|     } | ||||
|  | ||||
|      | ||||
|     fun broadcast(message: String) { | ||||
|         val deadSessions = mutableListOf<WsContext>() | ||||
|          | ||||
| @@ -174,48 +294,202 @@ object WsSessionManager { | ||||
|             } | ||||
|         } | ||||
|          | ||||
|         // Clean up any dead sessions | ||||
|         deadSessions.forEach { removeSession(it) } | ||||
|     } | ||||
|  | ||||
|     fun getSessionCount(): Int = sessions.size | ||||
|      | ||||
|     fun getUserRoom(username: String): String? { | ||||
|         return userRooms[username] | ||||
|     } | ||||
|      | ||||
|     fun getRooms(): List<String> { | ||||
|         return roomList | ||||
|     } | ||||
| } | ||||
|  | ||||
| fun extractMessageContent(inputData: String, ctx: WsContext): String { | ||||
|     val jsonInputData = JSONObject(inputData) | ||||
|      | ||||
|     if (jsonInputData.getString("type") == "connect") { | ||||
|         val username = jsonInputData.getString("username") | ||||
|         WsSessionManager.associateUserWithSession(username, ctx) | ||||
|         WsSessionManager.handleUserLogin(username) | ||||
|          | ||||
|         val processedData = JSONObject().apply { | ||||
|             put("type", "connect") | ||||
|             put("username", "system") | ||||
|             put("content", "${jsonInputData.getString("username")} just joined the room!") | ||||
|             put("content", "${jsonInputData.getString("username")} just joined the chat!") | ||||
|         } | ||||
|         return(processedData.toString()) | ||||
|         return processedData.toString() | ||||
|     } | ||||
|      | ||||
|     if (jsonInputData.getString("type") == "joinRoom") { | ||||
|         val username = jsonInputData.getString("username") | ||||
|         val roomName = jsonInputData.getString("room") | ||||
|          | ||||
|         if (!jsonInputData.has("token")) { | ||||
|             val processedData = JSONObject().apply { | ||||
|                 put("type", "error") | ||||
|                 put("username", "system") | ||||
|                 put("content", "Authentication required") | ||||
|             } | ||||
|             return processedData.toString() | ||||
|         } | ||||
|          | ||||
|         val success = WsSessionManager.joinRoom(username, roomName) | ||||
|         if (success) { | ||||
|             val processedData = JSONObject().apply { | ||||
|                 put("type", "roomJoin") | ||||
|                 put("username", "system") | ||||
|                 put("room", roomName) | ||||
|                 put("content", "$username just joined the room!") | ||||
|             } | ||||
|             return processedData.toString() | ||||
|         } else { | ||||
|             val processedData = JSONObject().apply { | ||||
|                 put("type", "error") | ||||
|                 put("username", "system") | ||||
|                 put("content", "Failed to join room: $roomName") | ||||
|             } | ||||
|             return processedData.toString() | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     if (jsonInputData.getString("type") == "getUsersInRoom") { | ||||
|         val username = jsonInputData.getString("username") | ||||
|         val roomName = jsonInputData.getString("room") | ||||
|          | ||||
|         if (!jsonInputData.has("token")) { | ||||
|             val processedData = JSONObject().apply { | ||||
|                 put("type", "error") | ||||
|                 put("username", "system") | ||||
|                 put("content", "Authentication required") | ||||
|             } | ||||
|             return processedData.toString() | ||||
|         } | ||||
|          | ||||
|         val usersInRoom = WsSessionManager.getRoomUsers(roomName) | ||||
|         val processedData = JSONObject().apply { | ||||
|             put("type", "roomUsers") | ||||
|             put("username", "system") | ||||
|             put("room", roomName) | ||||
|             put("content", usersInRoom.joinToString(", ")) | ||||
|         } | ||||
|         return processedData.toString() | ||||
|     } | ||||
|      | ||||
|     if (jsonInputData.getString("type") == "createRoom") { | ||||
|         val username = jsonInputData.getString("username") | ||||
|         val roomName = jsonInputData.getString("room") | ||||
|          | ||||
|         if (!jsonInputData.has("token")) { | ||||
|             val processedData = JSONObject().apply { | ||||
|                 put("type", "error") | ||||
|                 put("username", "system") | ||||
|                 put("content", "Authentication required") | ||||
|             } | ||||
|             return processedData.toString() | ||||
|         } | ||||
|          | ||||
|         val success = WsSessionManager.createRoom(roomName) | ||||
|         if (success) { | ||||
|             WsSessionManager.joinRoom(username, roomName) | ||||
|             val processedData = JSONObject().apply { | ||||
|                 put("type", "roomCreated") | ||||
|                 put("username", "system") | ||||
|                 put("room", roomName) | ||||
|                 put("content", "Room '$roomName' created and joined!") | ||||
|             } | ||||
|             return processedData.toString() | ||||
|         } else { | ||||
|             val processedData = JSONObject().apply { | ||||
|                 put("type", "error") | ||||
|                 put("username", "system")  | ||||
|                 put("content", "Room '$roomName' already exists!") | ||||
|             } | ||||
|             return processedData.toString() | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     val username = jsonInputData.getString("username") | ||||
|     val room = WsSessionManager.getUserRoom(username) ?: "general" | ||||
|      | ||||
|     val processedData = JSONObject().apply { | ||||
|         put("type", jsonInputData.getString("type")) | ||||
|         put("username", jsonInputData.getString("username")) | ||||
|         put("username", username) | ||||
|         put("room", room) | ||||
|         put("content", jsonInputData.getString("content")) | ||||
|     }     | ||||
|     return(processedData.toString()) | ||||
|     } | ||||
|      | ||||
|     return processedData.toString() | ||||
| } | ||||
|  | ||||
| fun handleSentMessage(inputData: String): String { | ||||
|     println("API request recieved: $inputData") | ||||
|     println("API request received: $inputData") | ||||
|     var jsonInputData: JSONObject | ||||
|     try {jsonInputData = JSONObject(inputData)} catch (error: JSONException){return(error.toString())} | ||||
|     try { | ||||
|         jsonInputData = JSONObject(inputData) | ||||
|     } catch (error: JSONException) { | ||||
|         return error.toString() | ||||
|     } | ||||
|      | ||||
|     val username = jsonInputData.getString("username") | ||||
|     val token = jsonInputData.getString("token") | ||||
|     val content = jsonInputData.getString("content") | ||||
|  | ||||
|     val type = jsonInputData.getString("type") | ||||
|      | ||||
|     if (jsonInputData.has("type")) { | ||||
|         val type = jsonInputData.getString("type") | ||||
|         if (type == "joinRoom" || type == "createRoom") { | ||||
|             val userDatabaseParser = BufferedReader(File("userDatabase").reader()) | ||||
|             var userLine = "" | ||||
|              | ||||
|             userDatabaseParser.forEachLine { line -> | ||||
|                 if (line.contains(username)) { | ||||
|                     userLine = line | ||||
|                 } | ||||
|             } | ||||
|             userDatabaseParser.close() | ||||
|              | ||||
|             if (userLine == "") { | ||||
|                 val processedData = JSONObject().apply { | ||||
|                     put("type", "error") | ||||
|                     put("username", "system") | ||||
|                     put("content", "unknown-account") | ||||
|                 }     | ||||
|                 return processedData.toString() | ||||
|             } | ||||
|              | ||||
|             var tokenInDatabase = "" | ||||
|             var currentStage = 0 | ||||
|             for (char in userLine) { | ||||
|                 if (char == ':') { | ||||
|                     currentStage++ | ||||
|                 } | ||||
|                 if (currentStage == 1) { | ||||
|                     tokenInDatabase += char | ||||
|                 } | ||||
|             } | ||||
|             tokenInDatabase = tokenInDatabase.replace(":", "") | ||||
|              | ||||
|             if (token != tokenInDatabase) { | ||||
|                 val processedData = JSONObject().apply { | ||||
|                     put("type", "error") | ||||
|                     put("username", "system") | ||||
|                     put("content", "invalid-token") | ||||
|                 } | ||||
|                 return processedData.toString() | ||||
|             } | ||||
|              | ||||
|             return "Success"  | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     val userDatabaseParser = BufferedReader(File("userDatabase").reader()) | ||||
|     var lineNumber = 1 | ||||
|     var userLine = "" | ||||
|      | ||||
|     // Search the user database to find required information about the user | ||||
|     userDatabaseParser.forEachLine { line -> | ||||
|         if (line.contains(username)) { | ||||
|             userLine = line | ||||
| @@ -230,7 +504,7 @@ fun handleSentMessage(inputData: String): String { | ||||
|             put("username", "system") | ||||
|             put("content", "unknown-account") | ||||
|         }     | ||||
|         return(processedData.toString()) | ||||
|         return processedData.toString() | ||||
|     } | ||||
|   | ||||
|     var usernameInDatabase = "" | ||||
| @@ -255,133 +529,54 @@ fun handleSentMessage(inputData: String): String { | ||||
|     tokenInDatabase = tokenInDatabase.replace(":", "") | ||||
|     saltInDatabase = saltInDatabase.replace(":", "") | ||||
|     banStatus = banStatus.replace(":", "") | ||||
|      | ||||
|     if (banStatus == "1") { | ||||
|         val processedData = JSONObject().apply { | ||||
|             put("type", "error") | ||||
|             put("username", "system") | ||||
|             put("content", "banned") | ||||
|         }     | ||||
|         return(processedData.toString()) | ||||
|         return processedData.toString() | ||||
|     } | ||||
|     val tokenWithSalt = (md5(token + saltInDatabase)) | ||||
|     /*println(saltInDatabase) | ||||
|     println(tokenWithSalt) | ||||
|     if (tokenWithSalt != tokenInDatabase)  {*/ | ||||
|      | ||||
|     if (token != tokenInDatabase) { | ||||
|         val processedData = JSONObject().apply { | ||||
|             put("type", "error") | ||||
|             put("username", "system") | ||||
|             put("content", "invalid-token") | ||||
|         } | ||||
|         return(processedData.toString()) | ||||
|         return processedData.toString() | ||||
|     } | ||||
|     // Make the message to respond to the client | ||||
|     val chatHistoryView = File("chatHistory") | ||||
|     var fullMessage = "" | ||||
|     if (content != "") { | ||||
|         fullMessage = "${chatHistoryView.readText()}$username: $content" | ||||
|         // Add the client's message to the chat history | ||||
|         val chatHistory = File("chatHistory") | ||||
|         chatHistory.appendText("$username: $content ${System.lineSeparator()}") | ||||
|         return("Success") | ||||
|     } else { | ||||
|         return("No data provided") | ||||
|     } | ||||
|     return("Chookchat") | ||||
| } | ||||
|  | ||||
| fun createAccount(inputData: String): String { | ||||
|     println("Account creation request recieved: $inputData") | ||||
|     // Parse data sent to the server by client | ||||
|     var username = "" | ||||
|     var token = "" | ||||
|     var message = "" | ||||
|     var dataType = "" | ||||
|     var isParsingData = 0 | ||||
|     for (char in inputData) { | ||||
|         val character = char | ||||
|         if (character == ':') { | ||||
|             isParsingData = 1 | ||||
|         } else if (isParsingData == 1) { | ||||
|             if (character == '}') { | ||||
|                 isParsingData = 0 | ||||
|                 dataType = "" | ||||
|             } else if (character != '{') { | ||||
|                 if (dataType == "username") { | ||||
|                     username += character | ||||
|                 } else if (dataType == "token") { | ||||
|                     token += character | ||||
|                 } else if (dataType == "message") { | ||||
|                     message += character | ||||
|                 } | ||||
|             } | ||||
|         } else { | ||||
|             dataType += character | ||||
|         } | ||||
|     } | ||||
|     val userDatabaseParser = BufferedReader(File("userDatabase").reader()) | ||||
|     var lineNumber = 1 | ||||
|     var userExists = 0 | ||||
|      | ||||
|     // Search the user database to find required information about the user | ||||
|     var response = "" | ||||
|     userDatabaseParser.forEachLine { line -> | ||||
|         if (line.contains(username)) { | ||||
|             val processedData = JSONObject().apply { | ||||
|                 put("type", "error") | ||||
|                 put("username", "system") | ||||
|                 put("content", "username-taken") | ||||
|             } | ||||
|             response = processedData.toString()        | ||||
|     if (content != "") { | ||||
|         if (type != "message") { | ||||
|             return "Success" | ||||
|         } | ||||
|         lineNumber++ | ||||
|     } | ||||
|     if (response != "") { | ||||
|         return(response) | ||||
|     } | ||||
|     userDatabaseParser.close() | ||||
|     if (username == "") { | ||||
|         val processedData = JSONObject().apply { | ||||
|             put("type", "error") | ||||
|             put("username", "system") | ||||
|             put("content", "no-username") | ||||
|         val room = WsSessionManager.getUserRoom(username) ?: "general" | ||||
|          | ||||
|         val roomDirectory = File("roomChats") | ||||
|         if (!roomDirectory.exists()) { | ||||
|             roomDirectory.mkdir() | ||||
|         } | ||||
|         return(processedData.toString()) | ||||
|          | ||||
|         val roomChatHistory = File("roomChats/$room.txt") | ||||
|         roomChatHistory.appendText("$username: $content ${System.lineSeparator()}") | ||||
|          | ||||
|         val chatHistory = File("chatHistory") | ||||
|         chatHistory.appendText("$username: $content [Room: $room] ${System.lineSeparator()}") | ||||
|          | ||||
|         return "Success" | ||||
|     } else { | ||||
|         return "No data provided" | ||||
|     } | ||||
|  | ||||
|     if (token == "") { | ||||
|         val processedData = JSONObject().apply { | ||||
|             put("type", "error") | ||||
|             put("username", "system") | ||||
|             put("content", "no-token") | ||||
|         } | ||||
|         return(processedData.toString()) | ||||
|     } | ||||
|  | ||||
|     val userDatabaseFile = File("userDatabase") | ||||
|     userDatabaseFile.appendText("${System.lineSeparator()}$username:$token") | ||||
|     val processedData = JSONObject().apply { | ||||
|         put("type", "success") | ||||
|         put("username", "system") | ||||
|         put("content", "success") | ||||
|     } | ||||
|     return(processedData.toString()) | ||||
| } | ||||
|  | ||||
| fun handleServerCommand(command: String): String { | ||||
|     val commandArgs = mutableListOf("") | ||||
|     commandArgs.drop(1) | ||||
|     var currentStage = 0 | ||||
|  | ||||
|     for (char in command) { | ||||
|         if (char == ' ') { | ||||
|             currentStage ++ | ||||
|             commandArgs += "" | ||||
|         } else { | ||||
|             commandArgs[currentStage] += char | ||||
|         } | ||||
| fun getRoomChatHistory(roomName: String): String { | ||||
|     val roomChatFile = File("roomChats/$roomName.txt") | ||||
|     if (roomChatFile.exists()) { | ||||
|         return roomChatFile.readText() | ||||
|     } | ||||
|     return("I'm not sure how to ${commandArgs.toString()}") | ||||
|     return "" | ||||
| } | ||||
|  | ||||
| fun buildHTML(): String { | ||||
| @@ -442,7 +637,6 @@ fun buildJS(): String { | ||||
|                 editedJS += "$line\n" | ||||
|             } | ||||
|         } | ||||
|         //editedJS += js | ||||
|         for (line in eggs) { | ||||
|             val eggJSFile = File("eggs/$line/index.js") | ||||
|             if (eggJSFile.exists()) { | ||||
| @@ -458,19 +652,136 @@ fun buildJS(): String { | ||||
|     return("dingus") | ||||
| } | ||||
|  | ||||
| fun handleServerCommand(command: String): String { | ||||
|     val commandArgs = mutableListOf("") | ||||
|     commandArgs.drop(1) | ||||
|     var currentStage = 0 | ||||
|  | ||||
|     for (char in command) { | ||||
|         if (char == ' ') { | ||||
|             currentStage ++ | ||||
|             commandArgs += "" | ||||
|         } else { | ||||
|             commandArgs[currentStage] += char | ||||
|         } | ||||
|     } | ||||
|     return("I'm not sure how to ${commandArgs.toString()}") | ||||
| } | ||||
|  | ||||
| fun createAccount(inputData: String): String { | ||||
|     println("Account creation request recieved: $inputData") | ||||
|     var username = "" | ||||
|     var token = "" | ||||
|     var message = "" | ||||
|     var dataType = "" | ||||
|     var isParsingData = 0 | ||||
|     for (char in inputData) { | ||||
|         val character = char | ||||
|         if (character == ':') { | ||||
|             isParsingData = 1 | ||||
|         } else if (isParsingData == 1) { | ||||
|             if (character == '}') { | ||||
|                 isParsingData = 0 | ||||
|                 dataType = "" | ||||
|             } else if (character != '{') { | ||||
|                 if (dataType == "username") { | ||||
|                     username += character | ||||
|                 } else if (dataType == "token") { | ||||
|                     token += character | ||||
|                 } else if (dataType == "message") { | ||||
|                     message += character | ||||
|                 } | ||||
|             } | ||||
|         } else { | ||||
|             dataType += character | ||||
|         } | ||||
|     } | ||||
|     val userDatabaseParser = BufferedReader(File("userDatabase").reader()) | ||||
|     var lineNumber = 1 | ||||
|     var userExists = 0 | ||||
|  | ||||
|     var response = "" | ||||
|     userDatabaseParser.forEachLine { line -> | ||||
|         if (line.contains(username)) { | ||||
|             val processedData = JSONObject().apply { | ||||
|                 put("type", "error") | ||||
|                 put("username", "system") | ||||
|                 put("content", "username-taken") | ||||
|             } | ||||
|             response = processedData.toString() | ||||
|         } | ||||
|         lineNumber++ | ||||
|     } | ||||
|     if (response != "") { | ||||
|         return(response) | ||||
|     } | ||||
|     userDatabaseParser.close() | ||||
|     if (username == "") { | ||||
|         val processedData = JSONObject().apply { | ||||
|             put("type", "error") | ||||
|             put("username", "system") | ||||
|             put("content", "no-username") | ||||
|         } | ||||
|         return(processedData.toString()) | ||||
|     } | ||||
|  | ||||
|     if (token == "") { | ||||
|         val processedData = JSONObject().apply { | ||||
|             put("type", "error") | ||||
|             put("username", "system") | ||||
|             put("content", "no-token") | ||||
|         } | ||||
|         return(processedData.toString()) | ||||
|     } | ||||
|  | ||||
|     val userDatabaseFile = File("userDatabase") | ||||
|     userDatabaseFile.appendText("${System.lineSeparator()}$username:$token") | ||||
|     val processedData = JSONObject().apply { | ||||
|         put("type", "success") | ||||
|         put("username", "system") | ||||
|         put("content", "success") | ||||
|     } | ||||
|     return(processedData.toString()) | ||||
| } | ||||
|  | ||||
| fun main(args: Array<String>) { | ||||
|     WsSessionManager.peopleOnline.removeAt(0) | ||||
|     WsSessionManager.sessionsList.removeAt(0) | ||||
|     WsSessionManager.peopleOnline.clear() | ||||
|     WsSessionManager.sessionsList.clear() | ||||
|     WsSessionManager.roomList.clear() | ||||
|      | ||||
|     WsSessionManager.createRoom("general") | ||||
|      | ||||
|     val roomDirectory = File("roomChats") | ||||
|     if (!roomDirectory.exists()) { | ||||
|         roomDirectory.mkdir() | ||||
|     } | ||||
|      | ||||
|     val app = Javalin.create { config -> | ||||
|             config.staticFiles.add("/public") | ||||
|         }.get("/") { ctx ->   | ||||
|         } | ||||
|         .get("/") { ctx ->   | ||||
|             ctx.html(buildHTML()) | ||||
|             //ctx.redirect("/index.html")  | ||||
|         } | ||||
|         .get("/index.js") { ctx -> | ||||
|             ctx.result(buildJS()) | ||||
|         } | ||||
|         .get("/api/createaccount/{content}") { ctx -> ctx.result(createAccount(ctx.pathParam("content")))} | ||||
|         .get("/api/createaccount/{content}") { ctx ->  | ||||
|             ctx.result(createAccount(ctx.pathParam("content"))) | ||||
|         } | ||||
|         .get("/api/rooms") { ctx -> | ||||
|             val rooms = WsSessionManager.getRooms() | ||||
|             val roomsJson = JSONArray(rooms) | ||||
|             val processedData = JSONObject().apply { | ||||
|                 put("type", "roomsList") | ||||
|                 put("username", "system") | ||||
|                 put("content", roomsJson.toString()) | ||||
|             } | ||||
|             ctx.result(processedData.toString()) | ||||
|         } | ||||
|         .get("/api/room/{roomName}/history") { ctx -> | ||||
|             val roomName = ctx.pathParam("roomName") | ||||
|             ctx.result(getRoomChatHistory(roomName)) | ||||
|         } | ||||
|         .post("/api/upload") { ctx -> | ||||
|             val uploadedFiles = ctx.uploadedFiles() | ||||
|             if (uploadedFiles.isEmpty()) { | ||||
| @@ -485,18 +796,28 @@ fun main(args: Array<String>) { | ||||
|             val newFilename = "${baseFilename}_${uuid}${if (fileExtension.isNotEmpty()) ".$fileExtension" else ""}" | ||||
|             val filePath = Paths.get("uploads", newFilename) | ||||
|             Files.copy(uploadedFile.content(), filePath) | ||||
|              | ||||
|             val room = if (ctx.formParam("room") != null) ctx.formParam("room") else "general" | ||||
|              | ||||
|             val processedData = JSONObject().apply { | ||||
|                 put("type", "fileStatus") | ||||
|                 put("username", "system") | ||||
|                 put("content", "success") | ||||
|             } | ||||
|             ctx.result(processedData.toString()) | ||||
|              | ||||
|             val processedData2 = JSONObject().apply { | ||||
|                 put("type", "file") | ||||
|                 put("username", "system") | ||||
|                 put("room", room) | ||||
|                 put("content", "https://maxwellj.xyz/chookchat/uploads/$newFilename") | ||||
|             } | ||||
|             WsSessionManager.broadcast(processedData2.toString()) | ||||
|              | ||||
|             if (room != null && room != "general") { | ||||
|                 WsSessionManager.broadcastToRoom(room, processedData2.toString()) | ||||
|             } else { | ||||
|                 WsSessionManager.broadcast(processedData2.toString()) | ||||
|             } | ||||
|         } | ||||
|         .ws("/api/websocket") { ws ->  | ||||
|             ws.onConnect { ctx ->  | ||||
| @@ -508,24 +829,42 @@ fun main(args: Array<String>) { | ||||
|             ws.onMessage { ctx -> | ||||
|                 when (ctx.message()) { | ||||
|                     "pong" -> {} | ||||
|                 else -> { | ||||
|                     println(ctx.message())  | ||||
|                     val successState = handleSentMessage(ctx.message()) | ||||
|                     if (successState != "Success") { | ||||
|                         try { | ||||
|                             ctx.send(successState) | ||||
|                         } catch (e: Exception) { | ||||
|                             println("Error sending error message: ${e.message}") | ||||
|                     else -> { | ||||
|                         println(ctx.message())  | ||||
|                         val successState = handleSentMessage(ctx.message()) | ||||
|                         if (successState != "Success") { | ||||
|                             try { | ||||
|                                 ctx.send(successState) | ||||
|                             } catch (e: Exception) { | ||||
|                                 println("Error sending error message: ${e.message}") | ||||
|                             } | ||||
|                         } else { | ||||
|                             val messageContent = extractMessageContent(ctx.message(), ctx) | ||||
|                              | ||||
|                             try { | ||||
|                                 val jsonMessage = JSONObject(messageContent) | ||||
|                                 if (jsonMessage.has("room")) { | ||||
|                                     val room = jsonMessage.getString("room") | ||||
|                                     if (WsSessionManager.roomList.contains(room)) { | ||||
|                                         WsSessionManager.broadcastToRoom(room, messageContent) | ||||
|                                     } else { | ||||
|                                         WsSessionManager.createRoom(room) | ||||
|                                         WsSessionManager.broadcastToRoom(room, messageContent) | ||||
|                                     } | ||||
|                                 } else { | ||||
|                                     WsSessionManager.broadcastToRoom("general", messageContent) | ||||
|                                 } | ||||
|                             } catch (e: Exception) { | ||||
|                                 println("Error in broadcasting message: ${e.message}") | ||||
|                                 WsSessionManager.broadcastToRoom("general", messageContent) | ||||
|                             } | ||||
|                         } | ||||
|                     } else { | ||||
|                         val messageContent = extractMessageContent(ctx.message(), ctx) | ||||
|                         WsSessionManager.broadcast(messageContent) | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             } | ||||
|         } | ||||
|     .start(7070) | ||||
|         .start(7070) | ||||
|      | ||||
|     try { | ||||
|         if (args[0] == "-i") { | ||||
|             println("Type a command for the server") | ||||
| @@ -539,4 +878,3 @@ fun main(args: Array<String>) { | ||||
|         println("Interactive mode disabled, add -i to enable") | ||||
|     } | ||||
| } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Maxwell Jeffress
					Maxwell Jeffress