mirror of
https://github.com/fumiama/NanoBot.git
synced 2026-06-05 02:30:23 +08:00
finish handler
This commit is contained in:
29
bot.go
29
bot.go
@@ -30,16 +30,16 @@ type Bot struct {
|
||||
Intents uint32 // Intents 欲接收的事件
|
||||
Properties json.RawMessage // Properties 一些环境变量, 目前没用
|
||||
|
||||
gateway string // gateway 获得的网关
|
||||
shard [2]byte // shard 分片
|
||||
seq uint32 // seq 最新的 s
|
||||
handlers map[string]GeneralHandleType // handlers 方便调用的 handler
|
||||
mu sync.Mutex // 写锁
|
||||
conn *websocket.Conn // conn 目前的 wss 连接
|
||||
heartbeat uint32 // heartbeat 心跳周期, 单位毫秒
|
||||
hbonce sync.Once // hbonce 保证仅执行一次 heartbeat
|
||||
gateway string // gateway 获得的网关
|
||||
shard [2]byte // shard 分片
|
||||
seq uint32 // seq 最新的 s
|
||||
handlers map[string]eventHandlerType // handlers 方便调用的 handler
|
||||
mu sync.Mutex // 写锁
|
||||
conn *websocket.Conn // conn 目前的 wss 连接
|
||||
heartbeat uint32 // heartbeat 心跳周期, 单位毫秒
|
||||
hbonce sync.Once // hbonce 保证仅执行一次 heartbeat
|
||||
|
||||
ready EventReady //
|
||||
ready EventReady // ready 连接成功后下发的 bot 基本信息
|
||||
}
|
||||
|
||||
// Init 初始化, 只需执行一次
|
||||
@@ -49,7 +49,7 @@ func (b *Bot) Init(gateway string, shard [2]byte) *Bot {
|
||||
if b.Handler != nil {
|
||||
h := reflect.ValueOf(b.Handler).Elem()
|
||||
t := h.Type()
|
||||
b.handlers = make(map[string]GeneralHandleType, h.NumField()*4)
|
||||
b.handlers = make(map[string]eventHandlerType, h.NumField()*4)
|
||||
for i := 0; i < h.NumField(); i++ {
|
||||
f := h.Field(i)
|
||||
if f.IsZero() {
|
||||
@@ -58,7 +58,10 @@ func (b *Bot) Init(gateway string, shard [2]byte) *Bot {
|
||||
tp := t.Field(i).Name[2:] // skip On
|
||||
log.Infoln(getLogHeader(), "注册处理函数", tp)
|
||||
handler := f.Interface()
|
||||
b.handlers[tp] = *(*GeneralHandleType)(unsafe.Add(unsafe.Pointer(&handler), unsafe.Sizeof(uintptr(0))))
|
||||
b.handlers[tp] = eventHandlerType{
|
||||
h: *(*generalHandleType)(unsafe.Add(unsafe.Pointer(&handler), unsafe.Sizeof(uintptr(0)))),
|
||||
t: t.Field(i).Type.In(2).Elem(),
|
||||
}
|
||||
}
|
||||
}
|
||||
return b
|
||||
@@ -257,6 +260,8 @@ func (bot *Bot) Listen() {
|
||||
switch payload.T {
|
||||
case "RESUMED":
|
||||
log.Infoln(getLogHeader(), bot.ready.User.Username, "的网关连接恢复完成")
|
||||
default:
|
||||
bot.processEvent(&payload)
|
||||
}
|
||||
case OpCodeHeartbeat: // Send/Receive
|
||||
log.Debugln(getLogHeader(), "收到服务端推送心跳, 间隔:", time.Since(lastheartbeat))
|
||||
@@ -280,6 +285,8 @@ func (bot *Bot) Listen() {
|
||||
log.Debugln(getLogHeader(), "收到心跳返回, 间隔:", time.Since(lastheartbeat))
|
||||
lastheartbeat = time.Now()
|
||||
case OpCodeHTTPCallbackACK: // Reply
|
||||
default:
|
||||
log.Warnln(getLogHeader(), "忽略未知事件, 序号:", payload.S, ", Op:", payload.Op, ", 类型:", payload.T, ", 数据:", BytesToString(payload.D))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
28
event.go
Normal file
28
event.go
Normal file
@@ -0,0 +1,28 @@
|
||||
package nano
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"reflect"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// processEvent 处理需要关注的业务事件
|
||||
func (bot *Bot) processEvent(payload *WebsocketPayload) {
|
||||
tp := UnderlineToCamel(payload.T)
|
||||
if bot.Handler != nil {
|
||||
ev, ok := bot.handlers[tp]
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
log.Debugln(getLogHeader(), "使用 handlers 处理", tp, "事件")
|
||||
x := reflect.New(ev.t)
|
||||
err := json.Unmarshal(payload.D, x.Interface())
|
||||
if err != nil {
|
||||
log.Warnln(getLogHeader(), "解析", tp, "事件时出现错误:", err)
|
||||
return
|
||||
}
|
||||
go ev.h(payload.S, bot, x.UnsafePointer())
|
||||
return
|
||||
}
|
||||
}
|
||||
95
handler.go
95
handler.go
@@ -1,9 +1,18 @@
|
||||
package nano
|
||||
|
||||
import "unsafe"
|
||||
import (
|
||||
"reflect"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// GeneralHandleType 作为通用的 handler 函数调用约定使用
|
||||
type GeneralHandleType func(int, *Bot, unsafe.Pointer)
|
||||
// generalHandleType 作为通用的 handler 函数调用约定使用
|
||||
type generalHandleType func(uint32, *Bot, unsafe.Pointer)
|
||||
|
||||
// eventHandlerType 一个事件函数调用的必须信息
|
||||
type eventHandlerType struct {
|
||||
h generalHandleType
|
||||
t reflect.Type
|
||||
}
|
||||
|
||||
// Handler 事件订阅
|
||||
//
|
||||
@@ -11,66 +20,66 @@ type GeneralHandleType func(int, *Bot, unsafe.Pointer)
|
||||
type Handler struct {
|
||||
// GUILDS (1 << 0)
|
||||
|
||||
OnGuildCreate func(s int, bot *Bot, d *Guild)
|
||||
OnGuildUpdate func(s int, bot *Bot, d *Guild)
|
||||
OnGuildDelete func(s int, bot *Bot, d *Guild)
|
||||
OnChannelCreate func(s int, bot *Bot, d *Channel)
|
||||
OnChannelUpdate func(s int, bot *Bot, d *Channel)
|
||||
OnChannelDelete func(s int, bot *Bot, d *Channel)
|
||||
OnGuildCreate func(s uint32, bot *Bot, d *Guild)
|
||||
OnGuildUpdate func(s uint32, bot *Bot, d *Guild)
|
||||
OnGuildDelete func(s uint32, bot *Bot, d *Guild)
|
||||
OnChannelCreate func(s uint32, bot *Bot, d *Channel)
|
||||
OnChannelUpdate func(s uint32, bot *Bot, d *Channel)
|
||||
OnChannelDelete func(s uint32, bot *Bot, d *Channel)
|
||||
// GUILD_MEMBERS (1 << 1)
|
||||
|
||||
OnGuildMemberAdd func(s int, bot *Bot, d *Member)
|
||||
OnGuildMemberUpdate func(s int, bot *Bot, d *Member)
|
||||
OnGuildMemberRemove func(s int, bot *Bot, d *Member)
|
||||
OnGuildMemberAdd func(s uint32, bot *Bot, d *Member)
|
||||
OnGuildMemberUpdate func(s uint32, bot *Bot, d *Member)
|
||||
OnGuildMemberRemove func(s uint32, bot *Bot, d *Member)
|
||||
// GUILD_MESSAGES (1 << 9) // 消息事件,仅 *私域* 机器人能够设置此 intents。
|
||||
|
||||
OnMessageCreate func(s int, bot *Bot, d *Message)
|
||||
OnMessageDelete func(s int, bot *Bot, d *Message)
|
||||
OnMessageCreate func(s uint32, bot *Bot, d *Message)
|
||||
OnMessageDelete func(s uint32, bot *Bot, d *MessageDelete)
|
||||
// GUILD_MESSAGE_REACTIONS (1 << 10)
|
||||
|
||||
OnMessageReactionAdd func(s int, bot *Bot, d *MessageReaction)
|
||||
OnMessageReactionRemove func(s int, bot *Bot, d *MessageReaction)
|
||||
OnMessageReactionAdd func(s uint32, bot *Bot, d *MessageReaction)
|
||||
OnMessageReactionRemove func(s uint32, bot *Bot, d *MessageReaction)
|
||||
// DIRECT_MESSAGE (1 << 12)
|
||||
|
||||
OnDirectMessageCreate func(s int, bot *Bot, d *Message)
|
||||
OnDirectMessageDelete func(s int, bot *Bot, d *Message)
|
||||
OnDirectMessageCreate func(s uint32, bot *Bot, d *Message)
|
||||
OnDirectMessageDelete func(s uint32, bot *Bot, d *MessageDelete)
|
||||
// OPEN_FORUMS_EVENT (1 << 18) // 论坛事件, 此为公域的论坛事件
|
||||
|
||||
OnOpenForumThreadCreate func(s int, bot *Bot, d *Thread)
|
||||
OnOpenForumThreadUpdate func(s int, bot *Bot, d *Thread)
|
||||
OnOpenForumThreadDelete func(s int, bot *Bot, d *Thread)
|
||||
OnOpenForumPostCreate func(s int, bot *Bot, d *Post)
|
||||
OnOpenForumPostDelete func(s int, bot *Bot, d *Post)
|
||||
OnOpenForumReplyCreate func(s int, bot *Bot, d *Reply)
|
||||
OnOpenForumReplyDelete func(s int, bot *Bot, d *Reply)
|
||||
OnOpenForumThreadCreate func(s uint32, bot *Bot, d *Thread)
|
||||
OnOpenForumThreadUpdate func(s uint32, bot *Bot, d *Thread)
|
||||
OnOpenForumThreadDelete func(s uint32, bot *Bot, d *Thread)
|
||||
OnOpenForumPostCreate func(s uint32, bot *Bot, d *Post)
|
||||
OnOpenForumPostDelete func(s uint32, bot *Bot, d *Post)
|
||||
OnOpenForumReplyCreate func(s uint32, bot *Bot, d *Reply)
|
||||
OnOpenForumReplyDelete func(s uint32, bot *Bot, d *Reply)
|
||||
// AUDIO_OR_LIVE_CHANNEL_MEMBER (1 << 19) // 音视频/直播子频道成员进出事件
|
||||
|
||||
OnAudioOrLiveChannelMemberEnter func(s int, bot *Bot, d *AudioLiveChannelUsersChange)
|
||||
OnAudioOrLiveChannelMemberExit func(s int, bot *Bot, d *AudioLiveChannelUsersChange)
|
||||
OnAudioOrLiveChannelMemberEnter func(s uint32, bot *Bot, d *AudioLiveChannelUsersChange)
|
||||
OnAudioOrLiveChannelMemberExit func(s uint32, bot *Bot, d *AudioLiveChannelUsersChange)
|
||||
// INTERACTION (1 << 26) 事件结构不明
|
||||
|
||||
// MESSAGE_AUDIT (1 << 27)
|
||||
|
||||
OnMessageAuditPass func(s int, bot *Bot, d *MessageAudited)
|
||||
OnMessageAuditReject func(s int, bot *Bot, d *MessageAudited)
|
||||
OnMessageAuditPass func(s uint32, bot *Bot, d *MessageAudited)
|
||||
OnMessageAuditReject func(s uint32, bot *Bot, d *MessageAudited)
|
||||
// FORUMS_EVENT (1 << 28) // 论坛事件,仅 *私域* 机器人能够设置此 intents。
|
||||
|
||||
OnForumThreadCreate func(s int, bot *Bot, d *Thread)
|
||||
OnForumThreadUpdate func(s int, bot *Bot, d *Thread)
|
||||
OnForumThreadDelete func(s int, bot *Bot, d *Thread)
|
||||
OnForumPostCreate func(s int, bot *Bot, d *Post)
|
||||
OnForumPostDelete func(s int, bot *Bot, d *Post)
|
||||
OnForumReplyCreate func(s int, bot *Bot, d *Reply)
|
||||
OnForumReplyDelete func(s int, bot *Bot, d *Reply)
|
||||
OnForumPublishAuditResult func(s int, bot *Bot, d *AuditResult)
|
||||
OnForumThreadCreate func(s uint32, bot *Bot, d *Thread)
|
||||
OnForumThreadUpdate func(s uint32, bot *Bot, d *Thread)
|
||||
OnForumThreadDelete func(s uint32, bot *Bot, d *Thread)
|
||||
OnForumPostCreate func(s uint32, bot *Bot, d *Post)
|
||||
OnForumPostDelete func(s uint32, bot *Bot, d *Post)
|
||||
OnForumReplyCreate func(s uint32, bot *Bot, d *Reply)
|
||||
OnForumReplyDelete func(s uint32, bot *Bot, d *Reply)
|
||||
OnForumPublishAuditResult func(s uint32, bot *Bot, d *AuditResult)
|
||||
// AUDIO_ACTION (1 << 29)
|
||||
|
||||
OnAudioStart func(s int, bot *Bot, d *AudioAction)
|
||||
OnAudioFinish func(s int, bot *Bot, d *AudioAction)
|
||||
OnAudioOnMic func(s int, bot *Bot, d *AudioAction)
|
||||
OnAudioOffMic func(s int, bot *Bot, d *AudioAction)
|
||||
OnAudioStart func(s uint32, bot *Bot, d *AudioAction)
|
||||
OnAudioFinish func(s uint32, bot *Bot, d *AudioAction)
|
||||
OnAudioOnMic func(s uint32, bot *Bot, d *AudioAction)
|
||||
OnAudioOffMic func(s uint32, bot *Bot, d *AudioAction)
|
||||
// PUBLIC_GUILD_MESSAGES (1 << 30) // 消息事件,此为公域的消息事件
|
||||
|
||||
OnAtMessageCreate func(s int, bot *Bot, d *Message)
|
||||
OnPublicMessageDelete func(s int, bot *Bot, d *Message)
|
||||
OnAtMessageCreate func(s uint32, bot *Bot, d *Message)
|
||||
OnPublicMessageDelete func(s uint32, bot *Bot, d *MessageDelete)
|
||||
}
|
||||
|
||||
@@ -10,6 +10,10 @@ type Emoji struct {
|
||||
Type uint32 `json:"type"`
|
||||
}
|
||||
|
||||
func (e *Emoji) String() string {
|
||||
return "<emoji:" + e.ID + ">"
|
||||
}
|
||||
|
||||
// MessageReaction https://bot.q.qq.com/wiki/develop/api/openapi/reaction/model.html#messagereaction
|
||||
type MessageReaction struct {
|
||||
UserID string `json:"user_id"`
|
||||
@@ -20,12 +24,12 @@ type MessageReaction struct {
|
||||
}
|
||||
|
||||
// ReactionTargetType https://bot.q.qq.com/wiki/develop/api/openapi/reaction/model.html#reactiontargettype
|
||||
type ReactionTargetType int
|
||||
type ReactionTargetType string
|
||||
|
||||
// ReactionTarget https://bot.q.qq.com/wiki/develop/api/openapi/reaction/model.html#reactiontarget
|
||||
type ReactionTarget struct {
|
||||
ID string `json:"id"`
|
||||
Type ReactionTargetType `json:"type"`
|
||||
Type ReactionTargetType `json:"type"` // 实际是 string 而非 int
|
||||
}
|
||||
|
||||
// GiveMessageReaction 对消息 message_id 进行表情表态
|
||||
|
||||
@@ -56,7 +56,13 @@ type MessageEmbedField struct {
|
||||
|
||||
// MessageAttachment https://bot.q.qq.com/wiki/develop/api/openapi/message/model.html#messageattachment
|
||||
type MessageAttachment struct {
|
||||
URL string `json:"url"`
|
||||
ContentType string `json:"content_type,omitempty"`
|
||||
Filename string `json:"filename,omitempty"`
|
||||
Height int `json:"height,omitempty"`
|
||||
ID string `json:"id,omitempty"`
|
||||
Size int `json:"size,omitempty"`
|
||||
URL string `json:"url,omitempty"`
|
||||
Width int `json:"width,omitempty"`
|
||||
}
|
||||
|
||||
// MessageArk https://bot.q.qq.com/wiki/develop/api/openapi/message/model.html#messageark
|
||||
|
||||
Reference in New Issue
Block a user