From 6f5ba9138ecbe420a790519709c60850d4e89caa Mon Sep 17 00:00:00 2001
From: Byteflux <byte@byteflux.net>
Date: Wed, 2 Mar 2016 14:35:27 -0600
Subject: [PATCH] Add player view distance API


diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java
index 7ef3f62..6e19244 100644
--- a/src/main/java/net/minecraft/server/EntityPlayer.java
+++ b/src/main/java/net/minecraft/server/EntityPlayer.java
@@ -56,6 +56,15 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
     public boolean f;
     public int ping;
     public boolean viewingCredits;
+    // Paper start - Player view distance API
+    private int viewDistance = -1;
+    public int getViewDistance() {
+        return viewDistance == -1 ? ((WorldServer) world).getPlayerChunkMap().getViewDistance() : viewDistance;
+    }
+    public void setViewDistance(int viewDistance) {
+        this.viewDistance = viewDistance;
+    }
+    // Paper end
 
     // CraftBukkit start
     public String displayName;
diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
index b0249ff..77e9187 100644
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
@@ -46,7 +46,7 @@ public class PlayerChunkMap {
     private final List<PlayerChunk> g = Lists.newLinkedList();
     private final List<PlayerChunk> h = Lists.newLinkedList();
     private final List<PlayerChunk> i = Lists.newArrayList();
-    private int j;
+    private int j;public int getViewDistance() { return j; } // Paper OBFHELPER
     private long k;
     private boolean l = true;
     private boolean m = true;
@@ -288,8 +288,11 @@ public class PlayerChunkMap {
         int i = (int) entityplayer.d >> 4;
         int j = (int) entityplayer.e >> 4;
 
-        for (int k = i - this.j; k <= i + this.j; ++k) {
-            for (int l = j - this.j; l <= j + this.j; ++l) {
+        // Paper start - Player view distance API
+        int viewDistance = entityplayer.getViewDistance();
+        for (int k = i - viewDistance; k <= i + viewDistance; ++k) {
+            for (int l = j - viewDistance; l <= j + viewDistance; ++l) {
+                // Paper end
                 PlayerChunk playerchunk = this.getChunk(k, l);
 
                 if (playerchunk != null) {
@@ -319,7 +322,9 @@ public class PlayerChunkMap {
         if (d2 >= 64.0D) {
             int k = (int) entityplayer.d >> 4;
             int l = (int) entityplayer.e >> 4;
-            int i1 = this.j;
+            final int viewDistance = entityplayer.getViewDistance(); // Paper - Player view distance API
+            int i1 = Math.max(getViewDistance(), viewDistance); // Paper - Player view distance API
+
             int j1 = i - k;
             int k1 = j - l;
 
@@ -328,7 +333,7 @@ public class PlayerChunkMap {
             if (j1 != 0 || k1 != 0) {
                 for (int l1 = i - i1; l1 <= i + i1; ++l1) {
                     for (int i2 = j - i1; i2 <= j + i1; ++i2) {
-                        if (!this.a(l1, i2, k, l, i1)) {
+                        if (!this.a(l1, i2, k, l, viewDistance)) { // Paper - Player view distance API
                             // this.c(l1, i2).a(entityplayer);
                             chunksToLoad.add(new ChunkCoordIntPair(l1, i2)); // CraftBukkit
                         }
@@ -480,4 +485,20 @@ public class PlayerChunkMap {
         }
     }
     // CraftBukkit end
+
+    // Paper start - Player view distance API
+    public void updateViewDistance(EntityPlayer player, int toSet) {
+        final int oldViewDistance = player.getViewDistance();
+
+        int viewDistance = MathHelper.clamp(toSet, 3, 32);
+        if (toSet < 0) {
+            viewDistance = -1;
+        }
+        if (viewDistance != oldViewDistance) {
+            removePlayer(player);
+            player.setViewDistance(viewDistance);
+            addPlayer(player);
+        }
+    }
+    // Paper end
 }
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
index 5515958..9770c99 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -1419,6 +1419,16 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
         return this.getHandle().affectsSpawning;
     }
 
+    @Override
+    public int getViewDistance() {
+        return getHandle().getViewDistance();
+    }
+
+    @Override
+    public void setViewDistance(int viewDistance) {
+        ((WorldServer) getHandle().world).getPlayerChunkMap().updateViewDistance(getHandle(), viewDistance);
+    }
+
     // Spigot start
     private final Player.Spigot spigot = new Player.Spigot()
     {
-- 
2.8.2.windows.1