Skip to content

基础环境

  1. AZUL 8u382
  2. Forge 14.23.5.2847
  3. RetroFuturaGradle 1.3.16
  4. MCP 1.12.2-stable39

开发配置

打开DEBUG日志

默认日志配置文件路径为:

  1. build/resources/patchedMc/log4j2.xml
  2. build/resources/patchedMc/log4j2_server.xml

内容如下:

log4j2.xml
xml
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" packages="net.minecraftforge.server.terminalconsole.util">
    <Appenders>
        <Console name="SysOut" target="SYSTEM_OUT">
            <PatternLayout>
                <LoggerNamePatternSelector defaultPattern="[%d{HH:mm:ss}] [%t/%level] [%logger]: %msg%n">
                    <!-- don't include the full logger name for Mojang's logs since they use full class names and it's very verbose -->
                    <PatternMatch key="net.minecraft." pattern="[%d{HH:mm:ss}] [%t/%level] [minecraft/%logger{1}]: %msg%n"/>
                    <PatternMatch key="com.mojang." pattern="[%d{HH:mm:ss}] [%t/%level] [mojang/%logger{1}]: %msg%n"/>
                </LoggerNamePatternSelector>
            </PatternLayout>
        </Console>
        <Queue name="ServerGuiConsole" ignoreExceptions="true">
            <PatternLayout>
                <LoggerNamePatternSelector defaultPattern="[%d{HH:mm:ss}] [%t/%level] [%logger]: %msg%n">
                    <!-- don't include the full logger name for Mojang's logs since they use full class names and it's very verbose -->
                    <PatternMatch key="net.minecraft." pattern="[%d{HH:mm:ss}] [%t/%level] [minecraft/%logger{1}]: %msg%n"/>
                    <PatternMatch key="com.mojang." pattern="[%d{HH:mm:ss}] [%t/%level] [mojang/%logger{1}]: %msg%n"/>
                </LoggerNamePatternSelector>
            </PatternLayout>
        </Queue>
        <RollingRandomAccessFile name="File" fileName="logs/latest.log" filePattern="logs/%d{yyyy-MM-dd}-%i.log.gz">
            <PatternLayout pattern="[%d{HH:mm:ss}] [%t/%level] [%logger]: %msg%n"/>
            <Policies>
                <TimeBasedTriggeringPolicy/>
                <OnStartupTriggeringPolicy/>
            </Policies>
        </RollingRandomAccessFile>
        <RollingRandomAccessFile name="DebugFile" fileName="logs/debug.log" filePattern="logs/debug-%i.log.gz">
            <PatternLayout pattern="[%d{HH:mm:ss}] [%t/%level] [%logger]: %msg%n"/>
            <Policies>
                <OnStartupTriggeringPolicy/>
                <SizeBasedTriggeringPolicy size="200MB"/>
            </Policies>
            <DefaultRolloverStrategy max="5" fileIndex="min"/>
        </RollingRandomAccessFile>
    </Appenders>
    <Loggers>
        <!-- make sure mojang's logging is set to 'info' so that their LOGGER.isDebugEnabled() behavior isn't active -->
        <Logger level="${sys:forge.logging.mojang.level:-info}" name="com.mojang"/>
        <Logger level="${sys:forge.logging.mojang.level:-info}" name="net.minecraft"/>
        <Root level="all">
            <filters>
                <MarkerFilter marker="NETWORK_PACKETS" onMatch="DENY" onMismatch="NEUTRAL"/>
            </filters>
            <AppenderRef ref="SysOut" level="${sys:forge.logging.console.level:-info}"/>
            <AppenderRef ref="ServerGuiConsole" level="${sys:forge.logging.console.level:-info}"/>
            <AppenderRef ref="File" level="${sys:forge.logging.file.level:-info}"/>
            <AppenderRef ref="DebugFile" level="${sys:forge.logging.debugFile.level:-trace}"/>
        </Root>
    </Loggers>
</Configuration>
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" packages="net.minecraftforge.server.terminalconsole.util">
    <Appenders>
        <Console name="SysOut" target="SYSTEM_OUT">
            <PatternLayout>
                <LoggerNamePatternSelector defaultPattern="[%d{HH:mm:ss}] [%t/%level] [%logger]: %msg%n">
                    <!-- don't include the full logger name for Mojang's logs since they use full class names and it's very verbose -->
                    <PatternMatch key="net.minecraft." pattern="[%d{HH:mm:ss}] [%t/%level] [minecraft/%logger{1}]: %msg%n"/>
                    <PatternMatch key="com.mojang." pattern="[%d{HH:mm:ss}] [%t/%level] [mojang/%logger{1}]: %msg%n"/>
                </LoggerNamePatternSelector>
            </PatternLayout>
        </Console>
        <Queue name="ServerGuiConsole" ignoreExceptions="true">
            <PatternLayout>
                <LoggerNamePatternSelector defaultPattern="[%d{HH:mm:ss}] [%t/%level] [%logger]: %msg%n">
                    <!-- don't include the full logger name for Mojang's logs since they use full class names and it's very verbose -->
                    <PatternMatch key="net.minecraft." pattern="[%d{HH:mm:ss}] [%t/%level] [minecraft/%logger{1}]: %msg%n"/>
                    <PatternMatch key="com.mojang." pattern="[%d{HH:mm:ss}] [%t/%level] [mojang/%logger{1}]: %msg%n"/>
                </LoggerNamePatternSelector>
            </PatternLayout>
        </Queue>
        <RollingRandomAccessFile name="File" fileName="logs/latest.log" filePattern="logs/%d{yyyy-MM-dd}-%i.log.gz">
            <PatternLayout pattern="[%d{HH:mm:ss}] [%t/%level] [%logger]: %msg%n"/>
            <Policies>
                <TimeBasedTriggeringPolicy/>
                <OnStartupTriggeringPolicy/>
            </Policies>
        </RollingRandomAccessFile>
        <RollingRandomAccessFile name="DebugFile" fileName="logs/debug.log" filePattern="logs/debug-%i.log.gz">
            <PatternLayout pattern="[%d{HH:mm:ss}] [%t/%level] [%logger]: %msg%n"/>
            <Policies>
                <OnStartupTriggeringPolicy/>
                <SizeBasedTriggeringPolicy size="200MB"/>
            </Policies>
            <DefaultRolloverStrategy max="5" fileIndex="min"/>
        </RollingRandomAccessFile>
    </Appenders>
    <Loggers>
        <!-- make sure mojang's logging is set to 'info' so that their LOGGER.isDebugEnabled() behavior isn't active -->
        <Logger level="${sys:forge.logging.mojang.level:-info}" name="com.mojang"/>
        <Logger level="${sys:forge.logging.mojang.level:-info}" name="net.minecraft"/>
        <Root level="all">
            <filters>
                <MarkerFilter marker="NETWORK_PACKETS" onMatch="DENY" onMismatch="NEUTRAL"/>
            </filters>
            <AppenderRef ref="SysOut" level="${sys:forge.logging.console.level:-info}"/>
            <AppenderRef ref="ServerGuiConsole" level="${sys:forge.logging.console.level:-info}"/>
            <AppenderRef ref="File" level="${sys:forge.logging.file.level:-info}"/>
            <AppenderRef ref="DebugFile" level="${sys:forge.logging.debugFile.level:-trace}"/>
        </Root>
    </Loggers>
</Configuration>
log4j2_server.xml
xml
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" packages="net.minecraftforge.server.terminalconsole,com.mojang.util">
    <Appenders>
        <TerminalConsole name="Console">
            <PatternLayout>
                <LoggerNamePatternSelector defaultPattern="%highlightError{[%d{HH:mm:ss}] [%t/%level] [%logger]: %minecraftFormatting{%msg}%n%xEx}">
                    <!-- don't include the full logger name for Mojang's logs since they use full class names and it's very verbose -->
                    <PatternMatch key="net.minecraft." pattern="%highlightError{[%d{HH:mm:ss}] [%t/%level] [minecraft/%logger{1}]: %minecraftFormatting{%msg}%n%xEx}"/>
                    <PatternMatch key="com.mojang." pattern="%highlightError{[%d{HH:mm:ss}] [%t/%level] [mojang/%logger{1}]: %minecraftFormatting{%msg}%n%xEx}"/>
                </LoggerNamePatternSelector>
            </PatternLayout>
        </TerminalConsole>
        <Queue name="ServerGuiConsole" ignoreExceptions="true">
            <PatternLayout>
                <LoggerNamePatternSelector defaultPattern="[%d{HH:mm:ss}] [%t/%level] [%logger]: %minecraftFormatting{%msg}{strip}%n">
                    <!-- don't include the full logger name for Mojang's logs since they use full class names and it's very verbose -->
                    <PatternMatch key="net.minecraft." pattern="[%d{HH:mm:ss}] [%t/%level] [minecraft/%logger{1}]: %minecraftFormatting{%msg}{strip}%n"/>
                    <PatternMatch key="com.mojang." pattern="[%d{HH:mm:ss}] [%t/%level] [mojang/%logger{1}]: %minecraftFormatting{%msg}{strip}%n"/>
                </LoggerNamePatternSelector>
            </PatternLayout>
        </Queue>
        <RollingRandomAccessFile name="File" fileName="logs/latest.log" filePattern="logs/%d{yyyy-MM-dd}-%i.log.gz">
            <PatternLayout pattern="[%d{HH:mm:ss}] [%t/%level] [%logger]: %minecraftFormatting{%msg}{strip}%n"/>
            <Policies>
                <TimeBasedTriggeringPolicy/>
                <OnStartupTriggeringPolicy/>
            </Policies>
        </RollingRandomAccessFile>
        <RollingRandomAccessFile name="DebugFile" fileName="logs/debug.log" filePattern="logs/debug-%i.log.gz">
            <PatternLayout pattern="[%d{HH:mm:ss}] [%t/%level] [%logger]: %minecraftFormatting{%msg}{strip}%n"/>
            <Policies>
                <OnStartupTriggeringPolicy/>
                <SizeBasedTriggeringPolicy size="200MB"/>
            </Policies>
            <DefaultRolloverStrategy max="5" fileIndex="min"/>
        </RollingRandomAccessFile>
    </Appenders>
    <Loggers>
        <!-- make sure mojang's logging is set to 'info' so that their LOGGER.isDebugEnabled() behavior isn't active -->
        <Logger level="${sys:forge.logging.mojang.level:-info}" name="com.mojang"/>
        <Logger level="${sys:forge.logging.mojang.level:-info}" name="net.minecraft"/>
        <Root level="all">
            <filters>
                <MarkerFilter marker="NETWORK_PACKETS" onMatch="DENY" onMismatch="NEUTRAL"/>
            </filters>
            <AppenderRef ref="Console" level="${sys:forge.logging.console.level:-info}"/>
            <AppenderRef ref="ServerGuiConsole" level="${sys:forge.logging.console.level:-info}"/>
            <AppenderRef ref="File" level="${sys:forge.logging.file.level:-info}"/>
            <AppenderRef ref="DebugFile" level="${sys:forge.logging.debugFile.level:-trace}"/>
        </Root>
    </Loggers>
</Configuration>
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" packages="net.minecraftforge.server.terminalconsole,com.mojang.util">
    <Appenders>
        <TerminalConsole name="Console">
            <PatternLayout>
                <LoggerNamePatternSelector defaultPattern="%highlightError{[%d{HH:mm:ss}] [%t/%level] [%logger]: %minecraftFormatting{%msg}%n%xEx}">
                    <!-- don't include the full logger name for Mojang's logs since they use full class names and it's very verbose -->
                    <PatternMatch key="net.minecraft." pattern="%highlightError{[%d{HH:mm:ss}] [%t/%level] [minecraft/%logger{1}]: %minecraftFormatting{%msg}%n%xEx}"/>
                    <PatternMatch key="com.mojang." pattern="%highlightError{[%d{HH:mm:ss}] [%t/%level] [mojang/%logger{1}]: %minecraftFormatting{%msg}%n%xEx}"/>
                </LoggerNamePatternSelector>
            </PatternLayout>
        </TerminalConsole>
        <Queue name="ServerGuiConsole" ignoreExceptions="true">
            <PatternLayout>
                <LoggerNamePatternSelector defaultPattern="[%d{HH:mm:ss}] [%t/%level] [%logger]: %minecraftFormatting{%msg}{strip}%n">
                    <!-- don't include the full logger name for Mojang's logs since they use full class names and it's very verbose -->
                    <PatternMatch key="net.minecraft." pattern="[%d{HH:mm:ss}] [%t/%level] [minecraft/%logger{1}]: %minecraftFormatting{%msg}{strip}%n"/>
                    <PatternMatch key="com.mojang." pattern="[%d{HH:mm:ss}] [%t/%level] [mojang/%logger{1}]: %minecraftFormatting{%msg}{strip}%n"/>
                </LoggerNamePatternSelector>
            </PatternLayout>
        </Queue>
        <RollingRandomAccessFile name="File" fileName="logs/latest.log" filePattern="logs/%d{yyyy-MM-dd}-%i.log.gz">
            <PatternLayout pattern="[%d{HH:mm:ss}] [%t/%level] [%logger]: %minecraftFormatting{%msg}{strip}%n"/>
            <Policies>
                <TimeBasedTriggeringPolicy/>
                <OnStartupTriggeringPolicy/>
            </Policies>
        </RollingRandomAccessFile>
        <RollingRandomAccessFile name="DebugFile" fileName="logs/debug.log" filePattern="logs/debug-%i.log.gz">
            <PatternLayout pattern="[%d{HH:mm:ss}] [%t/%level] [%logger]: %minecraftFormatting{%msg}{strip}%n"/>
            <Policies>
                <OnStartupTriggeringPolicy/>
                <SizeBasedTriggeringPolicy size="200MB"/>
            </Policies>
            <DefaultRolloverStrategy max="5" fileIndex="min"/>
        </RollingRandomAccessFile>
    </Appenders>
    <Loggers>
        <!-- make sure mojang's logging is set to 'info' so that their LOGGER.isDebugEnabled() behavior isn't active -->
        <Logger level="${sys:forge.logging.mojang.level:-info}" name="com.mojang"/>
        <Logger level="${sys:forge.logging.mojang.level:-info}" name="net.minecraft"/>
        <Root level="all">
            <filters>
                <MarkerFilter marker="NETWORK_PACKETS" onMatch="DENY" onMismatch="NEUTRAL"/>
            </filters>
            <AppenderRef ref="Console" level="${sys:forge.logging.console.level:-info}"/>
            <AppenderRef ref="ServerGuiConsole" level="${sys:forge.logging.console.level:-info}"/>
            <AppenderRef ref="File" level="${sys:forge.logging.file.level:-info}"/>
            <AppenderRef ref="DebugFile" level="${sys:forge.logging.debugFile.level:-trace}"/>
        </Root>
    </Loggers>
</Configuration>

着重关注Loggers标签下的内容:

xml
    <Loggers>
        <!-- make sure mojang's logging is set to 'info' so that their LOGGER.isDebugEnabled() behavior isn't active -->
        <Logger level="${sys:forge.logging.mojang.level:-info}" name="com.mojang"/>
        <Logger level="${sys:forge.logging.mojang.level:-info}" name="net.minecraft"/>
        <Root level="all">
            <filters>
                <MarkerFilter marker="NETWORK_PACKETS" onMatch="DENY" onMismatch="NEUTRAL"/>
            </filters>
            <AppenderRef ref="Console" level="${sys:forge.logging.console.level:-info}"/> 
            <AppenderRef ref="ServerGuiConsole" level="${sys:forge.logging.console.level:-info}"/>
            <AppenderRef ref="File" level="${sys:forge.logging.file.level:-info}"/>
            <AppenderRef ref="DebugFile" level="${sys:forge.logging.debugFile.level:-trace}"/>
        </Root>
    </Loggers>
    <Loggers>
        <!-- make sure mojang's logging is set to 'info' so that their LOGGER.isDebugEnabled() behavior isn't active -->
        <Logger level="${sys:forge.logging.mojang.level:-info}" name="com.mojang"/>
        <Logger level="${sys:forge.logging.mojang.level:-info}" name="net.minecraft"/>
        <Root level="all">
            <filters>
                <MarkerFilter marker="NETWORK_PACKETS" onMatch="DENY" onMismatch="NEUTRAL"/>
            </filters>
            <AppenderRef ref="Console" level="${sys:forge.logging.console.level:-info}"/> 
            <AppenderRef ref="ServerGuiConsole" level="${sys:forge.logging.console.level:-info}"/>
            <AppenderRef ref="File" level="${sys:forge.logging.file.level:-info}"/>
            <AppenderRef ref="DebugFile" level="${sys:forge.logging.debugFile.level:-trace}"/>
        </Root>
    </Loggers>

其中level可以通过命令行指定系统属性进行覆盖,要将控制台的DEBUG输出打开,需要将Console输出端口的日志等级调整为debug,通过如下参数覆盖:

properties
-Dforge.logging.console.level=debug
-Dforge.logging.console.level=debug

修改build.gradle文件:

build.gradle
groovy
import org.jetbrains.gradle.ext.Gradle

plugins {
    id 'java'
    id 'java-library'
    id 'maven-publish'
    id 'org.jetbrains.gradle.plugin.idea-ext' version '1.1.7'
    id 'eclipse'
    id 'com.gtnewhorizons.retrofuturagradle' version '1.3.16'
    id 'com.matthewprenger.cursegradle' version '1.4.0'
}

version = project.mod_version
group = project.maven_group
archivesBaseName = project.archives_base_name

// Set the toolchain version to decouple the Java we run Gradle with from the Java used to compile and run the mod
java {
    toolchain {
        languageVersion.set(JavaLanguageVersion.of(8))
        // Azul covers the most platforms for Java 8 toolchains, crucially including MacOS arm64
        vendor.set(org.gradle.jvm.toolchain.JvmVendorSpec.AZUL)
    }
    // Generate sources and javadocs jars when building and publishing
    withSourcesJar()
    // withJavadocJar()
}

tasks.withType(JavaCompile).configureEach {
    options.encoding = 'UTF-8'
}

configurations {
    embed
    implementation.extendsFrom(embed)
}

minecraft {
    mcVersion = '1.12.2'

    // MCP Mappings
    mcpMappingChannel = 'stable'
    mcpMappingVersion = '39'
    
    // Set username here, the UUID will be looked up automatically
    username = 'Developer'
    
    // Add any additional tweaker classes here
    // extraTweakClasses.add('org.spongepowered.asm.launch.MixinTweaker')
    
    // Add various JVM arguments here for runtime
    def args = ["-ea:${project.group}"]
    // 打开debug日志
    args << '-Dforge.logging.console.level=debug' 
    if (project.use_coremod.toBoolean()) {
        args << '-Dfml.coreMods.load=' + coremod_plugin_class_name
    }
    if (project.use_mixins.toBoolean()) {
        args << '-Dmixin.hotSwap=true'
        args << '-Dmixin.checks.interfaces=true'
        args << '-Dmixin.debug.export=true'
    }
    extraRunJvmArguments.addAll(args)

    // Include and use dependencies' Access Transformer files
    useDependencyAccessTransformers = true
    
    // Add any properties you want to swap out for a dynamic value at build time here
    // Any properties here will be added to a class at build time, the name can be configured below
    // Example:
    // injectedTags.put('VERSION', project.version)
    // injectedTags.put('MOD_ID', project.archives_base_name)
}

// Generate a group.archives_base_name.Tags class
tasks.injectTags.configure {
    // Change Tags class' name here:
    outputClassName.set("${project.group}.${project.archives_base_name}.Tags")
}

repositories {
    maven {
        name 'CleanroomMC Maven'
        url 'https://maven.cleanroommc.com'
    }
    maven {
        name 'SpongePowered Maven'
        url 'https://repo.spongepowered.org/maven'
    }
    maven {
        name 'CurseMaven'
        url 'https://cursemaven.com'
        content {
            includeGroup 'curse.maven'
        }
    }
    mavenLocal() // Must be last for caching to work
}

dependencies {
    annotationProcessor 'org.projectlombok:lombok:1.18.24'
    compileOnly 'org.projectlombok:lombok:1.18.24'
    if (project.use_assetmover.toBoolean()) {
        implementation 'com.cleanroommc:assetmover:2.5'
    }
    if (project.use_mixins.toBoolean()) {
        implementation 'zone.rong:mixinbooter:7.1'
    }

    // Example of deobfuscating a dependency
    // implementation rfg.deobf('curse.maven:had-enough-items-557549:4543375')

    if (project.use_mixins.toBoolean()) {
        // Change your mixin refmap name here:
        String mixin = modUtils.enableMixins('org.spongepowered:mixin:0.8.3', "mixins.${project.archives_base_name}.refmap.json")
        api (mixin) {
            transitive = false
        }
        annotationProcessor 'org.ow2.asm:asm-debug-all:5.2'
        annotationProcessor 'com.google.guava:guava:24.1.1-jre'
        annotationProcessor 'com.google.code.gson:gson:2.8.6'
        annotationProcessor (mixin) {
            transitive = false
        }
    }
}

// Adds Access Transformer files to tasks
if (project.use_access_transformer.toBoolean()) {
    for (File at : sourceSets.getByName("main").resources.files) {
        if (at.name.toLowerCase().endsWith("_at.cfg")) {
            tasks.deobfuscateMergedJarToSrg.accessTransformerFiles.from(at)
            tasks.srgifyBinpatchedJar.accessTransformerFiles.from(at)
        }
    }
}

processResources {
    // This will ensure that this task is redone when the versions change
    inputs.property 'version', project.version
    inputs.property 'mcversion', project.minecraft.version
    
    // Replace various properties in mcmod.info and pack.mcmeta if applicable
    filesMatching(['mcmod.info', 'pack.mcmeta']) { fcd ->
        // Replace version and mcversion
        fcd.expand (
                'version': project.version,
                'mcversion': project.minecraft.version
        )
    }
    
    if (project.use_access_transformer.toBoolean()) {
        rename '(.+_at.cfg)', 'META-INF/$1' // Make sure Access Transformer files are in META-INF folder
    }
}

jar {
    manifest {
        def attribute_map = [:]
        if (project.use_coremod.toBoolean()) {
            attribute_map['FMLCorePlugin'] = project.coremod_plugin_class_name
            if (project.include_mod.toBoolean()) {
                attribute_map['FMLCorePluginContainsFMLMod'] = true
                attribute_map['ForceLoadAsMod'] = project.gradle.startParameter.taskNames[0] == "build"
            }
        }
        if (project.use_access_transformer.toBoolean()) {
            attribute_map['FMLAT'] = project.archives_base_name + '_at.cfg'
        }
        attributes(attribute_map)
    }
    // Add all embedded dependencies into the jar
    from(provider{ configurations.embed.collect {it.isDirectory() ? it : zipTree(it)} })
}

idea {
    module {
        inheritOutputDirs = true
    }
    project {
        settings {
            runConfigurations {
                "1. Run Client"(Gradle) {
                    taskNames = ["runClient"]
                }
                "2. Run Server"(Gradle) {
                    taskNames = ["runServer"]
                }
                "3. Run Obfuscated Client"(Gradle) {
                    taskNames = ["runObfClient"]
                }
                "4. Run Obfuscated Server"(Gradle) {
                    taskNames = ["runObfServer"]
                }
            }
            compiler.javac {
                afterEvaluate {
                    javacAdditionalOptions = "-encoding utf8"
                    moduleJavacAdditionalOptions = [
                            (project.name + ".main"): tasks.compileJava.options.compilerArgs.collect { '"' + it + '"' }.join(' ')
                    ]
                }
            }
        }
    }
}

tasks.named("processIdeaSettings").configure {
    dependsOn("injectTags")
}
import org.jetbrains.gradle.ext.Gradle

plugins {
    id 'java'
    id 'java-library'
    id 'maven-publish'
    id 'org.jetbrains.gradle.plugin.idea-ext' version '1.1.7'
    id 'eclipse'
    id 'com.gtnewhorizons.retrofuturagradle' version '1.3.16'
    id 'com.matthewprenger.cursegradle' version '1.4.0'
}

version = project.mod_version
group = project.maven_group
archivesBaseName = project.archives_base_name

// Set the toolchain version to decouple the Java we run Gradle with from the Java used to compile and run the mod
java {
    toolchain {
        languageVersion.set(JavaLanguageVersion.of(8))
        // Azul covers the most platforms for Java 8 toolchains, crucially including MacOS arm64
        vendor.set(org.gradle.jvm.toolchain.JvmVendorSpec.AZUL)
    }
    // Generate sources and javadocs jars when building and publishing
    withSourcesJar()
    // withJavadocJar()
}

tasks.withType(JavaCompile).configureEach {
    options.encoding = 'UTF-8'
}

configurations {
    embed
    implementation.extendsFrom(embed)
}

minecraft {
    mcVersion = '1.12.2'

    // MCP Mappings
    mcpMappingChannel = 'stable'
    mcpMappingVersion = '39'
    
    // Set username here, the UUID will be looked up automatically
    username = 'Developer'
    
    // Add any additional tweaker classes here
    // extraTweakClasses.add('org.spongepowered.asm.launch.MixinTweaker')
    
    // Add various JVM arguments here for runtime
    def args = ["-ea:${project.group}"]
    // 打开debug日志
    args << '-Dforge.logging.console.level=debug' 
    if (project.use_coremod.toBoolean()) {
        args << '-Dfml.coreMods.load=' + coremod_plugin_class_name
    }
    if (project.use_mixins.toBoolean()) {
        args << '-Dmixin.hotSwap=true'
        args << '-Dmixin.checks.interfaces=true'
        args << '-Dmixin.debug.export=true'
    }
    extraRunJvmArguments.addAll(args)

    // Include and use dependencies' Access Transformer files
    useDependencyAccessTransformers = true
    
    // Add any properties you want to swap out for a dynamic value at build time here
    // Any properties here will be added to a class at build time, the name can be configured below
    // Example:
    // injectedTags.put('VERSION', project.version)
    // injectedTags.put('MOD_ID', project.archives_base_name)
}

// Generate a group.archives_base_name.Tags class
tasks.injectTags.configure {
    // Change Tags class' name here:
    outputClassName.set("${project.group}.${project.archives_base_name}.Tags")
}

repositories {
    maven {
        name 'CleanroomMC Maven'
        url 'https://maven.cleanroommc.com'
    }
    maven {
        name 'SpongePowered Maven'
        url 'https://repo.spongepowered.org/maven'
    }
    maven {
        name 'CurseMaven'
        url 'https://cursemaven.com'
        content {
            includeGroup 'curse.maven'
        }
    }
    mavenLocal() // Must be last for caching to work
}

dependencies {
    annotationProcessor 'org.projectlombok:lombok:1.18.24'
    compileOnly 'org.projectlombok:lombok:1.18.24'
    if (project.use_assetmover.toBoolean()) {
        implementation 'com.cleanroommc:assetmover:2.5'
    }
    if (project.use_mixins.toBoolean()) {
        implementation 'zone.rong:mixinbooter:7.1'
    }

    // Example of deobfuscating a dependency
    // implementation rfg.deobf('curse.maven:had-enough-items-557549:4543375')

    if (project.use_mixins.toBoolean()) {
        // Change your mixin refmap name here:
        String mixin = modUtils.enableMixins('org.spongepowered:mixin:0.8.3', "mixins.${project.archives_base_name}.refmap.json")
        api (mixin) {
            transitive = false
        }
        annotationProcessor 'org.ow2.asm:asm-debug-all:5.2'
        annotationProcessor 'com.google.guava:guava:24.1.1-jre'
        annotationProcessor 'com.google.code.gson:gson:2.8.6'
        annotationProcessor (mixin) {
            transitive = false
        }
    }
}

// Adds Access Transformer files to tasks
if (project.use_access_transformer.toBoolean()) {
    for (File at : sourceSets.getByName("main").resources.files) {
        if (at.name.toLowerCase().endsWith("_at.cfg")) {
            tasks.deobfuscateMergedJarToSrg.accessTransformerFiles.from(at)
            tasks.srgifyBinpatchedJar.accessTransformerFiles.from(at)
        }
    }
}

processResources {
    // This will ensure that this task is redone when the versions change
    inputs.property 'version', project.version
    inputs.property 'mcversion', project.minecraft.version
    
    // Replace various properties in mcmod.info and pack.mcmeta if applicable
    filesMatching(['mcmod.info', 'pack.mcmeta']) { fcd ->
        // Replace version and mcversion
        fcd.expand (
                'version': project.version,
                'mcversion': project.minecraft.version
        )
    }
    
    if (project.use_access_transformer.toBoolean()) {
        rename '(.+_at.cfg)', 'META-INF/$1' // Make sure Access Transformer files are in META-INF folder
    }
}

jar {
    manifest {
        def attribute_map = [:]
        if (project.use_coremod.toBoolean()) {
            attribute_map['FMLCorePlugin'] = project.coremod_plugin_class_name
            if (project.include_mod.toBoolean()) {
                attribute_map['FMLCorePluginContainsFMLMod'] = true
                attribute_map['ForceLoadAsMod'] = project.gradle.startParameter.taskNames[0] == "build"
            }
        }
        if (project.use_access_transformer.toBoolean()) {
            attribute_map['FMLAT'] = project.archives_base_name + '_at.cfg'
        }
        attributes(attribute_map)
    }
    // Add all embedded dependencies into the jar
    from(provider{ configurations.embed.collect {it.isDirectory() ? it : zipTree(it)} })
}

idea {
    module {
        inheritOutputDirs = true
    }
    project {
        settings {
            runConfigurations {
                "1. Run Client"(Gradle) {
                    taskNames = ["runClient"]
                }
                "2. Run Server"(Gradle) {
                    taskNames = ["runServer"]
                }
                "3. Run Obfuscated Client"(Gradle) {
                    taskNames = ["runObfClient"]
                }
                "4. Run Obfuscated Server"(Gradle) {
                    taskNames = ["runObfServer"]
                }
            }
            compiler.javac {
                afterEvaluate {
                    javacAdditionalOptions = "-encoding utf8"
                    moduleJavacAdditionalOptions = [
                            (project.name + ".main"): tasks.compileJava.options.compilerArgs.collect { '"' + it + '"' }.join(' ')
                    ]
                }
            }
        }
    }
}

tasks.named("processIdeaSettings").configure {
    dependsOn("injectTags")
}

注意

这会修改所有运行配置