Skip to content

开发接口

LyGalaxyStrengthen 提供 LyGalaxyStrengthenAPI,供其他服务端插件读取装备强化数据、直接调整装备等级,以及按照普通强化规则执行一次完整强化。

API 会处理装备 NBT、Lore、玩家背包、货币、权限、材料、保护石、通用材料和强化脚本。所有修改装备或玩家数据的操作都必须在服务端主线程调用,并等待强化系统初始化完成。

公开类型

API 接口

java
Ly.galaxy.strengthen.client.plugin.api.LyGalaxyStrengthenAPI

结果类型

java
Ly.galaxy.strengthen.client.plugin.api.data.StrengthenResult
Ly.galaxy.strengthen.client.plugin.api.data.StrengthenAttemptResult

项目证据未提供 API 实例的公开获取方法。接入时应使用实际发布版本提供的入口,不要自行创建 API 实现类,也不要依赖非公开实现类型。

调用要求

要求说明
修改线程upgradedowngradeattemptStrengthenexecutePendingScripts 必须在服务端主线程调用
初始化状态强化配置、强化方案、界面和 NBT 适配完成加载后,修改类方法才可使用
物品处理API 通过结果对象返回处理后的 ItemStack,调用方必须使用返回物品完成写回
失败判断先检查结果对象的状态,不要只判断返回物品是否为 null
完整强化会读取并修改玩家的金币、额外货币、普通材料和相关外部材料来源
强化脚本可能返回待执行脚本,应先完成物品结算,再调用脚本执行方法

从异步任务发起修改操作时,需要先切换到 Bukkit 主线程:

java
// 插件实例:用于向 Bukkit 调度器提交主线程任务。
Plugin plugin = yourPlugin;

Bukkit.getScheduler().runTask(plugin, () -> {
    // 在服务端主线程中调用强化 API。
});

如果修改方法在异步线程调用,将返回失败结果。待处理脚本在异步线程执行时会抛出 IllegalStateException

方法总览

方法返回值用途
getStrengthenLevel(ItemStack item)int获取装备当前强化等级
getStrengthenSchemeId(ItemStack item)String获取装备绑定的强化方案 ID
getStrengthenFailureCount(ItemStack item)int获取装备当前连续强化失败次数
upgrade(ItemStack item, int targetLevel)StrengthenResult不扣除费用,直接将装备提升到指定等级
downgrade(ItemStack item, int targetLevel)StrengthenResult不扣除费用,直接将装备降低到指定等级
attemptStrengthen(Player player, ItemStack equipment, ItemStack protectionStone, ItemStack universalMaterial)StrengthenAttemptResult按照普通强化规则执行一次完整强化

公开 API 未提供强化直升、强化转移、打开界面或重载配置的方法。

读取强化数据

读取方法不会执行强化、扣除费用、消耗材料或修改物品。

获取当前等级

java
int getStrengthenLevel(ItemStack item)

返回装备当前保存的强化等级。没有有效强化数据的物品按 0 级处理。

java
// 当前等级:装备没有有效强化数据时为 0。
int currentLevel = api.getStrengthenLevel(item);

获取强化方案 ID

java
String getStrengthenSchemeId(ItemStack item)

返回装备绑定的普通强化方案 ID。装备未被强化系统托管时返回 null

方案 ID 对应普通强化方案文件中的 id。装备首次完成强化数据初始化后会绑定方案,后续不能直接改用其他方案。

java
// 强化方案 ID:未托管装备返回 null。
String schemeId = api.getStrengthenSchemeId(item);

if (schemeId == null) {
    // 当前装备尚未绑定强化方案。
    return;
}

不要只通过装备名称或可见 Lore 判断装备是否由插件托管。应以 getStrengthenSchemeId(item) 是否返回有效方案 ID 为准。

获取连续失败次数

java
int getStrengthenFailureCount(ItemStack item)

返回装备当前连续强化失败次数。该数据保存在装备中,并参与失败保底计算。

情况失败次数变化
有效强化成功清零
有效强化失败增加一次
保护石阻止降级或破坏仍然增加一次
装备失败后等级不变增加一次
装备失败后降级增加一次
装备失败后破坏本次结果仍按失败处理,但装备不再存在
金币、额外货币或材料不足未进入有效强化,不增加
方案、物品或公式校验失败未进入有效强化,不增加
java
// 连续失败次数:用于展示或外部逻辑判断。
int failureCount = api.getStrengthenFailureCount(item);

一次读取多项数据

java
// 强化方案 ID:用于判断装备是否由强化系统托管。
String schemeId = api.getStrengthenSchemeId(item);
// 当前等级:没有强化数据时为 0。
int currentLevel = api.getStrengthenLevel(item);
// 连续失败次数:没有强化数据时为 0。
int failureCount = api.getStrengthenFailureCount(item);

if (schemeId != null) {
    player.sendMessage("强化方案:" + schemeId);
    player.sendMessage("当前等级:" + currentLevel);
    player.sendMessage("连续失败:" + failureCount);
}

直接调整等级

upgradedowngrade 用于不扣除金币、额外货币、普通材料、保护石和通用材料的等级调整。方法会根据装备绑定的强化方案重新计算强化数据并重绘 Lore。

直接调整等级不等同于玩家通过普通强化界面执行强化,不会进行以下处理:

  • 不进行成功率判定。
  • 不应用权限成功率加成。
  • 不应用连续失败保底。
  • 不扣除金币、额外货币或普通材料。
  • 不处理保护石和通用材料。
  • 不随机执行等级不变、降级或装备破坏。
  • 不执行普通强化方案中的触发脚本。

直接升级

java
StrengthenResult upgrade(ItemStack item, int targetLevel)
参数说明
item已由强化系统托管的装备
targetLevel要提升到的目标等级

目标等级必须高于当前等级,并且不能超过装备绑定方案的最高等级。

java
// 目标等级:本次准备直接提升到的等级。
int targetLevel = 10;
// 升级结果:包含状态、说明和处理后的装备。
StrengthenResult result = api.upgrade(item, targetLevel);

if (!result.isSuccess()) {
    player.sendMessage(result.getMessage());
    return;
}

// 升级后装备:需要由调用方写回原槽位。
ItemStack upgradedItem = result.getItem();

直接降级

java
StrengthenResult downgrade(ItemStack item, int targetLevel)
参数说明
item已由强化系统托管的装备
targetLevel要降低到的目标等级

目标等级必须低于当前等级。降至 0 级时,插件会使用装备首次强化时保存的基础数据恢复对应 Lore。

java
// 目标等级:本次准备直接降低到的等级。
int targetLevel = 0;
// 降级结果:包含状态、说明和处理后的装备。
StrengthenResult result = api.downgrade(item, targetLevel);

if (!result.isSuccess()) {
    player.sendMessage(result.getMessage());
    return;
}

// 降级后装备:需要由调用方写回原槽位。
ItemStack downgradedItem = result.getItem();

StrengthenResult

upgradedowngrade 返回 StrengthenResult

方法返回值说明
isSuccess()boolean本次等级调整是否成功
getMessage()String简体中文处理结果或失败原因
getItem()ItemStack处理后的装备

调用方应始终接收 getItem() 返回的装备,不要假设传入的 ItemStack 已被原地修改。

常见失败情况包括:

  • 强化系统尚未就绪。
  • 在异步线程调用修改方法。
  • 物品为空或没有有效强化数据。
  • 装备绑定的强化方案已经失效。
  • 目标等级不符合升级或降级方向。
  • 目标等级超过方案上限。
  • 强化方案缺少目标等级规则。
  • 装备保存的基础 Lore 数据无法读取。
  • Lore 模板或强化公式无法正常计算。

修改方法失败时会尽量在结果中返回传入装备的安全副本。仍应先检查 isSuccess(),再决定是否写回结果物品。

执行完整强化

java
StrengthenAttemptResult attemptStrengthen(
    Player player,
    ItemStack equipment,
    ItemStack protectionStone,
    ItemStack universalMaterial
)

该方法按照普通强化界面的规则,执行一次从当前等级到下一级的强化。

完整流程包括:

  1. 检查强化系统状态与调用线程。
  2. 根据装备名称和已有强化数据识别唯一方案。
  3. 检查装备是否达到强化上限。
  4. 读取目标等级的强化规则。
  5. 计算基础成功率、权限加成和连续失败保底。
  6. 校验保护石与通用材料。
  7. 首次强化时提取并保存基础 Lore 数据。
  8. 预先验证目标等级装备能否正常重绘。
  9. 检查并扣除金币、额外货币和普通材料,或消耗通用材料。
  10. 按最终成功率判断强化结果。
  11. 处理保护石消耗。
  12. 处理成功、等级不变、降级或装备破坏。
  13. 更新当前等级、历史最高等级和连续失败次数。
  14. 返回结算物品以及可能存在的待执行脚本。

参数

参数是否可空说明
player承担费用、提供权限并作为脚本执行对象的玩家
equipment待强化装备
protectionStone本次使用的保护石;不使用时传入 null
universalMaterial本次使用的通用强化材料;不使用时传入 null

传入保护石或通用材料时,物品必须符合当前方案和目标等级规则。槽位中存在物品但规则不匹配时,本次操作会直接失败,不会消耗物品。

调用示例

java
// 强化结果:包含本次强化状态及三个结算物品。
StrengthenAttemptResult result = api.attemptStrengthen(
    player,
    equipment,
    protectionStone,
    universalMaterial
);

方案识别

完整强化不需要传入方案 ID。插件使用与普通强化界面相同的规则自动识别方案。

装备状态识别规则
未托管装备装备名称需要匹配方案的 equipment-names
首次强化需要从装备实际拥有的 Lore 中提取方案引用模板所需的基础值
已托管装备必须继续使用装备原先绑定的强化方案
多方案冲突同时匹配多个方案时拒绝处理,避免绑定错误
方案失效装备绑定的方案不存在时拒绝处理
名称变化已托管装备名称不再符合绑定方案时拒绝处理

成功率计算

最终成功率依次应用以下内容:

  1. 目标等级规则中的基础 chance
  2. 玩家拥有的最高一项 permission-chance
  3. 装备当前连续失败次数对应的 failure-guarantee
  4. 最终结果限制在 0100 之间。

权限加成按基础成功率乘算。玩家同时拥有多个配置权限时,只使用数值最高的一项。

失败保底使用 add 还是 multiply,由主配置中的 failure-guarantee-mode 决定。

消耗规则

未使用通用材料时,完整强化会按照目标等级规则检查并扣除以下内容:

消耗类型配置来源所需前置
金币need-moneyVault 和已注册的经济服务
点券need-currency.pointPlayerPoints
LyShop 货币need-currency.lyshop@货币IDLyShopReload
CraftX 变量货币need-currency.cx@变量IDCraftX
普通材料need-items材料标识对应的物品库插件

只有实际计算结果大于 0 的消耗才要求对应前置可用。前置不可用、余额不足、材料不足或材料模板无法读取时,不会进入成功率判定。

普通材料按显示名称匹配。重复配置的同名材料会合并数量后统一检查和扣除。

完整强化会直接处理玩家的货币和材料。调用方不得在调用 API 前后重复扣除相同内容。

OP 缺少消耗时的处理

当执行玩家是服务器 OP,并且本次普通强化缺少金币、额外货币或普通材料时,插件会尝试补齐实际缺少的数量,然后返回未处理成功的结果。

此时需要注意:

  • 本次不会进入成功率判定。
  • isProcessed() 返回 false
  • 结果说明会标明缺少内容是否全部补发成功。
  • 可能生成 cost-insufficient 类型的待执行脚本。
  • 调用方不应在收到该结果后自动再次强化,是否重试应由玩家重新发起操作。

通用材料

通用材料必须同时满足方案中的物品名称和目标等级范围。

匹配成功后:

  • 每次有效强化消耗一个通用材料。
  • 跳过本次 Vault 金币检查与扣除。
  • 跳过本次额外货币检查与扣除。
  • 跳过本次普通材料检查与扣除。
  • 仍然执行成功率、保护石、失败结果和强化脚本处理。

通用材料不匹配时,本次操作直接失败,并返回未消耗的物品副本。

保护石

保护石只阻止强化失败后的降级或装备破坏,不会将失败改为成功,也不会阻止连续失败次数增加。

保护石的消耗时机由 protection-item-consume 决定:

模式说明
failure仅在有效强化失败时消耗
always进入有效强化后,无论成功或失败都消耗

保护石生效后,装备保持强化前等级,但连续失败次数仍增加一次。

失败结算

未使用保护石且强化失败时,插件按照目标等级规则中的 failure-results 权重随机选择结果。

配置结果实际处理
0装备等级不变
负整数根据数值降低对应等级,最低降至 0
break装备被破坏,结果装备为 null

如果降级后的装备重绘失败,API 会保留可用装备,并写入本次连续失败次数。此时结果仍属于已处理的有效强化。

StrengthenAttemptResult

完整强化返回 StrengthenAttemptResult

方法返回值说明
isSuccess()boolean本次强化是否成功
isProcessed()boolean是否已经进入有效强化并完成消耗
isBroken()boolean装备是否在失败结算中被破坏
getMessage()String简体中文结果或失败原因
getEquipment()ItemStack操作后的装备;装备被破坏时为 null
getProtectionStone()ItemStack操作后剩余的保护石;全部消耗时为 null
getUniversalMaterial()ItemStack操作后剩余的通用材料;全部消耗时为 null
getResultLevel()int操作后的装备等级
getFinalChance()double本次强化最终成功率,按百分比表示
hasPendingScripts()boolean是否存在等待物品结算后执行的脚本
executePendingScripts()StrengthenAttemptResult执行待处理脚本并返回最终结果

successprocessed

isSuccess()isProcessed() 表示不同状态。

isSuccess()isProcessed()含义
truetrue已完成对应消耗,并且强化成功
falsetrue已进入有效强化并完成消耗,但概率判定失败
falsefalse在状态、物品、方案、公式、前置或消耗检查阶段失败,没有执行普通强化结算

不能使用 isSuccess() 判断是否已经产生消耗。判断本次是否进入有效强化时,必须使用 isProcessed()

isProcessed()false 时仍可能存在待执行脚本。例如金币、额外货币或材料不足时,可能命中方案中的 cost-insufficient 脚本。

返回物品

API 基于传入物品的副本执行安全处理,并通过结果对象返回结算后的物品。调用方需要分别写回装备、保护石和通用材料。

返回方法null 的可能含义
getEquipment()装备被破坏、原本没有装备,或结果中不存在可写回装备
getProtectionStone()未提供保护石,或保护石已全部消耗
getUniversalMaterial()未提供通用材料,或通用材料已全部消耗

无效操作会尽量返回未消耗的物品副本。不要只根据物品是否为 null 判断操作状态。

最终成功率

getFinalChance() 返回本次计算出的最终成功率,数值按百分比表示。例如返回 75.0 表示成功率为 75%

如果操作在成功率计算前失败,该值可能为 0。如果成功率已经计算,但后续保护石、材料或物品校验失败,结果中仍可能保留已经计算出的成功率。

结果等级

getResultLevel() 表示本次操作后的装备等级。

  • 强化成功时为目标等级。
  • 保护石生效时为强化前等级。
  • 等级不变时为强化前等级。
  • 降级时为降级后的等级。
  • 装备破坏时为 0
  • 在早期校验阶段失败时,通常为当前已识别等级或 0

强化脚本

完整强化可能命中普通强化方案中的 scripts。API 不会在返回强化结果前立即执行脚本,而是将脚本保留为待处理状态,使调用方可以先写回结算物品。

可能产生脚本的结果包括:

  • 强化成功。
  • 保护石生效。
  • 失败后等级不变。
  • 失败后装备降级。
  • 失败后装备破坏。
  • 金币、额外货币或普通材料不足。

脚本可能执行以下操作:

  • 添加装备 Lore。
  • 在指定 Lore 前插入内容。
  • 在指定 Lore 后插入内容。
  • 替换指定 Lore。
  • 删除指定 Lore。
  • 以控制台身份执行指令。
  • 临时以管理员身份执行指令。
  • 以玩家身份执行指令。

脚本条件可能使用本次强化前等级、目标等级、结算后等级、历史最高等级、连续失败次数、等级变化和 PlaceholderAPI 变量。

执行顺序

推荐按以下顺序处理:

  1. 调用 attemptStrengthen
  2. 读取并写回 getEquipment()getProtectionStone()getUniversalMaterial()
  3. 检查 hasPendingScripts()
  4. 在服务端主线程调用 executePendingScripts()
  5. 使用脚本执行结果中的 getEquipment() 再次更新装备。
java
// 初始结果:先完成强化概率、消耗和失败结算。
StrengthenAttemptResult result = api.attemptStrengthen(
    player,
    equipment,
    protectionStone,
    universalMaterial
);

// 结算装备:装备破坏时可能为 null。
ItemStack settledEquipment = result.getEquipment();
// 结算保护石:未提供或全部消耗时可能为 null。
ItemStack settledProtectionStone = result.getProtectionStone();
// 结算通用材料:未提供或全部消耗时可能为 null。
ItemStack settledUniversalMaterial = result.getUniversalMaterial();

// 由调用方先将三个结算结果写回实际背包、容器或界面槽位。

if (result.hasPendingScripts()) {
    // 脚本结果:同一批待处理脚本只会执行一次。
    StrengthenAttemptResult scriptedResult = result.executePendingScripts();
    // 最终装备:Lore 脚本可能返回新的装备对象。
    ItemStack finalEquipment = scriptedResult.getEquipment();

    // 由调用方再次写回脚本处理后的最终装备。
}

executePendingScripts() 必须在服务端主线程执行。同一个待处理结果重复调用时,不会重复执行同一批脚本,而是返回已经完成脚本处理的结果。

装备破坏时,脚本仍可能包含指令操作。Lore 操作接收到的装备为 null 时,应以结果对象最终返回值为准。

完整结果处理

以下代码只展示结果处理流程,不包含 API 实例获取方式和具体物品槽位来源:

java
// 强化结果:执行一次普通强化流程。
StrengthenAttemptResult result = api.attemptStrengthen(
    player,
    equipment,
    protectionStone,
    universalMaterial
);

// 结算装备:需要写回装备槽位,允许为 null。
ItemStack settledEquipment = result.getEquipment();
// 结算保护石:需要写回保护石槽位,允许为 null。
ItemStack settledProtectionStone = result.getProtectionStone();
// 结算通用材料:需要写回通用材料槽位,允许为 null。
ItemStack settledUniversalMaterial = result.getUniversalMaterial();

// 先将三个结算物品写回调用方管理的背包、容器或界面。

if (result.hasPendingScripts()) {
    // 脚本执行结果:包含脚本处理后的最终装备。
    result = result.executePendingScripts();
    // 脚本后装备:需要再次写回装备槽位。
    settledEquipment = result.getEquipment();
}

if (!result.isProcessed()) {
    player.sendMessage(result.getMessage());
    return;
}

if (result.isBroken()) {
    player.sendMessage("强化失败,装备已被破坏");
    return;
}

player.sendMessage(result.getMessage());

即使 isProcessed()false,也应先处理返回物品和待执行脚本,再向玩家展示失败信息。

接入注意事项

  • 不要在插件加载早期执行物品修改,应等待 LyGalaxyStrengthen 完成初始化。
  • 不要在异步线程执行强化、等级调整或待处理脚本。
  • 不要自行创建 API 实现类,应使用发布版本提供的公开入口。
  • 不要依赖非公开服务类、数据类、界面类或实现类。
  • 不要忽略结果对象返回的物品,传入对象不能视为最终结算结果。
  • 不要使用 isSuccess() 代替 isProcessed() 判断是否已经产生消耗。
  • 不要因为 isProcessed()false 就跳过 hasPendingScripts() 检查。
  • 装备被破坏时,getEquipment() 可以返回 null,写回前必须检查。
  • 完整强化会直接处理玩家金币、额外货币和材料,调用方不得重复扣除。
  • 使用通用材料时,插件会跳过本次普通材料和货币消耗,调用方不得再次结算。
  • 执行待处理脚本前,应先完成物品写回,避免脚本指令读取到旧装备状态。
  • Lore 脚本可能返回新的装备对象,脚本执行后必须再次写回最终装备。
  • getMessage() 返回简体中文结果说明,可用于玩家提示或日志记录。
  • 公开读取方法应优先用于判断装备状态,不要自行解析插件保存的隐藏 NBT 或 Lore 标记。