diff --git a/client/c2c_switch.go b/client/c2c_switch.go new file mode 100644 index 00000000..e0fb94f4 --- /dev/null +++ b/client/c2c_switch.go @@ -0,0 +1,81 @@ +// Code generated by client/c2c_switcher.go DO NOT EDIT. + +package client + +import ( + "github.com/Mrs4s/MiraiGo/client/pb/msg" +) + +const ( + UnknownDecoder = iota + sysMsgDecoders + otherDecoders + privateMsgDecoders + nonSvcNotifyTroopSystemMsgDecoders + troopSystemMsgDecoders +) + +func peekC2CDecoder(msgType int32) (decoder func(*QQClient, *msg.Message, *incomingPacketInfo), decoderType uint8) { + switch msgType { + case 9: + return privateMessageDecoder, privateMsgDecoders + case 10: + return privateMessageDecoder, privateMsgDecoders + case 31: + return privateMessageDecoder, privateMsgDecoders + case 33: + return troopAddMemberBroadcastDecoder, otherDecoders + case 35: + return troopSystemMessageDecoder, troopSystemMsgDecoders + case 36: + return troopSystemMessageDecoder, nonSvcNotifyTroopSystemMsgDecoders + case 37: + return troopSystemMessageDecoder, troopSystemMsgDecoders + case 45: + return troopSystemMessageDecoder, troopSystemMsgDecoders + case 46: + return troopSystemMessageDecoder, troopSystemMsgDecoders + case 79: + return privateMessageDecoder, privateMsgDecoders + case 84: + return troopSystemMessageDecoder, troopSystemMsgDecoders + case 85: + return troopSystemMessageDecoder, nonSvcNotifyTroopSystemMsgDecoders + case 86: + return troopSystemMessageDecoder, troopSystemMsgDecoders + case 87: + return troopSystemMessageDecoder, troopSystemMsgDecoders + case 97: + return privateMessageDecoder, privateMsgDecoders + case 120: + return privateMessageDecoder, privateMsgDecoders + case 132: + return privateMessageDecoder, privateMsgDecoders + case 133: + return privateMessageDecoder, privateMsgDecoders + case 140: + return tempSessionDecoder, privateMsgDecoders + case 141: + return tempSessionDecoder, privateMsgDecoders + case 166: + return privateMessageDecoder, privateMsgDecoders + case 167: + return privateMessageDecoder, privateMsgDecoders + case 187: + return systemMessageDecoder, sysMsgDecoders + case 188: + return systemMessageDecoder, sysMsgDecoders + case 189: + return systemMessageDecoder, sysMsgDecoders + case 190: + return systemMessageDecoder, sysMsgDecoders + case 191: + return systemMessageDecoder, sysMsgDecoders + case 208: + return privatePttDecoder, privateMsgDecoders + case 529: + return msgType0x211Decoder, otherDecoders + default: + return nil, UnknownDecoder + } +} diff --git a/client/c2c_switcher.go b/client/c2c_switcher.go new file mode 100644 index 00000000..01088f55 --- /dev/null +++ b/client/c2c_switcher.go @@ -0,0 +1,122 @@ +//go:build ignore +// +build ignore + +package main + +import ( + "bytes" + "go/ast" + "go/format" + "go/parser" + "go/token" + "os" + "sort" + "strconv" + "text/template" +) + +const codeTemplate = `// Code generated by client/c2c_switcher.go DO NOT EDIT. + +package client + +import ( +{{range .Imports}} {{.}} +{{end}} +) + +const ( + UnknownDecoder = iota +{{range .Consts}} {{.}} +{{end}} +) + +func peekC2CDecoder(msgType int32) (decoder func(*QQClient, *msg.Message, *incomingPacketInfo), decoderType uint8) { + switch msgType { +{{range .Decoders}} case {{.Id}}: + return {{.Func}}, {{.DecoderType}} +{{end}} default: + return nil, UnknownDecoder + } +}` + +type decoder struct { + Id int64 + Func string + DecoderType string +} +type DecoderSort []decoder + +func (d DecoderSort) Len() int { return len(d) } +func (d DecoderSort) Swap(i, j int) { d[i], d[j] = d[j], d[i] } +func (d DecoderSort) Less(i, j int) bool { return d[i].Id < d[j].Id } + +func main() { + type switchFile struct { + Imports []string + Consts []string + Decoders DecoderSort + } + var sf switchFile + + fset := token.NewFileSet() + astF, err := parser.ParseFile(fset, "c2c_decoders.go", nil, parser.AllErrors|parser.ParseComments) + if err != nil { + panic(err) + } + + sf.Imports = make([]string, 0, len(astF.Imports)) + for _, imp := range astF.Imports { + sf.Imports = append(sf.Imports, imp.Path.Value) + } + + sf.Consts = make([]string, 0, len(astF.Scope.Objects)) + for _, obj := range astF.Scope.Objects { + if obj.Kind != ast.Var { + panic(`unknown non-variable in "c2c_decoders.go"`) + } + value := obj.Decl.(*ast.ValueSpec) + sf.Consts = append(sf.Consts, obj.Name) + for _, value := range value.Values { + if value, ok := value.(*ast.CompositeLit); ok { + for _, kv := range value.Elts { + if kv, ok := kv.(*ast.KeyValueExpr); ok { + k := kv.Key.(*ast.BasicLit) + v := kv.Value.(*ast.Ident) + sf.Decoders = append(sf.Decoders, decoder{ + Id: mustParseInt(k.Value), + Func: v.Name, + DecoderType: obj.Name, + }) + } else { + panic(`unknown key value in ` + obj.Name + ` in "c2c_decoders.go"`) + } + } + } else { + panic(`unknown non-map value in "c2c_decoders.go"`) + } + } + } + sort.Sort(sf.Decoders) + + f, _ := os.OpenFile("c2c_switch.go", os.O_WRONLY|os.O_CREATE|os.O_SYNC|os.O_TRUNC, 0o755) + tmpl, err := template.New("template").Parse(codeTemplate) + if err != nil { + panic(err) + } + buffer := &bytes.Buffer{} + err = tmpl.Execute(buffer, &sf) + if err != nil { + panic(err) + } + source, _ := format.Source(buffer.Bytes()) + f.Write(source) + f.Close() +} + +func mustParseInt(s string) int64 { + i, err := strconv.ParseInt(s, 10, 32) + if err != nil { + panic(err) + } + return i +}