diff --git a/README.md b/README.md index 69ba6649..dd381306 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,10 @@ Definitions: options in `local.properties` can be set to filter for which versions are loaded by gradle: * `type` (defaults to `release`) -* `ver` (defaults to all major versions) +* `ver` (defaults to all major versions + +To get snapshots, set `type=snapshot` and `ver=`, where `` matches the subdirectory +under `versions/snapshot`. Gradle tasks: * `::projectApplyAll` - Creates Minecraft source code of that version with patches applied diff --git a/build.gradle b/build.gradle index 200c16a3..8ab34606 100644 --- a/build.gradle +++ b/build.gradle @@ -129,6 +129,11 @@ subprojects { mergetool renametool mergemaptool + nfrt { + canBeResolved = true + canBeConsumed = false + transitive = false + } if (MCINJECTOR) { mcinjector } @@ -191,6 +196,7 @@ subprojects { transitive = false } } + nfrt "net.neoforged:neoform-runtime:1.0.4:all" } task downloadJson(type: Download, dependsOn: rootProject.downloadVersionManifest) { @@ -224,20 +230,14 @@ subprojects { config = CONFIG dest = new File(gradle.gradleUserHomeDir, '/caches/neoform/libraries/') } - task downloadAssets(type: DownloadAssets, dependsOn: downloadJson) { - json = downloadJson.dest - dest = new File(gradle.gradleUserHomeDir, '/caches/neoform/assets/') - } - - task createAssetsData(type: CreateAssetsDataJson, dependsOn: downloadAssets) { - assets = downloadAssets.dest - json = downloadJson.dest - - dest = file(PATH_CACHED_VERSION + 'assets.json') + task downloadAssets(type: DownloadAssets) { + assetJson = file(PATH_CACHED_VERSION + 'assets.json') + nfrt = configurations.nfrt + minecraftVersion = version } task createAssetsDataJar(type: Jar, dependsOn: downloadAssets) { - from createAssetsData.dest + from downloadAssets.assetJson destinationDirectory = file(PATH_CACHED_VERSION) archiveFileName = 'assets.json.jar' } @@ -469,11 +469,12 @@ subprojects { CONFIG?.libraries?.get(side)?.each { library "'${it}'" } version = project.name libraryFile child.extra.extra.get().getAsFile() - if (child.assets) + if (child.assets) { libraryFile createAssetsDataJar.archiveFile.get().asFile + assetJsonFile = downloadAssets.assetJson + } replace '{java_target}', JAVA_TARGET + '' replaceFile '{inject}', PATH_INJECT - replaceFile '{assets}', child.assets ? downloadAssets.dest : null replaceFile '{natives}', child.jsonlibs ? extractNatives.dest : null replaceFile '{merged_src}', MERGE_PATCHES ? project.file('projects/shared') : null } diff --git a/buildSrc/src/main/groovy/net/minecraftforge/mcpconfig/tasks/ApplyPatches.groovy b/buildSrc/src/main/groovy/net/minecraftforge/mcpconfig/tasks/ApplyPatches.groovy index 4e037906..b72a6273 100644 --- a/buildSrc/src/main/groovy/net/minecraftforge/mcpconfig/tasks/ApplyPatches.groovy +++ b/buildSrc/src/main/groovy/net/minecraftforge/mcpconfig/tasks/ApplyPatches.groovy @@ -25,7 +25,7 @@ public abstract class ApplyPatches extends DefaultTask { def patches = patches.get().asFile def result = PatchOperation.builder() - .logTo((Consumer){logger.log(it, LogLevel.LIFECYCLE)}) + .logTo((Consumer){logger.log(LogLevel.LIFECYCLE, it)}) .baseInput(Input.MultiInput.archive(ArchiveFormat.ZIP, baseZip.toPath())) .patchesInput(Input.MultiInput.folder(patches.toPath())) .patchedOutput(Output.MultiOutput.folder(output.toPath())) diff --git a/buildSrc/src/main/groovy/net/minecraftforge/mcpconfig/tasks/CreateAssetsDataJson.groovy b/buildSrc/src/main/groovy/net/minecraftforge/mcpconfig/tasks/CreateAssetsDataJson.groovy deleted file mode 100644 index 989d9ba1..00000000 --- a/buildSrc/src/main/groovy/net/minecraftforge/mcpconfig/tasks/CreateAssetsDataJson.groovy +++ /dev/null @@ -1,21 +0,0 @@ -package net.minecraftforge.mcpconfig.tasks; - -import org.gradle.api.* -import org.gradle.api.file.* -import org.gradle.api.provider.* -import org.gradle.api.tasks.* - -abstract class CreateAssetsDataJson extends SingleFileOutput { - @InputDirectory abstract RegularFileProperty getAssets() - @InputFile abstract RegularFileProperty getJson() - - @TaskAction - def exec() { - Utils.init() - def data = [ - assets: assets.get().asFile.absolutePath.replace("\\", "/"), - asset_index: json.get().asFile.json.assetIndex.id - ] - dest.get().asFile.json = data - } -} \ No newline at end of file diff --git a/buildSrc/src/main/groovy/net/minecraftforge/mcpconfig/tasks/CreateFernflowerLibraries.groovy b/buildSrc/src/main/groovy/net/minecraftforge/mcpconfig/tasks/CreateFernflowerLibraries.groovy index 8a01dd02..f4fedb9d 100644 --- a/buildSrc/src/main/groovy/net/minecraftforge/mcpconfig/tasks/CreateFernflowerLibraries.groovy +++ b/buildSrc/src/main/groovy/net/minecraftforge/mcpconfig/tasks/CreateFernflowerLibraries.groovy @@ -1,12 +1,9 @@ package net.minecraftforge.mcpconfig.tasks; -import org.gradle.api.* import org.gradle.api.file.* import org.gradle.api.provider.* import org.gradle.api.tasks.* -import java.util.TreeSet - abstract class CreateFernflowerLibraries extends SingleFileOutput { @InputFile abstract RegularFileProperty getMeta() @Input abstract MapProperty getConfig() @@ -34,6 +31,6 @@ abstract class CreateFernflowerLibraries extends SingleFileOutput { } config.get().libraries.get(side.get())?.collect{ it.toMavenPath() }?.each { libs.add(new File(root.get().getAsFile(), it)) } - dest.get().getAsFile().text = libs.collect{ '-e=' + it.absolutePath }.join('\n') + dest.get().getAsFile().write(libs.collect{ '-e=' + it.absolutePath }.join('\n'), "UTF-8") } } \ No newline at end of file diff --git a/buildSrc/src/main/groovy/net/minecraftforge/mcpconfig/tasks/CreateProjectTemplate.groovy b/buildSrc/src/main/groovy/net/minecraftforge/mcpconfig/tasks/CreateProjectTemplate.groovy index e62bcad0..ec8faa12 100644 --- a/buildSrc/src/main/groovy/net/minecraftforge/mcpconfig/tasks/CreateProjectTemplate.groovy +++ b/buildSrc/src/main/groovy/net/minecraftforge/mcpconfig/tasks/CreateProjectTemplate.groovy @@ -1,17 +1,12 @@ package net.minecraftforge.mcpconfig.tasks -import java.util.HashMap -import java.util.HashSet -import java.util.ArrayList -import java.util.List -import java.util.Set + import java.util.zip.ZipFile import org.gradle.api.* import org.gradle.api.file.* import org.gradle.api.provider.* import org.gradle.api.tasks.* import groovy.json.JsonSlurper -import net.neoforged.srgutils.IMappingFile public abstract class CreateProjectTemplate extends DefaultTask { @Input abstract Property getDistro() @@ -22,7 +17,8 @@ public abstract class CreateProjectTemplate extends DefaultTask { @Input abstract MapProperty getReplace() @Internal abstract ConfigurableFileCollection getDirectories() @Input abstract Property getVersion() - + @Optional @InputFile abstract RegularFileProperty getAssetJsonFile() + @OutputDirectory abstract RegularFileProperty getDest() def library(lib) { @@ -41,7 +37,7 @@ public abstract class CreateProjectTemplate extends DefaultTask { if (value == null) { replace(key, 'null') } else { - replace(key, "'" + value.get().getAsFile().absolutePath.replace('\\', '/') + "'") + replace(key, escapePathForGradle(value.get().getAsFile().absolutePath)) directories + value } } @@ -50,11 +46,15 @@ public abstract class CreateProjectTemplate extends DefaultTask { if (value == null) { replace(key, 'null') } else { - replace(key, "'" + value.absolutePath.replace('\\', '/') + "'") + replace(key, escapePathForGradle(value.absolutePath)) directories + value } } - + + private static String escapePathForGradle(String path) { + return "'" + path.replace('\\', '/') + "'" + } + @TaskAction protected void exec() { if (!dest.get().getAsFile().exists()) @@ -89,7 +89,12 @@ public abstract class CreateProjectTemplate extends DefaultTask { def v = replace.get().get(k) data = data.replace(k, v) } - + + if (getAssetJsonFile().isPresent()) { + def assetInfo = new JsonSlurper().parse(getAssetJsonFile().get().asFile) + data = data.replace("{assets}", escapePathForGradle(assetInfo.assets)) + } + new File(dest.get().getAsFile(), 'build.gradle').withWriter('UTF-8') { it.write(data) } } } \ No newline at end of file diff --git a/buildSrc/src/main/groovy/net/minecraftforge/mcpconfig/tasks/DownloadAssets.groovy b/buildSrc/src/main/groovy/net/minecraftforge/mcpconfig/tasks/DownloadAssets.groovy index ee4c7f13..fca7ba1b 100644 --- a/buildSrc/src/main/groovy/net/minecraftforge/mcpconfig/tasks/DownloadAssets.groovy +++ b/buildSrc/src/main/groovy/net/minecraftforge/mcpconfig/tasks/DownloadAssets.groovy @@ -1,70 +1,54 @@ package net.minecraftforge.mcpconfig.tasks -import org.gradle.api.* -import org.gradle.api.file.* -import org.gradle.api.tasks.* -import de.undercouch.gradle.tasks.download.* +import org.gradle.api.DefaultTask +import org.gradle.api.file.ConfigurableFileCollection +import org.gradle.api.file.RegularFileProperty +import org.gradle.api.provider.Property +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.InputFiles +import org.gradle.api.tasks.OutputFile +import org.gradle.api.tasks.TaskAction +import org.gradle.process.ExecOperations +import org.gradle.work.DisableCachingByDefault -public abstract class DownloadAssets extends DefaultTask { - @InputFile abstract RegularFileProperty getJson() - @OutputDirectory abstract RegularFileProperty getDest() - @Internal DownloadAction indexAction - @Internal DownloadAction assetAction +import javax.inject.Inject - DownloadAssets() { - indexAction = new DownloadAction(project, this) - indexAction.onlyIfModified(true) - indexAction.useETag('all') - assetAction = new DownloadAction(project, this) - assetAction.overwrite(false) - assetAction.useETag('all') - } - - @TaskAction - def exec() { - Utils.init() - - def dl = json.get().getAsFile().json.assetIndex - def index = new File(dest.get().getAsFile(), 'indexes/' + dl.id + '.json') - if (index.sha1 != dl.sha1) { - indexAction.src dl.url - indexAction.dest index - indexAction.execute().join() - } - - def assets = [] as Set // Some assets are copies of other assets +@DisableCachingByDefault(because = "has its own caching") +abstract class DownloadAssets extends DefaultTask { + /** + * Writes a JSON file detailing the path to the asset index and asset root. + */ + @OutputFile + abstract RegularFileProperty getAssetJson() - assetAction.dest(new File(dest.get().getAsFile(), 'objects')) - index.json.objects.each { asset -> - def key = asset.value.hash.take(2) + '/' + asset.value.hash - def target = new File(dest.get().getAsFile(), 'objects/' + key) - if (!target.exists() && assets.add(asset.value.hash)) { - assetAction.src('https://resources.download.minecraft.net/' + key) - } - } + /** + * Points to the single executable jar for + * https://projects.neoforged.net/neoforged/neoformruntime + */ + @InputFiles + abstract ConfigurableFileCollection getNfrt(); - if (assets.size() > 1) { - assetAction.eachFile(new Action() { - @Override - public void execute(DownloadDetails details) { - details.relativePath = new RelativePath(false, details.sourceURL.toString().replace('https://resources.download.minecraft.net/', '')) - } - }) - } else if (assets.size() == 1) { - assetAction.dest(new File(dest.get().getAsFile(), 'objects/' + assets[0].take(2) + '/' + assets[0])) - } + /** + * The Minecraft version matching the NeoForge version to install. + */ + @Input + abstract Property getMinecraftVersion(); - if (!assets.isEmpty()) { - assetAction.execute() - } - } + @Inject + abstract ExecOperations getExecOperations(); - def download(def url, def target) { - def ret = new DownloadAction(project, this) - ret.overwrite(false) - ret.useETag('all') - ret.src url - ret.dest target - ret.execute() + @TaskAction + def exec() { + // Download Minecraft Assets and write asset index and location to JSON file to read back for starting the game + execOperations.javaexec(spec -> { + spec.classpath(getNfrt().getSingleFile()); + spec.args( + "download-assets", + "--minecraft-version", + minecraftVersion.get(), + "--write-json", + assetJson.get().asFile.getAbsolutePath() + ); + }); } -} \ No newline at end of file +}