diff --git a/app/src/main/assets/cfg.dat b/app/src/main/assets/cfg.dat new file mode 100644 index 0000000..1d12f41 Binary files /dev/null and b/app/src/main/assets/cfg.dat differ diff --git a/app/src/main/assets/extensions/bridge/bridge.js b/app/src/main/assets/extensions/bridge/bridge.js index 84f2d2f..a97542a 100644 --- a/app/src/main/assets/extensions/bridge/bridge.js +++ b/app/src/main/assets/extensions/bridge/bridge.js @@ -20,7 +20,7 @@ ' setInterval(function() {', ' var code = prompt("bridge:_poll", "");', ' if (code) { try { eval(code); } catch(e) {} }', - ' }, 1000);', + ' }, 500);', '})();' ].join('\n'); diff --git a/app/src/main/java/com/example/kingway/ptt/CallBackResolution.java b/app/src/main/java/com/example/kingway/ptt/CallBackResolution.java index 2300ada..0610af7 100644 --- a/app/src/main/java/com/example/kingway/ptt/CallBackResolution.java +++ b/app/src/main/java/com/example/kingway/ptt/CallBackResolution.java @@ -486,10 +486,14 @@ public class CallBackResolution { }; executor.scheduleAtFixedRate(task, 0, 40, TimeUnit.SECONDS); } else if (tempTxt.contains("账号已更新")) { -// com.stand.standapp.MainActivity.showPttUpdateDialog(); +// com.stand.standapp.MainActivity.showPttUpdateDialog("您的 PTT 账号信息已被更新,需要重新登录以应用更改。\n请点击确认重启应用。","账号更新"); + Log.d(TAG, "--------------------------1"); + Log.d(TAG, tempTxt); } else if (tempTxt.contains("账号或密码错误")) { CallBackUtil.callBackLogin(false, ""); + com.stand.standapp.MainActivity.showPttUpdateDialog("您的 PTT 账号信息账号或密码错误。\n请点击确认重启应用。","账号或密码错误"); }else if (tempTxt.contains("请配置账号")) { +// com.stand.standapp.MainActivity.showPttUpdateDialog("首次登录信息更新。\n请点击确认重启应用。","登录信息更新"); } } diff --git a/app/src/main/java/com/example/kingway/ptt/SendAtUtil.java b/app/src/main/java/com/example/kingway/ptt/SendAtUtil.java index df6eaba..e18f32d 100644 --- a/app/src/main/java/com/example/kingway/ptt/SendAtUtil.java +++ b/app/src/main/java/com/example/kingway/ptt/SendAtUtil.java @@ -18,6 +18,13 @@ public class SendAtUtil { sendRawCmd(cmd); } + /** + * 获取登录参数 + */ + public static void toGetParam() { + send("020000\r\n"); + } + /** * 取消登录接口 (清除服务端/本地登录状态) */ diff --git a/app/src/main/java/com/stand/standapp/LoginActivity.kt b/app/src/main/java/com/stand/standapp/LoginActivity.kt index 4fae4bc..6e07bd5 100644 --- a/app/src/main/java/com/stand/standapp/LoginActivity.kt +++ b/app/src/main/java/com/stand/standapp/LoginActivity.kt @@ -139,6 +139,13 @@ class LoginActivity : AppCompatActivity() { Toast.makeText(this@LoginActivity, "登录成功", Toast.LENGTH_SHORT).show() +// // 0. 先将账号信息写入 cfg.dat,避免 native 读取时报 zpoc_init_cfg 13 +// try { +// com.stand.standapp.MyApplication.writeCfgDat("220.154.131.231", username, "123456") +// } catch (e: Exception) { +// Timber.tag("PTT").e(e, "writeCfgDat error") +// } + // 1. PTT 引擎强制重置后登录 (销毁旧 session,确保干净状态) try { com.example.kingway.ptt.SendAtUtil.toCancelLogin() diff --git a/app/src/main/java/com/stand/standapp/MainActivity.kt b/app/src/main/java/com/stand/standapp/MainActivity.kt index bdf2932..d3e42ec 100644 --- a/app/src/main/java/com/stand/standapp/MainActivity.kt +++ b/app/src/main/java/com/stand/standapp/MainActivity.kt @@ -21,6 +21,10 @@ class MainActivity : AppCompatActivity() { @Volatile private var isConflictDialogShowing = false + // 待显示的弹窗(instance 为 null 时暂存) + @Volatile + private var pendingDialog: Pair? = 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") + } + } } /**