diff --git a/Makefile b/Makefile index 39371f3..3a3c03d 100644 --- a/Makefile +++ b/Makefile @@ -9,14 +9,14 @@ gen: test: go run test/client.go http: - go run cmd/http.go + go run -race cmd/http.go game: - go run cmd/game.go + go run -race cmd/game.go build: - go build -o bin/account cmd/http.go - go build -o bin/game cmd/game.go - go build -o bin/test test/client.go + go build -race -o bin/account cmd/http.go + go build -race -o bin/game cmd/game.go + go build -race -o bin/test test/client.go regame:plugin lsof -i:8849 | grep "game" | grep -v grep | awk '{print $$2}' | xargs -I {} kill -USR1 {} diff --git a/src/actions/AccountAction.go b/src/actions/AccountAction.go index a2e3680..5e5bfcd 100644 --- a/src/actions/AccountAction.go +++ b/src/actions/AccountAction.go @@ -26,7 +26,7 @@ func (h *AccountAction) Register(c *gin.Context) (int, interface{}){ account.Uid = conf.SnowFlack.NextValStr() account.Password = utils.Md5V(register.Password) - if _, err := account.Create(); err != nil{ + if err := account.Create(); err != nil{ return -3, "account register err: " + err.Error() } account.Password = register.Password diff --git a/src/common/common.go b/src/common/common.go index e8528f1..1d27e7b 100644 --- a/src/common/common.go +++ b/src/common/common.go @@ -16,6 +16,6 @@ const ( WheelSize = 3600 //心跳 - HEART_TIMER_INTERVAL = 5 //s - HEART_TIMEOUT_COUNT_MAX = 20 //最大超时次数 + HeartTimerInterval = 5 //s + HeartTimeoutCountMax = 20 //最大超时次数 ) diff --git a/src/components/db/mongo.go b/src/components/db/mongo.go index befd4a6..cae34e7 100644 --- a/src/components/db/mongo.go +++ b/src/components/db/mongo.go @@ -76,8 +76,7 @@ func SetUnique(collection string, key string) (string, error) { type MgoColl struct { collection *mongo.Collection - pri interface{} - schema interface{} + schema *Schema } func GetBsonD(key string, value interface{}) interface{} { @@ -87,10 +86,9 @@ func GetBsonM(key string, value interface{}) interface{} { return bson.M{key: value} } -func NewMongoColl(key string, schema interface{}) *MgoColl { +func NewMongoColl(schema *Schema) *MgoColl { return &MgoColl{ - collection: MongoDatabase.Collection(utils.GetCollName(schema)), - pri: GetBsonM(utils.GetPriKey(schema), key), + collection: MongoDatabase.Collection(schema.GetCollName()), schema: schema, } } @@ -196,7 +194,7 @@ func (m *MgoColl) FindOneAndUpdate(filter interface{}, update interface{})*mongo } func (m *MgoColl) UpdateOne(filter interface{}, update interface{})*mongo.UpdateResult { - res, err := m.collection.UpdateOne(context.TODO(), filter, update) + res, err := m.collection.UpdateOne(context.TODO(), filter, bson.D{{"$set", update}}) if err != nil { return nil } @@ -204,10 +202,9 @@ func (m *MgoColl) UpdateOne(filter interface{}, update interface{})*mongo.Update return res } - func (m *MgoColl) Load() error{ - r := m.collection.FindOne(context.TODO(), m.pri) - err := r.Decode(m.schema) + r := m.collection.FindOne(context.TODO(), m.schema.GetPri()) + err := r.Decode(m.schema.GetSchema()) if err != nil { return err } @@ -215,17 +212,13 @@ func (m *MgoColl) Load() error{ } func (m *MgoColl) Create() (*mongo.InsertOneResult, error){ - return m.collection.InsertOne(context.TODO(), m.schema) -} - -func (m *MgoColl) Update(update interface{}) { - m.FindOneAndUpdate(m.pri, update) + return m.collection.InsertOne(context.TODO(), m.schema.GetSchema()) } func (m *MgoColl) UpdateProperty(key string, val interface{}) { - m.FindOneAndUpdate(m.pri, bson.M{strings.ToLower(key): val}) + m.UpdateOne(m.schema.GetPri(), bson.M{strings.ToLower(key): val}) } -func (m *MgoColl)Save() { - m.FindOneAndUpdate(m.pri, m.schema) -} \ No newline at end of file +func (m *MgoColl) UpdateProperties(properties map[string]interface{}) { + m.UpdateOne(m.schema.GetPri(), properties) +} diff --git a/src/components/db/schema.go b/src/components/db/schema.go index b2847d0..9a67d6b 100644 --- a/src/components/db/schema.go +++ b/src/components/db/schema.go @@ -6,38 +6,74 @@ import ( ) type Schema struct { - reflect.Type + mgo *MgoColl + reflectValue *reflect.Value + reflectType reflect.Type + + pri interface{} schema interface{} } -func NewSchema(pri, schema interface{}) *Schema { - s := reflect.TypeOf(schema) +func NewSchema(key string, schema interface{}) *Schema { + s := reflect.ValueOf(schema) if s.Kind() == reflect.Ptr { - s = reflect.TypeOf(s).Elem() + s = reflect.ValueOf(schema).Elem() } - return &Schema{ - Type: s, - pri: pri, + sch := &Schema{ + reflectValue: &s, + reflectType: s.Type(), schema: schema, } + sch.mgo = NewMongoColl(sch) + sch.pri = GetBsonD(sch.getPriTag(), key) + return sch } -func (s *Schema)GetSchemaType() reflect.Type { - return s.Type +func (s *Schema) GetSchemaType() reflect.Type { + return s.reflectType } -func (s *Schema)GetCollName() string { +func (s *Schema) GetCollName() string { return strings.ToLower(s.GetSchemaType().Name()) } -func (s *Schema)GetPriKey() string { +func (s *Schema) getPriTag() string { var pri string - for i := 0; i < s.NumField(); i++ { - if s.Field(i).Tag.Get("pri") == "1" { - pri = strings.ToLower(s.Field(i).Name) + for i := 0; i < s.reflectType.NumField(); i++ { + if s.reflectType.Field(i).Tag.Get("pri") == "1" { + pri = strings.ToLower(s.reflectType.Field(i).Name) break } } return pri } + +func (s *Schema) GetPri() interface{} { + return s.pri +} + +func (s *Schema) GetSchema() interface{} { + return s.schema +} + +func (s *Schema) Load() error { + return s.mgo.Load() +} + +func (s *Schema) Create() error { + _, err := s.mgo.Create() + return err +} + +func (s *Schema) UpdateProperty(key string, val interface{}) { + s.reflectValue.FieldByName(key).Set(reflect.ValueOf(val)) + s.mgo.UpdateProperty(key, val) +} + +func (s *Schema) UpdateProperties(properties map[string]interface{}) { + for key, val := range properties { + s.reflectValue.FieldByName(key).Set(reflect.ValueOf(val)) + } + s.mgo.UpdateProperties(properties) +} diff --git a/src/components/jwt/jwt.go b/src/components/jwt/jwt.go deleted file mode 100644 index 6662675..0000000 --- a/src/components/jwt/jwt.go +++ /dev/null @@ -1,96 +0,0 @@ -package jwt - -import ( - "context" - "fmt" - "pro2d/src/common" - "pro2d/src/components/logger" - "time" - - jwt "github.com/dgrijalva/jwt-go" - "google.golang.org/grpc/metadata" -) - -func CreateToken(uid string) (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", - "uid": uid, - }) - tokenString, err := token.SignedString([]byte(common.Pro2DTokenSignedString)) - if err != nil { - panic(err) - } - return tokenString -} - -func ParseToken(tokenStr string) string { - var clientClaims Claims - token, err := jwt.ParseWithClaims(tokenStr, &clientClaims, func(token *jwt.Token) (interface{}, error) { - if token.Header["alg"] != "HS256" { - //panic("ErrInvalidAlgorithm") - logger.Error("ErrInvalidAlgorithm") - return nil, nil - } - return []byte(common.Pro2DTokenSignedString), nil - }) - if err != nil { - logger.Error("jwt parse error") - return "" - } - - if !token.Valid { - logger.Error("ErrInvalidToken") - return "" - } - return clientClaims.Uid -} - - -// Claims defines the struct containing the token claims. -type Claims struct { - jwt.StandardClaims - Uid string -} - -// 从 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) string { - tokenStr, err := getTokenFromContext(ctx) - if err != nil { - logger.Error("get token from context error") - return "" - } - return ParseToken(tokenStr) -} - -// 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 -} \ No newline at end of file diff --git a/src/components/jwt/jwt_test.go b/src/components/jwt/jwt_test.go deleted file mode 100644 index ecc2eb7..0000000 --- a/src/components/jwt/jwt_test.go +++ /dev/null @@ -1,18 +0,0 @@ -package jwt - -import ( - "fmt" - "pro2d/protos/pb" - "testing" -) - -func TestCreateToken(t *testing.T) { - account := &pb.Account{ - Phone: "17683852936", - Password: "123456", - Uid: "12312", - } - token := CreateToken(account.Uid) - ac := ParseToken(token) - fmt.Println("token: ", token, "\nac: ", ac) -} diff --git a/src/components/net/conn.go b/src/components/net/conn.go index 253fabf..80fbfaf 100644 --- a/src/components/net/conn.go +++ b/src/components/net/conn.go @@ -28,7 +28,6 @@ type Connection struct { writer *bufio.Writer WBuffer chan []byte - RBuffer chan *MsgPkg Quit chan *Connection @@ -52,7 +51,6 @@ func NewConn(id int, conn net.Conn, s *Server) *Connection { scanner: bufio.NewScanner(conn), writer: bufio.NewWriter(conn), WBuffer: make(chan []byte), - RBuffer: make(chan *MsgPkg), Quit: make(chan *Connection), lastHeartCheckTime: utils.Timex(), heartTimeoutCount: 0, @@ -99,18 +97,16 @@ func (c *Connection) read() { if err := c.scanner.Err(); err != nil { fmt.Printf("scanner.err: %s\n", err.Error()) - c.Quiting() return } } - func (c *Connection) checkHeartBeat(now int64) { lastHeartCheckTime := atomic.LoadInt64(&c.lastHeartCheckTime) logger.Debug("checkHeartBeat ID: %d, last: %d, now: %d", c.Id, lastHeartCheckTime, now) - if math.Abs(float64(lastHeartCheckTime - now)) > common.HEART_TIMER_INTERVAL { + if math.Abs(float64(lastHeartCheckTime - now)) > common.HeartTimerInterval { c.heartTimeoutCount++ - if c.heartTimeoutCount >= common.HEART_TIMEOUT_COUNT_MAX { + if c.heartTimeoutCount >= common.HeartTimeoutCountMax { c.Quiting() return } @@ -125,31 +121,18 @@ func (c *Connection) update() { now := utils.Timex() if now >= nextCheckTime { c.checkHeartBeat(now) - nextCheckTime = now + common.HEART_TIMER_INTERVAL + nextCheckTime = now + common.HeartTimerInterval atomic.StoreInt64(&c.nextCheckTime, nextCheckTime) } } -// -//func (c *Connection) SetLastHeartCheckTime() { -// now := utils.Timex() -// lastHeartCheckTime := atomic.LoadInt64(&c.lastHeartCheckTime) -// if now - lastHeartCheckTime < common.HEART_TIMER_INTERVAL { -// logger.Debug("heart too quick") -// } -// atomic.StoreInt64(&c.lastHeartCheckTime, now) -//} + func (c *Connection) Start() { go c.write() go c.read() - //for { - // c.SendMsgByCode(100, 1, nil) - // time.Sleep(2*time.Second) - //} } func (c *Connection) Stop() { - close(c.RBuffer) c.Conn.Close() } diff --git a/src/components/timewheel/timerwheel.go b/src/components/timewheel/timerwheel.go index 7339f3c..b6fd1b9 100644 --- a/src/components/timewheel/timerwheel.go +++ b/src/components/timewheel/timerwheel.go @@ -99,7 +99,7 @@ func NewTimeWheel() *TimeWheel { func (tw *TimeWheel) add(t *timer) bool { time := t.expiration - currentTime := tw.time + currentTime := atomic.LoadUint32(&tw.time) if time <= currentTime { return false } @@ -136,8 +136,7 @@ func (tw *TimeWheel) moveList(level, idx int) { func (tw *TimeWheel) shift() { mask := TimeNear - tw.time++ - ct := tw.time + ct := atomic.AddUint32(&tw.time, 1) if ct == 0 { tw.moveList(3, 0) }else { diff --git a/src/models/account.go b/src/models/account.go index c337784..4152174 100644 --- a/src/models/account.go +++ b/src/models/account.go @@ -6,7 +6,7 @@ import ( ) type AccountModel struct { - *db.MgoColl + *db.Schema *pb.Account } @@ -23,7 +23,7 @@ func NewAccount(phone string) *AccountModel { Phone: phone, } account := &AccountModel{ - MgoColl: db.NewMongoColl(phone, ac), + Schema: db.NewSchema(phone, ac), Account: ac, } diff --git a/src/models/equip.go b/src/models/equip.go index 790e3a1..bc9154d 100644 --- a/src/models/equip.go +++ b/src/models/equip.go @@ -3,20 +3,19 @@ package models import ( "pro2d/protos/pb" "pro2d/src/components/db" - "strconv" ) type EquipModels struct { - *db.MgoColl + *db.Schema Equip *pb.Equipment } -func NewEquip(id int64) *EquipModels { +func NewEquip(id string) *EquipModels { data := &pb.Equipment{ Id: id, } m := &EquipModels{ - MgoColl: db.NewMongoColl(strconv.Itoa(int(id)), data), + Schema: db.NewSchema(id, data), Equip: data, } diff --git a/src/models/hero.go b/src/models/hero.go index 7ce56a2..4c82106 100644 --- a/src/models/hero.go +++ b/src/models/hero.go @@ -3,11 +3,10 @@ package models import ( "pro2d/protos/pb" "pro2d/src/components/db" - "strconv" ) type HeroModel struct { - *db.MgoColl + *db.Schema Hero *pb.Hero } type HeroMap map[string]*HeroModel @@ -20,12 +19,12 @@ func GetHeros(hm HeroMap) map[string]*pb.Hero { return h } -func NewHero(id int64) *HeroModel { +func NewHero(id string) *HeroModel { h := &pb.Hero{ Id: id, } m := &HeroModel{ - MgoColl: db.NewMongoColl(strconv.Itoa(int(id)), h), + Schema: db.NewSchema(id, h), Hero: h, } return m diff --git a/src/models/prop.go b/src/models/prop.go index ce3901c..ae7159f 100644 --- a/src/models/prop.go +++ b/src/models/prop.go @@ -3,20 +3,19 @@ package models import ( "pro2d/protos/pb" "pro2d/src/components/db" - "strconv" ) type PropModels struct { - *db.MgoColl + *db.Schema Prop *pb.Prop } -func NewProp(id int64) *PropModels { +func NewProp(id string) *PropModels { data := &pb.Prop{ Id: id, } m := &PropModels{ - MgoColl: db.NewMongoColl(strconv.Itoa(int(id)), data), + Schema: db.NewSchema(id, data), Prop: data, } diff --git a/src/models/role.go b/src/models/role.go index 4faaa07..9d6b4e8 100644 --- a/src/models/role.go +++ b/src/models/role.go @@ -5,11 +5,10 @@ import ( "pro2d/protos/pb" "pro2d/src/components/db" "pro2d/src/components/logger" - "strconv" ) type RoleModel struct { - *db.MgoColl + *db.Schema Role *pb.Role Heros HeroMap Teams *TeamModel @@ -27,7 +26,7 @@ func RoleExistByUid(uid string) *RoleModel { r := &RoleModel{ - MgoColl: db.NewMongoColl(strconv.Itoa(int(data.Id)), data), + Schema: db.NewSchema(data.Id, data), Role: data, Heros: make(HeroMap), Teams: new(TeamModel), @@ -38,10 +37,10 @@ func RoleExistByUid(uid string) *RoleModel { return r } -func NewRole(id int64) *RoleModel { +func NewRole(id string) *RoleModel { data := &pb.Role{Id: id} m := &RoleModel{ - MgoColl: db.NewMongoColl(strconv.Itoa(int(id)), data), + Schema: db.NewSchema(id, data), Role: data, Heros: make(HeroMap), Teams: new(TeamModel), @@ -52,9 +51,9 @@ func NewRole(id int64) *RoleModel { } func (m *RoleModel) LoadHero() { - m.Heros["test"] = NewHero(0) + m.Heros["test"] = NewHero("") m.Heros["test"].Hero = &pb.Hero{ - Id: 1, + Id: "1", RoleId: m.Role.Id, Type: 1, Level: 1, @@ -65,17 +64,17 @@ func (m *RoleModel) LoadHero() { } func (m *RoleModel) LoadTeams() { - m.Teams = NewTeam(0) + m.Teams = NewTeam("0") m.Teams.Team = &pb.Team{ - Id: 1, + Id: "1", HeroIds: "1", } } func (m *RoleModel) LoadEquips() { - m.Equip = NewEquip(0) + m.Equip = NewEquip("0") m.Equip.Equip = &pb.Equipment{ - Id: 0, + Id: "0", RoleId: m.Role.Id, Type: 0, Equip: false, @@ -93,7 +92,7 @@ func (m *RoleModel) AddHero(hero *pb.Hero) { h := NewHero(hero.Id) h.Hero = hero h.Create() - m.Heros[fmt.Sprintf("%d%d", m.Role.Id, h.Hero.Id)] = h + m.Heros[fmt.Sprintf("%s%s", m.Role.Id, h.Hero.Id)] = h } func (m *RoleModel) GetAllHero() map[string]*pb.Hero { diff --git a/src/models/role_test.go b/src/models/role_test.go index 09639ba..5125ec3 100644 --- a/src/models/role_test.go +++ b/src/models/role_test.go @@ -2,7 +2,7 @@ package models import ( "fmt" - "pro2d/conf" + _ "pro2d/conf" "pro2d/protos/pb" "pro2d/src/components/db" "pro2d/src/components/logger" @@ -13,29 +13,29 @@ import ( func TestNewRole(t *testing.T) { db.MongoDatabase = db.MongoClient.Database("game") - var uid = conf.SnowFlack.NextValStr() + var uid = "141815055745814528" role := RoleExistByUid(uid) if role != nil { //uid存在 , 更新角色 - role.Role.Device = "222222" - role.AddHero(&pb.Hero{ - Id: 1, - RoleId: role.Role.Id, - Type: 0, - Level: 0, - ReinCount: 0, - ReinPoint: 0, - Equipments: "", - }) - role.Save() + //role.AddHero(&pb.Hero{ + // Id: 1, + // RoleId: role.Role.Id, + // Type: 0, + // Level: 0, + // ReinCount: 0, + // ReinPoint: 0, + // Equipments: "", + //}) + role.UpdateProperty("Device", "999999999") + //role.Save() }else { //uid不存在,创建角色 - role = NewRole(1) + role = NewRole("1") role.Role.Uid = uid role.Role.Device = "111111" role.Role.Level = 0 - i, err := role.Create() - fmt.Println(i, err) + err := role.Create() + fmt.Println(err) } print(role) } diff --git a/src/models/team.go b/src/models/team.go index 0cd93a4..73234e0 100644 --- a/src/models/team.go +++ b/src/models/team.go @@ -3,20 +3,19 @@ package models import ( "pro2d/protos/pb" "pro2d/src/components/db" - "strconv" ) type TeamModel struct { - *db.MgoColl + *db.Schema Team *pb.Team } -func NewTeam(id int64) *TeamModel { +func NewTeam(id string) *TeamModel { data := &pb.Team{ Id: id, } m := &TeamModel{ - MgoColl: db.NewMongoColl(strconv.Itoa(int(id)), data), + Schema: db.NewSchema(id, data), Team: data, } diff --git a/src/plugin/RolePlugin.go b/src/plugin/RolePlugin.go index ff1f15f..b45cc97 100644 --- a/src/plugin/RolePlugin.go +++ b/src/plugin/RolePlugin.go @@ -25,9 +25,9 @@ func CreateRpc(msg *net.MsgPkg) (int32, proto.Message) { return 2, nil } - roleId := conf.SnowFlack.NextVal() + roleId := conf.SnowFlack.NextValStr() role = models.NewRole(roleId) - if _, err := role.Create(); err != nil { + if err := role.Create(); err != nil { logger.Error("CreateRpc role create err: %v", err) return 3, nil } -- libgit2 0.21.2