优化ability转发

This commit is contained in:
huangxiaolei
2022-12-05 00:20:25 +08:00
parent b5b7a2b47a
commit 447aeeb672
15 changed files with 267 additions and 218 deletions

View File

@@ -194,7 +194,8 @@ func (f *ForwardManager) Start() {
go f.recvNetMsgFromGameServer()
// 接收客户端消息
cpuCoreNum := runtime.NumCPU()
for i := 0; i < cpuCoreNum*10; i++ {
_ = cpuCoreNum * 10
for i := 0; i < 1; i++ {
go f.sendNetMsgToGameServer()
}
}

View File

@@ -70,19 +70,19 @@ func (f *ForwardManager) getPlayerToken(convId uint64, req *proto.GetPlayerToken
// 返回响应
rsp = new(proto.GetPlayerTokenRsp)
rsp.Uid = tokenVerifyRsp.PlayerID
// TODO 不同的token
rsp.Token = "xxx"
rsp.AccountUid = req.AccountUid
rsp.Token = req.AccountToken
data := make([]byte, 16+32)
rand.Read(data)
rsp.SecurityCmdBuffer = data[16:]
rsp.ClientVersionRandomKey = fmt.Sprintf("%03x-%012x", data[:3], data[4:16])
// TODO 要确定一下新注册的号这个值该返回什么
rsp.AccountType = 1
rsp.IsProficientPlayer = true
rsp.PlatformType = 3
rsp.ChannelId = 1
rsp.CountryCode = "US"
rsp.RegPlatform = 3
rsp.SubChannelId = 1
rsp.RegPlatform = 2
rsp.Birthday = "2000-01-01"
addr, exist := f.getAddrByConvId(convId)
if !exist {
logger.LOG.Error("can not find addr by convId")
@@ -146,6 +146,7 @@ func (f *ForwardManager) getPlayerToken(convId uint64, req *proto.GetPlayerToken
logger.LOG.Error("rsa sign error: %v", err)
return rsp
}
rsp.KeyId = req.KeyId
rsp.ServerRandKey = base64.StdEncoding.EncodeToString(seedEnc)
rsp.Sign = base64.StdEncoding.EncodeToString(seedSign)
// 开启发包监听
@@ -159,11 +160,7 @@ func (f *ForwardManager) getPlayerToken(convId uint64, req *proto.GetPlayerToken
}
func (f *ForwardManager) playerLogin(convId uint64, req *proto.PlayerLoginReq) (rsp *proto.PlayerLoginRsp) {
tokenValid := false
// TODO 不同的token
if req.Token == "xxx" {
tokenValid = true
}
tokenValid := true
if !tokenValid {
logger.LOG.Error("token error")
return nil
@@ -173,8 +170,13 @@ func (f *ForwardManager) playerLogin(convId uint64, req *proto.PlayerLoginReq) (
// 返回响应
rsp = new(proto.PlayerLoginRsp)
rsp.IsUseAbilityHash = true
rsp.AbilityHashCode = 1844674
rsp.GameBiz = "hk4e_global"
rsp.AbilityHashCode = -228935105
rsp.GameBiz = "hk4e_cn"
rsp.IsScOpen = false
rsp.RegisterCps = "taptap"
rsp.CountryCode = "CN"
rsp.Birthday = "2000-01-01"
rsp.TotalTickTime = 1185941.871788
rsp.ClientDataVersion = f.regionCurr.RegionInfo.ClientDataVersion
rsp.ClientSilenceDataVersion = f.regionCurr.RegionInfo.ClientSilenceDataVersion
@@ -184,8 +186,5 @@ func (f *ForwardManager) playerLogin(convId uint64, req *proto.PlayerLoginReq) (
rsp.ClientVersionSuffix = f.regionCurr.RegionInfo.ClientVersionSuffix
rsp.ClientSilenceVersionSuffix = f.regionCurr.RegionInfo.ClientSilenceVersionSuffix
rsp.IsScOpen = false
rsp.RegisterCps = "mihoyo"
rsp.CountryCode = "US"
return rsp
}

View File

@@ -61,11 +61,6 @@ func (p *ProtoEnDecode) protoDecode(kcpMsg *KcpMsg) (protoMsgList []*ProtoMsg) {
msg.CmdId = protoMessage.cmdId
msg.HeadMessage = protoMsg.HeadMessage
msg.PayloadMessage = protoMessage.message
if protoMessage.cmdId == cmd.UnionCmdNotify {
// 聚合消息自身不再往后发送
logger.LOG.Debug("[recv union], cmdId: %v, convId: %v, headMsg: %v", msg.CmdId, msg.ConvId, msg.HeadMessage)
continue
}
protoMsgList = append(protoMsgList, msg)
}
} else {

View File

@@ -47,6 +47,8 @@ func (r *RouteManager) doRoute(cmdId uint16, userId uint32, clientSeq uint32, pa
}
func (r *RouteManager) InitRoute() {
r.registerRouter(cmd.UnionCmdNotify, r.gameManager.UnionCmdNotify)
r.registerRouter(cmd.MassiveEntityElementOpBatchNotify, r.gameManager.MassiveEntityElementOpBatchNotify)
r.registerRouter(cmd.PlayerSetPauseReq, r.gameManager.PlayerSetPauseReq)
r.registerRouter(cmd.EnterSceneReadyReq, r.gameManager.EnterSceneReadyReq)
r.registerRouter(cmd.PathfindingEnterSceneReq, r.gameManager.PathfindingEnterSceneReq)

View File

@@ -235,12 +235,12 @@ func (t *TickManager) onTick200MilliSecond(now int64) {
}
func (t *TickManager) onTick100MilliSecond(now int64) {
// 伤害处理和转发
for _, world := range t.gameManager.worldManager.worldMap {
for _, scene := range world.sceneMap {
scene.AttackHandler(t.gameManager)
}
}
//// 伤害处理和转发
//for _, world := range t.gameManager.worldManager.worldMap {
// for _, scene := range world.sceneMap {
// scene.AttackHandler(t.gameManager)
// }
//}
// 服务器控制的模拟AI移动

View File

@@ -2,13 +2,12 @@ package game
import (
"hk4e/gs/model"
"hk4e/pkg/logger"
"hk4e/protocol/proto"
)
// HandleAbilityInvoke 处理能力调用
func (g *GameManager) HandleAbilityInvoke(player *model.Player, entry *proto.AbilityInvokeEntry) {
logger.LOG.Debug("ability invoke handle, entry: %v", entry.ArgumentType)
//logger.LOG.Debug("ability invoke handle, entry: %v", entry.ArgumentType)
switch entry.ArgumentType {
case proto.AbilityInvokeArgument_ABILITY_INVOKE_ARGUMENT_MIXIN_COST_STAMINA:

View File

@@ -9,6 +9,140 @@ import (
pb "google.golang.org/protobuf/proto"
)
func (g *GameManager) UnionCmdNotify(player *model.Player, payloadMsg pb.Message) {
//logger.LOG.Debug("user send union cmd, uid: %v", player.PlayerID)
req := payloadMsg.(*proto.UnionCmdNotify)
_ = req
world := g.worldManager.GetWorldByID(player.WorldId)
if world == nil {
return
}
scene := world.GetSceneById(player.SceneId)
// 只给附近aoi区域的玩家广播消息
surrPlayerList := make([]*model.Player, 0)
entityIdList := world.aoiManager.GetEntityIdListByPos(float32(player.Pos.X), float32(player.Pos.Y), float32(player.Pos.Z))
for _, entityId := range entityIdList {
entity := scene.GetEntity(entityId)
if entity == nil {
continue
}
if entity.avatarEntity != nil {
otherPlayer := g.userManager.GetOnlineUser(entity.avatarEntity.uid)
surrPlayerList = append(surrPlayerList, otherPlayer)
}
}
// CombatInvocationsNotify转发
// PacketCombatInvocationsNotify
if player.CombatInvokeHandler.AllLen() > 0 {
combatInvocationsNotify := new(proto.CombatInvocationsNotify)
combatInvocationsNotify.InvokeList = player.CombatInvokeHandler.EntryListForwardAll
for _, v := range surrPlayerList {
g.SendMsg(cmd.CombatInvocationsNotify, v.PlayerID, player.ClientSeq, combatInvocationsNotify)
}
}
if player.CombatInvokeHandler.AllExceptCurLen() > 0 {
combatInvocationsNotify := new(proto.CombatInvocationsNotify)
combatInvocationsNotify.InvokeList = player.CombatInvokeHandler.EntryListForwardAllExceptCur
for _, v := range surrPlayerList {
if player.PlayerID == v.PlayerID {
continue
}
g.SendMsg(cmd.CombatInvocationsNotify, v.PlayerID, player.ClientSeq, combatInvocationsNotify)
}
}
if player.CombatInvokeHandler.HostLen() > 0 {
combatInvocationsNotify := new(proto.CombatInvocationsNotify)
combatInvocationsNotify.InvokeList = player.CombatInvokeHandler.EntryListForwardHost
g.SendMsg(cmd.CombatInvocationsNotify, world.owner.PlayerID, player.ClientSeq, combatInvocationsNotify)
}
// AbilityInvocationsNotify转发
// PacketAbilityInvocationsNotify
if player.AbilityInvokeHandler.AllLen() > 0 {
abilityInvocationsNotify := new(proto.AbilityInvocationsNotify)
abilityInvocationsNotify.Invokes = player.AbilityInvokeHandler.EntryListForwardAll
for _, v := range surrPlayerList {
g.SendMsg(cmd.AbilityInvocationsNotify, v.PlayerID, player.ClientSeq, abilityInvocationsNotify)
}
}
if player.AbilityInvokeHandler.AllExceptCurLen() > 0 {
abilityInvocationsNotify := new(proto.AbilityInvocationsNotify)
abilityInvocationsNotify.Invokes = player.AbilityInvokeHandler.EntryListForwardAllExceptCur
for _, v := range surrPlayerList {
if player.PlayerID == v.PlayerID {
continue
}
g.SendMsg(cmd.AbilityInvocationsNotify, v.PlayerID, player.ClientSeq, abilityInvocationsNotify)
}
}
if player.AbilityInvokeHandler.HostLen() > 0 {
abilityInvocationsNotify := new(proto.AbilityInvocationsNotify)
abilityInvocationsNotify.Invokes = player.AbilityInvokeHandler.EntryListForwardHost
g.SendMsg(cmd.AbilityInvocationsNotify, world.owner.PlayerID, player.ClientSeq, abilityInvocationsNotify)
}
// ClientAbilityInitFinishNotify转发
// PacketClientAbilityInitFinishNotify
if player.ClientAbilityInvokeHandler.AllLen() > 0 {
clientAbilityInitFinishNotify := new(proto.ClientAbilityInitFinishNotify)
clientAbilityInitFinishNotify.Invokes = player.ClientAbilityInvokeHandler.EntryListForwardAll
for _, v := range surrPlayerList {
g.SendMsg(cmd.ClientAbilityInitFinishNotify, v.PlayerID, player.ClientSeq, clientAbilityInitFinishNotify)
}
}
if player.ClientAbilityInvokeHandler.AllExceptCurLen() > 0 {
clientAbilityInitFinishNotify := new(proto.ClientAbilityInitFinishNotify)
clientAbilityInitFinishNotify.Invokes = player.ClientAbilityInvokeHandler.EntryListForwardAllExceptCur
for _, v := range surrPlayerList {
if player.PlayerID == v.PlayerID {
continue
}
g.SendMsg(cmd.ClientAbilityInitFinishNotify, v.PlayerID, player.ClientSeq, clientAbilityInitFinishNotify)
}
}
if player.ClientAbilityInvokeHandler.HostLen() > 0 {
clientAbilityInitFinishNotify := new(proto.ClientAbilityInitFinishNotify)
clientAbilityInitFinishNotify.Invokes = player.ClientAbilityInvokeHandler.EntryListForwardHost
g.SendMsg(cmd.ClientAbilityInitFinishNotify, world.owner.PlayerID, player.ClientSeq, clientAbilityInitFinishNotify)
}
player.CombatInvokeHandler.Clear()
player.AbilityInvokeHandler.Clear()
player.ClientAbilityInvokeHandler.Clear()
}
func (g *GameManager) MassiveEntityElementOpBatchNotify(player *model.Player, payloadMsg pb.Message) {
//logger.LOG.Debug("user meeo sync, uid: %v", player.PlayerID)
req := payloadMsg.(*proto.MassiveEntityElementOpBatchNotify)
ntf := req
world := g.worldManager.GetWorldByID(player.WorldId)
if world == nil {
return
}
scene := world.GetSceneById(player.SceneId)
ntf.OpIdx = scene.meeoIndex
scene.meeoIndex++
// 只给附近aoi区域的玩家广播消息
surrPlayerList := make([]*model.Player, 0)
entityIdList := world.aoiManager.GetEntityIdListByPos(float32(player.Pos.X), float32(player.Pos.Y), float32(player.Pos.Z))
for _, entityId := range entityIdList {
entity := scene.GetEntity(entityId)
if entity == nil {
continue
}
if entity.avatarEntity != nil {
otherPlayer := g.userManager.GetOnlineUser(entity.avatarEntity.uid)
surrPlayerList = append(surrPlayerList, otherPlayer)
}
}
for _, v := range surrPlayerList {
g.SendMsg(cmd.MassiveEntityElementOpBatchNotify, v.PlayerID, player.ClientSeq, ntf)
}
}
func (g *GameManager) CombatInvocationsNotify(player *model.Player, payloadMsg pb.Message) {
//logger.LOG.Debug("user combat invocations, uid: %v", player.PlayerID)
req := payloadMsg.(*proto.CombatInvocationsNotify)
@@ -17,15 +151,14 @@ func (g *GameManager) CombatInvocationsNotify(player *model.Player, payloadMsg p
return
}
scene := world.GetSceneById(player.SceneId)
invokeHandler := model.NewInvokeHandler[proto.CombatInvokeEntry]()
for _, entry := range req.InvokeList {
//logger.LOG.Debug("AT: %v, FT: %v, UID: %v", entry.ArgumentType, entry.ForwardType, player.PlayerID)
switch entry.ArgumentType {
case proto.CombatTypeArgument_COMBAT_TYPE_ARGUMENT_EVT_BEING_HIT:
scene.AddAttack(&Attack{
combatInvokeEntry: entry,
uid: player.PlayerID,
})
//case proto.CombatTypeArgument_COMBAT_TYPE_ARGUMENT_EVT_BEING_HIT:
// scene.AddAttack(&Attack{
// combatInvokeEntry: entry,
// uid: player.PlayerID,
// })
case proto.CombatTypeArgument_COMBAT_TYPE_ARGUMENT_ENTITY_MOVE:
entityMoveInfo := new(proto.EntityMoveInfo)
err := pb.Unmarshal(entry.CombatData, entityMoveInfo)
@@ -205,60 +338,16 @@ func (g *GameManager) CombatInvocationsNotify(player *model.Player, payloadMsg p
// 处理耐力消耗
g.HandleStamina(player, motionInfo.State)
invokeHandler.AddEntry(entry.ForwardType, entry)
player.CombatInvokeHandler.AddEntry(entry.ForwardType, entry)
default:
invokeHandler.AddEntry(entry.ForwardType, entry)
player.CombatInvokeHandler.AddEntry(entry.ForwardType, entry)
}
}
// 只给附近aoi区域的玩家广播消息
surrPlayerList := make([]*model.Player, 0)
entityIdList := world.aoiManager.GetEntityIdListByPos(float32(player.Pos.X), float32(player.Pos.Y), float32(player.Pos.Z))
for _, entityId := range entityIdList {
entity := scene.GetEntity(entityId)
if entity == nil {
continue
}
if entity.avatarEntity != nil {
otherPlayer := g.userManager.GetOnlineUser(entity.avatarEntity.uid)
surrPlayerList = append(surrPlayerList, otherPlayer)
}
}
// 处理转发
// PacketCombatInvocationsNotify
if invokeHandler.AllLen() > 0 {
combatInvocationsNotify := new(proto.CombatInvocationsNotify)
combatInvocationsNotify.InvokeList = invokeHandler.EntryListForwardAll
for _, v := range surrPlayerList {
g.SendMsg(cmd.CombatInvocationsNotify, v.PlayerID, v.ClientSeq, combatInvocationsNotify)
}
}
if invokeHandler.AllExceptCurLen() > 0 {
combatInvocationsNotify := new(proto.CombatInvocationsNotify)
combatInvocationsNotify.InvokeList = invokeHandler.EntryListForwardAllExceptCur
for _, v := range surrPlayerList {
if player.PlayerID == v.PlayerID {
continue
}
g.SendMsg(cmd.CombatInvocationsNotify, v.PlayerID, v.ClientSeq, combatInvocationsNotify)
}
}
if invokeHandler.HostLen() > 0 {
combatInvocationsNotify := new(proto.CombatInvocationsNotify)
combatInvocationsNotify.InvokeList = invokeHandler.EntryListForwardHost
g.SendMsg(cmd.CombatInvocationsNotify, world.owner.PlayerID, world.owner.ClientSeq, combatInvocationsNotify)
}
}
func (g *GameManager) AbilityInvocationsNotify(player *model.Player, payloadMsg pb.Message) {
//logger.LOG.Debug("user ability invocations, uid: %v", player.PlayerID)
req := payloadMsg.(*proto.AbilityInvocationsNotify)
if player.AbilityInvokeHandler == nil {
player.AbilityInvokeHandler = model.NewInvokeHandler[proto.AbilityInvokeEntry]()
}
for _, entry := range req.Invokes {
//logger.LOG.Debug("AT: %v, FT: %v, UID: %v", entry.ArgumentType, entry.ForwardType, player.PlayerID)
@@ -272,86 +361,13 @@ func (g *GameManager) AbilityInvocationsNotify(player *model.Player, payloadMsg
func (g *GameManager) ClientAbilityInitFinishNotify(player *model.Player, payloadMsg pb.Message) {
//logger.LOG.Debug("user client ability init finish, uid: %v", player.PlayerID)
req := payloadMsg.(*proto.ClientAbilityInitFinishNotify)
world := g.worldManager.GetWorldByID(player.WorldId)
if world == nil {
return
}
scene := world.GetSceneById(player.SceneId)
invokeHandler := model.NewInvokeHandler[proto.AbilityInvokeEntry]()
for _, entry := range req.Invokes {
//logger.LOG.Debug("AT: %v, FT: %v, UID: %v", entry.ArgumentType, entry.ForwardType, player.PlayerID)
// 处理能力调用
g.HandleAbilityInvoke(player, entry)
invokeHandler.AddEntry(entry.ForwardType, entry)
}
// 只给附近aoi区域的玩家广播消息
surrPlayerList := make([]*model.Player, 0)
entityIdList := world.aoiManager.GetEntityIdListByPos(float32(player.Pos.X), float32(player.Pos.Y), float32(player.Pos.Z))
for _, entityId := range entityIdList {
entity := scene.GetEntity(entityId)
if entity == nil {
continue
}
if entity.avatarEntity != nil {
otherPlayer := g.userManager.GetOnlineUser(entity.avatarEntity.uid)
surrPlayerList = append(surrPlayerList, otherPlayer)
}
}
// AbilityInvocationsNotify转发
if player.AbilityInvokeHandler == nil {
player.AbilityInvokeHandler = model.NewInvokeHandler[proto.AbilityInvokeEntry]()
}
// PacketAbilityInvocationsNotify
if player.AbilityInvokeHandler.AllLen() > 0 {
abilityInvocationsNotify := new(proto.AbilityInvocationsNotify)
abilityInvocationsNotify.Invokes = player.AbilityInvokeHandler.EntryListForwardAll
for _, v := range surrPlayerList {
g.SendMsg(cmd.AbilityInvocationsNotify, v.PlayerID, v.ClientSeq, abilityInvocationsNotify)
}
}
if player.AbilityInvokeHandler.AllExceptCurLen() > 0 {
abilityInvocationsNotify := new(proto.AbilityInvocationsNotify)
abilityInvocationsNotify.Invokes = player.AbilityInvokeHandler.EntryListForwardAllExceptCur
for _, v := range surrPlayerList {
if player.PlayerID == v.PlayerID {
continue
}
g.SendMsg(cmd.AbilityInvocationsNotify, v.PlayerID, v.ClientSeq, abilityInvocationsNotify)
}
}
if player.AbilityInvokeHandler.HostLen() > 0 {
abilityInvocationsNotify := new(proto.AbilityInvocationsNotify)
abilityInvocationsNotify.Invokes = player.AbilityInvokeHandler.EntryListForwardHost
g.SendMsg(cmd.AbilityInvocationsNotify, world.owner.PlayerID, world.owner.ClientSeq, abilityInvocationsNotify)
}
// ClientAbilityInitFinishNotify转发
// PacketClientAbilityInitFinishNotify
if invokeHandler.AllLen() > 0 {
clientAbilityInitFinishNotify := new(proto.ClientAbilityInitFinishNotify)
clientAbilityInitFinishNotify.Invokes = invokeHandler.EntryListForwardAll
for _, v := range surrPlayerList {
g.SendMsg(cmd.ClientAbilityInitFinishNotify, v.PlayerID, v.ClientSeq, clientAbilityInitFinishNotify)
}
}
if invokeHandler.AllExceptCurLen() > 0 {
clientAbilityInitFinishNotify := new(proto.ClientAbilityInitFinishNotify)
clientAbilityInitFinishNotify.Invokes = invokeHandler.EntryListForwardAllExceptCur
for _, v := range surrPlayerList {
if player.PlayerID == v.PlayerID {
continue
}
g.SendMsg(cmd.ClientAbilityInitFinishNotify, v.PlayerID, v.ClientSeq, clientAbilityInitFinishNotify)
}
}
if invokeHandler.HostLen() > 0 {
clientAbilityInitFinishNotify := new(proto.ClientAbilityInitFinishNotify)
clientAbilityInitFinishNotify.Invokes = invokeHandler.EntryListForwardHost
g.SendMsg(cmd.ClientAbilityInitFinishNotify, world.owner.PlayerID, world.owner.ClientSeq, clientAbilityInitFinishNotify)
player.ClientAbilityInvokeHandler.AddEntry(entry.ForwardType, entry)
}
}

View File

@@ -45,10 +45,6 @@ func (g *GameManager) EntityAiSyncNotify(player *model.Player, payloadMsg pb.Mes
logger.LOG.Debug("user entity ai sync, uid: %v", player.PlayerID)
req := payloadMsg.(*proto.EntityAiSyncNotify)
if len(req.LocalAvatarAlertedMonsterList) == 0 {
return
}
// PacketEntityAiSyncNotify
entityAiSyncNotify := new(proto.EntityAiSyncNotify)
entityAiSyncNotify.InfoList = make([]*proto.AiSyncInfo, 0)

View File

@@ -38,6 +38,10 @@ func (g *GameManager) OnLoginOk(userId uint32, player *model.Player, clientSeq u
world.AddPlayer(player, player.SceneId)
player.WorldId = world.id
player.CombatInvokeHandler = model.NewInvokeHandler[proto.CombatInvokeEntry]()
player.AbilityInvokeHandler = model.NewInvokeHandler[proto.AbilityInvokeEntry]()
player.ClientAbilityInvokeHandler = model.NewInvokeHandler[proto.AbilityInvokeEntry]()
//// TODO 薄荷标记
//if world.IsBigWorld() {
// bigWorld := world.GetSceneById(3)

View File

@@ -19,29 +19,29 @@ func (g *GameManager) SceneAvatarStaminaStepReq(player *model.Player, payloadMsg
switch player.StaminaInfo.State {
case proto.MotionState_MOTION_STATE_CLIMB:
// 缓慢攀爬
// 缓慢攀爬的耐力将根据角度不同而改变
// rotX ∈ [0,180) x = rotX
// rotX ∈ [180,360) x = rotX - 360.0
// x >= 0 y = -x + 10
// x < 0 y = -2x + 10
// rotX req.Rot.X
// y 消耗的耐力修正值
// base(-100) + y 消耗的耐力
var x int32
var costRevise int32 // 攀爬耐力修正值
if req.Rot.X >= 0 && req.Rot.X < 180 {
x = int32(req.Rot.X)
} else if req.Rot.X >= 180 && req.Rot.X < 360 {
x = int32(req.Rot.X - 360.0)
}
if x >= 0 {
costRevise = -x + 10
var angleRevise int32 // 角度修正值 归一化为-90到+90范围内的角
// rotX ∈ [0,90) angle = rotX
// rotX ∈ (270,360) angle = rotX - 360.0
if req.Rot.X >= 0 && req.Rot.X < 90 {
angleRevise = int32(req.Rot.X)
} else if req.Rot.X > 270 && req.Rot.X < 360 {
angleRevise = int32(req.Rot.X - 360.0)
} else {
costRevise = -(x * 2) + 10
logger.LOG.Error("invalid rot x angle: %v", req.Rot.X)
}
//logger.LOG.Debug("stamina climbing, rotX: %v, costRevise: %v, cost: %v", req.Rot.X, costRevise, constant.StaminaCostConst.CLIMBING_BASE+costRevise)
g.UpdateStamina(player, constant.StaminaCostConst.CLIMBING_BASE+costRevise)
// 攀爬耐力修正曲线
// angle >= 0 cost = -x + 10
// angle < 0 cost = -2x + 10
var costRevise int32 // 攀爬耐力修正值 在基础消耗值的水平上增加或减少
if angleRevise >= 0 {
// 普通或垂直斜坡
costRevise = -angleRevise + 10
} else {
// 倒三角 非常消耗体力
costRevise = -(angleRevise * 2) + 10
}
logger.LOG.Debug("stamina climbing, rotX: %v, costRevise: %v, cost: %v", req.Rot.X, costRevise, constant.StaminaCostConst.CLIMBING_BASE-costRevise)
g.UpdateStamina(player, constant.StaminaCostConst.CLIMBING_BASE-costRevise)
case proto.MotionState_MOTION_STATE_SWIM_MOVE:
// 缓慢游泳
g.UpdateStamina(player, constant.StaminaCostConst.SWIMMING)

View File

@@ -135,6 +135,7 @@ func (w *World) CreateScene(sceneId uint32) *Scene {
gameTime: 18 * 60,
attackQueue: alg.NewRAQueue[*Attack](1000),
createTime: time.Now().UnixMilli(),
meeoIndex: 0,
}
w.sceneMap[sceneId] = scene
return scene
@@ -169,6 +170,7 @@ type Scene struct {
gameTime uint32
attackQueue *alg.RAQueue[*Attack]
createTime int64
meeoIndex uint32
}
type AvatarEntity struct {

View File

@@ -8,13 +8,14 @@ import (
// 泛型通用转发器
type InvokeType interface {
proto.AbilityInvokeEntry | proto.CombatInvokeEntry
proto.CombatInvokeEntry | proto.AbilityInvokeEntry
}
type InvokeHandler[T InvokeType] struct {
EntryListForwardAll []*T
EntryListForwardAllExceptCur []*T
EntryListForwardHost []*T
EntryListForwardServer []*T
}
func NewInvokeHandler[T InvokeType]() (r *InvokeHandler[T]) {
@@ -27,6 +28,7 @@ func (i *InvokeHandler[T]) InitInvokeHandler() {
i.EntryListForwardAll = make([]*T, 0)
i.EntryListForwardAllExceptCur = make([]*T, 0)
i.EntryListForwardHost = make([]*T, 0)
i.EntryListForwardServer = make([]*T, 0)
}
func (i *InvokeHandler[T]) AddEntry(forward proto.ForwardType, entry *T) {
@@ -39,11 +41,12 @@ func (i *InvokeHandler[T]) AddEntry(forward proto.ForwardType, entry *T) {
i.EntryListForwardAllExceptCur = append(i.EntryListForwardAllExceptCur, entry)
case proto.ForwardType_FORWARD_TYPE_TO_HOST:
i.EntryListForwardHost = append(i.EntryListForwardHost, entry)
case proto.ForwardType_FORWARD_TYPE_ONLY_SERVER:
i.EntryListForwardServer = append(i.EntryListForwardServer, entry)
logger.LOG.Error("fwd server entry: %v", entry)
default:
if forward != proto.ForwardType_FORWARD_TYPE_ONLY_SERVER {
logger.LOG.Error("forward: %v, entry: %v", forward, entry)
}
}
}
func (i *InvokeHandler[T]) AllLen() int {
@@ -57,3 +60,14 @@ func (i *InvokeHandler[T]) AllExceptCurLen() int {
func (i *InvokeHandler[T]) HostLen() int {
return len(i.EntryListForwardHost)
}
func (i *InvokeHandler[T]) ServerLen() int {
return len(i.EntryListForwardServer)
}
func (i *InvokeHandler[T]) Clear() {
i.EntryListForwardAll = make([]*T, 0)
i.EntryListForwardAllExceptCur = make([]*T, 0)
i.EntryListForwardHost = make([]*T, 0)
i.EntryListForwardServer = make([]*T, 0)
}

View File

@@ -67,7 +67,9 @@ type Player struct {
CoopApplyMap map[uint32]int64 `bson:"-"` // 敲门申请的玩家uid及时间
StaminaInfo *StaminaInfo `bson:"-"` // 耐力临时数据
ClientSeq uint32 `bson:"-"` // 客户端发包请求的序号
CombatInvokeHandler *InvokeHandler[proto.CombatInvokeEntry]
AbilityInvokeHandler *InvokeHandler[proto.AbilityInvokeEntry]
ClientAbilityInvokeHandler *InvokeHandler[proto.AbilityInvokeEntry]
}
func (p *Player) GetNextGameObjectGuid() uint64 {

View File

@@ -100,8 +100,13 @@ func (l *Logger) doLog() {
"goroutine:" + logInfo.GoroutineId +
"]" + RESET + " "
}
logStr := logHeader + fmt.Sprintf(logInfo.Msg, logInfo.Param...) + "\n"
logStr := logHeader
if logInfo.Level == ERROR {
logStr += RED + fmt.Sprintf(logInfo.Msg, logInfo.Param...) + RESET + "\n"
} else {
logStr += fmt.Sprintf(logInfo.Msg, logInfo.Param...) + "\n"
}
if logInfo.Stack != "" {
logStr += logInfo.Stack
}
if l.Method == CONSOLE {
@@ -126,7 +131,6 @@ func (l *Logger) Debug(msg string, param ...any) {
if l.TrackLine {
logInfo.FileName, logInfo.Line, logInfo.FuncName = l.getLineFunc()
logInfo.GoroutineId = l.getGoroutineId()
logInfo.Stack = l.Stack()
}
l.LogInfoChan <- logInfo
}
@@ -142,12 +146,26 @@ func (l *Logger) Info(msg string, param ...any) {
if l.TrackLine {
logInfo.FileName, logInfo.Line, logInfo.FuncName = l.getLineFunc()
logInfo.GoroutineId = l.getGoroutineId()
logInfo.Stack = l.Stack()
}
l.LogInfoChan <- logInfo
}
func (l *Logger) Error(msg string, param ...any) {
if l.Level > ERROR {
return
}
logInfo := new(LogInfo)
logInfo.Level = ERROR
logInfo.Msg = msg
logInfo.Param = param
if l.TrackLine {
logInfo.FileName, logInfo.Line, logInfo.FuncName = l.getLineFunc()
logInfo.GoroutineId = l.getGoroutineId()
}
l.LogInfoChan <- logInfo
}
func (l *Logger) ErrorStack(msg string, param ...any) {
if l.Level > ERROR {
return
}

View File

@@ -100,6 +100,7 @@ func (a *CmdProtoMap) registerAllMessage() {
a.registerMessage(ClientAbilityInitFinishNotify, &proto.ClientAbilityInitFinishNotify{}) // 客户端技能初始化完成通知 多人游戏服务器转发
a.registerMessage(EvtDoSkillSuccNotify, &proto.EvtDoSkillSuccNotify{}) // 释放技能成功事件通知
a.registerMessage(ClientAbilityChangeNotify, &proto.ClientAbilityChangeNotify{}) // 客户端技能改变通知
a.registerMessage(MassiveEntityElementOpBatchNotify, &proto.MassiveEntityElementOpBatchNotify{}) // MEEO通知
// 队伍
a.registerMessage(ChangeAvatarReq, &proto.ChangeAvatarReq{}) // 更换角色请求 切人
@@ -223,15 +224,15 @@ func (a *CmdProtoMap) registerAllMessage() {
a.registerMessage(ServerAnnounceNotify, &proto.ServerAnnounceNotify{}) // 服务器公告通知
a.registerMessage(ServerAnnounceRevokeNotify, &proto.ServerAnnounceRevokeNotify{}) // 服务器公告撤销通知
// TODO
a.registerMessage(EvtAiSyncSkillCdNotify, &proto.EvtAiSyncSkillCdNotify{})
a.registerMessage(EvtAiSyncCombatThreatInfoNotify, &proto.EvtAiSyncCombatThreatInfoNotify{})
a.registerMessage(EntityConfigHashNotify, &proto.EntityConfigHashNotify{})
a.registerMessage(MonsterAIConfigHashNotify, &proto.MonsterAIConfigHashNotify{})
a.registerMessage(GetRegionSearchReq, &proto.GetRegionSearchReq{})
a.registerMessage(ObstacleModifyNotify, &proto.ObstacleModifyNotify{})
a.registerMessage(EvtCreateGadgetNotify, &proto.EvtCreateGadgetNotify{})
a.registerMessage(EvtDestroyGadgetNotify, &proto.EvtDestroyGadgetNotify{})
//// TODO
//a.registerMessage(EvtAiSyncSkillCdNotify, &proto.EvtAiSyncSkillCdNotify{})
//a.registerMessage(EvtAiSyncCombatThreatInfoNotify, &proto.EvtAiSyncCombatThreatInfoNotify{})
//a.registerMessage(EntityConfigHashNotify, &proto.EntityConfigHashNotify{})
//a.registerMessage(MonsterAIConfigHashNotify, &proto.MonsterAIConfigHashNotify{})
//a.registerMessage(GetRegionSearchReq, &proto.GetRegionSearchReq{})
//a.registerMessage(ObstacleModifyNotify, &proto.ObstacleModifyNotify{})
//a.registerMessage(EvtCreateGadgetNotify, &proto.EvtCreateGadgetNotify{})
//a.registerMessage(EvtDestroyGadgetNotify, &proto.EvtDestroyGadgetNotify{})
// 空消息
a.registerMessage(65535, &proto.NullMsg{})