Fallen Lib 是一个小型的开发工具库。 它目前用于 Fallen Gems & Affixes 的开发过程中.
Fallen Lib 是一个小型的开发工具库。 它目前用于 Fallen Gems & Affixes 的开发过程中 . 该模组提供了一些与 ASM 相关的 API 以及用于模组开发的运行时实用工具。 它不会添加任何游戏内容,也不面向普通玩家。 开发环境 Gradle repositories { maven { url " https://rtxyd.github.io/maven-repo " } } dependencies { implementation fg.deobf("io.github.rtxyd:fallen-lib:1.4.6:core") implementation fg.deobf("io.github.rtxyd:fallen-lib:1.4.6:runtime") } 或者你可以在“附加文件”部分下载它们。 对于普通游戏或分发,请使用普通的 JAR 文件。 功能特性 FallenPatch 一个用于修补模组类的委托 API。 它可以挂钩特定的类或所有子类, 这有助于在扩展模组行为时减少重复的修补代码。 要使用此 API,你必须实现 `IFallenPatch` 接口,然后该类必须具有带有正确参数的 `@FallenPatch` 注解。 例如: @FallenPatch( priority = 1000, targets = @Targets( exact = {SomeClass.class}, subclass = {SuperClass.class}), inserters = {FallenInserters.class}) public class FallenPatch implements IFallenPatch { private final IPatchDescriptor desc; // Here you must provide a constructor like this. public FallenPatch(IFallenPatchCtorContext iFallenPatchCtorContext) { desc = iFallenPatchCtorContext.currentPatch(); } @Override public void apply(ClassNode cn, IFallenPatchContext iFallenPatchContext) { MethodInsnNode hook = iFallenPatchContext.getFallenInserter( InserterKey.of("xxx.xxx.FallenInserters", "hook", InserterType.STANDARD_VOID)); for (MethodNode method : cn.methods) { InsnList insns = method.instructions; if (insns == null) continue; PatchUtil.insertMethodHook(cn, method, m -> m instanceof MethodInsnNode mn && mn.owner.equals("xxx.xxx.ClassName") && mn.name.equals("methodName") && mn.desc.startsWith("(Ljava/lang/Object;") && Type.getReturnType(mn.desc).getSort() != Type.VOID, InserterType.STANDARD_VOID, hook, false, false); } } } `inserters` 针对的是至少有一个方法带有 `@FallenInserter` 注解的类。 例如 `FallenInserters.class`: public class FallenInserters { @FallenInserter(type = InserterType.STANDARD_VOID) public static void hook(IInserterContext<Object, Object> ctx, Object... args) { Object rec = ctx.receiver(); } } 然后在你的资源根目录下应该有一个 xxx.fallen.json 文件。 格式如下: { "required": true, "min_version": "1.2.0", "package": "xxx.package.name", "fallen_patches": [ "FallenPatch", "PatchClassName" ] } 目前,FallenPatch 仅支持修补模组类。 未来可能会增加更多支持。 FallenInserter 与 FallenPatch 配合使用,在具有正确参数类型和返回类型的方法上使用 `@FallenInserter`, 现在有两种类型的 InserterType : ` InserterType.STANDARD` ` InserterType.STANDARD_VOID` 默认是 standard,格式应如下所示: @FallenInserter(type = InserterType.STANDARD) public static Object hook(IInserterContext<Object, Object> ctx, Object... args) { return ctx.ret(); } @FallenInserter(type = InserterType.STANDARD_VOID) public static void hook(IInserterContext<Object, Object> ctx, Object... args) { } ` ctx` 包含 ctx.receiver()` 和 ctx.ret()` 方法,分别提供你插入方法的 ` this(可能为 null)` 和返回值对象;如果该方法有返回值且方法中的 `replaceReturn` 标志为 `true`,则返回值将替换原始方法的返回值,你可以尝试以下工具 ObjectModifierFactory` 来修改此对象的数值字段并返回。 ` args` 是一个 Object[]` ,包含你所插入方法的所有参数。`InserterType.STANDARD` 在方法执行后调用,因此它们只是视图,不要修改它们。 如果你正确配置并实现了带有正确注解的 IFallenPatch 接口,那么你可以 MehtodInsnNode hookMethod = iFallenPatchContext.getFallenInserter( InserterKey.of("your.class.name", "methodName", InserterType)); 获取你的 hookMethod(如果它们具有正确的参数类型和返回类型,它们将由 fallen lib 构建) 然后使用 PatchUtil.insertMethodHook() 以简化修补过程(虽然不如 mixin 那样容易)。 RuntimeUtility 一些运行时实用工具。 ` ObjectModifierFactory` : 复制一个对象 修改数值字段 使用缓存和字段名称过滤器 例如: public class FallenInserters { // this needs a Predicate<String> private static final ObjectModifierFactory FACTORY = new ObjectModifierFactory(s -> { String filedName = s.toLowerCase(); if (name.contains("xxx")) return true; return false;}); @FallenInserter(type = InserterType.STANDARD) public static Object hook(IInserterContext<Object, Object> ctx, Object... args) { Object ret = ctx.ret() return FACTORY.doSomething(ret); } } 这主要用于在不修改原始对象的情况下进行运行时调整。 `Delegated Mixin Connector Registry` :(高于版本 1.3.2) 一个类似注册表的服务,通过在你的模组中实现官方的 IMixinConnector 接口,你可以实现在 IDEA 中通过条件加载 mixins 配置文件进行测试。 用法如下,目标是一个实现 IMixinConnector 的类,然后在 resources root 中使用以下格式配置 json { "required": true, "min_version": "…
在鱼乐云资源中心浏览该资源,登录后可一键安装到你的游戏服务器。