Add depth limit to Component deserialization (#145)

This commit is contained in:
Nathan Curran 2024-02-07 11:40:11 +11:00 committed by GitHub
parent 0030c335bf
commit f00572a121
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 158 additions and 31 deletions

View File

@ -44,10 +44,10 @@ index 1f55185814125c691288294d18bf1580461c8066..259d65f8e21f9cf99585d416eafdc967
}
diff --git a/src/main/java/net/minecraft/world/entity/EntityType.java b/src/main/java/net/minecraft/world/entity/EntityType.java
index edc723ea5ca3a325106e7af38c60dbf9f0f5fb77..1b5305c4ac7881c76d4fd326c4547d7e242b8ea4 100644
index 09e8445a3f8c6b3ebc852a75a9a25b41a51ba659..cfb2ce684da0ae97a844554b5ad3d41290058f32 100644
--- a/src/main/java/net/minecraft/world/entity/EntityType.java
+++ b/src/main/java/net/minecraft/world/entity/EntityType.java
@@ -599,7 +599,7 @@ public class EntityType<T extends Entity> implements FeatureElement, EntityTypeT
@@ -595,7 +595,7 @@ public class EntityType<T extends Entity> implements FeatureElement, EntityTypeT
if (generation) entity.generation = true; // Paper - Don't fire sync event during generation
entity.load(nbt);
}, () -> {

View File

@ -5,10 +5,10 @@ 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 1ccf71be865af4d3c5ab8f4323a228a947e0bf3f..efebc156e45fca4b5a5896bd25398c28ef39dfe3 100644
index 850f75172e9efa72cabb8e5bd124b96a0b1a945f..2c3ef2a0c745cf6b470555706389e0ce4a15cb67 100644
--- a/src/main/java/io/papermc/paper/util/MCUtil.java
+++ b/src/main/java/io/papermc/paper/util/MCUtil.java
@@ -653,12 +653,6 @@ public final class MCUtil {
@@ -649,12 +649,6 @@ public final class MCUtil {
return null;
}
String string = compound.getString(key);
@ -93,7 +93,7 @@ index 186547674894fd084bceb478bb6017b747df4173..74c880425964da042ca57c097eb93273
}
}).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 2c06f3ebf7e1069727387bfc60db30c958c14b5a..fc6cff4121db4c08452817df846286103fe23ad9 100644
index 9ee1e3da1cb16291ff3e37829e25227a6b97a177..1772313459992523eefd6b05bfb0b7ee33114469 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -2525,11 +2525,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, S

View File

@ -447,7 +447,7 @@ index 6de6dad36203479677a29ad61e21bc369d4e5513..2aed9abbcb2526a2535099fe8d345d25
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 f4d2b7c1d12bff88aec747ded3a6626dbba3baae..0a94c7face891dfbb124f39632ea2d8770201a2d 100644
index 0cc658b701a406dd6683a5107b67aea8c18a22ba..5b100731794e63d7b51d6cd49e66f0997761a015 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -1036,6 +1036,7 @@ public final class CraftServer implements Server {
@ -466,7 +466,7 @@ index f4d2b7c1d12bff88aec747ded3a6626dbba3baae..0a94c7face891dfbb124f39632ea2d87
this.overrideAllCommandBlockCommands = this.commandsConfiguration.getStringList("command-block-overrides").contains("*");
this.ignoreVanillaPermissions = this.commandsConfiguration.getBoolean("ignore-vanilla-permissions");
@@ -2998,6 +3000,14 @@ public final class CraftServer implements Server {
@@ -2996,6 +2998,14 @@ public final class CraftServer implements Server {
return CraftServer.this.console.paperConfigurations.createLegacyObject(CraftServer.this.console);
}

View File

@ -5,10 +5,10 @@ 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 6071451339080bbdd98fb634791a56988984c8bc..702dbcf60ba35a3427353ea27547dab4b4c11ecc 100644
index 6523795e715e5d472739e9bc6433143115c3de8f..12d6c53adcdf773ff95190c7936a3c5a3f26e9bf 100644
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
@@ -628,7 +628,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
@@ -627,7 +627,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
protected void tickDeath() {
++this.deathTime;

View File

@ -5,10 +5,10 @@ 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 702dbcf60ba35a3427353ea27547dab4b4c11ecc..432e9259bb0a4715eb7f30d331f33cc79b632f83 100644
index 12d6c53adcdf773ff95190c7936a3c5a3f26e9bf..d9603cfc81b2f0b77a85a5dd99ae2db013937b14 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 {
@@ -860,7 +860,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
boolean flag = scoreboardteam != null && this.level().getScoreboard().addPlayerToTeam(this.getStringUUID(), scoreboardteam);
if (!flag) {

View File

@ -5,7 +5,7 @@ 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 6f9ec543185b6f68bb1eaa61a7ebea9d866d688f..cf147f5318cb27571b4b050b92d7df582ddccea2 100644
index 2562ea3b63b055319a775c12ff327d127f8039c3..ad85b716f861a38192d51fc2f9725d48255d5f7c 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 @@
@ -15,7 +15,7 @@ index 6f9ec543185b6f68bb1eaa61a7ebea9d866d688f..cf147f5318cb27571b4b050b92d7df58
import com.google.common.collect.Lists;
import com.google.common.primitives.Floats;
import com.mojang.authlib.GameProfile;
@@ -2019,6 +2020,12 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
@@ -2018,6 +2019,12 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
Entity entity = packet.getEntity(worldserver);
if (entity != null) {

View File

@ -5,7 +5,7 @@ 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 cf147f5318cb27571b4b050b92d7df582ddccea2..06fd1a549c9829c250c983861e3a02ed14c21f4f 100644
index ad85b716f861a38192d51fc2f9725d48255d5f7c..9f0a66d21ccac4b22f1fc7a632170ef16d0b82c5 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -29,6 +29,7 @@ import java.util.function.UnaryOperator;
@ -16,7 +16,7 @@ index cf147f5318cb27571b4b050b92d7df582ddccea2..06fd1a549c9829c250c983861e3a02ed
import net.minecraft.ChatFormatting;
import net.minecraft.SharedConstants;
import net.minecraft.Util;
@@ -2891,6 +2892,18 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
@@ -2879,6 +2880,18 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
return;
}

View File

@ -5,10 +5,10 @@ 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 06fd1a549c9829c250c983861e3a02ed14c21f4f..af9af2fd22eb9ecaec86888752f177f6ed6ae0b0 100644
index 9f0a66d21ccac4b22f1fc7a632170ef16d0b82c5..62c4470308ebcca9c5b6850065906a33879c0016 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -1264,7 +1264,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
@@ -1263,7 +1263,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
if (this.player.hasPermissions(2)) {
Entity entity = this.player.level().getEntity(packet.getEntityId());
@ -17,7 +17,7 @@ index 06fd1a549c9829c250c983861e3a02ed14c21f4f..af9af2fd22eb9ecaec86888752f177f6
CompoundTag nbttagcompound = entity.saveWithoutId(new CompoundTag());
this.player.connection.send(new ClientboundTagQueryPacket(packet.getTransactionId(), nbttagcompound));
@@ -1296,7 +1296,10 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
@@ -1295,7 +1295,10 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
@Override
public void handleBlockEntityTagQuery(ServerboundBlockEntityTagQuery packet) {
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());

View File

@ -62,7 +62,7 @@ index ba12919c3f9aec34a9e64993b143ae92be5eb172..bdfa4a7f5b50e80195e79a6dd1204cb7
}
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index af9af2fd22eb9ecaec86888752f177f6ed6ae0b0..551a353e53211ed07b3069f2a82eccb8c35823bf 100644
index 62c4470308ebcca9c5b6850065906a33879c0016..3eae4d979400b1e206abfcee676653ce7966155e 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 @@
@ -72,7 +72,7 @@ index af9af2fd22eb9ecaec86888752f177f6ed6ae0b0..551a353e53211ed07b3069f2a82eccb8
import me.totalfreedom.scissors.event.player.SpectatorTeleportEvent; // Scissors
import com.google.common.collect.Lists;
import com.google.common.primitives.Floats;
@@ -2229,7 +2230,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
@@ -2228,7 +2229,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
private void handleMessageDecodeFailure(SignedMessageChain.DecodeException exception) {
ServerGamePacketListenerImpl.LOGGER.warn("Failed to update secure chat state for {}: '{}'", this.player.getGameProfile().getName(), exception.getComponent().getString());
@ -81,7 +81,7 @@ index af9af2fd22eb9ecaec86888752f177f6ed6ae0b0..551a353e53211ed07b3069f2a82eccb8
this.disconnect(exception.getComponent(), exception.kickCause); // Paper - kick event causes
} else {
this.player.sendSystemMessage(exception.getComponent().copy().withStyle(ChatFormatting.RED));
@@ -2277,6 +2278,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
@@ -2276,6 +2277,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
Optional<LastSeenMessages> optional = this.lastSeenMessages.applyUpdate(acknowledgment);
if (optional.isEmpty()) {
@ -89,7 +89,7 @@ index af9af2fd22eb9ecaec86888752f177f6ed6ae0b0..551a353e53211ed07b3069f2a82eccb8
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
}
@@ -2475,6 +2477,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
@@ -2474,6 +2476,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
synchronized (this.lastSeenMessages) {
if (!this.lastSeenMessages.applyOffset(packet.offset())) {
@ -97,7 +97,7 @@ index af9af2fd22eb9ecaec86888752f177f6ed6ae0b0..551a353e53211ed07b3069f2a82eccb8
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
}
@@ -3453,6 +3456,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
@@ -3441,6 +3444,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
@Override
public void handleChatSessionUpdate(ServerboundChatSessionUpdatePacket packet) {
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());

View File

@ -18,7 +18,7 @@ index c99fc118013cb3d4043638e2001a8297e79ddf9c..cdaa81e1f2167b29ec01cc25e51a8400
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 551a353e53211ed07b3069f2a82eccb8c35823bf..51e5742e265d4d624eda119e199d6bc0f528b835 100644
index 3eae4d979400b1e206abfcee676653ce7966155e..60360cc52bbd61ae4e8b8b2f5f94b107aa0c88c8 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 @@
@ -47,7 +47,7 @@ index 551a353e53211ed07b3069f2a82eccb8c35823bf..51e5742e265d4d624eda119e199d6bc0
import org.slf4j.Logger;
// CraftBukkit start
@@ -891,6 +896,16 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
@@ -890,6 +895,16 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
this.player.level().getChunkAt(blockposition).setBlockEntity(tileentity);
}
@ -64,7 +64,7 @@ index 551a353e53211ed07b3069f2a82eccb8c35823bf..51e5742e265d4d624eda119e199d6bc0
commandblocklistenerabstract.setCommand(s);
commandblocklistenerabstract.setTrackOutput(flag);
if (!flag) {
@@ -922,7 +937,18 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
@@ -921,7 +936,18 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
BaseCommandBlock commandblocklistenerabstract = packet.getCommandBlock(this.player.level());
if (commandblocklistenerabstract != null) {

View File

@ -5,10 +5,10 @@ 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 51e5742e265d4d624eda119e199d6bc0f528b835..1865e5219bfb1930b2d01e03c04718b64617522f 100644
index 60360cc52bbd61ae4e8b8b2f5f94b107aa0c88c8..b42258c6d4d465a86e9e01464d99d72e1e70a82b 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -856,7 +856,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
@@ -855,7 +855,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"));
@ -17,7 +17,7 @@ index 51e5742e265d4d624eda119e199d6bc0f528b835..1865e5219bfb1930b2d01e03c04718b6
BaseCommandBlock commandblocklistenerabstract = null;
CommandBlockEntity tileentitycommand = null;
BlockPos blockposition = packet.getPos();
@@ -1025,7 +1025,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
@@ -1024,7 +1024,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
@Override
public void handleSetStructureBlock(ServerboundSetStructureBlockPacket packet) {
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
@ -26,7 +26,7 @@ index 51e5742e265d4d624eda119e199d6bc0f528b835..1865e5219bfb1930b2d01e03c04718b6
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
@@ -1082,7 +1082,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
@Override
public void handleSetJigsawBlock(ServerboundSetJigsawBlockPacket packet) {
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
@ -35,7 +35,7 @@ index 51e5742e265d4d624eda119e199d6bc0f528b835..1865e5219bfb1930b2d01e03c04718b6
BlockPos blockposition = packet.getPos();
BlockState iblockdata = this.player.level().getBlockState(blockposition);
BlockEntity tileentity = this.player.level().getBlockEntity(blockposition);
@@ -1108,7 +1108,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
@@ -1107,7 +1107,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
@Override
public void handleJigsawGenerate(ServerboundJigsawGeneratePacket packet) {
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());

View File

@ -0,0 +1,127 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Focusvity <nathan.curran10012@gmail.com>
Date: Mon, 5 Feb 2024 19:39:23 +1100
Subject: [PATCH] Add depth limit to Component deserialization
diff --git a/src/main/java/net/minecraft/network/chat/Component.java b/src/main/java/net/minecraft/network/chat/Component.java
index ba13650b52e39c9cc5cfa421f7720c7d4ba75678..f500b4aa5aaea89a2a878afe70d386f044401be4 100644
--- a/src/main/java/net/minecraft/network/chat/Component.java
+++ b/src/main/java/net/minecraft/network/chat/Component.java
@@ -3,9 +3,11 @@ package net.minecraft.network.chat;
import com.google.common.collect.Lists;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
+import com.google.gson.JsonArray;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.JsonParser;
import com.google.gson.JsonSerializationContext;
@@ -13,6 +15,7 @@ import com.google.gson.JsonSerializer;
import com.google.gson.stream.JsonReader;
import com.mojang.brigadier.Message;
import com.mojang.serialization.JsonOps;
+
import java.io.StringReader;
import java.lang.reflect.Type;
import java.util.ArrayList;
@@ -24,6 +27,7 @@ import java.util.Optional;
import java.util.UUID;
import javax.annotation.Nullable;
+import me.totalfreedom.scissors.ScissorsConfig; // Scissors
import net.minecraft.ChatFormatting;
import net.minecraft.Util;
import net.minecraft.network.chat.contents.DataSource;
@@ -35,8 +39,10 @@ import net.minecraft.network.chat.contents.SelectorContents;
import net.minecraft.network.chat.contents.TranslatableContents;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.FormattedCharSequence;
+import net.minecraft.util.GsonHelper;
import net.minecraft.world.level.ChunkPos;
// CraftBukkit start
+import java.util.regex.Pattern; // Scissors
import java.util.stream.Stream;
// CraftBukkit end
@@ -272,7 +278,8 @@ public interface Component extends Message, FormattedText, Iterable<Component> {
public static class SerializerAdapter implements JsonDeserializer<MutableComponent>, JsonSerializer<Component> {
- public SerializerAdapter() {}
+ public SerializerAdapter() {
+ }
public MutableComponent deserialize(JsonElement jsonelement, Type type, JsonDeserializationContext jsondeserializationcontext) throws JsonParseException {
return Component.Serializer.deserialize(jsonelement);
@@ -286,10 +293,66 @@ public interface Component extends Message, FormattedText, Iterable<Component> {
public static class Serializer {
private static final Gson GSON = (new GsonBuilder()).disableHtmlEscaping().create();
+ private static final Pattern PLACEHOLDER_PATTERN = Pattern.compile("%[0-9]+\\$s"); // Scissors
+
+ private Serializer() {
+ }
- private Serializer() {}
+ // Scissors start
+ static int depthChecker(int depth) {
+ depth = depth + 1;
+ if (depth > ScissorsConfig.componentDepthLimit) {
+ throw new JsonParseException("Depth limit exceeded");
+ }
+ return depth;
+ }
+
+ static int getPenalty(String string) {
+ if (PLACEHOLDER_PATTERN.matcher(string).find()) {
+ long translate_placeholders = PLACEHOLDER_PATTERN.matcher(string).results().count();
+ return (int) translate_placeholders * 12;
+ }
+ return 0;
+ }
static MutableComponent deserialize(JsonElement json) {
+ int depth = 1;
+ if (!json.isJsonPrimitive()) {
+ if (!json.isJsonObject()) {
+ if (json.isJsonArray()) {
+ JsonArray jsonArray = json.getAsJsonArray();
+ if (jsonArray.size() <= 0) throw new JsonParseException("Unexpected empty array of components");
+
+ for (JsonElement ignored : jsonArray) {
+ depth = depthChecker(depth);
+ }
+ }
+ } else {
+ JsonObject jsonObject = json.getAsJsonObject();
+ if (jsonObject.has("translate")) {
+ String s = GsonHelper.getAsString(jsonObject, "translate");
+ int penalty = getPenalty(s);
+ depth = depthChecker(depth + penalty);
+
+ if (jsonObject.has("with")) {
+ String s1 = GsonHelper.getAsJsonArray(jsonObject, "with").toString();
+ penalty = getPenalty(s1);
+ depth = depthChecker(depth + penalty);
+ }
+ }
+
+ if (jsonObject.has("extra")) {
+ JsonArray jsonArray = GsonHelper.getAsJsonArray(jsonObject, "extra");
+ if (jsonArray.size() <= 0) throw new JsonParseException("Unexpected empty array of components");
+
+ for (JsonElement ignored : jsonArray) {
+ depth = depthChecker(depth);
+ }
+ }
+ }
+ }
+ // Scissors end
+
return (MutableComponent) Util.getOrThrow(ComponentSerialization.CODEC.parse(JsonOps.INSTANCE, json), JsonParseException::new);
}