From d133e556663afc78c287ff050165df7f9c89bebe Mon Sep 17 00:00:00 2001 From: LDA Date: Sat, 30 Apr 2022 10:04:36 -0700 Subject: [PATCH] Implement viewing character details in character showcase --- .../emu/grasscutter/game/avatar/Avatar.java | 51 +++++++++++++++++-- .../grasscutter/game/inventory/GameItem.java | 46 ++++++++++------- .../emu/grasscutter/game/player/Player.java | 31 ++++++++++- .../HandlerGetFriendShowAvatarInfoReq.java | 26 ++++++++++ .../PacketGetFriendShowAvatarInfoRsp.java | 24 +++++++++ 5 files changed, 155 insertions(+), 23 deletions(-) create mode 100644 src/main/java/emu/grasscutter/server/packet/recv/HandlerGetFriendShowAvatarInfoReq.java create mode 100644 src/main/java/emu/grasscutter/server/packet/send/PacketGetFriendShowAvatarInfoRsp.java diff --git a/src/main/java/emu/grasscutter/game/avatar/Avatar.java b/src/main/java/emu/grasscutter/game/avatar/Avatar.java index d16b9a2fa..cf5446ab7 100644 --- a/src/main/java/emu/grasscutter/game/avatar/Avatar.java +++ b/src/main/java/emu/grasscutter/game/avatar/Avatar.java @@ -15,7 +15,6 @@ import dev.morphia.annotations.Indexed; import dev.morphia.annotations.PostLoad; import dev.morphia.annotations.PrePersist; import dev.morphia.annotations.Transient; -import emu.grasscutter.Grasscutter; import emu.grasscutter.data.GameData; import emu.grasscutter.data.common.FightPropData; import emu.grasscutter.data.custom.OpenConfigEntry; @@ -26,18 +25,19 @@ import emu.grasscutter.data.def.AvatarSkillDepotData; import emu.grasscutter.data.def.AvatarSkillDepotData.InherentProudSkillOpens; import emu.grasscutter.data.def.AvatarTalentData; import emu.grasscutter.data.def.EquipAffixData; +import emu.grasscutter.data.def.ItemData.WeaponProperty; +import emu.grasscutter.data.def.ProudSkillData; import emu.grasscutter.data.def.ReliquaryAffixData; import emu.grasscutter.data.def.ReliquaryLevelData; import emu.grasscutter.data.def.ReliquaryMainPropData; import emu.grasscutter.data.def.ReliquarySetData; import emu.grasscutter.data.def.WeaponCurveData; import emu.grasscutter.data.def.WeaponPromoteData; -import emu.grasscutter.data.def.ItemData.WeaponProperty; -import emu.grasscutter.data.def.ProudSkillData; import emu.grasscutter.database.DatabaseHelper; import emu.grasscutter.game.entity.EntityAvatar; import emu.grasscutter.game.inventory.EquipType; import emu.grasscutter.game.inventory.GameItem; +import emu.grasscutter.game.inventory.ItemType; import emu.grasscutter.game.player.Player; import emu.grasscutter.game.props.ElementType; import emu.grasscutter.game.props.EntityIdType; @@ -45,8 +45,11 @@ import emu.grasscutter.game.props.FetterState; import emu.grasscutter.game.props.FightProperty; import emu.grasscutter.game.props.PlayerProperty; import emu.grasscutter.net.proto.AvatarFetterInfoOuterClass.AvatarFetterInfo; -import emu.grasscutter.net.proto.FetterDataOuterClass.FetterData; import emu.grasscutter.net.proto.AvatarInfoOuterClass.AvatarInfo; +import emu.grasscutter.net.proto.FetterDataOuterClass.FetterData; +import emu.grasscutter.net.proto.ShowAvatarInfoOuterClass; +import emu.grasscutter.net.proto.ShowAvatarInfoOuterClass.ShowAvatarInfo; +import emu.grasscutter.net.proto.ShowEquipOuterClass.ShowEquip; import emu.grasscutter.server.packet.send.PacketAbilityChangeNotify; import emu.grasscutter.server.packet.send.PacketAvatarEquipChangeNotify; import emu.grasscutter.server.packet.send.PacketAvatarFightPropNotify; @@ -797,6 +800,46 @@ public class Avatar { return avatarInfo.build(); } + + // used only in character showcase + public ShowAvatarInfo toShowAvatarInfoProto() { + AvatarFetterInfo.Builder avatarFetter = AvatarFetterInfo.newBuilder() + .setExpLevel(this.getFetterLevel()); + + ShowAvatarInfo.Builder showAvatarInfo = ShowAvatarInfoOuterClass.ShowAvatarInfo.newBuilder() + .setAvatarId(avatarId) + .addAllTalentIdList(this.getTalentIdList()) + .putAllFightPropMap(this.getFightProperties()) + .setSkillDepotId(this.getSkillDepotId()) + .setCoreProudSkillLevel(this.getCoreProudSkillLevel()) + .addAllInherentProudSkillList(this.getProudSkillList()) + .putAllSkillLevelMap(this.getSkillLevelMap()) + .putAllProudSkillExtraLevelMap(this.getProudSkillBonusMap()) + .setFetterInfo(avatarFetter) + .setCostumeId(this.getCostume()); + + showAvatarInfo.putPropMap(PlayerProperty.PROP_LEVEL.getId(), ProtoHelper.newPropValue(PlayerProperty.PROP_LEVEL, this.getLevel())); + showAvatarInfo.putPropMap(PlayerProperty.PROP_EXP.getId(), ProtoHelper.newPropValue(PlayerProperty.PROP_EXP, this.getExp())); + showAvatarInfo.putPropMap(PlayerProperty.PROP_BREAK_LEVEL.getId(), ProtoHelper.newPropValue(PlayerProperty.PROP_BREAK_LEVEL, this.getPromoteLevel())); + showAvatarInfo.putPropMap(PlayerProperty.PROP_SATIATION_VAL.getId(), ProtoHelper.newPropValue(PlayerProperty.PROP_SATIATION_VAL, this.getSatiation())); + showAvatarInfo.putPropMap(PlayerProperty.PROP_SATIATION_PENALTY_TIME.getId(), ProtoHelper.newPropValue(PlayerProperty.PROP_SATIATION_VAL, this.getSatiationPenalty())); + int maxStamina = this.getPlayer().getProperty(PlayerProperty.PROP_MAX_STAMINA); + showAvatarInfo.putPropMap(PlayerProperty.PROP_MAX_STAMINA.getId(), ProtoHelper.newPropValue(PlayerProperty.PROP_MAX_STAMINA, maxStamina)); + + for (GameItem item : this.getEquips().values()) { + if (item.getItemType() == ItemType.ITEM_RELIQUARY) { + showAvatarInfo.addEquipList(ShowEquip.newBuilder() + .setItemId(item.getItemId()) + .setReliquary(item.toReliquaryProto())); + } else if (item.getItemType() == ItemType.ITEM_WEAPON) { + showAvatarInfo.addEquipList(ShowEquip.newBuilder() + .setItemId(item.getItemId()) + .setWeapon(item.toWeaponProto())); + } + } + + return showAvatarInfo.build(); + } @PostLoad private void onLoad() { diff --git a/src/main/java/emu/grasscutter/game/inventory/GameItem.java b/src/main/java/emu/grasscutter/game/inventory/GameItem.java index 252c0a01c..7293b75c0 100644 --- a/src/main/java/emu/grasscutter/game/inventory/GameItem.java +++ b/src/main/java/emu/grasscutter/game/inventory/GameItem.java @@ -375,6 +375,32 @@ public class GameItem { return relicInfo; } + public Weapon toWeaponProto() { + Weapon.Builder weapon = Weapon.newBuilder() + .setLevel(this.getLevel()) + .setExp(this.getExp()) + .setPromoteLevel(this.getPromoteLevel()); + + if (this.getAffixes() != null && this.getAffixes().size() > 0) { + for (int affix : this.getAffixes()) { + weapon.putAffixMap(affix, this.getRefinement()); + } + } + + return weapon.build(); + } + + public Reliquary toReliquaryProto() { + Reliquary.Builder relic = Reliquary.newBuilder() + .setLevel(this.getLevel()) + .setExp(this.getExp()) + .setPromoteLevel(this.getPromoteLevel()) + .setMainPropId(this.getMainPropId()) + .addAllAppendPropIdList(this.getAppendPropIdList()); + + return relic.build(); + } + public Item toProto() { Item.Builder proto = Item.newBuilder() .setGuid(this.getGuid()) @@ -382,27 +408,11 @@ public class GameItem { switch (getItemType()) { case ITEM_WEAPON: - Weapon.Builder weapon = Weapon.newBuilder() - .setLevel(this.getLevel()) - .setExp(this.getExp()) - .setPromoteLevel(this.getPromoteLevel()); - - if (this.getAffixes() != null && this.getAffixes().size() > 0) { - for (int affix : this.getAffixes()) { - weapon.putAffixMap(affix, this.getRefinement()); - } - } - + Weapon weapon = this.toWeaponProto(); proto.setEquip(Equip.newBuilder().setWeapon(weapon).setIsLocked(this.isLocked()).build()); break; case ITEM_RELIQUARY: - Reliquary relic = Reliquary.newBuilder() - .setLevel(this.getLevel()) - .setExp(this.getExp()) - .setPromoteLevel(this.getPromoteLevel()) - .setMainPropId(this.getMainPropId()) - .addAllAppendPropIdList(this.getAppendPropIdList()) - .build(); + Reliquary relic = this.toReliquaryProto(); proto.setEquip(Equip.newBuilder().setReliquary(relic).setIsLocked(this.isLocked()).build()); break; case ITEM_MATERIAL: diff --git a/src/main/java/emu/grasscutter/game/player/Player.java b/src/main/java/emu/grasscutter/game/player/Player.java index 0637e3d43..2d3442bbe 100644 --- a/src/main/java/emu/grasscutter/game/player/Player.java +++ b/src/main/java/emu/grasscutter/game/player/Player.java @@ -21,7 +21,6 @@ import emu.grasscutter.game.inventory.Inventory; import emu.grasscutter.game.mail.Mail; import emu.grasscutter.game.props.ActionReason; import emu.grasscutter.game.props.PlayerProperty; -import emu.grasscutter.game.shop.ShopInfo; import emu.grasscutter.game.shop.ShopLimit; import emu.grasscutter.game.world.Scene; import emu.grasscutter.game.world.World; @@ -34,6 +33,7 @@ import emu.grasscutter.net.proto.OnlinePlayerInfoOuterClass.OnlinePlayerInfo; import emu.grasscutter.net.proto.PlayerApplyEnterMpResultNotifyOuterClass; import emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfo; import emu.grasscutter.net.proto.PlayerWorldLocationInfoOuterClass; +import emu.grasscutter.net.proto.ShowAvatarInfoOuterClass; import emu.grasscutter.net.proto.ProfilePictureOuterClass.ProfilePicture; import emu.grasscutter.net.proto.SocialDetailOuterClass.SocialDetail; import emu.grasscutter.net.proto.SocialShowAvatarInfoOuterClass; @@ -898,6 +898,35 @@ public class Player { .setFinishAchievementNum(0); return social; } + + public List getShowAvatarInfoList() { + List showAvatarInfoList = new ArrayList<>(); + + Player player; + boolean shouldRecalc; + if (this.isOnline()) { + player = this; + shouldRecalc = false; + } else { + player = DatabaseHelper.getPlayerById(id); + player.getAvatars().loadFromDatabase(); + player.getInventory().loadFromDatabase(); + shouldRecalc = true; + } + + List showAvatarList = player.getShowAvatarList(); + AvatarStorage avatars = player.getAvatars(); + if (showAvatarList != null) { + for (int avatarId : showAvatarList) { + Avatar avatar = avatars.getAvatarById(avatarId); + if (shouldRecalc) { + avatar.recalcStats(); + } + showAvatarInfoList.add(avatar.toShowAvatarInfoProto()); + } + } + return showAvatarInfoList; + } public PlayerWorldLocationInfoOuterClass.PlayerWorldLocationInfo getWorldPlayerLocationInfo() { return PlayerWorldLocationInfoOuterClass.PlayerWorldLocationInfo.newBuilder() diff --git a/src/main/java/emu/grasscutter/server/packet/recv/HandlerGetFriendShowAvatarInfoReq.java b/src/main/java/emu/grasscutter/server/packet/recv/HandlerGetFriendShowAvatarInfoReq.java new file mode 100644 index 000000000..61fd31640 --- /dev/null +++ b/src/main/java/emu/grasscutter/server/packet/recv/HandlerGetFriendShowAvatarInfoReq.java @@ -0,0 +1,26 @@ +package emu.grasscutter.server.packet.recv; + +import emu.grasscutter.game.player.Player; +import emu.grasscutter.net.packet.Opcodes; +import emu.grasscutter.net.packet.PacketHandler; +import emu.grasscutter.net.packet.PacketOpcodes; +import emu.grasscutter.net.proto.GetFriendShowAvatarInfoReqOuterClass.GetFriendShowAvatarInfoReq; +import emu.grasscutter.server.game.GameSession; +import emu.grasscutter.server.packet.send.PacketGetFriendShowAvatarInfoRsp; + +@Opcodes(PacketOpcodes.GetFriendShowAvatarInfoReq) +public class HandlerGetFriendShowAvatarInfoReq extends PacketHandler { + + @Override + public void handle(GameSession session, byte[] header, byte[] payload) throws Exception { + GetFriendShowAvatarInfoReq req = GetFriendShowAvatarInfoReq.parseFrom(payload); + + int targetUid = req.getUid(); + Player targetPlayer = session.getServer().getPlayerByUid(targetUid, true); + + if (targetPlayer.isShowAvatars()) { + session.send(new PacketGetFriendShowAvatarInfoRsp(targetUid, targetPlayer.getShowAvatarInfoList())); + } + } + +} diff --git a/src/main/java/emu/grasscutter/server/packet/send/PacketGetFriendShowAvatarInfoRsp.java b/src/main/java/emu/grasscutter/server/packet/send/PacketGetFriendShowAvatarInfoRsp.java new file mode 100644 index 000000000..f9b640659 --- /dev/null +++ b/src/main/java/emu/grasscutter/server/packet/send/PacketGetFriendShowAvatarInfoRsp.java @@ -0,0 +1,24 @@ +package emu.grasscutter.server.packet.send; + +import java.util.List; + +import emu.grasscutter.net.packet.BasePacket; +import emu.grasscutter.net.packet.Opcodes; +import emu.grasscutter.net.packet.PacketOpcodes; +import emu.grasscutter.net.proto.GetFriendShowAvatarInfoRspOuterClass.GetFriendShowAvatarInfoRsp; +import emu.grasscutter.net.proto.ShowAvatarInfoOuterClass.ShowAvatarInfo; + +@Opcodes(PacketOpcodes.GetFriendShowAvatarInfoRsp) +public class PacketGetFriendShowAvatarInfoRsp extends BasePacket { + + public PacketGetFriendShowAvatarInfoRsp(int uid, List showAvatarInfoList) { + super(PacketOpcodes.GetFriendShowAvatarInfoRsp); + + GetFriendShowAvatarInfoRsp.Builder p = GetFriendShowAvatarInfoRsp.newBuilder() + .setUid(uid) + .addAllShowAvatarInfoList(showAvatarInfoList); + + this.setData(p.build()); + } + +}