commit e4443279d67e61d6f858324a6d745cfb3608bd04
parent 7a77ea6935f8098f6e6835aa4a013f4efd0b3744
Author: rhunk <101876869+rhunk@users.noreply.github.com>
Date:   Sun,  8 Oct 2023 18:04:34 +0200

refactor: mapper

Diffstat:
Mcore/src/main/kotlin/me/rhunk/snapenhance/core/bridge/wrapper/MappingsWrapper.kt | 1-
Mmapper/src/main/kotlin/me/rhunk/snapenhance/mapper/AbstractClassMapper.kt | 14+++++++++-----
Mmapper/src/main/kotlin/me/rhunk/snapenhance/mapper/Mapper.kt | 21---------------------
Mmapper/src/main/kotlin/me/rhunk/snapenhance/mapper/impl/BCryptClassMapper.kt | 39++++++++++++++++++++-------------------
Mmapper/src/main/kotlin/me/rhunk/snapenhance/mapper/impl/CallbackMapper.kt | 29+++++++++++++++--------------
Mmapper/src/main/kotlin/me/rhunk/snapenhance/mapper/impl/CompositeConfigurationProviderMapper.kt | 73+++++++++++++++++++++++++++++++++++++------------------------------------
Mmapper/src/main/kotlin/me/rhunk/snapenhance/mapper/impl/DefaultMediaItemMapper.kt | 21+++++++++++----------
Dmapper/src/main/kotlin/me/rhunk/snapenhance/mapper/impl/EnumMapper.kt | 25-------------------------
Mmapper/src/main/kotlin/me/rhunk/snapenhance/mapper/impl/FriendRelationshipChangerMapper.kt | 32+++++++++++++++++---------------
Mmapper/src/main/kotlin/me/rhunk/snapenhance/mapper/impl/FriendsFeedEventDispatcherMapper.kt | 31++++++++++++++++---------------
Mmapper/src/main/kotlin/me/rhunk/snapenhance/mapper/impl/MediaQualityLevelProviderMapper.kt | 43++++++++++++++++++++++++++++++-------------
Mmapper/src/main/kotlin/me/rhunk/snapenhance/mapper/impl/OperaPageViewControllerMapper.kt | 67++++++++++++++++++++++++++++++++++---------------------------------
Mmapper/src/main/kotlin/me/rhunk/snapenhance/mapper/impl/PlatformAnalyticsCreatorMapper.kt | 25+++++++++++++------------
Mmapper/src/main/kotlin/me/rhunk/snapenhance/mapper/impl/PlusSubscriptionMapper.kt | 33+++++++++++++++++----------------
Mmapper/src/main/kotlin/me/rhunk/snapenhance/mapper/impl/ScCameraSettingsMapper.kt | 19++++++++++---------
Mmapper/src/main/kotlin/me/rhunk/snapenhance/mapper/impl/ScoreUpdateMapper.kt | 29+++++++++++++++--------------
Mmapper/src/main/kotlin/me/rhunk/snapenhance/mapper/impl/StoryBoostStateMapper.kt | 19++++++++++---------
Mmapper/src/main/kotlin/me/rhunk/snapenhance/mapper/impl/ViewBinderMapper.kt | 44+++++++++++++++++++++++---------------------
Mmapper/src/test/kotlin/me/rhunk/snapenhance/mapper/tests/TestMappings.kt | 3+--
19 files changed, 278 insertions(+), 290 deletions(-)

diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/core/bridge/wrapper/MappingsWrapper.kt b/core/src/main/kotlin/me/rhunk/snapenhance/core/bridge/wrapper/MappingsWrapper.kt @@ -21,7 +21,6 @@ class MappingsWrapper : FileLoaderWrapper(BridgeFileType.MAPPINGS, "{}".toByteAr CallbackMapper::class, DefaultMediaItemMapper::class, MediaQualityLevelProviderMapper::class, - EnumMapper::class, OperaPageViewControllerMapper::class, PlatformAnalyticsCreatorMapper::class, PlusSubscriptionMapper::class, diff --git a/mapper/src/main/kotlin/me/rhunk/snapenhance/mapper/AbstractClassMapper.kt b/mapper/src/main/kotlin/me/rhunk/snapenhance/mapper/AbstractClassMapper.kt @@ -1,9 +1,13 @@ package me.rhunk.snapenhance.mapper -import kotlin.reflect.KClass +abstract class AbstractClassMapper { + private val mappers = mutableListOf<MapperContext.() -> Unit>() -abstract class AbstractClassMapper( - vararg val dependsOn: KClass<out AbstractClassMapper> = arrayOf() -) { - abstract fun run(context: MapperContext) + fun mapper(task: MapperContext.() -> Unit) { + mappers.add(task) + } + + fun run(context: MapperContext) { + mappers.forEach { it(context) } + } } \ No newline at end of file diff --git a/mapper/src/main/kotlin/me/rhunk/snapenhance/mapper/Mapper.kt b/mapper/src/main/kotlin/me/rhunk/snapenhance/mapper/Mapper.kt @@ -56,30 +56,9 @@ class Mapper( runBlocking { withContext(Dispatchers.IO) { - val finishedJobs = mutableListOf<Class<*>>() - val dependentsMappers = mappers.filter { it.dependsOn.isNotEmpty() } - - fun onJobFinished(mapper: AbstractClassMapper) { - finishedJobs.add(mapper.javaClass) - - dependentsMappers.filter { it -> - !finishedJobs.contains(it.javaClass) && - it.dependsOn.all { - finishedJobs.contains(it.java) - } - }.forEach { - launch { - it.run(context) - onJobFinished(it) - } - } - } - mappers.forEach { mapper -> - if (mapper.dependsOn.isNotEmpty()) return@forEach launch { mapper.run(context) - onJobFinished(mapper) } } } diff --git a/mapper/src/main/kotlin/me/rhunk/snapenhance/mapper/impl/BCryptClassMapper.kt b/mapper/src/main/kotlin/me/rhunk/snapenhance/mapper/impl/BCryptClassMapper.kt @@ -1,34 +1,35 @@ package me.rhunk.snapenhance.mapper.impl import me.rhunk.snapenhance.mapper.AbstractClassMapper -import me.rhunk.snapenhance.mapper.MapperContext import me.rhunk.snapenhance.mapper.ext.getClassName import me.rhunk.snapenhance.mapper.ext.getStaticConstructor import me.rhunk.snapenhance.mapper.ext.isFinal import org.jf.dexlib2.iface.instruction.formats.ArrayPayload class BCryptClassMapper : AbstractClassMapper() { - override fun run(context: MapperContext) { - for (clazz in context.classes) { - if (!clazz.isFinal()) continue + init { + mapper { + for (clazz in classes) { + if (!clazz.isFinal()) continue - val isBcryptClass = clazz.getStaticConstructor()?.let { constructor -> - constructor.implementation?.instructions?.filterIsInstance<ArrayPayload>()?.any { it.arrayElements.size == 18 && it.arrayElements[0] == 608135816 } - } - - if (isBcryptClass == true) { - val hashMethod = clazz.methods.first { - it.parameterTypes.size == 2 && - it.parameterTypes[0] == "Ljava/lang/String;" && - it.parameterTypes[1] == "Ljava/lang/String;" && - it.returnType == "Ljava/lang/String;" + val isBcryptClass = clazz.getStaticConstructor()?.let { constructor -> + constructor.implementation?.instructions?.filterIsInstance<ArrayPayload>()?.any { it.arrayElements.size == 18 && it.arrayElements[0] == 608135816 } } - context.addMapping("BCrypt", - "class" to clazz.getClassName(), - "hashMethod" to hashMethod.name - ) - return + if (isBcryptClass == true) { + val hashMethod = clazz.methods.first { + it.parameterTypes.size == 2 && + it.parameterTypes[0] == "Ljava/lang/String;" && + it.parameterTypes[1] == "Ljava/lang/String;" && + it.returnType == "Ljava/lang/String;" + } + + addMapping("BCrypt", + "class" to clazz.getClassName(), + "hashMethod" to hashMethod.name + ) + return@mapper + } } } } diff --git a/mapper/src/main/kotlin/me/rhunk/snapenhance/mapper/impl/CallbackMapper.kt b/mapper/src/main/kotlin/me/rhunk/snapenhance/mapper/impl/CallbackMapper.kt @@ -1,28 +1,29 @@ package me.rhunk.snapenhance.mapper.impl import me.rhunk.snapenhance.mapper.AbstractClassMapper -import me.rhunk.snapenhance.mapper.MapperContext import me.rhunk.snapenhance.mapper.ext.getClassName import me.rhunk.snapenhance.mapper.ext.getSuperClassName import me.rhunk.snapenhance.mapper.ext.isFinal class CallbackMapper : AbstractClassMapper() { - override fun run(context: MapperContext) { - val callbackClasses = context.classes.filter { clazz -> - if (clazz.superclass == null) return@filter false + init { + mapper { + val callbackClasses = classes.filter { clazz -> + if (clazz.superclass == null) return@filter false - val superclassName = clazz.getSuperClassName()!! - if ((!superclassName.endsWith("Callback") && !superclassName.endsWith("Delegate")) - || superclassName.endsWith("\$Callback")) return@filter false + val superclassName = clazz.getSuperClassName()!! + if ((!superclassName.endsWith("Callback") && !superclassName.endsWith("Delegate")) + || superclassName.endsWith("\$Callback")) return@filter false - if (clazz.getClassName().endsWith("\$CppProxy")) return@filter false + if (clazz.getClassName().endsWith("\$CppProxy")) return@filter false - val superClass = context.getClass(clazz.superclass) ?: return@filter false - !superClass.isFinal() - }.map { - it.getSuperClassName()!!.substringAfterLast("/") to it.getClassName() - } + val superClass = getClass(clazz.superclass) ?: return@filter false + !superClass.isFinal() + }.map { + it.getSuperClassName()!!.substringAfterLast("/") to it.getClassName() + } - context.addMapping("callbacks", *callbackClasses.toTypedArray()) + addMapping("callbacks", *callbackClasses.toTypedArray()) + } } } \ No newline at end of file diff --git a/mapper/src/main/kotlin/me/rhunk/snapenhance/mapper/impl/CompositeConfigurationProviderMapper.kt b/mapper/src/main/kotlin/me/rhunk/snapenhance/mapper/impl/CompositeConfigurationProviderMapper.kt @@ -1,7 +1,6 @@ package me.rhunk.snapenhance.mapper.impl import me.rhunk.snapenhance.mapper.AbstractClassMapper -import me.rhunk.snapenhance.mapper.MapperContext import me.rhunk.snapenhance.mapper.ext.findConstString import me.rhunk.snapenhance.mapper.ext.getClassName import me.rhunk.snapenhance.mapper.ext.hasStaticConstructorString @@ -9,47 +8,49 @@ import me.rhunk.snapenhance.mapper.ext.isEnum import java.lang.reflect.Modifier class CompositeConfigurationProviderMapper : AbstractClassMapper() { - override fun run(context: MapperContext) { - for (classDef in context.classes) { - val constructor = classDef.methods.firstOrNull { it.name == "<init>" } ?: continue - if (constructor.parameterTypes.size == 0 || constructor.parameterTypes[0] != "Ljava/util/List;") continue - if (constructor.implementation?.findConstString("CompositeConfigurationProvider") != true) continue + init { + mapper { + for (classDef in classes) { + val constructor = classDef.methods.firstOrNull { it.name == "<init>" } ?: continue + if (constructor.parameterTypes.size == 0 || constructor.parameterTypes[0] != "Ljava/util/List;") continue + if (constructor.implementation?.findConstString("CompositeConfigurationProvider") != true) continue - val getPropertyMethod = classDef.methods.first { method -> - method.parameterTypes.size > 1 && - method.returnType == "Ljava/lang/Object;" && - context.getClass(method.parameterTypes[0])?.interfaces?.contains("Ljava/io/Serializable;") == true && - context.getClass(method.parameterTypes[1])?.let { it.isEnum() && it.hasStaticConstructorString("BOOLEAN") } == true - } + val getPropertyMethod = classDef.methods.first { method -> + method.parameterTypes.size > 1 && + method.returnType == "Ljava/lang/Object;" && + getClass(method.parameterTypes[0])?.interfaces?.contains("Ljava/io/Serializable;") == true && + getClass(method.parameterTypes[1])?.let { it.isEnum() && it.hasStaticConstructorString("BOOLEAN") } == true + } - val configEnumInterface = context.getClass(getPropertyMethod.parameterTypes[0])!! - val enumType = context.getClass(getPropertyMethod.parameterTypes[1])!! + val configEnumInterface = getClass(getPropertyMethod.parameterTypes[0])!! + val enumType = getClass(getPropertyMethod.parameterTypes[1])!! - val observePropertyMethod = classDef.methods.first { - it.parameterTypes.size > 2 && - it.parameterTypes[0] == configEnumInterface.type && - it.parameterTypes[1] == "Ljava/lang/String;" && - it.parameterTypes[2] == enumType.type - } + val observePropertyMethod = classDef.methods.first { + it.parameterTypes.size > 2 && + it.parameterTypes[0] == configEnumInterface.type && + it.parameterTypes[1] == "Ljava/lang/String;" && + it.parameterTypes[2] == enumType.type + } - val enumGetDefaultValueMethod = configEnumInterface.methods.first { context.getClass(it.returnType)?.interfaces?.contains("Ljava/io/Serializable;") == true } - val defaultValueField = context.getClass(enumGetDefaultValueMethod.returnType)!!.fields.first { - Modifier.isFinal(it.accessFlags) && - Modifier.isPublic(it.accessFlags) && - it.type == "Ljava/lang/Object;" - } + val enumGetDefaultValueMethod = configEnumInterface.methods.first { getClass(it.returnType)?.interfaces?.contains("Ljava/io/Serializable;") == true } + val defaultValueField = getClass(enumGetDefaultValueMethod.returnType)!!.fields.first { + Modifier.isFinal(it.accessFlags) && + Modifier.isPublic(it.accessFlags) && + it.type == "Ljava/lang/Object;" + } - context.addMapping("CompositeConfigurationProvider", - "class" to classDef.getClassName(), - "observeProperty" to observePropertyMethod.name, - "getProperty" to getPropertyMethod.name, - "enum" to mapOf( - "class" to configEnumInterface.getClassName(), - "getValue" to enumGetDefaultValueMethod.name, - "defaultValueField" to defaultValueField.name + addMapping("CompositeConfigurationProvider", + "class" to classDef.getClassName(), + "observeProperty" to observePropertyMethod.name, + "getProperty" to getPropertyMethod.name, + "enum" to mapOf( + "class" to configEnumInterface.getClassName(), + "getValue" to enumGetDefaultValueMethod.name, + "defaultValueField" to defaultValueField.name + ) ) - ) - return + return@mapper + } } } } \ No newline at end of file diff --git a/mapper/src/main/kotlin/me/rhunk/snapenhance/mapper/impl/DefaultMediaItemMapper.kt b/mapper/src/main/kotlin/me/rhunk/snapenhance/mapper/impl/DefaultMediaItemMapper.kt @@ -1,23 +1,24 @@ package me.rhunk.snapenhance.mapper.impl import me.rhunk.snapenhance.mapper.AbstractClassMapper -import me.rhunk.snapenhance.mapper.MapperContext import me.rhunk.snapenhance.mapper.ext.getClassName import me.rhunk.snapenhance.mapper.ext.isAbstract class DefaultMediaItemMapper : AbstractClassMapper() { - override fun run(context: MapperContext) { - for (clazz in context.classes) { - val superClass = context.getClass(clazz.superclass) ?: continue + init { + mapper { + for (clazz in classes) { + val superClass = getClass(clazz.superclass) ?: continue - if (!superClass.isAbstract() || superClass.interfaces.isEmpty() || superClass.interfaces[0] != "Ljava/lang/Comparable;") continue - if (clazz.methods.none { it.returnType == "Landroid/net/Uri;" }) continue + if (!superClass.isAbstract() || superClass.interfaces.isEmpty() || superClass.interfaces[0] != "Ljava/lang/Comparable;") continue + if (clazz.methods.none { it.returnType == "Landroid/net/Uri;" }) continue - val constructorParameters = clazz.directMethods.firstOrNull { it.name == "<init>" }?.parameterTypes ?: continue - if (constructorParameters.size < 6 || constructorParameters[5] != "J") continue + val constructorParameters = clazz.directMethods.firstOrNull { it.name == "<init>" }?.parameterTypes ?: continue + if (constructorParameters.size < 6 || constructorParameters[5] != "J") continue - context.addMapping("DefaultMediaItem", clazz.getClassName()) - return + addMapping("DefaultMediaItem", clazz.getClassName()) + return@mapper + } } } } \ No newline at end of file diff --git a/mapper/src/main/kotlin/me/rhunk/snapenhance/mapper/impl/EnumMapper.kt b/mapper/src/main/kotlin/me/rhunk/snapenhance/mapper/impl/EnumMapper.kt @@ -1,24 +0,0 @@ -package me.rhunk.snapenhance.mapper.impl - -import me.rhunk.snapenhance.mapper.AbstractClassMapper -import me.rhunk.snapenhance.mapper.MapperContext -import me.rhunk.snapenhance.mapper.ext.getClassName -import me.rhunk.snapenhance.mapper.ext.hasStaticConstructorString -import me.rhunk.snapenhance.mapper.ext.isEnum - -class EnumMapper : AbstractClassMapper() { - override fun run(context: MapperContext) { - lateinit var enumQualityLevel : String - - for (enumClass in context.classes) { - if (!enumClass.isEnum()) continue - - if (enumClass.hasStaticConstructorString("LEVEL_MAX")) { - enumQualityLevel = enumClass.getClassName() - break; - } - } - - context.addMapping("EnumQualityLevel", enumQualityLevel) - } -}- \ No newline at end of file diff --git a/mapper/src/main/kotlin/me/rhunk/snapenhance/mapper/impl/FriendRelationshipChangerMapper.kt b/mapper/src/main/kotlin/me/rhunk/snapenhance/mapper/impl/FriendRelationshipChangerMapper.kt @@ -1,27 +1,29 @@ package me.rhunk.snapenhance.mapper.impl import me.rhunk.snapenhance.mapper.AbstractClassMapper -import me.rhunk.snapenhance.mapper.MapperContext import me.rhunk.snapenhance.mapper.ext.findConstString import me.rhunk.snapenhance.mapper.ext.getClassName import me.rhunk.snapenhance.mapper.ext.isEnum class FriendRelationshipChangerMapper : AbstractClassMapper() { - override fun run(context: MapperContext) { - for (classDef in context.classes) { - classDef.methods.firstOrNull { it.name == "<init>" }?.implementation?.findConstString("FriendRelationshipChangerImpl")?.takeIf { it } ?: continue - val addFriendMethod = classDef.methods.first { - it.parameterTypes.size > 4 && - context.getClass(it.parameterTypes[1])?.isEnum() == true && - context.getClass(it.parameterTypes[2])?.isEnum() == true && - context.getClass(it.parameterTypes[3])?.isEnum() == true && - it.parameters[4].type == "Ljava/lang/String;" - } + init { + mapper { + for (classDef in classes) { + classDef.methods.firstOrNull { it.name == "<init>" }?.implementation?.findConstString("FriendRelationshipChangerImpl")?.takeIf { it } ?: continue + val addFriendMethod = classDef.methods.first { + it.parameterTypes.size > 4 && + getClass(it.parameterTypes[1])?.isEnum() == true && + getClass(it.parameterTypes[2])?.isEnum() == true && + getClass(it.parameterTypes[3])?.isEnum() == true && + it.parameters[4].type == "Ljava/lang/String;" + } - context.addMapping("FriendRelationshipChanger", - "class" to classDef.getClassName(), - "addFriendMethod" to addFriendMethod.name - ) + addMapping("FriendRelationshipChanger", + "class" to classDef.getClassName(), + "addFriendMethod" to addFriendMethod.name + ) + return@mapper + } } } } \ No newline at end of file diff --git a/mapper/src/main/kotlin/me/rhunk/snapenhance/mapper/impl/FriendsFeedEventDispatcherMapper.kt b/mapper/src/main/kotlin/me/rhunk/snapenhance/mapper/impl/FriendsFeedEventDispatcherMapper.kt @@ -1,28 +1,29 @@ package me.rhunk.snapenhance.mapper.impl import me.rhunk.snapenhance.mapper.AbstractClassMapper -import me.rhunk.snapenhance.mapper.MapperContext import me.rhunk.snapenhance.mapper.ext.findConstString import me.rhunk.snapenhance.mapper.ext.getClassName class FriendsFeedEventDispatcherMapper : AbstractClassMapper() { - override fun run(context: MapperContext) { - for (clazz in context.classes) { - if (clazz.methods.count { it.name == "onClickFeed" || it.name == "onItemLongPress" } != 2) continue - val onItemLongPress = clazz.methods.first { it.name == "onItemLongPress" } - val viewHolderContainerClass = context.getClass(onItemLongPress.parameterTypes[0]) ?: continue + init { + mapper { + for (clazz in classes) { + if (clazz.methods.count { it.name == "onClickFeed" || it.name == "onItemLongPress" } != 2) continue + val onItemLongPress = clazz.methods.first { it.name == "onItemLongPress" } + val viewHolderContainerClass = getClass(onItemLongPress.parameterTypes[0]) ?: continue - val viewModelField = viewHolderContainerClass.fields.firstOrNull { field -> - val typeClass = context.getClass(field.type) ?: return@firstOrNull false - typeClass.methods.firstOrNull {it.name == "toString"}?.implementation?.findConstString("FriendFeedItemViewModel", contains = true) == true - }?.name ?: continue + val viewModelField = viewHolderContainerClass.fields.firstOrNull { field -> + val typeClass = getClass(field.type) ?: return@firstOrNull false + typeClass.methods.firstOrNull {it.name == "toString"}?.implementation?.findConstString("FriendFeedItemViewModel", contains = true) == true + }?.name ?: continue - context.addMapping("FriendsFeedEventDispatcher", - "class" to clazz.getClassName(), - "viewModelField" to viewModelField - ) - return + addMapping("FriendsFeedEventDispatcher", + "class" to clazz.getClassName(), + "viewModelField" to viewModelField + ) + return@mapper + } } } } \ No newline at end of file diff --git a/mapper/src/main/kotlin/me/rhunk/snapenhance/mapper/impl/MediaQualityLevelProviderMapper.kt b/mapper/src/main/kotlin/me/rhunk/snapenhance/mapper/impl/MediaQualityLevelProviderMapper.kt @@ -1,25 +1,42 @@ package me.rhunk.snapenhance.mapper.impl import me.rhunk.snapenhance.mapper.AbstractClassMapper -import me.rhunk.snapenhance.mapper.MapperContext import me.rhunk.snapenhance.mapper.ext.getClassName +import me.rhunk.snapenhance.mapper.ext.hasStaticConstructorString import me.rhunk.snapenhance.mapper.ext.isAbstract +import me.rhunk.snapenhance.mapper.ext.isEnum import org.jf.dexlib2.AccessFlags -class MediaQualityLevelProviderMapper : AbstractClassMapper(EnumMapper::class) { - override fun run(context: MapperContext) { - val mediaQualityLevelClass = context.getStringMapping("EnumQualityLevel") ?: return +class MediaQualityLevelProviderMapper : AbstractClassMapper() { + init { + var enumQualityLevel : String? = null - for (clazz in context.classes) { - if (!clazz.isAbstract()) continue - if (clazz.fields.none { it.accessFlags and AccessFlags.TRANSIENT.value != 0 }) continue + mapper { + for (enumClass in classes) { + if (!enumClass.isEnum()) continue - clazz.methods.firstOrNull { it.returnType == "L$mediaQualityLevelClass;" }?.let { - context.addMapping("MediaQualityLevelProvider", - "class" to clazz.getClassName(), - "method" to it.name - ) - return + if (enumClass.hasStaticConstructorString("LEVEL_MAX")) { + enumQualityLevel = enumClass.getClassName() + break; + } + } + addMapping("EnumQualityLevel", enumQualityLevel ?: return@mapper) + } + + mapper { + if (enumQualityLevel == null) return@mapper + + for (clazz in classes) { + if (!clazz.isAbstract()) continue + if (clazz.fields.none { it.accessFlags and AccessFlags.TRANSIENT.value != 0 }) continue + + clazz.methods.firstOrNull { it.returnType == "L$enumQualityLevel;" }?.let { + addMapping("MediaQualityLevelProvider", + "class" to clazz.getClassName(), + "method" to it.name + ) + return@mapper + } } } } diff --git a/mapper/src/main/kotlin/me/rhunk/snapenhance/mapper/impl/OperaPageViewControllerMapper.kt b/mapper/src/main/kotlin/me/rhunk/snapenhance/mapper/impl/OperaPageViewControllerMapper.kt @@ -1,7 +1,6 @@ package me.rhunk.snapenhance.mapper.impl import me.rhunk.snapenhance.mapper.AbstractClassMapper -import me.rhunk.snapenhance.mapper.MapperContext import me.rhunk.snapenhance.mapper.ext.getClassName import me.rhunk.snapenhance.mapper.ext.hasConstructorString import me.rhunk.snapenhance.mapper.ext.hasStaticConstructorString @@ -9,45 +8,47 @@ import me.rhunk.snapenhance.mapper.ext.isAbstract import me.rhunk.snapenhance.mapper.ext.isEnum class OperaPageViewControllerMapper : AbstractClassMapper() { - override fun run(context: MapperContext) { - for (clazz in context.classes) { - if (!clazz.isAbstract()) continue - if (!clazz.hasConstructorString("OperaPageViewController") || !clazz.hasStaticConstructorString("ad_product_type")) { - continue - } + init { + mapper { + for (clazz in classes) { + if (!clazz.isAbstract()) continue + if (!clazz.hasConstructorString("OperaPageViewController") || !clazz.hasStaticConstructorString("ad_product_type")) { + continue + } - val viewStateField = clazz.fields.first { field -> - val fieldClass = context.getClass(field.type) ?: return@first false - fieldClass.isEnum() && fieldClass.hasStaticConstructorString("FULLY_DISPLAYED") - } + val viewStateField = clazz.fields.first { field -> + val fieldClass = getClass(field.type) ?: return@first false + fieldClass.isEnum() && fieldClass.hasStaticConstructorString("FULLY_DISPLAYED") + } - val layerListField = clazz.fields.first { it.type == "Ljava/util/ArrayList;" } + val layerListField = clazz.fields.first { it.type == "Ljava/util/ArrayList;" } - val onDisplayStateChange = clazz.methods.first { - if (it.returnType != "V" || it.parameterTypes.size != 1) return@first false - val firstParameterType = context.getClass(it.parameterTypes[0]) ?: return@first false - //check if the class contains a field with the enumViewStateClass type - firstParameterType.fields.any { field -> - field.type == viewStateField.type + val onDisplayStateChange = clazz.methods.first { + if (it.returnType != "V" || it.parameterTypes.size != 1) return@first false + val firstParameterType = getClass(it.parameterTypes[0]) ?: return@first false + //check if the class contains a field with the enumViewStateClass type + firstParameterType.fields.any { field -> + field.type == viewStateField.type + } } - } - val onDisplayStateChangeGesture = clazz.methods.first { - if (it.returnType != "V" || it.parameterTypes.size != 2) return@first false - val firstParameterType = context.getClass(it.parameterTypes[0]) ?: return@first false - val secondParameterType = context.getClass(it.parameterTypes[1]) ?: return@first false - firstParameterType.isEnum() && secondParameterType.isEnum() - } + val onDisplayStateChangeGesture = clazz.methods.first { + if (it.returnType != "V" || it.parameterTypes.size != 2) return@first false + val firstParameterType = getClass(it.parameterTypes[0]) ?: return@first false + val secondParameterType = getClass(it.parameterTypes[1]) ?: return@first false + firstParameterType.isEnum() && secondParameterType.isEnum() + } - context.addMapping("OperaPageViewController", - "class" to clazz.getClassName(), - "viewStateField" to viewStateField.name, - "layerListField" to layerListField.name, - "onDisplayStateChange" to onDisplayStateChange.name, - "onDisplayStateChangeGesture" to onDisplayStateChangeGesture.name - ) + addMapping("OperaPageViewController", + "class" to clazz.getClassName(), + "viewStateField" to viewStateField.name, + "layerListField" to layerListField.name, + "onDisplayStateChange" to onDisplayStateChange.name, + "onDisplayStateChangeGesture" to onDisplayStateChangeGesture.name + ) - return + return@mapper + } } } } \ No newline at end of file diff --git a/mapper/src/main/kotlin/me/rhunk/snapenhance/mapper/impl/PlatformAnalyticsCreatorMapper.kt b/mapper/src/main/kotlin/me/rhunk/snapenhance/mapper/impl/PlatformAnalyticsCreatorMapper.kt @@ -1,25 +1,26 @@ package me.rhunk.snapenhance.mapper.impl import me.rhunk.snapenhance.mapper.AbstractClassMapper -import me.rhunk.snapenhance.mapper.MapperContext import me.rhunk.snapenhance.mapper.ext.findConstString import me.rhunk.snapenhance.mapper.ext.getClassName import me.rhunk.snapenhance.mapper.ext.getStaticConstructor import me.rhunk.snapenhance.mapper.ext.isEnum class PlatformAnalyticsCreatorMapper : AbstractClassMapper() { - override fun run(context: MapperContext) { - for (clazz in context.classes) { - val firstConstructor = clazz.directMethods.firstOrNull { it.name == "<init>" } ?: continue - // 47 is the number of parameters of the constructor - // it may change in future versions - if (firstConstructor.parameters.size != 47) continue - val firstParameterClass = context.getClass(firstConstructor.parameterTypes[0]) ?: continue - if (!firstParameterClass.isEnum()) continue - if (firstParameterClass.getStaticConstructor()?.implementation?.findConstString("IN_APP_NOTIFICATION") != true) continue + init { + mapper { + for (clazz in classes) { + val firstConstructor = clazz.directMethods.firstOrNull { it.name == "<init>" } ?: continue + // 47 is the number of parameters of the constructor + // it may change in future versions + if (firstConstructor.parameters.size != 47) continue + val firstParameterClass = getClass(firstConstructor.parameterTypes[0]) ?: continue + if (!firstParameterClass.isEnum()) continue + if (firstParameterClass.getStaticConstructor()?.implementation?.findConstString("IN_APP_NOTIFICATION") != true) continue - context.addMapping("PlatformAnalyticsCreator", clazz.getClassName()) - return + addMapping("PlatformAnalyticsCreator", clazz.getClassName()) + return@mapper + } } } } \ No newline at end of file diff --git a/mapper/src/main/kotlin/me/rhunk/snapenhance/mapper/impl/PlusSubscriptionMapper.kt b/mapper/src/main/kotlin/me/rhunk/snapenhance/mapper/impl/PlusSubscriptionMapper.kt @@ -1,28 +1,29 @@ package me.rhunk.snapenhance.mapper.impl import me.rhunk.snapenhance.mapper.AbstractClassMapper -import me.rhunk.snapenhance.mapper.MapperContext import me.rhunk.snapenhance.mapper.ext.findConstString import me.rhunk.snapenhance.mapper.ext.getClassName class PlusSubscriptionMapper : AbstractClassMapper(){ - override fun run(context: MapperContext) { - for (clazz in context.classes) { - if (clazz.directMethods.filter { it.name == "<init>" }.none { - it.parameters.size == 4 && - it.parameterTypes[0] == "I" && - it.parameterTypes[1] == "I" && - it.parameterTypes[2] == "J" && - it.parameterTypes[3] == "J" - }) continue + init { + mapper { + for (clazz in classes) { + if (clazz.directMethods.filter { it.name == "<init>" }.none { + it.parameters.size == 4 && + it.parameterTypes[0] == "I" && + it.parameterTypes[1] == "I" && + it.parameterTypes[2] == "J" && + it.parameterTypes[3] == "J" + }) continue - val isPlusSubscriptionInfoClass = clazz.virtualMethods.firstOrNull { it.name == "toString" }?.implementation?.let { - it.findConstString("SubscriptionInfo", contains = true) && it.findConstString("expirationTimeMillis", contains = true) - } + val isPlusSubscriptionInfoClass = clazz.virtualMethods.firstOrNull { it.name == "toString" }?.implementation?.let { + it.findConstString("SubscriptionInfo", contains = true) && it.findConstString("expirationTimeMillis", contains = true) + } - if (isPlusSubscriptionInfoClass == true) { - context.addMapping("SubscriptionInfoClass", clazz.getClassName()) - return + if (isPlusSubscriptionInfoClass == true) { + addMapping("SubscriptionInfoClass", clazz.getClassName()) + return@mapper + } } } } diff --git a/mapper/src/main/kotlin/me/rhunk/snapenhance/mapper/impl/ScCameraSettingsMapper.kt b/mapper/src/main/kotlin/me/rhunk/snapenhance/mapper/impl/ScCameraSettingsMapper.kt @@ -1,22 +1,23 @@ package me.rhunk.snapenhance.mapper.impl import me.rhunk.snapenhance.mapper.AbstractClassMapper -import me.rhunk.snapenhance.mapper.MapperContext import me.rhunk.snapenhance.mapper.ext.findConstString import me.rhunk.snapenhance.mapper.ext.getClassName import me.rhunk.snapenhance.mapper.ext.getStaticConstructor import me.rhunk.snapenhance.mapper.ext.isEnum class ScCameraSettingsMapper : AbstractClassMapper() { - override fun run(context: MapperContext) { - for (clazz in context.classes) { - val firstConstructor = clazz.directMethods.firstOrNull { it.name == "<init>" } ?: continue - if (firstConstructor.parameterTypes.size < 27) continue - val firstParameter = context.getClass(firstConstructor.parameterTypes[0]) ?: continue - if (!firstParameter.isEnum() || firstParameter.getStaticConstructor()?.implementation?.findConstString("CONTINUOUS_PICTURE") != true) continue + init { + mapper { + for (clazz in classes) { + val firstConstructor = clazz.directMethods.firstOrNull { it.name == "<init>" } ?: continue + if (firstConstructor.parameterTypes.size < 27) continue + val firstParameter = getClass(firstConstructor.parameterTypes[0]) ?: continue + if (!firstParameter.isEnum() || firstParameter.getStaticConstructor()?.implementation?.findConstString("CONTINUOUS_PICTURE") != true) continue - context.addMapping("ScCameraSettings", clazz.getClassName()) - return + addMapping("ScCameraSettings", clazz.getClassName()) + return@mapper + } } } } \ No newline at end of file diff --git a/mapper/src/main/kotlin/me/rhunk/snapenhance/mapper/impl/ScoreUpdateMapper.kt b/mapper/src/main/kotlin/me/rhunk/snapenhance/mapper/impl/ScoreUpdateMapper.kt @@ -1,25 +1,26 @@ package me.rhunk.snapenhance.mapper.impl import me.rhunk.snapenhance.mapper.AbstractClassMapper -import me.rhunk.snapenhance.mapper.MapperContext import me.rhunk.snapenhance.mapper.ext.findConstString import me.rhunk.snapenhance.mapper.ext.getClassName class ScoreUpdateMapper : AbstractClassMapper() { - override fun run(context: MapperContext) { - for (classDef in context.classes) { - classDef.methods.firstOrNull { - it.name == "<init>" && - it.parameterTypes.size > 4 && - it.parameterTypes[1] == "Ljava/lang/Long;" && - it.parameterTypes[3] == "Ljava/util/Collection;" - } ?: continue - if (classDef.methods.firstOrNull { - it.name == "toString" - }?.implementation?.findConstString("Friend.sq:selectFriendUserScoresNeedToUpdate") != true) continue + init { + mapper { + for (classDef in classes) { + classDef.methods.firstOrNull { + it.name == "<init>" && + it.parameterTypes.size > 4 && + it.parameterTypes[1] == "Ljava/lang/Long;" && + it.parameterTypes[3] == "Ljava/util/Collection;" + } ?: continue + if (classDef.methods.firstOrNull { + it.name == "toString" + }?.implementation?.findConstString("Friend.sq:selectFriendUserScoresNeedToUpdate") != true) continue - context.addMapping("ScoreUpdate", classDef.getClassName()) - return + addMapping("ScoreUpdate", classDef.getClassName()) + return@mapper + } } } } \ No newline at end of file diff --git a/mapper/src/main/kotlin/me/rhunk/snapenhance/mapper/impl/StoryBoostStateMapper.kt b/mapper/src/main/kotlin/me/rhunk/snapenhance/mapper/impl/StoryBoostStateMapper.kt @@ -1,21 +1,22 @@ package me.rhunk.snapenhance.mapper.impl import me.rhunk.snapenhance.mapper.AbstractClassMapper -import me.rhunk.snapenhance.mapper.MapperContext import me.rhunk.snapenhance.mapper.ext.findConstString import me.rhunk.snapenhance.mapper.ext.getClassName class StoryBoostStateMapper : AbstractClassMapper() { - override fun run(context: MapperContext) { - for (clazz in context.classes) { - val firstConstructor = clazz.directMethods.firstOrNull { it.name == "<init>" } ?: continue - if (firstConstructor.parameters.size != 3) continue - if (firstConstructor.parameterTypes[1] != "J" || firstConstructor.parameterTypes[2] != "J") continue + init { + mapper { + for (clazz in classes) { + val firstConstructor = clazz.directMethods.firstOrNull { it.name == "<init>" } ?: continue + if (firstConstructor.parameters.size != 3) continue + if (firstConstructor.parameterTypes[1] != "J" || firstConstructor.parameterTypes[2] != "J") continue - if (clazz.methods.firstOrNull { it.name == "toString" }?.implementation?.findConstString("StoryBoostState", contains = true) != true) continue + if (clazz.methods.firstOrNull { it.name == "toString" }?.implementation?.findConstString("StoryBoostState", contains = true) != true) continue - context.addMapping("StoryBoostStateClass", clazz.getClassName()) - return + addMapping("StoryBoostStateClass", clazz.getClassName()) + return@mapper + } } } } \ No newline at end of file diff --git a/mapper/src/main/kotlin/me/rhunk/snapenhance/mapper/impl/ViewBinderMapper.kt b/mapper/src/main/kotlin/me/rhunk/snapenhance/mapper/impl/ViewBinderMapper.kt @@ -1,37 +1,39 @@ package me.rhunk.snapenhance.mapper.impl import me.rhunk.snapenhance.mapper.AbstractClassMapper -import me.rhunk.snapenhance.mapper.MapperContext import me.rhunk.snapenhance.mapper.ext.getClassName import me.rhunk.snapenhance.mapper.ext.isAbstract import me.rhunk.snapenhance.mapper.ext.isInterface import java.lang.reflect.Modifier class ViewBinderMapper : AbstractClassMapper() { - override fun run(context: MapperContext) { - for (clazz in context.classes) { - if (!clazz.isAbstract() || clazz.isInterface()) continue + init { + mapper { + for (clazz in classes) { + if (!clazz.isAbstract() || clazz.isInterface()) continue - val getViewMethod = clazz.methods.firstOrNull { it.returnType == "Landroid/view/View;" && it.parameterTypes.size == 0 } ?: continue + val getViewMethod = clazz.methods.firstOrNull { it.returnType == "Landroid/view/View;" && it.parameterTypes.size == 0 } ?: continue - // update view - clazz.methods.filter { - Modifier.isAbstract(it.accessFlags) && it.parameterTypes.size == 1 && it.parameterTypes[0] == "Landroid/view/View;" && it.returnType == "V" - }.also { - if (it.size != 1) return@also - }.firstOrNull() ?: continue + // update view + clazz.methods.filter { + Modifier.isAbstract(it.accessFlags) && it.parameterTypes.size == 1 && it.parameterTypes[0] == "Landroid/view/View;" && it.returnType == "V" + }.also { + if (it.size != 1) return@also + }.firstOrNull() ?: continue - val bindMethod = clazz.methods.filter { - Modifier.isAbstract(it.accessFlags) && it.parameterTypes.size == 2 && it.parameterTypes[0] == it.parameterTypes[1] && it.returnType == "V" - }.also { - if (it.size != 1) return@also - }.firstOrNull() ?: continue + val bindMethod = clazz.methods.filter { + Modifier.isAbstract(it.accessFlags) && it.parameterTypes.size == 2 && it.parameterTypes[0] == it.parameterTypes[1] && it.returnType == "V" + }.also { + if (it.size != 1) return@also + }.firstOrNull() ?: continue - context.addMapping("ViewBinder", - "class" to clazz.getClassName(), - "bindMethod" to bindMethod.name, - "getViewMethod" to getViewMethod.name - ) + addMapping("ViewBinder", + "class" to clazz.getClassName(), + "bindMethod" to bindMethod.name, + "getViewMethod" to getViewMethod.name + ) + return@mapper + } } } } \ No newline at end of file diff --git a/mapper/src/test/kotlin/me/rhunk/snapenhance/mapper/tests/TestMappings.kt b/mapper/src/test/kotlin/me/rhunk/snapenhance/mapper/tests/TestMappings.kt @@ -15,7 +15,6 @@ class TestMappings { CallbackMapper::class, DefaultMediaItemMapper::class, MediaQualityLevelProviderMapper::class, - EnumMapper::class, OperaPageViewControllerMapper::class, PlatformAnalyticsCreatorMapper::class, PlusSubscriptionMapper::class, @@ -25,7 +24,7 @@ class TestMappings { CompositeConfigurationProviderMapper::class, ScoreUpdateMapper::class, FriendRelationshipChangerMapper::class, - ViewBinderMapper::class + ViewBinderMapper::class, ) val gson = GsonBuilder().setPrettyPrinting().create()