Skip to content

Commit

Permalink
Improved hierarchy
Browse files Browse the repository at this point in the history
Improved hierarchy and process speed
  • Loading branch information
SpartanB312 committed Apr 12, 2023
1 parent b8bc9ec commit 4ba3432
Show file tree
Hide file tree
Showing 7 changed files with 72 additions and 52 deletions.
3 changes: 2 additions & 1 deletion src/main/kotlin/net/spartanb312/grunt/Grunt.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import net.spartanb312.grunt.process.resource.ResourceCache
import net.spartanb312.grunt.utils.logging.Logger
import kotlin.system.measureTimeMillis

const val VERSION = "1.5.6"
const val VERSION = "1.5.7"
const val TYPE = "Stable"
const val AUTHOR = "B_312"
const val GITHUB = "https://github.com/SpartanB312/Grunt"
Expand Down Expand Up @@ -35,6 +35,7 @@ fun main(args: Array<String>) {
Configs.saveConfig(configName)
} catch (ignore: Exception) {
Logger.info("Failed to read config $configName!But we generated a new one.")
Configs.saveConfig(configName)
Logger.info("Type (Y/N) if you want to continue")
if (readLine()?.lowercase() == "n") return
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,30 +1,40 @@
package net.spartanb312.grunt.process.resource
package net.spartanb312.grunt.process.hierarchy

import net.spartanb312.grunt.process.resource.ResourceCache
import net.spartanb312.grunt.utils.logging.Logger
import org.objectweb.asm.tree.ClassNode

class Hierarchy(private val resourceCache: ResourceCache) {
/**
* Fast class hierarchy graph
* Prebuild all class infos
* Faster in most situations
*/
class FastHierarchy(private val resourceCache: ResourceCache) : Hierarchy {

private val hierarchies = mutableMapOf<String, HierarchyInfo>()
// All hierarchy nodes
private val hierarchyNodes = mutableMapOf<String, HierarchyNode>()
val size get() = hierarchyNodes.size

// Subset of hierarchy nodes, only includes hierarchyNode with classNode
private val hierarchies = mutableMapOf<String, HierarchyInfo>()
override val size get() = hierarchyNodes.size

open inner class HierarchyNode {
val parents = mutableSetOf<HierarchyNode>()
val children = mutableSetOf<HierarchyNode>()
var iterated = false
open var missingDependencies = false
}

inner class HierarchyInfo(val classNode: ClassNode) : HierarchyNode() {
var superName: String? = classNode.superName
val interfaces = classNode.interfaces.toMutableList()
val superName: String? get() = classNode.superName
val interfaces: MutableList<String> get() = classNode.interfaces
}

inner class BrokenHierarchyInfo(val name: String) : HierarchyNode() {
override var missingDependencies = true
}

fun build() {
override fun build() {
resourceCache.classes.values.forEach { getHierarchyInfo(it) }
fillParentsInfo()
fillChildrenInfo()
Expand All @@ -39,35 +49,25 @@ class Hierarchy(private val resourceCache: ResourceCache) {
if (info == null) {
val newInfo = HierarchyInfo(classNode)

// SuperName
val superName = newInfo.superName
if (superName != null) {
val clazz = resourceCache.getClassNode(superName)
if (clazz == null) {
Logger.error("Missing dependency $superName")
fun solveParentNode(className: String): HierarchyNode {
val clazz = resourceCache.getClassNode(className)
return if (clazz == null) {
Logger.error("Missing dependency $className")
newInfo.missingDependencies = true
val brokenInfo = BrokenHierarchyInfo(superName)
newInfo.parents.add(brokenInfo)
hierarchyNodes[superName] = brokenInfo
} else {
val parentInfo = buildHierarchy(clazz, newInfo)
newInfo.parents.add(parentInfo)
}
val brokenInfo = BrokenHierarchyInfo(className)
hierarchyNodes[className] = brokenInfo
brokenInfo
} else buildHierarchy(clazz, newInfo)
}

// SuperName
newInfo.superName?.let { superName ->
newInfo.parents.add(solveParentNode(superName))
}

// Interfaces
for (itf in newInfo.interfaces) {
val clazz = resourceCache.getClassNode(itf)
if (clazz == null) {
Logger.error("Missing dependency $itf")
newInfo.missingDependencies = true
val brokenInfo = BrokenHierarchyInfo(itf)
newInfo.parents.add(brokenInfo)
hierarchyNodes[itf] = brokenInfo
} else {
val parentInfo = buildHierarchy(clazz, newInfo)
newInfo.parents.add(parentInfo)
}
newInfo.parents.add(solveParentNode(itf))
}

hierarchies[classNode.name] = newInfo
Expand All @@ -81,31 +81,32 @@ class Hierarchy(private val resourceCache: ResourceCache) {

private fun fillChildrenInfo() {
hierarchies.values.forEach {
fun iterateParents(info: HierarchyNode) {
for (parent in info.parents) {
parent.children.add(it)
iterateParents(parent)
}
for (parent in it.parents) {
parent.children.add(it)
}
iterateParents(it)
}
}

private fun fillParentsInfo() {
hierarchies.values.forEach {
fun iterateParents(info: HierarchyNode) {
for (parent in info.parents.toList()) {
it.parents.add(parent)
if (parent is HierarchyInfo && parent.missingDependencies)
it.missingDependencies = true
iterateParents(parent)
fun iterateParents(current: HierarchyNode): Set<HierarchyNode> {
if (!current.iterated) {
current.iterated = true
val parents = mutableSetOf<HierarchyNode>()
for (p in current.parents) {
if (p is HierarchyInfo && p.missingDependencies)
current.missingDependencies = true
parents.addAll(iterateParents(p))
}
current.parents.addAll(parents)
}
return current.parents
}
iterateParents(it)
}
}

fun isSubType(child: String, father: String): Boolean {
override fun isSubType(child: String, father: String): Boolean {
val childInfo = hierarchyNodes[child] ?: return false
val fatherInfo = hierarchyNodes[father] ?: return false
return if (childInfo.parents.contains(fatherInfo)) true
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package net.spartanb312.grunt.process.hierarchy

interface Hierarchy {
fun build()
fun isSubType(child: String, father: String): Boolean
val size: Int
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package net.spartanb312.grunt.process.resource

import net.spartanb312.grunt.process.hierarchy.Hierarchy
import net.spartanb312.grunt.utils.isInterface
import org.objectweb.asm.ClassWriter

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package net.spartanb312.grunt.process.resource
import com.google.gson.JsonObject
import net.spartanb312.grunt.config.Configs
import net.spartanb312.grunt.config.Configs.saveToFile
import net.spartanb312.grunt.process.hierarchy.FastHierarchy
import net.spartanb312.grunt.utils.corruptCRC32
import net.spartanb312.grunt.utils.isExcluded
import net.spartanb312.grunt.utils.logging.Logger
Expand Down Expand Up @@ -60,7 +61,7 @@ class ResourceCache(private val input: String, private val libs: List<String>) {

fun dumpJar(targetFile: String) = ZipOutputStream(File(targetFile).outputStream()).apply {
Logger.info("Building hierarchies...")
val hierarchy = Hierarchy(this@ResourceCache)
val hierarchy = FastHierarchy(this@ResourceCache)
hierarchy.build()
if (Configs.Settings.corruptOutput) {
Logger.info("Corrupting output...")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import net.spartanb312.grunt.config.Configs
import net.spartanb312.grunt.config.value
import net.spartanb312.grunt.process.resource.NameGenerator
import net.spartanb312.grunt.process.Transformer
import net.spartanb312.grunt.process.resource.Hierarchy
import net.spartanb312.grunt.process.hierarchy.FastHierarchy
import net.spartanb312.grunt.process.resource.ResourceCache
import net.spartanb312.grunt.utils.*
import net.spartanb312.grunt.utils.logging.Logger
Expand All @@ -25,7 +25,7 @@ object MethodRenameTransformer : Transformer("MethodRename") {

override fun ResourceCache.transform() {
Logger.info(" - Renaming methods...")
val hierarchy = Hierarchy(this)
val hierarchy = FastHierarchy(this)
Logger.info(" Building hierarchy graph...")
val buildTime = measureTimeMillis {
hierarchy.build()
Expand Down Expand Up @@ -53,7 +53,7 @@ object MethodRenameTransformer : Transformer("MethodRename") {
mapping[combine(classNode.name, methodNode.name, methodNode.desc)] = newName
// Apply to children
info.children.forEach { c ->
if (c is Hierarchy.HierarchyInfo)
if (c is FastHierarchy.HierarchyInfo)
mapping[combine(c.classNode.name, methodNode.name, methodNode.desc)] =
newName
}
Expand Down Expand Up @@ -87,11 +87,11 @@ object MethodRenameTransformer : Transformer("MethodRename") {

private fun combine(owner: String, name: String, desc: String) = "$owner.$name$desc"

private fun Hierarchy.isPrimeMethod(owner: ClassNode, method: MethodNode): Boolean {
private fun FastHierarchy.isPrimeMethod(owner: ClassNode, method: MethodNode): Boolean {
val ownerInfo = getHierarchyInfo(owner)
if (ownerInfo.missingDependencies) return false
return ownerInfo.parents.none { p ->
if (p is Hierarchy.HierarchyInfo)
if (p is FastHierarchy.HierarchyInfo)
p.classNode.methods.any { it.name == method.name && it.desc == method.desc }
else false//Missing dependencies
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import org.objectweb.asm.tree.VarInsnNode

object ScrambleTransformer : Transformer("ScrambleTransformer") {

private val intensity by value("Intensity", 1)
private val randomName by value("RandomName", false)
private val redirectGetStatic by value("RedirectGetStatic", true)
private val redirectSetStatic by value("RedirectSetStatic", true)
Expand All @@ -33,6 +34,14 @@ object ScrambleTransformer : Transformer("ScrambleTransformer") {
override fun ResourceCache.transform() {
Logger.info(" - Redirecting field calls")
val newClasses = mutableMapOf<ClassNode, ClassNode>() // Owner Companion
var count = 0
repeat(intensity) {
count += process(newClasses)
}
Logger.info(" Redirected $count field calls")
}

private fun ResourceCache.process(newClasses: MutableMap<ClassNode, ClassNode>): Int {
val count = count {
nonExcluded.asSequence()
.filter { it.name.isNotExcludedIn(excludedClasses) }
Expand Down Expand Up @@ -123,7 +132,7 @@ object ScrambleTransformer : Transformer("ScrambleTransformer") {
classes[c.name] = c
}
}.get()
Logger.info(" Redirected $count field calls")
return count
}

private val nativeAnnotationCount = Counter()
Expand Down

0 comments on commit 4ba3432

Please sign in to comment.