fix: 部分逻辑

This commit is contained in:
bietiaop 2024-08-19 22:39:21 +08:00
parent 34cd8b15dc
commit 70836ab785
9 changed files with 204 additions and 173 deletions

View file

@ -1,3 +1,7 @@
# 1.4.1
* 绑定设备
* 优化部分代码
# 1.4 # 1.4
* 添加 `练度统计` 功能,发送 `%练度统计``%练度` 查看 * 添加 `练度统计` 功能,发送 `%练度统计``%练度` 查看

View file

@ -21,13 +21,12 @@ export class Abyss extends ZZZPlugin {
}); });
} }
async abyss() { async abyss() {
const { api, deviceFp } = await this.getAPI(); const { api } = await this.getAPI();
if (!api) return false;
await this.getPlayerInfo(); await this.getPlayerInfo();
const method = this.e.msg.match(`(上期|往期)`) ? 'zzzChallengePeriod' : 'zzzChallenge'; const method = this.e.msg.match(`(上期|往期)`)
const abyssData = await api.getFinalData(this.e, method, { ? 'zzzChallengePeriod'
deviceFp, : 'zzzChallenge';
}); const abyssData = await api.getFinalData(this.e, method);
if (!abyssData?.has_data) { if (!abyssData?.has_data) {
await this.reply('没有式舆防卫战数据'); await this.reply('没有式舆防卫战数据');
return false; return false;
@ -37,7 +36,7 @@ export class Abyss extends ZZZPlugin {
if (this?.reply) { if (this?.reply) {
this.reply('查询成功,正在下载图片资源,请稍候。'); this.reply('查询成功,正在下载图片资源,请稍候。');
} }
}, 3000); }, 5000);
await abyss.get_assets(); await abyss.get_assets();
clearTimeout(timer); clearTimeout(timer);
const finalData = { const finalData = {

View file

@ -21,21 +21,16 @@ export class Card extends ZZZPlugin {
}); });
} }
async card() { async card() {
const { api, deviceFp } = await this.getAPI(); const { api } = await this.getAPI();
if (!api) return false;
await this.getPlayerInfo(); await this.getPlayerInfo();
const indexData = await api.getFinalData(this.e, 'zzzIndex', { deviceFp }); const indexData = await api.getFinalData(this.e, 'zzzIndex');
if (!indexData) return false; if (!indexData) return false;
let zzzAvatarList = await api.getFinalData(this.e, 'zzzAvatarList', { let zzzAvatarList = await api.getFinalData(this.e, 'zzzAvatarList');
deviceFp,
});
if (!zzzAvatarList) return false; if (!zzzAvatarList) return false;
indexData.avatar_list = zzzAvatarList.avatar_list; indexData.avatar_list = zzzAvatarList.avatar_list;
let zzzBuddyList = await api.getFinalData(this.e, 'zzzBuddyList', { let zzzBuddyList = await api.getFinalData(this.e, 'zzzBuddyList');
deviceFp,
});
if (!zzzBuddyList) return false; if (!zzzBuddyList) return false;
indexData.buddy_list = zzzBuddyList.list; indexData.buddy_list = zzzBuddyList.list;
const finalIndexData = new ZZZIndexResp(indexData); const finalIndexData = new ZZZIndexResp(indexData);
@ -45,7 +40,7 @@ export class Card extends ZZZPlugin {
if (this?.reply) { if (this?.reply) {
this.reply('查询成功,正在下载图片资源,请稍候。'); this.reply('查询成功,正在下载图片资源,请稍候。');
} }
}, 3000); }, 5000);
await finalIndexData.get_assets(); await finalIndexData.get_assets();
clearTimeout(timer); clearTimeout(timer);
const data = { const data = {

View file

@ -21,12 +21,9 @@ export class Note extends ZZZPlugin {
}); });
} }
async note() { async note() {
const { api, deviceFp } = await this.getAPI(); const { api } = await this.getAPI();
if (!api) return false;
await this.getPlayerInfo(); await this.getPlayerInfo();
const noteResponse = await api.getFinalData(this.e, 'zzzNote', { const noteResponse = await api.getFinalData(this.e, 'zzzNote');
deviceFp,
});
if (!noteResponse) return false; if (!noteResponse) return false;
const noteData = new ZZZNoteResp(noteResponse); const noteData = new ZZZNoteResp(noteResponse);
const finalData = { const finalData = {

View file

@ -43,7 +43,6 @@ export class Panel extends ZZZPlugin {
async refreshPanel() { async refreshPanel() {
const uid = await this.getUID(); const uid = await this.getUID();
if (!uid) return;
const lastQueryTime = await redis.get(`ZZZ:PANEL:${uid}:LASTTIME`); const lastQueryTime = await redis.get(`ZZZ:PANEL:${uid}:LASTTIME`);
const panelSettings = settings.getConfig('panel'); const panelSettings = settings.getConfig('panel');
const coldTime = _.get(panelSettings, 'interval', 300); const coldTime = _.get(panelSettings, 'interval', 300);
@ -51,12 +50,11 @@ export class Panel extends ZZZPlugin {
await this.reply(`${coldTime}秒内只能刷新一次,请稍后再试`); await this.reply(`${coldTime}秒内只能刷新一次,请稍后再试`);
return false; return false;
} }
const { api, deviceFp } = await this.getAPI(); const { api } = await this.getAPI();
if (!api) return false;
await redis.set(`ZZZ:PANEL:${uid}:LASTTIME`, Date.now()); await redis.set(`ZZZ:PANEL:${uid}:LASTTIME`, Date.now());
await this.reply('正在刷新面板列表,请稍候...'); await this.reply('正在刷新面板列表,请稍候...');
await this.getPlayerInfo(); await this.getPlayerInfo();
const result = await refreshPanel(this.e, api, uid, deviceFp); const result = await refreshPanel(this.e, api, uid);
if (!result) { if (!result) {
await this.reply('面板列表刷新失败,请稍后再试'); await this.reply('面板列表刷新失败,请稍后再试');
return false; return false;
@ -70,7 +68,6 @@ export class Panel extends ZZZPlugin {
} }
async getCharPanelList() { async getCharPanelList() {
const uid = await this.getUID(); const uid = await this.getUID();
if (!uid) return false;
const result = getPanelList(uid); const result = getPanelList(uid);
if (!result) { if (!result) {
await this.reply('未找到面板数据,请先%刷新面板'); await this.reply('未找到面板数据,请先%刷新面板');
@ -81,7 +78,7 @@ export class Panel extends ZZZPlugin {
if (this?.reply) { if (this?.reply) {
this.reply('查询成功,正在下载图片资源,请稍候。'); this.reply('查询成功,正在下载图片资源,请稍候。');
} }
}, 3000); }, 5000);
for (const item of result) { for (const item of result) {
await item.get_basic_assets(); await item.get_basic_assets();
} }
@ -94,7 +91,6 @@ export class Panel extends ZZZPlugin {
} }
async getCharPanel() { async getCharPanel() {
const uid = await this.getUID(); const uid = await this.getUID();
if (!uid) return false;
const reg = new RegExp(`${rulePrefix}(.+)面板$`); const reg = new RegExp(`${rulePrefix}(.+)面板$`);
const match = this.e.msg.match(reg); const match = this.e.msg.match(reg);
if (!match) return false; if (!match) return false;
@ -108,7 +104,7 @@ export class Panel extends ZZZPlugin {
if (this?.reply) { if (this?.reply) {
this.reply('查询成功,正在下载图片资源,请稍候。'); this.reply('查询成功,正在下载图片资源,请稍候。');
} }
}, 3000); }, 5000);
await data.get_detail_assets(); await data.get_detail_assets();
clearTimeout(timer); clearTimeout(timer);
const finalData = { const finalData = {
@ -128,7 +124,6 @@ export class Panel extends ZZZPlugin {
} }
async proficiency() { async proficiency() {
const uid = await this.getUID(); const uid = await this.getUID();
if (!uid) return false;
const result = getPanelList(uid); const result = getPanelList(uid);
if (!result) { if (!result) {
await this.reply('未找到面板数据,请先%刷新面板'); await this.reply('未找到面板数据,请先%刷新面板');
@ -160,7 +155,7 @@ export class Panel extends ZZZPlugin {
if (this?.reply) { if (this?.reply) {
this.reply('查询成功,正在下载图片资源,请稍候。'); this.reply('查询成功,正在下载图片资源,请稍候。');
} }
}, 3000); }, 5000);
for (const item of result) { for (const item of result) {
await item.get_small_basic_assets(); await item.get_small_basic_assets();
} }

View file

@ -16,6 +16,10 @@ export class Panel extends ZZZPlugin {
reg: `${rulePrefix}绑定设备$`, reg: `${rulePrefix}绑定设备$`,
fnc: 'bindDevice', fnc: 'bindDevice',
}, },
{
reg: `${rulePrefix}解绑设备$`,
fnc: 'deleteBind',
},
{ {
reg: `${rulePrefix}绑定设备帮助$`, reg: `${rulePrefix}绑定设备帮助$`,
fnc: 'bindDeviceHelp', fnc: 'bindDeviceHelp',
@ -25,9 +29,6 @@ export class Panel extends ZZZPlugin {
} }
async bindDevice() { async bindDevice() {
const uid = await this.getUID(); const uid = await this.getUID();
if (!uid) {
this.reply('未绑定UID');
}
this.setContext('toBindDevice'); this.setContext('toBindDevice');
await this.reply( await this.reply(
`为UID ${uid}绑定设备,请发送设备信息,或者发送“取消”取消绑定`, `为UID ${uid}绑定设备,请发送设备信息,或者发送“取消”取消绑定`,
@ -58,13 +59,20 @@ export class Panel extends ZZZPlugin {
this.reply('设备信息格式错误', false, { at: true, recallMsg: 100 }); this.reply('设备信息格式错误', false, { at: true, recallMsg: 100 });
return false; return false;
} }
if (!!info?.device_id && !!info.device_fp) {
await redis.set(`ZZZ:DEVICE_FP:${ltuid}:FP`, info.device_fp);
await redis.set(`ZZZ:DEVICE_FP:${ltuid}:ID`, info.device_id);
await this.reply('绑定设备成功', false, { at: true, recallMsg: 100 });
this.finish('toBindDevice');
return false;
}
if ( if (
!'deviceName' in info || !info?.deviceName ||
!'deviceBoard' in info || !info?.deviceBoard ||
!'deviceModel' in info || !info?.deviceModel ||
!'oaid' in info || !info?.oaid ||
!'deviceFingerprint' in info || !info?.deviceFingerprint ||
!'deviceProduct' in info !info?.deviceProduct
) { ) {
this.reply('设备信息格式错误', false, { at: true, recallMsg: 100 }); this.reply('设备信息格式错误', false, { at: true, recallMsg: 100 });
return false; return false;
@ -86,16 +94,41 @@ export class Panel extends ZZZPlugin {
return false; return false;
} }
} }
async deleteBind() {
const ltuid = await this.getLtuid();
await redis.del(`ZZZ:DEVICE_FP:${ltuid}:FP`);
await redis.del(`ZZZ:DEVICE_FP:${ltuid}:BIND`);
await redis.del(`ZZZ:DEVICE_FP:${ltuid}:ID`);
await this.reply('解绑设备成功', false, { at: true, recallMsg: 100 });
}
async bindDeviceHelp() { async bindDeviceHelp() {
const msgs = [ const msgs = [
'绑定设备帮助', '[绑定设备]',
settings.getConfig('config')?.url, '方法一:',
'1. 使用常用米游社手机下载以上APK并安装', '1. 使用抓包软件抓取米游社APP的请求',
'2. 在请求头内找到【x-rpc-device_id】和【x-rpc-device_fp】',
'3. 自行构造如下格式的信息:',
' {device_id: "x-rpc-device_id的内容", device_fp: "x-rpc-device_fp的内容"}',
'4. 给机器人发送"%绑定设备"指令',
'5. 机器人会提示发送设备信息',
'6. 粘贴自行构造的信息发送',
'7. 提示绑定成功',
'--------------------------------',
'方法二(仅适用于安卓设备):',
'1. 使用常用米游社手机下载下面链接的APK文件并安装',
_.get(
settings.getConfig('config'),
'url',
'https://ghproxy.mihomo.me/https://raw.githubusercontent.com/forchannot/get_device_info/main/app/build/outputs/apk/debug/app-debug.apk'
),
'2. 打开后点击按钮复制', '2. 打开后点击按钮复制',
'3. 给机器人发送"%绑定设备"指令', '3. 给机器人发送"%绑定设备"指令',
'4. 机器人会提示发送设备信息', '4. 机器人会提示发送设备信息',
'5. 粘贴设备信息发送', '5. 粘贴设备信息发送',
'6. 提示绑定成功', '6. 提示绑定成功',
'--------------------------------',
'[解绑设备]',
'发送 %解绑设备 即可',
], ],
msg = msgs.join('\n'); msg = msgs.join('\n');
await this.reply(await common.makeForwardMsg(this.e, msg, '绑定设备帮助')); await this.reply(await common.makeForwardMsg(this.e, msg, '绑定设备帮助'));

View file

@ -7,15 +7,12 @@ import { char } from './convert.js';
* 获取角色基础信息列表 * 获取角色基础信息列表
* @param {*} e 消息事件 * @param {*} e 消息事件
* @param {MysZZZApi} api * @param {MysZZZApi} api
* @param {string} deviceFp
* @param {boolean} origin 是否返回原始数据 * @param {boolean} origin 是否返回原始数据
* @returns {Promise<ZZZAvatarBasic[] | null>} * @returns {Promise<ZZZAvatarBasic[] | null>}
*/ */
export const getAvatarBasicList = async (e, api, deviceFp, origin = false) => { export const getAvatarBasicList = async (e, api, origin = false) => {
// 获取米游社角色列表 // 获取米游社角色列表
const avatarBaseListData = await api.getFinalData(e, 'zzzAvatarList', { const avatarBaseListData = await api.getFinalData(e, 'zzzAvatarList');
deviceFp,
});
if (!avatarBaseListData) return null; if (!avatarBaseListData) return null;
// 是否返回原始数据 // 是否返回原始数据
if (origin) return avatarBaseListData.avatar_list; if (origin) return avatarBaseListData.avatar_list;
@ -31,16 +28,14 @@ export const getAvatarBasicList = async (e, api, deviceFp, origin = false) => {
* @param {*} e 消息事件 * @param {*} e 消息事件
* @param {MysZZZApi} api * @param {MysZZZApi} api
* @returns {Promise<ZZZAvatarInfo[] | null>} * @returns {Promise<ZZZAvatarInfo[] | null>}
* @param {string} deviceFp
* @param {boolean} origin 是否返回原始数据 * @param {boolean} origin 是否返回原始数据
*/ */
export const getAvatarInfoList = async (e, api, deviceFp, origin = false) => { export const getAvatarInfoList = async (e, api, origin = false) => {
// 获取角色基础信息列表 // 获取角色基础信息列表
const avatarBaseList = await getAvatarBasicList(e, api, deviceFp, origin); const avatarBaseList = await getAvatarBasicList(e, api, origin);
if (!avatarBaseList) return null; if (!avatarBaseList) return null;
// 获取角色详细信息 // 获取角色详细信息
const avatarInfoList = await api.getFinalData(e, 'zzzAvatarInfo', { const avatarInfoList = await api.getFinalData(e, 'zzzAvatarInfo', {
deviceFp,
query: { query: {
id_list: avatarBaseList.map(item => item.id), id_list: avatarBaseList.map(item => item.id),
}, },
@ -60,14 +55,13 @@ export const getAvatarInfoList = async (e, api, deviceFp, origin = false) => {
* @param {*} e 消息事件 * @param {*} e 消息事件
* @param {MysZZZApi} api * @param {MysZZZApi} api
* @param {string} uid * @param {string} uid
* @param {string} deviceFp
* @returns {Promise<ZZZAvatarInfo[] | null>} * @returns {Promise<ZZZAvatarInfo[] | null>}
*/ */
export const refreshPanel = async (e, api, uid, deviceFp) => { export const refreshPanel = async (e, api, uid) => {
// 获取已保存数据 // 获取已保存数据
const originData = getPanelData(uid); const originData = getPanelData(uid);
// 获取新数据 // 获取新数据
const newData = await getAvatarInfoList(e, api, deviceFp, true); const newData = await getAvatarInfoList(e, api, true);
if (!newData) return null; if (!newData) return null;
// 初始化最终数据 // 初始化最终数据
const finalData = [...newData]; const finalData = [...newData];

View file

@ -110,6 +110,9 @@ export default class MysZZZApi extends MysApi {
if (this._device) { if (this._device) {
headers['x-rpc-device_id'] = this._device; headers['x-rpc-device_id'] = this._device;
} }
if (data.deviceId) {
headers['x-rpc-device_id'] = data.deviceId;
}
if (data?.deviceInfo && data?.modelName) { if (data?.deviceInfo && data?.modelName) {
const deviceBrand = data.deviceInfo?.split('/')[0]; const deviceBrand = data.deviceInfo?.split('/')[0];
try { try {
@ -143,6 +146,9 @@ export default class MysZZZApi extends MysApi {
if (this._device) { if (this._device) {
body = JSON.parse(body); body = JSON.parse(body);
body.device_id = this._device; body.device_id = this._device;
if (data.deviceId) {
body.device_id = data.deviceId;
}
body = JSON.stringify(body); body = JSON.stringify(body);
} }
} }
@ -256,7 +262,7 @@ export default class MysZZZApi extends MysApi {
case 10041: case 10041:
case 5003: case 5003:
this.e.reply( this.e.reply(
`UID:${this.uid},米游社账号异常,暂时无法查询,请尝试 %绑定设备帮助` `UID:${this.uid},米游社账号异常,暂时无法查询,请发送 %绑定设备帮助 查看如何绑定设备`
); );
break; break;
case 10035: case 10035:
@ -300,6 +306,12 @@ export default class MysZZZApi extends MysApi {
logger.mark( logger.mark(
`[米游社zzz接口报错]${JSON.stringify(res)}UID${this.uid}` `[米游社zzz接口报错]${JSON.stringify(res)}UID${this.uid}`
); );
throw new Error({
type: 'mysApi',
uid: this.uid,
retcode: res.retcode,
result: res,
});
} }
return res; return res;
} }
@ -308,12 +320,12 @@ export default class MysZZZApi extends MysApi {
* 获取米游社数据 * 获取米游社数据
* @param {*} e 消息e * @param {*} e 消息e
* @param {keyof ZZZApiTool['zzzUrlMap']} type 请求类型 * @param {keyof ZZZApiTool['zzzUrlMap']} type 请求类型
* @param {{deviceFp: string; query: Record<string, any>; headers: object;}} data * @param {{deviceFp?: string; query: Record<string, any>; headers: object;}} data
* @param {boolean} cached * @param {boolean} cached
*/ */
async getFinalData(e, type, data = {}, cached = false) { async getFinalData(e, type, data = {}, cached = false) {
if (!data.headers) data.headers = {};
if (data.deviceFp) { if (data.deviceFp) {
if (!data.headers) data.headers = {};
data.headers['x-rpc-device_fp'] = data.deviceFp; data.headers['x-rpc-device_fp'] = data.deviceFp;
} }
// 从 this.cookie 中获取ltuid // 从 this.cookie 中获取ltuid
@ -322,22 +334,33 @@ export default class MysZZZApi extends MysApi {
if (ltuid) { if (ltuid) {
ltuid = ltuid[1]; ltuid = ltuid[1];
} }
if (ltuid) {
let bindInfo = await redis.get(`ZZZ:DEVICE_FP:${ltuid}:BIND`); let bindInfo = await redis.get(`ZZZ:DEVICE_FP:${ltuid}:BIND`);
if (bindInfo) { if (bindInfo) {
try { try {
bindInfo = JSON.parse(bindInfo); bindInfo = JSON.parse(bindInfo);
data = { data = {
...data, ...data,
productName: bindInfo?.deviceProduct, productName: bindInfo?.deviceProduct,
deviceType: bindInfo?.deviceName, deviceType: bindInfo?.deviceName,
modelName: bindInfo?.deviceModel, modelName: bindInfo?.deviceModel,
oaid: bindInfo?.oaid, oaid: bindInfo?.oaid,
deviceInfo: bindInfo?.deviceFingerprint, deviceInfo: bindInfo?.deviceFingerprint,
board: bindInfo?.deviceBoard, board: bindInfo?.deviceBoard,
}; };
} catch (error) { } catch (error) {
bindInfo = null; bindInfo = null;
}
}
const device_fp = await redis.get(`ZZZ:DEVICE_FP:${ltuid}:FP`);
if (device_fp) {
data.deviceFp = device_fp;
data.headers['x-rpc-device_fp'] = device_fp;
}
const device_id = await redis.get(`ZZZ:DEVICE_FP:${ltuid}:ID`);
if (device_id) {
data.deviceId = device_id;
data.headers['x-rpc-device_id'] = device_id;
} }
} }
const result = await this.getData(type, data, cached); const result = await this.getData(type, data, cached);

View file

@ -32,7 +32,7 @@ export class ZZZPlugin extends plugin {
await this.reply( await this.reply(
'uid为空需要CK的功能请先绑定CK或者#扫码登录需要SK的功能请#扫码登录若不清楚需要CK或SK请查看%帮助' 'uid为空需要CK的功能请先绑定CK或者#扫码登录需要SK的功能请#扫码登录若不清楚需要CK或SK请查看%帮助'
); );
return false; throw new Error('UID为空');
} }
// 返回 UID // 返回 UID
return uid; return uid;
@ -43,18 +43,14 @@ export class ZZZPlugin extends plugin {
* @returns {Promise<string | boolean>} * @returns {Promise<string | boolean>}
* @memberof ZZZPlugin * @memberof ZZZPlugin
* @description 获取用户 ltuid * @description 获取用户 ltuid
* @example
* const ltuid = await this.getLtuid();
* if (!ltuid) return false;
* @returns {Promise<string | boolean>} * @returns {Promise<string | boolean>}
*/ */
async getLtuid() { async getLtuid() {
const uid = await this.getUID(); const uid = await this.getUID();
if (!uid) return false;
const ck = await getCk(this.e); const ck = await getCk(this.e);
if (!ck || Object.keys(ck).filter(k => ck[k].ck).length === 0) { if (!ck || Object.keys(ck).filter(k => ck[k].ck).length === 0) {
await this.reply('尚未绑定cookie请先绑定cookie或者#扫码登录'); await this.reply('尚未绑定cookie请先绑定cookie或者#扫码登录');
return false; throw new Error('CK为空');
} }
const currentCK = Object.values(ck).find(item => { const currentCK = Object.values(ck).find(item => {
return item.ck && item.uid === uid; return item.ck && item.uid === uid;
@ -68,109 +64,105 @@ export class ZZZPlugin extends plugin {
async getAPI() { async getAPI() {
// 直接调用获取 UID // 直接调用获取 UID
const uid = await this.getUID(); const uid = await this.getUID();
if (!uid) return { api: null, uid: null, deviceFp: null };
// 获取用户的 cookie // 获取用户的 cookie
const ck = await getCk(this.e); const ck = await getCk(this.e);
// 如果 cookie 不存在或者 cookie 为空,说明没有绑定 cookie // 如果 cookie 不存在或者 cookie 为空,说明没有绑定 cookie
if (!ck || Object.keys(ck).filter(k => ck[k].ck).length === 0) { if (!ck || Object.keys(ck).filter(k => ck[k].ck).length === 0) {
await this.reply('尚未绑定cookie请先绑定cookie或者#扫码登录'); await this.reply('尚未绑定cookie请先绑定cookie或者#扫码登录');
return { api: null, uid: null, deviceFp: null }; throw new Error('CK为空');
} }
try {
// 创建米游社 API 对象 // 创建米游社 API 对象
const api = new MysZZZApi(uid, ck); const api = new MysZZZApi(uid, ck);
const currentCK = Object.values(ck).find(item => { const currentCK = Object.values(ck).find(item => {
return item.ck && item.uid === uid; return item.ck && item.uid === uid;
}); });
const ltuid = currentCK?.ltuid || ''; const ltuid = currentCK?.ltuid || '';
if (!ltuid) { if (!ltuid) {
return { api: null, uid: null, deviceFp: null }; this.reply('ltuid为空请重新绑定CK');
} throw new Error('ltuid为空');
// 获取设备指纹 }
let deviceFp // 获取设备指纹
let bindInfo = await redis.get(`ZZZ:DEVICE_FP:${ltuid}:BIND`); let deviceFp;
if (bindInfo) { let bindInfo = await redis.get(`ZZZ:DEVICE_FP:${ltuid}:BIND`);
deviceFp = await redis.get(`ZZZ:DEVICE_FP:${ltuid}:FP`); if (bindInfo) {
let data = { deviceFp = await redis.get(`ZZZ:DEVICE_FP:${ltuid}:FP`);
deviceFp, let data = {
deviceFp,
};
try {
bindInfo = JSON.parse(bindInfo);
data = {
productName: bindInfo?.deviceProduct,
deviceType: bindInfo?.deviceName,
modelName: bindInfo?.deviceModel,
oaid: bindInfo?.oaid,
deviceInfo: bindInfo?.deviceFingerprint,
board: bindInfo?.deviceBoard,
}; };
try { } catch (error) {
bindInfo = JSON.parse(bindInfo); bindInfo = null;
data = { }
productName: bindInfo?.deviceProduct, if (!deviceFp) {
deviceType: bindInfo?.deviceName, const sdk = api.getUrl('getFp', data);
modelName: bindInfo?.deviceModel, const res = await request(sdk.url, {
oaid: bindInfo?.oaid, headers: sdk.headers,
deviceInfo: bindInfo?.deviceFingerprint, method: 'POST',
board: bindInfo?.deviceBoard, body: sdk.body,
}; });
} catch (error) { const fpRes = await res.json();
bindInfo = null; logger.debug(`[米游社][设备指纹]${JSON.stringify(fpRes)}`);
} deviceFp = fpRes?.data?.device_fp;
if (!deviceFp) { if (!deviceFp) {
const sdk = api.getUrl('getFp', data); return { api: null, uid: null, deviceFp: null };
const res = await request(sdk.url, { }
headers: sdk.headers, await redis.set(`ZZZ:DEVICE_FP:${ltuid}:FP`, deviceFp, {
method: 'POST', EX: 86400 * 7,
body: sdk.body, });
}); data['deviceFp'] = deviceFp;
const fpRes = await res.json(); const deviceLogin = api.getUrl('deviceLogin', data);
logger.debug(`[米游社][设备指纹]${JSON.stringify(fpRes)}`); const saveDevice = api.getUrl('saveDevice', data);
deviceFp = fpRes?.data?.device_fp; if (!!deviceLogin && !!saveDevice) {
if (!deviceFp) { logger.debug(`[米游社][设备登录]保存设备信息`);
return { api: null, uid: null, deviceFp: null }; try {
logger.debug(`[米游社][设备登录]${JSON.stringify(deviceLogin)}`);
const login = await request(deviceLogin.url, {
headers: deviceLogin.headers,
method: 'POST',
body: deviceLogin.body,
});
const save = await request(saveDevice.url, {
headers: saveDevice.headers,
method: 'POST',
body: saveDevice.body,
});
const result = await Promise.all([login.json(), save.json()]);
logger.debug(`[米游社][设备登录]${JSON.stringify(result)}`);
} catch (error) {
logger.error(`[米游社][设备登录]${error.message}`);
} }
await redis.set(`ZZZ:DEVICE_FP:${ltuid}:FP`, deviceFp, { }
}
} else {
deviceFp = await redis.get(`ZZZ:DEVICE_FP:${uid}`);
if (!deviceFp) {
const sdk = api.getUrl('getFp');
const res = await fetch(sdk.url, {
headers: sdk.headers,
method: 'POST',
body: sdk.body,
});
const fpRes = await res.json();
deviceFp = fpRes?.data?.device_fp;
if (deviceFp) {
await redis.set(`ZZZ:DEVICE_FP:${uid}`, deviceFp, {
EX: 86400 * 7, EX: 86400 * 7,
}); });
data['deviceFp'] = deviceFp;
const deviceLogin = api.getUrl('deviceLogin', data);
const saveDevice = api.getUrl('saveDevice', data);
if (!!deviceLogin && !!saveDevice) {
logger.debug(`[米游社][设备登录]保存设备信息`);
try {
logger.debug(`[米游社][设备登录]${JSON.stringify(deviceLogin)}`);
const login = await request(deviceLogin.url, {
headers: deviceLogin.headers,
method: 'POST',
body: deviceLogin.body,
});
const save = await request(saveDevice.url, {
headers: saveDevice.headers,
method: 'POST',
body: saveDevice.body,
});
const result = await Promise.all([login.json(), save.json()]);
logger.debug(`[米游社][设备登录]${JSON.stringify(result)}`);
} catch (error) {
logger.error(`[米游社][设备登录]${error.message}`);
}
}
}
} else {
deviceFp = await redis.get(`ZZZ:DEVICE_FP:${uid}`);
if (!deviceFp) {
const sdk = api.getUrl('getFp');
const res = await fetch(sdk.url, {
headers: sdk.headers,
method: 'POST',
body: sdk.body,
});
const fpRes = await res.json();
deviceFp = fpRes?.data?.device_fp;
if (deviceFp) {
await redis.set(`ZZZ:DEVICE_FP:${uid}`, deviceFp, {
EX: 86400 * 7,
});
}
} }
} }
// 返回数据API、UID、设备指纹
return { api, uid, deviceFp };
} catch (error) {
this.reply(error.message);
return { api: null, uid: null, deviceFp: null };
} }
// 返回数据API、UID、设备指纹
return { api, uid, deviceFp };
} }
/** /**
@ -180,10 +172,9 @@ export class ZZZPlugin extends plugin {
async getPlayerInfo() { async getPlayerInfo() {
// 获取 米游社 API // 获取 米游社 API
const { api, uid } = await this.getAPI(); const { api, uid } = await this.getAPI();
if (!api) return false;
// 获取用户信息 // 获取用户信息
let userData = await api.getFinalData(this.e, 'zzzUser'); let userData = await api.getFinalData(this.e, 'zzzUser');
if (!userData) return false; if (!userData) throw new Error('获取用户数据失败');
// 取第一个用户信息 // 取第一个用户信息
userData = userData =
userData?.list?.find(item => item.game_uid == uid) || userData?.list?.[0]; userData?.list?.find(item => item.game_uid == uid) || userData?.list?.[0];
@ -195,7 +186,7 @@ export class ZZZPlugin extends plugin {
} else if (this.e.friend?.getAvatarUrl) { } else if (this.e.friend?.getAvatarUrl) {
avatar = await this.e.friend.getAvatarUrl(); avatar = await this.e.friend.getAvatarUrl();
} else { } else {
avatar = this.e?.bot?.avatar avatar = this.e?.bot?.avatar;
} }
// 写入数据 // 写入数据
this.e.playerCard = { this.e.playerCard = {