Improved build sync
This commit is contained in:
@@ -9,6 +9,7 @@ import com.badlogic.gdx.utils.TimeUtils;
|
|||||||
import io.anuke.annotations.Annotations.Loc;
|
import io.anuke.annotations.Annotations.Loc;
|
||||||
import io.anuke.annotations.Annotations.Remote;
|
import io.anuke.annotations.Annotations.Remote;
|
||||||
import io.anuke.mindustry.content.Mechs;
|
import io.anuke.mindustry.content.Mechs;
|
||||||
|
import io.anuke.mindustry.content.blocks.Blocks;
|
||||||
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.traits.BuilderTrait.BuildRequest;
|
import io.anuke.mindustry.entities.traits.BuilderTrait.BuildRequest;
|
||||||
@@ -202,6 +203,12 @@ public class NetServer extends Module{
|
|||||||
player.isShooting = packet.shooting;
|
player.isShooting = packet.shooting;
|
||||||
player.getPlaceQueue().clear();
|
player.getPlaceQueue().clear();
|
||||||
for(BuildRequest req : packet.requests){
|
for(BuildRequest req : packet.requests){
|
||||||
|
//auto-skip done requests
|
||||||
|
if(req.remove && world.tile(req.x, req.y).block() == Blocks.air){
|
||||||
|
continue;
|
||||||
|
}else if(!req.remove && world.tile(req.x, req.y).block() == req.recipe.result && (!req.recipe.result.rotate || world.tile(req.x, req.y).getRotation() == req.rotation)){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
player.getPlaceQueue().addLast(req);
|
player.getPlaceQueue().addLast(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -108,6 +108,8 @@ public interface BuilderTrait extends Entity{
|
|||||||
|
|
||||||
if(applyChanges){
|
if(applyChanges){
|
||||||
getPlaceQueue().addLast(request);
|
getPlaceQueue().addLast(request);
|
||||||
|
}else if(isBuilding()){
|
||||||
|
getCurrentRequest().progress = progress;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -149,6 +151,10 @@ public interface BuilderTrait extends Entity{
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Tile tile = world.tile(place.x, place.y);
|
||||||
|
if(tile != null && tile.entity instanceof BuildEntity){
|
||||||
|
place.progress = tile.<BuildEntity>entity().progress;
|
||||||
|
}
|
||||||
getPlaceQueue().addLast(place);
|
getPlaceQueue().addLast(place);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -226,6 +232,8 @@ public interface BuilderTrait extends Entity{
|
|||||||
}
|
}
|
||||||
|
|
||||||
current.progress = entity.progress();
|
current.progress = entity.progress();
|
||||||
|
}else{
|
||||||
|
entity.progress = current.progress;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,89 +0,0 @@
|
|||||||
package io.anuke.kryonet;
|
|
||||||
|
|
||||||
import com.esotericsoftware.kryonet.Connection;
|
|
||||||
import com.esotericsoftware.kryonet.Listener;
|
|
||||||
import com.esotericsoftware.kryonet.Listener.QueuedListener;
|
|
||||||
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
public class CustomListeners {
|
|
||||||
|
|
||||||
static public class LagListener extends QueuedListener {
|
|
||||||
protected final ScheduledExecutorService threadPool;
|
|
||||||
private final int lagMillisMin, lagMillisMax;
|
|
||||||
final LinkedList<Runnable> runnables = new LinkedList<>();
|
|
||||||
|
|
||||||
public LagListener (int lagMillisMin, int lagMillisMax, Listener listener) {
|
|
||||||
super(listener);
|
|
||||||
this.lagMillisMin = lagMillisMin;
|
|
||||||
this.lagMillisMax = lagMillisMax;
|
|
||||||
threadPool = Executors.newScheduledThreadPool(1, r -> {
|
|
||||||
Thread t = Executors.defaultThreadFactory().newThread(r);
|
|
||||||
t.setDaemon(true);
|
|
||||||
return t;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
protected int calculateLag() {
|
|
||||||
return lagMillisMin + (int)(Math.random() * (lagMillisMax - lagMillisMin));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void queue (Runnable runnable) {
|
|
||||||
|
|
||||||
synchronized (runnables) {
|
|
||||||
runnables.addFirst(runnable);
|
|
||||||
}
|
|
||||||
threadPool.schedule(() -> {
|
|
||||||
Runnable runnable1;
|
|
||||||
synchronized (runnables) {
|
|
||||||
runnable1 = runnables.removeLast();
|
|
||||||
}
|
|
||||||
runnable1.run();
|
|
||||||
}, calculateLag(), TimeUnit.MILLISECONDS);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Delays, reorders and does not make guarantees to the delivery of incoming objects
|
|
||||||
* to the wrapped listener (in order to simulate lag, jitter, package loss and
|
|
||||||
* package duplication).
|
|
||||||
* Notification events are likely processed on a separate thread after a delay.
|
|
||||||
* Note that only the delivery of incoming objects is modified. To modify the delivery
|
|
||||||
* of outgoing objects, use a UnreliableListener at the other end of the connection.
|
|
||||||
*/
|
|
||||||
static public class UnreliableListener extends LagListener {
|
|
||||||
private final float lossPercentage;
|
|
||||||
private final float duplicationPercentage;
|
|
||||||
private final CustomListeners.LagListener tcpListener;
|
|
||||||
|
|
||||||
public UnreliableListener (int lagMillisMin, int lagMillisMax, float lossPercentage,
|
|
||||||
float duplicationPercentage, Listener listener) {
|
|
||||||
super(lagMillisMin, lagMillisMax, listener);
|
|
||||||
this.tcpListener = new CustomListeners.LagListener(lagMillisMin, lagMillisMax, listener);
|
|
||||||
this.lossPercentage = lossPercentage;
|
|
||||||
this.duplicationPercentage = duplicationPercentage;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void received(Connection connection, Object object) {
|
|
||||||
if(KryoCore.lastUDP) {
|
|
||||||
super.received(connection, object);
|
|
||||||
}else{
|
|
||||||
tcpListener.received(connection, object);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void queue (Runnable runnable) {
|
|
||||||
do {
|
|
||||||
if (Math.random() >= lossPercentage) {
|
|
||||||
threadPool.schedule(runnable, calculateLag(), TimeUnit.MILLISECONDS);
|
|
||||||
}
|
|
||||||
} while (Math.random() < duplicationPercentage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -6,7 +6,6 @@ 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.minlog.Log;
|
import com.esotericsoftware.minlog.Log;
|
||||||
import io.anuke.kryonet.CustomListeners.UnreliableListener;
|
|
||||||
import io.anuke.mindustry.net.Host;
|
import io.anuke.mindustry.net.Host;
|
||||||
import io.anuke.mindustry.net.Net;
|
import io.anuke.mindustry.net.Net;
|
||||||
import io.anuke.mindustry.net.Net.ClientProvider;
|
import io.anuke.mindustry.net.Net.ClientProvider;
|
||||||
@@ -100,7 +99,7 @@ public class KryoClient implements ClientProvider{
|
|||||||
};
|
};
|
||||||
|
|
||||||
if(KryoCore.fakeLag){
|
if(KryoCore.fakeLag){
|
||||||
client.addListener(new UnreliableListener(KryoCore.fakeLagMin, KryoCore.fakeLagMax, KryoCore.fakeLagDrop, KryoCore.fakeLagDuplicate, listener));
|
client.addListener(new Listener.LagListener(KryoCore.fakeLagMin, KryoCore.fakeLagMax, listener));
|
||||||
}else{
|
}else{
|
||||||
client.addListener(listener);
|
client.addListener(listener);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,9 +5,9 @@ import com.badlogic.gdx.utils.Array;
|
|||||||
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.kryonet.CustomListeners.UnreliableListener;
|
|
||||||
import io.anuke.mindustry.net.Net;
|
import io.anuke.mindustry.net.Net;
|
||||||
import io.anuke.mindustry.net.Net.SendMode;
|
import io.anuke.mindustry.net.Net.SendMode;
|
||||||
import io.anuke.mindustry.net.Net.ServerProvider;
|
import io.anuke.mindustry.net.Net.ServerProvider;
|
||||||
@@ -100,7 +100,7 @@ public class KryoServer implements ServerProvider {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if(KryoCore.fakeLag){
|
if(KryoCore.fakeLag){
|
||||||
server.addListener(new UnreliableListener(KryoCore.fakeLagMin, KryoCore.fakeLagMax, KryoCore.fakeLagDrop, KryoCore.fakeLagDuplicate, listener));
|
server.addListener(new LagListener(KryoCore.fakeLagMin, KryoCore.fakeLagMax, listener));
|
||||||
}else{
|
}else{
|
||||||
server.addListener(listener);
|
server.addListener(listener);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user