mirror of
https://github.com/Minestom/Minestom.git
synced 2025-02-11 18:02:08 +01:00
Fix chunks not being refreshed when view distance updates (#2197)
* Fix chunks not being refreshed when view distance updates
This commit is contained in:
parent
3172039f39
commit
1b85254f91
@ -2469,6 +2469,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
|
||||
byte displayedSkinParts, MainHand mainHand, boolean enableTextFiltering, boolean allowServerListings) {
|
||||
this.locale = locale;
|
||||
// Clamp viewDistance to valid bounds
|
||||
byte previousViewDistance = this.viewDistance;
|
||||
this.viewDistance = (byte) MathUtils.clamp(viewDistance, 2, 32);
|
||||
this.chatMessageType = chatMessageType;
|
||||
this.chatColors = chatColors;
|
||||
@ -2477,6 +2478,27 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
|
||||
this.enableTextFiltering = enableTextFiltering;
|
||||
this.allowServerListings = allowServerListings;
|
||||
|
||||
// Check to see if we're in an instance first, as this method is called when first logging in since the client sends the Settings packet during configuration
|
||||
if (instance != null) {
|
||||
// Load/unload chunks if necessary due to view distance changes
|
||||
if (previousViewDistance < this.viewDistance) {
|
||||
// View distance expanded, send chunks
|
||||
ChunkUtils.forChunksInRange(position.chunkX(), position.chunkZ(), this.viewDistance, (chunkX, chunkZ) -> {
|
||||
if (Math.abs(chunkX - position.chunkX()) > previousViewDistance || Math.abs(chunkZ - position.chunkZ()) > previousViewDistance) {
|
||||
chunkAdder.accept(chunkX, chunkZ);
|
||||
}
|
||||
});
|
||||
} else if (previousViewDistance > this.viewDistance) {
|
||||
// View distance shrunk, unload chunks
|
||||
ChunkUtils.forChunksInRange(position.chunkX(), position.chunkZ(), previousViewDistance, (chunkX, chunkZ) -> {
|
||||
if (Math.abs(chunkX - position.chunkX()) > this.viewDistance || Math.abs(chunkZ - position.chunkZ()) > this.viewDistance) {
|
||||
chunkRemover.accept(chunkX, chunkZ);
|
||||
}
|
||||
});
|
||||
}
|
||||
// Else previous and current are equal, do nothing
|
||||
}
|
||||
|
||||
boolean isInPlayState = getPlayerConnection().getConnectionState() == ConnectionState.PLAY;
|
||||
PlayerMeta playerMeta = getPlayerMeta();
|
||||
if (isInPlayState) playerMeta.setNotifyAboutChanges(false);
|
||||
|
@ -8,10 +8,12 @@ import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.instance.Chunk;
|
||||
import net.minestom.server.instance.Instance;
|
||||
import net.minestom.server.message.ChatMessageType;
|
||||
import net.minestom.server.network.packet.client.common.ClientSettingsPacket;
|
||||
import net.minestom.server.network.packet.client.play.ClientPlayerPositionPacket;
|
||||
import net.minestom.server.network.packet.client.play.ClientTeleportConfirmPacket;
|
||||
import net.minestom.server.network.packet.server.play.ChunkDataPacket;
|
||||
import net.minestom.server.network.packet.server.play.EntityPositionPacket;
|
||||
import net.minestom.server.network.packet.server.play.UnloadChunkPacket;
|
||||
import net.minestom.server.utils.MathUtils;
|
||||
import net.minestom.server.utils.chunk.ChunkUtils;
|
||||
import net.minestom.testing.Collector;
|
||||
@ -21,6 +23,8 @@ import net.minestom.testing.TestConnection;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
@ -137,4 +141,32 @@ public class PlayerMovementIntegrationTest {
|
||||
player.interpretPacketQueue();
|
||||
chunkDataPacketCollector.assertCount(MathUtils.square(viewDistance * 2 + 1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSettingsViewDistanceExpansionAndShrink(Env env) {
|
||||
int startingViewDistance = 8;
|
||||
byte endViewDistance = 12;
|
||||
byte finalViewDistance = 10;
|
||||
var instance = env.createFlatInstance();
|
||||
var connection = env.createConnection();
|
||||
Pos startingPlayerPos = new Pos(0, 42, 0);
|
||||
var player = connection.connect(instance, startingPlayerPos).join();
|
||||
|
||||
int chunkDifference = ChunkUtils.getChunkCount(endViewDistance) - ChunkUtils.getChunkCount(startingViewDistance);
|
||||
|
||||
// Preload chunks, otherwise our first tracker.assertCount call will fail randomly due to chunks being loaded off the main thread
|
||||
ChunkUtils.forChunksInRange(0, 0, endViewDistance, instance::loadChunk);
|
||||
|
||||
var tracker = connection.trackIncoming(ChunkDataPacket.class);
|
||||
player.addPacketToQueue(new ClientSettingsPacket("en_US", endViewDistance, ChatMessageType.FULL, false, (byte) 0, Player.MainHand.RIGHT, false, true));
|
||||
player.interpretPacketQueue();
|
||||
tracker.assertCount(chunkDifference);
|
||||
|
||||
var tracker1 = connection.trackIncoming(UnloadChunkPacket.class);
|
||||
player.addPacketToQueue(new ClientSettingsPacket("en_US", finalViewDistance, ChatMessageType.FULL, false, (byte) 0, Player.MainHand.RIGHT, false, true));
|
||||
player.interpretPacketQueue();
|
||||
|
||||
int chunkDifference1 = ChunkUtils.getChunkCount(endViewDistance) - ChunkUtils.getChunkCount(finalViewDistance);
|
||||
tracker1.assertCount(chunkDifference1);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user