环境配置

路线1

在build.gradle加上:

repositories {
    maven {
        url "https://maven.cleanroommc.com"
    }
}
 
dependencies {
    deobfCompile ("zone.rong:mixinbooter:8.3")
}

其中deobfCompile ("zone.rong:mixinbooter:8.3")中8.3为mixinbooter版本号,可自行修改。

开发者的IDE通常会自动完成。如果没有,可以gradlew.bat setupDecompWorkspace idea genIntellijRuns手动完成。

路线2

下载一份MixinBooter,文件>项目结构>模块>依赖 添加这个jar文件。

build.gradle加入:

dependencies {
    compile files('文件路径')//单引号
}

MixinGradle

MixinGradle is a Gradle plugin which simplifies the build-time complexity of working with the SpongePowered Mixin framework for Java. It currently only supports usage with ForgeGradle.

将这部分内容合并到你的build.gradle

buildscript {
    repositories {
        maven { url = "https://repo.spongepowered.org/maven" }
    }
    dependencies {
        classpath 'org.spongepowered:mixingradle:0.6-SNAPSHOT'//1.12.2适用于0.6-SNAPSHOT
    }
}
apply plugin: 'org.spongepowered.mixin'
mixin {
    add sourceSets.main, "mixins.modid.refmap.json"
    //生成一个refmap json,上方是文件名称的推荐格式
}

然后重新构建环境,例如:

setupDecompWorkspace
genIntellijRuns

refmap

refmap记载了你需要使用的部分反混淆表。

使用MixinGradle可以自动生成所需refmap。

例如:

@Inject(method = "getMetaFromState"

{
  "mappings": {
    "com/example/mixin/MixinBlock": {
      "getMetaFromState": "Lnet/minecraft/block/BlockChest;func_176201_c(Lnet/minecraft/block/state/IBlockState;)I"
    }
  },
  "data": {
    "notch": {
      "com/example/mixin/MixinBlock": {
        "getMetaFromState": "Lapi;e(Lawt;)I"
      }
    },
    "searge": {
      "com/example/mixin/MixinBlock": {
        "getMetaFromState": "Lnet/minecraft/block/BlockChest;func_176201_c(Lnet/minecraft/block/state/IBlockState;)I"
      }
    }
  }
}

ILateMixinLoader

ILateMixinLoader用于第三方代码的Mixin,例如普通模组。

Constructing mods阶段前(此阶段是Forge将mod文件添加到ModClassLoader的位置),MixinBooter会寻找所有实现了ILateMixinLoader的类,并调用无参构造函数构造ILateMixinLoader对象。

public List getMixinConfigs()

这个方法必须实现,不能返回null,它代表了resources下的文件名称的集合。例如return Collections.singletonList("mixin.simple.mixin.json");表示了"mixin.simple.mixin.json"这个文件。

public boolean shouldMixinConfigQueue(String mixinConfig)

这个方法不必须实现。getMixinConfigs()返回的String会被依次传输到这里调用,返回true则代表它需要被添加,否则返回false。该方法默认返回true。若返回false,这个配置不会传递到Mixin。

public void onMixinConfigQueued(String mixinConfig)

这个方法不必须实现。配置传递到Mixin后调用。

IEarlyMixinLoader

IEarlyMixinLoader用于forge,minecraft等很早就传递到ClassLoader的代码。

为了把握这个“早”时机,MixinBooter需要在CoreMod正在运作的时机完成Mixin。MixinBooter利用了CoreMod机制获取EarlyMixin。

因此,一个IEarlyMixinLoader也应该同时是一个IFMLLoadingPlugin,即

public class MixinLoader implements IEarlyMixinLoader, IFMLLoadingPlugin

若不需要进行CoreMod操作,对IFMLLoadingPlugin的方法,void留空,数组返回String[0],其余返回null即可。IEarlyMixinLoader各接口同ILateMixinLoader。

CoreMod

CoreMod需要告诉FML自己是CoreMod。通常在META-INF/MANIFEST.MF中。

在build.gradle中编辑使打包时向MANIFEST.MF写入数据。

jar {
    manifest {
        attributes([
                        "FMLCorePlugin": "com.example.ExamplePlugin",
                        "FMLCorePluginContainsFMLMod": true
        ])
    }
}

FMLCorePlugin属性是IFMLLoadingPlugin实现类的完整类名

FMLCorePluginContainsFMLMod属性标记CoreMod的jar中是否还含有普通的Mod,如果为false,FML不会尝试寻找@Mod注解并加载普通Mod

jar是会在build等task打包时才会被执行,在runClient之类的测试运行时并不会被读取到,如果需要在测试运行时使用CoreMod,还需要在build.gradle中加入jvm参数的设置:

minecraft {
    clientJvmArgs += "-Dfml.coreMods.load=com.example.ExamplePlugin"
    serverJvmArgs += "-Dfml.coreMods.load=com.example.ExamplePlugin"}

但是实际上,这个参数可能会被忽略。

[main/INFO] [STDOUT]: [net.minecraft.client.main.Main:main:59]: Completely ignored arguments: [-Dfml.coreMods.load, com.example.ExamplePlugin]

因此,可以在resources下手动建立META-INF/MANIFEST.MF写入数据。