diff --git a/src/main/java/emu/nebula/game/GameContext.java b/src/main/java/emu/nebula/game/GameContext.java index 1542bb6..5e14d40 100644 --- a/src/main/java/emu/nebula/game/GameContext.java +++ b/src/main/java/emu/nebula/game/GameContext.java @@ -65,12 +65,12 @@ public class GameContext { while (it.hasNext()) { var session = it.next().getValue(); - if (timeout > session.getLastActiveTime()) { + if (timeout > session.getLastActiveTime() || session.isRemove()) { // Remove from session map it.remove(); // Clear player - session.clearPlayer(this); + session.clearPlayer(); } } } diff --git a/src/main/java/emu/nebula/game/player/Player.java b/src/main/java/emu/nebula/game/player/Player.java index 9e7f9b8..b8c345e 100644 --- a/src/main/java/emu/nebula/game/player/Player.java +++ b/src/main/java/emu/nebula/game/player/Player.java @@ -1,7 +1,5 @@ package emu.nebula.game.player; -import java.util.HashSet; -import java.util.Set; import java.util.Stack; import dev.morphia.annotations.Entity; @@ -44,7 +42,7 @@ public class Player implements GameDatabaseObject { @Indexed private String accountUid; private transient Account account; - private transient Set sessions; + private transient GameSession session; // Details private String name; @@ -80,7 +78,6 @@ public class Player implements GameDatabaseObject { @Deprecated // Morphia only public Player() { - this.sessions = new HashSet<>(); this.characters = new CharacterStorage(this); this.gachaManager = new GachaManager(this); @@ -135,22 +132,17 @@ public class Player implements GameDatabaseObject { return this.account; } - public void addSession(GameSession session) { - synchronized (this.sessions) { - this.sessions.add(session); + public void setSession(GameSession session) { + if (this.session != null) { + this.session.clearPlayer(); } + + this.session = session; } - public void removeSession(GameSession session) { - synchronized (this.sessions) { - this.sessions.remove(session); - } - } - - public boolean hasSessions() { - synchronized (this.sessions) { - return !this.sessions.isEmpty(); - } + public void removeSession() { + this.session = null; + Nebula.getGameContext().getPlayerModule().removeFromCache(this); } public boolean getGender() { diff --git a/src/main/java/emu/nebula/net/GameSession.java b/src/main/java/emu/nebula/net/GameSession.java index 5b35efe..8728520 100644 --- a/src/main/java/emu/nebula/net/GameSession.java +++ b/src/main/java/emu/nebula/net/GameSession.java @@ -7,7 +7,6 @@ import org.bouncycastle.crypto.params.ECPrivateKeyParameters; import org.bouncycastle.crypto.params.ECPublicKeyParameters; import emu.nebula.Nebula; -import emu.nebula.game.GameContext; import emu.nebula.game.account.Account; import emu.nebula.game.account.AccountHelper; import emu.nebula.game.player.Player; @@ -32,19 +31,24 @@ public class GameSession { private byte[] serverPrivateKey; private byte[] key; - // + // Session cleanup + private boolean remove; private long lastActiveTime; public GameSession() { this.updateLastActiveTime(); } - public void setPlayer(Player player) { - this.player = player; - this.player.addSession(this); + public synchronized Player getPlayer() { + return this.player; } - public void clearPlayer(GameContext context) { + public synchronized void setPlayer(Player player) { + this.player = player; + this.player.setSession(this); + } + + public synchronized void clearPlayer() { // Sanity check if (this.player == null) { return; @@ -55,15 +59,13 @@ public class GameSession { this.player = null; // Remove session from player - player.removeSession(this); + player.removeSession(); - // Clean up from player module - if (!player.hasSessions()) { - context.getPlayerModule().removeFromCache(player); - } + // Set remove flag + this.remove = true; } - public boolean hasPlayer() { + public synchronized boolean hasPlayer() { return this.player != null; }