Compare commits
2 Commits
5c8a9eb55e
...
f8e47879f1
Author | SHA1 | Date | |
---|---|---|---|
f8e47879f1 | |||
dd86b82e1c |
@ -1,9 +1,10 @@
|
||||
{
|
||||
"token":"",
|
||||
"client_type":"",
|
||||
"device_name":"",
|
||||
"device_model":"",
|
||||
"device_id":"",
|
||||
"sys_version":"",
|
||||
"channel":""
|
||||
"token": "",
|
||||
"client_type": "",
|
||||
"device_name": "",
|
||||
"device_model": "",
|
||||
"device_id": "",
|
||||
"sys_version": "",
|
||||
"channel": "",
|
||||
"email": ""
|
||||
}
|
12
global.json
12
global.json
@ -3,11 +3,11 @@
|
||||
"maxDelay": 5000,
|
||||
"sendMail": false,
|
||||
"mailConfig": {
|
||||
"user":"",
|
||||
"pass":"",
|
||||
"mailto":"",
|
||||
"smtpServer":"",
|
||||
"smtpPort":"",
|
||||
"smtpSecure":true
|
||||
"user": "",
|
||||
"pass": "",
|
||||
"mailto": "",
|
||||
"smtpServer": "",
|
||||
"smtpPort": "",
|
||||
"smtpSecure": true
|
||||
}
|
||||
}
|
235
src/config.js
235
src/config.js
@ -1,140 +1,183 @@
|
||||
const { exit } = require("process")
|
||||
const fs = require("fs")
|
||||
const { default: axios } = require("axios")
|
||||
const { log } = require("./util")
|
||||
const { exit } = require("process");
|
||||
const fs = require("fs");
|
||||
const { default: axios } = require("axios");
|
||||
const { log } = require("./util");
|
||||
|
||||
exports.ListNotificationURL = 'https://api-cloudgame.mihoyo.com/hk4e_cg_cn/gamer/api/listNotifications?is_sort=true&source=NotificationSourceUnknown&status=NotificationStatusUnread&type=NotificationTypePopup'
|
||||
exports.AckNotificationURL = 'https://api-cloudgame.mihoyo.com/hk4e_cg_cn/gamer/api/ackNotification'
|
||||
exports.WalletURL = 'https://api-cloudgame.mihoyo.com/hk4e_cg_cn/wallet/wallet/get?cost_method=COST_METHOD_UNSPECIFIED'
|
||||
exports.AnnouncementURL = 'https://api-cloudgame.mihoyo.com/hk4e_cg_cn/gamer/api/getAnnouncementInfo'
|
||||
exports.ListNotificationURL =
|
||||
"https://api-cloudgame.mihoyo.com/hk4e_cg_cn/gamer/api/listNotifications?is_sort=true&source=NotificationSourceUnknown&status=NotificationStatusUnread&type=NotificationTypePopup";
|
||||
exports.AckNotificationURL =
|
||||
"https://api-cloudgame.mihoyo.com/hk4e_cg_cn/gamer/api/ackNotification";
|
||||
exports.WalletURL =
|
||||
"https://api-cloudgame.mihoyo.com/hk4e_cg_cn/wallet/wallet/get?cost_method=COST_METHOD_UNSPECIFIED";
|
||||
exports.AnnouncementURL =
|
||||
"https://api-cloudgame.mihoyo.com/hk4e_cg_cn/gamer/api/getAnnouncementInfo";
|
||||
// Here must be an earlier version so that the response won't be null
|
||||
exports.AppVersionURL = 'https://api-takumi.mihoyo.com/ptolemaios/api/getLatestRelease?app_id=1953443910&app_version=3.8.0&channel=mihoyo'
|
||||
exports.AppVersionURL =
|
||||
"https://api-takumi.mihoyo.com/ptolemaios/api/getLatestRelease?app_id=1953443910&app_version=3.8.0&channel=mihoyo";
|
||||
|
||||
exports.ListNotification = async function(header) {
|
||||
let tmp = (await axios(exports.ListNotificationURL,{
|
||||
headers:header
|
||||
})).data;
|
||||
exports.ListNotification = async function (header) {
|
||||
let tmp = (
|
||||
await axios(exports.ListNotificationURL, {
|
||||
headers: header,
|
||||
})
|
||||
).data;
|
||||
tmp.StringVersion = JSON.stringify(tmp);
|
||||
return tmp;
|
||||
}
|
||||
exports.AckNotification = async function(header, id) {
|
||||
};
|
||||
exports.AckNotification = async function (header, id) {
|
||||
let data = `{"id":"${id}"}`;
|
||||
await axios.post(exports.AckNotificationURL, data,{
|
||||
headers:header
|
||||
await axios.post(exports.AckNotificationURL, data, {
|
||||
headers: header,
|
||||
});
|
||||
}
|
||||
exports.Wallet = async function(header) {
|
||||
let tmp = (await axios(exports.WalletURL,{
|
||||
headers:header
|
||||
})).data;
|
||||
};
|
||||
exports.Wallet = async function (header) {
|
||||
let tmp = (
|
||||
await axios(exports.WalletURL, {
|
||||
headers: header,
|
||||
})
|
||||
).data;
|
||||
tmp.StringVersion = JSON.stringify(tmp);
|
||||
return tmp;
|
||||
}
|
||||
exports.Announcement = async function(header) {
|
||||
let tmp = (await axios(exports.AnnouncementURL,{
|
||||
headers:header
|
||||
})).data;
|
||||
};
|
||||
exports.Announcement = async function (header) {
|
||||
let tmp = (
|
||||
await axios(exports.AnnouncementURL, {
|
||||
headers: header,
|
||||
})
|
||||
).data;
|
||||
tmp.StringVersion = JSON.stringify(tmp);
|
||||
return tmp;
|
||||
}
|
||||
exports.AppVersion = async function() {
|
||||
};
|
||||
exports.AppVersion = async function () {
|
||||
let tmp = (await axios(exports.AppVersionURL)).data;
|
||||
tmp.StringVersion = JSON.stringify(tmp);
|
||||
return tmp;
|
||||
}
|
||||
};
|
||||
var configKeys = [
|
||||
"token",
|
||||
"client_type",
|
||||
"device_name",
|
||||
"device_model",
|
||||
"sys_version",
|
||||
"channel"
|
||||
]
|
||||
"channel",
|
||||
];
|
||||
|
||||
exports.getGlobalConfig = function() {
|
||||
exports.getGlobalConfig = function () {
|
||||
try {
|
||||
var globalConfig = fs.readFileSync("global.json")
|
||||
} catch(e) {
|
||||
if(e.toString().includes("Error: ENOENT: no such file or directory")) {
|
||||
log.error(`读取配置失败!找不到全局配置文件`)
|
||||
var globalConfig = fs.readFileSync("global.json");
|
||||
} catch (e) {
|
||||
if (e.toString().includes("Error: ENOENT: no such file or directory")) {
|
||||
log.error(`读取配置失败!找不到全局配置文件`);
|
||||
} else {
|
||||
log.error(`读取配置失败!错误信息:${e}`);
|
||||
}
|
||||
exit()
|
||||
exit();
|
||||
}
|
||||
return JSON.parse(globalConfig);
|
||||
}
|
||||
};
|
||||
|
||||
exports.getConfigs = function(){
|
||||
exports.getConfigs = function () {
|
||||
try {
|
||||
var configsList = fs.readdirSync("configs")
|
||||
} catch(e) {
|
||||
if(e == "Error: ENOENT: no such file or directory, scandir 'configs'") {
|
||||
log.error(`读取配置失败!找不到configs文件夹`)
|
||||
var configsList = fs.readdirSync("configs");
|
||||
} catch (e) {
|
||||
if (
|
||||
e == "Error: ENOENT: no such file or directory, scandir 'configs'"
|
||||
) {
|
||||
log.error(`读取配置失败!找不到configs文件夹`);
|
||||
} else {
|
||||
log.error(`读取配置失败!错误信息:${e}`);
|
||||
}
|
||||
exit()
|
||||
exit();
|
||||
}
|
||||
log.info(`检测到${configsList.length}个配置文件:`)
|
||||
configsList.forEach(file => {
|
||||
log.info(`${file}`)
|
||||
})
|
||||
var configs = {}
|
||||
configsList.forEach(file => {
|
||||
configs[file] = JSON.parse(fs.readFileSync(`configs/${file}`))
|
||||
})
|
||||
return configs
|
||||
}
|
||||
exports.checkConfigs = function(configs){
|
||||
for(file in configs) {
|
||||
log.info(`检测到${configsList.length}个配置文件:`);
|
||||
configsList.forEach((file) => {
|
||||
log.info(`${file}`);
|
||||
});
|
||||
var configs = {};
|
||||
configsList.forEach((file) => {
|
||||
configs[file] = JSON.parse(fs.readFileSync(`configs/${file}`));
|
||||
});
|
||||
return configs;
|
||||
};
|
||||
exports.checkConfigs = function (configs) {
|
||||
for (file in configs) {
|
||||
var configThis = configs[file];
|
||||
for(key in configKeys) {
|
||||
if(configThis[configKeys[key]] == "" || configThis[configKeys[key]] == undefined || configThis[configKeys[key]] == null || configThis[configKeys[key]] == NaN) {
|
||||
for (key in configKeys) {
|
||||
if (
|
||||
configThis[configKeys[key]] == "" ||
|
||||
configThis[configKeys[key]] == undefined ||
|
||||
configThis[configKeys[key]] == null ||
|
||||
configThis[configKeys[key]] == NaN
|
||||
) {
|
||||
log.error(`配置文件 ${file} 异常:`);
|
||||
log.error(` —— ${configKeys[key]}字段缺失`);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
exports.makeHeader = function(data,appversion){
|
||||
exports.makeHeader = function (data, appversion) {
|
||||
return {
|
||||
"x-rpc-combo_token": data.token,
|
||||
"x-rpc-client_type": data.client_type,
|
||||
"x-rpc-app_version": appversion,
|
||||
"x-rpc-sys_version": data.sys_version,
|
||||
"x-rpc-channel": data.channel,
|
||||
"x-rpc-device_id": data.device_id,
|
||||
"x-rpc-device_name": data.device_name,
|
||||
"x-rpc-device_model": data.device_model,
|
||||
"x-rpc-app_id": 1953439974,
|
||||
"x-rpc-cg_game_biz": "hk4e_cn",
|
||||
"x-rpc-preview": 0,
|
||||
"x-rpc-op_biz": "clgm_cn",
|
||||
"x-rpc-language": "zh-cn",
|
||||
"x-rpc-vendor_id": 2,
|
||||
Referer: "https://app.mihoyo.com",
|
||||
Host: "api-cloudgame.mihoyo.com",
|
||||
Connection: "Keep-Alive",
|
||||
"Accept-Encoding": "gzip, deflate",
|
||||
Accept: "*/*",
|
||||
}
|
||||
}
|
||||
"x-rpc-client_type": data.client_type,
|
||||
"x-rpc-app_version": appversion,
|
||||
"x-rpc-sys_version": data.sys_version,
|
||||
"x-rpc-channel": data.channel,
|
||||
"x-rpc-device_id": data.device_id,
|
||||
"x-rpc-device_name": data.device_name,
|
||||
"x-rpc-device_model": data.device_model,
|
||||
"x-rpc-app_id": 1953439974,
|
||||
"x-rpc-cg_game_biz": "hk4e_cn",
|
||||
"x-rpc-preview": 0,
|
||||
"x-rpc-op_biz": "clgm_cn",
|
||||
"x-rpc-language": "zh-cn",
|
||||
"x-rpc-vendor_id": 2,
|
||||
Referer: "https://app.mihoyo.com",
|
||||
Host: "api-cloudgame.mihoyo.com",
|
||||
Connection: "Keep-Alive",
|
||||
"Accept-Encoding": "gzip, deflate",
|
||||
Accept: "*/*",
|
||||
};
|
||||
};
|
||||
|
||||
exports.SendLog = function(transporter,mailfrom,mailto,successNum,totalNum,content) {
|
||||
transporter.sendMail({
|
||||
from: `"Genshin Cloud Game Helper" <${mailfrom}>`, //邮件来源
|
||||
to: mailto, //邮件发送到哪里,多个邮箱使用逗号隔开
|
||||
subject: `今日已签到${successNum}/${totalNum}名用户`, // 邮件主题
|
||||
text: '', // 存文本类型的邮件正文
|
||||
html: `${content}` // html类型的邮件正文
|
||||
}, (error) => {
|
||||
if (error) {
|
||||
return console.log(error);
|
||||
exports.SendLog = function (
|
||||
transporter,
|
||||
mailfrom,
|
||||
mailto,
|
||||
successNum,
|
||||
totalNum,
|
||||
content
|
||||
) {
|
||||
transporter.sendMail(
|
||||
{
|
||||
from: `"Genshin Cloud Game Helper" <${mailfrom}>`, //邮件来源
|
||||
to: mailto, //邮件发送到哪里,多个邮箱使用逗号隔开
|
||||
subject: `今日已签到${successNum}/${totalNum}名用户`, // 邮件主题
|
||||
text: "", // 存文本类型的邮件正文
|
||||
html: `${content}`, // html类型的邮件正文
|
||||
},
|
||||
(error) => {
|
||||
if (error) {
|
||||
return console.log(error);
|
||||
}
|
||||
log.info("日志已丢出!");
|
||||
}
|
||||
log.info("日志已丢出!")
|
||||
});
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
exports.SendResult = function (transporter, mailfrom, mailto, content) {
|
||||
transporter.sendMail(
|
||||
{
|
||||
from: `"Genshin Cloud Game Helper" <${mailfrom}>`, //邮件来源
|
||||
to: mailto, //邮件发送到哪里,多个邮箱使用逗号隔开
|
||||
subject: `Genshin Cloud Game Helper`, // 邮件主题
|
||||
text: `${content}`, // 存文本类型的邮件正文
|
||||
},
|
||||
(error) => {
|
||||
if (error) {
|
||||
return console.log(error);
|
||||
}
|
||||
log.info(`已发送通知至${mailto}`);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
117
src/index.js
117
src/index.js
@ -1,67 +1,110 @@
|
||||
const { getConfigs, checkConfigs, makeHeader, ListNotification, AckNotification, Wallet, SendLog, AppVersion, getGlobalConfig } = require("./config")
|
||||
const {
|
||||
getConfigs,
|
||||
checkConfigs,
|
||||
makeHeader,
|
||||
ListNotification,
|
||||
AckNotification,
|
||||
Wallet,
|
||||
SendLog,
|
||||
AppVersion,
|
||||
getGlobalConfig,
|
||||
SendResult,
|
||||
} = require("./config");
|
||||
|
||||
const { log, addLogContent, getLogs, sleep } = require("./util");
|
||||
|
||||
const nodemailer = require("nodemailer");
|
||||
|
||||
(async () => {
|
||||
log.info("开始获取全局配置")
|
||||
log.info("开始获取全局配置");
|
||||
var globalConfig = getGlobalConfig();
|
||||
log.info("获取成功")
|
||||
log.info("获取成功");
|
||||
if (globalConfig.sendMail == true) {
|
||||
log.info("组装邮件发射器")
|
||||
log.info("组装邮件发射器");
|
||||
var transporter = nodemailer.createTransport({
|
||||
host: globalConfig.mailConfig.smtpServer,
|
||||
port: globalConfig.mailConfig.smtpPort,
|
||||
secure: globalConfig.mailConfig.smtpSecure,
|
||||
auth: {
|
||||
user: globalConfig.mailConfig.user,
|
||||
pass: globalConfig.mailConfig.pass
|
||||
}
|
||||
pass: globalConfig.mailConfig.pass,
|
||||
},
|
||||
});
|
||||
}
|
||||
var minDelay = globalConfig.minDelay
|
||||
var maxDelay = globalConfig.maxDelay
|
||||
var minDelay = globalConfig.minDelay;
|
||||
var maxDelay = globalConfig.maxDelay;
|
||||
var configs = getConfigs();
|
||||
log.info(`正在检测配置有效性`)
|
||||
checkConfigs(configs)
|
||||
log.info("检测完毕!")
|
||||
log.info("正在获取版本号")
|
||||
log.info(`正在检测配置有效性`);
|
||||
checkConfigs(configs);
|
||||
log.info("检测完毕!");
|
||||
log.info("正在获取版本号");
|
||||
var appversion = await AppVersion();
|
||||
appversion = appversion.data.package_version
|
||||
log.info(`获取成功!当前版本号:${appversion}`)
|
||||
var successNum = 0,totalNum = 0;
|
||||
appversion = appversion.data.package_version;
|
||||
log.info(`获取成功!当前版本号:${appversion}`);
|
||||
var successNum = 0,
|
||||
totalNum = 0;
|
||||
for (key in configs) {
|
||||
totalNum ++;
|
||||
log.info(`正在执行配置 ${key}`)
|
||||
log.info("尝试签到……")
|
||||
totalNum++;
|
||||
log.info(`正在执行配置 ${key}`);
|
||||
log.info("尝试签到……");
|
||||
var header = makeHeader(configs[key], appversion);
|
||||
var WalletRespond = await Wallet(header);
|
||||
addLogContent(`<span style="color: orange; font-weight: bold">${key} Wallet返回体</span> <br> <span style="color: orange">${JSON.stringify(WalletRespond)}</span><br>`);
|
||||
if(WalletRespond.data != null) {
|
||||
addLogContent(
|
||||
`<span style="color: orange; font-weight: bold">${key} Wallet返回体</span> <br> <span style="color: orange">${JSON.stringify(
|
||||
WalletRespond
|
||||
)}</span><br>`
|
||||
);
|
||||
if (WalletRespond.data != null) {
|
||||
var NotificationRespond = await ListNotification(header);
|
||||
addLogContent(`<span style="color: orange; font-weight: bold">${key} Notification返回体</span> <br> <span style="color: orange">${JSON.stringify(NotificationRespond)}</span><br>`);
|
||||
successNum ++;
|
||||
log.info(`签到完毕! 获得时长:${WalletRespond.data.free_time.send_freetime}分钟,总时长:${WalletRespond.data.free_time.free_time}分钟`);
|
||||
let NotificationLength = NotificationRespond.data.list.length
|
||||
addLogContent(
|
||||
`<span style="color: orange; font-weight: bold">${key} Notification返回体</span> <br> <span style="color: orange">${JSON.stringify(
|
||||
NotificationRespond
|
||||
)}</span><br>`
|
||||
);
|
||||
successNum++;
|
||||
log.info(
|
||||
`签到完毕! 获得时长:${WalletRespond.data.free_time.send_freetime}分钟,总时长:${WalletRespond.data.free_time.free_time}分钟`
|
||||
);
|
||||
if (configs[key].email != null) {
|
||||
SendResult(
|
||||
transporter,
|
||||
globalConfig.mailConfig.user,
|
||||
configs[key].email,
|
||||
`签到完毕! 获得时长:${WalletRespond.data.free_time.send_freetime}分钟,总时长:${WalletRespond.data.free_time.free_time}分钟`
|
||||
);
|
||||
}
|
||||
let NotificationLength = NotificationRespond.data.list.length;
|
||||
let postHeader = header;
|
||||
Object.assign(postHeader, {
|
||||
"Content-Length": 28,
|
||||
"Content-Type": "application/json",
|
||||
});
|
||||
for (var i = 0; i < NotificationLength; i++) {
|
||||
AckNotification(postHeader, NotificationRespond.data.list[i].id);
|
||||
}
|
||||
Object.assign(postHeader, {
|
||||
"Content-Length": 28,
|
||||
"Content-Type": "application/json",
|
||||
});
|
||||
for (var i = 0; i < NotificationLength; i++) {
|
||||
AckNotification(
|
||||
postHeader,
|
||||
NotificationRespond.data.list[i].id
|
||||
);
|
||||
}
|
||||
} else {
|
||||
log.error("签到失败")
|
||||
log.error("签到失败");
|
||||
if (configs[key].email != null) {
|
||||
SendResult(
|
||||
transporter,
|
||||
globalConfig.mailConfig.user,
|
||||
configs[key].email,
|
||||
"签到失败"
|
||||
);
|
||||
}
|
||||
}
|
||||
var delay = Math.round(Math.random() * (maxDelay - minDelay) + minDelay)
|
||||
log.info(`暂停:${delay}毫秒`)
|
||||
var delay = Math.round(
|
||||
Math.random() * (maxDelay - minDelay) + minDelay
|
||||
);
|
||||
log.info(`暂停:${delay}毫秒`);
|
||||
await sleep(delay);
|
||||
}
|
||||
|
||||
if (globalConfig.sendMail == true) {
|
||||
log.info(`运行完毕!丢出日志`)
|
||||
log.info(`运行完毕!丢出日志`);
|
||||
SendLog(
|
||||
transporter,
|
||||
globalConfig.mailConfig.user,
|
||||
@ -69,6 +112,6 @@ const nodemailer = require("nodemailer");
|
||||
successNum,
|
||||
totalNum,
|
||||
getLogs()
|
||||
)
|
||||
);
|
||||
}
|
||||
})()
|
||||
})();
|
||||
|
36
src/util.js
36
src/util.js
@ -1,26 +1,26 @@
|
||||
const reggol = require("reggol")
|
||||
const baseLogger = new reggol("GenshinCloudGameHelper")
|
||||
let logContent = ``
|
||||
exports.addLogContent = function(content) {
|
||||
logContent += content
|
||||
}
|
||||
exports.getLogs = function() {
|
||||
return logContent
|
||||
}
|
||||
const reggol = require("reggol");
|
||||
const baseLogger = new reggol("GenshinCloudGameHelper");
|
||||
let logContent = ``;
|
||||
exports.addLogContent = function (content) {
|
||||
logContent += content;
|
||||
};
|
||||
exports.getLogs = function () {
|
||||
return logContent;
|
||||
};
|
||||
|
||||
exports.log = {
|
||||
info(content) {
|
||||
logContent += `<strong style="color: green">[info]</strong> ${content}<br>`
|
||||
baseLogger.info(content)
|
||||
logContent += `<strong style="color: green">[info]</strong> ${content}<br>`;
|
||||
baseLogger.info(content);
|
||||
},
|
||||
error(content) {
|
||||
logContent += `<strong style="color: red">[error]</strong> ${content}<br>`
|
||||
baseLogger.error(content)
|
||||
}
|
||||
}
|
||||
logContent += `<strong style="color: red">[error]</strong> ${content}<br>`;
|
||||
baseLogger.error(content);
|
||||
},
|
||||
};
|
||||
|
||||
exports.sleep = function (delay) {
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(resolve, delay)
|
||||
})
|
||||
}
|
||||
setTimeout(resolve, delay);
|
||||
});
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user