Skip to content

Commit

Permalink
功能修复5
Browse files Browse the repository at this point in the history
继续修复,见UPDATE.md
  • Loading branch information
cnxysoft committed May 29, 2024
1 parent 9723c8a commit 27f7ddd
Show file tree
Hide file tree
Showing 7 changed files with 147 additions and 48 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ DDBOT-WSa 是基于 DDBOT-ws 的修改版本,目的是恢复DDBOT的原有功
其它更详细的更动见更新日志。
目前已经兼容:LLOnebot v3.x / NapCat v1.3.x / ws-plugin v0.6.x。

目前已恢复大部分指令(除了:mode、好友申请、群邀请)。

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

DDBOT是一个基于 [MiraiGO](https://github.com/Mrs4s/MiraiGo) 的QQ群推送框架, 内置支持b站直播/动态,斗鱼直播,YTB直播/预约直播,虎牙直播,ACFUN直播,微博动态,
Expand Down
7 changes: 5 additions & 2 deletions UPDATE.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
## DDBOT最近更新日志
- 2024-05-29 v0.0.5e(WSa)
- 2024-05-29 v0.0.6(WSa)
- 修复逻辑漏洞导致的加群崩溃问题
- 修复Quit指令的致命错误(但没做功能)
- 修复Quit指令,现在可以正常退群
- 修复群消息发送结果判定,恢复失败重试功能
- 修复收到的上报自身消息目标错误(私聊)
- 将好友、群、群员信息改为连上ws后加载(避免断线后不刷新)
- 优化部分通信和赋值逻辑,避免信息错漏,日志错漏

- 2024-05-26 v0.0.5b(WSa)
- 兼容 NapCat / ws-plugin
Expand Down
2 changes: 1 addition & 1 deletion bot.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ func Run() {

// 刷新好友列表,群列表
//以后刷新
bot.RefreshList()
// bot.RefreshList()

lsp.Instance.PostStart(bot.Instance)
fmt.Println("运行完了lsp.Instance.PostStart(bot.Instance)")
Expand Down
3 changes: 1 addition & 2 deletions lsp/privateCommand.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (
"strings"
"time"

"github.com/Mrs4s/MiraiGo/client"
"github.com/Mrs4s/MiraiGo/message"
localdb "github.com/Sora233/DDBOT/lsp/buntdb"
"github.com/Sora233/DDBOT/lsp/concern"
Expand Down Expand Up @@ -799,7 +798,7 @@ func (c *LspPrivateCommand) QuitCommand() {
return
}
} else {
gi.Quit(&client.QQClient{Uin: c.bot.GetUin()})
gi.Quit((*(*(*(*(*(c)).Runtime).bot).Bot)).QQClient)
log.Debugf("已退出群【%v】", displayName)
c.textSend(fmt.Sprintf("已退出群【%v】", displayName))
}
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 = "a005e"
BuildTime = "2024-5-29 01:39:00"
CommitId = "a006"
BuildTime = "2024-5-29 21:22:00"
Tags = "DDBOT-WSa"
)

Expand Down
175 changes: 135 additions & 40 deletions miraigo/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,12 +132,13 @@ type QQClient struct {

groupListLock sync.Mutex
//增加的字段
ws *websocket.Conn
responseChans map[string]chan *ResponseGroupData
responseMembers map[string]chan *ResponseGroupMemberData
responseFriends map[string]chan *ResponseFriendList
responseMessage map[string]chan *ResponseSendMessage
currentEcho string
ws *websocket.Conn
responseChans map[string]chan *ResponseGroupData
responseMembers map[string]chan *ResponseGroupMemberData
responseFriends map[string]chan *ResponseFriendList
responseMessage map[string]chan *ResponseSendMessage
responseSetLeave map[string]chan *ResponseSetGroupLeave
currentEcho string
}

// 新增
Expand Down Expand Up @@ -226,6 +227,15 @@ type ResponseSendMessage struct {
Wording string `json:"wording"`
}

// set指令返回
type ResponseSetGroupLeave struct {
Status string `json:"status"`
Retcode int `json:"retcode"`
Message string `json:"message"`
Wording string `json:"wording"`
Echo string `json:"echo"`
}

type QiDianAccountInfo struct {
MasterUin int64
ExtName string
Expand Down Expand Up @@ -322,6 +332,7 @@ type WebSocketMessage struct {
MessageContent interface{} `json:"message"`
MessageSeq DynamicInt64 `json:"message_seq"`
RawMessage string `json:"raw_message"`
TargetID DynamicInt64 `json:"target_id"`
Echo string `json:"echo,omitempty"`
}

Expand Down Expand Up @@ -474,7 +485,7 @@ func (c *QQClient) handleConnection(ws *websocket.Conn) {
}
var friendData ResponseFriendList
if err := json.Unmarshal(basicMsg.Data, &friendData.Data); err != nil {
//log.Println("Failed to unmarshal group member data:", err)
//log.Println("Failed to unmarshal friend data:", err)
logger.Errorf("Failed to unmarshal friend data: %v", err)
continue
}
Expand All @@ -491,6 +502,17 @@ func (c *QQClient) handleConnection(ws *websocket.Conn) {
continue
}
respCh <- &SendResp
case "set_group_leave":
respCh, isResponse := c.responseSetLeave[basicMsg.Echo]
if !isResponse {
continue
}
var SendResp ResponseSetGroupLeave
if err = json.Unmarshal(p, &SendResp); err != nil {
logger.Errorf("Failed to unmarshal set group leave response: %v", err)
continue
}
respCh <- &SendResp
}
//其他类型
// delete(c.responseChans, basicMsg.Echo)
Expand Down Expand Up @@ -526,12 +548,6 @@ 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 @@ -587,8 +603,9 @@ func (c *QQClient) handleConnection(ws *websocket.Conn) {
//fmt.Println("准备c.GroupMessageEvent.dispatch(c, g)")
//fmt.Printf("%+v\n", g)
// 使用 dispatch 方法
c.GroupMessageEvent.dispatch(c, g)
logger.Infof("%+v", g)
// c.GroupMessageEvent.dispatch(c, g)
// logger.Infof("%+v", g)
go c.waitDataAndDispatch(g)
}

if wsmsg.MessageType == "private" {
Expand All @@ -606,6 +623,11 @@ func (c *QQClient) handleConnection(ws *websocket.Conn) {
},
}

// 拿到发送自身发送的消息时修改为正确目标
if wsmsg.PostType == "message_sent" {
pMsg.Target = int64(wsmsg.TargetID)
}

if MessageContent, ok := wsmsg.MessageContent.(string); ok {
// 替换字符串中的"\/"为"/"
MessageContent = strings.Replace(MessageContent, "\\/", "/", -1)
Expand Down Expand Up @@ -674,13 +696,6 @@ func (c *QQClient) handleConnection(ws *websocket.Conn) {
// 刷新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", wsmsg.MetaEventType)
}
// 通知事件
Expand Down Expand Up @@ -709,7 +724,7 @@ func (c *QQClient) handleConnection(ws *websocket.Conn) {
// 选择性执行上述结果
if sync {
if c.GroupList != nil {
go c.SyncGroupMembers(intern.NewStringInterner(), wsmsg.GroupID, flash)
go c.SyncGroupMembers(wsmsg.GroupID, flash)
}
}
logger.Infof("收到通知事件消息:%s", wsmsg.NoticeType)
Expand All @@ -718,37 +733,41 @@ func (c *QQClient) handleConnection(ws *websocket.Conn) {
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", wsmsg.RequestType)
}
}
}

func (c *QQClient) SetFriend(userID DynamicInt64, g *message.GroupMessage) {
friend := c.FindFriend(userID.ToInt64())
if friend == nil {
return
func (c *QQClient) waitDataAndDispatch(g *message.GroupMessage) {
if c.GroupList != nil {
c.SetMsgGroupNames(g)
}
g.Sender.IsFriend = true
if c.FriendList != nil {
c.SetFriend(g)
}
// 使用 dispatch 方法
c.GroupMessageEvent.dispatch(c, g)
logger.Infof("%+v", g)
}

func (c *QQClient) SetMsgGroupNames(groupID DynamicInt64, g *message.GroupMessage) {
group := c.FindGroupByUin(groupID.ToInt64())
func (c *QQClient) SetFriend(g *message.GroupMessage) {
g.Sender.IsFriend = c.FindFriend(g.Sender.Uin) != nil
}

func (c *QQClient) SetMsgGroupNames(g *message.GroupMessage) {
group := c.FindGroupByUin(g.GroupCode)
if group != nil {
g.GroupName = group.Name
} else {
logger.Warnf("Not found group name: %d", groupID.ToInt64())
logger.Warnf("Not found group name: %d", g.GroupCode)
}
}

func (c *QQClient) SyncGroupMembers(intern *intern.StringInterner, groupID DynamicInt64, flash bool) {
func (c *QQClient) SyncGroupMembers(groupID DynamicInt64, flash bool) {
if flash {
//logger.Info("start reload groups list")
err := c.ReloadGroupList()
Expand All @@ -770,7 +789,7 @@ func (c *QQClient) SyncGroupMembers(intern *intern.StringInterner, groupID Dynam
//c.GroupList[i].Members, err = c.getGroupMembers(c.GroupList[i], intern)
if group != nil {
var err error
group.Members, err = c.getGroupMembers(group, intern)
group.Members, err = c.GetGroupMembers(group)
if err != nil {
logger.Errorf("Failed to update group members: %v", err)
}
Expand Down Expand Up @@ -799,7 +818,7 @@ func (c *QQClient) StartWebSocketServer() {
//log.Printf("%s: %s", name, value)
}
}

go c.RefreshList()
c.handleConnection(ws)
})

Expand All @@ -813,6 +832,41 @@ func (c *QQClient) StartWebSocketServer() {
//log.Fatal(http.ListenAndServe("0.0.0.0:15630", nil))
}

// RefreshList 刷新联系人
func (c *QQClient) RefreshList() {
//time.Sleep(time.Second * 3)
logger.Info("start reload friends list")
err := c.ReloadFriendList()
if err != nil {
logger.WithError(err).Error("unable to load friends list")
}
logger.Infof("load %d friends", len(c.FriendList))
logger.Info("start reload groups list")
err = c.ReloadGroupList()
if err != nil {
logger.WithError(err).Error("unable to load groups list")
}
logger.Infof("load %d groups", len(c.GroupList))
logger.Info("start reload group members list")
err = c.ReloadGroupMembers()
if err != nil {
logger.WithError(err).Error("unable to load group members list")
} else {
logger.Info("load members done.")
}
}

func (c *QQClient) ReloadGroupMembers() error {
var err error
for _, group := range c.GroupList {
group.Members, err = c.GetGroupMembers(group)
if err != nil {
return err
}
}
return nil
}

func (c *QQClient) sendToWebSocketClient(ws *websocket.Conn, message []byte) {
if ws != nil {
err := ws.WriteMessage(websocket.TextMessage, message)
Expand Down Expand Up @@ -1578,8 +1632,49 @@ func (c *QQClient) groupMute(groupCode, memberUin int64, time uint32) {
_, _ = c.sendAndWait(c.buildGroupMutePacket(groupCode, memberUin, time))
}

func (c *QQClient) quitGroup(groupCode int64) {
_, _ = c.sendAndWait(c.buildQuitGroupPacket(groupCode))
func (c *QQClient) quitGroup(group *GroupInfo) {
//_, _ = c.sendAndWait(c.buildQuitGroupPacket(groupCode))
//group = c.FindGroup(group.Code)
echo := generateEcho("set_group_leave")
// 构建请求
req := map[string]interface{}{
"action": "set_group_leave",
"params": map[string]interface{}{
"group_id": group.Code,
"is_dismiss": false,
// "group_id": strconv.FormatInt(group.Code, 10),
// "is_dismiss": strconv.FormatBool(false),
},
"echo": echo,
}
// 创建响应通道并添加到映射中
respChan := make(chan *ResponseSetGroupLeave)
// 初始化 c.responseChans 映射
c.responseSetLeave = make(map[string]chan *ResponseSetGroupLeave)
c.responseSetLeave[echo] = respChan
// 发送请求
data, _ := json.Marshal(req)
c.sendToWebSocketClient(c.ws, data)
// 等待响应或超时
select {
case resp := <-respChan:
if resp.Retcode == 0 {
sort.Slice(c.GroupList, func(i, j int) bool {
return c.GroupList[i].Code < c.GroupList[j].Code
})
i := sort.Search(len(c.GroupList), func(i int) bool {
return c.GroupList[i].Code >= group.Code
})
if i < len(c.GroupList) && c.GroupList[i].Code == group.Code {
c.GroupList = append(c.GroupList[:i], c.GroupList[i+1:]...)
}
logger.Infof("退出群组成功")
} else {
logger.Errorf("退出群组失败: %v", resp.Message)
}
case <-time.After(10 * time.Second):
logger.Errorf("退出群组超时")
}
}

func (c *QQClient) KickGroupMembers(groupCode int64, msg string, block bool, memberUins ...int64) {
Expand Down
2 changes: 1 addition & 1 deletion miraigo/client/group_info.go
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ func (g *GroupInfo) MuteAnonymous(id, nick string, seconds int32) error {
func (g *GroupInfo) Quit(client *QQClient) {
g.client = client
if g.SelfPermission() != Owner {
g.client.quitGroup(g.Code)
g.client.quitGroup(g)
}
}

Expand Down

0 comments on commit 27f7ddd

Please sign in to comment.