From ae05036bb370f62e54341c9d31d9411ad846290b Mon Sep 17 00:00:00 2001 From: Technici4n <13494793+Technici4n@users.noreply.github.com> Date: Fri, 5 May 2023 19:03:55 +0200 Subject: [PATCH] Make FakePlayerFactory respect the given ServerLevel (#9479) --- .../common/util/FakePlayerFactory.java | 35 +++++-------------- 1 file changed, 8 insertions(+), 27 deletions(-) diff --git a/src/main/java/net/minecraftforge/common/util/FakePlayerFactory.java b/src/main/java/net/minecraftforge/common/util/FakePlayerFactory.java index 5b587a13f0..30a8f1e44d 100644 --- a/src/main/java/net/minecraftforge/common/util/FakePlayerFactory.java +++ b/src/main/java/net/minecraftforge/common/util/FakePlayerFactory.java @@ -5,7 +5,6 @@ package net.minecraftforge.common.util; -import java.lang.ref.WeakReference; import java.util.Map; import java.util.UUID; @@ -17,48 +16,30 @@ import net.minecraft.server.level.ServerLevel; //To be expanded for generic Mod fake players? public class FakePlayerFactory { - private static GameProfile MINECRAFT = new GameProfile(UUID.fromString("41C82C87-7AfB-4024-BA57-13D2C99CAE77"), "[Minecraft]"); + private static final GameProfile MINECRAFT = new GameProfile(UUID.fromString("41C82C87-7AfB-4024-BA57-13D2C99CAE77"), "[Minecraft]"); // Map of all active fake player usernames to their entities - private static Map fakePlayers = Maps.newHashMap(); - private static WeakReference MINECRAFT_PLAYER = null; + private static final Map fakePlayers = Maps.newHashMap(); + private record FakePlayerKey(ServerLevel level, GameProfile username) { } public static FakePlayer getMinecraft(ServerLevel level) { - FakePlayer ret = MINECRAFT_PLAYER != null ? MINECRAFT_PLAYER.get() : null; - if (ret == null) - { - ret = FakePlayerFactory.get(level, MINECRAFT); - MINECRAFT_PLAYER = new WeakReference(ret); - } - return ret; + return get(level, MINECRAFT); } /** * Get a fake player with a given username, * Mods should either hold weak references to the return value, or listen for a - * WorldEvent.Unload and kill all references to prevent worlds staying in memory. + * WorldEvent.Unload and kill all references to prevent worlds staying in memory, + * or call this function every time and let Forge take care of the cleanup. */ public static FakePlayer get(ServerLevel level, GameProfile username) { - if (!fakePlayers.containsKey(username)) - { - FakePlayer fakePlayer = new FakePlayer(level, username); - fakePlayers.put(username, fakePlayer); - } - - return fakePlayers.get(username); + FakePlayerKey key = new FakePlayerKey(level, username); + return fakePlayers.computeIfAbsent(key, k -> new FakePlayer(k.level(), k.username())); } public static void unloadLevel(ServerLevel level) { fakePlayers.entrySet().removeIf(entry -> entry.getValue().level == level); - if (MINECRAFT_PLAYER != null && MINECRAFT_PLAYER.get() != null && MINECRAFT_PLAYER.get().level == level) // This shouldn't be strictly necessary, but lets be aggressive. - { - FakePlayer mc = MINECRAFT_PLAYER.get(); - if (mc != null && mc.level == level) - { - MINECRAFT_PLAYER = null; - } - } } }