From 240f4d59799fbc801df981f49420cf9b5a9b563f 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 698cfb918b..fbdb2df27d 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java
@@ -27,12 +27,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
 
     }
 
@@ -169,8 +169,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() {
@@ -187,7 +202,7 @@ public class CraftOfflinePlayer implements OfflinePlayer, ConfigurationSerializa
     }
 
     private File getDataFile() {
-        return new File(storage.getPlayerDir(), getUniqueId() + ".dat");
+        return new File(getStorageLazy().getPlayerDir(), getUniqueId() + ".dat");
     }
 
     public long getFirstPlayed() {
-- 
2.21.0