跳到正文

Flight API

一个简单、零依赖的 API,用于控制飞行并检测会破坏飞行功能的模组。

收藏

介绍

介绍由机器翻译自 CurseForge 原页面,仅供参考。

Flight API


一个用于控制飞行,以及检测会破坏飞行功能的模组的简单零依赖 API。

Flight API 是适用于 Minecraft(Fabric/NeoForge)的前置库,用于解决多个模组争夺玩家飞行控制权而产生的冲突。借助 Flight API,可以避免玩家突然掉到地面或完全无法飞行的情况,因为多个模组可能会反复开关 player.getAbilities().flying 和 player.getAbilities().allowFlying。

当前功能

  • 基于队列的飞行控制系统,通过拦截玩家能力中的 allowFlying 和 flying 回调,帮助模组更好地管理原版飞行系统。
  • 提供易于理解的日志,帮助玩家找出与飞行相关的模组问题,轻松检测并自动解决冲突。此系统最初是为调试创意模式或旁观模式飞行异常,以及排查模组兼容性问题而设计的;也能帮助你在大型整合包中找出有问题的模组。

面向玩家

将 .jar 文件放入 mods 文件夹即可使用!如果遇到与飞行相关的问题,可以将日志文件夹中的 debug.log 提供给模组作者,Flight API 能帮助识别有问题的模组,从而协助作者调查问题。

面向开发者

核心概念

在原版 Minecraft(以及许多模组)中,飞行逻辑代码可能如下所示:

player.getAbilities().flying = true;
player.getAbilities().allowFlying = true;

如果两个或更多模组未协调地执行这些操作,玩家的飞行状态可能会快速反复切换。

Flight API 通过以下机制避免此问题:

  • 任何时候都只有一个模组(一个“所有者”)可以控制玩家的飞行。其他所有飞行请求都会进入队列。当前所有者释放飞行控制权后,队列中的下一个请求将生效,让玩家能够按预期继续飞行或停止飞行。

  • 未经授权直接修改 flying 或 allowFlying 的操作,会被 mixin 拦截或阻止。

  • 建议并强烈鼓励模组开发者调用:

    FlightAPI.requestFlight(String modId, ServerPlayerEntity player);
    // ...
    FlightAPI.releaseFlight(String modId, ServerPlayerEntity player);

    而不是直接访问 player.getAbilities().flying。这个统一的控制入口可确保同一时间只有一个模组控制飞行。

依赖配置(Fabric/NeoForge)

你需要在 build.gradle 中声明 Flight API 的 Maven 仓库(也可以使用 CurseMaven),并使用 modImplementation 依赖处理器将该前置库加载到开发环境中。

目前官方 Maven 仓库尚不可用,因此暂时可以使用 CurseMaven 将该前置库加载到开发环境中。抱歉带来不便。

你也可以将此 API 以 jar-in-jar 的方式打包到模组中,以便用户更轻松地安装模组,无需额外处理 Flight API。不过,你也可以像依赖其他模组一样直接依赖它。

使用方法

请求飞行权限

当你希望允许玩家飞行时(例如,按下“开启喷气背包”按钮、施放悬浮法术等),不要调用 player.abilities.flying = true。

请改为调用 requestFlight(String modId, ServerPlayerEntity player) 方法:

    boolean gotControl = FlightAPI.requestFlight(modId, player);
    if (gotControl) {
        // 你已立即成为飞行控制者。
        // 在底层,FlightManager 会将玩家的 allowFlying/flying 设为 true。
        // 玩家现在可以飞行(除非处于创造模式、旁观模式等)。
    } else {
        // 另一个模组已经在控制该玩家的飞行。
        // 你的请求会进入队列。当前控制者释放飞行后,
        // 你将自动获得控制权。你可以在此处理这种情况。
    }

注意: modId 是用于标识你的模组的唯一字符串(例如 “mymod”)。

释放飞行控制权

当你的模组不再需要控制飞行时(例如玩家关闭喷气背包、法术结束等),应调用 releaseFlight(String modId, ServerPlayerEntity player) 方法。

FlightAPI.releaseFlight("MyAwesomeMod", player);

如果队列中没有其他等待的模组,玩家将无法继续飞行。如果队列中还有其他模组,该模组会立即接管控制权。玩家可以继续由新的控制者控制飞行(也可能会被强制降落,具体取决于新模组的逻辑)。

检查当前控制者

你可以检查当前由哪个模组控制飞行:

    Optional<String> currentOwner = FlightAPI.getCurrentOwner(player);

    if (currentOwner.isPresent()) {
        System.out.println("当前飞行控制者为:" + currentOwner.get());
    } else {
        System.out.println("当前没有飞行控制者");
    }

示例场景

“喷气背包”和“悬浮术”模组

JetpackMod 会在玩家穿戴喷气背包物品时授予飞行能力。

MagicSpellMod 会在玩家施放悬浮术时授予飞行能力。

如果没有 Flight API,两个模组都可能不断切换 flying = true/false,导致玩家上下抖动;如果两个 MCreator 模组都试图以同样方式实现飞行,就可能发生这种情况。

使用 Flight API 时,JetpackMod 会调用 FlightAPI.requestFlight("JetpackMod", player)。MagicSpellMod 会调用 FlightAPI.requestFlight("MagicSpellMod", player),但此时飞行控制权已由 JetpackMod 持有,因此 MagicSpellMod 会进入队列。当 JetpackMod 的燃料耗尽并调用 FlightApi.releaseFlight("JetpackMod", player) 时,控制权会立即转交给 MagicSpellMod。玩家不会突然失去飞行能力;当然,只要满足施放法术飞行的条件,法术就会继续维持飞行。

“有问题的”模组破坏了我的飞行!我该怎么办?

假设某个“BuggyMod”每个游戏刻都会强制执行 player.getAbilities().flying = false;。得益于拦截这项直接赋值的 mixin,Flight API 会检查:“BuggyMod 是当前控制者吗?不是。”

这项赋值会被拦截,玩家也不会坠落。

你的整合包中的 debug.log 可能会反复显示:

[MixinPlayerAbilities] Flight owned by JetpackMod, ignoring NBT flying=false

这有助于你发现问题并向模组作者报告。

优先级逻辑

默认情况下,FlightManager 会按 FIFO(先进先出)处理请求。最先发出请求的模组会成为控制者。

许可证

Flight API 采用 CC0-1.0 许可证。你可以随意使用。

常见问题

Flight API 支持哪些 Minecraft 版本?

Flight API 支持 Minecraft Java 版 1.21–1.21.1,共 2 个版本,可用的加载器:Fabric / NeoForge / Quilt。下载时注意选择和你游戏版本一致的文件。

Flight API 怎么安装?

先用 PCL2 或 HMCL 启动器安装对应版本的 Fabric / NeoForge / Quilt,再把下载的 .jar 文件放进游戏目录的 mods 文件夹,重新启动游戏即可。开启了版本隔离的,mods 文件夹在 versions/版本名 下面。

评论

登录后评论和评分

DenisMasterHerobrine 的其他作品

查看全部 →