/* will create new Client object and add it to the 'clients' list * and will also register it's socket channel with 'readSelector'. * Use 'sendBufferSize' to specify socket's send buffer size. */ public static Client addNewClient(SocketChannel chan, Selector readSelector, int sendBufferSize) { Client client = new Client(chan); clients.add(client); // register the channel with the selector // store a new Client as the Key's attachment try { chan.configureBlocking(false); chan.socket().setSendBufferSize(sendBufferSize); // ***chan.socket().setSoTimeout(TIMEOUT_LENGTH); -> this doesn't seem to have an effect with // java.nio client.selKey = chan.register(readSelector, SelectionKey.OP_READ, client); } catch (ClosedChannelException cce) { killClient(client); return null; } catch (IOException ioe) { killClient(client); return null; } catch (Exception e) { killClient(client); return null; } return client; }
/* this method disconnects and removes client from the clients list. * Also cleans up after him (channels, battles) and notifies other * users of his departure. "reason" is used with LEFT command to * notify other users on same channel of this client's departure * reason (it may be left blank ("") to give no reason). */ public static boolean killClient(Client client, String reason) { int index = clients.indexOf(client); if (index == -1) return false; if (!client.alive) return false; client.disconnect(); clients.remove(index); client.alive = false; if (reason.trim().equals("")) reason = "Quit"; // let's remove client from all channels he is participating in: client.leaveAllChannels(reason); if (client.battleID != -1) { Battle bat = Battles.getBattleByID(client.battleID); if (bat == null) { System.out.println("Serious error occured: Invalid battle ID. Server will now exit!"); TASServer.closeServerAndExit(); } Battles.leaveBattle( client, bat); // automatically checks if client is founder and closes the battle } if (client.account.accessLevel() != Account.NIL_ACCESS) { sendToAllRegisteredUsers("REMOVEUSER " + client.account.user); if (TASServer.DEBUG > 0) System.out.println("Registered user killed: " + client.account.user); } else { if (TASServer.DEBUG > 0) System.out.println("Unregistered user killed"); } if (TASServer.LAN_MODE) { Accounts.removeAccount(client.account); } return true; }
/* notifies client of all statuses, including his own (but only if they are different from 0) */ public static void sendInfoOnStatusesToClient(Client client) { for (int i = 0; i < clients.size(); i++) { if (clients.get(i).account.accessLevel() < Account.NORMAL_ACCESS) continue; if (clients.get(i).status != 0) // only send it if not 0. User assumes that every new user's status is 0, so we // don't need to tell him that explicitly. client.sendLine("CLIENTSTATUS " + clients.get(i).account.user + " " + clients.get(i).status); } }
/* sends a list of all users connected to the server to client (this list includes * the client itself, assuming he is already logged in and in the list) */ public static void sendListOfAllUsersToClient(Client client) { for (int i = 0; i < clients.size(); i++) { if (clients.get(i).account.accessLevel() < Account.NORMAL_ACCESS) continue; client.sendLine( "ADDUSER " + clients.get(i).account.user + " " + clients.get(i).country + " " + clients.get(i).cpu); } }