Refactor player sync packet

This commit is contained in:
Melledy
2024-08-04 01:32:30 -07:00
parent 4cd7a512ae
commit 9ce053c1b3
12 changed files with 135 additions and 215 deletions

View File

@@ -64,7 +64,7 @@ public class AvatarCommand implements CommandHandler {
if (changeList.size() > 0) { if (changeList.size() > 0) {
// Send packet // Send packet
args.getTarget().sendPacket(new PacketPlayerSyncScNotify(changeList.toArray(GameAvatar[]::new))); args.getTarget().sendPacket(new PacketPlayerSyncScNotify(changeList));
// Send message // Send message
args.sendMessage("Set avatar(s) properties successfully"); args.sendMessage("Set avatar(s) properties successfully");
} else { } else {

View File

@@ -20,7 +20,7 @@ public class AvatarData {
@Setter private int rank; // Eidolons @Setter private int rank; // Eidolons
private Int2IntMap skills; // Skill tree private Int2IntMap skills; // Skill tree
@Setter private transient IAvatar baseAvatar; @Setter private transient BaseAvatar baseAvatar;
private transient Int2ObjectMap<GameItem> equips; private transient Int2ObjectMap<GameItem> equips;
@Deprecated // Morphia only @Deprecated // Morphia only

View File

@@ -15,12 +15,13 @@ import emu.lunarcore.game.player.Player;
import emu.lunarcore.proto.AvatarSkillTreeOuterClass.AvatarSkillTree; import emu.lunarcore.proto.AvatarSkillTreeOuterClass.AvatarSkillTree;
import emu.lunarcore.proto.EquipRelicOuterClass.EquipRelic; import emu.lunarcore.proto.EquipRelicOuterClass.EquipRelic;
import emu.lunarcore.proto.MultiPathAvatarInfoOuterClass.MultiPathAvatarInfo; import emu.lunarcore.proto.MultiPathAvatarInfoOuterClass.MultiPathAvatarInfo;
import emu.lunarcore.proto.PlayerSyncScNotifyOuterClass.PlayerSyncScNotify;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
@Getter @Getter
@Entity(value = "multiPaths", useDiscriminator = false) @Entity(value = "multiPaths", useDiscriminator = false)
public class AvatarMultiPath implements IAvatar { public class AvatarMultiPath extends BaseAvatar {
@Id private ObjectId id; @Id private ObjectId id;
@Indexed private int ownerUid; @Indexed private int ownerUid;
@@ -62,6 +63,16 @@ public class AvatarMultiPath implements IAvatar {
return this.getData().getSkills(); return this.getData().getSkills();
} }
// Player sync
// Player sync
public void onSync(PlayerSyncScNotify proto) {
proto.addMultiPathAvatarInfoList(this.toProto());
}
// Proto
public MultiPathAvatarInfo toProto() { public MultiPathAvatarInfo toProto() {
var proto = MultiPathAvatarInfo.newInstance() var proto = MultiPathAvatarInfo.newInstance()
.setAvatarIdValue(this.getExcelId()) .setAvatarIdValue(this.getExcelId())
@@ -83,6 +94,8 @@ public class AvatarMultiPath implements IAvatar {
return proto; return proto;
} }
// Database
public void save() { public void save() {
LunarCore.getGameDatabase().save(this); LunarCore.getGameDatabase().save(this);
} }

View File

@@ -42,8 +42,8 @@ public class AvatarStorage extends BasePlayerManager implements Iterable<GameAva
// Base avatars // Base avatars
public IAvatar getBaseAvatarById(int id) { public BaseAvatar getBaseAvatarById(int id) {
IAvatar baseAvatar = this.getMultiPathById(id); BaseAvatar baseAvatar = this.getMultiPathById(id);
if (baseAvatar == null) { if (baseAvatar == null) {
baseAvatar = this.getAvatarById(id); baseAvatar = this.getAvatarById(id);
} }
@@ -51,8 +51,8 @@ public class AvatarStorage extends BasePlayerManager implements Iterable<GameAva
return baseAvatar; return baseAvatar;
} }
public IAvatar getBaseAvatarById(ObjectId id) { public BaseAvatar getBaseAvatarById(ObjectId id) {
IAvatar baseAvatar = this.getMultiPathById(id); BaseAvatar baseAvatar = this.getMultiPathById(id);
if (baseAvatar == null) { if (baseAvatar == null) {
baseAvatar = this.getAvatarById(id); baseAvatar = this.getAvatarById(id);
} }

View File

@@ -6,43 +6,46 @@ import emu.lunarcore.GameConstants;
import emu.lunarcore.data.excel.AvatarExcel; import emu.lunarcore.data.excel.AvatarExcel;
import emu.lunarcore.game.inventory.GameItem; import emu.lunarcore.game.inventory.GameItem;
import emu.lunarcore.game.player.Player; import emu.lunarcore.game.player.Player;
import emu.lunarcore.server.game.Syncable;
import emu.lunarcore.server.packet.send.PacketPlayerSyncScNotify; import emu.lunarcore.server.packet.send.PacketPlayerSyncScNotify;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
public interface IAvatar { public abstract class BaseAvatar implements Syncable {
public ObjectId getId(); // Properties
public Player getOwner(); public abstract ObjectId getId();
public AvatarData getData(); public abstract Player getOwner();
public abstract AvatarData getData();
// Excels // Excels
public int getExcelId(); public abstract int getExcelId();
public AvatarExcel getExcel(); public abstract AvatarExcel getExcel();
// Equip handlers // Equip handlers
public default Int2ObjectMap<GameItem> getEquips() { public Int2ObjectMap<GameItem> getEquips() {
return this.getData().getEquips(); return this.getData().getEquips();
} }
public default GameItem getEquipBySlot(int slot) { public GameItem getEquipBySlot(int slot) {
return this.getEquips().get(slot); return this.getEquips().get(slot);
} }
public default GameItem getEquipment() { public GameItem getEquipment() {
return this.getEquips().get(GameConstants.EQUIPMENT_SLOT_ID); return this.getEquips().get(GameConstants.EQUIPMENT_SLOT_ID);
} }
public default boolean equipItem(GameItem item) { public boolean equipItem(GameItem item) {
// Sanity check // Sanity check
int slot = item.getEquipSlot(); int slot = item.getEquipSlot();
if (slot == 0) return false; if (slot == 0) return false;
// Check if other avatars have this item equipped // Check if other avatars have this item equipped
IAvatar otherAvatar = item.getEquipAvatar(); BaseAvatar otherAvatar = item.getEquipAvatar();
if (otherAvatar != null) { if (otherAvatar != null) {
// Unequip this item from the other avatar // Unequip this item from the other avatar
if (otherAvatar.unequipItem(slot) != null) { if (otherAvatar.unequipItem(slot) != null) {
@@ -75,7 +78,7 @@ public interface IAvatar {
return true; return true;
} }
public default GameItem unequipItem(int slot) { public GameItem unequipItem(int slot) {
GameItem item = getEquips().remove(slot); GameItem item = getEquips().remove(slot);
if (item != null) { if (item != null) {

View File

@@ -28,6 +28,7 @@ import emu.lunarcore.proto.DisplayRelicInfoOuterClass.DisplayRelicInfo;
import emu.lunarcore.proto.EquipRelicOuterClass.EquipRelic; import emu.lunarcore.proto.EquipRelicOuterClass.EquipRelic;
import emu.lunarcore.proto.LineupAvatarOuterClass.LineupAvatar; import emu.lunarcore.proto.LineupAvatarOuterClass.LineupAvatar;
import emu.lunarcore.proto.MotionInfoOuterClass.MotionInfo; import emu.lunarcore.proto.MotionInfoOuterClass.MotionInfo;
import emu.lunarcore.proto.PlayerSyncScNotifyOuterClass.PlayerSyncScNotify;
import emu.lunarcore.proto.SceneActorInfoOuterClass.SceneActorInfo; import emu.lunarcore.proto.SceneActorInfoOuterClass.SceneActorInfo;
import emu.lunarcore.proto.SceneEntityInfoOuterClass.SceneEntityInfo; import emu.lunarcore.proto.SceneEntityInfoOuterClass.SceneEntityInfo;
import emu.lunarcore.proto.SpBarInfoOuterClass.SpBarInfo; import emu.lunarcore.proto.SpBarInfoOuterClass.SpBarInfo;
@@ -40,7 +41,7 @@ import lombok.Setter;
@Getter @Getter
@Entity(value = "avatars", useDiscriminator = false) @Entity(value = "avatars", useDiscriminator = false)
public class GameAvatar implements GameEntity, IAvatar { public class GameAvatar extends BaseAvatar implements GameEntity {
@Id private ObjectId id; @Id private ObjectId id;
@Indexed @Getter private int ownerUid; // Uid of player that this avatar belongs to @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)); 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 // Proto
public Avatar toProto() { public Avatar toProto() {

View File

@@ -13,7 +13,7 @@ import emu.lunarcore.data.GameDepot;
import emu.lunarcore.data.excel.ItemExcel; import emu.lunarcore.data.excel.ItemExcel;
import emu.lunarcore.data.excel.RelicMainAffixExcel; import emu.lunarcore.data.excel.RelicMainAffixExcel;
import emu.lunarcore.data.excel.RelicSubAffixExcel; 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.AvatarPropertyType;
import emu.lunarcore.game.enums.ItemMainType; import emu.lunarcore.game.enums.ItemMainType;
import emu.lunarcore.game.player.Player; 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.ItemOuterClass.Item;
import emu.lunarcore.proto.MaterialOuterClass.Material; import emu.lunarcore.proto.MaterialOuterClass.Material;
import emu.lunarcore.proto.PileItemOuterClass.PileItem; import emu.lunarcore.proto.PileItemOuterClass.PileItem;
import emu.lunarcore.proto.PlayerSyncScNotifyOuterClass.PlayerSyncScNotify;
import emu.lunarcore.proto.RelicOuterClass.Relic; import emu.lunarcore.proto.RelicOuterClass.Relic;
import emu.lunarcore.server.game.Syncable;
import emu.lunarcore.util.Utils; import emu.lunarcore.util.Utils;
import emu.lunarcore.util.WeightedList; import emu.lunarcore.util.WeightedList;
import it.unimi.dsi.fastutil.ints.IntOpenHashSet; import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
@@ -31,7 +33,7 @@ import lombok.Setter;
@Getter @Getter
@Entity(value = "items", useDiscriminator = false) @Entity(value = "items", useDiscriminator = false)
public class GameItem { public class GameItem implements Syncable {
@Id private ObjectId id; @Id private ObjectId id;
@Indexed private int ownerUid; // Uid of player that this avatar belongs to @Indexed private int ownerUid; // Uid of player that this avatar belongs to
@@ -53,7 +55,7 @@ public class GameItem {
private List<GameItemSubAffix> subAffixes; private List<GameItemSubAffix> subAffixes;
@Indexed private ObjectId equipAvatarId; // Object id of the avatar this item is equipped to @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") @LoadOnly @AlsoLoad("equipAvatar")
private int equipAvatarExcelId; // Deprecated legacy field private int equipAvatarExcelId; // Deprecated legacy field
@@ -151,7 +153,7 @@ public class GameItem {
return false; return false;
} }
public boolean setEquipAvatar(IAvatar baseAvatar) { public boolean setEquipAvatar(BaseAvatar baseAvatar) {
if (baseAvatar == null && this.isEquipped()) { if (baseAvatar == null && this.isEquipped()) {
this.equipAvatarId = null; this.equipAvatarId = null;
this.equipAvatar = null; this.equipAvatar = null;
@@ -272,6 +274,33 @@ public class GameItem {
} }
} }
// 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 // Proto
public Material toMaterialProto() { public Material toMaterialProto() {

View File

@@ -14,7 +14,7 @@ import emu.lunarcore.data.excel.AvatarExcel;
import emu.lunarcore.data.excel.ItemExcel; import emu.lunarcore.data.excel.ItemExcel;
import emu.lunarcore.game.avatar.AvatarStorage; import emu.lunarcore.game.avatar.AvatarStorage;
import emu.lunarcore.game.avatar.GameAvatar; 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.ItemMainType;
import emu.lunarcore.game.enums.ItemSubType; import emu.lunarcore.game.enums.ItemSubType;
import emu.lunarcore.game.inventory.tabs.EquipInventoryTab; import emu.lunarcore.game.inventory.tabs.EquipInventoryTab;
@@ -554,7 +554,7 @@ public class Inventory extends BasePlayerManager {
// Equips // Equips
public boolean equipItem(int avatarId, int equipId) { public boolean equipItem(int avatarId, int equipId) {
IAvatar avatar = getPlayer().getAvatars().getBaseAvatarById(avatarId); BaseAvatar avatar = getPlayer().getAvatars().getBaseAvatarById(avatarId);
GameItem item = this.getItemByUid(equipId); GameItem item = this.getItemByUid(equipId);
if (avatar != null && item != null) { if (avatar != null && item != null) {
@@ -565,7 +565,7 @@ public class Inventory extends BasePlayerManager {
} }
public boolean unequipItem(int avatarId, int slot) { public boolean unequipItem(int avatarId, int slot) {
IAvatar avatar = getPlayer().getAvatars().getBaseAvatarById(avatarId); BaseAvatar avatar = getPlayer().getAvatars().getBaseAvatarById(avatarId);
if (avatar != null) { if (avatar != null) {
GameItem unequipped = avatar.unequipItem(slot); GameItem unequipped = avatar.unequipItem(slot);
@@ -614,7 +614,7 @@ public class Inventory extends BasePlayerManager {
// Equip to a character if possible // Equip to a character if possible
if (item.isEquipped() || item.getEquipAvatarExcelId() > 0) { if (item.isEquipped() || item.getEquipAvatarExcelId() > 0) {
IAvatar avatar = null; BaseAvatar avatar = null;
boolean hasEquipped = false; boolean hasEquipped = false;
if (item.getEquipAvatarExcelId() > 0) { if (item.getEquipAvatarExcelId() > 0) {

View File

@@ -61,10 +61,12 @@ import emu.lunarcore.proto.HeadIconOuterClass.HeadIcon;
import emu.lunarcore.proto.PlatformTypeOuterClass.PlatformType; import emu.lunarcore.proto.PlatformTypeOuterClass.PlatformType;
import emu.lunarcore.proto.PlayerBasicInfoOuterClass.PlayerBasicInfo; import emu.lunarcore.proto.PlayerBasicInfoOuterClass.PlayerBasicInfo;
import emu.lunarcore.proto.PlayerDetailInfoOuterClass.PlayerDetailInfo; import emu.lunarcore.proto.PlayerDetailInfoOuterClass.PlayerDetailInfo;
import emu.lunarcore.proto.PlayerSyncScNotifyOuterClass.PlayerSyncScNotify;
import emu.lunarcore.proto.RogueCurVirtualItemInfoOuterClass.RogueCurVirtualItemInfo; import emu.lunarcore.proto.RogueCurVirtualItemInfoOuterClass.RogueCurVirtualItemInfo;
import emu.lunarcore.proto.SimpleInfoOuterClass.SimpleInfo; import emu.lunarcore.proto.SimpleInfoOuterClass.SimpleInfo;
import emu.lunarcore.server.game.GameServer; import emu.lunarcore.server.game.GameServer;
import emu.lunarcore.server.game.GameSession; import emu.lunarcore.server.game.GameSession;
import emu.lunarcore.server.game.Syncable;
import emu.lunarcore.server.game.Tickable; import emu.lunarcore.server.game.Tickable;
import emu.lunarcore.server.packet.BasePacket; import emu.lunarcore.server.packet.BasePacket;
import emu.lunarcore.server.packet.CmdId; import emu.lunarcore.server.packet.CmdId;
@@ -80,7 +82,7 @@ import us.hebi.quickbuf.RepeatedMessage;
@Entity(value = "players", useDiscriminator = false) @Entity(value = "players", useDiscriminator = false)
@Getter @Getter
public class Player implements Tickable { public class Player implements Tickable, Syncable {
@Id private int uid; @Id private int uid;
@Indexed private String accountUid; @Indexed private String accountUid;
private String name; 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 // Protobuf serialization
public PlayerBasicInfo toProto() { public PlayerBasicInfo toProto() {

View File

@@ -7,6 +7,8 @@ import emu.lunarcore.LunarCore;
import emu.lunarcore.data.GameData; import emu.lunarcore.data.GameData;
import emu.lunarcore.game.avatar.GameAvatar; import emu.lunarcore.game.avatar.GameAvatar;
import emu.lunarcore.game.enums.PersonalizeShowType; 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.BasePacket;
import emu.lunarcore.server.packet.send.PacketPlayerSyncScNotify; import emu.lunarcore.server.packet.send.PacketPlayerSyncScNotify;
import emu.lunarcore.server.packet.send.PacketUnlockChatBubbleScNotify; import emu.lunarcore.server.packet.send.PacketUnlockChatBubbleScNotify;
@@ -17,7 +19,7 @@ import lombok.Getter;
@Getter @Getter
@Entity(value = "unlocks", useDiscriminator = false) @Entity(value = "unlocks", useDiscriminator = false)
public class PlayerUnlockData { public class PlayerUnlockData implements Syncable {
private transient Player owner; private transient Player owner;
@Id private int ownerUid; @Id private int ownerUid;
@@ -89,7 +91,7 @@ public class PlayerUnlockData {
boolean success = this.getHeadIcons().add(headIconId); boolean success = this.getHeadIcons().add(headIconId);
if (success && this.getOwner().isLoggedIn()) { if (success && this.getOwner().isLoggedIn()) {
this.sendPacket(new PacketPlayerSyncScNotify(getOwner().toBoardData())); this.sendPacket(new PacketPlayerSyncScNotify(this));
this.save(); this.save();
} }
} }
@@ -116,6 +118,14 @@ public class PlayerUnlockData {
this.getOwner().sendPacket(packet); this.getOwner().sendPacket(packet);
} }
// Player sync
public void onSync(PlayerSyncScNotify proto) {
proto.setBoardDataSync(this.getOwner().toBoardData());
}
// Database
public void save() { public void save() {
LunarCore.getGameDatabase().save(this); LunarCore.getGameDatabase().save(this);
} }

View File

@@ -0,0 +1,9 @@
package emu.lunarcore.server.game;
import emu.lunarcore.proto.PlayerSyncScNotifyOuterClass.PlayerSyncScNotify;
public interface Syncable {
public void onSync(PlayerSyncScNotify proto);
}

View File

@@ -1,16 +1,9 @@
package emu.lunarcore.server.packet.send; package emu.lunarcore.server.packet.send;
import java.util.Collection; import java.util.List;
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 emu.lunarcore.proto.PlayerSyncScNotifyOuterClass.PlayerSyncScNotify; import emu.lunarcore.proto.PlayerSyncScNotifyOuterClass.PlayerSyncScNotify;
import emu.lunarcore.server.game.Syncable;
import emu.lunarcore.server.packet.BasePacket; import emu.lunarcore.server.packet.BasePacket;
import emu.lunarcore.server.packet.CmdId; import emu.lunarcore.server.packet.CmdId;
@@ -21,195 +14,37 @@ public class PacketPlayerSyncScNotify extends BasePacket {
super(CmdId.PlayerSyncScNotify); super(CmdId.PlayerSyncScNotify);
} }
public PacketPlayerSyncScNotify(Player player) { public PacketPlayerSyncScNotify(Syncable object) {
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) {
this(); this();
var data = PlayerSyncScNotify.newInstance(); var data = PlayerSyncScNotify.newInstance();
if (baseAvatar instanceof GameAvatar avatar) { object.onSync(data);
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());
}
this.setData(data); this.setData(data);
} }
public PacketPlayerSyncScNotify(IAvatar baseAvatar, GameItem item) { public PacketPlayerSyncScNotify(Syncable... objects) {
this(); this();
var data = PlayerSyncScNotify.newInstance(); var data = PlayerSyncScNotify.newInstance();
if (baseAvatar instanceof GameAvatar avatar) { for (var object : objects) {
data.getMutableAvatarSync().addAvatarList(avatar.toProto()); object.onSync(data);
// Also update multipath info
if (avatar.getMultiPath() != null) {
data.addMultiPathAvatarInfoList(avatar.getMultiPath().toProto());
} }
} else if (baseAvatar instanceof AvatarMultiPath multiPath) {
data.addMultiPathAvatarInfoList(multiPath.toProto());
}
this.addItemToProto(data, item);
this.setData(data); this.setData(data);
} }
public PacketPlayerSyncScNotify(GameAvatar avatar) { public PacketPlayerSyncScNotify(List<? extends Syncable> objects) {
this(); this();
var data = PlayerSyncScNotify.newInstance(); var data = PlayerSyncScNotify.newInstance();
// Update avatar for (var object : objects) {
data.getMutableAvatarSync().addAvatarList(avatar.toProto()); object.onSync(data);
// Also update multipath info
if (avatar.getMultiPath() != null) {
data.addMultiPathAvatarInfoList(avatar.getMultiPath().toProto());
} }
this.setData(data); 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<GameItem> 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);
}
} }