From e4443279d67e61d6f858324a6d745cfb3608bd04 Mon Sep 17 00:00:00 2001 From: rhunk <101876869+rhunk@users.noreply.github.com> Date: Sun, 8 Oct 2023 18:04:34 +0200 Subject: [PATCH] refactor: mapper --- .../core/bridge/wrapper/MappingsWrapper.kt | 1 - .../snapenhance/mapper/AbstractClassMapper.kt | 14 ++-- .../me/rhunk/snapenhance/mapper/Mapper.kt | 21 ----- .../mapper/impl/BCryptClassMapper.kt | 39 +++++----- .../snapenhance/mapper/impl/CallbackMapper.kt | 29 +++---- .../CompositeConfigurationProviderMapper.kt | 73 +++++++++--------- .../mapper/impl/DefaultMediaItemMapper.kt | 21 ++--- .../snapenhance/mapper/impl/EnumMapper.kt | 24 ------ .../impl/FriendRelationshipChangerMapper.kt | 32 ++++---- .../impl/FriendsFeedEventDispatcherMapper.kt | 31 ++++---- .../impl/MediaQualityLevelProviderMapper.kt | 43 +++++++---- .../impl/OperaPageViewControllerMapper.kt | 77 ++++++++++--------- .../impl/PlatformAnalyticsCreatorMapper.kt | 25 +++--- .../mapper/impl/PlusSubscriptionMapper.kt | 33 ++++---- .../mapper/impl/ScCameraSettingsMapper.kt | 19 ++--- .../mapper/impl/ScoreUpdateMapper.kt | 29 +++---- .../mapper/impl/StoryBoostStateMapper.kt | 19 ++--- .../mapper/impl/ViewBinderMapper.kt | 44 ++++++----- .../snapenhance/mapper/tests/TestMappings.kt | 3 +- 19 files changed, 283 insertions(+), 294 deletions(-) delete mode 100644 mapper/src/main/kotlin/me/rhunk/snapenhance/mapper/impl/EnumMapper.kt 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 index 1b9ef429..e2cdc8e7 100644 --- 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 index b87b1f4d..a5e82cce 100644 --- 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 Unit>() -abstract class AbstractClassMapper( - vararg val dependsOn: KClass = 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 index c0004dfe..cac0595d 100644 --- 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>() - 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 index 00ac0ef7..f84cea8b 100644 --- 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()?.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()?.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 index 437865f6..a7b132e6 100644 --- 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() + } + + addMapping("callbacks", *callbackClasses.toTypedArray()) } - - context.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 index 74191b63..dbddb534 100644 --- 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 == "" } ?: 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 == "" } ?: 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 index 4fb5c711..00ace631 100644 --- 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 == "" }?.parameterTypes ?: continue - if (constructorParameters.size < 6 || constructorParameters[5] != "J") continue + val constructorParameters = clazz.directMethods.firstOrNull { it.name == "" }?.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 deleted file mode 100644 index 702edee1..00000000 --- a/mapper/src/main/kotlin/me/rhunk/snapenhance/mapper/impl/EnumMapper.kt +++ /dev/null @@ -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 index 88bc0ffa..e2222cd6 100644 --- 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 == "" }?.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 == "" }?.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 index 7f16e816..74619f45 100644 --- 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 index fb805681..1c74e6a7 100644 --- 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 index 25d48be1..6d2751de 100644 --- 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 - } - - val viewStateField = clazz.fields.first { field -> - val fieldClass = context.getClass(field.type) ?: return@first false - fieldClass.isEnum() && fieldClass.hasStaticConstructorString("FULLY_DISPLAYED") - } - - 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 + 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 = getClass(field.type) ?: return@first false + fieldClass.isEnum() && fieldClass.hasStaticConstructorString("FULLY_DISPLAYED") + } + + 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 = 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 = getClass(it.parameterTypes[0]) ?: return@first false + val secondParameterType = getClass(it.parameterTypes[1]) ?: return@first false + firstParameterType.isEnum() && secondParameterType.isEnum() + } + + addMapping("OperaPageViewController", + "class" to clazz.getClassName(), + "viewStateField" to viewStateField.name, + "layerListField" to layerListField.name, + "onDisplayStateChange" to onDisplayStateChange.name, + "onDisplayStateChangeGesture" to onDisplayStateChangeGesture.name + ) + + return@mapper } - - 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() - } - - context.addMapping("OperaPageViewController", - "class" to clazz.getClassName(), - "viewStateField" to viewStateField.name, - "layerListField" to layerListField.name, - "onDisplayStateChange" to onDisplayStateChange.name, - "onDisplayStateChangeGesture" to onDisplayStateChangeGesture.name - ) - - return } } } \ 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 index d6f01804..747d9b0d 100644 --- 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 == "" } ?: 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 == "" } ?: 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 index dbd31a71..6f5a3667 100644 --- 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 == "" }.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 == "" }.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 index 2c20495e..4793ad45 100644 --- 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 == "" } ?: 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 == "" } ?: 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 index f72de805..dba8900b 100644 --- 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 == "" && - 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 == "" && + 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 index 6d1dae66..bbc409ee 100644 --- 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 == "" } ?: 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 == "" } ?: 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 index 9c15fec6..311b2b06 100644 --- 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 index 6bb5e2bd..fff1fa66 100644 --- 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()