Move around patches again

This commit is contained in:
Nassim Jahnke 2024-12-05 11:18:29 +01:00
parent da567b2d9a
commit 10cba26ae2
47 changed files with 403 additions and 382 deletions

View file

@ -16,28 +16,27 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ @Override
+ public Set<java.lang.Long> getSentChunkKeys() {
+ org.spigotmc.AsyncCatcher.catchOp("accessing sent chunks");
+ return it.unimi.dsi.fastutil.longs.LongSets.unmodifiable(
+ this.getHandle().moonrise$getChunkLoader().getSentChunksRaw().clone()
+ );
+ final it.unimi.dsi.fastutil.longs.LongOpenHashSet keys = new it.unimi.dsi.fastutil.longs.LongOpenHashSet();
+ this.getHandle().getChunkTrackingView().forEach(pos -> keys.add(pos.longKey));
+ return it.unimi.dsi.fastutil.longs.LongSets.unmodifiable(keys);
+ }
+
+ @Override
+ public Set<org.bukkit.Chunk> getSentChunks() {
+ org.spigotmc.AsyncCatcher.catchOp("accessing sent chunks");
+ final it.unimi.dsi.fastutil.longs.LongOpenHashSet rawChunkKeys = this.getHandle().moonrise$getChunkLoader().getSentChunksRaw();
+ final it.unimi.dsi.fastutil.objects.ObjectOpenHashSet<org.bukkit.Chunk> chunks = new it.unimi.dsi.fastutil.objects.ObjectOpenHashSet<>(rawChunkKeys.size());
+ final it.unimi.dsi.fastutil.objects.ObjectOpenHashSet<org.bukkit.Chunk> chunks = new it.unimi.dsi.fastutil.objects.ObjectOpenHashSet<>();
+ final org.bukkit.World world = this.getWorld();
+
+ final it.unimi.dsi.fastutil.longs.LongIterator iter = this.getHandle().moonrise$getChunkLoader().getSentChunksRaw().longIterator();
+ while (iter.hasNext()) chunks.add(world.getChunkAt(iter.nextLong(), false));
+
+ this.getHandle().getChunkTrackingView().forEach(pos -> {
+ final org.bukkit.Chunk chunk = world.getChunkAt(pos.longKey);
+ chunks.add(chunk);
+ });
+ return it.unimi.dsi.fastutil.objects.ObjectSets.unmodifiable(chunks);
+ }
+
+ @Override
+ public boolean isChunkSent(final long chunkKey) {
+ org.spigotmc.AsyncCatcher.catchOp("accessing sent chunks");
+ return this.getHandle().moonrise$getChunkLoader().getSentChunksRaw().contains(chunkKey);
+ return this.getHandle().getChunkTrackingView().contains(new net.minecraft.world.level.ChunkPos(chunkKey));
+ }
+ // Paper end
+

View file

@ -9,13 +9,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
public volatile Thread shutdownThread; // Paper
public volatile boolean abnormalExit = false; // Paper
public static final long SERVER_INIT = System.nanoTime(); // Paper - Lag compensation
// Spigot end
public final io.papermc.paper.configuration.PaperConfigurations paperConfigurations; // Paper - add paper configuration files
public boolean isIteratingOverLevels = false; // Paper - Throw exception on world create while being ticked
+ private final Set<String> pluginsBlockingSleep = new java.util.HashSet<>(); // Paper - API to allow/disallow tick sleeping
public static <S extends MinecraftServer> S spin(Function<Thread, S> serverFactory) {
ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.init(); // Paper - rewrite data converter system
AtomicReference<S> atomicreference = new AtomicReference();
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
long i = Util.getNanos();
int j = this.pauseWhileEmptySeconds() * 20;

View file

@ -20,8 +20,6 @@ Alternate Current needs the following modifications:
* RedStoneWireBlock: Replace calls to vanilla's or Eigencraft's methods for handling power changes with calls to
Alternate Current's wire handler.
Feature patch
diff --git a/src/main/java/alternate/current/wire/LevelHelper.java b/src/main/java/alternate/current/wire/LevelHelper.java
new file mode 100644
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000

View file

@ -23,7 +23,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+
public void setupCompression(int compressionThreshold, boolean rejectsBadPackets) {
if (compressionThreshold >= 0) {
com.velocitypowered.natives.compression.VelocityCompressor compressor = com.velocitypowered.natives.util.Natives.compress.get().create(io.papermc.paper.configuration.GlobalConfiguration.get().misc.compressionLevel.or(-1)); // Paper - Use Velocity cipher
ChannelHandler channelhandler = this.channel.pipeline().get("decompress");
diff --git a/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java

View file

@ -3,7 +3,6 @@ From: Bjarne Koll <git@lynxplay.dev>
Date: Thu, 13 Jun 2024 23:45:32 +0200
Subject: [PATCH] Add registry entry and builders
Feature patch
diff --git a/src/main/java/io/papermc/paper/registry/PaperRegistries.java b/src/main/java/io/papermc/paper/registry/PaperRegistries.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644

View file

@ -5,6 +5,9 @@ Subject: [PATCH] Add startup flag to disable gamerule limits
-DPaper.DisableGameRuleLimits=true will disable gamerule limits
== AT ==
public net.minecraft.server.level.ChunkLevel ENTITY_TICKING_LEVEL
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java

View file

@ -30,8 +30,6 @@ This fix also maintains compatability if someone switches server jars to one wit
this fix, as the data will remain in the oversized file. Once the server returns
to a jar with this fix, the data will be restored.
Feature patch
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java

View file

@ -12,7 +12,7 @@ diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/ma
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -0,0 +0,0 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple
@@ -0,0 +0,0 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player {
while (iterator.hasNext()) {
ThrownEnderpearl entityenderpearl = (ThrownEnderpearl) iterator.next();
@ -20,7 +20,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
if (entityenderpearl.isRemoved()) {
ServerPlayer.LOGGER.warn("Trying to save removed ender pearl, skipping");
@@ -0,0 +0,0 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple
@@ -0,0 +0,0 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player {
}
public static long placeEnderPearlTicket(ServerLevel world, ChunkPos chunkPos) {

View file

@ -3,7 +3,6 @@ From: stonar96 <minecraft.stonar96@gmail.com>
Date: Thu, 25 Nov 2021 13:27:51 +0100
Subject: [PATCH] Anti-Xray
Feature patch
diff --git a/src/main/java/com/destroystokyo/paper/antixray/BitStorageReader.java b/src/main/java/com/destroystokyo/paper/antixray/BitStorageReader.java
new file mode 100644

View file

@ -9,8 +9,6 @@ we instead drop the current regionfile header and recalculate -
hoping that at least then we don't swap chunks, and maybe recover
them all.
Feature patch
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/RegionBitmap.java b/src/main/java/net/minecraft/world/level/chunk/storage/RegionBitmap.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/chunk/storage/RegionBitmap.java

View file

@ -300,13 +300,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
this.server.waitForAsyncTasksShutdown(); // Paper - Wait for Async Tasks during shutdown
}
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
// tasks are default scheduled at -1 + delay, and first tick will tick at 1
final long actualDoneTimeMs = System.currentTimeMillis() - org.bukkit.craftbukkit.Main.BOOT_TIME.toEpochMilli(); // Paper - Add total time
LOGGER.info("Done ({})! For help, type \"help\"", String.format(java.util.Locale.ROOT, "%.3fs", actualDoneTimeMs / 1000.00D)); // Paper - Add total time
this.statusIcon = (ServerStatus.Favicon) this.loadStatusIcon().orElse(null); // CraftBukkit - decompile error
this.status = this.buildServerStatus();
+ this.server.spark.enableBeforePlugins(); // Paper - spark
org.spigotmc.WatchdogThread.tick();
// Paper end - Improved Watchdog Support
// Spigot start
org.spigotmc.WatchdogThread.hasStarted = true; // Paper
Arrays.fill( this.recentTps, 20 );
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
}

View file

@ -3,7 +3,6 @@ From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Mon, 2 Aug 2021 10:10:40 +0200
Subject: [PATCH] Check distance in entity interactions
Feature patch
diff --git a/src/main/java/net/minecraft/Util.java b/src/main/java/net/minecraft/Util.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644

View file

@ -6,8 +6,6 @@ Subject: [PATCH] Detail more information in watchdog dumps
- Dump position, world, velocity, and uuid for currently ticking entities
- Dump player name, player uuid, position, and world for packet handling
Feature patch
diff --git a/src/main/java/net/minecraft/network/Connection.java b/src/main/java/net/minecraft/network/Connection.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/network/Connection.java

View file

@ -17,8 +17,6 @@ A lot of this code is self-contained in a helper class.
Aside from making the obvious class/function renames and obfhelpers I didn't need to modify much.
Just added Bukkit's event system and took a few liberties with dead code and comment misspellings.
Feature patch
== AT ==
public net.minecraft.world.level.block.RedStoneWireBlock shouldSignal
public net.minecraft.world.level.block.RedStoneWireBlock canSurvive(Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/LevelReader;Lnet/minecraft/core/BlockPos;)Z

View file

@ -13,8 +13,6 @@ Adds water Mobs to activation range config and nerfs fish
Adds flying monsters to control ghast and phantoms
Adds villagers as separate config
Feature patch
== AT ==
public net.minecraft.world.entity.Entity isInsidePortal

View file

@ -28,8 +28,6 @@ which is most likely in an unloaded chunk - which means that the
client will not tick the entity and thus not lerp the entity
from its old position to its new position.
Feature patch
diff --git a/src/main/java/net/minecraft/network/protocol/game/ClientboundAddEntityPacket.java b/src/main/java/net/minecraft/network/protocol/game/ClientboundAddEntityPacket.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/network/protocol/game/ClientboundAddEntityPacket.java

View file

@ -9,8 +9,6 @@ when if this was fixed on the client, that wouldn't be needed.
Mojira Issue: https://bugs.mojang.com/browse/MC-235045
Feature patch
diff --git a/src/main/java/net/minecraft/commands/CommandSourceStack.java b/src/main/java/net/minecraft/commands/CommandSourceStack.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/commands/CommandSourceStack.java

View file

@ -18,8 +18,6 @@ public net.minecraft.world.level.levelgen.SurfaceRules$SurfaceRule
Co-authored-by: Noah van der Aa <ndvdaa@gmail.com>
Feature patch
diff --git a/src/main/java/io/papermc/paper/world/worldgen/OptionallyFlatBedrockConditionSource.java b/src/main/java/io/papermc/paper/world/worldgen/OptionallyFlatBedrockConditionSource.java
new file mode 100644
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000

View file

@ -6,8 +6,6 @@ Subject: [PATCH] Handle Oversized block entities in chunks
Splits out Extra Packets if too many TE's are encountered to prevent
creating too large of a packet to sed.
Feature patch
Co-authored-by: Spottedleaf <Spottedleaf@users.noreply.github.com>
diff --git a/src/main/java/net/minecraft/network/protocol/game/ClientboundLevelChunkPacketData.java b/src/main/java/net/minecraft/network/protocol/game/ClientboundLevelChunkPacketData.java

View file

@ -317,7 +317,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ public static EnumSet<GoalType> vanillaToPaper(Goal goal) {
+ EnumSet<GoalType> goals = EnumSet.noneOf(GoalType.class);
+ for (GoalType type : GoalType.values()) {
+ if (goal.getFlags().hasElement(paperToVanilla(type))) {
+ if (goal.hasFlag(paperToVanilla(type))) {
+ goals.add(type);
+ }
+ }
@ -423,7 +423,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+
+ this.setFlags(MobGoalHelper.paperToVanilla(handle.getTypes()));
+ if (this.getFlags().size() == 0) {
+ this.getFlags().addUnchecked(Flag.UNKNOWN_BEHAVIOR);
+ this.addFlag(Flag.UNKNOWN_BEHAVIOR);
+ }
+ }
+
@ -587,7 +587,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ CraftMob craftMob = (CraftMob) mob;
+ Set<Goal<T>> goals = new HashSet<>();
+ for (WrappedGoal item : getHandle(craftMob, type).getAvailableGoals()) {
+ if (!item.getGoal().getFlags().hasElement(MobGoalHelper.paperToVanilla(type))) {
+ if (!item.getGoal().hasFlag(MobGoalHelper.paperToVanilla(type))) {
+ continue;
+ }
+
@ -610,7 +610,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ continue;
+ }
+ for (WrappedGoal item : getHandle(craftMob, internalType).getAvailableGoals()) {
+ if (item.getGoal().getFlags().hasElement(MobGoalHelper.paperToVanilla(type))) {
+ if (item.getGoal().hasFlag(MobGoalHelper.paperToVanilla(type))) {
+ continue;
+ }
+
@ -640,7 +640,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ Set<Goal<T>> goals = new HashSet<>();
+ getHandle(craftMob, type).getAvailableGoals()
+ .stream().filter(WrappedGoal::isRunning)
+ .filter(item -> item.getGoal().getFlags().hasElement(MobGoalHelper.paperToVanilla(type)))
+ .filter(item -> item.getGoal().hasFlag(MobGoalHelper.paperToVanilla(type)))
+ .forEach(item -> {
+ if (item.getGoal() instanceof PaperCustomGoal) {
+ //noinspection unchecked
@ -663,7 +663,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ getHandle(craftMob, internalType).getAvailableGoals()
+ .stream()
+ .filter(WrappedGoal::isRunning)
+ .filter(item -> !item.getGoal().getFlags().hasElement(MobGoalHelper.paperToVanilla(type)))
+ .filter(item -> !item.getGoal().hasFlag(MobGoalHelper.paperToVanilla(type)))
+ .forEach(item -> {
+ if (item.getGoal() instanceof PaperCustomGoal) {
+ //noinspection unchecked
@ -763,6 +763,23 @@ diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/Goal.java b/src/ma
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/ai/goal/Goal.java
+++ b/src/main/java/net/minecraft/world/entity/ai/goal/Goal.java
@@ -0,0 +0,0 @@ public abstract class Goal {
return this.flags;
}
+ // Paper start - Mob Goal API
+ public boolean hasFlag(final Goal.Flag flag) {
+ return this.flags.contains(flag);
+ }
+
+ public void addFlag(final Goal.Flag flag) {
+ this.flags.add(flag);
+ }
+ // Paper end - Mob Goal API
+
protected int adjustedTickDelay(int ticks) {
return this.requiresUpdateEveryTick() ? ticks : reducedTickDelay(ticks);
}
@@ -0,0 +0,0 @@ public abstract class Goal {
return (ServerLevel)world;
}

View file

@ -0,0 +1,48 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Flo0 <flo.roma@web.de>
Date: Thu, 5 Dec 2024 12:15:07 +0100
Subject: [PATCH] Implement chunk view API
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
@Override
public Set<java.lang.Long> getSentChunkKeys() {
org.spigotmc.AsyncCatcher.catchOp("accessing sent chunks");
- final it.unimi.dsi.fastutil.longs.LongOpenHashSet keys = new it.unimi.dsi.fastutil.longs.LongOpenHashSet();
- this.getHandle().getChunkTrackingView().forEach(pos -> keys.add(pos.longKey));
- return it.unimi.dsi.fastutil.longs.LongSets.unmodifiable(keys);
+ return it.unimi.dsi.fastutil.longs.LongSets.unmodifiable(
+ this.getHandle().moonrise$getChunkLoader().getSentChunksRaw().clone()
+ );
}
@Override
public Set<org.bukkit.Chunk> getSentChunks() {
org.spigotmc.AsyncCatcher.catchOp("accessing sent chunks");
- final it.unimi.dsi.fastutil.objects.ObjectOpenHashSet<org.bukkit.Chunk> chunks = new it.unimi.dsi.fastutil.objects.ObjectOpenHashSet<>();
+ final it.unimi.dsi.fastutil.longs.LongOpenHashSet rawChunkKeys = this.getHandle().moonrise$getChunkLoader().getSentChunksRaw();
+ final it.unimi.dsi.fastutil.objects.ObjectOpenHashSet<org.bukkit.Chunk> chunks = new it.unimi.dsi.fastutil.objects.ObjectOpenHashSet<>(rawChunkKeys.size());
final org.bukkit.World world = this.getWorld();
- this.getHandle().getChunkTrackingView().forEach(pos -> {
- final org.bukkit.Chunk chunk = world.getChunkAt(pos.longKey);
- chunks.add(chunk);
- });
+
+ final it.unimi.dsi.fastutil.longs.LongIterator iter = this.getHandle().moonrise$getChunkLoader().getSentChunksRaw().longIterator();
+ while (iter.hasNext()) chunks.add(world.getChunkAt(iter.nextLong(), false));
+
return it.unimi.dsi.fastutil.objects.ObjectSets.unmodifiable(chunks);
}
@Override
public boolean isChunkSent(final long chunkKey) {
org.spigotmc.AsyncCatcher.catchOp("accessing sent chunks");
- return this.getHandle().getChunkTrackingView().contains(new net.minecraft.world.level.ChunkPos(chunkKey));
+ return this.getHandle().moonrise$getChunkLoader().getSentChunksRaw().contains(chunkKey);
}
// Paper end

View file

@ -12,8 +12,6 @@ custom renderers are in use, defaulting to the much simpler Vanilla system.
Additionally, numerous issues to player position tracking on maps has been fixed.
Feature patch
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java

View file

@ -6,8 +6,6 @@ Subject: [PATCH] Improve exact choice recipe ingredients
Fixes exact choices not working with recipe book clicks
and shapeless recipes.
Feature patch
== AT ==
public net.minecraft.world.item.ItemStackLinkedSet TYPE_AND_TAG

View file

@ -19,8 +19,6 @@ for each craft, that logic is run 9 times (hence the 64 * 9). The + 64 is from t
After this patch, the full iteration over all recipes checking for a match should run once for a full craft to find the
initial recipe match. Then that recipe will be checked first for all future recipe match checks.
Feature patch
diff --git a/src/main/java/net/minecraft/world/inventory/CraftingContainer.java b/src/main/java/net/minecraft/world/inventory/CraftingContainer.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/inventory/CraftingContainer.java

View file

@ -40,8 +40,6 @@ This is to ensure that if main isn't truely stuck, it's not manipulating state w
This also moves all plugins who register "delayed init" tasks to occur just before "Done" so they
are properly accounted for and wont trip watchdog on init.
Feature patch
diff --git a/src/main/java/com/destroystokyo/paper/Metrics.java b/src/main/java/com/destroystokyo/paper/Metrics.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/com/destroystokyo/paper/Metrics.java
@ -130,8 +128,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
// Spigot start
public static final int TPS = 20;
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
public final io.papermc.paper.configuration.PaperConfigurations paperConfigurations; // Paper - add paper configuration files
public boolean isIteratingOverLevels = false; // Paper - Throw exception on world create while being ticked
private final Set<String> pluginsBlockingSleep = new java.util.HashSet<>(); // Paper - API to allow/disallow tick sleeping
+ public volatile Thread shutdownThread; // Paper
+ public volatile boolean abnormalExit = false; // Paper
@ -191,8 +189,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
throw new IllegalStateException("Failed to initialize server");
}
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
this.status = this.buildServerStatus();
this.server.spark.enableBeforePlugins(); // Paper - spark
// Spigot start
+ // Paper start - Improved Watchdog Support
+ LOGGER.info("Running delayed init tasks");

View file

@ -3,7 +3,6 @@ From: Shane Freeder <theboyetronic@gmail.com>
Date: Sun, 9 Jun 2019 03:53:22 +0100
Subject: [PATCH] Incremental chunk and player saving
Feature patch
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644

View file

@ -60,10 +60,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+
+ final int dataVersion = data.get("DataVersion").getAsInt();
+ final int currentVersion = org.bukkit.craftbukkit.util.CraftMagicNumbers.INSTANCE.getDataVersion();
+ data = ca.spottedleaf.dataconverter.minecraft.MCDataConverter.convertJson(
+ ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.ITEM_STACK,
+ data, false, dataVersion, currentVersion
+ );
+ data = (com.google.gson.JsonObject) MinecraftServer.getServer().fixerUpper.update(References.ITEM_STACK, new Dynamic<>(com.mojang.serialization.JsonOps.INSTANCE, data), dataVersion, currentVersion).getValue();
+ com.mojang.serialization.DynamicOps<com.google.gson.JsonElement> ops = MinecraftServer.getServer().registryAccess().createSerializationContext(com.mojang.serialization.JsonOps.INSTANCE);
+ return CraftItemStack.asCraftMirror(net.minecraft.world.item.ItemStack.CODEC.parse(ops, data).getOrThrow(IllegalArgumentException::new));
+ }

View file

@ -7,8 +7,6 @@ Areas affected by lag comepnsation:
- Block breaking and destroying
- Eating food items
Feature patch
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java

View file

@ -2597,285 +2597,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ ((Runnable)TO_RUN_HANDLE.getVolatile(this)).run();
+ }
+}
diff --git a/src/main/java/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java b/src/main/java/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java
new file mode 100644
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
--- /dev/null
+++ b/src/main/java/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java
@@ -0,0 +0,0 @@
+package ca.spottedleaf.moonrise.common.misc;
+
+import ca.spottedleaf.moonrise.common.list.ReferenceList;
+import ca.spottedleaf.moonrise.common.util.CoordinateUtils;
+import ca.spottedleaf.moonrise.common.util.MoonriseConstants;
+import ca.spottedleaf.moonrise.common.util.ChunkSystem;
+import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevel;
+import ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkData;
+import ca.spottedleaf.moonrise.patches.chunk_tick_iteration.ChunkTickConstants;
+import ca.spottedleaf.moonrise.patches.chunk_tick_iteration.ChunkTickServerLevel;
+import it.unimi.dsi.fastutil.longs.Long2ReferenceOpenHashMap;
+import it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap;
+import net.minecraft.core.BlockPos;
+import net.minecraft.server.level.ServerLevel;
+import net.minecraft.server.level.ServerPlayer;
+import net.minecraft.world.level.ChunkPos;
+import java.util.ArrayList;
+
+public final class NearbyPlayers {
+
+ public static enum NearbyMapType {
+ GENERAL,
+ GENERAL_SMALL,
+ GENERAL_REALLY_SMALL,
+ TICK_VIEW_DISTANCE,
+ VIEW_DISTANCE,
+ // Moonrise start - chunk tick iteration
+ SPAWN_RANGE {
+ @Override
+ void addTo(final ServerPlayer player, final ServerLevel world, final int chunkX, final int chunkZ) {
+ ((ChunkTickServerLevel)world).moonrise$addPlayerTickingRequest(chunkX, chunkZ);
+ }
+
+ @Override
+ void removeFrom(final ServerPlayer player, final ServerLevel world, final int chunkX, final int chunkZ) {
+ ((ChunkTickServerLevel)world).moonrise$removePlayerTickingRequest(chunkX, chunkZ);
+ }
+ };
+ // Moonrise end - chunk tick iteration
+
+ void addTo(final ServerPlayer player, final ServerLevel world, final int chunkX, final int chunkZ) {
+
+ }
+
+ void removeFrom(final ServerPlayer player, final ServerLevel world, final int chunkX, final int chunkZ) {
+
+ }
+ }
+
+ private static final NearbyMapType[] MAP_TYPES = NearbyMapType.values();
+ public static final int TOTAL_MAP_TYPES = MAP_TYPES.length;
+
+ private static final int GENERAL_AREA_VIEW_DISTANCE = MoonriseConstants.MAX_VIEW_DISTANCE + 1;
+ private static final int GENERAL_SMALL_VIEW_DISTANCE = 10;
+ private static final int GENERAL_REALLY_SMALL_VIEW_DISTANCE = 3;
+
+ public static final int GENERAL_AREA_VIEW_DISTANCE_BLOCKS = (GENERAL_AREA_VIEW_DISTANCE << 4);
+ public static final int GENERAL_SMALL_AREA_VIEW_DISTANCE_BLOCKS = (GENERAL_SMALL_VIEW_DISTANCE << 4);
+ public static final int GENERAL_REALLY_SMALL_AREA_VIEW_DISTANCE_BLOCKS = (GENERAL_REALLY_SMALL_VIEW_DISTANCE << 4);
+
+ private final ServerLevel world;
+ private final Reference2ReferenceOpenHashMap<ServerPlayer, TrackedPlayer[]> players = new Reference2ReferenceOpenHashMap<>();
+ private final Long2ReferenceOpenHashMap<TrackedChunk> byChunk = new Long2ReferenceOpenHashMap<>();
+ private final Long2ReferenceOpenHashMap<ReferenceList<ServerPlayer>>[] directByChunk = new Long2ReferenceOpenHashMap[TOTAL_MAP_TYPES];
+ {
+ for (int i = 0; i < this.directByChunk.length; ++i) {
+ this.directByChunk[i] = new Long2ReferenceOpenHashMap<>();
+ }
+ }
+
+ public NearbyPlayers(final ServerLevel world) {
+ this.world = world;
+ }
+
+ public void addPlayer(final ServerPlayer player) {
+ final TrackedPlayer[] newTrackers = new TrackedPlayer[TOTAL_MAP_TYPES];
+ if (this.players.putIfAbsent(player, newTrackers) != null) {
+ throw new IllegalStateException("Already have player " + player);
+ }
+
+ final ChunkPos chunk = player.chunkPosition();
+
+ for (int i = 0; i < TOTAL_MAP_TYPES; ++i) {
+ // use 0 for default, will be updated by tickPlayer
+ (newTrackers[i] = new TrackedPlayer(player, MAP_TYPES[i])).add(chunk.x, chunk.z, 0);
+ }
+
+ // update view distances
+ this.tickPlayer(player);
+ }
+
+ public void removePlayer(final ServerPlayer player) {
+ final TrackedPlayer[] players = this.players.remove(player);
+ if (players == null) {
+ return; // May be called during teleportation before the player is actually placed
+ }
+
+ for (final TrackedPlayer tracker : players) {
+ tracker.remove();
+ }
+ }
+
+ public void clear() {
+ if (this.players.isEmpty()) {
+ return;
+ }
+
+ for (final ServerPlayer player : new ArrayList<>(this.players.keySet())) {
+ this.removePlayer(player);
+ }
+ }
+
+ public void tickPlayer(final ServerPlayer player) {
+ final TrackedPlayer[] players = this.players.get(player);
+ if (players == null) {
+ throw new IllegalStateException("Don't have player " + player);
+ }
+
+ final ChunkPos chunk = player.chunkPosition();
+
+ players[NearbyMapType.GENERAL.ordinal()].update(chunk.x, chunk.z, GENERAL_AREA_VIEW_DISTANCE);
+ players[NearbyMapType.GENERAL_SMALL.ordinal()].update(chunk.x, chunk.z, GENERAL_SMALL_VIEW_DISTANCE);
+ players[NearbyMapType.GENERAL_REALLY_SMALL.ordinal()].update(chunk.x, chunk.z, GENERAL_REALLY_SMALL_VIEW_DISTANCE);
+ players[NearbyMapType.TICK_VIEW_DISTANCE.ordinal()].update(chunk.x, chunk.z, ChunkSystem.getTickViewDistance(player));
+ players[NearbyMapType.VIEW_DISTANCE.ordinal()].update(chunk.x, chunk.z, ChunkSystem.getViewDistance(player));
+ players[NearbyMapType.SPAWN_RANGE.ordinal()].update(chunk.x, chunk.z, ChunkTickConstants.PLAYER_SPAWN_TRACK_RANGE); // Moonrise - chunk tick iteration
+ }
+
+ public TrackedChunk getChunk(final ChunkPos pos) {
+ return this.byChunk.get(CoordinateUtils.getChunkKey(pos));
+ }
+
+ public TrackedChunk getChunk(final BlockPos pos) {
+ return this.byChunk.get(CoordinateUtils.getChunkKey(pos));
+ }
+
+ public TrackedChunk getChunk(final int chunkX, final int chunkZ) {
+ return this.byChunk.get(CoordinateUtils.getChunkKey(chunkX, chunkZ));
+ }
+
+ public ReferenceList<ServerPlayer> getPlayers(final BlockPos pos, final NearbyMapType type) {
+ return this.directByChunk[type.ordinal()].get(CoordinateUtils.getChunkKey(pos));
+ }
+
+ public ReferenceList<ServerPlayer> getPlayers(final ChunkPos pos, final NearbyMapType type) {
+ return this.directByChunk[type.ordinal()].get(CoordinateUtils.getChunkKey(pos));
+ }
+
+ public ReferenceList<ServerPlayer> getPlayersByChunk(final int chunkX, final int chunkZ, final NearbyMapType type) {
+ return this.directByChunk[type.ordinal()].get(CoordinateUtils.getChunkKey(chunkX, chunkZ));
+ }
+
+ public ReferenceList<ServerPlayer> getPlayersByBlock(final int blockX, final int blockZ, final NearbyMapType type) {
+ return this.directByChunk[type.ordinal()].get(CoordinateUtils.getChunkKey(blockX >> 4, blockZ >> 4));
+ }
+
+ public static final class TrackedChunk {
+
+ private static final ServerPlayer[] EMPTY_PLAYERS_ARRAY = new ServerPlayer[0];
+
+ private final long chunkKey;
+ private final NearbyPlayers nearbyPlayers;
+ private final ReferenceList<ServerPlayer>[] players = new ReferenceList[TOTAL_MAP_TYPES];
+ private int nonEmptyLists;
+ private long updateCount;
+
+ public TrackedChunk(final long chunkKey, final NearbyPlayers nearbyPlayers) {
+ this.chunkKey = chunkKey;
+ this.nearbyPlayers = nearbyPlayers;
+ }
+
+ public boolean isEmpty() {
+ return this.nonEmptyLists == 0;
+ }
+
+ public long getUpdateCount() {
+ return this.updateCount;
+ }
+
+ public ReferenceList<ServerPlayer> getPlayers(final NearbyMapType type) {
+ return this.players[type.ordinal()];
+ }
+
+ public void addPlayer(final ServerPlayer player, final NearbyMapType type) {
+ ++this.updateCount;
+
+ final int idx = type.ordinal();
+ final ReferenceList<ServerPlayer> list = this.players[idx];
+ if (list == null) {
+ ++this.nonEmptyLists;
+ final ReferenceList<ServerPlayer> players = (this.players[idx] = new ReferenceList<>(EMPTY_PLAYERS_ARRAY));
+ this.nearbyPlayers.directByChunk[idx].put(this.chunkKey, players);
+ players.add(player);
+ return;
+ }
+
+ if (!list.add(player)) {
+ throw new IllegalStateException("Already contains player " + player);
+ }
+ }
+
+ public void removePlayer(final ServerPlayer player, final NearbyMapType type) {
+ ++this.updateCount;
+
+ final int idx = type.ordinal();
+ final ReferenceList<ServerPlayer> list = this.players[idx];
+ if (list == null) {
+ throw new IllegalStateException("Does not contain player " + player);
+ }
+
+ if (!list.remove(player)) {
+ throw new IllegalStateException("Does not contain player " + player);
+ }
+
+ if (list.size() == 0) {
+ this.players[idx] = null;
+ this.nearbyPlayers.directByChunk[idx].remove(this.chunkKey);
+ --this.nonEmptyLists;
+ }
+ }
+ }
+
+ private final class TrackedPlayer extends SingleUserAreaMap<ServerPlayer> {
+
+ private final NearbyMapType type;
+
+ public TrackedPlayer(final ServerPlayer player, final NearbyMapType type) {
+ super(player);
+ this.type = type;
+ }
+
+ @Override
+ protected void addCallback(final ServerPlayer parameter, final int chunkX, final int chunkZ) {
+ final long chunkKey = CoordinateUtils.getChunkKey(chunkX, chunkZ);
+
+ final TrackedChunk chunk = NearbyPlayers.this.byChunk.get(chunkKey);
+ final NearbyMapType type = this.type;
+ if (chunk != null) {
+ chunk.addPlayer(parameter, type);
+ type.addTo(parameter, NearbyPlayers.this.world, chunkX, chunkZ);
+ } else {
+ final TrackedChunk created = new TrackedChunk(chunkKey, NearbyPlayers.this);
+ NearbyPlayers.this.byChunk.put(chunkKey, created);
+ created.addPlayer(parameter, type);
+ type.addTo(parameter, NearbyPlayers.this.world, chunkX, chunkZ);
+
+ ((ChunkSystemLevel)NearbyPlayers.this.world).moonrise$requestChunkData(chunkKey).nearbyPlayers = created;
+ }
+ }
+
+ @Override
+ protected void removeCallback(final ServerPlayer parameter, final int chunkX, final int chunkZ) {
+ final long chunkKey = CoordinateUtils.getChunkKey(chunkX, chunkZ);
+
+ final TrackedChunk chunk = NearbyPlayers.this.byChunk.get(chunkKey);
+ if (chunk == null) {
+ throw new IllegalStateException("Chunk should exist at " + new ChunkPos(chunkKey));
+ }
+
+ final NearbyMapType type = this.type;
+ chunk.removePlayer(parameter, type);
+ type.removeFrom(parameter, NearbyPlayers.this.world, chunkX, chunkZ);
+
+ if (chunk.isEmpty()) {
+ NearbyPlayers.this.byChunk.remove(chunkKey);
+ final ChunkData chunkData = ((ChunkSystemLevel)NearbyPlayers.this.world).moonrise$releaseChunkData(chunkKey);
+ if (chunkData != null) {
+ chunkData.nearbyPlayers = null;
+ }
+ }
+ }
+ }
+}
diff --git a/src/main/java/ca/spottedleaf/moonrise/common/misc/PositionCountingAreaMap.java b/src/main/java/ca/spottedleaf/moonrise/common/misc/PositionCountingAreaMap.java
new file mode 100644
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000

View file

@ -17,6 +17,285 @@ Currently includes:
See https://github.com/Tuinity/Moonrise
diff --git a/src/main/java/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java b/src/main/java/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java
new file mode 100644
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
--- /dev/null
+++ b/src/main/java/ca/spottedleaf/moonrise/common/misc/NearbyPlayers.java
@@ -0,0 +0,0 @@
+package ca.spottedleaf.moonrise.common.misc;
+
+import ca.spottedleaf.moonrise.common.list.ReferenceList;
+import ca.spottedleaf.moonrise.common.util.CoordinateUtils;
+import ca.spottedleaf.moonrise.common.util.MoonriseConstants;
+import ca.spottedleaf.moonrise.common.util.ChunkSystem;
+import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevel;
+import ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkData;
+import ca.spottedleaf.moonrise.patches.chunk_tick_iteration.ChunkTickConstants;
+import ca.spottedleaf.moonrise.patches.chunk_tick_iteration.ChunkTickServerLevel;
+import it.unimi.dsi.fastutil.longs.Long2ReferenceOpenHashMap;
+import it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap;
+import net.minecraft.core.BlockPos;
+import net.minecraft.server.level.ServerLevel;
+import net.minecraft.server.level.ServerPlayer;
+import net.minecraft.world.level.ChunkPos;
+import java.util.ArrayList;
+
+public final class NearbyPlayers {
+
+ public static enum NearbyMapType {
+ GENERAL,
+ GENERAL_SMALL,
+ GENERAL_REALLY_SMALL,
+ TICK_VIEW_DISTANCE,
+ VIEW_DISTANCE,
+ // Moonrise start - chunk tick iteration
+ SPAWN_RANGE {
+ @Override
+ void addTo(final ServerPlayer player, final ServerLevel world, final int chunkX, final int chunkZ) {
+ ((ChunkTickServerLevel)world).moonrise$addPlayerTickingRequest(chunkX, chunkZ);
+ }
+
+ @Override
+ void removeFrom(final ServerPlayer player, final ServerLevel world, final int chunkX, final int chunkZ) {
+ ((ChunkTickServerLevel)world).moonrise$removePlayerTickingRequest(chunkX, chunkZ);
+ }
+ };
+ // Moonrise end - chunk tick iteration
+
+ void addTo(final ServerPlayer player, final ServerLevel world, final int chunkX, final int chunkZ) {
+
+ }
+
+ void removeFrom(final ServerPlayer player, final ServerLevel world, final int chunkX, final int chunkZ) {
+
+ }
+ }
+
+ private static final NearbyMapType[] MAP_TYPES = NearbyMapType.values();
+ public static final int TOTAL_MAP_TYPES = MAP_TYPES.length;
+
+ private static final int GENERAL_AREA_VIEW_DISTANCE = MoonriseConstants.MAX_VIEW_DISTANCE + 1;
+ private static final int GENERAL_SMALL_VIEW_DISTANCE = 10;
+ private static final int GENERAL_REALLY_SMALL_VIEW_DISTANCE = 3;
+
+ public static final int GENERAL_AREA_VIEW_DISTANCE_BLOCKS = (GENERAL_AREA_VIEW_DISTANCE << 4);
+ public static final int GENERAL_SMALL_AREA_VIEW_DISTANCE_BLOCKS = (GENERAL_SMALL_VIEW_DISTANCE << 4);
+ public static final int GENERAL_REALLY_SMALL_AREA_VIEW_DISTANCE_BLOCKS = (GENERAL_REALLY_SMALL_VIEW_DISTANCE << 4);
+
+ private final ServerLevel world;
+ private final Reference2ReferenceOpenHashMap<ServerPlayer, TrackedPlayer[]> players = new Reference2ReferenceOpenHashMap<>();
+ private final Long2ReferenceOpenHashMap<TrackedChunk> byChunk = new Long2ReferenceOpenHashMap<>();
+ private final Long2ReferenceOpenHashMap<ReferenceList<ServerPlayer>>[] directByChunk = new Long2ReferenceOpenHashMap[TOTAL_MAP_TYPES];
+ {
+ for (int i = 0; i < this.directByChunk.length; ++i) {
+ this.directByChunk[i] = new Long2ReferenceOpenHashMap<>();
+ }
+ }
+
+ public NearbyPlayers(final ServerLevel world) {
+ this.world = world;
+ }
+
+ public void addPlayer(final ServerPlayer player) {
+ final TrackedPlayer[] newTrackers = new TrackedPlayer[TOTAL_MAP_TYPES];
+ if (this.players.putIfAbsent(player, newTrackers) != null) {
+ throw new IllegalStateException("Already have player " + player);
+ }
+
+ final ChunkPos chunk = player.chunkPosition();
+
+ for (int i = 0; i < TOTAL_MAP_TYPES; ++i) {
+ // use 0 for default, will be updated by tickPlayer
+ (newTrackers[i] = new TrackedPlayer(player, MAP_TYPES[i])).add(chunk.x, chunk.z, 0);
+ }
+
+ // update view distances
+ this.tickPlayer(player);
+ }
+
+ public void removePlayer(final ServerPlayer player) {
+ final TrackedPlayer[] players = this.players.remove(player);
+ if (players == null) {
+ return; // May be called during teleportation before the player is actually placed
+ }
+
+ for (final TrackedPlayer tracker : players) {
+ tracker.remove();
+ }
+ }
+
+ public void clear() {
+ if (this.players.isEmpty()) {
+ return;
+ }
+
+ for (final ServerPlayer player : new ArrayList<>(this.players.keySet())) {
+ this.removePlayer(player);
+ }
+ }
+
+ public void tickPlayer(final ServerPlayer player) {
+ final TrackedPlayer[] players = this.players.get(player);
+ if (players == null) {
+ throw new IllegalStateException("Don't have player " + player);
+ }
+
+ final ChunkPos chunk = player.chunkPosition();
+
+ players[NearbyMapType.GENERAL.ordinal()].update(chunk.x, chunk.z, GENERAL_AREA_VIEW_DISTANCE);
+ players[NearbyMapType.GENERAL_SMALL.ordinal()].update(chunk.x, chunk.z, GENERAL_SMALL_VIEW_DISTANCE);
+ players[NearbyMapType.GENERAL_REALLY_SMALL.ordinal()].update(chunk.x, chunk.z, GENERAL_REALLY_SMALL_VIEW_DISTANCE);
+ players[NearbyMapType.TICK_VIEW_DISTANCE.ordinal()].update(chunk.x, chunk.z, ChunkSystem.getTickViewDistance(player));
+ players[NearbyMapType.VIEW_DISTANCE.ordinal()].update(chunk.x, chunk.z, ChunkSystem.getViewDistance(player));
+ players[NearbyMapType.SPAWN_RANGE.ordinal()].update(chunk.x, chunk.z, ChunkTickConstants.PLAYER_SPAWN_TRACK_RANGE); // Moonrise - chunk tick iteration
+ }
+
+ public TrackedChunk getChunk(final ChunkPos pos) {
+ return this.byChunk.get(CoordinateUtils.getChunkKey(pos));
+ }
+
+ public TrackedChunk getChunk(final BlockPos pos) {
+ return this.byChunk.get(CoordinateUtils.getChunkKey(pos));
+ }
+
+ public TrackedChunk getChunk(final int chunkX, final int chunkZ) {
+ return this.byChunk.get(CoordinateUtils.getChunkKey(chunkX, chunkZ));
+ }
+
+ public ReferenceList<ServerPlayer> getPlayers(final BlockPos pos, final NearbyMapType type) {
+ return this.directByChunk[type.ordinal()].get(CoordinateUtils.getChunkKey(pos));
+ }
+
+ public ReferenceList<ServerPlayer> getPlayers(final ChunkPos pos, final NearbyMapType type) {
+ return this.directByChunk[type.ordinal()].get(CoordinateUtils.getChunkKey(pos));
+ }
+
+ public ReferenceList<ServerPlayer> getPlayersByChunk(final int chunkX, final int chunkZ, final NearbyMapType type) {
+ return this.directByChunk[type.ordinal()].get(CoordinateUtils.getChunkKey(chunkX, chunkZ));
+ }
+
+ public ReferenceList<ServerPlayer> getPlayersByBlock(final int blockX, final int blockZ, final NearbyMapType type) {
+ return this.directByChunk[type.ordinal()].get(CoordinateUtils.getChunkKey(blockX >> 4, blockZ >> 4));
+ }
+
+ public static final class TrackedChunk {
+
+ private static final ServerPlayer[] EMPTY_PLAYERS_ARRAY = new ServerPlayer[0];
+
+ private final long chunkKey;
+ private final NearbyPlayers nearbyPlayers;
+ private final ReferenceList<ServerPlayer>[] players = new ReferenceList[TOTAL_MAP_TYPES];
+ private int nonEmptyLists;
+ private long updateCount;
+
+ public TrackedChunk(final long chunkKey, final NearbyPlayers nearbyPlayers) {
+ this.chunkKey = chunkKey;
+ this.nearbyPlayers = nearbyPlayers;
+ }
+
+ public boolean isEmpty() {
+ return this.nonEmptyLists == 0;
+ }
+
+ public long getUpdateCount() {
+ return this.updateCount;
+ }
+
+ public ReferenceList<ServerPlayer> getPlayers(final NearbyMapType type) {
+ return this.players[type.ordinal()];
+ }
+
+ public void addPlayer(final ServerPlayer player, final NearbyMapType type) {
+ ++this.updateCount;
+
+ final int idx = type.ordinal();
+ final ReferenceList<ServerPlayer> list = this.players[idx];
+ if (list == null) {
+ ++this.nonEmptyLists;
+ final ReferenceList<ServerPlayer> players = (this.players[idx] = new ReferenceList<>(EMPTY_PLAYERS_ARRAY));
+ this.nearbyPlayers.directByChunk[idx].put(this.chunkKey, players);
+ players.add(player);
+ return;
+ }
+
+ if (!list.add(player)) {
+ throw new IllegalStateException("Already contains player " + player);
+ }
+ }
+
+ public void removePlayer(final ServerPlayer player, final NearbyMapType type) {
+ ++this.updateCount;
+
+ final int idx = type.ordinal();
+ final ReferenceList<ServerPlayer> list = this.players[idx];
+ if (list == null) {
+ throw new IllegalStateException("Does not contain player " + player);
+ }
+
+ if (!list.remove(player)) {
+ throw new IllegalStateException("Does not contain player " + player);
+ }
+
+ if (list.size() == 0) {
+ this.players[idx] = null;
+ this.nearbyPlayers.directByChunk[idx].remove(this.chunkKey);
+ --this.nonEmptyLists;
+ }
+ }
+ }
+
+ private final class TrackedPlayer extends SingleUserAreaMap<ServerPlayer> {
+
+ private final NearbyMapType type;
+
+ public TrackedPlayer(final ServerPlayer player, final NearbyMapType type) {
+ super(player);
+ this.type = type;
+ }
+
+ @Override
+ protected void addCallback(final ServerPlayer parameter, final int chunkX, final int chunkZ) {
+ final long chunkKey = CoordinateUtils.getChunkKey(chunkX, chunkZ);
+
+ final TrackedChunk chunk = NearbyPlayers.this.byChunk.get(chunkKey);
+ final NearbyMapType type = this.type;
+ if (chunk != null) {
+ chunk.addPlayer(parameter, type);
+ type.addTo(parameter, NearbyPlayers.this.world, chunkX, chunkZ);
+ } else {
+ final TrackedChunk created = new TrackedChunk(chunkKey, NearbyPlayers.this);
+ NearbyPlayers.this.byChunk.put(chunkKey, created);
+ created.addPlayer(parameter, type);
+ type.addTo(parameter, NearbyPlayers.this.world, chunkX, chunkZ);
+
+ ((ChunkSystemLevel)NearbyPlayers.this.world).moonrise$requestChunkData(chunkKey).nearbyPlayers = created;
+ }
+ }
+
+ @Override
+ protected void removeCallback(final ServerPlayer parameter, final int chunkX, final int chunkZ) {
+ final long chunkKey = CoordinateUtils.getChunkKey(chunkX, chunkZ);
+
+ final TrackedChunk chunk = NearbyPlayers.this.byChunk.get(chunkKey);
+ if (chunk == null) {
+ throw new IllegalStateException("Chunk should exist at " + new ChunkPos(chunkKey));
+ }
+
+ final NearbyMapType type = this.type;
+ chunk.removePlayer(parameter, type);
+ type.removeFrom(parameter, NearbyPlayers.this.world, chunkX, chunkZ);
+
+ if (chunk.isEmpty()) {
+ NearbyPlayers.this.byChunk.remove(chunkKey);
+ final ChunkData chunkData = ((ChunkSystemLevel)NearbyPlayers.this.world).moonrise$releaseChunkData(chunkKey);
+ if (chunkData != null) {
+ chunkData.nearbyPlayers = null;
+ }
+ }
+ }
+ }
+}
diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/ChunkSystem.java b/src/main/java/ca/spottedleaf/moonrise/common/util/ChunkSystem.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/ca/spottedleaf/moonrise/common/util/ChunkSystem.java
@ -23847,13 +24126,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public class ChunkLevel {
- private static final int FULL_CHUNK_LEVEL = 33;
- private static final int BLOCK_TICKING_LEVEL = 32;
- private static final int ENTITY_TICKING_LEVEL = 31;
+ public static final int FULL_CHUNK_LEVEL = 33;
+ public static final int BLOCK_TICKING_LEVEL = 32;
+ public static final int ENTITY_TICKING_LEVEL = 31;
public static final int ENTITY_TICKING_LEVEL = 31;
private static final ChunkStep FULL_CHUNK_STEP = ChunkPyramid.GENERATION_PYRAMID.getStepTo(ChunkStatus.FULL);
public static final int RADIUS_AROUND_FULL_CHUNK = FULL_CHUNK_STEP.accumulatedDependencies().getRadius();
public static final int MAX_LEVEL = 33 + RADIUS_AROUND_FULL_CHUNK;
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java

View file

@ -5,8 +5,6 @@ Subject: [PATCH] Optimise collision checking in player move packet handling
Move collision logic to just the hasNewCollision call instead of getCubes + hasNewCollision
Feature patch
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java

View file

@ -30,8 +30,6 @@ This patch also specifically optimises other areas of code to
use PoiAccess. For example, some villager AI and portaling code
had to be specifically modified.
Feature patch
diff --git a/src/main/java/io/papermc/paper/util/PoiAccess.java b/src/main/java/io/papermc/paper/util/PoiAccess.java
new file mode 100644
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000

View file

@ -6,8 +6,6 @@ Subject: [PATCH] Optimize Bit Operations by inlining
Inline bit operations and reduce instruction count to make these hot
operations faster
Feature patch
diff --git a/src/main/java/net/minecraft/core/BlockPos.java b/src/main/java/net/minecraft/core/BlockPos.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/core/BlockPos.java

View file

@ -13,8 +13,6 @@ If that serting is not enabled, collisions will be ignored for players, since
movement will load only the chunk the player enters anyways and avoids loading
massive amounts of surrounding chunks due to large AABB lookups.
Feature patch
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java

View file

@ -6,8 +6,6 @@ Subject: [PATCH] Optimize GoalSelector Goal.Flag Set operations
Optimise the stream.anyMatch statement to move to a bitset
where we can replace the call with a single bitwise operation.
Feature patch
diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/Goal.java b/src/main/java/net/minecraft/world/entity/ai/goal/Goal.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/ai/goal/Goal.java
@ -58,7 +56,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ // Paper end - remove streams from pathfindergoalselector
}
protected int adjustedTickDelay(int ticks) {
// Paper start - Mob Goal API
public boolean hasFlag(final Goal.Flag flag) {
- return this.flags.contains(flag);
+ return this.goalTypes.hasElement(flag);
}
public void addFlag(final Goal.Flag flag) {
- this.flags.add(flag);
+ this.goalTypes.addUnchecked(flag);
}
// Paper end - Mob Goal API
diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java b/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/ai/goal/GoalSelector.java

View file

@ -12,8 +12,6 @@ Subject: [PATCH] Optimize Hoppers
* Don't check for Entities with Inventories if the block above us is also occluding (not just Inventoried)
* Remove Streams from Item Suck In and restore restore 1.12 AABB checks which is simpler and no voxel allocations (was doing TWO Item Suck ins)
Feature patch
diff --git a/src/main/java/io/papermc/paper/event/inventory/PaperInventoryMoveItemEvent.java b/src/main/java/io/papermc/paper/event/inventory/PaperInventoryMoveItemEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000

View file

@ -27,8 +27,6 @@ and then catch exceptions and close if they fire.
Part of this commit was authored by: Spottedleaf, sandtechnology
Feature patch
diff --git a/src/main/java/net/minecraft/network/Connection.java b/src/main/java/net/minecraft/network/Connection.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/network/Connection.java

View file

@ -15,8 +15,6 @@ Optimize collection by creating a list instead of a set of the key and value.
This lets us get faster foreach iteration, as well as avoids map lookups on
the values when needed.
Feature patch
diff --git a/src/main/java/net/minecraft/world/level/pathfinder/PathFinder.java b/src/main/java/net/minecraft/world/level/pathfinder/PathFinder.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/pathfinder/PathFinder.java

View file

@ -29,8 +29,6 @@ and compute a deterministic result for the MergerList values.
Additionally, this lets us avoid even allocating new objects for this too, further
reducing memory usage.
Feature patch
diff --git a/src/main/java/net/minecraft/world/phys/shapes/IndirectMerger.java b/src/main/java/net/minecraft/world/phys/shapes/IndirectMerger.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/phys/shapes/IndirectMerger.java

View file

@ -11,8 +11,6 @@ Replace all calls to the new place to the unnecessary forward.
Optimize getType and getBlockData to manually inline and optimize the calls
Feature patch
diff --git a/src/main/java/net/minecraft/core/Vec3i.java b/src/main/java/net/minecraft/core/Vec3i.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/core/Vec3i.java

View file

@ -3,7 +3,6 @@ From: kickash32 <kickash32@gmail.com>
Date: Mon, 19 Aug 2019 01:27:58 +0500
Subject: [PATCH] Optional per player mob spawns
Feature patch
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644

View file

@ -19,8 +19,6 @@ and so we have to (forcibly) resend them in order for the client to reset their
See: https://github.com/PaperMC/Paper/pull/1896
Feature patch
== AT ==
public net.minecraft.server.level.ChunkMap$TrackedEntity serverEntity

View file

@ -3,8 +3,6 @@ From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Mon, 27 Feb 2023 18:28:39 -0800
Subject: [PATCH] Registry Modification API
Feature patch
== AT ==
public net.minecraft.core.MappedRegistry validateWrite(Lnet/minecraft/resources/ResourceKey;)V
public net.minecraft.resources.RegistryOps lookupProvider

View file

@ -3,8 +3,6 @@ From: Josh Roy <10731363+JRoy@users.noreply.github.com>
Date: Wed, 1 Jul 2020 18:01:49 -0400
Subject: [PATCH] Remove streams from hot code
Feature patch
Co-authored-by: Bjarne Koll <git@lynxplay.dev>
Co-authored-by: Spottedleaf <Spottedleaf@users.noreply.github.com>

View file

@ -30625,7 +30625,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
public boolean isIteratingOverLevels = false; // Paper - Throw exception on world create while being ticked
private final Set<String> pluginsBlockingSleep = new java.util.HashSet<>(); // Paper - API to allow/disallow tick sleeping
public static <S extends MinecraftServer> S spin(Function<Thread, S> serverFactory) {
+ ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.init(); // Paper - rewrite data converter system
@ -30781,6 +30781,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
return CraftItemStack.asCraftMirror(net.minecraft.world.item.ItemStack.parse(MinecraftServer.getServer().registryAccess(), compound).orElseThrow());
}
@@ -0,0 +0,0 @@ public final class CraftMagicNumbers implements UnsafeValues {
final int dataVersion = data.get("DataVersion").getAsInt();
final int currentVersion = org.bukkit.craftbukkit.util.CraftMagicNumbers.INSTANCE.getDataVersion();
- data = (com.google.gson.JsonObject) MinecraftServer.getServer().fixerUpper.update(References.ITEM_STACK, new Dynamic<>(com.mojang.serialization.JsonOps.INSTANCE, data), dataVersion, currentVersion).getValue();
+ data = ca.spottedleaf.dataconverter.minecraft.MCDataConverter.convertJson(
+ ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.ITEM_STACK,
+ data, false, dataVersion, currentVersion
+ );
com.mojang.serialization.DynamicOps<com.google.gson.JsonElement> ops = MinecraftServer.getServer().registryAccess().createSerializationContext(com.mojang.serialization.JsonOps.INSTANCE);
return CraftItemStack.asCraftMirror(net.minecraft.world.item.ItemStack.CODEC.parse(ops, data).getOrThrow(IllegalArgumentException::new));
}
@@ -0,0 +0,0 @@ public final class CraftMagicNumbers implements UnsafeValues {
net.minecraft.nbt.CompoundTag compound = deserializeNbtFromBytes(data);

View file

@ -3,8 +3,6 @@ From: Andrew Steinborn <git@steinborn.me>
Date: Mon, 26 Jul 2021 02:15:17 -0400
Subject: [PATCH] Use Velocity compression and cipher natives
Feature patch
== AT ==
private-f net.minecraft.network.CompressionDecoder inflater

View file

@ -3,7 +3,6 @@ From: lukas81298 <lukas81298@gommehd.net>
Date: Fri, 22 Jan 2021 21:50:18 +0100
Subject: [PATCH] optimize dirt and snow spreading
Feature patch
diff --git a/src/main/java/net/minecraft/world/level/block/SpreadingSnowyDirtBlock.java b/src/main/java/net/minecraft/world/level/block/SpreadingSnowyDirtBlock.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644