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 5e46428e5dd24c581c816125b52cb32de087d5f4..c11449da3a89221e5525c229e990577c91238dc2 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java @@ -762,7 +762,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()); } } @@ -1093,7 +1093,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()); } } @@ -1240,7 +1240,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 3149a45297b5cffd247238bb04d3035568de5c07..4880ed8eaa3966c9669addfc72d7eb4abf537260 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -227,7 +227,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player, PluginMessa private long lastPlayed = 0; private boolean hasPlayedBefore = false; 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 static final WeakHashMap> pluginWeakReferences = new WeakHashMap<>(); private int hash = 0; @@ -2834,7 +2834,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; }