Fixed disconnect with many enemies and editor redo/undo bug

This commit is contained in:
Anuken
2018-01-14 11:37:23 -05:00
parent 487424f047
commit e545b7cca7
17 changed files with 88 additions and 33 deletions

View File

@@ -21,7 +21,7 @@ allprojects {
appName = "Mindustry" appName = "Mindustry"
gdxVersion = '1.9.8' gdxVersion = '1.9.8'
aiVersion = '1.8.1' aiVersion = '1.8.1'
uCoreVersion = '46c6564'; uCoreVersion = '89fa665';
} }
repositories { repositories {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 238 B

After

Width:  |  Height:  |  Size: 303 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 80 KiB

After

Width:  |  Height:  |  Size: 80 KiB

View File

@@ -18,6 +18,8 @@ import io.anuke.mindustry.net.Net.SendMode;
import io.anuke.mindustry.net.Packets.*; import io.anuke.mindustry.net.Packets.*;
import io.anuke.mindustry.net.Syncable; import io.anuke.mindustry.net.Syncable;
import io.anuke.mindustry.net.Syncable.Interpolator; 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.Upgrade;
import io.anuke.mindustry.resource.Weapon; import io.anuke.mindustry.resource.Weapon;
import io.anuke.mindustry.world.Block; import io.anuke.mindustry.world.Block;
@@ -125,7 +127,6 @@ public class NetClient extends Module {
Syncable sync = ((Syncable)entity); Syncable sync = ((Syncable)entity);
if(sync == null){ if(sync == null){
Gdx.app.error("Mindustry", "Unknown entity ID: " + id + " " + (i >= packet.enemyStart ? "(enemy)" : "(player)"));
if(!requests.contains(id)){ if(!requests.contains(id)){
requests.add(id); requests.add(id);
Gdx.app.error("Mindustry", "Sending entity request: " + id); Gdx.app.error("Mindustry", "Sending entity request: " + id);
@@ -150,7 +151,11 @@ public class NetClient extends Module {
}); });
Net.handle(PlacePacket.class, packet -> { 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 -> { Net.handle(BreakPacket.class, packet -> {
@@ -229,8 +234,9 @@ public class NetClient extends Module {
Gdx.app.postRunnable(() -> { Gdx.app.postRunnable(() -> {
try { 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) { while (stream.available() > 0) {
int pos = stream.readInt(); int pos = stream.readInt();
@@ -241,10 +247,13 @@ public class NetClient extends Module {
byte times = stream.readByte(); byte times = stream.readByte();
for (int i = 0; i < times; i++) { 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) { } catch (IOException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
@@ -325,6 +334,10 @@ public class NetClient extends Module {
} }
} }
public void beginConnecting(){
connecting = true;
}
public void disconnectQuietly(){ public void disconnectQuietly(){
kicked = true; kicked = true;
Net.disconnect(); Net.disconnect();

View File

@@ -336,7 +336,7 @@ public class NetServer extends Module{
try { try {
DataOutputStream stream = new DataOutputStream(bs); DataOutputStream stream = new DataOutputStream(bs);
stream.writeLong(TimeUtils.millis()); stream.writeFloat(Timers.time());
for (int rx = -viewx / 2; rx <= viewx / 2; rx++) { for (int rx = -viewx / 2; rx <= viewx / 2; rx++) {
for (int ry = -viewy / 2; ry <= viewy / 2; ry++) { 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.writeFloat(tile.entity.timer.getTimes()[i]);
} }
stream.writeShort(tile.getPackedData());
tile.entity.write(stream); tile.entity.write(stream);
} }
} }

View File

@@ -54,6 +54,10 @@ public class TileEntity extends Entity{
} }
public void readNetwork(DataInputStream stream, float elapsed) throws IOException{
read(stream);
}
public void onDeath(){ public void onDeath(){
onDeath(false); onDeath(false);
} }

View File

@@ -19,7 +19,7 @@ import io.anuke.ucore.entities.Entities;
import java.io.*; import java.io.*;
public class NetworkIO { 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){ public static void write(int playerID, ByteArray upgrades, OutputStream os){
@@ -106,7 +106,7 @@ public class NetworkIO {
} }
if(tile.entity != null){ if(tile.entity != null){
stream.writeByte(tile.getRotation()); //placerot stream.writeShort(tile.getPackedData());
stream.writeShort(tile.entity.health); //health stream.writeShort(tile.entity.health); //health
//items //items
@@ -240,11 +240,11 @@ public class NetworkIO {
} }
if(tile.entity != null){ if(tile.entity != null){
byte rotation = stream.readByte(); short data = stream.readShort();
short health = stream.readShort(); short health = stream.readShort();
tile.entity.health = health; tile.entity.health = health;
tile.setRotation(rotation); tile.setPackedData(data);
for(int j = 0; j < tile.entity.items.length; j ++){ for(int j = 0; j < tile.entity.items.length; j ++){
tile.entity.items[j] = stream.readInt(); tile.entity.items[j] = stream.readInt();

View File

@@ -24,7 +24,7 @@ public class MapGenerateDialog extends FloatingDialog{
private boolean loading; private boolean loading;
public MapGenerateDialog(MapEditor editor) { public MapGenerateDialog(MapEditor editor) {
super("$text.generate"); super("$text.editor.generate");
this.editor = editor; this.editor = editor;
Stack stack = new Stack(); Stack stack = new Stack();

View File

@@ -143,7 +143,7 @@ public class MapView extends Element implements GestureListener{
if(op == null) op = new DrawOperation(editor.pixmap()); if(op == null) op = new DrawOperation(editor.pixmap());
Pixmap next = Pixmaps.copy(editor.pixmap()); Pixmap next = Pixmaps.copy(editor.pixmap());
op.add(current, next); op.add(current, next);
current = next; current = null;
stack.add(op); stack.add(op);
op = null; op = null;
} }

View File

@@ -214,6 +214,7 @@ public class JoinDialog extends FloatingDialog {
Timers.runTask(2f, () -> { Timers.runTask(2f, () -> {
try{ try{
Vars.netClient.beginConnecting();
Net.connect(ip, port); Net.connect(ip, port);
hide(); hide();
join.hide(); join.hide();

View File

@@ -9,6 +9,7 @@ import io.anuke.mindustry.core.GameState.State;
import io.anuke.mindustry.net.Net; import io.anuke.mindustry.net.Net;
import io.anuke.ucore.core.Core; import io.anuke.ucore.core.Core;
import io.anuke.ucore.core.Settings; import io.anuke.ucore.core.Settings;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.scene.actions.Actions; import io.anuke.ucore.scene.actions.Actions;
import io.anuke.ucore.scene.builders.imagebutton; import io.anuke.ucore.scene.builders.imagebutton;
import io.anuke.ucore.scene.builders.label; import io.anuke.ucore.scene.builders.label;
@@ -155,6 +156,8 @@ public class HudFragment implements Fragment{
row(); row();
new label(() -> "[orange]noclip: " + Vars.noclip).left(); new label(() -> "[orange]noclip: " + Vars.noclip).left();
row(); row();
new label(() -> "[purple]time: " + (int)(Timers.time() / 10f) % 50).left();
row();
new label("[red]DEBUG MODE").scale(0.5f).left(); new label("[red]DEBUG MODE").scale(0.5f).left();
}}.end(); }}.end();
} }

View File

@@ -186,7 +186,7 @@ public class Block{
i++; i++;
i %= 4; i %= 4;
} }
tile.setDump((byte)pdump); tile.setDump(pdump);
handleItem(item, tile, tile); handleItem(item, tile, tile);
} }

View File

@@ -154,6 +154,14 @@ public class Tile{
return Bits.getRightByte(Bits.getRightByte(data)); return Bits.getRightByte(Bits.getRightByte(data));
} }
public short getPackedData(){
return data;
}
public void setPackedData(short data){
this.data = data;
}
public boolean passable(){ public boolean passable(){
Block block = block(); Block block = block();
Block floor = floor(); Block floor = floor();

View File

@@ -92,6 +92,8 @@ public class Conveyor extends Block{
removals.clear(); removals.clear();
float shift = entity.elapsed * speed;
for(int i = 0; i < entity.convey.size; i ++){ for(int i = 0; i < entity.convey.size; i ++){
int value = entity.convey.get(i); int value = entity.convey.get(i);
ItemPos pos = pos1.set(value); 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()); !(pos2.set(entity.convey.get(i + 1)).y - pos.y < itemSpace * Timers.delta());
if(canmove){ 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); pos.x = Mathf.lerpDelta(pos.x, 0, 0.06f);
}else{ }else{
pos.x = Mathf.lerpDelta(pos.x, pos.seed/offsetScl, 0.1f); 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); entity.convey.removeAll(removals);
} }
@@ -174,7 +178,7 @@ public class Conveyor extends Block{
*/ */
public static class ConveyorEntity extends TileEntity{ public static class ConveyorEntity extends TileEntity{
IntArray convey = new IntArray(); IntArray convey = new IntArray();
float minitem = 1; float minitem = 1, elapsed;
@Override @Override
public void write(DataOutputStream stream) throws IOException{ public void write(DataOutputStream stream) throws IOException{
@@ -197,6 +201,12 @@ public class Conveyor extends Block{
sort(convey.items, convey.size); 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){ private static void sort(int[] elements, int length){

View File

@@ -6,6 +6,7 @@ import com.badlogic.gdx.utils.ObjectMap;
import com.badlogic.gdx.utils.ObjectSet; import com.badlogic.gdx.utils.ObjectSet;
import com.esotericsoftware.kryonet.*; import com.esotericsoftware.kryonet.*;
import com.esotericsoftware.kryonet.FrameworkMessage.DiscoverHost; import com.esotericsoftware.kryonet.FrameworkMessage.DiscoverHost;
import com.esotericsoftware.kryonet.Listener.LagListener;
import com.esotericsoftware.kryonet.serialization.Serialization; import com.esotericsoftware.kryonet.serialization.Serialization;
import io.anuke.mindustry.Vars; import io.anuke.mindustry.Vars;
import io.anuke.mindustry.net.Host; 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.setDiscoveryHandler(handler);
client.addListener(new Listener(){ Listener listener = new Listener(){
@Override @Override
public void connected (Connection connection) { public void connected (Connection connection) {
Connect c = new Connect(); Connect c = new Connect();
c.id = connection.getID(); c.id = connection.getID();
c.addressTCP = connection.getRemoteAddressTCP().toString(); if(connection.getRemoteAddressTCP() != null) c.addressTCP = connection.getRemoteAddressTCP().toString();
try{ try{
Net.handleClientReceived(c); 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()); register(Registrator.getClasses());
} }

View File

@@ -9,9 +9,12 @@ import java.net.InetAddress;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
public class KryoRegistrator { public class KryoRegistrator {
public static boolean fakeLag = true;
public static final int fakeLagAmount = 500;
public static void register(Kryo kryo){ public static void register(Kryo kryo){
//TODO register stuff? //TODO register stuff?
//Log.set(Log.LEVEL_DEBUG);
} }
public static ByteBuffer writeServerData(){ public static ByteBuffer writeServerData(){

View File

@@ -5,6 +5,7 @@ import com.badlogic.gdx.utils.IntArray;
import com.esotericsoftware.kryonet.Connection; import com.esotericsoftware.kryonet.Connection;
import com.esotericsoftware.kryonet.FrameworkMessage; import com.esotericsoftware.kryonet.FrameworkMessage;
import com.esotericsoftware.kryonet.Listener; import com.esotericsoftware.kryonet.Listener;
import com.esotericsoftware.kryonet.Listener.LagListener;
import com.esotericsoftware.kryonet.Server; import com.esotericsoftware.kryonet.Server;
import com.esotericsoftware.kryonet.util.InputStreamSender; import com.esotericsoftware.kryonet.util.InputStreamSender;
import io.anuke.mindustry.net.Net; import io.anuke.mindustry.net.Net;
@@ -23,14 +24,13 @@ import io.anuke.ucore.core.Timers;
import java.io.IOException; import java.io.IOException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.util.Arrays;
public class KryoServer implements ServerProvider { public class KryoServer implements ServerProvider {
Server server; Server server;
IntArray connections = new IntArray(); IntArray connections = new IntArray();
public KryoServer(){ public KryoServer(){
server = new Server(4096*2, 2048); //TODO tweak server = new Server(4096*2, 2048*2); //TODO tweak
server.setDiscoveryHandler((datagramChannel, fromAddress) -> { server.setDiscoveryHandler((datagramChannel, fromAddress) -> {
ByteBuffer buffer = KryoRegistrator.writeServerData(); ByteBuffer buffer = KryoRegistrator.writeServerData();
UCore.log("Replying to discover request with buffer of size " + buffer.capacity()); UCore.log("Replying to discover request with buffer of size " + buffer.capacity());
@@ -39,7 +39,7 @@ public class KryoServer implements ServerProvider {
return true; return true;
}); });
server.addListener(new Listener(){ Listener listener = new Listener(){
@Override @Override
public void connected (Connection connection) { public void connected (Connection connection) {
@@ -81,7 +81,13 @@ public class KryoServer implements ServerProvider {
//Gdx.app.postRunnable(() -> {throw new RuntimeException(e);}); //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()); register(Registrator.getClasses());
} }
@@ -93,14 +99,13 @@ public class KryoServer implements ServerProvider {
@Override @Override
public void kick(int connection) { public void kick(int connection) {
Connection conn; Connection conn = getByID(connection);
try {
conn = getByID(connection); if(conn == null){
}catch (Exception e){
e.printStackTrace();
connections.removeValue(connection); connections.removeValue(connection);
return; return;
} }
KickPacket p = new KickPacket(); KickPacket p = new KickPacket();
p.reason = (byte)KickReason.kick.ordinal(); p.reason = (byte)KickReason.kick.ordinal();
@@ -137,6 +142,7 @@ public class KryoServer implements ServerProvider {
@Override @Override
public void sendStream(int id, Streamable stream) { public void sendStream(int id, Streamable stream) {
Connection connection = getByID(id); Connection connection = getByID(id);
if(connection == null) return;
connection.addListener(new InputStreamSender(stream.stream, 512) { connection.addListener(new InputStreamSender(stream.stream, 512) {
int id; int id;
@@ -219,7 +225,6 @@ public class KryoServer implements ServerProvider {
} }
} }
throw new RuntimeException("Unable to find connection with ID " + id + "! Current connections: " return null;
+ Arrays.toString(server.getConnections()));
} }
} }