//file:noinspection GroovyAssignabilityCheck plugins { id 'java' id 'idea' id 'java-library' id 'maven-publish' id 'com.github.johnrengelman.shadow' version '8.1.1' id 'net.neoforged.moddev.legacyforge' version '2.0.103' id 'com.dorongold.task-tree' version '2.1.1' } apply from: 'gradle/jni-heads.gradle' java { toolchain.languageVersion = JavaLanguageVersion.of(17) } tasks.named('wrapper', Wrapper).configure { distributionType = Wrapper.DistributionType.BIN } version = "${minecraft_version}-${mod_version}" group = mod_group_id repositories { mavenLocal() maven { url = "https://libraries.minecraft.net/" } maven { url = "https://neoforged.forgecdn.net/releases" } maven { url = "https://neoforged.forgecdn.net/mojang-meta" } maven { url = "https://maven.neoforged.net/releases" } maven { name = "LTD Maven" url = "https://nexus.bot.leisuretimedock.top/repository/maven-public/" } flatDir { dir "libs" } } base { archivesName = mod_id } // Mojang ships Java 17 to end users in 1.20.1, so mods should target Java 17. java.toolchain.languageVersion = JavaLanguageVersion.of(17) legacyForge { // Specify the version of MinecraftForge to use. version = project.minecraft_version + '-' + project.forge_version parchment { mappingsVersion = project.parchment_mappings_version minecraftVersion = project.parchment_minecraft_version } // Default run configurations. runs { client { client() systemProperty 'forge.enabledGameTestNamespaces', project.mod_id } clientAuth{ devLogin = true client() systemProperty 'forge.enabledGameTestNamespaces', project.mod_id } server { server() programArgument '--nogui' systemProperty 'forge.enabledGameTestNamespaces', project.mod_id } gameTestServer { type = "gameTestServer" systemProperty 'forge.enabledGameTestNamespaces', project.mod_id } data { data() programArguments.addAll '--mod', project.mod_id, '--all', '--output', file('src/generated/resources/').getAbsolutePath(), '--existing', file('src/main/resources/').getAbsolutePath() } configureEach { systemProperty 'forge.logging.markers', 'REGISTRIES' logLevel = org.slf4j.event.Level.DEBUG } } mods { "${mod_id}" { sourceSet(sourceSets.main) } } } // Include resources generated by data generators. sourceSets.main.resources { srcDir 'src/generated/resources' } configurations { runtimeClasspath.extendsFrom localRuntime } obfuscation { createRemappingConfiguration(configurations.localRuntime) } dependencies { } test { useJUnitPlatform() // 显示测试输出 testLogging { events "passed", "skipped", "failed" showStandardStreams = true } // 设置类路径 classpath = sourceSets.test.runtimeClasspath } // This block of code expands all declared replace properties in the specified resource targets. var generateModMetadata = tasks.register("generateModMetadata", ProcessResources) { var replaceProperties = [ minecraft_version : minecraft_version, minecraft_version_range : minecraft_version_range, forge_version : forge_version, forge_version_range : forge_version_range, loader_version_range : loader_version_range, mod_id : mod_id, mod_name : mod_name, mod_license : mod_license, mod_version : mod_version, mod_authors : mod_authors, mod_description : mod_description, mod_credits : mod_credits ] duplicatesStrategy = DuplicatesStrategy.EXCLUDE inputs.properties replaceProperties expand replaceProperties from "src/main/templates" into "build/generated/sources/modMetadata" } sourceSets.main.resources.srcDir generateModMetadata legacyForge.ideSyncTask generateModMetadata // ==================== Javadoc 配置 ==================== javadoc { options { encoding = 'UTF-8' charSet = 'UTF-8' author = true version = true windowTitle = "RedEnvelope ${project.mod_version}" docTitle = "RedEnvelope ${project.mod_version}" memberLevel = JavadocMemberLevel.PROTECTED links = [ 'https://docs.oracle.com/javase/8/docs/api/' ] addBooleanOption('Xdoclint:none', true) addBooleanOption('html5', true) } // 确保有源代码可供生成文档 if (sourceSets.main.allJava.files.any { it.exists() }) { source = sourceSets.main.allJava } classpath = configurations.compileClasspath exclude '**/test/**' exclude '**/internal/**' // 确保输出目录存在 doFirst { destinationDir.mkdirs() } } tasks.register('javadocJar', Jar) { archiveFileName = "${mod_id}-${minecraft_version}-${mod_version}-javadoc.jar" archiveClassifier.set("javadoc") from tasks.javadoc dependsOn tasks.javadoc } tasks.register('sourceJar', Jar) { from(sourceSets.main.allSource) // java archiveFileName = "${mod_id}-${minecraft_version}-${mod_version}-sources.jar" archiveClassifier.set("sources") duplicatesStrategy = DuplicatesStrategy.EXCLUDE manifest { attributes([ 'Specification-Title' : mod_id, 'Specification-Vendor' : mod_authors, 'Specification-Version' : '1', 'Implementation-Title' : project.name, 'Implementation-Version' : archiveVersion, 'Implementation-Vendor' : mod_authors, 'Implementation-Timestamp': new Date().format("yyyy-MM-dd'T'HH:mm:ssZ"), 'MixinConfigs' : "${mod_id}.mixins.json" ]) } dependsOn classes } tasks.named('publish') { dependsOn build } // ==================== 发布配置 ==================== publishing { publications { mavenJava(MavenPublication) { artifactId = mod_id artifact reobfJar artifact sourceJar artifact javadocJar pom { name = 'RedEnvelope' description = 'A mod allows you to send red envelopes (also hongbao) to other players.' url = 'https://github.com/3944Realms/lib39' properties = [ 'minecraft.version': project.minecraft_version, 'mod.version': project.mod_version, 'forge.version': project.forge_version, 'java.version': '17' ] licenses { license { name = 'Camellia License' url = 'https://raw.githubusercontent.com/LeisureTimeDock/RedEnvelope/refs/heads/master/LICENSE.md' distribution = 'repo' } } developers { developer { id = 'R3944Realms' name = "${mod_authors}" email = 'f256198830@hotmail.com' } } scm { connection = 'scm:git:https://github.com/3944Realms/lib39.git' developerConnection = 'scm:git:ssh://git@github.com:3944Realms/lib39.git' url = 'https://github.com/3944Realms/lib39' tag = 'main' } issueManagement { system = 'GitHub' url = 'https://github.com/3944Realms/lib39/issues' } } } } repositories { // 本地仓库 maven { name = 'local' url = layout.buildDirectory.dir("repo") } // Nexus 远程仓库 maven { name = 'LTDNexus' url = 'https://nexus.bot.leisuretimedock.top/repository/maven-releases/' credentials { username = System.getenv('LTDNexusUsername') ?: '' password = System.getenv('LTDNexusPassword') ?: '' } } } } // ==================== 任务配置 ==================== tasks.withType(JavaCompile).configureEach { options.encoding = 'UTF-8' options.compilerArgs += ['-Xlint:unchecked', '-Xlint:deprecation'] } // 配置 Javadoc JAR - 使用标准 javadoc 任务输出 tasks.named('javadocJar') { from javadoc.destinationDir } // ==================== 验证任务 ==================== tasks.register('verifyNexusCredentials') { doLast { def username = System.getenv('LTDNexusUsername') def password = System.getenv('LTDNexusPassword') // 安全地显示用户名和密码(只显示最后两位) def displayUsername = username ? "***${username.length() > 2 ? username.substring(username.length() - 2) : '**'}" : 'NOT SET' def displayPassword = password ? "***${password.length() > 2 ? password.substring(password.length() - 2) : '**'}" : 'NOT SET' println "Nexus Username: ${displayUsername}" println "Nexus Password: ${displayPassword}" if (!username || !password) { throw new GradleException('LTDNexusUsername or LTDNexusPassword environment variables are not set') } } } tasks.register('checkPublicationContents') { doLast { def publication = publishing.publications.mavenJava println "=== Publication Details ===" println "Group: ${publication.groupId}" println "Artifact: ${publication.artifactId}" println "Version: ${publication.version}" println "Artifacts:" publication.artifacts.each { artifact -> def file = artifact.file def exists = file.exists() println " - ${file.name} (${artifact.classifier ?: 'main'}) - Exists: ${exists}" if (!exists) { throw new GradleException("Publication artifact missing: ${file.absolutePath}") } } } } // ==================== 任务依赖 ==================== tasks.named('publishMavenJavaPublicationToLTDNexusRepository') { dependsOn verifyNexusCredentials dependsOn checkPublicationContents } tasks.withType(PublishToMavenRepository) { dependsOn assemble dependsOn javadocJar } // ==================== 便捷任务 ==================== tasks.register('publishToNexus') { group = 'publishing' description = 'Publishes all publications to LTD Nexus' dependsOn 'publishMavenJavaPublicationToLTDNexusRepository' } tasks.named('build') { dependsOn javadocJar, sourceJar } tasks.register('publishLocal') { group = 'publishing' description = 'Publishes all publications to the local Maven repository' dependsOn 'publishToMavenLocal' } tasks.register('cleanRepo', Delete) { delete layout.buildDirectory.dir("repo") } tasks.named('clean') { dependsOn cleanRepo } // ==================== IDEA 配置 ==================== idea { module { downloadSources = true downloadJavadoc = true } } // 禁用模块元数据生成 tasks.withType(GenerateModuleMetadata) { enabled = false } tasks.register('showTaskTree') { doLast { def showTaskDeps showTaskDeps = { task, prefix = '' -> println "${prefix}${task.name}" task.getTaskDependencies().getDependencies(task).each { dep -> showTaskDeps(dep, prefix + ' ') } } def targetTask = tasks.findByName('build') if (targetTask) { println "构建任务依赖树:" showTaskDeps(targetTask) } else { println "未找到 build 任务" } } }