diff --git a/patches/server/0881-Add-debug-for-invalid-GameProfiles-on-skull-blocks-i.patch b/patches/server/0881-Add-debug-for-invalid-GameProfiles-on-skull-blocks-i.patch new file mode 100644 index 0000000000..78f9466f9f --- /dev/null +++ b/patches/server/0881-Add-debug-for-invalid-GameProfiles-on-skull-blocks-i.patch @@ -0,0 +1,63 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Jason Penilla <11360596+jpenilla@users.noreply.github.com> +Date: Sat, 26 Feb 2022 13:27:31 -0700 +Subject: [PATCH] Add debug for invalid GameProfiles on skull blocks/items + +Improves the error message for placed in world skull blocks by default, +also adds 'Paper.debugInvalidSkullProfiles' system property which can be +set to 'true' for extra debug info (trace of updateGameprofile caller). + +diff --git a/src/main/java/net/minecraft/world/level/block/entity/SkullBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/SkullBlockEntity.java +index 118472b83a21a250f398c088c91ac4560c19c749..5840cf6d22029cf1599ae9460b4498d5c8c5ae7d 100644 +--- a/src/main/java/net/minecraft/world/level/block/entity/SkullBlockEntity.java ++++ b/src/main/java/net/minecraft/world/level/block/entity/SkullBlockEntity.java +@@ -142,13 +142,28 @@ public class SkullBlockEntity extends BlockEntity { + updateGameprofile(this.owner, (owner) -> { + this.owner = owner; + this.setChanged(); ++ // Paper start ++ }, () -> { ++ final @Nullable Level level = this.getLevel(); ++ return "SkullBlockEntity at " + this.getBlockPos() + (level == null ? "" : (" in level: " + level.dimension().location())); ++ // Paper end + }); + } + + public static void updateGameprofile(@Nullable GameProfile owner, Consumer callback) { ++ // Paper start ++ updateGameprofile(owner, callback, null); ++ } ++ ++ private static final boolean DEBUG_INVALID_SKULL_PROFILES = Boolean.getBoolean("Paper.debugInvalidSkullProfiles"); ++ ++ public static void updateGameprofile(@Nullable GameProfile owner, Consumer callback, final @Nullable java.util.function.Supplier debugInfo) { + if (owner != null && !StringUtil.isNullOrEmpty(owner.getName()) && (!owner.isComplete() || !owner.getProperties().containsKey("textures")) && profileCache != null && sessionService != null) { ++ final @Nullable Throwable trace = DEBUG_INVALID_SKULL_PROFILES ? new Throwable("updateGameprofile caller debug trace") : null; + profileCache.getAsync(owner.getName(), (profile) -> { + Util.PROFILE_EXECUTOR.execute(() -> { // Paper - not a good idea to use BLOCKING OPERATIONS on the worldgen executor ++ try { ++ // Paper end + Util.ifElse(profile, (profilex) -> { + Property property = Iterables.getFirst(profilex.getProperties().get("textures"), (Property)null); + if (property == null) { +@@ -165,6 +180,20 @@ public class SkullBlockEntity extends BlockEntity { + callback.accept(owner); + }); + }); ++ // Paper start ++ } catch (final Exception ex) { ++ if (trace != null) { ++ ex.addSuppressed(trace); ++ } ++ final String ownerMessage = "Original profile: '" + owner + "'"; ++ final String debugMessage = " Run with -DPaper.debugInvalidSkullProfiles=true for further debug information."; ++ final String message = ownerMessage + (trace == null ? debugMessage : ""); ++ if (debugInfo == null) { ++ throw new RuntimeException(message, ex); ++ } ++ throw new RuntimeException(debugInfo.get() + " " + message, ex); ++ } ++ // Paper end + }); + }); + } else {