diff --git a/src/main/java/net/minecraft/world/World.java b/src/main/java/net/minecraft/world/World.java index 37c9acd..ce3e84b 100644 --- a/src/main/java/net/minecraft/world/World.java +++ b/src/main/java/net/minecraft/world/World.java @@ -72,7 +72,7 @@ public abstract class World implements IBlockAccess { - /** +/** * Used in the getEntitiesWithinAABB functions to expand the search area for entities. * Modders should change this variable to a higher value if it is less then the radius * of one of there entities. @@ -334,7 +334,7 @@ public Block getBlock(int p_147439_1_, int p_147439_2_, int p_147439_3_) { - if (p_147439_1_ >= -30000000 && p_147439_3_ >= -30000000 && p_147439_1_ < 30000000 && p_147439_3_ < 30000000 && p_147439_2_ >= 0 && p_147439_2_ < 256) + if (p_147439_1_ >= -MAX_BLOCK_COORD && p_147439_3_ >= -MAX_BLOCK_COORD && p_147439_1_ < MAX_BLOCK_COORD && p_147439_3_ < MAX_BLOCK_COORD && p_147439_2_ >= 0 && p_147439_2_ < 256) { Chunk chunk = null; @@ -419,7 +419,7 @@ public boolean setBlock(int p_147465_1_, int p_147465_2_, int p_147465_3_, Block p_147465_4_, int p_147465_5_, int p_147465_6_) { - if (p_147465_1_ >= -30000000 && p_147465_3_ >= -30000000 && p_147465_1_ < 30000000 && p_147465_3_ < 30000000) + if (p_147465_1_ >= -MAX_BLOCK_COORD && p_147465_3_ >= -MAX_BLOCK_COORD && p_147465_1_ < MAX_BLOCK_COORD && p_147465_3_ < MAX_BLOCK_COORD) { if (p_147465_2_ < 0) { @@ -473,7 +473,7 @@ public int getBlockMetadata(int par1, int par2, int par3) { - if (par1 >= -30000000 && par3 >= -30000000 && par1 < 30000000 && par3 < 30000000) + if (par1 >= -MAX_BLOCK_COORD && par3 >= -MAX_BLOCK_COORD && par1 < MAX_BLOCK_COORD && par3 < MAX_BLOCK_COORD) { if (par2 < 0) { @@ -499,7 +499,7 @@ public boolean setBlockMetadataWithNotify(int par1, int par2, int par3, int par4, int par5) { - if (par1 >= -30000000 && par3 >= -30000000 && par1 < 30000000 && par3 < 30000000) + if (par1 >= -MAX_BLOCK_COORD && par3 >= -MAX_BLOCK_COORD && par1 < MAX_BLOCK_COORD && par3 < MAX_BLOCK_COORD) { if (par2 < 0) { @@ -743,7 +743,7 @@ public int getBlockLightValue_do(int par1, int par2, int par3, boolean par4) { - if (par1 >= -30000000 && par3 >= -30000000 && par1 < 30000000 && par3 < 30000000) + if (par1 >= -MAX_BLOCK_COORD && par3 >= -MAX_BLOCK_COORD && par1 < MAX_BLOCK_COORD && par3 < MAX_BLOCK_COORD) { if (par4 && this.getBlock(par1, par2, par3).getUseNeighborBrightness()) { @@ -800,7 +800,7 @@ public int getHeightValue(int par1, int par2) { - if (par1 >= -30000000 && par2 >= -30000000 && par1 < 30000000 && par2 < 30000000) + if (par1 >= -MAX_BLOCK_COORD && par2 >= -MAX_BLOCK_COORD && par1 < MAX_BLOCK_COORD && par2 < MAX_BLOCK_COORD) { if (!this.chunkExists(par1 >> 4, par2 >> 4)) { @@ -820,7 +820,7 @@ public int getChunkHeightMapMinimum(int par1, int par2) { - if (par1 >= -30000000 && par2 >= -30000000 && par1 < 30000000 && par2 < 30000000) + if (par1 >= -MAX_BLOCK_COORD && par2 >= -MAX_BLOCK_COORD && par1 < MAX_BLOCK_COORD && par2 < MAX_BLOCK_COORD) { if (!this.chunkExists(par1 >> 4, par2 >> 4)) { @@ -856,7 +856,7 @@ { return par1EnumSkyBlock.defaultLightValue; } - else if (par2 >= -30000000 && par4 >= -30000000 && par2 < 30000000 && par4 < 30000000) + else if (par2 >= -MAX_BLOCK_COORD && par4 >= -MAX_BLOCK_COORD && par2 < MAX_BLOCK_COORD && par4 < MAX_BLOCK_COORD) { int l = par2 >> 4; int i1 = par4 >> 4; @@ -920,7 +920,7 @@ par3 = 255; } - if (par2 >= -30000000 && par4 >= -30000000 && par2 < 30000000 && par4 < 30000000) + if (par2 >= -MAX_BLOCK_COORD && par4 >= -MAX_BLOCK_COORD && par2 < MAX_BLOCK_COORD && par4 < MAX_BLOCK_COORD) { int l = par2 >> 4; int i1 = par4 >> 4; @@ -943,7 +943,7 @@ public void setLightValue(EnumSkyBlock par1EnumSkyBlock, int par2, int par3, int par4, int par5) { - if (par2 >= -30000000 && par4 >= -30000000 && par2 < 30000000 && par4 < 30000000) + if (par2 >= -MAX_BLOCK_COORD && par4 >= -MAX_BLOCK_COORD && par2 < MAX_BLOCK_COORD && par4 < MAX_BLOCK_COORD) { if (par3 >= 0) { @@ -1398,7 +1398,7 @@ { Block block; - if (k1 >= -30000000 && k1 < 30000000 && l1 >= -30000000 && l1 < 30000000) + if (k1 >= -MAX_BLOCK_COORD && k1 < MAX_BLOCK_COORD && l1 >= -MAX_BLOCK_COORD && l1 < MAX_BLOCK_COORD) { block = this.getBlock(k1, i2, l1); } @@ -1456,7 +1456,7 @@ { Block block; - if (k1 >= -30000000 && k1 < 30000000 && l1 >= -30000000 && l1 < 30000000) + if (k1 >= -MAX_BLOCK_COORD && k1 < MAX_BLOCK_COORD && l1 >= -MAX_BLOCK_COORD && l1 < MAX_BLOCK_COORD) { block = this.getBlock(k1, i2, l1); } @@ -1925,7 +1925,7 @@ { for (Object tile : field_147483_b) { - ((TileEntity)tile).onChunkUnload(); + ((TileEntity)tile).onChunkUnload(); } this.loadedTileEntityList.removeAll(this.field_147483_b); this.field_147483_b.clear(); @@ -2569,7 +2569,7 @@ public boolean isBlockNormalCubeDefault(int p_147445_1_, int p_147445_2_, int p_147445_3_, boolean p_147445_4_) { - if (p_147445_1_ >= -30000000 && p_147445_3_ >= -30000000 && p_147445_1_ < 30000000 && p_147445_3_ < 30000000) + if (p_147445_1_ >= -MAX_BLOCK_COORD && p_147445_3_ >= -MAX_BLOCK_COORD && p_147445_1_ < MAX_BLOCK_COORD && p_147445_3_ < MAX_BLOCK_COORD) { Chunk chunk = this.chunkProvider.provideChunk(p_147445_1_ >> 4, p_147445_3_ >> 4); @@ -3357,7 +3357,7 @@ public int getIndirectPowerLevelTo(int par1, int par2, int par3, int par4) { - Block block = this.getBlock(par1, par2, par3); + Block block = this.getBlock(par1, par2, par3); return block.shouldCheckWeakPower(this, par1, par2, par3, par4) ? this.getBlockPowerInput(par1, par2, par3) : block.isProvidingWeakPower(this, par1, par2, par3, par4); } @@ -3893,7 +3893,7 @@ @Override public boolean isSideSolid(int x, int y, int z, ForgeDirection side, boolean _default) { - if (x < -30000000 || z < -30000000 || x >= 30000000 || z >= 30000000) + if (x < -MAX_BLOCK_COORD || z < -MAX_BLOCK_COORD || x >= MAX_BLOCK_COORD || z >= MAX_BLOCK_COORD) { return _default; } @@ -3926,7 +3926,7 @@ */ public int getBlockLightOpacity(int x, int y, int z) { - if (x < -30000000 || z < -30000000 || x >= 30000000 || z >= 30000000) + if (x < -MAX_BLOCK_COORD || z < -MAX_BLOCK_COORD || x >= MAX_BLOCK_COORD || z >= MAX_BLOCK_COORD) { return 0; } @@ -3954,4 +3954,11 @@ } return count; } + + + + /* ======================================== ULTRAMINE START =====================================*/ + + + private static final int MAX_BLOCK_COORD = 500000;//524288; } \ No newline at end of file diff --git a/src/main/java/net/minecraft/world/gen/ChunkProviderServer.java b/src/main/java/net/minecraft/world/gen/ChunkProviderServer.java index 1027427..28549d8 100644 --- a/src/main/java/net/minecraft/world/gen/ChunkProviderServer.java +++ b/src/main/java/net/minecraft/world/gen/ChunkProviderServer.java @@ -1,5 +1,11 @@ package net.minecraft.world.gen; +import gnu.trove.iterator.TIntIterator; +import gnu.trove.map.TIntObjectMap; +import gnu.trove.map.hash.TIntObjectHashMap; +import gnu.trove.set.TIntSet; +import gnu.trove.set.hash.TIntHashSet; + import java.io.IOException; import java.util.ArrayList; import java.util.HashSet; @@ -26,19 +32,20 @@ import net.minecraft.world.chunk.storage.IChunkLoader; import net.minecraftforge.common.DimensionManager; import net.minecraftforge.common.ForgeChunkManager; + import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.ultramine.server.chunk.ChunkHash; public class ChunkProviderServer implements IChunkProvider { private static final Logger logger = LogManager.getLogger(); - private Set chunksToUnload = new HashSet(); + private TIntSet chunksToUnload = new TIntHashSet(); private Chunk defaultEmptyChunk; private IChunkProvider currentChunkProvider; public IChunkLoader currentChunkLoader; public boolean loadChunkOnProvideRequest = true; - private LongHashMap loadedChunkHashMap = new LongHashMap(); - private List loadedChunks = new ArrayList(); + private TIntObjectMap loadedChunkHashMap = new TIntObjectHashMap(); private WorldServer worldObj; private static final String __OBFID = "CL_00001436"; @@ -52,7 +59,7 @@ public boolean chunkExists(int par1, int par2) { - return this.loadedChunkHashMap.containsItem(ChunkCoordIntPair.chunkXZ2Int(par1, par2)); + return this.loadedChunkHashMap.containsKey(ChunkHash.chunkToKey(par1, par2)); } public void unloadChunksIfNotNearSpawn(int par1, int par2) @@ -66,31 +73,31 @@ if (k < -short1 || k > short1 || l < -short1 || l > short1) { - this.chunksToUnload.add(Long.valueOf(ChunkCoordIntPair.chunkXZ2Int(par1, par2))); + this.chunksToUnload.add(ChunkHash.chunkToKey(par1, par2)); } } else { - this.chunksToUnload.add(Long.valueOf(ChunkCoordIntPair.chunkXZ2Int(par1, par2))); + this.chunksToUnload.add(ChunkHash.chunkToKey(par1, par2)); } } public void unloadAllChunks() { - Iterator iterator = this.loadedChunks.iterator(); + //Iterator iterator = this.loadedChunks.iterator(); - while (iterator.hasNext()) - { - Chunk chunk = (Chunk)iterator.next(); - this.unloadChunksIfNotNearSpawn(chunk.xPosition, chunk.zPosition); - } + //while (iterator.hasNext()) + //{ + // Chunk chunk = (Chunk)iterator.next(); + // this.unloadChunksIfNotNearSpawn(chunk.xPosition, chunk.zPosition); + //} } public Chunk loadChunk(int par1, int par2) { - long k = ChunkCoordIntPair.chunkXZ2Int(par1, par2); - this.chunksToUnload.remove(Long.valueOf(k)); - Chunk chunk = (Chunk)this.loadedChunkHashMap.getValueByKey(k); + int k = ChunkHash.chunkToKey(par1, par2); + this.chunksToUnload.remove(k); + Chunk chunk = (Chunk)this.loadedChunkHashMap.get(k); if (chunk == null) { @@ -124,8 +131,7 @@ } } - this.loadedChunkHashMap.add(k, chunk); - this.loadedChunks.add(chunk); + this.loadedChunkHashMap.put(k, chunk); chunk.onChunkLoad(); chunk.populateChunk(this, this, par1, par2); } @@ -135,7 +141,7 @@ public Chunk provideChunk(int par1, int par2) { - Chunk chunk = (Chunk)this.loadedChunkHashMap.getValueByKey(ChunkCoordIntPair.chunkXZ2Int(par1, par2)); + Chunk chunk = this.loadedChunkHashMap.get(ChunkHash.chunkToKey(par1, par2)); return chunk == null ? (!this.worldObj.findingSpawnPoint && !this.loadChunkOnProvideRequest ? this.defaultEmptyChunk : this.loadChunk(par1, par2)) : chunk; } @@ -227,10 +233,8 @@ { int i = 0; - for (int j = 0; j < this.loadedChunks.size(); ++j) + for (Chunk chunk : loadedChunkHashMap.valueCollection()) { - Chunk chunk = (Chunk)this.loadedChunks.get(j); - if (par1) { this.safeSaveExtraChunkData(chunk); @@ -266,9 +270,10 @@ { for (ChunkCoordIntPair forced : this.worldObj.getPersistentChunks().keySet()) { - this.chunksToUnload.remove(ChunkCoordIntPair.chunkXZ2Int(forced.chunkXPos, forced.chunkZPos)); + this.chunksToUnload.remove(ChunkHash.chunkToKey(forced.chunkXPos, forced.chunkZPos)); } + /* for (int i = 0; i < 100; ++i) { if (!this.chunksToUnload.isEmpty()) @@ -288,6 +293,36 @@ } } } + */ + + int processed = 0; + for(TIntIterator it = chunksToUnload.iterator(); it.hasNext();) + { + if(processed >= 20) break; + int hash = it.next(); + Chunk chunk = loadedChunkHashMap.get(hash); + if(chunk != null) + { + if(true/*chunk.getBindReason().canUnload()*/) + { + chunk.onChunkUnload(); + if(true/*chunk.shouldSaveOnUnload()*/) + { + processed++; + safeSaveChunk(chunk); + } + this.safeSaveExtraChunkData(chunk); + this.loadedChunkHashMap.remove(hash); + //chunk.postChunkUnload(); + } + } + else + { + logger.warn("Not existing chunk was queued for unload (" + ChunkHash.keyToX(hash) + ", " + ChunkHash.keyToZ(hash) + ")"); + } + + it.remove(); + } if (this.currentChunkLoader != null) { @@ -305,7 +340,7 @@ public String makeString() { - return "ServerChunkCache: " + this.loadedChunkHashMap.getNumHashElements() + " Drop: " + this.chunksToUnload.size(); + return "ServerChunkCache: " + this.loadedChunkHashMap.size() + " Drop: " + this.chunksToUnload.size(); } public List getPossibleCreatures(EnumCreatureType par1EnumCreatureType, int par2, int par3, int par4) @@ -320,7 +355,7 @@ public int getLoadedChunkCount() { - return this.loadedChunkHashMap.getNumHashElements(); + return this.loadedChunkHashMap.size(); } public void recreateStructures(int par1, int par2) {} diff --git a/src/main/java/org/ultramine/server/chunk/ChunkHash.java b/src/main/java/org/ultramine/server/chunk/ChunkHash.java new file mode 100644 index 0000000..3705c60 --- /dev/null +++ b/src/main/java/org/ultramine/server/chunk/ChunkHash.java @@ -0,0 +1,23 @@ +package org.ultramine.server.chunk; + +public class ChunkHash +{ + public static int chunkToKey(int x, int z) + { + return (x & 0xffff) << 16 | (z & 0xffff); + } + + public static int keyToX(int k) + { + return (short)((k >> 16) & 0xffff); + } + public static int keyToZ(int k) + { + return (short)(k & 0xffff); + } + + public static short chunkCoordToHash(int x, int y, int z) + { + return (short)(((x&15)<<12) | ((z&15)<<8) | (y&255)); + } +}