Fixed jittery snapshots / Fixed misaligned unit bullets
This commit is contained in:
@@ -47,7 +47,7 @@ public class Mechs implements ContentList{
|
|||||||
boostSpeed = 0.85f;
|
boostSpeed = 0.85f;
|
||||||
weapon = Weapons.blaster;
|
weapon = Weapons.blaster;
|
||||||
maxSpeed = 4f;
|
maxSpeed = 4f;
|
||||||
altChargeAlpha = 0.04f;
|
altChargeAlpha = 0.02f;
|
||||||
trailColorTo = Color.valueOf("ffd37f");
|
trailColorTo = Color.valueOf("ffd37f");
|
||||||
armor = 20f;
|
armor = 20f;
|
||||||
}
|
}
|
||||||
@@ -64,8 +64,8 @@ public class Mechs implements ContentList{
|
|||||||
drone.leader = player;
|
drone.leader = player;
|
||||||
drone.set(player.x, player.y);
|
drone.set(player.x, player.y);
|
||||||
drone.add();
|
drone.add();
|
||||||
Effects.effect(UnitFx.unitLand, player);
|
|
||||||
}
|
}
|
||||||
|
Effects.effect(UnitFx.unitLand, player);
|
||||||
player.altHeat = 0f;
|
player.altHeat = 0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ public class UnitTypes implements ContentList{
|
|||||||
speed = 0.5f;
|
speed = 0.5f;
|
||||||
maxVelocity = 1.6f;
|
maxVelocity = 1.6f;
|
||||||
range = 40f;
|
range = 40f;
|
||||||
health = 20;
|
health = 30;
|
||||||
weapon = Weapons.droneBlaster;
|
weapon = Weapons.droneBlaster;
|
||||||
trailColor = Color.valueOf("ffd37f");
|
trailColor = Color.valueOf("ffd37f");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,12 +3,16 @@ package io.anuke.mindustry.core;
|
|||||||
import com.badlogic.gdx.Gdx;
|
import com.badlogic.gdx.Gdx;
|
||||||
import com.badlogic.gdx.graphics.Color;
|
import com.badlogic.gdx.graphics.Color;
|
||||||
import com.badlogic.gdx.utils.Base64Coder;
|
import com.badlogic.gdx.utils.Base64Coder;
|
||||||
|
import com.badlogic.gdx.utils.IntArray;
|
||||||
|
import com.badlogic.gdx.utils.IntMap;
|
||||||
|
import com.badlogic.gdx.utils.IntMap.Entry;
|
||||||
import com.badlogic.gdx.utils.IntSet;
|
import com.badlogic.gdx.utils.IntSet;
|
||||||
import io.anuke.annotations.Annotations.PacketPriority;
|
import io.anuke.annotations.Annotations.PacketPriority;
|
||||||
import io.anuke.annotations.Annotations.Remote;
|
import io.anuke.annotations.Annotations.Remote;
|
||||||
import io.anuke.annotations.Annotations.Variant;
|
import io.anuke.annotations.Annotations.Variant;
|
||||||
import io.anuke.mindustry.core.GameState.State;
|
import io.anuke.mindustry.core.GameState.State;
|
||||||
import io.anuke.mindustry.entities.Player;
|
import io.anuke.mindustry.entities.Player;
|
||||||
|
import io.anuke.mindustry.entities.TileEntity;
|
||||||
import io.anuke.mindustry.entities.traits.SyncTrait;
|
import io.anuke.mindustry.entities.traits.SyncTrait;
|
||||||
import io.anuke.mindustry.entities.traits.TypeTrait;
|
import io.anuke.mindustry.entities.traits.TypeTrait;
|
||||||
import io.anuke.mindustry.gen.Call;
|
import io.anuke.mindustry.gen.Call;
|
||||||
@@ -18,6 +22,7 @@ import io.anuke.mindustry.net.Net.SendMode;
|
|||||||
import io.anuke.mindustry.net.NetworkIO;
|
import io.anuke.mindustry.net.NetworkIO;
|
||||||
import io.anuke.mindustry.net.Packets.*;
|
import io.anuke.mindustry.net.Packets.*;
|
||||||
import io.anuke.mindustry.net.TraceInfo;
|
import io.anuke.mindustry.net.TraceInfo;
|
||||||
|
import io.anuke.mindustry.world.modules.InventoryModule;
|
||||||
import io.anuke.ucore.core.Settings;
|
import io.anuke.ucore.core.Settings;
|
||||||
import io.anuke.ucore.core.Timers;
|
import io.anuke.ucore.core.Timers;
|
||||||
import io.anuke.ucore.entities.Entities;
|
import io.anuke.ucore.entities.Entities;
|
||||||
@@ -41,6 +46,7 @@ import static io.anuke.mindustry.Vars.*;
|
|||||||
public class NetClient extends Module{
|
public class NetClient extends Module{
|
||||||
private final static float dataTimeout = 60 * 18;
|
private final static float dataTimeout = 60 * 18;
|
||||||
private final static float playerSyncTime = 2;
|
private final static float playerSyncTime = 2;
|
||||||
|
private final static IntArray removals = new IntArray();
|
||||||
|
|
||||||
private Timer timer = new Timer(5);
|
private Timer timer = new Timer(5);
|
||||||
/**Whether the client is currently connecting.*/
|
/**Whether the client is currently connecting.*/
|
||||||
@@ -54,8 +60,8 @@ public class NetClient extends Module{
|
|||||||
|
|
||||||
/**Last snapshot ID recieved.*/
|
/**Last snapshot ID recieved.*/
|
||||||
private int lastSnapshotBaseID = -1;
|
private int lastSnapshotBaseID = -1;
|
||||||
/**Last snapshot recieved.*/
|
|
||||||
private byte[] lastSnapshotBase;
|
private IntMap<byte[]> recievedSnapshots = new IntMap<>();
|
||||||
/**Current snapshot that is being built from chinks.*/
|
/**Current snapshot that is being built from chinks.*/
|
||||||
private byte[] currentSnapshot;
|
private byte[] currentSnapshot;
|
||||||
/**Array of recieved chunk statuses.*/
|
/**Array of recieved chunk statuses.*/
|
||||||
@@ -191,12 +197,12 @@ public class NetClient extends Module{
|
|||||||
|
|
||||||
@Remote(variants = Variant.one, priority = PacketPriority.low, unreliable = true)
|
@Remote(variants = Variant.one, priority = PacketPriority.low, unreliable = true)
|
||||||
public static void onSnapshot(byte[] chunk, int snapshotID, short chunkID, int totalLength, int base){
|
public static void onSnapshot(byte[] chunk, int snapshotID, short chunkID, int totalLength, int base){
|
||||||
if(NetServer.showSnapshotSize)
|
if(NetServer.debugSnapshots)
|
||||||
Log.info("Recieved snapshot: len {0} ID {1} chunkID {2} totalLength {3} base {4} client-base {5}", chunk.length, snapshotID, chunkID, totalLength, base, netClient.lastSnapshotBaseID);
|
Log.info("Recieved snapshot: len {0} ID {1} chunkID {2} totalLength {3} base {4} client-base {5}", chunk.length, snapshotID, chunkID, totalLength, base, netClient.lastSnapshotBaseID);
|
||||||
|
|
||||||
//skip snapshot IDs that have already been recieved OR snapshots that are too far in front
|
//skip snapshot IDs that have already been recieved OR snapshots that are too far in front
|
||||||
if(snapshotID < netClient.lastSnapshotBaseID || base != netClient.lastSnapshotBaseID){
|
if(base != -1 && (snapshotID < netClient.lastSnapshotBaseID || !netClient.recievedSnapshots.containsKey(base))){
|
||||||
if(NetServer.showSnapshotSize) Log.info("//SKIP SNAPSHOT");
|
if(NetServer.debugSnapshots) Log.info("//SKIP SNAPSHOT");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -235,7 +241,7 @@ public class NetClient extends Module{
|
|||||||
snapshot = chunk;
|
snapshot = chunk;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(NetServer.showSnapshotSize)
|
if(NetServer.debugSnapshots)
|
||||||
Log.info("Finished recieving snapshot ID {0} length {1}", snapshotID, chunk.length);
|
Log.info("Finished recieving snapshot ID {0} length {1}", snapshotID, chunk.length);
|
||||||
|
|
||||||
byte[] result;
|
byte[] result;
|
||||||
@@ -243,20 +249,21 @@ public class NetClient extends Module{
|
|||||||
if(base == -1){ //fresh snapshot
|
if(base == -1){ //fresh snapshot
|
||||||
result = snapshot;
|
result = snapshot;
|
||||||
length = snapshot.length;
|
length = snapshot.length;
|
||||||
netClient.lastSnapshotBase = Arrays.copyOf(snapshot, snapshot.length);
|
netClient.recievedSnapshots.put(snapshotID, Arrays.copyOf(snapshot, snapshot.length));
|
||||||
}else{ //otherwise, last snapshot must not be null, decode it
|
}else{ //otherwise, last snapshot must not be null, decode it
|
||||||
if(NetServer.showSnapshotSize)
|
byte[] baseBytes = netClient.recievedSnapshots.get(base);
|
||||||
Log.info("Base size: {0} Patch size: {1}", netClient.lastSnapshotBase.length, snapshot.length);
|
if(NetServer.debugSnapshots)
|
||||||
netClient.decoder.init(netClient.lastSnapshotBase, snapshot);
|
Log.info("Base size: {0} Patch size: {1}", baseBytes.length, snapshot.length);
|
||||||
|
netClient.decoder.init(baseBytes, snapshot);
|
||||||
result = netClient.decoder.decode();
|
result = netClient.decoder.decode();
|
||||||
length = netClient.decoder.getDecodedLength();
|
length = netClient.decoder.getDecodedLength();
|
||||||
//set last snapshot to a copy to prevent issues
|
//set last snapshot to a copy to prevent issues
|
||||||
netClient.lastSnapshotBase = Arrays.copyOf(result, length);
|
netClient.recievedSnapshots.put(snapshotID, Arrays.copyOf(result, length));
|
||||||
}
|
}
|
||||||
|
|
||||||
netClient.lastSnapshotBaseID = snapshotID;
|
netClient.lastSnapshotBaseID = snapshotID;
|
||||||
|
|
||||||
//set stream bytes to begin snapshot reaeding
|
//set stream bytes to begin snapshot reading
|
||||||
netClient.byteStream.setBytes(result, 0, length);
|
netClient.byteStream.setBytes(result, 0, length);
|
||||||
|
|
||||||
//get data input for reading from the stream
|
//get data input for reading from the stream
|
||||||
@@ -266,6 +273,16 @@ public class NetClient extends Module{
|
|||||||
|
|
||||||
//confirm that snapshot has been recieved
|
//confirm that snapshot has been recieved
|
||||||
netClient.lastSnapshotBaseID = snapshotID;
|
netClient.lastSnapshotBaseID = snapshotID;
|
||||||
|
|
||||||
|
removals.clear();
|
||||||
|
for(Entry<byte[]> entry : netClient.recievedSnapshots.entries()){
|
||||||
|
if(entry.key < base){
|
||||||
|
removals.add(entry.key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(int i = 0; i < removals.size; i++){
|
||||||
|
netClient.recievedSnapshots.remove(removals.get(i));
|
||||||
|
}
|
||||||
}catch(Exception e){
|
}catch(Exception e){
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
@@ -280,7 +297,12 @@ public class NetClient extends Module{
|
|||||||
byte cores = input.readByte();
|
byte cores = input.readByte();
|
||||||
for(int i = 0; i < cores; i++){
|
for(int i = 0; i < cores; i++){
|
||||||
int pos = input.readInt();
|
int pos = input.readInt();
|
||||||
world.tile(pos).entity.items.read(input);
|
TileEntity entity = world.tile(pos).entity;
|
||||||
|
if(entity != null){
|
||||||
|
entity.items.read(input);
|
||||||
|
}else{
|
||||||
|
new InventoryModule().read(input);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
long timestamp = input.readLong();
|
long timestamp = input.readLong();
|
||||||
@@ -364,7 +386,7 @@ public class NetClient extends Module{
|
|||||||
connecting = true;
|
connecting = true;
|
||||||
quiet = false;
|
quiet = false;
|
||||||
lastSent = 0;
|
lastSent = 0;
|
||||||
lastSnapshotBase = null;
|
recievedSnapshots.clear();
|
||||||
currentSnapshot = null;
|
currentSnapshot = null;
|
||||||
currentSnapshotID = -1;
|
currentSnapshotID = -1;
|
||||||
lastSnapshotBaseID = -1;
|
lastSnapshotBaseID = -1;
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import com.badlogic.gdx.graphics.Color;
|
|||||||
import com.badlogic.gdx.graphics.Colors;
|
import com.badlogic.gdx.graphics.Colors;
|
||||||
import com.badlogic.gdx.math.Vector2;
|
import com.badlogic.gdx.math.Vector2;
|
||||||
import com.badlogic.gdx.utils.Array;
|
import com.badlogic.gdx.utils.Array;
|
||||||
|
import com.badlogic.gdx.utils.IntArray;
|
||||||
import com.badlogic.gdx.utils.IntMap;
|
import com.badlogic.gdx.utils.IntMap;
|
||||||
import com.badlogic.gdx.utils.TimeUtils;
|
import com.badlogic.gdx.utils.TimeUtils;
|
||||||
import io.anuke.annotations.Annotations.Loc;
|
import io.anuke.annotations.Annotations.Loc;
|
||||||
@@ -45,11 +46,15 @@ import static io.anuke.mindustry.Vars.*;
|
|||||||
|
|
||||||
public class NetServer extends Module{
|
public class NetServer extends Module{
|
||||||
public final static int maxSnapshotSize = 2047;
|
public final static int maxSnapshotSize = 2047;
|
||||||
public final static boolean showSnapshotSize = false;
|
|
||||||
|
public final static boolean debugSnapshots = true;
|
||||||
|
public final static float maxSnapshotDelay = 200;
|
||||||
|
public final static float snapshotDropchance = 0.01f;
|
||||||
|
|
||||||
private final static byte[] reusableSnapArray = new byte[maxSnapshotSize];
|
private final static byte[] reusableSnapArray = new byte[maxSnapshotSize];
|
||||||
private final static float serverSyncTime = 4, kickDuration = 30 * 1000;
|
private final static float serverSyncTime = 4, kickDuration = 30 * 1000;
|
||||||
private final static Vector2 vector = new Vector2();
|
private final static Vector2 vector = new Vector2();
|
||||||
|
private final static IntArray removals = new IntArray();
|
||||||
/**If a play goes away of their server-side coordinates by this distance, they get teleported back.*/
|
/**If a play goes away of their server-side coordinates by this distance, they get teleported back.*/
|
||||||
private final static float correctDist = 16f;
|
private final static float correctDist = 16f;
|
||||||
|
|
||||||
@@ -215,6 +220,7 @@ public class NetServer extends Module{
|
|||||||
player.setMineTile(packet.mining);
|
player.setMineTile(packet.mining);
|
||||||
player.isBoosting = packet.boosting;
|
player.isBoosting = packet.boosting;
|
||||||
player.isShooting = packet.shooting;
|
player.isShooting = packet.shooting;
|
||||||
|
player.isAlt = packet.alting;
|
||||||
player.getPlaceQueue().clear();
|
player.getPlaceQueue().clear();
|
||||||
for(BuildRequest req : packet.requests){
|
for(BuildRequest req : packet.requests){
|
||||||
//auto-skip done requests
|
//auto-skip done requests
|
||||||
@@ -231,7 +237,7 @@ public class NetServer extends Module{
|
|||||||
|
|
||||||
float prevx = player.x, prevy = player.y;
|
float prevx = player.x, prevy = player.y;
|
||||||
player.set(player.getInterpolator().target.x, player.getInterpolator().target.y);
|
player.set(player.getInterpolator().target.x, player.getInterpolator().target.y);
|
||||||
if(!player.mech.flying){
|
if(!player.mech.flying && player.boostHeat < 0.01f){
|
||||||
player.move(vector.x, vector.y);
|
player.move(vector.x, vector.y);
|
||||||
}else{
|
}else{
|
||||||
player.x += vector.x;
|
player.x += vector.x;
|
||||||
@@ -257,9 +263,18 @@ public class NetServer extends Module{
|
|||||||
player.getVelocity().set(packet.xv, packet.yv); //only for visual calculation purposes, doesn't actually update the player
|
player.getVelocity().set(packet.xv, packet.yv); //only for visual calculation purposes, doesn't actually update the player
|
||||||
|
|
||||||
//when the client confirms recieveing a snapshot, update base and clear map
|
//when the client confirms recieveing a snapshot, update base and clear map
|
||||||
if(packet.lastSnapshot > connection.currentBaseID){
|
if(packet.lastSnapshot > connection.lastRecievedSnapshotID){
|
||||||
connection.currentBaseID = packet.lastSnapshot;
|
connection.lastRecievedSnapshotID = packet.lastSnapshot;
|
||||||
connection.currentBaseSnapshot = connection.lastSentRawSnapshot;
|
removals.clear();
|
||||||
|
for(IntMap.Entry entry : connection.sent){
|
||||||
|
if(entry.key < packet.lastSnapshot){
|
||||||
|
removals.add(entry.key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < removals.size; i++){
|
||||||
|
connection.sent.remove(removals.get(i));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
connection.lastRecievedClientSnapshot = packet.snapid;
|
connection.lastRecievedClientSnapshot = packet.snapid;
|
||||||
@@ -285,7 +300,7 @@ public class NetServer extends Module{
|
|||||||
/** Sends a raw byte[] snapshot to a client, splitting up into chunks when needed.*/
|
/** Sends a raw byte[] snapshot to a client, splitting up into chunks when needed.*/
|
||||||
private static void sendSplitSnapshot(int userid, byte[] bytes, int snapshotID, int base){
|
private static void sendSplitSnapshot(int userid, byte[] bytes, int snapshotID, int base){
|
||||||
if(bytes.length < maxSnapshotSize){
|
if(bytes.length < maxSnapshotSize){
|
||||||
Call.onSnapshot(userid, bytes, snapshotID, (short) 0, bytes.length, base);
|
scheduleSnapshot(() -> Call.onSnapshot(userid, bytes, snapshotID, (short) 0, bytes.length, base));
|
||||||
}else{
|
}else{
|
||||||
int remaining = bytes.length;
|
int remaining = bytes.length;
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
@@ -294,13 +309,15 @@ public class NetServer extends Module{
|
|||||||
int used = Math.min(remaining, maxSnapshotSize);
|
int used = Math.min(remaining, maxSnapshotSize);
|
||||||
byte[] toSend;
|
byte[] toSend;
|
||||||
//re-use sent byte arrays when possible
|
//re-use sent byte arrays when possible
|
||||||
if(used == maxSnapshotSize){
|
if(used == maxSnapshotSize && !debugSnapshots){
|
||||||
toSend = reusableSnapArray;
|
toSend = reusableSnapArray;
|
||||||
System.arraycopy(bytes, offset, toSend, 0, Math.min(offset + maxSnapshotSize, bytes.length) - offset);
|
System.arraycopy(bytes, offset, toSend, 0, Math.min(offset + maxSnapshotSize, bytes.length) - offset);
|
||||||
}else{
|
}else{
|
||||||
toSend = Arrays.copyOfRange(bytes, offset, Math.min(offset + maxSnapshotSize, bytes.length));
|
toSend = Arrays.copyOfRange(bytes, offset, Math.min(offset + maxSnapshotSize, bytes.length));
|
||||||
}
|
}
|
||||||
Call.onSnapshot(userid, toSend, snapshotID, (short) chunkid, bytes.length, base);
|
|
||||||
|
short fchunk = (short)chunkid;
|
||||||
|
scheduleSnapshot(() -> Call.onSnapshot(userid, toSend, snapshotID, fchunk, bytes.length, base));
|
||||||
|
|
||||||
remaining -= used;
|
remaining -= used;
|
||||||
offset += used;
|
offset += used;
|
||||||
@@ -309,6 +326,16 @@ public class NetServer extends Module{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void scheduleSnapshot(Runnable r){
|
||||||
|
if(debugSnapshots){
|
||||||
|
if(!Mathf.chance(snapshotDropchance)){
|
||||||
|
Timers.run(maxSnapshotDelay / 1000f * 60f, r);
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
r.run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void sendWorldData(Player player, int clientID){
|
public void sendWorldData(Player player, int clientID){
|
||||||
ByteArrayOutputStream stream = new ByteArrayOutputStream();
|
ByteArrayOutputStream stream = new ByteArrayOutputStream();
|
||||||
DeflaterOutputStream def = new DeflaterOutputStream(stream);
|
DeflaterOutputStream def = new DeflaterOutputStream(stream);
|
||||||
@@ -490,10 +517,6 @@ public class NetServer extends Module{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String getUUID(int connectionID){
|
|
||||||
return connections.get(connectionID).uuid;
|
|
||||||
}
|
|
||||||
|
|
||||||
String fixName(String name){
|
String fixName(String name){
|
||||||
if(name.equals("[") || name.equals("]")){
|
if(name.equals("[") || name.equals("]")){
|
||||||
return "";
|
return "";
|
||||||
@@ -559,12 +582,12 @@ public class NetServer extends Module{
|
|||||||
if(!player.timer.get(Player.timerSync, serverSyncTime) || !connection.hasConnected) continue;
|
if(!player.timer.get(Player.timerSync, serverSyncTime) || !connection.hasConnected) continue;
|
||||||
|
|
||||||
//if the player hasn't acknowledged that it has recieved the packet, send the same thing again
|
//if the player hasn't acknowledged that it has recieved the packet, send the same thing again
|
||||||
if(connection.currentBaseID < connection.lastSentSnapshotID){
|
/*if(connection.currentBaseID < connection.lastSentSnapshotID){
|
||||||
if(showSnapshotSize)
|
if(debugSnapshots)
|
||||||
Log.info("Re-sending snapshot: {0} bytes, ID {1} base {2} baselength {3}", connection.lastSentSnapshot.length, connection.lastSentSnapshotID, connection.lastSentBase, connection.currentBaseSnapshot.length);
|
Log.info("Re-sending snapshot: {0} bytes, ID {1} base {2} baselength {3}", connection.lastSentSnapshot.length, connection.lastSentSnapshotID, connection.lastSentBase, connection.currentBaseSnapshot.length);
|
||||||
sendSplitSnapshot(connection.id, connection.lastSentSnapshot, connection.lastSentSnapshotID, connection.lastSentBase);
|
sendSplitSnapshot(connection.id, connection.lastSentSnapshot, connection.lastSentSnapshotID, connection.lastSentBase);
|
||||||
return;
|
return;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
//reset stream to begin writing
|
//reset stream to begin writing
|
||||||
syncStream.reset();
|
syncStream.reset();
|
||||||
@@ -573,29 +596,28 @@ public class NetServer extends Module{
|
|||||||
|
|
||||||
byte[] bytes = syncStream.toByteArray();
|
byte[] bytes = syncStream.toByteArray();
|
||||||
|
|
||||||
if(connection.currentBaseID == -1){
|
int snapid = connection.lastSentSnapshotID ++;
|
||||||
//assign to last sent snapshot so that there is only ever one unique snapshot with ID 0
|
|
||||||
if(connection.lastSentSnapshot != null){
|
if(connection.lastRecievedSnapshotID == -1){
|
||||||
|
/*if(connection.lastSentSnapshot != null){
|
||||||
bytes = connection.lastSentSnapshot;
|
bytes = connection.lastSentSnapshot;
|
||||||
}else{
|
}else{
|
||||||
connection.lastSentRawSnapshot = bytes;
|
connection.lastSentRawSnapshot = bytes;
|
||||||
connection.lastSentSnapshot = bytes;
|
connection.lastSentSnapshot = bytes;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
if(showSnapshotSize) Log.info("Sent raw snapshot: {0} bytes.", bytes.length);
|
if(debugSnapshots) Log.info("Sent raw snapshot: {0} bytes.", bytes.length);
|
||||||
///Nothing to diff off of in this case, send the whole thing
|
///Nothing to diff off of in this case, send the whole thing
|
||||||
sendSplitSnapshot(connection.id, bytes, 0, -1);
|
sendSplitSnapshot(connection.id, bytes, snapid, -1);
|
||||||
|
connection.sent.put(snapid, bytes);
|
||||||
}else{
|
}else{
|
||||||
connection.lastSentRawSnapshot = bytes;
|
|
||||||
|
|
||||||
//send diff, otherwise
|
//send diff, otherwise
|
||||||
byte[] diff = ByteDeltaEncoder.toDiff(new ByteMatcherHash(connection.currentBaseSnapshot, bytes), encoder);
|
byte[] diff = ByteDeltaEncoder.toDiff(new ByteMatcherHash(connection.sent.get(connection.lastRecievedSnapshotID), bytes), encoder);
|
||||||
if(showSnapshotSize)
|
if(debugSnapshots)
|
||||||
Log.info("Shrank snapshot: {0} -> {1}, Base {2} ID {3} base length = {4}", bytes.length, diff.length, connection.currentBaseID, connection.currentBaseID + 1, connection.currentBaseSnapshot.length);
|
Log.info("Shrank snapshot: {0} -> {1}, Base {2}", bytes.length, diff.length, connection.lastRecievedSnapshotID);
|
||||||
sendSplitSnapshot(connection.id, diff, connection.currentBaseID + 1, connection.currentBaseID);
|
|
||||||
connection.lastSentSnapshot = diff;
|
sendSplitSnapshot(connection.id, diff, snapid, connection.lastRecievedSnapshotID);
|
||||||
connection.lastSentSnapshotID = connection.currentBaseID + 1;
|
connection.sent.put(snapid, bytes);
|
||||||
connection.lastSentBase = connection.currentBaseID;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -460,6 +460,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
|
|||||||
|
|
||||||
altHeat = Mathf.lerpDelta(altHeat, isAlt ? 1f : 0f, mech.altChargeAlpha);
|
altHeat = Mathf.lerpDelta(altHeat, isAlt ? 1f : 0f, mech.altChargeAlpha);
|
||||||
boostHeat = Mathf.lerpDelta(boostHeat, (tile != null && tile.solid()) || (isBoosting && ((!movement.isZero() && moved) || !isLocal)) ? 1f : 0f, 0.08f);
|
boostHeat = Mathf.lerpDelta(boostHeat, (tile != null && tile.solid()) || (isBoosting && ((!movement.isZero() && moved) || !isLocal)) ? 1f : 0f, 0.08f);
|
||||||
|
mech.updateAlt(this); //updated regardless
|
||||||
|
|
||||||
if(!isLocal){
|
if(!isLocal){
|
||||||
interpolate();
|
interpolate();
|
||||||
@@ -480,8 +481,6 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra
|
|||||||
control.database().unlockContent(mech);
|
control.database().unlockContent(mech);
|
||||||
}
|
}
|
||||||
|
|
||||||
mech.updateAlt(this);
|
|
||||||
|
|
||||||
if(mobile){
|
if(mobile){
|
||||||
updateFlying();
|
updateFlying();
|
||||||
}else{
|
}else{
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ public class AlphaDrone extends FlyingUnit {
|
|||||||
public final UnitState attack = new UnitState() {
|
public final UnitState attack = new UnitState() {
|
||||||
@Override
|
@Override
|
||||||
public void update() {
|
public void update() {
|
||||||
if(leader == null || leader.isDead()){
|
if(leader == null || leader.isDead() || !leader.isAdded()){
|
||||||
damage(99999f);
|
damage(99999f);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -67,12 +67,19 @@ public class AlphaDrone extends FlyingUnit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeSave(DataOutput stream) throws IOException {
|
public void write(DataOutput stream) throws IOException {
|
||||||
super.writeSave(stream);
|
super.write(stream);
|
||||||
|
stream.writeInt(leader == null ? -1 : leader.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void readSave(DataInput stream) throws IOException {
|
public void read(DataInput stream, long time) throws IOException {
|
||||||
|
super.read(stream, time);
|
||||||
|
leader = Vars.playerGroup.getByID(stream.readInt());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void readSave(DataInput stream) throws IOException{
|
||||||
super.readSave(stream);
|
super.readSave(stream);
|
||||||
|
|
||||||
if(!Net.active()){
|
if(!Net.active()){
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ public class Interpolator{
|
|||||||
public void read(float cx, float cy, float x, float y, long sent, float... target1ds){
|
public void read(float cx, float cy, float x, float y, long sent, float... target1ds){
|
||||||
if(lastUpdated != 0) updateSpacing = TimeUtils.timeSinceMillis(lastUpdated);
|
if(lastUpdated != 0) updateSpacing = TimeUtils.timeSinceMillis(lastUpdated);
|
||||||
|
|
||||||
lastUpdated = sent;
|
lastUpdated = TimeUtils.millis();
|
||||||
|
|
||||||
targets = target1ds;
|
targets = target1ds;
|
||||||
last.set(cx, cy);
|
last.set(cx, cy);
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package io.anuke.mindustry.net;
|
package io.anuke.mindustry.net;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.utils.IntMap;
|
||||||
import io.anuke.mindustry.net.Net.SendMode;
|
import io.anuke.mindustry.net.Net.SendMode;
|
||||||
|
|
||||||
public abstract class NetConnection{
|
public abstract class NetConnection{
|
||||||
@@ -10,24 +11,22 @@ public abstract class NetConnection{
|
|||||||
* The current base snapshot that the client is absolutely confirmed to have recieved.
|
* The current base snapshot that the client is absolutely confirmed to have recieved.
|
||||||
* All sent snapshots should be taking the diff from this base snapshot, if it isn't null.
|
* All sent snapshots should be taking the diff from this base snapshot, if it isn't null.
|
||||||
*/
|
*/
|
||||||
public byte[] currentBaseSnapshot;
|
//public byte[] currentBaseSnapshot;
|
||||||
/**
|
/**
|
||||||
* ID of the current base snapshot.
|
* ID of the current base snapshot.
|
||||||
*/
|
*/
|
||||||
public int currentBaseID = -1;
|
// public int currentBaseID = -1;
|
||||||
|
|
||||||
public int lastSentBase = -1;
|
//public int lastSentBase = -1;
|
||||||
public byte[] lastSentSnapshot;
|
// public byte[] lastSentSnapshot;
|
||||||
public byte[] lastSentRawSnapshot;
|
//public byte[] lastSentRawSnapshot;
|
||||||
|
public int lastRecievedSnapshotID = -1;
|
||||||
public int lastSentSnapshotID = -1;
|
public int lastSentSnapshotID = -1;
|
||||||
|
public IntMap<byte[]> sent = new IntMap<>();
|
||||||
|
|
||||||
/**
|
/**ID of last recieved client snapshot.*/
|
||||||
* ID of last recieved client snapshot.
|
|
||||||
*/
|
|
||||||
public int lastRecievedClientSnapshot = -1;
|
public int lastRecievedClientSnapshot = -1;
|
||||||
/**
|
/**Timestamp of last recieved snapshot.*/
|
||||||
* Timestamp of last recieved snapshot.
|
|
||||||
*/
|
|
||||||
public long lastRecievedClientTime;
|
public long lastRecievedClientTime;
|
||||||
|
|
||||||
public boolean hasConnected = false;
|
public boolean hasConnected = false;
|
||||||
|
|||||||
@@ -155,7 +155,7 @@ public class Packets{
|
|||||||
//player snapshot data
|
//player snapshot data
|
||||||
public float x, y, pointerX, pointerY, rotation, baseRotation, xv, yv;
|
public float x, y, pointerX, pointerY, rotation, baseRotation, xv, yv;
|
||||||
public Tile mining;
|
public Tile mining;
|
||||||
public boolean boosting, shooting;
|
public boolean boosting, shooting, alting;
|
||||||
public Array<BuildRequest> requests = new Array<>();
|
public Array<BuildRequest> requests = new Array<>();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -172,6 +172,7 @@ public class Packets{
|
|||||||
buffer.putFloat(player.pointerY);
|
buffer.putFloat(player.pointerY);
|
||||||
buffer.put(player.isBoosting ? (byte) 1 : 0);
|
buffer.put(player.isBoosting ? (byte) 1 : 0);
|
||||||
buffer.put(player.isShooting ? (byte) 1 : 0);
|
buffer.put(player.isShooting ? (byte) 1 : 0);
|
||||||
|
buffer.put(player.isAlt ? (byte) 1 : 0);
|
||||||
|
|
||||||
buffer.put((byte) (Mathf.clamp(player.getVelocity().x, -Unit.maxAbsVelocity, Unit.maxAbsVelocity) * Unit.velocityPercision));
|
buffer.put((byte) (Mathf.clamp(player.getVelocity().x, -Unit.maxAbsVelocity, Unit.maxAbsVelocity) * Unit.velocityPercision));
|
||||||
buffer.put((byte) (Mathf.clamp(player.getVelocity().y, -Unit.maxAbsVelocity, Unit.maxAbsVelocity) * Unit.velocityPercision));
|
buffer.put((byte) (Mathf.clamp(player.getVelocity().y, -Unit.maxAbsVelocity, Unit.maxAbsVelocity) * Unit.velocityPercision));
|
||||||
@@ -204,6 +205,7 @@ public class Packets{
|
|||||||
pointerY = buffer.getFloat();
|
pointerY = buffer.getFloat();
|
||||||
boosting = buffer.get() == 1;
|
boosting = buffer.get() == 1;
|
||||||
shooting = buffer.get() == 1;
|
shooting = buffer.get() == 1;
|
||||||
|
alting = buffer.get() == 1;
|
||||||
xv = buffer.get() / Unit.velocityPercision;
|
xv = buffer.get() / Unit.velocityPercision;
|
||||||
yv = buffer.get() / Unit.velocityPercision;
|
yv = buffer.get() / Unit.velocityPercision;
|
||||||
rotation = buffer.getShort() / 2f;
|
rotation = buffer.getShort() / 2f;
|
||||||
|
|||||||
@@ -81,7 +81,10 @@ public class Weapon implements Content{
|
|||||||
shootDirect(shooter, x, y, rotation, left);
|
shootDirect(shooter, x, y, rotation, left);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void shootDirect(ShooterTrait shooter, float x, float y, float rotation, boolean left){
|
public static void shootDirect(ShooterTrait shooter, float offsetX, float offsetY, float rotation, boolean left){
|
||||||
|
float x = shooter.getX() + offsetX;
|
||||||
|
float y = shooter.getY() + offsetY;
|
||||||
|
|
||||||
Weapon weapon = shooter.getWeapon();
|
Weapon weapon = shooter.getWeapon();
|
||||||
|
|
||||||
Angles.shotgun(weapon.shots, weapon.spacing, rotation, f -> weapon.bullet(shooter, x, y, f + Mathf.range(weapon.inaccuracy)));
|
Angles.shotgun(weapon.shots, weapon.spacing, rotation, f -> weapon.bullet(shooter, x, y, f + Mathf.range(weapon.inaccuracy)));
|
||||||
@@ -149,7 +152,7 @@ public class Weapon implements Content{
|
|||||||
float ang = tr.angle();
|
float ang = tr.angle();
|
||||||
tr.trns(ang - 90, width * Mathf.sign(left), length);
|
tr.trns(ang - 90, width * Mathf.sign(left), length);
|
||||||
|
|
||||||
shoot(shooter, shooter.getX() + tr.x, shooter.getY() + tr.y, Angles.angle(shooter.getX() + tr.x, shooter.getY() + tr.y, cx, cy), left);
|
shoot(shooter, tr.x, tr.y, Angles.angle(shooter.getX() + tr.x, shooter.getY() + tr.y, cx, cy), left);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -352,7 +352,9 @@ public class JoinDialog extends FloatingDialog{
|
|||||||
this.ip = ip;
|
this.ip = ip;
|
||||||
this.port = Vars.port;
|
this.port = Vars.port;
|
||||||
}
|
}
|
||||||
|
}else{
|
||||||
|
this.ip = ip;
|
||||||
|
this.port = Vars.port;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -179,6 +179,10 @@ public class CoreBlock extends StorageBlock{
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(entity.currentUnit != null){
|
if(entity.currentUnit != null){
|
||||||
|
if(!entity.currentUnit.isDead()){
|
||||||
|
entity.currentUnit = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
entity.heat = Mathf.lerpDelta(entity.heat, 1f, 0.1f);
|
entity.heat = Mathf.lerpDelta(entity.heat, 1f, 0.1f);
|
||||||
entity.time += Timers.delta();
|
entity.time += Timers.delta();
|
||||||
entity.progress += 1f / (entity.currentUnit instanceof Player ? state.mode.respawnTime : droneRespawnDuration) * Timers.delta();
|
entity.progress += 1f / (entity.currentUnit instanceof Player ? state.mode.respawnTime : droneRespawnDuration) * Timers.delta();
|
||||||
|
|||||||
@@ -163,6 +163,7 @@ public class ServerControl extends Module{
|
|||||||
|
|
||||||
handler.register("stop", "Stop hosting the server.", arg -> {
|
handler.register("stop", "Stop hosting the server.", arg -> {
|
||||||
Net.closeServer();
|
Net.closeServer();
|
||||||
|
Timers.clear();
|
||||||
state.set(State.menu);
|
state.set(State.menu);
|
||||||
netServer.reset();
|
netServer.reset();
|
||||||
Log.info("Stopped server.");
|
Log.info("Stopped server.");
|
||||||
@@ -889,6 +890,7 @@ public class ServerControl extends Module{
|
|||||||
private void play(boolean wait, Runnable run){
|
private void play(boolean wait, Runnable run){
|
||||||
inExtraRound = true;
|
inExtraRound = true;
|
||||||
Runnable r = () -> {
|
Runnable r = () -> {
|
||||||
|
|
||||||
Array<Player> players = new Array<>();
|
Array<Player> players = new Array<>();
|
||||||
for(Player p : playerGroup.all()){
|
for(Player p : playerGroup.all()){
|
||||||
players.add(p);
|
players.add(p);
|
||||||
@@ -906,7 +908,7 @@ public class ServerControl extends Module{
|
|||||||
};
|
};
|
||||||
|
|
||||||
if(wait){
|
if(wait){
|
||||||
Timers.runTask(60f * roundExtraTime, r);
|
Timers.run(60f * roundExtraTime, r);
|
||||||
}else{
|
}else{
|
||||||
r.run();
|
r.run();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user