From ad57bb91df66430b20bfd6415d38c2dcf5374e48 Mon Sep 17 00:00:00 2001 From: Melledy <52122272+Melledy@users.noreply.github.com> Date: Sun, 17 Apr 2022 23:43:47 -0700 Subject: [PATCH] Remove gadgets from world when a player leaves --- src/main/java/emu/grasscutter/game/TeamManager.java | 11 +++++++++-- src/main/java/emu/grasscutter/game/World.java | 12 ++++++++++-- .../packet/recv/HandlerEvtCreateGadgetNotify.java | 5 +++++ 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/main/java/emu/grasscutter/game/TeamManager.java b/src/main/java/emu/grasscutter/game/TeamManager.java index 5649151a4..cf8de4169 100644 --- a/src/main/java/emu/grasscutter/game/TeamManager.java +++ b/src/main/java/emu/grasscutter/game/TeamManager.java @@ -2,9 +2,12 @@ package emu.grasscutter.game; import java.util.ArrayList; import java.util.HashMap; +import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; +import java.util.Set; + import dev.morphia.annotations.Transient; import emu.grasscutter.GenshinConstants; import emu.grasscutter.data.def.AvatarSkillDepotData; @@ -47,14 +50,14 @@ public class TeamManager { @Transient private TeamInfo mpTeam; @Transient private int entityId; @Transient private final List avatars; - @Transient private final List gadgets; + @Transient private final Set gadgets; @Transient private final IntSet teamResonances; @Transient private final IntSet teamResonancesConfig; public TeamManager() { this.mpTeam = new TeamInfo(); this.avatars = new ArrayList<>(); - this.gadgets = new ArrayList<>(); + this.gadgets = new HashSet<>(); this.teamResonances = new IntOpenHashSet(); this.teamResonancesConfig = new IntOpenHashSet(); } @@ -134,6 +137,10 @@ public class TeamManager { this.entityId = entityId; } + public Set getGadgets() { + return gadgets; + } + public IntSet getTeamResonances() { return teamResonances; } diff --git a/src/main/java/emu/grasscutter/game/World.java b/src/main/java/emu/grasscutter/game/World.java index 76187d1de..a06b584f1 100644 --- a/src/main/java/emu/grasscutter/game/World.java +++ b/src/main/java/emu/grasscutter/game/World.java @@ -17,6 +17,7 @@ import emu.grasscutter.game.props.LifeState; import emu.grasscutter.game.GenshinPlayer.SceneLoadState; import emu.grasscutter.game.entity.EntityAvatar; import emu.grasscutter.game.entity.EntityClientGadget; +import emu.grasscutter.game.entity.EntityGadget; import emu.grasscutter.net.packet.GenshinPacket; import emu.grasscutter.net.proto.AttackResultOuterClass.AttackResult; import emu.grasscutter.net.proto.EnterTypeOuterClass.EnterType; @@ -197,6 +198,11 @@ public class World implements Iterable { this.updatePlayerInfos(player); } + // Remove player gadgets + for (EntityGadget gadget : player.getTeamManager().getGadgets()) { + this.removeEntity(gadget); + } + // Disband world if host leaves if (getHost() == player) { List kicked = new ArrayList<>(this.getPlayers()); @@ -377,7 +383,8 @@ public class World implements Iterable { // Directly add this.addEntityDirectly(gadget); - // Add to owner's gadget list TODO + // Add to owner's gadget list + gadget.getOwner().getTeamManager().getGadgets().add(gadget); // Optimization if (this.getPlayerCount() == 1 && this.getPlayers().get(0) == gadget.getOwner()) { @@ -398,7 +405,8 @@ public class World implements Iterable { EntityClientGadget gadget = (EntityClientGadget) entity; this.removeEntityDirectly(gadget); - // Remove from owner's gadget list TODO + // Remove from owner's gadget list + gadget.getOwner().getTeamManager().getGadgets().remove(gadget); // Optimization if (this.getPlayerCount() == 1 && this.getPlayers().get(0) == gadget.getOwner()) { diff --git a/src/main/java/emu/grasscutter/server/packet/recv/HandlerEvtCreateGadgetNotify.java b/src/main/java/emu/grasscutter/server/packet/recv/HandlerEvtCreateGadgetNotify.java index f4c5708d0..9fbd97fdf 100644 --- a/src/main/java/emu/grasscutter/server/packet/recv/HandlerEvtCreateGadgetNotify.java +++ b/src/main/java/emu/grasscutter/server/packet/recv/HandlerEvtCreateGadgetNotify.java @@ -19,6 +19,11 @@ public class HandlerEvtCreateGadgetNotify extends PacketHandler { return; } + // Sanity check - dont add duplicate entities + if (session.getPlayer().getWorld().getEntityById(notify.getEntityId()) != null) { + return; + } + // Create entity and summon in world EntityClientGadget gadget = new EntityClientGadget(session.getPlayer().getWorld(), session.getPlayer(), notify); session.getPlayer().getWorld().onPlayerCreateGadget(gadget);