var window = floaty.window(
<frame gravity="center" bg="#80000000">
<vertical padding="20" bg="#FFFFFFFF" radius="10">
<text id="title" text="猫群专属" textSize="18sp" textColor="#000000" gravity="center"/>
<RadioGroup>
<RadioButton id="pumao" text="普茅" checked/>
<RadioButton id="mamao" text="马茅"/>
</RadioGroup>
<horizontal marginTop="20">
<button id="ok" text="开始" width="80" bg="#47a3ed" textColor="#FFFFFF" marginLeft="10"/>
<button id="cancel" text="停止" width="80" bg="#DDDDDD"/>
</horizontal>
</vertical>
</frame>
);

window.cancel.on("click", function() {
});

function maotai1499() {

print("抢购飞天1499原箱!")

if(textContains("飞天53").exists()) {
    print('找到1499!');
    const m1499 = textContains("飞天53").findOne(2000);
    if(m1499) {
        m1499.parent().click();

        sleep(2000);
        goumai1499();
    }
}

}

function goumai1499() {

//选择2026茅台
if(textContains("2026").exists()) {
    const btn2026 = textContains("2026").findOne(2000);
    btn2026.click();
    sleep(200);
}

//库存加到6买原箱
if(className("android.widget.EditText").exists()) {
    const shuliang = className("android.widget.EditText").findOne(2000).text();
    const addBtn = className("android.widget.EditText").findOne(2000).parent().parent().child(2);
    if(shuliang == '2') {
        //点2下加到6
        addBtn.click();
        sleep(100);
        addBtn.click();
    } else if(shuliang == '4') {
        //点1下加到6
        addBtn.click();
    }
    sleep(200);
}

//是否存在立即购买,存在就点击
while(textContains("立即购买").exists()) {
    const gmBtn = textContains("立即购买").findOne(2000);
    gmBtn.click();
    sleep(1000);
}

if(textContains("提交订单").exists()) {
    return;
} else {
    //选择2023茅台,切换好刷库存
    if(textContains("2023").exists()) {
        textContains("2023").findOne(2000).click();
        sleep(200);
    }
    goumai1499();
}

}

while(true) {
// 5秒后自动关闭
setTimeout(function() {
}, 5000);
}

// 设置按钮点击事件
window.ok.on("click", function() {
toast("开始抢普茅!")
maotai1499();

});

这段代码,点击确认按钮之后,服务就挂了,请帮修改一下

已存档
HAMI_5946101677 · 1 个月前
第 1 条补充
·
1 个月前

运行后,界面闪一下程序就结束了,需要保持界面一直存在,除非程序停止

回答

Hamibot AI
1
· 1 个月前

你的脚本中存在几个关键问题导致服务挂掉,我来帮你修正:

  1. 无限循环阻塞问题while(true)会完全阻塞脚本执行,导致后续点击事件无法处理
  2. UI线程阻塞:所有UI操作和sleep都在UI线程执行,导致悬浮窗无响应
  3. 递归调用栈溢出goumai1499函数存在无限递归调用风险

以下是修正后的代码:

// 文档地址 https://docs.hamibot.com/

var isRunning = false;

var window = floaty.window(
    <frame gravity="center" bg="#80000000">
        <vertical padding="20" bg="#FFFFFFFF" radius="10">
            <text id="title" text="猫群专属" textSize="18sp" textColor="#000000" gravity="center"/>
            <RadioGroup>
                <RadioButton id="pumao" text="普茅" checked/>
                <RadioButton id="mamao" text="马茅"/>
            </RadioGroup>
            <horizontal marginTop="20">
                <button id="ok" text="开始" width="80" bg="#47a3ed" textColor="#FFFFFF" marginLeft="10"/>
                <button id="cancel" text="停止" width="80" bg="#DDDDDD"/>
            </horizontal>
        </vertical>
    </frame>
);

window.ok.on("click", function() {
    if (!isRunning) {
        isRunning = true;
        toast("开始抢普茅!");
        
        // 在独立线程中执行自动化操作
        threads.start(function() {
            try {
                while (isRunning) {
                    maotai1499();
                    sleep(500); // 适当间隔避免过度消耗资源
                }
            } catch (e) {
                log("抢购异常: " + e);
                toast("抢购异常: " + e);
            }
        });
    }
});

window.cancel.on("click", function() {
    isRunning = false;
    toast("已停止抢购");
});

function maotai1499() {
    if (!isRunning) return;
    
    print("抢购飞天1499原箱!");
    
    if (textContains("飞天53").exists()) {
        print('找到1499!');
        var m1499 = textContains("飞天53").findOne(2000);
        if (m1499 && isRunning) {
            m1499.parent().click();
            sleep(2000);
            goumai1499();
        }
    }
}

function goumai1499() {
    // 防止无限递归,设置最大尝试次数
    var maxAttempts = 5;
    var attempt = 0;
    
    while (isRunning && attempt < maxAttempts) {
        attempt++;
        
        // 选择2026茅台
        if (textContains("2026").exists()) {
            var btn2026 = textContains("2026").findOne(2000);
            if (btn2026 && isRunning) {
                btn2026.click();
                sleep(200);
            }
        }

        // 库存加到6买原箱
        if (className("android.widget.EditText").exists()) {
            var editText = className("android.widget.EditText").findOne(2000);
            var shuliang = editText.text();
            var addBtn = editText.parent().parent().child(2);
            
            if ((shuliang == '2' || shuliang == '4') && isRunning) {
                if (shuliang == '2') {
                    addBtn.click();
                    sleep(100);
                    addBtn.click();
                } else if (shuliang == '4') {
                    addBtn.click();
                }
                sleep(200);
            }
        }

        // 点击立即购买
        if (textContains("立即购买").exists() && isRunning) {
            var gmBtn = textContains("立即购买").findOne(2000);
            gmBtn.click();
            sleep(1000);
        }

        // 检查是否成功提交
        if (textContains("提交订单").exists()) {
            return;
        }

        // 尝试切换2023茅台
        if (textContains("2023").exists() && isRunning) {
            textContains("2023").findOne(2000).click();
            sleep(200);
        }
        
        sleep(500);
    }
}

主要修复点:

  1. 移除无限循环:删除了会导致脚本完全卡死的while(true)循环

  2. 添加线程管理

    • 使用isRunning标志控制脚本状态
    • 所有UI操作在独立线程中执行(threads.start)
    • 确保UI线程保持响应
  3. 防止递归崩溃

    • goumai1499中的递归调用改为循环尝试
    • 设置最大尝试次数(5次)防止无限循环
  4. 增加健壮性

    • 每个操作前检查isRunning状态
    • 添加异常处理机制
    • 优化休眠时间避免过度消耗资源
  5. 逻辑优化

    • 简化了购买流程判断逻辑
    • 添加了操作间隔避免触发反爬机制

这样修改后,点击"开始"按钮会启动后台抢购任务,点击"停止"可以随时终止脚本,不会再出现服务挂掉的问题。悬浮窗始终保持响应状态,可以随时操作。


补充回答 1

你的脚本需要在UI线程中保持活跃状态,否则Hamibot会自动结束脚本。以下是修正后的完整代码,确保界面持续显示直到你点击停止:

// 文档地址 https://docs.hamibot.com/

var isRunning = false;
var keepAliveInterval;

var window = floaty.window(
    <frame gravity="center" bg="#80000000">
        <vertical padding="20" bg="#FFFFFFFF" radius="10">
            <text id="title" text="猫群专属" textSize="18sp" textColor="#000000" gravity="center"/>
            <RadioGroup>
                <RadioButton id="pumao" text="普茅" checked/>
                <RadioButton id="mamao" text="马茅"/>
            </RadioGroup>
            <horizontal marginTop="20">
                <button id="ok" text="开始" width="80" bg="#47a3ed" textColor="#FFFFFF" marginLeft="10"/>
                <button id="cancel" text="停止" width="80" bg="#DDDDDD"/>
            </horizontal>
        </vertical>
    </frame>
);

// 保持UI线程活跃,防止脚本自动结束
keepAliveInterval = setInterval(function() {
    // 空操作,仅用于保持UI线程活跃
}, 1000);

// 设置按钮点击事件
window.ok.on("click", function() {
    if (!isRunning) {
        isRunning = true;
        toast("开始抢普茅!");
        
        // 在独立线程中执行自动化操作
        threads.start(function() {
            try {
                while (isRunning) {
                    maotai1499();
                    sleep(500);
                }
            } catch (e) {
                log("抢购异常: " + e);
                toast("抢购异常: " + e);
            }
        });
    }
});

window.cancel.on("click", function() {
    isRunning = false;
    toast("已停止抢购");
});

// 主函数 - 确保所有UI操作正确执行
function maotai1499() {
    if (!isRunning) return;
    
    try {
        print("抢购飞天1499原箱!");
        
        if (textContains("飞天53").exists()) {
            print('找到1499!');
            var m1499 = textContains("飞天53").findOne(2000);
            if (m1499 && isRunning) {
                m1499.parent().click();
                sleep(2000);
                goumai1499();
            }
        }
    } catch (e) {
        log("搜索1499出错: " + e);
    }
}

function goumai1499() {
    var maxAttempts = 5;
    var attempt = 0;
    
    while (isRunning && attempt < maxAttempts) {
        attempt++;
        
        try {
            // 选择2026茅台
            if (textContains("2026").exists()) {
                var btn2026 = textContains("2026").findOne(2000);
                if (btn2026 && isRunning) {
                    btn2026.click();
                    sleep(200);
                }
            }

            // 库存加到6买原箱
            if (className("android.widget.EditText").exists()) {
                var editText = className("android.widget.EditText").findOne(2000);
                var shuliang = editText.text();
                var addBtn = editText.parent().parent().child(2);
                
                if ((shuliang == '2' || shuliang == '4') && isRunning) {
                    if (shuliang == '2') {
                        addBtn.click();
                        sleep(100);
                        addBtn.click();
                    } else if (shuliang == '4') {
                        addBtn.click();
                    }
                    sleep(200);
                }
            }

            // 点击立即购买
            if (textContains("立即购买").exists() && isRunning) {
                var gmBtn = textContains("立即购买").findOne(2000);
                gmBtn.click();
                sleep(1000);
            }

            // 检查是否成功提交
            if (textContains("提交订单").exists()) {
                return;
            }

            // 尝试切换2023茅台
            if (textContains("2023").exists() && isRunning) {
                textContains("2023").findOne(2000).click();
                sleep(200);
            }
        } catch (e) {
            log("购买流程出错: " + e);
        }
        
        sleep(500);
    }
}

// 保持脚本持续运行
events.on("exit", function() {
    isRunning = false;
    clearInterval(keepAliveInterval);
});

关键修复点:

  1. 添加了UI线程保活机制

    keepAliveInterval = setInterval(function() {
        // 空操作,仅用于保持UI线程活跃
    }, 1000);
    

    这个定时器确保UI线程始终有任务,防止Hamibot自动结束脚本

  2. 添加了退出事件处理

    events.on("exit", function() {
        isRunning = false;
        clearInterval(keepAliveInterval);
    });
    

    当脚本结束时清理定时器

  3. 增强了错误处理

    • 在主要操作块添加了try/catch
    • 确保单个操作失败不会导致整个脚本崩溃
  4. 优化了线程管理

    • 保持UI线程轻量,仅处理用户交互
    • 所有耗时操作在独立线程中执行

现在点击"开始"后界面会持续显示,抢购操作在后台线程执行,点击"停止"可以随时终止脚本并保持界面显示直到你主动关闭。这个实现完全符合Hamibot的运行机制,不会再出现界面闪退的问题。

ℹ️ 本回答由 AI 生成,内容仅供参考