mirror of
https://github.com/FlourishingWorld/hk4e.git
synced 2026-02-04 17:02:26 +08:00
完善重连流程
This commit is contained in:
@@ -5,7 +5,7 @@ client_proto_proxy_enable = false
|
|||||||
version = "300,310,320" # 支持的客户端协议版本号 三位数字 多个以逗号分隔 如300,310,320
|
version = "300,310,320" # 支持的客户端协议版本号 三位数字 多个以逗号分隔 如300,310,320
|
||||||
gate_tcp_mq_addr = "127.0.0.1" # 访问网关tcp直连消息队列的地址 填网关的内网地址
|
gate_tcp_mq_addr = "127.0.0.1" # 访问网关tcp直连消息队列的地址 填网关的内网地址
|
||||||
gate_tcp_mq_port = 33333
|
gate_tcp_mq_port = 33333
|
||||||
login_sdk_url = "http://127.0.0.1:8080/gate/token/verify" # 网关登录验证token的sdk服务器地址 目前填dispatch的内网地址
|
login_sdk_url = "http://127.0.0.1:8080" # 网关登录验证token的sdk服务器地址 目前填dispatch的内网地址
|
||||||
|
|
||||||
[logger]
|
[logger]
|
||||||
level = "DEBUG"
|
level = "DEBUG"
|
||||||
|
|||||||
@@ -139,6 +139,7 @@ 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.POST("/gate/token/reset", c.gateTokenReset)
|
||||||
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)
|
||||||
|
|||||||
@@ -67,3 +67,32 @@ func (c *Controller) gateTokenVerify(context *gin.Context) {
|
|||||||
PlayerID: uint32(account.PlayerID),
|
PlayerID: uint32(account.PlayerID),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type TokenResetReq struct {
|
||||||
|
PlayerId uint32 `json:"playerId"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type TokenResetRsp struct {
|
||||||
|
Result bool `json:"result"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Controller) gateTokenReset(context *gin.Context) {
|
||||||
|
req := new(TokenResetReq)
|
||||||
|
err := context.ShouldBindJSON(req)
|
||||||
|
if err != nil {
|
||||||
|
context.JSON(http.StatusOK, &TokenResetRsp{
|
||||||
|
Result: false,
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_, err = c.dao.UpdateAccountFieldByFieldName("PlayerID", req.PlayerId, "comboTokenUsed", false)
|
||||||
|
if err != nil {
|
||||||
|
context.JSON(http.StatusOK, &TokenResetRsp{
|
||||||
|
Result: false,
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
context.JSON(http.StatusOK, &TokenResetRsp{
|
||||||
|
Result: true,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
@@ -169,7 +169,6 @@ func (k *KcpConnectManager) sendMsgHandle() {
|
|||||||
logger.Error("kcpRawSendChan is full, convId: %v", protoMsg.ConvId)
|
logger.Error("kcpRawSendChan is full, convId: %v", protoMsg.ConvId)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
kcpRawSendChan <- protoMsg
|
|
||||||
if protoMsg.CmdId == cmd.PlayerLoginRsp {
|
if protoMsg.CmdId == cmd.PlayerLoginRsp {
|
||||||
logger.Debug("session active, convId: %v", protoMsg.ConvId)
|
logger.Debug("session active, convId: %v", protoMsg.ConvId)
|
||||||
session.connState = ConnActive
|
session.connState = ConnActive
|
||||||
@@ -188,7 +187,30 @@ func (k *KcpConnectManager) sendMsgHandle() {
|
|||||||
EventId: mq.ServerAppidBindNotify,
|
EventId: mq.ServerAppidBindNotify,
|
||||||
ServerMsg: serverMsg,
|
ServerMsg: serverMsg,
|
||||||
})
|
})
|
||||||
|
} else if protoMsg.CmdId == cmd.ClientReconnectNotify {
|
||||||
|
tokenResetRsp, err := httpclient.Post[controller.TokenResetRsp](config.CONF.Hk4e.LoginSdkUrl+"/gate/token/reset", &controller.TokenResetReq{
|
||||||
|
PlayerId: session.userId,
|
||||||
|
}, "")
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("reset token error: %v", err)
|
||||||
|
k.kcpEventInput <- &KcpEvent{
|
||||||
|
ConvId: protoMsg.ConvId,
|
||||||
|
EventId: KcpConnForceClose,
|
||||||
|
EventMessage: uint32(kcp.EnetServerKick),
|
||||||
}
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !tokenResetRsp.Result {
|
||||||
|
logger.Error("reset token fail")
|
||||||
|
k.kcpEventInput <- &KcpEvent{
|
||||||
|
ConvId: protoMsg.ConvId,
|
||||||
|
EventId: KcpConnForceClose,
|
||||||
|
EventMessage: uint32(kcp.EnetServerKick),
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
kcpRawSendChan <- protoMsg
|
||||||
}
|
}
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
@@ -279,16 +301,25 @@ func (k *KcpConnectManager) getHeadMsg(clientSeq uint32) (headMsg *proto.PacketH
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (k *KcpConnectManager) getPlayerToken(req *proto.GetPlayerTokenReq, session *Session) (rsp *proto.GetPlayerTokenRsp) {
|
func (k *KcpConnectManager) getPlayerToken(req *proto.GetPlayerTokenReq, session *Session) (rsp *proto.GetPlayerTokenRsp) {
|
||||||
tokenVerifyRsp, err := httpclient.Post[controller.TokenVerifyRsp](config.CONF.Hk4e.LoginSdkUrl, &controller.TokenVerifyReq{
|
loginFail := func() {
|
||||||
|
k.kcpEventInput <- &KcpEvent{
|
||||||
|
ConvId: session.conn.GetConv(),
|
||||||
|
EventId: KcpConnForceClose,
|
||||||
|
EventMessage: uint32(kcp.EnetLoginUnfinished),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tokenVerifyRsp, err := httpclient.Post[controller.TokenVerifyRsp](config.CONF.Hk4e.LoginSdkUrl+"/gate/token/verify", &controller.TokenVerifyReq{
|
||||||
AccountId: req.AccountUid,
|
AccountId: req.AccountUid,
|
||||||
AccountToken: req.AccountToken,
|
AccountToken: req.AccountToken,
|
||||||
}, "")
|
}, "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error("verify token error: %v", err)
|
logger.Error("verify token error: %v", err)
|
||||||
|
loginFail()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if !tokenVerifyRsp.Valid {
|
if !tokenVerifyRsp.Valid {
|
||||||
logger.Error("token error")
|
logger.Error("token error")
|
||||||
|
loginFail()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
// comboToken验证成功
|
// comboToken验证成功
|
||||||
@@ -343,6 +374,7 @@ func (k *KcpConnectManager) getPlayerToken(req *proto.GetPlayerTokenReq, session
|
|||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error("get gs server appid error: %v", err)
|
logger.Error("get gs server appid error: %v", err)
|
||||||
|
loginFail()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
session.gsServerAppId = gsServerAppId.AppId
|
session.gsServerAppId = gsServerAppId.AppId
|
||||||
@@ -392,52 +424,61 @@ func (k *KcpConnectManager) getPlayerToken(req *proto.GetPlayerTokenReq, session
|
|||||||
encPubPrivKey, exist := k.encRsaKeyMap[keyId]
|
encPubPrivKey, exist := k.encRsaKeyMap[keyId]
|
||||||
if !exist {
|
if !exist {
|
||||||
logger.Error("can not found key id: %v", keyId)
|
logger.Error("can not found key id: %v", keyId)
|
||||||
return
|
loginFail()
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
pubKey, err := endec.RsaParsePubKeyByPrivKey(encPubPrivKey)
|
pubKey, err := endec.RsaParsePubKeyByPrivKey(encPubPrivKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error("parse rsa pub key error: %v", err)
|
logger.Error("parse rsa pub key error: %v", err)
|
||||||
|
loginFail()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
signPrivkey, err := endec.RsaParsePrivKey(k.signRsaKey)
|
signPrivkey, err := endec.RsaParsePrivKey(k.signRsaKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error("parse rsa priv key error: %v", err)
|
logger.Error("parse rsa priv key error: %v", err)
|
||||||
|
loginFail()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
clientSeedBase64 := req.GetClientRandKey()
|
clientSeedBase64 := req.GetClientRandKey()
|
||||||
clientSeedEnc, err := base64.StdEncoding.DecodeString(clientSeedBase64)
|
clientSeedEnc, err := base64.StdEncoding.DecodeString(clientSeedBase64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error("parse client seed base64 error: %v", err)
|
logger.Error("parse client seed base64 error: %v", err)
|
||||||
|
loginFail()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
clientSeed, err := endec.RsaDecrypt(clientSeedEnc, signPrivkey)
|
clientSeed, err := endec.RsaDecrypt(clientSeedEnc, signPrivkey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error("rsa dec error: %v", err)
|
logger.Error("rsa dec error: %v", err)
|
||||||
return rsp
|
loginFail()
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
clientSeedUint64 := uint64(0)
|
clientSeedUint64 := uint64(0)
|
||||||
err = binary.Read(bytes.NewReader(clientSeed), binary.BigEndian, &clientSeedUint64)
|
err = binary.Read(bytes.NewReader(clientSeed), binary.BigEndian, &clientSeedUint64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error("parse client seed to uint64 error: %v", err)
|
logger.Error("parse client seed to uint64 error: %v", err)
|
||||||
return rsp
|
loginFail()
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
seedUint64 := serverSeedUint64 ^ clientSeedUint64
|
seedUint64 := serverSeedUint64 ^ clientSeedUint64
|
||||||
seedBuf := new(bytes.Buffer)
|
seedBuf := new(bytes.Buffer)
|
||||||
err = binary.Write(seedBuf, binary.BigEndian, seedUint64)
|
err = binary.Write(seedBuf, binary.BigEndian, seedUint64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error("conv seed uint64 to bytes error: %v", err)
|
logger.Error("conv seed uint64 to bytes error: %v", err)
|
||||||
return rsp
|
loginFail()
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
seed := seedBuf.Bytes()
|
seed := seedBuf.Bytes()
|
||||||
seedEnc, err := endec.RsaEncrypt(seed, pubKey)
|
seedEnc, err := endec.RsaEncrypt(seed, pubKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error("rsa enc error: %v", err)
|
logger.Error("rsa enc error: %v", err)
|
||||||
return rsp
|
loginFail()
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
seedSign, err := endec.RsaSign(seed, signPrivkey)
|
seedSign, err := endec.RsaSign(seed, signPrivkey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error("rsa sign error: %v", err)
|
logger.Error("rsa sign error: %v", err)
|
||||||
return rsp
|
loginFail()
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
rsp.KeyId = req.KeyId
|
rsp.KeyId = req.KeyId
|
||||||
rsp.ServerRandKey = base64.StdEncoding.EncodeToString(seedEnc)
|
rsp.ServerRandKey = base64.StdEncoding.EncodeToString(seedEnc)
|
||||||
|
|||||||
Reference in New Issue
Block a user