From 5ee03beb5e78d9e9896eb5d87af93a5829ecb7df Mon Sep 17 00:00:00 2001 From: Melledy <121644117+Melledy@users.noreply.github.com> Date: Mon, 20 Nov 2023 04:50:35 -0800 Subject: [PATCH] Delete player data when an account is deleted --- .../command/commands/AccountCommand.java | 2 +- .../lunarcore/game/account/AccountHelper.java | 13 +++- .../{HeroPath.java => AvatarHeroPath.java} | 12 ++-- .../lunarcore/game/avatar/AvatarStorage.java | 8 +-- .../emu/lunarcore/game/avatar/GameAvatar.java | 6 +- .../emu/lunarcore/game/player/Player.java | 62 ++++++++++++++----- .../emu/lunarcore/server/game/GameServer.java | 25 ++++++++ .../lunarcore/server/game/GameSession.java | 4 +- .../send/PacketGetHeroBasicTypeInfoScRsp.java | 4 +- .../packet/send/PacketPlayerSyncScNotify.java | 5 +- 10 files changed, 102 insertions(+), 39 deletions(-) rename src/main/java/emu/lunarcore/game/avatar/{HeroPath.java => AvatarHeroPath.java} (89%) diff --git a/src/main/java/emu/lunarcore/command/commands/AccountCommand.java b/src/main/java/emu/lunarcore/command/commands/AccountCommand.java index 6bc17b7..402ac3b 100644 --- a/src/main/java/emu/lunarcore/command/commands/AccountCommand.java +++ b/src/main/java/emu/lunarcore/command/commands/AccountCommand.java @@ -29,7 +29,7 @@ public class AccountCommand implements CommandHandler { reservedUid = Utils.parseSafeInt(args.get(2)); } - if (AccountHelper.createAccount(username, null, reservedUid)) { + if (AccountHelper.createAccount(username, null, reservedUid) != null) { this.sendMessage(sender, "Account created"); } else { this.sendMessage(sender, "Account already exists"); diff --git a/src/main/java/emu/lunarcore/game/account/AccountHelper.java b/src/main/java/emu/lunarcore/game/account/AccountHelper.java index 23efdf7..d722175 100644 --- a/src/main/java/emu/lunarcore/game/account/AccountHelper.java +++ b/src/main/java/emu/lunarcore/game/account/AccountHelper.java @@ -7,18 +7,18 @@ import emu.lunarcore.LunarCore; */ public class AccountHelper { - public static boolean createAccount(String username, String password, int reservedUid) { + public static Account createAccount(String username, String password, int reservedUid) { Account account = LunarCore.getAccountDatabase().getObjectByField(Account.class, "username", username); if (account != null) { - return false; + return null; } account = new Account(username); account.setReservedPlayerUid(reservedUid); account.save(); - return true; + return account; } public static boolean deleteAccount(String username) { @@ -28,6 +28,13 @@ public class AccountHelper { return false; } + // Delete the player too + // IMPORTANT: This will only delete the player from the current game server + if (LunarCore.getGameServer() != null) { + LunarCore.getGameServer().deletePlayer(account.getUid()); + } + + // Delete the account first return LunarCore.getAccountDatabase().delete(account); } diff --git a/src/main/java/emu/lunarcore/game/avatar/HeroPath.java b/src/main/java/emu/lunarcore/game/avatar/AvatarHeroPath.java similarity index 89% rename from src/main/java/emu/lunarcore/game/avatar/HeroPath.java rename to src/main/java/emu/lunarcore/game/avatar/AvatarHeroPath.java index 9e5b88c..8e2542c 100644 --- a/src/main/java/emu/lunarcore/game/avatar/HeroPath.java +++ b/src/main/java/emu/lunarcore/game/avatar/AvatarHeroPath.java @@ -17,11 +17,9 @@ import lombok.Setter; @Getter @Entity(value = "heroPaths", useDiscriminator = false) -public class HeroPath { - @Id - private int id; // Equivalent to HeroBaseType - @Indexed - private int ownerUid; +public class AvatarHeroPath { + @Id private int id; // Equivalent to HeroBaseType + @Indexed private int ownerUid; private AvatarData data; @@ -29,11 +27,11 @@ public class HeroPath { private transient AvatarExcel excel; @Deprecated // Morphia only! - public HeroPath() { + public AvatarHeroPath() { } - public HeroPath(Player player, AvatarExcel excel) { + public AvatarHeroPath(Player player, AvatarExcel excel) { // Set excel avatar id as id this.id = excel.getId(); this.ownerUid = player.getUid(); diff --git a/src/main/java/emu/lunarcore/game/avatar/AvatarStorage.java b/src/main/java/emu/lunarcore/game/avatar/AvatarStorage.java index c541a4d..92132b5 100644 --- a/src/main/java/emu/lunarcore/game/avatar/AvatarStorage.java +++ b/src/main/java/emu/lunarcore/game/avatar/AvatarStorage.java @@ -19,7 +19,7 @@ import lombok.Getter; @Getter public class AvatarStorage extends BasePlayerManager implements Iterable { private final Int2ObjectMap avatars; - private final Int2ObjectMap heroPaths; + private final Int2ObjectMap heroPaths; public AvatarStorage(Player player) { super(player); @@ -65,7 +65,7 @@ public class AvatarStorage extends BasePlayerManager implements Iterable heroStream = LunarCore.getGameDatabase().getObjects(HeroPath.class, "ownerUid", this.getPlayer().getUid()); + Stream heroStream = LunarCore.getGameDatabase().getObjects(AvatarHeroPath.class, "ownerUid", this.getPlayer().getUid()); heroStream.forEach(heroPath -> { // Load avatar excel data diff --git a/src/main/java/emu/lunarcore/game/avatar/GameAvatar.java b/src/main/java/emu/lunarcore/game/avatar/GameAvatar.java index 1bb2fe4..e446883 100644 --- a/src/main/java/emu/lunarcore/game/avatar/GameAvatar.java +++ b/src/main/java/emu/lunarcore/game/avatar/GameAvatar.java @@ -64,7 +64,7 @@ public class GameAvatar implements GameEntity { private transient int entityId; private transient Int2ObjectMap equips; private transient Int2LongMap buffs; - private transient HeroPath heroPath; + private transient AvatarHeroPath heroPath; @Deprecated // Morphia only public GameAvatar() { @@ -86,7 +86,7 @@ public class GameAvatar implements GameEntity { this.setExcel(excel); } - public GameAvatar(HeroPath path) { + public GameAvatar(AvatarHeroPath path) { this(); this.avatarId = GameConstants.TRAILBLAZER_AVATAR_ID; this.timestamp = System.currentTimeMillis() / 1000; @@ -188,7 +188,7 @@ public class GameAvatar implements GameEntity { return this.getData().getSkills(); } - public void setHeroPath(HeroPath heroPath) { + public void setHeroPath(AvatarHeroPath heroPath) { // Clear prev set hero path from avatar if (this.getHeroPath() != null) { this.getHeroPath().setAvatar(null); diff --git a/src/main/java/emu/lunarcore/game/player/Player.java b/src/main/java/emu/lunarcore/game/player/Player.java index 56c42c2..21c546d 100644 --- a/src/main/java/emu/lunarcore/game/player/Player.java +++ b/src/main/java/emu/lunarcore/game/player/Player.java @@ -2,6 +2,8 @@ package emu.lunarcore.game.player; import java.util.Set; +import com.mongodb.client.model.Filters; + import dev.morphia.annotations.Entity; import dev.morphia.annotations.Id; import dev.morphia.annotations.Indexed; @@ -17,8 +19,10 @@ import emu.lunarcore.data.excel.MazePlaneExcel; import emu.lunarcore.game.account.Account; import emu.lunarcore.game.avatar.AvatarStorage; import emu.lunarcore.game.avatar.GameAvatar; -import emu.lunarcore.game.avatar.HeroPath; +import emu.lunarcore.game.avatar.AvatarHeroPath; import emu.lunarcore.game.battle.Battle; +import emu.lunarcore.game.challenge.ChallengeGroupReward; +import emu.lunarcore.game.challenge.ChallengeHistory; import emu.lunarcore.game.challenge.ChallengeInstance; import emu.lunarcore.game.challenge.ChallengeManager; import emu.lunarcore.game.chat.ChatManager; @@ -26,12 +30,16 @@ import emu.lunarcore.game.chat.ChatMessage; import emu.lunarcore.game.enums.PlaneType; import emu.lunarcore.game.enums.PropState; import emu.lunarcore.game.gacha.PlayerGachaInfo; +import emu.lunarcore.game.inventory.GameItem; import emu.lunarcore.game.inventory.Inventory; +import emu.lunarcore.game.mail.Mail; import emu.lunarcore.game.mail.Mailbox; import emu.lunarcore.game.player.lineup.LineupManager; +import emu.lunarcore.game.player.lineup.PlayerExtraLineup; import emu.lunarcore.game.player.lineup.PlayerLineup; import emu.lunarcore.game.rogue.RogueInstance; import emu.lunarcore.game.rogue.RogueManager; +import emu.lunarcore.game.rogue.RogueTalentData; import emu.lunarcore.game.scene.Scene; import emu.lunarcore.game.scene.entity.EntityProp; import emu.lunarcore.game.scene.entity.GameEntity; @@ -332,12 +340,12 @@ public class Player { return this.exp - GameData.getPlayerExpRequired(this.level); } - public HeroPath getCurHeroPath() { + public AvatarHeroPath getCurHeroPath() { return this.getAvatars().getHeroPathById(this.getCurBasicType()); } public void setHeroBasicType(int heroType) { - HeroPath path = this.getAvatars().getHeroPathById(heroType); + AvatarHeroPath path = this.getAvatars().getHeroPathById(heroType); if (path == null) return; GameAvatar mainCharacter = this.getAvatarById(GameConstants.TRAILBLAZER_AVATAR_ID); @@ -601,17 +609,6 @@ public class Player { this.updateStamina(); } - // Database - - public void save() { - if (this.uid <= 0) { - LunarCore.getLogger().error("Tried to save a player object without a uid!"); - return; - } - - LunarCore.getGameDatabase().save(this); - } - public void onLogin() { // Validate this.getLineupManager().setPlayer(this); @@ -645,6 +642,42 @@ public class Player { } } + + // Database + + public void save() { + if (this.uid <= 0) { + LunarCore.getLogger().error("Tried to save a player object without a uid!"); + return; + } + + LunarCore.getGameDatabase().save(this); + } + + public void delete() { + // Close session first + if (this.getSession() != null) { + this.getSession().close(); + } + + // Cache filter object so we can reuse it for our delete queries + var filter = Filters.eq("ownerUid", uid); + + // Delete data from collections + LunarCore.getGameDatabase().getDatastore().getCollection(GameAvatar.class).deleteMany(filter); + LunarCore.getGameDatabase().getDatastore().getCollection(ChallengeHistory.class).deleteMany(filter); + LunarCore.getGameDatabase().getDatastore().getCollection(ChallengeGroupReward.class).deleteMany(filter); + LunarCore.getGameDatabase().getDatastore().getCollection(AvatarHeroPath.class).deleteMany(filter); + LunarCore.getGameDatabase().getDatastore().getCollection(GameItem.class).deleteMany(filter); + LunarCore.getGameDatabase().getDatastore().getCollection(PlayerLineup.class).deleteMany(filter); + LunarCore.getGameDatabase().getDatastore().getCollection(PlayerExtraLineup.class).deleteMany(filter); + LunarCore.getGameDatabase().getDatastore().getCollection(Mail.class).deleteMany(filter); + LunarCore.getGameDatabase().getDatastore().getCollection(RogueTalentData.class).deleteMany(filter); + + // Delete the player last + LunarCore.getGameDatabase().delete(this); + } + // Protobuf serialization public PlayerBasicInfo toProto() { @@ -678,5 +711,4 @@ public class Player { return proto; } - } \ No newline at end of file diff --git a/src/main/java/emu/lunarcore/server/game/GameServer.java b/src/main/java/emu/lunarcore/server/game/GameServer.java index d0fb10f..cb12dcd 100644 --- a/src/main/java/emu/lunarcore/server/game/GameServer.java +++ b/src/main/java/emu/lunarcore/server/game/GameServer.java @@ -92,6 +92,31 @@ public class GameServer extends KcpServer { return this.players.get(uid); } } + + public Player getOnlinePlayerByAccountId(String accountUid) { + synchronized (this.players) { + return this.players.values() + .stream() + .filter(p -> accountUid.equals(p.getAccountUid())) + .findFirst() + .orElse(null); + } + } + + public boolean deletePlayer(String accountUid) { + // Check if player exists + Player player = this.getOnlinePlayerByAccountId(accountUid); + + // Try to get player from database + if (player == null) { + player = LunarCore.getGameDatabase().getObjectByField(Player.class, "accountUid", accountUid); + if (player == null) return false; + } + + // Delete the player + player.delete(); + return true; + } public void start() { // Setup config and init server diff --git a/src/main/java/emu/lunarcore/server/game/GameSession.java b/src/main/java/emu/lunarcore/server/game/GameSession.java index b0f4bb5..d633c66 100644 --- a/src/main/java/emu/lunarcore/server/game/GameSession.java +++ b/src/main/java/emu/lunarcore/server/game/GameSession.java @@ -176,6 +176,8 @@ public class GameSession { } public void close() { - this.ukcp.close(); + if (this.ukcp != null) { + this.ukcp.close(); + } } } diff --git a/src/main/java/emu/lunarcore/server/packet/send/PacketGetHeroBasicTypeInfoScRsp.java b/src/main/java/emu/lunarcore/server/packet/send/PacketGetHeroBasicTypeInfoScRsp.java index 9ef7687..13386db 100644 --- a/src/main/java/emu/lunarcore/server/packet/send/PacketGetHeroBasicTypeInfoScRsp.java +++ b/src/main/java/emu/lunarcore/server/packet/send/PacketGetHeroBasicTypeInfoScRsp.java @@ -1,6 +1,6 @@ package emu.lunarcore.server.packet.send; -import emu.lunarcore.game.avatar.HeroPath; +import emu.lunarcore.game.avatar.AvatarHeroPath; import emu.lunarcore.game.player.Player; import emu.lunarcore.proto.GetHeroBasicTypeInfoScRspOuterClass.GetHeroBasicTypeInfoScRsp; import emu.lunarcore.server.packet.BasePacket; @@ -15,7 +15,7 @@ public class PacketGetHeroBasicTypeInfoScRsp extends BasePacket { .setGenderValue(player.getGender().getVal()) .setCurBasicTypeValue(player.getCurBasicType()); - for (HeroPath path : player.getAvatars().getHeroPaths().values()) { + for (AvatarHeroPath path : player.getAvatars().getHeroPaths().values()) { data.addAllBasicTypeInfoList(path.toProto()); } diff --git a/src/main/java/emu/lunarcore/server/packet/send/PacketPlayerSyncScNotify.java b/src/main/java/emu/lunarcore/server/packet/send/PacketPlayerSyncScNotify.java index b6531bd..41105bd 100644 --- a/src/main/java/emu/lunarcore/server/packet/send/PacketPlayerSyncScNotify.java +++ b/src/main/java/emu/lunarcore/server/packet/send/PacketPlayerSyncScNotify.java @@ -3,10 +3,9 @@ package emu.lunarcore.server.packet.send; import java.util.Collection; import emu.lunarcore.game.avatar.GameAvatar; -import emu.lunarcore.game.avatar.HeroPath; +import emu.lunarcore.game.avatar.AvatarHeroPath; import emu.lunarcore.game.inventory.GameItem; import emu.lunarcore.game.player.Player; -import emu.lunarcore.proto.AvatarSyncOuterClass.AvatarSync; import emu.lunarcore.proto.BoardDataSyncOuterClass.BoardDataSync; import emu.lunarcore.proto.PlayerSyncScNotifyOuterClass.PlayerSyncScNotify; import emu.lunarcore.server.packet.BasePacket; @@ -109,7 +108,7 @@ public class PacketPlayerSyncScNotify extends BasePacket { } } - public PacketPlayerSyncScNotify(HeroPath heroPath) { + public PacketPlayerSyncScNotify(AvatarHeroPath heroPath) { this(); var data = PlayerSyncScNotify.newInstance()