From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: peaches94 Date: Sat, 2 Jul 2022 00:35:56 -0500 Subject: [PATCH] Multithreaded Tracker Original license: GPL v3 Original project: https://github.com/Bloom-host/Petal Original license: GPL v3 Original project: https://github.com/TECHNOVE/Airplane-Experimental Co-authored-by: Paul Sauve Co-authored-by: Kevin Raneri Co-authored-by: HaHaWTH <102713261+HaHaWTH@users.noreply.github.com> Co-authored-by: hayanesuru This patch refactored from original multithreaded tracker (Petal version), and is derived from the Airplane fork by Paul Sauve, the tree is like: Airplane -> Pufferfish(?) -> Petal -> Leaf The core logic has beed reworked compared to the old one, can handle larger scale situation better now. Current impl includes many improvements and fixes we made, such as plugin compat issues with some NPC plugins using real entity type, e.g. Citizens. However we still recommend to use those packet based NPC plugins, e.g. ZNPC Plus, Adyeshach, Fancy NPC, etc. diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java index beae8a57a0ce9b8e7d81619efe4c39d908869319..6b1926080eddf61ff9c0156a6846f7f0bcff1c2d 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java @@ -764,7 +764,7 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { ChunkMap.TrackedEntity entityTracker = world.getChunkSource().chunkMap.entityMap.get(this.getEntityId()); if (entityTracker != null) { - for (ServerPlayerConnection connection : entityTracker.seenBy) { + for (ServerPlayerConnection connection : entityTracker.seenBy()) { // Leaf - Multithreaded tracker players.add(connection.getPlayer().getBukkitEntity()); } } @@ -1095,7 +1095,7 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { return; } - for (final ServerPlayerConnection connection : entityTracker.seenBy) { + for (final ServerPlayerConnection connection : entityTracker.seenBy()) { // Leaf - Multithreaded tracker this.getHandle().resendPossiblyDesyncedEntityData(connection.getPlayer()); } } @@ -1242,7 +1242,7 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { } Set set = new java.util.HashSet<>(tracker.seenBy.size()); - for (net.minecraft.server.network.ServerPlayerConnection connection : tracker.seenBy) { + for (net.minecraft.server.network.ServerPlayerConnection connection : tracker.seenBy()) { // Leaf - Multithreaded tracker set.add(connection.getPlayer().getBukkitEntity().getPlayer()); } return set; diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java index a6463974c63e40afce0c6656122f6f918fdc089b..0f085618f6866bef1a526c6404f92e26f7bef0fd 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -217,7 +217,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player, PluginMessa private static final WeakHashMap> pluginWeakReferences = new WeakHashMap<>(); private static final net.kyori.adventure.text.Component DEFAULT_KICK_COMPONENT = net.kyori.adventure.text.Component.translatable("multiplayer.disconnect.kicked"); private final ConversationTracker conversationTracker = new ConversationTracker(); - private final Map>> invertedVisibilityEntities = new it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<>(); // SparklyPaper - optimize canSee checks + private final Map>> invertedVisibilityEntities = org.dreeam.leaf.config.modules.async.MultithreadedTracker.enabled ? it.unimi.dsi.fastutil.objects.Object2ObjectMaps.synchronize(new it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<>()) : new it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<>(); // SparklyPaper - optimize canSee checks // Leaf - Multithreaded tracker private final Set unlistedEntities = new HashSet<>(); // Paper - Add Listing API for Player private long firstPlayed = 0; private long lastPlayed = 0; @@ -2961,7 +2961,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player, PluginMessa Iterator iterator = collection.iterator(); while (iterator.hasNext()) { AttributeInstance genericInstance = iterator.next(); - if (genericInstance.getAttribute() == Attributes.MAX_HEALTH) { + if (genericInstance != null && genericInstance.getAttribute() == Attributes.MAX_HEALTH) { // Leaf - Multithreaded tracker iterator.remove(); break; }