From 5e99cd92dff5b93984794f0e29d6099c6513cd1a Mon Sep 17 00:00:00 2001 From: Persson-dev Date: Thu, 23 Jan 2025 18:59:11 +0100 Subject: [PATCH] network structure --- app/src/main/java/gui/Main.java | 5 ++ app/src/main/java/gui/menu/BaseView.java | 2 + .../main/java/gui/menu/CreateGameMenu.java | 17 ------ app/src/main/java/gui/menu/JoinGameMenu.java | 17 ------ app/src/main/java/gui/menu/MultiMenu.java | 20 ++++++- .../main/java/gui/menu/MultiPlayerView.java | 58 +++++++++++++++++++ app/src/main/java/gui/menu/StateMachine.java | 8 +++ app/src/main/java/network/Connexion.java | 27 +++++++++ .../main/java/network/ConnexionThread.java | 39 +++++++++++++ app/src/main/java/network/Packet.java | 11 ++++ 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 | 17 ++++++ .../java/network/client/ClientConnexion.java | 33 +++++++++++ .../java/network/client/PacketDispatcher.java | 31 ++++++++++ .../network/packets/ConnexionInfoPacket.java | 25 ++++++++ .../java/network/packets/KeepAlivePacket.java | 26 +++++++++ app/src/main/java/network/server/Server.java | 28 +++++++++ .../java/network/server/ServerConnexion.java | 35 +++++++++++ .../java/network/server/ServerThread.java | 36 ++++++++++++ 21 files changed, 429 insertions(+), 36 deletions(-) delete mode 100644 app/src/main/java/gui/menu/CreateGameMenu.java delete mode 100644 app/src/main/java/gui/menu/JoinGameMenu.java create mode 100644 app/src/main/java/gui/menu/MultiPlayerView.java create mode 100644 app/src/main/java/network/Connexion.java create mode 100644 app/src/main/java/network/ConnexionThread.java create mode 100644 app/src/main/java/network/Packet.java create mode 100644 app/src/main/java/network/PacketFactory.java create mode 100644 app/src/main/java/network/PacketVisitor.java create mode 100644 app/src/main/java/network/Packets.java create mode 100644 app/src/main/java/network/client/Client.java create mode 100644 app/src/main/java/network/client/ClientConnexion.java create mode 100644 app/src/main/java/network/client/PacketDispatcher.java create mode 100644 app/src/main/java/network/packets/ConnexionInfoPacket.java create mode 100644 app/src/main/java/network/packets/KeepAlivePacket.java create mode 100644 app/src/main/java/network/server/Server.java create mode 100644 app/src/main/java/network/server/ServerConnexion.java create mode 100644 app/src/main/java/network/server/ServerThread.java diff --git a/app/src/main/java/gui/Main.java b/app/src/main/java/gui/Main.java index f751b4b..50ca9a6 100644 --- a/app/src/main/java/gui/Main.java +++ b/app/src/main/java/gui/Main.java @@ -15,6 +15,11 @@ public class Main extends Application { config.setTitle("Let's play sudoku!"); } + @Override + protected void disposeWindow() { + stateMachine.clear(); + } + @Override protected void initImGui(Configuration config) { super.initImGui(config); diff --git a/app/src/main/java/gui/menu/BaseView.java b/app/src/main/java/gui/menu/BaseView.java index 317fdce..9992279 100644 --- a/app/src/main/java/gui/menu/BaseView.java +++ b/app/src/main/java/gui/menu/BaseView.java @@ -12,6 +12,8 @@ public abstract class BaseView { public abstract void render(); + public void onKill() {} + public void closeMenu() { this.stateMachine.popState(); } diff --git a/app/src/main/java/gui/menu/CreateGameMenu.java b/app/src/main/java/gui/menu/CreateGameMenu.java deleted file mode 100644 index 9b99af7..0000000 --- a/app/src/main/java/gui/menu/CreateGameMenu.java +++ /dev/null @@ -1,17 +0,0 @@ -package gui.menu; - -import imgui.ImGui; - -public class CreateGameMenu extends BaseView { - - public CreateGameMenu(StateMachine stateMachine) { - super(stateMachine); - } - - @Override - public void render() { - ImGui.text("Créer"); - renderReturnButton(); - } - -} diff --git a/app/src/main/java/gui/menu/JoinGameMenu.java b/app/src/main/java/gui/menu/JoinGameMenu.java deleted file mode 100644 index cc64558..0000000 --- a/app/src/main/java/gui/menu/JoinGameMenu.java +++ /dev/null @@ -1,17 +0,0 @@ -package gui.menu; - -import imgui.ImGui; - -public class JoinGameMenu extends BaseView { - - public JoinGameMenu(StateMachine stateMachine) { - super(stateMachine); - } - - @Override - public void render() { - ImGui.text("Rejoindre"); - renderReturnButton(); - } - -} diff --git a/app/src/main/java/gui/menu/MultiMenu.java b/app/src/main/java/gui/menu/MultiMenu.java index 9a23a3f..e6e87dc 100644 --- a/app/src/main/java/gui/menu/MultiMenu.java +++ b/app/src/main/java/gui/menu/MultiMenu.java @@ -1,15 +1,22 @@ package gui.menu; +import java.io.IOException; + 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); } @@ -19,7 +26,11 @@ public class MultiMenu extends BaseView { ImGui.beginChild("##CreateGame", new ImVec2(displaySize.x / 2.0f, displaySize.y * 8.0f / 9.0f)); ImGui.inputInt("Port", port); if (ImGui.button("Créer")) { - // TODO: create game + try { + this.stateMachine.pushState(new MultiPlayerView(stateMachine, (short) port.get())); + } catch (IOException e) { + e.printStackTrace(); + } } ImGui.endChild(); } @@ -30,7 +41,12 @@ public class MultiMenu extends BaseView { ImGui.inputText("Adresse", address); ImGui.inputInt("Port", port); if (ImGui.button("Rejoindre")) { - // TODO: join game + try { + this.stateMachine.pushState(new MultiPlayerView(stateMachine, address.get(), (short) port.get())); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } } ImGui.endChild(); } diff --git a/app/src/main/java/gui/menu/MultiPlayerView.java b/app/src/main/java/gui/menu/MultiPlayerView.java new file mode 100644 index 0000000..3646f1c --- /dev/null +++ b/app/src/main/java/gui/menu/MultiPlayerView.java @@ -0,0 +1,58 @@ +package gui.menu; + +import java.io.IOException; +import java.net.UnknownHostException; + +import imgui.ImGui; +import network.client.Client; +import network.server.Server; + +public class MultiPlayerView extends BaseView { + + private Client client; + private Server server; + + /** + * Client + * + * @param stateMachine + * @param address + * @param port + * @throws IOException + * @throws UnknownHostException + */ + public MultiPlayerView(StateMachine stateMachine, String address, short port) + throws UnknownHostException, IOException { + super(stateMachine); + this.client = new Client(address, port); + } + + /** + * Server + * + * @param stateMachine + * @param port + * @throws IOException + */ + public MultiPlayerView(StateMachine stateMachine, short port) throws IOException { + super(stateMachine); + this.server = new Server(port); + this.client = new Client("localhost", port); + } + + @Override + public void onKill() { + if (this.server != null) { + this.server.stop(); + } + if (this.client != null) { + this.client.stop(); + } + } + + @Override + public void render() { + ImGui.text("Tema le gameplay"); + } + +} diff --git a/app/src/main/java/gui/menu/StateMachine.java b/app/src/main/java/gui/menu/StateMachine.java index db25a51..c698ac8 100644 --- a/app/src/main/java/gui/menu/StateMachine.java +++ b/app/src/main/java/gui/menu/StateMachine.java @@ -15,11 +15,19 @@ public class StateMachine { this.menus = new Stack<>(); } + public void clear() { + for (BaseView view : menus) { + view.onKill(); + } + menus.clear(); + } + public void pushState(BaseView menu) { menus.add(menu); } public void popState() { + menus.getLast().onKill(); menus.pop(); } diff --git a/app/src/main/java/network/Connexion.java b/app/src/main/java/network/Connexion.java new file mode 100644 index 0000000..4dd54da --- /dev/null +++ b/app/src/main/java/network/Connexion.java @@ -0,0 +1,27 @@ +package network; + +import java.io.IOException; +import java.io.ObjectOutputStream; +import java.net.Socket; + +public abstract class Connexion implements PacketVisitor { + + final Socket socket; + private final ObjectOutputStream objectOutputStream; + private final ConnexionThread connexionThread; + + public Connexion(Socket socket) throws IOException { + this.socket = socket; + this.objectOutputStream = new ObjectOutputStream(this.socket.getOutputStream()); + this.connexionThread = new ConnexionThread(this); + this.connexionThread.start(); + } + + public void sendPacket(Packet packet) throws IOException { + objectOutputStream.writeObject(packet); + } + + public void close() { + this.connexionThread.cancel(); + } +} diff --git a/app/src/main/java/network/ConnexionThread.java b/app/src/main/java/network/ConnexionThread.java new file mode 100644 index 0000000..81ab76c --- /dev/null +++ b/app/src/main/java/network/ConnexionThread.java @@ -0,0 +1,39 @@ +package network; + +import java.io.IOException; +import java.io.ObjectInputStream; + +public class ConnexionThread extends Thread{ + + private final Connexion connexion; + private final ObjectInputStream objectInputStream; + + public ConnexionThread(Connexion connexion) throws IOException { + this.connexion = connexion; + this.objectInputStream = new ObjectInputStream(this.connexion.socket.getInputStream()); + } + + @Override + public void run() { + while(!interrupted()) { + try { + Object o = objectInputStream.readObject(); + if (o instanceof Packet packet) { + connexion.visit(packet); + } + } catch (ClassNotFoundException | IOException e) { + break; + } + } + } + + public void cancel() { + try { + objectInputStream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + interrupt(); + } + +} diff --git a/app/src/main/java/network/Packet.java b/app/src/main/java/network/Packet.java new file mode 100644 index 0000000..3bc5765 --- /dev/null +++ b/app/src/main/java/network/Packet.java @@ -0,0 +1,11 @@ +package network; + +import java.io.Serializable; + +public abstract class Packet implements Serializable { + + // public abstract int getId(); + + public abstract void accept(PacketVisitor packetVisitor); + +} diff --git a/app/src/main/java/network/PacketFactory.java b/app/src/main/java/network/PacketFactory.java new file mode 100644 index 0000000..45a879a --- /dev/null +++ b/app/src/main/java/network/PacketFactory.java @@ -0,0 +1,8 @@ +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 new file mode 100644 index 0000000..679a8f5 --- /dev/null +++ b/app/src/main/java/network/PacketVisitor.java @@ -0,0 +1,15 @@ +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 new file mode 100644 index 0000000..6132427 --- /dev/null +++ b/app/src/main/java/network/Packets.java @@ -0,0 +1,7 @@ +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 new file mode 100644 index 0000000..4b310ed --- /dev/null +++ b/app/src/main/java/network/client/Client.java @@ -0,0 +1,17 @@ +package network.client; + +import java.io.IOException; +import java.net.UnknownHostException; + +public class Client { + private final ClientConnexion clientConnection; + + public Client(String address, short port) throws UnknownHostException, IOException { + this.clientConnection = new ClientConnexion(address, port); + } + + public void stop() { + this.clientConnection.close(); + } + +} diff --git a/app/src/main/java/network/client/ClientConnexion.java b/app/src/main/java/network/client/ClientConnexion.java new file mode 100644 index 0000000..6ff751c --- /dev/null +++ b/app/src/main/java/network/client/ClientConnexion.java @@ -0,0 +1,33 @@ +package network.client; + +import java.io.IOException; +import java.net.Socket; +import java.net.UnknownHostException; + +import network.Connexion; +import network.packets.ConnexionInfoPacket; +import network.packets.KeepAlivePacket; + +public class ClientConnexion extends Connexion { + + public ClientConnexion(String address, short port) throws UnknownHostException, IOException { + super(new Socket(address, port)); + } + + @Override + public void visit(ConnexionInfoPacket packet) { + + } + + @Override + public void visit(KeepAlivePacket packet) { + System.out.println("Coucou !!!!!!!!!!!!!!!!!!!"); + try { + sendPacket(packet); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + +} diff --git a/app/src/main/java/network/client/PacketDispatcher.java b/app/src/main/java/network/client/PacketDispatcher.java new file mode 100644 index 0000000..4a6d490 --- /dev/null +++ b/app/src/main/java/network/client/PacketDispatcher.java @@ -0,0 +1,31 @@ +package network.client; + +import java.util.ArrayList; +import java.util.List; + +import network.Packet; +import network.PacketVisitor; + +public class PacketDispatcher { + + private final List handlers; + + public PacketDispatcher() { + this.handlers = new ArrayList<>(); + } + + public void dispatch(Packet packet) { + for (PacketVisitor handler : handlers) { + handler.visit(packet); + } + } + + public void registerHandler(PacketVisitor handler) { + handlers.add(handler); + } + + public void unregisterHandler(PacketVisitor handler) { + handlers.remove(handler); + } + +} diff --git a/app/src/main/java/network/packets/ConnexionInfoPacket.java b/app/src/main/java/network/packets/ConnexionInfoPacket.java new file mode 100644 index 0000000..d9a1b9d --- /dev/null +++ b/app/src/main/java/network/packets/ConnexionInfoPacket.java @@ -0,0 +1,25 @@ +package network.packets; + +import network.Packet; +import network.PacketVisitor; +import network.Packets; + +public class ConnexionInfoPacket extends Packet { + + static private final long serialVersionUID = Packets.ConnectionInfo.ordinal(); + + private final int connectionId; + + public ConnexionInfoPacket(int connectionId) { + this.connectionId = connectionId; + } + + public int getConnectionId() { + return connectionId; + } + + @Override + public void accept(PacketVisitor packetVisitor) { + packetVisitor.visit(this); + } +} diff --git a/app/src/main/java/network/packets/KeepAlivePacket.java b/app/src/main/java/network/packets/KeepAlivePacket.java new file mode 100644 index 0000000..cc4e8c6 --- /dev/null +++ b/app/src/main/java/network/packets/KeepAlivePacket.java @@ -0,0 +1,26 @@ +package network.packets; + +import network.Packet; +import network.PacketVisitor; +import network.Packets; + +public class KeepAlivePacket extends Packet { + + static private final long serialVersionUID = Packets.KeepAlive.ordinal(); + + private final long keepAliveId; + + public KeepAlivePacket(long keepAliveId) { + this.keepAliveId = keepAliveId; + } + + public long getKeepAliveId() { + return keepAliveId; + } + + @Override + public void accept(PacketVisitor packetVisitor) { + packetVisitor.visit(this); + } + +} diff --git a/app/src/main/java/network/server/Server.java b/app/src/main/java/network/server/Server.java new file mode 100644 index 0000000..8ba9e0d --- /dev/null +++ b/app/src/main/java/network/server/Server.java @@ -0,0 +1,28 @@ +package network.server; + +import java.io.IOException; +import java.net.ServerSocket; +import java.util.ArrayList; +import java.util.List; + +public class Server { + + final ServerSocket serverSocket; + final List connexions; + private final ServerThread thread; + + public Server(short port) throws IOException { + this.serverSocket = new ServerSocket(port); + this.connexions = new ArrayList<>(); + this.thread = new ServerThread(this); + this.thread.start(); + } + + public void stop() { + this.thread.cancel(); + for (ServerConnexion connexion : this.connexions) { + connexion.close(); + } + } + +} diff --git a/app/src/main/java/network/server/ServerConnexion.java b/app/src/main/java/network/server/ServerConnexion.java new file mode 100644 index 0000000..b1ba7a7 --- /dev/null +++ b/app/src/main/java/network/server/ServerConnexion.java @@ -0,0 +1,35 @@ +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; + +public class ServerConnexion extends Connexion{ + + public ServerConnexion(Socket socket) throws IOException { + super(socket); + System.out.println("Bonjour le client !"); + sendKeepAlive(); + } + + public void sendKeepAlive() throws IOException { + Random r = new Random(); + sendPacket(new KeepAlivePacket(r.nextLong())); + } + + @Override + public void visit(ConnexionInfoPacket packet) { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'visit'"); + } + + @Override + public void visit(KeepAlivePacket packet) { + System.out.println("Je l'ai reçu !"); + } + +} diff --git a/app/src/main/java/network/server/ServerThread.java b/app/src/main/java/network/server/ServerThread.java new file mode 100644 index 0000000..4844be8 --- /dev/null +++ b/app/src/main/java/network/server/ServerThread.java @@ -0,0 +1,36 @@ +package network.server; + +import java.io.IOException; +import java.net.Socket; + +public class ServerThread extends Thread { + + private final Server server; + + public ServerThread(Server server) { + this.server = server; + } + + public void cancel() { + try { + this.server.serverSocket.close(); + } catch (IOException e) { + e.printStackTrace(); + } + interrupt(); + } + + @Override + public void run() { + try { + while(!interrupted()) { + Socket newConnection = this.server.serverSocket.accept(); + ServerConnexion serverConnection = new ServerConnexion(newConnection); + this.server.connexions.add(serverConnection); + } + } catch(IOException e) { + // e.printStackTrace(); + } + } + +}