mirror of
https://github.com/FlourishingWorld/hk4e.git
synced 2026-02-04 16:02:26 +08:00
添加了节点服务器,各个服务器之间支持多对多
This commit is contained in:
6
Makefile
6
Makefile
@@ -23,6 +23,10 @@ gen:
|
|||||||
--go_out=paths=source_relative:gs/api \
|
--go_out=paths=source_relative:gs/api \
|
||||||
--natsrpc_out=paths=source_relative:gs/api \
|
--natsrpc_out=paths=source_relative:gs/api \
|
||||||
gs/api/*.proto
|
gs/api/*.proto
|
||||||
|
protoc \
|
||||||
|
--proto_path=node/api \
|
||||||
|
--go_out=paths=source_relative:node/api \
|
||||||
|
--natsrpc_out=paths=source_relative:node/api \
|
||||||
|
node/api/*.proto
|
||||||
#cd protocol/proto && make gen
|
#cd protocol/proto && make gen
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
17
README.md
17
README.md
@@ -4,19 +4,20 @@ hk4e game server
|
|||||||
|
|
||||||
## 开发快速上手
|
## 开发快速上手
|
||||||
|
|
||||||
* Go >= 1.19
|
* Go >= 1.18
|
||||||
|
|
||||||
1. 首次需要安装工具 `make dev_tool`
|
1. 首次需要安装工具 `make dev_tool`
|
||||||
1. 生成协议 `make gen`
|
2. 生成协议 `make gen`
|
||||||
|
|
||||||
## 快速运行
|
## 快速运行
|
||||||
|
|
||||||
* mongodb
|
* mongodb
|
||||||
* nats-server
|
* nats-server
|
||||||
|
|
||||||
1. 启动http登录服务器 `cmd/dispatch && go run .`
|
1. 启动节点服务器 `cmd/node && go run .`
|
||||||
2. 启动网关服务器 `cd cmd/gate && go run .`
|
2. 启动http登录服务器 `cmd/dispatch && go run .`
|
||||||
3. 启动游戏服务器 `cd cmd/gs && go run .`
|
3. 启动网关服务器 `cd cmd/gate && go run .`
|
||||||
4. 启动游戏管理服务器 `cmd/gm && go run .`
|
4. 启动战斗服务器 `cmd/fight && go run .`
|
||||||
5. 启动战斗服务器 `cmd/fight && go run .`
|
5. 启动寻路服务器 `cmd/pathfinding && go run .`
|
||||||
6. 启动寻路服务器 `cmd/pathfinding && go run .`
|
6. 启动游戏服务器 `cd cmd/gs && go run .`
|
||||||
|
7. 启动游戏管理服务器 `cmd/gm && go run .`
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
|
|
||||||
"hk4e/dispatch/app"
|
"hk4e/dispatch/app"
|
||||||
|
"hk4e/pkg/statsviz_serve"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -16,7 +17,12 @@ var (
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
// go statsviz_serve.Serve("0.0.0.0:2345")
|
go func() {
|
||||||
|
err := statsviz_serve.Serve("0.0.0.0:2345")
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
err := app.Run(context.TODO(), *config)
|
err := app.Run(context.TODO(), *config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
|
|
||||||
"hk4e/fight/app"
|
"hk4e/fight/app"
|
||||||
|
"hk4e/pkg/statsviz_serve"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -16,7 +17,9 @@ var (
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
// go statsviz_serve.Serve("0.0.0.0:2345")
|
go func() {
|
||||||
|
_ = statsviz_serve.Serve("0.0.0.0:5678")
|
||||||
|
}()
|
||||||
err := app.Run(context.TODO(), *config)
|
err := app.Run(context.TODO(), *config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
|
|||||||
@@ -17,7 +17,9 @@ var (
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
go statsviz_serve.Serve("0.0.0.0:2345")
|
go func() {
|
||||||
|
_ = statsviz_serve.Serve("0.0.0.0:3456")
|
||||||
|
}()
|
||||||
err := app.Run(context.TODO(), *config)
|
err := app.Run(context.TODO(), *config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
|
|||||||
@@ -4,9 +4,11 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
_ "net/http/pprof"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"hk4e/gm/app"
|
"hk4e/gm/app"
|
||||||
|
"hk4e/pkg/statsviz_serve"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -15,6 +17,12 @@ var (
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
go func() {
|
||||||
|
err := statsviz_serve.Serve("0.0.0.0:7890")
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
err := app.Run(context.TODO(), *config)
|
err := app.Run(context.TODO(), *config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
|
|||||||
@@ -17,7 +17,9 @@ var (
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
go statsviz_serve.Serve("0.0.0.0:3456")
|
go func() {
|
||||||
|
_ = statsviz_serve.Serve("0.0.0.0:4567")
|
||||||
|
}()
|
||||||
err := app.Run(context.TODO(), *config)
|
err := app.Run(context.TODO(), *config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
|
|||||||
23
cmd/hk4e/node.go
Normal file
23
cmd/hk4e/node.go
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"hk4e/node/app"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NodeCmd 检查配表命令
|
||||||
|
func NodeCmd() *cobra.Command {
|
||||||
|
var cfg string
|
||||||
|
c := &cobra.Command{
|
||||||
|
Use: "node",
|
||||||
|
Short: "node server",
|
||||||
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
return app.Run(context.Background(), cfg)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
c.Flags().StringVar(&cfg, "config", "application.toml", "config file")
|
||||||
|
return c
|
||||||
|
}
|
||||||
12
cmd/node/application.toml
Normal file
12
cmd/node/application.toml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
[hk4e]
|
||||||
|
kcp_addr = "127.0.0.1"
|
||||||
|
kcp_port = 22103
|
||||||
|
|
||||||
|
[logger]
|
||||||
|
level = "DEBUG"
|
||||||
|
mode = "BOTH"
|
||||||
|
track = true
|
||||||
|
max_size = 10485760
|
||||||
|
|
||||||
|
[mq]
|
||||||
|
nats_url = "nats://nats:4222"
|
||||||
31
cmd/node/main.go
Normal file
31
cmd/node/main.go
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
_ "net/http/pprof"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"hk4e/node/app"
|
||||||
|
"hk4e/pkg/statsviz_serve"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
config = flag.String("config", "application.toml", "config file")
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
flag.Parse()
|
||||||
|
go func() {
|
||||||
|
err := statsviz_serve.Serve("0.0.0.0:1234")
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
err := app.Run(context.TODO(), *config)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,6 +8,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
|
|
||||||
"hk4e/pathfinding/app"
|
"hk4e/pathfinding/app"
|
||||||
|
"hk4e/pkg/statsviz_serve"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -16,7 +17,9 @@ var (
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
// go statsviz_serve.Serve("0.0.0.0:2345")
|
go func() {
|
||||||
|
_ = statsviz_serve.Serve("0.0.0.0:6789")
|
||||||
|
}()
|
||||||
err := app.Run(context.TODO(), *config)
|
err := app.Run(context.TODO(), *config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
|
|||||||
@@ -10,12 +10,20 @@ import (
|
|||||||
pb "google.golang.org/protobuf/proto"
|
pb "google.golang.org/protobuf/proto"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// 用于服务器之间传输游戏协议
|
||||||
|
// 仅用于传递数据平面(client<--->server)和控制平面(server<--->server)的消息
|
||||||
|
// 目前是全部消息都走NATS 之后可以做优化服务器之间socket直连
|
||||||
|
// 请不要用这个来搞RPC写一大堆异步回调!!!
|
||||||
|
// 要用RPC有专门的NATSRPC
|
||||||
|
|
||||||
type MessageQueue struct {
|
type MessageQueue struct {
|
||||||
natsConn *nats.Conn
|
natsConn *nats.Conn
|
||||||
natsMsgChan chan *nats.Msg
|
natsMsgChan chan *nats.Msg
|
||||||
netMsgInput chan *NetMsg
|
netMsgInput chan *NetMsg
|
||||||
netMsgOutput chan *NetMsg
|
netMsgOutput chan *NetMsg
|
||||||
cmdProtoMap *cmd.CmdProtoMap
|
cmdProtoMap *cmd.CmdProtoMap
|
||||||
|
serverType string
|
||||||
|
appId string
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewMessageQueue(serverType string, appId string) (r *MessageQueue) {
|
func NewMessageQueue(serverType string, appId string) (r *MessageQueue) {
|
||||||
@@ -35,6 +43,8 @@ func NewMessageQueue(serverType string, appId string) (r *MessageQueue) {
|
|||||||
r.netMsgInput = make(chan *NetMsg, 1000)
|
r.netMsgInput = make(chan *NetMsg, 1000)
|
||||||
r.netMsgOutput = make(chan *NetMsg, 1000)
|
r.netMsgOutput = make(chan *NetMsg, 1000)
|
||||||
r.cmdProtoMap = cmd.NewCmdProtoMap()
|
r.cmdProtoMap = cmd.NewCmdProtoMap()
|
||||||
|
r.serverType = serverType
|
||||||
|
r.appId = appId
|
||||||
go r.recvHandler()
|
go r.recvHandler()
|
||||||
go r.sendHandler()
|
go r.sendHandler()
|
||||||
return r
|
return r
|
||||||
|
|||||||
@@ -9,12 +9,14 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type NetMsg struct {
|
type NetMsg struct {
|
||||||
MsgType uint8 `msgpack:"MsgType"`
|
MsgType uint8 `msgpack:"MsgType"`
|
||||||
EventId uint16 `msgpack:"EventId"`
|
EventId uint16 `msgpack:"EventId"`
|
||||||
Topic string `msgpack:"-"`
|
Topic string `msgpack:"-"`
|
||||||
GameMsg *GameMsg `msgpack:"GameMsg"`
|
GameMsg *GameMsg `msgpack:"GameMsg"`
|
||||||
FightMsg *FightMsg `msgpack:"FightMsg"`
|
FightMsg *FightMsg `msgpack:"FightMsg"`
|
||||||
ConnCtrlMsg *ConnCtrlMsg `msgpack:"ConnCtrlMsg"`
|
ConnCtrlMsg *ConnCtrlMsg `msgpack:"ConnCtrlMsg"`
|
||||||
|
OriginServerType string `msgpack:"OriginServerType"`
|
||||||
|
OriginServerAppId string `msgpack:"OriginServerAppId"`
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -33,15 +35,17 @@ type GameMsg struct {
|
|||||||
const (
|
const (
|
||||||
ClientRttNotify = iota
|
ClientRttNotify = iota
|
||||||
ClientTimeNotify
|
ClientTimeNotify
|
||||||
|
FightServerSelectNotify
|
||||||
KickPlayerNotify
|
KickPlayerNotify
|
||||||
)
|
)
|
||||||
|
|
||||||
type ConnCtrlMsg struct {
|
type ConnCtrlMsg struct {
|
||||||
UserId uint32 `msgpack:"UserId"`
|
UserId uint32 `msgpack:"UserId"`
|
||||||
ClientRtt uint32 `msgpack:"ClientRtt"`
|
ClientRtt uint32 `msgpack:"ClientRtt"`
|
||||||
ClientTime uint32 `msgpack:"ClientTime"`
|
ClientTime uint32 `msgpack:"ClientTime"`
|
||||||
KickUserId uint32 `msgpack:"KickUserId"`
|
FightServerAppId string `msgpack:"FightServerAppId"`
|
||||||
KickReason uint32 `msgpack:"KickReason"`
|
KickUserId uint32 `msgpack:"KickUserId"`
|
||||||
|
KickReason uint32 `msgpack:"KickReason"`
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -52,9 +56,10 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type FightMsg struct {
|
type FightMsg struct {
|
||||||
FightRoutineId uint32 `msgpack:"FightRoutineId"`
|
FightRoutineId uint32 `msgpack:"FightRoutineId"`
|
||||||
EntityId uint32 `msgpack:"EntityId"`
|
EntityId uint32 `msgpack:"EntityId"`
|
||||||
FightPropMap map[uint32]float32 `msgpack:"FightPropMap"`
|
FightPropMap map[uint32]float32 `msgpack:"FightPropMap"`
|
||||||
Uid uint32 `msgpack:"Uid"`
|
Uid uint32 `msgpack:"Uid"`
|
||||||
AvatarGuid uint64 `msgpack:"AvatarGuid"`
|
AvatarGuid uint64 `msgpack:"AvatarGuid"`
|
||||||
|
GateServerAppId string `msgpack:"GateServerAppId"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,37 +1,48 @@
|
|||||||
package mq
|
package mq
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strings"
|
"hk4e/node/api"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
func (m *MessageQueue) getOriginServer() (originServerType string, originServerAppId string) {
|
||||||
GATE = "GATE_${APPID}_HK4E"
|
originServerType = m.serverType
|
||||||
GS = "GS_${APPID}_HK4E"
|
originServerAppId = m.appId
|
||||||
FIGHT = "FIGHT_${APPID}_HK4E"
|
return originServerType, originServerAppId
|
||||||
PATHFINDING = "PATHFINDING_${APPID}_HK4E"
|
}
|
||||||
)
|
|
||||||
|
|
||||||
func (m *MessageQueue) getTopic(serverType string, appId string) string {
|
func (m *MessageQueue) getTopic(serverType string, appId string) string {
|
||||||
topic := strings.ReplaceAll(serverType, "${APPID}", appId)
|
topic := serverType + "_" + appId + "_" + "HK4E"
|
||||||
return topic
|
return topic
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *MessageQueue) SendToGate(appId string, netMsg *NetMsg) {
|
func (m *MessageQueue) SendToGate(appId string, netMsg *NetMsg) {
|
||||||
netMsg.Topic = m.getTopic(GATE, appId)
|
netMsg.Topic = m.getTopic(api.GATE, appId)
|
||||||
|
originServerType, originServerAppId := m.getOriginServer()
|
||||||
|
netMsg.OriginServerType = originServerType
|
||||||
|
netMsg.OriginServerAppId = originServerAppId
|
||||||
m.netMsgInput <- netMsg
|
m.netMsgInput <- netMsg
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *MessageQueue) SendToGs(appId string, netMsg *NetMsg) {
|
func (m *MessageQueue) SendToGs(appId string, netMsg *NetMsg) {
|
||||||
netMsg.Topic = m.getTopic(GS, appId)
|
netMsg.Topic = m.getTopic(api.GS, appId)
|
||||||
|
originServerType, originServerAppId := m.getOriginServer()
|
||||||
|
netMsg.OriginServerType = originServerType
|
||||||
|
netMsg.OriginServerAppId = originServerAppId
|
||||||
m.netMsgInput <- netMsg
|
m.netMsgInput <- netMsg
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *MessageQueue) SendToFight(appId string, netMsg *NetMsg) {
|
func (m *MessageQueue) SendToFight(appId string, netMsg *NetMsg) {
|
||||||
netMsg.Topic = m.getTopic(FIGHT, appId)
|
netMsg.Topic = m.getTopic(api.FIGHT, appId)
|
||||||
|
originServerType, originServerAppId := m.getOriginServer()
|
||||||
|
netMsg.OriginServerType = originServerType
|
||||||
|
netMsg.OriginServerAppId = originServerAppId
|
||||||
m.netMsgInput <- netMsg
|
m.netMsgInput <- netMsg
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *MessageQueue) SendToPathfinding(appId string, netMsg *NetMsg) {
|
func (m *MessageQueue) SendToPathfinding(appId string, netMsg *NetMsg) {
|
||||||
netMsg.Topic = m.getTopic(PATHFINDING, appId)
|
netMsg.Topic = m.getTopic(api.PATHFINDING, appId)
|
||||||
|
originServerType, originServerAppId := m.getOriginServer()
|
||||||
|
netMsg.OriginServerType = originServerType
|
||||||
|
netMsg.OriginServerAppId = originServerAppId
|
||||||
m.netMsgInput <- netMsg
|
m.netMsgInput <- netMsg
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,8 +33,11 @@ func LoadRsaKey() (signRsaKey []byte, encRsaKeyMap map[string][]byte, pwdRsaKey
|
|||||||
return signRsaKey, encRsaKeyMap, pwdRsaKey
|
return signRsaKey, encRsaKeyMap, pwdRsaKey
|
||||||
}
|
}
|
||||||
|
|
||||||
func InitRegion(kcpAddr string, kcpPort int32) (*proto.QueryCurrRegionHttpRsp, *proto.QueryRegionListHttpRsp, *random.Ec2b) {
|
func InitRegion(kcpAddr string, kcpPort int32, ec2b *random.Ec2b) (*proto.QueryCurrRegionHttpRsp, *proto.QueryRegionListHttpRsp, *random.Ec2b) {
|
||||||
dispatchEc2b := random.NewEc2b()
|
dispatchEc2b := random.NewEc2b()
|
||||||
|
if ec2b != nil {
|
||||||
|
dispatchEc2b = ec2b
|
||||||
|
}
|
||||||
dispatchEc2bData := dispatchEc2b.Bytes()
|
dispatchEc2bData := dispatchEc2b.Bytes()
|
||||||
dispatchXorKey := dispatchEc2b.XorKey()
|
dispatchXorKey := dispatchEc2b.XorKey()
|
||||||
// RegionCurr
|
// RegionCurr
|
||||||
|
|||||||
81
common/rpc/client.go
Normal file
81
common/rpc/client.go
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
package rpc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"hk4e/common/config"
|
||||||
|
gsapi "hk4e/gs/api"
|
||||||
|
nodeapi "hk4e/node/api"
|
||||||
|
|
||||||
|
"github.com/nats-io/nats.go"
|
||||||
|
"github.com/nats-io/nats.go/encoders/protobuf"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Client natsrpc客户端
|
||||||
|
type Client struct {
|
||||||
|
conn *nats.Conn
|
||||||
|
Discovery *DiscoveryClient
|
||||||
|
GM *GMClient
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewClient 构造
|
||||||
|
func NewClient() (*Client, error) {
|
||||||
|
r := new(Client)
|
||||||
|
conn, err := nats.Connect(config.CONF.MQ.NatsUrl)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
r.conn = conn
|
||||||
|
discoveryClient, err := newDiscoveryClient(conn)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
r.Discovery = discoveryClient
|
||||||
|
gmClient, err := newGmClient(conn)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
r.GM = gmClient
|
||||||
|
return r, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close 销毁
|
||||||
|
func (c *Client) Close() {
|
||||||
|
c.conn.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
// DiscoveryClient node的discovery服务
|
||||||
|
type DiscoveryClient struct {
|
||||||
|
nodeapi.DiscoveryNATSRPCClient
|
||||||
|
}
|
||||||
|
|
||||||
|
func newDiscoveryClient(conn *nats.Conn) (*DiscoveryClient, error) {
|
||||||
|
enc, err := nats.NewEncodedConn(conn, protobuf.PROTOBUF_ENCODER)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
cli, err := nodeapi.NewDiscoveryNATSRPCClient(enc)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &DiscoveryClient{
|
||||||
|
DiscoveryNATSRPCClient: cli,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GMClient gs的gm服务
|
||||||
|
type GMClient struct {
|
||||||
|
gsapi.GMNATSRPCClient
|
||||||
|
}
|
||||||
|
|
||||||
|
func newGmClient(conn *nats.Conn) (*GMClient, error) {
|
||||||
|
enc, err := nats.NewEncodedConn(conn, protobuf.PROTOBUF_ENCODER)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
cli, err := gsapi.NewGMNATSRPCClient(enc)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &GMClient{
|
||||||
|
GMNATSRPCClient: cli,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
@@ -9,6 +9,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"hk4e/common/config"
|
"hk4e/common/config"
|
||||||
|
"hk4e/common/rpc"
|
||||||
"hk4e/dispatch/controller"
|
"hk4e/dispatch/controller"
|
||||||
"hk4e/dispatch/dao"
|
"hk4e/dispatch/dao"
|
||||||
"hk4e/pkg/logger"
|
"hk4e/pkg/logger"
|
||||||
@@ -23,7 +24,12 @@ func Run(ctx context.Context, configFile string) error {
|
|||||||
db := dao.NewDao()
|
db := dao.NewDao()
|
||||||
defer db.CloseDao()
|
defer db.CloseDao()
|
||||||
|
|
||||||
_ = controller.NewController(db)
|
client, err := rpc.NewClient()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_ = controller.NewController(db, client.Discovery)
|
||||||
|
|
||||||
c := make(chan os.Signal, 1)
|
c := make(chan os.Signal, 1)
|
||||||
signal.Notify(c, syscall.SIGHUP, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT)
|
signal.Notify(c, syscall.SIGHUP, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT)
|
||||||
|
|||||||
@@ -1,13 +1,16 @@
|
|||||||
package controller
|
package controller
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"hk4e/common/config"
|
"hk4e/common/config"
|
||||||
"hk4e/common/region"
|
"hk4e/common/region"
|
||||||
|
"hk4e/common/rpc"
|
||||||
"hk4e/dispatch/dao"
|
"hk4e/dispatch/dao"
|
||||||
|
"hk4e/node/api"
|
||||||
"hk4e/pkg/logger"
|
"hk4e/pkg/logger"
|
||||||
"hk4e/pkg/random"
|
"hk4e/pkg/random"
|
||||||
|
|
||||||
@@ -17,22 +20,32 @@ import (
|
|||||||
|
|
||||||
type Controller struct {
|
type Controller struct {
|
||||||
dao *dao.Dao
|
dao *dao.Dao
|
||||||
|
discovery *rpc.DiscoveryClient
|
||||||
regionListBase64 string
|
regionListBase64 string
|
||||||
regionCurrBase64 string
|
regionCurrBase64 string
|
||||||
signRsaKey []byte
|
signRsaKey []byte
|
||||||
encRsaKeyMap map[string][]byte
|
encRsaKeyMap map[string][]byte
|
||||||
pwdRsaKey []byte
|
pwdRsaKey []byte
|
||||||
dispatchEc2b *random.Ec2b
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewController(dao *dao.Dao) (r *Controller) {
|
func NewController(dao *dao.Dao, discovery *rpc.DiscoveryClient) (r *Controller) {
|
||||||
r = new(Controller)
|
r = new(Controller)
|
||||||
r.dao = dao
|
r.dao = dao
|
||||||
|
r.discovery = discovery
|
||||||
r.regionListBase64 = ""
|
r.regionListBase64 = ""
|
||||||
r.regionCurrBase64 = ""
|
r.regionCurrBase64 = ""
|
||||||
regionCurr, regionList, dispatchEc2b := region.InitRegion(config.CONF.Hk4e.KcpAddr, config.CONF.Hk4e.KcpPort)
|
|
||||||
r.dispatchEc2b = dispatchEc2b
|
|
||||||
r.signRsaKey, r.encRsaKeyMap, r.pwdRsaKey = region.LoadRsaKey()
|
r.signRsaKey, r.encRsaKeyMap, r.pwdRsaKey = region.LoadRsaKey()
|
||||||
|
rsp, err := r.discovery.GetRegionEc2B(context.TODO(), &api.NullMsg{})
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("get region ec2b error: %v", err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
ec2b, err := random.LoadEc2bKey(rsp.Data)
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("parse region ec2b error: %v", err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
regionCurr, regionList, _ := region.InitRegion(config.CONF.Hk4e.KcpAddr, config.CONF.Hk4e.KcpPort, ec2b)
|
||||||
regionCurrModify, err := pb.Marshal(regionCurr)
|
regionCurrModify, err := pb.Marshal(regionCurr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error("Marshal QueryCurrRegionHttpRsp error")
|
logger.Error("Marshal QueryCurrRegionHttpRsp error")
|
||||||
@@ -143,7 +156,6 @@ func (c *Controller) registerRouter() {
|
|||||||
}
|
}
|
||||||
engine.Use(c.authorize())
|
engine.Use(c.authorize())
|
||||||
engine.POST("/gate/token/verify", c.gateTokenVerify)
|
engine.POST("/gate/token/verify", c.gateTokenVerify)
|
||||||
engine.GET("/dispatch/ec2b/seed", c.getDispatchEc2bSeed)
|
|
||||||
port := config.CONF.HttpPort
|
port := config.CONF.HttpPort
|
||||||
addr := ":" + strconv.Itoa(int(port))
|
addr := ":" + strconv.Itoa(int(port))
|
||||||
err := engine.Run(addr)
|
err := engine.Run(addr)
|
||||||
|
|||||||
@@ -49,14 +49,3 @@ func (c *Controller) gateTokenVerify(context *gin.Context) {
|
|||||||
PlayerID: uint32(account.PlayerID),
|
PlayerID: uint32(account.PlayerID),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
type DispatchEc2bSeedRsp struct {
|
|
||||||
Seed string `json:"seed"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Controller) getDispatchEc2bSeed(context *gin.Context) {
|
|
||||||
dispatchEc2bSeed := c.dispatchEc2b.Seed()
|
|
||||||
context.JSON(http.StatusOK, &DispatchEc2bSeedRsp{
|
|
||||||
Seed: strconv.FormatUint(dispatchEc2bSeed, 10),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -9,21 +9,40 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"hk4e/common/config"
|
"hk4e/common/config"
|
||||||
|
"hk4e/common/constant"
|
||||||
"hk4e/common/mq"
|
"hk4e/common/mq"
|
||||||
|
"hk4e/common/rpc"
|
||||||
"hk4e/fight/engine"
|
"hk4e/fight/engine"
|
||||||
"hk4e/gs/constant"
|
"hk4e/node/api"
|
||||||
"hk4e/pkg/logger"
|
"hk4e/pkg/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var APPID string
|
||||||
|
|
||||||
func Run(ctx context.Context, configFile string) error {
|
func Run(ctx context.Context, configFile string) error {
|
||||||
config.InitConfig(configFile)
|
config.InitConfig(configFile)
|
||||||
|
|
||||||
logger.InitLogger("fight")
|
// natsrpc client
|
||||||
logger.Warn("fight start")
|
client, err := rpc.NewClient()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 注册到节点服务器
|
||||||
|
rsp, err := client.Discovery.RegisterServer(context.TODO(), &api.RegisterServerReq{
|
||||||
|
ServerType: api.FIGHT,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
APPID = rsp.GetAppId()
|
||||||
|
|
||||||
|
logger.InitLogger("fight_" + APPID)
|
||||||
|
logger.Warn("fight start, appid: %v", APPID)
|
||||||
|
|
||||||
constant.InitConstant()
|
constant.InitConstant()
|
||||||
|
|
||||||
messageQueue := mq.NewMessageQueue(mq.FIGHT, "1")
|
messageQueue := mq.NewMessageQueue(api.FIGHT, APPID)
|
||||||
defer messageQueue.Close()
|
defer messageQueue.Close()
|
||||||
|
|
||||||
_ = engine.NewFightEngine(messageQueue)
|
_ = engine.NewFightEngine(messageQueue)
|
||||||
@@ -38,7 +57,7 @@ func Run(ctx context.Context, configFile string) error {
|
|||||||
logger.Warn("get a signal %s", s.String())
|
logger.Warn("get a signal %s", s.String())
|
||||||
switch s {
|
switch s {
|
||||||
case syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT:
|
case syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT:
|
||||||
logger.Warn("fight exit")
|
logger.Warn("fight exit, appid: %v", APPID)
|
||||||
time.Sleep(time.Second)
|
time.Sleep(time.Second)
|
||||||
return nil
|
return nil
|
||||||
case syscall.SIGHUP:
|
case syscall.SIGHUP:
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ package engine
|
|||||||
import (
|
import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"hk4e/common/constant"
|
||||||
"hk4e/common/mq"
|
"hk4e/common/mq"
|
||||||
"hk4e/gs/constant"
|
|
||||||
"hk4e/pkg/logger"
|
"hk4e/pkg/logger"
|
||||||
"hk4e/protocol/cmd"
|
"hk4e/protocol/cmd"
|
||||||
"hk4e/protocol/proto"
|
"hk4e/protocol/proto"
|
||||||
@@ -29,16 +29,24 @@ func (f *FightEngine) fightHandle() {
|
|||||||
userIdFightRoutineIdMap := make(map[uint32]uint32)
|
userIdFightRoutineIdMap := make(map[uint32]uint32)
|
||||||
for {
|
for {
|
||||||
netMsg := <-f.messageQueue.GetNetMsg()
|
netMsg := <-f.messageQueue.GetNetMsg()
|
||||||
// logger.Debug("recv net msg, netMsg: %v", netMsg)
|
logger.Debug("recv net msg, netMsg: %v", netMsg)
|
||||||
switch netMsg.MsgType {
|
switch netMsg.MsgType {
|
||||||
case mq.MsgTypeGame:
|
case mq.MsgTypeGame:
|
||||||
gameMsg := netMsg.GameMsg
|
gameMsg := netMsg.GameMsg
|
||||||
if netMsg.EventId != mq.NormalMsg {
|
if netMsg.EventId != mq.NormalMsg {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
// logger.Debug("recv game msg, gameMsg: %v", gameMsg)
|
logger.Debug("recv game msg, gameMsg: %v", gameMsg)
|
||||||
fightRoutineId := userIdFightRoutineIdMap[gameMsg.UserId]
|
fightRoutineId, exist := userIdFightRoutineIdMap[gameMsg.UserId]
|
||||||
fightRoutineMsgChan := fightRoutineMsgChanMap[fightRoutineId]
|
if !exist {
|
||||||
|
logger.Error("could not found fight routine id by uid: %v", gameMsg.UserId)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
fightRoutineMsgChan, exist := fightRoutineMsgChanMap[fightRoutineId]
|
||||||
|
if !exist {
|
||||||
|
logger.Error("could not found fight routine msg chan by fight routine id: %v", fightRoutineId)
|
||||||
|
continue
|
||||||
|
}
|
||||||
fightRoutineMsgChan <- netMsg
|
fightRoutineMsgChan <- netMsg
|
||||||
case mq.MsgTypeFight:
|
case mq.MsgTypeFight:
|
||||||
fightMsg := netMsg.FightMsg
|
fightMsg := netMsg.FightMsg
|
||||||
@@ -49,21 +57,33 @@ func (f *FightEngine) fightHandle() {
|
|||||||
fightRoutineMsgChanMap[fightMsg.FightRoutineId] = fightRoutineMsgChan
|
fightRoutineMsgChanMap[fightMsg.FightRoutineId] = fightRoutineMsgChan
|
||||||
fightRoutineCloseChan := make(chan bool, 1)
|
fightRoutineCloseChan := make(chan bool, 1)
|
||||||
fightRoutineCloseChanMap[fightMsg.FightRoutineId] = fightRoutineCloseChan
|
fightRoutineCloseChanMap[fightMsg.FightRoutineId] = fightRoutineCloseChan
|
||||||
go runFightRoutine(fightMsg.FightRoutineId, fightRoutineMsgChan, fightRoutineCloseChan, f.messageQueue)
|
go runFightRoutine(fightMsg.FightRoutineId, fightMsg.GateServerAppId, fightRoutineMsgChan, fightRoutineCloseChan, f.messageQueue)
|
||||||
case mq.DelFightRoutine:
|
case mq.DelFightRoutine:
|
||||||
fightRoutineCloseChan := fightRoutineCloseChanMap[fightMsg.FightRoutineId]
|
fightRoutineCloseChan, exist := fightRoutineCloseChanMap[fightMsg.FightRoutineId]
|
||||||
|
if !exist {
|
||||||
|
logger.Error("could not found fight routine close chan by fight routine id: %v", fightMsg.FightRoutineId)
|
||||||
|
continue
|
||||||
|
}
|
||||||
fightRoutineCloseChan <- true
|
fightRoutineCloseChan <- true
|
||||||
case mq.FightRoutineAddEntity:
|
case mq.FightRoutineAddEntity:
|
||||||
if fightMsg.Uid != 0 {
|
if fightMsg.Uid != 0 {
|
||||||
userIdFightRoutineIdMap[fightMsg.Uid] = fightMsg.FightRoutineId
|
userIdFightRoutineIdMap[fightMsg.Uid] = fightMsg.FightRoutineId
|
||||||
}
|
}
|
||||||
fightRoutineMsgChan := fightRoutineMsgChanMap[fightMsg.FightRoutineId]
|
fightRoutineMsgChan, exist := fightRoutineMsgChanMap[fightMsg.FightRoutineId]
|
||||||
|
if !exist {
|
||||||
|
logger.Error("could not found fight routine msg chan by fight routine id: %v", fightMsg.FightRoutineId)
|
||||||
|
continue
|
||||||
|
}
|
||||||
fightRoutineMsgChan <- netMsg
|
fightRoutineMsgChan <- netMsg
|
||||||
case mq.FightRoutineDelEntity:
|
case mq.FightRoutineDelEntity:
|
||||||
if fightMsg.Uid != 0 {
|
if fightMsg.Uid != 0 {
|
||||||
delete(userIdFightRoutineIdMap, fightMsg.Uid)
|
delete(userIdFightRoutineIdMap, fightMsg.Uid)
|
||||||
}
|
}
|
||||||
fightRoutineMsgChan := fightRoutineMsgChanMap[fightMsg.FightRoutineId]
|
fightRoutineMsgChan, exist := fightRoutineMsgChanMap[fightMsg.FightRoutineId]
|
||||||
|
if !exist {
|
||||||
|
logger.Error("could not found fight routine msg chan by fight routine id: %v", fightMsg.FightRoutineId)
|
||||||
|
continue
|
||||||
|
}
|
||||||
fightRoutineMsgChan <- netMsg
|
fightRoutineMsgChan <- netMsg
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -71,7 +91,7 @@ func (f *FightEngine) fightHandle() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SendMsg 发送消息给客户端
|
// SendMsg 发送消息给客户端
|
||||||
func SendMsg(messageQueue *mq.MessageQueue, cmdId uint16, userId uint32, payloadMsg pb.Message) {
|
func SendMsg(messageQueue *mq.MessageQueue, cmdId uint16, userId uint32, gateAppId string, payloadMsg pb.Message) {
|
||||||
if userId < 100000000 || payloadMsg == nil {
|
if userId < 100000000 || payloadMsg == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -86,7 +106,7 @@ func SendMsg(messageQueue *mq.MessageQueue, cmdId uint16, userId uint32, payload
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
gameMsg.PayloadMessageData = payloadMessageData
|
gameMsg.PayloadMessageData = payloadMessageData
|
||||||
messageQueue.SendToGate("1", &mq.NetMsg{
|
messageQueue.SendToGate(gateAppId, &mq.NetMsg{
|
||||||
MsgType: mq.MsgTypeGame,
|
MsgType: mq.MsgTypeGame,
|
||||||
EventId: mq.NormalMsg,
|
EventId: mq.NormalMsg,
|
||||||
GameMsg: gameMsg,
|
GameMsg: gameMsg,
|
||||||
@@ -106,14 +126,16 @@ type FightRoutine struct {
|
|||||||
entityMap map[uint32]*Entity
|
entityMap map[uint32]*Entity
|
||||||
combatInvokeEntryList []*proto.CombatInvokeEntry
|
combatInvokeEntryList []*proto.CombatInvokeEntry
|
||||||
tickCount uint64
|
tickCount uint64
|
||||||
|
gateAppId string
|
||||||
}
|
}
|
||||||
|
|
||||||
func runFightRoutine(fightRoutineId uint32, fightRoutineMsgChan chan *mq.NetMsg, fightRoutineCloseChan chan bool, messageQueue *mq.MessageQueue) {
|
func runFightRoutine(fightRoutineId uint32, gateAppId string, fightRoutineMsgChan chan *mq.NetMsg, fightRoutineCloseChan chan bool, messageQueue *mq.MessageQueue) {
|
||||||
f := new(FightRoutine)
|
f := new(FightRoutine)
|
||||||
f.messageQueue = messageQueue
|
f.messageQueue = messageQueue
|
||||||
f.entityMap = make(map[uint32]*Entity)
|
f.entityMap = make(map[uint32]*Entity)
|
||||||
f.combatInvokeEntryList = make([]*proto.CombatInvokeEntry, 0)
|
f.combatInvokeEntryList = make([]*proto.CombatInvokeEntry, 0)
|
||||||
f.tickCount = 0
|
f.tickCount = 0
|
||||||
|
f.gateAppId = gateAppId
|
||||||
logger.Debug("create fight routine, fightRoutineId: %v", fightRoutineId)
|
logger.Debug("create fight routine, fightRoutineId: %v", fightRoutineId)
|
||||||
ticker := time.NewTicker(time.Millisecond * 10)
|
ticker := time.NewTicker(time.Millisecond * 10)
|
||||||
for {
|
for {
|
||||||
@@ -162,7 +184,7 @@ func (f *FightRoutine) onTick50MilliSecond(now int64) {
|
|||||||
combatInvocationsNotifyAll := new(proto.CombatInvocationsNotify)
|
combatInvocationsNotifyAll := new(proto.CombatInvocationsNotify)
|
||||||
combatInvocationsNotifyAll.InvokeList = f.combatInvokeEntryList
|
combatInvocationsNotifyAll.InvokeList = f.combatInvokeEntryList
|
||||||
for _, uid := range f.getAllPlayer(f.entityMap) {
|
for _, uid := range f.getAllPlayer(f.entityMap) {
|
||||||
SendMsg(f.messageQueue, cmd.CombatInvocationsNotify, uid, combatInvocationsNotifyAll)
|
SendMsg(f.messageQueue, cmd.CombatInvocationsNotify, uid, f.gateAppId, combatInvocationsNotifyAll)
|
||||||
}
|
}
|
||||||
f.combatInvokeEntryList = make([]*proto.CombatInvokeEntry, 0)
|
f.combatInvokeEntryList = make([]*proto.CombatInvokeEntry, 0)
|
||||||
}
|
}
|
||||||
@@ -180,7 +202,7 @@ func (f *FightRoutine) onTickSecond(now int64) {
|
|||||||
AvatarGuid: entity.avatarGuid,
|
AvatarGuid: entity.avatarGuid,
|
||||||
FightPropMap: entity.fightPropMap,
|
FightPropMap: entity.fightPropMap,
|
||||||
}
|
}
|
||||||
SendMsg(f.messageQueue, cmd.AvatarFightPropNotify, entity.uid, avatarFightPropNotify)
|
SendMsg(f.messageQueue, cmd.AvatarFightPropNotify, entity.uid, f.gateAppId, avatarFightPropNotify)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -231,7 +253,7 @@ func (f *FightRoutine) attackHandle(gameMsg *mq.GameMsg) {
|
|||||||
entityFightPropUpdateNotify.FightPropMap = make(map[uint32]float32)
|
entityFightPropUpdateNotify.FightPropMap = make(map[uint32]float32)
|
||||||
entityFightPropUpdateNotify.FightPropMap[uint32(constant.FightPropertyConst.FIGHT_PROP_CUR_HP)] = currHp
|
entityFightPropUpdateNotify.FightPropMap[uint32(constant.FightPropertyConst.FIGHT_PROP_CUR_HP)] = currHp
|
||||||
for _, uid := range f.getAllPlayer(f.entityMap) {
|
for _, uid := range f.getAllPlayer(f.entityMap) {
|
||||||
SendMsg(f.messageQueue, cmd.EntityFightPropUpdateNotify, uid, entityFightPropUpdateNotify)
|
SendMsg(f.messageQueue, cmd.EntityFightPropUpdateNotify, uid, f.gateAppId, entityFightPropUpdateNotify)
|
||||||
}
|
}
|
||||||
combatData, err := pb.Marshal(hitInfo)
|
combatData, err := pb.Marshal(hitInfo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -10,19 +10,38 @@ import (
|
|||||||
|
|
||||||
"hk4e/common/config"
|
"hk4e/common/config"
|
||||||
"hk4e/common/mq"
|
"hk4e/common/mq"
|
||||||
|
"hk4e/common/rpc"
|
||||||
"hk4e/gate/net"
|
"hk4e/gate/net"
|
||||||
|
"hk4e/node/api"
|
||||||
"hk4e/pkg/logger"
|
"hk4e/pkg/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var APPID string
|
||||||
|
|
||||||
func Run(ctx context.Context, configFile string) error {
|
func Run(ctx context.Context, configFile string) error {
|
||||||
config.InitConfig(configFile)
|
config.InitConfig(configFile)
|
||||||
|
|
||||||
logger.InitLogger("gate")
|
// natsrpc client
|
||||||
logger.Warn("gate start")
|
client, err := rpc.NewClient()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
messageQueue := mq.NewMessageQueue(mq.GATE, "1")
|
// 注册到节点服务器
|
||||||
|
rsp, err := client.Discovery.RegisterServer(context.TODO(), &api.RegisterServerReq{
|
||||||
|
ServerType: api.GATE,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
APPID = rsp.GetAppId()
|
||||||
|
|
||||||
connectManager := net.NewKcpConnectManager(messageQueue)
|
logger.InitLogger("gate_" + APPID)
|
||||||
|
logger.Warn("gate start, appid: %v", APPID)
|
||||||
|
|
||||||
|
messageQueue := mq.NewMessageQueue(api.GATE, APPID)
|
||||||
|
|
||||||
|
connectManager := net.NewKcpConnectManager(messageQueue, client.Discovery)
|
||||||
connectManager.Start()
|
connectManager.Start()
|
||||||
defer connectManager.Stop()
|
defer connectManager.Stop()
|
||||||
|
|
||||||
@@ -43,7 +62,7 @@ func Run(ctx context.Context, configFile string) error {
|
|||||||
logger.Warn("get a signal %s", s.String())
|
logger.Warn("get a signal %s", s.String())
|
||||||
switch s {
|
switch s {
|
||||||
case syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT:
|
case syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT:
|
||||||
logger.Warn("gate exit")
|
logger.Warn("gate exit, appid: %v", APPID)
|
||||||
time.Sleep(time.Second)
|
time.Sleep(time.Second)
|
||||||
return nil
|
return nil
|
||||||
case syscall.SIGHUP:
|
case syscall.SIGHUP:
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package net
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"context"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
@@ -13,6 +14,7 @@ import (
|
|||||||
"hk4e/common/mq"
|
"hk4e/common/mq"
|
||||||
"hk4e/dispatch/controller"
|
"hk4e/dispatch/controller"
|
||||||
"hk4e/gate/kcp"
|
"hk4e/gate/kcp"
|
||||||
|
"hk4e/node/api"
|
||||||
"hk4e/pkg/endec"
|
"hk4e/pkg/endec"
|
||||||
"hk4e/pkg/httpclient"
|
"hk4e/pkg/httpclient"
|
||||||
"hk4e/pkg/logger"
|
"hk4e/pkg/logger"
|
||||||
@@ -80,25 +82,25 @@ func (k *KcpConnectManager) recvMsgHandle(protoMsg *ProtoMsg, session *Session)
|
|||||||
if connState != ConnActive {
|
if connState != ConnActive {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// 通知GS玩家客户端的本地时钟
|
|
||||||
connCtrlMsg := new(mq.ConnCtrlMsg)
|
|
||||||
connCtrlMsg.UserId = userId
|
|
||||||
connCtrlMsg.ClientTime = pingReq.ClientTime
|
|
||||||
k.messageQueue.SendToGs("1", &mq.NetMsg{
|
|
||||||
MsgType: mq.MsgTypeConnCtrl,
|
|
||||||
EventId: mq.ClientTimeNotify,
|
|
||||||
ConnCtrlMsg: connCtrlMsg,
|
|
||||||
})
|
|
||||||
// 通知GS玩家客户端往返时延
|
// 通知GS玩家客户端往返时延
|
||||||
rtt := session.conn.GetSRTT()
|
rtt := session.conn.GetSRTT()
|
||||||
connCtrlMsg = new(mq.ConnCtrlMsg)
|
connCtrlMsg := new(mq.ConnCtrlMsg)
|
||||||
connCtrlMsg.UserId = userId
|
connCtrlMsg.UserId = userId
|
||||||
connCtrlMsg.ClientRtt = uint32(rtt)
|
connCtrlMsg.ClientRtt = uint32(rtt)
|
||||||
k.messageQueue.SendToGs("1", &mq.NetMsg{
|
k.messageQueue.SendToGs(session.gsServerAppId, &mq.NetMsg{
|
||||||
MsgType: mq.MsgTypeConnCtrl,
|
MsgType: mq.MsgTypeConnCtrl,
|
||||||
EventId: mq.ClientRttNotify,
|
EventId: mq.ClientRttNotify,
|
||||||
ConnCtrlMsg: connCtrlMsg,
|
ConnCtrlMsg: connCtrlMsg,
|
||||||
})
|
})
|
||||||
|
// 通知GS玩家客户端的本地时钟
|
||||||
|
connCtrlMsg = new(mq.ConnCtrlMsg)
|
||||||
|
connCtrlMsg.UserId = userId
|
||||||
|
connCtrlMsg.ClientTime = pingReq.ClientTime
|
||||||
|
k.messageQueue.SendToGs(session.gsServerAppId, &mq.NetMsg{
|
||||||
|
MsgType: mq.MsgTypeConnCtrl,
|
||||||
|
EventId: mq.ClientTimeNotify,
|
||||||
|
ConnCtrlMsg: connCtrlMsg,
|
||||||
|
})
|
||||||
default:
|
default:
|
||||||
if connState != ConnActive && !(protoMsg.CmdId == cmd.PlayerLoginReq || protoMsg.CmdId == cmd.SetPlayerBornDataReq) {
|
if connState != ConnActive && !(protoMsg.CmdId == cmd.PlayerLoginReq || protoMsg.CmdId == cmd.SetPlayerBornDataReq) {
|
||||||
logger.Error("conn not active so drop packet, cmdId: %v, userId: %v, convId: %v", protoMsg.CmdId, userId, protoMsg.ConvId)
|
logger.Error("conn not active so drop packet, cmdId: %v, userId: %v, convId: %v", protoMsg.CmdId, userId, protoMsg.ConvId)
|
||||||
@@ -106,12 +108,15 @@ func (k *KcpConnectManager) recvMsgHandle(protoMsg *ProtoMsg, session *Session)
|
|||||||
}
|
}
|
||||||
// 只转发到寻路服务器
|
// 只转发到寻路服务器
|
||||||
if protoMsg.CmdId == cmd.QueryPathReq || protoMsg.CmdId == cmd.ObstacleModifyNotify {
|
if protoMsg.CmdId == cmd.QueryPathReq || protoMsg.CmdId == cmd.ObstacleModifyNotify {
|
||||||
|
if session.pathfindingServerAppId == "" {
|
||||||
|
return
|
||||||
|
}
|
||||||
gameMsg := new(mq.GameMsg)
|
gameMsg := new(mq.GameMsg)
|
||||||
gameMsg.UserId = userId
|
gameMsg.UserId = userId
|
||||||
gameMsg.CmdId = protoMsg.CmdId
|
gameMsg.CmdId = protoMsg.CmdId
|
||||||
gameMsg.ClientSeq = protoMsg.HeadMessage.ClientSequenceId
|
gameMsg.ClientSeq = protoMsg.HeadMessage.ClientSequenceId
|
||||||
gameMsg.PayloadMessage = protoMsg.PayloadMessage
|
gameMsg.PayloadMessage = protoMsg.PayloadMessage
|
||||||
k.messageQueue.SendToPathfinding("1", &mq.NetMsg{
|
k.messageQueue.SendToPathfinding(session.pathfindingServerAppId, &mq.NetMsg{
|
||||||
MsgType: mq.MsgTypeGame,
|
MsgType: mq.MsgTypeGame,
|
||||||
EventId: mq.NormalMsg,
|
EventId: mq.NormalMsg,
|
||||||
GameMsg: gameMsg,
|
GameMsg: gameMsg,
|
||||||
@@ -119,13 +124,13 @@ func (k *KcpConnectManager) recvMsgHandle(protoMsg *ProtoMsg, session *Session)
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
// 同时转发到战斗服务器
|
// 同时转发到战斗服务器
|
||||||
if protoMsg.CmdId == cmd.CombatInvocationsNotify {
|
if protoMsg.CmdId == cmd.CombatInvocationsNotify && session.fightServerAppId != "" {
|
||||||
gameMsg := new(mq.GameMsg)
|
gameMsg := new(mq.GameMsg)
|
||||||
gameMsg.UserId = userId
|
gameMsg.UserId = userId
|
||||||
gameMsg.CmdId = protoMsg.CmdId
|
gameMsg.CmdId = protoMsg.CmdId
|
||||||
gameMsg.ClientSeq = protoMsg.HeadMessage.ClientSequenceId
|
gameMsg.ClientSeq = protoMsg.HeadMessage.ClientSequenceId
|
||||||
gameMsg.PayloadMessage = protoMsg.PayloadMessage
|
gameMsg.PayloadMessage = protoMsg.PayloadMessage
|
||||||
k.messageQueue.SendToFight("1", &mq.NetMsg{
|
k.messageQueue.SendToFight(session.fightServerAppId, &mq.NetMsg{
|
||||||
MsgType: mq.MsgTypeGame,
|
MsgType: mq.MsgTypeGame,
|
||||||
EventId: mq.NormalMsg,
|
EventId: mq.NormalMsg,
|
||||||
GameMsg: gameMsg,
|
GameMsg: gameMsg,
|
||||||
@@ -137,7 +142,7 @@ func (k *KcpConnectManager) recvMsgHandle(protoMsg *ProtoMsg, session *Session)
|
|||||||
gameMsg.CmdId = protoMsg.CmdId
|
gameMsg.CmdId = protoMsg.CmdId
|
||||||
gameMsg.ClientSeq = protoMsg.HeadMessage.ClientSequenceId
|
gameMsg.ClientSeq = protoMsg.HeadMessage.ClientSequenceId
|
||||||
gameMsg.PayloadMessage = protoMsg.PayloadMessage
|
gameMsg.PayloadMessage = protoMsg.PayloadMessage
|
||||||
k.messageQueue.SendToGs("1", &mq.NetMsg{
|
k.messageQueue.SendToGs(session.gsServerAppId, &mq.NetMsg{
|
||||||
MsgType: mq.MsgTypeGame,
|
MsgType: mq.MsgTypeGame,
|
||||||
EventId: mq.NormalMsg,
|
EventId: mq.NormalMsg,
|
||||||
GameMsg: gameMsg,
|
GameMsg: gameMsg,
|
||||||
@@ -269,6 +274,32 @@ func (k *KcpConnectManager) getPlayerToken(req *proto.GetPlayerTokenReq, session
|
|||||||
session.userId = tokenVerifyRsp.PlayerID
|
session.userId = tokenVerifyRsp.PlayerID
|
||||||
k.SetSession(session, session.conn.GetConv(), session.userId)
|
k.SetSession(session, session.conn.GetConv(), session.userId)
|
||||||
k.createSessionChan <- session
|
k.createSessionChan <- session
|
||||||
|
// 绑定各个服务器appid
|
||||||
|
gsServerAppId, err := k.discovery.GetServerAppId(context.TODO(), &api.GetServerAppIdReq{
|
||||||
|
ServerType: api.GS,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("get gs server appid error: %v", err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
session.gsServerAppId = gsServerAppId.AppId
|
||||||
|
fightServerAppId, err := k.discovery.GetServerAppId(context.TODO(), &api.GetServerAppIdReq{
|
||||||
|
ServerType: api.FIGHT,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("get fight server appid error: %v", err)
|
||||||
|
}
|
||||||
|
session.fightServerAppId = fightServerAppId.AppId
|
||||||
|
pathfindingServerAppId, err := k.discovery.GetServerAppId(context.TODO(), &api.GetServerAppIdReq{
|
||||||
|
ServerType: api.PATHFINDING,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("get pathfinding server appid error: %v", err)
|
||||||
|
}
|
||||||
|
session.pathfindingServerAppId = pathfindingServerAppId.AppId
|
||||||
|
logger.Debug("session gs appid: %v", session.gsServerAppId)
|
||||||
|
logger.Debug("session fight appid: %v", session.fightServerAppId)
|
||||||
|
logger.Debug("session pathfinding appid: %v", session.pathfindingServerAppId)
|
||||||
// 返回响应
|
// 返回响应
|
||||||
rsp = new(proto.GetPlayerTokenRsp)
|
rsp = new(proto.GetPlayerTokenRsp)
|
||||||
rsp.Uid = tokenVerifyRsp.PlayerID
|
rsp.Uid = tokenVerifyRsp.PlayerID
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package net
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"context"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"strconv"
|
"strconv"
|
||||||
"sync"
|
"sync"
|
||||||
@@ -10,9 +11,9 @@ import (
|
|||||||
"hk4e/common/config"
|
"hk4e/common/config"
|
||||||
"hk4e/common/mq"
|
"hk4e/common/mq"
|
||||||
"hk4e/common/region"
|
"hk4e/common/region"
|
||||||
"hk4e/dispatch/controller"
|
"hk4e/common/rpc"
|
||||||
"hk4e/gate/kcp"
|
"hk4e/gate/kcp"
|
||||||
"hk4e/pkg/httpclient"
|
"hk4e/node/api"
|
||||||
"hk4e/pkg/logger"
|
"hk4e/pkg/logger"
|
||||||
"hk4e/pkg/random"
|
"hk4e/pkg/random"
|
||||||
"hk4e/protocol/cmd"
|
"hk4e/protocol/cmd"
|
||||||
@@ -21,6 +22,7 @@ import (
|
|||||||
const PacketFreqLimit = 1000
|
const PacketFreqLimit = 1000
|
||||||
|
|
||||||
type KcpConnectManager struct {
|
type KcpConnectManager struct {
|
||||||
|
discovery *rpc.DiscoveryClient
|
||||||
openState bool
|
openState bool
|
||||||
sessionConvIdMap map[uint64]*Session
|
sessionConvIdMap map[uint64]*Session
|
||||||
sessionUserIdMap map[uint32]*Session
|
sessionUserIdMap map[uint32]*Session
|
||||||
@@ -38,8 +40,9 @@ type KcpConnectManager struct {
|
|||||||
encRsaKeyMap map[string][]byte
|
encRsaKeyMap map[string][]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewKcpConnectManager(messageQueue *mq.MessageQueue) (r *KcpConnectManager) {
|
func NewKcpConnectManager(messageQueue *mq.MessageQueue, discovery *rpc.DiscoveryClient) (r *KcpConnectManager) {
|
||||||
r = new(KcpConnectManager)
|
r = new(KcpConnectManager)
|
||||||
|
r.discovery = discovery
|
||||||
r.openState = true
|
r.openState = true
|
||||||
r.sessionConvIdMap = make(map[uint64]*Session)
|
r.sessionConvIdMap = make(map[uint64]*Session)
|
||||||
r.sessionUserIdMap = make(map[uint32]*Session)
|
r.sessionUserIdMap = make(map[uint32]*Session)
|
||||||
@@ -57,20 +60,19 @@ func (k *KcpConnectManager) Start() {
|
|||||||
// 读取密钥相关文件
|
// 读取密钥相关文件
|
||||||
k.signRsaKey, k.encRsaKeyMap, _ = region.LoadRsaKey()
|
k.signRsaKey, k.encRsaKeyMap, _ = region.LoadRsaKey()
|
||||||
// key
|
// key
|
||||||
dispatchEc2bSeedRsp, err := httpclient.Get[controller.DispatchEc2bSeedRsp]("http://127.0.0.1:8080/dispatch/ec2b/seed", "")
|
rsp, err := k.discovery.GetRegionEc2B(context.TODO(), &api.NullMsg{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error("get dispatch ec2b seed error: %v", err)
|
logger.Error("get region ec2b error: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
dispatchEc2bSeed, err := strconv.ParseUint(dispatchEc2bSeedRsp.Seed, 10, 64)
|
ec2b, err := random.LoadEc2bKey(rsp.Data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error("parse dispatch ec2b seed error: %v", err)
|
logger.Error("parse region ec2b error: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
logger.Debug("get dispatch ec2b seed: %v", dispatchEc2bSeed)
|
regionEc2b := random.NewEc2b()
|
||||||
gateDispatchEc2b := random.NewEc2b()
|
regionEc2b.SetSeed(ec2b.Seed())
|
||||||
gateDispatchEc2b.SetSeed(dispatchEc2bSeed)
|
k.dispatchKey = regionEc2b.XorKey()
|
||||||
k.dispatchKey = gateDispatchEc2b.XorKey()
|
|
||||||
// kcp
|
// kcp
|
||||||
port := strconv.Itoa(int(config.CONF.Hk4e.KcpPort))
|
port := strconv.Itoa(int(config.CONF.Hk4e.KcpPort))
|
||||||
listener, err := kcp.ListenWithOptions(config.CONF.Hk4e.KcpAddr+":"+port, nil, 0, 0)
|
listener, err := kcp.ListenWithOptions(config.CONF.Hk4e.KcpAddr+":"+port, nil, 0, 0)
|
||||||
@@ -201,13 +203,16 @@ func (k *KcpConnectManager) enetHandle(listener *kcp.Listener) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Session struct {
|
type Session struct {
|
||||||
conn *kcp.UDPSession
|
conn *kcp.UDPSession
|
||||||
connState uint8
|
connState uint8
|
||||||
userId uint32
|
userId uint32
|
||||||
kcpRawSendChan chan *ProtoMsg
|
kcpRawSendChan chan *ProtoMsg
|
||||||
seed uint64
|
seed uint64
|
||||||
xorKey []byte
|
xorKey []byte
|
||||||
changeXorKeyFin bool
|
changeXorKeyFin bool
|
||||||
|
gsServerAppId string
|
||||||
|
fightServerAppId string
|
||||||
|
pathfindingServerAppId string
|
||||||
}
|
}
|
||||||
|
|
||||||
// 接收
|
// 接收
|
||||||
@@ -288,6 +293,15 @@ func (k *KcpConnectManager) sendHandle(session *Session) {
|
|||||||
if protoMsg.CmdId == cmd.PlayerLoginRsp {
|
if protoMsg.CmdId == cmd.PlayerLoginRsp {
|
||||||
logger.Debug("session active, convId: %v", convId)
|
logger.Debug("session active, convId: %v", convId)
|
||||||
session.connState = ConnActive
|
session.connState = ConnActive
|
||||||
|
// 通知GS玩家战斗服务器的appid
|
||||||
|
connCtrlMsg := new(mq.ConnCtrlMsg)
|
||||||
|
connCtrlMsg.UserId = session.userId
|
||||||
|
connCtrlMsg.FightServerAppId = session.fightServerAppId
|
||||||
|
k.messageQueue.SendToGs(session.gsServerAppId, &mq.NetMsg{
|
||||||
|
MsgType: mq.MsgTypeConnCtrl,
|
||||||
|
EventId: mq.FightServerSelectNotify,
|
||||||
|
ConnCtrlMsg: connCtrlMsg,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -328,7 +342,7 @@ func (k *KcpConnectManager) closeKcpConn(session *Session, enetType uint32) {
|
|||||||
// 通知GS玩家下线
|
// 通知GS玩家下线
|
||||||
gameMsg := new(mq.GameMsg)
|
gameMsg := new(mq.GameMsg)
|
||||||
gameMsg.UserId = session.userId
|
gameMsg.UserId = session.userId
|
||||||
k.messageQueue.SendToGs("1", &mq.NetMsg{
|
k.messageQueue.SendToGs(session.gsServerAppId, &mq.NetMsg{
|
||||||
MsgType: mq.MsgTypeGame,
|
MsgType: mq.MsgTypeGame,
|
||||||
EventId: mq.UserOfflineNotify,
|
EventId: mq.UserOfflineNotify,
|
||||||
GameMsg: gameMsg,
|
GameMsg: gameMsg,
|
||||||
|
|||||||
@@ -8,11 +8,9 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"hk4e/common/config"
|
"hk4e/common/config"
|
||||||
|
"hk4e/common/rpc"
|
||||||
"hk4e/gm/controller"
|
"hk4e/gm/controller"
|
||||||
"hk4e/gm/rpc_client"
|
|
||||||
"hk4e/pkg/logger"
|
"hk4e/pkg/logger"
|
||||||
|
|
||||||
"github.com/nats-io/nats.go"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func Run(ctx context.Context, configFile string) error {
|
func Run(ctx context.Context, configFile string) error {
|
||||||
@@ -21,18 +19,12 @@ func Run(ctx context.Context, configFile string) error {
|
|||||||
logger.InitLogger("gm")
|
logger.InitLogger("gm")
|
||||||
logger.Warn("gm start")
|
logger.Warn("gm start")
|
||||||
|
|
||||||
conn, err := nats.Connect(config.CONF.MQ.NatsUrl)
|
client, err := rpc.NewClient()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error("connect nats error: %v", err)
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer conn.Close()
|
|
||||||
|
|
||||||
rpc, err := rpc_client.New(conn)
|
_ = controller.NewController(client.GM)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
_ = controller.NewController(rpc)
|
|
||||||
|
|
||||||
c := make(chan os.Signal, 1)
|
c := make(chan os.Signal, 1)
|
||||||
signal.Notify(c, syscall.SIGHUP, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT)
|
signal.Notify(c, syscall.SIGHUP, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT)
|
||||||
|
|||||||
@@ -5,19 +5,19 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"hk4e/common/config"
|
"hk4e/common/config"
|
||||||
"hk4e/gm/rpc_client"
|
"hk4e/common/rpc"
|
||||||
"hk4e/pkg/logger"
|
"hk4e/pkg/logger"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Controller struct {
|
type Controller struct {
|
||||||
rpc *rpc_client.Client
|
gm *rpc.GMClient
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewController(rpc *rpc_client.Client) (r *Controller) {
|
func NewController(gm *rpc.GMClient) (r *Controller) {
|
||||||
r = new(Controller)
|
r = new(Controller)
|
||||||
r.rpc = rpc
|
r.gm = gm
|
||||||
go r.registerRouter()
|
go r.registerRouter()
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ func (c *Controller) gmCmd(context *gin.Context) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
rep, err := c.rpc.Cmd(context.Request.Context(), &api.CmdRequest{
|
rep, err := c.gm.Cmd(context.Request.Context(), &api.CmdRequest{
|
||||||
FuncName: gmCmdReq.FuncName,
|
FuncName: gmCmdReq.FuncName,
|
||||||
Param: gmCmdReq.Param,
|
Param: gmCmdReq.Param,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,29 +0,0 @@
|
|||||||
// Package rpc_client rpc客户端
|
|
||||||
package rpc_client
|
|
||||||
|
|
||||||
import (
|
|
||||||
"hk4e/gs/api"
|
|
||||||
|
|
||||||
"github.com/nats-io/nats.go"
|
|
||||||
"github.com/nats-io/nats.go/encoders/protobuf"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Client rpc客户端
|
|
||||||
type Client struct {
|
|
||||||
api.GMNATSRPCClient
|
|
||||||
}
|
|
||||||
|
|
||||||
// New 构造
|
|
||||||
func New(conn *nats.Conn) (*Client, error) {
|
|
||||||
enc, err := nats.NewEncodedConn(conn, protobuf.PROTOBUF_ENCODER)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
cli, err := api.NewGMNATSRPCClient(enc)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &Client{
|
|
||||||
GMNATSRPCClient: cli,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
11
go.mod
11
go.mod
@@ -1,6 +1,6 @@
|
|||||||
module hk4e
|
module hk4e
|
||||||
|
|
||||||
go 1.19
|
go 1.18
|
||||||
|
|
||||||
// toml
|
// toml
|
||||||
require github.com/BurntSushi/toml v0.3.1
|
require github.com/BurntSushi/toml v0.3.1
|
||||||
@@ -44,10 +44,11 @@ require github.com/jszwec/csvutil v1.7.1
|
|||||||
// hjson
|
// hjson
|
||||||
require github.com/hjson/hjson-go/v4 v4.2.0
|
require github.com/hjson/hjson-go/v4 v4.2.0
|
||||||
|
|
||||||
require (
|
// natsrpc
|
||||||
github.com/byebyebruce/natsrpc v0.5.5-0.20221125150611-56cd29a4e335
|
require github.com/byebyebruce/natsrpc v0.5.5-0.20221125150611-56cd29a4e335
|
||||||
github.com/spf13/cobra v1.6.1
|
|
||||||
)
|
// cobra
|
||||||
|
require github.com/spf13/cobra v1.6.1
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-go v1.26.0
|
// protoc-gen-go v1.26.0
|
||||||
// protoc v3.14.0
|
// protoc v3.7.0
|
||||||
// source: api.proto
|
// source: api.proto
|
||||||
|
|
||||||
package api
|
package api
|
||||||
|
|||||||
@@ -9,57 +9,75 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"hk4e/common/config"
|
"hk4e/common/config"
|
||||||
|
"hk4e/common/constant"
|
||||||
"hk4e/common/mq"
|
"hk4e/common/mq"
|
||||||
|
"hk4e/common/rpc"
|
||||||
"hk4e/gdconf"
|
"hk4e/gdconf"
|
||||||
gdc "hk4e/gs/config"
|
gdc "hk4e/gs/config"
|
||||||
"hk4e/gs/constant"
|
|
||||||
"hk4e/gs/dao"
|
"hk4e/gs/dao"
|
||||||
"hk4e/gs/game"
|
"hk4e/gs/game"
|
||||||
"hk4e/gs/service"
|
"hk4e/gs/service"
|
||||||
|
"hk4e/node/api"
|
||||||
"hk4e/pkg/logger"
|
"hk4e/pkg/logger"
|
||||||
|
|
||||||
"github.com/nats-io/nats.go"
|
"github.com/nats-io/nats.go"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var APPID string
|
||||||
|
|
||||||
func Run(ctx context.Context, configFile string) error {
|
func Run(ctx context.Context, configFile string) error {
|
||||||
config.InitConfig(configFile)
|
config.InitConfig(configFile)
|
||||||
|
|
||||||
logger.InitLogger("gs")
|
// natsrpc client
|
||||||
logger.Warn("gs start")
|
client, err := rpc.NewClient()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 注册到节点服务器
|
||||||
|
rsp, err := client.Discovery.RegisterServer(context.TODO(), &api.RegisterServerReq{
|
||||||
|
ServerType: api.GS,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
APPID = rsp.GetAppId()
|
||||||
|
|
||||||
|
logger.InitLogger("gs_" + APPID)
|
||||||
|
logger.Warn("gs start, appid: %v", APPID)
|
||||||
|
|
||||||
constant.InitConstant()
|
constant.InitConstant()
|
||||||
|
|
||||||
gdc.InitGameDataConfig()
|
gdc.InitGameDataConfig()
|
||||||
gdconf.InitGameDataConfig()
|
gdconf.InitGameDataConfig()
|
||||||
|
|
||||||
conn, err := nats.Connect(config.CONF.MQ.NatsUrl)
|
|
||||||
if err != nil {
|
|
||||||
logger.Error("connect nats error: %v", err)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer conn.Close()
|
|
||||||
|
|
||||||
db, err := dao.NewDao()
|
db, err := dao.NewDao()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
defer db.CloseDao()
|
defer db.CloseDao()
|
||||||
|
|
||||||
messageQueue := mq.NewMessageQueue(mq.GS, "1")
|
messageQueue := mq.NewMessageQueue(api.GS, APPID)
|
||||||
defer messageQueue.Close()
|
defer messageQueue.Close()
|
||||||
|
|
||||||
gameManager := game.NewGameManager(db, messageQueue)
|
gameManager := game.NewGameManager(db, messageQueue)
|
||||||
defer gameManager.Stop()
|
defer gameManager.Stop()
|
||||||
|
|
||||||
c := make(chan os.Signal, 1)
|
// natsrpc server
|
||||||
signal.Notify(c, syscall.SIGHUP, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT)
|
conn, err := nats.Connect(config.CONF.MQ.NatsUrl)
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("connect nats error: %v", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer conn.Close()
|
||||||
s, err := service.NewService(conn)
|
s, err := service.NewService(conn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer s.Close()
|
defer s.Close()
|
||||||
|
|
||||||
|
c := make(chan os.Signal, 1)
|
||||||
|
signal.Notify(c, syscall.SIGHUP, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT)
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
@@ -68,7 +86,7 @@ func Run(ctx context.Context, configFile string) error {
|
|||||||
logger.Warn("get a signal %s", s.String())
|
logger.Warn("get a signal %s", s.String())
|
||||||
switch s {
|
switch s {
|
||||||
case syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT:
|
case syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT:
|
||||||
logger.Warn("gs exit")
|
logger.Warn("gs exit, appid: %v", APPID)
|
||||||
time.Sleep(time.Second)
|
time.Sleep(time.Second)
|
||||||
return nil
|
return nil
|
||||||
case syscall.SIGHUP:
|
case syscall.SIGHUP:
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"hk4e/gs/constant"
|
"hk4e/common/constant"
|
||||||
"hk4e/pkg/logger"
|
"hk4e/pkg/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"hk4e/gs/constant"
|
"hk4e/common/constant"
|
||||||
"hk4e/pkg/endec"
|
"hk4e/pkg/endec"
|
||||||
"hk4e/pkg/logger"
|
"hk4e/pkg/logger"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"hk4e/gs/constant"
|
"hk4e/common/constant"
|
||||||
"hk4e/pkg/logger"
|
"hk4e/pkg/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"hk4e/gs/constant"
|
"hk4e/common/constant"
|
||||||
"hk4e/pkg/logger"
|
"hk4e/pkg/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package game
|
package game
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"hk4e/gs/constant"
|
"hk4e/common/constant"
|
||||||
"hk4e/gs/model"
|
"hk4e/gs/model"
|
||||||
"hk4e/pkg/logger"
|
"hk4e/pkg/logger"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -47,7 +47,8 @@ func NewCommandManager() *CommandManager {
|
|||||||
r := new(CommandManager)
|
r := new(CommandManager)
|
||||||
|
|
||||||
// 创建AI世界
|
// 创建AI世界
|
||||||
GAME_MANAGER.OnRegOk(false, &proto.SetPlayerBornDataReq{AvatarId: 10000007, NickName: "System"}, 1, 0)
|
GAME_MANAGER.OnRegOk(false, &proto.SetPlayerBornDataReq{AvatarId: 10000007, NickName: "System"}, 1, 0, "")
|
||||||
|
GAME_MANAGER.FightServerSelectNotify(1, "")
|
||||||
r.system = USER_MANAGER.GetOnlineUser(1)
|
r.system = USER_MANAGER.GetOnlineUser(1)
|
||||||
r.system.DbState = model.DbNormal
|
r.system.DbState = model.DbNormal
|
||||||
r.system.SceneLoadState = model.SceneEnterDone
|
r.system.SceneLoadState = model.SceneEnterDone
|
||||||
|
|||||||
@@ -134,17 +134,47 @@ func (g *GameManager) Stop() {
|
|||||||
for _, player := range userList {
|
for _, player := range userList {
|
||||||
g.DisconnectPlayer(player.PlayerID, kcp.EnetServerShutdown)
|
g.DisconnectPlayer(player.PlayerID, kcp.EnetServerShutdown)
|
||||||
}
|
}
|
||||||
time.Sleep(time.Second * 5)
|
time.Sleep(time.Second * 3)
|
||||||
// 保存玩家数据
|
// 保存玩家数据
|
||||||
LOCAL_EVENT_MANAGER.localEventChan <- &LocalEvent{
|
LOCAL_EVENT_MANAGER.localEventChan <- &LocalEvent{
|
||||||
EventId: RunUserCopyAndSave,
|
EventId: RunUserCopyAndSave,
|
||||||
}
|
}
|
||||||
time.Sleep(time.Second * 5)
|
time.Sleep(time.Second * 3)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *GameManager) SendMsgEx(cmdId uint16, userId uint32, clientSeq uint32, gateAppId string, payloadMsg pb.Message) {
|
||||||
|
if userId < 100000000 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if payloadMsg == nil {
|
||||||
|
logger.Error("payload msg is nil")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
gameMsg := &mq.GameMsg{
|
||||||
|
UserId: userId,
|
||||||
|
CmdId: cmdId,
|
||||||
|
ClientSeq: clientSeq,
|
||||||
|
PayloadMessage: payloadMsg,
|
||||||
|
}
|
||||||
|
g.messageQueue.SendToGate(gateAppId, &mq.NetMsg{
|
||||||
|
MsgType: mq.MsgTypeGame,
|
||||||
|
EventId: mq.NormalMsg,
|
||||||
|
GameMsg: gameMsg,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// SendMsg 发送消息给客户端
|
// SendMsg 发送消息给客户端
|
||||||
func (g *GameManager) SendMsg(cmdId uint16, userId uint32, clientSeq uint32, payloadMsg pb.Message) {
|
func (g *GameManager) SendMsg(cmdId uint16, userId uint32, clientSeq uint32, payloadMsg pb.Message) {
|
||||||
if userId < 100000000 || payloadMsg == nil {
|
if userId < 100000000 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if payloadMsg == nil {
|
||||||
|
logger.Error("payload msg is nil")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
player := USER_MANAGER.GetOnlineUser(userId)
|
||||||
|
if player == nil {
|
||||||
|
logger.Error("player not exist, uid: %v", userId)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
gameMsg := new(mq.GameMsg)
|
gameMsg := new(mq.GameMsg)
|
||||||
@@ -158,7 +188,7 @@ func (g *GameManager) SendMsg(cmdId uint16, userId uint32, clientSeq uint32, pay
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
gameMsg.PayloadMessageData = payloadMessageData
|
gameMsg.PayloadMessageData = payloadMessageData
|
||||||
g.messageQueue.SendToGate("1", &mq.NetMsg{
|
g.messageQueue.SendToGate(player.GateAppId, &mq.NetMsg{
|
||||||
MsgType: mq.MsgTypeGame,
|
MsgType: mq.MsgTypeGame,
|
||||||
EventId: mq.NormalMsg,
|
EventId: mq.NormalMsg,
|
||||||
GameMsg: gameMsg,
|
GameMsg: gameMsg,
|
||||||
@@ -222,7 +252,11 @@ func (g *GameManager) ReconnectPlayer(userId uint32) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (g *GameManager) DisconnectPlayer(userId uint32, reason uint32) {
|
func (g *GameManager) DisconnectPlayer(userId uint32, reason uint32) {
|
||||||
g.messageQueue.SendToGate("1", &mq.NetMsg{
|
player := USER_MANAGER.GetOnlineUser(userId)
|
||||||
|
if player == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
g.messageQueue.SendToGate(player.GateAppId, &mq.NetMsg{
|
||||||
MsgType: mq.MsgTypeConnCtrl,
|
MsgType: mq.MsgTypeConnCtrl,
|
||||||
EventId: mq.KickPlayerNotify,
|
EventId: mq.KickPlayerNotify,
|
||||||
ConnCtrlMsg: &mq.ConnCtrlMsg{
|
ConnCtrlMsg: &mq.ConnCtrlMsg{
|
||||||
|
|||||||
@@ -38,10 +38,10 @@ func (l *LocalEventManager) LocalEventHandle(localEvent *LocalEvent) {
|
|||||||
if playerLoginInfo.Player != nil {
|
if playerLoginInfo.Player != nil {
|
||||||
USER_MANAGER.playerMap[playerLoginInfo.Player.PlayerID] = playerLoginInfo.Player
|
USER_MANAGER.playerMap[playerLoginInfo.Player.PlayerID] = playerLoginInfo.Player
|
||||||
}
|
}
|
||||||
GAME_MANAGER.OnLoginOk(playerLoginInfo.UserId, playerLoginInfo.Player, playerLoginInfo.ClientSeq)
|
GAME_MANAGER.OnLoginOk(playerLoginInfo.UserId, playerLoginInfo.Player, playerLoginInfo.ClientSeq, playerLoginInfo.GateAppId)
|
||||||
case CheckUserExistOnRegFromDbFinish:
|
case CheckUserExistOnRegFromDbFinish:
|
||||||
playerRegInfo := localEvent.Msg.(*PlayerRegInfo)
|
playerRegInfo := localEvent.Msg.(*PlayerRegInfo)
|
||||||
GAME_MANAGER.OnRegOk(playerRegInfo.Exist, playerRegInfo.Req, playerRegInfo.UserId, playerRegInfo.ClientSeq)
|
GAME_MANAGER.OnRegOk(playerRegInfo.Exist, playerRegInfo.Req, playerRegInfo.UserId, playerRegInfo.ClientSeq, playerRegInfo.GateAppId)
|
||||||
case RunUserCopyAndSave:
|
case RunUserCopyAndSave:
|
||||||
startTime := time.Now().UnixNano()
|
startTime := time.Now().UnixNano()
|
||||||
// 拷贝一份数据避免并发访问
|
// 拷贝一份数据避免并发访问
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"hk4e/common/mq"
|
"hk4e/common/mq"
|
||||||
"hk4e/gate/kcp"
|
"hk4e/gate/kcp"
|
||||||
"hk4e/gs/model"
|
"hk4e/gs/model"
|
||||||
|
"hk4e/node/api"
|
||||||
"hk4e/pkg/logger"
|
"hk4e/pkg/logger"
|
||||||
"hk4e/protocol/cmd"
|
"hk4e/protocol/cmd"
|
||||||
|
|
||||||
@@ -120,15 +121,18 @@ func (r *RouteManager) InitRoute() {
|
|||||||
func (r *RouteManager) RouteHandle(netMsg *mq.NetMsg) {
|
func (r *RouteManager) RouteHandle(netMsg *mq.NetMsg) {
|
||||||
switch netMsg.MsgType {
|
switch netMsg.MsgType {
|
||||||
case mq.MsgTypeGame:
|
case mq.MsgTypeGame:
|
||||||
|
if netMsg.OriginServerType != api.GATE {
|
||||||
|
return
|
||||||
|
}
|
||||||
gameMsg := netMsg.GameMsg
|
gameMsg := netMsg.GameMsg
|
||||||
switch netMsg.EventId {
|
switch netMsg.EventId {
|
||||||
case mq.NormalMsg:
|
case mq.NormalMsg:
|
||||||
if gameMsg.CmdId == cmd.PlayerLoginReq {
|
if gameMsg.CmdId == cmd.PlayerLoginReq {
|
||||||
GAME_MANAGER.PlayerLoginReq(gameMsg.UserId, gameMsg.ClientSeq, gameMsg.PayloadMessage)
|
GAME_MANAGER.PlayerLoginReq(gameMsg.UserId, gameMsg.ClientSeq, netMsg.OriginServerAppId, gameMsg.PayloadMessage)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if gameMsg.CmdId == cmd.SetPlayerBornDataReq {
|
if gameMsg.CmdId == cmd.SetPlayerBornDataReq {
|
||||||
GAME_MANAGER.SetPlayerBornDataReq(gameMsg.UserId, gameMsg.ClientSeq, gameMsg.PayloadMessage)
|
GAME_MANAGER.SetPlayerBornDataReq(gameMsg.UserId, gameMsg.ClientSeq, netMsg.OriginServerAppId, gameMsg.PayloadMessage)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
r.doRoute(gameMsg.CmdId, gameMsg.UserId, gameMsg.ClientSeq, gameMsg.PayloadMessage)
|
r.doRoute(gameMsg.CmdId, gameMsg.UserId, gameMsg.ClientSeq, gameMsg.PayloadMessage)
|
||||||
@@ -136,12 +140,17 @@ func (r *RouteManager) RouteHandle(netMsg *mq.NetMsg) {
|
|||||||
GAME_MANAGER.OnUserOffline(gameMsg.UserId)
|
GAME_MANAGER.OnUserOffline(gameMsg.UserId)
|
||||||
}
|
}
|
||||||
case mq.MsgTypeConnCtrl:
|
case mq.MsgTypeConnCtrl:
|
||||||
|
if netMsg.OriginServerType != api.GATE {
|
||||||
|
return
|
||||||
|
}
|
||||||
connCtrlMsg := netMsg.ConnCtrlMsg
|
connCtrlMsg := netMsg.ConnCtrlMsg
|
||||||
switch netMsg.EventId {
|
switch netMsg.EventId {
|
||||||
case mq.ClientRttNotify:
|
case mq.ClientRttNotify:
|
||||||
GAME_MANAGER.ClientRttNotify(connCtrlMsg.UserId, connCtrlMsg.ClientRtt)
|
GAME_MANAGER.ClientRttNotify(connCtrlMsg.UserId, connCtrlMsg.ClientRtt)
|
||||||
case mq.ClientTimeNotify:
|
case mq.ClientTimeNotify:
|
||||||
GAME_MANAGER.ClientTimeNotify(connCtrlMsg.UserId, connCtrlMsg.ClientTime)
|
GAME_MANAGER.ClientTimeNotify(connCtrlMsg.UserId, connCtrlMsg.ClientTime)
|
||||||
|
case mq.FightServerSelectNotify:
|
||||||
|
GAME_MANAGER.FightServerSelectNotify(connCtrlMsg.UserId, connCtrlMsg.FightServerAppId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package game
|
|||||||
import (
|
import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"hk4e/gs/constant"
|
"hk4e/common/constant"
|
||||||
"hk4e/gs/model"
|
"hk4e/gs/model"
|
||||||
"hk4e/pkg/logger"
|
"hk4e/pkg/logger"
|
||||||
"hk4e/pkg/random"
|
"hk4e/pkg/random"
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
package game
|
package game
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"hk4e/common/constant"
|
||||||
gdc "hk4e/gs/config"
|
gdc "hk4e/gs/config"
|
||||||
"hk4e/gs/constant"
|
|
||||||
"hk4e/gs/model"
|
"hk4e/gs/model"
|
||||||
"hk4e/pkg/logger"
|
"hk4e/pkg/logger"
|
||||||
"hk4e/pkg/object"
|
"hk4e/pkg/object"
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package game
|
|||||||
import (
|
import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"hk4e/common/mq"
|
||||||
"hk4e/gs/model"
|
"hk4e/gs/model"
|
||||||
"hk4e/pkg/logger"
|
"hk4e/pkg/logger"
|
||||||
"hk4e/protocol/cmd"
|
"hk4e/protocol/cmd"
|
||||||
@@ -56,6 +57,16 @@ func (g *GameManager) EntityAiSyncNotify(player *model.Player, payloadMsg pb.Mes
|
|||||||
g.SendMsg(cmd.EntityAiSyncNotify, player.PlayerID, player.ClientSeq, entityAiSyncNotify)
|
g.SendMsg(cmd.EntityAiSyncNotify, player.PlayerID, player.ClientSeq, entityAiSyncNotify)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (g *GameManager) ClientRttNotify(userId uint32, clientRtt uint32) {
|
||||||
|
player := USER_MANAGER.GetOnlineUser(userId)
|
||||||
|
if player == nil {
|
||||||
|
logger.Error("player is nil, uid: %v", userId)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
logger.Debug("client rtt notify, uid: %v, rtt: %v", userId, clientRtt)
|
||||||
|
player.ClientRTT = clientRtt
|
||||||
|
}
|
||||||
|
|
||||||
func (g *GameManager) ClientTimeNotify(userId uint32, clientTime uint32) {
|
func (g *GameManager) ClientTimeNotify(userId uint32, clientTime uint32) {
|
||||||
player := USER_MANAGER.GetOnlineUser(userId)
|
player := USER_MANAGER.GetOnlineUser(userId)
|
||||||
if player == nil {
|
if player == nil {
|
||||||
@@ -66,14 +77,29 @@ func (g *GameManager) ClientTimeNotify(userId uint32, clientTime uint32) {
|
|||||||
player.ClientTime = clientTime
|
player.ClientTime = clientTime
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *GameManager) ClientRttNotify(userId uint32, clientRtt uint32) {
|
func (g *GameManager) FightServerSelectNotify(userId uint32, fightAppId string) {
|
||||||
player := USER_MANAGER.GetOnlineUser(userId)
|
player := USER_MANAGER.GetOnlineUser(userId)
|
||||||
if player == nil {
|
if player == nil {
|
||||||
logger.Error("player is nil, uid: %v", userId)
|
logger.Error("player is nil, uid: %v", userId)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
logger.Debug("client rtt notify, uid: %v, rtt: %v", userId, clientRtt)
|
logger.Debug("fight server select notify, uid: %v, fightAppId: %v", userId, fightAppId)
|
||||||
player.ClientRTT = clientRtt
|
player.FightAppId = fightAppId
|
||||||
|
// 创建世界
|
||||||
|
world := WORLD_MANAGER.CreateWorld(player)
|
||||||
|
GAME_MANAGER.messageQueue.SendToFight(fightAppId, &mq.NetMsg{
|
||||||
|
MsgType: mq.MsgTypeFight,
|
||||||
|
EventId: mq.AddFightRoutine,
|
||||||
|
FightMsg: &mq.FightMsg{
|
||||||
|
FightRoutineId: world.id,
|
||||||
|
GateServerAppId: player.GateAppId,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
world.AddPlayer(player, player.SceneId)
|
||||||
|
player.WorldId = world.id
|
||||||
|
// 进入场景
|
||||||
|
player.SceneLoadState = model.SceneNone
|
||||||
|
g.SendMsg(cmd.PlayerEnterSceneNotify, userId, player.ClientSeq, g.PacketPlayerEnterSceneNotifyLogin(player, proto.EnterType_ENTER_TYPE_SELF))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *GameManager) ServerAnnounceNotify(announceId uint32, announceMsg string) {
|
func (g *GameManager) ServerAnnounceNotify(announceId uint32, announceMsg string) {
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
package game
|
package game
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"hk4e/common/constant"
|
||||||
gdc "hk4e/gs/config"
|
gdc "hk4e/gs/config"
|
||||||
"hk4e/gs/constant"
|
|
||||||
"hk4e/pkg/logger"
|
"hk4e/pkg/logger"
|
||||||
"hk4e/protocol/cmd"
|
"hk4e/protocol/cmd"
|
||||||
"hk4e/protocol/proto"
|
"hk4e/protocol/proto"
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ package game
|
|||||||
import (
|
import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"hk4e/common/constant"
|
||||||
gdc "hk4e/gs/config"
|
gdc "hk4e/gs/config"
|
||||||
"hk4e/gs/constant"
|
|
||||||
"hk4e/gs/model"
|
"hk4e/gs/model"
|
||||||
"hk4e/pkg/logger"
|
"hk4e/pkg/logger"
|
||||||
"hk4e/pkg/reflection"
|
"hk4e/pkg/reflection"
|
||||||
@@ -14,36 +14,38 @@ import (
|
|||||||
pb "google.golang.org/protobuf/proto"
|
pb "google.golang.org/protobuf/proto"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (g *GameManager) PlayerLoginReq(userId uint32, clientSeq uint32, payloadMsg pb.Message) {
|
func (g *GameManager) PlayerLoginReq(userId uint32, clientSeq uint32, gateAppId string, payloadMsg pb.Message) {
|
||||||
logger.Info("user login req, uid: %v", userId)
|
logger.Info("user login req, uid: %v, gateAppId: %v", userId, gateAppId)
|
||||||
req := payloadMsg.(*proto.PlayerLoginReq)
|
req := payloadMsg.(*proto.PlayerLoginReq)
|
||||||
logger.Debug("login data: %v", req)
|
logger.Debug("login data: %v", req)
|
||||||
g.OnLogin(userId, clientSeq)
|
g.OnLogin(userId, clientSeq, gateAppId)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *GameManager) SetPlayerBornDataReq(userId uint32, clientSeq uint32, payloadMsg pb.Message) {
|
func (g *GameManager) SetPlayerBornDataReq(userId uint32, clientSeq uint32, gateAppId string, payloadMsg pb.Message) {
|
||||||
logger.Info("user reg req, uid: %v", userId)
|
logger.Info("user reg req, uid: %v, gateAppId: %v", userId, gateAppId)
|
||||||
req := payloadMsg.(*proto.SetPlayerBornDataReq)
|
req := payloadMsg.(*proto.SetPlayerBornDataReq)
|
||||||
logger.Debug("reg data: %v", req)
|
logger.Debug("reg data: %v", req)
|
||||||
g.OnReg(userId, clientSeq, req)
|
g.OnReg(userId, clientSeq, gateAppId, req)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *GameManager) OnLogin(userId uint32, clientSeq uint32) {
|
func (g *GameManager) OnLogin(userId uint32, clientSeq uint32, gateAppId string) {
|
||||||
logger.Info("user login, uid: %v", userId)
|
logger.Info("user login, uid: %v", userId)
|
||||||
player, asyncWait := USER_MANAGER.OnlineUser(userId, clientSeq)
|
player, asyncWait := USER_MANAGER.OnlineUser(userId, clientSeq, gateAppId)
|
||||||
if !asyncWait {
|
if !asyncWait {
|
||||||
g.OnLoginOk(userId, player, clientSeq)
|
g.OnLoginOk(userId, player, clientSeq, gateAppId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *GameManager) OnLoginOk(userId uint32, player *model.Player, clientSeq uint32) {
|
func (g *GameManager) OnLoginOk(userId uint32, player *model.Player, clientSeq uint32, gateAppId string) {
|
||||||
if player == nil {
|
if player == nil {
|
||||||
g.SendMsg(cmd.DoSetPlayerBornDataNotify, userId, clientSeq, new(proto.DoSetPlayerBornDataNotify))
|
g.SendMsgEx(cmd.DoSetPlayerBornDataNotify, userId, clientSeq, gateAppId, new(proto.DoSetPlayerBornDataNotify))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
player.OnlineTime = uint32(time.Now().UnixMilli())
|
player.OnlineTime = uint32(time.Now().UnixMilli())
|
||||||
player.Online = true
|
player.Online = true
|
||||||
|
|
||||||
|
player.GateAppId = gateAppId
|
||||||
|
|
||||||
// 初始化
|
// 初始化
|
||||||
player.InitAll()
|
player.InitAll()
|
||||||
// player.TeamConfig.UpdateTeam()
|
// player.TeamConfig.UpdateTeam()
|
||||||
@@ -53,32 +55,24 @@ func (g *GameManager) OnLoginOk(userId uint32, player *model.Player, clientSeq u
|
|||||||
player.Pos.Y = player.SafePos.Y
|
player.Pos.Y = player.SafePos.Y
|
||||||
player.Pos.Z = player.SafePos.Z
|
player.Pos.Z = player.SafePos.Z
|
||||||
|
|
||||||
// 创建世界
|
|
||||||
world := WORLD_MANAGER.CreateWorld(player)
|
|
||||||
world.AddPlayer(player, player.SceneId)
|
|
||||||
player.WorldId = world.id
|
|
||||||
|
|
||||||
player.CombatInvokeHandler = model.NewInvokeHandler[proto.CombatInvokeEntry]()
|
player.CombatInvokeHandler = model.NewInvokeHandler[proto.CombatInvokeEntry]()
|
||||||
player.AbilityInvokeHandler = model.NewInvokeHandler[proto.AbilityInvokeEntry]()
|
player.AbilityInvokeHandler = model.NewInvokeHandler[proto.AbilityInvokeEntry]()
|
||||||
|
|
||||||
g.LoginNotify(userId, player, clientSeq)
|
g.LoginNotify(userId, player, clientSeq)
|
||||||
|
|
||||||
player.SceneLoadState = model.SceneNone
|
|
||||||
g.SendMsg(cmd.PlayerEnterSceneNotify, userId, clientSeq, g.PacketPlayerEnterSceneNotifyLogin(player, proto.EnterType_ENTER_TYPE_SELF))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *GameManager) OnReg(userId uint32, clientSeq uint32, payloadMsg pb.Message) {
|
func (g *GameManager) OnReg(userId uint32, clientSeq uint32, gateAppId string, payloadMsg pb.Message) {
|
||||||
logger.Debug("user reg, uid: %v", userId)
|
logger.Debug("user reg, uid: %v", userId)
|
||||||
req := payloadMsg.(*proto.SetPlayerBornDataReq)
|
req := payloadMsg.(*proto.SetPlayerBornDataReq)
|
||||||
logger.Debug("avatar id: %v, nickname: %v", req.AvatarId, req.NickName)
|
logger.Debug("avatar id: %v, nickname: %v", req.AvatarId, req.NickName)
|
||||||
|
|
||||||
exist, asyncWait := USER_MANAGER.CheckUserExistOnReg(userId, req, clientSeq)
|
exist, asyncWait := USER_MANAGER.CheckUserExistOnReg(userId, req, clientSeq, gateAppId)
|
||||||
if !asyncWait {
|
if !asyncWait {
|
||||||
g.OnRegOk(exist, req, userId, clientSeq)
|
g.OnRegOk(exist, req, userId, clientSeq, gateAppId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *GameManager) OnRegOk(exist bool, req *proto.SetPlayerBornDataReq, userId uint32, clientSeq uint32) {
|
func (g *GameManager) OnRegOk(exist bool, req *proto.SetPlayerBornDataReq, userId uint32, clientSeq uint32, gateAppId string) {
|
||||||
if exist {
|
if exist {
|
||||||
logger.Error("recv reg req, but user is already exist, userId: %v", userId)
|
logger.Error("recv reg req, but user is already exist, userId: %v", userId)
|
||||||
return
|
return
|
||||||
@@ -98,8 +92,8 @@ func (g *GameManager) OnRegOk(exist bool, req *proto.SetPlayerBornDataReq, userI
|
|||||||
}
|
}
|
||||||
USER_MANAGER.AddUser(player)
|
USER_MANAGER.AddUser(player)
|
||||||
|
|
||||||
g.SendMsg(cmd.SetPlayerBornDataRsp, userId, clientSeq, new(proto.SetPlayerBornDataRsp))
|
g.SendMsgEx(cmd.SetPlayerBornDataRsp, userId, clientSeq, gateAppId, new(proto.SetPlayerBornDataRsp))
|
||||||
g.OnLogin(userId, clientSeq)
|
g.OnLogin(userId, clientSeq, gateAppId)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *GameManager) OnUserOffline(userId uint32) {
|
func (g *GameManager) OnUserOffline(userId uint32) {
|
||||||
|
|||||||
@@ -66,9 +66,10 @@ type PlayerRegInfo struct {
|
|||||||
Req *proto.SetPlayerBornDataReq
|
Req *proto.SetPlayerBornDataReq
|
||||||
UserId uint32
|
UserId uint32
|
||||||
ClientSeq uint32
|
ClientSeq uint32
|
||||||
|
GateAppId string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *UserManager) CheckUserExistOnReg(userId uint32, req *proto.SetPlayerBornDataReq, clientSeq uint32) (exist bool, asyncWait bool) {
|
func (u *UserManager) CheckUserExistOnReg(userId uint32, req *proto.SetPlayerBornDataReq, clientSeq uint32, gateAppId string) (exist bool, asyncWait bool) {
|
||||||
_, exist = u.playerMap[userId]
|
_, exist = u.playerMap[userId]
|
||||||
if exist {
|
if exist {
|
||||||
return true, false
|
return true, false
|
||||||
@@ -86,6 +87,7 @@ func (u *UserManager) CheckUserExistOnReg(userId uint32, req *proto.SetPlayerBor
|
|||||||
Req: req,
|
Req: req,
|
||||||
UserId: userId,
|
UserId: userId,
|
||||||
ClientSeq: clientSeq,
|
ClientSeq: clientSeq,
|
||||||
|
GateAppId: gateAppId,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
@@ -137,9 +139,10 @@ type PlayerLoginInfo struct {
|
|||||||
UserId uint32
|
UserId uint32
|
||||||
Player *model.Player
|
Player *model.Player
|
||||||
ClientSeq uint32
|
ClientSeq uint32
|
||||||
|
GateAppId string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *UserManager) OnlineUser(userId uint32, clientSeq uint32) (*model.Player, bool) {
|
func (u *UserManager) OnlineUser(userId uint32, clientSeq uint32, gateAppId string) (*model.Player, bool) {
|
||||||
player, exist := u.playerMap[userId]
|
player, exist := u.playerMap[userId]
|
||||||
if exist {
|
if exist {
|
||||||
u.ChangeUserDbState(player, model.DbNormal)
|
u.ChangeUserDbState(player, model.DbNormal)
|
||||||
@@ -158,6 +161,7 @@ func (u *UserManager) OnlineUser(userId uint32, clientSeq uint32) (*model.Player
|
|||||||
UserId: userId,
|
UserId: userId,
|
||||||
Player: player,
|
Player: player,
|
||||||
ClientSeq: clientSeq,
|
ClientSeq: clientSeq,
|
||||||
|
GateAppId: gateAppId,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|||||||
@@ -3,8 +3,7 @@ package game
|
|||||||
import (
|
import (
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"hk4e/gs/constant"
|
"hk4e/common/constant"
|
||||||
|
|
||||||
gdc "hk4e/gs/config"
|
gdc "hk4e/gs/config"
|
||||||
"hk4e/gs/model"
|
"hk4e/gs/model"
|
||||||
"hk4e/pkg/logger"
|
"hk4e/pkg/logger"
|
||||||
|
|||||||
@@ -3,7 +3,8 @@ package game
|
|||||||
import (
|
import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"hk4e/gs/constant"
|
"hk4e/common/constant"
|
||||||
|
"hk4e/common/mq"
|
||||||
"hk4e/gs/model"
|
"hk4e/gs/model"
|
||||||
"hk4e/pkg/logger"
|
"hk4e/pkg/logger"
|
||||||
"hk4e/pkg/object"
|
"hk4e/pkg/object"
|
||||||
@@ -320,6 +321,13 @@ func (g *GameManager) UserWorldRemovePlayer(world *World, player *model.Player)
|
|||||||
if world.owner.PlayerID == player.PlayerID {
|
if world.owner.PlayerID == player.PlayerID {
|
||||||
// 房主离开销毁世界
|
// 房主离开销毁世界
|
||||||
WORLD_MANAGER.DestroyWorld(world.id)
|
WORLD_MANAGER.DestroyWorld(world.id)
|
||||||
|
GAME_MANAGER.messageQueue.SendToFight(world.owner.FightAppId, &mq.NetMsg{
|
||||||
|
MsgType: mq.MsgTypeFight,
|
||||||
|
EventId: mq.DelFightRoutine,
|
||||||
|
FightMsg: &mq.FightMsg{
|
||||||
|
FightRoutineId: world.id,
|
||||||
|
},
|
||||||
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if world.multiplayer && world.GetWorldPlayerNum() > 0 {
|
if world.multiplayer && world.GetWorldPlayerNum() > 0 {
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"hk4e/common/constant"
|
||||||
gdc "hk4e/gs/config"
|
gdc "hk4e/gs/config"
|
||||||
"hk4e/gs/constant"
|
|
||||||
"hk4e/gs/model"
|
"hk4e/gs/model"
|
||||||
"hk4e/pkg/logger"
|
"hk4e/pkg/logger"
|
||||||
"hk4e/pkg/object"
|
"hk4e/pkg/object"
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package game
|
|||||||
import (
|
import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"hk4e/gs/constant"
|
"hk4e/common/constant"
|
||||||
"hk4e/gs/model"
|
"hk4e/gs/model"
|
||||||
"hk4e/pkg/logger"
|
"hk4e/pkg/logger"
|
||||||
"hk4e/protocol/cmd"
|
"hk4e/protocol/cmd"
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
|
|
||||||
"hk4e/gs/constant"
|
"hk4e/common/constant"
|
||||||
"hk4e/gs/model"
|
"hk4e/gs/model"
|
||||||
"hk4e/pkg/logger"
|
"hk4e/pkg/logger"
|
||||||
"hk4e/pkg/object"
|
"hk4e/pkg/object"
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"hk4e/common/constant"
|
||||||
"hk4e/gdconf"
|
"hk4e/gdconf"
|
||||||
"hk4e/gs/constant"
|
|
||||||
"hk4e/gs/model"
|
"hk4e/gs/model"
|
||||||
"hk4e/pkg/endec"
|
"hk4e/pkg/endec"
|
||||||
"hk4e/pkg/logger"
|
"hk4e/pkg/logger"
|
||||||
@@ -462,7 +462,7 @@ func (g *GameManager) DrownBackHandler(player *model.Player) {
|
|||||||
}
|
}
|
||||||
// 获取最近角色实体的锚点
|
// 获取最近角色实体的锚点
|
||||||
// TODO 阻塞优化 16ms我感觉有点慢
|
// TODO 阻塞优化 16ms我感觉有点慢
|
||||||
//for _, entry := range gdc.CONF.ScenePointEntries {
|
// for _, entry := range gdc.CONF.ScenePointEntries {
|
||||||
// if entry.PointData == nil || entry.PointData.TranPos == nil {
|
// if entry.PointData == nil || entry.PointData.TranPos == nil {
|
||||||
// continue
|
// continue
|
||||||
// }
|
// }
|
||||||
@@ -475,7 +475,7 @@ func (g *GameManager) DrownBackHandler(player *model.Player) {
|
|||||||
// if player.SafePos.Distance(pointPos) < player.SafePos.Distance(pos) {
|
// if player.SafePos.Distance(pointPos) < player.SafePos.Distance(pos) {
|
||||||
// pos = pointPos
|
// pos = pointPos
|
||||||
// }
|
// }
|
||||||
//}
|
// }
|
||||||
// 传送玩家至安全位置
|
// 传送玩家至安全位置
|
||||||
g.TeleportPlayer(player, uint32(constant.EnterReasonConst.Revival), player.SceneId, pos)
|
g.TeleportPlayer(player, uint32(constant.EnterReasonConst.Revival), player.SceneId, pos)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
package game
|
package game
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"hk4e/common/constant"
|
||||||
gdc "hk4e/gs/config"
|
gdc "hk4e/gs/config"
|
||||||
"hk4e/gs/constant"
|
|
||||||
"hk4e/gs/model"
|
"hk4e/gs/model"
|
||||||
"hk4e/pkg/endec"
|
"hk4e/pkg/endec"
|
||||||
"hk4e/pkg/logger"
|
"hk4e/pkg/logger"
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
package game
|
package game
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"hk4e/common/constant"
|
||||||
gdc "hk4e/gs/config"
|
gdc "hk4e/gs/config"
|
||||||
"hk4e/gs/constant"
|
|
||||||
"hk4e/pkg/logger"
|
"hk4e/pkg/logger"
|
||||||
"hk4e/protocol/cmd"
|
"hk4e/protocol/cmd"
|
||||||
"hk4e/protocol/proto"
|
"hk4e/protocol/proto"
|
||||||
|
|||||||
@@ -4,10 +4,10 @@ import (
|
|||||||
"math"
|
"math"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"hk4e/common/constant"
|
||||||
"hk4e/protocol/cmd"
|
"hk4e/protocol/cmd"
|
||||||
|
|
||||||
"hk4e/common/mq"
|
"hk4e/common/mq"
|
||||||
"hk4e/gs/constant"
|
|
||||||
"hk4e/gs/game/aoi"
|
"hk4e/gs/game/aoi"
|
||||||
"hk4e/gs/model"
|
"hk4e/gs/model"
|
||||||
"hk4e/pkg/alg"
|
"hk4e/pkg/alg"
|
||||||
@@ -71,13 +71,6 @@ func (w *WorldManager) CreateWorld(owner *model.Player) *World {
|
|||||||
}
|
}
|
||||||
world.mpLevelEntityId = world.GetNextWorldEntityId(constant.EntityIdTypeConst.MPLEVEL)
|
world.mpLevelEntityId = world.GetNextWorldEntityId(constant.EntityIdTypeConst.MPLEVEL)
|
||||||
w.worldMap[worldId] = world
|
w.worldMap[worldId] = world
|
||||||
GAME_MANAGER.messageQueue.SendToFight("1", &mq.NetMsg{
|
|
||||||
MsgType: mq.MsgTypeFight,
|
|
||||||
EventId: mq.AddFightRoutine,
|
|
||||||
FightMsg: &mq.FightMsg{
|
|
||||||
FightRoutineId: world.id,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
return world
|
return world
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,13 +81,6 @@ func (w *WorldManager) DestroyWorld(worldId uint32) {
|
|||||||
player.WorldId = 0
|
player.WorldId = 0
|
||||||
}
|
}
|
||||||
delete(w.worldMap, worldId)
|
delete(w.worldMap, worldId)
|
||||||
GAME_MANAGER.messageQueue.SendToFight("1", &mq.NetMsg{
|
|
||||||
MsgType: mq.MsgTypeFight,
|
|
||||||
EventId: mq.DelFightRoutine,
|
|
||||||
FightMsg: &mq.FightMsg{
|
|
||||||
FightRoutineId: world.id,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetBigWorld 获取本服务器的AI世界
|
// GetBigWorld 获取本服务器的AI世界
|
||||||
@@ -715,7 +701,7 @@ func (s *Scene) CreateEntityAvatar(player *model.Player, avatarId uint32) uint32
|
|||||||
if avatarId == s.world.GetPlayerActiveAvatarId(player) {
|
if avatarId == s.world.GetPlayerActiveAvatarId(player) {
|
||||||
s.world.aoiManager.AddEntityIdToGridByPos(entity.id, float32(entity.pos.X), float32(entity.pos.Y), float32(entity.pos.Z))
|
s.world.aoiManager.AddEntityIdToGridByPos(entity.id, float32(entity.pos.X), float32(entity.pos.Y), float32(entity.pos.Z))
|
||||||
}
|
}
|
||||||
GAME_MANAGER.messageQueue.SendToFight("1", &mq.NetMsg{
|
GAME_MANAGER.messageQueue.SendToFight(s.world.owner.FightAppId, &mq.NetMsg{
|
||||||
MsgType: mq.MsgTypeFight,
|
MsgType: mq.MsgTypeFight,
|
||||||
EventId: mq.FightRoutineAddEntity,
|
EventId: mq.FightRoutineAddEntity,
|
||||||
FightMsg: &mq.FightMsg{
|
FightMsg: &mq.FightMsg{
|
||||||
@@ -765,7 +751,7 @@ func (s *Scene) CreateEntityMonster(pos *model.Vector, level uint8, fightProp ma
|
|||||||
}
|
}
|
||||||
s.entityMap[entity.id] = entity
|
s.entityMap[entity.id] = entity
|
||||||
s.world.aoiManager.AddEntityIdToGridByPos(entity.id, float32(entity.pos.X), float32(entity.pos.Y), float32(entity.pos.Z))
|
s.world.aoiManager.AddEntityIdToGridByPos(entity.id, float32(entity.pos.X), float32(entity.pos.Y), float32(entity.pos.Z))
|
||||||
GAME_MANAGER.messageQueue.SendToFight("1", &mq.NetMsg{
|
GAME_MANAGER.messageQueue.SendToFight(s.world.owner.FightAppId, &mq.NetMsg{
|
||||||
MsgType: mq.MsgTypeFight,
|
MsgType: mq.MsgTypeFight,
|
||||||
EventId: mq.FightRoutineAddEntity,
|
EventId: mq.FightRoutineAddEntity,
|
||||||
FightMsg: &mq.FightMsg{
|
FightMsg: &mq.FightMsg{
|
||||||
@@ -915,7 +901,7 @@ func (s *Scene) DestroyEntity(entityId uint32) {
|
|||||||
}
|
}
|
||||||
s.world.aoiManager.RemoveEntityIdFromGridByPos(entity.id, float32(entity.pos.X), float32(entity.pos.Y), float32(entity.pos.Z))
|
s.world.aoiManager.RemoveEntityIdFromGridByPos(entity.id, float32(entity.pos.X), float32(entity.pos.Y), float32(entity.pos.Z))
|
||||||
delete(s.entityMap, entityId)
|
delete(s.entityMap, entityId)
|
||||||
GAME_MANAGER.messageQueue.SendToFight("1", &mq.NetMsg{
|
GAME_MANAGER.messageQueue.SendToFight(s.world.owner.FightAppId, &mq.NetMsg{
|
||||||
MsgType: mq.MsgTypeFight,
|
MsgType: mq.MsgTypeFight,
|
||||||
EventId: mq.FightRoutineDelEntity,
|
EventId: mq.FightRoutineDelEntity,
|
||||||
FightMsg: &mq.FightMsg{
|
FightMsg: &mq.FightMsg{
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package model
|
package model
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"hk4e/gs/constant"
|
"hk4e/common/constant"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Item struct {
|
type Item struct {
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ package model
|
|||||||
import (
|
import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"hk4e/common/constant"
|
||||||
gdc "hk4e/gs/config"
|
gdc "hk4e/gs/config"
|
||||||
"hk4e/gs/constant"
|
|
||||||
"hk4e/pkg/logger"
|
"hk4e/pkg/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -71,6 +71,8 @@ type Player struct {
|
|||||||
ClientSeq uint32 `bson:"-" msgpack:"-"` // 客户端发包请求的序号
|
ClientSeq uint32 `bson:"-" msgpack:"-"` // 客户端发包请求的序号
|
||||||
CombatInvokeHandler *InvokeHandler[proto.CombatInvokeEntry] `bson:"-" msgpack:"-"` // combat转发器
|
CombatInvokeHandler *InvokeHandler[proto.CombatInvokeEntry] `bson:"-" msgpack:"-"` // combat转发器
|
||||||
AbilityInvokeHandler *InvokeHandler[proto.AbilityInvokeEntry] `bson:"-" msgpack:"-"` // ability转发器
|
AbilityInvokeHandler *InvokeHandler[proto.AbilityInvokeEntry] `bson:"-" msgpack:"-"` // ability转发器
|
||||||
|
GateAppId string `bson:"-" msgpack:"-"` // 网关服务器的appid
|
||||||
|
FightAppId string `bson:"-" msgpack:"-"` // 战斗服务器的appid
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Player) GetNextGameObjectGuid() uint64 {
|
func (p *Player) GetNextGameObjectGuid() uint64 {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package model
|
package model
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"hk4e/gs/constant"
|
"hk4e/common/constant"
|
||||||
"hk4e/protocol/proto"
|
"hk4e/protocol/proto"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
package model
|
package model
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"hk4e/common/constant"
|
||||||
gdc "hk4e/gs/config"
|
gdc "hk4e/gs/config"
|
||||||
"hk4e/gs/constant"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Team struct {
|
type Team struct {
|
||||||
|
|||||||
@@ -30,5 +30,4 @@ func NewService(conn *nats.Conn) (*Service, error) {
|
|||||||
// Close 关闭
|
// Close 关闭
|
||||||
func (s *Service) Close() {
|
func (s *Service) Close() {
|
||||||
// TODO
|
// TODO
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
70
node/api/api.natsrpc.pb.go
Normal file
70
node/api/api.natsrpc.pb.go
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
// Code generated by protoc-gen-natsrpc. DO NOT EDIT.
|
||||||
|
// versions:
|
||||||
|
// - protoc-gen-natsrpc v0.5.0
|
||||||
|
// source: api.proto
|
||||||
|
|
||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
context "context"
|
||||||
|
fmt "fmt"
|
||||||
|
natsrpc "github.com/byebyebruce/natsrpc"
|
||||||
|
nats_go "github.com/nats-io/nats.go"
|
||||||
|
proto "google.golang.org/protobuf/proto"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ = new(context.Context)
|
||||||
|
var _ = proto.Marshal
|
||||||
|
var _ = fmt.Errorf
|
||||||
|
var _ = natsrpc.Version
|
||||||
|
var _ = nats_go.Version
|
||||||
|
|
||||||
|
// 节点服务器注册发现服务
|
||||||
|
type DiscoveryNATSRPCServer interface {
|
||||||
|
RegisterServer(ctx context.Context, req *RegisterServerReq) (*RegisterServerRsp, error)
|
||||||
|
GetServerAppId(ctx context.Context, req *GetServerAppIdReq) (*GetServerAppIdRsp, error)
|
||||||
|
GetRegionEc2B(ctx context.Context, req *NullMsg) (*RegionEc2B, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RegisterDiscoveryNATSRPCServer register Discovery service
|
||||||
|
func RegisterDiscoveryNATSRPCServer(server *natsrpc.Server, s DiscoveryNATSRPCServer, opts ...natsrpc.ServiceOption) (natsrpc.IService, error) {
|
||||||
|
return server.Register("hk4e.node.api.Discovery", s, opts...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 节点服务器注册发现服务
|
||||||
|
type DiscoveryNATSRPCClient interface {
|
||||||
|
RegisterServer(ctx context.Context, req *RegisterServerReq, opt ...natsrpc.CallOption) (*RegisterServerRsp, error)
|
||||||
|
GetServerAppId(ctx context.Context, req *GetServerAppIdReq, opt ...natsrpc.CallOption) (*GetServerAppIdRsp, error)
|
||||||
|
GetRegionEc2B(ctx context.Context, req *NullMsg, opt ...natsrpc.CallOption) (*RegionEc2B, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type _DiscoveryNATSRPCClient struct {
|
||||||
|
c *natsrpc.Client
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewDiscoveryNATSRPCClient
|
||||||
|
func NewDiscoveryNATSRPCClient(enc *nats_go.EncodedConn, opts ...natsrpc.ClientOption) (DiscoveryNATSRPCClient, error) {
|
||||||
|
c, err := natsrpc.NewClient(enc, "hk4e.node.api.Discovery", opts...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
ret := &_DiscoveryNATSRPCClient{
|
||||||
|
c: c,
|
||||||
|
}
|
||||||
|
return ret, nil
|
||||||
|
}
|
||||||
|
func (c *_DiscoveryNATSRPCClient) RegisterServer(ctx context.Context, req *RegisterServerReq, opt ...natsrpc.CallOption) (*RegisterServerRsp, error) {
|
||||||
|
rep := &RegisterServerRsp{}
|
||||||
|
err := c.c.Request(ctx, "RegisterServer", req, rep, opt...)
|
||||||
|
return rep, err
|
||||||
|
}
|
||||||
|
func (c *_DiscoveryNATSRPCClient) GetServerAppId(ctx context.Context, req *GetServerAppIdReq, opt ...natsrpc.CallOption) (*GetServerAppIdRsp, error) {
|
||||||
|
rep := &GetServerAppIdRsp{}
|
||||||
|
err := c.c.Request(ctx, "GetServerAppId", req, rep, opt...)
|
||||||
|
return rep, err
|
||||||
|
}
|
||||||
|
func (c *_DiscoveryNATSRPCClient) GetRegionEc2B(ctx context.Context, req *NullMsg, opt ...natsrpc.CallOption) (*RegionEc2B, error) {
|
||||||
|
rep := &RegionEc2B{}
|
||||||
|
err := c.c.Request(ctx, "GetRegionEc2B", req, rep, opt...)
|
||||||
|
return rep, err
|
||||||
|
}
|
||||||
466
node/api/api.pb.go
Normal file
466
node/api/api.pb.go
Normal file
@@ -0,0 +1,466 @@
|
|||||||
|
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||||
|
// versions:
|
||||||
|
// protoc-gen-go v1.26.0
|
||||||
|
// protoc v3.7.0
|
||||||
|
// source: api.proto
|
||||||
|
|
||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||||
|
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||||
|
reflect "reflect"
|
||||||
|
sync "sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// Verify that this generated code is sufficiently up-to-date.
|
||||||
|
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||||
|
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||||
|
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||||
|
)
|
||||||
|
|
||||||
|
type NullMsg struct {
|
||||||
|
state protoimpl.MessageState
|
||||||
|
sizeCache protoimpl.SizeCache
|
||||||
|
unknownFields protoimpl.UnknownFields
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *NullMsg) Reset() {
|
||||||
|
*x = NullMsg{}
|
||||||
|
if protoimpl.UnsafeEnabled {
|
||||||
|
mi := &file_api_proto_msgTypes[0]
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *NullMsg) String() string {
|
||||||
|
return protoimpl.X.MessageStringOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*NullMsg) ProtoMessage() {}
|
||||||
|
|
||||||
|
func (x *NullMsg) ProtoReflect() protoreflect.Message {
|
||||||
|
mi := &file_api_proto_msgTypes[0]
|
||||||
|
if protoimpl.UnsafeEnabled && x != nil {
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
if ms.LoadMessageInfo() == nil {
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
return ms
|
||||||
|
}
|
||||||
|
return mi.MessageOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated: Use NullMsg.ProtoReflect.Descriptor instead.
|
||||||
|
func (*NullMsg) Descriptor() ([]byte, []int) {
|
||||||
|
return file_api_proto_rawDescGZIP(), []int{0}
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetServerAppIdReq struct {
|
||||||
|
state protoimpl.MessageState
|
||||||
|
sizeCache protoimpl.SizeCache
|
||||||
|
unknownFields protoimpl.UnknownFields
|
||||||
|
|
||||||
|
ServerType string `protobuf:"bytes,1,opt,name=server_type,json=serverType,proto3" json:"server_type,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *GetServerAppIdReq) Reset() {
|
||||||
|
*x = GetServerAppIdReq{}
|
||||||
|
if protoimpl.UnsafeEnabled {
|
||||||
|
mi := &file_api_proto_msgTypes[1]
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *GetServerAppIdReq) String() string {
|
||||||
|
return protoimpl.X.MessageStringOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*GetServerAppIdReq) ProtoMessage() {}
|
||||||
|
|
||||||
|
func (x *GetServerAppIdReq) ProtoReflect() protoreflect.Message {
|
||||||
|
mi := &file_api_proto_msgTypes[1]
|
||||||
|
if protoimpl.UnsafeEnabled && x != nil {
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
if ms.LoadMessageInfo() == nil {
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
return ms
|
||||||
|
}
|
||||||
|
return mi.MessageOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated: Use GetServerAppIdReq.ProtoReflect.Descriptor instead.
|
||||||
|
func (*GetServerAppIdReq) Descriptor() ([]byte, []int) {
|
||||||
|
return file_api_proto_rawDescGZIP(), []int{1}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *GetServerAppIdReq) GetServerType() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.ServerType
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetServerAppIdRsp struct {
|
||||||
|
state protoimpl.MessageState
|
||||||
|
sizeCache protoimpl.SizeCache
|
||||||
|
unknownFields protoimpl.UnknownFields
|
||||||
|
|
||||||
|
AppId string `protobuf:"bytes,1,opt,name=app_id,json=appId,proto3" json:"app_id,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *GetServerAppIdRsp) Reset() {
|
||||||
|
*x = GetServerAppIdRsp{}
|
||||||
|
if protoimpl.UnsafeEnabled {
|
||||||
|
mi := &file_api_proto_msgTypes[2]
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *GetServerAppIdRsp) String() string {
|
||||||
|
return protoimpl.X.MessageStringOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*GetServerAppIdRsp) ProtoMessage() {}
|
||||||
|
|
||||||
|
func (x *GetServerAppIdRsp) ProtoReflect() protoreflect.Message {
|
||||||
|
mi := &file_api_proto_msgTypes[2]
|
||||||
|
if protoimpl.UnsafeEnabled && x != nil {
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
if ms.LoadMessageInfo() == nil {
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
return ms
|
||||||
|
}
|
||||||
|
return mi.MessageOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated: Use GetServerAppIdRsp.ProtoReflect.Descriptor instead.
|
||||||
|
func (*GetServerAppIdRsp) Descriptor() ([]byte, []int) {
|
||||||
|
return file_api_proto_rawDescGZIP(), []int{2}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *GetServerAppIdRsp) GetAppId() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.AppId
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
type RegisterServerReq struct {
|
||||||
|
state protoimpl.MessageState
|
||||||
|
sizeCache protoimpl.SizeCache
|
||||||
|
unknownFields protoimpl.UnknownFields
|
||||||
|
|
||||||
|
ServerType string `protobuf:"bytes,1,opt,name=server_type,json=serverType,proto3" json:"server_type,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *RegisterServerReq) Reset() {
|
||||||
|
*x = RegisterServerReq{}
|
||||||
|
if protoimpl.UnsafeEnabled {
|
||||||
|
mi := &file_api_proto_msgTypes[3]
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *RegisterServerReq) String() string {
|
||||||
|
return protoimpl.X.MessageStringOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*RegisterServerReq) ProtoMessage() {}
|
||||||
|
|
||||||
|
func (x *RegisterServerReq) ProtoReflect() protoreflect.Message {
|
||||||
|
mi := &file_api_proto_msgTypes[3]
|
||||||
|
if protoimpl.UnsafeEnabled && x != nil {
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
if ms.LoadMessageInfo() == nil {
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
return ms
|
||||||
|
}
|
||||||
|
return mi.MessageOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated: Use RegisterServerReq.ProtoReflect.Descriptor instead.
|
||||||
|
func (*RegisterServerReq) Descriptor() ([]byte, []int) {
|
||||||
|
return file_api_proto_rawDescGZIP(), []int{3}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *RegisterServerReq) GetServerType() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.ServerType
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
type RegisterServerRsp struct {
|
||||||
|
state protoimpl.MessageState
|
||||||
|
sizeCache protoimpl.SizeCache
|
||||||
|
unknownFields protoimpl.UnknownFields
|
||||||
|
|
||||||
|
AppId string `protobuf:"bytes,1,opt,name=app_id,json=appId,proto3" json:"app_id,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *RegisterServerRsp) Reset() {
|
||||||
|
*x = RegisterServerRsp{}
|
||||||
|
if protoimpl.UnsafeEnabled {
|
||||||
|
mi := &file_api_proto_msgTypes[4]
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *RegisterServerRsp) String() string {
|
||||||
|
return protoimpl.X.MessageStringOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*RegisterServerRsp) ProtoMessage() {}
|
||||||
|
|
||||||
|
func (x *RegisterServerRsp) ProtoReflect() protoreflect.Message {
|
||||||
|
mi := &file_api_proto_msgTypes[4]
|
||||||
|
if protoimpl.UnsafeEnabled && x != nil {
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
if ms.LoadMessageInfo() == nil {
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
return ms
|
||||||
|
}
|
||||||
|
return mi.MessageOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated: Use RegisterServerRsp.ProtoReflect.Descriptor instead.
|
||||||
|
func (*RegisterServerRsp) Descriptor() ([]byte, []int) {
|
||||||
|
return file_api_proto_rawDescGZIP(), []int{4}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *RegisterServerRsp) GetAppId() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.AppId
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
type RegionEc2B struct {
|
||||||
|
state protoimpl.MessageState
|
||||||
|
sizeCache protoimpl.SizeCache
|
||||||
|
unknownFields protoimpl.UnknownFields
|
||||||
|
|
||||||
|
Data []byte `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *RegionEc2B) Reset() {
|
||||||
|
*x = RegionEc2B{}
|
||||||
|
if protoimpl.UnsafeEnabled {
|
||||||
|
mi := &file_api_proto_msgTypes[5]
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *RegionEc2B) String() string {
|
||||||
|
return protoimpl.X.MessageStringOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*RegionEc2B) ProtoMessage() {}
|
||||||
|
|
||||||
|
func (x *RegionEc2B) ProtoReflect() protoreflect.Message {
|
||||||
|
mi := &file_api_proto_msgTypes[5]
|
||||||
|
if protoimpl.UnsafeEnabled && x != nil {
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
if ms.LoadMessageInfo() == nil {
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
return ms
|
||||||
|
}
|
||||||
|
return mi.MessageOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated: Use RegionEc2B.ProtoReflect.Descriptor instead.
|
||||||
|
func (*RegionEc2B) Descriptor() ([]byte, []int) {
|
||||||
|
return file_api_proto_rawDescGZIP(), []int{5}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *RegionEc2B) GetData() []byte {
|
||||||
|
if x != nil {
|
||||||
|
return x.Data
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var File_api_proto protoreflect.FileDescriptor
|
||||||
|
|
||||||
|
var file_api_proto_rawDesc = []byte{
|
||||||
|
0x0a, 0x09, 0x61, 0x70, 0x69, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x08, 0x6e, 0x6f, 0x64,
|
||||||
|
0x65, 0x2e, 0x61, 0x70, 0x69, 0x22, 0x09, 0x0a, 0x07, 0x4e, 0x75, 0x6c, 0x6c, 0x4d, 0x73, 0x67,
|
||||||
|
0x22, 0x34, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x41, 0x70, 0x70,
|
||||||
|
0x49, 0x64, 0x52, 0x65, 0x71, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f,
|
||||||
|
0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x65, 0x72, 0x76,
|
||||||
|
0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x22, 0x2a, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x53, 0x65, 0x72,
|
||||||
|
0x76, 0x65, 0x72, 0x41, 0x70, 0x70, 0x49, 0x64, 0x52, 0x73, 0x70, 0x12, 0x15, 0x0a, 0x06, 0x61,
|
||||||
|
0x70, 0x70, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61, 0x70, 0x70,
|
||||||
|
0x49, 0x64, 0x22, 0x34, 0x0a, 0x11, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x53, 0x65,
|
||||||
|
0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x71, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x65, 0x72, 0x76, 0x65,
|
||||||
|
0x72, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x65,
|
||||||
|
0x72, 0x76, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x22, 0x2a, 0x0a, 0x11, 0x52, 0x65, 0x67, 0x69,
|
||||||
|
0x73, 0x74, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x73, 0x70, 0x12, 0x15, 0x0a,
|
||||||
|
0x06, 0x61, 0x70, 0x70, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x61,
|
||||||
|
0x70, 0x70, 0x49, 0x64, 0x22, 0x20, 0x0a, 0x0a, 0x52, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x45, 0x63,
|
||||||
|
0x32, 0x62, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c,
|
||||||
|
0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x32, 0xe3, 0x01, 0x0a, 0x09, 0x44, 0x69, 0x73, 0x63, 0x6f,
|
||||||
|
0x76, 0x65, 0x72, 0x79, 0x12, 0x4c, 0x0a, 0x0e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72,
|
||||||
|
0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x1b, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x61, 0x70,
|
||||||
|
0x69, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72,
|
||||||
|
0x52, 0x65, 0x71, 0x1a, 0x1b, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x52,
|
||||||
|
0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x73, 0x70,
|
||||||
|
0x22, 0x00, 0x12, 0x4c, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x41,
|
||||||
|
0x70, 0x70, 0x49, 0x64, 0x12, 0x1b, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e,
|
||||||
|
0x47, 0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x41, 0x70, 0x70, 0x49, 0x64, 0x52, 0x65,
|
||||||
|
0x71, 0x1a, 0x1b, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74,
|
||||||
|
0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x41, 0x70, 0x70, 0x49, 0x64, 0x52, 0x73, 0x70, 0x22, 0x00,
|
||||||
|
0x12, 0x3a, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x52, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x45, 0x63, 0x32,
|
||||||
|
0x62, 0x12, 0x11, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4e, 0x75, 0x6c,
|
||||||
|
0x6c, 0x4d, 0x73, 0x67, 0x1a, 0x14, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e,
|
||||||
|
0x52, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x45, 0x63, 0x32, 0x62, 0x22, 0x00, 0x42, 0x13, 0x5a, 0x11,
|
||||||
|
0x68, 0x6b, 0x34, 0x65, 0x2f, 0x6e, 0x6f, 0x64, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x3b, 0x61, 0x70,
|
||||||
|
0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
file_api_proto_rawDescOnce sync.Once
|
||||||
|
file_api_proto_rawDescData = file_api_proto_rawDesc
|
||||||
|
)
|
||||||
|
|
||||||
|
func file_api_proto_rawDescGZIP() []byte {
|
||||||
|
file_api_proto_rawDescOnce.Do(func() {
|
||||||
|
file_api_proto_rawDescData = protoimpl.X.CompressGZIP(file_api_proto_rawDescData)
|
||||||
|
})
|
||||||
|
return file_api_proto_rawDescData
|
||||||
|
}
|
||||||
|
|
||||||
|
var file_api_proto_msgTypes = make([]protoimpl.MessageInfo, 6)
|
||||||
|
var file_api_proto_goTypes = []interface{}{
|
||||||
|
(*NullMsg)(nil), // 0: node.api.NullMsg
|
||||||
|
(*GetServerAppIdReq)(nil), // 1: node.api.GetServerAppIdReq
|
||||||
|
(*GetServerAppIdRsp)(nil), // 2: node.api.GetServerAppIdRsp
|
||||||
|
(*RegisterServerReq)(nil), // 3: node.api.RegisterServerReq
|
||||||
|
(*RegisterServerRsp)(nil), // 4: node.api.RegisterServerRsp
|
||||||
|
(*RegionEc2B)(nil), // 5: node.api.RegionEc2b
|
||||||
|
}
|
||||||
|
var file_api_proto_depIdxs = []int32{
|
||||||
|
3, // 0: node.api.Discovery.RegisterServer:input_type -> node.api.RegisterServerReq
|
||||||
|
1, // 1: node.api.Discovery.GetServerAppId:input_type -> node.api.GetServerAppIdReq
|
||||||
|
0, // 2: node.api.Discovery.GetRegionEc2b:input_type -> node.api.NullMsg
|
||||||
|
4, // 3: node.api.Discovery.RegisterServer:output_type -> node.api.RegisterServerRsp
|
||||||
|
2, // 4: node.api.Discovery.GetServerAppId:output_type -> node.api.GetServerAppIdRsp
|
||||||
|
5, // 5: node.api.Discovery.GetRegionEc2b:output_type -> node.api.RegionEc2b
|
||||||
|
3, // [3:6] is the sub-list for method output_type
|
||||||
|
0, // [0:3] is the sub-list for method input_type
|
||||||
|
0, // [0:0] is the sub-list for extension type_name
|
||||||
|
0, // [0:0] is the sub-list for extension extendee
|
||||||
|
0, // [0:0] is the sub-list for field type_name
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() { file_api_proto_init() }
|
||||||
|
func file_api_proto_init() {
|
||||||
|
if File_api_proto != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !protoimpl.UnsafeEnabled {
|
||||||
|
file_api_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||||
|
switch v := v.(*NullMsg); i {
|
||||||
|
case 0:
|
||||||
|
return &v.state
|
||||||
|
case 1:
|
||||||
|
return &v.sizeCache
|
||||||
|
case 2:
|
||||||
|
return &v.unknownFields
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
file_api_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
|
||||||
|
switch v := v.(*GetServerAppIdReq); i {
|
||||||
|
case 0:
|
||||||
|
return &v.state
|
||||||
|
case 1:
|
||||||
|
return &v.sizeCache
|
||||||
|
case 2:
|
||||||
|
return &v.unknownFields
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
file_api_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
|
||||||
|
switch v := v.(*GetServerAppIdRsp); i {
|
||||||
|
case 0:
|
||||||
|
return &v.state
|
||||||
|
case 1:
|
||||||
|
return &v.sizeCache
|
||||||
|
case 2:
|
||||||
|
return &v.unknownFields
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
file_api_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
|
||||||
|
switch v := v.(*RegisterServerReq); i {
|
||||||
|
case 0:
|
||||||
|
return &v.state
|
||||||
|
case 1:
|
||||||
|
return &v.sizeCache
|
||||||
|
case 2:
|
||||||
|
return &v.unknownFields
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
file_api_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
|
||||||
|
switch v := v.(*RegisterServerRsp); i {
|
||||||
|
case 0:
|
||||||
|
return &v.state
|
||||||
|
case 1:
|
||||||
|
return &v.sizeCache
|
||||||
|
case 2:
|
||||||
|
return &v.unknownFields
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
file_api_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
|
||||||
|
switch v := v.(*RegionEc2B); i {
|
||||||
|
case 0:
|
||||||
|
return &v.state
|
||||||
|
case 1:
|
||||||
|
return &v.sizeCache
|
||||||
|
case 2:
|
||||||
|
return &v.unknownFields
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
type x struct{}
|
||||||
|
out := protoimpl.TypeBuilder{
|
||||||
|
File: protoimpl.DescBuilder{
|
||||||
|
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||||
|
RawDescriptor: file_api_proto_rawDesc,
|
||||||
|
NumEnums: 0,
|
||||||
|
NumMessages: 6,
|
||||||
|
NumExtensions: 0,
|
||||||
|
NumServices: 1,
|
||||||
|
},
|
||||||
|
GoTypes: file_api_proto_goTypes,
|
||||||
|
DependencyIndexes: file_api_proto_depIdxs,
|
||||||
|
MessageInfos: file_api_proto_msgTypes,
|
||||||
|
}.Build()
|
||||||
|
File_api_proto = out.File
|
||||||
|
file_api_proto_rawDesc = nil
|
||||||
|
file_api_proto_goTypes = nil
|
||||||
|
file_api_proto_depIdxs = nil
|
||||||
|
}
|
||||||
34
node/api/api.proto
Normal file
34
node/api/api.proto
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package node.api;
|
||||||
|
option go_package = "hk4e/node/api;api";
|
||||||
|
|
||||||
|
// 节点服务器注册发现服务
|
||||||
|
service Discovery {
|
||||||
|
rpc RegisterServer (RegisterServerReq) returns (RegisterServerRsp) {} // 服务器启动注册获取appid
|
||||||
|
rpc GetServerAppId (GetServerAppIdReq) returns (GetServerAppIdRsp) {} // 随机获取某服务器的appid
|
||||||
|
rpc GetRegionEc2b (NullMsg) returns (RegionEc2b) {} // 获取区服密钥信息
|
||||||
|
}
|
||||||
|
|
||||||
|
message NullMsg {
|
||||||
|
}
|
||||||
|
|
||||||
|
message GetServerAppIdReq {
|
||||||
|
string server_type = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message GetServerAppIdRsp {
|
||||||
|
string app_id = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message RegisterServerReq {
|
||||||
|
string server_type = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message RegisterServerRsp {
|
||||||
|
string app_id = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message RegionEc2b {
|
||||||
|
bytes data = 1;
|
||||||
|
}
|
||||||
8
node/api/server_type.go
Normal file
8
node/api/server_type.go
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
package api
|
||||||
|
|
||||||
|
const (
|
||||||
|
GATE = "GATE"
|
||||||
|
GS = "GS"
|
||||||
|
FIGHT = "FIGHT"
|
||||||
|
PATHFINDING = "PATHFINDING"
|
||||||
|
)
|
||||||
56
node/app/app.go
Normal file
56
node/app/app.go
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
package app
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
_ "net/http/pprof"
|
||||||
|
"os"
|
||||||
|
"os/signal"
|
||||||
|
"syscall"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"hk4e/common/config"
|
||||||
|
"hk4e/node/service"
|
||||||
|
"hk4e/pkg/logger"
|
||||||
|
|
||||||
|
"github.com/nats-io/nats.go"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Run(ctx context.Context, configFile string) error {
|
||||||
|
config.InitConfig(configFile)
|
||||||
|
|
||||||
|
logger.InitLogger("node")
|
||||||
|
logger.Warn("node start")
|
||||||
|
|
||||||
|
// natsrpc server
|
||||||
|
conn, err := nats.Connect(config.CONF.MQ.NatsUrl)
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("connect nats error: %v", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer conn.Close()
|
||||||
|
s, err := service.NewService(conn)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer s.Close()
|
||||||
|
|
||||||
|
c := make(chan os.Signal, 1)
|
||||||
|
signal.Notify(c, syscall.SIGHUP, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT)
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
return nil
|
||||||
|
case s := <-c:
|
||||||
|
logger.Warn("get a signal %s", s.String())
|
||||||
|
switch s {
|
||||||
|
case syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT:
|
||||||
|
logger.Warn("node exit")
|
||||||
|
time.Sleep(time.Second)
|
||||||
|
return nil
|
||||||
|
case syscall.SIGHUP:
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
94
node/service/discovery.go
Normal file
94
node/service/discovery.go
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
package service
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"hk4e/common/config"
|
||||||
|
"hk4e/common/region"
|
||||||
|
"hk4e/node/api"
|
||||||
|
"hk4e/pkg/logger"
|
||||||
|
"hk4e/pkg/random"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ api.DiscoveryNATSRPCServer = (*DiscoveryService)(nil)
|
||||||
|
|
||||||
|
type ServerInstance struct {
|
||||||
|
serverType string
|
||||||
|
appId string
|
||||||
|
}
|
||||||
|
|
||||||
|
type DiscoveryService struct {
|
||||||
|
regionEc2b *random.Ec2b
|
||||||
|
// TODO 加锁
|
||||||
|
serverInstanceMap map[string]map[string]*ServerInstance
|
||||||
|
serverAppIdMap map[string]bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewDiscoveryService() *DiscoveryService {
|
||||||
|
r := new(DiscoveryService)
|
||||||
|
_, _, r.regionEc2b = region.InitRegion(config.CONF.Hk4e.KcpAddr, config.CONF.Hk4e.KcpPort, nil)
|
||||||
|
logger.Info("region ec2b create ok, seed: %v", r.regionEc2b.Seed())
|
||||||
|
r.serverInstanceMap = map[string]map[string]*ServerInstance{
|
||||||
|
api.GATE: make(map[string]*ServerInstance),
|
||||||
|
api.GS: make(map[string]*ServerInstance),
|
||||||
|
api.FIGHT: make(map[string]*ServerInstance),
|
||||||
|
api.PATHFINDING: make(map[string]*ServerInstance),
|
||||||
|
}
|
||||||
|
r.serverAppIdMap = make(map[string]bool)
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *DiscoveryService) RegisterServer(ctx context.Context, req *api.RegisterServerReq) (*api.RegisterServerRsp, error) {
|
||||||
|
logger.Info("register new server, server type: %v", req.ServerType)
|
||||||
|
instMap, exist := s.serverInstanceMap[req.ServerType]
|
||||||
|
if !exist {
|
||||||
|
return nil, errors.New("server type not exist")
|
||||||
|
}
|
||||||
|
var appId string
|
||||||
|
for {
|
||||||
|
appId = strings.ToLower(random.GetRandomStr(8))
|
||||||
|
_, exist := s.serverAppIdMap[appId]
|
||||||
|
if !exist {
|
||||||
|
s.serverAppIdMap[appId] = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
instMap[appId] = &ServerInstance{
|
||||||
|
serverType: req.ServerType,
|
||||||
|
appId: appId,
|
||||||
|
}
|
||||||
|
logger.Info("new server appid is: %v", appId)
|
||||||
|
return &api.RegisterServerRsp{
|
||||||
|
AppId: appId,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *DiscoveryService) GetServerAppId(ctx context.Context, req *api.GetServerAppIdReq) (*api.GetServerAppIdRsp, error) {
|
||||||
|
logger.Info("get server instance, server type: %v", req.ServerType)
|
||||||
|
instMap, exist := s.serverInstanceMap[req.ServerType]
|
||||||
|
if !exist {
|
||||||
|
return nil, errors.New("server type not exist")
|
||||||
|
}
|
||||||
|
if len(instMap) == 0 {
|
||||||
|
return nil, errors.New("no server found")
|
||||||
|
}
|
||||||
|
var inst *ServerInstance = nil
|
||||||
|
for _, v := range instMap {
|
||||||
|
inst = v
|
||||||
|
break
|
||||||
|
}
|
||||||
|
logger.Info("get server appid is: %v", inst.appId)
|
||||||
|
return &api.GetServerAppIdRsp{
|
||||||
|
AppId: inst.appId,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *DiscoveryService) GetRegionEc2B(ctx context.Context, req *api.NullMsg) (*api.RegionEc2B, error) {
|
||||||
|
logger.Info("get region ec2b ok")
|
||||||
|
return &api.RegionEc2B{
|
||||||
|
Data: s.regionEc2b.Bytes(),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
32
node/service/service.go
Normal file
32
node/service/service.go
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
package service
|
||||||
|
|
||||||
|
import (
|
||||||
|
"hk4e/node/api"
|
||||||
|
|
||||||
|
"github.com/byebyebruce/natsrpc"
|
||||||
|
"github.com/nats-io/nats.go"
|
||||||
|
"github.com/nats-io/nats.go/encoders/protobuf"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Service struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewService(conn *nats.Conn) (*Service, error) {
|
||||||
|
enc, err := nats.NewEncodedConn(conn, protobuf.PROTOBUF_ENCODER)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
svr, err := natsrpc.NewServer(enc)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
discoveryService := NewDiscoveryService()
|
||||||
|
_, err = api.RegisterDiscoveryNATSRPCServer(svr, discoveryService)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &Service{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) Close() {
|
||||||
|
}
|
||||||
@@ -10,17 +10,36 @@ import (
|
|||||||
|
|
||||||
"hk4e/common/config"
|
"hk4e/common/config"
|
||||||
"hk4e/common/mq"
|
"hk4e/common/mq"
|
||||||
|
"hk4e/common/rpc"
|
||||||
|
"hk4e/node/api"
|
||||||
"hk4e/pathfinding/handle"
|
"hk4e/pathfinding/handle"
|
||||||
"hk4e/pkg/logger"
|
"hk4e/pkg/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var APPID string
|
||||||
|
|
||||||
func Run(ctx context.Context, configFile string) error {
|
func Run(ctx context.Context, configFile string) error {
|
||||||
config.InitConfig(configFile)
|
config.InitConfig(configFile)
|
||||||
|
|
||||||
logger.InitLogger("pathfinding")
|
// natsrpc client
|
||||||
logger.Warn("pathfinding start")
|
client, err := rpc.NewClient()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
messageQueue := mq.NewMessageQueue(mq.PATHFINDING, "1")
|
// 注册到节点服务器
|
||||||
|
rsp, err := client.Discovery.RegisterServer(context.TODO(), &api.RegisterServerReq{
|
||||||
|
ServerType: api.PATHFINDING,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
APPID = rsp.GetAppId()
|
||||||
|
|
||||||
|
logger.InitLogger("pathfinding_" + APPID)
|
||||||
|
logger.Warn("pathfinding start, appid: %v", APPID)
|
||||||
|
|
||||||
|
messageQueue := mq.NewMessageQueue(api.PATHFINDING, APPID)
|
||||||
defer messageQueue.Close()
|
defer messageQueue.Close()
|
||||||
|
|
||||||
_ = handle.NewHandle(messageQueue)
|
_ = handle.NewHandle(messageQueue)
|
||||||
@@ -35,7 +54,7 @@ func Run(ctx context.Context, configFile string) error {
|
|||||||
logger.Warn("get a signal %s", s.String())
|
logger.Warn("get a signal %s", s.String())
|
||||||
switch s {
|
switch s {
|
||||||
case syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT:
|
case syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT:
|
||||||
logger.Warn("pathfinding exit")
|
logger.Warn("pathfinding exit, appid: %v", APPID)
|
||||||
time.Sleep(time.Second)
|
time.Sleep(time.Second)
|
||||||
return nil
|
return nil
|
||||||
case syscall.SIGHUP:
|
case syscall.SIGHUP:
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package handle
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"hk4e/common/mq"
|
"hk4e/common/mq"
|
||||||
|
"hk4e/node/api"
|
||||||
"hk4e/pathfinding/world"
|
"hk4e/pathfinding/world"
|
||||||
"hk4e/pkg/logger"
|
"hk4e/pkg/logger"
|
||||||
"hk4e/protocol/cmd"
|
"hk4e/protocol/cmd"
|
||||||
@@ -34,12 +35,15 @@ func (h *Handle) run() {
|
|||||||
if netMsg.EventId != mq.NormalMsg {
|
if netMsg.EventId != mq.NormalMsg {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
if netMsg.OriginServerType != api.GATE {
|
||||||
|
continue
|
||||||
|
}
|
||||||
gameMsg := netMsg.GameMsg
|
gameMsg := netMsg.GameMsg
|
||||||
switch gameMsg.CmdId {
|
switch gameMsg.CmdId {
|
||||||
case cmd.QueryPathReq:
|
case cmd.QueryPathReq:
|
||||||
h.QueryPath(gameMsg.UserId, gameMsg.PayloadMessage)
|
h.QueryPath(gameMsg.UserId, netMsg.OriginServerAppId, gameMsg.PayloadMessage)
|
||||||
case cmd.ObstacleModifyNotify:
|
case cmd.ObstacleModifyNotify:
|
||||||
h.ObstacleModifyNotify(gameMsg.UserId, gameMsg.PayloadMessage)
|
h.ObstacleModifyNotify(gameMsg.UserId, netMsg.OriginServerAppId, gameMsg.PayloadMessage)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
@@ -47,7 +51,7 @@ func (h *Handle) run() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SendMsg 发送消息给客户端
|
// SendMsg 发送消息给客户端
|
||||||
func (h *Handle) SendMsg(cmdId uint16, userId uint32, payloadMsg pb.Message) {
|
func (h *Handle) SendMsg(cmdId uint16, userId uint32, gateAppId string, payloadMsg pb.Message) {
|
||||||
if userId < 100000000 || payloadMsg == nil {
|
if userId < 100000000 || payloadMsg == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -62,7 +66,7 @@ func (h *Handle) SendMsg(cmdId uint16, userId uint32, payloadMsg pb.Message) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
gameMsg.PayloadMessageData = payloadMessageData
|
gameMsg.PayloadMessageData = payloadMessageData
|
||||||
h.messageQueue.SendToGate("1", &mq.NetMsg{
|
h.messageQueue.SendToGate(gateAppId, &mq.NetMsg{
|
||||||
MsgType: mq.MsgTypeGame,
|
MsgType: mq.MsgTypeGame,
|
||||||
EventId: mq.NormalMsg,
|
EventId: mq.NormalMsg,
|
||||||
GameMsg: gameMsg,
|
GameMsg: gameMsg,
|
||||||
|
|||||||
@@ -41,9 +41,9 @@ func (h *Handle) ConvMeshVecListToPbVecList(meshVecList []pfalg.MeshVector) []*p
|
|||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Handle) QueryPath(userId uint32, payloadMsg pb.Message) {
|
func (h *Handle) QueryPath(userId uint32, gateAppId string, payloadMsg pb.Message) {
|
||||||
req := payloadMsg.(*proto.QueryPathReq)
|
req := payloadMsg.(*proto.QueryPathReq)
|
||||||
logger.Debug("query path req: %v, uid: %v", req, userId)
|
logger.Debug("query path req: %v, uid: %v, gateAppId: %v", req, userId, gateAppId)
|
||||||
var ok = false
|
var ok = false
|
||||||
var path []pfalg.MeshVector = nil
|
var path []pfalg.MeshVector = nil
|
||||||
for _, destinationPos := range req.DestinationPos {
|
for _, destinationPos := range req.DestinationPos {
|
||||||
@@ -57,7 +57,7 @@ func (h *Handle) QueryPath(userId uint32, payloadMsg pb.Message) {
|
|||||||
QueryId: req.QueryId,
|
QueryId: req.QueryId,
|
||||||
QueryStatus: proto.QueryPathRsp_PATH_STATUS_TYPE_FAIL,
|
QueryStatus: proto.QueryPathRsp_PATH_STATUS_TYPE_FAIL,
|
||||||
}
|
}
|
||||||
h.SendMsg(cmd.QueryPathRsp, userId, queryPathRsp)
|
h.SendMsg(cmd.QueryPathRsp, userId, gateAppId, queryPathRsp)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
queryPathRsp := &proto.QueryPathRsp{
|
queryPathRsp := &proto.QueryPathRsp{
|
||||||
@@ -65,10 +65,10 @@ func (h *Handle) QueryPath(userId uint32, payloadMsg pb.Message) {
|
|||||||
QueryStatus: proto.QueryPathRsp_PATH_STATUS_TYPE_SUCC,
|
QueryStatus: proto.QueryPathRsp_PATH_STATUS_TYPE_SUCC,
|
||||||
Corners: h.ConvMeshVecListToPbVecList(path),
|
Corners: h.ConvMeshVecListToPbVecList(path),
|
||||||
}
|
}
|
||||||
h.SendMsg(cmd.QueryPathRsp, userId, queryPathRsp)
|
h.SendMsg(cmd.QueryPathRsp, userId, gateAppId, queryPathRsp)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Handle) ObstacleModifyNotify(userId uint32, payloadMsg pb.Message) {
|
func (h *Handle) ObstacleModifyNotify(userId uint32, gateAppId string, payloadMsg pb.Message) {
|
||||||
req := payloadMsg.(*proto.ObstacleModifyNotify)
|
req := payloadMsg.(*proto.ObstacleModifyNotify)
|
||||||
logger.Debug("obstacle modify req: %v, uid: %v", req, userId)
|
logger.Debug("obstacle modify req: %v, uid: %v, gateAppId: %v", req, userId, gateAppId)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,21 +3,19 @@ package statsviz_serve
|
|||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"hk4e/pkg/logger"
|
|
||||||
|
|
||||||
"github.com/arl/statsviz"
|
"github.com/arl/statsviz"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Serve 性能检测
|
||||||
|
// 原生pprof /debug/pprof
|
||||||
|
// 可视化图表 /debug/statsviz
|
||||||
func Serve(addr string) error {
|
func Serve(addr string) error {
|
||||||
// 性能检测
|
|
||||||
err := statsviz.RegisterDefault()
|
err := statsviz.RegisterDefault()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error("statsviz init error: %v", err)
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err = http.ListenAndServe(addr, nil)
|
err = http.ListenAndServe(addr, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error("perf debug http start error: %v", err)
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
Reference in New Issue
Block a user