commit b15dada1732d31dd1fa701ee67257dfe9e25f911
parent 28433922c5ed00740328ae7afcc4c763de6a79dd
Author: rhunk <101876869+rhunk@users.noreply.github.com>
Date:   Fri, 17 May 2024 23:34:05 +0200

fix: streak expiration info

Diffstat:
Mcore/src/main/kotlin/me/rhunk/snapenhance/core/features/impl/ui/CustomStreaksExpirationFormat.kt | 13++++++++++++-
Mmapper/src/main/kotlin/me/rhunk/snapenhance/mapper/impl/StreaksExpirationMapper.kt | 30+++++++++++++++++++++++++++++-
2 files changed, 41 insertions(+), 2 deletions(-)

diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/core/features/impl/ui/CustomStreaksExpirationFormat.kt b/core/src/main/kotlin/me/rhunk/snapenhance/core/features/impl/ui/CustomStreaksExpirationFormat.kt @@ -15,10 +15,21 @@ class CustomStreaksExpirationFormat: Feature("CustomStreaksExpirationFormat", lo override fun onActivityCreate() { val expirationFormat by context.config.experimental.customStreaksExpirationFormat + if (expirationFormat.isNotEmpty() || context.config.userInterface.streakExpirationInfo.get()) { + context.mappings.useMapper(StreaksExpirationMapper::class) { + runCatching { + simpleStreaksFormatterClass.getAsClass()?.hook(formatSimpleStreaksTextMethod.get() ?: return@useMapper, HookStage.BEFORE) { param -> + param.setResult(null) + } + }.onFailure { + context.log.warn("Failed to hook simpleStreaksFormatterClass : " + it.message) + } + } + } if (expirationFormat.isEmpty()) return context.mappings.useMapper(StreaksExpirationMapper::class) { - findClass(streaksFormatterClass.get() ?: return@useMapper).hook(formatStreaksTextMethod.get() ?: return@useMapper, HookStage.AFTER) { param -> + streaksFormatterClass.getAsClass()?.hook(formatStreaksTextMethod.get() ?: return@useMapper, HookStage.AFTER) { param -> val streaksCount = param.argNullable(2) ?: 0 val streaksExpiration = param.argNullable<Any>(3) ?: return@hook diff --git a/mapper/src/main/kotlin/me/rhunk/snapenhance/mapper/impl/StreaksExpirationMapper.kt b/mapper/src/main/kotlin/me/rhunk/snapenhance/mapper/impl/StreaksExpirationMapper.kt @@ -10,11 +10,39 @@ class StreaksExpirationMapper: AbstractClassMapper("StreaksExpirationMapper") { val hourGlassTimeRemainingField = string("hourGlassTimeRemainingField") val expirationTimeField = string("expirationTimeField") - val streaksFormatterClass = string("streaksFormatterClass") + val streaksFormatterClass = classReference("streaksFormatterClass") val formatStreaksTextMethod = string("formatStreaksTextMethod") + val simpleStreaksFormatterClass = classReference("simpleStreaksFormatterClass") + val formatSimpleStreaksTextMethod = string("formatSimpleStreaksTextMethod") + init { mapper { + var streaksResultClass: String? = null + for (clazz in classes) { + val toStringMethod = clazz.methods.firstOrNull { it.name == "toString" } ?: continue + if (toStringMethod.implementation?.findConstString("StreaksResult(", contains = true) != true) continue + streaksResultClass = clazz.type + break + } + + if (streaksResultClass == null) return@mapper + + for (clazz in classes) { + val formatStreaksTextDexMethod = clazz.methods.firstOrNull { method -> + Modifier.isStatic(method.accessFlags) && + method.returnType == "Ljava/lang/String;" && + method.parameterTypes.let { + it.size >= 3 && it.first() == streaksResultClass && it[1] == "Ljava/lang/String;" && it[2] == "J" + } + } ?: continue + simpleStreaksFormatterClass.set(clazz.getClassName()) + formatSimpleStreaksTextMethod.set(formatStreaksTextDexMethod.name) + return@mapper + } + } + + mapper { var streaksExpirationClassName: String? = null for (clazz in classes) { val toStringMethod = clazz.methods.firstOrNull { it.name == "toString" } ?: continue