Path: blob/main/sp-server/src_aux/SaveHandler.java
8641 views
package net.minecraft.src;12import java.io.DataInputStream;3import java.io.DataOutputStream;4import java.io.File;5import java.io.FileInputStream;6import java.io.FileOutputStream;7import java.io.IOException;8import net.minecraft.server.MinecraftServer;910public class SaveHandler implements ISaveHandler, IPlayerFileData {11/** The directory in which to save world data. */12private final File worldDirectory;1314/** The directory in which to save player data. */15private final File playersDirectory;16private final File mapDataDir;1718/**19* The time in milliseconds when this field was initialized. Stored in the20* session lock file.21*/22private final long initializationTime = System.currentTimeMillis();2324/** The directory name of the world */25private final String saveDirectoryName;2627public SaveHandler(File par1File, String par2Str, boolean par3) {28this.worldDirectory = new File(par1File, par2Str);29this.worldDirectory.mkdirs();30this.playersDirectory = new File(this.worldDirectory, "players");31this.mapDataDir = new File(this.worldDirectory, "data");32this.mapDataDir.mkdirs();33this.saveDirectoryName = par2Str;3435if (par3) {36this.playersDirectory.mkdirs();37}3839this.setSessionLock();40}4142/**43* Creates a session lock file for this process44*/45private void setSessionLock() {46try {47File var1 = new File(this.worldDirectory, "session.lock");48DataOutputStream var2 = new DataOutputStream(new FileOutputStream(var1));4950try {51var2.writeLong(this.initializationTime);52} finally {53var2.close();54}55} catch (IOException var7) {56var7.printStackTrace();57throw new RuntimeException("Failed to check session lock, aborting");58}59}6061/**62* Gets the File object corresponding to the base directory of this world.63*/64protected File getWorldDirectory() {65return this.worldDirectory;66}6768/**69* Checks the session lock to prevent save collisions70*/71public void checkSessionLock() throws MinecraftException {72try {73File var1 = new File(this.worldDirectory, "session.lock");74DataInputStream var2 = new DataInputStream(new FileInputStream(var1));7576try {77if (var2.readLong() != this.initializationTime) {78throw new MinecraftException("The save is being accessed from another location, aborting");79}80} finally {81var2.close();82}83} catch (IOException var7) {84throw new MinecraftException("Failed to check session lock, aborting");85}86}8788/**89* initializes and returns the chunk loader for the specified world provider90*/91public IChunkLoader getChunkLoader(WorldProvider par1WorldProvider) {92throw new RuntimeException("Old Chunk Storage is no longer supported.");93}9495/**96* Loads and returns the world info97*/98public WorldInfo loadWorldInfo() {99File var1 = new File(this.worldDirectory, "level.dat");100NBTTagCompound var2;101NBTTagCompound var3;102103if (var1.exists()) {104try {105var2 = CompressedStreamTools.readCompressed(new FileInputStream(var1));106var3 = var2.getCompoundTag("Data");107return new WorldInfo(var3);108} catch (Exception var5) {109var5.printStackTrace();110}111}112113var1 = new File(this.worldDirectory, "level.dat_old");114115if (var1.exists()) {116try {117var2 = CompressedStreamTools.readCompressed(new FileInputStream(var1));118var3 = var2.getCompoundTag("Data");119return new WorldInfo(var3);120} catch (Exception var4) {121var4.printStackTrace();122}123}124125return null;126}127128/**129* Saves the given World Info with the given NBTTagCompound as the Player.130*/131public void saveWorldInfoWithPlayer(WorldInfo par1WorldInfo, NBTTagCompound par2NBTTagCompound) {132NBTTagCompound var3 = par1WorldInfo.cloneNBTCompound(par2NBTTagCompound);133NBTTagCompound var4 = new NBTTagCompound();134var4.setTag("Data", var3);135136try {137File var5 = new File(this.worldDirectory, "level.dat_new");138File var6 = new File(this.worldDirectory, "level.dat_old");139File var7 = new File(this.worldDirectory, "level.dat");140CompressedStreamTools.writeCompressed(var4, new FileOutputStream(var5));141142if (var6.exists()) {143var6.delete();144}145146var7.renameTo(var6);147148if (var7.exists()) {149var7.delete();150}151152var5.renameTo(var7);153154if (var5.exists()) {155var5.delete();156}157} catch (Exception var8) {158var8.printStackTrace();159}160}161162/**163* used to update level.dat from old format to MCRegion format164*/165public void saveWorldInfo(WorldInfo par1WorldInfo) {166NBTTagCompound var2 = par1WorldInfo.getNBTTagCompound();167NBTTagCompound var3 = new NBTTagCompound();168var3.setTag("Data", var2);169170try {171File var4 = new File(this.worldDirectory, "level.dat_new");172File var5 = new File(this.worldDirectory, "level.dat_old");173File var6 = new File(this.worldDirectory, "level.dat");174CompressedStreamTools.writeCompressed(var3, new FileOutputStream(var4));175176if (var5.exists()) {177var5.delete();178}179180var6.renameTo(var5);181182if (var6.exists()) {183var6.delete();184}185186var4.renameTo(var6);187188if (var4.exists()) {189var4.delete();190}191} catch (Exception var7) {192var7.printStackTrace();193}194}195196/**197* Writes the player data to disk from the specified PlayerEntityMP.198*/199public void writePlayerData(EntityPlayer par1EntityPlayer) {200try {201NBTTagCompound var2 = new NBTTagCompound();202par1EntityPlayer.writeToNBT(var2);203File var3 = new File(this.playersDirectory, par1EntityPlayer.username + ".dat.tmp");204File var4 = new File(this.playersDirectory, par1EntityPlayer.username + ".dat");205CompressedStreamTools.writeCompressed(var2, new FileOutputStream(var3));206207if (var4.exists()) {208var4.delete();209}210211var3.renameTo(var4);212} catch (Exception var5) {213MinecraftServer.getServer().getLogAgent()214.func_98236_b("Failed to save player data for " + par1EntityPlayer.username);215}216}217218/**219* Reads the player data from disk into the specified PlayerEntityMP.220*/221public NBTTagCompound readPlayerData(EntityPlayer par1EntityPlayer) {222NBTTagCompound var2 = this.getPlayerData(par1EntityPlayer.username);223224if (var2 != null) {225par1EntityPlayer.readFromNBT(var2);226}227228return var2;229}230231/**232* Gets the player data for the given playername as a NBTTagCompound.233*/234public NBTTagCompound getPlayerData(String par1Str) {235try {236File var2 = new File(this.playersDirectory, par1Str + ".dat");237238if (var2.exists()) {239return CompressedStreamTools.readCompressed(new FileInputStream(var2));240}241} catch (Exception var3) {242MinecraftServer.getServer().getLogAgent().func_98236_b("Failed to load player data for " + par1Str);243}244245return null;246}247248public IPlayerFileData getPlayerNBTManager() {249return this;250}251252/**253* Returns an array of usernames for which player.dat exists for.254*/255public String[] getAvailablePlayerDat() {256String[] var1 = this.playersDirectory.list();257258for (int var2 = 0; var2 < var1.length; ++var2) {259if (var1[var2].endsWith(".dat")) {260var1[var2] = var1[var2].substring(0, var1[var2].length() - 4);261}262}263264return var1;265}266267/**268* Called to flush all changes to disk, waiting for them to complete.269*/270public void flush() {271}272273/**274* Gets the file location of the given map275*/276public File getMapFileFromName(String par1Str) {277return new File(this.mapDataDir, par1Str + ".dat");278}279280/**281* Returns the name of the directory where world information is saved.282*/283public String getWorldDirectoryName() {284return this.saveDirectoryName;285}286}287288289