From 5cf461979b07c8b31867b7e64c36fa6bc4a2e8fa Mon Sep 17 00:00:00 2001
From: Iceee <andrew@opticgaming.tv>
Date: Wed, 15 Jul 2015 02:41:12 -0700
Subject: [PATCH] ChunkMap caching


diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
index ab4de94..2b70bf4 100644
--- a/src/main/java/net/minecraft/server/Chunk.java
+++ b/src/main/java/net/minecraft/server/Chunk.java
@@ -50,6 +50,39 @@ public class Chunk {
     public long lightUpdateTime;
     // PaperSpigot end
 
+    // PaperSpigot start - ChunkMap caching
+    private PacketPlayOutMapChunk.ChunkMap chunkMap;
+    private int emptySectionBits;
+
+    public PacketPlayOutMapChunk.ChunkMap getChunkMap() {
+        boolean isDirty = false;
+        for (int i = 0; i < sections.length; ++i) {
+            ChunkSection section = sections[i];
+            if (section == null) {
+                if ((emptySectionBits & (1 << i)) == 0) {
+                    isDirty = true;
+                    emptySectionBits |= (1 << i);
+                }
+            } else {
+                if ((emptySectionBits & (1 << i)) == 1) {
+                    isDirty = true;
+                    emptySectionBits &= ~(1 << i);
+                    section.isDirty = false;
+                } else if (section.isDirty) {
+                    isDirty = true;
+                    section.isDirty = false;
+                }
+            }
+        }
+
+        if (isDirty || chunkMap == null) {
+            chunkMap = PacketPlayOutMapChunk.a(this, true, !world.worldProvider.o(), '\uffff');
+        }
+
+        return chunkMap;
+    }
+    // PaperSpigot end
+
     // CraftBukkit start - Neighbor loaded cache for chunk lighting and entity ticking
     private int neighbors = 0x1 << 12;
 
diff --git a/src/main/java/net/minecraft/server/ChunkSection.java b/src/main/java/net/minecraft/server/ChunkSection.java
index f734ab0..907c57b 100644
--- a/src/main/java/net/minecraft/server/ChunkSection.java
+++ b/src/main/java/net/minecraft/server/ChunkSection.java
@@ -8,6 +8,7 @@ public class ChunkSection {
     private char[] blockIds;
     private NibbleArray emittedLight;
     private NibbleArray skyLight;
+    boolean isDirty; // PaperSpigot
 
     public ChunkSection(int i, boolean flag) {
         this.yPos = i;
@@ -57,6 +58,7 @@ public class ChunkSection {
         }
 
         this.blockIds[j << 8 | k << 4 | i] = (char) Block.d.b(iblockdata);
+        isDirty = true; // PaperSpigot
     }
 
     public Block b(int i, int j, int k) {
@@ -83,6 +85,7 @@ public class ChunkSection {
 
     public void a(int i, int j, int k, int l) {
         this.skyLight.a(i, j, k, l);
+        isDirty = true; // PaperSpigot
     }
 
     public int d(int i, int j, int k) {
@@ -91,6 +94,7 @@ public class ChunkSection {
 
     public void b(int i, int j, int k, int l) {
         this.emittedLight.a(i, j, k, l);
+        isDirty = true; // PaperSpigot
     }
 
     public int e(int i, int j, int k) {
diff --git a/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java b/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java
index 58c0275..91ceb81 100644
--- a/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java
+++ b/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java
@@ -18,7 +18,7 @@ public class PacketPlayOutMapChunk implements Packet<PacketListenerPlayOut> {
         this.a = chunk.locX;
         this.b = chunk.locZ;
         this.d = flag;
-        this.c = a(chunk, flag, !chunk.getWorld().worldProvider.o(), i);
+        this.c = chunk.getChunkMap(); // PaperSpigot
         chunk.world.spigotConfig.antiXrayInstance.obfuscateSync(chunk.locX, chunk.locZ, c.b, c.a, chunk.world);
     }
 
diff --git a/src/main/java/net/minecraft/server/PacketPlayOutMapChunkBulk.java b/src/main/java/net/minecraft/server/PacketPlayOutMapChunkBulk.java
index 10c0e34..f7e8ab3 100644
--- a/src/main/java/net/minecraft/server/PacketPlayOutMapChunkBulk.java
+++ b/src/main/java/net/minecraft/server/PacketPlayOutMapChunkBulk.java
@@ -23,7 +23,7 @@ public class PacketPlayOutMapChunkBulk implements Packet<PacketListenerPlayOut>
 
         for (int j = 0; j < i; ++j) {
             Chunk chunk = (Chunk) list.get(j);
-            PacketPlayOutMapChunk.ChunkMap packetplayoutmapchunk_chunkmap = PacketPlayOutMapChunk.a(chunk, true, this.d, '\uffff');
+            PacketPlayOutMapChunk.ChunkMap packetplayoutmapchunk_chunkmap = chunk.getChunkMap(); // PaperSpigot
 
             this.a[j] = chunk.locX;
             this.b[j] = chunk.locZ;
-- 
1.9.5.msysgit.1