auto.waitFor();
threads.start(function(){
// 悬浮窗权限
requestFloaty();
});

// =全局变量(悬浮窗可改)
var clickX = 540;
var clickY = 1600;
var isRun = false; //启停开关
// =====================================

// 延时参数 可自己改
const t_clickWait = 1200;
const t_payWait = 1500;
const t_backWait = 1000;

// --------创建悬浮窗布局--------
let w = floaty.rawWindow(
<frame bg="#CC000000" w="280" h="180">
<vertical padding="10">
<text text="支付脚本控制台" textSize="16" color="#ffffff" gravity="center"/>
<button id="btnStart" text="开始运行" marginTop="8"/>
<button id="btnPause" text="暂停脚本" marginTop="5"/>
<button id="btnSetXY" text="修改第一步点击坐标" marginTop="5"/>
</vertical>
</frame>
);

//悬浮窗可拖动
w.setPosition(100, 300);
w.exitOnClose();

// --------按钮绑定事件--------
//开始
w.btnStart.click(()=>{
isRun = true;
toast("✅脚本已启动");
});

//暂停
w.btnPause.click(()=>{
isRun = false;
toast("⏸脚本已暂停");
});

//弹窗改XY坐标
w.btnSetXY.click(()=>{
let x = dialogs.input("输入新X坐标", String(clickX));
if(x === null) return;
let y = dialogs.input("输入新Y坐标", String(clickY));
if(y === null) return;

clickX = parseInt(x) || clickX;
clickY = parseInt(y) || clickY;
toast("✅坐标已更新:"+clickX+" , "+clickY);

});

// --------主循环逻辑--------
function mainLoop(){
while(true){
//暂停就卡住
while(!isRun){
sleep(300);
}

    console.log("————本轮开始,点击坐标:",clickX,clickY);
    click(clickX, clickY);
    sleep(t_clickWait);

    //识别立即支付
    if(text("立即支付").waitFor(2000)){
        toast("💰识别到立即支付,自动点击");
        text("立即支付").click();
        sleep(t_payWait);
    }else{
        toast("❌未找到,返回上一页");
        back();
        sleep(t_backWait);
    }

    sleep(800);
}

}

//启动任务线程
threads.start(mainLoop);我这个脚本有什么问题

jm4v9u9s4b · 9 小时前

回答

Hamibot AI
1
· 9 小时前

脚本存在语法兼容性、API 使用错误及稳定性风险,会导致脚本无法运行或崩溃。主要问题如下:

  1. 语法兼容性错误
    Hamibot 脚本引擎基于 Rhino 1.7.15,不支持 ES6 箭头函数 ()=>。代码中多处使用箭头函数(如 w.btnStart.click(()=>{...})),这会直接导致语法错误,脚本无法启动。必须使用传统 function() 写法。

  2. API 函数不存在
    requestFloaty() 不是 Hamibot 标准 API 函数。悬浮窗权限需要在手机系统设置中手动授予,或通过代码检查权限状态。调用不存在的函数会抛出 ReferenceError

  3. 悬浮窗生命周期问题
    虽然使用了 threads.start 保持脚本运行,但为了确保悬浮窗不被系统意外回收,建议按照最佳实践添加空 setInterval 保活。

  4. 线程变量可见性风险
    isRun 变量在主线程和子线程间共享。在 Rhino 引擎中,普通变量在线程间可能存在可见性问题。建议增加日志或使用更明确的控制逻辑。

  5. 权限检查缺失
    脚本未检查悬浮窗权限是否已授予。如果未授权,floaty.rawWindow 创建时会崩溃。

以下是修复后的代码及优化建议:

// 文档地址 https://docs.hamibot.com/
auto.waitFor();

// =========全局变量=========
var clickX = 540;
var clickY = 1600;
var isRun = false;
// =========================

// 延时参数
const t_clickWait = 1200;
const t_payWait = 1500;
const t_backWait = 1000;

// 检查悬浮窗权限
if (!android.provider.Settings.canDrawOverlays(context)) {
    toastLog("未获得悬浮窗权限,请在设置中开启");
    // app.startActivity({ action: "android.settings.action_MANAGE_OVERLAY_PERMISSION" }); // 可选:尝试跳转设置
    stop();
}

// --------创建悬浮窗布局--------
let w = floaty.rawWindow(
    <frame bg="#CC000000" w="280" h="180">
        <vertical padding="10">
            <text text="支付脚本控制台" textSize="16" color="#ffffff" gravity="center"/>
            <button id="btnStart" text="开始运行" marginTop="8"/>
            <button id="btnPause" text="暂停脚本" marginTop="5"/>
            <button id="btnSetXY" text="修改第一步点击坐标" marginTop="5"/>
        </vertical>
    </frame>
);

w.setPosition(100, 300);
w.exitOnClose();

// --------按钮绑定事件 (使用 function 替代箭头函数)--------
w.btnStart.click(function () {
    isRun = true;
    toast("✅脚本已启动");
});

w.btnPause.click(function () {
    isRun = false;
    toast("⏸脚本已暂停");
});

w.btnSetXY.click(function () {
    let x = dialogs.input("输入新 X 坐标", String(clickX));
    if (x === null) return;
    let y = dialogs.input("输入新 Y 坐标", String(clickY));
    if (y === null) return;

    clickX = parseInt(x) || clickX;
    clickY = parseInt(y) || clickY;
    toast("✅坐标已更新:" + clickX + " , " + clickY);
});

// --------主循环逻辑--------
function mainLoop() {
    while (true) {
        // 暂停等待
        while (!isRun) {
            sleep(300);
        }

        console.log("————本轮开始,点击坐标:", clickX, clickY);
        click(clickX, clickY);
        sleep(t_clickWait);

        // 识别立即支付
        if (text("立即支付").waitFor(2000)) {
            toast("💰识别到立即支付,自动点击");
            text("立即支付").click();
            sleep(t_payWait);
        } else {
            toast("❌未找到,返回上一页");
            back();
            sleep(t_backWait);
        }

        sleep(800);
    }
}

// 启动任务线程
threads.start(mainLoop);

// 保持悬浮窗不被关闭 (保活)
setInterval(function () {}, 1000);

优化建议:

  1. 权限管理:确保在手机设置中授予 Hamibot「悬浮窗权限」和「无障碍服务」。
  2. 线程安全:脚本停止时,建议调用 threads.shutDownAll() 清理残留线程,避免影响下次运行。
  3. 元素定位text("立即支付") 依赖具体文本,如果 APP 版本更新导致文本变化,脚本会失效。建议使用 iddesc 定位,或通过「布局分析」工具获取更稳定的特征。
  4. 异常处理:建议在 mainLoop 外层包裹 try...catch,防止单次错误导致整个脚本崩溃退出。
ℹ️ 本回答由 AI 生成,内容仅供参考