From e24179cd4ce058a27a10c33ea33c809032d9eacf Mon Sep 17 00:00:00 2001 From: Anuken Date: Sat, 30 Dec 2017 12:28:17 -0500 Subject: [PATCH] Added full Kryonet server/client implementation --- core/src/io/anuke/mindustry/Net.java | 86 ------------ core/src/io/anuke/mindustry/net/Net.java | 123 ++++++++++++++++++ .../anuke/mindustry/net/packets/Connect.java | 6 + .../mindustry/net/packets/Disconnect.java | 6 + .../anuke/mindustry/net/packets/Packets.java | 4 + .../mindustry/desktop/DesktopLauncher.java | 122 ++++++++++++++++- 6 files changed, 256 insertions(+), 91 deletions(-) delete mode 100644 core/src/io/anuke/mindustry/Net.java create mode 100644 core/src/io/anuke/mindustry/net/Net.java create mode 100644 core/src/io/anuke/mindustry/net/packets/Connect.java create mode 100644 core/src/io/anuke/mindustry/net/packets/Disconnect.java create mode 100644 core/src/io/anuke/mindustry/net/packets/Packets.java diff --git a/core/src/io/anuke/mindustry/Net.java b/core/src/io/anuke/mindustry/Net.java deleted file mode 100644 index 8bbb356900..0000000000 --- a/core/src/io/anuke/mindustry/Net.java +++ /dev/null @@ -1,86 +0,0 @@ -package io.anuke.mindustry; - -import java.io.IOException; - -import com.badlogic.gdx.Gdx; -import com.badlogic.gdx.utils.ObjectMap; - -import io.anuke.ucore.function.Consumer; - -//TODO stub -public class Net{ - private static boolean server; - private static boolean active; - private static ObjectMap, Consumer> listeners = new ObjectMap<>(); - private static ClientProvider clientProvider; - private static ServerProvider serverProvider; - - /**Connect to an address.*/ - public static void connect(String ip, String port) throws IOException{ - clientProvider.connect(ip, port); - } - - /**Host a server at an address*/ - public static void host(String port) throws IOException{ - serverProvider.host(port); - } - - /**Send an object to all connected clients, or to the server if this is a client.*/ - public static void send(Object object){ - if(server){ - serverProvider.send(object); - }else { - clientProvider.send(object); - } - } - - /**Sets the net clientProvider, e.g. what handles sending, recieving and connecting to a server.*/ - public static void setClientProvider(ClientProvider provider){ - Net.clientProvider = provider; - } - - /**Sets the net serverProvider, e.g. what handles hosting a server.*/ - public static void setServerProvider(ServerProvider provider){ - Net.serverProvider = provider; - } - - /**Registers a client listener for when an object is recieved.*/ - public static void handle(Class type, Consumer listener){ - listeners.put(type, listener); - } - - /**Call to handle a packet being recieved (for the client).*/ - public static void handleNetReceived(Object object){ - if(listeners.get(object.getClass()) != null){ - listeners.get(object.getClass()).accept(object); - }else{ - Gdx.app.error("Mindustry::Net", "Unhandled packet type: '" + object.getClass() + "'!"); - } - } - - /**Whether the net is active, e.g. whether this is a multiplayer game.*/ - public static boolean active(){ - return active; - } - - /**Whether this is a server or not.*/ - public static boolean server(){ - return server; - } - - public static void registerClasses(Class... classes){ - clientProvider.register(classes); - } - - public static interface ClientProvider { - public void connect(String ip, String port) throws IOException; - public void send(Object object); - public void register(Class... types); - } - - public static interface ServerProvider { - public void host(String port) throws IOException; - public void send(Object object); - public void register(Class... types); - } -} diff --git a/core/src/io/anuke/mindustry/net/Net.java b/core/src/io/anuke/mindustry/net/Net.java new file mode 100644 index 0000000000..c2b8afe1c1 --- /dev/null +++ b/core/src/io/anuke/mindustry/net/Net.java @@ -0,0 +1,123 @@ +package io.anuke.mindustry.net; + +import java.io.IOException; + +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.utils.ObjectMap; + +import io.anuke.ucore.function.Consumer; + +//TODO stub +public class Net{ + private static boolean server; + private static boolean active; + private static ObjectMap, Consumer> clientListeners = new ObjectMap<>(); + private static ObjectMap, Consumer> serverListeners = new ObjectMap<>(); + private static ClientProvider clientProvider; + private static ServerProvider serverProvider; + + /**Connect to an address.*/ + public static void connect(String ip, int port) throws IOException{ + clientProvider.connect(ip, port); + } + + /**Host a server at an address*/ + public static void host(int port) throws IOException{ + serverProvider.host(port); + } + + /**Send an object to all connected clients, or to the server if this is a client.*/ + public static void send(Object object, SendMode mode){ + if(server){ + serverProvider.send(object, mode); + }else { + clientProvider.send(object, mode); + } + } + + /**Sets the net clientProvider, e.g. what handles sending, recieving and connecting to a server.*/ + public static void setClientProvider(ClientProvider provider){ + Net.clientProvider = provider; + } + + /**Sets the net serverProvider, e.g. what handles hosting a server.*/ + public static void setServerProvider(ServerProvider provider){ + Net.serverProvider = provider; + } + + /**Registers a client listener for when an object is recieved.*/ + public static void handle(Class type, Consumer listener){ + clientListeners.put(type, listener); + } + + /**Registers a server listener for when an object is recieved.*/ + public static void handleServer(Class type, Consumer listener){ + serverListeners.put(type, listener); + } + + /**Call to handle a packet being recieved for the client.*/ + public static void handleClientReceived(Object object){ + if(clientListeners.get(object.getClass()) != null){ + clientListeners.get(object.getClass()).accept(object); + }else{ + Gdx.app.error("Mindustry::Net", "Unhandled packet type: '" + object.getClass() + "'!"); + } + } + + /**Call to handle a packet being recieved for the server.*/ + public static void handleServerReceived(Object object){ + if(serverListeners.get(object.getClass()) != null){ + serverListeners.get(object.getClass()).accept(object); + }else{ + Gdx.app.error("Mindustry::Net", "Unhandled packet type: '" + object.getClass() + "'!"); + } + } + + /**Whether the net is active, e.g. whether this is a multiplayer game.*/ + public static boolean active(){ + return active; + } + + /**Whether this is a server or not.*/ + public static boolean server(){ + return server; + } + + /**Register classes that will be sent. Must be done for all classes.*/ + public static void registerClasses(Class... classes){ + clientProvider.register(classes); + serverProvider.register(classes); + } + + /**Client implementation.*/ + public static interface ClientProvider { + /**Connect to a server.*/ + public void connect(String ip, int port) throws IOException; + /**Send an object to the server.*/ + public void send(Object object, SendMode mode); + /**Update the ping. Should be done every second or so.*/ + public void updatePing(); + /**Get ping in milliseconds. Will only be valid after a call to updatePing.*/ + public int getPing(); + /**Register classes to be sent.*/ + public void register(Class... types); + } + + /**Server implementation.*/ + public static interface ServerProvider { + /**Host a server at specified port.*/ + public void host(int port) throws IOException; + /**Send an object to everyone connected.*/ + public void send(Object object, SendMode mode); + /**Send an object to a specific client ID.*/ + public void sendTo(int id, Object object, SendMode mode); + /**Send an object to everyone except a client ID.*/ + public void sendExcept(int id, Object object, SendMode mode); + /**Register classes to be sent.*/ + public void register(Class... types); + } + + public enum SendMode{ + tcp, udp + } +} diff --git a/core/src/io/anuke/mindustry/net/packets/Connect.java b/core/src/io/anuke/mindustry/net/packets/Connect.java new file mode 100644 index 0000000000..6c0c2280d5 --- /dev/null +++ b/core/src/io/anuke/mindustry/net/packets/Connect.java @@ -0,0 +1,6 @@ +package io.anuke.mindustry.net.packets; + +public class Connect { + public int id; + public String addressTCP; +} diff --git a/core/src/io/anuke/mindustry/net/packets/Disconnect.java b/core/src/io/anuke/mindustry/net/packets/Disconnect.java new file mode 100644 index 0000000000..990254d998 --- /dev/null +++ b/core/src/io/anuke/mindustry/net/packets/Disconnect.java @@ -0,0 +1,6 @@ +package io.anuke.mindustry.net.packets; + +public class Disconnect { + public int id; + public String addressTCP; +} diff --git a/core/src/io/anuke/mindustry/net/packets/Packets.java b/core/src/io/anuke/mindustry/net/packets/Packets.java new file mode 100644 index 0000000000..c980d0f1ab --- /dev/null +++ b/core/src/io/anuke/mindustry/net/packets/Packets.java @@ -0,0 +1,4 @@ +package io.anuke.mindustry.net.packets; + +public class Packets { +} diff --git a/desktop/src/io/anuke/mindustry/desktop/DesktopLauncher.java b/desktop/src/io/anuke/mindustry/desktop/DesktopLauncher.java index 63dd525ce2..c0178ce039 100644 --- a/desktop/src/io/anuke/mindustry/desktop/DesktopLauncher.java +++ b/desktop/src/io/anuke/mindustry/desktop/DesktopLauncher.java @@ -13,11 +13,18 @@ import com.badlogic.gdx.backends.lwjgl3.Lwjgl3ApplicationConfiguration; import com.badlogic.gdx.utils.Array; import com.esotericsoftware.kryonet.Client; +import com.esotericsoftware.kryonet.Connection; +import com.esotericsoftware.kryonet.Listener; +import com.esotericsoftware.kryonet.Server; import io.anuke.mindustry.Mindustry; -import io.anuke.mindustry.Net; -import io.anuke.mindustry.Net.ClientProvider; +import io.anuke.mindustry.net.Net; +import io.anuke.mindustry.net.Net.ClientProvider; +import io.anuke.mindustry.net.Net.SendMode; import io.anuke.mindustry.Vars; import io.anuke.mindustry.io.PlatformFunction; +import io.anuke.mindustry.net.Net.ServerProvider; +import io.anuke.mindustry.net.packets.Connect; +import io.anuke.mindustry.net.packets.Disconnect; import io.anuke.ucore.scene.ui.TextField; public class DesktopLauncher { @@ -66,16 +73,51 @@ public class DesktopLauncher { { client = new Client(); + client.start(); + client.addListener(new Listener(){ + @Override + public void connected (Connection connection) { + Connect c = new Connect(); + c.id = connection.getID(); + c.addressTCP = connection.getRemoteAddressTCP().toString(); + Net.handleClientReceived(c); + } + + @Override + public void disconnected (Connection connection) { + Disconnect c = new Disconnect(); + Net.handleClientReceived(c); + } + + @Override + public void received (Connection connection, Object object) { + Net.handleClientReceived(object); + } + }); } @Override - public void connect(String ip, String port) throws IOException { - + public void connect(String ip, int port) throws IOException { + client.connect(5000, ip, port, port); } @Override - public void send(Object object) { + public void send(Object object, SendMode mode) { + if(mode == SendMode.tcp){ + client.sendTCP(object); + }else{ + client.sendUDP(object); + } + } + @Override + public void updatePing() { + client.updateReturnTripTime(); + } + + @Override + public int getPing() { + return client.getReturnTripTime(); } @Override @@ -85,6 +127,76 @@ public class DesktopLauncher { } } }); + + Net.setServerProvider(new ServerProvider() { + Server server; + + { + server = new Server(); + server.start(); + server.addListener(new Listener(){ + @Override + public void connected (Connection connection) { + Connect c = new Connect(); + c.id = connection.getID(); + c.addressTCP = connection.getRemoteAddressTCP().toString(); + Net.handleClientReceived(c); + } + + @Override + public void disconnected (Connection connection) { + Disconnect c = new Disconnect(); + c.id = connection.getID(); + c.addressTCP = connection.getRemoteAddressTCP().toString(); + Net.handleClientReceived(c); + } + + @Override + public void received (Connection connection, Object object) { + Net.handleServerReceived(object); + } + }); + } + + @Override + public void host(int port) throws IOException { + server.bind(port, port); + } + + @Override + public void send(Object object, SendMode mode) { + if(mode == SendMode.tcp){ + server.sendToAllTCP(object); + }else{ + server.sendToAllUDP(object); + } + } + + @Override + public void sendTo(int id, Object object, SendMode mode) { + if(mode == SendMode.tcp){ + server.sendToTCP(id, object); + }else{ + server.sendToUDP(id, object); + } + } + + @Override + public void sendExcept(int id, Object object, SendMode mode) { + if(mode == SendMode.tcp){ + server.sendToAllExceptTCP(id, object); + }else{ + server.sendToAllExceptUDP(id, object); + } + } + + @Override + public void register(Class... types) { + for(Class c : types){ + server.getKryo().register(c); + } + } + }); new Lwjgl3Application(new Mindustry(), config); }