Skip to content

Commit

Permalink
功能修复3
Browse files Browse the repository at this point in the history
修复BUG、恢复功能
详情见UPDATE.md
  • Loading branch information
cnxysoft committed May 26, 2024
1 parent 6447ce2 commit 7371da1
Show file tree
Hide file tree
Showing 4 changed files with 225 additions and 43 deletions.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@
[<img src="https://coveralls.io/repos/github/Sora233/DDBOT/badge.svg?branch=master"/>](https://coveralls.io/github/Sora233/DDBOT)
[![GoDoc](http://img.shields.io/badge/go-documentation-blue.svg?style=flat-square)](https://pkg.go.dev/github.com/Sora233/DDBOT)

DDBOT-WSa 是基于 DDBOT-ws 的修改版本,目的是恢复DDBOT的原有功能。
其它更详细的更动见更新日志。
目前已经兼容:LLOnebot v3.x / NapCat v1.3.x / ws-plugin v0.6.x。

以下是原DDBOT-ws的README.md:

DDBOT是一个基于 [MiraiGO](https://github.com/Mrs4s/MiraiGo) 的QQ群推送框架, 内置支持b站直播/动态,斗鱼直播,YTB直播/预约直播,虎牙直播,ACFUN直播,微博动态,
也可以通过插件支持任何订阅源。

Expand Down
8 changes: 8 additions & 0 deletions UPDATE.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
## DDBOT最近更新日志
- 2024-05-26 v0.0.5b(WSa)
- 兼容 NapCat / ws-plugin
- 修复无法获取好友列表的问题
- 修复群/私聊消息的好友判断
- 修复因请求传参类型错误导致NapCat无法获取群员信息的问题
- 修复群员、好友变更事件监听,发生变动后自动更新
- 优化通信过程,避免通信错误导致重连(NapCat)

- 2024-05-23 v0.0.4(WSa)
- 恢复DDBOT原生权限管理
- 修复消息长度超限导致at消息发送失败
Expand Down
4 changes: 2 additions & 2 deletions lsp/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ import (
)

var (
CommitId = "a004"
BuildTime = "2024-5-23 17:33:00"
CommitId = "a005b"
BuildTime = "2024-5-26 13:50:00"
Tags = "DDBOT-WSa"
)

Expand Down
250 changes: 209 additions & 41 deletions miraigo/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ type QQClient struct {
ws *websocket.Conn
responseChans map[string]chan *ResponseGroupData
responseMembers map[string]chan *ResponseGroupMemberData
responseFriends map[string]chan *ResponseFriendList
currentEcho string
}

Expand All @@ -158,6 +159,24 @@ type ResponseGroupData struct {
Echo string `json:"echo"`
}

// 好友信息请求返回
type ResponseFriendList struct {
Status string `json:"status"`
Retcode int `json:"retcode"`
Message string `json:"message"`
Data []FriendData `json:"data"`
Wording string `json:"wording"`
}

// 好友信息
type FriendData struct {
UserID int64 `json:"user_id"`
NickName string `json:"nick_name"`
Remark string `json:"remark"`
Sex string `json:"sex"`
Level int `json:"level"`
}

// 群成员信息
type MemberData struct {
GroupID int64 `json:"group_id"`
Expand Down Expand Up @@ -261,7 +280,17 @@ type MessageContent struct {
}

type WebSocketMessage struct {
PostType string `json:"post_type"`
PostType string `json:"post_type"`
MetaEventType string `json:"meta_event_type"`
NoticeType string `json:"notice_type"`
// Status struct {
// Online bool `json:"online"`
// Good bool `json:"good"`
// } `json:"status"`
RequestType string `json:"request_type"`
Comment string `json:"comment"`
Flag string `json:"flag"`
Interval int `json:"interval"`
MessageType string `json:"message_type"`
Time DynamicInt64 `json:"time"`
SelfID DynamicInt64 `json:"self_id"`
Expand All @@ -275,6 +304,7 @@ type WebSocketMessage struct {
} `json:"sender"`
UserID DynamicInt64 `json:"user_id"`
MessageID DynamicInt64 `json:"message_id"`
RealId DynamicInt64 `json:"real_id"`
GroupID DynamicInt64 `json:"group_id"`
MessageContent interface{} `json:"message"`
MessageSeq DynamicInt64 `json:"message_seq"`
Expand Down Expand Up @@ -395,14 +425,16 @@ func (c *QQClient) handleConnection(ws *websocket.Conn) {
logger.Errorf("Failed to parse basic message: %v", err)
continue
}
respCh, isResponse := c.responseChans[basicMsg.Echo]
respCha, isResponseA := c.responseMembers[basicMsg.Echo]
//根据echo判断
if isResponse || isResponseA {
if basicMsg.Echo != "" {
action, _ := parseEcho(basicMsg.Echo)
logger.Debug(action)
logger.Debugf("Received action: %s", action)
//根据echo判断
switch action {
case "get_group_list":
respCh, isResponse := c.responseChans[basicMsg.Echo]
if !isResponse {
continue
}
var groupData ResponseGroupData
if err := json.Unmarshal(basicMsg.Data, &groupData.Data); err != nil {
//log.Println("Failed to unmarshal group data:", err)
Expand All @@ -411,14 +443,29 @@ func (c *QQClient) handleConnection(ws *websocket.Conn) {
}
respCh <- &groupData
case "get_group_member_list":

respCh, isResponse := c.responseMembers[basicMsg.Echo]
if !isResponse {
continue
}
var memberData ResponseGroupMemberData
if err := json.Unmarshal(basicMsg.Data, &memberData.Data); err != nil {
//log.Println("Failed to unmarshal group member data:", err)
logger.Errorf("Failed to unmarshal group member data: %v", err)
continue
}
respCha <- &memberData
respCh <- &memberData
case "get_friend_list":
respCh, isResponse := c.responseFriends[basicMsg.Echo]
if !isResponse {
continue
}
var friendData ResponseFriendList
if err := json.Unmarshal(basicMsg.Data, &friendData.Data); err != nil {
//log.Println("Failed to unmarshal group member data:", err)
logger.Errorf("Failed to unmarshal friend data: %v", err)
continue
}
respCh <- &friendData
}
//其他类型
delete(c.responseChans, basicMsg.Echo)
Expand All @@ -434,18 +481,17 @@ func (c *QQClient) handleConnection(ws *websocket.Conn) {
}
// 存储 echo
c.currentEcho = wsmsg.Echo
// 变更UIN
c.Uin = int64(wsmsg.SelfID)
// 处理解析后的消息
if wsmsg.MessageType == "group" {
var groupName = ""
if len(c.GroupList) > 0 {
groupName = c.FindGroupByUin(wsmsg.GroupID.ToInt64()).Name
}
// var groupName string
// if len(c.GroupList) > 0 {
// groupName = c.FindGroupByUin(wsmsg.GroupID.ToInt64()).Name
// }
g := &message.GroupMessage{
Id: int32(wsmsg.MessageSeq),
GroupCode: wsmsg.GroupID.ToInt64(),
GroupName: groupName,
GroupName: "",
// GroupName: groupName,
Sender: &message.Sender{
Uin: wsmsg.Sender.UserID.ToInt64(),
Nickname: wsmsg.Sender.Nickname,
Expand All @@ -455,6 +501,12 @@ func (c *QQClient) handleConnection(ws *websocket.Conn) {
Time: int32(wsmsg.Time),
OriginalObject: nil,
}
if c.GroupList != nil {
go c.SetMsgGroupNames(wsmsg.GroupID, g)
}
if c.FriendList != nil {
go c.SetFriend(wsmsg.Sender.UserID, g)
}

if MessageContent, ok := wsmsg.MessageContent.(string); ok {
// 替换字符串中的"\/"为"/"
Expand Down Expand Up @@ -525,7 +577,7 @@ func (c *QQClient) handleConnection(ws *websocket.Conn) {
Uin: wsmsg.Sender.UserID.ToInt64(),
Nickname: wsmsg.Sender.Nickname,
CardName: "", // Private message might not have a Card
IsFriend: true,
IsFriend: wsmsg.SubType == "friend",
},
}

Expand Down Expand Up @@ -590,6 +642,83 @@ func (c *QQClient) handleConnection(ws *websocket.Conn) {

logger.Infof("%+v", pMsg)
}
// 元事件
if wsmsg.PostType == "meta_event" {
// 生命周期
if wsmsg.SubType == "connect" {
// 刷新Bot.Uin
c.Uin = int64(wsmsg.SelfID)
}
// 心跳包
// if wsmsg.MetaEventType == "heartbeat" {
// 发送心跳包
// c.sendToWebSocketClient(ws, c.buildHeartbeatPacket())
// 刷新BOT状态
// c.alive = wsmsg.Status.Online
// }
logger.Infof("收到元事件消息:%s\n", wsmsg.MetaEventType)
}
// 通知事件
if wsmsg.PostType == "notice" {
// 如果是群事件,则更新群信息
if wsmsg.NoticeType == "group_admin" || wsmsg.NoticeType == "group_decrease" || wsmsg.NoticeType == "group_increase" {
if c.GroupList != nil {
go c.SyncGroupMembers(intern.NewStringInterner(), wsmsg.GroupID)
}
}
// 如果是好友事件,则更新好友信息
if wsmsg.NoticeType == "friend_add" {
if c.FriendList != nil {
go c.ReloadFriendList()
}
}
logger.Infof("收到通知事件消息:%s\n", wsmsg.NoticeType)
}
// 请求事件
if wsmsg.PostType == "request" {
// 加好友邀请
if wsmsg.RequestType == "friend" {
// 发送请求获取群列表
//c.sendToWebSocketClient(ws, c.buildGetGroupListPacket())
}
// 加群邀请
if wsmsg.RequestType == "group" {
// 发送请求获取群成员列表
//c.sendToWebSocketClient(ws, c.buildGetGroupMemberListPacket(wsmsg.GroupID))
}
logger.Infof("收到请求事件消息:%s\n", wsmsg.RequestType)
}
}
}

func (c *QQClient) SetFriend(userID DynamicInt64, g *message.GroupMessage) {
friend := c.FindFriend(userID.ToInt64())
if friend == nil {
return
}
g.Sender.IsFriend = true
}

func (c *QQClient) SetMsgGroupNames(groupID DynamicInt64, g *message.GroupMessage) {
g.GroupName = c.FindGroupByUin(groupID.ToInt64()).Name
}

func (c *QQClient) SyncGroupMembers(intern *intern.StringInterner, groupID DynamicInt64) {
group := c.FindGroupByUin(groupID.ToInt64())
// sort.Slice(c.GroupList, func(i2, j int) bool {
// return c.GroupList[i2].Uin < c.GroupList[j].Uin
// })
// i := sort.Search(len(c.GroupList), func(i int) bool {
// return c.GroupList[i].Uin >= int64(groupID)
// })
// if i >= len(c.GroupList) || c.GroupList[i].Uin != int64(groupID) {
// return
// }
var err error
//c.GroupList[i].Members, err = c.getGroupMembers(c.GroupList[i], intern)
group.Members, err = c.getGroupMembers(group, intern)
if err != nil {
logger.Errorf("Failed to update group members: %v", err)
}
}

Expand Down Expand Up @@ -941,35 +1070,74 @@ func (c *QQClient) ReloadFriendList() error {
return nil
}

// GetFriendList
// 当使用普通QQ时: 请求好友列表
// 当使用企点QQ时: 请求外部联系人列表
func (c *QQClient) GetFriendList() (*FriendListResponse, error) {
if c.version().Protocol == auth.QiDian {
rsp, err := c.getQiDianAddressDetailList()
if err != nil {
return nil, err
}
return &FriendListResponse{TotalCount: int32(len(rsp)), List: rsp}, nil

echo := generateEcho("get_friend_list")
// 构建请求
req := map[string]interface{}{
"action": "get_friend_list",
"params": map[string]int64{},
"echo": echo,
}
curFriendCount := 0
r := &FriendListResponse{}
for {
rsp, err := c.sendAndWait(c.buildFriendGroupListRequestPacket(int16(curFriendCount), 150, 0, 0))
if err != nil {
return nil, err
}
list := rsp.(*FriendListResponse)
r.TotalCount = list.TotalCount
r.List = append(r.List, list.List...)
curFriendCount += len(list.List)
if int32(len(r.List)) >= r.TotalCount {
break
// 创建响应通道并添加到映射中
respChan := make(chan *ResponseFriendList)
// 初始化 c.responseChans 映射
c.responseFriends = make(map[string]chan *ResponseFriendList)
c.responseFriends[echo] = respChan

// 发送请求
data, _ := json.Marshal(req)
c.sendToWebSocketClient(c.ws, data)

// 等待响应或超时
select {
case resp := <-respChan:
friends := make([]*FriendInfo, len(resp.Data))
c.debug("GetFriendList: %v", resp.Data)
for i, friend := range resp.Data {
friends[i] = &FriendInfo{
Uin: friend.UserID,
Nickname: friend.NickName,
Remark: friend.Remark,
FaceId: 0,
}
}
return &FriendListResponse{TotalCount: int32(len(friends)), List: friends}, nil

case <-time.After(10 * time.Second):
return nil, errors.New("GetFriendList: timeout waiting for response.")
}
return r, nil
}

// GetFriendList
// 当使用普通QQ时: 请求好友列表
// 当使用企点QQ时: 请求外部联系人列表
// func (c *QQClient) GetFriendList() (*FriendListResponse, error) {
// if c.version().Protocol == auth.QiDian {
// rsp, err := c.getQiDianAddressDetailList()
// if err != nil {
// return nil, err
// }
// return &FriendListResponse{TotalCount: int32(len(rsp)), List: rsp}, nil
// }
// curFriendCount := 0
// r := &FriendListResponse{}
// for {
// rsp, err := c.sendAndWait(c.buildFriendGroupListRequestPacket(int16(curFriendCount), 150, 0, 0))
// if err != nil {
// return nil, err
// }
// list := rsp.(*FriendListResponse)
// r.TotalCount = list.TotalCount
// r.List = append(r.List, list.List...)
// curFriendCount += len(list.List)
// if int32(len(r.List)) >= r.TotalCount {
// break
// }
// }
// return r, nil
// }

func (c *QQClient) SendGroupPoke(groupCode, target int64) {
_, _ = c.sendAndWait(c.buildGroupPokePacket(groupCode, target))
}
Expand Down Expand Up @@ -1136,8 +1304,8 @@ func (c *QQClient) getGroupMembers(group *GroupInfo, interner *intern.StringInte
// 构建请求
req := map[string]interface{}{
"action": "get_group_member_list",
"params": map[string]string{
"group_id": strconv.FormatInt(group.Uin, 10),
"params": map[string]int64{
"group_id": group.Uin,
},
"echo": echo,
}
Expand Down

0 comments on commit 7371da1

Please sign in to comment.