diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ee46674 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.idea +vendor + +*.log \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..ed281a8 --- /dev/null +++ b/Makefile @@ -0,0 +1,15 @@ + + +all: ge build run + +ge: + protoc -I./protos --go_out=./protos --go-grpc_out=./protos ./protos/*proto + +test: + go run test/client.go +run: + go run main.go +build: + go build -o bin/server main.go + +.PHONY: all build protos test \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..61c71e5 --- /dev/null +++ b/README.md @@ -0,0 +1,34 @@ +## Pro2dServer +这是pro2d项目的服务器, 使用golang搭建 + +## 技术点 +* grpc +* http2 +* golang +* mongo + +* etcd +* grpc 热更 +* proto gorm 查询 + +## 环境安装 +etcd +```shell +$ go get go.etcd.io/etcd/client/v3 +$ go install google.golang.org/protobuf/cmd/protoc-gen-go +$ go get google.golang.org/grpc/cmd/protoc-gen-go-grpc +$ go install google.golang.org/grpc/cmd/protoc-gen-go-grpc +``` +## Usage +编译 & 运行 +```shell +$ make run +``` +测试 +```shell +$ make test +``` + + + + diff --git a/actions/accountaction.go b/actions/accountaction.go new file mode 100644 index 0000000..84a970e --- /dev/null +++ b/actions/accountaction.go @@ -0,0 +1,39 @@ +package actions + +import ( + "context" + "fmt" + "pro2d/conf" + "pro2d/models" + "pro2d/protos/pb" + "pro2d/utils" +) + +func (s *AccountServer) RegisterHandler(ctx context.Context, in *pb.Register) (*pb.PubRsp, error) { + ok, account := models.AccountExistByPhone(s.Database, in.Phone) + if !ok { + account.Phone = in.Phone + account.Password = utils.Md5V(in.Password) + account.Uid = conf.SnowFlack.NextVal() + account.Device = "123123" + account.Create() + }else { + return nil, fmt.Errorf("1") + } + + return &pb.PubRsp{ + Code: 0, + }, nil + +} + +func (s *AccountServer) CreateTokenHandler(ctx context.Context, in *pb.AccountInfo) (*pb.CreateTokenRsp, error) { + return &pb.CreateTokenRsp{ + Token: utils.CreateToken(in), + GameService: &pb.ServiceInfo{ + Id: "1", + Name: conf.GlobalConf.GameConf.Name, + Address: fmt.Sprintf("%s:%d",conf.GlobalConf.GameConf.IP, conf.GlobalConf.GameConf.Port), + }, + }, nil +} diff --git a/actions/basic.go b/actions/basic.go new file mode 100644 index 0000000..c72c036 --- /dev/null +++ b/actions/basic.go @@ -0,0 +1,36 @@ +package actions + +import ( + "fmt" + "net" + "pro2d/components/db" + "pro2d/conf" + "pro2d/utils" +) + +type BasicServer struct { + Database *db.Database +} + +func NewServer() *BasicServer { + return &BasicServer{ + Database: new(db.Database), + } +} + +func (b *BasicServer) Start(sConf *conf.SConf) (net.Listener, error) { + if err := b.Database.Connect(sConf.MongoConf); err !=nil { + utils.Sugar.Debugf("db error: %v", err) + return nil, err + } + + listing := fmt.Sprintf(":%d", sConf.Port) + lis, err := net.Listen("tcp", listing) + if err != nil { + return nil, err + } + return lis, err +} + +func (b *BasicServer) Close() { +} diff --git a/actions/roleaction.go b/actions/roleaction.go new file mode 100644 index 0000000..d9ed160 --- /dev/null +++ b/actions/roleaction.go @@ -0,0 +1,88 @@ +package actions + +import ( + "context" + "errors" + "fmt" + "google.golang.org/grpc/metadata" + "pro2d/models" + "pro2d/protos/pb" + "pro2d/utils" + "time" +) + +func (s *GameServer) HeartBeatHandler(ctx context.Context, in *pb.Token) (*pb.PubRsp, error) { + utils.Sugar.Debugf("HeartBeatHandler被调用!!!") + //获取元数据信息 + md,ok := metadata.FromIncomingContext(ctx) + if !ok { + return nil,errors.New("未传输token") + } + var ( + appId string + appKey string + ) + if val, ok := md["appId"]; ok { + appId = val[0] + } + if val, ok := md["appKey"]; ok { + appKey = val[0] + } + //进行校验的信息是否正确 + if appId != "123" || appKey != "456" { + return nil, errors.New("token传输不正确") + } + + return &pb.PubRsp{ + Code: 0, + Msg: "heart beat successful", + }, nil +} + +func (s *GameServer) CreateRoleHandler(ctx context.Context, in *pb.Token) (*pb.RoleRsp, error) { + account := utils.ParseToken(in.Token) + if account == nil { + return nil, fmt.Errorf("1") + } + ok, role := models.RoleExistByUid(s.Database, account.Uid) + if !ok { + role.Role = &pb.Role{ + Level: 0, + LoginTime: time.Now().Unix(), + Device: account.Device, + Uid: account.Uid, + } + role.Create() + + } + return &pb.RoleRsp{ + Rsp: &pb.PubRsp{ + Code: 0, + Msg: "successful", + }, + Role: role.Role, + }, nil +} + +func (s *GameServer) LoginHandler(ctx context.Context, in *pb.Token) (*pb.RoleRsp, error) { + account := utils.ParseToken(in.Token) + if account == nil { + return nil, fmt.Errorf("token is error") + } + ok, role := models.RoleExistByUid(s.Database, account.Uid) + if !ok { + return &pb.RoleRsp{ + Rsp: &pb.PubRsp{ + Code: -1, + Msg: "role not exist", + }, + }, nil + } + return &pb.RoleRsp{ + Rsp: &pb.PubRsp{ + Code: 0, + Msg: "successful", + }, + Role: role.Role, + }, nil +} diff --git a/actions/server.go b/actions/server.go new file mode 100644 index 0000000..936a0a9 --- /dev/null +++ b/actions/server.go @@ -0,0 +1,95 @@ +package actions + +import ( + "context" + "google.golang.org/grpc" + "google.golang.org/grpc/reflection" + "pro2d/conf" + "pro2d/protos/pb" + "pro2d/utils" +) + +type AccountServer struct{ + pb.UnimplementedAccountServer + *BasicServer +} + +func NewAccountServer() *AccountServer { + return &AccountServer{ + BasicServer: NewServer(), + } +} + +//拦截器 +func AccountServerInterceptor(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, + handler grpc.UnaryHandler) (interface{}, error) { + + utils.Sugar.Debugf("gRPC method: %s, %v", info.FullMethod, req) + resp, err := handler(ctx, req) + return resp, err +} + +func (s *AccountServer)Start() error { + lis, err := s.BasicServer.Start(conf.GlobalConf.AccountConf) + if err != nil { + return err + } + + //new一个grpc + gs := grpc.NewServer(grpc.UnaryInterceptor(AccountServerInterceptor)) + + pb.RegisterAccountServer(gs, s) + reflection.Register(gs) //在给定的gRPC服务器上注册服务器反射服务 + + // Serve方法在lis上接受传入连接,为每个连接创建一个ServerTransport和server的goroutine。 + // 该goroutine读取gRPC请求,然后调用已注册的处理程序来响应它们。 + utils.Sugar.Debugf("Start AccountServer listening on %d", conf.GlobalConf.AccountConf.Port) + + return gs.Serve(lis) +} + +func (s *AccountServer)Stop() { + s.BasicServer.Close() +} + + +type GameServer struct{ + pb.UnimplementedGameServer + *BasicServer +} + +func NewGameServer() *GameServer { + return &GameServer{ + BasicServer: NewServer(), + } +} +//拦截器 +func GameServerInterceptor(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, + handler grpc.UnaryHandler) (interface{}, error) { + + utils.Sugar.Debugf("gRPC method: %s, %v", info.FullMethod, req) + resp, err := handler(ctx, req) + return resp, err +} + +func (s *GameServer)Start() error { + lis, err := s.BasicServer.Start(conf.GlobalConf.GameConf) + if err != nil { + return err + } + + //new一个grpc + gs := grpc.NewServer(grpc.UnaryInterceptor(GameServerInterceptor)) + + pb.RegisterGameServer(gs, s) + reflection.Register(gs) //在给定的gRPC服务器上注册服务器反射服务 + + // Serve方法在lis上接受传入连接,为每个连接创建一个ServerTransport和server的goroutine。 + // 该goroutine读取gRPC请求,然后调用已注册的处理程序来响应它们。 + utils.Sugar.Debugf("Start GameServer listening on %d", conf.GlobalConf.GameConf.Port) + return gs.Serve(lis) +} + +func (s *GameServer)Stop() { + s.BasicServer.Close() +} \ No newline at end of file diff --git a/bin/server b/bin/server new file mode 100755 index 0000000..3beb462 Binary files /dev/null and b/bin/server differ diff --git a/components/db/mongo.go b/components/db/mongo.go new file mode 100644 index 0000000..5f3b529 --- /dev/null +++ b/components/db/mongo.go @@ -0,0 +1,224 @@ +package db + +import ( + "context" + "fmt" + "go.mongodb.org/mongo-driver/bson" + "go.mongodb.org/mongo-driver/mongo" + "go.mongodb.org/mongo-driver/mongo/options" + "go.mongodb.org/mongo-driver/mongo/readpref" + "go.mongodb.org/mongo-driver/x/bsonx" + "pro2d/conf" + "strconv" + "time" +) +type Database struct { + Mongo *mongo.Database +} + +//初始化 +func (db *Database)Connect(conf *conf.MongoConf) error { + var uri string + if conf.User!= "" { + uri = fmt.Sprintf("mongodb://%s:%s@%s:%d/%s?w=majority", conf.User, conf.Password, conf.Host, conf.Port, conf.DBName) + }else { + uri = fmt.Sprintf("mongodb://%s:%d/%s?w=majority", conf.Host, conf.Port, conf.DBName) + } + // 设置连接超时时间 + ctx, cancel := context.WithTimeout(context.Background(), time.Duration(conf.TimeOut)) + defer cancel() + // 通过传进来的uri连接相关的配置 + o := options.Client().ApplyURI(uri) + // 设置最大连接数 - 默认是100 ,不设置就是最大 max 64 + o.SetMaxPoolSize(uint64(conf.MaxNum)) + // 发起链接 + client, err := mongo.Connect(ctx, o) + if err != nil { + fmt.Println("ConnectToDB", err) + return err + } + // 判断服务是不是可用 + if err = client.Ping(context.Background(), readpref.Primary()); err != nil { + fmt.Println("ConnectToDB", err) + return err + } + + db.Mongo = client.Database(conf.DBName) + return nil +} + +type MgoPool struct { + mgo *mongo.Database + + collection string +} + +func GetBsonD(key string, value interface{}) interface{} { + return bson.D{ {key, value}} +} +func GetBsonM(key string, value interface{}) interface{} { + return bson.M{key: value} +} + +func NewMongoPool(mgo *Database, collection string)*MgoPool { + return &MgoPool{ + mgo: mgo.Mongo, + collection: collection, + } +} + +func (m *MgoPool)SetDatabase(databases string) { + //m.db = databases +} +func (m *MgoPool)SetCollect(coll string) { + m.collection = coll +} + + +//func (m *MgoPool)Insert(coll string, buffer interface{}) error { +// _, err := m.mgo.Collection(coll).InsertOne(context.TODO(), buffer) +// if err != nil { +// fmt.Println(err) +// } +// return err +//} + +//func (m *MgoPool)FindOne(coll string, filter interface{}) (interface{}, error){ +// findOptions := options.FindOne() +// cur := m.MongoDBClient.Collection(coll).FindOne(context.TODO(), filter, findOptions) +// var role interface{} +// if err := cur.Decode(role); err != nil { +// return nil, err +// } +// return role, nil +//} +// 查询单个 +func (m *MgoPool) FindOneKV(key string, value interface{}) *mongo.SingleResult { + collection := m.mgo.Collection(m.collection) + //collection. + filter := bson.D{ {key, value}} + singleResult := collection.FindOne(context.TODO(), filter) + return singleResult +} + +func (m *MgoPool) FindOne(pri interface{}) *mongo.SingleResult { + collection := m.mgo.Collection(m.collection) + //collection. + singleResult := collection.FindOne(context.TODO(), pri) + return singleResult +} + +//插入单个 +func (m *MgoPool) InsertOne(value interface{}) *mongo.InsertOneResult { + collection := m.mgo.Collection(m.collection) + insertResult, err := collection.InsertOne(context.TODO(), value) + if err != nil { + fmt.Println(err) + } + return insertResult +} + +//查询集合里有多少数据 +func (m *MgoPool) CollectionCount() (string, int64) { + collection := m.mgo.Collection(m.collection) + name := collection.Name() + size, _ := collection.EstimatedDocumentCount(context.TODO()) + return name, size +} + +//按选项查询集合 Skip 跳过 Limit 读取数量 sort 1 ,-1 . 1 为最初时间读取 , -1 为最新时间读取 +func (m *MgoPool) CollectionDocuments(Skip, Limit int64, sort int) *mongo.Cursor { + collection := m.mgo.Collection(m.collection) + SORT := bson.D{ + {"_id", sort}} //filter := bson.D{ {key,value}} + filter := bson.D{ + {}} + findOptions := options.Find().SetSort(SORT).SetLimit(Limit).SetSkip(Skip) + //findOptions.SetLimit(i) + temp, _ := collection.Find(context.Background(), filter, findOptions) + return temp +} + +//获取集合创建时间和编号 +func (m *MgoPool) ParsingId(result string) (time.Time, uint64) { + temp1 := result[:8] + timestamp, _ := strconv.ParseInt(temp1, 16, 64) + dateTime := time.Unix(timestamp, 0) //这是截获情报时间 时间格式 2019-04-24 09:23:39 +0800 CST + temp2 := result[18:] + count, _ := strconv.ParseUint(temp2, 16, 64) //截获情报的编号 + return dateTime, count +} + +//删除文章和查询文章 +func (m *MgoPool) DeleteAndFind(key string, value interface{}) (int64, *mongo.SingleResult) { + collection := m.mgo.Collection(m.collection) + filter := bson.D{ + {key, value}} + singleResult := collection.FindOne(context.TODO(), filter) + DeleteResult, err := collection.DeleteOne(context.TODO(), filter, nil) + if err != nil { + fmt.Println("删除时出现错误,你删不掉的~") + } + return DeleteResult.DeletedCount, singleResult +} + +//删除文章 +func (m *MgoPool) Delete(key string, value interface{}) int64 { + collection := m.mgo.Collection(m.collection) + filter := bson.D{ {key, value}} + count, err := collection.DeleteOne(context.TODO(), filter, nil) + if err != nil { + fmt.Println(err) + } + return count.DeletedCount + +} + +//删除多个 +func (m *MgoPool) DeleteMany(key string, value interface{}) int64 { + collection := m.mgo.Collection(m.collection) + filter := bson.D{ {key, value}} + + count, err := collection.DeleteMany(context.TODO(), filter) + if err != nil { + fmt.Println(err) + } + return count.DeletedCount +} + +//索引 +func (m *MgoPool) Index(key string){ + collection := m.mgo.Collection(m.collection) + collection.Indexes().CreateOne( + context.Background(), + mongo.IndexModel{ + Keys : bsonx.Doc{{key, bsonx.Int32(1)}}, + Options: options.Index().SetUnique(true), + }, + ) +} + +//更新&保存 +func (m *MgoPool) FindOneAndUpdate(filter interface{}, update interface{})*mongo.SingleResult { + //filter := bson.M{"name": "x", "array.name": "b"} + //update := bson.M{"array.$[item].detail": "test"} + + collection := m.mgo.Collection(m.collection) + res := collection.FindOneAndUpdate(context.Background(), + filter, + bson.M{"$set": update}) + if res.Err() != nil { + return nil + } + return res +} + +func (m *MgoPool) UpdateOne(filter interface{}, update interface{})*mongo.UpdateResult { + collection := m.mgo.Collection(m.collection) + res, err := collection.UpdateOne(context.TODO(), filter, update) + if err != nil { + return nil + } + + return res +} \ No newline at end of file diff --git a/components/db/redis.go b/components/db/redis.go new file mode 100644 index 0000000..4b73e4c --- /dev/null +++ b/components/db/redis.go @@ -0,0 +1,54 @@ +package db + +import ( + "fmt" + "github.com/garyburd/redigo/redis" + "pro2d/conf" + "pro2d/utils" + "time" +) + +type RedisPool struct { + RedisPool *redis.Pool +} + +func (rp *RedisPool)Connect(conf *conf.ServerConf) error { + rp.RedisPool = &redis.Pool{ + //最大活跃连接数,0代表无限 + MaxActive: 888, + MaxIdle: 20, + //闲置连接的超时时间 + IdleTimeout: time.Second * 100, + //定义拨号获得连接的函数 + Dial: func() (redis.Conn, error) { + option := []redis.DialOption{redis.DialDatabase(conf.RedisConf.DB)} + if conf.RedisConf.Auth != "" { + option = append(option, redis.DialPassword(conf.RedisConf.Auth)) + } + return redis.Dial("tcp",conf.RedisConf.Address, option...) + }, + } + return nil +} + +func (rp *RedisPool)Close() { + rp.RedisPool.Close() +} + +func (rp *RedisPool) Insert() error { + conn := rp.RedisPool.Get() + defer conn.Close() + reply, err := conn.Do("HKEYS", fmt.Sprintf("account:%s", "123123")) + if err != nil { + return err + } + + utils.Sugar.Debugf("%v", reply) + reply, err = conn.Do("HMSET", fmt.Sprintf("account:%s", "1231231"), "phone", "1231231", "passwd", "2131231") + if err != nil { + utils.Sugar.Errorf("%v", err) + return err + } + utils.Sugar.Debugf("%v", reply) + return nil +} diff --git a/conf/RedisKeys.go b/conf/RedisKeys.go new file mode 100644 index 0000000..3d8b4a9 --- /dev/null +++ b/conf/RedisKeys.go @@ -0,0 +1,2 @@ +package conf + diff --git a/conf/conf.go b/conf/conf.go new file mode 100644 index 0000000..107cf68 --- /dev/null +++ b/conf/conf.go @@ -0,0 +1,73 @@ +package conf + +import ( + "fmt" + lumberjack "gopkg.in/natefinch/lumberjack.v2" + "gopkg.in/yaml.v3" + "io/ioutil" + "pro2d/utils" +) + +type RedisConf struct { + Address string `json:"address"` + Auth string `json:"auth"` + DB int `json:"db"` +} + +type EndPoint struct { + Address string `json:"address"` +} + +type Etcd struct { + Endpoints []EndPoint `json:"endpoints"` +} + +type MongoConf struct { + User string `yaml:"user"` + Password string `yaml:"password"` + Host string `yaml:"host"` + Port int `yaml:"port"` + DBName string `yaml:"dbname"` + TimeOut int `yaml:"timeout"` + MaxNum int `yaml:"maxnum"` +} + +type SConf struct { + Name string `yaml:"name"` + IP string `yaml:"ip"` + Port int `yaml:"port"` + MongoConf *MongoConf `yaml:"mongo"` +} + +type ServerConf struct { + ID string `yaml:"id"` + Name string `yaml:"name"` + WorkerID int64 `yaml:"workerid"` + DatacenterID int64 `yaml:"datacenterid"` + AccountConf *SConf `yaml:"server_account"` + GameConf *SConf `yaml:"server_game"` + RedisConf *RedisConf `yaml:"redis"` + LogConf *lumberjack.Logger `json:"logconf"` + Etcd *Etcd `yaml:"etcd"` +} + +var GlobalConf ServerConf +var SnowFlack *utils.Snowflake +func init() { + configFile, err := ioutil.ReadFile("conf/conf.yaml") + if err != nil { + fmt.Printf("conf faild: %v", err) + return + } + //初始化配置 + if err = yaml.Unmarshal(configFile, &GlobalConf); err != nil { + fmt.Printf("yaml unmarshal faild: %v", err) + return + } + + //初始化日志 + utils.InitLogger(GlobalConf.LogConf) + + //初始化雪花算法 + SnowFlack = utils.NewSnowflake(GlobalConf.WorkerID, GlobalConf.DatacenterID) +} \ No newline at end of file diff --git a/conf/conf.yaml b/conf/conf.yaml new file mode 100644 index 0000000..9a59c94 --- /dev/null +++ b/conf/conf.yaml @@ -0,0 +1,39 @@ +develop: true +name: "Pro2DServer" +workerid: 1 +datacenterid: 1 +server_account: + name: "account" + ip: "192.168.0.206" + port: 8848 + mongo: + host: "192.168.0.206" + port: 27017 + user: "" + password: "" + dbname: "account" + timeout: 2 + maxnum: 50 +server_game: + name: "game" + ip: "192.168.0.206" + port: 8849 + mongo: + host: "192.168.0.206" + port: 27017 + user: "" + password: "" + dbname: "game" + timeout: 2 + maxnum: 50 + +logconf: + filename: "./pro2d.log" # ⽇志⽂件路径 + maxsize: 1024 # 1M=1024KB=1024000byte + maxbackups: 5 # 最多保留5个备份 + maxage: 30 # days + compress: true # 是否压缩 disabled by default + +etcd: + endpoints: + - address: "192.168.0.206:2379" \ No newline at end of file diff --git a/doc/login.md b/doc/login.md new file mode 100644 index 0000000..27357e1 --- /dev/null +++ b/doc/login.md @@ -0,0 +1,7 @@ + +## 注册 & 登录流程 +1. Account服务注册账号 +2. Account服务createToken +3. Game服务登录,判断角色是否创建, 未创建角色则创建,返回角色信息 + + diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..d4f3db8 --- /dev/null +++ b/go.mod @@ -0,0 +1,37 @@ +module pro2d + +go 1.17 + +require ( + github.com/dgrijalva/jwt-go v3.2.0+incompatible + github.com/garyburd/redigo v1.6.3 + github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b + github.com/golang/protobuf v1.5.2 + go.mongodb.org/mongo-driver v1.8.3 + go.uber.org/zap v1.17.0 + google.golang.org/grpc v1.38.0 + google.golang.org/protobuf v1.27.1 + gopkg.in/natefinch/lumberjack.v2 v2.0.0 + gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b +) + +require ( + github.com/go-stack/stack v1.8.0 // indirect + github.com/golang/snappy v0.0.1 // indirect + github.com/klauspost/compress v1.13.6 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/xdg-go/pbkdf2 v1.0.0 // indirect + github.com/xdg-go/scram v1.0.2 // indirect + github.com/xdg-go/stringprep v1.0.2 // indirect + github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect + go.uber.org/atomic v1.7.0 // indirect + go.uber.org/multierr v1.6.0 // indirect + golang.org/x/crypto v0.0.0-20201216223049-8b5274cf687f // indirect + golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 // indirect + golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect + golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40 // indirect + golang.org/x/text v0.3.5 // indirect + google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c // indirect + gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..7cd185b --- /dev/null +++ b/go.sum @@ -0,0 +1,180 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +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/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +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.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/garyburd/redigo v1.6.3 h1:HCeeRluvAgMusMomi1+6Y5dmFOdYV/JzoRrrbFlkGIc= +github.com/garyburd/redigo v1.6.3/go.mod h1:rTb6epsqigu3kYKBnaF028A7Tf/Aw5s0cqA47doKKqw= +github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= +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= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +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.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= +github.com/golang/snappy v0.0.1/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= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2/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/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc= +github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +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/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +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 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= +github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= +github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c= +github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= +github.com/xdg-go/scram v1.0.2 h1:akYIkZ28e6A96dkWNJQu3nmCzH3YfwMPQExUYDaRv7w= +github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs= +github.com/xdg-go/stringprep v1.0.2 h1:6iq84/ryjjeRmMJwxutI51F2GIPlP5BfTvXHeYjyhBc= +github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM= +github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d h1:splanxYIlg+5LfHAM6xpdFEAYOk8iySO56hMFq6uLyA= +github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +go.mongodb.org/mongo-driver v1.8.3 h1:TDKlTkGDKm9kkJVUOAXDK5/fkqKHJVwYQSpoRfB43R4= +go.mongodb.org/mongo-driver v1.8.3/go.mod h1:0sQWfOeY63QTntERDJJ/0SuKK0T1uVSgKCuAROlKEPY= +go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= +go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4= +go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= +go.uber.org/zap v1.17.0 h1:MTjgFu6ZLKvY6Pvaqk97GlxNBuMpV4Hy/3P6tRGlI2U= +go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= +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-20201216223049-8b5274cf687f h1:aZp0e2vLN4MToVqnjNEYEtrEA8RH8U8FN1CU7JgqsPU= +golang.org/x/crypto v0.0.0-20201216223049-8b5274cf687f/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +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-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +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-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-20210405180319-a5a99cb37ef4 h1:4nGaVu0QrbjT/AK2PRLuQfQuh6DJve+pELhqTdAj3x0= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/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-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= +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-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-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40 h1:JWgyZ1qgdTaF3N3oxC+MdTV7qvEEgHo3otj+HB5CM7Q= +golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +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 h1:i6eZZ+zk0SOf0xgBpEpPD18qWcJda6q1sxt3S0kzyUQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +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-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.1.2/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= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c h1:wtujag7C+4D6KMoulW9YauvK2lgdvCMS260jsqqBXr0= +google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.38.0 h1:/9BgsAsa5nWe26HqOlvlgJnqBuktYOLCgjCPqsa56W0= +google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +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-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8= +gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= +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/main.go b/main.go new file mode 100644 index 0000000..e2dff38 --- /dev/null +++ b/main.go @@ -0,0 +1,23 @@ +package main + +import ( + "pro2d/actions" + "pro2d/utils" +) + +func main() { + err := make(chan error) + accountS := actions.NewAccountServer() + go func() { + defer accountS.Stop() + err <- accountS.Start() + }() + + gameS := actions.NewGameServer() + go func() { + defer gameS.Stop() + err <- gameS.Start() + }() + + utils.Sugar.Errorf("server error: %v", <- err) +} diff --git a/models/account.go b/models/account.go new file mode 100644 index 0000000..b5f3cb3 --- /dev/null +++ b/models/account.go @@ -0,0 +1,32 @@ +package models + +import ( + "pro2d/components/db" + "pro2d/protos/pb" +) + +type AccountModel struct { + *ModelBaseMgo + *pb.AccountInfo +} + +func AccountExistByPhone(mgo *db.Database, phone string) (bool, *AccountModel){ + m := NewAccount(mgo, phone) + if err := m.Load(); err != nil { + return false, m + } + return true, m +} + +func NewAccount(mgo *db.Database, phone string) *AccountModel { + ac := &pb.AccountInfo{ + Phone: phone, + } + account := &AccountModel{ + ModelBaseMgo: NewModelBaseMgo(mgo, "account", db.GetBsonM("phone", phone), ac), + AccountInfo: ac, + } + + + return account +} \ No newline at end of file diff --git a/models/basic.go b/models/basic.go new file mode 100644 index 0000000..89ecc36 --- /dev/null +++ b/models/basic.go @@ -0,0 +1,46 @@ +package models + +import ( + "pro2d/components/db" +) + +type ModelBaseMgo struct { + MonGo *db.MgoPool + + pri interface{} + schema interface{} +} + + +func NewModelBaseMgo(mgo *db.Database, collection string, pri interface{}, schema interface{}) *ModelBaseMgo{ + return &ModelBaseMgo{ + MonGo: db.NewMongoPool(mgo, collection), + pri: pri, + schema: schema, + } +} + +func (base *ModelBaseMgo) Load() error{ + r := base.MonGo.FindOne(base.pri) + err := r.Decode(base.schema) + if err != nil { + return err + } + return nil +} + +func (base *ModelBaseMgo) Create() { + base.MonGo.InsertOne(base.schema) +} + +func (base *ModelBaseMgo) Index(key string) { + base.MonGo.Index(key) +} + +func (base *ModelBaseMgo) Update(update interface{}) { + base.MonGo.FindOneAndUpdate(base.pri, update) +} + +func (base *ModelBaseMgo) Save() { + base.MonGo.FindOneAndUpdate(base.pri, base.schema) +} \ No newline at end of file diff --git a/models/role.go b/models/role.go new file mode 100644 index 0000000..71d5a4b --- /dev/null +++ b/models/role.go @@ -0,0 +1,38 @@ +package models + +import ( + "pro2d/components/db" + "pro2d/protos/pb" +) + +type RoleModel struct { + *ModelBaseMgo + *pb.Role +} + +//创建数据 +//数据加载 +//数据保存 + +func RoleExistByUid(mgo *db.Database, uid int64) (bool, *RoleModel){ + m := NewRole(mgo, uid) + if err := m.Load(); err != nil { + return false, m + } + return true, m +} + +func NewRole(mgo *db.Database, uid int64) *RoleModel { + r := &pb.Role{ + Uid: uid, + } + m := &RoleModel{ + ModelBaseMgo: NewModelBaseMgo(mgo, "role", db.GetBsonM("uid", uid), r), + Role: r, + } + m.Load() + return m +} + +func (m *RoleModel) LoadAll() { +} diff --git a/models/role_test.go b/models/role_test.go new file mode 100644 index 0000000..f463aa3 --- /dev/null +++ b/models/role_test.go @@ -0,0 +1,35 @@ +package models + +import ( + "pro2d/components/db" + "pro2d/conf" + "pro2d/utils" + "testing" + "time" +) + +func TestNewRole(t *testing.T) { + db := &db.Database{} + if err := db.Connect(conf.GlobalConf.GameConf.MongoConf); err != nil { + utils.Sugar.Errorf("%v", err) + return + } + + + //db.Mongo.Drop(context.Background()) + var uid int64 = 1 + var role *RoleModel + if ok, role := RoleExistByUid(db, uid); ok { + role.Role.Device = "111111" + role.Role.LoginTime = time.Now().Unix() + role.Save() + }else { + role = NewRole(db, uid) + role.Role.Id = "1" + role.Role.Device = "222222" + role.Role.Level = 0 + role.Create() + role.Index("uid") + } + print(role) +} \ No newline at end of file diff --git a/protos/account.proto b/protos/account.proto new file mode 100644 index 0000000..66d979d --- /dev/null +++ b/protos/account.proto @@ -0,0 +1,34 @@ +syntax = "proto3"; +option go_package = "./pb;pb"; + +package account; +import "public.proto"; + +message ServiceInfo { + string id = 1; + string name = 2; + string address = 3; +} + +message AccountInfo{ + string phone = 2; + string password = 3; + int64 uid = 4; + string device = 5; +} + +message CreateTokenRsp { + string token = 1; + ServiceInfo game_service = 2; +} + +message Register { + string phone = 1; + string password = 2; + int32 code = 3; +} + +service Account{ + rpc RegisterHandler(Register) returns (public.PubRsp) {} + rpc CreateTokenHandler(AccountInfo) returns (CreateTokenRsp) {} +} \ No newline at end of file diff --git a/protos/game.proto b/protos/game.proto new file mode 100644 index 0000000..0938b34 --- /dev/null +++ b/protos/game.proto @@ -0,0 +1,28 @@ +syntax = "proto3"; +option go_package = "./pb;pb"; + +package game; +import "public.proto"; + +message Role{ + string id = 1; + int32 level = 3; + int64 login_time = 4; + string device = 5; + int64 uid = 6; +} + +message Token { + string token = 1; +} + +message RoleRsp { + public.PubRsp rsp = 1; + Role role = 2; +} + +service Game{ + rpc HeartBeatHandler(Token) returns (public.PubRsp) {} + rpc LoginHandler(Token) returns (RoleRsp) {} + rpc CreateRoleHandler(Token) returns (RoleRsp) {} +} \ No newline at end of file diff --git a/protos/generate.sh b/protos/generate.sh new file mode 100755 index 0000000..32dd263 --- /dev/null +++ b/protos/generate.sh @@ -0,0 +1,3 @@ +#!/bin/bash +protoc -I. --go_out=. --go-grpc_out=. ./*proto +#./account/*.proto ./game/*.proto ./public/*.proto \ No newline at end of file diff --git a/protos/pb/account.pb.go b/protos/pb/account.pb.go new file mode 100644 index 0000000..df49b57 --- /dev/null +++ b/protos/pb/account.pb.go @@ -0,0 +1,422 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.26.0 +// protoc v3.17.3 +// source: account.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 ServiceInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + Address string `protobuf:"bytes,3,opt,name=address,proto3" json:"address,omitempty"` +} + +func (x *ServiceInfo) Reset() { + *x = ServiceInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_account_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ServiceInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ServiceInfo) ProtoMessage() {} + +func (x *ServiceInfo) ProtoReflect() protoreflect.Message { + mi := &file_account_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 ServiceInfo.ProtoReflect.Descriptor instead. +func (*ServiceInfo) Descriptor() ([]byte, []int) { + return file_account_proto_rawDescGZIP(), []int{0} +} + +func (x *ServiceInfo) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *ServiceInfo) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *ServiceInfo) GetAddress() string { + if x != nil { + return x.Address + } + return "" +} + +type AccountInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Phone string `protobuf:"bytes,2,opt,name=phone,proto3" json:"phone,omitempty"` + Password string `protobuf:"bytes,3,opt,name=password,proto3" json:"password,omitempty"` + Uid int64 `protobuf:"varint,4,opt,name=uid,proto3" json:"uid,omitempty"` + Device string `protobuf:"bytes,5,opt,name=device,proto3" json:"device,omitempty"` +} + +func (x *AccountInfo) Reset() { + *x = AccountInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_account_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AccountInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AccountInfo) ProtoMessage() {} + +func (x *AccountInfo) ProtoReflect() protoreflect.Message { + mi := &file_account_proto_msgTypes[1] + 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 AccountInfo.ProtoReflect.Descriptor instead. +func (*AccountInfo) Descriptor() ([]byte, []int) { + return file_account_proto_rawDescGZIP(), []int{1} +} + +func (x *AccountInfo) GetPhone() string { + if x != nil { + return x.Phone + } + return "" +} + +func (x *AccountInfo) GetPassword() string { + if x != nil { + return x.Password + } + return "" +} + +func (x *AccountInfo) GetUid() int64 { + if x != nil { + return x.Uid + } + return 0 +} + +func (x *AccountInfo) GetDevice() string { + if x != nil { + return x.Device + } + return "" +} + +type CreateTokenRsp struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Token string `protobuf:"bytes,1,opt,name=token,proto3" json:"token,omitempty"` + GameService *ServiceInfo `protobuf:"bytes,2,opt,name=game_service,json=gameService,proto3" json:"game_service,omitempty"` +} + +func (x *CreateTokenRsp) Reset() { + *x = CreateTokenRsp{} + if protoimpl.UnsafeEnabled { + mi := &file_account_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateTokenRsp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateTokenRsp) ProtoMessage() {} + +func (x *CreateTokenRsp) ProtoReflect() protoreflect.Message { + mi := &file_account_proto_msgTypes[2] + 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 CreateTokenRsp.ProtoReflect.Descriptor instead. +func (*CreateTokenRsp) Descriptor() ([]byte, []int) { + return file_account_proto_rawDescGZIP(), []int{2} +} + +func (x *CreateTokenRsp) GetToken() string { + if x != nil { + return x.Token + } + return "" +} + +func (x *CreateTokenRsp) GetGameService() *ServiceInfo { + if x != nil { + return x.GameService + } + return nil +} + +type Register struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Phone string `protobuf:"bytes,1,opt,name=phone,proto3" json:"phone,omitempty"` + Password string `protobuf:"bytes,2,opt,name=password,proto3" json:"password,omitempty"` + Code int32 `protobuf:"varint,3,opt,name=code,proto3" json:"code,omitempty"` +} + +func (x *Register) Reset() { + *x = Register{} + if protoimpl.UnsafeEnabled { + mi := &file_account_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Register) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Register) ProtoMessage() {} + +func (x *Register) ProtoReflect() protoreflect.Message { + mi := &file_account_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 Register.ProtoReflect.Descriptor instead. +func (*Register) Descriptor() ([]byte, []int) { + return file_account_proto_rawDescGZIP(), []int{3} +} + +func (x *Register) GetPhone() string { + if x != nil { + return x.Phone + } + return "" +} + +func (x *Register) GetPassword() string { + if x != nil { + return x.Password + } + return "" +} + +func (x *Register) GetCode() int32 { + if x != nil { + return x.Code + } + return 0 +} + +var File_account_proto protoreflect.FileDescriptor + +var file_account_proto_rawDesc = []byte{ + 0x0a, 0x0d, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, + 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x1a, 0x0c, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x4b, 0x0a, 0x0b, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, + 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x22, 0x69, 0x0a, 0x0b, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x6e, + 0x66, 0x6f, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x05, 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, + 0x77, 0x6f, 0x72, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, + 0x77, 0x6f, 0x72, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x03, 0x52, 0x03, 0x75, 0x69, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x22, 0x5f, + 0x0a, 0x0e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x73, 0x70, + 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x37, 0x0a, 0x0c, 0x67, 0x61, 0x6d, 0x65, 0x5f, 0x73, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x61, + 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x6e, + 0x66, 0x6f, 0x52, 0x0b, 0x67, 0x61, 0x6d, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x22, + 0x50, 0x0a, 0x08, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x70, + 0x68, 0x6f, 0x6e, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x70, 0x68, 0x6f, 0x6e, + 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x12, 0x0a, + 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x63, 0x6f, 0x64, + 0x65, 0x32, 0x88, 0x01, 0x0a, 0x07, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x36, 0x0a, + 0x0f, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, + 0x12, 0x11, 0x2e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, + 0x74, 0x65, 0x72, 0x1a, 0x0e, 0x2e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2e, 0x50, 0x75, 0x62, + 0x52, 0x73, 0x70, 0x22, 0x00, 0x12, 0x45, 0x0a, 0x12, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, + 0x6f, 0x6b, 0x65, 0x6e, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x12, 0x14, 0x2e, 0x61, 0x63, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x6e, 0x66, + 0x6f, 0x1a, 0x17, 0x2e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2e, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x73, 0x70, 0x22, 0x00, 0x42, 0x09, 0x5a, 0x07, + 0x2e, 0x2f, 0x70, 0x62, 0x3b, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_account_proto_rawDescOnce sync.Once + file_account_proto_rawDescData = file_account_proto_rawDesc +) + +func file_account_proto_rawDescGZIP() []byte { + file_account_proto_rawDescOnce.Do(func() { + file_account_proto_rawDescData = protoimpl.X.CompressGZIP(file_account_proto_rawDescData) + }) + return file_account_proto_rawDescData +} + +var file_account_proto_msgTypes = make([]protoimpl.MessageInfo, 4) +var file_account_proto_goTypes = []interface{}{ + (*ServiceInfo)(nil), // 0: account.ServiceInfo + (*AccountInfo)(nil), // 1: account.AccountInfo + (*CreateTokenRsp)(nil), // 2: account.CreateTokenRsp + (*Register)(nil), // 3: account.Register + (*PubRsp)(nil), // 4: public.PubRsp +} +var file_account_proto_depIdxs = []int32{ + 0, // 0: account.CreateTokenRsp.game_service:type_name -> account.ServiceInfo + 3, // 1: account.Account.RegisterHandler:input_type -> account.Register + 1, // 2: account.Account.CreateTokenHandler:input_type -> account.AccountInfo + 4, // 3: account.Account.RegisterHandler:output_type -> public.PubRsp + 2, // 4: account.Account.CreateTokenHandler:output_type -> account.CreateTokenRsp + 3, // [3:5] is the sub-list for method output_type + 1, // [1:3] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name +} + +func init() { file_account_proto_init() } +func file_account_proto_init() { + if File_account_proto != nil { + return + } + file_public_proto_init() + if !protoimpl.UnsafeEnabled { + file_account_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ServiceInfo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_account_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AccountInfo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_account_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateTokenRsp); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_account_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Register); 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_account_proto_rawDesc, + NumEnums: 0, + NumMessages: 4, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_account_proto_goTypes, + DependencyIndexes: file_account_proto_depIdxs, + MessageInfos: file_account_proto_msgTypes, + }.Build() + File_account_proto = out.File + file_account_proto_rawDesc = nil + file_account_proto_goTypes = nil + file_account_proto_depIdxs = nil +} diff --git a/protos/pb/account_grpc.pb.go b/protos/pb/account_grpc.pb.go new file mode 100644 index 0000000..606f8b3 --- /dev/null +++ b/protos/pb/account_grpc.pb.go @@ -0,0 +1,141 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.2.0 +// - protoc v3.17.3 +// source: account.proto + +package pb + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// AccountClient is the client API for Account service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type AccountClient interface { + RegisterHandler(ctx context.Context, in *Register, opts ...grpc.CallOption) (*PubRsp, error) + CreateTokenHandler(ctx context.Context, in *AccountInfo, opts ...grpc.CallOption) (*CreateTokenRsp, error) +} + +type accountClient struct { + cc grpc.ClientConnInterface +} + +func NewAccountClient(cc grpc.ClientConnInterface) AccountClient { + return &accountClient{cc} +} + +func (c *accountClient) RegisterHandler(ctx context.Context, in *Register, opts ...grpc.CallOption) (*PubRsp, error) { + out := new(PubRsp) + err := c.cc.Invoke(ctx, "/account.Account/RegisterHandler", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *accountClient) CreateTokenHandler(ctx context.Context, in *AccountInfo, opts ...grpc.CallOption) (*CreateTokenRsp, error) { + out := new(CreateTokenRsp) + err := c.cc.Invoke(ctx, "/account.Account/CreateTokenHandler", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// AccountServer is the server API for Account service. +// All implementations must embed UnimplementedAccountServer +// for forward compatibility +type AccountServer interface { + RegisterHandler(context.Context, *Register) (*PubRsp, error) + CreateTokenHandler(context.Context, *AccountInfo) (*CreateTokenRsp, error) + mustEmbedUnimplementedAccountServer() +} + +// UnimplementedAccountServer must be embedded to have forward compatible implementations. +type UnimplementedAccountServer struct { +} + +func (UnimplementedAccountServer) RegisterHandler(context.Context, *Register) (*PubRsp, error) { + return nil, status.Errorf(codes.Unimplemented, "method RegisterHandler not implemented") +} +func (UnimplementedAccountServer) CreateTokenHandler(context.Context, *AccountInfo) (*CreateTokenRsp, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreateTokenHandler not implemented") +} +func (UnimplementedAccountServer) mustEmbedUnimplementedAccountServer() {} + +// UnsafeAccountServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to AccountServer will +// result in compilation errors. +type UnsafeAccountServer interface { + mustEmbedUnimplementedAccountServer() +} + +func RegisterAccountServer(s grpc.ServiceRegistrar, srv AccountServer) { + s.RegisterService(&Account_ServiceDesc, srv) +} + +func _Account_RegisterHandler_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(Register) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AccountServer).RegisterHandler(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/account.Account/RegisterHandler", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AccountServer).RegisterHandler(ctx, req.(*Register)) + } + return interceptor(ctx, in, info, handler) +} + +func _Account_CreateTokenHandler_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(AccountInfo) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AccountServer).CreateTokenHandler(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/account.Account/CreateTokenHandler", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AccountServer).CreateTokenHandler(ctx, req.(*AccountInfo)) + } + return interceptor(ctx, in, info, handler) +} + +// Account_ServiceDesc is the grpc.ServiceDesc for Account service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var Account_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "account.Account", + HandlerType: (*AccountServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "RegisterHandler", + Handler: _Account_RegisterHandler_Handler, + }, + { + MethodName: "CreateTokenHandler", + Handler: _Account_CreateTokenHandler_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "account.proto", +} diff --git a/protos/pb/game.pb.go b/protos/pb/game.pb.go new file mode 100644 index 0000000..b6382ab --- /dev/null +++ b/protos/pb/game.pb.go @@ -0,0 +1,334 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.26.0 +// protoc v3.17.3 +// source: game.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 Role struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Level int32 `protobuf:"varint,3,opt,name=level,proto3" json:"level,omitempty"` + LoginTime int64 `protobuf:"varint,4,opt,name=login_time,json=loginTime,proto3" json:"login_time,omitempty"` + Device string `protobuf:"bytes,5,opt,name=device,proto3" json:"device,omitempty"` + Uid int64 `protobuf:"varint,6,opt,name=uid,proto3" json:"uid,omitempty"` +} + +func (x *Role) Reset() { + *x = Role{} + if protoimpl.UnsafeEnabled { + mi := &file_game_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Role) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Role) ProtoMessage() {} + +func (x *Role) ProtoReflect() protoreflect.Message { + mi := &file_game_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 Role.ProtoReflect.Descriptor instead. +func (*Role) Descriptor() ([]byte, []int) { + return file_game_proto_rawDescGZIP(), []int{0} +} + +func (x *Role) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *Role) GetLevel() int32 { + if x != nil { + return x.Level + } + return 0 +} + +func (x *Role) GetLoginTime() int64 { + if x != nil { + return x.LoginTime + } + return 0 +} + +func (x *Role) GetDevice() string { + if x != nil { + return x.Device + } + return "" +} + +func (x *Role) GetUid() int64 { + if x != nil { + return x.Uid + } + return 0 +} + +type Token struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Token string `protobuf:"bytes,1,opt,name=token,proto3" json:"token,omitempty"` +} + +func (x *Token) Reset() { + *x = Token{} + if protoimpl.UnsafeEnabled { + mi := &file_game_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Token) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Token) ProtoMessage() {} + +func (x *Token) ProtoReflect() protoreflect.Message { + mi := &file_game_proto_msgTypes[1] + 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 Token.ProtoReflect.Descriptor instead. +func (*Token) Descriptor() ([]byte, []int) { + return file_game_proto_rawDescGZIP(), []int{1} +} + +func (x *Token) GetToken() string { + if x != nil { + return x.Token + } + return "" +} + +type RoleRsp struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Rsp *PubRsp `protobuf:"bytes,1,opt,name=rsp,proto3" json:"rsp,omitempty"` + Role *Role `protobuf:"bytes,2,opt,name=role,proto3" json:"role,omitempty"` +} + +func (x *RoleRsp) Reset() { + *x = RoleRsp{} + if protoimpl.UnsafeEnabled { + mi := &file_game_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RoleRsp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RoleRsp) ProtoMessage() {} + +func (x *RoleRsp) ProtoReflect() protoreflect.Message { + mi := &file_game_proto_msgTypes[2] + 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 RoleRsp.ProtoReflect.Descriptor instead. +func (*RoleRsp) Descriptor() ([]byte, []int) { + return file_game_proto_rawDescGZIP(), []int{2} +} + +func (x *RoleRsp) GetRsp() *PubRsp { + if x != nil { + return x.Rsp + } + return nil +} + +func (x *RoleRsp) GetRole() *Role { + if x != nil { + return x.Role + } + return nil +} + +var File_game_proto protoreflect.FileDescriptor + +var file_game_proto_rawDesc = []byte{ + 0x0a, 0x0a, 0x67, 0x61, 0x6d, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x04, 0x67, 0x61, + 0x6d, 0x65, 0x1a, 0x0c, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x22, 0x75, 0x0a, 0x04, 0x52, 0x6f, 0x6c, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x65, 0x76, 0x65, + 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x1d, + 0x0a, 0x0a, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x09, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x16, 0x0a, + 0x06, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, + 0x65, 0x76, 0x69, 0x63, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x03, 0x75, 0x69, 0x64, 0x22, 0x1d, 0x0a, 0x05, 0x54, 0x6f, 0x6b, 0x65, 0x6e, + 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x4b, 0x0a, 0x07, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x73, + 0x70, 0x12, 0x20, 0x0a, 0x03, 0x72, 0x73, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, + 0x2e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2e, 0x50, 0x75, 0x62, 0x52, 0x73, 0x70, 0x52, 0x03, + 0x72, 0x73, 0x70, 0x12, 0x1e, 0x0a, 0x04, 0x72, 0x6f, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x0a, 0x2e, 0x67, 0x61, 0x6d, 0x65, 0x2e, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x04, 0x72, + 0x6f, 0x6c, 0x65, 0x32, 0x9a, 0x01, 0x0a, 0x04, 0x47, 0x61, 0x6d, 0x65, 0x12, 0x31, 0x0a, 0x10, + 0x48, 0x65, 0x61, 0x72, 0x74, 0x42, 0x65, 0x61, 0x74, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, + 0x12, 0x0b, 0x2e, 0x67, 0x61, 0x6d, 0x65, 0x2e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x1a, 0x0e, 0x2e, + 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2e, 0x50, 0x75, 0x62, 0x52, 0x73, 0x70, 0x22, 0x00, 0x12, + 0x2c, 0x0a, 0x0c, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x12, + 0x0b, 0x2e, 0x67, 0x61, 0x6d, 0x65, 0x2e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x1a, 0x0d, 0x2e, 0x67, + 0x61, 0x6d, 0x65, 0x2e, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x73, 0x70, 0x22, 0x00, 0x12, 0x31, 0x0a, + 0x11, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6c, 0x65, 0x48, 0x61, 0x6e, 0x64, 0x6c, + 0x65, 0x72, 0x12, 0x0b, 0x2e, 0x67, 0x61, 0x6d, 0x65, 0x2e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x1a, + 0x0d, 0x2e, 0x67, 0x61, 0x6d, 0x65, 0x2e, 0x52, 0x6f, 0x6c, 0x65, 0x52, 0x73, 0x70, 0x22, 0x00, + 0x42, 0x09, 0x5a, 0x07, 0x2e, 0x2f, 0x70, 0x62, 0x3b, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, +} + +var ( + file_game_proto_rawDescOnce sync.Once + file_game_proto_rawDescData = file_game_proto_rawDesc +) + +func file_game_proto_rawDescGZIP() []byte { + file_game_proto_rawDescOnce.Do(func() { + file_game_proto_rawDescData = protoimpl.X.CompressGZIP(file_game_proto_rawDescData) + }) + return file_game_proto_rawDescData +} + +var file_game_proto_msgTypes = make([]protoimpl.MessageInfo, 3) +var file_game_proto_goTypes = []interface{}{ + (*Role)(nil), // 0: game.Role + (*Token)(nil), // 1: game.Token + (*RoleRsp)(nil), // 2: game.RoleRsp + (*PubRsp)(nil), // 3: public.PubRsp +} +var file_game_proto_depIdxs = []int32{ + 3, // 0: game.RoleRsp.rsp:type_name -> public.PubRsp + 0, // 1: game.RoleRsp.role:type_name -> game.Role + 1, // 2: game.Game.HeartBeatHandler:input_type -> game.Token + 1, // 3: game.Game.LoginHandler:input_type -> game.Token + 1, // 4: game.Game.CreateRoleHandler:input_type -> game.Token + 3, // 5: game.Game.HeartBeatHandler:output_type -> public.PubRsp + 2, // 6: game.Game.LoginHandler:output_type -> game.RoleRsp + 2, // 7: game.Game.CreateRoleHandler:output_type -> game.RoleRsp + 5, // [5:8] is the sub-list for method output_type + 2, // [2:5] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name +} + +func init() { file_game_proto_init() } +func file_game_proto_init() { + if File_game_proto != nil { + return + } + file_public_proto_init() + if !protoimpl.UnsafeEnabled { + file_game_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Role); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_game_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Token); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_game_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RoleRsp); 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_game_proto_rawDesc, + NumEnums: 0, + NumMessages: 3, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_game_proto_goTypes, + DependencyIndexes: file_game_proto_depIdxs, + MessageInfos: file_game_proto_msgTypes, + }.Build() + File_game_proto = out.File + file_game_proto_rawDesc = nil + file_game_proto_goTypes = nil + file_game_proto_depIdxs = nil +} diff --git a/protos/pb/game_grpc.pb.go b/protos/pb/game_grpc.pb.go new file mode 100644 index 0000000..07dc7e9 --- /dev/null +++ b/protos/pb/game_grpc.pb.go @@ -0,0 +1,177 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.2.0 +// - protoc v3.17.3 +// source: game.proto + +package pb + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// GameClient is the client API for Game service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type GameClient interface { + HeartBeatHandler(ctx context.Context, in *Token, opts ...grpc.CallOption) (*PubRsp, error) + LoginHandler(ctx context.Context, in *Token, opts ...grpc.CallOption) (*RoleRsp, error) + CreateRoleHandler(ctx context.Context, in *Token, opts ...grpc.CallOption) (*RoleRsp, error) +} + +type gameClient struct { + cc grpc.ClientConnInterface +} + +func NewGameClient(cc grpc.ClientConnInterface) GameClient { + return &gameClient{cc} +} + +func (c *gameClient) HeartBeatHandler(ctx context.Context, in *Token, opts ...grpc.CallOption) (*PubRsp, error) { + out := new(PubRsp) + err := c.cc.Invoke(ctx, "/game.Game/HeartBeatHandler", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *gameClient) LoginHandler(ctx context.Context, in *Token, opts ...grpc.CallOption) (*RoleRsp, error) { + out := new(RoleRsp) + err := c.cc.Invoke(ctx, "/game.Game/LoginHandler", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *gameClient) CreateRoleHandler(ctx context.Context, in *Token, opts ...grpc.CallOption) (*RoleRsp, error) { + out := new(RoleRsp) + err := c.cc.Invoke(ctx, "/game.Game/CreateRoleHandler", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// GameServer is the server API for Game service. +// All implementations must embed UnimplementedGameServer +// for forward compatibility +type GameServer interface { + HeartBeatHandler(context.Context, *Token) (*PubRsp, error) + LoginHandler(context.Context, *Token) (*RoleRsp, error) + CreateRoleHandler(context.Context, *Token) (*RoleRsp, error) + mustEmbedUnimplementedGameServer() +} + +// UnimplementedGameServer must be embedded to have forward compatible implementations. +type UnimplementedGameServer struct { +} + +func (UnimplementedGameServer) HeartBeatHandler(context.Context, *Token) (*PubRsp, error) { + return nil, status.Errorf(codes.Unimplemented, "method HeartBeatHandler not implemented") +} +func (UnimplementedGameServer) LoginHandler(context.Context, *Token) (*RoleRsp, error) { + return nil, status.Errorf(codes.Unimplemented, "method LoginHandler not implemented") +} +func (UnimplementedGameServer) CreateRoleHandler(context.Context, *Token) (*RoleRsp, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreateRoleHandler not implemented") +} +func (UnimplementedGameServer) mustEmbedUnimplementedGameServer() {} + +// UnsafeGameServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to GameServer will +// result in compilation errors. +type UnsafeGameServer interface { + mustEmbedUnimplementedGameServer() +} + +func RegisterGameServer(s grpc.ServiceRegistrar, srv GameServer) { + s.RegisterService(&Game_ServiceDesc, srv) +} + +func _Game_HeartBeatHandler_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(Token) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(GameServer).HeartBeatHandler(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/game.Game/HeartBeatHandler", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(GameServer).HeartBeatHandler(ctx, req.(*Token)) + } + return interceptor(ctx, in, info, handler) +} + +func _Game_LoginHandler_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(Token) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(GameServer).LoginHandler(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/game.Game/LoginHandler", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(GameServer).LoginHandler(ctx, req.(*Token)) + } + return interceptor(ctx, in, info, handler) +} + +func _Game_CreateRoleHandler_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(Token) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(GameServer).CreateRoleHandler(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/game.Game/CreateRoleHandler", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(GameServer).CreateRoleHandler(ctx, req.(*Token)) + } + return interceptor(ctx, in, info, handler) +} + +// Game_ServiceDesc is the grpc.ServiceDesc for Game service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var Game_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "game.Game", + HandlerType: (*GameServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "HeartBeatHandler", + Handler: _Game_HeartBeatHandler_Handler, + }, + { + MethodName: "LoginHandler", + Handler: _Game_LoginHandler_Handler, + }, + { + MethodName: "CreateRoleHandler", + Handler: _Game_CreateRoleHandler_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "game.proto", +} diff --git a/protos/pb/public.pb.go b/protos/pb/public.pb.go new file mode 100644 index 0000000..b1bf0f0 --- /dev/null +++ b/protos/pb/public.pb.go @@ -0,0 +1,212 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.26.0 +// protoc v3.17.3 +// source: public.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 PubRsp struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Code int32 `protobuf:"varint,1,opt,name=code,proto3" json:"code,omitempty"` + Msg string `protobuf:"bytes,2,opt,name=msg,proto3" json:"msg,omitempty"` +} + +func (x *PubRsp) Reset() { + *x = PubRsp{} + if protoimpl.UnsafeEnabled { + mi := &file_public_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PubRsp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PubRsp) ProtoMessage() {} + +func (x *PubRsp) ProtoReflect() protoreflect.Message { + mi := &file_public_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 PubRsp.ProtoReflect.Descriptor instead. +func (*PubRsp) Descriptor() ([]byte, []int) { + return file_public_proto_rawDescGZIP(), []int{0} +} + +func (x *PubRsp) GetCode() int32 { + if x != nil { + return x.Code + } + return 0 +} + +func (x *PubRsp) GetMsg() string { + if x != nil { + return x.Msg + } + return "" +} + +type GenerateToken struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Phone string `protobuf:"bytes,1,opt,name=phone,proto3" json:"phone,omitempty"` +} + +func (x *GenerateToken) Reset() { + *x = GenerateToken{} + if protoimpl.UnsafeEnabled { + mi := &file_public_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GenerateToken) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GenerateToken) ProtoMessage() {} + +func (x *GenerateToken) ProtoReflect() protoreflect.Message { + mi := &file_public_proto_msgTypes[1] + 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 GenerateToken.ProtoReflect.Descriptor instead. +func (*GenerateToken) Descriptor() ([]byte, []int) { + return file_public_proto_rawDescGZIP(), []int{1} +} + +func (x *GenerateToken) GetPhone() string { + if x != nil { + return x.Phone + } + return "" +} + +var File_public_proto protoreflect.FileDescriptor + +var file_public_proto_rawDesc = []byte{ + 0x0a, 0x0c, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x06, + 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x22, 0x2e, 0x0a, 0x06, 0x50, 0x75, 0x62, 0x52, 0x73, 0x70, + 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, + 0x63, 0x6f, 0x64, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x03, 0x6d, 0x73, 0x67, 0x22, 0x25, 0x0a, 0x0d, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, + 0x74, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x68, 0x6f, 0x6e, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x42, 0x09, 0x5a, + 0x07, 0x2e, 0x2f, 0x70, 0x62, 0x3b, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_public_proto_rawDescOnce sync.Once + file_public_proto_rawDescData = file_public_proto_rawDesc +) + +func file_public_proto_rawDescGZIP() []byte { + file_public_proto_rawDescOnce.Do(func() { + file_public_proto_rawDescData = protoimpl.X.CompressGZIP(file_public_proto_rawDescData) + }) + return file_public_proto_rawDescData +} + +var file_public_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_public_proto_goTypes = []interface{}{ + (*PubRsp)(nil), // 0: public.PubRsp + (*GenerateToken)(nil), // 1: public.GenerateToken +} +var file_public_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_public_proto_init() } +func file_public_proto_init() { + if File_public_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_public_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PubRsp); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_public_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GenerateToken); 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_public_proto_rawDesc, + NumEnums: 0, + NumMessages: 2, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_public_proto_goTypes, + DependencyIndexes: file_public_proto_depIdxs, + MessageInfos: file_public_proto_msgTypes, + }.Build() + File_public_proto = out.File + file_public_proto_rawDesc = nil + file_public_proto_goTypes = nil + file_public_proto_depIdxs = nil +} diff --git a/protos/public.proto b/protos/public.proto new file mode 100644 index 0000000..f78af68 --- /dev/null +++ b/protos/public.proto @@ -0,0 +1,13 @@ +syntax = "proto3"; +package public; + +option go_package = "./pb;pb"; + +message PubRsp { + int32 code = 1; + string msg = 2; +} + +message GenerateToken { + string phone = 1; +} \ No newline at end of file diff --git a/test/client.go b/test/client.go new file mode 100644 index 0000000..5dff92d --- /dev/null +++ b/test/client.go @@ -0,0 +1,80 @@ +package main + +import ( + "context" + "fmt" + "google.golang.org/grpc" + _ "pro2d/conf" + "pro2d/protos/pb" + "pro2d/utils" +) + +func Register(c pb.AccountClient, phone, password string) error { + r, err := c.RegisterHandler(context.Background(), &pb.Register{ + Phone: "17683852936", + Password: "123456", + Code: 0, + }) + + if err != nil { + return err + } + if r.Code != 0 { + return fmt.Errorf("%s", r.Msg) + } + utils.Sugar.Debug("register success") + return nil +} + +func Login(loginUri, token string) { + gameConn, err := grpc.Dial(loginUri, grpc.WithInsecure() ) + if err != nil { + utils.Sugar.Errorf("game conn err: %v", err) + return + } + defer gameConn.Close() + + client:= pb.NewGameClient(gameConn) + loginRsp, err := client.LoginHandler(context.Background(), &pb.Token{ + Token: token, + }) + + if err != nil { + utils.Sugar.Errorf("login error: %v", err) + return + } + + print(loginRsp) + + createRole, err := client.CreateRoleHandler(context.Background(), &pb.Token{Token: token}) + if err != nil { + utils.Sugar.Errorf("create role err: %v", err) + return + } + print(createRole) + + utils.Sugar.Debug("login rsp: ", createRole.Rsp.Code, createRole.Rsp.Msg) +} + +func main() { + conn, err := grpc.Dial("localhost:8848", grpc.WithInsecure()) + if err != nil { + utils.Sugar.Errorf("conn err: %v", err) + return + } + defer conn.Close() + c := pb.NewAccountClient(conn) + //err = Register(c,"17683852936", "123456") + //if err != nil { + // utils.Sugar.Errorf("register err: %v", err) + // return + //} + rsp, err := c.CreateTokenHandler(context.Background(), &pb.AccountInfo{ + Phone: "17683852936", + Password: "123456", + }) + + Login(rsp.GameService.Address, rsp.Token) + + +} diff --git a/utils/common.go b/utils/common.go new file mode 100644 index 0000000..9fd1e1a --- /dev/null +++ b/utils/common.go @@ -0,0 +1,11 @@ +package utils + +const ( + Pro2DTokenSignedString = "Pro2DSecret" + + ACCOUNTDB = "account" + ACCOUNT = "account" + + GAMEDB = "game" + ROLET = "role" +) diff --git a/utils/jwt.go b/utils/jwt.go new file mode 100644 index 0000000..aa56471 --- /dev/null +++ b/utils/jwt.go @@ -0,0 +1,98 @@ +package utils + +import ( + "context" + "fmt" + "pro2d/protos/pb" + "time" + + jwt "github.com/dgrijalva/jwt-go" + "google.golang.org/grpc/metadata" +) + +func CreateToken(account *pb.AccountInfo) (tokenString string) { + token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{ + "iss": "pro2d-app-server", + "aud": "pro2d-app-server", + "nbf": time.Now().Unix(), + "exp": time.Now().Add(time.Hour).Unix(), + "sub": "pro2d", + "phone": account.Phone, + "uid": account.Uid, + "device": account.Device, + }) + tokenString, err := token.SignedString([]byte(Pro2DTokenSignedString)) + if err != nil { + panic(err) + } + return tokenString +} + +func ParseToken(tokenStr string)*pb.AccountInfo { + var clientClaims Claims + token, err := jwt.ParseWithClaims(tokenStr, &clientClaims, func(token *jwt.Token) (interface{}, error) { + if token.Header["alg"] != "HS256" { + //panic("ErrInvalidAlgorithm") + Sugar.Error("ErrInvalidAlgorithm") + return nil, nil + } + return []byte(Pro2DTokenSignedString), nil + }) + if err != nil { + Sugar.Error("jwt parse error") + return nil + } + + if !token.Valid { + Sugar.Error("ErrInvalidToken") + return nil + } + return &clientClaims.AccountInfo +} + +// AuthToken 自定义认证 +type AuthToken struct { + Token string +} + +func (c AuthToken) GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error) { + return map[string]string{ + "authorization": c.Token, + }, nil +} + +func (c AuthToken) RequireTransportSecurity() bool { + return false +} + +// Claims defines the struct containing the token claims. +type Claims struct { + jwt.StandardClaims + //phone string `json:"phone"` + //uid int64 `json:"uid"` + //device string `json:"device"` + pb.AccountInfo +} + +// 从 context 的 metadata 中,取出 token +func getTokenFromContext(ctx context.Context) (string, error) { + md, ok := metadata.FromIncomingContext(ctx) + if !ok { + return "", fmt.Errorf("ErrNoMetadataInContext") + } + // md 的类型是 type MD map[string][]string + token, ok := md["authorization"] + if !ok || len(token) == 0 { + return "", fmt.Errorf("ErrNoAuthorizationInMetadata") + } + // 因此,token 是一个字符串数组,我们只用了 token[0] + return token[0], nil +} + +func CheckAuth(ctx context.Context) *pb.AccountInfo { + tokenStr, err := getTokenFromContext(ctx) + if err != nil { + panic("get token from context error") + } + return ParseToken(tokenStr) +} \ No newline at end of file diff --git a/utils/jwt_test.go b/utils/jwt_test.go new file mode 100644 index 0000000..55e809c --- /dev/null +++ b/utils/jwt_test.go @@ -0,0 +1,19 @@ +package utils + +import ( + "fmt" + "pro2d/protos/pb" + "testing" +) + +func TestCreateToken(t *testing.T) { + account := &pb.AccountInfo{ + Phone: "17683852936", + Password: "123456", + Uid: 12312, + Device: "12312312", + } + token := CreateToken(account) + ac := ParseToken(token) + fmt.Println("token: ", token, "\nac: ", ac) +} diff --git a/utils/logger.go b/utils/logger.go new file mode 100644 index 0000000..8528c45 --- /dev/null +++ b/utils/logger.go @@ -0,0 +1,107 @@ +package utils + +import ( + "go.uber.org/zap" + "go.uber.org/zap/zapcore" + lumberjack "gopkg.in/natefinch/lumberjack.v2" + "net/http" + "os" +) + +var Sugar *zap.SugaredLogger +var Logger *zap.Logger + +func InitLogger(conf *lumberjack.Logger) { + writeSyncer := zapcore.NewMultiWriteSyncer(zapcore.AddSync(os.Stdout), zapcore.AddSync(conf)) //控制台和日志同时输出 + encoder := getEncoder() + core := zapcore.NewCore(encoder, writeSyncer, zapcore.DebugLevel) + + Logger = zap.New(core, zap.AddCaller()) + Sugar = Logger.Sugar() +} + +func getEncoder() zapcore.Encoder { + encoderConfig := zap.NewProductionEncoderConfig() + encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder + encoderConfig.EncodeLevel = zapcore.CapitalColorLevelEncoder + return zapcore.NewConsoleEncoder(encoderConfig) +} + +func simpleHttpGet(url string) { + Sugar.Debugf("Trying to hit GET request for %s", url) + resp, err := http.Get(url) + if err != nil { + Sugar.Errorf("Error fetching URL %s : Error = %s", url, err) + } else { + Sugar.Infof("Success! statusCode = %s for URL %s", resp.Status, url) + resp.Body.Close() + } +} + +func LogTest() { + lumberJackLogger := &lumberjack.Logger{ + Filename: "./pro2d.log", // ⽇志⽂件路径 + MaxSize: 1024, // 1M=1024KB=1024000byte + MaxBackups: 5, // 最多保留5个备份 + MaxAge: 30, // days + Compress: true, // 是否压缩 disabled by default + } + + InitLogger(lumberJackLogger) + defer Logger.Sync() + for i:=0; i < 10000;i++ { + simpleHttpGet("www.baidu.com") + simpleHttpGet("http://www.baidu.com") + } +} + +//--使用sink 结合es使用 +//func registerSinkDemo() { +// zap.RegisterSink("mq", mq.NewMqSink) +// writer, close, err := zap.Open("mq://192.168.99.100:9876/log") +// if err != nil { +// panic(err) +// } +// defer close() +// logger := zap.New(zapcore.NewCore(zapcore.NewJSONEncoder(zap.NewProductionEncoderConfig()), writer, zap.DebugLevel)).Sugar() +// logger.Info("hello") +//} +// +//type MqWriteSyncer struct { +// topic string +// producer rocketmq.Producer +// ctx context.Context +//} +// +//func (m *MqWriteSyncer) Close() error { +// return m.producer.Shutdown() +//} +// +//func (m *MqWriteSyncer) Write(p []byte) (n int, err error) { +// msg := &primitive.Message{ +// Topic: m.topic, +// Body: p, +// } +// err = m.producer.SendOneWay(m.ctx, msg) +// return len(p), err +//} +// +//func (m *MqWriteSyncer) Sync() error { +// return nil +//} +// +//func NewMqSink(url *url.URL) (zap.Sink, error) { +// broker := fmt.Sprintf("%s:%s", url.Hostname(), url.Port()) +// topic := url.Path[1:len(url.Path)] +// p, _ := rocketmq.NewProducer( +// producer.WithNameServer([]string{broker}), +// producer.WithRetry(2), +// ) +// err := p.Start() +// if err != nil { +// fmt.Printf("start producer error: %s", err.Error()) +// return nil, err +// } +// +// return &MqWriteSyncer{producer: p, ctx: context.Background(), topic: topic}, nil +//} \ No newline at end of file diff --git a/utils/md5.go b/utils/md5.go new file mode 100644 index 0000000..ce94156 --- /dev/null +++ b/utils/md5.go @@ -0,0 +1,12 @@ +package utils + +import ( + "crypto/md5" + "encoding/hex" +) + +func Md5V(str string) string { + h := md5.New() + h.Write([]byte(str)) + return hex.EncodeToString(h.Sum(nil)) +} \ No newline at end of file diff --git a/utils/snowflake.go b/utils/snowflake.go new file mode 100644 index 0000000..3b94ba5 --- /dev/null +++ b/utils/snowflake.go @@ -0,0 +1,76 @@ +package utils + +import ( + "fmt" + "github.com/golang/glog" + "sync" + "time" +) + +type Snowflake struct { + *sync.Mutex // 锁 + timestamp int64 // 时间戳 ,毫秒 + workerid int64 // 工作节点 + datacenterid int64 // 数据中心机房id + sequence int64 // 序列号 +} +const ( + epoch = int64(1577808000000) // 设置起始时间(时间戳/毫秒):2020-01-01 00:00:00,有效期69年 + timestampBits = uint(41) // 时间戳占用位数 + datacenteridBits = uint(2) // 数据中心id所占位数 + workeridBits = uint(7) // 机器id所占位数 + sequenceBits = uint(12) // 序列所占的位数 + timestampMax = int64(-1 ^ (-1 << timestampBits)) // 时间戳最大值 + datacenteridMax = int64(-1 ^ (-1 << datacenteridBits)) // 支持的最大数据中心id数量 + workeridMax = int64(-1 ^ (-1 << workeridBits)) // 支持的最大机器id数量 + sequenceMask = int64(-1 ^ (-1 << sequenceBits)) // 支持的最大序列id数量 + workeridShift = sequenceBits // 机器id左移位数 + datacenteridShift = sequenceBits + workeridBits // 数据中心id左移位数 + timestampShift = sequenceBits + workeridBits + datacenteridBits // 时间戳左移位数 +) + + + +func NewSnowflake(workerid, datacenterid int64) *Snowflake { + return &Snowflake{ + Mutex: new(sync.Mutex), + timestamp: time.Now().UnixNano() / 1000000, + workerid: workerid, + datacenterid: datacenterid, + sequence: 0, + } +} + +func (s *Snowflake) NextValStr() string { + return fmt.Sprintf("%d", s.NextVal()) +} + + +func (s *Snowflake) NextVal() int64 { + s.Lock() + now := time.Now().UnixNano() / 1000000 // 转毫秒 + if s.timestamp == now { + // 当同一时间戳(精度:毫秒)下多次生成id会增加序列号 + s.sequence = (s.sequence + 1) & sequenceMask + if s.sequence == 0 { + // 如果当前序列超出12bit长度,则需要等待下一毫秒 + // 下一毫秒将使用sequence:0 + for now <= s.timestamp { + now = time.Now().UnixNano() / 1000000 + } + } + } else { + // 不同时间戳(精度:毫秒)下直接使用序列号:0 + s.sequence = 0 + } + t := now - epoch + if t > timestampMax { + s.Unlock() + glog.Errorf("epoch must be between 0 and %d", timestampMax-1) + return 0 + } + s.timestamp = now + r := int64((t)<