finish pipe

This commit is contained in:
锦恢 2024-06-01 02:14:46 +08:00
parent a13a6ba34f
commit c27bb27ec3
8 changed files with 487 additions and 147 deletions

View File

@ -9,12 +9,12 @@
import * as Lagrange from '../type';
/**
* @description
* @description
* @param user_id QQ
* @param message
* @param auto_escape CQ message
*/
export function sendPrivateMsg(user_id: number, message: Lagrange.Message, auto_escape: boolean = false) {
export function sendPrivateMsg(user_id: number, message: string | Lagrange.Send.Default[], auto_escape: boolean = false) {
return {
action: 'send_private_msg',
params: { user_id, message, auto_escape }
@ -22,12 +22,12 @@ export function sendPrivateMsg(user_id: number, message: Lagrange.Message, auto_
}
/**
* @description
* @description
* @param group_id
* @param message
* @param auto_escape CQ message
*/
export function sendGroupMsg(group_id: number, message: Lagrange.Message, auto_escape: boolean = false) {
export function sendGroupMsg(group_id: number, message: string | Lagrange.Send.Default[], auto_escape: boolean = false) {
return {
action: 'send_group_msg',
params: { group_id, message, auto_escape }
@ -35,14 +35,14 @@ export function sendGroupMsg(group_id: number, message: Lagrange.Message, auto_e
}
/**
* @description
* @description
* @param message_type privategroup *_id
* @param user_id QQ private
* @param group_id group
* @param message
* @param auto_escape CQ message
*/
export function sendMsg(message_type: string, user_id: number, group_id: number, message: Lagrange.Message, auto_escape: boolean = false) {
export function sendMsg(message_type: string, user_id: number, group_id: number, message: string | Lagrange.Send.Default[], auto_escape: boolean = false) {
return {
action: 'send_msg',
params: { message_type, user_id, group_id, message, auto_escape }
@ -50,7 +50,7 @@ export function sendMsg(message_type: string, user_id: number, group_id: number,
}
/**
* @description
* @description
* @param message_id ID
*/
export function deleteMsg(message_id: number) {
@ -61,7 +61,7 @@ export function deleteMsg(message_id: number) {
}
/**
* @description
* @description
* @param message_id ID
*/
export function getMsg(message_id: number) {
@ -72,7 +72,7 @@ export function getMsg(message_id: number) {
}
/**
* @description
* @description
* @param id ID
*/
export function getForwardMsg(id: string) {
@ -83,7 +83,7 @@ export function getForwardMsg(id: string) {
}
/**
* @description
* @description
* @param user_id QQ
* @param times 10
*/
@ -95,7 +95,7 @@ export function sendLike(user_id: number, times: number = 1) {
}
/**
* @description
* @description
* @param group_id
* @param user_id QQ
* @param reject_add_request
@ -108,7 +108,7 @@ export function setGroupKick(group_id: number, user_id: number, reject_add_reque
}
/**
* @description
* @description
* @param group_id
* @param user_id QQ
* @param duration 0
@ -121,7 +121,7 @@ export function setGroupBan(group_id: number, user_id: number, duration: number
}
/**
* @description
* @description
* @param group_id
* @param anonymous anonymous
* @param anonymous_flag flag
@ -135,7 +135,7 @@ export function setGroupAnonymousBan(group_id: number, anonymous: object, anonym
}
/**
* @description
* @description
* @param group_id
* @param enable
*/
@ -147,7 +147,7 @@ export function setGroupWholeBan(group_id: number, enable: boolean = true) {
}
/**
* @description
* @description
* @param group_id
* @param user_id QQ
* @param enable true false
@ -160,7 +160,7 @@ export function setGroupAdmin(group_id: number, user_id: number, enable: boolean
}
/**
* @description
* @description
* @param group_id
* @param enable
*/
@ -172,7 +172,7 @@ export function setGroupAnonymous(group_id: number, enable: boolean = true) {
}
/**
* @description
* @description
* @param group_id
* @param user_id QQ
* @param card
@ -185,7 +185,7 @@ export function setGroupCard(group_id: number, user_id: number, card: string = "
}
/**
* @description
* @description
* @param group_id
* @param group_name
*/
@ -197,7 +197,7 @@ export function setGroupName(group_id: number, group_name: string) {
}
/**
* @description 退
* @description 退
* @param group_id
* @param is_dismiss true
*/
@ -209,7 +209,7 @@ export function setGroupLeave(group_id: number, is_dismiss: boolean = false) {
}
/**
* @description
* @description
* @param group_id
* @param user_id QQ
* @param special_title
@ -223,7 +223,7 @@ export function setGroupSpecialTitle(group_id: number, user_id: number, special_
}
/**
* @description
* @description
* @param flag flag
* @param approve
* @param remark
@ -236,7 +236,7 @@ export function setFriendAddRequest(flag: string, approve: boolean = true, remar
}
/**
* @description
* @description
* @param flag flag
* @param sub_type add invite sub_type
* @param approve
@ -250,7 +250,7 @@ export function setGroupAddRequest(flag: string, sub_type: string, approve: bool
}
/**
* @description
* @description
*/
export function getLoginInfo() {
return {
@ -260,7 +260,7 @@ export function getLoginInfo() {
}
/**
* @description
* @description
* @param user_id QQ
* @param no_cache 使使
*/
@ -272,7 +272,7 @@ export function getStrangerInfo(user_id: number, no_cache: boolean = false) {
}
/**
* @description
* @description
*/
export function getFriendList() {
return {
@ -282,7 +282,7 @@ export function getFriendList() {
}
/**
* @description
* @description
* @param group_id
* @param no_cache 使使
*/
@ -294,7 +294,7 @@ export function getGroupInfo(group_id: number, no_cache: boolean = false) {
}
/**
* @description
* @description
*/
export function getGroupList() {
return {
@ -304,7 +304,7 @@ export function getGroupList() {
}
/**
* @description
* @description
* @param group_id
* @param user_id QQ
* @param no_cache 使使
@ -317,7 +317,7 @@ export function getGroupMemberInfo(group_id: number, user_id: number, no_cache:
}
/**
* @description
* @description
* @param group_id
*/
export function getGroupMemberList(group_id: number) {
@ -328,7 +328,7 @@ export function getGroupMemberList(group_id: number) {
}
/**
* @description
* @description
* @param group_id
* @param type talkative performer legend strong_newbie emotion all
*/
@ -340,7 +340,7 @@ export function getGroupHonorInfo(group_id: number, type: string) {
}
/**
* @description Cookies
* @description Cookies
* @param domain cookies
*/
export function getCookies(domain: string = "") {
@ -351,7 +351,7 @@ export function getCookies(domain: string = "") {
}
/**
* @description CSRF Token
* @description CSRF Token
*/
export function getCsrfToken() {
return {
@ -361,7 +361,7 @@ export function getCsrfToken() {
}
/**
* @description QQ
* @description QQ
*/
export function getCredentials() {
return {
@ -371,7 +371,7 @@ export function getCredentials() {
}
/**
* @description
* @description
*/
export function getRecord() {
return {
@ -381,7 +381,7 @@ export function getRecord() {
}
/**
* @description
* @description
* @param file file 6B4DE3DFD1BD271E3297859D41C530F5.jpg
*/
export function getImage(file: string) {
@ -392,7 +392,7 @@ export function getImage(file: string) {
}
/**
* @description
* @description
*/
export function canSendImage() {
return {
@ -402,7 +402,7 @@ export function canSendImage() {
}
/**
* @description
* @description
*/
export function canSendRecord() {
return {
@ -412,7 +412,7 @@ export function canSendRecord() {
}
/**
* @description
* @description
*/
export function getStatus() {
return {
@ -422,7 +422,7 @@ export function getStatus() {
}
/**
* @description
* @description
*/
export function getVersionInfo() {
return {
@ -432,7 +432,7 @@ export function getVersionInfo() {
}
/**
* @description OneBot
* @description OneBot
*/
export function setRestart() {
return {
@ -442,7 +442,7 @@ export function setRestart() {
}
/**
* @description
* @description
*/
export function cleanCache() {
return {

View File

@ -1,50 +1,63 @@
import type * as Lagrange from './type';
import lagrangeMapper from './lagrange-mapping';
function runPipe(message: Lagrange.Message) {
switch (message.post_type) {
case 'message': messagePipe(message); break;
case 'notice': noticePipe(message); break;
case 'request': requestPipe(message); break;
default: break;
import type * as Lagrange from './type';
import type { LagrangeContext } from './context';
class Pipe {
context: LagrangeContext | undefined;
send: Lagrange.SendApi | undefined;
public injectContext(context: LagrangeContext) {
this.context = context;
this.send = context.send.bind(context);
}
public run(message: Lagrange.Message) {
switch (message.post_type) {
case 'message': this.messagePipe(message); break;
case 'notice': this.noticePipe(message); break;
case 'request':this.requestPipe(message); break;
default: break;
}
}
// 处理 message 类型的 post_type 消息
public messagePipe(message: Lagrange.MessagePostType) {
switch (message.message_type) {
case 'private':
lagrangeMapper.resolvePrivateUser(message, this.send);
break;
case 'group':
lagrangeMapper.resolveGroup(message, this.send);
break;
default:
break;
}
}
// 处理 notice 类型的 post_type 消息
public noticePipe(message: Lagrange.NoticePostType) {
}
// 处理 request 类型的 post_type 消息
public requestPipe(message: Lagrange.RequestPostType) {
}
}
// 处理 message 类型的 post_type 的
function messagePipe(message: Lagrange.MessagePostType) {
switch (message.message_type) {
case 'private':
break;
case 'group':
break;
default:
break;
}
}
// 处理 notice 类型的 post_type 消息
function noticePipe(message: Lagrange.NoticePostType) {
}
// 处理 request 类型的 post_type 消息
function requestPipe(message: Lagrange.RequestPostType) {
}
export const pipe = new Pipe();
export function onMessage(event: Buffer) {
const messageBuffer = event.toString('utf-8');
const messageJson = JSON.parse(messageBuffer) as Lagrange.Message;
// 忽略系统 message
if (messageJson.post_type !== 'meta_event') {
runPipe(messageJson);
console.log('进入 runPipe');
pipe.run(messageJson);
}
}
export function onClose() {
console.log('服务器连接关闭');
}
}

View File

@ -1,13 +1,15 @@
import lagrangeMapper from './lagrange-mapping';
import { apiQueryVecdb } from './api/vecdb';
import type * as Lagrange from './type';
class Impl {
export class Impl {
@lagrangeMapper.onPrivateUser({ user_id: 1193466151 })
async handleJinhui(message: Lagrange.PrivateMessage) {
@lagrangeMapper.onPrivateUser(1193466151)
async handleJinhui(c: Lagrange.PrivateUserInvokeContext) {
console.log('raw message:' + c.message.raw_message);
}
}

View File

@ -1,8 +1,9 @@
import assert from 'assert';
import type * as Lagrange from './type';
type PrivateUserInvoker = (message: Lagrange.PrivateMessage) => void;
type GroupUserInvoker = (message: Lagrange.GroupMessage) => void;
type PrivateUserInvoker = (context: Lagrange.PrivateUserInvokeContext) => Lagrange.Thenable<undefined | void | string | Lagrange.Send.Default>;
type GroupUserInvoker = (context: Lagrange.GroupUserInvokeContext) => Lagrange.Thenable<undefined | void | string | Lagrange.Send.Default>;
type MessageInvoker = PrivateUserInvoker | GroupUserInvoker;
@ -17,7 +18,7 @@ interface CustomDescriptor<T extends MessageInvoker> {
interface MessageInvokerStorage<T extends MessageInvoker> {
invoker: T;
config: Partial<Lagrange.CommonMessage>
config?: Partial<Lagrange.CommonMessage>
}
class LagrangeMapper {
@ -37,24 +38,33 @@ class LagrangeMapper {
return this._groupStorage;
}
public matchPrivateUser(message: Lagrange.PrivateMessage) {
public resolvePrivateUser(message: Lagrange.PrivateMessage, send: Lagrange.SendApi) {
const user_id = message.user_id;
const userStorage = this._privateUserStorage.get(user_id);
console.log(user_id);
console.log(userStorage);
if (userStorage) {
userStorage.invoker(message);
userStorage.invoker({ message, send });
}
}
public resolveGroup(message: Lagrange.GroupMessage, send: Lagrange.SendApi) {
const group_id = message.group_id;
const groupStorage = this._groupStorage.get(group_id);
if (groupStorage) {
groupStorage.invoker({ message, send });
}
}
public onPrivateUser(config: Partial<Lagrange.CommonMessage>) {
assert(config.user_id, 'onPrivateUser 中 user_id 不能为空');
const _this = this;
public onPrivateUser(user_id: number) {
const _this = this;
return function(target: any, propertyKey: string, descriptor: CustomDescriptor<PrivateUserInvoker>) {
const user_id = config.user_id;
if (_this.privateUserStorage.has(user_id)) {
if (_this._privateUserStorage.has(user_id)) {
console.warn(`${propertyKey} -> 用户 ${user_id} 已经被注册过了,该操作将覆盖原本的!`);
}
const invoker = descriptor.value;
_this.privateUserStorage.set(user_id, { invoker, config });
_this._privateUserStorage.set(user_id, { invoker });
}
}

View File

@ -1,35 +1,14 @@
import * as fs from 'fs';
import WebSocket from 'ws';
import lagServer from './context';
import './impl';
import { onMessage, onClose } from './event';
import { apiQueryVecdb } from './api/vecdb';
const buffer = fs.readFileSync('./app/publish/appsettings.json', 'utf-8');
const config = JSON.parse(buffer);
const impl = config.Implementations[0];
const lagrangeBuffer = fs.readFileSync('./app/publish/appsettings.json', 'utf-8');
const lagrangeConfig = JSON.parse(lagrangeBuffer);
const impl = lagrangeConfig.Implementations[0];
const connectionParam = {
lagServer.run({
host: impl.Host,
port: impl.Port,
path: impl.Suffix
};
const socket = new WebSocket.Server(connectionParam);
socket.on('connection', (ws: WebSocket) => {
console.log('完成 ws 连接,启动参数如下');
console.table(connectionParam);
ws.on('message', onMessage);
ws.on('close', onClose);
const testMsg = {
action: 'send_private_msg',
params: {
user_id: 1193466151,
message: '你好'
}
}
ws.send(JSON.stringify(testMsg));
});
});

View File

@ -1,4 +1,5 @@
import type * as Lagrange from './type';
import * as Lagrange from './type';
class Plugins {
registeredPlugins: Map<string, Function>;

View File

@ -38,36 +38,357 @@ export interface Sender {
title?: string
}
export interface MsgText {
type: 'text',
data: {
text: string
// 参考文档: https://github.com/botuniverse/onebot-11/blob/master/message/segment.md
export namespace Receive {
export interface Text {
type: 'text',
data: {
text: string
}
}
export interface Face {
type: 'face',
data: {
id: string
}
}
export interface Image {
type: 'image',
data: {
file: string,
url: string,
// 在简略窗口可以看到的信息,对于图片来说,这就是 [图片]
summary: string
}
}
export interface Audio {
type: 'record',
data: {
file: string,
magic: 0 | 1,
url: string
}
}
export interface Video {
type: 'video',
data: {
file: string,
url: string
}
}
export interface At {
type: 'at',
data: {
qq: string
}
}
// 猜拳魔法表情
export interface FingerGuess {
type: 'rps',
data: {}
}
// 掷骰子魔法表情
export interface Dice {
type: 'dice',
data: {}
}
// 窗口抖动(戳一戳)
export interface WindowJitter {
type: 'shake',
data: {}
}
// 戳一戳
export interface Poke {
type: 'poke',
data: {
type: string,
id: string,
name: string
}
}
export interface Link {
type: 'share',
data: {
// URL
url: string,
// 标题
title: string,
// 发送时可选,内容描述
content?: string,
// 发送时可选,图片 URL
image?: string
}
}
export interface RecommendFriend {
type: 'contact',
data: {
type: 'qq',
// 被推荐人的 QQ 号
id: string
}
}
export interface RecommendGroup {
type: 'contact',
data: {
type: 'group',
// 被推荐群的群号
id: string
}
}
export interface Location {
type: 'location',
data: {
// 纬度
lat: string,
// 经度
lon: string,
// 发送时可选,标题
title?: string,
// 发送时可选,内容描述
content?: string
}
}
export interface Reply {
type: 'reply',
data: {
id: string
}
}
export interface Forward {
type: 'forward',
data: {
id: string
}
}
export interface XML {
type: 'xml',
data: {
// XML 内容
data: string
}
}
export interface JSON {
type: 'json',
data: {
data: string
}
}
export type Default = Text | Face | Image | Audio | Video | At | FingerGuess | Dice | WindowJitter | Poke | Link | RecommendFriend | RecommendGroup | Location | Reply | Forward | XML | JSON;
}
export interface MsgImage {
type: 'image',
data: {
file: string,
url: string,
// 在简略窗口可以看到的信息,对于图片来说,这就是 [图片]
summary: string
export namespace Send {
export interface Text {
type: 'text',
data: {
text: string
}
}
export interface Face {
type: 'face',
data: {
id: string
}
}
export interface Image {
type: 'image',
data: {
/**
* file
* 1. file:///C:\\Users\Richard\Pictures\1.png
* 2. URL http://i1.piimg.com/567571/fdd6e7b6d93f1ef0.jpg
* Base64 base64://iVBORw0KGgoAAAANSUhEUgAAABQAAAAVCAIAAADJt1n/AAAAKElEQVQ4EWPk5+RmIBcwkasRpG9UM4mhNxpgowFGMARGEwnBIEJVAAAdBgBNAZf+QAAAAABJRU5ErkJggg==
*/
file: string,
// 只在通过网络 URL 发送时有效,表示是否使用已缓存的文件,默认 1
cache: 0 | 1,
// 只在通过网络 URL 发送时有效,表示是否通过代理下载文件(需通过环境变量或配置文件配置代理),默认 1
proxy: 0 | 1,
// 只在通过网络 URL 发送时有效,单位秒,表示下载网络文件的超时时间,默认不超时
timeout: number
}
}
export interface Audio {
type: 'record',
data: {
file: string,
magic: 0 | 1,
cache: 0 | 1,
proxy: 0 | 1,
timeout: number
}
}
export interface Video {
type: 'video',
data: {
file: string,
cache: 0 | 1,
proxy: 0 | 1,
timeout: number
}
}
export interface At {
type: 'at',
data: {
qq: string
}
}
export interface FingerGuess {
type: 'rps',
data: {}
}
export interface Dice {
type: 'dice',
data: {}
}
export interface WindowJitter {
type: 'shake',
data: {}
}
// 戳一戳
export interface Poke {
type: 'poke',
data: {
type: string,
id: string,
}
}
export interface Anonymous {
type: 'anonymous',
data: {}
}
export interface Link {
type: 'share',
data: {
// URL
url: string,
// 标题
title: string,
// 发送时可选,内容描述
content?: string,
// 发送时可选,图片 URL
image?: string
}
}
export interface RecommendFriend {
type: 'contact',
data: {
type: 'qq',
// 被推荐人的 QQ 号
id: string
}
}
export interface RecommendGroup {
type: 'contact',
data: {
type: 'group',
// 被推荐群的群号
id: string
}
}
export interface Location {
type: 'location',
data: {
// 纬度
lat: string,
// 经度
lon: string,
// 发送时可选,标题
title?: string,
// 发送时可选,内容描述
content?: string
}
}
export interface MusicShare {
type: 'music',
data: {
// 分别表示使用 QQ 音乐、网易云音乐、虾米音乐
type: 'qq' | '163' | 'xm',
// 歌曲 ID
id: string
}
}
export interface CustomMusicShare {
type: 'music',
data: {
type: 'custom',
url: string,
audio: string,
title: string,
content: string,
image: string
}
}
export interface Reply {
type: 'reply',
data: {
id: string
}
}
export interface ForwardNode {
type: 'node',
data: {
id: string
}
}
export interface XML {
type: 'xml',
data: {
// XML 内容
data: string
}
}
export interface JSON {
type: 'json',
data: {
data: string
}
}
export type Default = Text | Face | Image | Audio | Video | At | FingerGuess | Dice | WindowJitter | Poke | Anonymous | Link | RecommendFriend | RecommendGroup | Location | MusicShare | CustomMusicShare | Reply | ForwardNode | XML | JSON;
}
export interface MsgFace {
type: 'face',
data: {
id: string
}
}
export interface MsgAt {
type: 'at',
data: {
qq: string
}
}
export interface MsgFile {
// 一般是 ''
@ -103,7 +424,7 @@ export interface CommonMessage {
// 是否为匿名发言,一般都是 null
anonymous?: null | boolean,
// 消息内容(结构化)
message?: MsgText | MsgImage | MsgFace | MsgAt,
message?: Receive.Default,
// 消息内容(纯文本)
raw_message?: string,
// 发送的时间戳
@ -125,7 +446,7 @@ export interface PrivateMessage {
// 发消息的人的 QQ 号
user_id: number,
// 消息内容(结构化)
message: MsgText | MsgImage | MsgFace | MsgAt,
message: Receive.Default,
// 消息内容(纯文本)
raw_message: string,
// 发送的时间戳
@ -136,6 +457,7 @@ export interface PrivateMessage {
font?: number
}
export interface GroupMessage {
// 事件类型
post_type: 'message',
@ -152,7 +474,7 @@ export interface GroupMessage {
// 是否为匿名发言,一般都是 null
anonymous: null | boolean,
// 消息内容(结构化)
message: MsgText | MsgImage | MsgFace | MsgAt,
message: Receive.Default,
// 消息内容(纯文本)
raw_message: string,
// 发送的时间戳
@ -204,4 +526,17 @@ export interface ApproveMessage {
export type Message = MetaMessage | PrivateMessage | GroupMessage | FileMessage | AddMessage | ApproveMessage;
export type MessagePostType = PrivateMessage | GroupMessage;
export type NoticePostType = FileMessage | ApproveMessage;
export type RequestPostType = AddMessage;
export type RequestPostType = AddMessage;
export type Thenable<T> = T | Promise<T>;
export type SendApi = (msg: string | Send.Default[]) => Thenable<void | Error>;
export interface InvokerContext<M = Message> {
message: M,
send: SendApi
}
export type PrivateUserInvokeContext = InvokerContext<PrivateMessage>;
export type GroupUserInvokeContext = InvokerContext<GroupMessage>;

View File

@ -96,11 +96,11 @@ for el in soup.find_all('h2'):
}
if param['type'] == 'message':
param['type'] = 'Lagrange.Message'
param['type'] = 'string | Lagrange.Send.Default[]'
params.append(param)
t1 = function_desc
t1 = function_desc.strip()
t2 = '\n'
for param in params:
t2 += ' * @param {} {}\n'.format(param['name'], param['desc'])