Commit c47aa250d2603e4af3134a5917dac109a33867f1

Authored by zhangqijia
1 parent 15864203

feat: 增加GM相关接口。详情请看protoc/doc/gm.md文档

cmd/gameserver/action/GmAction.go 0 → 100644
... ... @@ -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  
... ...
cmd/gameserver/service/gm.go 0 → 100644
... ... @@ -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 &quot;sync&quot;
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
... ... @@ -40,8 +40,9 @@ server_game:
40 40 ip: "192.168.0.206"
41 41 encipher: false
42 42 port: 8850
43   - pool_size: 1
44 43 debugport: 6061
  44 + gm: 8881
  45 + pool_size: 1
45 46 plugin_path: "./bin/plugin.so"
46 47 mongo:
47 48 <<: *default-mongo
... ...
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)
... ...