package com.cardshifter.server.model; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.atomic.AtomicReference; import java.util.function.Consumer; import java.util.function.Predicate; import java.util.stream.Collectors; import com.cardshifter.ai.FakeAIClientTCG; import com.cardshifter.api.*; import com.cardshifter.api.outgoing.*; import com.cardshifter.core.username.*; import com.cardshifter.server.clients.ClientSocketHandler; import com.cardshifter.server.clients.ClientWebSocket; import org.apache.log4j.LogManager; import org.apache.log4j.Logger; import com.cardshifter.api.both.ChatMessage; import com.cardshifter.api.both.InviteResponse; import com.cardshifter.api.both.PlayerConfigMessage; import com.cardshifter.api.incoming.LoginMessage; import com.cardshifter.api.incoming.RequestTargetsMessage; import com.cardshifter.api.incoming.ServerQueryMessage; import com.cardshifter.api.incoming.StartGameRequest; import com.cardshifter.api.incoming.UseAbilityMessage; import com.cardshifter.api.outgoing.UserStatusMessage.Status; import com.cardshifter.api.outgoing.WelcomeMessage; import com.cardshifter.core.game.FakeClient; import com.cardshifter.core.game.TCGGame; public class Handlers { private static final Logger logger = LogManager.getLogger(Handlers.class); private final Server server; public Handlers(Server server) { this.server = server; } public void query(ServerQueryMessage message, ClientIO client) { switch (message.getRequest()) { case USERS: List<ClientIO> clientsCopy = new ArrayList<>(server.getClients().values()); Consumer<ClientIO> sendUser = cl -> client.sendToClient(new UserStatusMessage(cl.getId(), cl.getName(), Status.ONLINE)); clientsCopy.stream() .filter(ClientIO::isLoggedIn) .forEach(sendUser); break; case DECK_BUILDER: Map<String, GameFactory> gameFactories = server.getGameFactories(); if (message.getMessage() == null || !gameFactories.containsKey(message.getMessage())) { client.sendToClient(new ServerErrorMessage("Invalid gameType specified.")); return; } TCGGame game = (TCGGame) server.createGame(message.getMessage()); game.addPlayer(client); game.addPlayer(new FakeClient(server, e -> {})); if (!game.preStartForConfiguration()) { client.sendToClient(new ServerErrorMessage("There is no configuration required for mod " + message.getMessage())); } break; case STATUS: List<ClientIO> clients = server.getClients().values().stream() .collect(Collectors.toList()); Predicate<ClientIO> aiFilter = cl -> cl instanceof FakeAIClientTCG; int ais = (int) clients.stream().filter(aiFilter).count(); int users = (int) clients.stream() .filter(cl -> cl instanceof ClientWebSocket || cl instanceof ClientSocketHandler) .count(); int games = server.getGames().size(); String[] mods = server.getGameFactories().keySet().stream().toArray(size -> new String[size]); client.sendToClient(new ServerStatusMessage(users, ais, games, mods)); break; default: client.sendToClient(new ServerErrorMessage("No such query request")); break; } } public void loginMessage(LoginMessage message, ClientIO client) { logger.info("Login request: " + message.getUsername() + " for client " + client); try { UserName name = UserName.create(message.getUsername()); server.trySetClientName(client, name); } catch (UserNameAlreadyInUseException | InvalidUserNameException e) { client.sendToClient(new WelcomeMessage(0, false, e.getMessage())); return; } logger.info("Client is welcome!"); client.sendToClient(new WelcomeMessage(client.getId(), true, "OK")); UserStatusMessage statusMessage = new UserStatusMessage(client.getId(), client.getName(), Status.ONLINE); server.getClients().values().stream() .filter(cl -> cl != client) .forEach(cl -> cl.sendToClient(statusMessage)); server.getMainChat().add(client); Set<String> gameFactories = server.getGameFactories().keySet(); client.sendToClient(new AvailableModsMessage(gameFactories.toArray(new String[gameFactories.size()]))); } public void play(StartGameRequest message, ClientIO client) { if (message.getOpponent() == client.getId()) { client.sendToClient(new ChatMessage(server.getMainChat().getId(), "Server", "You cannot invite yourself.")); return; } if (message.getOpponent() < 0) { this.playAny(message, client); } else { ClientIO target = server.getClients().get(message.getOpponent()); if (target == null) { logger.warn("Invite sent to unknown user: " + message); client.sendToClient(new InviteResponse(0, false)); return; } server.getInviteManager().createAndSend(client, target, message.getGameType()); } } public void inviteResponse(InviteResponse message, ClientIO client) { GameInvite invite = server.getInviteManager().getInvite(message.getInviteId()); if (invite != null) { invite.handleResponse(client, message.isAccepted()); } else { logger.warn("No such invite: " + message.getInviteId()); } } private void playAny(StartGameRequest message, ClientIO client) { AtomicReference<ClientIO> playAny = server.getPlayAny(); if (!playAny.compareAndSet(null, client)) { ClientIO opponent = playAny.getAndSet(null); server.getInviteManager().createAndAdd(client, opponent, message.getGameType()); } } public void useAbility(UseAbilityMessage message, ClientIO client) { TCGGame game = (TCGGame) server.getGames().get(message.getGameId()); game.handleMove(message, client); } public void requestTargets(RequestTargetsMessage message, ClientIO client) { TCGGame game = (TCGGame) server.getGames().get(message.getGameId()); game.informAboutTargets(message, client); } public void chat(ChatMessage message, ClientIO client) { ChatArea chat = server.getChats().get(message.getChatId()); if (message.getMessage().startsWith("/")) { client.sendToClient(new ChatMessage(message.getChatId(), "Command Handler", message.getMessage())); server.getCommandHandler().handle(new Command(client, message.getMessage().substring(1))); } else { chat.incomingMessage(message, client); } } public void incomingConfig(PlayerConfigMessage message, ClientIO client) { TCGGame game = (TCGGame) server.getGames().get(message.getGameId()); game.incomingPlayerConfig(message, client); } }