diff --git a/Server/src/main/content/global/handlers/iface/LogoutInterface.java b/Server/src/main/content/global/handlers/iface/LogoutInterface.java index ba1784c8f..d3a7c9c1a 100644 --- a/Server/src/main/content/global/handlers/iface/LogoutInterface.java +++ b/Server/src/main/content/global/handlers/iface/LogoutInterface.java @@ -7,6 +7,7 @@ import core.game.node.entity.player.Player; import core.game.world.GameWorld; import core.plugin.Initializable; import core.plugin.Plugin; +import core.game.world.repository.Repository; /** * Represents the interface used to logout of the game. @@ -31,10 +32,11 @@ public final class LogoutInterface extends ComponentPlugin { player.getPacketDispatch().sendMessage("You can't log out until 10 seconds after the end of combat."); return true; } - if (player.getAttribute("logoutDelay", 0) < GameWorld.getTicks()) { - player.getPacketDispatch().sendLogout(); - player.setAttribute("logoutDelay", GameWorld.getTicks() + 3); - } + if (player.isTeleporting()) { + player.sendMessage("Please finish your teleport before logging out."); + return true; + } + Repository.getDisconnectionQueue().add(player); return true; } } diff --git a/Server/src/main/core/game/node/entity/Entity.java b/Server/src/main/core/game/node/entity/Entity.java index 5da08ee16..d6b7e4e26 100644 --- a/Server/src/main/core/game/node/entity/Entity.java +++ b/Server/src/main/core/game/node/entity/Entity.java @@ -990,4 +990,8 @@ public abstract class Entity extends Node { public boolean delayed() { return scripts.getDelay() > GameWorld.getTicks(); } + + public boolean isTeleporting() { + return getAttribute("tele-pulse", null) != null || properties.getTeleportLocation() != null; + } } diff --git a/Server/src/main/core/game/node/entity/player/Player.java b/Server/src/main/core/game/node/entity/player/Player.java index f0481e9e8..458069690 100644 --- a/Server/src/main/core/game/node/entity/player/Player.java +++ b/Server/src/main/core/game/node/entity/player/Player.java @@ -578,6 +578,7 @@ public class Player extends Entity { @Override public void commenceDeath(Entity killer) { + if (!isPlaying()) return; super.commenceDeath(killer); if (prayer.get(PrayerType.RETRIBUTION)) { prayer.startRetribution(killer); @@ -586,6 +587,7 @@ public class Player extends Entity { @Override public void finalizeDeath(Entity killer) { + if (!isPlaying()) return; //if the player has already been full cleared, it has already disconnected. This code is probably getting called because something is maintaining a stale reference. GlobalStats.incrementDeathCount(); settings.setSpecialEnergy(100); settings.updateRunEnergy(settings.getRunEnergy() - 100); @@ -904,7 +906,7 @@ public class Player extends Entity { * @return {@code True} if so. */ public boolean allowRemoval() { - return !(inCombat() || getSkills().getLifepoints() < 1 || DeathTask.isDead(this)); + return !(inCombat() || getSkills().getLifepoints() < 1 || DeathTask.isDead(this) || isTeleporting()); } /** diff --git a/Server/src/main/core/game/node/entity/player/link/TeleportManager.java b/Server/src/main/core/game/node/entity/player/link/TeleportManager.java index f6cbf4f4f..e74ef3752 100644 --- a/Server/src/main/core/game/node/entity/player/link/TeleportManager.java +++ b/Server/src/main/core/game/node/entity/player/link/TeleportManager.java @@ -177,6 +177,7 @@ public class TeleportManager { return currentTeleport; } + /** * Represents a NodeType for Teleporter * @author SonicForce41 @@ -189,7 +190,7 @@ public class TeleportManager { NORMAL(new TeleportSettings(8939, 8941, 1576, 1577)) { @Override public Pulse getPulse(final Entity entity, final Location location) { - return new Pulse(1) { + return new TeleportPulse(entity) { int delay = 0; @Override @@ -227,7 +228,7 @@ public class TeleportManager { ANCIENT(new TeleportSettings(1979, -1, 392, -1)) { @Override public Pulse getPulse(final Entity entity, final Location location) { - return new Pulse(1) { + return new TeleportPulse(entity) { int delay = 0; @Override @@ -260,7 +261,7 @@ public class TeleportManager { LUNAR(new TeleportSettings(1816, -1, 747, -1)) { @Override public Pulse getPulse(final Entity entity, final Location location) { - return new Pulse(1) { + return new TeleportPulse(entity) { int delay = 0; @Override @@ -293,7 +294,7 @@ public class TeleportManager { TELETABS(new TeleportSettings(4731, -1, 678, -1)) { @Override public Pulse getPulse(final Entity entity, final Location location) { - return new Pulse(1) { + return new TeleportPulse(entity) { int delay = 0; @Override @@ -331,7 +332,7 @@ public class TeleportManager { HOME(new TeleportSettings(4847, 4857, 800, 804)) { @Override public Pulse getPulse(final Entity entity, final Location location) { - return new Pulse(1) { + return new TeleportPulse(entity) { int count; Player player; @@ -382,7 +383,7 @@ public class TeleportManager { OBELISK(new TeleportSettings(8939, 8941, 661, -1)) { @Override public Pulse getPulse(final Entity entity, final Location location) { - return new Pulse(1) { + return new TeleportPulse(entity) { int delay = 0; @Override @@ -406,7 +407,7 @@ public class TeleportManager { TELE_OTHER(new TeleportSettings(1816, -1, 342, -1)) { @Override public Pulse getPulse(final Entity entity, final Location location) { - return new Pulse(1) { + return new TeleportPulse(entity) { int delay = 0; @Override @@ -434,7 +435,7 @@ public class TeleportManager { @Override public Pulse getPulse(final Entity entity, final Location location) { entity.graphics(Graphics.create(569)); - return new Pulse(1, entity) { + return new TeleportPulse(entity) { int delay; @Override @@ -462,7 +463,7 @@ public class TeleportManager { PURO_PURO(new TeleportSettings(6601, 1118, -1, -1)) { @Override public Pulse getPulse(final Entity entity, final Location location) { - return new Pulse(1) { + return new TeleportPulse(entity) { int delay = 0; @Override @@ -485,7 +486,7 @@ public class TeleportManager { ECTOPHIAL(new TeleportSettings(8939, 8941, 1587, 1588)) { @Override public Pulse getPulse(final Entity entity, final Location location) { - return new Pulse(1) { + return new TeleportPulse(entity) { int delay = 0; @Override @@ -523,7 +524,7 @@ public class TeleportManager { CHRISTMAS(new TeleportSettings(7534, -1, 1292, -1)) { @Override public Pulse getPulse(final Entity entity, final Location location) { - return new Pulse(1) { + return new TeleportPulse(entity) { int delay = 0; @Override @@ -561,7 +562,7 @@ public class TeleportManager { CABBAGE(new TeleportSettings(9984, 9986, 1731, 1732)) { @Override public Pulse getPulse(final Entity entity, final Location location) { - return new Pulse(1) { + return new TeleportPulse(entity) { int delay = 0; @Override @@ -598,7 +599,7 @@ public class TeleportManager { ENTRANA_MAGIC_DOOR(new TeleportSettings(10100, 9013, 1745, 1747)) { // @Override public Pulse getPulse(final Entity entity, final Location location) { - return new Pulse(1) { + return new TeleportPulse(entity) { int delay = 0; @Override @@ -636,7 +637,7 @@ public class TeleportManager { MINIGAME(new TeleportSettings(6601, 1118, -1, -1)) { @Override public Pulse getPulse(final Entity entity, final Location location) { - return new Pulse(1) { + return new TeleportPulse(entity) { int delay = 0; Player player; @@ -673,7 +674,7 @@ public class TeleportManager { INSTANT(new TeleportSettings(-1, -1, -1, -1)) { @Override public Pulse getPulse(final Entity entity, final Location location) { - return new Pulse(1) { + return new TeleportPulse(entity) { int delay = 0; @Override diff --git a/Server/src/main/core/game/node/entity/player/link/TeleportPulse.java b/Server/src/main/core/game/node/entity/player/link/TeleportPulse.java new file mode 100644 index 000000000..31d76f3b0 --- /dev/null +++ b/Server/src/main/core/game/node/entity/player/link/TeleportPulse.java @@ -0,0 +1,24 @@ +package core.game.node.entity.player.link; + +import core.game.system.task.Pulse; +import core.game.node.entity.Entity; + +abstract class TeleportPulse extends Pulse { + private Entity entity; + + public TeleportPulse(Entity e) { this.entity = e; } + + public abstract boolean pulse(); + + @Override + public void start() { + entity.setAttribute("tele-pulse", this); + super.start(); + } + + @Override + public void stop() { + entity.removeAttribute("tele-pulse"); + super.stop(); + } +} diff --git a/Server/src/main/core/game/world/repository/DisconnectionQueue.kt b/Server/src/main/core/game/world/repository/DisconnectionQueue.kt index 8727bd4b7..58d9fdd22 100644 --- a/Server/src/main/core/game/world/repository/DisconnectionQueue.kt +++ b/Server/src/main/core/game/world/repository/DisconnectionQueue.kt @@ -64,6 +64,7 @@ class DisconnectionQueue { if (!force && !player.allowRemoval()) { return false } + player.packetDispatch.sendLogout() player.finishClear() Repository.removePlayer(player) try { diff --git a/Server/src/main/core/net/packet/PacketWriteQueue.kt b/Server/src/main/core/net/packet/PacketWriteQueue.kt index 131661b57..fad453300 100644 --- a/Server/src/main/core/net/packet/PacketWriteQueue.kt +++ b/Server/src/main/core/net/packet/PacketWriteQueue.kt @@ -21,6 +21,7 @@ class PacketWriteQueue { is UpdateSceneGraph, is BuildDynamicScene, is InstancedLocationUpdate, + is Logout, is ClearRegionChunk -> packet.send(context) //Rest get queued up and sent at the end of the tick (authentic) else -> push(packet, context) @@ -65,4 +66,4 @@ class PacketWriteQueue { } } -class QueuedPacket(val out: OutgoingPacket, val context: T) \ No newline at end of file +class QueuedPacket(val out: OutgoingPacket, val context: T) diff --git a/Server/src/test/kotlin/TestUtils.kt b/Server/src/test/kotlin/TestUtils.kt index f0f2e101e..fdd128f3f 100644 --- a/Server/src/test/kotlin/TestUtils.kt +++ b/Server/src/test/kotlin/TestUtils.kt @@ -30,6 +30,7 @@ object TestUtils { val p = MockPlayer(name) p.ironmanManager.mode = ironman p.details.accountInfo.uid = uidCounter++ + p.setPlaying(true); Repository.addPlayer(p) //Update sequence has a separate list of players for some reason... UpdateSequence.renderablePlayers.add(p)