├── .gitattributes ├── .gradle ├── 7.4.2 │ ├── checksums │ │ ├── checksums.lock │ │ ├── md5-checksums.bin │ │ └── sha1-checksums.bin │ ├── dependencies-accessors │ │ ├── dependencies-accessors.lock │ │ └── gc.properties │ ├── executionHistory │ │ ├── executionHistory.bin │ │ └── executionHistory.lock │ ├── fileChanges │ │ └── last-build.bin │ ├── fileHashes │ │ ├── fileHashes.bin │ │ ├── fileHashes.lock │ │ └── resourceHashesCache.bin │ └── gc.properties ├── buildOutputCleanup │ ├── buildOutputCleanup.lock │ ├── cache.properties │ └── outputFiles.bin └── vcs-1 │ └── gc.properties ├── README.md ├── app ├── build.gradle.kts └── src │ └── main │ ├── AndroidManifest.xml │ ├── assets │ └── xposed_init │ ├── java │ └── Xuoos │ │ └── GenshinImpact │ │ └── Proxy │ │ ├── Hook.kt │ │ ├── MainHook.kt │ │ ├── ToastCustom.java │ │ ├── TrustMeAlready.java │ │ └── Utils.kt │ └── res │ ├── mipmap │ └── xuoos.png │ └── values │ ├── arrays.xml │ └── strings.xml ├── build.gradle.kts ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle.kts /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.gradle/7.4.2/checksums/checksums.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xuoos/GenshinProxy/66d5acd9cf75042386f3b6d05ac8f9301d3644e0/.gradle/7.4.2/checksums/checksums.lock -------------------------------------------------------------------------------- /.gradle/7.4.2/checksums/md5-checksums.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xuoos/GenshinProxy/66d5acd9cf75042386f3b6d05ac8f9301d3644e0/.gradle/7.4.2/checksums/md5-checksums.bin -------------------------------------------------------------------------------- /.gradle/7.4.2/checksums/sha1-checksums.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xuoos/GenshinProxy/66d5acd9cf75042386f3b6d05ac8f9301d3644e0/.gradle/7.4.2/checksums/sha1-checksums.bin -------------------------------------------------------------------------------- /.gradle/7.4.2/dependencies-accessors/dependencies-accessors.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xuoos/GenshinProxy/66d5acd9cf75042386f3b6d05ac8f9301d3644e0/.gradle/7.4.2/dependencies-accessors/dependencies-accessors.lock -------------------------------------------------------------------------------- /.gradle/7.4.2/dependencies-accessors/gc.properties: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xuoos/GenshinProxy/66d5acd9cf75042386f3b6d05ac8f9301d3644e0/.gradle/7.4.2/dependencies-accessors/gc.properties -------------------------------------------------------------------------------- /.gradle/7.4.2/executionHistory/executionHistory.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xuoos/GenshinProxy/66d5acd9cf75042386f3b6d05ac8f9301d3644e0/.gradle/7.4.2/executionHistory/executionHistory.bin -------------------------------------------------------------------------------- /.gradle/7.4.2/executionHistory/executionHistory.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xuoos/GenshinProxy/66d5acd9cf75042386f3b6d05ac8f9301d3644e0/.gradle/7.4.2/executionHistory/executionHistory.lock -------------------------------------------------------------------------------- /.gradle/7.4.2/fileChanges/last-build.bin: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gradle/7.4.2/fileHashes/fileHashes.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xuoos/GenshinProxy/66d5acd9cf75042386f3b6d05ac8f9301d3644e0/.gradle/7.4.2/fileHashes/fileHashes.bin -------------------------------------------------------------------------------- /.gradle/7.4.2/fileHashes/fileHashes.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xuoos/GenshinProxy/66d5acd9cf75042386f3b6d05ac8f9301d3644e0/.gradle/7.4.2/fileHashes/fileHashes.lock -------------------------------------------------------------------------------- /.gradle/7.4.2/fileHashes/resourceHashesCache.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xuoos/GenshinProxy/66d5acd9cf75042386f3b6d05ac8f9301d3644e0/.gradle/7.4.2/fileHashes/resourceHashesCache.bin -------------------------------------------------------------------------------- /.gradle/7.4.2/gc.properties: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xuoos/GenshinProxy/66d5acd9cf75042386f3b6d05ac8f9301d3644e0/.gradle/7.4.2/gc.properties -------------------------------------------------------------------------------- /.gradle/buildOutputCleanup/buildOutputCleanup.lock: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xuoos/GenshinProxy/66d5acd9cf75042386f3b6d05ac8f9301d3644e0/.gradle/buildOutputCleanup/buildOutputCleanup.lock -------------------------------------------------------------------------------- /.gradle/buildOutputCleanup/cache.properties: -------------------------------------------------------------------------------- 1 | #Tue Mar 28 13:01:37 GMT 2023 2 | gradle.version=7.4.2 3 | -------------------------------------------------------------------------------- /.gradle/buildOutputCleanup/outputFiles.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xuoos/GenshinProxy/66d5acd9cf75042386f3b6d05ac8f9301d3644e0/.gradle/buildOutputCleanup/outputFiles.bin -------------------------------------------------------------------------------- /.gradle/vcs-1/gc.properties: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xuoos/GenshinProxy/66d5acd9cf75042386f3b6d05ac8f9301d3644e0/.gradle/vcs-1/gc.properties -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # GenshinProxy 2 | 3 | ### 4 | 本项目已不再更新,请查看我的另一个项目[AnimeGamesProxy]https://github.com/Xuoos/AnimeGamesProxy 5 | 6 | 基于方块君的GenshinProxy([577fkj](https://github.com/577fkj)) 修改 7 | 勿用于商业,否则我会直接删除本仓库 8 | 9 | qq group 782305852 10 | 11 | This is an xposed module that does not use a proxy to enter the grasscutter server 12 | 13 | 14 | -------------------------------------------------------------------------------- /app/build.gradle.kts: -------------------------------------------------------------------------------- 1 | 2 | plugins { 3 | id("com.android.application") 4 | id("kotlin-android") 5 | } 6 | 7 | android { 8 | compileSdk = 32 9 | 10 | defaultConfig { 11 | applicationId = "Xuoos.GenshinImpact.Proxy" 12 | minSdk = 28 13 | targetSdk = 32 14 | versionCode = 3 15 | versionName = "1.0.5" 16 | } 17 | 18 | 19 | 20 | buildTypes { 21 | release { 22 | isMinifyEnabled = false 23 | isShrinkResources = false 24 | setProguardFiles(listOf(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro", "proguard-log.pro")) 25 | } 26 | } 27 | 28 | compileOptions { 29 | sourceCompatibility = JavaVersion.VERSION_11 30 | targetCompatibility = JavaVersion.VERSION_11 31 | } 32 | 33 | kotlinOptions { 34 | jvmTarget = JavaVersion.VERSION_11.majorVersion 35 | } 36 | 37 | packagingOptions { 38 | resources { 39 | excludes += "/META-INF/**" 40 | excludes += "/kotlin/**" 41 | excludes += "/*.txt" 42 | excludes += "/*.bin" 43 | } 44 | } 45 | 46 | applicationVariants.all { 47 | outputs.all { 48 | (this as com.android.build.gradle.internal.api.BaseVariantOutputImpl).outputFileName = 49 | "GI-Proxy-Xuoos-$name.apk" 50 | } 51 | } 52 | } 53 | 54 | dependencies { 55 | compileOnly("de.robv.android.xposed:api:82") 56 | compileOnly("de.robv.android.xposed:api:82:sources") 57 | implementation("com.github.kyuubiran:EzXHelper:0.9.2") 58 | implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.0") 59 | } 60 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | 13 | 16 | 19 | 22 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /app/src/main/assets/xposed_init: -------------------------------------------------------------------------------- 1 | Xuoos.GenshinImpact.Proxy.MainHook -------------------------------------------------------------------------------- /app/src/main/java/Xuoos/GenshinImpact/Proxy/Hook.kt: -------------------------------------------------------------------------------- 1 | package Xuoos.GenshinImpact.Proxy 2 | 3 | import android.app.Activity 4 | import android.app.AlertDialog 5 | //==== 6 | import android.content.ClipboardManager 7 | import android.content.Context 8 | import android.content.SharedPreferences 9 | import android.content.res.XModuleResources 10 | //==== 11 | import android.graphics.Color 12 | import android.graphics.Paint 13 | import android.graphics.Typeface 14 | import android.graphics.PixelFormat 15 | import android.graphics.drawable.ShapeDrawable 16 | import android.graphics.drawable.shapes.RoundRectShape 17 | import android.graphics.drawable.ColorDrawable 18 | import android.graphics.drawable.Drawable 19 | import android.graphics.drawable.TransitionDrawable 20 | //==== 21 | import android.text.style.StyleSpan 22 | import android.text.Spannable 23 | import android.text.SpannableString 24 | import android.text.style.ForegroundColorSpan 25 | import android.text.style.UnderlineSpan 26 | import android.text.Editable 27 | import android.text.InputType 28 | import android.text.TextWatcher 29 | //===== 30 | import android.view.Gravity 31 | import android.view.MotionEvent 32 | import android.view.View 33 | import android.view.WindowManager 34 | //===== 35 | import android.widget.LinearLayout 36 | import android.widget.TextView 37 | import android.widget.* 38 | //==== 39 | import com.github.kyuubiran.ezxhelper.init.EzXHelperInit 40 | import com.github.kyuubiran.ezxhelper.utils.* 41 | //==== 42 | import de.robv.android.xposed.IXposedHookZygoteInit 43 | import de.robv.android.xposed.XC_MethodHook 44 | import de.robv.android.xposed.XposedBridge 45 | import de.robv.android.xposed.XposedHelpers 46 | import de.robv.android.xposed.callbacks.XC_LoadPackage 47 | //==== 48 | import Xuoos.GenshinImpact.Proxy.Utils.dp2px 49 | //==== 50 | import java.io.BufferedReader 51 | import java.io.ByteArrayOutputStream 52 | import java.io.File 53 | import java.math.BigInteger 54 | import java.security.SecureRandom 55 | import java.security.cert.X509Certificate 56 | import java.util.regex.Pattern 57 | import java.io.IOException 58 | import java.util.* 59 | //==== 60 | import javax.net.ssl.* 61 | import java.net.HttpURLConnection 62 | import java.net.URL 63 | //==== 64 | import kotlinx.coroutines.Dispatchers 65 | import kotlinx.coroutines.GlobalScope 66 | import kotlinx.coroutines.launch 67 | import kotlinx.coroutines.withContext 68 | import kotlin.concurrent.thread 69 | import kotlin.system.exitProcess 70 | //==== 71 | import android.webkit.SslErrorHandler 72 | import android.annotation.SuppressLint 73 | 74 | class Hook { 75 | 76 | private var SaveIP = "" 77 | private var SizeError = false 78 | 79 | private val red = Color.RED 80 | private val blue = Color.BLUE 81 | private val white = Color.WHITE 82 | private val black = Color.BLACK 83 | private val green = Color.GREEN 84 | private val yellow = Color.YELLOW 85 | private val Toast = ToastCustom.createToastConfig() 86 | 87 | private lateinit var server: String 88 | private lateinit var modulePath: String 89 | private lateinit var dialog: LinearLayout 90 | private lateinit var PackageName: String 91 | private lateinit var sp: SharedPreferences 92 | private lateinit var moduleRes: XModuleResources 93 | private lateinit var windowManager: WindowManager 94 | 95 | private val regex = Pattern.compile("http(s|)://.*?\\.(hk4e|hoyoverse|mihoyo|yuanshen|mob)\\.com") 96 | 97 | private val more_domain = 98 | arrayListOf( 99 | "overseauspider.yuanshen.com:8888", 100 | "uspider.yuanshen.com:8888" 101 | ) 102 | 103 | private val activityList: ArrayList = arrayListOf() 104 | private var activity: Activity 105 | get() { 106 | for (mActivity in activityList) { 107 | if (mActivity.isFinishing) { 108 | activityList.remove(mActivity) 109 | } else { 110 | return mActivity 111 | } 112 | } 113 | throw Throwable("Activity not found.") 114 | } 115 | set(value) { 116 | activityList.add(value) 117 | } 118 | 119 | private fun getDefaultSSLSocketFactory(): SSLSocketFactory { 120 | return SSLContext.getInstance("TLS").apply { 121 | init(arrayOf(), arrayOf(DefaultTrustManager()), SecureRandom()) 122 | }.socketFactory 123 | } 124 | 125 | private fun getDefaultHostnameVerifier(): HostnameVerifier { 126 | return DefaultHostnameVerifier() 127 | } 128 | 129 | class DefaultHostnameVerifier : HostnameVerifier { 130 | @SuppressLint("BadHostnameVerifier") 131 | override fun verify(p0: String?, p1: SSLSession?): Boolean { 132 | return true 133 | } 134 | 135 | } 136 | 137 | @SuppressLint("CustomX509TrustManager") 138 | private class DefaultTrustManager : X509TrustManager { 139 | 140 | @SuppressLint("TrustAllX509TrustManager") 141 | override fun checkClientTrusted(chain: Array?, authType: String?) { 142 | } 143 | 144 | @SuppressLint("TrustAllX509TrustManager") 145 | override fun checkServerTrusted(chain: Array?, authType: String?) { 146 | } 147 | 148 | override fun getAcceptedIssuers(): Array { 149 | return arrayOf() 150 | } 151 | } 152 | 153 | fun initZygote(startupParam: IXposedHookZygoteInit.StartupParam) { 154 | modulePath = startupParam.modulePath 155 | moduleRes = XModuleResources.createInstance(modulePath, null) 156 | TrustMeAlready().initZygote() 157 | } 158 | 159 | @SuppressLint("WrongConstant", "ClickableViewAccessibility") 160 | fun handleLoadPackage(lpparam: XC_LoadPackage.LoadPackageParam) { 161 | 162 | if (lpparam.packageName == "com.miHoYo.GenshinImpact" || lpparam.packageName == "com.miHoYo.Yuanshen" || lpparam.packageName == "com.miHoYo.YuanshenPS") { 163 | PackageName = lpparam.packageName 164 | EzXHelperInit.initHandleLoadPackage(lpparam) 165 | 166 | fun getFolderSize(folderPath: String): Long { 167 | val folder = File(folderPath) 168 | var totalSize: Long = 0 169 | 170 | if (folder.exists() && folder.isDirectory) { 171 | folder.listFiles()?.forEach { file -> 172 | totalSize += if (file.isFile) file.length() else getFolderSize(file.absolutePath) 173 | } 174 | } 175 | return totalSize 176 | } 177 | 178 | val folderPath = "/sdcard/Android/data/${PackageName}/files" 179 | val folderSize = getFolderSize(folderPath) 180 | var size = "无法获取" 181 | var unit = "" 182 | 183 | if (folderSize < 20L * 1024 * 1024 * 1024) { 184 | 185 | if (folderSize < 1024 * 1024) { 186 | size = (folderSize / 1024).toString() 187 | unit = "KB" 188 | } else if (folderSize < 1024 * 1024 * 1024) { 189 | size = String.format("%.2f", folderSize.toFloat() / (1024 * 1024)) 190 | unit = "MB" 191 | } else { 192 | size = String.format("%.2f", folderSize.toFloat() / (1024 * 1024 * 1024)) 193 | unit = "GB" 194 | } 195 | if (size == "0") { 196 | size = "无法获取" 197 | unit = "" 198 | } 199 | SizeError = true 200 | } 201 | 202 | SSLHook() 203 | HttpHook() 204 | 205 | findMethod("com.combosdk.openapi.ComboApplication") { name == "attachBaseContext" }.hookBefore { 206 | val context = it.args[0] as Context 207 | sp = context.getSharedPreferences("ProxyConfig", 0) 208 | if (!sp.contains("serverip")) { 209 | sp.edit().putString("serverip", "https://127.0.0.1:54321").apply() 210 | XposedBridge.log("W: serverip不存在,使用默认地址") 211 | } 212 | 213 | server = sp.getString("serverip", "") ?: "" 214 | 215 | if (!sp.contains("ResCheck")) { 216 | sp.edit().putBoolean("ResCheck", true).apply() 217 | XposedBridge.log("W: rescheck不存在,自动启用") 218 | } 219 | 220 | if (sp.getBoolean("ResCheck", true)) { 221 | if (SizeError == true) { 222 | server = "" 223 | } 224 | } 225 | } 226 | 227 | findMethod("com.miHoYo.GetMobileInfo.MainActivity") { name == "onCreate" }.hookBefore { param -> 228 | activity = param.thisObject as Activity 229 | 230 | if (sp.getBoolean("AutoDelCache", false)) AutoDelCache() 231 | if (sp.getBoolean("AtDelLl2cppFolder", false)) AutoDelLl2cppFolder() 232 | 233 | if (sp.getBoolean("ResCheck", true)) { 234 | if (SizeError == true) { 235 | Toast.show(activity, "客户端无数据/数据不完整,大小:\t${size}${unit}", 0, yellow, black) 236 | Toast.show(activity, "自动进入资源下载服务器...", 0, white, black) 237 | } 238 | } 239 | 240 | if (server.startsWith("https:") || server.startsWith("http:")) { 241 | GlobalScope.launch { 242 | val serverStatus = checkServerAvailability() 243 | var ToastColor: Int 244 | if (serverStatus.startsWith("目标服务器可")) { 245 | ToastColor = green 246 | } else { 247 | ToastColor = red 248 | } 249 | 250 | withContext(Dispatchers.Main) { 251 | Toast.show_ServerStatus(activity, serverStatus, 1, ToastColor, black) 252 | } 253 | } 254 | } else { 255 | Toast.show_ServerStatus(activity, "地址错误,无法获取服务器状态", 1, red, black) 256 | } 257 | 258 | activity.windowManager.addView(LinearLayout(activity).apply { 259 | dialog = this 260 | visibility = View.GONE 261 | setGravity(Gravity.CENTER) 262 | background = ShapeDrawable().apply { 263 | shape = RoundRectShape(floatArrayOf(20f, 20f, 20f, 20f, 20f, 20f, 20f, 20f), null, null) 264 | paint.color = Color.argb((255 * 0.90).toInt(), 0x80, 0x8E, 0xEA) 265 | } 266 | 267 | addView(TextView(activity).apply { 268 | layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT).also { 269 | } 270 | setTextColor(Color.RED) 271 | setGravity(Gravity.CENTER) 272 | setOnClickListener { 273 | showDialog() 274 | } 275 | }) 276 | }, WindowManager.LayoutParams(dp2px(activity, 200f), dp2px(activity, 90f), WindowManager.LayoutParams.TYPE_APPLICATION, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, PixelFormat.TRANSLUCENT).apply { 277 | gravity = Gravity.CENTER_VERTICAL 278 | x = 0 279 | y = 0 280 | }) 281 | 282 | // 随机颜色 283 | fun getRainbowColor(): Int { 284 | val rainbowColors = intArrayOf( 285 | Color.parseColor("#FF8C00"), // 橙色 286 | Color.parseColor("#FFFF00"), // 黄色 287 | Color.parseColor("#008000"), // 绿色 288 | Color.parseColor("#0000FF"), // 蓝色 289 | Color.parseColor("#4B0082"), // 靛蓝色 290 | Color.parseColor("#EE82EE"), // 紫罗兰色 291 | Color.parseColor("#800000"), // 栗色 292 | Color.parseColor("#808000"), // 橄榄色 293 | Color.parseColor("#00FFFF") // 青色 294 | ) 295 | val random = Random() 296 | return rainbowColors[random.nextInt(rainbowColors.size)] 297 | } 298 | 299 | var ShowIP = server 300 | if (ShowIP == "") { 301 | ShowIP = "未设置地址(连接至官方服务器)" 302 | } 303 | 304 | val sb = StringBuilder() 305 | sb.append("→点我打开代理设置←\n") 306 | sb.append("目标服务器:\n") 307 | val startIndex = sb.length 308 | sb.append(ShowIP) 309 | val originalString = sb.toString() 310 | 311 | Thread { 312 | runOnMainThread { 313 | val textView = dialog.getChildAt(0) as? TextView 314 | textView?.let { 315 | it.text = originalString 316 | val span = SpannableString(originalString) 317 | span.setSpan(ForegroundColorSpan(Color.GREEN), 0, 10, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE) 318 | span.setSpan(ForegroundColorSpan(getRainbowColor()), startIndex, startIndex + ShowIP.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE) 319 | span.setSpan(UnderlineSpan(), startIndex, startIndex + ShowIP.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE) 320 | span.setSpan(StyleSpan(Typeface.BOLD), startIndex, startIndex + ShowIP.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE) 321 | it.text = span 322 | dialog.visibility = View.VISIBLE 323 | } 324 | } 325 | Thread.sleep(8000) 326 | runOnMainThread { 327 | dialog.visibility = View.GONE 328 | activity.windowManager.removeView(dialog) 329 | } 330 | }.start() 331 | } 332 | } else { 333 | XposedBridge.log("E: 被注入应用不是目标应用,包名:" + lpparam.packageName) 334 | } 335 | } 336 | 337 | private fun AutoDelCache() { 338 | try { 339 | val cachePath = File("/sdcard/Android/data/${PackageName}/cache") 340 | val cache1Path = File("/sdcard/Android/data/${PackageName}/files/gee_logger_cache") 341 | val cache2Path = File("/data/data/${PackageName}/code_cache") 342 | val cache3Path = File("/data/data/${PackageName}/cache/WebView") 343 | val cache4Path = File("/data/data/${PackageName}/app_webview/Default/GPUCache") 344 | if (cachePath.exists()) { 345 | cachePath.deleteRecursively() 346 | } 347 | if (cache1Path.exists()) { 348 | cache1Path.deleteRecursively() 349 | } 350 | if (cache2Path.exists()) { 351 | cache2Path.deleteRecursively() 352 | } 353 | if (cache3Path.exists()) { 354 | cache3Path.deleteRecursively() 355 | } 356 | if (cache4Path.exists()) { 357 | cache4Path.deleteRecursively() 358 | } 359 | } catch (e: IOException) { 360 | Toast.show(activity, "删除缓存时发生错误\n" + e.toString(), 1, red, white) 361 | XposedBridge.log("E: 删除缓存失败" + e.toString()) 362 | } 363 | } 364 | 365 | private val cornerRadius = 25f 366 | private val dialogBg = ShapeDrawable().apply { 367 | paint.color = Color.parseColor("#E6E7F8FF") 368 | shape = RoundRectShape(floatArrayOf(cornerRadius, cornerRadius,cornerRadius, cornerRadius,cornerRadius, cornerRadius,cornerRadius, cornerRadius), null, null) 369 | } 370 | 371 | private fun IPDialog() { 372 | val subject = arrayOf( 373 | "自定义服务器", 374 | "本地服务器" 375 | ) 376 | var selectedSubject = subject[0] 377 | AlertDialog.Builder(activity).apply { 378 | setTitle("请选择服务器:") 379 | setCancelable(false) 380 | setSingleChoiceItems(subject, 0) { _, which -> 381 | selectedSubject = subject[which] 382 | } 383 | setPositiveButton("确定") { _, _ -> 384 | when (selectedSubject) { 385 | "自定义服务器" -> { 386 | CustomIPDialog() 387 | } 388 | "本地服务器" -> { 389 | sp.edit().run { 390 | putString("serverip", "https://127.0.0.1:54321") 391 | apply() 392 | Toast.show(activity, "已保存地址设置,请重新打开客户端~", 0, green, black) 393 | thread { 394 | Thread.sleep(2100) 395 | exitProcess(0) 396 | } 397 | } 398 | } 399 | } 400 | } 401 | setNeutralButton("取消") { _, _ -> 402 | showDialog() 403 | } 404 | }.create().apply { 405 | window?.setBackgroundDrawable(dialogBg) 406 | window?.setGravity(Gravity.CENTER) 407 | show() 408 | } 409 | } 410 | 411 | private fun showDialog() { 412 | AlertDialog.Builder(activity).apply { 413 | setTitle("代理设置") 414 | setMessage("倒卖🐶骨灰都给你妈扬咯") 415 | setCancelable(false) 416 | setView(ScrollView(context).apply { 417 | setPadding(25, 0, 25, 0) 418 | addView(LinearLayout(activity).apply { 419 | orientation = LinearLayout.VERTICAL 420 | addView(Switch(activity).apply { 421 | text = "游戏数据检测 (需重启)" 422 | isChecked = sp.getBoolean("ResCheck", false) 423 | setOnCheckedChangeListener { _, b -> 424 | sp.edit().run { 425 | putBoolean("ResCheck", b) 426 | apply() 427 | } 428 | } 429 | }) 430 | addView(Switch(activity).apply { 431 | text = "自动删除客户端缓存 (需重启)" 432 | isChecked = sp.getBoolean("AutoDelCache", false) 433 | setOnCheckedChangeListener { _, b -> 434 | sp.edit().run { 435 | putBoolean("AutoDelCache", b) 436 | apply() 437 | } 438 | } 439 | }) 440 | addView(Switch(activity).apply { 441 | text = "自动删除“il2cpp”文件夹 (需重启)" 442 | isChecked = sp.getBoolean("AtDelLl2cppFolder", false) 443 | setOnCheckedChangeListener { _, b -> 444 | sp.edit().run { 445 | putBoolean("AtDelLl2cppFolder", b) 446 | apply() 447 | } 448 | } 449 | }) 450 | }) 451 | }) 452 | setPositiveButton("关闭") { _, _ -> 453 | // 无 454 | } 455 | setNegativeButton("修改服务器地址") { _, _ -> 456 | IPDialog() 457 | } 458 | setNeutralButton("🚫退出游戏") { _, _ -> 459 | exitProcess(0) 460 | } 461 | }.create().apply { 462 | window?.setBackgroundDrawable(dialogBg) 463 | window?.setGravity(Gravity.CENTER) 464 | show() 465 | } 466 | } 467 | 468 | private fun CustomIPDialog() { 469 | AlertDialog.Builder(activity).apply { 470 | setTitle("请输入服务器地址:") 471 | setCancelable(false) 472 | setView(ScrollView(context).apply { 473 | setPadding(25, 0, 25, 0) 474 | addView(LinearLayout(activity).apply { 475 | orientation = LinearLayout.VERTICAL 476 | addView(EditText(activity).apply { 477 | //输入框提示 478 | hint = "http(s)://server.com:1234" 479 | //输入框显示内容 480 | val str = "" 481 | setText(str.toCharArray(), 0, str.length) 482 | addTextChangedListener(object : TextWatcher { 483 | override fun beforeTextChanged(p0: CharSequence, p1: Int, p2: Int, p3: Int) {} 484 | override fun onTextChanged(p0: CharSequence, p1: Int, p2: Int, p3: Int) {} 485 | 486 | @SuppressLint("CommitPrefEdits") 487 | override fun afterTextChanged(p0: Editable) { 488 | val import_ip = p0.toString() 489 | if (import_ip == "") { 490 | SaveIP = "" 491 | } else if (import_ip == "localhost" || import_ip == "127.0.0.1") { 492 | SaveIP = "https://127.0.0.1:54321" 493 | } else if (!import_ip.startsWith("https://") && !import_ip.startsWith("http://")) { 494 | SaveIP = "https://" + import_ip 495 | } else { 496 | SaveIP = import_ip 497 | } 498 | } 499 | }) 500 | }) 501 | }) 502 | }) 503 | setNeutralButton("返回") { _, _ -> 504 | showDialog() 505 | } 506 | setPositiveButton("保存地址") { _, _ -> 507 | if (SaveIP == "") { 508 | Toast.show(activity, "错误: 输入框未填写任何内容", 0, red, white) 509 | CustomIPDialog() 510 | } else if (SaveIP.endsWith("/")) { 511 | Toast.show(activity, "错误: 地址结尾不能有“/”!", 0, red, white) 512 | SaveIP = "" 513 | CustomIPDialog() 514 | } else { 515 | sp.edit().run { 516 | putString("serverip", SaveIP) 517 | apply() 518 | val ser_ip = sp.getString("serverip", "") ?: "" 519 | Toast.show(activity, "已保存地址:\t${ser_ip}", 0, green, black) 520 | Toast.show(activity, "请重新打开客户端~", 0, white, black) 521 | thread { 522 | Thread.sleep(4200) 523 | exitProcess(0) 524 | } 525 | } 526 | } 527 | } 528 | }.create().apply { 529 | window?.setBackgroundDrawable(dialogBg) 530 | window?.setGravity(Gravity.CENTER) 531 | show() 532 | } 533 | } 534 | 535 | private fun AutoDelLl2cppFolder() { 536 | try { 537 | val il2cppPath = File("/sdcard/Android/data/${PackageName}/files/il2cpp") 538 | if (il2cppPath.exists()) { 539 | il2cppPath.deleteRecursively() 540 | } 541 | } catch (e: IOException) { 542 | Toast.show(activity, "删除il2cpp文件夹时发生错误\n" + e.toString(), 1, red, white) 543 | XposedBridge.log("E: 删除il2cpp失败" + e.toString()) 544 | } 545 | } 546 | 547 | private fun SSLHook() { 548 | // OkHttp3 Hook 549 | findMethodOrNull("com.combosdk.lib.third.okhttp3.OkHttpClient\$Builder") { name == "build" } 550 | ?.hookBefore { 551 | it.thisObject.invokeMethod( 552 | "sslSocketFactory", 553 | args(getDefaultSSLSocketFactory()), 554 | argTypes(SSLSocketFactory::class.java) 555 | ) 556 | it.thisObject.invokeMethod( 557 | "hostnameVerifier", 558 | args(getDefaultHostnameVerifier()), 559 | argTypes(HostnameVerifier::class.java) 560 | ) 561 | } 562 | findMethodOrNull("okhttp3.OkHttpClient\$Builder") { name == "build" }?.hookBefore { 563 | it.thisObject.invokeMethod( 564 | "sslSocketFactory", 565 | args(getDefaultSSLSocketFactory(), DefaultTrustManager()), 566 | argTypes(SSLSocketFactory::class.java, X509TrustManager::class.java) 567 | ) 568 | it.thisObject.invokeMethod( 569 | "hostnameVerifier", 570 | args(getDefaultHostnameVerifier()), 571 | argTypes(HostnameVerifier::class.java) 572 | ) 573 | } 574 | // WebView Hook 575 | arrayListOf( 576 | "android.webkit.WebViewClient", 577 | //"cn.sharesdk.framework.g", 578 | //"com.facebook.internal.WebDialog\$DialogWebViewClient", 579 | "com.geetest.sdk.dialog.views.GtWebView\$c", 580 | "com.miHoYo.sdk.webview.common.view.ContentWebView\$6" 581 | ) 582 | .forEach { 583 | findMethodOrNull(it) { 584 | name == "onReceivedSslError" && 585 | parameterTypes[1] == SslErrorHandler::class.java 586 | } 587 | ?.hookBefore { param -> (param.args[1] as SslErrorHandler).proceed() } 588 | } 589 | // Android HttpsURLConnection Hook 590 | findMethodOrNull("javax.net.ssl.HttpsURLConnection") { 591 | name == "getDefaultSSLSocketFactory" 592 | } 593 | ?.hookBefore { it.result = getDefaultSSLSocketFactory() } 594 | findMethodOrNull("javax.net.ssl.HttpsURLConnection") { name == "setSSLSocketFactory" } 595 | ?.hookBefore { it.result = null } 596 | findMethodOrNull("javax.net.ssl.HttpsURLConnection") { 597 | name == "setDefaultSSLSocketFactory" 598 | } 599 | ?.hookBefore { it.result = null } 600 | findMethodOrNull("javax.net.ssl.HttpsURLConnection") { name == "setHostnameVerifier" } 601 | ?.hookBefore { it.result = null } 602 | findMethodOrNull("javax.net.ssl.HttpsURLConnection") { 603 | name == "setDefaultHostnameVerifier" 604 | } 605 | ?.hookBefore { it.result = null } 606 | findMethodOrNull("javax.net.ssl.HttpsURLConnection") { 607 | name == "getDefaultHostnameVerifier" 608 | } 609 | ?.hookBefore { it.result = getDefaultHostnameVerifier() } 610 | } 611 | 612 | // Bypass HTTP 613 | private fun HttpHook() { 614 | findMethod("com.miHoYo.sdk.webview.MiHoYoWebview") { 615 | name == "load" && 616 | parameterTypes[0] == String::class.java && 617 | parameterTypes[1] == String::class.java 618 | } 619 | .hookBefore { replaceUrl(it, 1) } 620 | findAllMethods("android.webkit.WebView") { name == "loadUrl" }.hookBefore { 621 | replaceUrl(it, 0) 622 | } 623 | findAllMethods("android.webkit.WebView") { name == "postUrl" }.hookBefore { 624 | replaceUrl(it, 0) 625 | } 626 | 627 | findMethod("okhttp3.HttpUrl") { name == "parse" && parameterTypes[0] == String::class.java } 628 | .hookBefore { replaceUrl(it, 0) } 629 | findMethod("com.combosdk.lib.third.okhttp3.HttpUrl") { 630 | name == "parse" && parameterTypes[0] == String::class.java 631 | } 632 | .hookBefore { replaceUrl(it, 0) } 633 | 634 | findMethod("com.google.gson.Gson") { 635 | name == "fromJson" && 636 | parameterTypes[0] == String::class.java && 637 | parameterTypes[1] == java.lang.reflect.Type::class.java 638 | } 639 | .hookBefore { replaceUrl(it, 0) } 640 | findConstructor("java.net.URL") { parameterTypes[0] == String::class.java }.hookBefore { 641 | replaceUrl(it, 0) 642 | } 643 | findMethod("com.combosdk.lib.third.okhttp3.Request\$Builder") { 644 | name == "url" && parameterTypes[0] == String::class.java 645 | } 646 | .hookBefore { replaceUrl(it, 0) } 647 | findMethod("okhttp3.Request\$Builder") { 648 | name == "url" && parameterTypes[0] == String::class.java 649 | } 650 | .hookBefore { replaceUrl(it, 0) } 651 | } 652 | 653 | private suspend fun checkServerAvailability(): String = withContext(Dispatchers.IO) { 654 | val url = URL(server) 655 | val connection = url.openConnection() as HttpURLConnection 656 | connection.requestMethod = "GET" 657 | 658 | try { 659 | val startTime = System.currentTimeMillis() 660 | connection.connect() 661 | val responseCode = connection.responseCode 662 | if (responseCode == HttpURLConnection.HTTP_OK) { 663 | val endTime = System.currentTimeMillis() 664 | val delay = endTime - startTime 665 | 666 | "目标服务器可用\nSuccessfully connect to " + server + "\n请求耗时: ${delay}毫秒" 667 | } else if (responseCode in 400..499) { 668 | "目标服务器存在异常,服务器无法处理请求\nHTTP状态码:" + responseCode 669 | } else if (responseCode in 500..599) { 670 | "目标服务器存在异常,服务器处理请求时出错\nHTTP状态码:" + responseCode 671 | } else { 672 | "目标服务器存在异常,原因未知" 673 | } 674 | } catch (e: Exception) { 675 | "无法连接至目标服务器,错误:\n" + e.toString() 676 | } finally { 677 | connection.disconnect() 678 | } 679 | } 680 | 681 | private fun replaceUrl(method: XC_MethodHook.MethodHookParam, args: Int) { 682 | var Xuoos = method.args[args].toString() 683 | val m = regex.matcher(Xuoos) 684 | 685 | if (server == "" || Xuoos == "" || method.args[args] == null) return 686 | for (list in more_domain) { 687 | for (head in arrayListOf("http://", "https://")) { 688 | method.args[args] = method.args[args].toString().replace(head + list, server) 689 | } 690 | } 691 | 692 | if (m.find()) { 693 | method.args[args] = m.replaceAll(server) 694 | } 695 | } 696 | } -------------------------------------------------------------------------------- /app/src/main/java/Xuoos/GenshinImpact/Proxy/MainHook.kt: -------------------------------------------------------------------------------- 1 | package Xuoos.GenshinImpact.Proxy 2 | 3 | import de.robv.android.xposed.IXposedHookLoadPackage 4 | import de.robv.android.xposed.IXposedHookZygoteInit 5 | import de.robv.android.xposed.callbacks.XC_LoadPackage 6 | 7 | class MainHook : IXposedHookLoadPackage, IXposedHookZygoteInit { 8 | private val hook: Hook = Hook() 9 | 10 | override fun handleLoadPackage(lpparam: XC_LoadPackage.LoadPackageParam) { 11 | hook.handleLoadPackage(lpparam) 12 | } 13 | 14 | override fun initZygote(startupParam: IXposedHookZygoteInit.StartupParam) { 15 | hook.initZygote(startupParam) 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /app/src/main/java/Xuoos/GenshinImpact/Proxy/ToastCustom.java: -------------------------------------------------------------------------------- 1 | package Xuoos.GenshinImpact.Proxy; 2 | 3 | import android.app.Activity; 4 | import android.graphics.Color; 5 | import android.graphics.drawable.ShapeDrawable; 6 | import android.graphics.drawable.shapes.RoundRectShape; 7 | import android.view.Gravity; 8 | import android.view.View; 9 | import android.widget.TextView; 10 | import android.widget.Toast; 11 | 12 | public class ToastCustom { 13 | private Toast toast; 14 | 15 | private static ToastCustom toastCustom; 16 | 17 | public static ToastCustom createToastConfig() { 18 | if (toastCustom == null) { 19 | toastCustom = new ToastCustom(); 20 | } 21 | return toastCustom; 22 | } 23 | 24 | public void show(Activity activity, String msg, int duration, int backgroundColor, int textColor) { 25 | TextView toastView = new TextView(activity); 26 | toastView.setText(msg); 27 | toastView.setTextColor(textColor); 28 | toastView.setGravity(Gravity.CENTER); 29 | toastView.setBackgroundColor(backgroundColor); 30 | toastView.setPadding(25, 30, 25, 30); 31 | float radius = 20f; 32 | ShapeDrawable shapeDrawable = new ShapeDrawable(new RoundRectShape(new float[]{radius, radius, radius, radius, radius, radius, radius, radius}, null, null)); 33 | shapeDrawable.getPaint().setColor(backgroundColor); 34 | toastView.setBackground(shapeDrawable); 35 | 36 | toast = new Toast(activity); 37 | toast.setGravity(Gravity.BOTTOM, 0, 80); 38 | if (duration == 1) { 39 | toast.setDuration(Toast.LENGTH_LONG); 40 | } else { 41 | toast.setDuration(Toast.LENGTH_SHORT); 42 | } 43 | toast.setView(toastView); 44 | 45 | View view = toast.getView(); 46 | if (view != null) { 47 | view.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED); 48 | int width = view.getMeasuredWidth(); 49 | int height = view.getMeasuredHeight(); 50 | view.setPadding(0, 0, 0, 0); 51 | view.setMinimumWidth(width); 52 | view.setMinimumHeight(height); 53 | } 54 | 55 | toast.show(); 56 | } 57 | 58 | public void show_ServerStatus(Activity activity, String msg, int duration, int backgroundColor, int textColor) { 59 | TextView toastView = new TextView(activity); 60 | toastView.setText(msg); 61 | toastView.setTextColor(textColor); 62 | toastView.setGravity(Gravity.CENTER); 63 | toastView.setBackgroundColor(backgroundColor); 64 | toastView.setPadding(25, 30, 25, 30); 65 | float radius = 20f; 66 | ShapeDrawable shapeDrawable = new ShapeDrawable(new RoundRectShape(new float[]{radius, radius, radius, radius, radius, radius, radius, radius}, null, null)); 67 | shapeDrawable.getPaint().setColor(backgroundColor); 68 | toastView.setBackground(shapeDrawable); 69 | 70 | toast = new Toast(activity); 71 | toast.setGravity(Gravity.TOP, 0, 0); 72 | if (duration == 1) { 73 | toast.setDuration(Toast.LENGTH_LONG); 74 | } else { 75 | toast.setDuration(Toast.LENGTH_SHORT); 76 | } 77 | toast.setView(toastView); 78 | 79 | View view = toast.getView(); 80 | if (view != null) { 81 | view.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED); 82 | int width = view.getMeasuredWidth(); 83 | int height = view.getMeasuredHeight(); 84 | view.setPadding(0, 0, 0, 0); 85 | view.setMinimumWidth(width); 86 | view.setMinimumHeight(height); 87 | } 88 | 89 | toast.show(); 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /app/src/main/java/Xuoos/GenshinImpact/Proxy/TrustMeAlready.java: -------------------------------------------------------------------------------- 1 | package Xuoos.GenshinImpact.Proxy; 2 | 3 | import java.lang.reflect.Method; 4 | import java.lang.reflect.ParameterizedType; 5 | import java.lang.reflect.Type; 6 | import java.security.cert.X509Certificate; 7 | import java.util.ArrayList; 8 | import java.util.Arrays; 9 | import java.util.List; 10 | import java.util.Locale; 11 | 12 | import de.robv.android.xposed.XC_MethodReplacement; 13 | import static de.robv.android.xposed.XposedHelpers.*; 14 | 15 | public class TrustMeAlready { 16 | 17 | private static final String SSL_CLASS_NAME = "com.android.org.conscrypt.TrustManagerImpl"; 18 | private static final String SSL_METHOD_NAME = "checkTrustedRecursive"; 19 | private static final Class SSL_RETURN_TYPE = List.class; 20 | private static final Class SSL_RETURN_PARAM_TYPE = X509Certificate.class; 21 | 22 | public void initZygote() { 23 | int hookedMethods = 0; 24 | 25 | for (Method method : findClass(SSL_CLASS_NAME, null).getDeclaredMethods()) { 26 | if (!checkSSLMethod(method)) { 27 | continue; 28 | } 29 | 30 | List params = new ArrayList<>(); 31 | params.addAll(Arrays.asList(method.getParameterTypes())); 32 | params.add(new XC_MethodReplacement() { 33 | @Override 34 | protected Object replaceHookedMethod(MethodHookParam param) throws Throwable { 35 | return new ArrayList(); 36 | } 37 | }); 38 | 39 | findAndHookMethod(SSL_CLASS_NAME, null, SSL_METHOD_NAME, params.toArray()); 40 | hookedMethods++; 41 | } 42 | } 43 | 44 | private boolean checkSSLMethod(Method method) { 45 | if (!method.getName().equals(SSL_METHOD_NAME)) { 46 | return false; 47 | } 48 | 49 | // check return type 50 | if (!SSL_RETURN_TYPE.isAssignableFrom(method.getReturnType())) { 51 | return false; 52 | } 53 | 54 | // check if parameterized return type 55 | Type returnType = method.getGenericReturnType(); 56 | if (!(returnType instanceof ParameterizedType)) { 57 | return false; 58 | } 59 | 60 | // check parameter type 61 | Type[] args = ((ParameterizedType) returnType).getActualTypeArguments(); 62 | if (args.length != 1 || !(args[0].equals(SSL_RETURN_PARAM_TYPE))) { 63 | return false; 64 | } 65 | 66 | return true; 67 | } 68 | } -------------------------------------------------------------------------------- /app/src/main/java/Xuoos/GenshinImpact/Proxy/Utils.kt: -------------------------------------------------------------------------------- 1 | package Xuoos.GenshinImpact.Proxy 2 | 3 | import android.content.Context 4 | 5 | object Utils { 6 | fun dp2px(context: Context, dpValue: Float): Int { 7 | val scale: Float = context.resources.displayMetrics.density 8 | return (dpValue * scale + 0.5f).toInt() 9 | } 10 | } -------------------------------------------------------------------------------- /app/src/main/res/mipmap/xuoos.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xuoos/GenshinProxy/66d5acd9cf75042386f3b6d05ac8f9301d3644e0/app/src/main/res/mipmap/xuoos.png -------------------------------------------------------------------------------- /app/src/main/res/values/arrays.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | com.miHoYo.GenshinImpact 5 | com.miHoYo.Yuanshen 6 | com.miHoYo.YuanshenPS 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Genshin Impact Proxy 4 | -------------------------------------------------------------------------------- /build.gradle.kts: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | buildscript { 3 | repositories { 4 | google() 5 | mavenCentral() 6 | maven("https://api.xposed.info") 7 | } 8 | dependencies { 9 | classpath("com.android.tools.build:gradle:7.2.1") 10 | classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.10") 11 | // NOTE: Do not place your application dependencies here; they belong 12 | // in the individual module build.gradle files 13 | } 14 | } 15 | 16 | tasks.register("Delete", Delete::class) { 17 | delete(rootProject.buildDir) 18 | } 19 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | # IDE (e.g. Android Studio) users: 3 | # Gradle settings configured through the IDE *will override* 4 | # any settings specified in this file. 5 | # For more details on how to configure your build environment visit 6 | # http://www.gradle.org/docs/current/userguide/build_environment.html 7 | # Specifies the JVM arguments used for the daemon process. 8 | # The setting is particularly useful for tweaking memory settings. 9 | org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 10 | # When configured, Gradle will run in incubating parallel mode. 11 | # This option should only be used with decoupled projects. More details, visit 12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 13 | # org.gradle.parallel=true 14 | # AndroidX package structure to make it clearer which packages are bundled with the 15 | # Android operating system, and which are packaged with your app"s APK 16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn 17 | android.useAndroidX=true 18 | # Automatically convert third-party libraries to use AndroidX 19 | android.enableJetifier=true 20 | # Kotlin code style for this project: "official" or "obsolete": 21 | kotlin.code.style=official -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xuoos/GenshinProxy/66d5acd9cf75042386f3b6d05ac8f9301d3644e0/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Sun May 15 10:11:18 CST 2022 2 | distributionBase=GRADLE_USER_HOME 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip 4 | distributionPath=wrapper/dists 5 | zipStorePath=wrapper/dists 6 | zipStoreBase=GRADLE_USER_HOME 7 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # 4 | # Copyright 2015 the original author or authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | ## 21 | ## Gradle start up script for UN*X 22 | ## 23 | ############################################################################## 24 | 25 | # Attempt to set APP_HOME 26 | # Resolve links: $0 may be a link 27 | PRG="$0" 28 | # Need this for relative symlinks. 29 | while [ -h "$PRG" ] ; do 30 | ls=`ls -ld "$PRG"` 31 | link=`expr "$ls" : '.*-> \(.*\)$'` 32 | if expr "$link" : '/.*' > /dev/null; then 33 | PRG="$link" 34 | else 35 | PRG=`dirname "$PRG"`"/$link" 36 | fi 37 | done 38 | SAVED="`pwd`" 39 | cd "`dirname \"$PRG\"`/" >/dev/null 40 | APP_HOME="`pwd -P`" 41 | cd "$SAVED" >/dev/null 42 | 43 | APP_NAME="Gradle" 44 | APP_BASE_NAME=`basename "$0"` 45 | 46 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 47 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 48 | 49 | # Use the maximum available, or set MAX_FD != -1 to use that value. 50 | MAX_FD="maximum" 51 | 52 | warn () { 53 | echo "$*" 54 | } 55 | 56 | die () { 57 | echo 58 | echo "$*" 59 | echo 60 | exit 1 61 | } 62 | 63 | # OS specific support (must be 'true' or 'false'). 64 | cygwin=false 65 | msys=false 66 | darwin=false 67 | nonstop=false 68 | case "`uname`" in 69 | CYGWIN* ) 70 | cygwin=true 71 | ;; 72 | Darwin* ) 73 | darwin=true 74 | ;; 75 | MINGW* ) 76 | msys=true 77 | ;; 78 | NONSTOP* ) 79 | nonstop=true 80 | ;; 81 | esac 82 | 83 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 84 | 85 | 86 | # Determine the Java command to use to start the JVM. 87 | if [ -n "$JAVA_HOME" ] ; then 88 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 89 | # IBM's JDK on AIX uses strange locations for the executables 90 | JAVACMD="$JAVA_HOME/jre/sh/java" 91 | else 92 | JAVACMD="$JAVA_HOME/bin/java" 93 | fi 94 | if [ ! -x "$JAVACMD" ] ; then 95 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 96 | 97 | Please set the JAVA_HOME variable in your environment to match the 98 | location of your Java installation." 99 | fi 100 | else 101 | JAVACMD="java" 102 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 103 | 104 | Please set the JAVA_HOME variable in your environment to match the 105 | location of your Java installation." 106 | fi 107 | 108 | # Increase the maximum file descriptors if we can. 109 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 110 | MAX_FD_LIMIT=`ulimit -H -n` 111 | if [ $? -eq 0 ] ; then 112 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 113 | MAX_FD="$MAX_FD_LIMIT" 114 | fi 115 | ulimit -n $MAX_FD 116 | if [ $? -ne 0 ] ; then 117 | warn "Could not set maximum file descriptor limit: $MAX_FD" 118 | fi 119 | else 120 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 121 | fi 122 | fi 123 | 124 | # For Darwin, add options to specify how the application appears in the dock 125 | if $darwin; then 126 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 127 | fi 128 | 129 | # For Cygwin or MSYS, switch paths to Windows format before running java 130 | if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then 131 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 132 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 133 | 134 | JAVACMD=`cygpath --unix "$JAVACMD"` 135 | 136 | # We build the pattern for arguments to be converted via cygpath 137 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 138 | SEP="" 139 | for dir in $ROOTDIRSRAW ; do 140 | ROOTDIRS="$ROOTDIRS$SEP$dir" 141 | SEP="|" 142 | done 143 | OURCYGPATTERN="(^($ROOTDIRS))" 144 | # Add a user-defined pattern to the cygpath arguments 145 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 146 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 147 | fi 148 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 149 | i=0 150 | for arg in "$@" ; do 151 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 152 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 153 | 154 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 155 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 156 | else 157 | eval `echo args$i`="\"$arg\"" 158 | fi 159 | i=`expr $i + 1` 160 | done 161 | case $i in 162 | 0) set -- ;; 163 | 1) set -- "$args0" ;; 164 | 2) set -- "$args0" "$args1" ;; 165 | 3) set -- "$args0" "$args1" "$args2" ;; 166 | 4) set -- "$args0" "$args1" "$args2" "$args3" ;; 167 | 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 168 | 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 169 | 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 170 | 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 171 | 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 172 | esac 173 | fi 174 | 175 | # Escape application args 176 | save () { 177 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 178 | echo " " 179 | } 180 | APP_ARGS=`save "$@"` 181 | 182 | # Collect all arguments for the java command, following the shell quoting and substitution rules 183 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 184 | 185 | exec "$JAVACMD" "$@" 186 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /settings.gradle.kts: -------------------------------------------------------------------------------- 1 | dependencyResolutionManagement { 2 | repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) 3 | repositories { 4 | google() 5 | mavenCentral() 6 | jcenter() // Warning: this repository is going to shut down soon 7 | } 8 | } 9 | 10 | pluginManagement { 11 | repositories { 12 | gradlePluginPortal() 13 | google() 14 | mavenCentral() 15 | } 16 | } 17 | 18 | rootProject.name = "HK4E Android Proxy" 19 | include(":app") 20 | --------------------------------------------------------------------------------