mirror of
https://github.com/Minestom/Minestom.git
synced 2025-03-02 11:21:15 +01:00
The chunk view distance can now be dynamically modified both by the client or with the server using MinecraftServer#setChunkViewDistance, also added UpdateViewDistancePacket
This commit is contained in:
parent
6e36f3242d
commit
b74d85eca8
@ -13,12 +13,14 @@ import net.minestom.server.data.DataType;
|
||||
import net.minestom.server.data.SerializableData;
|
||||
import net.minestom.server.entity.EntityManager;
|
||||
import net.minestom.server.entity.EntityType;
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.extensions.Extension;
|
||||
import net.minestom.server.extensions.ExtensionManager;
|
||||
import net.minestom.server.extras.mojangAuth.MojangCrypt;
|
||||
import net.minestom.server.fluids.Fluid;
|
||||
import net.minestom.server.gamedata.loottables.LootTableManager;
|
||||
import net.minestom.server.gamedata.tags.TagManager;
|
||||
import net.minestom.server.instance.Chunk;
|
||||
import net.minestom.server.instance.InstanceManager;
|
||||
import net.minestom.server.instance.block.Block;
|
||||
import net.minestom.server.instance.block.BlockManager;
|
||||
@ -33,6 +35,7 @@ import net.minestom.server.network.PacketWriterUtils;
|
||||
import net.minestom.server.network.netty.NettyServer;
|
||||
import net.minestom.server.network.packet.server.play.PluginMessagePacket;
|
||||
import net.minestom.server.network.packet.server.play.ServerDifficultyPacket;
|
||||
import net.minestom.server.network.packet.server.play.UpdateViewDistancePacket;
|
||||
import net.minestom.server.particle.Particle;
|
||||
import net.minestom.server.ping.ResponseDataConsumer;
|
||||
import net.minestom.server.potion.PotionEffect;
|
||||
@ -45,6 +48,7 @@ import net.minestom.server.stat.StatisticType;
|
||||
import net.minestom.server.storage.StorageLocation;
|
||||
import net.minestom.server.storage.StorageManager;
|
||||
import net.minestom.server.timer.SchedulerManager;
|
||||
import net.minestom.server.utils.MathUtils;
|
||||
import net.minestom.server.utils.thread.MinestomThread;
|
||||
import net.minestom.server.utils.validate.Check;
|
||||
import net.minestom.server.world.Difficulty;
|
||||
@ -57,6 +61,7 @@ import org.slf4j.LoggerFactory;
|
||||
import java.io.IOException;
|
||||
import java.net.Proxy;
|
||||
import java.security.KeyPair;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* The main server class used to start the server and retrieve all the managers.
|
||||
@ -432,15 +437,28 @@ public class MinecraftServer {
|
||||
|
||||
/**
|
||||
* Changes the chunk view distance of the server.
|
||||
* <p>
|
||||
* WARNING: this need to be called before {@link #start(String, int, ResponseDataConsumer)}.
|
||||
*
|
||||
* @param chunkViewDistance the new chunk view distance
|
||||
* @throws IllegalStateException if this is called after the server started
|
||||
*/
|
||||
public static void setChunkViewDistance(int chunkViewDistance) {
|
||||
Check.stateCondition(started, "The chunk view distance cannot be changed after the server has been started.");
|
||||
Check.argCondition(!MathUtils.isBetween(chunkViewDistance, 2, 32), "The chunk view distance needs to be between 2 and 32");
|
||||
MinecraftServer.chunkViewDistance = chunkViewDistance;
|
||||
if (started) {
|
||||
UpdateViewDistancePacket updateViewDistancePacket = new UpdateViewDistancePacket();
|
||||
updateViewDistancePacket.viewDistance = chunkViewDistance;
|
||||
|
||||
final Collection<Player> players = connectionManager.getOnlinePlayers();
|
||||
|
||||
PacketWriterUtils.writeAndSend(players, updateViewDistancePacket);
|
||||
|
||||
connectionManager.getOnlinePlayers().forEach(player -> {
|
||||
final Chunk playerChunk = player.getChunk();
|
||||
if (playerChunk != null) {
|
||||
player.refreshVisibleChunks(playerChunk);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1032,7 +1032,7 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer {
|
||||
final boolean isPlayer = this instanceof Player;
|
||||
|
||||
if (isPlayer)
|
||||
((Player) this).onChunkChange(newChunk); // Refresh loaded chunk
|
||||
((Player) this).refreshVisibleChunks(newChunk); // Refresh loaded chunk
|
||||
|
||||
// Refresh entity viewable list
|
||||
final int entityViewDistance = MinecraftServer.getEntityViewDistance();
|
||||
|
@ -1327,7 +1327,7 @@ public class Player extends LivingEntity implements CommandSender {
|
||||
final BlockPosition pos = position.toBlockPosition();
|
||||
final Chunk chunk = instance.getChunk(pos.getX() >> 4, pos.getZ() >> 4);
|
||||
Check.notNull(chunk, "Tried to interact with an unloaded chunk.");
|
||||
onChunkChange(chunk);
|
||||
refreshVisibleChunks(chunk);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1406,13 +1406,14 @@ public class Player extends LivingEntity implements CommandSender {
|
||||
|
||||
/**
|
||||
* Called when the player changes chunk (move from one to another).
|
||||
* Can also be used to refresh the list of chunks that the client should see.
|
||||
* <p>
|
||||
* It does remove and add the player from the chunks viewers list when removed or added.
|
||||
* It also calls the events {@link PlayerChunkUnloadEvent} and {@link PlayerChunkLoadEvent}.
|
||||
*
|
||||
* @param newChunk the current/new player chunk
|
||||
*/
|
||||
protected void onChunkChange(@NotNull Chunk newChunk) {
|
||||
public void refreshVisibleChunks(@NotNull Chunk newChunk) {
|
||||
// Previous chunks indexes
|
||||
final long[] lastVisibleChunks = viewableChunks.stream().mapToLong(viewableChunks ->
|
||||
ChunkUtils.getChunkIndex(viewableChunks.getChunkX(), viewableChunks.getChunkZ())
|
||||
@ -2389,6 +2390,8 @@ public class Player extends LivingEntity implements CommandSender {
|
||||
private byte displayedSkinParts;
|
||||
private MainHand mainHand;
|
||||
|
||||
private boolean firstRefresh = true;
|
||||
|
||||
/**
|
||||
* The player game language.
|
||||
*
|
||||
@ -2451,6 +2454,9 @@ public class Player extends LivingEntity implements CommandSender {
|
||||
* @param mainHand the player main hand
|
||||
*/
|
||||
public void refresh(String locale, byte viewDistance, ChatMode chatMode, boolean chatColors, byte displayedSkinParts, MainHand mainHand) {
|
||||
|
||||
final boolean viewDistanceChanged = !firstRefresh && this.viewDistance != viewDistance;
|
||||
|
||||
this.locale = locale;
|
||||
this.viewDistance = viewDistance;
|
||||
this.chatMode = chatMode;
|
||||
@ -2458,6 +2464,16 @@ public class Player extends LivingEntity implements CommandSender {
|
||||
this.displayedSkinParts = displayedSkinParts;
|
||||
this.mainHand = mainHand;
|
||||
sendMetadataIndex(16);
|
||||
|
||||
this.firstRefresh = false;
|
||||
|
||||
// Client changed his view distance in the settings
|
||||
if (viewDistanceChanged) {
|
||||
final Chunk playerChunk = getChunk();
|
||||
if (playerChunk != null) {
|
||||
refreshVisibleChunks(playerChunk);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,21 @@
|
||||
package net.minestom.server.network.packet.server.play;
|
||||
|
||||
import net.minestom.server.network.packet.server.ServerPacket;
|
||||
import net.minestom.server.network.packet.server.ServerPacketIdentifier;
|
||||
import net.minestom.server.utils.binary.BinaryWriter;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class UpdateViewDistancePacket implements ServerPacket {
|
||||
|
||||
public int viewDistance;
|
||||
|
||||
@Override
|
||||
public void write(@NotNull BinaryWriter writer) {
|
||||
writer.writeVarInt(viewDistance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return ServerPacketIdentifier.UPDATE_VIEW_DISTANCE;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user