Continue seeded Qinglong script collection

This commit is contained in:
Hermes Agent
2026-05-24 05:33:05 +00:00
parent ca1a4275e4
commit b082da3fe1
392 changed files with 131619 additions and 7 deletions

View File

@@ -0,0 +1,342 @@
// # Source: https://github.com/sudojia/AutoTaskScript/blob/script/src/client/sudojia_xiangwan.js
// # Raw: https://raw.githubusercontent.com/sudojia/AutoTaskScript/script/src/client/sudojia_xiangwan.js
// # Repo: sudojia/AutoTaskScript
// # Path: src/client/sudojia_xiangwan.js
// # UploadedAt: 2025-04-28T19:26:13+08:00
// # SHA256: 659341f6d90da24ae84aff1ca890993bb08f62f22537ed7eca9ee139ad06e61d
// # Category: APP版/账密
// # Evidence: username/password/mobile/login
//
/**
* 享玩游戏APP
* 下载链接https://dl.duoyou.com/fenapk/xwshare/xw_100016.apk?version=1.3
*
* 会员v0起始签到 10 个玩豆,连续签到递增 1 玩豆,最高签到 15 个玩豆
* 会员v1-2起始 15最高 20
* ...
* 会员v10起始 75最高 80
* 具体自行查看签到规则
*
* 以会员v0来计算包含连签奖励
* 10 玩豆 兑换 0.1 现金,
* 500 玩豆 兑换 5 现金,大约需 21 天
* 1000 玩豆 兑换 10 现金,大约需 30 天
* 5000 玩豆 兑换 50 现金,大约需 200 天
* 10000 玩豆 兑换 100现金大约需 381 天
* 30000 玩豆 兑换 300 现金,大约需 1135 天 😂😂😂
*
* export XWGAME_ACCOUNTS = '手机号#密码'
* 多账号用 & 或换行
*
* @author Telegram@sudojia
* @site https://blog.imzjw.cn
* @date 2025/02/25
*
* const $ = new Env('享玩游戏APP')
* cron: 33 0 * * *
*/
const initScript = require('../utils/initScript')
const {$, notify, sudojia, checkUpdate} = initScript('享玩游戏APP');
const crypto = require('crypto');
const moment = require('moment');
const fs = require('fs').promises;
const path = require('path');
const xiangWanList = process.env.XWGAME_ACCOUNTS ? process.env.XWGAME_ACCOUNTS.split(/[\n&]/) : [];
// 消息推送
let message = '';
// token 缓存地址
const TOKEN_CACHE_PATH = path.join(__dirname, 'xiangwan_token_cache.json');
// 接口地址
const baseUrl = 'https://sdk-api.xiangwan.com'
// 加密秘钥Base64
const keyBase64 = '5snOI0E5WUpP99pG5+fzug==';
// 解码 Base64 得到原始的二进制密钥
const key = Buffer.from(keyBase64, 'base64');
// 加密 IvBase64
const ivBase64 = 'KhVRUtkYTNM82dSDxb7/YQ==';
// 解码 Base64 得到原始的二进制 IV
const iv = Buffer.from(ivBase64, 'base64');
// 请求头
const headers = {
'User-Agent': 'okhttp/4.11.0',
'Accept-Encoding': 'gzip',
'Content-Type': 'application/x-www-form-urlencoded'
};
!(async () => {
await checkUpdate($.name, xiangWanList);
for (let i = 0; i < xiangWanList.length; i++) {
const index = i + 1;
const [account, pwd] = xiangWanList[i].split('#');
console.log(`\n*****第[${index}]个${$.name}账号*****`);
await login(account, pwd);
if (!$.isLogin) {
continue;
}
await $.wait(sudojia.getRandomWait(1e3, 2e3));
message += `📣====${$.name}账号[${index}]====📣\n`;
await main();
await $.wait(sudojia.getRandomWait(2000, 2500));
}
if (message) {
await notify.sendNotify(`${$.name}`, `${message}`);
}
})().catch((e) => $.logErr(e)).finally(() => $.done());
async function main() {
await sign();
await $.wait(sudojia.getRandomWait(1e3, 2e3));
await getUserInfo();
}
/**
* 登录
*
* @param account
* @param password
* @returns {Promise<void>}
*/
async function login(account, password) {
try {
let cachedToken = await getTokenFromCache("xiangwan", account);
if (cachedToken) {
headers.authorization = `Bearer ${cachedToken}`;
console.log('使用缓存 token 登录,验证中...');
const isValid = await validateToken(cachedToken);
await $.wait(sudojia.getRandomWait(2e3, 3e3));
if (isValid) {
$.isLogin = true;
console.log('token 验证有效✅');
return;
} else {
console.log('缓存 token 验证失效,开始重新登录更新 token...');
}
}
const encryptData = await sudojia.sendRequest(`${baseUrl}/account/account_login`, 'post', headers, {
"params": encryptCredentials(JSON.stringify({
...getCommonParams(),
account: account,
password: password
}))
});
const decryptData = JSON.parse(decryptCredentials(encryptData));
if (200 !== decryptData.status_code) {
$.isLogin = false;
return console.error(`登录失败 ->`, decryptData);
}
console.log('登录成功~');
headers.authorization = `Bearer ${decryptData.data.token}`;
$.isLogin = true;
// 保存 token 到文件
await saveTokenToCache("xiangwan", account, decryptData.data.token);
} catch (e) {
$.isLogin = false;
if (e.response || e.response.data) {
console.error(`登录时发生异常 ->`, e.response.data);
} else {
console.error(`登录时发生异常 ->`, e);
}
}
}
/**
* 签到
*
* @returns {Promise<void>}
*/
async function sign() {
try {
console.log('\n开始执行...');
await $.wait(sudojia.getRandomWait(1e3, 2e3));
const days = moment().format('YYYYMMDD');
const encryptData = await sudojia.sendRequest(`${baseUrl}/discover/sign`, 'post', headers, {
"params": encryptCredentials(JSON.stringify({
...getCommonParams(),
"days": days
}))
});
const decryptData = JSON.parse(decryptCredentials(encryptData));
if (200 !== decryptData.status_code) {
message += `签到失败 -> ${decryptData.message}\n`;
return console.error(`签到失败 ->`, decryptData.message);
}
console.log(`签到成功,恭喜获得:${decryptData.data.score}玩豆`);
message += `签到成功,恭喜获得:${decryptData.data.score}玩豆\n`;
} catch (e) {
console.error(`签到时发生异常 ->`, e);
}
}
/**
* 获取用户信息
*
* @returns {Promise<void>}
*/
async function getUserInfo() {
try {
const encryptData = await sudojia.sendRequest(`${baseUrl}/me/member_info`, 'post', headers, {
"params": encryptCredentials(JSON.stringify({
...getCommonParams()
}))
});
const decryptData = JSON.parse(decryptCredentials(encryptData));
if (200 !== decryptData.status_code) {
return console.error(`获取用户信息时发生异常 ->`, decryptData);
}
const {nickname, mobile, balance} = decryptData.data;
const hiddenMobile = `${mobile.slice(0, 3)}***${mobile.slice(-3)}` || 18888888888;
const displayName = nickname || "吴彦祖";
console.log(`${displayName}(${hiddenMobile})`);
console.log(`当前玩豆:${balance}`);
message += `${nickname}(${hiddenMobile})\n`;
message += `当前玩豆:${balance}\n\n`;
} catch (e) {
console.error(`获取用户信息时发生异常 ->`, e);
}
}
/**
* 验证 token 是否有效
*
* @param token
* @returns {Promise<boolean>}
*/
async function validateToken(token) {
try {
const encryptData = await sudojia.sendRequest(`${baseUrl}/me/member_account`, 'post', {
authorization: `Bearer ${token}`
}, {
"params": encryptCredentials(JSON.stringify({
...getCommonParams()
}))
});
const decryptData = JSON.parse(decryptCredentials(encryptData));
return 200 === decryptData.status_code;
} catch (error) {
console.error('验证 token 时发生异常:', error);
return false;
}
}
/**
* 获取公共请求参数
*
* @returns {Object} 包含公共请求参数的对象
*/
function getCommonParams() {
return {
"app_channel": "xw_100016",
"app_version": "1.3",
"invite_uid": "",
"app_os": "android",
"server_device_id": "176"
};
}
/**
* 加密请求数据
*
* @returns {string} 加密后的Base64字符串
*/
function encryptCredentials(plainText) {
// 创建加密器
const cipher = crypto.createCipheriv('aes-128-cbc', key, iv);
// 加密数据
let encrypted = cipher.update(plainText, 'utf8', 'base64');
encrypted += cipher.final('base64');
return encrypted;
}
/**
* 解密响应数据
*
* @param encryptedText
* @returns {string}
*/
function decryptCredentials(encryptedText) {
// 创建解密器
const decipher = crypto.createDecipheriv('aes-128-cbc', key, iv);
// 解密数据
let decrypted = decipher.update(encryptedText, 'base64', 'utf8');
decrypted += decipher.final('utf8');
return decrypted;
}
/**
* 从文件中读取 token
*
* @param platform
* @param username
* @returns {Promise<*|null>}
*/
async function getTokenFromCache(platform, username) {
try {
try {
// 检查文件是否存在
await fs.access(TOKEN_CACHE_PATH);
} catch (error) {
console.warn('token 缓存文件不存在,创建一个空文件...');
await fs.writeFile(TOKEN_CACHE_PATH, JSON.stringify({}, null, 2), 'utf8');
return null;
}
const cache = await fs.readFile(TOKEN_CACHE_PATH, 'utf-8');
// 检查文件内容是否为空
if (!cache.trim()) {
console.warn('token 缓存文件内容为空,开始重新登录生成 token 内容');
return null;
}
let cacheObj;
try {
cacheObj = JSON.parse(cache);
} catch (parseError) {
console.error('解析 token 缓存文件失败:', parseError);
return null; // 解析失败时返回 null
}
// 检查平台和用户名是否存在
if (cacheObj[platform] && cacheObj[platform][username]) {
return cacheObj[platform][username];
} else {
console.warn(`token 缓存文件中未找到[${username}]的账号,开始重新登录生成 token`);
return null;
}
} catch (error) {
console.error('读取缓存文件失败:', error);
return null;
}
}
/**
* 将 token 保存到文件
*
* @param platform
* @param username
* @param token
*
* @returns {Promise<void>}
*/
async function saveTokenToCache(platform, username, token) {
try {
let cacheObj = {};
try {
const cache = await fs.readFile(TOKEN_CACHE_PATH, 'utf-8');
if (cache.trim()) {
cacheObj = JSON.parse(cache);
} else {
console.warn('token 缓存文件内容为空,开始初始化为空对象...');
}
} catch (error) {
console.warn('读取缓存文件失败,初始化为空对象:', error);
}
if (!cacheObj[platform]) {
cacheObj[platform] = {};
}
cacheObj[platform][username] = token;
await fs.writeFile(TOKEN_CACHE_PATH, JSON.stringify(cacheObj, null, 2), 'utf-8');
console.log('token 已保存到缓存文件[xiangwan_token_cache.json]');
console.log(`路径:${TOKEN_CACHE_PATH}`);
} catch (error) {
console.error('保存 token 失败:', error);
}
}