import net.darkhax.curseforgegradle.TaskPublishCurseForge import org.w3c.dom.Document import org.w3c.dom.NodeList import javax.xml.parsers.DocumentBuilderFactory import java.nio.ByteBuffer import java.nio.charset.StandardCharsets plugins { id 'java-library' id 'idea' id 'maven-publish' id 'net.darkhax.curseforgegradle' version '1.1.18' id 'com.modrinth.minotaur' version '2.+' id 'net.neoforged.moddev' version '[2.0,2.1)' } version = minecraft_version + "-" + mod_version repositories { mavenLocal() } base { archivesName = project.name } java.toolchain.languageVersion = JavaLanguageVersion.of(21) // Include resources generated by data generators. sourceSets.main.resources { srcDir 'src/generated/resources' } configurations { runtimeClasspath.extendsFrom localRuntime } neoForge { version = project.neo_version validateAccessTransformers = true parchment { minecraftVersion = project.parchment_minecraft_version mappingsVersion = project.parchment_mappings_version } runs { client { client() systemProperty 'neoforge.enableGameTestNamespaces', project.modid } server { server() programArgument '--nogui' systemProperty 'neoforge.enabledGameTestNamespaces', project.modid } data { data() programArguments.addAll '--mod', project.modid, '--all', '--output', file('src/generated/resources/').getAbsolutePath(), '--existing', file('src/main/resources/').getAbsolutePath() } gameTestServer { type = "gameTestServer" systemProperty 'neoforge.enabledGameTestNamespaces', project.modid } configureEach { // "SCAN": For mods scan. // "REGISTRIES": For firing of registry events. // "REGISTRYDUMP": For getting the contents of all registries. systemProperty 'forge.logging.markers', 'REGISTRIES' logLevel = org.slf4j.event.Level.DEBUG gameDirectory = project.file('run' + name.capitalize()) } } mods { // define mod <-> source bindings // these are used to tell the game which sources are for which mod // mostly optional in a single mod project // but multi mod projects should define one per mod "${modid}" { sourceSet(sourceSets.main) } } } tasks.withType(ProcessResources).configureEach { var replaceProperties = [ minecraft_version : minecraft_version, neo_version : neo_version, loader_version_range: loader_version_range, modid : modid, license : license, mod_version : version ] inputs.properties replaceProperties filesMatching(['META-INF/neoforge.mods.toml']) { expand replaceProperties } } tasks.withType(JavaCompile).configureEach { options.encoding = 'UTF-8' } idea { module { downloadSources = true downloadJavadoc = true } } private static String getVersion(String baseVersion, URL url) { try { HttpURLConnection connection = (HttpURLConnection) url.openConnection() connection.setRequestMethod("GET") Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(connection.getInputStream()) NodeList versionNodes = doc.getElementsByTagName("version") String latestVersion = null for (int i = 0; i < versionNodes.getLength(); i++) { String version = versionNodes.item(i).getTextContent() if (version.startsWith(baseVersion)) { latestVersion = version } } if (latestVersion == null) { return baseVersion + ".0" } return baseVersion + "." + (Integer.parseInt(latestVersion.substring(latestVersion.lastIndexOf('.') + 1)) + 1) } catch (FileNotFoundException ignored) { // This exception is thrown if the maven-metadata.xml file doesn't exist at the provided URL, // which would be the case if there were no previous publications to this Maven repository with this project return baseVersion + ".0" } catch (Exception e) { throw new RuntimeException(e) } } if (!getProperty('project', 'curse').isEmpty()) { task curseforge(type: TaskPublishCurseForge) { apiToken = project.findProperty('curse_token') ?: System.getenv('CURSEFORGE_TOKEN') ?: '' Closure fileConfig = { file -> file.releaseType = getProperty('release', 'curse', 'release') file.changelog = changelog(project) file.changelogType = 'markdown' getArray(getProperty('requirements', 'curse')).each { file.addRequirement(it) } getArray(getProperty('optionals', 'curse')).each { file.addOptional(it) } getArray(getProperty('versions', 'curse', minecraft_version)).each { file.addGameVersion(it) } file.addModLoader('neoforge') } def mainFile = upload(getProperty('project', 'curse'), jar) fileConfig(mainFile) } project.tasks.getByName('curseforge').dependsOn('build') } if (!getProperty('project', 'modrinth').isEmpty()) { modrinth { token = project.findProperty('modrinth_token') ?: System.getenv('MODRINTH_TOKEN') ?: '' projectId = getProperty('project', 'modrinth') versionNumber = project.version versionName = jar.getArchiveFileName().get() uploadFile = jar dependencies = [] changelog = changelog(project) versionType = getProperty('release', 'modrinth', 'release') getArray(getProperty('requirements', 'modrinth')).each { dependencies.add(new com.modrinth.minotaur.dependencies.ModDependency(it, 'required')) } getArray(getProperty('optionals', 'modrinth')).each { dependencies.add(new com.modrinth.minotaur.dependencies.ModDependency(it, 'optional')) } gameVersions = getArray(getProperty('versions', 'modrinth', minecraft_version)).toList() loaders = ['neoforge'] } } String getProperty(String entry, String platform) { return getProperty(entry, platform, '') } String getProperty(String entry, String platform, String ret) { return project.findProperty('upload_' + entry) ?: project.findProperty(platform + '_' + entry) ?: ret } static String[] getArray(String deps) { return deps.split(',')*.strip().toList().findAll { !it.isEmpty() } } String changelog(Project project) { String logFmt = '--pretty=tformat:"- [%s](' + project.changelog_repository.toString() + ') - *%aN*"' def stdout = new ByteArrayOutputStream() def gitHash = System.getenv('GIT_COMMIT') def gitPrevHash = System.getenv('GIT_PREVIOUS_COMMIT') if (gitPrevHash == "0000000000000000000000000000000000000000") { gitPrevHash = "HEAD~1" } if (gitHash != null && gitPrevHash != null) { exec { commandLine 'bash', '-c', "git log ${logFmt} ${gitPrevHash}...${gitHash} | grep -v '^- \\[\\[meta\\]'" standardOutput = stdout } } else { stdout.write('No changelog provided\n'.getBytes(StandardCharsets.UTF_8)) } return StandardCharsets.UTF_8.decode(ByteBuffer.wrap(stdout.toByteArray())).toString() }