Files
clone_scripts_clone/jd_cfd1.ts
2021-07-13 09:33:42 -04:00

388 lines
14 KiB
TypeScript
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 京喜财富岛
* 包含雇佣导游建议每小时1次
*
* 此版本暂定默认帮助HelloWorld帮助助力池
* export CFD_HELP_HW = true // 帮助HelloWorld
* export CFD_HELP_POOL = true // 帮助助力池
*
* 使用jd_env_copy.js同步js环境变量到ts
* 使用jd_ts_test.ts测试环境变量
*/
import {format} from 'date-fns';
import axios from 'axios';
import USER_AGENT from './TS_USER_AGENTS';
import {Md5} from 'ts-md5'
import * as dotenv from 'dotenv';
const CryptoJS = require('crypto-js')
dotenv.config()
let appId: number = 10028, fingerprint: string | number, token: string, enCryptMethodJD: any;
let cookie: string = '', cookiesArr: Array<string> = [], res: any = '', shareCodes: string[] = [];
let CFD_HELP_HW: string = process.env.CFD_HELP_HW ? process.env.CFD_HELP_HW : "true";
console.log('帮助HelloWorld:', CFD_HELP_HW)
let CFD_HELP_POOL: string = process.env.CFD_HELP_POOL ? process.env.CFD_HELP_POOL : "true";
console.log('帮助助力池:', CFD_HELP_POOL)
let UserName: string, index: number, isLogin: boolean, nickName: string
!(async () => {
await requestAlgo();
await requireConfig();
for (let i = 0; i < cookiesArr.length; i++) {
cookie = cookiesArr[i];
UserName = decodeURIComponent(cookie.match(/pt_pin=([^;]*)/)![1])
index = i + 1;
isLogin = true;
nickName = '';
console.log(`\n开始【京东账号${index}${nickName || UserName}\n`);
try {
await makeShareCodes();
} catch (e) {
console.log(e)
}
let dwUserId: number = 1
// 助力奖励
while (1) {
res = await api('story/helpdraw', '_cfd_t,bizCode,dwEnv,dwUserId,ptag,source,strZone', {dwUserId: dwUserId})
dwUserId++
if (res.iRet === 0) {
console.log('助力奖励领取成功', res.Data.ddwCoin)
} else if (res.iRet === 1000)
break
else {
console.log('助力奖励领取其他错误:', res)
break
}
await wait(2000)
}
// 清空背包
res = await api('story/querystorageroom', '_cfd_t,bizCode,dwEnv,ptag,source,strZone')
let bags: number[] = []
for (let s of res.Data.Office) {
console.log(s.dwCount, s.dwType)
bags.push(s.dwType)
bags.push(s.dwCount)
}
await wait(1000)
let strTypeCnt: string = ''
for (let n = 0; n < bags.length; n++) {
if (n % 2 === 0)
strTypeCnt += `${bags[n]}:`
else
strTypeCnt += `${bags[n]}|`
}
if (bags.length !== 0) {
res = await api('story/sellgoods', '_cfd_t,bizCode,dwEnv,dwSceneId,ptag,source,strTypeCnt,strZone',
{dwSceneId: '1', strTypeCnt: strTypeCnt})
console.log('卖贝壳收入:', res.Data.ddwCoin, res.Data.ddwMoney)
}
// 任务➡️
let tasks: any
tasks = await api('story/GetActTask', '_cfd_t,bizCode,dwEnv,ptag,source,strZone')
for (let t of tasks.Data.TaskList) {
if (t.dwCompleteNum === t.dwTargetNum && t.dwAwardStatus === 2) {
res = await api('Award', '_cfd_t,bizCode,dwEnv,ptag,source,strZone,taskId', {taskId: t.ddwTaskId})
if (res.ret === 0) {
console.log(`${t.strTaskName}领奖成功:`, res.data.prizeInfo)
}
await wait(1000)
}
}
// 导游
res = await api('user/EmployTourGuideInfo', '_cfd_t,bizCode,dwEnv,ptag,source,strZone')
if (!res.TourGuideList) {
console.log('手动雇佣4个试用导游')
} else {
for (let e of res.TourGuideList) {
if (e.strBuildIndex !== 'food' && e.ddwRemainTm === 0) {
let employ: any = await api('user/EmployTourGuide', '_cfd_t,bizCode,ddwConsumeCoin,dwEnv,dwIsFree,ptag,source,strBuildIndex,strZone',
{ddwConsumeCoin: e.ddwCostCoin, dwIsFree: 0, strBuildIndex: e.strBuildIndex})
console.log(employ)
await wait(3000)
}
}
}
// 任务⬇️
tasks = await mainTask('GetUserTaskStatusList', '_cfd_t,bizCode,dwEnv,ptag,source,strZone,taskId', {taskId: 0});
for (let t of tasks.data.userTaskStatusList) {
if (t.dateType === 2) {
// 每日任务
if (t.awardStatus === 2 && t.completedTimes === t.targetTimes) {
console.log(1, t.taskName)
res = await mainTask('Award', '_cfd_t,bizCode,dwEnv,ptag,source,strZone,taskId', {taskId: t.taskId})
console.log(res)
if (res.ret === 0) {
console.log(`${t.taskName}领奖成功:`, res.data.prizeInfo)
}
await wait(2000)
} else if (t.awardStatus === 2 && t.completedTimes < t.targetTimes && ([1, 2, 3, 4].includes(t.orderId))) {
console.log('做任务:', t.taskId, t.taskName, t.completedTimes, t.targetTimes)
res = await mainTask('DoTask', '_cfd_t,bizCode,configExtra,dwEnv,ptag,source,strZone,taskId', {taskId: t.taskId, configExtra: ''})
console.log('做任务:', res)
await wait(5000)
}
}
}
for (let b of ['food', 'fun', 'shop', 'sea']) {
res = await api('user/GetBuildInfo', '_cfd_t,bizCode,dwEnv,dwType,ptag,source,strBuildIndex,strZone', {strBuildIndex: b})
console.log(`${b}升级需要:`, res.ddwNextLvlCostCoin)
await wait(1000)
if (res.dwCanLvlUp === 1) {
res = await api('user/BuildLvlUp', '_cfd_t,bizCode,ddwCostCoin,dwEnv,ptag,source,strBuildIndex,strZone', {ddwCostCoin: res.ddwNextLvlCostCoin, strBuildIndex: b})
if (res.iRet === 0) {
console.log(`升级成功`)
await wait(2000)
}
}
res = await api('user/CollectCoin', '_cfd_t,bizCode,dwEnv,dwType,ptag,source,strBuildIndex,strZone', {strBuildIndex: b, dwType: '1'})
console.log(`${b}收金币:`, res.ddwCoin)
await wait(1000)
}
}
// 获取随机助力码
if (CFD_HELP_HW === 'true') {
try {
let {data} = await axios.get("https://api.sharecode.ga/api/HW_CODES")
shareCodes = [
...shareCodes,
...data.jxcfd
]
console.log('获取HelloWorld助力码成功')
} catch (e) {
console.log('获取HelloWorld助力码出错')
}
}
if (CFD_HELP_POOL === 'true') {
try {
let {data} = await axios.get('https://api.sharecode.ga/api/jxcfd/20')
console.log('获取到20个随机助力码:', data.data)
shareCodes = [...shareCodes, ...data.data]
} catch (e) {
console.log('获取助力池失败')
}
} else {
console.log('你的设置是不帮助助力池!')
}
for (let i = 0; i < cookiesArr.length; i++) {
for (let j = 0; j < shareCodes.length; j++) {
cookie = cookiesArr[i]
console.log('去助力:', shareCodes[j])
res = await api('story/helpbystage', '_cfd_t,bizCode,dwEnv,ptag,source,strShareId,strZone', {strShareId: shareCodes[j]})
console.log('助力:', res)
if (res.iRet === 2232 || res.sErrMsg === '今日助力次数达到上限,明天再来帮忙吧~') {
break
}
await wait(3000)
}
}
})()
interface Params {
strBuildIndex?: string,
ddwCostCoin?: number,
taskId?: number,
dwType?: string,
configExtra?: string,
strStoryId?: string,
triggerType?: number,
ddwTriggerDay?: number,
ddwConsumeCoin?: number,
dwIsFree?: number,
ddwTaskId?: string,
strShareId?: string,
strMarkList?: string,
dwSceneId?: string,
strTypeCnt?: string,
dwUserId?: number
}
function api(fn: string, stk: string, params: Params = {}) {
return new Promise(async resolve => {
let url = `https://m.jingxi.com/jxbfd/${fn}?strZone=jxbfd&bizCode=jxbfd&source=jxbfd&dwEnv=7&_cfd_t=${Date.now()}&ptag=&_ste=1&_=${Date.now()}&sceneval=2&_stk=${encodeURIComponent(stk)}`
if (['GetUserTaskStatusList', 'Award', 'DoTask'].includes(fn)) {
console.log('api2')
url = `https://m.jingxi.com/newtasksys/newtasksys_front/${fn}?strZone=jxbfd&bizCode=jxbfddch&source=jxbfd&dwEnv=7&_cfd_t=${Date.now()}&ptag=&_stk=${encodeURIComponent(stk)}&_ste=1&_=${Date.now()}&sceneval=2`
}
if (Object.keys(params).length !== 0) {
let key: (keyof Params)
for (key in params) {
if (params.hasOwnProperty(key))
url += `&${key}=${params[key]}`
}
}
url += '&h5st=' + decrypt(stk, url)
let {data} = await axios.get(url, {
headers: {
'Host': 'm.jingxi.com',
'Referer': 'https://st.jingxi.com/',
'User-Agent': USER_AGENT,
'Cookie': cookie
}
})
resolve(data)
})
}
function mainTask(fn: string, stk: string, params: Params = {}) {
return new Promise(async resolve => {
let url = `https://m.jingxi.com/newtasksys/newtasksys_front/${fn}?strZone=jxbfd&bizCode=jxbfd&source=jxbfd&dwEnv=7&_cfd_t=${Date.now()}&ptag=&_stk=${encodeURIComponent(stk)}&_ste=1&_=${Date.now()}&sceneval=2`
if (Object.keys(params).length !== 0) {
let key: (keyof Params)
for (key in params) {
if (params.hasOwnProperty(key))
url += `&${key}=${params[key]}`
}
}
url += '&h5st=' + decrypt(stk, url)
let {data} = await axios.get(url, {
headers: {
'X-Requested-With': 'com.jd.pingou',
'Referer': 'https://st.jingxi.com/',
'Host': 'm.jingxi.com',
'User-Agent': USER_AGENT,
'Cookie': cookie
}
})
resolve(data)
})
}
function makeShareCodes() {
return new Promise<void>(async (resolve, reject) => {
let {data} = await axios.post('https://api.m.jd.com/client.action?functionId=initForFarm', `body=${escape(JSON.stringify({"version": 4}))}&appid=wh5&clientVersion=9.1.0`, {
headers: {
"cookie": cookie,
"origin": "https://home.m.jd.com",
"referer": "https://home.m.jd.com/myJd/newhome.action",
"User-Agent": USER_AGENT,
"Content-Type": "application/x-www-form-urlencoded"
}
})
let farm: string = data.farmUserPro.shareCode
res = await api('user/QueryUserInfo', '_cfd_t,bizCode,ddwTaskId,dwEnv,ptag,source,strShareId,strZone', {ddwTaskId: '', strShareId: '', strMarkList: 'undefined'})
console.log('助力码:', res.strMyShareId)
shareCodes.push(res.strMyShareId)
let pin: string = cookie.match(/pt_pin=([^;]*)/)![1]
pin = Md5.hashStr(pin)
axios.get(`https://api.sharecode.ga/api/jxcfd/insert?code=${res.strMyShareId}&farm=${farm}&pin=${pin}`)
.then(res => {
if (res.data.code === 200)
console.log('已自动提交助力码')
else
console.log('提交失败已提交farm的cookie才可提交cfd')
resolve()
})
.catch(e => {
reject('访问助力池出错')
})
})
}
async function requestAlgo() {
fingerprint = await generateFp();
return new Promise(async resolve => {
let {data} = await axios.post('https://cactus.jd.com/request_algo?g_ty=ajax', {
"version": "1.0",
"fp": fingerprint,
"appId": appId,
"timestamp": Date.now(),
"platform": "web",
"expandParams": ""
}, {
"headers": {
'Authority': 'cactus.jd.com',
'Pragma': 'no-cache',
'Cache-Control': 'no-cache',
'Accept': 'application/json',
'User-Agent': USER_AGENT,
'Content-Type': 'application/json',
'Origin': 'https://st.jingxi.com',
'Sec-Fetch-Site': 'cross-site',
'Sec-Fetch-Mode': 'cors',
'Sec-Fetch-Dest': 'empty',
'Referer': 'https://st.jingxi.com/',
'Accept-Language': 'zh-CN,zh;q=0.9,zh-TW;q=0.8,en;q=0.7'
},
})
if (data['status'] === 200) {
token = data.data.result.tk;
let enCryptMethodJDString = data.data.result.algo;
if (enCryptMethodJDString) enCryptMethodJD = new Function(`return ${enCryptMethodJDString}`)();
} else {
console.log(`fp: ${fingerprint}`)
console.log('request_algo 签名参数API请求失败:')
}
resolve(200)
})
}
function decrypt(stk: string, url: string) {
const timestamp = (format(new Date(), 'yyyyMMddhhmmssSSS'))
let hash1: string;
if (fingerprint && token && enCryptMethodJD) {
hash1 = enCryptMethodJD(token, fingerprint.toString(), timestamp.toString(), appId.toString(), CryptoJS).toString(CryptoJS.enc.Hex);
} else {
const random = '5gkjB6SpmC9s';
token = `tk01wcdf61cb3a8nYUtHcmhSUFFCfddDPRvKvYaMjHkxo6Aj7dhzO+GXGFa9nPXfcgT+mULoF1b1YIS1ghvSlbwhE0Xc`;
fingerprint = 9686767825751161;
// $.fingerprint = 7811850938414161;
const str = `${token}${fingerprint}${timestamp}${appId}${random}`;
hash1 = CryptoJS.SHA512(str, token).toString(CryptoJS.enc.Hex);
}
let st: string = '';
stk.split(',').map((item, index) => {
st += `${item}:${getQueryString(url, item)}${index === stk.split(',').length - 1 ? '' : '&'}`;
})
const hash2 = CryptoJS.HmacSHA256(st, hash1.toString()).toString(CryptoJS.enc.Hex);
return encodeURIComponent(["".concat(timestamp.toString()), "".concat(fingerprint.toString()), "".concat(appId.toString()), "".concat(token), "".concat(hash2)].join(";"))
}
function requireConfig() {
return new Promise<void>(resolve => {
console.log('开始获取配置文件\n')
const jdCookieNode = require('./jdCookie.js');
Object.keys(jdCookieNode).forEach((item) => {
if (jdCookieNode[item]) {
cookiesArr.push(jdCookieNode[item])
}
})
console.log(`${cookiesArr.length}个京东账号\n`)
resolve()
})
}
function generateFp() {
let e = "0123456789";
let a = 13;
let i = '';
for (; a--;)
i += e[Math.random() * e.length | 0];
return (i + Date.now()).slice(0, 16)
}
function getQueryString(url: string, name: string) {
let reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
let r = url.split('?')[1].match(reg);
if (r != null) return unescape(r[2]);
return '';
}
function wait(t: number) {
return new Promise<void>(resolve => {
setTimeout(() => {
resolve()
}, t)
})
}