From e545b7cca79227e99629e6c43856f65826cfd7a3 Mon Sep 17 00:00:00 2001 From: Anuken Date: Sun, 14 Jan 2018 11:37:23 -0500 Subject: [PATCH] Fixed disconnect with many enemies and editor redo/undo bug --- build.gradle | 2 +- core/assets-raw/sprites/icon-iron.png | Bin 238 -> 303 bytes core/assets/sprites/sprites.png | Bin 81418 -> 81433 bytes .../io/anuke/mindustry/core/NetClient.java | 25 ++++++++++++---- .../io/anuke/mindustry/core/NetServer.java | 4 ++- .../anuke/mindustry/entities/TileEntity.java | 4 +++ core/src/io/anuke/mindustry/io/NetworkIO.java | 8 +++--- .../mapeditor/MapGenerateDialog.java | 2 +- .../io/anuke/mindustry/mapeditor/MapView.java | 2 +- .../mindustry/ui/dialogs/JoinDialog.java | 1 + .../mindustry/ui/fragments/HudFragment.java | 3 ++ core/src/io/anuke/mindustry/world/Block.java | 2 +- core/src/io/anuke/mindustry/world/Tile.java | 8 ++++++ .../blocks/types/distribution/Conveyor.java | 14 +++++++-- kryonet/src/io/anuke/kryonet/KryoClient.java | 16 +++++++---- .../src/io/anuke/kryonet/KryoRegistrator.java | 3 ++ kryonet/src/io/anuke/kryonet/KryoServer.java | 27 +++++++++++------- 17 files changed, 88 insertions(+), 33 deletions(-) diff --git a/build.gradle b/build.gradle index 6f767c8370..095b0e129a 100644 --- a/build.gradle +++ b/build.gradle @@ -21,7 +21,7 @@ allprojects { appName = "Mindustry" gdxVersion = '1.9.8' aiVersion = '1.8.1' - uCoreVersion = '46c6564'; + uCoreVersion = '89fa665'; } repositories { diff --git a/core/assets-raw/sprites/icon-iron.png b/core/assets-raw/sprites/icon-iron.png index f9072d1348fa7a97900ed0b07fa355f95ffc4a84..50f34510aecd5a5777346f873737736b85ca7cf4 100644 GIT binary patch delta 213 zcmV;`04o3P0j~m(Bo78+OGiWi{{a60|De66laV1F3gQ6{5F;6k12TJ&Nhp7pNklGSDfFLM#Vwp<_-oR5VHk!s`cmqN341ypbbwVIbnlvG%)55XZ zWqv#F|9M740C?Q40uXO^1{Ld%byZSVWdMB!k$hz|p3rwK0Daf;ZkkiHTqR*4&r+td zd1&b+yHCzWLmC7yUh;B0gx@WT^#(6&0i1IbpI@-gvy}VuWdMeHPD4I_)KNdY-6dVw P00000NkvXXu0mjfImA}? delta 173 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 delta 15637 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 diff --git a/core/src/io/anuke/mindustry/core/NetClient.java b/core/src/io/anuke/mindustry/core/NetClient.java index eabc0b3c67..237f1a16f4 100644 --- a/core/src/io/anuke/mindustry/core/NetClient.java +++ b/core/src/io/anuke/mindustry/core/NetClient.java @@ -18,6 +18,8 @@ import io.anuke.mindustry.net.Net.SendMode; import io.anuke.mindustry.net.Packets.*; import io.anuke.mindustry.net.Syncable; import io.anuke.mindustry.net.Syncable.Interpolator; +import io.anuke.mindustry.resource.Recipe; +import io.anuke.mindustry.resource.Recipes; import io.anuke.mindustry.resource.Upgrade; import io.anuke.mindustry.resource.Weapon; import io.anuke.mindustry.world.Block; @@ -125,7 +127,6 @@ public class NetClient extends Module { Syncable sync = ((Syncable)entity); if(sync == null){ - Gdx.app.error("Mindustry", "Unknown entity ID: " + id + " " + (i >= packet.enemyStart ? "(enemy)" : "(player)")); if(!requests.contains(id)){ requests.add(id); Gdx.app.error("Mindustry", "Sending entity request: " + id); @@ -150,7 +151,11 @@ public class NetClient extends Module { }); Net.handle(PlacePacket.class, packet -> { - Gdx.app.postRunnable(() -> Vars.control.input.placeBlockInternal(packet.x, packet.y, Block.getByID(packet.block), packet.rotation, true, false)); + Gdx.app.postRunnable(() ->{ + Recipe recipe = Recipes.getByResult(Block.getByID(packet.block)); + if(recipe != null) Vars.control.removeItems(recipe.requirements); + Vars.control.input.placeBlockInternal(packet.x, packet.y, Block.getByID(packet.block), packet.rotation, true, false); + }); }); Net.handle(BreakPacket.class, packet -> { @@ -229,8 +234,9 @@ public class NetClient extends Module { Gdx.app.postRunnable(() -> { try { - long timestamp = stream.readLong(); - float elapsed = TimeUtils.timeSinceMillis(timestamp) / 1000f * 60f; + + float time = stream.readFloat(); + float elapsed = Timers.time() - time; while (stream.available() > 0) { int pos = stream.readInt(); @@ -241,10 +247,13 @@ public class NetClient extends Module { byte times = stream.readByte(); for (int i = 0; i < times; i++) { - tile.entity.timer.getTimes()[i] = stream.readFloat() + elapsed; + tile.entity.timer.getTimes()[i] = stream.readFloat(); } - tile.entity.read(stream); + short data = stream.readShort(); + tile.setPackedData(data); + + tile.entity.readNetwork(stream, elapsed); } } catch (IOException e) { throw new RuntimeException(e); @@ -325,6 +334,10 @@ public class NetClient extends Module { } } + public void beginConnecting(){ + connecting = true; + } + public void disconnectQuietly(){ kicked = true; Net.disconnect(); diff --git a/core/src/io/anuke/mindustry/core/NetServer.java b/core/src/io/anuke/mindustry/core/NetServer.java index 436577b14b..b2c982a908 100644 --- a/core/src/io/anuke/mindustry/core/NetServer.java +++ b/core/src/io/anuke/mindustry/core/NetServer.java @@ -336,7 +336,7 @@ public class NetServer extends Module{ try { DataOutputStream stream = new DataOutputStream(bs); - stream.writeLong(TimeUtils.millis()); + stream.writeFloat(Timers.time()); for (int rx = -viewx / 2; rx <= viewx / 2; rx++) { for (int ry = -viewy / 2; ry <= viewy / 2; ry++) { @@ -359,6 +359,8 @@ public class NetServer extends Module{ stream.writeFloat(tile.entity.timer.getTimes()[i]); } + stream.writeShort(tile.getPackedData()); + tile.entity.write(stream); } } diff --git a/core/src/io/anuke/mindustry/entities/TileEntity.java b/core/src/io/anuke/mindustry/entities/TileEntity.java index 21ea1d52b1..9d755b3116 100644 --- a/core/src/io/anuke/mindustry/entities/TileEntity.java +++ b/core/src/io/anuke/mindustry/entities/TileEntity.java @@ -53,6 +53,10 @@ public class TileEntity extends Entity{ public void read(DataInputStream stream) throws IOException{ } + + public void readNetwork(DataInputStream stream, float elapsed) throws IOException{ + read(stream); + } public void onDeath(){ onDeath(false); diff --git a/core/src/io/anuke/mindustry/io/NetworkIO.java b/core/src/io/anuke/mindustry/io/NetworkIO.java index f2e097370a..b4bffa9650 100644 --- a/core/src/io/anuke/mindustry/io/NetworkIO.java +++ b/core/src/io/anuke/mindustry/io/NetworkIO.java @@ -19,7 +19,7 @@ import io.anuke.ucore.entities.Entities; import java.io.*; public class NetworkIO { - private static final int fileVersionID = 14; + private static final int fileVersionID = 15; public static void write(int playerID, ByteArray upgrades, OutputStream os){ @@ -106,7 +106,7 @@ public class NetworkIO { } if(tile.entity != null){ - stream.writeByte(tile.getRotation()); //placerot + stream.writeShort(tile.getPackedData()); stream.writeShort(tile.entity.health); //health //items @@ -240,11 +240,11 @@ public class NetworkIO { } if(tile.entity != null){ - byte rotation = stream.readByte(); + short data = stream.readShort(); short health = stream.readShort(); tile.entity.health = health; - tile.setRotation(rotation); + tile.setPackedData(data); for(int j = 0; j < tile.entity.items.length; j ++){ tile.entity.items[j] = stream.readInt(); diff --git a/core/src/io/anuke/mindustry/mapeditor/MapGenerateDialog.java b/core/src/io/anuke/mindustry/mapeditor/MapGenerateDialog.java index 430f5fd52f..330f70b7ee 100644 --- a/core/src/io/anuke/mindustry/mapeditor/MapGenerateDialog.java +++ b/core/src/io/anuke/mindustry/mapeditor/MapGenerateDialog.java @@ -24,7 +24,7 @@ public class MapGenerateDialog extends FloatingDialog{ private boolean loading; public MapGenerateDialog(MapEditor editor) { - super("$text.generate"); + super("$text.editor.generate"); this.editor = editor; Stack stack = new Stack(); diff --git a/core/src/io/anuke/mindustry/mapeditor/MapView.java b/core/src/io/anuke/mindustry/mapeditor/MapView.java index 92abf3543e..0cc7ddabc1 100644 --- a/core/src/io/anuke/mindustry/mapeditor/MapView.java +++ b/core/src/io/anuke/mindustry/mapeditor/MapView.java @@ -143,7 +143,7 @@ public class MapView extends Element implements GestureListener{ if(op == null) op = new DrawOperation(editor.pixmap()); Pixmap next = Pixmaps.copy(editor.pixmap()); op.add(current, next); - current = next; + current = null; stack.add(op); op = null; } diff --git a/core/src/io/anuke/mindustry/ui/dialogs/JoinDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/JoinDialog.java index 83c600df15..1268a261d1 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/JoinDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/JoinDialog.java @@ -214,6 +214,7 @@ public class JoinDialog extends FloatingDialog { Timers.runTask(2f, () -> { try{ + Vars.netClient.beginConnecting(); Net.connect(ip, port); hide(); join.hide(); diff --git a/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java b/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java index 57fdbd9e2b..235f3f31f0 100644 --- a/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java +++ b/core/src/io/anuke/mindustry/ui/fragments/HudFragment.java @@ -9,6 +9,7 @@ import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.net.Net; import io.anuke.ucore.core.Core; import io.anuke.ucore.core.Settings; +import io.anuke.ucore.core.Timers; import io.anuke.ucore.scene.actions.Actions; import io.anuke.ucore.scene.builders.imagebutton; import io.anuke.ucore.scene.builders.label; @@ -155,6 +156,8 @@ public class HudFragment implements Fragment{ row(); new label(() -> "[orange]noclip: " + Vars.noclip).left(); row(); + new label(() -> "[purple]time: " + (int)(Timers.time() / 10f) % 50).left(); + row(); new label("[red]DEBUG MODE").scale(0.5f).left(); }}.end(); } diff --git a/core/src/io/anuke/mindustry/world/Block.java b/core/src/io/anuke/mindustry/world/Block.java index f05756cc06..b44f173cef 100644 --- a/core/src/io/anuke/mindustry/world/Block.java +++ b/core/src/io/anuke/mindustry/world/Block.java @@ -186,7 +186,7 @@ public class Block{ i++; i %= 4; } - tile.setDump((byte)pdump); + tile.setDump(pdump); handleItem(item, tile, tile); } diff --git a/core/src/io/anuke/mindustry/world/Tile.java b/core/src/io/anuke/mindustry/world/Tile.java index e2c7d49af6..89326ca590 100644 --- a/core/src/io/anuke/mindustry/world/Tile.java +++ b/core/src/io/anuke/mindustry/world/Tile.java @@ -154,6 +154,14 @@ public class Tile{ return Bits.getRightByte(Bits.getRightByte(data)); } + public short getPackedData(){ + return data; + } + + public void setPackedData(short data){ + this.data = data; + } + public boolean passable(){ Block block = block(); Block floor = floor(); diff --git a/core/src/io/anuke/mindustry/world/blocks/types/distribution/Conveyor.java b/core/src/io/anuke/mindustry/world/blocks/types/distribution/Conveyor.java index 0b4648fa03..fb6c983217 100644 --- a/core/src/io/anuke/mindustry/world/blocks/types/distribution/Conveyor.java +++ b/core/src/io/anuke/mindustry/world/blocks/types/distribution/Conveyor.java @@ -92,6 +92,8 @@ public class Conveyor extends Block{ removals.clear(); + float shift = entity.elapsed * speed; + for(int i = 0; i < entity.convey.size; i ++){ int value = entity.convey.get(i); ItemPos pos = pos1.set(value); @@ -100,7 +102,7 @@ public class Conveyor extends Block{ !(pos2.set(entity.convey.get(i + 1)).y - pos.y < itemSpace * Timers.delta()); if(canmove){ - pos.y += Math.max(speed * Timers.delta(), 1f/252f); //TODO fix precision issues when at high FPS? + pos.y += Math.max(speed * Timers.delta() + shift, 1f/252f); //TODO fix precision issues when at high FPS? pos.x = Mathf.lerpDelta(pos.x, 0, 0.06f); }else{ pos.x = Mathf.lerpDelta(pos.x, pos.seed/offsetScl, 0.1f); @@ -119,6 +121,8 @@ public class Conveyor extends Block{ } } + + entity.elapsed = 0f; entity.convey.removeAll(removals); } @@ -174,7 +178,7 @@ public class Conveyor extends Block{ */ public static class ConveyorEntity extends TileEntity{ IntArray convey = new IntArray(); - float minitem = 1; + float minitem = 1, elapsed; @Override public void write(DataOutputStream stream) throws IOException{ @@ -197,6 +201,12 @@ public class Conveyor extends Block{ sort(convey.items, convey.size); } + + @Override + public void readNetwork(DataInputStream stream, float elapsed) throws IOException{ + read(stream); + this.elapsed = elapsed; + } } private static void sort(int[] elements, int length){ diff --git a/kryonet/src/io/anuke/kryonet/KryoClient.java b/kryonet/src/io/anuke/kryonet/KryoClient.java index cb40be6af1..c429873950 100644 --- a/kryonet/src/io/anuke/kryonet/KryoClient.java +++ b/kryonet/src/io/anuke/kryonet/KryoClient.java @@ -6,6 +6,7 @@ import com.badlogic.gdx.utils.ObjectMap; import com.badlogic.gdx.utils.ObjectSet; import com.esotericsoftware.kryonet.*; import com.esotericsoftware.kryonet.FrameworkMessage.DiscoverHost; +import com.esotericsoftware.kryonet.Listener.LagListener; import com.esotericsoftware.kryonet.serialization.Serialization; import io.anuke.mindustry.Vars; import io.anuke.mindustry.net.Host; @@ -51,15 +52,15 @@ public class KryoClient implements ClientProvider{ } }; - client = new Client(); + client = new Client(8192, 2048*2); client.setDiscoveryHandler(handler); - client.addListener(new Listener(){ + Listener listener = new Listener(){ @Override public void connected (Connection connection) { Connect c = new Connect(); c.id = connection.getID(); - c.addressTCP = connection.getRemoteAddressTCP().toString(); + if(connection.getRemoteAddressTCP() != null) c.addressTCP = connection.getRemoteAddressTCP().toString(); try{ Net.handleClientReceived(c); @@ -95,9 +96,14 @@ public class KryoClient implements ClientProvider{ }); } } - } - }); + }; + + if(KryoRegistrator.fakeLag){ + client.addListener(new LagListener(0, KryoRegistrator.fakeLagAmount, listener)); + }else{ + client.addListener(listener); + } register(Registrator.getClasses()); } diff --git a/kryonet/src/io/anuke/kryonet/KryoRegistrator.java b/kryonet/src/io/anuke/kryonet/KryoRegistrator.java index a104347e3e..15aebd8ae3 100644 --- a/kryonet/src/io/anuke/kryonet/KryoRegistrator.java +++ b/kryonet/src/io/anuke/kryonet/KryoRegistrator.java @@ -9,9 +9,12 @@ import java.net.InetAddress; import java.nio.ByteBuffer; public class KryoRegistrator { + public static boolean fakeLag = true; + public static final int fakeLagAmount = 500; public static void register(Kryo kryo){ //TODO register stuff? + //Log.set(Log.LEVEL_DEBUG); } public static ByteBuffer writeServerData(){ diff --git a/kryonet/src/io/anuke/kryonet/KryoServer.java b/kryonet/src/io/anuke/kryonet/KryoServer.java index e4640427af..b01b3c4e74 100644 --- a/kryonet/src/io/anuke/kryonet/KryoServer.java +++ b/kryonet/src/io/anuke/kryonet/KryoServer.java @@ -5,6 +5,7 @@ import com.badlogic.gdx.utils.IntArray; import com.esotericsoftware.kryonet.Connection; import com.esotericsoftware.kryonet.FrameworkMessage; import com.esotericsoftware.kryonet.Listener; +import com.esotericsoftware.kryonet.Listener.LagListener; import com.esotericsoftware.kryonet.Server; import com.esotericsoftware.kryonet.util.InputStreamSender; import io.anuke.mindustry.net.Net; @@ -23,14 +24,13 @@ import io.anuke.ucore.core.Timers; import java.io.IOException; import java.nio.ByteBuffer; -import java.util.Arrays; public class KryoServer implements ServerProvider { Server server; IntArray connections = new IntArray(); public KryoServer(){ - server = new Server(4096*2, 2048); //TODO tweak + server = new Server(4096*2, 2048*2); //TODO tweak server.setDiscoveryHandler((datagramChannel, fromAddress) -> { ByteBuffer buffer = KryoRegistrator.writeServerData(); UCore.log("Replying to discover request with buffer of size " + buffer.capacity()); @@ -39,7 +39,7 @@ public class KryoServer implements ServerProvider { return true; }); - server.addListener(new Listener(){ + Listener listener = new Listener(){ @Override public void connected (Connection connection) { @@ -81,7 +81,13 @@ public class KryoServer implements ServerProvider { //Gdx.app.postRunnable(() -> {throw new RuntimeException(e);}); } } - }); + }; + + if(KryoRegistrator.fakeLag){ + server.addListener(new LagListener(0, KryoRegistrator.fakeLagAmount, listener)); + }else{ + server.addListener(listener); + } register(Registrator.getClasses()); } @@ -93,14 +99,13 @@ public class KryoServer implements ServerProvider { @Override public void kick(int connection) { - Connection conn; - try { - conn = getByID(connection); - }catch (Exception e){ - e.printStackTrace(); + Connection conn = getByID(connection); + + if(conn == null){ connections.removeValue(connection); return; } + KickPacket p = new KickPacket(); p.reason = (byte)KickReason.kick.ordinal(); @@ -137,6 +142,7 @@ public class KryoServer implements ServerProvider { @Override public void sendStream(int id, Streamable stream) { Connection connection = getByID(id); + if(connection == null) return; connection.addListener(new InputStreamSender(stream.stream, 512) { int id; @@ -219,7 +225,6 @@ public class KryoServer implements ServerProvider { } } - throw new RuntimeException("Unable to find connection with ID " + id + "! Current connections: " - + Arrays.toString(server.getConnections())); + return null; } }