mirror of
https://github.com/rhunk/SnapEnhance.git
synced 2025-04-29 22:24:35 +02:00
fix(core): opera viewer params override
supports v13.22.0.61 and higher Signed-off-by: rhunk <101876869+rhunk@users.noreply.github.com>
This commit is contained in:
parent
c7cb25c190
commit
2c435a3760
@ -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))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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")
|
||||
|
@ -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
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user