场景group加载卸载流程优化

This commit is contained in:
flswld
2023-03-22 19:35:55 +08:00
parent b5267d57d8
commit e370098d86
7 changed files with 200 additions and 105 deletions

View File

@@ -327,7 +327,10 @@ func (g *GameManager) AoiPlayerMove(player *model.Player, oldPos *model.Vector,
for _, entity := range group.GetAllEntity() {
delEntityIdList = append(delEntityIdList, entity.GetId())
}
g.RemoveGroup(scene, groupConfig)
if !world.GetMultiplayer() {
// 处理多人世界不同玩家不同位置的group卸载情况
g.RemoveGroup(scene, groupConfig)
}
}
// 出现的场景实体
addEntityIdList := make([]uint32, 0)
@@ -339,6 +342,9 @@ func (g *GameManager) AoiPlayerMove(player *model.Player, oldPos *model.Vector,
// 新有旧没有的group即为出现的
g.AddSceneGroup(scene, groupConfig)
group := scene.GetGroupById(groupId)
if group == nil {
continue
}
for _, entity := range group.GetAllEntity() {
addEntityIdList = append(addEntityIdList, entity.GetId())
}

View File

@@ -10,7 +10,6 @@ import (
"hk4e/gs/model"
"hk4e/pkg/logger"
"hk4e/pkg/object"
"hk4e/pkg/random"
"hk4e/protocol/cmd"
"hk4e/protocol/proto"
@@ -23,24 +22,59 @@ const (
)
func (g *GameManager) EnterSceneReadyReq(player *model.Player, payloadMsg pb.Message) {
req := payloadMsg.(*proto.EnterSceneReadyReq)
logger.Debug("player enter scene ready, uid: %v", player.PlayerID)
world := WORLD_MANAGER.GetWorldByID(player.WorldId)
enterSceneContext := world.GetEnterSceneContextByToken(req.EnterSceneToken)
aoiManager, exist := WORLD_MANAGER.GetSceneBlockAoiMap()[enterSceneContext.OldSceneId]
if !exist {
logger.Error("player scene not exist in aoi, sceneId: %v, uid: %v", enterSceneContext.OldSceneId, player.PlayerID)
return
}
objectList := aoiManager.GetObjectListByPos(float32(enterSceneContext.OldPos.X), 0.0, float32(enterSceneContext.OldPos.Z))
delEntityIdList := make([]uint32, 0)
oldScene := world.GetSceneById(enterSceneContext.OldSceneId)
for _, groupAny := range objectList {
groupConfig := groupAny.(*gdconf.Group)
distance2D := math.Sqrt((player.Pos.X-float64(groupConfig.Pos.X))*(player.Pos.X-float64(groupConfig.Pos.X)) +
(player.Pos.Z-float64(groupConfig.Pos.Z))*(player.Pos.Z-float64(groupConfig.Pos.Z)))
if distance2D > ENTITY_LOD {
continue
}
if groupConfig.DynamicLoad {
continue
}
group := oldScene.GetGroupById(uint32(groupConfig.Id))
if group == nil {
continue
}
for _, entity := range group.GetAllEntity() {
delEntityIdList = append(delEntityIdList, entity.GetId())
}
if !world.GetMultiplayer() {
// 处理多人世界不同玩家不同位置的group卸载情况
g.RemoveGroup(oldScene, groupConfig)
}
}
g.RemoveSceneEntityNotifyToPlayer(player, proto.VisionType_VISION_MISS, delEntityIdList)
enterScenePeerNotify := &proto.EnterScenePeerNotify{
DestSceneId: player.SceneId,
PeerId: world.GetPlayerPeerId(player),
HostPeerId: world.GetPlayerPeerId(world.GetOwner()),
EnterSceneToken: player.EnterSceneToken,
EnterSceneToken: req.EnterSceneToken,
}
g.SendMsg(cmd.EnterScenePeerNotify, player.PlayerID, player.ClientSeq, enterScenePeerNotify)
enterSceneReadyRsp := &proto.EnterSceneReadyRsp{
EnterSceneToken: player.EnterSceneToken,
EnterSceneToken: req.EnterSceneToken,
}
g.SendMsg(cmd.EnterSceneReadyRsp, player.PlayerID, player.ClientSeq, enterSceneReadyRsp)
}
func (g *GameManager) SceneInitFinishReq(player *model.Player, payloadMsg pb.Message) {
req := payloadMsg.(*proto.SceneInitFinishReq)
logger.Debug("player scene init finish, uid: %v", player.PlayerID)
world := WORLD_MANAGER.GetWorldByID(player.WorldId)
scene := world.GetSceneById(player.SceneId)
@@ -136,7 +170,7 @@ func (g *GameManager) SceneInitFinishReq(player *model.Player, payloadMsg pb.Mes
activeAvatarId := world.GetPlayerActiveAvatarId(player)
playerEnterSceneInfoNotify := &proto.PlayerEnterSceneInfoNotify{
CurAvatarEntityId: world.GetPlayerWorldAvatarEntityId(player, activeAvatarId),
EnterSceneToken: player.EnterSceneToken,
EnterSceneToken: req.EnterSceneToken,
TeamEnterInfo: &proto.TeamEnterSceneInfo{
TeamEntityId: world.GetPlayerTeamEntityId(player),
TeamAbilityInfo: empty,
@@ -235,30 +269,15 @@ func (g *GameManager) SceneInitFinishReq(player *model.Player, payloadMsg pb.Mes
g.SendMsg(cmd.DungeonDataNotify, player.PlayerID, player.ClientSeq, &proto.DungeonDataNotify{})
SceneInitFinishRsp := &proto.SceneInitFinishRsp{
EnterSceneToken: player.EnterSceneToken,
EnterSceneToken: req.EnterSceneToken,
}
g.SendMsg(cmd.SceneInitFinishRsp, player.PlayerID, player.ClientSeq, SceneInitFinishRsp)
player.SceneLoadState = model.SceneInitFinish
}
func (g *GameManager) AddSceneGroup(scene *Scene, groupConfig *gdconf.Group) {
initSuiteId := int(groupConfig.GroupInitConfig.Suite)
if initSuiteId > len(groupConfig.SuiteList) {
logger.Error("invalid init suite id: %v", initSuiteId)
return
}
scene.AddGroupSuite(uint32(groupConfig.Id), uint8(initSuiteId))
}
func (g *GameManager) RemoveGroup(scene *Scene, groupConfig *gdconf.Group) {
group := scene.GetGroupById(uint32(groupConfig.Id))
for suiteId := range group.GetAllSuite() {
scene.RemoveGroupSuite(uint32(groupConfig.Id), suiteId)
}
}
func (g *GameManager) EnterSceneDoneReq(player *model.Player, payloadMsg pb.Message) {
req := payloadMsg.(*proto.EnterSceneDoneReq)
logger.Debug("player enter scene done, uid: %v", player.PlayerID)
world := WORLD_MANAGER.GetWorldByID(player.WorldId)
scene := world.GetSceneById(player.SceneId)
@@ -288,39 +307,35 @@ func (g *GameManager) EnterSceneDoneReq(player *model.Player, payloadMsg pb.Mess
// 加载附近的group
aoiManager, exist := WORLD_MANAGER.GetSceneBlockAoiMap()[scene.GetId()]
addEntityIdList := make([]uint32, 0)
if exist {
objectList := aoiManager.GetObjectListByPos(float32(player.Pos.X), 0.0, float32(player.Pos.Z))
for _, groupAny := range objectList {
groupConfig := groupAny.(*gdconf.Group)
distance2D := math.Sqrt((player.Pos.X-float64(groupConfig.Pos.X))*(player.Pos.X-float64(groupConfig.Pos.X)) +
(player.Pos.Z-float64(groupConfig.Pos.Z))*(player.Pos.Z-float64(groupConfig.Pos.Z)))
if distance2D > ENTITY_LOD {
continue
}
if groupConfig.DynamicLoad {
continue
}
g.AddSceneGroup(scene, groupConfig)
group := scene.GetGroupById(uint32(groupConfig.Id))
for _, entity := range group.GetAllEntity() {
addEntityIdList = append(addEntityIdList, entity.GetId())
}
}
if !exist {
logger.Error("player scene not exist in aoi, sceneId: %v, uid: %v", scene.GetId(), player.PlayerID)
return
}
objectList := aoiManager.GetObjectListByPos(float32(player.Pos.X), 0.0, float32(player.Pos.Z))
for _, groupAny := range objectList {
groupConfig := groupAny.(*gdconf.Group)
distance2D := math.Sqrt((player.Pos.X-float64(groupConfig.Pos.X))*(player.Pos.X-float64(groupConfig.Pos.X)) +
(player.Pos.Z-float64(groupConfig.Pos.Z))*(player.Pos.Z-float64(groupConfig.Pos.Z)))
if distance2D > ENTITY_LOD {
continue
}
if groupConfig.DynamicLoad {
continue
}
g.AddSceneGroup(scene, groupConfig)
}
entityIdList := make([]uint32, 0)
if player.SceneJump {
visionType = proto.VisionType_VISION_MEET
entityMap := scene.GetAllEntity()
for _, entity := range entityMap {
if entity.GetId() == activeAvatarEntityId {
continue
}
entityIdList = append(entityIdList, entity.GetId())
}
} else {
visionType = proto.VisionType_VISION_TRANSPORT
entityIdList = addEntityIdList
}
entityIdList := make([]uint32, 0)
entityMap := scene.GetAllEntity()
for _, entity := range entityMap {
if entity.GetId() == activeAvatarEntityId {
continue
}
entityIdList = append(entityIdList, entity.GetId())
}
g.AddSceneEntityNotify(player, visionType, entityIdList, false, false)
@@ -331,7 +346,7 @@ func (g *GameManager) EnterSceneDoneReq(player *model.Player, payloadMsg pb.Mess
g.SendMsg(cmd.SceneAreaWeatherNotify, player.PlayerID, player.ClientSeq, sceneAreaWeatherNotify)
enterSceneDoneRsp := &proto.EnterSceneDoneRsp{
EnterSceneToken: player.EnterSceneToken,
EnterSceneToken: req.EnterSceneToken,
}
g.SendMsg(cmd.EnterSceneDoneRsp, player.PlayerID, player.ClientSeq, enterSceneDoneRsp)
@@ -351,10 +366,11 @@ func (g *GameManager) EnterSceneDoneReq(player *model.Player, payloadMsg pb.Mess
}
func (g *GameManager) PostEnterSceneReq(player *model.Player, payloadMsg pb.Message) {
req := payloadMsg.(*proto.PostEnterSceneReq)
logger.Debug("player post enter scene, uid: %v", player.PlayerID)
postEnterSceneRsp := &proto.PostEnterSceneRsp{
EnterSceneToken: player.EnterSceneToken,
EnterSceneToken: req.EnterSceneToken,
}
g.SendMsg(cmd.PostEnterSceneRsp, player.PlayerID, player.ClientSeq, postEnterSceneRsp)
}
@@ -384,7 +400,6 @@ func (g *GameManager) ChangeGameTimeReq(player *model.Player, payloadMsg pb.Mess
g.SendMsg(cmd.ChangeGameTimeRsp, player.PlayerID, player.ClientSeq, changeGameTimeRsp)
}
// SceneEntityDrownReq 实体溺水请求
func (g *GameManager) SceneEntityDrownReq(player *model.Player, payloadMsg pb.Message) {
req := payloadMsg.(*proto.SceneEntityDrownReq)
@@ -401,6 +416,18 @@ func (g *GameManager) SceneEntityDrownReq(player *model.Player, payloadMsg pb.Me
g.SendMsg(cmd.SceneEntityDrownRsp, player.PlayerID, player.ClientSeq, sceneEntityDrownRsp)
}
func (g *GameManager) NpcTalkReq(player *model.Player, payloadMsg pb.Message) {
req := payloadMsg.(*proto.NpcTalkReq)
rsp := &proto.NpcTalkRsp{
CurTalkId: req.TalkId,
NpcEntityId: req.NpcEntityId,
EntityId: req.EntityId,
}
g.SendMsg(cmd.EnterSceneReadyRsp, player.PlayerID, player.ClientSeq, rsp)
}
var SceneTransactionSeq uint32 = 0
func (g *GameManager) PacketPlayerEnterSceneNotifyLogin(player *model.Player, enterType proto.EnterType) *proto.PlayerEnterSceneNotify {
world := WORLD_MANAGER.GetWorldByID(player.WorldId)
scene := world.GetSceneById(player.SceneId)
@@ -408,24 +435,24 @@ func (g *GameManager) PacketPlayerEnterSceneNotifyLogin(player *model.Player, en
logger.Error("scene is nil, sceneId: %v", player.SceneId)
return new(proto.PlayerEnterSceneNotify)
}
player.EnterSceneToken = uint32(random.GetRandomInt32(5000, 50000))
playerEnterSceneNotify := &proto.PlayerEnterSceneNotify{
SceneId: player.SceneId,
Pos: &proto.Vector{X: float32(player.Pos.X), Y: float32(player.Pos.Y), Z: float32(player.Pos.Z)},
SceneBeginTime: uint64(scene.GetSceneCreateTime()),
Type: enterType,
TargetUid: player.PlayerID,
EnterSceneToken: player.EnterSceneToken,
EnterSceneToken: world.enterSceneToken,
WorldLevel: player.PropertiesMap[constant.PLAYER_PROP_PLAYER_WORLD_LEVEL],
EnterReason: uint32(proto.EnterReason_ENTER_REASON_LOGIN),
IsFirstLoginEnterScene: true,
WorldType: 1,
SceneTagIdList: make([]uint32, 0),
}
SceneTransactionSeq++
playerEnterSceneNotify.SceneTransaction = strconv.Itoa(int(player.SceneId)) + "-" +
strconv.Itoa(int(player.PlayerID)) + "-" +
strconv.Itoa(int(time.Now().Unix())) + "-" +
"296359"
strconv.Itoa(int(SceneTransactionSeq))
for _, sceneTagDataConfig := range gdconf.GetSceneTagDataMap() {
if uint32(sceneTagDataConfig.SceneId) == player.SceneId {
playerEnterSceneNotify.SceneTagIdList = append(playerEnterSceneNotify.SceneTagIdList, uint32(sceneTagDataConfig.SceneTagId))
@@ -460,7 +487,14 @@ func (g *GameManager) PacketPlayerEnterSceneNotifyMp(
logger.Error("scene is nil, sceneId: %v", player.SceneId)
return new(proto.PlayerEnterSceneNotify)
}
player.EnterSceneToken = uint32(random.GetRandomInt32(5000, 50000))
enterSceneToken := world.AddEnterSceneContext(&EnterSceneContext{
OldSceneId: prevSceneId,
OldPos: &model.Vector{
X: prevPos.X,
Y: prevPos.Y,
Z: prevPos.Z,
},
})
playerEnterSceneNotify := &proto.PlayerEnterSceneNotify{
PrevSceneId: prevSceneId,
PrevPos: &proto.Vector{X: float32(prevPos.X), Y: float32(prevPos.Y), Z: float32(prevPos.Z)},
@@ -469,17 +503,18 @@ func (g *GameManager) PacketPlayerEnterSceneNotifyMp(
SceneBeginTime: uint64(scene.GetSceneCreateTime()),
Type: enterType,
TargetUid: targetPlayer.PlayerID,
EnterSceneToken: player.EnterSceneToken,
EnterSceneToken: enterSceneToken,
WorldLevel: targetPlayer.PropertiesMap[constant.PLAYER_PROP_PLAYER_WORLD_LEVEL],
EnterReason: enterReason,
WorldType: 1,
DungeonId: dungeonId,
SceneTagIdList: make([]uint32, 0),
}
SceneTransactionSeq++
playerEnterSceneNotify.SceneTransaction = strconv.Itoa(int(player.SceneId)) + "-" +
strconv.Itoa(int(targetPlayer.PlayerID)) + "-" +
strconv.Itoa(int(time.Now().Unix())) + "-" +
"296359"
strconv.Itoa(int(SceneTransactionSeq))
for _, sceneTagDataConfig := range gdconf.GetSceneTagDataMap() {
if uint32(sceneTagDataConfig.SceneId) == player.SceneId {
playerEnterSceneNotify.SceneTagIdList = append(playerEnterSceneNotify.SceneTagIdList, uint32(sceneTagDataConfig.SceneTagId))
@@ -488,6 +523,26 @@ func (g *GameManager) PacketPlayerEnterSceneNotifyMp(
return playerEnterSceneNotify
}
func (g *GameManager) AddSceneGroup(scene *Scene, groupConfig *gdconf.Group) {
initSuiteId := int(groupConfig.GroupInitConfig.Suite)
if initSuiteId < 1 || initSuiteId > len(groupConfig.SuiteList) {
logger.Error("invalid init suite id: %v", initSuiteId)
return
}
scene.AddGroupSuite(uint32(groupConfig.Id), uint8(initSuiteId))
}
func (g *GameManager) RemoveGroup(scene *Scene, groupConfig *gdconf.Group) {
group := scene.GetGroupById(uint32(groupConfig.Id))
if group == nil {
logger.Error("group not exist, groupId: %v", groupConfig.Id)
return
}
for suiteId := range group.GetAllSuite() {
scene.RemoveGroupSuite(uint32(groupConfig.Id), suiteId)
}
}
func (g *GameManager) AddSceneEntityNotifyToPlayer(player *model.Player, visionType proto.VisionType, entityList []*proto.SceneEntityInfo) {
sceneEntityAppearNotify := &proto.SceneEntityAppearNotify{
AppearType: visionType,

View File

@@ -140,6 +140,7 @@ func (r *RouteManager) initRoute() {
r.registerRouter(cmd.SetEquipLockStateReq, GAME_MANAGER.SetEquipLockStateReq)
r.registerRouter(cmd.TakeoffEquipReq, GAME_MANAGER.TakeoffEquipReq)
r.registerRouter(cmd.AddQuestContentProgressReq, GAME_MANAGER.AddQuestContentProgressReq)
r.registerRouter(cmd.NpcTalkReq, GAME_MANAGER.NpcTalkReq)
}
func (r *RouteManager) RouteHandle(netMsg *mq.NetMsg) {

View File

@@ -8,6 +8,7 @@ import (
"hk4e/gs/model"
"hk4e/pkg/alg"
"hk4e/pkg/logger"
"hk4e/pkg/random"
"hk4e/protocol/proto"
)
@@ -47,19 +48,21 @@ func (w *WorldManager) GetAllWorld() map[uint32]*World {
func (w *WorldManager) CreateWorld(owner *model.Player) *World {
worldId := uint32(w.snowflake.GenId())
world := &World{
id: worldId,
owner: owner,
playerMap: make(map[uint32]*model.Player),
sceneMap: make(map[uint32]*Scene),
entityIdCounter: 0,
worldLevel: 0,
multiplayer: false,
mpLevelEntityId: 0,
chatMsgList: make([]*proto.ChatInfo, 0),
playerFirstEnterMap: make(map[uint32]int64),
waitEnterPlayerMap: make(map[uint32]int64),
multiplayerTeam: CreateMultiplayerTeam(),
peerList: make([]*model.Player, 0),
id: worldId,
owner: owner,
playerMap: make(map[uint32]*model.Player),
sceneMap: make(map[uint32]*Scene),
enterSceneToken: uint32(random.GetRandomInt32(5000, 50000)),
enterSceneContextMap: make(map[uint32]*EnterSceneContext),
entityIdCounter: 0,
worldLevel: 0,
multiplayer: false,
mpLevelEntityId: 0,
chatMsgList: make([]*proto.ChatInfo, 0),
playerFirstEnterMap: make(map[uint32]int64),
waitEnterPlayerMap: make(map[uint32]int64),
multiplayerTeam: CreateMultiplayerTeam(),
peerList: make([]*model.Player, 0),
}
world.mpLevelEntityId = world.GetNextWorldEntityId(constant.ENTITY_TYPE_MP_LEVEL)
w.worldMap[worldId] = world
@@ -200,21 +203,29 @@ func (w *WorldManager) GetMultiplayerWorldNum() uint32 {
return w.multiplayerWorldNum
}
// EnterSceneContext 场景切换上下文数据结构
type EnterSceneContext struct {
OldSceneId uint32
OldPos *model.Vector
}
// World 世界数据结构
type World struct {
id uint32
owner *model.Player
playerMap map[uint32]*model.Player
sceneMap map[uint32]*Scene
entityIdCounter uint32 // 世界的实体id生成计数器
worldLevel uint8 // 世界等级
multiplayer bool // 是否多人世界
mpLevelEntityId uint32
chatMsgList []*proto.ChatInfo // 世界聊天消息列表
playerFirstEnterMap map[uint32]int64 // 玩家第一次进入世界的时间 key:uid value:进入时间
waitEnterPlayerMap map[uint32]int64 // 进入世界的玩家等待列表 key:uid value:开始时间
multiplayerTeam *MultiplayerTeam
peerList []*model.Player // 玩家编号列表
id uint32
owner *model.Player
playerMap map[uint32]*model.Player
sceneMap map[uint32]*Scene
enterSceneToken uint32
enterSceneContextMap map[uint32]*EnterSceneContext // 场景切换上下文 key:EnterSceneToken value:EnterSceneContext
entityIdCounter uint32 // 世界的实体id生成计数器
worldLevel uint8 // 世界等级
multiplayer bool // 是否多人世界
mpLevelEntityId uint32 // 多人世界等级实体id
chatMsgList []*proto.ChatInfo // 世界聊天消息列表
playerFirstEnterMap map[uint32]int64 // 玩家第一次进入世界的时间 key:uid value:进入时间
waitEnterPlayerMap map[uint32]int64 // 进入世界的玩家等待列表 key:uid value:开始时间
multiplayerTeam *MultiplayerTeam // 多人队伍
peerList []*model.Player // 玩家编号列表
}
func (w *World) GetId() uint32 {
@@ -233,6 +244,20 @@ func (w *World) GetAllScene() map[uint32]*Scene {
return w.sceneMap
}
func (w *World) GetEnterSceneToken() uint32 {
return w.enterSceneToken
}
func (w *World) GetEnterSceneContextByToken(token uint32) *EnterSceneContext {
return w.enterSceneContextMap[token]
}
func (w *World) AddEnterSceneContext(ctx *EnterSceneContext) uint32 {
w.enterSceneToken += 100
w.enterSceneContextMap[w.enterSceneToken] = ctx
return w.enterSceneToken
}
func (w *World) GetWorldLevel() uint8 {
return w.worldLevel
}

View File

@@ -397,7 +397,12 @@ func (s *Scene) AddGroupSuite(groupId uint32, suiteId uint8) {
logger.Error("get scene group config is nil, groupId: %v", groupId)
return
}
suiteConfig := groupConfig.SuiteList[suiteId-1]
suiteIndex := suiteId - 1
if int(suiteIndex) >= len(groupConfig.SuiteList) {
logger.Error("invalid suiteId: %v", suiteId)
return
}
suiteConfig := groupConfig.SuiteList[suiteIndex]
suite := &Suite{
entityMap: make(map[uint32]*Entity),
}
@@ -431,6 +436,7 @@ func (s *Scene) AddGroupSuite(groupId uint32, suiteId uint8) {
group = &Group{
suiteMap: make(map[uint8]*Suite),
}
s.groupMap[groupId] = group
}
group.suiteMap[suiteId] = suite
}

View File

@@ -56,7 +56,6 @@ type Player struct {
DbWorld *DbWorld // 大世界
// 在线数据 请随意 记得加忽略字段的tag
LastSaveTime uint32 `bson:"-" msgpack:"-"` // 上一次保存时间
EnterSceneToken uint32 `bson:"-" msgpack:"-"` // 世界进入令牌
DbState int `bson:"-" msgpack:"-"` // 数据库存档状态
WorldId uint32 `bson:"-" msgpack:"-"` // 所在的世界id
GameObjectGuidCounter uint64 `bson:"-" msgpack:"-"` // 游戏对象guid计数器

View File

@@ -116,6 +116,8 @@ func (c *CmdProtoMap) registerAllMessage() {
c.regMsg(DungeonDataNotify, func() any { return new(proto.DungeonDataNotify) }) // 地牢副本相关
c.regMsg(SceneAudioNotify, func() any { return new(proto.SceneAudioNotify) }) // 场景风物之琴音乐同步通知
c.regMsg(BeginCameraSceneLookNotify, func() any { return new(proto.BeginCameraSceneLookNotify) }) // 场景镜头注目通知
c.regMsg(NpcTalkReq, func() any { return new(proto.NpcTalkReq) }) // NPC对话请求
c.regMsg(NpcTalkRsp, func() any { return new(proto.NpcTalkRsp) }) // NPC对话响应
// 战斗与同步
c.regMsg(AvatarFightPropNotify, func() any { return new(proto.AvatarFightPropNotify) }) // 角色战斗属性通知
@@ -222,24 +224,25 @@ func (c *CmdProtoMap) registerAllMessage() {
c.regMsg(DoGachaRsp, func() any { return new(proto.DoGachaRsp) }) // 抽卡响应
// 角色
c.regMsg(AvatarDataNotify, func() any { return new(proto.AvatarDataNotify) }) // 角色信息通知
c.regMsg(AvatarAddNotify, func() any { return new(proto.AvatarAddNotify) }) // 角色新增通知
c.regMsg(AvatarLifeStateChangeNotify, func() any { return new(proto.AvatarLifeStateChangeNotify) }) // 角色存活状态改变通知
c.regMsg(AvatarUpgradeReq, func() any { return new(proto.AvatarUpgradeReq) }) // 角色升级请求
c.regMsg(AvatarUpgradeRsp, func() any { return new(proto.AvatarUpgradeRsp) }) // 角色升级通知
c.regMsg(AvatarPropNotify, func() any { return new(proto.AvatarPropNotify) }) // 角色属性表更新通知
c.regMsg(AvatarPromoteReq, func() any { return new(proto.AvatarPromoteReq) }) // 角色突破请求
c.regMsg(AvatarPromoteRsp, func() any { return new(proto.AvatarPromoteRsp) }) // 角色突破响应
c.regMsg(AvatarPromoteGetRewardReq, func() any { return new(proto.AvatarPromoteGetRewardReq) }) // 角色突破获取奖励请求
c.regMsg(AvatarPromoteGetRewardRsp, func() any { return new(proto.AvatarPromoteGetRewardRsp) }) // 角色突破获取奖励响应
c.regMsg(AvatarChangeCostumeReq, func() any { return new(proto.AvatarChangeCostumeReq) }) // 角色换装请求
c.regMsg(AvatarChangeCostumeRsp, func() any { return new(proto.AvatarChangeCostumeRsp) }) // 角色换装响应
c.regMsg(AvatarChangeCostumeNotify, func() any { return new(proto.AvatarChangeCostumeNotify) }) // 角色换装通知
c.regMsg(AvatarGainCostumeNotify, func() any { return new(proto.AvatarGainCostumeNotify) }) // 角色获得时装通知
c.regMsg(AvatarWearFlycloakReq, func() any { return new(proto.AvatarWearFlycloakReq) }) // 角色换风之翼请求
c.regMsg(AvatarWearFlycloakRsp, func() any { return new(proto.AvatarWearFlycloakRsp) }) // 角色换风之翼响应
c.regMsg(AvatarFlycloakChangeNotify, func() any { return new(proto.AvatarFlycloakChangeNotify) }) // 角色换风之翼通知
c.regMsg(AvatarGainFlycloakNotify, func() any { return new(proto.AvatarGainFlycloakNotify) }) // 角色获得风之翼通知
c.regMsg(AvatarDataNotify, func() any { return new(proto.AvatarDataNotify) }) // 角色信息通知
c.regMsg(AvatarAddNotify, func() any { return new(proto.AvatarAddNotify) }) // 角色新增通知
c.regMsg(AvatarLifeStateChangeNotify, func() any { return new(proto.AvatarLifeStateChangeNotify) }) // 角色存活状态改变通知
c.regMsg(AvatarUpgradeReq, func() any { return new(proto.AvatarUpgradeReq) }) // 角色升级请求
c.regMsg(AvatarUpgradeRsp, func() any { return new(proto.AvatarUpgradeRsp) }) // 角色升级通知
c.regMsg(AvatarPropNotify, func() any { return new(proto.AvatarPropNotify) }) // 角色属性表更新通知
c.regMsg(AvatarPromoteReq, func() any { return new(proto.AvatarPromoteReq) }) // 角色突破请求
c.regMsg(AvatarPromoteRsp, func() any { return new(proto.AvatarPromoteRsp) }) // 角色突破响应
c.regMsg(AvatarPromoteGetRewardReq, func() any { return new(proto.AvatarPromoteGetRewardReq) }) // 角色突破获取奖励请求
c.regMsg(AvatarPromoteGetRewardRsp, func() any { return new(proto.AvatarPromoteGetRewardRsp) }) // 角色突破获取奖励响应
c.regMsg(AvatarChangeCostumeReq, func() any { return new(proto.AvatarChangeCostumeReq) }) // 角色换装请求
c.regMsg(AvatarChangeCostumeRsp, func() any { return new(proto.AvatarChangeCostumeRsp) }) // 角色换装响应
c.regMsg(AvatarChangeCostumeNotify, func() any { return new(proto.AvatarChangeCostumeNotify) }) // 角色换装通知
c.regMsg(AvatarGainCostumeNotify, func() any { return new(proto.AvatarGainCostumeNotify) }) // 角色获得时装通知
c.regMsg(AvatarWearFlycloakReq, func() any { return new(proto.AvatarWearFlycloakReq) }) // 角色换风之翼请求
c.regMsg(AvatarWearFlycloakRsp, func() any { return new(proto.AvatarWearFlycloakRsp) }) // 角色换风之翼响应
c.regMsg(AvatarFlycloakChangeNotify, func() any { return new(proto.AvatarFlycloakChangeNotify) }) // 角色换风之翼通知
c.regMsg(AvatarGainFlycloakNotify, func() any { return new(proto.AvatarGainFlycloakNotify) }) // 角色获得风之翼通知
c.regMsg(AvatarSkillDepotChangeNotify, func() any { return new(proto.AvatarSkillDepotChangeNotify) }) // 角色技能库切换通知 主角切元素
// 背包与道具
c.regMsg(PlayerStoreNotify, func() any { return new(proto.PlayerStoreNotify) }) // 玩家背包数据通知