Merge branch 'master' into ConnectImmediately

# Conflicts:
#	app/src/main/java/com/yingmao/clash/act/NewMainActivity.kt
#	app/src/main/java/com/yingmao/clash/act/SplashActivity.kt
This commit is contained in:
level 2025-05-23 10:37:02 +08:00
commit aa1bdbde62
31 changed files with 1476 additions and 329 deletions

View File

@ -10,7 +10,7 @@
<uses-feature
android:name="android.hardware.touchscreen"
android:required="false" /> <!-- <uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE" /> -->
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_SPECIAL_USE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
@ -43,6 +43,7 @@
android:supportsRtl="true"
android:theme="@style/Theme.Octopus"
tools:ignore="GoogleAppIndexingWarning"
android:usesCleartextTraffic="true"
tools:targetApi="N">
<activity
android:name=".act.InstallApplicationActivity"

View File

@ -0,0 +1,126 @@
<html>
<style type="text/css">
.font_foot{
font-family:verdana;
font-size:80%;
color:gray;
margin:0 auto;}
.font_subtitle{
font-family:verdana;
font-size:120%;
color:black;
font-weight: bold;}
.font_content{
font-family:verdana;
font-size:100%;
color:black;
margin:0 auto;
text-indent:1.8em;}
</style>
<body>
<h2 align="center">服務條款</h2>
<hr/>
<p class="font_content">爲維護雙方利益,根據相關法律、法規的規定,雙方在平等、自願、公平、誠信的基礎上,加速器科技(以下簡稱“加速器”)旗下產品加速器客户端(以下簡稱“加速器”)就用户購買跨境互聯網虛擬專用網絡服務(以下簡稱“服務”)的相關事宜達成如下協議,請您務必審慎閲讀、充分理解各條款內容,特彆是免除或者限製責任的條款、法律適用和爭議解決條款,您應重點閲讀。如您對協議有任何疑問,可嚮我方平枱客服咨詢,協議如下:</p>
<p class="font_content">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. <br/>
</p>
<p class="font_content">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.</p>
<p class="font_subtitle">
太子 Service
</p>
<p class="font_content">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.</p>
<p class="font_subtitle">
Usage Policy
</p>
<p class="font_content">a) BY USING 太子 加速器 SERVICE (the "Service") YOU AGREE:</p>
<p class="font_content">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.</p>
<p class="font_content">b) NOT to launch any pop-ups from our service.</p>
<p class="font_content">c) NOT to attack in any way shape or form any other computer or network while on our service.</p>
<p class="font_content">d) NOT to use the service for things that could hurt our network or other people.</p>
<p class="font_content">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.</p>
<p class="font_content">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 attorneys fees and costs without limitation.</p>
<p class="font_content">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.</p>
<p class="font_subtitle">
Disclaimers
</p>
<p class="font_content">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.</p>
<p class="font_content">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.</p>
<p class="font_content">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.</p>
<p class="font_content">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.</p>
<p class="font_content">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.</p>
<p class="font_subtitle">
第一條 服務範圍
</p>
<p class="font_content">1.1 加速器嚮申請主體(以下簡稱“用户”)提供服務,用户按照本協議約定的條款接受服務。</p>
<p class="font_subtitle">
第二條 賬户注冊及用户資料
</p>
<p class="font_content">2.1 用户下載加速器客户端後,首次使用手機號和驗證碼登録即爲注冊;</p>
<p class="font_content">2.2 用户在使用加速器提供的服務時,應使用真實、準確的手機號進行注冊或登録,不得冒用他人手機號,若因冒用他人手機號而產生瞭糾紛或損失,由客户自行承擔;</p>
<p class="font_content">2.3 加速器對用户資料依法保密,但爲建立與用户溝通渠道,改善服務工作,加速器可以使用本協議涉及的用户資料;</p>
<p class="font_content">2.4 用户應妥善保管手機號和驗證碼,因用户原因造成的用户驗證碼遺失或被他人穫取造成的責任、損失,加速器不予承擔。</p>
<p class="font_subtitle">
第三條 業務使用
</p>
<p class="font_content">3.1 用户確認開始使用/注冊程序使用我方平枱服務前,應當具備中華人民共和國法律規定的與您行爲相適應的民事行爲能力。若用户不具備前述與用户行爲相適應的民事行爲能力,則應穫得監護人的知情同意,用户及用户的監護人應依照法律規定承擔因此而導緻的相應的責任。如果用户是未成年人,請在用户的監護人同意和指導下訪問和/或使用我方服務;</p>
<p class="font_content">3.2 用户使用服務時,應遵守中華人民共和國的法律、法規、規章等相關規定;</p>
<p class="font_content">3.3 加速器提供的服務僅限成功注冊并繳費的用户使用,若因用户將服務提供給第三方使用等而產生的責任及損失,由用户自行承擔;</p>
<p class="font_content">3.4 官網公布的方式,爲下載、注冊、登録、使用我方服務的唯一合法途徑,您通過其他任何方式穫取的我方服務均爲非法取得,我方概不承認其效力,一經發現,我方有權立即做齣刪除、取消、暫停、封號等處理,任何因此導緻的一切不利後果均由用户自行承擔。我方保留嚮相關責任主體追究法律責任的權利。</p>
<p class="font_subtitle">
第四條 費用標準和費用交納
</p>
<p class="font_content">4.1 服務的計費周期爲:用户首次登録時係統默認贈送 24 小時免費體驗,如需續期,則按官網及客户端展示的租期費用執行,具體租期分爲 1 個月、6 個月和 1 年,支付方式可選擇微信、支付寶等;</p>
<p class="font_content">4.2 如有政策調整,自調整時間起按新標準執行。</p>
<p class="font_content">4.3 租期服務期限以用户自行選擇并支付相應費用的期限爲準,租期服務到期後,加速器將停止繼續嚮用户提供相關服務;</p>
<p class="font_subtitle">
第五條 服務質量與用户服務
</p>
<p class="font_content">5.1 加速器會在官網等公布相關事宜的服務項目、服務時限、服務範圍、使用規則、交費規定等內容。</p>
<p class="font_content">5.2 加速器負責嚮用户提供加速器客户端的下載、安裝、注冊、登録、使用等方面的咨詢服務;</p>
<p class="font_content">5.3 因加速器原因造成通信障礙,且不能修複的,加速器免收故障期間的服務費,按天計算(另有約定的除外)。加速器不賠償因故障造成的其他損失。故障時間的計算,以加速器接到用户申告或加速器查齣障礙的時間起至恢複使用爲止。</p>
<p class="font_subtitle">
第六條 協議中止和解除
</p>
<p class="font_content">6.1 本協議有效期與用户購買的服務時長一緻。</p>
<p class="font_content">6.2 用户有下列情形之一的,加速器可以終止服務并不承擔責任,已收取的費用不做退迴:</p>
<p class="font_content">1用户違反本協議約定我方依據違約條款終止本協議的</p>
<p class="font_content">2用户轉借賬號、盜用他人賬號、發布違禁內容和信息、騙取他人財物、采取不正當手段謀利等行爲我方依據我方平枱規則對您的賬號予以查封的</p>
<p class="font_content">3除上述情形外因用户多次違反我方平枱規則相關規定且情節嚴重我方依據我方平枱規則對您的賬户予以查封的</p>
<p class="font_content">4用户在我方平枱有侵犯他人合法權益或其他嚴重違法違約行爲的</p>
<p class="font_content">5其它根據相關法律法規我方應當終止服務的情況。</p>
<p class="font_subtitle">
第七條 不可抗力及免責
</p>
<p class="font_content">7.1 由於不可抗力,如戰爭、電力故障,罷工,暴亂、自然灾害等,鑒於互聯網的特殊性,不可抗力還包括黑客攻擊、運營商網絡通訊中斷及其他非因加速器過錯產生的係統故障等導緻本協議不能履行的,加速器均無需承擔違約責任。</p>
<p class="font_content">7.2 如政府、司法行政機關等相關管理部門提齣要求,暫停或終止提供相應服務,加速器不承擔任何責任。</p>
<p class="font_subtitle">
第八條 爭議解決
</p>
<p class="font_content">8.1 所有因本協議引起的或與本協議有關的爭議,本着互讓互利的原則,通過協商解決。協商不成的,雙方也可請求有管轄權的人民法院對所爭議的事項做齣裁決。</p>
<p class="font_subtitle">
第九條 用户服務協議變更
</p>
<p class="font_content">9.1 加速器更新用户服務協議、隱私權政策及相關平枱規則(統稱“服務協議”),屆時協議更新會通過官網提示、短信推送或客户端公告等方式通知和提醒用户注意。 服務協議變更後,若用户繼續使用加速器服務,即錶示用户同意接受加速器更新後的服務協議。若用户不同意變更後的服務協議,請用户停止使用加速器服務。</p>
<p class="font_subtitle">
第十條 附則
</p>
<p class="font_content">10.1 本協議自訂立、生效、解釋、修訂、補充、終止、執行與爭議解決均適用中華人民共和國法律;如法律無相關規定的,參照商業慣例及/或行業慣例;</p>
<p class="font_content">10.2 加速器保留因技術進步或國傢政策變動等原因對服務做齣調整的權利,但調整時應提前告知用户并提供相應解決方案;</p>
<p class="font_content">10.3 加速器可以采用電話、互聯網等渠道進行業務公告或業務通知;</p>
<p class="font_content">10.4 用户下載并注冊加速器客户端時即錶示已默認同意本服務協議,此服務協議自用户注冊之日起生效;</p>
<p class="font_content">10.5 本協議任一條款被視爲廢止、無效或不可執行,該條應視爲可分的且并不影響本協議其餘條款的有效性及可執行性。</p><br/>
</body>
</html>

View File

@ -0,0 +1,109 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<meta name="data-spm" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<!--1.在引入阿里云验证码JS脚本的位置之前或者在html的head标签最前的位置添加一个script脚本里面保存一个含有region和prefix参数的全局变量AliyunCaptchaConfig即可-->
<script>
window.AliyunCaptchaConfig = {
// 必填验证码示例所属地区支持中国内地cn、新加坡sgp
region: "cn",
// 必填身份标。开通阿里云验证码2.0后,您可以在控制台概览页面的实例基本信息卡片区域,获取身份标
prefix: "hjj2nk",
};
</script>
<!--2.集成主JS-->
<script type="text/javascript" src="https://o.alicdn.com/captcha-frontend/aliyunCaptcha/AliyunCaptcha.js">
</script>
</head>
<style>
.spinner {
border: 6px solid #f3f3f3;
border-top: 6px solid #3498db;
border-radius: 50%;
width: 40px;
height: 40px;
animation: spin 1s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
</style>
<body>
<div style="display: flex; flex-direction: column; justify-content: center; align-items: center; min-height: 100vh">
<div style="font-size: 22px; font-weight: bold;">快速注册</div>
<div id="loading" style="margin-bottom: 20px;">
<div class="spinner"></div>
</div>
<div id="captcha-element"></div>
<div style="font-size: 16px; ">滑动完成注册</div>
</div>
<!--3.新建一个<script>标签用于调用验证码初始化函数initAliyunCaptcha-->
<script type="text/javascript">
var captcha;
// 弹出式除region和prefix以外的参数
window.initAliyunCaptcha({
// 场景ID。根据步骤二新建验证场景后您可以在验证码场景列表获取该场景的场景ID
SceneId: '14psrdp3',
// 验证码模式。popup表示要集成的验证码模式为弹出式。无需修改
mode: 'embed',
//页面上预留的渲染验证码的元素,与原代码中预留的页面元素保持一致。
element: '#captcha-element',
// 触发验证码弹窗的元素。button表示单击登录按钮后触发captchaVerifyCallback函数。您可以根据实际使用的元素修改element的值
button: '#button',
// 业务请求(带验证码校验)回调函数,无需修改
captchaVerifyCallback: captchaVerifyCallback,
// 业务请求结果回调函数,无需修改
onBizResultCallback: onBizResultCallback,
// 绑定验证码实例函数,无需修改
getInstance: getInstance,
// 滑块验证码样式支持自定义宽度和高度单位为px。其中width最小值为320 px
slideStyle: {
width: 360,
height: 40,
},
// 验证码语言类型支持简体中文cn、繁体中文tw、英文en
language: 'cn',
immediate: true
});
function getInstance(instance) {
captcha = instance
}
async function captchaVerifyCallback(captchaVerifyParam) {
const result = window.CaptchaJsInterface.getVerifyResult(captchaVerifyParam);
const verifyResult = {
captchaResult: result, // 验证码验证是否通过boolean类型必选
bizResult: result, // 业务验证是否通过boolean类型可选若为无业务验证结果的场景bizResult可以为空
};
return verifyResult;
}
// 业务请求验证结果回调函数
function onBizResultCallback(bizResult) {
}
const captchaElement = document.getElementById("captcha-element");
const loading = document.getElementById("loading");
const observer = new MutationObserver((mutationsList, observer) => {
// 如果 captcha-element 有子节点,就说明它已经被渲染
if (captchaElement.childNodes.length > 0) {
loading.style.display = "none"; // 隐藏 loading
observer.disconnect(); // 停止监听
}
});
// 开始监听 captcha-element 节点的子元素变化
observer.observe(captchaElement, { childList: true, subtree: true });
</script>
</body>
</html>

View File

@ -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" -> {

View File

@ -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) {

View File

@ -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);
}

View File

@ -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
}

View File

@ -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

View File

@ -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<String>()
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<Bitmap>(){
.into(object : SimpleTarget<Bitmap>() {
override fun onResourceReady(
resource: Bitmap,
transition: Transition<in Bitmap>?
transition: Transition<in Bitmap>?,
) {
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)
)
)
}
}
})
}
}

View File

@ -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) {

View File

@ -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()
}
}
}
}

View File

@ -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/"

View File

@ -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()) {

View File

@ -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)

View File

@ -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<String, String>): Call<LoginRsp2>
fun login2(@QueryMap params: Map<String, String>): Call<LoginRsp2>
//检查登录 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<String, String>): RegisterRsp
suspend fun encryptionRegister(
@Body requestBody: RequestBody,
): RegisterRsp
//显示赠送时长
@Headers(
@ -147,7 +153,7 @@ interface HttpApi {
@QueryMap params: Map<String, String>,
@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<String, String>,
@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<String, String>,
@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<String, String>,
@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<String, String>,
@Header("token") string: String = MMKV.defaultMMKV().decodeString(
BZYConstants.MMKV_KEY_TOKEN
).toString()
).toString(),
): PayRsp
@ -306,7 +340,7 @@ interface HttpApi {
@QueryMap params: HashMap<String, String?>,
@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<String, String>,
@Header("token") string: String = MMKV.defaultMMKV().decodeString(
BZYConstants.MMKV_KEY_TOKEN
).toString()
).toString(),
): NormalRsp
//汇旺财二维码支付
@ -330,7 +364,7 @@ interface HttpApi {
@QueryMap params: Map<String, String>,
@Header("token") string: String = MMKV.defaultMMKV().decodeString(
BZYConstants.MMKV_KEY_TOKEN
).toString()
).toString(),
): QRPayRsp
//汇旺财二维码支付结果
@ -342,7 +376,7 @@ interface HttpApi {
@QueryMap params: Map<String, String>,
@Header("token") string: String = MMKV.defaultMMKV().decodeString(
BZYConstants.MMKV_KEY_TOKEN
).toString()
).toString(),
): QRPayStatusRsp
@ -355,7 +389,7 @@ interface HttpApi {
@QueryMap params: Map<String, String>,
@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<String, String>,
@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<String, String>,
@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<String, String>,
@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<String, String>,
@Header("token") string: String = MMKV.defaultMMKV().decodeString(
BZYConstants.MMKV_KEY_TOKEN
).toString()
).toString(),
): NormalMessageRsp
@Headers(
@ -414,7 +448,7 @@ interface HttpApi {
@QueryMap params: Map<String, String>,
@Header("token") string: String = MMKV.defaultMMKV().decodeString(
BZYConstants.MMKV_KEY_TOKEN
).toString()
).toString(),
): BiLaiNormalRsp
@Headers(
@ -425,7 +459,7 @@ interface HttpApi {
@QueryMap params: Map<String, String>,
@Header("token") string: String = MMKV.defaultMMKV().decodeString(
BZYConstants.MMKV_KEY_TOKEN
).toString()
).toString(),
): BiLaiNormalRsp
@Headers(
@ -436,7 +470,7 @@ interface HttpApi {
@QueryMap params: Map<String, String>,
@Header("token") string: String = MMKV.defaultMMKV().decodeString(
BZYConstants.MMKV_KEY_TOKEN
).toString()
).toString(),
): PhDownloadUrlRsp
@Headers(
@ -447,7 +481,7 @@ interface HttpApi {
@QueryMap params: Map<String, String>,
@Header("token") string: String = MMKV.defaultMMKV().decodeString(
BZYConstants.MMKV_KEY_TOKEN
).toString()
).toString(),
): BiLaiPayStatusRsp
@ -459,7 +493,7 @@ interface HttpApi {
@QueryMap params: Map<String, String>,
@Header("token") string: String = MMKV.defaultMMKV().decodeString(
BZYConstants.MMKV_KEY_TOKEN
).toString()
).toString(),
): SubscriptionRsp
//网页支付统一订单查询
@ -471,7 +505,7 @@ interface HttpApi {
@QueryMap params: Map<String, String>,
@Header("token") string: String = MMKV.defaultMMKV().decodeString(
BZYConstants.MMKV_KEY_TOKEN
).toString()
).toString(),
): NormalMessageRsp
@Headers(
@ -482,7 +516,7 @@ interface HttpApi {
@QueryMap params: Map<String, String>,
@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<String, String>
@QueryMap params: Map<String, String>,
): AppVersionCheckRsp
//忘记密码
@ -511,7 +545,7 @@ interface HttpApi {
@QueryMap params: Map<String, String>,
@Header("token") string: String = MMKV.defaultMMKV().decodeString(
BZYConstants.MMKV_KEY_TOKEN
).toString()
).toString(),
): SendSmsRsp
//会员签到
@ -523,7 +557,7 @@ interface HttpApi {
@QueryMap params: Map<String, String>,
@Header("token") string: String = MMKV.defaultMMKV().decodeString(
BZYConstants.MMKV_KEY_TOKEN
).toString()
).toString(),
): VipSignRsp
//会员签到
@ -535,7 +569,7 @@ interface HttpApi {
@QueryMap params: Map<String, String>,
@Header("token") string: String = MMKV.defaultMMKV().decodeString(
BZYConstants.MMKV_KEY_TOKEN
).toString()
).toString(),
): GetActivityRsp
//获取阿里云上传数据
@ -547,7 +581,7 @@ interface HttpApi {
@QueryMap params: Map<String, String>,
@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<String, String>,
@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
}

View File

@ -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 {

View File

@ -254,32 +254,7 @@ object Utils {
}
}
fun getIPAddress(): String {
try {
val en: Enumeration<NetworkInterface> = NetworkInterface.getNetworkInterfaces()
while (en.hasMoreElements()) {
val intf: NetworkInterface = en.nextElement()
val enumIpAddr: Enumeration<InetAddress> = 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 {

View File

@ -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()
}
}

View File

@ -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 =

View File

@ -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<String, String>) {
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)
}
}

View File

@ -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()
}
}
}

View File

@ -0,0 +1,93 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="@drawable/activity_bg"
android:gravity="center"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_percent="0.8"
tools:ignore="MissingConstraints">
<TextView
android:id="@+id/tv_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:layout_marginBottom="10dp"
android:gravity="center"
android:text="用户协议与隐私政策说明"
android:textColor="@color/blue_4072FE"
android:textSize="16sp"
android:textStyle="bold" />
<LinearLayout
android:id="@+id/rg_pay_type"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="15dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:orientation="vertical">
<TextView
android:id="@+id/dialog_agreement_info"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</TextView>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_margin="15dp"
android:layout_height="wrap_content">
<TextView
android:id="@+id/but_cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/activity_close_bg"
android:layout_weight="1"
android:gravity="center"
android:paddingTop="5dp"
android:textSize="12sp"
android:layout_marginStart="@dimen/dp_15"
android:layout_marginEnd="@dimen/dp_15"
android:paddingBottom="5dp"
android:text="@string/disagree">
</TextView>
<TextView
android:id="@+id/but_agree"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/activity_jump_bg"
android:textSize="14sp"
android:layout_weight="1"
android:textStyle="bold"
android:gravity="center"
android:text="@string/agree"
android:paddingTop="5dp"
android:paddingBottom="5dp">
</TextView>
</LinearLayout>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -1,19 +1,77 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/rlMain"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/splash_background"
tools:context=".act.SplashActivity"
android:id="@+id/rlMain"
>
tools:context=".act.SplashActivity">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</TextView>
<WebView
android:id="@+id/webView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/main_bg"
android:visibility="invisible" />
<ProgressBar
android:id="@+id/pb_web"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:indeterminateTint="@color/blue_0136CB"
android:visibility="invisible" />
<LinearLayout
android:layout_alignParentBottom="true"
android:layout_centerInParent="true"
android:layout_marginBottom="@dimen/dp_40"
android:layout_marginLeft="@dimen/dp_15"
android:layout_marginRight="@dimen/dp_15"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:id="@+id/but_skip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="@dimen/dp_15"
android:layout_weight="1"
android:background="@drawable/login_btn_bg_selector"
android:text="@string/skip"
android:visibility="invisible">
</Button>
<Button
android:id="@+id/but_register"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@drawable/login_btn_bg_selector"
android:text="@string/email_or_phone_register"
android:visibility="invisible">
</Button>
</LinearLayout>
</RelativeLayout>
<LinearLayout
android:visibility="gone"
android:id="@+id/ll_action"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -23,7 +81,7 @@
android:layout_marginRight="@dimen/dp_10"
android:layout_marginBottom="50dp"
android:orientation="horizontal"
>
android:visibility="gone">
<RelativeLayout
android:id="@+id/rl_action_login"
@ -32,10 +90,10 @@
android:layout_weight="1">
<ImageView
android:layout_centerHorizontal="true"
android:id="@+id/iv_login"
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_centerHorizontal="true"
android:src="@mipmap/action_login" />
<TextView
@ -53,11 +111,11 @@
</RelativeLayout>
<RelativeLayout
android:visibility="gone"
android:id="@+id/rl_action_register"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1">
android:layout_weight="1"
android:visibility="gone">
<ImageView
android:id="@+id/iv_register"
@ -101,8 +159,8 @@
android:layout_below="@id/pb"
android:layout_marginTop="5dp"
android:text="@string/LoadingProgress"
android:textSize="15sp"
android:textColor="@color/blue_0136CB" />
android:textColor="@color/blue_0136CB"
android:textSize="15sp" />
</RelativeLayout>
</RelativeLayout>

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 688 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 380 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 962 B

View File

@ -4,6 +4,7 @@
<string name="app_name_gz">影猫</string>
<string name="app_name_gz2">影猫加速器</string>
<string name="app_name_taizi">太子</string>
<string name="app_name_yunti">云梯加速器</string>
<string name="file">file</string>
<string name="rule">rule</string>
<string name="proxy">proxy</string>
@ -351,5 +352,10 @@ Service Description\n
<string name="sure_restart">Suggest restarting</string>
<string name="restart">Restart</string>
<string name="node_item_test">Speed test</string>
<string name="agree">Agree</string>
<string name="disagree">Disagree</string>
<string name="skip">Go to login</string>
<string name="email_or_phone_register">Email registration</string>
<string name="CZHY">Recharge Membership</string>
</resources>

View File

@ -338,8 +338,15 @@
<string name="everyDay">每天</string>
<string name="PopularApplications">熱門應用</string>
<string name="PopularApplicationsStr">熱門應用導航</string>
<string name="sure_restart">"建議重啓 "</string>
<string name="restart">"重啓 "</string>
<string name="sure_restart">"建議重啓"</string>
<string name="restart">"重啓"</string>
<string name="node_item_test">線路測速</string>
<string name="agree">同意</string>
<string name="disagree">不同意</string>
<string name="skip">直接登入</string>
<string name="app_name_yunti">雲梯加速器</string>
<string name="email_or_phone_register">手動注册</string>
<string name="CZHY">充值會員</string>
</resources>

View File

@ -337,8 +337,14 @@
<string name="everyDay">每天</string>
<string name="PopularApplications">熱門應用</string>
<string name="PopularApplicationsStr">熱門應用導航</string>
<string name="sure_restart">"建議重啓 "</string>
<string name="restart">"重啓 "</string>
<string name="sure_restart">"建議重啓"</string>
<string name="restart">"重啓"</string>
<string name="node_item_test">線路測速</string>
<string name="agree">同意</string>
<string name="disagree">不同意</string>
<string name="skip">直接登入</string>
<string name="app_name_yunti">雲梯加速器</string>
<string name="email_or_phone_register">手動注册</string>
<string name="CZHY">充值會員</string>
</resources>

View File

@ -131,6 +131,7 @@
<string name="CheckLoginFailure">检查登录失败</string>
<string name="LoginException">登录异常</string>
<string name="AgreeAgreement">同意《隐私协议》和《用户协议》</string>
<string name="AgreeAgreement2">请您充分阅读并理解《隐私政策》和《用户协议》我们非常重视您的隐私和个人信息,在您使用过程中,我们会收集部分个人信息。例如,会申请设备信息等。您可以点击《用户协议》和《隐私政策》查看详细内容。您可以选择“同意”继续使用我们的服务,或者选择“不同意”退出。</string>
<string name="ReadAgreement">请仔细阅读并同意《隐私协议》和《用户协议》</string>
<string name="loginTips">小提示:自动注册初始密码为 123456手动注册请忽略</string>
<string name="LoginTips2">小提示2华为鸿蒙系统由于鉴定机制的问题将App误报为诈骗软件请忽略正常放心使用有任何问题联系客服及售后</string>
@ -359,6 +360,14 @@
<string name="sure_restart">建议重启</string>
<string name="restart">重启</string>
<string name="node_item_test">线路测速</string>
<string name="agree">同意</string>
<string name="disagree">不同意</string>
<string name="skip">直接登录</string>
<string name="app_name_yunti">云梯加速器</string>
<string name="email_or_phone_register">手动注册</string>
<string name="CZHY">充值会员</string>