import groovy.json.JsonSlurper import java.util.zip.ZipEntry import java.util.zip.ZipFile Configuration nativeMinecraftSources = configurations.create('nativeMinecraftSources') { canBeConsumed = false canBeResolved = true } String nativeSourceLoader = extensions.extraProperties.get('nativeSourceLoader') String nativeSourceImplementation = 'minecraft26_2' List nativeSourceOverlays = (List) irisModTarget.overlays List versionPrefixes = nativeSourceOverlays.collect { String overlay -> "versions/${overlay}/".toString() } extensions.extraProperties.set('nativeSourceImplementation', nativeSourceImplementation) dependencies.add(nativeMinecraftSources.name, "com.github.VolmitSoftware.VolmLib:native-${nativeSourceImplementation}-sources:master-SNAPSHOT") List> overlayEntries = versionPrefixes.collect { String ignored -> new HashSet() } List> overlayReplacements = versionPrefixes.collect { String ignored -> new HashMap() } Closure overlayOrigin = { String path -> for (int index = overlayEntries.size() - 1; index >= 0; index--) { if (overlayEntries.get(index).contains(path)) { return index } } return -1 } TaskProvider unpackNativeMinecraftSources = tasks.register('unpackNativeMinecraftSources', Sync) { dependsOn(nativeMinecraftSources) inputs.property('overlays', nativeSourceOverlays) inputs.property('loader', nativeSourceLoader) doFirst { overlayEntries.each { Set entries -> entries.clear() } overlayReplacements.each { Map rules -> rules.clear() } for (File artifact : nativeMinecraftSources) { new ZipFile(artifact).withCloseable { ZipFile archive -> versionPrefixes.eachWithIndex { String versionPrefix, int index -> archive.entries().each { ZipEntry entry -> if (entry.name.startsWith(versionPrefix)) { overlayEntries.get(index).add(entry.name.substring(versionPrefix.length())) } } ZipEntry rules = archive.getEntry(versionPrefix + 'source-replacements.json') if (rules != null) { archive.getInputStream(rules).withCloseable { InputStream stream -> overlayReplacements.get(index).putAll((Map) new JsonSlurper().parse(stream)) } } } } } } from(provider { nativeMinecraftSources.collect { File artifact -> zipTree(artifact) } }) { include('art/**', 'modded/**', "${nativeSourceLoader}/**", 'resources/modded/**', "resources/${nativeSourceLoader}/**") eachFile { FileCopyDetails source -> if (overlayOrigin(source.path) >= 0) { source.exclude() } } } versionPrefixes.eachWithIndex { String versionPrefix, int index -> from(provider { nativeMinecraftSources.collect { File artifact -> zipTree(artifact) } }) { include("${versionPrefix}art/**", "${versionPrefix}modded/**", "${versionPrefix}${nativeSourceLoader}/**", "${versionPrefix}resources/modded/**", "${versionPrefix}resources/${nativeSourceLoader}/**") eachFile { FileCopyDetails source -> source.path = source.path.substring(versionPrefix.length()) if (overlayOrigin(source.path) != index) { source.exclude() } } } } includeEmptyDirs = false into(layout.buildDirectory.dir('generated/sources/native-minecraft')) doLast { project.fileTree(destinationDir).matching { include('**/*.java') }.each { File source -> String path = destinationDir.toPath().relativize(source.toPath()).toString().replace(File.separator, '/') String content = source.getText('UTF-8') String rewritten = content for (int index = overlayOrigin(path) + 1; index < overlayReplacements.size(); index++) { Map replacements = overlayReplacements.get(index) List> rules = (List>) (replacements.get('global') ?: []) Map>> fileRules = (Map>>) (replacements.get('files') ?: [:]) for (Map rule : rules + (fileRules.get(path) ?: [])) { rewritten = rewritten.replaceAll(rule.pattern, rule.replacement) } } if (content != rewritten) { source.setText(rewritten, 'UTF-8') } } } } sourceSets.main.java.srcDir(unpackNativeMinecraftSources) tasks.named('compileJava').configure { dependsOn(unpackNativeMinecraftSources) } sourceSets.main.resources.srcDir(layout.buildDirectory.dir('generated/sources/native-minecraft/resources/modded')) sourceSets.main.resources.srcDir(layout.buildDirectory.dir("generated/sources/native-minecraft/resources/${nativeSourceLoader}")) tasks.named('processResources').configure { dependsOn(unpackNativeMinecraftSources) } tasks.named('verifyLoggingPolicy').configure { dependsOn(unpackNativeMinecraftSources) } tasks.named('verifyNativeBoundary').configure { dependsOn(unpackNativeMinecraftSources) } tasks.named('verifyNativeClassBoundary').configure { dependsOn(tasks.named('classes')) } tasks.matching { Task task -> task.name == 'createMinecraftArtifacts' }.configureEach { dependsOn(unpackNativeMinecraftSources) }