Skip to content

Commit

Permalink
feat: message elements encode and decode
Browse files Browse the repository at this point in the history
  • Loading branch information
BIYUEHU committed Jul 29, 2024
1 parent 31d33e1 commit d2d5071
Show file tree
Hide file tree
Showing 24 changed files with 477 additions and 278 deletions.
1 change: 1 addition & 0 deletions TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,4 @@
- [x] Kotori cli start
- [x] kotori-plugin-request: onGroupMsg and onPrivateMsg
- [ ] webui load tips twice
- [ ] symbols props inject and reality context
7 changes: 3 additions & 4 deletions modules/access/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { UserAccess, Context, MessageScope } from 'kotori-bot'
import { UserAccess, type Context, MessageScope, EventsList } from 'kotori-bot'

export const lang = [__dirname, '../locales']

Expand All @@ -10,13 +10,12 @@ export function main(ctx: Context) {
const load = (bot: string) => ctx.file.load<Data>(`${bot}.json`, 'json', {})
const save = (bot: string, data: Data) => ctx.file.save(`${bot}.json`, data)

ctx.on('before_parse', (data) => {
const d = data
ctx.on('before_parse', (d) => {
if (d.session.type !== MessageScope.GROUP || !d.session.groupId) return
const list = load(d.session.api.adapter.identity)
if (!(String(d.session.groupId) in list)) return
if (!list[String(d.session.groupId)].includes(String(d.session.userId))) return
d.session.sender.role = 'admin'
if (d.session.type === MessageScope.GROUP) d.session.sender.role = 'admin'
})

ctx
Expand Down
7 changes: 0 additions & 7 deletions packages/core/src/app/message.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,13 +143,6 @@ export class Message {
})
}

/**
* ss
*
* @param callback
* @param priority
* @returns
*/
public midware(callback: MidwareCallback, priority = 100) {
setMidwareMeta(callback, { identity: this.ctx.identity, priority })
const data = { callback, priority }
Expand Down
63 changes: 27 additions & 36 deletions packages/core/src/components/adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,41 +106,6 @@ export interface Adapter<A extends Api = Api, C extends AdapterConfig = AdapterC
send(...data: unknown[]): void
}

function setProxy<T extends Api>(api: T, ctx: Context): T {
// TODO: modify them
api.sendPrivateMsg = new Proxy(api.sendPrivateMsg, {
apply(_, __, argArray) {
const [message, targetId] = argArray
const cancel = cancelFactory()
ctx.emit('before_send', {
api,
message,
messageType: MessageScope.PRIVATE,
targetId,
cancel: cancel.get()
})
if (cancel.value) return
Reflect.apply(message, targetId, argArray[2])
}
})
api.sendGroupMsg = new Proxy(api.sendGroupMsg, {
apply(_, __, argArray) {
const [message, targetId] = argArray
const cancel = cancelFactory()
ctx.emit('before_send', {
api,
message,
messageType: MessageScope.PRIVATE,
targetId,
cancel: cancel.get()
})
if (cancel.value) return
Reflect.apply(message, targetId, argArray[2])
}
})
return api
}

abstract class AdapterOrigin<
A extends Api = Api,
C extends AdapterConfig = AdapterConfig,
Expand Down Expand Up @@ -207,7 +172,33 @@ abstract class AdapterOrigin<
export const Adapter = new Proxy(AdapterOrigin, {
construct: (target, args, newTarget) => {
const bot = Reflect.construct(target, args, newTarget)
bot.api = setProxy(bot.api, bot.ctx)
bot.api = new Proxy(bot.api, {
get: (target, prop, receiver) => {
const value = Reflect.get(target, prop, receiver)
if (typeof prop !== 'string' || !['sendPrivateMsg', 'sendGroupMsg', 'sendChannelMsg'].includes(prop)) {
return value
}
return new Proxy(value as () => void, {
apply(target, thisArg, argArray) {
const [message, id1, id2] = argArray
const cancel = cancelFactory()
bot.ctx.emit('before_send', {
api: bot.api,
message,
cancel: cancel.get(),
target:
prop === 'sendPrivateMsg'
? { type: MessageScope.PRIVATE, userId: id1 }
: prop === 'sendGroupMsg'
? { type: MessageScope.GROUP, groupId: id1 }
: { type: MessageScope.CHANNEL, guildId: id1, channelId: id2 }
})
if (cancel.value) return
Reflect.apply(target, thisArg, argArray)
}
})
}
})
return bot
}
})
Expand Down
84 changes: 48 additions & 36 deletions packages/core/src/components/elements.ts
Original file line number Diff line number Diff line change
@@ -1,49 +1,61 @@
import { none } from '@kotori-bot/tools'
import type { Adapter } from './adapter'
import type { Api } from './api'
import type { AdapterConfig } from '../types'
import type { AdapterConfig, Message, MessageMapping } from '../types'
import { none } from '@kotori-bot/tools'

/**
* Elements handler base class.
*
* @abstract
*/
export abstract class Elements {
/**
* Adapter instance.
*
* @readonly
*/
public readonly adapter: Adapter<Api, AdapterConfig, this>

/**
* Create a elements handler.
*
* @param adapter - Adapter instance
*/
public constructor(adapter: Adapter) {
this.adapter = adapter as Adapter<Api, AdapterConfig, this>
}

private default(...args: unknown[]) {
none(this, args)
return ''
}

public at(target: string, ...extra: unknown[]) {
return this.default(target, extra)
}

public image(url: string, ...extra: unknown[]) {
return this.default(url, extra)
}

public voice(url: string, ...extra: unknown[]) {
return this.default(url, extra)
}

public video(url: string, ...extra: unknown[]) {
return this.default(url, extra)
}

public face(id: number | string, ...extra: unknown[]) {
return this.default(id, extra)
}

public file(data: unknown, ...extra: unknown[]) {
return this.default(data, extra)
}

public getSupports() {
return (['at', 'image', 'voice', 'video', 'face', 'file'] as const).filter(
(key) => this[key] && this[key] !== Object.getPrototypeOf(Object.getPrototypeOf(key))[key]
)
}
/**
* Encode raw message string to `Message`.
*
* @param raw - Raw message
* @param meta - Message metadata
* @returns Encoded message
*/
public encode(raw: string, meta: object = {}): Message {
none(meta)
return raw
}

/**
* Decode `Message` elements to string.
*
* @param message - Message to decode
* @returns Decoded message
*/
// biome-ignore lint:
public decode(message: Message): any {
return message.toString()
}

/**
* Get supported elements.
*
* @returns Supported elements
*
* @abstract
*/
public abstract getSupportsElements(): (keyof MessageMapping)[]
}

export default Elements
Loading

0 comments on commit d2d5071

Please sign in to comment.