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/CommandBlockListenerAbstract.java b/src/main/java/net/minecraft/server/CommandBlockListenerAbstract.java
index 786712297435fed5247abd577efd092bcb9c44cb..ef2a496eda45ae5ee8fe52ef09e77c2906069d2e 100644
--- a/src/main/java/net/minecraft/server/CommandBlockListenerAbstract.java
+++ b/src/main/java/net/minecraft/server/CommandBlockListenerAbstract.java
@@ -59,7 +59,7 @@ public abstract class CommandBlockListenerAbstract implements ICommandListener {
         this.command = nbttagcompound.getString("Command");
         this.successCount = nbttagcompound.getInt("SuccessCount");
         if (nbttagcompound.hasKeyOfType("CustomName", 8)) {
-            this.setName(IChatBaseComponent.ChatSerializer.a(nbttagcompound.getString("CustomName")));
+            this.setName(MCUtil.getBaseComponentFromNbt("CustomName", nbttagcompound)); // Paper - Catch ParseException
         }
 
         if (nbttagcompound.hasKeyOfType("TrackOutput", 1)) {
diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java
index 0f74ec89b3e85c918c95f9d8fef6d68403ed1107..4609e402b419ed21e17ad34d02dca55b47c1c95e 100644
--- a/src/main/java/net/minecraft/server/Entity.java
+++ b/src/main/java/net/minecraft/server/Entity.java
@@ -1680,7 +1680,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
                     this.Z();
                     this.setYawPitch(this.yaw, this.pitch);
                     if (nbttagcompound.hasKeyOfType("CustomName", 8)) {
-                        this.setCustomName(IChatBaseComponent.ChatSerializer.a(nbttagcompound.getString("CustomName")));
+                        this.setCustomName(MCUtil.getBaseComponentFromNbt("CustomName", nbttagcompound)); // Paper - Catch ParseException
                     }
 
                     this.setCustomNameVisible(nbttagcompound.getBoolean("CustomNameVisible"));
diff --git a/src/main/java/net/minecraft/server/MCUtil.java b/src/main/java/net/minecraft/server/MCUtil.java
index 8ca1a4719d934db31d57b34cf7050acc5a1a7048..206d04dcce1d7d074cf7151a083bdc626b0b8e07 100644
--- a/src/main/java/net/minecraft/server/MCUtil.java
+++ b/src/main/java/net/minecraft/server/MCUtil.java
@@ -510,4 +510,19 @@ public final class MCUtil {
                 return null;
         }
     }
+
+    @Nullable
+    public static IChatBaseComponent getBaseComponentFromNbt(String key, NBTTagCompound compound) {
+        if (!compound.hasKey(key)) {
+            return null;
+        }
+        String string = compound.getString(key);
+        try {
+            return IChatBaseComponent.ChatSerializer.jsonToComponent(string);
+        } catch (com.google.gson.JsonParseException e) {
+            org.bukkit.Bukkit.getLogger().warning("Unable to parse " + key + " from " + compound +": " + e.getMessage());
+        }
+
+        return null;
+    }
 }
diff --git a/src/main/java/net/minecraft/server/TileEntityBanner.java b/src/main/java/net/minecraft/server/TileEntityBanner.java
index 93911a825154d04dd3f1495b1bab5a3ab2aea30b..d35604edb21441032bce87d658b76b39fea917fc 100644
--- a/src/main/java/net/minecraft/server/TileEntityBanner.java
+++ b/src/main/java/net/minecraft/server/TileEntityBanner.java
@@ -60,7 +60,7 @@ public class TileEntityBanner extends TileEntity implements INamableTileEntity {
     public void load(NBTTagCompound nbttagcompound) {
         super.load(nbttagcompound);
         if (nbttagcompound.hasKeyOfType("CustomName", 8)) {
-            this.a = IChatBaseComponent.ChatSerializer.a(nbttagcompound.getString("CustomName"));
+            this.a = MCUtil.getBaseComponentFromNbt("CustomName", nbttagcompound); // Paper - Catch ParseException
         }
 
         if (this.hasWorld()) {
diff --git a/src/main/java/net/minecraft/server/TileEntityContainer.java b/src/main/java/net/minecraft/server/TileEntityContainer.java
index 473ec2cbde5b31398f57bf9ab7034139572fa666..ab6b86e4e9f99a60140187c06480cf511327a710 100644
--- a/src/main/java/net/minecraft/server/TileEntityContainer.java
+++ b/src/main/java/net/minecraft/server/TileEntityContainer.java
@@ -17,7 +17,7 @@ public abstract class TileEntityContainer extends TileEntity implements IInvento
         super.load(nbttagcompound);
         this.chestLock = ChestLock.b(nbttagcompound);
         if (nbttagcompound.hasKeyOfType("CustomName", 8)) {
-            this.customName = IChatBaseComponent.ChatSerializer.a(nbttagcompound.getString("CustomName"));
+            this.customName = MCUtil.getBaseComponentFromNbt("CustomName", nbttagcompound); // Paper - Catch ParseException
         }
 
     }
