diff --git a/build-data/dev-imports.txt b/build-data/dev-imports.txt index 2e1c303..93991a1 100644 --- a/build-data/dev-imports.txt +++ b/build-data/dev-imports.txt @@ -9,4 +9,5 @@ # minecraft net.minecraft.world.level.entity.LevelEntityGetterAdapter # minecraft net/minecraft/world/level/entity/LevelEntityGetter.java -minecraft net/minecraft/world/ContainerHelper \ No newline at end of file +minecraft net/minecraft/world/ContainerHelper +minecraft net/minecraft/network/chat/contents/NbtContents \ No newline at end of file diff --git a/patches/server/0025-Limit-amount-of-vehicle-collision-checks-to-3-and-di.patch b/patches/server/0025-Limit-amount-of-vehicle-collision-checks-to-3-and-di.patch new file mode 100644 index 0000000..4fe1643 --- /dev/null +++ b/patches/server/0025-Limit-amount-of-vehicle-collision-checks-to-3-and-di.patch @@ -0,0 +1,109 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Telesphoreo +Date: Sun, 1 May 2022 14:23:35 -0500 +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 3f31a3c17ecca6e93b794478129b95ecff4e1a9c..1db184c47880a3527e6c83666c90b7d9a9bd3ad7 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; + import javax.annotation.Nullable; + import net.minecraft.BlockUtil; + import net.minecraft.Util; +@@ -106,6 +107,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 + +@@ -424,8 +426,10 @@ 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()) { +- for (int l = 0; l < list.size(); ++l) { ++ // Scissors - Add a collision debounce ++ if (!list.isEmpty() && (System.currentTimeMillis() - lastLargeCollision) >= TimeUnit.SECONDS.toMillis(5)) { // Using TimeUnit for better code readability ++ // Scissors - Limit amount of vehicle collision checks to 3 maximum ++ for (int l = 0; l < Math.min(3, list.size()); ++l) { + Entity entity = (Entity) list.get(l); + + if (!(entity instanceof Player) && !(entity instanceof IronGolem) && !(entity instanceof AbstractMinecart) && !this.isVehicle() && !entity.isPassenger()) { +@@ -452,6 +456,16 @@ public abstract class AbstractMinecart extends Entity { + entity.push(this); + } + } ++ ++ // Scissors - Add a collision debounce ++ if (list.size() > 3) { ++ lastLargeCollision = System.currentTimeMillis(); ++ } ++ ++ // Scissors - Delete entity if the collision amount is over 15 ++ if (list.size() > 15) { ++ this.discard(); ++ } + } + } else { + Iterator iterator = 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 eb753323f67badb1bed28405c07b03078e322b44..8e1855ae99ce0a1c098a67c7e0fead87c061eb4f 100644 +--- a/src/main/java/net/minecraft/world/entity/vehicle/Boat.java ++++ b/src/main/java/net/minecraft/world/entity/vehicle/Boat.java +@@ -4,6 +4,7 @@ import com.google.common.collect.Lists; + import com.google.common.collect.UnmodifiableIterator; + import java.util.Iterator; + import java.util.List; ++import java.util.concurrent.TimeUnit; + import javax.annotation.Nullable; + import net.minecraft.BlockUtil; + import net.minecraft.core.BlockPos; +@@ -106,6 +107,7 @@ public class Boat extends Entity { + public double unoccupiedDeceleration = -1; + public boolean landBoats = false; + // CraftBukkit end ++ private long lastLargeCollision = 0L; // Scissors - Add a collision debounce + + public Boat(EntityType type, Level world) { + super(type, world); +@@ -403,10 +405,12 @@ public class Boat extends Entity { + this.checkInsideBlocks(); + List list = this.level.getEntities((Entity) this, this.getBoundingBox().inflate(0.20000000298023224D, -0.009999999776482582D, 0.20000000298023224D), EntitySelector.pushableBy(this)); + +- if (!list.isEmpty()) { ++ // Scissors - Add collision debounce ++ if (!list.isEmpty() && (System.currentTimeMillis() - lastLargeCollision) >= TimeUnit.SECONDS.toMillis(5)) { // Using TimeUnit for better code readability + boolean flag = !this.level.isClientSide && !(this.getControllingPassenger() instanceof Player); + +- for (int j = 0; j < list.size(); ++j) { ++ // Scissors - Limit amount of vehicle collision checks to 3 maximum ++ for (int j = 0; j < Math.min(3, list.size()); ++j) { + Entity entity = (Entity) list.get(j); + + if (!entity.hasPassenger((Entity) this)) { +@@ -417,6 +421,16 @@ public class Boat extends Entity { + } + } + } ++ ++ // Scissors - Add collision debounce ++ if (list.size() > 3) { ++ lastLargeCollision = System.currentTimeMillis(); ++ } ++ ++ // Scissors - Delete entity if the collision amount is over 15 ++ if (list.size() > 15) { ++ this.discard(); ++ } + } + + } diff --git a/patches/server/0026-Make-the-maximum-tag-size-a-constant-add-a-method-fo.patch b/patches/server/0026-Make-the-maximum-tag-size-a-constant-add-a-method-fo.patch new file mode 100644 index 0000000..3ceac46 --- /dev/null +++ b/patches/server/0026-Make-the-maximum-tag-size-a-constant-add-a-method-fo.patch @@ -0,0 +1,22 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Business Goose +Date: Sun, 1 May 2022 01:19:36 +0100 +Subject: [PATCH] Make the maximum tag size a constant & add a method for + getting tag size + + +diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java +index ac85b2444322d1f2bd5ccdc285443bfc1a4855ca..63229d6c61346821ad45997bddcbbfd95fb96de8 100644 +--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java ++++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java +@@ -836,7 +836,9 @@ public abstract class LivingEntity extends Entity { + 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 start - Prevent log spam possible with this error message, easily provokable by players in creative. ++ // LivingEntity.LOGGER.warn("Unable to add mob to team \"{}\" (that team probably doesn't exist)", s); ++ // Scissors end + } + } + diff --git a/patches/server/0027-Better-handling-of-invalid-JSON-components.patch b/patches/server/0027-Better-handling-of-invalid-JSON-components.patch new file mode 100644 index 0000000..fdbc944 --- /dev/null +++ b/patches/server/0027-Better-handling-of-invalid-JSON-components.patch @@ -0,0 +1,194 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Telesphoreo +Date: Sun, 12 Jun 2022 00:06:07 -0500 +Subject: [PATCH] Better handling of invalid JSON components + + +diff --git a/src/main/java/net/minecraft/network/chat/Component.java b/src/main/java/net/minecraft/network/chat/Component.java +index bbfb98618a0b87406cc48465bdda15a0a4974b7e..a38127366c55a2d377727d9a9aec32b0e3ad437a 100644 +--- a/src/main/java/net/minecraft/network/chat/Component.java ++++ b/src/main/java/net/minecraft/network/chat/Component.java +@@ -25,6 +25,7 @@ import java.util.List; + import java.util.Map.Entry; + import java.util.Optional; + import javax.annotation.Nullable; ++import net.minecraft.ChatFormatting; + import net.minecraft.Util; + import net.minecraft.network.chat.contents.BlockDataSource; + import net.minecraft.network.chat.contents.DataSource; +@@ -490,6 +491,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 d38562b518b28ba4617d39e4587c7fa72859ab11..454e73bbcf449561e18bb8565932872c5a62a6e1 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 = Registry.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..7b6476455e095eed15c92797ce3a3e1146dbdc3f 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; + import net.minecraft.commands.CommandSourceStack; + import net.minecraft.commands.arguments.NbtPathArgument; + import net.minecraft.nbt.Tag; +@@ -107,10 +108,11 @@ 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 ++ // LOGGER.warn("Failed to parse component: {}", text, var5); + 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 89cecb3603b41ae22efc54a9f2858a6f60e52148..5ed67adfbc193dfd8c8cd0daf89f2a3f7d641ace 100644 +--- a/src/main/java/net/minecraft/world/entity/Entity.java ++++ b/src/main/java/net/minecraft/world/entity/Entity.java +@@ -2298,12 +2298,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/level/block/entity/BeaconBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java +index 5f6eeb36f57bd342b18590c8f0ffb668d2bf273c..5ae750a2f12917ecddb0c14c23e6b02735385599 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 +@@ -408,7 +408,7 @@ public class BeaconBlockEntity extends BlockEntity implements MenuProvider { + this.levels = nbt.getInt("Levels"); // SPIGOT-5053, use where available + // CraftBukkit end + if (nbt.contains("CustomName", 8)) { +- this.name = net.minecraft.server.MCUtil.getBaseComponentFromNbt("CustomName", nbt); // Paper - Catch ParseException ++ this.name = Component.Serializer.fromJsonSafe(nbt.getString("CustomName")); // Scissors - Use safer method for getting Components from JSON + } + + this.lockKey = LockCode.fromTag(nbt); +diff --git a/src/main/java/net/minecraft/world/level/block/entity/EnchantmentTableBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/EnchantmentTableBlockEntity.java +index 2341a5a249d455628165fc6ba508fc6d70c3dbfb..3e23451066894ebd88cad7022970cb2c0e9b75db 100644 +--- a/src/main/java/net/minecraft/world/level/block/entity/EnchantmentTableBlockEntity.java ++++ b/src/main/java/net/minecraft/world/level/block/entity/EnchantmentTableBlockEntity.java +@@ -42,7 +42,7 @@ public class EnchantmentTableBlockEntity extends BlockEntity implements Nameable + public void load(CompoundTag nbt) { + super.load(nbt); + if (nbt.contains("CustomName", 8)) { +- this.name = net.minecraft.server.MCUtil.getBaseComponentFromNbt("CustomName", nbt); // Paper - Catch ParseException ++ this.name = Component.Serializer.fromJsonSafe(nbt.getString("CustomName")); // Scissors - Use safer method for getting Components from JSON + } + + } +diff --git a/src/main/java/net/minecraft/world/scores/ScoreboardSaveData.java b/src/main/java/net/minecraft/world/scores/ScoreboardSaveData.java +index 2be7a697f08045b974579e6942b38571e744efac..84ec21c38bb44db1e9ff26c01d5c8af1a2417616 100644 +--- a/src/main/java/net/minecraft/world/scores/ScoreboardSaveData.java ++++ b/src/main/java/net/minecraft/world/scores/ScoreboardSaveData.java +@@ -35,7 +35,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); + } +@@ -53,14 +53,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); + } +@@ -115,7 +115,7 @@ public class ScoreboardSaveData extends SavedData { + CompoundTag compoundTag = nbt.getCompound(i); + ObjectiveCriteria.byName(compoundTag.getString("CriteriaName")).ifPresent((criterion) -> { + String string = 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(string, criterion, component, renderType); + });