///快手、快手极速版广告刷视频脚本
var errorbasestr1="必须实现";
var errorbasestr2="方法!";
const APP_TYPE=Object.freeze({
KS:200,
KSFAST:666
});
const ActionType=Object.freeze({
LOOKAD:0,
LOOKVIDEO:1
});
class UIOperatorUtils{
}
class BaseBehavior{
/*
看广告刷视频基础行为层面协定抽象类所有协定抽象方法如下 如需实现全部复制即可无需手动敲空方法提升效率
openRedPacketPage(){}
changeActionType(actionvalue){}
browsevideos(){}
browseHD(){}
*/
openRedPacketPage(){throw new Error(errorbasestr1+"openRedPacket"+errorbasestr2);}
changeActionType(actionvalue){throw new Error(errorbasestr1+"changeActionType"+errorbasestr2);}
browsevideos(){throw new Error(errorbasestr1+"browsevideos"+errorbasestr2);}
browseHD(){throw new Error(errorbasestr1+"browseHD"+errorbasestr2);}
checkParmsOfActionType(actionvalue){
//动态类型校验 必须是ActionType里的值
if(!Object.values(ActionType).includes(actionvalue)){
throw new Error('参数必须是 ActionType 枚举类型');
}
}
static checkParmsOfAPPTYPE(apptype){
if(!Object.values(APP_TYPE).includes(apptype)){
throw new Error('参数必须是 AppType 枚举类型');
}
}
static waitForAccessibilityGranted(){
auto.waitFor()
}
//脚本操作者对象明确后首先调用可以打印可toast之类 如需重写请注意千万不要在此方法实现操作和复杂逻辑逻辑这不符合此函数规范
startingSmallTask(){
setScreenMetrics(1080, 2340);
toast("开始打开快手红包");
}
};
// 快手操作者 - 单例
class KSOperator extends BaseBehavior {
// 单例实例
static instance=null;
#appPackageName="com.smile.gifmaker"
// 私有化构造(防止外部 new)
constructor() {
super()
}
// 获取单例
static getInstance() {
if (!this.instance) {
this.instance = new KSOperator();
}
return this.instance;
}
openRedPacketPage() {}
changeActionType(actionValue) {}
browsevideos() {}
browseHD() {}
}
class KSFastOperator extends BaseBehavior {
static instance=null;
#appPackageName="com.kuaishou.nebula"
constructor() {
super();
}
static getInstance(){
if (!this.instance) {
this.instance = new KSFastOperator();
}
return this.instance;
}
openRedPacketPage() {
BaseBehavior.waitForAccessibilityGranted();
launch(this.#appPackageName);
toast("10秒后开始进入刷红包广告模式");
sleep(10000);
let btn=id("android:id/text1").findOne(3000);
if(btn){
btn.click();
}
}
changeActionType(actionValue) {}
browsevideos() {}
browseHD(){}
}
const OperatorInstances=Object.freeze({
[APP_TYPE.KS]:KSOperator.getInstance(),
[APP_TYPE.KSFAST]:KSFastOperator.getInstance()
});
function main(apptype){
BaseBehavior.checkParmsOfAPPTYPE(apptype);
let opinstance=OperatorInstances[apptype];
if(!opinstance){
throw Error("意料之外的异常!") ;
}
opinstance.startingSmallTask();
opinstance.openRedPacketPage();
}
main(APP_TYPE.KSFAST);
那里错了
回答
这段代码在 Hamibot 运行环境中存在几个关键的兼容性错误和逻辑问题,主要集中在 JavaScript 引擎版本支持和业务逻辑实现上。
主要错误分析
-
私有字段语法不支持
代码中使用了#appPackageName定义私有类字段。Hamibot 使用的 Rhino 1.7.15 JavaScript 引擎不支持 ES2022 的私有字段语法(#开头)。这会导致脚本直接报错无法运行。
修正:去掉#号,改为普通属性,如this.appPackageName。 -
ES6+ API 兼容性风险
代码中使用了Object.values()。这是 ES2017 的特性,在部分旧版运行环境或特定配置下可能不可用。
修正:建议手动列举值进行判断,或使用兼容写法。 -
类继承与方法实现
KSOperator继承自BaseBehavior,但其内部方法(如openRedPacketPage)是空的。如果主函数调用的是APP_TYPE.KS,脚本不会报错但不会执行任何操作。KSFastOperator中实现了部分逻辑,但依赖的控件选择器id("android:id/text1")可能因应用版本更新而失效。 -
自动化风险
根据服务条款,脚本操作第三方应用(如快手)存在风险。自动化刷视频或广告可能违反目标应用的用户协议,导致账号被封禁或功能限制。用户需自行评估风险。
修正后的代码示例
以下是修正了语法兼容性问题的代码,去掉了私有字段,调整了枚举检查方式,并添加了必要的文档注释。
// 文档地址 https://docs.hamibot.com/
var errorbasestr1 = "必须实现";
var errorbasestr2 = "方法!";
// 定义应用类型常量
var APP_TYPE = {
KS: 200,
KSFAST: 666
};
// 定义动作类型常量
var ActionType = {
LOOKAD: 0,
LOOKVIDEO: 1
};
// 基础行为类
function BaseBehavior() {}
BaseBehavior.prototype.openRedPacketPage = function() {
throw new Error(errorbasestr1 + "openRedPacket" + errorbasestr2);
};
BaseBehavior.prototype.changeActionType = function(actionvalue) {
throw new Error(errorbasestr1 + "changeActionType" + errorbasestr2);
};
BaseBehavior.prototype.browsevideos = function() {
throw new Error(errorbasestr1 + "browsevideos" + errorbasestr2);
};
BaseBehavior.prototype.browseHD = function() {
throw new Error(errorbasestr1 + "browseHD" + errorbasestr2);
};
BaseBehavior.prototype.checkParmsOfActionType = function(actionvalue) {
if (actionvalue !== ActionType.LOOKAD && actionvalue !== ActionType.LOOKVIDEO) {
throw new Error('参数必须是 ActionType 枚举类型');
}
};
BaseBehavior.checkParmsOfAPPTYPE = function(apptype) {
if (apptype !== APP_TYPE.KS && apptype !== APP_TYPE.KSFAST) {
throw new Error('参数必须是 AppType 枚举类型');
}
};
BaseBehavior.waitForAccessibilityGranted = function() {
auto.waitFor();
};
BaseBehavior.prototype.startingSmallTask = function() {
setScreenMetrics(1080, 2340);
toast("开始打开快手红包");
};
// 快手操作者
function KSOperator() {
this.appPackageName = "com.smile.gifmaker";
}
KSOperator.prototype = new BaseBehavior();
KSOperator.prototype.openRedPacketPage = function() {
// 需补充具体实现
};
KSOperator.prototype.changeActionType = function(actionValue) {};
KSOperator.prototype.browsevideos = function() {};
KSOperator.prototype.browseHD = function() {};
// 快手极速版操作者
function KSFastOperator() {
this.appPackageName = "com.kuaishou.nebula";
}
KSFastOperator.prototype = new BaseBehavior();
KSFastOperator.prototype.openRedPacketPage = function() {
BaseBehavior.waitForAccessibilityGranted();
launch(this.appPackageName);
toast("10 秒后开始进入刷红包广告模式");
sleep(10000);
// 注意:控件 ID 可能随版本变化,建议结合 text 或 className 定位
var btn = id("android:id/text1").findOne(3000);
if (btn) {
btn.click();
}
};
KSFastOperator.prototype.changeActionType = function(actionValue) {};
KSFastOperator.prototype.browsevideos = function() {};
KSFastOperator.prototype.browseHD = function() {};
// 获取实例辅助函数
function getOperator(apptype) {
if (apptype === APP_TYPE.KS) {
return new KSOperator();
} else if (apptype === APP_TYPE.KSFAST) {
return new KSFastOperator();
}
return null;
}
function main(apptype) {
BaseBehavior.checkParmsOfAPPTYPE(apptype);
var opinstance = getOperator(apptype);
if (!opinstance) {
throw Error("意料之外的异常!");
}
opinstance.startingSmallTask();
opinstance.openRedPacketPage();
}
// 执行入口
main(APP_TYPE.KSFAST);
最佳实践建议
- 控件定位优化:代码中
id("android:id/text1")过于通用,极易匹配到错误控件。建议使用布局分析工具获取具体的text、className或desc属性组合定位,例如className("android.widget.TextView").text("签到").findOne()。 - 异常处理:在
click()或findOne()前后增加try-catch或存在性判断,防止因控件未加载导致脚本意外停止。 - 合规使用:自动化脚本应仅用于辅助操作,避免高频、模拟人工痕迹过弱的操作,以免触发目标应用的风控机制。