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:
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"title.craftengine.config": "CraftEngine设置",
|
||||
"category.craftengine.general": "通用",
|
||||
"option.craftengine.enable_network": "启用服务器内自定义方块",
|
||||
"tooltip.craftengine.enable_network": "需要重新进入服务器即可生效"
|
||||
}
|
||||
@@ -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}"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user