/
ledart
/
RRP_LedNik
Обзор
Документация
Войти
/
ledart
/
RRP_LedNik
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
develop
server/Room.java
265 строк
8 KB
Darya
обновлены комментарии
18 дек 2025, 14:46
18 дек 2025, 14:46
95c0a7f
Код
Авторство
О чём код?
package server; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; public class Room { public enum RoomState { WAITING, READY, COUNTDOWN, GAME } private final String name; private final CopyOnWriteArrayList<ClientHandler> players = new CopyOnWriteArrayList<>(); private boolean botGame = false; private Bot bot; private GameSession gameSession; private RoomState state = RoomState.WAITING; private ConcurrentHashMap<String, Integer> sessionScores = new ConcurrentHashMap<>(); private ConcurrentHashMap<String, Integer> bestSessionScores = new ConcurrentHashMap<>(); public Room(String name) { this.name = name; } public String getName() { return name; } public List<ClientHandler> getPlayers() { return new ArrayList<>(players); } public RoomState getState() { return state; } public boolean hasBot() { return botGame && bot != null; } public Bot getBot() { return bot; } public int getPlayerCount() { int count = players.size(); if (hasBot()) { count++; } return count; } public ConcurrentHashMap<String, Integer> getSessionScores() { return sessionScores; } public ConcurrentHashMap<String, Integer> getBestSessionScores() { return bestSessionScores; } public void updateSessionScore(String player, int points) { int current = sessionScores.getOrDefault(player, 0); sessionScores.put(player, current + points); int best = bestSessionScores.getOrDefault(player, 0); if (current + points > best) { bestSessionScores.put(player, current + points); } System.out.println("[Room] Session score: " + player + " = " + (current + points)); broadcastSessionScores(); } private void broadcastSessionScores() { if (sessionScores.isEmpty()) return; StringBuilder sb = new StringBuilder("SESSION_SCORES:"); for (Map.Entry<String, Integer> entry : sessionScores.entrySet()) { sb.append(entry.getKey()).append(":").append(entry.getValue()).append(";"); } if (sb.charAt(sb.length() - 1) == ';') { sb.deleteCharAt(sb.length() - 1); } broadcast(sb.toString()); } public void broadcastChat(String message) { broadcast("CHAT_MSG:" + message); } public void saveBestScoresToDB(Database db) { for (Map.Entry<String, Integer> entry : bestSessionScores.entrySet()) { String player = entry.getKey(); int sessionScore = entry.getValue(); int bestInDB = db.getPlayerScore(player); // Сохраняем ТОЛЬКО если новый результат лучше if (sessionScore > bestInDB) { db.updatePlayerStatsDirect(player, sessionScore); System.out.println("[Room] Saved best score for " + player + ": " + sessionScore); } } sessionScores.clear(); bestSessionScores.clear(); } // Управление игроками в комнате public synchronized void addPlayer(ClientHandler player) { if (players.contains(player)) { System.out.println("[Room] Player already in room: " + player.getUsername()); return; } players.add(player); System.out.println("[Room] " + player.getUsername() + " joined " + name + " (total: " + players.size() + ")"); broadcast("PLAYER_JOINED:" + player.getUsername()); if (players.size() == 1) { state = RoomState.WAITING; player.send("ROOM_WAITING"); broadcastRoomInfo(); } else if (players.size() == 2) { state = RoomState.READY; broadcast("ROOM_READY"); broadcastRoomInfo(); startGame(); } } // Управление игроками в комнате public synchronized void removePlayer(ClientHandler player) { if (players.remove(player)) { System.out.println("[Room] " + player.getUsername() + " left " + name + " (remaining: " + players.size() + ")"); broadcast("PLAYER_LEFT:" + player.getUsername()); if (players.size() < 2) { state = RoomState.WAITING; broadcastRoomInfo(); if (gameSession != null) { gameSession.running = false; gameSession = null; broadcast("GAME_STOPPED"); } sessionScores.clear(); bestSessionScores.clear(); broadcast("SCORES_RESET"); if (hasBot()) { botGame = false; bot = null; } } } } public void setBotGame(boolean botGame) { this.botGame = botGame; } public void setBot(Bot bot) { this.bot = bot; } // Управление игрой public void startGame() { if (state == RoomState.GAME) { System.out.println("[Room] Game already finished, resetting..."); if (gameSession != null) { gameSession.running = false; gameSession = null; } state = RoomState.READY; } if (state != RoomState.READY && state != RoomState.WAITING) { System.out.println("[Room] Cannot start game, state is: " + state); return; } if (players.size() < 1) { System.out.println("[Room] Not enough players to start"); return; } startCountdown(); } private void startCountdown() { state = RoomState.COUNTDOWN; System.out.println("[Room] Starting countdown in room: " + name); new Thread(() -> { try { broadcast("COUNTDOWN:3"); Thread.sleep(1000); broadcast("COUNTDOWN:2"); Thread.sleep(1000); broadcast("COUNTDOWN:1"); Thread.sleep(1000); broadcast("COUNTDOWN:START"); startGameInternal(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); System.err.println("[Room] Countdown interrupted: " + e.getMessage()); } }, "Countdown-" + name).start(); } private void startGameInternal() { state = RoomState.GAME; System.out.println("[Room] Starting game in room: " + name); broadcast("GAME_START"); gameSession = new GameSession(this); // СОЗДАНИЕ сессии gameSession.start(); // ЗАПУСК в отдельном потоке if (hasBot()) { System.out.println("[Room] Starting bot in room: " + name); bot.start(gameSession); } } public void handleMove(String username, String direction) { if (state != RoomState.GAME) { System.out.println("[Room] Cannot move, game not running. State: " + state); return; } if (gameSession != null) { gameSession.handleMove(username, direction); } } public void broadcast(String message) { for (ClientHandler player : players) { try { player.send(message); } catch (Exception e) { System.err.println("[Room] Error sending to player: " + e.getMessage()); } } } private void broadcastRoomInfo() { broadcast("ROOM_INFO:" + name + ":" + getPlayerCount()); } public boolean isEmpty() { return players.isEmpty(); } }