From 9a783e9d5d3f0787d9071171231fe42aa59cdad6 Mon Sep 17 00:00:00 2001 From: Altiami Date: Wed, 3 Apr 2024 00:50:52 -0700 Subject: [PATCH] Move to more effective inject point --- .../nitori/access/IMixinChunkMapAccess.java | 35 +++++++++++++++++++ .../nitori/core/ChunkMapMixin.java | 14 ++++++++ .../nitori/tracker/MultithreadedTracker.java | 22 +----------- 3 files changed, 50 insertions(+), 21 deletions(-) diff --git a/src/main/java/net/gensokyoreimagined/nitori/access/IMixinChunkMapAccess.java b/src/main/java/net/gensokyoreimagined/nitori/access/IMixinChunkMapAccess.java index c6fe9da..339404e 100644 --- a/src/main/java/net/gensokyoreimagined/nitori/access/IMixinChunkMapAccess.java +++ b/src/main/java/net/gensokyoreimagined/nitori/access/IMixinChunkMapAccess.java @@ -14,6 +14,41 @@ // along with this program. If not, see . package net.gensokyoreimagined.nitori.access; +import org.spongepowered.asm.mixin.Unique; + +import javax.annotation.Nullable; + public interface IMixinChunkMapAccess { void gensouHacks$runOnTrackerMainThread(final Runnable runnable); + + @Nullable + Class gensouHacks$citizensPluginTrackedEntityClass = initCitizensPluginTrackedEntityClass(); + @Nullable + Class gensouHacks$citizensPluginHumanNPCEntityClass = initCitizensPluginHumanNPCEntityClass(); + + @Nullable + private static Class initCitizensPluginTrackedEntityClass() { + try { + return Class.forName("net.citizensnpcs.nms.v1_20_R3.util.CitizensEntityTracker", false, ClassLoader.getSystemClassLoader()); + } catch (ClassNotFoundException e) { + return null; + } + } + @Nullable + private static Class initCitizensPluginHumanNPCEntityClass() { + try { + return Class.forName("net.citizensnpcs.nms.v1_20_R3.entity.EntityHumanNPC", false, ClassLoader.getSystemClassLoader()); + } catch (ClassNotFoundException e) { + return null; + } + } + + @Nullable + static Class getGensouHacks$citizensPluginTrackedEntityClass() { + return gensouHacks$citizensPluginTrackedEntityClass; + } + @Nullable + static Class getGensouHacks$citizensPluginHumanNPCEntityClass() { + return gensouHacks$citizensPluginHumanNPCEntityClass; + } } diff --git a/src/main/java/net/gensokyoreimagined/nitori/core/ChunkMapMixin.java b/src/main/java/net/gensokyoreimagined/nitori/core/ChunkMapMixin.java index a8af258..c8494cb 100755 --- a/src/main/java/net/gensokyoreimagined/nitori/core/ChunkMapMixin.java +++ b/src/main/java/net/gensokyoreimagined/nitori/core/ChunkMapMixin.java @@ -116,6 +116,8 @@ public class ChunkMapMixin implements IMixinChunkMapAccess { @Shadow public Set seenBy; + @Shadow public abstract void updatePlayer(ServerPlayer player); + @Inject(method = "", at = @At("RETURN")) private void reassignSeenBy(CallbackInfo ci) { // Implementation of 0107-Multithreaded-Tracker.patch @@ -128,6 +130,18 @@ public class ChunkMapMixin implements IMixinChunkMapAccess { @Invoker public abstract void callUpdatePlayers(PooledLinkedHashSets.PooledObjectLinkedOpenHashSet newTrackerCandidates); // Mirai -> public + @Redirect(method = "updatePlayers(Lcom/destroystokyo/paper/util/misc/PooledLinkedHashSets$PooledObjectLinkedOpenHashSet;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ChunkMap$TrackedEntity;updatePlayer(Lnet/minecraft/server/level/ServerPlayer;)V")) + private void handleCitizensPluginTracking(ChunkMap.TrackedEntity self, ServerPlayer serverPlayer) { + // Nitori - Citizens tracker must run on the main thread to avoid cyclic wait + if (IMixinChunkMapAccess.gensouHacks$citizensPluginTrackedEntityClass != null && IMixinChunkMapAccess.gensouHacks$citizensPluginHumanNPCEntityClass != null && ChunkMapMixin.gensouHacks$citizensPluginTrackedEntityClass.isInstance(this) && ChunkMapMixin.gensouHacks$citizensPluginHumanNPCEntityClass.isInstance(serverPlayer)) { + ((IMixinChunkMapAccess) (Object) ((ServerLevel) serverPlayer.level()).chunkSource.chunkMap).gensouHacks$runOnTrackerMainThread(() -> + this.updatePlayer(serverPlayer) + ); + } else { + this.updatePlayer(serverPlayer); + } + } + // Implementation of 0107-Multithreaded-Tracker.patch @SuppressWarnings("EmptyMethod") @Redirect(method = "removePlayer", at = @At(value = "INVOKE", target = "Lorg/spigotmc/AsyncCatcher;catchOp(Ljava/lang/String;)V")) diff --git a/src/main/java/net/gensokyoreimagined/nitori/tracker/MultithreadedTracker.java b/src/main/java/net/gensokyoreimagined/nitori/tracker/MultithreadedTracker.java index 2ce337a..84a5482 100644 --- a/src/main/java/net/gensokyoreimagined/nitori/tracker/MultithreadedTracker.java +++ b/src/main/java/net/gensokyoreimagined/nitori/tracker/MultithreadedTracker.java @@ -53,9 +53,6 @@ public class MultithreadedTracker { private final ConcurrentLinkedQueue mainThreadTasks; private final AtomicInteger finishedTasks = new AtomicInteger(); - private static boolean searchedForCitizensPlugin = false; - private static Class citizensTrackedEtntityClass; - public MultithreadedTracker(IteratorSafeOrderedReferenceSet entityTickingChunks, ConcurrentLinkedQueue mainThreadTasks) { this.entityTickingChunks = entityTickingChunks; this.mainThreadTasks = mainThreadTasks; @@ -168,28 +165,11 @@ public class MultithreadedTracker { if (trackerStage == TrackerStage.SEND_CHANGES) { entityTracker.serverEntity.sendChanges(); } else if (trackerStage == TrackerStage.UPDATE_PLAYERS) { - // Nitori - Citizens tracker must run on the main thread to avoid cyclic wait - if (!searchedForCitizensPlugin) { - try { - citizensTrackedEtntityClass = Class.forName("net.citizensnpcs.nms.v1_20_R3.util.CitizensEntityTracker", false, ClassLoader.getSystemClassLoader()); - } catch (ClassNotFoundException ignored) {} - searchedForCitizensPlugin = true; - } - if (citizensTrackedEtntityClass != null && citizensTrackedEtntityClass.isInstance(entityTracker)) { - this.mainThreadTasks.add(() -> - invokeUpdatePlayersForCitizensTracker(entityTracker) - ); - } else { - invokeUpdatePlayersForCitizensTracker(entityTracker); - } + ((IMixinChunkMap_TrackedEntityAccess) (Object) entityTracker).callUpdatePlayers(((IMixinChunkMap_TrackedEntityAccess) (Object) entityTracker).getEntity().getPlayersInTrackRange()); } } } } } - private void invokeUpdatePlayersForCitizensTracker(ChunkMap.TrackedEntity entityTracker) { - ((IMixinChunkMap_TrackedEntityAccess) (Object) entityTracker).callUpdatePlayers(((IMixinChunkMap_TrackedEntityAccess) (Object) entityTracker).getEntity().getPlayersInTrackRange()); - } - }