diff --git a/patches/server/0005-Plazma-Configurations.patch b/patches/server/0005-Plazma-Configurations.patch index 38b9c06..0bcbd25 100644 --- a/patches/server/0005-Plazma-Configurations.patch +++ b/patches/server/0005-Plazma-Configurations.patch @@ -980,12 +980,13 @@ index 0000000000000000000000000000000000000000..d8006ae086c18a4ef43906d516eba0d5 +} diff --git a/src/main/java/org/plazmamc/plazma/configurations/PlazmaConfigurations.java b/src/main/java/org/plazmamc/plazma/configurations/PlazmaConfigurations.java new file mode 100644 -index 0000000000000000000000000000000000000000..7f2d55dc627e380b47db128fa0acf71fe16b3071 +index 0000000000000000000000000000000000000000..af27a8199c46c2995424a60893439c0dbc162791 --- /dev/null +++ b/src/main/java/org/plazmamc/plazma/configurations/PlazmaConfigurations.java -@@ -0,0 +1,214 @@ +@@ -0,0 +1,217 @@ +package org.plazmamc.plazma.configurations; + ++import com.mojang.logging.LogUtils; +import io.papermc.paper.configuration.ConfigurationPart; +import io.papermc.paper.configuration.Configurations; +import net.minecraft.core.RegistryAccess; @@ -994,6 +995,7 @@ index 0000000000000000000000000000000000000000..7f2d55dc627e380b47db128fa0acf71f +import org.checkerframework.framework.qual.DefaultQualifier; +import org.jetbrains.annotations.VisibleForTesting; +import org.plazmamc.plazma.Options; ++import org.slf4j.Logger; +import org.spongepowered.configurate.BasicConfigurationNode; +import org.spongepowered.configurate.ConfigurateException; +import org.spongepowered.configurate.ConfigurationNode; @@ -1010,6 +1012,7 @@ index 0000000000000000000000000000000000000000..7f2d55dc627e380b47db128fa0acf71f +@DefaultQualifier(NonNull.class) +public class PlazmaConfigurations extends Configurations { + ++ public static final Logger LOGGER = LogUtils.getLogger(); + public static final String CONFIG_DIR = "config"; + static final String GLOBAL_CONFIG_FILE_NAME = "plazma-global.yml"; + static final String WORLD_DEFAULTS_CONFIG_FILE_NAME = "plazma-world-defaults.yml"; diff --git a/patches/server/0015-Completely-remove-Mojang-Profiler.patch b/patches/server/0015-Completely-remove-Mojang-Profiler.patch index a12bbd0..c00d12c 100644 --- a/patches/server/0015-Completely-remove-Mojang-Profiler.patch +++ b/patches/server/0015-Completely-remove-Mojang-Profiler.patch @@ -360,6 +360,24 @@ index 8c587f829c5e8c6b6df3150024c4ae704988c47b..319f484b535143a94ee2da11114acacc + */ } +// Plazma end - Completely remove Mojang's Profiler +diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java +index 361dc9c3434d9b4ac4b9966fa09b17f6820b0f22..705a71ca533ad9b6dab394c8cbcbb9814d72ec84 100644 +--- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java ++++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java +@@ -922,11 +922,13 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface + return this.settings.getProperties().serverResourcePackInfo; + } + ++ /* // Plazma - Completely remove Mojang's Profiler + @Override + public void endMetricsRecordingTick() { + super.endMetricsRecordingTick(); + this.debugSampleSubscriptionTracker.tick(this.getTickCount()); + } ++ */ // Plazma - Completely remove Mojang's Profiler + + @Override + public SampleLogger getTickTimeLogger() { diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java index 4e6fccec4f5ca14562bf5bae495ac36c14982d85..73c1f17f1e6fa63e98081304f8cbd336902d9ac6 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java @@ -1203,9 +1221,18 @@ index 97c129f5949ca7cb7430e1cf56e881c00f129530..5c4d902a6febe8ffadecbbc64b50ecdc + */ // Plazma - Completely remove Mojang's Profiler } diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java -index 56da8a4600688efd1987d82d4fcad1757e33f4f2..274ca06fbda0f54805fc82614d43b6e1a4a5d4a8 100644 +index 56da8a4600688efd1987d82d4fcad1757e33f4f2..cdae1cda0bf50d6fd7d40945b99663f79da80ab1 100644 --- a/src/main/java/net/minecraft/world/entity/Mob.java +++ b/src/main/java/net/minecraft/world/entity/Mob.java +@@ -37,7 +37,7 @@ import net.minecraft.sounds.SoundEvent; + import net.minecraft.tags.TagKey; + import net.minecraft.util.Mth; + import net.minecraft.util.RandomSource; +-import net.minecraft.util.profiling.ProfilerFiller; ++// import net.minecraft.util.profiling.ProfilerFiller; // Plazma - Completely remove Mojang's Profiler + import net.minecraft.world.Difficulty; + import net.minecraft.world.DifficultyInstance; + import net.minecraft.world.InteractionHand; @@ -165,8 +165,8 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Targeti this.pathfindingMalus = Maps.newEnumMap(PathType.class); this.restrictCenter = BlockPos.ZERO; diff --git a/patches/server/0017-Reduce-create-random-instance.patch b/patches/server/0017-Reduce-create-random-instance.patch index b5556d2..210ceee 100644 --- a/patches/server/0017-Reduce-create-random-instance.patch +++ b/patches/server/0017-Reduce-create-random-instance.patch @@ -4,6 +4,18 @@ Date: Wed, 27 Sep 2023 21:18:22 +0900 Subject: [PATCH] Reduce create random instance +diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java +index 4a265c97ea872b178286394e2b8d2382166e4cf0..f0f33f5aea9a9d7b4c9b761458d425f83e83f227 100644 +--- a/src/main/java/net/minecraft/server/MinecraftServer.java ++++ b/src/main/java/net/minecraft/server/MinecraftServer.java +@@ -235,6 +235,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop implements Iterable { protected final List> entries; - private final RandomSource random = RandomSource.create(); -+ private final RandomSource random = org.plazmamc.plazma.configurations.GlobalConfiguration.get().misc.reduceRandom ? net.minecraft.server.MinecraftServer.getServer().random() : RandomSource.create(); // Plazma - Reduce create random instance ++ private final RandomSource random = org.plazmamc.plazma.configurations.GlobalConfiguration.get().misc.reduceRandom ? net.minecraft.server.MinecraftServer.random() : RandomSource.create(); // Plazma - Reduce create random instance private final boolean isUnsafe; // Paper - Fix Concurrency issue in ShufflingList during worldgen public ShufflingList() { diff --git a/src/main/java/net/minecraft/world/entity/ai/sensing/Sensor.java b/src/main/java/net/minecraft/world/entity/ai/sensing/Sensor.java -index 09a7b418ddf564c0be13297f7c216db2e7ae1578..0eebd9e50e8a26c40e246bcc9feb18cba137ee7d 100644 +index 09a7b418ddf564c0be13297f7c216db2e7ae1578..703006eb5df8099c4f51cdb4e41f95cacfbe43a6 100644 --- a/src/main/java/net/minecraft/world/entity/ai/sensing/Sensor.java +++ b/src/main/java/net/minecraft/world/entity/ai/sensing/Sensor.java @@ -8,7 +8,7 @@ import net.minecraft.world.entity.ai.memory.MemoryModuleType; @@ -87,12 +99,12 @@ index 09a7b418ddf564c0be13297f7c216db2e7ae1578..0eebd9e50e8a26c40e246bcc9feb18cb public abstract class Sensor { - private static final RandomSource RANDOM = RandomSource.createThreadSafe(); -+ private static final RandomSource RANDOM = org.plazmamc.plazma.configurations.GlobalConfiguration.get().misc.reduceRandom && org.plazmamc.plazma.configurations.GlobalConfiguration.get().misc.ignoreThreadSafeRandom ? net.minecraft.server.MinecraftServer.getServer().random() : RandomSource.createThreadSafe(); // Plazma - Reduce create random instance ++ private static final RandomSource RANDOM = org.plazmamc.plazma.configurations.GlobalConfiguration.get().misc.reduceRandom && org.plazmamc.plazma.configurations.GlobalConfiguration.get().misc.ignoreThreadSafeRandom ? net.minecraft.server.MinecraftServer.random() : RandomSource.createThreadSafe(); // Plazma - Reduce create random instance private static final int DEFAULT_SCAN_RATE = 20; protected static final int TARGETING_RANGE = 16; private static final TargetingConditions TARGET_CONDITIONS = TargetingConditions.forNonCombat().range(16.0); diff --git a/src/main/java/net/minecraft/world/entity/monster/warden/AngerManagement.java b/src/main/java/net/minecraft/world/entity/monster/warden/AngerManagement.java -index 3d792957f27fd4bdfad8d76262a8e2a2012bf35f..2d96cf85fb9250bbbddb8065307a47929c0c905c 100644 +index 3d792957f27fd4bdfad8d76262a8e2a2012bf35f..71539b5910692489cad6f78ac90f3aabc4e58236 100644 --- a/src/main/java/net/minecraft/world/entity/monster/warden/AngerManagement.java +++ b/src/main/java/net/minecraft/world/entity/monster/warden/AngerManagement.java @@ -33,7 +33,7 @@ public class AngerManagement { @@ -100,12 +112,12 @@ index 3d792957f27fd4bdfad8d76262a8e2a2012bf35f..2d96cf85fb9250bbbddb8065307a4792 protected static final int MAX_ANGER = 150; private static final int DEFAULT_ANGER_DECREASE = 1; - private int conversionDelay = Mth.randomBetweenInclusive(RandomSource.create(), 0, 2); -+ private int conversionDelay = Mth.randomBetweenInclusive((org.plazmamc.plazma.configurations.GlobalConfiguration.get().misc.reduceRandom ? net.minecraft.server.MinecraftServer.getServer().random() : RandomSource.create()), 0, 2); // Plazma - Reduce create random instance ++ private int conversionDelay = Mth.randomBetweenInclusive((org.plazmamc.plazma.configurations.GlobalConfiguration.get().misc.reduceRandom ? net.minecraft.server.MinecraftServer.random() : RandomSource.create()), 0, 2); // Plazma - Reduce create random instance int highestAnger; private static final Codec> SUSPECT_ANGER_PAIR = RecordCodecBuilder.create( instance -> instance.group( diff --git a/src/main/java/net/minecraft/world/entity/npc/WanderingTraderSpawner.java b/src/main/java/net/minecraft/world/entity/npc/WanderingTraderSpawner.java -index 96e9fce5f9084737d2fcf4deb83305733b480179..0a5277638a0d5197d7bbce301bc5f74de40a321a 100644 +index 96e9fce5f9084737d2fcf4deb83305733b480179..43da8ea227b2b01d6975a3f4f209099d350386f6 100644 --- a/src/main/java/net/minecraft/world/entity/npc/WanderingTraderSpawner.java +++ b/src/main/java/net/minecraft/world/entity/npc/WanderingTraderSpawner.java @@ -32,7 +32,7 @@ public class WanderingTraderSpawner implements CustomSpawner { @@ -113,7 +125,7 @@ index 96e9fce5f9084737d2fcf4deb83305733b480179..0a5277638a0d5197d7bbce301bc5f74d private static final int SPAWN_ONE_IN_X_CHANCE = 10; private static final int NUMBER_OF_SPAWN_ATTEMPTS = 10; - private final RandomSource random = RandomSource.create(); -+ private final RandomSource random = org.plazmamc.plazma.configurations.GlobalConfiguration.get().misc.reduceRandom ? net.minecraft.server.MinecraftServer.getServer().random() : RandomSource.create(); // Plazma - reduce create random instace ++ private final RandomSource random = org.plazmamc.plazma.configurations.GlobalConfiguration.get().misc.reduceRandom ? net.minecraft.server.MinecraftServer.random() : RandomSource.create(); // Plazma - reduce create random instace private final ServerLevelData serverLevelData; private int tickDelay; private int spawnDelay; @@ -215,7 +227,7 @@ index fb9611866671880fc7a1a969da928b8f2ad15269..44962ecedf724e941e59913188afe4cf @Override diff --git a/src/main/java/net/minecraft/world/level/chunk/ChunkGeneratorStructureState.java b/src/main/java/net/minecraft/world/level/chunk/ChunkGeneratorStructureState.java -index a6b6e5ea191c0e2cd7a2e4f01b89d8af40a83c1b..6908248519c39a1fb4454c1d6c8503c36d7ddaa0 100644 +index a6b6e5ea191c0e2cd7a2e4f01b89d8af40a83c1b..19769ac9fa688969fd2db7c9a5e92eaadac124c4 100644 --- a/src/main/java/net/minecraft/world/level/chunk/ChunkGeneratorStructureState.java +++ b/src/main/java/net/minecraft/world/level/chunk/ChunkGeneratorStructureState.java @@ -224,7 +224,7 @@ public class ChunkGeneratorStructureState { @@ -223,7 +235,7 @@ index a6b6e5ea191c0e2cd7a2e4f01b89d8af40a83c1b..6908248519c39a1fb4454c1d6c8503c3 int k = placement.spread(); HolderSet holderset = placement.preferredBiomes(); - RandomSource randomsource = RandomSource.create(); -+ RandomSource randomsource = org.plazmamc.plazma.configurations.GlobalConfiguration.get().misc.reduceRandom ? net.minecraft.server.MinecraftServer.getServer().random() : RandomSource.create(); // Plazma - Reduce create random instace ++ RandomSource randomsource = org.plazmamc.plazma.configurations.GlobalConfiguration.get().misc.reduceRandom ? net.minecraft.server.MinecraftServer.random() : RandomSource.create(); // Plazma - Reduce create random instace // Paper start - Add missing structure set seed configs if (this.conf.strongholdSeed != null && structureSetEntry.is(net.minecraft.world.level.levelgen.structure.BuiltinStructureSets.STRONGHOLDS)) { diff --git a/patches/server/0033-Implement-FreedomChat.patch b/patches/unapplied/0033-Implement-FreedomChat.patch similarity index 100% rename from patches/server/0033-Implement-FreedomChat.patch rename to patches/unapplied/0033-Implement-FreedomChat.patch diff --git a/patches/unapplied/server/0031-Skip-event-if-no-listeners.patch b/patches/unapplied/server/0031-Skip-event-if-no-listeners.patch deleted file mode 100644 index d982627..0000000 --- a/patches/unapplied/server/0031-Skip-event-if-no-listeners.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: AlphaKR93 -Date: Mon, 4 Dec 2023 23:17:15 +0900 -Subject: [PATCH] Skip event if no listeners - - -diff --git a/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java b/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java -index 7ce9ebba8ce304d1f3f21d4f15ee5f3560d7700b..23594fb7eb4b2f33146592866608c2858ef23937 100644 ---- a/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java -+++ b/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java -@@ -36,15 +36,16 @@ class PaperEventManager { - - // SimplePluginManager - public void callEvent(@NotNull Event event) { -+ // Plazma start - Skip event if no listeners -+ RegisteredListener[] listeners = event.getHandlers().getRegisteredListeners(); -+ if (listeners.length == 0) return; -+ // Plazma end - if (event.isAsynchronous() && this.server.isPrimaryThread()) { - throw new IllegalStateException(event.getEventName() + " may only be triggered asynchronously."); - } else if (!event.isAsynchronous() && !this.server.isPrimaryThread() && !this.server.isStopping()) { - throw new IllegalStateException(event.getEventName() + " may only be triggered synchronously."); - } - -- HandlerList handlers = event.getHandlers(); -- RegisteredListener[] listeners = handlers.getRegisteredListeners(); -- - for (RegisteredListener registration : listeners) { - if (!registration.getPlugin().isEnabled()) { - continue; diff --git a/patches/unapplied/server/0033-Add-entity-spawn-deadlock-timer.patch b/patches/unapplied/server/0033-Add-entity-spawn-deadlock-timer.patch deleted file mode 100644 index a410529..0000000 --- a/patches/unapplied/server/0033-Add-entity-spawn-deadlock-timer.patch +++ /dev/null @@ -1,80 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: AlphaKR93 -Date: Tue, 5 Dec 2023 13:29:28 +0900 -Subject: [PATCH] Add entity spawn deadlock timer - -[REFERENCE] -- AbsolemJackdaw/FixMySpawnR - -diff --git a/src/main/java/net/minecraft/world/level/BaseSpawner.java b/src/main/java/net/minecraft/world/level/BaseSpawner.java -index 40c199812ecf7b16fe5a17c18cb0d6d3ce258910..f01390790cab0425e5d702d93b6755be41e94313 100644 ---- a/src/main/java/net/minecraft/world/level/BaseSpawner.java -+++ b/src/main/java/net/minecraft/world/level/BaseSpawner.java -@@ -48,6 +48,8 @@ public abstract class BaseSpawner { - public int requiredPlayerRange = 16; - public int spawnRange = 4; - private int tickDelay = 0; // Paper - Configurable mob spawner tick rate -+ private int blockExistsTick = 0; // Plazma - Add entity spawn deadlock timer -+ private boolean blockLockedByTime = false; // Plazma - Add entity spawn deadlock timer - - public BaseSpawner() {} - -@@ -83,6 +85,17 @@ public abstract class BaseSpawner { - } - - public void serverTick(ServerLevel world, BlockPos pos) { -+ // Plazma start - Add entity spawn deadlock timer -+ if (world.plazmaConfig().entity.spawnDeadlockTimer.enabled) { -+ if (!this.blockLockedByTime) { -+ if (this.blockExistsTick > world.plazmaConfig().entity.spawnDeadlockTimer.timerTimeout) -+ blockLockedByTime = true; -+ else blockExistsTick++; -+ } -+ -+ if (blockLockedByTime && world.getBestNeighborSignal(pos) > 0) return; -+ } -+ // Plazma end - Add entity spawn deadlock timer - if (spawnCount <= 0 || maxNearbyEntities <= 0) return; // Paper - Ignore impossible spawn tick - // Paper start - Configurable mob spawner tick rate - if (spawnDelay > 0 && --tickDelay > 0) return; -@@ -280,6 +293,12 @@ public abstract class BaseSpawner { - if (nbt.contains("SpawnRange", 99)) { - this.spawnRange = nbt.getShort("SpawnRange"); - } -+ // Plazma start - Add entity spawn deadlock timer -+ if (nbt.contains("Plazma.SpawnerTicks", 99)) { -+ this.blockExistsTick = nbt.getInt("Plazma.SpawnerTicks"); -+ this.blockLockedByTime = nbt.getBoolean("Plazma.SpawnerLocked"); -+ } -+ // Plazma end - Add entity spawn deadlock timer - - this.displayEntity = null; - } -@@ -309,6 +328,8 @@ public abstract class BaseSpawner { - })); - } - -+ nbt.putInt("Plazma.SpawnerTicks", this.blockExistsTick); // Plazma - Add entity spawn deadlock timer -+ nbt.putBoolean("Plazma.SpawnerLocked", this.blockLockedByTime); // Plazma - Add entity spawn deadlock timer - nbt.put("SpawnPotentials", (Tag) SpawnData.LIST_CODEC.encodeStart(NbtOps.INSTANCE, this.spawnPotentials).result().orElseThrow()); - return nbt; - } -diff --git a/src/main/java/org/plazmamc/plazma/configurations/WorldConfigurations.java b/src/main/java/org/plazmamc/plazma/configurations/WorldConfigurations.java -index 29514dd01d46ba9f6b123bf3af56981541f670db..6a0cfec24618227d9a5ddc6c71e37d1986147799 100644 ---- a/src/main/java/org/plazmamc/plazma/configurations/WorldConfigurations.java -+++ b/src/main/java/org/plazmamc/plazma/configurations/WorldConfigurations.java -@@ -54,6 +54,14 @@ public class WorldConfigurations extends ConfigurationPart { - - } - -+ public SpawnDeadlockTimer spawnDeadlockTimer; -+ public class SpawnDeadlockTimer extends ConfigurationPart { -+ -+ public boolean enabled = OPTIMIZE; -+ public int timerTimeout = 0; -+ -+ } -+ - } - - public Structure structure; diff --git a/patches/unapplied/server/0034-Lithium-HashedList.patch b/patches/unapplied/server/0034-Lithium-HashedList.patch deleted file mode 100644 index 095ff2c..0000000 --- a/patches/unapplied/server/0034-Lithium-HashedList.patch +++ /dev/null @@ -1,306 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: AlphaKR93 -Date: Wed, 10 Jan 2024 18:08:59 +0900 -Subject: [PATCH] Lithium - HashedList - - -diff --git a/src/main/java/me/jellysquid/mods/lithium/common/util/collections/HashedReferenceList.java b/src/main/java/me/jellysquid/mods/lithium/common/util/collections/HashedReferenceList.java -new file mode 100644 -index 0000000000000000000000000000000000000000..d11579075e653868a43fe826bdf9b41ddc031b85 ---- /dev/null -+++ b/src/main/java/me/jellysquid/mods/lithium/common/util/collections/HashedReferenceList.java -@@ -0,0 +1,277 @@ -+package me.jellysquid.mods.lithium.common.util.collections; -+ -+import it.unimi.dsi.fastutil.objects.Reference2IntOpenHashMap; -+import it.unimi.dsi.fastutil.objects.ReferenceArrayList; -+import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet; -+import org.jetbrains.annotations.NotNull; -+ -+import java.util.*; -+ -+/** -+ * Wraps a {@link List} with a hash table which provides O(1) lookups for {@link Collection#contains(Object)}. The type -+ * contained by this list must use reference-equality semantics. -+ */ -+@SuppressWarnings("SuspiciousMethodCalls") -+public class HashedReferenceList implements List { -+ private final ReferenceArrayList list; -+ private final Reference2IntOpenHashMap counter; -+ -+ public HashedReferenceList(List list) { -+ this.list = new ReferenceArrayList<>(); -+ this.list.addAll(list); -+ -+ this.counter = new Reference2IntOpenHashMap<>(); -+ this.counter.defaultReturnValue(0); -+ -+ for (T obj : this.list) { -+ this.counter.addTo(obj, 1); -+ } -+ } -+ -+ @Override -+ public int size() { -+ return this.list.size(); -+ } -+ -+ @Override -+ public boolean isEmpty() { -+ return this.list.isEmpty(); -+ } -+ -+ @Override -+ public boolean contains(Object o) { -+ return this.counter.containsKey(o); -+ } -+ -+ @Override -+ public @NotNull Iterator iterator() { -+ return this.listIterator(); -+ } -+ -+ @Override -+ public Object @NotNull [] toArray() { -+ return this.list.toArray(); -+ } -+ -+ @Override -+ public T1 @NotNull [] toArray(T1 @NotNull [] a) { -+ return this.list.toArray(a); -+ } -+ -+ @Override -+ public boolean add(T t) { -+ this.trackReferenceAdded(t); -+ -+ return this.list.add(t); -+ } -+ -+ @Override -+ public boolean remove(Object o) { -+ this.trackReferenceRemoved(o); -+ -+ return this.list.remove(o); -+ } -+ -+ @Override -+ public boolean containsAll(Collection c) { -+ for (Object obj : c) { -+ if (!this.counter.containsKey(obj)) { -+ return false; -+ } -+ } -+ -+ return true; -+ } -+ -+ @Override -+ public boolean addAll(Collection c) { -+ for (T obj : c) { -+ this.trackReferenceAdded(obj); -+ } -+ -+ return this.list.addAll(c); -+ } -+ -+ @Override -+ public boolean addAll(int index, Collection c) { -+ for (T obj : c) { -+ this.trackReferenceAdded(obj); -+ } -+ -+ return this.list.addAll(index, c); -+ } -+ -+ @Override -+ public boolean removeAll(@NotNull Collection c) { -+ if (this.size() >= 2 && c.size() > 4 && c instanceof List) { -+ //HashReferenceList uses reference equality, so using ReferenceOpenHashSet is fine -+ c = new ReferenceOpenHashSet<>(c); -+ } -+ this.counter.keySet().removeAll(c); -+ return this.list.removeAll(c); -+ } -+ -+ @Override -+ public boolean retainAll(@NotNull Collection c) { -+ this.counter.keySet().retainAll(c); -+ return this.list.retainAll(c); -+ } -+ -+ @Override -+ public void clear() { -+ this.counter.clear(); -+ this.list.clear(); -+ } -+ -+ @Override -+ public T get(int index) { -+ return this.list.get(index); -+ } -+ -+ @Override -+ public T set(int index, T element) { -+ T prev = this.list.set(index, element); -+ -+ if (prev != element) { -+ if (prev != null) { -+ this.trackReferenceRemoved(prev); -+ } -+ -+ this.trackReferenceAdded(element); -+ } -+ -+ return prev; -+ } -+ -+ @Override -+ public void add(int index, T element) { -+ this.trackReferenceAdded(element); -+ -+ this.list.add(index, element); -+ } -+ -+ @Override -+ public T remove(int index) { -+ T prev = this.list.remove(index); -+ -+ if (prev != null) { -+ this.trackReferenceRemoved(prev); -+ } -+ -+ return prev; -+ } -+ -+ @Override -+ public int indexOf(Object o) { -+ return this.list.indexOf(o); -+ } -+ -+ @Override -+ public int lastIndexOf(Object o) { -+ return this.list.lastIndexOf(o); -+ } -+ -+ @Override -+ public @NotNull ListIterator listIterator() { -+ return this.listIterator(0); -+ } -+ -+ @Override -+ public @NotNull ListIterator listIterator(int index) { -+ return new ListIterator<>() { -+ private final ListIterator inner = HashedReferenceList.this.list.listIterator(index); -+ -+ @Override -+ public boolean hasNext() { -+ return this.inner.hasNext(); -+ } -+ -+ @Override -+ public T next() { -+ return this.inner.next(); -+ } -+ -+ @Override -+ public boolean hasPrevious() { -+ return this.inner.hasPrevious(); -+ } -+ -+ @Override -+ public T previous() { -+ return this.inner.previous(); -+ } -+ -+ @Override -+ public int nextIndex() { -+ return this.inner.nextIndex(); -+ } -+ -+ @Override -+ public int previousIndex() { -+ return this.inner.previousIndex(); -+ } -+ -+ @Override -+ public void remove() { -+ int last = this.previousIndex(); -+ -+ if (last == -1) { -+ throw new NoSuchElementException(); -+ } -+ -+ T prev = HashedReferenceList.this.get(last); -+ -+ if (prev != null) { -+ HashedReferenceList.this.trackReferenceRemoved(prev); -+ } -+ -+ this.inner.remove(); -+ } -+ -+ @Override -+ public void set(T t) { -+ int last = this.previousIndex(); -+ -+ if (last == -1) { -+ throw new NoSuchElementException(); -+ } -+ -+ T prev = HashedReferenceList.this.get(last); -+ -+ if (prev != t) { -+ if (prev != null) { -+ HashedReferenceList.this.trackReferenceRemoved(prev); -+ } -+ -+ HashedReferenceList.this.trackReferenceAdded(t); -+ } -+ -+ this.inner.remove(); -+ } -+ -+ @Override -+ public void add(T t) { -+ HashedReferenceList.this.trackReferenceAdded(t); -+ -+ this.inner.add(t); -+ } -+ }; -+ } -+ -+ @Override -+ public @NotNull List subList(int fromIndex, int toIndex) { -+ return this.list.subList(fromIndex, toIndex); -+ } -+ -+ private void trackReferenceAdded(T t) { -+ this.counter.addTo(t, 1); -+ } -+ -+ @SuppressWarnings("unchecked") -+ private void trackReferenceRemoved(Object o) { -+ if (this.counter.addTo((T) o, -1) <= 1) { -+ this.counter.removeInt(o); -+ } -+ } -+ -+} -diff --git a/src/main/java/net/minecraft/util/random/WeightedRandomList.java b/src/main/java/net/minecraft/util/random/WeightedRandomList.java -index 1bcb5a58b945cdb3dc94efb314d7ba41fbb38e07..3bd989b2af76392a31d2aca23fdab20a79dc3933 100644 ---- a/src/main/java/net/minecraft/util/random/WeightedRandomList.java -+++ b/src/main/java/net/minecraft/util/random/WeightedRandomList.java -@@ -8,10 +8,10 @@ import net.minecraft.util.RandomSource; - - public class WeightedRandomList { - private final int totalWeight; -- private final ImmutableList items; -+ private final List items; // Plazma - Lithium: collections.mob_spawning - - WeightedRandomList(List entries) { -- this.items = ImmutableList.copyOf(entries); -+ this.items = entries.size() > 4 ? ImmutableList.copyOf(entries) : java.util.Collections.unmodifiableList(new me.jellysquid.mods.lithium.common.util.collections.HashedReferenceList<>(entries)); // Plazma - Lithium: collections.mob_spawning - this.totalWeight = WeightedRandom.getTotalWeight(entries); - } - diff --git a/patches/unapplied/server/0035-Improve-SwingTime-ticking.patch b/patches/unapplied/server/0035-Improve-SwingTime-ticking.patch deleted file mode 100644 index 5ff007a..0000000 --- a/patches/unapplied/server/0035-Improve-SwingTime-ticking.patch +++ /dev/null @@ -1,18 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: AlphaKR93 -Date: Wed, 10 Jan 2024 18:11:03 +0900 -Subject: [PATCH] Improve SwingTime ticking - - -diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index d6705dce3bc8c1964184fe425386b3f3c0a8202e..6ca6d44114bb2e18786b9fa3c0e2c78c1b07ea75 100644 ---- a/src/main/java/net/minecraft/world/entity/LivingEntity.java -+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -2624,6 +2624,7 @@ public abstract class LivingEntity extends Entity implements Attackable { - } - - protected void updateSwingTime() { -+ if (!this.swinging && this.swingTime == 0) return; // Plazma - Improve SwingTime ticking - int i = this.getCurrentSwingDuration(); - - if (this.swinging) { diff --git a/patches/unapplied/server/0036-Save-Json-list-asynchronously.patch b/patches/unapplied/server/0036-Save-Json-list-asynchronously.patch deleted file mode 100644 index 668c1b5..0000000 --- a/patches/unapplied/server/0036-Save-Json-list-asynchronously.patch +++ /dev/null @@ -1,239 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: AlphaKR93 -Date: Thu, 11 Jan 2024 13:40:41 +0900 -Subject: [PATCH] Save Json list asynchronously - - -diff --git a/src/main/java/com/destroystokyo/paper/util/maplist/ChunkList.java b/src/main/java/com/destroystokyo/paper/util/maplist/ChunkList.java -index 554f4d4e63c1431721989e6f502a32ccc53a8807..b85bc5834d90f20d46f640621abec891456b47a0 100644 ---- a/src/main/java/com/destroystokyo/paper/util/maplist/ChunkList.java -+++ b/src/main/java/com/destroystokyo/paper/util/maplist/ChunkList.java -@@ -17,7 +17,7 @@ public final class ChunkList implements Iterable { - this.chunkToIndex.defaultReturnValue(Integer.MIN_VALUE); - } - -- protected static final LevelChunk[] EMPTY_LIST = new LevelChunk[0]; -+ protected static final LevelChunk[] EMPTY_LIST = new LevelChunk[0]; // Plazma - Reduce allocations (mark) - - protected LevelChunk[] chunks = EMPTY_LIST; - protected int count; -diff --git a/src/main/java/io/papermc/paper/plugin/manager/DummyBukkitPluginLoader.java b/src/main/java/io/papermc/paper/plugin/manager/DummyBukkitPluginLoader.java -index aef19b44075a3b2e8696315baa89117dd8ebb513..6370d3f4451de4ca12a8bcc2661e4b2b4833fc0e 100644 ---- a/src/main/java/io/papermc/paper/plugin/manager/DummyBukkitPluginLoader.java -+++ b/src/main/java/io/papermc/paper/plugin/manager/DummyBukkitPluginLoader.java -@@ -30,7 +30,7 @@ import java.util.regex.Pattern; - @ApiStatus.Internal - public class DummyBukkitPluginLoader implements PluginLoader { - -- private static final Pattern[] PATTERNS = new Pattern[0]; -+ private static final Pattern[] PATTERNS = new Pattern[0]; // Plazma - Reduce allocations (mark) - - @Override - public @NotNull Plugin loadPlugin(@NotNull File file) throws InvalidPluginException, UnknownDependencyException { -diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedPlayerList.java b/src/main/java/net/minecraft/server/dedicated/DedicatedPlayerList.java -index 22c4f8dea99f92a1eb3da2baf0a15bf9d2ca0462..20c531f11b310dab0a867e589c769393ed835df5 100644 ---- a/src/main/java/net/minecraft/server/dedicated/DedicatedPlayerList.java -+++ b/src/main/java/net/minecraft/server/dedicated/DedicatedPlayerList.java -@@ -58,21 +58,23 @@ public class DedicatedPlayerList extends PlayerList { - this.loadWhiteList(); - } - -+ // Plazma start - Save JSON list asynchronously - private void saveIpBanList() { -- try { -- this.getIpBans().save(); -- } catch (IOException var2) { -- LOGGER.warn("Failed to save ip banlist: ", (Throwable)var2); -- } -+ this.getIpBans().save(); - } - - private void saveUserBanList() { -- try { -- this.getBans().save(); -- } catch (IOException var2) { -- LOGGER.warn("Failed to save user banlist: ", (Throwable)var2); -- } -+ this.getBans().save(); -+ } -+ -+ private void saveOps() { -+ this.getOps().save(); -+ } -+ -+ private void saveWhiteList() { -+ this.getWhiteList().save(); - } -+ // Plazma end - Save JSON list asynchronously - - private void loadIpBanList() { - try { -@@ -98,14 +100,6 @@ public class DedicatedPlayerList extends PlayerList { - } - } - -- private void saveOps() { -- try { -- this.getOps().save(); -- } catch (Exception var2) { -- LOGGER.warn("Failed to save operators list: ", (Throwable)var2); -- } -- } -- - private void loadWhiteList() { - try { - this.getWhiteList().load(); -@@ -114,14 +108,6 @@ public class DedicatedPlayerList extends PlayerList { - } - } - -- private void saveWhiteList() { -- try { -- this.getWhiteList().save(); -- } catch (Exception var2) { -- LOGGER.warn("Failed to save white-list: ", (Throwable)var2); -- } -- } -- - @Override - public boolean isWhiteListed(GameProfile profile) { - return !this.isUsingWhitelist() || this.isOp(profile) || this.getWhiteList().isWhiteListed(profile); -diff --git a/src/main/java/net/minecraft/server/players/StoredUserList.java b/src/main/java/net/minecraft/server/players/StoredUserList.java -index 1289e8e9c54a584f5037ea8e852df37376af093d..2014e0c4f412bead5881de588ec941a9a5ae3565 100644 ---- a/src/main/java/net/minecraft/server/players/StoredUserList.java -+++ b/src/main/java/net/minecraft/server/players/StoredUserList.java -@@ -43,11 +43,11 @@ public abstract class StoredUserList> { - public void add(V entry) { - this.map.put(this.getKeyForUser(entry.getUser()), entry); - -- try { -+ //try { // Plazma - Save Json list asynchronously - this.save(); -- } catch (IOException ioexception) { -+ /*} catch (IOException ioexception) { // Plazma - Save Json list asynchronously - StoredUserList.LOGGER.warn("Could not save the list after adding a user.", ioexception); -- } -+ }*/ // Plazma - Save Json list asynchronously - - } - -@@ -63,11 +63,11 @@ public abstract class StoredUserList> { - public void remove(K key) { - this.map.remove(this.getKeyForUser(key)); - -- try { -+ //try { // Plazma - Save Json list asynchronously - this.save(); -- } catch (IOException ioexception) { -+ /*} catch (IOException ioexception) { // Plazma - Save Json list asynchronously - StoredUserList.LOGGER.warn("Could not save the list after removing a user.", ioexception); -- } -+ }*/ // Plazma - Save Json list asynchronously - - } - -@@ -102,7 +102,10 @@ public abstract class StoredUserList> { - return this.map.values(); - } - -- public void save() throws IOException { -+ // Plazma start - Save Json list asynchronously -+ public void save()/* throws IOException*/ { -+ io.papermc.paper.util.MCUtil.scheduleAsyncTask(() -> { -+ - this.removeExpired(); // Paper - remove expired values before saving - JsonArray jsonarray = new JsonArray(); - Stream stream = this.map.values().stream().map((jsonlistentry) -> { // CraftBukkit - decompile error -@@ -114,27 +117,16 @@ public abstract class StoredUserList> { - - Objects.requireNonNull(jsonarray); - stream.forEach(jsonarray::add); -- BufferedWriter bufferedwriter = Files.newWriter(this.file, StandardCharsets.UTF_8); - -- try { -+ try (BufferedWriter bufferedwriter = Files.newWriter(this.file, StandardCharsets.UTF_8)) { - StoredUserList.GSON.toJson(jsonarray, bufferedwriter); -- } catch (Throwable throwable) { -- if (bufferedwriter != null) { -- try { -- bufferedwriter.close(); -- } catch (Throwable throwable1) { -- throwable.addSuppressed(throwable1); -- } -- } -- -- throw throwable; -- } -- -- if (bufferedwriter != null) { -- bufferedwriter.close(); -+ } catch (IOException e) { -+ StoredUserList.LOGGER.warn("Failed to asynchronously save file " + this.file, e); - } - -+ }); - } -+ // Plazma end - Save Json list asynchronously - - public void load() throws IOException { - if (this.file.exists()) { -diff --git a/src/main/java/net/minecraft/world/entity/monster/Endermite.java b/src/main/java/net/minecraft/world/entity/monster/Endermite.java -index 965362c281315c15fb70a83a6949d7825bebf15b..e463df132c9b3cbb2217e7019b1bd9a0e0027c10 100644 ---- a/src/main/java/net/minecraft/world/entity/monster/Endermite.java -+++ b/src/main/java/net/minecraft/world/entity/monster/Endermite.java -@@ -94,7 +94,7 @@ public class Endermite extends Monster { - this.goalSelector.addGoal(7, new LookAtPlayerGoal(this, Player.class, 8.0F)); - this.goalSelector.addGoal(8, new RandomLookAroundGoal(this)); - this.targetSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur -- this.targetSelector.addGoal(1, (new HurtByTargetGoal(this, new Class[0])).setAlertOthers()); -+ this.targetSelector.addGoal(1, (new HurtByTargetGoal(this/*, new Class[0]*/)).setAlertOthers()); // Plazma - Reduce allocations - this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, Player.class, true)); - } - -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 6b9cd8543a5bfc2b936ba18f66ffd60f2f792e43..d99c56194d1a16c34a62d8f2f01026974a242921 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 -@@ -832,7 +832,7 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen - - // Paper start - Perf: Optimize Hoppers - static final AABB HOPPER_ITEM_SUCK_OVERALL = Hopper.SUCK.bounds(); -- static final AABB[] HOPPER_ITEM_SUCK_INDIVIDUAL = Hopper.SUCK.toAabbs().toArray(new AABB[0]); -+ static final AABB[] HOPPER_ITEM_SUCK_INDIVIDUAL = Hopper.SUCK.toAabbs().toArray(new AABB[0]); // Plazma - Reduce allocations (mark) - // Paper end - Perf: Optimize Hoppers - - public static List getItemsAtAndAbove(Level world, Hopper hopper) { -diff --git a/src/main/java/org/bukkit/craftbukkit/bootstrap/Main.java b/src/main/java/org/bukkit/craftbukkit/bootstrap/Main.java -index 8a4f95049c63afb28bef6719c77b7a7092e75aae..e117350504e0c37b27f10ff102781ed78210cad2 100644 ---- a/src/main/java/org/bukkit/craftbukkit/bootstrap/Main.java -+++ b/src/main/java/org/bukkit/craftbukkit/bootstrap/Main.java -@@ -50,7 +50,7 @@ public class Main { - System.exit(0); - } - -- URLClassLoader classLoader = new URLClassLoader(extractedUrls.toArray(new URL[0])); -+ URLClassLoader classLoader = new URLClassLoader(extractedUrls.toArray(new URL[0])); // Plazma - Reduce allocations (mark) - - System.out.println("Starting server"); - Thread runThread = new Thread(() -> { -diff --git a/src/main/java/org/plazmamc/plazma/commands/plazma/subcommand/VersionCommand.java b/src/main/java/org/plazmamc/plazma/commands/plazma/subcommand/VersionCommand.java -index b6664ba0fce55f5cfa0c8d3051dc8c2be0fd0703..ccb5008987dff2365fe58eddc86227e4515cbbfc 100644 ---- a/src/main/java/org/plazmamc/plazma/commands/plazma/subcommand/VersionCommand.java -+++ b/src/main/java/org/plazmamc/plazma/commands/plazma/subcommand/VersionCommand.java -@@ -7,6 +7,7 @@ import org.checkerframework.checker.nullness.qual.NonNull; - import org.checkerframework.checker.nullness.qual.Nullable; - import org.checkerframework.framework.qual.DefaultQualifier; - import org.plazmamc.plazma.commands.PlazmaSubCommand; -+import org.plazmamc.plazma.constants.Empty; - - @DefaultQualifier(NonNull.class) - public class VersionCommand implements PlazmaSubCommand { -@@ -14,7 +15,7 @@ public class VersionCommand implements PlazmaSubCommand { - @Override - public boolean execute(final CommandSender sender, final String subCommand, final String[] args) { - final @Nullable Command ver = MinecraftServer.getServer().server.getCommandMap().getCommand("version"); -- if (ver != null) return ver.execute(sender, "plazma", new String[0]); -+ if (ver != null) return ver.execute(sender, "plazma", Empty.STRING); - return false; - } - diff --git a/patches/unapplied/server/0037-Implement-FreedomChat.patch b/patches/unapplied/server/0037-Implement-FreedomChat.patch deleted file mode 100644 index db56900..0000000 --- a/patches/unapplied/server/0037-Implement-FreedomChat.patch +++ /dev/null @@ -1,191 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: AlphaKR93 -Date: Mon, 29 Apr 2024 14:49:37 +0900 -Subject: [PATCH] Implement FreedomChat - -ocelotpotpie/FreedomChat -Copyright (C) 2022-2024 ocelotpotpie, Licensed under GNU GPL v3.0 - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . - -diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 14d15dd0d4973957871f5c06042fcaa4ea8b7a8a..2a45bebb2b83efd4ffcecad6c0a979198ab985c7 100644 ---- a/src/main/java/net/minecraft/server/players/PlayerList.java -+++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -134,6 +134,7 @@ public abstract class PlayerList { - private static final int SEND_PLAYER_INFO_INTERVAL = 600; - private static final SimpleDateFormat BAN_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd 'at' HH:mm:ss z"); - private static final org.bukkit.event.player.PlayerRespawnEvent.RespawnFlag[] EMPTY_FLAG = new org.bukkit.event.player.PlayerRespawnEvent.RespawnFlag[0]; // Plazma - Reduce allocations -+ private static final ru.bk.oharass.freedomchat.FreedomChat FREEDOM_HANDLER = new ru.bk.oharass.freedomchat.FreedomChat(); // Plazma - Implement FreedomChat - private final MinecraftServer server; - public final List players = new java.util.concurrent.CopyOnWriteArrayList(); // CraftBukkit - ArrayList -> CopyOnWriteArrayList: Iterator safety - private final Map playersByUUID = Maps.newHashMap(); -@@ -287,6 +288,8 @@ public abstract class PlayerList { - // PlayerList.LOGGER.info("{}[{}] logged in with entity id {} at ({}, {}, {})", new Object[]{entityplayer.getName().getString(), s1, entityplayer.getId(), entityplayer.getX(), entityplayer.getY(), entityplayer.getZ()}); - LevelData worlddata = worldserver1.getLevelData(); - -+ connection.channel.pipeline().addAfter("packet_handler", "freedom_handler", FREEDOM_HANDLER); // Plazma - Implement FreedomChat -+ - player.loadGameTypes(nbttagcompound); - ServerGamePacketListenerImpl playerconnection = new ServerGamePacketListenerImpl(this.server, connection, player, clientData); - GameRules gamerules = worldserver1.getGameRules(); -diff --git a/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/EnderDragonPhase.java b/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/EnderDragonPhase.java -index 48826eb0a960f7af6dd2ef184a8aed744a1d8f83..c6df4262d660a1043705c3a4041f959490fae79e 100644 ---- a/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/EnderDragonPhase.java -+++ b/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/EnderDragonPhase.java -@@ -5,7 +5,7 @@ import java.util.Arrays; - import net.minecraft.world.entity.boss.enderdragon.EnderDragon; - - public class EnderDragonPhase { -- private static EnderDragonPhase[] phases = new EnderDragonPhase[0]; -+ private static EnderDragonPhase[] phases = new EnderDragonPhase[0]; // Plazma - Reduce allocations (mark) - public static final EnderDragonPhase HOLDING_PATTERN = create(DragonHoldingPatternPhase.class, "HoldingPattern"); - public static final EnderDragonPhase STRAFE_PLAYER = create(DragonStrafePlayerPhase.class, "StrafePlayer"); - public static final EnderDragonPhase LANDING_APPROACH = create(DragonLandingApproachPhase.class, "LandingApproach"); -diff --git a/src/main/java/net/minecraft/world/item/crafting/ShapedRecipePattern.java b/src/main/java/net/minecraft/world/item/crafting/ShapedRecipePattern.java -index d8fe760bb74c8ea0d6fb8321d2c8a49d838c5362..6e910d74bac39735020d553cf31eb65b750163e0 100644 ---- a/src/main/java/net/minecraft/world/item/crafting/ShapedRecipePattern.java -+++ b/src/main/java/net/minecraft/world/item/crafting/ShapedRecipePattern.java -@@ -85,7 +85,7 @@ public record ShapedRecipePattern(int width, int height, NonNullList - } - - if (pattern.size() == l) { -- return new String[0]; -+ return org.plazmamc.plazma.constants.Empty.STRING; // Plazma - Reduce allocations - } else { - String[] strings = new String[pattern.size() - l - k]; - -diff --git a/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java b/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java -index 4f3ed01e12ccb8a6f1a5c4f605451bb36370a236..98f26e3de66a881163e84295e9156c7f362bf7cb 100644 ---- a/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java -+++ b/src/main/java/org/plazmamc/plazma/configurations/GlobalConfiguration.java -@@ -29,6 +29,16 @@ public class GlobalConfiguration extends ConfigurationPart { - - public boolean checkSpectatorMovedToQuickly = !OPTIMIZE; - -+ public FreedomChat freedomChat; -+ public class FreedomChat extends ConfigurationPart { -+ -+ public boolean enabled = false; -+ public boolean rewriteChat = true; -+ public boolean claimSecureChatEnforced = true; -+ public boolean noChatReports = true; -+ -+ } -+ - } - - @Setting("world-generation") -diff --git a/src/main/java/ru/bk/oharass/freedomchat/FreedomChat.java b/src/main/java/ru/bk/oharass/freedomchat/FreedomChat.java -new file mode 100644 -index 0000000000000000000000000000000000000000..67f21c23e80881f52e7b92f22c6cbbe3a0bd55b5 ---- /dev/null -+++ b/src/main/java/ru/bk/oharass/freedomchat/FreedomChat.java -@@ -0,0 +1,96 @@ -+package ru.bk.oharass.freedomchat; -+ -+import com.google.gson.JsonObject; -+import com.mojang.logging.LogUtils; -+import com.mojang.serialization.JsonOps; -+import io.netty.buffer.ByteBuf; -+import io.netty.channel.ChannelHandler; -+import io.netty.channel.ChannelHandlerContext; -+import io.netty.handler.codec.EncoderException; -+import io.netty.handler.codec.MessageToByteEncoder; -+import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; -+import net.minecraft.network.Connection; -+import net.minecraft.network.FriendlyByteBuf; -+import net.minecraft.network.chat.ChatType; -+import net.minecraft.network.chat.Component; -+import net.minecraft.network.protocol.Packet; -+import net.minecraft.network.protocol.game.ClientboundPlayerChatPacket; -+import net.minecraft.network.protocol.game.ClientboundServerDataPacket; -+import net.minecraft.network.protocol.game.ClientboundSystemChatPacket; -+import net.minecraft.network.protocol.status.ClientboundStatusResponsePacket; -+import net.minecraft.network.protocol.status.ServerStatus; -+import org.slf4j.Logger; -+ -+import java.util.Optional; -+ -+import static org.plazmamc.plazma.configurations.GlobalConfiguration.get; -+import static net.minecraft.server.MinecraftServer.getServer; -+ -+@ChannelHandler.Sharable -+public class FreedomChat extends MessageToByteEncoder> { -+ -+ private static final Logger LOGGER = LogUtils.getLogger(); -+ -+ @Override -+ public boolean acceptOutboundMessage(final Object msg) { -+ return get().player.freedomChat.rewriteChat && msg instanceof ClientboundPlayerChatPacket -+ || get().player.freedomChat.claimSecureChatEnforced && msg instanceof ClientboundServerDataPacket -+ || get().player.freedomChat.noChatReports && msg instanceof ClientboundStatusResponsePacket; -+ } -+ -+ @Override -+ protected void encode(final ChannelHandlerContext context, final Packet packet, final ByteBuf byteBuf) throws Exception { -+ final FriendlyByteBuf buf = new FriendlyByteBuf(byteBuf); -+ -+ // TODO: JDK 21 - Change to pattern matching -+ if (packet instanceof ClientboundPlayerChatPacket chat) -+ encodeChat(context, chat, buf); -+ else if (packet instanceof ClientboundServerDataPacket data) -+ encodeData(context, data, buf); -+ else if (packet instanceof ClientboundStatusResponsePacket query) -+ encodeQuery(context, query, buf); -+ } -+ -+ private static void encodeChat( -+ final ChannelHandlerContext context, final ClientboundPlayerChatPacket packet, final FriendlyByteBuf byteBuf -+ ) { -+ final Optional bound = packet.chatType().resolve(getServer().registryAccess()); -+ if (bound.isEmpty()) { -+ LOGGER.warn("Failed to resolve chat type: {}", packet.chatType().chatType(), new Throwable()); -+ return; -+ } -+ -+ final ClientboundSystemChatPacket after = new ClientboundSystemChatPacket( bound.orElseThrow().decorate( -+ Optional.ofNullable( packet.unsignedContent() ).orElse( Component.literal(packet.body().content()) ) -+ ), false ); -+ write(context, after, byteBuf); -+ after.write(byteBuf); -+ } -+ -+ private static void encodeData( -+ final ChannelHandlerContext context, final ClientboundServerDataPacket packet, final FriendlyByteBuf byteBuf -+ ) { -+ write(context, packet, byteBuf); -+ byteBuf.writeComponent(packet.getMotd()); -+ byteBuf.writeOptional(packet.getIconBytes(), FriendlyByteBuf::writeByteArray); -+ byteBuf.writeBoolean(true); -+ } -+ -+ private static void encodeQuery( -+ final ChannelHandlerContext context, final ClientboundStatusResponsePacket packet, final FriendlyByteBuf byteBuf -+ ) { -+ final JsonObject status = ServerStatus.CODEC.encodeStart(JsonOps.INSTANCE, packet.status()).get().left() -+ .orElseThrow(() -> new EncoderException("Failed to encode server status query response")).getAsJsonObject(); -+ -+ status.addProperty("preventsChatReports", true); -+ write(context, packet, byteBuf); -+ byteBuf.writeUtf(GsonComponentSerializer.gson().serializer().toJson(status)); -+ } -+ -+ private static void write( -+ final ChannelHandlerContext context, final Packet packet, final FriendlyByteBuf byteBuf -+ ) { -+ byteBuf.writeVarInt(context.channel().attr(Connection.ATTRIBUTE_CLIENTBOUND_PROTOCOL).get().packetId(packet)); -+ } -+ -+}