diff --git a/go.mod b/go.mod index b1f44b10..f48dc374 100644 --- a/go.mod +++ b/go.mod @@ -53,6 +53,9 @@ require github.com/spf13/cobra v1.6.1 // redis require github.com/go-redis/redis/v8 v8.11.5 +// midi +require gitlab.com/gomidi/midi/v2 v2.0.25 + require ( github.com/cespare/xxhash/v2 v2.1.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect diff --git a/go.sum b/go.sum index 1d12c77e..3c77ae44 100644 --- a/go.sum +++ b/go.sum @@ -147,6 +147,8 @@ github.com/xtaci/lossyconn v0.0.0-20200209145036-adba10fffc37 h1:EWU6Pktpas0n8lL github.com/xtaci/lossyconn v0.0.0-20200209145036-adba10fffc37/go.mod h1:HpMP7DB2CyokmAh4lp0EQnnWhmycP/TvwBGzvuie+H0= github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d h1:splanxYIlg+5LfHAM6xpdFEAYOk8iySO56hMFq6uLyA= github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= +gitlab.com/gomidi/midi/v2 v2.0.25 h1:dkzVBqbaFHjyWwP71MrQNX7IeRUIDonddmHbPpO/Ucg= +gitlab.com/gomidi/midi/v2 v2.0.25/go.mod h1:quTyMKSQ4Klevxu6gY4gy2USbeZra0fV5SalndmPfsY= go.mongodb.org/mongo-driver v1.8.3 h1:TDKlTkGDKm9kkJVUOAXDK5/fkqKHJVwYQSpoRfB43R4= go.mongodb.org/mongo-driver v1.8.3/go.mod h1:0sQWfOeY63QTntERDJJ/0SuKK0T1uVSgKCuAROlKEPY= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= diff --git a/gs/game/audio_player.go b/gs/game/audio_player.go new file mode 100644 index 00000000..8584a98d --- /dev/null +++ b/gs/game/audio_player.go @@ -0,0 +1,91 @@ +package game + +import ( + "time" + + "hk4e/pkg/logger" + + "gitlab.com/gomidi/midi/v2" + "gitlab.com/gomidi/midi/v2/smf" +) + +const ( + KeyOffset = -12 * 1 // 八度修正偏移 +) + +var AUDIO_CHAN chan uint32 + +func init() { + AUDIO_CHAN = make(chan uint32, 1000) +} + +func RunPlayAudio() { + audio, err := smf.ReadFile("./in.mid") + if err != nil { + logger.Error("read midi file error: %v", err) + return + } + tempoChangeList := audio.TempoChanges() + if len(tempoChangeList) != 1 { + logger.Error("midi file format not support") + return + } + tempoChange := tempoChangeList[0] + metricTicks := audio.TimeFormat.(smf.MetricTicks) + tickTime := ((60000000.0 / tempoChange.BPM) / float64(metricTicks.Resolution())) / 1000.0 + for { + // 洗脑循环 + logger.Debug("start play audio") + for _, track := range audio.Tracks { + // 全部轨道 + totalTick := uint64(0) + for _, event := range track { + // 单个轨道 + delay := uint32(float64(event.Delta) * tickTime) + busyPoolWaitMilliSecond(delay) + // interruptWaitMilliSecond(delay) + totalTick += uint64(delay) + + msg := event.Message + if msg.Type() != midi.NoteOnMsg { + continue + } + midiMsg := midi.Message(msg) + var channel, key, velocity uint8 + midiMsg.GetNoteOn(&channel, &key, &velocity) + // TODO 测试一下客户端是否支持更宽的音域 + // 60 -> 中央C C4 + // if key < 36 || key > 71 { + // continue + // } + note := int32(key) + int32(KeyOffset) + if note < 21 || note > 108 { + // 非88键钢琴音域 + continue + } + if velocity == 0 { + // 可能是NoteOffMsg + continue + } + + AUDIO_CHAN <- uint32(note) + // logger.Debug("send midi note: %v, delay: %v, totalTick: %v", note, delay, totalTick) + } + } + } +} + +func interruptWaitMilliSecond(delay uint32) { + time.Sleep(time.Millisecond * time.Duration(delay)) +} + +func busyPoolWaitMilliSecond(delay uint32) { + start := time.Now() + end := start.Add(time.Millisecond * time.Duration(delay)) + for { + now := time.Now() + if now.After(end) { + break + } + } +} diff --git a/gs/game/game_manager.go b/gs/game/game_manager.go index 26cf876e..f285e0ba 100644 --- a/gs/game/game_manager.go +++ b/gs/game/game_manager.go @@ -252,14 +252,14 @@ func (g *GameManager) CommonRetSucc(cmdId uint16, player *model.Player, rsp pb.M // SendToWorldA 给世界内所有玩家发消息 func (g *GameManager) SendToWorldA(world *World, cmdId uint16, seq uint32, msg pb.Message) { - for _, v := range world.playerMap { + for _, v := range world.GetAllPlayer() { GAME_MANAGER.SendMsg(cmdId, v.PlayerID, seq, msg) } } // SendToWorldAEC 给世界内除自己以外的所有玩家发消息 func (g *GameManager) SendToWorldAEC(world *World, cmdId uint16, seq uint32, msg pb.Message, uid uint32) { - for _, v := range world.playerMap { + for _, v := range world.GetAllPlayer() { if uid == v.PlayerID { continue } diff --git a/gs/game/tick_manager.go b/gs/game/tick_manager.go index 86a31729..b5fb4ae0 100644 --- a/gs/game/tick_manager.go +++ b/gs/game/tick_manager.go @@ -13,6 +13,11 @@ import ( // 游戏服务器定时帧管理器 +const ( + ServerTickTime = 20 // 服务器全局tick最小间隔毫秒 + UserTickTime = 1000 // 玩家自身tick最小间隔毫秒 +) + type UserTimer struct { timer *time.Timer action int @@ -33,7 +38,7 @@ type TickManager struct { func NewTickManager() (r *TickManager) { r = new(TickManager) - r.globalTick = time.NewTicker(time.Millisecond * 100) + r.globalTick = time.NewTicker(time.Millisecond * ServerTickTime) r.globalTickCount = 0 r.userTickMap = make(map[uint32]*UserTick) logger.Info("game server tick start at: %v", time.Now().UnixMilli()) @@ -45,7 +50,7 @@ func NewTickManager() (r *TickManager) { // CreateUserGlobalTick 创建玩家tick对象 func (t *TickManager) CreateUserGlobalTick(userId uint32) { t.userTickMap[userId] = &UserTick{ - globalTick: time.NewTicker(time.Second * 1), + globalTick: time.NewTicker(time.Millisecond * UserTickTime), globalTickCount: 0, timerIdCounter: 0, timerMap: make(map[uint64]*UserTimer), @@ -74,11 +79,9 @@ func (t *TickManager) CreateUserTimer(userId uint32, action int, delay uint32) { } func (t *TickManager) onUserTickSecond(userId uint32, now int64) { - // logger.Info("on user tick second, uid: %v, time: %v", userId, now) } func (t *TickManager) onUserTickMinute(userId uint32, now int64) { - logger.Info("on user tick minute, uid: %v, time: %v", userId, now) // 每分钟保存玩家数据 saveUserIdList := []uint32{userId} LOCAL_EVENT_MANAGER.localEventChan <- &LocalEvent{ @@ -105,32 +108,34 @@ func (t *TickManager) userTimerHandle(userId uint32, action int) { func (t *TickManager) OnGameServerTick() { t.globalTickCount++ now := time.Now().UnixMilli() - t.onTick100MilliSecond(now) - if t.globalTickCount%2 == 0 { + if t.globalTickCount%(50/ServerTickTime) == 0 { + t.onTick50MilliSecond(now) + } + if t.globalTickCount%(100/ServerTickTime) == 0 { + t.onTick100MilliSecond(now) + } + if t.globalTickCount%(200/ServerTickTime) == 0 { t.onTick200MilliSecond(now) } - if t.globalTickCount%(10*1) == 0 { + if t.globalTickCount%(1000/ServerTickTime) == 0 { t.onTickSecond(now) } - if t.globalTickCount%(10*5) == 0 { + if t.globalTickCount%(5000/ServerTickTime) == 0 { t.onTick5Second(now) } - if t.globalTickCount%(10*10) == 0 { + if t.globalTickCount%(10000/ServerTickTime) == 0 { t.onTick10Second(now) } - if t.globalTickCount%(10*60) == 0 { + if t.globalTickCount%(60000/ServerTickTime) == 0 { t.onTickMinute(now) } - if t.globalTickCount%(10*60*10) == 0 { - t.onTick10Minute(now) - } - if t.globalTickCount%(10*3600) == 0 { + if t.globalTickCount%(60000*60/ServerTickTime) == 0 { t.onTickHour(now) } - if t.globalTickCount%(10*3600*24) == 0 { + if t.globalTickCount%(60000*60*24/ServerTickTime) == 0 { t.onTickDay(now) } - if t.globalTickCount%(10*3600*24*7) == 0 { + if t.globalTickCount%(60000*60*24*7/ServerTickTime) == 0 { t.onTickWeek(now) } for userId, userTick := range t.userTickMap { @@ -138,11 +143,12 @@ func (t *TickManager) OnGameServerTick() { // 跳过还没到时间的定时器 continue } + <-userTick.globalTick.C userTick.globalTickCount++ - if userTick.globalTickCount%(10*1) == 0 { + if userTick.globalTickCount%(1000/UserTickTime) == 0 { t.onUserTickSecond(userId, now) } - if userTick.globalTickCount%(10*60) == 0 { + if userTick.globalTickCount%(60000/UserTickTime) == 0 { t.onUserTickMinute(userId, now) } for timerId, timer := range userTick.timerMap { @@ -150,6 +156,7 @@ func (t *TickManager) OnGameServerTick() { // 跳过还没到时间的定时器 continue } + <-timer.timer.C timer.timer.Stop() delete(userTick.timerMap, timerId) t.userTimerHandle(userId, timer.action) @@ -169,20 +176,10 @@ func (t *TickManager) onTickHour(now int64) { logger.Info("on tick hour, time: %v", now) } -func (t *TickManager) onTick10Minute(now int64) { - for _, world := range WORLD_MANAGER.worldMap { - for _, player := range world.playerMap { - // 蓝球粉球 - GAME_MANAGER.AddUserItem(player.PlayerID, []*UserItem{{ItemId: 223, ChangeCount: 1}}, true, 0) - GAME_MANAGER.AddUserItem(player.PlayerID, []*UserItem{{ItemId: 224, ChangeCount: 1}}, true, 0) - } - } -} - func (t *TickManager) onTickMinute(now int64) { // GAME_MANAGER.ServerAnnounceNotify(100, "test123") - for _, world := range WORLD_MANAGER.worldMap { - for _, player := range world.playerMap { + for _, world := range WORLD_MANAGER.GetAllWorld() { + for _, player := range world.GetAllPlayer() { // 随机物品 allItemDataConfig := GAME_MANAGER.GetAllItemDataConfig() count := random.GetRandomInt32(0, 4) @@ -208,131 +205,133 @@ func (t *TickManager) onTickMinute(now int64) { GAME_MANAGER.AddUserItem(player.PlayerID, []*UserItem{{ItemId: 201, ChangeCount: 10}}, true, 0) GAME_MANAGER.AddUserItem(player.PlayerID, []*UserItem{{ItemId: 202, ChangeCount: 100}}, true, 0) GAME_MANAGER.AddUserItem(player.PlayerID, []*UserItem{{ItemId: 203, ChangeCount: 10}}, true, 0) + // 蓝球粉球 + GAME_MANAGER.AddUserItem(player.PlayerID, []*UserItem{{ItemId: 223, ChangeCount: 1}}, true, 0) + GAME_MANAGER.AddUserItem(player.PlayerID, []*UserItem{{ItemId: 224, ChangeCount: 1}}, true, 0) } } } func (t *TickManager) onTick10Second(now int64) { - for _, world := range WORLD_MANAGER.worldMap { - for _, scene := range world.sceneMap { - for _, player := range scene.playerMap { + for _, world := range WORLD_MANAGER.GetAllWorld() { + for _, scene := range world.GetAllScene() { + for _, player := range scene.GetAllPlayer() { sceneTimeNotify := &proto.SceneTimeNotify{ SceneId: player.SceneId, SceneTime: uint64(scene.GetSceneTime()), } GAME_MANAGER.SendMsg(cmd.SceneTimeNotify, player.PlayerID, 0, sceneTimeNotify) - - playerTimeNotify := &proto.PlayerTimeNotify{ - IsPaused: player.Pause, - PlayerTime: uint64(player.TotalOnlineTime), - ServerTime: uint64(time.Now().UnixMilli()), - } - GAME_MANAGER.SendMsg(cmd.PlayerTimeNotify, player.PlayerID, 0, playerTimeNotify) } } + for _, player := range world.GetAllPlayer() { + playerTimeNotify := &proto.PlayerTimeNotify{ + IsPaused: player.Pause, + PlayerTime: uint64(player.TotalOnlineTime), + ServerTime: uint64(time.Now().UnixMilli()), + } + GAME_MANAGER.SendMsg(cmd.PlayerTimeNotify, player.PlayerID, 0, playerTimeNotify) + } } } func (t *TickManager) onTick5Second(now int64) { - for _, world := range WORLD_MANAGER.worldMap { + for _, world := range WORLD_MANAGER.GetAllWorld() { if world.IsBigWorld() { for applyUid := range world.owner.CoopApplyMap { GAME_MANAGER.UserDealEnterWorld(world.owner, applyUid, true) } } - for _, player := range world.playerMap { - // 多人世界其他玩家的坐标位置广播 - worldPlayerLocationNotify := &proto.WorldPlayerLocationNotify{ - PlayerWorldLocList: make([]*proto.PlayerWorldLocationInfo, 0), + // 多人世界其他玩家的坐标位置广播 + worldPlayerLocationNotify := &proto.WorldPlayerLocationNotify{ + PlayerWorldLocList: make([]*proto.PlayerWorldLocationInfo, 0), + } + for _, worldPlayer := range world.GetAllPlayer() { + playerWorldLocationInfo := &proto.PlayerWorldLocationInfo{ + SceneId: worldPlayer.SceneId, + PlayerLoc: &proto.PlayerLocationInfo{ + Uid: worldPlayer.PlayerID, + Pos: &proto.Vector{ + X: float32(worldPlayer.Pos.X), + Y: float32(worldPlayer.Pos.Y), + Z: float32(worldPlayer.Pos.Z), + }, + Rot: &proto.Vector{ + X: float32(worldPlayer.Rot.X), + Y: float32(worldPlayer.Rot.Y), + Z: float32(worldPlayer.Rot.Z), + }, + }, } - for _, worldPlayer := range world.playerMap { - playerWorldLocationInfo := &proto.PlayerWorldLocationInfo{ - SceneId: worldPlayer.SceneId, - PlayerLoc: &proto.PlayerLocationInfo{ - Uid: worldPlayer.PlayerID, - Pos: &proto.Vector{ - X: float32(worldPlayer.Pos.X), - Y: float32(worldPlayer.Pos.Y), - Z: float32(worldPlayer.Pos.Z), - }, - Rot: &proto.Vector{ - X: float32(worldPlayer.Rot.X), - Y: float32(worldPlayer.Rot.Y), - Z: float32(worldPlayer.Rot.Z), - }, + worldPlayerLocationNotify.PlayerWorldLocList = append(worldPlayerLocationNotify.PlayerWorldLocList, playerWorldLocationInfo) + } + GAME_MANAGER.SendToWorldA(world, cmd.WorldPlayerLocationNotify, 0, worldPlayerLocationNotify) + + for _, scene := range world.GetAllScene() { + scenePlayerLocationNotify := &proto.ScenePlayerLocationNotify{ + SceneId: scene.id, + PlayerLocList: make([]*proto.PlayerLocationInfo, 0), + VehicleLocList: make([]*proto.VehicleLocationInfo, 0), + } + for _, scenePlayer := range scene.GetAllPlayer() { + // 玩家位置 + playerLocationInfo := &proto.PlayerLocationInfo{ + Uid: scenePlayer.PlayerID, + Pos: &proto.Vector{ + X: float32(scenePlayer.Pos.X), + Y: float32(scenePlayer.Pos.Y), + Z: float32(scenePlayer.Pos.Z), + }, + Rot: &proto.Vector{ + X: float32(scenePlayer.Rot.X), + Y: float32(scenePlayer.Rot.Y), + Z: float32(scenePlayer.Rot.Z), }, } - worldPlayerLocationNotify.PlayerWorldLocList = append(worldPlayerLocationNotify.PlayerWorldLocList, playerWorldLocationInfo) - } - GAME_MANAGER.SendMsg(cmd.WorldPlayerLocationNotify, player.PlayerID, 0, worldPlayerLocationNotify) - - for _, scene := range world.sceneMap { - scenePlayerLocationNotify := &proto.ScenePlayerLocationNotify{ - SceneId: scene.id, - PlayerLocList: make([]*proto.PlayerLocationInfo, 0), - VehicleLocList: make([]*proto.VehicleLocationInfo, 0), - } - for _, scenePlayer := range scene.playerMap { - // 玩家位置 - playerLocationInfo := &proto.PlayerLocationInfo{ - Uid: scenePlayer.PlayerID, - Pos: &proto.Vector{ - X: float32(scenePlayer.Pos.X), - Y: float32(scenePlayer.Pos.Y), - Z: float32(scenePlayer.Pos.Z), - }, - Rot: &proto.Vector{ - X: float32(scenePlayer.Rot.X), - Y: float32(scenePlayer.Rot.Y), - Z: float32(scenePlayer.Rot.Z), - }, - } - scenePlayerLocationNotify.PlayerLocList = append(scenePlayerLocationNotify.PlayerLocList, playerLocationInfo) - // 载具位置 - for _, entityId := range scenePlayer.VehicleInfo.LastCreateEntityIdMap { - entity := scene.GetEntity(entityId) - // 确保实体类型是否为载具 - if entity != nil && entity.gadgetEntity != nil && entity.gadgetEntity.gadgetVehicleEntity != nil { - vehicleLocationInfo := &proto.VehicleLocationInfo{ - Rot: &proto.Vector{ - X: float32(entity.rot.X), - Y: float32(entity.rot.Y), - Z: float32(entity.rot.Z), - }, - EntityId: entity.id, - CurHp: entity.fightProp[uint32(constant.FightPropertyConst.FIGHT_PROP_CUR_HP)], - OwnerUid: entity.gadgetEntity.gadgetVehicleEntity.owner.PlayerID, - Pos: &proto.Vector{ - X: float32(entity.pos.X), - Y: float32(entity.pos.Y), - Z: float32(entity.pos.Z), - }, - UidList: make([]uint32, 0, len(entity.gadgetEntity.gadgetVehicleEntity.memberMap)), - GadgetId: entity.gadgetEntity.gadgetVehicleEntity.vehicleId, - MaxHp: entity.fightProp[uint32(constant.FightPropertyConst.FIGHT_PROP_MAX_HP)], - } - for _, p := range entity.gadgetEntity.gadgetVehicleEntity.memberMap { - vehicleLocationInfo.UidList = append(vehicleLocationInfo.UidList, p.PlayerID) - } - scenePlayerLocationNotify.VehicleLocList = append(scenePlayerLocationNotify.VehicleLocList, vehicleLocationInfo) + scenePlayerLocationNotify.PlayerLocList = append(scenePlayerLocationNotify.PlayerLocList, playerLocationInfo) + // 载具位置 + for _, entityId := range scenePlayer.VehicleInfo.LastCreateEntityIdMap { + entity := scene.GetEntity(entityId) + // 确保实体类型是否为载具 + if entity != nil && entity.gadgetEntity != nil && entity.gadgetEntity.gadgetVehicleEntity != nil { + vehicleLocationInfo := &proto.VehicleLocationInfo{ + Rot: &proto.Vector{ + X: float32(entity.rot.X), + Y: float32(entity.rot.Y), + Z: float32(entity.rot.Z), + }, + EntityId: entity.id, + CurHp: entity.fightProp[uint32(constant.FightPropertyConst.FIGHT_PROP_CUR_HP)], + OwnerUid: entity.gadgetEntity.gadgetVehicleEntity.owner.PlayerID, + Pos: &proto.Vector{ + X: float32(entity.pos.X), + Y: float32(entity.pos.Y), + Z: float32(entity.pos.Z), + }, + UidList: make([]uint32, 0, len(entity.gadgetEntity.gadgetVehicleEntity.memberMap)), + GadgetId: entity.gadgetEntity.gadgetVehicleEntity.vehicleId, + MaxHp: entity.fightProp[uint32(constant.FightPropertyConst.FIGHT_PROP_MAX_HP)], } + for _, p := range entity.gadgetEntity.gadgetVehicleEntity.memberMap { + vehicleLocationInfo.UidList = append(vehicleLocationInfo.UidList, p.PlayerID) + } + scenePlayerLocationNotify.VehicleLocList = append(scenePlayerLocationNotify.VehicleLocList, vehicleLocationInfo) } } - GAME_MANAGER.SendMsg(cmd.ScenePlayerLocationNotify, player.PlayerID, 0, scenePlayerLocationNotify) } + GAME_MANAGER.SendToWorldA(world, cmd.ScenePlayerLocationNotify, 0, scenePlayerLocationNotify) } } } func (t *TickManager) onTickSecond(now int64) { - for _, world := range WORLD_MANAGER.worldMap { - for _, player := range world.playerMap { + for _, world := range WORLD_MANAGER.GetAllWorld() { + for _, player := range world.GetAllPlayer() { // 世界里所有玩家的网络延迟广播 worldPlayerRTTNotify := &proto.WorldPlayerRTTNotify{ PlayerRttList: make([]*proto.PlayerRTTInfo, 0), } - for _, worldPlayer := range world.playerMap { + for _, worldPlayer := range world.GetAllPlayer() { playerRTTInfo := &proto.PlayerRTTInfo{Uid: worldPlayer.PlayerID, Rtt: worldPlayer.ClientRTT} worldPlayerRTTNotify.PlayerRttList = append(worldPlayerRTTNotify.PlayerRttList, playerRTTInfo) } @@ -367,9 +366,9 @@ func (t *TickManager) onTickSecond(now int64) { } func (t *TickManager) onTick200MilliSecond(now int64) { - // 耐力消耗 - for _, world := range WORLD_MANAGER.worldMap { - for _, player := range world.playerMap { + for _, world := range WORLD_MANAGER.GetAllWorld() { + for _, player := range world.GetAllPlayer() { + // 耐力消耗 GAME_MANAGER.SustainStaminaHandler(player) GAME_MANAGER.VehicleRestoreStaminaHandler(player) GAME_MANAGER.DrownBackHandler(player) @@ -380,6 +379,20 @@ func (t *TickManager) onTick200MilliSecond(now int64) { func (t *TickManager) onTick100MilliSecond(now int64) { } +func (t *TickManager) onTick50MilliSecond(now int64) { + // 音乐播放器 + for i := 0; i < len(AUDIO_CHAN); i++ { + bigWorld := WORLD_MANAGER.GetBigWorld() + GAME_MANAGER.SendToWorldA(bigWorld, cmd.SceneAudioNotify, 0, &proto.SceneAudioNotify{ + Type: 5, + SourceUid: bigWorld.owner.PlayerID, + Param1: []uint32{1, <-AUDIO_CHAN}, + Param2: nil, + Param3: nil, + }) + } +} + func (t *TickManager) createMonster(scene *Scene) uint32 { pos := &model.Vector{ X: 2747, diff --git a/gs/game/world_manager.go b/gs/game/world_manager.go index 781c61b4..d83ddbc5 100644 --- a/gs/game/world_manager.go +++ b/gs/game/world_manager.go @@ -32,7 +32,7 @@ func (w *WorldManager) GetWorldByID(worldId uint32) *World { return w.worldMap[worldId] } -func (w *WorldManager) GetWorldMap() map[uint32]*World { +func (w *WorldManager) GetAllWorld() map[uint32]*World { return w.worldMap } @@ -90,6 +90,7 @@ func (w *WorldManager) GetBigWorld() *World { func (w *WorldManager) InitBigWorld(owner *model.Player) { w.bigWorld = w.GetWorldByID(owner.WorldId) w.bigWorld.ChangeToMultiplayer() + go RunPlayAudio() } func (w *World) IsBigWorld() bool { @@ -115,6 +116,14 @@ type World struct { peerList []*model.Player // 玩家编号列表 } +func (w *World) GetAllPlayer() map[uint32]*model.Player { + return w.playerMap +} + +func (w *World) GetAllScene() map[uint32]*Scene { + return w.sceneMap +} + func (w *World) GetNextWorldEntityId(entityType uint16) uint32 { for { w.entityIdCounter++ @@ -517,6 +526,14 @@ type Scene struct { meeoIndex uint32 // 客户端风元素染色同步协议的计数器 } +func (s *Scene) GetAllPlayer() map[uint32]*model.Player { + return s.playerMap +} + +func (s *Scene) GetAllEntity() map[uint32]*Entity { + return s.entityMap +} + type AvatarEntity struct { uid uint32 avatarId uint32 diff --git a/protocol/cmd/cmd_id_proto_obj_map.go b/protocol/cmd/cmd_id_proto_obj_map.go index 160c35d0..6220101a 100644 --- a/protocol/cmd/cmd_id_proto_obj_map.go +++ b/protocol/cmd/cmd_id_proto_obj_map.go @@ -107,6 +107,7 @@ func (c *CmdProtoMap) registerAllMessage() { c.registerMessage(ObstacleModifyNotify, &proto.ObstacleModifyNotify{}) // 寻路阻挡变动通知 c.registerMessage(DungeonWayPointNotify, &proto.DungeonWayPointNotify{}) // 地牢副本相关 c.registerMessage(DungeonDataNotify, &proto.DungeonDataNotify{}) // 地牢副本相关 + c.registerMessage(SceneAudioNotify, &proto.SceneAudioNotify{}) // 场景风物之琴音乐同步通知 // 战斗与同步 c.registerMessage(AvatarFightPropNotify, &proto.AvatarFightPropNotify{}) // 角色战斗属性通知