Merge branch 'main' of github.com:f1ynng8/wechat_chatter

This commit is contained in:
f1ynng8
2026-06-21 14:08:49 +08:00
31 changed files with 1831 additions and 1038 deletions
+12 -10
View File
@@ -3,22 +3,24 @@ module github.com/yincongcyincong/weixin-macos/onebot
go 1.25.0
require (
github.com/frida/frida-go v1.0.0
github.com/frida/frida-go v1.0.2
github.com/gorilla/websocket v1.5.3
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d
github.com/rs/zerolog v1.34.0
github.com/rs/zerolog v1.35.1
github.com/wdvxdr1123/go-silk v0.0.0-20220304095002-f67345df09ea
google.golang.org/protobuf v1.36.11
gopkg.in/natefinch/lumberjack.v2 v2.2.1
)
require (
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.19 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 // indirect
golang.org/x/sys v0.12.0 // indirect
google.golang.org/protobuf v1.36.11 // indirect
modernc.org/libc v1.8.1 // indirect
modernc.org/mathutil v1.2.2 // indirect
modernc.org/memory v1.0.4 // indirect
github.com/mattn/go-colorable v0.1.14 // indirect
github.com/mattn/go-isatty v0.0.22 // indirect
github.com/ncruces/go-strftime v1.0.0 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
golang.org/x/sys v0.45.0 // indirect
modernc.org/libc v1.72.3 // indirect
modernc.org/mathutil v1.7.1 // indirect
modernc.org/memory v1.11.0 // indirect
)
+50 -21
View File
@@ -1,42 +1,48 @@
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/frida/frida-go v1.0.0 h1:Xlq1CB8QSAC6zbOFdjCX0oK8RjQGtdl2yATbUQKROwo=
github.com/frida/frida-go v1.0.0/go.mod h1:O8Dg1YBGfQsBEL1a8x3GURw/JllJrcuvg78ga2OgdM4=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/frida/frida-go v1.0.2 h1:qsWfYM2tcTMXw1iimnsnajhp8QJVT75jgJebtW3rPig=
github.com/frida/frida-go v1.0.2/go.mod h1:O8Dg1YBGfQsBEL1a8x3GURw/JllJrcuvg78ga2OgdM4=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-isatty v0.0.22 h1:j8l17JJ9i6VGPUFUYoTUKPSgKe/83EYU2zBC7YNKMw4=
github.com/mattn/go-isatty v0.0.22/go.mod h1:ZXfXG4SQHsB/w3ZeOYbR0PrPwLy+n6xiMrJlRFqopa4=
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d h1:5PJl274Y63IEHC+7izoQE9x6ikvDFZS2mDVS3drnohI=
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/ncruces/go-strftime v1.0.0 h1:HMFp8mLCTPp341M/ZnA4qaf7ZlsbTc+miZjCLOFAw7w=
github.com/ncruces/go-strftime v1.0.0/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6OkFY5QxjkYwrChwuRruF69c169dPK26NUlk=
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0=
github.com/rs/zerolog v1.34.0 h1:k43nTLIwcTVQAncfCw4KZ2VY6ukYoZaBPNOE8txlOeY=
github.com/rs/zerolog v1.34.0/go.mod h1:bJsvje4Z08ROH4Nhs5iH600c3IkWhwp44iRc54W6wYQ=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/rs/zerolog v1.35.1 h1:m7xQeoiLIiV0BCEY4Hs+j2NG4Gp2o2KPKmhnnLiazKI=
github.com/rs/zerolog v1.35.1/go.mod h1:EjML9kdfa/RMA7h/6z6pYmq1ykOuA8/mjWaEvGI+jcw=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/wdvxdr1123/go-silk v0.0.0-20220304095002-f67345df09ea h1:sl1pYm1kHtIndckTY8YDt+QFt77vI0JnKHP0U8rZtKc=
github.com/wdvxdr1123/go-silk v0.0.0-20220304095002-f67345df09ea/go.mod h1:ecFKZPX81BaB70I6ruUgEwYcDOtuNgJGnjdK+MIl5ko=
golang.org/x/mod v0.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8=
golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w=
golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4=
golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201126233918-771906719818/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o=
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY=
golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/tools v0.42.0 h1:uNgphsn75Tdz5Ji2q36v/nsFSfR/9BRFvqhGBaJGd5k=
golang.org/x/tools v0.42.0/go.mod h1:Ma6lCIwGZvHK6XtgbswSoWroEkhugApmsXyrUmBhfr0=
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
@@ -44,10 +50,33 @@ gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST
gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
modernc.org/libc v1.8.1 h1:y9oPIhwcaFXxX7kMp6Qb2ZLKzr0mDkikWN3CV5GS63o=
modernc.org/cc/v4 v4.28.2 h1:3tQ0lf2ADtoby2EtSP+J7IE2SHwEJdP8ioR59wx7XpY=
modernc.org/cc/v4 v4.28.2/go.mod h1:OnovgIhbbMXMu1aISnJ0wvVD1KnW+cAUJkIrAWh+kVI=
modernc.org/ccgo/v4 v4.34.0 h1:yRLPFZieg532OT4rp4JFNIVcquwalMX26G95WQDqwCQ=
modernc.org/ccgo/v4 v4.34.0/go.mod h1:AS5WYMyBakQ+fhsHhtP8mWB82KTGPkNNJDGfGQCe0/A=
modernc.org/fileutil v1.4.0 h1:j6ZzNTftVS054gi281TyLjHPp6CPHr2KCxEXjEbD6SM=
modernc.org/fileutil v1.4.0/go.mod h1:EqdKFDxiByqxLk8ozOxObDSfcVOv/54xDs/DUHdvCUU=
modernc.org/gc/v2 v2.6.5 h1:nyqdV8q46KvTpZlsw66kWqwXRHdjIlJOhG6kxiV/9xI=
modernc.org/gc/v2 v2.6.5/go.mod h1:YgIahr1ypgfe7chRuJi2gD7DBQiKSLMPgBQe9oIiito=
modernc.org/gc/v3 v3.1.2 h1:ZtDCnhonXSZexk/AYsegNRV1lJGgaNZJuKjJSWKyEqo=
modernc.org/gc/v3 v3.1.2/go.mod h1:HFK/6AGESC7Ex+EZJhJ2Gni6cTaYpSMmU/cT9RmlfYY=
modernc.org/goabi0 v0.2.0 h1:HvEowk7LxcPd0eq6mVOAEMai46V+i7Jrj13t4AzuNks=
modernc.org/goabi0 v0.2.0/go.mod h1:CEFRnnJhKvWT1c1JTI3Avm+tgOWbkOu5oPA8eH8LnMI=
modernc.org/libc v1.8.1/go.mod h1:U1eq8YWr/Kc1RWCMFUWEdkTg8OTcfLw2kY8EDwl039w=
modernc.org/libc v1.72.3 h1:ZnDF4tXn4NBXFutMMQC4vtbTFSXhhKzR73fv0beZEAU=
modernc.org/libc v1.72.3/go.mod h1:dn0dZNnnn1clLyvRxLxYExxiKRZIRENOfqQ8XEeg4Qs=
modernc.org/mathutil v1.1.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
modernc.org/mathutil v1.2.2 h1:+yFk8hBprV+4c0U9GjFtL+dV3N8hOJ8JCituQcMShFY=
modernc.org/mathutil v1.2.2/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
modernc.org/memory v1.0.4 h1:utMBrFcpnQDdNsmM6asmyH/FM9TqLPS7XF7otpJmrwM=
modernc.org/mathutil v1.7.1 h1:GCZVGXdaN8gTqB1Mf/usp1Y/hSqgI2vAGGP4jZMCxOU=
modernc.org/mathutil v1.7.1/go.mod h1:4p5IwJITfppl0G4sUEDtCr4DthTaT47/N3aT6MhfgJg=
modernc.org/memory v1.0.4/go.mod h1:nV2OApxradM3/OVbs2/0OsP6nPfakXpi50C7dcoHXlc=
modernc.org/memory v1.11.0 h1:o4QC8aMQzmcwCK3t3Ux/ZHmwFPzE6hf2Y5LbkRs+hbI=
modernc.org/memory v1.11.0/go.mod h1:/JP4VbVC+K5sU2wZi9bHoq2MAkCnrt2r98UGeSK7Mjw=
modernc.org/opt v0.2.0 h1:tGyef5ApycA7FSEOMraay9SaTk5zmbx7Tu+cJs4QKZg=
modernc.org/opt v0.2.0/go.mod h1:03fq9lsNfvkYSfxrfUhZCWPk1lm4cq4N+Bh//bEtgns=
modernc.org/sortutil v1.2.1 h1:+xyoGf15mM3NMlPDnFqrteY07klSFxLElE2PVuWIJ7w=
modernc.org/sortutil v1.2.1/go.mod h1:7ZI3a3REbai7gzCLcotuw9AC4VZVpYMjDzETGsSMqJE=
modernc.org/strutil v1.2.1 h1:UneZBkQA+DX2Rp35KcM69cSsNES9ly8mQWD71HKlOA0=
modernc.org/strutil v1.2.1/go.mod h1:EHkiggD70koQxjVdSBM3JKM7k6L0FbGE5eymy9i3B9A=
modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y=
modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
+40 -10
View File
@@ -37,6 +37,7 @@ func sendHandler(w http.ResponseWriter, r *http.Request) {
sendContent := ""
atUserID := ""
var resultChans []chan error
for _, v := range req.Message {
if v.Type == "text" {
sendContent += v.Data.Text
@@ -49,12 +50,16 @@ func sendHandler(w http.ResponseWriter, r *http.Request) {
}
} else if v.Type == "image" || v.Type == "video" {
msgChan <- &SendMsg{
UserId: req.UserID,
GroupID: req.GroupID,
Content: v.Data.File,
Type: v.Type,
ch := make(chan error, 1)
msg := &SendMsg{
UserId: req.UserID,
GroupID: req.GroupID,
Content: v.Data.File,
Type: v.Type,
ResultChan: ch,
}
msgChan <- msg
resultChans = append(resultChans, ch)
} else if v.Type == "reply" {
if v.Data.ReplyMessage == nil {
Error("reply_message为空")
@@ -62,6 +67,11 @@ func sendHandler(w http.ResponseWriter, r *http.Request) {
}
rm := v.Data.ReplyMessage
// 顶层没有group_id时,从reply_message中取
if req.GroupID == "" && rm.GroupId != "" {
req.GroupID = rm.GroupId
}
// 提取被回复消息的内容
referContent := ""
referMsgType := 1 // 默认text
@@ -88,6 +98,7 @@ func sendHandler(w http.ResponseWriter, r *http.Request) {
// msgsource需要JSON unescape(双重编码: \\u003c → \u003c → <
msgsource := jsonUnescapeString(rm.MsgResource)
ch := make(chan error, 1)
msgChan <- &SendMsg{
UserId: req.UserID,
GroupID: req.GroupID,
@@ -100,17 +111,35 @@ func sendHandler(w http.ResponseWriter, r *http.Request) {
ReferMsgsource: msgsource,
ReferDisplayName: displayName,
ReferContent: referContent,
ResultChan: ch,
}
resultChans = append(resultChans, ch)
}
}
if sendContent != "" {
ch := make(chan error, 1)
msgChan <- &SendMsg{
UserId: req.UserID,
GroupID: req.GroupID,
Content: sendContent,
Type: "text",
AtUser: strings.TrimRight(atUserID, ","),
UserId: req.UserID,
GroupID: req.GroupID,
Content: sendContent,
Type: "text",
AtUser: strings.TrimRight(atUserID, ","),
ResultChan: ch,
}
resultChans = append(resultChans, ch)
}
// 等待所有消息发送完成
for _, ch := range resultChans {
if err := <-ch; err != nil {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusInternalServerError)
json.NewEncoder(w).Encode(map[string]any{
"status": "failed",
"error": err.Error(),
})
return
}
}
@@ -182,3 +211,4 @@ func jsonUnescapeString(s string) string {
}
return result
}
+6 -24
View File
@@ -1,36 +1,18 @@
package main
import (
"crypto/rand"
"encoding/hex"
"fmt"
mathrand "math/rand"
"strconv"
"time"
"github.com/yincongcyincong/weixin-macos/onebot/proto/wxproto"
wxproto "github.com/yincongcyincong/weixin-macos/onebot/proto"
"google.golang.org/protobuf/encoding/protowire"
"google.golang.org/protobuf/proto"
)
// BuildImgMsgProto 构建发送图片消息的protobuf并返回hex编码的字符串
func BuildImgMsgProto(sender, targetId, cdnKey, aesKey, md5Key string) (string, error) {
// 生成16字节随机client_proof (模拟JS的generateBytes(16))
clientProof := make([]byte, 16)
const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
randBytes := make([]byte, 16)
rand.Read(randBytes)
for i := range clientProof {
clientProof[i] = chars[int(randBytes[i])%len(chars)]
}
// 生成5字节varint范围的msgId (2^28 ~ 2^35-1)
msgId := mathrand.Int63n(1<<35-1<<28) + (1 << 28)
// header.unknown4 的值: 从 [0xAF, 0xAC, 0x90, 0x93, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01] 解码
// = -228321745 (signed int64)
const headerUnknown4 int64 = -228321745
// client_msg_id: targetId_timestamp_160_xwechat_3
timestamp := time.Now().Unix()
clientMsgId := targetId + "_" + strconv.FormatInt(timestamp, 10) + "_160_xwechat_3"
@@ -41,11 +23,11 @@ func BuildImgMsgProto(sender, targetId, cdnKey, aesKey, md5Key string) (string,
msg := &wxproto.WxSendImgMsg{
Header: &wxproto.ImgMsgHeader{
Flag: []byte{0x00},
MsgId: msgId,
ClientProof: clientProof,
Unknown4: headerUnknown4,
SysInfo: []byte("UnifiedPCMac 26 arm64"),
Unknown6: 304,
SessionId: int64(globalSessionId),
ClientProof: globalClientProof,
DeviceId: int64(globalDeviceId),
Platform: []byte("UnifiedPCMac 26 arm64"),
Version: 304,
},
ClientMsgId: &wxproto.WxString{Value: clientMsgId},
Sender: &wxproto.WxString{Value: sender},
+38 -17
View File
@@ -27,6 +27,7 @@ func main() {
initFrida()
}
go SendWorker()
go cleanExpiredDownloads()
http.HandleFunc("/send_private_msg", sendHandler)
http.HandleFunc("/send_group_msg", sendHandler)
@@ -60,7 +61,7 @@ func initFlag() {
flag.StringVar(&config.FridaGadgetAddr, "gadget_addr", "127.0.0.1:27042", "Gadget 地址: 127.0.0.1:27042 仅当 type 为 gadget 时有效")
flag.StringVar(&config.OnebotToken, "token", "MuseBot", "OneBot Token: MuseBot")
flag.StringVar(&config.ImagePath, "image_path", "", "图片路径: /Users/xxx/Library/Containers/com.tencent.xinWeChat/Data/Documents/xwechat_files/xxx/temp/xxx/2026-01/Img/")
flag.StringVar(&config.WechatConf, "wechat_conf", "../wechat_version/4_1_9_52_mac.json", "微信配置文件路径: ../wechat_version/4_1_6_12_mac.json")
flag.StringVar(&config.WechatConf, "wechat_conf", "../wechat_version/4_1_9_58_mac.json", "微信配置文件路径: ../wechat_version/4_1_6_12_mac.json")
flag.StringVar(&config.ConnType, "conn_type", "http", "连接类型: http | websocket")
flag.IntVar(&config.SendInterval, "send_interval", 1000, "发送间隔: ms")
flag.IntVar(&config.WechatPid, "wechat_pid", 0, "微信进程 PID,不设置则自动查找")
@@ -125,8 +126,8 @@ func attachWechat() {
if err == nil {
break
}
Info("未发现正在运行的微信进程,5秒后重试...")
time.Sleep(5 * time.Second)
Info("未发现正在运行的微信进程,20秒后重试...")
time.Sleep(20 * time.Second)
}
Info("自动发现微信进程 PID", "PID", pid)
}
@@ -207,22 +208,35 @@ func loadJs() {
} else {
go SendWebSocketMsg(payloadJson)
}
case "finish":
finishChan <- struct{}{}
case "upload":
if selfId, ok := pMap["self_id"]; ok && myWechatId == "" {
myWechatId = selfId.(string)
}
case "buf2resp":
go func() {
msgType := ""
if mt, ok := pMap["msg_type"]; ok {
msgType = mt.(string)
}
if dataInter, ok := pMap["data"]; ok {
if dataArr, ok := dataInter.([]interface{}); ok {
rawBytes := make([]byte, len(dataArr))
for i, v := range dataArr {
if f, ok := v.(float64); ok {
rawBytes[i] = byte(int(f))
}
}
HandleBuf2Resp(msgType, rawBytes)
}
}
}()
case "upload_image_finish":
m := &SendMsg{
Type: "send_image",
}
targetId := ""
if targetIdInter, ok := pMap["target_id"]; ok {
targetIdStr := targetIdInter.(string)
if strings.Contains(targetIdStr, "wxid_") {
m.UserId = targetIdStr
targetId = targetIdInter.(string)
if strings.Contains(targetId, "wxid_") {
m.UserId = targetId
} else {
m.GroupID = targetIdStr
m.GroupID = targetId
}
}
if cdnKey, ok := pMap["cdn_key"]; ok {
@@ -234,17 +248,21 @@ func loadJs() {
if md5Key, ok := pMap["md5_key"]; ok {
m.Md5Key = md5Key.(string)
}
if ch, ok := pendingResultMap.LoadAndDelete(targetId); ok {
m.ResultChan = ch.(chan error)
}
msgChan <- m
case "upload_video_finish":
m := &SendMsg{
Type: "send_video",
}
targetId := ""
if targetIdInter, ok := pMap["target_id"]; ok {
targetIdStr := targetIdInter.(string)
if strings.Contains(targetIdStr, "wxid_") {
m.UserId = targetIdStr
targetId = targetIdInter.(string)
if strings.Contains(targetId, "wxid_") {
m.UserId = targetId
} else {
m.GroupID = targetIdStr
m.GroupID = targetId
}
}
if cdnKey, ok := pMap["cdn_key"]; ok {
@@ -259,6 +277,9 @@ func loadJs() {
if videoId, ok := pMap["video_id"]; ok {
m.VideoId = videoId.(string)
}
if ch, ok := pendingResultMap.LoadAndDelete(targetId); ok {
m.ResultChan = ch.(chan error)
}
msgChan <- m
case "download":
err = Download(payloadJson)
+14
View File
@@ -5,6 +5,20 @@ import (
"time"
)
func cleanExpiredDownloads() {
ticker := time.NewTicker(1 * time.Hour)
for range ticker.C {
now := time.Now().UnixMilli()
userID2FileMsgMap.Range(func(key, value any) bool {
req := value.(*DownloadRequest)
if now-req.LastAppendTime > 24*60*60*1000 {
userID2FileMsgMap.Delete(key)
}
return true
})
}
}
func Download(rawMsg []byte) error {
downloadReq := new(DownloadRequest)
err := json.Unmarshal(rawMsg, downloadReq)
+37 -20
View File
@@ -2,8 +2,10 @@ package main
import (
"encoding/xml"
"fmt"
"math/rand"
"sync"
"github.com/frida/frida-go/frida"
)
@@ -14,15 +16,21 @@ var (
device frida.DeviceInt
taskId = int64(0x20000000)
myWechatId = ""
msgChan = make(chan *SendMsg, 100)
finishChan = make(chan struct{}, 100)
// 全局共享的header字段,启动时初始化一次,两个protobuf共用
globalSessionId = uint32(rand.Int63n(4000000000) + 100000000)
globalDeviceId = rand.Uint64() | (0xFFFFFFFF << 32)
globalClientProof = []byte(fmt.Sprintf("m64%s", generateClientProof(13)))
msgChan = make(chan *SendMsg, 100)
pendingResultMap sync.Map // targetId -> chan error
config = &Config{}
userID2NicknameMap sync.Map
userID2FileMsgMap sync.Map
videoInfoMap sync.Map // targetId -> *VideoInfo
userID2NicknameMap sync.Map
userID2FileMsgMap sync.Map
videoInfoMap sync.Map // targetId -> *VideoInfo
buf2RespChan = make(chan *Buf2RespData, 10)
)
type WechatMessage struct {
@@ -58,9 +66,10 @@ type SendMsg struct {
FilePath string
FileType int
CdnKey string
Md5Key string
VideoId string
CdnKey string
Md5Key string
VideoId string
Duration int32
VideoSize int32
@@ -71,6 +80,8 @@ type SendMsg struct {
ReferMsgsource string
ReferDisplayName string
ReferContent string
ResultChan chan error // 发送结果回传
}
type VideoInfo struct {
@@ -78,6 +89,12 @@ type VideoInfo struct {
VideoSize int32
}
type Buf2RespData struct {
MsgType string
Data []byte
Err error
}
// SendRequest 请求结构体
type SendRequest struct {
Message []*Message `json:"message"`
@@ -91,13 +108,13 @@ type Message struct {
}
type SendRequestData struct {
Id string `json:"id,omitempty"`
Text string `json:"text,omitempty"`
File string `json:"file,omitempty"`
URL string `json:"url,omitempty"`
QQ string `json:"qq,omitempty"`
Media []byte `json:"media,omitempty"`
ReplyMessage *WechatMessage `json:"reply_message,omitempty"`
Id string `json:"id,omitempty"`
Text string `json:"text,omitempty"`
File string `json:"file,omitempty"`
URL string `json:"url,omitempty"`
QQ string `json:"qq,omitempty"`
Media []byte `json:"media,omitempty"`
ReplyMessage *WechatMessage `json:"reply_message,omitempty"`
}
type Config struct {
@@ -163,7 +180,7 @@ type Image struct {
HDHeight int `xml:"cdnhdheight,attr"`
HDWidth int `xml:"cdnhdwidth,attr"`
MidImgURL string `xml:"cdnmidimgurl,attr"`
// 子节点
SecHashInfo string `xml:"secHashInfoBase64"`
Live Live `xml:"live"`
@@ -2,7 +2,7 @@
// versions:
// protoc-gen-go v1.36.11
// protoc v3.5.1
// source: proto/wxproto/reply_msg.proto
// source: app_msg.proto
package wxproto
@@ -28,13 +28,17 @@ type WxSendReplyMsg struct {
state protoimpl.MessageState `protogen:"open.v1"`
Header *ReplyMsgHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"`
Body *ReplyMsgBody `protobuf:"bytes,2,opt,name=body" json:"body,omitempty"`
Unknown5 []byte `protobuf:"bytes,5,opt,name=unknown5" json:"unknown5,omitempty"` // md5
Unknown9 *int32 `protobuf:"varint,9,opt,name=unknown9" json:"unknown9,omitempty"` // 1
Unknown10 *uint64 `protobuf:"varint,10,opt,name=unknown10" json:"unknown10,omitempty"` // msgSvrId
Unknown11 *int32 `protobuf:"varint,11,opt,name=unknown11" json:"unknown11,omitempty"` // 2
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *WxSendReplyMsg) Reset() {
*x = WxSendReplyMsg{}
mi := &file_proto_wxproto_reply_msg_proto_msgTypes[0]
mi := &file_app_msg_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -46,7 +50,7 @@ func (x *WxSendReplyMsg) String() string {
func (*WxSendReplyMsg) ProtoMessage() {}
func (x *WxSendReplyMsg) ProtoReflect() protoreflect.Message {
mi := &file_proto_wxproto_reply_msg_proto_msgTypes[0]
mi := &file_app_msg_proto_msgTypes[0]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -59,7 +63,7 @@ func (x *WxSendReplyMsg) ProtoReflect() protoreflect.Message {
// Deprecated: Use WxSendReplyMsg.ProtoReflect.Descriptor instead.
func (*WxSendReplyMsg) Descriptor() ([]byte, []int) {
return file_proto_wxproto_reply_msg_proto_rawDescGZIP(), []int{0}
return file_app_msg_proto_rawDescGZIP(), []int{0}
}
func (x *WxSendReplyMsg) GetHeader() *ReplyMsgHeader {
@@ -76,22 +80,50 @@ func (x *WxSendReplyMsg) GetBody() *ReplyMsgBody {
return nil
}
// Header: 固定64字节
func (x *WxSendReplyMsg) GetUnknown5() []byte {
if x != nil {
return x.Unknown5
}
return nil
}
func (x *WxSendReplyMsg) GetUnknown9() int32 {
if x != nil && x.Unknown9 != nil {
return *x.Unknown9
}
return 0
}
func (x *WxSendReplyMsg) GetUnknown10() uint64 {
if x != nil && x.Unknown10 != nil {
return *x.Unknown10
}
return 0
}
func (x *WxSendReplyMsg) GetUnknown11() int32 {
if x != nil && x.Unknown11 != nil {
return *x.Unknown11
}
return 0
}
// Header: 请求头,所有消息共用
type ReplyMsgHeader struct {
state protoimpl.MessageState `protogen:"open.v1"`
Flag []byte `protobuf:"bytes,1,opt,name=flag" json:"flag,omitempty"` // 固定 [0x00]
Timestamp *uint32 `protobuf:"varint,2,opt,name=timestamp" json:"timestamp,omitempty"` // 请求时间戳(秒)
ClientProof []byte `protobuf:"bytes,3,opt,name=client_proof,json=clientProof" json:"client_proof,omitempty"` // 16字节随机数据/md5
DeviceId *uint64 `protobuf:"varint,4,opt,name=device_id,json=deviceId" json:"device_id,omitempty"` // 设备标识(大整数)
SessionId *uint32 `protobuf:"varint,2,opt,name=session_id,json=sessionId" json:"session_id,omitempty"` // 会话ID (启动时生成,全局复用)
ClientProof []byte `protobuf:"bytes,3,opt,name=client_proof,json=clientProof" json:"client_proof,omitempty"` // 16字节设备标识字符串 (如"m64a7624402b3883")
DeviceId *uint64 `protobuf:"varint,4,opt,name=device_id,json=deviceId" json:"device_id,omitempty"` // 设备ID (大整数,启动时生成,全局复用)
Platform *string `protobuf:"bytes,5,opt,name=platform" json:"platform,omitempty"` // 平台信息 "UnifiedPCMac 26 arm64"
Version *uint32 `protobuf:"varint,6,opt,name=version" json:"version,omitempty"` // 版本/标记 = 163
Version *uint32 `protobuf:"varint,6,opt,name=version" json:"version,omitempty"` // 版本标记
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *ReplyMsgHeader) Reset() {
*x = ReplyMsgHeader{}
mi := &file_proto_wxproto_reply_msg_proto_msgTypes[1]
mi := &file_app_msg_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -103,7 +135,7 @@ func (x *ReplyMsgHeader) String() string {
func (*ReplyMsgHeader) ProtoMessage() {}
func (x *ReplyMsgHeader) ProtoReflect() protoreflect.Message {
mi := &file_proto_wxproto_reply_msg_proto_msgTypes[1]
mi := &file_app_msg_proto_msgTypes[1]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -116,7 +148,7 @@ func (x *ReplyMsgHeader) ProtoReflect() protoreflect.Message {
// Deprecated: Use ReplyMsgHeader.ProtoReflect.Descriptor instead.
func (*ReplyMsgHeader) Descriptor() ([]byte, []int) {
return file_proto_wxproto_reply_msg_proto_rawDescGZIP(), []int{1}
return file_app_msg_proto_rawDescGZIP(), []int{1}
}
func (x *ReplyMsgHeader) GetFlag() []byte {
@@ -126,9 +158,9 @@ func (x *ReplyMsgHeader) GetFlag() []byte {
return nil
}
func (x *ReplyMsgHeader) GetTimestamp() uint32 {
if x != nil && x.Timestamp != nil {
return *x.Timestamp
func (x *ReplyMsgHeader) GetSessionId() uint32 {
if x != nil && x.SessionId != nil {
return *x.SessionId
}
return 0
}
@@ -185,7 +217,7 @@ type ReplyMsgBody struct {
func (x *ReplyMsgBody) Reset() {
*x = ReplyMsgBody{}
mi := &file_proto_wxproto_reply_msg_proto_msgTypes[2]
mi := &file_app_msg_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -197,7 +229,7 @@ func (x *ReplyMsgBody) String() string {
func (*ReplyMsgBody) ProtoMessage() {}
func (x *ReplyMsgBody) ProtoReflect() protoreflect.Message {
mi := &file_proto_wxproto_reply_msg_proto_msgTypes[2]
mi := &file_app_msg_proto_msgTypes[2]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -210,7 +242,7 @@ func (x *ReplyMsgBody) ProtoReflect() protoreflect.Message {
// Deprecated: Use ReplyMsgBody.ProtoReflect.Descriptor instead.
func (*ReplyMsgBody) Descriptor() ([]byte, []int) {
return file_proto_wxproto_reply_msg_proto_rawDescGZIP(), []int{2}
return file_app_msg_proto_rawDescGZIP(), []int{2}
}
func (x *ReplyMsgBody) GetSender() string {
@@ -318,17 +350,23 @@ func (x *ReplyMsgBody) GetUnknown15() []byte {
return nil
}
var File_proto_wxproto_reply_msg_proto protoreflect.FileDescriptor
var File_app_msg_proto protoreflect.FileDescriptor
const file_proto_wxproto_reply_msg_proto_rawDesc = "" +
const file_app_msg_proto_rawDesc = "" +
"\n" +
"\x1dproto/wxproto/reply_msg.proto\x12\awxproto\"l\n" +
"\rapp_msg.proto\x12\awxproto\"\xe0\x01\n" +
"\x0eWxSendReplyMsg\x12/\n" +
"\x06header\x18\x01 \x01(\v2\x17.wxproto.ReplyMsgHeaderR\x06header\x12)\n" +
"\x04body\x18\x02 \x01(\v2\x15.wxproto.ReplyMsgBodyR\x04body\"\xb8\x01\n" +
"\x04body\x18\x02 \x01(\v2\x15.wxproto.ReplyMsgBodyR\x04body\x12\x1a\n" +
"\bunknown5\x18\x05 \x01(\fR\bunknown5\x12\x1a\n" +
"\bunknown9\x18\t \x01(\x05R\bunknown9\x12\x1c\n" +
"\tunknown10\x18\n" +
" \x01(\x04R\tunknown10\x12\x1c\n" +
"\tunknown11\x18\v \x01(\x05R\tunknown11\"\xb9\x01\n" +
"\x0eReplyMsgHeader\x12\x12\n" +
"\x04flag\x18\x01 \x01(\fR\x04flag\x12\x1c\n" +
"\ttimestamp\x18\x02 \x01(\rR\ttimestamp\x12!\n" +
"\x04flag\x18\x01 \x01(\fR\x04flag\x12\x1d\n" +
"\n" +
"session_id\x18\x02 \x01(\rR\tsessionId\x12!\n" +
"\fclient_proof\x18\x03 \x01(\fR\vclientProof\x12\x1b\n" +
"\tdevice_id\x18\x04 \x01(\x04R\bdeviceId\x12\x1a\n" +
"\bplatform\x18\x05 \x01(\tR\bplatform\x12\x18\n" +
@@ -349,27 +387,27 @@ const file_proto_wxproto_reply_msg_proto_rawDesc = "" +
"\tmsgsource\x18\f \x01(\fR\tmsgsource\x12\x1c\n" +
"\tunknown13\x18\r \x01(\fR\tunknown13\x12\x1c\n" +
"\tunknown14\x18\x0e \x01(\fR\tunknown14\x12\x1c\n" +
"\tunknown15\x18\x0f \x01(\fR\tunknown15B>Z<github.com/yincongcyincong/weixin-macos/onebot/proto/wxproto"
"\tunknown15\x18\x0f \x01(\fR\tunknown15B>Z<github.com/yincongcyincong/weixin-macos/onebot/proto;wxproto"
var (
file_proto_wxproto_reply_msg_proto_rawDescOnce sync.Once
file_proto_wxproto_reply_msg_proto_rawDescData []byte
file_app_msg_proto_rawDescOnce sync.Once
file_app_msg_proto_rawDescData []byte
)
func file_proto_wxproto_reply_msg_proto_rawDescGZIP() []byte {
file_proto_wxproto_reply_msg_proto_rawDescOnce.Do(func() {
file_proto_wxproto_reply_msg_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_proto_wxproto_reply_msg_proto_rawDesc), len(file_proto_wxproto_reply_msg_proto_rawDesc)))
func file_app_msg_proto_rawDescGZIP() []byte {
file_app_msg_proto_rawDescOnce.Do(func() {
file_app_msg_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_app_msg_proto_rawDesc), len(file_app_msg_proto_rawDesc)))
})
return file_proto_wxproto_reply_msg_proto_rawDescData
return file_app_msg_proto_rawDescData
}
var file_proto_wxproto_reply_msg_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
var file_proto_wxproto_reply_msg_proto_goTypes = []any{
var file_app_msg_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
var file_app_msg_proto_goTypes = []any{
(*WxSendReplyMsg)(nil), // 0: wxproto.WxSendReplyMsg
(*ReplyMsgHeader)(nil), // 1: wxproto.ReplyMsgHeader
(*ReplyMsgBody)(nil), // 2: wxproto.ReplyMsgBody
}
var file_proto_wxproto_reply_msg_proto_depIdxs = []int32{
var file_app_msg_proto_depIdxs = []int32{
1, // 0: wxproto.WxSendReplyMsg.header:type_name -> wxproto.ReplyMsgHeader
2, // 1: wxproto.WxSendReplyMsg.body:type_name -> wxproto.ReplyMsgBody
2, // [2:2] is the sub-list for method output_type
@@ -379,26 +417,26 @@ var file_proto_wxproto_reply_msg_proto_depIdxs = []int32{
0, // [0:2] is the sub-list for field type_name
}
func init() { file_proto_wxproto_reply_msg_proto_init() }
func file_proto_wxproto_reply_msg_proto_init() {
if File_proto_wxproto_reply_msg_proto != nil {
func init() { file_app_msg_proto_init() }
func file_app_msg_proto_init() {
if File_app_msg_proto != nil {
return
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: unsafe.Slice(unsafe.StringData(file_proto_wxproto_reply_msg_proto_rawDesc), len(file_proto_wxproto_reply_msg_proto_rawDesc)),
RawDescriptor: unsafe.Slice(unsafe.StringData(file_app_msg_proto_rawDesc), len(file_app_msg_proto_rawDesc)),
NumEnums: 0,
NumMessages: 3,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_proto_wxproto_reply_msg_proto_goTypes,
DependencyIndexes: file_proto_wxproto_reply_msg_proto_depIdxs,
MessageInfos: file_proto_wxproto_reply_msg_proto_msgTypes,
GoTypes: file_app_msg_proto_goTypes,
DependencyIndexes: file_app_msg_proto_depIdxs,
MessageInfos: file_app_msg_proto_msgTypes,
}.Build()
File_proto_wxproto_reply_msg_proto = out.File
file_proto_wxproto_reply_msg_proto_goTypes = nil
file_proto_wxproto_reply_msg_proto_depIdxs = nil
File_app_msg_proto = out.File
file_app_msg_proto_goTypes = nil
file_app_msg_proto_depIdxs = nil
}
@@ -2,7 +2,7 @@ syntax = "proto2";
package wxproto;
option go_package = "github.com/yincongcyincong/weixin-macos/onebot/proto/wxproto";
option go_package = "github.com/yincongcyincong/weixin-macos/onebot/proto;wxproto";
// ()protobuf结构
// CG路径: /cgi-bin/micromsg-bin/sendappmsg
@@ -10,16 +10,20 @@ option go_package = "github.com/yincongcyincong/weixin-macos/onebot/proto/wxprot
message WxSendReplyMsg {
optional ReplyMsgHeader header = 1;
optional ReplyMsgBody body = 2;
optional bytes unknown5 = 5; // md5
optional int32 unknown9 = 9; // 1
optional uint64 unknown10 = 10; // msgSvrId
optional int32 unknown11 = 11; // 2
}
// Header: 64
// Header:
message ReplyMsgHeader {
optional bytes flag = 1; // [0x00]
optional uint32 timestamp = 2; // ()
optional bytes client_proof = 3; // 16/md5
optional uint64 device_id = 4; // ()
optional uint32 session_id = 2; // ID ()
optional bytes client_proof = 3; // 16 ("m64a7624402b3883")
optional uint64 device_id = 4; // ID ()
optional string platform = 5; // "UnifiedPCMac 26 arm64"
optional uint32 version = 6; // / = 163
optional uint32 version = 6; //
}
// Body:
+456
View File
@@ -0,0 +1,456 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.36.11
// protoc v3.5.1
// source: common_resp.proto
package wxproto
import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
unsafe "unsafe"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
// 通用响应: BaseResponse 在 field 1 (适用于 text/video/image/file/reply 等)
type SendMsgResponse struct {
state protoimpl.MessageState `protogen:"open.v1"`
BaseResponse *BaseResponse `protobuf:"bytes,1,opt,name=baseResponse" json:"baseResponse,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *SendMsgResponse) Reset() {
*x = SendMsgResponse{}
mi := &file_common_resp_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *SendMsgResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*SendMsgResponse) ProtoMessage() {}
func (x *SendMsgResponse) ProtoReflect() protoreflect.Message {
mi := &file_common_resp_proto_msgTypes[0]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use SendMsgResponse.ProtoReflect.Descriptor instead.
func (*SendMsgResponse) Descriptor() ([]byte, []int) {
return file_common_resp_proto_rawDescGZIP(), []int{0}
}
func (x *SendMsgResponse) GetBaseResponse() *BaseResponse {
if x != nil {
return x.BaseResponse
}
return nil
}
// 语音响应: BaseResponse 在 field 10
type SendVoiceMsgResponse struct {
state protoimpl.MessageState `protogen:"open.v1"`
SenderWxid *string `protobuf:"bytes,1,opt,name=senderWxid" json:"senderWxid,omitempty"`
ReceiverWxid *string `protobuf:"bytes,2,opt,name=receiverWxid" json:"receiverWxid,omitempty"`
Field3 *uint64 `protobuf:"varint,3,opt,name=field3" json:"field3,omitempty"`
Field4 *uint64 `protobuf:"varint,4,opt,name=field4" json:"field4,omitempty"`
Field5 *uint64 `protobuf:"varint,5,opt,name=field5" json:"field5,omitempty"`
ClientMsgId *string `protobuf:"bytes,6,opt,name=clientMsgId" json:"clientMsgId,omitempty"`
NewMsgId *uint64 `protobuf:"varint,7,opt,name=newMsgId" json:"newMsgId,omitempty"`
Field8 *uint64 `protobuf:"varint,8,opt,name=field8" json:"field8,omitempty"`
Field9 *uint64 `protobuf:"varint,9,opt,name=field9" json:"field9,omitempty"`
BaseResponse *BaseResponse `protobuf:"bytes,10,opt,name=baseResponse" json:"baseResponse,omitempty"`
Field11 *uint64 `protobuf:"varint,11,opt,name=field11" json:"field11,omitempty"`
MsgSvrId *uint64 `protobuf:"varint,12,opt,name=msgSvrId" json:"msgSvrId,omitempty"`
Field13 *uint64 `protobuf:"varint,13,opt,name=field13" json:"field13,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *SendVoiceMsgResponse) Reset() {
*x = SendVoiceMsgResponse{}
mi := &file_common_resp_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *SendVoiceMsgResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*SendVoiceMsgResponse) ProtoMessage() {}
func (x *SendVoiceMsgResponse) ProtoReflect() protoreflect.Message {
mi := &file_common_resp_proto_msgTypes[1]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use SendVoiceMsgResponse.ProtoReflect.Descriptor instead.
func (*SendVoiceMsgResponse) Descriptor() ([]byte, []int) {
return file_common_resp_proto_rawDescGZIP(), []int{1}
}
func (x *SendVoiceMsgResponse) GetSenderWxid() string {
if x != nil && x.SenderWxid != nil {
return *x.SenderWxid
}
return ""
}
func (x *SendVoiceMsgResponse) GetReceiverWxid() string {
if x != nil && x.ReceiverWxid != nil {
return *x.ReceiverWxid
}
return ""
}
func (x *SendVoiceMsgResponse) GetField3() uint64 {
if x != nil && x.Field3 != nil {
return *x.Field3
}
return 0
}
func (x *SendVoiceMsgResponse) GetField4() uint64 {
if x != nil && x.Field4 != nil {
return *x.Field4
}
return 0
}
func (x *SendVoiceMsgResponse) GetField5() uint64 {
if x != nil && x.Field5 != nil {
return *x.Field5
}
return 0
}
func (x *SendVoiceMsgResponse) GetClientMsgId() string {
if x != nil && x.ClientMsgId != nil {
return *x.ClientMsgId
}
return ""
}
func (x *SendVoiceMsgResponse) GetNewMsgId() uint64 {
if x != nil && x.NewMsgId != nil {
return *x.NewMsgId
}
return 0
}
func (x *SendVoiceMsgResponse) GetField8() uint64 {
if x != nil && x.Field8 != nil {
return *x.Field8
}
return 0
}
func (x *SendVoiceMsgResponse) GetField9() uint64 {
if x != nil && x.Field9 != nil {
return *x.Field9
}
return 0
}
func (x *SendVoiceMsgResponse) GetBaseResponse() *BaseResponse {
if x != nil {
return x.BaseResponse
}
return nil
}
func (x *SendVoiceMsgResponse) GetField11() uint64 {
if x != nil && x.Field11 != nil {
return *x.Field11
}
return 0
}
func (x *SendVoiceMsgResponse) GetMsgSvrId() uint64 {
if x != nil && x.MsgSvrId != nil {
return *x.MsgSvrId
}
return 0
}
func (x *SendVoiceMsgResponse) GetField13() uint64 {
if x != nil && x.Field13 != nil {
return *x.Field13
}
return 0
}
// sendfileuploadmsg 专用响应
type SendFileUploadMsgResponse struct {
state protoimpl.MessageState `protogen:"open.v1"`
BaseResponse *BaseResponse `protobuf:"bytes,1,opt,name=baseResponse" json:"baseResponse,omitempty"`
FileUploadToken *string `protobuf:"bytes,2,opt,name=fileUploadToken" json:"fileUploadToken,omitempty"`
MsgSvrId *uint64 `protobuf:"varint,3,opt,name=msgSvrId" json:"msgSvrId,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *SendFileUploadMsgResponse) Reset() {
*x = SendFileUploadMsgResponse{}
mi := &file_common_resp_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *SendFileUploadMsgResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*SendFileUploadMsgResponse) ProtoMessage() {}
func (x *SendFileUploadMsgResponse) ProtoReflect() protoreflect.Message {
mi := &file_common_resp_proto_msgTypes[2]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use SendFileUploadMsgResponse.ProtoReflect.Descriptor instead.
func (*SendFileUploadMsgResponse) Descriptor() ([]byte, []int) {
return file_common_resp_proto_rawDescGZIP(), []int{2}
}
func (x *SendFileUploadMsgResponse) GetBaseResponse() *BaseResponse {
if x != nil {
return x.BaseResponse
}
return nil
}
func (x *SendFileUploadMsgResponse) GetFileUploadToken() string {
if x != nil && x.FileUploadToken != nil {
return *x.FileUploadToken
}
return ""
}
func (x *SendFileUploadMsgResponse) GetMsgSvrId() uint64 {
if x != nil && x.MsgSvrId != nil {
return *x.MsgSvrId
}
return 0
}
type BaseResponse struct {
state protoimpl.MessageState `protogen:"open.v1"`
Ret *int32 `protobuf:"varint,1,opt,name=ret" json:"ret,omitempty"`
ErrMsg *BaseErrMsg `protobuf:"bytes,2,opt,name=errMsg" json:"errMsg,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *BaseResponse) Reset() {
*x = BaseResponse{}
mi := &file_common_resp_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *BaseResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*BaseResponse) ProtoMessage() {}
func (x *BaseResponse) ProtoReflect() protoreflect.Message {
mi := &file_common_resp_proto_msgTypes[3]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use BaseResponse.ProtoReflect.Descriptor instead.
func (*BaseResponse) Descriptor() ([]byte, []int) {
return file_common_resp_proto_rawDescGZIP(), []int{3}
}
func (x *BaseResponse) GetRet() int32 {
if x != nil && x.Ret != nil {
return *x.Ret
}
return 0
}
func (x *BaseResponse) GetErrMsg() *BaseErrMsg {
if x != nil {
return x.ErrMsg
}
return nil
}
type BaseErrMsg struct {
state protoimpl.MessageState `protogen:"open.v1"`
Msg *string `protobuf:"bytes,1,opt,name=msg" json:"msg,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *BaseErrMsg) Reset() {
*x = BaseErrMsg{}
mi := &file_common_resp_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *BaseErrMsg) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*BaseErrMsg) ProtoMessage() {}
func (x *BaseErrMsg) ProtoReflect() protoreflect.Message {
mi := &file_common_resp_proto_msgTypes[4]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use BaseErrMsg.ProtoReflect.Descriptor instead.
func (*BaseErrMsg) Descriptor() ([]byte, []int) {
return file_common_resp_proto_rawDescGZIP(), []int{4}
}
func (x *BaseErrMsg) GetMsg() string {
if x != nil && x.Msg != nil {
return *x.Msg
}
return ""
}
var File_common_resp_proto protoreflect.FileDescriptor
const file_common_resp_proto_rawDesc = "" +
"\n" +
"\x11common_resp.proto\x12\awxproto\"L\n" +
"\x0fSendMsgResponse\x129\n" +
"\fbaseResponse\x18\x01 \x01(\v2\x15.wxproto.BaseResponseR\fbaseResponse\"\x9b\x03\n" +
"\x14SendVoiceMsgResponse\x12\x1e\n" +
"\n" +
"senderWxid\x18\x01 \x01(\tR\n" +
"senderWxid\x12\"\n" +
"\freceiverWxid\x18\x02 \x01(\tR\freceiverWxid\x12\x16\n" +
"\x06field3\x18\x03 \x01(\x04R\x06field3\x12\x16\n" +
"\x06field4\x18\x04 \x01(\x04R\x06field4\x12\x16\n" +
"\x06field5\x18\x05 \x01(\x04R\x06field5\x12 \n" +
"\vclientMsgId\x18\x06 \x01(\tR\vclientMsgId\x12\x1a\n" +
"\bnewMsgId\x18\a \x01(\x04R\bnewMsgId\x12\x16\n" +
"\x06field8\x18\b \x01(\x04R\x06field8\x12\x16\n" +
"\x06field9\x18\t \x01(\x04R\x06field9\x129\n" +
"\fbaseResponse\x18\n" +
" \x01(\v2\x15.wxproto.BaseResponseR\fbaseResponse\x12\x18\n" +
"\afield11\x18\v \x01(\x04R\afield11\x12\x1a\n" +
"\bmsgSvrId\x18\f \x01(\x04R\bmsgSvrId\x12\x18\n" +
"\afield13\x18\r \x01(\x04R\afield13\"\x9c\x01\n" +
"\x19SendFileUploadMsgResponse\x129\n" +
"\fbaseResponse\x18\x01 \x01(\v2\x15.wxproto.BaseResponseR\fbaseResponse\x12(\n" +
"\x0ffileUploadToken\x18\x02 \x01(\tR\x0ffileUploadToken\x12\x1a\n" +
"\bmsgSvrId\x18\x03 \x01(\x04R\bmsgSvrId\"M\n" +
"\fBaseResponse\x12\x10\n" +
"\x03ret\x18\x01 \x01(\x05R\x03ret\x12+\n" +
"\x06errMsg\x18\x02 \x01(\v2\x13.wxproto.BaseErrMsgR\x06errMsg\"\x1e\n" +
"\n" +
"BaseErrMsg\x12\x10\n" +
"\x03msg\x18\x01 \x01(\tR\x03msgB>Z<github.com/yincongcyincong/weixin-macos/onebot/proto;wxproto"
var (
file_common_resp_proto_rawDescOnce sync.Once
file_common_resp_proto_rawDescData []byte
)
func file_common_resp_proto_rawDescGZIP() []byte {
file_common_resp_proto_rawDescOnce.Do(func() {
file_common_resp_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_common_resp_proto_rawDesc), len(file_common_resp_proto_rawDesc)))
})
return file_common_resp_proto_rawDescData
}
var file_common_resp_proto_msgTypes = make([]protoimpl.MessageInfo, 5)
var file_common_resp_proto_goTypes = []any{
(*SendMsgResponse)(nil), // 0: wxproto.SendMsgResponse
(*SendVoiceMsgResponse)(nil), // 1: wxproto.SendVoiceMsgResponse
(*SendFileUploadMsgResponse)(nil), // 2: wxproto.SendFileUploadMsgResponse
(*BaseResponse)(nil), // 3: wxproto.BaseResponse
(*BaseErrMsg)(nil), // 4: wxproto.BaseErrMsg
}
var file_common_resp_proto_depIdxs = []int32{
3, // 0: wxproto.SendMsgResponse.baseResponse:type_name -> wxproto.BaseResponse
3, // 1: wxproto.SendVoiceMsgResponse.baseResponse:type_name -> wxproto.BaseResponse
3, // 2: wxproto.SendFileUploadMsgResponse.baseResponse:type_name -> wxproto.BaseResponse
4, // 3: wxproto.BaseResponse.errMsg:type_name -> wxproto.BaseErrMsg
4, // [4:4] is the sub-list for method output_type
4, // [4:4] is the sub-list for method input_type
4, // [4:4] is the sub-list for extension type_name
4, // [4:4] is the sub-list for extension extendee
0, // [0:4] is the sub-list for field type_name
}
func init() { file_common_resp_proto_init() }
func file_common_resp_proto_init() {
if File_common_resp_proto != nil {
return
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: unsafe.Slice(unsafe.StringData(file_common_resp_proto_rawDesc), len(file_common_resp_proto_rawDesc)),
NumEnums: 0,
NumMessages: 5,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_common_resp_proto_goTypes,
DependencyIndexes: file_common_resp_proto_depIdxs,
MessageInfos: file_common_resp_proto_msgTypes,
}.Build()
File_common_resp_proto = out.File
file_common_resp_proto_goTypes = nil
file_common_resp_proto_depIdxs = nil
}
+43
View File
@@ -0,0 +1,43 @@
syntax = "proto2";
package wxproto;
option go_package = "github.com/yincongcyincong/weixin-macos/onebot/proto;wxproto";
// 通用响应: BaseResponse 在 field 1 (适用于 text/video/image/file/reply 等)
message SendMsgResponse {
optional BaseResponse baseResponse = 1;
}
// 语音响应: BaseResponse 在 field 10
message SendVoiceMsgResponse {
optional string senderWxid = 1;
optional string receiverWxid = 2;
optional uint64 field3 = 3;
optional uint64 field4 = 4;
optional uint64 field5 = 5;
optional string clientMsgId = 6;
optional uint64 newMsgId = 7;
optional uint64 field8 = 8;
optional uint64 field9 = 9;
optional BaseResponse baseResponse = 10;
optional uint64 field11 = 11;
optional uint64 msgSvrId = 12;
optional uint64 field13 = 13;
}
// sendfileuploadmsg 专用响应
message SendFileUploadMsgResponse {
optional BaseResponse baseResponse = 1;
optional string fileUploadToken = 2;
optional uint64 msgSvrId = 3;
}
message BaseResponse {
optional int32 ret = 1;
optional BaseErrMsg errMsg = 2;
}
message BaseErrMsg {
optional string msg = 1;
}
@@ -2,7 +2,7 @@
// versions:
// protoc-gen-go v1.36.11
// protoc v3.5.1
// source: proto/wxproto/img_msg.proto
// source: img_msg.proto
package wxproto
@@ -64,7 +64,7 @@ type WxSendImgMsg struct {
func (x *WxSendImgMsg) Reset() {
*x = WxSendImgMsg{}
mi := &file_proto_wxproto_img_msg_proto_msgTypes[0]
mi := &file_img_msg_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -76,7 +76,7 @@ func (x *WxSendImgMsg) String() string {
func (*WxSendImgMsg) ProtoMessage() {}
func (x *WxSendImgMsg) ProtoReflect() protoreflect.Message {
mi := &file_proto_wxproto_img_msg_proto_msgTypes[0]
mi := &file_img_msg_proto_msgTypes[0]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -89,7 +89,7 @@ func (x *WxSendImgMsg) ProtoReflect() protoreflect.Message {
// Deprecated: Use WxSendImgMsg.ProtoReflect.Descriptor instead.
func (*WxSendImgMsg) Descriptor() ([]byte, []int) {
return file_proto_wxproto_img_msg_proto_rawDescGZIP(), []int{0}
return file_img_msg_proto_rawDescGZIP(), []int{0}
}
func (x *WxSendImgMsg) GetHeader() *ImgMsgHeader {
@@ -298,18 +298,18 @@ func (x *WxSendImgMsg) GetUnknown41() int32 {
type ImgMsgHeader struct {
state protoimpl.MessageState `protogen:"open.v1"`
Flag []byte `protobuf:"bytes,1,opt,name=flag,proto3" json:"flag,omitempty"`
MsgId int64 `protobuf:"varint,2,opt,name=msg_id,json=msgId,proto3" json:"msg_id,omitempty"`
SessionId int64 `protobuf:"varint,2,opt,name=session_id,json=sessionId,proto3" json:"session_id,omitempty"`
ClientProof []byte `protobuf:"bytes,3,opt,name=client_proof,json=clientProof,proto3" json:"client_proof,omitempty"`
Unknown4 int64 `protobuf:"varint,4,opt,name=unknown4,proto3" json:"unknown4,omitempty"`
SysInfo []byte `protobuf:"bytes,5,opt,name=sys_info,json=sysInfo,proto3" json:"sys_info,omitempty"`
Unknown6 int32 `protobuf:"varint,6,opt,name=unknown6,proto3" json:"unknown6,omitempty"`
DeviceId int64 `protobuf:"varint,4,opt,name=device_id,json=deviceId,proto3" json:"device_id,omitempty"`
Platform []byte `protobuf:"bytes,5,opt,name=platform,proto3" json:"platform,omitempty"`
Version int32 `protobuf:"varint,6,opt,name=version,proto3" json:"version,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *ImgMsgHeader) Reset() {
*x = ImgMsgHeader{}
mi := &file_proto_wxproto_img_msg_proto_msgTypes[1]
mi := &file_img_msg_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -321,7 +321,7 @@ func (x *ImgMsgHeader) String() string {
func (*ImgMsgHeader) ProtoMessage() {}
func (x *ImgMsgHeader) ProtoReflect() protoreflect.Message {
mi := &file_proto_wxproto_img_msg_proto_msgTypes[1]
mi := &file_img_msg_proto_msgTypes[1]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -334,7 +334,7 @@ func (x *ImgMsgHeader) ProtoReflect() protoreflect.Message {
// Deprecated: Use ImgMsgHeader.ProtoReflect.Descriptor instead.
func (*ImgMsgHeader) Descriptor() ([]byte, []int) {
return file_proto_wxproto_img_msg_proto_rawDescGZIP(), []int{1}
return file_img_msg_proto_rawDescGZIP(), []int{1}
}
func (x *ImgMsgHeader) GetFlag() []byte {
@@ -344,9 +344,9 @@ func (x *ImgMsgHeader) GetFlag() []byte {
return nil
}
func (x *ImgMsgHeader) GetMsgId() int64 {
func (x *ImgMsgHeader) GetSessionId() int64 {
if x != nil {
return x.MsgId
return x.SessionId
}
return 0
}
@@ -358,23 +358,23 @@ func (x *ImgMsgHeader) GetClientProof() []byte {
return nil
}
func (x *ImgMsgHeader) GetUnknown4() int64 {
func (x *ImgMsgHeader) GetDeviceId() int64 {
if x != nil {
return x.Unknown4
return x.DeviceId
}
return 0
}
func (x *ImgMsgHeader) GetSysInfo() []byte {
func (x *ImgMsgHeader) GetPlatform() []byte {
if x != nil {
return x.SysInfo
return x.Platform
}
return nil
}
func (x *ImgMsgHeader) GetUnknown6() int32 {
func (x *ImgMsgHeader) GetVersion() int32 {
if x != nil {
return x.Unknown6
return x.Version
}
return 0
}
@@ -389,7 +389,7 @@ type ImgMsgExtra struct {
func (x *ImgMsgExtra) Reset() {
*x = ImgMsgExtra{}
mi := &file_proto_wxproto_img_msg_proto_msgTypes[2]
mi := &file_img_msg_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -401,7 +401,7 @@ func (x *ImgMsgExtra) String() string {
func (*ImgMsgExtra) ProtoMessage() {}
func (x *ImgMsgExtra) ProtoReflect() protoreflect.Message {
mi := &file_proto_wxproto_img_msg_proto_msgTypes[2]
mi := &file_img_msg_proto_msgTypes[2]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -414,7 +414,7 @@ func (x *ImgMsgExtra) ProtoReflect() protoreflect.Message {
// Deprecated: Use ImgMsgExtra.ProtoReflect.Descriptor instead.
func (*ImgMsgExtra) Descriptor() ([]byte, []int) {
return file_proto_wxproto_img_msg_proto_rawDescGZIP(), []int{2}
return file_img_msg_proto_rawDescGZIP(), []int{2}
}
func (x *ImgMsgExtra) GetField1() int32 {
@@ -431,11 +431,11 @@ func (x *ImgMsgExtra) GetField2() []byte {
return nil
}
var File_proto_wxproto_img_msg_proto protoreflect.FileDescriptor
var File_img_msg_proto protoreflect.FileDescriptor
const file_proto_wxproto_img_msg_proto_rawDesc = "" +
const file_img_msg_proto_rawDesc = "" +
"\n" +
"\x1bproto/wxproto/img_msg.proto\x12\awxproto\x1a\x1aproto/wxproto/wx_msg.proto\"\xa3\a\n" +
"\rimg_msg.proto\x12\awxproto\x1a\fwx_msg.proto\"\xa3\a\n" +
"\fWxSendImgMsg\x12-\n" +
"\x06header\x18\x01 \x01(\v2\x15.wxproto.ImgMsgHeaderR\x06header\x125\n" +
"\rclient_msg_id\x18\x02 \x01(\v2\x11.wxproto.WxStringR\vclientMsgId\x12)\n" +
@@ -466,38 +466,39 @@ const file_proto_wxproto_img_msg_proto_rawDesc = "" +
"\tunknown28\x18\x1c \x01(\x03R\tunknown28\x12\x1c\n" +
"\tunknown30\x18\x1e \x01(\x05R\tunknown30\x12\x1c\n" +
"\tunknown36\x18$ \x01(\x05R\tunknown36\x12\x1c\n" +
"\tunknown41\x18) \x01(\x05R\tunknown41\"\xaf\x01\n" +
"\tunknown41\x18) \x01(\x05R\tunknown41\"\xb7\x01\n" +
"\fImgMsgHeader\x12\x12\n" +
"\x04flag\x18\x01 \x01(\fR\x04flag\x12\x15\n" +
"\x06msg_id\x18\x02 \x01(\x03R\x05msgId\x12!\n" +
"\fclient_proof\x18\x03 \x01(\fR\vclientProof\x12\x1a\n" +
"\bunknown4\x18\x04 \x01(\x03R\bunknown4\x12\x19\n" +
"\bsys_info\x18\x05 \x01(\fR\asysInfo\x12\x1a\n" +
"\bunknown6\x18\x06 \x01(\x05R\bunknown6\"=\n" +
"\x04flag\x18\x01 \x01(\fR\x04flag\x12\x1d\n" +
"\n" +
"session_id\x18\x02 \x01(\x03R\tsessionId\x12!\n" +
"\fclient_proof\x18\x03 \x01(\fR\vclientProof\x12\x1b\n" +
"\tdevice_id\x18\x04 \x01(\x03R\bdeviceId\x12\x1a\n" +
"\bplatform\x18\x05 \x01(\fR\bplatform\x12\x18\n" +
"\aversion\x18\x06 \x01(\x05R\aversion\"=\n" +
"\vImgMsgExtra\x12\x16\n" +
"\x06field1\x18\x01 \x01(\x05R\x06field1\x12\x16\n" +
"\x06field2\x18\x02 \x01(\fR\x06field2B>Z<github.com/yincongcyincong/weixin-macos/onebot/proto/wxprotob\x06proto3"
"\x06field2\x18\x02 \x01(\fR\x06field2B>Z<github.com/yincongcyincong/weixin-macos/onebot/proto;wxprotob\x06proto3"
var (
file_proto_wxproto_img_msg_proto_rawDescOnce sync.Once
file_proto_wxproto_img_msg_proto_rawDescData []byte
file_img_msg_proto_rawDescOnce sync.Once
file_img_msg_proto_rawDescData []byte
)
func file_proto_wxproto_img_msg_proto_rawDescGZIP() []byte {
file_proto_wxproto_img_msg_proto_rawDescOnce.Do(func() {
file_proto_wxproto_img_msg_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_proto_wxproto_img_msg_proto_rawDesc), len(file_proto_wxproto_img_msg_proto_rawDesc)))
func file_img_msg_proto_rawDescGZIP() []byte {
file_img_msg_proto_rawDescOnce.Do(func() {
file_img_msg_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_img_msg_proto_rawDesc), len(file_img_msg_proto_rawDesc)))
})
return file_proto_wxproto_img_msg_proto_rawDescData
return file_img_msg_proto_rawDescData
}
var file_proto_wxproto_img_msg_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
var file_proto_wxproto_img_msg_proto_goTypes = []any{
var file_img_msg_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
var file_img_msg_proto_goTypes = []any{
(*WxSendImgMsg)(nil), // 0: wxproto.WxSendImgMsg
(*ImgMsgHeader)(nil), // 1: wxproto.ImgMsgHeader
(*ImgMsgExtra)(nil), // 2: wxproto.ImgMsgExtra
(*WxString)(nil), // 3: wxproto.WxString
}
var file_proto_wxproto_img_msg_proto_depIdxs = []int32{
var file_img_msg_proto_depIdxs = []int32{
1, // 0: wxproto.WxSendImgMsg.header:type_name -> wxproto.ImgMsgHeader
3, // 1: wxproto.WxSendImgMsg.client_msg_id:type_name -> wxproto.WxString
3, // 2: wxproto.WxSendImgMsg.sender:type_name -> wxproto.WxString
@@ -510,27 +511,27 @@ var file_proto_wxproto_img_msg_proto_depIdxs = []int32{
0, // [0:5] is the sub-list for field type_name
}
func init() { file_proto_wxproto_img_msg_proto_init() }
func file_proto_wxproto_img_msg_proto_init() {
if File_proto_wxproto_img_msg_proto != nil {
func init() { file_img_msg_proto_init() }
func file_img_msg_proto_init() {
if File_img_msg_proto != nil {
return
}
file_proto_wxproto_wx_msg_proto_init()
file_wx_msg_proto_init()
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: unsafe.Slice(unsafe.StringData(file_proto_wxproto_img_msg_proto_rawDesc), len(file_proto_wxproto_img_msg_proto_rawDesc)),
RawDescriptor: unsafe.Slice(unsafe.StringData(file_img_msg_proto_rawDesc), len(file_img_msg_proto_rawDesc)),
NumEnums: 0,
NumMessages: 3,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_proto_wxproto_img_msg_proto_goTypes,
DependencyIndexes: file_proto_wxproto_img_msg_proto_depIdxs,
MessageInfos: file_proto_wxproto_img_msg_proto_msgTypes,
GoTypes: file_img_msg_proto_goTypes,
DependencyIndexes: file_img_msg_proto_depIdxs,
MessageInfos: file_img_msg_proto_msgTypes,
}.Build()
File_proto_wxproto_img_msg_proto = out.File
file_proto_wxproto_img_msg_proto_goTypes = nil
file_proto_wxproto_img_msg_proto_depIdxs = nil
File_img_msg_proto = out.File
file_img_msg_proto_goTypes = nil
file_img_msg_proto_depIdxs = nil
}
@@ -2,9 +2,9 @@ syntax = "proto3";
package wxproto;
option go_package = "github.com/yincongcyincong/weixin-macos/onebot/proto/wxproto";
option go_package = "github.com/yincongcyincong/weixin-macos/onebot/proto;wxproto";
import "proto/wxproto/wx_msg.proto";
import "wx_msg.proto";
// protobuf结构
message WxSendImgMsg {
@@ -46,11 +46,11 @@ message WxSendImgMsg {
message ImgMsgHeader {
bytes flag = 1;
int64 msg_id = 2;
int64 session_id = 2;
bytes client_proof = 3;
int64 unknown4 = 4;
bytes sys_info = 5;
int32 unknown6 = 6;
int64 device_id = 4;
bytes platform = 5;
int32 version = 6;
}
message ImgMsgExtra {
@@ -2,7 +2,7 @@
// versions:
// protoc-gen-go v1.36.11
// protoc v3.5.1
// source: proto/wxproto/text_msg.proto
// source: text_msg.proto
package wxproto
@@ -32,7 +32,7 @@ type WxSendTextMsg struct {
func (x *WxSendTextMsg) Reset() {
*x = WxSendTextMsg{}
mi := &file_proto_wxproto_text_msg_proto_msgTypes[0]
mi := &file_text_msg_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -44,7 +44,7 @@ func (x *WxSendTextMsg) String() string {
func (*WxSendTextMsg) ProtoMessage() {}
func (x *WxSendTextMsg) ProtoReflect() protoreflect.Message {
mi := &file_proto_wxproto_text_msg_proto_msgTypes[0]
mi := &file_text_msg_proto_msgTypes[0]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -57,7 +57,7 @@ func (x *WxSendTextMsg) ProtoReflect() protoreflect.Message {
// Deprecated: Use WxSendTextMsg.ProtoReflect.Descriptor instead.
func (*WxSendTextMsg) Descriptor() ([]byte, []int) {
return file_proto_wxproto_text_msg_proto_rawDescGZIP(), []int{0}
return file_text_msg_proto_rawDescGZIP(), []int{0}
}
func (x *WxSendTextMsg) GetType() int32 {
@@ -88,7 +88,7 @@ type WxSendTextBody struct {
func (x *WxSendTextBody) Reset() {
*x = WxSendTextBody{}
mi := &file_proto_wxproto_text_msg_proto_msgTypes[1]
mi := &file_text_msg_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -100,7 +100,7 @@ func (x *WxSendTextBody) String() string {
func (*WxSendTextBody) ProtoMessage() {}
func (x *WxSendTextBody) ProtoReflect() protoreflect.Message {
mi := &file_proto_wxproto_text_msg_proto_msgTypes[1]
mi := &file_text_msg_proto_msgTypes[1]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -113,7 +113,7 @@ func (x *WxSendTextBody) ProtoReflect() protoreflect.Message {
// Deprecated: Use WxSendTextBody.ProtoReflect.Descriptor instead.
func (*WxSendTextBody) Descriptor() ([]byte, []int) {
return file_proto_wxproto_text_msg_proto_rawDescGZIP(), []int{1}
return file_text_msg_proto_rawDescGZIP(), []int{1}
}
func (x *WxSendTextBody) GetReceiver() *WxString {
@@ -158,11 +158,11 @@ func (x *WxSendTextBody) GetXml() []byte {
return nil
}
var File_proto_wxproto_text_msg_proto protoreflect.FileDescriptor
var File_text_msg_proto protoreflect.FileDescriptor
const file_proto_wxproto_text_msg_proto_rawDesc = "" +
const file_text_msg_proto_rawDesc = "" +
"\n" +
"\x1cproto/wxproto/text_msg.proto\x12\awxproto\x1a\x1aproto/wxproto/wx_msg.proto\"P\n" +
"\x0etext_msg.proto\x12\awxproto\x1a\fwx_msg.proto\"P\n" +
"\rWxSendTextMsg\x12\x12\n" +
"\x04type\x18\x01 \x01(\x05R\x04type\x12+\n" +
"\x04body\x18\x02 \x01(\v2\x17.wxproto.WxSendTextBodyR\x04body\"\xb4\x01\n" +
@@ -172,27 +172,27 @@ const file_proto_wxproto_text_msg_proto_rawDesc = "" +
"\x04flag\x18\x03 \x01(\x05R\x04flag\x12\x1c\n" +
"\ttimestamp\x18\x04 \x01(\x03R\ttimestamp\x12\x15\n" +
"\x06msg_id\x18\x05 \x01(\x03R\x05msgId\x12\x10\n" +
"\x03xml\x18\x06 \x01(\fR\x03xmlB>Z<github.com/yincongcyincong/weixin-macos/onebot/proto/wxprotob\x06proto3"
"\x03xml\x18\x06 \x01(\fR\x03xmlB>Z<github.com/yincongcyincong/weixin-macos/onebot/proto;wxprotob\x06proto3"
var (
file_proto_wxproto_text_msg_proto_rawDescOnce sync.Once
file_proto_wxproto_text_msg_proto_rawDescData []byte
file_text_msg_proto_rawDescOnce sync.Once
file_text_msg_proto_rawDescData []byte
)
func file_proto_wxproto_text_msg_proto_rawDescGZIP() []byte {
file_proto_wxproto_text_msg_proto_rawDescOnce.Do(func() {
file_proto_wxproto_text_msg_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_proto_wxproto_text_msg_proto_rawDesc), len(file_proto_wxproto_text_msg_proto_rawDesc)))
func file_text_msg_proto_rawDescGZIP() []byte {
file_text_msg_proto_rawDescOnce.Do(func() {
file_text_msg_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_text_msg_proto_rawDesc), len(file_text_msg_proto_rawDesc)))
})
return file_proto_wxproto_text_msg_proto_rawDescData
return file_text_msg_proto_rawDescData
}
var file_proto_wxproto_text_msg_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
var file_proto_wxproto_text_msg_proto_goTypes = []any{
var file_text_msg_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
var file_text_msg_proto_goTypes = []any{
(*WxSendTextMsg)(nil), // 0: wxproto.WxSendTextMsg
(*WxSendTextBody)(nil), // 1: wxproto.WxSendTextBody
(*WxString)(nil), // 2: wxproto.WxString
}
var file_proto_wxproto_text_msg_proto_depIdxs = []int32{
var file_text_msg_proto_depIdxs = []int32{
1, // 0: wxproto.WxSendTextMsg.body:type_name -> wxproto.WxSendTextBody
2, // 1: wxproto.WxSendTextBody.receiver:type_name -> wxproto.WxString
2, // [2:2] is the sub-list for method output_type
@@ -202,27 +202,27 @@ var file_proto_wxproto_text_msg_proto_depIdxs = []int32{
0, // [0:2] is the sub-list for field type_name
}
func init() { file_proto_wxproto_text_msg_proto_init() }
func file_proto_wxproto_text_msg_proto_init() {
if File_proto_wxproto_text_msg_proto != nil {
func init() { file_text_msg_proto_init() }
func file_text_msg_proto_init() {
if File_text_msg_proto != nil {
return
}
file_proto_wxproto_wx_msg_proto_init()
file_wx_msg_proto_init()
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: unsafe.Slice(unsafe.StringData(file_proto_wxproto_text_msg_proto_rawDesc), len(file_proto_wxproto_text_msg_proto_rawDesc)),
RawDescriptor: unsafe.Slice(unsafe.StringData(file_text_msg_proto_rawDesc), len(file_text_msg_proto_rawDesc)),
NumEnums: 0,
NumMessages: 2,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_proto_wxproto_text_msg_proto_goTypes,
DependencyIndexes: file_proto_wxproto_text_msg_proto_depIdxs,
MessageInfos: file_proto_wxproto_text_msg_proto_msgTypes,
GoTypes: file_text_msg_proto_goTypes,
DependencyIndexes: file_text_msg_proto_depIdxs,
MessageInfos: file_text_msg_proto_msgTypes,
}.Build()
File_proto_wxproto_text_msg_proto = out.File
file_proto_wxproto_text_msg_proto_goTypes = nil
file_proto_wxproto_text_msg_proto_depIdxs = nil
File_text_msg_proto = out.File
file_text_msg_proto_goTypes = nil
file_text_msg_proto_depIdxs = nil
}
@@ -2,9 +2,9 @@ syntax = "proto3";
package wxproto;
option go_package = "github.com/yincongcyincong/weixin-macos/onebot/proto/wxproto";
option go_package = "github.com/yincongcyincong/weixin-macos/onebot/proto;wxproto";
import "proto/wxproto/wx_msg.proto";
import "wx_msg.proto";
// protobuf结构
message WxSendTextMsg {
@@ -2,7 +2,7 @@
// versions:
// protoc-gen-go v1.36.11
// protoc v3.5.1
// source: proto/wxproto/video_msg.proto
// source: video_msg.proto
package wxproto
@@ -63,7 +63,7 @@ type WxSendVideoMsg struct {
func (x *WxSendVideoMsg) Reset() {
*x = WxSendVideoMsg{}
mi := &file_proto_wxproto_video_msg_proto_msgTypes[0]
mi := &file_video_msg_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -75,7 +75,7 @@ func (x *WxSendVideoMsg) String() string {
func (*WxSendVideoMsg) ProtoMessage() {}
func (x *WxSendVideoMsg) ProtoReflect() protoreflect.Message {
mi := &file_proto_wxproto_video_msg_proto_msgTypes[0]
mi := &file_video_msg_proto_msgTypes[0]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -88,7 +88,7 @@ func (x *WxSendVideoMsg) ProtoReflect() protoreflect.Message {
// Deprecated: Use WxSendVideoMsg.ProtoReflect.Descriptor instead.
func (*WxSendVideoMsg) Descriptor() ([]byte, []int) {
return file_proto_wxproto_video_msg_proto_rawDescGZIP(), []int{0}
return file_video_msg_proto_rawDescGZIP(), []int{0}
}
func (x *WxSendVideoMsg) GetHeader() *VideoMsgHeader {
@@ -304,18 +304,18 @@ func (x *WxSendVideoMsg) GetVideoSize3() int32 {
type VideoMsgHeader struct {
state protoimpl.MessageState `protogen:"open.v1"`
Flag []byte `protobuf:"bytes,1,opt,name=flag,proto3" json:"flag,omitempty"`
MsgId int64 `protobuf:"varint,2,opt,name=msg_id,json=msgId,proto3" json:"msg_id,omitempty"`
SessionId int64 `protobuf:"varint,2,opt,name=session_id,json=sessionId,proto3" json:"session_id,omitempty"`
ClientProof []byte `protobuf:"bytes,3,opt,name=client_proof,json=clientProof,proto3" json:"client_proof,omitempty"`
Unknown4 int64 `protobuf:"varint,4,opt,name=unknown4,proto3" json:"unknown4,omitempty"`
SysInfo []byte `protobuf:"bytes,5,opt,name=sys_info,json=sysInfo,proto3" json:"sys_info,omitempty"`
Unknown6 int32 `protobuf:"varint,6,opt,name=unknown6,proto3" json:"unknown6,omitempty"`
DeviceId int64 `protobuf:"varint,4,opt,name=device_id,json=deviceId,proto3" json:"device_id,omitempty"`
Platform []byte `protobuf:"bytes,5,opt,name=platform,proto3" json:"platform,omitempty"`
Version int32 `protobuf:"varint,6,opt,name=version,proto3" json:"version,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *VideoMsgHeader) Reset() {
*x = VideoMsgHeader{}
mi := &file_proto_wxproto_video_msg_proto_msgTypes[1]
mi := &file_video_msg_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -327,7 +327,7 @@ func (x *VideoMsgHeader) String() string {
func (*VideoMsgHeader) ProtoMessage() {}
func (x *VideoMsgHeader) ProtoReflect() protoreflect.Message {
mi := &file_proto_wxproto_video_msg_proto_msgTypes[1]
mi := &file_video_msg_proto_msgTypes[1]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -340,7 +340,7 @@ func (x *VideoMsgHeader) ProtoReflect() protoreflect.Message {
// Deprecated: Use VideoMsgHeader.ProtoReflect.Descriptor instead.
func (*VideoMsgHeader) Descriptor() ([]byte, []int) {
return file_proto_wxproto_video_msg_proto_rawDescGZIP(), []int{1}
return file_video_msg_proto_rawDescGZIP(), []int{1}
}
func (x *VideoMsgHeader) GetFlag() []byte {
@@ -350,9 +350,9 @@ func (x *VideoMsgHeader) GetFlag() []byte {
return nil
}
func (x *VideoMsgHeader) GetMsgId() int64 {
func (x *VideoMsgHeader) GetSessionId() int64 {
if x != nil {
return x.MsgId
return x.SessionId
}
return 0
}
@@ -364,23 +364,23 @@ func (x *VideoMsgHeader) GetClientProof() []byte {
return nil
}
func (x *VideoMsgHeader) GetUnknown4() int64 {
func (x *VideoMsgHeader) GetDeviceId() int64 {
if x != nil {
return x.Unknown4
return x.DeviceId
}
return 0
}
func (x *VideoMsgHeader) GetSysInfo() []byte {
func (x *VideoMsgHeader) GetPlatform() []byte {
if x != nil {
return x.SysInfo
return x.Platform
}
return nil
}
func (x *VideoMsgHeader) GetUnknown6() int32 {
func (x *VideoMsgHeader) GetVersion() int32 {
if x != nil {
return x.Unknown6
return x.Version
}
return 0
}
@@ -395,7 +395,7 @@ type VideoMsgExtra struct {
func (x *VideoMsgExtra) Reset() {
*x = VideoMsgExtra{}
mi := &file_proto_wxproto_video_msg_proto_msgTypes[2]
mi := &file_video_msg_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -407,7 +407,7 @@ func (x *VideoMsgExtra) String() string {
func (*VideoMsgExtra) ProtoMessage() {}
func (x *VideoMsgExtra) ProtoReflect() protoreflect.Message {
mi := &file_proto_wxproto_video_msg_proto_msgTypes[2]
mi := &file_video_msg_proto_msgTypes[2]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -420,7 +420,7 @@ func (x *VideoMsgExtra) ProtoReflect() protoreflect.Message {
// Deprecated: Use VideoMsgExtra.ProtoReflect.Descriptor instead.
func (*VideoMsgExtra) Descriptor() ([]byte, []int) {
return file_proto_wxproto_video_msg_proto_rawDescGZIP(), []int{2}
return file_video_msg_proto_rawDescGZIP(), []int{2}
}
func (x *VideoMsgExtra) GetField1() int32 {
@@ -437,11 +437,11 @@ func (x *VideoMsgExtra) GetField2() []byte {
return nil
}
var File_proto_wxproto_video_msg_proto protoreflect.FileDescriptor
var File_video_msg_proto protoreflect.FileDescriptor
const file_proto_wxproto_video_msg_proto_rawDesc = "" +
const file_video_msg_proto_rawDesc = "" +
"\n" +
"\x1dproto/wxproto/video_msg.proto\x12\awxproto\"\xa7\a\n" +
"\x0fvideo_msg.proto\x12\awxproto\"\xa7\a\n" +
"\x0eWxSendVideoMsg\x12/\n" +
"\x06header\x18\x01 \x01(\v2\x17.wxproto.VideoMsgHeaderR\x06header\x12\"\n" +
"\rclient_msg_id\x18\x02 \x01(\fR\vclientMsgId\x12\x16\n" +
@@ -476,37 +476,38 @@ const file_proto_wxproto_video_msg_proto_rawDesc = "" +
"\bcdn_key3\x181 \x01(\fR\acdnKey3\x12\x19\n" +
"\baes_key3\x182 \x01(\fR\aaesKey3\x12\x1f\n" +
"\vvideo_size3\x183 \x01(\x05R\n" +
"videoSize3\"\xb1\x01\n" +
"videoSize3\"\xb9\x01\n" +
"\x0eVideoMsgHeader\x12\x12\n" +
"\x04flag\x18\x01 \x01(\fR\x04flag\x12\x15\n" +
"\x06msg_id\x18\x02 \x01(\x03R\x05msgId\x12!\n" +
"\fclient_proof\x18\x03 \x01(\fR\vclientProof\x12\x1a\n" +
"\bunknown4\x18\x04 \x01(\x03R\bunknown4\x12\x19\n" +
"\bsys_info\x18\x05 \x01(\fR\asysInfo\x12\x1a\n" +
"\bunknown6\x18\x06 \x01(\x05R\bunknown6\"?\n" +
"\x04flag\x18\x01 \x01(\fR\x04flag\x12\x1d\n" +
"\n" +
"session_id\x18\x02 \x01(\x03R\tsessionId\x12!\n" +
"\fclient_proof\x18\x03 \x01(\fR\vclientProof\x12\x1b\n" +
"\tdevice_id\x18\x04 \x01(\x03R\bdeviceId\x12\x1a\n" +
"\bplatform\x18\x05 \x01(\fR\bplatform\x12\x18\n" +
"\aversion\x18\x06 \x01(\x05R\aversion\"?\n" +
"\rVideoMsgExtra\x12\x16\n" +
"\x06field1\x18\x01 \x01(\x05R\x06field1\x12\x16\n" +
"\x06field2\x18\x02 \x01(\fR\x06field2B>Z<github.com/yincongcyincong/weixin-macos/onebot/proto/wxprotob\x06proto3"
"\x06field2\x18\x02 \x01(\fR\x06field2B>Z<github.com/yincongcyincong/weixin-macos/onebot/proto;wxprotob\x06proto3"
var (
file_proto_wxproto_video_msg_proto_rawDescOnce sync.Once
file_proto_wxproto_video_msg_proto_rawDescData []byte
file_video_msg_proto_rawDescOnce sync.Once
file_video_msg_proto_rawDescData []byte
)
func file_proto_wxproto_video_msg_proto_rawDescGZIP() []byte {
file_proto_wxproto_video_msg_proto_rawDescOnce.Do(func() {
file_proto_wxproto_video_msg_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_proto_wxproto_video_msg_proto_rawDesc), len(file_proto_wxproto_video_msg_proto_rawDesc)))
func file_video_msg_proto_rawDescGZIP() []byte {
file_video_msg_proto_rawDescOnce.Do(func() {
file_video_msg_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_video_msg_proto_rawDesc), len(file_video_msg_proto_rawDesc)))
})
return file_proto_wxproto_video_msg_proto_rawDescData
return file_video_msg_proto_rawDescData
}
var file_proto_wxproto_video_msg_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
var file_proto_wxproto_video_msg_proto_goTypes = []any{
var file_video_msg_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
var file_video_msg_proto_goTypes = []any{
(*WxSendVideoMsg)(nil), // 0: wxproto.WxSendVideoMsg
(*VideoMsgHeader)(nil), // 1: wxproto.VideoMsgHeader
(*VideoMsgExtra)(nil), // 2: wxproto.VideoMsgExtra
}
var file_proto_wxproto_video_msg_proto_depIdxs = []int32{
var file_video_msg_proto_depIdxs = []int32{
1, // 0: wxproto.WxSendVideoMsg.header:type_name -> wxproto.VideoMsgHeader
2, // 1: wxproto.WxSendVideoMsg.unknown7:type_name -> wxproto.VideoMsgExtra
2, // 2: wxproto.WxSendVideoMsg.unknown10:type_name -> wxproto.VideoMsgExtra
@@ -517,26 +518,26 @@ var file_proto_wxproto_video_msg_proto_depIdxs = []int32{
0, // [0:3] is the sub-list for field type_name
}
func init() { file_proto_wxproto_video_msg_proto_init() }
func file_proto_wxproto_video_msg_proto_init() {
if File_proto_wxproto_video_msg_proto != nil {
func init() { file_video_msg_proto_init() }
func file_video_msg_proto_init() {
if File_video_msg_proto != nil {
return
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: unsafe.Slice(unsafe.StringData(file_proto_wxproto_video_msg_proto_rawDesc), len(file_proto_wxproto_video_msg_proto_rawDesc)),
RawDescriptor: unsafe.Slice(unsafe.StringData(file_video_msg_proto_rawDesc), len(file_video_msg_proto_rawDesc)),
NumEnums: 0,
NumMessages: 3,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_proto_wxproto_video_msg_proto_goTypes,
DependencyIndexes: file_proto_wxproto_video_msg_proto_depIdxs,
MessageInfos: file_proto_wxproto_video_msg_proto_msgTypes,
GoTypes: file_video_msg_proto_goTypes,
DependencyIndexes: file_video_msg_proto_depIdxs,
MessageInfos: file_video_msg_proto_msgTypes,
}.Build()
File_proto_wxproto_video_msg_proto = out.File
file_proto_wxproto_video_msg_proto_goTypes = nil
file_proto_wxproto_video_msg_proto_depIdxs = nil
File_video_msg_proto = out.File
file_video_msg_proto_goTypes = nil
file_video_msg_proto_depIdxs = nil
}
@@ -2,7 +2,7 @@ syntax = "proto3";
package wxproto;
option go_package = "github.com/yincongcyincong/weixin-macos/onebot/proto/wxproto";
option go_package = "github.com/yincongcyincong/weixin-macos/onebot/proto;wxproto";
// protobuf结构
message WxSendVideoMsg {
@@ -43,11 +43,11 @@ message WxSendVideoMsg {
message VideoMsgHeader {
bytes flag = 1;
int64 msg_id = 2;
int64 session_id = 2;
bytes client_proof = 3;
int64 unknown4 = 4;
bytes sys_info = 5;
int32 unknown6 = 6;
int64 device_id = 4;
bytes platform = 5;
int32 version = 6;
}
message VideoMsgExtra {
@@ -2,7 +2,7 @@
// versions:
// protoc-gen-go v1.36.11
// protoc v3.5.1
// source: proto/wxproto/wx_msg.proto
// source: wx_msg.proto
package wxproto
@@ -32,7 +32,7 @@ type WxRecvMsg struct {
func (x *WxRecvMsg) Reset() {
*x = WxRecvMsg{}
mi := &file_proto_wxproto_wx_msg_proto_msgTypes[0]
mi := &file_wx_msg_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -44,7 +44,7 @@ func (x *WxRecvMsg) String() string {
func (*WxRecvMsg) ProtoMessage() {}
func (x *WxRecvMsg) ProtoReflect() protoreflect.Message {
mi := &file_proto_wxproto_wx_msg_proto_msgTypes[0]
mi := &file_wx_msg_proto_msgTypes[0]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -57,7 +57,7 @@ func (x *WxRecvMsg) ProtoReflect() protoreflect.Message {
// Deprecated: Use WxRecvMsg.ProtoReflect.Descriptor instead.
func (*WxRecvMsg) Descriptor() ([]byte, []int) {
return file_proto_wxproto_wx_msg_proto_rawDescGZIP(), []int{0}
return file_wx_msg_proto_rawDescGZIP(), []int{0}
}
func (x *WxRecvMsg) GetRecvType() int32 {
@@ -85,7 +85,7 @@ type WxRecvMsgWrapper struct {
func (x *WxRecvMsgWrapper) Reset() {
*x = WxRecvMsgWrapper{}
mi := &file_proto_wxproto_wx_msg_proto_msgTypes[1]
mi := &file_wx_msg_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -97,7 +97,7 @@ func (x *WxRecvMsgWrapper) String() string {
func (*WxRecvMsgWrapper) ProtoMessage() {}
func (x *WxRecvMsgWrapper) ProtoReflect() protoreflect.Message {
mi := &file_proto_wxproto_wx_msg_proto_msgTypes[1]
mi := &file_wx_msg_proto_msgTypes[1]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -110,7 +110,7 @@ func (x *WxRecvMsgWrapper) ProtoReflect() protoreflect.Message {
// Deprecated: Use WxRecvMsgWrapper.ProtoReflect.Descriptor instead.
func (*WxRecvMsgWrapper) Descriptor() ([]byte, []int) {
return file_proto_wxproto_wx_msg_proto_rawDescGZIP(), []int{1}
return file_wx_msg_proto_rawDescGZIP(), []int{1}
}
func (x *WxRecvMsgWrapper) GetMsgType() int32 {
@@ -138,7 +138,7 @@ type WxRecvMsgBody struct {
func (x *WxRecvMsgBody) Reset() {
*x = WxRecvMsgBody{}
mi := &file_proto_wxproto_wx_msg_proto_msgTypes[2]
mi := &file_wx_msg_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -150,7 +150,7 @@ func (x *WxRecvMsgBody) String() string {
func (*WxRecvMsgBody) ProtoMessage() {}
func (x *WxRecvMsgBody) ProtoReflect() protoreflect.Message {
mi := &file_proto_wxproto_wx_msg_proto_msgTypes[2]
mi := &file_wx_msg_proto_msgTypes[2]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -163,7 +163,7 @@ func (x *WxRecvMsgBody) ProtoReflect() protoreflect.Message {
// Deprecated: Use WxRecvMsgBody.ProtoReflect.Descriptor instead.
func (*WxRecvMsgBody) Descriptor() ([]byte, []int) {
return file_proto_wxproto_wx_msg_proto_rawDescGZIP(), []int{2}
return file_wx_msg_proto_rawDescGZIP(), []int{2}
}
func (x *WxRecvMsgBody) GetMsgType() int32 {
@@ -191,7 +191,7 @@ type WxRecvMsgContent struct {
func (x *WxRecvMsgContent) Reset() {
*x = WxRecvMsgContent{}
mi := &file_proto_wxproto_wx_msg_proto_msgTypes[3]
mi := &file_wx_msg_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -203,7 +203,7 @@ func (x *WxRecvMsgContent) String() string {
func (*WxRecvMsgContent) ProtoMessage() {}
func (x *WxRecvMsgContent) ProtoReflect() protoreflect.Message {
mi := &file_proto_wxproto_wx_msg_proto_msgTypes[3]
mi := &file_wx_msg_proto_msgTypes[3]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -216,7 +216,7 @@ func (x *WxRecvMsgContent) ProtoReflect() protoreflect.Message {
// Deprecated: Use WxRecvMsgContent.ProtoReflect.Descriptor instead.
func (*WxRecvMsgContent) Descriptor() ([]byte, []int) {
return file_proto_wxproto_wx_msg_proto_rawDescGZIP(), []int{3}
return file_wx_msg_proto_rawDescGZIP(), []int{3}
}
func (x *WxRecvMsgContent) GetDataLen() int32 {
@@ -257,7 +257,7 @@ type WxRecvMsgData struct {
func (x *WxRecvMsgData) Reset() {
*x = WxRecvMsgData{}
mi := &file_proto_wxproto_wx_msg_proto_msgTypes[4]
mi := &file_wx_msg_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -269,7 +269,7 @@ func (x *WxRecvMsgData) String() string {
func (*WxRecvMsgData) ProtoMessage() {}
func (x *WxRecvMsgData) ProtoReflect() protoreflect.Message {
mi := &file_proto_wxproto_wx_msg_proto_msgTypes[4]
mi := &file_wx_msg_proto_msgTypes[4]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -282,7 +282,7 @@ func (x *WxRecvMsgData) ProtoReflect() protoreflect.Message {
// Deprecated: Use WxRecvMsgData.ProtoReflect.Descriptor instead.
func (*WxRecvMsgData) Descriptor() ([]byte, []int) {
return file_proto_wxproto_wx_msg_proto_rawDescGZIP(), []int{4}
return file_wx_msg_proto_rawDescGZIP(), []int{4}
}
func (x *WxRecvMsgData) GetId() int64 {
@@ -400,7 +400,7 @@ type WxString struct {
func (x *WxString) Reset() {
*x = WxString{}
mi := &file_proto_wxproto_wx_msg_proto_msgTypes[5]
mi := &file_wx_msg_proto_msgTypes[5]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -412,7 +412,7 @@ func (x *WxString) String() string {
func (*WxString) ProtoMessage() {}
func (x *WxString) ProtoReflect() protoreflect.Message {
mi := &file_proto_wxproto_wx_msg_proto_msgTypes[5]
mi := &file_wx_msg_proto_msgTypes[5]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -425,7 +425,7 @@ func (x *WxString) ProtoReflect() protoreflect.Message {
// Deprecated: Use WxString.ProtoReflect.Descriptor instead.
func (*WxString) Descriptor() ([]byte, []int) {
return file_proto_wxproto_wx_msg_proto_rawDescGZIP(), []int{5}
return file_wx_msg_proto_rawDescGZIP(), []int{5}
}
func (x *WxString) GetValue() string {
@@ -435,11 +435,11 @@ func (x *WxString) GetValue() string {
return ""
}
var File_proto_wxproto_wx_msg_proto protoreflect.FileDescriptor
var File_wx_msg_proto protoreflect.FileDescriptor
const file_proto_wxproto_wx_msg_proto_rawDesc = "" +
const file_wx_msg_proto_rawDesc = "" +
"\n" +
"\x1aproto/wxproto/wx_msg.proto\x12\awxproto\"]\n" +
"\fwx_msg.proto\x12\awxproto\"]\n" +
"\tWxRecvMsg\x12\x1b\n" +
"\trecv_type\x18\x01 \x01(\x05R\brecvType\x123\n" +
"\awrapper\x18\x02 \x01(\v2\x19.wxproto.WxRecvMsgWrapperR\awrapper\"Y\n" +
@@ -471,22 +471,22 @@ const file_proto_wxproto_wx_msg_proto_rawDesc = "" +
"\textra_xml\x18\x0e \x01(\fR\bextraXml\x12\x1c\n" +
"\tunknown15\x18\x0f \x01(\x05R\tunknown15\" \n" +
"\bWxString\x12\x14\n" +
"\x05value\x18\x01 \x01(\tR\x05valueB>Z<github.com/yincongcyincong/weixin-macos/onebot/proto/wxprotob\x06proto3"
"\x05value\x18\x01 \x01(\tR\x05valueB>Z<github.com/yincongcyincong/weixin-macos/onebot/proto;wxprotob\x06proto3"
var (
file_proto_wxproto_wx_msg_proto_rawDescOnce sync.Once
file_proto_wxproto_wx_msg_proto_rawDescData []byte
file_wx_msg_proto_rawDescOnce sync.Once
file_wx_msg_proto_rawDescData []byte
)
func file_proto_wxproto_wx_msg_proto_rawDescGZIP() []byte {
file_proto_wxproto_wx_msg_proto_rawDescOnce.Do(func() {
file_proto_wxproto_wx_msg_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_proto_wxproto_wx_msg_proto_rawDesc), len(file_proto_wxproto_wx_msg_proto_rawDesc)))
func file_wx_msg_proto_rawDescGZIP() []byte {
file_wx_msg_proto_rawDescOnce.Do(func() {
file_wx_msg_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_wx_msg_proto_rawDesc), len(file_wx_msg_proto_rawDesc)))
})
return file_proto_wxproto_wx_msg_proto_rawDescData
return file_wx_msg_proto_rawDescData
}
var file_proto_wxproto_wx_msg_proto_msgTypes = make([]protoimpl.MessageInfo, 6)
var file_proto_wxproto_wx_msg_proto_goTypes = []any{
var file_wx_msg_proto_msgTypes = make([]protoimpl.MessageInfo, 6)
var file_wx_msg_proto_goTypes = []any{
(*WxRecvMsg)(nil), // 0: wxproto.WxRecvMsg
(*WxRecvMsgWrapper)(nil), // 1: wxproto.WxRecvMsgWrapper
(*WxRecvMsgBody)(nil), // 2: wxproto.WxRecvMsgBody
@@ -494,7 +494,7 @@ var file_proto_wxproto_wx_msg_proto_goTypes = []any{
(*WxRecvMsgData)(nil), // 4: wxproto.WxRecvMsgData
(*WxString)(nil), // 5: wxproto.WxString
}
var file_proto_wxproto_wx_msg_proto_depIdxs = []int32{
var file_wx_msg_proto_depIdxs = []int32{
1, // 0: wxproto.WxRecvMsg.wrapper:type_name -> wxproto.WxRecvMsgWrapper
2, // 1: wxproto.WxRecvMsgWrapper.body:type_name -> wxproto.WxRecvMsgBody
3, // 2: wxproto.WxRecvMsgBody.content:type_name -> wxproto.WxRecvMsgContent
@@ -509,26 +509,26 @@ var file_proto_wxproto_wx_msg_proto_depIdxs = []int32{
0, // [0:7] is the sub-list for field type_name
}
func init() { file_proto_wxproto_wx_msg_proto_init() }
func file_proto_wxproto_wx_msg_proto_init() {
if File_proto_wxproto_wx_msg_proto != nil {
func init() { file_wx_msg_proto_init() }
func file_wx_msg_proto_init() {
if File_wx_msg_proto != nil {
return
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: unsafe.Slice(unsafe.StringData(file_proto_wxproto_wx_msg_proto_rawDesc), len(file_proto_wxproto_wx_msg_proto_rawDesc)),
RawDescriptor: unsafe.Slice(unsafe.StringData(file_wx_msg_proto_rawDesc), len(file_wx_msg_proto_rawDesc)),
NumEnums: 0,
NumMessages: 6,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_proto_wxproto_wx_msg_proto_goTypes,
DependencyIndexes: file_proto_wxproto_wx_msg_proto_depIdxs,
MessageInfos: file_proto_wxproto_wx_msg_proto_msgTypes,
GoTypes: file_wx_msg_proto_goTypes,
DependencyIndexes: file_wx_msg_proto_depIdxs,
MessageInfos: file_wx_msg_proto_msgTypes,
}.Build()
File_proto_wxproto_wx_msg_proto = out.File
file_proto_wxproto_wx_msg_proto_goTypes = nil
file_proto_wxproto_wx_msg_proto_depIdxs = nil
File_wx_msg_proto = out.File
file_wx_msg_proto_goTypes = nil
file_wx_msg_proto_depIdxs = nil
}
@@ -2,7 +2,7 @@ syntax = "proto3";
package wxproto;
option go_package = "github.com/yincongcyincong/weixin-macos/onebot/proto/wxproto";
option go_package = "github.com/yincongcyincong/weixin-macos/onebot/proto;wxproto";
//
message WxRecvMsg {
+8 -3
View File
@@ -7,7 +7,7 @@ import (
"strings"
"time"
"github.com/yincongcyincong/weixin-macos/onebot/proto/wxproto"
wxproto "github.com/yincongcyincong/weixin-macos/onebot/proto"
"google.golang.org/protobuf/proto"
)
@@ -82,11 +82,17 @@ func HandleProtobufMsg(payload map[string]interface{}) ([]byte, error) {
}
selfId := receiver
if strings.Contains(receiver, "@chatroom") {
selfId = sender
}
msgType := "private"
groupId := ""
senderUser := sender
senderNickname := ""
messages := getMessagesFromProto(content, sender, data.MediaContent)
if len(messages) == 0 {
return nil, fmt.Errorf("protobuf_msg: no messages found")
}
if strings.Contains(sender, "@chatroom") {
msgType = "group"
@@ -133,7 +139,6 @@ func HandleProtobufMsg(payload map[string]interface{}) ([]byte, error) {
}
}
myWechatId = selfId
if groupId != "" {
userID2NicknameMap.Store(groupId+"_"+senderUser, senderNickname)
}
@@ -230,7 +235,7 @@ func classifyMessage(content string, mediaContent []byte) *Message {
return &Message{Type: "face", Data: &SendRequestData{Text: content}}
case strings.HasPrefix(content, "<?xml version=\"1.0\"?><msg><videomsg"):
return &Message{Type: "video", Data: &SendRequestData{Text: content}}
case strings.HasPrefix(content, "<sysmsg") || strings.HasPrefix(content, "<?xml version=\"1.0\"?><sysmsg"):
case strings.HasPrefix(content, "<sysmsg") || strings.HasPrefix(content, "<?xml version=\"1.0\"?><sysmsg") || strings.HasPrefix(content, "<msg><op id"):
return &Message{Type: "sys", Data: &SendRequestData{Text: content}}
default:
return &Message{Type: "text", Data: &SendRequestData{Text: content}}
+24 -30
View File
@@ -8,18 +8,18 @@ import (
"google.golang.org/protobuf/proto"
"github.com/yincongcyincong/weixin-macos/onebot/proto/wxproto"
wxproto "github.com/yincongcyincong/weixin-macos/onebot/proto"
)
// BuildReplyMsgProto 构建发送回复消息的protobuf并返回hex编码的字符串
func BuildReplyMsgProto(sender, receiver string, replyInfo *ReplyInfo) (string, error) {
now := time.Now().Unix()
// 构建appmsg XML
appmsgXml := buildReplyAppmsgXml(replyInfo)
// 构建appmsg XML (需要传入自己的wxid用于fromusername)
appmsgXml := buildReplyAppmsgXml(sender, replyInfo)
// 构建客户端消息ID
clientMsgId := fmt.Sprintf("%s_%d_%d_xwechat_1", sender, now, rand.Intn(100))
// 构建客户端消息ID (使用对方的wxid,即receiver)
clientMsgId := fmt.Sprintf("%s_%d_%d_xwechat_3", receiver, now, rand.Intn(100))
// msgsource
msgsource := "<msgsource><alnode><fr>1</fr></alnode></msgsource>"
@@ -29,43 +29,41 @@ func BuildReplyMsgProto(sender, receiver string, replyInfo *ReplyInfo) (string,
unknown2 = []byte{}
unknown3 = int32(0)
msgType = int32(57)
unknown9 = int32(0)
flag = int32(1)
unknown11 = int32(0)
unknown13 = []byte{}
unknown14 = []byte{}
unknown15 = []byte{}
timestamp = uint32(now)
deviceId = generateDeviceId()
version = uint32(163)
version = uint32(161)
)
msg := &wxproto.WxSendReplyMsg{
Header: &wxproto.ReplyMsgHeader{
Flag: []byte{0x00},
Timestamp: &timestamp,
ClientProof: generateRandomBytes(16),
DeviceId: &deviceId,
SessionId: &globalSessionId,
ClientProof: globalClientProof,
DeviceId: &globalDeviceId,
Platform: proto.String("UnifiedPCMac 26 arm64"),
Version: &version,
},
Body: &wxproto.ReplyMsgBody{
Sender: &receiver,
Sender: &sender,
Unknown2: unknown2,
Unknown3: &unknown3,
Receiver: &sender,
Receiver: &receiver,
MsgType: &msgType,
Content: []byte(appmsgXml),
SendTimestamp: proto.Int64(now),
SendTimestamp: proto.Int64(now),
ClientMsgId: &clientMsgId,
Unknown9: &unknown9,
Flag: &flag,
Unknown11: &unknown11,
Msgsource: []byte(msgsource),
Unknown13: unknown13,
Unknown14: unknown14,
Unknown15: unknown15,
},
Unknown5: []byte{},
Unknown9: proto.Int32(0),
Unknown10: proto.Uint64(0),
Unknown11: proto.Int32(2),
}
data, err := proto.Marshal(msg)
@@ -73,7 +71,7 @@ func BuildReplyMsgProto(sender, receiver string, replyInfo *ReplyInfo) (string,
return "", fmt.Errorf("marshal reply proto failed: %w", err)
}
fmt.Println(fmt.Printf("0x% x\n", data))
//fmt.Println(fmt.Print(HexDump(data, 0x0000000C12334C00)))
return hex.EncodeToString(data), nil
}
@@ -91,7 +89,7 @@ type ReplyInfo struct {
}
// buildReplyAppmsgXml 构建回复消息的appmsg XML,字段顺序匹配微信真实protobuf
func buildReplyAppmsgXml(info *ReplyInfo) string {
func buildReplyAppmsgXml(selfWxid string, info *ReplyInfo) string {
// 时间戳:毫秒转秒
createTime := info.CreateTime / 1000
@@ -128,14 +126,14 @@ func buildReplyAppmsgXml(info *ReplyInfo) string {
xml += `<type>` + fmt.Sprintf("%d", info.MsgType) + `</type>`
xml += `<createtime>` + fmt.Sprintf("%d", createTime) + `</createtime>`
xml += `<msgsource>` + escapeXmlStr(info.Msgsource) + `</msgsource>`
xml += `<displayname>` + escapeXmlStr(info.DisplayName) + `</displayname>`
xml += `<displayname></displayname>`
xml += `<svrid>` + escapeXmlStr(info.MsgId) + `</svrid>`
xml += `<fromusr>` + escapeXmlStr(info.MsgSender) + `</fromusr>`
xml += `<content>` + escapeXmlStr(info.MsgContent) + `</content>`
xml += `</refermsg>`
xml += `</appmsg>`
xml += `<fromusername>` + escapeXmlStr(info.MsgSender) + `</fromusername>`
xml += `<fromusername>` + escapeXmlStr(selfWxid) + `</fromusername>`
return xml
}
@@ -162,16 +160,12 @@ func escapeXmlStr(s string) string {
return result
}
// generateRandomBytes 生成随机字节
func generateRandomBytes(n int) []byte {
// generateClientProof 生成n字节可见字符(模拟微信的client_proof格式)
func generateClientProof(n int) []byte {
const chars = "0123456789abcdefghijklmnopqrstuvwxyz"
b := make([]byte, n)
for i := range b {
b[i] = byte(rand.Intn(256))
b[i] = chars[rand.Intn(len(chars))]
}
return b
}
// generateDeviceId 动态生成设备ID (大整数,高位置1模拟真实设备)
func generateDeviceId() uint64 {
return rand.Uint64() | (0xFFFFFFFF << 32)
}
+45
View File
@@ -0,0 +1,45 @@
package main
import (
"fmt"
"google.golang.org/protobuf/proto"
wxproto "github.com/yincongcyincong/weixin-macos/onebot/proto"
)
// ParseSendMsgResponse 解析发送消息响应,提取 BaseResponse 中的错误码
// 不同消息类型的响应格式不同:
// - text/video/image/file/reply: BaseResponse 在 field 1 → SendMsgResponse
// - voice: BaseResponse 在 field 10 → SendVoiceMsgResponse
//
// 返回 (ret, errMsg, error)
// 如果两种格式都无法提取到有效的 BaseResponse,返回 ret=0 视为成功
func ParseSendMsgResponse(data []byte) (int32, string, error) {
// 尝试格式1: BaseResponse 在 field 1 (text/video/image/file/reply)
resp1 := &wxproto.SendMsgResponse{}
if err := proto.Unmarshal(data, resp1); err == nil {
if resp1.BaseResponse != nil && resp1.BaseResponse.Ret != nil {
errMsg := ""
if resp1.BaseResponse.ErrMsg != nil {
errMsg = resp1.BaseResponse.ErrMsg.GetMsg()
}
return *resp1.BaseResponse.Ret, errMsg, nil
}
}
// 尝试格式2: BaseResponse 在 field 10 (voice)
resp2 := &wxproto.SendVoiceMsgResponse{}
if err := proto.Unmarshal(data, resp2); err == nil {
if resp2.BaseResponse != nil && resp2.BaseResponse.Ret != nil {
errMsg := ""
if resp2.BaseResponse.ErrMsg != nil {
errMsg = resp2.BaseResponse.ErrMsg.GetMsg()
}
return *resp2.BaseResponse.Ret, errMsg, nil
}
}
// 两种格式都未提取到 BaseResponse,视为成功
return 0, "", fmt.Errorf("unable to extract BaseResponse from response")
}
+511 -600
View File
File diff suppressed because it is too large Load Diff
+20 -3
View File
@@ -7,7 +7,7 @@ import (
"math/rand"
"time"
"github.com/yincongcyincong/weixin-macos/onebot/proto/wxproto"
wxproto "github.com/yincongcyincong/weixin-macos/onebot/proto"
"google.golang.org/protobuf/proto"
)
@@ -18,7 +18,7 @@ func BuildTextMsgProto(receiver, content, atUser string) (string, error) {
if atUser != "" {
xmlStr += "<atuserlist>" + atUser + "</atuserlist>"
}
xmlStr += "<alnode><fr>1</fr></alnode></msgsource>\x00"
xmlStr += "<alnode><fr>1</fr></alnode></msgsource>"
// 生成随机消息ID
msgId := rand.Int63n(1<<34) | (1 << 34)
@@ -40,6 +40,8 @@ func BuildTextMsgProto(receiver, content, atUser string) (string, error) {
return "", fmt.Errorf("marshal text proto failed: %w", err)
}
//fmt.Printf("[text-proto] final protobuf hex dump:\n%s\n", HexDump(data, 0))
return hex.EncodeToString(data), nil
}
@@ -127,7 +129,22 @@ func BuildSendPayload(taskId int64, msgType string) string {
case "reply":
payloadData[0] = 0x6E
payloadData[16] = 0x10
payloadData[28] = 0x22
payloadData[28] = 0x20
payloadData[92] = 0x6E
case "file":
payloadData[0] = 0x6E
payloadData[16] = 0x10
payloadData[28] = 0x20
payloadData[92] = 0x6E
case "fileupload":
payloadData[0] = 0x6E
payloadData[16] = 0x10
payloadData[28] = 0x27
payloadData[92] = 0x6E
case "voice":
payloadData[0] = 0x6E
payloadData[16] = 0x10
payloadData[28] = 0x21
payloadData[92] = 0x6E
}
+7 -5
View File
@@ -1,13 +1,15 @@
package main
import "encoding/hex"
import (
"encoding/hex"
)
// BuildUploadPayload 构建上传图片/视频的payload模板,返回hex编码字符串
// uploadType: "img", "video"
// BuildUploadPayload 构建上传图片/视频/语音的payload模板,返回hex编码字符串
// uploadType: "img", "video", "voice"
// JS侧会在固定偏移写入运行时指针: 0x00, 0x08, 0x48, 0x68(receiver), 0xa8, 0xe8, 0x118, 0x148, 0x200
func BuildUploadPayload(uploadType string) string {
// 公共部分 (760字节 = 0x2F8),以img为基准
// 差异字节: [0x9C] img=0x01/video=0x04, [0x1BC-0x1BF] img=AAAAAAAA/video=01000000
// 差异字节: [0x9C] img=0x01/video=0x04/voice=0x0F, [0x1BC-0x1BF] img=AAAAAAAA/video=01000000/voice=07000000
payload := []byte{
0x20, 0x05, 0x33, 0x8C, 0x0B, 0x00, 0x00, 0x00, // 0x00 (被uploadFunc1Addr覆盖)
0x00, 0x05, 0x33, 0x8C, 0x0B, 0x00, 0x00, 0x00, // 0x08 (被uploadFunc2Addr覆盖)
@@ -18,7 +20,7 @@ func BuildUploadPayload(uploadType string) string {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x30
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x38
0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, // 0x40
0xD0, 0x72, 0x20, 0x89, 0x0B, 0x00, 0x00, 0x00, // 0x48 (被imageIdAddr/videoIdAddr覆盖)
0xD0, 0x72, 0x20, 0x89, 0x0B, 0x00, 0x00, 0x00, // 0x48 (被imageIdAddr/videoIdAddr/voiceIdAddr覆盖)
0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x50
0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, // 0x58
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x60
+62
View File
@@ -98,6 +98,15 @@ func GetFileMD5(filePath string) (string, error) {
return hex.EncodeToString(hash.Sum(nil)), nil
}
// FileToBase64 读取文件并返回 base64 编码字符串
func FileToBase64(filePath string) (string, error) {
data, err := os.ReadFile(filePath)
if err != nil {
return "", fmt.Errorf("read file failed: %v", err)
}
return base64.StdEncoding.EncodeToString(data), nil
}
func SaveAudioFile(silkBytes []byte) (path string, err error) {
mp3Bytes, err := SilkToMp3(silkBytes)
if err != nil {
@@ -222,6 +231,22 @@ func DetectFileFormat(data []byte) string {
case bytes.HasPrefix(data, []byte("7z\xBC\xAF\x27\x1C")):
return "7z"
// 音频格式
case data[0] == 0x02 && bytes.HasPrefix(data[1:], []byte("#!SILK")):
return "silk"
case bytes.HasPrefix(data, []byte("#!SILK")):
return "silk"
case bytes.HasPrefix(data, []byte("RIFF")) && len(data) > 8 && bytes.HasPrefix(data[8:], []byte("WAVE")):
return "wav"
case bytes.HasPrefix(data, []byte{0xFF, 0xFB}) || bytes.HasPrefix(data, []byte{0xFF, 0xF3}) || bytes.HasPrefix(data, []byte{0xFF, 0xF2}):
return "mp3"
case bytes.HasPrefix(data, []byte("ID3")):
return "mp3"
case bytes.HasPrefix(data, []byte("OggS")):
return "ogg"
case bytes.HasPrefix(data, []byte("fLaC")):
return "flac"
default:
return "unknown"
}
@@ -419,3 +444,40 @@ func cleanAndReattach() {
// 重新等待微信进程并 attach
attachWechat()
}
// HexDump formats data like:
// 0000000C12334C00 0A 40 0A 01 00 10 C6 BC 90 B9 08 1A 10 6D 36 34 .@....Ƽ.....m64
func HexDump(data []byte, baseAddr uint64) string {
var sb strings.Builder
for i := 0; i < len(data); i += 16 {
// Address
sb.WriteString(fmt.Sprintf("%016X ", baseAddr+uint64(i)))
// Hex bytes
for j := 0; j < 16; j++ {
if j == 8 {
sb.WriteByte(' ')
}
if i+j < len(data) {
sb.WriteString(fmt.Sprintf("%02X ", data[i+j]))
} else {
sb.WriteString(" ")
}
}
// ASCII
sb.WriteByte(' ')
for j := 0; j < 16; j++ {
if i+j < len(data) {
b := data[i+j]
if b >= 0x20 && b <= 0x7E {
sb.WriteByte(b)
} else {
sb.WriteByte('.')
}
}
}
sb.WriteByte('\n')
}
return sb.String()
}
+12
View File
@@ -0,0 +1,12 @@
package main
import (
"fmt"
"testing"
)
func TestFileToBase64(t *testing.T) {
// 测试文件不存在
f, _ := FileToBase64("/Users/yincong/Desktop/2_base64.txt")
fmt.Println(f)
}
+7 -24
View File
@@ -1,34 +1,17 @@
package main
import (
"crypto/rand"
"encoding/hex"
"fmt"
mathrand "math/rand"
"strconv"
"time"
"github.com/yincongcyincong/weixin-macos/onebot/proto/wxproto"
wxproto "github.com/yincongcyincong/weixin-macos/onebot/proto"
"google.golang.org/protobuf/proto"
)
// BuildVideoMsgProto 构建发送视频消息的protobuf并返回hex编码的字符串
func BuildVideoMsgProto(sender, targetId, cdnKey, aesKey, md5Key, videoId string, duration int32, videoSize int32) (string, error) {
// 生成16字节随机client_proof
clientProof := make([]byte, 16)
const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
randBytes := make([]byte, 16)
rand.Read(randBytes)
for i := range clientProof {
clientProof[i] = chars[int(randBytes[i])%len(chars)]
}
// 生成5字节varint范围的msgId (2^28 ~ 2^35-1)
msgId := mathrand.Int63n(1<<35-1<<28) + (1 << 28)
// header.unknown4: 同图片proto
const headerUnknown4 int64 = -228321745
// client_msg_id: targetId_timestamp_160_xwechat_1
timestamp := time.Now().Unix()
clientMsgId := targetId + "_" + strconv.FormatInt(timestamp, 10) + "_160_xwechat_1"
@@ -39,11 +22,11 @@ func BuildVideoMsgProto(sender, targetId, cdnKey, aesKey, md5Key, videoId string
msg := &wxproto.WxSendVideoMsg{
Header: &wxproto.VideoMsgHeader{
Flag: []byte{0x00},
MsgId: msgId,
ClientProof: clientProof,
Unknown4: headerUnknown4,
SysInfo: []byte("UnifiedPCMac 26 arm64"),
Unknown6: 118,
SessionId: int64(globalSessionId),
ClientProof: globalClientProof,
DeviceId: int64(globalDeviceId),
Platform: []byte("UnifiedPCMac 26 arm64"),
Version: 118,
},
ClientMsgId: []byte(clientMsgId),
Sender: []byte(sender),
@@ -76,7 +59,7 @@ func BuildVideoMsgProto(sender, targetId, cdnKey, aesKey, md5Key, videoId string
Md5Key: []byte(md5Key),
VideoId: []byte(videoId),
// Unknown38: 0, // 需要手动追加
Md5Key2: []byte(md5Key),
Md5Key2: []byte(md5Key),
CdnKey3: []byte(cdnKey),
AesKey3: []byte(aesKey),
VideoSize3: videoSize,
+107 -29
View File
@@ -6,6 +6,7 @@ import (
"encoding/json"
"encoding/xml"
"errors"
"fmt"
"os"
"runtime/debug"
"sync/atomic"
@@ -19,11 +20,9 @@ func SendWorker() {
go SendWorker()
}
}()
for {
select {
case <-finishChan:
Info("收到完成信号")
case m, ok := <-msgChan:
if !ok {
Fatal("发送通道关闭")
@@ -35,28 +34,37 @@ func SendWorker() {
}
func SendWechatMsg(m *SendMsg) {
var sendErr error
defer func() {
if m.ResultChan != nil {
m.ResultChan <- sendErr
}
}()
time.Sleep(time.Duration(config.SendInterval) * time.Millisecond)
currTaskId := atomic.AddInt64(&taskId, 1)
Info("📩 收到任务", "task_id", currTaskId, "type", m.Type)
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
defer cancel()
targetId := m.UserId
if m.GroupID != "" {
targetId = m.GroupID
}
if targetId == "" {
Error("目标为空", "task_id", currTaskId, "target_id", targetId)
sendErr = errors.New("target is empty")
return
}
switch m.Type {
case "text":
protoHex, err := BuildTextMsgProto(targetId, m.Content, m.AtUser)
if err != nil {
Error("构建文本protobuf失败", "err", err)
sendErr = err
return
}
payloadHex := BuildSendPayload(currTaskId, "text")
@@ -64,39 +72,50 @@ func SendWechatMsg(m *SendMsg) {
Info("📩 发送文本任务执行结果", "result", result, "task_id", currTaskId, "target_id", targetId, "at_user", m.AtUser)
if result != "1" {
Error("发送文本失败", "task_id", currTaskId, "target_id", targetId, "result", result)
sendErr = errors.New("send text failed")
return
}
case "image":
targetPath, md5Str, err := SaveBase64Image(m.Content)
if err != nil {
Error("保存图片失败", "err", err)
sendErr = err
return
}
uploadPayloadHex := BuildUploadPayload("img")
result := fridaScript.ExportsCall("triggerUploadImg", targetId, md5Str, targetPath, uploadPayloadHex)
Info("📩 上传图片任务执行结果", "result", result, "target_id", targetId, "md5", md5Str, "path", targetPath)
if result != "0" {
Error("上传图片失败", "target_id", targetId, "md5", md5Str, "result", result)
sendErr = errors.New("upload image failed")
return
}
if m.ResultChan != nil {
pendingResultMap.Store(targetId, m.ResultChan)
m.ResultChan = nil // 不让 defer 发送结果
}
return
case "send_image":
protoHex, err := BuildImgMsgProto(myWechatId, targetId, m.CdnKey, m.AesKey, m.Md5Key)
if err != nil {
Error("构建图片protobuf失败", "err", err)
sendErr = err
return
}
payloadHex := BuildSendPayload(currTaskId, "img")
result := fridaScript.ExportsCall("triggerSendImgMessage", currTaskId, myWechatId, targetId, protoHex, payloadHex)
Info("📩 发送图片任务执行结果", "result", result, "task_id", currTaskId, "wechat_id", myWechatId, "target_id", targetId)
if result != "1" {
Error("上传图片失败", "task_id", currTaskId, "target_id", targetId, "result", result)
Error("发送图片失败", "task_id", currTaskId, "target_id", targetId, "result", result)
sendErr = errors.New("send image failed")
return
}
case "video":
targetPath, md5Str, err := SaveBase64Image(m.Content)
if err != nil {
Error("保存图片失败", "err", err)
sendErr = err
return
}
@@ -118,8 +137,14 @@ func SendWechatMsg(m *SendMsg) {
Info("📩 上传视频任务执行结果", "result", result, "target_id", targetId, "md5", md5Str, "path", targetPath, "duration", info.Duration, "size", info.VideoSize)
if result != "0" {
Error("上传视频失败", "target_id", targetId, "md5", md5Str, "result", result)
sendErr = errors.New("upload video failed")
return
}
if m.ResultChan != nil {
pendingResultMap.Store(targetId, m.ResultChan)
m.ResultChan = nil
}
return
case "send_video":
var duration, videoSize int32
if info, ok := videoInfoMap.LoadAndDelete(targetId); ok {
@@ -130,6 +155,7 @@ func SendWechatMsg(m *SendMsg) {
protoHex, err := BuildVideoMsgProto(myWechatId, targetId, m.CdnKey, m.AesKey, m.Md5Key, m.VideoId, duration, videoSize)
if err != nil {
Error("构建视频protobuf失败", "err", err)
sendErr = err
return
}
payloadHex := BuildSendPayload(currTaskId, "video")
@@ -137,6 +163,7 @@ func SendWechatMsg(m *SendMsg) {
Info("📩 发送视频任务执行结果", "result", result, "task_id", currTaskId, "wechat_id", myWechatId, "target_id", targetId, "duration", duration, "size", videoSize)
if result != "1" {
Error("发送视频失败", "task_id", currTaskId, "target_id", targetId, "result", result)
sendErr = errors.New("send video failed")
return
}
case "download":
@@ -156,6 +183,7 @@ func SendWechatMsg(m *SendMsg) {
protoHex, err := BuildReplyMsgProto(myWechatId, targetId, replyInfo)
if err != nil {
Error("构建回复protobuf失败", "err", err)
sendErr = err
return
}
payloadHex := BuildSendPayload(currTaskId, "reply")
@@ -163,15 +191,22 @@ func SendWechatMsg(m *SendMsg) {
Info("📩 发送回复任务执行结果", "result", result, "task_id", currTaskId, "wechat_id", myWechatId, "target_id", targetId)
if result != "1" {
Error("发送回复失败", "task_id", currTaskId, "target_id", targetId, "result", result)
sendErr = errors.New("send reply failed")
return
}
}
select {
case <-ctx.Done():
Error("任务执行超时!", "taskId", currTaskId)
case <-finishChan:
Info("收到完成信号,任务完成", "taskId", currTaskId)
sendErr = errors.New("send timeout")
case resp := <-buf2RespChan:
if resp.Err != nil {
Error("收到buf2resp失败信号", "taskId", currTaskId, "msg_type", resp.MsgType, "err", resp.Err)
sendErr = resp.Err
return
}
Info("收到buf2resp完成信号,任务完成", "taskId", currTaskId, "msg_type", resp.MsgType, "data_len", len(resp.Data))
}
}
@@ -182,11 +217,14 @@ func HandleMsg(jsonData []byte) ([]byte, error) {
Error("解析消息失败", "err", err)
return nil, err
}
myWechatId = m.SelfID
if myWechatId == "" && m.SelfID != "" {
myWechatId = m.SelfID
}
if m.GroupId != "" {
userID2NicknameMap.Store(m.GroupId+"_"+m.UserID, m.Sender.Nickname)
}
for _, msg := range m.Message {
switch msg.Type {
case "record":
@@ -204,15 +242,15 @@ func HandleMsg(jsonData []byte) ([]byte, error) {
Error("XML解析失败", "err", err)
return nil, err
}
path, err := GetDownloadPath(fileMsg.Image.MidImgURL, fileMsg.Image.AesKey)
if err != nil {
Error("获取文件路径失败", "err", err)
return nil, err
}
msg.Data.URL = "file://" + path
case "file":
var fileMsg FileMsg
err = xml.Unmarshal([]byte(msg.Data.Text), &fileMsg)
@@ -225,7 +263,7 @@ func HandleMsg(jsonData []byte) ([]byte, error) {
Error("获取文件路径失败", "err", err)
return nil, err
}
msg.Data.URL = "file://" + path
case "video":
var fileMsg FileMsg
@@ -239,7 +277,7 @@ func HandleMsg(jsonData []byte) ([]byte, error) {
Error("获取文件路径失败", "err", err)
return nil, err
}
msg.Data.URL = "file://" + path
case "face":
var fileMsg FileMsg
@@ -249,8 +287,11 @@ func HandleMsg(jsonData []byte) ([]byte, error) {
return nil, err
}
// 优先thumburl,为空则用externurl
emojiUrl := fileMsg.Emoji.ThumbUrl
// 优先cdnurl,为空则用thumburl为空则用externurl
emojiUrl := fileMsg.Emoji.CdnUrl
if emojiUrl == "" {
emojiUrl = fileMsg.Emoji.ThumbUrl
}
if emojiUrl == "" {
emojiUrl = fileMsg.Emoji.ExternUrl
}
@@ -260,13 +301,13 @@ func HandleMsg(jsonData []byte) ([]byte, error) {
Error("下载表情失败", "err", err)
return nil, err
}
path, err := DetectAndSaveImage(data)
if err != nil {
Error("保存表情失败", "err", err)
return nil, err
}
msg.Data.URL = "file://" + path
}
}
@@ -280,17 +321,17 @@ func GetDownloadPath(cdnUrl, aesKeyStr string) (string, error) {
if downloadReq.FilePath != "" {
return downloadReq.FilePath, nil
}
// 检查数据是否还在接收中
timeSinceLastAppend := time.Now().UnixMilli() - downloadReq.LastAppendTime
Info("文件等待下载", "url", cdnUrl, "times", i, "last_append_time", timeSinceLastAppend)
// 如果数据仍在接收中(1秒内有新数据),继续等待
if timeSinceLastAppend < 1000 && i < 9 {
time.Sleep(2 * time.Second)
continue
}
// 数据接收完成,尝试解密
if len(downloadReq.Media) > 0 {
aesKey, err := hex.DecodeString(aesKeyStr)
@@ -304,15 +345,52 @@ func GetDownloadPath(cdnUrl, aesKeyStr string) (string, error) {
userID2FileMsgMap.Delete(cdnUrl)
return "", err
}
downloadReq.FilePath = filePath
downloadReq.Media = nil
return filePath, nil
}
}
time.Sleep(2 * time.Second)
}
return "", errors.New("文件下载超时或数据为空")
}
// HandleBuf2Resp 处理所有消息类型的buf2resp响应
func HandleBuf2Resp(msgType string, data []byte) {
Info("收到buf2resp响应", "msg_type", msgType, "data_len", len(data))
if len(data) == 0 {
Error("buf2resp响应数据为空", "msg_type", msgType)
buf2RespChan <- &Buf2RespData{
MsgType: msgType,
Data: data,
Err: errors.New("response data is empty"),
}
return
}
ret, errMsg, err := ParseSendMsgResponse(data)
if err != nil {
Info("buf2resp响应无法提取错误码,视为成功", "msg_type", msgType, "err", err)
}
// 判断错误码是否为0
if ret != 0 {
Error("buf2resp响应错误", "msg_type", msgType, "ret", ret, "errMsg", errMsg)
buf2RespChan <- &Buf2RespData{
MsgType: msgType,
Data: data,
Err: fmt.Errorf("response error, ret=%d, errMsg=%s", ret, errMsg),
}
return
}
Info("buf2resp响应成功", "msg_type", msgType)
buf2RespChan <- &Buf2RespData{
MsgType: msgType,
Data: data,
}
}
+26
View File
@@ -0,0 +1,26 @@
{
"textCallbackFuncAddr": "0x268a554",
"sendMessageCallbackFunc": "0x8c61290",
"sendFuncAddr": "0x4be3a84",
"req2bufEnterAddr": "0x39e5fb4",
"req2bufExitAddr": "0x39e70c8",
"imageCallbackFuncAddr": "0x2680f18",
"imgMessageCallbackFunc": "0x8c60d58",
"uploadImageAddr": "0x4d5e838",
"cndOnCompleteAddr": "0x39a25e8",
"buf2RespAddr": "0x3a0b9dc",
"uploadGetCallbackWrapperAddr": "0x4d1d590",
"uploadGetCallbackWrapperFuncAddr": "0x39A1E34",
"uploadOnCompleteAddr": "0x4D1DD48",
"uploadOnCompleteFuncAddr": "0x39A3018",
"startDownloadMedia": "0x4d5f4a0",
"downloadImagAddr": "0x4e81f94",
"downloadFileAddr": "0x4e20ecc",
"downloadVideoAddr": "0x4e3acac",
"videoCallbackFuncAddr": "0x26f04c4",
"videoMessageCallbackFunc": "0x8c63b08",
"replyCallbackFuncAddr": "0x261ef64",
"replyMessageCallbackFunc": "0x8c5e418",
"voiceCallbackFuncAddr": "0x31BF70C",
"voiceMessageCallbackFunc": "0x8CA34E0"
}
+20
View File
@@ -0,0 +1,20 @@
{
"sendFuncAddr": "0x4bf1b44",
"req2bufEnterAddr": "0x39f18e0",
"req2bufExitAddr": "0x39f29f4",
"buf2RespAddr": "0x3a17308",
"blrX8Addr": "0x39F1960",
"autoBufferWriteFunc": "0x3A18970",
"uploadImageAddr": "0x4d6c8f8",
"cndOnCompleteAddr": "0x39adf14",
"uploadGetCallbackWrapperAddr": "0x4d2b650",
"uploadGetCallbackWrapperFuncAddr": "0x39AD760",
"uploadOnCompleteAddr": "0x4D2BE08",
"uploadOnCompleteFuncAddr": "0x39AE944",
"startDownloadMedia": "0x4d6d560",
"downloadImagAddr": "0x4e90054",
"downloadFileAddr": "0x4e2ef8c",
"downloadVideoAddr": "0x4e48d6c"
}