Archived
根因: BurstDrive 对每把 SlashBlade 的服务器更新都会读取状态并调用通用特效查询;没有 BurstDrive 注册项的刀也会走到该路径,通用查询还会懒创建空的 SB.SEffect 复合标签。 改动: 在保留根 NBT 获取后,先检查 SB.SEffect 复合标签及 BurstDrive 键。未注册或空标签直接返回;已注册的键继续调用既有 isEffective、损坏状态、粒子和攻击代码。 契约: 已注册的 BurstDrive 仍由原有通用特效 API 决定有效性,包含零值、异常数值类型、玩家状态和后续攻击时序。未注册或空特效标签本来只能得到 None;现在不再为其调用通用查询,也不再写入语义为空的 SB.SEffect 子标签。 性能: 静态计数:未注册刀每个服务器更新从 1 次通用 isEffective/getSpecialEffect 查询及其潜在空子标签写入,降为 2 次 NBT 键存在性检查后返回。已注册刀路径不变。未进行实际服务器性能测量。 验证: 通过 tests/regression/burst_drive_effect_registration_regression.py,检查过滤顺序及空、已注册和异常数值键的分流;通过 ./gradlew --no-daemon compileJava reobfJar --console=plain 与 git diff --check。未在 Forge 多人运行时验证粒子与攻击体验。 Refs: #2
This commit is contained in:
1 parent
27199534f4
commit
7b31dd5ab8
2 files changed
+60
No files matched your search
@@ -46,6 +46,7 @@ import net.minecraft.world.World;
|
||||
public class BurstDrive
|
||||
implements ISpecialEffect {
|
||||
static final String EffectKey = "BurstDrive";
|
||||
private static final String SPECIAL_EFFECTS_TAG = "SB.SEffect";
|
||||
|
||||
private boolean useBlade(ItemSlashBlade.ComboSequence sequence) {
|
||||
if (sequence.useScabbard) {
|
||||
@@ -66,6 +67,13 @@ implements ISpecialEffect {
|
||||
EntityPlayer player = (EntityPlayer)event.entity;
|
||||
ItemStack blade = event.blade;
|
||||
NBTTagCompound tag = ItemSlashBlade.getItemTagCompound((ItemStack)blade);
|
||||
if (!tag.hasKey(SPECIAL_EFFECTS_TAG, 10)) {
|
||||
return;
|
||||
}
|
||||
NBTTagCompound specialEffects = tag.getCompoundTag(SPECIAL_EFFECTS_TAG);
|
||||
if (!specialEffects.hasKey(EffectKey)) {
|
||||
return;
|
||||
}
|
||||
if (ItemSlashBlade.IsBroken.get(tag).booleanValue()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Regression checks for BurstDrive's registration prefilter.
|
||||
|
||||
This is a source-level guard test: Forge 1.7.10 event dispatch is not available
|
||||
in the build environment. It protects the intended ordering and the two
|
||||
semantics that matter for the fast path: absent or empty effect data cannot
|
||||
activate BurstDrive, while registered data still reaches isEffective().
|
||||
"""
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
SOURCE = Path(__file__).parents[2] / (
|
||||
"src/main/java/mods/flammpfeil/slashblade/kirisaya/specialeffect/BurstDrive.java"
|
||||
)
|
||||
|
||||
|
||||
def registration_prefilter(effect_data):
|
||||
"""Mirror the new guard, where None denotes a missing/non-compound tag."""
|
||||
if effect_data is None:
|
||||
return False
|
||||
return "BurstDrive" in effect_data
|
||||
|
||||
|
||||
def main():
|
||||
source = SOURCE.read_text(encoding="utf-8")
|
||||
compound_guard = 'if (!tag.hasKey(SPECIAL_EFFECTS_TAG, 10))'
|
||||
effect_guard = 'if (!specialEffects.hasKey(EffectKey))'
|
||||
broken_read = 'if (ItemSlashBlade.IsBroken.get(tag).booleanValue())'
|
||||
effectiveness = 'switch (SpecialEffects.isEffective('
|
||||
|
||||
assert compound_guard in source
|
||||
assert effect_guard in source
|
||||
assert source.index(compound_guard) < source.index(broken_read)
|
||||
assert source.index(effect_guard) < source.index(effectiveness)
|
||||
|
||||
# Both cases historically resolve to SpecialEffects.Result.None; neither
|
||||
# may reach the broken-state, effect lookup, particles, or attack path.
|
||||
assert not registration_prefilter(None)
|
||||
assert not registration_prefilter({})
|
||||
|
||||
# A present key deliberately continues through the existing API, including
|
||||
# its handling of zero, malformed numeric data, and player/equipment state.
|
||||
assert registration_prefilter({"BurstDrive": 0})
|
||||
assert registration_prefilter({"BurstDrive": 1})
|
||||
assert registration_prefilter({"BurstDrive": "unexpected-type"})
|
||||
|
||||
print("burst-drive-registration-prefilter-regression-ok")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in new issue
Block a user