package com.square.WeakLinkServer; import jdk.nashorn.internal.ir.RuntimeNode; import java.io.*; import java.net.Socket; import java.util.LinkedList; import java.util.Random; import java.util.Timer; import java.util.TimerTask; public class Client extends Thread { // Server --> Client cmd public final int S_CHANGE_STATE = 0; public final int S_GET_QUESTION = 1; public final int S_GET_ANSWER = 2; public final int S_REFRESH_COSTS = 3; public final int S_CURRENT_PLAYER = 4; public final int S_KICK = 5; public final int S_BANK_AVAILABLE = 6; public final int S_RATE = 7; // Client --> Server cmd public final int C_REFRESH_COSTS = -1; public final int C_ANSWER = -2; public final int C_DISCONNECT = -3; public final int C_RATE = -4; private Socket socket = null; private ClientManager manager = null; private int ID = -1; private ObjectInputStream streamIn = null; private ObjectOutputStream streamOut = null; private boolean threadDone = false; private LinkedList receives = new LinkedList(); private String name = Integer.toString(ID); private boolean isBot = false; private int currentPlayer = -1; private String currentState; public Client(ClientManager _manager, Socket _socket) { super(); manager = _manager; socket = _socket; ID = socket.getPort(); } public Client(ClientManager _manager){ super(); manager = _manager; isBot = true; ID = - (++manager.BotsNum); } public void send(Request request) { if (request.cmd == S_CHANGE_STATE) currentState = (String) request.data; if (!isBot) { try { Printer.printLine("Sending '" + request.cmd+ " " + request.type + "' to " + socket); streamOut.writeObject(request); streamOut.flush(); } catch (IOException ioe) { Printer.exception(ID + " Error sending '" + request.cmd+ " " + request.type + "' to " + socket, ioe); manager.remove(ID); terminate(true); } } else { botReceive(request); } } public void send(String msg){ if (!isBot) { try { Printer.printLine("Sending '" + msg + "' to " + socket); streamOut.writeUTF(msg); streamOut.flush(); } catch (IOException ioe) { Printer.exception(ID + " Error sending '" +msg + "' to " + socket, ioe); manager.remove(ID); terminate(true); } } } public int getID() { return ID; } public String getPlayerName() { return name; } public void run() { Printer.printLine("Thread " + ID + " running."); while (true) { if (threadDone) { return; } try { Request msg = (Request) streamIn.readObject(); receives.add(msg); manager.handle(ID, msg.type); } catch (IOException ioe) { Printer.exception(ID + " Error reading: ", ioe); manager.remove(ID); terminate(true); } catch (ClassNotFoundException ce){ Printer.printLine(ce.getMessage()); } } } public void open() throws IOException { streamIn = new ObjectInputStream(new BufferedInputStream(socket.getInputStream())); streamOut = new ObjectOutputStream(new BufferedOutputStream(socket.getOutputStream())); } public void close() throws IOException { if (socket != null) { socket.close(); } if (streamIn != null) { streamIn.close(); } if (streamOut != null) { streamOut.close(); } } public void terminate(boolean done) { threadDone = done; } public Request getReceive() { if (receives.isEmpty()) { return null; } return receives.poll(); } public void flush() { receives.clear(); } //=========================================================================// private boolean enabled = true; public boolean isEnabled() { return enabled; } public void enable() { enabled = true; } public void disable() { enabled = false; } private int correct = 0; public int getCorrect() { return correct; } public void correctUp() { correct++; } public void correctDown() { correct--; } public void correctFlush() { correct = 0; } public void botOn() { isBot = true; if (currentState.equals("ROUND")) receives.add(new Request(C_ANSWER, "Integer", Math.random()*4)); //!!!!!!!!!!!!!!! 3 variants of answer if (currentState.equals("RATE")) //receives.add(new Request(C_RATE, "Integer", Math.random()*(playersAvailableCount+1))); if (currentState.equals("FINAL_ROUND")) receives.add(new Request(C_ANSWER, "Integer", Math.random()*4)); //!!!!!!!!!!!!!!! 3 variants of answer } private void botReceive(final Request request){ final Timer locTimer = new Timer(); switch (request.cmd){ case S_CHANGE_STATE: break; case S_GET_QUESTION: if (currentPlayer != getID()) break; locTimer.schedule(new TimerTask() { @Override public void run() { Random rnd = new Random(); receives.add(new Request(C_REFRESH_COSTS, "Boolean", rnd.nextBoolean())); } }, 2000); Question q = (Question) request.data; final int ansSize = q.answers.length; long waitingTime = 2 + (long) (Math.random() * 5); //waitingTime in [2, 6] locTimer.schedule(new TimerTask() { @Override public void run() { receives.add(new Request(C_ANSWER, "Integer", (int)(Math.random() * (ansSize + 1)))); } }, waitingTime * 1000); break; case S_GET_ANSWER: break; case S_CURRENT_PLAYER: currentPlayer = (Integer) request.data; break; case S_RATE: final int playersAvailableCount = (Integer) request.data; locTimer.schedule(new TimerTask() { @Override public void run() { receives.add(new Request(C_RATE, "Integer", (int)(Math.random()*(playersAvailableCount+1)))); } }, 2000); break; } } }