aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJason Penilla <[email protected]>2024-04-27 13:53:56 -0700
committerJason Penilla <[email protected]>2024-04-27 13:54:09 -0700
commitb7e148a107a7492945c4a342de800995a679a6c4 (patch)
treea3c8e8bdc9277ffa0745f03e03707da4ccd1da34
parentaf97400701fdabcfc8f4424fce27821a91ff8ad0 (diff)
downloadPaper-b7e148a107a7492945c4a342de800995a679a6c4.tar.gz
Paper-b7e148a107a7492945c4a342de800995a679a6c4.zip
Move obfhelper/stack deobf diff into original patch
-rw-r--r--patches/server/0001-Setup-Gradle-project.patch8
-rw-r--r--patches/server/0003-Build-system-changes.patch2
-rw-r--r--patches/server/0004-Test-changes.patch2
-rw-r--r--patches/server/0005-Paper-config-files.patch2
-rw-r--r--patches/server/0011-Use-TerminalConsoleAppender-for-console-improvements.patch2
-rw-r--r--patches/server/0012-Handle-plugin-prefixes-using-Log4J-configuration.patch2
-rw-r--r--patches/server/0014-Use-AsyncAppender-to-keep-logging-IO-off-main-thread.patch2
-rw-r--r--patches/server/0015-Deobfuscate-stacktraces-in-log-messages-crash-report.patch184
-rw-r--r--patches/server/0020-Plugin-remapping.patch25
-rw-r--r--patches/server/0022-Remap-reflection-calls-in-plugins-using-internals.patch276
-rw-r--r--patches/server/0283-Brigadier-Mojang-API.patch2
-rw-r--r--patches/server/0363-Implement-Mob-Goal-API.patch2
-rw-r--r--patches/server/0723-Add-support-for-Proxy-Protocol.patch2
-rw-r--r--patches/server/1012-Use-Velocity-compression-and-cipher-natives.patch2
14 files changed, 139 insertions, 374 deletions
diff --git a/patches/server/0001-Setup-Gradle-project.patch b/patches/server/0001-Setup-Gradle-project.patch
index b5c120a1df..d3e3f1ad9d 100644
--- a/patches/server/0001-Setup-Gradle-project.patch
+++ b/patches/server/0001-Setup-Gradle-project.patch
@@ -28,7 +28,7 @@ index 37dab9e868dbfb019c271a547d975a48ad1cb571..3811c0d849a3eb028ed1a6b7a2d4747f
+/.factorypath
diff --git a/build.gradle.kts b/build.gradle.kts
new file mode 100644
-index 0000000000000000000000000000000000000000..b3055953028759e4754d507c31f387b6bf7c0108
+index 0000000000000000000000000000000000000000..a41b15de7eba00d62822f582015d324ccde7dfe7
--- /dev/null
+++ b/build.gradle.kts
@@ -0,0 +1,119 @@
@@ -135,9 +135,9 @@ index 0000000000000000000000000000000000000000..b3055953028759e4754d507c31f387b6
+ runtime.filterNot { it.asFile.absolutePath == vanilla }
+ }
+
-+tasks.registerRunTask("runShadow") {
-+ description = "Spin up a test server from the shadowJar archiveFile"
-+ classpath(tasks.shadowJar.flatMap { it.archiveFile })
++tasks.registerRunTask("runServerJar") {
++ description = "Spin up a test server from the serverJar archiveFile"
++ classpath(tasks.serverJar.flatMap { it.archiveFile })
+ classpath(runtimeClasspathWithoutVanillaServer)
+}
+
diff --git a/patches/server/0003-Build-system-changes.patch b/patches/server/0003-Build-system-changes.patch
index 52428906e4..f7608aaf06 100644
--- a/patches/server/0003-Build-system-changes.patch
+++ b/patches/server/0003-Build-system-changes.patch
@@ -9,7 +9,7 @@ public net.minecraft.server.packs.VanillaPackResourcesBuilder safeGetPath(Ljava/
Co-authored-by: Jake Potrebic <[email protected]>
diff --git a/build.gradle.kts b/build.gradle.kts
-index b3055953028759e4754d507c31f387b6bf7c0108..39e4021d3fa7e79bd28463a01e3e6d07181f6765 100644
+index a41b15de7eba00d62822f582015d324ccde7dfe7..4d38e90fddc74fb0b0d1be23990d35e60ccd9544 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -8,9 +8,7 @@ plugins {
diff --git a/patches/server/0004-Test-changes.patch b/patches/server/0004-Test-changes.patch
index da0eca4b4b..b504fb1161 100644
--- a/patches/server/0004-Test-changes.patch
+++ b/patches/server/0004-Test-changes.patch
@@ -5,7 +5,7 @@ Subject: [PATCH] Test changes
diff --git a/build.gradle.kts b/build.gradle.kts
-index 39e4021d3fa7e79bd28463a01e3e6d07181f6765..83598b48724e3a4f40a153be3e681564105b90b4 100644
+index 4d38e90fddc74fb0b0d1be23990d35e60ccd9544..583f2c236d98d2c8348787eadc813d1218e25336 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -22,6 +22,7 @@ dependencies {
diff --git a/patches/server/0005-Paper-config-files.patch b/patches/server/0005-Paper-config-files.patch
index 3e158b1a0c..69e6aa4696 100644
--- a/patches/server/0005-Paper-config-files.patch
+++ b/patches/server/0005-Paper-config-files.patch
@@ -15,7 +15,7 @@ public net.minecraft.server.dedicated.DedicatedServerProperties reload(Lnet/mine
public net.minecraft.world.level.NaturalSpawner SPAWNING_CATEGORIES
diff --git a/build.gradle.kts b/build.gradle.kts
-index 83598b48724e3a4f40a153be3e681564105b90b4..94fcbfae0678391d38ee8e6e54576d9fb294585e 100644
+index 583f2c236d98d2c8348787eadc813d1218e25336..2a7db88148b708754d5f33ed5266ecefcad9d27c 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -10,6 +10,7 @@ dependencies {
diff --git a/patches/server/0011-Use-TerminalConsoleAppender-for-console-improvements.patch b/patches/server/0011-Use-TerminalConsoleAppender-for-console-improvements.patch
index 3692466a0c..b40a930712 100644
--- a/patches/server/0011-Use-TerminalConsoleAppender-for-console-improvements.patch
+++ b/patches/server/0011-Use-TerminalConsoleAppender-for-console-improvements.patch
@@ -25,7 +25,7 @@ Other changes:
Co-Authored-By: Emilia Kond <[email protected]>
diff --git a/build.gradle.kts b/build.gradle.kts
-index 94fcbfae0678391d38ee8e6e54576d9fb294585e..05ea33821177d5a4917cd3cb69be85fefb9452a7 100644
+index 2a7db88148b708754d5f33ed5266ecefcad9d27c..0aed38d217707a916f2a42ede9525b88560b6c8b 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -5,9 +5,29 @@ plugins {
diff --git a/patches/server/0012-Handle-plugin-prefixes-using-Log4J-configuration.patch b/patches/server/0012-Handle-plugin-prefixes-using-Log4J-configuration.patch
index e3a8285a0e..32b5c0e06d 100644
--- a/patches/server/0012-Handle-plugin-prefixes-using-Log4J-configuration.patch
+++ b/patches/server/0012-Handle-plugin-prefixes-using-Log4J-configuration.patch
@@ -15,7 +15,7 @@ This may cause additional prefixes to be disabled for plugins bypassing
the plugin logger.
diff --git a/build.gradle.kts b/build.gradle.kts
-index 05ea33821177d5a4917cd3cb69be85fefb9452a7..859ef5811880e988640230374f180fb2d197a26e 100644
+index 0aed38d217707a916f2a42ede9525b88560b6c8b..4260860c3dc0335b570899ab461c17f0ade00ed6 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -23,7 +23,7 @@ dependencies {
diff --git a/patches/server/0014-Use-AsyncAppender-to-keep-logging-IO-off-main-thread.patch b/patches/server/0014-Use-AsyncAppender-to-keep-logging-IO-off-main-thread.patch
index 920a040798..3f7d87c091 100644
--- a/patches/server/0014-Use-AsyncAppender-to-keep-logging-IO-off-main-thread.patch
+++ b/patches/server/0014-Use-AsyncAppender-to-keep-logging-IO-off-main-thread.patch
@@ -5,7 +5,7 @@ Subject: [PATCH] Use AsyncAppender to keep logging IO off main thread
diff --git a/build.gradle.kts b/build.gradle.kts
-index 859ef5811880e988640230374f180fb2d197a26e..2412647683b78f811537bf527d2c70bd3ec7ad21 100644
+index 4260860c3dc0335b570899ab461c17f0ade00ed6..d3005f310a256c000a62314832d5e90eecfefbf6 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -32,8 +32,7 @@ dependencies {
diff --git a/patches/server/0015-Deobfuscate-stacktraces-in-log-messages-crash-report.patch b/patches/server/0015-Deobfuscate-stacktraces-in-log-messages-crash-report.patch
index c9901448e0..77aa4f4e51 100644
--- a/patches/server/0015-Deobfuscate-stacktraces-in-log-messages-crash-report.patch
+++ b/patches/server/0015-Deobfuscate-stacktraces-in-log-messages-crash-report.patch
@@ -6,17 +6,17 @@ Subject: [PATCH] Deobfuscate stacktraces in log messages, crash reports, and
diff --git a/build.gradle.kts b/build.gradle.kts
-index 2412647683b78f811537bf527d2c70bd3ec7ad21..dbb67a5dc1eecb1339cd4da1a23e69ed675ddbe4 100644
+index d3005f310a256c000a62314832d5e90eecfefbf6..3587ff0a4c0fe92c99501aa5251f379481e43437 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
-@@ -32,6 +32,7 @@ dependencies {
- implementation("org.ow2.asm:asm-commons:9.7")
- implementation("org.spongepowered:configurate-yaml:4.2.0-SNAPSHOT") // Paper - config files
- implementation("commons-lang:commons-lang:2.6")
-+ implementation("net.fabricmc:mapping-io:0.5.0") // Paper - needed to read mappings for stacktrace deobfuscation
- runtimeOnly("com.lmax:disruptor:3.4.4") // Paper
+@@ -43,6 +43,7 @@ dependencies {
+ testImplementation("org.mockito:mockito-core:5.11.0")
+ testImplementation("org.ow2.asm:asm-tree:9.7")
+ testImplementation("org.junit-pioneer:junit-pioneer:2.2.0") // Paper - CartesianTest
++ implementation("net.neoforged:srgutils:1.0.9") // Paper - mappings handling
+ }
- runtimeOnly("org.apache.maven:maven-resolver-provider:3.9.6")
+ val craftbukkitPackageVersion = "1_20_R4" // Paper
diff --git a/src/log4jPlugins/java/io/papermc/paper/logging/StacktraceDeobfuscatingRewritePolicy.java b/src/log4jPlugins/java/io/papermc/paper/logging/StacktraceDeobfuscatingRewritePolicy.java
new file mode 100644
index 0000000000000000000000000000000000000000..66b6011ee3684695b2ab9292961c80bf2a420ee9
@@ -91,27 +91,21 @@ index 0000000000000000000000000000000000000000..66b6011ee3684695b2ab9292961c80bf
+}
diff --git a/src/main/java/io/papermc/paper/util/ObfHelper.java b/src/main/java/io/papermc/paper/util/ObfHelper.java
new file mode 100644
-index 0000000000000000000000000000000000000000..e8ff684d8bd994c64ff34f20e1e0601b678244c1
+index 0000000000000000000000000000000000000000..9e6d48335b37fa5204bfebf396d748089884555b
--- /dev/null
+++ b/src/main/java/io/papermc/paper/util/ObfHelper.java
-@@ -0,0 +1,147 @@
+@@ -0,0 +1,156 @@
+package io.papermc.paper.util;
+
+import java.io.IOException;
+import java.io.InputStream;
-+import java.io.InputStreamReader;
-+import java.nio.charset.StandardCharsets;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
-+import java.util.function.Function;
+import java.util.stream.Collectors;
-+import net.fabricmc.mappingio.MappingReader;
-+import net.fabricmc.mappingio.format.MappingFormat;
-+import net.fabricmc.mappingio.tree.MappingTree;
-+import net.fabricmc.mappingio.tree.MemoryMappingTree;
++import net.neoforged.srgutils.IMappingFile;
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.checkerframework.checker.nullness.qual.Nullable;
+import org.checkerframework.framework.qual.DefaultQualifier;
@@ -120,9 +114,6 @@ index 0000000000000000000000000000000000000000..e8ff684d8bd994c64ff34f20e1e0601b
+public enum ObfHelper {
+ INSTANCE;
+
-+ public static final String MOJANG_PLUS_YARN_NAMESPACE = "mojang+yarn";
-+ public static final String SPIGOT_NAMESPACE = "spigot";
-+
+ private final @Nullable Map<String, ClassMapping> mappingsByObfName;
+ private final @Nullable Map<String, ClassMapping> mappingsByMojangName;
+
@@ -190,73 +181,90 @@ index 0000000000000000000000000000000000000000..e8ff684d8bd994c64ff34f20e1e0601b
+ if (mappingsInputStream == null) {
+ return null;
+ }
-+ final MemoryMappingTree tree = new MemoryMappingTree();
-+ MappingReader.read(new InputStreamReader(mappingsInputStream, StandardCharsets.UTF_8), MappingFormat.TINY_2_FILE, tree);
++ final IMappingFile mappings = IMappingFile.load(mappingsInputStream); // Mappings are mojang->spigot
+ final Set<ClassMapping> classes = new HashSet<>();
+
+ final StringPool pool = new StringPool();
-+ for (final MappingTree.ClassMapping cls : tree.getClasses()) {
++ for (final IMappingFile.IClass cls : mappings.getClasses()) {
+ final Map<String, String> methods = new HashMap<>();
++ final Map<String, String> fields = new HashMap<>();
++ final Map<String, String> strippedMethods = new HashMap<>();
+
-+ for (final MappingTree.MethodMapping methodMapping : cls.getMethods()) {
++ for (final IMappingFile.IMethod methodMapping : cls.getMethods()) {
+ methods.put(
-+ pool.string(methodKey(
-+ Objects.requireNonNull(methodMapping.getName(SPIGOT_NAMESPACE)),
-+ Objects.requireNonNull(methodMapping.getDesc(SPIGOT_NAMESPACE))
-+ )),
-+ pool.string(Objects.requireNonNull(methodMapping.getName(MOJANG_PLUS_YARN_NAMESPACE)))
++ pool.string(methodKey(
++ Objects.requireNonNull(methodMapping.getMapped()),
++ Objects.requireNonNull(methodMapping.getMappedDescriptor())
++ )),
++ pool.string(Objects.requireNonNull(methodMapping.getOriginal()))
++ );
++
++ strippedMethods.put(
++ pool.string(pool.string(strippedMethodKey(
++ methodMapping.getMapped(),
++ methodMapping.getDescriptor()
++ ))),
++ pool.string(methodMapping.getOriginal())
++ );
++ }
++ for (final IMappingFile.IField field : cls.getFields()) {
++ fields.put(
++ pool.string(field.getMapped()),
++ pool.string(field.getOriginal())
+ );
+ }
+
+ final ClassMapping map = new ClassMapping(
-+ Objects.requireNonNull(cls.getName(SPIGOT_NAMESPACE)).replace('/', '.'),
-+ Objects.requireNonNull(cls.getName(MOJANG_PLUS_YARN_NAMESPACE)).replace('/', '.'),
-+ Map.copyOf(methods)
++ Objects.requireNonNull(cls.getMapped()).replace('/', '.'),
++ Objects.requireNonNull(cls.getOriginal()).replace('/', '.'),
++ Map.copyOf(methods),
++ Map.copyOf(fields),
++ Map.copyOf(strippedMethods)
+ );
+ classes.add(map);
+ }
+
+ return Set.copyOf(classes);
+ } catch (final IOException ex) {
-+ System.err.println("Failed to load mappings for stacktrace deobfuscation.");
++ System.err.println("Failed to load mappings.");
+ ex.printStackTrace();
+ return null;
+ }
+ }
+
-+ public static String methodKey(final String obfName, final String obfDescriptor) {
-+ return obfName + obfDescriptor;
++ public static String strippedMethodKey(final String methodName, final String methodDescriptor) {
++ final String methodKey = methodKey(methodName, methodDescriptor);
++ final int returnDescriptorEnd = methodKey.indexOf(')');
++ return methodKey.substring(0, returnDescriptorEnd + 1);
+ }
+
-+ private static final class StringPool {
-+ private final Map<String, String> pool = new HashMap<>();
-+
-+ public String string(final String string) {
-+ return this.pool.computeIfAbsent(string, Function.identity());
-+ }
++ public static String methodKey(final String methodName, final String methodDescriptor) {
++ return methodName + methodDescriptor;
+ }
+
+ public record ClassMapping(
-+ String obfName,
-+ String mojangName,
-+ Map<String, String> methodsByObf
++ String obfName,
++ String mojangName,
++ Map<String, String> methodsByObf,
++ Map<String, String> fieldsByObf,
++ // obf name with mapped desc to mapped name. return value is excluded from desc as reflection doesn't use it
++ Map<String, String> strippedMethods
+ ) {}
+}
diff --git a/src/main/java/io/papermc/paper/util/StacktraceDeobfuscator.java b/src/main/java/io/papermc/paper/util/StacktraceDeobfuscator.java
new file mode 100644
-index 0000000000000000000000000000000000000000..eb910d4abf91488fa7cf1f5d47e0ee916c47f512
+index 0000000000000000000000000000000000000000..242811578a786e3807a1a7019d472d5a68f87116
--- /dev/null
+++ b/src/main/java/io/papermc/paper/util/StacktraceDeobfuscator.java
-@@ -0,0 +1,163 @@
+@@ -0,0 +1,144 @@
+package io.papermc.paper.util;
+
+import io.papermc.paper.configuration.GlobalConfiguration;
-+import it.unimi.dsi.fastutil.ints.IntArrayList;
-+import it.unimi.dsi.fastutil.ints.IntList;
++import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
++import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Collections;
-+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import org.checkerframework.checker.nullness.qual.NonNull;
@@ -272,9 +280,9 @@ index 0000000000000000000000000000000000000000..eb910d4abf91488fa7cf1f5d47e0ee91
+public enum StacktraceDeobfuscator {
+ INSTANCE;
+
-+ private final Map<Class<?>, Map<String, IntList>> lineMapCache = Collections.synchronizedMap(new LinkedHashMap<>(128, 0.75f, true) {
++ private final Map<Class<?>, Int2ObjectMap<String>> lineMapCache = Collections.synchronizedMap(new LinkedHashMap<>(128, 0.75f, true) {
+ @Override
-+ protected boolean removeEldestEntry(final Map.Entry<Class<?>, Map<String, IntList>> eldest) {
++ protected boolean removeEldestEntry(final Map.Entry<Class<?>, Int2ObjectMap<String>> eldest) {
+ return this.size() > 127;
+ }
+ });
@@ -339,18 +347,7 @@ index 0000000000000000000000000000000000000000..eb910d4abf91488fa7cf1f5d47e0ee91
+ }
+
+ private @Nullable String determineMethodForLine(final Class<?> clazz, final int lineNumber) {
-+ final Map<String, IntList> lineMap = this.lineMapCache.computeIfAbsent(clazz, StacktraceDeobfuscator::buildLineMap);
-+ for (final var entry : lineMap.entrySet()) {
-+ final String methodKey = entry.getKey();
-+ final IntList lines = entry.getValue();
-+ for (int i = 0, linesSize = lines.size(); i < linesSize; i++) {
-+ final int num = lines.getInt(i);
-+ if (num == lineNumber) {
-+ return methodKey;
-+ }
-+ }
-+ }
-+ return null;
++ return this.lineMapCache.computeIfAbsent(clazz, StacktraceDeobfuscator::buildLineMap).get(lineNumber);
+ }
+
+ private static String sourceFileName(final String fullClassName) {
@@ -362,34 +359,27 @@ index 0000000000000000000000000000000000000000..eb910d4abf91488fa7cf1f5d47e0ee91
+ return rootClassName + ".java";
+ }
+
-+ private static Map<String, IntList> buildLineMap(final Class<?> key) {
-+ final Map<String, IntList> lineMap = new HashMap<>();
++ private static Int2ObjectMap<String> buildLineMap(final Class<?> key) {
++ final StringPool pool = new StringPool();
++ final Int2ObjectMap<String> lineMap = new Int2ObjectOpenHashMap<>();
+ final class LineCollectingMethodVisitor extends MethodVisitor {
-+ private final IntList lines = new IntArrayList();
+ private final String name;
+ private final String descriptor;
+
-+ LineCollectingMethodVisitor(String name, String descriptor) {
++ LineCollectingMethodVisitor(final String name, final String descriptor) {
+ super(Opcodes.ASM9);
+ this.name = name;
+ this.descriptor = descriptor;
+ }
+
+ @Override
-+ public void visitLineNumber(int line, Label start) {
-+ super.visitLineNumber(line, start);
-+ this.lines.add(line);
-+ }
-+
-+ @Override
-+ public void visitEnd() {
-+ super.visitEnd();
-+ lineMap.put(ObfHelper.methodKey(this.name, this.descriptor), this.lines);
++ public void visitLineNumber(final int line, final Label start) {
++ lineMap.put(line, pool.string(ObfHelper.methodKey(this.name, this.descriptor)));
+ }
+ }
+ final ClassVisitor classVisitor = new ClassVisitor(Opcodes.ASM9) {
+ @Override
-+ public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) {
++ public MethodVisitor visitMethod(final int access, final String name, final String descriptor, final String signature, final String[] exceptions) {
+ return new LineCollectingMethodVisitor(name, descriptor);
+ }
+ };
@@ -411,6 +401,46 @@ index 0000000000000000000000000000000000000000..eb910d4abf91488fa7cf1f5d47e0ee91
+ return lineMap;
+ }
+}
+diff --git a/src/main/java/io/papermc/paper/util/StringPool.java b/src/main/java/io/papermc/paper/util/StringPool.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..c0a486cb46ff30353c3ff09567891cd36238eeb4
+--- /dev/null
++++ b/src/main/java/io/papermc/paper/util/StringPool.java
+@@ -0,0 +1,34 @@
++package io.papermc.paper.util;
++
++import java.util.HashMap;
++import java.util.Map;
++import java.util.function.Function;
++import org.checkerframework.checker.nullness.qual.NonNull;
++import org.checkerframework.framework.qual.DefaultQualifier;
++
++/**
++ * De-duplicates {@link String} instances without using {@link String#intern()}.
++ *
++ * <p>Interning may not be desired as we may want to use the heap for our pool,
++ * so it can be garbage collected as normal, etc.</p>
++ *
++ * <p>Additionally, interning can be slow due to the potentially large size of the
++ * pool (as it is shared for the entire JVM), and because most JVMs implement
++ * it using JNI.</p>
++ */
++@DefaultQualifier(NonNull.class)
++public final class StringPool {
++ private final Map<String, String> pool;
++
++ public StringPool() {
++ this(new HashMap<>());
++ }
++
++ public StringPool(final Map<String, String> map) {
++ this.pool = map;
++ }
++
++ public String string(final String string) {
++ return this.pool.computeIfAbsent(string, Function.identity());
++ }
++}
diff --git a/src/main/java/net/minecraft/CrashReport.java b/src/main/java/net/minecraft/CrashReport.java
index a23407fa1b906743890cff74f5051ad55d59c85e..06c514b2d0674cd7df6692981f020437ea0f2f91 100644
--- a/src/main/java/net/minecraft/CrashReport.java
diff --git a/patches/server/0020-Plugin-remapping.patch b/patches/server/0020-Plugin-remapping.patch
index 62d0316083..4f89a129ef 100644
--- a/patches/server/0020-Plugin-remapping.patch
+++ b/patches/server/0020-Plugin-remapping.patch
@@ -6,15 +6,14 @@ Subject: [PATCH] Plugin remapping
Co-authored-by: Nassim Jahnke <[email protected]>
diff --git a/build.gradle.kts b/build.gradle.kts
-index dbb67a5dc1eecb1339cd4da1a23e69ed675ddbe4..c29c309503d5d5defe7991baca34b0d692d57e36 100644
+index 3587ff0a4c0fe92c99501aa5251f379481e43437..600b442986fa5ca9dd12f900caa284b854cc30ca 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
-@@ -44,9 +44,14 @@ dependencies {
- testImplementation("org.mockito:mockito-core:5.11.0")
+@@ -44,9 +44,13 @@ dependencies {
testImplementation("org.ow2.asm:asm-tree:9.7")
testImplementation("org.junit-pioneer:junit-pioneer:2.2.0") // Paper - CartesianTest
+ implementation("net.neoforged:srgutils:1.0.9") // Paper - mappings handling
+ implementation("net.neoforged:AutoRenamingTool:2.0.3") // Paper - remap plugins
-+ implementation("net.neoforged:srgutils:1.0.9") // Paper - remap plugins - bump transitive of ART
+}
+
+paperweight {
@@ -25,7 +24,7 @@ index dbb67a5dc1eecb1339cd4da1a23e69ed675ddbe4..c29c309503d5d5defe7991baca34b0d6
tasks.jar {
archiveClassifier.set("dev")
-@@ -66,7 +71,7 @@ tasks.jar {
+@@ -66,7 +70,7 @@ tasks.jar {
"Specification-Vendor" to "Bukkit Team",
"Git-Branch" to gitBranch, // Paper
"Git-Commit" to gitHash, // Paper
@@ -34,13 +33,13 @@ index dbb67a5dc1eecb1339cd4da1a23e69ed675ddbe4..c29c309503d5d5defe7991baca34b0d6
)
for (tld in setOf("net", "com", "org")) {
attributes("$tld/bukkit", "Sealed" to true)
-@@ -155,20 +160,41 @@ val runtimeClasspathWithoutVanillaServer = configurations.runtimeClasspath.flatM
+@@ -155,20 +159,41 @@ val runtimeClasspathWithoutVanillaServer = configurations.runtimeClasspath.flatM
runtime.filterNot { it.asFile.absolutePath == vanilla }
}
--tasks.registerRunTask("runShadow") {
-- description = "Spin up a test server from the shadowJar archiveFile"
-- classpath(tasks.shadowJar.flatMap { it.archiveFile })
+-tasks.registerRunTask("runServerJar") {
+- description = "Spin up a test server from the serverJar archiveFile"
+- classpath(tasks.serverJar.flatMap { it.archiveFile })
+tasks.registerRunTask("runServer") {
+ description = "Spin up a test server from the Mojang mapped server jar"
+ classpath(tasks.includeMappings.flatMap { it.outputJar })
@@ -1362,10 +1361,10 @@ index 0000000000000000000000000000000000000000..8e4229634d41a42b3d93948eebb77def
+ }
+}
diff --git a/src/main/java/io/papermc/paper/util/ObfHelper.java b/src/main/java/io/papermc/paper/util/ObfHelper.java
-index e8ff684d8bd994c64ff34f20e1e0601b678244c1..3f03d5efcd95e3adb76dc4292b3d2c420fdc58af 100644
+index 9e6d48335b37fa5204bfebf396d748089884555b..6067be951c4c52c4b1da51efc01436b2c90ea3bf 100644
--- a/src/main/java/io/papermc/paper/util/ObfHelper.java
+++ b/src/main/java/io/papermc/paper/util/ObfHelper.java
-@@ -89,10 +89,10 @@ public enum ObfHelper {
+@@ -80,10 +80,10 @@ public enum ObfHelper {
}
private static @Nullable Set<ClassMapping> loadMappingsIfPresent() {
@@ -1377,9 +1376,9 @@ index e8ff684d8bd994c64ff34f20e1e0601b678244c1..3f03d5efcd95e3adb76dc4292b3d2c42
+ return null;
+ }
+ try (final InputStream mappingsInputStream = MappingEnvironment.mappingsStream()) {
- final MemoryMappingTree tree = new MemoryMappingTree();
- MappingReader.read(new InputStreamReader(mappingsInputStream, StandardCharsets.UTF_8), MappingFormat.TINY_2_FILE, tree);
+ final IMappingFile mappings = IMappingFile.load(mappingsInputStream); // Mappings are mojang->spigot
final Set<ClassMapping> classes = new HashSet<>();
+
diff --git a/src/main/java/io/papermc/paper/util/concurrent/ScalingThreadPool.java b/src/main/java/io/papermc/paper/util/concurrent/ScalingThreadPool.java
new file mode 100644
index 0000000000000000000000000000000000000000..badff5d6ae6dd8d209c82bc7e8afe370db6148f2
diff --git a/patches/server/0022-Remap-reflection-calls-in-plugins-using-internals.patch b/patches/server/0022-Remap-reflection-calls-in-plugins-using-internals.patch
index 348061d5a7..817d23fa98 100644
--- a/patches/server/0022-Remap-reflection-calls-in-plugins-using-internals.patch
+++ b/patches/server/0022-Remap-reflection-calls-in-plugins-using-internals.patch
@@ -6,21 +6,13 @@ Subject: [PATCH] Remap reflection calls in plugins using internals
Co-authored-by: Jason Penilla <[email protected]>
diff --git a/build.gradle.kts b/build.gradle.kts
-index c29c309503d5d5defe7991baca34b0d692d57e36..1caa3ef9f0fd71f2bea2e1ea36bb2fa34c6ee689 100644
+index 600b442986fa5ca9dd12f900caa284b854cc30ca..caf738482232039e6e28376daa37b2a3a7465c69 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
-@@ -32,7 +32,6 @@ dependencies {
- implementation("org.ow2.asm:asm-commons:9.7")
- implementation("org.spongepowered:configurate-yaml:4.2.0-SNAPSHOT") // Paper - config files
- implementation("commons-lang:commons-lang:2.6")
-- implementation("net.fabricmc:mapping-io:0.5.0") // Paper - needed to read mappings for stacktrace deobfuscation
- runtimeOnly("com.lmax:disruptor:3.4.4") // Paper
-
- runtimeOnly("org.apache.maven:maven-resolver-provider:3.9.6")
-@@ -46,6 +45,12 @@ dependencies {
+@@ -45,6 +45,12 @@ dependencies {
testImplementation("org.junit-pioneer:junit-pioneer:2.2.0") // Paper - CartesianTest
+ implementation("net.neoforged:srgutils:1.0.9") // Paper - mappings handling
implementation("net.neoforged:AutoRenamingTool:2.0.3") // Paper - remap plugins
- implementation("net.neoforged:srgutils:1.0.9") // Paper - remap plugins - bump transitive of ART
+ // Paper start - Remap reflection
+ val reflectionRewriterVersion = "0.0.1"
+ implementation("io.papermc:reflection-rewriter:$reflectionRewriterVersion")
@@ -364,165 +356,11 @@ index 8e4229634d41a42b3d93948eebb77def7c0c72b1..38745299ea49f253a410e77557100903
private static final @Nullable String MAPPINGS_HASH = readMappingsHash();
private static final boolean REOBF = checkReobf();
-diff --git a/src/main/java/io/papermc/paper/util/ObfHelper.java b/src/main/java/io/papermc/paper/util/ObfHelper.java
-index 3f03d5efcd95e3adb76dc4292b3d2c420fdc58af..9eecb96cb7ec6d6a157ed2c5637e05138c3f55b9 100644
---- a/src/main/java/io/papermc/paper/util/ObfHelper.java
-+++ b/src/main/java/io/papermc/paper/util/ObfHelper.java
-@@ -2,19 +2,13 @@ package io.papermc.paper.util;
-
- import java.io.IOException;
- import java.io.InputStream;
--import java.io.InputStreamReader;
--import java.nio.charset.StandardCharsets;
- import java.util.HashMap;
- import java.util.HashSet;
- import java.util.Map;
- import java.util.Objects;
- import java.util.Set;
--import java.util.function.Function;
- import java.util.stream.Collectors;
--import net.fabricmc.mappingio.MappingReader;
--import net.fabricmc.mappingio.format.MappingFormat;
--import net.fabricmc.mappingio.tree.MappingTree;
--import net.fabricmc.mappingio.tree.MemoryMappingTree;
-+import net.neoforged.srgutils.IMappingFile;
- import org.checkerframework.checker.nullness.qual.NonNull;
- import org.checkerframework.checker.nullness.qual.Nullable;
- import org.checkerframework.framework.qual.DefaultQualifier;
-@@ -23,9 +17,6 @@ import org.checkerframework.framework.qual.DefaultQualifier;
- public enum ObfHelper {
- INSTANCE;
-
-- public static final String MOJANG_PLUS_YARN_NAMESPACE = "mojang+yarn";
-- public static final String SPIGOT_NAMESPACE = "spigot";
--
- private final @Nullable Map<String, ClassMapping> mappingsByObfName;
- private final @Nullable Map<String, ClassMapping> mappingsByMojangName;
-
-@@ -93,55 +84,73 @@ public enum ObfHelper {
- return null;
- }
- try (final InputStream mappingsInputStream = MappingEnvironment.mappingsStream()) {
-- final MemoryMappingTree tree = new MemoryMappingTree();
-- MappingReader.read(new InputStreamReader(mappingsInputStream, StandardCharsets.UTF_8), MappingFormat.TINY_2_FILE, tree);
-+ final IMappingFile mappings = IMappingFile.load(mappingsInputStream); // Mappings are mojang->spigot
- final Set<ClassMapping> classes = new HashSet<>();
-
- final StringPool pool = new StringPool();
-- for (final MappingTree.ClassMapping cls : tree.getClasses()) {
-+ for (final IMappingFile.IClass cls : mappings.getClasses()) {
- final Map<String, String> methods = new HashMap<>();
-+ final Map<String, String> fields = new HashMap<>();
-+ final Map<String, String> strippedMethods = new HashMap<>();
-
-- for (final MappingTree.MethodMapping methodMapping : cls.getMethods()) {
-+ for (final IMappingFile.IMethod methodMapping : cls.getMethods()) {
- methods.put(
- pool.string(methodKey(
-- Objects.requireNonNull(methodMapping.getName(SPIGOT_NAMESPACE)),
-- Objects.requireNonNull(methodMapping.getDesc(SPIGOT_NAMESPACE))
-+ Objects.requireNonNull(methodMapping.getMapped()),
-+ Objects.requireNonNull(methodMapping.getMappedDescriptor())
- )),
-- pool.string(Objects.requireNonNull(methodMapping.getName(MOJANG_PLUS_YARN_NAMESPACE)))
-+ pool.string(Objects.requireNonNull(methodMapping.getOriginal()))
-+ );
-+
-+ strippedMethods.put(
-+ pool.string(pool.string(strippedMethodKey(
-+ methodMapping.getMapped(),
-+ methodMapping.getDescriptor()
-+ ))),
-+ pool.string(methodMapping.getOriginal())
-+ );
-+ }
-+ for (final IMappingFile.IField field : cls.getFields()) {
-+ fields.put(
-+ pool.string(field.getMapped()),
-+ pool.string(field.getOriginal())
- );
- }
-
- final ClassMapping map = new ClassMapping(
-- Objects.requireNonNull(cls.getName(SPIGOT_NAMESPACE)).replace('/', '.'),
-- Objects.requireNonNull(cls.getName(MOJANG_PLUS_YARN_NAMESPACE)).replace('/', '.'),
-- Map.copyOf(methods)
-+ Objects.requireNonNull(cls.getMapped()).replace('/', '.'),
-+ Objects.requireNonNull(cls.getOriginal()).replace('/', '.'),
-+ Map.copyOf(methods),
-+ Map.copyOf(fields),
-+ Map.copyOf(strippedMethods)
- );
- classes.add(map);
- }
-
- return Set.copyOf(classes);
- } catch (final IOException ex) {
-- System.err.println("Failed to load mappings for stacktrace deobfuscation.");
-+ System.err.println("Failed to load mappings.");
- ex.printStackTrace();
- return null;
- }
- }
-
-- public static String methodKey(final String obfName, final String obfDescriptor) {
-- return obfName + obfDescriptor;
-+ public static String strippedMethodKey(final String methodName, final String methodDescriptor) {
-+ final String methodKey = methodKey(methodName, methodDescriptor);
-+ final int returnDescriptorEnd = methodKey.indexOf(')');
-+ return methodKey.substring(0, returnDescriptorEnd + 1);
- }
-
-- private static final class StringPool {
-- private final Map<String, String> pool = new HashMap<>();
--
-- public String string(final String string) {
-- return this.pool.computeIfAbsent(string, Function.identity());
-- }
-+ public static String methodKey(final String methodName, final String methodDescriptor) {
-+ return methodName + methodDescriptor;
- }
-
- public record ClassMapping(
- String obfName,
- String mojangName,
-- Map<String, String> methodsByObf
-+ Map<String, String> methodsByObf,
-+ Map<String, String> fieldsByObf,
-+ // obf name with mapped desc to mapped name. return value is excluded from desc as reflection doesn't use it
-+ Map<String, String> strippedMethods
- ) {}
- }
diff --git a/src/main/java/io/papermc/paper/util/StacktraceDeobfuscator.java b/src/main/java/io/papermc/paper/util/StacktraceDeobfuscator.java
-index eb910d4abf91488fa7cf1f5d47e0ee916c47f512..0b65fdf53124f3dd042b2363b1b8df8e1ca7de00 100644
+index 242811578a786e3807a1a7019d472d5a68f87116..0b65fdf53124f3dd042b2363b1b8df8e1ca7de00 100644
--- a/src/main/java/io/papermc/paper/util/StacktraceDeobfuscator.java
+++ b/src/main/java/io/papermc/paper/util/StacktraceDeobfuscator.java
-@@ -1,12 +1,11 @@
- package io.papermc.paper.util;
-
- import io.papermc.paper.configuration.GlobalConfiguration;
--import it.unimi.dsi.fastutil.ints.IntArrayList;
--import it.unimi.dsi.fastutil.ints.IntList;
-+import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
-+import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
- import java.io.IOException;
- import java.io.InputStream;
- import java.util.Collections;
--import java.util.HashMap;
- import java.util.LinkedHashMap;
- import java.util.Map;
- import org.checkerframework.checker.nullness.qual.NonNull;
-@@ -22,14 +21,17 @@ import org.objectweb.asm.Opcodes;
- public enum StacktraceDeobfuscator {
- INSTANCE;
-
-- private final Map<Class<?>, Map<String, IntList>> lineMapCache = Collections.synchronizedMap(new LinkedHashMap<>(128, 0.75f, true) {
-+ private final Map<Class<?>, Int2ObjectMap<String>> lineMapCache = Collections.synchronizedMap(new LinkedHashMap<>(128, 0.75f, true) {
- @Override
-- protected boolean removeEldestEntry(final Map.Entry<Class<?>, Map<String, IntList>> eldest) {
-+ protected boolean removeEldestEntry(final Map.Entry<Class<?>, Int2ObjectMap<String>> eldest) {
- return this.size() > 127;
- }
+@@ -29,6 +29,9 @@ public enum StacktraceDeobfuscator {
});
public void deobfuscateThrowable(final Throwable throwable) {
@@ -532,7 +370,7 @@ index eb910d4abf91488fa7cf1f5d47e0ee916c47f512..0b65fdf53124f3dd042b2363b1b8df8e
if (GlobalConfiguration.get() != null && !GlobalConfiguration.get().logging.deobfuscateStacktraces) { // handle null as true
return;
}
-@@ -45,6 +47,9 @@ public enum StacktraceDeobfuscator {
+@@ -44,6 +47,9 @@ public enum StacktraceDeobfuscator {
}
public StackTraceElement[] deobfuscateStacktrace(final StackTraceElement[] traceElements) {
@@ -542,108 +380,6 @@ index eb910d4abf91488fa7cf1f5d47e0ee916c47f512..0b65fdf53124f3dd042b2363b1b8df8e
if (GlobalConfiguration.get() != null && !GlobalConfiguration.get().logging.deobfuscateStacktraces) { // handle null as true
return traceElements;
}
-@@ -89,18 +94,7 @@ public enum StacktraceDeobfuscator {
- }
-
- private @Nullable String determineMethodForLine(final Class<?> clazz, final int lineNumber) {
-- final Map<String, IntList> lineMap = this.lineMapCache.computeIfAbsent(clazz, StacktraceDeobfuscator::buildLineMap);
-- for (final var entry : lineMap.entrySet()) {
-- final String methodKey = entry.getKey();
-- final IntList lines = entry.getValue();
-- for (int i = 0, linesSize = lines.size(); i < linesSize; i++) {
-- final int num = lines.getInt(i);
-- if (num == lineNumber) {
-- return methodKey;
-- }
-- }
-- }
-- return null;
-+ return this.lineMapCache.computeIfAbsent(clazz, StacktraceDeobfuscator::buildLineMap).get(lineNumber);
- }
-
- private static String sourceFileName(final String fullClassName) {
-@@ -112,34 +106,27 @@ public enum StacktraceDeobfuscator {
- return rootClassName + ".java";
- }
-
-- private static Map<String, IntList> buildLineMap(final Class<?> key) {
-- final Map<String, IntList> lineMap = new HashMap<>();
-+ private static Int2ObjectMap<String> buildLineMap(final Class<?> key) {
-+ final StringPool pool = new StringPool();
-+ final Int2ObjectMap<String> lineMap = new Int2ObjectOpenHashMap<>();
- final class LineCollectingMethodVisitor extends MethodVisitor {
-- private final IntList lines = new IntArrayList();
- private final String name;
- private final String descriptor;
-
-- LineCollectingMethodVisitor(String name, String descriptor) {
-+ LineCollectingMethodVisitor(final String name, final String descriptor) {
- super(Opcodes.ASM9);
- this.name = name;
- this.descriptor = descriptor;
- }
-
- @Override
-- public void visitLineNumber(int line, Label start) {
-- super.visitLineNumber(line, start);
-- this.lines.add(line);
-- }
--
-- @Override
-- public void visitEnd() {
-- super.visitEnd();
-- lineMap.put(ObfHelper.methodKey(this.name, this.descriptor), this.lines);
-+ public void visitLineNumber(final int line, final Label start) {
-+ lineMap.put(line, pool.string(ObfHelper.methodKey(this.name, this.descriptor)));
- }
- }
- final ClassVisitor classVisitor = new ClassVisitor(Opcodes.ASM9) {
- @Override
-- public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) {
-+ public MethodVisitor visitMethod(final int access, final String name, final String descriptor, final String signature, final String[] exceptions) {
- return new LineCollectingMethodVisitor(name, descriptor);
- }
- };
-diff --git a/src/main/java/io/papermc/paper/util/StringPool.java b/src/main/java/io/papermc/paper/util/StringPool.java
-new file mode 100644
-index 0000000000000000000000000000000000000000..c0a486cb46ff30353c3ff09567891cd36238eeb4
---- /dev/null
-+++ b/src/main/java/io/papermc/paper/util/StringPool.java
-@@ -0,0 +1,34 @@
-+package io.papermc.paper.util;
-+
-+import java.util.HashMap;
-+import java.util.Map;
-+import java.util.function.Function;
-+import org.checkerframework.checker.nullness.qual.NonNull;
-+import org.checkerframework.framework.qual.DefaultQualifier;
-+
-+/**
-+ * De-duplicates {@link String} instances without using {@link String#intern()}.
-+ *
-+ * <p>Interning may not be desired as we may want to use the heap for our pool,
-+ * so it can be garbage collected as normal, etc.</p>
-+ *
-+ * <p>Additionally, interning can be slow due to the potentially large size of the
-+ * pool (as it is shared for the entire JVM), and because most JVMs implement
-+ * it using JNI.</p>
-+ */
-+@DefaultQualifier(NonNull.class)
-+public final class StringPool {
-+ private final Map<String, String> pool;
-+
-+ public StringPool() {
-+ this(new HashMap<>());
-+ }
-+
-+ public StringPool(final Map<String, String> map) {
-+ this.pool = map;
-+ }
-+
-+ public String string(final String string) {
-+ return this.pool.computeIfAbsent(string, Function.identity());
-+ }
-+}
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 457a963ee6ebd3cf5c3831f6660e3850335af49f..61744d8fde3ba98585cf261fc09f0acc042b67b8 100644
--- a/src/main/java/net/minecraft/world/level/redstone/CollectingNeighborUpdater.java
diff --git a/patches/server/0283-Brigadier-Mojang-API.patch b/patches/server/0283-Brigadier-Mojang-API.patch
index 80e75802b7..ce03b4e287 100644
--- a/patches/server/0283-Brigadier-Mojang-API.patch
+++ b/patches/server/0283-Brigadier-Mojang-API.patch
@@ -10,7 +10,7 @@ Adds CommandRegisteredEvent
- Allows manipulating the CommandNode to add more children/metadata for the client
diff --git a/build.gradle.kts b/build.gradle.kts
-index 1caa3ef9f0fd71f2bea2e1ea36bb2fa34c6ee689..b1b7d9b72c9f79fe2cfcde47be35a7e73b35d6ff 100644
+index caf738482232039e6e28376daa37b2a3a7465c69..8e667150eb288c4e2cbc8e9d97de040f38abdfb1 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -13,6 +13,7 @@ val alsoShade: Configuration by configurations.creating
diff --git a/patches/server/0363-Implement-Mob-Goal-API.patch b/patches/server/0363-Implement-Mob-Goal-API.patch
index 50b5ac2812..f618eaf066 100644
--- a/patches/server/0363-Implement-Mob-Goal-API.patch
+++ b/patches/server/0363-Implement-Mob-Goal-API.patch
@@ -5,7 +5,7 @@ Subject: [PATCH] Implement Mob Goal API
diff --git a/build.gradle.kts b/build.gradle.kts
-index b1b7d9b72c9f79fe2cfcde47be35a7e73b35d6ff..81b42b378f2d44ce1ffba5ee3f50aad3c13e60fa 100644
+index 8e667150eb288c4e2cbc8e9d97de040f38abdfb1..e4caad0371110c90b7c65cd6dccc53d549c98aca 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -39,6 +39,7 @@ dependencies {
diff --git a/patches/server/0723-Add-support-for-Proxy-Protocol.patch b/patches/server/0723-Add-support-for-Proxy-Protocol.patch
index 8a97a4d29d..d1b1e9e5fc 100644
--- a/patches/server/0723-Add-support-for-Proxy-Protocol.patch
+++ b/patches/server/0723-Add-support-for-Proxy-Protocol.patch
@@ -5,7 +5,7 @@ Subject: [PATCH] Add support for Proxy Protocol
diff --git a/build.gradle.kts b/build.gradle.kts
-index 81b42b378f2d44ce1ffba5ee3f50aad3c13e60fa..4216f5b1d5fa5769b6c2b24204e2146c4511cc8b 100644
+index e4caad0371110c90b7c65cd6dccc53d549c98aca..97d7857828007f5f164c76a33a68d7d2f4250dce 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -28,6 +28,7 @@ dependencies {
diff --git a/patches/server/1012-Use-Velocity-compression-and-cipher-natives.patch b/patches/server/1012-Use-Velocity-compression-and-cipher-natives.patch
index bf3cd56769..0c8f9cc197 100644
--- a/patches/server/1012-Use-Velocity-compression-and-cipher-natives.patch
+++ b/patches/server/1012-Use-Velocity-compression-and-cipher-natives.patch
@@ -5,7 +5,7 @@ Subject: [PATCH] Use Velocity compression and cipher natives
diff --git a/build.gradle.kts b/build.gradle.kts
-index 4216f5b1d5fa5769b6c2b24204e2146c4511cc8b..3b0cb2a4e200fb31b8789b2d99f033758b4f7145 100644
+index 97d7857828007f5f164c76a33a68d7d2f4250dce..2143aa04db50ec04448af338170d67369a5ca023 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -35,6 +35,11 @@ dependencies {