Updated client snapshot system, fixed stuck respawn bug

This commit is contained in:
Anuken
2018-06-09 13:44:24 -04:00
parent be2fa1dfad
commit 30e13259b3
8 changed files with 59 additions and 18 deletions

View File

@@ -1,6 +1,7 @@
package io.anuke.mindustry.core; package io.anuke.mindustry.core;
import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.utils.Pools;
import com.badlogic.gdx.utils.reflect.ClassReflection; import com.badlogic.gdx.utils.reflect.ClassReflection;
import com.badlogic.gdx.utils.reflect.ReflectionException; import com.badlogic.gdx.utils.reflect.ReflectionException;
import io.anuke.annotations.Annotations.Remote; import io.anuke.annotations.Annotations.Remote;
@@ -40,6 +41,8 @@ public class NetClient extends Module {
private boolean quiet = false; private boolean quiet = false;
/**Counter for data timeout.*/ /**Counter for data timeout.*/
private float timeoutTime = 0f; private float timeoutTime = 0f;
/**Last sent client snapshot ID.*/
private int lastSent;
/**Last snapshot recieved.*/ /**Last snapshot recieved.*/
private byte[] lastSnapshot; private byte[] lastSnapshot;
/**Last snapshot ID recieved.*/ /**Last snapshot ID recieved.*/
@@ -159,8 +162,9 @@ public class NetClient extends Module {
if(timer.get(0, playerSyncTime)){ if(timer.get(0, playerSyncTime)){
Player player = players[0]; Player player = players[0];
ClientSnapshotPacket packet = new ClientSnapshotPacket(); ClientSnapshotPacket packet = Pools.obtain(ClientSnapshotPacket.class);
packet.lastSnapshot = lastSnapshotID; packet.lastSnapshot = lastSnapshotID;
packet.snapid = lastSent++;
packet.player = player; packet.player = player;
Net.send(packet, SendMode.udp); Net.send(packet, SendMode.udp);
} }

View File

@@ -136,7 +136,19 @@ public class NetServer extends Module{
}); });
//update last recieved snapshot based on client snapshot //update last recieved snapshot based on client snapshot
Net.handleServer(ClientSnapshotPacket.class, (id, packet) -> Net.getConnection(id).lastSnapshotID = packet.lastSnapshot); Net.handleServer(ClientSnapshotPacket.class, (id, packet) ->{
Player player = connections.get(id);
NetConnection connection = Net.getConnection(id);
if(player == null || connection == null || packet.snapid < connection.lastRecievedSnapshot) return;
try {
player.read(packet.in, packet.timeSent);
connection.lastSnapshotID = packet.lastSnapshot;
connection.lastRecievedSnapshot = packet.snapid;
}catch (IOException e){
e.printStackTrace();
}
});
Net.handleServer(InvokePacket.class, (id, packet) -> RemoteReadServer.readPacket(packet.writeBuffer, packet.type, connections.get(id))); Net.handleServer(InvokePacket.class, (id, packet) -> RemoteReadServer.readPacket(packet.writeBuffer, packet.type, connections.get(id)));
} }

View File

@@ -188,7 +188,7 @@ public class Units {
EntityPhysics.getNearby(group, rect, entity -> cons.accept((Unit)entity)); EntityPhysics.getNearby(group, rect, entity -> cons.accept((Unit)entity));
} }
//now check all ally players //now check all players
EntityPhysics.getNearby(playerGroup, rect, player -> { EntityPhysics.getNearby(playerGroup, rect, player -> {
if(((Unit)player).team == team) cons.accept((Unit)player); if(((Unit)player).team == team) cons.accept((Unit)player);
}); });

View File

@@ -22,12 +22,17 @@ public class TypeIO {
@WriteClass(Player.class) @WriteClass(Player.class)
public static void writePlayer(ByteBuffer buffer, Player player){ public static void writePlayer(ByteBuffer buffer, Player player){
buffer.putInt(player.id); if(player == null){
buffer.putInt(-1);
}else {
buffer.putInt(player.id);
}
} }
@ReadClass(Player.class) @ReadClass(Player.class)
public static Player readPlayer(ByteBuffer buffer){ public static Player readPlayer(ByteBuffer buffer){
return playerGroup.getByID(buffer.getInt()); int id = buffer.getInt();
return id == -1 ? null : playerGroup.getByID(id);
} }
@WriteClass(Tile.class) @WriteClass(Tile.class)

View File

@@ -16,6 +16,9 @@ public abstract class NetConnection {
/**Byte array of last sent snapshot.*/ /**Byte array of last sent snapshot.*/
public byte[] lastSentSnapshot; public byte[] lastSentSnapshot;
/**ID of last recieved client snapshot.*/
public int lastRecievedSnapshot = -1;
public NetConnection(int id, String address){ public NetConnection(int id, String address){
this.id = id; this.id = id;
this.address = address; this.address = address;

View File

@@ -1,7 +1,6 @@
package io.anuke.mindustry.net; package io.anuke.mindustry.net;
import com.badlogic.gdx.utils.TimeUtils; import com.badlogic.gdx.utils.TimeUtils;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.entities.Player; import io.anuke.mindustry.entities.Player;
import io.anuke.mindustry.io.Version; import io.anuke.mindustry.io.Version;
import io.anuke.mindustry.net.Packet.ImportantPacket; import io.anuke.mindustry.net.Packet.ImportantPacket;
@@ -97,18 +96,33 @@ public class Packets {
} }
public static class ClientSnapshotPacket implements Packet{ public static class ClientSnapshotPacket implements Packet{
/**For writing only.*/
public Player player; public Player player;
public int lastSnapshot; public int lastSnapshot;
public int snapid;
public int length;
public long timeSent;
public byte[] bytes;
public ByteBuffer result;
public ByteBufferInput in;
@Override @Override
public void write(ByteBuffer buffer) { public void write(ByteBuffer buffer) {
ByteBufferOutput out = new ByteBufferOutput(buffer); ByteBufferOutput out = new ByteBufferOutput(buffer);
buffer.putInt(lastSnapshot); buffer.putInt(lastSnapshot);
buffer.putInt(player.id); buffer.putInt(snapid);
buffer.putLong(TimeUtils.millis()); buffer.putLong(TimeUtils.millis());
int position = buffer.position();
try { try {
player.write(out); player.write(out);
length = buffer.position() - position;
buffer.position(position);
buffer.putInt(length);
player.write(out);
}catch (IOException e){ }catch (IOException e){
e.printStackTrace(); e.printStackTrace();
} }
@@ -116,17 +130,20 @@ public class Packets {
@Override @Override
public void read(ByteBuffer buffer) { public void read(ByteBuffer buffer) {
ByteBufferInput in = new ByteBufferInput(buffer);
lastSnapshot = buffer.getInt(); lastSnapshot = buffer.getInt();
int id = buffer.getInt(); snapid = buffer.getInt();
long time = buffer.getLong(); timeSent = buffer.getLong();
player = Vars.playerGroup.getByID(id); length = buffer.getInt();
try {
player.read(in, time); if(bytes == null || bytes.length != length){
}catch (IOException e){ bytes = new byte[length];
e.printStackTrace(); result = ByteBuffer.wrap(bytes);
in = new ByteBufferInput(result);
} }
buffer.get(bytes);
result.position(0);
} }
} }

View File

@@ -101,7 +101,7 @@ public class Weapon extends Upgrade {
Bullet.create(owner.inventory.getAmmo().bullet, owner, x + tr.x, y + tr.y, angle); Bullet.create(owner.inventory.getAmmo().bullet, owner, x + tr.x, y + tr.y, angle);
} }
@Remote(targets = Loc.both, called = Loc.both, in = In.entities, forward = true) @Remote(targets = Loc.both, called = Loc.both, in = In.entities, unreliable = true, forward = true)
public static void onShootWeapon(Player player, Weapon weapon, float x, float y, float rotation, boolean left){ public static void onShootWeapon(Player player, Weapon weapon, float x, float y, float rotation, boolean left){
Angles.shotgun(weapon.shots, weapon.spacing, rotation, f -> weapon.bullet(player, x, y, f + Mathf.range(weapon.inaccuracy))); Angles.shotgun(weapon.shots, weapon.spacing, rotation, f -> weapon.bullet(player, x, y, f + Mathf.range(weapon.inaccuracy)));
@@ -119,6 +119,6 @@ public class Weapon extends Upgrade {
Effects.effect(type.smokeEffect, x + weapon.tr.x, y + weapon.tr.y, rotation, player); Effects.effect(type.smokeEffect, x + weapon.tr.x, y + weapon.tr.y, rotation, player);
//reset timer for remote players //reset timer for remote players
player.timer.reset(left ? Player.timerShootLeft : Player.timerShootRight, weapon.reload); player.timer.get(left ? Player.timerShootLeft : Player.timerShootRight, weapon.reload);
} }
} }

View File

@@ -151,7 +151,7 @@ public class CoreBlock extends StorageBlock {
//instant build for fast testing. //instant build for fast testing.
if(debug){ if(debug){
entity.progress = 1f; // entity.progress = 1f;
} }
if(entity.progress >= 1f){ if(entity.progress >= 1f){