Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use NFRT to get more robust asset downloading #12

Merged
merged 1 commit into from
Aug 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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()
);
});
}
}
}