ZZZ-Plugin/lib/code.js
2024-10-03 13:12:36 +08:00

107 lines
3 KiB
JavaScript

/**
* From ZZZeroUID
*/
import request from '../utils/request.js';
const TZ_OFFSET = 8 * 60 * 60 * 1000;
async function getData(type, data = {}) {
const urls = {
activity:
'https://bbs-api.miyoushe.com/apihub/api/home/new?gids=8&parts=1%2C3%2C4&device=OnePlus%20IN2025&cpu=placeholder&version=3',
index: 'https://api-takumi.mihoyo.com/event/miyolive/index',
code: 'https://api-takumi-static.mihoyo.com/event/miyolive/refreshCode',
};
try {
const headers = { 'x-rpc-act_id': data.actId || '' };
const params = new URLSearchParams({
version: data.version || '',
time: Math.floor(Date.now() / 1000).toString(),
});
let res;
if (type === 'index') {
res = await request(urls[type], { headers });
} else if (type === 'code') {
res = await request(`${urls[type]}?${params}`, { headers });
} else {
res = await request(urls[type]);
}
return await res.json();
} catch (e) {
return { error: `[${e.name}] ${type} 接口请求错误` };
}
}
async function getActId() {
const ret = await getData('activity');
if (ret.error || ret.retcode !== 0) return '';
const keywords = ['前瞻直播'];
for (const nav of ret.data.navigator) {
const name = nav.name;
if (name && keywords.every(word => name.includes(word))) {
const matched = nav.app_path.match(/act_id=(.*?)&/);
if (matched) return matched[1];
}
}
return '';
}
async function getLiveData(actId) {
const ret = await getData('index', { actId });
if (ret.error || ret.retcode !== 0) {
return { error: ret.error || '前瞻直播数据异常' };
}
const liveRaw = ret.data.live;
const liveTemp = JSON.parse(ret.data.template);
const liveData = {
code_ver: liveRaw.code_ver,
title: liveRaw.title.replace('特别直播', ''),
header: liveTemp.kvDesktop,
room: liveTemp.liveConfig[0].desktop,
};
if (liveRaw.is_end) {
liveData.review = liveTemp.reviewUrl.args.post_id;
} else {
const now = new Date(Date.now() + TZ_OFFSET);
const start = new Date(liveRaw.start + ' GMT+0800');
if (now < start) {
liveData.start = liveRaw.start;
}
}
return liveData;
}
async function getCode(version, actId) {
const ret = await getData('code', { version, actId });
if (ret.error || ret.retcode !== 0) {
return { error: ret.error || '兑换码数据异常' };
}
return ret.data.code_list.map(codeInfo => ({
items: codeInfo.title.replace(/<.*?>/g, ''),
code: codeInfo.code,
}));
}
export async function getCodeMsg() {
const actId = await getActId();
if (!actId) return '暂无前瞻直播资讯';
const liveData = await getLiveData(actId);
if (liveData.error) return `获取兑换码失败:\n${liveData.error}`;
const codeData = await getCode(liveData.code_ver, actId);
if (Array.isArray(codeData) && codeData.length > 0) {
const code = codeData[0];
return `${liveData.title}\n${code.items}:\n${code.code}`;
}
return '获取兑换码失败';
}