diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java new file mode 100644 index 0000000000..816ae774c5 --- /dev/null +++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java @@ -0,0 +1,226 @@ +package net.minecraft.server; + + +import java.io.IOException; +import java.util.*; +import org.bukkit.craftbukkit.CraftChunk; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.craftbukkit.CraftWorld; +import org.bukkit.event.Event.Type; +import org.bukkit.event.world.ChunkLoadedEvent; + + +public class ChunkProviderServer + implements IChunkProvider { + + private Set a; + private Chunk b; + private IChunkProvider c; + private IChunkLoader d; + private Map e; + private List f; + private WorldServer g; + + public ChunkProviderServer(WorldServer worldserver, IChunkLoader ichunkloader, IChunkProvider ichunkprovider) { + a = new HashSet(); + e = new HashMap(); + f = new ArrayList(); + b = new Chunk(worldserver, new byte[32768], 0, 0); + b.q = true; + b.p = true; + g = worldserver; + d = ichunkloader; + c = ichunkprovider; + } + + public boolean a(int i, int j) { + ChunkCoordinates chunkcoordinates = new ChunkCoordinates(i, j); + + return e.containsKey(chunkcoordinates); + } + + public void c(int i, int j) { + int k = (i * 16 + 8) - g.m; + int l = (j * 16 + 8) - g.o; + char c1 = '\200'; + + if (k < -c1 || k > c1 || l < -c1 || l > c1) { + a.add(new ChunkCoordinates(i, j)); + } + } + + public Chunk d(int i, int j) { + ChunkCoordinates chunkcoordinates = new ChunkCoordinates(i, j); + + a.remove(new ChunkCoordinates(i, j)); + Chunk chunk = (Chunk) e.get(chunkcoordinates); + + if (chunk == null) { + chunk = e(i, j); + if (chunk == null) { + if (c == null) { + chunk = b; + } else { + chunk = c.b(i, j); + } + } + e.put(chunkcoordinates, chunk); + f.add(chunk); + chunk.c(); + if (chunk != null) { + chunk.d(); + } + + // Craftbukkit start + CraftServer server = g.getServer(); + if (server != null) { + /* + * If it's a new world, the first few chunks are generated inside + * the World constructor. We can't reliably alter that, so we have + * no way of creating a CraftWorld/CraftServer at that point. + */ + CraftWorld world = g.getWorld(); + CraftChunk cchunk = world.updateChunk(i, j); + server.getPluginManager().callEvent(new ChunkLoadedEvent(Type.CHUNK_LOADED, cchunk)); + } + // Craftbukkit end + + if (!chunk.n && a(i + 1, j + 1) && a(i, j + 1) && a(i + 1, j)) { + a(this, i, j); + } + if (a(i - 1, j) && !b(i - 1, j).n && a(i - 1, j + 1) && a(i, j + 1) && a(i - 1, j)) { + a(this, i - 1, j); + } + if (a(i, j - 1) && !b(i, j - 1).n && a(i + 1, j - 1) && a(i, j - 1) && a(i + 1, j)) { + a(this, i, j - 1); + } + if (a(i - 1, j - 1) && !b(i - 1, j - 1).n && a(i - 1, j - 1) && a(i, j - 1) && a(i - 1, j)) { + a(this, i - 1, j - 1); + } + } + return chunk; + } + + public Chunk b(int i, int j) { + ChunkCoordinates chunkcoordinates = new ChunkCoordinates(i, j); + Chunk chunk = (Chunk) e.get(chunkcoordinates); + + if (chunk == null) { + if (g.x) { + return d(i, j); + } else { + return b; + } + } else { + return chunk; + } + } + + private Chunk e(int i, int j) { + if (d == null) { + return null; + } + try { + Chunk chunk = d.a(g, i, j); + + if (chunk != null) { + chunk.s = g.e; + } + return chunk; + } catch (Exception exception) { + exception.printStackTrace(); + } + return null; + } + + private void a(Chunk chunk) { + if (d == null) { + return; + } + try { + d.b(g, chunk); + } catch (Exception exception) { + exception.printStackTrace(); + } + } + + private void b(Chunk chunk) { + if (d == null) { + return; + } + try { + chunk.s = g.e; + d.a(g, chunk); + } catch (Throwable ioexception) { // Craftbukkit: Cast down to compile + ioexception.printStackTrace(); + } + } + + public void a(IChunkProvider ichunkprovider, int i, int j) { + Chunk chunk = b(i, j); + + if (!chunk.n) { + chunk.n = true; + if (c != null) { + c.a(ichunkprovider, i, j); + chunk.f(); + } + } + } + + public boolean a(boolean flag, IProgressUpdate iprogressupdate) { + int i = 0; + + for (int j = 0; j < f.size(); j++) { + Chunk chunk = (Chunk) f.get(j); + + if (flag && !chunk.p) { + a(chunk); + } + if (!chunk.a(flag)) { + continue; + } + b(chunk); + chunk.o = false; + if (++i == 24 && !flag) { + return false; + } + } + + if (flag) { + if (d == null) { + return true; + } + d.b(); + } + return true; + } + + public boolean a() { + if (!g.C) { + for (int i = 0; i < 100; i++) { + if (!a.isEmpty()) { + ChunkCoordinates chunkcoordinates = (ChunkCoordinates) a.iterator().next(); + Chunk chunk = b(chunkcoordinates.a, chunkcoordinates.b); + + chunk.e(); + b(chunk); + a(chunk); + a.remove(chunkcoordinates); + e.remove(chunkcoordinates); + f.remove(chunk); + } + } + + if (d != null) { + d.a(); + } + } + return c.a(); + } + + public boolean b() { + return !g.C; + } +} + diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java index 75dc1b45ef..74c49a9ec1 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -21,8 +21,8 @@ import org.bukkit.Vector; import org.bukkit.World; public class CraftWorld implements World { - private final Map chunkCache = new HashMap(); - private final Map blockCache = new HashMap(); + private final Map chunkCache = new HashMap(); + private final Map blockCache = new HashMap(); private final WorldServer world; private static final Random rand = new Random(); @@ -33,7 +33,7 @@ public class CraftWorld implements World { public Block getBlockAt(int x, int y, int z) { BlockCoordinate loc = new BlockCoordinate(x, y, z); - Block block = blockCache.get(loc); + CraftBlock block = blockCache.get(loc); if (block == null) { block = new CraftBlock(this, x, y, z, world.a(x, y, z), (byte)world.b(x, y, z)); @@ -49,7 +49,7 @@ public class CraftWorld implements World { public Chunk getChunkAt(int x, int z) { ChunkCoordinate loc = new ChunkCoordinate(x, z); - Chunk chunk = chunkCache.get(loc); + CraftChunk chunk = chunkCache.get(loc); if (chunk == null) { chunk = new CraftChunk(this, x, z); @@ -84,6 +84,20 @@ public class CraftWorld implements World { return block; } + public CraftChunk updateChunk(int x, int z) { + ChunkCoordinate loc = new ChunkCoordinate(x, z); + CraftChunk chunk = chunkCache.get(loc); + + if (chunk == null) { + chunk = new CraftChunk(this, x, z); + chunkCache.put(loc, chunk); + } else { + // TODO: Chunk stuff + } + + return chunk; + } + public WorldServer getHandle() { return world; }