From bfe98a2cf0f91207a1e177a81c4c76d984354f90 Mon Sep 17 00:00:00 2001 From: Persson-dev Date: Thu, 23 Jan 2025 22:24:23 +0100 Subject: [PATCH] better network structure --- app/src/main/java/gui/menu/MultiMenu.java | 5 -- app/src/main/java/gui/menu/StateMachine.java | 4 +- app/src/main/java/network/Connexion.java | 12 ++++- .../main/java/network/ConnexionThread.java | 4 +- app/src/main/java/network/PacketFactory.java | 8 --- app/src/main/java/network/PacketVisitor.java | 15 ------ app/src/main/java/network/Packets.java | 7 --- app/src/main/java/network/client/Client.java | 7 ++- .../java/network/client/ClientConnexion.java | 36 +++++++++----- .../java/network/{ => protocol}/Packet.java | 2 +- .../PacketDispatcher.java | 7 +-- .../java/network/protocol/PacketFactory.java | 6 +++ .../java/network/protocol/PacketVisitor.java | 17 +++++++ .../main/java/network/protocol/Packets.java | 7 +++ .../packets/ConnexionInfoPacket.java | 10 ++-- .../protocol/packets/DisconnectPacket.java | 23 +++++++++ .../packets/KeepAlivePacket.java | 10 ++-- .../java/network/server/KeepAliveHandler.java | 49 +++++++++++++++++++ app/src/main/java/network/server/Server.java | 30 ++++++++++-- ...verThread.java => ServerAcceptThread.java} | 6 +-- .../java/network/server/ServerConnexion.java | 48 ++++++++++++------ .../network/server/ServerLogicThread.java | 28 +++++++++++ 22 files changed, 248 insertions(+), 93 deletions(-) delete mode 100644 app/src/main/java/network/PacketFactory.java delete mode 100644 app/src/main/java/network/PacketVisitor.java delete mode 100644 app/src/main/java/network/Packets.java rename app/src/main/java/network/{ => protocol}/Packet.java (87%) rename app/src/main/java/network/{client => protocol}/PacketDispatcher.java (81%) create mode 100644 app/src/main/java/network/protocol/PacketFactory.java create mode 100644 app/src/main/java/network/protocol/PacketVisitor.java create mode 100644 app/src/main/java/network/protocol/Packets.java rename app/src/main/java/network/{ => protocol}/packets/ConnexionInfoPacket.java (68%) create mode 100644 app/src/main/java/network/protocol/packets/DisconnectPacket.java rename app/src/main/java/network/{ => protocol}/packets/KeepAlivePacket.java (67%) create mode 100644 app/src/main/java/network/server/KeepAliveHandler.java rename app/src/main/java/network/server/{ServerThread.java => ServerAcceptThread.java} (83%) create mode 100644 app/src/main/java/network/server/ServerLogicThread.java diff --git a/app/src/main/java/gui/menu/MultiMenu.java b/app/src/main/java/gui/menu/MultiMenu.java index e6e87dc..cecd1fb 100644 --- a/app/src/main/java/gui/menu/MultiMenu.java +++ b/app/src/main/java/gui/menu/MultiMenu.java @@ -6,17 +6,12 @@ import imgui.ImGui; import imgui.ImVec2; import imgui.type.ImInt; import imgui.type.ImString; -import network.client.Client; -import network.server.Server; public class MultiMenu extends BaseView { private final ImInt port = new ImInt(25565); private final ImString address = new ImString("localhost"); - private Server server; - private Client client; - public MultiMenu(StateMachine stateMachine) { super(stateMachine); } diff --git a/app/src/main/java/gui/menu/StateMachine.java b/app/src/main/java/gui/menu/StateMachine.java index c698ac8..9317a25 100644 --- a/app/src/main/java/gui/menu/StateMachine.java +++ b/app/src/main/java/gui/menu/StateMachine.java @@ -27,7 +27,7 @@ public class StateMachine { } public void popState() { - menus.getLast().onKill(); + menus.get(menus.size() - 1).onKill(); menus.pop(); } @@ -43,7 +43,7 @@ public class StateMachine { ImGui.setNextWindowSize(displaySize); ImGui.begin("##Main Window", null, ImGuiWindowFlags.NoDecoration | ImGuiWindowFlags.NoMove | ImGuiWindowFlags.NoSavedSettings | ImGuiWindowFlags.NoBackground); - menus.getLast().render(); + menus.get(menus.size() - 1).render(); ImGui.end(); checkEscape(); } diff --git a/app/src/main/java/network/Connexion.java b/app/src/main/java/network/Connexion.java index 4dd54da..a565012 100644 --- a/app/src/main/java/network/Connexion.java +++ b/app/src/main/java/network/Connexion.java @@ -4,6 +4,9 @@ import java.io.IOException; import java.io.ObjectOutputStream; import java.net.Socket; +import network.protocol.Packet; +import network.protocol.PacketVisitor; + public abstract class Connexion implements PacketVisitor { final Socket socket; @@ -17,8 +20,13 @@ public abstract class Connexion implements PacketVisitor { this.connexionThread.start(); } - public void sendPacket(Packet packet) throws IOException { - objectOutputStream.writeObject(packet); + public void sendPacket(Packet packet) { + try { + objectOutputStream.writeObject(packet); + } catch (IOException e) { + System.err.println("Error while sending packet ! " + e.getLocalizedMessage()); + close(); + } } public void close() { diff --git a/app/src/main/java/network/ConnexionThread.java b/app/src/main/java/network/ConnexionThread.java index 81ab76c..cba97bf 100644 --- a/app/src/main/java/network/ConnexionThread.java +++ b/app/src/main/java/network/ConnexionThread.java @@ -3,6 +3,8 @@ package network; import java.io.IOException; import java.io.ObjectInputStream; +import network.protocol.Packet; + public class ConnexionThread extends Thread{ private final Connexion connexion; @@ -19,7 +21,7 @@ public class ConnexionThread extends Thread{ try { Object o = objectInputStream.readObject(); if (o instanceof Packet packet) { - connexion.visit(packet); + connexion.visitPacket(packet); } } catch (ClassNotFoundException | IOException e) { break; diff --git a/app/src/main/java/network/PacketFactory.java b/app/src/main/java/network/PacketFactory.java deleted file mode 100644 index 45a879a..0000000 --- a/app/src/main/java/network/PacketFactory.java +++ /dev/null @@ -1,8 +0,0 @@ -package network; - -import java.nio.ByteBuffer; - -public class PacketFactory { - - -} diff --git a/app/src/main/java/network/PacketVisitor.java b/app/src/main/java/network/PacketVisitor.java deleted file mode 100644 index 679a8f5..0000000 --- a/app/src/main/java/network/PacketVisitor.java +++ /dev/null @@ -1,15 +0,0 @@ -package network; - -import network.packets.ConnexionInfoPacket; -import network.packets.KeepAlivePacket; - -public interface PacketVisitor { - - default void visit(Packet packet) { - packet.accept(this); - } - - void visit(ConnexionInfoPacket packet); - void visit(KeepAlivePacket packet); - -} diff --git a/app/src/main/java/network/Packets.java b/app/src/main/java/network/Packets.java deleted file mode 100644 index 6132427..0000000 --- a/app/src/main/java/network/Packets.java +++ /dev/null @@ -1,7 +0,0 @@ -package network; - -public enum Packets { - - ConnectionInfo, KeepAlive - -} diff --git a/app/src/main/java/network/client/Client.java b/app/src/main/java/network/client/Client.java index 4b310ed..2baa2a0 100644 --- a/app/src/main/java/network/client/Client.java +++ b/app/src/main/java/network/client/Client.java @@ -7,11 +7,16 @@ public class Client { private final ClientConnexion clientConnection; public Client(String address, short port) throws UnknownHostException, IOException { - this.clientConnection = new ClientConnexion(address, port); + this.clientConnection = new ClientConnexion(address, port, this); } public void stop() { this.clientConnection.close(); } + + public void onDisconnect() { + // do some stuff + System.out.println("OSEKOUR"); + } } diff --git a/app/src/main/java/network/client/ClientConnexion.java b/app/src/main/java/network/client/ClientConnexion.java index 6ff751c..42b2f1c 100644 --- a/app/src/main/java/network/client/ClientConnexion.java +++ b/app/src/main/java/network/client/ClientConnexion.java @@ -5,29 +5,39 @@ import java.net.Socket; import java.net.UnknownHostException; import network.Connexion; -import network.packets.ConnexionInfoPacket; -import network.packets.KeepAlivePacket; +import network.protocol.packets.ConnexionInfoPacket; +import network.protocol.packets.DisconnectPacket; +import network.protocol.packets.KeepAlivePacket; public class ClientConnexion extends Connexion { - public ClientConnexion(String address, short port) throws UnknownHostException, IOException { + private final Client client; + + public ClientConnexion(String address, short port, Client client) throws UnknownHostException, IOException { super(new Socket(address, port)); + this.client = client; } @Override - public void visit(ConnexionInfoPacket packet) { - + public void close() { + super.close(); + client.onDisconnect(); } @Override - public void visit(KeepAlivePacket packet) { - System.out.println("Coucou !!!!!!!!!!!!!!!!!!!"); - try { - sendPacket(packet); - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } + public void visitPacket(ConnexionInfoPacket packet) { + + } + + @Override + public void visitPacket(KeepAlivePacket packet) { + // we just send the packet back to the server + sendPacket(packet); + } + + @Override + public void visitPacket(DisconnectPacket packet) { + close(); } } diff --git a/app/src/main/java/network/Packet.java b/app/src/main/java/network/protocol/Packet.java similarity index 87% rename from app/src/main/java/network/Packet.java rename to app/src/main/java/network/protocol/Packet.java index 3bc5765..d7b4c19 100644 --- a/app/src/main/java/network/Packet.java +++ b/app/src/main/java/network/protocol/Packet.java @@ -1,4 +1,4 @@ -package network; +package network.protocol; import java.io.Serializable; diff --git a/app/src/main/java/network/client/PacketDispatcher.java b/app/src/main/java/network/protocol/PacketDispatcher.java similarity index 81% rename from app/src/main/java/network/client/PacketDispatcher.java rename to app/src/main/java/network/protocol/PacketDispatcher.java index 4a6d490..376ab96 100644 --- a/app/src/main/java/network/client/PacketDispatcher.java +++ b/app/src/main/java/network/protocol/PacketDispatcher.java @@ -1,11 +1,8 @@ -package network.client; +package network.protocol; import java.util.ArrayList; import java.util.List; -import network.Packet; -import network.PacketVisitor; - public class PacketDispatcher { private final List handlers; @@ -16,7 +13,7 @@ public class PacketDispatcher { public void dispatch(Packet packet) { for (PacketVisitor handler : handlers) { - handler.visit(packet); + handler.visitPacket(packet); } } diff --git a/app/src/main/java/network/protocol/PacketFactory.java b/app/src/main/java/network/protocol/PacketFactory.java new file mode 100644 index 0000000..14b2347 --- /dev/null +++ b/app/src/main/java/network/protocol/PacketFactory.java @@ -0,0 +1,6 @@ +package network.protocol; + +public class PacketFactory { + + +} diff --git a/app/src/main/java/network/protocol/PacketVisitor.java b/app/src/main/java/network/protocol/PacketVisitor.java new file mode 100644 index 0000000..73babe1 --- /dev/null +++ b/app/src/main/java/network/protocol/PacketVisitor.java @@ -0,0 +1,17 @@ +package network.protocol; + +import network.protocol.packets.ConnexionInfoPacket; +import network.protocol.packets.DisconnectPacket; +import network.protocol.packets.KeepAlivePacket; + +public interface PacketVisitor { + + default void visitPacket(Packet packet) { + packet.accept(this); + } + + void visitPacket(ConnexionInfoPacket packet); + void visitPacket(DisconnectPacket packet); + void visitPacket(KeepAlivePacket packet); + +} diff --git a/app/src/main/java/network/protocol/Packets.java b/app/src/main/java/network/protocol/Packets.java new file mode 100644 index 0000000..716b9be --- /dev/null +++ b/app/src/main/java/network/protocol/Packets.java @@ -0,0 +1,7 @@ +package network.protocol; + +public enum Packets { + + ConnectionInfo, KeepAlive, Disconnect + +} diff --git a/app/src/main/java/network/packets/ConnexionInfoPacket.java b/app/src/main/java/network/protocol/packets/ConnexionInfoPacket.java similarity index 68% rename from app/src/main/java/network/packets/ConnexionInfoPacket.java rename to app/src/main/java/network/protocol/packets/ConnexionInfoPacket.java index d9a1b9d..5be408b 100644 --- a/app/src/main/java/network/packets/ConnexionInfoPacket.java +++ b/app/src/main/java/network/protocol/packets/ConnexionInfoPacket.java @@ -1,8 +1,8 @@ -package network.packets; +package network.protocol.packets; -import network.Packet; -import network.PacketVisitor; -import network.Packets; +import network.protocol.Packet; +import network.protocol.PacketVisitor; +import network.protocol.Packets; public class ConnexionInfoPacket extends Packet { @@ -20,6 +20,6 @@ public class ConnexionInfoPacket extends Packet { @Override public void accept(PacketVisitor packetVisitor) { - packetVisitor.visit(this); + packetVisitor.visitPacket(this); } } diff --git a/app/src/main/java/network/protocol/packets/DisconnectPacket.java b/app/src/main/java/network/protocol/packets/DisconnectPacket.java new file mode 100644 index 0000000..2d8f854 --- /dev/null +++ b/app/src/main/java/network/protocol/packets/DisconnectPacket.java @@ -0,0 +1,23 @@ +package network.protocol.packets; + +import network.protocol.Packet; +import network.protocol.PacketVisitor; + +public class DisconnectPacket extends Packet { + + private final String reason; + + public DisconnectPacket(String reason) { + this.reason = reason; + } + + public String getReason() { + return reason; + } + + @Override + public void accept(PacketVisitor packetVisitor) { + packetVisitor.visitPacket(this); + } + +} diff --git a/app/src/main/java/network/packets/KeepAlivePacket.java b/app/src/main/java/network/protocol/packets/KeepAlivePacket.java similarity index 67% rename from app/src/main/java/network/packets/KeepAlivePacket.java rename to app/src/main/java/network/protocol/packets/KeepAlivePacket.java index cc4e8c6..5804470 100644 --- a/app/src/main/java/network/packets/KeepAlivePacket.java +++ b/app/src/main/java/network/protocol/packets/KeepAlivePacket.java @@ -1,8 +1,8 @@ -package network.packets; +package network.protocol.packets; -import network.Packet; -import network.PacketVisitor; -import network.Packets; +import network.protocol.Packet; +import network.protocol.PacketVisitor; +import network.protocol.Packets; public class KeepAlivePacket extends Packet { @@ -20,7 +20,7 @@ public class KeepAlivePacket extends Packet { @Override public void accept(PacketVisitor packetVisitor) { - packetVisitor.visit(this); + packetVisitor.visitPacket(this); } } diff --git a/app/src/main/java/network/server/KeepAliveHandler.java b/app/src/main/java/network/server/KeepAliveHandler.java new file mode 100644 index 0000000..ae1ba22 --- /dev/null +++ b/app/src/main/java/network/server/KeepAliveHandler.java @@ -0,0 +1,49 @@ +package network.server; + +import java.util.Random; + +import network.protocol.packets.KeepAlivePacket; + +public class KeepAliveHandler { + + private final ServerConnexion serverConnexion; + + private static final int KEEP_ALIVE_COOLDOWN = 5 * 1000; + + private long lastKeepAlive = 0; + private long lastSend = 0; + private volatile boolean keepAliveRecieved = false; + + public KeepAliveHandler(ServerConnexion serverConnexion) { + this.serverConnexion = serverConnexion; + sendKeepAlive(); + } + + public boolean update() { + var currentTime = System.currentTimeMillis(); + if (currentTime - lastSend > KEEP_ALIVE_COOLDOWN) { + if (keepAliveRecieved) { + sendKeepAlive(); + } else { + System.out.println("Zombie"); + serverConnexion.close(); + return false; + } + } + return true; + } + + public void recievedKeepAlive(long keepAliveId) { + if (lastKeepAlive == keepAliveId) + this.keepAliveRecieved = true; + } + + private void sendKeepAlive() { + Random r = new Random(); + lastKeepAlive = r.nextLong(); + lastSend = System.currentTimeMillis(); + keepAliveRecieved = false; + this.serverConnexion.sendPacket(new KeepAlivePacket(lastKeepAlive)); + } + +} diff --git a/app/src/main/java/network/server/Server.java b/app/src/main/java/network/server/Server.java index 8ba9e0d..ac07cf7 100644 --- a/app/src/main/java/network/server/Server.java +++ b/app/src/main/java/network/server/Server.java @@ -5,21 +5,43 @@ import java.net.ServerSocket; import java.util.ArrayList; import java.util.List; +import network.protocol.Packet; + public class Server { final ServerSocket serverSocket; final List connexions; - private final ServerThread thread; + private final ServerAcceptThread acceptThread; + private final ServerLogicThread logicThread; public Server(short port) throws IOException { this.serverSocket = new ServerSocket(port); this.connexions = new ArrayList<>(); - this.thread = new ServerThread(this); - this.thread.start(); + this.acceptThread = new ServerAcceptThread(this); + this.acceptThread.start(); + this.logicThread = new ServerLogicThread(this); + this.logicThread.start(); + } + + public void broadcastPacket(Packet packet) { + for (ServerConnexion connexion : this.connexions) { + connexion.sendPacket(packet); + } + } + + public void update() { + for (var it = connexions.iterator(); it.hasNext();) { + ServerConnexion connexion = it.next(); + if(!connexion.update()) { + connexion.close(); + it.remove(); + } + } } public void stop() { - this.thread.cancel(); + this.acceptThread.cancel(); + this.logicThread.cancel(); for (ServerConnexion connexion : this.connexions) { connexion.close(); } diff --git a/app/src/main/java/network/server/ServerThread.java b/app/src/main/java/network/server/ServerAcceptThread.java similarity index 83% rename from app/src/main/java/network/server/ServerThread.java rename to app/src/main/java/network/server/ServerAcceptThread.java index 4844be8..61800db 100644 --- a/app/src/main/java/network/server/ServerThread.java +++ b/app/src/main/java/network/server/ServerAcceptThread.java @@ -3,11 +3,11 @@ package network.server; import java.io.IOException; import java.net.Socket; -public class ServerThread extends Thread { +public class ServerAcceptThread extends Thread { private final Server server; - public ServerThread(Server server) { + public ServerAcceptThread(Server server) { this.server = server; } @@ -25,7 +25,7 @@ public class ServerThread extends Thread { try { while(!interrupted()) { Socket newConnection = this.server.serverSocket.accept(); - ServerConnexion serverConnection = new ServerConnexion(newConnection); + ServerConnexion serverConnection = new ServerConnexion(newConnection, this.server); this.server.connexions.add(serverConnection); } } catch(IOException e) { diff --git a/app/src/main/java/network/server/ServerConnexion.java b/app/src/main/java/network/server/ServerConnexion.java index b1ba7a7..9ac20cb 100644 --- a/app/src/main/java/network/server/ServerConnexion.java +++ b/app/src/main/java/network/server/ServerConnexion.java @@ -2,34 +2,50 @@ package network.server; import java.io.IOException; import java.net.Socket; -import java.util.Random; import network.Connexion; -import network.packets.ConnexionInfoPacket; -import network.packets.KeepAlivePacket; +import network.protocol.packets.ConnexionInfoPacket; +import network.protocol.packets.DisconnectPacket; +import network.protocol.packets.KeepAlivePacket; -public class ServerConnexion extends Connexion{ +public class ServerConnexion extends Connexion { - public ServerConnexion(Socket socket) throws IOException { + private final Server server; + private final KeepAliveHandler keepAliveHandler; + private boolean shouldClose = false; + + public ServerConnexion(Socket socket, Server server) throws IOException { super(socket); - System.out.println("Bonjour le client !"); - sendKeepAlive(); + this.server = server; + this.keepAliveHandler = new KeepAliveHandler(this); } - public void sendKeepAlive() throws IOException { - Random r = new Random(); - sendPacket(new KeepAlivePacket(r.nextLong())); + public boolean update() { + if (shouldClose) + return false; + return this.keepAliveHandler.update(); } @Override - public void visit(ConnexionInfoPacket packet) { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'visit'"); + public void close() { + sendPacket(new DisconnectPacket("Server stopped")); + super.close(); + shouldClose = true; } @Override - public void visit(KeepAlivePacket packet) { - System.out.println("Je l'ai reçu !"); + public void visitPacket(ConnexionInfoPacket packet) { + throw new UnsupportedOperationException("Unimplemented method 'visitPacket'"); } - + + @Override + public void visitPacket(KeepAlivePacket packet) { + this.keepAliveHandler.recievedKeepAlive(packet.getKeepAliveId()); + } + + @Override + public void visitPacket(DisconnectPacket packet) { + close(); + } + } diff --git a/app/src/main/java/network/server/ServerLogicThread.java b/app/src/main/java/network/server/ServerLogicThread.java new file mode 100644 index 0000000..c9b2a4b --- /dev/null +++ b/app/src/main/java/network/server/ServerLogicThread.java @@ -0,0 +1,28 @@ +package network.server; + +public class ServerLogicThread extends Thread { + + private final Server server; + + public ServerLogicThread(Server server) { + this.server = server; + } + + public void cancel() { + interrupt(); + } + + @Override + public void run() { + while (!interrupted()) { + server.update(); + try { + Thread.sleep(50); + } catch (InterruptedException e) { + // e.printStackTrace(); + break; + } + } + } + +}