mirror of
https://github.com/whitechi73/OpenShamrock.git
synced 2024-08-14 13:12:17 +08:00
Shamrock
: 金メダル免除、システムレベルの保活をサポートする
This commit is contained in:
parent
ee8dc75be3
commit
0d35d5834b
@ -47,7 +47,7 @@
|
|||||||
android:value="基于 Xposed 实现 OneBot 标准的 QQ 机器人框架" />
|
android:value="基于 Xposed 实现 OneBot 标准的 QQ 机器人框架" />
|
||||||
<meta-data
|
<meta-data
|
||||||
android:name="xposedminversion"
|
android:name="xposedminversion"
|
||||||
android:value="23" />
|
android:value="93" />
|
||||||
<meta-data
|
<meta-data
|
||||||
android:name="xposedscope"
|
android:name="xposedscope"
|
||||||
android:resource="@array/xposed_scope" />
|
android:resource="@array/xposed_scope" />
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package moe.fuqiuluo.shamrock.ui.fragment
|
package moe.fuqiuluo.shamrock.ui.fragment
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.absolutePadding
|
import androidx.compose.foundation.layout.absolutePadding
|
||||||
@ -22,6 +23,7 @@ import androidx.compose.ui.unit.dp
|
|||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import moe.fuqiuluo.shamrock.R
|
import moe.fuqiuluo.shamrock.R
|
||||||
import moe.fuqiuluo.shamrock.ui.app.AppRuntime
|
import moe.fuqiuluo.shamrock.ui.app.AppRuntime
|
||||||
|
import moe.fuqiuluo.shamrock.ui.app.Level
|
||||||
import moe.fuqiuluo.shamrock.ui.app.ShamrockConfig
|
import moe.fuqiuluo.shamrock.ui.app.ShamrockConfig
|
||||||
import moe.fuqiuluo.shamrock.ui.theme.GlobalColor
|
import moe.fuqiuluo.shamrock.ui.theme.GlobalColor
|
||||||
import moe.fuqiuluo.shamrock.ui.theme.LocalString
|
import moe.fuqiuluo.shamrock.ui.theme.LocalString
|
||||||
@ -90,7 +92,7 @@ fun LabFragment() {
|
|||||||
modifier = Modifier.padding(top = 12.dp),
|
modifier = Modifier.padding(top = 12.dp),
|
||||||
painter = painterResource(id = R.drawable.round_logo_dev_24),
|
painter = painterResource(id = R.drawable.round_logo_dev_24),
|
||||||
title = "实验功能"
|
title = "实验功能"
|
||||||
) {
|
) { color ->
|
||||||
Column {
|
Column {
|
||||||
Divider(
|
Divider(
|
||||||
modifier = Modifier,
|
modifier = Modifier,
|
||||||
@ -101,7 +103,7 @@ fun LabFragment() {
|
|||||||
Function(
|
Function(
|
||||||
title = "自动清理QQ垃圾",
|
title = "自动清理QQ垃圾",
|
||||||
desc = "也许会导致奇怪的问题(无效)。",
|
desc = "也许会导致奇怪的问题(无效)。",
|
||||||
descColor = it,
|
descColor = color,
|
||||||
isSwitch = ShamrockConfig.isAutoClean(ctx)
|
isSwitch = ShamrockConfig.isAutoClean(ctx)
|
||||||
) {
|
) {
|
||||||
ShamrockConfig.setAutoClean(ctx, it)
|
ShamrockConfig.setAutoClean(ctx, it)
|
||||||
@ -112,7 +114,7 @@ fun LabFragment() {
|
|||||||
Function(
|
Function(
|
||||||
title = "拦截QQ无用收包",
|
title = "拦截QQ无用收包",
|
||||||
desc = "测试阶段,可能导致网络异常或掉线。",
|
desc = "测试阶段,可能导致网络异常或掉线。",
|
||||||
descColor = it,
|
descColor = color,
|
||||||
isSwitch = ShamrockConfig.isInjectPacket(ctx)
|
isSwitch = ShamrockConfig.isInjectPacket(ctx)
|
||||||
) {
|
) {
|
||||||
ShamrockConfig.setInjectPacket(ctx, it)
|
ShamrockConfig.setInjectPacket(ctx, it)
|
||||||
@ -123,7 +125,7 @@ fun LabFragment() {
|
|||||||
Function(
|
Function(
|
||||||
title = "自动唤醒QQ",
|
title = "自动唤醒QQ",
|
||||||
desc = "QQ进程死亡时重新打开QQ进程,前提本进程存活。",
|
desc = "QQ进程死亡时重新打开QQ进程,前提本进程存活。",
|
||||||
descColor = it,
|
descColor = color,
|
||||||
isSwitch = ShamrockConfig.enableAutoStart(ctx)
|
isSwitch = ShamrockConfig.enableAutoStart(ctx)
|
||||||
) {
|
) {
|
||||||
ShamrockConfig.setAutoStart(ctx, it)
|
ShamrockConfig.setAutoStart(ctx, it)
|
||||||
@ -133,12 +135,30 @@ fun LabFragment() {
|
|||||||
Function(
|
Function(
|
||||||
title = "开启Shell接口",
|
title = "开启Shell接口",
|
||||||
desc = "可能导致设备被入侵,请勿随意开启。",
|
desc = "可能导致设备被入侵,请勿随意开启。",
|
||||||
descColor = it,
|
descColor = color,
|
||||||
isSwitch = ShamrockConfig.allowShell(ctx)
|
isSwitch = ShamrockConfig.allowShell(ctx)
|
||||||
) {
|
) {
|
||||||
ShamrockConfig.setShellStatus(ctx, it)
|
ShamrockConfig.setShellStatus(ctx, it)
|
||||||
return@Function true
|
return@Function true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
kotlin.runCatching {
|
||||||
|
ctx.getSharedPreferences("shared_config", Context.MODE_WORLD_READABLE)
|
||||||
|
}.onSuccess {
|
||||||
|
Function(
|
||||||
|
title = "免死金牌",
|
||||||
|
desc = "由系统复活QQ和Shamrock,需要重新启动系统。",
|
||||||
|
descColor = color,
|
||||||
|
isSwitch = it.getBoolean("persistent", false)
|
||||||
|
) { v ->
|
||||||
|
it.edit().putBoolean("persistent", v).apply()
|
||||||
|
scope.toast(ctx, "重启系统生效哦!")
|
||||||
|
return@Function true
|
||||||
|
}
|
||||||
|
}.onFailure {
|
||||||
|
AppRuntime.log("无法启用免死金牌选项,当前Lsposed模块未激活或者不支持NewSharedPreferences。", Level.WARN)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ import io.ktor.http.ContentType
|
|||||||
import io.ktor.http.content.PartData
|
import io.ktor.http.content.PartData
|
||||||
import io.ktor.http.content.forEachPart
|
import io.ktor.http.content.forEachPart
|
||||||
import io.ktor.http.content.streamProvider
|
import io.ktor.http.content.streamProvider
|
||||||
|
import io.ktor.server.application.Application
|
||||||
import io.ktor.server.application.call
|
import io.ktor.server.application.call
|
||||||
import io.ktor.server.request.receiveMultipart
|
import io.ktor.server.request.receiveMultipart
|
||||||
import io.ktor.server.response.respondText
|
import io.ktor.server.response.respondText
|
||||||
@ -27,6 +28,7 @@ import moe.fuqiuluo.shamrock.tools.fetchOrThrow
|
|||||||
import moe.fuqiuluo.shamrock.tools.fetchPostJsonArray
|
import moe.fuqiuluo.shamrock.tools.fetchPostJsonArray
|
||||||
import moe.fuqiuluo.shamrock.tools.getOrPost
|
import moe.fuqiuluo.shamrock.tools.getOrPost
|
||||||
import moe.fuqiuluo.shamrock.tools.isJsonArray
|
import moe.fuqiuluo.shamrock.tools.isJsonArray
|
||||||
|
import moe.fuqiuluo.shamrock.tools.json
|
||||||
import moe.fuqiuluo.shamrock.tools.respond
|
import moe.fuqiuluo.shamrock.tools.respond
|
||||||
import moe.fuqiuluo.shamrock.utils.FileUtils
|
import moe.fuqiuluo.shamrock.utils.FileUtils
|
||||||
import moe.fuqiuluo.shamrock.utils.MD5
|
import moe.fuqiuluo.shamrock.utils.MD5
|
||||||
@ -39,7 +41,7 @@ fun Routing.otherAction() {
|
|||||||
post("/shell") {
|
post("/shell") {
|
||||||
val runtime = Runtime.getRuntime()
|
val runtime = Runtime.getRuntime()
|
||||||
val dir = fetchOrThrow("dir")
|
val dir = fetchOrThrow("dir")
|
||||||
val out = StringBuilder()
|
val out = hashMapOf<String, Any>()
|
||||||
withTimeoutOrNull(5000L) {
|
withTimeoutOrNull(5000L) {
|
||||||
if (isJsonArray("cmd")) {
|
if (isJsonArray("cmd")) {
|
||||||
val cmd = fetchPostJsonArray("cmd").map {
|
val cmd = fetchPostJsonArray("cmd").map {
|
||||||
@ -59,17 +61,15 @@ fun Routing.otherAction() {
|
|||||||
respond(false, Status.IAmTired, "执行超时")
|
respond(false, Status.IAmTired, "执行超时")
|
||||||
} else {
|
} else {
|
||||||
it.inputStream.use {
|
it.inputStream.use {
|
||||||
out.append("stdout:\n")
|
out["out"] = it.readBytes().toString(Charsets.UTF_8)
|
||||||
out.append(it.readBytes().toString(Charsets.UTF_8))
|
|
||||||
}
|
}
|
||||||
it.errorStream.use {
|
it.errorStream.use {
|
||||||
out.append("\nstderr:\n")
|
out["err"] = it.readBytes().toString(Charsets.UTF_8)
|
||||||
out.append(it.readBytes().toString(Charsets.UTF_8))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
call.respondText(out.toString())
|
call.respondText(out.json.toString(), ContentType.Application.Json)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,6 +3,8 @@ package moe.fuqiuluo.shamrock.xposed.loader
|
|||||||
|
|
||||||
import android.content.pm.ApplicationInfo
|
import android.content.pm.ApplicationInfo
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
|
import com.arthenica.ffmpegkit.BuildConfig
|
||||||
|
import de.robv.android.xposed.XSharedPreferences
|
||||||
import de.robv.android.xposed.XposedBridge
|
import de.robv.android.xposed.XposedBridge
|
||||||
import de.robv.android.xposed.XposedHelpers
|
import de.robv.android.xposed.XposedHelpers
|
||||||
import moe.fuqiuluo.shamrock.tools.hookMethod
|
import moe.fuqiuluo.shamrock.tools.hookMethod
|
||||||
@ -16,6 +18,7 @@ internal object FuckAMS {
|
|||||||
private lateinit var KeepThread: Thread
|
private lateinit var KeepThread: Thread
|
||||||
|
|
||||||
private lateinit var METHOD_IS_KILLED: Method
|
private lateinit var METHOD_IS_KILLED: Method
|
||||||
|
private var allowPersistent: Boolean = false
|
||||||
|
|
||||||
fun injectAMS(loader: ClassLoader) {
|
fun injectAMS(loader: ClassLoader) {
|
||||||
kotlin.runCatching {
|
kotlin.runCatching {
|
||||||
@ -24,15 +27,24 @@ internal object FuckAMS {
|
|||||||
increaseAdj(it.result)
|
increaseAdj(it.result)
|
||||||
}
|
}
|
||||||
}.onFailure {
|
}.onFailure {
|
||||||
XposedBridge.log("Plan A failed: ${it.message}")
|
XposedBridge.log("[Shamrock] Plan A failed: ${it.message}")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val pref = XSharedPreferences("moe.fuqiuluo.shamrock", "shared_config")
|
||||||
|
if (pref.file.canRead()) {
|
||||||
|
allowPersistent = pref.getBoolean("persistent", false)
|
||||||
|
XposedBridge.log("[Shamrock] allowPersistent = $allowPersistent")
|
||||||
|
} else {
|
||||||
|
XposedBridge.log("[Shamrock] unable to load XSharedPreferences")
|
||||||
|
}
|
||||||
|
|
||||||
kotlin.runCatching {
|
kotlin.runCatching {
|
||||||
val ProcessList = XposedHelpers.findClass("com.android.server.am.ProcessList", loader)
|
val ProcessList = XposedHelpers.findClass("com.android.server.am.ProcessList", loader)
|
||||||
ProcessList.hookMethod("newProcessRecordLocked").after {
|
ProcessList.hookMethod("newProcessRecordLocked").after {
|
||||||
increaseAdj(it.result)
|
increaseAdj(it.result)
|
||||||
}
|
}
|
||||||
}.onFailure {
|
}.onFailure {
|
||||||
XposedBridge.log("Plan B failed: ${it.message}")
|
XposedBridge.log("[Shamrock] Plan B failed: ${it.message}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,14 +87,14 @@ internal object FuckAMS {
|
|||||||
if (!it.isAccessible) it.isAccessible = true
|
if (!it.isAccessible) it.isAccessible = true
|
||||||
}.get(record) as ApplicationInfo
|
}.get(record) as ApplicationInfo
|
||||||
if(applicationInfo.processName in KeepPackage) {
|
if(applicationInfo.processName in KeepPackage) {
|
||||||
XposedBridge.log("Process is keeping: $record")
|
XposedBridge.log("[Shamrock] Process is keeping: $record")
|
||||||
KeepRecords.add(record)
|
KeepRecords.add(record)
|
||||||
keepByAdj(record)
|
keepByAdj(record)
|
||||||
// Error
|
// Error
|
||||||
//if (noDied.exists()) {
|
if (allowPersistent) {
|
||||||
// XposedBridge.log("Open NoDied Mode!!!")
|
XposedBridge.log("[Shamrock] Open NoDied Mode!!!")
|
||||||
// keepByPersistent(record)
|
keepByPersistent(record)
|
||||||
//}
|
}
|
||||||
checkThread()
|
checkThread()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user