From 626612688fa409fd1224c8cfd974b0197364e515 Mon Sep 17 00:00:00 2001 From: Dereku Date: Fri, 30 Jan 2026 04:41:51 +0700 Subject: [PATCH] round-view-of-the-terrain option --- .../server/observers/PlayerInstance.java | 5 +- .../server/observers/PlayerManager.java | 151 ++++++++++++++---- 2 files changed, 123 insertions(+), 33 deletions(-) diff --git a/src/net/minecraft/server/observers/PlayerInstance.java b/src/net/minecraft/server/observers/PlayerInstance.java index dc73057..1c4e864 100644 --- a/src/net/minecraft/server/observers/PlayerInstance.java +++ b/src/net/minecraft/server/observers/PlayerInstance.java @@ -61,7 +61,10 @@ class PlayerInstance { } var1.loadedChunks.remove(this.currentChunk); - if (var1.field_420_ah.contains(this.currentChunk)) { + // Patch start + //if (var1.field_420_ah.contains(this.currentChunk)) { // ChunkCoordIntPair leaking + if (var1.field_420_ah.remove(this.currentChunk)) { + // Patch end var1.playerNetServerHandler.sendPacket(new Packet50PreChunk(this.chunkX, this.chunkZ, false)); } diff --git a/src/net/minecraft/server/observers/PlayerManager.java b/src/net/minecraft/server/observers/PlayerManager.java index 62e3638..9e4eb4c 100644 --- a/src/net/minecraft/server/observers/PlayerManager.java +++ b/src/net/minecraft/server/observers/PlayerManager.java @@ -1,11 +1,11 @@ package net.minecraft.server.observers; import net.minecraft.entity.EntityPlayerMP; +import net.minecraft.math.ChunkCoordIntPair; import net.minecraft.server.MinecraftServer; import net.minecraft.world.WorldServer; -import java.util.ArrayList; -import java.util.List; +import java.util.*; public class PlayerManager { public List players = new ArrayList(); @@ -15,6 +15,10 @@ public class PlayerManager { private int field_28110_e; private int playerViewRadius; private final int[][] field_22089_e = new int[][]{{1, 0}, {0, 1}, {-1, 0}, {0, -1}}; + // Patch start + private final byte[] circularMask; + private final Set prevChunksTmp = new HashSet<>(); + // Patch end public PlayerManager(MinecraftServer var1, int var2, int var3) { if (var3 > 15) { @@ -25,6 +29,22 @@ public class PlayerManager { this.playerViewRadius = var3; this.mcServer = var1; this.field_28110_e = var2; + // Patch start + if (var1.propertyManagerObj.getBooleanProperty("round-view-of-the-terrain", false)) { + int sideWidth = var3 + var3 + 1; + this.circularMask = new byte[sideWidth * sideWidth]; + for (int x = 0; x < sideWidth; x++) { + for (int y = 0; y < sideWidth; y++) { + int a = x - var3, b = y - var3; + if (a * a + b * b - sideWidth < var3 * var3) { + this.circularMask[sideWidth * x + y] = 1; + } + } + } + } else { + this.circularMask = new byte[0]; + } + // Patch end } } @@ -62,37 +82,62 @@ public class PlayerManager { } public void addPlayer(EntityPlayerMP var1) { - int var2 = (int) var1.posX >> 4; - int var3 = (int) var1.posZ >> 4; + // Patch start + //int var2 = (int) var1.posX >> 4; + //int var3 = (int) var1.posZ >> 4; + final int var2 = (int) var1.posX >> 4; + final int var3 = (int) var1.posZ >> 4; + // Patch end var1.field_9155_d = var1.posX; var1.field_9154_e = var1.posZ; int var4 = 0; int var5 = this.playerViewRadius; int var6 = 0; int var7 = 0; - this.getPlayerInstance(var2, var3, true).addPlayer(var1); - - int var8; - for (var8 = 1; var8 <= var5 * 2; ++var8) { - for (int var9 = 0; var9 < 2; ++var9) { - int[] var10 = this.field_22089_e[var4++ % 4]; - - for (int var11 = 0; var11 < var8; ++var11) { - var6 += var10[0]; - var7 += var10[1]; - this.getPlayerInstance(var2 + var6, var3 + var7, true).addPlayer(var1); + // Patch start + if (this.circularMask.length > 0) { + int k1 = var5 + var5 + 1; + for (int vx = -var5; vx <= var5; vx++) { + for (int vz = -var5; vz <= var5; vz++) { + int relX = vx + var5, relZ = vz + var5; + if (this.circularMask[k1 * relX + relZ] != 0) { + this.getPlayerInstance(var2 + vx, var3 + vz, true).addPlayer(var1); + } } } + } else { + this.getPlayerInstance(var2, var3, true).addPlayer(var1); + + int var8; + for (var8 = 1; var8 <= var5 * 2; ++var8) { + for (int var9 = 0; var9 < 2; ++var9) { + int[] var10 = this.field_22089_e[var4++ % 4]; + + for (int var11 = 0; var11 < var8; ++var11) { + var6 += var10[0]; + var7 += var10[1]; + this.getPlayerInstance(var2 + var6, var3 + var7, true).addPlayer(var1); + } + } + } + + var4 %= 4; + + for (var8 = 0; var8 < var5 * 2; ++var8) { + var6 += this.field_22089_e[var4][0]; + var7 += this.field_22089_e[var4][1]; + this.getPlayerInstance(var2 + var6, var3 + var7, true).addPlayer(var1); + } } - var4 %= 4; - - for (var8 = 0; var8 < var5 * 2; ++var8) { - var6 += this.field_22089_e[var4][0]; - var7 += this.field_22089_e[var4][1]; - this.getPlayerInstance(var2 + var6, var3 + var7, true).addPlayer(var1); - } - + Collections.sort(var1.loadedChunks, new Comparator() { + @Override + public int compare(ChunkCoordIntPair a, ChunkCoordIntPair b) { + return Math.max(Math.abs(a.chunkXPos - var2), Math.abs(a.chunkZPos - var3)) + - Math.max(Math.abs(b.chunkXPos - var2), Math.abs(b.chunkZPos - var3)); + } + }); + // Patch end this.players.add(var1); } @@ -130,16 +175,44 @@ public class PlayerManager { int var12 = var2 - var10; int var13 = var3 - var11; if (var12 != 0 || var13 != 0) { - for (int var14 = var2 - this.playerViewRadius; var14 <= var2 + this.playerViewRadius; ++var14) { - for (int var15 = var3 - this.playerViewRadius; var15 <= var3 + this.playerViewRadius; ++var15) { - if (!this.func_544_a(var14, var15, var10, var11)) { - this.getPlayerInstance(var14, var15, true).addPlayer(var1); - } + // Patch start + if (this.circularMask.length > 0) { + this.prevChunksTmp.clear(); + this.prevChunksTmp.addAll(var1.field_420_ah); + int k1 = this.playerViewRadius + this.playerViewRadius + 1; - if (!this.func_544_a(var14 - var12, var15 - var13, var2, var3)) { - PlayerInstance var16 = this.getPlayerInstance(var14 - var12, var15 - var13, false); - if (var16 != null) { - var16.removePlayer(var1); + for (int vx = -this.playerViewRadius; vx <= this.playerViewRadius; vx++) { + for (int vz = -this.playerViewRadius; vz <= this.playerViewRadius; vz++) { + int relX = vx + this.playerViewRadius, relZ = vz + this.playerViewRadius; + if (this.circularMask[k1 * relX + relZ] == 0) { + continue; + } + ChunkCoordIntPair rem = new ChunkCoordIntPair(var2 + vx, var3 + vz); + if (!this.prevChunksTmp.remove(rem)) { + this.getPlayerInstance(var2 + vx, var3 + vz, true).addPlayer(var1); + } + } + } + + for (ChunkCoordIntPair pair : this.prevChunksTmp) { + PlayerInstance playerinstance = this.getPlayerInstance(pair.chunkXPos, pair.chunkZPos, false); + if (playerinstance != null) { + playerinstance.removePlayer(var1); + } + } + this.prevChunksTmp.clear(); + } else { + for (int var14 = var2 - this.playerViewRadius; var14 <= var2 + this.playerViewRadius; ++var14) { + for (int var15 = var3 - this.playerViewRadius; var15 <= var3 + this.playerViewRadius; ++var15) { + if (!this.func_544_a(var14, var15, var10, var11)) { + this.getPlayerInstance(var14, var15, true).addPlayer(var1); + } + + if (!this.func_544_a(var14 - var12, var15 - var13, var2, var3)) { + PlayerInstance var16 = this.getPlayerInstance(var14 - var12, var15 - var13, false); + if (var16 != null) { + var16.removePlayer(var1); + } } } } @@ -147,6 +220,20 @@ public class PlayerManager { var1.field_9155_d = var1.posX; var1.field_9154_e = var1.posZ; + + // CraftBukkit start - send nearest chunks first + if (var12 > 1 || var12 < -1 || var13 > 1 || var13 < -1) { + final int x = var2; + final int z = var3; + Collections.sort(var1.loadedChunks, new Comparator() { + public int compare(ChunkCoordIntPair a, ChunkCoordIntPair b) { + return Math.max(Math.abs(a.chunkXPos - x), Math.abs(a.chunkZPos - z)) + - Math.max(Math.abs(b.chunkXPos - x), Math.abs(b.chunkZPos - z)); + } + }); + } + // CraftBukkit end + // Patch end } } }