diff --git a/gradle.properties b/gradle.properties index fdadab3ea..ceb4a5e1c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ org.gradle.jvmargs=-Xmx1G # Project settings # Rule: [major update].[feature update].[bug fix] -project_version=0.0.47.2 +project_version=0.0.47.3 config_version=25 lang_version=4 project_group=net.momirealms diff --git a/server-mod/src/main/java/net/momirealms/craftengine/mod/block/CustomBlocks.java b/server-mod/src/main/java/net/momirealms/craftengine/mod/block/CustomBlocks.java new file mode 100644 index 000000000..d9b1a5db3 --- /dev/null +++ b/server-mod/src/main/java/net/momirealms/craftengine/mod/block/CustomBlocks.java @@ -0,0 +1,126 @@ +package net.momirealms.craftengine.mod.block; + +import com.mojang.brigadier.StringReader; +import net.minecraft.commands.arguments.blocks.BlockStateParser; +import net.minecraft.core.Registry; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.core.registries.Registries; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockBehaviour; +import net.minecraft.world.level.block.state.BlockState; +import net.momirealms.craftengine.mod.CraftEnginePlugin; +import net.momirealms.craftengine.mod.util.NoteBlockUtils; +import net.momirealms.craftengine.mod.util.VersionHelper; +import org.bukkit.configuration.file.YamlConfiguration; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; + +public class CustomBlocks { + + public static void register() { + CraftEnginePlugin.setVanillaRegistrySize(Block.BLOCK_STATE_REGISTRY.size()); + ResourceLocation noteBlock = ResourceLocation.fromNamespaceAndPath("minecraft", "note_block"); + Map map = loadMappingsAndAdditionalBlocks(); + for (Map.Entry entry : map.entrySet()) { + ResourceLocation replacedBlockId = entry.getKey(); + boolean isNoteBlock = replacedBlockId.equals(noteBlock); + Block replacedBlock = BuiltInRegistries.BLOCK.getValue(replacedBlockId); + for (int i = 0; i < entry.getValue(); i++) { + ResourceLocation location = ResourceLocation.fromNamespaceAndPath("craftengine", replacedBlockId.getPath() + "_" + i); + ResourceKey resourceKey = ResourceKey.create(Registries.BLOCK, location); + BlockBehaviour.Properties properties = BlockBehaviour.Properties.of(); + if (VersionHelper.above1_21_2()) { + properties.setId(resourceKey); + } + if (!replacedBlock.hasCollision) { + properties.noCollission(); + } + CraftEngineBlock block = new CraftEngineBlock(properties); + if (isNoteBlock) { + block.setNoteBlock(true); + NoteBlockUtils.CLIENT_SIDE_NOTE_BLOCKS.add(block.defaultBlockState()); + } + Registry.register(BuiltInRegistries.BLOCK, location, block); + Block.BLOCK_STATE_REGISTRY.add(block.defaultBlockState()); + } + } + NoteBlockUtils.CLIENT_SIDE_NOTE_BLOCKS.addAll(net.minecraft.world.level.block.Blocks.NOTE_BLOCK.getStateDefinition().getPossibleStates()); + if (!map.isEmpty()) { + CraftEnginePlugin.setIsSuccessfullyRegistered(true); + } + } + + private static Map loadMappingsAndAdditionalBlocks() { + Path mappingPath = CraftEnginePlugin.getCraftEngineMappingsPath(); + if (!Files.exists(mappingPath)) return Map.of(); + YamlConfiguration mappings = YamlConfiguration.loadConfiguration(mappingPath.toFile()); + Map blockStateMappings = loadBlockStateMappings(mappings); + validateBlockStateMappings(blockStateMappings); + Map blockTypeCounter = new LinkedHashMap<>(); + Map appearanceMapper = new HashMap<>(); + for (Map.Entry entry : blockStateMappings.entrySet()) { + processBlockStateMapping(entry, appearanceMapper, blockTypeCounter); + } + YamlConfiguration additionalYaml = YamlConfiguration.loadConfiguration(CraftEnginePlugin.getCraftEngineAdditionalBlocksPath().toFile()); + return buildRegisteredRealBlockSlots(blockTypeCounter, additionalYaml); + } + + private static Map loadBlockStateMappings(YamlConfiguration mappings) { + Map blockStateMappings = new LinkedHashMap<>(); + for (Map.Entry entry : mappings.getValues(false).entrySet()) { + if (entry.getValue() instanceof String afterValue) { + blockStateMappings.put(entry.getKey(), afterValue); + } + } + return blockStateMappings; + } + + private static void validateBlockStateMappings(Map blockStateMappings) { + Map temp = new HashMap<>(blockStateMappings); + for (Map.Entry entry : temp.entrySet()) { + String state = entry.getValue(); + blockStateMappings.remove(state); + } + } + + private static LinkedHashMap buildRegisteredRealBlockSlots(Map counter, YamlConfiguration additionalYaml) { + LinkedHashMap map = new LinkedHashMap<>(); + for (Map.Entry entry : counter.entrySet()) { + String id = entry.getKey().toString(); + int additionalStates = additionalYaml.getInt(id, 0); + int internalIds = entry.getValue() + additionalStates; + map.put(entry.getKey(), internalIds); + } + return map; + } + + private static void processBlockStateMapping(Map.Entry entry, Map mapper, Map counter) { + BlockState before = createBlockData(entry.getKey()); + BlockState after = createBlockData(entry.getValue()); + if (before == null || after == null) return; + + int beforeId = Block.BLOCK_STATE_REGISTRY.getId(before); + int afterId = Block.BLOCK_STATE_REGISTRY.getId(after); + + Integer previous = mapper.put(beforeId, afterId); + if (previous == null) { + counter.compute(BuiltInRegistries.BLOCK.getKey(before.getBlock()), (k, count) -> count == null ? 1 : count + 1); + } + } + + private static BlockState createBlockData(String blockState) { + try { + StringReader reader = new StringReader(blockState); + BlockStateParser.BlockResult arg = BlockStateParser.parseForBlock(BuiltInRegistries.BLOCK, reader, false); + return arg.blockState(); + } catch (Exception e) { + return null; + } + } +} diff --git a/server-mod/src/main/java/net/momirealms/craftengine/mod/mixin/BlocksMixin.java b/server-mod/src/main/java/net/momirealms/craftengine/mod/mixin/BlocksMixin.java index 451ee115c..a14af758c 100644 --- a/server-mod/src/main/java/net/momirealms/craftengine/mod/mixin/BlocksMixin.java +++ b/server-mod/src/main/java/net/momirealms/craftengine/mod/mixin/BlocksMixin.java @@ -1,131 +1,17 @@ package net.momirealms.craftengine.mod.mixin; -import com.mojang.brigadier.StringReader; -import net.minecraft.commands.arguments.blocks.BlockStateParser; -import net.minecraft.core.Registry; -import net.minecraft.core.registries.BuiltInRegistries; -import net.minecraft.core.registries.Registries; -import net.minecraft.resources.ResourceKey; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.state.BlockBehaviour; -import net.minecraft.world.level.block.state.BlockState; -import net.momirealms.craftengine.mod.CraftEnginePlugin; -import net.momirealms.craftengine.mod.block.CraftEngineBlock; -import net.momirealms.craftengine.mod.util.NoteBlockUtils; -import org.bukkit.configuration.file.YamlConfiguration; +import net.momirealms.craftengine.mod.block.CustomBlocks; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.Map; - @Mixin(value = Blocks.class) public abstract class BlocksMixin { @Inject(method = "", at = @At("RETURN")) private static void onBlocksInit(CallbackInfo ci) { - CraftEnginePlugin.setVanillaRegistrySize(Block.BLOCK_STATE_REGISTRY.size()); - ResourceLocation noteBlock = ResourceLocation.fromNamespaceAndPath("minecraft", "note_block"); - Map map = loadMappingsAndAdditionalBlocks(); - for (Map.Entry entry : map.entrySet()) { - ResourceLocation replacedBlockId = entry.getKey(); - boolean isNoteBlock = replacedBlockId.equals(noteBlock); - Block replacedBlock = BuiltInRegistries.BLOCK.getValue(replacedBlockId); - for (int i = 0; i < entry.getValue(); i++) { - ResourceLocation location = ResourceLocation.fromNamespaceAndPath("craftengine", replacedBlockId.getPath() + "_" + i); - ResourceKey resourceKey = ResourceKey.create(Registries.BLOCK, location); - BlockBehaviour.Properties properties = BlockBehaviour.Properties.of() - .setId(resourceKey); - if (!replacedBlock.hasCollision) { - properties.noCollission(); - } - CraftEngineBlock block = new CraftEngineBlock(properties); - if (isNoteBlock) { - block.setNoteBlock(true); - NoteBlockUtils.CLIENT_SIDE_NOTE_BLOCKS.add(block.defaultBlockState()); - } - Registry.register(BuiltInRegistries.BLOCK, location, block); - Block.BLOCK_STATE_REGISTRY.add(block.defaultBlockState()); - } - } - NoteBlockUtils.CLIENT_SIDE_NOTE_BLOCKS.addAll(Blocks.NOTE_BLOCK.getStateDefinition().getPossibleStates()); - if (!map.isEmpty()) { - CraftEnginePlugin.setIsSuccessfullyRegistered(true); - } - } - - private static Map loadMappingsAndAdditionalBlocks() { - Path mappingPath = CraftEnginePlugin.getCraftEngineMappingsPath(); - if (!Files.exists(mappingPath)) return Map.of(); - YamlConfiguration mappings = YamlConfiguration.loadConfiguration(mappingPath.toFile()); - Map blockStateMappings = loadBlockStateMappings(mappings); - validateBlockStateMappings(blockStateMappings); - Map blockTypeCounter = new LinkedHashMap<>(); - Map appearanceMapper = new HashMap<>(); - for (Map.Entry entry : blockStateMappings.entrySet()) { - processBlockStateMapping(entry, appearanceMapper, blockTypeCounter); - } - YamlConfiguration additionalYaml = YamlConfiguration.loadConfiguration(CraftEnginePlugin.getCraftEngineAdditionalBlocksPath().toFile()); - return buildRegisteredRealBlockSlots(blockTypeCounter, additionalYaml); - } - - private static Map loadBlockStateMappings(YamlConfiguration mappings) { - Map blockStateMappings = new LinkedHashMap<>(); - for (Map.Entry entry : mappings.getValues(false).entrySet()) { - if (entry.getValue() instanceof String afterValue) { - blockStateMappings.put(entry.getKey(), afterValue); - } - } - return blockStateMappings; - } - - private static void validateBlockStateMappings(Map blockStateMappings) { - Map temp = new HashMap<>(blockStateMappings); - for (Map.Entry entry : temp.entrySet()) { - String state = entry.getValue(); - blockStateMappings.remove(state); - } - } - - private static LinkedHashMap buildRegisteredRealBlockSlots(Map counter, YamlConfiguration additionalYaml) { - LinkedHashMap map = new LinkedHashMap<>(); - for (Map.Entry entry : counter.entrySet()) { - String id = entry.getKey().toString(); - int additionalStates = additionalYaml.getInt(id, 0); - int internalIds = entry.getValue() + additionalStates; - map.put(entry.getKey(), internalIds); - } - return map; - } - - private static void processBlockStateMapping(Map.Entry entry, Map mapper, Map counter) { - BlockState before = createBlockData(entry.getKey()); - BlockState after = createBlockData(entry.getValue()); - if (before == null || after == null) return; - - int beforeId = Block.BLOCK_STATE_REGISTRY.getId(before); - int afterId = Block.BLOCK_STATE_REGISTRY.getId(after); - - Integer previous = mapper.put(beforeId, afterId); - if (previous == null) { - counter.compute(BuiltInRegistries.BLOCK.getKey(before.getBlock()), (k, count) -> count == null ? 1 : count + 1); - } - } - - private static BlockState createBlockData(String blockState) { - try { - StringReader reader = new StringReader(blockState); - BlockStateParser.BlockResult arg = BlockStateParser.parseForBlock(BuiltInRegistries.BLOCK, reader, false); - return arg.blockState(); - } catch (Exception e) { - return null; - } + CustomBlocks.register(); } } diff --git a/server-mod/src/main/java/net/momirealms/craftengine/mod/util/VersionHelper.java b/server-mod/src/main/java/net/momirealms/craftengine/mod/util/VersionHelper.java new file mode 100644 index 000000000..ef66fda78 --- /dev/null +++ b/server-mod/src/main/java/net/momirealms/craftengine/mod/util/VersionHelper.java @@ -0,0 +1,18 @@ +package net.momirealms.craftengine.mod.util; + +import net.minecraft.server.MinecraftServer; + +public class VersionHelper { + public static final boolean v1_21_2; + + static { + String version = MinecraftServer.getServer().getServerVersion(); + String[] split = version.split("\\."); + float versionF = Float.parseFloat(split[1] + "." + (split.length == 3 ? split[2] : "0")); + v1_21_2 = versionF >= 21.2f; + } + + public static boolean above1_21_2() { + return v1_21_2; + } +}