Blank038 的博客
type: channel
link: https://i.blank038.com/
items: 使用 Zed Editor 开发网易我的世界 Addon 时使用 minecraft-bedrock-json-schemas
items: 网易我的世界大型结构控制生成群系与生成范围
items: GLM-4.6/GLM Coding Plan 对接 claude-code/claude-code-router
items: 如何制作一个网易我的世界带技能的 BOSS
items: 网易我的世界 PE 组件踩的坑
items: 我的世界基岩版实体死亡动画无法正常播放
items: 我的 2024 年度总结
items: 使用 Gradle 合并编译后的 class 至指定 jar 文件中
items: 一个基于 Kotlin 的简易 Bilibili 接口客户端
items: 个人的一些日常学习方法及管理软件

使用 Zed Editor 开发网易我的世界 Addon 时使用 minecraft-bedrock-json-schemas
type: item
date: 2025-11-16T03:58:00+08:00
description: 壹；前言最近迷上了 Zed Editor，将原本 PyCharm 与 VSCode 的环境都迁移至 Zed，也将Blockception/minecraft-bedrock-json-schemas的提示迁移至 Zed，同时镜像了Blockception/minecraft-bedrock-json-schemas仓库于国内站点，对部分功能进行汉化与添加网易特殊配置的提示。原仓库地址：https://github.com/Blockception/Minecraft-bedrock-json-schemas镜像仓库地址：https://code.mc9y.com/blank038/minecraft-bedrock-json-schemas(这是一个由社区维护的汉化镜像，并非官方版本。原始项目由 Blockception 创建并维护)贰；前置工具Zed Editor叁；效果预览肆；配置修改{ "file_types": { "JSONC": ["*.json"] }, "languages": { "JSONC": { "language_servers": ["json-language-server"] } }, "lsp": { "json-language-server": { "settings": { "json": { "schemas": [ { "fileMatch": ["skin_pack/skins.{json,jsonc,json5}"], "url": "https://code.mc9y.com/blank038/minecraft-bedrock-json-schemas/raw/branch/main/skinpacks/skins.json" }, { "fileMatch": ["language_names.{json,jsonc,json5}"], "url": "https://code.mc9y.com/blank038/minecraft-bedrock-json-schemas/raw/branch/main/language/language_names.json" }, { "fileMatch": ["languages.{json,jsonc,json5}"], "url": "https://code.mc9y.com/blank038/minecraft-bedrock-json-schemas/raw/branch/main/language/languages.json" }, { "fileMatch": ["manifest.{json,jsonc,json5}"], "url": "https://code.mc9y.com/blank038/minecraft-bedrock-json-schemas/raw/branch/main/general/manifest.json" }, { "fileMatch": [ "world_behavior_packs.{json,jsonc,json5}", "world_resource_packs.{json,jsonc,json5}" ], "url": "https://code.mc9y.com/blank038/minecraft-bedrock-json-schemas/raw/branch/main/general/world_x_packs.json" }, { "fileMatch": [ "resource_packs/*/animation_controllers/*.{json,jsonc,json5}", "*resource*pack*/animation_controllers/*.{json,jsonc,json5}", "*Resource*Pack*/animation_controllers/*.{json,jsonc,json5}", "*RP*/animation_controllers/*.{json,jsonc,json5}", "*rp*/animation_controllers/*.{json,jsonc,json5}", "resource_packs/*/animation_controllers/**/*.{json,jsonc,json5}", "*resource*pack*/animation_controllers/**/*.{json,jsonc,json5}", "*Resource*Pack*/animation_controllers/**/*.{json,jsonc,json5}", "*RP*/animation_controlle…

网易我的世界大型结构控制生成群系与生成范围
type: item
date: 2025-11-05T01:40:00+08:00
description: 壹；前言这篇文章不是为纯新手准备的，你至少了解或掌握以下技能才适合查看。Python(BP) 特征与特征生成规则(BP) 结构与大型结构Molang贰；实现原理1. 纯 Python 实现已知网易大型结构可拆分为不同大小的子结构(16,32,64)，并且提供了初始化时的结构生成事件 PlaceNeteaseStructureFeatureEvent，我们可以通过事件的参数来得到当前结构生成区块群系与坐标，也可以通过设定参数 cancel 来取消结构的生成，但是网易的结构生成事件是每个子结构都会触发，所以我们需要一个唯一标识来标记当前大型结构，我这里使用的方式是通过简单的计算取到第一个结构的起始坐标来做为唯一标识，代码如下。# structureManager.py # -*- coding: utf-8 -*- import mod.server.extraServerApi as serverApi from abyssogenesisScripts.modServer.storage import serverStorage comp_factory = serverApi.GetEngineCompFactory() class StructureManager(object): structures = {} @staticmethod def init(): # 延迟导入避免循环依赖 from abyssogenesisScripts.modServer import serverSystem serverStorage.ServerSystemObj.ListenForEvent( serverSystem.engine_namespace, serverSystem.engine_system_name, "PlaceNeteaseStructureFeatureEvent", StructureManager, StructureManager.on_dispose ) @staticmethod def register(structure_id, xc, zc, size, chance, biomes, radius=0): # type: (str, int, int, int, int, list, int) -> None """ 注册大型结构到结构控制器中, 用于控制群系生成 :param structure_id: 结构标识名 :param xc: 区块 x 宽度 :param zc: 区块 z 宽度 :param size: 单区块大小(16,32) :param chance: 刷新概率 :param biomes: 群系列表 :param radius: xz 超过 (0,0) 坐标半径多少才刷新 """ # 计算最大区块数 maxc = xc * zc # 记录结构数据 StructureManager.structures[structure_id] = { 'structure_id': structure_id, 'xc': xc, 'zc': zc, 'size': size, 'chance': chance, 'biomes': biomes, 'radius': radius } # 注册子区块 comp = comp_factory.CreateFeature(serverApi.GetLevelId()) for i in xrange(1, maxc + 1): comp.AddNeteaseFeatureWhiteList('{}_{}'.format(structure_id, i)) @staticmethod def on_dispose(params): """ 当结构开始生成的时候触发, 此处会判断是否为目标结构 """ # 判断结构是否存在于列表 structure_name = params['structureName'].rsplit('_', 1) if structure_name[0] not in StructureManager.structures: return # 获取结构信息 structure_data = StructureManager.structures[structure_name[0]] # 获取当前索引 index = int(structure_name[1]) - 1 # 计算当前原点坐标 current_x = index / 5 current_z = index % 5 origin_x = params['x'] - current_x * 16 origin_z = params['z'] - cur…

GLM-4.6/GLM Coding Plan 对接 claude-code/claude-code-router
type: item
date: 2025-10-19T21:44:00+08:00
description: 壹；前言在 AI 技术日益精进的今天，合理利用 AI 辅助编程能够显著提升工作效率与学习效果。本文主要演示如何将智谱 GLM-4.6 对接至 claude-code-router、以及将 GLM Coding Plan 接入 claude-code，以较低成本打造流畅高效的编程体验。贰；正文注意：文中代码或文件出现的 ... 指的是你其他配置，如果你没有其他配置则只写上演示配置即可。准备步骤智谱 AI 开放平台 API Keys（https://bigmodel.cn/usercenter/proj-mgmt/apikeys）已安装 claude-code / claude-code-router如果你还未安装 claude-code 或 claude-code-router，可以通过下面的命令安装。claude-code：npm install -g @anthropic-ai/claude-codeclaude-code-router：npm install -g @musistudio/claude-code-router如果提示 npm 命令不存在的话，请百度搜索一下 npm 是什么与怎么安装 npm 工具。1. GLM Coding Plan 对接 claude-code (推荐)设置系统变量 ANTHROPIC_BASE_URL 值为 https://open.bigmodel.cn/api/anthropic设置系统变量 ANTHROPIC_AUTH_TOKEN 值为你的 API Keys修改 claude-code 的设置如下，文件路径：~/.claude/settings.json，路径中的 ~ 为你的用户目录，例如 Windows：C:\Users\Administrator\.claude\settings.json{ "env": { "ANTHROPIC_DEFAULT_HAIKU_MODEL": "glm-4.5-air", "ANTHROPIC_DEFAULT_SONNET_MODEL": "glm-4.6", "ANTHROPIC_DEFAULT_OPUS_MODEL": "glm-4.6" } ... }如果需要一直使用中文回答你的问题，请输入 claude 进入 claude-code 后输入 /memory 指令，选择 User memory，并在打开的文件中写入下方提示词后保存文件。- Always reply in Chinese在项目目录下使用 claude 命令即可使用 GLM Coding Plan 的 GLM-4.6 模型了。2. GLM Coding Plan 对接 claude-code-router在 Providers 下增加模型设置，并在 Router 中启用模型，设置完成后在终端执行 ccr restart 重启 claude-code-router 服务{ ... "Providers": [ { "name": "bigmodel", "api_base_url": "https://open.bigmodel.cn/api/coding/paas/v4/chat/completions", "api_key": "YOUR_API_KEYS", "models": [ "glm-4.6", "glm-4.5-air" ] } ], "Router": { "default": "bigmodel,glm-4.6", "background": "bigmodel,glm-4.5-air", "think": "bigmodel,glm-4.6", "longContext": "bigmodel,glm-4.6", "longContextThreshold": 60000, ... } ... }在项目目录下使用 ccr code 命令即可使用 GLM Coding Plan 的 GLM-4.6 模型了。3. GLM-4.6 对接 claude-code-router参照 GLM Coding Plan 对接 claude-code-router 的步骤进行配置{ ... "Providers": [ { "name": "bigmodel", "api_base_url": "https://open.bigmodel.cn/api/paas/v4/chat/completions", "api_key": "YOUR_API_KEYS", "models": [ "glm-4.6" ] } ], "Router": { "default": "bigmodel,glm-4.6", "background": "bigmodel,glm-4.6", "th…

如何制作一个网易我的世界带技能的 BOSS
type: item
date: 2025-04-23T15:03:00+08:00
description: 本文仅简单演示下我个人在网易我的世界基岩版组件开发过程中制作 BOSS 用到的方法。壹；要求技能MolangAnimationController实体行为文件结构实体资源文件结构Python(可选)BP：行为包RP：资源包贰；哪些方式可以实现？CustomGoal + AnimationController(RP) + Molang(动作会有延迟)原理：通过对生物行为文件添加 CustomGoal 来控制技能的释放与暂停，并同时更新 Molang 来使 AnimationController 同步播放动画，但是这种方式动作播放会有延迟。[推荐] AnimationController(BP) + AnimationController(RP) + Property原理：通过行为文件修改 property，并开启 client_sync 来同步 property 给客户端，RP 的动画控制器通过 property 来同步技能动作，该方式延迟较低，如果对行为文件熟练的话，可以通过纯行为文件来实现技能效果。叁；实现过程这里采用推荐的方案二，BP 的动画控制器用来控制技能的动作切换(控制技能时长来同步客户端动作)过程思考在实现之前，我们需要简单梳理下需要用到东西：网易SDK事件(EntityDefinitionsEventServerEvent)、行为文件事件(event)、行为文件属性(property)。在 BP(行为包) 中也可以实现 animation_controllers 和 animations，与 RP(资源包) 的区别是在 BP 中可以让生物执行命令。如果你对基岩版的实体行为文件熟悉，就知道有 properties 可以设置生物属性，例如：不同颜色的羊。同理，我们也可以通过这个属性来设置当前生物释放的技能状态，再通过 aniamtion_controller 来调用行为文件事件取消技能释放的状态，当然，你也可以通过纯 Python 代码来控制技能状态，但这里按下不表。实现流程生物行为文件中定义一个随机释放技能的事件 example:random_skill生物行为文件中创建一个 enum 类型的 property，值为技能编号与无状态(不懂可以看下方实现逻辑)生物行为文件中定义一个无状态的事件 netease:example_skill_none，用来修改生物技能释放状态为无技能生物行为文件中写好对应技能的 event 来修改 property通过 timer 定时调用 example:random_skill 事件example:random_skill 中通过 randomize 来实现随机技能再调用具体的技能事件通过事件修改技能状态的 property 为对应技能的值Python 代码中监听 EntityDefinitionsEventServerEvent 来同时实现技能逻辑(例如：爆炸、范围伤害、技能音效等)在 aniamtion_controller 中对应的动画控制器下调用 netease:example_skill_none 来取消技能状态实现逻辑behavior_packs/entities/example_test_mob.json{ "format_version": "1.16.0", "minecraft:entity": { "component_groups": { }, "components": { ..., // 创建一个定时器来定时触发随机技能的事件，这里间隔是 8-9 秒 "minecraft:timer": { "looping": true, "randomInterval": true, "time": [ 8, 9 ], "time_down_event": { "event": "netease:random_example_skill", "target": "self" } } }, "description": { "identifier": "example:test_mob", "is_experimental": false, "is_spawnable": true, "is_summonable": true, // 创建一个 property 来调整生物当前的技能状态，并通过 client_sync 同步给客户端。 "properties": { "example:skill_state": { "type": "enum", "values": [ "none", "skill1" ], "default": "none", "client_sync": true } }, // 定义动画控制器与动画 "animations": { "base":…

网易我的世界 PE 组件踩的坑
type: item
date: 2025-03-23T17:25:00+08:00
description: 修改原生 UI 时审核错误代码18网易官方的 DEMO 中使用的是from client.ui.viewBinder import ViewBinder from client.ui.viewRequest import ViewRequest修改为import mod.client.extraClientApi as clientApi ViewBinder = clientApi.GetViewBinderCls() ViewRequest = clientApi.GetViewViewRequestCls()

我的世界基岩版实体死亡动画无法正常播放
type: item
date: 2025-03-13T17:38:00+08:00
description: 动画修改对死亡动画的根节点增加一个关键帧，如果你的动作已经做在根节点上，请新建一个根节点，如下方的 root 就是根节点。插入关键帧复制下方公式填入关键帧的 Z 轴旋转中Math.min(Math.sqrt(Math.max(0, q.anim_time * 20 - 0.5) / 20 * 1.6), 1) * -90动画控制器修改{ "format_version": "1.10.0", "animation_controllers": { "controller.animation.example.death": { "initial_state": "default", "states": { "default": { "transitions": [ { "override_death": "!q.is_alive" } ] }, "override_death": { "animations": [ "deathing" ], "transitions": [ { "default": "q.is_alive" } ], "blend_transition": 0.5 } } } } }参考资料https://wiki.bedrock.dev/visuals/death-animations

我的 2024 年度总结
type: item
date: 2025-01-02T16:36:00+08:00
description: 壹；今年做了什么与 KOI-工作室 推进《灾厄之门》网络服。 B站视频列表开发了 Minecraft 模组 Lantern，中文名：灯笼引擎，寓意能为一些开发者指引方向。推进了网易我的世界 PE 组件工作室 AiYo-Studio，在年尾时发布了库存组件，目前数据超越预期。使用 Rust 开发了一个基于网易我的世界 Addon 的 cli 工具 emod-cli，用于打包与创建预设组件等。 emod-cli 贰；今年学了什么今年除了深入学习感兴趣的几门编程语言与一些底层原理外，没有新学习其他编程语言。其他：入门魔方叁；去年的感悟未来还没发生的事情，不要将臆想的结果强加在当下的状态。肆；今年的目标当好、做好一名合格的团队领导者三阶魔方能 sub30伍；结尾简短的文章正如简短的一年，共勉。

使用 Gradle 合并编译后的 class 至指定 jar 文件中
type: item
date: 2024-10-04T02:13:00+08:00
description: 仅适用于产品没有开源的情况下作者允许反编译修改时使用。 壹; 配置文件tasks.register('patchJar') { finalizedBy('mergePatch') doLast { def originFile = file('origin/原文件.jar') def tempDir = file("${buildDir}/tempJar") copy { from zipTree(originFile) into tempDir } copy { from 'build/classes/java/main', 'build/resources/main' into tempDir include '**/*.class', '**/*.yml' } } } tasks.register('mergePatch', Jar) { from file("${buildDir}/tempJar") archiveFileName = "${archivesBaseName}-${version}.jar" destinationDirectory = file("${buildDir}/libs") doLast { file("${buildDir}/tempJar").deleteDir() } } tasks.build.dependsOn(tasks.patchJar)

一个基于 Kotlin 的简易 Bilibili 接口客户端
type: item
date: 2024-03-09T13:34:00+08:00
description: 2024-05-22 补充 请求标头需要增加 Referer 指向 https://space.bilibili.com为减少风控提高稳定性，可在设备登录自己账号后复制 dm_img_list, dm_img_str, dm_cover_img_str, dm_img_inter 四个参数覆盖 getDm() 方法返回值。 壹；简介基于 Kotlin 开发封装的 Bilibili 接口客户端, 支持 WebAPI 鉴权。贰；相关代码封装类，支持异步调用，同步执行可直接实例化 HttpBilibiliClientclass HttpBilibiliClient(private val apiUrl: String, private val parameters: String = "") { private var wbi: Boolean = false private val cookies: MutableList<String> = mutableListOf() private val headers: MutableMap<String, List<String>> = mutableMapOf() fun request(): JsonObject { var appendParameters = parameters // 当启用 WBI 签名 if (wbi) { val rawWBIKey: String = "替换成 img_key" + "替换成 sub_key" val mixinKeyEncTab = intArrayOf( 46, 47, 18, 2, 53, 8, 23, 32, 15, 50, 10, 31, 58, 3, 45, 35, 27, 43, 5, 49, 33, 9, 42, 19, 29, 28, 14, 39, 12, 38, 41, 13, 37, 48, 7, 16, 24, 55, 40, 61, 26, 17, 0, 1, 60, 51, 30, 4, 22, 25, 54, 21, 56, 59, 6, 63, 57, 62, 11, 36, 20, 34, 44, 52 ) val key = StringBuilder() for (i in 0..31) { key.append(rawWBIKey[mixinKeyEncTab[i]]) } val mixinKey = key.toString() val wts = System.currentTimeMillis() / 1000 val tempParamenters = "${this.getUrlParameters("$appendParameters&wts=$wts")}$mixinKey" appendParameters = "$appendParameters&w_rid=${DigestUtil.calculateMD5(tempParamenters)}&wts=$wts" } val client = URL("$apiUrl${if (appendParameters.isEmpty()) "" else "?$appendParameters"}") with(client.openConnection() as HttpURLConnection) { val response = StringBuilder() setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36 Edg/118.0.2088.76") setRequestProperty("Accept", "*/*") setRequestProperty("Connection", "keep-alive") if (cookies.isNotEmpty()) { val strJoiner = StringJoiner("; ") cookies.forEach { strJoiner.add(it) } setRequestProperty("Cookie", strJoiner.toString()) } requestMethod = "GET" inputStream.bufferedReader().use { it.lines().forEach { line -> response.append(line) } it.close() headers.putAll(he…

个人的一些日常学习方法及管理软件
type: item
date: 2024-02-01T22:12:00+08:00
description: 壹; 前言这篇文章仅分享一些我个人日常学习方法及管理软件，文中提到的软件均为长期使用过的。为什么要分那么多软件？因为在使用软件的时候可以专注于一个类型的事情上，比如：只专注于学习、只专注于任务管理。贰; 日记个人比较推荐使用记事本与笔手写日记，而非在软件上记录，用笔撰写日记与键盘敲打体验是不一样的，虽然键盘能带来更高的效率，但在过程中你的思绪不会像手写一样沉浸与深入，也没有过多影响思考的因素。当然，如果你非要使用软件的话，我会向你推荐 思源笔记 与 memos叁; 滴答清单滴答清单是我现在最离不开的软件了，滴答清单我已使用了快三年时间，我会用它来管理我的事务及项目，在滴答清单更新看板模式之前，我尝试过不少项目管理软件，如：Trello、MicrosoftTodo、Asana、ClickUp 等，其中 Trello 体验较为不错，但免费版只能创建十个看板，而且在一些时候延迟较高。为什么选择滴答清单来管理事务及项目？跨平台支持(Windows、Linux、MacOS、Android、iOS、网页版、浏览器扩展等)、看板模式、时间线模式、番茄钟、四象限、支持分组、任务日期提醒、自定义过滤器、共享协作等。滴答清单我只用于分配今天、未来什么时候要做什么事、项目管理，或有什么新的项目灵感会记录在收集箱中，等我思考确定可行性之后就会分配至任务组并确定任务日期与优先级，在项目管理过程中，我会使用看板模式来分组并分配事务类型，如下图。肆; 思源笔记思源笔记也是我现在离不开的软件之一，我会用他来记录我的年度总结、个人计划、年度计划、季度计划与更详细作品策划和灵感。伍; Cubox这款软件是偶然发现的，整个界面非常简洁美观，非常适合处理碎片化知识及待阅读文章，跨平台支持并且有浏览器扩展，可以在查阅网站或选择需要的内容拖动收藏，我会每天收集一些文章放在 Cubox，当我忙完工作上的事之后，就可以在 Cubox 内直接开始阅读。陆; 结尾这是个快餐化的时代，愿各位在这个充满碎片化信息的汪洋大海中能独立思考，不被沈覆，共勉。