diff --git a/build.gradle.kts b/build.gradle.kts
index 37921cf..203fcfa 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -2,7 +2,7 @@ plugins {
java
`maven-publish`
id("com.github.johnrengelman.shadow") version "8.1.1" apply false
- id("io.papermc.paperweight.patcher") version "1.5.10"
+ id("io.papermc.paperweight.patcher") version "1.5.11"
}
val paperMavenPublicUrl = "https://repo.papermc.io/repository/maven-public/"
diff --git a/gradle.properties b/gradle.properties
index c7da3fd..feca2fc 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,8 +1,8 @@
group=me.totalfreedom.scissors
-version=1.20.2-R0.1-SNAPSHOT
+version=1.20.4-R0.1-SNAPSHOT
-mcVersion=1.20.2
-paperRef=931781c220b98dde0159c9a3c8dce06c3b2b1e13
+mcVersion=1.20.4
+paperRef=b4c9e7e5d40fd4a0a7fea270fd4ebb72b38fa0fc
org.gradle.caching=true
org.gradle.parallel=true
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
index 033e24c..7f93135 100644
Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index ac72c34..1af9e09 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
diff --git a/gradlew b/gradlew
index fcb6fca..0adc8e1 100755
--- a/gradlew
+++ b/gradlew
@@ -83,7 +83,8 @@ done
# This is normally unused
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
-APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
+# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
+APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
diff --git a/patches/api/0001-AdvancedSlimePaper-API-Changes.patch b/patches/api/0001-AdvancedSlimePaper-API-Changes.patch
index ed23c8f..f03cca2 100644
--- a/patches/api/0001-AdvancedSlimePaper-API-Changes.patch
+++ b/patches/api/0001-AdvancedSlimePaper-API-Changes.patch
@@ -20,7 +20,7 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see .
diff --git a/build.gradle.kts b/build.gradle.kts
-index e827ee211e3c65dc68ac5867fd8476639df63645..4bf0c234eacc8398333fe7704acadfecff21c505 100644
+index 3e3ea0e4e4ceb3283ad2b99957e3795d66a9a716..e2db0e69bd254fca5177781d67f4664b69a18625 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -28,6 +28,7 @@ configurations.api {
@@ -30,4 +30,4 @@ index e827ee211e3c65dc68ac5867fd8476639df63645..4bf0c234eacc8398333fe7704acadfec
+ api(project(":aswm-api")) // ASWM
api("com.google.guava:guava:32.1.2-jre")
api("com.google.code.gson:gson:2.10.1")
- api("net.md-5:bungeecord-chat:$bungeeCordChatVersion-deprecated+build.14") // Paper
+ // Paper start - adventure
diff --git a/patches/api/0004-Add-Scissors-configuration-file.patch b/patches/api/0004-Add-Scissors-configuration-file.patch
index 8f6474a..bf6b224 100644
--- a/patches/api/0004-Add-Scissors-configuration-file.patch
+++ b/patches/api/0004-Add-Scissors-configuration-file.patch
@@ -5,10 +5,10 @@ Subject: [PATCH] Add Scissors configuration file
diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java
-index d0c634629aa0b6bac0da93655dd86ad3aea0ce30..5729362a327f6cc67e86d4ebf5328fc60ed710f7 100644
+index 9af4bc16da09e59009c47911219e99450cdf2aa5..94244872f7cd6b4a6df709c0f68b1f484538c159 100644
--- a/src/main/java/org/bukkit/Server.java
+++ b/src/main/java/org/bukkit/Server.java
-@@ -2190,6 +2190,13 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
+@@ -2198,6 +2198,13 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
}
// Paper end
diff --git a/patches/server/0001-AdvancedSlimePaper-Server-Changes.patch b/patches/server/0001-AdvancedSlimePaper-Server-Changes.patch
index 2601935..8b1c40c 100644
--- a/patches/server/0001-AdvancedSlimePaper-Server-Changes.patch
+++ b/patches/server/0001-AdvancedSlimePaper-Server-Changes.patch
@@ -181,10 +181,10 @@ index 0000000000000000000000000000000000000000..61518ab2b68e7a41500f3c8c8a5ec123
\ No newline at end of file
diff --git a/src/main/java/com/infernalsuite/aswm/SimpleDataFixerConverter.java b/src/main/java/com/infernalsuite/aswm/SimpleDataFixerConverter.java
new file mode 100644
-index 0000000000000000000000000000000000000000..21120ef498bda725f6360d289e7d21553b0f614d
+index 0000000000000000000000000000000000000000..1e340b382ea19a46bf16d58f0655a9320f262354
--- /dev/null
+++ b/src/main/java/com/infernalsuite/aswm/SimpleDataFixerConverter.java
-@@ -0,0 +1,101 @@
+@@ -0,0 +1,104 @@
+package com.infernalsuite.aswm;
+
+import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry;
@@ -217,7 +217,7 @@ index 0000000000000000000000000000000000000000..21120ef498bda725f6360d289e7d2155
+ return data;
+ }
+
-+ Map chunks = new HashMap<>();
++ Map chunks = new HashMap<>();
+ for (SlimeChunk chunk : data.getChunkStorage()) {
+ List entities = new ArrayList<>();
+ List blockEntities = new ArrayList<>();
@@ -232,9 +232,12 @@ index 0000000000000000000000000000000000000000..21120ef498bda725f6360d289e7d2155
+ );
+ }
+
++ ChunkPos chunkPos = new ChunkPos(chunk.getX(), chunk.getZ());
++
+ SlimeChunkSection[] sections = new SlimeChunkSection[chunk.getSections().length];
+ for (int i = 0; i < sections.length; i++) {
+ SlimeChunkSection dataSection = chunk.getSections()[i];
++ if (dataSection == null) continue;
+
+ CompoundTag blockStateTag = blockStateTag = convertAndBack(dataSection.getBlockStatesTag(), (tag) -> {
+ WalkerUtils.convertList(MCTypeRegistry.BLOCK_STATE, new NBTMapType(tag), "palette", currentVersion, newVersion);
@@ -250,17 +253,17 @@ index 0000000000000000000000000000000000000000..21120ef498bda725f6360d289e7d2155
+ dataSection.getBlockLight(),
+ dataSection.getSkyLight()
+ );
-+
-+ chunks.put(new ChunkPos(chunk.getX(), chunk.getZ()), new SlimeChunkSkeleton(
-+ chunk.getX(),
-+ chunk.getZ(),
-+ sections,
-+ chunk.getHeightMaps(),
-+ blockEntities,
-+ entities
-+ ));
+ }
+
++ chunks.put(chunkPos, new SlimeChunkSkeleton(
++ chunk.getX(),
++ chunk.getX(),
++ sections,
++ chunk.getHeightMaps(),
++ blockEntities,
++ entities
++ ));
++
+ }
+
+ return new SkeletonSlimeWorld(
@@ -288,12 +291,13 @@ index 0000000000000000000000000000000000000000..21120ef498bda725f6360d289e7d2155
+}
diff --git a/src/main/java/com/infernalsuite/aswm/SlimeNMSBridgeImpl.java b/src/main/java/com/infernalsuite/aswm/SlimeNMSBridgeImpl.java
new file mode 100644
-index 0000000000000000000000000000000000000000..2cb9ae2314fd3bdbbf8c7e161cd7b9300ab580d8
+index 0000000000000000000000000000000000000000..c9b9cff84b203581e943d8f37b574878a3a5994c
--- /dev/null
+++ b/src/main/java/com/infernalsuite/aswm/SlimeNMSBridgeImpl.java
-@@ -0,0 +1,211 @@
+@@ -0,0 +1,238 @@
+package com.infernalsuite.aswm;
+
++import com.flowpowered.nbt.CompoundMap;
+import com.infernalsuite.aswm.api.SlimeNMSBridge;
+import com.infernalsuite.aswm.api.world.SlimeWorld;
+import com.infernalsuite.aswm.api.world.SlimeWorldInstance;
@@ -305,6 +309,7 @@ index 0000000000000000000000000000000000000000..2cb9ae2314fd3bdbbf8c7e161cd7b930
+import net.minecraft.SharedConstants;
+import net.minecraft.core.registries.Registries;
+import net.minecraft.nbt.CompoundTag;
++import net.minecraft.nbt.Tag;
+import net.minecraft.resources.ResourceKey;
+import net.minecraft.resources.ResourceLocation;
+import net.minecraft.server.MinecraftServer;
@@ -323,13 +328,18 @@ index 0000000000000000000000000000000000000000..2cb9ae2314fd3bdbbf8c7e161cd7b930
+import org.bukkit.Bukkit;
+import org.bukkit.World;
+import org.bukkit.craftbukkit.CraftWorld;
++import org.bukkit.craftbukkit.persistence.CraftPersistentDataContainer;
++import org.bukkit.craftbukkit.persistence.CraftPersistentDataTypeRegistry;
++import org.bukkit.persistence.PersistentDataContainer;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.IOException;
+import java.util.Locale;
++import java.util.Map;
+
+public class SlimeNMSBridgeImpl implements SlimeNMSBridge {
+
++ private static final CraftPersistentDataTypeRegistry REGISTRY = new CraftPersistentDataTypeRegistry();
+ private static final SimpleDataFixerConverter DATA_FIXER_CONVERTER = new SimpleDataFixerConverter();
+
+ private static final Logger LOGGER = LogManager.getLogger("SWM");
@@ -343,6 +353,26 @@ index 0000000000000000000000000000000000000000..2cb9ae2314fd3bdbbf8c7e161cd7b930
+ }
+
+ @Override
++ public void extractCraftPDC(PersistentDataContainer source, CompoundMap target) {
++ if (source instanceof CraftPersistentDataContainer craftPDC) {
++ for (Map.Entry entry : craftPDC.getRaw().entrySet()) {
++ target.put(Converter.convertTag(entry.getKey(), entry.getValue()));
++ }
++ } else {
++ throw new IllegalArgumentException("PersistentDataContainer is not a CraftPersistentDataContainer");
++ }
++ }
++
++ @Override
++ public PersistentDataContainer extractCompoundMapIntoCraftPDC(CompoundMap source) {
++ var container = new CraftPersistentDataContainer(REGISTRY);
++ for (Map.Entry> entry : source.entrySet()) {
++ container.put(entry.getKey(), Converter.convertTag(entry.getValue()));
++ }
++ return container;
++ }
++
++ @Override
+ public boolean loadOverworldOverride() {
+ if (defaultWorld == null) {
+ return false;
@@ -505,18 +535,20 @@ index 0000000000000000000000000000000000000000..2cb9ae2314fd3bdbbf8c7e161cd7b930
+}
diff --git a/src/main/java/com/infernalsuite/aswm/level/ChunkDataLoadTask.java b/src/main/java/com/infernalsuite/aswm/level/ChunkDataLoadTask.java
new file mode 100644
-index 0000000000000000000000000000000000000000..66093eaed9a45c7b714471915c8bd38f23ac7894
+index 0000000000000000000000000000000000000000..65642a9bde0fffc6531604026dd957fd268b6642
--- /dev/null
+++ b/src/main/java/com/infernalsuite/aswm/level/ChunkDataLoadTask.java
-@@ -0,0 +1,113 @@
+@@ -0,0 +1,117 @@
+package com.infernalsuite.aswm.level;
+
+import ca.spottedleaf.concurrentutil.executor.standard.PrioritisedExecutor;
++import com.infernalsuite.aswm.Converter;
+import com.infernalsuite.aswm.api.world.SlimeChunk;
+import com.mojang.logging.LogUtils;
+import io.papermc.paper.chunk.system.scheduling.ChunkLoadTask;
+import io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler;
+import io.papermc.paper.chunk.system.scheduling.GenericDataLoadTask;
++import net.minecraft.nbt.CompoundTag;
+import net.minecraft.server.level.ServerLevel;
+import net.minecraft.world.level.ChunkPos;
+import net.minecraft.world.level.block.Block;
@@ -557,7 +589,7 @@ index 0000000000000000000000000000000000000000..66093eaed9a45c7b714471915c8bd38f
+ try {
+ SlimeChunk chunk = ((SlimeLevelInstance) this.world).slimeInstance.getChunk(this.chunkX, this.chunkZ);
+ this.onRun.accept(new GenericDataLoadTask.TaskResult<>(runOnMain(chunk), null));
-+ } catch (Throwable e) {
++ } catch (final Exception e) {
+ LOGGER.error("ERROR", e);
+ this.onRun.accept(new GenericDataLoadTask.TaskResult<>(null, e));
+ }
@@ -569,7 +601,7 @@ index 0000000000000000000000000000000000000000..66093eaed9a45c7b714471915c8bd38f
+ LevelChunkTicks fluidLevelChunkTicks = new LevelChunkTicks<>();
+
+ return new ImposterProtoChunk(new LevelChunk(this.world, new ChunkPos(this.chunkX, this.chunkZ), UpgradeData.EMPTY, blockLevelChunkTicks, fluidLevelChunkTicks,
-+ 0L, null, null, null), true);
++ 0L, null, chunk -> {}, null), true);
+ }
+
+ protected ChunkAccess runOnMain(final SlimeChunk data) {
@@ -582,12 +614,14 @@ index 0000000000000000000000000000000000000000..66093eaed9a45c7b714471915c8bd38f
+ // }
+
+ LevelChunk chunk = this.world.slimeInstance.promote(chunkX, chunkZ, data);
++ ImposterProtoChunk protoChunk = new ImposterProtoChunk(chunk, false);
++ if (data != null) {
++ data.getEntities().stream().map(flowTag -> (CompoundTag) Converter.convertTag(flowTag)).forEach(protoChunk::addEntity);
++ }
+
+ return new ImposterProtoChunk(chunk, false);
-+ } catch (final ThreadDeath death) {
-+ throw death;
-+ } catch (final Throwable thr2) {
-+ LOGGER.error("Failed to parse main tasks for task " + this.toString() + ", chunk data will be lost", thr2);
++ } catch (final Exception e) {
++ LOGGER.error("Failed to parse main tasks for task {}, chunk data will be lost", this, e);
+ return this.getEmptyChunk();
+ }
+ }
@@ -622,6 +656,7 @@ index 0000000000000000000000000000000000000000..66093eaed9a45c7b714471915c8bd38f
+ return true;
+ }
+}
+\ No newline at end of file
diff --git a/src/main/java/com/infernalsuite/aswm/level/CommonLoadTask.java b/src/main/java/com/infernalsuite/aswm/level/CommonLoadTask.java
new file mode 100644
index 0000000000000000000000000000000000000000..fc6e46972bcc77134ed718c8c157ec3893d4bcdf
@@ -924,10 +959,10 @@ index 0000000000000000000000000000000000000000..c94ee5460d3859d373ae81e9d3623db0
+}
diff --git a/src/main/java/com/infernalsuite/aswm/level/NMSSlimeWorld.java b/src/main/java/com/infernalsuite/aswm/level/NMSSlimeWorld.java
new file mode 100644
-index 0000000000000000000000000000000000000000..9a27369c00345bbb94aa19f77687269dc94c0b0a
+index 0000000000000000000000000000000000000000..07e542e3f75bf272f53345dc040d90358e7d7b2d
--- /dev/null
+++ b/src/main/java/com/infernalsuite/aswm/level/NMSSlimeWorld.java
-@@ -0,0 +1,91 @@
+@@ -0,0 +1,98 @@
+package com.infernalsuite.aswm.level;
+
+import com.flowpowered.nbt.CompoundTag;
@@ -939,6 +974,8 @@ index 0000000000000000000000000000000000000000..9a27369c00345bbb94aa19f77687269d
+import net.minecraft.SharedConstants;
+import net.minecraft.server.level.ChunkHolder;
+import net.minecraft.world.level.chunk.LevelChunk;
++import org.bukkit.persistence.PersistentDataContainer;
++import org.jetbrains.annotations.NotNull;
+
+import java.io.IOException;
+import java.util.Collection;
@@ -1018,6 +1055,11 @@ index 0000000000000000000000000000000000000000..9a27369c00345bbb94aa19f77687269d
+ public int getDataVersion() {
+ return SharedConstants.getCurrentVersion().getDataVersion().getVersion();
+ }
++
++ @Override
++ public @NotNull PersistentDataContainer getPersistentDataContainer() {
++ return memoryWorld.getPersistentDataContainer();
++ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/infernalsuite/aswm/level/SafeNmsChunkWrapper.java b/src/main/java/com/infernalsuite/aswm/level/SafeNmsChunkWrapper.java
@@ -1127,10 +1169,10 @@ index 0000000000000000000000000000000000000000..8853088c5c6306511716bbffac9bf73c
\ No newline at end of file
diff --git a/src/main/java/com/infernalsuite/aswm/level/SlimeChunkConverter.java b/src/main/java/com/infernalsuite/aswm/level/SlimeChunkConverter.java
new file mode 100644
-index 0000000000000000000000000000000000000000..91a7f41db47c7df3ecc301e0827a1d07305f604e
+index 0000000000000000000000000000000000000000..a771d4975d47246d4d1597492daf0e19d6e25558
--- /dev/null
+++ b/src/main/java/com/infernalsuite/aswm/level/SlimeChunkConverter.java
-@@ -0,0 +1,164 @@
+@@ -0,0 +1,172 @@
+package com.infernalsuite.aswm.level;
+
+import ca.spottedleaf.starlight.common.light.SWMRNibbleArray;
@@ -1148,6 +1190,7 @@ index 0000000000000000000000000000000000000000..91a7f41db47c7df3ecc301e0827a1d07
+import net.minecraft.core.Registry;
+import net.minecraft.core.registries.Registries;
+import net.minecraft.nbt.NbtOps;
++import net.minecraft.world.entity.EntityType;
+import net.minecraft.world.level.ChunkPos;
+import net.minecraft.world.level.biome.Biome;
+import net.minecraft.world.level.biome.Biomes;
@@ -1260,6 +1303,13 @@ index 0000000000000000000000000000000000000000..91a7f41db47c7df3ecc301e0827a1d07
+ }
+ }
+ }
++
++ List entities = chunk.getEntities();
++
++ if (entities != null) {
++ instance.addLegacyChunkEntities(EntityType.loadEntitiesRecursive(entities.stream()
++ .map(flowTag -> (net.minecraft.nbt.CompoundTag) Converter.convertTag(flowTag)).toList(), instance), nmsChunk.getPos());
++ }
+ };
+
+ LevelChunkTicks blockLevelChunkTicks = new LevelChunkTicks<>();
@@ -1295,7 +1345,6 @@ index 0000000000000000000000000000000000000000..91a7f41db47c7df3ecc301e0827a1d07
+ return nmsChunk;
+ }
+}
-\ No newline at end of file
diff --git a/src/main/java/com/infernalsuite/aswm/level/SlimeChunkLevel.java b/src/main/java/com/infernalsuite/aswm/level/SlimeChunkLevel.java
new file mode 100644
index 0000000000000000000000000000000000000000..b159fc8751e9840b311cc1eda01e496e2dbc5f2e
@@ -1332,10 +1381,10 @@ index 0000000000000000000000000000000000000000..b159fc8751e9840b311cc1eda01e496e
\ No newline at end of file
diff --git a/src/main/java/com/infernalsuite/aswm/level/SlimeInMemoryWorld.java b/src/main/java/com/infernalsuite/aswm/level/SlimeInMemoryWorld.java
new file mode 100644
-index 0000000000000000000000000000000000000000..f0509f07a743302dfedce9413b0d9c8fb3ff111d
+index 0000000000000000000000000000000000000000..9bdf0e3778a03cbbf3af213e8c197257ce0964f6
--- /dev/null
+++ b/src/main/java/com/infernalsuite/aswm/level/SlimeInMemoryWorld.java
-@@ -0,0 +1,259 @@
+@@ -0,0 +1,269 @@
+package com.infernalsuite.aswm.level;
+
+import com.flowpowered.nbt.CompoundTag;
@@ -1347,6 +1396,7 @@ index 0000000000000000000000000000000000000000..f0509f07a743302dfedce9413b0d9c8f
+import com.infernalsuite.aswm.api.world.SlimeWorld;
+import com.infernalsuite.aswm.api.world.SlimeWorldInstance;
+import com.infernalsuite.aswm.api.world.properties.SlimePropertyMap;
++import com.infernalsuite.aswm.pdc.FlowPersistentDataContainer;
+import com.infernalsuite.aswm.serialization.slime.SlimeSerializer;
+import com.infernalsuite.aswm.skeleton.SkeletonCloning;
+import com.infernalsuite.aswm.skeleton.SkeletonSlimeWorld;
@@ -1357,6 +1407,8 @@ index 0000000000000000000000000000000000000000..f0509f07a743302dfedce9413b0d9c8f
+import net.minecraft.world.level.material.Fluid;
+import net.minecraft.world.ticks.LevelChunkTicks;
+import org.bukkit.World;
++import org.bukkit.persistence.PersistentDataContainer;
++import org.jetbrains.annotations.NotNull;
+
+import java.io.IOException;
+import java.util.*;
@@ -1372,6 +1424,7 @@ index 0000000000000000000000000000000000000000..f0509f07a743302dfedce9413b0d9c8f
+ private final SlimeWorld liveWorld;
+
+ private final CompoundTag extra;
++ private final FlowPersistentDataContainer extraPDC;
+ private final SlimePropertyMap propertyMap;
+ private final SlimeLoader loader;
+
@@ -1394,6 +1447,7 @@ index 0000000000000000000000000000000000000000..f0509f07a743302dfedce9413b0d9c8f
+ this.chunkStorage.put(pos, initial);
+ }
+
++ this.extraPDC = new FlowPersistentDataContainer(extra);
+ this.liveWorld = new NMSSlimeWorld(this);
+ }
+
@@ -1594,6 +1648,11 @@ index 0000000000000000000000000000000000000000..f0509f07a743302dfedce9413b0d9c8f
+ public SlimeLevelInstance getInstance() {
+ return instance;
+ }
++
++ @Override
++ public @NotNull PersistentDataContainer getPersistentDataContainer() {
++ return this.extraPDC;
++ }
+}
diff --git a/src/main/java/com/infernalsuite/aswm/level/SlimeLevelGenerator.java b/src/main/java/com/infernalsuite/aswm/level/SlimeLevelGenerator.java
new file mode 100644
@@ -1858,983 +1917,3 @@ index 0000000000000000000000000000000000000000..3500005bb09dc484bc333f1e0799613d
+ }
+}
\ No newline at end of file
-diff --git a/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkHolderManager.java b/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkHolderManager.java
-index abd0217cf0bff183c8e262edc173a53403797c1a..42170127cc1ed35cb2aec6bf7eb473a0137c63bb 100644
---- a/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkHolderManager.java
-+++ b/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkHolderManager.java
-@@ -165,7 +165,8 @@ public final class ChunkHolderManager {
- return this.chunkHolders.size();
- }
-
-- public void close(final boolean save, final boolean halt) {
-+ public void close(boolean save, final boolean halt) { // ASWM
-+ if (this.world instanceof com.infernalsuite.aswm.level.SlimeLevelInstance) save = false; // ASWM
- TickThread.ensureTickThread("Closing world off-main");
- if (halt) {
- LOGGER.info("Waiting 60s for chunk system to halt for world '" + this.world.getWorld().getName() + "'");
-@@ -1316,7 +1317,7 @@ public final class ChunkHolderManager {
-
- public boolean processTicketUpdates() {
- co.aikar.timings.MinecraftTimings.distanceManagerTick.startTiming(); try { // Paper - add timings for distance manager
-- return this.processTicketUpdates(true, true, null);
-+ return this.processTicketUpdates(true, true, null);
- } finally { co.aikar.timings.MinecraftTimings.distanceManagerTick.stopTiming(); } // Paper - add timings for distance manager
- }
-
-diff --git a/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkLoadTask.java b/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkLoadTask.java
-index e7fb084ddb88ab62f1d493a999cc82b9258d275e..943cdd570c9e5c87ee9f3984404e08b4cdffeca0 100644
---- a/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkLoadTask.java
-+++ b/src/main/java/io/papermc/paper/chunk/system/scheduling/ChunkLoadTask.java
-@@ -6,6 +6,7 @@ import ca.spottedleaf.concurrentutil.lock.ReentrantAreaLock;
- import ca.spottedleaf.concurrentutil.util.ConcurrentUtil;
- import ca.spottedleaf.dataconverter.minecraft.MCDataConverter;
- import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry;
-+import com.infernalsuite.aswm.level.CommonLoadTask;
- import com.mojang.logging.LogUtils;
- import io.papermc.paper.chunk.system.io.RegionFileIOThread;
- import io.papermc.paper.chunk.system.poi.PoiChunk;
-@@ -32,8 +33,8 @@ public final class ChunkLoadTask extends ChunkProgressionTask {
-
- private static final Logger LOGGER = LogUtils.getClassLogger();
-
-- private final NewChunkHolder chunkHolder;
-- private final ChunkDataLoadTask loadTask;
-+ public final NewChunkHolder chunkHolder; // ASWM
-+ private final CommonLoadTask loadTask;
-
- private volatile boolean cancelled;
- private NewChunkHolder.GenericDataLoadTaskCallback entityLoadTask;
-@@ -45,11 +46,20 @@ public final class ChunkLoadTask extends ChunkProgressionTask {
- final NewChunkHolder chunkHolder, final PrioritisedExecutor.Priority priority) {
- super(scheduler, world, chunkX, chunkZ);
- this.chunkHolder = chunkHolder;
-- this.loadTask = new ChunkDataLoadTask(scheduler, world, chunkX, chunkZ, priority);
-- this.loadTask.addCallback((final GenericDataLoadTask.TaskResult result) -> {
-- ChunkLoadTask.this.loadResult = result; // must be before getAndDecrement
-- ChunkLoadTask.this.tryCompleteLoad();
-- });
-+ // ASWM start
-+ if (world instanceof com.infernalsuite.aswm.level.SlimeLevelInstance levelInstance) {
-+
-+ this.loadTask = levelInstance.getLoadTask(this, scheduler, world, chunkX, chunkZ, priority, result -> {
-+ ChunkLoadTask.this.complete(result == null ? null : result.left(), result == null ? null : result.right());
-+ });
-+ } else {
-+ ChunkDataLoadTask task = new ChunkDataLoadTask(scheduler, world, chunkX, chunkZ, priority);
-+ task.addCallback((final GenericDataLoadTask.TaskResult result) -> {
-+ ChunkLoadTask.this.complete(result == null ? null : result.left(), result == null ? null : result.right());
-+ });
-+ this.loadTask = task;
-+ }
-+ // ASWM end
- }
-
- private void tryCompleteLoad() {
-@@ -274,7 +284,7 @@ public final class ChunkLoadTask extends ChunkProgressionTask {
- }
- }
-
-- public static final class ChunkDataLoadTask extends CallbackDataLoadTask {
-+ public static final class ChunkDataLoadTask extends CallbackDataLoadTask implements CommonLoadTask { // ASWM
- protected ChunkDataLoadTask(final ChunkTaskScheduler scheduler, final ServerLevel world, final int chunkX,
- final int chunkZ, final PrioritisedExecutor.Priority priority) {
- super(scheduler, world, chunkX, chunkZ, RegionFileIOThread.RegionFileType.CHUNK_DATA, priority);
-diff --git a/src/main/java/io/papermc/paper/chunk/system/scheduling/NewChunkHolder.java b/src/main/java/io/papermc/paper/chunk/system/scheduling/NewChunkHolder.java
-index b66a7d4aab887309579154815a0d4abf9de506b0..2fe8a17cdc2a823548fa180f72cd70e4d5e5fdf3 100644
---- a/src/main/java/io/papermc/paper/chunk/system/scheduling/NewChunkHolder.java
-+++ b/src/main/java/io/papermc/paper/chunk/system/scheduling/NewChunkHolder.java
-@@ -1775,7 +1775,7 @@ public final class NewChunkHolder {
- }
-
- boolean canSaveChunk = !(chunk instanceof LevelChunk levelChunk && levelChunk.mustNotSave) &&
-- (chunk != null && ((shutdown || chunk instanceof LevelChunk) && chunk.isUnsaved()));
-+ (chunk != null && ((shutdown || chunk instanceof LevelChunk) && chunk.isUnsaved()));
- boolean canSavePOI = !(chunk instanceof LevelChunk levelChunk && levelChunk.mustNotSave) && (poi != null && poi.isDirty());
- boolean canSaveEntities = entities != null;
-
-diff --git a/src/main/java/io/papermc/paper/world/ChunkEntitySlices.java b/src/main/java/io/papermc/paper/world/ChunkEntitySlices.java
-index 7e8dc9e8f381abfdcce2746edc93122d623622d1..12aadf4c981cdb1a6405de99016f4b40e83a04b8 100644
---- a/src/main/java/io/papermc/paper/world/ChunkEntitySlices.java
-+++ b/src/main/java/io/papermc/paper/world/ChunkEntitySlices.java
-@@ -36,7 +36,7 @@ public final class ChunkEntitySlices {
- protected final EntityCollectionBySection allEntities;
- protected final EntityCollectionBySection hardCollidingEntities;
- protected final Reference2ObjectOpenHashMap, EntityCollectionBySection> entitiesByClass;
-- protected final EntityList entities = new EntityList();
-+ public final EntityList entities = new EntityList(); // ASWM
-
- public FullChunkStatus status;
-
-diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
-index 8f31413c939cc2b0454ad3d9a1b618dbae449d00..3d5d79e428a7b0f1aa7d0d3911e6d61b9537e8a0 100644
---- a/src/main/java/net/minecraft/server/MinecraftServer.java
-+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
-@@ -268,7 +268,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop dimensions = this.registries.compositeAccess().registryOrThrow(Registries.LEVEL_STEM);
-- for (LevelStem worldDimension : dimensions) {
-+ for(LevelStem worldDimension : dimensions) {
- ResourceKey dimensionKey = dimensions.getResourceKey(worldDimension).get();
-
- ServerLevel world;
- int dimension = 0;
-
-- if (dimensionKey == LevelStem.NETHER) {
-- if (this.isNetherEnabled()) {
-+ if(dimensionKey == LevelStem.NETHER) {
-+ if(this.isNetherEnabled()) {
- dimension = -1;
-- } else {
-+ // ASWM START
-+ if(com.infernalsuite.aswm.SlimeNMSBridgeImpl.instance().loadNetherOverride()) {
-+ continue;
-+ }
-+ // ASWM END
-+ }else{
- continue;
- }
-- } else if (dimensionKey == LevelStem.END) {
-- if (this.server.getAllowEnd()) {
-+ }else if(dimensionKey == LevelStem.END) {
-+ if(this.server.getAllowEnd()) {
- dimension = 1;
-- } else {
-+ // ASWM START
-+ if(com.infernalsuite.aswm.SlimeNMSBridgeImpl.instance().loadEndOverride()) {
-+ continue;
-+ }
-+ // ASWM END
-+ }else{
- continue;
- }
-- } else if (dimensionKey != LevelStem.OVERWORLD) {
-+ }else if(dimensionKey != LevelStem.OVERWORLD) {
- dimension = -999;
- }
-+ // ASWM START
-+ else if(dimensionKey == LevelStem.OVERWORLD && com.infernalsuite.aswm.SlimeNMSBridgeImpl.instance().loadOverworldOverride()) {
-+ continue;
-+ }
-+ // ASWM END
-
- String worldType = (dimension == -999) ? dimensionKey.location().getNamespace() + "_" + dimensionKey.location().getPath() : org.bukkit.World.Environment.getEnvironment(dimension).toString().toLowerCase();
- String name = (dimensionKey == LevelStem.OVERWORLD) ? s : s + "_" + worldType;
-- if (dimension != 0) {
-+ if(dimension != 0) {
- File newWorld = LevelStorageSource.getStorageFolder(new File(name).toPath(), dimensionKey).toFile();
- File oldWorld = LevelStorageSource.getStorageFolder(new File(s).toPath(), dimensionKey).toFile();
- File oldLevelDat = new File(new File(s), "level.dat"); // The data folders exist on first run as they are created in the PersistentCollection constructor above, but the level.dat won't
-
-- if (!newWorld.isDirectory() && oldWorld.isDirectory() && oldLevelDat.isFile()) {
-+ if(!newWorld.isDirectory() && oldWorld.isDirectory() && oldLevelDat.isFile()) {
- MinecraftServer.LOGGER.info("---- Migration of old " + worldType + " folder required ----");
- MinecraftServer.LOGGER.info("Unfortunately due to the way that Minecraft implemented multiworld support in 1.6, Bukkit requires that you move your " + worldType + " folder to a new location in order to operate correctly.");
- MinecraftServer.LOGGER.info("We will move this folder for you, but it will mean that you need to move it back should you wish to stop using Bukkit in the future.");
- MinecraftServer.LOGGER.info("Attempting to move " + oldWorld + " to " + newWorld + "...");
-
-- if (newWorld.exists()) {
-+ if(newWorld.exists()) {
- MinecraftServer.LOGGER.warn("A file or folder already exists at " + newWorld + "!");
- MinecraftServer.LOGGER.info("---- Migration of old " + worldType + " folder failed ----");
-- } else if (newWorld.getParentFile().mkdirs()) {
-- if (oldWorld.renameTo(newWorld)) {
-+ }else if(newWorld.getParentFile().mkdirs()) {
-+ if(oldWorld.renameTo(newWorld)) {
- MinecraftServer.LOGGER.info("Success! To restore " + worldType + " in the future, simply move " + newWorld + " to " + oldWorld);
- // Migrate world data too.
- try {
- com.google.common.io.Files.copy(oldLevelDat, new File(new File(name), "level.dat"));
- org.apache.commons.io.FileUtils.copyDirectory(new File(new File(s), "data"), new File(new File(name), "data"));
-- } catch (IOException exception) {
-+ } catch(IOException exception) {
- MinecraftServer.LOGGER.warn("Unable to migrate world data.");
- }
- MinecraftServer.LOGGER.info("---- Migration of old " + worldType + " folder complete ----");
-- } else {
-+ }else{
- MinecraftServer.LOGGER.warn("Could not move folder " + oldWorld + " to " + newWorld + "!");
- MinecraftServer.LOGGER.info("---- Migration of old " + worldType + " folder failed ----");
- }
-- } else {
-+ }else{
- MinecraftServer.LOGGER.warn("Could not create path for " + newWorld + "!");
- MinecraftServer.LOGGER.info("---- Migration of old " + worldType + " folder failed ----");
- }
-@@ -505,7 +520,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop dynamicops = RegistryOps.create(NbtOps.INSTANCE, (HolderLookup.Provider) worldloader_a.datapackWorldgen());
- Pair pair = worldSession.getDataTag(dynamicops, worldloader_a.dataConfiguration(), iregistry, worldloader_a.datapackWorldgen().allRegistriesLifecycle());
-
-- if (pair != null) {
-+ if(pair != null) {
- worlddata = (PrimaryLevelData) pair.getFirst();
-- } else {
-+ }else{
- LevelSettings worldsettings;
- WorldOptions worldoptions;
- WorldDimensions worlddimensions;
-
-- if (this.isDemo()) {
-+ if(this.isDemo()) {
- worldsettings = MinecraftServer.DEMO_SETTINGS;
- worldoptions = WorldOptions.DEMO_OPTIONS;
- worlddimensions = WorldPresets.createNormalWorldDimensions(worldloader_a.datapackWorldgen());
-- } else {
-+ }else{
- DedicatedServerProperties dedicatedserverproperties = ((DedicatedServer) this).getProperties();
-
- worldsettings = new LevelSettings(dedicatedserverproperties.levelName, dedicatedserverproperties.gamemode, dedicatedserverproperties.hardcore, dedicatedserverproperties.difficulty, false, new GameRules(), worldloader_a.dataConfiguration());
-@@ -555,12 +570,12 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop worldKey = ResourceKey.create(Registries.DIMENSION, dimensionKey.location());
-
-- if (dimensionKey == LevelStem.OVERWORLD) {
-+ if(dimensionKey == LevelStem.OVERWORLD) {
- this.worldData = worlddata;
- this.worldData.setGameType(((DedicatedServer) this).getProperties().gamemode); // From DedicatedServer.init
-
-@@ -579,13 +594,13 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop spawners;
-- if (io.papermc.paper.configuration.GlobalConfiguration.get().misc.useDimensionTypeForCustomSpawners && this.registryAccess().registryOrThrow(Registries.DIMENSION_TYPE).getResourceKey(worlddimension.type().value()).orElseThrow() == net.minecraft.world.level.dimension.BuiltinDimensionTypes.OVERWORLD) {
-+ if(io.papermc.paper.configuration.GlobalConfiguration.get().misc.useDimensionTypeForCustomSpawners && this.registryAccess().registryOrThrow(Registries.DIMENSION_TYPE).getResourceKey(worlddimension.type().value()).orElseThrow() == net.minecraft.world.level.dimension.BuiltinDimensionTypes.OVERWORLD) {
- spawners = list;
-- } else {
-+ }else{
- spawners = Collections.emptyList();
- }
- world = new ServerLevel(this, this.executor, worldSession, iworlddataserver, worldKey, worlddimension, worldloadlistener, flag, j, spawners, true, this.overworld().getRandomSequences(), org.bukkit.World.Environment.getEnvironment(dimension), gen, biomeProvider);
-@@ -599,12 +614,12 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop toRemove = scoreboard.getPlayerTeams().stream().filter(team -> team.getName().startsWith("collideRule_")).map(net.minecraft.world.scores.PlayerTeam::getName).collect(java.util.stream.Collectors.toList());
-- for (String teamName : toRemove) {
-+ for(String teamName : toRemove) {
- scoreboard.removePlayerTeam(scoreboard.getPlayerTeam(teamName)); // Clean up after ourselves
- }
-
-- if (!io.papermc.paper.configuration.GlobalConfiguration.get().collisions.enablePlayerCollisions) {
-+ if(!io.papermc.paper.configuration.GlobalConfiguration.get().collisions.enablePlayerCollisions) {
- this.getPlayerList().collideRuleTeamName = org.apache.commons.lang3.StringUtils.left("collideRule_" + java.util.concurrent.ThreadLocalRandom.current().nextInt(), 16);
- net.minecraft.world.scores.PlayerTeam collideTeam = scoreboard.addPlayerTeam(this.getPlayerList().collideRuleTeamName);
- collideTeam.setSeeFriendlyInvisibles(false); // Because we want to mimic them not being on a team at all
-@@ -752,26 +767,26 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop entityTickingChunks = new io.papermc.paper.util.maplist.IteratorSafeOrderedReferenceSet<>(4096, 0.75f, 4096, 0.15, true);
- // Paper end
-
-- public ServerChunkCache(ServerLevel world, LevelStorageSource.LevelStorageAccess session, DataFixer dataFixer, StructureTemplateManager structureTemplateManager, Executor workerExecutor, ChunkGenerator chunkGenerator, int viewDistance, int simulationDistance, boolean dsync, ChunkProgressListener worldGenerationProgressListener, ChunkStatusUpdateListener chunkStatusChangeListener, Supplier persistentStateManagerFactory) {
-+ // ASWM START
-+ public final com.infernalsuite.aswm.level.SlimeBootstrap bootstrap;
-+ public ServerChunkCache(com.infernalsuite.aswm.level.SlimeBootstrap bootstrap, ServerLevel world, LevelStorageSource.LevelStorageAccess session, DataFixer dataFixer, StructureTemplateManager structureTemplateManager, Executor workerExecutor, ChunkGenerator chunkGenerator, int viewDistance, int simulationDistance, boolean dsync, ChunkProgressListener worldGenerationProgressListener, ChunkStatusUpdateListener chunkStatusChangeListener, Supplier persistentStateManagerFactory) { // ASWM
-+ this.bootstrap = bootstrap;
-+ // ASWM end
- this.level = world;
- this.mainThreadProcessor = new ServerChunkCache.MainThreadExecutor(world);
- this.mainThread = Thread.currentThread();
-@@ -296,7 +300,7 @@ public class ServerChunkCache extends ChunkSource {
- // Paper end
- com.destroystokyo.paper.io.SyncLoadFinder.logSyncLoad(this.level, x1, z1); // Paper - sync load info
- this.level.timings.syncChunkLoad.startTiming(); // Paper
-- chunkproviderserver_b.managedBlock(completablefuture::isDone);
-+ chunkproviderserver_b.managedBlock(completablefuture::isDone);
- io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler.popChunkWait(); // Paper - async chunk debug // Paper - rewrite chunk system
- this.level.timings.syncChunkLoad.stopTiming(); // Paper
- } // Paper
-@@ -448,7 +452,7 @@ public class ServerChunkCache extends ChunkSource {
- public void save(boolean flush) {
- this.runDistanceManagerUpdates();
- try (co.aikar.timings.Timing timed = level.timings.chunkSaveData.startTiming()) { // Paper - Timings
-- this.chunkMap.saveAllChunks(flush);
-+ this.chunkMap.saveAllChunks(flush);
- } // Paper - Timings
- }
-
-@@ -614,47 +618,47 @@ public class ServerChunkCache extends ChunkSource {
- iterator1 = shuffled.iterator();
- }
- try {
-- // Paper end - optimise chunk tick iteration
-- while (iterator1.hasNext()) {
-- LevelChunk chunk1 = iterator1.next(); // Paper - optimise chunk tick iteration
-- ChunkPos chunkcoordintpair = chunk1.getPos();
-+ // Paper end - optimise chunk tick iteration
-+ while (iterator1.hasNext()) {
-+ LevelChunk chunk1 = iterator1.next(); // Paper - optimise chunk tick iteration
-+ ChunkPos chunkcoordintpair = chunk1.getPos();
-
-- // Paper start - optimise chunk tick iteration
-- com.destroystokyo.paper.util.maplist.ReferenceList playersNearby
-- = nearbyPlayers.getPlayers(chunkcoordintpair, io.papermc.paper.util.player.NearbyPlayers.NearbyMapType.SPAWN_RANGE);
-- if (playersNearby == null) {
-- continue;
-- }
-- Object[] rawData = playersNearby.getRawData();
-- boolean spawn = false;
-- boolean tick = false;
-- for (int itr = 0, len = playersNearby.size(); itr < len; ++itr) {
-- ServerPlayer player = (ServerPlayer)rawData[itr];
-- if (player.isSpectator()) {
-+ // Paper start - optimise chunk tick iteration
-+ com.destroystokyo.paper.util.maplist.ReferenceList playersNearby
-+ = nearbyPlayers.getPlayers(chunkcoordintpair, io.papermc.paper.util.player.NearbyPlayers.NearbyMapType.SPAWN_RANGE);
-+ if (playersNearby == null) {
- continue;
- }
-+ Object[] rawData = playersNearby.getRawData();
-+ boolean spawn = false;
-+ boolean tick = false;
-+ for (int itr = 0, len = playersNearby.size(); itr < len; ++itr) {
-+ ServerPlayer player = (ServerPlayer)rawData[itr];
-+ if (player.isSpectator()) {
-+ continue;
-+ }
-
-- double distance = ChunkMap.euclideanDistanceSquared(chunkcoordintpair, player);
-- spawn |= player.lastEntitySpawnRadiusSquared >= distance;
-- tick |= ((double)io.papermc.paper.util.player.NearbyPlayers.SPAWN_RANGE_VIEW_DISTANCE_BLOCKS) * ((double)io.papermc.paper.util.player.NearbyPlayers.SPAWN_RANGE_VIEW_DISTANCE_BLOCKS) >= distance;
-- if (spawn & tick) {
-- break;
-- }
-- }
-- // Paper end - optimise chunk tick iteration
-- if (tick && chunk1.chunkStatus.isOrAfter(net.minecraft.server.level.FullChunkStatus.ENTITY_TICKING)) { // Paper - optimise chunk tick iteration
-- chunk1.incrementInhabitedTime(j);
-- if (spawn && flag2 && (this.spawnEnemies || this.spawnFriendlies) && this.level.getWorldBorder().isWithinBounds(chunkcoordintpair)) { // Spigot // Paper - optimise chunk tick iteration
-- NaturalSpawner.spawnForChunk(this.level, chunk1, spawnercreature_d, this.spawnFriendlies, this.spawnEnemies, flag1);
-+ double distance = ChunkMap.euclideanDistanceSquared(chunkcoordintpair, player);
-+ spawn |= player.lastEntitySpawnRadiusSquared >= distance;
-+ tick |= ((double)io.papermc.paper.util.player.NearbyPlayers.SPAWN_RANGE_VIEW_DISTANCE_BLOCKS) * ((double)io.papermc.paper.util.player.NearbyPlayers.SPAWN_RANGE_VIEW_DISTANCE_BLOCKS) >= distance;
-+ if (spawn & tick) {
-+ break;
-+ }
- }
-+ // Paper end - optimise chunk tick iteration
-+ if (tick && chunk1.chunkStatus.isOrAfter(net.minecraft.server.level.FullChunkStatus.ENTITY_TICKING)) { // Paper - optimise chunk tick iteration
-+ chunk1.incrementInhabitedTime(j);
-+ if (spawn && flag2 && (this.spawnEnemies || this.spawnFriendlies) && this.level.getWorldBorder().isWithinBounds(chunkcoordintpair)) { // Spigot // Paper - optimise chunk tick iteration
-+ NaturalSpawner.spawnForChunk(this.level, chunk1, spawnercreature_d, this.spawnFriendlies, this.spawnEnemies, flag1);
-+ }
-
-- if (true || this.level.shouldTickBlocksAt(chunkcoordintpair.toLong())) { // Paper - optimise chunk tick iteration
-- this.level.tickChunk(chunk1, k);
-- if ((chunksTicked++ & 1) == 0) net.minecraft.server.MinecraftServer.getServer().executeMidTickTasks(); // Paper
-+ if (true || this.level.shouldTickBlocksAt(chunkcoordintpair.toLong())) { // Paper - optimise chunk tick iteration
-+ this.level.tickChunk(chunk1, k);
-+ if ((chunksTicked++ & 1) == 0) net.minecraft.server.MinecraftServer.getServer().executeMidTickTasks(); // Paper
-+ }
- }
- }
-- }
-- // Paper start - optimise chunk tick iteration
-+ // Paper start - optimise chunk tick iteration
- } finally {
- if (iterator1 instanceof io.papermc.paper.util.maplist.IteratorSafeOrderedReferenceSet.Iterator safeIterator) {
- safeIterator.finishedIterating();
-@@ -665,13 +669,13 @@ public class ServerChunkCache extends ChunkSource {
- gameprofilerfiller.popPush("customSpawners");
- if (flag2) {
- try (co.aikar.timings.Timing ignored = this.level.timings.miscMobSpawning.startTiming()) { // Paper - timings
-- this.level.tickCustomSpawners(this.spawnEnemies, this.spawnFriendlies);
-+ this.level.tickCustomSpawners(this.spawnEnemies, this.spawnFriendlies);
- } // Paper - timings
- }
-
- gameprofilerfiller.popPush("broadcast");
- // Paper - optimise chunk tick iteration
-- this.level.timings.broadcastChunkUpdates.startTiming(); // Paper - timing
-+ this.level.timings.broadcastChunkUpdates.startTiming(); // Paper - timing
- // Paper start - optimise chunk tick iteration
- if (!this.chunkMap.needsChangeBroadcasting.isEmpty()) {
- it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet copy = this.chunkMap.needsChangeBroadcasting.clone();
-@@ -685,7 +689,7 @@ public class ServerChunkCache extends ChunkSource {
- }
- }
- // Paper end - optimise chunk tick iteration
-- this.level.timings.broadcastChunkUpdates.stopTiming(); // Paper - timing
-+ this.level.timings.broadcastChunkUpdates.stopTiming(); // Paper - timing
- // Paper - optimise chunk tick iteration
- gameprofilerfiller.pop();
- gameprofilerfiller.pop();
-diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
-index 584a768f2ce1c98a1de7749060c47f21721f9055..529b7caf18443b23422402ba62747b788ade69f3 100644
---- a/src/main/java/net/minecraft/server/level/ServerLevel.java
-+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
-@@ -317,7 +317,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
- java.util.function.Consumer consumer = (net.minecraft.world.level.chunk.ChunkAccess chunk) -> {
- if (chunk != null) {
- synchronized (ret) { // Folia - region threading - make callback thread-safe TODO rebase
-- ret.add(chunk);
-+ ret.add(chunk);
- } // Folia - region threading - make callback thread-safe TODO rebase
- chunkProvider.addTicketAtLevel(TicketType.FUTURE_AWAIT, chunk.getPos(), ticketLevel, holderIdentifier);
- }
-@@ -687,6 +687,14 @@ public class ServerLevel extends Level implements WorldGenLevel {
-
- // Add env and gen to constructor, IWorldDataServer -> WorldDataServer
- public ServerLevel(MinecraftServer minecraftserver, Executor executor, LevelStorageSource.LevelStorageAccess convertable_conversionsession, PrimaryLevelData iworlddataserver, ResourceKey resourcekey, LevelStem worlddimension, ChunkProgressListener worldloadlistener, boolean flag, long i, List list, boolean flag1, @Nullable RandomSequences randomsequences, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider) {
-+ // ASWM START
-+ this(null, minecraftserver, executor, convertable_conversionsession, iworlddataserver, resourcekey, worlddimension, worldloadlistener, flag, randomsequences, i, list, flag1, env, gen, biomeProvider);
-+ }
-+
-+ public com.infernalsuite.aswm.level.SlimeInMemoryWorld slimeInstance;
-+
-+ public ServerLevel(com.infernalsuite.aswm.level.SlimeBootstrap bootstrap, MinecraftServer minecraftserver, Executor executor, LevelStorageSource.LevelStorageAccess convertable_conversionsession, PrimaryLevelData iworlddataserver, ResourceKey resourcekey, LevelStem worlddimension, ChunkProgressListener worldloadlistener, boolean flag, @Nullable RandomSequences randomsequences, long i, List list, boolean flag1, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider) {
-+ // ASWM END
- // IRegistryCustom.Dimension iregistrycustom_dimension = minecraftserver.registryAccess(); // CraftBukkit - decompile error
- // Holder holder = worlddimension.type(); // CraftBukkit - decompile error
-
-@@ -725,6 +733,12 @@ public class ServerLevel extends Level implements WorldGenLevel {
- chunkgenerator = new org.bukkit.craftbukkit.generator.CustomChunkGenerator(this, chunkgenerator, gen);
- }
- // CraftBukkit end
-+ // ASWM START
-+ ChunkGenerator result = this.getGenerator(bootstrap);
-+ if (result != null) {
-+ chunkgenerator = result;
-+ }
-+ // ASWM END
- boolean flag2 = minecraftserver.forceSynchronousWrites();
- DataFixer datafixer = minecraftserver.getFixerUpper();
- this.entityStorage = new EntityRegionFileStorage(convertable_conversionsession.getDimensionPath(resourcekey).resolve("entities"), flag2); // Paper - rewrite chunk system //EntityPersistentStorage entitypersistentstorage = new EntityStorage(this, convertable_conversionsession.getDimensionPath(resourcekey).resolve("entities"), datafixer, flag2, minecraftserver);
-@@ -736,7 +750,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
- //PersistentEntitySectionManager persistententitysectionmanager = this.entityManager; // Paper - rewrite chunk system
-
- //Objects.requireNonNull(this.entityManager); // Paper - rewrite chunk system
-- this.chunkSource = new ServerChunkCache(this, convertable_conversionsession, datafixer, structuretemplatemanager, executor, chunkgenerator, j, k, flag2, worldloadlistener, null, () -> { // Paper - rewrite chunk system
-+ this.chunkSource = new ServerChunkCache(bootstrap, this, convertable_conversionsession, datafixer, structuretemplatemanager, executor, chunkgenerator, j, k, flag2, worldloadlistener, null, () -> { // Paper - rewrite chunk system // ASWM
- return minecraftserver.overworld().getDataStorage();
- });
- this.chunkSource.getGeneratorState().ensureStructuresGenerated();
-@@ -784,6 +798,12 @@ public class ServerLevel extends Level implements WorldGenLevel {
- this.dragonFight = enderDragonFight;
- }
-
-+ // ASWM START
-+ public ChunkGenerator getGenerator(com.infernalsuite.aswm.level.SlimeBootstrap bootstrap) {
-+ return null;
-+ }
-+ // ASWM END
-+
- public void setWeatherParameters(int clearDuration, int rainDuration, boolean raining, boolean thundering) {
- this.serverLevelData.setClearWeatherTime(clearDuration);
- this.serverLevelData.setRainTime(rainDuration);
-@@ -1006,12 +1026,12 @@ public class ServerLevel extends Level implements WorldGenLevel {
- gameprofilerfiller.popPush("iceandsnow");
-
- if (!this.paperConfig().environment.disableIceAndSnow) { // Paper
-- for (int l = 0; l < randomTickSpeed; ++l) {
-- if (this.random.nextInt(48) == 0) {
-- this.getRandomBlockPosition(j, 0, k, 15, blockposition);
-- this.tickIceAndSnow(flag, blockposition, chunk);
-+ for (int l = 0; l < randomTickSpeed; ++l) {
-+ if (this.random.nextInt(48) == 0) {
-+ this.getRandomBlockPosition(j, 0, k, 15, blockposition);
-+ this.tickIceAndSnow(flag, blockposition, chunk);
-+ }
- }
-- }
- } // Paper
-
- // Paper start - optimise random block ticking
-@@ -1357,9 +1377,9 @@ public class ServerLevel extends Level implements WorldGenLevel {
- currentlyTickingEntity.lazySet(entity);
- }
- // Paper end - log detailed entity tick information
-- ++TimingHistory.entityTicks; // Paper - timings
-- // Spigot start
-- co.aikar.timings.Timing timer; // Paper
-+ ++TimingHistory.entityTicks; // Paper - timings
-+ // Spigot start
-+ co.aikar.timings.Timing timer; // Paper
- /*if (!org.spigotmc.ActivationRange.checkIfActive(entity)) { // Paper - comment out - EAR 2, reimplement below
- entity.tickCount++;
- timer = entity.getType().inactiveTickTimer.startTiming(); try { // Paper - timings
-@@ -1367,36 +1387,36 @@ public class ServerLevel extends Level implements WorldGenLevel {
- } finally { timer.stopTiming(); } // Paper
- return;
- }*/ // Paper - comment out EAR 2
-- // Spigot end
-- // Paper start- timings
-- final boolean isActive = org.spigotmc.ActivationRange.checkIfActive(entity);
-- timer = isActive ? entity.getType().tickTimer.startTiming() : entity.getType().inactiveTickTimer.startTiming(); // Paper
-- try {
-- // Paper end - timings
-- entity.setOldPosAndRot();
-- ProfilerFiller gameprofilerfiller = this.getProfiler();
-+ // Spigot end
-+ // Paper start- timings
-+ final boolean isActive = org.spigotmc.ActivationRange.checkIfActive(entity);
-+ timer = isActive ? entity.getType().tickTimer.startTiming() : entity.getType().inactiveTickTimer.startTiming(); // Paper
-+ try {
-+ // Paper end - timings
-+ entity.setOldPosAndRot();
-+ ProfilerFiller gameprofilerfiller = this.getProfiler();
-
-- ++entity.tickCount;
-- this.getProfiler().push(() -> {
-- return BuiltInRegistries.ENTITY_TYPE.getKey(entity.getType()).toString();
-- });
-- gameprofilerfiller.incrementCounter("tickNonPassenger");
-- if (isActive) { // Paper - EAR 2
-- TimingHistory.activatedEntityTicks++;
-- entity.tick();
-- entity.postTick(); // CraftBukkit
-- } else { entity.inactiveTick(); } // Paper - EAR 2
-- this.getProfiler().pop();
-- } finally { timer.stopTiming(); } // Paper - timings
-- Iterator iterator = entity.getPassengers().iterator();
-+ ++entity.tickCount;
-+ this.getProfiler().push(() -> {
-+ return BuiltInRegistries.ENTITY_TYPE.getKey(entity.getType()).toString();
-+ });
-+ gameprofilerfiller.incrementCounter("tickNonPassenger");
-+ if (isActive) { // Paper - EAR 2
-+ TimingHistory.activatedEntityTicks++;
-+ entity.tick();
-+ entity.postTick(); // CraftBukkit
-+ } else { entity.inactiveTick(); } // Paper - EAR 2
-+ this.getProfiler().pop();
-+ } finally { timer.stopTiming(); } // Paper - timings
-+ Iterator iterator = entity.getPassengers().iterator();
-
-- while (iterator.hasNext()) {
-- Entity entity1 = (Entity) iterator.next();
-+ while (iterator.hasNext()) {
-+ Entity entity1 = (Entity) iterator.next();
-
-- this.tickPassenger(entity, entity1);
-- }
-- // } finally { timer.stopTiming(); } // Paper - timings - move up
-- // Paper start - log detailed entity tick information
-+ this.tickPassenger(entity, entity1);
-+ }
-+ // } finally { timer.stopTiming(); } // Paper - timings - move up
-+ // Paper start - log detailed entity tick information
- } finally {
- if (currentlyTickingEntity.get() == entity) {
- currentlyTickingEntity.lazySet(null);
-@@ -1412,36 +1432,36 @@ public class ServerLevel extends Level implements WorldGenLevel {
- final boolean isActive = org.spigotmc.ActivationRange.checkIfActive(passenger);
- co.aikar.timings.Timing timer = isActive ? passenger.getType().passengerTickTimer.startTiming() : passenger.getType().passengerInactiveTickTimer.startTiming(); // Paper
- try {
-- // Paper end
-- passenger.setOldPosAndRot();
-- ++passenger.tickCount;
-- ProfilerFiller gameprofilerfiller = this.getProfiler();
--
-- gameprofilerfiller.push(() -> {
-- return BuiltInRegistries.ENTITY_TYPE.getKey(passenger.getType()).toString();
-- });
-- gameprofilerfiller.incrementCounter("tickPassenger");
-- // Paper start - EAR 2
-- if (isActive) {
-- passenger.rideTick();
-- passenger.postTick(); // CraftBukkit
-- } else {
-- passenger.setDeltaMovement(Vec3.ZERO);
-- passenger.inactiveTick();
-- // copied from inside of if (isPassenger()) of passengerTick, but that ifPassenger is unnecessary
-- vehicle.positionRider(passenger);
-- }
-- // Paper end - EAR 2
-- gameprofilerfiller.pop();
-- Iterator iterator = passenger.getPassengers().iterator();
-+ // Paper end
-+ passenger.setOldPosAndRot();
-+ ++passenger.tickCount;
-+ ProfilerFiller gameprofilerfiller = this.getProfiler();
-+
-+ gameprofilerfiller.push(() -> {
-+ return BuiltInRegistries.ENTITY_TYPE.getKey(passenger.getType()).toString();
-+ });
-+ gameprofilerfiller.incrementCounter("tickPassenger");
-+ // Paper start - EAR 2
-+ if (isActive) {
-+ passenger.rideTick();
-+ passenger.postTick(); // CraftBukkit
-+ } else {
-+ passenger.setDeltaMovement(Vec3.ZERO);
-+ passenger.inactiveTick();
-+ // copied from inside of if (isPassenger()) of passengerTick, but that ifPassenger is unnecessary
-+ vehicle.positionRider(passenger);
-+ }
-+ // Paper end - EAR 2
-+ gameprofilerfiller.pop();
-+ Iterator iterator = passenger.getPassengers().iterator();
-
-- while (iterator.hasNext()) {
-- Entity entity2 = (Entity) iterator.next();
-+ while (iterator.hasNext()) {
-+ Entity entity2 = (Entity) iterator.next();
-
-- this.tickPassenger(passenger, entity2);
-- }
-+ this.tickPassenger(passenger, entity2);
-+ }
-
-- } finally { timer.stopTiming(); }// Paper - EAR2 timings
-+ } finally { timer.stopTiming(); }// Paper - EAR2 timings
- }
- } else {
- passenger.stopRiding();
-@@ -1495,18 +1515,18 @@ public class ServerLevel extends Level implements WorldGenLevel {
- if (!savingDisabled) {
- org.bukkit.Bukkit.getPluginManager().callEvent(new org.bukkit.event.world.WorldSaveEvent(this.getWorld())); // CraftBukkit
- try (co.aikar.timings.Timing ignored = timings.worldSave.startTiming()) { // Paper
-- if (progressListener != null) {
-- progressListener.progressStartNoAbort(Component.translatable("menu.savingLevel"));
-- }
-+ if (progressListener != null) {
-+ progressListener.progressStartNoAbort(Component.translatable("menu.savingLevel"));
-+ }
-
-- this.saveLevelData();
-- if (progressListener != null) {
-- progressListener.progressStage(Component.translatable("menu.savingChunks"));
-- }
-+ this.saveLevelData();
-+ if (progressListener != null) {
-+ progressListener.progressStage(Component.translatable("menu.savingChunks"));
-+ }
-
- timings.worldSaveChunks.startTiming(); // Paper
-- if (!close) chunkproviderserver.save(flush); // Paper - rewrite chunk system
-- if (close) chunkproviderserver.close(true); // Paper - rewrite chunk system
-+ if (!close) chunkproviderserver.save(flush); // Paper - rewrite chunk system
-+ if (close) chunkproviderserver.close(true); // Paper - rewrite chunk system
- timings.worldSaveChunks.stopTiming(); // Paper
- }// Paper
- // Paper - rewrite chunk system - entity saving moved into ChunkHolder
-@@ -1834,47 +1854,47 @@ public class ServerLevel extends Level implements WorldGenLevel {
-
- this.getChunkSource().blockChanged(pos);
- if(this.paperConfig().misc.updatePathfindingOnBlockUpdate) { // Paper - option to disable pathfinding updates
-- VoxelShape voxelshape = oldState.getCollisionShape(this, pos);
-- VoxelShape voxelshape1 = newState.getCollisionShape(this, pos);
-+ VoxelShape voxelshape = oldState.getCollisionShape(this, pos);
-+ VoxelShape voxelshape1 = newState.getCollisionShape(this, pos);
-
-- if (Shapes.joinIsNotEmpty(voxelshape, voxelshape1, BooleanOp.NOT_SAME)) {
-- List list = new ObjectArrayList();
-- Iterator iterator = this.navigatingMobs.iterator();
-+ if (Shapes.joinIsNotEmpty(voxelshape, voxelshape1, BooleanOp.NOT_SAME)) {
-+ List list = new ObjectArrayList();
-+ Iterator iterator = this.navigatingMobs.iterator();
-
-- while (iterator.hasNext()) {
-- // CraftBukkit start - fix SPIGOT-6362
-- Mob entityinsentient;
-- try {
-- entityinsentient = (Mob) iterator.next();
-- } catch (java.util.ConcurrentModificationException ex) {
-- // This can happen because the pathfinder update below may trigger a chunk load, which in turn may cause more navigators to register
-- // In this case we just run the update again across all the iterators as the chunk will then be loaded
-- // As this is a relative edge case it is much faster than copying navigators (on either read or write)
-- this.sendBlockUpdated(pos, oldState, newState, flags);
-- return;
-- }
-- // CraftBukkit end
-- PathNavigation navigationabstract = entityinsentient.getNavigation();
-+ while (iterator.hasNext()) {
-+ // CraftBukkit start - fix SPIGOT-6362
-+ Mob entityinsentient;
-+ try {
-+ entityinsentient = (Mob) iterator.next();
-+ } catch (java.util.ConcurrentModificationException ex) {
-+ // This can happen because the pathfinder update below may trigger a chunk load, which in turn may cause more navigators to register
-+ // In this case we just run the update again across all the iterators as the chunk will then be loaded
-+ // As this is a relative edge case it is much faster than copying navigators (on either read or write)
-+ this.sendBlockUpdated(pos, oldState, newState, flags);
-+ return;
-+ }
-+ // CraftBukkit end
-+ PathNavigation navigationabstract = entityinsentient.getNavigation();
-
-- if (navigationabstract.shouldRecomputePath(pos)) {
-- list.add(navigationabstract);
-+ if (navigationabstract.shouldRecomputePath(pos)) {
-+ list.add(navigationabstract);
-+ }
- }
-- }
-
-- try {
-- this.isUpdatingNavigations = true;
-- iterator = list.iterator();
-+ try {
-+ this.isUpdatingNavigations = true;
-+ iterator = list.iterator();
-
-- while (iterator.hasNext()) {
-- PathNavigation navigationabstract1 = (PathNavigation) iterator.next();
-+ while (iterator.hasNext()) {
-+ PathNavigation navigationabstract1 = (PathNavigation) iterator.next();
-
-- navigationabstract1.recomputePath();
-+ navigationabstract1.recomputePath();
-+ }
-+ } finally {
-+ this.isUpdatingNavigations = false;
- }
-- } finally {
-- this.isUpdatingNavigations = false;
-- }
-
-- }
-+ }
- } // Paper
- }
-
-diff --git a/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java b/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java
-index 16fbc633de3a1d9e5e8c65ae107397a6f0e50811..d04c0147a87d4b31e6b5b090abeec316d235f1bd 100644
---- a/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java
-+++ b/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java
-@@ -31,7 +31,8 @@ public class PalettedContainer implements PaletteResize, PalettedContainer
- };
- public final IdMap registry;
- private final T @org.jetbrains.annotations.Nullable [] presetValues; // Paper - Anti-Xray - Add preset values
-- private volatile PalettedContainer.Data data;
-+
-+ public volatile PalettedContainer.Data data; // ASWM
- private final PalettedContainer.Strategy strategy;
- // private final ThreadingDetector threadingDetector = new ThreadingDetector("PalettedContainer"); // Paper - unused
-
-@@ -399,7 +400,7 @@ public class PalettedContainer implements PaletteResize, PalettedContainer
- void accept(T object, int count);
- }
-
-- static record Data(PalettedContainer.Configuration configuration, BitStorage storage, Palette palette) {
-+ public static record Data(PalettedContainer.Configuration configuration, BitStorage storage, Palette palette) { // ASWM
- public void copyFrom(Palette palette, BitStorage storage) {
- for(int i = 0; i < storage.getSize(); ++i) {
- T object = palette.valueFor(storage.get(i));
-diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
-index 1379084a80ce25644f13736b4a5ee5fabbd9ec1f..464e1c7970af5aa06ef563b823d7fd8b2776f8f5 100644
---- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
-+++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
-@@ -1,6 +1,9 @@
- package net.minecraft.world.level.chunk.storage;
-
- import com.google.common.collect.Maps;
-+import com.infernalsuite.aswm.api.world.SlimeWorld;
-+import com.infernalsuite.aswm.level.NMSSlimeWorld;
-+import com.infernalsuite.aswm.level.SlimeLevelInstance;
- import com.mojang.logging.LogUtils;
- import com.mojang.serialization.Codec;
- import com.mojang.serialization.DataResult;
-@@ -134,6 +137,7 @@ public class ChunkSerializer {
- public static ProtoChunk read(ServerLevel world, PoiManager poiStorage, ChunkPos chunkPos, CompoundTag nbt) {
- // Paper start - add variant for async calls
- InProgressChunkHolder holder = loadChunk(world, poiStorage, chunkPos, nbt, true);
-+
- return holder.protoChunk;
- }
- // Paper start
-@@ -229,36 +233,40 @@ public class ChunkSerializer {
- // Paper start - rewrite the light engine
- if (flag) {
- try {
-- int y = sectionData.getByte("Y");
-- // Paper end - rewrite the light engine
-- if (flag3) {
-- // Paper start - rewrite the light engine
-- // this is where our diff is
-- blockNibbles[y - minSection] = new ca.spottedleaf.starlight.common.light.SWMRNibbleArray(sectionData.getByteArray("BlockLight").clone(), sectionData.getInt(BLOCKLIGHT_STATE_TAG)); // clone for data safety
-- } else {
-- blockNibbles[y - minSection] = new ca.spottedleaf.starlight.common.light.SWMRNibbleArray(null, sectionData.getInt(BLOCKLIGHT_STATE_TAG));
-+ int y = sectionData.getByte("Y");
- // Paper end - rewrite the light engine
-- }
-+ if (flag3) {
-+ // Paper start - rewrite the light engine
-+ // this is where our diff is
-+ blockNibbles[y - minSection] = new ca.spottedleaf.starlight.common.light.SWMRNibbleArray(sectionData.getByteArray("BlockLight").clone(), sectionData.getInt(BLOCKLIGHT_STATE_TAG)); // clone for data safety
-+ } else {
-+ blockNibbles[y - minSection] = new ca.spottedleaf.starlight.common.light.SWMRNibbleArray(null, sectionData.getInt(BLOCKLIGHT_STATE_TAG));
-+ // Paper end - rewrite the light engine
-+ }
-
-- if (flag4) {
-- // Paper start - rewrite the light engine
-- // we store under the same key so mod programs editing nbt
-- // can still read the data, hopefully.
-- // however, for compatibility we store chunks as unlit so vanilla
-- // is forced to re-light them if it encounters our data. It's too much of a burden
-- // to try and maintain compatibility with a broken and inferior skylight management system.
-- skyNibbles[y - minSection] = new ca.spottedleaf.starlight.common.light.SWMRNibbleArray(sectionData.getByteArray("SkyLight").clone(), sectionData.getInt(SKYLIGHT_STATE_TAG)); // clone for data safety
-- } else if (flag1) {
-- skyNibbles[y - minSection] = new ca.spottedleaf.starlight.common.light.SWMRNibbleArray(null, sectionData.getInt(SKYLIGHT_STATE_TAG));
-- // Paper end - rewrite the light engine
-- }
-+ if (flag4) {
-+ // Paper start - rewrite the light engine
-+ // we store under the same key so mod programs editing nbt
-+ // can still read the data, hopefully.
-+ // however, for compatibility we store chunks as unlit so vanilla
-+ // is forced to re-light them if it encounters our data. It's too much of a burden
-+ // to try and maintain compatibility with a broken and inferior skylight management system.
-+ skyNibbles[y - minSection] = new ca.spottedleaf.starlight.common.light.SWMRNibbleArray(sectionData.getByteArray("SkyLight").clone(), sectionData.getInt(SKYLIGHT_STATE_TAG)); // clone for data safety
-+ } else if (flag1) {
-+ skyNibbles[y - minSection] = new ca.spottedleaf.starlight.common.light.SWMRNibbleArray(null, sectionData.getInt(SKYLIGHT_STATE_TAG));
-+ // Paper end - rewrite the light engine
-+ }
-
-- // Paper start - rewrite the light engine
-+ // Paper start - rewrite the light engine
- } catch (Exception ex) {
- LOGGER.warn("Failed to load light data for chunk " + chunkPos + " in world '" + world.getWorld().getName() + "', light will be regenerated", ex);
- flag = false;
- }
- // Paper end - rewrite light engine
-+
-+ if(world instanceof SlimeLevelInstance) {
-+ poiStorage.checkConsistencyWithBlocks(SectionPos.of(chunkPos.getWorldPosition()), achunksection[j]);
-+ }
- }
- }
-
-@@ -441,7 +449,7 @@ public class ChunkSerializer {
- ChunkSerializer.LOGGER.error("Recoverable errors when loading section [" + chunkPos.x + ", " + y + ", " + chunkPos.z + "]: " + message);
- }
-
-- private static Codec>> makeBiomeCodec(Registry biomeRegistry) {
-+ public static Codec>> makeBiomeCodec(Registry biomeRegistry) { // ASWM
- return PalettedContainer.codecRO(biomeRegistry.asHolderIdMap(), biomeRegistry.holderByNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, biomeRegistry.getHolderOrThrow(Biomes.PLAINS));
- }
-
-@@ -620,7 +628,7 @@ public class ChunkSerializer {
- nbttagcompound.put(BLOCK_TICKS_TAG, asyncsavedata.blockTickList);
- nbttagcompound.put(FLUID_TICKS_TAG, asyncsavedata.fluidTickList);
- } else {
-- ChunkSerializer.saveTicks(world, nbttagcompound, chunk.getTicksForSerialization());
-+ ChunkSerializer.saveTicks(world, nbttagcompound, chunk.getTicksForSerialization());
- }
- // Paper end
- nbttagcompound.put("PostProcessing", ChunkSerializer.packOffsets(chunk.getPostProcessing()));
-diff --git a/src/main/resources/META-INF/services/com.infernalsuite.aswm.api.SlimeNMSBridge b/src/main/resources/META-INF/services/com.infernalsuite.aswm.api.SlimeNMSBridge
-new file mode 100644
-index 0000000000000000000000000000000000000000..916b4d2edba2f2a8a0fc1fdb6ab6a57e2a16f938
---- /dev/null
-+++ b/src/main/resources/META-INF/services/com.infernalsuite.aswm.api.SlimeNMSBridge
-@@ -0,0 +1 @@
-+com.infernalsuite.aswm.SlimeNMSBridgeImpl
diff --git a/patches/server/0002-Build-changes.patch b/patches/server/0002-Build-changes.patch
index 54f7e1e..d7a0031 100644
--- a/patches/server/0002-Build-changes.patch
+++ b/patches/server/0002-Build-changes.patch
@@ -1,17 +1,17 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Luna
-Date: Sat, 12 Mar 2022 22:22:22 -0300
+From: Telesphoreo
+Date: Thu, 21 Dec 2023 23:23:17 -0600
Subject: [PATCH] Build changes
diff --git a/build.gradle.kts b/build.gradle.kts
-index 79beac737c17412913983614bd478d33e3c6ed58..27d5dd68175641152cb78e6aba69890c00ef9b51 100644
+index b12b5a1e82a5ebf47135a3863a390a45a9d8d8ec..780ef52f50556633c2e402790e339ef513f6bf24 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
-@@ -13,8 +13,13 @@ configurations.named(log4jPlugins.compileClasspathConfigurationName) {
- val alsoShade: Configuration by configurations.creating
+@@ -27,8 +27,13 @@ repositories {
dependencies {
+ extraRuntime(platform("net.kyori:adventure-bom:4.15.0-SNAPSHOT"))
- implementation(project(":paper-api"))
- implementation(project(":paper-mojangapi"))
+ implementation(project(":aswm-core"))
@@ -24,7 +24,7 @@ index 79beac737c17412913983614bd478d33e3c6ed58..27d5dd68175641152cb78e6aba69890c
// Paper start
implementation("org.jline:jline-terminal-jansi:3.21.0")
implementation("net.minecrell:terminalconsoleappender:1.3.0")
-@@ -66,11 +71,19 @@ tasks.jar {
+@@ -80,11 +85,19 @@ tasks.jar {
val gitHash = git("rev-parse", "--short=7", "HEAD").getText().trim()
val implementationVersion = System.getenv("BUILD_NUMBER") ?: "\"$gitHash\""
val date = git("show", "-s", "--format=%ci", gitHash).getText().trim() // Paper
@@ -46,7 +46,7 @@ index 79beac737c17412913983614bd478d33e3c6ed58..27d5dd68175641152cb78e6aba69890c
"Implementation-Vendor" to date, // Paper
"Specification-Title" to "Bukkit",
"Specification-Version" to project.version,
-@@ -154,7 +167,7 @@ fun TaskContainer.registerRunTask(
+@@ -168,7 +181,7 @@ fun TaskContainer.registerRunTask(
name: String,
block: JavaExec.() -> Unit
): TaskProvider = register(name) {
@@ -96,10 +96,10 @@ index c5d5648f4ca603ef2b1df723b58f9caf4dd3c722..21ded7c14c56a40feaa7741131be5166
.completer(new ConsoleCommandCompleter(this.server))
.option(LineReader.Option.COMPLETE_IN_WORD, true);
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
-index 3d5d79e428a7b0f1aa7d0d3911e6d61b9537e8a0..97231b3a80c248efca4a7ef644272801644386d5 100644
+index 34f19ac897a30c0c4e3ab406013fcca1c8b7db93..6f284b7cd52ea47bd96ecd3b7a21d68ae5c12d77 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
-@@ -1712,7 +1712,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop
-Date: Sat, 12 Mar 2022 19:34:59 -0700
-Subject: [PATCH] UUID validation
-
-
-diff --git a/src/main/java/net/minecraft/nbt/NbtUtils.java b/src/main/java/net/minecraft/nbt/NbtUtils.java
-index b65dcff9812dbc3256c080ac264c4aafd83ce276..82b53a7bfb37bfa1752a016a8a454c0b994b9108 100644
---- a/src/main/java/net/minecraft/nbt/NbtUtils.java
-+++ b/src/main/java/net/minecraft/nbt/NbtUtils.java
-@@ -74,7 +74,11 @@ public final class NbtUtils {
- UUID uUID = nbt.hasUUID("Id") ? nbt.getUUID("Id") : Util.NIL_UUID;
- // Paper start - support string UUID's
- if (nbt.contains("Id", Tag.TAG_STRING)) {
-- uUID = UUID.fromString(nbt.getString("Id"));
-+ // Scissors start - Validate String UUIDs in game profiles
-+ try {
-+ uUID = UUID.fromString(nbt.getString("Id"));
-+ } catch (Exception ignored) {}
-+ // Scissors end
- }
- // Paper end
- String string = nbt.getString("Name");
-diff --git a/src/main/java/net/minecraft/network/chat/HoverEvent.java b/src/main/java/net/minecraft/network/chat/HoverEvent.java
-index 3ad05bbab726c59e7b67d9614af4b208d4520cb3..c0633f9553fb5aa52e8ffc863159521d09cb3bd5 100644
---- a/src/main/java/net/minecraft/network/chat/HoverEvent.java
-+++ b/src/main/java/net/minecraft/network/chat/HoverEvent.java
-@@ -174,7 +174,14 @@ public class HoverEvent {
- } else {
- JsonObject jsonObject = json.getAsJsonObject();
- EntityType> entityType = BuiltInRegistries.ENTITY_TYPE.get(new ResourceLocation(GsonHelper.getAsString(jsonObject, "type")));
-- UUID uUID = UUID.fromString(GsonHelper.getAsString(jsonObject, "id"));
-+ // Scissors start
-+ UUID uUID;
-+ try {
-+ uUID = UUID.fromString(GsonHelper.getAsString(jsonObject, "id"));
-+ } catch (Exception ex) {
-+ return null;
-+ }
-+ // Scissors end
- Component component = Component.Serializer.fromJson(jsonObject.get("name"));
- return new HoverEvent.EntityTooltipInfo(entityType, uUID, component);
- }
-@@ -186,7 +193,14 @@ public class HoverEvent {
- CompoundTag compoundTag = TagParser.parseTag(text.getString());
- Component component = Component.Serializer.fromJson(compoundTag.getString("name"));
- EntityType> entityType = BuiltInRegistries.ENTITY_TYPE.get(new ResourceLocation(compoundTag.getString("type")));
-- UUID uUID = UUID.fromString(compoundTag.getString("id"));
-+ // Scissors start
-+ UUID uUID;
-+ try {
-+ uUID = UUID.fromString(compoundTag.getString("id"));
-+ } catch (Exception ex) {
-+ return null;
-+ }
-+ // Scissors end
- return new HoverEvent.EntityTooltipInfo(entityType, uUID, component);
- } catch (Exception var5) {
- return null;
diff --git a/patches/server/0004-ResourceLocation-validation.patch b/patches/server/0004-ResourceLocation-validation.patch
deleted file mode 100644
index bc946a2..0000000
--- a/patches/server/0004-ResourceLocation-validation.patch
+++ /dev/null
@@ -1,187 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Video
-Date: Sun, 13 Mar 2022 07:39:26 -0600
-Subject: [PATCH] ResourceLocation validation
-
-
-diff --git a/src/main/java/com/destroystokyo/paper/loottable/PaperContainerEntityLootableInventory.java b/src/main/java/com/destroystokyo/paper/loottable/PaperContainerEntityLootableInventory.java
-index 15173e715fa36546820d930a46e0f0c493d07cfc..356cc6f468975faa676db87db8fc0fa2df32f020 100644
---- a/src/main/java/com/destroystokyo/paper/loottable/PaperContainerEntityLootableInventory.java
-+++ b/src/main/java/com/destroystokyo/paper/loottable/PaperContainerEntityLootableInventory.java
-@@ -17,7 +17,7 @@ public class PaperContainerEntityLootableInventory implements PaperLootableEntit
-
- @Override
- public org.bukkit.loot.LootTable getLootTable() {
-- return entity.getLootTable() != null && !entity.getLootTable().getPath().isEmpty() ? Bukkit.getLootTable(CraftNamespacedKey.fromMinecraft(entity.getLootTable())) : null;
-+ return entity.getLootTable() != null && !entity.getLootTable().getPath().isEmpty() && entity.getLootTable().toString().length() < 256 ? Bukkit.getLootTable(CraftNamespacedKey.fromMinecraft(entity.getLootTable())) : null; // Scissors - Validate length of loot tables before even trying
- }
-
- @Override
-diff --git a/src/main/java/com/destroystokyo/paper/loottable/PaperTileEntityLootableInventory.java b/src/main/java/com/destroystokyo/paper/loottable/PaperTileEntityLootableInventory.java
-index 2ee4ee14ab3345486dad6b24fd9a4fcc6c746b99..c5ac6cda91a81d3075f5c763e30dc009b6be7936 100644
---- a/src/main/java/com/destroystokyo/paper/loottable/PaperTileEntityLootableInventory.java
-+++ b/src/main/java/com/destroystokyo/paper/loottable/PaperTileEntityLootableInventory.java
-@@ -15,7 +15,7 @@ public class PaperTileEntityLootableInventory implements PaperLootableBlockInven
-
- @Override
- public org.bukkit.loot.LootTable getLootTable() {
-- return tileEntityLootable.lootTable != null && !tileEntityLootable.lootTable.getPath().isEmpty() ? Bukkit.getLootTable(CraftNamespacedKey.fromMinecraft(tileEntityLootable.lootTable)) : null;
-+ return tileEntityLootable.lootTable != null && !tileEntityLootable.lootTable.getPath().isEmpty() && tileEntityLootable.lootTable.toString().length() < 256 ? Bukkit.getLootTable(CraftNamespacedKey.fromMinecraft(tileEntityLootable.lootTable)) : null; // Scissors - Validate length of loot tables before even trying
- }
-
- @Override
-diff --git a/src/main/java/net/minecraft/world/entity/AreaEffectCloud.java b/src/main/java/net/minecraft/world/entity/AreaEffectCloud.java
-index 1f55185814125c691288294d18bf1580461c8066..259d65f8e21f9cf99585d416eafdc967dddccf57 100644
---- a/src/main/java/net/minecraft/world/entity/AreaEffectCloud.java
-+++ b/src/main/java/net/minecraft/world/entity/AreaEffectCloud.java
-@@ -409,7 +409,7 @@ public class AreaEffectCloud extends Entity implements TraceableEntity {
- try {
- this.setParticle(ParticleArgument.readParticle(new StringReader(nbt.getString("Particle")), (HolderLookup) BuiltInRegistries.PARTICLE_TYPE.asLookup()));
- } catch (CommandSyntaxException commandsyntaxexception) {
-- AreaEffectCloud.LOGGER.warn("Couldn't load custom particle {}", nbt.getString("Particle"), commandsyntaxexception);
-+ // Scissors - Don't log custom particle errors
- }
- }
-
-diff --git a/src/main/java/net/minecraft/world/entity/EntityType.java b/src/main/java/net/minecraft/world/entity/EntityType.java
-index 73871f456a85bda1e51f54986d0e61fb629822e8..df16049a70061c7c38d72b188d054339f5434e03 100644
---- a/src/main/java/net/minecraft/world/entity/EntityType.java
-+++ b/src/main/java/net/minecraft/world/entity/EntityType.java
-@@ -589,7 +589,7 @@ public class EntityType implements FeatureElement, EntityTypeT
- }), (entity) -> {
- entity.load(nbt);
- }, () -> {
-- EntityType.LOGGER.warn("Skipping Entity with id {}", nbt.getString("id"));
-+ // Scissors - Don't log invalid entities
- });
- }
-
-@@ -608,7 +608,7 @@ public class EntityType implements FeatureElement, EntityTypeT
- }
-
- public static Optional> by(CompoundTag nbt) {
-- return BuiltInRegistries.ENTITY_TYPE.getOptional(new ResourceLocation(nbt.getString("id")));
-+ return BuiltInRegistries.ENTITY_TYPE.getOptional(ResourceLocation.tryParse(nbt.getString("id"))); // Scissors
- }
-
- @Nullable
-diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java
-index d28c477171c1b6888a45175075017d960464b5cd..cc46185c05a735d4443b266423215f1f7a0c7741 100644
---- a/src/main/java/net/minecraft/world/entity/Mob.java
-+++ b/src/main/java/net/minecraft/world/entity/Mob.java
-@@ -619,7 +619,7 @@ public abstract class Mob extends LivingEntity implements Targeting {
-
- this.setLeftHanded(nbt.getBoolean("LeftHanded"));
- if (nbt.contains("DeathLootTable", 8)) {
-- this.lootTable = new ResourceLocation(nbt.getString("DeathLootTable"));
-+ this.lootTable = ResourceLocation.tryParse(nbt.getString("DeathLootTable")); // Scissors
- this.lootTableSeed = nbt.getLong("DeathLootTableSeed");
- }
-
-diff --git a/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java
-index a18aadbf7ae83713e1f2b21553185d8000bc7699..f5ad7ddf13cbb6452c2927aef9b54eae3335b4c6 100644
---- a/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java
-+++ b/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java
-@@ -289,7 +289,12 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit
- while (iterator.hasNext()) {
- String s = (String) iterator.next();
-
-- this.recipesUsed.put(new ResourceLocation(s), nbttagcompound1.getInt(s));
-+ // Scissors start
-+ final ResourceLocation rl = ResourceLocation.tryParse(s);
-+ if (rl != null) {
-+ this.recipesUsed.put(rl, nbttagcompound1.getInt(s));
-+ }
-+ // Scissors end
- }
-
- // Paper start - cook speed API
-diff --git a/src/main/java/net/minecraft/world/level/block/entity/BrushableBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BrushableBlockEntity.java
-index 0425151e688966442340ea1cf892aff34ffe0791..244b04e0020b1bd1e7be34a1b6266a8ac75d29fc 100644
---- a/src/main/java/net/minecraft/world/level/block/entity/BrushableBlockEntity.java
-+++ b/src/main/java/net/minecraft/world/level/block/entity/BrushableBlockEntity.java
-@@ -199,7 +199,7 @@ public class BrushableBlockEntity extends BlockEntity {
-
- private boolean tryLoadLootTable(CompoundTag nbt) {
- if (nbt.contains("LootTable", 8)) {
-- this.lootTable = new ResourceLocation(nbt.getString("LootTable"));
-+ this.lootTable = ResourceLocation.tryParse(nbt.getString("LootTable")); // Scissors
- this.lootTableSeed = nbt.getLong("LootTableSeed");
- return true;
- } else {
-diff --git a/src/main/java/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java
-index 081691f9710ff1115e4308f79ed49fbc38941193..c29dfd15e147d5c4d9c9584ff7803c2a52009f0d 100644
---- a/src/main/java/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java
-+++ b/src/main/java/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java
-@@ -46,7 +46,7 @@ public abstract class RandomizableContainerBlockEntity extends BaseContainerBloc
- protected boolean tryLoadLootTable(CompoundTag nbt) {
- this.lootableData.loadNbt(nbt); // Paper
- if (nbt.contains("LootTable", 8)) {
-- this.lootTable = new ResourceLocation(nbt.getString("LootTable"));
-+ this.lootTable = ResourceLocation.tryParse(nbt.getString("LootTable")); // Scissors - Validate loot tables
- try { org.bukkit.craftbukkit.util.CraftNamespacedKey.fromMinecraft(this.lootTable); } catch (IllegalArgumentException ex) { this.lootTable = null; } // Paper - validate
- this.lootTableSeed = nbt.getLong("LootTableSeed");
- return false; // Paper - always load the items, table may still remain
-diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftLootable.java b/src/main/java/org/bukkit/craftbukkit/block/CraftLootable.java
-index f6942cb3ef1f9ef03708d4bc932ea9aeb1c13894..8b32864bafb3c1948993688be8f639dd6492057e 100644
---- a/src/main/java/org/bukkit/craftbukkit/block/CraftLootable.java
-+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftLootable.java
-@@ -34,8 +34,14 @@ public abstract class CraftLootable
- return null;
- }
-
-- ResourceLocation key = this.getSnapshot().lootTable;
-- return Bukkit.getLootTable(CraftNamespacedKey.fromMinecraft(key));
-+ // Scissors start - Return a null loot table if the specified loot table is not valid
-+ try {
-+ ResourceLocation key = this.getSnapshot().lootTable;
-+ return Bukkit.getLootTable(CraftNamespacedKey.fromMinecraft(key));
-+ } catch (Exception ex) {
-+ return null;
-+ }
-+ // Scissors end
- }
-
- @Override
-diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartContainer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartContainer.java
-index 313ee5c8737b2e57f9b5db6512c1871766b2ccd4..aa7fa17b9fb8519d8b57e27a5b422249b9b875d8 100644
---- a/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartContainer.java
-+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartContainer.java
-@@ -33,8 +33,14 @@ public abstract class CraftMinecartContainer extends CraftMinecart implements Lo
- return null; // return empty loot table?
- }
-
-- NamespacedKey key = CraftNamespacedKey.fromMinecraft(nmsTable);
-- return Bukkit.getLootTable(key);
-+ // Scissors start - Return a null loot table if the specified loot table is not valid
-+ try {
-+ NamespacedKey key = CraftNamespacedKey.fromMinecraft(nmsTable);
-+ return Bukkit.getLootTable(key);
-+ } catch (Exception ex) {
-+ return null;
-+ }
-+ // Scissors end
- }
-
- @Override
-diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java
-index b4e45d8e9851552f30c9c29d3d9671e1e9094c38..4e8e1a6b718d9ec8720efb648ab023e9e39f67e3 100644
---- a/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java
-+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java
-@@ -80,8 +80,14 @@ public abstract class CraftMob extends CraftLivingEntity implements Mob {
-
- @Override
- public LootTable getLootTable() {
-- NamespacedKey key = CraftNamespacedKey.fromMinecraft(this.getHandle().getLootTable());
-- return Bukkit.getLootTable(key);
-+ // Scissors start - Return a null loot table if the specified loot table is not valid
-+ try {
-+ NamespacedKey key = CraftNamespacedKey.fromMinecraft(this.getHandle().getLootTable());
-+ return Bukkit.getLootTable(key);
-+ } catch (Exception ex) {
-+ return null;
-+ }
-+ // Scissors end
- }
-
- @Override
diff --git a/patches/server/0005-Fixes-log-spam-caused-by-invalid-entities-in-beehive.patch b/patches/server/0005-Fixes-log-spam-caused-by-invalid-entities-in-beehive.patch
deleted file mode 100644
index dc1a5a1..0000000
--- a/patches/server/0005-Fixes-log-spam-caused-by-invalid-entities-in-beehive.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Video
-Date: Sun, 13 Mar 2022 06:10:22 -0600
-Subject: [PATCH] Fixes log spam caused by invalid entities in beehives
-
-
-diff --git a/src/main/java/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java
-index 41c9f074203915c31c1ae7a160ce509c13383f84..8b4989593da43fc2fd661ac66bfe5ae1eb5e2780 100644
---- a/src/main/java/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java
-+++ b/src/main/java/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java
-@@ -11,6 +11,7 @@ import net.minecraft.nbt.CompoundTag;
- import net.minecraft.nbt.ListTag;
- import net.minecraft.nbt.NbtUtils;
- import net.minecraft.network.protocol.game.DebugPackets;
-+import net.minecraft.resources.ResourceLocation; // Scissors
- import net.minecraft.sounds.SoundEvents;
- import net.minecraft.sounds.SoundSource;
- import net.minecraft.tags.BlockTags;
-@@ -370,6 +371,13 @@ public class BeehiveBlockEntity extends BlockEntity {
-
- for (int i = 0; i < nbttaglist.size(); ++i) {
- CompoundTag nbttagcompound1 = nbttaglist.getCompound(i);
-+
-+ // Scissors start - Do not allow invalid entities from being used for bees
-+ if (!nbttagcompound1.contains("id") || !ResourceLocation.isValidResourceLocation(nbttagcompound1.getString("id")) || EntityType.byString(nbttagcompound1.getString("id")).isEmpty()) {
-+ continue;
-+ }
-+ // Scissors end
-+
- BeehiveBlockEntity.BeeData tileentitybeehive_hivebee = new BeehiveBlockEntity.BeeData(nbttagcompound1.getCompound("EntityData"), nbttagcompound1.getInt("TicksInHive"), nbttagcompound1.getInt("MinOccupationTicks"));
-
- this.stored.add(tileentitybeehive_hivebee);
diff --git a/patches/server/0006-Removes-useless-spammy-error-logging.patch b/patches/server/0006-Removes-useless-spammy-error-logging.patch
deleted file mode 100644
index 7a963b9..0000000
--- a/patches/server/0006-Removes-useless-spammy-error-logging.patch
+++ /dev/null
@@ -1,20 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Video
-Date: Sun, 13 Mar 2022 07:47:20 -0600
-Subject: [PATCH] Removes useless spammy error logging
-
-
-diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
-index aeca803cc0434d9de9434987d6e43b70353e305b..5bd581c1a82236359c810037333590d0d9741587 100644
---- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
-+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
-@@ -1814,8 +1814,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
- resource = CraftNamespacedKey.fromMinecraft(key);
- }
- } catch (IllegalArgumentException ex) {
-- org.bukkit.Bukkit.getLogger().warning("Namespaced resource does not validate: " + key.toString());
-- ex.printStackTrace();
-+ // Scissors - Don't log errors thrown by invalid namespaces when an error is thrown
- }
-
- return resource;
diff --git a/patches/server/0007-Ignore-errors-thrown-when-trying-to-remove-minecart-.patch b/patches/server/0007-Ignore-errors-thrown-when-trying-to-remove-minecart-.patch
deleted file mode 100644
index f75a7c5..0000000
--- a/patches/server/0007-Ignore-errors-thrown-when-trying-to-remove-minecart-.patch
+++ /dev/null
@@ -1,24 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Video
-Date: Sun, 13 Mar 2022 08:14:44 -0600
-Subject: [PATCH] Ignore errors thrown when trying to remove minecart entities
- with content in them
-
-
-diff --git a/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecartContainer.java b/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecartContainer.java
-index 272095d7a09ab41227d741172735f66fd2798ce1..757ae1773ba35c2348483dddbb231060afafc602 100644
---- a/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecartContainer.java
-+++ b/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecartContainer.java
-@@ -139,7 +139,11 @@ public abstract class AbstractMinecartContainer extends AbstractMinecart impleme
- @Override
- public void remove(Entity.RemovalReason reason) {
- if (!this.level().isClientSide && reason.shouldDestroy()) {
-- Containers.dropContents(this.level(), (Entity) this, (Container) this);
-+ // Scissors start - Ignore errors thrown when trying to remove minecart entities with content in them
-+ try {
-+ Containers.dropContents(this.level(), (Entity) this, (Container) this);
-+ } catch (Exception ignored) {}
-+ // Scissors end
- }
-
- super.remove(reason);
diff --git a/patches/server/0008-ItemEntity-Check-if-items-are-air-before-calling-set.patch b/patches/server/0008-ItemEntity-Check-if-items-are-air-before-calling-set.patch
deleted file mode 100644
index 8c8d0c8..0000000
--- a/patches/server/0008-ItemEntity-Check-if-items-are-air-before-calling-set.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Luna
-Date: Sun, 13 Mar 2022 14:38:38 -0300
-Subject: [PATCH] ItemEntity - Check if items are air before calling setItem
-
-
-diff --git a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java
-index eb0351aa12eebcefab1d1d14641fc3c60cbbcab8..cf944848cdebbb6f04f5211e00c876329e86d9cc 100644
---- a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java
-+++ b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java
-@@ -425,11 +425,15 @@ public class ItemEntity extends Entity implements TraceableEntity {
-
- CompoundTag nbttagcompound1 = nbt.getCompound("Item");
-
-- this.setItem(ItemStack.of(nbttagcompound1));
-- if (this.getItem().isEmpty()) {
-+ // Scissors start
-+ ItemStack item = ItemStack.of(nbttagcompound1);
-+ if (item.isEmpty()) {
- this.discard();
-+ return;
- }
-
-+ this.setItem(item);
-+ // Scissors end
- }
-
- @Override
diff --git a/patches/server/0009-Fixes-Knowledge-Books-causing-log-spam-when-invalid-.patch b/patches/server/0009-Fixes-Knowledge-Books-causing-log-spam-when-invalid-.patch
deleted file mode 100644
index dd2c69f..0000000
--- a/patches/server/0009-Fixes-Knowledge-Books-causing-log-spam-when-invalid-.patch
+++ /dev/null
@@ -1,49 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Video
-Date: Sun, 13 Mar 2022 18:42:07 -0600
-Subject: [PATCH] Fixes Knowledge Books causing log spam when invalid data is
- provided
-
-
-diff --git a/src/main/java/net/minecraft/world/item/KnowledgeBookItem.java b/src/main/java/net/minecraft/world/item/KnowledgeBookItem.java
-index 37f37be56bab171df442b980ff46ff325daae283..deade19d16a7d6870171b9a60806a8cadb437db4 100644
---- a/src/main/java/net/minecraft/world/item/KnowledgeBookItem.java
-+++ b/src/main/java/net/minecraft/world/item/KnowledgeBookItem.java
-@@ -40,9 +40,9 @@ public class KnowledgeBookItem extends Item {
-
- for(int i = 0; i < listTag.size(); ++i) {
- String string = listTag.getString(i);
-- Optional> optional = recipeManager.byKey(new ResourceLocation(string));
-+ Optional> optional = recipeManager.byKey(ResourceLocation.tryParse(string)); // Scissors - Validate resource locations
- if (!optional.isPresent()) {
-- LOGGER.error("Invalid recipe: {}", (Object)string);
-+ // Scissors - Don't log errors caused by invalid recipes being provided
- return InteractionResultHolder.fail(itemStack);
- }
-
-@@ -55,7 +55,7 @@ public class KnowledgeBookItem extends Item {
-
- return InteractionResultHolder.sidedSuccess(itemStack, world.isClientSide());
- } else {
-- LOGGER.error("Tag not valid: {}", (Object)compoundTag);
-+ // Scissors - Don't throw errors into the logs if an NBT compound isn't present or is missing the Recipes tag.
- return InteractionResultHolder.fail(itemStack);
- }
- }
-diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaKnowledgeBook.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaKnowledgeBook.java
-index 50fdb086ffec84edc5138737c95f08ed4757a6f3..da312b4670fc0ac07e4ab798d4793025e362783e 100644
---- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaKnowledgeBook.java
-+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaKnowledgeBook.java
-@@ -41,7 +41,11 @@ public class CraftMetaKnowledgeBook extends CraftMetaItem implements KnowledgeBo
- for (int i = 0; i < pages.size(); i++) {
- String recipe = pages.getString(i);
-
-- this.addRecipe(CraftNamespacedKey.fromString(recipe));
-+ // Scissors start - Don't add recipes with invalid namespaces
-+ try {
-+ this.addRecipe(CraftNamespacedKey.fromString(recipe));
-+ } catch (Exception ignored) {}
-+ // Scissors end
- }
- }
- }
diff --git a/patches/server/0010-Validate-BlockState-and-SoundEvent-values.patch b/patches/server/0010-Validate-BlockState-and-SoundEvent-values.patch
deleted file mode 100644
index 7bf1fcb..0000000
--- a/patches/server/0010-Validate-BlockState-and-SoundEvent-values.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Video
-Date: Sun, 13 Mar 2022 21:56:29 -0600
-Subject: [PATCH] Validate BlockState and SoundEvent values
-
-
-diff --git a/src/main/java/net/minecraft/nbt/NbtUtils.java b/src/main/java/net/minecraft/nbt/NbtUtils.java
-index 82b53a7bfb37bfa1752a016a8a454c0b994b9108..b8720020f98ea26da7d3225ddfbb1d9e80be4eb1 100644
---- a/src/main/java/net/minecraft/nbt/NbtUtils.java
-+++ b/src/main/java/net/minecraft/nbt/NbtUtils.java
-@@ -231,7 +231,7 @@ public final class NbtUtils {
- if (!nbt.contains("Name", 8)) {
- return Blocks.AIR.defaultBlockState();
- } else {
-- ResourceLocation resourceLocation = new ResourceLocation(nbt.getString("Name"));
-+ ResourceLocation resourceLocation = ResourceLocation.tryParse(nbt.getString("Name")); // Scissors - Validate BlockState
- Optional extends Holder> optional = blockLookup.get(ResourceKey.create(Registries.BLOCK, resourceLocation));
- if (optional.isEmpty()) {
- return Blocks.AIR.defaultBlockState();
-diff --git a/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java b/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java
-index 8affdd74769aed9aa92a76ba539cd9d27208827c..23e480535bfb4071cde84fc400c2e6acb129e1ae 100644
---- a/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java
-+++ b/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java
-@@ -541,7 +541,7 @@ public abstract class AbstractArrow extends Projectile {
- this.setCritArrow(nbt.getBoolean("crit"));
- this.setPierceLevel(nbt.getByte("PierceLevel"));
- if (nbt.contains("SoundEvent", 8)) {
-- this.soundEvent = (SoundEvent) BuiltInRegistries.SOUND_EVENT.getOptional(new ResourceLocation(nbt.getString("SoundEvent"))).orElse(this.getDefaultHitGroundSoundEvent());
-+ this.soundEvent = (SoundEvent) BuiltInRegistries.SOUND_EVENT.getOptional(ResourceLocation.tryParse(nbt.getString("SoundEvent"))).orElse(this.getDefaultHitGroundSoundEvent()); // Scissors - Validate SoundEvents before trying to play them
- }
-
- this.setShotFromCrossbow(nbt.getBoolean("ShotFromCrossbow"));
diff --git a/patches/server/0011-Do-not-log-invalid-items-in-HoverEvent-and-ItemFrame.patch b/patches/server/0011-Do-not-log-invalid-items-in-HoverEvent-and-ItemFrame.patch
deleted file mode 100644
index 0c49198..0000000
--- a/patches/server/0011-Do-not-log-invalid-items-in-HoverEvent-and-ItemFrame.patch
+++ /dev/null
@@ -1,41 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Luna
-Date: Sun, 20 Mar 2022 09:31:16 -0300
-Subject: [PATCH] Do not log invalid items in HoverEvent and ItemFrame
-
-
-diff --git a/src/main/java/net/minecraft/network/chat/HoverEvent.java b/src/main/java/net/minecraft/network/chat/HoverEvent.java
-index c0633f9553fb5aa52e8ffc863159521d09cb3bd5..7449a024265c42f28a6c9a1ed8d8f4b9e3096aac 100644
---- a/src/main/java/net/minecraft/network/chat/HoverEvent.java
-+++ b/src/main/java/net/minecraft/network/chat/HoverEvent.java
-@@ -314,7 +314,7 @@ public class HoverEvent {
- CompoundTag compoundTag = TagParser.parseTag(string);
- return new HoverEvent.ItemStackInfo(item, i, compoundTag);
- } catch (CommandSyntaxException var6) {
-- HoverEvent.LOGGER.warn("Failed to parse tag: {}", string, var6);
-+ // Scissors - Ignore invalid items
- }
- }
-
-@@ -328,7 +328,7 @@ public class HoverEvent {
- CompoundTag compoundTag = TagParser.parseTag(text.getString());
- return new HoverEvent.ItemStackInfo(ItemStack.of(compoundTag));
- } catch (CommandSyntaxException var2) {
-- HoverEvent.LOGGER.warn("Failed to parse item tag: {}", text, var2);
-+ // Scissors - Ignore invalid items
- return null;
- }
- }
-diff --git a/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java b/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java
-index 759ecd79534a7706f7d4a63eb9dacbefcfe54674..9afda54ad70d446672749506822c6abd729b8f1b 100644
---- a/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java
-+++ b/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java
-@@ -441,7 +441,7 @@ public class ItemFrame extends HangingEntity {
- ItemStack itemstack = ItemStack.of(nbttagcompound1);
-
- if (itemstack.isEmpty()) {
-- ItemFrame.LOGGER.warn("Unable to load item from: {}", nbttagcompound1);
-+ // Scissors - ignore invalid items
- }
-
- ItemStack itemstack1 = this.getItem();
diff --git a/patches/server/0012-Change-version-fetcher-to-AMG.patch b/patches/server/0012-Change-version-fetcher-to-AMG.patch
deleted file mode 100644
index 4efd451..0000000
--- a/patches/server/0012-Change-version-fetcher-to-AMG.patch
+++ /dev/null
@@ -1,91 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Telesphoreo
-Date: Sat, 26 Mar 2022 21:51:07 -0500
-Subject: [PATCH] Change version fetcher to AMG
-
-
-diff --git a/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java b/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java
-index 9d687da5bdf398bb3f6c84cdf1249a7213d09f2e..bc5ed619e05f24f3ad50a6a81306d120869f57a1 100644
---- a/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java
-+++ b/src/main/java/com/destroystokyo/paper/PaperVersionFetcher.java
-@@ -4,11 +4,13 @@ import com.destroystokyo.paper.util.VersionFetcher;
- import com.google.common.base.Charsets;
- import com.google.common.io.Resources;
- import com.google.gson.*;
-+import io.papermc.paper.util.JarManifests; // Scissors
- import net.kyori.adventure.text.Component;
- import net.kyori.adventure.text.event.ClickEvent;
- import net.kyori.adventure.text.format.NamedTextColor;
- import net.kyori.adventure.text.format.TextDecoration;
- import net.kyori.adventure.text.TextComponent;
-+import org.bukkit.Bukkit; // Scissors
-
- import javax.annotation.Nonnull;
- import javax.annotation.Nullable;
-@@ -19,8 +21,8 @@ import java.util.stream.StreamSupport;
-
- public class PaperVersionFetcher implements VersionFetcher {
- private static final java.util.regex.Pattern VER_PATTERN = java.util.regex.Pattern.compile("^([0-9\\.]*)\\-.*R"); // R is an anchor, will always give '-R' at end
-- private static final String GITHUB_BRANCH_NAME = "master";
-- private static final String DOWNLOAD_PAGE = "https://papermc.io/downloads/paper";
-+ private static final String GITHUB_BRANCH_NAME = getBranch(); // Scissors
-+ private static final String DOWNLOAD_PAGE = "https://ci.scissors.gg/job/Scissors/job/" + GITHUB_BRANCH_NAME; // Scissors
- private static @Nullable String mcVer;
-
- @Override
-@@ -31,8 +33,8 @@ public class PaperVersionFetcher implements VersionFetcher {
- @Nonnull
- @Override
- public Component getVersionMessage(@Nonnull String serverVersion) {
-- String[] parts = serverVersion.substring("git-Paper-".length()).split("[-\\s]");
-- final Component updateMessage = getUpdateStatusMessage("PaperMC/Paper", GITHUB_BRANCH_NAME, parts[0]);
-+ String[] parts = serverVersion.substring("git-Scissors-".length()).split("[-\\s]"); // Scissors
-+ final Component updateMessage = getUpdateStatusMessage("AtlasMediaGroup/Scissors", GITHUB_BRANCH_NAME, parts[0]); // Scissors
- final Component history = getHistory();
-
- return history != null ? TextComponent.ofChildren(updateMessage, Component.newline(), history) : updateMessage;
-@@ -54,15 +56,24 @@ public class PaperVersionFetcher implements VersionFetcher {
- return mcVer;
- }
-
-+ // Scissors start - Allow getting git information
-+ public static String getCommit() {
-+ final var manifest = JarManifests.manifest(Bukkit.getServer().getClass());
-+ return manifest == null ? null : manifest.getMainAttributes().getValue("Git-Commit");
-+ }
-+
-+ public static String getBranch() {
-+ final var manifest = JarManifests.manifest(Bukkit.getServer().getClass());
-+ return manifest == null ? null : manifest.getMainAttributes().getValue("Git-Branch");
-+ }
-+ // Scissors end
-+
- private static Component getUpdateStatusMessage(@Nonnull String repo, @Nonnull String branch, @Nonnull String versionInfo) {
- int distance;
-- try {
-- int jenkinsBuild = Integer.parseInt(versionInfo);
-- distance = fetchDistanceFromSiteApi(jenkinsBuild, getMinecraftVersion());
-- } catch (NumberFormatException ignored) {
-- versionInfo = versionInfo.replace("\"", "");
-- distance = fetchDistanceFromGitHub(repo, branch, versionInfo);
-- }
-+ // Scissors start - always use Git for version checking
-+ versionInfo = getCommit();
-+ distance = fetchDistanceFromGitHub(repo, branch, versionInfo);
-+ // Scissors end
-
- switch (distance) {
- case -1:
-diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java
-index c737c5d62407337d3db2899cfc01713a058a6467..54891c5d7ca19a4fdab74a8729814a6fecee3fda 100644
---- a/src/main/java/org/bukkit/craftbukkit/Main.java
-+++ b/src/main/java/org/bukkit/craftbukkit/Main.java
-@@ -301,7 +301,7 @@ public class Main {
- if (buildDate.before(deadline.getTime())) {
- // Paper start - This is some stupid bullshit
- System.err.println("*** Warning, you've not updated in a while! ***");
-- System.err.println("*** Please download a new build as per instructions from https://papermc.io/downloads/paper ***"); // Paper
-+ System.err.println("*** Please download a new build from https://ci.scissors.gg/job/Scissors ***"); // Scissors > // Paper
- //System.err.println("*** Server will start in 20 seconds ***");
- //Thread.sleep(TimeUnit.SECONDS.toMillis(20));
- // Paper End
diff --git a/patches/server/0013-Better-handling-of-invalid-JSON-components.patch b/patches/server/0013-Better-handling-of-invalid-JSON-components.patch
deleted file mode 100644
index 78f2802..0000000
--- a/patches/server/0013-Better-handling-of-invalid-JSON-components.patch
+++ /dev/null
@@ -1,185 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Video
-Date: Mon, 28 Mar 2022 13:19:43 -0600
-Subject: [PATCH] Better handling of invalid JSON components
-
-
-diff --git a/src/main/java/io/papermc/paper/util/MCUtil.java b/src/main/java/io/papermc/paper/util/MCUtil.java
-index 8240bb085b619f257f8c0a25775e0b15068e440f..c80d58dc9cb9171d51ff0a0596bb27bf161c3c83 100644
---- a/src/main/java/io/papermc/paper/util/MCUtil.java
-+++ b/src/main/java/io/papermc/paper/util/MCUtil.java
-@@ -659,12 +659,6 @@ public final class MCUtil {
- return null;
- }
- String string = compound.getString(key);
-- try {
-- return net.minecraft.network.chat.Component.Serializer.fromJson(string);
-- } catch (com.google.gson.JsonParseException e) {
-- org.bukkit.Bukkit.getLogger().warning("Unable to parse " + key + " from " + compound +": " + e.getMessage());
-- }
--
-- return null;
-+ return net.minecraft.network.chat.Component.Serializer.fromJsonSafe(string);
- }
- }
-diff --git a/src/main/java/net/minecraft/network/chat/Component.java b/src/main/java/net/minecraft/network/chat/Component.java
-index b540ce21c65ad52ad7e94d2ca2b3926c0875bee1..9cb6fa8e35c89f73e7c95dbe219a4bf6d00b60a9 100644
---- a/src/main/java/net/minecraft/network/chat/Component.java
-+++ b/src/main/java/net/minecraft/network/chat/Component.java
-@@ -26,6 +26,7 @@ import java.util.List;
- import java.util.Map.Entry;
- import java.util.Optional;
- import javax.annotation.Nullable;
-+import net.minecraft.ChatFormatting; // Scissors
- import net.minecraft.Util;
- import net.minecraft.network.chat.contents.BlockDataSource;
- import net.minecraft.network.chat.contents.DataSource;
-@@ -522,6 +523,26 @@ public interface Component extends Message, FormattedText, Iterable {
- return GsonHelper.toStableString(Serializer.toJsonTree(text));
- }
-
-+ // Scissors start
-+ @Nullable
-+ public static MutableComponent fromJsonSafe(String json) {
-+ try {
-+ return fromJson(json);
-+ } catch (Exception ex) {
-+ return Component.empty().append("** Invalid JSON Component **").withStyle(ChatFormatting.RED);
-+ }
-+ }
-+
-+ @Nullable
-+ public static MutableComponent fromJsonSafe(JsonElement json) {
-+ try {
-+ return fromJson(json);
-+ } catch (Exception ex) {
-+ return Component.empty().append("** Invalid JSON Component **").withStyle(ChatFormatting.RED);
-+ }
-+ }
-+ // Scissors end
-+
- public static JsonElement toJsonTree(Component text) {
- return Component.Serializer.GSON.toJsonTree(text);
- }
-diff --git a/src/main/java/net/minecraft/network/chat/HoverEvent.java b/src/main/java/net/minecraft/network/chat/HoverEvent.java
-index 7449a024265c42f28a6c9a1ed8d8f4b9e3096aac..487c68abc3eb5c18dc7fee762b2164001283cab7 100644
---- a/src/main/java/net/minecraft/network/chat/HoverEvent.java
-+++ b/src/main/java/net/minecraft/network/chat/HoverEvent.java
-@@ -79,7 +79,7 @@ public class HoverEvent {
- if (jsonElement != null) {
- return action.deserialize(jsonElement);
- } else {
-- Component component = Component.Serializer.fromJson(json.get("value"));
-+ Component component = Component.Serializer.fromJsonSafe(json.get("value")); // Scissors - Use safer method for getting Components from JSON
- return component != null ? action.deserializeFromLegacy(component) : null;
- }
- }
-@@ -94,7 +94,7 @@ public class HoverEvent {
- }
-
- public static class Action {
-- public static final HoverEvent.Action SHOW_TEXT = new HoverEvent.Action<>("show_text", true, Component.Serializer::fromJson, Component.Serializer::toJsonTree, Function.identity());
-+ public static final HoverEvent.Action SHOW_TEXT = new HoverEvent.Action<>("show_text", true, Component.Serializer::fromJsonSafe, Component.Serializer::toJsonTree, Function.identity()); // Scissors - Use safer method for getting Components from JSON
- public static final HoverEvent.Action SHOW_ITEM = new HoverEvent.Action<>("show_item", true, HoverEvent.ItemStackInfo::create, HoverEvent.ItemStackInfo::serialize, HoverEvent.ItemStackInfo::create);
- public static final HoverEvent.Action SHOW_ENTITY = new HoverEvent.Action<>("show_entity", true, HoverEvent.EntityTooltipInfo::create, HoverEvent.EntityTooltipInfo::serialize, HoverEvent.EntityTooltipInfo::create);
- private static final Map> LOOKUP = Stream.of(SHOW_TEXT, SHOW_ITEM, SHOW_ENTITY).collect(ImmutableMap.toImmutableMap(HoverEvent.Action::getName, (action) -> {
-@@ -182,7 +182,7 @@ public class HoverEvent {
- return null;
- }
- // Scissors end
-- Component component = Component.Serializer.fromJson(jsonObject.get("name"));
-+ Component component = Component.Serializer.fromJsonSafe(jsonObject.get("name")); // Scissors - Use safer method for getting Components from JSON
- return new HoverEvent.EntityTooltipInfo(entityType, uUID, component);
- }
- }
-@@ -191,7 +191,7 @@ public class HoverEvent {
- public static HoverEvent.EntityTooltipInfo create(Component text) {
- try {
- CompoundTag compoundTag = TagParser.parseTag(text.getString());
-- Component component = Component.Serializer.fromJson(compoundTag.getString("name"));
-+ Component component = Component.Serializer.fromJsonSafe(compoundTag.getString("name")); // Scissors - Use safer method for getting Components from JSON
- EntityType> entityType = BuiltInRegistries.ENTITY_TYPE.get(new ResourceLocation(compoundTag.getString("type")));
- // Scissors start
- UUID uUID;
-diff --git a/src/main/java/net/minecraft/network/chat/contents/NbtContents.java b/src/main/java/net/minecraft/network/chat/contents/NbtContents.java
-index 97a2657bc98d41c3c1e376b266d2c85f685acc88..9d20f3f1af8e663a8c13714c8928d4a91653daa4 100644
---- a/src/main/java/net/minecraft/network/chat/contents/NbtContents.java
-+++ b/src/main/java/net/minecraft/network/chat/contents/NbtContents.java
-@@ -8,6 +8,7 @@ import java.util.Optional;
- import java.util.stream.Collectors;
- import java.util.stream.Stream;
- import javax.annotation.Nullable;
-+import net.kyori.adventure.text.TextComponent; // Scissors
- import net.minecraft.commands.CommandSourceStack;
- import net.minecraft.commands.arguments.NbtPathArgument;
- import net.minecraft.nbt.Tag;
-@@ -107,10 +108,10 @@ public class NbtContents implements ComponentContents {
- Component component = DataFixUtils.orElse(ComponentUtils.updateForEntity(source, this.separator, sender, depth), ComponentUtils.DEFAULT_NO_STYLE_SEPARATOR);
- return stream.flatMap((text) -> {
- try {
-- MutableComponent mutableComponent = Component.Serializer.fromJson(text);
-+ MutableComponent mutableComponent = Component.Serializer.fromJsonSafe(text); // Scissors
- return Stream.of(ComponentUtils.updateForEntity(source, mutableComponent, sender, depth));
- } catch (Exception var5) {
-- LOGGER.warn("Failed to parse component: {}", text, var5);
-+ // Scissors - don't log
- return Stream.of();
- }
- }).reduce((accumulator, current) -> {
-diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
-index 1e05fca2a2ba6e2c0b641b6e27585520889cd8a6..3bf0c06f5042e9ff5572714dfc6a641a01a65978 100644
---- a/src/main/java/net/minecraft/world/entity/Entity.java
-+++ b/src/main/java/net/minecraft/world/entity/Entity.java
-@@ -2503,12 +2503,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
- this.setRot(this.getYRot(), this.getXRot());
- if (nbt.contains("CustomName", 8)) {
- String s = nbt.getString("CustomName");
--
-- try {
-- this.setCustomName(Component.Serializer.fromJson(s));
-- } catch (Exception exception) {
-- Entity.LOGGER.warn("Failed to parse entity custom name {}", s, exception);
-- }
-+ this.setCustomName(Component.Serializer.fromJsonSafe(s)); // Scissors - Use safer method for getting Components from JSON
- }
-
- this.setCustomNameVisible(nbt.getBoolean("CustomNameVisible"));
-diff --git a/src/main/java/net/minecraft/world/scores/ScoreboardSaveData.java b/src/main/java/net/minecraft/world/scores/ScoreboardSaveData.java
-index 4def212655cea0fd998b52e924f8b671d6aeb559..4359fb5997f8a207c52a09aa61a9431fa3ff550e 100644
---- a/src/main/java/net/minecraft/world/scores/ScoreboardSaveData.java
-+++ b/src/main/java/net/minecraft/world/scores/ScoreboardSaveData.java
-@@ -38,7 +38,7 @@ public class ScoreboardSaveData extends SavedData {
- CompoundTag compoundTag = nbt.getCompound(i);
- String string = compoundTag.getString("Name");
- PlayerTeam playerTeam = this.scoreboard.addPlayerTeam(string);
-- Component component = Component.Serializer.fromJson(compoundTag.getString("DisplayName"));
-+ Component component = Component.Serializer.fromJsonSafe(compoundTag.getString("DisplayName")); // Scissors - Use safer method for getting Components from JSON
- if (component != null) {
- playerTeam.setDisplayName(component);
- }
-@@ -56,14 +56,14 @@ public class ScoreboardSaveData extends SavedData {
- }
-
- if (compoundTag.contains("MemberNamePrefix", 8)) {
-- Component component2 = Component.Serializer.fromJson(compoundTag.getString("MemberNamePrefix"));
-+ Component component2 = Component.Serializer.fromJsonSafe(compoundTag.getString("MemberNamePrefix")); // Scissors - Use safer method for getting Components from JSON
- if (component2 != null) {
- playerTeam.setPlayerPrefix(component2);
- }
- }
-
- if (compoundTag.contains("MemberNameSuffix", 8)) {
-- Component component3 = Component.Serializer.fromJson(compoundTag.getString("MemberNameSuffix"));
-+ Component component3 = Component.Serializer.fromJsonSafe(compoundTag.getString("MemberNameSuffix")); // Scissors - Use safer method for getting Components from JSON
- if (component3 != null) {
- playerTeam.setPlayerSuffix(component3);
- }
-@@ -123,7 +123,7 @@ public class ScoreboardSaveData extends SavedData {
- return ObjectiveCriteria.DUMMY;
- });
- String string2 = compoundTag.getString("Name");
-- Component component = Component.Serializer.fromJson(compoundTag.getString("DisplayName"));
-+ Component component = Component.Serializer.fromJsonSafe(compoundTag.getString("DisplayName")); // Scissors - Use safer method for getting Components from JSON
- ObjectiveCriteria.RenderType renderType = ObjectiveCriteria.RenderType.byId(compoundTag.getString("RenderType"));
- this.scoreboard.addObjective(string2, objectiveCriteria, component, renderType);
- }
diff --git a/patches/server/0014-Block-server-side-chunkbans.patch b/patches/server/0014-Block-server-side-chunkbans.patch
deleted file mode 100644
index 87884fe..0000000
--- a/patches/server/0014-Block-server-side-chunkbans.patch
+++ /dev/null
@@ -1,180 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: ayunami2000
-Date: Mon, 28 Mar 2022 17:02:21 -0400
-Subject: [PATCH] Block server-side chunkbans
-
-
-diff --git a/src/main/java/net/minecraft/network/PacketEncoder.java b/src/main/java/net/minecraft/network/PacketEncoder.java
-index d364bd57b1675c8b21d781c2bc16c3e65800455c..f2e7585630ff724f966c7bcedc17e502d786870d 100644
---- a/src/main/java/net/minecraft/network/PacketEncoder.java
-+++ b/src/main/java/net/minecraft/network/PacketEncoder.java
-@@ -7,8 +7,16 @@ import io.netty.handler.codec.MessageToByteEncoder;
- import io.netty.util.Attribute;
- import io.netty.util.AttributeKey;
- import java.io.IOException;
-+import java.util.Collections; // Scissors
-+import net.minecraft.ChatFormatting; // Scissors
-+import net.minecraft.core.NonNullList; // Scissors
-+import net.minecraft.nbt.CompoundTag; // Scissors
-+import net.minecraft.network.chat.Component; // Scissors
-+import net.minecraft.network.chat.SignedMessageBody; // Scissors
- import net.minecraft.network.protocol.Packet;
-+import net.minecraft.network.protocol.game.*; // Scissors
- import net.minecraft.util.profiling.jfr.JvmProfiler;
-+import net.minecraft.world.item.ItemStack; // Scissors
- import org.slf4j.Logger;
-
- public class PacketEncoder extends MessageToByteEncoder> {
-@@ -19,6 +27,23 @@ public class PacketEncoder extends MessageToByteEncoder> {
- this.codecKey = protocolKey;
- }
-
-+ // Scissors start
-+ private int tryWrite(Packet packet, FriendlyByteBuf friendlyByteBuf, ChannelHandlerContext channelHandlerContext, int i) {
-+ friendlyByteBuf.writeVarInt(i);
-+ friendlyByteBuf.adventure$locale = channelHandlerContext.channel().attr(io.papermc.paper.adventure.PaperAdventure.LOCALE_ATTRIBUTE).get(); // Paper
-+
-+ int j = friendlyByteBuf.writerIndex();
-+ packet.write(friendlyByteBuf);
-+ int k = friendlyByteBuf.writerIndex() - j;
-+ int packetLength = friendlyByteBuf.readableBytes();
-+ if (packetLength > MAX_PACKET_SIZE) {
-+ throw new PacketTooLargeException(packet, this.codecKey, packetLength);
-+ }
-+
-+ return k;
-+ }
-+ // Scissors end
-+
- protected void encode(ChannelHandlerContext channelHandlerContext, Packet> packet, ByteBuf byteBuf) throws Exception {
- Attribute> attribute = channelHandlerContext.channel().attr(this.codecKey);
- ConnectionProtocol.CodecData> codecData = attribute.get();
-@@ -34,46 +59,59 @@ public class PacketEncoder extends MessageToByteEncoder> {
- throw new IOException("Can't serialize unregistered packet");
- } else {
- FriendlyByteBuf friendlyByteBuf = new FriendlyByteBuf(byteBuf);
-- friendlyByteBuf.writeVarInt(i);
-- friendlyByteBuf.adventure$locale = channelHandlerContext.channel().attr(io.papermc.paper.adventure.PaperAdventure.LOCALE_ATTRIBUTE).get(); // Paper
-
-+ // Scissors start
-+ int k;
- try {
-- int j = friendlyByteBuf.writerIndex();
-- packet.write(friendlyByteBuf);
-- int k = friendlyByteBuf.writerIndex() - j;
-- if (false && k > 8388608) { // Paper - disable
-- throw new IllegalArgumentException("Packet too big (is " + k + ", should be less than 8388608): " + packet);
-- }
--
-- JvmProfiler.INSTANCE.onPacketSent(codecData.protocol(), i, channelHandlerContext.channel().remoteAddress(), k);
-+ k = this.tryWrite(packet, friendlyByteBuf, channelHandlerContext, i);
- } catch (Throwable var13) {
-- // Paper start - Give proper error message
-- String packetName = io.papermc.paper.util.ObfHelper.INSTANCE.deobfClassName(packet.getClass().getName());
-- if (packetName.contains(".")) {
-- packetName = packetName.substring(packetName.lastIndexOf(".") + 1);
-- }
--
-- LOGGER.error("Packet encoding of packet {} (ID: {}) threw (skippable? {})", packetName, i, packet.isSkippable(), var13);
-- // Paper end
-- if (packet.isSkippable()) {
-- throw new SkipPacketException(var13);
-- }
--
-- throw var13;
-- } finally {
-- // Paper start
-- int packetLength = friendlyByteBuf.readableBytes();
-- if (packetLength > MAX_PACKET_SIZE) {
-- throw new PacketTooLargeException(packet, this.codecKey, packetLength);
-+ packet = capPacket(packet, i);
-+ if (packet == null) {
-+ throw new SkipPacketException(new IllegalArgumentException("Packet too big: " + packet));
- }
-- // Paper end
-- ProtocolSwapHandler.swapProtocolIfNeeded(attribute, packet);
-+ friendlyByteBuf.clear();
-+ k = this.tryWrite(packet, friendlyByteBuf, channelHandlerContext, i);
- }
-
-+ JvmProfiler.INSTANCE.onPacketSent(codecData.protocol(), i, channelHandlerContext.channel().remoteAddress(), k);
-+ ProtocolSwapHandler.swapProtocolIfNeeded(attribute, packet);
-+ // Scissors end
- }
- }
- }
-
-+ // Scissors start
-+ private static Packet capPacket(Packet packet, int i) {
-+ if (packet instanceof ClientboundBlockEntityDataPacket blockEntityDataPacket) {
-+ packet = new ClientboundBlockEntityDataPacket(blockEntityDataPacket.getPos(), blockEntityDataPacket.getType(), new CompoundTag());
-+ } else if (packet instanceof ClientboundLevelChunkPacketData chunkPacket) {
-+ chunkPacket.clearNBT();
-+ } else if (packet instanceof ClientboundContainerSetContentPacket containerSetContentPacket) {
-+ packet = new ClientboundContainerSetContentPacket(containerSetContentPacket.getContainerId(), containerSetContentPacket.getStateId(), NonNullList.create(), ItemStack.EMPTY);
-+ } else if (packet instanceof ClientboundSetEquipmentPacket setEquipmentPacket) {
-+ packet = new ClientboundSetEquipmentPacket(setEquipmentPacket.getEntity(), Collections.emptyList());
-+ } else if (packet instanceof ClientboundContainerSetSlotPacket containerSetSlotPacket) {
-+ packet = new ClientboundContainerSetSlotPacket(containerSetSlotPacket.getContainerId(), containerSetSlotPacket.getStateId(), containerSetSlotPacket.getSlot(), ItemStack.EMPTY);
-+ } else if (packet instanceof ClientboundMapItemDataPacket mapItemDataPacket) {
-+ packet = new ClientboundMapItemDataPacket(mapItemDataPacket.getMapId(), mapItemDataPacket.getScale(), mapItemDataPacket.isLocked(), null, null);
-+ } else if (packet instanceof ClientboundPlayerChatPacket playerChatPacket) {
-+ final SignedMessageBody.Packed body = playerChatPacket.body();
-+ packet = new ClientboundPlayerChatPacket(playerChatPacket.sender(), // Not sending this packet results in a kick when someone says something.
-+ playerChatPacket.index(),
-+ playerChatPacket.signature(),
-+ playerChatPacket.body(),
-+ Component.empty().append("** Message too large **").withStyle(ChatFormatting.RED),
-+ playerChatPacket.filterMask(),
-+ playerChatPacket.chatType()
-+ );
-+ } else {
-+ return null;
-+ }
-+
-+ return packet;
-+ }
-+ // Scissors end
-+
- // Paper start
- private static int MAX_PACKET_SIZE = 8388608;
-
-diff --git a/src/main/java/net/minecraft/network/protocol/game/ClientboundBlockEntityDataPacket.java b/src/main/java/net/minecraft/network/protocol/game/ClientboundBlockEntityDataPacket.java
-index 3944852921335c78a04a9dc301882ab5b152b1ed..96ee53c7cc862e059328c5cdf5e07f309df6a79e 100644
---- a/src/main/java/net/minecraft/network/protocol/game/ClientboundBlockEntityDataPacket.java
-+++ b/src/main/java/net/minecraft/network/protocol/game/ClientboundBlockEntityDataPacket.java
-@@ -24,7 +24,7 @@ public class ClientboundBlockEntityDataPacket implements Packet blockEntityType, CompoundTag nbt) {
-+ public ClientboundBlockEntityDataPacket(BlockPos pos, BlockEntityType> blockEntityType, CompoundTag nbt) { // Scissors - private -> public
- this.pos = pos;
- this.type = blockEntityType;
- this.tag = nbt.isEmpty() ? null : nbt;
-diff --git a/src/main/java/net/minecraft/network/protocol/game/ClientboundLevelChunkPacketData.java b/src/main/java/net/minecraft/network/protocol/game/ClientboundLevelChunkPacketData.java
-index 51e24105facfe71ce9f2757c6c881a21b58dacfd..5692fbae221fb01d32d92edc7bea0f6312e24e1c 100644
---- a/src/main/java/net/minecraft/network/protocol/game/ClientboundLevelChunkPacketData.java
-+++ b/src/main/java/net/minecraft/network/protocol/game/ClientboundLevelChunkPacketData.java
-@@ -33,6 +33,13 @@ public class ClientboundLevelChunkPacketData {
- }
- // Paper end
-
-+ // Scissors start
-+ public void clearNBT() {
-+ this.blockEntitiesData.clear();
-+ this.extraPackets.clear();
-+ }
-+ // Scissors end
-+
- // Paper start - Anti-Xray - Add chunk packet info
- @Deprecated @io.papermc.paper.annotation.DoNotUse public ClientboundLevelChunkPacketData(LevelChunk chunk) { this(chunk, null); }
- public ClientboundLevelChunkPacketData(LevelChunk chunk, com.destroystokyo.paper.antixray.ChunkPacketInfo chunkPacketInfo) {
-@@ -58,6 +65,7 @@ public class ClientboundLevelChunkPacketData {
- int totalTileEntities = 0; // Paper
-
- for(Map.Entry entry2 : chunk.getBlockEntities().entrySet()) {
-+ if (this.extraPackets.size() > 50) break; // Scissors - Limit extraPackets size
- // Paper start
- if (++totalTileEntities > TE_LIMIT) {
- var packet = entry2.getValue().getUpdatePacket();
diff --git a/patches/server/0015-Reject-oversized-components-from-updating.patch b/patches/server/0015-Reject-oversized-components-from-updating.patch
deleted file mode 100644
index 62ee5c6..0000000
--- a/patches/server/0015-Reject-oversized-components-from-updating.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Video
-Date: Mon, 28 Mar 2022 16:49:17 -0600
-Subject: [PATCH] Reject oversized components from updating
-
-
-diff --git a/src/main/java/net/minecraft/network/chat/ComponentUtils.java b/src/main/java/net/minecraft/network/chat/ComponentUtils.java
-index 7daca712816a79cc4a30b084afbd3d07b5d3755f..a7e04eb4284e7d5148e1c7b991620d666785ec70 100644
---- a/src/main/java/net/minecraft/network/chat/ComponentUtils.java
-+++ b/src/main/java/net/minecraft/network/chat/ComponentUtils.java
-@@ -38,8 +38,9 @@ public class ComponentUtils {
- }
-
- public static MutableComponent updateForEntity(@Nullable CommandSourceStack source, Component text, @Nullable Entity sender, int depth) throws CommandSyntaxException {
-+ MutableComponent result; // Scissors
- if (depth > 100) {
-- return text.copy();
-+ result = text.copy(); // Scissors
- } else {
- // Paper start
- if (text instanceof io.papermc.paper.adventure.AdventureComponent adventureComponent) {
-@@ -52,8 +53,9 @@ public class ComponentUtils {
- mutableComponent.append(updateForEntity(source, component, sender, depth + 1));
- }
-
-- return mutableComponent.withStyle(resolveStyle(source, text.getStyle(), sender, depth));
-+ result = mutableComponent.withStyle(resolveStyle(source, text.getStyle(), sender, depth)); // Scissors
- }
-+ return Component.Serializer.toJson(result).length() > 65535 ? Component.empty() : result; // Scissors
- }
-
- private static Style resolveStyle(@Nullable CommandSourceStack source, Style style, @Nullable Entity sender, int depth) throws CommandSyntaxException {
diff --git a/patches/server/0016-Add-Scissors-configuration-file-command.patch b/patches/server/0016-Add-Scissors-configuration-file-command.patch
deleted file mode 100644
index 813f380..0000000
--- a/patches/server/0016-Add-Scissors-configuration-file-command.patch
+++ /dev/null
@@ -1,508 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Allink
-Date: Sun, 10 Jul 2022 10:12:04 +0100
-Subject: [PATCH] Add Scissors configuration file & command
-
-
-diff --git a/src/main/java/co/aikar/timings/TimingsExport.java b/src/main/java/co/aikar/timings/TimingsExport.java
-index a2f71a6d1a9e98133dff6cd0f625da9435a8af14..f83b2c4298bd1a5f65487f64bd6a11fb190a622d 100644
---- a/src/main/java/co/aikar/timings/TimingsExport.java
-+++ b/src/main/java/co/aikar/timings/TimingsExport.java
-@@ -25,6 +25,7 @@ package co.aikar.timings;
-
- import com.google.common.collect.Sets;
- import io.papermc.paper.adventure.PaperAdventure;
-+import me.totalfreedom.scissors.ScissorsConfig;
- import net.kyori.adventure.text.event.ClickEvent;
- import net.kyori.adventure.text.format.NamedTextColor;
- import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
-@@ -242,7 +243,8 @@ public class TimingsExport extends Thread {
- parent.put("config", createObject(
- pair("spigot", mapAsJSON(Bukkit.spigot().getSpigotConfig(), null)),
- pair("bukkit", mapAsJSON(Bukkit.spigot().getBukkitConfig(), null)),
-- pair("paper", mapAsJSON(Bukkit.spigot().getPaperConfig(), null))
-+ pair("paper", mapAsJSON(Bukkit.spigot().getPaperConfig(), null)),
-+ pair("scissors", mapAsJSON(ScissorsConfig.config, null)) // Scissors
- ));
-
- new TimingsExport(listeners, parent, history).start();
-diff --git a/src/main/java/me/totalfreedom/scissors/ScissorsCommand.java b/src/main/java/me/totalfreedom/scissors/ScissorsCommand.java
-new file mode 100644
-index 0000000000000000000000000000000000000000..797677d892d83cf54d9a60af1e277b67ed3d6e95
---- /dev/null
-+++ b/src/main/java/me/totalfreedom/scissors/ScissorsCommand.java
-@@ -0,0 +1,150 @@
-+package me.totalfreedom.scissors;
-+
-+import com.google.common.base.Functions;
-+import com.google.common.base.Joiner;
-+import com.google.common.collect.ImmutableSet;
-+import com.google.common.collect.Iterables;
-+import com.google.common.collect.Lists;
-+import net.minecraft.resources.ResourceLocation;
-+import net.minecraft.server.MinecraftServer;
-+import org.bukkit.Bukkit;
-+import org.bukkit.ChatColor;
-+import org.bukkit.Location;
-+import org.bukkit.command.Command;
-+import org.bukkit.command.CommandSender;
-+
-+import java.io.File;
-+import java.util.*;
-+import java.util.stream.Collectors;
-+
-+public class ScissorsCommand extends Command
-+{
-+
-+ private static final String BASE_PERM = "bukkit.command.scissors.";
-+ private static final ImmutableSet SUBCOMMANDS = ImmutableSet.builder().add("reload", "version").build();
-+
-+ public ScissorsCommand(String name)
-+ {
-+ super(name);
-+ this.description = "Scissors related commands";
-+ this.usageMessage = "/scissors [" + Joiner.on(" | ").join(SUBCOMMANDS) + "]";
-+ this.setPermission("bukkit.command.scissors;" + Joiner.on(';').join(SUBCOMMANDS.stream().map(s -> BASE_PERM + s).collect(Collectors.toSet())));
-+ }
-+
-+ private static boolean testPermission(CommandSender commandSender, String permission)
-+ {
-+ if (commandSender.hasPermission(BASE_PERM + permission) || commandSender.hasPermission("bukkit.command.scissors"))
-+ return true;
-+ commandSender.sendMessage(Bukkit.getPermissionMessage()); // Sorry, kashike
-+ return false;
-+ }
-+
-+ // Code from Mojang - copyright them
-+ public static List getListMatchingLast(CommandSender sender, String[] args, String... matches)
-+ {
-+ return getListMatchingLast(sender, args, Arrays.asList(matches));
-+ }
-+
-+ public static boolean matches(String s, String s1)
-+ {
-+ return s1.regionMatches(true, 0, s, 0, s.length());
-+ }
-+
-+ public static List getListMatchingLast(CommandSender sender, String[] strings, Collection> collection)
-+ {
-+ String last = strings[strings.length - 1];
-+ ArrayList results = Lists.newArrayList();
-+
-+ if (!collection.isEmpty())
-+ {
-+ Iterator iterator = Iterables.transform(collection, Functions.toStringFunction()).iterator();
-+
-+ while (iterator.hasNext())
-+ {
-+ String s1 = (String) iterator.next();
-+
-+ if (matches(last, s1) && (sender.hasPermission(BASE_PERM + s1) || sender.hasPermission("bukkit.command.scissors")))
-+ {
-+ results.add(s1);
-+ }
-+ }
-+
-+ if (results.isEmpty())
-+ {
-+ iterator = collection.iterator();
-+
-+ while (iterator.hasNext())
-+ {
-+ Object object = iterator.next();
-+
-+ if (object instanceof ResourceLocation && matches(last, ((ResourceLocation) object).getPath()))
-+ {
-+ results.add(String.valueOf(object));
-+ }
-+ }
-+ }
-+ }
-+
-+ return results;
-+ }
-+
-+ @Override
-+ public List tabComplete(CommandSender sender, String alias, String[] args, Location location) throws IllegalArgumentException
-+ {
-+ if (args.length <= 1)
-+ return getListMatchingLast(sender, args, SUBCOMMANDS);
-+
-+ return Collections.emptyList();
-+ }
-+ // end copy stuff
-+
-+ @Override
-+ public boolean execute(CommandSender sender, String commandLabel, String[] args)
-+ {
-+ if (!testPermission(sender)) return true;
-+
-+ if (args.length == 0)
-+ {
-+ sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage);
-+ return false;
-+ }
-+ if (SUBCOMMANDS.contains(args[0].toLowerCase(Locale.ENGLISH)))
-+ {
-+ if (!testPermission(sender, args[0].toLowerCase(Locale.ENGLISH))) return true;
-+ }
-+ switch (args[0].toLowerCase(Locale.ENGLISH))
-+ {
-+ case "reload":
-+ doReload(sender);
-+ break;
-+ case "ver":
-+ if (!testPermission(sender, "version"))
-+ break; // "ver" needs a special check because it's an alias. All other commands are checked up before the switch statement (because they are present in the SUBCOMMANDS set)
-+ case "version":
-+ Command ver = MinecraftServer.getServer().server.getCommandMap().getCommand("version");
-+ if (ver != null)
-+ {
-+ ver.execute(sender, commandLabel, new String[0]);
-+ break;
-+ }
-+ // else - fall through to default
-+ default:
-+ sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage);
-+ return false;
-+ }
-+
-+ return true;
-+ }
-+
-+ private void doReload(CommandSender sender)
-+ {
-+ Command.broadcastCommandMessage(sender, ChatColor.RED + "Please note that this command is not supported and may cause issues.");
-+ Command.broadcastCommandMessage(sender, ChatColor.RED + "If you encounter any issues please use the /stop command to restart your server.");
-+
-+ MinecraftServer console = MinecraftServer.getServer();
-+ ScissorsConfig.init((File) console.options.valueOf("scissors-settings"));
-+ console.server.reloadCount++;
-+
-+ Command.broadcastCommandMessage(sender, ChatColor.GREEN + "Scissors config reload complete.");
-+ }
-+}
-diff --git a/src/main/java/me/totalfreedom/scissors/ScissorsConfig.java b/src/main/java/me/totalfreedom/scissors/ScissorsConfig.java
-new file mode 100644
-index 0000000000000000000000000000000000000000..8cd2848aa6b06c5efbe797ed2d75ff4b025b3c52
---- /dev/null
-+++ b/src/main/java/me/totalfreedom/scissors/ScissorsConfig.java
-@@ -0,0 +1,225 @@
-+package me.totalfreedom.scissors;
-+
-+
-+import com.google.common.base.Throwables;
-+import net.minecraft.server.MinecraftServer;
-+import net.minecraft.server.dedicated.DedicatedServer;
-+import org.bukkit.Bukkit;
-+import org.bukkit.command.Command;
-+import org.bukkit.configuration.InvalidConfigurationException;
-+import org.bukkit.configuration.file.YamlConfiguration;
-+
-+import java.io.File;
-+import java.io.IOException;
-+import java.lang.reflect.InvocationTargetException;
-+import java.lang.reflect.Method;
-+import java.lang.reflect.Modifier;
-+import java.nio.file.Files;
-+import java.nio.file.Path;
-+import java.util.HashMap;
-+import java.util.List;
-+import java.util.Map;
-+import java.util.logging.Level;
-+import java.util.regex.Pattern;
-+
-+// TODO - Migrate to new format
-+public class ScissorsConfig
-+{
-+
-+ private static final String HEADER = """
-+ This is the main configuration file for Scissors.
-+ As you can see, there's tons to configure. Some options may impact gameplay, so use
-+ with caution, and make sure you know what each option does before configuring.
-+
-+ If you need help with the configuration or have any questions related to Scissors,
-+ join us in our Discord.
-+
-+ Discord: https://discord.com/invite/mtVQcHn58h
-+ Website: https://scissors.gg/\s
-+ Docs: https://javadoc.scissors.gg/1.20.1/\s
-+ """;
-+ private static final Pattern SPACE = Pattern.compile(" ");
-+ private static final Pattern NOT_NUMERIC = Pattern.compile("[^-\\d.]");
-+ /*========================================================================*/
-+ public static YamlConfiguration config;
-+ static int version;
-+ /*========================================================================*/
-+ static Map commands;
-+ private static File CONFIG_FILE;
-+
-+ public static void init(File configFile)
-+ {
-+ final File configFolder = (File) DedicatedServer.getServer().options.valueOf("scissors-settings" + "-directory");
-+ final Path configFolderPath = configFolder.toPath();
-+ final Path oldConfigFilePath = configFile.toPath();
-+ final Path newConfigFilePath = configFolderPath.resolve(configFile.toPath());
-+
-+ if (configFile.exists())
-+ {
-+ try
-+ {
-+ Files.move(oldConfigFilePath, newConfigFilePath);
-+ }
-+ catch (IOException e)
-+ {
-+ throw new RuntimeException("Error migrating configuration file to new directory!", e);
-+ }
-+ }
-+
-+ CONFIG_FILE = newConfigFilePath.toFile();
-+ config = new YamlConfiguration();
-+ try
-+ {
-+ config.load(CONFIG_FILE);
-+ }
-+ catch (IOException ex)
-+ {
-+ }
-+ catch (InvalidConfigurationException ex)
-+ {
-+ Bukkit.getLogger().log(Level.SEVERE, "Could not load scissors.yml, please correct your syntax errors", ex);
-+ throw Throwables.propagate(ex);
-+ }
-+
-+ commands = new HashMap<>();
-+ commands.put("scissors", new ScissorsCommand("scissors"));
-+
-+ config.options().header(HEADER);
-+ config.options().copyDefaults(true);
-+
-+ version = getInt("config-version", 5);
-+ set("config-version", 5);
-+ readConfig(ScissorsConfig.class, null);
-+ }
-+
-+ protected static void logError(String s)
-+ {
-+ Bukkit.getLogger().severe(s);
-+ }
-+
-+ protected static void fatal(String s)
-+ {
-+ throw new RuntimeException("Fatal scissors.yml config error: " + s);
-+ }
-+
-+ public static void registerCommands()
-+ {
-+ for (Map.Entry entry : commands.entrySet())
-+ {
-+ MinecraftServer.getServer().server.getCommandMap().register(entry.getKey(), "Scissors", entry.getValue());
-+ }
-+ }
-+
-+ static void readConfig(Class> clazz, Object instance)
-+ {
-+ for (Method method : clazz.getDeclaredMethods())
-+ {
-+ if (Modifier.isPrivate(method.getModifiers()))
-+ {
-+ if (method.getParameterTypes().length == 0 && method.getReturnType() == Void.TYPE)
-+ {
-+ try
-+ {
-+ method.setAccessible(true);
-+ method.invoke(instance);
-+ }
-+ catch (InvocationTargetException ex)
-+ {
-+ throw Throwables.propagate(ex.getCause());
-+ }
-+ catch (Exception ex)
-+ {
-+ Bukkit.getLogger().log(Level.SEVERE, "Error invoking " + method, ex);
-+ }
-+ }
-+ }
-+ }
-+ saveConfig();
-+ }
-+
-+ static void saveConfig()
-+ {
-+ try
-+ {
-+ config.save(CONFIG_FILE);
-+ }
-+ catch (IOException ex)
-+ {
-+ Bukkit.getLogger().log(Level.SEVERE, "Could not save " + CONFIG_FILE, ex);
-+ }
-+ }
-+
-+ public static boolean runCommandsInBooks = false;
-+
-+ private static void runCommandsInBooks()
-+ {
-+ runCommandsInBooks = getBoolean("runCommandsInBooks", false);
-+ }
-+
-+ // people still may want them to bypass permissions for warps
-+ public static boolean commandSignsBypassPermissions = false;
-+ private static void commandSignsBypassPermissions()
-+ {
-+ commandSignsBypassPermissions = getBoolean("commandSignsBypassPermissions", false);
-+ }
-+
-+ public static boolean chatSignaturesEnabled = true;
-+ private static void chatSignaturesEnabled()
-+ {
-+ chatSignaturesEnabled = getBoolean("chatSignaturesEnabled", true);
-+ }
-+
-+ public static boolean excludePlayersFromNbtComponents = false;
-+ private static void excludePlayersFromNbtComponents()
-+ {
-+ excludePlayersFromNbtComponents = getBoolean("excludePlayersFromNbtComponents", false);
-+ }
-+ public static int componentDepthLimit = 128;
-+ private static void componentDepthLimit()
-+ {
-+ componentDepthLimit = getInt("componentDepthLimit", 128);
-+ }
-+
-+
-+ private static void set(String path, Object val)
-+ {
-+ config.set(path, val);
-+ }
-+
-+ private static boolean getBoolean(String path, boolean def)
-+ {
-+ config.addDefault(path, def);
-+ return config.getBoolean(path, config.getBoolean(path));
-+ }
-+
-+ private static double getDouble(String path, double def)
-+ {
-+ config.addDefault(path, def);
-+ return config.getDouble(path, config.getDouble(path));
-+ }
-+
-+ private static float getFloat(String path, float def)
-+ {
-+ // TODO: Figure out why getFloat() always returns the default value.
-+ return (float) getDouble(path, def);
-+ }
-+
-+ private static int getInt(String path, int def)
-+ {
-+ config.addDefault(path, def);
-+ return config.getInt(path, config.getInt(path));
-+ }
-+
-+ private static List getList(String path, T def)
-+ {
-+ config.addDefault(path, def);
-+ return config.getList(path, config.getList(path));
-+ }
-+
-+ private static String getString(String path, String def)
-+ {
-+ config.addDefault(path, def);
-+ return config.getString(path, config.getString(path));
-+ }
-+}
-+
-diff --git a/src/main/java/net/minecraft/server/Main.java b/src/main/java/net/minecraft/server/Main.java
-index ec268189b19b6fa5c4521f96ce211a531db35ec5..343cb72710ef100cf7e4de1e081cfdc2744aab46 100644
---- a/src/main/java/net/minecraft/server/Main.java
-+++ b/src/main/java/net/minecraft/server/Main.java
-@@ -144,6 +144,7 @@ public class Main {
- // Paper start - load config files for access below if needed
- org.bukkit.configuration.file.YamlConfiguration bukkitConfiguration = io.papermc.paper.configuration.PaperConfigurations.loadLegacyConfigFile((File) optionset.valueOf("bukkit-settings"));
- org.bukkit.configuration.file.YamlConfiguration spigotConfiguration = io.papermc.paper.configuration.PaperConfigurations.loadLegacyConfigFile((File) optionset.valueOf("spigot-settings"));
-+ org.bukkit.configuration.file.YamlConfiguration scissorsConfiguration = io.papermc.paper.configuration.PaperConfigurations.loadLegacyConfigFile((File) optionset.valueOf("scissors-settings")); // Scissors - TODO Change this
- // Paper end
-
- if (optionset.has("initSettings")) { // CraftBukkit
-diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
-index 1c9742ad81f04052d2c3bc18c7636f45b2fc5160..e2cb86f0323d91fa10ecf6cdf1db2e28405798a8 100644
---- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
-+++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
-@@ -222,6 +222,16 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
- io.papermc.paper.brigadier.PaperBrigadierProviderImpl.INSTANCE.getClass(); // init PaperBrigadierProvider
- // Paper end
-
-+ // Scissors start
-+ try {
-+ me.totalfreedom.scissors.ScissorsConfig.init((java.io.File) options.valueOf("scissors-settings"));
-+ } catch (Exception e) {
-+ DedicatedServer.LOGGER.error("Unable to load server configuration", e);
-+ return false;
-+ }
-+ me.totalfreedom.scissors.ScissorsConfig.registerCommands();
-+ // Scissors end
-+
- this.setPvpAllowed(dedicatedserverproperties.pvp);
- this.setFlightAllowed(dedicatedserverproperties.allowFlight);
- this.setMotd(dedicatedserverproperties.motd);
-diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
-index 903df63725faeaa160609edddf9f5c54144945e6..058780b420c9207119f4bb889f602bd94199d7fb 100644
---- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
-+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
-@@ -1040,6 +1040,7 @@ public final class CraftServer implements Server {
- }
-
- org.spigotmc.SpigotConfig.init((File) this.console.options.valueOf("spigot-settings")); // Spigot
-+ me.totalfreedom.scissors.ScissorsConfig.init(((File) console.options.valueOf("scissors-settings"))); // Scissors
- this.console.paperConfigurations.reloadConfigs(this.console);
- for (ServerLevel world : this.console.getAllLevels()) {
- // world.serverLevelData.setDifficulty(config.difficulty); // Paper - per level difficulty
-@@ -1071,6 +1072,7 @@ public final class CraftServer implements Server {
- this.reloadData();
- org.spigotmc.SpigotConfig.registerCommands(); // Spigot
- io.papermc.paper.command.PaperCommands.registerCommands(this.console); // Paper
-+ me.totalfreedom.scissors.ScissorsConfig.registerCommands(); // Scissors
- this.overrideAllCommandBlockCommands = this.commandsConfiguration.getStringList("command-block-overrides").contains("*");
- this.ignoreVanillaPermissions = this.commandsConfiguration.getBoolean("ignore-vanilla-permissions");
-
-@@ -2978,6 +2980,14 @@ public final class CraftServer implements Server {
- return CraftServer.this.console.paperConfigurations.createLegacyObject(CraftServer.this.console);
- }
-
-+ // Scissors start
-+ @Override
-+ public YamlConfiguration getScissorsConfig()
-+ {
-+ return me.totalfreedom.scissors.ScissorsConfig.config;
-+ }
-+ // Scissors end
-+
- @Override
- public void restart() {
- org.spigotmc.RestartCommand.restart();
-diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java
-index 54891c5d7ca19a4fdab74a8729814a6fecee3fda..05db4799fddfbd8045c967520db99a75ba807697 100644
---- a/src/main/java/org/bukkit/craftbukkit/Main.java
-+++ b/src/main/java/org/bukkit/craftbukkit/Main.java
-@@ -181,6 +181,20 @@ public class Main {
- .defaultsTo("Unknown Server")
- .describedAs("Name");
- // Paper end
-+
-+ // Scissors start
-+ acceptsAll(asList("scissors-dir", "scissors-settings-directory"), "Directory for Scissors settings")
-+ .withRequiredArg()
-+ .ofType(File.class)
-+ .defaultsTo(new File(io.papermc.paper.configuration.PaperConfigurations.CONFIG_DIR))
-+ .describedAs("Config directory");
-+
-+ acceptsAll(asList("scissors", "scissors-settings"), "File for Scissors settings")
-+ .withRequiredArg()
-+ .ofType(File.class)
-+ .defaultsTo(new File("scissors.yml"))
-+ .describedAs("YAML file");
-+ // Scissors end
- }
- };
-
diff --git a/patches/server/0017-Prevent-attributes-with-invalid-namespaces-from-bein.patch b/patches/server/0017-Prevent-attributes-with-invalid-namespaces-from-bein.patch
deleted file mode 100644
index ffa7156..0000000
--- a/patches/server/0017-Prevent-attributes-with-invalid-namespaces-from-bein.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Video
-Date: Wed, 30 Mar 2022 18:20:09 -0600
-Subject: [PATCH] Prevent attributes with invalid namespaces from being applied
- to CraftMetaItems
-
-
-diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
-index ed6e5060901c348c4f56a573c23e2000d8f2fb72..5cdf1e6fcdc9e2bd821f40ec9bf95cf03f03179a 100644
---- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
-+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
-@@ -46,6 +46,7 @@ import net.minecraft.nbt.NbtIo;
- import net.minecraft.nbt.StringTag;
- import net.minecraft.nbt.Tag;
- import net.minecraft.network.chat.Component;
-+import net.minecraft.resources.ResourceLocation; // Scissors
- import net.minecraft.world.item.BlockItem;
- import net.minecraft.world.level.block.state.BlockState;
- import org.apache.commons.lang3.EnumUtils;
-@@ -487,7 +488,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
- AttributeModifier attribMod = CraftAttributeInstance.convert(nmsModifier);
-
- String attributeName = CraftAttributeMap.convertIfNeeded(entry.getString(CraftMetaItem.ATTRIBUTES_IDENTIFIER.NBT)); // Paper
-- if (attributeName == null || attributeName.isEmpty()) {
-+ if (attributeName == null || attributeName.isEmpty() || attributeName.length() > 256 || !ResourceLocation.isValidResourceLocation(attributeName)) { // Scissors
- continue;
- }
-
diff --git a/patches/server/0018-Don-t-query-player-data-in-the-nbt-component.patch b/patches/server/0018-Don-t-query-player-data-in-the-nbt-component.patch
deleted file mode 100644
index 3860b8c..0000000
--- a/patches/server/0018-Don-t-query-player-data-in-the-nbt-component.patch
+++ /dev/null
@@ -1,38 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Video
-Date: Sat, 9 Apr 2022 13:00:27 -0600
-Subject: [PATCH] Don't query player data in the `nbt` component
-
-
-diff --git a/src/main/java/net/minecraft/network/chat/contents/EntityDataSource.java b/src/main/java/net/minecraft/network/chat/contents/EntityDataSource.java
-index 8a6799b50062c1b7b141ee1568dc523f9ee7ecfd..80e7b0889235288b60d813a569daecb7e08e108e 100644
---- a/src/main/java/net/minecraft/network/chat/contents/EntityDataSource.java
-+++ b/src/main/java/net/minecraft/network/chat/contents/EntityDataSource.java
-@@ -1,5 +1,6 @@
- package net.minecraft.network.chat.contents;
-
-+import me.totalfreedom.scissors.ScissorsConfig; // Scissors
- import com.mojang.brigadier.StringReader;
- import com.mojang.brigadier.exceptions.CommandSyntaxException;
- import java.util.List;
-@@ -11,6 +12,7 @@ import net.minecraft.commands.arguments.selector.EntitySelector;
- import net.minecraft.commands.arguments.selector.EntitySelectorParser;
- import net.minecraft.nbt.CompoundTag;
- import net.minecraft.world.entity.Entity;
-+import net.minecraft.world.entity.player.Player; // Scissors
-
- public record EntityDataSource(String selectorPattern, @Nullable EntitySelector compiledSelector) implements DataSource {
- public EntityDataSource(String rawPath) {
-@@ -31,7 +33,11 @@ public record EntityDataSource(String selectorPattern, @Nullable EntitySelector
- public Stream getData(CommandSourceStack source) throws CommandSyntaxException {
- if (this.compiledSelector != null) {
- List extends Entity> list = this.compiledSelector.findEntities(source);
-- return list.stream().map(NbtPredicate::getEntityTagToCompare);
-+ // Scissors start
-+ Stream extends Entity> stream = list.stream();
-+ if (ScissorsConfig.excludePlayersFromNbtComponents) stream = stream.filter((entity) -> !(entity instanceof Player));
-+ return stream.map(NbtPredicate::getEntityTagToCompare);
-+ // Scissors end
- } else {
- return Stream.empty();
- }
diff --git a/patches/server/0019-Limit-string-tag-visitors-to-1024-elements.patch b/patches/server/0019-Limit-string-tag-visitors-to-1024-elements.patch
deleted file mode 100644
index 255a727..0000000
--- a/patches/server/0019-Limit-string-tag-visitors-to-1024-elements.patch
+++ /dev/null
@@ -1,142 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Luna
-Date: Fri, 8 Apr 2022 23:38:12 -0300
-Subject: [PATCH] Limit string tag visitors to 1024 elements
-
-
-diff --git a/src/main/java/net/minecraft/nbt/SnbtPrinterTagVisitor.java b/src/main/java/net/minecraft/nbt/SnbtPrinterTagVisitor.java
-index e07cc7970955ce240754cfe424d768c2bba0241a..a4f41bb4ec6cb20f782668c714229b61415cfdfb 100644
---- a/src/main/java/net/minecraft/nbt/SnbtPrinterTagVisitor.java
-+++ b/src/main/java/net/minecraft/nbt/SnbtPrinterTagVisitor.java
-@@ -89,6 +89,7 @@ public class SnbtPrinterTagVisitor implements TagVisitor {
- public void visitByteArray(ByteArrayTag element) {
- StringBuilder stringBuilder = (new StringBuilder("[")).append("B").append(";");
- byte[] bs = element.getAsByteArray();
-+ if (bs.length > 1024) { this.result = stringBuilder.append("]").toString(); return; } // Scissors
-
- for(int i = 0; i < bs.length; ++i) {
- stringBuilder.append(" ").append((int)bs[i]).append("B");
-@@ -105,6 +106,7 @@ public class SnbtPrinterTagVisitor implements TagVisitor {
- public void visitIntArray(IntArrayTag element) {
- StringBuilder stringBuilder = (new StringBuilder("[")).append("I").append(";");
- int[] is = element.getAsIntArray();
-+ if (is.length > 1024) { this.result = stringBuilder.append("]").toString(); return; } // Scissors
-
- for(int i = 0; i < is.length; ++i) {
- stringBuilder.append(" ").append(is[i]);
-@@ -122,6 +124,7 @@ public class SnbtPrinterTagVisitor implements TagVisitor {
- String string = "L";
- StringBuilder stringBuilder = (new StringBuilder("[")).append("L").append(";");
- long[] ls = element.getAsLongArray();
-+ if (ls.length > 1024) { this.result = stringBuilder.append("]").toString(); return; } // Scissors
-
- for(int i = 0; i < ls.length; ++i) {
- stringBuilder.append(" ").append(ls[i]).append("L");
-@@ -136,7 +139,7 @@ public class SnbtPrinterTagVisitor implements TagVisitor {
-
- @Override
- public void visitList(ListTag element) {
-- if (element.isEmpty()) {
-+ if (element.isEmpty() || element.size() > 1024) { // Scissors
- this.result = "[]";
- } else {
- StringBuilder stringBuilder = new StringBuilder("[");
-@@ -166,7 +169,7 @@ public class SnbtPrinterTagVisitor implements TagVisitor {
-
- @Override
- public void visitCompound(CompoundTag compound) {
-- if (compound.isEmpty()) {
-+ if (compound.isEmpty() || compound.size() > 1024) { // Scissors
- this.result = "{}";
- } else {
- StringBuilder stringBuilder = new StringBuilder("{");
-diff --git a/src/main/java/net/minecraft/nbt/StringTagVisitor.java b/src/main/java/net/minecraft/nbt/StringTagVisitor.java
-index a687a0f17df30126d53a1e3a669dc6d157c23ed5..2c50f41dd8034af16fcceca75eeb6c7a9940e327 100644
---- a/src/main/java/net/minecraft/nbt/StringTagVisitor.java
-+++ b/src/main/java/net/minecraft/nbt/StringTagVisitor.java
-@@ -53,6 +53,7 @@ public class StringTagVisitor implements TagVisitor {
- public void visitByteArray(ByteArrayTag element) {
- this.builder.append("[B;");
- byte[] bs = element.getAsByteArray();
-+ if (bs.length > 1024) { this.builder.append(']'); return; } // Scissors
-
- for(int i = 0; i < bs.length; ++i) {
- if (i != 0) {
-@@ -69,6 +70,7 @@ public class StringTagVisitor implements TagVisitor {
- public void visitIntArray(IntArrayTag element) {
- this.builder.append("[I;");
- int[] is = element.getAsIntArray();
-+ if (is.length > 1024) { this.builder.append(']'); return; } // Scissors
-
- for(int i = 0; i < is.length; ++i) {
- if (i != 0) {
-@@ -85,6 +87,7 @@ public class StringTagVisitor implements TagVisitor {
- public void visitLongArray(LongArrayTag element) {
- this.builder.append("[L;");
- long[] ls = element.getAsLongArray();
-+ if (ls.length > 1024) { this.builder.append(']'); return; } // Scissors
-
- for(int i = 0; i < ls.length; ++i) {
- if (i != 0) {
-@@ -100,6 +103,7 @@ public class StringTagVisitor implements TagVisitor {
- @Override
- public void visitList(ListTag element) {
- this.builder.append('[');
-+ if (element.size() > 1024) { this.builder.append(']'); return; } // Scissors
-
- for(int i = 0; i < element.size(); ++i) {
- if (i != 0) {
-@@ -116,6 +120,7 @@ public class StringTagVisitor implements TagVisitor {
- public void visitCompound(CompoundTag compound) {
- this.builder.append('{');
- List list = Lists.newArrayList(compound.getAllKeys());
-+ if (list.size() > 1024) { this.builder.append('}'); return; } // Scissors
- Collections.sort(list);
-
- for(String string : list) {
-diff --git a/src/main/java/net/minecraft/nbt/TextComponentTagVisitor.java b/src/main/java/net/minecraft/nbt/TextComponentTagVisitor.java
-index 149def3da0b92f64e4fc04630965dce44884f938..c9d753f37bd65e35f8a4e2eb5c6fe8f74d5d1606 100644
---- a/src/main/java/net/minecraft/nbt/TextComponentTagVisitor.java
-+++ b/src/main/java/net/minecraft/nbt/TextComponentTagVisitor.java
-@@ -97,6 +97,7 @@ public class TextComponentTagVisitor implements TagVisitor {
- Component component = Component.literal("B").withStyle(SYNTAX_HIGHLIGHTING_NUMBER_TYPE);
- MutableComponent mutableComponent = Component.literal("[").append(component).append(";");
- byte[] bs = element.getAsByteArray();
-+ if (bs.length > 1024) { this.result = mutableComponent.append("]"); return; } // Scissors
-
- for(int i = 0; i < bs.length; ++i) {
- MutableComponent mutableComponent2 = Component.literal(String.valueOf((int)bs[i])).withStyle(SYNTAX_HIGHLIGHTING_NUMBER);
-@@ -115,6 +116,7 @@ public class TextComponentTagVisitor implements TagVisitor {
- Component component = Component.literal("I").withStyle(SYNTAX_HIGHLIGHTING_NUMBER_TYPE);
- MutableComponent mutableComponent = Component.literal("[").append(component).append(";");
- int[] is = element.getAsIntArray();
-+ if (is.length > 1024) { this.result = mutableComponent.append("]"); return; } // Scissors
-
- for(int i = 0; i < is.length; ++i) {
- mutableComponent.append(" ").append(Component.literal(String.valueOf(is[i])).withStyle(SYNTAX_HIGHLIGHTING_NUMBER));
-@@ -132,6 +134,7 @@ public class TextComponentTagVisitor implements TagVisitor {
- Component component = Component.literal("L").withStyle(SYNTAX_HIGHLIGHTING_NUMBER_TYPE);
- MutableComponent mutableComponent = Component.literal("[").append(component).append(";");
- long[] ls = element.getAsLongArray();
-+ if (ls.length > 1024) { this.result = mutableComponent.append("]"); return; } // Scissors
-
- for(int i = 0; i < ls.length; ++i) {
- Component component2 = Component.literal(String.valueOf(ls[i])).withStyle(SYNTAX_HIGHLIGHTING_NUMBER);
-@@ -147,7 +150,7 @@ public class TextComponentTagVisitor implements TagVisitor {
-
- @Override
- public void visitList(ListTag element) {
-- if (element.isEmpty()) {
-+ if (element.isEmpty() || element.size() > 1024) { // Scissors
- this.result = Component.literal("[]");
- } else if (INLINE_ELEMENT_TYPES.contains(element.getElementType()) && element.size() <= 8) {
- String string = ELEMENT_SEPARATOR + " ";
-@@ -190,7 +193,7 @@ public class TextComponentTagVisitor implements TagVisitor {
-
- @Override
- public void visitCompound(CompoundTag compound) {
-- if (compound.isEmpty()) {
-+ if (compound.isEmpty() || compound.size() > 1024) { // Scissors
- this.result = Component.literal("{}");
- } else {
- MutableComponent mutableComponent = Component.literal("{");
diff --git a/patches/server/0020-Fixes-creative-killing-potion-effects-and-certain-po.patch b/patches/server/0020-Fixes-creative-killing-potion-effects-and-certain-po.patch
deleted file mode 100644
index 8e64224..0000000
--- a/patches/server/0020-Fixes-creative-killing-potion-effects-and-certain-po.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Video
-Date: Mon, 11 Apr 2022 13:33:52 -0600
-Subject: [PATCH] Fixes creative-killing potion effects and certain potion
- effect overflows
-
-
-diff --git a/src/main/java/net/minecraft/world/effect/HealOrHarmMobEffect.java b/src/main/java/net/minecraft/world/effect/HealOrHarmMobEffect.java
-index 1c7794de5f0a7238b944c9473e2cc9d011ef2306..9c594c504611b9da5fcd119284b2dcb4b59d3bf4 100644
---- a/src/main/java/net/minecraft/world/effect/HealOrHarmMobEffect.java
-+++ b/src/main/java/net/minecraft/world/effect/HealOrHarmMobEffect.java
-@@ -16,6 +16,11 @@ class HealOrHarmMobEffect extends InstantenousMobEffect {
- @Override
- public void applyEffectTick(LivingEntity entity, int amplifier) {
- super.applyEffectTick(entity, amplifier);
-+ // Scissors start - Don't apply any healing/harming effects for Creative/Invulnerable players and cap the amplifier for those who aren't.
-+ if (entity instanceof net.minecraft.world.entity.player.Player player && (player.isCreative() || player.isInvulnerable())) return;
-+ amplifier = Math.min(Math.abs(amplifier), 124);
-+ // Scissors end
-+
- if (this.isHarm == entity.isInvertedHealAndHarm()) {
- entity.heal((float) Math.max(4 << amplifier, 0), org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason.MAGIC); // CraftBukkit
- } else {
-@@ -27,6 +32,10 @@ class HealOrHarmMobEffect extends InstantenousMobEffect {
- @Override
- public void applyInstantenousEffect(@Nullable Entity source, @Nullable Entity attacker, LivingEntity target, int amplifier, double proximity) {
- int j;
-+ // Scissors start - Don't apply any healing/harming effects for Creative/Invulnerable players and cap the amplifier for those who aren't.
-+ if (target instanceof net.minecraft.world.entity.player.Player player && (player.isCreative() || player.isInvulnerable())) return;
-+ amplifier = Math.min(Math.abs(amplifier), 124);
-+ // Scissors end
-
- if (this.isHarm == target.isInvertedHealAndHarm()) {
- j = (int) (proximity * (double) (4 << amplifier) + 0.5D);
diff --git a/patches/server/0021-Fix-negative-death-times.patch b/patches/server/0021-Fix-negative-death-times.patch
deleted file mode 100644
index 69c0571..0000000
--- a/patches/server/0021-Fix-negative-death-times.patch
+++ /dev/null
@@ -1,19 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Allink
-Date: Mon, 18 Apr 2022 16:55:19 +0100
-Subject: [PATCH] Fix negative death times
-
-
-diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
-index b95f88d5e5b4785ee063695fd81935636a0588d1..168b002377e258f84a3bb86dd8e4a5f42060e3e0 100644
---- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
-+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
-@@ -629,7 +629,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
-
- protected void tickDeath() {
- ++this.deathTime;
-- if (this.deathTime >= 20 && !this.level().isClientSide() && !this.isRemoved()) {
-+ if ((this.deathTime >= 20 || this.deathTime <= 0) && !this.level().isClientSide() && !this.isRemoved()) { // Scissors
- this.level().broadcastEntityEvent(this, (byte) 60);
- this.remove(Entity.RemovalReason.KILLED);
- }
diff --git a/patches/server/0022-Limit-amount-of-vehicle-collision-checks-to-3-and-di.patch b/patches/server/0022-Limit-amount-of-vehicle-collision-checks-to-3-and-di.patch
deleted file mode 100644
index 2eba0c0..0000000
--- a/patches/server/0022-Limit-amount-of-vehicle-collision-checks-to-3-and-di.patch
+++ /dev/null
@@ -1,100 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Allink
-Date: Thu, 21 Apr 2022 13:52:32 +0100
-Subject: [PATCH] Limit amount of vehicle collision checks to 3 and discard
- vehicles if they collide with more than 15 other entities
-
-
-diff --git a/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecart.java b/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecart.java
-index 44a6118d3bd67a95180f750c17967561946e2e87..8aece67eba8d6b558bc2441b8b8e599f86e12e4f 100644
---- a/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecart.java
-+++ b/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecart.java
-@@ -8,6 +8,7 @@ import com.mojang.datafixers.util.Pair;
- import java.util.Iterator;
- import java.util.List;
- import java.util.Map;
-+import java.util.concurrent.TimeUnit; // Scissors
- import javax.annotation.Nullable;
- import net.minecraft.BlockUtil;
- import net.minecraft.Util;
-@@ -111,6 +112,7 @@ public abstract class AbstractMinecart extends Entity {
- private double flyingX = 0.949999988079071D; // Paper - restore vanilla precision
- private double flyingY = 0.949999988079071D; // Paper - restore vanilla precision
- private double flyingZ = 0.949999988079071D; // Paper - restore vanilla precision
-+ private long lastLargeCollision = 0L; // Scissors - Add a collision debounce
- public double maxSpeed = 0.4D;
- // CraftBukkit end
-
-@@ -432,8 +434,8 @@ public abstract class AbstractMinecart extends Entity {
- if (this.getMinecartType() == AbstractMinecart.Type.RIDEABLE && this.getDeltaMovement().horizontalDistanceSqr() > 0.01D) {
- List list = this.level().getEntities((Entity) this, this.getBoundingBox().inflate(0.20000000298023224D, 0.0D, 0.20000000298023224D), EntitySelector.pushableBy(this));
-
-- if (!list.isEmpty()) {
-- Iterator iterator = list.iterator();
-+ if (!list.isEmpty() && (System.currentTimeMillis() - lastLargeCollision) >= TimeUnit.SECONDS.toMillis(5)) { // Scissors - add collision debounce, using TimeUnit for better code readability
-+ Iterator iterator = list.size() <= 15 ? list.iterator() : list.subList(0, 15).iterator(); // Scissors
-
- while (iterator.hasNext()) {
- Entity entity = (Entity) iterator.next();
-@@ -462,6 +464,14 @@ public abstract class AbstractMinecart extends Entity {
- entity.push(this);
- }
- }
-+
-+ // Scissors start - Add a collision debounce
-+ if (list.size() > 15) {
-+ this.discard();
-+ } else if (list.size() > 3) {
-+ lastLargeCollision = System.currentTimeMillis();
-+ }
-+ // Scissors end
- }
- } else {
- Iterator iterator1 = this.level().getEntities(this, this.getBoundingBox().inflate(0.20000000298023224D, 0.0D, 0.20000000298023224D)).iterator();
-diff --git a/src/main/java/net/minecraft/world/entity/vehicle/Boat.java b/src/main/java/net/minecraft/world/entity/vehicle/Boat.java
-index 5c07da62c82bc70138f6cb5007629d6974be69ac..301a72dffd4ac58333d987e85d22136498d2d82a 100644
---- a/src/main/java/net/minecraft/world/entity/vehicle/Boat.java
-+++ b/src/main/java/net/minecraft/world/entity/vehicle/Boat.java
-@@ -5,6 +5,7 @@ import com.google.common.collect.UnmodifiableIterator;
- import java.util.Iterator;
- import java.util.List;
- import java.util.function.IntFunction;
-+import java.util.concurrent.TimeUnit; // Scissors
- import javax.annotation.Nullable;
- import net.minecraft.BlockUtil;
- import net.minecraft.core.BlockPos;
-@@ -112,6 +113,7 @@ public class Boat extends Entity implements VariantHolder {
- public double unoccupiedDeceleration = -1;
- public boolean landBoats = false;
- // CraftBukkit end
-+ private long lastLargeCollision = 0L; // Scissors - Add a collision debounce
-
- public Boat(EntityType extends Boat> type, Level world) {
- super(type, world);
-@@ -465,9 +467,9 @@ public class Boat extends Entity implements VariantHolder {
- this.checkInsideBlocks();
- List list = this.level().getEntities((Entity) this, this.getBoundingBox().inflate(0.20000000298023224D, -0.009999999776482582D, 0.20000000298023224D), EntitySelector.pushableBy(this));
-
-- if (!list.isEmpty()) {
-+ if (!list.isEmpty() && (System.currentTimeMillis() - lastLargeCollision) >= TimeUnit.SECONDS.toMillis(5)) { // Scissors - add collision debounce, using TimeUnit for better code readability
- boolean flag = !this.level().isClientSide && !(this.getControllingPassenger() instanceof Player);
-- Iterator iterator = list.iterator();
-+ Iterator iterator = list.size() <= 15 ? list.iterator() : list.subList(0, 15).iterator(); // Scissors
-
- while (iterator.hasNext()) {
- Entity entity = (Entity) iterator.next();
-@@ -480,6 +482,14 @@ public class Boat extends Entity implements VariantHolder {
- }
- }
- }
-+
-+ // Scissors start - Add collision debounce
-+ if (list.size() > 15) {
-+ this.discard();
-+ } else if (list.size() > 3) {
-+ lastLargeCollision = System.currentTimeMillis();
-+ }
-+ // Scissors end
- }
-
- }
diff --git a/patches/server/0023-Add-custom-classes-used-by-Scissors.patch b/patches/server/0023-Add-custom-classes-used-by-Scissors.patch
deleted file mode 100644
index 8c5f502..0000000
--- a/patches/server/0023-Add-custom-classes-used-by-Scissors.patch
+++ /dev/null
@@ -1,181 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Telesphoreo
-Date: Sat, 11 Jun 2022 22:56:59 -0500
-Subject: [PATCH] Add custom classes used by Scissors
-
-
-diff --git a/src/main/java/me/totalfreedom/scissors/MathUtility.java b/src/main/java/me/totalfreedom/scissors/MathUtility.java
-new file mode 100644
-index 0000000000000000000000000000000000000000..754b578b575137a9c48cb20dee965a9388fedb3c
---- /dev/null
-+++ b/src/main/java/me/totalfreedom/scissors/MathUtility.java
-@@ -0,0 +1,29 @@
-+package me.totalfreedom.scissors;
-+
-+public class MathUtility
-+{
-+ public static int clampInt(int number, int minimum, int maximum)
-+ {
-+ return Math.min(Math.max(number, minimum), maximum);
-+ }
-+
-+ public static long clampLong(long number, long minimum, long maximum)
-+ {
-+ return Math.min(Math.max(number, minimum), maximum);
-+ }
-+
-+ public static double clampDouble(double number, double minimum, double maximum)
-+ {
-+ return Math.min(Math.max(number, minimum), maximum);
-+ }
-+
-+ public static int safeDoubleToInt(double number)
-+ {
-+ return (int) clampDouble(number, Integer.MIN_VALUE, Integer.MAX_VALUE);
-+ }
-+
-+ public static int safeLongToInt(long number)
-+ {
-+ return (int) clampLong(number, Integer.MIN_VALUE, Integer.MAX_VALUE);
-+ }
-+}
-diff --git a/src/main/java/me/totalfreedom/scissors/NbtUtility.java b/src/main/java/me/totalfreedom/scissors/NbtUtility.java
-new file mode 100644
-index 0000000000000000000000000000000000000000..b3efac47ee700d5a7ff26452d6bcbf2f687a32cf
---- /dev/null
-+++ b/src/main/java/me/totalfreedom/scissors/NbtUtility.java
-@@ -0,0 +1,75 @@
-+package me.totalfreedom.scissors;
-+
-+import java.nio.charset.StandardCharsets;
-+import javax.annotation.Nullable;
-+import net.minecraft.nbt.CompoundTag;
-+import net.minecraft.nbt.ListTag;
-+import net.minecraft.nbt.Tag;
-+
-+public class NbtUtility
-+{
-+ public static final long MAXIMUM_SIZE = (256 * 1024);
-+
-+ public static long getTagSize(@Nullable Tag tag, int depth)
-+ {
-+ if (depth > 512)
-+ {
-+ return 0;
-+ }
-+ if (tag == null)
-+ {
-+ return 0;
-+ }
-+
-+ long size = 0;
-+
-+ if (tag.getType() == CompoundTag.TYPE)
-+ {
-+ CompoundTag compoundTag = (CompoundTag) tag;
-+ for (String key : compoundTag.getAllKeys())
-+ {
-+ size += key.getBytes(StandardCharsets.UTF_8).length;
-+ size += getTagSize(compoundTag.get(key), depth + 1);
-+ }
-+ }
-+ else if (tag.getType() == ListTag.TYPE)
-+ {
-+ ListTag listTag = (ListTag) tag;
-+ for (Tag tag1 : listTag)
-+ {
-+ size += getTagSize(tag1, depth + 1);
-+ }
-+ }
-+ else
-+ {
-+ size += tag.getAsString().getBytes(StandardCharsets.UTF_8).length;
-+ }
-+
-+ return size;
-+ }
-+
-+ public static long getTagSize(@Nullable CompoundTag tag)
-+ {
-+ return getTagSize(tag, 0);
-+ }
-+
-+ public static boolean isTooLarge(@Nullable CompoundTag tag)
-+ {
-+ if (tag == null)
-+ {
-+ return false;
-+ }
-+ return getTagSize(tag) > MAXIMUM_SIZE;
-+ }
-+
-+ public static class Item
-+ {
-+ public static CompoundTag removeItemData(CompoundTag tag)
-+ {
-+ CompoundTag cleaned = new CompoundTag();
-+ cleaned.putString("id", tag.getString("id"));
-+ cleaned.putByte("Count", tag.getByte("Count"));
-+ return cleaned;
-+ }
-+ }
-+}
-diff --git a/src/main/java/me/totalfreedom/scissors/PositionUtility.java b/src/main/java/me/totalfreedom/scissors/PositionUtility.java
-new file mode 100644
-index 0000000000000000000000000000000000000000..c5dcc833d6f2c0daa1d0c2a7ab81430f25e0b2f3
---- /dev/null
-+++ b/src/main/java/me/totalfreedom/scissors/PositionUtility.java
-@@ -0,0 +1,53 @@
-+package me.totalfreedom.scissors;
-+
-+import net.minecraft.core.BlockPos;
-+import net.minecraft.world.entity.Entity;
-+import net.minecraft.world.level.Level;
-+import net.minecraft.world.level.border.WorldBorder;
-+import net.minecraft.world.phys.Vec3;
-+
-+public class PositionUtility
-+{
-+
-+ public static Vec3 getValidVec3FromBlockPos(BlockPos blockPos, Entity entity)
-+ {
-+ final BlockPos validBlockPos = getValidBlockPos(blockPos, entity);
-+
-+ return new Vec3(validBlockPos.getX(), validBlockPos.getY(), validBlockPos.getZ());
-+ }
-+
-+ public static BlockPos getValidBlockPos(BlockPos blockPos, Entity entity)
-+ {
-+ final Level level = entity.level();
-+
-+ try
-+ {
-+ if (level.isInWorldBounds(blockPos))
-+ {
-+ return blockPos;
-+ }
-+ else
-+ {
-+ final int x = blockPos.getX();
-+ final int y = blockPos.getY();
-+ final int z = blockPos.getZ();
-+
-+ final WorldBorder worldBorder = level.getWorldBorder();
-+
-+ final int maxX = MathUtility.safeDoubleToInt(worldBorder.getMaxX());
-+ final int maxY = level.getMaxBuildHeight();
-+ final int maxZ = MathUtility.safeDoubleToInt(worldBorder.getMaxZ());
-+
-+ final int minX = MathUtility.safeDoubleToInt(worldBorder.getMinX());
-+ final int minY = level.getMinBuildHeight();
-+ final int minZ = MathUtility.safeDoubleToInt(worldBorder.getMinZ());
-+
-+ return new BlockPos(MathUtility.clampInt(x, minX, maxX), MathUtility.clampInt(y, minY, maxY), MathUtility.clampInt(z, minZ, maxZ));
-+ }
-+ }
-+ catch (Exception e)
-+ { // If we throw some sort of exception due to the position being crazy, catch it
-+ return new BlockPos(0, 0, 0);
-+ }
-+ }
-+}
diff --git a/patches/server/0024-Reset-large-tags.patch b/patches/server/0024-Reset-large-tags.patch
deleted file mode 100644
index 494b867..0000000
--- a/patches/server/0024-Reset-large-tags.patch
+++ /dev/null
@@ -1,313 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Allink
-Date: Mon, 18 Apr 2022 03:56:09 +0100
-Subject: [PATCH] Reset large tags
-
-
-diff --git a/src/main/java/net/minecraft/world/ContainerHelper.java b/src/main/java/net/minecraft/world/ContainerHelper.java
-index 4092c7a8c2b0d9d26e6f4d97386735236300d132..04c47cf1a920ae6c356449df801227ee14f6dfb7 100644
---- a/src/main/java/net/minecraft/world/ContainerHelper.java
-+++ b/src/main/java/net/minecraft/world/ContainerHelper.java
-@@ -2,6 +2,7 @@ package net.minecraft.world;
-
- import java.util.List;
- import java.util.function.Predicate;
-+import me.totalfreedom.scissors.NbtUtility; // Scissors
- import net.minecraft.core.NonNullList;
- import net.minecraft.nbt.CompoundTag;
- import net.minecraft.nbt.ListTag;
-@@ -22,10 +23,12 @@ public class ContainerHelper {
-
- public static CompoundTag saveAllItems(CompoundTag nbt, NonNullList stacks, boolean setIfEmpty) {
- ListTag listTag = new ListTag();
-+ long total = 0; // Scissors
-
- for(int i = 0; i < stacks.size(); ++i) {
- ItemStack itemStack = stacks.get(i);
- if (!itemStack.isEmpty()) {
-+ total += NbtUtility.getTagSize(itemStack.getTag()); // Scissors
- CompoundTag compoundTag = new CompoundTag();
- compoundTag.putByte("Slot", (byte)i);
- itemStack.save(compoundTag);
-@@ -33,7 +36,7 @@ public class ContainerHelper {
- }
- }
-
-- if (!listTag.isEmpty() || setIfEmpty) {
-+ if ((!listTag.isEmpty() || setIfEmpty) && !(total > NbtUtility.MAXIMUM_SIZE)) { // Scissors
- nbt.put("Items", listTag);
- }
-
-@@ -42,11 +45,19 @@ public class ContainerHelper {
-
- public static void loadAllItems(CompoundTag nbt, NonNullList stacks) {
- ListTag listTag = nbt.getList("Items", 10);
-+ long total = 0; // Scissors - Account for items inside containers
-
- for(int i = 0; i < listTag.size(); ++i) {
- CompoundTag compoundTag = listTag.getCompound(i);
- int j = compoundTag.getByte("Slot") & 255;
- if (j >= 0 && j < stacks.size()) {
-+ // Scissors start
-+ total += NbtUtility.getTagSize(compoundTag);
-+ if (total >= NbtUtility.MAXIMUM_SIZE) {
-+ stacks.clear();
-+ break;
-+ }
-+ // Scissors end
- stacks.set(j, ItemStack.of(compoundTag));
- }
- }
-diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java
-index d0f7baa80cb7d0883304abe2ed990c258a0d92b6..bedd53797391005d70dcdd61c5ed6d56a32fee5c 100644
---- a/src/main/java/net/minecraft/world/item/ItemStack.java
-+++ b/src/main/java/net/minecraft/world/item/ItemStack.java
-@@ -21,6 +21,7 @@ import java.util.function.Predicate;
- import java.util.stream.Collectors;
- import java.util.stream.Stream;
- import javax.annotation.Nullable;
-+import me.totalfreedom.scissors.NbtUtility; // Scissors
- import net.minecraft.ChatFormatting;
- import net.minecraft.Util;
- import net.minecraft.advancements.CriteriaTriggers;
-@@ -254,6 +255,12 @@ public final class ItemStack {
-
- // CraftBukkit - break into own method
- private void load(CompoundTag nbttagcompound) {
-+ // Scissors start - Reset large tags
-+ if (NbtUtility.isTooLarge(nbttagcompound)) {
-+ // Reset tag without destroying item
-+ nbttagcompound = NbtUtility.Item.removeItemData(nbttagcompound);
-+ }
-+ // Scissors end
- this.item = (Item) BuiltInRegistries.ITEM.get(new ResourceLocation(nbttagcompound.getString("id")));
- this.count = nbttagcompound.getByte("Count");
- if (nbttagcompound.contains("tag", 10)) {
-@@ -563,7 +570,11 @@ public final class ItemStack {
- nbt.putString("id", minecraftkey == null ? "minecraft:air" : minecraftkey.toString());
- nbt.putByte("Count", (byte) this.count);
- if (this.tag != null) {
-- nbt.put("tag", this.tag.copy());
-+ // Scissors start - Don't save large tags
-+ if (!NbtUtility.isTooLarge(this.tag)) {
-+ nbt.put("tag", this.tag.copy());
-+ }
-+ // Scissors end
- }
-
- return nbt;
-@@ -893,6 +904,7 @@ public final class ItemStack {
- // Paper end
-
- public void setTag(@Nullable CompoundTag nbt) {
-+ if (NbtUtility.isTooLarge(nbt)) return; // Scissors - Ignore large tags
- this.tag = nbt;
- this.processEnchantOrder(this.tag); // Paper
- if (this.getItem().canBeDepleted()) {
-diff --git a/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java
-index f5ad7ddf13cbb6452c2927aef9b54eae3335b4c6..041e3c8fb7c9ca69a7c7c1c952ed9915a75d7752 100644
---- a/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java
-+++ b/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java
-@@ -9,6 +9,7 @@ import java.util.Iterator;
- import java.util.List;
- import java.util.Map;
- import javax.annotation.Nullable;
-+import me.totalfreedom.scissors.NbtUtility; // Scissors
- import net.minecraft.SharedConstants;
- import net.minecraft.Util;
- import net.minecraft.core.BlockPos;
-@@ -212,6 +213,17 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit
- public List transaction = new java.util.ArrayList();
-
- public List getContents() {
-+ // Scissors start - Account for items inside containers
-+ long total = 0;
-+
-+ for (ItemStack item : this.items) {
-+ total += NbtUtility.getTagSize(item.getOrCreateTag());
-+ }
-+
-+ if (total > NbtUtility.MAXIMUM_SIZE) {
-+ this.items.clear();
-+ }
-+ // Scissors end
- return this.items;
- }
-
-diff --git a/src/main/java/net/minecraft/world/level/block/entity/BarrelBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BarrelBlockEntity.java
-index 416aa989ebb18a8741cc9d605a1180ab830f6643..a9a8c9e68e5b767dec2c26495685da88e0caa627 100644
---- a/src/main/java/net/minecraft/world/level/block/entity/BarrelBlockEntity.java
-+++ b/src/main/java/net/minecraft/world/level/block/entity/BarrelBlockEntity.java
-@@ -1,5 +1,6 @@
- package net.minecraft.world.level.block.entity;
-
-+import me.totalfreedom.scissors.NbtUtility; // Scissors
- import net.minecraft.core.BlockPos;
- import net.minecraft.core.Direction;
- import net.minecraft.core.NonNullList;
-@@ -34,6 +35,17 @@ public class BarrelBlockEntity extends RandomizableContainerBlockEntity {
-
- @Override
- public List getContents() {
-+ // Scissors start - Account for items inside containers
-+ long total = 0;
-+
-+ for (ItemStack item : this.items) {
-+ total += NbtUtility.getTagSize(item.getOrCreateTag());
-+ }
-+
-+ if (total > NbtUtility.MAXIMUM_SIZE) {
-+ this.items.clear();
-+ }
-+ // Scissors end
- return this.items;
- }
-
-diff --git a/src/main/java/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java
-index c57efcb9a79337ec791e4e8f6671612f0a82b441..2cbb8170953cb555411db8c171a3d1d91eb799bb 100644
---- a/src/main/java/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java
-+++ b/src/main/java/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java
-@@ -3,6 +3,7 @@ package net.minecraft.world.level.block.entity;
- import java.util.Arrays;
- import java.util.Iterator;
- import javax.annotation.Nullable;
-+import me.totalfreedom.scissors.NbtUtility; // Scissors
- import net.minecraft.core.BlockPos;
- import net.minecraft.core.Direction;
- import net.minecraft.core.NonNullList;
-@@ -73,6 +74,17 @@ public class BrewingStandBlockEntity extends BaseContainerBlockEntity implements
- }
-
- public List getContents() {
-+ // Scissors start - Account for items inside containers
-+ long total = 0;
-+
-+ for (ItemStack item : this.items) {
-+ total += NbtUtility.getTagSize(item.getOrCreateTag());
-+ }
-+
-+ if (total > NbtUtility.MAXIMUM_SIZE) {
-+ this.items.clear();
-+ }
-+ // Scissors end
- return this.items;
- }
-
-diff --git a/src/main/java/net/minecraft/world/level/block/entity/ChestBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/ChestBlockEntity.java
-index a71414397bd45ee7bcacfeef0041d80dfa25f114..f51abf1722e98d7ce9e616d84472d847e597eafb 100644
---- a/src/main/java/net/minecraft/world/level/block/entity/ChestBlockEntity.java
-+++ b/src/main/java/net/minecraft/world/level/block/entity/ChestBlockEntity.java
-@@ -1,5 +1,6 @@
- package net.minecraft.world.level.block.entity;
-
-+import me.totalfreedom.scissors.NbtUtility; // Scissors
- import net.minecraft.core.BlockPos;
- import net.minecraft.core.Direction;
- import net.minecraft.core.NonNullList;
-@@ -40,6 +41,17 @@ public class ChestBlockEntity extends RandomizableContainerBlockEntity implement
- private int maxStack = MAX_STACK;
-
- public List getContents() {
-+ // Scissors start - Account for items inside containers
-+ long total = 0;
-+
-+ for (ItemStack item : this.items) {
-+ total += NbtUtility.getTagSize(item.getOrCreateTag());
-+ }
-+
-+ if (total > NbtUtility.MAXIMUM_SIZE) {
-+ this.items.clear();
-+ }
-+ // Scissors end
- return this.items;
- }
-
-diff --git a/src/main/java/net/minecraft/world/level/block/entity/DispenserBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/DispenserBlockEntity.java
-index 881379681c39230a00b3a1f11cd87498984396c7..d0513b72cdaec3b67b9341d251367b193bafa40c 100644
---- a/src/main/java/net/minecraft/world/level/block/entity/DispenserBlockEntity.java
-+++ b/src/main/java/net/minecraft/world/level/block/entity/DispenserBlockEntity.java
-@@ -1,5 +1,6 @@
- package net.minecraft.world.level.block.entity;
-
-+import me.totalfreedom.scissors.NbtUtility; // Scissors
- import net.minecraft.core.BlockPos;
- import net.minecraft.core.NonNullList;
- import net.minecraft.nbt.CompoundTag;
-@@ -28,6 +29,17 @@ public class DispenserBlockEntity extends RandomizableContainerBlockEntity {
- private int maxStack = MAX_STACK;
-
- public List getContents() {
-+ // Scissors start - Account for items inside containers
-+ long total = 0;
-+
-+ for (ItemStack item : this.items) {
-+ total += NbtUtility.getTagSize(item.getOrCreateTag());
-+ }
-+
-+ if (total > NbtUtility.MAXIMUM_SIZE) {
-+ this.items.clear();
-+ }
-+ // Scissors end
- return this.items;
- }
-
-diff --git a/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java
-index d4dcf7fe26474ae07374e7761d823bc5c8b54f97..7352183f7eaa1ddcd028e53f4b66a1c34e32b988 100644
---- a/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java
-+++ b/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java
-@@ -6,6 +6,7 @@ import java.util.function.BooleanSupplier;
- import java.util.stream.Collectors;
- import java.util.stream.IntStream;
- import javax.annotation.Nullable;
-+import me.totalfreedom.scissors.NbtUtility; // Scissors
- import net.minecraft.core.BlockPos;
- import net.minecraft.core.Direction;
- import net.minecraft.core.NonNullList;
-@@ -56,6 +57,17 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
- private int maxStack = MAX_STACK;
-
- public List getContents() {
-+ // Scissors start - Account for items inside containers
-+ long total = 0;
-+
-+ for (ItemStack item : this.items) {
-+ total += NbtUtility.getTagSize(item.getOrCreateTag());
-+ }
-+
-+ if (total > NbtUtility.MAXIMUM_SIZE) {
-+ this.items.clear();
-+ }
-+ // Scissors end
- return this.items;
- }
-
-diff --git a/src/main/java/net/minecraft/world/level/block/entity/ShulkerBoxBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/ShulkerBoxBlockEntity.java
-index 1fa22445a4ecc8c08dbcf0cc6bd39dc5003604c4..9f12fbcd8d0c75de1d8c06bed2c64a0acdc877c9 100644
---- a/src/main/java/net/minecraft/world/level/block/entity/ShulkerBoxBlockEntity.java
-+++ b/src/main/java/net/minecraft/world/level/block/entity/ShulkerBoxBlockEntity.java
-@@ -4,6 +4,7 @@ import java.util.Iterator;
- import java.util.List;
- import java.util.stream.IntStream;
- import javax.annotation.Nullable;
-+import me.totalfreedom.scissors.NbtUtility; // Scissors
- import net.minecraft.core.BlockPos;
- import net.minecraft.core.Direction;
- import net.minecraft.core.NonNullList;
-@@ -61,6 +62,17 @@ public class ShulkerBoxBlockEntity extends RandomizableContainerBlockEntity impl
- public boolean opened;
-
- public List getContents() {
-+ // Scissors start - Account for items inside containers
-+ long total = 0;
-+
-+ for (ItemStack item : this.itemStacks) {
-+ total += NbtUtility.getTagSize(item.getOrCreateTag());
-+ }
-+
-+ if (total > NbtUtility.MAXIMUM_SIZE) {
-+ this.itemStacks.clear();
-+ }
-+ // Scissors end
- return this.itemStacks;
- }
-
diff --git a/patches/server/0025-Don-t-log-invalid-teams-to-console.patch b/patches/server/0025-Don-t-log-invalid-teams-to-console.patch
deleted file mode 100644
index c9d51fa..0000000
--- a/patches/server/0025-Don-t-log-invalid-teams-to-console.patch
+++ /dev/null
@@ -1,19 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Allink
-Date: Tue, 17 May 2022 05:57:52 +0100
-Subject: [PATCH] Don't log invalid teams to console
-
-
-diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
-index 168b002377e258f84a3bb86dd8e4a5f42060e3e0..065d2c1543832190bd8bdcd4b553542115c07e64 100644
---- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
-+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
-@@ -861,7 +861,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
- boolean flag = scoreboardteam != null && this.level().getScoreboard().addPlayerToTeam(this.getStringUUID(), scoreboardteam);
-
- if (!flag) {
-- LivingEntity.LOGGER.warn("Unable to add mob to team \"{}\" (that team probably doesn't exist)", s);
-+ // Scissors - Prevent log spam possible with this error message, easily provokable by players in creative.
- }
- }
-
diff --git a/patches/server/0026-Fixes-out-of-bounds-HangingEntity-crash-exploit.patch b/patches/server/0026-Fixes-out-of-bounds-HangingEntity-crash-exploit.patch
deleted file mode 100644
index 1358980..0000000
--- a/patches/server/0026-Fixes-out-of-bounds-HangingEntity-crash-exploit.patch
+++ /dev/null
@@ -1,24 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Video
-Date: Fri, 19 Aug 2022 00:49:38 -0600
-Subject: [PATCH] Fixes out of bounds HangingEntity crash exploit
-
-
-diff --git a/src/main/java/net/minecraft/world/entity/decoration/HangingEntity.java b/src/main/java/net/minecraft/world/entity/decoration/HangingEntity.java
-index 66cf0a6cd1525ecf2615809210a26d55f445d07d..74fb79d4ea11f88f2c0de65b492a5fecc49684f1 100644
---- a/src/main/java/net/minecraft/world/entity/decoration/HangingEntity.java
-+++ b/src/main/java/net/minecraft/world/entity/decoration/HangingEntity.java
-@@ -270,6 +270,13 @@ public abstract class HangingEntity extends Entity {
- public void readAdditionalSaveData(CompoundTag nbt) {
- BlockPos blockposition = new BlockPos(nbt.getInt("TileX"), nbt.getInt("TileY"), nbt.getInt("TileZ"));
-
-+ // Scissors start - Fixes exploit where bad TileX, TileY, and TileZ coordinates can crash servers
-+ if (level().isLoadedAndInBounds(blockposition))
-+ {
-+ this.pos = blockposition;
-+ }
-+ // Scissors end
-+
- if (!blockposition.closerThan(this.blockPosition(), 16.0D)) {
- HangingEntity.LOGGER.error("Hanging entity at invalid position: {}", blockposition);
- } else {
diff --git a/patches/server/0027-Add-MasterBlockFireEvent.patch b/patches/server/0027-Add-MasterBlockFireEvent.patch
deleted file mode 100644
index b90aea3..0000000
--- a/patches/server/0027-Add-MasterBlockFireEvent.patch
+++ /dev/null
@@ -1,158 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Allink
-Date: Mon, 4 Jul 2022 22:12:19 +0100
-Subject: [PATCH] Add MasterBlockFireEvent
-
-
-diff --git a/src/main/java/net/minecraft/world/level/block/CommandBlock.java b/src/main/java/net/minecraft/world/level/block/CommandBlock.java
-index 2e7c03b00bc941b86df6a7f1b2b188c9f0aede22..0ae03d3934ad7b2b38afa45a65c7753dcbe796d2 100644
---- a/src/main/java/net/minecraft/world/level/block/CommandBlock.java
-+++ b/src/main/java/net/minecraft/world/level/block/CommandBlock.java
-@@ -1,5 +1,6 @@
- package net.minecraft.world.level.block;
-
-+import me.totalfreedom.scissors.event.block.MasterBlockFireEvent; // Scissors
- import com.mojang.logging.LogUtils;
- import net.minecraft.core.BlockPos;
- import net.minecraft.core.Direction;
-@@ -25,6 +26,7 @@ import net.minecraft.world.level.block.state.properties.BlockStateProperties;
- import net.minecraft.world.level.block.state.properties.BooleanProperty;
- import net.minecraft.world.level.block.state.properties.DirectionProperty;
- import net.minecraft.world.phys.BlockHitResult;
-+import org.bukkit.Location; // Scissors
- import org.slf4j.Logger;
-
- import org.bukkit.event.block.BlockRedstoneEvent; // CraftBukkit
-@@ -117,6 +119,15 @@ public class CommandBlock extends BaseEntityBlock implements GameMasterBlock {
- }
-
- private void execute(BlockState state, Level world, BlockPos pos, BaseCommandBlock executor, boolean hasCommand) {
-+ // Scissors start - Add master block fire event
-+ final MasterBlockFireEvent event = new MasterBlockFireEvent(new Location(world.getWorld(), pos.getX(), pos.getY(), pos.getZ()));
-+
-+ if (!event.callEvent())
-+ {
-+ return;
-+ }
-+ // Scissors end
-+
- if (hasCommand) {
- executor.performCommand(world);
- } else {
-diff --git a/src/main/java/net/minecraft/world/level/block/entity/JigsawBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/JigsawBlockEntity.java
-index 182e16c1d968707a11329150d71b7d01df6c6e52..8582a9369cffe0eebeb82a81fc413d0bf4ad28ed 100644
---- a/src/main/java/net/minecraft/world/level/block/entity/JigsawBlockEntity.java
-+++ b/src/main/java/net/minecraft/world/level/block/entity/JigsawBlockEntity.java
-@@ -2,6 +2,7 @@ package net.minecraft.world.level.block.entity;
-
- import java.util.Arrays;
- import java.util.Optional;
-+import me.totalfreedom.scissors.event.block.MasterBlockFireEvent; // Scissors
- import net.minecraft.core.BlockPos;
- import net.minecraft.core.Holder;
- import net.minecraft.core.Registry;
-@@ -17,6 +18,7 @@ import net.minecraft.world.level.block.JigsawBlock;
- import net.minecraft.world.level.block.state.BlockState;
- import net.minecraft.world.level.levelgen.structure.pools.JigsawPlacement;
- import net.minecraft.world.level.levelgen.structure.pools.StructureTemplatePool;
-+import org.bukkit.Location; // Scissors
-
- public class JigsawBlockEntity extends BlockEntity {
- public static final String TARGET = "target";
-@@ -107,6 +109,16 @@ public class JigsawBlockEntity extends BlockEntity {
- }
-
- public void generate(ServerLevel world, int maxDepth, boolean keepJigsaws) {
-+ // Scissors start - Add master block fire event
-+ final BlockPos pos = this.getBlockPos();
-+ final MasterBlockFireEvent event = new MasterBlockFireEvent(new Location(this.getLevel().getWorld(), pos.getX(), pos.getY(), pos.getZ()));
-+
-+ if (!event.callEvent())
-+ {
-+ return;
-+ }
-+ // Scissors end
-+
- BlockPos blockPos = this.getBlockPos().relative(this.getBlockState().getValue(JigsawBlock.ORIENTATION).front());
- Registry registry = world.registryAccess().registryOrThrow(Registries.TEMPLATE_POOL);
- // Paper start - Replace getHolderOrThrow with a null check
-diff --git a/src/main/java/net/minecraft/world/level/block/entity/StructureBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/StructureBlockEntity.java
-index e8ecced687261861953899a3bea162dbc03977b4..30720203173b23ccdbb0789f7e2adbbe180c7c69 100644
---- a/src/main/java/net/minecraft/world/level/block/entity/StructureBlockEntity.java
-+++ b/src/main/java/net/minecraft/world/level/block/entity/StructureBlockEntity.java
-@@ -5,6 +5,7 @@ import java.util.Objects;
- import java.util.Optional;
- import java.util.stream.Stream;
- import javax.annotation.Nullable;
-+import me.totalfreedom.scissors.event.block.MasterBlockFireEvent; // Scissors
- import net.minecraft.ResourceLocationException;
- import net.minecraft.Util;
- import net.minecraft.core.BlockPos;
-@@ -29,6 +30,7 @@ import net.minecraft.world.level.levelgen.structure.templatesystem.BlockRotProce
- import net.minecraft.world.level.levelgen.structure.templatesystem.StructurePlaceSettings;
- import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate;
- import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplateManager;
-+import org.bukkit.Location; // Scissors
-
- public class StructureBlockEntity extends BlockEntity {
- private static final int SCAN_CORNER_BLOCKS_RANGE = 5;
-@@ -264,7 +266,7 @@ public class StructureBlockEntity extends BlockEntity {
- return false;
- } else {
- BlockPos blockPos = this.getBlockPos();
-- int i = 80;
-+ // Scissors - Obfuscation fixes
- BlockPos blockPos2 = new BlockPos(blockPos.getX() - 80, this.level.getMinBuildHeight(), blockPos.getZ() - 80);
- BlockPos blockPos3 = new BlockPos(blockPos.getX() + 80, this.level.getMaxBuildHeight() - 1, blockPos.getZ() + 80);
- Stream stream = this.getRelatedCorners(blockPos2, blockPos3);
-@@ -321,6 +323,16 @@ public class StructureBlockEntity extends BlockEntity {
-
- public boolean saveStructure(boolean interactive) {
- if (this.mode == StructureMode.SAVE && !this.level.isClientSide && this.structureName != null) {
-+ // Scissors start - Add master block fire event
-+ final BlockPos pos = this.getBlockPos();
-+ final MasterBlockFireEvent event = new MasterBlockFireEvent(new Location(this.getLevel().getWorld(), pos.getX(), pos.getY(), pos.getZ()));
-+
-+ if (!event.callEvent())
-+ {
-+ return false;
-+ }
-+ // Scissors end
-+
- BlockPos blockPos = this.getBlockPos().offset(this.structurePos);
- ServerLevel serverLevel = (ServerLevel)this.level;
- StructureTemplateManager structureTemplateManager = serverLevel.getStructureManager();
-@@ -358,6 +370,16 @@ public class StructureBlockEntity extends BlockEntity {
-
- public boolean loadStructure(ServerLevel world, boolean interactive) {
- if (this.mode == StructureMode.LOAD && this.structureName != null) {
-+ // Scissors start - Add master block fire event
-+ final BlockPos blockPos = this.getBlockPos();
-+ final MasterBlockFireEvent event = new MasterBlockFireEvent(new Location(this.getLevel().getWorld(), blockPos.getX(), blockPos.getY(), blockPos.getZ()));
-+
-+ if (!event.callEvent())
-+ {
-+ return false;
-+ }
-+ // Scissors end
-+
- StructureTemplateManager structureTemplateManager = world.getStructureManager();
-
- Optional optional;
-@@ -403,6 +425,16 @@ public class StructureBlockEntity extends BlockEntity {
- }
-
- public void unloadStructure() {
-+ // Scissors start - Add master block fire event
-+ final BlockPos blockPos = this.getBlockPos();
-+ final MasterBlockFireEvent event = new MasterBlockFireEvent(new Location(this.getLevel().getWorld(), blockPos.getX(), blockPos.getY(), blockPos.getZ()));
-+
-+ if (!event.callEvent())
-+ {
-+ return;
-+ }
-+ // Scissors end
-+
- if (this.structureName != null) {
- ServerLevel serverLevel = (ServerLevel)this.level;
- StructureTemplateManager structureTemplateManager = serverLevel.getStructureManager();
diff --git a/patches/server/0028-Add-spectator-teleport-event.patch b/patches/server/0028-Add-spectator-teleport-event.patch
deleted file mode 100644
index cd389cf..0000000
--- a/patches/server/0028-Add-spectator-teleport-event.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Allink
-Date: Tue, 5 Jul 2022 04:12:31 +0100
-Subject: [PATCH] Add spectator teleport event
-
-
-diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
-index 65bb221993147a558995b36fb835f7b82e0eb4bd..4ea2c551d924f976a8de9e2ae521544f323fbec4 100644
---- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
-+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
-@@ -1,5 +1,6 @@
- package net.minecraft.server.network;
-
-+import me.totalfreedom.scissors.event.player.SpectatorTeleportEvent; // Scissors
- import com.google.common.collect.Lists;
- import com.google.common.primitives.Floats;
- import com.mojang.authlib.GameProfile;
-@@ -2006,6 +2007,12 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
- Entity entity = packet.getEntity(worldserver);
-
- if (entity != null) {
-+ // Scissors start - Add spectator teleport event
-+ final SpectatorTeleportEvent event = new SpectatorTeleportEvent(this.player.getBukkitEntity(), entity.getBukkitEntity());
-+ if (!event.callEvent()) {
-+ return;
-+ }
-+ // Scissors end
- this.player.teleportTo(worldserver, entity.getX(), entity.getY(), entity.getZ(), entity.getYRot(), entity.getXRot(), org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.SPECTATE); // CraftBukkit
- return;
- }
diff --git a/patches/server/0029-Prevent-invalid-container-events.patch b/patches/server/0029-Prevent-invalid-container-events.patch
deleted file mode 100644
index 44ed9ea..0000000
--- a/patches/server/0029-Prevent-invalid-container-events.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Allink
-Date: Sun, 10 Jul 2022 02:55:01 +0100
-Subject: [PATCH] Prevent invalid container events
-
-
-diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
-index 4ea2c551d924f976a8de9e2ae521544f323fbec4..83ae366b4f52261e2e2b65a4183d7ca823edd315 100644
---- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
-+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
-@@ -30,6 +30,7 @@ import java.util.function.UnaryOperator;
- import java.util.stream.Collectors;
- import java.util.stream.Stream;
- import javax.annotation.Nullable;
-+import net.kyori.adventure.text.format.NamedTextColor; // Scissors
- import net.minecraft.ChatFormatting;
- import net.minecraft.SharedConstants;
- import net.minecraft.Util;
-@@ -2900,6 +2901,18 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
- return;
- }
-
-+ // Scissors start - Do not call events when the slot/button number is invalid
-+ final int sentSlotNum = packet.getSlotNum();
-+ if((Mth.clamp(sentSlotNum, -1, this.player.containerMenu.slots.size() - 1) != sentSlotNum) && sentSlotNum != -999)
-+ {
-+ this.getCraftPlayer().kick(
-+ net.kyori.adventure.text.Component.text("Invalid container click slot (Hacking?)")
-+ .color(NamedTextColor.RED)
-+ );
-+ return;
-+ }
-+ // Scissors end
-+
- InventoryView inventory = this.player.containerMenu.getBukkitView();
- SlotType type = inventory.getSlotType(packet.getSlotNum());
-
diff --git a/patches/server/0030-Disable-running-commands-in-books-by-default.patch b/patches/server/0030-Disable-running-commands-in-books-by-default.patch
deleted file mode 100644
index 18bb269..0000000
--- a/patches/server/0030-Disable-running-commands-in-books-by-default.patch
+++ /dev/null
@@ -1,73 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Allink
-Date: Sun, 10 Jul 2022 10:29:03 +0100
-Subject: [PATCH] Disable running commands in books by default
-
-
-diff --git a/src/main/java/net/minecraft/world/item/WrittenBookItem.java b/src/main/java/net/minecraft/world/item/WrittenBookItem.java
-index 31911c09fe15753ae32fa39417bdc9e9de552a88..b810a5afcb2343174e37efb7dd8a36b968b07c3a 100644
---- a/src/main/java/net/minecraft/world/item/WrittenBookItem.java
-+++ b/src/main/java/net/minecraft/world/item/WrittenBookItem.java
-@@ -2,6 +2,7 @@ package net.minecraft.world.item;
-
- import java.util.List;
- import javax.annotation.Nullable;
-+import me.totalfreedom.scissors.ScissorsConfig; // Scissors
- import net.minecraft.ChatFormatting;
- import net.minecraft.commands.CommandSourceStack;
- import net.minecraft.core.BlockPos;
-@@ -9,8 +10,7 @@ import net.minecraft.nbt.CompoundTag;
- import net.minecraft.nbt.ListTag;
- import net.minecraft.nbt.StringTag;
- import net.minecraft.nbt.Tag;
--import net.minecraft.network.chat.Component;
--import net.minecraft.network.chat.ComponentUtils;
-+import net.minecraft.network.chat.*; // Scissors
- import net.minecraft.stats.Stats;
- import net.minecraft.util.StringUtil;
- import net.minecraft.world.InteractionHand;
-@@ -161,9 +161,43 @@ public class WrittenBookItem extends Item {
- component2 = Component.literal(text);
- }
-
-- return Component.Serializer.toJson(component2);
-+ return Component.Serializer.toJson(!ScissorsConfig.runCommandsInBooks ? sanitize(component2, 0) : component2); // Scissors - Allow server owners to disable run command in books
- }
-
-+ // Scissors start - Allow server owners to disable run command in books
-+ public static Component sanitize(Component component, int depth)
-+ {
-+ if (depth > 128)
-+ {
-+ return Component.nullToEmpty("Sanitization function depth limit exceeded");
-+ }
-+
-+ MutableComponent component2 = component.copy();
-+
-+ final Style style = component2.getStyle();
-+ final ClickEvent clickEvent = style.getClickEvent();
-+
-+ if (clickEvent != null && clickEvent.getAction().equals(ClickEvent.Action.RUN_COMMAND))
-+ {
-+ final String clickEventValue = clickEvent.getValue();
-+
-+ component2 = component2.copy().setStyle(style
-+ .withClickEvent(null)
-+ .withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, Component.nullToEmpty("Would've " + (clickEventValue.startsWith("/") ? "ran" : "said") + ": " + clickEvent.getValue())))
-+ );
-+ }
-+
-+ final List processedExtra = component2.getSiblings()
-+ .stream()
-+ .map(comp -> sanitize(comp, depth + 1))
-+ .toList();
-+ component2.getSiblings().clear();
-+ component2.getSiblings().addAll(processedExtra);
-+
-+ return component2;
-+ }
-+ // Scissors end
-+
- @Override
- public boolean isFoil(ItemStack stack) {
- return true;
diff --git a/patches/server/0031-Validate-block-entity-entity-tag-query-positions.patch b/patches/server/0031-Validate-block-entity-entity-tag-query-positions.patch
deleted file mode 100644
index addf64d..0000000
--- a/patches/server/0031-Validate-block-entity-entity-tag-query-positions.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Luna
-Date: Mon, 11 Jul 2022 17:29:12 -0300
-Subject: [PATCH] Validate block entity/entity tag query positions
-
-
-diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
-index 83ae366b4f52261e2e2b65a4183d7ca823edd315..67b5447ffcf54c54b2087df456690a9bed98fbd3 100644
---- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
-+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
-@@ -1262,7 +1262,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
- if (this.player.hasPermissions(2)) {
- Entity entity = this.player.level().getEntity(packet.getEntityId());
-
-- if (entity != null) {
-+ if (entity != null && this.player.distanceToSqr(entity.position().x, entity.position().y, entity.position().z) < 32 * 32) { // Scissors - Validate entity tag query positions
- CompoundTag nbttagcompound = entity.saveWithoutId(new CompoundTag());
-
- this.player.connection.send(new ClientboundTagQueryPacket(packet.getTransactionId(), nbttagcompound));
-@@ -1274,7 +1274,10 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
- @Override
- public void handleBlockEntityTagQuery(ServerboundBlockEntityTagQuery packet) {
- PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
-- if (this.player.hasPermissions(2)) {
-+ // Scissors start - Validate block entity tag query positions
-+ if (this.player.hasPermissions(2) && this.player.level().isLoadedAndInBounds(packet.getPos())
-+ && this.player.distanceToSqr(packet.getPos().getX(), packet.getPos().getY(), packet.getPos().getZ()) < 32 * 32) {
-+ // Scissors end
- BlockEntity tileentity = this.player.level().getBlockEntity(packet.getPos());
- CompoundTag nbttagcompound = tileentity != null ? tileentity.saveWithoutMetadata() : null;
-
diff --git a/patches/server/0032-Fix-ClickEvents-on-Signs-bypassing-permissions.patch b/patches/server/0032-Fix-ClickEvents-on-Signs-bypassing-permissions.patch
deleted file mode 100644
index 56e90f5..0000000
--- a/patches/server/0032-Fix-ClickEvents-on-Signs-bypassing-permissions.patch
+++ /dev/null
@@ -1,67 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Allink
-Date: Wed, 13 Jul 2022 12:13:22 +0100
-Subject: [PATCH] Fix ClickEvents on Signs bypassing permissions
-
-
-diff --git a/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java
-index 38cde466714e5663cd416b6afd5d2558e139ec09..ed48eaae75e709361a260421934b6b925ae9b427 100644
---- a/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java
-+++ b/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java
-@@ -8,8 +8,10 @@ import java.util.Objects;
- import java.util.UUID;
- import java.util.function.UnaryOperator;
- import javax.annotation.Nullable;
-+import me.totalfreedom.scissors.ScissorsConfig; // Scissors
- import net.minecraft.commands.CommandSource;
- import net.minecraft.commands.CommandSourceStack;
-+import net.minecraft.commands.Commands; // Scissors
- import net.minecraft.core.BlockPos;
- import net.minecraft.nbt.CompoundTag;
- import net.minecraft.nbt.NbtOps;
-@@ -19,6 +21,7 @@ import net.minecraft.network.chat.Component;
- import net.minecraft.network.chat.ComponentUtils;
- import net.minecraft.network.chat.Style;
- import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket;
-+import net.minecraft.server.MinecraftServer; // Scissors
- import net.minecraft.server.level.ServerLevel;
- import net.minecraft.server.level.ServerPlayer;
- import net.minecraft.server.network.FilteredText;
-@@ -30,6 +33,7 @@ import net.minecraft.world.level.block.SignBlock;
- import net.minecraft.world.level.block.state.BlockState;
- import net.minecraft.world.phys.Vec2;
- import net.minecraft.world.phys.Vec3;
-+import org.bukkit.craftbukkit.entity.CraftHumanEntity; // Scissors
- import org.slf4j.Logger;
- import org.bukkit.block.sign.Side;
- import org.bukkit.craftbukkit.block.CraftBlock;
-@@ -37,6 +41,7 @@ import org.bukkit.craftbukkit.util.CraftChatMessage;
- import org.bukkit.entity.Player;
- import org.bukkit.event.block.SignChangeEvent;
- // CraftBukkit end
-+import org.bukkit.craftbukkit.CraftServer; // Scissors
-
- public class SignBlockEntity extends BlockEntity implements CommandSource { // CraftBukkit - implements
-
-@@ -291,6 +296,21 @@ public class SignBlockEntity extends BlockEntity implements CommandSource { // C
- }
- player.getServer().getCommands().performPrefixedCommand(this.createCommandSourceStack(((org.bukkit.craftbukkit.entity.CraftPlayer) event.getPlayer()).getHandle(), world, pos), event.getMessage());
- // Paper end
-+ // Scissors start - Add optional permissions to command signs
-+ final MinecraftServer vanillaServer = player.getServer();
-+ final CraftServer craftServer = vanillaServer.server;
-+ final CraftHumanEntity craftPlayer = player.getBukkitEntity();
-+ final Commands commands = vanillaServer.getCommands();
-+
-+ if (ScissorsConfig.commandSignsBypassPermissions)
-+ {
-+ commands.performPrefixedCommand(this.createCommandSourceStack(((org.bukkit.craftbukkit.entity.CraftPlayer) event.getPlayer()).getHandle(), world, pos), event.getMessage());
-+ }
-+ else
-+ {
-+ craftServer.dispatchCommand(craftPlayer, command.substring(1));
-+ }
-+ // Scissors end
- flag1 = true;
- }
- }
diff --git a/patches/server/0033-Refuse-to-convert-legacy-messages-over-1k-characters.patch b/patches/server/0033-Refuse-to-convert-legacy-messages-over-1k-characters.patch
deleted file mode 100644
index 7eac5d1..0000000
--- a/patches/server/0033-Refuse-to-convert-legacy-messages-over-1k-characters.patch
+++ /dev/null
@@ -1,18 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Allink
-Date: Tue, 16 Aug 2022 17:13:02 +0100
-Subject: [PATCH] Refuse to convert legacy messages over 1k characters
-
-
-diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftChatMessage.java b/src/main/java/org/bukkit/craftbukkit/util/CraftChatMessage.java
-index 0f70be614f8f5350ad558d0ae645cdf0027e1e76..c006ac8531cf2c029fd2fac449f96736a4afed0d 100644
---- a/src/main/java/org/bukkit/craftbukkit/util/CraftChatMessage.java
-+++ b/src/main/java/org/bukkit/craftbukkit/util/CraftChatMessage.java
-@@ -199,6 +199,7 @@ public final class CraftChatMessage {
- }
-
- public static Component[] fromString(String message, boolean keepNewlines, boolean plain) {
-+ if (message.length() > 1_000) return new Component[]{Component.empty()}; // Scissors - Refuse to convert legacy messages over 1k characters
- return new StringMessage(message, keepNewlines, plain).getOutput();
- }
-
diff --git a/patches/server/0034-Prevent-velocity-freeze.patch b/patches/server/0034-Prevent-velocity-freeze.patch
deleted file mode 100644
index 71456b4..0000000
--- a/patches/server/0034-Prevent-velocity-freeze.patch
+++ /dev/null
@@ -1,94 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Allink
-Date: Sun, 27 Nov 2022 05:14:18 +0000
-Subject: [PATCH] Prevent velocity freeze
-
-
-diff --git a/src/main/java/net/minecraft/world/entity/projectile/AbstractHurtingProjectile.java b/src/main/java/net/minecraft/world/entity/projectile/AbstractHurtingProjectile.java
-index 6c9a8f062f989db022154155e8a05b334a0510da..978fad27ad17de03d108ade2c2bfa464b7d83491 100644
---- a/src/main/java/net/minecraft/world/entity/projectile/AbstractHurtingProjectile.java
-+++ b/src/main/java/net/minecraft/world/entity/projectile/AbstractHurtingProjectile.java
-@@ -1,5 +1,6 @@
- package net.minecraft.world.entity.projectile;
-
-+import me.totalfreedom.scissors.MathUtility; // Scissors
- import net.minecraft.core.particles.ParticleOptions;
- import net.minecraft.core.particles.ParticleTypes;
- import net.minecraft.nbt.CompoundTag;
-@@ -41,9 +42,13 @@ public abstract class AbstractHurtingProjectile extends Projectile {
- double d6 = Math.sqrt(d3 * d3 + d4 * d4 + d5 * d5);
-
- if (d6 != 0.0D) {
-- this.xPower = d3 / d6 * 0.1D;
-- this.yPower = d4 / d6 * 0.1D;
-- this.zPower = d5 / d6 * 0.1D;
-+ // Scissors start - Prevent projectile velocity freeze
-+ //this.xPower = d3 / d6 * 0.1D;
-+ //this.yPower = d4 / d6 * 0.1D;
-+ //this.zPower = d5 / d6 * 0.1D;
-+
-+ setPower(d3 / d6 * .1d, d4 / d6 * .1d, d5 / d6 * .1d);
-+ // Scissors end
- }
-
- }
-@@ -141,6 +146,25 @@ public abstract class AbstractHurtingProjectile extends Projectile {
- nbt.put("power", this.newDoubleList(new double[]{this.xPower, this.yPower, this.zPower}));
- }
-
-+ // Scissors start - Prevent projectile velocity freeze
-+ public void setPower(double xPower, double yPower, double zPower)
-+ {
-+ if (Double.isInfinite(xPower) || Double.isInfinite(yPower) || Double.isInfinite(zPower))
-+ {
-+ return;
-+ }
-+
-+ if (Double.isNaN(xPower) || Double.isNaN(yPower) || Double.isNaN(zPower))
-+ {
-+ return;
-+ }
-+
-+ this.xPower = MathUtility.clampDouble(xPower, -1024, 1024);
-+ this.yPower = MathUtility.clampDouble(yPower, -1024, 1024);
-+ this.zPower = MathUtility.clampDouble(zPower, -1024, 1024);
-+ }
-+ // Scissors end
-+
- @Override
- public void readAdditionalSaveData(CompoundTag nbt) {
- super.readAdditionalSaveData(nbt);
-@@ -148,9 +172,13 @@ public abstract class AbstractHurtingProjectile extends Projectile {
- ListTag nbttaglist = nbt.getList("power", 6);
-
- if (nbttaglist.size() == 3) {
-- this.xPower = nbttaglist.getDouble(0);
-- this.yPower = nbttaglist.getDouble(1);
-- this.zPower = nbttaglist.getDouble(2);
-+ // Scissors start - Prevent projectile velocity freeze
-+ //this.xPower = nbttaglist.getDouble(0);
-+ //this.yPower = nbttaglist.getDouble(1);
-+ //this.zPower = nbttaglist.getDouble(2);
-+
-+ setPower(nbttaglist.getDouble(0), nbttaglist.getDouble(1), nbttaglist.getDouble(2));
-+ // Scissors end
- }
- }
-
-@@ -184,9 +212,13 @@ public abstract class AbstractHurtingProjectile extends Projectile {
- Vec3 vec3d = entity.getLookAngle();
-
- this.setDeltaMovement(vec3d);
-- this.xPower = vec3d.x * 0.1D;
-- this.yPower = vec3d.y * 0.1D;
-- this.zPower = vec3d.z * 0.1D;
-+ // Scissors start - Prevent projectile velocity freeze
-+ //this.xPower = vec3d.x * 0.1D;
-+ //this.yPower = vec3d.y * 0.1D;
-+ //this.zPower = vec3d.z * 0.1D;
-+
-+ setPower(vec3d.x * 0.1D, vec3d.y * 0.1D, vec3d.z * 0.1D);
-+ // Scissors end
- this.setOwner(entity);
- }
-
diff --git a/patches/server/0035-Add-configuration-option-to-disable-chat-signatures.patch b/patches/server/0035-Add-configuration-option-to-disable-chat-signatures.patch
deleted file mode 100644
index a02e9bb..0000000
--- a/patches/server/0035-Add-configuration-option-to-disable-chat-signatures.patch
+++ /dev/null
@@ -1,105 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Allink
-Date: Tue, 31 Jan 2023 23:16:52 +0000
-Subject: [PATCH] Add configuration option to disable chat signatures
-
-
-diff --git a/src/main/java/net/minecraft/network/chat/OutgoingChatMessage.java b/src/main/java/net/minecraft/network/chat/OutgoingChatMessage.java
-index 74cf1c043beef03cfd5adf481414a5ee78bef2a6..516c61cbb8299828b2f28d4564d08ae1829649b5 100644
---- a/src/main/java/net/minecraft/network/chat/OutgoingChatMessage.java
-+++ b/src/main/java/net/minecraft/network/chat/OutgoingChatMessage.java
-@@ -1,5 +1,6 @@
- package net.minecraft.network.chat;
-
-+import me.totalfreedom.scissors.ScissorsConfig; // Scissors
- import net.minecraft.server.level.ServerPlayer;
-
- public interface OutgoingChatMessage {
-@@ -44,10 +45,21 @@ public interface OutgoingChatMessage {
- // Paper end
- PlayerChatMessage playerChatMessage = this.message.filter(filterMaskEnabled);
- playerChatMessage = unsigned != null ? playerChatMessage.withUnsignedContent(unsigned) : playerChatMessage; // Paper
-- if (!playerChatMessage.isFullyFiltered()) {
-+ // Scissors start
-+ if (!playerChatMessage.isFullyFiltered() && ScissorsConfig.chatSignaturesEnabled) {
- sender.connection.sendPlayerChatMessage(playerChatMessage, params);
-+ return;
- }
-
-+ sender.connection.sendPlayerChatMessage(new PlayerChatMessage(
-+ SignedMessageLink.unsigned(playerChatMessage.sender()),
-+ null,
-+ SignedMessageBody.unsigned(playerChatMessage.signedContent()),
-+ unsigned,
-+ playerChatMessage.filterMask(),
-+ playerChatMessage.result()
-+ ), params);
-+ // Scissors end
- }
- }
- }
-diff --git a/src/main/java/net/minecraft/network/chat/SignedMessageChain.java b/src/main/java/net/minecraft/network/chat/SignedMessageChain.java
-index c0a80824a0307ea673805015119cc834b268f0dc..9f28f86b1b56ea55ab39f6ac988c1f47c5312c6c 100644
---- a/src/main/java/net/minecraft/network/chat/SignedMessageChain.java
-+++ b/src/main/java/net/minecraft/network/chat/SignedMessageChain.java
-@@ -4,6 +4,7 @@ import com.mojang.logging.LogUtils;
- import java.time.Instant;
- import java.util.UUID;
- import javax.annotation.Nullable;
-+import me.totalfreedom.scissors.ScissorsConfig; // Scissors
- import net.minecraft.util.SignatureUpdater;
- import net.minecraft.util.SignatureValidator;
- import net.minecraft.util.Signer;
-@@ -41,7 +42,7 @@ public class SignedMessageChain {
- if (!playerChatMessage.verify(signatureValidator)) {
- throw new SignedMessageChain.DecodeException(Component.translatable("multiplayer.disconnect.unsigned_chat"), true, org.bukkit.event.player.PlayerKickEvent.Cause.UNSIGNED_CHAT); // Paper - kick event causes
- } else {
-- if (playerChatMessage.hasExpiredServer(Instant.now())) {
-+ if (playerChatMessage.hasExpiredServer(Instant.now()) && ScissorsConfig.chatSignaturesEnabled) { // Scissors
- LOGGER.warn("Received expired chat: '{}'. Is the client/server system time unsynchronized?", (Object)body.content());
- }
-
-diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
-index 67b5447ffcf54c54b2087df456690a9bed98fbd3..94cc122aad0e48687ea9f25cd810f07dc893acc6 100644
---- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
-+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
-@@ -1,5 +1,6 @@
- package net.minecraft.server.network;
-
-+import me.totalfreedom.scissors.ScissorsConfig; // Scissors
- import me.totalfreedom.scissors.event.player.SpectatorTeleportEvent; // Scissors
- import com.google.common.collect.Lists;
- import com.google.common.primitives.Floats;
-@@ -2220,7 +2221,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
- }
-
- private void handleMessageDecodeFailure(SignedMessageChain.DecodeException exception) {
-- if (exception.shouldDisconnect()) {
-+ if (exception.shouldDisconnect() && ScissorsConfig.chatSignaturesEnabled) { // Scissors - Do not kick when chat signatures are disabled
- this.disconnect(exception.getComponent(), exception.kickCause); // Paper - kick event causes
- } else {
- this.player.sendSystemMessage(exception.getComponent().copy().withStyle(ChatFormatting.RED));
-@@ -2276,6 +2277,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
- Optional optional = this.lastSeenMessages.applyUpdate(acknowledgment);
-
- if (optional.isEmpty()) {
-+ if (!ScissorsConfig.chatSignaturesEnabled) return optional; // Scissors
- ServerGamePacketListenerImpl.LOGGER.warn("Failed to validate message acknowledgements from {}", this.player.getName().getString());
- this.disconnect(ServerGamePacketListenerImpl.CHAT_VALIDATION_FAILED, org.bukkit.event.player.PlayerKickEvent.Cause.CHAT_VALIDATION_FAILED); // Paper - kick event causes
- }
-@@ -2484,6 +2486,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
-
- synchronized (this.lastSeenMessages) {
- if (!this.lastSeenMessages.applyOffset(packet.offset())) {
-+ if (!ScissorsConfig.chatSignaturesEnabled) return; // Scissors
- ServerGamePacketListenerImpl.LOGGER.warn("Failed to validate message acknowledgements from {}", this.player.getName().getString());
- this.disconnect(ServerGamePacketListenerImpl.CHAT_VALIDATION_FAILED, org.bukkit.event.player.PlayerKickEvent.Cause.CHAT_VALIDATION_FAILED); // Paper - kick event causes
- }
-@@ -3462,6 +3465,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
- @Override
- public void handleChatSessionUpdate(ServerboundChatSessionUpdatePacket packet) {
- PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
-+ if (!ScissorsConfig.chatSignaturesEnabled) return; // Scissors
- RemoteChatSession.Data remotechatsession_a = packet.chatSession();
- ProfilePublicKey.Data profilepublickey_a = this.chatSession != null ? this.chatSession.profilePublicKey().data() : null;
- ProfilePublicKey.Data profilepublickey_a1 = remotechatsession_a.profilePublicKey();
diff --git a/patches/server/0036-Patch-large-selector-distance-crash.patch b/patches/server/0036-Patch-large-selector-distance-crash.patch
deleted file mode 100644
index 6dd8079..0000000
--- a/patches/server/0036-Patch-large-selector-distance-crash.patch
+++ /dev/null
@@ -1,78 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Luna
-Date: Sun, 2 Apr 2023 16:29:51 -0300
-Subject: [PATCH] Patch large selector distance crash
-
-
-diff --git a/src/main/java/net/minecraft/advancements/critereon/MinMaxBounds.java b/src/main/java/net/minecraft/advancements/critereon/MinMaxBounds.java
-index 8897496323378080135127f53db004d576476c21..5f957d3241c1931f8166bc9e4960cef15679e932 100644
---- a/src/main/java/net/minecraft/advancements/critereon/MinMaxBounds.java
-+++ b/src/main/java/net/minecraft/advancements/critereon/MinMaxBounds.java
-@@ -129,9 +129,9 @@ public interface MinMaxBounds {
-
- public static record Doubles(Optional min, Optional max, Optional minSq, Optional maxSq) implements MinMaxBounds {
- public static final MinMaxBounds.Doubles ANY = new MinMaxBounds.Doubles(Optional.empty(), Optional.empty());
-- public static final Codec CODEC = MinMaxBounds.createCodec(Codec.DOUBLE, MinMaxBounds.Doubles::new);
-+ public static final Codec CODEC = MinMaxBounds.createCodec(Codec.DOUBLE, MinMaxBounds.Doubles::new); // Scissors - compile fixes
-
-- private Doubles(Optional optional, Optional optional2) {
-+ public Doubles(Optional optional, Optional optional2) { // Scissors - private -> public
- this(optional, optional2, squareOpt(optional), squareOpt(optional2));
- }
-
-@@ -202,7 +202,7 @@ public interface MinMaxBounds {
-
- public static record Ints(Optional min, Optional max, Optional minSq, Optional maxSq) implements MinMaxBounds {
- public static final MinMaxBounds.Ints ANY = new MinMaxBounds.Ints(Optional.empty(), Optional.empty());
-- public static final Codec CODEC = MinMaxBounds.createCodec(Codec.INT, MinMaxBounds.Ints::new);
-+ public static final Codec CODEC = MinMaxBounds.createCodec(Codec.INT, MinMaxBounds.Ints::new); // Scissors - compile fixes
-
- private Ints(Optional optional, Optional optional2) {
- this(optional, optional2, optional.map((integer) -> {
-diff --git a/src/main/java/net/minecraft/commands/arguments/selector/EntitySelector.java b/src/main/java/net/minecraft/commands/arguments/selector/EntitySelector.java
-index 73c15a0c56a103ba4e62f0a51af8d42566b07245..6cb3e86f2d661a55536b782729f768ef72163223 100644
---- a/src/main/java/net/minecraft/commands/arguments/selector/EntitySelector.java
-+++ b/src/main/java/net/minecraft/commands/arguments/selector/EntitySelector.java
-@@ -5,11 +5,13 @@ import com.mojang.brigadier.exceptions.CommandSyntaxException;
- import java.util.Collections;
- import java.util.Iterator;
- import java.util.List;
-+import java.util.Optional; // Scissors
- import java.util.UUID;
- import java.util.function.BiConsumer;
- import java.util.function.Function;
- import java.util.function.Predicate;
- import javax.annotation.Nullable;
-+import me.totalfreedom.scissors.MathUtility; // Scissors
- import net.minecraft.advancements.critereon.MinMaxBounds;
- import net.minecraft.commands.CommandSourceStack;
- import net.minecraft.commands.arguments.EntityArgument;
-@@ -60,9 +62,26 @@ public class EntitySelector {
- this.includesEntities = includesNonPlayers;
- this.worldLimited = localWorldOnly;
- this.predicate = basePredicate;
-- this.range = distance;
-+ // Scissors start - Patch large selector distance crash
-+ this.range = new MinMaxBounds.Doubles(
-+ distance.min().map(min -> Math.min(min, 1024)),
-+ distance.max().map(max -> Math.min(max, 1024))
-+ );
- this.position = positionOffset;
-- this.aabb = box;
-+ if (box != null) {
-+ this.aabb = new AABB(
-+ MathUtility.clampDouble(box.minX, -1024, 1025),
-+ MathUtility.clampDouble(box.minY, -1024, 1025),
-+ MathUtility.clampDouble(box.minZ, -1024, 1025),
-+ MathUtility.clampDouble(box.maxX, -1024, 1025),
-+ MathUtility.clampDouble(box.maxY, -1024, 1025),
-+ MathUtility.clampDouble(box.maxZ, -1024, 1025),
-+ false
-+ );
-+ } else {
-+ this.aabb = null;
-+ }
-+ // Scissors end
- this.order = sorter;
- this.currentEntity = senderOnly;
- this.playerName = playerName;
diff --git a/patches/server/0037-Patch-invalid-entity-rotation-log-spam.patch b/patches/server/0037-Patch-invalid-entity-rotation-log-spam.patch
deleted file mode 100644
index e19406d..0000000
--- a/patches/server/0037-Patch-invalid-entity-rotation-log-spam.patch
+++ /dev/null
@@ -1,19 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Allink
-Date: Mon, 20 Mar 2023 07:04:50 +0000
-Subject: [PATCH] Patch invalid entity rotation log spam
-
-
-diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
-index e8845d6ec1bcba6df2eb8e1af0d658b10299831a..015d5e9b6de5f1fb466e1801bdf5fb430ba91f35 100644
---- a/src/main/java/net/minecraft/world/entity/Entity.java
-+++ b/src/main/java/net/minecraft/world/entity/Entity.java
-@@ -4696,7 +4696,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
-
- public void setXRot(float pitch) {
- if (!Float.isFinite(pitch)) {
-- Util.logAndPauseIfInIde("Invalid entity rotation: " + pitch + ", discarding.");
-+ // Scissors - Patch invalid entity rotation log spam
- } else {
- this.xRot = pitch;
- }
diff --git a/patches/server/0038-Limit-sculk-catalyst-cursor-positions.patch b/patches/server/0038-Limit-sculk-catalyst-cursor-positions.patch
deleted file mode 100644
index 0759bd9..0000000
--- a/patches/server/0038-Limit-sculk-catalyst-cursor-positions.patch
+++ /dev/null
@@ -1,19 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Luna
-Date: Mon, 10 Apr 2023 13:56:18 -0300
-Subject: [PATCH] Limit sculk catalyst cursor positions
-
-
-diff --git a/src/main/java/net/minecraft/world/level/block/SculkSpreader.java b/src/main/java/net/minecraft/world/level/block/SculkSpreader.java
-index de90a216321f7d82310a0d1c915fefe64360534c..7e52f6c26234cf6fa092151d51c0c6b70dc22ca8 100644
---- a/src/main/java/net/minecraft/world/level/block/SculkSpreader.java
-+++ b/src/main/java/net/minecraft/world/level/block/SculkSpreader.java
-@@ -181,7 +181,7 @@ public class SculkSpreader {
-
- while (iterator.hasNext()) {
- SculkSpreader.ChargeCursor sculkspreader_a = (SculkSpreader.ChargeCursor) iterator.next();
--
-+ if (!world.getMinecraftWorld().isLoadedAndInBounds(sculkspreader_a.getPos())) continue; // Scissors
- sculkspreader_a.update(world, pos, random, this, shouldConvertToBlock);
- if (sculkspreader_a.charge <= 0) {
- world.levelEvent(3006, sculkspreader_a.getPos(), 0);
diff --git a/patches/server/0039-Limit-map-decorations.patch b/patches/server/0039-Limit-map-decorations.patch
deleted file mode 100644
index 310eaa6..0000000
--- a/patches/server/0039-Limit-map-decorations.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Luna
-Date: Fri, 28 Apr 2023 16:29:23 -0300
-Subject: [PATCH] Limit map decorations
-
-
-diff --git a/src/main/java/net/minecraft/network/protocol/game/ClientboundMapItemDataPacket.java b/src/main/java/net/minecraft/network/protocol/game/ClientboundMapItemDataPacket.java
-index 81f3e64d94fa17e45411e5c1641d9c5a2fe3d2e2..bcf6e2ce9f00d1688a5fa00ec055a57389346922 100644
---- a/src/main/java/net/minecraft/network/protocol/game/ClientboundMapItemDataPacket.java
-+++ b/src/main/java/net/minecraft/network/protocol/game/ClientboundMapItemDataPacket.java
-@@ -65,7 +65,8 @@ public class ClientboundMapItemDataPacket implements Packet 32) {
-+ return;
-+ }
-+ // Scissors end
- int i = 1 << this.scale;
- float f = (float) (x - (double) this.centerX) / (float) i;
- float f1 = (float) (z - (double) this.centerZ) / (float) i;
diff --git a/patches/server/0040-Prevent-player-banning-using-duplicate-UUIDs.patch b/patches/server/0040-Prevent-player-banning-using-duplicate-UUIDs.patch
deleted file mode 100644
index cbce7eb..0000000
--- a/patches/server/0040-Prevent-player-banning-using-duplicate-UUIDs.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Luna
-Date: Fri, 28 Apr 2023 16:44:50 -0300
-Subject: [PATCH] Prevent player banning using duplicate UUIDs
-
-
-diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
-index 3f26fdcc5cbf0a684ad724ab8c042d0053cc187e..c6f36a6b967aeb6ffdf5b099b2692e038401dc79 100644
---- a/src/main/java/net/minecraft/server/level/ServerLevel.java
-+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
-@@ -1664,7 +1664,13 @@ public class ServerLevel extends Level implements WorldGenLevel {
- if (entity != null) {
- ServerLevel.LOGGER.warn("Force-added player with duplicate UUID {}", player.getUUID());
- entity.unRide();
-- this.removePlayerImmediately((ServerPlayer) entity, Entity.RemovalReason.DISCARDED);
-+ // Scissors start - Prevent player banning using duplicate UUIDs
-+ if (entity instanceof ServerPlayer serverPlayer) {
-+ this.removePlayerImmediately(serverPlayer, Entity.RemovalReason.DISCARDED);
-+ } else {
-+ entity.discard();
-+ }
-+ // Scissors end
- }
-
- this.entityLookup.addNewEntity(player); // Paper - rewite chunk system
diff --git a/patches/server/0041-Don-t-warn-on-duplicate-entity-UUIDs.patch b/patches/server/0041-Don-t-warn-on-duplicate-entity-UUIDs.patch
deleted file mode 100644
index 6667b27..0000000
--- a/patches/server/0041-Don-t-warn-on-duplicate-entity-UUIDs.patch
+++ /dev/null
@@ -1,19 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Luna
-Date: Fri, 28 Apr 2023 16:46:00 -0300
-Subject: [PATCH] Don't warn on duplicate entity UUIDs
-
-
-diff --git a/src/main/java/io/papermc/paper/chunk/system/entity/EntityLookup.java b/src/main/java/io/papermc/paper/chunk/system/entity/EntityLookup.java
-index 15ee41452992714108efe53b708b5a4e1da7c1ff..5054dce35127cb0132431021578c345fcbb1f92a 100644
---- a/src/main/java/io/papermc/paper/chunk/system/entity/EntityLookup.java
-+++ b/src/main/java/io/papermc/paper/chunk/system/entity/EntityLookup.java
-@@ -415,7 +415,7 @@ public final class EntityLookup implements LevelEntityGetter {
- return false;
- }
- if (this.entityByUUID.containsKey(entity.getUUID())) {
-- LOGGER.warn("Entity uuid already exists: " + entity.getUUID() + ", mapped to " + this.entityByUUID.get(entity.getUUID()) + ", can't add " + entity);
-+ // Scissors - Don't warn on duplicate entity UUIDs
- return false;
- }
- this.entityById.put(entity.getId(), entity);
diff --git a/patches/server/0042-Fix-component-extra-empty-array-exploit.patch b/patches/server/0042-Fix-component-extra-empty-array-exploit.patch
deleted file mode 100644
index df0a0c3..0000000
--- a/patches/server/0042-Fix-component-extra-empty-array-exploit.patch
+++ /dev/null
@@ -1,18 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Luna
-Date: Mon, 29 May 2023 19:34:50 -0300
-Subject: [PATCH] Fix component extra empty array exploit
-
-
-diff --git a/src/main/java/net/minecraft/network/chat/Component.java b/src/main/java/net/minecraft/network/chat/Component.java
-index 9cb6fa8e35c89f73e7c95dbe219a4bf6d00b60a9..fa6151a2361684426bdd3bf3b433fe4dbd0cf47b 100644
---- a/src/main/java/net/minecraft/network/chat/Component.java
-+++ b/src/main/java/net/minecraft/network/chat/Component.java
-@@ -266,6 +266,7 @@ public interface Component extends Message, FormattedText, Iterable {
- if (!jsonelement.isJsonObject()) {
- if (jsonelement.isJsonArray()) {
- JsonArray jsonarray = jsonelement.getAsJsonArray();
-+ if (jsonarray.size() <= 0) throw new JsonParseException("Unexpected empty array of components"); // Scissors
-
- ichatmutablecomponent = null;
- Iterator iterator = jsonarray.iterator();
diff --git a/patches/server/0043-Add-depth-limit-to-Component-deserializer.patch b/patches/server/0043-Add-depth-limit-to-Component-deserializer.patch
deleted file mode 100644
index c8d87de..0000000
--- a/patches/server/0043-Add-depth-limit-to-Component-deserializer.patch
+++ /dev/null
@@ -1,125 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Luna
-Date: Wed, 31 May 2023 18:14:00 -0300
-Subject: [PATCH] Add depth limit to Component deserializer
-
-
-diff --git a/src/main/java/net/minecraft/network/chat/Component.java b/src/main/java/net/minecraft/network/chat/Component.java
-index fa6151a2361684426bdd3bf3b433fe4dbd0cf47b..4dd93e02f2b18e5c75be14ff8f052220ca69f427 100644
---- a/src/main/java/net/minecraft/network/chat/Component.java
-+++ b/src/main/java/net/minecraft/network/chat/Component.java
-@@ -26,6 +26,7 @@ import java.util.List;
- import java.util.Map.Entry;
- import java.util.Optional;
- import javax.annotation.Nullable;
-+import me.totalfreedom.scissors.ScissorsConfig; // Scissors
- import net.minecraft.ChatFormatting; // Scissors
- import net.minecraft.Util;
- import net.minecraft.network.chat.contents.BlockDataSource;
-@@ -44,6 +45,7 @@ import net.minecraft.util.GsonHelper;
- import net.minecraft.util.LowerCaseEnumTypeAdapterFactory;
- // CraftBukkit start
- import com.google.common.collect.Streams;
-+import java.util.regex.Pattern; // Scissors
- import java.util.stream.Stream;
- // CraftBukkit end
-
-@@ -254,10 +256,16 @@ public interface Component extends Message, FormattedText, Iterable {
- throw new IllegalStateException("Couldn't get field 'lineStart' for JsonReader", nosuchfieldexception);
- }
- });
-+ private static final Pattern PLACEHOLDER_PATTERN = Pattern.compile("%[0-9]+\\$s"); // Scissors
-
- public Serializer() {}
-
-- public MutableComponent deserialize(JsonElement jsonelement, Type type, JsonDeserializationContext jsondeserializationcontext) throws JsonParseException {
-+ // Scissors start
-+ private MutableComponent deserialize(JsonElement jsonelement, JsonDeserializationContext jsondeserializationcontext, int depth) throws JsonParseException {
-+ if (depth > ScissorsConfig.componentDepthLimit) {
-+ throw new JsonParseException("Depth limit exceeded");
-+ }
-+ // Scissors end
- if (jsonelement.isJsonPrimitive()) {
- return Component.literal(jsonelement.getAsString());
- } else {
-@@ -273,7 +281,7 @@ public interface Component extends Message, FormattedText, Iterable {
-
- while (iterator.hasNext()) {
- JsonElement jsonelement1 = (JsonElement) iterator.next();
-- MutableComponent ichatmutablecomponent1 = this.deserialize(jsonelement1, jsonelement1.getClass(), jsondeserializationcontext);
-+ MutableComponent ichatmutablecomponent1 = this.deserialize(jsonelement1, jsondeserializationcontext, depth + 1); // Scissors
-
- if (ichatmutablecomponent == null) {
- ichatmutablecomponent = ichatmutablecomponent1;
-@@ -297,12 +305,17 @@ public interface Component extends Message, FormattedText, Iterable {
- s = GsonHelper.getAsString(jsonobject, "translate");
- String s1 = GsonHelper.getAsString(jsonobject, "fallback", (String) null);
-
-+ // Scissors start - Penalize depth for placeholders in translate & fallback
-+ long translate_placeholders = PLACEHOLDER_PATTERN.matcher(s).results().count();
-+ long fallback_placeholders = s1 != null ? PLACEHOLDER_PATTERN.matcher(s1).results().count() : 0;
-+ int penalty = (int)Math.max(translate_placeholders, fallback_placeholders) * 12;
-+ // Scissors end
- if (jsonobject.has("with")) {
- JsonArray jsonarray1 = GsonHelper.getAsJsonArray(jsonobject, "with");
- Object[] aobject = new Object[jsonarray1.size()];
-
- for (int i = 0; i < aobject.length; ++i) {
-- aobject[i] = Serializer.unwrapTextArgument(this.deserialize(jsonarray1.get(i), type, jsondeserializationcontext));
-+ aobject[i] = Serializer.unwrapTextArgument(this.deserialize(jsonarray1.get(i), jsondeserializationcontext, depth + 1 + penalty)); // Scissors
- }
-
- ichatmutablecomponent = Component.translatableWithFallback(s, s1, aobject);
-@@ -318,7 +331,7 @@ public interface Component extends Message, FormattedText, Iterable {
-
- ichatmutablecomponent = Component.score(GsonHelper.getAsString(jsonobject1, "name"), GsonHelper.getAsString(jsonobject1, "objective"));
- } else if (jsonobject.has("selector")) {
-- Optional optional = this.parseSeparator(type, jsondeserializationcontext, jsonobject);
-+ Optional optional = this.parseSeparator(jsondeserializationcontext, jsonobject, depth + 1); // Scissors
-
- ichatmutablecomponent = Component.selector(GsonHelper.getAsString(jsonobject, "selector"), optional);
- } else if (jsonobject.has("keybind")) {
-@@ -329,7 +342,7 @@ public interface Component extends Message, FormattedText, Iterable {
- }
-
- s = GsonHelper.getAsString(jsonobject, "nbt");
-- Optional optional1 = this.parseSeparator(type, jsondeserializationcontext, jsonobject);
-+ Optional optional1 = this.parseSeparator(jsondeserializationcontext, jsonobject, depth + 1); // Scissors
- boolean flag = GsonHelper.getAsBoolean(jsonobject, "interpret", false);
- Object object;
-
-@@ -356,7 +369,7 @@ public interface Component extends Message, FormattedText, Iterable {
- }
-
- for (int j = 0; j < jsonarray2.size(); ++j) {
-- ichatmutablecomponent.append((Component) this.deserialize(jsonarray2.get(j), type, jsondeserializationcontext));
-+ ichatmutablecomponent.append((Component) this.deserialize(jsonarray2.get(j), jsondeserializationcontext, depth + 1)); // Scissors
- }
- }
-
-@@ -366,6 +379,12 @@ public interface Component extends Message, FormattedText, Iterable {
- }
- }
-
-+ // Scissors start
-+ public MutableComponent deserialize(JsonElement jsonelement, Type type, JsonDeserializationContext jsondeserializationcontext) throws JsonParseException {
-+ return this.deserialize(jsonelement, jsondeserializationcontext, 1);
-+ }
-+ // Scissors end
-+
- private static Object unwrapTextArgument(Object text) {
- if (text instanceof Component) {
- Component ichatbasecomponent = (Component) text;
-@@ -384,8 +403,10 @@ public interface Component extends Message, FormattedText, Iterable {
- return text;
- }
-
-- private Optional parseSeparator(Type type, JsonDeserializationContext context, JsonObject json) {
-- return json.has("separator") ? Optional.of(this.deserialize(json.get("separator"), type, context)) : Optional.empty();
-+ // Scissors start
-+ private Optional parseSeparator(JsonDeserializationContext context, JsonObject json, int depth) {
-+ return json.has("separator") ? Optional.of(this.deserialize(json.get("separator"), context, depth + 1)) : Optional.empty();
-+ // Scissors end
- }
-
- private void serializeStyle(Style style, JsonObject json, JsonSerializationContext context) {
diff --git a/patches/server/0044-Implement-command-block-events.patch b/patches/server/0044-Implement-command-block-events.patch
deleted file mode 100644
index dc34029..0000000
--- a/patches/server/0044-Implement-command-block-events.patch
+++ /dev/null
@@ -1,86 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Allink
-Date: Fri, 2 Jun 2023 20:55:18 +0100
-Subject: [PATCH] Implement command block events
-
-
-diff --git a/src/main/java/net/minecraft/network/protocol/game/ServerboundSetCommandMinecartPacket.java b/src/main/java/net/minecraft/network/protocol/game/ServerboundSetCommandMinecartPacket.java
-index c99fc118013cb3d4043638e2001a8297e79ddf9c..cdaa81e1f2167b29ec01cc25e51a8400deb533d2 100644
---- a/src/main/java/net/minecraft/network/protocol/game/ServerboundSetCommandMinecartPacket.java
-+++ b/src/main/java/net/minecraft/network/protocol/game/ServerboundSetCommandMinecartPacket.java
-@@ -9,7 +9,7 @@ import net.minecraft.world.level.BaseCommandBlock;
- import net.minecraft.world.level.Level;
-
- public class ServerboundSetCommandMinecartPacket implements Packet {
-- private final int entity;
-+ public final int entity; // Scissors - private -> public
- private final String command;
- private final boolean trackOutput;
-
-diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
-index 94cc122aad0e48687ea9f25cd810f07dc893acc6..bcb195b1e40f562d0cd5ecca236ebba87150d236 100644
---- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
-+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
-@@ -1,6 +1,8 @@
- package net.minecraft.server.network;
-
- import me.totalfreedom.scissors.ScissorsConfig; // Scissors
-+import me.totalfreedom.scissors.event.block.CommandBlockPlayerEditEvent; // Scissors
-+import me.totalfreedom.scissors.event.block.CommandMinecartPlayerEditEvent; // Scissors
- import me.totalfreedom.scissors.event.player.SpectatorTeleportEvent; // Scissors
- import com.google.common.collect.Lists;
- import com.google.common.primitives.Floats;
-@@ -154,6 +156,7 @@ import net.minecraft.world.entity.player.Inventory;
- import net.minecraft.world.entity.player.ProfilePublicKey;
- import net.minecraft.world.entity.projectile.AbstractArrow;
- import net.minecraft.world.entity.vehicle.Boat;
-+import net.minecraft.world.entity.vehicle.MinecartCommandBlock; // Scissors
- import net.minecraft.world.item.BlockItem;
- import net.minecraft.world.item.BucketItem;
- import net.minecraft.world.item.Item;
-@@ -181,6 +184,8 @@ import net.minecraft.world.phys.Vec3;
- import net.minecraft.world.phys.shapes.BooleanOp;
- import net.minecraft.world.phys.shapes.Shapes;
- import net.minecraft.world.phys.shapes.VoxelShape;
-+import org.bukkit.craftbukkit.block.CraftCommandBlock; // Scissors
-+import org.bukkit.craftbukkit.entity.CraftMinecartCommand; // Scissors
- import org.slf4j.Logger;
-
- // CraftBukkit start
-@@ -893,6 +898,16 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
- this.player.level().getChunkAt(blockposition).setBlockEntity(tileentity);
- }
-
-+ // Scissors start
-+ CommandBlockPlayerEditEvent event = new CommandBlockPlayerEditEvent(this.getCraftPlayer(), commandblocklistenerabstract.getCommand(), s, new CraftCommandBlock(this.player.level().getWorld(), tileentitycommand));
-+
-+ if (!event.callEvent()) {
-+ return;
-+ }
-+
-+ s = event.getNewCommand();
-+ // Scissors end
-+
- commandblocklistenerabstract.setCommand(s);
- commandblocklistenerabstract.setTrackOutput(flag);
- if (!flag) {
-@@ -924,7 +939,18 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
- BaseCommandBlock commandblocklistenerabstract = packet.getCommandBlock(this.player.level());
-
- if (commandblocklistenerabstract != null) {
-- commandblocklistenerabstract.setCommand(packet.getCommand());
-+ // Scissors start - Implement command block events
-+ String command = packet.getCommand();
-+ CommandMinecartPlayerEditEvent event = new CommandMinecartPlayerEditEvent(this.getCraftPlayer(), commandblocklistenerabstract.getCommand(), command, new CraftMinecartCommand(this.cserver, (MinecartCommandBlock) this.player.level().getEntity(packet.entity)));
-+
-+ if (!event.callEvent()) {
-+ return;
-+ }
-+
-+ command = event.getNewCommand();
-+ commandblocklistenerabstract.setCommand(command);
-+
-+ // Scissors end
- commandblocklistenerabstract.setTrackOutput(packet.isTrackOutput());
- if (!packet.isTrackOutput()) {
- commandblocklistenerabstract.setLastOutput((Component) null);
diff --git a/patches/server/0045-Add-depth-limit-to-SNBT.patch b/patches/server/0045-Add-depth-limit-to-SNBT.patch
deleted file mode 100644
index dd5f315..0000000
--- a/patches/server/0045-Add-depth-limit-to-SNBT.patch
+++ /dev/null
@@ -1,110 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Allink
-Date: Fri, 2 Jun 2023 22:13:54 +0100
-Subject: [PATCH] Add depth limit to SNBT
-
-
-diff --git a/src/main/java/net/minecraft/nbt/TagParser.java b/src/main/java/net/minecraft/nbt/TagParser.java
-index ee012f1ef1ff7f2adf76d1690dbd5611af7deb4d..d79723047317c24c53fb85c423de8dd9f84891ac 100644
---- a/src/main/java/net/minecraft/nbt/TagParser.java
-+++ b/src/main/java/net/minecraft/nbt/TagParser.java
-@@ -179,9 +179,56 @@ public class TagParser {
- }
-
- this.expect('}');
-- return compoundTag;
-+ return exceedsDepthLimit(compoundTag) ? new CompoundTag() : compoundTag; // Scissors - Add depth limit to SNBT
- }
-
-+ // Scissors start - Add depth limit to SNBT
-+ private boolean exceedsDepthLimit(Tag tag) {
-+ return this.exceedsDepthLimit(0, tag);
-+ }
-+
-+ private boolean exceedsDepthLimit(long depth, Tag tag)
-+ {
-+ if (depth > 256)
-+ {
-+ return true;
-+ }
-+
-+ if (tag instanceof ListTag listTag)
-+ {
-+ for (Tag childTag : listTag)
-+ {
-+ boolean returnValue = this.exceedsDepthLimit(depth + 1, childTag);
-+
-+ if (returnValue)
-+ {
-+ return true;
-+ }
-+ }
-+ } else if (tag instanceof CompoundTag compoundTag)
-+ {
-+ for (String key: compoundTag.getAllKeys())
-+ {
-+ Tag childTag = compoundTag.get(key);
-+
-+ if (childTag == null)
-+ {
-+ continue;
-+ }
-+
-+ boolean returnValue = this.exceedsDepthLimit(depth + 1, childTag);
-+
-+ if (returnValue)
-+ {
-+ return true;
-+ }
-+ }
-+ }
-+
-+ return false;
-+ }
-+ // Scissors end
-+
- private Tag readListTag() throws CommandSyntaxException {
- this.expect('[');
- this.reader.skipWhitespace();
-@@ -213,7 +260,7 @@ public class TagParser {
- }
-
- this.expect(']');
-- return listTag;
-+ return exceedsDepthLimit(listTag) ? new ListTag() : listTag; // Scissors - Add depth limit to SNBT
- }
- }
-
-@@ -238,7 +285,7 @@ public class TagParser {
- }
-
- private List readArray(TagType> arrayTypeReader, TagType> typeReader) throws CommandSyntaxException {
-- List list = Lists.newArrayList();
-+ List list = Lists.newArrayList(); // Scissors - List -> List
-
- while(true) {
- if (this.reader.peek() != ']') {
-@@ -251,11 +298,11 @@ public class TagParser {
- }
-
- if (typeReader == ByteTag.TYPE) {
-- list.add((T)((NumericTag)tag).getAsByte());
-+ list.add(((NumericTag)tag).getAsByte()); // Scissors - Remove (T) cast
- } else if (typeReader == LongTag.TYPE) {
-- list.add((T)((NumericTag)tag).getAsLong());
-+ list.add(((NumericTag)tag).getAsLong()); // Scissors - Remove (T) cast
- } else {
-- list.add((T)((NumericTag)tag).getAsInt());
-+ list.add(((NumericTag)tag).getAsInt()); // Scissors - Remove (T) cast
- }
-
- if (this.hasElementSeparator()) {
-@@ -267,7 +314,7 @@ public class TagParser {
- }
-
- this.expect(']');
-- return list;
-+ return (List) list; // Scissors - Cast to List
- }
- }
-
diff --git a/patches/server/0046-Limit-beacon-effectRange.patch b/patches/server/0046-Limit-beacon-effectRange.patch
deleted file mode 100644
index 46ad5b9..0000000
--- a/patches/server/0046-Limit-beacon-effectRange.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Luna
-Date: Wed, 7 Jun 2023 16:50:35 -0300
-Subject: [PATCH] Limit beacon effectRange
-
-
-diff --git a/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java
-index f13943db6f2fb923c52dcf9e8bf7000041d0a362..2fdcc47dd6a813d5f7a32dc58ca67b6b965c8749 100644
---- a/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java
-+++ b/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java
-@@ -87,7 +87,7 @@ public class BeaconBlockEntity extends BlockEntity implements MenuProvider, Name
- private double effectRange = -1;
-
- public double getEffectRange() {
-- if (this.effectRange < 0) {
-+ if (this.effectRange < 0 || this.effectRange > 256) { // Scissors
- return this.levels * 10 + 10;
- } else {
- return effectRange;
-@@ -456,6 +456,7 @@ public class BeaconBlockEntity extends BlockEntity implements MenuProvider, Name
-
- this.lockKey = LockCode.fromTag(nbt);
- this.effectRange = nbt.contains(PAPER_RANGE_TAG, 6) ? nbt.getDouble(PAPER_RANGE_TAG) : -1; // Paper
-+ if (this.effectRange > 256) this.effectRange = 256; // Scissors
- }
-
- @Override
diff --git a/patches/server/0047-Improve-validation-of-ResourceLocations.patch b/patches/server/0047-Improve-validation-of-ResourceLocations.patch
deleted file mode 100644
index 3f0f967..0000000
--- a/patches/server/0047-Improve-validation-of-ResourceLocations.patch
+++ /dev/null
@@ -1,18 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Luna
-Date: Tue, 13 Jun 2023 18:29:18 -0300
-Subject: [PATCH] Improve validation of ResourceLocations
-
-
-diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftNamespacedKey.java b/src/main/java/org/bukkit/craftbukkit/util/CraftNamespacedKey.java
-index 5014192edb9616ce725fc1592832034789527b6f..64da1b0afd51720803aba0d9e86d0b1743bdb0da 100644
---- a/src/main/java/org/bukkit/craftbukkit/util/CraftNamespacedKey.java
-+++ b/src/main/java/org/bukkit/craftbukkit/util/CraftNamespacedKey.java
-@@ -21,6 +21,7 @@ public final class CraftNamespacedKey {
- }
-
- public static NamespacedKey fromMinecraft(ResourceLocation minecraft) {
-+ if (minecraft == null) throw new IllegalArgumentException("Null ResourceLocation provided"); // Scissors
- return new NamespacedKey(minecraft.getNamespace(), minecraft.getPath());
- }
-
diff --git a/patches/server/0048-Don-t-log-on-too-many-chained-updates.patch b/patches/server/0048-Don-t-log-on-too-many-chained-updates.patch
deleted file mode 100644
index 51e1ab4..0000000
--- a/patches/server/0048-Don-t-log-on-too-many-chained-updates.patch
+++ /dev/null
@@ -1,19 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Luna
-Date: Sat, 1 Jul 2023 21:22:29 -0300
-Subject: [PATCH] Don't log on too many chained updates
-
-
-diff --git a/src/main/java/net/minecraft/world/level/redstone/CollectingNeighborUpdater.java b/src/main/java/net/minecraft/world/level/redstone/CollectingNeighborUpdater.java
-index 598dc0d3a2b9387e76d7e4e19e54c4573a24bc54..9eed28bf8bc7e2fa528729cde01a535bc7040815 100644
---- a/src/main/java/net/minecraft/world/level/redstone/CollectingNeighborUpdater.java
-+++ b/src/main/java/net/minecraft/world/level/redstone/CollectingNeighborUpdater.java
-@@ -56,7 +56,7 @@ public class CollectingNeighborUpdater implements NeighborUpdater {
- this.stack.push(entry);
- }
- } else if (this.count - 1 == this.maxChainedNeighborUpdates) {
-- LOGGER.error("Too many chained neighbor updates. Skipping the rest. First skipped position: " + pos.toShortString());
-+ // Scissors - don't log
- }
-
- if (!bl) {
diff --git a/patches/server/0049-Fix-packet-related-lag-exploits.patch b/patches/server/0049-Fix-packet-related-lag-exploits.patch
deleted file mode 100644
index b3b06b6..0000000
--- a/patches/server/0049-Fix-packet-related-lag-exploits.patch
+++ /dev/null
@@ -1,46 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Luna
-Date: Tue, 4 Jul 2023 18:49:34 -0300
-Subject: [PATCH] Fix packet-related lag exploits
-
-
-diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
-index bcb195b1e40f562d0cd5ecca236ebba87150d236..fee0a88c6ccecd71ebf63651655dec2d5097f894 100644
---- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
-+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
-@@ -858,7 +858,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
- this.player.sendSystemMessage(Component.translatable("advMode.notEnabled"));
- } else if (!this.player.canUseGameMasterBlocks() && (!this.player.isCreative() || !this.player.getBukkitEntity().hasPermission("minecraft.commandblock"))) { // Paper - command block permission
- this.player.sendSystemMessage(Component.translatable("advMode.notAllowed"));
-- } else {
-+ } else if (this.player.level().isLoadedAndInBounds(packet.getPos())) { // Scissors
- BaseCommandBlock commandblocklistenerabstract = null;
- CommandBlockEntity tileentitycommand = null;
- BlockPos blockposition = packet.getPos();
-@@ -1025,7 +1025,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
- @Override
- public void handleSetStructureBlock(ServerboundSetStructureBlockPacket packet) {
- PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
-- if (this.player.canUseGameMasterBlocks()) {
-+ if (this.player.canUseGameMasterBlocks() && this.player.level().isLoadedAndInBounds(packet.getPos())) { // Scissors
- BlockPos blockposition = packet.getPos();
- BlockState iblockdata = this.player.level().getBlockState(blockposition);
- BlockEntity tileentity = this.player.level().getBlockEntity(blockposition);
-@@ -1083,7 +1083,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
- @Override
- public void handleSetJigsawBlock(ServerboundSetJigsawBlockPacket packet) {
- PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
-- if (this.player.canUseGameMasterBlocks()) {
-+ if (this.player.canUseGameMasterBlocks() && this.player.level().isLoadedAndInBounds(packet.getPos())) { // Scissors
- BlockPos blockposition = packet.getPos();
- BlockState iblockdata = this.player.level().getBlockState(blockposition);
- BlockEntity tileentity = this.player.level().getBlockEntity(blockposition);
-@@ -1106,7 +1106,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
- @Override
- public void handleJigsawGenerate(ServerboundJigsawGeneratePacket packet) {
- PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
-- if (this.player.canUseGameMasterBlocks()) {
-+ if (this.player.canUseGameMasterBlocks() && this.player.level().isLoadedAndInBounds(packet.getPos())) { // Scissors
- BlockPos blockposition = packet.getPos();
- BlockEntity tileentity = this.player.level().getBlockEntity(blockposition);
-
diff --git a/patches/server/0050-Limit-save-data-for-Bees-and-Vexes.patch b/patches/server/0050-Limit-save-data-for-Bees-and-Vexes.patch
deleted file mode 100644
index a3d10c6..0000000
--- a/patches/server/0050-Limit-save-data-for-Bees-and-Vexes.patch
+++ /dev/null
@@ -1,44 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Allink
-Date: Wed, 5 Jul 2023 22:58:24 +0100
-Subject: [PATCH] Limit save data for Bees and Vexes
-
-
-diff --git a/src/main/java/net/minecraft/world/entity/animal/Bee.java b/src/main/java/net/minecraft/world/entity/animal/Bee.java
-index 9a7956befc346e1b58f064213800fd099a052fc6..2ebedd806bafc6ff7c4bf5a962ead50ce2ad1a8a 100644
---- a/src/main/java/net/minecraft/world/entity/animal/Bee.java
-+++ b/src/main/java/net/minecraft/world/entity/animal/Bee.java
-@@ -227,8 +227,12 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal {
- @Override
- public void readAdditionalSaveData(CompoundTag nbt) {
- this.hivePos = null;
-- if (nbt.contains("HivePos")) {
-- this.hivePos = NbtUtils.readBlockPos(nbt.getCompound("HivePos"));
-+ if (nbt.contains("HivePos"))
-+ {
-+ // Scissors start - Limit HivePos
-+ final BlockPos savedHivePos = NbtUtils.readBlockPos(nbt.getCompound("HivePos"));
-+ this.hivePos = this.level().isLoadedAndInBounds(savedHivePos) ? savedHivePos : null;
-+ // Scissors end - Limit HivePos
- }
-
- this.savedFlowerPos = null;
-diff --git a/src/main/java/net/minecraft/world/entity/monster/Vex.java b/src/main/java/net/minecraft/world/entity/monster/Vex.java
-index 90e577b1a89b02c38daff2845a63dafe5ed929e1..1a2b6ee032ab6952634c9f596820db3e7374fb50 100644
---- a/src/main/java/net/minecraft/world/entity/monster/Vex.java
-+++ b/src/main/java/net/minecraft/world/entity/monster/Vex.java
-@@ -118,8 +118,12 @@ public class Vex extends Monster implements TraceableEntity {
- @Override
- public void readAdditionalSaveData(CompoundTag nbt) {
- super.readAdditionalSaveData(nbt);
-- if (nbt.contains("BoundX")) {
-- this.boundOrigin = new BlockPos(nbt.getInt("BoundX"), nbt.getInt("BoundY"), nbt.getInt("BoundZ"));
-+ if (nbt.contains("BoundX"))
-+ {
-+ // Scissors start - Limit Vex bound origin
-+ final BlockPos savedBoundOrigin = new BlockPos(nbt.getInt("BoundX"), nbt.getInt("BoundY"), nbt.getInt("BoundZ"));
-+ this.boundOrigin = this.level().isLoadedAndInBounds(savedBoundOrigin) ? savedBoundOrigin : null;
-+ // Scissors end - Limit Vex bound origin
- }
-
- if (nbt.contains("LifeTicks")) {
diff --git a/patches/server/0051-Mute-invalid-attributes.patch b/patches/server/0051-Mute-invalid-attributes.patch
deleted file mode 100644
index 0da0a1c..0000000
--- a/patches/server/0051-Mute-invalid-attributes.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Allink
-Date: Thu, 6 Jul 2023 23:01:12 +0100
-Subject: [PATCH] Mute invalid attributes
-
-
-diff --git a/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java b/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java
-index 7204b973c3ad9239e82355513f6d538107102e48..2463444778f19f937b18173798c04d9d9788a824 100644
---- a/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java
-+++ b/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeMap.java
-@@ -147,7 +147,7 @@ public class AttributeMap {
- }
-
- }, () -> {
-- LOGGER.warn("Ignoring unknown attribute '{}'", (Object)string);
-+ // LOGGER.warn("Ignoring unknown attribute '{}'", (Object)string); // Scissors - Mute invalid attributes
- });
- }
-
-diff --git a/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeModifier.java b/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeModifier.java
-index a7380ce6dcbf64ad8a51dd047d178ae887518041..cb015941e5ea4618bd0964f4aa66a9f0fceb27a1 100644
---- a/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeModifier.java
-+++ b/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeModifier.java
-@@ -92,7 +92,7 @@ public class AttributeModifier {
- AttributeModifier.Operation operation = AttributeModifier.Operation.fromValue(nbt.getInt("Operation"));
- return new AttributeModifier(uUID, nbt.getString("Name"), nbt.getDouble("Amount"), operation);
- } catch (Exception var3) {
-- LOGGER.warn("Unable to create attribute: {}", (Object)var3.getMessage());
-+ // LOGGER.warn("Unable to create attribute: {}", (Object)var3.getMessage()); // Scissors - Mute invalid attributes
- return null;
- }
- }
diff --git a/patches/server/0052-Mute-invalid-Enderdragon-phases.patch b/patches/server/0052-Mute-invalid-Enderdragon-phases.patch
deleted file mode 100644
index 5d50163..0000000
--- a/patches/server/0052-Mute-invalid-Enderdragon-phases.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Allink
-Date: Thu, 6 Jul 2023 23:34:46 +0100
-Subject: [PATCH] Mute invalid Enderdragon phases
-
-
-diff --git a/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonChargePlayerPhase.java b/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonChargePlayerPhase.java
-index bca131e9c428e2cb073ae2ef517dda12f73a5dcd..b9d603c82b12299e94c31928b36c9517834cff62 100644
---- a/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonChargePlayerPhase.java
-+++ b/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonChargePlayerPhase.java
-@@ -20,7 +20,7 @@ public class DragonChargePlayerPhase extends AbstractDragonPhaseInstance {
- @Override
- public void doServerTick() {
- if (this.targetLocation == null) {
-- LOGGER.warn("Aborting charge player as no target was set.");
-+ // LOGGER.warn("Aborting charge player as no target was set."); // Scissors - Mute invalid Enderdragon phases
- this.dragon.getPhaseManager().setPhase(EnderDragonPhase.HOLDING_PATTERN);
- } else if (this.timeSinceCharge > 0 && this.timeSinceCharge++ >= 10) {
- this.dragon.getPhaseManager().setPhase(EnderDragonPhase.HOLDING_PATTERN);
-diff --git a/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonStrafePlayerPhase.java b/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonStrafePlayerPhase.java
-index a3456b35db4e938f91d6bc32d4d202a011bf13c4..aad0b066e4fd63195aa117c5a03f64846bf46fbd 100644
---- a/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonStrafePlayerPhase.java
-+++ b/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonStrafePlayerPhase.java
-@@ -32,7 +32,7 @@ public class DragonStrafePlayerPhase extends AbstractDragonPhaseInstance {
- @Override
- public void doServerTick() {
- if (this.attackTarget == null) {
-- LOGGER.warn("Skipping player strafe phase because no player was found");
-+ // LOGGER.warn("Skipping player strafe phase because no player was found"); // Scissors - Mute invalid Enderdragon phases
- this.dragon.getPhaseManager().setPhase(EnderDragonPhase.HOLDING_PATTERN);
- } else {
- if (this.currentPath != null && this.currentPath.isDone()) {
diff --git a/patches/server/0053-Don-t-return-null-Components-in-the-Component-codec.patch b/patches/server/0053-Don-t-return-null-Components-in-the-Component-codec.patch
deleted file mode 100644
index 52f7bb2..0000000
--- a/patches/server/0053-Don-t-return-null-Components-in-the-Component-codec.patch
+++ /dev/null
@@ -1,53 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Luna
-Date: Fri, 28 Jul 2023 19:33:23 -0300
-Subject: [PATCH] Don't return null Components in the Component codec
-
-Found by Sk8kman
-
-diff --git a/src/main/java/net/minecraft/util/ExtraCodecs.java b/src/main/java/net/minecraft/util/ExtraCodecs.java
-index 607f32b856c6c1fb81d3f1604f3bf3fb240d713f..5afdc9d93e696568cc8a263ab0142fbac258e874 100644
---- a/src/main/java/net/minecraft/util/ExtraCodecs.java
-+++ b/src/main/java/net/minecraft/util/ExtraCodecs.java
-@@ -70,7 +70,10 @@ public class ExtraCodecs {
- public static final Codec COMPONENT = adaptJsonSerializer(Component.Serializer::fromJson, Component.Serializer::toJsonTree);
- public static final Codec FLAT_COMPONENT = Codec.STRING.flatXmap((json) -> {
- try {
-- return DataResult.success(Component.Serializer.fromJson(json));
-+ // Scissors start
-+ final Component component = Component.Serializer.fromJson(json);
-+ return DataResult.success(component != null ? component : Component.empty());
-+ // Scissors end
- } catch (JsonParseException var2) {
- return DataResult.error(var2::getMessage);
- }
-@@ -233,7 +236,10 @@ public class ExtraCodecs {
- public static Codec adaptJsonSerializer(Function deserializer, Function serializer) {
- return JSON.flatXmap((json) -> {
- try {
-- return DataResult.success(deserializer.apply(json));
-+ // Scissors start
-+ final T value = deserializer.apply(json);
-+ return DataResult.success(value != null ? value : (T)Component.empty());
-+ // Scissors end
- } catch (JsonParseException var3) {
- return DataResult.error(var3::getMessage);
- }
-@@ -260,7 +266,7 @@ public class ExtraCodecs {
- }, (pair) -> {
- return ImmutableList.of(leftFunction.apply(pair), rightFunction.apply(pair));
- });
-- Codec codec3 = RecordCodecBuilder.create((instance) -> {
-+ Codec codec3 = RecordCodecBuilder.>create((instance) -> { // Scissors - Decompile error
- return instance.group(codec.fieldOf(leftFieldName).forGetter(Pair::getFirst), codec.fieldOf(rightFieldName).forGetter(Pair::getSecond)).apply(instance, Pair::of);
- }).comapFlatMap((pair) -> {
- return combineFunction.apply((P)pair.getFirst(), (P)pair.getSecond());
-@@ -286,7 +292,7 @@ public class ExtraCodecs {
- Optional> optional = dataResult.resultOrPartial(mutableObject::setValue);
- return optional.isPresent() ? dataResult : DataResult.error(() -> {
- return "(" + (String)mutableObject.getValue() + " -> using default)";
-- }, Pair.of(object, object));
-+ }, (Pair) Pair.of(object, object)); // Scissors - Decompile error
- }
-
- public DataResult coApply(DynamicOps dynamicOps, A objectx, DataResult dataResult) {
diff --git a/patches/server/0054-Add-length-limit-to-note-block-sound.patch b/patches/server/0054-Add-length-limit-to-note-block-sound.patch
deleted file mode 100644
index 161c66c..0000000
--- a/patches/server/0054-Add-length-limit-to-note-block-sound.patch
+++ /dev/null
@@ -1,19 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Allink
-Date: Fri, 25 Aug 2023 11:51:47 +0100
-Subject: [PATCH] Add length limit to note block sound
-
-
-diff --git a/src/main/java/net/minecraft/world/level/block/entity/SkullBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/SkullBlockEntity.java
-index 238b6cd88cb24ca63770db607f2241fcd7210574..ec02597810a4022112ddf31928eb6976e6ac5371 100644
---- a/src/main/java/net/minecraft/world/level/block/entity/SkullBlockEntity.java
-+++ b/src/main/java/net/minecraft/world/level/block/entity/SkullBlockEntity.java
-@@ -92,7 +92,7 @@ public class SkullBlockEntity extends BlockEntity {
- }
-
- if (nbt.contains("note_block_sound", 8)) {
-- this.noteBlockSound = ResourceLocation.tryParse(nbt.getString("note_block_sound"));
-+ this.noteBlockSound = ResourceLocation.tryParse(StringUtil.truncateStringIfNecessary(nbt.getString("note_block_sound"), 32767, false)); // Scissors - Add length limit to note block sound
- }
-
- }
diff --git a/submodules/AdvancedSlimePaper b/submodules/AdvancedSlimePaper
index 0ecbd01..2967518 160000
--- a/submodules/AdvancedSlimePaper
+++ b/submodules/AdvancedSlimePaper
@@ -1 +1 @@
-Subproject commit 0ecbd018a033ddd98c3cd60fd094965db8a3774c
+Subproject commit 2967518cc70a6b15498a36abfc1c2322f8e6a1b4