Datagen insanity, dependency, mixin & AW remapping #4
|
@ -19,4 +19,5 @@ object Constants {
|
||||||
const val CLEAR_GLOBAL_CACHE_TASK = "clearGlobalCache"
|
const val CLEAR_GLOBAL_CACHE_TASK = "clearGlobalCache"
|
||||||
const val ASM_VERSION = Opcodes.ASM9
|
const val ASM_VERSION = Opcodes.ASM9
|
||||||
const val ALTERNATIVE_RUNTIME_JAR_NAME = "runtime.jar"
|
const val ALTERNATIVE_RUNTIME_JAR_NAME = "runtime.jar"
|
||||||
|
const val MOJANG_MANIFEST_URL = "https://piston-meta.mojang.com/mc/game/version_manifest_v2.json"
|
||||||
}
|
}
|
|
@ -203,12 +203,17 @@ class PhytotelmaPlugin : Plugin<Project> {
|
||||||
project.tasks.getByName(JavaPlugin.JAR_TASK_NAME).actions.addLast { task ->
|
project.tasks.getByName(JavaPlugin.JAR_TASK_NAME).actions.addLast { task ->
|
||||||
val storage = ProjectStorage.get(project)
|
val storage = ProjectStorage.get(project)
|
||||||
if (storage.targetNamespace != Constants.MOJMAP_NAMESPACE) {
|
if (storage.targetNamespace != Constants.MOJMAP_NAMESPACE) {
|
||||||
val mappings = MappingBundle.merge(
|
val moj = if (storage.intermediaryNs == Constants.MOJMAP_NAMESPACE) {
|
||||||
storage.mappings!!.reverse(), MojmapProvider.get(
|
MojmapProvider.get(
|
||||||
storage.minecraftVersion!!,
|
storage.minecraftVersion!!,
|
||||||
globalCacheDir.resolve("net/minecraft/client/${storage.minecraftVersion}/client-${storage.minecraftVersion}.txt")
|
globalCacheDir.resolve("net/minecraft/client/${storage.minecraftVersion}/client-${storage.minecraftVersion}.txt")
|
||||||
).orElseThrow().reverse().renameDstNamespace(Constants.MOJMAP_NAMESPACE)
|
).orElseThrow().reverse().renameDstNamespace(Constants.MOJMAP_NAMESPACE)
|
||||||
).forNamespaces(storage.targetNamespace, Constants.MOJMAP_NAMESPACE)
|
} else null
|
||||||
|
val mappings = (moj?.let {
|
||||||
|
MappingBundle.merge(
|
||||||
|
storage.mappings!!.reverse(), it
|
||||||
|
)
|
||||||
|
} ?: storage.mappings!!).forNamespaces(storage.targetNamespace, storage.intermediaryNs)
|
||||||
val includeConfiguration = project.configurations.findByName(Constants.INCLUDE_CONFIGURATION)
|
val includeConfiguration = project.configurations.findByName(Constants.INCLUDE_CONFIGURATION)
|
||||||
task.outputs.files.forEach { file ->
|
task.outputs.files.forEach { file ->
|
||||||
val temp = Files.createTempFile("", file.name)
|
val temp = Files.createTempFile("", file.name)
|
||||||
|
|
|
@ -6,16 +6,14 @@ import com.google.gson.TypeAdapter
|
||||||
import com.google.gson.stream.JsonReader
|
import com.google.gson.stream.JsonReader
|
||||||
import com.google.gson.stream.JsonToken
|
import com.google.gson.stream.JsonToken
|
||||||
import com.google.gson.stream.JsonWriter
|
import com.google.gson.stream.JsonWriter
|
||||||
import dev.frogmc.thyroxine.api.data.DocumentationData
|
|
||||||
import dev.frogmc.thyroxine.api.data.DocumentationData.Field
|
|
||||||
import dev.frogmc.thyroxine.api.data.DocumentationData.Method
|
|
||||||
import dev.frogmc.thyroxine.api.data.MappingBundle
|
import dev.frogmc.thyroxine.api.data.MappingBundle
|
||||||
import dev.frogmc.thyroxine.api.data.MappingData
|
|
||||||
import dev.frogmc.thyroxine.api.data.Member
|
|
||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.io.path.*
|
import kotlin.io.path.absolutePathString
|
||||||
|
import kotlin.io.path.exists
|
||||||
|
import kotlin.io.path.reader
|
||||||
|
import kotlin.io.path.writeText
|
||||||
|
|
||||||
object ProjectStorage {
|
object ProjectStorage {
|
||||||
|
|
||||||
|
@ -24,7 +22,6 @@ object ProjectStorage {
|
||||||
.setPrettyPrinting()
|
.setPrettyPrinting()
|
||||||
.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
|
.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
|
||||||
.registerTypeAdapter(ProjectData::class.java, ProjectDataTypeAdapter())
|
.registerTypeAdapter(ProjectData::class.java, ProjectDataTypeAdapter())
|
||||||
//.registerTypeAdapter(MappingBundle::class.java, MappingBundleTypeAdapter())
|
|
||||||
.create()
|
.create()
|
||||||
|
|
||||||
fun get(project: Project): ProjectData {
|
fun get(project: Project): ProjectData {
|
||||||
|
@ -36,7 +33,7 @@ object ProjectStorage {
|
||||||
data[id] = projectData
|
data[id] = projectData
|
||||||
} else {
|
} else {
|
||||||
println("Creating project data store for $id, size: ${data.size}, ${this.hashCode()}")
|
println("Creating project data store for $id, size: ${data.size}, ${this.hashCode()}")
|
||||||
data[id] = ProjectData(null, null, null, null, null, null)
|
data[id] = ProjectData()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return data[id]!!
|
return data[id]!!
|
||||||
|
@ -51,13 +48,6 @@ object ProjectStorage {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun write(path: Path, projectData: ProjectData) {
|
private fun write(path: Path, projectData: ProjectData) {
|
||||||
/**
|
|
||||||
* If you're wondering "why not use the stream-based API, it should offer better performance *especially*
|
|
||||||
* for huge documents like this!"
|
|
||||||
* The answer is because it doesn't work. Somewhere in the buffer handling the document just
|
|
||||||
* gets cut off and left in an invalid state. Yes, 30+ MiB Strings aren't ideal either.
|
|
||||||
* But I'd honestly prefer that nightmare over invalid json files.
|
|
||||||
*/
|
|
||||||
path.writeText(gson.toJson(projectData))
|
path.writeText(gson.toJson(projectData))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,8 +67,12 @@ class ProjectData(
|
||||||
var remappedGameJarPath: Path?,
|
var remappedGameJarPath: Path?,
|
||||||
var mappings: MappingBundle?,
|
var mappings: MappingBundle?,
|
||||||
var mappingsName: String?,
|
var mappingsName: String?,
|
||||||
var targetNamespace: String?
|
var intermediaryNs: String?,
|
||||||
)
|
var targetNamespace: String?,
|
||||||
|
var manifestUrl: String?
|
||||||
|
) {
|
||||||
|
internal constructor() : this(null, null, null, null, null, null, null, null)
|
||||||
|
}
|
||||||
|
|
||||||
class ProjectDataTypeAdapter : TypeAdapter<ProjectData>() {
|
class ProjectDataTypeAdapter : TypeAdapter<ProjectData>() {
|
||||||
override fun write(out: JsonWriter, value: ProjectData) {
|
override fun write(out: JsonWriter, value: ProjectData) {
|
||||||
|
@ -87,8 +81,6 @@ class ProjectDataTypeAdapter : TypeAdapter<ProjectData>() {
|
||||||
out.name("local_cache_dir").value(value.localCacheDir?.absolutePathString())
|
out.name("local_cache_dir").value(value.localCacheDir?.absolutePathString())
|
||||||
out.name("minecraft_version").value(value.minecraftVersion)
|
out.name("minecraft_version").value(value.minecraftVersion)
|
||||||
out.name("remapped_game_jar_path").value(value.remappedGameJarPath?.absolutePathString())
|
out.name("remapped_game_jar_path").value(value.remappedGameJarPath?.absolutePathString())
|
||||||
/*out.name("mappings")
|
|
||||||
value.mappings?.let { MappingBundleTypeAdapter().write(out, it) }?:out.nullValue()*/
|
|
||||||
out.name("mappings_name").value(value.mappingsName)
|
out.name("mappings_name").value(value.mappingsName)
|
||||||
out.name("target_namespace").value(value.targetNamespace)
|
out.name("target_namespace").value(value.targetNamespace)
|
||||||
out.endObject()
|
out.endObject()
|
||||||
|
@ -96,7 +88,7 @@ class ProjectDataTypeAdapter : TypeAdapter<ProjectData>() {
|
||||||
|
|
||||||
override fun read(r: JsonReader): ProjectData {
|
override fun read(r: JsonReader): ProjectData {
|
||||||
r.beginObject()
|
r.beginObject()
|
||||||
val data = ProjectData(null, null, null, null, null, null)
|
val data = ProjectData()
|
||||||
while (r.peek() != JsonToken.END_OBJECT) {
|
while (r.peek() != JsonToken.END_OBJECT) {
|
||||||
val name = r.nextName()
|
val name = r.nextName()
|
||||||
if (r.peek() == JsonToken.STRING) {
|
if (r.peek() == JsonToken.STRING) {
|
||||||
|
@ -122,8 +114,6 @@ class ProjectDataTypeAdapter : TypeAdapter<ProjectData>() {
|
||||||
data.targetNamespace = value
|
data.targetNamespace = value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*} else if (name == "mappings") {
|
|
||||||
data.mappings = MappingBundleTypeAdapter().read(r)*/
|
|
||||||
} else {
|
} else {
|
||||||
r.skipValue()
|
r.skipValue()
|
||||||
}
|
}
|
||||||
|
@ -133,258 +123,3 @@ class ProjectDataTypeAdapter : TypeAdapter<ProjectData>() {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*class MappingBundleTypeAdapter : TypeAdapter<MappingBundle>() {
|
|
||||||
override fun write(out: JsonWriter, value: MappingBundle) {
|
|
||||||
out.beginObject()
|
|
||||||
out.name("data").beginArray()
|
|
||||||
value.data.forEach {
|
|
||||||
out.beginObject()
|
|
||||||
out.name("srcNs").value(it.srcNamespace)
|
|
||||||
out.name("dstNs").value(it.dstNamespace)
|
|
||||||
out.name("classes").beginObject()
|
|
||||||
it.classes.forEach { (k, v) ->
|
|
||||||
out.name(k).value(v)
|
|
||||||
}
|
|
||||||
out.endObject()
|
|
||||||
out.name("methods").beginArray()
|
|
||||||
it.methods.forEach { (k, v) ->
|
|
||||||
out.beginObject()
|
|
||||||
out.name("owner").value(k.owner)
|
|
||||||
out.name("desc").value(k.descriptor)
|
|
||||||
out.name("name").value(k.name)
|
|
||||||
out.name("value").value(v)
|
|
||||||
out.endObject()
|
|
||||||
}
|
|
||||||
out.endArray()
|
|
||||||
out.name("fields").beginArray()
|
|
||||||
it.fields.forEach { (k, v) ->
|
|
||||||
out.beginObject()
|
|
||||||
out.name("owner").value(k.owner)
|
|
||||||
out.name("desc").value(k.descriptor)
|
|
||||||
out.name("name").value(k.name)
|
|
||||||
out.name("value").value(v)
|
|
||||||
out.endObject()
|
|
||||||
}
|
|
||||||
out.endArray()
|
|
||||||
out.name("parameters").beginArray()
|
|
||||||
it.parameters.forEach { (k, v) ->
|
|
||||||
out.beginObject()
|
|
||||||
out.name("owner").value(k.owner)
|
|
||||||
out.name("desc").value(k.descriptor)
|
|
||||||
out.name("name").value(k.name)
|
|
||||||
out.name("value").beginObject()
|
|
||||||
v.forEach { (i, s) ->
|
|
||||||
out.name("$i").value(s)
|
|
||||||
}
|
|
||||||
out.endObject()
|
|
||||||
out.endObject()
|
|
||||||
}
|
|
||||||
out.endArray()
|
|
||||||
out.endObject()
|
|
||||||
}
|
|
||||||
out.endArray()
|
|
||||||
out.name("documentation").beginArray()
|
|
||||||
value.documentation.forEach {
|
|
||||||
out.beginObject()
|
|
||||||
out.name("ns").value(it.namespace)
|
|
||||||
out.name("classes").beginArray()
|
|
||||||
it.classes.forEach { c ->
|
|
||||||
out.beginObject()
|
|
||||||
out.name("name").value(c.name)
|
|
||||||
out.name("javadoc").beginArray()
|
|
||||||
c.javadoc.forEach { d ->
|
|
||||||
out.value(d)
|
|
||||||
}
|
|
||||||
out.endArray()
|
|
||||||
out.name("methods").beginArray()
|
|
||||||
c.methods.forEach { m ->
|
|
||||||
out.beginObject()
|
|
||||||
out.name("name").value(m.name)
|
|
||||||
out.name("desc").value(m.descriptor)
|
|
||||||
out.name("javadoc").beginArray()
|
|
||||||
m.javadoc.forEach { d ->
|
|
||||||
out.value(d)
|
|
||||||
}
|
|
||||||
out.endArray()
|
|
||||||
out.endObject()
|
|
||||||
}
|
|
||||||
out.endArray()
|
|
||||||
out.name("fields").beginArray()
|
|
||||||
c.fields.forEach { f ->
|
|
||||||
out.beginObject()
|
|
||||||
out.name("name").value(f.name)
|
|
||||||
out.name("desc").value(f.descriptor)
|
|
||||||
out.name("javadoc").beginArray()
|
|
||||||
f.javadoc.forEach { d ->
|
|
||||||
out.value(d)
|
|
||||||
}
|
|
||||||
out.endArray()
|
|
||||||
out.endObject()
|
|
||||||
}
|
|
||||||
out.endArray()
|
|
||||||
out.endObject()
|
|
||||||
}
|
|
||||||
out.endArray()
|
|
||||||
out.endObject()
|
|
||||||
}
|
|
||||||
out.endArray()
|
|
||||||
out.endObject()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun read(r: JsonReader): MappingBundle {
|
|
||||||
val out = MappingBundle()
|
|
||||||
r.beginObject()
|
|
||||||
r.nextName()
|
|
||||||
r.beginArray()
|
|
||||||
while (r.peek() != JsonToken.END_ARRAY) {
|
|
||||||
r.beginObject()
|
|
||||||
out.data.add(readData(r))
|
|
||||||
r.endObject()
|
|
||||||
}
|
|
||||||
r.endArray()
|
|
||||||
r.nextName()
|
|
||||||
r.beginArray()
|
|
||||||
while (r.peek() != JsonToken.END_ARRAY) {
|
|
||||||
r.beginObject()
|
|
||||||
r.nextName()
|
|
||||||
val namespace = r.nextString()
|
|
||||||
val data = DocumentationData(namespace)
|
|
||||||
out.documentation.add(data)
|
|
||||||
r.nextName()
|
|
||||||
r.beginArray()
|
|
||||||
while (r.peek() != JsonToken.END_ARRAY) {
|
|
||||||
r.beginObject()
|
|
||||||
r.nextName()
|
|
||||||
val name = r.nextString()
|
|
||||||
r.nextName()
|
|
||||||
val javadoc = mutableListOf<String>()
|
|
||||||
r.beginArray()
|
|
||||||
while (r.peek() != JsonToken.END_ARRAY) {
|
|
||||||
javadoc.add(r.nextString())
|
|
||||||
}
|
|
||||||
r.endArray()
|
|
||||||
r.nextName()
|
|
||||||
val methods = mutableListOf<Method>()
|
|
||||||
r.beginArray()
|
|
||||||
while (r.peek() != JsonToken.END_ARRAY) {
|
|
||||||
r.beginObject()
|
|
||||||
r.nextName()
|
|
||||||
val methodName = r.nextString()
|
|
||||||
r.nextName()
|
|
||||||
val desc = r.nextString()
|
|
||||||
r.nextName()
|
|
||||||
val methodJavadoc = mutableListOf<String>()
|
|
||||||
r.beginArray()
|
|
||||||
while (r.peek() != JsonToken.END_ARRAY) {
|
|
||||||
methodJavadoc.add(r.nextString())
|
|
||||||
}
|
|
||||||
r.endArray()
|
|
||||||
methods.add(Method(methodName, desc, methodJavadoc))
|
|
||||||
r.endObject()
|
|
||||||
}
|
|
||||||
r.endArray()
|
|
||||||
r.nextName()
|
|
||||||
val fields = mutableListOf<Field>()
|
|
||||||
r.beginArray()
|
|
||||||
while (r.peek() != JsonToken.END_ARRAY) {
|
|
||||||
r.beginObject()
|
|
||||||
r.nextName()
|
|
||||||
val fieldName = r.nextString()
|
|
||||||
r.nextName()
|
|
||||||
val desc = r.nextString()
|
|
||||||
r.nextName()
|
|
||||||
val fieldJavadoc = mutableListOf<String>()
|
|
||||||
r.beginArray()
|
|
||||||
while (r.peek() != JsonToken.END_ARRAY) {
|
|
||||||
fieldJavadoc.add(r.nextString())
|
|
||||||
}
|
|
||||||
r.endArray()
|
|
||||||
fields.add(Field(fieldName, desc, fieldJavadoc))
|
|
||||||
r.endObject()
|
|
||||||
}
|
|
||||||
r.endArray()
|
|
||||||
data.classes.add(DocumentationData.Class(name, javadoc, fields, methods))
|
|
||||||
r.endObject()
|
|
||||||
}
|
|
||||||
r.endArray()
|
|
||||||
r.endObject()
|
|
||||||
}
|
|
||||||
r.endArray()
|
|
||||||
r.endObject()
|
|
||||||
|
|
||||||
return out
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun readData(r: JsonReader): MappingData {
|
|
||||||
r.nextName()
|
|
||||||
val srcNs = r.nextString()
|
|
||||||
r.nextName()
|
|
||||||
val dstNs = r.nextString()
|
|
||||||
r.nextName()
|
|
||||||
r.beginObject()
|
|
||||||
val classes = mutableMapOf<String, String>()
|
|
||||||
while (r.peek() != JsonToken.END_OBJECT) {
|
|
||||||
classes[r.nextName()] = r.nextString()
|
|
||||||
}
|
|
||||||
r.endObject()
|
|
||||||
r.nextName()
|
|
||||||
r.beginArray()
|
|
||||||
val methods = mutableMapOf<Member, String>()
|
|
||||||
while (r.peek() != JsonToken.END_ARRAY) {
|
|
||||||
r.beginObject()
|
|
||||||
r.nextName()
|
|
||||||
val owner = r.nextString()
|
|
||||||
r.nextName()
|
|
||||||
val desc = r.nextString()
|
|
||||||
r.nextName()
|
|
||||||
val name = r.nextString()
|
|
||||||
r.nextName()
|
|
||||||
val value = r.nextString()
|
|
||||||
methods[Member(owner, name, desc)] = value
|
|
||||||
r.endObject()
|
|
||||||
}
|
|
||||||
r.endArray()
|
|
||||||
r.nextName()
|
|
||||||
r.beginArray()
|
|
||||||
val fields = mutableMapOf<Member, String>()
|
|
||||||
while (r.peek() != JsonToken.END_ARRAY) {
|
|
||||||
r.beginObject()
|
|
||||||
r.nextName()
|
|
||||||
val owner = r.nextString()
|
|
||||||
r.nextName()
|
|
||||||
val desc = r.nextString()
|
|
||||||
r.nextName()
|
|
||||||
val name = r.nextString()
|
|
||||||
r.nextName()
|
|
||||||
val value = r.nextString()
|
|
||||||
fields[Member(owner, name, desc)] = value
|
|
||||||
r.endObject()
|
|
||||||
}
|
|
||||||
r.endArray()
|
|
||||||
r.nextName()
|
|
||||||
r.beginArray()
|
|
||||||
val parameters = mutableMapOf<Member, MutableMap<Int, String>>()
|
|
||||||
while (r.peek() != JsonToken.END_ARRAY) {
|
|
||||||
r.beginObject()
|
|
||||||
r.nextName()
|
|
||||||
val owner = r.nextString()
|
|
||||||
r.nextName()
|
|
||||||
val desc = r.nextString()
|
|
||||||
r.nextName()
|
|
||||||
val name = r.nextString()
|
|
||||||
r.nextName()
|
|
||||||
r.beginObject()
|
|
||||||
val values = mutableMapOf<Int, String>()
|
|
||||||
while (r.peek() != JsonToken.END_OBJECT) {
|
|
||||||
values[r.nextName().toInt()] = r.nextString()
|
|
||||||
}
|
|
||||||
r.endObject()
|
|
||||||
parameters[Member(owner, name, desc)] = values
|
|
||||||
r.endObject()
|
|
||||||
}
|
|
||||||
r.endArray()
|
|
||||||
return MappingData(srcNs, dstNs, classes, methods, fields, parameters)
|
|
||||||
}
|
|
||||||
|
|
||||||
}*/
|
|
||||||
|
|
|
@ -18,8 +18,8 @@ object VersionChecker {
|
||||||
@Suppress("DEPRECATION")
|
@Suppress("DEPRECATION")
|
||||||
fun downloadClient(project: Project, version: String): Path {
|
fun downloadClient(project: Project, version: String): Path {
|
||||||
|
|
||||||
fetchVersionData(version)
|
fetchVersionData(project, version)
|
||||||
val clientData = fetchClientDownload(version)
|
val clientData = fetchClientDownload(project, version)
|
||||||
// download client data
|
// download client data
|
||||||
val downloadDirectory = PhytotelmaPlugin.globalCacheDir.resolve("net/minecraft/client/$version/")
|
val downloadDirectory = PhytotelmaPlugin.globalCacheDir.resolve("net/minecraft/client/$version/")
|
||||||
val downloadFile = downloadDirectory.resolve("client-$version.jar")
|
val downloadFile = downloadDirectory.resolve("client-$version.jar")
|
||||||
|
@ -47,39 +47,39 @@ object VersionChecker {
|
||||||
dir.resolve("client-$version.pom").writeText(content)
|
dir.resolve("client-$version.pom").writeText(content)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getDependencies(version: String, action: (String) -> Unit) {
|
fun getDependencies(project: Project, version: String, action: (String) -> Unit) {
|
||||||
fetchVersionData(version).libraries.map { it.name }.forEach {
|
fetchVersionData(project, version).libraries.map { it.name }.forEach {
|
||||||
action.invoke(it)
|
action.invoke(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun validateVersion(version: String, ignoreCache: Boolean = false, offlineMode: Boolean): Boolean {
|
fun validateVersion(project: Project, version: String, ignoreCache: Boolean = false, offlineMode: Boolean): Boolean {
|
||||||
if (validVersions.isEmpty() || ignoreCache) getValidVersions(ignoreCache)
|
if (validVersions.isEmpty() || ignoreCache) getValidVersions(project, ignoreCache)
|
||||||
if (!validVersions.any { it.id == version }) {
|
if (!validVersions.any { it.id == version }) {
|
||||||
if (!offlineMode) {
|
if (!offlineMode) {
|
||||||
return validateVersion(version, ignoreCache = true, offlineMode = false)
|
return validateVersion(project, version, ignoreCache = true, offlineMode = false)
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getVersionUrl(version: String): String {
|
fun getVersionUrl(project: Project, version: String): String {
|
||||||
if (validVersions.isEmpty()) getValidVersions()
|
if (validVersions.isEmpty()) getValidVersions(project)
|
||||||
return validVersions.first { it.id == version }.url
|
return validVersions.first { it.id == version }.url
|
||||||
}
|
}
|
||||||
|
|
||||||
fun fetchVersionData(version: String): VersionData {
|
fun fetchVersionData(project: Project, version: String): VersionData {
|
||||||
if (versionData == null || versionData!!.id != version) {
|
if (versionData == null || versionData!!.id != version) {
|
||||||
val url = getVersionUrl(version)
|
val url = getVersionUrl(project, version)
|
||||||
val response = getUrl(url)
|
val response = getUrl(url)
|
||||||
versionData = Gson().fromJson(response, VersionData::class.java)
|
versionData = Gson().fromJson(response, VersionData::class.java)
|
||||||
}
|
}
|
||||||
return versionData!!
|
return versionData!!
|
||||||
}
|
}
|
||||||
|
|
||||||
fun fetchClientDownload(version: String): VersionClientData {
|
fun fetchClientDownload(project: Project, version: String): VersionClientData {
|
||||||
return fetchVersionData(version).downloads.client
|
return fetchVersionData(project, version).downloads.client
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun rawDownload(url: String): ByteArray {
|
private fun rawDownload(url: String): ByteArray {
|
||||||
|
@ -90,12 +90,12 @@ object VersionChecker {
|
||||||
return CachingHttpClient.getString(URI.create(url), ignoreCache)
|
return CachingHttpClient.getString(URI.create(url), ignoreCache)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getValidVersions(ignoreCache: Boolean = false) {
|
private fun getValidVersions(project: Project, ignoreCache: Boolean = false) {
|
||||||
if (validVersions.isNotEmpty() && !ignoreCache) return
|
if (validVersions.isNotEmpty() && !ignoreCache) return
|
||||||
// get json from https://piston-meta.mojang.com/mc/game/version_manifest_v2.json
|
// get json from https://piston-meta.mojang.com/mc/game/version_manifest_v2.json
|
||||||
// make http request
|
// make http request
|
||||||
|
|
||||||
val url = "https://piston-meta.mojang.com/mc/game/version_manifest_v2.json"
|
val url = ProjectStorage.get(project).manifestUrl!!
|
||||||
val response = getUrl(url, ignoreCache)
|
val response = getUrl(url, ignoreCache)
|
||||||
// response is in format of {versions: [{id: "1.17.1", type: "release"}, ...]}
|
// response is in format of {versions: [{id: "1.17.1", type: "release"}, ...]}
|
||||||
// parse json
|
// parse json
|
||||||
|
|
|
@ -49,7 +49,7 @@ abstract class PhytotelmaBuildTask : DefaultTask() {
|
||||||
.plus(
|
.plus(
|
||||||
"""
|
"""
|
||||||
Built-By: Phytotelma ${this.javaClass.`package`.implementationVersion}
|
Built-By: Phytotelma ${this.javaClass.`package`.implementationVersion}
|
||||||
Target-Namespace: Mojmap
|
Target-Namespace: ${ProjectStorage.get(project).intermediaryNs}
|
||||||
Built-For: Minecraft ${ProjectStorage.get(project).minecraftVersion}
|
Built-For: Minecraft ${ProjectStorage.get(project).minecraftVersion}
|
||||||
Build-Date: ${LocalDateTime.now()}
|
Build-Date: ${LocalDateTime.now()}
|
||||||
""".trimIndent()
|
""".trimIndent()
|
||||||
|
|
|
@ -28,6 +28,8 @@ abstract class MinecraftConfiguration @Inject constructor(
|
||||||
|
|
||||||
val version: Property<String> = objects.property(String::class.java).unset()
|
val version: Property<String> = objects.property(String::class.java).unset()
|
||||||
var mappings: Provider<MappingBundle> = mojmapParchment()
|
var mappings: Provider<MappingBundle> = mojmapParchment()
|
||||||
|
val intermediaryNamespace: Property<String> = objects.property(String::class.java).convention(Constants.MOJMAP_NAMESPACE)
|
||||||
|
val manifestUrl: Property<String> = objects.property(String::class.java).convention(Constants.MOJANG_MANIFEST_URL)
|
||||||
internal lateinit var mappingsName: String
|
internal lateinit var mappingsName: String
|
||||||
internal lateinit var targetNamespace: String
|
internal lateinit var targetNamespace: String
|
||||||
|
|
||||||
|
@ -123,6 +125,23 @@ abstract class MinecraftConfiguration @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun feather(action: Action<VersionConfiguration>): Provider<MappingBundle> {
|
||||||
|
return project.provider {
|
||||||
|
val conf = objects.newInstance(VersionConfiguration::class.java)
|
||||||
|
action.execute(conf)
|
||||||
|
if (!conf.version.isPresent) {
|
||||||
|
error("No version provided for yarn!")
|
||||||
|
}
|
||||||
|
mappingsName = "yarn(${conf.version.get()})"
|
||||||
|
targetNamespace = "yarn"
|
||||||
|
// Use qm via intermediary because hashed publications are broken
|
||||||
|
return@provider twoStepMappings(
|
||||||
|
"net.ornithemc:calamus-intermediary:${version.get()}:v2",
|
||||||
|
"net.fabricmc:yarn:${conf.version.get()}:v2"
|
||||||
|
).flatten(true).renameDstNamespace(targetNamespace)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun twoStepMappings(action: Action<TwoStepMappingsConfiguration>): Provider<MappingBundle> {
|
fun twoStepMappings(action: Action<TwoStepMappingsConfiguration>): Provider<MappingBundle> {
|
||||||
return project.provider {
|
return project.provider {
|
||||||
val conf = objects.newInstance(TwoStepMappingsConfiguration::class.java)
|
val conf = objects.newInstance(TwoStepMappingsConfiguration::class.java)
|
||||||
|
|
|
@ -35,7 +35,7 @@ abstract class PhytotelmaGradleExtensionImpl @Inject constructor(
|
||||||
}
|
}
|
||||||
val version = mcConf.version.get()
|
val version = mcConf.version.get()
|
||||||
|
|
||||||
if (VersionChecker.validateVersion(version, offlineMode = project.gradle.startParameter.isOffline)) {
|
if (VersionChecker.validateVersion(project, version, offlineMode = project.gradle.startParameter.isOffline)) {
|
||||||
|
|
||||||
val projectData = ProjectStorage.get(project)
|
val projectData = ProjectStorage.get(project)
|
||||||
projectData.minecraftVersion = version
|
projectData.minecraftVersion = version
|
||||||
|
@ -50,6 +50,7 @@ abstract class PhytotelmaGradleExtensionImpl @Inject constructor(
|
||||||
remappedJar.createParentDirectories()
|
remappedJar.createParentDirectories()
|
||||||
projectData.remappedGameJarPath = remappedJar
|
projectData.remappedGameJarPath = remappedJar
|
||||||
var applyAW = AccessWidener.needsUpdate(project)
|
var applyAW = AccessWidener.needsUpdate(project)
|
||||||
|
projectData.intermediaryNs = mcConf.intermediaryNamespace.get()
|
||||||
if (remappedJar.notExists() || applyAW || mcConf.mappingsName != projectData.mappingsName) {
|
if (remappedJar.notExists() || applyAW || mcConf.mappingsName != projectData.mappingsName) {
|
||||||
projectData.mappingsName = mcConf.mappingsName
|
projectData.mappingsName = mcConf.mappingsName
|
||||||
println("Remapping the game...")
|
println("Remapping the game...")
|
||||||
|
@ -67,7 +68,7 @@ abstract class PhytotelmaGradleExtensionImpl @Inject constructor(
|
||||||
Constants.MINECRAFT_CONFIGURATION,
|
Constants.MINECRAFT_CONFIGURATION,
|
||||||
"net.minecrell:terminalconsoleappender:1.2.0"
|
"net.minecrell:terminalconsoleappender:1.2.0"
|
||||||
)
|
)
|
||||||
VersionChecker.getDependencies(version) {
|
VersionChecker.getDependencies(project, version) {
|
||||||
project.dependencies.add(Constants.MINECRAFT_CONFIGURATION, it)
|
project.dependencies.add(Constants.MINECRAFT_CONFIGURATION, it)
|
||||||
}
|
}
|
||||||
project.dependencies.add(Constants.MINECRAFT_CONFIGURATION, "net.minecraft:client:$version:remapped")
|
project.dependencies.add(Constants.MINECRAFT_CONFIGURATION, "net.minecraft:client:$version:remapped")
|
||||||
|
|
|
@ -21,7 +21,7 @@ object AssetDownloader {
|
||||||
fun download(project: Project, manualInvocation: Boolean = false) {
|
fun download(project: Project, manualInvocation: Boolean = false) {
|
||||||
val version = ProjectStorage.get(project).minecraftVersion!!
|
val version = ProjectStorage.get(project).minecraftVersion!!
|
||||||
val path = PhytotelmaPlugin.globalCacheDir.resolve("assets")
|
val path = PhytotelmaPlugin.globalCacheDir.resolve("assets")
|
||||||
val assetIndex = VersionChecker.fetchVersionData(version).assetIndex
|
val assetIndex = VersionChecker.fetchVersionData(project, version).assetIndex
|
||||||
val dest = path.resolve("indexes").resolve(assetIndex.id + ".json")
|
val dest = path.resolve("indexes").resolve(assetIndex.id + ".json")
|
||||||
var overwrite = manualInvocation
|
var overwrite = manualInvocation
|
||||||
if (dest.notExists()) {
|
if (dest.notExists()) {
|
||||||
|
|
|
@ -25,7 +25,7 @@ object RunConfigGenerator {
|
||||||
if (assetIndexPath.notExists()) {
|
if (assetIndexPath.notExists()) {
|
||||||
assetIndexPath.createDirectories()
|
assetIndexPath.createDirectories()
|
||||||
}
|
}
|
||||||
val indexId = VersionChecker.fetchVersionData(ProjectStorage.get(project).minecraftVersion!!).assetIndex.id
|
val indexId = VersionChecker.fetchVersionData(project, ProjectStorage.get(project).minecraftVersion!!).assetIndex.id
|
||||||
val log4jPath = project.rootDir.resolve(".gradle/phytotelma/log4j.xml").toPath().absolute()
|
val log4jPath = project.rootDir.resolve(".gradle/phytotelma/log4j.xml").toPath().absolute()
|
||||||
if (log4jPath.notExists()) {
|
if (log4jPath.notExists()) {
|
||||||
log4jPath.createParentDirectories()
|
log4jPath.createParentDirectories()
|
||||||
|
|
|
@ -29,7 +29,7 @@ abstract class RunGameTask @Inject constructor(env: Env) : JavaExec() {
|
||||||
if (assetIndexPath.notExists()) {
|
if (assetIndexPath.notExists()) {
|
||||||
assetIndexPath.createDirectories()
|
assetIndexPath.createDirectories()
|
||||||
}
|
}
|
||||||
val indexId = VersionChecker.fetchVersionData(ProjectStorage.get(project).minecraftVersion!!).assetIndex.id
|
val indexId = VersionChecker.fetchVersionData(project, ProjectStorage.get(project).minecraftVersion!!).assetIndex.id
|
||||||
val log4jPath = project.rootDir.resolve(".gradle/phytotelma/log4j.xml").toPath().absolute()
|
val log4jPath = project.rootDir.resolve(".gradle/phytotelma/log4j.xml").toPath().absolute()
|
||||||
if (log4jPath.notExists()) {
|
if (log4jPath.notExists()) {
|
||||||
log4jPath.createParentDirectories()
|
log4jPath.createParentDirectories()
|
||||||
|
|
Loading…
Reference in a new issue