From a8ce961268ea014ea4bac98bc3171acbe8edeed4 Mon Sep 17 00:00:00 2001 From: Anuken Date: Tue, 6 Mar 2018 23:18:34 -0500 Subject: [PATCH] Added server version display and compatibility checking --- core/assets/bundles/bundle.properties | 4 ++ core/assets/version.properties | 4 +- core/src/io/anuke/mindustry/net/Host.java | 4 +- .../mindustry/ui/dialogs/JoinDialog.java | 45 +++++++++---- .../mindustry/client/WebsocketClient.java | 67 ++++++++++--------- .../src/io/anuke/kryonet/KryoRegistrator.java | 5 +- kryonet/src/io/anuke/kryonet/KryoServer.java | 3 +- 7 files changed, 84 insertions(+), 48 deletions(-) diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index eff18ffebc..344a93d722 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -58,6 +58,10 @@ text.server.add=Add Server text.server.delete=Are you sure you want to delete this server? text.server.hostname=Host: {0} text.server.edit=Edit Server +text.server.outdated=[crimson]Outdated Server![] +text.server.outdated.client=[crimson]Outdated Client![] +text.server.version=[lightgray]Version: {0} +text.server.custombuild=[yellow]Custom Build text.confirmban=Are you sure you want to ban this player? text.confirmunban=Are you sure you want to unban this player? text.confirmadmin=Are you sure you want to make this player an admin? diff --git a/core/assets/version.properties b/core/assets/version.properties index 333f55ed98..15321b98e5 100644 --- a/core/assets/version.properties +++ b/core/assets/version.properties @@ -1,7 +1,7 @@ #Autogenerated file. Do not modify. -#Tue Mar 06 22:28:38 EST 2018 +#Tue Mar 06 23:17:50 EST 2018 version=release -androidBuildCode=336 +androidBuildCode=337 name=Mindustry code=3.4 build=custom build diff --git a/core/src/io/anuke/mindustry/net/Host.java b/core/src/io/anuke/mindustry/net/Host.java index 415b90913f..631f74a726 100644 --- a/core/src/io/anuke/mindustry/net/Host.java +++ b/core/src/io/anuke/mindustry/net/Host.java @@ -6,12 +6,14 @@ public class Host { public final String mapname; public final int wave; public final int players; + public final int version; - public Host(String name, String address, String mapname, int wave, int players){ + public Host(String name, String address, String mapname, int wave, int players, int version){ this.name = name; this.address = address; this.players = players; this.mapname = mapname; this.wave = wave; + this.version = version; } } diff --git a/core/src/io/anuke/mindustry/ui/dialogs/JoinDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/JoinDialog.java index e62efde4d9..adef04a1b7 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/JoinDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/JoinDialog.java @@ -4,6 +4,7 @@ import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.utils.Array; import io.anuke.mindustry.Vars; import io.anuke.mindustry.io.Platform; +import io.anuke.mindustry.io.Version; import io.anuke.mindustry.net.Host; import io.anuke.mindustry.net.Net; import io.anuke.ucore.core.Settings; @@ -84,7 +85,7 @@ public class JoinDialog extends FloatingDialog { TextButton button = buttons[0] = remote.addButton("[accent]"+server.ip, "clear", () -> { if(!buttons[0].childrenPressed()) connect(server.ip, Vars.port); - }).width(w).height(140f).pad(4f).get(); + }).width(w).height(150f).pad(4f).get(); button.getLabel().setWrap(true); @@ -131,16 +132,37 @@ public class JoinDialog extends FloatingDialog { server.content.label(() -> Bundles.get("text.server.refreshing") + Strings.animated(4, 11, ".")); Net.pingHost(server.ip, server.port, host -> { + String versionString; + + if(host.version == -1) { + versionString = Bundles.format("text.server.version", Bundles.get("text.server.custombuild")); + }else if(host.version == 0){ + versionString = Bundles.get("text.server.outdated"); + }else if(host.version < Version.build && Version.build != -1){ + versionString = Bundles.get("text.server.outdated") + "\n" + + Bundles.format("text.server.version", host.version); + }else if(host.version > Version.build && Version.build != -1){ + versionString = Bundles.get("text.server.outdated.client") + "\n" + + Bundles.format("text.server.version", host.version); + }else{ + versionString = Bundles.format("text.server.version", host.version); + } + server.content.clear(); - server.content.add("[lightgray]" + Bundles.format("text.server.hostname", host.name)).left(); - server.content.row(); - server.content.add("[lightgray]" + (host.players != 1 ? Bundles.format("text.players", host.players) : - Bundles.format("text.players.single", host.players))).left(); - server.content.row(); - server.content.add("[lightgray]" + Bundles.format("text.save.map", host.mapname)).left(); - server.content.row(); - server.content.add("[lightgray]" + Bundles.format("text.save.wave", host.wave)).left(); + server.content.table(t -> { + t.add(versionString).left(); + t.row(); + t.add("[lightgray]" + Bundles.format("text.server.hostname", host.name)).left(); + t.row(); + t.add("[lightgray]" + (host.players != 1 ? Bundles.format("text.players", host.players) : + Bundles.format("text.players.single", host.players))).left(); + t.row(); + t.add("[lightgray]" + Bundles.format("text.save.map", host.mapname) + " / " + Bundles.format("text.save.wave", host.wave)).left(); + }).expand().left().bottom().padLeft(12f).padBottom(8); + + //server.content.add(versionString).top().expandY().top().expandX(); + }, e -> { server.content.clear(); server.content.add("$text.host.invalid"); @@ -161,7 +183,7 @@ public class JoinDialog extends FloatingDialog { hosts.add(remote).growX(); hosts.row(); - hosts.add(local).growX(); + hosts.add(local).width(w); ScrollPane pane = new ScrollPane(hosts, "clear"); pane.setFadeScrollBars(false); @@ -188,10 +210,9 @@ public class JoinDialog extends FloatingDialog { }); }).size(50f, 54f).get(); button.update(() -> button.getStyle().imageUpColor = player.getColor()); - }).width(w).height(70f).pad(4); content().row(); - content().add(pane).width(w).pad(0); + content().add(pane).width(w + 34).pad(0); content().row(); content().addCenteredImageTextButton("$text.server.add", "icon-add", "clear", 14*3, () -> { renaming = null; diff --git a/html/src/io/anuke/mindustry/client/WebsocketClient.java b/html/src/io/anuke/mindustry/client/WebsocketClient.java index 66b82fe32a..19b944433e 100644 --- a/html/src/io/anuke/mindustry/client/WebsocketClient.java +++ b/html/src/io/anuke/mindustry/client/WebsocketClient.java @@ -104,39 +104,44 @@ public class WebsocketClient implements ClientProvider { @Override public void pingHost(String address, int port, Consumer valid, Consumer failed) { - if(!Platform.instance.canJoinGame()) { - failed.accept(new IOException()); - }else { - Websocket socket = new Websocket("ws://" + address + ":" + webPort); - final boolean[] accepted = {false}; - socket.addListener(new WebsocketListener() { - @Override - public void onClose() { - if (!accepted[0]) failed.accept(new IOException("Failed to connect to host.")); - } + try { + if (!Platform.instance.canJoinGame()) { + failed.accept(new IOException()); + } else { + Websocket socket = new Websocket("ws://" + address + ":" + webPort); + final boolean[] accepted = {false}; + socket.addListener(new WebsocketListener() { + @Override + public void onClose() { + if (!accepted[0]) failed.accept(new IOException("Failed to connect to host.")); + } - @Override - public void onMessage(String msg) { - if(!msg.startsWith("---")) return; - String[] text = msg.substring(3).split("\\|"); - Host host = new Host(text[1], address, text[2], Strings.parseInt(text[3]), Strings.parseInt(text[0])); - valid.accept(host); - accepted[0] = true; - socket.close(); - } + @Override + public void onMessage(String msg) { + if (!msg.startsWith("---")) return; + String[] text = msg.substring(3).split("\\|"); + Host host = new Host(text[1], address, text[2], Strings.parseInt(text[3]), + Strings.parseInt(text[0]), Strings.parseInt(text[4])); + valid.accept(host); + accepted[0] = true; + socket.close(); + } - @Override - public void onOpen() { - socket.send("_ping_"); - } - }); - socket.open(); - Timers.runTask(60f * 5, () -> { - if (!accepted[0]) { - failed.accept(new IOException("Failed to connect to host.")); - socket.close(); - } - }); + @Override + public void onOpen() { + socket.send("_ping_"); + } + }); + socket.open(); + Timers.runTask(60f * 5, () -> { + if (!accepted[0]) { + failed.accept(new IOException("Failed to connect to host.")); + socket.close(); + } + }); + } + }catch (Exception e){ + failed.accept(new IOException("Failed to connect to host.")); } } diff --git a/kryonet/src/io/anuke/kryonet/KryoRegistrator.java b/kryonet/src/io/anuke/kryonet/KryoRegistrator.java index 007580013b..1f724e898a 100644 --- a/kryonet/src/io/anuke/kryonet/KryoRegistrator.java +++ b/kryonet/src/io/anuke/kryonet/KryoRegistrator.java @@ -2,6 +2,7 @@ package io.anuke.kryonet; import com.esotericsoftware.minlog.Log; import com.esotericsoftware.minlog.Log.Logger; +import io.anuke.mindustry.io.Version; import io.anuke.mindustry.net.Host; import io.anuke.ucore.util.ColorCodes; @@ -65,6 +66,7 @@ public class KryoRegistrator { buffer.putInt(playerGroup.size()); buffer.putInt(state.wave); + buffer.putInt(Version.build); return buffer; } @@ -84,7 +86,8 @@ public class KryoRegistrator { int players = buffer.getInt(); int wave = buffer.getInt(); + int version = buffer.getInt(); - return new Host(host, ia.getHostAddress(), map, wave, players); + return new Host(host, ia.getHostAddress(), map, wave, players, version); } } diff --git a/kryonet/src/io/anuke/kryonet/KryoServer.java b/kryonet/src/io/anuke/kryonet/KryoServer.java index 24b53ad0da..9f6e30414c 100644 --- a/kryonet/src/io/anuke/kryonet/KryoServer.java +++ b/kryonet/src/io/anuke/kryonet/KryoServer.java @@ -10,6 +10,7 @@ import com.esotericsoftware.kryonet.Listener.LagListener; import com.esotericsoftware.kryonet.Server; import com.esotericsoftware.kryonet.util.InputStreamSender; import io.anuke.mindustry.Vars; +import io.anuke.mindustry.io.Version; import io.anuke.mindustry.net.Net; import io.anuke.mindustry.net.Net.SendMode; import io.anuke.mindustry.net.Net.ServerProvider; @@ -475,7 +476,7 @@ public class KryoServer implements ServerProvider { if(message.equals("_ping_")){ conn.send("---" + Vars.playerGroup.size() + "|" + (headless ? "Server" : Vars.player.name) - + "|" + world.getMap().name + "|" + state.wave); + + "|" + world.getMap().name + "|" + state.wave + "|" + Version.build); connections.remove(k); }else { byte[] out = Base64Coder.decode(message);