/
ledart
/
RRP_LedNik
Обзор
Документация
Войти
/
ledart
/
RRP_LedNik
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
develop
server/ClientHandler.java
434 строки
13 KB
Darya
добавлена аутентификация с паролями
18 дек 2025, 04:44
18 дек 2025, 04:44
7f98831
Код
Авторство
О чём код?
package server; import java.io.*; import java.net.Socket; import java.util.List; public class ClientHandler implements Runnable { private Socket socket; private BufferedReader in; private PrintWriter out; private String username; private Database db; private List<Room> rooms; private Server server; private Room currentRoom; public ClientHandler(Socket socket, Database db, List<Room> rooms, Server server) { this.socket = socket; this.db = db; this.rooms = rooms; this.server = server; try { in = new BufferedReader(new InputStreamReader(socket.getInputStream())); out = new PrintWriter(socket.getOutputStream(), true); } catch (IOException e) { System.err.println("[ClientHandler] Error creating streams: " + e.getMessage()); } } public String getUsername() { return username; } public Database getDatabase() { return db; } public void send(String message) { if (out != null) { out.println(message); } } @Override public void run() { try { String line; while ((line = in.readLine()) != null) { System.out.println("[Server] Received from " + (username != null ? username : "unknown") + ": " + line); String[] parts = line.split(":", 3); if (parts.length < 1) continue; switch (parts[0]) { case "REGISTER" -> handleRegister(parts); case "LOGIN" -> handleLogin(parts); case "JOIN_ROOM" -> handleJoinRoom(parts); case "LEAVE_ROOM" -> handleLeaveRoom(); case "CREATE_ROOM" -> handleCreateRoom(parts); case "START_GAME" -> handleStartGame(parts); case "MOVE" -> handleMove(parts); case "PLAYER_READY" -> handlePlayerReady(); case "DISCONNECT" -> { handleDisconnect(); return; } case "REFRESH_ROOMS" -> handleRefreshRooms(); case "GET_TOP_SCORES" -> handleGetTopScores(); case "QUICK_CHAT" -> handleQuickChat(parts); case "CHAT" -> handleChat(parts); default -> System.out.println("[Server] Unknown command: " + line); } } } catch (IOException e) { System.out.println("[Server] Client disconnected: " + (username != null ? username : "unknown")); } finally { cleanup(); } } private void handleRegister(String[] parts) { if (parts.length < 3) { send("ERROR:Invalid register format. Use: REGISTER:username:password"); return; } String username = parts[1]; String password = parts[2]; if (username.length() < 3) { send("ERROR:Username too short (min 3 characters)"); return; } if (username.length() > 20) { send("ERROR:Username too long (max 20 characters)"); return; } if (password.length() < 4) { send("ERROR:Password too short (min 4 characters)"); return; } if (db.userExists(username)) { send("ERROR:Username already exists"); return; } boolean success = db.registerUser(username, password); if (success) { send("REGISTER_OK"); System.out.println("[Server] User registered: " + username); } else { send("ERROR:Registration failed"); } } private void handleLogin(String[] parts) { if (parts.length < 3) { send("ERROR:Invalid login format. Use: LOGIN:username:password"); return; } String username = parts[1]; String password = parts[2]; if (username.isEmpty() || password.isEmpty()) { send("ERROR:Username and password required"); return; } // ПРОВЕРКА: существует ли пользователь if (!db.userExists(username)) { send("ERROR:User does not exist"); return; } boolean authenticated = db.authenticateUser(username, password); if (!authenticated) { send("ERROR:Invalid password"); return; } this.username = username; send("LOGIN_OK:" + username); System.out.println("[Server] User logged in: " + username); server.broadcastChatToAll(username + " joined the lobby"); System.out.println("[Server] Sending " + rooms.size() + " rooms to " + username); for (Room room : rooms) { send("NEW_ROOM:" + room.getName()); send("ROOM_INFO:" + room.getName() + ":" + room.getPlayerCount()); System.out.println("[Server] Sent room info: " + room.getName() + " (" + room.getPlayerCount() + " players) to " + username); } } private void handleJoinRoom(String[] parts) { if (username == null) { send("ERROR:You must login first"); return; } if (parts.length < 2) { send("ERROR:Room name required"); return; } String roomName = parts[1]; Room room = findRoom(roomName); if (room == null) { send("ERROR:Room not found: " + roomName); return; } if (room.getPlayers().size() >= 2) { send("ERROR:Room is full"); return; } if (currentRoom != null) { currentRoom.removePlayer(this); } currentRoom = room; room.addPlayer(this); send("JOIN_ROOM_OK:" + roomName); System.out.println("[Server] " + username + " joined room: " + roomName); currentRoom.broadcastChat(username + " joined the room"); } private void handleLeaveRoom() { if (username == null) { send("ERROR:You must login first"); return; } if (currentRoom != null) { String roomName = currentRoom.getName(); if (db != null) { currentRoom.saveBestScoresToDB(db); } currentRoom.removePlayer(this); send("LEAVE_ROOM_OK:" + roomName); currentRoom = null; System.out.println("[Server] " + username + " left room: " + roomName); } } private void handleCreateRoom(String[] parts) { if (username == null) { send("ERROR:You must login first"); return; } if (parts.length < 2) { send("ERROR:Room name required"); return; } String roomName = parts[1]; if (findRoom(roomName) != null) { send("ERROR:Room already exists: " + roomName); return; } Room room = new Room(roomName); rooms.add(room); if (currentRoom != null) { currentRoom.removePlayer(this); } currentRoom = room; room.addPlayer(this); send("CREATE_ROOM_OK:" + roomName); server.broadcastNewRoom(roomName); server.broadcastToAll("ROOM_INFO:" + roomName + ":" + room.getPlayerCount()); System.out.println("[Server] " + username + " created room: " + roomName); server.broadcastChatToAll(username + " created room: " + roomName); currentRoom.broadcastChat("Welcome to room: " + roomName); } private void handleStartGame(String[] parts) { if (username == null) { send("ERROR:You must login first"); return; } if (currentRoom == null) { send("ERROR:Not in a room"); return; } System.out.println("[Server] Start game requested by " + username + " in room: " + currentRoom.getName() + " (state: " + currentRoom.getState() + ")"); if (parts.length > 1 && "BOT".equals(parts[1])) { currentRoom.setBotGame(true); currentRoom.setBot(new Bot("Bot_" + currentRoom.getName())); System.out.println("[Server] Bot game started in room: " + currentRoom.getName()); } currentRoom.startGame(); } private void handleMove(String[] parts) { if (username == null) { return; } if (currentRoom == null || parts.length < 2) { System.out.println("[Server] Cannot process MOVE: currentRoom=" + currentRoom + ", parts=" + parts.length); return; } String direction = parts[1]; System.out.println("[Server] Processing MOVE for " + username + ": " + direction); currentRoom.handleMove(username, direction); } private void handlePlayerReady() { if (username == null) { return; } System.out.println("[Server] Player ready: " + username + " in room: " + (currentRoom != null ? currentRoom.getName() : "none")); } private void handleRefreshRooms() { if (username == null) { send("ERROR:You must login first"); return; } System.out.println("[Server] " + username + " requested room refresh"); for (Room room : rooms) { send("NEW_ROOM:" + room.getName()); send("ROOM_INFO:" + room.getName() + ":" + room.getPlayerCount()); } send("REFRESH_COMPLETE"); } private void handleGetTopScores() { if (username == null) { send("ERROR:You must login first"); return; } System.out.println("[Server] " + username + " requested top scores"); var topScores = db.getTopScores(10); if (topScores.isEmpty()) { send("TOP_SCORES_EMPTY"); return; } send("TOP_SCORES_START"); for (var row : topScores) { String rowStr = String.join(":", row); send("TOP_SCORES_ROW:" + rowStr); } send("TOP_SCORES_END"); } private void handleQuickChat(String[] parts) { if (username == null) { return; } if (parts.length < 2) return; String phrase = parts[1]; String message = switch(phrase) { case "READY" -> ": Ready!"; case "GOOD_GAME" -> ": Good game!"; case "WELL_PLAYED" -> ": Well played!"; case "HELLO" -> ": Hello everyone!"; case "GOOD_LUCK" -> ": Good luck!"; default -> ": " + phrase; }; String fullMessage = username + message; if (currentRoom != null) { currentRoom.broadcastChat(fullMessage); } else { server.broadcastChatToAll(fullMessage); } } private void handleChat(String[] parts) { if (username == null) { send("ERROR:You must login first"); return; } if (parts.length < 2) { send("ERROR:Message required"); return; } String message = parts[1].trim(); if (message.isEmpty()) { send("ERROR:Message cannot be empty"); return; } String fullMessage = username + ": " + message; server.broadcastChatToAll(fullMessage); System.out.println("[Server] Chat message from " + username + ": " + message); } private void handleDisconnect() { System.out.println("[Server] Client requested disconnect: " + username); if (username != null) { if (currentRoom != null) { currentRoom.broadcastChat(username + " left the room"); } else { server.broadcastChatToAll(username + " left the lobby"); } } cleanup(); } private Room findRoom(String roomName) { for (Room room : rooms) { if (room.getName().equals(roomName)) { return room; } } return null; } private void cleanup() { System.out.println("[Server] Cleaning up client: " + username); if (currentRoom != null) { if (db != null) { currentRoom.saveBestScoresToDB(db); } currentRoom.removePlayer(this); currentRoom = null; } try { if (in != null) in.close(); if (out != null) out.close(); if (socket != null && !socket.isClosed()) socket.close(); } catch (IOException e) { System.err.println("[ClientHandler] Error closing resources: " + e.getMessage()); } server.removeClient(this); System.out.println("[Server] Client cleanup complete: " + username); } }