18c3716c49
This enables us a fast reference to the entities current chunk instead of having to look it up by hashmap lookups. We also store counts by type to further enable other performance optimizations in later patches.
229 Zeilen
9.1 KiB
Diff
229 Zeilen
9.1 KiB
Diff
From bc0c7f66ac5a805ce36fbeec388e30315c77e22e 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 dfaab774d..3058dfef0 100644
|
|
--- a/src/main/java/net/minecraft/server/EntityPlayer.java
|
|
+++ b/src/main/java/net/minecraft/server/EntityPlayer.java
|
|
@@ -66,6 +66,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 e4ed2e991..9627a9be0 100644
|
|
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
|
|
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
|
|
@@ -47,7 +47,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;
|
|
@@ -291,8 +291,11 @@ public class PlayerChunkMap {
|
|
// CraftBukkit start - Load nearby chunks first
|
|
List<ChunkCoordIntPair> chunkList = new LinkedList<ChunkCoordIntPair>();
|
|
|
|
- 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
|
|
chunkList.add(new ChunkCoordIntPair(k, l));
|
|
}
|
|
}
|
|
@@ -311,8 +314,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) {
|
|
@@ -342,7 +348,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;
|
|
|
|
@@ -351,7 +359,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
|
|
}
|
|
@@ -386,6 +394,8 @@ public class PlayerChunkMap {
|
|
return playerchunk != null && playerchunk.d(entityplayer) && playerchunk.e();
|
|
}
|
|
|
|
+ public final void setViewDistanceForAll(int viewDistance) { this.a(viewDistance); } // Paper - OBFHELPER
|
|
+ // Paper start - Separate into two methods
|
|
public void a(int i) {
|
|
i = MathHelper.clamp(i, 3, 32);
|
|
if (i != this.j) {
|
|
@@ -395,36 +405,55 @@ public class PlayerChunkMap {
|
|
|
|
while (iterator.hasNext()) {
|
|
EntityPlayer entityplayer = (EntityPlayer) iterator.next();
|
|
- int k = (int) entityplayer.locX >> 4;
|
|
- int l = (int) entityplayer.locZ >> 4;
|
|
- int i1;
|
|
- int j1;
|
|
-
|
|
- if (j > 0) {
|
|
- for (i1 = k - i; i1 <= k + i; ++i1) {
|
|
- for (j1 = l - i; j1 <= l + i; ++j1) {
|
|
- PlayerChunk playerchunk = this.c(i1, j1);
|
|
-
|
|
- if (!playerchunk.d(entityplayer)) {
|
|
- playerchunk.a(entityplayer);
|
|
- }
|
|
+ this.setViewDistance(entityplayer, i, false); // Paper - Split, don't mark sort pending, we'll handle it after
|
|
+ }
|
|
+
|
|
+ this.j = i;
|
|
+ this.e();
|
|
+ }
|
|
+ }
|
|
+
|
|
+ public void setViewDistance(EntityPlayer entityplayer, int i) {
|
|
+ this.setViewDistance(entityplayer, i, true); // Mark sort pending by default so we don't have to remember to do so all the time
|
|
+ }
|
|
+
|
|
+ // Copied from above with minor changes
|
|
+ public void setViewDistance(EntityPlayer entityplayer, int i, boolean markSort) {
|
|
+ i = MathHelper.clamp(i, 3, 32);
|
|
+ int oldViewDistance = entityplayer.getViewDistance();
|
|
+ if (i != oldViewDistance) {
|
|
+ int j = i - oldViewDistance;
|
|
+
|
|
+ int k = (int) entityplayer.locX >> 4;
|
|
+ int l = (int) entityplayer.locZ >> 4;
|
|
+ int i1;
|
|
+ int j1;
|
|
+
|
|
+ if (j > 0) {
|
|
+ for (i1 = k - i; i1 <= k + i; ++i1) {
|
|
+ for (j1 = l - i; j1 <= l + i; ++j1) {
|
|
+ PlayerChunk playerchunk = this.c(i1, j1);
|
|
+
|
|
+ if (!playerchunk.d(entityplayer)) {
|
|
+ playerchunk.a(entityplayer);
|
|
}
|
|
}
|
|
- } else {
|
|
- for (i1 = k - this.j; i1 <= k + this.j; ++i1) {
|
|
- for (j1 = l - this.j; j1 <= l + this.j; ++j1) {
|
|
- if (!this.a(i1, j1, k, l, i)) {
|
|
- this.c(i1, j1).b(entityplayer);
|
|
- }
|
|
+ }
|
|
+ } else {
|
|
+ for (i1 = k - oldViewDistance; i1 <= k + oldViewDistance; ++i1) {
|
|
+ for (j1 = l - oldViewDistance; j1 <= l + oldViewDistance; ++j1) {
|
|
+ if (!this.a(i1, j1, k, l, i)) {
|
|
+ this.c(i1, j1).b(entityplayer);
|
|
}
|
|
}
|
|
}
|
|
+ if (markSort) {
|
|
+ this.e();
|
|
+ }
|
|
}
|
|
-
|
|
- this.j = i;
|
|
- this.e();
|
|
}
|
|
}
|
|
+ // Paper end
|
|
|
|
private void e() {
|
|
this.l = true;
|
|
@@ -503,4 +532,29 @@ public class PlayerChunkMap {
|
|
}
|
|
}
|
|
// CraftBukkit end
|
|
+
|
|
+ // Paper start - Player view distance API
|
|
+ public void updateViewDistance(EntityPlayer player, int distanceIn) {
|
|
+ final int oldViewDistance = player.getViewDistance();
|
|
+
|
|
+ // This represents the view distance that we will set on the player
|
|
+ // It can exist as a negative value
|
|
+ int playerViewDistance = MathHelper.clamp(distanceIn, 3, 32);
|
|
+
|
|
+ // This value is the one we actually use to update the chunk map
|
|
+ // We don't ever want this to be a negative
|
|
+ int toSet = playerViewDistance;
|
|
+
|
|
+ if (distanceIn < 0) {
|
|
+ playerViewDistance = -1;
|
|
+ toSet = world.getPlayerChunkMap().getViewDistance();
|
|
+ }
|
|
+
|
|
+ if (toSet != oldViewDistance) {
|
|
+ // Order matters
|
|
+ this.setViewDistance(player, toSet);
|
|
+ player.setViewDistance(playerViewDistance);
|
|
+ }
|
|
+ }
|
|
+ // 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 44d0db180..b2b707305 100644
|
|
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
|
@@ -1549,6 +1549,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.18.0
|
|
|