commit 2c435a3760502adead950b342ed654f672f8df85
parent c7cb25c19022f3cad69a5add6d7845cab6b77fd5
Author: rhunk <101876869+rhunk@users.noreply.github.com>
Date:   Fri, 10 Jan 2025 15:25:49 +0100

fix(core): opera viewer params override
supports v13.22.0.61 and higher

Signed-off-by: rhunk <101876869+rhunk@users.noreply.github.com>

Diffstat:
Mcore/src/main/kotlin/me/rhunk/snapenhance/core/features/impl/OperaViewerParamsOverride.kt | 20+++++++++++++-------
Mcore/src/main/kotlin/me/rhunk/snapenhance/core/wrapper/impl/media/opera/ParamMap.kt | 2+-
Mmapper/src/main/kotlin/me/rhunk/snapenhance/mapper/impl/OperaViewerParamsMapper.kt | 22+++++-----------------
3 files changed, 19 insertions(+), 25 deletions(-)

diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/core/features/impl/OperaViewerParamsOverride.kt b/core/src/main/kotlin/me/rhunk/snapenhance/core/features/impl/OperaViewerParamsOverride.kt @@ -2,8 +2,10 @@ package me.rhunk.snapenhance.core.features.impl import me.rhunk.snapenhance.core.features.Feature import me.rhunk.snapenhance.core.util.hook.HookStage -import me.rhunk.snapenhance.core.util.hook.hook +import me.rhunk.snapenhance.core.util.hook.hookConstructor +import me.rhunk.snapenhance.core.wrapper.impl.media.opera.ParamMap import me.rhunk.snapenhance.mapper.impl.OperaViewerParamsMapper +import java.util.concurrent.ConcurrentHashMap class OperaViewerParamsOverride : Feature("OperaViewerParamsOverride") { var currentPlaybackRate = 1.0F @@ -37,7 +39,7 @@ class OperaViewerParamsOverride : Feature("OperaViewerParamsOverride") { overrideParam("auto_advance_max_loop_number", { true }, { _, _ -> Int.MAX_VALUE }) overrideParam("media_playback_mode", { true }, { _, value -> val playbackMode = value ?: return@overrideParam null - playbackMode::class.java.enumConstants.firstOrNull { + playbackMode::class.java.enumConstants?.firstOrNull { it.toString() == "LOOPING" } ?: return@overrideParam value }) @@ -69,12 +71,16 @@ class OperaViewerParamsOverride : Feature("OperaViewerParamsOverride") { return value } - classReference.get()?.hook(getMethod.get()!!, HookStage.AFTER) { param -> - param.setResult(overrideParamResult(param.arg(0), param.getResult())) - } + classReference.get()?.hookConstructor(HookStage.AFTER) { param -> + ParamMap(param.thisObject()).paramMapField.set(param.thisObject(), object: ConcurrentHashMap<Any, Any>() { + override fun put(key: Any, value: Any): Any? { + return super.put(key, overrideParamResult(key, value) ?: return value) + } - classReference.get()?.hook(getOrDefaultMethod.get()!!, HookStage.AFTER) { param -> - param.setResult(overrideParamResult(param.arg(0), param.getResult())) + override fun get(key: Any): Any? { + return overrideParamResult(key, super.get(key)) + } + }) } } } diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/core/wrapper/impl/media/opera/ParamMap.kt b/core/src/main/kotlin/me/rhunk/snapenhance/core/wrapper/impl/media/opera/ParamMap.kt @@ -8,7 +8,7 @@ import java.util.concurrent.ConcurrentHashMap @Suppress("UNCHECKED_CAST") class ParamMap(obj: Any?) : AbstractWrapper(obj) { - private val paramMapField: Field by lazy { + val paramMapField: Field by lazy { instanceNonNull()::class.java.findFields(once = true) { it.type == ConcurrentHashMap::class.java || runCatching { it.get(instance) }.getOrNull() is ConcurrentHashMap<*, *> }.firstOrNull() ?: throw RuntimeException("Could not find paramMap field") diff --git a/mapper/src/main/kotlin/me/rhunk/snapenhance/mapper/impl/OperaViewerParamsMapper.kt b/mapper/src/main/kotlin/me/rhunk/snapenhance/mapper/impl/OperaViewerParamsMapper.kt @@ -9,8 +9,6 @@ import me.rhunk.snapenhance.mapper.ext.getClassName class OperaViewerParamsMapper : AbstractClassMapper("OperaViewerParams") { val classReference = classReference("class") - val getMethod = string("getMethod") - val getOrDefaultMethod = string("getOrDefaultMethod") private fun Method.hasHashMapReference(methodName: String) = implementation?.instructions?.any { val instruction = it as? Instruction35c ?: return@any false @@ -21,25 +19,15 @@ class OperaViewerParamsMapper : AbstractClassMapper("OperaViewerParams") { init { mapper { for (classDef in classes) { - classDef.fields.firstOrNull { it.type == "Ljava/util/concurrent/ConcurrentHashMap;" } ?: continue if (classDef.methods.firstOrNull { it.name == "toString" }?.implementation?.findConstString("Params") != true) continue - val getOrDefaultDexMethod = classDef.methods.firstOrNull { method -> + classDef.methods.firstOrNull { method -> method.returnType == "Ljava/lang/Object;" && - method.parameters.size == 2 && - method.parameterTypes[1] == "Ljava/lang/Object;" && - method.hasHashMapReference("get") - } ?: return@mapper + method.parameters.size == 2 && + method.parameterTypes[1] == "Ljava/lang/Object;" && + method.hasHashMapReference("get") + } ?: continue - val getDexMethod = classDef.methods.firstOrNull { method -> - method.returnType == "Ljava/lang/Object;" && - method.parameters.size == 1 && - method.parameterTypes[0] == getOrDefaultDexMethod.parameterTypes[0] && - method.hasHashMapReference("get") - } ?: return@mapper - - getMethod.set(getDexMethod.name) - getOrDefaultMethod.set(getOrDefaultDexMethod.name) classReference.set(classDef.getClassName()) return@mapper }