Add forced mode
This commit is contained in:
parent
27f2c13ff5
commit
d371a68382
@ -3,65 +3,102 @@ package xfk233.GenshinProxy
|
|||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.app.AlertDialog
|
import android.app.AlertDialog
|
||||||
|
import android.app.Application
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.res.XModuleResources
|
||||||
import android.text.Editable
|
import android.text.Editable
|
||||||
import android.text.TextWatcher
|
import android.text.TextWatcher
|
||||||
import android.widget.EditText
|
import android.widget.EditText
|
||||||
|
import android.widget.LinearLayout
|
||||||
|
import android.widget.Switch
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import com.github.kyuubiran.ezxhelper.init.EzXHelperInit
|
import com.github.kyuubiran.ezxhelper.init.EzXHelperInit
|
||||||
import com.github.kyuubiran.ezxhelper.init.InitFields
|
|
||||||
import com.github.kyuubiran.ezxhelper.utils.findConstructor
|
import com.github.kyuubiran.ezxhelper.utils.findConstructor
|
||||||
import com.github.kyuubiran.ezxhelper.utils.findMethod
|
import com.github.kyuubiran.ezxhelper.utils.findMethod
|
||||||
import com.github.kyuubiran.ezxhelper.utils.findMethodOrNull
|
import com.github.kyuubiran.ezxhelper.utils.findMethodOrNull
|
||||||
import com.github.kyuubiran.ezxhelper.utils.hookBefore
|
import com.github.kyuubiran.ezxhelper.utils.hookBefore
|
||||||
import de.robv.android.xposed.IXposedHookLoadPackage
|
import de.robv.android.xposed.IXposedHookLoadPackage
|
||||||
|
import de.robv.android.xposed.IXposedHookZygoteInit
|
||||||
|
import de.robv.android.xposed.XC_MethodHook
|
||||||
import de.robv.android.xposed.XposedBridge
|
import de.robv.android.xposed.XposedBridge
|
||||||
import de.robv.android.xposed.callbacks.XC_LoadPackage
|
import de.robv.android.xposed.callbacks.XC_LoadPackage
|
||||||
import java.util.regex.Pattern
|
import java.util.regex.Pattern
|
||||||
import kotlin.system.exitProcess
|
|
||||||
|
|
||||||
|
|
||||||
class MainHook : IXposedHookLoadPackage {
|
class MainHook : IXposedHookLoadPackage, IXposedHookZygoteInit {
|
||||||
private val regex = Pattern.compile("http(s|)://.*?\\.(hoyoverse|mihoyo|yuanshen|mob)\\.com")
|
private val regex = Pattern.compile("http(s|)://.*?\\.(hoyoverse|mihoyo|yuanshen|mob)\\.com")
|
||||||
private lateinit var server: String
|
private lateinit var server: String
|
||||||
|
private var forceUrl = false
|
||||||
|
private lateinit var modulePath: String
|
||||||
|
private lateinit var moduleRes: XModuleResources
|
||||||
|
|
||||||
|
override fun initZygote(startupParam: IXposedHookZygoteInit.StartupParam) {
|
||||||
|
modulePath = startupParam.modulePath
|
||||||
|
moduleRes = XModuleResources.createInstance(modulePath, null)
|
||||||
|
}
|
||||||
|
|
||||||
override fun handleLoadPackage(lpparam: XC_LoadPackage.LoadPackageParam) {
|
override fun handleLoadPackage(lpparam: XC_LoadPackage.LoadPackageParam) {
|
||||||
if (lpparam.packageName != "com.miHoYo.GenshinImpact") return
|
if (lpparam.packageName != "com.miHoYo.GenshinImpact") return
|
||||||
EzXHelperInit.initHandleLoadPackage(lpparam)
|
EzXHelperInit.initHandleLoadPackage(lpparam)
|
||||||
findMethod("com.miHoYo.GetMobileInfo.MainActivity") { name == "onCreate" }.hookBefore {
|
findMethod(Application::class.java, true) { name == "attachBaseContext" }.hookBefore {
|
||||||
val context = it.thisObject as Activity
|
val context = it.args[0] as Context
|
||||||
val sp = context.getPreferences(0)
|
val sp = context.getSharedPreferences("serverConfig", 0)
|
||||||
|
forceUrl = sp.getBoolean("forceUrl", false)
|
||||||
|
server = sp.getString("serverip", "") ?: ""
|
||||||
|
}
|
||||||
|
sslHook(lpparam)
|
||||||
|
hook()
|
||||||
|
findMethod("com.miHoYo.GetMobileInfo.MainActivity") { name == "onCreate" }.hookBefore { param ->
|
||||||
|
val context = param.thisObject as Activity
|
||||||
|
val sp = context.getSharedPreferences("serverConfig", 0)
|
||||||
AlertDialog.Builder(context).apply {
|
AlertDialog.Builder(context).apply {
|
||||||
setTitle("Select server / 选择服务器")
|
setCancelable(false)
|
||||||
setMessage("Input server address / 请输入服务器地址: ")
|
setTitle(moduleRes.getString(R.string.SelectServer))
|
||||||
setView(EditText(context).apply {
|
setMessage(moduleRes.getString(R.string.Tips))
|
||||||
hint = "http(s)://server.com:1234"
|
setView(LinearLayout(context).apply {
|
||||||
val str = sp.getString("serverip", "") ?: ""
|
orientation = LinearLayout.VERTICAL
|
||||||
setText(str.toCharArray(), 0, str.length)
|
addView(EditText(context).apply {
|
||||||
addTextChangedListener(object : TextWatcher {
|
hint = "http(s)://server.com:1234"
|
||||||
override fun beforeTextChanged(p0: CharSequence, p1: Int, p2: Int, p3: Int) {}
|
val str = sp.getString("serverip", "") ?: ""
|
||||||
override fun onTextChanged(p0: CharSequence, p1: Int, p2: Int, p3: Int) {}
|
setText(str.toCharArray(), 0, str.length)
|
||||||
|
addTextChangedListener(object : TextWatcher {
|
||||||
|
override fun beforeTextChanged(p0: CharSequence, p1: Int, p2: Int, p3: Int) {}
|
||||||
|
override fun onTextChanged(p0: CharSequence, p1: Int, p2: Int, p3: Int) {}
|
||||||
|
|
||||||
@SuppressLint("CommitPrefEdits")
|
@SuppressLint("CommitPrefEdits")
|
||||||
override fun afterTextChanged(p0: Editable) {
|
override fun afterTextChanged(p0: Editable) {
|
||||||
|
sp.edit().run {
|
||||||
|
putString("serverip", p0.toString())
|
||||||
|
apply()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
addView(Switch(context).apply {
|
||||||
|
text = moduleRes.getString(R.string.ForcedMode)
|
||||||
|
isChecked = sp.getBoolean("forceUrl", false)
|
||||||
|
setOnClickListener {
|
||||||
sp.edit().run {
|
sp.edit().run {
|
||||||
putString("serverip", p0.toString())
|
putBoolean("forceUrl", (it as Switch).isChecked)
|
||||||
apply()
|
apply()
|
||||||
}
|
}
|
||||||
|
forceUrl = (it as Switch).isChecked
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
setNegativeButton("Custom server / 自定义服务器") { _, _ ->
|
setNegativeButton(moduleRes.getString(R.string.CustomServer)) { _, _ ->
|
||||||
val ip = sp.getString("serverip", "") ?: ""
|
val ip = sp.getString("serverip", "") ?: ""
|
||||||
if (ip == "") {
|
if (ip == "") {
|
||||||
Toast.makeText(context, "Server address error.", Toast.LENGTH_LONG).show()
|
Toast.makeText(context, moduleRes.getString(R.string.ServerAddressError), Toast.LENGTH_LONG).show()
|
||||||
exitProcess(1)
|
context.finish()
|
||||||
} else {
|
} else {
|
||||||
server = ip
|
server = ip
|
||||||
|
forceUrl = true
|
||||||
}
|
}
|
||||||
sslHook(lpparam)
|
|
||||||
hook()
|
|
||||||
}
|
}
|
||||||
setNeutralButton("Official server / 官方服务器") { _, _ ->
|
setNeutralButton(moduleRes.getString(R.string.OfficialServer)) { _, _ ->
|
||||||
|
forceUrl = false
|
||||||
|
server = ""
|
||||||
}
|
}
|
||||||
}.show()
|
}.show()
|
||||||
}
|
}
|
||||||
@ -79,62 +116,40 @@ class MainHook : IXposedHookLoadPackage {
|
|||||||
|
|
||||||
private fun hook() {
|
private fun hook() {
|
||||||
findMethod("com.miHoYo.sdk.webview.MiHoYoWebview") { name == "load" && parameterTypes[0] == String::class.java && parameterTypes[1] == String::class.java }.hookBefore {
|
findMethod("com.miHoYo.sdk.webview.MiHoYoWebview") { name == "load" && parameterTypes[0] == String::class.java && parameterTypes[1] == String::class.java }.hookBefore {
|
||||||
XposedBridge.log("old: " + it.args[1].toString())
|
replaceUrl(it, 1)
|
||||||
val m = regex.matcher(it.args[1].toString())
|
|
||||||
if (m.find()) {
|
|
||||||
it.args[1] = m.replaceAll(server)
|
|
||||||
}
|
|
||||||
XposedBridge.log("new: " + it.args[1].toString())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
findMethod("okhttp3.HttpUrl") { name == "parse" && parameterTypes[0] == String::class.java }.hookBefore {
|
findMethod("okhttp3.HttpUrl") { name == "parse" && parameterTypes[0] == String::class.java }.hookBefore {
|
||||||
XposedBridge.log("old: " + it.args[0].toString())
|
replaceUrl(it, 0)
|
||||||
val m = regex.matcher(it.args[0].toString())
|
|
||||||
if (m.find()) {
|
|
||||||
it.args[0] = m.replaceAll(server)
|
|
||||||
}
|
|
||||||
XposedBridge.log("new: " + it.args[0].toString())
|
|
||||||
}
|
}
|
||||||
findMethod("com.combosdk.lib.third.okhttp3.HttpUrl") { name == "parse" && parameterTypes[0] == String::class.java }.hookBefore {
|
findMethod("com.combosdk.lib.third.okhttp3.HttpUrl") { name == "parse" && parameterTypes[0] == String::class.java }.hookBefore {
|
||||||
XposedBridge.log("old: " + it.args[0].toString())
|
replaceUrl(it, 0)
|
||||||
val m = regex.matcher(it.args[0].toString())
|
|
||||||
if (m.find()) {
|
|
||||||
it.args[0] = m.replaceAll(server)
|
|
||||||
}
|
|
||||||
XposedBridge.log("new: " + it.args[0].toString())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
findMethod("com.google.gson.Gson") { name == "fromJson" && parameterTypes[0] == String::class.java && parameterTypes[1] == java.lang.reflect.Type::class.java }.hookBefore {
|
findMethod("com.google.gson.Gson") { name == "fromJson" && parameterTypes[0] == String::class.java && parameterTypes[1] == java.lang.reflect.Type::class.java }.hookBefore {
|
||||||
XposedBridge.log("old: " + it.args[0].toString())
|
replaceUrl(it, 0)
|
||||||
val m = regex.matcher(it.args[0].toString())
|
|
||||||
if (m.find()) {
|
|
||||||
it.args[0] = m.replaceAll(server)
|
|
||||||
}
|
|
||||||
XposedBridge.log("new: " + it.args[0].toString())
|
|
||||||
}
|
}
|
||||||
findConstructor("java.net.URL") { parameterTypes[0] == String::class.java }.hookBefore {
|
findConstructor("java.net.URL") { parameterTypes[0] == String::class.java }.hookBefore {
|
||||||
XposedBridge.log("old: " + it.args[0].toString())
|
replaceUrl(it, 0)
|
||||||
val m = regex.matcher(it.args[0].toString())
|
|
||||||
if (m.find()) {
|
|
||||||
it.args[0] = m.replaceAll(server)
|
|
||||||
}
|
|
||||||
XposedBridge.log("new: " + it.args[0].toString())
|
|
||||||
}
|
}
|
||||||
findMethod("com.combosdk.lib.third.okhttp3.Request\$Builder") { name == "url" && parameterTypes[0] == String::class.java }.hookBefore {
|
findMethod("com.combosdk.lib.third.okhttp3.Request\$Builder") { name == "url" && parameterTypes[0] == String::class.java }.hookBefore {
|
||||||
XposedBridge.log("old: " + it.args[0].toString())
|
replaceUrl(it, 0)
|
||||||
val m = regex.matcher(it.args[0].toString())
|
|
||||||
if (m.find()) {
|
|
||||||
it.args[0] = m.replaceAll(server)
|
|
||||||
}
|
|
||||||
XposedBridge.log("new: " + it.args[0].toString())
|
|
||||||
}
|
}
|
||||||
findMethod("okhttp3.Request\$Builder") { name == "url" && parameterTypes[0] == String::class.java }.hookBefore {
|
findMethod("okhttp3.Request\$Builder") { name == "url" && parameterTypes[0] == String::class.java }.hookBefore {
|
||||||
XposedBridge.log("old: " + it.args[0].toString())
|
replaceUrl(it, 0)
|
||||||
val m = regex.matcher(it.args[0].toString())
|
|
||||||
if (m.find()) {
|
|
||||||
it.args[0] = m.replaceAll(server)
|
|
||||||
}
|
|
||||||
XposedBridge.log("new: " + it.args[0].toString())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun replaceUrl(method: XC_MethodHook.MethodHookParam, args: Int) {
|
||||||
|
if (!forceUrl) return
|
||||||
|
if (!this::server.isInitialized) return
|
||||||
|
if (server == "") return
|
||||||
|
|
||||||
|
if (BuildConfig.DEBUG) XposedBridge.log("old: " + method.args[args].toString())
|
||||||
|
val m = regex.matcher(method.args[args].toString())
|
||||||
|
if (m.find()) {
|
||||||
|
method.args[args] = m.replaceAll(server)
|
||||||
|
}
|
||||||
|
if (BuildConfig.DEBUG) XposedBridge.log("new: " + method.args[args].toString())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
10
app/src/main/res/values-zh-rCN/strings.xml
Normal file
10
app/src/main/res/values-zh-rCN/strings.xml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<string name="app_name">Genshin Impact Proxy</string>
|
||||||
|
<string name="CustomServer">自定义服务器</string>
|
||||||
|
<string name="OfficialServer">官方服务器</string>
|
||||||
|
<string name="SelectServer">选择服务器</string>
|
||||||
|
<string name="Tips">第一次使用请输入好服务器地址后进入官方服务器下载资源,之后便可进入私服。\n强制模式: 强制替换全部域名\n\n请输入服务器地址: </string>
|
||||||
|
<string name="ForcedMode">强制模式 (需重启)</string>
|
||||||
|
<string name="ServerAddressError">服务器地址错误</string>
|
||||||
|
</resources>
|
@ -1,3 +1,9 @@
|
|||||||
<resources>
|
<resources>
|
||||||
<string name="app_name">Genshin Impact Proxy</string>
|
<string name="app_name">Genshin Impact Proxy</string>
|
||||||
|
<string name="CustomServer">Custom server</string>
|
||||||
|
<string name="OfficialServer">Official server</string>
|
||||||
|
<string name="SelectServer">Select server</string>
|
||||||
|
<string name="Tips">For the first time, please enter the server address and enter the official server to download resources. Then you can enter the private server.\nForced mode: Forced replacement of all domain names\n\nInput server address: </string>
|
||||||
|
<string name="ForcedMode">Forced mode (restart required)</string>
|
||||||
|
<string name="ServerAddressError">Server address error.</string>
|
||||||
</resources>
|
</resources>
|
Loading…
Reference in New Issue
Block a user