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