开发接口
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 实现类,也不要依赖非公开实现类型。
调用要求
| 要求 | 说明 |
|---|---|
| 修改线程 | upgrade、downgrade、attemptStrengthen 和 executePendingScripts 必须在服务端主线程调用 |
| 初始化状态 | 强化配置、强化方案、界面和 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);
}直接调整等级
upgrade 和 downgrade 用于不扣除金币、额外货币、普通材料、保护石和通用材料的等级调整。方法会根据装备绑定的强化方案重新计算强化数据并重绘 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
upgrade 与 downgrade 返回 StrengthenResult。
| 方法 | 返回值 | 说明 |
|---|---|---|
isSuccess() | boolean | 本次等级调整是否成功 |
getMessage() | String | 简体中文处理结果或失败原因 |
getItem() | ItemStack | 处理后的装备 |
调用方应始终接收 getItem() 返回的装备,不要假设传入的 ItemStack 已被原地修改。
常见失败情况包括:
- 强化系统尚未就绪。
- 在异步线程调用修改方法。
- 物品为空或没有有效强化数据。
- 装备绑定的强化方案已经失效。
- 目标等级不符合升级或降级方向。
- 目标等级超过方案上限。
- 强化方案缺少目标等级规则。
- 装备保存的基础 Lore 数据无法读取。
- Lore 模板或强化公式无法正常计算。
修改方法失败时会尽量在结果中返回传入装备的安全副本。仍应先检查 isSuccess(),再决定是否写回结果物品。
执行完整强化
java
StrengthenAttemptResult attemptStrengthen(
Player player,
ItemStack equipment,
ItemStack protectionStone,
ItemStack universalMaterial
)该方法按照普通强化界面的规则,执行一次从当前等级到下一级的强化。
完整流程包括:
- 检查强化系统状态与调用线程。
- 根据装备名称和已有强化数据识别唯一方案。
- 检查装备是否达到强化上限。
- 读取目标等级的强化规则。
- 计算基础成功率、权限加成和连续失败保底。
- 校验保护石与通用材料。
- 首次强化时提取并保存基础 Lore 数据。
- 预先验证目标等级装备能否正常重绘。
- 检查并扣除金币、额外货币和普通材料,或消耗通用材料。
- 按最终成功率判断强化结果。
- 处理保护石消耗。
- 处理成功、等级不变、降级或装备破坏。
- 更新当前等级、历史最高等级和连续失败次数。
- 返回结算物品以及可能存在的待执行脚本。
参数
| 参数 | 是否可空 | 说明 |
|---|---|---|
player | 否 | 承担费用、提供权限并作为脚本执行对象的玩家 |
equipment | 否 | 待强化装备 |
protectionStone | 是 | 本次使用的保护石;不使用时传入 null |
universalMaterial | 是 | 本次使用的通用强化材料;不使用时传入 null |
传入保护石或通用材料时,物品必须符合当前方案和目标等级规则。槽位中存在物品但规则不匹配时,本次操作会直接失败,不会消耗物品。
调用示例
java
// 强化结果:包含本次强化状态及三个结算物品。
StrengthenAttemptResult result = api.attemptStrengthen(
player,
equipment,
protectionStone,
universalMaterial
);方案识别
完整强化不需要传入方案 ID。插件使用与普通强化界面相同的规则自动识别方案。
| 装备状态 | 识别规则 |
|---|---|
| 未托管装备 | 装备名称需要匹配方案的 equipment-names |
| 首次强化 | 需要从装备实际拥有的 Lore 中提取方案引用模板所需的基础值 |
| 已托管装备 | 必须继续使用装备原先绑定的强化方案 |
| 多方案冲突 | 同时匹配多个方案时拒绝处理,避免绑定错误 |
| 方案失效 | 装备绑定的方案不存在时拒绝处理 |
| 名称变化 | 已托管装备名称不再符合绑定方案时拒绝处理 |
成功率计算
最终成功率依次应用以下内容:
- 目标等级规则中的基础
chance。 - 玩家拥有的最高一项
permission-chance。 - 装备当前连续失败次数对应的
failure-guarantee。 - 最终结果限制在
0至100之间。
权限加成按基础成功率乘算。玩家同时拥有多个配置权限时,只使用数值最高的一项。
失败保底使用 add 还是 multiply,由主配置中的 failure-guarantee-mode 决定。
消耗规则
未使用通用材料时,完整强化会按照目标等级规则检查并扣除以下内容:
| 消耗类型 | 配置来源 | 所需前置 |
|---|---|---|
| 金币 | need-money | Vault 和已注册的经济服务 |
| 点券 | need-currency.point | PlayerPoints |
| LyShop 货币 | need-currency.lyshop@货币ID | LyShopReload |
| CraftX 变量货币 | need-currency.cx@变量ID | CraftX |
| 普通材料 | 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 | 执行待处理脚本并返回最终结果 |
success 与 processed
isSuccess() 和 isProcessed() 表示不同状态。
isSuccess() | isProcessed() | 含义 |
|---|---|---|
true | true | 已完成对应消耗,并且强化成功 |
false | true | 已进入有效强化并完成消耗,但概率判定失败 |
false | false | 在状态、物品、方案、公式、前置或消耗检查阶段失败,没有执行普通强化结算 |
不能使用 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 变量。
执行顺序
推荐按以下顺序处理:
- 调用
attemptStrengthen。 - 读取并写回
getEquipment()、getProtectionStone()和getUniversalMaterial()。 - 检查
hasPendingScripts()。 - 在服务端主线程调用
executePendingScripts()。 - 使用脚本执行结果中的
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 标记。