add accesswidener processing
This commit is contained in:
parent
5f8c1538c3
commit
80a9fc3fdc
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -37,3 +37,4 @@ bin/
|
||||||
|
|
||||||
### Mac OS ###
|
### Mac OS ###
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
.kotlin/
|
||||||
|
|
|
@ -22,6 +22,7 @@ repositories {
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation("org.ecorous.esnesnon:nonsense-remapper:1.0.0-SNAPSHOT")
|
implementation("org.ecorous.esnesnon:nonsense-remapper:1.0.0-SNAPSHOT")
|
||||||
|
implementation("org.ow2.asm:asm:9.7")
|
||||||
implementation("com.google.code.gson:gson:2.10.1")
|
implementation("com.google.code.gson:gson:2.10.1")
|
||||||
implementation("org.vineflower:vineflower:1.10.1")
|
implementation("org.vineflower:vineflower:1.10.1")
|
||||||
testImplementation(kotlin("test"))
|
testImplementation(kotlin("test"))
|
||||||
|
@ -31,9 +32,9 @@ dependencies {
|
||||||
|
|
||||||
gradlePlugin {
|
gradlePlugin {
|
||||||
plugins {
|
plugins {
|
||||||
create("nonsense-gradle") {
|
create("phytotelma") {
|
||||||
id = "org.ecorous.esnesnon.nonsense-gradle"
|
id = "org.ecorous.esnesnon.phytotelma"
|
||||||
implementationClass = "org.ecorous.esnesnon.gradle.NonsenseGradlePlugin"
|
implementationClass = "org.ecorous.esnesnon.gradle.PhytotelmaPlugin"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
plugins {
|
plugins {
|
||||||
id("org.gradle.toolchains.foojay-resolver-convention") version "0.8.0"
|
id("org.gradle.toolchains.foojay-resolver-convention") version "0.8.0"
|
||||||
}
|
}
|
||||||
rootProject.name = "nonsense-gradle"
|
rootProject.name = "phytotelma"
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ import com.electronwill.nightconfig.core.io.WritingMode
|
||||||
import com.electronwill.nightconfig.toml.TomlParser
|
import com.electronwill.nightconfig.toml.TomlParser
|
||||||
import com.electronwill.nightconfig.toml.TomlWriter
|
import com.electronwill.nightconfig.toml.TomlWriter
|
||||||
import net.fabricmc.fernflower.api.IFabricJavadocProvider
|
import net.fabricmc.fernflower.api.IFabricJavadocProvider
|
||||||
|
import org.ecorous.esnesnon.gradle.accesswidener.AccessWidener
|
||||||
import org.ecorous.esnesnon.gradle.common.Env
|
import org.ecorous.esnesnon.gradle.common.Env
|
||||||
import org.ecorous.esnesnon.gradle.nest.Nester
|
import org.ecorous.esnesnon.gradle.nest.Nester
|
||||||
import org.ecorous.esnesnon.gradle.run.AssetDownloader
|
import org.ecorous.esnesnon.gradle.run.AssetDownloader
|
||||||
|
@ -32,18 +33,19 @@ import kotlin.io.path.deleteExisting
|
||||||
import kotlin.io.path.exists
|
import kotlin.io.path.exists
|
||||||
|
|
||||||
|
|
||||||
class NonsenseGradlePlugin : Plugin<Project> {
|
class PhytotelmaPlugin : Plugin<Project> {
|
||||||
|
|
||||||
|
private val taskGroup = "frog"
|
||||||
|
|
||||||
override fun apply(project: Project) {
|
override fun apply(project: Project) {
|
||||||
println("> Applying Nonsense Gradle Plugin")
|
println("> Applying Nonsense Gradle Plugin")
|
||||||
nonsenseCacheDir = project.gradle.gradleUserHomeDir.resolve("caches/nonsense-gradle/").toPath()
|
nonsenseCacheDir = project.gradle.gradleUserHomeDir.resolve("caches/nonsense-gradle/").toPath()
|
||||||
nonsenseCacheDir.createDirectories()
|
nonsenseCacheDir.createDirectories()
|
||||||
|
|
||||||
project.apply {
|
project.plugins.let {
|
||||||
mapOf("plugin" to "java-library")
|
it.apply("java-library")
|
||||||
mapOf("plugin" to "eclipse")
|
it.apply("eclipse")
|
||||||
mapOf("plugin" to "idea")
|
it.apply("idea")
|
||||||
mapOf("plugin" to "maven-publish")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
project.repositories.apply {
|
project.repositories.apply {
|
||||||
|
@ -67,11 +69,11 @@ class NonsenseGradlePlugin : Plugin<Project> {
|
||||||
project.repositories.mavenCentral()
|
project.repositories.mavenCentral()
|
||||||
|
|
||||||
project.task("genSources").apply {
|
project.task("genSources").apply {
|
||||||
group = "nonsense"
|
group = taskGroup
|
||||||
doFirst {
|
doFirst {
|
||||||
val fileName = remappedGameJarPath.fileName.toString()
|
val fileName = remappedGameJarPath.fileName.toString()
|
||||||
val output =
|
val output =
|
||||||
remappedGameJarPath.resolveSibling(fileName.substring(0, fileName.length - 13) + "-sources.jar")
|
remappedGameJarPath.resolveSibling(fileName.substring(0, fileName.lastIndexOf("-")) + "-sources.jar")
|
||||||
if (output.exists()) {
|
if (output.exists()) {
|
||||||
println("Output $output already exists, deleting!")
|
println("Output $output already exists, deleting!")
|
||||||
output.deleteExisting()
|
output.deleteExisting()
|
||||||
|
@ -110,7 +112,7 @@ class NonsenseGradlePlugin : Plugin<Project> {
|
||||||
}
|
}
|
||||||
|
|
||||||
project.task("genRunConfigs").apply {
|
project.task("genRunConfigs").apply {
|
||||||
group = "nonsense"
|
group = taskGroup
|
||||||
doFirst {
|
doFirst {
|
||||||
RunConfigGenerator.generate(project)
|
RunConfigGenerator.generate(project)
|
||||||
}
|
}
|
||||||
|
@ -120,7 +122,7 @@ class NonsenseGradlePlugin : Plugin<Project> {
|
||||||
project.tasks.register("runServer", RunGameTask::class.java, Env.SERVER)
|
project.tasks.register("runServer", RunGameTask::class.java, Env.SERVER)
|
||||||
|
|
||||||
project.task("downloadAssets").apply {
|
project.task("downloadAssets").apply {
|
||||||
group = "nonsense"
|
group = taskGroup
|
||||||
doFirst {
|
doFirst {
|
||||||
AssetDownloader.download()
|
AssetDownloader.download()
|
||||||
}
|
}
|
||||||
|
@ -168,6 +170,13 @@ class NonsenseGradlePlugin : Plugin<Project> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
project.tasks.register("updateAccesswidener") {
|
||||||
|
it.group = taskGroup
|
||||||
|
it.actions.addFirst {
|
||||||
|
AccessWidener.apply(project, remappedGameJarPath)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
|
@ -17,7 +17,7 @@ object VersionChecker {
|
||||||
fetchVersionData(version)
|
fetchVersionData(version)
|
||||||
val clientData = fetchClientDownload(version)
|
val clientData = fetchClientDownload(version)
|
||||||
// download client data
|
// download client data
|
||||||
val downloadDirectory = NonsenseGradlePlugin.nonsenseCacheDir.resolve("net/minecraft/client/$version/")
|
val downloadDirectory = PhytotelmaPlugin.nonsenseCacheDir.resolve("net/minecraft/client/$version/")
|
||||||
println("Directory: "+downloadDirectory.absolutePathString())
|
println("Directory: "+downloadDirectory.absolutePathString())
|
||||||
val downloadFile = downloadDirectory.resolve("client-$version.jar")
|
val downloadFile = downloadDirectory.resolve("client-$version.jar")
|
||||||
if (downloadFile.exists()) {
|
if (downloadFile.exists()) {
|
||||||
|
|
|
@ -0,0 +1,298 @@
|
||||||
|
package org.ecorous.esnesnon.gradle.accesswidener
|
||||||
|
|
||||||
|
import com.electronwill.nightconfig.core.file.FileNotFoundAction
|
||||||
|
import com.electronwill.nightconfig.toml.TomlParser
|
||||||
|
import com.google.common.hash.Hashing
|
||||||
|
import org.gradle.api.Project
|
||||||
|
import org.gradle.api.plugins.JavaPluginExtension
|
||||||
|
import org.objectweb.asm.*
|
||||||
|
import java.nio.charset.StandardCharsets
|
||||||
|
import java.nio.file.*
|
||||||
|
import java.nio.file.attribute.BasicFileAttributes
|
||||||
|
import java.util.regex.Pattern
|
||||||
|
import kotlin.io.path.bufferedReader
|
||||||
|
import kotlin.io.path.readBytes
|
||||||
|
import kotlin.io.path.readLines
|
||||||
|
import kotlin.io.path.writeBytes
|
||||||
|
|
||||||
|
object AccessWidener {
|
||||||
|
|
||||||
|
private val PARSER = TomlParser()
|
||||||
|
|
||||||
|
private var awHash = ""
|
||||||
|
private val HEADER = Pattern.compile("accessWidener\\s+v[12]\\s+.*").asMatchPredicate()
|
||||||
|
private val COMMENT = Pattern.compile("^#.*").asMatchPredicate()
|
||||||
|
private val SEPARATOR = "[\\t ]+".toRegex()
|
||||||
|
|
||||||
|
private fun getAWFile(project: Project): Path? {
|
||||||
|
project.extensions.getByType(JavaPluginExtension::class.java).sourceSets.forEach { set ->
|
||||||
|
set.resources.filter { it.name == "frog.mod.toml" }.firstOrNull {
|
||||||
|
if (it == null){
|
||||||
|
println("Please make sure a 'frog.mod.toml' file is present in the mod's resources!")
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
return PARSER.parse(it, FileNotFoundAction.READ_NOTHING)
|
||||||
|
.get<String>("frog.extensions.frog_aw")?.let { name ->
|
||||||
|
return it.resolveSibling(name).toPath()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
println("Please make sure a 'frog.mod.toml' file is present in the mod's resources!")
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun findDependencyAWs(project: Project): List<Path> {
|
||||||
|
return project.configurations.getByName("runtimeClasspath").resolvedConfiguration.firstLevelModuleDependencies.flatMap { dep ->
|
||||||
|
dep.moduleArtifacts
|
||||||
|
}.map { it.file }.map { it.toPath() }.toList()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun needsUpdate(project: Project): Boolean {
|
||||||
|
getAWFile(project)?.let {
|
||||||
|
val hash = Hashing.sha256().hashBytes(it.readBytes()).toString()
|
||||||
|
if (hash != awHash) {
|
||||||
|
awHash = hash
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun readAW(project: Project): List<String> {
|
||||||
|
val awFile = getAWFile(project)
|
||||||
|
println("Found accesswidener in project: $awFile")
|
||||||
|
return awFile?.readLines(StandardCharsets.UTF_8)?.map { it.replace("transitive-", "") }?.toList()
|
||||||
|
?: listOf()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun readTransitiveAW(path: Path): List<String> {
|
||||||
|
return path.bufferedReader(StandardCharsets.UTF_8).lines().filter { it.startsWith("transitive-") }.toList()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun parseAW(entries: List<String>): List<Entry> {
|
||||||
|
return entries.asSequence().filter { it.isNotBlank() }
|
||||||
|
.filter { !COMMENT.test(it) }.filter { !HEADER.test(it) }.distinct()
|
||||||
|
.map { it.split(SEPARATOR) }.filter { it.isNotEmpty() } .map { Entry(it) }.toList()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun readAllAWs(project: Project): List<Entry> {
|
||||||
|
return findDependencyAWs(project).flatMap { readTransitiveAW(it) }.plus(readAW(project))
|
||||||
|
.let { parseAW(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun apply(project: Project, input: Path) {
|
||||||
|
val startTime = System.currentTimeMillis()
|
||||||
|
val entries: List<Entry> = readAllAWs(project)
|
||||||
|
|
||||||
|
val classMap: MutableMap<String, Entry> = mutableMapOf()
|
||||||
|
val methods: MutableMap<String, MutableMap<String, Entry>> = mutableMapOf()
|
||||||
|
val fields: MutableMap<String, MutableMap<String, Entry>> = mutableMapOf()
|
||||||
|
val mutations: MutableMap<String, MutableMap<String, Entry>> = mutableMapOf()
|
||||||
|
entries.forEach { e ->
|
||||||
|
if ("class" == e.targetType) {
|
||||||
|
if (e.type == AccessType.MUTABLE) {
|
||||||
|
throw IllegalArgumentException("aw format error: classes can not have a 'mutable' modifier (at: $e)")
|
||||||
|
}
|
||||||
|
if (!classMap.containsKey(e.className)) {
|
||||||
|
classMap[e.className] = e
|
||||||
|
} else {
|
||||||
|
val other = classMap[e.className]!!
|
||||||
|
if (e.isAccessGreaterThan(other)) {
|
||||||
|
classMap[e.className] = e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if ("method" == e.targetType) {
|
||||||
|
if (e.type == AccessType.MUTABLE) {
|
||||||
|
throw IllegalArgumentException("aw format error: methods can not have a 'mutable' modifier (at: $e)")
|
||||||
|
}
|
||||||
|
val map = methods.computeIfAbsent(e.className) { mutableMapOf() }
|
||||||
|
val id = e.name + e.descriptor
|
||||||
|
if (!map.containsKey(id)) {
|
||||||
|
map[id] = e
|
||||||
|
} else {
|
||||||
|
val other = map[id]!!
|
||||||
|
if (e.isAccessGreaterThan(other)) {
|
||||||
|
classMap[id] = e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if ("field" == e.targetType) {
|
||||||
|
if (e.type == AccessType.EXTENDABLE) {
|
||||||
|
throw IllegalArgumentException("aw format error: fields can not have a 'extendable' modifier (at: $e)")
|
||||||
|
}
|
||||||
|
val map = fields.computeIfAbsent(e.className) { mutableMapOf() }
|
||||||
|
val id = e.name + e.descriptor
|
||||||
|
if (e.type == AccessType.MUTABLE) {
|
||||||
|
mutations.computeIfAbsent(e.className) { mutableMapOf() }.putIfAbsent(id, e)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!map.containsKey(id)) {
|
||||||
|
map[id] = e
|
||||||
|
} else {
|
||||||
|
val other = map[id]!!
|
||||||
|
if (e.isAccessGreaterThan(other)) {
|
||||||
|
classMap[id] = e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FileSystems.newFileSystem(input).use {
|
||||||
|
Files.walkFileTree(it.getPath("/"), AWFileVisitor(classMap, fields, methods, mutations))
|
||||||
|
}
|
||||||
|
println("Finished widening ${classMap.size} classes, ${methods.size} methods and ${fields.size+mutations.size} fields in ${"%2f".format(System.currentTimeMillis()-startTime)}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data class Entry(
|
||||||
|
val type: AccessType,
|
||||||
|
val targetType: String,
|
||||||
|
val className: String,
|
||||||
|
val name: String,
|
||||||
|
val descriptor: String
|
||||||
|
) {
|
||||||
|
constructor(line: List<String>) : this(
|
||||||
|
AccessType.of(line[0]),
|
||||||
|
line[1],
|
||||||
|
line[2],
|
||||||
|
line[3],
|
||||||
|
line[4]
|
||||||
|
)
|
||||||
|
|
||||||
|
fun isAccessGreaterThan(other: Entry): Boolean {
|
||||||
|
return Access.of(type.access).index < Access.of(other.type.access).index
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum class AccessType(val id: String, val access: Int) {
|
||||||
|
ACCESSIBLE("accessible", Opcodes.ACC_PUBLIC),
|
||||||
|
EXTENDABLE("extendable", Opcodes.ACC_PROTECTED),
|
||||||
|
MUTABLE("mutable", Opcodes.ACC_FINAL.inv());
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun of(name: String): AccessType {
|
||||||
|
return entries.first { a -> a.id == name }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum class Access(val index: Int) {
|
||||||
|
PUBLIC(1), PROTECTED(2), PACKAGE_PRIVATE(3), PRIVATE(4);
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun of(access: Int): Access {
|
||||||
|
if ((access and Opcodes.ACC_PUBLIC) != 0) {
|
||||||
|
return PUBLIC
|
||||||
|
}
|
||||||
|
if ((access and Opcodes.ACC_PROTECTED) != 0) {
|
||||||
|
return PROTECTED
|
||||||
|
}
|
||||||
|
if ((access and Opcodes.ACC_PRIVATE) != 0) {
|
||||||
|
return PRIVATE
|
||||||
|
}
|
||||||
|
return PACKAGE_PRIVATE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class AWFileVisitor(
|
||||||
|
private val classMap: Map<String, Entry>,
|
||||||
|
private val fields: Map<String, Map<String, Entry>>,
|
||||||
|
private val methods: Map<String, Map<String, Entry>>,
|
||||||
|
private val mutations: Map<String, Map<String, Entry>>,
|
||||||
|
) : SimpleFileVisitor<Path>() {
|
||||||
|
override fun visitFile(file: Path, attrs: BasicFileAttributes): FileVisitResult {
|
||||||
|
if (file.fileName.toString().endsWith(".class")) {
|
||||||
|
val className = file.toString().substring(1, file.toString().length - 6)
|
||||||
|
|
||||||
|
if (classMap.containsKey(className) || fields.containsKey(className) || methods.containsKey(className) || mutations.containsKey(className)) {
|
||||||
|
|
||||||
|
val reader = ClassReader(file.readBytes())
|
||||||
|
val writer = ClassWriter(0)
|
||||||
|
val mapper = AWClassVisitor(writer, classMap, fields, methods, mutations, className)
|
||||||
|
|
||||||
|
reader.accept(mapper, 0)
|
||||||
|
file.writeBytes(writer.toByteArray())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return FileVisitResult.CONTINUE
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class AWClassVisitor(
|
||||||
|
visitor: ClassVisitor,
|
||||||
|
private val classMap: Map<String, Entry>,
|
||||||
|
private val fields: Map<String, Map<String, Entry>>,
|
||||||
|
private val methods: Map<String, Map<String, Entry>>,
|
||||||
|
private val mutations: Map<String, Map<String, Entry>>,
|
||||||
|
private val className: String
|
||||||
|
) : ClassVisitor(Opcodes.ASM9, visitor) {
|
||||||
|
override fun visit(
|
||||||
|
version: Int,
|
||||||
|
acc: Int,
|
||||||
|
name: String?,
|
||||||
|
signature: String?,
|
||||||
|
superName: String?,
|
||||||
|
interfaces: Array<out String>?
|
||||||
|
) {
|
||||||
|
var access = acc
|
||||||
|
val e = classMap[className]
|
||||||
|
if (e != null) {
|
||||||
|
access = access and ((Opcodes.ACC_PRIVATE or Opcodes.ACC_PROTECTED or Opcodes.ACC_PUBLIC).inv())
|
||||||
|
access = access.or(e.type.access)
|
||||||
|
} else if (fields.containsKey(className) || methods.containsKey(className) || mutations.containsKey(
|
||||||
|
className
|
||||||
|
)
|
||||||
|
) { // make all classes with modifications public as well
|
||||||
|
access = access and ((Opcodes.ACC_PRIVATE or Opcodes.ACC_PROTECTED or Opcodes.ACC_PUBLIC).inv())
|
||||||
|
access = access.or(Opcodes.ACC_PUBLIC)
|
||||||
|
}
|
||||||
|
super.visit(version, access, name, signature, superName, interfaces)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitField(
|
||||||
|
acc: Int,
|
||||||
|
name: String?,
|
||||||
|
descriptor: String?,
|
||||||
|
signature: String?,
|
||||||
|
value: Any?
|
||||||
|
): FieldVisitor {
|
||||||
|
var access = acc
|
||||||
|
var map = fields[className]
|
||||||
|
if (map != null) {
|
||||||
|
val e = map[name + descriptor]
|
||||||
|
if (e != null) {
|
||||||
|
access = access and ((Opcodes.ACC_PRIVATE or Opcodes.ACC_PROTECTED or Opcodes.ACC_PUBLIC).inv())// remove all access modifiers
|
||||||
|
access = access.or(e.type.access)// re-add the new one
|
||||||
|
}
|
||||||
|
}
|
||||||
|
map = mutations[className]
|
||||||
|
if (map != null) {
|
||||||
|
val e = map[name + descriptor]
|
||||||
|
if (e != null) {
|
||||||
|
access = access.or(Opcodes.ACC_FINAL.inv()) // always AccessType.MUTABLE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return super.visitField(access, name, descriptor, signature, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitMethod(
|
||||||
|
acc: Int,
|
||||||
|
name: String?,
|
||||||
|
descriptor: String?,
|
||||||
|
signature: String?,
|
||||||
|
exceptions: Array<out String>?
|
||||||
|
): MethodVisitor {
|
||||||
|
var access = acc
|
||||||
|
val map = methods[className]
|
||||||
|
if (map != null) {
|
||||||
|
val e = map[name + descriptor]
|
||||||
|
if (e != null) {
|
||||||
|
access = access and ((Opcodes.ACC_PRIVATE or Opcodes.ACC_PROTECTED or Opcodes.ACC_PUBLIC).inv())// remove all access modifiers
|
||||||
|
access = access.or(e.type.access)// re-add the new one
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return super.visitMethod(access, name, descriptor, signature, exceptions)
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
package org.ecorous.esnesnon.gradle.common
|
package org.ecorous.esnesnon.gradle.common
|
||||||
|
|
||||||
import org.ecorous.esnesnon.gradle.NonsenseGradlePlugin
|
import org.ecorous.esnesnon.gradle.PhytotelmaPlugin
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
import java.net.URI
|
import java.net.URI
|
||||||
import java.nio.charset.StandardCharsets
|
import java.nio.charset.StandardCharsets
|
||||||
|
@ -39,7 +39,7 @@ object CachingHttpClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getCacheFile(uri: URI): Path {
|
private fun getCacheFile(uri: URI): Path {
|
||||||
val path = NonsenseGradlePlugin.nonsenseCacheDir.resolve("httpCache")
|
val path = PhytotelmaPlugin.nonsenseCacheDir.resolve("httpCache")
|
||||||
.resolve(uri.host+uri.rawPath) // Use rawPath to ensure ASCII compat (since this will be a filesystem dir)
|
.resolve(uri.host+uri.rawPath) // Use rawPath to ensure ASCII compat (since this will be a filesystem dir)
|
||||||
path.createParentDirectories()
|
path.createParentDirectories()
|
||||||
return path
|
return path
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
package org.ecorous.esnesnon.gradle.ext
|
package org.ecorous.esnesnon.gradle.ext
|
||||||
|
|
||||||
import org.ecorous.esnesnon.gradle.NonsenseGradlePlugin
|
import org.ecorous.esnesnon.gradle.PhytotelmaPlugin
|
||||||
import org.ecorous.esnesnon.gradle.VersionChecker
|
import org.ecorous.esnesnon.gradle.VersionChecker
|
||||||
|
import org.ecorous.esnesnon.gradle.accesswidener.AccessWidener
|
||||||
import org.ecorous.esnesnon.gradle.run.RunConfigGenerator
|
import org.ecorous.esnesnon.gradle.run.RunConfigGenerator
|
||||||
import org.ecorous.esnesnon.nonsense_remapper.NonsenseRemapper
|
import org.ecorous.esnesnon.nonsense_remapper.NonsenseRemapper
|
||||||
import org.ecorous.esnesnon.nonsense_remapper.parser.ProguardParser
|
import org.ecorous.esnesnon.nonsense_remapper.parser.ProguardParser
|
||||||
|
@ -15,8 +16,8 @@ fun Project.minecraft(
|
||||||
parchmentVersion: String = ParchmentProvider.findForMinecraftVersion(version)
|
parchmentVersion: String = ParchmentProvider.findForMinecraftVersion(version)
|
||||||
): Project { // return self to allow for chaining
|
): Project { // return self to allow for chaining
|
||||||
if (VersionChecker.validateVersion(version)) {
|
if (VersionChecker.validateVersion(version)) {
|
||||||
NonsenseGradlePlugin.minecraftVersion = version
|
PhytotelmaPlugin.minecraftVersion = version
|
||||||
NonsenseGradlePlugin.parchmentVersion = parchmentVersion
|
PhytotelmaPlugin.parchmentVersion = parchmentVersion
|
||||||
println("Valid version! $version")
|
println("Valid version! $version")
|
||||||
val clientData = VersionChecker.fetchClientDownload(version)
|
val clientData = VersionChecker.fetchClientDownload(version)
|
||||||
println("Client data: ${clientData.url}")
|
println("Client data: ${clientData.url}")
|
||||||
|
@ -25,16 +26,18 @@ fun Project.minecraft(
|
||||||
val clientJar = VersionChecker.downloadClient(version)
|
val clientJar = VersionChecker.downloadClient(version)
|
||||||
println("Downloaded client!")
|
println("Downloaded client!")
|
||||||
val remappedJar = clientJar.resolveSibling("client-$version-remapped.jar")
|
val remappedJar = clientJar.resolveSibling("client-$version-remapped.jar")
|
||||||
NonsenseGradlePlugin.remappedGameJarPath = remappedJar
|
PhytotelmaPlugin.remappedGameJarPath = remappedJar
|
||||||
println("Time to setup Minecraft!")
|
println("Time to setup Minecraft!")
|
||||||
if (remappedJar.notExists()) {
|
var applyAW = false
|
||||||
|
if (remappedJar.notExists() || AccessWidener.needsUpdate(this)) {
|
||||||
println("Remapping the game...")
|
println("Remapping the game...")
|
||||||
val data = ProguardParser.read(MojmapProvider.get(version, clientJar.resolveSibling("client-$version.txt")).orElseThrow()).reverse()
|
val data = ProguardParser.read(MojmapProvider.get(version, clientJar.resolveSibling("client-$version.txt")).orElseThrow()).reverse()
|
||||||
val paramMappings = ParchmentProvider.getParchment(
|
val paramMappings = ParchmentProvider.getParchment(
|
||||||
version, parchmentVersion,
|
version, parchmentVersion,
|
||||||
NonsenseGradlePlugin.nonsenseCacheDir.resolve("org/parchmentmc/parchment/$version/$parchmentVersion")
|
PhytotelmaPlugin.nonsenseCacheDir.resolve("org/parchmentmc/parchment/$version/$parchmentVersion")
|
||||||
)
|
)
|
||||||
NonsenseRemapper.remap(data, clientJar, remappedJar, true, paramMappings)
|
NonsenseRemapper.remap(data, clientJar, remappedJar, true, paramMappings)
|
||||||
|
applyAW = true
|
||||||
}
|
}
|
||||||
println("Adding dependencies...")
|
println("Adding dependencies...")
|
||||||
dependencies.add("implementation","net.minecrell:terminalconsoleappender:1.2.0")
|
dependencies.add("implementation","net.minecrell:terminalconsoleappender:1.2.0")
|
||||||
|
@ -45,6 +48,14 @@ fun Project.minecraft(
|
||||||
|
|
||||||
println("Generating run configurations...")
|
println("Generating run configurations...")
|
||||||
RunConfigGenerator.generate(this)
|
RunConfigGenerator.generate(this)
|
||||||
|
|
||||||
|
if (applyAW) {
|
||||||
|
project.afterEvaluate {
|
||||||
|
println("Applying accesswideners")
|
||||||
|
AccessWidener.apply(this, remappedJar)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
println("Done!")
|
println("Done!")
|
||||||
} else {
|
} else {
|
||||||
println("Invalid version! $version")
|
println("Invalid version! $version")
|
||||||
|
@ -54,5 +65,5 @@ fun Project.minecraft(
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Project.loader(version: String){
|
fun Project.loader(version: String){
|
||||||
dependencies.add("implementation", "org.ecorous.esnesnon:nonsense-loader:$version")
|
dependencies.add("implementation", "org.ecorous.esnesnon:frogloader:$version")
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ package org.ecorous.esnesnon.gradle.run
|
||||||
|
|
||||||
import com.google.gson.Gson
|
import com.google.gson.Gson
|
||||||
import com.google.gson.JsonObject
|
import com.google.gson.JsonObject
|
||||||
import org.ecorous.esnesnon.gradle.NonsenseGradlePlugin
|
import org.ecorous.esnesnon.gradle.PhytotelmaPlugin
|
||||||
import org.ecorous.esnesnon.gradle.VersionChecker
|
import org.ecorous.esnesnon.gradle.VersionChecker
|
||||||
import org.ecorous.esnesnon.gradle.common.CachingHttpClient
|
import org.ecorous.esnesnon.gradle.common.CachingHttpClient
|
||||||
import java.net.URI
|
import java.net.URI
|
||||||
|
@ -15,8 +15,8 @@ object AssetDownloader {
|
||||||
private const val ASSETS_URL = "https://resources.download.minecraft.net"
|
private const val ASSETS_URL = "https://resources.download.minecraft.net"
|
||||||
|
|
||||||
fun download() {
|
fun download() {
|
||||||
val version = NonsenseGradlePlugin.minecraftVersion
|
val version = PhytotelmaPlugin.minecraftVersion
|
||||||
val path = NonsenseGradlePlugin.nonsenseCacheDir.resolve("assets")
|
val path = PhytotelmaPlugin.nonsenseCacheDir.resolve("assets")
|
||||||
val id = VersionChecker.downloadAssetIndex(version, path.resolve("indexes"))
|
val id = VersionChecker.downloadAssetIndex(version, path.resolve("indexes"))
|
||||||
|
|
||||||
val index = Gson().fromJson(
|
val index = Gson().fromJson(
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package org.ecorous.esnesnon.gradle.run
|
package org.ecorous.esnesnon.gradle.run
|
||||||
|
|
||||||
import org.ecorous.esnesnon.gradle.NonsenseGradlePlugin
|
import org.ecorous.esnesnon.gradle.PhytotelmaPlugin
|
||||||
import org.ecorous.esnesnon.gradle.VersionChecker
|
import org.ecorous.esnesnon.gradle.VersionChecker
|
||||||
import org.ecorous.esnesnon.gradle.common.Env
|
import org.ecorous.esnesnon.gradle.common.Env
|
||||||
import org.ecorous.esnesnon.gradle.run.adapter.EclipseAdapter
|
import org.ecorous.esnesnon.gradle.run.adapter.EclipseAdapter
|
||||||
|
@ -27,15 +27,12 @@ object RunConfigGenerator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val assetPath = NonsenseGradlePlugin.nonsenseCacheDir.resolve(ASSET_DIR).absolute()
|
val assetPath = PhytotelmaPlugin.nonsenseCacheDir.resolve(ASSET_DIR).absolute()
|
||||||
val assetIndexPath = assetPath.resolve("indexes")
|
val assetIndexPath = assetPath.resolve("indexes")
|
||||||
if (assetIndexPath.notExists()) {
|
if (assetIndexPath.notExists()) {
|
||||||
assetIndexPath.createDirectories()
|
assetIndexPath.createDirectories()
|
||||||
}
|
}
|
||||||
val indexId = VersionChecker.downloadAssetIndex(NonsenseGradlePlugin.minecraftVersion, assetIndexPath)
|
val indexId = VersionChecker.downloadAssetIndex(PhytotelmaPlugin.minecraftVersion, assetIndexPath)
|
||||||
|
|
||||||
val runConfigPath = project.rootDir.resolve(".idea").resolve("runConfigurations")
|
|
||||||
runConfigPath.mkdirs()
|
|
||||||
|
|
||||||
for (adapter in ADAPTERS) {
|
for (adapter in ADAPTERS) {
|
||||||
if (!adapter.shouldGenerate())
|
if (!adapter.shouldGenerate())
|
||||||
|
@ -49,7 +46,7 @@ object RunConfigGenerator {
|
||||||
mutableListOf(
|
mutableListOf(
|
||||||
"-Xmx${project.properties.getOrDefault("nonsense.gameHeap", "2048M")}",
|
"-Xmx${project.properties.getOrDefault("nonsense.gameHeap", "2048M")}",
|
||||||
"-Dnonsense.development=true",
|
"-Dnonsense.development=true",
|
||||||
"-Dnonsense.plugin.minecraft.gameJar=${NonsenseGradlePlugin.remappedGameJarPath}",
|
"-Dnonsense.plugin.minecraft.gameJar=${PhytotelmaPlugin.remappedGameJarPath}",
|
||||||
"-Dlog4j2.configurationFile=$log4jPath",
|
"-Dlog4j2.configurationFile=$log4jPath",
|
||||||
"-Dlog4j2.formatMsgLookups=true"
|
"-Dlog4j2.formatMsgLookups=true"
|
||||||
).apply {
|
).apply {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package org.ecorous.esnesnon.gradle.run.task
|
package org.ecorous.esnesnon.gradle.run.task
|
||||||
|
|
||||||
import org.ecorous.esnesnon.gradle.NonsenseGradlePlugin
|
import org.ecorous.esnesnon.gradle.PhytotelmaPlugin
|
||||||
import org.ecorous.esnesnon.gradle.VersionChecker
|
import org.ecorous.esnesnon.gradle.VersionChecker
|
||||||
import org.ecorous.esnesnon.gradle.common.Env
|
import org.ecorous.esnesnon.gradle.common.Env
|
||||||
import org.gradle.api.file.ConfigurableFileCollection
|
import org.gradle.api.file.ConfigurableFileCollection
|
||||||
|
@ -21,13 +21,13 @@ abstract class RunGameTask @Inject constructor(env: Env) : JavaExec() {
|
||||||
private val classpath: ConfigurableFileCollection = project.objects.fileCollection()
|
private val classpath: ConfigurableFileCollection = project.objects.fileCollection()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
group = "nonsense"
|
group = "frog"
|
||||||
val assetPath = NonsenseGradlePlugin.nonsenseCacheDir.resolve("assets").absolute()
|
val assetPath = PhytotelmaPlugin.nonsenseCacheDir.resolve("assets").absolute()
|
||||||
val assetIndexPath = assetPath.resolve("indexes")
|
val assetIndexPath = assetPath.resolve("indexes")
|
||||||
if (assetIndexPath.notExists()) {
|
if (assetIndexPath.notExists()) {
|
||||||
assetIndexPath.createDirectories()
|
assetIndexPath.createDirectories()
|
||||||
}
|
}
|
||||||
val indexId = VersionChecker.downloadAssetIndex(NonsenseGradlePlugin.minecraftVersion, assetIndexPath)
|
val indexId = VersionChecker.downloadAssetIndex(PhytotelmaPlugin.minecraftVersion, assetIndexPath)
|
||||||
val log4jPath = project.rootDir.resolve(".gradle/nonsense-gradle/log4j.xml").toPath().absolute()
|
val log4jPath = project.rootDir.resolve(".gradle/nonsense-gradle/log4j.xml").toPath().absolute()
|
||||||
if (log4jPath.notExists()) {
|
if (log4jPath.notExists()) {
|
||||||
log4jPath.createParentDirectories()
|
log4jPath.createParentDirectories()
|
||||||
|
@ -55,7 +55,7 @@ abstract class RunGameTask @Inject constructor(env: Env) : JavaExec() {
|
||||||
jvmArguments.addAll(
|
jvmArguments.addAll(
|
||||||
"-Xmx${project.properties.getOrDefault("nonsense.gameHeap", "2048M")}",
|
"-Xmx${project.properties.getOrDefault("nonsense.gameHeap", "2048M")}",
|
||||||
"-Dnonsense.development=true",
|
"-Dnonsense.development=true",
|
||||||
"-Dnonsense.plugin.minecraft.gameJar=${NonsenseGradlePlugin.remappedGameJarPath}",
|
"-Dnonsense.plugin.minecraft.gameJar=${PhytotelmaPlugin.remappedGameJarPath}",
|
||||||
"-Dlog4j2.configurationFile=$log4jPath",
|
"-Dlog4j2.configurationFile=$log4jPath",
|
||||||
"-Dlog4j2.formatMsgNoLookups=true",
|
"-Dlog4j2.formatMsgNoLookups=true",
|
||||||
writeArgFile()
|
writeArgFile()
|
||||||
|
|
Loading…
Reference in a new issue