mirror of
https://git.zelz.net/catfoolyou/Project164.git
synced 2025-12-14 08:47:40 +00:00
Fixed server crash
This commit is contained in:
@@ -1,371 +0,0 @@
|
||||
package net.minecraft.src;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class AnvilChunkLoader implements IChunkLoader, IThreadedFileIO {
|
||||
private List chunksToRemove = new ArrayList();
|
||||
private Set pendingAnvilChunksCoordinates = new HashSet();
|
||||
private Object syncLockObject = new Object();
|
||||
|
||||
/** Save directory for chunks using the Anvil format */
|
||||
private final File chunkSaveLocation;
|
||||
|
||||
public AnvilChunkLoader(File par1File) {
|
||||
this.chunkSaveLocation = par1File;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the specified(XZ) chunk into the specified world.
|
||||
*/
|
||||
public Chunk loadChunk(World par1World, int par2, int par3) throws IOException {
|
||||
NBTTagCompound var4 = null;
|
||||
ChunkCoordIntPair var5 = new ChunkCoordIntPair(par2, par3);
|
||||
Object var6 = this.syncLockObject;
|
||||
|
||||
synchronized (this.syncLockObject) {
|
||||
if (this.pendingAnvilChunksCoordinates.contains(var5)) {
|
||||
for (int var7 = 0; var7 < this.chunksToRemove.size(); ++var7) {
|
||||
if (((AnvilChunkLoaderPending) this.chunksToRemove.get(var7)).chunkCoordinate.equals(var5)) {
|
||||
var4 = ((AnvilChunkLoaderPending) this.chunksToRemove.get(var7)).nbtTags;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (var4 == null) {
|
||||
DataInputStream var10 = RegionFileCache.getChunkInputStream(this.chunkSaveLocation, par2, par3);
|
||||
|
||||
if (var10 == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var4 = CompressedStreamTools.read(var10);
|
||||
}
|
||||
|
||||
return this.checkedReadChunkFromNBT(par1World, par2, par3, var4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps readChunkFromNBT. Checks the coordinates and several NBT tags.
|
||||
*/
|
||||
protected Chunk checkedReadChunkFromNBT(World par1World, int par2, int par3, NBTTagCompound par4NBTTagCompound) {
|
||||
if (!par4NBTTagCompound.hasKey("Level")) {
|
||||
par1World.getWorldLogAgent()
|
||||
.logSevere("Chunk file at " + par2 + "," + par3 + " is missing level data, skipping");
|
||||
return null;
|
||||
} else if (!par4NBTTagCompound.getCompoundTag("Level").hasKey("Sections")) {
|
||||
par1World.getWorldLogAgent()
|
||||
.logSevere("Chunk file at " + par2 + "," + par3 + " is missing block data, skipping");
|
||||
return null;
|
||||
} else {
|
||||
Chunk var5 = this.readChunkFromNBT(par1World, par4NBTTagCompound.getCompoundTag("Level"));
|
||||
|
||||
if (!var5.isAtLocation(par2, par3)) {
|
||||
par1World.getWorldLogAgent()
|
||||
.logSevere("Chunk file at " + par2 + "," + par3
|
||||
+ " is in the wrong location; relocating. (Expected " + par2 + ", " + par3 + ", got "
|
||||
+ var5.xPosition + ", " + var5.zPosition + ")");
|
||||
par4NBTTagCompound.setInteger("xPos", par2);
|
||||
par4NBTTagCompound.setInteger("zPos", par3);
|
||||
var5 = this.readChunkFromNBT(par1World, par4NBTTagCompound.getCompoundTag("Level"));
|
||||
}
|
||||
|
||||
return var5;
|
||||
}
|
||||
}
|
||||
|
||||
public void saveChunk(World par1World, Chunk par2Chunk) throws MinecraftException, IOException {
|
||||
par1World.checkSessionLock();
|
||||
|
||||
try {
|
||||
NBTTagCompound var3 = new NBTTagCompound();
|
||||
NBTTagCompound var4 = new NBTTagCompound();
|
||||
var3.setTag("Level", var4);
|
||||
this.writeChunkToNBT(par2Chunk, par1World, var4);
|
||||
this.addChunkToPending(par2Chunk.getChunkCoordIntPair(), var3);
|
||||
} catch (Exception var5) {
|
||||
var5.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
protected void addChunkToPending(ChunkCoordIntPair par1ChunkCoordIntPair, NBTTagCompound par2NBTTagCompound) {
|
||||
Object var3 = this.syncLockObject;
|
||||
|
||||
synchronized (this.syncLockObject) {
|
||||
if (this.pendingAnvilChunksCoordinates.contains(par1ChunkCoordIntPair)) {
|
||||
for (int var4 = 0; var4 < this.chunksToRemove.size(); ++var4) {
|
||||
if (((AnvilChunkLoaderPending) this.chunksToRemove.get(var4)).chunkCoordinate
|
||||
.equals(par1ChunkCoordIntPair)) {
|
||||
this.chunksToRemove.set(var4,
|
||||
new AnvilChunkLoaderPending(par1ChunkCoordIntPair, par2NBTTagCompound));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.chunksToRemove.add(new AnvilChunkLoaderPending(par1ChunkCoordIntPair, par2NBTTagCompound));
|
||||
this.pendingAnvilChunksCoordinates.add(par1ChunkCoordIntPair);
|
||||
ThreadedFileIOBase.threadedIOInstance.queueIO(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a boolean stating if the write was unsuccessful.
|
||||
*/
|
||||
public boolean writeNextIO() {
|
||||
AnvilChunkLoaderPending var1 = null;
|
||||
Object var2 = this.syncLockObject;
|
||||
|
||||
synchronized (this.syncLockObject) {
|
||||
if (this.chunksToRemove.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var1 = (AnvilChunkLoaderPending) this.chunksToRemove.remove(0);
|
||||
this.pendingAnvilChunksCoordinates.remove(var1.chunkCoordinate);
|
||||
}
|
||||
|
||||
if (var1 != null) {
|
||||
try {
|
||||
this.writeChunkNBTTags(var1);
|
||||
} catch (Exception var4) {
|
||||
var4.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void writeChunkNBTTags(AnvilChunkLoaderPending par1AnvilChunkLoaderPending) throws IOException {
|
||||
DataOutputStream var2 = RegionFileCache.getChunkOutputStream(this.chunkSaveLocation,
|
||||
par1AnvilChunkLoaderPending.chunkCoordinate.chunkXPos,
|
||||
par1AnvilChunkLoaderPending.chunkCoordinate.chunkZPos);
|
||||
CompressedStreamTools.write(par1AnvilChunkLoaderPending.nbtTags, var2);
|
||||
var2.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Save extra data associated with this Chunk not normally saved during
|
||||
* autosave, only during chunk unload. Currently unused.
|
||||
*/
|
||||
public void saveExtraChunkData(World par1World, Chunk par2Chunk) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Called every World.tick()
|
||||
*/
|
||||
public void chunkTick() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Save extra data not associated with any Chunk. Not saved during autosave,
|
||||
* only during world unload. Currently unused.
|
||||
*/
|
||||
public void saveExtraData() {
|
||||
while (this.writeNextIO()) {
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the Chunk passed as an argument to the NBTTagCompound also passed,
|
||||
* using the World argument to retrieve the Chunk's last update time.
|
||||
*/
|
||||
private void writeChunkToNBT(Chunk par1Chunk, World par2World, NBTTagCompound par3NBTTagCompound) {
|
||||
par3NBTTagCompound.setInteger("xPos", par1Chunk.xPosition);
|
||||
par3NBTTagCompound.setInteger("zPos", par1Chunk.zPosition);
|
||||
par3NBTTagCompound.setLong("LastUpdate", par2World.getTotalWorldTime());
|
||||
par3NBTTagCompound.setIntArray("HeightMap", par1Chunk.heightMap);
|
||||
par3NBTTagCompound.setBoolean("TerrainPopulated", par1Chunk.isTerrainPopulated);
|
||||
ExtendedBlockStorage[] var4 = par1Chunk.getBlockStorageArray();
|
||||
NBTTagList var5 = new NBTTagList("Sections");
|
||||
boolean var6 = !par2World.provider.hasNoSky;
|
||||
ExtendedBlockStorage[] var7 = var4;
|
||||
int var8 = var4.length;
|
||||
NBTTagCompound var11;
|
||||
|
||||
for (int var9 = 0; var9 < var8; ++var9) {
|
||||
ExtendedBlockStorage var10 = var7[var9];
|
||||
|
||||
if (var10 != null) {
|
||||
var11 = new NBTTagCompound();
|
||||
var11.setByte("Y", (byte) (var10.getYLocation() >> 4 & 255));
|
||||
var11.setByteArray("Blocks", var10.getBlockLSBArray());
|
||||
|
||||
if (var10.getBlockMSBArray() != null) {
|
||||
var11.setByteArray("Add", var10.getBlockMSBArray().data);
|
||||
}
|
||||
|
||||
var11.setByteArray("Data", var10.getMetadataArray().data);
|
||||
var11.setByteArray("BlockLight", var10.getBlocklightArray().data);
|
||||
|
||||
if (var6) {
|
||||
var11.setByteArray("SkyLight", var10.getSkylightArray().data);
|
||||
} else {
|
||||
var11.setByteArray("SkyLight", new byte[var10.getBlocklightArray().data.length]);
|
||||
}
|
||||
|
||||
var5.appendTag(var11);
|
||||
}
|
||||
}
|
||||
|
||||
par3NBTTagCompound.setTag("Sections", var5);
|
||||
par3NBTTagCompound.setByteArray("Biomes", par1Chunk.getBiomeArray());
|
||||
par1Chunk.hasEntities = false;
|
||||
NBTTagList var16 = new NBTTagList();
|
||||
Iterator var18;
|
||||
|
||||
for (var8 = 0; var8 < par1Chunk.entityLists.length; ++var8) {
|
||||
var18 = par1Chunk.entityLists[var8].iterator();
|
||||
|
||||
while (var18.hasNext()) {
|
||||
Entity var20 = (Entity) var18.next();
|
||||
var11 = new NBTTagCompound();
|
||||
|
||||
if (var20.addEntityID(var11)) {
|
||||
par1Chunk.hasEntities = true;
|
||||
var16.appendTag(var11);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
par3NBTTagCompound.setTag("Entities", var16);
|
||||
NBTTagList var17 = new NBTTagList();
|
||||
var18 = par1Chunk.chunkTileEntityMap.values().iterator();
|
||||
|
||||
while (var18.hasNext()) {
|
||||
TileEntity var21 = (TileEntity) var18.next();
|
||||
var11 = new NBTTagCompound();
|
||||
var21.writeToNBT(var11);
|
||||
var17.appendTag(var11);
|
||||
}
|
||||
|
||||
par3NBTTagCompound.setTag("TileEntities", var17);
|
||||
List var19 = par2World.getPendingBlockUpdates(par1Chunk, false);
|
||||
|
||||
if (var19 != null) {
|
||||
long var22 = par2World.getTotalWorldTime();
|
||||
NBTTagList var12 = new NBTTagList();
|
||||
Iterator var13 = var19.iterator();
|
||||
|
||||
while (var13.hasNext()) {
|
||||
NextTickListEntry var14 = (NextTickListEntry) var13.next();
|
||||
NBTTagCompound var15 = new NBTTagCompound();
|
||||
var15.setInteger("i", var14.blockID);
|
||||
var15.setInteger("x", var14.xCoord);
|
||||
var15.setInteger("y", var14.yCoord);
|
||||
var15.setInteger("z", var14.zCoord);
|
||||
var15.setInteger("t", (int) (var14.scheduledTime - var22));
|
||||
var15.setInteger("p", var14.field_82754_f);
|
||||
var12.appendTag(var15);
|
||||
}
|
||||
|
||||
par3NBTTagCompound.setTag("TileTicks", var12);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the data stored in the passed NBTTagCompound and creates a Chunk with
|
||||
* that data in the passed World. Returns the created Chunk.
|
||||
*/
|
||||
private Chunk readChunkFromNBT(World par1World, NBTTagCompound par2NBTTagCompound) {
|
||||
int var3 = par2NBTTagCompound.getInteger("xPos");
|
||||
int var4 = par2NBTTagCompound.getInteger("zPos");
|
||||
Chunk var5 = new Chunk(par1World, var3, var4);
|
||||
var5.heightMap = par2NBTTagCompound.getIntArray("HeightMap");
|
||||
var5.isTerrainPopulated = par2NBTTagCompound.getBoolean("TerrainPopulated");
|
||||
NBTTagList var6 = par2NBTTagCompound.getTagList("Sections");
|
||||
byte var7 = 16;
|
||||
ExtendedBlockStorage[] var8 = new ExtendedBlockStorage[var7];
|
||||
boolean var9 = !par1World.provider.hasNoSky;
|
||||
|
||||
for (int var10 = 0; var10 < var6.tagCount(); ++var10) {
|
||||
NBTTagCompound var11 = (NBTTagCompound) var6.tagAt(var10);
|
||||
byte var12 = var11.getByte("Y");
|
||||
ExtendedBlockStorage var13 = new ExtendedBlockStorage(var12 << 4, var9);
|
||||
var13.setBlockLSBArray(var11.getByteArray("Blocks"));
|
||||
|
||||
if (var11.hasKey("Add")) {
|
||||
var13.setBlockMSBArray(new NibbleArray(var11.getByteArray("Add"), 4));
|
||||
}
|
||||
|
||||
var13.setBlockMetadataArray(new NibbleArray(var11.getByteArray("Data"), 4));
|
||||
var13.setBlocklightArray(new NibbleArray(var11.getByteArray("BlockLight"), 4));
|
||||
|
||||
if (var9) {
|
||||
var13.setSkylightArray(new NibbleArray(var11.getByteArray("SkyLight"), 4));
|
||||
}
|
||||
|
||||
var13.removeInvalidBlocks();
|
||||
var8[var12] = var13;
|
||||
}
|
||||
|
||||
var5.setStorageArrays(var8);
|
||||
|
||||
if (par2NBTTagCompound.hasKey("Biomes")) {
|
||||
var5.setBiomeArray(par2NBTTagCompound.getByteArray("Biomes"));
|
||||
}
|
||||
|
||||
NBTTagList var17 = par2NBTTagCompound.getTagList("Entities");
|
||||
|
||||
if (var17 != null) {
|
||||
for (int var18 = 0; var18 < var17.tagCount(); ++var18) {
|
||||
NBTTagCompound var20 = (NBTTagCompound) var17.tagAt(var18);
|
||||
Entity var22 = EntityList.createEntityFromNBT(var20, par1World);
|
||||
var5.hasEntities = true;
|
||||
|
||||
if (var22 != null) {
|
||||
var5.addEntity(var22);
|
||||
Entity var14 = var22;
|
||||
|
||||
for (NBTTagCompound var15 = var20; var15.hasKey("Riding"); var15 = var15.getCompoundTag("Riding")) {
|
||||
Entity var16 = EntityList.createEntityFromNBT(var15.getCompoundTag("Riding"), par1World);
|
||||
|
||||
if (var16 != null) {
|
||||
var5.addEntity(var16);
|
||||
var14.mountEntity(var16);
|
||||
}
|
||||
|
||||
var14 = var16;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NBTTagList var19 = par2NBTTagCompound.getTagList("TileEntities");
|
||||
|
||||
if (var19 != null) {
|
||||
for (int var21 = 0; var21 < var19.tagCount(); ++var21) {
|
||||
NBTTagCompound var24 = (NBTTagCompound) var19.tagAt(var21);
|
||||
TileEntity var26 = TileEntity.createAndLoadEntity(var24);
|
||||
|
||||
if (var26 != null) {
|
||||
var5.addTileEntity(var26);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (par2NBTTagCompound.hasKey("TileTicks")) {
|
||||
NBTTagList var23 = par2NBTTagCompound.getTagList("TileTicks");
|
||||
|
||||
if (var23 != null) {
|
||||
for (int var25 = 0; var25 < var23.tagCount(); ++var25) {
|
||||
NBTTagCompound var27 = (NBTTagCompound) var23.tagAt(var25);
|
||||
par1World.scheduleBlockUpdateFromLoad(var27.getInteger("x"), var27.getInteger("y"),
|
||||
var27.getInteger("z"), var27.getInteger("i"), var27.getInteger("t"), var27.getInteger("p"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return var5;
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
package net.minecraft.src;
|
||||
|
||||
class AnvilChunkLoaderPending {
|
||||
public final ChunkCoordIntPair chunkCoordinate;
|
||||
public final NBTTagCompound nbtTags;
|
||||
|
||||
public AnvilChunkLoaderPending(ChunkCoordIntPair par1ChunkCoordIntPair, NBTTagCompound par2NBTTagCompound) {
|
||||
this.chunkCoordinate = par1ChunkCoordIntPair;
|
||||
this.nbtTags = par2NBTTagCompound;
|
||||
}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
package net.minecraft.src;
|
||||
|
||||
public class AnvilConverterData {
|
||||
public long lastUpdated;
|
||||
public boolean terrainPopulated;
|
||||
public byte[] heightmap;
|
||||
public NibbleArrayReader blockLight;
|
||||
public NibbleArrayReader skyLight;
|
||||
public NibbleArrayReader data;
|
||||
public byte[] blocks;
|
||||
public NBTTagList entities;
|
||||
public NBTTagList tileEntities;
|
||||
public NBTTagList tileTicks;
|
||||
public final int x;
|
||||
public final int z;
|
||||
|
||||
public AnvilConverterData(int par1, int par2) {
|
||||
this.x = par1;
|
||||
this.z = par2;
|
||||
}
|
||||
}
|
||||
@@ -1,191 +0,0 @@
|
||||
package net.minecraft.src;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
|
||||
public class AnvilSaveConverter extends SaveFormatOld {
|
||||
public AnvilSaveConverter(File par1File) {
|
||||
super(par1File);
|
||||
}
|
||||
|
||||
protected int getSaveVersion() {
|
||||
return 19133;
|
||||
}
|
||||
|
||||
public void flushCache() {
|
||||
RegionFileCache.clearRegionFileReferences();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns back a loader for the specified save directory
|
||||
*/
|
||||
public ISaveHandler getSaveLoader(String par1Str, boolean par2) {
|
||||
return new AnvilSaveHandler(this.savesDirectory, par1Str, par2);
|
||||
}
|
||||
|
||||
/**
|
||||
* gets if the map is old chunk saving (true) or McRegion (false)
|
||||
*/
|
||||
public boolean isOldMapFormat(String par1Str) {
|
||||
WorldInfo var2 = this.getWorldInfo(par1Str);
|
||||
return var2 != null && var2.getSaveVersion() != this.getSaveVersion();
|
||||
}
|
||||
|
||||
/**
|
||||
* converts the map to mcRegion
|
||||
*/
|
||||
public boolean convertMapFormat(String par1Str, IProgressUpdate par2IProgressUpdate) {
|
||||
par2IProgressUpdate.setLoadingProgress(0);
|
||||
ArrayList var3 = new ArrayList();
|
||||
ArrayList var4 = new ArrayList();
|
||||
ArrayList var5 = new ArrayList();
|
||||
File var6 = new File(this.savesDirectory, par1Str);
|
||||
File var7 = new File(var6, "DIM-1");
|
||||
File var8 = new File(var6, "DIM1");
|
||||
MinecraftServer.getServer().getLogAgent().func_98233_a("Scanning folders...");
|
||||
this.addRegionFilesToCollection(var6, var3);
|
||||
|
||||
if (var7.exists()) {
|
||||
this.addRegionFilesToCollection(var7, var4);
|
||||
}
|
||||
|
||||
if (var8.exists()) {
|
||||
this.addRegionFilesToCollection(var8, var5);
|
||||
}
|
||||
|
||||
int var9 = var3.size() + var4.size() + var5.size();
|
||||
MinecraftServer.getServer().getLogAgent().func_98233_a("Total conversion count is " + var9);
|
||||
WorldInfo var10 = this.getWorldInfo(par1Str);
|
||||
Object var11 = null;
|
||||
|
||||
if (var10.getTerrainType() == WorldType.FLAT) {
|
||||
var11 = new WorldChunkManagerHell(BiomeGenBase.plains, 0.5F, 0.5F);
|
||||
} else {
|
||||
var11 = new WorldChunkManager(var10.getSeed(), var10.getTerrainType());
|
||||
}
|
||||
|
||||
this.convertFile(new File(var6, "region"), var3, (WorldChunkManager) var11, 0, var9, par2IProgressUpdate);
|
||||
this.convertFile(new File(var7, "region"), var4, new WorldChunkManagerHell(BiomeGenBase.hell, 1.0F, 0.0F),
|
||||
var3.size(), var9, par2IProgressUpdate);
|
||||
this.convertFile(new File(var8, "region"), var5, new WorldChunkManagerHell(BiomeGenBase.sky, 0.5F, 0.0F),
|
||||
var3.size() + var4.size(), var9, par2IProgressUpdate);
|
||||
var10.setSaveVersion(19133);
|
||||
|
||||
if (var10.getTerrainType() == WorldType.DEFAULT_1_1) {
|
||||
var10.setTerrainType(WorldType.DEFAULT);
|
||||
}
|
||||
|
||||
this.createFile(par1Str);
|
||||
ISaveHandler var12 = this.getSaveLoader(par1Str, false);
|
||||
var12.saveWorldInfo(var10);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* par: filename for the level.dat_mcr backup
|
||||
*/
|
||||
private void createFile(String par1Str) {
|
||||
File var2 = new File(this.savesDirectory, par1Str);
|
||||
|
||||
if (!var2.exists()) {
|
||||
System.out.println("Warning: Unable to create level.dat_mcr backup");
|
||||
} else {
|
||||
File var3 = new File(var2, "level.dat");
|
||||
|
||||
if (!var3.exists()) {
|
||||
System.out.println("Warning: Unable to create level.dat_mcr backup");
|
||||
} else {
|
||||
File var4 = new File(var2, "level.dat_mcr");
|
||||
|
||||
if (!var3.renameTo(var4)) {
|
||||
System.out.println("Warning: Unable to create level.dat_mcr backup");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void convertFile(File par1File, Iterable par2Iterable, WorldChunkManager par3WorldChunkManager, int par4,
|
||||
int par5, IProgressUpdate par6IProgressUpdate) {
|
||||
Iterator var7 = par2Iterable.iterator();
|
||||
|
||||
while (var7.hasNext()) {
|
||||
File var8 = (File) var7.next();
|
||||
this.convertChunks(par1File, var8, par3WorldChunkManager, par4, par5, par6IProgressUpdate);
|
||||
++par4;
|
||||
int var9 = (int) Math.round(100.0D * (double) par4 / (double) par5);
|
||||
par6IProgressUpdate.setLoadingProgress(var9);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* copies a 32x32 chunk set from par2File to par1File, via AnvilConverterData
|
||||
*/
|
||||
private void convertChunks(File par1File, File par2File, WorldChunkManager par3WorldChunkManager, int par4,
|
||||
int par5, IProgressUpdate par6IProgressUpdate) {
|
||||
try {
|
||||
String var7 = par2File.getName();
|
||||
RegionFile var8 = new RegionFile(par2File);
|
||||
RegionFile var9 = new RegionFile(
|
||||
new File(par1File, var7.substring(0, var7.length() - ".mcr".length()) + ".mca"));
|
||||
|
||||
for (int var10 = 0; var10 < 32; ++var10) {
|
||||
int var11;
|
||||
|
||||
for (var11 = 0; var11 < 32; ++var11) {
|
||||
if (var8.isChunkSaved(var10, var11) && !var9.isChunkSaved(var10, var11)) {
|
||||
DataInputStream var12 = var8.getChunkDataInputStream(var10, var11);
|
||||
|
||||
if (var12 == null) {
|
||||
MinecraftServer.getServer().getLogAgent().func_98236_b("Failed to fetch input stream");
|
||||
} else {
|
||||
NBTTagCompound var13 = CompressedStreamTools.read(var12);
|
||||
var12.close();
|
||||
NBTTagCompound var14 = var13.getCompoundTag("Level");
|
||||
AnvilConverterData var15 = ChunkLoader.load(var14);
|
||||
NBTTagCompound var16 = new NBTTagCompound();
|
||||
NBTTagCompound var17 = new NBTTagCompound();
|
||||
var16.setTag("Level", var17);
|
||||
ChunkLoader.convertToAnvilFormat(var15, var17, par3WorldChunkManager);
|
||||
DataOutputStream var18 = var9.getChunkDataOutputStream(var10, var11);
|
||||
CompressedStreamTools.write(var16, var18);
|
||||
var18.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var11 = (int) Math.round(100.0D * (double) (par4 * 1024) / (double) (par5 * 1024));
|
||||
int var20 = (int) Math
|
||||
.round(100.0D * (double) ((var10 + 1) * 32 + par4 * 1024) / (double) (par5 * 1024));
|
||||
|
||||
if (var20 > var11) {
|
||||
par6IProgressUpdate.setLoadingProgress(var20);
|
||||
}
|
||||
}
|
||||
|
||||
var8.close();
|
||||
var9.close();
|
||||
} catch (IOException var19) {
|
||||
var19.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* filters the files in the par1 directory, and adds them to the par2
|
||||
* collections
|
||||
*/
|
||||
private void addRegionFilesToCollection(File par1File, Collection par2Collection) {
|
||||
File var3 = new File(par1File, "region");
|
||||
File[] var4 = var3.listFiles(new AnvilSaveConverterFileFilter(this));
|
||||
|
||||
if (var4 != null) {
|
||||
Collections.addAll(par2Collection, var4);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
package net.minecraft.src;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FilenameFilter;
|
||||
|
||||
class AnvilSaveConverterFileFilter implements FilenameFilter {
|
||||
final AnvilSaveConverter parent;
|
||||
|
||||
AnvilSaveConverterFileFilter(AnvilSaveConverter par1AnvilSaveConverter) {
|
||||
this.parent = par1AnvilSaveConverter;
|
||||
}
|
||||
|
||||
public boolean accept(File par1File, String par2Str) {
|
||||
return par2Str.endsWith(".mcr");
|
||||
}
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
package net.minecraft.src;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class AnvilSaveHandler extends SaveHandler {
|
||||
public AnvilSaveHandler(File par1File, String par2Str, boolean par3) {
|
||||
super(par1File, par2Str, par3);
|
||||
}
|
||||
|
||||
/**
|
||||
* initializes and returns the chunk loader for the specified world provider
|
||||
*/
|
||||
public IChunkLoader getChunkLoader(WorldProvider par1WorldProvider) {
|
||||
File var2 = this.getWorldDirectory();
|
||||
File var3;
|
||||
|
||||
if (par1WorldProvider instanceof WorldProviderHell) {
|
||||
var3 = new File(var2, "DIM-1");
|
||||
var3.mkdirs();
|
||||
return new AnvilChunkLoader(var3);
|
||||
} else if (par1WorldProvider instanceof WorldProviderEnd) {
|
||||
var3 = new File(var2, "DIM1");
|
||||
var3.mkdirs();
|
||||
return new AnvilChunkLoader(var3);
|
||||
} else {
|
||||
return new AnvilChunkLoader(var2);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the given World Info with the given NBTTagCompound as the Player.
|
||||
*/
|
||||
public void saveWorldInfoWithPlayer(WorldInfo par1WorldInfo, NBTTagCompound par2NBTTagCompound) {
|
||||
par1WorldInfo.setSaveVersion(19133);
|
||||
super.saveWorldInfoWithPlayer(par1WorldInfo, par2NBTTagCompound);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to flush all changes to disk, waiting for them to complete.
|
||||
*/
|
||||
public void flush() {
|
||||
try {
|
||||
ThreadedFileIOBase.threadedIOInstance.waitForFinish();
|
||||
} catch (InterruptedException var2) {
|
||||
var2.printStackTrace();
|
||||
}
|
||||
|
||||
RegionFileCache.clearRegionFileReferences();
|
||||
}
|
||||
}
|
||||
@@ -1,122 +0,0 @@
|
||||
package net.minecraft.src;
|
||||
|
||||
public class ChunkLoader {
|
||||
public static AnvilConverterData load(NBTTagCompound par0NBTTagCompound) {
|
||||
int var1 = par0NBTTagCompound.getInteger("xPos");
|
||||
int var2 = par0NBTTagCompound.getInteger("zPos");
|
||||
AnvilConverterData var3 = new AnvilConverterData(var1, var2);
|
||||
var3.blocks = par0NBTTagCompound.getByteArray("Blocks");
|
||||
var3.data = new NibbleArrayReader(par0NBTTagCompound.getByteArray("Data"), 7);
|
||||
var3.skyLight = new NibbleArrayReader(par0NBTTagCompound.getByteArray("SkyLight"), 7);
|
||||
var3.blockLight = new NibbleArrayReader(par0NBTTagCompound.getByteArray("BlockLight"), 7);
|
||||
var3.heightmap = par0NBTTagCompound.getByteArray("HeightMap");
|
||||
var3.terrainPopulated = par0NBTTagCompound.getBoolean("TerrainPopulated");
|
||||
var3.entities = par0NBTTagCompound.getTagList("Entities");
|
||||
var3.tileEntities = par0NBTTagCompound.getTagList("TileEntities");
|
||||
var3.tileTicks = par0NBTTagCompound.getTagList("TileTicks");
|
||||
|
||||
try {
|
||||
var3.lastUpdated = par0NBTTagCompound.getLong("LastUpdate");
|
||||
} catch (ClassCastException var5) {
|
||||
var3.lastUpdated = (long) par0NBTTagCompound.getInteger("LastUpdate");
|
||||
}
|
||||
|
||||
return var3;
|
||||
}
|
||||
|
||||
public static void convertToAnvilFormat(AnvilConverterData par0AnvilConverterData,
|
||||
NBTTagCompound par1NBTTagCompound, WorldChunkManager par2WorldChunkManager) {
|
||||
par1NBTTagCompound.setInteger("xPos", par0AnvilConverterData.x);
|
||||
par1NBTTagCompound.setInteger("zPos", par0AnvilConverterData.z);
|
||||
par1NBTTagCompound.setLong("LastUpdate", par0AnvilConverterData.lastUpdated);
|
||||
int[] var3 = new int[par0AnvilConverterData.heightmap.length];
|
||||
|
||||
for (int var4 = 0; var4 < par0AnvilConverterData.heightmap.length; ++var4) {
|
||||
var3[var4] = par0AnvilConverterData.heightmap[var4];
|
||||
}
|
||||
|
||||
par1NBTTagCompound.setIntArray("HeightMap", var3);
|
||||
par1NBTTagCompound.setBoolean("TerrainPopulated", par0AnvilConverterData.terrainPopulated);
|
||||
NBTTagList var16 = new NBTTagList("Sections");
|
||||
int var7;
|
||||
|
||||
for (int var5 = 0; var5 < 8; ++var5) {
|
||||
boolean var6 = true;
|
||||
|
||||
for (var7 = 0; var7 < 16 && var6; ++var7) {
|
||||
int var8 = 0;
|
||||
|
||||
while (var8 < 16 && var6) {
|
||||
int var9 = 0;
|
||||
|
||||
while (true) {
|
||||
if (var9 < 16) {
|
||||
int var10 = var7 << 11 | var9 << 7 | var8 + (var5 << 4);
|
||||
byte var11 = par0AnvilConverterData.blocks[var10];
|
||||
|
||||
if (var11 == 0) {
|
||||
++var9;
|
||||
continue;
|
||||
}
|
||||
|
||||
var6 = false;
|
||||
}
|
||||
|
||||
++var8;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!var6) {
|
||||
byte[] var19 = new byte[4096];
|
||||
NibbleArray var20 = new NibbleArray(var19.length, 4);
|
||||
NibbleArray var21 = new NibbleArray(var19.length, 4);
|
||||
NibbleArray var22 = new NibbleArray(var19.length, 4);
|
||||
|
||||
for (int var23 = 0; var23 < 16; ++var23) {
|
||||
for (int var12 = 0; var12 < 16; ++var12) {
|
||||
for (int var13 = 0; var13 < 16; ++var13) {
|
||||
int var14 = var23 << 11 | var13 << 7 | var12 + (var5 << 4);
|
||||
byte var15 = par0AnvilConverterData.blocks[var14];
|
||||
var19[var12 << 8 | var13 << 4 | var23] = (byte) (var15 & 255);
|
||||
var20.set(var23, var12, var13,
|
||||
par0AnvilConverterData.data.get(var23, var12 + (var5 << 4), var13));
|
||||
var21.set(var23, var12, var13,
|
||||
par0AnvilConverterData.skyLight.get(var23, var12 + (var5 << 4), var13));
|
||||
var22.set(var23, var12, var13,
|
||||
par0AnvilConverterData.blockLight.get(var23, var12 + (var5 << 4), var13));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NBTTagCompound var24 = new NBTTagCompound();
|
||||
var24.setByte("Y", (byte) (var5 & 255));
|
||||
var24.setByteArray("Blocks", var19);
|
||||
var24.setByteArray("Data", var20.data);
|
||||
var24.setByteArray("SkyLight", var21.data);
|
||||
var24.setByteArray("BlockLight", var22.data);
|
||||
var16.appendTag(var24);
|
||||
}
|
||||
}
|
||||
|
||||
par1NBTTagCompound.setTag("Sections", var16);
|
||||
byte[] var17 = new byte[256];
|
||||
|
||||
for (int var18 = 0; var18 < 16; ++var18) {
|
||||
for (var7 = 0; var7 < 16; ++var7) {
|
||||
var17[var7 << 4
|
||||
| var18] = (byte) (par2WorldChunkManager.getBiomeGenAt(par0AnvilConverterData.x << 4 | var18,
|
||||
par0AnvilConverterData.z << 4 | var7).biomeID & 255);
|
||||
}
|
||||
}
|
||||
|
||||
par1NBTTagCompound.setByteArray("Biomes", var17);
|
||||
par1NBTTagCompound.setTag("Entities", par0AnvilConverterData.entities);
|
||||
par1NBTTagCompound.setTag("TileEntities", par0AnvilConverterData.tileEntities);
|
||||
|
||||
if (par0AnvilConverterData.tileTicks != null) {
|
||||
par1NBTTagCompound.setTag("TileTicks", par0AnvilConverterData.tileTicks);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,368 +0,0 @@
|
||||
package net.minecraft.src;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
|
||||
public class DedicatedServer extends MinecraftServer implements IServer {
|
||||
private final List pendingCommandList = Collections.synchronizedList(new ArrayList());
|
||||
private final ILogAgent field_98131_l;
|
||||
private RConThreadQuery theRConThreadQuery;
|
||||
private RConThreadMain theRConThreadMain;
|
||||
private PropertyManager settings;
|
||||
private boolean canSpawnStructures;
|
||||
private EnumGameType gameType;
|
||||
private NetworkListenThread networkThread;
|
||||
private boolean guiIsEnabled = false;
|
||||
|
||||
public DedicatedServer(File par1File) {
|
||||
super(par1File);
|
||||
this.field_98131_l = new LogAgent("Minecraft-Server", (String) null,
|
||||
(new File(par1File, "server.log")).getAbsolutePath());
|
||||
new DedicatedServerSleepThread(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialises the server and starts it.
|
||||
*/
|
||||
protected boolean startServer() throws IOException {
|
||||
DedicatedServerCommandThread var1 = new DedicatedServerCommandThread(this);
|
||||
var1.setDaemon(true);
|
||||
var1.start();
|
||||
this.getLogAgent().func_98233_a("Starting minecraft server version 1.5.2");
|
||||
|
||||
if (Runtime.getRuntime().maxMemory() / 1024L / 1024L < 512L) {
|
||||
this.getLogAgent().func_98236_b(
|
||||
"To start the server with more ram, launch it as \"java -Xmx1024M -Xms1024M -jar minecraft_server.jar\"");
|
||||
}
|
||||
|
||||
this.getLogAgent().func_98233_a("Loading properties");
|
||||
this.settings = new PropertyManager(new File("server.properties"), this.getLogAgent());
|
||||
|
||||
if (this.isSinglePlayer()) {
|
||||
this.setHostname("127.0.0.1");
|
||||
} else {
|
||||
this.setOnlineMode(this.settings.getBooleanProperty("online-mode", true));
|
||||
this.setHostname(this.settings.getStringProperty("server-ip", ""));
|
||||
}
|
||||
|
||||
this.setCanSpawnAnimals(this.settings.getBooleanProperty("spawn-animals", true));
|
||||
this.setCanSpawnNPCs(this.settings.getBooleanProperty("spawn-npcs", true));
|
||||
this.setAllowPvp(this.settings.getBooleanProperty("pvp", true));
|
||||
this.setAllowFlight(this.settings.getBooleanProperty("allow-flight", false));
|
||||
this.setTexturePack(this.settings.getStringProperty("texture-pack", ""));
|
||||
this.setMOTD(this.settings.getStringProperty("motd", "A Minecraft Server"));
|
||||
this.func_104055_i(this.settings.getBooleanProperty("force-gamemode", false));
|
||||
|
||||
if (this.settings.getIntProperty("difficulty", 1) < 0) {
|
||||
this.settings.setProperty("difficulty", Integer.valueOf(0));
|
||||
} else if (this.settings.getIntProperty("difficulty", 1) > 3) {
|
||||
this.settings.setProperty("difficulty", Integer.valueOf(3));
|
||||
}
|
||||
|
||||
this.canSpawnStructures = this.settings.getBooleanProperty("generate-structures", true);
|
||||
int var2 = this.settings.getIntProperty("gamemode", EnumGameType.SURVIVAL.getID());
|
||||
this.gameType = WorldSettings.getGameTypeById(var2);
|
||||
this.getLogAgent().func_98233_a("Default game type: " + this.gameType);
|
||||
InetAddress var3 = null;
|
||||
|
||||
if (this.getServerHostname().length() > 0) {
|
||||
var3 = InetAddress.getByName(this.getServerHostname());
|
||||
}
|
||||
|
||||
if (this.getServerPort() < 0) {
|
||||
this.setServerPort(this.settings.getIntProperty("server-port", 25565));
|
||||
}
|
||||
|
||||
this.getLogAgent().func_98233_a("Generating keypair");
|
||||
this.setKeyPair(CryptManager.generateKeyPair());
|
||||
this.getLogAgent()
|
||||
.func_98233_a("Starting Minecraft server on "
|
||||
+ (this.getServerHostname().length() == 0 ? "*" : this.getServerHostname()) + ":"
|
||||
+ this.getServerPort());
|
||||
|
||||
try {
|
||||
this.networkThread = new DedicatedServerListenThread(this, var3, this.getServerPort());
|
||||
} catch (IOException var16) {
|
||||
this.getLogAgent().func_98236_b("**** FAILED TO BIND TO PORT!");
|
||||
this.getLogAgent().logWarningFormatted("The exception was: {0}", new Object[] { var16.toString() });
|
||||
this.getLogAgent().func_98236_b("Perhaps a server is already running on that port?");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!this.isServerInOnlineMode()) {
|
||||
this.getLogAgent().func_98236_b("**** SERVER IS RUNNING IN OFFLINE/INSECURE MODE!");
|
||||
this.getLogAgent().func_98236_b("The server will make no attempt to authenticate usernames. Beware.");
|
||||
this.getLogAgent().func_98236_b(
|
||||
"While this makes the game possible to play without internet access, it also opens up the ability for hackers to connect with any username they choose.");
|
||||
this.getLogAgent()
|
||||
.func_98236_b("To change this, set \"online-mode\" to \"true\" in the server.properties file.");
|
||||
}
|
||||
|
||||
this.setConfigurationManager(new DedicatedPlayerList(this));
|
||||
long var4 = System.nanoTime();
|
||||
|
||||
if (this.getFolderName() == null) {
|
||||
this.setFolderName(this.settings.getStringProperty("level-name", "world"));
|
||||
}
|
||||
|
||||
String var6 = this.settings.getStringProperty("level-seed", "");
|
||||
String var7 = this.settings.getStringProperty("level-type", "DEFAULT");
|
||||
String var8 = this.settings.getStringProperty("generator-settings", "");
|
||||
long var9 = (new Random()).nextLong();
|
||||
|
||||
if (var6.length() > 0) {
|
||||
try {
|
||||
long var11 = Long.parseLong(var6);
|
||||
|
||||
if (var11 != 0L) {
|
||||
var9 = var11;
|
||||
}
|
||||
} catch (NumberFormatException var15) {
|
||||
var9 = (long) var6.hashCode();
|
||||
}
|
||||
}
|
||||
|
||||
WorldType var17 = WorldType.parseWorldType(var7);
|
||||
|
||||
if (var17 == null) {
|
||||
var17 = WorldType.DEFAULT;
|
||||
}
|
||||
|
||||
this.setBuildLimit(this.settings.getIntProperty("max-build-height", 256));
|
||||
this.setBuildLimit((this.getBuildLimit() + 8) / 16 * 16);
|
||||
this.setBuildLimit(MathHelper.clamp_int(this.getBuildLimit(), 64, 256));
|
||||
this.settings.setProperty("max-build-height", Integer.valueOf(this.getBuildLimit()));
|
||||
this.getLogAgent().func_98233_a("Preparing level \"" + this.getFolderName() + "\"");
|
||||
this.loadAllWorlds(this.getFolderName(), this.getFolderName(), var9, var17, var8);
|
||||
long var12 = System.nanoTime() - var4;
|
||||
String var14 = String.format("%.3fs", new Object[] { Double.valueOf((double) var12 / 1.0E9D) });
|
||||
this.getLogAgent().func_98233_a("Done (" + var14 + ")! For help, type \"help\" or \"?\"");
|
||||
|
||||
if (this.settings.getBooleanProperty("enable-query", false)) {
|
||||
this.getLogAgent().func_98233_a("Starting GS4 status listener");
|
||||
this.theRConThreadQuery = new RConThreadQuery(this);
|
||||
this.theRConThreadQuery.startThread();
|
||||
}
|
||||
|
||||
if (this.settings.getBooleanProperty("enable-rcon", false)) {
|
||||
this.getLogAgent().func_98233_a("Starting remote control listener");
|
||||
this.theRConThreadMain = new RConThreadMain(this);
|
||||
this.theRConThreadMain.startThread();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean canStructuresSpawn() {
|
||||
return this.canSpawnStructures;
|
||||
}
|
||||
|
||||
public EnumGameType getGameType() {
|
||||
return this.gameType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defaults to "1" (Easy) for the dedicated server, defaults to "2" (Normal) on
|
||||
* the client.
|
||||
*/
|
||||
public int getDifficulty() {
|
||||
return this.settings.getIntProperty("difficulty", 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Defaults to false.
|
||||
*/
|
||||
public boolean isHardcore() {
|
||||
return this.settings.getBooleanProperty("hardcore", false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called on exit from the main run() loop.
|
||||
*/
|
||||
protected void finalTick(CrashReport par1CrashReport) {
|
||||
while (this.isServerRunning()) {
|
||||
this.executePendingCommands();
|
||||
|
||||
try {
|
||||
Thread.sleep(10L);
|
||||
} catch (InterruptedException var3) {
|
||||
var3.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the server info, including from theWorldServer, to the crash report.
|
||||
*/
|
||||
public CrashReport addServerInfoToCrashReport(CrashReport par1CrashReport) {
|
||||
par1CrashReport = super.addServerInfoToCrashReport(par1CrashReport);
|
||||
par1CrashReport.func_85056_g().addCrashSectionCallable("Is Modded", new CallableType(this));
|
||||
par1CrashReport.func_85056_g().addCrashSectionCallable("Type", new CallableServerType(this));
|
||||
return par1CrashReport;
|
||||
}
|
||||
|
||||
/**
|
||||
* Directly calls System.exit(0), instantly killing the program.
|
||||
*/
|
||||
protected void systemExitNow() {
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
public void updateTimeLightAndEntities() {
|
||||
super.updateTimeLightAndEntities();
|
||||
this.executePendingCommands();
|
||||
}
|
||||
|
||||
public boolean getAllowNether() {
|
||||
return this.settings.getBooleanProperty("allow-nether", true);
|
||||
}
|
||||
|
||||
public boolean allowSpawnMonsters() {
|
||||
return this.settings.getBooleanProperty("spawn-monsters", true);
|
||||
}
|
||||
|
||||
public void addServerStatsToSnooper(PlayerUsageSnooper par1PlayerUsageSnooper) {
|
||||
par1PlayerUsageSnooper.addData("whitelist_enabled",
|
||||
Boolean.valueOf(this.getDedicatedPlayerList().isWhiteListEnabled()));
|
||||
par1PlayerUsageSnooper.addData("whitelist_count",
|
||||
Integer.valueOf(this.getDedicatedPlayerList().getWhiteListedPlayers().size()));
|
||||
super.addServerStatsToSnooper(par1PlayerUsageSnooper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether snooping is enabled or not.
|
||||
*/
|
||||
public boolean isSnooperEnabled() {
|
||||
return this.settings.getBooleanProperty("snooper-enabled", true);
|
||||
}
|
||||
|
||||
public void addPendingCommand(String par1Str, ICommandSender par2ICommandSender) {
|
||||
this.pendingCommandList.add(new ServerCommand(par1Str, par2ICommandSender));
|
||||
}
|
||||
|
||||
public void executePendingCommands() {
|
||||
while (!this.pendingCommandList.isEmpty()) {
|
||||
ServerCommand var1 = (ServerCommand) this.pendingCommandList.remove(0);
|
||||
this.getCommandManager().executeCommand(var1.sender, var1.command);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isDedicatedServer() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public DedicatedPlayerList getDedicatedPlayerList() {
|
||||
return (DedicatedPlayerList) super.getConfigurationManager();
|
||||
}
|
||||
|
||||
public NetworkListenThread getNetworkThread() {
|
||||
return this.networkThread;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an integer property. If it does not exist, set it to the specified
|
||||
* value.
|
||||
*/
|
||||
public int getIntProperty(String par1Str, int par2) {
|
||||
return this.settings.getIntProperty(par1Str, par2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a string property. If it does not exist, set it to the specified value.
|
||||
*/
|
||||
public String getStringProperty(String par1Str, String par2Str) {
|
||||
return this.settings.getStringProperty(par1Str, par2Str);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a boolean property. If it does not exist, set it to the specified value.
|
||||
*/
|
||||
public boolean getBooleanProperty(String par1Str, boolean par2) {
|
||||
return this.settings.getBooleanProperty(par1Str, par2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves an Object with the given property name.
|
||||
*/
|
||||
public void setProperty(String par1Str, Object par2Obj) {
|
||||
this.settings.setProperty(par1Str, par2Obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves all of the server properties to the properties file.
|
||||
*/
|
||||
public void saveProperties() {
|
||||
this.settings.saveProperties();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the filename where server properties are stored
|
||||
*/
|
||||
public String getSettingsFilename() {
|
||||
File var1 = this.settings.getPropertiesFile();
|
||||
return var1 != null ? var1.getAbsolutePath() : "No settings file";
|
||||
}
|
||||
|
||||
public void enableGui() {
|
||||
ServerGUI.initGUI(this);
|
||||
this.guiIsEnabled = true;
|
||||
}
|
||||
|
||||
public boolean getGuiEnabled() {
|
||||
return this.guiIsEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* On dedicated does nothing. On integrated, sets commandsAllowedForAll,
|
||||
* gameType and allows external connections.
|
||||
*/
|
||||
public String shareToLAN(EnumGameType par1EnumGameType, boolean par2) {
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether command blocks are enabled.
|
||||
*/
|
||||
public boolean isCommandBlockEnabled() {
|
||||
return this.settings.getBooleanProperty("enable-command-block", false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the spawn protection area's size.
|
||||
*/
|
||||
public int getSpawnProtectionSize() {
|
||||
return this.settings.getIntProperty("spawn-protection", super.getSpawnProtectionSize());
|
||||
}
|
||||
|
||||
public boolean func_96290_a(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer) {
|
||||
if (par1World.provider.dimensionId != 0) {
|
||||
return false;
|
||||
} else if (this.getDedicatedPlayerList().getOps().isEmpty()) {
|
||||
return false;
|
||||
} else if (this.getDedicatedPlayerList().areCommandsAllowed(par5EntityPlayer.username)) {
|
||||
return false;
|
||||
} else if (this.getSpawnProtectionSize() <= 0) {
|
||||
return false;
|
||||
} else {
|
||||
ChunkCoordinates var6 = par1World.getSpawnPoint();
|
||||
int var7 = MathHelper.abs_int(par2 - var6.posX);
|
||||
int var8 = MathHelper.abs_int(par4 - var6.posZ);
|
||||
int var9 = Math.max(var7, var8);
|
||||
return var9 <= this.getSpawnProtectionSize();
|
||||
}
|
||||
}
|
||||
|
||||
public ILogAgent getLogAgent() {
|
||||
return this.field_98131_l;
|
||||
}
|
||||
|
||||
public ServerConfigurationManager getConfigurationManager() {
|
||||
return this.getDedicatedPlayerList();
|
||||
}
|
||||
}
|
||||
@@ -1,284 +0,0 @@
|
||||
package net.minecraft.src;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.util.ArrayList;
|
||||
import java.util.zip.DeflaterOutputStream;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
import java.util.zip.InflaterInputStream;
|
||||
|
||||
public class RegionFile {
|
||||
private static final byte[] emptySector = new byte[4096];
|
||||
private final File fileName;
|
||||
private RandomAccessFile dataFile;
|
||||
private final int[] offsets = new int[1024];
|
||||
private final int[] chunkTimestamps = new int[1024];
|
||||
private ArrayList sectorFree;
|
||||
|
||||
/** McRegion sizeDelta */
|
||||
private int sizeDelta;
|
||||
private long lastModified = 0L;
|
||||
|
||||
public RegionFile(File par1File) {
|
||||
this.fileName = par1File;
|
||||
this.sizeDelta = 0;
|
||||
|
||||
try {
|
||||
if (par1File.exists()) {
|
||||
this.lastModified = par1File.lastModified();
|
||||
}
|
||||
|
||||
this.dataFile = new RandomAccessFile(par1File, "rw");
|
||||
int var2;
|
||||
|
||||
if (this.dataFile.length() < 4096L) {
|
||||
for (var2 = 0; var2 < 1024; ++var2) {
|
||||
this.dataFile.writeInt(0);
|
||||
}
|
||||
|
||||
for (var2 = 0; var2 < 1024; ++var2) {
|
||||
this.dataFile.writeInt(0);
|
||||
}
|
||||
|
||||
this.sizeDelta += 8192;
|
||||
}
|
||||
|
||||
if ((this.dataFile.length() & 4095L) != 0L) {
|
||||
for (var2 = 0; (long) var2 < (this.dataFile.length() & 4095L); ++var2) {
|
||||
this.dataFile.write(0);
|
||||
}
|
||||
}
|
||||
|
||||
var2 = (int) this.dataFile.length() / 4096;
|
||||
this.sectorFree = new ArrayList(var2);
|
||||
int var3;
|
||||
|
||||
for (var3 = 0; var3 < var2; ++var3) {
|
||||
this.sectorFree.add(Boolean.valueOf(true));
|
||||
}
|
||||
|
||||
this.sectorFree.set(0, Boolean.valueOf(false));
|
||||
this.sectorFree.set(1, Boolean.valueOf(false));
|
||||
this.dataFile.seek(0L);
|
||||
int var4;
|
||||
|
||||
for (var3 = 0; var3 < 1024; ++var3) {
|
||||
var4 = this.dataFile.readInt();
|
||||
this.offsets[var3] = var4;
|
||||
|
||||
if (var4 != 0 && (var4 >> 8) + (var4 & 255) <= this.sectorFree.size()) {
|
||||
for (int var5 = 0; var5 < (var4 & 255); ++var5) {
|
||||
this.sectorFree.set((var4 >> 8) + var5, Boolean.valueOf(false));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (var3 = 0; var3 < 1024; ++var3) {
|
||||
var4 = this.dataFile.readInt();
|
||||
this.chunkTimestamps[var3] = var4;
|
||||
}
|
||||
} catch (IOException var6) {
|
||||
var6.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* args: x, y - get uncompressed chunk stream from the region file
|
||||
*/
|
||||
public synchronized DataInputStream getChunkDataInputStream(int par1, int par2) {
|
||||
if (this.outOfBounds(par1, par2)) {
|
||||
return null;
|
||||
} else {
|
||||
try {
|
||||
int var3 = this.getOffset(par1, par2);
|
||||
|
||||
if (var3 == 0) {
|
||||
return null;
|
||||
} else {
|
||||
int var4 = var3 >> 8;
|
||||
int var5 = var3 & 255;
|
||||
|
||||
if (var4 + var5 > this.sectorFree.size()) {
|
||||
return null;
|
||||
} else {
|
||||
this.dataFile.seek((long) (var4 * 4096));
|
||||
int var6 = this.dataFile.readInt();
|
||||
|
||||
if (var6 > 4096 * var5) {
|
||||
return null;
|
||||
} else if (var6 <= 0) {
|
||||
return null;
|
||||
} else {
|
||||
byte var7 = this.dataFile.readByte();
|
||||
byte[] var8;
|
||||
|
||||
if (var7 == 1) {
|
||||
var8 = new byte[var6 - 1];
|
||||
this.dataFile.read(var8);
|
||||
return new DataInputStream(
|
||||
new BufferedInputStream(new GZIPInputStream(new ByteArrayInputStream(var8))));
|
||||
} else if (var7 == 2) {
|
||||
var8 = new byte[var6 - 1];
|
||||
this.dataFile.read(var8);
|
||||
return new DataInputStream(new BufferedInputStream(
|
||||
new InflaterInputStream(new ByteArrayInputStream(var8))));
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException var9) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* args: x, z - get an output stream used to write chunk data, data is on disk
|
||||
* when the returned stream is closed
|
||||
*/
|
||||
public DataOutputStream getChunkDataOutputStream(int par1, int par2) {
|
||||
return this.outOfBounds(par1, par2) ? null
|
||||
: new DataOutputStream(new DeflaterOutputStream(new RegionFileChunkBuffer(this, par1, par2)));
|
||||
}
|
||||
|
||||
/**
|
||||
* args: x, z, data, length - write chunk data at (x, z) to disk
|
||||
*/
|
||||
protected synchronized void write(int par1, int par2, byte[] par3ArrayOfByte, int par4) {
|
||||
try {
|
||||
int var5 = this.getOffset(par1, par2);
|
||||
int var6 = var5 >> 8;
|
||||
int var7 = var5 & 255;
|
||||
int var8 = (par4 + 5) / 4096 + 1;
|
||||
|
||||
if (var8 >= 256) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (var6 != 0 && var7 == var8) {
|
||||
this.write(var6, par3ArrayOfByte, par4);
|
||||
} else {
|
||||
int var9;
|
||||
|
||||
for (var9 = 0; var9 < var7; ++var9) {
|
||||
this.sectorFree.set(var6 + var9, Boolean.valueOf(true));
|
||||
}
|
||||
|
||||
var9 = this.sectorFree.indexOf(Boolean.valueOf(true));
|
||||
int var10 = 0;
|
||||
int var11;
|
||||
|
||||
if (var9 != -1) {
|
||||
for (var11 = var9; var11 < this.sectorFree.size(); ++var11) {
|
||||
if (var10 != 0) {
|
||||
if (((Boolean) this.sectorFree.get(var11)).booleanValue()) {
|
||||
++var10;
|
||||
} else {
|
||||
var10 = 0;
|
||||
}
|
||||
} else if (((Boolean) this.sectorFree.get(var11)).booleanValue()) {
|
||||
var9 = var11;
|
||||
var10 = 1;
|
||||
}
|
||||
|
||||
if (var10 >= var8) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (var10 >= var8) {
|
||||
var6 = var9;
|
||||
this.setOffset(par1, par2, var9 << 8 | var8);
|
||||
|
||||
for (var11 = 0; var11 < var8; ++var11) {
|
||||
this.sectorFree.set(var6 + var11, Boolean.valueOf(false));
|
||||
}
|
||||
|
||||
this.write(var6, par3ArrayOfByte, par4);
|
||||
} else {
|
||||
this.dataFile.seek(this.dataFile.length());
|
||||
var6 = this.sectorFree.size();
|
||||
|
||||
for (var11 = 0; var11 < var8; ++var11) {
|
||||
this.dataFile.write(emptySector);
|
||||
this.sectorFree.add(Boolean.valueOf(false));
|
||||
}
|
||||
|
||||
this.sizeDelta += 4096 * var8;
|
||||
this.write(var6, par3ArrayOfByte, par4);
|
||||
this.setOffset(par1, par2, var6 << 8 | var8);
|
||||
}
|
||||
}
|
||||
|
||||
this.setChunkTimestamp(par1, par2, (int) (System.currentTimeMillis() / 1000L));
|
||||
} catch (IOException var12) {
|
||||
var12.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* args: sectorNumber, data, length - write the chunk data to this RegionFile
|
||||
*/
|
||||
private void write(int par1, byte[] par2ArrayOfByte, int par3) throws IOException {
|
||||
this.dataFile.seek((long) (par1 * 4096));
|
||||
this.dataFile.writeInt(par3 + 1);
|
||||
this.dataFile.writeByte(2);
|
||||
this.dataFile.write(par2ArrayOfByte, 0, par3);
|
||||
}
|
||||
|
||||
/**
|
||||
* args: x, z - check region bounds
|
||||
*/
|
||||
private boolean outOfBounds(int par1, int par2) {
|
||||
return par1 < 0 || par1 >= 32 || par2 < 0 || par2 >= 32;
|
||||
}
|
||||
|
||||
/**
|
||||
* args: x, y - get chunk's offset in region file
|
||||
*/
|
||||
private int getOffset(int par1, int par2) {
|
||||
return this.offsets[par1 + par2 * 32];
|
||||
}
|
||||
|
||||
/**
|
||||
* args: x, z, - true if chunk has been saved / converted
|
||||
*/
|
||||
public boolean isChunkSaved(int par1, int par2) {
|
||||
return this.getOffset(par1, par2) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* args: x, z, offset - sets the chunk's offset in the region file
|
||||
*/
|
||||
private void setOffset(int par1, int par2, int par3) throws IOException {
|
||||
this.offsets[par1 + par2 * 32] = par3;
|
||||
this.dataFile.seek((long) ((par1 + par2 * 32) * 4));
|
||||
this.dataFile.writeInt(par3);
|
||||
}
|
||||
|
||||
/**
|
||||
* args: x, z, timestamp - sets the chunk's write timestamp
|
||||
*/
|
||||
private void setChunkTimestamp(int par1, int par2, int par3) throws IOException {
|
||||
this.chunkTimestamps[par1 + par2 * 32] = par3;
|
||||
this.dataFile.seek((long) (4096 + (par1 + par2 * 32) * 4));
|
||||
this.dataFile.writeInt(par3);
|
||||
}
|
||||
|
||||
/**
|
||||
* close this RegionFile and prevent further writes
|
||||
*/
|
||||
public void close() throws IOException {
|
||||
if (this.dataFile != null) {
|
||||
this.dataFile.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
package net.minecraft.src;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
public class RegionFileCache {
|
||||
/** A map containing Files as keys and RegionFiles as values */
|
||||
private static final Map regionsByFilename = new HashMap();
|
||||
|
||||
public static synchronized RegionFile createOrLoadRegionFile(File par0File, int par1, int par2) {
|
||||
File var3 = new File(par0File, "region");
|
||||
File var4 = new File(var3, "r." + (par1 >> 5) + "." + (par2 >> 5) + ".mca");
|
||||
RegionFile var5 = (RegionFile) regionsByFilename.get(var4);
|
||||
|
||||
if (var5 != null) {
|
||||
return var5;
|
||||
} else {
|
||||
if (!var3.exists()) {
|
||||
var3.mkdirs();
|
||||
}
|
||||
|
||||
if (regionsByFilename.size() >= 256) {
|
||||
clearRegionFileReferences();
|
||||
}
|
||||
|
||||
RegionFile var6 = new RegionFile(var4);
|
||||
regionsByFilename.put(var4, var6);
|
||||
return var6;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* clears region file references
|
||||
*/
|
||||
public static synchronized void clearRegionFileReferences() {
|
||||
Iterator var0 = regionsByFilename.values().iterator();
|
||||
|
||||
while (var0.hasNext()) {
|
||||
RegionFile var1 = (RegionFile) var0.next();
|
||||
|
||||
try {
|
||||
if (var1 != null) {
|
||||
var1.close();
|
||||
}
|
||||
} catch (IOException var3) {
|
||||
var3.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
regionsByFilename.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an input stream for the specified chunk. Args: worldDir, chunkX,
|
||||
* chunkZ
|
||||
*/
|
||||
public static DataInputStream getChunkInputStream(File par0File, int par1, int par2) {
|
||||
RegionFile var3 = createOrLoadRegionFile(par0File, par1, par2);
|
||||
return var3.getChunkDataInputStream(par1 & 31, par2 & 31);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an output stream for the specified chunk. Args: worldDir, chunkX,
|
||||
* chunkZ
|
||||
*/
|
||||
public static DataOutputStream getChunkOutputStream(File par0File, int par1, int par2) {
|
||||
RegionFile var3 = createOrLoadRegionFile(par0File, par1, par2);
|
||||
return var3.getChunkDataOutputStream(par1 & 31, par2 & 31);
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
package net.minecraft.src;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
class RegionFileChunkBuffer extends ByteArrayOutputStream {
|
||||
private int chunkX;
|
||||
private int chunkZ;
|
||||
|
||||
final RegionFile regionFile;
|
||||
|
||||
public RegionFileChunkBuffer(RegionFile par1RegionFile, int par2, int par3) {
|
||||
super(8096);
|
||||
this.regionFile = par1RegionFile;
|
||||
this.chunkX = par2;
|
||||
this.chunkZ = par3;
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
this.regionFile.write(this.chunkX, this.chunkZ, this.buf, this.count);
|
||||
}
|
||||
}
|
||||
@@ -1,141 +0,0 @@
|
||||
package net.minecraft.src;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
|
||||
public class SaveFormatOld implements ISaveFormat {
|
||||
/**
|
||||
* Reference to the File object representing the directory for the world saves
|
||||
*/
|
||||
protected final File savesDirectory;
|
||||
|
||||
public SaveFormatOld(File par1File) {
|
||||
if (!par1File.exists()) {
|
||||
par1File.mkdirs();
|
||||
}
|
||||
|
||||
this.savesDirectory = par1File;
|
||||
}
|
||||
|
||||
public void flushCache() {
|
||||
}
|
||||
|
||||
/**
|
||||
* gets the world info
|
||||
*/
|
||||
public WorldInfo getWorldInfo(String par1Str) {
|
||||
File var2 = new File(this.savesDirectory, par1Str);
|
||||
|
||||
if (!var2.exists()) {
|
||||
return null;
|
||||
} else {
|
||||
File var3 = new File(var2, "level.dat");
|
||||
NBTTagCompound var4;
|
||||
NBTTagCompound var5;
|
||||
|
||||
if (var3.exists()) {
|
||||
try {
|
||||
var4 = CompressedStreamTools.readCompressed(new FileInputStream(var3));
|
||||
var5 = var4.getCompoundTag("Data");
|
||||
return new WorldInfo(var5);
|
||||
} catch (Exception var7) {
|
||||
var7.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
var3 = new File(var2, "level.dat_old");
|
||||
|
||||
if (var3.exists()) {
|
||||
try {
|
||||
var4 = CompressedStreamTools.readCompressed(new FileInputStream(var3));
|
||||
var5 = var4.getCompoundTag("Data");
|
||||
return new WorldInfo(var5);
|
||||
} catch (Exception var6) {
|
||||
var6.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @args: Takes one argument - the name of the directory of the world to
|
||||
* delete. @desc: Delete the world by deleting the associated directory
|
||||
* recursively.
|
||||
*/
|
||||
public boolean deleteWorldDirectory(String par1Str) {
|
||||
File var2 = new File(this.savesDirectory, par1Str);
|
||||
|
||||
if (!var2.exists()) {
|
||||
return true;
|
||||
} else {
|
||||
System.out.println("Deleting level " + par1Str);
|
||||
|
||||
for (int var3 = 1; var3 <= 5; ++var3) {
|
||||
System.out.println("Attempt " + var3 + "...");
|
||||
|
||||
if (deleteFiles(var2.listFiles())) {
|
||||
break;
|
||||
}
|
||||
|
||||
System.out.println("Unsuccessful in deleting contents.");
|
||||
|
||||
if (var3 < 5) {
|
||||
try {
|
||||
Thread.sleep(500L);
|
||||
} catch (InterruptedException var5) {
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return var2.delete();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @args: Takes one argument - the list of files and directories to
|
||||
* delete. @desc: Deletes the files and directory listed in the list
|
||||
* recursively.
|
||||
*/
|
||||
protected static boolean deleteFiles(File[] par0ArrayOfFile) {
|
||||
for (int var1 = 0; var1 < par0ArrayOfFile.length; ++var1) {
|
||||
File var2 = par0ArrayOfFile[var1];
|
||||
System.out.println("Deleting " + var2);
|
||||
|
||||
if (var2.isDirectory() && !deleteFiles(var2.listFiles())) {
|
||||
System.out.println("Couldn\'t delete directory " + var2);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!var2.delete()) {
|
||||
System.out.println("Couldn\'t delete file " + var2);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns back a loader for the specified save directory
|
||||
*/
|
||||
public ISaveHandler getSaveLoader(String par1Str, boolean par2) {
|
||||
return new SaveHandler(this.savesDirectory, par1Str, par2);
|
||||
}
|
||||
|
||||
/**
|
||||
* gets if the map is old chunk saving (true) or McRegion (false)
|
||||
*/
|
||||
public boolean isOldMapFormat(String par1Str) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* converts the map to mcRegion
|
||||
*/
|
||||
public boolean convertMapFormat(String par1Str, IProgressUpdate par2IProgressUpdate) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,287 +0,0 @@
|
||||
package net.minecraft.src;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
|
||||
public class SaveHandler implements ISaveHandler, IPlayerFileData {
|
||||
/** The directory in which to save world data. */
|
||||
private final File worldDirectory;
|
||||
|
||||
/** The directory in which to save player data. */
|
||||
private final File playersDirectory;
|
||||
private final File mapDataDir;
|
||||
|
||||
/**
|
||||
* The time in milliseconds when this field was initialized. Stored in the
|
||||
* session lock file.
|
||||
*/
|
||||
private final long initializationTime = System.currentTimeMillis();
|
||||
|
||||
/** The directory name of the world */
|
||||
private final String saveDirectoryName;
|
||||
|
||||
public SaveHandler(File par1File, String par2Str, boolean par3) {
|
||||
this.worldDirectory = new File(par1File, par2Str);
|
||||
this.worldDirectory.mkdirs();
|
||||
this.playersDirectory = new File(this.worldDirectory, "players");
|
||||
this.mapDataDir = new File(this.worldDirectory, "data");
|
||||
this.mapDataDir.mkdirs();
|
||||
this.saveDirectoryName = par2Str;
|
||||
|
||||
if (par3) {
|
||||
this.playersDirectory.mkdirs();
|
||||
}
|
||||
|
||||
this.setSessionLock();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a session lock file for this process
|
||||
*/
|
||||
private void setSessionLock() {
|
||||
try {
|
||||
File var1 = new File(this.worldDirectory, "session.lock");
|
||||
DataOutputStream var2 = new DataOutputStream(new FileOutputStream(var1));
|
||||
|
||||
try {
|
||||
var2.writeLong(this.initializationTime);
|
||||
} finally {
|
||||
var2.close();
|
||||
}
|
||||
} catch (IOException var7) {
|
||||
var7.printStackTrace();
|
||||
throw new RuntimeException("Failed to check session lock, aborting");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the File object corresponding to the base directory of this world.
|
||||
*/
|
||||
protected File getWorldDirectory() {
|
||||
return this.worldDirectory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the session lock to prevent save collisions
|
||||
*/
|
||||
public void checkSessionLock() throws MinecraftException {
|
||||
try {
|
||||
File var1 = new File(this.worldDirectory, "session.lock");
|
||||
DataInputStream var2 = new DataInputStream(new FileInputStream(var1));
|
||||
|
||||
try {
|
||||
if (var2.readLong() != this.initializationTime) {
|
||||
throw new MinecraftException("The save is being accessed from another location, aborting");
|
||||
}
|
||||
} finally {
|
||||
var2.close();
|
||||
}
|
||||
} catch (IOException var7) {
|
||||
throw new MinecraftException("Failed to check session lock, aborting");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* initializes and returns the chunk loader for the specified world provider
|
||||
*/
|
||||
public IChunkLoader getChunkLoader(WorldProvider par1WorldProvider) {
|
||||
throw new RuntimeException("Old Chunk Storage is no longer supported.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads and returns the world info
|
||||
*/
|
||||
public WorldInfo loadWorldInfo() {
|
||||
File var1 = new File(this.worldDirectory, "level.dat");
|
||||
NBTTagCompound var2;
|
||||
NBTTagCompound var3;
|
||||
|
||||
if (var1.exists()) {
|
||||
try {
|
||||
var2 = CompressedStreamTools.readCompressed(new FileInputStream(var1));
|
||||
var3 = var2.getCompoundTag("Data");
|
||||
return new WorldInfo(var3);
|
||||
} catch (Exception var5) {
|
||||
var5.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
var1 = new File(this.worldDirectory, "level.dat_old");
|
||||
|
||||
if (var1.exists()) {
|
||||
try {
|
||||
var2 = CompressedStreamTools.readCompressed(new FileInputStream(var1));
|
||||
var3 = var2.getCompoundTag("Data");
|
||||
return new WorldInfo(var3);
|
||||
} catch (Exception var4) {
|
||||
var4.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the given World Info with the given NBTTagCompound as the Player.
|
||||
*/
|
||||
public void saveWorldInfoWithPlayer(WorldInfo par1WorldInfo, NBTTagCompound par2NBTTagCompound) {
|
||||
NBTTagCompound var3 = par1WorldInfo.cloneNBTCompound(par2NBTTagCompound);
|
||||
NBTTagCompound var4 = new NBTTagCompound();
|
||||
var4.setTag("Data", var3);
|
||||
|
||||
try {
|
||||
File var5 = new File(this.worldDirectory, "level.dat_new");
|
||||
File var6 = new File(this.worldDirectory, "level.dat_old");
|
||||
File var7 = new File(this.worldDirectory, "level.dat");
|
||||
CompressedStreamTools.writeCompressed(var4, new FileOutputStream(var5));
|
||||
|
||||
if (var6.exists()) {
|
||||
var6.delete();
|
||||
}
|
||||
|
||||
var7.renameTo(var6);
|
||||
|
||||
if (var7.exists()) {
|
||||
var7.delete();
|
||||
}
|
||||
|
||||
var5.renameTo(var7);
|
||||
|
||||
if (var5.exists()) {
|
||||
var5.delete();
|
||||
}
|
||||
} catch (Exception var8) {
|
||||
var8.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* used to update level.dat from old format to MCRegion format
|
||||
*/
|
||||
public void saveWorldInfo(WorldInfo par1WorldInfo) {
|
||||
NBTTagCompound var2 = par1WorldInfo.getNBTTagCompound();
|
||||
NBTTagCompound var3 = new NBTTagCompound();
|
||||
var3.setTag("Data", var2);
|
||||
|
||||
try {
|
||||
File var4 = new File(this.worldDirectory, "level.dat_new");
|
||||
File var5 = new File(this.worldDirectory, "level.dat_old");
|
||||
File var6 = new File(this.worldDirectory, "level.dat");
|
||||
CompressedStreamTools.writeCompressed(var3, new FileOutputStream(var4));
|
||||
|
||||
if (var5.exists()) {
|
||||
var5.delete();
|
||||
}
|
||||
|
||||
var6.renameTo(var5);
|
||||
|
||||
if (var6.exists()) {
|
||||
var6.delete();
|
||||
}
|
||||
|
||||
var4.renameTo(var6);
|
||||
|
||||
if (var4.exists()) {
|
||||
var4.delete();
|
||||
}
|
||||
} catch (Exception var7) {
|
||||
var7.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the player data to disk from the specified PlayerEntityMP.
|
||||
*/
|
||||
public void writePlayerData(EntityPlayer par1EntityPlayer) {
|
||||
try {
|
||||
NBTTagCompound var2 = new NBTTagCompound();
|
||||
par1EntityPlayer.writeToNBT(var2);
|
||||
File var3 = new File(this.playersDirectory, par1EntityPlayer.username + ".dat.tmp");
|
||||
File var4 = new File(this.playersDirectory, par1EntityPlayer.username + ".dat");
|
||||
CompressedStreamTools.writeCompressed(var2, new FileOutputStream(var3));
|
||||
|
||||
if (var4.exists()) {
|
||||
var4.delete();
|
||||
}
|
||||
|
||||
var3.renameTo(var4);
|
||||
} catch (Exception var5) {
|
||||
MinecraftServer.getServer().getLogAgent()
|
||||
.func_98236_b("Failed to save player data for " + par1EntityPlayer.username);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the player data from disk into the specified PlayerEntityMP.
|
||||
*/
|
||||
public NBTTagCompound readPlayerData(EntityPlayer par1EntityPlayer) {
|
||||
NBTTagCompound var2 = this.getPlayerData(par1EntityPlayer.username);
|
||||
|
||||
if (var2 != null) {
|
||||
par1EntityPlayer.readFromNBT(var2);
|
||||
}
|
||||
|
||||
return var2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the player data for the given playername as a NBTTagCompound.
|
||||
*/
|
||||
public NBTTagCompound getPlayerData(String par1Str) {
|
||||
try {
|
||||
File var2 = new File(this.playersDirectory, par1Str + ".dat");
|
||||
|
||||
if (var2.exists()) {
|
||||
return CompressedStreamTools.readCompressed(new FileInputStream(var2));
|
||||
}
|
||||
} catch (Exception var3) {
|
||||
MinecraftServer.getServer().getLogAgent().func_98236_b("Failed to load player data for " + par1Str);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public IPlayerFileData getPlayerNBTManager() {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of usernames for which player.dat exists for.
|
||||
*/
|
||||
public String[] getAvailablePlayerDat() {
|
||||
String[] var1 = this.playersDirectory.list();
|
||||
|
||||
for (int var2 = 0; var2 < var1.length; ++var2) {
|
||||
if (var1[var2].endsWith(".dat")) {
|
||||
var1[var2] = var1[var2].substring(0, var1[var2].length() - 4);
|
||||
}
|
||||
}
|
||||
|
||||
return var1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to flush all changes to disk, waiting for them to complete.
|
||||
*/
|
||||
public void flush() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the file location of the given map
|
||||
*/
|
||||
public File getMapFileFromName(String par1Str) {
|
||||
return new File(this.mapDataDir, par1Str + ".dat");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the directory where world information is saved.
|
||||
*/
|
||||
public String getWorldDirectoryName() {
|
||||
return this.saveDirectoryName;
|
||||
}
|
||||
}
|
||||
@@ -1,106 +0,0 @@
|
||||
package net.minecraft.src;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import net.lax1dude.eaglercraft.sp.WorkerListenThread;
|
||||
|
||||
public class ServerListenThread extends Thread {
|
||||
private final List pendingConnections = Collections.synchronizedList(new ArrayList());
|
||||
|
||||
/**
|
||||
* This map stores a list of InetAddresses and the last time which they
|
||||
* connected at
|
||||
*/
|
||||
private final HashMap recentConnections = new HashMap();
|
||||
private int connectionCounter = 0;
|
||||
private final ServerSocket myServerSocket;
|
||||
private WorkerListenThread myNetworkListenThread;
|
||||
private final InetAddress myServerAddress;
|
||||
private final int myPort;
|
||||
|
||||
public ServerListenThread(WorkerListenThread par1NetworkListenThread, InetAddress par2InetAddress, int par3)
|
||||
throws IOException {
|
||||
super("Listen thread");
|
||||
this.myNetworkListenThread = par1NetworkListenThread;
|
||||
this.myPort = par3;
|
||||
this.myServerSocket = new ServerSocket(par3, 0, par2InetAddress);
|
||||
this.myServerAddress = par2InetAddress == null ? this.myServerSocket.getInetAddress() : par2InetAddress;
|
||||
this.myServerSocket.setPerformancePreferences(0, 2, 1);
|
||||
}
|
||||
|
||||
public void processPendingConnections() {
|
||||
List var1 = this.pendingConnections;
|
||||
|
||||
synchronized (this.pendingConnections) {
|
||||
for (int var2 = 0; var2 < this.pendingConnections.size(); ++var2) {
|
||||
NetLoginHandler var3 = (NetLoginHandler) this.pendingConnections.get(var2);
|
||||
|
||||
try {
|
||||
var3.tryLogin();
|
||||
} catch (Exception var6) {
|
||||
var3.kickUser("Internal server error");
|
||||
this.myNetworkListenThread.getServer().getLogAgent().logWarningException(
|
||||
"Failed to handle packet for " + var3.getUsernameAndAddress() + ": " + var6, var6);
|
||||
}
|
||||
|
||||
if (var3.finishedProcessing) {
|
||||
this.pendingConnections.remove(var2--);
|
||||
}
|
||||
|
||||
var3.myTCPConnection.wakeThreads();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void run() {
|
||||
while (this.myNetworkListenThread.isListening) {
|
||||
try {
|
||||
Socket var1 = this.myServerSocket.accept();
|
||||
NetLoginHandler var2 = new NetLoginHandler(this.myNetworkListenThread.getServer(), var1,
|
||||
"Connection #" + this.connectionCounter++);
|
||||
this.addPendingConnection(var2);
|
||||
} catch (IOException var3) {
|
||||
var3.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
this.myNetworkListenThread.getServer().getLogAgent().func_98233_a("Closing listening thread");
|
||||
}
|
||||
|
||||
private void addPendingConnection(NetLoginHandler par1NetLoginHandler) {
|
||||
if (par1NetLoginHandler == null) {
|
||||
throw new IllegalArgumentException("Got null pendingconnection!");
|
||||
} else {
|
||||
List var2 = this.pendingConnections;
|
||||
|
||||
synchronized (this.pendingConnections) {
|
||||
this.pendingConnections.add(par1NetLoginHandler);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void func_71769_a(InetAddress par1InetAddress) {
|
||||
if (par1InetAddress != null) {
|
||||
HashMap var2 = this.recentConnections;
|
||||
|
||||
synchronized (this.recentConnections) {
|
||||
this.recentConnections.remove(par1InetAddress);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void func_71768_b() {
|
||||
try {
|
||||
this.myServerSocket.close();
|
||||
} catch (Throwable var2) {
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,484 +0,0 @@
|
||||
package net.minecraft.src;
|
||||
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.Socket;
|
||||
import java.net.SocketAddress;
|
||||
import java.net.SocketException;
|
||||
import java.security.PrivateKey;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import javax.crypto.SecretKey;
|
||||
|
||||
public class TcpConnection implements INetworkManager {
|
||||
public static AtomicInteger field_74471_a = new AtomicInteger();
|
||||
public static AtomicInteger field_74469_b = new AtomicInteger();
|
||||
|
||||
/** The object used for synchronization on the send queue. */
|
||||
private final Object sendQueueLock = new Object();
|
||||
private final ILogAgent field_98215_i;
|
||||
|
||||
/** The socket used by this network manager. */
|
||||
private Socket networkSocket;
|
||||
|
||||
/** The InetSocketAddress of the remote endpoint */
|
||||
private final SocketAddress remoteSocketAddress;
|
||||
|
||||
/** The input stream connected to the socket. */
|
||||
private volatile DataInputStream socketInputStream;
|
||||
|
||||
/** The output stream connected to the socket. */
|
||||
private volatile DataOutputStream socketOutputStream;
|
||||
|
||||
/** Whether the network is currently operational. */
|
||||
private volatile boolean isRunning = true;
|
||||
|
||||
/**
|
||||
* Whether this network manager is currently terminating (and should ignore
|
||||
* further errors).
|
||||
*/
|
||||
private volatile boolean isTerminating = false;
|
||||
|
||||
/**
|
||||
* Linked list of packets that have been read and are awaiting processing.
|
||||
*/
|
||||
private List readPackets = Collections.synchronizedList(new ArrayList());
|
||||
|
||||
/** Linked list of packets awaiting sending. */
|
||||
private List dataPackets = Collections.synchronizedList(new ArrayList());
|
||||
|
||||
/** Linked list of packets with chunk data that are awaiting sending. */
|
||||
private List chunkDataPackets = Collections.synchronizedList(new ArrayList());
|
||||
|
||||
/** A reference to the NetHandler object. */
|
||||
private NetHandler theNetHandler;
|
||||
|
||||
/**
|
||||
* Whether this server is currently terminating. If this is a client, this is
|
||||
* always false.
|
||||
*/
|
||||
private boolean isServerTerminating = false;
|
||||
|
||||
/** The thread used for writing. */
|
||||
private Thread writeThread;
|
||||
|
||||
/** The thread used for reading. */
|
||||
private Thread readThread;
|
||||
|
||||
/** A String indicating why the network has shutdown. */
|
||||
private String terminationReason = "";
|
||||
private Object[] field_74480_w;
|
||||
private int field_74490_x = 0;
|
||||
|
||||
/**
|
||||
* The length in bytes of the packets in both send queues (data and chunkData).
|
||||
*/
|
||||
private int sendQueueByteLength = 0;
|
||||
public static int[] field_74470_c = new int[256];
|
||||
public static int[] field_74467_d = new int[256];
|
||||
public int field_74468_e = 0;
|
||||
boolean isInputBeingDecrypted = false;
|
||||
boolean isOutputEncrypted = false;
|
||||
private SecretKey sharedKeyForEncryption = null;
|
||||
private PrivateKey field_74463_A = null;
|
||||
|
||||
/**
|
||||
* Delay for sending pending chunk data packets (as opposed to pending non-chunk
|
||||
* data packets)
|
||||
*/
|
||||
private int chunkDataPacketsDelay = 50;
|
||||
|
||||
public TcpConnection(ILogAgent par1ILogAgent, Socket par2Socket, String par3Str, NetHandler par4NetHandler,
|
||||
PrivateKey par5PrivateKey) throws IOException {
|
||||
this.field_74463_A = par5PrivateKey;
|
||||
this.networkSocket = par2Socket;
|
||||
this.field_98215_i = par1ILogAgent;
|
||||
this.remoteSocketAddress = par2Socket.getRemoteSocketAddress();
|
||||
this.theNetHandler = par4NetHandler;
|
||||
|
||||
try {
|
||||
par2Socket.setSoTimeout(30000);
|
||||
par2Socket.setTrafficClass(24);
|
||||
} catch (SocketException var7) {
|
||||
System.err.println(var7.getMessage());
|
||||
}
|
||||
|
||||
this.socketInputStream = new DataInputStream(par2Socket.getInputStream());
|
||||
this.socketOutputStream = new DataOutputStream(new BufferedOutputStream(par2Socket.getOutputStream(), 5120));
|
||||
this.readThread = new TcpReaderThread(this, par3Str + " read thread");
|
||||
this.writeThread = new TcpWriterThread(this, par3Str + " write thread");
|
||||
this.readThread.start();
|
||||
this.writeThread.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the NetHandler for this NetworkManager. Server-only.
|
||||
*/
|
||||
public void setNetHandler(NetHandler par1NetHandler) {
|
||||
this.theNetHandler = par1NetHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the packet to the correct send queue (chunk data packets go to a
|
||||
* separate queue).
|
||||
*/
|
||||
public void addToSendQueue(Packet par1Packet) {
|
||||
if (!this.isServerTerminating) {
|
||||
Object var2 = this.sendQueueLock;
|
||||
|
||||
synchronized (this.sendQueueLock) {
|
||||
this.sendQueueByteLength += par1Packet.getPacketSize() + 1;
|
||||
this.dataPackets.add(par1Packet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a data packet if there is one to send, or sends a chunk data packet if
|
||||
* there is one and the counter is up, or does nothing.
|
||||
*/
|
||||
private boolean sendPacket() {
|
||||
boolean var1 = false;
|
||||
|
||||
try {
|
||||
int[] var10000;
|
||||
int var10001;
|
||||
Packet var2;
|
||||
|
||||
if (this.field_74468_e == 0 || !this.dataPackets.isEmpty() && System.currentTimeMillis()
|
||||
- ((Packet) this.dataPackets.get(0)).creationTimeMillis >= (long) this.field_74468_e) {
|
||||
var2 = this.func_74460_a(false);
|
||||
|
||||
if (var2 != null) {
|
||||
Packet.writePacket(var2, this.socketOutputStream);
|
||||
|
||||
if (var2 instanceof Packet252SharedKey && !this.isOutputEncrypted) {
|
||||
if (!this.theNetHandler.isServerHandler()) {
|
||||
this.sharedKeyForEncryption = ((Packet252SharedKey) var2).getSharedKey();
|
||||
}
|
||||
|
||||
this.encryptOuputStream();
|
||||
}
|
||||
|
||||
var10000 = field_74467_d;
|
||||
var10001 = var2.getPacketId();
|
||||
var10000[var10001] += var2.getPacketSize() + 1;
|
||||
var1 = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.chunkDataPacketsDelay-- <= 0 && (this.field_74468_e == 0
|
||||
|| !this.chunkDataPackets.isEmpty() && System.currentTimeMillis() - ((Packet) this.chunkDataPackets
|
||||
.get(0)).creationTimeMillis >= (long) this.field_74468_e)) {
|
||||
var2 = this.func_74460_a(true);
|
||||
|
||||
if (var2 != null) {
|
||||
Packet.writePacket(var2, this.socketOutputStream);
|
||||
var10000 = field_74467_d;
|
||||
var10001 = var2.getPacketId();
|
||||
var10000[var10001] += var2.getPacketSize() + 1;
|
||||
this.chunkDataPacketsDelay = 0;
|
||||
var1 = true;
|
||||
}
|
||||
}
|
||||
|
||||
return var1;
|
||||
} catch (Exception var3) {
|
||||
if (!this.isTerminating) {
|
||||
this.onNetworkError(var3);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private Packet func_74460_a(boolean par1) {
|
||||
Packet var2 = null;
|
||||
List var3 = par1 ? this.chunkDataPackets : this.dataPackets;
|
||||
Object var4 = this.sendQueueLock;
|
||||
|
||||
synchronized (this.sendQueueLock) {
|
||||
while (!var3.isEmpty() && var2 == null) {
|
||||
var2 = (Packet) var3.remove(0);
|
||||
this.sendQueueByteLength -= var2.getPacketSize() + 1;
|
||||
|
||||
if (this.func_74454_a(var2, par1)) {
|
||||
var2 = null;
|
||||
}
|
||||
}
|
||||
|
||||
return var2;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean func_74454_a(Packet par1Packet, boolean par2) {
|
||||
if (!par1Packet.isRealPacket()) {
|
||||
return false;
|
||||
} else {
|
||||
List var3 = par2 ? this.chunkDataPackets : this.dataPackets;
|
||||
Iterator var4 = var3.iterator();
|
||||
Packet var5;
|
||||
|
||||
do {
|
||||
if (!var4.hasNext()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var5 = (Packet) var4.next();
|
||||
} while (var5.getPacketId() != par1Packet.getPacketId());
|
||||
|
||||
return par1Packet.containsSameEntityIDAs(var5);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wakes reader and writer threads
|
||||
*/
|
||||
public void wakeThreads() {
|
||||
if (this.readThread != null) {
|
||||
this.readThread.interrupt();
|
||||
}
|
||||
|
||||
if (this.writeThread != null) {
|
||||
this.writeThread.interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a single packet from the input stream and adds it to the read queue. If
|
||||
* no packet is read, it shuts down the network.
|
||||
*/
|
||||
private boolean readPacket() {
|
||||
boolean var1 = false;
|
||||
|
||||
try {
|
||||
Packet var2 = Packet.readPacket(this.field_98215_i, this.socketInputStream,
|
||||
this.theNetHandler.isServerHandler(), this.networkSocket);
|
||||
|
||||
if (var2 != null) {
|
||||
if (var2 instanceof Packet252SharedKey && !this.isInputBeingDecrypted) {
|
||||
if (this.theNetHandler.isServerHandler()) {
|
||||
this.sharedKeyForEncryption = ((Packet252SharedKey) var2).getSharedKey(this.field_74463_A);
|
||||
}
|
||||
|
||||
this.decryptInputStream();
|
||||
}
|
||||
|
||||
int[] var10000 = field_74470_c;
|
||||
int var10001 = var2.getPacketId();
|
||||
var10000[var10001] += var2.getPacketSize() + 1;
|
||||
|
||||
if (!this.isServerTerminating) {
|
||||
if (var2.canProcessAsync() && this.theNetHandler.canProcessPacketsAsync()) {
|
||||
this.field_74490_x = 0;
|
||||
var2.processPacket(this.theNetHandler);
|
||||
} else {
|
||||
this.readPackets.add(var2);
|
||||
}
|
||||
}
|
||||
|
||||
var1 = true;
|
||||
} else {
|
||||
this.networkShutdown("disconnect.endOfStream", new Object[0]);
|
||||
}
|
||||
|
||||
return var1;
|
||||
} catch (Exception var3) {
|
||||
if (!this.isTerminating) {
|
||||
this.onNetworkError(var3);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to report network errors and causes a network shutdown.
|
||||
*/
|
||||
private void onNetworkError(Exception par1Exception) {
|
||||
par1Exception.printStackTrace();
|
||||
this.networkShutdown("disconnect.genericReason",
|
||||
new Object[] { "Internal exception: " + par1Exception.toString() });
|
||||
}
|
||||
|
||||
/**
|
||||
* Shuts down the network with the specified reason. Closes all streams and
|
||||
* sockets, spawns NetworkMasterThread to stop reading and writing threads.
|
||||
*/
|
||||
public void networkShutdown(String par1Str, Object... par2ArrayOfObj) {
|
||||
if (this.isRunning) {
|
||||
this.isTerminating = true;
|
||||
this.terminationReason = par1Str;
|
||||
this.field_74480_w = par2ArrayOfObj;
|
||||
this.isRunning = false;
|
||||
(new TcpMasterThread(this)).start();
|
||||
|
||||
try {
|
||||
this.socketInputStream.close();
|
||||
} catch (Throwable var6) {
|
||||
;
|
||||
}
|
||||
|
||||
try {
|
||||
this.socketOutputStream.close();
|
||||
} catch (Throwable var5) {
|
||||
;
|
||||
}
|
||||
|
||||
try {
|
||||
this.networkSocket.close();
|
||||
} catch (Throwable var4) {
|
||||
;
|
||||
}
|
||||
|
||||
this.socketInputStream = null;
|
||||
this.socketOutputStream = null;
|
||||
this.networkSocket = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks timeouts and processes all pending read packets.
|
||||
*/
|
||||
public void processReadPackets() {
|
||||
if (this.sendQueueByteLength > 2097152) {
|
||||
this.networkShutdown("disconnect.overflow", new Object[0]);
|
||||
}
|
||||
|
||||
if (this.readPackets.isEmpty()) {
|
||||
if (this.field_74490_x++ == 1200) {
|
||||
this.networkShutdown("disconnect.timeout", new Object[0]);
|
||||
}
|
||||
} else {
|
||||
this.field_74490_x = 0;
|
||||
}
|
||||
|
||||
int var1 = 1000;
|
||||
|
||||
while (!this.readPackets.isEmpty() && var1-- >= 0) {
|
||||
Packet var2 = (Packet) this.readPackets.remove(0);
|
||||
var2.processPacket(this.theNetHandler);
|
||||
}
|
||||
|
||||
this.wakeThreads();
|
||||
|
||||
if (this.isTerminating && this.readPackets.isEmpty()) {
|
||||
this.theNetHandler.handleErrorMessage(this.terminationReason, this.field_74480_w);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the socket address of the remote side. Server-only.
|
||||
*/
|
||||
public SocketAddress getRemoteAddress() {
|
||||
return this.remoteSocketAddress;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shuts down the server. (Only actually used on the server)
|
||||
*/
|
||||
public void serverShutdown() {
|
||||
if (!this.isServerTerminating) {
|
||||
this.wakeThreads();
|
||||
this.isServerTerminating = true;
|
||||
this.readThread.interrupt();
|
||||
(new TcpMonitorThread(this)).start();
|
||||
}
|
||||
}
|
||||
|
||||
private void decryptInputStream() throws IOException {
|
||||
this.isInputBeingDecrypted = true;
|
||||
InputStream var1 = this.networkSocket.getInputStream();
|
||||
this.socketInputStream = new DataInputStream(
|
||||
CryptManager.decryptInputStream(this.sharedKeyForEncryption, var1));
|
||||
}
|
||||
|
||||
/**
|
||||
* flushes the stream and replaces it with an encryptedOutputStream
|
||||
*/
|
||||
private void encryptOuputStream() throws IOException {
|
||||
this.socketOutputStream.flush();
|
||||
this.isOutputEncrypted = true;
|
||||
BufferedOutputStream var1 = new BufferedOutputStream(
|
||||
CryptManager.encryptOuputStream(this.sharedKeyForEncryption, this.networkSocket.getOutputStream()),
|
||||
5120);
|
||||
this.socketOutputStream = new DataOutputStream(var1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of chunk data packets waiting to be sent.
|
||||
*/
|
||||
public int getNumChunkDataPackets() {
|
||||
return this.chunkDataPackets.size();
|
||||
}
|
||||
|
||||
public Socket getSocket() {
|
||||
return this.networkSocket;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the network is operational.
|
||||
*/
|
||||
static boolean isRunning(TcpConnection par0TcpConnection) {
|
||||
return par0TcpConnection.isRunning;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the server terminating? Client side aways returns false.
|
||||
*/
|
||||
static boolean isServerTerminating(TcpConnection par0TcpConnection) {
|
||||
return par0TcpConnection.isServerTerminating;
|
||||
}
|
||||
|
||||
/**
|
||||
* Static accessor to readPacket.
|
||||
*/
|
||||
static boolean readNetworkPacket(TcpConnection par0TcpConnection) {
|
||||
return par0TcpConnection.readPacket();
|
||||
}
|
||||
|
||||
/**
|
||||
* Static accessor to sendPacket.
|
||||
*/
|
||||
static boolean sendNetworkPacket(TcpConnection par0TcpConnection) {
|
||||
return par0TcpConnection.sendPacket();
|
||||
}
|
||||
|
||||
static DataOutputStream getOutputStream(TcpConnection par0TcpConnection) {
|
||||
return par0TcpConnection.socketOutputStream;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether the Network manager is terminating.
|
||||
*/
|
||||
static boolean isTerminating(TcpConnection par0TcpConnection) {
|
||||
return par0TcpConnection.isTerminating;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the network manager an error
|
||||
*/
|
||||
static void sendError(TcpConnection par0TcpConnection, Exception par1Exception) {
|
||||
par0TcpConnection.onNetworkError(par1Exception);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the read thread.
|
||||
*/
|
||||
static Thread getReadThread(TcpConnection par0TcpConnection) {
|
||||
return par0TcpConnection.readThread;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the write thread.
|
||||
*/
|
||||
static Thread getWriteThread(TcpConnection par0TcpConnection) {
|
||||
return par0TcpConnection.writeThread;
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
package net.minecraft.src;
|
||||
|
||||
class TcpMasterThread extends Thread {
|
||||
final TcpConnection theTcpConnection;
|
||||
|
||||
TcpMasterThread(TcpConnection par1TcpConnection) {
|
||||
this.theTcpConnection = par1TcpConnection;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public void run() {
|
||||
try {
|
||||
Thread.sleep(5000L);
|
||||
|
||||
if (TcpConnection.getReadThread(this.theTcpConnection).isAlive()) {
|
||||
try {
|
||||
TcpConnection.getReadThread(this.theTcpConnection).stop();
|
||||
} catch (Throwable var3) {
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
if (TcpConnection.getWriteThread(this.theTcpConnection).isAlive()) {
|
||||
try {
|
||||
TcpConnection.getWriteThread(this.theTcpConnection).stop();
|
||||
} catch (Throwable var2) {
|
||||
;
|
||||
}
|
||||
}
|
||||
} catch (InterruptedException var4) {
|
||||
var4.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
package net.minecraft.src;
|
||||
|
||||
class TcpMonitorThread extends Thread {
|
||||
final TcpConnection theTcpConnection;
|
||||
|
||||
TcpMonitorThread(TcpConnection par1TcpConnection) {
|
||||
this.theTcpConnection = par1TcpConnection;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
try {
|
||||
Thread.sleep(2000L);
|
||||
|
||||
if (TcpConnection.isRunning(this.theTcpConnection)) {
|
||||
TcpConnection.getWriteThread(this.theTcpConnection).interrupt();
|
||||
this.theTcpConnection.networkShutdown("disconnect.closed", new Object[0]);
|
||||
}
|
||||
} catch (Exception var2) {
|
||||
var2.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
package net.minecraft.src;
|
||||
|
||||
class TcpReaderThread extends Thread {
|
||||
final TcpConnection theTcpConnection;
|
||||
|
||||
TcpReaderThread(TcpConnection par1TcpConnection, String par2Str) {
|
||||
super(par2Str);
|
||||
this.theTcpConnection = par1TcpConnection;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
TcpConnection.field_74471_a.getAndIncrement();
|
||||
|
||||
try {
|
||||
while (TcpConnection.isRunning(this.theTcpConnection)
|
||||
&& !TcpConnection.isServerTerminating(this.theTcpConnection)) {
|
||||
while (true) {
|
||||
if (!TcpConnection.readNetworkPacket(this.theTcpConnection)) {
|
||||
try {
|
||||
sleep(2L);
|
||||
} catch (InterruptedException var5) {
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
TcpConnection.field_74471_a.getAndDecrement();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
package net.minecraft.src;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
class TcpWriterThread extends Thread {
|
||||
final TcpConnection theTcpConnection;
|
||||
|
||||
TcpWriterThread(TcpConnection par1TcpConnection, String par2Str) {
|
||||
super(par2Str);
|
||||
this.theTcpConnection = par1TcpConnection;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
TcpConnection.field_74469_b.getAndIncrement();
|
||||
|
||||
try {
|
||||
while (TcpConnection.isRunning(this.theTcpConnection)) {
|
||||
boolean var1;
|
||||
|
||||
for (var1 = false; TcpConnection.sendNetworkPacket(this.theTcpConnection); var1 = true) {
|
||||
;
|
||||
}
|
||||
|
||||
try {
|
||||
if (var1 && TcpConnection.getOutputStream(this.theTcpConnection) != null) {
|
||||
TcpConnection.getOutputStream(this.theTcpConnection).flush();
|
||||
}
|
||||
} catch (IOException var8) {
|
||||
if (!TcpConnection.isTerminating(this.theTcpConnection)) {
|
||||
TcpConnection.sendError(this.theTcpConnection, var8);
|
||||
}
|
||||
|
||||
var8.printStackTrace();
|
||||
}
|
||||
|
||||
try {
|
||||
sleep(2L);
|
||||
} catch (InterruptedException var7) {
|
||||
;
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
TcpConnection.field_74469_b.getAndDecrement();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user