Commit c47aa250d2603e4af3134a5917dac109a33867f1
1 parent
15864203
feat: 增加GM相关接口。详情请看protoc/doc/gm.md文档
Showing
12 changed files
with
189 additions
and
16 deletions
Show diff stats
| ... | ... | @@ -0,0 +1,33 @@ |
| 1 | +package action | |
| 2 | + | |
| 3 | +import ( | |
| 4 | + "pro2d/common" | |
| 5 | + "pro2d/common/components" | |
| 6 | + "pro2d/common/logger" | |
| 7 | + "pro2d/models" | |
| 8 | + "strconv" | |
| 9 | +) | |
| 10 | + | |
| 11 | +type GmAction struct { | |
| 12 | +} | |
| 13 | + | |
| 14 | +func (gm *GmAction) AddExp(properties map[string]interface{}) int { | |
| 15 | + r := properties[common.Role_] | |
| 16 | + c := properties[common.Conn_] | |
| 17 | + | |
| 18 | + role := r.(*models.RoleModel) | |
| 19 | + var conn components.IConnection | |
| 20 | + if c == nil { | |
| 21 | + conn = nil | |
| 22 | + } else { | |
| 23 | + conn = c.(components.IConnection) | |
| 24 | + } | |
| 25 | + | |
| 26 | + logger.Debug(properties) | |
| 27 | + exp, _ := strconv.Atoi(properties["exp"].(string)) | |
| 28 | + logger.Debug("update before id: %s, exp: %d", role.Role.Id, role.Role.Exp) | |
| 29 | + role.Role.Exp += int64(exp) | |
| 30 | + role.UpdateProperty(conn, "exp", role.Role.Exp, true) | |
| 31 | + logger.Debug("update after id: %s, exp: %d", role.Role.Id, role.Role.Exp) | |
| 32 | + return 0 | |
| 33 | +} | ... | ... |
cmd/gameserver/action/RoleAction.go
| ... | ... | @@ -48,6 +48,7 @@ func CreateRpc(agent components.IAgent, msg components.IMessage) (int32, interfa |
| 48 | 48 | |
| 49 | 49 | roleId := common.SnowFlack.NextValStr() |
| 50 | 50 | role = models.NewRole(roleId) |
| 51 | + role.Role.Uid = req.Token | |
| 51 | 52 | role.Role.Nick = getRandomName() |
| 52 | 53 | if err := role.Create(); err != nil { |
| 53 | 54 | logger.Error("CreateRpc role create err: %v", err) | ... | ... |
cmd/gameserver/main.go
| ... | ... | @@ -19,13 +19,19 @@ func main() { |
| 19 | 19 | userChan := make(chan os.Signal) |
| 20 | 20 | signal.Notify(userChan, syscall.SIGUSR1, syscall.SIGUSR2) |
| 21 | 21 | |
| 22 | - s, err1 := service.NewGameServer(common.GlobalConf.GameConf) | |
| 22 | + sconf := common.GlobalConf.GameConf | |
| 23 | + s, err1 := service.NewGameServer(sconf) | |
| 23 | 24 | if err1 != nil { |
| 24 | 25 | logger.Error(err1) |
| 25 | 26 | return |
| 26 | 27 | } |
| 27 | 28 | go func() { |
| 28 | - err <- http.ListenAndServe(fmt.Sprintf("localhost:%d", common.GlobalConf.GameConf.DebugPort), nil) | |
| 29 | + err <- http.ListenAndServe(fmt.Sprintf("localhost:%d", sconf.DebugPort), nil) | |
| 30 | + }() | |
| 31 | + | |
| 32 | + gm := service.NewGmServer(s, fmt.Sprintf(":%d", sconf.GMPort)) | |
| 33 | + go func() { | |
| 34 | + err <- gm.Start() | |
| 29 | 35 | }() |
| 30 | 36 | |
| 31 | 37 | go func() { | ... | ... |
cmd/gameserver/service/agent.go
| ... | ... | @@ -37,6 +37,8 @@ func NewAgent(s components.IServer) *Agent { |
| 37 | 37 | |
| 38 | 38 | func (c *Agent) SetSchema(schema components.ISchema) { |
| 39 | 39 | c.Role = schema.(*models.RoleModel) |
| 40 | + | |
| 41 | + c.Server.GetConnManage().AddRID(c.Role.Role.Id, c.IConnection.GetID()) | |
| 40 | 42 | } |
| 41 | 43 | |
| 42 | 44 | func (c *Agent) GetSchema() components.ISchema { |
| ... | ... | @@ -110,6 +112,7 @@ func (c *Agent) OnClose() { |
| 110 | 112 | return |
| 111 | 113 | } |
| 112 | 114 | |
| 115 | + c.Server.GetConnManage().DelRID(c.Role.Role.Id) | |
| 113 | 116 | c.Role.OnOfflineEvent() |
| 114 | 117 | } |
| 115 | 118 | ... | ... |
| ... | ... | @@ -0,0 +1,74 @@ |
| 1 | +package service | |
| 2 | + | |
| 3 | +import ( | |
| 4 | + "github.com/gin-gonic/gin" | |
| 5 | + "net/http" | |
| 6 | + "pro2d/cmd/gameserver/action" | |
| 7 | + "pro2d/common/components" | |
| 8 | + "pro2d/models" | |
| 9 | + "reflect" | |
| 10 | +) | |
| 11 | + | |
| 12 | +type GmServer struct { | |
| 13 | + components.IHttp | |
| 14 | + Server components.IServer | |
| 15 | +} | |
| 16 | + | |
| 17 | +func NewGmServer(server components.IServer, port ...string) *GmServer { | |
| 18 | + return &GmServer{ | |
| 19 | + IHttp: components.NewHttpServer("", port...), | |
| 20 | + Server: server, | |
| 21 | + } | |
| 22 | +} | |
| 23 | + | |
| 24 | +func (s *GmServer) HandlerFuncObj(tvl, obj reflect.Value) gin.HandlerFunc { | |
| 25 | + return func(c *gin.Context) { | |
| 26 | + c.Request.ParseForm() | |
| 27 | + roleId, ok := c.GetPostForm("role_id") | |
| 28 | + if !ok { | |
| 29 | + c.JSON(http.StatusOK, gin.H{"code": -101, "message": "role not exist"}) | |
| 30 | + return | |
| 31 | + } | |
| 32 | + | |
| 33 | + conn := s.Server.GetConnManage().GetConnByRID(roleId) | |
| 34 | + var role *models.RoleModel | |
| 35 | + if conn != nil { | |
| 36 | + //在线 | |
| 37 | + role = conn.(*Agent).Role | |
| 38 | + } else { | |
| 39 | + //离线 | |
| 40 | + role = models.NewRole(roleId) | |
| 41 | + if err := role.Load(); err != nil { | |
| 42 | + c.JSON(http.StatusOK, gin.H{"code": -102, "message": "role not exist"}) | |
| 43 | + return | |
| 44 | + } | |
| 45 | + role.LoadAll() | |
| 46 | + } | |
| 47 | + | |
| 48 | + properties := make(map[string]interface{}) | |
| 49 | + | |
| 50 | + for k, v := range c.Request.PostForm { | |
| 51 | + properties[k] = v[0] | |
| 52 | + } | |
| 53 | + | |
| 54 | + properties["_conn"] = conn | |
| 55 | + properties["_role"] = role | |
| 56 | + | |
| 57 | + v := tvl.Call([]reflect.Value{obj, reflect.ValueOf(properties)}) | |
| 58 | + | |
| 59 | + role.SaveRoleData(0) | |
| 60 | + | |
| 61 | + if len(v) != 1 { | |
| 62 | + c.JSON(http.StatusNotFound, gin.H{"code": -100, "message": "request param len is error"}) | |
| 63 | + return | |
| 64 | + } | |
| 65 | + c.JSON(http.StatusOK, gin.H{"code": v[0].Interface()}) | |
| 66 | + } | |
| 67 | +} | |
| 68 | + | |
| 69 | +func (s *GmServer) Start() error { | |
| 70 | + s.SetHandlerFuncCallback(s.HandlerFuncObj) | |
| 71 | + s.BindHandler(&action.GmAction{}) | |
| 72 | + //gin.SetMode(gin.ReleaseMode) | |
| 73 | + return s.IHttp.Start() | |
| 74 | +} | ... | ... |
common/components/connmanage.go
| ... | ... | @@ -5,12 +5,18 @@ import "sync" |
| 5 | 5 | type ConnManage struct { |
| 6 | 6 | mu sync.RWMutex |
| 7 | 7 | conns map[uint32]IConnection |
| 8 | + | |
| 9 | + r2cRW sync.RWMutex | |
| 10 | + r2c map[string]uint32 // role to connID | |
| 8 | 11 | } |
| 9 | 12 | |
| 10 | 13 | func NewConnManage() *ConnManage { |
| 11 | 14 | return &ConnManage{ |
| 12 | 15 | mu: sync.RWMutex{}, |
| 13 | 16 | conns: make(map[uint32]IConnection), |
| 17 | + | |
| 18 | + r2cRW: sync.RWMutex{}, | |
| 19 | + r2c: make(map[string]uint32), | |
| 14 | 20 | } |
| 15 | 21 | } |
| 16 | 22 | |
| ... | ... | @@ -51,3 +57,22 @@ func (c *ConnManage) StopAllConns() { |
| 51 | 57 | return true |
| 52 | 58 | }) |
| 53 | 59 | } |
| 60 | + | |
| 61 | +func (c *ConnManage) AddRID(rid string, id uint32) { | |
| 62 | + c.r2cRW.Lock() | |
| 63 | + defer c.r2cRW.Unlock() | |
| 64 | + c.r2c[rid] = id | |
| 65 | +} | |
| 66 | + | |
| 67 | +func (c *ConnManage) DelRID(rid string) { | |
| 68 | + c.r2cRW.Lock() | |
| 69 | + defer c.r2cRW.Unlock() | |
| 70 | + delete(c.r2c, rid) | |
| 71 | +} | |
| 72 | + | |
| 73 | +func (c *ConnManage) GetConnByRID(rid string) IConnection { | |
| 74 | + c.r2cRW.RLock() | |
| 75 | + defer c.r2cRW.RUnlock() | |
| 76 | + cid := c.r2c[rid] | |
| 77 | + return c.GetConn(cid) | |
| 78 | +} | ... | ... |
common/components/http.go
| ... | ... | @@ -9,9 +9,10 @@ import ( |
| 9 | 9 | |
| 10 | 10 | type HttpServer struct { |
| 11 | 11 | IHttp |
| 12 | - version string | |
| 13 | - port []string | |
| 14 | - Handler interface{} | |
| 12 | + version string | |
| 13 | + port []string | |
| 14 | + Handler interface{} | |
| 15 | + HandlerFuncCallBack func(tvl, obj reflect.Value) gin.HandlerFunc | |
| 15 | 16 | } |
| 16 | 17 | |
| 17 | 18 | func Pong(c *gin.Context) { |
| ... | ... | @@ -29,6 +30,10 @@ func GetRoutePath(objName, objFunc string) string { |
| 29 | 30 | } |
| 30 | 31 | |
| 31 | 32 | func (h *HttpServer) HandlerFuncObj(tvl, obj reflect.Value) gin.HandlerFunc { |
| 33 | + if h.HandlerFuncCallBack != nil { | |
| 34 | + return h.HandlerFuncCallBack(tvl, obj) | |
| 35 | + } | |
| 36 | + | |
| 32 | 37 | return func(c *gin.Context) { |
| 33 | 38 | v := tvl.Call([]reflect.Value{obj, reflect.ValueOf(c)}) |
| 34 | 39 | if len(v) != 2 { |
| ... | ... | @@ -44,6 +49,10 @@ func (h *HttpServer) HandlerFuncObj(tvl, obj reflect.Value) gin.HandlerFunc { |
| 44 | 49 | } |
| 45 | 50 | } |
| 46 | 51 | |
| 52 | +func (h *HttpServer) SetHandlerFuncCallback(gh func(tvl, obj reflect.Value) gin.HandlerFunc) { | |
| 53 | + h.HandlerFuncCallBack = gh | |
| 54 | +} | |
| 55 | + | |
| 47 | 56 | func (h *HttpServer) BindHandler(handler interface{}) { |
| 48 | 57 | h.Handler = handler |
| 49 | 58 | } | ... | ... |
common/components/icompontents.go
| 1 | 1 | package components |
| 2 | 2 | |
| 3 | -import "google.golang.org/protobuf/reflect/protoreflect" | |
| 3 | +import ( | |
| 4 | + "github.com/gin-gonic/gin" | |
| 5 | + "google.golang.org/protobuf/reflect/protoreflect" | |
| 6 | + "reflect" | |
| 7 | +) | |
| 4 | 8 | |
| 5 | 9 | //----------------- |
| 6 | 10 | //----net start---- |
| ... | ... | @@ -60,6 +64,10 @@ type ( |
| 60 | 64 | DelConn(id uint32) IConnection |
| 61 | 65 | Range(f func(key interface{}, value interface{}) bool) |
| 62 | 66 | StopAllConns() |
| 67 | + | |
| 68 | + AddRID(rid string, id uint32) | |
| 69 | + DelRID(rid string) | |
| 70 | + GetConnByRID(rid string) IConnection | |
| 63 | 71 | } |
| 64 | 72 | //server |
| 65 | 73 | IServer interface { |
| ... | ... | @@ -97,6 +105,7 @@ type ( |
| 97 | 105 | IHttp interface { |
| 98 | 106 | Start() error |
| 99 | 107 | Stop() |
| 108 | + SetHandlerFuncCallback(func(tvl, obj reflect.Value) gin.HandlerFunc) | |
| 100 | 109 | BindHandler(interface{}) |
| 101 | 110 | } |
| 102 | 111 | ActionHandler func(msg IMessage) (int32, interface{}) | ... | ... |
common/conf.go
| ... | ... | @@ -36,8 +36,9 @@ type SConf struct { |
| 36 | 36 | Name string `yaml:"name"` |
| 37 | 37 | IP string `yaml:"ip"` |
| 38 | 38 | Port int `yaml:"port"` |
| 39 | - Encipher bool `yaml:"encipher"` | |
| 40 | 39 | DebugPort int `yaml:"debugport"` |
| 40 | + GMPort int `yaml:"gm"` | |
| 41 | + Encipher bool `yaml:"encipher"` | |
| 41 | 42 | MongoConf *MongoConf `yaml:"mongo"` |
| 42 | 43 | RedisConf *RedisConf `yaml:"redis"` |
| 43 | 44 | WorkerPoolSize int `yaml:"pool_size"` | ... | ... |
common/const.go
| ... | ... | @@ -3,7 +3,7 @@ package common |
| 3 | 3 | const ( |
| 4 | 4 | //最大包大 |
| 5 | 5 | MaxPacketLength = 10 * 1024 * 1024 |
| 6 | - MaxMsgChan = 100 | |
| 6 | + MaxMsgChan = 100 | |
| 7 | 7 | |
| 8 | 8 | //心跳 |
| 9 | 9 | HeartTimerInterval = 5 //s |
| ... | ... | @@ -11,10 +11,20 @@ const ( |
| 11 | 11 | |
| 12 | 12 | //保存数据时间 |
| 13 | 13 | SaveDataInterval = 5 //s |
| 14 | + | |
| 15 | + //id相关 | |
| 16 | + MaxRoleNum = 1000000 | |
| 17 | + MaxUidNum = 1000000 | |
| 18 | + MaxHeroNum = 1000000 | |
| 19 | + MaxTeamNum = 1000000 | |
| 20 | + | |
| 21 | + //gm参数属性 | |
| 22 | + Role_ = "_role" | |
| 23 | + Conn_ = "_conn" | |
| 14 | 24 | ) |
| 15 | 25 | |
| 16 | 26 | //redis keys |
| 17 | 27 | const ( |
| 18 | 28 | NickNames = "name:%s" |
| 19 | - SMSCode = "smscode:%s" | |
| 29 | + SMSCode = "smscode:%s" | |
| 20 | 30 | ) | ... | ... |
conf/conf.yaml
models/role.go
| ... | ... | @@ -24,7 +24,7 @@ func RoleExistByUid(uid string) *RoleModel { |
| 24 | 24 | data := &pb.Role{Uid: uid} |
| 25 | 25 | |
| 26 | 26 | if err := mongoproxy.FindOne(mongoproxy.GetBsonM("uid", uid), data); err != nil { |
| 27 | - logger.Error("Role exist err: %v", err) | |
| 27 | + logger.Error("Role not exist err: %v", err) | |
| 28 | 28 | return nil |
| 29 | 29 | } |
| 30 | 30 | |
| ... | ... | @@ -35,6 +35,7 @@ func RoleExistByUid(uid string) *RoleModel { |
| 35 | 35 | Teams: make(SchemaMap), |
| 36 | 36 | Prop: new(PropModel), |
| 37 | 37 | } |
| 38 | + r.Load() | |
| 38 | 39 | r.LoadAll() |
| 39 | 40 | return r |
| 40 | 41 | } |
| ... | ... | @@ -154,7 +155,7 @@ func (m *RoleModel) UpdateProperties(conn components.IConnection, property map[s |
| 154 | 155 | logger.Error("id %s, err:", m.Role.Id, err) |
| 155 | 156 | return |
| 156 | 157 | } else { |
| 157 | - if conn != nil { | |
| 158 | + if conn != nil && notify { | |
| 158 | 159 | conn.Send(0, uint32(pb.ProtoCode_UpdateRolePropertyRsp), rsp) |
| 159 | 160 | } |
| 160 | 161 | } |
| ... | ... | @@ -199,16 +200,16 @@ func (m *RoleModel) UpdateTeam(teams []*pb.Team) { |
| 199 | 200 | } |
| 200 | 201 | |
| 201 | 202 | func (m *RoleModel) OnRecoverTimer(now int64) { |
| 202 | - m.saveRoleData(now) | |
| 203 | + m.SaveRoleData(now) | |
| 203 | 204 | } |
| 204 | 205 | |
| 205 | 206 | func (m *RoleModel) OnOfflineEvent() { |
| 206 | 207 | // 设置最新的登录时间 |
| 207 | - m.saveRoleData(common.Timex()) | |
| 208 | + m.SaveRoleData(common.Timex()) | |
| 208 | 209 | } |
| 209 | 210 | |
| 210 | -func (m *RoleModel) saveRoleData(now int64) { | |
| 211 | - if now-m.lastSaveTs < common.SaveDataInterval { | |
| 211 | +func (m *RoleModel) SaveRoleData(now int64) { | |
| 212 | + if now > 0 && now-m.lastSaveTs < common.SaveDataInterval { | |
| 212 | 213 | return |
| 213 | 214 | } |
| 214 | 215 | atomic.StoreInt64(&m.lastSaveTs, now) | ... | ... |