mirror of
https://github.com/FlourishingWorld/hk4e.git
synced 2026-02-04 15:32:26 +08:00
添加了节点服务器,各个服务器之间支持多对多
This commit is contained in:
@@ -2,6 +2,7 @@ package net
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
@@ -13,6 +14,7 @@ import (
|
||||
"hk4e/common/mq"
|
||||
"hk4e/dispatch/controller"
|
||||
"hk4e/gate/kcp"
|
||||
"hk4e/node/api"
|
||||
"hk4e/pkg/endec"
|
||||
"hk4e/pkg/httpclient"
|
||||
"hk4e/pkg/logger"
|
||||
@@ -80,25 +82,25 @@ func (k *KcpConnectManager) recvMsgHandle(protoMsg *ProtoMsg, session *Session)
|
||||
if connState != ConnActive {
|
||||
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玩家客户端往返时延
|
||||
rtt := session.conn.GetSRTT()
|
||||
connCtrlMsg = new(mq.ConnCtrlMsg)
|
||||
connCtrlMsg := new(mq.ConnCtrlMsg)
|
||||
connCtrlMsg.UserId = userId
|
||||
connCtrlMsg.ClientRtt = uint32(rtt)
|
||||
k.messageQueue.SendToGs("1", &mq.NetMsg{
|
||||
k.messageQueue.SendToGs(session.gsServerAppId, &mq.NetMsg{
|
||||
MsgType: mq.MsgTypeConnCtrl,
|
||||
EventId: mq.ClientRttNotify,
|
||||
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:
|
||||
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)
|
||||
@@ -106,12 +108,15 @@ func (k *KcpConnectManager) recvMsgHandle(protoMsg *ProtoMsg, session *Session)
|
||||
}
|
||||
// 只转发到寻路服务器
|
||||
if protoMsg.CmdId == cmd.QueryPathReq || protoMsg.CmdId == cmd.ObstacleModifyNotify {
|
||||
if session.pathfindingServerAppId == "" {
|
||||
return
|
||||
}
|
||||
gameMsg := new(mq.GameMsg)
|
||||
gameMsg.UserId = userId
|
||||
gameMsg.CmdId = protoMsg.CmdId
|
||||
gameMsg.ClientSeq = protoMsg.HeadMessage.ClientSequenceId
|
||||
gameMsg.PayloadMessage = protoMsg.PayloadMessage
|
||||
k.messageQueue.SendToPathfinding("1", &mq.NetMsg{
|
||||
k.messageQueue.SendToPathfinding(session.pathfindingServerAppId, &mq.NetMsg{
|
||||
MsgType: mq.MsgTypeGame,
|
||||
EventId: mq.NormalMsg,
|
||||
GameMsg: gameMsg,
|
||||
@@ -119,13 +124,13 @@ func (k *KcpConnectManager) recvMsgHandle(protoMsg *ProtoMsg, session *Session)
|
||||
return
|
||||
}
|
||||
// 同时转发到战斗服务器
|
||||
if protoMsg.CmdId == cmd.CombatInvocationsNotify {
|
||||
if protoMsg.CmdId == cmd.CombatInvocationsNotify && session.fightServerAppId != "" {
|
||||
gameMsg := new(mq.GameMsg)
|
||||
gameMsg.UserId = userId
|
||||
gameMsg.CmdId = protoMsg.CmdId
|
||||
gameMsg.ClientSeq = protoMsg.HeadMessage.ClientSequenceId
|
||||
gameMsg.PayloadMessage = protoMsg.PayloadMessage
|
||||
k.messageQueue.SendToFight("1", &mq.NetMsg{
|
||||
k.messageQueue.SendToFight(session.fightServerAppId, &mq.NetMsg{
|
||||
MsgType: mq.MsgTypeGame,
|
||||
EventId: mq.NormalMsg,
|
||||
GameMsg: gameMsg,
|
||||
@@ -137,7 +142,7 @@ func (k *KcpConnectManager) recvMsgHandle(protoMsg *ProtoMsg, session *Session)
|
||||
gameMsg.CmdId = protoMsg.CmdId
|
||||
gameMsg.ClientSeq = protoMsg.HeadMessage.ClientSequenceId
|
||||
gameMsg.PayloadMessage = protoMsg.PayloadMessage
|
||||
k.messageQueue.SendToGs("1", &mq.NetMsg{
|
||||
k.messageQueue.SendToGs(session.gsServerAppId, &mq.NetMsg{
|
||||
MsgType: mq.MsgTypeGame,
|
||||
EventId: mq.NormalMsg,
|
||||
GameMsg: gameMsg,
|
||||
@@ -269,6 +274,32 @@ func (k *KcpConnectManager) getPlayerToken(req *proto.GetPlayerTokenReq, session
|
||||
session.userId = tokenVerifyRsp.PlayerID
|
||||
k.SetSession(session, session.conn.GetConv(), session.userId)
|
||||
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.Uid = tokenVerifyRsp.PlayerID
|
||||
|
||||
@@ -2,6 +2,7 @@ package net
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/binary"
|
||||
"strconv"
|
||||
"sync"
|
||||
@@ -10,9 +11,9 @@ import (
|
||||
"hk4e/common/config"
|
||||
"hk4e/common/mq"
|
||||
"hk4e/common/region"
|
||||
"hk4e/dispatch/controller"
|
||||
"hk4e/common/rpc"
|
||||
"hk4e/gate/kcp"
|
||||
"hk4e/pkg/httpclient"
|
||||
"hk4e/node/api"
|
||||
"hk4e/pkg/logger"
|
||||
"hk4e/pkg/random"
|
||||
"hk4e/protocol/cmd"
|
||||
@@ -21,6 +22,7 @@ import (
|
||||
const PacketFreqLimit = 1000
|
||||
|
||||
type KcpConnectManager struct {
|
||||
discovery *rpc.DiscoveryClient
|
||||
openState bool
|
||||
sessionConvIdMap map[uint64]*Session
|
||||
sessionUserIdMap map[uint32]*Session
|
||||
@@ -38,8 +40,9 @@ type KcpConnectManager struct {
|
||||
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.discovery = discovery
|
||||
r.openState = true
|
||||
r.sessionConvIdMap = make(map[uint64]*Session)
|
||||
r.sessionUserIdMap = make(map[uint32]*Session)
|
||||
@@ -57,20 +60,19 @@ func (k *KcpConnectManager) Start() {
|
||||
// 读取密钥相关文件
|
||||
k.signRsaKey, k.encRsaKeyMap, _ = region.LoadRsaKey()
|
||||
// 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 {
|
||||
logger.Error("get dispatch ec2b seed error: %v", err)
|
||||
logger.Error("get region ec2b error: %v", err)
|
||||
return
|
||||
}
|
||||
dispatchEc2bSeed, err := strconv.ParseUint(dispatchEc2bSeedRsp.Seed, 10, 64)
|
||||
ec2b, err := random.LoadEc2bKey(rsp.Data)
|
||||
if err != nil {
|
||||
logger.Error("parse dispatch ec2b seed error: %v", err)
|
||||
logger.Error("parse region ec2b error: %v", err)
|
||||
return
|
||||
}
|
||||
logger.Debug("get dispatch ec2b seed: %v", dispatchEc2bSeed)
|
||||
gateDispatchEc2b := random.NewEc2b()
|
||||
gateDispatchEc2b.SetSeed(dispatchEc2bSeed)
|
||||
k.dispatchKey = gateDispatchEc2b.XorKey()
|
||||
regionEc2b := random.NewEc2b()
|
||||
regionEc2b.SetSeed(ec2b.Seed())
|
||||
k.dispatchKey = regionEc2b.XorKey()
|
||||
// kcp
|
||||
port := strconv.Itoa(int(config.CONF.Hk4e.KcpPort))
|
||||
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 {
|
||||
conn *kcp.UDPSession
|
||||
connState uint8
|
||||
userId uint32
|
||||
kcpRawSendChan chan *ProtoMsg
|
||||
seed uint64
|
||||
xorKey []byte
|
||||
changeXorKeyFin bool
|
||||
conn *kcp.UDPSession
|
||||
connState uint8
|
||||
userId uint32
|
||||
kcpRawSendChan chan *ProtoMsg
|
||||
seed uint64
|
||||
xorKey []byte
|
||||
changeXorKeyFin bool
|
||||
gsServerAppId string
|
||||
fightServerAppId string
|
||||
pathfindingServerAppId string
|
||||
}
|
||||
|
||||
// 接收
|
||||
@@ -288,6 +293,15 @@ func (k *KcpConnectManager) sendHandle(session *Session) {
|
||||
if protoMsg.CmdId == cmd.PlayerLoginRsp {
|
||||
logger.Debug("session active, convId: %v", convId)
|
||||
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玩家下线
|
||||
gameMsg := new(mq.GameMsg)
|
||||
gameMsg.UserId = session.userId
|
||||
k.messageQueue.SendToGs("1", &mq.NetMsg{
|
||||
k.messageQueue.SendToGs(session.gsServerAppId, &mq.NetMsg{
|
||||
MsgType: mq.MsgTypeGame,
|
||||
EventId: mq.UserOfflineNotify,
|
||||
GameMsg: gameMsg,
|
||||
|
||||
Reference in New Issue
Block a user