feat: init
This commit is contained in:
BIN
audio/caixueying.m4a
Normal file
BIN
audio/caixueying.m4a
Normal file
Binary file not shown.
BIN
audio/chenhong.m4a
Normal file
BIN
audio/chenhong.m4a
Normal file
Binary file not shown.
BIN
audio/dubaojun.m4a
Normal file
BIN
audio/dubaojun.m4a
Normal file
Binary file not shown.
BIN
audio/genghonghai.m4a
Normal file
BIN
audio/genghonghai.m4a
Normal file
Binary file not shown.
BIN
audio/liliuji.m4a
Normal file
BIN
audio/liliuji.m4a
Normal file
Binary file not shown.
BIN
audio/liudong.m4a
Normal file
BIN
audio/liudong.m4a
Normal file
Binary file not shown.
BIN
audio/liulianqi.m4a
Normal file
BIN
audio/liulianqi.m4a
Normal file
Binary file not shown.
BIN
audio/wangguozhong.m4a
Normal file
BIN
audio/wangguozhong.m4a
Normal file
Binary file not shown.
BIN
audio/xueyongdong.m4a
Normal file
BIN
audio/xueyongdong.m4a
Normal file
Binary file not shown.
BIN
audio/yaobaosen.m4a
Normal file
BIN
audio/yaobaosen.m4a
Normal file
Binary file not shown.
BIN
audio/zhangguangsheng.m4a
Normal file
BIN
audio/zhangguangsheng.m4a
Normal file
Binary file not shown.
BIN
audio/zhangzhaofa.m4a
Normal file
BIN
audio/zhangzhaofa.m4a
Normal file
Binary file not shown.
139
boot/main.js
Normal file
139
boot/main.js
Normal file
@@ -0,0 +1,139 @@
|
||||
auto.waitFor();
|
||||
|
||||
const deviceID = device.getAndroidId()
|
||||
log(`设备号 ${deviceID}`);
|
||||
|
||||
let e = null;
|
||||
let canAutoRun = false;
|
||||
|
||||
let CheckVersion = function () {
|
||||
log("检查更新")
|
||||
let version = "0.0.0"
|
||||
if (files.isFile("version.txt")) {
|
||||
version = files.read("version.txt");
|
||||
version = version.trim()
|
||||
}
|
||||
|
||||
let store = storages.create("_##_@_DY_Proxy");
|
||||
let host = store.get("__host", "")
|
||||
if (host.length == 0) {
|
||||
host = "https://f.jdwan.com"
|
||||
}
|
||||
|
||||
let url = "{host}/api/version"
|
||||
url = url.replace("{host}", host)
|
||||
log("url =", url)
|
||||
|
||||
let headers = {
|
||||
headers: {
|
||||
"Authorization": "Basic cm9nZWVjbjp4aXhpQDAyMDI="
|
||||
}
|
||||
}
|
||||
try {
|
||||
let resp = http.get(url, headers)
|
||||
if (resp.statusCode != 200) {
|
||||
log("更新请求失败, statusCode: ", resp.statusCode)
|
||||
canAutoRun = true
|
||||
return false
|
||||
}
|
||||
|
||||
let body = resp.body.json()
|
||||
if (body == null) {
|
||||
log("没有新的数据")
|
||||
canAutoRun = true
|
||||
return false
|
||||
}
|
||||
|
||||
if (body.version == version) {
|
||||
canAutoRun = true
|
||||
return false
|
||||
}
|
||||
log(`有新版本 ${body.version} 当前版本: ${version}, 开始更新`)
|
||||
|
||||
|
||||
if (e && !e.getEngine().isDestroyed()) {
|
||||
canAutoRun = false
|
||||
e.getEngine().forceStop()
|
||||
}
|
||||
|
||||
body.files.forEach((file, index) => {
|
||||
log("下载文件: ( " + (index + 1) + " / " + body.files.length + ")" + file)
|
||||
let url = "{host}/api/version/file/{file}"
|
||||
url = url.replace("{host}", host).replace("{file}", file)
|
||||
|
||||
let resp = http.get(url, headers)
|
||||
if (resp.statusCode != 200) {
|
||||
log(`下载文件(${file})失败, statusCode: ${resp.statusCode}`)
|
||||
return
|
||||
}
|
||||
|
||||
let path = files.path(file)
|
||||
files.createWithDirs(path)
|
||||
files.writeBytes(path, resp.body.bytes())
|
||||
})
|
||||
} catch (e) {
|
||||
log("更新请求失败, ", e)
|
||||
canAutoRun = true
|
||||
return false
|
||||
}
|
||||
|
||||
canAutoRun = true
|
||||
log("更新完成")
|
||||
return true
|
||||
}
|
||||
|
||||
events.on("exit", function () {
|
||||
log("结束运行");
|
||||
if (e && !e.getEngine().isDestroyed()) {
|
||||
canAutoRun = false
|
||||
e.getEngine().forceStop()
|
||||
}
|
||||
});
|
||||
|
||||
CheckVersion()
|
||||
setInterval(CheckVersion, 60 * 1000)
|
||||
|
||||
setInterval(() => {
|
||||
let activity = currentActivity()
|
||||
if ("com.ss.android.ugc.aweme.update.dialog.ui.UpdateNotifyDialog" == activity) {
|
||||
let btn = text("以后再说").findOne(500)
|
||||
if (btn) {
|
||||
btn.click()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ("com.ss.android.ugc.aweme.account.business.logout.LogoutDialogActivity" == activity) {
|
||||
// todo: 退出登录
|
||||
let btn = text("我知道了").findOne(500)
|
||||
if (btn) {
|
||||
btn.click()
|
||||
}
|
||||
}
|
||||
|
||||
if ("com.bytedance.dux.dialog.alert.DuxAlertDialog" == activity) {
|
||||
let btn = text("拒绝").findOne(500)
|
||||
if (btn) {
|
||||
btn.click()
|
||||
}
|
||||
}
|
||||
|
||||
}, 1000)
|
||||
|
||||
setInterval(() => {
|
||||
if (!canAutoRun) {
|
||||
return
|
||||
}
|
||||
|
||||
if (e && !e.getEngine().isDestroyed()) {
|
||||
return
|
||||
}
|
||||
|
||||
let path = files.path("runner.js");
|
||||
log("runner", path);
|
||||
log("开始执行脚本");
|
||||
e = engines.execScriptFile(path, {
|
||||
loopTimes: 1,
|
||||
path: files.path("./"),
|
||||
});
|
||||
}, 2000)
|
||||
59
boot/project.json
Normal file
59
boot/project.json
Normal file
@@ -0,0 +1,59 @@
|
||||
{
|
||||
"abis": [
|
||||
"arm64-v8a",
|
||||
"armeabi-v7a",
|
||||
"x86",
|
||||
"x86_64"
|
||||
],
|
||||
"assets": [
|
||||
{
|
||||
"form": "/storage/emulated/0/脚本/autojs/boot",
|
||||
"to": "/project"
|
||||
}
|
||||
],
|
||||
"buildDir": "build",
|
||||
"build": {
|
||||
"build_id": null,
|
||||
"build_number": 0,
|
||||
"build_time": 0
|
||||
},
|
||||
"useFeatures": [],
|
||||
"icon": "res/logo.png",
|
||||
"ignoredDirs": [
|
||||
"build"
|
||||
],
|
||||
"encrypt-code": false,
|
||||
"launchConfig": {
|
||||
"displaySplash": true,
|
||||
"hideAccessibilityServices": false,
|
||||
"hideLauncher": false,
|
||||
"hideLogs": false,
|
||||
"stableMode": false,
|
||||
"volumeUpcontrol": true,
|
||||
"permissions": [
|
||||
"accessibility_services",
|
||||
"background_start",
|
||||
"draw_overlay"
|
||||
],
|
||||
"serviceDesc": "自动操作",
|
||||
"splashIcon": "res/splashIcon.png",
|
||||
"splashText": "请合理使用"
|
||||
},
|
||||
"libs": [
|
||||
"libjackpal-androidterm5.so",
|
||||
"libjackpal-termexec2.so"
|
||||
],
|
||||
"main": "main.js",
|
||||
"name": "PowerBank",
|
||||
"outputPath": "/storage/emulated/0/脚本/autojs/boot/build",
|
||||
"packageName": "com.power.bank",
|
||||
"projectDirectory": "/storage/emulated/0/脚本/autojs/boot",
|
||||
"scripts": {},
|
||||
"signingConfig": {
|
||||
"alias": null,
|
||||
"keystore": null
|
||||
},
|
||||
"sourcePath": "/storage/emulated/0/脚本/autojs/boot/main.js",
|
||||
"versionCode": 1,
|
||||
"versionName": "1.0.0"
|
||||
}
|
||||
BIN
boot/res/logo.png
Normal file
BIN
boot/res/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 24 KiB |
BIN
boot/res/splashIcon.png
Normal file
BIN
boot/res/splashIcon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 24 KiB |
10
consts.js
Normal file
10
consts.js
Normal file
@@ -0,0 +1,10 @@
|
||||
module.exports = {
|
||||
AppID: function (idx) {
|
||||
return `com.miui.securitycore:id/app1`
|
||||
return `com.miui.securitycore:id/app${idx}`
|
||||
},
|
||||
Package: {
|
||||
DouYin: "com.ss.android.ugc.aweme",
|
||||
MiShu: "com.miui.securitycore"
|
||||
},
|
||||
}
|
||||
84
core.request.js
Normal file
84
core.request.js
Normal file
@@ -0,0 +1,84 @@
|
||||
let lib = require("./lib.js")
|
||||
|
||||
const headers = {
|
||||
headers: {
|
||||
"Authorization": "Basic cm9nZWVjbjp4aXhpQDAyMDI="
|
||||
}
|
||||
}
|
||||
|
||||
let getOneUser = function () {
|
||||
const deviceID = device.getAndroidId()
|
||||
|
||||
let lastID = lib.store.lastID()
|
||||
let path = "{host}/api/devices/{deviceID}/follower"
|
||||
let url = path.replace("{host}", lib.store.host()).replace("{deviceID}", deviceID)
|
||||
if (lastID != 0) {
|
||||
url = url + "?last=" + lastID
|
||||
}
|
||||
log("url =", url)
|
||||
|
||||
try {
|
||||
http.__okhttp__.setTimeout(10 * 1000);
|
||||
let resp = http.get(url, headers)
|
||||
if (resp.statusCode != 200) {
|
||||
return false
|
||||
}
|
||||
// 检查 version
|
||||
let version = lib.store.config_version()
|
||||
let newVersion = resp.headers["x-config-at"]
|
||||
if (newVersion && version != newVersion) {
|
||||
log(`更新配置 ${version} => ${newVersion} `)
|
||||
updateConfig(resp.headers["x-expert-uid"])
|
||||
}
|
||||
|
||||
let body = resp.body.json()
|
||||
log("body =", body)
|
||||
if (body == null) {
|
||||
toastLog("没有新的数据")
|
||||
return false
|
||||
}
|
||||
return body
|
||||
} catch (e) {
|
||||
log("ERROR", e)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
let updateConfig = function (uid) {
|
||||
let host = lib.store.host()
|
||||
let url = `${host}/api/experts/${uid}/config`
|
||||
log("url =", url)
|
||||
|
||||
try {
|
||||
http.__okhttp__.setTimeout(10 * 1000);
|
||||
let resp = http.get(url, headers)
|
||||
if (resp.statusCode != 200) {
|
||||
return false
|
||||
}
|
||||
|
||||
let body = resp.body.json()
|
||||
if (body == null) {
|
||||
return false
|
||||
}
|
||||
log("body =", body)
|
||||
|
||||
lib.store.config_version(resp.headers["x-config-at"])
|
||||
lib.store.hello(body.Hello)
|
||||
lib.store.voice(body.Voice)
|
||||
lib.store.wechat(body.Wechat)
|
||||
lib.store.region(body.Region)
|
||||
lib.store.produce(body.Produce)
|
||||
lib.store.default_name(body.DefaultName)
|
||||
lib.store.default_avatar(body.DefaultAvatar)
|
||||
lib.store.name_keyword(body.NameKeyword)
|
||||
return true
|
||||
} catch (e) {
|
||||
log("ERROR", e)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
getOneUser,
|
||||
updateConfig,
|
||||
}
|
||||
417
core.sqlite.js
Normal file
417
core.sqlite.js
Normal file
@@ -0,0 +1,417 @@
|
||||
// 导入必要的class
|
||||
importClass(android.database.sqlite.SQLiteDatabase);
|
||||
importClass(android.content.ContentValues);
|
||||
|
||||
function SQLiteSDK(filePath) {
|
||||
this._dbFilePath = filePath;
|
||||
}
|
||||
|
||||
|
||||
/** 根据 json 键值 快速建表
|
||||
* @public
|
||||
* @param {*} tableName 表名
|
||||
* @param {*} data json数据
|
||||
* @param {*} uniqueArr 唯一
|
||||
*/
|
||||
SQLiteSDK.prototype.fastCreateTable = function (tableName, data, uniqueArr) {
|
||||
let columnArr = [];
|
||||
let itemName = "";
|
||||
|
||||
// 拼接数据类型
|
||||
for (let key in data) {
|
||||
//_log((typeof data[key]) + data[key])
|
||||
switch (typeof data[key]) {
|
||||
case "number":
|
||||
itemName = key + " INTEGER DEFAULT 0";
|
||||
break;
|
||||
case "boolean":
|
||||
itemName = key + " INTEGER DEFAULT 0";
|
||||
break;
|
||||
default:
|
||||
itemName = key + " TEXT DEFAULT ''";
|
||||
break;
|
||||
}
|
||||
|
||||
if (uniqueArr.indexOf(key) > -1) {
|
||||
itemName += " unique";
|
||||
}
|
||||
columnArr.push(itemName);
|
||||
}
|
||||
// 创建
|
||||
this.createTable(tableName, columnArr);
|
||||
};
|
||||
|
||||
/** 创建表
|
||||
* @public
|
||||
* @param {string} tableName 表名
|
||||
* @param {string[]} columns 参数列名 数组, 源码中会用 逗号隔开
|
||||
*/
|
||||
SQLiteSDK.prototype.createTable = function (tableName, columns) {
|
||||
this._log("init");
|
||||
try {
|
||||
files.ensureDir(this._dbFilePath);
|
||||
this.execSQL("create table IF NOt EXISTS " + tableName + "(id integer primary key autoincrement," + columns.join(",") + ")");
|
||||
} catch (e) {
|
||||
this._error("createTable error: " + e);
|
||||
}
|
||||
};
|
||||
|
||||
/** 查询
|
||||
* @public
|
||||
* @example
|
||||
* db.find("select * from " + tableName + " where weibo_UserName='13235919724'");
|
||||
* @param {string} sqlStr sql字符串
|
||||
* @returns {object[]} json 数组
|
||||
*/
|
||||
SQLiteSDK.prototype.find = function (sqlStr) {
|
||||
this._log("find");
|
||||
let res = [];
|
||||
let db;
|
||||
try {
|
||||
db = this._getDBConnection();
|
||||
res = this._getCursorDataArr(db.rawQuery(sqlStr, null));
|
||||
} catch (e) {
|
||||
this._error("find error: " + e);
|
||||
} finally {
|
||||
db ? db.close() : "";
|
||||
}
|
||||
return res;
|
||||
};
|
||||
|
||||
/** 插入
|
||||
*
|
||||
* @public
|
||||
* @param {表明} tableName 表明
|
||||
* @param {object} jsonObj json数据对象
|
||||
* @param {string?} nullColumnHack 可以不传,一般为null即可 https://www.iteye.com/blog/mofan-1412262
|
||||
* @returns {number} 插入的行ID;如果发生错误,则返回-1
|
||||
*/
|
||||
SQLiteSDK.prototype.insert = function (tableName, jsonObj, nullColumnHack) {
|
||||
this._log("insert");
|
||||
nullColumnHack = nullColumnHack || null;
|
||||
let res = -1;
|
||||
let db;
|
||||
try {
|
||||
db = this._getDBConnection();
|
||||
db.beginTransaction();
|
||||
res = db.insert(tableName, nullColumnHack, this._getContentValues(jsonObj));
|
||||
db.setTransactionSuccessful(); //设置事务处理成功,不设置会自动回滚不提交。
|
||||
} catch (e) {
|
||||
this._error("insert error: " + e);
|
||||
} finally {
|
||||
db ? db.endTransaction() : "";
|
||||
db ? db.close() : "";
|
||||
}
|
||||
return res;
|
||||
};
|
||||
|
||||
/** 删除
|
||||
* @public
|
||||
* @example
|
||||
* db.delete(tableName,"weibo_UserName=?",["1名字"])
|
||||
* @param {string} tableName 表名
|
||||
* @param {string} whereClause where 条件
|
||||
* @param {string[]} whereArgs where 条件的参数
|
||||
* @returns {number} 如果传入whereClause,则受影响的行数,否则为0 。要删除所有行并获得计数,请将“1”作为 whereClause。
|
||||
*/
|
||||
SQLiteSDK.prototype.delete = function (tableName, whereClause, whereArgs) {
|
||||
this._log("delete");
|
||||
let res = 0;
|
||||
let db;
|
||||
try {
|
||||
db = this._getDBConnection();
|
||||
db.beginTransaction();
|
||||
res = db.delete(tableName, whereClause, whereArgs);
|
||||
db.setTransactionSuccessful(); //设置事务处理成功,不设置会自动回滚不提交。
|
||||
} catch (e) {
|
||||
this._error("delete error: " + e);
|
||||
} finally {
|
||||
db ? db.endTransaction() : "";
|
||||
db ? db.close() : "";
|
||||
}
|
||||
return res;
|
||||
};
|
||||
|
||||
/** 更新
|
||||
* @public
|
||||
* @example
|
||||
* db.update(tableName,{"weibo_NickName":"哈哈哈"},"weibo_UserName=?",["13235919724"])
|
||||
* @param {string} tableName 表名
|
||||
* @param {object} jsonObj json对象
|
||||
* @param {string} whereClause where 条件
|
||||
* @param {string[]} whereArgs where 条件的参数
|
||||
* @returns {number} 受影响的行数
|
||||
*/
|
||||
SQLiteSDK.prototype.update = function (tableName, jsonObj, whereClause, whereArgs) {
|
||||
this._log("update");
|
||||
let res = 0;
|
||||
let db;
|
||||
try {
|
||||
db = this._getDBConnection();
|
||||
res = db.update(tableName, this._getContentValues(jsonObj), whereClause, whereArgs);
|
||||
} catch (e) {
|
||||
this._error("update error: " + e);
|
||||
} finally {
|
||||
db ? db.close() : "";
|
||||
}
|
||||
return res;
|
||||
};
|
||||
|
||||
/** 替换数据库中一行的便捷方法。 如果行不存在,则插入新行。
|
||||
*
|
||||
* !!!! 当表有一个PRIMARY KEY或UNIQUE索引才有意义
|
||||
* @public
|
||||
* @example
|
||||
* https://blog.csdn.net/wangyanguiyiyang/article/details/51126590
|
||||
* @param {string} tableName 表名
|
||||
* @param {object} jsonObj json对象
|
||||
* @param {string?} nullColumnHack 一般为null即可 https://www.iteye.com/blog/mofan-1412262
|
||||
* @returns {number} 新插入的行的行ID;如果发生错误,则返回-1
|
||||
*/
|
||||
SQLiteSDK.prototype.replace = function (tableName, jsonObj, nullColumnHack) {
|
||||
nullColumnHack = nullColumnHack || null;
|
||||
let res = -1;
|
||||
let db;
|
||||
try {
|
||||
db = this._getDBConnection();
|
||||
|
||||
res = db.replace(tableName, nullColumnHack, this._getContentValues(jsonObj));
|
||||
} catch (e) {
|
||||
this._error("replace error: " + e);
|
||||
} finally {
|
||||
db ? db.close() : "";
|
||||
}
|
||||
return res;
|
||||
};
|
||||
|
||||
|
||||
/** 删除表
|
||||
* @public
|
||||
* @param {string} tableName 表名
|
||||
*/
|
||||
SQLiteSDK.prototype.dropTable = function (tableName) {
|
||||
try {
|
||||
this.execSQL("drop table if exists " + tableName);
|
||||
} catch (e) {
|
||||
this._error("dropTable error: " + e);
|
||||
}
|
||||
};
|
||||
|
||||
/** 清空表
|
||||
* @public
|
||||
* @param {string} tableName 表名
|
||||
*/
|
||||
SQLiteSDK.prototype.clearTable = function (tableName) {
|
||||
try {
|
||||
this.execSQL("delete from " + tableName);
|
||||
} catch (e) {
|
||||
this._error("clearTable error: " + e);
|
||||
}
|
||||
};
|
||||
|
||||
/** 表索引序列归0
|
||||
* @public
|
||||
* @param {string} tableName 表名
|
||||
*/
|
||||
SQLiteSDK.prototype.resetTableSequence = function (tableName) {
|
||||
try {
|
||||
db.execSQL("UPDATE sqlite_sequence SET seq = 0 WHERE name = '" + tableName + "'");
|
||||
} catch (e) {
|
||||
this._error("resetTableSequence error: " + e);
|
||||
}
|
||||
};
|
||||
|
||||
/** 执行sql
|
||||
* @public
|
||||
* @param {string} sqlStr
|
||||
*/
|
||||
SQLiteSDK.prototype.execSQL = function (sqlStr) {
|
||||
let db;
|
||||
try {
|
||||
db = this._getDBConnection();
|
||||
db.execSQL(sqlStr);
|
||||
} catch (e) {
|
||||
throw e;
|
||||
} finally {
|
||||
db ? db.close() : "";
|
||||
}
|
||||
};
|
||||
|
||||
/** 需要升级
|
||||
* @public
|
||||
* @param {number} newVersion 版本号 数字
|
||||
* @returns {boolean} 如果新版本代码大于当前数据库版本,则返回true。
|
||||
*/
|
||||
SQLiteSDK.prototype.needUpgrade = function (newVersion) {
|
||||
let res = false;
|
||||
let db;
|
||||
try {
|
||||
db = this._getDBConnection();
|
||||
res = db.needUpgrade(newVersion);
|
||||
} catch (e) {
|
||||
this._error("needUpgrade error:" + e);
|
||||
} finally {
|
||||
db ? db.close() : "";
|
||||
}
|
||||
return res;
|
||||
};
|
||||
|
||||
/** 删除数据库文件
|
||||
* @public
|
||||
*/
|
||||
SQLiteSDK.prototype.deleteDbFile = function () {
|
||||
if (files.exists(this._dbFilePath)) {
|
||||
files.remove(this._dbFilePath);
|
||||
this._log("数据库删除成功,地址:" + this._dbFilePath);
|
||||
}
|
||||
};
|
||||
|
||||
//#region 私有方法
|
||||
|
||||
/** 获取 游标里的 数据
|
||||
*
|
||||
* @private
|
||||
* @param {string} cursor 游标
|
||||
* @returns {object[]} json 数组
|
||||
*/
|
||||
SQLiteSDK.prototype._getCursorDataArr = function (cursor) {
|
||||
let res = [];
|
||||
if (cursor) {
|
||||
try {
|
||||
cursor.moveToFirst();
|
||||
this._log("cursor count: " + cursor.getCount());
|
||||
|
||||
let columnNameArr = cursor.getColumnNames();
|
||||
|
||||
if (cursor.getCount() > 0) {
|
||||
do {
|
||||
let resItem = {};
|
||||
for (let nameIndex = 0; nameIndex < columnNameArr.length; nameIndex++) {
|
||||
let nameItem = columnNameArr[nameIndex];
|
||||
let columnIndex = cursor.getColumnIndex(nameItem);
|
||||
if (columnIndex > -1) {
|
||||
let itemValue;
|
||||
switch (cursor.getType(columnIndex)) {
|
||||
case 0: // FIELD_TYPE_NULL 0
|
||||
itemValue = null;
|
||||
break;
|
||||
case 1: // FIELD_TYPE_INTEGER 1
|
||||
itemValue = cursor.getInt(columnIndex);
|
||||
break;
|
||||
case 2: // FIELD_TYPE_FLOAT 2
|
||||
itemValue = cursor.getFloat(columnIndex);
|
||||
break;
|
||||
case 3: // FIELD_TYPE_STRING 3
|
||||
itemValue = cursor.getString(columnIndex);
|
||||
break;
|
||||
case 4: // FIELD_TYPE_BLOB 4
|
||||
itemValue = cursor.getBlob(columnIndex);
|
||||
break;
|
||||
default:
|
||||
itemValue = cursor.getString(columnIndex);
|
||||
break;
|
||||
}
|
||||
resItem[nameItem] = itemValue;
|
||||
}
|
||||
}
|
||||
res.push(resItem);
|
||||
} while (cursor.moveToNext());
|
||||
}
|
||||
} catch (e) {
|
||||
this._error("_getCursorDataArr error: " + e);
|
||||
} finally {
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
return res;
|
||||
};
|
||||
|
||||
/** 获取 contentValues -------- (json转 contentValues)
|
||||
*
|
||||
* @private
|
||||
* @param {object} jsonObj json对象
|
||||
* @returns ContentValues对象
|
||||
*/
|
||||
SQLiteSDK.prototype._getContentValues = function (jsonObj) {
|
||||
let cv = new ContentValues();
|
||||
if (jsonObj) {
|
||||
for (let key in jsonObj) {
|
||||
let item = jsonObj[key];
|
||||
switch (typeof item) {
|
||||
case "number":
|
||||
cv.put(key, java.lang.Integer(item));
|
||||
break;
|
||||
case "boolean":
|
||||
cv.put(key, java.lang.Boolean(item));
|
||||
break;
|
||||
case "boolean":
|
||||
cv.put(key, java.lang.Boolean(item));
|
||||
break;
|
||||
default:
|
||||
cv.put(key, java.lang.String(item));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
void put(java.lang.String,java.lang.Long)
|
||||
void put(java.lang.String,java.lang.Byte)
|
||||
void put(java.lang.String,java.lang.Double)
|
||||
void put(java.lang.String,java.lang.Float)
|
||||
void put(java.lang.String,java.lang.Integer)
|
||||
void put(java.lang.String,java.lang.Short)
|
||||
*/
|
||||
return cv;
|
||||
};
|
||||
|
||||
/** log日志
|
||||
*
|
||||
* @private
|
||||
* @param {*} msg
|
||||
*/
|
||||
SQLiteSDK.prototype._log = function (msg) {
|
||||
// console.log(msg);
|
||||
};
|
||||
|
||||
/** error日志
|
||||
*
|
||||
* @private
|
||||
* @param {any} msg
|
||||
*/
|
||||
SQLiteSDK.prototype._error = function (msg) {
|
||||
console.error(msg);
|
||||
};
|
||||
|
||||
/** 获取 db连接对象
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
SQLiteSDK.prototype._getDBConnection = function () {
|
||||
return SQLiteDatabase.openOrCreateDatabase(this._dbFilePath, null);
|
||||
};
|
||||
|
||||
|
||||
let db = new SQLiteSDK(files.path("./data.db"))
|
||||
db.createTable("friends", [
|
||||
"name TEXT not null default ''",
|
||||
"created_at INTEGER not null default 0",
|
||||
])
|
||||
|
||||
let addUser = function (name) {
|
||||
if (existsUser(name)) {
|
||||
log(`insert failed, user "${name}" exists`)
|
||||
return false
|
||||
}
|
||||
return db.insert("friends", { name: name, created_at: Math.floor(new Date().getTime() / 1000) })
|
||||
}
|
||||
|
||||
let existsUser = function (name) {
|
||||
let result = db.find(`select count(*) as cnt from friends where name='${name}' limit 1`)
|
||||
return result[0].cnt > 0
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
addUser,
|
||||
existsUser,
|
||||
}
|
||||
147
flow.js
Normal file
147
flow.js
Normal file
@@ -0,0 +1,147 @@
|
||||
let lib = require("./lib.js")
|
||||
let flowUser = require("./flow_user.js")
|
||||
let flowFriend = require("./flow_friend.js")
|
||||
let flowChat = require("./flow_chat.js")
|
||||
|
||||
|
||||
|
||||
// 获取用户并关注、私信、发送喜欢视频、发送陌生人文本、返回用户主页
|
||||
let HuoQuYongHuBingGuanZhuFaSiXin = function () {
|
||||
home()
|
||||
sleep(200)
|
||||
|
||||
let checkName = undefined;
|
||||
if (lib.store.default_name()) {
|
||||
checkName = function (body) {
|
||||
let reg = /用户\d+/
|
||||
if (body.Nickname.match(reg)) {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
let checkNameKeyword = undefined;
|
||||
if (lib.store.name_keyword()) {
|
||||
checkNameKeyword = function (body) {
|
||||
for (let i = 0; i < lib.store.name_keyword().length; i++) {
|
||||
let keyword = lib.store.name_keyword()[i]
|
||||
if (body.Nickname.indexOf(keyword) >= 0) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
let checkAvatar = undefined
|
||||
if (lib.store.default_avatar()) {
|
||||
checkAvatar = function (body) {
|
||||
if (body.Avatar.indexOf("/mosaic-legacy") > 0) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
if (!flowUser.HuoQuXinYongHu(checkName, checkAvatar, checkNameKeyword)) {
|
||||
toastLog("获取新用户失败")
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
if (lib.store.produce() && !lib.page.user.hasProduce()) {
|
||||
toastLog("用户没有发布作品")
|
||||
return true
|
||||
}
|
||||
|
||||
let location = lib.page.user.getIPLocation()
|
||||
if (location && lib.store.region().indexOf(location) >= 0) {
|
||||
toastLog(`用户地区(${location})不符合`)
|
||||
back()
|
||||
return true
|
||||
}
|
||||
|
||||
toastLog("准备关注")
|
||||
if (!flowUser.GuanZhu()) {
|
||||
toastLog("关注失败")
|
||||
back()
|
||||
return false
|
||||
}
|
||||
|
||||
toastLog("准备私信")
|
||||
if (!flowUser.SiXin()) {
|
||||
toastLog("私信失败")
|
||||
back()
|
||||
return
|
||||
}
|
||||
|
||||
toastLog("准备发送喜欢视频")
|
||||
if (!flowChat.FaSongXiHuanShiPin()) {
|
||||
toastLog("发送喜欢视频失败")
|
||||
return
|
||||
}
|
||||
|
||||
toastLog("准备发送陌生人文本")
|
||||
if (!flowChat.FaSongMoShengRenWenBen()) {
|
||||
toastLog("发送陌生人文本失败")
|
||||
return
|
||||
}
|
||||
back()
|
||||
sleep(500)
|
||||
|
||||
toastLog("返回用户主页")
|
||||
if (!flowUser.GoToYongHuZhuYe()) {
|
||||
toastLog("返回用户主页 失败")
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
let FaSongHuGuanXiaoXi = function () {
|
||||
toastLog("打开用户主页")
|
||||
if (!flowUser.GoToYongHuZhuYe()) {
|
||||
toastLog("打开用户主页 失败")
|
||||
return false
|
||||
}
|
||||
|
||||
toastLog("打开朋友列表")
|
||||
if (!flowUser.GoToPengYouLieBiao()) {
|
||||
toastLog("打开朋友列表 失败")
|
||||
return
|
||||
}
|
||||
|
||||
while (true) {
|
||||
toastLog("选择一个好友")
|
||||
let name = flowFriend.XuanZeYiGe()
|
||||
if (!name) {
|
||||
// 好友列表为空,返回上一页
|
||||
back()
|
||||
break
|
||||
}
|
||||
|
||||
|
||||
toastLog("发送私信")
|
||||
if (!flowFriend.FaSiXin(name)) {
|
||||
toastLog("发送私信失败")
|
||||
back()
|
||||
continue
|
||||
}
|
||||
|
||||
back()
|
||||
sleep(1000)
|
||||
while (desc("设置").find().length === 0) {
|
||||
log("currentActivity() = ", currentActivity())
|
||||
back()
|
||||
sleep(1000)
|
||||
}
|
||||
sleep(1000)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
HuoQuYongHuBingGuanZhuFaSiXin,
|
||||
FaSongHuGuanXiaoXi,
|
||||
}
|
||||
60
flow_chat.js
Normal file
60
flow_chat.js
Normal file
@@ -0,0 +1,60 @@
|
||||
let lib = require("./lib.js")
|
||||
|
||||
let FaSongXiHuanShiPin = function () {
|
||||
// if (!lib.page.chat.clickInputSendTxt()) {
|
||||
// toastLog("没有找到输入框")
|
||||
// return false
|
||||
// }
|
||||
|
||||
if (!lib.page.chat.clickBtnMore()) {
|
||||
toastLog("没有找到更多按钮")
|
||||
return false
|
||||
}
|
||||
|
||||
if (!lib.page.chat.clickBtnMyLove()) {
|
||||
toastLog("没有找到我的喜欢按钮")
|
||||
return false
|
||||
}
|
||||
|
||||
if (!lib.page.chat.clickBtnMyLoveFirstProduct()) {
|
||||
toastLog("没有找到第一个我的喜欢视频")
|
||||
return false
|
||||
}
|
||||
|
||||
if (!lib.page.chat.clickBtnMyLoveSend()) {
|
||||
toastLog("没有找到发送按钮")
|
||||
return false
|
||||
}
|
||||
|
||||
back()
|
||||
return true
|
||||
}
|
||||
|
||||
let FaSongMoShengRenWenBen = function () {
|
||||
// let msg = "您好,我是 {user} 诊室,主任看到了您的关注,有什么可以帮到您的?也可以加一下方便了解您的详细情况哦。"
|
||||
// msg = msg.replace("{user}", "小猪佩奇")
|
||||
// if (!lib.page.chat.clickInputSendTxt()) {
|
||||
// toastLog("没有找到输入框")
|
||||
// return false
|
||||
// }
|
||||
|
||||
let hellos = lib.store.hello().split("\n").filter((i) => i.trim().length > 0)
|
||||
if (hellos.length == 0) {
|
||||
toastLog("没有找到问候语")
|
||||
back()
|
||||
return false
|
||||
}
|
||||
|
||||
//random one
|
||||
// let hello = hellos[Math.floor(Math.random() * hellos.length)]
|
||||
let hello = hellos[new Date().getTime() % hellos.length]
|
||||
lib.page.chat.sendText(hello)
|
||||
back()
|
||||
sleep(500)
|
||||
return true
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
FaSongXiHuanShiPin,
|
||||
FaSongMoShengRenWenBen,
|
||||
}
|
||||
39
flow_friend.js
Normal file
39
flow_friend.js
Normal file
@@ -0,0 +1,39 @@
|
||||
let lib = require("./lib.js")
|
||||
let db = require("./core.sqlite.js")
|
||||
let msg = require("./message.js")
|
||||
|
||||
|
||||
let FaSiXin = function (name) {
|
||||
msg.get().forEach((item, index) => {
|
||||
log("message =", item)
|
||||
|
||||
if (item.type == "text") {
|
||||
lib.page.chat.sendText(item.data)
|
||||
} else if (item.type == "voice") {
|
||||
lib.page.chat.sendAudioVoice(item.data)
|
||||
}
|
||||
})
|
||||
|
||||
db.addUser(name)
|
||||
return true
|
||||
}
|
||||
|
||||
let XuanZeYiGe = function () {
|
||||
let friends = lib.page.friend.getFriends()
|
||||
if (friends.length == 0) {
|
||||
log("没有好友")
|
||||
return false
|
||||
}
|
||||
|
||||
let friend = friends.pop()
|
||||
log(friend.name)
|
||||
friend.button.click()
|
||||
sleep(1000)
|
||||
|
||||
return friend.name
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
FaSiXin,
|
||||
XuanZeYiGe,
|
||||
}
|
||||
156
flow_user.js
Normal file
156
flow_user.js
Normal file
@@ -0,0 +1,156 @@
|
||||
let lib = require("./lib.js")
|
||||
let consts = require("./consts.js")
|
||||
let request = require("./core.request.js")
|
||||
|
||||
let GuanZhu = function () {
|
||||
let times = 0;
|
||||
while (lib.page.user.getBtnGuanZhu() && times++ < 10) {
|
||||
lib.page.user.clickBtnGuanZhu()
|
||||
sleep(1000)
|
||||
}
|
||||
if (times > 10) {
|
||||
toastLog("关注失败")
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
let SiXin = function () {
|
||||
return lib.page.user.clickBtnSiXin()
|
||||
}
|
||||
|
||||
let GoToPengYouLieBiao = function () {
|
||||
return lib.page.user.gotoFriend()
|
||||
}
|
||||
|
||||
let GoToYongHuZhuYe = function () {
|
||||
// 如果当前不是抖音应用,则先打开抖音
|
||||
let times = 0;
|
||||
log("package:", currentPackage())
|
||||
if (currentPackage() == "com.tencent.wetype") {
|
||||
back()
|
||||
sleep(1000)
|
||||
}
|
||||
|
||||
while (times++ < 10 && currentPackage() != consts.Package.DouYin) {
|
||||
log("package:", currentPackage())
|
||||
app.launchPackage(consts.Package.DouYin)
|
||||
sleep(1000)
|
||||
let appId = id(consts.AppID()).findOne(1000)
|
||||
if (appId) {
|
||||
appId.click()
|
||||
}
|
||||
sleep(1000)
|
||||
}
|
||||
if (times > 10) {
|
||||
toastLog("打开 抖音 失败")
|
||||
return false
|
||||
}
|
||||
|
||||
log("activity:", currentActivity())
|
||||
times = 0
|
||||
while (times++ < 20) {
|
||||
log("--------------------------")
|
||||
log("package:", currentPackage())
|
||||
log("activity:", currentActivity())
|
||||
|
||||
let activity = currentActivity()
|
||||
|
||||
|
||||
if (activity == "android.widget.FrameLayout") {
|
||||
times--
|
||||
sleep(2000)
|
||||
continue
|
||||
}
|
||||
|
||||
if (activity == "com.bytedance.dux.toast.ToastDialog") {
|
||||
lib.page.user.open()
|
||||
sleep(1000)
|
||||
continue
|
||||
}
|
||||
|
||||
if (activity == "com.ss.android.ugc.aweme.main.MainActivity") {
|
||||
lib.page.user.clickTabMe()
|
||||
break
|
||||
}
|
||||
|
||||
let package = currentPackage()
|
||||
if (package == consts.Package.DouYin && activity != "com.bytedance.dux.toast.ToastDialo") {
|
||||
|
||||
back()
|
||||
}
|
||||
|
||||
sleep(1000)
|
||||
}
|
||||
|
||||
needLoginActivity = "android.inputmethodservice.SoftInputWindow"
|
||||
needLoginActivity1 = "com.ss.android.ugc.aweme.account.business.login.DYLoginActivity"
|
||||
activity = currentActivity()
|
||||
if (activity == needLoginActivity || activity == needLoginActivity1) {
|
||||
log("当前抖音未登录")
|
||||
return false
|
||||
}
|
||||
|
||||
times = 0
|
||||
while (times++ < 10) {
|
||||
if (lib.page.user.getBtnBianJiZiLiao()) {
|
||||
break
|
||||
}
|
||||
lib.page.user.clickTabMe()
|
||||
sleep(500)
|
||||
}
|
||||
|
||||
if (times > 10) {
|
||||
toastLog("进入 个人中心 失败")
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
let HuoQuXinYongHu = function () {
|
||||
//指定确定按钮点击时要执行的动作
|
||||
let body = null;
|
||||
while (true) {
|
||||
body = request.getOneUser()
|
||||
if (!body) {
|
||||
return false
|
||||
}
|
||||
|
||||
lib.store.lastID(body.ID)
|
||||
toastLog("获取到新用户 " + body.Nickname)
|
||||
if (arguments.length > 0) {
|
||||
let isValid = [];
|
||||
|
||||
for (let i = 0; i < arguments.length; i++) {
|
||||
let f = arguments[i]
|
||||
if (f == undefined) {
|
||||
isValid.push(true)
|
||||
continue
|
||||
}
|
||||
|
||||
if (f(body)) {
|
||||
isValid.push(true)
|
||||
}
|
||||
}
|
||||
|
||||
if (isValid.length != arguments.length) {
|
||||
log("用户不符合要求")
|
||||
continue
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
|
||||
return lib.page.user.openUser(body.UID)
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
GuanZhu,
|
||||
SiXin,
|
||||
HuoQuXinYongHu,
|
||||
GoToYongHuZhuYe,
|
||||
GoToPengYouLieBiao,
|
||||
}
|
||||
654
lib.js
Normal file
654
lib.js
Normal file
@@ -0,0 +1,654 @@
|
||||
let db = require("./core.sqlite.js")
|
||||
let consts = require("./consts.js")
|
||||
|
||||
let _global_duration = 1000;
|
||||
let userList = [];
|
||||
text("发私信").find().forEach((item, idx) => {
|
||||
let obj =
|
||||
userList.push({
|
||||
obj: item,
|
||||
name: item.parent().parent().child(1).child(0).child(0).text(),
|
||||
})
|
||||
})
|
||||
|
||||
let global = {
|
||||
setDuration: function (duration) {
|
||||
_global_duration = duration
|
||||
},
|
||||
}
|
||||
|
||||
let store = storages.create("_##_@_DY_Proxy");
|
||||
|
||||
const project = "autojs"
|
||||
|
||||
let pwdFile = function (path) {
|
||||
let pwd = engines.myEngine().cwd()
|
||||
|
||||
if (!path) {
|
||||
return pwd
|
||||
}
|
||||
|
||||
if (path) {
|
||||
path = path.replace(/^\//, "")
|
||||
}
|
||||
|
||||
return `${pwd}/${project}/${path}`.replace(/\/\//g, "/").replace(/\/$/, "")
|
||||
}
|
||||
|
||||
let pageUser = {
|
||||
activity: "com.ss.android.ugc.aweme.profile.ui.UserProfileActivity",
|
||||
wait: function () {
|
||||
waitForActivity(this.activity)
|
||||
},
|
||||
open: function () {
|
||||
home()
|
||||
sleep(500)
|
||||
let activity = "snssdk1128://user/profile"
|
||||
app.startActivity({
|
||||
packageName: consts.Package.DouYin,
|
||||
action: "android.intent.action.VIEW",
|
||||
data: activity,
|
||||
});
|
||||
let appId = id(consts.AppID()).findOne(1000)
|
||||
if (appId) {
|
||||
appId.click()
|
||||
}
|
||||
|
||||
waitForActivity("com.ss.android.ugc.aweme.main.MainActivity")
|
||||
this.clickTabMe()
|
||||
},
|
||||
openUser: function (uid) {
|
||||
let activity = "snssdk1128://user/profile/{uid}".replace("{uid}", uid)
|
||||
app.startActivity({
|
||||
packageName: consts.Package.DouYin,
|
||||
action: "android.intent.action.VIEW",
|
||||
data: activity,
|
||||
});
|
||||
let appId = id(consts.AppID()).findOne(1000)
|
||||
if (appId) {
|
||||
appId.click()
|
||||
}
|
||||
|
||||
for (let i = 0; i <= 10; i++) {
|
||||
sleep(1000)
|
||||
if (currentActivity() != "com.ss.android.ugc.aweme.profile.ui.UserProfileActivity") {
|
||||
if (i == 10) {
|
||||
return false
|
||||
}
|
||||
continue
|
||||
}
|
||||
break
|
||||
}
|
||||
return true
|
||||
},
|
||||
gotoFriend: function () {
|
||||
className("com.bytedance.highperformanceview.layout.MeasureOnceRelativeLayout2").find()[2].click()
|
||||
waitForActivity("com.ss.android.ugc.aweme.following.ui.FollowRelationTabActivity")
|
||||
sleep(2000)
|
||||
return true
|
||||
},
|
||||
getStatistics: function () {
|
||||
let statistics = {
|
||||
like: 0,
|
||||
friend: 0,
|
||||
focus: 0,
|
||||
fans: 0,
|
||||
}
|
||||
className("com.bytedance.highperformanceview.layout.MeasureOnceRelativeLayout2").find().forEach((item, index) => {
|
||||
let tv = item.findOne(className("android.widget.TextView"))
|
||||
if (tv) {
|
||||
let text = tv.text()
|
||||
switch (index) {
|
||||
case 0:
|
||||
statistics.like = parseInt(text)
|
||||
case 1:
|
||||
statistics.focus = parseInt(text)
|
||||
case 2:
|
||||
statistics.fans = parseInt(text)
|
||||
case 3:
|
||||
statistics.friend = parseInt(text)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
store.put("__statistics", statistics)
|
||||
return statistics
|
||||
},
|
||||
hasNewFriend: function () {
|
||||
let statistics = store.get("__statistics", {
|
||||
like: 0,
|
||||
friend: 0,
|
||||
focus: 0,
|
||||
fans: 0,
|
||||
})
|
||||
|
||||
let currentStatistics = this.getStatistics()
|
||||
|
||||
if (currentStatistics.friend > statistics.friend) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
},
|
||||
hasPublishItems: function () {
|
||||
let txt = "还没有作品"
|
||||
let id = "com.ss.android.ugc.aweme:id/title"
|
||||
|
||||
let elem = text(txt).findOne(2 * 1000)
|
||||
if (!elem) {
|
||||
return true
|
||||
}
|
||||
|
||||
return !(elem.id() == id)
|
||||
},
|
||||
|
||||
getBtnGuanZhu: function () {
|
||||
let txt = "关注"
|
||||
let _class = "android.widget.TextView"
|
||||
|
||||
let elems = text(txt).find()
|
||||
if (elems.empty()) {
|
||||
return false
|
||||
}
|
||||
|
||||
let elem = elems.find(className(_class)).findOne(clickable())
|
||||
if (!elem) {
|
||||
return false
|
||||
}
|
||||
|
||||
return elem
|
||||
},
|
||||
getBtnBianJiZiLiao: function () {
|
||||
let _desc = "编辑资料"
|
||||
let _class = "android.view.ViewGroup"
|
||||
|
||||
let elem = className(_class).find().findOne(descStartsWith(_desc))
|
||||
if (!elem) {
|
||||
log("找不到编辑资料")
|
||||
return false
|
||||
}
|
||||
|
||||
return elem
|
||||
},
|
||||
|
||||
getBtnSiXin: function () {
|
||||
let txt = "私信"
|
||||
let desc = "私信"
|
||||
|
||||
let elem = text(txt).findOne(2 * _global_duration)
|
||||
if (!elem) {
|
||||
log("找不到私信按钮")
|
||||
return false
|
||||
}
|
||||
|
||||
if (elem.desc() != desc) {
|
||||
log("私信按钮 desc 不匹配")
|
||||
return false
|
||||
}
|
||||
return elem
|
||||
},
|
||||
|
||||
hasProduce: function () {
|
||||
let _text = "还没有作品"
|
||||
let elem = text(_text).findOne(1000)
|
||||
if (!elem) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
},
|
||||
getIPLocation: function () {
|
||||
let txt = "IP:"
|
||||
|
||||
let elem = textStartsWith(txt).findOne(1000)
|
||||
if (!elem) {
|
||||
log("找不到 IP 标签 id")
|
||||
return false
|
||||
}
|
||||
|
||||
return elem.text().replace(txt, "").trim()
|
||||
},
|
||||
|
||||
clickBtnSiXin: function () {
|
||||
let elem = this.getBtnSiXin()
|
||||
if (!elem) {
|
||||
return false
|
||||
}
|
||||
|
||||
elem.click()
|
||||
sleep(2 * _global_duration)
|
||||
return true
|
||||
},
|
||||
|
||||
clickBtnGuanZhu: function () {
|
||||
let elem = this.getBtnGuanZhu()
|
||||
if (!elem) {
|
||||
return false
|
||||
}
|
||||
|
||||
elem.click()
|
||||
sleep(2 * _global_duration)
|
||||
return true
|
||||
},
|
||||
clickTabMe: function () {
|
||||
let pt = className("android.widget.TextView").find().findOne(text("我")).bounds()
|
||||
click(pt.centerX(), pt.centerY())
|
||||
sleep(1000)
|
||||
},
|
||||
}
|
||||
|
||||
let pageChat = {
|
||||
getBtnVoice: function () {
|
||||
let _desc = "语音"
|
||||
let _class = "android.widget.Button"
|
||||
|
||||
let elem = className(_class).find().findOne(desc(_desc))
|
||||
if (!elem) {
|
||||
return false
|
||||
}
|
||||
return elem
|
||||
},
|
||||
getBtnMyLoveSend: function () {
|
||||
let _txt = "发送"
|
||||
let _id = "com.ss.android.ugc.aweme:id/send"
|
||||
|
||||
let elem = id(_id).findOne(2 * _global_duration)
|
||||
if (!elem) {
|
||||
log("找不到发送按钮")
|
||||
return false
|
||||
}
|
||||
|
||||
return elem
|
||||
},
|
||||
getMyLoveFirstProduct: function () {
|
||||
let _class = "com.bytedance.ies.dmt.ui.widget.DmtTextView";
|
||||
let loves = className(_class).find()
|
||||
if (loves.empty()) {
|
||||
log("找不到我的喜欢")
|
||||
return false
|
||||
}
|
||||
|
||||
return loves.shift()
|
||||
},
|
||||
getMyLoveButton: function () {
|
||||
let _txt = "我的喜欢"
|
||||
let elem = null;
|
||||
|
||||
let times = 0
|
||||
while (times++ < 10) {
|
||||
elem = className("android.widget.Button").find().findOne(desc(_txt))
|
||||
if (elem) {
|
||||
return elem
|
||||
}
|
||||
|
||||
elem = className("android.widget.TextView").find().findOne(text(_txt))
|
||||
if (!elem) {
|
||||
sleep(1000)
|
||||
continue
|
||||
}
|
||||
elem = elem.parent()
|
||||
break
|
||||
}
|
||||
|
||||
if (times > 10) {
|
||||
log("找不到 我的喜欢 按钮")
|
||||
return false
|
||||
}
|
||||
|
||||
return elem
|
||||
},
|
||||
getPanelMore: function () {
|
||||
let _class = "androidx.viewpager.widget.ViewPager"
|
||||
|
||||
let elem = className(_class).findOne(2 * _global_duration)
|
||||
if (!elem) {
|
||||
log("找不到 更多面板")
|
||||
return false
|
||||
}
|
||||
|
||||
return elem
|
||||
},
|
||||
getBtnCloseMore: function () {
|
||||
let _desc = "关闭面板"
|
||||
let _class = "android.widget.Button"
|
||||
|
||||
let elem = className(_class).find().findOne(desc(_desc))
|
||||
if (!elem) {
|
||||
log("找不到关闭面板按钮")
|
||||
return false
|
||||
}
|
||||
|
||||
return elem
|
||||
},
|
||||
getBtnMore: function () {
|
||||
let _desc = "更多面板"
|
||||
let _class = "android.widget.Button"
|
||||
|
||||
let elem = className(_class).find().findOne(desc(_desc))
|
||||
if (!elem) {
|
||||
log("找不到更多面板按钮")
|
||||
return false
|
||||
}
|
||||
// log(elem.id())
|
||||
|
||||
return elem
|
||||
},
|
||||
clickBtnCloseMore: function () {
|
||||
let elem = this.getBtnCloseMore()
|
||||
if (!elem) {
|
||||
return false
|
||||
}
|
||||
|
||||
log("点击更多按钮")
|
||||
elem.click()
|
||||
sleep(_global_duration)
|
||||
return true
|
||||
},
|
||||
clickBtnMore: function () {
|
||||
if (desc("关闭面板").findOne(2 * _global_duration)) {
|
||||
return true
|
||||
}
|
||||
|
||||
let elem = this.getBtnMore()
|
||||
if (!elem) {
|
||||
return false
|
||||
}
|
||||
|
||||
elem.click()
|
||||
sleep(2 * _global_duration)
|
||||
return true
|
||||
},
|
||||
swipeMorePanelRight: function () {
|
||||
let elem = this.getPanelMore()
|
||||
if (!elem) {
|
||||
return false
|
||||
}
|
||||
|
||||
// elem.scrollLeft()
|
||||
let x = elem.bounds().centerX() + elem.bounds().width() / 4
|
||||
let y = elem.bounds().centerY()
|
||||
let x1 = elem.bounds().left
|
||||
let y1 = elem.bounds().centerY()
|
||||
log(x, y, x1, y1)
|
||||
swipe(x, y, x1, y1, 200)
|
||||
sleep(_global_duration)
|
||||
return true
|
||||
},
|
||||
swipeMorePanelLeft: function () {
|
||||
let elem = this.getPanelMore()
|
||||
if (!elem) {
|
||||
return false
|
||||
}
|
||||
|
||||
let x = elem.bounds().centerX() - elem.bounds().width() / 4
|
||||
let y = elem.bounds().centerY()
|
||||
let x1 = elem.bounds().right
|
||||
let y1 = elem.bounds().centerY()
|
||||
log(x, y, x1, y1)
|
||||
swipe(x, y, x1, y1, 200)
|
||||
sleep(_global_duration)
|
||||
return true
|
||||
},
|
||||
|
||||
clickBtnMyLove: function () {
|
||||
let elem = this.getMyLoveButton()
|
||||
if (!elem) {
|
||||
return false
|
||||
}
|
||||
|
||||
elem.click()
|
||||
// click(elem.bounds().centerX(), elem.bounds().centerY())
|
||||
sleep(_global_duration)
|
||||
return true
|
||||
},
|
||||
clickBtnMyLoveFirstProduct: function () {
|
||||
let elem = this.getMyLoveFirstProduct()
|
||||
if (!elem) {
|
||||
return false
|
||||
}
|
||||
|
||||
log(elem.className())
|
||||
click(elem.bounds().centerX(), elem.bounds().centerY())
|
||||
sleep(_global_duration)
|
||||
return true
|
||||
},
|
||||
clickBtnMyLoveSend: function () {
|
||||
let elem = this.getBtnMyLoveSend()
|
||||
if (!elem) {
|
||||
return false
|
||||
}
|
||||
|
||||
elem.click()
|
||||
sleep(_global_duration)
|
||||
return true
|
||||
},
|
||||
pressBtnVoice: function (duration) {
|
||||
let elem = this.getBtnVoice()
|
||||
if (!elem) {
|
||||
return false
|
||||
}
|
||||
|
||||
press(elem.bounds().centerX(), elem.bounds().centerY(), duration)
|
||||
sleep(_global_duration)
|
||||
return true
|
||||
},
|
||||
sendAudioVoice: function (voice) {
|
||||
let elem = this.getBtnVoice()
|
||||
if (!elem) {
|
||||
log("找不到 语音 按钮")
|
||||
return false
|
||||
}
|
||||
|
||||
var musicDuration = threads.disposable();
|
||||
threads.start(function () {
|
||||
sleep(500)
|
||||
//播放音乐
|
||||
media.playMusic(files.path(`audio/${voice}.m4a`));
|
||||
media.pauseMusic()
|
||||
|
||||
//让音乐播放完
|
||||
let duration = media.getMusicDuration()
|
||||
musicDuration.setAndNotify(duration)
|
||||
sleep(500)
|
||||
media.resumeMusic()
|
||||
|
||||
sleep(duration);
|
||||
});
|
||||
|
||||
let duration = musicDuration.blockedGet()
|
||||
|
||||
press(elem.bounds().centerX(), elem.bounds().centerY(), 1000 + duration)
|
||||
sleep(_global_duration)
|
||||
return true
|
||||
|
||||
},
|
||||
isSendVoiceMode: function () {
|
||||
let _txt = "按住 说话"
|
||||
return text(_txt).findOne(2 * _global_duration)
|
||||
},
|
||||
getBtnVoiceToTxt: function () {
|
||||
return desc("文本").findOne(2 * _global_duration)
|
||||
},
|
||||
getInputSendTxt: function () {
|
||||
return text("发送消息").findOne(2 * _global_duration)
|
||||
},
|
||||
clickInputSendTxt: function () {
|
||||
let elem = this.getInputSendTxt()
|
||||
if (!elem) {
|
||||
log("找不到发送消息输入框")
|
||||
return false
|
||||
}
|
||||
|
||||
elem.click()
|
||||
sleep(_global_duration)
|
||||
return true
|
||||
},
|
||||
getBtnSendTxt: function () {
|
||||
return desc('发送').findOne(2 * _global_duration)
|
||||
},
|
||||
sendText: function (txt) {
|
||||
if (this.isSendVoiceMode()) {
|
||||
let elem = this.getBtnVoiceToTxt()
|
||||
if (!elem) {
|
||||
return false
|
||||
}
|
||||
elem.click()
|
||||
sleep(_global_duration)
|
||||
}
|
||||
|
||||
elem = this.getInputSendTxt()
|
||||
if (!elem) {
|
||||
log("找不到发送消息输入框")
|
||||
return false
|
||||
}
|
||||
|
||||
elem.setText(txt)
|
||||
sleep(_global_duration)
|
||||
|
||||
if (!this.getBtnSendTxt().click()) {
|
||||
log("找不到发送按钮")
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
let pageFriend = {
|
||||
activity: "com.ss.android.ugc.aweme.following.ui.FollowRelationTabActivity",
|
||||
wait: function () {
|
||||
lib.waitForActivity(_activity)
|
||||
},
|
||||
open: function () {
|
||||
// app.startActivity(this.activity)
|
||||
},
|
||||
getFriends: function () {
|
||||
let userList = [];
|
||||
|
||||
text("发私信").find().forEach((item, idx) => {
|
||||
let name = item.parent().parent().child(1).child(0).child(0).text()
|
||||
// log("check name exists", name)
|
||||
if (db.existsUser(name)) {
|
||||
return
|
||||
}
|
||||
|
||||
userList.push({ button: item, name: name })
|
||||
})
|
||||
return userList
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
let st = {
|
||||
times: function (times) {
|
||||
if (times != undefined) {
|
||||
return store.put('__times', times)
|
||||
}
|
||||
return store.get('__times', 0)
|
||||
},
|
||||
addTimes: function () {
|
||||
return store.put('__times', this.times() + 1)
|
||||
},
|
||||
voice: function (voice) {
|
||||
if (voice != undefined) {
|
||||
return store.put('__voice', voice)
|
||||
}
|
||||
return store.get('__voice', "default")
|
||||
},
|
||||
produce: function (produce) {
|
||||
if (produce != undefined) {
|
||||
return store.put('__produce', produce)
|
||||
}
|
||||
return store.get('__produce', false)
|
||||
},
|
||||
name_keyword: function (keyword) {
|
||||
if (keyword != undefined) {
|
||||
return store.put('__name_keyword', keyword)
|
||||
}
|
||||
return store.get('__name_keyword', [])
|
||||
},
|
||||
default_avatar: function (avatar) {
|
||||
if (avatar != undefined) {
|
||||
return store.put('__default_avatar', avatar)
|
||||
}
|
||||
return store.get('__default_avatar', false)
|
||||
},
|
||||
default_name: function (name) {
|
||||
if (name != undefined) {
|
||||
return store.put('__default_name', name)
|
||||
}
|
||||
return store.get('__default_name', false)
|
||||
},
|
||||
region: function (region) {
|
||||
if (region != undefined) {
|
||||
return store.put('__region', region)
|
||||
}
|
||||
return store.get('__region', [])
|
||||
},
|
||||
wechat: function (wechat) {
|
||||
if (wechat != undefined) {
|
||||
return store.put('__wechat', wechat)
|
||||
}
|
||||
return store.get('__wechat', "")
|
||||
},
|
||||
hello: function (hello) {
|
||||
if (hello != undefined) {
|
||||
return store.put('__hello', hello)
|
||||
}
|
||||
return store.get('__hello', "你好")
|
||||
},
|
||||
host: function (h) {
|
||||
if (h) {
|
||||
store.put("__host", h)
|
||||
return h
|
||||
}
|
||||
|
||||
let host = store.get("__host", "")
|
||||
if (host.length == 0) {
|
||||
host = "https://f.jdwan.com"
|
||||
store.put("__host", host)
|
||||
}
|
||||
return host
|
||||
},
|
||||
lastID: function (id) {
|
||||
if (id) {
|
||||
return store.put('__lastID', id)
|
||||
}
|
||||
return store.get('__lastID', 0)
|
||||
},
|
||||
config_version: function (version) {
|
||||
if (version) {
|
||||
return store.put('__configVersion', version)
|
||||
}
|
||||
return store.get('__configVersion', 0)
|
||||
},
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
duration: 1000,
|
||||
global: global,
|
||||
page: {
|
||||
user: pageUser,
|
||||
chat: pageChat,
|
||||
friend: pageFriend,
|
||||
},
|
||||
store: st,
|
||||
kill: function () {
|
||||
let name = consts.Package.DouYin
|
||||
app.openAppSetting(name);//通过包名打开应用的详情页(设置页)
|
||||
text(app.getAppName(name)).waitFor();//通过包名获取已安装的应用名称,判断是否已经跳转至该app的应用设置界面
|
||||
sleep(500);//稍微休息一下,不然看不到运行过程,自己用时可以删除这行
|
||||
let is_sure = textMatches(/(.*强.*|.*停.*|.*结.*)/).findOne();//在app的应用设置界面找寻包含“强”,“停”,“结”,“行”的控件
|
||||
//特别注意,应用设置界面可能存在并非关闭该app的控件,但是包含上述字样的控件,如果某个控件包含名称“行”字
|
||||
//textMatches(/(.*强.*|.*停.*|.*结.*|.*行.*)/)改为textMatches(/(.*强.*|.*停.*|.*结.*)/)
|
||||
//或者结束应用的控件名为“结束运行”直接将textMatches(/(.*强.*|.*停.*|.*结.*|.*行.*)/)改为text("结束运行")
|
||||
|
||||
if (is_sure.enabled()) {//判断控件是否已启用(想要关闭的app是否运行)
|
||||
is_sure.parent().click();//结束应用的控件如果无法点击,需要在布局中找寻它的父控件,如果还无法点击,再上一级控件,本案例就是控件无法点击
|
||||
textMatches(/(.*确.*|.*定.*)/).findOne().click();//需找包含“确”,“定”的控件
|
||||
log(app.getAppName(name) + "应用已被关闭");
|
||||
sleep(1000);
|
||||
back();
|
||||
} else {
|
||||
log(app.getAppName(name) + "应用不能被正常关闭或不在后台运行");
|
||||
back();
|
||||
}
|
||||
},
|
||||
}
|
||||
60
main.js
Normal file
60
main.js
Normal file
@@ -0,0 +1,60 @@
|
||||
let db = require("./core.sqlite.js")
|
||||
let request = require("./core.request.js")
|
||||
let lib = require("./lib.js")
|
||||
const message = require("./message.js")
|
||||
let msg = require("./message.js")
|
||||
let flow = require("./flow.js")
|
||||
let flowUser = require("./flow_user.js")
|
||||
let runner = require("./runner.js")
|
||||
|
||||
function logItem(item, index) {
|
||||
if (!item) {
|
||||
return
|
||||
}
|
||||
if (index !== undefined) {
|
||||
log(`----------[ ${index} ]--------------`)
|
||||
} else {
|
||||
log("------------------------")
|
||||
}
|
||||
log("TEXT: ", item.text())
|
||||
log("DESC: ", item.desc())
|
||||
log("ID: ", item.id())
|
||||
log("CLASS:", item.className())
|
||||
|
||||
}
|
||||
log("ACTIVITY: ", currentActivity())
|
||||
log("PACKAGE : ", currentPackage())
|
||||
|
||||
|
||||
//
|
||||
// let _class = "android.widget.Button"
|
||||
// let _desc = "设置"
|
||||
// let _text = "还没有作品"
|
||||
// text(_text).find().forEach((item, idx) => {
|
||||
// logItem(item, idx)
|
||||
// })
|
||||
|
||||
// runner.Run()
|
||||
// lib.store.host("https://f.jdwan.com")
|
||||
// request.getOneUser()
|
||||
|
||||
// let body = request.updateConfig("102189147098")
|
||||
// log(lib.store.hello())
|
||||
// log(lib.store.voice())
|
||||
// log(lib.store.wechat())
|
||||
// log(lib.store.region())
|
||||
// log(lib.store.produce())
|
||||
// log(lib.store.default_name())
|
||||
// log(lib.store.default_avatar())
|
||||
|
||||
let txt = `
|
||||
11111
|
||||
22222
|
||||
33333
|
||||
44444`
|
||||
|
||||
let hellos = txt.split("\n").filter((i) => i.trim().length > 0)
|
||||
// let hello = hellos[Math.floor(Math.random() * hellos.length)]
|
||||
//random by current timestamp
|
||||
let hello = hellos[new Date().getTime() % hellos.length]
|
||||
log(hello)
|
||||
57
message.js
Normal file
57
message.js
Normal file
@@ -0,0 +1,57 @@
|
||||
let messages = [
|
||||
[
|
||||
"你好,是要男性健康方面的问题吗",
|
||||
"{voice}",
|
||||
"十我详谈吧,这里敏感词太多",
|
||||
"这里敏感词多",
|
||||
"这里有时候不常在,消息回复不及时",
|
||||
],
|
||||
[
|
||||
"{wechat}"
|
||||
],
|
||||
[
|
||||
"↑微訫号",
|
||||
"微訫号",
|
||||
"↑微訫号",
|
||||
"↑徽沁",
|
||||
"↑微沁",
|
||||
],
|
||||
[
|
||||
"十了说一下给你通过",
|
||||
"加上一对一给你解答",
|
||||
"加上详谈",
|
||||
"伽上詳談",
|
||||
"加上详细沟通一下你的情况",
|
||||
]
|
||||
];
|
||||
module.exports = {
|
||||
get: function () {
|
||||
let msg = [];
|
||||
for (let i = 0; i < messages.length; i++) {
|
||||
let item = messages[i]
|
||||
if (item.length == 1) {
|
||||
msg.push(item[0])
|
||||
continue
|
||||
}
|
||||
msg.push(item[Math.floor(Math.random() * item.length)])
|
||||
}
|
||||
|
||||
return msg.map((item) => {
|
||||
let voice = lib.store.voice()
|
||||
if (item == "{voice}") {
|
||||
if (voice == 'default') {
|
||||
return false
|
||||
}
|
||||
return { type: "voice", data: voice }
|
||||
}
|
||||
|
||||
item = item.replace("{wechat}", lib.store.wechat())
|
||||
return {
|
||||
type: "text",
|
||||
data: item
|
||||
}
|
||||
}).filter((item) => {
|
||||
return item !== false
|
||||
})
|
||||
}
|
||||
}
|
||||
59
project.json
Normal file
59
project.json
Normal file
@@ -0,0 +1,59 @@
|
||||
{
|
||||
"abis": [
|
||||
"arm64-v8a",
|
||||
"armeabi-v7a",
|
||||
"x86",
|
||||
"x86_64"
|
||||
],
|
||||
"assets": [
|
||||
{
|
||||
"form": "/storage/emulated/0/脚本/autojs/boot",
|
||||
"to": "/project"
|
||||
}
|
||||
],
|
||||
"buildDir": "build",
|
||||
"build": {
|
||||
"build_id": null,
|
||||
"build_number": 0,
|
||||
"build_time": 0
|
||||
},
|
||||
"useFeatures": [],
|
||||
"icon": "res/logo.png",
|
||||
"ignoredDirs": [
|
||||
"build"
|
||||
],
|
||||
"encrypt-code": false,
|
||||
"launchConfig": {
|
||||
"displaySplash": true,
|
||||
"hideAccessibilityServices": false,
|
||||
"hideLauncher": false,
|
||||
"hideLogs": false,
|
||||
"stableMode": false,
|
||||
"volumeUpcontrol": true,
|
||||
"permissions": [
|
||||
"accessibility_services",
|
||||
"background_start",
|
||||
"draw_overlay"
|
||||
],
|
||||
"serviceDesc": "自动操作",
|
||||
"splashIcon": "res/splashIcon.png",
|
||||
"splashText": "请合理使用"
|
||||
},
|
||||
"libs": [
|
||||
"libjackpal-androidterm5.so",
|
||||
"libjackpal-termexec2.so"
|
||||
],
|
||||
"main": "main.js",
|
||||
"name": "PowerBank",
|
||||
"outputPath": "/storage/emulated/0/脚本/autojs/boot/build",
|
||||
"packageName": "com.power.bank",
|
||||
"projectDirectory": "/storage/emulated/0/脚本/autojs/boot",
|
||||
"scripts": {},
|
||||
"signingConfig": {
|
||||
"alias": null,
|
||||
"keystore": null
|
||||
},
|
||||
"sourcePath": "/storage/emulated/0/脚本/autojs/main.js",
|
||||
"versionCode": 1,
|
||||
"versionName": "1.0.0"
|
||||
}
|
||||
12
readme.md
Normal file
12
readme.md
Normal file
@@ -0,0 +1,12 @@
|
||||
|
||||
## TODO
|
||||
[ ] 私密账号需要对方通过才能发私信
|
||||
|
||||
|
||||
## 安装过程
|
||||
1. 安装应用
|
||||
1.1 安装过程中会报病毒,忽略即可。
|
||||
2. 开启无障碍
|
||||
3. 账号配置
|
||||
3.1 添加喜欢视频
|
||||
|
||||
53
runner.js
Normal file
53
runner.js
Normal file
@@ -0,0 +1,53 @@
|
||||
let lib = require("./lib.js")
|
||||
let flow = require("./flow.js")
|
||||
let flowUser = require("./flow_user.js")
|
||||
let request = require("./core.request.js")
|
||||
|
||||
let Run = function () {
|
||||
if (currentPackage() !== "com.miui.home") {
|
||||
toastLog("返回桌面")
|
||||
home()
|
||||
sleep(1000)
|
||||
}
|
||||
|
||||
// lib.store.times(10)
|
||||
|
||||
toastLog("打开用户主页")
|
||||
if (!flowUser.GoToYongHuZhuYe()) {
|
||||
toastLog("打开用户主页 失败")
|
||||
return false
|
||||
}
|
||||
|
||||
while (true) {
|
||||
let times = lib.store.times()
|
||||
log("times = ", times)
|
||||
|
||||
let delta = 0
|
||||
try {
|
||||
if (times % 5 === 0) {
|
||||
lib.store.times(1)
|
||||
flow.FaSongHuGuanXiaoXi()
|
||||
} else {
|
||||
let start = Math.floor((new Date()).getTime() / 1000)
|
||||
flow.HuoQuYongHuBingGuanZhuFaSiXin()
|
||||
let end = Math.floor((new Date()).getTime() / 1000)
|
||||
delta = end - start
|
||||
lib.store.addTimes()
|
||||
}
|
||||
} catch (e) {
|
||||
log("ERROR:", e)
|
||||
}
|
||||
|
||||
if (delta < 3) {
|
||||
sleep(5000)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof module !== "undefined") {
|
||||
module.exports = {
|
||||
Run
|
||||
}
|
||||
} else {
|
||||
Run()
|
||||
}
|
||||
Reference in New Issue
Block a user