From ba37d3365ea294c52954caaa8718ff163774d0e2 Mon Sep 17 00:00:00 2001 From: "844143714@qq,com" <844143714@qq,com> Date: Thu, 7 May 2026 14:50:19 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/assets/cfg.dat | Bin 0 -> 240 bytes .../main/assets/extensions/bridge/bridge.js | 2 +- .../kingway/ptt/CallBackResolution.java | 6 ++- .../com/example/kingway/ptt/SendAtUtil.java | 7 +++ .../java/com/stand/standapp/LoginActivity.kt | 7 +++ .../java/com/stand/standapp/MainActivity.kt | 28 ++++++++--- .../java/com/stand/standapp/MyApplication.kt | 45 ++++++++++++++++++ 7 files changed, 87 insertions(+), 8 deletions(-) create mode 100644 app/src/main/assets/cfg.dat diff --git a/app/src/main/assets/cfg.dat b/app/src/main/assets/cfg.dat new file mode 100644 index 0000000000000000000000000000000000000000..1d12f417a1530b4e0362c5465258edabcdaef91f GIT binary patch literal 240 zcmXpqGSD+LHPJIPHq? = null + // 待执行的 JS 代码(由 bridge.js 轮询获取) @Volatile private var pendingJsCode: String? = null @@ -75,14 +79,18 @@ class MainActivity : AppCompatActivity() { } @JvmStatic - fun showPttUpdateDialog() { + fun showPttUpdateDialog(msg: String, title: String) { if (isConflictDialogShowing) return + val ctx = instance + if (ctx == null) { + pendingDialog = title to msg + return + } isConflictDialogShowing = true - instance?.runOnUiThread { - val ctx = instance ?: return@runOnUiThread + ctx.runOnUiThread { androidx.appcompat.app.AlertDialog.Builder(ctx) - .setTitle("账号更新") - .setMessage("您的 PTT 账号信息已被更新,需要重新登录以应用更改。\n请点击确认重启应用。") + .setTitle(title) + .setMessage(msg) .setCancelable(false) .setPositiveButton("确认") { _, _ -> com.stand.standapp.utils.AppKiller.killApp(ctx, restart = true) @@ -92,6 +100,13 @@ class MainActivity : AppCompatActivity() { } } + @JvmStatic + fun showPendingDialogIfNeeded() { + val pending = pendingDialog ?: return + pendingDialog = null + showPttUpdateDialog(pending.second, pending.first) + } + // 获取并清除待执行的 JS 代码(由 bridge.js 轮询) @JvmStatic fun pollPendingJs(): String { @@ -110,7 +125,7 @@ class MainActivity : AppCompatActivity() { private lateinit var geckoView: GeckoView private val mHandler = android.os.Handler(android.os.Looper.getMainLooper()) - private val TIMEOUT_MS = 30000L + private val TIMEOUT_MS = 10000L private val timeoutRunnable = Runnable { showErrorPage() @@ -119,6 +134,7 @@ class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) instance = this + showPendingDialogIfNeeded() try { setContentView(R.layout.activity_main) diff --git a/app/src/main/java/com/stand/standapp/MyApplication.kt b/app/src/main/java/com/stand/standapp/MyApplication.kt index 478a5e3..ea03c70 100644 --- a/app/src/main/java/com/stand/standapp/MyApplication.kt +++ b/app/src/main/java/com/stand/standapp/MyApplication.kt @@ -2,9 +2,11 @@ package com.stand.standapp import android.app.Application import android.util.Log +import com.example.kingway.ptt.SendAtUtil import com.example.kingway.ptt.pttNative import com.stand.standapp.utils.LogManager import timber.log.Timber +import java.io.File class MyApplication : Application() { @@ -23,6 +25,7 @@ class MyApplication : Application() { @JvmStatic fun initPTT() { if (pNative != null) return + ensureCfgDat() try { pNative = pttNative() @@ -44,6 +47,48 @@ class MyApplication : Application() { var pageName: String = "" var pNative: pttNative? = null + + /** + * 首次安装时从 assets 复制一份有效的 cfg.dat, + * 避免 native 读不到配置报 zpoc_init_cfg 13。 + */ + private fun ensureCfgDat() { + try { + val cfgFile = File("/data/data/$pageName/cfg.dat") + if (cfgFile.exists()) return + val app = mApp + app.assets.open("cfg.dat").use { input -> + cfgFile.outputStream().use { output -> + input.copyTo(output) + } + } + Timber.tag("PTT_INIT").i("Copied cfg.dat from assets") + } catch (e: Exception) { + Timber.tag("PTT_INIT").w(e, "Failed to copy cfg.dat from assets") + } + } + + /** + * 登录成功后将真实账号信息覆盖写入 cfg.dat + */ + @JvmStatic + fun writeCfgDat(ip: String, account: String, password: String) { + try { + val cfgFile = File("/data/data/$pageName/cfg.dat") + val data = ByteArray(240) + ip.toByteArray().copyInto(data, 0) + account.toByteArray().copyInto(data, 0x10) + password.toByteArray().copyInto(data, 0x20) + "GPSON".toByteArray().copyInto(data, 0x30) + data[0xE1] = 0x01 + data[0xEA] = 0x3F + data[0xEB] = 0x3F + cfgFile.writeBytes(data) + Timber.tag("PTT_INIT").i("writeCfgDat done: ip=$ip, account=$account") + } catch (e: Exception) { + Timber.tag("PTT_INIT").w(e, "writeCfgDat failed") + } + } } /**