diff --git a/core/src/io/anuke/mindustry/content/Mechs.java b/core/src/io/anuke/mindustry/content/Mechs.java index 234d5b9ef3..e92e2236f8 100644 --- a/core/src/io/anuke/mindustry/content/Mechs.java +++ b/core/src/io/anuke/mindustry/content/Mechs.java @@ -47,7 +47,7 @@ public class Mechs implements ContentList{ boostSpeed = 0.85f; weapon = Weapons.blaster; maxSpeed = 4f; - altChargeAlpha = 0.04f; + altChargeAlpha = 0.02f; trailColorTo = Color.valueOf("ffd37f"); armor = 20f; } @@ -64,8 +64,8 @@ public class Mechs implements ContentList{ drone.leader = player; drone.set(player.x, player.y); drone.add(); - Effects.effect(UnitFx.unitLand, player); } + Effects.effect(UnitFx.unitLand, player); player.altHeat = 0f; } } diff --git a/core/src/io/anuke/mindustry/content/UnitTypes.java b/core/src/io/anuke/mindustry/content/UnitTypes.java index a8f76006ed..7521d0a666 100644 --- a/core/src/io/anuke/mindustry/content/UnitTypes.java +++ b/core/src/io/anuke/mindustry/content/UnitTypes.java @@ -30,7 +30,7 @@ public class UnitTypes implements ContentList{ speed = 0.5f; maxVelocity = 1.6f; range = 40f; - health = 20; + health = 30; weapon = Weapons.droneBlaster; trailColor = Color.valueOf("ffd37f"); } diff --git a/core/src/io/anuke/mindustry/core/NetClient.java b/core/src/io/anuke/mindustry/core/NetClient.java index 839e6aab10..273f8d1746 100644 --- a/core/src/io/anuke/mindustry/core/NetClient.java +++ b/core/src/io/anuke/mindustry/core/NetClient.java @@ -3,12 +3,16 @@ package io.anuke.mindustry.core; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.Color; 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 io.anuke.annotations.Annotations.PacketPriority; import io.anuke.annotations.Annotations.Remote; import io.anuke.annotations.Annotations.Variant; import io.anuke.mindustry.core.GameState.State; 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.TypeTrait; 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.Packets.*; import io.anuke.mindustry.net.TraceInfo; +import io.anuke.mindustry.world.modules.InventoryModule; import io.anuke.ucore.core.Settings; import io.anuke.ucore.core.Timers; import io.anuke.ucore.entities.Entities; @@ -41,6 +46,7 @@ import static io.anuke.mindustry.Vars.*; public class NetClient extends Module{ private final static float dataTimeout = 60 * 18; private final static float playerSyncTime = 2; + private final static IntArray removals = new IntArray(); private Timer timer = new Timer(5); /**Whether the client is currently connecting.*/ @@ -54,8 +60,8 @@ public class NetClient extends Module{ /**Last snapshot ID recieved.*/ private int lastSnapshotBaseID = -1; - /**Last snapshot recieved.*/ - private byte[] lastSnapshotBase; + + private IntMap recievedSnapshots = new IntMap<>(); /**Current snapshot that is being built from chinks.*/ private byte[] currentSnapshot; /**Array of recieved chunk statuses.*/ @@ -191,12 +197,12 @@ public class NetClient extends Module{ @Remote(variants = Variant.one, priority = PacketPriority.low, unreliable = true) 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); //skip snapshot IDs that have already been recieved OR snapshots that are too far in front - if(snapshotID < netClient.lastSnapshotBaseID || base != netClient.lastSnapshotBaseID){ - if(NetServer.showSnapshotSize) Log.info("//SKIP SNAPSHOT"); + if(base != -1 && (snapshotID < netClient.lastSnapshotBaseID || !netClient.recievedSnapshots.containsKey(base))){ + if(NetServer.debugSnapshots) Log.info("//SKIP SNAPSHOT"); return; } @@ -235,7 +241,7 @@ public class NetClient extends Module{ snapshot = chunk; } - if(NetServer.showSnapshotSize) + if(NetServer.debugSnapshots) Log.info("Finished recieving snapshot ID {0} length {1}", snapshotID, chunk.length); byte[] result; @@ -243,20 +249,21 @@ public class NetClient extends Module{ if(base == -1){ //fresh snapshot result = snapshot; 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 - if(NetServer.showSnapshotSize) - Log.info("Base size: {0} Patch size: {1}", netClient.lastSnapshotBase.length, snapshot.length); - netClient.decoder.init(netClient.lastSnapshotBase, snapshot); + byte[] baseBytes = netClient.recievedSnapshots.get(base); + if(NetServer.debugSnapshots) + Log.info("Base size: {0} Patch size: {1}", baseBytes.length, snapshot.length); + netClient.decoder.init(baseBytes, snapshot); result = netClient.decoder.decode(); length = netClient.decoder.getDecodedLength(); //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; - //set stream bytes to begin snapshot reaeding + //set stream bytes to begin snapshot reading netClient.byteStream.setBytes(result, 0, length); //get data input for reading from the stream @@ -266,6 +273,16 @@ public class NetClient extends Module{ //confirm that snapshot has been recieved netClient.lastSnapshotBaseID = snapshotID; + + removals.clear(); + for(Entry 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){ throw new RuntimeException(e); } @@ -280,7 +297,12 @@ public class NetClient extends Module{ byte cores = input.readByte(); for(int i = 0; i < cores; i++){ 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(); @@ -364,7 +386,7 @@ public class NetClient extends Module{ connecting = true; quiet = false; lastSent = 0; - lastSnapshotBase = null; + recievedSnapshots.clear(); currentSnapshot = null; currentSnapshotID = -1; lastSnapshotBaseID = -1; diff --git a/core/src/io/anuke/mindustry/core/NetServer.java b/core/src/io/anuke/mindustry/core/NetServer.java index 4e78ffe845..95e6c0bdda 100644 --- a/core/src/io/anuke/mindustry/core/NetServer.java +++ b/core/src/io/anuke/mindustry/core/NetServer.java @@ -4,6 +4,7 @@ import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.Colors; import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.utils.Array; +import com.badlogic.gdx.utils.IntArray; import com.badlogic.gdx.utils.IntMap; import com.badlogic.gdx.utils.TimeUtils; import io.anuke.annotations.Annotations.Loc; @@ -45,11 +46,15 @@ import static io.anuke.mindustry.Vars.*; public class NetServer extends Module{ 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 float serverSyncTime = 4, kickDuration = 30 * 1000; 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.*/ private final static float correctDist = 16f; @@ -215,6 +220,7 @@ public class NetServer extends Module{ player.setMineTile(packet.mining); player.isBoosting = packet.boosting; player.isShooting = packet.shooting; + player.isAlt = packet.alting; player.getPlaceQueue().clear(); for(BuildRequest req : packet.requests){ //auto-skip done requests @@ -231,7 +237,7 @@ public class NetServer extends Module{ float prevx = player.x, prevy = player.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); }else{ 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 //when the client confirms recieveing a snapshot, update base and clear map - if(packet.lastSnapshot > connection.currentBaseID){ - connection.currentBaseID = packet.lastSnapshot; - connection.currentBaseSnapshot = connection.lastSentRawSnapshot; + if(packet.lastSnapshot > connection.lastRecievedSnapshotID){ + connection.lastRecievedSnapshotID = packet.lastSnapshot; + 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; @@ -285,7 +300,7 @@ public class NetServer extends Module{ /** 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){ 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{ int remaining = bytes.length; int offset = 0; @@ -294,13 +309,15 @@ public class NetServer extends Module{ int used = Math.min(remaining, maxSnapshotSize); byte[] toSend; //re-use sent byte arrays when possible - if(used == maxSnapshotSize){ + if(used == maxSnapshotSize && !debugSnapshots){ toSend = reusableSnapArray; System.arraycopy(bytes, offset, toSend, 0, Math.min(offset + maxSnapshotSize, bytes.length) - offset); }else{ 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; 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){ ByteArrayOutputStream stream = new ByteArrayOutputStream(); 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){ if(name.equals("[") || name.equals("]")){ return ""; @@ -559,12 +582,12 @@ public class NetServer extends Module{ 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(connection.currentBaseID < connection.lastSentSnapshotID){ - if(showSnapshotSize) + /*if(connection.currentBaseID < connection.lastSentSnapshotID){ + 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); sendSplitSnapshot(connection.id, connection.lastSentSnapshot, connection.lastSentSnapshotID, connection.lastSentBase); return; - } + }*/ //reset stream to begin writing syncStream.reset(); @@ -573,29 +596,28 @@ public class NetServer extends Module{ byte[] bytes = syncStream.toByteArray(); - if(connection.currentBaseID == -1){ - //assign to last sent snapshot so that there is only ever one unique snapshot with ID 0 - if(connection.lastSentSnapshot != null){ + int snapid = connection.lastSentSnapshotID ++; + + if(connection.lastRecievedSnapshotID == -1){ + /*if(connection.lastSentSnapshot != null){ bytes = connection.lastSentSnapshot; }else{ connection.lastSentRawSnapshot = 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 - sendSplitSnapshot(connection.id, bytes, 0, -1); + sendSplitSnapshot(connection.id, bytes, snapid, -1); + connection.sent.put(snapid, bytes); }else{ - connection.lastSentRawSnapshot = bytes; - //send diff, otherwise - byte[] diff = ByteDeltaEncoder.toDiff(new ByteMatcherHash(connection.currentBaseSnapshot, bytes), encoder); - if(showSnapshotSize) - 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); - sendSplitSnapshot(connection.id, diff, connection.currentBaseID + 1, connection.currentBaseID); - connection.lastSentSnapshot = diff; - connection.lastSentSnapshotID = connection.currentBaseID + 1; - connection.lastSentBase = connection.currentBaseID; + byte[] diff = ByteDeltaEncoder.toDiff(new ByteMatcherHash(connection.sent.get(connection.lastRecievedSnapshotID), bytes), encoder); + if(debugSnapshots) + Log.info("Shrank snapshot: {0} -> {1}, Base {2}", bytes.length, diff.length, connection.lastRecievedSnapshotID); + + sendSplitSnapshot(connection.id, diff, snapid, connection.lastRecievedSnapshotID); + connection.sent.put(snapid, bytes); } } diff --git a/core/src/io/anuke/mindustry/entities/Player.java b/core/src/io/anuke/mindustry/entities/Player.java index dfd24c32c6..8f9e2c6f52 100644 --- a/core/src/io/anuke/mindustry/entities/Player.java +++ b/core/src/io/anuke/mindustry/entities/Player.java @@ -460,6 +460,7 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra 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); + mech.updateAlt(this); //updated regardless if(!isLocal){ interpolate(); @@ -480,8 +481,6 @@ public class Player extends Unit implements BuilderTrait, CarryTrait, ShooterTra control.database().unlockContent(mech); } - mech.updateAlt(this); - if(mobile){ updateFlying(); }else{ diff --git a/core/src/io/anuke/mindustry/entities/units/types/AlphaDrone.java b/core/src/io/anuke/mindustry/entities/units/types/AlphaDrone.java index 9165b69cb1..b7962d530a 100644 --- a/core/src/io/anuke/mindustry/entities/units/types/AlphaDrone.java +++ b/core/src/io/anuke/mindustry/entities/units/types/AlphaDrone.java @@ -23,7 +23,7 @@ public class AlphaDrone extends FlyingUnit { public final UnitState attack = new UnitState() { @Override public void update() { - if(leader == null || leader.isDead()){ + if(leader == null || leader.isDead() || !leader.isAdded()){ damage(99999f); return; } @@ -67,12 +67,19 @@ public class AlphaDrone extends FlyingUnit { } @Override - public void writeSave(DataOutput stream) throws IOException { - super.writeSave(stream); + public void write(DataOutput stream) throws IOException { + super.write(stream); + stream.writeInt(leader == null ? -1 : leader.id); } @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); if(!Net.active()){ diff --git a/core/src/io/anuke/mindustry/net/Interpolator.java b/core/src/io/anuke/mindustry/net/Interpolator.java index 9748544b28..b184875d88 100644 --- a/core/src/io/anuke/mindustry/net/Interpolator.java +++ b/core/src/io/anuke/mindustry/net/Interpolator.java @@ -19,7 +19,7 @@ public class Interpolator{ public void read(float cx, float cy, float x, float y, long sent, float... target1ds){ if(lastUpdated != 0) updateSpacing = TimeUtils.timeSinceMillis(lastUpdated); - lastUpdated = sent; + lastUpdated = TimeUtils.millis(); targets = target1ds; last.set(cx, cy); diff --git a/core/src/io/anuke/mindustry/net/NetConnection.java b/core/src/io/anuke/mindustry/net/NetConnection.java index e8e3c7697b..f50f657b4f 100644 --- a/core/src/io/anuke/mindustry/net/NetConnection.java +++ b/core/src/io/anuke/mindustry/net/NetConnection.java @@ -1,5 +1,6 @@ package io.anuke.mindustry.net; +import com.badlogic.gdx.utils.IntMap; import io.anuke.mindustry.net.Net.SendMode; 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. * 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. */ - public int currentBaseID = -1; + // public int currentBaseID = -1; - public int lastSentBase = -1; - public byte[] lastSentSnapshot; - public byte[] lastSentRawSnapshot; + //public int lastSentBase = -1; + // public byte[] lastSentSnapshot; + //public byte[] lastSentRawSnapshot; + public int lastRecievedSnapshotID = -1; public int lastSentSnapshotID = -1; + public IntMap sent = new IntMap<>(); - /** - * ID of last recieved client snapshot. - */ + /**ID of last recieved client snapshot.*/ public int lastRecievedClientSnapshot = -1; - /** - * Timestamp of last recieved snapshot. - */ + /**Timestamp of last recieved snapshot.*/ public long lastRecievedClientTime; public boolean hasConnected = false; diff --git a/core/src/io/anuke/mindustry/net/Packets.java b/core/src/io/anuke/mindustry/net/Packets.java index 579dff792f..9e9dfb36f2 100644 --- a/core/src/io/anuke/mindustry/net/Packets.java +++ b/core/src/io/anuke/mindustry/net/Packets.java @@ -155,7 +155,7 @@ public class Packets{ //player snapshot data public float x, y, pointerX, pointerY, rotation, baseRotation, xv, yv; public Tile mining; - public boolean boosting, shooting; + public boolean boosting, shooting, alting; public Array requests = new Array<>(); @Override @@ -172,6 +172,7 @@ public class Packets{ buffer.putFloat(player.pointerY); buffer.put(player.isBoosting ? (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().y, -Unit.maxAbsVelocity, Unit.maxAbsVelocity) * Unit.velocityPercision)); @@ -204,6 +205,7 @@ public class Packets{ pointerY = buffer.getFloat(); boosting = buffer.get() == 1; shooting = buffer.get() == 1; + alting = buffer.get() == 1; xv = buffer.get() / Unit.velocityPercision; yv = buffer.get() / Unit.velocityPercision; rotation = buffer.getShort() / 2f; diff --git a/core/src/io/anuke/mindustry/type/Weapon.java b/core/src/io/anuke/mindustry/type/Weapon.java index 30cfaa4495..0f02804f14 100644 --- a/core/src/io/anuke/mindustry/type/Weapon.java +++ b/core/src/io/anuke/mindustry/type/Weapon.java @@ -81,7 +81,10 @@ public class Weapon implements Content{ 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(); 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(); 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); } } diff --git a/core/src/io/anuke/mindustry/ui/dialogs/JoinDialog.java b/core/src/io/anuke/mindustry/ui/dialogs/JoinDialog.java index 2c7e082277..b3b6c4ac99 100644 --- a/core/src/io/anuke/mindustry/ui/dialogs/JoinDialog.java +++ b/core/src/io/anuke/mindustry/ui/dialogs/JoinDialog.java @@ -352,7 +352,9 @@ public class JoinDialog extends FloatingDialog{ this.ip = ip; this.port = Vars.port; } - + }else{ + this.ip = ip; + this.port = Vars.port; } } diff --git a/core/src/io/anuke/mindustry/world/blocks/storage/CoreBlock.java b/core/src/io/anuke/mindustry/world/blocks/storage/CoreBlock.java index 30aa00c154..9ff5d3c47d 100644 --- a/core/src/io/anuke/mindustry/world/blocks/storage/CoreBlock.java +++ b/core/src/io/anuke/mindustry/world/blocks/storage/CoreBlock.java @@ -179,6 +179,10 @@ public class CoreBlock extends StorageBlock{ } if(entity.currentUnit != null){ + if(!entity.currentUnit.isDead()){ + entity.currentUnit = null; + return; + } entity.heat = Mathf.lerpDelta(entity.heat, 1f, 0.1f); entity.time += Timers.delta(); entity.progress += 1f / (entity.currentUnit instanceof Player ? state.mode.respawnTime : droneRespawnDuration) * Timers.delta(); diff --git a/server/src/io/anuke/mindustry/server/ServerControl.java b/server/src/io/anuke/mindustry/server/ServerControl.java index 507e45f544..a579ca4710 100644 --- a/server/src/io/anuke/mindustry/server/ServerControl.java +++ b/server/src/io/anuke/mindustry/server/ServerControl.java @@ -163,6 +163,7 @@ public class ServerControl extends Module{ handler.register("stop", "Stop hosting the server.", arg -> { Net.closeServer(); + Timers.clear(); state.set(State.menu); netServer.reset(); Log.info("Stopped server."); @@ -889,6 +890,7 @@ public class ServerControl extends Module{ private void play(boolean wait, Runnable run){ inExtraRound = true; Runnable r = () -> { + Array players = new Array<>(); for(Player p : playerGroup.all()){ players.add(p); @@ -906,7 +908,7 @@ public class ServerControl extends Module{ }; if(wait){ - Timers.runTask(60f * roundExtraTime, r); + Timers.run(60f * roundExtraTime, r); }else{ r.run(); }