From 9ce053c1b3755ab75cde63dad8aefecbd75ffb39 Mon Sep 17 00:00:00 2001 From: Melledy <121644117+Melledy@users.noreply.github.com> Date: Sun, 4 Aug 2024 01:32:30 -0700 Subject: [PATCH] Refactor player sync packet --- .../command/commands/AvatarCommand.java | 2 +- .../emu/lunarcore/game/avatar/AvatarData.java | 2 +- .../game/avatar/AvatarMultiPath.java | 15 +- .../lunarcore/game/avatar/AvatarStorage.java | 8 +- .../avatar/{IAvatar.java => BaseAvatar.java} | 27 +-- .../emu/lunarcore/game/avatar/GameAvatar.java | 15 +- .../lunarcore/game/inventory/GameItem.java | 37 +++- .../lunarcore/game/inventory/Inventory.java | 8 +- .../emu/lunarcore/game/player/Player.java | 10 +- .../game/player/PlayerUnlockData.java | 14 +- .../emu/lunarcore/server/game/Syncable.java | 9 + .../packet/send/PacketPlayerSyncScNotify.java | 203 ++---------------- 12 files changed, 135 insertions(+), 215 deletions(-) rename src/main/java/emu/lunarcore/game/avatar/{IAvatar.java => BaseAvatar.java} (77%) create mode 100644 src/main/java/emu/lunarcore/server/game/Syncable.java diff --git a/src/main/java/emu/lunarcore/command/commands/AvatarCommand.java b/src/main/java/emu/lunarcore/command/commands/AvatarCommand.java index 3aaaffb..1f78792 100644 --- a/src/main/java/emu/lunarcore/command/commands/AvatarCommand.java +++ b/src/main/java/emu/lunarcore/command/commands/AvatarCommand.java @@ -64,7 +64,7 @@ public class AvatarCommand implements CommandHandler { if (changeList.size() > 0) { // Send packet - args.getTarget().sendPacket(new PacketPlayerSyncScNotify(changeList.toArray(GameAvatar[]::new))); + args.getTarget().sendPacket(new PacketPlayerSyncScNotify(changeList)); // Send message args.sendMessage("Set avatar(s) properties successfully"); } else { diff --git a/src/main/java/emu/lunarcore/game/avatar/AvatarData.java b/src/main/java/emu/lunarcore/game/avatar/AvatarData.java index 483b4bd..df04e55 100644 --- a/src/main/java/emu/lunarcore/game/avatar/AvatarData.java +++ b/src/main/java/emu/lunarcore/game/avatar/AvatarData.java @@ -20,7 +20,7 @@ public class AvatarData { @Setter private int rank; // Eidolons private Int2IntMap skills; // Skill tree - @Setter private transient IAvatar baseAvatar; + @Setter private transient BaseAvatar baseAvatar; private transient Int2ObjectMap equips; @Deprecated // Morphia only diff --git a/src/main/java/emu/lunarcore/game/avatar/AvatarMultiPath.java b/src/main/java/emu/lunarcore/game/avatar/AvatarMultiPath.java index d4c453d..5e62900 100644 --- a/src/main/java/emu/lunarcore/game/avatar/AvatarMultiPath.java +++ b/src/main/java/emu/lunarcore/game/avatar/AvatarMultiPath.java @@ -15,12 +15,13 @@ import emu.lunarcore.game.player.Player; import emu.lunarcore.proto.AvatarSkillTreeOuterClass.AvatarSkillTree; import emu.lunarcore.proto.EquipRelicOuterClass.EquipRelic; import emu.lunarcore.proto.MultiPathAvatarInfoOuterClass.MultiPathAvatarInfo; +import emu.lunarcore.proto.PlayerSyncScNotifyOuterClass.PlayerSyncScNotify; import lombok.Getter; import lombok.Setter; @Getter @Entity(value = "multiPaths", useDiscriminator = false) -public class AvatarMultiPath implements IAvatar { +public class AvatarMultiPath extends BaseAvatar { @Id private ObjectId id; @Indexed private int ownerUid; @@ -62,6 +63,16 @@ public class AvatarMultiPath implements IAvatar { return this.getData().getSkills(); } + // Player sync + + // Player sync + + public void onSync(PlayerSyncScNotify proto) { + proto.addMultiPathAvatarInfoList(this.toProto()); + } + + // Proto + public MultiPathAvatarInfo toProto() { var proto = MultiPathAvatarInfo.newInstance() .setAvatarIdValue(this.getExcelId()) @@ -83,6 +94,8 @@ public class AvatarMultiPath implements IAvatar { return proto; } + // Database + public void save() { LunarCore.getGameDatabase().save(this); } diff --git a/src/main/java/emu/lunarcore/game/avatar/AvatarStorage.java b/src/main/java/emu/lunarcore/game/avatar/AvatarStorage.java index 8c73c18..8b198c0 100644 --- a/src/main/java/emu/lunarcore/game/avatar/AvatarStorage.java +++ b/src/main/java/emu/lunarcore/game/avatar/AvatarStorage.java @@ -42,8 +42,8 @@ public class AvatarStorage extends BasePlayerManager implements Iterable getEquips() { + public Int2ObjectMap getEquips() { return this.getData().getEquips(); } - public default GameItem getEquipBySlot(int slot) { + public GameItem getEquipBySlot(int slot) { return this.getEquips().get(slot); } - public default GameItem getEquipment() { + public GameItem getEquipment() { return this.getEquips().get(GameConstants.EQUIPMENT_SLOT_ID); } - public default boolean equipItem(GameItem item) { + public boolean equipItem(GameItem item) { // Sanity check int slot = item.getEquipSlot(); if (slot == 0) return false; // Check if other avatars have this item equipped - IAvatar otherAvatar = item.getEquipAvatar(); + BaseAvatar otherAvatar = item.getEquipAvatar(); if (otherAvatar != null) { // Unequip this item from the other avatar if (otherAvatar.unequipItem(slot) != null) { @@ -75,7 +78,7 @@ public interface IAvatar { return true; } - public default GameItem unequipItem(int slot) { + public GameItem unequipItem(int slot) { GameItem item = getEquips().remove(slot); if (item != null) { diff --git a/src/main/java/emu/lunarcore/game/avatar/GameAvatar.java b/src/main/java/emu/lunarcore/game/avatar/GameAvatar.java index 1a0893a..b4d1559 100644 --- a/src/main/java/emu/lunarcore/game/avatar/GameAvatar.java +++ b/src/main/java/emu/lunarcore/game/avatar/GameAvatar.java @@ -28,6 +28,7 @@ import emu.lunarcore.proto.DisplayRelicInfoOuterClass.DisplayRelicInfo; import emu.lunarcore.proto.EquipRelicOuterClass.EquipRelic; import emu.lunarcore.proto.LineupAvatarOuterClass.LineupAvatar; import emu.lunarcore.proto.MotionInfoOuterClass.MotionInfo; +import emu.lunarcore.proto.PlayerSyncScNotifyOuterClass.PlayerSyncScNotify; import emu.lunarcore.proto.SceneActorInfoOuterClass.SceneActorInfo; import emu.lunarcore.proto.SceneEntityInfoOuterClass.SceneEntityInfo; import emu.lunarcore.proto.SpBarInfoOuterClass.SpBarInfo; @@ -40,7 +41,7 @@ import lombok.Setter; @Getter @Entity(value = "avatars", useDiscriminator = false) -public class GameAvatar implements GameEntity, IAvatar { +public class GameAvatar extends BaseAvatar implements GameEntity { @Id private ObjectId id; @Indexed @Getter private int ownerUid; // Uid of player that this avatar belongs to @@ -223,6 +224,18 @@ public class GameAvatar implements GameEntity, IAvatar { this.buffs.put(buffId, System.currentTimeMillis() + (duration * 1000)); } + // Player sync + + public void onSync(PlayerSyncScNotify proto) { + // Add to avatar sync + proto.getMutableAvatarSync().addAvatarList(this.toProto()); + + // Also update multipath info + if (this.getMultiPath() != null) { + proto.addMultiPathAvatarInfoList(this.getMultiPath().toProto()); + } + } + // Proto public Avatar toProto() { diff --git a/src/main/java/emu/lunarcore/game/inventory/GameItem.java b/src/main/java/emu/lunarcore/game/inventory/GameItem.java index 40aff4a..8813778 100644 --- a/src/main/java/emu/lunarcore/game/inventory/GameItem.java +++ b/src/main/java/emu/lunarcore/game/inventory/GameItem.java @@ -13,7 +13,7 @@ import emu.lunarcore.data.GameDepot; import emu.lunarcore.data.excel.ItemExcel; import emu.lunarcore.data.excel.RelicMainAffixExcel; import emu.lunarcore.data.excel.RelicSubAffixExcel; -import emu.lunarcore.game.avatar.IAvatar; +import emu.lunarcore.game.avatar.BaseAvatar; import emu.lunarcore.game.enums.AvatarPropertyType; import emu.lunarcore.game.enums.ItemMainType; import emu.lunarcore.game.player.Player; @@ -21,7 +21,9 @@ import emu.lunarcore.proto.EquipmentOuterClass.Equipment; import emu.lunarcore.proto.ItemOuterClass.Item; import emu.lunarcore.proto.MaterialOuterClass.Material; import emu.lunarcore.proto.PileItemOuterClass.PileItem; +import emu.lunarcore.proto.PlayerSyncScNotifyOuterClass.PlayerSyncScNotify; import emu.lunarcore.proto.RelicOuterClass.Relic; +import emu.lunarcore.server.game.Syncable; import emu.lunarcore.util.Utils; import emu.lunarcore.util.WeightedList; import it.unimi.dsi.fastutil.ints.IntOpenHashSet; @@ -31,7 +33,7 @@ import lombok.Setter; @Getter @Entity(value = "items", useDiscriminator = false) -public class GameItem { +public class GameItem implements Syncable { @Id private ObjectId id; @Indexed private int ownerUid; // Uid of player that this avatar belongs to @@ -53,7 +55,7 @@ public class GameItem { private List subAffixes; @Indexed private ObjectId equipAvatarId; // Object id of the avatar this item is equipped to - private transient IAvatar equipAvatar; + private transient BaseAvatar equipAvatar; @LoadOnly @AlsoLoad("equipAvatar") private int equipAvatarExcelId; // Deprecated legacy field @@ -151,7 +153,7 @@ public class GameItem { return false; } - public boolean setEquipAvatar(IAvatar baseAvatar) { + public boolean setEquipAvatar(BaseAvatar baseAvatar) { if (baseAvatar == null && this.isEquipped()) { this.equipAvatarId = null; this.equipAvatar = null; @@ -271,6 +273,33 @@ public class GameItem { LunarCore.getGameDatabase().delete(this); } } + + // Player sync + + public void onSync(PlayerSyncScNotify proto) { + switch (this.getExcel().getItemMainType().getTabType()) { + case MATERIAL -> { + proto.addMaterialList(this.toMaterialProto()); + } + case RELIC -> { + if (this.getCount() > 0) { + proto.addRelicList(this.toRelicProto()); + } else { + proto.addDelRelicList(this.getInternalUid()); + } + } + case EQUIPMENT -> { + if (this.getCount() > 0) { + proto.addEquipmentList(this.toEquipmentProto()); + } else { + proto.addDelEquipmentList(this.getInternalUid()); + } + } + default -> { + // Skip + } + } + } // Proto diff --git a/src/main/java/emu/lunarcore/game/inventory/Inventory.java b/src/main/java/emu/lunarcore/game/inventory/Inventory.java index c480455..3195959 100644 --- a/src/main/java/emu/lunarcore/game/inventory/Inventory.java +++ b/src/main/java/emu/lunarcore/game/inventory/Inventory.java @@ -14,7 +14,7 @@ import emu.lunarcore.data.excel.AvatarExcel; import emu.lunarcore.data.excel.ItemExcel; import emu.lunarcore.game.avatar.AvatarStorage; import emu.lunarcore.game.avatar.GameAvatar; -import emu.lunarcore.game.avatar.IAvatar; +import emu.lunarcore.game.avatar.BaseAvatar; import emu.lunarcore.game.enums.ItemMainType; import emu.lunarcore.game.enums.ItemSubType; import emu.lunarcore.game.inventory.tabs.EquipInventoryTab; @@ -554,7 +554,7 @@ public class Inventory extends BasePlayerManager { // Equips public boolean equipItem(int avatarId, int equipId) { - IAvatar avatar = getPlayer().getAvatars().getBaseAvatarById(avatarId); + BaseAvatar avatar = getPlayer().getAvatars().getBaseAvatarById(avatarId); GameItem item = this.getItemByUid(equipId); if (avatar != null && item != null) { @@ -565,7 +565,7 @@ public class Inventory extends BasePlayerManager { } public boolean unequipItem(int avatarId, int slot) { - IAvatar avatar = getPlayer().getAvatars().getBaseAvatarById(avatarId); + BaseAvatar avatar = getPlayer().getAvatars().getBaseAvatarById(avatarId); if (avatar != null) { GameItem unequipped = avatar.unequipItem(slot); @@ -614,7 +614,7 @@ public class Inventory extends BasePlayerManager { // Equip to a character if possible if (item.isEquipped() || item.getEquipAvatarExcelId() > 0) { - IAvatar avatar = null; + BaseAvatar avatar = null; boolean hasEquipped = false; if (item.getEquipAvatarExcelId() > 0) { diff --git a/src/main/java/emu/lunarcore/game/player/Player.java b/src/main/java/emu/lunarcore/game/player/Player.java index f51b929..b5974e4 100644 --- a/src/main/java/emu/lunarcore/game/player/Player.java +++ b/src/main/java/emu/lunarcore/game/player/Player.java @@ -61,10 +61,12 @@ import emu.lunarcore.proto.HeadIconOuterClass.HeadIcon; import emu.lunarcore.proto.PlatformTypeOuterClass.PlatformType; import emu.lunarcore.proto.PlayerBasicInfoOuterClass.PlayerBasicInfo; import emu.lunarcore.proto.PlayerDetailInfoOuterClass.PlayerDetailInfo; +import emu.lunarcore.proto.PlayerSyncScNotifyOuterClass.PlayerSyncScNotify; import emu.lunarcore.proto.RogueCurVirtualItemInfoOuterClass.RogueCurVirtualItemInfo; import emu.lunarcore.proto.SimpleInfoOuterClass.SimpleInfo; import emu.lunarcore.server.game.GameServer; import emu.lunarcore.server.game.GameSession; +import emu.lunarcore.server.game.Syncable; import emu.lunarcore.server.game.Tickable; import emu.lunarcore.server.packet.BasePacket; import emu.lunarcore.server.packet.CmdId; @@ -80,7 +82,7 @@ import us.hebi.quickbuf.RepeatedMessage; @Entity(value = "players", useDiscriminator = false) @Getter -public class Player implements Tickable { +public class Player implements Tickable, Syncable { @Id private int uid; @Indexed private String accountUid; private String name; @@ -1026,6 +1028,12 @@ public class Player implements Tickable { } } + // Player sync + + public void onSync(PlayerSyncScNotify proto) { + proto.setBasicInfo(this.toProto()); + } + // Protobuf serialization public PlayerBasicInfo toProto() { diff --git a/src/main/java/emu/lunarcore/game/player/PlayerUnlockData.java b/src/main/java/emu/lunarcore/game/player/PlayerUnlockData.java index 31798c7..af7919c 100644 --- a/src/main/java/emu/lunarcore/game/player/PlayerUnlockData.java +++ b/src/main/java/emu/lunarcore/game/player/PlayerUnlockData.java @@ -7,6 +7,8 @@ import emu.lunarcore.LunarCore; import emu.lunarcore.data.GameData; import emu.lunarcore.game.avatar.GameAvatar; import emu.lunarcore.game.enums.PersonalizeShowType; +import emu.lunarcore.proto.PlayerSyncScNotifyOuterClass.PlayerSyncScNotify; +import emu.lunarcore.server.game.Syncable; import emu.lunarcore.server.packet.BasePacket; import emu.lunarcore.server.packet.send.PacketPlayerSyncScNotify; import emu.lunarcore.server.packet.send.PacketUnlockChatBubbleScNotify; @@ -17,7 +19,7 @@ import lombok.Getter; @Getter @Entity(value = "unlocks", useDiscriminator = false) -public class PlayerUnlockData { +public class PlayerUnlockData implements Syncable { private transient Player owner; @Id private int ownerUid; @@ -89,7 +91,7 @@ public class PlayerUnlockData { boolean success = this.getHeadIcons().add(headIconId); if (success && this.getOwner().isLoggedIn()) { - this.sendPacket(new PacketPlayerSyncScNotify(getOwner().toBoardData())); + this.sendPacket(new PacketPlayerSyncScNotify(this)); this.save(); } } @@ -115,6 +117,14 @@ public class PlayerUnlockData { private void sendPacket(BasePacket packet) { this.getOwner().sendPacket(packet); } + + // Player sync + + public void onSync(PlayerSyncScNotify proto) { + proto.setBoardDataSync(this.getOwner().toBoardData()); + } + + // Database public void save() { LunarCore.getGameDatabase().save(this); diff --git a/src/main/java/emu/lunarcore/server/game/Syncable.java b/src/main/java/emu/lunarcore/server/game/Syncable.java new file mode 100644 index 0000000..ffbd0f0 --- /dev/null +++ b/src/main/java/emu/lunarcore/server/game/Syncable.java @@ -0,0 +1,9 @@ +package emu.lunarcore.server.game; + +import emu.lunarcore.proto.PlayerSyncScNotifyOuterClass.PlayerSyncScNotify; + +public interface Syncable { + + public void onSync(PlayerSyncScNotify proto); + +} 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 5cd0f51..268e55d 100644 --- a/src/main/java/emu/lunarcore/server/packet/send/PacketPlayerSyncScNotify.java +++ b/src/main/java/emu/lunarcore/server/packet/send/PacketPlayerSyncScNotify.java @@ -1,16 +1,9 @@ package emu.lunarcore.server.packet.send; -import java.util.Collection; -import emu.lunarcore.game.avatar.GameAvatar; -import emu.lunarcore.game.avatar.IAvatar; -import emu.lunarcore.game.avatar.AvatarMultiPath; -import emu.lunarcore.game.inventory.GameItem; -import emu.lunarcore.game.player.Player; -import emu.lunarcore.proto.BoardDataSyncOuterClass.BoardDataSync; -import emu.lunarcore.proto.MissionSyncOuterClass.MissionSync; -import emu.lunarcore.proto.MissionOuterClass.Mission; -import emu.lunarcore.proto.MissionStatusOuterClass.MissionStatus; +import java.util.List; + import emu.lunarcore.proto.PlayerSyncScNotifyOuterClass.PlayerSyncScNotify; +import emu.lunarcore.server.game.Syncable; import emu.lunarcore.server.packet.BasePacket; import emu.lunarcore.server.packet.CmdId; @@ -20,196 +13,38 @@ public class PacketPlayerSyncScNotify extends BasePacket { private PacketPlayerSyncScNotify() { super(CmdId.PlayerSyncScNotify); } - - public PacketPlayerSyncScNotify(Player player) { - this(); - - var data = PlayerSyncScNotify.newInstance() - .setBasicInfo(player.toProto()); - - this.setData(data); - } - public PacketPlayerSyncScNotify(BoardDataSync boardData) { - this(); - - var data = PlayerSyncScNotify.newInstance() - .setBoardDataSync(boardData); - - this.setData(data); - } - - public PacketPlayerSyncScNotify(IAvatar baseAvatar) { + public PacketPlayerSyncScNotify(Syncable object) { this(); var data = PlayerSyncScNotify.newInstance(); - if (baseAvatar instanceof GameAvatar avatar) { - data.getMutableAvatarSync().addAvatarList(avatar.toProto()); - - // Also update multipath info - if (avatar.getMultiPath() != null) { - data.addMultiPathAvatarInfoList(avatar.getMultiPath().toProto()); - } - } else if (baseAvatar instanceof AvatarMultiPath multiPath) { - data.addMultiPathAvatarInfoList(multiPath.toProto()); + object.onSync(data); + + this.setData(data); + } + + public PacketPlayerSyncScNotify(Syncable... objects) { + this(); + + var data = PlayerSyncScNotify.newInstance(); + + for (var object : objects) { + object.onSync(data); } this.setData(data); } - public PacketPlayerSyncScNotify(IAvatar baseAvatar, GameItem item) { + public PacketPlayerSyncScNotify(List objects) { this(); var data = PlayerSyncScNotify.newInstance(); - if (baseAvatar instanceof GameAvatar avatar) { - data.getMutableAvatarSync().addAvatarList(avatar.toProto()); - - // Also update multipath info - if (avatar.getMultiPath() != null) { - data.addMultiPathAvatarInfoList(avatar.getMultiPath().toProto()); - } - } else if (baseAvatar instanceof AvatarMultiPath multiPath) { - data.addMultiPathAvatarInfoList(multiPath.toProto()); + for (var object : objects) { + object.onSync(data); } - this.addItemToProto(data, item); - - this.setData(data); - } - - public PacketPlayerSyncScNotify(GameAvatar avatar) { - this(); - - var data = PlayerSyncScNotify.newInstance(); - - // Update avatar - data.getMutableAvatarSync().addAvatarList(avatar.toProto()); - - // Also update multipath info - if (avatar.getMultiPath() != null) { - data.addMultiPathAvatarInfoList(avatar.getMultiPath().toProto()); - } - - this.setData(data); - } - - public PacketPlayerSyncScNotify(GameAvatar avatar, GameItem item) { - this(); - - var data = PlayerSyncScNotify.newInstance(); - - // Update avatar - data.getMutableAvatarSync().addAvatarList(avatar.toProto()); - - // Also update multipath info - if (avatar.getMultiPath() != null) { - data.addMultiPathAvatarInfoList(avatar.getMultiPath().toProto()); - } - - // Update item - this.addItemToProto(data, item); - - this.setData(data); - } - - public PacketPlayerSyncScNotify(GameItem item) { - this(); - - var data = PlayerSyncScNotify.newInstance(); - - this.addItemToProto(data, item); - - this.setData(data); - } - - public PacketPlayerSyncScNotify(GameAvatar... avatars) { // Ugly workaround - this(); - - var data = PlayerSyncScNotify.newInstance(); - - for (var avatar : avatars) { - // Sync avatar - data.getMutableAvatarSync().addAvatarList(avatar.toProto()); - - // Also update hero basic type info if were updating the main character - if (avatar.getMultiPath() != null) { - data.addMultiPathAvatarInfoList(avatar.getMultiPath().toProto()); - } - } - - this.setData(data); - } - - public PacketPlayerSyncScNotify(Collection items) { - this(); - - var data = PlayerSyncScNotify.newInstance(); - - for (GameItem item : items) { - this.addItemToProto(data, item); - } - - this.setData(data); - } - - private void addItemToProto(PlayerSyncScNotify data, GameItem item) { - switch (item.getExcel().getItemMainType().getTabType()) { - case MATERIAL -> { - data.addMaterialList(item.toMaterialProto()); - } - case RELIC -> { - if (item.getCount() > 0) { - data.addRelicList(item.toRelicProto()); - } else { - data.addDelRelicList(item.getInternalUid()); - } - } - case EQUIPMENT -> { - if (item.getCount() > 0) { - data.addEquipmentList(item.toEquipmentProto()); - } else { - data.addDelEquipmentList(item.getInternalUid()); - } - } - default -> { - // Skip - } - } - } - - public PacketPlayerSyncScNotify(AvatarMultiPath... multiPaths) { - this(); - - var data = PlayerSyncScNotify.newInstance(); - - for (var path : multiPaths) { - if (path != null) { - data.addMultiPathAvatarInfoList(path.toProto()); - } - } - - this.setData(data); - } - - - public PacketPlayerSyncScNotify(int mainMissionId, int[] subMissionIds, MissionStatus missionStatus) { - this(); - - var missionSync = MissionSync.newInstance(); - - for (int subMissionId : subMissionIds) { - missionSync.addMissionList( - Mission.newInstance() - .setId(subMissionId) - .setStatus(missionStatus) - ); - } - - var data = PlayerSyncScNotify.newInstance() - .setMissionSync(missionSync); - this.setData(data); } }