mirror of
https://github.com/yoimiya-kokomi/miao-plugin.git
synced 2024-11-16 04:35:42 +00:00
将User、MysApi的使用改为主框架的引用
This commit is contained in:
parent
90d50c6b72
commit
4fc34783b8
@ -22,31 +22,42 @@ export async function init(isUpdate = false) {
|
||||
}
|
||||
|
||||
// 查看当前角色
|
||||
export async function character(e, { render, MysApi }) {
|
||||
let name = e.msg.replace(/#|老婆|老公|[1|2|5][0-9]{8}/g, "").trim();
|
||||
export async function character(e, { render, MysApi, User }) {
|
||||
|
||||
if (!e.msg) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
let name = e.msg.replace(/#?|老婆|老公|[1|2|5][0-9]{8}/g, "").trim();
|
||||
let char = Character.get(name);
|
||||
if (!char) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
let check = await User.checkAuth(e, "bind", {
|
||||
action: "查询角色详情"
|
||||
});
|
||||
if (!check) {
|
||||
return true;
|
||||
}
|
||||
|
||||
let roleId = char.id;
|
||||
|
||||
getUrl = MysApi.getUrl;
|
||||
getServer = MysApi.getServer;
|
||||
|
||||
let uidRes = await getUid(e);
|
||||
if (!uidRes.uid && uidRes.isSelf) {
|
||||
e.reply("请先发送#+你游戏的uid");
|
||||
let { selfUser, targetUser } = e;
|
||||
if (!targetUser.uid) {
|
||||
e.reply("未能找到查询角色");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(await limitGet(e))) return true;
|
||||
let uid = targetUser.uid;
|
||||
|
||||
let uid = uidRes.uid;
|
||||
let res = await MysApi.requestData(e, uid, "character");
|
||||
|
||||
let res = await mysApi(e, uid, "character", {
|
||||
role_id: uid,
|
||||
server: getServer(uid),
|
||||
});
|
||||
|
||||
if (res.retcode == "-1") {
|
||||
return true;
|
||||
@ -97,7 +108,6 @@ export async function character(e, { render, MysApi }) {
|
||||
bg: getCharacterImg(char.name),
|
||||
...getCharacterData(avatars),
|
||||
ds: char.getData("name,id,title,desc"),
|
||||
|
||||
}, "png");
|
||||
|
||||
if (base64) {
|
||||
|
@ -1,295 +0,0 @@
|
||||
import UserModel from "./models/UserModel.js";
|
||||
import { segment } from "oicq";
|
||||
import fetch from "node-fetch";
|
||||
import { MysApi } from "./index.js";
|
||||
import md5 from "md5";
|
||||
|
||||
const getUidByToken = async function (token) {
|
||||
let ltoken = `ltoken=${token["ltoken"]}ltuid=${token["ltuid"]};`;
|
||||
let cookie_token = `cookie_token=${token["cookie_token"]} account_id=${token["ltuid"]};`;
|
||||
ltoken += cookie_token;
|
||||
let uid = 0;
|
||||
let url = host + "binding/api/getUserGameRolesByCookie?game_biz=hk4e_cn";
|
||||
|
||||
await MysApi.fetch(url, {
|
||||
method: "get",
|
||||
cookie: ltoken,
|
||||
error: async () => {
|
||||
throw `cookie错误:${res.message}`;
|
||||
},
|
||||
success: async (data) => {
|
||||
for (let val of data.list) {
|
||||
//米游社默认展示的角色
|
||||
if (val.is_chosen) {
|
||||
uid = val.game_uid;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!uid) {
|
||||
uid = data.list[0].game_uid;
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
return uid;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
let User = {};
|
||||
|
||||
/*
|
||||
* 在文本中检索uid,若未查找到则返回false
|
||||
* */
|
||||
User.matchUid = function (msg) {
|
||||
let ret = /[1|2|5][0-9]{8}/g.exec(msg);
|
||||
if (ret) {
|
||||
return ret[0];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* 返回需要绑定 cookie
|
||||
*
|
||||
* */
|
||||
User.replyNeedBind = function (e, replyMsg = "") {
|
||||
replyMsg = replyMsg || `您尚未绑定米游社cookie,无法进行操作`;
|
||||
let helpMsg = "获取cookie后发送至当前聊天窗口即可,Cookie获取方式:https://docs.qq.com/doc/DUWNVQVFTU3liTVlO";
|
||||
|
||||
if (e.isGroup) {
|
||||
replyMsg = segment.image(`file:///${_path}/resources/help/help.png`);
|
||||
e.reply([replyMsg, helpMsg]);
|
||||
} else {
|
||||
e.reply(replyMsg);
|
||||
e.reply(helpMsg);
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
/*
|
||||
* 获取当前用户消息所查询的目标用户
|
||||
*
|
||||
* 策略:优先级依次递减
|
||||
* 1. 消息里包含 uid
|
||||
* 2. 存在 msg.at,且msg.at 用户 是绑定用户
|
||||
* 3. 存在 msg.at 且msg.at 名片包含uid
|
||||
* 4. 当前用户为绑定用户
|
||||
* 5. 当前用户名片包含 uid
|
||||
* 6. 当前用户存在redis-uid 缓存
|
||||
* */
|
||||
User.getTargetUser = async function (e, selfUser) {
|
||||
let res;
|
||||
let reg = /[1|2|5][0-9]{8}/g;
|
||||
let msg = e.msg;
|
||||
|
||||
let targetId, targetUser;
|
||||
|
||||
/*-- 有指定的查询目标 --*/
|
||||
|
||||
/* 消息里包含 uid的话优先匹配 */
|
||||
if (e.msg) {
|
||||
targetId = getUid(e.msg);
|
||||
if (targetId) {
|
||||
// 根据targetId查找用户
|
||||
targetUser = await User.get({ uid: targetId });
|
||||
//存在则返回,不存在则将该uid绑定至当前用户
|
||||
if (targetUser) {
|
||||
return targetUser;
|
||||
}
|
||||
|
||||
let selfUserBindUid = await selfUser.getRegUid();
|
||||
// 当前用户未注册,则将uid绑定至当前用户
|
||||
if (!selfUser.isBind || selfUser.uid == targetId) {
|
||||
await selfUser.setRegUid(targetId)
|
||||
return selfUser;
|
||||
} else {
|
||||
// 当前用户为注册用户,返回 Draft
|
||||
return User.get({ uid: targetId }, true)
|
||||
}
|
||||
|
||||
|
||||
selfUser.setRegUid(targetId);
|
||||
return selfUser;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// 如果有at的用户,使用被at的用户
|
||||
if (!targetId && e.at) {
|
||||
targetUser = await User.get({ qq: e.at.qq });
|
||||
|
||||
// 识别at用户的名片结果。如果at用户无uid信息则使用此结果
|
||||
targetId = getUid(e.at.card.toString());
|
||||
|
||||
if (targetUser) {
|
||||
targetUser
|
||||
}
|
||||
}
|
||||
|
||||
if (targetUser) {
|
||||
let targetUserUid = await targetUser.getRegUid();
|
||||
targetUser.setRegUid(targetUserUid || targetId)
|
||||
if (!targetId && !targetUserUid) {
|
||||
// return false;
|
||||
}
|
||||
}
|
||||
|
||||
targetUser = selfUser;
|
||||
// 使用当前用户作为targetUser
|
||||
if (selfUser.isBind) {
|
||||
// 设置查询用户为当前用户
|
||||
targetUser = selfUser;
|
||||
|
||||
// 从当前用户的昵称中匹配uid
|
||||
targetId = getUid(e.sender.card.toString());
|
||||
} else if (false) {
|
||||
// selfUser.uid =
|
||||
}
|
||||
|
||||
selfUser.setRegUid(uid);
|
||||
|
||||
|
||||
// 存在查询用户,但无
|
||||
if (!targetUser && targetId) {
|
||||
// 根据uid创建的用户包含uid
|
||||
return User.get({ uid: targetId }, true);
|
||||
|
||||
} else if (targetUser && targetId) {
|
||||
// 存在目标用户,但不存在查询uid的话,赋值给targetUser
|
||||
if (!targetUser.uid && targetId) {
|
||||
targetUser.uid = targetId;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
if (targetUser) {
|
||||
targetUser.setLastQuery(targetUser.id);
|
||||
}
|
||||
|
||||
return targetUser;
|
||||
|
||||
|
||||
//从redis获取
|
||||
res = await redis.get(`genshin:uid:${e.user_id}`);
|
||||
if (res) {
|
||||
redis.expire(`genshin:uid:${e.user_id}`, 2592000);
|
||||
return { isSelf: true, uid: res };
|
||||
}
|
||||
return { isSelf: true, uid: false };
|
||||
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* 获取当前 MysApi 的最佳查询User
|
||||
*
|
||||
* 策略,优先级依次递减 ( sUid 在下方代指被查询的Uid )
|
||||
* 1. 如果 sUid 为绑定用户,优先使用绑定用户自身的 cookie( 在不允许跨系统调用时需传递 allowCrossUid = false )
|
||||
* 2. 如果 sUid 24小时内被查询过,优先使用曾经查询过该用户的 cookie
|
||||
* 3. 如果 当前查询用户为绑定用户,优先使用绑定用户自身的 cookie
|
||||
* 4. 使用系统cookie : 暂未接管bot逻辑,目前需要传入getBotCookie方法
|
||||
*
|
||||
* */
|
||||
User.getReqUser = async function (e, allowCrossUser = true, getBotCookie=false) {
|
||||
|
||||
// 当前用户
|
||||
let selfUser = User.get(e.user_id);
|
||||
|
||||
// 被查询用户
|
||||
let targetUser = await User.getTargetUser(e);
|
||||
|
||||
// 如果 sUid 为绑定用户,优先使用绑定用户自身的 cookie
|
||||
if (targetUser.isBind && allowCrossUser) {
|
||||
return targetUser;
|
||||
}
|
||||
|
||||
// 如果 sUid 24小时内被查询过,优先使用曾经查询过该用户的 cookie
|
||||
let lastQueryUser = targetUser.getSourceUser();
|
||||
if (lastQueryUser) {
|
||||
return lastQueryUser;
|
||||
}
|
||||
|
||||
// 如果 当前查询用户为绑定用户,优先使用绑定用户自身的 cookie
|
||||
if (selfUser.isBind) {
|
||||
await targetUser.setSourceUser(selfUser);
|
||||
return selfUser;
|
||||
}
|
||||
|
||||
// 使用系统 cookie
|
||||
// 将系统注册的cookie视作机器人,同样包装为 User 用户返回
|
||||
let botUser = User.getAvailableBot(e, true);
|
||||
if (botUser) {
|
||||
await targetUser.setSourceUser(botUser);
|
||||
return botUser;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/*
|
||||
* 对当前用户的类型进行检查,并对不符合条件的用户进行回复
|
||||
* type: all-不检查,bind-绑定用户(设置了有效的NoteCookie),master-管理员
|
||||
* replyMsg:不符合条件的消息
|
||||
* */
|
||||
User.check = async function (e, type = "all", checkParams = {}) {
|
||||
let self = User.get(e.user_id);
|
||||
|
||||
let { limit = true, action, replyMsg } = checkParams;
|
||||
|
||||
// 校验频度限制
|
||||
if (limit) {
|
||||
if (!(await limitGet(e))) return true;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case 'bind':
|
||||
// 需要是绑定用户
|
||||
if (!self.isBind) {
|
||||
if (!replyMsg) {
|
||||
action = action || "进行操作";
|
||||
replyMsg = "您尚未绑定米游社cookie,无法" + action;
|
||||
}
|
||||
User.replyNeedBind(e, replyMsg);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'master':
|
||||
if (!self.isMaster) {
|
||||
// 如果主动传递了replyMsg则进行回复,否则静默
|
||||
if (replyMsg) {
|
||||
e.reply(replyMsg)
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
case 'all':
|
||||
//不检查权限
|
||||
return self;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return self;
|
||||
};
|
||||
|
||||
/*
|
||||
* 获取可用的机器人,作为UserModel返回
|
||||
* noticeError: 在无可用机器人时是否 e.reply 错误信息
|
||||
* */
|
||||
// TODO: 待实现
|
||||
User.getAvailableBot = async function (e, noticeError = false) {
|
||||
let id = md5("BOT_" & md5('cookie'));
|
||||
|
||||
User.get(md5);
|
||||
User.bindCookie(cookie, {
|
||||
isBot: true
|
||||
});
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
export default User;
|
||||
|
@ -1,273 +0,0 @@
|
||||
/*
|
||||
* UserModel Class
|
||||
* 提供用户实例相关的操作方法
|
||||
*
|
||||
* * TODO:将与具体用户操作相关的方法逐步迁移到UserModel中,外部尽量只调用实例方法
|
||||
* 以确保逻辑收敛且维护性更强
|
||||
* */
|
||||
import BaseModel from "./BaseModel.js"
|
||||
import lodash from "lodash";
|
||||
import md5 from "md5";
|
||||
import { MysApi, Data } from "../index.js";
|
||||
|
||||
const _path = process.cwd();
|
||||
const redisPrefix = "cache";
|
||||
|
||||
const userInstanceReclaimTime = 60;
|
||||
let userMap = {};
|
||||
|
||||
// Redis相关操作方法
|
||||
const Cache = {
|
||||
prefix: "genshin",
|
||||
async get(type, key) {
|
||||
return await redis.get(`${Cache.prefix}:${type}:${key}`);
|
||||
},
|
||||
async set(type, key, val, exp = 2592000) {
|
||||
return await redis.set(`${Cache.prefix}:${type}:${key}`, val, { EX: exp });
|
||||
},
|
||||
async del(type, key) {
|
||||
return await redis.del(`${Cache.prefix}:${type}:${key}`);
|
||||
}
|
||||
};
|
||||
const saveCookieFile = function () {
|
||||
Data.writeJson("./data/NoteCookie/", "NoteCookie", NoteCookie);
|
||||
};
|
||||
|
||||
// UserModel class
|
||||
class UserModel extends BaseModel {
|
||||
|
||||
// 初始化用户
|
||||
constructor(id) {
|
||||
super();
|
||||
// 一个id对应一个用户,根据id检索用户信息
|
||||
this.id = id;
|
||||
|
||||
// 检索是否存在NoteCookie信息
|
||||
let data = NoteCookie[id];
|
||||
|
||||
if (data) {
|
||||
this._data = data;
|
||||
this.isPush = data.isPush;
|
||||
this.isSignAuto = data.isSignAuto;
|
||||
this.uid = data.uid;
|
||||
} else {
|
||||
this._data = {};
|
||||
}
|
||||
}
|
||||
|
||||
// 是绑定的cookie用户
|
||||
// 需要存在NoteCookie记录且存在 cookie 与 uid 才认为是正确记录
|
||||
get isBind() {
|
||||
let dbData = NoteCookie[this.id];
|
||||
return !!(dbData && dbData.cookie && dbData.uid);
|
||||
}
|
||||
|
||||
// 是否是管理员
|
||||
// TODO
|
||||
get isMaster() {
|
||||
return !this.isBot && BotConfig.masterQQ && BotConfig.masterQQ.includes(Number(this.id));
|
||||
}
|
||||
|
||||
get isBot() {
|
||||
// todo
|
||||
return false;
|
||||
}
|
||||
|
||||
// 获取当前用户cookie
|
||||
get cookie() {
|
||||
return this._data.cookie;
|
||||
}
|
||||
|
||||
// 获取当前用户uid
|
||||
get uid() {
|
||||
return this._uid || this._data.uid || this._reg_uid;
|
||||
}
|
||||
|
||||
set uid(uid) {
|
||||
this._uid = uid;
|
||||
this._reg_uid = uid;
|
||||
}
|
||||
|
||||
// 保存用户信息
|
||||
/*
|
||||
async _save() {
|
||||
// todo
|
||||
return
|
||||
|
||||
let data = NoteCookie[this.id] || this._data || {};
|
||||
|
||||
// 将信息更新至 NoteCookie
|
||||
data.id = this.id;
|
||||
data.uid = this._uid || this._data.uid;
|
||||
data.cookie = this._cookie || this._data.cookie;
|
||||
data.isPush = this.isPush;
|
||||
data.isAutoSign = !!this.isAutoSign;
|
||||
|
||||
// 保存信息
|
||||
NoteCookie[this.id] = data;
|
||||
this._data = data;
|
||||
saveCookieFile();
|
||||
|
||||
// 建立当前用户相关缓存
|
||||
await this.refreshCache();
|
||||
return this;
|
||||
}
|
||||
*/
|
||||
|
||||
// 设置&更新用户缓存
|
||||
async refreshCache() {
|
||||
// 设置缓存
|
||||
await Cache.set("id-uid", this.qq, this.uid);
|
||||
await Cache.set("uid-id", this.uid, this.id);
|
||||
Bot.logger.mark(`绑定用户:QQ${this.id},UID${this.uid}`);
|
||||
}
|
||||
|
||||
// 删除用户缓存
|
||||
async delCache() {
|
||||
await Cache.del("id-uid", this.id);
|
||||
await Cache.del("uid-id", this.uid);
|
||||
}
|
||||
|
||||
|
||||
// 获取曾经查询过当前用户的人
|
||||
async getSourceUser() {
|
||||
let lastQuery = await Cache.get("id-source", this.id);
|
||||
|
||||
if (lastQuery) {
|
||||
return UserModel.get(lastQuery);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// 设置曾经查询过当前用户的人,缓存23小时
|
||||
async setSourceUser(user) {
|
||||
await Cache.set("id-source", this.id, user.id, 3600 * 23);
|
||||
}
|
||||
|
||||
// 删除曾经查询过当前用户的人
|
||||
async delSourceUser() {
|
||||
await Cache.del("id-source", this.id);
|
||||
}
|
||||
|
||||
|
||||
/* 获取当前用户注册的uid
|
||||
*
|
||||
* 1. 如果是绑定用户,优先返回当前绑定的uid(cookie 对应uid)
|
||||
* 2. 返回redis中存储的uid
|
||||
*
|
||||
* 注:redis uid需要主动调用一次 getRegUid 才能被this.uid访问到
|
||||
*
|
||||
* */
|
||||
async getRegUid() {
|
||||
if (this.isBind) {
|
||||
return this.uid;
|
||||
}
|
||||
if (!this._reg_uid) {
|
||||
let uid = await Cache.get('id-regUid', this.id);
|
||||
if (uid) {
|
||||
this._reg_uid = uid;
|
||||
}
|
||||
}
|
||||
return this._reg_uid;
|
||||
}
|
||||
|
||||
async setRegUid(uid) {
|
||||
// 只有非绑定用户才设置 注册uid
|
||||
if (!this.isBind) {
|
||||
this._reg_uid = uid;
|
||||
Cache.set('id-regUid', this.id, uid);
|
||||
Cache.set('regUid-id', this.uid, this.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* UserModel static function */
|
||||
|
||||
/*
|
||||
* 获取用户实例
|
||||
* query为获取条件,默认为 id
|
||||
*
|
||||
* */
|
||||
UserModel.get = async function (query, getDraftWhenNotFound = false) {
|
||||
let user = await getUser(query, getDraftWhenNotFound);
|
||||
|
||||
user._reclaimFn && clearTimeout(user._reclaimFn);
|
||||
user._reclaimFn = setTimeout(() => {
|
||||
delete userMap[user.id];
|
||||
}, userInstanceReclaimTime);
|
||||
userMap[user.id] = user;
|
||||
|
||||
return user;
|
||||
};
|
||||
|
||||
// 格式化查询
|
||||
const formatQuery = function (query) {
|
||||
if (typeof (query) === "string") {
|
||||
return { id: query };
|
||||
}
|
||||
return query;
|
||||
};
|
||||
|
||||
let getUser = async function (query, getDraftWhenNotFound = false) {
|
||||
query = formatQuery(query);
|
||||
|
||||
let id = "";
|
||||
// 根据id获取用户
|
||||
if (query.id) {
|
||||
id = query.id;
|
||||
} else if (query.uid) {
|
||||
// 根据uid检索id
|
||||
id = await Cache.get("uid-id", query.uid);
|
||||
if (!id) {
|
||||
// 如未查找到,则从注册uid中检索
|
||||
id = await Cache.get("regUid-id", query.uid)
|
||||
}
|
||||
} else if (query.token) {
|
||||
// 根据token检索id
|
||||
// 不常用,仅用在机器人绑定环节
|
||||
id = await Cache.get("token-id", query.token);
|
||||
}
|
||||
|
||||
// 已有实例优先使用已有的
|
||||
if (userMap[id]) {
|
||||
return userMap[id];
|
||||
}
|
||||
|
||||
// 如果是注册用户,则返回新instance
|
||||
if (NoteCookie[id]) {
|
||||
return new UserModel(id);
|
||||
}
|
||||
|
||||
// 如果允许返回Draft,则生成并返回
|
||||
if (getDraftWhenNotFound) {
|
||||
return getDraft(query);
|
||||
}
|
||||
|
||||
// 未查询到用户则返回false
|
||||
return false;
|
||||
}
|
||||
|
||||
let getDraft = function (query) {
|
||||
let id = '';
|
||||
if (query.id) {
|
||||
id = query.id;
|
||||
} else if (query.uid) {
|
||||
id = '_UID_' + query.uid;
|
||||
} else if (query.token) {
|
||||
id = "_CK_" + md5(query.token);
|
||||
}
|
||||
|
||||
let user = new UserModel(id);
|
||||
user.id = query.id;
|
||||
user.uid = query.uid;
|
||||
user.cookie = query.cookie;
|
||||
return user;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
export default UserModel;
|
6
index.js
6
index.js
@ -1,25 +1,29 @@
|
||||
export const rule = {
|
||||
character: {
|
||||
prehash: true,
|
||||
reg: "^#(.*)(#.*)?$",
|
||||
priority: 208,
|
||||
describe: "【#刻晴】角色详情",
|
||||
},
|
||||
setCharacterImg: {
|
||||
prehash: true,
|
||||
reg: "^#(添加|更新)(.*)图片(#.*)?(上|右|下|左)?$",
|
||||
priority: 208,
|
||||
},
|
||||
|
||||
userStat: {
|
||||
prehash: true,
|
||||
reg: "^#*user\s*\d*",
|
||||
priority: 200
|
||||
},
|
||||
rebuildCookie: {
|
||||
prehash: true,
|
||||
reg: "#rebuild"
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
import { character, setCharacterImg } from "./apps/character.js";
|
||||
import {userStat, rebuildCookie} from "./apps/admin.js";
|
||||
import { userStat, rebuildCookie } from "./apps/admin.js";
|
||||
|
||||
export { character, setCharacterImg, userStat, rebuildCookie };
|
||||
|
Loading…
Reference in New Issue
Block a user