Skip to content

新映射 LyGalaxyMapped

LyGalaxyMapped 是一个服务端动态构筑插件。插件根据装备、玩家状态、权限、PlaceholderAPI 条件和临时标签计算标签层数,再按照映射需求、排斥条件和组优先级选择生效构筑,最后刷新属性、药水效果和状态消息。

插件版本为 1.0.0。属性写入需要配置并启用对应的属性插件;PlaceholderAPI 为可选接入,只有使用 PAPI 条件、插件占位符、消息占位符或公式占位符时才需要安装。

项目概览

项目说明
发布类型服务端插件
当前版本1.0.0
主要玩法装备、玩家状态和临时标签转换为标签层数,再匹配动态映射构筑
属性接入AttributePlus、AttributeSystem、SX-Attribute、ItemLoreOrigin
主配置plugins/LyGalaxyMapped/config.yml
映射配置plugins/LyGalaxyMapped/mapped/ 下扩展名为 .yml 的文件
根指令/lgm

支持版本

项目提供以下 Minecraft 服务端版本的适配代码:

1.7.101.8.81.11.21.12.21.13.21.14.41.15.21.16.51.17.11.18.21.19.21.19.41.20.11.20.21.20.3

项目证据未确认未列出版本的兼容性。

依赖与外部接入

属性插件

主配置中的 attribute-plugin 用于选择属性写入方式。需要让映射属性生效时,必须安装并启用配置对应的属性插件。

配置值用途与要求
AttributePlus使用 AttributePlus 写入属性。
AttributeSystem使用 AttributeSystem 写入属性。
SX-Attribute使用 SX-Attribute 写入属性。
ItemLoreOrigin使用 ItemLoreOrigin 写入属性。ItemLoreOrigin 未启动时属性写入不会成功,同步任务固定每 20 tick 运行一次。

属性插件名称会去除首尾空格并按不区分大小写处理。配置值不支持或对应接口不可用时,属性不会写入。

PlaceholderAPI

PlaceholderAPI 为可选依赖。以下功能需要 PlaceholderAPI 已安装并启用:

  • papi(...) 标签条件。
  • LyGalaxyMapped 的 PlaceholderAPI 占位符。
  • 映射属性公式中的 PlaceholderAPI 占位符。
  • 映射状态消息中的 PlaceholderAPI 占位符展开。

外部背包与槽位

plugin-slot 可以读取原版背包和多个外部背包插件的槽位。使用外部槽位时,对应插件及其槽位 API 必须可用。

支持的外部槽位类型包括 DragonCore、GermPlugin、APInventory、LyInventory、LyInventoryReload 和 YeeJewelry。

插件资源中的 plugin.yml 声明了以下软依赖:PlaceholderAPIDZ_StatusAttributePlusSX-AttributeItemLoreOriginAPInventoryLyInventoryGermPlugin。其中 DZ_Status 的具体功能接入,项目证据未作进一步确认。

功能

  • 按物品名称、Lore、NBT、权限、PlaceholderAPI 和玩家状态计算标签层数。
  • 每条条件独立统计命中次数,并按照数字权重增加标签层数。
  • 支持标签层数上限、映射需求和排斥条件。
  • 相同映射组只激活满足条件且优先级最高的一条映射。
  • 不同映射组可以同时生效。
  • 从装备 Lore 提取数值,为映射属性提供动态变量。
  • 使用标签层数、Lore 动态变量和 PlaceholderAPI 展开属性公式。
  • 为生效映射刷新药水效果。
  • 在映射进入、离开或同组切换时发送消息。
  • 提供标签、映射状态和映射属性的 PlaceholderAPI 查询。
  • 提供临时标签公共 API。
  • 支持重载配置,并在重载后重新计算在线玩家状态。

指令

根指令为 /lgm

指令说明执行限制
/lgm显示帮助。无额外限制。
/lgm help显示帮助。无额外限制。
/lgm active [玩家]查询自己或指定在线玩家当前已激活的映射。查询其他玩家需要 OP;控制台执行时必须指定在线玩家。
/lgm tag [玩家]查询自己或指定在线玩家最近计算出的标签及层数。查询其他玩家需要 OP;控制台执行时必须指定在线玩家。
/lgm reload重载主配置和 mapped 目录中的 .yml 文件,并重新计算在线玩家。仅 OP。

plugin.yml 未声明权限节点,权限判断使用发送者的 OP 状态。

activetag 查询读取最近一次计算缓存,不会因为查询命令重新扫描物品。OP 在查询命令的第二个参数输入在线玩家名称时,可以查询目标玩家;普通玩家不会获得其他玩家名称的补全。

配置文件结构

插件使用两个配置范围:

  • plugins/LyGalaxyMapped/config.yml:运行参数、属性插件和全局槽位。
  • plugins/LyGalaxyMapped/mapped/:标签和映射数据。

tag-checkmapped 不从主 config.yml 读取,只从 mapped 目录中的 .yml 文件读取。插件会递归扫描该目录及其子目录,并按文件路径排序加载。相同标签 ID 或映射 ID 重复时,后加载的定义会被忽略。

插件默认保存 mapped/示例配置.yml,不会覆盖已经存在的文件。

主配置:config.yml

yaml
attribute-plugin: 'AttributePlus'
thread-running-interval: 20
plugin-slot:
  - 'Origin#MainHand'
  - 'Origin#OffHand'
  - 'Origin#Helmet'
  - 'Origin#ChestPlate'
  - 'Origin#Legging'
  - 'Origin#Boots'

顶层配置键

配置键类型默认值说明
attribute-plugin字符串AttributePlus选择属性写入插件。支持 AttributePlusAttributeSystemSX-AttributeItemLoreOrigin
thread-running-interval整数20标签和映射检测间隔,单位为 tick。小于 1 时按 1 处理。
plugin-slot字符串列表配置文件中的六个原版槽位指定插件读取和扫描的物品槽位。

plugin-slot 槽位格式

槽位配置使用完整字符串,# 用于分隔插件类型、背包标识和槽位标识。

格式说明
Minecraft#槽位ID读取原版背包数字槽位,槽位 ID 必须是数字。
Origin#MainHand原版主手。
Origin#OffHand原版副手。旧版本没有副手 API 时返回空值。
Origin#Helmet原版头盔槽位。
Origin#ChestPlate原版胸甲槽位。
Origin#Legging原版护腿槽位。
Origin#Boots原版鞋子槽位。
DragonCore#槽位名读取 DragonCore 槽位。
GermPlugin#槽位名读取 GermPlugin 槽位。
APInventory#分页ID#槽位ID读取 APInventory 指定分页的数字槽位。
LyInventory#背包ID#槽位名读取 LyInventory 指定背包的槽位。
LyInventoryReload#背包ID#槽位名读取 LyInventoryReload 指定背包的槽位。
YeeJewelry#背包ID#槽位ID读取 YeeJewelry 指定背包的槽位。

读取到的物品会保存为独立克隆。单个槽位或外部接口读取失败时只跳过该槽位;主手或副手读取失败时会移除对应旧快照,避免旧属性残留。

标签检测配置:mapped/*.yml

标签配置的顶层节点为 tag-check

yaml
tag-check:
  '火焰':
    condition:
      1:
        - lore('元素:火焰')
        - nbt('lgm.element', 'fire')
      2:
        - permission('lgm.先天霜火圣体')
    max-point: -1

标签节点

配置键类型默认值说明
tag-check.<标签>节点定义一个标签及其计算规则。
tag-check.<标签>.condition节点或字符串列表定义条件。标准写法为 权重: 条件列表
tag-check.<标签>.condition.<权重>字符串列表每条条件独立统计命中次数,每次命中增加对应权重的标签层数。
tag-check.<标签>.check-slot字符串列表,可选使用全局 plugin-slot指定当前标签扫描的槽位。
tag-check.<标签>.max-point整数-1限制最终标签层数。负数表示不限制。
tag-check.<标签>.point整数,可选1condition 直接写成字符串列表时,指定每次命中的层数。

同一权重下的多条条件不是多行 AND。每条字符串条件分别统计命中次数,再乘以该条件的权重后累计。同一件物品同时满足多条条件时,各条件仍然分别计数,不进行物品去重。

包含 namelorenbt 的条件表达式,会在配置槽位范围内按符合条件的物品快照数量统计。只包含权限、PlaceholderAPI 或玩家状态函数的条件,每条条件只按结果命中一次,不会按物品槽位重复计算。

max-point 会在所有条件累计完成后限制最终层数。-1 表示无上限。

直接列表写法

condition 不是节点而是字符串列表时,可以使用 point 指定统一权重:

yaml
tag-check:
  '白天':
    condition:
      - time('day')
    point: 1
    max-point: 1

条件表达式

条件使用函数式写法。函数参数使用单引号,多个参数使用逗号分隔。单条条件中的顶层 || 表示 OR;在函数前添加 ! 表示取反。&& 仅用于 papi(...) 的比较表达式。

条件说明
name('文本')物品名称包含文本。
name('文本', contains)物品名称包含文本。
name('文本', equals)物品名称完整匹配文本。
lore('文本')任意一行 Lore 包含文本。
lore('文本', contains)任意一行 Lore 包含文本。
lore('文本', equals)任意一行 Lore 完整匹配文本。
nbt('路径', '值')NBT 标量值完整匹配。
nbt('路径', 5)NBT 数值完整匹配。
permission('权限节点')玩家拥有指定权限时命中。
nopermission('权限节点')玩家没有指定权限时命中。
papi(比较表达式)根据 PlaceholderAPI 展开的比较表达式判断。
world('世界名')玩家当前世界名称匹配时命中。
time('day')当前世界时间为白天,即 011999
time('night')当前世界时间为夜晚,即 1200023999
gamemode('模式')玩家当前游戏模式匹配时命中。
weather('clear')当前世界无雨且无雷。
weather('rain')当前世界下雨但不打雷。
weather('thunder')当前世界正在打雷。
weather('storm')thunder 的同义写法。

名称和 Lore 条件的文本参数会先转换 & 颜色码,再进行匹配。

NBT 比较模式

nbt 的字符串比较支持:

  • equals:完整匹配。
  • !=:不等于。
  • contains:包含目标文本。
  • startsWith:以目标文本开头。
  • endsWith:以目标文本结尾。
  • ignoreCase:忽略英文大小写,可以与其他比较模式组合使用。

NBT 数值比较支持 >>=<<=。数值比较要求 NBT 实际值和目标值都可以转换为数字。

示例:

yaml
condition:
  1:
    - papi(%player_level% >= 5 && %player_level% <= 10)
    - permission('lgm.vip') || papi(%player_level% >= 30)
    - "!lore('已绑定')"

当前格式不读取旧版的 checkattribute-grouplore:{...}nbt:{...}permission:{...} 写法。

映射配置:mapped/*.yml

映射配置的顶层节点为 mapped

yaml
mapped:
  '霜火共鸣1级':
    group-id: '霜火共鸣'
    group-priority: 1
    require:
      '火焰': 1
      '冰霜': 1
    exclude:
      '夜间': 1
    lore-get-placeholder:
      '变量id': '获得 <value>x玩家 等级点攻击力'
    attribute:
      - '火属性伤害: {var.变量id}'
      - '火焰层数伤害: <{tag.火焰}*2>'
    potion:
      - 'SPEED:1'
    start-message:
      - '&7你触发了 &a{id}'
    end-message:
      - '&7你的 &a{id} &7消失了'

映射节点

配置键类型默认值说明
mapped.<映射>.group-id字符串当前映射 ID映射所属的组。同组映射只生效一条。
mapped.<映射>.group-priority整数0同组映射优先级。满足需求时优先级最高者生效。
mapped.<映射>.require节点标签 ID 到最低层数的映射。多个标签必须同时满足。
mapped.<映射>.exclude节点标签 ID 到排斥层数的映射。任意标签达到配置层数时,映射不生效。
mapped.<映射>.attribute字符串列表空列表映射生效时提交给属性插件的属性文本。
mapped.<映射>.lore-get-placeholder节点从配置槽位物品的 Lore 中提取动态数值。
mapped.<映射>.potion字符串列表空列表映射生效时应用的药水效果。
mapped.<映射>.start-message字符串列表空列表映射开始生效时发送的消息。
mapped.<映射>.end-message字符串列表空列表映射结束生效时发送的消息。

require 中的多个标签默认使用 AND 关系。exclude 中任意标签达到配置层数,当前映射都会被排斥。

相同 group-id 的映射只保留一条:先筛选满足 require 且未触发 exclude 的映射,再选择 group-priority 最高者。同组优先级相同时,映射 ID 按字典序较小者优先。不同 group-id 的映射可以同时生效。

药水格式

药水配置格式为 TYPE:LEVEL[:SECONDS]

  • TYPE 使用 Bukkit 药水效果名称。
  • LEVEL 按游戏显示等级填写,1 对应一级效果。
  • SECONDS 可选,单位为秒,必须是正整数。
  • 未填写持续时间或持续时间无效时,默认使用检测间隔的两倍,并且默认值至少为 2 秒。
  • 单行配置格式错误或效果类型无法识别时,跳过该行。
  • 同一类型药水同时来自多个映射时,等级更高者优先;等级相同时持续时间更长者优先。

示例资源中列出的效果名称包括:

SPEEDFAST_DIGGINGSLOW_DIGGINGINCREASE_DAMAGEHEALHARMJUMPCONFUSIONREGENERATIONDAMAGE_RESISTANCEFIRE_RESISTANCEWATER_BREATHINGINVISIBILITYBLINDNESSNIGHT_VISIONHUNGERWEAKNESSPOISONWITHERHEALTH_BOOSTABSORPTIONSATURATIONFIRE

映射消息

start-messageend-message 只在映射组状态发生变化时发送,不会在每次检测时重复发送。

  • {id} 替换为当前映射 ID。
  • & 转换为 Minecraft 颜色码。
  • PlaceholderAPI 启用时,消息会继续展开 PlaceholderAPI 占位符。
  • 同组映射切换时,先发送旧映射的结束消息,再发送新映射的开始消息。

变量与属性公式

Lore 动态变量

lore-get-placeholder 的键是变量名,值是 Lore 模板。使用 <value> 标记待提取的数值位置:

yaml
lore-get-placeholder:
  '变量id': '获得 <value>x玩家 等级点攻击力'

插件会扫描配置槽位中物品的每一行 Lore,将匹配到的数值累加。同一变量在多个物品或多行 Lore 中命中时会继续累加,未命中的变量按 0 处理。

属性中使用 {var.变量名} 读取 Lore 动态变量。

标签变量

属性中使用 {tag.标签名} 读取本次计算得到的标签层数。装备条件标签和临时标签会合并计算,未找到的标签按 0 处理。

属性公式

属性文本中的 <...> 会被逐段计算。公式支持整数、浮点数、+-*/ 和括号运算。PlaceholderAPI 启用时,公式中的 PlaceholderAPI 占位符会先展开。

yaml
attribute:
  - '火焰层数伤害: <{tag.火焰}*2>'
  - '等级伤害: <%player_level%*2>'

属性中的 {var.xxx}{tag.xxx} 会先替换,再计算 <...> 公式。

PlaceholderAPI 占位符

扩展标识为 lgm。PlaceholderAPI 未安装或玩家对象为空时,插件占位符返回空字符串或对应的零值。

占位符返回内容
%lgm_tag-标签%当前玩家指定标签的层数。
%lgm_active-组ID%当前玩家指定映射组实际激活的映射 ID。
%lgm_mapped-映射ID%当前缓存中指定映射的第 1 条属性。
%lgm_mapped-映射ID:序号%当前缓存中指定映射的指定序号属性,序号从 1 开始。
%lgm_Mapped-映射ID%mapped 前缀的大小写兼容写法。
%lgm_Mapped-映射ID:序号%mapped 前缀的大小写兼容写法。

映射属性占位符读取最近一次计算缓存,不会因为查询而重新扫描物品或重新计算公式。映射未激活、序号无效或属性不存在时返回空字符串。

公共 API

插件提供 LyGalaxyMappedAPI 公共接口,用于向玩家添加、移除和查询临时标签。

方法返回值说明
addTag(Player player, String tagId, int points, long durationTicks)boolean添加一个按 tick 自动过期的临时标签条目。
removeTag(Player player, String tagId)boolean移除玩家指定标签的全部临时标签条目。
clearTags(Player player)清空玩家当前全部临时标签。
getTemporaryTagPoints(Player player)Map<String, Integer>获取玩家当前尚未过期的临时标签层数合计。

API 规则:

  • player 为空、标签 ID 为空或只有空格、points0durationTicks 不大于 0 时,addTag 返回 false
  • 标签 ID 会去除首尾空格后保存。
  • 同一玩家同一标签的多次添加会独立叠加,并分别按持续 tick 数过期。
  • 临时标签会与装备计算出的标签层数合并后参与映射判断。
  • removeTag 移除不存在的标签时返回 false
  • getTemporaryTagPoints 只统计尚未过期的条目,并返回当前标签的合计层数。
  • 玩家退出或插件停止时,会清理该玩家的临时标签。

运行机制

  1. 插件按 plugin-slot 异步读取物品快照,并以完整槽位配置字符串保存独立物品克隆。
  2. 玩家加入、关闭背包、切换快捷栏或交换主副手时,会请求刷新相关快照。
  3. 全局快照任务每 10 tick 批量处理被标记的玩家;标签和映射计算按照 thread-running-interval 执行,默认间隔为 20 tick。
  4. tag-check 统计装备条件、玩家状态和临时标签,得到最终标签层数。
  5. mapped 检查 requireexclude,再按 group-id 选择同组最高优先级映射。
  6. 不同组的生效映射会合并属性和药水结果。
  7. 属性插件写入、药水修改、消息发送和外部槽位事件在服务端主线程执行。
  8. 重载时先清理旧属性和由插件管理的药水,再加载新配置并重新计算在线玩家。
  9. 玩家退出或插件停止时,会清理属性、药水、临时标签和快照缓存。

常见问题

为什么映射没有生效?

检查以下内容:

  • require 中的多个标签是否全部达到要求。
  • exclude 中是否有任意标签达到排斥层数。
  • plugin-slot 是否包含实际存放装备的槽位。
  • 外部背包插件及对应槽位 API 是否正常可用。
  • 同组是否存在优先级更高且同样满足需求的映射。
  • mapped 配置文件是否位于 plugins/LyGalaxyMapped/mapped/ 目录,并且扩展名为 .yml
  • papi(...) 条件使用时 PlaceholderAPI 是否已安装并启用。

为什么标签层数比装备数量更多?

每条条件独立累计。命中次数会乘以该条件所在数字节点的权重,同一件物品满足多条条件时会分别计数,不会去重;临时标签也会合并到最终层数。

condition 下的数字是不是条件编号?

不是。数字代表每次条件命中增加的标签层数。例如 2 表示该条件每命中一次增加 2 层。

为什么同组的多个映射不会同时生效?

相同 group-id 的映射属于同一组。同组只保留满足需求、未触发排斥条件且优先级最高的一条;相同优先级时按映射 ID 字典序选择一条。不同 group-id 的映射可以同时生效。

为什么属性没有刷新?

确认 attribute-plugin 与已安装的属性插件名称一致,并确认对应插件已经启动。配置为 ItemLoreOrigin 时,还要确认 ItemLoreOrigin 已启动。属性插件接口不可用或配置值不支持时,属性写入不会成功。

为什么 PlaceholderAPI 条件没有命中?

确认 PlaceholderAPI 已安装并启用,并检查表达式中的占位符和比较运算符是否正确。papi(...) 支持 ==!=>>=<<=&&||

为什么映射属性占位符没有返回内容?

映射属性占位符读取最近一次计算缓存。检查映射是否实际激活、属性序号是否从 1 开始,以及查询的映射 ID 是否完全一致。查询不会主动触发重新计算。

药水配置应该怎么写?

使用 TYPE:LEVEL[:SECONDS]。例如 SPEED:1 表示一级速度效果,SPEED:2:10 表示二级速度效果并指定持续 10 秒。未填写持续时间时,插件根据检测间隔生成默认持续时间。

修改配置后需要重新加载吗?

需要执行 /lgm reload。该指令仅允许 OP 执行。重载会重新读取 config.ymlmapped 目录中的 .yml 文件,并重新计算在线玩家状态。

tag-checkmapped 写在主配置中为什么没有生效?

当前版本只从 plugins/LyGalaxyMapped/mapped/ 目录中的 .yml 文件读取 tag-checkmapped。主 config.yml 只读取 attribute-pluginthread-running-intervalplugin-slot 等运行配置。

旧版 checkattribute-group 配置还能使用吗?

不能。当前版本只读取 tag-checkmapped 节点,旧版 checkattribute-group 以及旧的冒号大括号条件格式不会被读取。

为什么使用 Origin#OffHand 后旧版本没有检测到副手?

部分旧版本没有副手 API,插件会安全返回空值。项目提供证据未确认这些版本存在可读取的副手槽位接口。