mirror of
https://github.com/LeavesMC/Leaves.git
synced 2025-12-19 14:59:32 +00:00
Update Servux
This commit is contained in:
6
.github/workflows/build.yml
vendored
6
.github/workflows/build.yml
vendored
@@ -68,12 +68,6 @@ jobs:
|
||||
with:
|
||||
name: ${{ env.jar }}
|
||||
path: ${{ env.jar }}
|
||||
- name: Delete Draft Releases
|
||||
if: "!contains(github.event.commits[0].message, '[release-skip]')"
|
||||
continue-on-error: true
|
||||
uses: hugo19941994/delete-draft-releases@v1.0.1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Create Release
|
||||
if: "!contains(github.event.commits[0].message, '[release-skip]')"
|
||||
continue-on-error: true
|
||||
|
||||
@@ -5,14 +5,14 @@ Subject: [PATCH] Servux Protocol
|
||||
|
||||
|
||||
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
|
||||
index 1deedd3fc28792fc368580973038c1824b15691d..8dc71b01b9e7970729a82c68402eec9375dbae04 100644
|
||||
index 1deedd3fc28792fc368580973038c1824b15691d..f25eca541f377ee7b908a900c6a1b50f02a41eef 100644
|
||||
--- a/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -2189,6 +2189,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
||||
}
|
||||
|
||||
this.lastSpawnChunkRadius = i;
|
||||
+ org.leavesmc.leaves.protocol.servux.ServuxStructuresProtocol.refreshSpawnMetadata = true; // Leaves - servux
|
||||
+ org.leavesmc.leaves.protocol.servux.ServuxHudDataProtocol.refreshSpawnMetadata = true; // Leaves - servux
|
||||
}
|
||||
|
||||
public LongSet getForcedChunks() {
|
||||
|
||||
@@ -747,6 +747,12 @@ public final class LeavesConfig {
|
||||
|
||||
@GlobalConfig("entity-protocol")
|
||||
public boolean entityProtocol = false;
|
||||
|
||||
@GlobalConfig("hud-metadata-protocol")
|
||||
public boolean hudMetadataProtocol = false;
|
||||
|
||||
@GlobalConfig("hud-metadata-protocol-share-seed")
|
||||
public boolean hudMetadataShareSeed = true;
|
||||
}
|
||||
|
||||
@GlobalConfig("bbor-protocol")
|
||||
|
||||
@@ -49,10 +49,16 @@ public class LitematicaEasyPlaceProtocol {
|
||||
BlockStateProperties.ROTATION_16
|
||||
);
|
||||
|
||||
public static final ImmutableSet<Property<?>> BLACKLISTED_PROPERTIES = ImmutableSet.of(
|
||||
BlockStateProperties.WATERLOGGED,
|
||||
BlockStateProperties.POWERED
|
||||
);
|
||||
|
||||
public static BlockState applyPlacementProtocol(BlockState state, BlockPlaceContext context) {
|
||||
return applyPlacementProtocolV3(state, UseContext.from(context, context.getHand()));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Nullable
|
||||
private static <T extends Comparable<T>> BlockState applyPlacementProtocolV3(BlockState state, @NotNull UseContext context) {
|
||||
int protocolValue = (int) (context.getHitVec().x - (double) context.getPos().getX()) - 2;
|
||||
@@ -86,8 +92,13 @@ public class LitematicaEasyPlaceProtocol {
|
||||
|
||||
try {
|
||||
for (Property<?> p : propList) {
|
||||
if (((p instanceof EnumProperty<?> ep) && !ep.getValueClass().equals(Direction.class)) && WHITELISTED_PROPERTIES.contains(p)) {
|
||||
@SuppressWarnings("unchecked")
|
||||
if (property != null && property.equals(p)) {
|
||||
continue;
|
||||
}
|
||||
if (!WHITELISTED_PROPERTIES.contains(p) || BLACKLISTED_PROPERTIES.contains(p)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Property<T> prop = (Property<T>) p;
|
||||
List<T> list = new ArrayList<>(prop.getPossibleValues());
|
||||
list.sort(Comparable::compareTo);
|
||||
@@ -112,11 +123,18 @@ public class LitematicaEasyPlaceProtocol {
|
||||
protocolValue >>>= requiredBits;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LeavesLogger.LOGGER.warning("Exception trying to apply placement protocol value", e);
|
||||
}
|
||||
|
||||
for (Property<?> p : BLACKLISTED_PROPERTIES) {
|
||||
if (state.hasProperty(p)) {
|
||||
Property<T> prop = (Property<T>) p;
|
||||
BlockState def = state.getBlock().defaultBlockState();
|
||||
state = state.setValue(prop, def.getValue(prop));
|
||||
}
|
||||
}
|
||||
|
||||
if (state.canSurvive(context.getWorld(), context.getPos())) {
|
||||
return state;
|
||||
} else {
|
||||
|
||||
@@ -0,0 +1,265 @@
|
||||
package org.leavesmc.leaves.protocol.servux;
|
||||
|
||||
import com.mojang.serialization.DataResult;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.ListTag;
|
||||
import net.minecraft.nbt.NbtOps;
|
||||
import net.minecraft.nbt.Tag;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.item.crafting.Recipe;
|
||||
import net.minecraft.world.item.crafting.RecipeHolder;
|
||||
import net.minecraft.world.level.GameRules;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.leavesmc.leaves.LeavesConfig;
|
||||
import org.leavesmc.leaves.protocol.core.LeavesCustomPayload;
|
||||
import org.leavesmc.leaves.protocol.core.LeavesProtocol;
|
||||
import org.leavesmc.leaves.protocol.core.ProtocolHandler;
|
||||
import org.leavesmc.leaves.protocol.core.ProtocolUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@LeavesProtocol(namespace = "servux")
|
||||
public class ServuxHudDataProtocol {
|
||||
|
||||
public static final ResourceLocation CHANNEL = ServuxProtocol.id("hud_metadata");
|
||||
public static final int PROTOCOL_VERSION = 1;
|
||||
|
||||
private static final List<ServerPlayer> players = new ArrayList<>();
|
||||
private static final int updateInterval = 80;
|
||||
|
||||
public static boolean refreshSpawnMetadata = false;
|
||||
|
||||
@ProtocolHandler.PayloadReceiver(payload = HudDataPayload.class, payloadId = "hud_metadata")
|
||||
public static void onPacketReceive(ServerPlayer player, HudDataPayload payload) {
|
||||
if (!LeavesConfig.protocol.servux.hudMetadataProtocol) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (payload.packetType) {
|
||||
case PACKET_C2S_METADATA_REQUEST -> {
|
||||
players.add(player);
|
||||
|
||||
CompoundTag metadata = new CompoundTag();
|
||||
metadata.putString("name", "hud_metadata");
|
||||
metadata.putString("id", CHANNEL.toString());
|
||||
metadata.putInt("version", PROTOCOL_VERSION);
|
||||
metadata.putString("servux", ServuxProtocol.SERVUX_STRING);
|
||||
putWorldData(metadata);
|
||||
|
||||
sendPacket(player, new HudDataPayload(HudDataPayloadType.PACKET_S2C_METADATA, metadata));
|
||||
}
|
||||
|
||||
case PACKET_C2S_SPAWN_DATA_REQUEST -> refreshSpawnMetadata(player);
|
||||
case PACKET_C2S_RECIPE_MANAGER_REQUEST -> refreshRecipeManager(player);
|
||||
}
|
||||
}
|
||||
|
||||
@ProtocolHandler.Ticker
|
||||
public void onTick() {
|
||||
if (!LeavesConfig.protocol.servux.hudMetadataProtocol) {
|
||||
return;
|
||||
}
|
||||
|
||||
MinecraftServer server = MinecraftServer.getServer();
|
||||
int tickCounter = server.getTickCount();
|
||||
if ((tickCounter % updateInterval) == 0) {
|
||||
for (ServerPlayer player : players) {
|
||||
if (refreshSpawnMetadata) {
|
||||
refreshSpawnMetadata(player);
|
||||
}
|
||||
refreshWeatherData(player);
|
||||
}
|
||||
refreshSpawnMetadata = false;
|
||||
}
|
||||
}
|
||||
|
||||
public static void refreshSpawnMetadata(ServerPlayer player) {
|
||||
if (!LeavesConfig.protocol.servux.hudMetadataProtocol) {
|
||||
return;
|
||||
}
|
||||
|
||||
CompoundTag metadata = new CompoundTag();
|
||||
metadata.putString("id", CHANNEL.toString());
|
||||
metadata.putString("servux", ServuxProtocol.SERVUX_STRING);
|
||||
putWorldData(metadata);
|
||||
|
||||
sendPacket(player, new HudDataPayload(HudDataPayloadType.PACKET_S2C_SPAWN_DATA, metadata));
|
||||
}
|
||||
|
||||
public static void refreshRecipeManager(ServerPlayer player) {
|
||||
if (!LeavesConfig.protocol.servux.hudMetadataProtocol) {
|
||||
return;
|
||||
}
|
||||
|
||||
Collection<RecipeHolder<?>> recipes = player.server.getRecipeManager().getRecipes();
|
||||
CompoundTag nbt = new CompoundTag();
|
||||
ListTag list = new ListTag();
|
||||
|
||||
recipes.forEach((recipeEntry -> {
|
||||
DataResult<Tag> dr = Recipe.CODEC.encodeStart(NbtOps.INSTANCE, recipeEntry.value());
|
||||
|
||||
if (dr.result().isPresent()) {
|
||||
CompoundTag entry = new CompoundTag();
|
||||
entry.putString("id_reg", recipeEntry.id().registry().toString());
|
||||
entry.putString("id_value", recipeEntry.id().location().toString());
|
||||
entry.put("recipe", dr.result().get());
|
||||
list.add(entry);
|
||||
}
|
||||
}));
|
||||
|
||||
nbt.put("RecipeManager", list);
|
||||
sendPacket(player, new HudDataPayload(HudDataPayloadType.PACKET_S2C_NBT_RESPONSE_START, nbt));
|
||||
}
|
||||
|
||||
public static void refreshWeatherData(ServerPlayer player) {
|
||||
if (!LeavesConfig.protocol.servux.hudMetadataProtocol) {
|
||||
return;
|
||||
}
|
||||
|
||||
ServerLevel level = MinecraftServer.getServer().overworld();
|
||||
if (level.getGameRules().getBoolean(GameRules.RULE_WEATHER_CYCLE)) {
|
||||
return;
|
||||
}
|
||||
|
||||
CompoundTag nbt = new CompoundTag();
|
||||
nbt.putString("id", CHANNEL.toString());
|
||||
nbt.putString("servux", ServuxProtocol.SERVUX_STRING);
|
||||
|
||||
if (level.serverLevelData.isRaining() && level.serverLevelData.getRainTime() > -1) {
|
||||
nbt.putInt("SetRaining", level.serverLevelData.getRainTime());
|
||||
nbt.putBoolean("isRaining", true);
|
||||
} else {
|
||||
nbt.putBoolean("isRaining", false);
|
||||
}
|
||||
|
||||
if (level.serverLevelData.isThundering() && level.serverLevelData.getThunderTime() > -1) {
|
||||
nbt.putInt("SetThundering", level.serverLevelData.getThunderTime());
|
||||
nbt.putBoolean("isThundering", true);
|
||||
} else {
|
||||
nbt.putBoolean("isThundering", false);
|
||||
}
|
||||
|
||||
if (level.serverLevelData.getClearWeatherTime() > -1) {
|
||||
nbt.putInt("SetClear", level.serverLevelData.getClearWeatherTime());
|
||||
}
|
||||
|
||||
sendPacket(player, new HudDataPayload(HudDataPayloadType.PACKET_S2C_WEATHER_TICK, nbt));
|
||||
}
|
||||
|
||||
private static void putWorldData(@NotNull CompoundTag metadata) {
|
||||
ServerLevel level = MinecraftServer.getServer().overworld();
|
||||
BlockPos spawnPos = level.levelData.getSpawnPos();
|
||||
metadata.putInt("spawnPosX", spawnPos.getX());
|
||||
metadata.putInt("spawnPosY", spawnPos.getY());
|
||||
metadata.putInt("spawnPosZ", spawnPos.getZ());
|
||||
metadata.putInt("spawnChunkRadius", level.getGameRules().getInt(GameRules.RULE_SPAWN_CHUNK_RADIUS));
|
||||
|
||||
if (LeavesConfig.protocol.servux.hudMetadataShareSeed) {
|
||||
metadata.putLong("worldSeed", level.getSeed());
|
||||
}
|
||||
}
|
||||
|
||||
public static void sendPacket(ServerPlayer player, HudDataPayload payload) {
|
||||
if (!LeavesConfig.protocol.servux.hudMetadataProtocol) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (payload.packetType == HudDataPayloadType.PACKET_S2C_NBT_RESPONSE_START) {
|
||||
FriendlyByteBuf buffer = new FriendlyByteBuf(Unpooled.buffer());
|
||||
buffer.writeNbt(payload.nbt);
|
||||
PacketSplitter.send(ServuxHudDataProtocol::sendWithSplitter, buffer, player);
|
||||
} else {
|
||||
ProtocolUtils.sendPayloadPacket(player, payload);
|
||||
}
|
||||
}
|
||||
|
||||
private static void sendWithSplitter(ServerPlayer player, FriendlyByteBuf buf) {
|
||||
sendPacket(player, new HudDataPayload(HudDataPayloadType.PACKET_S2C_NBT_RESPONSE_DATA, buf));
|
||||
}
|
||||
|
||||
public enum HudDataPayloadType {
|
||||
PACKET_S2C_METADATA(1),
|
||||
PACKET_C2S_METADATA_REQUEST(2),
|
||||
PACKET_S2C_SPAWN_DATA(3),
|
||||
PACKET_C2S_SPAWN_DATA_REQUEST(4),
|
||||
PACKET_S2C_WEATHER_TICK(5),
|
||||
PACKET_C2S_RECIPE_MANAGER_REQUEST(6),
|
||||
// For Packet Splitter (Oversize Packets, S2C)
|
||||
PACKET_S2C_NBT_RESPONSE_START(10),
|
||||
PACKET_S2C_NBT_RESPONSE_DATA(11);
|
||||
|
||||
private static final class Helper {
|
||||
static Map<Integer, HudDataPayloadType> ID_TO_TYPE = new HashMap<>();
|
||||
}
|
||||
|
||||
public final int type;
|
||||
|
||||
HudDataPayloadType(int type) {
|
||||
this.type = type;
|
||||
HudDataPayloadType.Helper.ID_TO_TYPE.put(type, this);
|
||||
}
|
||||
|
||||
public static HudDataPayloadType fromId(int id) {
|
||||
return HudDataPayloadType.Helper.ID_TO_TYPE.get(id);
|
||||
}
|
||||
}
|
||||
|
||||
public record HudDataPayload(HudDataPayloadType packetType, CompoundTag nbt, FriendlyByteBuf buffer) implements LeavesCustomPayload<HudDataPayload> {
|
||||
|
||||
public HudDataPayload(HudDataPayloadType type, CompoundTag nbt) {
|
||||
this(type, nbt, null);
|
||||
}
|
||||
|
||||
public HudDataPayload(HudDataPayloadType type, FriendlyByteBuf buffer) {
|
||||
this(type, new CompoundTag(), buffer);
|
||||
}
|
||||
|
||||
@New
|
||||
@NotNull
|
||||
public static HudDataPayload decode(ResourceLocation location, @NotNull FriendlyByteBuf buf) {
|
||||
HudDataPayloadType type = HudDataPayloadType.fromId(buf.readVarInt());
|
||||
if (type == null) {
|
||||
throw new IllegalStateException("invalid packet type received");
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case PACKET_S2C_NBT_RESPONSE_DATA -> {
|
||||
return new HudDataPayload(type, new FriendlyByteBuf(buf.readBytes(buf.readableBytes())));
|
||||
}
|
||||
|
||||
case PACKET_C2S_METADATA_REQUEST, PACKET_S2C_METADATA, PACKET_C2S_SPAWN_DATA_REQUEST, PACKET_S2C_SPAWN_DATA, PACKET_S2C_WEATHER_TICK,
|
||||
PACKET_C2S_RECIPE_MANAGER_REQUEST -> {
|
||||
return new HudDataPayload(type, buf.readNbt());
|
||||
}
|
||||
}
|
||||
|
||||
throw new IllegalStateException("invalid packet type received");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(@NotNull FriendlyByteBuf buf) {
|
||||
buf.writeVarInt(this.packetType.type);
|
||||
|
||||
switch (this.packetType) {
|
||||
case PACKET_S2C_NBT_RESPONSE_DATA -> buf.writeBytes(this.buffer.copy());
|
||||
case PACKET_C2S_METADATA_REQUEST, PACKET_S2C_METADATA, PACKET_C2S_SPAWN_DATA_REQUEST,
|
||||
PACKET_S2C_SPAWN_DATA, PACKET_S2C_WEATHER_TICK, PACKET_C2S_RECIPE_MANAGER_REQUEST -> buf.writeNbt(this.nbt);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation id() {
|
||||
return CHANNEL;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,6 @@ import io.netty.buffer.Unpooled;
|
||||
import it.unimi.dsi.fastutil.longs.LongIterator;
|
||||
import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
|
||||
import it.unimi.dsi.fastutil.longs.LongSet;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.ListTag;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
@@ -13,7 +12,6 @@ import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.level.ChunkPos;
|
||||
import net.minecraft.world.level.GameRules;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||
import net.minecraft.world.level.chunk.LevelChunk;
|
||||
@@ -46,7 +44,6 @@ public class ServuxStructuresProtocol {
|
||||
private static final int updateInterval = 40;
|
||||
private static final int timeout = 30 * 20;
|
||||
|
||||
public static boolean refreshSpawnMetadata = false;
|
||||
private static int retainDistance;
|
||||
|
||||
public static final ResourceLocation CHANNEL = ServuxProtocol.id("structures");
|
||||
@@ -62,22 +59,10 @@ public class ServuxStructuresProtocol {
|
||||
|
||||
switch (payload.packetType()) {
|
||||
case PACKET_C2S_STRUCTURES_REGISTER -> onPlayerSubscribed(player);
|
||||
case PACKET_C2S_REQUEST_SPAWN_METADATA -> refreshSpawnMetadata(player);
|
||||
case PACKET_C2S_STRUCTURES_UNREGISTER -> {
|
||||
onPlayerLoggedOut(player);
|
||||
refreshSpawnMetadata(player);
|
||||
case PACKET_C2S_REQUEST_SPAWN_METADATA -> ServuxHudDataProtocol.refreshSpawnMetadata(player); // move to
|
||||
case PACKET_C2S_STRUCTURES_UNREGISTER -> onPlayerLoggedOut(player);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ProtocolHandler.PlayerJoin
|
||||
public static void onPlayerLoggedIn(ServerPlayer player) {
|
||||
if (!LeavesConfig.protocol.servux.structureProtocol) {
|
||||
return;
|
||||
}
|
||||
|
||||
onPlayerSubscribed(player);
|
||||
}
|
||||
|
||||
@ProtocolHandler.PlayerLeave
|
||||
public static void onPlayerLoggedOut(@NotNull ServerPlayer player) {
|
||||
@@ -99,17 +84,9 @@ public class ServuxStructuresProtocol {
|
||||
if ((tickCounter % updateInterval) == 0) {
|
||||
retainDistance = server.getPlayerList().getViewDistance() + 2;
|
||||
for (ServerPlayer player : players.values()) {
|
||||
if (refreshSpawnMetadata) {
|
||||
refreshSpawnMetadata(player);
|
||||
}
|
||||
|
||||
// TODO DimensionChange
|
||||
refreshTrackedChunks(player, tickCounter);
|
||||
}
|
||||
|
||||
if (refreshSpawnMetadata) {
|
||||
refreshSpawnMetadata = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -134,23 +111,24 @@ public class ServuxStructuresProtocol {
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean chunkHasStructureReferences(int chunkX, int chunkZ, Level world) {
|
||||
private static boolean chunkHasStructureReferences(int chunkX, int chunkZ, @NotNull Level world) {
|
||||
if (!world.hasChunk(chunkX, chunkZ)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ChunkAccess chunk = world.getChunk(chunkX, chunkZ, ChunkStatus.STRUCTURE_STARTS, false);
|
||||
|
||||
if (chunk != null) {
|
||||
for (Map.Entry<Structure, LongSet> entry : chunk.getAllReferences().entrySet()) {
|
||||
if (!entry.getValue().isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public static void onPlayerSubscribed(@NotNull ServerPlayer player) {
|
||||
if (!players.containsKey(player.getId())) {
|
||||
players.put(player.getId(), player);
|
||||
@@ -158,6 +136,7 @@ public class ServuxStructuresProtocol {
|
||||
LeavesLogger.LOGGER.warning(player.getScoreboardName() + " re-register servux:structures");
|
||||
}
|
||||
|
||||
MinecraftServer server = MinecraftServer.getServer();
|
||||
CompoundTag tag = new CompoundTag();
|
||||
tag.putString("name", "structure_bounding_boxes");
|
||||
tag.putString("id", CHANNEL.toString());
|
||||
@@ -165,32 +144,10 @@ public class ServuxStructuresProtocol {
|
||||
tag.putString("servux", ServuxProtocol.SERVUX_STRING);
|
||||
tag.putInt("timeout", timeout);
|
||||
|
||||
MinecraftServer server = MinecraftServer.getServer();
|
||||
BlockPos spawnPos = server.overworld().levelData.getSpawnPos();
|
||||
tag.putInt("spawnPosX", spawnPos.getX());
|
||||
tag.putInt("spawnPosY", spawnPos.getY());
|
||||
tag.putInt("spawnPosZ", spawnPos.getZ());
|
||||
tag.putInt("spawnChunkRadius", server.getGameRules().getInt(GameRules.RULE_SPAWN_CHUNK_RADIUS));
|
||||
|
||||
sendPacket(player, new StructuresPayload(StructuresPayloadType.PACKET_S2C_METADATA, tag));
|
||||
initialSyncStructures(player, player.moonrise$getViewDistanceHolder().getViewDistances().sendViewDistance() + 2, server.getTickCount());
|
||||
}
|
||||
|
||||
public static void refreshSpawnMetadata(ServerPlayer player) {
|
||||
CompoundTag tag = new CompoundTag();
|
||||
tag.putString("id", CHANNEL.toString());
|
||||
tag.putString("servux", ServuxProtocol.SERVUX_STRING);
|
||||
|
||||
MinecraftServer server = MinecraftServer.getServer();
|
||||
BlockPos spawnPos = server.overworld().levelData.getSpawnPos();
|
||||
tag.putInt("spawnPosX", spawnPos.getX());
|
||||
tag.putInt("spawnPosY", spawnPos.getY());
|
||||
tag.putInt("spawnPosZ", spawnPos.getZ());
|
||||
tag.putInt("spawnChunkRadius", server.getGameRules().getInt(GameRules.RULE_SPAWN_CHUNK_RADIUS));
|
||||
|
||||
sendPacket(player, new StructuresPayload(StructuresPayloadType.PACKET_S2C_SPAWN_METADATA, tag));
|
||||
}
|
||||
|
||||
public static void initialSyncStructures(ServerPlayer player, int chunkRadius, int tickCounter) {
|
||||
UUID uuid = player.getUUID();
|
||||
ChunkPos center = player.getLastSectionPos().chunk();
|
||||
@@ -220,6 +177,7 @@ public class ServuxStructuresProtocol {
|
||||
|
||||
ChunkAccess chunk = world.getChunk(chunkX, chunkZ, ChunkStatus.STRUCTURE_STARTS, false);
|
||||
|
||||
if (chunk != null) {
|
||||
for (Map.Entry<Structure, LongSet> entry : chunk.getAllReferences().entrySet()) {
|
||||
Structure feature = entry.getKey();
|
||||
LongSet startChunks = entry.getValue();
|
||||
@@ -234,6 +192,7 @@ public class ServuxStructuresProtocol {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void sendStructures(ServerPlayer player, Map<Structure, LongSet> references, int tickCounter) {
|
||||
ServerLevel world = player.serverLevel();
|
||||
@@ -280,7 +239,10 @@ public class ServuxStructuresProtocol {
|
||||
}
|
||||
|
||||
ChunkAccess chunk = world.getChunk(pos.x, pos.z, ChunkStatus.STRUCTURE_STARTS, false);
|
||||
StructureStart start = chunk.getStartForStructure(structure);
|
||||
StructureStart start = null;
|
||||
if (chunk != null) {
|
||||
start = chunk.getStartForStructure(structure);
|
||||
}
|
||||
|
||||
if (start != null) {
|
||||
starts.put(pos, start);
|
||||
|
||||
Reference in New Issue
Block a user