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) | ... | ... |