Skip to content

Commit

Permalink
Use NFRT to get more robust asset downloading.
Browse files Browse the repository at this point in the history
  • Loading branch information
shartte committed Aug 15, 2024
1 parent 42d8a2a commit 278955d
Show file tree
Hide file tree
Showing 7 changed files with 81 additions and 112 deletions.
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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=<expected-major>`, where `<expected-major>` matches the subdirectory
under `versions/snapshot`.

Gradle tasks:
* `:<version>:projectApplyAll` - Creates Minecraft source code of that version with patches applied
Expand Down
27 changes: 14 additions & 13 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,11 @@ subprojects {
mergetool
renametool
mergemaptool
nfrt {
canBeResolved = true
canBeConsumed = false
transitive = false
}
if (MCINJECTOR) {
mcinjector
}
Expand Down Expand Up @@ -191,6 +196,7 @@ subprojects {
transitive = false
}
}
nfrt "net.neoforged:neoform-runtime:1.0.4:all"
}

task downloadJson(type: Download, dependsOn: rootProject.downloadVersionManifest) {
Expand Down Expand Up @@ -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'
}
Expand Down Expand Up @@ -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
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public abstract class ApplyPatches extends DefaultTask {
def patches = patches.get().asFile

def result = PatchOperation.builder()
.logTo((Consumer<String>){logger.log(it, LogLevel.LIFECYCLE)})
.logTo((Consumer<String>){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()))
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -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<String, Object> getConfig()
Expand Down Expand Up @@ -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")
}
}
Original file line number Diff line number Diff line change
@@ -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<String> getDistro()
Expand All @@ -22,7 +17,8 @@ public abstract class CreateProjectTemplate extends DefaultTask {
@Input abstract MapProperty<String, String> getReplace()
@Internal abstract ConfigurableFileCollection getDirectories()
@Input abstract Property<String> getVersion()

@Optional @InputFile abstract RegularFileProperty getAssetJsonFile()

@OutputDirectory abstract RegularFileProperty getDest()

def library(lib) {
Expand All @@ -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
}
}
Expand All @@ -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())
Expand Down Expand Up @@ -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) }
}
}
Original file line number Diff line number Diff line change
@@ -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<DownloadDetails>() {
@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<String> 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()
);
});
}
}
}

0 comments on commit 278955d

Please sign in to comment.