feat: init
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+139
@@ -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)
|
||||
@@ -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"
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 24 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 24 KiB |
@@ -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"
|
||||
},
|
||||
}
|
||||
@@ -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
@@ -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,
|
||||
}
|
||||
@@ -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,
|
||||
}
|
||||
@@ -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,
|
||||
}
|
||||
@@ -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
@@ -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,
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
},
|
||||
}
|
||||
@@ -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
@@ -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
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
|
||||
## TODO
|
||||
[ ] 私密账号需要对方通过才能发私信
|
||||
|
||||
|
||||
## 安装过程
|
||||
1. 安装应用
|
||||
1.1 安装过程中会报病毒,忽略即可。
|
||||
2. 开启无障碍
|
||||
3. 账号配置
|
||||
3.1 添加喜欢视频
|
||||
|
||||
@@ -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