Compare commits

..

3 Commits

Author SHA1 Message Date
M2ke4U
dc6d7e9ca4 Complete tpsbar 2023-12-07 20:25:50 +08:00
M2ke4U
ea1df79c5d Added async pathfinding from kaiiju 2023-12-07 20:08:57 +08:00
M2ke4U
6f659aec21 Revert "Remove fluid direction optimization"
This reverts commit 5e5c48dab1.
2023-12-05 20:15:43 +08:00
23 changed files with 1598 additions and 13 deletions

View File

@@ -92,4 +92,4 @@ paperweight {
serverOutputDir.set(layout.projectDirectory.dir("Luminol-Server"))
}
}
}
}

View File

@@ -109,10 +109,10 @@ index 0000000000000000000000000000000000000000..3f74f748501d2f915869e9077dd2f220
+}
diff --git a/src/main/java/me/earthme/luminol/functions/GlobalServerTpsBar.java b/src/main/java/me/earthme/luminol/functions/GlobalServerTpsBar.java
new file mode 100644
index 0000000000000000000000000000000000000000..6a9919d8aec5e49df0dd13380cc7d8792ef7b228
index 0000000000000000000000000000000000000000..3023bc0e7420870e80dda75f7b044069b61a2b7e
--- /dev/null
+++ b/src/main/java/me/earthme/luminol/functions/GlobalServerTpsBar.java
@@ -0,0 +1,210 @@
@@ -0,0 +1,204 @@
+package me.earthme.luminol.functions;
+
+import com.google.common.collect.Lists;
@@ -139,7 +139,6 @@ index 0000000000000000000000000000000000000000..6a9919d8aec5e49df0dd13380cc7d879
+public class GlobalServerTpsBar {
+ protected static final MinecraftInternalPlugin NULL_PLUGIN = new MinecraftInternalPlugin();
+ protected static final Map<UUID,BossBar> uuid2Bossbars = new HashMap<>();
+ protected static final List<UUID> visibleExclude = Lists.newCopyOnWriteArrayList();
+ protected static volatile ScheduledTask tpsbarTask = null;
+
+ public static void init(){
@@ -162,16 +161,11 @@ index 0000000000000000000000000000000000000000..6a9919d8aec5e49df0dd13380cc7d879
+ }
+
+ public static boolean isPlayerVisible(Player player){
+ return !visibleExclude.contains(player.getUniqueId());
+ return ((CraftPlayer) player).getHandle().isTpsBarVisible;
+ }
+
+ public static void setVisibilityForPlayer(Player target,boolean canSee){
+ if (!canSee){
+ visibleExclude.add(target.getUniqueId());
+ return;
+ }
+
+ visibleExclude.remove(target.getUniqueId());
+ ((CraftPlayer) target).getHandle().isTpsBarVisible = canSee;
+ }
+
+ private static void update(){
@@ -201,7 +195,7 @@ index 0000000000000000000000000000000000000000..6a9919d8aec5e49df0dd13380cc7d879
+ if (removed != null){
+ final Player targetPlayer = Bukkit.getPlayer(uuid);
+ if (targetPlayer != null){
+ targetPlayer.showBossBar(removed);
+ targetPlayer.hideBossBar(removed);
+ }
+ }
+ }
@@ -220,7 +214,7 @@ index 0000000000000000000000000000000000000000..6a9919d8aec5e49df0dd13380cc7d879
+
+ BossBar targetBossbar = uuid2Bossbars.get(nmsPlayer.getUUID());
+
+ if (targetBossbar == null && !visibleExclude.contains(nmsPlayer.getUUID()) && isPlayerVisible(apiPlayer)){
+ if (targetBossbar == null && isPlayerVisible(apiPlayer)){
+ targetBossbar = BossBar.bossBar(Component.text(""),0.0F, BossBar.Color.valueOf(LuminolConfig.tpsColors[3]), BossBar.Overlay.NOTCHED_20);
+ uuid2Bossbars.put(nmsPlayer.getUUID(),targetBossbar);
+ apiPlayer.showBossBar(targetBossbar);
@@ -358,3 +352,41 @@ index f0bf57a7acd77eeffbeeb6743ba58166823022fd..4a1e068c27853a38db0641806626e7ac
super.stopServer();
//Util.shutdownExecutors(); // Paper - moved into super
SkullBlockEntity.clear();
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
index 97bfb92e52c3c5ef1cd22afe2b97c204eb45025a..d7a280427442bac8cc8ccb542d24d4e0901df70a 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -278,6 +278,7 @@ public class ServerPlayer extends Player {
// Paper start - replace player chunk loader
private final java.util.concurrent.atomic.AtomicReference<io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.ViewDistances> viewDistances = new java.util.concurrent.atomic.AtomicReference<>(new io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.ViewDistances(-1, -1, -1));
public io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.PlayerChunkLoaderData chunkLoader;
+ public volatile boolean isTpsBarVisible = false;
public io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.ViewDistances getViewDistances() {
return this.viewDistances.get();
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
index 6c8f6e26687b557fcdcd65c657d8b35d3fde805e..06c92a2d3ecb3b747c2303819f72c1c41967af8c 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -2216,6 +2216,10 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
handle.expToDrop = data.getInt("expToDrop");
handle.keepLevel = data.getBoolean("keepLevel");
}
+
+ //Luminol start - Tpsbar
+ getHandle().isTpsBarVisible = data.getBoolean("tpsbarVisible");
+ //Luminol end
}
}
@@ -2237,6 +2241,10 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
data.putLong("lastPlayed", System.currentTimeMillis());
data.putString("lastKnownName", handle.getScoreboardName());
+ //Luminol start - Tpsbar
+ data.putBoolean("tpsbarVisible",handle.isTpsBarVisible);
+ //Luminol end
+
// Paper start - persist for use in offline save data
if (!nbttagcompound.contains("Paper")) {
nbttagcompound.put("Paper", new CompoundTag());

View File

@@ -0,0 +1,237 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: M2ke4U <79621885+MrHua269@users.noreply.github.com>
Date: Sun, 26 Nov 2023 16:00:59 +0800
Subject: [PATCH] Pufferfish Improve fluid direction caching
diff --git a/src/main/java/gg/airplane/structs/FluidDirectionCache.java b/src/main/java/gg/airplane/structs/FluidDirectionCache.java
new file mode 100644
index 0000000000000000000000000000000000000000..aa8467b9dda1f7707e41f50ac7b3e9d7343723ec
--- /dev/null
+++ b/src/main/java/gg/airplane/structs/FluidDirectionCache.java
@@ -0,0 +1,136 @@
+package gg.airplane.structs;
+
+import it.unimi.dsi.fastutil.HashCommon;
+
+/**
+ * This is a replacement for the cache used in FluidTypeFlowing.
+ * The requirements for the previous cache were:
+ * - Store 200 entries
+ * - Look for the flag in the cache
+ * - If it exists, move to front of cache
+ * - If it doesn't exist, remove last entry in cache and insert in front
+ *
+ * This class accomplishes something similar, however has a few different
+ * requirements put into place to make this more optimize:
+ *
+ * - maxDistance is the most amount of entries to be checked, instead
+ * of having to check the entire list.
+ * - In combination with that, entries are all tracked by age and how
+ * frequently they're used. This enables us to remove old entries,
+ * without constantly shifting any around.
+ *
+ * Usage of the previous map would have to reset the head every single usage,
+ * shifting the entire map. Here, nothing happens except an increment when
+ * the cache is hit, and when it needs to replace an old element only a single
+ * element is modified.
+ */
+public class FluidDirectionCache<T> {
+
+ private static class FluidDirectionEntry<T> {
+ private final T data;
+ private final boolean flag;
+ private int uses = 0;
+ private int age = 0;
+
+ private FluidDirectionEntry(T data, boolean flag) {
+ this.data = data;
+ this.flag = flag;
+ }
+
+ public int getValue() {
+ return this.uses - (this.age >> 1); // age isn't as important as uses
+ }
+
+ public void incrementUses() {
+ this.uses = this.uses + 1 & Integer.MAX_VALUE;
+ }
+
+ public void incrementAge() {
+ this.age = this.age + 1 & Integer.MAX_VALUE;
+ }
+ }
+
+ private final FluidDirectionEntry[] entries;
+ private final int mask;
+ private final int maxDistance; // the most amount of entries to check for a value
+
+ public FluidDirectionCache(int size) {
+ int arraySize = HashCommon.nextPowerOfTwo(size);
+ this.entries = new FluidDirectionEntry[arraySize];
+ this.mask = arraySize - 1;
+ this.maxDistance = Math.min(arraySize, 4);
+ }
+
+ public Boolean getValue(T data) {
+ FluidDirectionEntry curr;
+ int pos;
+
+ if ((curr = this.entries[pos = HashCommon.mix(data.hashCode()) & this.mask]) == null) {
+ return null;
+ } else if (data.equals(curr.data)) {
+ curr.incrementUses();
+ return curr.flag;
+ }
+
+ int checked = 1; // start at 1 because we already checked the first spot above
+
+ while ((curr = this.entries[pos = (pos + 1) & this.mask]) != null) {
+ if (data.equals(curr.data)) {
+ curr.incrementUses();
+ return curr.flag;
+ } else if (++checked >= this.maxDistance) {
+ break;
+ }
+ }
+
+ return null;
+ }
+
+ public void putValue(T data, boolean flag) {
+ FluidDirectionEntry<T> curr;
+ int pos;
+
+ if ((curr = this.entries[pos = HashCommon.mix(data.hashCode()) & this.mask]) == null) {
+ this.entries[pos] = new FluidDirectionEntry<>(data, flag); // add
+ return;
+ } else if (data.equals(curr.data)) {
+ curr.incrementUses();
+ return;
+ }
+
+ int checked = 1; // start at 1 because we already checked the first spot above
+
+ while ((curr = this.entries[pos = (pos + 1) & this.mask]) != null) {
+ if (data.equals(curr.data)) {
+ curr.incrementUses();
+ return;
+ } else if (++checked >= this.maxDistance) {
+ this.forceAdd(data, flag);
+ return;
+ }
+ }
+
+ this.entries[pos] = new FluidDirectionEntry<>(data, flag); // add
+ }
+
+ private void forceAdd(T data, boolean flag) {
+ int expectedPos = HashCommon.mix(data.hashCode()) & this.mask;
+
+ int toRemovePos = expectedPos;
+ FluidDirectionEntry entryToRemove = this.entries[toRemovePos];
+
+ for (int i = expectedPos + 1; i < expectedPos + this.maxDistance; i++) {
+ int pos = i & this.mask;
+ FluidDirectionEntry entry = this.entries[pos];
+ if (entry.getValue() < entryToRemove.getValue()) {
+ toRemovePos = pos;
+ entryToRemove = entry;
+ }
+
+ entry.incrementAge(); // use this as a mechanism to age the other entries
+ }
+
+ // remove the least used/oldest entry
+ this.entries[toRemovePos] = new FluidDirectionEntry(data, flag);
+ }
+}
diff --git a/src/main/java/net/minecraft/world/level/material/FlowingFluid.java b/src/main/java/net/minecraft/world/level/material/FlowingFluid.java
index e21f4c5aff3a8e97101f6efc1349fbecf326b5ea..c55f51e6db55f9fa66f53eef0e7a56af5f81d742 100644
--- a/src/main/java/net/minecraft/world/level/material/FlowingFluid.java
+++ b/src/main/java/net/minecraft/world/level/material/FlowingFluid.java
@@ -45,6 +45,8 @@ public abstract class FlowingFluid extends Fluid {
public static final BooleanProperty FALLING = BlockStateProperties.FALLING;
public static final IntegerProperty LEVEL = BlockStateProperties.LEVEL_FLOWING;
private static final int CACHE_SIZE = 200;
+ // Pufferfish start - use our own cache
+ /*
private static final ThreadLocal<Object2ByteLinkedOpenHashMap<Block.BlockStatePairKey>> OCCLUSION_CACHE = ThreadLocal.withInitial(() -> {
Object2ByteLinkedOpenHashMap<Block.BlockStatePairKey> object2bytelinkedopenhashmap = new Object2ByteLinkedOpenHashMap<Block.BlockStatePairKey>(200) {
protected void rehash(int i) {}
@@ -53,6 +55,14 @@ public abstract class FlowingFluid extends Fluid {
object2bytelinkedopenhashmap.defaultReturnValue((byte) 127);
return object2bytelinkedopenhashmap;
});
+ */
+
+ private static final ThreadLocal<gg.airplane.structs.FluidDirectionCache<Block.BlockStatePairKey>> localFluidDirectionCache = ThreadLocal.withInitial(() -> {
+ // Pufferfish todo - mess with this number for performance
+ // with 2048 it seems very infrequent on a small world that it has to remove old entries
+ return new gg.airplane.structs.FluidDirectionCache<>(2048);
+ });
+ // Pufferfish end
private final Map<FluidState, VoxelShape> shapes = Maps.newIdentityHashMap();
public FlowingFluid() {}
@@ -252,6 +262,8 @@ public abstract class FlowingFluid extends Fluid {
return false;
}
// Paper end - optimise collisions
+ // Pufferfish start - modify to use our cache
+ /*
Object2ByteLinkedOpenHashMap object2bytelinkedopenhashmap;
if (!state.getBlock().hasDynamicShape() && !fromState.getBlock().hasDynamicShape()) {
@@ -259,9 +271,16 @@ public abstract class FlowingFluid extends Fluid {
} else {
object2bytelinkedopenhashmap = null;
}
+ */
+ gg.airplane.structs.FluidDirectionCache<Block.BlockStatePairKey> cache = null;
+
+ if (!state.getBlock().hasDynamicShape() && !fromState.getBlock().hasDynamicShape()) {
+ cache = localFluidDirectionCache.get();
+ }
Block.BlockStatePairKey block_a;
+ /*
if (object2bytelinkedopenhashmap != null) {
block_a = new Block.BlockStatePairKey(state, fromState, face);
byte b0 = object2bytelinkedopenhashmap.getAndMoveToFirst(block_a);
@@ -272,11 +291,22 @@ public abstract class FlowingFluid extends Fluid {
} else {
block_a = null;
}
+ */
+ if (cache != null) {
+ block_a = new Block.BlockStatePairKey(state, fromState, face);
+ Boolean flag = cache.getValue(block_a);
+ if (flag != null) {
+ return flag;
+ }
+ } else {
+ block_a = null;
+ }
VoxelShape voxelshape = state.getCollisionShape(world, pos);
VoxelShape voxelshape1 = fromState.getCollisionShape(world, fromPos);
boolean flag = !Shapes.mergedFaceOccludes(voxelshape, voxelshape1, face);
+ /*
if (object2bytelinkedopenhashmap != null) {
if (object2bytelinkedopenhashmap.size() == 200) {
object2bytelinkedopenhashmap.removeLastByte();
@@ -284,6 +314,11 @@ public abstract class FlowingFluid extends Fluid {
object2bytelinkedopenhashmap.putAndMoveToFirst(block_a, (byte) (flag ? 1 : 0));
}
+ */
+ if (cache != null) {
+ cache.putValue(block_a, flag);
+ }
+ // Pufferfish end
return flag;
}

File diff suppressed because it is too large Load Diff