9
0
mirror of https://github.com/BX-Team/DivineMC.git synced 2025-12-22 16:29:23 +00:00
Files
DivineMC/divinemc-server/paper-patches/features/0016-Petal-Multithreaded-Tracker.patch
2025-07-09 03:03:03 +03:00

78 lines
4.5 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
Date: Sat, 1 Mar 2025 23:06:52 +0300
Subject: [PATCH] Petal: Multithreaded Tracker
Original project: https://github.com/Bloom-host/Petal
Original license: GPL v3
Patch description:
We made much of tracking logic asynchronously, and fixed visible issue
for the case of some NPC plugins which using real entity type, e.g. Citizens.
But it is still recommending to use those packet based, virtual entity
based NPC plugins, e.g. ZNPC Plus, Adyeshach, Fancy NPC, etc.
diff --git a/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java b/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java
index d7398b1ecf2660c29fb7d106b48fe02d3736603e..ab499a7eaccdc1578ec64f90f54f79b0da3c0e96 100644
--- a/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java
+++ b/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java
@@ -42,6 +42,12 @@ class PaperEventManager {
if (event.isAsynchronous() && this.server.isPrimaryThread()) {
throw new IllegalStateException(event.getEventName() + " may only be triggered asynchronously.");
} else if (!event.isAsynchronous() && !this.server.isPrimaryThread() && !this.server.isStopping()) {
+ // DivineMC start - Multithreaded Tracker
+ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.multithreadedEnabled) {
+ net.minecraft.server.MinecraftServer.getServer().scheduleOnMain(event::callEvent);
+ return;
+ }
+ // DivineMC end - Multithreaded Tracker
throw new IllegalStateException(event.getEventName() + " may only be triggered synchronously.");
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
index 4913ac7d0426025689c8aee3790d87f7ac0131fd..d4d3aeae964d9a64805ddc5862e46fff5dd7d98a 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -2953,7 +2953,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player, PluginMessa
Iterator<AttributeInstance> iterator = collection.iterator();
while (iterator.hasNext()) {
AttributeInstance genericInstance = iterator.next();
- if (genericInstance.getAttribute() == Attributes.MAX_HEALTH) {
+ if (genericInstance != null && genericInstance.getAttribute() == Attributes.MAX_HEALTH) {
iterator.remove();
break;
}
diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
index d10ee84ed2f6b1c81667b968984f3ebf5c39e445..83c6cf3cb062c8a6508728822e37d52a543415a3 100644
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
@@ -1808,6 +1808,26 @@ public class CraftEventFactory {
}
public static boolean handleBlockFormEvent(Level world, BlockPos pos, net.minecraft.world.level.block.state.BlockState state, int flags, @Nullable Entity entity, boolean checkSetResult) {
+ // DivineMC start - Multithreaded Tracker
+ if (org.bxteam.divinemc.config.DivineConfig.AsyncCategory.multithreadedEnabled && Thread.currentThread() instanceof org.bxteam.divinemc.entity.tracking.MultithreadedTracker.MultithreadedTrackerThread) {
+ java.util.concurrent.CompletableFuture<Boolean> future = new java.util.concurrent.CompletableFuture<>();
+ net.minecraft.server.MinecraftServer.getServer().scheduleOnMain(() -> {
+ boolean resultFlag = false;
+ CraftBlockState snapshot = CraftBlockStates.getBlockState(world, pos);
+ snapshot.setData(state);
+
+ BlockFormEvent event = (entity == null) ? new BlockFormEvent(snapshot.getBlock(), snapshot) : new EntityBlockFormEvent(entity.getBukkitEntity(), snapshot.getBlock(), snapshot);
+ if (event.callEvent()) {
+ boolean result = snapshot.place(flags);
+ resultFlag = !checkSetResult || result;
+ }
+
+ future.complete(resultFlag);
+ });
+
+ return future.join();
+ }
+ // DivineMC end - Multithreaded Tracker
CraftBlockState snapshot = CraftBlockStates.getBlockState(world, pos);
snapshot.setData(state);