From 25426aceec630bee1e3e2a50203714cf7bdf530c Mon Sep 17 00:00:00 2001 From: Hadi Khodabande Date: Wed, 17 Dec 2014 11:33:02 +0330 Subject: [PATCH 01/40] Gson library added. --- .gitignore | 1 - libs/gson-2.3.1.jar | Bin 0 -> 210856 bytes 2 files changed, 1 deletion(-) create mode 100644 libs/gson-2.3.1.jar diff --git a/.gitignore b/.gitignore index c7cf644..61df785 100644 --- a/.gitignore +++ b/.gitignore @@ -7,7 +7,6 @@ SharifEngine.iml .mtj.tmp/ # Package Files # -*.jar *.war *.ear diff --git a/libs/gson-2.3.1.jar b/libs/gson-2.3.1.jar new file mode 100644 index 0000000000000000000000000000000000000000..250132c197467d7ddef3b7f40a98fdc036163b66 GIT binary patch literal 210856 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≪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

eMUo@%PPi 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 OZ$92#YJ45aW%wUD7hlN$ literal 0 HcmV?d00001 From 5c7abc0f9a5c4ff3427391df66e8cc50e0c34454 Mon Sep 17 00:00:00 2001 From: Hadi Khodabande Date: Thu, 18 Dec 2014 09:15:53 +0330 Subject: [PATCH 02/40] NetServer is a useful class for networking! --- src/server/network/ClientNetwork.java | 12 +++++- src/server/network/JsonSocket.java | 52 +++++++++++++++++++++++++ src/server/network/NetServer.java | 37 ++++++++++++++++++ src/server/network/NetServerThread.java | 45 +++++++++++++++++++++ src/server/network/TerminalNetwork.java | 12 +++++- 5 files changed, 156 insertions(+), 2 deletions(-) create mode 100644 src/server/network/JsonSocket.java create mode 100644 src/server/network/NetServer.java create mode 100644 src/server/network/NetServerThread.java diff --git a/src/server/network/ClientNetwork.java b/src/server/network/ClientNetwork.java index 00b8687..f0df736 100644 --- a/src/server/network/ClientNetwork.java +++ b/src/server/network/ClientNetwork.java @@ -3,5 +3,15 @@ /** * Created by Razi on 12/6/2014. */ -public class ClientNetwork { +public class ClientNetwork extends NetServer { + + protected ClientNetwork(int port) { + super(port); + } + + @Override + protected void accept(JsonSocket client) { + // handle new clients + } + } diff --git a/src/server/network/JsonSocket.java b/src/server/network/JsonSocket.java new file mode 100644 index 0000000..535e45a --- /dev/null +++ b/src/server/network/JsonSocket.java @@ -0,0 +1,52 @@ +package server.network; + +import com.google.gson.Gson; +import com.google.gson.JsonObject; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.net.Socket; + +/** + * Created by Hadi on 12/17/2014 11:53 PM. + */ +public class JsonSocket { + + private Gson mGson; + private Socket mSocket; + private DataInputStream mIn; + private DataOutputStream mOut; + + public JsonSocket(String host, int port) throws IOException { + this(new Socket(host, port)); + } + + public JsonSocket(Socket socket) throws IOException { + mGson = new Gson(); + mSocket = socket; + mIn = new DataInputStream(mSocket.getInputStream()); + mOut = new DataOutputStream(mSocket.getOutputStream()); + } + + public void close() throws IOException { + mSocket.close(); + } + + public boolean isClosed() { + return mSocket.isClosed(); + } + + public void send(Object obj) throws IOException { + mOut.writeUTF(mGson.toJson(obj)); + } + + public JsonObject get() throws IOException { + return mGson.fromJson(mIn.readUTF(), JsonObject.class); + } + + public T get(Class classOfInput) throws IOException { + return mGson.fromJson(mIn.readUTF(), classOfInput); + } + +} diff --git a/src/server/network/NetServer.java b/src/server/network/NetServer.java new file mode 100644 index 0000000..181d968 --- /dev/null +++ b/src/server/network/NetServer.java @@ -0,0 +1,37 @@ +package server.network; + +import java.io.IOException; + +/** + * Created by Hadi on 12/17/2014 11:57 PM. + */ +public abstract class NetServer { + + private int port; + private NetServerThread listener; + + protected NetServer(int port) { + this.port = port; + } + + public synchronized final void listen() { + if (listener != null) + throw new IllegalStateException("Network is currently listening."); + listener = new NetServerThread(port, this::accept); + listener.start(); + } + + public synchronized final void terminate() { + if (listener == null) + throw new IllegalStateException("Network not started or has been terminated."); + try { + listener.terminate(); + listener = null; + } catch (IOException e) { + e.printStackTrace(); + } + } + + protected abstract void accept(JsonSocket client); + +} diff --git a/src/server/network/NetServerThread.java b/src/server/network/NetServerThread.java new file mode 100644 index 0000000..efe1e2a --- /dev/null +++ b/src/server/network/NetServerThread.java @@ -0,0 +1,45 @@ +package server.network; + +import java.io.IOException; +import java.net.ServerSocket; +import java.util.function.Consumer; + +/** + * Created by Hadi on 12/17/2014 11:56 PM. + */ +public class NetServerThread extends Thread { + + private final int port; + private boolean terminateFlag; + private ServerSocket serverSocket; + private Consumer clientAcceptor; + + public NetServerThread(int port, Consumer clientAcceptor) { + this.port = port; + this.clientAcceptor = clientAcceptor; + } + + @Override + public void run() { + while (!terminateFlag) + try { + runServer(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + private void runServer() throws IOException { + if (serverSocket != null && serverSocket.isClosed()) + serverSocket.close(); + serverSocket = new ServerSocket(port); + while (!terminateFlag) + clientAcceptor.accept(new JsonSocket(serverSocket.accept())); + } + + public synchronized void terminate() throws IOException { + terminateFlag = true; + serverSocket.close(); + } + +} diff --git a/src/server/network/TerminalNetwork.java b/src/server/network/TerminalNetwork.java index 015299d..8697302 100644 --- a/src/server/network/TerminalNetwork.java +++ b/src/server/network/TerminalNetwork.java @@ -3,5 +3,15 @@ /** * Created by Razi on 12/6/2014. */ -public class TerminalNetwork { +public class TerminalNetwork extends NetServer { + + protected TerminalNetwork(int port) { + super(port); + } + + @Override + protected void accept(JsonSocket client) { + // handle new clients + } + } From 05df3874f5d23e128a3278cefc2e69be410ebe9f Mon Sep 17 00:00:00 2001 From: Hadi Khodabande Date: Fri, 19 Dec 2014 00:31:00 +0330 Subject: [PATCH 03/40] 64KB json limit problem is solved. --- src/server/network/JsonSocket.java | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/server/network/JsonSocket.java b/src/server/network/JsonSocket.java index 535e45a..f02c67a 100644 --- a/src/server/network/JsonSocket.java +++ b/src/server/network/JsonSocket.java @@ -38,15 +38,27 @@ public boolean isClosed() { } public void send(Object obj) throws IOException { - mOut.writeUTF(mGson.toJson(obj)); + String json = mGson.toJson(obj); + byte buffer[] = json.getBytes("utf-8"); + mOut.writeInt(buffer.length); + mOut.write(buffer, 0, buffer.length); } public JsonObject get() throws IOException { - return mGson.fromJson(mIn.readUTF(), JsonObject.class); + return get(JsonObject.class); } public T get(Class classOfInput) throws IOException { - return mGson.fromJson(mIn.readUTF(), classOfInput); + int length = mIn.readInt(), total = 0, current; + byte buffer[] = new byte[length]; + while (total < length) { + current = mIn.read(buffer, total, length-total); + total += current; + if (current == -1) + throw new IOException("EOF reached."); + } + String json = new String(buffer, 0, buffer.length, "utf-8"); + return mGson.fromJson(json, classOfInput); } } From 8bfa3645f704459ea615b30b2cc6e1346e0678b7 Mon Sep 17 00:00:00 2001 From: Hadi Khodabande Date: Sat, 20 Dec 2014 20:34:34 +0330 Subject: [PATCH 04/40] Javadoc is added. --- src/server/network/JsonSocket.java | 92 ++++++++++++++++++++++++- src/server/network/NetServer.java | 80 ++++++++++++++++++--- src/server/network/NetServerThread.java | 70 +++++++++++++++++-- 3 files changed, 226 insertions(+), 16 deletions(-) diff --git a/src/server/network/JsonSocket.java b/src/server/network/JsonSocket.java index f02c67a..0d248e9 100644 --- a/src/server/network/JsonSocket.java +++ b/src/server/network/JsonSocket.java @@ -9,19 +9,69 @@ import java.net.Socket; /** - * Created by Hadi on 12/17/2014 11:53 PM. + * This class is a wrapper for java's Socket that uses json strings + * to transmit objects. + *

+ * A JsonSocket holds a Gson object to convert + * objects to json string and vice-versa, and a Socket to + * send and receive json strings. + *

+ * To create a JsonSocket, one can pass an existing socket + * to the constructor of this class. + *

+ * After a JsonSocket was successfully created, one can send and + * receive objects with methods send and get. + *

+ * Note that the other endpoint of the communication must use a + * JsonSocket to send and receive objects correctly. + *

+ * This class is a member of {@link server.network}. + * + * @see com.google.gson.Gson + * @see java.net.Socket + * */ public class JsonSocket { + /** + * The Gson object is used to convert between java and json. + */ private Gson mGson; + /** + * The underlying Socket. + */ private Socket mSocket; + /** + * Input stream of the socket. + */ private DataInputStream mIn; + /** + * Output stream of the socket. + */ private DataOutputStream mOut; + /** + * Initiates new socket with specified host and port and uses + * that socket to transmit json strings. + * + * @param host the host name. + * @param port the port number. + * @throws IOException if an I/O error occurs when creating the socket or + * its input or output stream. + * @see java.net.Socket#Socket(java.lang.String, int) + * @see #JsonSocket(java.net.Socket) + */ public JsonSocket(String host, int port) throws IOException { this(new Socket(host, port)); } + /** + * Uses an existing socket to transmit json strings. + * + * @param socket the socket object. + * @throws IOException if an I/O error occurs when creating the + * input or output stream of the socket. + */ public JsonSocket(Socket socket) throws IOException { mGson = new Gson(); mSocket = socket; @@ -29,14 +79,36 @@ public JsonSocket(Socket socket) throws IOException { mOut = new DataOutputStream(mSocket.getOutputStream()); } + /** + * Closes the underlying socket. + * + * @throws IOException if an I/O error occurs when closing the socket. + * @see java.net.Socket#close + * @see #isClosed + */ public void close() throws IOException { mSocket.close(); } + /** + * Returns the closed state of the socket. + * + * @return true if the socket has been closed + * @see java.net.Socket#isClosed + * @see #close + */ public boolean isClosed() { return mSocket.isClosed(); } + /** + * Converts obj to json string and sends it via the socket's + * output stream. + * + * @param obj the object to send. + * @throws IOException if an I/O error occurs, e.g. when the socket is closed. + * @see com.google.gson.Gson#toJson(java.lang.Object) + */ public void send(Object obj) throws IOException { String json = mGson.toJson(obj); byte buffer[] = json.getBytes("utf-8"); @@ -44,10 +116,28 @@ public void send(Object obj) throws IOException { mOut.write(buffer, 0, buffer.length); } + /** + * Reads a json string from socket's input stream, and converts it to + * a JsonObject. + * + * @return the received JsonObject + * @throws IOException if an I/O error occurs, e.g. when the socket is closed. + * @see com.google.gson.Gson#fromJson(String,java.lang.Class) + * @see #get(java.lang.Class) + */ public JsonObject get() throws IOException { return get(JsonObject.class); } + /** + * Reads a json string from socket's input stream, and converts it to + * a an object of the specified class. + * + * @return the received object + * @throws IOException if an I/O error occurs, e.g. when the socket is closed. + * @see com.google.gson.Gson#fromJson(String,java.lang.Class) + * @see #get + */ public T get(Class classOfInput) throws IOException { int length = mIn.readInt(), total = 0, current; byte buffer[] = new byte[length]; diff --git a/src/server/network/NetServer.java b/src/server/network/NetServer.java index 181d968..09f53b3 100644 --- a/src/server/network/NetServer.java +++ b/src/server/network/NetServer.java @@ -1,37 +1,95 @@ package server.network; -import java.io.IOException; - /** - * Created by Hadi on 12/17/2014 11:57 PM. + * This class implements a network server. A NetServer runs a + * server on the specified port and waits for the clients to be connected, + * and then based on the implementation of the accept method, + * performs some operation for each client, + * e.g. performs some operation based on the request, + * returns some information to the requester, + * or offers a terminal for the client. + *

+ * When the method {@link #listen} is called, a + * {@link server.network.NetServerThread} is assigned to listen on the specified + * port. When a client attempts to connect to that port, the {@link #accept} + * method of the class is called, with a reference to the + * JsonSocket which is connected to the client. This is the initial + * point of the connection and one can send initial messages to start + * communication with the client. + *

+ * It is better to do all operations for a client in a separated thread. So if + * the client is fake it doesn't affect the behavior of the server. + * + * @see server.network.NetServerThread + * @see server.network.TerminalNetwork + * @see server.network.ClientNetwork + * @see server.network.UINetwork */ public abstract class NetServer { + /** + * The port of the server. + */ private int port; + /** + * The thread which is assigned to listen on the port. + */ private NetServerThread listener; + /** + * Constructor. The server is ready to listen on the port. + * @param port server port. + */ protected NetServer(int port) { this.port = port; } + /** + * A thread is created and assigned to listen on the specified port. + * {@link #terminate} must be called between two consecutive calls of this + * function. + * + * @see #terminate + * @see server.network.NetServerThread + */ public synchronized final void listen() { if (listener != null) - throw new IllegalStateException("Network is currently listening."); + throw new IllegalStateException("NetServer is currently listening."); listener = new NetServerThread(port, this::accept); listener.start(); } + /** + * Terminates operations of the current listener. {@link #listen} must be + * called between two consecutive calls of this function. + * + * @see #listen + * @see server.network.NetServerThread + */ public synchronized final void terminate() { if (listener == null) - throw new IllegalStateException("Network not started or has been terminated."); - try { - listener.terminate(); - listener = null; - } catch (IOException e) { - e.printStackTrace(); - } + throw new IllegalStateException("NetServer is not started or has been terminated."); + listener.terminate(); + listener = null; } + /** + * A method to accept new clients. When a client connects to the port of + * this NetServer, this method is called, with a reference to + * a {@link server.network.JsonSocket} which is connected to the client side + * socket. A new thread may be assigned to handle requests of the client. + *

+ * This method is abstract and so it is not implemented in this class. + * Each server has a different behavior on accepting new clients, e.g. + * it may take a token from client or send some information at initial point. + * To implement a server, one can extend this class and implement this method. + *

+ * Note that this method must take care of everything that could be happen + * during communications between client and server. + * + * @param client a {@link server.network.JsonSocket} which is connected + * to the client's socket. + */ protected abstract void accept(JsonSocket client); } diff --git a/src/server/network/NetServerThread.java b/src/server/network/NetServerThread.java index efe1e2a..b108e1e 100644 --- a/src/server/network/NetServerThread.java +++ b/src/server/network/NetServerThread.java @@ -5,30 +5,84 @@ import java.util.function.Consumer; /** - * Created by Hadi on 12/17/2014 11:56 PM. + * This thread is used by {@link server.network.NetServer} to listen on + * some port for the new clients. + *

+ * The actual work of the {@link server.network.NetServerThread} is done by a + * {@link java.net.ServerSocket}. When a NetServerThread is ran, + * it creates a new server socket to listen on that port. When a new client is + * connected to that port, it passes the client's + * {@link server.network.JsonSocket} to the specified consumer. + *

+ * The consumer should accept the client and perform necessary operations. + *

+ * In the {@link server.network.NetServer} the consumer is the abstract method + * {@link server.network.NetServer#accept}. + *

+ * When the server socket is disconnected from the port, e.g. when it is closed + * due to an unknown reason, a new server socket will be created. + * So it is guaranteed that server is always listening on the port. + * + * @see server.network.NetServer + * @see java.net.ServerSocket */ public class NetServerThread extends Thread { + /** + * The port to listen on. + */ private final int port; + /** + * Terminate flag! + */ private boolean terminateFlag; + /** + * The underlying server socket which actually listens on the port. + */ private ServerSocket serverSocket; + /** + * This consumer specifies the behavior of the server when a new client is + * connected. + * Actually, clientAcceptor.accept(JsonSocket) is called when + * a client is connected to the port. + */ private Consumer clientAcceptor; + /** + * Constructor. + * @param port the server port + * @param clientAcceptor specifies accept behavior of the server + */ public NetServerThread(int port, Consumer clientAcceptor) { this.port = port; this.clientAcceptor = clientAcceptor; } + /** + * Runs the server until the terminateFlag is set to + * true. + * + * @see #runServer + * @see #terminate + */ @Override public void run() { while (!terminateFlag) try { runServer(); - } catch (IOException e) { + } catch (Exception e) { e.printStackTrace(); } } + /** + * Runs the server and handles new clients. The method can not be completed + * without throwing an exception. + * + * @throws IOException if an I/O error occurs, + * e.g. when the server socket is closed. + * @see #terminate + */ private void runServer() throws IOException { if (serverSocket != null && serverSocket.isClosed()) serverSocket.close(); @@ -37,9 +91,17 @@ private void runServer() throws IOException { clientAcceptor.accept(new JsonSocket(serverSocket.accept())); } - public synchronized void terminate() throws IOException { + /** + * Terminates operations of the current thread. Sets the terminate flag + * to true and closes the server socket. + */ + public synchronized void terminate() { terminateFlag = true; - serverSocket.close(); + try { + serverSocket.close(); + } catch (Exception e) { + e.printStackTrace(); + } } } From 1a7a29cbb982e0be15e24cb6fc8cabbaaf2650bc Mon Sep 17 00:00:00 2001 From: Hadi Khodabande Date: Sun, 21 Dec 2014 15:32:26 +0330 Subject: [PATCH 05/40] JsonSocket's protocol is now the same as described in wiki. --- src/server/network/ClientNetwork.java | 4 --- src/server/network/JsonSocket.java | 36 +++++++++++++++---------- src/server/network/NetServer.java | 15 ++--------- src/server/network/TerminalNetwork.java | 4 --- 4 files changed, 24 insertions(+), 35 deletions(-) diff --git a/src/server/network/ClientNetwork.java b/src/server/network/ClientNetwork.java index f0df736..eac9e59 100644 --- a/src/server/network/ClientNetwork.java +++ b/src/server/network/ClientNetwork.java @@ -5,10 +5,6 @@ */ public class ClientNetwork extends NetServer { - protected ClientNetwork(int port) { - super(port); - } - @Override protected void accept(JsonSocket client) { // handle new clients diff --git a/src/server/network/JsonSocket.java b/src/server/network/JsonSocket.java index 0d248e9..b946a05 100644 --- a/src/server/network/JsonSocket.java +++ b/src/server/network/JsonSocket.java @@ -3,9 +3,7 @@ import com.google.gson.Gson; import com.google.gson.JsonObject; -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; +import java.io.*; import java.net.Socket; /** @@ -44,11 +42,11 @@ public class JsonSocket { /** * Input stream of the socket. */ - private DataInputStream mIn; + private InputStream mIn; /** * Output stream of the socket. */ - private DataOutputStream mOut; + private OutputStream mOut; /** * Initiates new socket with specified host and port and uses @@ -75,8 +73,8 @@ public JsonSocket(String host, int port) throws IOException { public JsonSocket(Socket socket) throws IOException { mGson = new Gson(); mSocket = socket; - mIn = new DataInputStream(mSocket.getInputStream()); - mOut = new DataOutputStream(mSocket.getOutputStream()); + mIn = mSocket.getInputStream(); + mOut = mSocket.getOutputStream(); } /** @@ -111,9 +109,9 @@ public boolean isClosed() { */ public void send(Object obj) throws IOException { String json = mGson.toJson(obj); - byte buffer[] = json.getBytes("utf-8"); - mOut.writeInt(buffer.length); + byte buffer[] = json.getBytes(); mOut.write(buffer, 0, buffer.length); + mOut.write('\0'); } /** @@ -133,21 +131,31 @@ public JsonObject get() throws IOException { * Reads a json string from socket's input stream, and converts it to * a an object of the specified class. * + * @param classOfInput object's class + * @param type * @return the received object * @throws IOException if an I/O error occurs, e.g. when the socket is closed. * @see com.google.gson.Gson#fromJson(String,java.lang.Class) * @see #get */ public T get(Class classOfInput) throws IOException { - int length = mIn.readInt(), total = 0, current; + int length = 1000, total = 0, current; byte buffer[] = new byte[length]; - while (total < length) { - current = mIn.read(buffer, total, length-total); - total += current; + while (true) { + current = mIn.read(); if (current == -1) throw new IOException("EOF reached."); + if (current == '\0') + break; + if (total >= length) { + byte newBuffer[] = new byte[2*length]; + System.arraycopy(buffer, 0, newBuffer, 0, length); + buffer = newBuffer; + length *= 2; + } + buffer[total++] = (byte) current; } - String json = new String(buffer, 0, buffer.length, "utf-8"); + String json = new String(buffer, 0, total); return mGson.fromJson(json, classOfInput); } diff --git a/src/server/network/NetServer.java b/src/server/network/NetServer.java index 09f53b3..f1678e5 100644 --- a/src/server/network/NetServer.java +++ b/src/server/network/NetServer.java @@ -27,32 +27,21 @@ */ public abstract class NetServer { - /** - * The port of the server. - */ - private int port; /** * The thread which is assigned to listen on the port. */ private NetServerThread listener; - /** - * Constructor. The server is ready to listen on the port. - * @param port server port. - */ - protected NetServer(int port) { - this.port = port; - } - /** * A thread is created and assigned to listen on the specified port. * {@link #terminate} must be called between two consecutive calls of this * function. * + * @param port server port * @see #terminate * @see server.network.NetServerThread */ - public synchronized final void listen() { + public synchronized final void listen(int port) { if (listener != null) throw new IllegalStateException("NetServer is currently listening."); listener = new NetServerThread(port, this::accept); diff --git a/src/server/network/TerminalNetwork.java b/src/server/network/TerminalNetwork.java index 8697302..d10f7bd 100644 --- a/src/server/network/TerminalNetwork.java +++ b/src/server/network/TerminalNetwork.java @@ -5,10 +5,6 @@ */ public class TerminalNetwork extends NetServer { - protected TerminalNetwork(int port) { - super(port); - } - @Override protected void accept(JsonSocket client) { // handle new clients From 3a8851f4bbe39886f99030d55b72975d9b88147b Mon Sep 17 00:00:00 2001 From: Hadi Khodabande Date: Mon, 22 Dec 2014 14:14:04 +0330 Subject: [PATCH 06/40] A small mistake in NetServerThread. --- src/server/network/NetServerThread.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/network/NetServerThread.java b/src/server/network/NetServerThread.java index b108e1e..32fcbd4 100644 --- a/src/server/network/NetServerThread.java +++ b/src/server/network/NetServerThread.java @@ -84,7 +84,7 @@ public void run() { * @see #terminate */ private void runServer() throws IOException { - if (serverSocket != null && serverSocket.isClosed()) + if (serverSocket != null && !serverSocket.isClosed()) serverSocket.close(); serverSocket = new ServerSocket(port); while (!terminateFlag) From 50f6b7f3c11a76135c9b0f9ac735627ea13f36d3 Mon Sep 17 00:00:00 2001 From: Semora Date: Mon, 22 Dec 2014 15:18:59 +0330 Subject: [PATCH 07/40] Make model pakage and Event class --- JGFramework.iml | 11 +++++++++++ src/server/core/model/Event.java | 7 +++++++ 2 files changed, 18 insertions(+) create mode 100644 JGFramework.iml create mode 100644 src/server/core/model/Event.java diff --git a/JGFramework.iml b/JGFramework.iml new file mode 100644 index 0000000..c90834f --- /dev/null +++ b/JGFramework.iml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/src/server/core/model/Event.java b/src/server/core/model/Event.java new file mode 100644 index 0000000..6b9595b --- /dev/null +++ b/src/server/core/model/Event.java @@ -0,0 +1,7 @@ +package server.core.model; + +/** + * Created by Razi on 12/22/2014. + */ +public class Event { +} From edc79433eceb0d60217a78b70e4eaa440e52b8a5 Mon Sep 17 00:00:00 2001 From: Saeed Rajabzadeh Date: Mon, 22 Dec 2014 15:46:41 +0330 Subject: [PATCH 08/40] Add "Command" and "CommandReport" classes and "TerminalInterface" --- .gitignore | 1 + src/server/network/TerminalNetwork.java | 12 ++++++++++++ src/server/network/data/Command.java | 7 +++++++ src/server/network/data/CommandReport.java | 7 +++++++ 4 files changed, 27 insertions(+) create mode 100644 src/server/network/data/Command.java create mode 100644 src/server/network/data/CommandReport.java diff --git a/.gitignore b/.gitignore index 61df785..5130051 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ SharifEngine.iml # Package Files # *.war *.ear +.DS_Store # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml hs_err_pid* diff --git a/src/server/network/TerminalNetwork.java b/src/server/network/TerminalNetwork.java index d10f7bd..f91556f 100644 --- a/src/server/network/TerminalNetwork.java +++ b/src/server/network/TerminalNetwork.java @@ -1,10 +1,22 @@ package server.network; +import server.core.model.Event; +import server.network.data.Command; +import server.network.data.CommandReport; + /** * Created by Razi on 12/6/2014. */ public class TerminalNetwork extends NetServer { + private int port; + private String token; + + public interface TerminalInterface { + void putEvent(Event event); + CommandReport runCommand(Command command); + } + @Override protected void accept(JsonSocket client) { // handle new clients diff --git a/src/server/network/data/Command.java b/src/server/network/data/Command.java new file mode 100644 index 0000000..a81702b --- /dev/null +++ b/src/server/network/data/Command.java @@ -0,0 +1,7 @@ +package server.network.data; + +/** + * Created by rajabzz on 12/22/14. + */ +public class Command { +} diff --git a/src/server/network/data/CommandReport.java b/src/server/network/data/CommandReport.java new file mode 100644 index 0000000..790686a --- /dev/null +++ b/src/server/network/data/CommandReport.java @@ -0,0 +1,7 @@ +package server.network.data; + +/** + * Created by rajabzz on 12/22/14. + */ +public class CommandReport { +} From 965eca4352880215f433967eb516f07ec9f58dcc Mon Sep 17 00:00:00 2001 From: rajabzz Date: Sat, 27 Dec 2014 16:15:32 +0330 Subject: [PATCH 09/40] TerminalNetwork has been completed --- src/server/core/model/Event.java | 2 + src/server/network/TerminalNetwork.java | 102 ++++++++++++++++++++- src/server/network/data/Command.java | 19 ++++ src/server/network/data/CommandReport.java | 3 + src/server/network/data/Message.java | 14 +++ 5 files changed, 138 insertions(+), 2 deletions(-) create mode 100644 src/server/network/data/Message.java diff --git a/src/server/core/model/Event.java b/src/server/core/model/Event.java index 6b9595b..8b09db7 100644 --- a/src/server/core/model/Event.java +++ b/src/server/core/model/Event.java @@ -4,4 +4,6 @@ * Created by Razi on 12/22/2014. */ public class Event { + public static final String EVENT = "event"; + } diff --git a/src/server/network/TerminalNetwork.java b/src/server/network/TerminalNetwork.java index f91556f..e7a1015 100644 --- a/src/server/network/TerminalNetwork.java +++ b/src/server/network/TerminalNetwork.java @@ -1,15 +1,18 @@ package server.network; +import com.google.gson.JsonObject; import server.core.model.Event; import server.network.data.Command; import server.network.data.CommandReport; +import server.network.data.Message; + +import java.io.IOException; /** * Created by Razi on 12/6/2014. */ public class TerminalNetwork extends NetServer { - private int port; private String token; public interface TerminalInterface { @@ -17,9 +20,104 @@ public interface TerminalInterface { CommandReport runCommand(Command command); } + private TerminalInterface handler; + @Override protected void accept(JsonSocket client) { - // handle new clients + new TerminalNetworkThread(client).start(); + } + + public TerminalNetwork(String token) { + this.token = token; + } + + public void setHandler(TerminalInterface handler) { + this.handler = handler; + } + + class TerminalNetworkThread extends Thread { + + private JsonSocket client; + + private boolean userHasCommand = true; + + public TerminalNetworkThread (JsonSocket client) { + + this.client = client; + + } + @Override + public void run() { + try { + Message msg = client.get(Message.class); + + if (!msg.name.equals(token)) + return; + if (!msg.args[0].equals(token)) + return; + + // now the user is a valid one + while (userHasCommand) { + try { + getInput(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void getInput() throws IOException { + Message msg = client.get(Message.class); + if (msg.name.equals(Command.COMMAND)) { + handleCommand(msg); + } else if (msg.name.equals(Event.EVENT)) { + handleEvent(msg); + } else { + client.send("Your input is invalid!\nPlease don't hack me :)"); + } + } + + private void handleEvent(Message msg) { + handler.putEvent((Event)msg.args[0]); + } + + public void handleCommand(Message msg) throws IOException { + Command cmd = new Command(); + String commandType = (String)msg.args[0]; + + // TODO use reflection for this part + if (commandType.equals("newGame")) { + cmd.cmdType = Command.COMMAND_TYPE_NEW_GAME; + } else if (commandType.equals("help")) { + cmd.cmdType = Command.COMMAND_TYPE_HELP; + } else if (commandType.equals("status")) { + cmd.cmdType = Command.COMMAND_TYPE_STATUS; + } else if (commandType.equals("resumeGame")) { + cmd.cmdType = Command.COMMAND_TYPE_RESUME_GAME; + } else if (commandType.equals("loadGame")) { + cmd.cmdType = Command.COMMAND_TYPE_LOAD_GAME; + } else if (commandType.equals("pauseGame")) { + cmd.cmdType = Command.COMMAND_TYPE_PAUSE_GAME; + } else if (commandType.equals("endGame")) { + cmd.cmdType = Command.COMMAND_TYPE_END_GAME; + } else if (commandType.equals("connect")) { + cmd.cmdType = Command.COMMAND_TYPE_CONNECT; + } else if (commandType.equals("disconnect")) { + cmd.cmdType = Command.COMMAND_TYPE_DISCONNECT; + } else if (commandType.equals("exit")) { + cmd.cmdType = Command.COMMAND_TYPE_EXIT; + } + + cmd.arg = (JsonObject)msg.args[1]; + + CommandReport cmdReport = handler.runCommand(cmd); + + client.send(new Message(CommandReport.REPORT, new Object[] {cmdReport.args})); + } } } diff --git a/src/server/network/data/Command.java b/src/server/network/data/Command.java index a81702b..37d4e99 100644 --- a/src/server/network/data/Command.java +++ b/src/server/network/data/Command.java @@ -1,7 +1,26 @@ package server.network.data; +import com.google.gson.JsonObject; + /** * Created by rajabzz on 12/22/14. */ public class Command { + public static final String COMMAND = "command"; + + public static final int COMMAND_TYPE_HELP = 0; + public static final int COMMAND_TYPE_STATUS = 1; + public static final int COMMAND_TYPE_NEW_GAME = 2; + public static final int COMMAND_TYPE_LOAD_GAME = 3; + public static final int COMMAND_TYPE_PAUSE_GAME = 4; + public static final int COMMAND_TYPE_RESUME_GAME = 5; + public static final int COMMAND_TYPE_END_GAME = 6; + public static final int COMMAND_TYPE_CONNECT = 7; + public static final int COMMAND_TYPE_DISCONNECT = 8; + public static final int COMMAND_TYPE_EXIT = 9; + + + public int cmdType; + public JsonObject arg; + } diff --git a/src/server/network/data/CommandReport.java b/src/server/network/data/CommandReport.java index 790686a..6858801 100644 --- a/src/server/network/data/CommandReport.java +++ b/src/server/network/data/CommandReport.java @@ -4,4 +4,7 @@ * Created by rajabzz on 12/22/14. */ public class CommandReport { + public static final String REPORT = "report"; + + public Object[] args; } diff --git a/src/server/network/data/Message.java b/src/server/network/data/Message.java new file mode 100644 index 0000000..c7827c5 --- /dev/null +++ b/src/server/network/data/Message.java @@ -0,0 +1,14 @@ +package server.network.data; + +/** + * Created by rajabzz on 12/27/14. + */ +public class Message { + public String name; + public Object[] args; + + public Message(String name, Object[] args) { + this.name = name; + this.args = args; + } +} From f7f8002f3b036009ab5aaa0430e0ee8731c083bf Mon Sep 17 00:00:00 2001 From: rajabzz Date: Tue, 30 Dec 2014 16:47:29 +0330 Subject: [PATCH 10/40] Refactor of TerminalNetwork + doc --- JGFramework.iml | 6 +- src/server/network/TerminalNetwork.java | 122 ++++++++++++++++-------- src/server/network/data/Command.java | 4 +- 3 files changed, 86 insertions(+), 46 deletions(-) diff --git a/JGFramework.iml b/JGFramework.iml index c90834f..63c111e 100644 --- a/JGFramework.iml +++ b/JGFramework.iml @@ -1,11 +1,13 @@ - + + - \ No newline at end of file + + diff --git a/src/server/network/TerminalNetwork.java b/src/server/network/TerminalNetwork.java index e7a1015..f79e932 100644 --- a/src/server/network/TerminalNetwork.java +++ b/src/server/network/TerminalNetwork.java @@ -1,25 +1,46 @@ package server.network; -import com.google.gson.JsonObject; import server.core.model.Event; import server.network.data.Command; import server.network.data.CommandReport; import server.network.data.Message; import java.io.IOException; +import java.util.ArrayList; +import java.util.StringTokenizer; /** - * Created by Razi on 12/6/2014. + * This class is responsible for create and handling the communication between users and the Terminal + *

+ * A new object from this class will be created when a Terminal wants to start. + *

+ * All of the required efforts for connecting a client to that server is done by the parent class called {@link server.network.NetServer} + * so in this class we just need to handle the events that are occur after user successfully connects with + * + * @see server.network.TerminalNetwork.TerminalNetworkThread + * @see server.network.NetServer */ public class TerminalNetwork extends NetServer { + /** + * used to identify the users to connect to Terminal. + */ private String token; + /** + * This interface is used for transfer Commands and Events. + * This interface is implemented in {@link server.core.GameHandler}. + * TerminalInterface has two methods called putEvent and runCommand + * that will be used for sending essential data to {@link server.core.GameHandler}. + */ public interface TerminalInterface { void putEvent(Event event); CommandReport runCommand(Command command); } + /** + * An instance of {@link server.network.TerminalNetwork} used to + */ private TerminalInterface handler; @Override @@ -35,17 +56,50 @@ public void setHandler(TerminalInterface handler) { this.handler = handler; } + /** + * This thread is used by {@link server.network.TerminalNetwork} + * to handle multiple clients that want to start a terminal. + *

+ * {@link server.network.TerminalNetwork.TerminalNetworkThread} uses a {@link server.network.JsonSocket} + * to get the inputs of a client. The first input is a Token. + * If user enter a correct Token then terminal actually starts. + *

+ * Then it converts every input to a {@link server.network.data.Message} class + * and if the input was a valid one it checks whether this input is command or event. + * Then it creates the appropriate object and by means of {@link server.network.TerminalNetwork.TerminalInterface} + * sends it to {@link server.core.model.Event}. + * + * @see server.network.NetServer + * @see server.network.JsonSocket + */ class TerminalNetworkThread extends Thread { + /** + * Use for get the user input. + */ private JsonSocket client; + /** + * For making an infinite loop. there's no need to make it false because when the terminal actually + * terminated, the thread will be stop. + */ private boolean userHasCommand = true; + /** + * Constructor. + * @param client use to get the input from user + */ public TerminalNetworkThread (JsonSocket client) { - this.client = client; - } + + /** + * Check tokens and analyze the inputs of the user. + * + * @see #TerminalNetworkThread(JsonSocket) + * @see #checkInput() + * @see #makeCommandObj(server.network.data.Message) + */ @Override public void run() { try { @@ -59,7 +113,7 @@ public void run() { // now the user is a valid one while (userHasCommand) { try { - getInput(); + checkInput(); } catch (Exception e) { e.printStackTrace(); } @@ -70,53 +124,37 @@ public void run() { } } - public void getInput() throws IOException { + /** + * If input was not a command or an event then this method throws an IOException + * @throws IOException if the input is invalid + */ + public void checkInput() throws IOException { Message msg = client.get(Message.class); if (msg.name.equals(Command.COMMAND)) { - handleCommand(msg); + handler.runCommand(makeCommandObj(msg)); } else if (msg.name.equals(Event.EVENT)) { - handleEvent(msg); + handler.putEvent((Event)msg.args[0]); } else { client.send("Your input is invalid!\nPlease don't hack me :)"); } } - private void handleEvent(Message msg) { - handler.putEvent((Event)msg.args[0]); - } - - public void handleCommand(Message msg) throws IOException { + /** + * It takes a {@link server.network.data.Message} object and return + * a {@link server.network.data.Command} object created from message. + * @param msg the object that was created from an user's input. + * @return A command object created from the message. + */ + private Command makeCommandObj(Message msg) { Command cmd = new Command(); - String commandType = (String)msg.args[0]; - - // TODO use reflection for this part - if (commandType.equals("newGame")) { - cmd.cmdType = Command.COMMAND_TYPE_NEW_GAME; - } else if (commandType.equals("help")) { - cmd.cmdType = Command.COMMAND_TYPE_HELP; - } else if (commandType.equals("status")) { - cmd.cmdType = Command.COMMAND_TYPE_STATUS; - } else if (commandType.equals("resumeGame")) { - cmd.cmdType = Command.COMMAND_TYPE_RESUME_GAME; - } else if (commandType.equals("loadGame")) { - cmd.cmdType = Command.COMMAND_TYPE_LOAD_GAME; - } else if (commandType.equals("pauseGame")) { - cmd.cmdType = Command.COMMAND_TYPE_PAUSE_GAME; - } else if (commandType.equals("endGame")) { - cmd.cmdType = Command.COMMAND_TYPE_END_GAME; - } else if (commandType.equals("connect")) { - cmd.cmdType = Command.COMMAND_TYPE_CONNECT; - } else if (commandType.equals("disconnect")) { - cmd.cmdType = Command.COMMAND_TYPE_DISCONNECT; - } else if (commandType.equals("exit")) { - cmd.cmdType = Command.COMMAND_TYPE_EXIT; + cmd.cmdType = (String)msg.args[0]; + StringTokenizer tokenizer = new StringTokenizer((String)msg.args[1], ","); + ArrayList argsList = new ArrayList<>(); + while (tokenizer.hasMoreTokens()) { + argsList.add(tokenizer.nextToken()); } - - cmd.arg = (JsonObject)msg.args[1]; - - CommandReport cmdReport = handler.runCommand(cmd); - - client.send(new Message(CommandReport.REPORT, new Object[] {cmdReport.args})); + cmd.args = argsList.toArray(new String[argsList.size()]); + return cmd; } } diff --git a/src/server/network/data/Command.java b/src/server/network/data/Command.java index 37d4e99..9faec15 100644 --- a/src/server/network/data/Command.java +++ b/src/server/network/data/Command.java @@ -20,7 +20,7 @@ public class Command { public static final int COMMAND_TYPE_EXIT = 9; - public int cmdType; - public JsonObject arg; + public String cmdType; + public String[] args; } From 6ac8d4ca406079b35840109efcc8e9199a23f984 Mon Sep 17 00:00:00 2001 From: Hadi Khodabande Date: Sun, 4 Jan 2015 12:42:43 +0330 Subject: [PATCH 11/40] Unit test for TerminalNetwork. --- .../server/network/TerminalNetworkTest.java | 86 +++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 src/test/server/network/TerminalNetworkTest.java diff --git a/src/test/server/network/TerminalNetworkTest.java b/src/test/server/network/TerminalNetworkTest.java new file mode 100644 index 0000000..dacd989 --- /dev/null +++ b/src/test/server/network/TerminalNetworkTest.java @@ -0,0 +1,86 @@ +package test.server.network; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import server.core.model.Event; +import server.network.JsonSocket; +import server.network.TerminalNetwork; +import server.network.data.Command; +import server.network.data.CommandReport; +import server.network.data.Message; + +import java.io.IOException; + +import static org.junit.Assert.*; + +public class TerminalNetworkTest { + public static final int port = 12345; + public static final String host = "localhost"; + public static final String token = "123456"; + private TerminalNetwork terminal; + + @Before + public void createTerminalNetwork() { + terminal = new TerminalNetwork(token); + terminal.setHandler(new TerminalNetwork.TerminalInterface() { + @Override + public void putEvent(Event event) { + System.out.println("event received"); + } + + @Override + public CommandReport runCommand(Command command) { + return new CommandReport(); + } + }); + terminal.listen(port); + } + + @After + public void terminateTerminalNetwork() { + terminal.terminate(); + } + + @Test(timeout = 500) + public void wrongToken() { + JsonSocket client = null; + try { + client = new JsonSocket(host, port); + client.send("123456"); // token must be of type Message, not an integer + } catch (IOException e) { + fail(e.getMessage()); + } + try { + Message init = client.get(Message.class); // socket must be closed by the server + fail(); + } catch (IOException ignored) {} + } + + @Test(timeout = 500) + public void initMessage() { + JsonSocket client; + try { + client = new JsonSocket(host, port); + client.send(new Message("token", new Object[] {token})); + Message init = client.get(Message.class); + assertEquals("init", init.name); + } catch (IOException e) { + fail(e.getMessage()); + } + } + + @Test(timeout = 500) + public void sendCommand() { + JsonSocket client; + try { + client = new JsonSocket(host, port); + client.send(new Message("token", new Object[] {token})); + Message init = client.get(Message.class); + client.send(new Message("command", new Object[] {})); + Message report = client.get(Message.class); + } catch (IOException e) { + fail(e.getMessage()); + } + } +} \ No newline at end of file From 598f455ef06f5a330d4f31f49e0ebfaa692164e6 Mon Sep 17 00:00:00 2001 From: Hadi Khodabande Date: Wed, 7 Jan 2015 14:18:39 +0330 Subject: [PATCH 12/40] UINetwork is completed and tested. --- src/server/network/NetServer.java | 9 + src/server/network/UINetwork.java | 230 ++++++++++++++++++++- src/test/server/network/UINetworkTest.java | 156 ++++++++++++++ 3 files changed, 392 insertions(+), 3 deletions(-) create mode 100644 src/test/server/network/UINetworkTest.java diff --git a/src/server/network/NetServer.java b/src/server/network/NetServer.java index f1678e5..fb763e1 100644 --- a/src/server/network/NetServer.java +++ b/src/server/network/NetServer.java @@ -62,6 +62,15 @@ public synchronized final void terminate() { listener = null; } + /** + * Returns the state of the server. + * + * @return true if listening is terminated. + */ + public final boolean isTerminated() { + return listener == null; + } + /** * A method to accept new clients. When a client connects to the port of * this NetServer, this method is called, with a reference to diff --git a/src/server/network/UINetwork.java b/src/server/network/UINetwork.java index f498950..c2aa3b0 100644 --- a/src/server/network/UINetwork.java +++ b/src/server/network/UINetwork.java @@ -1,7 +1,231 @@ package server.network; +import server.network.data.Message; + +import java.io.IOException; +import java.util.concurrent.*; + /** - * Created by Razi on 12/6/2014. + * {@link server.network.UINetwork} is a server which is responsible for sending + * UI data to the node.js client. + *

+ * When a client is connected to the server, it sends a token and waits for the + * initial message which contains necessary data of beginning of the game. + *

+ * Messages are sent using {@link #send} method. + *

+ * The communications are one sided, i.e. everything which is sent by client is + * ignored by the server. */ -public class UINetwork { -} +public final class UINetwork extends NetServer { + + /** + * token of the server + */ + private final String mToken; + + /** + * current client of the server + */ + private JsonSocket mClient; + + /** + * lock for {@link #mClient} + */ + private final Object mClientLock; + + /** + * a deque for messages that are waiting to send + */ + private LinkedBlockingDeque mMessagesToSend; + + /** + * thread executor which is used to accept clients + */ + private ExecutorService executor; + + /** + * Initializes the class and starts sending messages to clients. + * If there is no client at the time of sending, the message will be + * thrown away. + * + * @param token token of the server + * @see #send + * @see #startSending + * @see #hasClient + * @see #waitForClient + * @see #waitForNewClient + */ + public UINetwork(String token) { + mToken = token; + mClientLock = new Object(); + mMessagesToSend = new LinkedBlockingDeque<>(); + executor = Executors.newCachedThreadPool(); + startSending(); + } + + /** + * Sends a message to the client. + * It actually adds this message to {@link #mMessagesToSend} and sends is + * as soon as it is possible. + * + * @param msg message to send + */ + public void send(Message msg) { + mMessagesToSend.add(msg); + } + + /** + * Runs the main thread for sending messages to the client on the + * {@link #executor}. + * If there is no client at the time of sending, the message will be + * thrown away. + * To prevent this situation one can use {@link #waitForClient} to ensure + * that a client is connected to the server. + * + * @see #waitForClient + * @see #waitForNewClient + * @see #send + */ + private void startSending() { + executor.submit(() -> { + while (!isTerminated()) { + try { + Message msg = mMessagesToSend.take(); + synchronized (mClientLock) { + mClient.send(msg); + } + } catch (InterruptedException | IOException ignored) { + ignored.printStackTrace(); + } + } + }); + } + + /** + * Creates a new thread to verify the client by taking a token. + * + * @param client a {@link server.network.JsonSocket} which is connected + * @see server.network.NetServer#accept + */ + @Override + protected void accept(JsonSocket client) { + executor.submit(() -> { + try { + verifyClient(client); + } catch (Exception e) { + // if anything was wrong close the client! + try { + client.close(); + } catch (Exception ignored) {} + } + }); + } + + /** + * Verifies the client by taking a token. + * + * @param client client + * @throws Exception if verification is failed + * @see #accept + */ + private void verifyClient(JsonSocket client) throws Exception { + // get the token, timeout is 10 seconds + Future futureMessage + = executor.submit(() -> client.get(Message.class)); + Message token = futureMessage.get(10, TimeUnit.SECONDS); + // check the token + if (!"token".equals(token.name) || !mToken.equals(token.args[0])) + throw new Exception("UINetwork: Client rejected, " + + "token is not correct."); + // so the token is correct! + changeClient(client); + } + + /** + * Changes current client to the specified client. + * It actually closes the previous client (if exists) and then creates a + * thread for the new one. + * + * @param client new client + * @see #verifyClient + */ + private void changeClient(JsonSocket client) { + synchronized (mClientLock) { + try { + // close previous socket + mClient.close(); + } catch (Exception ignored) { + } finally { + // change the client + mClient = client; + // notify waiting threads + mClientLock.notify(); + } + } + } + + /** + * Returns true if any client is connected and verified by the server. + * + * @return true if there is any clients + */ + public boolean hasClient() { + return mClient != null; + } + + /** + * Caller will be blocked until a client is connected. + * If currently a client is connected, returns without waiting. + * + * @throws InterruptedException if the current thread is interrupted. + */ + public void waitForClient() throws InterruptedException { + synchronized (mClientLock) { + if (mClient != null) + return; + mClientLock.wait(); + } + } + + /** + * Caller will be blocked until a client is connected or the + * timeout is reached. + * If currently a client is connected, returns without waiting. + * + * @param timeout timeout in seconds + * @throws InterruptedException if the current thread is interrupted. + */ + public void waitForClient(long timeout) throws InterruptedException { + synchronized (mClientLock) { + if (mClient != null) + return; + mClientLock.wait(timeout); + } + } + + /** + * Caller will be blocked until a new client is connected. + * + * @throws InterruptedException if the current thread is interrupted. + */ + public void waitForNewClient() throws InterruptedException { + synchronized (mClientLock) { + mClientLock.wait(); + } + } + + /** + * Caller will be blocked until a new client is connected or the + * timeout is reached. + * + * @param timeout timeout in seconds + * @throws InterruptedException if the current thread is interrupted. + */ + public void waitForNewClient(long timeout) throws InterruptedException { + synchronized (mClientLock) { + mClientLock.wait(timeout); + } + } + +} \ No newline at end of file diff --git a/src/test/server/network/UINetworkTest.java b/src/test/server/network/UINetworkTest.java new file mode 100644 index 0000000..3e4b8a4 --- /dev/null +++ b/src/test/server/network/UINetworkTest.java @@ -0,0 +1,156 @@ +package test.server.network; + +import org.junit.*; +import org.junit.runners.MethodSorters; +import server.network.JsonSocket; +import server.network.UINetwork; +import server.network.data.Message; + +import java.io.IOException; +import java.net.SocketException; + +import static org.junit.Assert.*; + +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class UINetworkTest { + public static final int port = 12346; + public static final String host = "localhost"; + public static final String token = "123456"; + private UINetwork uiNetwork; + + @Before + public void createUINetwork() throws InterruptedException { + // create server before each test + uiNetwork = new UINetwork(token); + uiNetwork.listen(port); + } + + @After + public void terminateUINetwork() throws InterruptedException { + // terminate server after each test + uiNetwork.terminate(); + // we should wait for completion of the test (results may appear after a delay) + Thread.sleep(500); + } + + @Test(timeout = 2000) + public void test1_wrong_token() throws IOException, InterruptedException { + // create client + JsonSocket client = new JsonSocket(host, port); + // send wrong token (token must be an instance of Message, not a string) + client.send(token); + // wait for the server to check the token + uiNetwork.waitForClient(1000); + // client must be rejected by the server + assertEquals(uiNetwork.hasClient(), false); + // client must be closed due to incorrect token + try { + client.send("nothing!"); + fail(); + } catch (SocketException ignored) { + } catch (Exception e) { + fail(e.getMessage()); + } + } + + @Test(timeout = 1000) + public void test2_correct_token() throws IOException, InterruptedException { + // create client + JsonSocket client = new JsonSocket(host, port); + // send correct token + client.send(new Message("token", new Object[]{token})); + // wait for the server to check the token + uiNetwork.waitForClient(); + // token is correct, so client must be alive + client.send("nothing!"); + } + + @Test(timeout = 1000) + public void test3_send_message() throws IOException, InterruptedException { + // create client + JsonSocket client = new JsonSocket(host, port); + // send correct token + client.send(new Message("token", new Object[] {token})); + // wait for the server to check the token + uiNetwork.waitForClient(); + // send message from UINetwork to the client + uiNetwork.send(new Message("name", new Object[] {"arg0", "arg1"})); + // get message + Message msg = client.get(Message.class); + // check data of received message + assertEquals(msg.name, "name"); + assertEquals(msg.args.length, 2); + assertEquals(msg.args[0], "arg0"); + assertEquals(msg.args[1], "arg1"); + } + + @Test(timeout = 1000) + public void test4_10000_messages() throws IOException, InterruptedException { + // create client + JsonSocket client = new JsonSocket(host, port); + // send correct token + client.send(new Message("token", new Object[] {token})); + // wait for the server to check the token + uiNetwork.waitForClient(); + // init data to send + int total = 10000; + double data[] = new double[total]; + for (int i = 0; i < total; i++) + data[i] = Math.random(); + // send messages from server + long start = System.currentTimeMillis(); + for (int i = 0; i < total; i++) + uiNetwork.send(new Message("msg", new Object[] {data[i]})); + long end = System.currentTimeMillis(); + System.out.printf("total sending time: %d ms/%d msg%n", end-start, total); + // get messages on client side + start = System.currentTimeMillis(); + for (int i = 0; i < total; i++) + assertEquals(client.get(Message.class).args[0], data[i]); + end = System.currentTimeMillis(); + System.out.printf("total receiving time: %d ms/%d msg%n", end-start, total); + } + + @Test(timeout = 2000) + public void test5_multiple_clients() throws IOException, InterruptedException { + // client1 + JsonSocket client1 = new JsonSocket(host, port); + client1.send(new Message("token", new Object[] {token})); + uiNetwork.waitForClient(); + uiNetwork.send(new Message("to client1", null)); + // client2 + JsonSocket client2 = new JsonSocket(host, port); + client2.send(new Message("token", new Object[] {token})); + uiNetwork.waitForNewClient(); + uiNetwork.send(new Message("to client2", null)); + // client3 (wrong token) + JsonSocket client3 = new JsonSocket(host, port); + client3.send(token); + uiNetwork.waitForNewClient(1000); + uiNetwork.send(new Message("to client2 again", null)); + // get messages + Message msg1 = client1.get(Message.class); + Message msg2 = client2.get(Message.class); + Message msg3 = client2.get(Message.class); + assertEquals(msg1.name, "to client1"); + assertEquals(msg2.name, "to client2"); + assertEquals(msg3.name, "to client2 again"); + } + + @Test + public void test6_token_timeout() throws IOException, InterruptedException { + // create client + JsonSocket client = new JsonSocket(host, port); + // timeout (11 seconds) + Thread.sleep(11000); + // client must be closed due to timeout + try { + client.send(new Message("token", new Object[] {token})); + fail(); + } catch (SocketException ignored) { + } catch (Exception e) { + fail(e.getMessage()); + } + } + +} \ No newline at end of file From a6ce7337bc07cd84aa58e426c1d2dcb102513a16 Mon Sep 17 00:00:00 2001 From: Hadi Khodabande Date: Wed, 21 Jan 2015 00:59:32 +0330 Subject: [PATCH 13/40] ClientNetwork is completed and tested. A preliminary logging API is also added. --- JGFramework.iml | 16 +- src/server/network/ClientHandler.java | 218 ++++++++++++ src/server/network/ClientNetwork.java | 313 +++++++++++++++++- src/server/network/NetServer.java | 6 +- src/server/network/NetServerThread.java | 11 +- src/server/network/UINetwork.java | 16 +- .../server/network/ClientNetworkTest.java | 250 ++++++++++++++ src/util/Log.java | 77 +++++ 8 files changed, 894 insertions(+), 13 deletions(-) create mode 100644 src/server/network/ClientHandler.java create mode 100644 src/test/server/network/ClientNetworkTest.java create mode 100644 src/util/Log.java diff --git a/JGFramework.iml b/JGFramework.iml index 63c111e..02db710 100644 --- a/JGFramework.iml +++ b/JGFramework.iml @@ -7,7 +7,17 @@ - + + + + + + + + + + + + - - + \ No newline at end of file diff --git a/src/server/network/ClientHandler.java b/src/server/network/ClientHandler.java new file mode 100644 index 0000000..6b918a1 --- /dev/null +++ b/src/server/network/ClientHandler.java @@ -0,0 +1,218 @@ +package server.network; + +import server.network.data.Message; +import util.Log; + +import java.io.IOException; +import java.util.NoSuchElementException; +import java.util.concurrent.LinkedBlockingDeque; +import java.util.function.Supplier; + +/** + * {@link server.network.ClientHandler} handles a client, i.e. it is responsible + * for sending/receiving messages to/from the client. + *

+ * After that a client is verified by the server, server assigns a + * {@link server.network.ClientHandler} to that client. + *

+ * Messages should arrive in a predefined interval of time (which is determined + * by the server). Every message arrived out of this interval is discarded + * immediately. If two or more messages arrived in the valid time the last one + * is stored as the "last validated message". + */ +public class ClientHandler { + + /** + * Logging tag. + */ + private static String TAG = "ClientHandler"; + + /** + * Socket of the client. + */ + private JsonSocket client; + + /** + * Lock for {@link #client}. + */ + private final Object clientLock; + + /** + * Termination flag. + */ + private boolean terminateFlag; + + /** + * Last valid message which is arrived on time. + */ + private Message lastValidatedMessage; + + /** + * Last message received from client. + */ + private Message lastReceivedMessage; + + /** + * Message queue. These messages will be sent to the client asap. + */ + private final LinkedBlockingDeque messagesToSend; + + + /** + * Constructor. + */ + public ClientHandler() { + messagesToSend = new LinkedBlockingDeque<>(); + clientLock = new Object(); + } + + /** + * Queues a message for the client. Message is not sent until {@link #send} + * is called. + * + * @param msg message to send. + */ + public void queue(Message msg) { + messagesToSend.add(msg); + } + + /** + * Sends last queued message. + */ + public void send() { + try { + client.send(messagesToSend.remove()); + } catch (NoSuchElementException e) { + Log.i(TAG, "no message is queued for this client", e); + } catch (Exception e) { + Log.i(TAG, "message sending failure", e); + } + } + + /** + * Removes last validated message. + */ + public void clearLastValidatedMessage() { + lastValidatedMessage = null; + } + + /** + * A message is valid if it is arrived in a valid time, which is determined + * by the server. + * + * @return last validated message. + * @see #getReceiver + */ + public Message getLastValidatedMessage() { + return lastValidatedMessage; + } + + /** + * Binds handler to a socket, i.e. this handler is responsible for + * sending/receiving messages to/from the socket. + * + * @param socket client + */ + public void bind(JsonSocket socket) { + try { + if (client != null) + client.close(); + } catch (IOException e) { + Log.i(TAG, "socket closing failure", e); + } finally { + synchronized (clientLock) { + client = socket; + clientLock.notifyAll(); + } + } + } + + /** + * The result of method is a {@link java.lang.Runnable} object. When this + * runnable is called it receives a new message from the client and if it + * arrives in a valid time (which is checked using timeValidator) + * stores it in {@link #lastValidatedMessage}. + * + * @param timeValidator get method of this object returns + * true if and only if it is called in a valid time. + * (valid time is the time when messages can be + * arrived from clients, e.g. half a second after + * each turn) + * @return a runnable which is used by server to receive new messages of client + */ + public Runnable getReceiver(Supplier timeValidator) { + return () -> { + while (!terminateFlag) { + try { + waitForClient(); + receive(); + if (timeValidator.get()) + lastValidatedMessage = lastReceivedMessage; + } catch (InterruptedException e) { + Log.i(TAG, "waiting for client interrupted", e); + } catch (IOException e) { + Log.i(TAG, "message receiving failure", e); + } + } + }; + } + + /** + * Receives a message from client. + * + * @throws IOException if an I/O error occurs. + */ + private void receive() throws IOException { + lastReceivedMessage = client.get(Message.class); + } + + /** + * Returns true if any client is connected to this client handler. + * + * @return true if any client is connected to this client handler. + */ + public boolean isConnected() { + return client != null; + } + + /** + * Blocks caller method until a client is connected to this handler. + * + * @throws InterruptedException if current thread is interrupted. + */ + public void waitForClient() throws InterruptedException { + if (client == null || client.isClosed()) + synchronized (clientLock) { + clientLock.wait(); + } + } + + /** + * Blocks caller method at most timeout milliseconds until a + * client is connected to this handler. + * + * @param timeout timeout in milliseconds + * @throws InterruptedException if current thread is interrupted. + */ + public void waitForClient(long timeout) throws InterruptedException { + if (client == null || client.isClosed()) + synchronized (clientLock) { + clientLock.wait(timeout); + } + } + + /** + * Terminates operations of the handler. It actually closes the socket and + * changes a flag. + */ + public void terminate() { + try { + terminateFlag = true; + if (client != null) + client.close(); + } catch (IOException e) { + Log.i(TAG, "socket closing failure", e); + } + } + +} diff --git a/src/server/network/ClientNetwork.java b/src/server/network/ClientNetwork.java index eac9e59..4e1c30f 100644 --- a/src/server/network/ClientNetwork.java +++ b/src/server/network/ClientNetwork.java @@ -1,13 +1,322 @@ package server.network; +import server.network.data.Message; +import util.Log; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.concurrent.*; + /** - * Created by Razi on 12/6/2014. + * {@link server.network.ClientNetwork} is a server which is responsible for + * sending messages from server to players + * and receiving players' requests (messages). + *

+ * First of all clients (players) must be defined to the server via method + * {@link #defineClient}. Server assigns an ID to each client so further calls + * get ID of the client instead of its token. + *

+ * When a client (player) is connected to the server, it sends a token and waits + * for the initial message which contains necessary data of beginning of the + * game. + *

+ * Each turn server sends some data to the clients, these data are first queued + * by {@link #queue} and then sent by send method. Server does it best to send + * messages simultaneously to clients, i.e. sending procedure is fair. + *

+ * The communications are one sided, i.e. everything which is sent by client is + * ignored by the server. */ public class ClientNetwork extends NetServer { + /** + * Logging tag. + */ + private static String TAG = "ClientNetwork"; + + /** + * Indicates that receive time is valid or not. + */ + private volatile boolean receiveTimeFlag; + + /** + * Tokens of clients. + */ + private HashMap mTokens; + + /** + * Client handlers. + */ + private ArrayList mClients; + + /** + * A thread pool used to send all messages. + */ + private ExecutorService sendExecutor; + + /** + * A thread pool used to receive messages from clients. + */ + private ExecutorService receiveExecutor; + + /** + * A thread pool used to accept and verify clients. + */ + private ExecutorService acceptExecutor; + + /** + * Constructor. + */ + public ClientNetwork() { + mTokens = new HashMap<>(); + mClients = new ArrayList<>(); + sendExecutor = Executors.newCachedThreadPool(); + receiveExecutor = Executors.newCachedThreadPool(); + } + + /** + * Defines a client with a token. It actually assigns an ID and a handler to + * the client. + * + * @param token token of the client + * @return ID of the client + * @see {@link #omitAllClients} + */ + public int defineClient(String token) { + if (!isTerminated()) + throw new RuntimeException("ClientNetwork: " + + "server is not terminated when defineClient() is called."); + if (mTokens.containsKey(token)) + throw new RuntimeException("ClientNetwork: " + + "duplicate token. " + token); + int id = mClients.size(); + mTokens.put(token, id); + mClients.add(newClient()); + return id; + } + + /** + * Creates a new handler. + * + * @return new handler + */ + private ClientHandler newClient() { + ClientHandler client = new ClientHandler(); + Runnable receiver = client.getReceiver(() -> receiveTimeFlag); + receiveExecutor.submit(receiver); + return client; + } + + /** + * Remove defined clients and free memory allocated for them. + * + * @see {@link #defineClient} + */ + public void omitAllClients() { + if (!isTerminated()) + throw new RuntimeException("ClientNetwork: " + + "server is not terminated when omitAllClients() is called."); + mClients.forEach(server.network.ClientHandler::terminate); + mTokens.clear(); + mClients.clear(); + sendExecutor.shutdownNow(); + receiveExecutor.shutdownNow(); + System.gc(); + mTokens = new HashMap<>(); + mClients = new ArrayList<>(); + sendExecutor = Executors.newCachedThreadPool(); + receiveExecutor = Executors.newCachedThreadPool(); + } + + /** + * Queues a message for a client. + * + * @param clientID ID of the client + * @param msg message + * @see {@link #defineClient} + * @see {@link #sendAllBlocking} + */ + public void queue(int clientID, Message msg) { + mClients.get(clientID).queue(msg); + } + + /** + * Sends all queued messages. Method will not return until all messages + * sent. (or some failure occur) + * + * @see {@link #queue} + */ + public void sendAllBlocking() { + CyclicBarrier sendBarrier = new CyclicBarrier(mClients.size()+1); + for (ClientHandler client : mClients) { + sendExecutor.submit(() -> { + try { + sendBarrier.await(); + client.send(); + sendBarrier.await(); + } catch (InterruptedException | BrokenBarrierException e) { + Log.d(TAG, "waiting barrier interrupted.", e); + } + }); + } + try { + sendBarrier.await(); // start sending + sendBarrier.await(); // wait to send + } catch (Exception e) { + Log.d(TAG, "waiting barrier interrupted.", e); + } + } + + /** + * Stops receiving messages from clients. Any message which is arrived after + * a call of this method is discarded by the handler. + * + * @see {@link #startReceivingAll} + */ + public void stopReceivingAll() { + receiveTimeFlag = false; + } + + /** + * Starts receiving messages from clients. The last message which is arrived + * after a call of this method and before the corresponding call of + * {@link #stopReceivingAll} is stored as "last valid message". + * + * @see {@link #stopReceivingAll} + */ + public void startReceivingAll() { + mClients.forEach(server.network.ClientHandler::clearLastValidatedMessage); + receiveTimeFlag = true; + } + + /** + * Returns last valid message which is received from a client. + * + * @param clientID ID of the client + * @return last valid message or null if there is no valid msg + * @see {@link #defineClient} + */ + public Message getReceived(int clientID) { + return mClients.get(clientID).getLastValidatedMessage(); + } + @Override protected void accept(JsonSocket client) { - // handle new clients + acceptExecutor.submit(() -> { + try { + verifyClient(client); + } catch (Exception e) { + // if anything was wrong close the client! + Log.i(TAG, "client rejected", e); + try { + client.close(); + } catch (Exception ignored) {} + } + }); + } + + private void verifyClient(JsonSocket client) throws Exception { + // get the token, timeout is 10 seconds + Future futureMessage + = acceptExecutor.submit(() -> client.get(Message.class)); + Message token = futureMessage.get(10, TimeUnit.SECONDS); + // check the token + if (!"token".equals(token.name)) + throw new Exception("ClientNetwork: Client rejected, " + + "first message is not token."); + String clientToken = (String) token.args[0]; + // ID of client + int clientID = mTokens.get(clientToken); + // bind socket to corresponding client handler + mClients.get(clientID).bind(client); + } + + /** + * Blocks caller method until a client is connected to the server. + * + * @param clientID ID of the client + * @throws InterruptedException if current thread is interrupted. + * @see {@link #defineClient} + */ + public void waitForClient(int clientID) throws InterruptedException { + mClients.get(clientID).waitForClient(); + } + + /** + * Blocks caller method at most timeout milliseconds until a + * client is connected to the server. + * + * @param clientID ID of the client + * @param timeout timeout in milliseconds + * @throws InterruptedException if current thread is interrupted. + * @see {@link #defineClient} + */ + public void waitForClient(int clientID, long timeout) throws InterruptedException { + mClients.get(clientID).waitForClient(timeout); + } + + /** + * Blocks caller method until all clients are connected to the server. + * + * @throws InterruptedException if current thread is interrupted. + */ + public void waitForAllClients() throws InterruptedException { + for (ClientHandler client : mClients) + client.waitForClient(); + } + + /** + * Blocks caller method at most timeout milliseconds until all + * clients are connected to the server. + * + * @param timeout timeout in milliseconds + * @throws InterruptedException if current thread is interrupted. + */ + public void waitForAllClients(long timeout) throws InterruptedException { + for (ClientHandler client : mClients) { + long start = System.currentTimeMillis(); + client.waitForClient(timeout); + long end = System.currentTimeMillis(); + timeout -= end - start; + if (timeout <= 0) + return; + } + } + + /** + * Returns number of connected clients. + * + * @return num of connected clients. + */ + public int getNumberOfConnected() { + int noc = 0; + for (ClientHandler client : mClients) + if (client.isConnected()) + noc++; + return noc; + } + + /** + * States that a client is connected or not. + * + * @param clientID ID of the client + * @return true if the client is connected + * @see {@link #defineClient} + */ + public boolean isConnected(int clientID) { + return mClients.get(clientID).isConnected(); + } + + @Override + public void listen(int port) { + super.listen(port); + acceptExecutor = Executors.newCachedThreadPool(); + } + + @Override + public void terminate() { + super.terminate(); + acceptExecutor.shutdownNow(); } } diff --git a/src/server/network/NetServer.java b/src/server/network/NetServer.java index fb763e1..8e9b41c 100644 --- a/src/server/network/NetServer.java +++ b/src/server/network/NetServer.java @@ -41,7 +41,7 @@ public abstract class NetServer { * @see #terminate * @see server.network.NetServerThread */ - public synchronized final void listen(int port) { + public synchronized void listen(int port) { if (listener != null) throw new IllegalStateException("NetServer is currently listening."); listener = new NetServerThread(port, this::accept); @@ -55,7 +55,7 @@ public synchronized final void listen(int port) { * @see #listen * @see server.network.NetServerThread */ - public synchronized final void terminate() { + public synchronized void terminate() { if (listener == null) throw new IllegalStateException("NetServer is not started or has been terminated."); listener.terminate(); @@ -67,7 +67,7 @@ public synchronized final void terminate() { * * @return true if listening is terminated. */ - public final boolean isTerminated() { + public boolean isTerminated() { return listener == null; } diff --git a/src/server/network/NetServerThread.java b/src/server/network/NetServerThread.java index 32fcbd4..bb944fe 100644 --- a/src/server/network/NetServerThread.java +++ b/src/server/network/NetServerThread.java @@ -1,5 +1,7 @@ package server.network; +import util.Log; + import java.io.IOException; import java.net.ServerSocket; import java.util.function.Consumer; @@ -28,6 +30,11 @@ */ public class NetServerThread extends Thread { + /** + * Logging tag. + */ + private static String TAG = "NetServerThread"; + /** * The port to listen on. */ @@ -71,7 +78,7 @@ public void run() { try { runServer(); } catch (Exception e) { - e.printStackTrace(); + Log.i(TAG, "server socket closed", e); } } @@ -100,7 +107,7 @@ public synchronized void terminate() { try { serverSocket.close(); } catch (Exception e) { - e.printStackTrace(); + Log.i(TAG, "socket closing failure", e); } } diff --git a/src/server/network/UINetwork.java b/src/server/network/UINetwork.java index c2aa3b0..0f0d065 100644 --- a/src/server/network/UINetwork.java +++ b/src/server/network/UINetwork.java @@ -1,6 +1,7 @@ package server.network; import server.network.data.Message; +import util.Log; import java.io.IOException; import java.util.concurrent.*; @@ -19,6 +20,11 @@ */ public final class UINetwork extends NetServer { + /** + * Logging tag + */ + private static String TAG = "UINetwork"; + /** * token of the server */ @@ -95,8 +101,10 @@ private void startSending() { synchronized (mClientLock) { mClient.send(msg); } - } catch (InterruptedException | IOException ignored) { - ignored.printStackTrace(); + } catch (InterruptedException e) { + Log.d(TAG, "waiting for message interrupted", e); + } catch (IOException e) { + Log.d(TAG, "message sending failure", e); } } }); @@ -115,6 +123,7 @@ protected void accept(JsonSocket client) { verifyClient(client); } catch (Exception e) { // if anything was wrong close the client! + Log.i(TAG, "client rejected", e); try { client.close(); } catch (Exception ignored) {} @@ -155,7 +164,8 @@ private void changeClient(JsonSocket client) { try { // close previous socket mClient.close(); - } catch (Exception ignored) { + } catch (Exception e) { + Log.i(TAG, "socket closing failure", e); } finally { // change the client mClient = client; diff --git a/src/test/server/network/ClientNetworkTest.java b/src/test/server/network/ClientNetworkTest.java new file mode 100644 index 0000000..51a55e9 --- /dev/null +++ b/src/test/server/network/ClientNetworkTest.java @@ -0,0 +1,250 @@ +package test.server.network; + +import org.junit.After; +import org.junit.Before; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runners.MethodSorters; +import server.network.ClientNetwork; +import server.network.JsonSocket; +import server.network.data.Message; + +import java.net.SocketException; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class ClientNetworkTest { + + public static final int port = 12346; + public static final String host = "localhost"; + private ClientNetwork clientNetwork; + + @Before + public void createClientNetwork() throws Exception { + // create server before each test + clientNetwork = new ClientNetwork(); + } + + @After + public void terminateClientNetwork() throws Exception { + // terminate server after each test + clientNetwork.terminate(); + clientNetwork.omitAllClients(); + // we should wait for completion of the test (results may appear after a delay) + Thread.sleep(500); + } + + @Test(timeout = 5000) + public void test1_single_client_wrong_token() throws Exception { + String token = "123456"; + // define client + int id = clientNetwork.defineClient(token); + // run server + clientNetwork.listen(port); + // create client + JsonSocket client = new JsonSocket(host, port); + // send wrong token (token must be an instance of Message, not a string) + client.send(token); + // wait for the server to check the token + clientNetwork.waitForClient(id, 1000); + // client must be rejected by the server + assertEquals(clientNetwork.isConnected(id), false); + // client must be closed due to incorrect token + try { + client.send("nothing!"); + fail(); + } catch (SocketException ignored) { + } catch (Exception e) { + fail(e.getMessage()); + } + } + + @Test(timeout = 1000) + public void test2_single_client_correct_token() throws Exception { + String token = "123456"; + // define client + int id = clientNetwork.defineClient(token); + // run server + clientNetwork.listen(port); + // create client + JsonSocket client = new JsonSocket(host, port); + // send correct token + client.send(new Message("token", new Object[]{token})); + // wait for the server to check the token + clientNetwork.waitForClient(id); + // token is correct, so client must be alive + client.send(new Message("nothing!", null)); + } + + @Test(timeout = 1000) + public void test3_send_message_100_clients() throws Exception { + int n = 100; + int ids[] = new int[n]; + String tokens[] = new String[n]; + JsonSocket clients[] = new JsonSocket[n]; + // define clients + for (int i = 0; i < n; i++) { + tokens[i] = "random double: " + Math.random(); + ids[i] = clientNetwork.defineClient(tokens[i]); + } + // run server + clientNetwork.listen(port); + // create clients and send tokens + for (int i = 0; i < n; i++) { + clients[i] = new JsonSocket(host, port); + clients[i].send(new Message("token", new Object[]{tokens[i]})); + } + // wait for the server to handle incoming messages + clientNetwork.waitForAllClients(); + + long queueTime = System.currentTimeMillis(); + // these random numbers will be sent to clients + double randoms[] = new double[n]; + for (int i = 0; i < n; i++) { + randoms[i] = Math.random(); + clientNetwork.queue(ids[i], new Message("test message", new Object[]{"arg0", randoms[i]})); + } + queueTime = System.currentTimeMillis() - queueTime; + long sendTime = System.currentTimeMillis(); + clientNetwork.sendAllBlocking(); + sendTime = System.currentTimeMillis() - sendTime; + // check received messages + for (int i = 0; i < n; i++) { + // get message + Message msg = clients[i].get(Message.class); + // check data of received message + assertEquals(msg.name, "test message"); + assertEquals(msg.args.length, 2); + assertEquals(msg.args[0], "arg0"); + assertEquals(msg.args[1], randoms[i]); + } + System.out.printf("queue time: %dms%n", queueTime); + System.out.printf("send time: %dms%n", sendTime); + } + + @Test(timeout = 2000) + public void test4_10_clients_1000_messages() throws Exception { + int n = 10; + int m = 1000; + + int ids[] = new int[n]; + String tokens[] = new String[n]; + JsonSocket clients[] = new JsonSocket[n]; + // define clients + for (int i = 0; i < n; i++) { + tokens[i] = "random double: " + Math.random(); + ids[i] = clientNetwork.defineClient(tokens[i]); + } + // run server + clientNetwork.listen(port); + // create clients and send tokens + for (int i = 0; i < n; i++) { + clients[i] = new JsonSocket(host, port); + clients[i].send(new Message("token", new Object[]{tokens[i]})); + } + // wait for the server to handle incoming messages + clientNetwork.waitForAllClients(); + + Message msg[] = generateMessages(n); + for (int j = 0; j < m; j++) { + for (int i = 0; i < n; i++) + clientNetwork.queue(ids[i], msg[i]); + // send to clients + clientNetwork.sendAllBlocking(); + // check received messages + for (int i = 0; i < n; i++) { + // get message + Message cm = clients[i].get(Message.class); + // check data of received message + assertEquals(cm.name, msg[i].name); + for (int k = 0; k < msg[i].args.length; k++) + assertEquals(cm.args[k], msg[i].args[k]); + } + } + } + + @Test(timeout = 1000) + public void test5_wait_for_clients() throws Exception { + // takes about 500 seconds! + long startTime = System.currentTimeMillis(); + int n = 100; + String tokens[] = new String[n]; + JsonSocket clients[] = new JsonSocket[n]; + // define clients + for (int i = 0; i < n; i++) { + tokens[i] = "random double: " + Math.random(); + clientNetwork.defineClient(tokens[i]); + } + // run server + clientNetwork.listen(port); + // create clients and send tokens + // wrong token + clients[0] = new JsonSocket(host, port); + clients[0].send(tokens[0]); + // correct token + for (int i = 1; i < n; i++) { + clients[i] = new JsonSocket(host, port); + clients[i].send(new Message("token", new Object[]{tokens[i]})); + } + long endTime = System.currentTimeMillis(); + clientNetwork.waitForAllClients(950-(endTime-startTime)); + assertEquals(clientNetwork.getNumberOfConnected(), n-1); + } + + @Test(timeout = 1000) + public void test6_simple_send_receive() throws Exception { + String token = "123456"; + // define client + int id = clientNetwork.defineClient(token); + // run server + clientNetwork.listen(port); + // create client + JsonSocket client = new JsonSocket(host, port); + // send correct token + client.send(new Message("token", new Object[]{token})); + // wait for the server to check the token + clientNetwork.waitForClient(id); + + Message msg[] = generateMessages(10); + client.send(msg[0]); + client.send(msg[1]); + clientNetwork.startReceivingAll(); + client.send(msg[2]); + // wait for the server to get the message! + Thread.sleep(10); + clientNetwork.stopReceivingAll(); + client.send(msg[3]); + client.send(msg[4]); + Message m = clientNetwork.getReceived(id); + assertEquals(m.name, msg[2].name); + assertEquals(m.args[0], msg[2].args[0]); + assertEquals(m.args[1], msg[2].args[1]); + } + + @Test + public void test7_long_test_garbage_collection() throws Exception { + int n = 1000; + // transfer 10000*n messages + for (int i = 0; i < n; i++) { + // use the same clientNetwork instance + test4_10_clients_1000_messages(); + clientNetwork.terminate(); + clientNetwork.omitAllClients(); + } + clientNetwork.listen(port); + } + + public static Message generateMessage() { + return new Message("msg#"+Math.random(), new Object[] {null, Math.random()}); + } + + public static Message[] generateMessages(int n) { + Message messages[] = new Message[n]; + for (int i = 0; i < n; i++) + messages[i] = generateMessage(); + return messages; + } + +} \ No newline at end of file diff --git a/src/util/Log.java b/src/util/Log.java new file mode 100644 index 0000000..a4459f3 --- /dev/null +++ b/src/util/Log.java @@ -0,0 +1,77 @@ +package util; + +import java.io.PrintWriter; +import java.io.StringWriter; + +/** + * Logging API. + * + */ +public final class Log { + + public static final int VERBOSE = 2; + public static final int DEBUG = 3; + public static final int INFO = 4; + public static final int WARN = 5; + public static final int ERROR = 6; + + private Log() {} + + public static void v(String tag, String msg) { + log(VERBOSE, tag, msg); + } + + public static void v(String tag, String msg, Throwable tr) { + log(VERBOSE, tag, msg + '\n' + getStackTraceString(tr)); + } + + public static void d(String tag, String msg) { + log(DEBUG, tag, msg); + } + + public static void d(String tag, String msg, Throwable tr) { + log(DEBUG, tag, msg + '\n' + getStackTraceString(tr)); + } + + public static void i(String tag, String msg) { + log(INFO, tag, msg); + } + + public static void i(String tag, String msg, Throwable tr) { + log(INFO, tag, msg + '\n' + getStackTraceString(tr)); + } + + public static void w(String tag, String msg) { + log(WARN, tag, msg); + } + + public static void w(String tag, String msg, Throwable tr) { + log(WARN, tag, msg + '\n' + getStackTraceString(tr)); + } + + public static void w(String tag, Throwable tr) { + log(WARN, tag, getStackTraceString(tr)); + } + + public static void e(String tag, String msg) { + log(ERROR, tag, msg); + } + + public static void e(String tag, String msg, Throwable tr) { + log(ERROR, tag, msg + '\n' + getStackTraceString(tr)); + } + + public static String getStackTraceString(Throwable tr) { + if (tr == null) + return ""; + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + tr.printStackTrace(pw); + return sw.toString(); + } + + public static void log(int priority, String tag, String msg) { + System.out.printf("\tpriority=%d,%n\ttag=%s,%n\tmessage=%s%n", priority, tag, msg); + } + +} \ No newline at end of file From 1c3a61b2bb1b71778ea74d6236c80d03f00dcdaf Mon Sep 17 00:00:00 2001 From: Rajabzz Date: Fri, 23 Jan 2015 20:46:11 +0330 Subject: [PATCH 14/40] Terminal application created --- Terminal/Resources/ip-port.txt | 2 + Terminal/Terminal.iml | 12 +++ Terminal/src/Terminal.java | 176 +++++++++++++++++++++++++++++++++ Terminal/src/TerminalApp.java | 18 ++++ 4 files changed, 208 insertions(+) create mode 100644 Terminal/Resources/ip-port.txt create mode 100644 Terminal/Terminal.iml create mode 100644 Terminal/src/Terminal.java create mode 100644 Terminal/src/TerminalApp.java diff --git a/Terminal/Resources/ip-port.txt b/Terminal/Resources/ip-port.txt new file mode 100644 index 0000000..f5ea46c --- /dev/null +++ b/Terminal/Resources/ip-port.txt @@ -0,0 +1,2 @@ +192.168.1.1 +5050 diff --git a/Terminal/Terminal.iml b/Terminal/Terminal.iml new file mode 100644 index 0000000..2d0f670 --- /dev/null +++ b/Terminal/Terminal.iml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/Terminal/src/Terminal.java b/Terminal/src/Terminal.java new file mode 100644 index 0000000..238f476 --- /dev/null +++ b/Terminal/src/Terminal.java @@ -0,0 +1,176 @@ +import server.network.JsonSocket; + +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.IOException; +import java.io.PrintWriter; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.ArrayList; +import java.util.Scanner; +import java.util.StringTokenizer; + +/** + * Created by Saeed on 1/23/2015. + */ +public class Terminal { + private static final String FILE_PATH = "../JGFramework/Terminal/Resources/ip-port.txt"; + + private static final String CMD_TYPE_CONNECT = "connect"; + private static final String CMD_TYPE_DISCONNECT = "disconnect"; + private static final String CMD_TYPE_SETPORT = "set-port"; + private static final String CMD_TYPE_SETIP = "set-ip"; + + private static Terminal terminal = null; + private String ip; + private int port; + private JsonSocket jsonSocket; + + public Terminal() { + try { + setIpAndPortFromFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public static Terminal getInstance() { + if (terminal == null) { + terminal = new Terminal(); + } + return terminal; + } + + public void writeIpAndPortToFile(String ip, int port) throws IOException { + PrintWriter pw = new PrintWriter(FILE_PATH); + pw.println(ip); + pw.println(port); + pw.close(); + } + + public void setIpAndPortFromFile() throws IOException { + BufferedReader bf = new BufferedReader(new FileReader(FILE_PATH)); + String ip; + String port; + + if ((ip = bf.readLine()) != null) + this.ip = ip; + + if ((port = bf.readLine()) != null) + this.port = Integer.parseInt(port); + bf.close(); + } + + public void handleCommand(String cmd) { + StringTokenizer tokenizer = new StringTokenizer(cmd, " "); + ArrayList command = new ArrayList<>(); + while (tokenizer.hasMoreTokens()) { + command.add(tokenizer.nextToken()); + } + + String cmdType = command.get(0); + + switch (cmdType) { + case CMD_TYPE_CONNECT: + try { + handleConnectCmd(); + } catch (IOException e) { + e.printStackTrace(); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } + break; + + case CMD_TYPE_DISCONNECT: + try { + handleDisconnectCmd(); + } catch (IOException e) { + e.printStackTrace(); + } + break; + + case CMD_TYPE_SETIP: + try { + handleSetIpCmd(command); + } catch (IOException e) { + e.printStackTrace(); + } + break; + + case CMD_TYPE_SETPORT: + try { + handleSetPortCmd(command); + } catch (IOException e) { + e.printStackTrace(); + } + break; + + default: + //TODO it's an external command ... + } + + } + + private void handleConnectCmd() throws IOException, NoSuchAlgorithmException { + + System.out.print("Enter the password: "); + Scanner scanner = new Scanner(System.in); + String password = scanner.nextLine(); + MessageDigest md5 = MessageDigest.getInstance("MD5"); + md5.update(password.getBytes()); + byte[] bytes = md5.digest(); //This has bytes in decimal format; + //Convert it to hexadecimal format + StringBuilder sb = new StringBuilder(); + for (byte aByte : bytes) { + sb.append(Integer.toString((aByte & 0xff) + 0x100, 16).substring(1)); + } + //Get complete hashed password in hex format + String token = sb.toString(); + + jsonSocket = new JsonSocket(ip, port); + jsonSocket.send(token); + + System.out.println("Successfully connected!"); + } + + private void handleDisconnectCmd() throws IOException { + if (jsonSocket != null) {// it's connected + jsonSocket.close(); + System.out.println("Successfully disconnected!"); + } + else System.out.println("You are not connected yet!"); + } + + private void handleSetIpCmd(ArrayList command) throws IOException { + if (jsonSocket != null) { + System.out.println("Cannot change IP or Port while connecting to server."); + return; + } + if (command.get(1).equals("-s")) { + this.ip = command.get(2); + writeIpAndPortToFile(this.ip, this.port); + } else { + this.ip = command.get(1); + } + + System.out.println("IP changed successfully."); + } + + private void handleSetPortCmd(ArrayList command) throws IOException { + if (jsonSocket != null) { + System.out.println("Cannot change IP or Port while connecting to server."); + return; + } + if (command.get(1).equals("-s")) { + String port = command.get(2); + System.out.println(port); + this.port = Integer.parseInt(port); + writeIpAndPortToFile(this.ip, this.port); + } else { + String port = command.get(1); + this.port = Integer.parseInt(port); + } + + System.out.println("Port changed successfully."); + } +} diff --git a/Terminal/src/TerminalApp.java b/Terminal/src/TerminalApp.java new file mode 100644 index 0000000..4c77f26 --- /dev/null +++ b/Terminal/src/TerminalApp.java @@ -0,0 +1,18 @@ +import java.util.Scanner; + +/** + * Created by Saeed on 1/23/2015. + */ +public class TerminalApp { + public static void main(String[] args) { + Terminal terminal = Terminal.getInstance(); + + Scanner scanner = new Scanner(System.in); + System.out.println("<< JGFramework's Terminal >>"); + + while (true) { + String command = scanner.nextLine(); + terminal.handleCommand(command); + } + } +} From ab0a0821d181a9141afc98f4ddb475042fbeb807 Mon Sep 17 00:00:00 2001 From: AliLotfi Date: Sun, 25 Jan 2015 12:44:21 +0330 Subject: [PATCH 15/40] Output Controller added exceptions package added --- src/server/core/OutputController.java | 253 ++++++++++++++++++ ...utputControllerQueueOverflowException.java | 14 + 2 files changed, 267 insertions(+) create mode 100644 src/server/core/OutputController.java create mode 100644 src/server/exceptions/OutputControllerQueueOverflowException.java diff --git a/src/server/core/OutputController.java b/src/server/core/OutputController.java new file mode 100644 index 0000000..05a8e08 --- /dev/null +++ b/src/server/core/OutputController.java @@ -0,0 +1,253 @@ +package server.core; + +import server.exceptions.OutputControllerQueueOverflowException; +import server.network.UINetwork; +import server.network.data.Message; + +import java.io.File; +import java.util.LinkedList; +import java.util.Timer; +import java.util.TimerTask; + +/** + * Class created as a part of {@link GameHandler GameHandler} class for controlling the output. + *

+ * This class gathers all output taken from "GameLogic" into a queue, and the process them as the user + * wishes. Currently passing to {@link server.network.UINetwork UINetwork} and saving in a + * local file is supported. + *

+ */ +public class OutputController implements Runnable { + + private static final int QUEUE_DEFAULT_SIZE = 1000; + + private UINetwork uiNetwork; + private int timeInterval; + private Timer timer; + private File outputFile; + private int bufferSize; + private FileWriter fileWriter; + private OutputHandleMode outputHandleMode; + private LinkedList messagesQueue; + + public OutputController() { + messagesQueue = new LinkedList(); + } + + /** + * Run method implemented from {@link Runnable java.lang.Runnable} class. + *

+ * This method runs the class activities. In order to running the UINetwork timer correctly, must + * be called after initializing using one of the "setOutputHandleMode" methods. + *

+ */ + @Override + public void run() { + if (outputHandleMode == OutputHandleMode.UI_NETWORK) { + if (timeInterval != 0) { + timer.scheduleAtFixedRate(new TimerTask() { + @Override + public void run() { + sendToUINetwork(); + } + }, 0, timeInterval); + } + else { + throw new RuntimeException("Output controller, did not initialized yet"); + } + } + } + + /** + * Sets the output processing mode of class, to "Save to file" mode. + *

+ * This method will set the behavior of class, as a "Pre Runner" in order to a fast forward run based + * on the game logic, and storing data on a file for later usage.
+ * Data would be hold on main memory until reaches the specified buffer size, and then will be + * written to the specified file (Using {@link server.core.OutputController.FileWriter FileWriter} + * runnable class). + *

+ * @param file File to save outputs of processes to + * @param bufferSize Size which data will be held on RAM, before accessing the file + */ + public void setOutputHandleMode(File file, int bufferSize) { + outputFile = file; + if (bufferSize > 0) { + this.bufferSize = bufferSize; + } else if (bufferSize >= QUEUE_DEFAULT_SIZE) { + throw new RuntimeException("Buffer size greater than max queue size."); + } else { + throw new RuntimeException("Invalid buffer size."); + } + fileWriter = new FileWriter(file); + outputHandleMode = OutputHandleMode.FILE; + } + + /** + * Sets the output processing mode of class, to "Show on UI" mode. + *

+ * This type of output processing, will store outputs in the object, and sends it in regular + * timer ticks. This time is specified in milliseconds as "timeInterval". + *

+ * @param uiNetwork The instance of {@link server.network.UINetwork UINetwork} class, which output would be + * sent to + * @param timeInterval The ratio of sending outputs to the UI + */ + public void setOutputHandleMode(UINetwork uiNetwork, int timeInterval) { + this.uiNetwork = uiNetwork; + this.timer = new Timer("UI_Network_Sender"); + this.timeInterval = timeInterval; + outputHandleMode = OutputHandleMode.UI_NETWORK; + } + + /** + * Accepts an instance of {@link server.network.data.Message Message} class as an argument, and places it + * on the queue. + *

+ * In this method, the given message will be putted in the message queue, only if there's a place on the + * queue. Otherwise the cleaning and caching processes will be done (through the + * {@link #hanldeOverflow() hanldeOverflow} method). + * Also if the buffer size condition is met, then the file writer method will be called with an + * alternative thread, to save the contents on the file. + *

+ * @param message The given message (as output) to put in the message queue. + */ + public synchronized void putMessage(Message message) { + if (messagesQueue.size() < QUEUE_DEFAULT_SIZE) { + messagesQueue.addLast(message); + if (messagesQueue.size() == bufferSize && outputHandleMode == OutputHandleMode.FILE) { + try { + while (fileWriter.isBusy()) { + wait(); + } + fileWriter.setMessages((LinkedList) messagesQueue.clone()); + new Thread(fileWriter).start(); + messagesQueue.clear(); + } catch (Exception e) { // TODO: Change to appropriate exception handler + + } + } + } else { + if (hanldeOverflow()) { + messagesQueue.addLast(message); + } else { + throw new OutputControllerQueueOverflowException("Could not handle message queue overflow"); + } + } + notifyAll(); + } + + /** + * Method created to handle the possible overflows occurance in the message queue. + *

+ * + *

+ * @return True if the queue unblocked, false if any error occur during this operation + */ + private boolean hanldeOverflow() { + //TODO: Decide what to do with queue + + messagesQueue.clear(); + return true; + } + + /** + * This inner class is used to do processes needed during the file saving operations, as an alternative + * thread. + *

+ * This class will be run by the "OutputController" class, as a file save operation is needed. + * This Runnable implemented class, could do the long term file saving operations, as an alternative + * thread. + * Note that this class could just do one file operation at a time. + *

+ */ + private class FileWriter implements Runnable { + //TODO: Insurance about DEAD LOCK in huge files with multiple threads + + private boolean busy = false; + private File file; + private LinkedList messages; + + /** + * Constructor of the class which accepts a File and sets it as the output of writing operations. + * @param file Given File to store message data in + */ + public FileWriter(File file) { + this.file = file; + } + + /** + * Sets the message queue temp (which is stored in the object). + *

+ * This method makes the class enable to have a local copy of message queue, during the file + * processing operations (The outer copy could be destroyed). + *

+ * @param messages The given message linked list, in order to save as a local copy + */ + public void setMessages(LinkedList messages) { + this.messages = messages; + } + + /** + * The implemented run method of the {@link Runnable java.lang.Runnable} class which will + * blocks the other connections to the file writer (by setting "busy" boolean as true) and + * calls the {@link #writeToFile() writeToFile} method in order to writes the contents on the file. + */ + @Override + public void run() { + busy = true; + writeToFile(); + } + + /** + * Stores the contents of the message queue as an appendix to the FileWriter file. + *

+ * This method will write the whole contents of the saved message queue in the file writer object + * on the given file. As this operation is completed, the file writer is eligible to accept files + * again. + *

+ */ + private synchronized void writeToFile() { + for (Message message : this.messages) { + //TODO: Save messages in a file + } + busy = false; + notifyAll(); + } + + public boolean isBusy() { + return busy; + } + } + + /** + * This method serves the instance of {@link server.network.UINetwork UINetwork} class with messages. + *

+ * This method calls {@link server.network.UINetwork#send(server.network.data.Message) send(message)} + * method on {@link server.network.UINetwork UINetwork} instance in order to show up on UI. + * Calling this while the message queue is empty, will put it in the wait mode. + * Basically this method will be called by the timer scheduled according to user preferred + * time interval. + *

+ */ + private synchronized void sendToUINetwork() { + while (messagesQueue.size() <= 0) { + try { + wait(); + } catch (InterruptedException e) { + throw new RuntimeException("Sending to UINetwork interrupted"); + } + } + uiNetwork.send(messagesQueue.getFirst()); //TODO: Must be added in UINetwork + messagesQueue.removeFirst(); + notifyAll(); + } + + /** + * Holds supported types of output handling modes. + */ + private enum OutputHandleMode { + FILE(), + UI_NETWORK() + } +} diff --git a/src/server/exceptions/OutputControllerQueueOverflowException.java b/src/server/exceptions/OutputControllerQueueOverflowException.java new file mode 100644 index 0000000..1dfc891 --- /dev/null +++ b/src/server/exceptions/OutputControllerQueueOverflowException.java @@ -0,0 +1,14 @@ +package server.exceptions; + +/** + * Created by alilotfi on 1/23/15. + */ +public class OutputControllerQueueOverflowException extends RuntimeException { + public OutputControllerQueueOverflowException() { + super(); + } + + public OutputControllerQueueOverflowException(String s) { + super(s); + } +} From dae4cb2895d2d0834c8fd9f9ecbc73025d159d52 Mon Sep 17 00:00:00 2001 From: AliLotfi Date: Mon, 26 Jan 2015 02:52:56 +0330 Subject: [PATCH 16/40] Output Controller revised. --- src/server/core/OutputController.java | 338 +++++++++++++++++--------- 1 file changed, 225 insertions(+), 113 deletions(-) diff --git a/src/server/core/OutputController.java b/src/server/core/OutputController.java index 05a8e08..c3731a0 100644 --- a/src/server/core/OutputController.java +++ b/src/server/core/OutputController.java @@ -8,6 +8,7 @@ import java.util.LinkedList; import java.util.Timer; import java.util.TimerTask; +import java.util.concurrent.*; /** * Class created as a part of {@link GameHandler GameHandler} class for controlling the output. @@ -19,85 +20,107 @@ */ public class OutputController implements Runnable { - private static final int QUEUE_DEFAULT_SIZE = 1000; + private static final int QUEUE_DEFAULT_SIZE = 100000; + private boolean sendToUI = false; private UINetwork uiNetwork; private int timeInterval; private Timer timer; + private boolean sendToFile = false; private File outputFile; private int bufferSize; private FileWriter fileWriter; - private OutputHandleMode outputHandleMode; private LinkedList messagesQueue; - public OutputController() { - messagesQueue = new LinkedList(); - } - /** - * Run method implemented from {@link Runnable java.lang.Runnable} class. + * Constructor with the properties about how outputs must be handled. *

- * This method runs the class activities. In order to running the UINetwork timer correctly, must - * be called after initializing using one of the "setOutputHandleMode" methods. + * This constructor creates an instance of OutputController class with the given parameters. + * The two booleans indicate that how the class will handle the given outputs. + * In the case that sendToUI flag is set: + *

+ * Output handling will be assumed as a "Pre Runner" in order to a fast forward run based + * on the game logic, and storing data on a file for later use. + * Data would be held on memory until reaches the specified buffer size, and then will be + * written to the specified file (Using {@link server.core.OutputController.FileWriter FileWriter} + * runnable class). + *

+ * In the case that sendToFile flag is set: + *

+ * This type of output processing, will store outputs in the object, and sends it in regular + * timer ticks. This time is specified in milliseconds as timeInterval + *

+ * If the sendToUI or sendToFile flags were set, then the two other values would be assigned to the + * appropriate instance values. + * Note that this will raise a runtime exception, in the case of invalid arguments. *

+ * @param sendToUI Indicates that data will be sent to given {@link server.network.UINetwork UINetwork} instance + * or not + * @param uiNetwork The given instance of {@link server.network.UINetwork UINetwork} class to send data to + * @param timeInterval The indicated timer tick which triggers + * {@link server.core.OutputController.UINetworkSender#sendToUINetwork(server.network.data.Message) + * sendToUINetwork(Message)} method + * @param sendToFile Indicates that a log of output will be saved in the given {@link java.io.File java.io.File} or + * not + * @param outputFile The given {@link java.io.File java.io.File} to save data within + * @param bufferSize The preferred number of message elements to be held on memory before writing to file */ - @Override - public void run() { - if (outputHandleMode == OutputHandleMode.UI_NETWORK) { - if (timeInterval != 0) { - timer.scheduleAtFixedRate(new TimerTask() { - @Override - public void run() { - sendToUINetwork(); - } - }, 0, timeInterval); + public OutputController(boolean sendToUI, UINetwork uiNetwork, int timeInterval + , boolean sendToFile, File outputFile, int bufferSize) { + messagesQueue = new LinkedList(); + this.sendToUI = sendToUI; + if (sendToUI) { + if (uiNetwork != null) { + this.uiNetwork = uiNetwork; + } else { + throw new RuntimeException("The given parameter as uiNetwork is null"); } - else { - throw new RuntimeException("Output controller, did not initialized yet"); + + if (timeInterval > 0) { + this.timeInterval = timeInterval; + } else { + throw new RuntimeException("The given parameter as timeInterval is invalid"); } } - } + this.sendToFile = sendToFile; + if (sendToFile) { + if (outputFile.exists()) { + this.outputFile = outputFile; + } else { + throw new RuntimeException("The given parameter as outputFile does not exist"); + } - /** - * Sets the output processing mode of class, to "Save to file" mode. - *

- * This method will set the behavior of class, as a "Pre Runner" in order to a fast forward run based - * on the game logic, and storing data on a file for later usage.
- * Data would be hold on main memory until reaches the specified buffer size, and then will be - * written to the specified file (Using {@link server.core.OutputController.FileWriter FileWriter} - * runnable class). - *

- * @param file File to save outputs of processes to - * @param bufferSize Size which data will be held on RAM, before accessing the file - */ - public void setOutputHandleMode(File file, int bufferSize) { - outputFile = file; - if (bufferSize > 0) { - this.bufferSize = bufferSize; - } else if (bufferSize >= QUEUE_DEFAULT_SIZE) { - throw new RuntimeException("Buffer size greater than max queue size."); - } else { - throw new RuntimeException("Invalid buffer size."); + if (bufferSize > 0 && bufferSize <= QUEUE_DEFAULT_SIZE) { + this.bufferSize = bufferSize; + } else if (bufferSize > 0) { + throw new RuntimeException("The given parameter as bufferSize is greater than max queue size"); + } else { + throw new RuntimeException("The given parameter as bufferSize is not valid"); + } } - fileWriter = new FileWriter(file); - outputHandleMode = OutputHandleMode.FILE; } /** - * Sets the output processing mode of class, to "Show on UI" mode. + * Run method implemented from {@link Runnable java.lang.Runnable} class, which will set and run the two type + * of output handlers. *

- * This type of output processing, will store outputs in the object, and sends it in regular - * timer ticks. This time is specified in milliseconds as "timeInterval". + * In this method, if the sendToUI mode got activated in the class, then a {@link java.util.Timer Timer} will + * be scheduled in the given period to send data to {@link server.network.UINetwork UINetwork}. + * And also if the sendToFile mode got activated, then a thread of + * {@link server.core.OutputController.FileWriter FileWriter} class will be run. *

- * @param uiNetwork The instance of {@link server.network.UINetwork UINetwork} class, which output would be - * sent to - * @param timeInterval The ratio of sending outputs to the UI */ - public void setOutputHandleMode(UINetwork uiNetwork, int timeInterval) { - this.uiNetwork = uiNetwork; - this.timer = new Timer("UI_Network_Sender"); - this.timeInterval = timeInterval; - outputHandleMode = OutputHandleMode.UI_NETWORK; + @Override + public void run() { + if (sendToUI) { + timer = new Timer(); + timer.scheduleAtFixedRate(new UINetworkSender(), 0, timeInterval); + } + + if (sendToFile) { + fileWriter = new FileWriter(outputFile); + } + new Thread(fileWriter).start(); } /** @@ -113,19 +136,11 @@ public void setOutputHandleMode(UINetwork uiNetwork, int timeInterval) { * @param message The given message (as output) to put in the message queue. */ public synchronized void putMessage(Message message) { - if (messagesQueue.size() < QUEUE_DEFAULT_SIZE) { + if (messagesQueue.size() <= QUEUE_DEFAULT_SIZE) { messagesQueue.addLast(message); - if (messagesQueue.size() == bufferSize && outputHandleMode == OutputHandleMode.FILE) { - try { - while (fileWriter.isBusy()) { - wait(); - } - fileWriter.setMessages((LinkedList) messagesQueue.clone()); - new Thread(fileWriter).start(); - messagesQueue.clear(); - } catch (Exception e) { // TODO: Change to appropriate exception handler - - } + if (messagesQueue.size() == bufferSize && sendToFile) { + fileWriter.putMessages(messagesQueue); + messagesQueue = new LinkedList(); } } else { if (hanldeOverflow()) { @@ -140,17 +155,31 @@ public synchronized void putMessage(Message message) { /** * Method created to handle the possible overflows occurance in the message queue. *

- * + * TODO: INCOMPLETE - Must be implemented to cache the queue to file. *

* @return True if the queue unblocked, false if any error occur during this operation */ private boolean hanldeOverflow() { - //TODO: Decide what to do with queue - messagesQueue.clear(); return true; } + /** + * Tries to shutdown all the threads ran in this class so far. + *

+ * This method calls the close on the {@link server.core.OutputController.FileWriter FileWriter} instance of + * the object, causing it to interrupt as soon as all files wrote down on the file. + * Also cancels the timer to stop automatically invocation of + * {@link server.core.OutputController.UINetworkSender UINetworkSender}. + * Other threads would be closed automatically ({@link server.core.OutputController.UINetworkSender + * UINetworkSenders} after the timeout). + *

+ */ + public void shutdown() { + fileWriter.close(); + timer.cancel(); + } + /** * This inner class is used to do processes needed during the file saving operations, as an alternative * thread. @@ -158,15 +187,15 @@ private boolean hanldeOverflow() { * This class will be run by the "OutputController" class, as a file save operation is needed. * This Runnable implemented class, could do the long term file saving operations, as an alternative * thread. - * Note that this class could just do one file operation at a time. + * This class uses a {@link java.util.concurrent.BlockingQueue BlockingQueue>} + * implementation in order to save files without any block on the way of main thread. *

*/ private class FileWriter implements Runnable { - //TODO: Insurance about DEAD LOCK in huge files with multiple threads - private boolean busy = false; + private boolean open = false; private File file; - private LinkedList messages; + private BlockingQueue> messagesQueue; /** * Constructor of the class which accepts a File and sets it as the output of writing operations. @@ -174,80 +203,163 @@ private class FileWriter implements Runnable { */ public FileWriter(File file) { this.file = file; + this.messagesQueue = new ArrayBlockingQueue>(QUEUE_DEFAULT_SIZE); } + /** - * Sets the message queue temp (which is stored in the object). + * Puts the given message in the {@link java.util.concurrent.BlockingQueue BlockingQueue} in order to + * store to file as soon as possible. *

* This method makes the class enable to have a local copy of message queue, during the file * processing operations (The outer copy could be destroyed). *

- * @param messages The given message linked list, in order to save as a local copy + * @param messages The given message linked list, in order to save as a local copy in + * {@link java.util.concurrent.BlockingQueue BlockingQueue} */ - public void setMessages(LinkedList messages) { - this.messages = messages; + public void putMessages(LinkedList messages) { + try { + this.messagesQueue.put(messages); + notifyAll(); + } catch (InterruptedException e) { + throw new RuntimeException("Put messages in FileWriter blocking queue interrupted"); + } } /** * The implemented run method of the {@link Runnable java.lang.Runnable} class which will - * blocks the other connections to the file writer (by setting "busy" boolean as true) and - * calls the {@link #writeToFile() writeToFile} method in order to writes the contents on the file. + * starts the thread listening for any input in order to save to file. + *

+ * This method uses a while loop to save the whole contents of + * {@link java.util.concurrent.BlockingQueue BlockingQueue} of + * {@link server.network.data.Message Messages} to the given file. + * This will stop working only if the close order were sent and there's no more + * {@link server.network.data.Message Messages} on the queue. + *

*/ @Override public void run() { - busy = true; - writeToFile(); + open = true; + while (open || messagesQueue.size() > 0) { + writeToFile(); + } } /** * Stores the contents of the message queue as an appendix to the FileWriter file. *

* This method will write the whole contents of the saved message queue in the file writer object - * on the given file. As this operation is completed, the file writer is eligible to accept files - * again. + * on the given file. As this operation is completed, the file writer tries to write the next file in + * the {@link java.util.concurrent.BlockingQueue BlockingQueue} *

*/ - private synchronized void writeToFile() { - for (Message message : this.messages) { - //TODO: Save messages in a file + private void writeToFile() { + try { + for (Message message : messagesQueue.take()) { + //TODO: Save messages in a file + } + notifyAll(); + } catch (InterruptedException e) { + throw new RuntimeException("Taking from FileWriter message queue interrupted."); } - busy = false; - notifyAll(); } - public boolean isBusy() { - return busy; + /** + * This will send to the class a request to close connection to the file. + *

+ * This method sets the open flag of class to false and so as soon as + * {@link java.util.concurrent.BlockingQueue BlockingQueue} is empty, the writing operation will be + * finished and the thread will be killed. + *

+ */ + public void close() { + this.open = false; } } /** - * This method serves the instance of {@link server.network.UINetwork UINetwork} class with messages. + * Is responsible for sending the first {@link server.network.data.Message Message} in the queue to the + * {@link server.network.UINetwork UINetwork}. *

- * This method calls {@link server.network.UINetwork#send(server.network.data.Message) send(message)} - * method on {@link server.network.UINetwork UINetwork} instance in order to show up on UI. - * Calling this while the message queue is empty, will put it in the wait mode. - * Basically this method will be called by the timer scheduled according to user preferred - * time interval. + * As the failure in connection and some other issues leaves the + * {@link server.network.UINetwork#send(server.network.data.Message) UINetwork.send(Message)} method + * blocked, and so causes a thread block, this class runs as an alternative thread to send the messages + * in the queue, to the {@link server.network.UINetwork UINetwrok} instance without causing the main + * thread of OutputController to sleep. *

*/ - private synchronized void sendToUINetwork() { - while (messagesQueue.size() <= 0) { - try { - wait(); - } catch (InterruptedException e) { - throw new RuntimeException("Sending to UINetwork interrupted"); + private class UINetworkSender extends TimerTask { + + private final static int CONNECTION_TIMEOUT = 1000; + + private boolean sent = false; + + /** + * Implemented run method from {@link java.lang.Runnable Runnable} class which sends the first message in the + * queue to the {@link server.network.UINetwork UINetwork}. + *

+ * This method will call the {@link #sendToUINetwork(server.network.data.Message) sendToUINetwork(Message)} + * method with the appropriate message instance. + * Every connection made in a separate thread and with a specified timeout. + * If the last connection could send the message within the timeout, then this method will take another + * message from the queue and send to the network, otherwise, the last message will be sent again. + * The caller timer will be canceled if the shutdown request was sent to the class. + *

+ */ + @Override + public void run() { + Message message; + synchronized (messagesQueue) { + while (messagesQueue.size() <= 0) { + try { + wait(); + } catch (InterruptedException e) { + throw new RuntimeException("Wait on UINetworkSender interrupted"); + } + } + message = messagesQueue.getFirst(); + if (sent) { + messagesQueue.removeFirst(); + } } + sent = false; + sendToUINetwork(message); } - uiNetwork.send(messagesQueue.getFirst()); //TODO: Must be added in UINetwork - messagesQueue.removeFirst(); - notifyAll(); - } - /** - * Holds supported types of output handling modes. - */ - private enum OutputHandleMode { - FILE(), - UI_NETWORK() + /** + * This method serves the instance of {@link server.network.UINetwork UINetwork} class with messages. + *

+ * This method calls {@link server.network.UINetwork#send(server.network.data.Message) send(message)} + * method on {@link server.network.UINetwork UINetwork} instance in order to show up on UI. + * Calling this while the message queue is empty, will put it in the wait mode. + * Basically this method will be called by the timer scheduled according to user preferred + * time interval. + * As the time of sending message to the {@link server.network.UINetwork UINetworks} exceeds the + * timeout limit, then the execution will be cancelled. + *

+ */ + private void sendToUINetwork(Message message) { + Callable run = new Callable() { + @Override + public Void call() throws Exception { + uiNetwork.send(message); + return null; + } + }; + RunnableFuture runnableFuture = new FutureTask(run); + ExecutorService service = Executors.newSingleThreadExecutor(); + service.execute(runnableFuture); + try { + runnableFuture.get(CONNECTION_TIMEOUT, TimeUnit.MILLISECONDS); + sent = true; + } catch (ExecutionException execution) { + throw new RuntimeException("Connection to the UI failed in execution"); + } catch (TimeoutException timeOut) { + runnableFuture.cancel(true); + } catch (InterruptedException interrupted) { + throw new RuntimeException("Connection to the UI interrupted"); + } + service.shutdown(); + } } } From 31bc4b0f93c48dc00178d1dc2399138ac9915961 Mon Sep 17 00:00:00 2001 From: Hadi Khodabande Date: Mon, 26 Jan 2015 13:09:43 +0330 Subject: [PATCH 17/40] Client side code is nearly complete. --- src/client/AI.java | 32 +++++++ src/client/Controller.java | 174 +++++++++++++++++++++++++++++++++++++ src/client/Main.java | 12 +++ src/client/Model.java | 39 +++++++++ src/client/Network.java | 160 ++++++++++++++++++++++++++++++++++ 5 files changed, 417 insertions(+) create mode 100644 src/client/AI.java create mode 100644 src/client/Controller.java create mode 100644 src/client/Main.java create mode 100644 src/client/Model.java create mode 100644 src/client/Network.java diff --git a/src/client/AI.java b/src/client/AI.java new file mode 100644 index 0000000..255b2c2 --- /dev/null +++ b/src/client/AI.java @@ -0,0 +1,32 @@ +package client; + +/** + * AI class. + * You should fill body of the method {@link #doTurn}. + * Do not change name or modifiers of the methods or fields. + * You can add as many methods or fields as you want! + * You could use model to get information about current state of + * the game. + */ +public class AI { + + /** + * Game model. Describes current state of the game. + */ + public Model model; + + /** + * Constructor. + * + * @param model model of the game + */ + public AI(Model model) { + this.model = model; + } + + public void doTurn() { + // you should fill this method + // an example is included here + } + +} diff --git a/src/client/Controller.java b/src/client/Controller.java new file mode 100644 index 0000000..5ea698e --- /dev/null +++ b/src/client/Controller.java @@ -0,0 +1,174 @@ +package client; + +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import server.network.data.Message; +import util.Log; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.Timer; +import java.util.TimerTask; + +/** + * Main controller. Controls execution of the program, e.g. checks time limit of + * the client, handles incoming messages, controls network operations, etc. + */ +public class Controller { + + /** + * Logging tag. + */ + private static final String TAG = "Controller"; + + /** + * Connection details' file encoding. + */ + private static String detailsEnc = "UTF-8"; + + /** + * Connection details. + */ + private int port; + private String host; + private String token; + + /** + * Player of the game. + */ + private AI client; + + /** + * Model of the game. + */ + private Model model; + + /** + * Client side network. + */ + private Network network; + + /** + * Terminator. Controller waits for this object to be notified. Then it will + * be terminated. + */ + private final Object terminator; + + /** + * Name of the file which contains connection details. + */ + private String settingsFile; + + /** + * Timer used to limit execution of {@link AI#doTurn}. + */ + private Timer timer; + + + /** + * Constructor. + * + * @param settingsFile name of the file which contains connection details + */ + public Controller(String settingsFile) { + timer = new Timer(); + terminator = new Object(); + this.settingsFile = settingsFile; + } + + /** + * Starts a client by connecting to the server and sending a token. + */ + public void start() { + try { + readClientData(); + model = new Model(); + client = new AI(model); + network = new Network(this::handleMessage); + network.setConnectionData(host, port, token); + while (!network.isConnected()) + network.connect(); + synchronized (terminator) { + terminator.wait(); + } + network.terminate(); + } catch (Exception e) { + Log.i(TAG, "Error while starting client.", e); + } + } + + /** + * Handles incoming message. This method will be called from + * {@link client.Network} when a new message is received. + * + * @param msg incoming message + */ + private void handleMessage(Message msg) { + if (msg.name.equals("turn")) + handleTurnMessage(msg); + else if (msg.name.equals("init")) + handleInitMessage(msg); + } + + /** + * Handles init message. + * + * @param msg init message + */ + private void handleInitMessage(Message msg) { + model.handleInitMessage(msg); + } + + /** + * Handles turn message. Gives the message to the model and then executes + * client's code to do next turn. + * + * @param msg turn message + */ + private void handleTurnMessage(Message msg) { + model.handleTurnMessage(msg); + doTurn(); + } + + /** + * Starts {@link AI#doTurn} with turn timeout. + */ + private void doTurn() { + Thread turn = new Thread() { + @Override + public void run() { + // set timeout + timer.schedule(new TimerTask() { + @Override + public void run() { + // interrupt turn thread + interrupt(); + // send result of this turn + network.send(model.getClientTurn()); + } + }, model.getTurnTimeout()); + + // do client's turn + client.doTurn(); + } + }; + turn.start(); + } + + /** + * Reads data of client from the file {@link #settingsFile}. + * + * @throws IOException if an I/O exception occurs during read of the file. + */ + private void readClientData() throws IOException { + byte fileData[] = Files.readAllBytes(Paths.get(settingsFile)); + String json = new String(fileData, detailsEnc); + Gson gson = new Gson(); + JsonObject details = gson.fromJson(json, JsonObject.class); + host = details.getAsJsonPrimitive("ip").getAsString(); + port = details.getAsJsonPrimitive("port").getAsInt(); + token = details.getAsJsonPrimitive("token").getAsString(); + } + +} diff --git a/src/client/Main.java b/src/client/Main.java new file mode 100644 index 0000000..dec5f98 --- /dev/null +++ b/src/client/Main.java @@ -0,0 +1,12 @@ +package client; + +/** + * Initial point of execution. + */ +public class Main { + + public static void main(String[] args) { + new Controller("connection.conf").start(); + } + +} diff --git a/src/client/Model.java b/src/client/Model.java new file mode 100644 index 0000000..930c4b9 --- /dev/null +++ b/src/client/Model.java @@ -0,0 +1,39 @@ +package client; + +import server.network.data.Message; + +/** + * Model contains data which describes current state of the game. + */ +public class Model { + + private long turnTimeout; + private long turnStartTime; + + public void handleInitMessage(Message msg) { + // game developers' todo store data + } + + public void handleTurnMessage(Message msg) { + turnStartTime = System.currentTimeMillis(); + // game developers' todo store data + } + + public long getTurnTimeout() { + return turnTimeout; + } + + public long getTurnTimePassed() { + return System.currentTimeMillis() - turnStartTime; + } + + public long getTurnRemainingTime() { + return turnTimeout - getTurnTimePassed(); + } + + public Message getClientTurn() { + // game developers' todo collect client's events as a single message + return null; + } + +} diff --git a/src/client/Network.java b/src/client/Network.java new file mode 100644 index 0000000..f526e5b --- /dev/null +++ b/src/client/Network.java @@ -0,0 +1,160 @@ +package client; + +import server.network.JsonSocket; +import server.network.data.Message; +import util.Log; + +import java.io.IOException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.function.Consumer; + +/** + * {@link Network} is responsible for connecting to server, and + * sending/receiving messages to/from server. + */ +public class Network { + + /** + * Logging tag. + */ + private static final String TAG = "Network"; + + /** + * Handles incoming messages. + */ + private Consumer messageHandler; + + /** + * Connection details. + */ + private int port; + private String host; + private String token; + + /** + * Socket of the client. + */ + private JsonSocket client; + + /** + * Connection flag. + */ + private boolean isConnected; + + /** + * Executor used to receive messages. + */ + private ExecutorService executor; + + /** + * Termination flag. + */ + private boolean terminateFlag; + + + /** + * Constructor. + * + * @param messageHandler handles incoming messages + */ + public Network(Consumer messageHandler) { + this.messageHandler = messageHandler; + executor = Executors.newSingleThreadExecutor(); + } + + /** + * Setter for connection details. + * + * @param host server's host (ip) + * @param port server's port + * @param token client's token + */ + public void setConnectionData(String host, int port, String token) { + this.host = host; + this.port = port; + this.token = token; + } + + /** + * Tries to connect and send token to the server. + */ + public void connect() { + isConnected = false; + JsonSocket client; + Message init; + try { + client = new JsonSocket(host, port); + client.send(new Message("token", new Object[]{token})); + init = client.get(Message.class); + if (!init.name.equals("init")) { + client.close(); + throw new Exception("First message of the server was not init message."); + } + } catch (Exception e) { + Log.i(TAG, "Error while connection to server.", e); + return; + } + isConnected = true; + this.client = client; + messageHandler.accept(init); + startReceiving(); + } + + /** + * Starts listening for the server messages. + */ + private void startReceiving() { + executor.submit(() -> { + while (!terminateFlag) + doReceive(); + executor.shutdownNow(); + executor = null; + }); + } + + /** + * Listens for a single message of the server. + */ + private void doReceive() { + try { + messageHandler.accept(client.get(Message.class)); + } catch (IOException e) { + Log.i(TAG, "Error receiving the server's message.", e); + } + } + + /** + * Sends a message to the server. + * + * @param msg message to send + */ + public void send(Message msg) { + try { + client.send(msg); + } catch (IOException e) { + Log.i(TAG, "Error while sending client's message.", e); + } + } + + /** + * Terminates operations of the network. + */ + public void terminate() { + terminateFlag = true; + try { + client.close(); + } catch (IOException e) { + Log.i(TAG, "Error closing the client.", e); + } + } + + public boolean isConnected() { + return isConnected; + } + + public boolean isTerminated() { + return terminateFlag; + } + +} From a95d8ff6759ec8b09045e8d48980432a5bc486a3 Mon Sep 17 00:00:00 2001 From: AliLotfi Date: Tue, 27 Jan 2015 22:17:31 +0330 Subject: [PATCH 18/40] Server implemented Factory class added --- src/server/core/Factory.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 src/server/core/Factory.java diff --git a/src/server/core/Factory.java b/src/server/core/Factory.java new file mode 100644 index 0000000..28543ac --- /dev/null +++ b/src/server/core/Factory.java @@ -0,0 +1,19 @@ +package server.core; + +/** + * Factory class is based on factory design pattern, and returns preferred subclass of the + * {@link server.core.GameLogic GameLogic} class which represents the main game logic engine of the game. + *

+ * The user must fill in this method to return the preferred subclass of the + * {@link server.core.GameLogic GameLogic} in order to be used in the + * {@link server.core.GameHandler GameHandler} class + *

+ */ +public interface Factory { + + /** + * The user fills in this abstract method to return the preferred subclass of the game logic. + * @return The preferred child of the {@link server.core.GameLogic GameLogic} class + */ + public GameLogic getGameLogic(); +} From 10d9efd8cc412de523f66b1bb49dc32b26eb5582 Mon Sep 17 00:00:00 2001 From: AliLotfi Date: Tue, 27 Jan 2015 22:22:13 +0330 Subject: [PATCH 19/40] Server implemented Factory class added --- resources/terminal.conf | 4 ++ src/server/Server.java | 104 ++++++++++++++++++++++++++++++- src/server/core/GameHandler.java | 4 ++ src/server/core/GameLogic.java | 9 ++- 4 files changed, 117 insertions(+), 4 deletions(-) create mode 100644 resources/terminal.conf diff --git a/resources/terminal.conf b/resources/terminal.conf new file mode 100644 index 0000000..867a462 --- /dev/null +++ b/resources/terminal.conf @@ -0,0 +1,4 @@ +{ + "token":"", + "port": +} diff --git a/src/server/Server.java b/src/server/Server.java index 3640617..77ab779 100644 --- a/src/server/Server.java +++ b/src/server/Server.java @@ -1,12 +1,110 @@ package server; +import com.google.gson.Gson; +import com.google.gson.JsonParseException; +import server.core.Factory; import server.core.GameHandler; import server.network.TerminalNetwork; +import java.io.File; + /** - * Created by Razi on 12/6/2014. + * Class is the main Server of the game with networks and game logic within. + *

+ * {@link server.Server Server} class is the main runner of the framework activities. + * Creation of the server class will assign the proper objects with the preferred configurations based on + * files within the config files. + * The class creates a terminal with connection through a terminal network. + * Also sets the {@link server.core.GameLogic GameLogic} subclass instance to the + * {@link server.core.GameHandler GameHandler} of the framework with the utility + * {@link server.core.Factory Factory} class. + * Any mistake in the config files causes rising a runtime exception. + *

*/ public class Server { - private TerminalNetwork terminalNetwork; - public GameHandler gameHandler; + + private static final String RESOURCE_PATH_TERMINAL = "/resources/network/terminal.conf"; + + private TerminalNetwork mTerminalNetwork; + private GameHandler mGameHandler; + TerminalConfig mTerminalConfig; + + /** + * Constructor of main server of the framework, which creates and connects server components to the object. + *

+ * This class factory accepts a {@link server.core.Factory Factory} instance in order to set the + * user created subclass of {@link server.core.GameLogic GameLogic} class to the + * {@link server.core.GameHandler GameHandler} of the server. + * The configuration of the {@link server.network.TerminalNetwork TerminalNetwork} is inside a file + * in resource folder. ({@see https://github.com/JavaChallenge/JGFramework/wiki wiki}) + * Occurring any error during parsing the config json file, causes a runtime exception to be thrown. + *

+ * @param factory The factory class, implemented by user, will pass a {@link server.core.GameLogic GameLogic} + * object through its {@link server.core.Factory#getGameLogic() getGameLogic()} method. + */ + public Server (Factory factory) { + File file = new File(RESOURCE_PATH_TERMINAL); + Gson gson = new Gson(); + try { + mTerminalConfig = gson.fromJson(file.toString(), TerminalConfig.class); + } catch (JsonParseException e) { + throw new RuntimeException("Terminal config file does not meet expected syntax"); + } + mTerminalNetwork = new TerminalNetwork(mTerminalConfig.getTerminalToken()); + mGameHandler = new GameHandler(); + mGameHandler.setGameLogic(factory.getGameLogic()); + } + + /** + * Starts the server by make it listening and responding to the Terminal. + */ + public void start() { + mTerminalNetwork.listen(mTerminalConfig.getTerminalPort()); + } + + /** + * This class is the corresponding object of the json config file. + *

+ * This class will be created from the terminal config json file using the + * google-gson object. + * The token is the token of the {@link server.network.TerminalNetwork TerminalNetwork} + * and the port is the port to connect to the {@link server.network.TerminalNetwork TerminalNetwork}. + *

+ */ + private class TerminalConfig { + private String token; + private int port; + + /** + * Getter for the terminal token. + *

+ * This method will check the token for a valid 32-character token and returns it as an + * {@link java.lang.String String}. + * In the case of an invalid token, raises a runtime exception. + *

+ * @return 32-character token + */ + public String getTerminalToken() { + if (token.matches("(.){32}") && token.length() == 32) { + return token; + } + throw new RuntimeException("Invalid terminal token in config file"); + } + + /** + * Getter for the terminal port. + *

+ * This method checks the port for a valid number and returns it as an integer. + * In the case of an invalid port number (out of range numbers), raises a runtime exception. + *

+ * @return Integer port number + */ + public int getTerminalPort() { + if (port > 0 && port <= 65535) { + return port; + } else { + throw new RuntimeException("Invalid port number in config file"); + } + } + } } diff --git a/src/server/core/GameHandler.java b/src/server/core/GameHandler.java index 3a475da..308ebe8 100644 --- a/src/server/core/GameHandler.java +++ b/src/server/core/GameHandler.java @@ -10,4 +10,8 @@ public class GameHandler { private ClientNetwork clientNetwork; private UINetwork uiNetwork; private GameLogic gameLogic; + + public void setGameLogic (GameLogic gameLogic) { + this.gameLogic = gameLogic; + } } diff --git a/src/server/core/GameLogic.java b/src/server/core/GameLogic.java index f0fe94f..b753654 100644 --- a/src/server/core/GameLogic.java +++ b/src/server/core/GameLogic.java @@ -1,7 +1,14 @@ package server.core; +import server.core.model.Event; + /** - * Created by Razi on 12/6/2014. + * The abstract class representing the main game logic of the user's game. + *

+ * This class will be the simulator engine of the game. + *

*/ public abstract class GameLogic { + + public abstract void sendEvent(Event event); } From c377f37b06f24cf61004f6d4e6a051bcc5da9690 Mon Sep 17 00:00:00 2001 From: AliLotfi Date: Wed, 28 Jan 2015 02:19:28 +0330 Subject: [PATCH 20/40] GameHandler class nearly completed --- .gitignore | 5 +- resources/game_handler/output_handler.conf | 7 ++ resources/network/terminal.conf | 3 + resources/terminal.conf | 4 - src/server/Server.java | 7 +- src/server/core/GameHandler.java | 105 ++++++++++++++++++++- src/server/core/GameLogic.java | 8 +- src/server/core/OutputController.java | 8 +- 8 files changed, 130 insertions(+), 17 deletions(-) create mode 100644 resources/game_handler/output_handler.conf create mode 100644 resources/network/terminal.conf delete mode 100644 resources/terminal.conf diff --git a/.gitignore b/.gitignore index 5130051..295f330 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ .idea -SharifEngine.iml +JGFramework.iml *.class @@ -13,3 +13,6 @@ SharifEngine.iml # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml hs_err_pid* + +# Jar libraries # +./libs/*.jar \ No newline at end of file diff --git a/resources/game_handler/output_handler.conf b/resources/game_handler/output_handler.conf new file mode 100644 index 0000000..05bf6bd --- /dev/null +++ b/resources/game_handler/output_handler.conf @@ -0,0 +1,7 @@ +{ + "sendToUI" : true, + "timeInterval" : 100, + "sendToFile" : true, + "filePath" : "/log.log", + "bufferSize" : 10 +} \ No newline at end of file diff --git a/resources/network/terminal.conf b/resources/network/terminal.conf new file mode 100644 index 0000000..064739e --- /dev/null +++ b/resources/network/terminal.conf @@ -0,0 +1,3 @@ +{ "token":"abcdefghijklmnopqrstuvwxyz012345", + "port" : 3001 +} diff --git a/resources/terminal.conf b/resources/terminal.conf deleted file mode 100644 index 867a462..0000000 --- a/resources/terminal.conf +++ /dev/null @@ -1,4 +0,0 @@ -{ - "token":"", - "port": -} diff --git a/src/server/Server.java b/src/server/Server.java index 77ab779..9bf044b 100644 --- a/src/server/Server.java +++ b/src/server/Server.java @@ -4,7 +4,9 @@ import com.google.gson.JsonParseException; import server.core.Factory; import server.core.GameHandler; +import server.network.ClientNetwork; import server.network.TerminalNetwork; +import server.network.UINetwork; import java.io.File; @@ -51,8 +53,9 @@ public Server (Factory factory) { throw new RuntimeException("Terminal config file does not meet expected syntax"); } mTerminalNetwork = new TerminalNetwork(mTerminalConfig.getTerminalToken()); - mGameHandler = new GameHandler(); - mGameHandler.setGameLogic(factory.getGameLogic()); + //FIXME: INCOMPLETE STATEMENT. Client netwoek and UI network most be initialized correctly + mGameHandler = new GameHandler(new ClientNetwork(), new UINetwork(null), factory.getGameLogic()); + } /** diff --git a/src/server/core/GameHandler.java b/src/server/core/GameHandler.java index 308ebe8..62011e4 100644 --- a/src/server/core/GameHandler.java +++ b/src/server/core/GameHandler.java @@ -1,17 +1,114 @@ package server.core; +import com.google.gson.Gson; +import com.google.gson.JsonParseException; +import server.core.model.Event; import server.network.ClientNetwork; import server.network.UINetwork; +import server.network.data.Message; + +import java.io.File; +import java.util.ArrayList; +import java.util.concurrent.*; /** * Created by Razi on 12/6/2014. */ public class GameHandler { + + private static final String RESOURCE_PATH_OUTPUT_HANDLER = "/resources/game_handler/output_handler.conf"; + private static final int GAME_LOGIC_SIMULATE_TIMEOUT = 500; + private ClientNetwork clientNetwork; - private UINetwork uiNetwork; - private GameLogic gameLogic; + private UINetwork mUINetwork; + private GameLogic mGameLogic; + private OutputController mOutputController; + + private Loop mLoop; + private ArrayList mEventsQueue; + + public GameHandler(ClientNetwork clientNetwork, UINetwork uiNetwork, GameLogic gameLogic) { + this.mGameLogic = gameLogic; + } + + public void init() { + OutputHandlerConfig outputHandlerConfig; + File file = new File(RESOURCE_PATH_OUTPUT_HANDLER); + Gson gson = new Gson(); + try { + outputHandlerConfig = gson.fromJson(file.toString(), OutputHandlerConfig.class); + } catch (JsonParseException e) { + throw new RuntimeException("Output handler config file does not meet expected syntax"); + } + mOutputController = new OutputController(outputHandlerConfig.sendToUI , + mUINetwork, + outputHandlerConfig.timeInterval, + outputHandlerConfig.sendToFile, + outputHandlerConfig.getFile(), + outputHandlerConfig.bufferSize); + + } + + public void start() { + new Thread(mLoop).start(); + new Thread(mOutputController).start(); + } + + public void shutdown() { + mLoop.shutdown(); + mOutputController.shutdown(); + } + + private class Loop implements Runnable { + + private boolean shutdownRequest = false; + private Message[] messages; + + @Override + public void run() { + Callable simulate = new Callable() { + @Override + public Message[] call() throws Exception { + messages = mGameLogic.simulateEvents((Event[]) mEventsQueue.toArray()); + return messages = mGameLogic.setViews(messages); + } + }; + RunnableFuture runnableSimulate = new FutureTask(simulate); + ExecutorService service = Executors.newSingleThreadExecutor(); + + while (!shutdownRequest) { + service.execute(runnableSimulate); + try { + messages = runnableSimulate.get(GAME_LOGIC_SIMULATE_TIMEOUT, TimeUnit.MILLISECONDS); + } catch (ExecutionException execution) { + throw new RuntimeException("GameLogic execution encountered exception"); + } catch (TimeoutException timeOut) { + runnableSimulate.cancel(true); + } catch (InterruptedException interrupted) { + throw new RuntimeException("GameLogic execution interrupted"); + } + + for (Message message : messages) { + mOutputController.putMessage(message); + } + } + service.shutdown(); + } + + public void shutdown() { + this.shutdownRequest = true; + } + } + + private class OutputHandlerConfig { + private boolean sendToUI; + private int timeInterval; + private boolean sendToFile; + private String filePath; + private int bufferSize; - public void setGameLogic (GameLogic gameLogic) { - this.gameLogic = gameLogic; + private File getFile() { + return new File(filePath); + } } } diff --git a/src/server/core/GameLogic.java b/src/server/core/GameLogic.java index b753654..4efbda4 100644 --- a/src/server/core/GameLogic.java +++ b/src/server/core/GameLogic.java @@ -1,6 +1,7 @@ package server.core; import server.core.model.Event; +import server.network.data.Message; /** * The abstract class representing the main game logic of the user's game. @@ -8,7 +9,10 @@ * This class will be the simulator engine of the game. *

*/ -public abstract class GameLogic { +public interface GameLogic { - public abstract void sendEvent(Event event); + public Message[] simulateEvents(Event[] events); + + + public Message[] setViews(Message[] messages); } diff --git a/src/server/core/OutputController.java b/src/server/core/OutputController.java index c3731a0..391c818 100644 --- a/src/server/core/OutputController.java +++ b/src/server/core/OutputController.java @@ -67,7 +67,7 @@ public class OutputController implements Runnable { */ public OutputController(boolean sendToUI, UINetwork uiNetwork, int timeInterval , boolean sendToFile, File outputFile, int bufferSize) { - messagesQueue = new LinkedList(); + messagesQueue = new LinkedList<>(); this.sendToUI = sendToUI; if (sendToUI) { if (uiNetwork != null) { @@ -140,7 +140,7 @@ public synchronized void putMessage(Message message) { messagesQueue.addLast(message); if (messagesQueue.size() == bufferSize && sendToFile) { fileWriter.putMessages(messagesQueue); - messagesQueue = new LinkedList(); + messagesQueue = new LinkedList<>(); } } else { if (hanldeOverflow()) { @@ -203,7 +203,7 @@ private class FileWriter implements Runnable { */ public FileWriter(File file) { this.file = file; - this.messagesQueue = new ArrayBlockingQueue>(QUEUE_DEFAULT_SIZE); + this.messagesQueue = new ArrayBlockingQueue<>(QUEUE_DEFAULT_SIZE); } @@ -346,7 +346,7 @@ public Void call() throws Exception { return null; } }; - RunnableFuture runnableFuture = new FutureTask(run); + RunnableFuture runnableFuture = new FutureTask<>(run); ExecutorService service = Executors.newSingleThreadExecutor(); service.execute(runnableFuture); try { From 676c43fe1c2b73d0bbc0023826476b8c9d965729 Mon Sep 17 00:00:00 2001 From: Hadi Khodabande Date: Wed, 28 Jan 2015 15:03:13 +0330 Subject: [PATCH 21/40] Some changes in network. UINetwork no longer has a queue. ClientNetwork has capability to wait for a client's message. ClientNetwork now has a method which returns event of a client. --- src/server/network/ClientHandler.java | 34 ++++- src/server/network/ClientNetwork.java | 60 +++++++- src/server/network/NetServerThread.java | 4 +- src/server/network/UINetwork.java | 131 ++++++++++-------- .../server/network/ClientNetworkTest.java | 2 +- src/test/server/network/UINetworkTest.java | 17 +-- 6 files changed, 171 insertions(+), 77 deletions(-) diff --git a/src/server/network/ClientHandler.java b/src/server/network/ClientHandler.java index 6b918a1..ea23df1 100644 --- a/src/server/network/ClientHandler.java +++ b/src/server/network/ClientHandler.java @@ -52,6 +52,11 @@ public class ClientHandler { */ private Message lastReceivedMessage; + /** + * This object is notified when a message is received. + */ + private final Object messageNotifier; + /** * Message queue. These messages will be sent to the client asap. */ @@ -64,6 +69,7 @@ public class ClientHandler { public ClientHandler() { messagesToSend = new LinkedBlockingDeque<>(); clientLock = new Object(); + messageNotifier = new Object(); } /** @@ -164,6 +170,9 @@ public Runnable getReceiver(Supplier timeValidator) { */ private void receive() throws IOException { lastReceivedMessage = client.get(Message.class); + synchronized (messageNotifier) { + messageNotifier.notifyAll(); + } } /** @@ -175,6 +184,29 @@ public boolean isConnected() { return client != null; } + /** + * Blocks caller method until the client send a message. + * + * @throws InterruptedException if current thread is interrupted. + */ + public void waitForClientMessage() throws InterruptedException { + synchronized (messageNotifier) { + messageNotifier.wait(); + } + } + + /** + * Blocks caller method at most timeout milliseconds until + * the client send a message. + * + * @throws InterruptedException if current thread is interrupted. + */ + public void waitForClientMessage(long timeout) throws InterruptedException { + synchronized (messageNotifier) { + messageNotifier.wait(timeout); + } + } + /** * Blocks caller method until a client is connected to this handler. * @@ -211,7 +243,7 @@ public void terminate() { if (client != null) client.close(); } catch (IOException e) { - Log.i(TAG, "socket closing failure", e); + Log.i(TAG, "Socket closing failure.", e); } } diff --git a/src/server/network/ClientNetwork.java b/src/server/network/ClientNetwork.java index 4e1c30f..2ea5c16 100644 --- a/src/server/network/ClientNetwork.java +++ b/src/server/network/ClientNetwork.java @@ -1,5 +1,9 @@ package server.network; +import com.google.gson.Gson; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import server.core.model.Event; import server.network.data.Message; import util.Log; @@ -64,10 +68,16 @@ public class ClientNetwork extends NetServer { */ private ExecutorService acceptExecutor; + /** + * Gson used to extract event from a message. + */ + private Gson gson; + /** * Constructor. */ public ClientNetwork() { + gson = new Gson(); mTokens = new HashMap<>(); mClients = new ArrayList<>(); sendExecutor = Executors.newCachedThreadPool(); @@ -196,10 +206,29 @@ public void startReceivingAll() { * @return last valid message or null if there is no valid msg * @see {@link #defineClient} */ - public Message getReceived(int clientID) { + public Message getReceivedMessage(int clientID) { return mClients.get(clientID).getLastValidatedMessage(); } + /** + * Returns last valid event which is received from a client. + * + * @param clientID ID of the client + * @return last valid event or null if there is no valid event + * @see {@link #getReceivedMessage} + */ + public Event getReceivedEvent(int clientID) { + Message msg = getReceivedMessage(clientID); + Event event = null; + // convert argument 0 of the message to an object of type Event + if (msg != null && msg.args != null && + msg.args.length > 0 && msg.args[0] instanceof JsonElement) { + JsonElement arg0 = (JsonElement) msg.args[0]; + event = gson.fromJson(arg0, Event.class); + } + return event; + } + @Override protected void accept(JsonSocket client) { acceptExecutor.submit(() -> { @@ -232,7 +261,30 @@ private void verifyClient(JsonSocket client) throws Exception { } /** - * Blocks caller method until a client is connected to the server. + * Blocks caller method until the specified client send a message. + * + * @param clientID ID of the client + * @throws InterruptedException if current thread is interrupted. + * @see {@link #defineClient} + */ + public void waitForClientMessage(int clientID) throws InterruptedException { + mClients.get(clientID).waitForClientMessage(); + } + + /** + * Blocks caller method at most timeout milliseconds until + * the specified client send a message. + * + * @param clientID ID of the client + * @throws InterruptedException if current thread is interrupted. + * @see {@link #defineClient} + */ + public void waitForClientMessage(int clientID, long timeout) throws InterruptedException { + mClients.get(clientID).waitForClientMessage(timeout); + } + + /** + * Blocks caller method until the specified client is connected to the server. * * @param clientID ID of the client * @throws InterruptedException if current thread is interrupted. @@ -243,8 +295,8 @@ public void waitForClient(int clientID) throws InterruptedException { } /** - * Blocks caller method at most timeout milliseconds until a - * client is connected to the server. + * Blocks caller method at most timeout milliseconds until + * the specified client is connected to the server. * * @param clientID ID of the client * @param timeout timeout in milliseconds diff --git a/src/server/network/NetServerThread.java b/src/server/network/NetServerThread.java index bb944fe..7e906f5 100644 --- a/src/server/network/NetServerThread.java +++ b/src/server/network/NetServerThread.java @@ -78,7 +78,7 @@ public void run() { try { runServer(); } catch (Exception e) { - Log.i(TAG, "server socket closed", e); + Log.i(TAG, "Server socket closed", e); } } @@ -107,7 +107,7 @@ public synchronized void terminate() { try { serverSocket.close(); } catch (Exception e) { - Log.i(TAG, "socket closing failure", e); + Log.i(TAG, "Socket closing failure.", e); } } diff --git a/src/server/network/UINetwork.java b/src/server/network/UINetwork.java index 0f0d065..01d9e99 100644 --- a/src/server/network/UINetwork.java +++ b/src/server/network/UINetwork.java @@ -5,6 +5,8 @@ import java.io.IOException; import java.util.concurrent.*; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; /** * {@link server.network.UINetwork} is a server which is responsible for sending @@ -13,7 +15,7 @@ * When a client is connected to the server, it sends a token and waits for the * initial message which contains necessary data of beginning of the game. *

- * Messages are sent using {@link #send} method. + * Messages are sent using methods {@link #sendBlocking} or {@link #sendNonBlocking}. *

* The communications are one sided, i.e. everything which is sent by client is * ignored by the server. @@ -36,78 +38,66 @@ public final class UINetwork extends NetServer { private JsonSocket mClient; /** - * lock for {@link #mClient} + * Lock for {@link #mClient} */ - private final Object mClientLock; + private final Lock mClientLock; /** - * a deque for messages that are waiting to send + * Notifies waiters when a new client is connected. */ - private LinkedBlockingDeque mMessagesToSend; + private final Object clientNotifier; /** * thread executor which is used to accept clients */ private ExecutorService executor; + /** + * Thread executor which is used to send messages. + */ + private ExecutorService sendExecutor; + /** * Initializes the class and starts sending messages to clients. * If there is no client at the time of sending, the message will be * thrown away. * * @param token token of the server - * @see #send - * @see #startSending + * @see #sendBlocking + * @see #sendNonBlocking * @see #hasClient * @see #waitForClient * @see #waitForNewClient */ public UINetwork(String token) { mToken = token; - mClientLock = new Object(); - mMessagesToSend = new LinkedBlockingDeque<>(); - executor = Executors.newCachedThreadPool(); - startSending(); + clientNotifier = new Object(); + mClientLock = new ReentrantLock(true); } /** * Sends a message to the client. - * It actually adds this message to {@link #mMessagesToSend} and sends is - * as soon as it is possible. + * Caller method will be blocked until the message is sent. * - * @param msg message to send + * @param msg message to send */ - public void send(Message msg) { - mMessagesToSend.add(msg); + public void sendBlocking(Message msg) { + try { + mClient.send(msg); + } catch (IOException e) { + Log.d(TAG, "Message sending failure.", e); + } } /** - * Runs the main thread for sending messages to the client on the - * {@link #executor}. - * If there is no client at the time of sending, the message will be - * thrown away. - * To prevent this situation one can use {@link #waitForClient} to ensure - * that a client is connected to the server. + * Sends a message to the client. + * Caller method wont be blocked. * - * @see #waitForClient - * @see #waitForNewClient - * @see #send + * @param msg message to send + * @see #sendBlocking */ - private void startSending() { - executor.submit(() -> { - while (!isTerminated()) { - try { - Message msg = mMessagesToSend.take(); - synchronized (mClientLock) { - mClient.send(msg); - } - } catch (InterruptedException e) { - Log.d(TAG, "waiting for message interrupted", e); - } catch (IOException e) { - Log.d(TAG, "message sending failure", e); - } - } - }); + public void sendNonBlocking(Message msg) { + sendExecutor.submit(() -> sendBlocking(msg)); } /** @@ -123,7 +113,7 @@ protected void accept(JsonSocket client) { verifyClient(client); } catch (Exception e) { // if anything was wrong close the client! - Log.i(TAG, "client rejected", e); + Log.i(TAG, "Client rejected.", e); try { client.close(); } catch (Exception ignored) {} @@ -160,21 +150,40 @@ private void verifyClient(JsonSocket client) throws Exception { * @see #verifyClient */ private void changeClient(JsonSocket client) { - synchronized (mClientLock) { - try { - // close previous socket + mClientLock.lock(); + try { + // close previous socket + if (mClient != null) mClient.close(); - } catch (Exception e) { - Log.i(TAG, "socket closing failure", e); - } finally { - // change the client - mClient = client; - // notify waiting threads - mClientLock.notify(); + } catch (Exception e) { + Log.i(TAG, "Socket closing failure.", e); + } finally { + // change the client + mClient = client; + // notify waiting threads + synchronized (clientNotifier) { + clientNotifier.notifyAll(); } + mClientLock.unlock(); } } + @Override + public synchronized void listen(int port) { + executor = Executors.newCachedThreadPool(); + sendExecutor = Executors.newSingleThreadExecutor(); + super.listen(port); + } + + @Override + public synchronized void terminate() { + super.terminate(); + executor.shutdown(); + executor = null; + sendExecutor.shutdown(); + sendExecutor = null; + } + /** * Returns true if any client is connected and verified by the server. * @@ -191,10 +200,10 @@ public boolean hasClient() { * @throws InterruptedException if the current thread is interrupted. */ public void waitForClient() throws InterruptedException { - synchronized (mClientLock) { - if (mClient != null) + synchronized (clientNotifier) { + if (hasClient()) return; - mClientLock.wait(); + clientNotifier.wait(); } } @@ -207,10 +216,10 @@ public void waitForClient() throws InterruptedException { * @throws InterruptedException if the current thread is interrupted. */ public void waitForClient(long timeout) throws InterruptedException { - synchronized (mClientLock) { - if (mClient != null) + synchronized (clientNotifier) { + if (hasClient()) return; - mClientLock.wait(timeout); + clientNotifier.wait(timeout); } } @@ -220,8 +229,8 @@ public void waitForClient(long timeout) throws InterruptedException { * @throws InterruptedException if the current thread is interrupted. */ public void waitForNewClient() throws InterruptedException { - synchronized (mClientLock) { - mClientLock.wait(); + synchronized (clientNotifier) { + clientNotifier.wait(); } } @@ -233,8 +242,8 @@ public void waitForNewClient() throws InterruptedException { * @throws InterruptedException if the current thread is interrupted. */ public void waitForNewClient(long timeout) throws InterruptedException { - synchronized (mClientLock) { - mClientLock.wait(timeout); + synchronized (clientNotifier) { + clientNotifier.wait(timeout); } } diff --git a/src/test/server/network/ClientNetworkTest.java b/src/test/server/network/ClientNetworkTest.java index 51a55e9..de51408 100644 --- a/src/test/server/network/ClientNetworkTest.java +++ b/src/test/server/network/ClientNetworkTest.java @@ -217,7 +217,7 @@ public void test6_simple_send_receive() throws Exception { clientNetwork.stopReceivingAll(); client.send(msg[3]); client.send(msg[4]); - Message m = clientNetwork.getReceived(id); + Message m = clientNetwork.getReceivedMessage(id); assertEquals(m.name, msg[2].name); assertEquals(m.args[0], msg[2].args[0]); assertEquals(m.args[1], msg[2].args[1]); diff --git a/src/test/server/network/UINetworkTest.java b/src/test/server/network/UINetworkTest.java index 3e4b8a4..5d566bd 100644 --- a/src/test/server/network/UINetworkTest.java +++ b/src/test/server/network/UINetworkTest.java @@ -74,7 +74,7 @@ public void test3_send_message() throws IOException, InterruptedException { // wait for the server to check the token uiNetwork.waitForClient(); // send message from UINetwork to the client - uiNetwork.send(new Message("name", new Object[] {"arg0", "arg1"})); + uiNetwork.sendNonBlocking(new Message("name", new Object[]{"arg0", "arg1"})); // get message Message msg = client.get(Message.class); // check data of received message @@ -99,8 +99,9 @@ public void test4_10000_messages() throws IOException, InterruptedException { data[i] = Math.random(); // send messages from server long start = System.currentTimeMillis(); - for (int i = 0; i < total; i++) - uiNetwork.send(new Message("msg", new Object[] {data[i]})); + for (int i = 0; i < total; i++) { + uiNetwork.sendNonBlocking(new Message("msg", new Object[]{data[i]})); + } long end = System.currentTimeMillis(); System.out.printf("total sending time: %d ms/%d msg%n", end-start, total); // get messages on client side @@ -115,19 +116,19 @@ public void test4_10000_messages() throws IOException, InterruptedException { public void test5_multiple_clients() throws IOException, InterruptedException { // client1 JsonSocket client1 = new JsonSocket(host, port); - client1.send(new Message("token", new Object[] {token})); + client1.send(new Message("token", new Object[]{token})); uiNetwork.waitForClient(); - uiNetwork.send(new Message("to client1", null)); + uiNetwork.sendNonBlocking(new Message("to client1", null)); // client2 JsonSocket client2 = new JsonSocket(host, port); - client2.send(new Message("token", new Object[] {token})); + client2.send(new Message("token", new Object[]{token})); uiNetwork.waitForNewClient(); - uiNetwork.send(new Message("to client2", null)); + uiNetwork.sendNonBlocking(new Message("to client2", null)); // client3 (wrong token) JsonSocket client3 = new JsonSocket(host, port); client3.send(token); uiNetwork.waitForNewClient(1000); - uiNetwork.send(new Message("to client2 again", null)); + uiNetwork.sendNonBlocking(new Message("to client2 again", null)); // get messages Message msg1 = client1.get(Message.class); Message msg2 = client2.get(Message.class); From 28322ca1a120181e57780b0bd7883b06f4f9a024 Mon Sep 17 00:00:00 2001 From: rajabzz Date: Mon, 2 Feb 2015 14:07:06 +0330 Subject: [PATCH 22/40] Complete GameLogic Interface --- src/server/core/GameLogic.java | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/src/server/core/GameLogic.java b/src/server/core/GameLogic.java index 4efbda4..ba4bafa 100644 --- a/src/server/core/GameLogic.java +++ b/src/server/core/GameLogic.java @@ -3,6 +3,9 @@ import server.core.model.Event; import server.network.data.Message; +import java.util.HashMap; +import java.util.UUID; + /** * The abstract class representing the main game logic of the user's game. *

@@ -11,8 +14,34 @@ */ public interface GameLogic { - public Message[] simulateEvents(Event[] events); + /** + * This method must send initial and necessary values to UI and clients. + * @return A hashmap that has Token as key and a Message as value. + * Token is used for specifying if the Message is for UI or Client. + */ + public HashMap init(); + + /** + * Simulate events based on the current turn event and calculate the changes in game. + * @param terminalEvent Events that user enters in terminal. + * @param environmentEvent Events that is related to environment. Suppose we want to develop a strategic game. + * Increasing/Decreasing a specific resource in map is an environment event. + * @param clientsEvent Events that is related to client e.g. moving the player. + */ + public void simulateEvents(Event[] terminalEvent, Event[] environmentEvent, HashMap clientsEvent); + + /** + * This method generates the output based on the changes that were calculated in + * {@link #simulateEvents(server.core.model.Event[], server.core.model.Event[], java.util.HashMap)}. + * @return A hashmap that has Token as key and a Message as value. + * Token is used for specifying if the Message is for UI or Client. + */ + public HashMap generateOutputs(); + /** + * This method is used for making the environment events. + * @return An array that is environment events. + */ + public Event[] makeEnvironmentEvents(); - public Message[] setViews(Message[] messages); } From 702a6adaaa21b0bc5707c5464d05a3603daf9ac2 Mon Sep 17 00:00:00 2001 From: alilotfi Date: Mon, 2 Feb 2015 18:26:58 +0330 Subject: [PATCH 23/40] "New Game" created "Main Loop" manipulated --- resources/network/terminal.conf | 3 +- resources/network/ui.conf | 3 + src/server/Server.java | 92 ++++++++++++++++++++++++--- src/server/core/CommandHandler.java | 22 +++++++ src/server/core/Factory.java | 2 +- src/server/core/GameHandler.java | 81 ++++++++++++++++++----- src/server/core/GameLogic.java | 32 +++++++++- src/server/core/model/ClientInfo.java | 21 ++++++ src/server/network/ClientNetwork.java | 19 +++--- 9 files changed, 239 insertions(+), 36 deletions(-) create mode 100644 resources/network/ui.conf create mode 100644 src/server/core/CommandHandler.java create mode 100644 src/server/core/model/ClientInfo.java diff --git a/resources/network/terminal.conf b/resources/network/terminal.conf index 064739e..66eff6f 100644 --- a/resources/network/terminal.conf +++ b/resources/network/terminal.conf @@ -1,3 +1,4 @@ -{ "token":"abcdefghijklmnopqrstuvwxyz012345", +{ + "token" : "abcdefghijklmnopqrstuvwxyz012345", "port" : 3001 } diff --git a/resources/network/ui.conf b/resources/network/ui.conf new file mode 100644 index 0000000..b96e2a8 --- /dev/null +++ b/resources/network/ui.conf @@ -0,0 +1,3 @@ +{ + "token" : "abcdefghijklmnopqrstuvwxyz012345" +} \ No newline at end of file diff --git a/src/server/Server.java b/src/server/Server.java index 9bf044b..3cef92d 100644 --- a/src/server/Server.java +++ b/src/server/Server.java @@ -2,13 +2,18 @@ import com.google.gson.Gson; import com.google.gson.JsonParseException; +import server.core.CommandHandler; import server.core.Factory; import server.core.GameHandler; +import server.core.GameLogic; +import server.core.model.ClientInfo; import server.network.ClientNetwork; import server.network.TerminalNetwork; import server.network.UINetwork; +import server.network.data.Message; import java.io.File; +import java.util.HashMap; /** * Class is the main Server of the game with networks and game logic within. @@ -26,25 +31,32 @@ public class Server { private static final String RESOURCE_PATH_TERMINAL = "/resources/network/terminal.conf"; + private static final String RESOURCE_PATH_UI = "/resources/network/ui.conf"; + private Factory mFactory; private TerminalNetwork mTerminalNetwork; private GameHandler mGameHandler; + private CommandHandler mCommandHandler; TerminalConfig mTerminalConfig; + ClientInfo[] mClientsInfo; + /** * Constructor of main server of the framework, which creates and connects server components to the object. *

* This class factory accepts a {@link server.core.Factory Factory} instance in order to set the * user created subclass of {@link server.core.GameLogic GameLogic} class to the * {@link server.core.GameHandler GameHandler} of the server. - * The configuration of the {@link server.network.TerminalNetwork TerminalNetwork} is inside a file - * in resource folder. ({@see https://github.com/JavaChallenge/JGFramework/wiki wiki}) - * Occurring any error during parsing the config json file, causes a runtime exception to be thrown. + * The configuration of {@link server.network.TerminalNetwork TerminalNetwork} and + * {@link server.network.UINetwork UINetwork} are inside a file in resources folder. + * ({@see https://github.com/JavaChallenge/JGFramework/wiki wiki}) + * Occurring any error during parsing config json files, causes a runtime exception to be thrown. *

- * @param factory The factory class, implemented by user, will pass a {@link server.core.GameLogic GameLogic} - * object through its {@link server.core.Factory#getGameLogic() getGameLogic()} method. + * @param factory The factory class, implemented by user. */ - public Server (Factory factory) { + public Server(Factory factory) { + mFactory = factory; + File file = new File(RESOURCE_PATH_TERMINAL); Gson gson = new Gson(); try { @@ -53,9 +65,50 @@ public Server (Factory factory) { throw new RuntimeException("Terminal config file does not meet expected syntax"); } mTerminalNetwork = new TerminalNetwork(mTerminalConfig.getTerminalToken()); - //FIXME: INCOMPLETE STATEMENT. Client netwoek and UI network most be initialized correctly - mGameHandler = new GameHandler(new ClientNetwork(), new UINetwork(null), factory.getGameLogic()); + file = new File(RESOURCE_PATH_UI); + UIConfig uiConfig = gson.fromJson(file.toString(), UIConfig.class); + mGameHandler = new GameHandler(new ClientNetwork(), new UINetwork(uiConfig.getUIToken())); + + mCommandHandler = new CommandHandler(); + } + + public void setCommandHandler(CommandHandler commandHandler) { + mCommandHandler = commandHandler; + } + + private void newGame(String[] options, long timeout) { + GameLogic gameLogic = mFactory.getGameLogic(options); + gameLogic.init(); + mClientsInfo = gameLogic.getClientInfo(); + mGameHandler.setClientsInfo(mClientsInfo); + mGameHandler.setGameLogic(gameLogic); + for (ClientInfo c : mClientsInfo) { + int id = mGameHandler.getClientNetwork().defineClient(c.getToken()); + c.setID(id); + } + + try { + mGameHandler.getUINetwork().waitForClient(); + } catch (InterruptedException e) { + throw new RuntimeException("Waiting for ui clients interrupted"); + } + + try { + mGameHandler.getClientNetwork().waitForAllClients(timeout); + } catch (InterruptedException e) { + throw new RuntimeException("Waiting for clients interrupted"); + } + + Message initialMessage = gameLogic.getUIInitialMessage(); + mGameHandler.getUINetwork().sendBlocking(initialMessage); + + Message[] initialMessages = gameLogic.getClientInitialMessages(); + for (int i = 0; i + * This method will check the token for a valid 32-character token and returns it as an + * {@link java.lang.String String}. + * In the case of an invalid token, raises a runtime exception. + *

+ * @return 32-character token + */ + public String getUIToken() { + if (token.matches("(.){32}") && token.length() == 32) { + return token; + } + throw new RuntimeException("Invalid UI token in config file"); + } + } } diff --git a/src/server/core/CommandHandler.java b/src/server/core/CommandHandler.java new file mode 100644 index 0000000..f7f95a5 --- /dev/null +++ b/src/server/core/CommandHandler.java @@ -0,0 +1,22 @@ +package server.core; + +import server.core.model.Event; +import server.network.TerminalNetwork; +import server.network.data.Command; +import server.network.data.CommandReport; + +/** + * Created by alilotfi on 2/2/15. + */ +public class CommandHandler implements TerminalNetwork.TerminalInterface { + + @Override + public CommandReport runCommand(Command command) { + return null; + } + + @Override + public void putEvent(Event event) { + + } +} diff --git a/src/server/core/Factory.java b/src/server/core/Factory.java index 28543ac..5b9ec51 100644 --- a/src/server/core/Factory.java +++ b/src/server/core/Factory.java @@ -15,5 +15,5 @@ public interface Factory { * The user fills in this abstract method to return the preferred subclass of the game logic. * @return The preferred child of the {@link server.core.GameLogic GameLogic} class */ - public GameLogic getGameLogic(); + public GameLogic getGameLogic(String[] options); } diff --git a/src/server/core/GameHandler.java b/src/server/core/GameHandler.java index 62011e4..aad6d61 100644 --- a/src/server/core/GameHandler.java +++ b/src/server/core/GameHandler.java @@ -2,6 +2,7 @@ import com.google.gson.Gson; import com.google.gson.JsonParseException; +import server.core.model.ClientInfo; import server.core.model.Event; import server.network.ClientNetwork; import server.network.UINetwork; @@ -9,6 +10,8 @@ import java.io.File; import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; import java.util.concurrent.*; /** @@ -17,21 +20,26 @@ public class GameHandler { private static final String RESOURCE_PATH_OUTPUT_HANDLER = "/resources/game_handler/output_handler.conf"; - private static final int GAME_LOGIC_SIMULATE_TIMEOUT = 500; + private static long GAME_LOGIC_SIMULATE_TIMEOUT; + private static long CLIENT_LISTENING_TIMEOUT; - private ClientNetwork clientNetwork; + private ClientNetwork mClientNetwork; private UINetwork mUINetwork; private GameLogic mGameLogic; private OutputController mOutputController; + private ClientInfo[] mClientsInfo; private Loop mLoop; private ArrayList mEventsQueue; - public GameHandler(ClientNetwork clientNetwork, UINetwork uiNetwork, GameLogic gameLogic) { - this.mGameLogic = gameLogic; + public GameHandler(ClientNetwork clientNetwork, UINetwork uiNetwork) { + mClientNetwork = clientNetwork; + mUINetwork = uiNetwork; } - public void init() { + public void init(long simulateTimeout, long clientTimeout) { + GAME_LOGIC_SIMULATE_TIMEOUT = simulateTimeout; + CLIENT_LISTENING_TIMEOUT = clientTimeout; OutputHandlerConfig outputHandlerConfig; File file = new File(RESOURCE_PATH_OUTPUT_HANDLER); Gson gson = new Gson(); @@ -46,10 +54,26 @@ public void init() { outputHandlerConfig.sendToFile, outputHandlerConfig.getFile(), outputHandlerConfig.bufferSize); + } + + public void setGameLogic(GameLogic gameLogic) { + mGameLogic = gameLogic; + } + + public ClientNetwork getClientNetwork() { + return mClientNetwork; + } + public UINetwork getUINetwork() { + return mUINetwork; + } + + public void setClientsInfo(ClientInfo[] clientsInfo) { + mClientsInfo = clientsInfo; } public void start() { + mLoop = new Loop(); new Thread(mLoop).start(); new Thread(mOutputController).start(); } @@ -66,20 +90,51 @@ private class Loop implements Runnable { @Override public void run() { - Callable simulate = new Callable() { + Event[] environmentEvents; + Event[] terminalEvents; + Event[][] clientEvents; + + environmentEvents = mGameLogic.makeEnvironmentEvents(); + //FIXME: null, and mClientNetwork + mClientNetwork.startReceivingAll(); + try { + wait(CLIENT_LISTENING_TIMEOUT); + } catch (InterruptedException e) { + throw new RuntimeException("Waiting for clients interrupted"); + } + + clientEvents = new Event[mClientsInfo.length][]; + for (int i = 0; i < mClientsInfo.length; ++i) { + if (mClientNetwork.getReceivedEvent(i) != null) { + clientEvents[i] = mClientNetwork.getReceivedEvent(i); + } + } + + terminalEvents = null; + mGameLogic.makeEnvironmentEvents(); + Callable simulate = new Callable() { @Override - public Message[] call() throws Exception { - messages = mGameLogic.simulateEvents((Event[]) mEventsQueue.toArray()); - return messages = mGameLogic.setViews(messages); + public Void call() throws Exception { + mGameLogic.simulateEvents(terminalEvents, environmentEvents, clientEvents); + mGameLogic.generateOutputs(); + + mOutputController.putMessage(mGameLogic.getUIMessage()); + + Message[] output = mGameLogic.getClientMessages(); + for (int i = 0 ; i < output.length; ++i) { + mClientNetwork.queue(i, output[i]); + } + + return null; } }; - RunnableFuture runnableSimulate = new FutureTask(simulate); + RunnableFuture runnableSimulate = new FutureTask(simulate); ExecutorService service = Executors.newSingleThreadExecutor(); while (!shutdownRequest) { service.execute(runnableSimulate); try { - messages = runnableSimulate.get(GAME_LOGIC_SIMULATE_TIMEOUT, TimeUnit.MILLISECONDS); + runnableSimulate.get(GAME_LOGIC_SIMULATE_TIMEOUT, TimeUnit.MILLISECONDS); } catch (ExecutionException execution) { throw new RuntimeException("GameLogic execution encountered exception"); } catch (TimeoutException timeOut) { @@ -87,10 +142,6 @@ public Message[] call() throws Exception { } catch (InterruptedException interrupted) { throw new RuntimeException("GameLogic execution interrupted"); } - - for (Message message : messages) { - mOutputController.putMessage(message); - } } service.shutdown(); } diff --git a/src/server/core/GameLogic.java b/src/server/core/GameLogic.java index ba4bafa..163c347 100644 --- a/src/server/core/GameLogic.java +++ b/src/server/core/GameLogic.java @@ -1,11 +1,14 @@ package server.core; +import server.core.model.ClientInfo; import server.core.model.Event; import server.network.data.Message; import java.util.HashMap; import java.util.UUID; +import java.util.HashMap; + /** * The abstract class representing the main game logic of the user's game. *

@@ -14,12 +17,31 @@ */ public interface GameLogic { + //TODO: Saeed Rajab, change these... common baby... /** * This method must send initial and necessary values to UI and clients. * @return A hashmap that has Token as key and a Message as value. * Token is used for specifying if the Message is for UI or Client. */ - public HashMap init(); + public void init(); + + /** + * + * @return + */ + public Message getUIInitialMessage(); + + /** + * + * @return + */ + public Message[] getClientInitialMessages(); + + /** + * + * @return + */ + public ClientInfo[] getClientInfo(); /** * Simulate events based on the current turn event and calculate the changes in game. @@ -28,7 +50,7 @@ public interface GameLogic { * Increasing/Decreasing a specific resource in map is an environment event. * @param clientsEvent Events that is related to client e.g. moving the player. */ - public void simulateEvents(Event[] terminalEvent, Event[] environmentEvent, HashMap clientsEvent); + public void simulateEvents(Event[] terminalEvent, Event[] environmentEvent, Event[][] clientsEvent); /** * This method generates the output based on the changes that were calculated in @@ -36,7 +58,11 @@ public interface GameLogic { * @return A hashmap that has Token as key and a Message as value. * Token is used for specifying if the Message is for UI or Client. */ - public HashMap generateOutputs(); + public void generateOutputs(); + + public Message getUIMessage(); + + public Message[] getClientMessages(); /** * This method is used for making the environment events. diff --git a/src/server/core/model/ClientInfo.java b/src/server/core/model/ClientInfo.java new file mode 100644 index 0000000..cb0ea09 --- /dev/null +++ b/src/server/core/model/ClientInfo.java @@ -0,0 +1,21 @@ +package server.core.model; + +import java.util.UUID; + +/** + * Created by alilotfi on 2/2/15. + */ +public class ClientInfo { + + private String mToken; + private String mName; + private int mID; + + public void setID(int ID) { + mID = ID; + } + + public String getToken() { + return mToken; + } +} diff --git a/src/server/network/ClientNetwork.java b/src/server/network/ClientNetwork.java index 2ea5c16..f33e121 100644 --- a/src/server/network/ClientNetwork.java +++ b/src/server/network/ClientNetwork.java @@ -1,6 +1,7 @@ package server.network; import com.google.gson.Gson; +import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import server.core.model.Event; @@ -217,16 +218,18 @@ public Message getReceivedMessage(int clientID) { * @return last valid event or null if there is no valid event * @see {@link #getReceivedMessage} */ - public Event getReceivedEvent(int clientID) { + public Event[] getReceivedEvent(int clientID) { Message msg = getReceivedMessage(clientID); - Event event = null; - // convert argument 0 of the message to an object of type Event - if (msg != null && msg.args != null && - msg.args.length > 0 && msg.args[0] instanceof JsonElement) { - JsonElement arg0 = (JsonElement) msg.args[0]; - event = gson.fromJson(arg0, Event.class); + Event[] events = null; + try { + JsonArray eventArray = ((JsonElement)msg.args[0]).getAsJsonArray(); + events = new Event[eventArray.size()]; + for (int i = 0; i < events.length; i++) + events[i] = gson.fromJson(eventArray.get(i), Event.class); + } catch (Exception e) { + Log.i(TAG, "Error getting received messages.", e); } - return event; + return events; } @Override From 1e6d400008b20c01f9630f5f61697bd214108c95 Mon Sep 17 00:00:00 2001 From: alilotfi Date: Mon, 2 Feb 2015 21:33:34 +0330 Subject: [PATCH 24/40] Server and GameHandler Revised --- JGFramework.iml | 13 +-- resources/game_handler/output_handler.conf | 4 +- resources/game_handler/turn_timeout.conf | 4 + resources/network/client.conf | 3 + resources/network/ui.conf | 3 +- src/server/Server.java | 115 ++++++++++++++++----- src/server/core/GameHandler.java | 106 +++++++++++++------ 7 files changed, 176 insertions(+), 72 deletions(-) create mode 100644 resources/game_handler/turn_timeout.conf create mode 100644 resources/network/client.conf diff --git a/JGFramework.iml b/JGFramework.iml index 02db710..6f10785 100644 --- a/JGFramework.iml +++ b/JGFramework.iml @@ -1,6 +1,6 @@ - + @@ -8,16 +8,5 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/resources/game_handler/output_handler.conf b/resources/game_handler/output_handler.conf index 05bf6bd..a9be674 100644 --- a/resources/game_handler/output_handler.conf +++ b/resources/game_handler/output_handler.conf @@ -1,7 +1,7 @@ { "sendToUI" : true, - "timeInterval" : 100, + "timeInterval" : 500, "sendToFile" : true, "filePath" : "/log.log", - "bufferSize" : 10 + "bufferSize" : 100 } \ No newline at end of file diff --git a/resources/game_handler/turn_timeout.conf b/resources/game_handler/turn_timeout.conf new file mode 100644 index 0000000..a80c324 --- /dev/null +++ b/resources/game_handler/turn_timeout.conf @@ -0,0 +1,4 @@ +{ + "clientResponseTime" : 500, + "simulateTimeout" : 10000 +} \ No newline at end of file diff --git a/resources/network/client.conf b/resources/network/client.conf new file mode 100644 index 0000000..2259cad --- /dev/null +++ b/resources/network/client.conf @@ -0,0 +1,3 @@ +{ + "port" : 3002 +} \ No newline at end of file diff --git a/resources/network/ui.conf b/resources/network/ui.conf index b96e2a8..7a7ef62 100644 --- a/resources/network/ui.conf +++ b/resources/network/ui.conf @@ -1,3 +1,4 @@ { - "token" : "abcdefghijklmnopqrstuvwxyz012345" + "token" : "abcdefghijklmnopqrstuvwxyz012346", + "port" : 3000 } \ No newline at end of file diff --git a/src/server/Server.java b/src/server/Server.java index 3cef92d..377261f 100644 --- a/src/server/Server.java +++ b/src/server/Server.java @@ -13,7 +13,6 @@ import server.network.data.Message; import java.io.File; -import java.util.HashMap; /** * Class is the main Server of the game with networks and game logic within. @@ -32,12 +31,14 @@ public class Server { private static final String RESOURCE_PATH_TERMINAL = "/resources/network/terminal.conf"; private static final String RESOURCE_PATH_UI = "/resources/network/ui.conf"; + private static final String RESOURCE_PATH_CLIENT = "/resources/network/client.conf"; private Factory mFactory; private TerminalNetwork mTerminalNetwork; private GameHandler mGameHandler; - private CommandHandler mCommandHandler; TerminalConfig mTerminalConfig; + private UIConfig mUIConfig; + private ClientConfig mClientConfig; ClientInfo[] mClientsInfo; @@ -57,8 +58,9 @@ public class Server { public Server(Factory factory) { mFactory = factory; - File file = new File(RESOURCE_PATH_TERMINAL); Gson gson = new Gson(); + + File file = new File(RESOURCE_PATH_TERMINAL); try { mTerminalConfig = gson.fromJson(file.toString(), TerminalConfig.class); } catch (JsonParseException e) { @@ -67,35 +69,52 @@ public Server(Factory factory) { mTerminalNetwork = new TerminalNetwork(mTerminalConfig.getTerminalToken()); file = new File(RESOURCE_PATH_UI); - UIConfig uiConfig = gson.fromJson(file.toString(), UIConfig.class); - mGameHandler = new GameHandler(new ClientNetwork(), new UINetwork(uiConfig.getUIToken())); + mUIConfig = gson.fromJson(file.toString(), UIConfig.class); + mGameHandler = new GameHandler(new ClientNetwork(), new UINetwork(mUIConfig.getUIToken())); + mGameHandler.init(); + + file = new File(RESOURCE_PATH_CLIENT); + mClientConfig = gson.fromJson(file.toString(), ClientConfig.class); - mCommandHandler = new CommandHandler(); + setCommandHandler(new CommandHandler()); } public void setCommandHandler(CommandHandler commandHandler) { - mCommandHandler = commandHandler; + mTerminalNetwork.setHandler(commandHandler); + } + + /** + * Starts the server by make it listening and responding to the Terminal. + */ + public void start() { + mTerminalNetwork.listen(mTerminalConfig.getTerminalPort()); } - private void newGame(String[] options, long timeout) { + private void newGame(String[] options, long uiTimeout, long clientTimeout) { GameLogic gameLogic = mFactory.getGameLogic(options); gameLogic.init(); + mGameHandler.setGameLogic(gameLogic); mClientsInfo = gameLogic.getClientInfo(); mGameHandler.setClientsInfo(mClientsInfo); - mGameHandler.setGameLogic(gameLogic); - for (ClientInfo c : mClientsInfo) { - int id = mGameHandler.getClientNetwork().defineClient(c.getToken()); - c.setID(id); + for (int i = 0 ; i < mClientsInfo.length; ++i) { + int id = mGameHandler.getClientNetwork().defineClient(mClientsInfo[i].getToken()); + if (id != i) { + throw new RuntimeException("Client ID and client order does not match"); + } + mClientsInfo[i].setID(id); } + mGameHandler.getUINetwork().listen(mUIConfig.getUIPort()); + mGameHandler.getClientNetwork().listen(mClientConfig.getClientPort()); + try { - mGameHandler.getUINetwork().waitForClient(); + mGameHandler.getUINetwork().waitForClient(uiTimeout); } catch (InterruptedException e) { throw new RuntimeException("Waiting for ui clients interrupted"); } try { - mGameHandler.getClientNetwork().waitForAllClients(timeout); + mGameHandler.getClientNetwork().waitForAllClients(clientTimeout); } catch (InterruptedException e) { throw new RuntimeException("Waiting for clients interrupted"); } @@ -107,17 +126,9 @@ private void newGame(String[] options, long timeout) { for (int i = 0; i @@ -127,10 +138,15 @@ public void start() { * and the port is the port to connect to the {@link server.network.TerminalNetwork TerminalNetwork}. *

*/ - private class TerminalConfig { + private static class TerminalConfig { private String token; private int port; + public TerminalConfig(String token, int port) { + this.token = token; + this.port = port; + } + /** * Getter for the terminal token. *

@@ -159,7 +175,7 @@ public int getTerminalPort() { if (port > 0 && port <= 65535) { return port; } else { - throw new RuntimeException("Invalid port number in config file"); + throw new RuntimeException("Invalid terminal port number in config file"); } } } @@ -167,8 +183,14 @@ public int getTerminalPort() { /** * */ - private class UIConfig { + private static class UIConfig { private String token; + private int port; + + public UIConfig(String token, int port) { + this.token = token; + this.port = port; + } /** * Getter for the user interface token. @@ -185,5 +207,48 @@ public String getUIToken() { } throw new RuntimeException("Invalid UI token in config file"); } + + /** + * Getter for the ui port. + *

+ * This method checks the port for a valid number and returns it as an integer. + * In the case of an invalid port number (out of range numbers), raises a runtime exception. + *

+ * @return Integer port number + */ + public int getUIPort() { + if (port > 0 && port <= 65535) { + return port; + } else { + throw new RuntimeException("Invalid ui port number in config file"); + } + } + } + + /** + * + */ + private static class ClientConfig { + private int port; + + public ClientConfig(int port) { + this.port = port; + } + + /** + * Getter for the client server port. + *

+ * This method checks the port for a valid number and returns it as an integer. + * In the case of an invalid port number (out of range numbers), raises a runtime exception. + *

+ * @return Integer port number + */ + public int getClientPort() { + if (port > 0 && port <= 65535) { + return port; + } else { + throw new RuntimeException("Invalid ui port number in config file"); + } + } } } diff --git a/src/server/core/GameHandler.java b/src/server/core/GameHandler.java index aad6d61..c664b6d 100644 --- a/src/server/core/GameHandler.java +++ b/src/server/core/GameHandler.java @@ -10,18 +10,17 @@ import java.io.File; import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; import java.util.concurrent.*; /** - * Created by Razi on 12/6/2014. + * Created in order to... */ public class GameHandler { private static final String RESOURCE_PATH_OUTPUT_HANDLER = "/resources/game_handler/output_handler.conf"; - private static long GAME_LOGIC_SIMULATE_TIMEOUT; - private static long CLIENT_LISTENING_TIMEOUT; + private static final String RESOURCE_PATH_TURN_TIMEOUT = "/resources/game_handler/output_handler.conf"; + private final long GAME_LOGIC_SIMULATE_TIMEOUT; + private final long CLIENT_RESPONSE_TIME; private ClientNetwork mClientNetwork; private UINetwork mUINetwork; @@ -35,11 +34,19 @@ public class GameHandler { public GameHandler(ClientNetwork clientNetwork, UINetwork uiNetwork) { mClientNetwork = clientNetwork; mUINetwork = uiNetwork; + + Gson gson = new Gson(); + File file = new File(RESOURCE_PATH_TURN_TIMEOUT); + try { + TimeConfig timeConfig = gson.fromJson(file.toString(), TimeConfig.class); + GAME_LOGIC_SIMULATE_TIMEOUT = timeConfig.getClientResponseTime(); + CLIENT_RESPONSE_TIME = timeConfig.getUIResponseTime(); + } catch (JsonParseException e) { + throw new RuntimeException("Turn time config file does not meet expected syntax"); + } } - public void init(long simulateTimeout, long clientTimeout) { - GAME_LOGIC_SIMULATE_TIMEOUT = simulateTimeout; - CLIENT_LISTENING_TIMEOUT = clientTimeout; + public void init() { OutputHandlerConfig outputHandlerConfig; File file = new File(RESOURCE_PATH_OUTPUT_HANDLER); Gson gson = new Gson(); @@ -48,7 +55,7 @@ public void init(long simulateTimeout, long clientTimeout) { } catch (JsonParseException e) { throw new RuntimeException("Output handler config file does not meet expected syntax"); } - mOutputController = new OutputController(outputHandlerConfig.sendToUI , + mOutputController = new OutputController(outputHandlerConfig.sendToUI, mUINetwork, outputHandlerConfig.timeInterval, outputHandlerConfig.sendToFile, @@ -86,35 +93,18 @@ public void shutdown() { private class Loop implements Runnable { private boolean shutdownRequest = false; - private Message[] messages; + + private Event[] environmentEvents; + private Event[] terminalEvents; + private Event[][] clientEvents; @Override public void run() { - Event[] environmentEvents; - Event[] terminalEvents; - Event[][] clientEvents; - - environmentEvents = mGameLogic.makeEnvironmentEvents(); - //FIXME: null, and mClientNetwork - mClientNetwork.startReceivingAll(); - try { - wait(CLIENT_LISTENING_TIMEOUT); - } catch (InterruptedException e) { - throw new RuntimeException("Waiting for clients interrupted"); - } - - clientEvents = new Event[mClientsInfo.length][]; - for (int i = 0; i < mClientsInfo.length; ++i) { - if (mClientNetwork.getReceivedEvent(i) != null) { - clientEvents[i] = mClientNetwork.getReceivedEvent(i); - } - } - - terminalEvents = null; - mGameLogic.makeEnvironmentEvents(); Callable simulate = new Callable() { + @Override public Void call() throws Exception { + mGameLogic.simulateEvents(terminalEvents, environmentEvents, clientEvents); mGameLogic.generateOutputs(); @@ -124,6 +114,29 @@ public Void call() throws Exception { for (int i = 0 ; i < output.length; ++i) { mClientNetwork.queue(i, output[i]); } + mClientNetwork.sendAllBlocking(); + + mClientNetwork.startReceivingAll(); + long elapsedTime = System.currentTimeMillis(); + environmentEvents = mGameLogic.makeEnvironmentEvents(); + elapsedTime = System.currentTimeMillis() - elapsedTime; + if (CLIENT_RESPONSE_TIME - elapsedTime > 0) { + try { + wait(CLIENT_RESPONSE_TIME - elapsedTime); + } catch (InterruptedException e) { + throw new RuntimeException("Waiting for clients interrupted"); + } + } + mClientNetwork.stopReceivingAll(); + + clientEvents = new Event[mClientsInfo.length][]; + for (int i = 0; i < mClientsInfo.length; ++i) { + if (mClientNetwork.getReceivedEvent(i) != null) { + clientEvents[i] = mClientNetwork.getReceivedEvent(i); + } + } + //FIXME: Put a blocking queue for terminal + terminalEvents = null; return null; } @@ -162,4 +175,33 @@ private File getFile() { return new File(filePath); } } + + /** + * + */ + private static class TimeConfig { + private long mClientResponseTime; + private long mSimulateTimeout; + + public TimeConfig(long clientResponseTime,long uiResponseTime) { + mClientResponseTime = clientResponseTime; + mSimulateTimeout = uiResponseTime; + } + + /** + * + * @return + */ + public long getClientResponseTime() { + return mClientResponseTime; + } + + /** + * + * @return + */ + public long getUIResponseTime() { + return mSimulateTimeout; + } + } } From ea3c7e2a2fa45c6ea6c4749902bbc4ff703230f5 Mon Sep 17 00:00:00 2001 From: Ali Lotfi Date: Tue, 3 Feb 2015 04:12:44 -0800 Subject: [PATCH 25/40] GameHandler shutdown revised --- src/server/core/GameHandler.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/server/core/GameHandler.java b/src/server/core/GameHandler.java index c664b6d..5eb72b2 100644 --- a/src/server/core/GameHandler.java +++ b/src/server/core/GameHandler.java @@ -107,7 +107,10 @@ public Void call() throws Exception { mGameLogic.simulateEvents(terminalEvents, environmentEvents, clientEvents); mGameLogic.generateOutputs(); - + if (mGameLogic.isGameFinished()) { + shutdown(); + } + mOutputController.putMessage(mGameLogic.getUIMessage()); Message[] output = mGameLogic.getClientMessages(); @@ -115,7 +118,7 @@ public Void call() throws Exception { mClientNetwork.queue(i, output[i]); } mClientNetwork.sendAllBlocking(); - + mClientNetwork.startReceivingAll(); long elapsedTime = System.currentTimeMillis(); environmentEvents = mGameLogic.makeEnvironmentEvents(); From 591cb6f6127103035a835ce00d45edd9c8ca3d2a Mon Sep 17 00:00:00 2001 From: Ali Lotfi Date: Tue, 3 Feb 2015 04:14:39 -0800 Subject: [PATCH 26/40] GameHandler shutdown revised --- src/server/core/GameLogic.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/server/core/GameLogic.java b/src/server/core/GameLogic.java index 163c347..23689a3 100644 --- a/src/server/core/GameLogic.java +++ b/src/server/core/GameLogic.java @@ -69,5 +69,6 @@ public interface GameLogic { * @return An array that is environment events. */ public Event[] makeEnvironmentEvents(); - + + public boolean isGameFinished(); } From de30e868c7ecca5be8b941d0d5748374121ba6ed Mon Sep 17 00:00:00 2001 From: rajabzz Date: Wed, 4 Feb 2015 11:21:07 +0330 Subject: [PATCH 27/40] Sending external commands. --- Terminal/src/Terminal.java | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/Terminal/src/Terminal.java b/Terminal/src/Terminal.java index 238f476..27a0d5c 100644 --- a/Terminal/src/Terminal.java +++ b/Terminal/src/Terminal.java @@ -1,4 +1,5 @@ import server.network.JsonSocket; +import server.network.data.Command; import java.io.BufferedReader; import java.io.FileReader; @@ -74,9 +75,7 @@ public void handleCommand(String cmd) { case CMD_TYPE_CONNECT: try { handleConnectCmd(); - } catch (IOException e) { - e.printStackTrace(); - } catch (NoSuchAlgorithmException e) { + } catch (IOException | NoSuchAlgorithmException e) { e.printStackTrace(); } break; @@ -106,7 +105,16 @@ public void handleCommand(String cmd) { break; default: - //TODO it's an external command ... + Command externalCommand = new Command(); + externalCommand.cmdType = cmdType; + command.remove(0); + externalCommand.args = command.toArray(new String[command.size()]); + + try { + jsonSocket.send(externalCommand); + } catch (IOException e) { + e.printStackTrace(); + } } } From bf68de43f808a890f899e85618708908f4d0ae3e Mon Sep 17 00:00:00 2001 From: Semora Date: Wed, 4 Feb 2015 12:28:32 +0330 Subject: [PATCH 28/40] Make new branch and json file for terminal app --- JGFramework.iml | 3 +++ Terminal/Resources/ip-port.conf | 1 + libs/junit-4.12.jar | Bin 0 -> 314932 bytes 3 files changed, 4 insertions(+) create mode 100644 Terminal/Resources/ip-port.conf create mode 100644 libs/junit-4.12.jar diff --git a/JGFramework.iml b/JGFramework.iml index 6f10785..41d2e5e 100644 --- a/JGFramework.iml +++ b/JGFramework.iml @@ -4,9 +4,12 @@ + + + \ No newline at end of file diff --git a/Terminal/Resources/ip-port.conf b/Terminal/Resources/ip-port.conf new file mode 100644 index 0000000..d3ee843 --- /dev/null +++ b/Terminal/Resources/ip-port.conf @@ -0,0 +1 @@ +{"ip":"127.0.0.1","port":5000} \ No newline at end of file diff --git a/libs/junit-4.12.jar b/libs/junit-4.12.jar new file mode 100644 index 0000000000000000000000000000000000000000..3a7fc266c3e32283a2b21fe12166ebdcc33a1da1 GIT binary patch literal 314932 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

&R7;REBZd0NaNVcN6Eoy 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

?@Ib4$R$ZbA6MIsF(ZEk4Ii=sfRBa)&Yo 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�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 TY(h;@!?}i$7z!3V8^-w`q)kqw literal 0 HcmV?d00001 From 7a9047255bf9d8b54307b77a81e908813c61044e Mon Sep 17 00:00:00 2001 From: Semora Date: Wed, 4 Feb 2015 12:41:04 +0330 Subject: [PATCH 29/40] fix json file for terminal app --- Terminal/Resources/ip-port.conf | 2 +- Terminal/Resources/ip-port.txt | 2 - Terminal/src/Terminal.java | 78 ++++++++++++++++----------- resources/network/ui.conf | 2 +- src/server/core/OutputController.java | 6 +-- 5 files changed, 53 insertions(+), 37 deletions(-) delete mode 100644 Terminal/Resources/ip-port.txt diff --git a/Terminal/Resources/ip-port.conf b/Terminal/Resources/ip-port.conf index d3ee843..7f460c0 100644 --- a/Terminal/Resources/ip-port.conf +++ b/Terminal/Resources/ip-port.conf @@ -1 +1 @@ -{"ip":"127.0.0.1","port":5000} \ No newline at end of file +{"ip":"127.0.0.1","port":3001} \ No newline at end of file diff --git a/Terminal/Resources/ip-port.txt b/Terminal/Resources/ip-port.txt deleted file mode 100644 index f5ea46c..0000000 --- a/Terminal/Resources/ip-port.txt +++ /dev/null @@ -1,2 +0,0 @@ -192.168.1.1 -5050 diff --git a/Terminal/src/Terminal.java b/Terminal/src/Terminal.java index 27a0d5c..fde03a6 100644 --- a/Terminal/src/Terminal.java +++ b/Terminal/src/Terminal.java @@ -1,10 +1,8 @@ +import com.google.gson.Gson; +import com.google.gson.JsonParseException; import server.network.JsonSocket; -import server.network.data.Command; -import java.io.BufferedReader; -import java.io.FileReader; -import java.io.IOException; -import java.io.PrintWriter; +import java.io.*; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; @@ -15,7 +13,7 @@ * Created by Saeed on 1/23/2015. */ public class Terminal { - private static final String FILE_PATH = "../JGFramework/Terminal/Resources/ip-port.txt"; + private static final String FILE_PATH = "../JGFramework/Terminal/Resources/ip-port.conf"; private static final String CMD_TYPE_CONNECT = "connect"; private static final String CMD_TYPE_DISCONNECT = "disconnect"; @@ -43,23 +41,27 @@ public static Terminal getInstance() { } public void writeIpAndPortToFile(String ip, int port) throws IOException { - PrintWriter pw = new PrintWriter(FILE_PATH); - pw.println(ip); - pw.println(port); - pw.close(); + Gson gson = new Gson(); + String json = gson.toJson(new TerminalAppConfig(ip,port)); + FileWriter writer = new FileWriter(FILE_PATH); + writer.write(json); + writer.close(); + } public void setIpAndPortFromFile() throws IOException { - BufferedReader bf = new BufferedReader(new FileReader(FILE_PATH)); - String ip; - String port; - if ((ip = bf.readLine()) != null) - this.ip = ip; - if ((port = bf.readLine()) != null) - this.port = Integer.parseInt(port); - bf.close(); + Gson gson = new Gson(); + + try { + BufferedReader br = new BufferedReader( new FileReader(FILE_PATH)); + TerminalAppConfig terminalAppConfig= gson.fromJson(br, TerminalAppConfig.class); + this.port = terminalAppConfig.getPort(); + this.ip = terminalAppConfig.getIp(); + } catch (JsonParseException e) { + throw new RuntimeException("Terminal App config file does not meet expected syntax"); + } } public void handleCommand(String cmd) { @@ -75,7 +77,9 @@ public void handleCommand(String cmd) { case CMD_TYPE_CONNECT: try { handleConnectCmd(); - } catch (IOException | NoSuchAlgorithmException e) { + } catch (IOException e) { + e.printStackTrace(); + } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } break; @@ -105,16 +109,7 @@ public void handleCommand(String cmd) { break; default: - Command externalCommand = new Command(); - externalCommand.cmdType = cmdType; - command.remove(0); - externalCommand.args = command.toArray(new String[command.size()]); - - try { - jsonSocket.send(externalCommand); - } catch (IOException e) { - e.printStackTrace(); - } + //TODO it's an external command ... } } @@ -181,4 +176,27 @@ private void handleSetPortCmd(ArrayList command) throws IOException { System.out.println("Port changed successfully."); } -} + + private static class TerminalAppConfig { + private String ip; + private int port; + + public TerminalAppConfig(String ip, int port) { + this.ip = ip; + this.port = port; + } + + public String getIp() { + return ip; + } + + public int getPort() { + if (port > 0 && port <= 65535) { + return port; + } else { + throw new RuntimeException("Invalid ui port number in config file"); + } + } + } + +} \ No newline at end of file diff --git a/resources/network/ui.conf b/resources/network/ui.conf index 7a7ef62..5198add 100644 --- a/resources/network/ui.conf +++ b/resources/network/ui.conf @@ -1,4 +1,4 @@ { "token" : "abcdefghijklmnopqrstuvwxyz012346", - "port" : 3000 + "port" : 7000 } \ No newline at end of file diff --git a/src/server/core/OutputController.java b/src/server/core/OutputController.java index 391c818..cefd761 100644 --- a/src/server/core/OutputController.java +++ b/src/server/core/OutputController.java @@ -282,7 +282,7 @@ public void close() { * {@link server.network.UINetwork UINetwork}. *

* As the failure in connection and some other issues leaves the - * {@link server.network.UINetwork#send(server.network.data.Message) UINetwork.send(Message)} method + * {@link server.network.UINetwork#sendBlocking(server.network.data.Message) UINetwork.send(Message)} method * blocked, and so causes a thread block, this class runs as an alternative thread to send the messages * in the queue, to the {@link server.network.UINetwork UINetwrok} instance without causing the main * thread of OutputController to sleep. @@ -329,7 +329,7 @@ public void run() { /** * This method serves the instance of {@link server.network.UINetwork UINetwork} class with messages. *

- * This method calls {@link server.network.UINetwork#send(server.network.data.Message) send(message)} + * This method calls {@link server.network.UINetwork#sendBlocking(server.network.data.Message) send(message)} * method on {@link server.network.UINetwork UINetwork} instance in order to show up on UI. * Calling this while the message queue is empty, will put it in the wait mode. * Basically this method will be called by the timer scheduled according to user preferred @@ -342,7 +342,7 @@ private void sendToUINetwork(Message message) { Callable run = new Callable() { @Override public Void call() throws Exception { - uiNetwork.send(message); + uiNetwork.sendBlocking(message); return null; } }; From 101db2b6eef6dba13621a66fd46420b7fee7d40b Mon Sep 17 00:00:00 2001 From: alilotfi Date: Wed, 4 Feb 2015 14:24:56 +0330 Subject: [PATCH 30/40] Gson parsing revised Doc is nearly completed --- src/server/Server.java | 37 ++++++++++++++++++----- src/server/core/GameHandler.java | 43 +++++++++++++++++++++++---- src/server/core/GameLogic.java | 1 + src/server/core/OutputController.java | 6 ++-- src/server/core/model/ClientInfo.java | 24 +++++++++++++-- 5 files changed, 93 insertions(+), 18 deletions(-) diff --git a/src/server/Server.java b/src/server/Server.java index 377261f..726f14a 100644 --- a/src/server/Server.java +++ b/src/server/Server.java @@ -12,7 +12,10 @@ import server.network.UINetwork; import server.network.data.Message; +import java.io.BufferedReader; import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; /** * Class is the main Server of the game with networks and game logic within. @@ -60,21 +63,41 @@ public Server(Factory factory) { Gson gson = new Gson(); - File file = new File(RESOURCE_PATH_TERMINAL); + File file; + BufferedReader bufferedReader; + try { - mTerminalConfig = gson.fromJson(file.toString(), TerminalConfig.class); - } catch (JsonParseException e) { + file = new File(RESOURCE_PATH_TERMINAL); + bufferedReader = new BufferedReader(new FileReader(file)); + mTerminalConfig = gson.fromJson(bufferedReader, TerminalConfig.class); + } catch (FileNotFoundException notFound) { + throw new RuntimeException("Terminal config file not found"); + } catch (JsonParseException parse) { throw new RuntimeException("Terminal config file does not meet expected syntax"); } mTerminalNetwork = new TerminalNetwork(mTerminalConfig.getTerminalToken()); - file = new File(RESOURCE_PATH_UI); - mUIConfig = gson.fromJson(file.toString(), UIConfig.class); + try { + file = new File(RESOURCE_PATH_UI); + bufferedReader = new BufferedReader(new FileReader(file)); + mUIConfig = gson.fromJson(bufferedReader, UIConfig.class); + } catch (FileNotFoundException notFound) { + throw new RuntimeException("UI config file not found"); + } catch (JsonParseException parse) { + throw new RuntimeException("UI config file does not meet the expected syntax"); + } mGameHandler = new GameHandler(new ClientNetwork(), new UINetwork(mUIConfig.getUIToken())); mGameHandler.init(); - file = new File(RESOURCE_PATH_CLIENT); - mClientConfig = gson.fromJson(file.toString(), ClientConfig.class); + try { + file = new File(RESOURCE_PATH_CLIENT); + bufferedReader = new BufferedReader(new FileReader(file)); + mClientConfig = gson.fromJson(bufferedReader, ClientConfig.class); + } catch (FileNotFoundException notFound) { + throw new RuntimeException("Client config file not found"); + } catch (JsonParseException parse) { + throw new RuntimeException("Client config file does not meet the expected syntax"); + } setCommandHandler(new CommandHandler()); } diff --git a/src/server/core/GameHandler.java b/src/server/core/GameHandler.java index c664b6d..fdc1dd3 100644 --- a/src/server/core/GameHandler.java +++ b/src/server/core/GameHandler.java @@ -8,12 +8,33 @@ import server.network.UINetwork; import server.network.data.Message; +import java.io.BufferedReader; import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; import java.util.ArrayList; import java.util.concurrent.*; /** - * Created in order to... + * Core controller of the framework, controls the {@link server.core.GameLogic GameLogic}, main loop of the game and + * does the output controlling operations. + *

+ * This class runs the main running thread of the framework. Class interacts with the clients, UI, and the + * GameLogic itself. + * Threads in this class, will gather the clients' events + * (See also {@link server.network.ClientNetwork ClientNetwork}), send them to the main Game + * (See also {@link server.core.GameLogic GameLogic}) + * The output will be manipulated and sent to the appropriate controller within a inner module of the class + * (OutputController). + * The sequence of the creation and running the operations of this class will be through the call of the following + * methods. + * {@link server.core.GameHandler#init() init()}, {@link server.core.GameHandler#start() start()} and then at the + * moment the external terminal user wants to shut down the games loop (except than waiting for the + * {@link server.core.GameLogic GameLogic} to flag the end of the game), the + * {@link server.core.GameHandler#shutdown() shutdown()} method would be called. + * Note that shutting down the {@link server.core.GameHandler GameHandler} will not immedietlly stop the threads, + * actually it will set a shut down request flag in the class, which will + *

*/ public class GameHandler { @@ -36,22 +57,28 @@ public GameHandler(ClientNetwork clientNetwork, UINetwork uiNetwork) { mUINetwork = uiNetwork; Gson gson = new Gson(); - File file = new File(RESOURCE_PATH_TURN_TIMEOUT); try { + File file = new File(RESOURCE_PATH_TURN_TIMEOUT); + BufferedReader bufferedReader = new BufferedReader(new FileReader(file)); TimeConfig timeConfig = gson.fromJson(file.toString(), TimeConfig.class); GAME_LOGIC_SIMULATE_TIMEOUT = timeConfig.getClientResponseTime(); CLIENT_RESPONSE_TIME = timeConfig.getUIResponseTime(); + } catch (FileNotFoundException notFound) { + throw new RuntimeException("turn_timeout config file not found"); } catch (JsonParseException e) { - throw new RuntimeException("Turn time config file does not meet expected syntax"); + throw new RuntimeException("turn_time config file does not meet expected syntax"); } } public void init() { OutputHandlerConfig outputHandlerConfig; - File file = new File(RESOURCE_PATH_OUTPUT_HANDLER); Gson gson = new Gson(); try { - outputHandlerConfig = gson.fromJson(file.toString(), OutputHandlerConfig.class); + File file = new File(RESOURCE_PATH_OUTPUT_HANDLER); + BufferedReader bufferedReader = new BufferedReader(new FileReader(file)); + outputHandlerConfig = gson.fromJson(bufferedReader, OutputHandlerConfig.class); + } catch (FileNotFoundException notFound) { + throw new RuntimeException("Output handler config file not found"); } catch (JsonParseException e) { throw new RuntimeException("Output handler config file does not meet expected syntax"); } @@ -107,6 +134,10 @@ public Void call() throws Exception { mGameLogic.simulateEvents(terminalEvents, environmentEvents, clientEvents); mGameLogic.generateOutputs(); + if (mGameLogic.isGameFinished()) { + mLoop.shutdown(); + mOutputController.shutdown(); + } mOutputController.putMessage(mGameLogic.getUIMessage()); @@ -136,6 +167,8 @@ public Void call() throws Exception { } } //FIXME: Put a blocking queue for terminal + BlockingQueue terminalEventsQueue = new LinkedBlockingQueue<>(); + terminalEvents = null; return null; diff --git a/src/server/core/GameLogic.java b/src/server/core/GameLogic.java index 163c347..58ccab4 100644 --- a/src/server/core/GameLogic.java +++ b/src/server/core/GameLogic.java @@ -70,4 +70,5 @@ public interface GameLogic { */ public Event[] makeEnvironmentEvents(); + public boolean isGameFinished(); } diff --git a/src/server/core/OutputController.java b/src/server/core/OutputController.java index 391c818..cefd761 100644 --- a/src/server/core/OutputController.java +++ b/src/server/core/OutputController.java @@ -282,7 +282,7 @@ public void close() { * {@link server.network.UINetwork UINetwork}. *

* As the failure in connection and some other issues leaves the - * {@link server.network.UINetwork#send(server.network.data.Message) UINetwork.send(Message)} method + * {@link server.network.UINetwork#sendBlocking(server.network.data.Message) UINetwork.send(Message)} method * blocked, and so causes a thread block, this class runs as an alternative thread to send the messages * in the queue, to the {@link server.network.UINetwork UINetwrok} instance without causing the main * thread of OutputController to sleep. @@ -329,7 +329,7 @@ public void run() { /** * This method serves the instance of {@link server.network.UINetwork UINetwork} class with messages. *

- * This method calls {@link server.network.UINetwork#send(server.network.data.Message) send(message)} + * This method calls {@link server.network.UINetwork#sendBlocking(server.network.data.Message) send(message)} * method on {@link server.network.UINetwork UINetwork} instance in order to show up on UI. * Calling this while the message queue is empty, will put it in the wait mode. * Basically this method will be called by the timer scheduled according to user preferred @@ -342,7 +342,7 @@ private void sendToUINetwork(Message message) { Callable run = new Callable() { @Override public Void call() throws Exception { - uiNetwork.send(message); + uiNetwork.sendBlocking(message); return null; } }; diff --git a/src/server/core/model/ClientInfo.java b/src/server/core/model/ClientInfo.java index cb0ea09..b71024f 100644 --- a/src/server/core/model/ClientInfo.java +++ b/src/server/core/model/ClientInfo.java @@ -1,9 +1,12 @@ package server.core.model; -import java.util.UUID; - /** - * Created by alilotfi on 2/2/15. + * Is a template for information required for creation and assigned to a client of the game. + *

+ * Parts of this class members are required for creating and connecting a client to the + * {@link server.network.ClientNetwork ClientNetwork}, these parts have to be wrote down to the config file in + * "Resources" folder ({@see https://github.com/JavaChallenge/JGFramework/wiki wiki}). + *

*/ public class ClientInfo { @@ -11,10 +14,25 @@ public class ClientInfo { private String mName; private int mID; + /** + * Setter for the ID of the client. + *

+ * ID of every client would be generated inside the {@link server.network.ClientNetwork ClientNetwor} class. + * Then the assigned unique ID will be set to the client through this method. + *

+ * @param ID Assigned ID by the {@link server.network.ClientNetwork ClientNetwork} class. + */ public void setID(int ID) { mID = ID; } + /** + * Getter of the Token filed of the object. + *

+ * Returns the 32-character token assigned to the client (normally by user) as an String + *

+ * @return String token of the client + */ public String getToken() { return mToken; } From a5a874c4a4b01ba9489b8d3a1de91b2c07d6c24d Mon Sep 17 00:00:00 2001 From: alilotfi Date: Wed, 4 Feb 2015 14:31:39 +0330 Subject: [PATCH 31/40] Gson parsing revised Doc is nearly completed --- src/server/core/GameHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/core/GameHandler.java b/src/server/core/GameHandler.java index 8102a9d..d46990c 100644 --- a/src/server/core/GameHandler.java +++ b/src/server/core/GameHandler.java @@ -32,7 +32,7 @@ * moment the external terminal user wants to shut down the games loop (except than waiting for the * {@link server.core.GameLogic GameLogic} to flag the end of the game), the * {@link server.core.GameHandler#shutdown() shutdown()} method would be called. - * Note that shutting down the {@link server.core.GameHandler GameHandler} will not immedietlly stop the threads, + * Note that shutting down the {@link server.core.GameHandler GameHandler} will not immedietelly stop the threads, * actually it will set a shut down request flag in the class, which will *

*/ From 70f531b37c26083af6f40f614a7c87873cb0ab36 Mon Sep 17 00:00:00 2001 From: rajabzz Date: Wed, 4 Feb 2015 14:50:18 +0330 Subject: [PATCH 32/40] Sending external commands + json updates --- Terminal/src/Terminal.java | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/Terminal/src/Terminal.java b/Terminal/src/Terminal.java index fde03a6..4b51400 100644 --- a/Terminal/src/Terminal.java +++ b/Terminal/src/Terminal.java @@ -1,6 +1,7 @@ import com.google.gson.Gson; import com.google.gson.JsonParseException; import server.network.JsonSocket; +import server.network.data.Command; import java.io.*; import java.security.MessageDigest; @@ -109,7 +110,16 @@ public void handleCommand(String cmd) { break; default: - //TODO it's an external command ... + Command externalCommand = new Command(); + externalCommand.cmdType = cmdType; + command.remove(0); + externalCommand.args = command.toArray(new String[command.size()]); + + try { + jsonSocket.send(externalCommand); + } catch (IOException e) { + e.printStackTrace(); + } } } From d5d89fc9780cd686b23224a1a79812b496401d66 Mon Sep 17 00:00:00 2001 From: alilotfi Date: Wed, 4 Feb 2015 16:17:55 +0330 Subject: [PATCH 33/40] GameHandler revised (Docs + code review) --- src/server/core/GameHandler.java | 186 ++++++++++++++++++++++--------- 1 file changed, 132 insertions(+), 54 deletions(-) diff --git a/src/server/core/GameHandler.java b/src/server/core/GameHandler.java index d46990c..5674f28 100644 --- a/src/server/core/GameHandler.java +++ b/src/server/core/GameHandler.java @@ -32,14 +32,15 @@ * moment the external terminal user wants to shut down the games loop (except than waiting for the * {@link server.core.GameLogic GameLogic} to flag the end of the game), the * {@link server.core.GameHandler#shutdown() shutdown()} method would be called. - * Note that shutting down the {@link server.core.GameHandler GameHandler} will not immedietelly stop the threads, - * actually it will set a shut down request flag in the class, which will + * Note that shutting down the {@link server.core.GameHandler GameHandler} will not immediately stop the threads, + * actually it will set a shut down request flag in the class, which will closes the thread in the aspect of + * accepting more inputs, and the terminate the threads as soon as the operation queue got empty. *

*/ public class GameHandler { - private static final String RESOURCE_PATH_OUTPUT_HANDLER = "/resources/game_handler/output_handler.conf"; - private static final String RESOURCE_PATH_TURN_TIMEOUT = "/resources/game_handler/output_handler.conf"; + private static final String RESOURCE_PATH_OUTPUT_HANDLER = "resources/game_handler/output_handler.conf"; + private static final String RESOURCE_PATH_TURN_TIMEOUT = "resources/game_handler/turn_timeout.conf"; private final long GAME_LOGIC_SIMULATE_TIMEOUT; private final long CLIENT_RESPONSE_TIME; @@ -50,8 +51,19 @@ public class GameHandler { private ClientInfo[] mClientsInfo; private Loop mLoop; - private ArrayList mEventsQueue; + /** + * Constructor of the {@link server.core.GameHandler GameHandler}, connects the handler to the Clients through + * {@link server.network.ClientNetwork ClientNetwork} and to the UI through + * {@link server.network.UINetwork UINetwork}. + *

+ * The constructor accepts the instances of {@link server.core.GameHandler GameHandler} and + * {@link server.network.ClientNetwork ClientNetwork} classes. Then sets some configurations of the loops + * within the "turn_timeout.conf" file ({@see https://github.com/JavaChallenge/JGFramework/wiki wiki}). + *

+ * @param clientNetwork Network which the game will contact to the clients through + * @param uiNetwork Network which the game will contact to the UI through + */ public GameHandler(ClientNetwork clientNetwork, UINetwork uiNetwork) { mClientNetwork = clientNetwork; mUINetwork = uiNetwork; @@ -60,7 +72,7 @@ public GameHandler(ClientNetwork clientNetwork, UINetwork uiNetwork) { try { File file = new File(RESOURCE_PATH_TURN_TIMEOUT); BufferedReader bufferedReader = new BufferedReader(new FileReader(file)); - TimeConfig timeConfig = gson.fromJson(file.toString(), TimeConfig.class); + TimeConfig timeConfig = gson.fromJson(bufferedReader, TimeConfig.class); GAME_LOGIC_SIMULATE_TIMEOUT = timeConfig.getClientResponseTime(); CLIENT_RESPONSE_TIME = timeConfig.getUIResponseTime(); } catch (FileNotFoundException notFound) { @@ -70,6 +82,15 @@ public GameHandler(ClientNetwork clientNetwork, UINetwork uiNetwork) { } } + /** + * Initializes the game handler module based on the given game. + *

+ * This method creates needed instance of module {@link server.core.OutputController OutputController} based on + * configurations located in the "output_handler.conf" file + * ({@see https://github.com/JavaChallenge/JGFramework/wiki wiki}). + * Any problem in loading or parsing the configuration JSON files, will result in rising a runtime exception. + *

+ */ public void init() { OutputHandlerConfig outputHandlerConfig; Gson gson = new Gson(); @@ -90,33 +111,71 @@ public void init() { outputHandlerConfig.bufferSize); } + /** + * Setter of the game logic, will set the main game engine of the {@link server.core.GameHandler GameHandler} to + * the given instance of {@link server.core.GameLogic GameLogic}. + * @param gameLogic The given instance of the {@link server.core.GameLogic GameLogic} to set in the object. + */ + public void setGameLogic(GameLogic gameLogic) { mGameLogic = gameLogic; } + /** + * Getter of the {@link server.network.ClientNetwork ClientNetwork} class which is used to contact to the clients + * through it. + * @return The {@link server.network.ClientNetwork ClientNetwork} instance used to connect to clients + */ public ClientNetwork getClientNetwork() { return mClientNetwork; } + /** + * Getter of the {@link server.network.UINetwork UINetwork} class instance, which is used in order to connect to + * the UI. + * @return Instance of {@link server.network.UINetwork UINetwork} class, used to send messages to user interface + */ public UINetwork getUINetwork() { return mUINetwork; } + /** + * Setter of the {@link server.core.model.ClientInfo ClientInfo} instance stored in the class in order to recognize + * the clients from each other + * @param clientsInfo Array of information of the clients held in the class + */ public void setClientsInfo(ClientInfo[] clientsInfo) { mClientsInfo = clientsInfo; } + /** + * Starts the main game ({@link server.core.GameLogic GameLogic}) loop and the + * {@link server.core.OutputController OutputController} operations in two new {@link java.lang.Thread Thread}. + */ public void start() { mLoop = new Loop(); new Thread(mLoop).start(); new Thread(mOutputController).start(); } + /** + * Registers a shutdown request into the main loop and {@link server.core.OutputController OutputController} class + *

+ * Note that the shutdown requests, will be responded as soon as the current queue of operations got freed. + *

+ */ public void shutdown() { mLoop.shutdown(); mOutputController.shutdown(); } + /** + * In order to give the loop a thread to be ran beside of the main loop. + *

+ * This inner class has a {@link java.util.concurrent.Callable Callable} part, which is wrote down as a + * runnable code template. This template is composed by the multiple steps in every turn of the game. + *

+ */ private class Loop implements Runnable { private boolean shutdownRequest = false; @@ -125,54 +184,55 @@ private class Loop implements Runnable { private Event[] terminalEvents; private Event[][] clientEvents; + /** + * The run method of the {@link java.lang.Runnable Runnable} interface which will create a + * {@link java.util.concurrent.Callable Callable} instance and call it in a while until the finish flag if the + * game had been raised or the shutdown request sent to the class (through + * {@link server.core.GameHandler.Loop#shutdown() shutdown()} method) + */ @Override public void run() { - Callable simulate = new Callable() { + Callable simulate = () -> { + mGameLogic.simulateEvents(terminalEvents, environmentEvents, clientEvents); + mGameLogic.generateOutputs(); + if (mGameLogic.isGameFinished()) { + mLoop.shutdown(); + mOutputController.shutdown(); + } - @Override - public Void call() throws Exception { + mOutputController.putMessage(mGameLogic.getUIMessage()); - mGameLogic.simulateEvents(terminalEvents, environmentEvents, clientEvents); - mGameLogic.generateOutputs(); - if (mGameLogic.isGameFinished()) { - mLoop.shutdown(); - mOutputController.shutdown(); + Message[] output = mGameLogic.getClientMessages(); + for (int i = 0 ; i < output.length; ++i) { + mClientNetwork.queue(i, output[i]); + } + mClientNetwork.sendAllBlocking(); + + mClientNetwork.startReceivingAll(); + long elapsedTime = System.currentTimeMillis(); + environmentEvents = mGameLogic.makeEnvironmentEvents(); + elapsedTime = System.currentTimeMillis() - elapsedTime; + if (CLIENT_RESPONSE_TIME - elapsedTime > 0) { + try { + wait(CLIENT_RESPONSE_TIME - elapsedTime); + } catch (InterruptedException e) { + throw new RuntimeException("Waiting for clients interrupted"); } + } + mClientNetwork.stopReceivingAll(); - mOutputController.putMessage(mGameLogic.getUIMessage()); - - Message[] output = mGameLogic.getClientMessages(); - for (int i = 0 ; i < output.length; ++i) { - mClientNetwork.queue(i, output[i]); - } - mClientNetwork.sendAllBlocking(); - - mClientNetwork.startReceivingAll(); - long elapsedTime = System.currentTimeMillis(); - environmentEvents = mGameLogic.makeEnvironmentEvents(); - elapsedTime = System.currentTimeMillis() - elapsedTime; - if (CLIENT_RESPONSE_TIME - elapsedTime > 0) { - try { - wait(CLIENT_RESPONSE_TIME - elapsedTime); - } catch (InterruptedException e) { - throw new RuntimeException("Waiting for clients interrupted"); - } + clientEvents = new Event[mClientsInfo.length][]; + for (int i = 0; i < mClientsInfo.length; ++i) { + if (mClientNetwork.getReceivedEvent(i) != null) { + clientEvents[i] = mClientNetwork.getReceivedEvent(i); } - mClientNetwork.stopReceivingAll(); + } + //FIXME: Put a blocking queue for terminal + BlockingQueue terminalEventsQueue = new LinkedBlockingQueue<>(); - clientEvents = new Event[mClientsInfo.length][]; - for (int i = 0; i < mClientsInfo.length; ++i) { - if (mClientNetwork.getReceivedEvent(i) != null) { - clientEvents[i] = mClientNetwork.getReceivedEvent(i); - } - } - //FIXME: Put a blocking queue for terminal - BlockingQueue terminalEventsQueue = new LinkedBlockingQueue<>(); - - terminalEvents = null; + terminalEvents = null; - return null; - } + return null; }; RunnableFuture runnableSimulate = new FutureTask(simulate); ExecutorService service = Executors.newSingleThreadExecutor(); @@ -192,11 +252,22 @@ public Void call() throws Exception { service.shutdown(); } + /** + * Will set the shutdown request flag in order to finish the main {@link server.core.GameHandler.Loop Loop} at + * the first possible turn + */ public void shutdown() { this.shutdownRequest = true; } } + /** + * The template of the "output_handler.conf" JSON file. + *

+ * This class could be filled by a {@link com.google.gson.Gson Gson} object. The properties of class are + * normally accessed through {@link server.core.GameHandler#init() init()} method. + *

+ */ private class OutputHandlerConfig { private boolean sendToUI; private int timeInterval; @@ -204,13 +275,28 @@ private class OutputHandlerConfig { private String filePath; private int bufferSize; + public OutputHandlerConfig(boolean sendToUI, + int timeInterval, + boolean sendToFile, + String filePath, + int bufferSize) { + this.sendToUI = sendToUI; + this.timeInterval = timeInterval; + this.sendToFile = sendToFile; + this.filePath = filePath; + this.bufferSize = bufferSize; + } private File getFile() { return new File(filePath); } } /** - * + * The template of the "turn_timeout.conf" JSON file. + *

+ * This class could be filled by a {@link com.google.gson.Gson Gson} object. The properties of class are + * normally accessed through {@link server.core.GameHandler#GameHandler GameHandler Constructor} method. + *

*/ private static class TimeConfig { private long mClientResponseTime; @@ -221,18 +307,10 @@ public TimeConfig(long clientResponseTime,long uiResponseTime) { mSimulateTimeout = uiResponseTime; } - /** - * - * @return - */ public long getClientResponseTime() { return mClientResponseTime; } - /** - * - * @return - */ public long getUIResponseTime() { return mSimulateTimeout; } From 53071ad2002716e09dbf95bacea5b9548b163663 Mon Sep 17 00:00:00 2001 From: Hadi Khodabande Date: Wed, 4 Feb 2015 17:15:07 +0330 Subject: [PATCH 34/40] Small change in TerminalNetwork. --- src/server/core/CommandHandler.java | 5 +- src/server/network/TerminalNetwork.java | 54 ++++++++----------- src/server/network/data/Command.java | 26 --------- src/server/network/data/CommandReport.java | 10 ---- .../server/network/TerminalNetworkTest.java | 7 ++- 5 files changed, 27 insertions(+), 75 deletions(-) delete mode 100644 src/server/network/data/Command.java delete mode 100644 src/server/network/data/CommandReport.java diff --git a/src/server/core/CommandHandler.java b/src/server/core/CommandHandler.java index f7f95a5..21669ed 100644 --- a/src/server/core/CommandHandler.java +++ b/src/server/core/CommandHandler.java @@ -2,8 +2,7 @@ import server.core.model.Event; import server.network.TerminalNetwork; -import server.network.data.Command; -import server.network.data.CommandReport; +import server.network.data.Message; /** * Created by alilotfi on 2/2/15. @@ -11,7 +10,7 @@ public class CommandHandler implements TerminalNetwork.TerminalInterface { @Override - public CommandReport runCommand(Command command) { + public Message runCommand(Message command) { return null; } diff --git a/src/server/network/TerminalNetwork.java b/src/server/network/TerminalNetwork.java index f79e932..a065774 100644 --- a/src/server/network/TerminalNetwork.java +++ b/src/server/network/TerminalNetwork.java @@ -1,13 +1,9 @@ package server.network; import server.core.model.Event; -import server.network.data.Command; -import server.network.data.CommandReport; import server.network.data.Message; import java.io.IOException; -import java.util.ArrayList; -import java.util.StringTokenizer; /** * This class is responsible for create and handling the communication between users and the Terminal @@ -35,7 +31,7 @@ public class TerminalNetwork extends NetServer { */ public interface TerminalInterface { void putEvent(Event event); - CommandReport runCommand(Command command); + Message runCommand(Message command); } /** @@ -98,17 +94,18 @@ public TerminalNetworkThread (JsonSocket client) { * * @see #TerminalNetworkThread(JsonSocket) * @see #checkInput() - * @see #makeCommandObj(server.network.data.Message) */ @Override public void run() { try { Message msg = client.get(Message.class); - if (!msg.name.equals(token)) - return; - if (!msg.args[0].equals(token)) + if (!msg.name.equals("token") || msg.args == null || msg.args.length < 1 || !msg.args[0].equals(token)) { + client.close(); return; + } + + client.send(new Message("init", null)); // now the user is a valid one while (userHasCommand) { @@ -121,6 +118,11 @@ public void run() { } catch (Exception e) { e.printStackTrace(); + try { + client.close(); + } catch (IOException e1) { + e1.printStackTrace(); + } } } @@ -130,32 +132,20 @@ public void run() { */ public void checkInput() throws IOException { Message msg = client.get(Message.class); - if (msg.name.equals(Command.COMMAND)) { - handler.runCommand(makeCommandObj(msg)); - } else if (msg.name.equals(Event.EVENT)) { - handler.putEvent((Event)msg.args[0]); - } else { - client.send("Your input is invalid!\nPlease don't hack me :)"); + switch (msg.name) { + case "command": + Message report = handler.runCommand(msg); + client.send(report); + break; + case Event.EVENT: + handler.putEvent((Event) msg.args[0]); + break; + default: + client.send("Your input is invalid!\nPlease don't hack me :)"); + break; } } - /** - * It takes a {@link server.network.data.Message} object and return - * a {@link server.network.data.Command} object created from message. - * @param msg the object that was created from an user's input. - * @return A command object created from the message. - */ - private Command makeCommandObj(Message msg) { - Command cmd = new Command(); - cmd.cmdType = (String)msg.args[0]; - StringTokenizer tokenizer = new StringTokenizer((String)msg.args[1], ","); - ArrayList argsList = new ArrayList<>(); - while (tokenizer.hasMoreTokens()) { - argsList.add(tokenizer.nextToken()); - } - cmd.args = argsList.toArray(new String[argsList.size()]); - return cmd; - } } } diff --git a/src/server/network/data/Command.java b/src/server/network/data/Command.java deleted file mode 100644 index 9faec15..0000000 --- a/src/server/network/data/Command.java +++ /dev/null @@ -1,26 +0,0 @@ -package server.network.data; - -import com.google.gson.JsonObject; - -/** - * Created by rajabzz on 12/22/14. - */ -public class Command { - public static final String COMMAND = "command"; - - public static final int COMMAND_TYPE_HELP = 0; - public static final int COMMAND_TYPE_STATUS = 1; - public static final int COMMAND_TYPE_NEW_GAME = 2; - public static final int COMMAND_TYPE_LOAD_GAME = 3; - public static final int COMMAND_TYPE_PAUSE_GAME = 4; - public static final int COMMAND_TYPE_RESUME_GAME = 5; - public static final int COMMAND_TYPE_END_GAME = 6; - public static final int COMMAND_TYPE_CONNECT = 7; - public static final int COMMAND_TYPE_DISCONNECT = 8; - public static final int COMMAND_TYPE_EXIT = 9; - - - public String cmdType; - public String[] args; - -} diff --git a/src/server/network/data/CommandReport.java b/src/server/network/data/CommandReport.java deleted file mode 100644 index 6858801..0000000 --- a/src/server/network/data/CommandReport.java +++ /dev/null @@ -1,10 +0,0 @@ -package server.network.data; - -/** - * Created by rajabzz on 12/22/14. - */ -public class CommandReport { - public static final String REPORT = "report"; - - public Object[] args; -} diff --git a/src/test/server/network/TerminalNetworkTest.java b/src/test/server/network/TerminalNetworkTest.java index dacd989..302ce20 100644 --- a/src/test/server/network/TerminalNetworkTest.java +++ b/src/test/server/network/TerminalNetworkTest.java @@ -6,8 +6,6 @@ import server.core.model.Event; import server.network.JsonSocket; import server.network.TerminalNetwork; -import server.network.data.Command; -import server.network.data.CommandReport; import server.network.data.Message; import java.io.IOException; @@ -30,8 +28,8 @@ public void putEvent(Event event) { } @Override - public CommandReport runCommand(Command command) { - return new CommandReport(); + public Message runCommand(Message command) { + return new Message("report", null); } }); terminal.listen(port); @@ -79,6 +77,7 @@ public void sendCommand() { Message init = client.get(Message.class); client.send(new Message("command", new Object[] {})); Message report = client.get(Message.class); + assertEquals(report.name, "report"); } catch (IOException e) { fail(e.getMessage()); } From a33ac95e47768a353068b560f076a253c73dcbc7 Mon Sep 17 00:00:00 2001 From: Semora Date: Wed, 4 Feb 2015 22:32:36 +0330 Subject: [PATCH 35/40] edit gitignore and several changes --- .gitignore | 3 ++- JGFramework.iml | 4 +++- src/server/Server.java | 6 ++--- src/server/core/OutputController.java | 2 +- src/server/network/data/Command.java | 26 ++++++++++++++++++++++ src/server/network/data/CommandReport.java | 10 +++++++++ 6 files changed, 45 insertions(+), 6 deletions(-) create mode 100644 src/server/network/data/Command.java create mode 100644 src/server/network/data/CommandReport.java diff --git a/.gitignore b/.gitignore index 295f330..0969247 100644 --- a/.gitignore +++ b/.gitignore @@ -15,4 +15,5 @@ JGFramework.iml hs_err_pid* # Jar libraries # -./libs/*.jar \ No newline at end of file +libs/*.jar +out/ \ No newline at end of file diff --git a/JGFramework.iml b/JGFramework.iml index 41d2e5e..d3e9e47 100644 --- a/JGFramework.iml +++ b/JGFramework.iml @@ -6,10 +6,12 @@ + - + + \ No newline at end of file diff --git a/src/server/Server.java b/src/server/Server.java index 726f14a..faf3955 100644 --- a/src/server/Server.java +++ b/src/server/Server.java @@ -32,9 +32,9 @@ */ public class Server { - private static final String RESOURCE_PATH_TERMINAL = "/resources/network/terminal.conf"; - private static final String RESOURCE_PATH_UI = "/resources/network/ui.conf"; - private static final String RESOURCE_PATH_CLIENT = "/resources/network/client.conf"; + private static final String RESOURCE_PATH_TERMINAL = "resources/network/terminal.conf"; + private static final String RESOURCE_PATH_UI = "resources/network/ui.conf"; + private static final String RESOURCE_PATH_CLIENT = "resources/network/client.conf"; private Factory mFactory; private TerminalNetwork mTerminalNetwork; diff --git a/src/server/core/OutputController.java b/src/server/core/OutputController.java index cefd761..440204a 100644 --- a/src/server/core/OutputController.java +++ b/src/server/core/OutputController.java @@ -87,7 +87,7 @@ public OutputController(boolean sendToUI, UINetwork uiNetwork, int timeInterval if (outputFile.exists()) { this.outputFile = outputFile; } else { - throw new RuntimeException("The given parameter as outputFile does not exist"); + //throw new RuntimeException("The given parameter as outputFile does not exist"); //TODO CHECK } if (bufferSize > 0 && bufferSize <= QUEUE_DEFAULT_SIZE) { diff --git a/src/server/network/data/Command.java b/src/server/network/data/Command.java new file mode 100644 index 0000000..9faec15 --- /dev/null +++ b/src/server/network/data/Command.java @@ -0,0 +1,26 @@ +package server.network.data; + +import com.google.gson.JsonObject; + +/** + * Created by rajabzz on 12/22/14. + */ +public class Command { + public static final String COMMAND = "command"; + + public static final int COMMAND_TYPE_HELP = 0; + public static final int COMMAND_TYPE_STATUS = 1; + public static final int COMMAND_TYPE_NEW_GAME = 2; + public static final int COMMAND_TYPE_LOAD_GAME = 3; + public static final int COMMAND_TYPE_PAUSE_GAME = 4; + public static final int COMMAND_TYPE_RESUME_GAME = 5; + public static final int COMMAND_TYPE_END_GAME = 6; + public static final int COMMAND_TYPE_CONNECT = 7; + public static final int COMMAND_TYPE_DISCONNECT = 8; + public static final int COMMAND_TYPE_EXIT = 9; + + + public String cmdType; + public String[] args; + +} diff --git a/src/server/network/data/CommandReport.java b/src/server/network/data/CommandReport.java new file mode 100644 index 0000000..6858801 --- /dev/null +++ b/src/server/network/data/CommandReport.java @@ -0,0 +1,10 @@ +package server.network.data; + +/** + * Created by rajabzz on 12/22/14. + */ +public class CommandReport { + public static final String REPORT = "report"; + + public Object[] args; +} From 5b823c9514ae806de568a4a9bb9babc38a85eb85 Mon Sep 17 00:00:00 2001 From: Semora Date: Thu, 5 Feb 2015 11:15:29 +0330 Subject: [PATCH 36/40] Terminal network bug fixed init message args --- src/server/network/TerminalNetwork.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/server/network/TerminalNetwork.java b/src/server/network/TerminalNetwork.java index a065774..79ea032 100644 --- a/src/server/network/TerminalNetwork.java +++ b/src/server/network/TerminalNetwork.java @@ -4,6 +4,7 @@ import server.network.data.Message; import java.io.IOException; +import java.util.ArrayList; /** * This class is responsible for create and handling the communication between users and the Terminal @@ -104,8 +105,9 @@ public void run() { client.close(); return; } - - client.send(new Message("init", null)); + Object [] args = new Object[1]; + args[0] = new ArrayList(); + client.send(new Message("init", args)); // now the user is a valid one while (userHasCommand) { From 5254b1a2c1730bccede1d6eb5a0d9dfef1fd2ad4 Mon Sep 17 00:00:00 2001 From: Hadi Khodabande Date: Thu, 5 Feb 2015 11:55:20 +0330 Subject: [PATCH 37/40] CommandHandler improved. --- src/server/Server.java | 15 ++++++- src/server/core/CommandHandler.java | 69 +++++++++++++++++++++++++++-- src/server/core/GameHandler.java | 19 ++++++-- 3 files changed, 96 insertions(+), 7 deletions(-) diff --git a/src/server/Server.java b/src/server/Server.java index faf3955..b4db9d3 100644 --- a/src/server/Server.java +++ b/src/server/Server.java @@ -104,6 +104,19 @@ public Server(Factory factory) { public void setCommandHandler(CommandHandler commandHandler) { mTerminalNetwork.setHandler(commandHandler); + commandHandler.setServer(this); + } + + public Factory getFactory() { + return mFactory; + } + + public TerminalNetwork getTerminalNetwork() { + return mTerminalNetwork; + } + + public GameHandler getGameHandler() { + return mGameHandler; } /** @@ -113,7 +126,7 @@ public void start() { mTerminalNetwork.listen(mTerminalConfig.getTerminalPort()); } - private void newGame(String[] options, long uiTimeout, long clientTimeout) { + public void newGame(String[] options, long uiTimeout, long clientTimeout) { GameLogic gameLogic = mFactory.getGameLogic(options); gameLogic.init(); mGameHandler.setGameLogic(gameLogic); diff --git a/src/server/core/CommandHandler.java b/src/server/core/CommandHandler.java index 21669ed..d474a81 100644 --- a/src/server/core/CommandHandler.java +++ b/src/server/core/CommandHandler.java @@ -1,21 +1,84 @@ package server.core; +import server.Server; import server.core.model.Event; import server.network.TerminalNetwork; import server.network.data.Message; +import java.util.HashMap; +import java.util.function.UnaryOperator; + /** * Created by alilotfi on 2/2/15. */ public class CommandHandler implements TerminalNetwork.TerminalInterface { + public static final String REPORT_NAME = "report"; + + protected Server mServer; + private HashMap> mHandlers = new HashMap<>(); + + public CommandHandler() { + defineCommand("status", this::cmdStatus); + defineCommand("newGame", this::cmdNewGame); +// defineCommand("loadGame", this::cmdLoadGame); + defineCommand("startGame", this::cmdStartGame); +// defineCommand("pauseGame", this::cmdPauseGame); +// defineCommand("resumeGame", this::cmdResumeGame); +// defineCommand("endGame", this::cmdEndGame); +// defineCommand("exit", this::cmdExit); + } + + public void defineCommand(String command, UnaryOperator handler) { + mHandlers.put(command, handler); + } + + public void setServer(Server server) { + mServer = server; + } + @Override - public Message runCommand(Message command) { - return null; + public Message runCommand(Message cmd) { + if (cmd == null || cmd.name == null) + return null; + UnaryOperator handler = mHandlers.get(cmd.name); + if (handler != null) { + return handler.apply(cmd); + } else { + return new Message(REPORT_NAME, new Object[]{ + "This command is not defined." + }); + } } + public Message cmdStatus(Message cmd) { + return new Message(REPORT_NAME, new Object[] { + "Number of connected clients: " + mServer.getGameHandler().getClientNetwork().getNumberOfConnected() + }); + } + + public Message cmdNewGame(Message cmd) { + String args[] = null; + if (cmd.args != null) { + args = new String[cmd.args.length]; + for (int i = 0; i < args.length; i++) + args[i] = (String) cmd.args[i]; + } + mServer.newGame(args, 5*60*1000, 5*60*1000); // todo: change static timeouts + return new Message(REPORT_NAME, null); + } + + public Message cmdStartGame(Message cmd) { + mServer.getGameHandler().start(); + return new Message(REPORT_NAME, new Object[] { + "Game started successfully!" + }); + } + + @Override public void putEvent(Event event) { - + mServer.getGameHandler().queueEvent(event); } + } diff --git a/src/server/core/GameHandler.java b/src/server/core/GameHandler.java index 5674f28..f22cffd 100644 --- a/src/server/core/GameHandler.java +++ b/src/server/core/GameHandler.java @@ -169,6 +169,17 @@ public void shutdown() { mOutputController.shutdown(); } + /** + * Queues an event to be simulated in the next turn of the loop. + * + * @param event terminal event + */ + public void queueEvent(Event event) { + synchronized (mLoop.terminalEventsQueue) { + mLoop.terminalEventsQueue.add(event); + } + } + /** * In order to give the loop a thread to be ran beside of the main loop. *

@@ -183,6 +194,7 @@ private class Loop implements Runnable { private Event[] environmentEvents; private Event[] terminalEvents; private Event[][] clientEvents; + private final ArrayList terminalEventsQueue = new ArrayList<>(); /** * The run method of the {@link java.lang.Runnable Runnable} interface which will create a @@ -227,10 +239,11 @@ public void run() { clientEvents[i] = mClientNetwork.getReceivedEvent(i); } } - //FIXME: Put a blocking queue for terminal - BlockingQueue terminalEventsQueue = new LinkedBlockingQueue<>(); - terminalEvents = null; + synchronized (terminalEventsQueue) { + terminalEvents = terminalEventsQueue.toArray(new Event[terminalEventsQueue.size()]); + terminalEventsQueue.clear(); + } return null; }; From 3e6b83f86624af6112bba9ddf081cce34e18c7ea Mon Sep 17 00:00:00 2001 From: Semora Date: Sun, 8 Feb 2015 17:28:44 +0330 Subject: [PATCH 38/40] debuging server several works --- resources/client/connection.conf | 5 ++++ src/client/Main.java | 2 +- src/server/core/GameHandler.java | 31 ++++++++++++++++--------- src/server/core/OutputController.java | 14 +++++++---- src/server/core/model/ClientInfo.java | 11 +++++++++ src/server/network/TerminalNetwork.java | 10 +++++++- src/server/network/data/Message.java | 10 ++++++++ 7 files changed, 66 insertions(+), 17 deletions(-) create mode 100644 resources/client/connection.conf diff --git a/resources/client/connection.conf b/resources/client/connection.conf new file mode 100644 index 0000000..04b0f14 --- /dev/null +++ b/resources/client/connection.conf @@ -0,0 +1,5 @@ +{ + "token" : "00000000000000000000000000000000", + "port" : 7099, + "ip" : "127.0.0.1" +} \ No newline at end of file diff --git a/src/client/Main.java b/src/client/Main.java index dec5f98..21a29df 100644 --- a/src/client/Main.java +++ b/src/client/Main.java @@ -6,7 +6,7 @@ public class Main { public static void main(String[] args) { - new Controller("connection.conf").start(); + new Controller("resources/client/connection.conf").start(); } } diff --git a/src/server/core/GameHandler.java b/src/server/core/GameHandler.java index f22cffd..9bcb11b 100644 --- a/src/server/core/GameHandler.java +++ b/src/server/core/GameHandler.java @@ -7,6 +7,7 @@ import server.network.ClientNetwork; import server.network.UINetwork; import server.network.data.Message; +import util.Log; import java.io.BufferedReader; import java.io.File; @@ -42,6 +43,7 @@ public class GameHandler { private static final String RESOURCE_PATH_OUTPUT_HANDLER = "resources/game_handler/output_handler.conf"; private static final String RESOURCE_PATH_TURN_TIMEOUT = "resources/game_handler/turn_timeout.conf"; private final long GAME_LOGIC_SIMULATE_TIMEOUT; + private final long GAME_LOGIC_TURN_TIMEOUT = 1000; private final long CLIENT_RESPONSE_TIME; private ClientNetwork mClientNetwork; @@ -247,22 +249,29 @@ public void run() { return null; }; - RunnableFuture runnableSimulate = new FutureTask(simulate); - ExecutorService service = Executors.newSingleThreadExecutor(); +// RunnableFuture runnableSimulate = new FutureTask<>(simulate); +// ExecutorService service = Executors.newSingleThreadExecutor(); while (!shutdownRequest) { - service.execute(runnableSimulate); + long start = System.currentTimeMillis(); try { - runnableSimulate.get(GAME_LOGIC_SIMULATE_TIMEOUT, TimeUnit.MILLISECONDS); - } catch (ExecutionException execution) { - throw new RuntimeException("GameLogic execution encountered exception"); - } catch (TimeoutException timeOut) { - runnableSimulate.cancel(true); - } catch (InterruptedException interrupted) { - throw new RuntimeException("GameLogic execution interrupted"); + simulate.call(); + } catch (Exception e) { + e.printStackTrace(); + } + long end = System.currentTimeMillis(); + long remaining = GAME_LOGIC_TURN_TIMEOUT - (end - start); + if (remaining <= 0) { + Log.i("GameHandler", "Simulation timeout passed!"); + } else { + try { + Thread.sleep(remaining); + } catch (InterruptedException e) { + Log.i("GameHandler", "Loop interrupted!"); + break; + } } } - service.shutdown(); } /** diff --git a/src/server/core/OutputController.java b/src/server/core/OutputController.java index 440204a..ba30110 100644 --- a/src/server/core/OutputController.java +++ b/src/server/core/OutputController.java @@ -149,7 +149,9 @@ public synchronized void putMessage(Message message) { throw new OutputControllerQueueOverflowException("Could not handle message queue overflow"); } } - notifyAll(); + synchronized (messagesQueue) { + messagesQueue.notifyAll(); + } } /** @@ -220,7 +222,9 @@ public FileWriter(File file) { public void putMessages(LinkedList messages) { try { this.messagesQueue.put(messages); - notifyAll(); + synchronized (messagesQueue) { + messagesQueue.notifyAll(); + } } catch (InterruptedException e) { throw new RuntimeException("Put messages in FileWriter blocking queue interrupted"); } @@ -258,7 +262,9 @@ private void writeToFile() { for (Message message : messagesQueue.take()) { //TODO: Save messages in a file } - notifyAll(); + synchronized (messagesQueue) { + notifyAll(); + } } catch (InterruptedException e) { throw new RuntimeException("Taking from FileWriter message queue interrupted."); } @@ -312,7 +318,7 @@ public void run() { synchronized (messagesQueue) { while (messagesQueue.size() <= 0) { try { - wait(); + messagesQueue.wait(); } catch (InterruptedException e) { throw new RuntimeException("Wait on UINetworkSender interrupted"); } diff --git a/src/server/core/model/ClientInfo.java b/src/server/core/model/ClientInfo.java index b71024f..6a17ce8 100644 --- a/src/server/core/model/ClientInfo.java +++ b/src/server/core/model/ClientInfo.java @@ -36,4 +36,15 @@ public void setID(int ID) { public String getToken() { return mToken; } + + + //TODO DOC + public void setmName(String mName) { + this.mName = mName; + } + + //TODO DOC + public void setmToken(String mToken) { + this.mToken = mToken; + } } diff --git a/src/server/network/TerminalNetwork.java b/src/server/network/TerminalNetwork.java index 79ea032..1c78c91 100644 --- a/src/server/network/TerminalNetwork.java +++ b/src/server/network/TerminalNetwork.java @@ -19,6 +19,8 @@ */ public class TerminalNetwork extends NetServer { + public static final int MAX_RECEIVE_EXCEPTIONS = 20; + /** * used to identify the users to connect to Terminal. */ @@ -109,11 +111,16 @@ public void run() { args[0] = new ArrayList(); client.send(new Message("init", args)); + int exceptions = 0; + // now the user is a valid one while (userHasCommand) { try { checkInput(); } catch (Exception e) { + exceptions++; + if (exceptions > MAX_RECEIVE_EXCEPTIONS) + return; e.printStackTrace(); } } @@ -136,7 +143,8 @@ public void checkInput() throws IOException { Message msg = client.get(Message.class); switch (msg.name) { case "command": - Message report = handler.runCommand(msg); + Message command = new Message((String)msg.args[0], ((ArrayList)msg.args[1]).toArray()); + Message report = handler.runCommand(command); client.send(report); break; case Event.EVENT: diff --git a/src/server/network/data/Message.java b/src/server/network/data/Message.java index c7827c5..552f02e 100644 --- a/src/server/network/data/Message.java +++ b/src/server/network/data/Message.java @@ -7,8 +7,18 @@ public class Message { public String name; public Object[] args; + public Message(){} + public Message(String name, Object[] args) { this.name = name; this.args = args; } + + public void setName(String name) { + this.name = name; + } + + public void setArgs(Object[] args) { + this.args = args; + } } From e0fdcc8a531b1730aae117eef1c3e7c037fd1a4f Mon Sep 17 00:00:00 2001 From: alilotfi Date: Sun, 8 Feb 2015 17:31:12 +0330 Subject: [PATCH 39/40] Game Handler terminal events queue, added OutputController serializing messages to the log file implemented --- src/server/core/GameHandler.java | 30 ++++++++++++++++++--- src/server/core/OutputController.java | 39 ++++++++++++++++----------- 2 files changed, 50 insertions(+), 19 deletions(-) diff --git a/src/server/core/GameHandler.java b/src/server/core/GameHandler.java index 5674f28..f5f3161 100644 --- a/src/server/core/GameHandler.java +++ b/src/server/core/GameHandler.java @@ -51,6 +51,7 @@ public class GameHandler { private ClientInfo[] mClientsInfo; private Loop mLoop; + BlockingQueue terminalEventsQueue; /** * Constructor of the {@link server.core.GameHandler GameHandler}, connects the handler to the Clients through @@ -67,6 +68,7 @@ public class GameHandler { public GameHandler(ClientNetwork clientNetwork, UINetwork uiNetwork) { mClientNetwork = clientNetwork; mUINetwork = uiNetwork; + terminalEventsQueue = new LinkedBlockingQueue<>(); Gson gson = new Gson(); try { @@ -227,14 +229,16 @@ public void run() { clientEvents[i] = mClientNetwork.getReceivedEvent(i); } } - //FIXME: Put a blocking queue for terminal - BlockingQueue terminalEventsQueue = new LinkedBlockingQueue<>(); - terminalEvents = null; + ArrayList terminalEventsTemp = new ArrayList<>(); + while (!terminalEventsQueue.isEmpty()) { + terminalEventsTemp.add(terminalEventsQueue.take()); + } + terminalEvents = terminalEventsTemp.toArray(new Event[terminalEventsTemp.size()]); return null; }; - RunnableFuture runnableSimulate = new FutureTask(simulate); + RunnableFuture runnableSimulate = new FutureTask<>(simulate); ExecutorService service = Executors.newSingleThreadExecutor(); while (!shutdownRequest) { @@ -261,6 +265,24 @@ public void shutdown() { } } + /** + * This method is used to add a new event in the event queue of the terminal to be executed at the first simulation + * time. + *

+ * Normally this method would be called by the {@link server.core.CommandHandler CommandHandler} class, which + * will receive and manage the entered commands in the console. + * These commands will be passed to the {@link server.core.GameLogic GameLogic} instance as the terminal events + *

+ * @param event Received {@link server.core.model.Event Event} from terminal to add in terminal events queue + */ + public void putTerminalEvent(Event event) { + try { + terminalEventsQueue.put(event); + } catch (InterruptedException e) { + throw new RuntimeException("Putting event in the terminal event queue, interrupted"); + } + } + /** * The template of the "output_handler.conf" JSON file. *

diff --git a/src/server/core/OutputController.java b/src/server/core/OutputController.java index cefd761..ed4ce63 100644 --- a/src/server/core/OutputController.java +++ b/src/server/core/OutputController.java @@ -4,7 +4,7 @@ import server.network.UINetwork; import server.network.data.Message; -import java.io.File; +import java.io.*; import java.util.LinkedList; import java.util.Timer; import java.util.TimerTask; @@ -84,10 +84,11 @@ public OutputController(boolean sendToUI, UINetwork uiNetwork, int timeInterval } this.sendToFile = sendToFile; if (sendToFile) { - if (outputFile.exists()) { - this.outputFile = outputFile; - } else { - throw new RuntimeException("The given parameter as outputFile does not exist"); + this.outputFile = outputFile; + try { + this.outputFile.createNewFile(); + } catch (IOException e) { + throw new RuntimeException("Could not create log file"); } if (bufferSize > 0 && bufferSize <= QUEUE_DEFAULT_SIZE) { @@ -249,14 +250,25 @@ public void run() { * Stores the contents of the message queue as an appendix to the FileWriter file. *

* This method will write the whole contents of the saved message queue in the file writer object - * on the given file. As this operation is completed, the file writer tries to write the next file in - * the {@link java.util.concurrent.BlockingQueue BlockingQueue} + * on the given file object by object. As this operation is completed, the file writer tries to write the + * next file in the {@link java.util.concurrent.BlockingQueue BlockingQueue} *

*/ private void writeToFile() { try { - for (Message message : messagesQueue.take()) { - //TODO: Save messages in a file + try { + OutputStream outputStream = new FileOutputStream(file); + OutputStream buffer = new BufferedOutputStream(outputStream); + ObjectOutput outputFile = new ObjectOutputStream(buffer); + while (!messagesQueue.isEmpty()) { + for (Message message : messagesQueue.take()) { + outputFile.writeObject(message); + } + } + } catch (FileNotFoundException fileNotFound) { + throw new RuntimeException("Could not find the log file"); + } catch (IOException ioException) { + throw new RuntimeException("Could not write on the log file"); } notifyAll(); } catch (InterruptedException e) { @@ -339,12 +351,9 @@ public void run() { *

*/ private void sendToUINetwork(Message message) { - Callable run = new Callable() { - @Override - public Void call() throws Exception { - uiNetwork.sendBlocking(message); - return null; - } + Callable run = () -> { + uiNetwork.sendBlocking(message); + return null; }; RunnableFuture runnableFuture = new FutureTask<>(run); ExecutorService service = Executors.newSingleThreadExecutor(); From 87851ff387e6019da27b61ee8ea4e8289aa56245 Mon Sep 17 00:00:00 2001 From: alilotfi Date: Sun, 8 Feb 2015 17:47:09 +0330 Subject: [PATCH 40/40] Working copy of previous conflicted commit --- src/server/core/OutputController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/core/OutputController.java b/src/server/core/OutputController.java index 0a2cb34..307f1ec 100644 --- a/src/server/core/OutputController.java +++ b/src/server/core/OutputController.java @@ -4,7 +4,7 @@ import server.network.UINetwork; import server.network.data.Message; -import java.io.File; +import java.io.*; import java.util.LinkedList; import java.util.Timer; import java.util.TimerTask;