mirror of
https://github.com/Anuken/Mindustry.git
synced 2025-07-31 23:19:43 +07:00
Fixed #5774
This commit is contained in:
@ -45,6 +45,7 @@ abstract class PlayerComp implements UnitController, Entityc, Syncc, Timerc, Dra
|
||||
transient String lastText = "";
|
||||
transient float textFadeTime;
|
||||
transient private Unit lastReadUnit = Nulls.unit;
|
||||
transient private int wrongReadUnits;
|
||||
transient @Nullable Unit justSwitchFrom, justSwitchTo;
|
||||
|
||||
public boolean isBuilder(){
|
||||
@ -104,9 +105,15 @@ abstract class PlayerComp implements UnitController, Entityc, Syncc, Timerc, Dra
|
||||
//reason: we know the server is lying here, essentially skip the unit snapshot because we know the client's information is more recent
|
||||
if(isLocal() && unit == justSwitchFrom && justSwitchFrom != null && justSwitchTo != null){
|
||||
unit = justSwitchTo;
|
||||
//if several snapshots have passed and this unit is still incorrect, something's wrong
|
||||
if(++wrongReadUnits >= 2){
|
||||
justSwitchFrom = null;
|
||||
wrongReadUnits = 0;
|
||||
}
|
||||
}else{
|
||||
justSwitchFrom = null;
|
||||
justSwitchTo = null;
|
||||
wrongReadUnits = 0;
|
||||
}
|
||||
|
||||
//simulate a unit change after sync
|
||||
|
@ -379,15 +379,6 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
||||
throw new ValidateException(player, "Player cannot control a unit.");
|
||||
}
|
||||
|
||||
//TODO problem:
|
||||
//1. server send snapshot
|
||||
//2. client requests to control unit, becomes unit locally
|
||||
//3. snapshot arrives, client now thinks they're in the old unit (!!!)
|
||||
//4. server gets packet that player is in the right unit
|
||||
//5. server sends snapshot
|
||||
//6. client gets snapshot, realizes that they are actually in the unit they selected
|
||||
//7. client gets switched to new unit -> rubberbanding (!!!)
|
||||
|
||||
//clear player unit when they possess a core
|
||||
if(unit == null){ //just clear the unit (is this used?)
|
||||
player.clearUnit();
|
||||
@ -404,6 +395,9 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
||||
if(!player.dead()){
|
||||
Fx.unitSpirit.at(player.x, player.y, 0f, unit);
|
||||
}
|
||||
}else if(net.server()){
|
||||
//reject forwarding the packet if the unit was dead, AI or team
|
||||
throw new ValidateException(player, "Player attempted to control invalid unit.");
|
||||
}
|
||||
|
||||
Events.fire(new UnitControlEvent(player, unit));
|
||||
|
@ -77,9 +77,10 @@ public class ContentParser{
|
||||
}
|
||||
});
|
||||
put(StatusEffect.class, (type, data) -> {
|
||||
Object result = fieldOpt(StatusEffects.class, data);
|
||||
if(result != null){
|
||||
return result;
|
||||
if(data.isString()){
|
||||
StatusEffect result = locate(ContentType.status, data.asString());
|
||||
if(result != null) return result;
|
||||
throw new IllegalArgumentException("Unknown status effect: '" + data.asString() + "'");
|
||||
}
|
||||
StatusEffect effect = new StatusEffect(currentMod.name + "-" + data.getString("name"));
|
||||
readFields(effect, data);
|
||||
|
@ -287,7 +287,6 @@ public class ServerControl implements ApplicationListener{
|
||||
Core.app.exit();
|
||||
});
|
||||
|
||||
|
||||
handler.register("stop", "Stop hosting the server.", arg -> {
|
||||
net.closeServer();
|
||||
if(lastTask != null) lastTask.cancel();
|
||||
|
Reference in New Issue
Block a user