diff --git a/game/init.go b/game/init.go index 2146e26..4c1968e 100644 --- a/game/init.go +++ b/game/init.go @@ -11,11 +11,11 @@ import ( var ( Services = &component.Components{} - roomManager = room.NewRoomManager() + RoomManager = room.NewRoomManager() ) func init() { - Services.Register(roomManager, + Services.Register(RoomManager, component.WithName("room"), component.WithNameFunc(func(s string) string { return strings.ToLower(s) diff --git a/game/msg-transfer/danmaku_consumer_handler.go b/game/msg-transfer/danmaku_consumer_handler.go new file mode 100644 index 0000000..83b0a49 --- /dev/null +++ b/game/msg-transfer/danmaku_consumer_handler.go @@ -0,0 +1,51 @@ +package msg_transfer + +import ( + "dcg/game/pb" + "dcg/pkg/kafka" + "dcg/pkg/logger" + "github.com/Shopify/sarama" + "github.com/golang/protobuf/proto" +) + +type fcb func(data []byte, msgKey string) + +type DanmakuConsumerHandler struct { + msgHandle map[string]fcb + cg *kafka.ConsumerGroup +} + +func (h *DanmakuConsumerHandler) Init() { + h.msgHandle = make(map[string]fcb) + h.msgHandle["danmaku"] = h.handleDanmaku + h.cg, _ = kafka.NewConsumerGroup(&kafka.ConsumerGroupConfig{ + KafkaVersion: sarama.V3_1_0_0, + OffsetsInitial: sarama.OffsetNewest, + IsReturnErr: false, + }, []string{"danmaku"}, []string{"danmaku"}, "") +} + +func (h *DanmakuConsumerHandler) handleDanmaku(msg []byte, msgKey string) { + logger.SLog.Debug("msg come", string(msg), msgKey) + // danmaku msg proto + var msgFromMq pb.Danmaku + err := proto.Unmarshal(msg, &msgFromMq) + if err != nil { + logger.SLog.Error("unmarshal msg err", err) + return + } + // + +} + +func (DanmakuConsumerHandler) Setup(_ sarama.ConsumerGroupSession) error { return nil } +func (DanmakuConsumerHandler) Cleanup(_ sarama.ConsumerGroupSession) error { return nil } +func (h *DanmakuConsumerHandler) ConsumeClaim(sess sarama.ConsumerGroupSession, + claim sarama.ConsumerGroupClaim) error { + for msg := range claim.Messages() { + logger.SLog.Infow("kafka get info to mysql", "msgTopic", msg.Topic, "msgPartition", msg.Partition, "msg", string(msg.Value)) + h.msgHandle[msg.Topic](msg.Value, string(msg.Key)) + sess.MarkMessage(msg, "") + } + return nil +} diff --git a/game/msg-transfer/init.go b/game/msg-transfer/init.go new file mode 100644 index 0000000..0b849e4 --- /dev/null +++ b/game/msg-transfer/init.go @@ -0,0 +1,9 @@ +package msg_transfer + +var ( +//danmakuCH +) + +func Init() { + +} \ No newline at end of file diff --git a/game/pb/broadcast.proto b/game/pb/broadcast.proto new file mode 100644 index 0000000..21b158e --- /dev/null +++ b/game/pb/broadcast.proto @@ -0,0 +1,38 @@ +syntax = "proto3"; + +package pb; + +option go_package = "/pb"; + +message User{ + int64 uId = 1;//用户id + string uname = 2;//用户名 +} + +message JoinGame{ + User user = 1; +} + +message CreateUnit{ + User user = 1; + string unit = 2;//1-步兵,2-骑兵,3-弓箭手,4-法师 +} + +message Move{ + User user = 1; + string line = 2;//1-上,2-中,3-下 +} + +message Outbreak{ + User user = 1; +} + +message Gift{ + User user = 1; + int32 giftId = 2; + int64 totalCoin = 3; +} + +message Wai{ + User user = 1; +} \ No newline at end of file diff --git a/game/pb/danmaku.pb.go b/game/pb/danmaku.pb.go new file mode 100644 index 0000000..6275b63 --- /dev/null +++ b/game/pb/danmaku.pb.go @@ -0,0 +1,150 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.27.1 +// protoc v3.19.4 +// source: danmaku.proto + +package pb + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +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) +) + +type Danmaku struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Uid int64 `protobuf:"varint,1,opt,name=uid,proto3" json:"uid,omitempty"` + Uname string `protobuf:"bytes,2,opt,name=uname,proto3" json:"uname,omitempty"` +} + +func (x *Danmaku) Reset() { + *x = Danmaku{} + if protoimpl.UnsafeEnabled { + mi := &file_danmaku_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Danmaku) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Danmaku) ProtoMessage() {} + +func (x *Danmaku) ProtoReflect() protoreflect.Message { + mi := &file_danmaku_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Danmaku.ProtoReflect.Descriptor instead. +func (*Danmaku) Descriptor() ([]byte, []int) { + return file_danmaku_proto_rawDescGZIP(), []int{0} +} + +func (x *Danmaku) GetUid() int64 { + if x != nil { + return x.Uid + } + return 0 +} + +func (x *Danmaku) GetUname() string { + if x != nil { + return x.Uname + } + return "" +} + +var File_danmaku_proto protoreflect.FileDescriptor + +var file_danmaku_proto_rawDesc = []byte{ + 0x0a, 0x0d, 0x64, 0x61, 0x6e, 0x6d, 0x61, 0x6b, 0x75, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, + 0x02, 0x70, 0x62, 0x22, 0x31, 0x0a, 0x07, 0x44, 0x61, 0x6e, 0x6d, 0x61, 0x6b, 0x75, 0x12, 0x10, + 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x03, 0x75, 0x69, 0x64, + 0x12, 0x14, 0x0a, 0x05, 0x75, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x05, 0x75, 0x6e, 0x61, 0x6d, 0x65, 0x42, 0x05, 0x5a, 0x03, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_danmaku_proto_rawDescOnce sync.Once + file_danmaku_proto_rawDescData = file_danmaku_proto_rawDesc +) + +func file_danmaku_proto_rawDescGZIP() []byte { + file_danmaku_proto_rawDescOnce.Do(func() { + file_danmaku_proto_rawDescData = protoimpl.X.CompressGZIP(file_danmaku_proto_rawDescData) + }) + return file_danmaku_proto_rawDescData +} + +var file_danmaku_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_danmaku_proto_goTypes = []interface{}{ + (*Danmaku)(nil), // 0: pb.Danmaku +} +var file_danmaku_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_danmaku_proto_init() } +func file_danmaku_proto_init() { + if File_danmaku_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_danmaku_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Danmaku); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_danmaku_proto_rawDesc, + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_danmaku_proto_goTypes, + DependencyIndexes: file_danmaku_proto_depIdxs, + MessageInfos: file_danmaku_proto_msgTypes, + }.Build() + File_danmaku_proto = out.File + file_danmaku_proto_rawDesc = nil + file_danmaku_proto_goTypes = nil + file_danmaku_proto_depIdxs = nil +} diff --git a/game/pb/danmaku.proto b/game/pb/danmaku.proto new file mode 100644 index 0000000..50778b6 --- /dev/null +++ b/game/pb/danmaku.proto @@ -0,0 +1,10 @@ +syntax = "proto3"; + +package pb; + +option go_package = "/pb"; + +message Danmaku { + int64 uid = 1; + string uname = 2; +} \ No newline at end of file diff --git a/game/pb/room.pb.go b/game/pb/room.pb.go index 0efbbcb..b731b2c 100644 --- a/game/pb/room.pb.go +++ b/game/pb/room.pb.go @@ -169,53 +169,6 @@ func (x *Client) GetId() int64 { return 0 } -type Test struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - T int64 `protobuf:"varint,1,opt,name=T,proto3" json:"T,omitempty"` -} - -func (x *Test) Reset() { - *x = Test{} - if protoimpl.UnsafeEnabled { - mi := &file_room_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Test) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Test) ProtoMessage() {} - -func (x *Test) ProtoReflect() protoreflect.Message { - mi := &file_room_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Test.ProtoReflect.Descriptor instead. -func (*Test) Descriptor() ([]byte, []int) { - return file_room_proto_rawDescGZIP(), []int{3} -} - -func (x *Test) GetT() int64 { - if x != nil { - return x.T - } - return 0 -} - var File_room_proto protoreflect.FileDescriptor var file_room_proto_rawDesc = []byte{ @@ -228,9 +181,8 @@ var file_room_proto_rawDesc = []byte{ 0x6f, 0x64, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x18, 0x0a, 0x06, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x03, 0x52, 0x02, 0x49, 0x64, 0x22, 0x14, 0x0a, 0x04, 0x54, 0x65, 0x73, 0x74, 0x12, 0x0c, 0x0a, - 0x01, 0x54, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x01, 0x54, 0x42, 0x05, 0x5a, 0x03, 0x2f, - 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x03, 0x52, 0x02, 0x49, 0x64, 0x42, 0x05, 0x5a, 0x03, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -245,12 +197,11 @@ func file_room_proto_rawDescGZIP() []byte { return file_room_proto_rawDescData } -var file_room_proto_msgTypes = make([]protoimpl.MessageInfo, 4) +var file_room_proto_msgTypes = make([]protoimpl.MessageInfo, 3) var file_room_proto_goTypes = []interface{}{ (*JoinRoomReq)(nil), // 0: pb.JoinRoomReq (*JoinRoomResp)(nil), // 1: pb.JoinRoomResp (*Client)(nil), // 2: pb.Client - (*Test)(nil), // 3: pb.Test } var file_room_proto_depIdxs = []int32{ 0, // [0:0] is the sub-list for method output_type @@ -302,18 +253,6 @@ func file_room_proto_init() { return nil } } - file_room_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Test); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } } type x struct{} out := protoimpl.TypeBuilder{ @@ -321,7 +260,7 @@ func file_room_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_room_proto_rawDesc, NumEnums: 0, - NumMessages: 4, + NumMessages: 3, NumExtensions: 0, NumServices: 0, }, diff --git a/game/pb/room.proto b/game/pb/room.proto index a856864..20e7d6f 100644 --- a/game/pb/room.proto +++ b/game/pb/room.proto @@ -15,8 +15,4 @@ message JoinRoomResp { message Client { int64 Id = 1; // 客户端ID(直播间ID) -} - -message Test { - int64 T = 1; } \ No newline at end of file diff --git a/game/room/manager.go b/game/room/manager.go index 41fef83..69efccd 100644 --- a/game/room/manager.go +++ b/game/room/manager.go @@ -2,12 +2,13 @@ package room import ( "dcg/game/pb" + "dcg/pkg/logger" "fmt" "git.noahlan.cn/northlan/ngs" "git.noahlan.cn/northlan/ngs/component" "git.noahlan.cn/northlan/ngs/scheduler" "git.noahlan.cn/northlan/ngs/session" - "log" + "github.com/golang/protobuf/proto" "time" ) @@ -15,6 +16,7 @@ const roomIDKey = "ROOM_ID" type ( Room struct { + id int64 group *ngs.Group } @@ -55,11 +57,11 @@ func (m *Manager) Shutdown() { } func (m *Manager) Join(s *session.Session, msg *pb.JoinRoomReq) error { - log.Println("join ?") room, found := m.rooms[msg.LiveRoomId] if !found { room = &Room{ - group: ngs.NewGroup(fmt.Sprintf("room-%s", msg.LiveRoomId)), + id: msg.LiveRoomId, + group: ngs.NewGroup(fmt.Sprintf("room-%d", msg.LiveRoomId)), } m.rooms[msg.LiveRoomId] = room } @@ -81,3 +83,12 @@ func (m *Manager) Join(s *session.Session, msg *pb.JoinRoomReq) error { Result: "success", }) } + +func (m *Manager) Broadcast(route string, msg proto.Message) { + for _, room := range m.rooms { + err := room.group.Broadcast(route, msg) + if err != nil { + logger.SLog.Errorf("broadcast message to room %d err:%+v", room.id, err) + } + } +} diff --git a/go.mod b/go.mod index a314f1a..ad318d1 100644 --- a/go.mod +++ b/go.mod @@ -9,10 +9,30 @@ require ( ) require ( + github.com/Shopify/sarama v1.32.0 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.1 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/eapache/go-resiliency v1.2.0 // indirect + github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21 // indirect + github.com/eapache/queue v1.1.0 // indirect github.com/golang/protobuf v1.5.2 // indirect + github.com/golang/snappy v0.0.4 // indirect github.com/gorilla/websocket v1.5.0 // indirect + github.com/hashicorp/go-uuid v1.0.3 // indirect + github.com/jcmturner/aescts/v2 v2.0.0 // indirect + github.com/jcmturner/dnsutils/v2 v2.0.0 // indirect + github.com/jcmturner/gofork v1.0.0 // indirect + github.com/jcmturner/gokrb5/v8 v8.4.2 // indirect + github.com/jcmturner/rpc/v2 v2.0.3 // indirect + github.com/klauspost/compress v1.15.1 // indirect + github.com/natefinch/lumberjack v2.0.0+incompatible // indirect + github.com/pierrec/lz4 v2.6.1+incompatible // indirect + github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect + go.uber.org/atomic v1.9.0 // indirect + go.uber.org/multierr v1.8.0 // indirect + go.uber.org/zap v1.21.0 // indirect + golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 // indirect golang.org/x/net v0.0.0-20220418201149-a630d4f3e7a2 // indirect golang.org/x/sys v0.0.0-20220412211240-33da011f77ad // indirect golang.org/x/text v0.3.7 // indirect diff --git a/go.sum b/go.sum index d26eda1..839a3de 100644 --- a/go.sum +++ b/go.sum @@ -3,7 +3,11 @@ cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT git.noahlan.cn/northlan/ngs v0.1.2 h1:0+cZIAff14VgGBqkCw5Hur9gVD6HzxTmFIvuoWvFphQ= git.noahlan.cn/northlan/ngs v0.1.2/go.mod h1:dWoj94sHXJPFE1BbCvF8hOLtMRUe0V6v7RGpGs4+iAs= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/Shopify/sarama v1.32.0 h1:P+RUjEaRU0GMMbYexGMDyrMkLhbbBVUVISDywi+IlFU= +github.com/Shopify/sarama v1.32.0/go.mod h1:+EmJJKZWVT/faR9RcOxJerP+LId4iWdQPBGLy1Y1Njs= +github.com/Shopify/toxiproxy/v2 v2.3.0/go.mod h1:KvQTtB6RjCJY4zqNJn7C7JDFgsG5uoHYDirfUfpIm0c= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= @@ -16,13 +20,24 @@ github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWH github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.1 h1:r/myEWzV9lfsM1tFLgDyu0atFtJ1fXn261LKYj/3DxU= github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= 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/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/eapache/go-resiliency v1.2.0 h1:v7g92e/KSN71Rq7vSThKaWIq68fL4YHvWyiUKorFR1Q= +github.com/eapache/go-resiliency v1.2.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= +github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21 h1:YEetp8/yCZMuEPMUDHG0CW/brkkEp8mzqk2+ODEitlw= +github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= +github.com/eapache/queue v1.1.0 h1:YOEu7KNc61ntiQlcEeUIoDTJ2o8mQznoNvUhiigpIqc= +github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= +github.com/frankban/quicktest v1.14.2/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= @@ -40,6 +55,8 @@ github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= +github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -47,37 +64,102 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= +github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= +github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/jcmturner/aescts/v2 v2.0.0 h1:9YKLH6ey7H4eDBXW8khjYslgyqG2xZikXP0EQFKrle8= +github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs= +github.com/jcmturner/dnsutils/v2 v2.0.0 h1:lltnkeZGL0wILNvrNiVCR6Ro5PGU/SeBvVO/8c/iPbo= +github.com/jcmturner/dnsutils/v2 v2.0.0/go.mod h1:b0TnjGOvI/n42bZa+hmXL+kFJZsFT7G4t3HTlQ184QM= +github.com/jcmturner/gofork v1.0.0 h1:J7uCkflzTEhUZ64xqKnkDxq3kzc96ajM1Gli5ktUem8= +github.com/jcmturner/gofork v1.0.0/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o= +github.com/jcmturner/goidentity/v6 v6.0.1/go.mod h1:X1YW3bgtvwAXju7V3LCIMpY0Gbxyjn/mY9zx4tFonSg= +github.com/jcmturner/gokrb5/v8 v8.4.2 h1:6ZIM6b/JJN0X8UM43ZOM6Z4SJzla+a/u7scXFJzodkA= +github.com/jcmturner/gokrb5/v8 v8.4.2/go.mod h1:sb+Xq/fTY5yktf/VxLsE3wlfPqQjp0aWNYyvBVK62bc= +github.com/jcmturner/rpc/v2 v2.0.3 h1:7FXXj8Ti1IaVFpSAziCZWNzbNuZmnvw/i6CqLNdWfZY= +github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc= +github.com/klauspost/compress v1.14.4/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= +github.com/klauspost/compress v1.15.1 h1:y9FcTHGyrebwfP0ZZqFiaxTaiDnUrGkJkI+f583BL1A= +github.com/klauspost/compress v1.15.1/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/natefinch/lumberjack v2.0.0+incompatible h1:4QJd3OLAMgj7ph+yZTuX13Ld4UpgHp07nNdFX7mqFfM= +github.com/natefinch/lumberjack v2.0.0+incompatible/go.mod h1:Wi9p2TTF5DG5oU+6YfsmYQpsTIOm0B1VNzQg9Mw6nPk= +github.com/pierrec/lz4 v2.6.1+incompatible h1:9UY3+iC23yxF0UfGaYrGplQ+79Rg+h/q9FV9ix19jjM= +github.com/pierrec/lz4 v2.6.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= +github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= +github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/urfave/cli v1.22.5 h1:lNq9sAHXK2qfdI8W+GRItjCEkI+2oR4d+MEHy1CKXoU= github.com/urfave/cli v1.22.5/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= +github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= +github.com/xdg-go/scram v1.1.0/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs= +github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= +go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= +go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= +go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8= +go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= +go.uber.org/zap v1.21.0 h1:WefMeulhovoZ2sYXz7st6K0sLj7bBhpiFaud4r4zST8= +go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201112155050-0c6587e931a9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 h1:kUhD7nTDoI3fVd9G4ORWrbV5NY0liEs/Jg2pv5f+bBA= +golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220418201149-a630d4f3e7a2 h1:6mzvA99KwZxbOrxww4EvWVQUnN1+xEu9tafK5ZxkYeA= golang.org/x/net v0.0.0-20220418201149-a630d4f3e7a2/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -86,19 +168,26 @@ golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad h1:ntjMns5wyP/fN65tdBD4g8J5w8n015+iIIs9rtjXkY0= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -106,6 +195,10 @@ golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -139,8 +232,14 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/pkg/kafka/consumer.go b/pkg/kafka/consumer.go new file mode 100644 index 0000000..4a42f68 --- /dev/null +++ b/pkg/kafka/consumer.go @@ -0,0 +1,41 @@ +package kafka + +import ( + "dcg/pkg/logger" + "github.com/Shopify/sarama" +) + +type Consumer struct { + client sarama.Client + topic string + consumer sarama.Consumer + partitions []int32 +} + +func NewKafkaConsumer(addr []string, topic string) (*Consumer, error) { + p := Consumer{} + p.topic = topic + + config := sarama.NewConfig() + config.Version = sarama.V3_1_0_0 + config.Consumer.Offsets.Initial = sarama.OffsetNewest + + var err error + p.client, err = sarama.NewClient(addr, config) + if err != nil { + logger.SLog.Error("new kafka client err:", err) + return nil, err + } + + p.consumer, err = sarama.NewConsumerFromClient(p.client) + if err != nil { + logger.SLog.Error("new kafka consumer err:", err) + return nil, err + } + p.partitions, err = p.consumer.Partitions(topic) + if err != nil { + logger.SLog.Errorf("get partitions for topic %s err", topic) + return nil, err + } + return &p, nil +} diff --git a/pkg/kafka/consumer_group.go b/pkg/kafka/consumer_group.go new file mode 100644 index 0000000..65ef3c6 --- /dev/null +++ b/pkg/kafka/consumer_group.go @@ -0,0 +1,47 @@ +package kafka + +import ( + "context" + "dcg/pkg/logger" + "github.com/Shopify/sarama" +) + +type ConsumerGroup struct { + sarama.ConsumerGroup + groupId string + topics []string +} + +type ConsumerGroupConfig struct { + KafkaVersion sarama.KafkaVersion + OffsetsInitial int64 + IsReturnErr bool +} + +func NewConsumerGroup(config *ConsumerGroupConfig, addr, topics []string, groupId string) (*ConsumerGroup, error) { + c := sarama.NewConfig() + c.Version = config.KafkaVersion + c.Consumer.Offsets.Initial = config.OffsetsInitial + c.Consumer.Return.Errors = config.IsReturnErr + + client, err := sarama.NewClient(addr, c) + if err != nil { + return nil, err + } + + consumerGroup, err := sarama.NewConsumerGroupFromClient(groupId, client) + if err != nil { + return nil, err + } + return &ConsumerGroup{consumerGroup, groupId, topics}, nil +} + +func (cg *ConsumerGroup) RegisterHandlerAndConsumer(handler sarama.ConsumerGroupHandler) { + ctx := context.Background() + for { + err := cg.ConsumerGroup.Consume(ctx, cg.topics, handler) + if err != nil { + logger.SLog.Error("RegisterHandlerAndConsumer error: ", err) + } + } +} diff --git a/pkg/kafka/producer.go b/pkg/kafka/producer.go new file mode 100644 index 0000000..643f2d6 --- /dev/null +++ b/pkg/kafka/producer.go @@ -0,0 +1,62 @@ +package kafka + +import ( + "dcg/pkg/logger" + "github.com/Shopify/sarama" + "google.golang.org/protobuf/proto" +) + +type Producer struct { + topic string + client sarama.Client + producer sarama.AsyncProducer +} + +func NewKafkaProducer(addr []string, topic string) *Producer { + p := Producer{} + + config := sarama.NewConfig() //Instantiate a sarama Config + config.Producer.Return.Successes = true //Whether to enable the successes channel to be notified after the message is sent successfully + config.Producer.RequiredAcks = sarama.WaitForAll //Set producer Message Reply level 0 1 all + config.Producer.Partitioner = sarama.NewHashPartitioner //Set the hash-key automatic hash partition. When sending a message, you must specify the key value of the message. If there is no key, the partition will be selected randomly + + p.topic = topic + + var err error + p.client, err = sarama.NewClient(addr, config) + if err != nil { + logger.SLog.Error("new kafka client err:", err) + return &p + } + p.producer, err = sarama.NewAsyncProducerFromClient(p.client) + if err != nil { + logger.SLog.Error("new kafka producer err:", err) + return &p + } + + go func() { + for range p.producer.Successes() { + } + }() + + return &p +} + +func (p *Producer) SendMessageAsync(m proto.Message, key ...string) error { + kMsg := &sarama.ProducerMessage{} + kMsg.Topic = p.topic + if len(key) > 0 { + kMsg.Key = sarama.StringEncoder(key[0]) + } + bMsg, err := proto.Marshal(m) + if err != nil { + logger.SLog.Error("proto marshal err:", err) + return err + } + kMsg.Value = sarama.ByteEncoder(bMsg) + + select { + case p.producer.Input() <- kMsg: + } + return nil +} diff --git a/pkg/logger/logger.go b/pkg/logger/logger.go new file mode 100644 index 0000000..5988bd3 --- /dev/null +++ b/pkg/logger/logger.go @@ -0,0 +1,180 @@ +package logger + +import ( + "github.com/natefinch/lumberjack" + "go.uber.org/zap" + "go.uber.org/zap/zapcore" + "os" + "path" + "path/filepath" + "runtime" + "strings" +) + +var Log *zap.Logger +var SLog *zap.SugaredLogger + +const DefaultLogPath = "/logs" + +type ( + // FileConfig 日志文件配置 + FileConfig struct { + Level string // 日志打印级别 debug info warning error + Format string // 输出日志格式 console, json + Enabled bool // 是否开启 + + Path string // 输出日志文件路径 + FileName string // 输出日志文件名称 + FileMaxSize int // 【日志分割】单个日志文件最多存储量 单位(mb) + FileMaxBackups int // 【日志分割】日志备份文件最多数量 + MaxAge int // 日志保留时间,单位: 天 (day) + Compress bool // 是否压缩日志 + } + + // ConsoleConfig 控制台日志配置 + ConsoleConfig struct { + Level string // 日志打印级别 debug info warning error + Format string // 输出日志格式 console, json + } +) + +var logLevel = map[string]zapcore.Level{ + "debug": zapcore.DebugLevel, + "info": zapcore.InfoLevel, + "warn": zapcore.WarnLevel, + "error": zapcore.ErrorLevel, +} + +func Sync() { + if SLog != nil { + _ = SLog.Sync() + } + if Log != nil { + _ = Log.Sync() + } +} + +// InitLogger 初始化 log +func InitLogger(fileConf *FileConfig, consoleConf *ConsoleConfig) error { + cores := make([]zapcore.Core, 0, 2) + + consoleCore := zapcore.NewCore(getEncoder(consoleConf), zapcore.AddSync(os.Stdout), getLogLevel(consoleConf.Level)) + cores = append(cores, consoleCore) + + if fileConf.Enabled { + writeSyncer, err := getLogWriter(fileConf) // 日志文件配置 文件位置和切割 + if err != nil { + return err + } + fileCore := zapcore.NewCore(getEncoder(fileConf), writeSyncer, getLogLevel(fileConf.Level)) + cores = append(cores, fileCore) + } + + // 控制台/文件 配置分离 + core := zapcore.NewTee(cores...) + + logger := zap.New(core, zap.AddCaller()) //zap.AddCaller() 输出日志打印文件和行数如: logger/logger_test.go:33 + SLog = logger.Sugar() + Log = logger + return nil +} + +// getLogLevel 获取日志打印级别 +func getLogLevel(level string) zapcore.Level { + l, ok := logLevel[level] // 日志打印级别 + if !ok { + l = logLevel["info"] + } + return l +} + +// getLogWriter 获取日志输出方式 日志文件 控制台 +func getLogWriter(conf *FileConfig) (zapcore.WriteSyncer, error) { + // 判断日志路径是否存在,如果不存在就创建 + if conf.Path == "" { + conf.Path = getCurrentAbPath() + DefaultLogPath + } + if exist := isExist(conf.Path); !exist { + if err := os.MkdirAll(conf.Path, os.ModePerm); err != nil { + conf.Path = getCurrentAbPath() + DefaultLogPath + if err := os.MkdirAll(conf.Path, os.ModePerm); err != nil { + return nil, err + } + } + } + + // 日志文件 与 日志切割 配置 + lumberJackLogger := &lumberjack.Logger{ + Filename: filepath.Join(conf.Path, conf.FileName), // 日志文件路径 + MaxSize: conf.FileMaxSize, // 单个日志文件最大多少 mb + MaxBackups: conf.FileMaxBackups, // 日志备份数量 + MaxAge: conf.MaxAge, // 日志最长保留时间 + Compress: conf.Compress, // 是否压缩日志 + } + return zapcore.AddSync(lumberJackLogger), nil +} + +// getEncoder 编码器(如何写入日志) +func getEncoder(conf interface{}) zapcore.Encoder { + encoderConfig := zap.NewProductionEncoderConfig() + encoderConfig.EncodeTime = zapcore.TimeEncoderOfLayout("2006-01-02 15:04:05.000Z07") // log 时间格式 例如: 2021-09-11t20:05:54.852+0800 + encoderConfig.EncodeCaller = zapcore.FullCallerEncoder + + var format string + switch conf.(type) { + case FileConfig: + format = conf.(FileConfig).Format + encoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder + case ConsoleConfig: + format = conf.(ConsoleConfig).Format + // 输出level序列化为全大写字符串,如 INFO DEBUG ERROR 彩色 + encoderConfig.EncodeLevel = zapcore.CapitalColorLevelEncoder + } + + if format == "json" { + return zapcore.NewJSONEncoder(encoderConfig) // 以json格式写入 + } + return zapcore.NewConsoleEncoder(encoderConfig) // 以默认console格式写入 +} + +// isExist 判断文件或者目录是否存在 +func isExist(path string) bool { + _, err := os.Stat(path) + return err == nil || os.IsExist(err) +} + +// 最终方案-全兼容 +func getCurrentAbPath() string { + dir := getCurrentAbPathByExecutable() + if strings.Contains(dir, getTmpDir()) { + return getCurrentAbPathByCaller() + } + return dir +} + +// 获取系统临时目录,兼容go run +func getTmpDir() string { + dir := os.Getenv("TEMP") + if dir == "" { + dir = os.Getenv("TMP") + } + res, _ := filepath.EvalSymlinks(dir) + return res +} + +// 获取当前执行文件绝对路径 +func getCurrentAbPathByExecutable() string { + exePath, _ := os.Executable() + res, _ := filepath.EvalSymlinks(filepath.Dir(exePath)) + return res +} + +// 获取当前执行文件绝对路径(go run) +func getCurrentAbPathByCaller() string { + var abPath string + _, filename, _, ok := runtime.Caller(0) + if ok { + abPath = path.Dir(filename) + } + return abPath +} diff --git a/pkg/trie/trie.go b/pkg/trie/trie.go new file mode 100644 index 0000000..4e55542 --- /dev/null +++ b/pkg/trie/trie.go @@ -0,0 +1,58 @@ +package trie + +type ( + // trieNode 节点 + trieNode struct { + char string // unicode + isEnding bool // 是否单词结尾 + children map[rune]*trieNode // 子节点 + } + + // Trie 字典树(前缀树)(多叉树) + Trie struct { + root *trieNode // 根节点指针 + } +) + +func NewTrieNode(char string) *trieNode { + return &trieNode{ + char: char, + isEnding: false, + children: make(map[rune]*trieNode), + } +} + +func NewTrie() *Trie { + // 初始化根 + trieNode := NewTrieNode("/") + return &Trie{trieNode} +} + +// Insert 插入一个单词 +func (t *Trie) Insert(word string) { + node := t.root + for _, code := range word { + v, ok := node.children[code] + if !ok { + v = NewTrieNode(string(code)) + node.children[code] = v + } + node = v + } + node.isEnding = true +} + +func (t *Trie) Exists(word string) bool { + node := t.root + for _, code := range word { + v, ok := node.children[code] + if !ok { + return false + } + node = v + } + if node.isEnding == false { + return false + } + return true +} diff --git a/pkg/trie/trie_test.go b/pkg/trie/trie_test.go new file mode 100644 index 0000000..a31fbd3 --- /dev/null +++ b/pkg/trie/trie_test.go @@ -0,0 +1,26 @@ +package trie + +import ( + "fmt" + "testing" +) + +func TestTrie(t *testing.T) { + trie := NewTrie() + + // 指令集 + words := []string{"j", "c", "w", "s", "m"} + + // 构建 前缀树 + for _, word := range words { + trie.Insert(word) + } + + // 待搜索的连续指令 玩家自由搭配 + search := "jc3sm1c2m2c4m3" // 加入游戏 生产3 上路兵 生产2 中路兵 生产4 下路兵 + if trie.Exists(search) { + fmt.Println("可以用 ", search) + } else { + fmt.Println("啊 还没能匹配", search) + } +}