--- ../src-base/minecraft/net/minecraft/world/storage/SaveHandler.java +++ ../src-work/minecraft/net/minecraft/world/storage/SaveHandler.java @@ -21,6 +21,13 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +// CraftBukkit start +import java.util.UUID; + +import org.bukkit.craftbukkit.entity.CraftPlayer; +// CraftBukkit end +import cpw.mods.fml.common.registry.GameData; // Cauldron + public class SaveHandler implements ISaveHandler, IPlayerFileData { private static final Logger logger = LogManager.getLogger(); @@ -29,6 +36,8 @@ private final File mapDataDir; private final long initializationTime = MinecraftServer.getSystemTimeMillis(); private final String saveDirectoryName; + private UUID uuid = null; // CraftBukkit + private static boolean initializedBukkit = false; // Cauldron private static final String __OBFID = "CL_00000585"; public SaveHandler(File p_i2146_1_, String p_i2146_2_, boolean p_i2146_3_) @@ -67,7 +76,7 @@ catch (IOException ioexception) { ioexception.printStackTrace(); - throw new RuntimeException("Failed to check session lock, aborting"); + throw new RuntimeException("Failed to check session lock for world " + this.worldDirectory + ", aborting"); // Cauldron } } @@ -87,7 +96,7 @@ { if (datainputstream.readLong() != this.initializationTime) { - throw new MinecraftException("The save is being accessed from another location, aborting"); + throw new MinecraftException("The save folder for world " + this.worldDirectory + " is being accessed from another location, aborting"); // Cauldron } } finally @@ -97,7 +106,10 @@ } catch (IOException ioexception) { - throw new MinecraftException("Failed to check session lock, aborting"); + // Cauldron start + ioexception.printStackTrace(); + throw new MinecraftException("Failed to check session lock for world " + this.worldDirectory + ", aborting"); + // Cauldron end } } @@ -122,6 +134,7 @@ nbttagcompound1 = nbttagcompound.getCompoundTag("Data"); worldInfo = new WorldInfo(nbttagcompound1); FMLCommonHandler.instance().handleWorldDataLoad(this, worldInfo, nbttagcompound); + this.initBukkitData(worldInfo); // Cauldron return worldInfo; } catch (StartupQuery.AbortedException e) @@ -145,6 +158,7 @@ nbttagcompound1 = nbttagcompound.getCompoundTag("Data"); worldInfo = new WorldInfo(nbttagcompound1); FMLCommonHandler.instance().handleWorldDataLoad(this, worldInfo, nbttagcompound); + this.initBukkitData(worldInfo); // Cauldron return worldInfo; } catch (StartupQuery.AbortedException e) @@ -157,6 +171,7 @@ } } + this.initBukkitData(worldInfo); // Cauldron return null; } @@ -284,6 +299,18 @@ if (nbttagcompound != null) { + // CraftBukkit start + if (p_75752_1_ instanceof EntityPlayerMP) + { + CraftPlayer player = (CraftPlayer) p_75752_1_.getBukkitEntity(); // Cauldron + // Only update first played if it is older than the one we have + long modified = new File(playersDirectory, p_75752_1_.getCommandSenderName() + ".dat").lastModified(); + if (modified < player.getFirstPlayed()) + { + player.setFirstPlayed(modified); + } + } + // CraftBukkit end p_75752_1_.readFromNBT(nbttagcompound); } @@ -291,6 +318,27 @@ return nbttagcompound; } + // CraftBukkit start + public NBTTagCompound getPlayerData(String par1Str) + { + try + { + File file1 = new File(this.playersDirectory, par1Str + ".dat"); + + if (file1.exists()) + { + return CompressedStreamTools.readCompressed(new FileInputStream(file1)); + } + } + catch (Exception exception) + { + logger.warn("Failed to load player data for " + par1Str); + } + + return null; + } + // CraftBukkit end + public IPlayerFileData getSaveHandler() { return this; @@ -323,6 +371,100 @@ return this.saveDirectoryName; } + // CraftBukkit start + public UUID getUUID() + { + if (uuid != null) + { + return uuid; + } + + File file1 = new File(this.worldDirectory, "uid.dat"); + + if (file1.exists()) + { + DataInputStream dis = null; + + try + { + dis = new DataInputStream(new FileInputStream(file1)); + return uuid = new UUID(dis.readLong(), dis.readLong()); + } + catch (IOException ex) + { + logger.warn("Failed to read " + file1 + ", generating new random UUID", ex); + } + finally + { + if (dis != null) + { + try + { + dis.close(); + } + catch (IOException ex) + { + // NOOP + } + } + } + } + + uuid = UUID.randomUUID(); + DataOutputStream dos = null; + + try + { + dos = new DataOutputStream(new FileOutputStream(file1)); + dos.writeLong(uuid.getMostSignificantBits()); + dos.writeLong(uuid.getLeastSignificantBits()); + } + catch (IOException ex) + { + logger.warn("Failed to write " + file1, ex); + } + finally + { + if (dos != null) + { + try + { + dos.close(); + } + catch (IOException ex) + { + // NOOP + } + } + } + + return uuid; + } + + public File getPlayerDir() + { + return playersDirectory; + } + + // CraftBukkit end + + // Cauldron start + public void initBukkitData(WorldInfo worldInfo) + { + // inject bukkit materials before plugins load + if (!this.initializedBukkit && (worldInfo == null || worldInfo.getDimension() == 0)) + { + GameData.injectBlockBukkitMaterials(); + GameData.injectItemBukkitMaterials(); + // since we modify bukkit enums, we need to guarantee that plugins are + // loaded after all mods have been loaded by FML to avoid race conditions. + MinecraftServer.getServer().server.loadPlugins(); + MinecraftServer.getServer().server.enablePlugins(org.bukkit.plugin.PluginLoadOrder.STARTUP); + this.initializedBukkit = true; + } + } + // Cauldron end + public NBTTagCompound getPlayerNBT(EntityPlayerMP player) { try