From a7a6c01c51b445954e0449f83db2a55de7075b35 Mon Sep 17 00:00:00 2001
From: Zach Brown <zach@zachbr.io>
Date: Tue, 11 Dec 2018 22:25:07 -0500
Subject: [PATCH] Lazy init world storage in CraftOfflinePlayer

Allows access to some offline player properties even when there are no
worlds loaded. This is typically a rare occurrence but probably one that
should be covered as best we can.

diff --git a/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java b/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java
index 58e10381c8..0e8a21b803 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java
@@ -29,12 +29,12 @@ import org.bukkit.plugin.Plugin;
 public class CraftOfflinePlayer implements OfflinePlayer, ConfigurationSerializable {
     private final GameProfile profile;
     private final CraftServer server;
-    private final WorldNBTStorage storage;
+    private WorldNBTStorage storage; // Paper - lazy init
 
     protected CraftOfflinePlayer(CraftServer server, GameProfile profile) {
         this.server = server;
         this.profile = profile;
-        this.storage = (WorldNBTStorage) (server.console.getWorldServer(DimensionManager.OVERWORLD).getDataManager());
+        //this.storage = (WorldNBTStorage) (server.console.getWorldServer(DimensionManager.OVERWORLD).getDataManager()); // Paper - lazy init
 
     }
 
@@ -181,8 +181,23 @@ public class CraftOfflinePlayer implements OfflinePlayer, ConfigurationSerializa
         return hash;
     }
 
+    // Paper - lazy
+    private WorldNBTStorage getStorageLazy() {
+        if (this.storage == null) {
+            net.minecraft.server.WorldServer worldServer = server.console.getWorldServer(DimensionManager.OVERWORLD);
+            if (worldServer == null) {
+                throw new IllegalStateException("Cannot get world storage when there are no worlds loaded!");
+            } else {
+                this.storage = (WorldNBTStorage) worldServer.getDataManager();
+            }
+        }
+
+        return this.storage;
+    }
+    // Paper end
+
     private NBTTagCompound getData() {
-        return storage.getPlayerData(getUniqueId().toString());
+        return getStorageLazy().getPlayerData(getUniqueId().toString());
     }
 
     private NBTTagCompound getBukkitData() {
@@ -199,7 +214,7 @@ public class CraftOfflinePlayer implements OfflinePlayer, ConfigurationSerializa
     }
 
     private File getDataFile() {
-        return new File(storage.getPlayerDir(), getUniqueId() + ".dat");
+        return new File(getStorageLazy().getPlayerDir(), getUniqueId() + ".dat");
     }
 
     @Override
-- 
2.26.2