9
0
mirror of https://github.com/Xiao-MoMi/craft-engine.git synced 2025-12-30 04:19:27 +00:00

优化区块读写性能

This commit is contained in:
XiaoMoMi
2025-08-30 20:22:44 +08:00
parent 81087ea003
commit 16334e0c88
20 changed files with 107 additions and 58 deletions

View File

@@ -11,8 +11,8 @@ import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine;
import net.momirealms.craftengine.bukkit.plugin.network.id.PacketIdFinder;
import net.momirealms.craftengine.bukkit.plugin.network.id.PacketIds1_20;
import net.momirealms.craftengine.bukkit.plugin.network.id.PacketIds1_20_5;
import net.momirealms.craftengine.bukkit.plugin.reflection.leaves.LeavesReflections;
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.CoreReflections;
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.LeavesReflections;
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.LibraryReflections;
import net.momirealms.craftengine.bukkit.plugin.reflection.minecraft.NetworkReflections;
import net.momirealms.craftengine.bukkit.plugin.user.BukkitServerPlayer;
@@ -213,6 +213,7 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes
registerNMSPacketConsumer(PacketConsumers.LOGIN_FINISHED, NetworkReflections.clazz$ClientboundLoginFinishedPacket);
registerNMSPacketConsumer(PacketConsumers.UPDATE_TAGS, NetworkReflections.clazz$ClientboundUpdateTagsPacket);
registerNMSPacketConsumer(PacketConsumers.CONTAINER_CLICK_1_21_5, VersionHelper.isOrAbove1_21_5() ? NetworkReflections.clazz$ServerboundContainerClickPacket : null);
registerS2CByteBufPacketConsumer(PacketConsumers.FORGET_LEVEL_CHUNK, this.packetIds.clientboundForgetLevelChunkPacket());
registerS2CByteBufPacketConsumer(PacketConsumers.LEVEL_CHUNK_WITH_LIGHT, this.packetIds.clientboundLevelChunkWithLightPacket());
registerS2CByteBufPacketConsumer(PacketConsumers.SECTION_BLOCK_UPDATE, this.packetIds.clientboundSectionBlocksUpdatePacket());
registerS2CByteBufPacketConsumer(PacketConsumers.BLOCK_UPDATE, this.packetIds.clientboundBlockUpdatePacket());

View File

@@ -64,10 +64,7 @@ import net.momirealms.craftengine.core.plugin.logger.Debugger;
import net.momirealms.craftengine.core.plugin.network.*;
import net.momirealms.craftengine.core.plugin.text.component.ComponentProvider;
import net.momirealms.craftengine.core.util.*;
import net.momirealms.craftengine.core.world.BlockHitResult;
import net.momirealms.craftengine.core.world.BlockPos;
import net.momirealms.craftengine.core.world.EntityHitResult;
import net.momirealms.craftengine.core.world.WorldEvents;
import net.momirealms.craftengine.core.world.*;
import net.momirealms.craftengine.core.world.chunk.Palette;
import net.momirealms.craftengine.core.world.chunk.PalettedContainer;
import net.momirealms.craftengine.core.world.chunk.packet.BlockEntityData;
@@ -75,6 +72,7 @@ import net.momirealms.craftengine.core.world.chunk.packet.MCSection;
import net.momirealms.craftengine.core.world.collision.AABB;
import net.momirealms.sparrow.nbt.Tag;
import org.bukkit.*;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
@@ -261,12 +259,29 @@ public class PacketConsumers {
return MOD_BLOCK_STATE_MAPPINGS[stateId];
}
public static final BiConsumer<NetWorkUser, ByteBufPacketEvent> FORGET_LEVEL_CHUNK = (user, event) -> {
try {
FriendlyByteBuf buf = event.getBuffer();
if (VersionHelper.isOrAbove1_20_2()) {
long chunkPos = buf.readLong();
user.setChunkTrackStatus(new ChunkPos(chunkPos), false);
} else {
int x = buf.readInt();
int y = buf.readInt();
user.setChunkTrackStatus(ChunkPos.of(x, y), false);
}
} catch (Exception e) {
CraftEngine.instance().logger().warn("Failed to handle ClientboundForgetLevelChunkPacket", e);
}
};
public static final BiConsumer<NetWorkUser, ByteBufPacketEvent> LEVEL_CHUNK_WITH_LIGHT = (user, event) -> {
try {
BukkitServerPlayer player = (BukkitServerPlayer) user;
FriendlyByteBuf buf = event.getBuffer();
int chunkX = buf.readInt();
int chunkZ = buf.readInt();
player.setChunkTrackStatus(ChunkPos.of(chunkX, chunkZ), true);
boolean named = !VersionHelper.isOrAbove1_20_2();
// ClientboundLevelChunkPacketData
int heightmapsCount = 0;
@@ -1262,6 +1277,7 @@ public class PacketConsumers {
int sectionCount = (world.getMaxHeight() - world.getMinHeight()) / 16;
player.setClientSideSectionCount(sectionCount);
player.setClientSideDimension(Key.of(location.toString()));
player.clearTrackedChunks();
} else {
CraftEngine.instance().logger().warn("Failed to handle ClientboundRespawnPacket: World " + location + " does not exist");
}

View File

@@ -67,4 +67,6 @@ public interface PacketIds {
int serverboundInteractPacket();
int clientboundUpdateRecipesPacket();
int clientboundForgetLevelChunkPacket();
}

View File

@@ -169,4 +169,9 @@ public class PacketIds1_20 implements PacketIds {
public int clientboundUpdateAdvancementsPacket() {
return PacketIdFinder.clientboundByClazz(NetworkReflections.clazz$ClientboundUpdateAdvancementsPacket);
}
@Override
public int clientboundForgetLevelChunkPacket() {
return PacketIdFinder.clientboundByClazz(NetworkReflections.clazz$ClientboundForgetLevelChunkPacket);
}
}

View File

@@ -168,4 +168,9 @@ public class PacketIds1_20_5 implements PacketIds {
public int serverboundInteractPacket() {
return PacketIdFinder.serverboundByName("minecraft:interact");
}
@Override
public int clientboundForgetLevelChunkPacket() {
return PacketIdFinder.clientboundByName("minecraft:forget_level_chunk");
}
}

View File

@@ -1,4 +1,4 @@
package net.momirealms.craftengine.bukkit.plugin.reflection.minecraft;
package net.momirealms.craftengine.bukkit.plugin.reflection.leaves;
//import net.momirealms.craftengine.core.util.MiscUtils;
//import net.momirealms.craftengine.core.util.ReflectionUtils;

View File

@@ -1665,4 +1665,11 @@ public final class NetworkReflections {
),
VersionHelper.isOrAbove1_21_5()
);
public static final Class<?> clazz$ClientboundForgetLevelChunkPacket = requireNonNull(
BukkitReflectionUtils.findReobfOrMojmapClass(
"network.protocol.game.PacketPlayOutUnloadChunk",
"network.protocol.game.ClientboundForgetLevelChunkPacket"
)
);
}

View File

@@ -34,6 +34,7 @@ import net.momirealms.craftengine.core.util.Direction;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.VersionHelper;
import net.momirealms.craftengine.core.world.BlockPos;
import net.momirealms.craftengine.core.world.ChunkPos;
import net.momirealms.craftengine.core.world.World;
import net.momirealms.craftengine.core.world.WorldEvents;
import org.bukkit.*;
@@ -109,7 +110,11 @@ public class BukkitServerPlayer extends Player {
private double cachedInteractionRange;
// cooldown data
private CooldownData cooldownData;
// tracked chunks
private final Set<ChunkPos> trackedChunks = Collections.synchronizedSet(new HashSet<>());
// relighted chunks
private final Set<ChunkPos> relightedChunks = Collections.synchronizedSet(new HashSet<>());
// entity view
private final Map<Integer, EntityPacketHandler> entityTypeView = new ConcurrentHashMap<>();
public BukkitServerPlayer(BukkitCraftEngine plugin, @Nullable Channel channel) {
@@ -497,9 +502,6 @@ public class BukkitServerPlayer extends Player {
Item<ItemStack> tool = getItemInHand(InteractionHand.MAIN_HAND);
boolean isCorrectTool = FastNMS.INSTANCE.method$ItemStack$isCorrectToolForDrops(tool.getLiteralObject(), blockState);
// 如果自定义方块在服务端侧未使用正确的工具,那么需要还原挖掘速度
if (!isCorrectTool) {
progress *= (10f / 3f);
}
if (!BlockStateUtils.isCorrectTool(customState, tool)) {
progress *= customState.settings().incorrectToolSpeed();
}
@@ -1032,4 +1034,23 @@ public class BukkitServerPlayer extends Player {
public CooldownData cooldown() {
return this.cooldownData;
}
@Override
public boolean isChunkTracked(ChunkPos chunkPos) {
return this.trackedChunks.contains(chunkPos);
}
@Override
public void setChunkTrackStatus(ChunkPos chunkPos, boolean tracked) {
if (tracked) {
this.trackedChunks.add(chunkPos);
} else {
this.trackedChunks.remove(chunkPos);
}
}
@Override
public void clearTrackedChunks() {
this.trackedChunks.clear();
}
}

View File

@@ -1,5 +1,6 @@
package net.momirealms.craftengine.bukkit.world;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import net.momirealms.craftengine.bukkit.nms.FastNMS;
import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine;
import net.momirealms.craftengine.bukkit.plugin.injector.WorldStorageInjector;
@@ -29,7 +30,6 @@ import org.bukkit.event.world.*;
import org.jetbrains.annotations.NotNull;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
@@ -53,7 +53,7 @@ public class BukkitWorldManager implements WorldManager, Listener {
public BukkitWorldManager(BukkitCraftEngine plugin) {
instance = this;
this.plugin = plugin;
this.worlds = new HashMap<>();
this.worlds = new Object2ObjectOpenHashMap<>(32, 0.5f);
this.storageAdaptor = new DefaultStorageAdaptor();
for (World world : Bukkit.getWorlds()) {
this.worlds.put(world.getUID(), new BukkitCEWorld(new BukkitWorld(world), this.storageAdaptor));