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

feat(client-mod): 添加模组配置菜单功能

This commit is contained in:
jhqwqmc
2025-03-24 16:39:12 +08:00
parent d05c0fe689
commit 19f49073a7
10 changed files with 150 additions and 9 deletions

View File

@@ -1,25 +1,37 @@
package net.momirealms.craftEngineFabricMod;
import net.fabricmc.api.ModInitializer;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.block.BlockState;
import net.minecraft.util.Identifier;
import net.momirealms.craftEngineFabricMod.client.config.ModConfig;
import net.momirealms.craftEngineFabricMod.util.BlockUtils;
import net.momirealms.craftEngineFabricMod.util.LoggerFilter;
import net.momirealms.craftEngineFabricMod.util.RegisterBlocks;
import net.momirealms.craftEngineFabricMod.util.YamlUtils;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.Yaml;
import java.io.IOException;
import java.io.InputStream;
import java.io.Writer;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Map;
public class CraftEngineFabricMod implements ModInitializer {
private static final Path CONFIG_PATH = FabricLoader.getInstance().getConfigDir().resolve("craft-engine-fabric-mod/config.yml");
public static final String MOD_ID = "craftengine";
@Override
public void onInitialize() {
loadConfig();
Runtime.getRuntime().addShutdownHook(new Thread(this::saveConfig));
LoggerFilter.filter();
try {
YamlUtils.ensureConfigFile("additional-real-blocks.yml");
YamlUtils.ensureConfigFile("mappings.yml");
YamlUtils.ensureConfigFile("config.yml");
Map<Identifier, Integer> map = YamlUtils.loadMappingsAndAdditionalBlocks();
System.out.println("Loaded " + map.size() + " additional real blocks.");
for (Map.Entry<Identifier, Integer> entry : map.entrySet()) {
@@ -37,4 +49,35 @@ public class CraftEngineFabricMod implements ModInitializer {
e.printStackTrace();
}
}
@SuppressWarnings("unchecked")
private void loadConfig() {
if (!Files.exists(CONFIG_PATH)) {
saveConfig();
return;
}
try (InputStream inputStream = Files.newInputStream(CONFIG_PATH)) {
Yaml yaml = new Yaml();
var config = yaml.loadAs(inputStream, java.util.Map.class);
ModConfig.enableNetwork = (Boolean) config.getOrDefault("enable-network", true);
} catch (IOException e) {
e.printStackTrace();
}
}
private void saveConfig() {
DumperOptions options = new DumperOptions();
options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
Yaml yaml = new Yaml(options);
var data = new java.util.HashMap<String, Object>();
data.put("enable-network", ModConfig.enableNetwork);
try (Writer writer = Files.newBufferedWriter(CONFIG_PATH)) {
yaml.dump(data, writer);
} catch (IOException e) {
e.printStackTrace();
}
}
}

View File

@@ -1,127 +0,0 @@
package net.momirealms.craftEngineFabricMod.util;
import com.mojang.brigadier.StringReader;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.command.argument.BlockArgumentParser;
import net.minecraft.registry.BuiltinRegistries;
import net.minecraft.registry.Registries;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.registry.RegistryWrapper;
import net.minecraft.util.Identifier;
import org.yaml.snakeyaml.Yaml;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
public class YamlUtils {
private static final String CONFIG_DIR = "config/craft-engine-fabric-mod/";
private static final Yaml yaml = new Yaml();
private static final RegistryWrapper<Block> registryWrapper = BuiltinRegistries.createWrapperLookup().getOrThrow(RegistryKeys.BLOCK);
public static <T> T loadConfig(Path filePath) throws IOException {
try (InputStream inputStream = Files.newInputStream(filePath)) {
return yaml.load(inputStream);
}
}
public static void ensureConfigFile(String fileName) throws IOException {
Path configDir = Path.of(CONFIG_DIR);
if (!Files.exists(configDir)) {
Files.createDirectories(configDir);
}
Path targetPath = configDir.resolve(fileName);
if (Files.exists(targetPath)) return;
String resourcePath = "assets/craft-engine-fabric-mod/config/" + fileName;
try (InputStream inputStream = YamlUtils.class.getClassLoader().getResourceAsStream(resourcePath)) {
if (inputStream == null) {
throw new IOException("Default config file not found: " + resourcePath);
}
Files.copy(inputStream, targetPath, StandardCopyOption.REPLACE_EXISTING);
}
}
public static Map<Identifier, Integer> loadMappingsAndAdditionalBlocks() throws IOException {
Path mappingPath = Path.of(CONFIG_DIR + "mappings.yml");
Path additionalYamlPath = Path.of(CONFIG_DIR + "additional-real-blocks.yml");
System.out.println("Loading mappings.yml and additional-real-blocks.yml...");
Map<String, String> blockStateMappings = loadConfig(mappingPath);
System.out.println("Loaded " + blockStateMappings.size() + " block state mappings.");
validateBlockStateMappings(blockStateMappings);
System.out.println("Validated block state mappings.");
Map<Identifier, Integer> blockTypeCounter = new LinkedHashMap<>();
Map<Integer, Integer> appearanceMapper = new HashMap<>();
System.out.println("Processing block state mappings...");
for (Map.Entry<String, String> entry : blockStateMappings.entrySet()) {
processBlockStateMapping(entry, appearanceMapper, blockTypeCounter);
}
System.out.println("Processed " + blockTypeCounter.size() + " block state mappings.");
Map<String, Integer> additionalYaml = loadConfig(additionalYamlPath);
System.out.println("Loaded " + additionalYaml.size() + " additional real blocks.");
return buildRegisteredRealBlockSlots(blockTypeCounter, additionalYaml);
}
private static void validateBlockStateMappings(Map<String, String> blockStateMappings) {
Map<String, String> temp = new HashMap<>(blockStateMappings);
System.out.println("Validating block state mappings...");
for (Map.Entry<String, String> entry : temp.entrySet()) {
String state = entry.getValue();
blockStateMappings.remove(state);
}
System.out.println("Validated " + blockStateMappings.size() + " block state mappings.");
}
private static void processBlockStateMapping(
Map.Entry<String, String> entry,
Map<Integer, Integer> stateIdMapper,
Map<Identifier, Integer> blockUsageCounter
) {
final BlockState sourceState = createBlockData(entry.getKey());
final BlockState targetState = createBlockData(entry.getValue());
if (sourceState == null || targetState == null) {
return;
}
final int sourceStateId = Block.STATE_IDS.getRawId(sourceState);
final int targetStateId = Block.STATE_IDS.getRawId(targetState);
if (stateIdMapper.putIfAbsent(sourceStateId, targetStateId) == null) {
final Block sourceBlock = sourceState.getBlock();
final Identifier blockId = Registries.BLOCK.getId(sourceBlock);
blockUsageCounter.merge(blockId, 1, Integer::sum);
}
}
public static BlockState createBlockData(String blockState) {
try {
StringReader reader = new StringReader(blockState);
BlockArgumentParser.BlockResult arg = BlockArgumentParser.block(registryWrapper, reader, true);
return arg.blockState();
} catch (Exception e) {
return null;
}
}
private static LinkedHashMap<Identifier, Integer> buildRegisteredRealBlockSlots(Map<Identifier, Integer> counter, Map<String, Integer> additionalYaml) {
LinkedHashMap<Identifier, Integer> map = new LinkedHashMap<>();
System.out.println("Building registered real block slots...");
for (Map.Entry<Identifier, Integer> entry : counter.entrySet()) {
String id = entry.getKey().toString();
Integer additionalStates = additionalYaml.get(id);
int internalIds = entry.getValue() + (additionalStates != null ? additionalStates : 0);
map.put(entry.getKey(), internalIds);
}
System.out.println("Built " + map.size() + " registered real block slots.");
return map;
}
}

View File

@@ -0,0 +1,6 @@
{
"title.craftengine.config": "CraftEngine Settings",
"category.craftengine.general": "General",
"option.craftengine.enable_network": "Enable custom blocks in server",
"tooltip.craftengine.enable_network": "You need to re-enter the server to take effect"
}

View File

@@ -0,0 +1,6 @@
{
"title.craftengine.config": "CraftEngine设置",
"category.craftengine.general": "通用",
"option.craftengine.enable_network": "启用服务器内自定义方块",
"tooltip.craftengine.enable_network": "需要重新进入服务器即可生效"
}

View File

@@ -3,10 +3,16 @@
"id": "craft-engine-fabric-mod",
"version": "${version}",
"name": "craft-engine-fabric-mod",
"description": "",
"authors": [],
"contact": {},
"name": "CraftEngine Fabric Mod",
"description": "CraftEngine Fabric Mod",
"authors": [
"jhqwqmc"
],
"contact": {
"name": "CraftEngine",
"homepage": "https://github.com/Xiao-MoMi/craft-engine",
"issues": "https://github.com/Xiao-MoMi/craft-engine/issues"
},
"license": "GPL-3.0",
"icon": "assets/craft-engine-fabric-mod/icon.png",
@@ -14,12 +20,15 @@
"environment": "client",
"entrypoints": {
"client": ["net.momirealms.craftEngineFabricMod.client.CraftEngineFabricModClient"],
"main": ["net.momirealms.craftEngineFabricMod.CraftEngineFabricMod"]
"main": ["net.momirealms.craftEngineFabricMod.CraftEngineFabricMod"],
"modmenu": ["net.momirealms.craftEngineFabricMod.client.config.ModMenuIntegration"]
},
"depends": {
"fabricloader": ">=${loader_version}",
"fabric": "*",
"minecraft": "${minecraft_version}"
"minecraft": "${minecraft_version}",
"modmenu": ">=${modmenu_version}",
"cloth-config": ">=${cloth_version}"
}
}