mirror of
https://github.com/Mrs4s/MiraiGo.git
synced 2025-05-04 19:17:38 +08:00
Merge remote-tracking branch 'origin/master' into network
This commit is contained in:
commit
c1cbb69110
@ -3,13 +3,13 @@ package client
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"image"
|
|
||||||
"io"
|
"io"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/fumiama/imgsz"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
"github.com/Mrs4s/MiraiGo/binary"
|
"github.com/Mrs4s/MiraiGo/binary"
|
||||||
@ -76,12 +76,9 @@ func (c *QQClient) UploadGroupImage(groupCode int64, img io.ReadSeeker) (*messag
|
|||||||
return nil, errors.Wrap(err, "upload failed")
|
return nil, errors.Wrap(err, "upload failed")
|
||||||
ok:
|
ok:
|
||||||
_, _ = img.Seek(0, io.SeekStart)
|
_, _ = img.Seek(0, io.SeekStart)
|
||||||
i, _, _ := image.DecodeConfig(img)
|
i, t, _ := imgsz.DecodeSize(img)
|
||||||
var imageType int32 = 1000
|
var imageType int32 = 1000
|
||||||
_, _ = img.Seek(0, io.SeekStart)
|
if t == "gif" {
|
||||||
tmp := make([]byte, 4)
|
|
||||||
_, _ = img.Read(tmp)
|
|
||||||
if bytes.Equal(tmp, []byte{0x47, 0x49, 0x46, 0x38}) {
|
|
||||||
imageType = 2000
|
imageType = 2000
|
||||||
}
|
}
|
||||||
return message.NewGroupImage(binary.CalculateImageResourceId(fh), fh, rsp.FileId, int32(length), int32(i.Width), int32(i.Height), imageType), nil
|
return message.NewGroupImage(binary.CalculateImageResourceId(fh), fh, rsp.FileId, int32(length), int32(i.Width), int32(i.Height), imageType), nil
|
||||||
@ -129,12 +126,9 @@ func (c *QQClient) UploadGroupImageByFile(groupCode int64, path string) (*messag
|
|||||||
return nil, errors.Wrap(err, "upload failed")
|
return nil, errors.Wrap(err, "upload failed")
|
||||||
ok:
|
ok:
|
||||||
_, _ = img.Seek(0, io.SeekStart)
|
_, _ = img.Seek(0, io.SeekStart)
|
||||||
i, _, _ := image.DecodeConfig(img)
|
i, t, _ := imgsz.DecodeSize(img)
|
||||||
var imageType int32 = 1000
|
var imageType int32 = 1000
|
||||||
_, _ = img.Seek(0, io.SeekStart)
|
if t == "gif" {
|
||||||
tmp := make([]byte, 4)
|
|
||||||
_, _ = img.Read(tmp)
|
|
||||||
if bytes.Equal(tmp, []byte{0x47, 0x49, 0x46, 0x38}) {
|
|
||||||
imageType = 2000
|
imageType = 2000
|
||||||
}
|
}
|
||||||
return message.NewGroupImage(binary.CalculateImageResourceId(fh), fh, rsp.FileId, int32(length), int32(i.Width), int32(i.Height), imageType), nil
|
return message.NewGroupImage(binary.CalculateImageResourceId(fh), fh, rsp.FileId, int32(length), int32(i.Width), int32(i.Height), imageType), nil
|
||||||
|
@ -8,6 +8,7 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
@ -27,6 +28,8 @@ type Session struct {
|
|||||||
seq int32
|
seq int32
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const highwayMaxResponseSize int32 = 1024 * 100 // 100k
|
||||||
|
|
||||||
func (s *Session) AddrLength() int {
|
func (s *Session) AddrLength() int {
|
||||||
return len(s.SsoAddr)
|
return len(s.SsoAddr)
|
||||||
}
|
}
|
||||||
@ -48,7 +51,7 @@ type Input struct {
|
|||||||
func (s *Session) Upload(addr Addr, input Input) error {
|
func (s *Session) Upload(addr Addr, input Input) error {
|
||||||
fh, length := utils.ComputeMd5AndLength(input.Body)
|
fh, length := utils.ComputeMd5AndLength(input.Body)
|
||||||
_, _ = input.Body.Seek(0, io.SeekStart)
|
_, _ = input.Body.Seek(0, io.SeekStart)
|
||||||
conn, err := net.DialTCP("tcp", nil, addr.asTcpAddr())
|
conn, err := net.DialTimeout("tcp", addr.String(), time.Second*3)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "connect error")
|
return errors.Wrap(err, "connect error")
|
||||||
}
|
}
|
||||||
@ -246,6 +249,9 @@ func readResponse(r *binary.NetworkReader) (*pb.RspDataHighwayHead, []byte, erro
|
|||||||
}
|
}
|
||||||
hl, _ := r.ReadInt32()
|
hl, _ := r.ReadInt32()
|
||||||
a2, _ := r.ReadInt32()
|
a2, _ := r.ReadInt32()
|
||||||
|
if hl > highwayMaxResponseSize || a2 > highwayMaxResponseSize {
|
||||||
|
return nil, nil, errors.Errorf("highway response invild. head size: %v body size: %v", hl, a2)
|
||||||
|
}
|
||||||
head, _ := r.ReadBytes(int(hl))
|
head, _ := r.ReadBytes(int(hl))
|
||||||
payload, _ := r.ReadBytes(int(a2))
|
payload, _ := r.ReadBytes(int(a2))
|
||||||
_, _ = r.ReadByte()
|
_, _ = r.ReadByte()
|
||||||
|
@ -67,10 +67,10 @@ func (c *QQClient) ConnectionQualityTest() *ConnectionQualityInfo {
|
|||||||
}()
|
}()
|
||||||
go func() {
|
go func() {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
res := utils.RunICMPPingLoop(&net.IPAddr{IP: c.servers[c.currServerIndex].IP}, 10)
|
res := utils.RunTCPPingLoop(c.servers[c.currServerIndex].String(), 10)
|
||||||
r.ChatServerPacketLoss = res.PacketsLoss
|
r.ChatServerPacketLoss = res.PacketsLoss
|
||||||
if c.highwaySession.AddrLength() > 0 {
|
if c.highwaySession.AddrLength() > 0 {
|
||||||
res = utils.RunICMPPingLoop(&net.IPAddr{IP: c.highwaySession.SsoAddr[0].AsNetIP()}, 10)
|
res = utils.RunTCPPingLoop(c.highwaySession.SsoAddr[0].String(), 10)
|
||||||
r.SrvServerPacketLoss = res.PacketsLoss
|
r.SrvServerPacketLoss = res.PacketsLoss
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
1
go.mod
1
go.mod
@ -4,6 +4,7 @@ go 1.17
|
|||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/RomiChan/protobuf v0.0.0-20211223055824-048df49a8956
|
github.com/RomiChan/protobuf v0.0.0-20211223055824-048df49a8956
|
||||||
|
github.com/fumiama/imgsz v0.0.2
|
||||||
github.com/klauspost/compress v1.13.6
|
github.com/klauspost/compress v1.13.6
|
||||||
github.com/pierrec/lz4/v4 v4.1.11
|
github.com/pierrec/lz4/v4 v4.1.11
|
||||||
github.com/pkg/errors v0.9.1
|
github.com/pkg/errors v0.9.1
|
||||||
|
2
go.sum
2
go.sum
@ -3,6 +3,8 @@ github.com/RomiChan/protobuf v0.0.0-20211223055824-048df49a8956/go.mod h1:CKKOWC
|
|||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/fumiama/imgsz v0.0.2 h1:fAkC0FnIscdKOXwAxlyw3EUba5NzxZdSxGaq3Uyfxak=
|
||||||
|
github.com/fumiama/imgsz v0.0.2/go.mod h1:dR71mI3I2O5u6+PCpd47M9TZptzP+39tRBcbdIkoqM4=
|
||||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc=
|
github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc=
|
||||||
|
@ -4,7 +4,7 @@ import "github.com/Mrs4s/MiraiGo/binary"
|
|||||||
|
|
||||||
func T545(imei []byte) []byte {
|
func T545(imei []byte) []byte {
|
||||||
return binary.NewWriterF(func(w *binary.Writer) {
|
return binary.NewWriterF(func(w *binary.Writer) {
|
||||||
w.WriteUInt16(0x108)
|
w.WriteUInt16(0x545)
|
||||||
w.WriteBytesShort(imei)
|
w.WriteBytesShort(imei)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -90,6 +90,14 @@ func (e *GuildImageElement) Type() ElementType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (e *GroupImageElement) Pack() (r []*msg.Elem) {
|
func (e *GroupImageElement) Pack() (r []*msg.Elem) {
|
||||||
|
// width and height are required, set 720*480 if not set
|
||||||
|
if e.Width == 0 {
|
||||||
|
e.Width = 720
|
||||||
|
}
|
||||||
|
if e.Height == 0 {
|
||||||
|
e.Height = 480
|
||||||
|
}
|
||||||
|
|
||||||
cface := &msg.CustomFace{
|
cface := &msg.CustomFace{
|
||||||
FileType: proto.Int32(66),
|
FileType: proto.Int32(66),
|
||||||
Useful: proto.Int32(1),
|
Useful: proto.Int32(1),
|
||||||
|
@ -1,73 +0,0 @@
|
|||||||
package utils
|
|
||||||
|
|
||||||
import (
|
|
||||||
"math/rand"
|
|
||||||
"net"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
"golang.org/x/net/icmp"
|
|
||||||
"golang.org/x/net/ipv4"
|
|
||||||
)
|
|
||||||
|
|
||||||
type ICMPPingResult struct {
|
|
||||||
PacketsSent int
|
|
||||||
PacketsRecv int
|
|
||||||
PacketsLoss int
|
|
||||||
Rtts []int64
|
|
||||||
}
|
|
||||||
|
|
||||||
func RunICMPPingLoop(addr *net.IPAddr, count int) *ICMPPingResult {
|
|
||||||
if count <= 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
r := &ICMPPingResult{
|
|
||||||
PacketsSent: count,
|
|
||||||
Rtts: make([]int64, count),
|
|
||||||
}
|
|
||||||
for i := 1; i <= count; i++ {
|
|
||||||
rtt, err := SendICMPRequest(addr, i)
|
|
||||||
if err != nil {
|
|
||||||
r.PacketsLoss++
|
|
||||||
r.Rtts[i-1] = 9999
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
r.PacketsRecv++
|
|
||||||
r.Rtts[i-1] = rtt
|
|
||||||
time.Sleep(time.Millisecond * 100)
|
|
||||||
}
|
|
||||||
return r
|
|
||||||
}
|
|
||||||
|
|
||||||
func SendICMPRequest(addr *net.IPAddr, seq int) (int64, error) {
|
|
||||||
data := make([]byte, 32)
|
|
||||||
rand.Read(data)
|
|
||||||
body := &icmp.Echo{
|
|
||||||
ID: 0,
|
|
||||||
Seq: seq,
|
|
||||||
Data: data,
|
|
||||||
}
|
|
||||||
msg := &icmp.Message{
|
|
||||||
Type: ipv4.ICMPTypeEcho,
|
|
||||||
Code: 0,
|
|
||||||
Body: body,
|
|
||||||
}
|
|
||||||
msgBytes, _ := msg.Marshal(nil)
|
|
||||||
conn, err := net.DialIP("ip4:icmp", nil, addr)
|
|
||||||
if err != nil {
|
|
||||||
return 0, errors.Wrap(err, "dial icmp conn error")
|
|
||||||
}
|
|
||||||
defer func() { _ = conn.Close() }()
|
|
||||||
if _, err = conn.Write(msgBytes); err != nil {
|
|
||||||
return 0, errors.Wrap(err, "write icmp packet error")
|
|
||||||
}
|
|
||||||
start := time.Now()
|
|
||||||
_ = conn.SetReadDeadline(time.Now().Add(time.Second * 2))
|
|
||||||
buff := make([]byte, 1024)
|
|
||||||
_, err = conn.Read(buff)
|
|
||||||
if err != nil {
|
|
||||||
return 0, errors.Wrap(err, "read icmp conn error")
|
|
||||||
}
|
|
||||||
duration := time.Since(start).Milliseconds()
|
|
||||||
return duration, nil
|
|
||||||
}
|
|
59
utils/tcping.go
Normal file
59
utils/tcping.go
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ICMPPingResult struct {
|
||||||
|
PacketsSent int
|
||||||
|
PacketsLoss int
|
||||||
|
AvgTimeMill int64
|
||||||
|
}
|
||||||
|
|
||||||
|
// RunTCPPingLoop 使用 tcp 进行 ping
|
||||||
|
func RunTCPPingLoop(ipport string, count int) (r ICMPPingResult) {
|
||||||
|
r = ICMPPingResult{
|
||||||
|
PacketsSent: count,
|
||||||
|
PacketsLoss: count,
|
||||||
|
AvgTimeMill: 9999,
|
||||||
|
}
|
||||||
|
if count <= 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
durs := make([]int64, 0, count)
|
||||||
|
for i := 0; i < count; i++ {
|
||||||
|
d, err := tcping(ipport)
|
||||||
|
if err == nil {
|
||||||
|
r.PacketsLoss--
|
||||||
|
durs = append(durs, d)
|
||||||
|
}
|
||||||
|
time.Sleep(time.Millisecond * 100)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(durs) > 0 {
|
||||||
|
r.AvgTimeMill = 0
|
||||||
|
for _, d := range durs {
|
||||||
|
r.AvgTimeMill += d
|
||||||
|
}
|
||||||
|
if len(durs) > 1 {
|
||||||
|
r.AvgTimeMill /= int64(len(durs))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func tcping(ipport string) (int64, error) {
|
||||||
|
t := time.Now().UnixMilli()
|
||||||
|
conn, err := net.DialTimeout("tcp", ipport, time.Second*2)
|
||||||
|
if err != nil {
|
||||||
|
if strings.Contains(err.Error(), "timeout") {
|
||||||
|
return 9999, err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_ = conn.Close()
|
||||||
|
}
|
||||||
|
return time.Now().UnixMilli() - t, nil
|
||||||
|
}
|
12
utils/tcping_test.go
Normal file
12
utils/tcping_test.go
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestPing(t *testing.T) {
|
||||||
|
r := RunTCPPingLoop("127.0.0.1:23333", 4)
|
||||||
|
if r.PacketsLoss == r.PacketsSent {
|
||||||
|
t.Fatal(r)
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user