diff --git a/core/src/io/anuke/mindustry/core/Control.java b/core/src/io/anuke/mindustry/core/Control.java index 7f24463d93..853cbf0875 100644 --- a/core/src/io/anuke/mindustry/core/Control.java +++ b/core/src/io/anuke/mindustry/core/Control.java @@ -181,6 +181,10 @@ public class Control extends Module{ Effects.effect(Fx.coreexplosion, world.getCore().worldx(), world.getCore().worldy()); ui.restart.show(); + + Timers.runTask(30f, () -> { + state.set(State.menu); + }); }); } diff --git a/core/src/io/anuke/mindustry/core/ServerControl.java b/core/src/io/anuke/mindustry/core/ServerControl.java index 71798a915a..c65b404a36 100644 --- a/core/src/io/anuke/mindustry/core/ServerControl.java +++ b/core/src/io/anuke/mindustry/core/ServerControl.java @@ -66,7 +66,8 @@ public class ServerControl extends Module { Events.on(GameOverEvent.class, () -> { info("Game over!"); - Timers.runTask(10f, () -> { + Timers.runTask(30f, () -> { + state.set(State.menu); Net.closeServer(); if(shuffle) { @@ -79,8 +80,6 @@ public class ServerControl extends Module { logic.reset(); world.loadMap(map); host(); - }else{ - state.set(State.menu); } }); }); @@ -292,6 +291,11 @@ public class ServerControl extends Module { info("Saved to slot {0}.", slot); }); + handler.register("gameover", "Force a game over.", arg -> { + world.removeBlock(world.getCore()); + info("Core destroyed."); + }); + handler.register("info", "Print debug info", arg -> { info(DebugFragment.debugInfo()); }); diff --git a/core/src/io/anuke/mindustry/net/Net.java b/core/src/io/anuke/mindustry/net/Net.java index f3b384c388..ba6fd11fc3 100644 --- a/core/src/io/anuke/mindustry/net/Net.java +++ b/core/src/io/anuke/mindustry/net/Net.java @@ -171,7 +171,7 @@ public class Net{ /**Call to handle a packet being recieved for the server.*/ public static void handleServerReceived(int connection, Object object){ - if(debugNet) serverDebug.handle(object); + if(debugNet) serverDebug.handle(connection, object); if(serverListeners.get(object.getClass()) != null || listeners.get(object.getClass()) != null){ if(serverListeners.get(object.getClass()) != null) serverListeners.get(object.getClass()).accept(connection, object); diff --git a/core/src/io/anuke/mindustry/net/NetEvents.java b/core/src/io/anuke/mindustry/net/NetEvents.java index cc70b52eae..4ec6721eb1 100644 --- a/core/src/io/anuke/mindustry/net/NetEvents.java +++ b/core/src/io/anuke/mindustry/net/NetEvents.java @@ -1,7 +1,6 @@ package io.anuke.mindustry.net; import io.anuke.mindustry.Vars; -import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.entities.BulletType; import io.anuke.mindustry.entities.TileEntity; import io.anuke.mindustry.entities.enemies.Enemy; @@ -27,8 +26,6 @@ public class NetEvents { public static void handleGameOver(){ Net.send(new GameOverPacket(), SendMode.tcp); - state.gameOver = true; - state.set(State.menu); } public static void handleBullet(BulletType type, Entity owner, float x, float y, float angle, short damage){ diff --git a/core/src/io/anuke/mindustry/net/ServerDebug.java b/core/src/io/anuke/mindustry/net/ServerDebug.java index 4e5f92bb0f..96687c58ed 100644 --- a/core/src/io/anuke/mindustry/net/ServerDebug.java +++ b/core/src/io/anuke/mindustry/net/ServerDebug.java @@ -1,8 +1,58 @@ package io.anuke.mindustry.net; +import com.badlogic.gdx.utils.IntMap; +import com.badlogic.gdx.utils.OrderedMap; +import com.badlogic.gdx.utils.TimeUtils; +import com.badlogic.gdx.utils.reflect.ClassReflection; +import io.anuke.mindustry.entities.Player; +import io.anuke.mindustry.net.Packets.Disconnect; + +import static io.anuke.mindustry.Vars.playerGroup; + public class ServerDebug { + private IntMap, Long>> last = new IntMap<>(); - public void handle(Object packet){ + public void handle(int connection, Object packet){ + if(!last.containsKey(connection)) + last.put(connection, new OrderedMap<>()); + if(packet instanceof Disconnect) + last.remove(connection); + else + last.get(connection).put(packet.getClass(), TimeUtils.millis()); + } + public String getOut(){ + StringBuilder build = new StringBuilder(); + for(Player player : playerGroup.all()){ + OrderedMap, Long> map = last.get(player.clientid, new OrderedMap<>()); + build.append("connection "); + build.append(player.clientid); + build.append(" / player '"); + build.append(player.name); + build.append("'\n"); + + for(Class type : map.orderedKeys()){ + build.append(" "); + build.append(elapsed(type, map)); + build.append("\n"); + } + } + return build.toString(); + } + + private String elapsed(Class type, OrderedMap, Long> last) { + long t = last.get(type, -1L); + if (t == -1) { + return ClassReflection.getSimpleName(type) + ": "; + } else { + float el = TimeUtils.timeSinceMillis(t) / 1000f; + String tu; + if (el > 1f) { + tu = (int) el + "s"; + } else { + tu = (int) (el * 60) + "f"; + } + return ClassReflection.getSimpleName(type) + ": " + tu; + } } } diff --git a/core/src/io/anuke/mindustry/ui/fragments/DebugFragment.java b/core/src/io/anuke/mindustry/ui/fragments/DebugFragment.java index 54710b1b76..fe5257523c 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/DebugFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/DebugFragment.java @@ -106,13 +106,14 @@ public class DebugFragment implements Fragment { return join( "net.active: " + Net.active(), "net.server: " + Net.server(), - "chat.open: " + ui.chatfrag.chatOpen(), - "chat.messages: " + ui.chatfrag.getMessagesSize(), + Net.client() ? "chat.open: " + ui.chatfrag.chatOpen() : "", + Net.client() ? "chat.messages: " + ui.chatfrag.getMessagesSize() : "", "players: " + playerGroup.size(), "enemies: " + enemyGroup.size(), "tiles: " + tileGroup.size(), + world.getCore() != null ? "core.health: " + world.getCore().entity.health : "", "", - clientDebug.getOut() + !Net.server() ? clientDebug.getOut() : serverDebug.getOut() ); } diff --git a/kryonet/src/io/anuke/kryonet/KryoServer.java b/kryonet/src/io/anuke/kryonet/KryoServer.java index 4f6543449c..25e02001a4 100644 --- a/kryonet/src/io/anuke/kryonet/KryoServer.java +++ b/kryonet/src/io/anuke/kryonet/KryoServer.java @@ -44,6 +44,7 @@ public class KryoServer implements ServerProvider { final CopyOnWriteArrayList connections = new CopyOnWriteArrayList<>(); final Array array = new Array<>(); SocketServer webServer; + Thread serverThread; int lastconnection = 0; @@ -131,15 +132,15 @@ public class KryoServer implements ServerProvider { webServer = new SocketServer(Vars.webPort); webServer.start(); - Thread thread = new Thread(() -> { + serverThread = new Thread(() -> { try{ server.run(); }catch (Exception e){ if(!(e instanceof ClosedSelectorException)) handleException(e); } }, "Kryonet Server"); - thread.setDaemon(true); - thread.start(); + serverThread.setDaemon(true); + serverThread.start(); } @Override @@ -151,7 +152,6 @@ public class KryoServer implements ServerProvider { Thread thread = new Thread(() ->{ try { server.close(); - Log.info("Killing web server..."); try { if (webServer != null) webServer.stop(1); //please die, right now }catch(Exception e){ @@ -163,7 +163,6 @@ public class KryoServer implements ServerProvider { worker.interrupt(); } } - Log.info("Killed web server."); }catch (Exception e){ Gdx.app.postRunnable(() -> {throw new RuntimeException(e);}); } @@ -252,14 +251,15 @@ public class KryoServer implements ServerProvider { @Override public void dispose(){ + Log.info("Disposing server."); try { + if(serverThread != null) serverThread.interrupt(); server.dispose(); }catch (Exception e){ e.printStackTrace(); } try { - Log.info("Disposing web server..."); if(webServer != null) webServer.stop(1); //kill them all @@ -268,7 +268,6 @@ public class KryoServer implements ServerProvider { thread.interrupt(); } } - Log.info("Killed web server."); }catch (Exception e){ e.printStackTrace(); }