Mixins

備註

此页适用于 SpongeCommon、 SpongeForge 和 SpongeVanilla。这三个仓库利用 Mixin 挂钩到底层进行实现 (原版 Minecraft 服务器和 Forge 服)。

Mixins是一种在运行时修改Java代码的方式,它向类中添加额外的行为。这可以将我们需要的功能加入到原版的Minecraft中去。Mixins对于Sponge的运行来说是必须的。

Mixin Wiki 上对一些关于Mixin使用的核心概念进行了基本的介绍。

上面的Wiki相当基础,如果你是一位有经验的Java开发者,你可以跳过第4节,其中讨论了mixins本身。

如果您希望開始編寫 mixin,我們還強烈建議你仔細檢查 `SpongeCommon 儲存庫<https://github.com/SpongePowered/SpongeCommon/tree/stable-6/src/example/java/org/spongepowered>`__中被廣泛記錄並涵蓋許多更複雜情境的所有範例 。而且還要參考 Mixin 程式庫本身的 Javadoc,因為幾乎所有東西都已經記錄在上面。

警告:使用 Mixin 时请注意,不能在 Mixin 中使用任何匿名类或 lambda 表达式。

这意味着像后面的一些代码会搞坏mixin,同时也会把Sponge搞到万劫不复的境地。

return new Predicate<ItemStack>() {
    @Override
    public boolean test(ItemStack input) {
        return input.getItem().equals(Items.golden_apple);
    }
}
return input -> input.getItem().equals(Items.golden_apple);
return this::checkItem;

这适用于所有带 @Mixin 注解的类。不被 Mixin 处理器访问的类可以使用这些功能。然而,你可以在一个静态的实用程序类中创建匿名类;如此一来,实用程序类在运行时中仍然存在,而 Mixin 类将合并到指定的目标类中。因此,下面的代码可以工作。

public class ItemUtil {
    public static Predicate<ItemStack> typeChecker(final Item item) {
        return new Predicate<ItemStack>() {
            @Override
            public boolean test(ItemStack input) {
                return input.getItem().equals(item);
            }
        }
    }
}

@Mixin(TargetClass.class)
public abstract class SomeMixin {
    public Predicate<ItemStack> someFunction() {
        return ItemUtil.typeChecker(Items.golden_apple);
    }
}

備註

不仅是 Sponge,还有很多项目也在使用 Mixin。所以 Mixin 有其自己的文档。