From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Zach Brown <zach.brown@destroystokyo.com>
Date: Sat, 22 Sep 2018 15:56:59 -0400
Subject: [PATCH] Catch JsonParseException in Entity and TE names

As a result, data that no longer parses correctly will not crash the server
instead just logging the exception and continuing (and in most cases should
fix the data)

Player data is fixed pretty much immediately but some block data (like
Shulkers) may need to be changed in order for it to re-save properly

No more crashing though.

diff --git a/src/main/java/net/minecraft/server/MCUtil.java b/src/main/java/net/minecraft/server/MCUtil.java
index ccdee183f02ab55723e16f41efce55dc51e96297..162aa7718488a74980843944e0d026ccfd5a65a5 100644
--- a/src/main/java/net/minecraft/server/MCUtil.java
+++ b/src/main/java/net/minecraft/server/MCUtil.java
@@ -7,6 +7,8 @@ import it.unimi.dsi.fastutil.objects.ObjectRBTreeSet;
 import java.lang.ref.Cleaner;
 import net.minecraft.core.BlockPos;
 import net.minecraft.core.Direction;
+import net.minecraft.nbt.CompoundTag;
+import net.minecraft.network.chat.Component;
 import net.minecraft.server.level.ServerLevel;
 import net.minecraft.world.entity.Entity;
 import net.minecraft.world.level.ChunkPos;
@@ -524,6 +526,21 @@ public final class MCUtil {
         }
     }
 
+    @Nullable
+    public static Component getBaseComponentFromNbt(String key, CompoundTag compound) {
+        if (!compound.contains(key)) {
+            return null;
+        }
+        String string = compound.getString(key);
+        try {
+            return Component.Serializer.fromJson(string);
+        } catch (com.google.gson.JsonParseException e) {
+            org.bukkit.Bukkit.getLogger().warning("Unable to parse " + key + " from " + compound +": " + e.getMessage());
+        }
+
+        return null;
+    }
+
     public static int getTicketLevelFor(net.minecraft.world.level.chunk.ChunkStatus status) {
         return net.minecraft.server.level.ChunkMap.MAX_VIEW_DISTANCE + net.minecraft.world.level.chunk.ChunkStatus.getDistance(status);
     }
diff --git a/src/main/java/net/minecraft/world/level/BaseCommandBlock.java b/src/main/java/net/minecraft/world/level/BaseCommandBlock.java
index 04a3627667498b841fbff547d1874d99cc708af4..5b125aa77e769983a0aee7c5f6eb6a8a146fead0 100644
--- a/src/main/java/net/minecraft/world/level/BaseCommandBlock.java
+++ b/src/main/java/net/minecraft/world/level/BaseCommandBlock.java
@@ -73,7 +73,7 @@ public abstract class BaseCommandBlock implements CommandSource {
         this.command = nbt.getString("Command");
         this.successCount = nbt.getInt("SuccessCount");
         if (nbt.contains("CustomName", 8)) {
-            this.setName(Component.Serializer.fromJson(nbt.getString("CustomName")));
+            this.setName(net.minecraft.server.MCUtil.getBaseComponentFromNbt("CustomName", nbt)); // Paper - Catch ParseException
         }
 
         if (nbt.contains("TrackOutput", 1)) {
diff --git a/src/main/java/net/minecraft/world/level/block/entity/BannerBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BannerBlockEntity.java
index 0de9d86d5e2f0a9043640e3154c11612408e24d8..d58f3beabbdb48cbb36bd4802d12cda41628731f 100644
--- a/src/main/java/net/minecraft/world/level/block/entity/BannerBlockEntity.java
+++ b/src/main/java/net/minecraft/world/level/block/entity/BannerBlockEntity.java
@@ -97,7 +97,7 @@ public class BannerBlockEntity extends BlockEntity implements Nameable {
     public void load(CompoundTag nbt) {
         super.load(nbt);
         if (nbt.contains("CustomName", 8)) {
-            this.name = Component.Serializer.fromJson(nbt.getString("CustomName"));
+            this.name = net.minecraft.server.MCUtil.getBaseComponentFromNbt("CustomName", nbt); // Paper - Catch ParseException
         }
 
         this.itemPatterns = nbt.getList("Patterns", 10);
diff --git a/src/main/java/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java
index cfd1e2fbc029d928daa2d9f12df393c8cf30e850..72c4c367b3531b21f1f28601735a5250069b8713 100644
--- a/src/main/java/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java
+++ b/src/main/java/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java
@@ -31,7 +31,7 @@ public abstract class BaseContainerBlockEntity extends BlockEntity implements Co
         super.load(nbt);
         this.lockKey = LockCode.fromTag(nbt);
         if (nbt.contains("CustomName", 8)) {
-            this.name = Component.Serializer.fromJson(nbt.getString("CustomName"));
+            this.name = net.minecraft.server.MCUtil.getBaseComponentFromNbt("CustomName", nbt); // Paper - Catch ParseException
         }
 
     }
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 dca94c75f4531eab3ab788e722363d2065bf4170..4b7da0df927f669845c7d4c9b4a0acfab8efe657 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
@@ -359,7 +359,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 = Component.Serializer.fromJson(nbt.getString("CustomName"));
+            this.name = net.minecraft.server.MCUtil.getBaseComponentFromNbt("CustomName", nbt); // Paper - Catch ParseException
         }
 
         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 d399d9ea7656d1c96f3b7547049d2e133ef5e847..1eccf9424bd8a4bcbeed4ebb1795fd113fe5af18 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
@@ -43,7 +43,7 @@ public class EnchantmentTableBlockEntity extends BlockEntity implements Nameable
     public void load(CompoundTag nbt) {
         super.load(nbt);
         if (nbt.contains("CustomName", 8)) {
-            this.name = Component.Serializer.fromJson(nbt.getString("CustomName"));
+            this.name = net.minecraft.server.MCUtil.getBaseComponentFromNbt("CustomName", nbt); // Paper - Catch ParseException
         }
 
     }
