github.com/fumiama/NanoBot@v0.0.0-20231122134259-c22d8183efca/payload.go (about)

     1  package nano
     2  
     3  import (
     4  	"encoding/json"
     5  	"errors"
     6  	"strconv"
     7  )
     8  
     9  // WebsocketPayload payload 指的是在 websocket 连接上传输的数据,网关的上下行消息采用的都是同一个结构
    10  //
    11  // https://bot.q.qq.com/wiki/develop/api/gateway/reference.html
    12  type WebsocketPayload struct {
    13  	Op OpCode          `json:"op"`
    14  	D  json.RawMessage `json:"d,omitempty"`
    15  	S  uint32          `json:"s,omitempty"`
    16  	T  string          `json:"t,omitempty"`
    17  }
    18  
    19  // Reset 恢复到 0 值
    20  func (wp *WebsocketPayload) Reset() {
    21  	*wp = WebsocketPayload{}
    22  }
    23  
    24  // GetHeartbeatInterval OpCodeHello 获得心跳周期 单位毫秒
    25  func (wp *WebsocketPayload) GetHeartbeatInterval() (uint32, error) {
    26  	if wp.Op != OpCodeHello {
    27  		return 0, errors.New(getThisFuncName() + " unexpected OpCode " + strconv.Itoa(int(wp.Op)) + ", T: " + wp.T + ", D: " + BytesToString(wp.D))
    28  	}
    29  	data := &struct {
    30  		H uint32 `json:"heartbeat_interval"`
    31  	}{}
    32  	err := json.Unmarshal(wp.D, data)
    33  	return data.H, err
    34  }
    35  
    36  // SendPayload 发送 ws 包
    37  func (bot *Bot) SendPayload(wp *WebsocketPayload) error {
    38  	bot.mu.Lock()
    39  	defer bot.mu.Unlock()
    40  	return bot.conn.WriteJSON(wp)
    41  }
    42  
    43  // WrapData 将结构体序列化到 wp.D
    44  func (wp *WebsocketPayload) WrapData(v any) (err error) {
    45  	wp.D, err = json.Marshal(v)
    46  	return
    47  }
    48  
    49  // EventReady https://bot.q.qq.com/wiki/develop/api/gateway/reference.html#_2-%E9%89%B4%E6%9D%83%E8%BF%9E%E6%8E%A5
    50  type EventReady struct {
    51  	Version   int     `json:"version"`
    52  	SessionID string  `json:"session_id"`
    53  	User      *User   `json:"user"`
    54  	Shard     [2]byte `json:"shard"`
    55  }
    56  
    57  // GetEventReady OpCodeDispatch READY
    58  func (wp *WebsocketPayload) GetEventReady() (er EventReady, seq uint32, err error) {
    59  	if wp.Op != OpCodeDispatch {
    60  		err = errors.New(getThisFuncName() + " unexpected OpCode " + strconv.Itoa(int(wp.Op)) + ", T: " + wp.T + ", D: " + BytesToString(wp.D))
    61  		return
    62  	}
    63  	if wp.T != "READY" {
    64  		err = errors.New(getThisFuncName() + " unexpected event type " + wp.T + ", T: " + wp.T + ", D: " + BytesToString(wp.D))
    65  		return
    66  	}
    67  	seq = wp.S
    68  	err = json.Unmarshal(wp.D, &er)
    69  	return
    70  }