Custom drawables support

This commit is contained in:
Amsyar Rasyiq 2023-05-26 15:38:25 +00:00
parent d200ca382a
commit a682d676ff

View file

@ -2,10 +2,13 @@ package com.pyoncord.xposed
import android.app.Activity import android.app.Activity
import android.content.Intent import android.content.Intent
import android.content.Context
import android.content.res.AssetManager import android.content.res.AssetManager
import android.content.res.Resources import android.content.res.Resources
import android.content.res.XModuleResources import android.content.res.XModuleResources
import android.graphics.drawable.Drawable
import android.graphics.Typeface import android.graphics.Typeface
import android.net.Uri
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.os.Environment import android.os.Environment
@ -42,6 +45,8 @@ class Main : IXposedHookZygoteInit, IXposedHookLoadPackage {
val bundle = File(pyoncord, "pyoncord.js") val bundle = File(pyoncord, "pyoncord.js")
val etag = File(pyoncord, "etag") val etag = File(pyoncord, "etag")
val drawablesDir = File(pyoncord, "drawables")
} }
private lateinit var resources: XModuleResources private lateinit var resources: XModuleResources
@ -134,6 +139,18 @@ class Main : IXposedHookZygoteInit, IXposedHookLoadPackage {
} }
} }
// Fight package renaming side effects
if (packageName != "com.discord") {
val getIdentifier = Resources::class.java.getDeclaredMethod("getIdentifier", String::class.java, String::class.java, String::class.java)
XposedBridge.hookMethod(getIdentifier, object: XC_MethodHook() {
override fun beforeHookedMethod(param: MethodHookParam) {
if (param.args[2] == packageName) param.args[2] = "com.discord"
}
})
}
// Custom fonts
XposedBridge.hookMethod( XposedBridge.hookMethod(
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
Font.Builder::class.java.getDeclaredConstructor(AssetManager::class.java, String::class.java) Font.Builder::class.java.getDeclaredConstructor(AssetManager::class.java, String::class.java)
@ -143,22 +160,29 @@ class Main : IXposedHookZygoteInit, IXposedHookLoadPackage {
}, },
fontHook fontHook
) )
// Custom drawables
val uriCache = mutableMapOf<String, Uri?>()
val resourceDrawableIdHelper = classLoader.loadClass("com.facebook.react.views.imagehelper.ResourceDrawableIdHelper")
XposedBridge.hookMethod(resourceDrawableIdHelper.getDeclaredMethod("getResourceDrawableUri", Context::class.java, String::class.java), object: XC_MethodHook() {
override fun beforeHookedMethod(param: MethodHookParam) {
val name = param.args[1] as? String ?: return
val uri = uriCache.getOrPut(name) {
File(drawablesDir, "$name.png").takeIf { it.exists() }?.let {
Uri.fromFile(it)
} ?: null
}
if (uri != null) param.result = uri
}
})
} }
val loadScriptFromAssets = catalystInstance.getDeclaredMethod("jniLoadScriptFromAssets", AssetManager::class.java, String::class.java, Boolean::class.javaPrimitiveType) val loadScriptFromAssets = catalystInstance.getDeclaredMethod("jniLoadScriptFromAssets", AssetManager::class.java, String::class.java, Boolean::class.javaPrimitiveType)
val loadScriptFromFile = catalystInstance.getDeclaredMethod("jniLoadScriptFromFile", String::class.java, String::class.java, Boolean::class.javaPrimitiveType) val loadScriptFromFile = catalystInstance.getDeclaredMethod("jniLoadScriptFromFile", String::class.java, String::class.java, Boolean::class.javaPrimitiveType)
// Mirror resource resolver to "com.discord" if the package name is renamed
if (packageName != "com.discord") {
val getIdentifier = Resources::class.java.getDeclaredMethod("getIdentifier", String::class.java, String::class.java, String::class.java)
XposedBridge.hookMethod(getIdentifier, object: XC_MethodHook() {
override fun beforeHookedMethod(param: MethodHookParam) {
if (param.args[2] == packageName) param.args[2] = "com.discord"
}
})
}
// TODO: Loader config // TODO: Loader config
val hook = object: XC_MethodHook() { val hook = object: XC_MethodHook() {
override fun beforeHookedMethod(param: MethodHookParam) = with(param) { override fun beforeHookedMethod(param: MethodHookParam) = with(param) {