-
已经,没有modding的理由了 -
[原创][Mod]基于opengl取色的hsv色盘屏幕是KL大蛇
-
论坛怎么蓝蓝的有吗(
-
[搬运][Windows][JSON-i18n]一款JSON文件快速本地化的翻译工具项目地址:MonianHello/JSON-i18n: JSON文件快速本地化的翻译工具
以下介绍为项目地址readme,因介绍已较为详细,故不另行编写
本帖内不提供二次分发文件,请前往项目地址自行下载!
JSON-i18n
JSON文件快速本地化的翻译工具
部分功能参考自CFPATools/Minecraft-Mods-Translator: Mods Translator for Minecraft 1.16+ (github.com)
主要功能:
- 对接Minecraft模组翻译参考词典 (mcmod.cn),可以在程序内直接进行查询
- 对接文本翻译_机器翻译-百度AI开放平台 (baidu.com),可以一键对全文进行机器翻译
- 可以快速替换值中的单词而不会影响键名
- 支持切换深色模式与浅色模式,支持修改ui文字样式大小、保存布局后再次启动后自动应用、(进阶)提供对ui的高度自定义设置
程序提供五个快捷键:
- Ctrl+F 跳转至搜索
- Ctrl+H 跳转至替换
- Ctrl+Shift+A 全选替换候选项
- Ctrl+Up(方向键上) 跳转至审阅模式上一个键名
- Ctrl+Down(方向键下) 跳转至审阅模式下一个键名
详细说明:
首次启动:
首次启动后需要设置工作目录,设置完成后也可以在左上角
选项-首选项
中修改注意:请避免通过直接修改config.ini的方式修改配置,由于不同设备的文本编辑器编码方式可能不同,错误的编码方式会导致程序异常。如果出现此类情况请删除config.ini以初始化程序
外观设置:
程序内支持修改全局字体及大小,在左上角
选项-首选项
中修改。使用鼠标滚轮可以快速调整不同的字体及大小,方便预览。同时支持切换深色模式界面说明:
程序左侧为文件浏览区域,可以快速选择需要打开的json文件
程序右侧分别是查询栏和替换栏
程序中间为操作区域,用来编辑json文件,在浏览模式下点击行号可以快速跳转到审阅模式
菜单功能:
上方菜单栏中有以下四个功能:
- 首选项
- 保存当前布局
- 一键清空空格
- 安全模式保存(在保存文件按钮失效时使用)
左侧文件浏览区域中可以右键文件呼出菜单,有以下四个功能:
- 在资源管理器中打开
- 移动到回收站
- 复制并重命名
- 重命名
翻译功能:
翻译功能需要首先前往百度智能云-管理中心 (baidu.com)获取免费测试资源(500万字符/年),后续将陆续支持其他翻译api。
使用前需要在配置文件中填入获取到的接口ak/sk,具体步骤见下文。
测试成功后,可以点击左下角
翻译文件
按钮,程序将自动对全文进行翻译。此时翻译并不会直接替换原文,需要用户进行进一步校对。如不需要,可以点击左下角复制机翻
按钮,一键替换译文与原文。完成后点击左下角保存文件
按钮即可保存更改。翻译接口领取步骤:
1、登录百度账号,选择领取
文本翻译-通用版
2、创建应用,接口选择
文本翻译-通用版
,其他内容无要求3、复制ak与sk到程序中,测试成功后即可使用
-
常见问题 Q&A与问题无关的回复将会被删除
-
[原创][1.20.1][EidolonJS开发实录]基于链式调用达成在Schema注册中使用回调函数构建配方项目地址:PickAID/EidolonJS: as the name says
在为Eidolon中的坩埚注册相应的Schema时,我发现了一个问题:
坩埚配方的输入并不能够使用简单的RecipeKey添加,相关的代码如下:
public static class Step { public final List<Ingredient> matches = new ArrayList<>(); public final int stirs; public Step(int stirs, List<Ingredient> matches) { this.stirs = stirs; this.matches.addAll(matches); } }
而最初一版的RecipeKey与Schema设计如下:
public interface CrucibleSchema { RecipeKey<OutputItem> OUTPUT = ItemComponents.OUTPUT_ID_WITH_COUNT.key("result"); RecipeKey<OutputItem[]> OUTPUT = ItemComponents.OUTPUT_ARRAY.key("result"); RecipeComponentBuilder STEP_BUILDER = new RecipeComponentBuilder(2) .add(NumberComponent.INT.key("stirs").optional(1)) .add(NumberComponent.INT.key("stirs").defaultOptional()) .add(ItemComponents.INPUT_ARRAY.key("items")); RecipeKey<RecipeComponentBuilderMap[]> STEPS = STEP_BUILDER.inputRole().asArray().key("steps"); RecipeSchema SCHEMA = new RecipeSchema(OUTPUT, STEPS);
进行注册后简单对代码进行测试:
ServerEvents.recipes(event => { event.recipes.eidolon.crucible("2x stone", [ {stirs: 1, items: ["#forge:dusts/redstone", "2x eidolon:soul_shard"]}, {items: ["#forge:dusts/redstone", "eidolon:soul_shard"]}, {stirs: 1}, {stirs: 3} ]) }
配方的确可以正常注册,但是可以看到,Step部分的格式与json几乎一致,不够优雅。
于是笔者开始尝试在RecipeKey中使用回调函数,然而失败了(也有可能是我菜),
而我在阅读了SummoningRitual的源代码之后(AlmostReliable/summoningrituals at 1.20.1-forge)有了不一样的想法。
或许可以使用链式调用形式的配方,并在链式调用的方法中使用回调函数。
完整的代码实现如下://篇幅原因省去import //CrucibleSchema.java public interface CrucibleSchema { @FunctionalInterface interface StepBuilderCallback { void apply(StepBuilderJS builder); } class CrucibleRecipeJS extends RecipeJS { public CrucibleRecipeJS steps(StepBuilderCallback callback) { var builder = new StepBuilderJS(); callback.apply(builder); setValue(STEPS, builder.getStepList().toArray(CrucibleRecipe.Step[]::new)); return this; } } RecipeKey<CrucibleRecipe.Step[]> STEPS = new RecipeComponent<CrucibleRecipe.Step[]>() { @Override public Class<?> componentClass() { return CrucibleRecipe.Step[].class; } @Override public JsonElement write(RecipeJS recipe, CrucibleRecipe.Step[] value) { if (value == null) { return null; } JsonArray stepsArray = new JsonArray(); for (CrucibleRecipe.Step step : value) { JsonObject stepObj = new JsonObject(); // Add stirs stepObj.addProperty("stirs", step.stirs); // Add items if (!step.matches.isEmpty()) { JsonArray itemsArray = new JsonArray(); for (Ingredient ingredient : step.matches) { itemsArray.add(ingredient.toJson()); } stepObj.add("items", itemsArray); } stepsArray.add(stepObj); } return stepsArray; } @Override public CrucibleRecipe.Step[] read(RecipeJS recipe, Object from) { if (from instanceof JsonElement) { JsonArray stepsArray = ((JsonElement) from).getAsJsonArray(); List<CrucibleRecipe.Step> steps = new ArrayList<>(); for (JsonElement element : stepsArray) { if (!element.isJsonObject()) { throw new JsonSyntaxException("Each step must be a JSON object"); } JsonObject stepObj = element.getAsJsonObject(); int stirs = stepObj.has("stirs") ? stepObj.get("stirs").getAsInt() : 0; List<Ingredient> ingredients = new ArrayList<>(); if (stepObj.has("items")) { JsonArray itemsArray = stepObj.getAsJsonArray("items"); for (JsonElement item : itemsArray) { ingredients.add(Ingredient.fromJson(item)); } } steps.add(new CrucibleRecipe.Step(stirs, ingredients)); } return steps.toArray(CrucibleRecipe.Step[]::new); } else { throw new JsonSyntaxException("Each step must be a JSON object"); } } }.key("steps").noBuilders(); RecipeKey<OutputItem> OUTPUT = ItemComponents.OUTPUT.key("result").noBuilders(); RecipeSchema SCHEMA = new RecipeSchema(CrucibleRecipeJS.class, CrucibleRecipeJS::new, OUTPUT, STEPS).constructor(((recipe, schemaType, keys, from) -> { recipe.setValue(OUTPUT, from.getValue(recipe, OUTPUT)); recipe.setValue(STEPS, new CrucibleRecipe.Step[0]); }), OUTPUT); } //StepBuilderJS.java public class StepBuilderJS { List<CrucibleRecipe.Step> stepList = new ArrayList<>(); List<Ingredient> item = new ArrayList<>(); int stirs = 0; public StepBuilderJS stirs(int count) { stirs = count; return this; } public StepBuilderJS stirs() { return stirs(1); } public StepBuilderJS items(Ingredient... items) { item.addAll(List.of(items)); return this; } public void step(int count, Ingredient... items) { var step = new CrucibleRecipe.Step(count, item); stepList.add(step); } public void build(){ var step = new CrucibleRecipe.Step(stirs, item); stepList.add(step); stirs(0); item.clear(); } @HideFromJS public List<CrucibleRecipe.Step> getStepList() { return stepList; } }
最终实现的效果如下:
event.recipes.eidolon.crucible("2x stone").steps((step) => { step.stirs(1).items("#forge:dusts/redstone", "eidolon:soul_shard").build() step.items("#forge:dusts/redstone","eidolon:soul_shard").build() step.stirs(3).build() })
或许直接使用链式调用传入每一步的设计更为直接,但是出于个人偏好,笔者仍然选择使用回调函数的形式处理这部分。
(//TODO 代码详解施工中) -
[原创][KubeJS 6][BrokenClassFilter]关于反射的应用场景与使用实例的论述标题格式已修改,可以的话最好加个名字 @忆然
-
【发帖必读】妙妙工具版版规与发帖规范第一章 板块定位
第一条 核心宗旨
妙妙工具板块致力于分享实用技术资源,包括但不限于:
- 原创或转载的程序、网页工具
- KubeJS/CrT魔改脚本、工具集、配置集、Lib库
- 可复用的代码轮子、开发模板
- 其他可提升效率的技术解决方案
第二条 内容导向
鼓励发布完整度高、逻辑清晰、注释规范的作品,倡导技术交流与开源精神。
第二章 发帖规范
第三条 标题格式
一、基础格式
[原创/搬运][工具平台][工具英文名——工具译名] 其他说明与描述
说明:- 原创/搬运:必填,标明内容性质(搬运需注明原出处);
- 工具平台:必填,标明工具类型或适用平台(如
Windows
/Forge
/KubeJS 6
/在线工具
等); - 工具名称:
- 有中英文名:格式为
英文名——中文译名
; - 无中文译名:可仅写英文名;
- 无英文名:可仅写中文名;
- 有中英文名:格式为
- 其他说明:选填,补充版本、功能亮点或短评(如
v3.2.1更新
/便捷翻译工具
)。
二、注意事项
- 标题中英文间用 短破折号
——
(非短横线-
); - 标题中方括号使用英文字符
[]
,而不使用中文字符【】
- 禁止添加夸张符号(如
!!!
【爆款】
); - 平台分类需简洁明确,避免模糊表述(如
[Minecraft]
应改为[Minecraft 1.20.1-1.21.X]
)。
三、格式示例
[转载][Windows][JSON-i18n]一款JSON文件快速本地化的翻译工具
[转载][CrT 1.12.2][GrassUtils]基于CraftTweaker的便捷工具类集合
第四条 版权声明
- 原创内容:需在正文显著位置标注原创声明以及授权协议;
- 搬运内容:
- 一般情况下禁止二次转载(即“二转”),原搬运贴年久失修例外(超过三个大版本更新未同步内容);
- 若原作者注明转载需要授权,或原作品协议不允许转载,需在正文顶部展示授权协议截图/链接;
- 二次分发需要在协议允许的情况下进行,或获取原作者授权,需在正文顶部展示授权协议截图/链接;
- 衍生作品:若涉及二改、二次分发或反向工程,必须符合原始协议条款,否则视为剽窃。
第五条 安全警示
内容若包含以下操作,必须添加
unsafe
标签并在正文详细说明风险:- 修改系统关键文件
- 静默执行的操作
- 涉及敏感权限
- 存在数据丢失/泄露风险的功能
(示例):
本脚本涉及对系统文件进行修改的操作!
第六条 质量管控
禁止发布以下低质量内容:
- 功能重复:与已有工具核心功能高度相似;
- 代码简陋:无异常处理、无注释、逻辑混乱的“玩具代码”;
- 可替代性强:可通过现有工具组合或简单命令实现同等效果;
- 描述模糊:未提供使用场景、参数说明或效果演示。
注:若承诺改进,需在标题添加[持续更新]
并公示开发计划(如更新日志)。
第三章 违规行为
第七条 绝对禁止
- 剽窃:直接复制他人代码未标注来源,或篡改版权声明;
- 黑箱分发:对闭源工具进行逆向工程并违规传播;
- 恶意组件:植入后门、挖矿代码、数据爬虫等危害性内容;
- 虚假更新:标注
[持续更新]
但超30天无实质进展且未说明原因。
第八条 内容删除标准
- 未标注
[unsafe]
的高风险工具; - 未提供授权证明的搬运内容;
- 被3名以上用户举报核实为低创作品。
第九条 违规处罚
违规类型 处理措施 未标注 [unsafe]
警告+强制编辑 低创内容 删帖+禁止3日内发同类主题 剽窃/黑箱分发 永久封禁账号+全论坛置顶晒尸
第四章 附则
第十条 本规则自发布之日起生效,最终解释权归VariedMC管理组所有。
-
血肉重铸是一个很可爱的模组!WTF