Switch to our own scoped ProblemReporter due to incompatible logger

Signed-off-by: Irmo van den Berge <irmo.vandenberge@ziggo.nl>
This commit is contained in:
Irmo van den Berge committed 2025-06-23 21:14:05 +02:00
1 parent a67ea23c9c
commit 630be93a7d
12 files changed
+153 -22

No files matched your search

@@ -21,12 +21,12 @@ public abstract class ValueInputHandle extends Template.Handle {
/* ============================================================================== */
public static ValueInputHandle forNBTOnWorld(Object problemReporter, World world, CommonTagCompound nbttagcompound) {
return T.forNBTOnWorld.invoke(problemReporter, world, nbttagcompound);
public static ValueInputHandle forNBTOnWorld(Object problemreporter, World world, CommonTagCompound nbttagcompound) {
return T.forNBTOnWorld.invoke(problemreporter, world, nbttagcompound);
}
public static ValueInputHandle forNBT(Object problemReporter, Object holderLookup, CommonTagCompound nbttagcompound) {
return T.forNBT.invoke(problemReporter, holderLookup, nbttagcompound);
public static ValueInputHandle forNBT(Object problemreporter, Object holderLookup, CommonTagCompound nbttagcompound) {
return T.forNBT.invoke(problemreporter, holderLookup, nbttagcompound);
}
public abstract CommonTagCompound asNBT();
@@ -28,6 +28,7 @@ import com.bergerkiller.bukkit.common.conversion.type.MapConversion;
import com.bergerkiller.bukkit.common.conversion.type.ScoreboardDisplaySlotConversion;
import com.bergerkiller.bukkit.common.conversion.type.SerializedEnumConversion;
import com.bergerkiller.bukkit.common.entity.CommonEntityType;
import com.bergerkiller.bukkit.common.internal.logic.ScopedProblemReporterInit;
import com.bergerkiller.bukkit.common.internal.logic.UnsetDataWatcherItemInit;
import com.bergerkiller.bukkit.common.wrappers.Brightness;
import com.bergerkiller.bukkit.common.wrappers.ItemDisplayMode;
@@ -827,7 +828,6 @@ public class CommonBootstrap {
// 1.21.6 mappings
if (evaluateMCVersion(">=", "1.21.6")) {
// Broken obfuscated crap on spigot :(
remappings.put("net.minecraft.util.ProblemReporter$ScopedCollector", "net.minecraft.util.ProblemReporter$j");
remappings.put("net.minecraft.world.level.storage.ValueInput$TypedInputList", "net.minecraft.world.level.storage.ValueInput$a");
remappings.put("net.minecraft.world.level.storage.ValueOutput$TypedOutputList", "net.minecraft.world.level.storage.ValueOutput$a");
remappings.put("net.minecraft.world.level.storage.TagValueInput$TypedListWrapper", "net.minecraft.world.level.storage.TagValueInput$f");
@@ -915,6 +915,7 @@ public class CommonBootstrap {
// Initialize this one right away, as it's used in generated code
NullPacketDataSerializerInit.initialize();
ScopedProblemReporterInit.initialize();
UnsetDataWatcherItemInit.initialize();
// Register converters
@@ -50,7 +50,7 @@ public class NullPacketDataSerializerInit {
// If class already exists, the library was probably reloaded. The generated class doesn't touch
// any of this library's code, so it's fine to keep using that one.
try {
Class.forName(CLASS_NAME);
Resolver.getClassByExactName(CLASS_NAME);
return;
} catch (ClassNotFoundException ex) { /* expected */ }
@@ -0,0 +1,114 @@
package com.bergerkiller.bukkit.common.internal.logic;
import com.bergerkiller.bukkit.common.Logging;
import com.bergerkiller.bukkit.common.internal.CommonBootstrap;
import com.bergerkiller.mountiplex.reflection.resolver.Resolver;
import com.bergerkiller.mountiplex.reflection.util.ExtendedClassWriter;
import com.bergerkiller.mountiplex.reflection.util.asm.MPLType;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import java.util.logging.Level;
import static org.objectweb.asm.Opcodes.*;
/**
* Initializes the <code>com.bergerkiller.bukkit.common.internal.logic.ScopedProblemReporter</code>
* which is made available inside templates as a <b>scoped</b> problem reporter. Calling
* close() on it will log any problems to (BKCommonLib's) logger.
*/
public class ScopedProblemReporterInit {
public static final String CLASS_NAME = "com.bergerkiller.bukkit.common.internal.logic.ScopedProblemReporter";
public static volatile boolean is_initialized = false;
/**
* Makes sure to initialize the ScopedProblemReporter as a class, making it available on
* BKCommonLib's class path.
*/
public static synchronized void initialize() {
if (is_initialized) {
return;
} else {
is_initialized = true;
}
// Only used on 1.21.6 and later
if (CommonBootstrap.evaluateMCVersion("<", "1.21.6")) {
return;
}
// If class already exists, the library was probably reloaded. The generated class doesn't touch
// any of this library's code, so it's fine to keep using that one.
try {
Resolver.getClassByExactName(CLASS_NAME);
return;
} catch (ClassNotFoundException ex) { /* expected */ }
try {
// Find the ProblemReporter type
Class<?> problemReporterBaseType = Resolver.loadClass("net.minecraft.util.ProblemReporter$a", false);
final ExtendedClassWriter<Object> cw = ExtendedClassWriter.builder(problemReporterBaseType)
.addInterface(AutoCloseable.class)
.setExactName(CLASS_NAME)
.build();
// Add a private final logger field
{
FieldVisitor fv = cw.visitField(ACC_PRIVATE | ACC_FINAL, "logger", "Ljava/util/logging/Logger;", null, null);
fv.visitEnd();
}
// Add a constructor that calls super() and initializes this field
{
MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "<init>", "(Ljava/util/logging/Logger;)V", null, null);
mv.visitCode();
mv.visitVarInsn(ALOAD, 0);
mv.visitMethodInsn(INVOKESPECIAL, MPLType.getInternalName(problemReporterBaseType), "<init>", "()V", false);
mv.visitVarInsn(ALOAD, 0);
mv.visitVarInsn(ALOAD, 1);
mv.visitFieldInsn(PUTFIELD, cw.getInternalName(), "logger", "Ljava/util/logging/Logger;");
mv.visitInsn(RETURN);
mv.visitMaxs(2, 2);
mv.visitEnd();
}
// We need these obfuscated method names to work properly
String isEmptyMethodName = Resolver.resolveMethodName(problemReporterBaseType, "isEmpty", new Class[0]);
String getTreeReportMethodName = Resolver.resolveMethodName(problemReporterBaseType, "getTreeReport", new Class[0]);
// Implement AutoCloseable close() that logs getTreeReport() to the logger
{
MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "close", "()V", null, null);
mv.visitCode();
mv.visitVarInsn(ALOAD, 0);
mv.visitMethodInsn(INVOKEVIRTUAL, cw.getInternalName(), isEmptyMethodName, "()Z", false);
Label label0 = new Label();
mv.visitJumpInsn(IFNE, label0);
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, cw.getInternalName(), "logger", "Ljava/util/logging/Logger;");
mv.visitTypeInsn(NEW, "java/lang/StringBuilder");
mv.visitInsn(DUP);
mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuilder", "<init>", "()V", false);
mv.visitLdcInsn("Serialization errors\n: ");
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;", false);
mv.visitVarInsn(ALOAD, 0);
mv.visitMethodInsn(INVOKEVIRTUAL, cw.getInternalName(), getTreeReportMethodName, "()Ljava/lang/String;", false);
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;", false);
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;", false);
mv.visitMethodInsn(INVOKEVIRTUAL, "java/util/logging/Logger", "warning", "(Ljava/lang/String;)V", false);
mv.visitLabel(label0);
mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
mv.visitInsn(RETURN);
mv.visitMaxs(3, 1);
mv.visitEnd();
}
cw.generate();
} catch (Throwable t) {
Logging.LOGGER_REFLECTION.log(Level.SEVERE, "Failed to initialize scoped problem reporter", t);
}
}
}
@@ -222,22 +222,22 @@ import net.minecraft.world.level.storage.TagValueInput;
// This is all needed for serialization functions (save/load) on 1.21.6+
#if version >= 1.21.6
#require net.minecraft.util.ProblemReporter.ScopedCollector public static net.minecraft.util.ProblemReporter.ScopedCollector createScopedProblemReporter() {
return new net.minecraft.util.ProblemReporter$ScopedCollector(
#require net.minecraft.util.ProblemReporter public static com.bergerkiller.bukkit.common.internal.logic.ScopedProblemReporter createScopedProblemReporter() {
return new com.bergerkiller.bukkit.common.internal.logic.ScopedProblemReporter(
com.bergerkiller.bukkit.common.Logging.LOGGER);
}
#require TagValueOutput public static ValueOutput createTagValueOutput(net.minecraft.util.ProblemReporter problemreporter, net.minecraft.core.HolderLookup.a holderlookup_a, net.minecraft.nbt.NBTTagCompound nbttagcompound) {
#require TagValueOutput static TagValueOutput tagValueOutputCtor:<init>(net.minecraft.util.ProblemReporter problemreporter, com.mojang.serialization.DynamicOps<net.minecraft.nbt.NBTBase> dynamicops, net.minecraft.nbt.NBTTagCompound nbttagcompound);
com.mojang.serialization.DynamicOps<net.minecraft.nbt.NBTBase> dynamicops = holderlookup_a.createSerializationContext(net.minecraft.nbt.DynamicOpsNBT.INSTANCE);
com.mojang.serialization.DynamicOps dynamicops = holderlookup_a.createSerializationContext(net.minecraft.nbt.DynamicOpsNBT.INSTANCE);
return #tagValueOutputCtor(problemreporter, dynamicops, nbttagcompound);
}
#require TagValueOutput public static ValueOutput.TypedOutputList createTagListValueOutput(net.minecraft.util.ProblemReporter problemreporter, net.minecraft.core.HolderLookup.a holderlookup_a, com.mojang.serialization.Codec codec, net.minecraft.nbt.NBTTagList nbttaglist) {
#require TagValueOutput.TypedListWrapper static TagValueInput.TypedListWrapper tagListOutputCtor:<init>(net.minecraft.util.ProblemReporter problemreporter, String s, com.mojang.serialization.DynamicOps<net.minecraft.nbt.NBTBase> dynamicops, com.mojang.serialization.Codec codec, net.minecraft.nbt.NBTTagList nbttaglist);
com.mojang.serialization.DynamicOps<net.minecraft.nbt.NBTBase> dynamicops = holderlookup_a.createSerializationContext(net.minecraft.nbt.DynamicOpsNBT.INSTANCE);
com.mojang.serialization.DynamicOps dynamicops = holderlookup_a.createSerializationContext(net.minecraft.nbt.DynamicOpsNBT.INSTANCE);
return (ValueOutput.TypedOutputList) #tagListOutputCtor(problemreporter, "", dynamicops, codec, nbttaglist);
}
@@ -251,6 +251,6 @@ import net.minecraft.world.level.storage.TagValueInput;
}
#require TagValueInput.TypedListWrapper static TagValueInput.TypedListWrapper tagListInputCtor:<init>(net.minecraft.util.ProblemReporter problemreporter, String s, net.minecraft.world.level.storage.ValueInputContextHelper context, com.mojang.serialization.Codec codec, net.minecraft.nbt.NBTTagList nbttaglist);
return (ValueInput.TypedInputList) #tagListInputCtor(problemreporter, "", context, codec, nbttaglist);
return (ValueInput$TypedInputList) #tagListInputCtor(problemreporter, "", context, codec, nbttaglist);
}
#endif
@@ -1983,7 +1983,7 @@ class Entity {
#if version >= 1.21.6
public void loadFromNBT((CommonTagCompound) NBTTagCompound compound) {
net.minecraft.util.ProblemReporter$ScopedCollector reporter = #createScopedProblemReporter();
com.bergerkiller.bukkit.common.internal.logic.ScopedProblemReporter reporter = #createScopedProblemReporter();
try {
ValueInput input = #createTagValueInput(reporter, instance.registryAccess(), compound);
instance.load(input);
@@ -2017,7 +2017,7 @@ class Entity {
#if version >= 1.21.6
public void saveToNBT((CommonTagCompound) NBTTagCompound compound) {
net.minecraft.util.ProblemReporter$ScopedCollector reporter = #createScopedProblemReporter();
com.bergerkiller.bukkit.common.internal.logic.ScopedProblemReporter reporter = #createScopedProblemReporter();
try {
ValueOutput output = #createTagValueOutput(reporter, instance.registryAccess(), compound);
instance.saveWithoutId(output);
@@ -9,7 +9,7 @@ class PlayerInventory extends IInventory {
#if version >= 1.21.6
public (CommonTagList) NBTTagList saveToNBT((CommonTagList) NBTTagList nbttaglist) {
net.minecraft.core.HolderLookup$a holderLookup = org.bukkit.craftbukkit.CraftRegistry.getMinecraftRegistry();
net.minecraft.util.ProblemReporter$ScopedCollector reporter = #createScopedProblemReporter();
com.bergerkiller.bukkit.common.internal.logic.ScopedProblemReporter reporter = #createScopedProblemReporter();
try {
net.minecraft.world.level.storage.ValueOutput$TypedOutputList valueList = #createTagListValueOutput(reporter, holderLookup, net.minecraft.world.ItemStackWithSlot.CODEC, nbttaglist);
instance.save(valueList);
@@ -19,7 +19,7 @@ class PlayerInventory extends IInventory {
}
public void loadFromNBT((CommonTagList) NBTTagList nbttaglist) {
net.minecraft.core.HolderLookup$a holderLookup = org.bukkit.craftbukkit.CraftRegistry.getMinecraftRegistry();
net.minecraft.util.ProblemReporter$ScopedCollector reporter = #createScopedProblemReporter();
com.bergerkiller.bukkit.common.internal.logic.ScopedProblemReporter reporter = #createScopedProblemReporter();
try {
net.minecraft.world.level.storage.ValueInput$TypedInputList valueList = #createTagListValueInput(reporter, holderLookup, net.minecraft.world.ItemStackWithSlot.CODEC, nbttaglist);
instance.load(valueList);
@@ -11,7 +11,7 @@ class FoodMetaData {
#if version >= 1.21.5
public void loadFromNBT((CommonTagCompound) NBTTagCompound compound) {
net.minecraft.core.HolderLookup$a holderLookup = org.bukkit.craftbukkit.CraftRegistry.getMinecraftRegistry();
net.minecraft.util.ProblemReporter$ScopedCollector reporter = #createScopedProblemReporter();
com.bergerkiller.bukkit.common.internal.logic.ScopedProblemReporter reporter = #createScopedProblemReporter();
try {
ValueInput input = #createTagValueInput(reporter, holderLookup, compound);
instance.readAdditionalSaveData(input);
@@ -21,7 +21,7 @@ class FoodMetaData {
}
public void saveToNBT((CommonTagCompound) NBTTagCompound compound) {
net.minecraft.core.HolderLookup$a holderLookup = org.bukkit.craftbukkit.CraftRegistry.getMinecraftRegistry();
net.minecraft.util.ProblemReporter$ScopedCollector reporter = #createScopedProblemReporter();
com.bergerkiller.bukkit.common.internal.logic.ScopedProblemReporter reporter = #createScopedProblemReporter();
try {
ValueOutput output = #createTagValueOutput(reporter, holderLookup, compound);
instance.addAdditionalSaveData(output);
@@ -20,7 +20,7 @@ class InventoryEnderChest extends IInventory {
net.minecraft.core.HolderLookup$a holderLookup = owner.registryAccess();
#if version >= 1.21.6
net.minecraft.util.ProblemReporter$ScopedCollector reporter = #createScopedProblemReporter();
com.bergerkiller.bukkit.common.internal.logic.ScopedProblemReporter reporter = #createScopedProblemReporter();
try {
net.minecraft.world.level.storage.ValueInput$TypedInputList valueList = #createTagListValueInput(reporter, holderLookup, net.minecraft.world.ItemStackWithSlot.CODEC, nbttaglist);
instance.fromSlots(valueList);
@@ -45,7 +45,7 @@ class InventoryEnderChest extends IInventory {
net.minecraft.core.HolderLookup$a holderLookup = owner.registryAccess();
#if version >= 1.21.6
net.minecraft.util.ProblemReporter$ScopedCollector reporter = #createScopedProblemReporter();
com.bergerkiller.bukkit.common.internal.logic.ScopedProblemReporter reporter = #createScopedProblemReporter();
try {
NBTTagList nbttaglist = new NBTTagList();
net.minecraft.world.level.storage.ValueOutput$TypedOutputList valueList = #createTagListValueOutput(reporter, holderLookup, net.minecraft.world.ItemStackWithSlot.CODEC, nbttaglist);
@@ -78,7 +78,7 @@ class TileEntity {
#if version >= 1.21.6
public void load((BlockData) IBlockData blockData, (CommonTagCompound) NBTTagCompound nbttagcompound) {
net.minecraft.util.ProblemReporter$ScopedCollector reporter = #createScopedProblemReporter();
com.bergerkiller.bukkit.common.internal.logic.ScopedProblemReporter reporter = #createScopedProblemReporter();
try {
ValueInput input = #createTagValueInput(reporter, instance.getLevel().registryAccess(), nbttagcompound);
instance.loadWithComponents(input);
@@ -29,7 +29,7 @@ class ValueInput {
#endif
}
public static (ValueInputHandle) ValueInput forNBTOnWorld((Object) ProblemReporter problemReporter, (org.bukkit.World) net.minecraft.world.level.World world, (CommonTagCompound) NBTTagCompound nbttagcompound) {
public static (ValueInputHandle) ValueInput forNBTOnWorld((Object) ProblemReporter problemreporter, (org.bukkit.World) net.minecraft.world.level.World world, (CommonTagCompound) NBTTagCompound nbttagcompound) {
#if version >= 1.21.6
return TagValueInput.create(problemreporter, world.registryAccess(), nbttagcompound);
#else
@@ -37,7 +37,7 @@ class ValueInput {
#endif
}
public static (ValueInputHandle) ValueInput forNBT((Object) ProblemReporter problemReporter, (Object) HolderLookup.a holderLookup, (CommonTagCompound) NBTTagCompound nbttagcompound) {
public static (ValueInputHandle) ValueInput forNBT((Object) ProblemReporter problemreporter, (Object) HolderLookup.a holderLookup, (CommonTagCompound) NBTTagCompound nbttagcompound) {
#if version >= 1.21.6
return TagValueInput.create(problemreporter, holderLookup, nbttagcompound);
#else
@@ -5,7 +5,9 @@ import static org.junit.Assert.*;
import java.lang.reflect.Modifier;
import java.util.Set;
import com.bergerkiller.bukkit.common.internal.CommonBootstrap;
import com.bergerkiller.bukkit.common.internal.hooks.AdvancementDataPlayerHook;
import com.bergerkiller.bukkit.common.internal.logic.ScopedProblemReporterInit;
import com.bergerkiller.bukkit.common.wrappers.InteractionResult;
import com.bergerkiller.bukkit.common.wrappers.RelativeFlags;
import org.junit.Assert;
@@ -89,6 +91,20 @@ public class InternalLogicInitializeTest {
EntityMoveHandler.assertInitialized();
}
@Test
public void testScopedProblemReporter() {
if (!CommonBootstrap.evaluateMCVersion(">=", "1.21.6")) {
return;
}
ScopedProblemReporterInit.initialize();
try {
Resolver.getClassByExactName(ScopedProblemReporterInit.CLASS_NAME);
} catch (Throwable t) {
fail("Scoped problem reporter not initialized");
}
}
@Test
public void testNullPacketDataSerializer() {
NullPacketDataSerializerInit.initialize();