diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index dc576d9..83af42f 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -10,7 +10,7 @@ - + + + + +

服務條款

+
+

爲維護雙方利益,根據相關法律、法規的規定,雙方在平等、自願、公平、誠信的基礎上,加速器科技(以下簡稱“加速器”)旗下產品加速器客户端(以下簡稱“加速器”)就用户購買跨境互聯網虛擬專用網絡服務(以下簡稱“服務”)的相關事宜達成如下協議,請您務必審慎閲讀、充分理解各條款內容,特彆是免除或者限製責任的條款、法律適用和爭議解決條款,您應重點閲讀。如您對協議有任何疑問,可嚮我方平枱客服咨詢,協議如下:

+ +

a) Our goal is to provide quality service to all customers. Please read these terms of service carefully before you access the site or the service.
+

+

b) These Terms of Service (“the Terms”) govern your use of the 太子 and the associated website domains (the “Site”) and related service (the “Services”), which are owned and operated by the 太子 Team (“太子,” “our”, “we” or “us”). The Terms constitute a legally binding agreement (the “Agreement”) between you and the 太子 加速器 Team.

+

+ 太子 Service +

+

a) You understand that we are providing you with a virtual private network (or "加速器") service, which includes, but is not limited to, the use of servers, transport, routers, IP addresses and other equipment and protocols to transmit information over our network (the "System"). You agree to abide by the Terms with respect to your use of the Service.

+

+ Usage Policy +

+

a) BY USING 太子 加速器 SERVICE (the "Service") YOU AGREE:

+

a) NOT to use the system for sending spam, port scanning, scanning for open proxies or open relays, sending opt-in email, unsolicited email or any type or version of email sent in large quantities even if the email is ultimately sent off of another server.

+

b) NOT to launch any pop-ups from our service.

+

c) NOT to attack in any way shape or form any other computer or network while on our service.

+

d) NOT to use the service for things that could hurt our network or other people.

+

b) It is the user responsibility to know and comprehend any and all relevant laws related to any jurisdiction or venue that concerns you and your actions. 太子 加速器 is not liable in any way or form for actions done by its users including a criminal liability and a civil liability for harm executed or not executed beyond any money paid to 太子 加速器 for its services by a concrete individual.

+

c) Violations of this Usage Policy or the Terms may result in termination of your account, without any refund of amounts previously paid for the Service. Additionally, you may be held responsible for any and all damages incurred to 太子 加速器, including any amounts charged by any outside entity due to said violation(s), including attorney’s fees and costs without limitation.

+

d) 太子 加速器 enables you to download software, software updates or patches, or other utilities and tools onto your mobile phones or Internet-enabled device. 太子 加速器 ("the Software") grants to you a nonexclusive, limited license to use the Software solely for the purpose stated by 太子 加速器 at the time the Software is made available to you and in accordance with these Terms. Modifying, distributing to unauthorized parties, reverse engineering, or otherwise using the Software in any way not expressly authorized by 太子 加速器, is strictly prohibited.

+

+ Disclaimers +

+

a) We strive to prevent interruptions to the Site and the Service. However, these are provided on an “as is” and “as available” basis, and we do not warrant, either expressly or by implication, the accuracy of any materials or information provided through the Site or Service, or their suitability for any particular purpose.

+

b) Actual service coverage, speeds, locations and quality may vary. The Service will attempt to be available at all times except for limited periods for maintenance and repair. However the Service may be subject to unavailability for a variety of factors beyond our control including emergencies, third party service failures, transmission, equipment or network problems or limitations, interference, signal strength, and may be interrupted, refused, limited or curtailed.

+

c) We do not make any warranty that the Service will meet your requirements, or that it will be uninterrupted, timely, secure, or error free, or that defects, if any, will be corrected. You acknowledge that you access the Site and the Service at your own discretion and risk.

+

d) We are not responsible for data, messages or pages lost, not delivered, delayed or misdirected because of interruptions or performance issues with the Service or communications services or networks (e.g., T-1 lines or the Internet). We may impose usage or Service limits, suspend Service, or block certain kinds of usage in our sole discretion to protect users or the Service. Network speed is an estimate and is no indication of the speed at which your or the Service sends or receives data. Actual network speed will vary based on configuration, compression, network congestion and other factors. The accuracy and timeliness of data received is not guaranteed; delays or omissions may occur.

+

e) We do not log any user activity (sites visited, DNS lookups, emails etc.) We only log access attempts to our servers for the purposes of troubleshooting and improving the Services. We do not get involved in any form of censorship. We do not give your personal info to any third parties.

+ +

+ 第一條 服務範圍 +

+

1.1 加速器嚮申請主體(以下簡稱“用户”)提供服務,用户按照本協議約定的條款接受服務。

+ +

+ 第二條 賬户注冊及用户資料 +

+

2.1 用户下載加速器客户端後,首次使用手機號和驗證碼登録即爲注冊;

+

2.2 用户在使用加速器提供的服務時,應使用真實、準確的手機號進行注冊或登録,不得冒用他人手機號,若因冒用他人手機號而產生瞭糾紛或損失,由客户自行承擔;

+

2.3 加速器對用户資料依法保密,但爲建立與用户溝通渠道,改善服務工作,加速器可以使用本協議涉及的用户資料;

+

2.4 用户應妥善保管手機號和驗證碼,因用户原因造成的用户驗證碼遺失或被他人穫取造成的責任、損失,加速器不予承擔。

+ +

+ 第三條 業務使用 +

+

3.1 用户確認開始使用/注冊程序使用我方平枱服務前,應當具備中華人民共和國法律規定的與您行爲相適應的民事行爲能力。若用户不具備前述與用户行爲相適應的民事行爲能力,則應穫得監護人的知情同意,用户及用户的監護人應依照法律規定承擔因此而導緻的相應的責任。如果用户是未成年人,請在用户的監護人同意和指導下訪問和/或使用我方服務;

+

3.2 用户使用服務時,應遵守中華人民共和國的法律、法規、規章等相關規定;

+

3.3 加速器提供的服務僅限成功注冊并繳費的用户使用,若因用户將服務提供給第三方使用等而產生的責任及損失,由用户自行承擔;

+

3.4 官網公布的方式,爲下載、注冊、登録、使用我方服務的唯一合法途徑,您通過其他任何方式穫取的我方服務均爲非法取得,我方概不承認其效力,一經發現,我方有權立即做齣刪除、取消、暫停、封號等處理,任何因此導緻的一切不利後果均由用户自行承擔。我方保留嚮相關責任主體追究法律責任的權利。

+ +

+ 第四條 費用標準和費用交納 +

+

4.1 服務的計費周期爲:用户首次登録時係統默認贈送 24 小時免費體驗,如需續期,則按官網及客户端展示的租期費用執行,具體租期分爲 1 個月、6 個月和 1 年,支付方式可選擇微信、支付寶等;

+

4.2 如有政策調整,自調整時間起按新標準執行。

+

4.3 租期服務期限以用户自行選擇并支付相應費用的期限爲準,租期服務到期後,加速器將停止繼續嚮用户提供相關服務;

+ +

+ 第五條 服務質量與用户服務 +

+

5.1 加速器會在官網等公布相關事宜的服務項目、服務時限、服務範圍、使用規則、交費規定等內容。

+

5.2 加速器負責嚮用户提供加速器客户端的下載、安裝、注冊、登録、使用等方面的咨詢服務;

+

5.3 因加速器原因造成通信障礙,且不能修複的,加速器免收故障期間的服務費,按天計算(另有約定的除外)。加速器不賠償因故障造成的其他損失。故障時間的計算,以加速器接到用户申告或加速器查齣障礙的時間起至恢複使用爲止。

+ +

+ 第六條 協議中止和解除 +

+

6.1 本協議有效期與用户購買的服務時長一緻。

+

6.2 用户有下列情形之一的,加速器可以終止服務并不承擔責任,已收取的費用不做退迴:

+

(1)用户違反本協議約定,我方依據違約條款終止本協議的;

+

(2)用户轉借賬號、盜用他人賬號、發布違禁內容和信息、騙取他人財物、采取不正當手段謀利等行爲,我方依據我方平枱規則對您的賬號予以查封的;

+

(3)除上述情形外,因用户多次違反我方平枱規則相關規定且情節嚴重,我方依據我方平枱規則對您的賬户予以查封的;

+

(4)用户在我方平枱有侵犯他人合法權益或其他嚴重違法違約行爲的;

+

(5)其它根據相關法律法規我方應當終止服務的情況。

+ +

+ 第七條 不可抗力及免責 +

+

7.1 由於不可抗力,如戰爭、電力故障,罷工,暴亂、自然灾害等,鑒於互聯網的特殊性,不可抗力還包括黑客攻擊、運營商網絡通訊中斷及其他非因加速器過錯產生的係統故障等導緻本協議不能履行的,加速器均無需承擔違約責任。

+

7.2 如政府、司法行政機關等相關管理部門提齣要求,暫停或終止提供相應服務,加速器不承擔任何責任。

+ +

+ 第八條 爭議解決 +

+

8.1 所有因本協議引起的或與本協議有關的爭議,本着互讓互利的原則,通過協商解決。協商不成的,雙方也可請求有管轄權的人民法院對所爭議的事項做齣裁決。

+ +

+ 第九條 用户服務協議變更 +

+

9.1 加速器更新用户服務協議、隱私權政策及相關平枱規則(統稱“服務協議”),屆時協議更新會通過官網提示、短信推送或客户端公告等方式通知和提醒用户注意。 服務協議變更後,若用户繼續使用加速器服務,即錶示用户同意接受加速器更新後的服務協議。若用户不同意變更後的服務協議,請用户停止使用加速器服務。

+ +

+ 第十條 附則 +

+

10.1 本協議自訂立、生效、解釋、修訂、補充、終止、執行與爭議解決均適用中華人民共和國法律;如法律無相關規定的,參照商業慣例及/或行業慣例;

+

10.2 加速器保留因技術進步或國傢政策變動等原因對服務做齣調整的權利,但調整時應提前告知用户并提供相應解決方案;

+

10.3 加速器可以采用電話、互聯網等渠道進行業務公告或業務通知;

+

10.4 用户下載并注冊加速器客户端時即錶示已默認同意本服務協議,此服務協議自用户注冊之日起生效;

+

10.5 本協議任一條款被視爲廢止、無效或不可執行,該條應視爲可分的且并不影響本協議其餘條款的有效性及可執行性。


+ + + diff --git a/app/src/main/assets/captcha.html b/app/src/main/assets/captcha.html new file mode 100644 index 0000000..b15faa8 --- /dev/null +++ b/app/src/main/assets/captcha.html @@ -0,0 +1,109 @@ + + + + + + + + + + + + + + +
+
快速注册
+
+
+
+
+ +
滑动完成注册
+
+ + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/yingmao/clash/act/AgreementAndPrivacyActivity.kt b/app/src/main/java/com/yingmao/clash/act/AgreementAndPrivacyActivity.kt index 887118c..b8c0503 100644 --- a/app/src/main/java/com/yingmao/clash/act/AgreementAndPrivacyActivity.kt +++ b/app/src/main/java/com/yingmao/clash/act/AgreementAndPrivacyActivity.kt @@ -1,13 +1,16 @@ package com.yingmao.clash.act import android.annotation.SuppressLint +import android.content.Intent import android.content.pm.ActivityInfo +import android.net.Uri import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.text.Html import android.util.Log import android.view.View import android.webkit.WebChromeClient +import android.webkit.WebResourceRequest import android.webkit.WebSettings import android.webkit.WebView import android.webkit.WebViewClient @@ -41,30 +44,43 @@ class AgreementAndPrivacyActivity : BaseActivity() { settings.javaScriptEnabled = true settings.domStorageEnabled = true // settings.setAppCacheMaxSize((1024 * 1024 * 4).toLong()) - val appCachePath = applicationContext.cacheDir.absolutePath +// val appCachePath = applicationContext.cacheDir.absolutePath // settings.setAppCachePath(appCachePath) settings.allowFileAccess = true // settings.setAppCacheEnabled(true) + settings.cacheMode = WebSettings.LOAD_NO_CACHE if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) { settings.mixedContentMode = WebSettings.MIXED_CONTENT_ALWAYS_ALLOW } - webView.webViewClient = object : WebViewClient() { - override fun shouldOverrideUrlLoading(view: WebView, url: String): Boolean { - Logger.d("访问的url地址:$url") - return true - } - } +// webView.webViewClient = object : WebViewClient() { +// override fun shouldOverrideUrlLoading(view: WebView, url: String): Boolean { +// Logger.d("访问的url地址:$url") +// return true +// } +// } webView.webChromeClient = object : WebChromeClient() { override fun onProgressChanged(view: WebView?, newProgress: Int) { } } + // 处理所有点击跳转 + webView.webViewClient = object : WebViewClient() { + override fun shouldOverrideUrlLoading(view: WebView, request: WebResourceRequest): Boolean { + + val url = request.url.toString() + com.cncat.vpn.common.log.Log.d("shouldOverrideUrlLoading url ==>${url}") + // 可选:跳转外部浏览器 + val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url)) + view.context.startActivity(intent) + return true // 表示拦截并自处理 + } + } } fun loadAgreeHtml(){ if (BuildConfig.is_ym){ webView.loadUrl("file:android_asset/agreement.html") }else if (BuildConfig.is_tz){ - webView.loadUrl("file:android_asset/agreement_taizi_hk.html") + webView.loadUrl("https://www.taiziapp.com/agreement.html") } else{ webView.loadUrl("file:android_asset/agreement_bzy.html") @@ -75,7 +91,7 @@ class AgreementAndPrivacyActivity : BaseActivity() { if (BuildConfig.is_ym){ webView.loadUrl("file:android_asset/privacy.html") } else if (BuildConfig.is_tz){ - webView.loadUrl("file:android_asset/privacy_hk.html") + webView.loadUrl("https://www.taiziapp.com/privacy.html") } else{ webView.loadUrl("file:android_asset/privacy_bzy.html") @@ -95,7 +111,7 @@ class AgreementAndPrivacyActivity : BaseActivity() { if (language.equals("en")) { webView.loadUrl("file:android_asset/agreement_en.html") } else if (language.equals("zh") && country.equals("HK")) { - webView.loadUrl("file:android_asset/agreement_hk.html") + loadAgreeHtml() } else { loadAgreeHtml() } @@ -106,7 +122,7 @@ class AgreementAndPrivacyActivity : BaseActivity() { } "Chinese-HK" -> { - webView.loadUrl("file:android_asset/agreement_hk.html") + loadAgreeHtml() } "English" -> { @@ -125,7 +141,7 @@ class AgreementAndPrivacyActivity : BaseActivity() { if (language.equals("en")) { webView.loadUrl("file:android_asset/privacy_en.html") } else if (language.equals("zh") && country.equals("HK")) { - webView.loadUrl("file:android_asset/privacy_hk.html") + loadPriHtml() } else { loadPriHtml() } @@ -136,7 +152,7 @@ class AgreementAndPrivacyActivity : BaseActivity() { } "Chinese-HK" -> { - webView.loadUrl("file:android_asset/privacy_hk.html") + loadPriHtml() } "English" -> { diff --git a/app/src/main/java/com/yingmao/clash/act/LoginActivity.kt b/app/src/main/java/com/yingmao/clash/act/LoginActivity.kt index 4f4faa5..7d4f411 100644 --- a/app/src/main/java/com/yingmao/clash/act/LoginActivity.kt +++ b/app/src/main/java/com/yingmao/clash/act/LoginActivity.kt @@ -161,7 +161,7 @@ class LoginActivity : BaseActivity(), View.OnClickListener { ) } } - }else if(httpStatus.reqType == HttpReqType.GETAPPVERION){ + } else if (httpStatus.reqType == HttpReqType.GETAPPVERION) { (httpStatus.rsp as AppVersionCheckRsp).let { avcr -> com.cncat.vpn.common.log.Log.i("App_VERION_CHECK ==>$avcr") if (avcr.code == 200) { @@ -198,7 +198,11 @@ class LoginActivity : BaseActivity(), View.OnClickListener { var currentHost = MMKV.defaultMMKV() .decodeString(BZYConstants.MMKV_KEY_CURRENT_HOST, "") // com.cncat.vpn.common.log.Log.d("tryButton CHECK_LOGIN currentHost==>${currentHost}") - loginViewMode.login(username_encrypt, password_encrypt,user_oaid) + loginViewMode.login( + username_encrypt, + password_encrypt, + user_oaid + ) } override fun cancel() { @@ -209,7 +213,11 @@ class LoginActivity : BaseActivity(), View.OnClickListener { dialogDoMainChoose?.setOnListItemListener(object : DialogDoMainChoose.OnListItemListener { override fun listItemClick() { - loginViewMode.login(username_encrypt, password_encrypt,user_oaid) + loginViewMode.login( + username_encrypt, + password_encrypt, + user_oaid + ) } @@ -481,8 +489,8 @@ class LoginActivity : BaseActivity(), View.OnClickListener { password_encrypt = AESUtil.byteArrayToHexStr( AESUtil.encrypt(password) ) - Log.d("OALD","OAID.....::"+MainApplication.OAID) - user_oaid=AESUtil.byteArrayToHexStr( + Log.d("OALD", "OAID.....::" + MainApplication.OAID) + user_oaid = AESUtil.byteArrayToHexStr( AESUtil.encrypt(MainApplication.OAID) ) loginUserName = username @@ -490,24 +498,35 @@ class LoginActivity : BaseActivity(), View.OnClickListener { RxToast.warning(resources.getString(R.string.ReadAgreement)) return } - loginViewMode.login(username_encrypt, password_encrypt,user_oaid) + loginViewMode.login(username_encrypt, password_encrypt, user_oaid) } R.id.tv_register -> { -// val intent = Intent(applicationContext, RegisterActivity::class.java) -// startActivityForResult(intent, LOGIN_TO_REGISTER_REQUEST_CODE) - if (TextUtils.isEmpty(registerHost)) { - if (BuildConfig.is_tz) { - getTzRegister() - } else { - if (BuildConfig.is_ym) { - getYmRegister() - } else { - getBzyRegister() - } - } + if (!BuildConfig.is_free && BuildConfig.productId.isNotEmpty()) { + val intent = Intent(applicationContext, SplashActivity::class.java) + startActivity(intent) } else { - startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(registerHost))) + if (TextUtils.isEmpty(registerHost)) { + when { + BuildConfig.is_ym -> { + getYmRegister() + } + + BuildConfig.is_tz -> { + getTzRegister() + } + + BuildConfig.is_yunti -> { + getYunTiRegister() + } + + else -> { + getBzyRegister() + } + } + } else { + startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(registerHost))) + } } } @@ -515,12 +534,20 @@ class LoginActivity : BaseActivity(), View.OnClickListener { var mmkvHost = MMKV.defaultMMKV() .decodeString(BZYConstants.MMKV_KEY_KEFU_HOST, "") if (TextUtils.isEmpty(kefuHost)) { - if (BuildConfig.is_tz) { - getTzKefu(mmkvHost) - } else { - if (BuildConfig.is_ym) { + when { + BuildConfig.is_ym -> { getYmKefu(mmkvHost) - } else { + } + + BuildConfig.is_tz -> { + getTzKefu(mmkvHost) + } + + BuildConfig.is_yunti -> { + getYunTiKefu(mmkvHost) + } + + else -> { getBzyKefu(mmkvHost) } } @@ -631,6 +658,37 @@ class LoginActivity : BaseActivity(), View.OnClickListener { }) } + private fun getYunTiRegister() { + var mmkvHost = MMKV.defaultMMKV() + .decodeString(BZYConstants.MMKV_KEY_REGISTER_HOST, "") +// com.cncat.vpn.common.log.Log.d("mmkvHost==>${mmkvHost}") + loginViewMode.getYunTiRegisterHost(object : AsyncBodyCallback { + override suspend fun suc(str: String) { +// com.cncat.vpn.common.log.Log.d("str==>${str}") + if (str != mmkvHost) { + MMKV.defaultMMKV() + .encode(BZYConstants.MMKV_KEY_REGISTER_HOST, str) + } +// mmkvHost = str + registerHost = str + startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(str))) + } + + override fun err() { + if (!TextUtils.isEmpty(mmkvHost)) { + startActivity( + Intent( + Intent.ACTION_VIEW, + Uri.parse(mmkvHost) + ) + ) + } + + } + + }) + } + private fun getYmKefu(mmkvHost: String?) { loginViewMode.getYmKefuHost(object : AsyncBodyCallback { @@ -656,6 +714,30 @@ class LoginActivity : BaseActivity(), View.OnClickListener { }) } + private fun getYunTiKefu(mmkvHost: String?) { + loginViewMode.getYunTiKefuHost(object : AsyncBodyCallback { + override suspend fun suc(str: String) { + if (str != mmkvHost) { + MMKV.defaultMMKV() + .encode(BZYConstants.MMKV_KEY_KEFU_HOST, str) + } + kefuHost = str + startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(str))) + } + + override fun err() { + if (!TextUtils.isEmpty(mmkvHost)) { + startActivity( + Intent( + Intent.ACTION_VIEW, + Uri.parse(mmkvHost) + ) + ) + } + } + }) + } + private fun getBzyKefu(mmkvHost: String?) { loginViewMode.getBzyKefuHost(object : AsyncBodyCallback { override suspend fun suc(str: String) { @@ -733,6 +815,7 @@ class LoginActivity : BaseActivity(), View.OnClickListener { } } + private fun showUpdateDialog(url: String, illustrate: String, isForce: Boolean) { if (TextUtils.isEmpty(url)) { RxToast.error(resources.getString(R.string.downloadEmpty)) @@ -789,6 +872,7 @@ class LoginActivity : BaseActivity(), View.OnClickListener { }) dialog.show() } + fun installApk(filePath: String) { val file = File(filePath) val uri: Uri = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { diff --git a/app/src/main/java/com/yingmao/clash/act/MyClickableSpan.java b/app/src/main/java/com/yingmao/clash/act/MyClickableSpan.java index 9a6b2c3..d3240f6 100644 --- a/app/src/main/java/com/yingmao/clash/act/MyClickableSpan.java +++ b/app/src/main/java/com/yingmao/clash/act/MyClickableSpan.java @@ -51,7 +51,7 @@ public abstract class MyClickableSpan extends ClickableSpan { */ @Override public void updateDrawState(@NonNull TextPaint ds) { - ds.setColor(Color.parseColor("#B0BFFA")); + ds.setColor(Color.parseColor("#f11f04")); ds.setUnderlineText(false); } diff --git a/app/src/main/java/com/yingmao/clash/act/NewMainActivity.kt b/app/src/main/java/com/yingmao/clash/act/NewMainActivity.kt index bbfb4ee..f435c0b 100644 --- a/app/src/main/java/com/yingmao/clash/act/NewMainActivity.kt +++ b/app/src/main/java/com/yingmao/clash/act/NewMainActivity.kt @@ -509,13 +509,13 @@ class NewMainActivity : BaseActivity() { //todo 判断订阅地址是否修改过,未修改就用接口返回的地址反之使用本地修改的地址 var pro_sub_url = MMKV.defaultMMKV().decodeString(BZYConstants.PROFILE_SUB_URL, "") - if (!TextUtils.isEmpty(pro_sub_url)){ + if (!TextUtils.isEmpty(pro_sub_url)) { if (pro_sub_url == url) { subUrl = url } else { subUrl = pro_sub_url } - }else{ + } else { subUrl = url } diff --git a/app/src/main/java/com/yingmao/clash/act/RegisterActivity.kt b/app/src/main/java/com/yingmao/clash/act/RegisterActivity.kt index a0625aa..8331647 100644 --- a/app/src/main/java/com/yingmao/clash/act/RegisterActivity.kt +++ b/app/src/main/java/com/yingmao/clash/act/RegisterActivity.kt @@ -23,7 +23,6 @@ import com.yingmao.clash.net.http.HttpStatus import com.yingmao.clash.net.http.entity.RegisterRsp import com.yingmao.clash.util.AESUtil import com.yingmao.clash.util.CommonUtils -import com.yingmao.clash.util.Utils import com.yingmao.clash.view.PasswordTransformationMethodBigDot import com.yingmao.clash.view.RxToast import com.yingmao.clash.view.SlidingVerification @@ -146,7 +145,7 @@ class RegisterActivity : BaseActivity(), View.OnClickListener { req_json.addProperty("password", password) req_json.addProperty("checkPassword", password) req_json.addProperty("invitationCode", BuildConfig.productId) - req_json.addProperty("clientIp", Utils.getIPAddress()) + req_json.addProperty("clientIp", "127.0.0.1") req_json.addProperty("from", "5") var data = AESUtil.byteArrayToHexStr( AESUtil.encrypt(req_json.toString()) @@ -187,14 +186,14 @@ class RegisterActivity : BaseActivity(), View.OnClickListener { Log.d("it.progress==>${it.progress}") if (it.progress >= it.max) { it.isEnabled = false - verificationSv.progress=it.max + verificationSv.progress = it.max verificationTipTv.text = getString(R.string.verification_success) verificationTipTv.setTextColor(R.color.black) verificationSv.setProgressDrawableTiled(getDrawable(R.drawable.login_btn_bg_selector)) if (!checkInput()) { - }else { + } else { } } else it.progress = 0 diff --git a/app/src/main/java/com/yingmao/clash/act/SplashActivity.kt b/app/src/main/java/com/yingmao/clash/act/SplashActivity.kt index 8844c61..4f9a3ac 100644 --- a/app/src/main/java/com/yingmao/clash/act/SplashActivity.kt +++ b/app/src/main/java/com/yingmao/clash/act/SplashActivity.kt @@ -2,6 +2,7 @@ package com.yingmao.clash.act import android.Manifest import android.annotation.SuppressLint +import android.content.Context import android.content.Intent import android.content.pm.PackageManager import android.graphics.Bitmap @@ -10,10 +11,18 @@ import android.net.Uri import android.os.Build import android.os.Bundle import android.provider.Settings +import android.text.SpannableString +import android.text.TextPaint import android.text.TextUtils +import android.text.style.ClickableSpan import android.util.Log import android.view.View import android.view.WindowManager +import android.webkit.JavascriptInterface +import android.webkit.WebSettings +import android.webkit.WebView +import android.webkit.WebViewClient +import android.widget.Button import android.widget.ProgressBar import android.widget.RelativeLayout import android.widget.TextView @@ -46,6 +55,7 @@ import com.yingmao.clash.conf.BZYConstants.Companion.MMKV_KEY_NOTE_DEFAULT_PSW import com.yingmao.clash.conf.BZYConstants.Companion.MMKV_KEY_REMEMBER_PASSWORD import com.yingmao.clash.conf.BZYConstants.Companion.MMKV_KEY_REMEMBER_USERNAME import com.yingmao.clash.entity.CheckLoginRsp +import com.yingmao.clash.listener.AsyncBodyCallback import com.yingmao.clash.listener.DownLoadListener import com.yingmao.clash.net.http.HttpReqType import com.yingmao.clash.net.http.HttpStatus @@ -56,12 +66,17 @@ import com.yingmao.clash.net.http.entity.StartingBeans import com.yingmao.clash.util.AESUtil import com.yingmao.clash.util.Utils import com.yingmao.clash.view.RxToast +import com.yingmao.clash.view.dialog.DialogAgreementPrivacyChoose import com.yingmao.clash.view.dialog.DialogAppVersion import com.yingmao.clash.view.dialog.DialogDoMainChoose import com.yingmao.clash.view.dialog.RxDialogSureCancel import com.yingmao.clash.vm.SplashAtyVM +import kotlinx.coroutines.DelicateCoroutinesApi +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.MainScope import kotlinx.coroutines.async +import kotlinx.coroutines.delay import kotlinx.coroutines.launch import java.io.File import java.util.Locale @@ -73,29 +88,36 @@ class SplashActivity : BaseActivity() { private val mPermissions = hashSetOf() private val PERMISSION_REQUEST_CODE: Int = 1 private val PERMISSION_SETTING_REQUEST_CODE = 2 + private val Captcha_REQUEST_CODE = 3333 private lateinit var rlPb: View private lateinit var ll_action: View - private lateinit var username: String - private lateinit var rlMain: RelativeLayout + private var but_skip: Button? = null + private var but_register: Button? = null + + private lateinit var rlMain: RelativeLayout private lateinit var splashAtyVM: SplashAtyVM - private var registerKey = "" - private var registerIV2 = "" + private var registerHost = "" + + companion object { + public var registerKey = "" + public var registerIV2 = "" + public lateinit var username: String + } + + private var captchaInfo = "" private var initErrMsg = "" override fun onCreate(savedInstanceState: Bundle?) { window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION) super.onCreate(savedInstanceState) - - setLocalLanguage() initErrMsg = resources.getString(R.string.splashErrorTips) - username = Utils.getUniqueID(this) // var username2 = Utils.getUniqueID2(this); // com.cncat.vpn.common.log.Log.d("username==>" + username + ", username2==>" + username2) splashAtyVM = ViewModelProvider(this).get(SplashAtyVM::class.java) observe(this, splashAtyVM) setContentView(R.layout.layout_splash_activity) - rlMain=findViewById(R.id.rlMain) + rlMain = findViewById(R.id.rlMain) rlPb = findViewById(R.id.rl_pb) ll_action = findViewById(R.id.ll_action) @@ -107,6 +129,14 @@ class SplashActivity : BaseActivity() { serStore.isBZY = true } } + initWebView() + if (BuildConfig.productId == "182268") { + + initAgreementPrivacy() + } else { + //隐私政策先授权后获取权限 + initApplication(false) + } // mPermissions.add(Manifest.permission.READ_PHONE_STATE) @@ -153,6 +183,43 @@ class SplashActivity : BaseActivity() { // com.cncat.vpn.common.log.Log.d("onOAIDGetComplete result==>${ DeviceIdentifier.getOAID(this)}") //获取配置背景 + + +// val Sgtr= AESUtil.decrypt("6A9E6037E4E31FDFE8E09A79FAD64B5CE7AA2D6C0DF34000998651C877C8005AD68274B63FCB1FC35DAFAD278B3EF19B79E83738A3AD5DB70D9601E43050BE0E") +// println("Sgtr==>$Sgtr") + +// val Sgtr= AESUtil.Registerdecrypt("" +// , registerKey, registerIV2) +//com.cncat.vpn.common.log.Log.d("Sgtr==>$Sgtr") +// OpenInstall.getWakeUp(intent, wakeUpAdapter) +// OpenInstall.getInstall { appData, error -> +// var appData = appData +// if (error != null && error.shouldRetry()) { +// // 获取数据异常,可以尝试重新获取 +// } else { +// if (appData == null) appData = AppData() +// val channelCode = appData.getChannel() // 获取渠道编号参数 +// val bindData = appData.getData() // 获取自定义参数 +// Log.d("OpenInstall", "getInstall : channelCode = $channelCode"+"bindData::"+bindData) +// } +// } + } +// private var wakeUpAdapter: AppWakeUpAdapter = object : AppWakeUpAdapter() { +// override fun onWakeUp(appData: AppData) { +// // 打印数据便于调试 +// Log.d("OpenInstall", "getWakeUp : wakeupData = $appData") +// // 获取渠道编号参数 +// val channelCode = appData.getChannel() +// // 获取自定义参数 +// val bindData = appData.getData() +// Log.d("OpenInstall", "channelCode : bindData = $channelCode"+"bindData::"+bindData) +// } +// } + + private fun initApplication(isNeedRegister: Boolean) { + username = Utils.getUniqueID(this) + MainApplication.initUtil() + setLocalLanguage() splashAtyVM.getSplashBg() var clashBinder = MainApplication.getApp()?.let { ClashManager(it).wrap() as IClashManager @@ -179,90 +246,32 @@ class SplashActivity : BaseActivity() { // "ym encrypt:" + // AESUtil.byteArrayToHexStr( // AESUtil.encrypt( -// "https://api.yingmaohot.org+https://api.yingmao888.net+" + -// "https://api.ymsohot.com+https://ma.wztgyh.com+https://ymapi.yingmaox.cc" +// "" // ) // ) // ) val routerSet = MMKV.defaultMMKV().decodeStringSet(BZYConstants.MMKV_KEY_ROUTER_HOST) if (routerSet != null && routerSet.size > 0) { - isNeedRegister() + isNeedRegister(isNeedRegister) } else { - rlPb.visibility = View.VISIBLE if (BuildConfig.is_back_cn == true) { //没有备用域名所以无需调用getHost - isNeedRegister() + isNeedRegister(isNeedRegister) } else { SplashHelper(splashAtyVM).getHostWithFallback { success -> MainScope().launch { if (success) { - isNeedRegister() + isNeedRegister(isNeedRegister) } else { - isNeedRegister() + isNeedRegister(isNeedRegister) } } } -// splashAtyVM.getHostByGithub(object : AsyncCallback { -// override suspend fun suc() { -// Log.e("data", "getHostByGithub suc") -// MainScope().launch { -// isNeedRegister() -// } -// } -// -// override fun err() { -// Log.e("data", "getHostByGithub err") -// splashAtyVM.getHostByAWS(object : AsyncCallback { -// override suspend fun suc() { -// Log.e("data", "getHostByAWS suc") -// MainScope().launch { -// isNeedRegister() -// } -// } -// -// override fun err() { -// Log.e("data", "getHostByAWS err") -// splashAtyVM.getHost(object : AsyncCallback { -// override suspend fun suc() { -// Log.e("data", "getHost suc") -// MainScope().launch { -// isNeedRegister() -// } -// } -// -// override fun err() { -// Log.e("data", "getHost err") -// //全部失败后也调用 -// MainScope().launch { -// isNeedRegister() -// } -// } -// }) -// } -// }) -// } -// }) + } } } } -// val Sgtr= AESUtil.Registerdecrypt("CCBF308D702235C8F810876987A43AB02B84EBB47DBFF1B915D5FBB29FF2DBAE90DB72D58351D09D223D49E44A2A073D9156E84D6B7EB89D7493A3F0A7240EE076ADC83B5A12AC37616CEDED00643AD1E6851AFECA82E373CB4E518DF2190708F5191AE195758E8EA41A5242A6C94216B64FF8715B35C54CB894113FC93361F32FDA86CF34093DF924230DEBE27A69293C761A9A797A652A1C35C95C27FB5EB4" -// ,registerKey,registerIV2) -// println("Sgtr==>$Sgtr") - - -// OpenInstall.getWakeUp(intent, wakeUpAdapter) -// OpenInstall.getInstall { appData, error -> -// var appData = appData -// if (error != null && error.shouldRetry()) { -// // 获取数据异常,可以尝试重新获取 -// } else { -// if (appData == null) appData = AppData() -// val channelCode = appData.getChannel() // 获取渠道编号参数 -// val bindData = appData.getData() // 获取自定义参数 -// Log.d("OpenInstall", "getInstall : channelCode = $channelCode"+"bindData::"+bindData) -// } -// } } // private var wakeUpAdapter: AppWakeUpAdapter = object : AppWakeUpAdapter() { // override fun onWakeUp(appData: AppData) { @@ -281,9 +290,146 @@ class SplashActivity : BaseActivity() { // 此处要调用,否则App在后台运行时,会无法获取 // OpenInstall.getWakeUp(intent, wakeUpAdapter) } + + private lateinit var webView: WebView + private lateinit var pb_web: ProgressBar + var dialogAgreementPrivacyChoose: DialogAgreementPrivacyChoose? = null + private fun initAgreementPrivacy() { + if (BuildConfig.is_tz && BuildConfig.productId == "182268") { + if (MMKV.defaultMMKV().decodeBool(BZYConstants.MMKV_KEY_IS_REGISTER, false)) { + rlPb.visibility = View.VISIBLE + webView.visibility = View.GONE + initApplication(false) + } else { + setWebView() + if (dialogAgreementPrivacyChoose == null) { + dialogAgreementPrivacyChoose = DialogAgreementPrivacyChoose(this@SplashActivity) + } + if (dialogAgreementPrivacyChoose?.isShowing == false) { + dialogAgreementPrivacyChoose?.setOnTryButtonListener(object : + DialogAgreementPrivacyChoose.OnTryButtonListener { + override fun agree() { + initApplication(false) + dialogAgreementPrivacyChoose?.dismiss() + } + + override fun cancel() { + dialogAgreementPrivacyChoose?.dismiss() + finish() + } + }) + dialogAgreementPrivacyChoose?.show() + } + + } + + } + } + + private fun initWebView() { + if (!BuildConfig.is_free && BuildConfig.productId.isNotEmpty()) { + webView = findViewById(R.id.webView) + pb_web = findViewById(R.id.pb_web) + but_skip = findViewById(R.id.but_skip) + but_register = findViewById(R.id.but_register) + but_skip?.setOnClickListener { + val intent = Intent(this@SplashActivity, LoginActivity::class.java) + startActivity(intent) + finish() + } + but_register?.setOnClickListener { + if (TextUtils.isEmpty(registerHost)) { + when { + BuildConfig.is_ym -> { + getYmRegister() + } + + BuildConfig.is_tz -> { + getTzRegister() + } + + BuildConfig.is_yunti -> { + getYunTiRegister() + } + + else -> { + getBzyRegister() + } + } + } else { + startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(registerHost))) + } + } + } + + } + + + @SuppressLint("JavascriptInterface") + private fun setWebView() { + rlPb.visibility = View.INVISIBLE + webView.visibility = View.VISIBLE + lifecycleScope.launch(Dispatchers.Main) { + delay(3000) // 延迟3秒 + com.cncat.vpn.common.log.Log.d("setWebView delay") + but_skip?.visibility = View.VISIBLE + but_register?.visibility = View.VISIBLE + } + // WebView设置 + val webSettings = webView.settings + // 可选,设置开启Chrome调试 + WebView.setWebContentsDebuggingEnabled(true) + // 设置屏幕自适应 + webSettings.useWideViewPort = true + webSettings.loadWithOverviewMode = true + // 建议禁止缓存加载,以确保在攻击发生时可快速获取最新的阿里云验证码2.0进行对抗 + webSettings.cacheMode = WebSettings.LOAD_NO_CACHE + // 设置WebView组件支持加载JavaScript + webSettings.javaScriptEnabled = true + webSettings.domStorageEnabled = true + + + // 设置不使用默认浏览器,而直接使用WebView组件加载页面 + webView.webViewClient = object : WebViewClient() { + override fun shouldOverrideUrlLoading(view: WebView, url: String): Boolean { + view.loadUrl(url) + return true + } + } + webView.addJavascriptInterface(CaptchaJsInterface(), "CaptchaJsInterface") +// testWebview.addJavascriptInterface(new testJsInterface(), "testInterface"); + // 加载业务页面 + webView.loadUrl("file:///android_asset/captcha.html") +// webView.loadUrl("https://api.yingmaovpnpro.win:18002/78zccgy0nsgknh9n4/captcha.html") + } + + inner class CaptchaJsInterface() { + + @JavascriptInterface + public fun getVerifyResult(verifyResult: String): Boolean { + com.cncat.vpn.common.log.Log.d("verifyResult==>${verifyResult}") + captchaInfo = verifyResult + + launch { + webView.setOnTouchListener { _, _ -> true } + pb_web.visibility = View.VISIBLE + } + doRegisterByEncryption() + return true + } + } + + private class CaptchaJsSuccessInterface { + @JavascriptInterface + public fun result(verifyResult: String) { +// Log.d("verifyResult==>${verifyResult}") + + } + } + private fun setLocalLanguage() { var defLan = "" - if (BuildConfig.is_tz) { + if (BuildConfig.is_tz && BuildConfig.productId != "182268") { defLan = "Chinese-HK" } val decodeString = MMKV.defaultMMKV().decodeString(BZYConstants.languageInfo, defLan) @@ -379,20 +525,32 @@ class SplashActivity : BaseActivity() { } } - private fun isNeedRegister() { + private fun isNeedRegister(isNeedRegister: Boolean) { if (!BuildConfig.is_free && BuildConfig.productId.isNotEmpty()) { //渠道包都自动注册登录,广州22222也是非自动注册 - rlPb.visibility = View.VISIBLE + if (MMKV.defaultMMKV().decodeBool(BZYConstants.MMKV_KEY_IS_REGISTER, false)) { + rlPb.visibility = View.VISIBLE + but_skip?.visibility = View.INVISIBLE + but_register?.visibility = View.INVISIBLE splashAtyVM.checkLogin() } else { // doRegister() - doRegisterByEncryption() + + if (isNeedRegister) { + doRegisterByEncryption() + } else { + setWebView() + } + } } else {//非渠道自由包 val token = MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_TOKEN) ll_action.visibility = View.VISIBLE rlPb.visibility = View.INVISIBLE + but_skip?.visibility = View.INVISIBLE + but_register?.visibility = View.INVISIBLE if (MMKV.defaultMMKV().decodeBool(BZYConstants.MMKV_KEY_IS_REGISTER, false)) { + if (token != null && token.isNotEmpty()) { ll_action.visibility = View.GONE rlPb.visibility = View.VISIBLE @@ -424,7 +582,7 @@ class SplashActivity : BaseActivity() { "password" to BZYConstants.defaultPassword, "checkPassword" to BZYConstants.defaultPassword, "id" to BuildConfig.productId, - "clientIp" to Utils.getIPAddress(), + "clientIp" to "127.0.0.1", "from" to "5", ) splashAtyVM.register(params) @@ -432,14 +590,16 @@ class SplashActivity : BaseActivity() { @Synchronized fun doRegisterByEncryption() { - var req_json = JsonObject() req_json.addProperty("password", BZYConstants.defaultPassword) req_json.addProperty("checkPassword", BZYConstants.defaultPassword) req_json.addProperty("invitationCode", BuildConfig.productId) - req_json.addProperty("clientIp", Utils.getIPAddress()) + req_json.addProperty("clientIp", "127.0.0.1") req_json.addProperty("from", "5") req_json.addProperty("androidDevice", username) + if (captchaInfo.isNotEmpty()) { + req_json.addProperty("captchaVerifyParam", captchaInfo) + } if (registerKey.isNotEmpty() && registerIV2.isNotEmpty()) { val data = AESUtil.byteArrayToHexStr( AESUtil.RegisterEncrypt(req_json.toString(), registerKey, registerIV2) @@ -543,6 +703,7 @@ class SplashActivity : BaseActivity() { // // } + @SuppressLint("ClickableViewAccessibility") override fun httpSuccess(httpStatus: HttpStatus.Success) { when (httpStatus.reqType) { HttpReqType.REGISTER -> { @@ -602,6 +763,12 @@ class SplashActivity : BaseActivity() { startActivity(intent) finish() // graphicVerificationDialog() + } else if (code == "403") { + pb_web.visibility = View.INVISIBLE + message?.let { + RxToast.error(it) + } + webView.setOnTouchListener { _, _ -> false } } else { MaterialDialog(this@SplashActivity).show { message(text = initErrMsg) @@ -676,19 +843,23 @@ class SplashActivity : BaseActivity() { } } } - HttpReqType.SplashBg->{ + + HttpReqType.SplashBg -> { val startingBeans = httpStatus.rsp as StartingBeans startingBeans.data - if(startingBeans.data!=null){ - if(startingBeans.data!!.exist){ - Log.d("SplashActivityStarting","startingBeans.data!!.img::"+ startingBeans.data!!.img) + if (startingBeans.data != null) { + if (startingBeans.data!!.exist) { + Log.d( + "SplashActivityStarting", + "startingBeans.data!!.img::" + startingBeans.data!!.img + ) startingBeans.data!!.img.let { Glide.with(this).asBitmap() .load(startingBeans.data!!.img) - .into(object :SimpleTarget(){ + .into(object : SimpleTarget() { override fun onResourceReady( resource: Bitmap, - transition: Transition? + transition: Transition?, ) { val bitmapDrawable = BitmapDrawable(resource) rlMain.setBackgroundDrawable(bitmapDrawable) @@ -701,7 +872,8 @@ class SplashActivity : BaseActivity() { } } - HttpReqType.App_VERION_CHECK->{ + + HttpReqType.App_VERION_CHECK -> { (httpStatus.rsp as AppVersionCheckRsp).let { avcr -> com.cncat.vpn.common.log.Log.i("App_VERION_CHECK ==>$avcr") if (avcr.code == 200) { @@ -714,14 +886,14 @@ class SplashActivity : BaseActivity() { if (!TextUtils.isEmpty(md.versionPath)) { showUpdateDialog(md.versionPath!!, md.illustrate!!, false) } - }else{ - val intent = Intent(this@SplashActivity, NewMainActivity::class.java) + } else { + val intent = Intent(this@SplashActivity, UIMainActivity::class.java) startActivity(intent) finish() } } - }else{ - val intent = Intent(this@SplashActivity, NewMainActivity::class.java) + } else { + val intent = Intent(this@SplashActivity, UIMainActivity::class.java) startActivity(intent) finish() } @@ -737,14 +909,14 @@ class SplashActivity : BaseActivity() { when (httpStatus.reqType) { HttpReqType.REGISTER -> { rlPb.visibility = View.GONE - + pb_web.visibility = View.INVISIBLE com.cncat.vpn.common.log.Log.d("httpFailure HttpReqType.REGISTER") try { RxToast.error("检测到网络异常,请尝试切换其他地址.") - if (dialogDoMainChoose==null) { + if (dialogDoMainChoose == null) { dialogDoMainChoose = DialogDoMainChoose(this@SplashActivity) } - if (dialogDoMainChoose?.isShowing==false){ + if (dialogDoMainChoose?.isShowing == false) { dialogDoMainChoose?.setOnTryButtonListener(object : DialogDoMainChoose.OnTryButtonListener { override fun tryButton() { @@ -757,7 +929,7 @@ class SplashActivity : BaseActivity() { override fun cancel() { com.cncat.vpn.common.log.Log.d("tryButton REGISTER cancel") dialogDoMainChoose?.dismiss() - dialogDoMainChoose=null + dialogDoMainChoose = null } }) dialogDoMainChoose?.setOnListItemListener(object : @@ -817,15 +989,18 @@ class SplashActivity : BaseActivity() { SplashHelper(splashAtyVM).getHostWithFallback { success -> MainScope().launch { if (success) { - if (dialogDoMainChoose==null) { + if (dialogDoMainChoose == null) { dialogDoMainChoose = DialogDoMainChoose(this@SplashActivity) } - if (dialogDoMainChoose?.isShowing==false){ + if (dialogDoMainChoose?.isShowing == false) { dialogDoMainChoose?.setOnTryButtonListener(object : DialogDoMainChoose.OnTryButtonListener { override fun tryButton() { var currentHost = MMKV.defaultMMKV() - .decodeString(BZYConstants.MMKV_KEY_CURRENT_HOST, "") + .decodeString( + BZYConstants.MMKV_KEY_CURRENT_HOST, + "" + ) // com.cncat.vpn.common.log.Log.d("tryButton CHECK_LOGIN currentHost==>${currentHost}") splashAtyVM.checkLogin() } @@ -914,7 +1089,7 @@ class SplashActivity : BaseActivity() { } if (deniedAndNoLongerPromptPermissions.isNotEmpty()) { if (checkPermissions(mPermissions)) { - isNeedRegister() //TODO + isNeedRegister(true) //TODO return } val deniedAndNoLongerPromptPermissionsName = StringBuilder() @@ -964,7 +1139,7 @@ class SplashActivity : BaseActivity() { Logger.i("${deniedAndNoLongerPromptPermissions.size}需要${deniedAndNoLongerPromptPermissionsName.toString()}权限,由于您设置了不再提示,需要手动开启权限!") } else { if (checkPermissions(mPermissions)) { - isNeedRegister() //TODO + isNeedRegister(true) //TODO } else { finish() } @@ -974,13 +1149,23 @@ class SplashActivity : BaseActivity() { @RequiresApi(Build.VERSION_CODES.M) override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) + com.cncat.vpn.common.log.Log.d("onActivityResult requestCode==>${requestCode}") if (requestCode == PERMISSION_SETTING_REQUEST_CODE) { if (checkPermissions(mPermissions)) { - isNeedRegister() //TODO + isNeedRegister(true) //TODO } else { requestPermissions(deniedPermissions.toTypedArray(), PERMISSION_REQUEST_CODE) } + } else if (requestCode == Captcha_REQUEST_CODE) { + + + captchaInfo = + data?.extras?.getString(BZYConstants.REQUEST_CODE_Captcha_Result_Key).toString() + com.cncat.vpn.common.log.Log.d("onActivityResult captchaInfo==>${captchaInfo}") + doRegisterByEncryption() + } + } private fun toMainPage() { @@ -1002,6 +1187,7 @@ class SplashActivity : BaseActivity() { config.locale = locale resources.updateConfiguration(config, metrics) } + private fun showUpdateDialog(url: String, illustrate: String, isForce: Boolean) { if (TextUtils.isEmpty(url)) { RxToast.error(resources.getString(R.string.downloadEmpty)) @@ -1061,6 +1247,7 @@ class SplashActivity : BaseActivity() { }) dialog.show() } + fun installApk(filePath: String) { val file = File(filePath) val uri: Uri = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { @@ -1079,4 +1266,127 @@ class SplashActivity : BaseActivity() { } startActivity(intent) } + + private fun getYmRegister() { + var mmkvHost = MMKV.defaultMMKV() + .decodeString(BZYConstants.MMKV_KEY_REGISTER_HOST, "") +// com.cncat.vpn.common.log.Log.d("mmkvHost==>${mmkvHost}") + splashAtyVM.getRegisterHost(object : AsyncBodyCallback { + override suspend fun suc(str: String) { +// com.cncat.vpn.common.log.Log.d("str==>${str}") + if (str != mmkvHost) { + MMKV.defaultMMKV() + .encode(BZYConstants.MMKV_KEY_REGISTER_HOST, str) + } +// mmkvHost = str + registerHost = str + startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(str))) + } + + override fun err() { + if (!TextUtils.isEmpty(mmkvHost)) { + startActivity( + Intent( + Intent.ACTION_VIEW, + Uri.parse(mmkvHost) + ) + ) + } + + } + + }) + } + + private fun getTzRegister() { + var mmkvHost = MMKV.defaultMMKV() + .decodeString(BZYConstants.MMKV_KEY_REGISTER_HOST, "") +// com.cncat.vpn.common.log.Log.d("mmkvHost==>${mmkvHost}") + splashAtyVM.getTzRegisterHost(object : AsyncBodyCallback { + override suspend fun suc(str: String) { +// com.cncat.vpn.common.log.Log.d("str==>${str}") + if (str != mmkvHost) { + MMKV.defaultMMKV() + .encode(BZYConstants.MMKV_KEY_REGISTER_HOST, str) + } +// mmkvHost = str + registerHost = str + startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(str))) + } + + override fun err() { + if (!TextUtils.isEmpty(mmkvHost)) { + startActivity( + Intent( + Intent.ACTION_VIEW, + Uri.parse(mmkvHost) + ) + ) + } + + } + + }) + } + + private fun getBzyRegister() { + var mmkvHost = MMKV.defaultMMKV() + .decodeString(BZYConstants.MMKV_KEY_REGISTER_HOST, "") +// com.cncat.vpn.common.log.Log.d("mmkvHost==>${mmkvHost}") + splashAtyVM.getBzyRegisterHost(object : AsyncBodyCallback { + override suspend fun suc(str: String) { +// com.cncat.vpn.common.log.Log.d("str==>${str}") + if (str != mmkvHost) { + MMKV.defaultMMKV() + .encode(BZYConstants.MMKV_KEY_REGISTER_HOST, str) + } +// mmkvHost = str + registerHost = str + startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(str))) + } + + override fun err() { + if (!TextUtils.isEmpty(mmkvHost)) { + startActivity( + Intent( + Intent.ACTION_VIEW, + Uri.parse(mmkvHost) + ) + ) + } + + } + + }) + } + + private fun getYunTiRegister() { + var mmkvHost = MMKV.defaultMMKV() + .decodeString(BZYConstants.MMKV_KEY_REGISTER_HOST, "") +// com.cncat.vpn.common.log.Log.d("mmkvHost==>${mmkvHost}") + splashAtyVM.getYunTiRegisterHost(object : AsyncBodyCallback { + override suspend fun suc(str: String) { +// com.cncat.vpn.common.log.Log.d("str==>${str}") + if (str != mmkvHost) { + MMKV.defaultMMKV() + .encode(BZYConstants.MMKV_KEY_REGISTER_HOST, str) + } + registerHost = str + startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(str))) + } + + override fun err() { + if (!TextUtils.isEmpty(mmkvHost)) { + startActivity( + Intent( + Intent.ACTION_VIEW, + Uri.parse(mmkvHost) + ) + ) + } + + } + + }) + } } \ No newline at end of file diff --git a/app/src/main/java/com/yingmao/clash/app/MainApplication.kt b/app/src/main/java/com/yingmao/clash/app/MainApplication.kt index 05b2c25..0147963 100644 --- a/app/src/main/java/com/yingmao/clash/app/MainApplication.kt +++ b/app/src/main/java/com/yingmao/clash/app/MainApplication.kt @@ -15,10 +15,10 @@ import androidx.core.content.getSystemService import com.cncat.vpn.common.Global import com.cncat.vpn.common.compat.currentProcessName import com.cncat.vpn.common.log.Log -import com.fm.openinstall.OpenInstall import com.github.gzuliyujiang.oaid.DeviceID import com.github.gzuliyujiang.oaid.DeviceIdentifier import com.github.gzuliyujiang.oaid.IGetter + import com.jakewharton.processphoenix.ProcessPhoenix import com.orhanobut.logger.Logger import com.stripe.android.PaymentConfiguration @@ -64,7 +64,7 @@ class MainApplication : Application() { userBean = bean } - fun restartApp(activity: Activity,listener:OnRestartButtonListener) { + fun restartApp(activity: Activity, listener: OnRestartButtonListener) { var dialogDoMainChoose = DialogSureRestartChoose(activity) if (!dialogDoMainChoose.isShowing) { @@ -91,11 +91,54 @@ class MainApplication : Application() { } + fun initUtil() { + getApp()?.let { mainApplication -> + DeviceIdentifier.register(mApp); + + val processName = mainApplication.currentProcessName + mainApplication.extractGeoFiles() + Log.d("Process $processName started") + + mainApplication.updateNotificationChannels() + /* + * 错误日志上传捕获 + * */ + val crashCatchHandler: CrashCatchHandler = CrashCatchHandler.getInstance() //获得单例 + crashCatchHandler.init(mainApplication) //初始化,传入context + + if (DeviceID.supportedOAID(mainApplication)) { + // 获取OAID/AAID,异步回调 + DeviceID.getOAID(mainApplication, object : IGetter { + override fun onOAIDGetComplete(result: String) { + // 不同厂商的OAID/AAID格式是不一样的,可进行MD5、SHA1之类的哈希运算统一 + Log.d("onOAIDGetComplete ${result}") + OAID = result + } + + override fun onOAIDGetError(error: Exception) { + // 获取OAID/AAID失败 + error.printStackTrace() + } + }) + } + //openinstall +// OpenInstall.init(applicationContext); + PaymentConfiguration.init( + mainApplication, + "pk_live_51Nkl6vLWP3xWXY4LfXtdMtXzHazv6pav2rH1p1BfICeh5meGGjglExiw4GgmSzWO7NptEM1c549Fe11zRy9nCfxs009zEwLpXP" + ) +// OpenInstall.preInit(applicationContext) +// OpenInstall.init(applicationContext) + } + } + } - interface OnRestartButtonListener{ + + interface OnRestartButtonListener { fun enterButton() fun cancelButton() } + override fun attachBaseContext(base: Context?) { super.attachBaseContext(base) } @@ -104,54 +147,14 @@ class MainApplication : Application() { override fun onCreate() { super.onCreate() mApp = this -// if (privacyPolicyAgreed) { - DeviceIdentifier.register(mApp); -// } - Global.init(this) - val processName = currentProcessName - extractGeoFiles() - Log.d("Process $processName started") -// if (processName == packageName) { -// Log.d("Remote.launch()") -// Remote.launch() -// } else { -// Log.d("sendServiceRecreated") -// sendServiceRecreated() -// } - val MMKVRootDir = MMKV.initialize(applicationContext) + Global.init(mApp) + val MMKVRootDir = MMKV.initialize(mApp) Logger.i("MMKV_ROOT_DIR:$MMKVRootDir") - updateNotificationChannels() - /* - * 错误日志上传捕获 - * */ - val crashCatchHandler: CrashCatchHandler = CrashCatchHandler.getInstance() //获得单例 - crashCatchHandler.init(applicationContext) //初始化,传入context +// if (privacyPolicyAgreed) { - if (DeviceID.supportedOAID(applicationContext)) { - // 获取OAID/AAID,异步回调 - DeviceID.getOAID(applicationContext, object : IGetter { - override fun onOAIDGetComplete(result: String) { - // 不同厂商的OAID/AAID格式是不一样的,可进行MD5、SHA1之类的哈希运算统一 - Log.d("onOAIDGetComplete ${result}") - OAID = result - } - - override fun onOAIDGetError(error: Exception) { - // 获取OAID/AAID失败 - error.printStackTrace() - } - }) - } +// } - //openinstall -// OpenInstall.init(applicationContext); - PaymentConfiguration.init( - applicationContext, - "pk_live_51Nkl6vLWP3xWXY4LfXtdMtXzHazv6pav2rH1p1BfICeh5meGGjglExiw4GgmSzWO7NptEM1c549Fe11zRy9nCfxs009zEwLpXP" - ) -// OpenInstall.preInit(applicationContext) -// OpenInstall.init(applicationContext) } fun updateActivity(language: String, locale: Locale) { diff --git a/app/src/main/java/com/yingmao/clash/base/PublicViewMode.kt b/app/src/main/java/com/yingmao/clash/base/PublicViewMode.kt index b69c939..adc6adc 100644 --- a/app/src/main/java/com/yingmao/clash/base/PublicViewMode.kt +++ b/app/src/main/java/com/yingmao/clash/base/PublicViewMode.kt @@ -31,13 +31,20 @@ open class PublicViewMode : BaseViewMode() { NetService.instances.createFreeBaseUrl("https://yingmao.oss-cn-hongkong.aliyuncs.com/") doAsyncNoNeedReturn(HttpReqType.GET_HOST) { try { //TODO bug 会引起崩溃 - var host = if (BuildConfig.is_ym) { - rt.getHost() + val host = when { + BuildConfig.is_ym -> { + rt.getHostGithub() + } - } else if (BuildConfig.is_tz) { - rt.getTzHostTZ() - } else { - rt.getBzyHostDef() + BuildConfig.is_tz -> { + rt.getTzHostGithub() + } + BuildConfig.is_yunti -> { + rt.getYunTiHost() + } + else -> { + rt.getBzyHostGithub() + } } // Log.e("data", "2:$host") host?.takeIf { it.isNotEmpty() }?.let { @@ -71,7 +78,9 @@ open class PublicViewMode : BaseViewMode() { BuildConfig.is_tz -> { rt.getTzHostGithub() } - + BuildConfig.is_yunti -> { + rt.getYunTiHostGithub() + } else -> { rt.getBzyHostGithub() } @@ -107,7 +116,9 @@ open class PublicViewMode : BaseViewMode() { BuildConfig.is_tz -> { rt.getTzHostAWS() } - + BuildConfig.is_yunti -> { + rt.getYunTiHostAWS() + } else -> { rt.getBzyHostAWS() } @@ -223,4 +234,70 @@ open class PublicViewMode : BaseViewMode() { } } } + + fun getYunTiKefuHost(callback: AsyncBodyCallback) { + val rt = + NetService.instances.createFreeBaseUrl("https://yingmao.oss-cn-hongkong.aliyuncs.com/") + doAsyncNoNeedReturn(HttpReqType.GET_HOST) { + try { //TODO bug 会引起崩溃 + var host = rt.getYunTiKefuHost() + callback.suc(host) + } catch (e: Exception) { + e.printStackTrace() + callback.err() + } + } + } + fun getRegisterHost(callback: AsyncBodyCallback) { + val rt = + NetService.instances.createFreeBaseUrl("https://yingmao.oss-cn-hongkong.aliyuncs.com/") + doAsyncNoNeedReturn(HttpReqType.GET_HOST) { + try { //TODO bug 会引起崩溃 + var host = rt.getYmRegister() + callback.suc(host) + } catch (e: Exception) { + e.printStackTrace() + callback.err() + } + } + } + fun getTzRegisterHost(callback: AsyncBodyCallback) { + val rt = + NetService.instances.createFreeBaseUrl("https://yingmao.oss-cn-hongkong.aliyuncs.com/") + doAsyncNoNeedReturn(HttpReqType.GET_HOST) { + try { //TODO bug 会引起崩溃 + var host = rt.getTzRegister() + callback.suc(host) + } catch (e: Exception) { + e.printStackTrace() + callback.err() + } + } + } + fun getBzyRegisterHost(callback: AsyncBodyCallback) { + val rt = + NetService.instances.createFreeBaseUrl("https://yingmao.oss-cn-hongkong.aliyuncs.com/") + doAsyncNoNeedReturn(HttpReqType.GET_HOST) { + try { //TODO bug 会引起崩溃 + var host = rt.getBzyRegister() + callback.suc(host) + } catch (e: Exception) { + e.printStackTrace() + callback.err() + } + } + } + fun getYunTiRegisterHost(callback: AsyncBodyCallback) { + val rt = + NetService.instances.createFreeBaseUrl("https://yingmao.oss-cn-hongkong.aliyuncs.com/") + doAsyncNoNeedReturn(HttpReqType.GET_HOST) { + try { //TODO bug 会引起崩溃 + var host = rt.getYuntiRegister() + callback.suc(host) + } catch (e: Exception) { + e.printStackTrace() + callback.err() + } + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/yingmao/clash/conf/BZYConstants.kt b/app/src/main/java/com/yingmao/clash/conf/BZYConstants.kt index 0fbf6d2..7528c87 100644 --- a/app/src/main/java/com/yingmao/clash/conf/BZYConstants.kt +++ b/app/src/main/java/com/yingmao/clash/conf/BZYConstants.kt @@ -38,6 +38,8 @@ class BZYConstants { const val REQUEST_CODE_PAY_WEB_Stripe = 1001 const val REQUEST_CODE_PAY_WEB_BiLai = 1002 + const val REQUEST_CODE_Captcha_Result_Key = "REQUEST_CODE_Captcha_Result_Key" + //是否需要完善资料 const val MMKV_KEY_IS_PERFECT = "isPerfect" @@ -95,6 +97,7 @@ class BZYConstants { const val YMTGUrl = "https://t.me/shadowcat_vpn"; const val DefTGUrl = "https://t.me/bazhuayuvpn"; + const val YunTiTGUrl = "https://t.me/+0GFGw9JkM8EwMGRl"; const val TZTGUrl = "https://t.me/taizivpn"; const val PopularApplicationsUrl = "https://2828.im/" diff --git a/app/src/main/java/com/yingmao/clash/fragment/home/HomeFragment.kt b/app/src/main/java/com/yingmao/clash/fragment/home/HomeFragment.kt index 1c30731..2df728a 100644 --- a/app/src/main/java/com/yingmao/clash/fragment/home/HomeFragment.kt +++ b/app/src/main/java/com/yingmao/clash/fragment/home/HomeFragment.kt @@ -186,7 +186,9 @@ class HomeFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dispatcher llLine = view.findViewById(R.id.llLine) clActivity = view.findViewById(R.id.clActivity) clMember = view.findViewById(R.id.clMember) - + if (BuildConfig.productId=="182268"&&BuildConfig.is_tz){ + clActivity.visibility=View.INVISIBLE + } llLine.setOnClickListener { if (checkExpire()) { diff --git a/app/src/main/java/com/yingmao/clash/fragment/setting/SettingFragment.kt b/app/src/main/java/com/yingmao/clash/fragment/setting/SettingFragment.kt index 7486c0e..2cfd5d4 100644 --- a/app/src/main/java/com/yingmao/clash/fragment/setting/SettingFragment.kt +++ b/app/src/main/java/com/yingmao/clash/fragment/setting/SettingFragment.kt @@ -250,6 +250,11 @@ class SettingFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dispatc tvVersion = view.findViewById(R.id.tvVersion) clFire = view.findViewById(R.id.clFire) + if (BuildConfig.productId=="182268" && BuildConfig.is_tz){ + clFire.visibility=View.GONE + clTelegraph.visibility=View.GONE + clPreventLoss.visibility=View.INVISIBLE + } setExpireDate() if (checkExpire()) { @@ -465,12 +470,20 @@ class SettingFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dispatc clTelegraph.setOnClickListener { var uri = Uri.parse(BZYConstants.DefTGUrl) val intent = Intent(Intent.ACTION_VIEW) - if (BuildConfig.is_tz) { - uri = Uri.parse(BZYConstants.TZTGUrl) - } else { - if (BuildConfig.is_ym) { + when { + BuildConfig.is_ym -> { uri = Uri.parse(BZYConstants.YMTGUrl) } + + BuildConfig.is_tz -> { + uri = Uri.parse(BZYConstants.TZTGUrl) + } + BuildConfig.is_yunti -> { + uri = Uri.parse(BZYConstants.YunTiTGUrl) + } + else -> { + uri = Uri.parse(BZYConstants.DefTGUrl) + } } intent.setData(uri) startActivity(intent) diff --git a/app/src/main/java/com/yingmao/clash/net/http/HttpApi.kt b/app/src/main/java/com/yingmao/clash/net/http/HttpApi.kt index 7180753..36a3b81 100644 --- a/app/src/main/java/com/yingmao/clash/net/http/HttpApi.kt +++ b/app/src/main/java/com/yingmao/clash/net/http/HttpApi.kt @@ -54,11 +54,12 @@ interface HttpApi { ) @GET("/netbarcloud/open/startImg") suspend fun splashBg(): StartingBeans + @Headers( "User-Agent: Octopus_Android" ) @POST("/netbarcloud/vpn/phLogin.do") - fun login2(@QueryMap params: Map): Call + fun login2(@QueryMap params: Map): Call //检查登录 : http://10.10.23.115:8020/netbarcloud/api/userinfo @Headers( @@ -87,7 +88,12 @@ interface HttpApi { "User-Agent: Octopus_Android" ) @POST("/netbarcloud/vpn/appRegister2") - suspend fun encryptionRegister(@QueryMap params: Map): RegisterRsp + suspend fun encryptionRegister( + + @Body requestBody: RequestBody, + ): RegisterRsp + + //显示赠送时长 : @Headers( @@ -147,7 +153,7 @@ interface HttpApi { @QueryMap params: Map, @Header("token") string: String = MMKV.defaultMMKV().decodeString( BZYConstants.MMKV_KEY_TOKEN - ).toString() + ).toString(), ): String //心跳 http://10.10.23.115:8020/netbarcloud/api/heartbeat @@ -160,7 +166,7 @@ interface HttpApi { @QueryMap params: Map, @Header("token") string: String = MMKV.defaultMMKV().decodeString( BZYConstants.MMKV_KEY_TOKEN - ).toString() + ).toString(), ): String // @GET("/darkSuperman/lazy/blob/master/fire.json") @@ -169,32 +175,56 @@ interface HttpApi { //影猫 @GET("/host_ym.txt") suspend fun getHost(): String + @GET("/host_ym.txt") suspend fun getHostAWS(): String + @GET("/ym-source/ym/main/host_ym.txt") suspend fun getHostGithub(): String + //八爪鱼 @GET("/hostdef.txt") suspend fun getBzyHostDef(): String + @GET("/hostdef.txt") suspend fun getBzyHostAWS(): String + @GET("/ym-source/ym/main/hostdef.txt") suspend fun getBzyHostGithub(): String + //太子 @GET("/hosttaizi.txt") suspend fun getTzHostTZ(): String + @GET("/hosttaizi.txt") suspend fun getTzHostAWS(): String + @GET("/ym-source/ym/main/hosttaizi.txt") suspend fun getTzHostGithub(): String + //云梯 + @GET("/host_yunti.txt") + suspend fun getYunTiHost(): String + + @GET("/host_yunti.txt") + suspend fun getYunTiHostAWS(): String + + @GET("/ym-source/ym/main/host_yunti.txt") + suspend fun getYunTiHostGithub(): String + //注册链接 @GET("/ymregister.txt") suspend fun getYmRegister(): String + @GET("/taiziregister.txt") suspend fun getTzRegister(): String + @GET("/bzyregister.txt") suspend fun getBzyRegister(): String + + @GET("/yunti_register.txt") + suspend fun getYuntiRegister(): String + //客服链接 @GET("/ymkefu.txt") suspend fun getYingMaoKefuHost(): String @@ -204,6 +234,9 @@ interface HttpApi { @GET("/bzy_kefu.txt") suspend fun getBzyKefuHost(): String + + @GET("/yt_kefu.txt") + suspend fun getYunTiKefuHost(): String // @Headers( // "User-Agent: Octopus_Android" // ) @@ -245,9 +278,10 @@ interface HttpApi { ) @POST("/netbarcloud/upload/uploadRequestLogs") suspend fun uploadRequestLogs( - @Body param: RequestBody, @Header("token") string: String = MMKV.defaultMMKV().decodeString( + @Body param: RequestBody, + @Header("token") string: String = MMKV.defaultMMKV().decodeString( BZYConstants.MMKV_KEY_TOKEN - ).toString() + ).toString(), ): NormalRsp @@ -258,7 +292,7 @@ interface HttpApi { suspend fun getDomain( @Header("token") string: String = MMKV.defaultMMKV().decodeString( BZYConstants.MMKV_KEY_TOKEN - ).toString() + ).toString(), ): String //http://10.10.23.115:8020/netbarcloud/vpn/getPointCardSurplus.do @@ -268,7 +302,7 @@ interface HttpApi { @QueryMap params: Map, @Header("token") string: String = MMKV.defaultMMKV().decodeString( BZYConstants.MMKV_KEY_TOKEN - ).toString() + ).toString(), ): NormalRsp //http://10.10.23.115:8020/netbarcloud/vpn/phRechargeInfo.do @@ -285,7 +319,7 @@ interface HttpApi { @QueryMap params: Map, @Header("token") string: String = MMKV.defaultMMKV().decodeString( BZYConstants.MMKV_KEY_TOKEN - ).toString() + ).toString(), ): RechargeInfoRsp //http://10.10.23.115:8020/netbarcloud/vpn/phPay.do @@ -297,7 +331,7 @@ interface HttpApi { @QueryMap params: Map, @Header("token") string: String = MMKV.defaultMMKV().decodeString( BZYConstants.MMKV_KEY_TOKEN - ).toString() + ).toString(), ): PayRsp @@ -306,7 +340,7 @@ interface HttpApi { @QueryMap params: HashMap, @Header("token") string: String = MMKV.defaultMMKV().decodeString( BZYConstants.MMKV_KEY_TOKEN - ).toString() + ).toString(), ): PayRsp //http://10.10.23.115:8020/netbarcloud/vpn/appAliPay.do @@ -318,7 +352,7 @@ interface HttpApi { @QueryMap params: Map, @Header("token") string: String = MMKV.defaultMMKV().decodeString( BZYConstants.MMKV_KEY_TOKEN - ).toString() + ).toString(), ): NormalRsp //汇旺财二维码支付 @@ -330,7 +364,7 @@ interface HttpApi { @QueryMap params: Map, @Header("token") string: String = MMKV.defaultMMKV().decodeString( BZYConstants.MMKV_KEY_TOKEN - ).toString() + ).toString(), ): QRPayRsp //汇旺财二维码支付结果 @@ -342,7 +376,7 @@ interface HttpApi { @QueryMap params: Map, @Header("token") string: String = MMKV.defaultMMKV().decodeString( BZYConstants.MMKV_KEY_TOKEN - ).toString() + ).toString(), ): QRPayStatusRsp @@ -355,7 +389,7 @@ interface HttpApi { @QueryMap params: Map, @Header("token") string: String = MMKV.defaultMMKV().decodeString( BZYConstants.MMKV_KEY_TOKEN - ).toString() + ).toString(), ): WXPayRsp //http://10.10.23.115:8020/netbarcloud/vpn/pcPayStatus.do @@ -367,7 +401,7 @@ interface HttpApi { @QueryMap params: Map, @Header("token") string: String = MMKV.defaultMMKV().decodeString( BZYConstants.MMKV_KEY_TOKEN - ).toString() + ).toString(), ): NormalRsp //http://10.10.23.115:8020/netbarcloud/vpn/phOrderList.do @@ -379,7 +413,7 @@ interface HttpApi { @QueryMap params: Map, @Header("token") string: String = MMKV.defaultMMKV().decodeString( BZYConstants.MMKV_KEY_TOKEN - ).toString() + ).toString(), ): ExpensesRecordRsp //http://10.10.23.115:8020/netbarcloud/vpn/pointCardSurplusRecharge.do @@ -391,7 +425,7 @@ interface HttpApi { @QueryMap params: Map, @Header("token") string: String = MMKV.defaultMMKV().decodeString( BZYConstants.MMKV_KEY_TOKEN - ).toString() + ).toString(), ): NormalMessageRsp //http://10.10.23.115:8020/netbarcloud/vpn/appPcPointCardPay.do @@ -403,7 +437,7 @@ interface HttpApi { @QueryMap params: Map, @Header("token") string: String = MMKV.defaultMMKV().decodeString( BZYConstants.MMKV_KEY_TOKEN - ).toString() + ).toString(), ): NormalMessageRsp @Headers( @@ -414,7 +448,7 @@ interface HttpApi { @QueryMap params: Map, @Header("token") string: String = MMKV.defaultMMKV().decodeString( BZYConstants.MMKV_KEY_TOKEN - ).toString() + ).toString(), ): BiLaiNormalRsp @Headers( @@ -425,7 +459,7 @@ interface HttpApi { @QueryMap params: Map, @Header("token") string: String = MMKV.defaultMMKV().decodeString( BZYConstants.MMKV_KEY_TOKEN - ).toString() + ).toString(), ): BiLaiNormalRsp @Headers( @@ -436,7 +470,7 @@ interface HttpApi { @QueryMap params: Map, @Header("token") string: String = MMKV.defaultMMKV().decodeString( BZYConstants.MMKV_KEY_TOKEN - ).toString() + ).toString(), ): PhDownloadUrlRsp @Headers( @@ -447,7 +481,7 @@ interface HttpApi { @QueryMap params: Map, @Header("token") string: String = MMKV.defaultMMKV().decodeString( BZYConstants.MMKV_KEY_TOKEN - ).toString() + ).toString(), ): BiLaiPayStatusRsp @@ -459,7 +493,7 @@ interface HttpApi { @QueryMap params: Map, @Header("token") string: String = MMKV.defaultMMKV().decodeString( BZYConstants.MMKV_KEY_TOKEN - ).toString() + ).toString(), ): SubscriptionRsp //网页支付统一订单查询 @@ -471,7 +505,7 @@ interface HttpApi { @QueryMap params: Map, @Header("token") string: String = MMKV.defaultMMKV().decodeString( BZYConstants.MMKV_KEY_TOKEN - ).toString() + ).toString(), ): NormalMessageRsp @Headers( @@ -482,7 +516,7 @@ interface HttpApi { @QueryMap params: Map, @Header("token") string: String = MMKV.defaultMMKV().decodeString( BZYConstants.MMKV_KEY_TOKEN - ).toString() + ).toString(), ): AppVersionCheckRsp @Headers( @@ -490,7 +524,7 @@ interface HttpApi { ) @GET("/netbarcloud/vpn/upgradeVersion") suspend fun upgradeVersion( - @QueryMap params: Map + @QueryMap params: Map, ): AppVersionCheckRsp //忘记密码 @@ -511,7 +545,7 @@ interface HttpApi { @QueryMap params: Map, @Header("token") string: String = MMKV.defaultMMKV().decodeString( BZYConstants.MMKV_KEY_TOKEN - ).toString() + ).toString(), ): SendSmsRsp //会员签到 @@ -523,7 +557,7 @@ interface HttpApi { @QueryMap params: Map, @Header("token") string: String = MMKV.defaultMMKV().decodeString( BZYConstants.MMKV_KEY_TOKEN - ).toString() + ).toString(), ): VipSignRsp //会员签到 @@ -535,7 +569,7 @@ interface HttpApi { @QueryMap params: Map, @Header("token") string: String = MMKV.defaultMMKV().decodeString( BZYConstants.MMKV_KEY_TOKEN - ).toString() + ).toString(), ): GetActivityRsp //获取阿里云上传数据 @@ -547,7 +581,7 @@ interface HttpApi { @QueryMap params: Map, @Header("token") string: String = MMKV.defaultMMKV().decodeString( BZYConstants.MMKV_KEY_TOKEN - ).toString() + ).toString(), ): UploadParamData @Headers( @@ -559,7 +593,7 @@ interface HttpApi { @Body requestBody: RequestBody, @Header("token") string: String = MMKV.defaultMMKV().decodeString( BZYConstants.MMKV_KEY_TOKEN - ).toString() + ).toString(), ): PayUploadParamData @Headers( @@ -570,7 +604,7 @@ interface HttpApi { @QueryMap params: Map, @Header("token") string: String = MMKV.defaultMMKV().decodeString( BZYConstants.MMKV_KEY_TOKEN - ).toString() + ).toString(), ): AppStartupStatus @Headers( @@ -582,7 +616,7 @@ interface HttpApi { @Body requestBody: RequestBody, @Header("token") string: String = MMKV.defaultMMKV().decodeString( BZYConstants.MMKV_KEY_TOKEN - ).toString() + ).toString(), ): AppStopStatus @Headers( @@ -594,6 +628,6 @@ interface HttpApi { @Body requestBody: RequestBody, @Header("token") string: String = MMKV.defaultMMKV().decodeString( BZYConstants.MMKV_KEY_TOKEN - ).toString() + ).toString(), ): AppStopStatus } \ No newline at end of file diff --git a/app/src/main/java/com/yingmao/clash/net/http/NetService.kt b/app/src/main/java/com/yingmao/clash/net/http/NetService.kt index dba2407..e05d3fa 100644 --- a/app/src/main/java/com/yingmao/clash/net/http/NetService.kt +++ b/app/src/main/java/com/yingmao/clash/net/http/NetService.kt @@ -59,6 +59,7 @@ class NetService private constructor() : INetService { // "https://api.gaogaoshousoft.cc:18001" // "https://api.yingmaox.cc:8700" // "https://113.108.210.50:21002" +// "https://bc5b-14-146-29-2.ngrok-free.app" MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_CURRENT_HOST, BuildConfig.service_url)!! // MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_CURRENT_HOST, "https://app.bazhuayujiasu.cc:18001") } else { diff --git a/app/src/main/java/com/yingmao/clash/util/Utils.kt b/app/src/main/java/com/yingmao/clash/util/Utils.kt index 4e8dd07..bd68f1d 100644 --- a/app/src/main/java/com/yingmao/clash/util/Utils.kt +++ b/app/src/main/java/com/yingmao/clash/util/Utils.kt @@ -254,32 +254,7 @@ object Utils { } } - fun getIPAddress(): String { - try { - val en: Enumeration = NetworkInterface.getNetworkInterfaces() - while (en.hasMoreElements()) { - val intf: NetworkInterface = en.nextElement() - val enumIpAddr: Enumeration = intf.getInetAddresses() - while (enumIpAddr.hasMoreElements()) { - val inetAddress: InetAddress = enumIpAddr.nextElement() - if (!inetAddress.isLoopbackAddress() && !inetAddress.isLinkLocalAddress() && inetAddress.isSiteLocalAddress()) { - return inetAddress.getHostAddress() - } - } - } - } catch (e: java.lang.Exception) { - e.printStackTrace() - } - return "0.0.0.0" - } - fun getIPAddress(context: Context): String? { - val wifiManager = - context.applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager - val wifiInfo = wifiManager.connectionInfo - val ipAddress = wifiInfo.ipAddress - return (ipAddress and 0xFF).toString() + "." + (ipAddress shr 8 and 0xFF) + "." + (ipAddress shr 16 and 0xFF) + "." + (ipAddress shr 24 and 0xFF) - } public fun isAppInstalled(context: Context, packageName: String): Boolean { return try { diff --git a/app/src/main/java/com/yingmao/clash/view/dialog/DialogAgreementPrivacyChoose.kt b/app/src/main/java/com/yingmao/clash/view/dialog/DialogAgreementPrivacyChoose.kt new file mode 100644 index 0000000..b2088f9 --- /dev/null +++ b/app/src/main/java/com/yingmao/clash/view/dialog/DialogAgreementPrivacyChoose.kt @@ -0,0 +1,187 @@ +package com.yingmao.clash.view.dialog + +import android.annotation.SuppressLint +import android.app.Activity +import android.content.Context +import android.content.DialogInterface +import android.content.Intent +import android.graphics.Color +import android.text.Spannable +import android.text.SpannableStringBuilder +import android.text.TextUtils +import android.text.method.LinkMovementMethod +import android.text.style.BackgroundColorSpan +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.Button +import android.widget.TextView +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView +import com.chad.library.adapter.base.BaseQuickAdapter +import com.cncat.vpn.common.log.Log +import com.tencent.mmkv.MMKV + +import com.yingmao.clash.R +import com.yingmao.clash.act.AgreementAndPrivacyActivity +import com.yingmao.clash.act.MyClickableSpan +import com.yingmao.clash.act.UIMainActivity +import com.yingmao.clash.conf.BZYConstants +import com.yingmao.clash.entity.DomainItemBean + +import com.yingmao.clash.view.adapter.DomainListAdapter + + +/** + * @author tamsiree + * @date 2016/7/19 + * 确认 取消 Dialog + */ +open class DialogAgreementPrivacyChoose : RxDialog { + lateinit var titleView: TextView + private set + lateinit var but_agree: TextView + private set + lateinit var but_cancel: TextView + private set + lateinit var dialog_agreement_info: TextView + private set + lateinit var onTryListener: OnTryButtonListener + + lateinit var onDomainListItemListener: OnListItemListener + + constructor(context: Context?, themeResId: Int) : super(context!!, themeResId) { + initView() + } + + constructor( + context: Context?, + cancelable: Boolean, + cancelListener: DialogInterface.OnCancelListener?, + ) : super(context!!, cancelable, cancelListener) { + initView() + } + + constructor(context: Context?) : super(context!!) { + initView() + } + + constructor(context: Activity?) : super(context!!) { + initView() + } + + constructor(context: Context?, alpha: Float, gravity: Int) : super(context, alpha, gravity) { + initView() + } + + + @SuppressLint("MissingInflatedId") + private fun initView() { + val dialogView = + LayoutInflater.from(context).inflate(R.layout.dialog_agreement_privacy_choose, null) + titleView = dialogView.findViewById(R.id.tv_title) + but_agree = dialogView.findViewById(R.id.but_agree) + but_cancel = dialogView.findViewById(R.id.but_cancel) + dialog_agreement_info = dialogView.findViewById(R.id.dialog_agreement_info) + + initUserAgreementView(context, dialog_agreement_info) + + but_agree.setOnClickListener { + onTryListener.agree() + } + but_cancel.setOnClickListener { onTryListener.cancel() } + + setContentView(dialogView) + setCancelable(false) + window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT) + + + } + + private fun initUserAgreementView(activity: Context, textView: TextView) { + var privacy_s = 16 + var privacy_e = 22 + var agreement_s = 9 + var agreement_e = 15 + + val spannableStringBuilder = + SpannableStringBuilder(activity.resources.getString(R.string.AgreeAgreement2)) + val clickableSpan: MyClickableSpan = object : MyClickableSpan() { + override fun onClick(view: View) { + val backgroundColorSpan = BackgroundColorSpan(Color.parseColor("#4072FE")) + spannableStringBuilder.setSpan( + backgroundColorSpan, + agreement_s, + agreement_e, + Spannable.SPAN_EXCLUSIVE_INCLUSIVE + ) + textView.text = spannableStringBuilder + val intent = Intent(activity, AgreementAndPrivacyActivity::class.java) + intent.putExtra( + BZYConstants.EXTRA_KEY_AGREEMENT, + BZYConstants.EXTRA_PRIVACY_AGREEMENT + ) + activity.startActivity(intent) + } + } + spannableStringBuilder.setSpan( + clickableSpan, + agreement_s, + agreement_e, + Spannable.SPAN_EXCLUSIVE_INCLUSIVE + ) + + val privacyClickableSpan: MyClickableSpan = object : MyClickableSpan() { + override fun onClick(view: View) { + val backgroundColorSpan = BackgroundColorSpan(Color.parseColor("#4072FE")) + spannableStringBuilder.setSpan( + backgroundColorSpan, + privacy_s, + privacy_e, + Spannable.SPAN_EXCLUSIVE_INCLUSIVE + ) + textView.text = spannableStringBuilder + val intent = Intent(activity, AgreementAndPrivacyActivity::class.java) + intent.putExtra( + BZYConstants.EXTRA_KEY_AGREEMENT, + BZYConstants.EXTRA_USER_AGREEMENT + ) + activity.startActivity(intent) + } + } + spannableStringBuilder.setSpan( + privacyClickableSpan, + privacy_s, + privacy_e, + Spannable.SPAN_EXCLUSIVE_INCLUSIVE + ) + textView.text = spannableStringBuilder + textView.movementMethod = LinkMovementMethod.getInstance() + + + } + + fun setOnTryButtonListener(listener: OnTryButtonListener) { + this.onTryListener = listener + } + + fun setOnListItemListener(listener: OnListItemListener) { + this.onDomainListItemListener = listener + } + + + private fun changeSubUrl(originalUrl: String, newUrl: String): String { + return originalUrl.replace(Regex("https://[^/]+/"), "$newUrl/") + + } + + interface OnTryButtonListener { + fun agree() + fun cancel() + } + + interface OnListItemListener { + fun listItemClick() + + } +} \ No newline at end of file diff --git a/app/src/main/java/com/yingmao/clash/vm/LoginAtyVM.kt b/app/src/main/java/com/yingmao/clash/vm/LoginAtyVM.kt index df860b4..81a3a7c 100644 --- a/app/src/main/java/com/yingmao/clash/vm/LoginAtyVM.kt +++ b/app/src/main/java/com/yingmao/clash/vm/LoginAtyVM.kt @@ -96,45 +96,7 @@ class LoginAtyVM : PublicViewMode() { } } - fun getRegisterHost(callback: AsyncBodyCallback) { - val rt = - NetService.instances.createFreeBaseUrl("https://yingmao.oss-cn-hongkong.aliyuncs.com/") - doAsyncNoNeedReturn(HttpReqType.GET_HOST) { - try { //TODO bug 会引起崩溃 - var host = rt.getYmRegister() - callback.suc(host) - } catch (e: Exception) { - e.printStackTrace() - callback.err() - } - } - } - fun getTzRegisterHost(callback: AsyncBodyCallback) { - val rt = - NetService.instances.createFreeBaseUrl("https://yingmao.oss-cn-hongkong.aliyuncs.com/") - doAsyncNoNeedReturn(HttpReqType.GET_HOST) { - try { //TODO bug 会引起崩溃 - var host = rt.getTzRegister() - callback.suc(host) - } catch (e: Exception) { - e.printStackTrace() - callback.err() - } - } - } - fun getBzyRegisterHost(callback: AsyncBodyCallback) { - val rt = - NetService.instances.createFreeBaseUrl("https://yingmao.oss-cn-hongkong.aliyuncs.com/") - doAsyncNoNeedReturn(HttpReqType.GET_HOST) { - try { //TODO bug 会引起崩溃 - var host = rt.getBzyRegister() - callback.suc(host) - } catch (e: Exception) { - e.printStackTrace() - callback.err() - } - } - } + fun upgradeVersion() { val httpApi = NetService.instances.createHttpsEncodeStr(HttpApi::class.java) val phoneNumber = diff --git a/app/src/main/java/com/yingmao/clash/vm/SplashAtyVM.kt b/app/src/main/java/com/yingmao/clash/vm/SplashAtyVM.kt index bc6ec8d..e14cab3 100644 --- a/app/src/main/java/com/yingmao/clash/vm/SplashAtyVM.kt +++ b/app/src/main/java/com/yingmao/clash/vm/SplashAtyVM.kt @@ -2,6 +2,7 @@ package com.yingmao.clash.vm import android.text.TextUtils import android.util.Log +import com.google.gson.Gson import com.orhanobut.logger.Logger import com.tencent.mmkv.MMKV @@ -20,6 +21,9 @@ import com.yingmao.clash.net.http.NetService import com.yingmao.clash.util.AESUtil import kotlinx.coroutines.Job +import okhttp3.MediaType.Companion.toMediaType +import okhttp3.RequestBody +import okhttp3.RequestBody.Companion.toRequestBody class SplashAtyVM : PublicViewMode() { @@ -82,8 +86,12 @@ class SplashAtyVM : PublicViewMode() { fun registerByEncryption(params: Map) { Log.e("data", "register ....") val httpApi = NetService.instances.createHttps(HttpApi::class.java) + + val gson = Gson() + val jsonString = gson.toJson(params) + val requestBody: RequestBody = jsonString.toRequestBody("application/json; charset=utf-8".toMediaType()) doAsync(HttpReqType.REGISTER) { - httpApi.encryptionRegister(params) + httpApi.encryptionRegister(requestBody) } } diff --git a/app/src/main/java/com/yingmao/clash/webview/BZYWebViewKeFu.kt b/app/src/main/java/com/yingmao/clash/webview/BZYWebViewKeFu.kt index b4a986e..b01a729 100644 --- a/app/src/main/java/com/yingmao/clash/webview/BZYWebViewKeFu.kt +++ b/app/src/main/java/com/yingmao/clash/webview/BZYWebViewKeFu.kt @@ -84,14 +84,21 @@ class BZYWebViewKeFu : BaseActivity() { //// Log.e("data", "==$newProgress") // } // } - if (BuildConfig.is_tz) { -// webView.loadUrl("file:///android_asset/TZKeFu.html") - getTzKefu() - } else { - if (BuildConfig.is_ym) { + + when { + BuildConfig.is_ym -> { ymKefu() - } else { -// webView.loadUrl("file:///android_asset/kefu.html") + } + + BuildConfig.is_tz -> { + getTzKefu() + } + + BuildConfig.is_yunti -> { + getYunTiKefu() + } + + else -> { getBzyKefu() } } @@ -148,7 +155,8 @@ class BZYWebViewKeFu : BaseActivity() { finish() } } - private fun getBzyKefu(){ + + private fun getBzyKefu() { val userName = MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_REMEMBER_USERNAME, "") var enNmae = URLEncoder.encode(userName, "UTF-8") Log.d("enNmae==>${enNmae}") @@ -197,7 +205,8 @@ class BZYWebViewKeFu : BaseActivity() { finish() } } - private fun getTzKefu(){ + + private fun getTzKefu() { val userName = MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_REMEMBER_USERNAME, "") var enNmae = URLEncoder.encode(userName, "UTF-8") Log.d("enNmae==>${enNmae}") @@ -246,4 +255,53 @@ class BZYWebViewKeFu : BaseActivity() { finish() } } + + private fun getYunTiKefu() { + val userName = MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_REMEMBER_USERNAME, "") + var enNmae = URLEncoder.encode(userName, "UTF-8") + Log.d("enNmae==>${enNmae}") + if (TextUtils.isEmpty(kefuHost)) { + var mmkvHost = MMKV.defaultMMKV() + .decodeString(BZYConstants.MMKV_KEY_KEFU_HOST, "") +// com.cncat.vpn.common.log.Log.d("mmkvHost kf ==>${mmkvHost}") + webViewAtyVM.getYunTiKefuHost(object : AsyncBodyCallback { + override suspend fun suc(str: String) { +// com.cncat.vpn.common.log.Log.d("str==>${str}") + if (str != mmkvHost) { + MMKV.defaultMMKV() + .encode(BZYConstants.MMKV_KEY_KEFU_HOST, str) + } + kefuHost = str + startActivity( + Intent( + Intent.ACTION_VIEW, + Uri.parse(str + "&app_account=${enNmae}") + ) + ) + finish() + } + + override fun err() { + if (!TextUtils.isEmpty(mmkvHost)) { + startActivity( + Intent( + Intent.ACTION_VIEW, + Uri.parse(mmkvHost + "&app_account=${enNmae}") + ) + ) + finish() + } + } + + }) + } else { + startActivity( + Intent( + Intent.ACTION_VIEW, + Uri.parse(kefuHost + "&app_account=${enNmae}") + ) + ) + finish() + } + } } \ No newline at end of file diff --git a/app/src/main/res/layout/dialog_agreement_privacy_choose.xml b/app/src/main/res/layout/dialog_agreement_privacy_choose.xml new file mode 100644 index 0000000..0cca4f4 --- /dev/null +++ b/app/src/main/res/layout/dialog_agreement_privacy_choose.xml @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/layout_splash_activity.xml b/app/src/main/res/layout/layout_splash_activity.xml index 09c57cd..d842bda 100644 --- a/app/src/main/res/layout/layout_splash_activity.xml +++ b/app/src/main/res/layout/layout_splash_activity.xml @@ -1,19 +1,77 @@ + tools:context=".act.SplashActivity"> + + + + + + + + + + + + + + + + + + + + android:visibility="gone"> + android:layout_weight="1" + android:visibility="gone"> + android:textColor="@color/blue_0136CB" + android:textSize="15sp" /> diff --git a/app/src/main/res/mipmap-hdpi/img.png b/app/src/main/res/mipmap-hdpi/img.png new file mode 100644 index 0000000..ef90ea4 Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/img.png differ diff --git a/app/src/main/res/mipmap-hdpi/yunti_logo.webp b/app/src/main/res/mipmap-hdpi/yunti_logo.webp new file mode 100644 index 0000000..094b295 Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/yunti_logo.webp differ diff --git a/app/src/main/res/mipmap-mdpi/yunti_logo.webp b/app/src/main/res/mipmap-mdpi/yunti_logo.webp new file mode 100644 index 0000000..1f4cdb6 Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/yunti_logo.webp differ diff --git a/app/src/main/res/mipmap-xhdpi/yunti_logo.webp b/app/src/main/res/mipmap-xhdpi/yunti_logo.webp new file mode 100644 index 0000000..49961cb Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/yunti_logo.webp differ diff --git a/app/src/main/res/values-en/strings.xml b/app/src/main/res/values-en/strings.xml index 40c7373..545bb7c 100644 --- a/app/src/main/res/values-en/strings.xml +++ b/app/src/main/res/values-en/strings.xml @@ -4,6 +4,7 @@ 影猫 影猫加速器 太子 + 云梯加速器 file rule proxy @@ -351,5 +352,10 @@ Service Description\n Suggest restarting Restart Speed test + + Agree + Disagree + Go to login + Email registration Recharge Membership \ No newline at end of file diff --git a/app/src/main/res/values-zh-rHK/strings.xml b/app/src/main/res/values-zh-rHK/strings.xml index ed9ab9e..1896975 100644 --- a/app/src/main/res/values-zh-rHK/strings.xml +++ b/app/src/main/res/values-zh-rHK/strings.xml @@ -338,8 +338,15 @@ 每天 熱門應用 熱門應用導航 - "建議重啓 " - "重啓 " + "建議重啓" + "重啓" 線路測速 + + 同意 + 不同意 + 直接登入 + 雲梯加速器 + 手動注册 + 充值會員 \ No newline at end of file diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index a233591..b4fcc26 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -337,8 +337,14 @@ 每天 熱門應用 熱門應用導航 - "建議重啓 " - "重啓 " + "建議重啓" + "重啓" 線路測速 + + 同意 + 不同意 + 直接登入 + 雲梯加速器 + 手動注册 充值會員 \ 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 6bd477d..424ff30 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -131,6 +131,7 @@ 检查登录失败 登录异常 同意《隐私协议》和《用户协议》 + 请您充分阅读并理解《隐私政策》和《用户协议》我们非常重视您的隐私和个人信息,在您使用过程中,我们会收集部分个人信息。例如,会申请设备信息等。您可以点击《用户协议》和《隐私政策》查看详细内容。您可以选择“同意”继续使用我们的服务,或者选择“不同意”退出。 请仔细阅读并同意《隐私协议》和《用户协议》 小提示:自动注册初始密码为 123456,手动注册请忽略 小提示2:华为鸿蒙系统由于鉴定机制的问题,将App误报为诈骗软件,请忽略正常放心使用,有任何问题联系客服及售后 @@ -359,6 +360,14 @@ 建议重启 重启 线路测速 + + 同意 + 不同意 + 直接登录 + + 云梯加速器 + 手动注册 + 充值会员