mirror of
https://github.com/ZZZure/ZZZ-Plugin.git
synced 2025-12-16 13:17:32 +00:00
👀👀
This commit is contained in:
parent
4a54442fae
commit
14f24bbd4d
4 changed files with 150 additions and 27 deletions
86
apps/user.js
Normal file
86
apps/user.js
Normal file
|
|
@ -0,0 +1,86 @@
|
||||||
|
import { ZZZPlugin } from '../lib/plugin.js';
|
||||||
|
import render from '../lib/render.js';
|
||||||
|
import { rulePrefix } from '../lib/common.js';
|
||||||
|
import { getPanelList, refreshPanel, getPanel } from '../lib/avatar.js';
|
||||||
|
import settings from '../lib/settings.js';
|
||||||
|
import _ from 'lodash';
|
||||||
|
|
||||||
|
export class Panel extends ZZZPlugin {
|
||||||
|
constructor() {
|
||||||
|
super({
|
||||||
|
name: '[ZZZ-Plugin]User',
|
||||||
|
dsc: 'zzzuser',
|
||||||
|
event: 'message',
|
||||||
|
priority: _.get(settings.getConfig('priority'), 'user', 70),
|
||||||
|
rule: [
|
||||||
|
{
|
||||||
|
reg: `${rulePrefix}绑定设备$`,
|
||||||
|
fnc: 'bindDevice',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async bindDevice() {
|
||||||
|
const uid = await this.getUID();
|
||||||
|
if (!uid) {
|
||||||
|
this.reply('未绑定UID');
|
||||||
|
}
|
||||||
|
this.setContext('toBindDevice');
|
||||||
|
await this.reply(
|
||||||
|
`为UID ${uid}绑定设备,请发送设备信息,或者发送“取消”取消绑定`,
|
||||||
|
false,
|
||||||
|
{ at: true, recallMsg: 100 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
async toBindDevice() {
|
||||||
|
const uid = await this.getUID();
|
||||||
|
if (!uid) {
|
||||||
|
this.reply('未绑定UID');
|
||||||
|
this.finish('toBindDevice');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const msg = this.e.msg.trim();
|
||||||
|
if (!msg) {
|
||||||
|
this.reply('请发送设备信息', false, { at: true, recallMsg: 100 });
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (msg.includes('取消')) {
|
||||||
|
await this.reply('已取消', false, { at: true, recallMsg: 100 });
|
||||||
|
this.finish('toBindDevice');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const info = JSON.parse(msg);
|
||||||
|
if (!info) {
|
||||||
|
this.reply('设备信息格式错误', false, { at: true, recallMsg: 100 });
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
!'deviceName' in info ||
|
||||||
|
!'deviceBoard' in info ||
|
||||||
|
!'deviceModel' in info ||
|
||||||
|
!'oaid' in info ||
|
||||||
|
!'deviceFingerprint' in info ||
|
||||||
|
!'deviceProduct' in info
|
||||||
|
) {
|
||||||
|
this.reply('设备信息格式错误', false, { at: true, recallMsg: 100 });
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
await redis.del(`ZZZ:DEVICE_FP:${uid}:FP`);
|
||||||
|
await redis.set(`ZZZ:DEVICE_FP:${uid}:BIND`, JSON.stringify(info));
|
||||||
|
const { deviceFp } = await this.getAPI();
|
||||||
|
if (!deviceFp) {
|
||||||
|
await this.reply('绑定设备失败');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
logger.debug(`[UID:${uid}]绑定设备成功,deviceFp:${deviceFp}`);
|
||||||
|
await this.reply('绑定设备成功', false, { at: true, recallMsg: 100 });
|
||||||
|
} catch (error) {
|
||||||
|
this.reply('设备信息格式错误', false, { at: true, recallMsg: 100 });
|
||||||
|
return false;
|
||||||
|
} finally {
|
||||||
|
this.finish('toBindDevice');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -110,6 +110,16 @@ 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?.deviceInfo && data?.modelName) {
|
||||||
|
const deviceBrand = data.deviceInfo?.split('/')[0];
|
||||||
|
try {
|
||||||
|
headers['x-rpc-device_name'] = `${deviceBrand} ${data.modelName}`;
|
||||||
|
headers['x-rpc-device_model'] = data.modelName;
|
||||||
|
headers['x-rpc-csm_source'] = 'myself';
|
||||||
|
} catch (error) {
|
||||||
|
logger.error(`[ZZZ]设备信息解析失败:${error.message}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
// 写入DS
|
// 写入DS
|
||||||
switch (dsSalt) {
|
switch (dsSalt) {
|
||||||
case 'web': {
|
case 'web': {
|
||||||
|
|
@ -136,7 +146,6 @@ export default class MysZZZApi extends MysApi {
|
||||||
body = JSON.stringify(body);
|
body = JSON.stringify(body);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
logger.debug(`[mysapi]请求url:${url}`);
|
|
||||||
// 返回请求参数
|
// 返回请求参数
|
||||||
return { url, headers, body };
|
return { url, headers, body };
|
||||||
}
|
}
|
||||||
|
|
@ -237,20 +246,16 @@ export default class MysZZZApi extends MysApi {
|
||||||
break;
|
break;
|
||||||
case 10102:
|
case 10102:
|
||||||
if (res.message === 'Data is not public for the user') {
|
if (res.message === 'Data is not public for the user') {
|
||||||
this.e.reply(
|
this.e.reply(`\nUID:${this.uid},米游社数据未公开`, false, {
|
||||||
`\nUID:${this.uid},米游社数据未公开`, false, { at: this.userId }
|
at: this.userId,
|
||||||
);
|
});
|
||||||
} else {
|
} else {
|
||||||
this.e.reply(
|
this.e.reply(`UID:${this.uid},请先去米游社绑定角色`);
|
||||||
`UID:${this.uid},请先去米游社绑定角色`
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
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:
|
||||||
case 1034: {
|
case 1034: {
|
||||||
|
|
@ -274,20 +279,14 @@ export default class MysZZZApi extends MysApi {
|
||||||
logger.mark(
|
logger.mark(
|
||||||
`[米游社zzz查询失败][UID:${this.uid}][qq:${this.userId}] 遇到验证码`
|
`[米游社zzz查询失败][UID:${this.uid}][qq:${this.userId}] 遇到验证码`
|
||||||
);
|
);
|
||||||
this.e.reply(
|
this.e.reply('米游社zzz查询遇到验证码,请稍后再试');
|
||||||
'米游社zzz查询遇到验证码,请稍后再试'
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
if (/(登录|login)/i.test(res.message)) {
|
if (/(登录|login)/i.test(res.message)) {
|
||||||
logger.mark(
|
logger.mark(`[ck失效][UID:${this.uid}]`);
|
||||||
`[ck失效][UID:${this.uid}]`
|
this.e.reply(`UID:${this.uid},米游社cookie已失效`);
|
||||||
);
|
|
||||||
this.e.reply(
|
|
||||||
`UID:${this.uid},米游社cookie已失效`
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
this.e.reply(
|
this.e.reply(
|
||||||
`米游社接口报错,暂时无法查询:${res.message || 'error'}`
|
`米游社接口报错,暂时无法查询:${res.message || 'error'}`
|
||||||
|
|
@ -311,6 +310,28 @@ export default class MysZZZApi extends MysApi {
|
||||||
* @param {boolean} cached
|
* @param {boolean} cached
|
||||||
*/
|
*/
|
||||||
async getFinalData(e, type, data = {}, cached = false) {
|
async getFinalData(e, type, data = {}, cached = false) {
|
||||||
|
if (data.deviceFp) {
|
||||||
|
if (!data.headers) data.headers = {};
|
||||||
|
data.headers['x-rpc-device_fp'] = data.deviceFp;
|
||||||
|
}
|
||||||
|
const uid = this.uid;
|
||||||
|
let bindInfo = await redis.get(`ZZZ:DEVICE_FP:${uid}:BIND`);
|
||||||
|
if (bindInfo) {
|
||||||
|
try {
|
||||||
|
bindInfo = JSON.parse(bindInfo);
|
||||||
|
data = {
|
||||||
|
...data,
|
||||||
|
productName: bindInfo?.deviceProduct,
|
||||||
|
deviceType: bindInfo?.deviceName,
|
||||||
|
modelName: bindInfo?.deviceModel,
|
||||||
|
oaid: bindInfo?.oaid,
|
||||||
|
deviceInfo: bindInfo?.deviceFingerprint,
|
||||||
|
board: bindInfo?.deviceBoard,
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
bindInfo = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
const result = await this.getData(type, data, cached);
|
const result = await this.getData(type, data, cached);
|
||||||
const _data = await this.checkCode(e, result, type, {});
|
const _data = await this.checkCode(e, result, type, {});
|
||||||
if (!_data || _data.retcode !== 0) return false;
|
if (!_data || _data.retcode !== 0) return false;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { generateSeed } from '../../utils/data.js';
|
import { generateSeed, randomString } from '../../utils/data.js';
|
||||||
import crypto from 'crypto';
|
import crypto from 'crypto';
|
||||||
/**
|
/**
|
||||||
* derived from miao-yunzai
|
* derived from miao-yunzai
|
||||||
|
|
@ -73,6 +73,15 @@ export default class ZZZApiTool {
|
||||||
}
|
}
|
||||||
|
|
||||||
getUrlMap = (data = {}) => {
|
getUrlMap = (data = {}) => {
|
||||||
|
const {
|
||||||
|
productName = 'J9110',
|
||||||
|
deviceType = 'J9110',
|
||||||
|
modelName = 'Sony',
|
||||||
|
oaid = 'e3ba65d61709d17074a306072a7c3a2ec70e6d374ca6d29eb6b1b965cbb68e23',
|
||||||
|
deviceInfo = `Sony\/J9110\/J9110:11\/55.2.A.4.332\/055002A004033203408384484:user\/release-keys`,
|
||||||
|
board = 'msmnile',
|
||||||
|
} = data;
|
||||||
|
const deviceBrand = deviceInfo.split('/')[0];
|
||||||
let urlMap = {
|
let urlMap = {
|
||||||
zzz: {
|
zzz: {
|
||||||
...(['prod_gf_cn'].includes(this.server)
|
...(['prod_gf_cn'].includes(this.server)
|
||||||
|
|
@ -82,9 +91,13 @@ export default class ZZZApiTool {
|
||||||
body: {
|
body: {
|
||||||
seed_id: `${generateSeed(13)}`,
|
seed_id: `${generateSeed(13)}`,
|
||||||
device_id: data.deviceId,
|
device_id: data.deviceId,
|
||||||
platform: '1',
|
platform: '2',
|
||||||
seed_time: new Date().getTime() + '',
|
seed_time: new Date().getTime() + '',
|
||||||
ext_fields: `{"romRemain":"16357","romCapacity":"121947","osVersion":"15.7.1","ramCapacity":"3662","ramRemain":"62","appUpdateTimeDiff":"1722253089969","isJailBreak":"0","cpuCores":"6","magnetometer":"-205.693817x20.642471x-103.278427","vendor":"中国电信","networkType":"WIFI","gyroscope":"0.371554x0.804200x-0.526751","appMemory":"82","packageName":"com.miHoYo.mhybbs","model":"iPhone13,2","hasVpn":"1","appInstallTimeDiff":"1722253055560","screenBrightness":"0.063","cpuType":"CPU_TYPE_ARM64","chargeStatus":"1","packageVersion":"2.20.1","IDFV":"${data.deviceId.toUpperCase()}","deviceName":"navel","buildTime":"1719312801323","accelerometer":"0.044586x-0.842255x-0.624100","screenSize":"390×844","proxyStatus":"1","isPushEnabled":"0","isSimInserted":"1","batteryStatus":"46"}`,
|
ext_fields: `{"cpuType":"arm64-v8a","romCapacity":"512","productName":"${productName}","romRemain":"422","manufacturer":"${deviceBrand}","appMemory":"512","hostname":"dg02-pool03-kvm87","screenSize":"1264x2640","osVersion":"13","aaid":"${randomString(
|
||||||
|
64
|
||||||
|
)}","vendor":"中国联通","accelerometer":"0.44027936x7.256833x6.422336","buildTags":"release-keys","model":"${modelName}","brand":"XiaoMi","oaid":"${oaid}","hardware":"qcom","deviceType":"${deviceType}","devId":"REL","serialNumber":"unknown","buildTime":"1687848011000","buildUser":"root","ramCapacity":"469679","magnetometer":"20.081251x-27.487501x2.1937501","display":"${modelName}_13.1.0.181(CN01)","ramRemain":"215344","deviceInfo":"${deviceInfo}","gyroscope":"0.030226856x0.014647375x0.010652636","vaid":"${randomString(
|
||||||
|
64
|
||||||
|
)}","buildType":"user","sdkVersion":"33","board":"${board}"}`,
|
||||||
bbs_device_id: data.deviceId,
|
bbs_device_id: data.deviceId,
|
||||||
app_name: 'bbs_cn',
|
app_name: 'bbs_cn',
|
||||||
device_fp: '38d7fc717dc22',
|
device_fp: '38d7fc717dc22',
|
||||||
|
|
@ -101,7 +114,7 @@ export default class ZZZApiTool {
|
||||||
hoyolab_device_id: `${this.uuid}`,
|
hoyolab_device_id: `${this.uuid}`,
|
||||||
platform: '2',
|
platform: '2',
|
||||||
seed_time: new Date().getTime() + '',
|
seed_time: new Date().getTime() + '',
|
||||||
ext_fields: `{"proxyStatus":1,"isRoot":1,"romCapacity":"512","deviceName":"Xperia 1","productName":"J9110","romRemain":"483","hostname":"BuildHost","screenSize":"1096x2434","isTablet":0,"model":"J9110","brand":"Sony","hardware":"qcom","deviceType":"J9110","devId":"REL","serialNumber":"unknown","sdCapacity":107433,"buildTime":"1633631032000","buildUser":"BuildUser","simState":1,"ramRemain":"98076","appUpdateTimeDiff":1716545162858,"deviceInfo":"Sony\/J9110\/J9110:11\/55.2.A.4.332\/055002A004033203408384484:user\/release-keys","buildType":"user","sdkVersion":"30","ui_mode":"UI_MODE_TYPE_NORMAL","isMockLocation":0,"cpuType":"arm64-v8a","isAirMode":0,"ringMode":2,"app_set_id":"${this.uuid}","chargeStatus":1,"manufacturer":"Sony","emulatorStatus":0,"appMemory":"512","adid":"${this.uuid}","osVersion":"11","vendor":"unknown","accelerometer":"-0.9233304x7.574181x6.472585","sdRemain":97931,"buildTags":"release-keys","packageName":"com.mihoyo.hoyolab","networkType":"WiFi","debugStatus":1,"ramCapacity":"107433","magnetometer":"-9.075001x-27.300001x-3.3000002","display":"55.2.A.4.332","appInstallTimeDiff":1716489549794,"packageVersion":"","gyroscope":"0.027029991x-0.04459185x0.032222193","batteryStatus":45,"hasKeyboard":0,"board":"msmnile"}`,
|
ext_fields: `{"proxyStatus":1,"isRoot":1,"romCapacity":"512","deviceName":"Xperia 1","productName":"${productName}","romRemain":"483","hostname":"BuildHost","screenSize":"1096x2434","isTablet":0,"model":"${modelName}","brand":"${deviceBrand}","hardware":"qcom","deviceType":"${deviceType}","oaid":"${oaid}","devId":"REL","serialNumber":"unknown","sdCapacity":107433,"buildTime":"1633631032000","buildUser":"BuildUser","simState":1,"ramRemain":"98076","appUpdateTimeDiff":1716545162858,"deviceInfo":"${deviceInfo}","buildType":"user","sdkVersion":"30","ui_mode":"UI_MODE_TYPE_NORMAL","isMockLocation":0,"cpuType":"arm64-v8a","isAirMode":0,"ringMode":2,"app_set_id":"${this.uuid}","chargeStatus":1,"manufacturer":"${deviceBrand}","emulatorStatus":0,"appMemory":"512","adid":"${this.uuid}","osVersion":"11","vendor":"unknown","accelerometer":"-0.9233304x7.574181x6.472585","sdRemain":97931,"buildTags":"release-keys","packageName":"com.mihoyo.hoyolab","networkType":"WiFi","debugStatus":1,"ramCapacity":"107433","magnetometer":"-9.075001x-27.300001x-3.3000002","display":"${modelName}","appInstallTimeDiff":1716489549794,"packageVersion":"","gyroscope":"0.027029991x-0.04459185x0.032222193","batteryStatus":45,"hasKeyboard":0,"board":"${board}"}`,
|
||||||
app_name: 'bbs_oversea',
|
app_name: 'bbs_oversea',
|
||||||
device_fp: '38d7f2352506c',
|
device_fp: '38d7f2352506c',
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ export class ZZZPlugin extends plugin {
|
||||||
// 创建米游社 API 对象
|
// 创建米游社 API 对象
|
||||||
const api = new MysZZZApi(uid, ck);
|
const api = new MysZZZApi(uid, ck);
|
||||||
// 获取设备指纹
|
// 获取设备指纹
|
||||||
let deviceFp = await redis.get(`ZZZ:DEVICE_FP:${uid}`);
|
let deviceFp = await redis.get(`ZZZ:DEVICE_FP:${uid}:FP`);
|
||||||
if (!deviceFp) {
|
if (!deviceFp) {
|
||||||
const sdk = api.getUrl('getFp');
|
const sdk = api.getUrl('getFp');
|
||||||
const res = await fetch(sdk.url, {
|
const res = await fetch(sdk.url, {
|
||||||
|
|
@ -65,9 +65,10 @@ export class ZZZPlugin extends plugin {
|
||||||
body: sdk.body,
|
body: sdk.body,
|
||||||
});
|
});
|
||||||
const fpRes = await res.json();
|
const fpRes = await res.json();
|
||||||
|
logger.debug(`[米游社][设备指纹]${JSON.stringify(fpRes)}`);
|
||||||
deviceFp = fpRes?.data?.device_fp;
|
deviceFp = fpRes?.data?.device_fp;
|
||||||
if (deviceFp) {
|
if (deviceFp) {
|
||||||
await redis.set(`ZZZ:DEVICE_FP:${uid}`, deviceFp, {
|
await redis.set(`ZZZ:DEVICE_FP:${uid}:FP`, deviceFp, {
|
||||||
EX: 86400 * 7,
|
EX: 86400 * 7,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -86,10 +87,12 @@ export class ZZZPlugin extends plugin {
|
||||||
*/
|
*/
|
||||||
async getPlayerInfo() {
|
async getPlayerInfo() {
|
||||||
// 获取 米游社 API
|
// 获取 米游社 API
|
||||||
const { api, uid } = await this.getAPI();
|
const { api, uid, deviceFp } = await this.getAPI();
|
||||||
if (!api) return false;
|
if (!api) return false;
|
||||||
// 获取用户信息
|
// 获取用户信息
|
||||||
let userData = await api.getFinalData(this.e, 'zzzUser');
|
let userData = await api.getFinalData(this.e, 'zzzUser', {
|
||||||
|
deviceFp,
|
||||||
|
});
|
||||||
if (!userData) return false;
|
if (!userData) return false;
|
||||||
// 取第一个用户信息
|
// 取第一个用户信息
|
||||||
userData =
|
userData =
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue