mirror of
https://github.com/Xiao-MoMi/craft-engine.git
synced 2025-12-19 15:09:15 +00:00
优化调色盘判断
This commit is contained in:
@@ -25,8 +25,10 @@ import net.momirealms.craftengine.core.plugin.logger.Debugger;
|
||||
import net.momirealms.craftengine.core.registry.Holder;
|
||||
import net.momirealms.craftengine.core.sound.SoundData;
|
||||
import net.momirealms.craftengine.core.sound.SoundSet;
|
||||
import net.momirealms.craftengine.core.util.*;
|
||||
import net.momirealms.craftengine.core.world.chunk.PalettedContainer;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.ObjectHolder;
|
||||
import net.momirealms.craftengine.core.util.Tristate;
|
||||
import net.momirealms.craftengine.core.util.VersionHelper;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.event.HandlerList;
|
||||
@@ -322,9 +324,6 @@ public final class BukkitBlockManager extends AbstractBlockManager {
|
||||
// 注册服务端侧的真实方块
|
||||
private void registerServerSideCustomBlocks(int count) {
|
||||
// 这个会影响全局调色盘
|
||||
if (MiscUtils.ceilLog2(this.vanillaBlockStateCount + count) == MiscUtils.ceilLog2(this.vanillaBlockStateCount)) {
|
||||
PalettedContainer.NEED_DOWNGRADE = false;
|
||||
}
|
||||
try {
|
||||
unfreezeRegistry();
|
||||
for (int i = 0; i < count; i++) {
|
||||
|
||||
@@ -8,4 +8,6 @@ public class BukkitBlockEntityTypes extends BlockEntityTypes {
|
||||
public static final BlockEntityType<SimpleStorageBlockEntity> SIMPLE_STORAGE = register(BlockEntityTypeKeys.SIMPLE_STORAGE, SimpleStorageBlockEntity::new);
|
||||
public static final BlockEntityType<SimpleParticleBlockEntity> SIMPLE_PARTICLE = register(BlockEntityTypeKeys.SIMPLE_PARTICLE, SimpleParticleBlockEntity::new);
|
||||
public static final BlockEntityType<WallTorchParticleBlockEntity> WALL_TORCH_PARTICLE = register(BlockEntityTypeKeys.WALL_TORCH_PARTICLE, WallTorchParticleBlockEntity::new);
|
||||
|
||||
private BukkitBlockEntityTypes() {}
|
||||
}
|
||||
@@ -9,6 +9,8 @@ public class BukkitBlockEntityElementConfigs extends BlockEntityElementConfigs {
|
||||
register(TEXT_DISPLAY, TextDisplayBlockEntityElementConfig.FACTORY);
|
||||
}
|
||||
|
||||
private BukkitBlockEntityElementConfigs() {}
|
||||
|
||||
public static void init() {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -299,7 +299,12 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes
|
||||
}
|
||||
this.blockStateRemapper = newMappings;
|
||||
this.modBlockStateRemapper = newMappingsMOD;
|
||||
registerS2CGamePacketListener(new LevelChunkWithLightListener(newMappings, newMappingsMOD, newMappings.length, RegistryUtils.currentBiomeRegistrySize()), this.packetIds.clientboundLevelChunkWithLightPacket(), "ClientboundLevelChunkWithLightPacket");
|
||||
registerS2CGamePacketListener(new LevelChunkWithLightListener(
|
||||
newMappings,
|
||||
newMappingsMOD,
|
||||
newMappings.length,
|
||||
RegistryUtils.currentBiomeRegistrySize()
|
||||
), this.packetIds.clientboundLevelChunkWithLightPacket(), "ClientboundLevelChunkWithLightPacket");
|
||||
registerS2CGamePacketListener(new SectionBlockUpdateListener(newMappings, newMappingsMOD), this.packetIds.clientboundSectionBlocksUpdatePacket(), "ClientboundSectionBlocksUpdatePacket");
|
||||
registerS2CGamePacketListener(new BlockUpdateListener(newMappings, newMappingsMOD), this.packetIds.clientboundBlockUpdatePacket(), "ClientboundBlockUpdatePacket");
|
||||
registerS2CGamePacketListener(
|
||||
@@ -1922,12 +1927,14 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes
|
||||
private final int[] modBlockStateMapper;
|
||||
private final IntIdentityList biomeList;
|
||||
private final IntIdentityList blockList;
|
||||
private final boolean needsDowngrade;
|
||||
|
||||
public LevelChunkWithLightListener(int[] blockStateMapper, int[] modBlockStateMapper, int blockRegistrySize, int biomeRegistrySize) {
|
||||
this.blockStateMapper = blockStateMapper;
|
||||
this.modBlockStateMapper = modBlockStateMapper;
|
||||
this.biomeList = new IntIdentityList(biomeRegistrySize);
|
||||
this.blockList = new IntIdentityList(blockRegistrySize);
|
||||
this.needsDowngrade = MiscUtils.ceilLog2(BlockStateUtils.vanillaBlockStateCount()) != MiscUtils.ceilLog2(blockRegistrySize);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1936,8 +1943,10 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes
|
||||
FriendlyByteBuf buf = event.getBuffer();
|
||||
int chunkX = buf.readInt();
|
||||
int chunkZ = buf.readInt();
|
||||
ChunkPos chunkPos = new ChunkPos(chunkX, chunkZ);
|
||||
boolean named = !VersionHelper.isOrAbove1_20_2();
|
||||
// ClientboundLevelChunkPacketData
|
||||
|
||||
// 读取区块数据
|
||||
int heightmapsCount = 0;
|
||||
Map<Integer, long[]> heightmapsMap = null;
|
||||
net.momirealms.sparrow.nbt.Tag heightmaps = null;
|
||||
@@ -1956,6 +1965,42 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes
|
||||
int chunkDataBufferSize = buf.readVarInt();
|
||||
byte[] chunkDataBytes = new byte[chunkDataBufferSize];
|
||||
buf.readBytes(chunkDataBytes);
|
||||
|
||||
// 客户端侧section数量很重要,不能读取此时玩家所在的真实世界,包具有滞后性
|
||||
int count = player.clientSideSectionCount();
|
||||
MCSection[] sections = new MCSection[count];
|
||||
FriendlyByteBuf chunkDataByteBuf = new FriendlyByteBuf(Unpooled.wrappedBuffer(chunkDataBytes));
|
||||
|
||||
boolean hasChangedAnyBlock = false;
|
||||
boolean hasGlobalPalette = false;
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
MCSection mcSection = new MCSection(user.clientBlockList(), this.blockList, this.biomeList);
|
||||
mcSection.readPacket(chunkDataByteBuf);
|
||||
PalettedContainer<Integer> container = mcSection.blockStateContainer();
|
||||
remapBiomes(user, mcSection.biomeContainer());
|
||||
Palette<Integer> palette = container.data().palette();
|
||||
if (palette.canRemap()) {
|
||||
if (palette.remapAndCheck(s -> this.blockStateMapper[s])) {
|
||||
hasChangedAnyBlock = true;
|
||||
}
|
||||
} else {
|
||||
hasGlobalPalette = true;
|
||||
for (int j = 0; j < 4096; j++) {
|
||||
int state = container.get(j);
|
||||
int newState = this.blockStateMapper[state];
|
||||
if (newState != state) {
|
||||
container.set(j, newState);
|
||||
hasChangedAnyBlock = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
sections[i] = mcSection;
|
||||
}
|
||||
|
||||
// 只有被修改了,才读后续内容,并改写
|
||||
if (hasChangedAnyBlock || (this.needsDowngrade && hasGlobalPalette)) {
|
||||
// 读取其他非必要信息
|
||||
int blockEntitiesDataCount = buf.readVarInt();
|
||||
List<BlockEntityData> blockEntitiesData = new ArrayList<>();
|
||||
for (int i = 0; i < blockEntitiesDataCount; i++) {
|
||||
@@ -1966,7 +2011,7 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes
|
||||
BlockEntityData blockEntityData = new BlockEntityData(packedXZ, y, type, tag);
|
||||
blockEntitiesData.add(blockEntityData);
|
||||
}
|
||||
// ClientboundLightUpdatePacketData
|
||||
// 光照信息
|
||||
BitSet skyYMask = buf.readBitSet();
|
||||
BitSet blockYMask = buf.readBitSet();
|
||||
BitSet emptySkyYMask = buf.readBitSet();
|
||||
@@ -1974,54 +2019,8 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes
|
||||
List<byte[]> skyUpdates = buf.readByteArrayList(2048);
|
||||
List<byte[]> blockUpdates = buf.readByteArrayList(2048);
|
||||
|
||||
int count = player.clientSideSectionCount();
|
||||
MCSection[] sections = new MCSection[count];
|
||||
|
||||
FriendlyByteBuf chunkDataByteBuf = new FriendlyByteBuf(Unpooled.wrappedBuffer(chunkDataBytes));
|
||||
// 开始处理
|
||||
if (user.clientModEnabled()) {
|
||||
for (int i = 0; i < count; i++) {
|
||||
MCSection mcSection = new MCSection(user.clientBlockList(), this.blockList, this.biomeList);
|
||||
mcSection.readPacket(chunkDataByteBuf);
|
||||
PalettedContainer<Integer> container = mcSection.blockStateContainer();
|
||||
remapBiomes(user, mcSection.biomeContainer());
|
||||
Palette<Integer> palette = container.data().palette();
|
||||
if (palette.canRemap()) {
|
||||
palette.remap(s -> this.modBlockStateMapper[s]);
|
||||
} else {
|
||||
for (int j = 0; j < 4096; j++) {
|
||||
int state = container.get(j);
|
||||
int newState = this.modBlockStateMapper[state];
|
||||
if (newState != state) {
|
||||
container.set(j, newState);
|
||||
}
|
||||
}
|
||||
}
|
||||
sections[i] = mcSection;
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < count; i++) {
|
||||
MCSection mcSection = new MCSection(user.clientBlockList(), this.blockList, this.biomeList);
|
||||
mcSection.readPacket(chunkDataByteBuf);
|
||||
PalettedContainer<Integer> container = mcSection.blockStateContainer();
|
||||
remapBiomes(user, mcSection.biomeContainer());
|
||||
Palette<Integer> palette = container.data().palette();
|
||||
if (palette.canRemap()) {
|
||||
palette.remap(s -> this.blockStateMapper[s]);
|
||||
} else {
|
||||
for (int j = 0; j < 4096; j++) {
|
||||
int state = container.get(j);
|
||||
int newState = this.blockStateMapper[state];
|
||||
if (newState != state) {
|
||||
container.set(j, newState);
|
||||
}
|
||||
}
|
||||
}
|
||||
sections[i] = mcSection;
|
||||
}
|
||||
}
|
||||
|
||||
FriendlyByteBuf newChunkDataBuf = new FriendlyByteBuf(Unpooled.buffer(chunkDataBufferSize));
|
||||
// 预分配容量
|
||||
FriendlyByteBuf newChunkDataBuf = new FriendlyByteBuf(Unpooled.buffer(chunkDataBufferSize + 16));
|
||||
for (int i = 0; i < count; i++) {
|
||||
sections[i].writePacket(newChunkDataBuf);
|
||||
}
|
||||
@@ -2057,11 +2056,14 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes
|
||||
buf.writeBitSet(emptyBlockYMask);
|
||||
buf.writeByteArrayList(skyUpdates);
|
||||
buf.writeByteArrayList(blockUpdates);
|
||||
} else {
|
||||
System.out.println("没变化啊");
|
||||
}
|
||||
|
||||
ChunkPos chunkPos = new ChunkPos(chunkX, chunkZ);
|
||||
// 记录加载的区块
|
||||
player.addTrackedChunk(chunkPos.longKey, new ChunkStatus());
|
||||
|
||||
// 生成方块实体
|
||||
CEWorld ceWorld = BukkitWorldManager.instance().getWorld(player.world().uuid());
|
||||
CEChunk ceChunk = ceWorld.getChunkAtIfLoaded(chunkPos.longKey);
|
||||
if (ceChunk != null) {
|
||||
|
||||
@@ -6,7 +6,7 @@ import net.momirealms.craftengine.core.registry.WritableRegistry;
|
||||
import net.momirealms.craftengine.core.util.Key;
|
||||
import net.momirealms.craftengine.core.util.ResourceKey;
|
||||
|
||||
public class BlockEntityTypes {
|
||||
public abstract class BlockEntityTypes {
|
||||
|
||||
public static <T extends BlockEntity> BlockEntityType<T> register(Key id, BlockEntity.Factory<T> factory) {
|
||||
BlockEntityType<T> type = new BlockEntityType<>(id, factory);
|
||||
|
||||
@@ -10,7 +10,7 @@ import net.momirealms.craftengine.core.util.ResourceKey;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
public class BlockEntityElementConfigs {
|
||||
public abstract class BlockEntityElementConfigs {
|
||||
public static final Key ITEM_DISPLAY = Key.of("craftengine:item_display");
|
||||
public static final Key TEXT_DISPLAY = Key.of("craftengine:text_display");
|
||||
|
||||
|
||||
@@ -35,15 +35,36 @@ public class Int2ObjectBiMap<K> implements IndexedIterable<K> {
|
||||
|
||||
public void remapValues(Function<K, K> function) {
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
if (values[i] == null) break;
|
||||
values[i] = function.apply(values[i]);
|
||||
K prev = values[i];
|
||||
if (prev == null) break;
|
||||
values[i] = function.apply(prev);
|
||||
}
|
||||
for (int i = 0; i < idToValues.length; i++) {
|
||||
if (idToValues[i] == null) break;
|
||||
idToValues[i] = function.apply(idToValues[i]);
|
||||
K prev = idToValues[i];
|
||||
if (prev == null) break;
|
||||
idToValues[i] = function.apply(prev);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean remapValuesAndCheck(Function<K, K> function) {
|
||||
boolean changed = false;
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
K prev = values[i];
|
||||
if (prev == null) break;
|
||||
K apply = function.apply(prev);
|
||||
values[i] = apply;
|
||||
if (apply != prev) {
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < idToValues.length; i++) {
|
||||
K prev = idToValues[i];
|
||||
if (prev == null) break;
|
||||
idToValues[i] = function.apply(prev);
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
public static <A> Int2ObjectBiMap<A> create(int expectedSize) {
|
||||
return new Int2ObjectBiMap<>((int) ((float) expectedSize / LOAD_FACTOR));
|
||||
}
|
||||
|
||||
@@ -108,11 +108,27 @@ public class ArrayPalette<T> implements Palette<T> {
|
||||
@Override
|
||||
public void remap(Function<T, T> function) {
|
||||
for (int i = 0; i < this.array.length; i++) {
|
||||
if (this.array[i] == null) return;
|
||||
this.array[i] = function.apply(this.array[i]);
|
||||
T prev = this.array[i];
|
||||
if (prev == null) return;
|
||||
this.array[i] = function.apply(prev);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean remapAndCheck(Function<T, T> function) {
|
||||
boolean changed = false;
|
||||
for (int i = 0; i < this.array.length; i++) {
|
||||
T prev = this.array[i];
|
||||
if (prev == null) return changed;
|
||||
T newV = function.apply(prev);
|
||||
this.array[i] = newV;
|
||||
if (newV != prev) {
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canRemap() {
|
||||
return true;
|
||||
|
||||
@@ -106,6 +106,11 @@ public class BiMapPalette<T> implements Palette<T> {
|
||||
this.map.remapValues(function);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean remapAndCheck(Function<T, T> function) {
|
||||
return this.map.remapValuesAndCheck(function);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canRemap() {
|
||||
return true;
|
||||
|
||||
@@ -63,6 +63,11 @@ public class IdListPalette<T> implements Palette<T> {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean remapAndCheck(Function<T, T> function) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readPacket(FriendlyByteBuf buf) {
|
||||
}
|
||||
|
||||
@@ -25,6 +25,8 @@ public interface Palette<T> {
|
||||
|
||||
void remap(Function<T, T> function);
|
||||
|
||||
boolean remapAndCheck(Function<T, T> function);
|
||||
|
||||
boolean canRemap();
|
||||
|
||||
interface Factory {
|
||||
|
||||
@@ -23,7 +23,6 @@ import java.util.function.Predicate;
|
||||
import java.util.stream.LongStream;
|
||||
|
||||
public class PalettedContainer<T> implements PaletteResizeListener<T>, ReadableContainer<T> {
|
||||
public static boolean NEED_DOWNGRADE = true;
|
||||
private static final BiConsumer<FriendlyByteBuf, long[]> RAW_DATA_WRITER = VersionHelper.isOrAbove1_21_5() ?
|
||||
(FriendlyByteBuf::writeFixedSizeLongArray) : (FriendlyByteBuf::writeLongArray);
|
||||
private static final BiConsumer<FriendlyByteBuf, long[]> RAW_DATA_READER = VersionHelper.isOrAbove1_21_5() ?
|
||||
@@ -75,10 +74,7 @@ public class PalettedContainer<T> implements PaletteResizeListener<T>, ReadableC
|
||||
return false;
|
||||
}
|
||||
|
||||
public PalettedContainer<T> downgradeTo(IndexedIterable<T> idList) {
|
||||
if (!NEED_DOWNGRADE) {
|
||||
return this;
|
||||
}
|
||||
public PalettedContainer<T> getClientCompatiblePalettedContainer(IndexedIterable<T> idList) {
|
||||
Palette<T> palette = this.data.palette;
|
||||
if (!(palette instanceof IdListPalette<T> idListPalette)) {
|
||||
return this;
|
||||
|
||||
@@ -73,6 +73,13 @@ public class SingularPalette<T> implements Palette<T> {
|
||||
this.entry = function.apply(this.entry);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean remapAndCheck(Function<T, T> function) {
|
||||
T previous = this.entry;
|
||||
this.entry = function.apply(previous);
|
||||
return previous == this.entry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canRemap() {
|
||||
return true;
|
||||
|
||||
@@ -26,7 +26,7 @@ public class MCSection {
|
||||
|
||||
public void writePacket(FriendlyByteBuf buf) {
|
||||
buf.writeShort(this.nonEmptyBlockCount);
|
||||
this.serverBlockStateContainer.downgradeTo(this.clientBlockStateList).writePacket(buf);
|
||||
this.serverBlockStateContainer.getClientCompatiblePalettedContainer(this.clientBlockStateList).writePacket(buf);
|
||||
this.biomeContainer.writePacket(buf);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user