diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml
index 68e1fba775..a111ec0bae 100644
--- a/android/AndroidManifest.xml
+++ b/android/AndroidManifest.xml
@@ -7,7 +7,7 @@
-
+
, Consumer>> listeners = new ObjectMap<>();
- private static NetProvider provider;
-
- /**Connect to an address.*/
- public static void connect(String ip, String port) throws IOException{
- provider.connect(ip, port);
- }
-
- /**Send an object to all connected clients.*/
- public static void send(Object object){
- provider.send(object);
- }
-
- /**Sets the net provider, e.g. what handles sending, recieving and connecting.*/
- public static void setProvider(NetProvider provider){
- Net.provider = provider;
- }
-
- /**Registers a 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.*/
- public static void handleNetReceived(Object object){
- if(listeners.get(object.getClass()) != null){
-
- }else{
- Gdx.app.error("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 interface NetProvider{
- public void connect(String ip, String port) throws IOException;
- public void send(Object object);
- }
-}
diff --git a/core/src/io/anuke/mindustry/Vars.java b/core/src/io/anuke/mindustry/Vars.java
index 7cd08e69d1..d2048a193e 100644
--- a/core/src/io/anuke/mindustry/Vars.java
+++ b/core/src/io/anuke/mindustry/Vars.java
@@ -3,7 +3,6 @@ package io.anuke.mindustry;
import com.badlogic.gdx.Application.ApplicationType;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.files.FileHandle;
-import com.badlogic.gdx.utils.I18NBundle;
import io.anuke.mindustry.core.*;
import io.anuke.mindustry.entities.Player;
@@ -72,11 +71,16 @@ public class Vars{
public static final float multiplier = android ? 3 : 2;
public static final int tilesize = 8;
+
+ //server port
+ public static final int port = 6567;
public static Control control;
public static Renderer renderer;
public static UI ui;
public static World world;
+ public static NetServer netServer;
+ public static NetClient netClient;
public static Player player;
diff --git a/core/src/io/anuke/mindustry/core/NetClient.java b/core/src/io/anuke/mindustry/core/NetClient.java
index 7e2c4c4141..ebd61cbfe8 100644
--- a/core/src/io/anuke/mindustry/core/NetClient.java
+++ b/core/src/io/anuke/mindustry/core/NetClient.java
@@ -1,5 +1,7 @@
package io.anuke.mindustry.core;
+import io.anuke.mindustry.core.GameState.State;
+import io.anuke.mindustry.net.Net;
import com.badlogic.gdx.Gdx;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.core.GameState.State;
diff --git a/core/src/io/anuke/mindustry/core/NetServer.java b/core/src/io/anuke/mindustry/core/NetServer.java
new file mode 100644
index 0000000000..fcc7495b0e
--- /dev/null
+++ b/core/src/io/anuke/mindustry/core/NetServer.java
@@ -0,0 +1,25 @@
+package io.anuke.mindustry.core;
+
+import io.anuke.mindustry.Vars;
+import io.anuke.mindustry.core.GameState.State;
+import io.anuke.mindustry.net.Net;
+import io.anuke.ucore.modules.Module;
+
+import java.io.IOException;
+
+public class NetServer extends Module{
+
+ public NetServer(){
+
+ }
+
+ public void update(){
+ if(!Net.server()) return;
+
+ if(!GameState.is(State.menu) && Net.active()){
+
+ }else{
+ Net.closeServer();
+ }
+ }
+}
diff --git a/core/src/io/anuke/mindustry/core/Network.java b/core/src/io/anuke/mindustry/core/Network.java
deleted file mode 100644
index 8b0de963ea..0000000000
--- a/core/src/io/anuke/mindustry/core/Network.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package io.anuke.mindustry.core;
-
-import io.anuke.ucore.modules.Module;
-
-public class Network extends Module{
- //TODO implementation
-}
diff --git a/core/src/io/anuke/mindustry/core/UI.java b/core/src/io/anuke/mindustry/core/UI.java
index 79b08f37b9..73d8260315 100644
--- a/core/src/io/anuke/mindustry/core/UI.java
+++ b/core/src/io/anuke/mindustry/core/UI.java
@@ -22,6 +22,7 @@ import io.anuke.mindustry.Vars;
import io.anuke.mindustry.core.GameState.State;
import io.anuke.mindustry.mapeditor.MapEditor;
import io.anuke.mindustry.mapeditor.MapEditorDialog;
+import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.ui.*;
import io.anuke.mindustry.ui.fragments.*;
import io.anuke.mindustry.world.Tile;
@@ -42,24 +43,29 @@ import io.anuke.ucore.scene.builders.label;
import io.anuke.ucore.scene.builders.table;
import io.anuke.ucore.scene.event.Touchable;
import io.anuke.ucore.scene.ui.*;
+import io.anuke.ucore.scene.ui.TextField.TextFieldFilter;
+import io.anuke.ucore.scene.ui.TextField.TextFieldFilter.DigitsOnlyFilter;
import io.anuke.ucore.scene.ui.Window.WindowStyle;
import io.anuke.ucore.scene.ui.layout.Table;
import io.anuke.ucore.scene.ui.layout.Unit;
import io.anuke.ucore.util.Bundles;
+import io.anuke.ucore.util.Strings;
import javax.tools.Tool;
+import java.io.IOException;
public class UI extends SceneModule{
- Table loadingtable, desctable, configtable;
+ Table loadingtable, configtable;
MindustrySettingsDialog prefs;
MindustryKeybindDialog keys;
MapEditorDialog editorDialog;
- Dialog about, restart, levels, upgrades, load, settingserror, gameerror, discord;
+ Dialog about, restart, levels, upgrades, load, settingserror, gameerror, discord, join;
MenuDialog menu;
Tooltip tooltip;
Tile configTile;
- Array statlist = new Array<>();
MapEditor editor;
+ String lastip = "localhost";
+ int lastport = Vars.port;
boolean wasPaused = false;
private Fragment menufrag = new MenuFragment(),
@@ -67,9 +73,6 @@ public class UI extends SceneModule{
hudfrag = new HudFragment(),
placefrag = new PlacementFragment(),
weaponfrag = new WeaponFragment();
-
- VisibilityProvider play = () -> !GameState.is(State.menu);
- VisibilityProvider nplay = () -> GameState.is(State.menu);
public UI() {
Dialog.setShowAction(()-> sequence(
@@ -155,7 +158,7 @@ public class UI extends SceneModule{
public void update(){
if(Vars.debug && !Vars.showUI) return;
- if(nplay.visible()){
+ if(GameState.is(State.menu)){
scene.getBatch().getProjectionMatrix().setToOrtho2D(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
scene.getBatch().begin();
@@ -186,13 +189,32 @@ public class UI extends SceneModule{
editor = new MapEditor();
editorDialog = new MapEditorDialog(editor);
}
+
+ join = new FloatingDialog("$text.joingame.title");
+ join.content().add("$text.joingame.ip").left();
+ join.content().addField("localhost", text -> lastip = text).size(180f, 54f);
+ join.content().row();
+ join.content().add("$text.server.port").left();
+ join.content().addField(Vars.port + "", new DigitsOnlyFilter(), text -> lastport = Strings.parseInt(text)).size(180f, 54f);
+ join.buttons().defaults().size(140f, 60f).pad(4f);
+ join.buttons().addButton("$text.cancel", join::hide);
+ join.buttons().addButton("$text.ok", () -> {
+ showLoading("$text.connecting");
+
+ Timers.runTask(2f, () -> {
+ try{
+ Net.connect(lastip, lastport);
+ }catch (IOException e) {
+ showError(Bundles.format("text.connectfail", Strings.parseException(e, false)));
+ hideLoading();
+ }
+ });
+ }).disabled(b -> lastip.isEmpty() || lastport == Integer.MIN_VALUE);
settingserror = new Dialog("Warning", "dialog");
settingserror.content().add("[crimson]Failed to access local storage.\nSettings will not be saved.");
settingserror.content().margin(10f);
- settingserror.getButtonTable().addButton("OK", ()->{
- settingserror.hide();
- }).size(80f, 55f).pad(4);
+ settingserror.getButtonTable().addButton("OK", settingserror::hide).size(80f, 55f).pad(4);
gameerror = new Dialog("$text.error.crashtitle", "dialog");
gameerror.content().labelWrap("$text.error.crashmessage").width(600f).pad(10f);
@@ -325,14 +347,6 @@ public class UI extends SceneModule{
}
- void invalidateAll(){
- for(Element e : scene.getElements()){
- if(e instanceof Table){
- ((Table)e).invalidateHierarchy();
- }
- }
- }
-
public void showGameError(){
gameerror.show();
}
@@ -371,12 +385,12 @@ public class UI extends SceneModule{
configtable.setVisible(false);
}
- public void showTextInput(String title, String text, String def, Consumer confirmed){
+ public void showTextInput(String title, String text, String def, TextFieldFilter filter, Consumer confirmed){
new Dialog(title, "dialog"){{
content().margin(30);
content().add(text).padRight(6f);
TextField field = content().addField(def, t->{}).size(170f, 50f).get();
- field.setTextFieldFilter((f, c) -> field.getText().length() < 12);
+ field.setTextFieldFilter((f, c) -> field.getText().length() < 12 && filter.acceptChar(f, c));
Mindustry.platforms.addDialog(field);
buttons().defaults().size(120, 54).pad(4);
buttons().addButton("$text.ok", () -> {
@@ -387,6 +401,10 @@ public class UI extends SceneModule{
}}.show();
}
+ public void showTextInput(String title, String text, String def, Consumer confirmed){
+ showTextInput(title, text, def, (field, c) -> true, confirmed);
+ }
+
public void showError(String text){
new Dialog("$text.error.title", "dialog"){{
content().margin(15);
@@ -432,6 +450,10 @@ public class UI extends SceneModule{
public void showLoadGame(){
load.show();
}
+
+ public void showJoinGame(){
+ join.show();
+ }
public void showMenu(){
menu.show();
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..30151c8e45
--- /dev/null
+++ b/core/src/io/anuke/mindustry/net/Net.java
@@ -0,0 +1,149 @@
+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);
+ active = true;
+ server = false;
+ }
+
+ /**Host a server at an address*/
+ public static void host(int port) throws IOException{
+ serverProvider.host(port);
+ active = true;
+ server = true;
+ }
+
+ /**Closes the server.*/
+ public static void closeServer(){
+ serverProvider.close();
+ server = false;
+ active = false;
+ }
+
+ public static void disconnect(){
+ clientProvider.disconnect();
+ server = false;
+ active = false;
+ }
+
+ /**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;
+ }
+
+ /**Whether this is a client or not.*/
+ public static boolean client(){
+ 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();
+ /**Disconnect from the server.*/
+ public void disconnect();
+ /**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);
+ /**Close the server connection.*/
+ public void close();
+ /**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.java b/core/src/io/anuke/mindustry/net/Packets.java
index 5b5638caf8..947b72ceff 100644
--- a/core/src/io/anuke/mindustry/net/Packets.java
+++ b/core/src/io/anuke/mindustry/net/Packets.java
@@ -16,5 +16,4 @@ public class Packets {
public static class WorldData {
}
-
}
diff --git a/core/src/io/anuke/mindustry/ui/MenuButton.java b/core/src/io/anuke/mindustry/ui/MenuButton.java
index a114c9162a..d5c3e3e837 100644
--- a/core/src/io/anuke/mindustry/ui/MenuButton.java
+++ b/core/src/io/anuke/mindustry/ui/MenuButton.java
@@ -1,5 +1,7 @@
package io.anuke.mindustry.ui;
+import com.badlogic.gdx.graphics.Color;
+import com.badlogic.gdx.graphics.Colors;
import com.badlogic.gdx.utils.Align;
import com.badlogic.gdx.utils.Scaling;
@@ -9,13 +11,9 @@ import io.anuke.ucore.scene.ui.Image;
public class MenuButton extends Button{
- public MenuButton(String icon, PressGroup group, Listenable clicked){
+ public MenuButton(String text, PressGroup group, Listenable clicked){
super("menu");
- Image image = new Image(icon);
- image.setScaling(Scaling.fit);
- image.setScale(4f);
- image.setOrigin(Align.center);
- add(image);
+ add(text, "title", 4);
clicked(clicked);
group.add(this);
}
diff --git a/core/src/io/anuke/mindustry/ui/MenuDialog.java b/core/src/io/anuke/mindustry/ui/MenuDialog.java
index ee0d959cd3..dd484104a5 100644
--- a/core/src/io/anuke/mindustry/ui/MenuDialog.java
+++ b/core/src/io/anuke/mindustry/ui/MenuDialog.java
@@ -6,15 +6,18 @@ import com.badlogic.gdx.utils.reflect.ClassReflection;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.core.GameState;
import io.anuke.mindustry.core.GameState.State;
+import io.anuke.mindustry.net.Net;
import io.anuke.ucore.UCore;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.scene.Element;
import io.anuke.ucore.scene.builders.build;
import io.anuke.ucore.scene.builders.imagebutton;
-import io.anuke.ucore.scene.ui.ConfirmDialog;
import io.anuke.ucore.scene.ui.ImageButton;
-import io.anuke.ucore.scene.ui.layout.Cell;
+import io.anuke.ucore.scene.ui.TextField.TextFieldFilter.DigitsOnlyFilter;
import io.anuke.ucore.util.Bundles;
+import io.anuke.ucore.util.Strings;
+
+import java.io.IOException;
public class MenuDialog extends FloatingDialog{
private SaveDialog save = new SaveDialog();
@@ -59,17 +62,30 @@ public class MenuDialog extends FloatingDialog{
}
content().row();
+
+ content().addButton("$text.hostserver", () -> {
+ Vars.ui.showTextInput("$text.hostserver", "$text.server.port", Vars.port + "", new DigitsOnlyFilter(), text -> {
+ int result = Strings.parseInt(text);
+ if(result == Integer.MIN_VALUE || result >= 65535){
+ Vars.ui.showError("$text.server.invalidport");
+ }else{
+ try{
+ Net.host(result);
+ }catch (IOException e){
+ Vars.ui.showError(Bundles.format("text.server.error", Strings.parseException(e, false)));
+ }
+ }
+ });
+ }).disabled(b -> Net.active() || (Net.active() && !Net.server()));
+
+ content().row();
+
content().addButton("$text.quit", () -> {
- new ConfirmDialog("$text.confirm", "$text.quit.confirm", () -> {
+ Vars.ui.showConfirm("$text.confirm", "$text.quit.confirm", () -> {
runSave();
hide();
GameState.set(State.menu);
- }){
- {
- for(Cell> cell : getButtonTable().getCells())
- cell.pad(3).size(180, 44);
- }
- }.show();
+ });
});
}else{
@@ -93,14 +109,11 @@ public class MenuDialog extends FloatingDialog{
new imagebutton("icon-load", isize, () -> load.show()).text("$text.load").padTop(4f);
new imagebutton("icon-quit", isize, () -> {
- new ConfirmDialog("$text.confirm", "$text.quit.confirm", () -> {
+ Vars.ui.showConfirm("$text.confirm", "$text.quit.confirm", () -> {
runSave();
hide();
GameState.set(State.menu);
- }){{
- for(Cell> cell : getButtonTable().getCells())
- cell.pad(3).size(180, 44);
- }}.show();
+ });
}).text("Quit").padTop(4f);
for(Element e : content().getChildren()){
diff --git a/core/src/io/anuke/mindustry/ui/fragments/MenuFragment.java b/core/src/io/anuke/mindustry/ui/fragments/MenuFragment.java
index 08a24e1ff6..a7aeb3706e 100644
--- a/core/src/io/anuke/mindustry/ui/fragments/MenuFragment.java
+++ b/core/src/io/anuke/mindustry/ui/fragments/MenuFragment.java
@@ -25,25 +25,30 @@ public class MenuFragment implements Fragment{
float scale = 4f;
defaults().size(100*scale, 21*scale).pad(-10f);
- add(new MenuButton("text-play", group, ui::showLevels));
+ add(new MenuButton("$text.play", group, ui::showLevels));
row();
-
- add(new MenuButton("text-tutorial", group, ()-> control.playMap(world.maps().getMap("tutorial"))));
- row();
-
+
if(!gwt){
- add(new MenuButton("text-load", group, ui::showLoadGame));
- row();
-
- add(new MenuButton("text-editor", group, ui::showEditor));
+ add(new MenuButton("$text.joingame", group, ui::showJoinGame));
row();
}
- add(new MenuButton("text-settings", group, ui::showPrefs));
+ add(new MenuButton("$text.tutorial", group, ()-> control.playMap(world.maps().getMap("tutorial"))));
row();
if(!gwt){
- add(new MenuButton("text-exit", group, Gdx.app::exit));
+ add(new MenuButton("$text.loadgame", group, ui::showLoadGame));
+ row();
+
+ add(new MenuButton("$text.editor", group, ui::showEditor));
+ row();
+ }
+
+ add(new MenuButton("$text.settings", group, ui::showPrefs));
+ row();
+
+ if(!gwt){
+ add(new MenuButton("$text.quit", group, Gdx.app::exit));
}
get().margin(16);
}}.end();
diff --git a/desktop/src/io/anuke/mindustry/desktop/DesktopLauncher.java b/desktop/src/io/anuke/mindustry/desktop/DesktopLauncher.java
index 4ca906fa7d..41a1506e47 100644
--- a/desktop/src/io/anuke/mindustry/desktop/DesktopLauncher.java
+++ b/desktop/src/io/anuke/mindustry/desktop/DesktopLauncher.java
@@ -6,19 +6,23 @@ import java.net.URI;
import java.text.DateFormat;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
-import java.util.Arrays;
import java.util.Date;
import com.badlogic.gdx.backends.lwjgl3.Lwjgl3Application;
import com.badlogic.gdx.backends.lwjgl3.Lwjgl3ApplicationConfiguration;
import com.badlogic.gdx.utils.Array;
+import com.esotericsoftware.kryonet.*;
import io.anuke.mindustry.Mindustry;
+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.ucore.UCore;
+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;
-import io.anuke.ucore.scene.ui.layout.Unit;
public class DesktopLauncher {
@@ -60,6 +64,150 @@ public class DesktopLauncher {
};
Mindustry.args = Array.with(arg);
+
+ Net.setClientProvider(new ClientProvider() {
+ Client client;
+
+ {
+ 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) {
+ if(object instanceof FrameworkMessage) return;
+ Net.handleClientReceived(object);
+ }
+ });
+ }
+
+ @Override
+ public void connect(String ip, int port) throws IOException {
+ client.connect(5000, ip, port, port);
+ }
+
+ @Override
+ public void disconnect() {
+ client.close();
+ }
+
+ @Override
+ 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
+ public void register(Class>... types) {
+ for(Class> c : types){
+ client.getKryo().register(c);
+ }
+ }
+ });
+
+ Net.setServerProvider(new ServerProvider() {
+ Server server;
+
+ {
+ server = new Server();
+ Thread thread = new Thread(server, "Kryonet Server");
+ thread.setDaemon(true);
+ thread.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) {
+ if(object instanceof FrameworkMessage) return;
+ Net.handleServerReceived(object);
+ }
+ });
+ }
+
+ @Override
+ public void host(int port) throws IOException {
+ server.bind(port, port);
+ }
+
+ @Override
+ public void close() {
+ server.close();
+ }
+
+ @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);
}