Added full Kryonet server/client implementation

This commit is contained in:
Anuken 2017-12-30 12:28:17 -05:00
parent f6e9710b33
commit e24179cd4c
6 changed files with 256 additions and 91 deletions

View File

@ -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<Class<?>, 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 <T> void handle(Class<T> type, Consumer<T> 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);
}
}

View File

@ -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<Class<?>, Consumer> clientListeners = new ObjectMap<>();
private static ObjectMap<Class<?>, 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 <T> void handle(Class<T> type, Consumer<T> listener){
clientListeners.put(type, listener);
}
/**Registers a server listener for when an object is recieved.*/
public static <T> void handleServer(Class<T> type, Consumer<T> 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 <i>except</i> 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
}
}

View File

@ -0,0 +1,6 @@
package io.anuke.mindustry.net.packets;
public class Connect {
public int id;
public String addressTCP;
}

View File

@ -0,0 +1,6 @@
package io.anuke.mindustry.net.packets;
public class Disconnect {
public int id;
public String addressTCP;
}

View File

@ -0,0 +1,4 @@
package io.anuke.mindustry.net.packets;
public class Packets {
}

View File

@ -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);
}