Add files via upload
This commit is contained in:
parent
2c94757947
commit
08bfa8199d
2 changed files with 236 additions and 0 deletions
183
app/src/main/kotlin/ShiggyXposed/xposed/xposed/Module.kt.txt
Normal file
183
app/src/main/kotlin/ShiggyXposed/xposed/xposed/Module.kt.txt
Normal file
|
|
@ -0,0 +1,183 @@
|
||||||
|
package ShiggyXposed.xposed
|
||||||
|
|
||||||
|
import android.app.Activity
|
||||||
|
import android.content.Context
|
||||||
|
import android.os.Build
|
||||||
|
import de.robv.android.xposed.IXposedHookZygoteInit
|
||||||
|
import de.robv.android.xposed.XC_MethodHook
|
||||||
|
import de.robv.android.xposed.XposedBridge
|
||||||
|
import de.robv.android.xposed.callbacks.XC_LoadPackage
|
||||||
|
import kotlinx.serialization.json.JsonObjectBuilder
|
||||||
|
import java.io.File
|
||||||
|
import java.lang.reflect.Method
|
||||||
|
|
||||||
|
data class AppInfo(
|
||||||
|
val name: String,
|
||||||
|
val packageName: String,
|
||||||
|
val version: String,
|
||||||
|
val versionCode: Long,
|
||||||
|
)
|
||||||
|
|
||||||
|
abstract class Module {
|
||||||
|
/**
|
||||||
|
* Builds a JSON payload to be injected into the JavaScript context.
|
||||||
|
*/
|
||||||
|
@Deprecated("This will be removed in future versions. Payloads can be replaced via synchronous bridge methods.")
|
||||||
|
open fun buildPayload(builder: JsonObjectBuilder) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called during Zygote initialization.
|
||||||
|
*/
|
||||||
|
open fun onInit(startupParam: IXposedHookZygoteInit.StartupParam) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when a package is loaded.
|
||||||
|
*
|
||||||
|
* Hooks should typically be set up here.
|
||||||
|
*
|
||||||
|
* Bridge methods that do not require [Context] can also be registered here.
|
||||||
|
*/
|
||||||
|
open fun onLoad(packageParam: XC_LoadPackage.LoadPackageParam) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called after [Context] has been attached to a [android.content.ContextWrapper]
|
||||||
|
* via [android.content.ContextWrapper.attachBaseContext].
|
||||||
|
*
|
||||||
|
* This may be called multiple times for different [Context]s, e.g. when the app is killed by the system.
|
||||||
|
*
|
||||||
|
* For bridge methods that require access to [Context], register them here.
|
||||||
|
*/
|
||||||
|
open fun onContext(context: Context) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called after an [Activity.onCreate] method is executed.
|
||||||
|
*
|
||||||
|
* UI code that requires an [Activity] context can be placed here.
|
||||||
|
*
|
||||||
|
* Bridge methods must not be registered here, as it can be too late and cause crashes.
|
||||||
|
*
|
||||||
|
* If you need to register bridge methods that require an [Activity], do it in [onContext] and make it async.
|
||||||
|
*
|
||||||
|
* Once an [Activity] is available, execute the queued calls. Then from JS, call the method asynchronously.
|
||||||
|
*/
|
||||||
|
open fun onActivity(activity: Activity) {}
|
||||||
|
|
||||||
|
protected fun Context.getAppInfo(): AppInfo {
|
||||||
|
val pInfo = packageManager.getPackageInfo(packageName, 0)
|
||||||
|
val versionCode = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) pInfo.longVersionCode
|
||||||
|
else @Suppress("DEPRECATION") pInfo.versionCode.toLong()
|
||||||
|
|
||||||
|
return AppInfo(
|
||||||
|
packageManager.getApplicationLabel(applicationInfo).toString(),
|
||||||
|
packageName,
|
||||||
|
pInfo.versionName ?: versionCode.toString(),
|
||||||
|
versionCode,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
protected fun File.asDir() {
|
||||||
|
if (!this.isDirectory) this.delete()
|
||||||
|
this.mkdirs()
|
||||||
|
}
|
||||||
|
|
||||||
|
protected fun File.asFile() {
|
||||||
|
if (!this.isFile) this.deleteRecursively()
|
||||||
|
}
|
||||||
|
|
||||||
|
protected fun Class<*>.method(
|
||||||
|
name: String, vararg params: Class<*>?
|
||||||
|
): Method = getDeclaredMethod(name, *params).apply {
|
||||||
|
isAccessible = true
|
||||||
|
}
|
||||||
|
|
||||||
|
protected fun ClassLoader.safeLoadClass(name: String): Class<*>? = runCatching { loadClass(name) }.getOrNull()
|
||||||
|
|
||||||
|
protected fun Method.hook(hook: XC_MethodHook): XC_MethodHook.Unhook = XposedBridge.hookMethod(this, hook)
|
||||||
|
|
||||||
|
protected fun Method.hook(block: MethodHookBuilder.() -> Unit): XC_MethodHook.Unhook =
|
||||||
|
hook(MethodHookBuilder().apply(block).build())
|
||||||
|
|
||||||
|
protected fun Class<*>.hookMethod(
|
||||||
|
name: String, vararg params: Class<*>?, block: MethodHookBuilder.() -> Unit
|
||||||
|
): XC_MethodHook.Unhook = method(name, *params).hook(MethodHookBuilder().apply(block).build())
|
||||||
|
|
||||||
|
protected class MethodHookBuilder {
|
||||||
|
private var beforeBlock: (HookScope.() -> Unit)? = null
|
||||||
|
private var afterBlock: (HookScope.() -> Unit)? = null
|
||||||
|
|
||||||
|
fun before(block: HookScope.() -> Unit) {
|
||||||
|
beforeBlock = block
|
||||||
|
}
|
||||||
|
|
||||||
|
fun after(block: HookScope.() -> Unit) {
|
||||||
|
afterBlock = block
|
||||||
|
}
|
||||||
|
|
||||||
|
fun build(): XC_MethodHook = object : XC_MethodHook() {
|
||||||
|
override fun beforeHookedMethod(param: MethodHookParam) {
|
||||||
|
val b = beforeBlock
|
||||||
|
if (b != null) {
|
||||||
|
val scope = HookScope(
|
||||||
|
param = param, proceed = { p ->
|
||||||
|
super.beforeHookedMethod(p)
|
||||||
|
})
|
||||||
|
scope.b()
|
||||||
|
} else {
|
||||||
|
super.beforeHookedMethod(param)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun afterHookedMethod(param: MethodHookParam) {
|
||||||
|
val a = afterBlock
|
||||||
|
if (a != null) {
|
||||||
|
val scope = HookScope(
|
||||||
|
param = param, proceed = { p ->
|
||||||
|
super.afterHookedMethod(p)
|
||||||
|
})
|
||||||
|
scope.a()
|
||||||
|
} else {
|
||||||
|
super.afterHookedMethod(param)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scope object passed to before/after hook blocks.
|
||||||
|
*
|
||||||
|
* Provides:
|
||||||
|
* - Access to the [param] object
|
||||||
|
* - [proceed] to call the original XC_MethodHook super method
|
||||||
|
* - Accessors for `thisObject`, `args`, `result`, and `throwable`
|
||||||
|
*
|
||||||
|
* @property param The [XC_MethodHook.MethodHookParam] for the current hook.
|
||||||
|
* @property proceed Function that calls the super method.
|
||||||
|
*/
|
||||||
|
protected class HookScope internal constructor(
|
||||||
|
val param: XC_MethodHook.MethodHookParam, private val proceed: (XC_MethodHook.MethodHookParam) -> Unit
|
||||||
|
) {
|
||||||
|
/**
|
||||||
|
* Continues with the default XC_MethodHook super behavior.
|
||||||
|
* Equivalent to calling `super.beforeHookedMethod(param)` or
|
||||||
|
* `super.afterHookedMethod(param)` depending on the phase.
|
||||||
|
*/
|
||||||
|
fun proceed() = proceed(param)
|
||||||
|
|
||||||
|
val thisObject: Any? get() = param.thisObject
|
||||||
|
|
||||||
|
val args: Array<Any?> get() = param.args
|
||||||
|
|
||||||
|
var result: Any?
|
||||||
|
get() = param.result
|
||||||
|
set(value) {
|
||||||
|
param.result = value
|
||||||
|
}
|
||||||
|
|
||||||
|
var throwable: Throwable?
|
||||||
|
get() = param.throwable
|
||||||
|
set(value) {
|
||||||
|
param.throwable = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
53
app/src/main/kotlin/ShiggyXposed/xposed/xposed/Utils.kt.txt
Normal file
53
app/src/main/kotlin/ShiggyXposed/xposed/xposed/Utils.kt.txt
Normal file
|
|
@ -0,0 +1,53 @@
|
||||||
|
package ShiggyXposed.xposed
|
||||||
|
|
||||||
|
import android.app.AlertDialog
|
||||||
|
import android.app.AndroidAppHelper
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import ShiggyXposed.xposed.modules.UpdaterModule
|
||||||
|
import kotlinx.serialization.json.Json
|
||||||
|
import java.io.File
|
||||||
|
import kotlin.system.exitProcess
|
||||||
|
|
||||||
|
class Utils {
|
||||||
|
companion object {
|
||||||
|
val JSON = Json { ignoreUnknownKeys = true }
|
||||||
|
|
||||||
|
fun reloadApp() {
|
||||||
|
val application = AndroidAppHelper.currentApplication()
|
||||||
|
val intent = application.packageManager.getLaunchIntentForPackage(application.packageName)
|
||||||
|
application.startActivity(Intent.makeRestartActivityTask(intent!!.component))
|
||||||
|
exitProcess(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun showRecoveryAlert(context: Context) {
|
||||||
|
AlertDialog.Builder(context).setTitle("ShiggyCord Recovery Options")
|
||||||
|
.setItems(arrayOf("Reload", "Delete Script", "Reset Loader Config")) { _, which ->
|
||||||
|
when (which) {
|
||||||
|
0 -> {
|
||||||
|
reloadApp()
|
||||||
|
}
|
||||||
|
|
||||||
|
1 -> {
|
||||||
|
val bundleFile = File(
|
||||||
|
context.dataDir, "${Constants.CACHE_DIR}/${Constants.MAIN_SCRIPT_FILE}"
|
||||||
|
)
|
||||||
|
|
||||||
|
if (bundleFile.exists()) bundleFile.delete()
|
||||||
|
|
||||||
|
reloadApp()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object Log {
|
||||||
|
fun e(msg: String) = android.util.Log.e(Constants.LOG_TAG, msg)
|
||||||
|
fun e(msg: String, throwable: Throwable) = android.util.Log.e(Constants.LOG_TAG, msg, throwable)
|
||||||
|
fun i(msg: String) = android.util.Log.i(Constants.LOG_TAG, msg)
|
||||||
|
fun i(msg: String, throwable: Throwable) = android.util.Log.i(Constants.LOG_TAG, msg, throwable)
|
||||||
|
fun w(msg: String) = android.util.Log.w(Constants.LOG_TAG, msg)
|
||||||
|
fun w(msg: String, throwable: Throwable) = android.util.Log.w(Constants.LOG_TAG, msg, throwable)
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue