Dex 化妆品

Dex 化妆品

帽子。翅膀。暴风雪粒子效果。自定义物品皮肤。全在服务端实现。你的玩家无需安装任何东西。

装饰

Dex Cosmetics

一个基于 Fabric 1.21.1 的服务端装饰模组。包含帽子、背部物品(披风、翅膀、背包)、物品皮肤以及视觉效果(粒子、发光轮廓、基岩版格式粒子)。100% 服务端安装——原版客户端通过 Polymer 自动提供的资源包可看到所有内容。

运行环境

  • Minecraft: 1.21.1
  • Mod 加载器: Fabric 0.19.2 或更新版本
  • 仅服务端——客户端运行原版;无需客户端安装

依赖项

依赖项 版本 类型 作用
fabric-api 0.116.12+1.21.1 必需 核心 Fabric API(事件、指令、网络)
fabric-language-kotlin 1.13.11 / Kotlin 2.3.21 必需 模组使用 Kotlin 编写
polymer 0.9.19+1.21.1 必需 服务端自定义物品 + 模型注册
text-placeholder-api 2.4.2+1.21 必需(传递性) MiniMessage 格式文本解析
LuckPerms 5.4 API 可选 管理员指令的权限检查;若不存在则回退至原版 op 等级
Cobblemon 1.7.3+1.21.1 可选 仅雪暴粒子效果需要;运行时按需加载

安装

  1. 将模组 jar 文件放入服务器的 mods/ 文件夹,同时放入其必需依赖项(Fabric API、Fabric Language Kotlin、全部四个 Polymer 模块、sgui、placeholder-api)。
  2. 启动一次服务器——首次运行时会生成 config/dex_cosmetics/ 目录,包含默认设置文件、内置示例装饰物品,以及用于添加自定义装饰的目录结构。
  3. (可选)如需基于权限的管理员指令访问权限,请安装 LuckPerms。若不安装,管理员指令需 op 等级 4。
  4. (可选)如需雪暴粒子效果,请安装 Cobblemon。若不安装,这些装饰物品仍会加载但不会渲染效果。

客户端正常连接——Polymer-autohost 会在玩家加入时自动提供资源包。默认情况下资源包标记为必需;拒绝的玩家将被踢出。此设置可配置。

配置

全局配置 — config/dex_cosmetics/config.json

{
  "require_resource_pack": true,
  "resource_pack_kick_message": "此服务器需要 Dex Cosmetics 资源包。",
  "autosave_interval_seconds": 300,
  "particle_tick_budget_per_player": 32,
  "admin_permission": "dexcosmetics.admin",
  "allow_item_skin_sharing": true,
  "rename_item_to_skin_name": false,
  "resource_pack_mode": "auto",
  "custom_model_data_start": 2000,
  "menu_categories": {
    "ITEM": true,
    "HAT": true,
    "BACK": true,
    "EFFECT": true,
    "BALLOON": false,
    "POKEMON": false
  },
  "menu_focus": "HAT"
}
  • require_resource_pack——设为 true 时,拒绝资源包的客户端将被踢出并显示 resource_pack_kick_message 中的消息。设为 false 可允许玩家不安装资源包进入(他们将看到原版内容)。
  • autosave_interval_seconds——目前仅作参考;玩家数据在每次授予/收回/装备时都会持久化保存。
  • particle_tick_budget_per_player——目前仅作参考;粒子装饰通过每个装饰物的 interval_ticks 进行限流。
  • admin_permission——检查 LuckPerms 权限节点,用于 /cosmetics give/take/list/reload/generatepack 指令。若无 LuckPerms,则需要 op 等级 4。
  • allow_item_skin_sharing——设为 true(默认值)时,带皮肤的物品在掉落/交易时会保留皮肤。设为 false 时,非拥有者捡起物品时皮肤组件会被移除。
  • rename_item_to_skin_name——设为 true 时,应用了皮肤的物体会显示装饰物的名称而非原版物品名称。名称覆盖在同步时的客户端副本上生效,因此交易不会永久重命名底层物品堆。

装饰物定义 — config/dex_cosmetics/cosmetics/<type>/<id>.json

每个装饰物对应一个 JSON 文件,分为四个子目录:

  • hats/——头部装备(type: HAT)
  • back/——披风、翅膀、背包(type: BACK)
  • items/——手持物品皮肤(type: ITEM)
  • effects/——粒子、发光、雪暴(type: EFFECT)

每个文件定义如下:

{
  "id": "my_cosmetic",
  "type": "HAT",
  "display_name": "<gold>我的帽子</gold>",
  "description": ["描述文字 第一行", "描述文字 第二行"],
  "model": "dex_cosmetics:hats/my_cosmetic",
  "texture": "dex_cosmetics:hats/my_cosmetic/my_cosmetic",
  "model_parent": "minecraft:item/generated",
  "transform": {
    "offset_x": 0, "offset_y": 0, "offset_z": 0,
    "scale_x": 1, "scale_y": 1, "scale_z": 1
  }
}

按类型细分:

  • HAT——使用 transform 将偏移/缩放烘焙到模型的 display.head 视角中。
  • BACK——仅读取 scale.x(通过 SCALE 属性实现统一缩放)。位置由原版盔甲架骑乘逻辑固定。
  • ITEM——需要 item_skin: { compatible_items: [...] }。每个条目是物品 ID(minecraft:diamond_sword)或标签(#minecraft:swords)。
  • EFFECT——需要 effect: { kind: "particle" | "glow" | "snowstorm", ... }。详见 cosmetics/effects/ 中的示例。

模型 — config/dex_cosmetics/model/<type>/<id>.json

在此处放置以装饰物 ID 命名的 Blockbench 导出文件;资源包将自动使用它。若不存在,则会根据装饰物的 model_parent 和 texture 字段创建一个简单的 {parent, layer0} 模型。

对于手持工具(物品皮肤等),请确保模型包含 "parent": "minecraft:item/handheld" 以及正确的 display 部分。

纹理 — config/dex_cosmetics/textures/<type>/<id>/<png>

位于 textures/hats/my_hat/example.png 的文件在资源包中会显示为 assets/dex_cosmetics/textures/hats/my_hat/example.png,可通过 dex_cosmetics:hats/my_hat/example 引用。与 PNG 同目录的 .mcmeta 文件也会被保留,因此支持动画纹理。

雪暴粒子 — config/dex_cosmetics/snowstorm_particles/<id>.particle.json

基岩版格式的粒子定义。JSON 中的 description.identifier 字段是 EFFECT 装饰物通过 effect.snowstorm.particle_id 引用的内容。Cobblemon 的 BedrockParticleEffectRepository 会在资源包构建时获取这些内容。

功能

装饰物类型

帽子——通过伪造的 EntityEquipmentUpdateS2CPacket 发送,因此原版的头盔骨骼盔甲管线会渲染它们。支持头部旋转、俯仰时的前移偏移、完美追踪。穿戴者的真实头盔仍保留在物品栏中不受影响。

背部物品——一个隐形的标记实体以乘客身份骑乘在穿戴者身上,装饰物放在 HEAD 装备槽中。在游泳、飞行、睡觉、旋转攻击姿势时自动隐藏,退出姿势后重新生成。

物品皮肤——玩家通过装饰物 GUI 应用皮肤:手持目标物品并点击皮肤图标。可通过配置选择是否在非拥有者捡起物品时移除皮肤。

效果——通过 kind 字段提供三种风格:

  • 粒子:原版粒子。两种创作模式——内置预设形状(point/trail/halo/orbit/square),可通过粒子类型+数量+半径进行参数化;或者在穿戴者位置直接运行原版指令(op 等级+静默反馈)。
  • 发光:每 tick 刷新原版 GLOWING 状态效果。通过计分板队伍成员资格实现每个装饰物自定义轮廓颜色(每种 Formatting 颜色对应一个 dex_glow_<formatting> 队伍)。
  • 雪暴:通过 Cobblemon 的 SpawnSnowstormParticlePacket 实现基岩版格式粒子爆发。通过 interval_ticks 限流,在穿戴者周围 broadcast_radius 方块范围内广播。

按玩家所有权

基于 SQLite 的按玩家装饰物所有权。玩家可以在 GUI 中看到完整目录,但只能装备自己拥有的装饰物。管理员通过指令进行授予/收回。

数据存储在 <world>/dex_cosmetics/cosmetics.db 中。包含两个表:player_owned (uuid, cosmetic_id) 和 player_equipped (uuid, type, cosmetic_id)。首次运行时自动创建模式。

宝箱/商店集成

现有的宝箱插件、商店和战利品表可通过运行以下指令授予装饰物:

/cosmetics give <玩家> <装饰物ID>

(或使用 /cosmetics take 来收回)。这是支持的集成点——任何能执行控制台指令的系统都可以授予装饰物。

玩家指令

指令 权限 描述
/cosmetics 无 打开装饰物 GUI
/cosmetics remove 无 移除手持物品上应用的皮肤
/cosmetics give <玩家> <ID> 管理员 授予装饰物所有权
/cosmetics take <玩家> <ID> 管理员 收回装饰物所有权
/cosmetics list <玩家> 管理员 列出玩家拥有的装饰物
/cosmetics reload 管理员 重新加载所有装饰物配置并重建资源包
/cosmetics generatepack 管理员 手动生成资源包

资源包组装在标签加载后的 SERVER_STARTING 阶段进行:

  1. CosmeticItems.registerAll 通过 PolymerResourcePackUtils.requestModel 为每个装饰物以及每个(皮肤,物品)变体分配 CMD。
  2. DexCosmetics.buildResourcePack 触发 Polymer 的 RESOURCE_PACK_CREATION_EVENT。
  3. 事件处理器执行 pipeUserTextures、pipeSnowstormParticles、PackModelGenerator.writeAll、GlowIconGenerator.writeAll,并写入方块和粒子图集覆盖。
  4. polymer-autohost 在后续玩家加入时提供生成的 polymer/resource_pack.zip。

创建装饰物

  1. 模型:在 Blockbench 中设计装饰物。使用 Java 方块/物品项目类型,以便导出时包含 parent 和 display 块。
  2. 纹理:导出 PNG 并放入 config/dex_cosmetics/textures/<type>/<id>/<id>.png。
  3. 装饰物配置:在 config/dex_cosmetics/cosmetics/<type>/<id>.json 中编写 JSON 文件(参考内置示例)。
  4. 模型文件(可选但常见):如果有包含多个纹理、自定义元素等的 Blockbench 导出,将其保存为 config/dex_cosmetics/model/<type>/<id>.json。
  5. 重载:使用 /cosmetics reload 或重启服务器。玩家需要重新连接以重新下载更新后的资源包。