Coder Social home page Coder Social logo

miraigo's Introduction

MiraiGo

qq-android 协议的golang实现 移植于 mirai

使用前声明

本项目为协议实现,不推荐直接使用。

CQHTTP 用户建议使用基于 go-cqhttp 的框架开发。

同时也提供原生框架 MiraiGo-Template 进行开发。

使用方法

go get -u github.com/Mrs4s/MiraiGo

支持的功能

协议支持

已完成功能/开发计划列表

登录

  • 账号密码登录
  • 二维码登录
  • 验证码提交
  • 设备锁验证
  • 错误信息解析

消息类型

  • 文本
  • 图片
  • 语音
  • 表情
  • At
  • 回复
  • 长消息(仅群聊/私聊)
  • 链接分享
  • 小程序(暂只支持RAW)
  • 短视频
  • 合并转发
  • 群文件(上传与接收信息)

事件

  • 好友消息
  • 群消息
  • 临时会话消息
  • 登录号加群
  • 登录号退群(包含T出)
  • 新成员进群/退群
  • 群/好友消息撤回
  • 群禁言
  • 群成员权限变更
  • 收到邀请进群通知
  • 收到其他用户进群请求
  • 新好友
  • 新好友请求
  • 客户端离线
  • 群提示 (戳一戳/运气王等)

主动操作

为防止滥用,不支持主动邀请新成员进群

  • 发送群消息
  • 发送好友消息
  • 发送临时会话消息
  • 获取/刷新群列表
  • 获取/刷新群成员列表
  • 获取/刷新好友列表
  • 获取群荣誉 (龙王/群聊火焰等)
  • 处理加群请求
  • 处理被邀请加群请求
  • 处理好友请求
  • 撤回群消息
  • 群公告设置
  • 获取群文件下载链接
  • 群设置 (全体禁言/群名)
  • 修改群成员Card
  • 修改群成员头衔
  • 群成员邀请
  • 群成员禁言/解除禁言
  • T出群成员
  • 戳一戳群友
  • 获取陌生人信息

不支持的协议

基于 QQ钱包支付用户服务协议 不支持一切有关QQ钱包的协议

4.13 您不得利用本服务实施下列任一的行为:
(9) 侵害QQ钱包支付服务系統;

  • QQ钱包协议(收款/付款等)

miraigo's People

Contributors

01101sam avatar 1umine avatar 6dduu6 avatar arily avatar buhuang28 avatar fumiama avatar fzls avatar github-actions[bot] avatar icarus-ai avatar ink-33 avatar kengxxiao avatar littlecxm avatar lunzhipenxil avatar lxy1226 avatar lz1998 avatar mikewang000000 avatar mingxuangame avatar moyrne avatar mrs4s avatar qianjunakasumi avatar sora233 avatar synodriver avatar takayama-lily avatar tengattack avatar tom-snow avatar wdvxdr1123 avatar weilinfox avatar wfjsw avatar yyuueexxiinngg avatar zhaodice avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

miraigo's Issues

Can I Send a File?

Hello,I would link to create a software auto publisher,but I cannot find the API to send a file.
Thank you for help.

cli.Login()之后,处理验证码之前,cli.Online错误

预期:在Login之后不直接改变Online,在验证码处理完成之后改为true

// Login send login request
func (c *QQClient) Login() (*LoginResponse, error) {
	if c.Online {
		return nil, ErrAlreadyOnline
	}
	err := c.connect()
	if err != nil {
		return nil, err
	}
	c.Online = true // 把这个移动到下面3个位置

	go c.netLoop()
	seq, packet := c.buildLoginPacket()
	rsp, err := c.sendAndWait(seq, packet)
	if err != nil {
		return nil, err
	}
	l := rsp.(LoginResponse)
	if l.Success {
		c.lastLostMsg = ""
		c.registerClient()
		if !c.heartbeatEnabled {
			c.startHeartbeat()
		}
	        c.Online = true // 位置1
	}
	return &l, nil
}

// SubmitCaptcha send captcha to server
func (c *QQClient) SubmitCaptcha(result string, sign []byte) (*LoginResponse, error) {
	seq, packet := c.buildCaptchaPacket(result, sign)
	rsp, err := c.sendAndWait(seq, packet)
	if err != nil {
		return nil, err
	}
	l := rsp.(LoginResponse)
	if l.Success {
		c.registerClient()
		if !c.heartbeatEnabled {
			c.startHeartbeat()
		}
	        c.Online = true // 位置2
	}
	return &l, nil
}

func (c *QQClient) SubmitSMS(code string) (*LoginResponse, error) {
	rsp, err := c.sendAndWait(c.buildSMSCodeSubmitPacket(code))
	if err != nil {
		return nil, err
	}
	l := rsp.(LoginResponse)
	if l.Success {
		c.registerClient()
		if !c.heartbeatEnabled {
			c.startHeartbeat()
		}
	        c.Online = true // 位置3
	}
	return &l, nil
}

如下

图片
图片
读入图片是成功的,可以转为base64编码并且解码为图片成功。
麻烦看看好吗?

tts的解密方法是否有其他语言的?

大佬,感谢你的奉献,我最近抓包发现QQ语音的朗读挺有意思的感觉还带感情?但似乎是加密的。看了你的代码有解密的方法,但我不会go语言,能说下这是什么操作吗?我对qq协议也有兴趣

建议针对海外优化一下连接

目前看来,海外服务器连tx只有msfwifi.3g.qq.com这个地址是最稳定的。
其它固定ip都有一定程度的延迟和丢包。
(比如可以在启动的时候选定一个延迟最低的地址。或者让高级用户可以自己指定地址。)

修改IMEI随机算法

根据此处代码,目前本项目IMEI是直接选取的15位随机数

MiraiGo/client/global.go

Lines 107 to 121 in 98a77a6

func GenRandomDevice() {
r := make([]byte, 16)
rand.Read(r)
SystemDeviceInfo.Display = []byte("MIRAI." + utils.RandomStringRange(6, NumberRange) + ".001")
SystemDeviceInfo.FingerPrint = []byte("mamoe/mirai/mirai:10/MIRAI.200122.001/" + utils.RandomStringRange(7, NumberRange) + ":user/release-keys")
SystemDeviceInfo.BootId = []byte(binary.GenUUID(r))
SystemDeviceInfo.ProcVersion = []byte("Linux version 3.0.31-" + utils.RandomString(8) + " ([email protected])")
rand.Read(r)
t := md5.Sum(r)
SystemDeviceInfo.IMSIMd5 = t[:]
SystemDeviceInfo.IMEI = utils.RandomStringRange(15, NumberRange)
SystemDeviceInfo.AndroidId = SystemDeviceInfo.Display
SystemDeviceInfo.GenNewGuid()
SystemDeviceInfo.GenNewTgtgtKey()
}

但是事实上IMEI并不是完全随机的,具有地区号段以及校验位,技术细节可以参考维基百科,具体代码实现可以参考这篇CSDN博客

虽然目前看起来貌似并不影响使用的样子

net issues

以下问题均在调试滑块扫描二维码登录时检出

问题一

MiraiGo/client/client.go

Lines 1026 to 1040 in 8f474db

for {
l, err := c.TCP.ReadInt32()
if err != nil {
time.Sleep(time.Millisecond * 500)
continue
}
data, _ := c.TCP.ReadBytes(int(l) - 4)
pkt, err := packets.ParseIncomingPacket(data, c.sigInfo.d2Key)
if err != nil {
c.Error("parse incoming packet error: %v", err)
if errors.Is(err, packets.ErrSessionExpired) || errors.Is(err, packets.ErrPacketDropped) {
c.Disconnect()
go c.dispatchDisconnectEvent(&ClientDisconnectedEvent{Message: "session expired"})
continue
}

MiraiGo/client/client.go

Lines 932 to 947 in 8f474db

for {
select {
case rsp := <-ch:
return rsp.Response, rsp.Error
case <-time.After(time.Second * 15):
retry++
if retry < 2 {
_ = c.send(pkt)
continue
}
c.handlers.Delete(seq)
// c.Error("packet timed out, seq: %v", seq)
// println("Packet Timed out")
return nil, errors.New("Packet timed out")
}
}

如图所示,当调用sendAndWait时如果出现session expired就会因收不到包而超时退出
image

问题二

MiraiGo/client/client.go

Lines 979 to 993 in b66d8a9

func (c *QQClient) quickReconnect() {
c.Disconnect()
time.Sleep(time.Millisecond * 200)
if err := c.connect(); err != nil {
c.Error("connect server error: %v", err)
c.dispatchDisconnectEvent(&ClientDisconnectedEvent{Message: "quick reconnect failed"})
return
}
if err := c.registerClient(); err != nil {
c.Error("register client failed: %v", err)
c.Disconnect()
c.dispatchDisconnectEvent(&ClientDisconnectedEvent{Message: "register error"})
return
}
}

if errors.Is(err, packets.ErrSessionExpired) || errors.Is(err, packets.ErrPacketDropped) { 
 	c.Disconnect() 
 	go c.dispatchDisconnectEvent(&ClientDisconnectedEvent{Message: "session expired"}) 
	c.Connect()
 	continue 
 } 

则能暴力解决问题一。但需要等待接近15秒才能获取到二维码。且quickReconnect返回register error时会打断netLoop,导致正常的wtlogin.trans_emp被打断,程序也不退出。
image

复现方法:滑块选择使用二维码。即使第一次成功,重启程序后必定失败

Segmentation violation

bot正常运行几个小时后就出现下面的panic:

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x5bc3e5]

goroutine 16 [running]:
net.(*TCPConn).Write(0x0, 0xc0020c5680, 0x204, 0x280, 0x280, 0xb9b901, 0xc00203d1b0)
        <autogenerated>:1 +0x5
github.com/Mrs4s/MiraiGo/client.(*QQClient).send(...)
        /home/orzogc/go/pkg/mod/github.com/!mrs4s/[email protected]/client/client.go:939
github.com/Mrs4s/MiraiGo/client.(*QQClient).registerClient(0xc000110dc0)
        /home/orzogc/go/pkg/mod/github.com/!mrs4s/[email protected]/client/client.go:911 +0x67
github.com/Mrs4s/MiraiGo/client.(*QQClient).netLoop(0xc000110dc0)
        /home/orzogc/go/pkg/mod/github.com/!mrs4s/[email protected]/client/client.go:993 +0x4f1
created by github.com/Mrs4s/MiraiGo/client.(*QQClient).Login
        /home/orzogc/go/pkg/mod/github.com/!mrs4s/[email protected]/client/client.go:186 +0x92

存在一些data race

利用 Data Race Detector 发现MiraiGo存在data race:

2020/10/11 16:56:51 Mirai DEBUG: rev pkt: OnlinePush.SidTicketExpired seq: 14418
2020/10/11 16:56:55 Mirai DEBUG: rev pkt: OnlinePush.ReqPush seq: 63665
2020/10/11 16:57:04 Mirai DEBUG: rev pkt: OnlinePush.ReqPush seq: 63665
==================
WARNING: DATA RACE
Read at 0x00c0001d8ba8 by goroutine 126:
  github.com/Mrs4s/MiraiGo/client.decodeOnlinePushReqPacket.func1()
      /home/orzogc/go/pkg/mod/github.com/!mrs4s/[email protected]/client/decoders.go:700 +0x53
  github.com/Mrs4s/MiraiGo/client.decodeOnlinePushReqPacket()
      /home/orzogc/go/pkg/mod/github.com/!mrs4s/[email protected]/client/decoders.go:708 +0x794
  github.com/Mrs4s/MiraiGo/client.(*QQClient).netLoop.func1()
      /home/orzogc/go/pkg/mod/github.com/!mrs4s/[email protected]/client/client.go:1136 +0x1b7

Previous write at 0x00c0001d8ba8 by goroutine 158:
  github.com/Mrs4s/MiraiGo/client.decodeOnlinePushReqPacket()
      /home/orzogc/go/pkg/mod/github.com/!mrs4s/[email protected]/client/decoders.go:711 +0x88e
  github.com/Mrs4s/MiraiGo/client.(*QQClient).netLoop.func1()
      /home/orzogc/go/pkg/mod/github.com/!mrs4s/[email protected]/client/client.go:1136 +0x1b7

Goroutine 126 (running) created at:
  github.com/Mrs4s/MiraiGo/client.(*QQClient).netLoop()
      /home/orzogc/go/pkg/mod/github.com/!mrs4s/[email protected]/client/client.go:1121 +0x59c

Goroutine 158 (finished) created at:
  github.com/Mrs4s/MiraiGo/client.(*QQClient).netLoop()
      /home/orzogc/go/pkg/mod/github.com/!mrs4s/[email protected]/client/client.go:1121 +0x59c
==================
==================
WARNING: DATA RACE
Read at 0x00c0005f6e68 by goroutine 126:
  github.com/Mrs4s/MiraiGo/client.decodeOnlinePushReqPacket.func1()
      /home/orzogc/go/pkg/mod/github.com/!mrs4s/[email protected]/client/decoders.go:700 +0x96
  github.com/Mrs4s/MiraiGo/client.decodeOnlinePushReqPacket()
      /home/orzogc/go/pkg/mod/github.com/!mrs4s/[email protected]/client/decoders.go:708 +0x794
  github.com/Mrs4s/MiraiGo/client.(*QQClient).netLoop.func1()
      /home/orzogc/go/pkg/mod/github.com/!mrs4s/[email protected]/client/client.go:1136 +0x1b7

Previous write at 0x00c0005f6e68 by goroutine 158:
  github.com/Mrs4s/MiraiGo/client.decodeOnlinePushReqPacket()
      /home/orzogc/go/pkg/mod/github.com/!mrs4s/[email protected]/client/decoders.go:711 +0x864
  github.com/Mrs4s/MiraiGo/client.(*QQClient).netLoop.func1()
      /home/orzogc/go/pkg/mod/github.com/!mrs4s/[email protected]/client/client.go:1136 +0x1b7

Goroutine 126 (running) created at:
  github.com/Mrs4s/MiraiGo/client.(*QQClient).netLoop()
      /home/orzogc/go/pkg/mod/github.com/!mrs4s/[email protected]/client/client.go:1121 +0x59c

Goroutine 158 (finished) created at:
  github.com/Mrs4s/MiraiGo/client.(*QQClient).netLoop()
      /home/orzogc/go/pkg/mod/github.com/!mrs4s/[email protected]/client/client.go:1121 +0x59c
==================
2020/10/11 16:57:12 Mirai DEBUG: rev pkt: Heartbeat.Alive seq: 13887
2020/10/11 16:57:42 Mirai DEBUG: rev pkt: Heartbeat.Alive seq: 13888
2020/10/11 16:31:48 Mirai DEBUG: rev pkt: Heartbeat.Alive seq: 13885
2020/10/11 16:32:18 Mirai DEBUG: rev pkt: Heartbeat.Alive seq: 13886
==================
WARNING: DATA RACE
Write at 0x00c0003f05cc by goroutine 52:
  github.com/Mrs4s/MiraiGo/client.(*QQClient).doHeartbeat()
      /home/orzogc/go/pkg/mod/github.com/!mrs4s/[email protected]/client/client.go:1171 +0x79
  github.com/Mrs4s/MiraiGo/client.(*QQClient).doHeartbeat-fm()
      /home/orzogc/go/pkg/mod/github.com/!mrs4s/[email protected]/client/client.go:1160 +0x44

Previous write at 0x00c0003f05cc by goroutine 49:
  github.com/Mrs4s/MiraiGo/client.(*QQClient).doHeartbeat()
      /home/orzogc/go/pkg/mod/github.com/!mrs4s/[email protected]/client/client.go:1171 +0x79
  github.com/Mrs4s/MiraiGo/client.(*QQClient).doHeartbeat-fm()
      /home/orzogc/go/pkg/mod/github.com/!mrs4s/[email protected]/client/client.go:1160 +0x44

Goroutine 52 (running) created at:
  time.goFunc()
      /usr/lib/go/src/time/sleep.go:167 +0x51

Goroutine 49 (finished) created at:
  time.goFunc()
      /usr/lib/go/src/time/sleep.go:167 +0x51
==================
==================
WARNING: DATA RACE
Write at 0x00c0000e4f68 by main goroutine:
  github.com/Mrs4s/MiraiGo/client.(*QQClient).Disconnect()
      /home/orzogc/go/pkg/mod/github.com/!mrs4s/[email protected]/client/client.go:991 +0x8b5
  main.initMirai()
      /home/orzogc/src/go/acfunlive/mirai.go:151 +0x83e
  main.main()
      /home/orzogc/src/go/acfunlive/main.go:343 +0x115c

Previous read at 0x00c0000e4f68 by goroutine 32:
  github.com/Mrs4s/MiraiGo/client.(*QQClient).netLoop()
      /home/orzogc/go/pkg/mod/github.com/!mrs4s/[email protected]/client/client.go:1080 +0xe5

Goroutine 32 (running) created at:
  github.com/Mrs4s/MiraiGo/client.(*QQClient).Login()
      /home/orzogc/go/pkg/mod/github.com/!mrs4s/[email protected]/client/client.go:203 +0xd1
  main.initMirai()
      /home/orzogc/src/go/acfunlive/mirai.go:78 +0x2ba
  main.main()
      /home/orzogc/src/go/acfunlive/main.go:343 +0x115c
==================

[bug] go-cqhttp 长时间运行后空指针, panic退出

github.com/Mrs4s/MiraiGo/utils/connection.go:60,看代码中也有提到这个问题
报错信息:
`[2021-07-21 04:19:47] [ERROR]: Protocol -> unexpected disconnect: read tcp 192.168.122.11:40208->120.232.18.180:443: read: connection reset by peer
[2021-07-21 04:19:47] [INFO]: Protocol -> connect to server: 111.30.179.171:80
[2021-07-21 04:19:51] [ERROR]: Protocol -> parse incoming packet error: invalid payload
[2021-07-21 04:19:51] [ERROR]: Protocol -> unexpected disconnect: unexpected EOF
[2021-07-21 04:19:51] [INFO]: Protocol -> connect to server: 36.155.229.218:80
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x18 pc=0x47dd38]

goroutine 65 [running]:
io.ReadAtLeast(0x0, 0x0, 0xc0009e8000, 0x4854544c, 0x4854544c, 0x4854544c, 0x4, 0xc0003de11c, 0x4)
io/io.go:328 +0x58
io.ReadFull(...)
io/io.go:347
github.com/Mrs4s/MiraiGo/utils.(*TCPListener).ReadBytes(0xc0005853a0, 0x4854544c, 0x0, 0x0, 0x0, 0x1, 0x0)
github.com/Mrs4s/[email protected]/utils/connection.go:60 +0xb5
github.com/Mrs4s/MiraiGo/client.(*QQClient).netLoop(0xc00005fc00)
github.com/Mrs4s/[email protected]/client/client.go:1056 +0x90
created by github.com/Mrs4s/MiraiGo/client.NewClientMd5
github.com/Mrs4s/[email protected]/client/client.go:255 +0x78a`

SendGroupMessage时灵时不灵

就只有一个群,有时候消息可以发到群里,有时候发不到群里,SendGroupMessage的返回值我看也没有异常

package main

import (
	"github.com/Mrs4s/MiraiGo/client"
	"github.com/Mrs4s/MiraiGo/message"
	"log"
)

func main() {
	c := client.NewClient(xxx, "xxxx")
	r, err := c.Login()
	if err != nil {
		log.Fatalf("fail %s", err)
	}
	if !r.Success {
		log.Fatalf("fail %s", r.ErrorMessage)
	}
	log.Println("ok")

	gs, err := c.GetGroupList()
	if err != nil {
		log.Fatalf("fail %s", err)
	}

	for _, g := range gs {
		t := message.NewText("xxxxx")
		m := message.SendingMessage{Elements: []message.IMessageElement{t}}
		c.SendGroupMessage(g.Code, &m)
	}

	log.Println(len(gs))
}

GroupMemberInfo的Permission不准确

一个小规模的群,有12个管理员,Permission为Administrator的只有8个,一些管理员的Permission为10(member),reload也没用。

无法正常回复转发后的分享卡片?

前言

手机QQ通过其他App向好友分享一个链接,经过观察,其消息格式为
[LightAppElement]

LightAppElement是一段 JSON 数据,包含了jumpURL,以及 descr等等一系列必要信息

现象

第一次分享后,记此分享卡片的消息ID为 A
回复该分享卡片,ReplyElement的ReplySeq字段被正确设置为A

转发该分享卡片,此时消息ID变为 B
经过观察,转发后的消息格式为 [TextElement, LightAppElement],但实际内容不变
其中TextElement代表一个Fallback msg,例如:”[分享] xxxx 请使用最新版手机QQ查看消息"

回复转发后的卡片,此时ReplyElement的ReplySeq字段却不是B,而是一个负数?
这样导致我无法定位到回复的消息原文究竟是什么

是我对功能理解有问题还是bug ?

实例

// 第一次分享卡片
Message {
  ID=47489
  Elems=[LightAppElement]
}

// 回复上面的卡片
Message {
  ID=....
  Elems=[ReplyElement {
    ReplySeq=47489  // OK. 可以通过47489这个ID查找到消息原文
  }]
}

// 转发第一次分享的卡片
Message {
  ID=54751
  Elems=[TextElement, LightAppElement]
  // 其中 LightAppElement 字段仍然完整保留
}

// 回复转发的卡片
Message {
  ID=....
  Elems=[ReplyElement {
    ReplySeq=-10785  // ????
  }]
}

发送图片会失败

基本都是broken pipe

write conn error: write tcp X.X.X.X:35682->123.151.190.163:80: write: broken pipe

请问上传图片有什么限制?

Typo

Planed应为Planned,Fixed in #148

undefined: io.ReadAll

编译失败,提示 undefined: io.ReadAll
可能是utils/http.go中如下函数出错.

// HttpGetBytes 带 cookie 的 GET 请求
func HttpGetBytes(url, cookie string) ([]byte, error) {
	body, err := HTTPGetReadCloser(url, cookie)
	defer func() { _ = body.Close() }()
	if err != nil {
		return nil, err
	}
	return io.ReadAll(body)
}

return io.ReadAll(body)改为return ioutil.ReadAll(body)后编译成功.
是某个库未引入还是单纯typo?😂

希望增加网页临时会话回复功能

在收到 pMsg.Head.GetMsgType() == 141 && pMsg.Head.GetC2CCmd() == 11 时,回复消息提示需要加好友,但是在手机上和电脑端都可以回复不需要加好友,建议在收到这个类型的消息后可以回复,谢谢。
image
黑框中是我自己加的,已经可以收到临时会话的消息了。

支持从json读取更多设备信息

目前此项目支持读取的信息列表如下

MiraiGo/client/global.go

Lines 51 to 57 in 548911e

type DeviceInfoFile struct {
Display string `json:"display"`
FingerPrint string `json:"finger_print"`
BootId string `json:"boot_id"`
ProcVersion string `json:"proc_version"`
IMEI string `json:"imei"`
}

但是实际上设备信息需要的数据更多

MiraiGo/client/global.go

Lines 17 to 42 in 548911e

type DeviceInfo struct {
Display []byte
Product []byte
Device []byte
Board []byte
Brand []byte
Model []byte
Bootloader []byte
FingerPrint []byte
BootId []byte
ProcVersion []byte
BaseBand []byte
SimInfo []byte
OSType []byte
MacAddress []byte
IpAddress []byte
WifiBSSID []byte
WifiSSID []byte
IMSIMd5 []byte
IMEI string
AndroidId []byte
APN []byte
Guid []byte
TgtgtKey []byte
Version *Version
}

能否开放更多的json读取项目?

重启之后会重复收到私聊信息

重启之后,第一次收到私聊消息的时候会把之前的收到过的消息再接受一遍(不确定范围)
包括一段时间以前的:其中一条fields.time="2021-02-24 19:23:28 +0800 CST""
目前是用msg.Time过滤了一下

        OnPrivateMessage(func(qqClient *client.QQClient, msg *message.PrivateMessage) {
		if msg.Time < int32(time.Now().Add(time.Minute*-1).Unix()) {
			logger.WithField("Sender", msg.Sender.DisplayName()).
				WithField("time", time.Unix(int64(msg.Time), 0)).
				WithField("MessageID", msg.Id).
				Debug("past private message got, skip.")
			return
		}
LONG LOG

time="2021-03-05T13:00:01+08:00" level=debug msg="connect to server: 113.96.13.208:8080" module=miraigo type=INFO
time="2021-03-05T13:00:01+08:00" level=debug msg="rev pkt: wtlogin.login seq: 13878" module=miraigo type=DEBUG
time="2021-03-05T13:00:01+08:00" level=debug msg="rev pkt: wtlogin.login seq: 13879" module=miraigo type=DEBUG
time="2021-03-05T13:00:01+08:00" level=debug msg="rev pkt: StatSvc.register seq: 13880" module=miraigo type=DEBUG
time="2021-03-05T13:00:02+08:00" level=debug msg="rev pkt: OnlinePush.PbPushGroupMsg seq: 25312" module=miraigo type=DEBUG
time="2021-03-05T13:00:02+08:00" level=debug msg="sync group 824098832." module=miraigo type=DEBUG
time="2021-03-05T13:00:02+08:00" level=debug msg="rev pkt: OidbSvc.0x88d_0 seq: 13882" module=miraigo type=DEBUG
time="2021-03-05T13:00:02+08:00" level=debug msg="rev pkt: ProfileService.Pb.ReqSystemMsgNew.Group seq: 13881" module=miraigo type=DEBUG
time="2021-03-05T13:00:02+08:00" level=debug msg="rev pkt: friendlist.GetTroopMemberListReq seq: 13883" module=miraigo type=DEBUG
time="2021-03-05T13:00:02+08:00" level=debug msg="rev pkt: ProfileService.Pb.ReqSystemMsgNew.Group seq: 13884" module=miraigo type=DEBUG
time="2021-03-05T13:00:02+08:00" level=debug msg="rev pkt: Heartbeat.Alive seq: 13887" module=miraigo type=DEBUG
time="2021-03-05T13:00:02+08:00" level=debug msg="rev pkt: RegPrxySvc.GetMsgV2 seq: 36408" module=miraigo type=DEBUG
time="2021-03-05T13:00:02+08:00" level=debug msg="rev pkt: RegPrxySvc.getOffMsg seq: 13886" module=miraigo type=DEBUG
time="2021-03-05T13:00:02+08:00" level=debug msg="rev pkt: RegPrxySvc.PushParam seq: 36409" module=miraigo type=DEBUG
time="2021-03-05T13:00:02+08:00" level=debug msg="rev pkt: RegPrxySvc.PbGetMsg seq: 36410" module=miraigo type=DEBUG
time="2021-03-05T13:00:02+08:00" level=debug msg="rev pkt: RegPrxySvc.NoticeEnd seq: 36411" module=miraigo type=DEBUG
time="2021-03-05T13:00:02+08:00" level=debug msg="rev pkt: friendlist.GetTroopMemberListReq seq: 13885" module=miraigo type=DEBUG
time="2021-03-05T13:00:02+08:00" level=debug msg="rev pkt: StatSvc.GetDevLoginInfo seq: 13888" module=miraigo type=DEBUG
time="2021-03-05T13:00:02+08:00" level=debug msg="rev pkt: friendlist.getFriendGroupList seq: 13889" module=miraigo type=DEBUG
time="2021-03-05T13:00:02+08:00" level=debug msg="rev pkt: friendlist.GetTroopMemberListReq seq: 13890" module=miraigo type=DEBUG
time="2021-03-05T13:00:02+08:00" level=debug msg="rev pkt: friendlist.GetTroopListReqV2 seq: 13891" module=miraigo type=DEBUG
...
time="2021-03-05T13:00:03+08:00" level=debug msg="rev pkt: friendlist.GetTroopMemberListReq seq: 13927" module=miraigo type=DEBUG
time="2021-03-05T13:00:04+08:00" level=debug msg="rev pkt: OnlinePush.PbPushGroupMsg seq: 31280" module=miraigo type=DEBUG
time="2021-03-05T13:00:04+08:00" level=debug msg="rev pkt: OnlinePush.PbPushGroupMsg seq: 16410" module=miraigo type=DEBUG
time="2021-03-05T13:00:04+08:00" level=debug msg="rev pkt: ConfigPushSvc.PushReq seq: 25992" module=miraigo type=DEBUG
time="2021-03-05T13:00:04+08:00" level=debug msg="got file storage svc push." module=miraigo type=DEBUG
time="2021-03-05T13:00:04+08:00" level=debug msg="rev pkt: ConfigPushSvc.PushDomain seq: 25994" module=miraigo type=DEBUG
time="2021-03-05T13:00:04+08:00" level=debug msg="Unhandled Command: ConfigPushSvc.PushDomain\nSeq: 25994\nThis message can be ignored." module=miraigo type=DEBUG
time="2021-03-05T13:00:06+08:00" level=debug msg="rev pkt: OnlinePush.PbPushGroupMsg seq: 14624" module=miraigo type=DEBUG
time="2021-03-05T13:00:06+08:00" level=debug msg="rev pkt: OnlinePush.PbPushGroupMsg seq: 51189" module=miraigo type=DEBUG
time="2021-03-05T13:00:06+08:00" level=debug msg="rev pkt: MessageSvc.PushNotify seq: 26229" module=miraigo type=DEBUG
time="2021-03-05T13:00:06+08:00" level=debug msg="rev pkt: MessageSvc.PbGetMsg seq: 13930" module=miraigo type=DEBUG
time="2021-03-05T13:00:06+08:00" level=debug msg="rev pkt: MessageSvc.PbDeleteMsg seq: 13931" module=miraigo type=DEBUG
time="2021-03-05T13:00:06+08:00" level=debug msg="continue sync with flag: CONTINUME" module=miraigo type=DEBUG
time="2021-03-05T13:00:06+08:00" level=debug msg="rev pkt: MessageSvc.PbGetMsg seq: 13932" module=miraigo type=DEBUG
time="2021-03-05T13:00:06+08:00" level=debug msg="rev pkt: ProfileService.Pb.ReqSystemMsgNew.Group seq: 13933" module=miraigo type=DEBUG
time="2021-03-05T13:00:06+08:00" level=debug msg="rev pkt: ProfileService.Pb.ReqSystemMsgNew.Group seq: 13934" module=miraigo type=DEBUG
time="2021-03-05T13:00:06+08:00" level=debug msg="rev pkt: ProfileService.Pb.ReqSystemMsgNew.Group seq: 13935" module=miraigo type=DEBUG
time="2021-03-05T13:00:07+08:00" level=debug msg="rev pkt: ProfileService.Pb.ReqSystemMsgNew.Group seq: 13936" module=miraigo type=DEBUG
time="2021-03-05T13:00:07+08:00" level=debug msg="rev pkt: ProfileService.Pb.ReqSystemMsgNew.Group seq: 13937" module=miraigo type=DEBUG
time="2021-03-05T13:00:07+08:00" level=debug msg="rev pkt: ProfileService.Pb.ReqSystemMsgNew.Group seq: 13938" module=miraigo type=DEBUG
time="2021-03-05T13:00:07+08:00" level=debug msg="rev pkt: ProfileService.Pb.ReqSystemMsgNew.Group seq: 13939" module=miraigo type=DEBUG
time="2021-03-05T13:00:07+08:00" level=debug msg="rev pkt: ProfileService.Pb.ReqSystemMsgNew.Group seq: 13940" module=miraigo type=DEBUG
time="2021-03-05T13:00:07+08:00" level=debug msg="rev pkt: ProfileService.Pb.ReqSystemMsgNew.Group seq: 13941" module=miraigo type=DEBUG
time="2021-03-05T13:00:07+08:00" level=debug msg="rev pkt: ProfileService.Pb.ReqSystemMsgNew.Group seq: 13942" module=miraigo type=DEBUG
time="2021-03-05T13:00:07+08:00" level=debug msg="rev pkt: ProfileService.Pb.ReqSystemMsgNew.Group seq: 13943" module=miraigo type=DEBUG
time="2021-03-05T13:00:07+08:00" level=debug msg="rev pkt: ProfileService.Pb.ReqSystemMsgNew.Group seq: 13944" module=miraigo type=DEBUG
time="2021-03-05T13:00:07+08:00" level=debug msg="rev pkt: ProfileService.Pb.ReqSystemMsgNew.Group seq: 13945" module=miraigo type=DEBUG
time="2021-03-05T13:00:07+08:00" level=debug msg="rev pkt: ProfileService.Pb.ReqSystemMsgNew.Group seq: 13946" module=miraigo type=DEBUG
time="2021-03-05T13:00:07+08:00" level=debug msg="rev pkt: ProfileService.Pb.ReqSystemMsgNew.Group seq: 13947" module=miraigo type=DEBUG
time="2021-03-05T13:00:07+08:00" level=debug msg="rev pkt: ProfileService.Pb.ReqSystemMsgNew.Group seq: 13948" module=miraigo type=DEBUG
time="2021-03-05T13:00:07+08:00" level=debug msg="rev pkt: MessageSvc.PbDeleteMsg seq: 13949" module=miraigo type=DEBUG
time="2021-03-05T13:00:07+08:00" level=debug msg="continue sync with flag: CONTINUME" module=miraigo type=DEBUG
time="2021-03-05T13:00:08+08:00" level=debug msg="rev pkt: MessageSvc.PbGetMsg seq: 13950" module=miraigo type=DEBUG
time="2021-03-05T13:00:09+08:00" level=debug msg="rev pkt: MessageSvc.PbDeleteMsg seq: 13951" module=miraigo type=DEBUG
time="2021-03-05T13:00:09+08:00" level=debug msg="continue sync with flag: CONTINUME" module=miraigo type=DEBUG
time="2021-03-05T13:00:09+08:00" level=debug msg="rev pkt: MessageSvc.PbGetMsg seq: 13952" module=miraigo type=DEBUG
time="2021-03-05T13:00:09+08:00" level=debug msg="rev pkt: MessageSvc.PbDeleteMsg seq: 13953" module=miraigo type=DEBUG
time="2021-03-05T13:00:09+08:00" level=debug msg="continue sync with flag: CONTINUME" module=miraigo type=DEBUG
time="2021-03-05T13:00:09+08:00" level=debug msg="rev pkt: MessageSvc.PbGetMsg seq: 13954" module=miraigo type=DEBUG
time="2021-03-05T13:00:09+08:00" level=debug msg="rev pkt: MessageSvc.PbDeleteMsg seq: 13955" module=miraigo type=DEBUG
time="2021-03-05T13:00:09+08:00" level=debug msg="continue sync with flag: CONTINUME" module=miraigo type=DEBUG
time="2021-03-05T13:00:09+08:00" level=debug msg="rev pkt: MessageSvc.PbGetMsg seq: 13956" module=miraigo type=DEBUG
time="2021-03-05T13:00:09+08:00" level=debug msg="rev pkt: MessageSvc.PbDeleteMsg seq: 13957" module=miraigo type=DEBUG
time="2021-03-05T13:00:09+08:00" level=debug msg="continue sync with flag: CONTINUME" module=miraigo type=DEBUG
time="2021-03-05T13:00:09+08:00" level=debug msg="rev pkt: MessageSvc.PbGetMsg seq: 13958" module=miraigo type=DEBUG
time="2021-03-05T13:00:09+08:00" level=debug msg="rev pkt: MessageSvc.PbDeleteMsg seq: 13959" module=miraigo type=DEBUG
time="2021-03-05T13:00:09+08:00" level=debug msg="continue sync with flag: CONTINUME" module=miraigo type=DEBUG
time="2021-03-05T13:00:09+08:00" level=debug msg="rev pkt: MessageSvc.PbGetMsg seq: 13960" module=miraigo type=DEBUG
time="2021-03-05T13:00:09+08:00" level=debug msg="rev pkt: MessageSvc.PbDeleteMsg seq: 13961" module=miraigo type=DEBUG
time="2021-03-05T13:00:09+08:00" level=debug msg="continue sync with flag: CONTINUME" module=miraigo type=DEBUG
time="2021-03-05T13:00:09+08:00" level=debug msg="rev pkt: MessageSvc.PbGetMsg seq: 13962" module=miraigo type=DEBUG
time="2021-03-05T13:00:09+08:00" level=debug msg="rev pkt: MessageSvc.PbDeleteMsg seq: 13963" module=miraigo type=DEBUG
time="2021-03-05T13:00:09+08:00" level=debug msg="continue sync with flag: CONTINUME" module=miraigo type=DEBUG
time="2021-03-05T13:00:09+08:00" level=debug msg="rev pkt: MessageSvc.PbGetMsg seq: 13964" module=miraigo type=DEBUG
time="2021-03-05T13:00:09+08:00" level=debug msg="rev pkt: MessageSvc.PbDeleteMsg seq: 13965" module=miraigo type=DEBUG
time="2021-03-05T13:00:09+08:00" level=debug msg="continue sync with flag: CONTINUME" module=miraigo type=DEBUG
time="2021-03-05T13:00:10+08:00" level=debug msg="rev pkt: MessageSvc.PbGetMsg seq: 13966" module=miraigo type=DEBUG
time="2021-03-05T13:00:10+08:00" level=debug msg="rev pkt: MessageSvc.PbDeleteMsg seq: 13967" module=miraigo type=DEBUG
time="2021-03-05T13:00:10+08:00" level=debug msg="continue sync with flag: CONTINUME" module=miraigo type=DEBUG
time="2021-03-05T13:00:10+08:00" level=debug msg="rev pkt: MessageSvc.PbGetMsg seq: 13968" module=miraigo type=DEBUG
time="2021-03-05T13:00:10+08:00" level=debug msg="rev pkt: MessageSvc.PbDeleteMsg seq: 13969" module=miraigo type=DEBUG
time="2021-03-05T13:00:10+08:00" level=debug msg="continue sync with flag: CONTINUME" module=miraigo type=DEBUG
time="2021-03-05T13:00:10+08:00" level=debug msg="rev pkt: MessageSvc.PbGetMsg seq: 13970" module=miraigo type=DEBUG
time="2021-03-05T13:00:10+08:00" level=debug msg="rev pkt: MessageSvc.PbDeleteMsg seq: 13971" module=miraigo type=DEBUG

想知道如何部署

之前都用coolq的,现在出了这码事,打算更换平台了。
mirai之前没怎么研究过,想知道这个怎么部署呢?
可以给我点相关资料么

google/protobuf -> gogo/protobuf

speed++
size+
已经讨论过了,在这写点记录
gogo的protobuf有四种,其中
--gofast_out 需要换包名,+4M
--gogofast_out 需要换包名并改动现有代码,+3M
--gogofaster_out 需要换包名并把指针全部解引用,+2M,目前我那bot用的这,好像有变快但是内存没啥区别..
--gogoslick_out 同上一个,+4M

# find -name *.proto | xargs -I {} ./proto.sh {}
protoc --gogofaster_out=`dirname $1` $1

👆批量regen,也许可以扔到actions(大概率不用

Login 时提示“当前版本过低”

问题描述

使用 MiraiGo-Template 创建的项目,在调用 bot.Login() 方法之后收到错误提示“login failed: 当前版本过低,请升级到QQ最新版本“。已经尝试过切换各种协议、更改登录密码、关闭设备锁,均不能解决。

版本描述

依赖的 MiraiGo 版本为:github.com/Mrs4s/MiraiGo v0.0.0-20210124201115-fb93c5c73169

错误日志

{"bot":"internal","level":"info","msg":"initializing modules ...","time":"2021-01-25T00:15:28-08:00"}
{"level":"info","module":"daredemo_suki","msg":"DD enabled for group ******","time":"2021-01-25T00:15:28-08:00"}
{"level":"info","module":"daredemo_suki","msg":"DD enabled for group ******","time":"2021-01-25T00:15:28-08:00"}
{"bot":"internal","level":"info","msg":"all modules initialized","time":"2021-01-25T00:15:28-08:00"}
{"bot":"internal","level":"info","msg":"registering modules serve functions ...","time":"2021-01-25T00:15:28-08:00"}
{"bot":"internal","level":"info","msg":"all modules serve functions registered","time":"2021-01-25T00:15:28-08:00"}
{"bot":"internal","level":"info","msg":"starting modules tasks ...","time":"2021-01-25T00:15:28-08:00"}
{"bot":"internal","level":"info","msg":"tasks running","time":"2021-01-25T00:15:28-08:00"}
{"bot":"internal","level":"fatal","msg":"login failed: 当前版本过低,请升级到QQ最新版本。","time":"2021-01-25T00:15:29-08:00"}

整理下API,支持编译成C库

方便集成到各种不同语言、环境,也容易二次分发。

就是cgo要考虑的细节问题蛮多的,之前试过改 go-cqhttp ,用 JSON 当Go和C交换数据的格式,导出了 Login/Send/Recv,虽然能在 x86 下跑起来但树莓派上还会 panic。

先提个设想,看看有人感兴趣不。

希望把UploadGroupImage等操作 从go-cqhttp移到MiraiGo

这是一个比较通用的需求,放在SDK更好一点

		if i, ok := elem.(*message.ImageElement); ok {
			gm, err := bot.Client.UploadGroupImage(groupId, i.Data)
			if err != nil {
				log.Warnf("警告: 群 %v 消息图片上传失败: %v", groupId, err)
				continue
			}
			newElem = append(newElem, gm)
			continue
		}
		if i, ok := elem.(*message.VoiceElement); ok {
			gv, err := bot.Client.UploadGroupPtt(groupId, i.Data)
			if err != nil {
				log.Warnf("警告: 群 %v 消息语音上传失败: %v", groupId, err)
				continue
			}
			newElem = append(newElem, gv)
			continue
		}

UploadGroupImage导致panic

panic: runtime error: slice bounds out of range [:7] with capacity 0

goroutine 170 [running]:
github.com/Mrs4s/MiraiGo/binary.(*TEA).Encrypt(0xc0005314a0, 0x13b70e0, 0x0, 0x0, 0xc0005e1108, 0xc000361c48, 0xc0005e11b8)
        /home/xxx/go/pkg/mod/github.com/!mrs4s/[email protected]/binary/tea.go:48 +0x9b0
github.com/Mrs4s/MiraiGo/client.(*QQClient).highwayUploadByBDH(0xc00027aa80, 0xe707e0, 0xc000368060, 0x2, 0xc000630000, 0x80, 0x80, 0x13b70e0, 0x0, 0x0, ...)
        /home/xxx/go/pkg/mod/github.com/!mrs4s/[email protected]/client/highway.go:108 +0x18f
github.com/Mrs4s/MiraiGo/client.(*QQClient).UploadGroupImage(0xc00027aa80, 0xbf3a8a, 0xe707e0, 0xc000368060, 0x7fe00, 0x1a4, 0x0)
        /home/xxx/go/pkg/mod/github.com/!mrs4s/[email protected]/client/image.go:47 +0x59d
github.com/Sora233/Sora233-MiraiGo/lsp.(*LspGroupCommand).SetuCommand.func2(0xc000530ef0, 0xc0004c50a0, 0x1, 0x1, 0xc0004d0a70, 0x1, 0x1, 0xc0006021e0, 0xbf3a8a, 0xc0006a2390, ...)
        /home/xxx/go/src/github.com/Sora233/Sora233-MiraiGo/lsp/groupCommand.go:213 +0x453
created by github.com/Sora233/Sora233-MiraiGo/lsp.(*LspGroupCommand).SetuCommand
        /home/xxx/go/src/github.com/Sora233/Sora233-MiraiGo/lsp/groupCommand.go:199 +0x6c5

在升级了miraigo的版本之后,调用1~2次就会出现

-	github.com/Mrs4s/MiraiGo v0.0.0-20201227141240-b569935970d8
+	github.com/Mrs4s/MiraiGo v0.0.0-20210107163750-ce4834c2ba71

Exited due to segment fault after running for several hours

2020/08/08 01:21:25 parse incoming packet error: return code unsuccessful: -10008
Packet Timed out
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x8e1c45]

goroutine 2344 [running]:
github.com/Mrs4s/go-cqhttp/coolq.(*CQBot).InsertGroupMessage(0xc000094280, 0x0, 0xc0001a9c38)
/root/gocqhttp/go-cqhttp-3078884107/coolq/bot.go:141 +0x45
github.com/Mrs4s/go-cqhttp/coolq.(*CQBot).SendGroupMessage(0xc000094280, 0x44959988, 0xc0001a9c38, 0x1)
/root/gocqhttp/go-cqhttp-3078884107/coolq/bot.go:117 +0x120
github.com/Mrs4s/go-cqhttp/coolq.(*CQBot).CQSendGroupMessage(0xc000094280, 0x44959988, 0xc58ce0, 0xc0001a9da8, 0x0)
/root/gocqhttp/go-cqhttp-3078884107/coolq/api.go:124 +0x35d
github.com/Mrs4s/go-cqhttp/server.glob..func9(0xc000094280, 0x5, 0xc000539c24, 0x353, 0x0, 0x0, 0x0, 0x24, 0x6)
/root/gocqhttp/go-cqhttp-3078884107/server/websocket.go:339 +0x16d
github.com/Mrs4s/go-cqhttp/server.(*websocketServer).listenApi(0x12fae20, 0xc00063a2c0)
/root/gocqhttp/go-cqhttp-3078884107/server/websocket.go:277 +0x50a
created by github.com/Mrs4s/go-cqhttp/server.(*websocketServer).api
/root/gocqhttp/go-cqhttp-3078884107/server/websocket.go:241 +0x1c6

支持设备信息自定义

感谢维护,目前关于支持设备信息自定义有一点建议。

由于最近众所周知的原因风声比较紧,因此想替代原CQHTTP继续进行服务。但是初始化后发现,设备的是基于AndriodPad给出的设备信息,同时其中含有大量MiRai字段,出于隐私和安全性的考虑,想对设备进行高度自定义。

看到源码中,在Global中进行了定义和生成,在Builders中进行了与QQ-Client的交互。

但是本身对通信协议和Go语言都不够熟悉,不知道可否对除了JSON中生成的字段的其他信息进行修改?
以及如果支持修改的话,有无具体格式和自定义要求/限制?

同时基于此,是否可以以本JSON作为绕过“未知设备登录”的手段?以规避设备锁等安全机制。

[Callback]OnJoinGroup有时候不会触发

邀请加群当需要管理员同意时,会触发OnGroupInvited, 有时候管理员同意之后没有触发OnJoinGroup(已经开始接受这个群的消息了),日志里没有关于这个callback的信息。

加载好友列表出现panic

应该是10月5日的更新导致的,4日的 43db052 没有问题。

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x9d6f25]

goroutine 1 [running, locked to thread]:
github.com/Mrs4s/MiraiGo/binary.(*TEA).encode(0x0, 0xc0001987e0, 0x8, 0xe0, 0xc0001987e0, 0x8, 0xe0)
        /home/orzogc/go/pkg/mod/github.com/!mrs4s/[email protected]/binary/tea.go:124 +0x45
github.com/Mrs4s/MiraiGo/binary.(*TEA).Encrypt(0x0, 0xc0003d7400, 0xd6, 0x121, 0xc000010578, 0xc000010578, 0xc0008879e0)
        /home/orzogc/go/pkg/mod/github.com/!mrs4s/[email protected]/binary/tea.go:44 +0x1ee
github.com/Mrs4s/MiraiGo/binary.(*Writer).EncryptAndWrite(0xc000010570, 0x0, 0x0, 0x0, 0xc0003d7400, 0xd6, 0x121)
        /home/orzogc/go/pkg/mod/github.com/!mrs4s/[email protected]/binary/writer.go:68 +0x71
github.com/Mrs4s/MiraiGo/protocol/packets.BuildUniPacket.func1(0xc000010570)
        /home/orzogc/go/pkg/mod/github.com/!mrs4s/[email protected]/protocol/packets/builders.go:35 +0x225
github.com/Mrs4s/MiraiGo/binary.(*Writer).WriteIntLvPacket(0xc00045d650, 0x4, 0xc00045d680)
        /home/orzogc/go/pkg/mod/github.com/!mrs4s/[email protected]/binary/writer.go:74 +0x7b
github.com/Mrs4s/MiraiGo/protocol/packets.BuildUniPacket(0x78ad861d, 0xc000123637, 0xc9dae3, 0x1d, 0xc00042c001, 0xc0001661c8, 0x4, 0x4, 0xc00045d7bc, 0x0, ...)
        /home/orzogc/go/pkg/mod/github.com/!mrs4s/[email protected]/protocol/packets/builders.go:29 +0x1a5
github.com/Mrs4s/MiraiGo/client.(*QQClient).buildFriendGroupListRequestPacket(0xc000172300, 0x960000, 0xc00045d8d0, 0xad0a98, 0x1273d20, 0x1273d28)
        /home/orzogc/go/pkg/mod/github.com/!mrs4s/[email protected]/client/builders.go:363 +0x54a
github.com/Mrs4s/MiraiGo/client.(*QQClient).GetFriendList(0xc000172300, 0x1, 0x1, 0x2)
        /home/orzogc/go/pkg/mod/github.com/!mrs4s/[email protected]/client/client.go:346 +0x85
github.com/Mrs4s/MiraiGo/client.(*QQClient).ReloadFriendList(...)
        /home/orzogc/go/pkg/mod/github.com/!mrs4s/[email protected]/client/client.go:333
main.initMirai(0xc00045dca0)
        /home/orzogc/src/go/acfunlive/mirai.go:107 +0x5e9
main.main()
        /home/orzogc/src/go/acfunlive/main.go:343 +0xe8d

License

mirai 使用 AGPLv3,因此请 miraigo 也是用同样的协议

【feat】支持event取消订阅

MiraiGo提供了非常方便的定义事件,但是似乎不能取消订阅事件。

希望能在此基础上提供取消订阅的功能

下面是我不成熟的代码,通过订阅函数返回一个函数来实现取消订阅的功能。

func (c *QQClient) OnPrivateMessage(f func(*QQClient, *message.PrivateMessage)) func() {
	c.eventHandlers.privateMessageHandlers = append(c.eventHandlers.privateMessageHandlers, f)
	return func() {
		var newHandlers []func(client *QQClient, privateMessage *message.PrivateMessage)
		for _, i := range c.eventHandlers.privateMessageHandlers {
			if reflect.ValueOf(i) != reflect.ValueOf(f) {
				newHandlers = append(newHandlers, i)
			}
		}
		c.eventHandlers.privateMessageHandlers = newHandlers
	}
}

使用

unsub := c.OnPrivateMessage(func(client *QQClient, privateMessage *message.PrivateMessage) {
	//... balabala
})

//once, I dont want to listen to this, event, just unsubscribe it
unsub()

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.