From 69d286a7c94629a66d3065140ade7d58ae77166b Mon Sep 17 00:00:00 2001 From: zqj <582132116@qq.com> Date: Mon, 21 Mar 2022 14:36:48 +0800 Subject: [PATCH] fix: 插件用来做部分热更 --- Makefile | 2 +- cmd/gameserver/action/RoleAction.go | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ cmd/gameserver/action/protocode.go | 16 ++++++++++++++++ cmd/gameserver/game.go | 2 ++ cmd/gameserver/plugin/RolePlugin.go | 57 --------------------------------------------------------- cmd/gameserver/plugin/plugin.go | 43 +++++++++++++++++++++++++++++++++++++++++++ cmd/gameserver/plugin/protocode.go | 16 ---------------- common/components/connmanage.go | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ common/components/icompontents.go | 3 ++- common/components/plugin.go | 17 +++++++++-------- common/components/server.go | 22 ++++++++++++++++++---- conf/conf.yaml | 5 +++-- tools/protostostruct.go | 28 ++++++++++++++-------------- 13 files changed, 220 insertions(+), 103 deletions(-) create mode 100644 cmd/gameserver/action/RoleAction.go create mode 100644 cmd/gameserver/action/protocode.go delete mode 100644 cmd/gameserver/plugin/RolePlugin.go create mode 100644 cmd/gameserver/plugin/plugin.go delete mode 100644 cmd/gameserver/plugin/protocode.go create mode 100644 common/components/connmanage.go diff --git a/Makefile b/Makefile index b7db157..f13fe50 100644 --- a/Makefile +++ b/Makefile @@ -11,7 +11,7 @@ test: http: go run -race cmd/httpserver/http.go cmd/httpserver/AccountAction.go -game:plugin +game: go run -race cmd/gameserver/*.go build: go build -race -o bin/account cmd/http.go diff --git a/cmd/gameserver/action/RoleAction.go b/cmd/gameserver/action/RoleAction.go new file mode 100644 index 0000000..4a48d24 --- /dev/null +++ b/cmd/gameserver/action/RoleAction.go @@ -0,0 +1,57 @@ +package action + +import ( + "github.com/golang/protobuf/proto" + "pro2d/common" + "pro2d/common/components" + "pro2d/common/logger" + "pro2d/models" + "pro2d/pb" +) + +func HeartRpc(msg components.IMessage) (int32, interface{}) { + //msg.Conn.SetLastHeartCheckTime() + return 0, nil +} + +func CreateRpc(msg components.IMessage) (int32, interface{}) { + req := pb.CreateReq{} + if err := proto.Unmarshal(msg.GetData(), &req); err != nil { + logger.Error("CreateRpc err: %v", err) + return 1, nil + } + role := models.RoleExistByUid(req.Uid) + if role != nil { + return 2, nil + } + + roleId := common.SnowFlack.NextValStr() + role = models.NewRole(roleId) + if err := role.Create(); err != nil { + logger.Error("CreateRpc role create err: %v", err) + return 3, nil + } + return 0, nil +} + +func LoginRpc(msg components.IMessage) (int32, interface{}) { + //logger.Debug("11111111cmd: %v, msg: %s", msg.GetHeader().GetMsgID(), msg.GetData()) + req := pb.LoginReq{} + if err := proto.Unmarshal(msg.GetData(), &req); err != nil { + logger.Error("loginRpc err: %v", err) + return 1, nil + } + + role := models.RoleExistByUid(req.Uid) + if role == nil { + return 2, nil + } + role.SetProperty("Device", req.Device) + + return 0, &pb.RoleRsp{ + Role: role.Role, + Hero: role.GetAllHero(), + Team: role.Teams.Team, + Equips: []*pb.Equipment{role.Equip.Equip}, + } +} diff --git a/cmd/gameserver/action/protocode.go b/cmd/gameserver/action/protocode.go new file mode 100644 index 0000000..460699e --- /dev/null +++ b/cmd/gameserver/action/protocode.go @@ -0,0 +1,16 @@ +package action + +import ( + "pro2d/common/logger" + "pro2d/pb" +) + +func GetActionMap() map[interface{}]interface{} { + logger.Debug("init protocode...") + am := make(map[interface{}]interface{}) + am[uint32(pb.ProtoCode_HeartReq)] = HeartRpc + am[uint32(pb.ProtoCode_LoginReq)] = LoginRpc + am[uint32(pb.ProtoCode_CreateReq)] = CreateRpc + + return am +} diff --git a/cmd/gameserver/game.go b/cmd/gameserver/game.go index c032e9b..b6e2df3 100644 --- a/cmd/gameserver/game.go +++ b/cmd/gameserver/game.go @@ -3,6 +3,7 @@ package main import ( "fmt" _ "net/http/pprof" + "pro2d/cmd/gameserver/action" "pro2d/common" "pro2d/common/components" "pro2d/common/db" @@ -29,6 +30,7 @@ func NewGameServer(sconf *common.SConf) (*GameServer, error) { } iserver := components.NewServer(sconf.Port, options...) + iserver.SetActions(action.GetActionMap()) s.IServer = iserver //mgo init diff --git a/cmd/gameserver/plugin/RolePlugin.go b/cmd/gameserver/plugin/RolePlugin.go deleted file mode 100644 index ea5de95..0000000 --- a/cmd/gameserver/plugin/RolePlugin.go +++ /dev/null @@ -1,57 +0,0 @@ -package main - -import ( - "github.com/golang/protobuf/proto" - "pro2d/common" - "pro2d/common/components" - "pro2d/common/logger" - "pro2d/models" - "pro2d/pb" -) - -func HeartRpc(msg components.IMessage) (int32, interface{}) { - //msg.Conn.SetLastHeartCheckTime() - return 0, nil -} - -func CreateRpc(msg components.IMessage) (int32, interface{}) { - req := pb.CreateReq{} - if err := proto.Unmarshal(msg.GetData(), &req); err != nil { - logger.Error("CreateRpc err: %v", err) - return 1, nil - } - role := models.RoleExistByUid(req.Uid) - if role != nil { - return 2, nil - } - - roleId := common.SnowFlack.NextValStr() - role = models.NewRole(roleId) - if err := role.Create(); err != nil { - logger.Error("CreateRpc role create err: %v", err) - return 3, nil - } - return 0, nil -} - -func LoginRpc(msg components.IMessage) (int32, interface{}) { - //logger.Debug("11111111cmd: %v, msg: %s", msg.GetHeader().GetMsgID(), msg.GetData()) - req := pb.LoginReq{} - if err := proto.Unmarshal(msg.GetData(), &req); err != nil { - logger.Error("loginRpc err: %v", err) - return 1, nil - } - - role := models.RoleExistByUid(req.Uid) - if role == nil { - return 2, nil - } - role.SetProperty("Device", req.Device) - - return 0, &pb.RoleRsp{ - Role: role.Role, - Hero: role.GetAllHero(), - Team: role.Teams.Team, - Equips: []*pb.Equipment{role.Equip.Equip}, - } -} \ No newline at end of file diff --git a/cmd/gameserver/plugin/plugin.go b/cmd/gameserver/plugin/plugin.go new file mode 100644 index 0000000..775a434 --- /dev/null +++ b/cmd/gameserver/plugin/plugin.go @@ -0,0 +1,43 @@ +package main + +import ( + "github.com/golang/protobuf/proto" + "pro2d/common/components" + "pro2d/common/logger" + "pro2d/models" + "pro2d/pb" +) + +func init() { + logger.Debug("init game server plugin") +} + +func GetActionMap() map[interface{}]interface{} { + logger.Debug("init protocode...") + am := make(map[interface{}]interface{}) + am[uint32(pb.ProtoCode_LoginReq)] = LoginRpc + + return am +} + +func LoginRpc(msg components.IMessage) (int32, interface{}) { + //logger.Debug("11111111cmd: %v, msg: %s", msg.GetHeader().GetMsgID(), msg.GetData()) + req := pb.LoginReq{} + if err := proto.Unmarshal(msg.GetData(), &req); err != nil { + logger.Error("loginRpc err: %v", err) + return 1, nil + } + + role := models.RoleExistByUid(req.Uid) + if role == nil { + return 2, nil + } + role.SetProperty("Device", req.Device) + + return 0, &pb.RoleRsp{ + Role: role.Role, + Hero: role.GetAllHero(), + Team: role.Teams.Team, + Equips: []*pb.Equipment{role.Equip.Equip}, + } +} diff --git a/cmd/gameserver/plugin/protocode.go b/cmd/gameserver/plugin/protocode.go deleted file mode 100644 index a135bc5..0000000 --- a/cmd/gameserver/plugin/protocode.go +++ /dev/null @@ -1,16 +0,0 @@ -package main - -import ( - "pro2d/common/logger" - "pro2d/pb" -) - -func GetActionMap() map[interface{}]interface{} { - logger.Debug("init protocode...") - am := make(map[interface{}]interface{}) - am[pb.ProtoCode_HeartReq] = HeartRpc - am[pb.ProtoCode_LoginReq] = LoginRpc - am[pb.ProtoCode_CreateReq] = CreateRpc - - return am -} \ No newline at end of file diff --git a/common/components/connmanage.go b/common/components/connmanage.go new file mode 100644 index 0000000..c26c65a --- /dev/null +++ b/common/components/connmanage.go @@ -0,0 +1,55 @@ +package components + +import "sync" + +type ConnManage struct { + mu sync.RWMutex + conns map[int]IConnection +} + +func NewConnManage() *ConnManage { + return &ConnManage{ + mu: sync.RWMutex{}, + conns: make(map[int]IConnection), + } +} + +func (c *ConnManage) AddConn(id int, connection IConnection) { + c.mu.Lock() + defer c.mu.Unlock() + c.conns[id] = connection +} + +func (c *ConnManage) GetConn(id int) IConnection { + c.mu.RLock() + defer c.mu.RUnlock() + return c.conns[id] +} + +func (c *ConnManage) DelConn(id int) IConnection { + c.mu.Lock() + defer c.mu.Unlock() + conn := c.conns[id] + delete(c.conns, id) + return conn +} + +func (c *ConnManage) Range(f func(key interface{}, value interface{}) bool) { + for k, v := range c.conns { + c.mu.Lock() + if ok := f(k, v); !ok { + c.mu.Unlock() + return + } + c.mu.Unlock() + + } +} + +func (c *ConnManage) StopAllConns() { + c.Range(func(key interface{}, value interface{}) bool { + conn := value.(IConnection) + conn.Stop() + return true + }) +} diff --git a/common/components/icompontents.go b/common/components/icompontents.go index 4dd128f..68ae9e6 100644 --- a/common/components/icompontents.go +++ b/common/components/icompontents.go @@ -62,6 +62,7 @@ type ( GetSplitter() ISplitter GetPlugin() IPlugin GetAction(uint32) interface{} + SetActions(map[interface{}]interface{}) GetConnManage() IConnManage SetConnectionCallback(ConnectionCallback) @@ -76,7 +77,7 @@ type ( Stop() BindHandler(interface{}) } - ActionHandler func(conn IConnection, msg IMessage) (int32, interface{}) + ActionHandler func(msg IMessage) (int32, interface{}) //用于热更逻辑的插件接口 IPlugin interface { LoadPlugin() error diff --git a/common/components/plugin.go b/common/components/plugin.go index fa5706c..2cb657a 100644 --- a/common/components/plugin.go +++ b/common/components/plugin.go @@ -3,23 +3,24 @@ package components import ( "plugin" "pro2d/common/logger" - "pro2d/pb" "sync" ) -type ActionMap sync.Map//map[pb.ProtoCode]ActionHandler - type PluginOption func(*Plugin) type Plugin struct { pluginPath string - Actions sync.Map + Actions sync.Map } -func NewPlugin(path string, options ...PluginOption) IPlugin{ +func NewPlugin(path string, options ...PluginOption) IPlugin { + if path == "" { + return nil + } p := &Plugin{ pluginPath: path, + Actions: sync.Map{}, } for _, option := range options { option(p) @@ -41,7 +42,7 @@ func (p *Plugin) LoadPlugin() error { } logger.Debug("func LoadPlugin Lookup success...") - if x, ok := f.(func()map[interface{}]interface{}); ok { + if x, ok := f.(func() map[interface{}]interface{}); ok { logger.Debug("func LoadPlugin GetActionMap success...") p.SetActions(x()) } @@ -50,7 +51,7 @@ func (p *Plugin) LoadPlugin() error { } func (p *Plugin) GetAction(cmd uint32) interface{} { - f, ok := p.Actions.Load(pb.ProtoCode(cmd)) + f, ok := p.Actions.Load(cmd) if !ok { return nil } @@ -59,7 +60,7 @@ func (p *Plugin) GetAction(cmd uint32) interface{} { func (p *Plugin) SetActions(am map[interface{}]interface{}) { for k, v := range am { - cmd := k.(pb.ProtoCode) + cmd := k.(uint32) p.Actions.Delete(cmd) p.Actions.Store(cmd, v) } diff --git a/common/components/server.go b/common/components/server.go index 2f1d444..ce7d6c6 100644 --- a/common/components/server.go +++ b/common/components/server.go @@ -55,7 +55,8 @@ type Server struct { timerCallback TimerCallback port int - connManage *ConnManage + connManage IConnManage + Actions map[interface{}]interface{} } func NewServer(port int, options ...ServerOption) IServer { @@ -79,7 +80,18 @@ func (s *Server) GetPlugin() IPlugin { } func (s *Server) GetAction(cmd uint32) interface{} { - return s.plugins.GetAction(cmd) + if s.plugins != nil { + f := s.plugins.GetAction(cmd) + if f != nil { + return f + } + } + + return s.Actions[cmd] +} + +func (s *Server) SetActions(mi map[interface{}]interface{}) { + s.Actions = mi } func (s *Server) GetConnManage() IConnManage { @@ -103,8 +115,10 @@ func (s *Server) SetTimerCallback(cb TimerCallback) { } func (s *Server) Start() error { - if err := s.plugins.LoadPlugin(); err != nil { - return err + if s.plugins != nil { + if err := s.plugins.LoadPlugin(); err != nil { + return err + } } port := fmt.Sprintf(":%d", s.port) diff --git a/conf/conf.yaml b/conf/conf.yaml index 0fe233b..139c7aa 100644 --- a/conf/conf.yaml +++ b/conf/conf.yaml @@ -22,7 +22,7 @@ server_account: ip: "192.168.0.206" port: 8858 pool_size: 1 - debugport: 6061 + debugport: 6062 mongo: <<: *default-mongo dbname: "account" @@ -33,7 +33,8 @@ server_game: ip: "192.168.0.206" port: 8850 pool_size: 1 - plugin_path: "./bin/plugin.so" + debugport: 6061 + # plugin_path: "./bin/plugin.so" mongo: <<: *default-mongo dbname: "game" diff --git a/tools/protostostruct.go b/tools/protostostruct.go index 2e3a01e..6212a76 100644 --- a/tools/protostostruct.go +++ b/tools/protostostruct.go @@ -11,16 +11,17 @@ import ( ) var ( - ProtoCode = "syntax = \"proto3\";\noption go_package = \"./pb;pb\";\n\npackage protocode;\n\nenum ProtoCode\n{\n UNKNOWN = 0;\n %s\n}" + ProtoCode = "syntax = \"proto3\";\noption go_package = \"../pb;pb\";\n\npackage protocode;\n\nenum ProtoCode\n{\n UNKNOWN = 0;\n %s\n}" ProtoCodeLineReq = "\t%sReq = %d;\n" ProtoCodeLineRsp = "\t%sRsp = %d;\n" - GoProtoCodeStr = "package main\n\nimport (\n\t\"pro2d/pb\"\n\t\"pro2d/utils/logger\"\n)\n\nfunc GetActionMap() map[interface{}]interface{} {\n\tlogger.Debug(\"init protocode...\")\n\tam := make(map[interface{}]interface{})\n%s\n\treturn am\n}" - GoProtoCodeLine = "\tam[pb.ProtoCode_%sReq] = %sRpc\n" + GoProtoCodeStr = "package action\n\nimport (\n\t\"pro2d/common/logger\"\n\t\"pro2d/pb\"\n)\n\nfunc GetActionMap() map[interface{}]interface{} {\n\tlogger.Debug(\"init protocode...\")\n\tam := make(map[interface{}]interface{})\n%s\n\treturn am\n}" + + GoProtoCodeLine = "\tam[uint32(pb.ProtoCode_%sReq)] = %sRpc\n" ) func ProtoToCode(readPath, filename string) (string, string) { - protofile , err := os.Open(readPath+filename) + protofile, err := os.Open(readPath + filename) code := 0x000 protoData := "" goProtoData := "" @@ -57,45 +58,44 @@ func ProtoToCode(readPath, filename string) (string, string) { for _, v := range lb { n1 := bytes.Index(v, []byte("Req")) n2 := bytes.Index(v, []byte("Rsp")) - if n1 < 0 && n2 < 0 { + if n1 < 0 && n2 < 0 { continue } if n1 >= 0 { code++ - protoData += fmt.Sprintf(ProtoCodeLineReq, v[:n1],code) + protoData += fmt.Sprintf(ProtoCodeLineReq, v[:n1], code) goProtoData += fmt.Sprintf(GoProtoCodeLine, v[:n1], v[:n1]) } if n2 >= 0 { code++ - protoData += fmt.Sprintf(ProtoCodeLineRsp, v[:n2],code) + protoData += fmt.Sprintf(ProtoCodeLineRsp, v[:n2], code) } } } - return protoData ,goProtoData + return protoData, goProtoData } -func ReadProtos(readPath, OutPath string ) error { +func ReadProtos(readPath, OutPath string) error { files, err := ioutil.ReadDir(readPath) if err != nil { return fmt.Errorf("ReadExcel|ReadDir is err:%v", err) } - protoData, goProtoData := "", "" for _, file := range files { - if path.Ext(file.Name()) != ".proto"{ + if path.Ext(file.Name()) != ".proto" { continue } tprotoData, tgoProtoData := ProtoToCode(readPath, file.Name()) if tprotoData == "" || tgoProtoData == "" { - continue + continue } protoData += tprotoData goProtoData += tgoProtoData } - fw, err := os.OpenFile( OutPath+"protos/protocode.proto", os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644) + fw, err := os.OpenFile(OutPath+"protos/protocode.proto", os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644) if err != nil { return fmt.Errorf("WriteNewFile|OpenFile is err:%v", err) } @@ -106,7 +106,7 @@ func ReadProtos(readPath, OutPath string ) error { return fmt.Errorf("WriteNewFile|Write is err:%v", err) } - fw, err = os.OpenFile( OutPath+"cmd/gameserver/plugin/protocode.go", os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644) + fw, err = os.OpenFile(OutPath+"cmd/gameserver/action/protocode.go", os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644) if err != nil { return fmt.Errorf("WriteNewFile|OpenFile is err:%v", err) } -- libgit2 0.21.2