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 @@ | @@ -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,6 +48,7 @@ func CreateRpc(agent components.IAgent, msg components.IMessage) (int32, interfa | ||
48 | 48 | ||
49 | roleId := common.SnowFlack.NextValStr() | 49 | roleId := common.SnowFlack.NextValStr() |
50 | role = models.NewRole(roleId) | 50 | role = models.NewRole(roleId) |
51 | + role.Role.Uid = req.Token | ||
51 | role.Role.Nick = getRandomName() | 52 | role.Role.Nick = getRandomName() |
52 | if err := role.Create(); err != nil { | 53 | if err := role.Create(); err != nil { |
53 | logger.Error("CreateRpc role create err: %v", err) | 54 | logger.Error("CreateRpc role create err: %v", err) |
cmd/gameserver/main.go
@@ -19,13 +19,19 @@ func main() { | @@ -19,13 +19,19 @@ func main() { | ||
19 | userChan := make(chan os.Signal) | 19 | userChan := make(chan os.Signal) |
20 | signal.Notify(userChan, syscall.SIGUSR1, syscall.SIGUSR2) | 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 | if err1 != nil { | 24 | if err1 != nil { |
24 | logger.Error(err1) | 25 | logger.Error(err1) |
25 | return | 26 | return |
26 | } | 27 | } |
27 | go func() { | 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 | go func() { | 37 | go func() { |
cmd/gameserver/service/agent.go
@@ -37,6 +37,8 @@ func NewAgent(s components.IServer) *Agent { | @@ -37,6 +37,8 @@ func NewAgent(s components.IServer) *Agent { | ||
37 | 37 | ||
38 | func (c *Agent) SetSchema(schema components.ISchema) { | 38 | func (c *Agent) SetSchema(schema components.ISchema) { |
39 | c.Role = schema.(*models.RoleModel) | 39 | c.Role = schema.(*models.RoleModel) |
40 | + | ||
41 | + c.Server.GetConnManage().AddRID(c.Role.Role.Id, c.IConnection.GetID()) | ||
40 | } | 42 | } |
41 | 43 | ||
42 | func (c *Agent) GetSchema() components.ISchema { | 44 | func (c *Agent) GetSchema() components.ISchema { |
@@ -110,6 +112,7 @@ func (c *Agent) OnClose() { | @@ -110,6 +112,7 @@ func (c *Agent) OnClose() { | ||
110 | return | 112 | return |
111 | } | 113 | } |
112 | 114 | ||
115 | + c.Server.GetConnManage().DelRID(c.Role.Role.Id) | ||
113 | c.Role.OnOfflineEvent() | 116 | c.Role.OnOfflineEvent() |
114 | } | 117 | } |
115 | 118 |
@@ -0,0 +1,74 @@ | @@ -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,12 +5,18 @@ import "sync" | ||
5 | type ConnManage struct { | 5 | type ConnManage struct { |
6 | mu sync.RWMutex | 6 | mu sync.RWMutex |
7 | conns map[uint32]IConnection | 7 | conns map[uint32]IConnection |
8 | + | ||
9 | + r2cRW sync.RWMutex | ||
10 | + r2c map[string]uint32 // role to connID | ||
8 | } | 11 | } |
9 | 12 | ||
10 | func NewConnManage() *ConnManage { | 13 | func NewConnManage() *ConnManage { |
11 | return &ConnManage{ | 14 | return &ConnManage{ |
12 | mu: sync.RWMutex{}, | 15 | mu: sync.RWMutex{}, |
13 | conns: make(map[uint32]IConnection), | 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,3 +57,22 @@ func (c *ConnManage) StopAllConns() { | ||
51 | return true | 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 +9,10 @@ import ( | ||
9 | 9 | ||
10 | type HttpServer struct { | 10 | type HttpServer struct { |
11 | IHttp | 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 | func Pong(c *gin.Context) { | 18 | func Pong(c *gin.Context) { |
@@ -29,6 +30,10 @@ func GetRoutePath(objName, objFunc string) string { | @@ -29,6 +30,10 @@ func GetRoutePath(objName, objFunc string) string { | ||
29 | } | 30 | } |
30 | 31 | ||
31 | func (h *HttpServer) HandlerFuncObj(tvl, obj reflect.Value) gin.HandlerFunc { | 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 | return func(c *gin.Context) { | 37 | return func(c *gin.Context) { |
33 | v := tvl.Call([]reflect.Value{obj, reflect.ValueOf(c)}) | 38 | v := tvl.Call([]reflect.Value{obj, reflect.ValueOf(c)}) |
34 | if len(v) != 2 { | 39 | if len(v) != 2 { |
@@ -44,6 +49,10 @@ func (h *HttpServer) HandlerFuncObj(tvl, obj reflect.Value) gin.HandlerFunc { | @@ -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 | func (h *HttpServer) BindHandler(handler interface{}) { | 56 | func (h *HttpServer) BindHandler(handler interface{}) { |
48 | h.Handler = handler | 57 | h.Handler = handler |
49 | } | 58 | } |
common/components/icompontents.go
1 | package components | 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 | //----net start---- | 10 | //----net start---- |
@@ -60,6 +64,10 @@ type ( | @@ -60,6 +64,10 @@ type ( | ||
60 | DelConn(id uint32) IConnection | 64 | DelConn(id uint32) IConnection |
61 | Range(f func(key interface{}, value interface{}) bool) | 65 | Range(f func(key interface{}, value interface{}) bool) |
62 | StopAllConns() | 66 | StopAllConns() |
67 | + | ||
68 | + AddRID(rid string, id uint32) | ||
69 | + DelRID(rid string) | ||
70 | + GetConnByRID(rid string) IConnection | ||
63 | } | 71 | } |
64 | //server | 72 | //server |
65 | IServer interface { | 73 | IServer interface { |
@@ -97,6 +105,7 @@ type ( | @@ -97,6 +105,7 @@ type ( | ||
97 | IHttp interface { | 105 | IHttp interface { |
98 | Start() error | 106 | Start() error |
99 | Stop() | 107 | Stop() |
108 | + SetHandlerFuncCallback(func(tvl, obj reflect.Value) gin.HandlerFunc) | ||
100 | BindHandler(interface{}) | 109 | BindHandler(interface{}) |
101 | } | 110 | } |
102 | ActionHandler func(msg IMessage) (int32, interface{}) | 111 | ActionHandler func(msg IMessage) (int32, interface{}) |
common/conf.go
@@ -36,8 +36,9 @@ type SConf struct { | @@ -36,8 +36,9 @@ type SConf struct { | ||
36 | Name string `yaml:"name"` | 36 | Name string `yaml:"name"` |
37 | IP string `yaml:"ip"` | 37 | IP string `yaml:"ip"` |
38 | Port int `yaml:"port"` | 38 | Port int `yaml:"port"` |
39 | - Encipher bool `yaml:"encipher"` | ||
40 | DebugPort int `yaml:"debugport"` | 39 | DebugPort int `yaml:"debugport"` |
40 | + GMPort int `yaml:"gm"` | ||
41 | + Encipher bool `yaml:"encipher"` | ||
41 | MongoConf *MongoConf `yaml:"mongo"` | 42 | MongoConf *MongoConf `yaml:"mongo"` |
42 | RedisConf *RedisConf `yaml:"redis"` | 43 | RedisConf *RedisConf `yaml:"redis"` |
43 | WorkerPoolSize int `yaml:"pool_size"` | 44 | WorkerPoolSize int `yaml:"pool_size"` |
common/const.go
@@ -3,7 +3,7 @@ package common | @@ -3,7 +3,7 @@ package common | ||
3 | const ( | 3 | const ( |
4 | //最大包大 | 4 | //最大包大 |
5 | MaxPacketLength = 10 * 1024 * 1024 | 5 | MaxPacketLength = 10 * 1024 * 1024 |
6 | - MaxMsgChan = 100 | 6 | + MaxMsgChan = 100 |
7 | 7 | ||
8 | //心跳 | 8 | //心跳 |
9 | HeartTimerInterval = 5 //s | 9 | HeartTimerInterval = 5 //s |
@@ -11,10 +11,20 @@ const ( | @@ -11,10 +11,20 @@ const ( | ||
11 | 11 | ||
12 | //保存数据时间 | 12 | //保存数据时间 |
13 | SaveDataInterval = 5 //s | 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 | //redis keys | 26 | //redis keys |
17 | const ( | 27 | const ( |
18 | NickNames = "name:%s" | 28 | NickNames = "name:%s" |
19 | - SMSCode = "smscode:%s" | 29 | + SMSCode = "smscode:%s" |
20 | ) | 30 | ) |
conf/conf.yaml
@@ -40,8 +40,9 @@ server_game: | @@ -40,8 +40,9 @@ server_game: | ||
40 | ip: "192.168.0.206" | 40 | ip: "192.168.0.206" |
41 | encipher: false | 41 | encipher: false |
42 | port: 8850 | 42 | port: 8850 |
43 | - pool_size: 1 | ||
44 | debugport: 6061 | 43 | debugport: 6061 |
44 | + gm: 8881 | ||
45 | + pool_size: 1 | ||
45 | plugin_path: "./bin/plugin.so" | 46 | plugin_path: "./bin/plugin.so" |
46 | mongo: | 47 | mongo: |
47 | <<: *default-mongo | 48 | <<: *default-mongo |
models/role.go
@@ -24,7 +24,7 @@ func RoleExistByUid(uid string) *RoleModel { | @@ -24,7 +24,7 @@ func RoleExistByUid(uid string) *RoleModel { | ||
24 | data := &pb.Role{Uid: uid} | 24 | data := &pb.Role{Uid: uid} |
25 | 25 | ||
26 | if err := mongoproxy.FindOne(mongoproxy.GetBsonM("uid", uid), data); err != nil { | 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 | return nil | 28 | return nil |
29 | } | 29 | } |
30 | 30 | ||
@@ -35,6 +35,7 @@ func RoleExistByUid(uid string) *RoleModel { | @@ -35,6 +35,7 @@ func RoleExistByUid(uid string) *RoleModel { | ||
35 | Teams: make(SchemaMap), | 35 | Teams: make(SchemaMap), |
36 | Prop: new(PropModel), | 36 | Prop: new(PropModel), |
37 | } | 37 | } |
38 | + r.Load() | ||
38 | r.LoadAll() | 39 | r.LoadAll() |
39 | return r | 40 | return r |
40 | } | 41 | } |
@@ -154,7 +155,7 @@ func (m *RoleModel) UpdateProperties(conn components.IConnection, property map[s | @@ -154,7 +155,7 @@ func (m *RoleModel) UpdateProperties(conn components.IConnection, property map[s | ||
154 | logger.Error("id %s, err:", m.Role.Id, err) | 155 | logger.Error("id %s, err:", m.Role.Id, err) |
155 | return | 156 | return |
156 | } else { | 157 | } else { |
157 | - if conn != nil { | 158 | + if conn != nil && notify { |
158 | conn.Send(0, uint32(pb.ProtoCode_UpdateRolePropertyRsp), rsp) | 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,16 +200,16 @@ func (m *RoleModel) UpdateTeam(teams []*pb.Team) { | ||
199 | } | 200 | } |
200 | 201 | ||
201 | func (m *RoleModel) OnRecoverTimer(now int64) { | 202 | func (m *RoleModel) OnRecoverTimer(now int64) { |
202 | - m.saveRoleData(now) | 203 | + m.SaveRoleData(now) |
203 | } | 204 | } |
204 | 205 | ||
205 | func (m *RoleModel) OnOfflineEvent() { | 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 | return | 213 | return |
213 | } | 214 | } |
214 | atomic.StoreInt64(&m.lastSaveTs, now) | 215 | atomic.StoreInt64(&m.lastSaveTs, now) |