diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml index 4c56edee62..7664e5113f 100644 --- a/android/AndroidManifest.xml +++ b/android/AndroidManifest.xml @@ -1,8 +1,8 @@ + android:versionCode="53" + android:versionName="3.3b5" > diff --git a/core/src/io/anuke/mindustry/ai/Pathfind.java b/core/src/io/anuke/mindustry/ai/Pathfind.java index 4409a3c79d..a80319a874 100644 --- a/core/src/io/anuke/mindustry/ai/Pathfind.java +++ b/core/src/io/anuke/mindustry/ai/Pathfind.java @@ -48,6 +48,11 @@ public class Pathfind{ Tile[] path = Vars.control.getSpawnPoints().get(enemy.lane).pathTiles; + if(enemy.node >= path.length){ + enemy.node = -1; + return vector.set(enemy.x, enemy.y); + } + //if an enemy is idle for a while, it's probably stuck if(enemy.idletime > EnemyType.maxIdle){ diff --git a/core/src/io/anuke/mindustry/core/NetClient.java b/core/src/io/anuke/mindustry/core/NetClient.java index 28a170bb69..af3d53cc61 100644 --- a/core/src/io/anuke/mindustry/core/NetClient.java +++ b/core/src/io/anuke/mindustry/core/NetClient.java @@ -133,8 +133,8 @@ public class NetClient extends Module { if(sync == null){ Gdx.app.error("Mindustry", "Unknown entity ID: " + id + " " + (i >= packet.enemyStart ? "(enemy)" : "(player)")); if(!requests.contains(id)){ - Gdx.app.error("Mindustry", "Sending entity request: " + id); requests.add(id); + Gdx.app.error("Mindustry", "Sending entity request: " + id); EntityRequestPacket req = new EntityRequestPacket(); req.id = id; Net.send(req, SendMode.tcp); @@ -174,8 +174,9 @@ public class NetClient extends Module { }); Net.handle(EnemySpawnPacket.class, spawn -> { - requests.remove(spawn.id); Gdx.app.postRunnable(() -> { + //duplicates. + if(Vars.control.enemyGroup.getByID(spawn.id) != null) return; Enemy enemy = new Enemy(EnemyType.getByID(spawn.type)); enemy.set(spawn.x, spawn.y); enemy.tier = spawn.tier; @@ -260,10 +261,13 @@ public class NetClient extends Module { }); Net.handle(Player.class, player -> { - requests.remove(player.id); - player.getInterpolator().last.set(player.x, player.y); - player.getInterpolator().target.set(player.x, player.y); - player.add(); + Gdx.app.postRunnable(() -> { + //duplicates. + if(Vars.control.enemyGroup.getByID(player.id) != null) return; + player.getInterpolator().last.set(player.x, player.y); + player.getInterpolator().target.set(player.x, player.y); + player.add(); + }); }); Net.handle(ChatPacket.class, packet -> Gdx.app.postRunnable(() -> Vars.ui.chatfrag.addMessage(packet.text, Vars.netClient.colorizeName(packet.id, packet.name)))); @@ -386,5 +390,9 @@ public class NetClient extends Module { packet.data = Vars.player.getInterpolator().type.write(Vars.player); Net.send(packet, SendMode.udp); } + + if(Timers.get("updatePing", 60)){ + Net.updatePing(); + } } } diff --git a/core/src/io/anuke/mindustry/core/NetServer.java b/core/src/io/anuke/mindustry/core/NetServer.java index 0fce2c3930..832e2485ad 100644 --- a/core/src/io/anuke/mindustry/core/NetServer.java +++ b/core/src/io/anuke/mindustry/core/NetServer.java @@ -83,12 +83,14 @@ public class NetServer extends Module{ } sendMessage("[accent]"+Bundles.format("text.server.disconnected", player.name)); - Gdx.app.postRunnable(player::remove); + Gdx.app.postRunnable(() -> { + player.remove(); - DisconnectPacket dc = new DisconnectPacket(); - dc.playerid = player.id; + DisconnectPacket dc = new DisconnectPacket(); + dc.playerid = player.id; - Net.send(dc, SendMode.tcp); + Net.send(dc, SendMode.tcp); + }); }); Net.handleServer(PositionPacket.class, pos -> { @@ -185,7 +187,7 @@ public class NetServer extends Module{ Gdx.app.postRunnable(() -> { if(Vars.control.playerGroup.getByID(id) != null){ Net.sendTo(dest, Vars.control.playerGroup.getByID(id), SendMode.tcp); - Gdx.app.error("Mindustry", "Replying to entity request: player, " + id); + Gdx.app.error("Mindustry", "Replying to entity request ("+Net.getLastConnection()+"): player, " + id); }else if (Vars.control.enemyGroup.getByID(id) != null){ Enemy enemy = Vars.control.enemyGroup.getByID(id); EnemySpawnPacket e = new EnemySpawnPacket(); @@ -196,7 +198,7 @@ public class NetServer extends Module{ e.lane = (byte)enemy.lane; e.type = enemy.type.id; Net.sendTo(dest, e, SendMode.tcp); - Gdx.app.error("Mindustry", "Replying to entity request: enemy, " + id); + Gdx.app.error("Mindustry", "Replying to entity request("+Net.getLastConnection()+"): enemy, " + id); }else{ Gdx.app.error("Mindustry", "Entity request target not found!"); } diff --git a/core/src/io/anuke/mindustry/core/Renderer.java b/core/src/io/anuke/mindustry/core/Renderer.java index 5af5ae2a24..33b905a589 100644 --- a/core/src/io/anuke/mindustry/core/Renderer.java +++ b/core/src/io/anuke/mindustry/core/Renderer.java @@ -103,9 +103,9 @@ public class Renderer extends RendererModule{ //TODO identify the source of this bug if(control.core == null){ - ui.showError("$text.error.crashmessage"); - GameState.set(State.menu); - return; + // ui.showError("$text.error.crashmessage"); + // GameState.set(State.menu); + // return; } if(control.core.block() == ProductionBlocks.core){ diff --git a/core/src/io/anuke/mindustry/core/World.java b/core/src/io/anuke/mindustry/core/World.java index faeb81397c..9056cec29a 100644 --- a/core/src/io/anuke/mindustry/core/World.java +++ b/core/src/io/anuke/mindustry/core/World.java @@ -1,13 +1,11 @@ package io.anuke.mindustry.core; -import com.badlogic.gdx.Gdx; import com.badlogic.gdx.math.GridPoint2; import com.badlogic.gdx.math.MathUtils; import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.utils.Array; import io.anuke.mindustry.Vars; import io.anuke.mindustry.ai.Pathfind; -import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.entities.TileEntity; import io.anuke.mindustry.io.Maps; import io.anuke.mindustry.net.Net; @@ -109,11 +107,9 @@ public class World extends Module{ } public Tile tile(int x, int y){ - if(tiles == null){ - Gdx.app.postRunnable(() -> Vars.ui.showError("$text.error.crashmessage")); - GameState.set(State.menu); - return null; - } + //if(tiles == null){ + // return null; + //} if(!Mathf.inBounds(x, y, tiles)) return null; return tiles[x][y]; } diff --git a/core/src/io/anuke/mindustry/game/Difficulty.java b/core/src/io/anuke/mindustry/game/Difficulty.java index a0524e96aa..447f1467cc 100644 --- a/core/src/io/anuke/mindustry/game/Difficulty.java +++ b/core/src/io/anuke/mindustry/game/Difficulty.java @@ -7,7 +7,7 @@ public enum Difficulty { normal(2f, 1f), hard(1.5f, 0.5f), insane(0.5f, 0.25f), - purge(0.4f, 0.01f); + purge(0.35f, 0.01f); /**The scaling of how many waves it takes for one more enemy of a type to appear. * For example: with enemeyScaling = 2 and the default scaling being 2, it would take 4 waves for diff --git a/core/src/io/anuke/mindustry/net/Net.java b/core/src/io/anuke/mindustry/net/Net.java index 382d49f014..84c7ec4661 100644 --- a/core/src/io/anuke/mindustry/net/Net.java +++ b/core/src/io/anuke/mindustry/net/Net.java @@ -157,6 +157,16 @@ public class Net{ } } + /**Update client ping.*/ + public static void updatePing(){ + clientProvider.updatePing(); + } + + /**Get the client ping. Only valid after updatePing().*/ + public static int getPing(){ + return clientProvider.getPing(); + } + /**Returns the last connection that sent a packet to this server.*/ public static int getLastConnection(){ return lastConnection; diff --git a/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java b/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java index d2f40c99e2..57fdbd9e2b 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java @@ -95,7 +95,8 @@ public class HudFragment implements Fragment{ visible(()->!GameState.is(State.menu)); - Label fps = new Label(()->(Settings.getBool("fps") ? (Gdx.graphics.getFramesPerSecond() + " FPS") : "")); + Label fps = new Label(()->(Settings.getBool("fps") ? (Gdx.graphics.getFramesPerSecond() + " FPS") + + (Net.active() ? " / Ping: " + Net.getPing() : ""): "")); row(); add(fps).size(-1); @@ -122,6 +123,11 @@ public class HudFragment implements Fragment{ new table("white"){{ respawntable = get(); respawntable.setColor(Color.CLEAR); + update(t -> { + if(GameState.is(State.menu)){ + respawntable.setColor(Color.CLEAR); + } + }); }}.end(); //respawn table diff --git a/kryonet/src/io/anuke/kryonet/KryoServer.java b/kryonet/src/io/anuke/kryonet/KryoServer.java index bac41dd3d9..4b5b128c46 100644 --- a/kryonet/src/io/anuke/kryonet/KryoServer.java +++ b/kryonet/src/io/anuke/kryonet/KryoServer.java @@ -86,7 +86,9 @@ public class KryoServer implements ServerProvider { try{ Net.handleServerReceived(object, connection.getID()); }catch (Exception e){ - Gdx.app.postRunnable(() -> {throw new RuntimeException(e);}); + //...do absolutely nothing. + e.printStackTrace(); + //Gdx.app.postRunnable(() -> {throw new RuntimeException(e);}); } } }); @@ -133,7 +135,6 @@ public class KryoServer implements ServerProvider { @Override public void sendStream(int id, Streamable stream) { Connection connection = getByID(id); - UCore.log("Sending stream: " + stream.getClass().getSimpleName() + " / " + stream.stream.available()); connection.addListener(new InputStreamSender(stream.stream, 512) { int id;