feat: init

This commit is contained in:
Rogee
2024-09-30 10:59:36 +08:00
parent 8ce06f9a00
commit b05c9ada1b
31 changed files with 2006 additions and 0 deletions

BIN
audio/caixueying.m4a Normal file

Binary file not shown.

BIN
audio/chenhong.m4a Normal file

Binary file not shown.

BIN
audio/dubaojun.m4a Normal file

Binary file not shown.

BIN
audio/genghonghai.m4a Normal file

Binary file not shown.

BIN
audio/liliuji.m4a Normal file

Binary file not shown.

BIN
audio/liudong.m4a Normal file

Binary file not shown.

BIN
audio/liulianqi.m4a Normal file

Binary file not shown.

BIN
audio/wangguozhong.m4a Normal file

Binary file not shown.

BIN
audio/xueyongdong.m4a Normal file

Binary file not shown.

BIN
audio/yaobaosen.m4a Normal file

Binary file not shown.

BIN
audio/zhangguangsheng.m4a Normal file

Binary file not shown.

BIN
audio/zhangzhaofa.m4a Normal file

Binary file not shown.

139
boot/main.js Normal file
View 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
View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

BIN
boot/res/splashIcon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

10
consts.js Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View File

@@ -0,0 +1,12 @@
## TODO
[ ] 私密账号需要对方通过才能发私信
## 安装过程
1. 安装应用
1.1 安装过程中会报病毒,忽略即可。
2. 开启无障碍
3. 账号配置
3.1 添加喜欢视频

53
runner.js Normal file
View 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()
}