diff --git a/app/src/main/java/xfk233/GenshinProxy/MainHook.kt b/app/src/main/java/xfk233/GenshinProxy/MainHook.kt
index e64ac52..ca08faf 100644
--- a/app/src/main/java/xfk233/GenshinProxy/MainHook.kt
+++ b/app/src/main/java/xfk233/GenshinProxy/MainHook.kt
@@ -3,65 +3,102 @@ package xfk233.GenshinProxy
import android.annotation.SuppressLint
import android.app.Activity
import android.app.AlertDialog
+import android.app.Application
+import android.content.Context
+import android.content.res.XModuleResources
import android.text.Editable
import android.text.TextWatcher
import android.widget.EditText
+import android.widget.LinearLayout
+import android.widget.Switch
import android.widget.Toast
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.findMethod
import com.github.kyuubiran.ezxhelper.utils.findMethodOrNull
import com.github.kyuubiran.ezxhelper.utils.hookBefore
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.callbacks.XC_LoadPackage
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 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) {
if (lpparam.packageName != "com.miHoYo.GenshinImpact") return
EzXHelperInit.initHandleLoadPackage(lpparam)
- findMethod("com.miHoYo.GetMobileInfo.MainActivity") { name == "onCreate" }.hookBefore {
- val context = it.thisObject as Activity
- val sp = context.getPreferences(0)
+ findMethod(Application::class.java, true) { name == "attachBaseContext" }.hookBefore {
+ val context = it.args[0] as Context
+ 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 {
- setTitle("Select server / 选择服务器")
- setMessage("Input server address / 请输入服务器地址: ")
- setView(EditText(context).apply {
- hint = "http(s)://server.com:1234"
- val str = sp.getString("serverip", "") ?: ""
- 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) {}
+ setCancelable(false)
+ setTitle(moduleRes.getString(R.string.SelectServer))
+ setMessage(moduleRes.getString(R.string.Tips))
+ setView(LinearLayout(context).apply {
+ orientation = LinearLayout.VERTICAL
+ addView(EditText(context).apply {
+ hint = "http(s)://server.com:1234"
+ val str = sp.getString("serverip", "") ?: ""
+ 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")
- override fun afterTextChanged(p0: Editable) {
+ @SuppressLint("CommitPrefEdits")
+ 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 {
- putString("serverip", p0.toString())
+ putBoolean("forceUrl", (it as Switch).isChecked)
apply()
}
+ forceUrl = (it as Switch).isChecked
}
})
})
- setNegativeButton("Custom server / 自定义服务器") { _, _ ->
+ setNegativeButton(moduleRes.getString(R.string.CustomServer)) { _, _ ->
val ip = sp.getString("serverip", "") ?: ""
if (ip == "") {
- Toast.makeText(context, "Server address error.", Toast.LENGTH_LONG).show()
- exitProcess(1)
+ Toast.makeText(context, moduleRes.getString(R.string.ServerAddressError), Toast.LENGTH_LONG).show()
+ context.finish()
} else {
server = ip
+ forceUrl = true
}
- sslHook(lpparam)
- hook()
}
- setNeutralButton("Official server / 官方服务器") { _, _ ->
+ setNeutralButton(moduleRes.getString(R.string.OfficialServer)) { _, _ ->
+ forceUrl = false
+ server = ""
}
}.show()
}
@@ -79,62 +116,40 @@ class MainHook : IXposedHookLoadPackage {
private fun hook() {
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())
- val m = regex.matcher(it.args[1].toString())
- if (m.find()) {
- it.args[1] = m.replaceAll(server)
- }
- XposedBridge.log("new: " + it.args[1].toString())
+ replaceUrl(it, 1)
}
findMethod("okhttp3.HttpUrl") { name == "parse" && parameterTypes[0] == String::class.java }.hookBefore {
- XposedBridge.log("old: " + it.args[0].toString())
- val m = regex.matcher(it.args[0].toString())
- if (m.find()) {
- it.args[0] = m.replaceAll(server)
- }
- XposedBridge.log("new: " + it.args[0].toString())
+ replaceUrl(it, 0)
}
findMethod("com.combosdk.lib.third.okhttp3.HttpUrl") { name == "parse" && parameterTypes[0] == String::class.java }.hookBefore {
- XposedBridge.log("old: " + it.args[0].toString())
- val m = regex.matcher(it.args[0].toString())
- if (m.find()) {
- it.args[0] = m.replaceAll(server)
- }
- XposedBridge.log("new: " + it.args[0].toString())
+ replaceUrl(it, 0)
}
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())
- val m = regex.matcher(it.args[0].toString())
- if (m.find()) {
- it.args[0] = m.replaceAll(server)
- }
- XposedBridge.log("new: " + it.args[0].toString())
+ replaceUrl(it, 0)
}
findConstructor("java.net.URL") { parameterTypes[0] == String::class.java }.hookBefore {
- XposedBridge.log("old: " + it.args[0].toString())
- val m = regex.matcher(it.args[0].toString())
- if (m.find()) {
- it.args[0] = m.replaceAll(server)
- }
- XposedBridge.log("new: " + it.args[0].toString())
+ replaceUrl(it, 0)
}
findMethod("com.combosdk.lib.third.okhttp3.Request\$Builder") { name == "url" && parameterTypes[0] == String::class.java }.hookBefore {
- XposedBridge.log("old: " + it.args[0].toString())
- val m = regex.matcher(it.args[0].toString())
- if (m.find()) {
- it.args[0] = m.replaceAll(server)
- }
- XposedBridge.log("new: " + it.args[0].toString())
+ replaceUrl(it, 0)
}
findMethod("okhttp3.Request\$Builder") { name == "url" && parameterTypes[0] == String::class.java }.hookBefore {
- XposedBridge.log("old: " + it.args[0].toString())
- val m = regex.matcher(it.args[0].toString())
- if (m.find()) {
- it.args[0] = m.replaceAll(server)
- }
- XposedBridge.log("new: " + it.args[0].toString())
+ replaceUrl(it, 0)
}
}
+
+ 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())
+ }
}
diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml
new file mode 100644
index 0000000..ab1fa84
--- /dev/null
+++ b/app/src/main/res/values-zh-rCN/strings.xml
@@ -0,0 +1,10 @@
+
+
+ Genshin Impact Proxy
+ 自定义服务器
+ 官方服务器
+ 选择服务器
+ 第一次使用请输入好服务器地址后进入官方服务器下载资源,之后便可进入私服。\n强制模式: 强制替换全部域名\n\n请输入服务器地址:
+ 强制模式 (需重启)
+ 服务器地址错误
+
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index fac8215..de32885 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -1,3 +1,9 @@
Genshin Impact Proxy
+ Custom server
+ Official server
+ Select server
+ 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:
+ Forced mode (restart required)
+ Server address error.
\ No newline at end of file