From 2aa75f717810c7833f589e4da21990bade5529c2 Mon Sep 17 00:00:00 2001 From: XiaoMoMi <972454774@qq.com> Date: Sun, 28 Sep 2025 18:59:14 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=8D=E6=9E=84=E5=A3=B0=E9=9F=B3part=201?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bukkit/block/BlockEventListener.java | 64 ++++++--------- .../bukkit/block/BukkitBlockManager.java | 81 ++++++++++++++++--- .../plugin/network/BukkitNetworkManager.java | 44 ++++------ .../core/block/AbstractBlockManager.java | 63 ++++++++------- .../craftengine/core/util/GsonHelper.java | 20 ++--- gradle.properties | 2 +- 6 files changed, 152 insertions(+), 122 deletions(-) diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BlockEventListener.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BlockEventListener.java index e72055d3c..0a6cf5176 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BlockEventListener.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BlockEventListener.java @@ -73,18 +73,14 @@ public final class BlockEventListener implements Listener { // send sound if the placed block's sounds are removed if (Config.enableSoundSystem()) { Block block = event.getBlock(); - Object blockState = BlockStateUtils.blockDataToBlockState(block.getBlockData()); - if (blockState != MBlocks.AIR$defaultState) { - Object ownerBlock = BlockStateUtils.getBlockOwner(blockState); - if (this.manager.isBlockSoundRemoved(ownerBlock)) { + Object blockState = BlockStateUtils.getBlockState(block); + if (blockState != MBlocks.AIR$defaultState && BlockStateUtils.isVanillaBlock(blockState)) { + Object soundType = FastNMS.INSTANCE.method$BlockBehaviour$BlockStateBase$getSoundType(blockState); + Object soundEvent = FastNMS.INSTANCE.field$SoundType$placeSound(soundType); + Object soundId = FastNMS.INSTANCE.field$SoundEvent$location(soundEvent); + if (this.manager.isPlaceSoundMissing(soundId)) { if (player.getInventory().getItemInMainHand().getType() != Material.DEBUG_STICK) { - try { - Object soundType = CoreReflections.field$BlockBehaviour$soundType.get(ownerBlock); - Object placeSound = CoreReflections.field$SoundType$placeSound.get(soundType); - player.playSound(block.getLocation().add(0.5, 0.5, 0.5), FastNMS.INSTANCE.field$SoundEvent$location(placeSound).toString(), SoundCategory.BLOCKS, 1f, 0.8f); - } catch (ReflectiveOperationException e) { - this.plugin.logger().warn("Failed to get sound type", e); - } + player.playSound(block.getLocation().add(0.5, 0.5, 0.5), soundId.toString(), SoundCategory.BLOCKS, 1f, 0.8f); } return; } @@ -92,23 +88,19 @@ public final class BlockEventListener implements Listener { } // resend sound if the clicked block is interactable on client side if (serverPlayer.shouldResendSound()) { - try { - Block block = event.getBlock(); - Object blockState = BlockStateUtils.blockDataToBlockState(block.getBlockData()); - Object ownerBlock = BlockStateUtils.getBlockOwner(blockState); - Object soundType = CoreReflections.field$BlockBehaviour$soundType.get(ownerBlock); - Object placeSound = CoreReflections.field$SoundType$placeSound.get(soundType); - player.playSound(block.getLocation().add(0.5, 0.5, 0.5), FastNMS.INSTANCE.field$SoundEvent$location(placeSound).toString(), SoundCategory.BLOCKS, 1f, 0.8f); - } catch (ReflectiveOperationException e) { - this.plugin.logger().warn("Failed to get sound type", e); - } + Block block = event.getBlock(); + Object blockState = BlockStateUtils.getBlockState(block); + Object soundType = FastNMS.INSTANCE.method$BlockBehaviour$BlockStateBase$getSoundType(blockState); + Object soundEvent = FastNMS.INSTANCE.field$SoundType$placeSound(soundType); + Object soundId = FastNMS.INSTANCE.field$SoundEvent$location(soundEvent); + player.playSound(block.getLocation().add(0.5, 0.5, 0.5), soundId.toString(), SoundCategory.BLOCKS, 1f, 0.8f); } } @EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR) public void onPlayerBreak(BlockBreakEvent event) { org.bukkit.block.Block block = event.getBlock(); - Object blockState = BlockStateUtils.blockDataToBlockState(block.getBlockData()); + Object blockState = BlockStateUtils.getBlockState(block); int stateId = BlockStateUtils.blockStateToId(blockState); Player player = event.getPlayer(); Location location = block.getLocation(); @@ -194,15 +186,11 @@ public final class BlockEventListener implements Listener { } // sound system if (Config.enableSoundSystem()) { - Object ownerBlock = BlockStateUtils.getBlockOwner(blockState); - if (this.manager.isBlockSoundRemoved(ownerBlock)) { - try { - Object soundType = CoreReflections.field$BlockBehaviour$soundType.get(ownerBlock); - Object breakSound = CoreReflections.field$SoundType$breakSound.get(soundType); - player.playSound(block.getLocation().add(0.5, 0.5, 0.5), FastNMS.INSTANCE.field$SoundEvent$location(breakSound).toString(), SoundCategory.BLOCKS, 1f, 0.8f); - } catch (ReflectiveOperationException e) { - this.plugin.logger().warn("Failed to get sound type", e); - } + Object soundType = FastNMS.INSTANCE.method$BlockBehaviour$BlockStateBase$getSoundType(blockState); + Object soundEvent = FastNMS.INSTANCE.field$SoundType$breakSound(soundType); + Object soundId = FastNMS.INSTANCE.field$SoundEvent$location(soundEvent); + if (this.manager.isBreakSoundMissing(soundId)) { + player.playSound(block.getLocation().add(0.5, 0.5, 0.5), soundId.toString(), SoundCategory.BLOCKS, 1f, 0.8f); } } } @@ -259,15 +247,11 @@ public final class BlockEventListener implements Listener { } player.playSound(location, state.settings().sounds().stepSound().id().toString(), SoundCategory.BLOCKS, state.settings().sounds().stepSound().volume().get(), state.settings().sounds().stepSound().pitch().get()); } else if (Config.enableSoundSystem()) { - Object ownerBlock = BlockStateUtils.getBlockOwner(blockState); - if (this.manager.isBlockSoundRemoved(ownerBlock)) { - try { - Object soundType = CoreReflections.field$BlockBehaviour$soundType.get(ownerBlock); - Object stepSound = CoreReflections.field$SoundType$stepSound.get(soundType); - player.playSound(player.getLocation(), FastNMS.INSTANCE.field$SoundEvent$location(stepSound).toString(), SoundCategory.BLOCKS, 0.15f, 1f); - } catch (ReflectiveOperationException e) { - this.plugin.logger().warn("Failed to get sound type", e); - } + Object soundType = FastNMS.INSTANCE.method$BlockBehaviour$BlockStateBase$getSoundType(blockState); + Object soundEvent = FastNMS.INSTANCE.field$SoundType$stepSound(soundType); + Object soundId = FastNMS.INSTANCE.field$SoundEvent$location(soundEvent); + if (this.manager.isStepSoundMissing(soundId)) { + player.playSound(player.getLocation(), soundId.toString(), SoundCategory.BLOCKS, 0.15f, 1f); } } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BukkitBlockManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BukkitBlockManager.java index 48d1fa1b1..01f3ab547 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BukkitBlockManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/block/BukkitBlockManager.java @@ -1,6 +1,8 @@ package net.momirealms.craftengine.bukkit.block; import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; import net.momirealms.craftengine.bukkit.block.behavior.UnsafeCompositeBlockBehavior; import net.momirealms.craftengine.bukkit.nms.FastNMS; import net.momirealms.craftengine.bukkit.plugin.BukkitCraftEngine; @@ -31,6 +33,7 @@ import org.bukkit.event.HandlerList; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.lang.reflect.Field; import java.util.*; public final class BukkitBlockManager extends AbstractBlockManager { @@ -40,7 +43,11 @@ public final class BukkitBlockManager extends AbstractBlockManager { private static BukkitBlockManager instance; private final BukkitCraftEngine plugin; // 事件监听器 - private BlockEventListener blockEventListener; + private final BlockEventListener blockEventListener; + // 用于缓存string形式的方块状态到原版方块状态 + private final Map blockStateCache = new HashMap<>(1024); + // 用于临时存储可燃烧自定义方块的列表 + private final List burnableBlocks = new ArrayList<>(); // 可燃烧的方块 private Map igniteOdds; private Map burnOdds; @@ -50,15 +57,15 @@ public final class BukkitBlockManager extends AbstractBlockManager { // 缓存的原版方块tag包 private Object cachedUpdateTagsPacket; // 被移除声音的原版方块 - private final Set replacedBlockSounds = new HashSet<>(); - // 用于缓存string形式的方块状态到原版方块状态 - private final Map blockStateCache = new HashMap<>(1024); - // 用于临时存储可燃烧自定义方块的列表 - private final List burnableBlocks = new ArrayList<>(); + private Set missingPlaceSounds = Set.of(); + private Set missingBreakSounds = Set.of(); + private Set missingHitSounds = Set.of(); + private Set missingStepSounds = Set.of(); public BukkitBlockManager(BukkitCraftEngine plugin) { super(plugin, RegistryUtils.currentBlockRegistrySize(), Config.serverSideBlocks()); this.plugin = plugin; + this.blockEventListener = new BlockEventListener(plugin, this); this.registerServerSideCustomBlocks(Config.serverSideBlocks()); EmptyBlock.initialize(); instance = this; @@ -71,7 +78,6 @@ public final class BukkitBlockManager extends AbstractBlockManager { this.initVanillaBlockSettings(); this.deceiveBukkitRegistry(); this.markVanillaNoteBlocks(); - this.blockEventListener = new BlockEventListener(plugin, this); Arrays.fill(this.immutableBlockStates, EmptyBlock.INSTANCE.defaultState()); this.plugin.networkManager().registerBlockStatePacketListeners(this.blockStateMappings); // 一定要预先初始化一次,预防id超出上限 } @@ -411,8 +417,20 @@ public final class BukkitBlockManager extends AbstractBlockManager { this.clientBoundTags.put(FastNMS.INSTANCE.method$IdMap$getId(MBuiltInRegistries.BLOCK, block).orElseThrow(() -> new IllegalStateException("Block " + id + " not found")), tags); } - public boolean isBlockSoundRemoved(Object block) { - return this.replacedBlockSounds.contains(block); + public boolean isPlaceSoundMissing(Object sound) { + return this.missingPlaceSounds.contains(sound); + } + + public boolean isBreakSoundMissing(Object sound) { + return this.missingBreakSounds.contains(sound); + } + + public boolean isHitSoundMissing(Object sound) { + return this.missingHitSounds.contains(sound); + } + + public boolean isStepSoundMissing(Object sound) { + return this.missingStepSounds.contains(sound); } private void unfreezeRegistry() { @@ -463,6 +481,51 @@ public final class BukkitBlockManager extends AbstractBlockManager { return this.vanillaBlockStateCount; } + @SuppressWarnings("DuplicatedCode") + @Override + protected void processSounds() { + Set affectedBlockSoundTypes = new HashSet<>(); + for (BlockStateWrapper vanillaBlockState : super.tempVisualBlocksInUse) { + affectedBlockSoundTypes.add(FastNMS.INSTANCE.method$BlockBehaviour$BlockStateBase$getSoundType(vanillaBlockState.literalObject())); + } + + Set placeSounds = new HashSet<>(); + Set breakSounds = new HashSet<>(); + Set stepSounds = new HashSet<>(); + Set hitSounds = new HashSet<>(); + + for (Object soundType : affectedBlockSoundTypes) { + placeSounds.add(FastNMS.INSTANCE.field$SoundEvent$location(FastNMS.INSTANCE.field$SoundType$placeSound(soundType))); + breakSounds.add(FastNMS.INSTANCE.field$SoundEvent$location(FastNMS.INSTANCE.field$SoundType$breakSound(soundType))); + stepSounds.add(FastNMS.INSTANCE.field$SoundEvent$location(FastNMS.INSTANCE.field$SoundType$stepSound(soundType))); + hitSounds.add(FastNMS.INSTANCE.field$SoundEvent$location(FastNMS.INSTANCE.field$SoundType$hitSound(soundType))); + } + + ImmutableMap.Builder soundReplacementBuilder = ImmutableMap.builder(); + for (Object soundId : placeSounds) { + Key previousId = KeyUtils.resourceLocationToKey(soundId); + soundReplacementBuilder.put(previousId, Key.of(previousId.namespace(), "replaced." + previousId.value())); + } + for (Object soundId : breakSounds) { + Key previousId = KeyUtils.resourceLocationToKey(soundId); + soundReplacementBuilder.put(previousId, Key.of(previousId.namespace(), "replaced." + previousId.value())); + } + for (Object soundId : stepSounds) { + Key previousId = KeyUtils.resourceLocationToKey(soundId); + soundReplacementBuilder.put(previousId, Key.of(previousId.namespace(), "replaced." + previousId.value())); + } + for (Object soundId : hitSounds) { + Key previousId = KeyUtils.resourceLocationToKey(soundId); + soundReplacementBuilder.put(previousId, Key.of(previousId.namespace(), "replaced." + previousId.value())); + } + + this.missingPlaceSounds = placeSounds; + this.missingBreakSounds = breakSounds; + this.missingHitSounds = hitSounds; + this.missingStepSounds = stepSounds; + this.soundReplacements = soundReplacementBuilder.buildKeepingLast(); + } + @Override protected CustomBlock createCustomBlock(@NotNull Holder.Reference holder, @NotNull BlockStateVariantProvider variantProvider, diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/BukkitNetworkManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/BukkitNetworkManager.java index 3403b6124..733013ca6 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/BukkitNetworkManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/BukkitNetworkManager.java @@ -1037,8 +1037,10 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes // not a custom block if (BlockStateUtils.isVanillaBlock(stateId)) { if (Config.enableSoundSystem()) { - Object blockOwner = FastNMS.INSTANCE.method$BlockState$getBlock(blockState); - if (BukkitBlockManager.instance().isBlockSoundRemoved(blockOwner)) { + Object soundType = FastNMS.INSTANCE.method$BlockBehaviour$BlockStateBase$getSoundType(blockState); + Object soundEvent = FastNMS.INSTANCE.field$SoundType$hitSound(soundType); + Object soundId = FastNMS.INSTANCE.field$SoundEvent$location(soundEvent); + if (BukkitBlockManager.instance().isHitSoundMissing(soundId)) { player.startMiningBlock(pos, blockState, null); return; } @@ -2293,47 +2295,31 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes int state = buf.readInt(); boolean global = buf.readBoolean(); int newState = user.clientModEnabled() ? modBlockStateMapper[state] : blockStateMapper[state]; + Object blockState = BlockStateUtils.idToBlockState(state); + Object soundType = FastNMS.INSTANCE.method$BlockBehaviour$BlockStateBase$getSoundType(blockState); + Object soundEvent = FastNMS.INSTANCE.field$SoundType$breakSound(soundType); + Object rawSoundId = FastNMS.INSTANCE.field$SoundEvent$location(soundEvent); if (BlockStateUtils.isVanillaBlock(state)) { - Object blockState = BlockStateUtils.idToBlockState(state); - Object block = BlockStateUtils.getBlockOwner(blockState); - if (BukkitBlockManager.instance().isBlockSoundRemoved(block)) { - Object soundType = FastNMS.INSTANCE.method$BlockBehaviour$BlockStateBase$getSoundType(blockState); - Object breakSound = FastNMS.INSTANCE.field$SoundType$breakSound(soundType); - Key soundId = Key.of(FastNMS.INSTANCE.field$SoundEvent$location(breakSound).toString()); - Key mappedSoundId = BukkitBlockManager.instance().replaceSoundIfExist(soundId); + if (BukkitBlockManager.instance().isBreakSoundMissing(rawSoundId)) { + Key mappedSoundId = BukkitBlockManager.instance().replaceSoundIfExist(KeyUtils.resourceLocationToKey(rawSoundId)); if (mappedSoundId != null) { - Object mappedBreakSound = FastNMS.INSTANCE.constructor$SoundEvent(KeyUtils.toResourceLocation(mappedSoundId), Optional.empty()); - Object mappedBreakSoundHolder = FastNMS.INSTANCE.method$Holder$direct(mappedBreakSound); Object packet = FastNMS.INSTANCE.constructor$ClientboundSoundPacket( - mappedBreakSoundHolder, + FastNMS.INSTANCE.method$Holder$direct(FastNMS.INSTANCE.constructor$SoundEvent(KeyUtils.toResourceLocation(mappedSoundId), Optional.empty())), CoreReflections.instance$SoundSource$BLOCKS, - blockPos.x() + 0.5, - blockPos.y() + 0.5, - blockPos.z() + 0.5, - 1f, - 0.8F, + blockPos.x() + 0.5, blockPos.y() + 0.5, blockPos.z() + 0.5, 1f, 0.8F, RandomUtils.generateRandomLong() ); user.sendPacket(packet, true); } } } else { - Object blockState = BlockStateUtils.idToBlockState(state); - Object soundType = FastNMS.INSTANCE.method$BlockBehaviour$BlockStateBase$getSoundType(blockState); - Object breakSound = FastNMS.INSTANCE.field$SoundType$breakSound(soundType); - Key soundId = Key.of(FastNMS.INSTANCE.field$SoundEvent$location(breakSound).toString()); + Key soundId = KeyUtils.resourceLocationToKey(rawSoundId); Key mappedSoundId = BukkitBlockManager.instance().replaceSoundIfExist(soundId); Object finalSoundId = KeyUtils.toResourceLocation(mappedSoundId == null ? soundId : mappedSoundId); - Object mappedBreakSound = FastNMS.INSTANCE.constructor$SoundEvent(finalSoundId, Optional.empty()); - Object mappedBreakSoundHolder = FastNMS.INSTANCE.method$Holder$direct(mappedBreakSound); Object packet = FastNMS.INSTANCE.constructor$ClientboundSoundPacket( - mappedBreakSoundHolder, + FastNMS.INSTANCE.method$Holder$direct(FastNMS.INSTANCE.constructor$SoundEvent(finalSoundId, Optional.empty())), CoreReflections.instance$SoundSource$BLOCKS, - blockPos.x() + 0.5, - blockPos.y() + 0.5, - blockPos.z() + 0.5, - 1f, - 0.8F, + blockPos.x() + 0.5, blockPos.y() + 0.5, blockPos.z() + 0.5, 1f, 0.8F, RandomUtils.generateRandomLong() ); user.sendPacket(packet, true); diff --git a/core/src/main/java/net/momirealms/craftengine/core/block/AbstractBlockManager.java b/core/src/main/java/net/momirealms/craftengine/core/block/AbstractBlockManager.java index c1a8fd25a..6687d6731 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/block/AbstractBlockManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/block/AbstractBlockManager.java @@ -14,10 +14,7 @@ import net.momirealms.craftengine.core.block.parser.BlockNbtParser; import net.momirealms.craftengine.core.block.properties.Properties; import net.momirealms.craftengine.core.block.properties.Property; import net.momirealms.craftengine.core.loot.LootTable; -import net.momirealms.craftengine.core.pack.LoadingSequence; -import net.momirealms.craftengine.core.pack.Pack; -import net.momirealms.craftengine.core.pack.PendingConfigSection; -import net.momirealms.craftengine.core.pack.ResourceLocation; +import net.momirealms.craftengine.core.pack.*; import net.momirealms.craftengine.core.pack.cache.IdAllocator; import net.momirealms.craftengine.core.pack.model.generation.AbstractModelGenerator; import net.momirealms.craftengine.core.pack.model.generation.ModelGeneration; @@ -65,8 +62,6 @@ public abstract class AbstractBlockManager extends AbstractModelGenerator implem protected final Map modBlockStateOverrides = new HashMap<>(); // 根据外观查找真实状态,用于debug指令 protected final Map> appearanceToRealState = new Int2ObjectOpenHashMap<>(); - // 声音映射表,和使用了哪些视觉方块有关 - protected final Map soundReplacements = new HashMap<>(512, 0.5f); // 用于note_block:0这样格式的自动分配 protected final Map> blockStateArranger = new HashMap<>(); // 根据registry id找note_block:x中的x值 @@ -83,6 +78,10 @@ public abstract class AbstractBlockManager extends AbstractModelGenerator implem protected final ImmutableBlockState[] immutableBlockStates; // 原版方块的属性缓存 protected final BlockSettings[] vanillaBlockSettings; + // 临时存储哪些视觉方块被使用了 + protected final Set tempVisualBlocksInUse = new HashSet<>(); + // 声音映射表,和使用了哪些视觉方块有关 + protected Map soundReplacements = Map.of(); protected AbstractBlockManager(CraftEngine plugin, int vanillaBlockStateCount, int customBlockCount) { super(plugin); @@ -122,7 +121,6 @@ public abstract class AbstractBlockManager extends AbstractModelGenerator implem this.blockStateOverrides.clear(); this.modBlockStateOverrides.clear(); this.byId.clear(); - this.soundReplacements.clear(); this.blockStateArranger.clear(); this.reversedBlockStateArranger.clear(); this.appearanceToRealState.clear(); @@ -133,8 +131,9 @@ public abstract class AbstractBlockManager extends AbstractModelGenerator implem @Override public void delayedLoad() { this.initSuggestions(); - this.clearCache(); this.resendTags(); + this.processSounds(); + this.clearCache(); } @Override @@ -147,24 +146,6 @@ public abstract class AbstractBlockManager extends AbstractModelGenerator implem return Optional.ofNullable(this.byId.get(id)); } - protected void addCustomBlock(CustomBlock customBlock) { - // 绑定外观状态等 - for (ImmutableBlockState state : customBlock.variantProvider().states()) { - int internalId = state.customBlockState().registryId(); - int appearanceId = state.vanillaBlockState().registryId(); - int index = internalId - this.vanillaBlockStateCount; - this.immutableBlockStates[index] = state; - this.blockStateMappings[internalId] = appearanceId; - this.appearanceToRealState.computeIfAbsent(appearanceId, k -> new IntArrayList()).add(internalId); - this.applyPlatformSettings(state); - // generate mod assets - if (Config.generateModAssets()) { - this.modBlockStateOverrides.put(getBlockOwnerId(state.customBlockState()), this.tempVanillaBlockStateModels.get(appearanceId)); - } - } - this.byId.put(customBlock.id(), customBlock); - } - protected abstract void applyPlatformSettings(ImmutableBlockState state); @Override @@ -203,6 +184,7 @@ public abstract class AbstractBlockManager extends AbstractModelGenerator implem protected void clearCache() { this.tempVanillaBlockStateModels.clear(); + this.tempVisualBlocksInUse.clear(); } protected void initSuggestions() { @@ -238,6 +220,8 @@ public abstract class AbstractBlockManager extends AbstractModelGenerator implem protected abstract int vanillaBlockStateCount(); + protected abstract void processSounds(); + protected abstract CustomBlock createCustomBlock(@NotNull Holder.Reference holder, @NotNull BlockStateVariantProvider variantProvider, @NotNull Map>> events, @@ -538,15 +522,34 @@ public abstract class AbstractBlockManager extends AbstractModelGenerator implem boolean isEntityBlock = entityBlockBehavior != null; // 绑定行为 - for (ImmutableBlockState blockState : states) { - blockState.setBehavior(blockBehavior); + for (ImmutableBlockState state : states) { if (isEntityBlock) { - blockState.setBlockEntityType(entityBlockBehavior.blockEntityType()); + state.setBlockEntityType(entityBlockBehavior.blockEntityType()); + } + state.setBehavior(blockBehavior); + int internalId = state.customBlockState().registryId(); + int appearanceId = state.vanillaBlockState().registryId(); + int index = internalId - AbstractBlockManager.this.vanillaBlockStateCount; + AbstractBlockManager.this.immutableBlockStates[index] = state; + AbstractBlockManager.this.blockStateMappings[internalId] = appearanceId; + AbstractBlockManager.this.appearanceToRealState.computeIfAbsent(appearanceId, k -> new IntArrayList()).add(internalId); + AbstractBlockManager.this.tempVisualBlocksInUse.add(state.vanillaBlockState()); + AbstractBlockManager.this.applyPlatformSettings(state); + // generate mod assets + if (Config.generateModAssets()) { + AbstractBlockManager.this.modBlockStateOverrides.put(BlockManager.createCustomBlockKey(index), Optional.ofNullable(AbstractBlockManager.this.tempVanillaBlockStateModels.get(appearanceId)) + .orElseGet(() -> { + // 如果未指定模型,说明复用原版模型?但是部分模型是多部位模型,无法使用变体解决问题 + // 未来需要靠mod重构彻底解决问题 + JsonObject json = new JsonObject(); + json.addProperty("model", "minecraft:block/air"); + return json; + })); } } // 添加方块 - addCustomBlock(customBlock); + AbstractBlockManager.this.byId.put(customBlock.id(), customBlock); }, () -> GsonHelper.get().toJson(section))); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/util/GsonHelper.java b/core/src/main/java/net/momirealms/craftengine/core/util/GsonHelper.java index 975fcfee0..beb6c42a1 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/util/GsonHelper.java +++ b/core/src/main/java/net/momirealms/craftengine/core/util/GsonHelper.java @@ -11,25 +11,19 @@ import java.nio.file.Path; import java.util.List; import java.util.Map; -public class GsonHelper { - private final Gson gson; +public final class GsonHelper { + private static final Gson GSON; - public GsonHelper() { - this.gson = new GsonBuilder() + private GsonHelper() {} + + static { + GSON = new GsonBuilder() .disableHtmlEscaping() .create(); } - public Gson getGson() { - return gson; - } - public static Gson get() { - return SingletonHolder.INSTANCE.getGson(); - } - - private static class SingletonHolder { - private static final GsonHelper INSTANCE = new GsonHelper(); + return GSON; } public static void writeJsonFile(JsonElement json, Path path) throws IOException { diff --git a/gradle.properties b/gradle.properties index e56947eb0..c3f2fe021 100644 --- a/gradle.properties +++ b/gradle.properties @@ -50,7 +50,7 @@ byte_buddy_version=1.17.5 ahocorasick_version=0.6.3 snake_yaml_version=2.5 anti_grief_version=0.20 -nms_helper_version=1.0.96 +nms_helper_version=1.0.97 evalex_version=3.5.0 reactive_streams_version=1.0.4 amazon_awssdk_version=2.33.1