From 5fce82048ff25373d5f2c441b8a37cbb27e263e3 Mon Sep 17 00:00:00 2001 From: xeon Date: Sun, 25 Feb 2024 00:49:57 +0300 Subject: [PATCH] avoid explicit notify send in logic parts, implement callbacks for that --- .../ChatCommands/ChatPlayerCommandHandler.cs | 3 +- .../ChatCommands/ChatSpawnCommandHandler.cs | 9 +- .../Controllers/Combat/CombatManager.cs | 16 +-- GameServer/Controllers/CreatureController.cs | 71 ++++---------- GameServer/Controllers/InventoryController.cs | 37 +------ GameServer/Controllers/RoleController.cs | 23 ++++- GameServer/Controllers/WorldController.cs | 1 - GameServer/Program.cs | 4 +- GameServer/Systems/Entity/EntityBase.cs | 24 ++++- GameServer/Systems/Entity/EntityFactory.cs | 34 ++++++- GameServer/Systems/Entity/EntitySystem.cs | 29 ++++-- GameServer/Systems/Entity/MonsterEntity.cs | 3 +- GameServer/Systems/Entity/PlayerEntity.cs | 3 +- .../Systems/Notify/IGameActionListener.cs | 14 +++ GameServer/Systems/Notify/NotifySystem.cs | 98 +++++++++++++++++++ 15 files changed, 238 insertions(+), 131 deletions(-) create mode 100644 GameServer/Systems/Notify/IGameActionListener.cs create mode 100644 GameServer/Systems/Notify/NotifySystem.cs diff --git a/GameServer/Controllers/ChatCommands/ChatPlayerCommandHandler.cs b/GameServer/Controllers/ChatCommands/ChatPlayerCommandHandler.cs index 261d444..9722bea 100644 --- a/GameServer/Controllers/ChatCommands/ChatPlayerCommandHandler.cs +++ b/GameServer/Controllers/ChatCommands/ChatPlayerCommandHandler.cs @@ -1,5 +1,4 @@ -using Core.Config; -using GameServer.Controllers.Attributes; +using GameServer.Controllers.Attributes; using GameServer.Models; using GameServer.Models.Chat; using GameServer.Network; diff --git a/GameServer/Controllers/ChatCommands/ChatSpawnCommandHandler.cs b/GameServer/Controllers/ChatCommands/ChatSpawnCommandHandler.cs index 789b622..c801c8d 100644 --- a/GameServer/Controllers/ChatCommands/ChatSpawnCommandHandler.cs +++ b/GameServer/Controllers/ChatCommands/ChatSpawnCommandHandler.cs @@ -4,7 +4,6 @@ using GameServer.Models; using GameServer.Models.Chat; using GameServer.Network; using GameServer.Systems.Entity; -using Protocol; namespace GameServer.Controllers.ChatCommands; @@ -50,14 +49,8 @@ internal class ChatSpawnCommandHandler Z = z * 100 }; - _entitySystem.Create(monster); monster.InitProps(_configManager.GetConfig(600000100)!); // TODO: monster property config - - await _session.Push(MessageId.EntityAddNotify, new EntityAddNotify - { - IsAdd = true, - EntityPbs = { monster.Pb } - }); + _entitySystem.Add([monster]); await _creatureController.UpdateAiHate(); diff --git a/GameServer/Controllers/Combat/CombatManager.cs b/GameServer/Controllers/Combat/CombatManager.cs index 80ee432..b181a7e 100644 --- a/GameServer/Controllers/Combat/CombatManager.cs +++ b/GameServer/Controllers/Combat/CombatManager.cs @@ -82,7 +82,7 @@ internal class CombatManager } [CombatRequest(CombatRequestData.MessageOneofCase.DamageExecuteRequest)] - public async Task OnDamageExecuteRequest(CombatRequestContext context) + public CombatResponseData OnDamageExecuteRequest(CombatRequestContext context) { DamageExecuteRequest request = context.Request.DamageExecuteRequest; @@ -105,19 +105,7 @@ internal class CombatManager if (request.DamageId <= 0 && entity.Type != EEntityType.Player) // Player death not implemented { - _entitySystem.Destroy(entity); - await _session.Push(MessageId.EntityRemoveNotify, new EntityRemoveNotify - { - IsRemove = true, - RemoveInfos = - { - new EntityRemoveInfo - { - EntityId = entity.Id, - Type = (int)ERemoveEntityType.RemoveTypeNormal - } - } - }); + _entitySystem.Destroy([entity]); } return new CombatResponseData diff --git a/GameServer/Controllers/CreatureController.cs b/GameServer/Controllers/CreatureController.cs index 5af5a54..7882636 100644 --- a/GameServer/Controllers/CreatureController.cs +++ b/GameServer/Controllers/CreatureController.cs @@ -1,3 +1,4 @@ +using System.Security.Principal; using Core.Config; using GameServer.Controllers.Attributes; using GameServer.Extensions.Logic; @@ -8,6 +9,7 @@ using GameServer.Settings; using GameServer.Systems.Entity; using GameServer.Systems.Entity.Component; using GameServer.Systems.Event; +using GameServer.Systems.Notify; using Microsoft.Extensions.Options; using Protocol; @@ -18,15 +20,17 @@ internal class CreatureController : Controller private readonly EntityFactory _entityFactory; private readonly ModelManager _modelManager; private readonly ConfigManager _configManager; + private readonly IGameActionListener _listener; private readonly GameplayFeatureSettings _gameplayFeatures; - public CreatureController(PlayerSession session, EntitySystem entitySystem, EntityFactory entityFactory, ModelManager modelManager, ConfigManager configManager, IOptions gameplayFeatures) : base(session) + public CreatureController(PlayerSession session, EntitySystem entitySystem, EntityFactory entityFactory, ModelManager modelManager, ConfigManager configManager, IOptions gameplayFeatures, IGameActionListener listener) : base(session) { _entitySystem = entitySystem; _entityFactory = entityFactory; _modelManager = modelManager; _configManager = configManager; + _listener = listener; _gameplayFeatures = gameplayFeatures.Value; } @@ -36,15 +40,7 @@ internal class CreatureController : Controller CreateTeamPlayerEntities(); CreateWorldEntities(); - await Session.Push(MessageId.JoinSceneNotify, new JoinSceneNotify - { - MaxEntityId = 10000000, - TransitionOption = new TransitionOptionPb - { - TransitionType = (int)TransitionType.Empty - }, - SceneInfo = CreateSceneInfo() - }); + await _listener.OnJoinedScene(CreateSceneInfo(), TransitionType.Empty); } [NetEvent(MessageId.EntityActiveRequest)] @@ -85,47 +81,11 @@ internal class CreatureController : Controller [GameEvent(GameEventType.FormationUpdated)] public async Task OnFormationUpdated() { - // Remove old entities - - IEnumerable oldEntities = GetPlayerEntities().ToArray(); - foreach (PlayerEntity oldEntity in oldEntities) - { - _entitySystem.Destroy(oldEntity); - } - - await Session.Push(MessageId.EntityRemoveNotify, new EntityRemoveNotify - { - IsRemove = true, - RemoveInfos = - { - oldEntities.Select(entity => new EntityRemoveInfo - { - EntityId = entity.Id, - Type = (int)entity.Type - }) - } - }); - - // Spawn new entities - + _entitySystem.Destroy(GetPlayerEntities().ToArray()); CreateTeamPlayerEntities(); - IEnumerable newEntities = GetPlayerEntities(); - await Session.Push(MessageId.EntityAddNotify, new EntityAddNotify - { - IsAdd = true, - EntityPbs = - { - newEntities.Select(entity => entity.Pb) - } - }); - - _modelManager.Creature.PlayerEntityId = newEntities.First().Id; - await Session.Push(MessageId.UpdatePlayerAllFightRoleNotify, new UpdatePlayerAllFightRoleNotify - { - PlayerId = _modelManager.Player.Id, - FightRoleInfos = { GetFightRoleInfos() } - }); + _modelManager.Creature.PlayerEntityId = GetPlayerEntities().First().Id; + await _listener.OnPlayerFightRoleInfoUpdated(_modelManager.Player.Id, GetFightRoleInfos()); await UpdateAiHate(); } @@ -256,6 +216,8 @@ internal class CreatureController : Controller private void CreateTeamPlayerEntities() { + PlayerEntity[] playerEntities = new PlayerEntity[_modelManager.Formation.RoleIds.Length]; + for (int i = 0; i < _modelManager.Formation.RoleIds.Length; i++) { int roleId = _modelManager.Formation.RoleIds[i]; @@ -263,8 +225,7 @@ internal class CreatureController : Controller PlayerEntity entity = _entityFactory.CreatePlayer(roleId, _modelManager.Player.Id); entity.Pos = _modelManager.Player.Position.Clone(); entity.IsCurrentRole = i == 0; - - _entitySystem.Create(entity); + entity.ComponentSystem.Get().SetAll(_modelManager.Roles.GetRoleById(roleId)!.GetAttributeList()); CreateConcomitants(entity); @@ -281,7 +242,11 @@ internal class CreatureController : Controller attr.SetAttribute(EAttributeType.SpecialEnergy3Max, 0); attr.SetAttribute(EAttributeType.SpecialEnergy4Max, 0); } + + playerEntities[i] = entity; } + + _entitySystem.Add(playerEntities); } private void CreateConcomitants(PlayerEntity entity) @@ -295,7 +260,6 @@ internal class CreatureController : Controller if (roleId != -1) { PlayerEntity concomitant = _entityFactory.CreatePlayer(roleId, 0); - _entitySystem.Create(concomitant); EntityConcomitantsComponent concomitants = entity.ComponentSystem.Create(); concomitants.CustomEntityIds.Clear(); @@ -309,6 +273,7 @@ internal class CreatureController : Controller summoner.PlayerId = _modelManager.Player.Id; concomitant.InitProps(_configManager.GetConfig(roleId)!); + _entitySystem.Add([concomitant]); } } @@ -325,7 +290,7 @@ internal class CreatureController : Controller Z = playerPos.Z }; - _entitySystem.Create(monster); + _entitySystem.Add([monster]); monster.InitProps(_configManager.GetConfig(600000100)!); } } diff --git a/GameServer/Controllers/InventoryController.cs b/GameServer/Controllers/InventoryController.cs index b575b7d..876879b 100644 --- a/GameServer/Controllers/InventoryController.cs +++ b/GameServer/Controllers/InventoryController.cs @@ -38,7 +38,7 @@ internal class InventoryController : Controller public RpcResult OnItemExchangeInfoRequest() => Response(MessageId.ItemExchangeInfoResponse, new ItemExchangeInfoResponse()); [NetEvent(MessageId.EquipTakeOnRequest)] - public async Task OnEquipTakeOnRequest(EquipTakeOnRequest request, ModelManager modelManager, CreatureController creatureController, ConfigManager configManager) + public RpcResult OnEquipTakeOnRequest(EquipTakeOnRequest request, ModelManager modelManager, CreatureController creatureController, RoleController roleController, ConfigManager configManager) { WeaponItem? weapon = modelManager.Inventory.GetWeaponById(request.Data.EquipIncId); if (weapon == null) return Response(MessageId.EquipTakeOnResponse, new EquipTakeOnResponse @@ -60,39 +60,12 @@ internal class InventoryController : Controller // Set new weapon weapon.RoleId = role.RoleId; - role.ApplyWeaponProperties(weaponConf); - - // Update role prop data on client - await Session.Push(MessageId.PbRolePropsNotify, new PbRolePropsNotify - { - RoleId = role.RoleId, - BaseProp = { role.BaseProp }, - AddProp = { role.AddProp } - }); + roleController.ApplyWeaponPropertiesToRole(role.RoleId, weaponConf); + // Update entity (if this role is currently active) PlayerEntity? entity = creatureController.GetPlayerEntityByRoleId(request.Data.RoleId); - if (entity != null) - { - // Update entity equipment - EntityEquipComponent equipComponent = entity.ComponentSystem.Get(); - equipComponent.WeaponId = weapon.Id; - - await Session.Push(MessageId.EntityEquipChangeNotify, new EntityEquipChangeNotify - { - EntityId = entity.Id, - EquipComponent = equipComponent.Pb.EquipComponent - }); - - // Update entity gameplay attributes - EntityAttributeComponent attrComponent = entity.ComponentSystem.Get(); - attrComponent.SetAll(role.GetAttributeList()); - - await Session.Push(MessageId.AttributeChangedNotify, new AttributeChangedNotify - { - Id = entity.Id, - Attributes = { attrComponent.Pb.AttributeComponent.GameAttributes } - }); - } + entity?.ChangeEquipment(weapon.Id); + entity?.ChangeGameplayAttributes(role.GetAttributeList()); // Response EquipTakeOnResponse response = new() diff --git a/GameServer/Controllers/RoleController.cs b/GameServer/Controllers/RoleController.cs index 81fcf6c..487610e 100644 --- a/GameServer/Controllers/RoleController.cs +++ b/GameServer/Controllers/RoleController.cs @@ -4,25 +4,38 @@ using GameServer.Extensions.Logic; using GameServer.Models; using GameServer.Network; using GameServer.Systems.Event; +using GameServer.Systems.Notify; using Protocol; namespace GameServer.Controllers; internal class RoleController : Controller { - public RoleController(PlayerSession session) : base(session) + private readonly ModelManager _modelManager; + private readonly IGameActionListener _listener; + + public RoleController(PlayerSession session, ModelManager modelManager, IGameActionListener listener) : base(session) { - // RoleController. + _modelManager = modelManager; + _listener = listener; + } + + public void ApplyWeaponPropertiesToRole(int roleId, WeaponConfig weaponConfiguration) + { + roleInfo? role = _modelManager.Roles.GetRoleById(roleId) ?? throw new ArgumentException($"Role with id {roleId} doesn't exist"); + + role.ApplyWeaponProperties(weaponConfiguration); + _ = _listener.OnRolePropertiesUpdated(roleId, role.BaseProp, role.AddProp); } [GameEvent(GameEventType.DebugUnlockAllRoles)] - public void UnlockAllRoles(ConfigManager configManager, ModelManager modelManager) + public void UnlockAllRoles(ConfigManager configManager) { foreach (RoleInfoConfig roleConfig in configManager.Enumerate()) { - roleInfo role = modelManager.Roles.Create(roleConfig.Id); + roleInfo role = _modelManager.Roles.Create(roleConfig.Id); role.BaseProp.AddRange(CreateBasePropList(configManager.GetConfig(roleConfig.Id))); - WeaponItem weapon = modelManager.Inventory.AddNewWeapon(roleConfig.InitWeaponItemId); + WeaponItem weapon = _modelManager.Inventory.AddNewWeapon(roleConfig.InitWeaponItemId); weapon.RoleId = role.RoleId; role.ApplyWeaponProperties(configManager.GetConfig(weapon.Id)!); diff --git a/GameServer/Controllers/WorldController.cs b/GameServer/Controllers/WorldController.cs index bfe1335..3b43b92 100644 --- a/GameServer/Controllers/WorldController.cs +++ b/GameServer/Controllers/WorldController.cs @@ -1,6 +1,5 @@ using GameServer.Controllers.Attributes; using GameServer.Network; -using GameServer.Network.Messages; using GameServer.Systems.Event; using Protocol; diff --git a/GameServer/Program.cs b/GameServer/Program.cs index 92093df..3347516 100644 --- a/GameServer/Program.cs +++ b/GameServer/Program.cs @@ -13,6 +13,7 @@ using GameServer.Network.Rpc; using GameServer.Settings; using GameServer.Systems.Entity; using GameServer.Systems.Event; +using GameServer.Systems.Notify; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; @@ -39,7 +40,8 @@ internal static class Program .AddScoped().AddSingleton() .AddScoped().AddScoped() .AddSingleton() - .AddScoped().AddScoped().AddScoped() + .AddScoped().AddScoped().AddScoped() + .AddScoped() .AddScoped().AddScoped() .AddScoped().AddScoped() .AddHostedService(); diff --git a/GameServer/Systems/Entity/EntityBase.cs b/GameServer/Systems/Entity/EntityBase.cs index 53a69c9..977986c 100644 --- a/GameServer/Systems/Entity/EntityBase.cs +++ b/GameServer/Systems/Entity/EntityBase.cs @@ -1,5 +1,6 @@ using Core.Config; using GameServer.Systems.Entity.Component; +using GameServer.Systems.Notify; using Protocol; namespace GameServer.Systems.Entity; @@ -17,7 +18,9 @@ internal abstract class EntityBase public bool IsConcomitant => ComponentSystem.TryGet(out _); - public EntityBase(long id) + protected IGameActionListener ActionListener { get; } + + public EntityBase(long id, IGameActionListener listener) { Id = id; @@ -25,6 +28,7 @@ internal abstract class EntityBase Rot = new Rotator(); ComponentSystem = new EntityComponentSystem(); + ActionListener = listener; } public virtual void OnCreate() @@ -40,6 +44,24 @@ internal abstract class EntityBase // Activate. } + public void ChangeEquipment(int weaponId) + { + if (ComponentSystem.TryGet(out EntityEquipComponent? equipComponent)) + { + equipComponent.WeaponId = weaponId; + _ = ActionListener.OnEntityEquipmentChanged(Id, equipComponent.Pb.EquipComponent); + } + } + + public void ChangeGameplayAttributes(IEnumerable attributes) + { + if (ComponentSystem.TryGet(out EntityAttributeComponent? attrComponent)) + { + attrComponent.SetAll(attributes); + _ = ActionListener.OnEntityAttributesChanged(Id, attrComponent.Pb.AttributeComponent.GameAttributes); + } + } + public virtual LivingStatus LivingStatus => LivingStatus.Alive; public virtual bool IsVisible => true; diff --git a/GameServer/Systems/Entity/EntityFactory.cs b/GameServer/Systems/Entity/EntityFactory.cs index 11919f8..27e20ba 100644 --- a/GameServer/Systems/Entity/EntityFactory.cs +++ b/GameServer/Systems/Entity/EntityFactory.cs @@ -1,12 +1,40 @@ -namespace GameServer.Systems.Entity; +using Microsoft.Extensions.DependencyInjection; + +namespace GameServer.Systems.Entity; internal class EntityFactory { + private static readonly ObjectFactory s_createPlayerEntity; + private static readonly ObjectFactory s_createMonsterEntity; + private long _entityIdCounter; + private readonly IServiceProvider _serviceProvider; + + static EntityFactory() + { + s_createPlayerEntity = ActivatorUtilities.CreateFactory([typeof(long), typeof(int), typeof(int)]); + s_createMonsterEntity = ActivatorUtilities.CreateFactory([typeof(long), typeof(int)]); + } + + public EntityFactory(IServiceProvider serviceProvider) + { + _serviceProvider = serviceProvider; + } public PlayerEntity CreatePlayer(int characterConfigId, int playerId) - => new(NextId(), characterConfigId, playerId); + { + PlayerEntity entity = s_createPlayerEntity(_serviceProvider, [NextId(), characterConfigId, playerId]); + entity.OnCreate(); - public MonsterEntity CreateMonster(int levelEntityId) => new(NextId(), levelEntityId); + return entity; + } + + public MonsterEntity CreateMonster(int levelEntityId) + { + MonsterEntity monsterEntity = s_createMonsterEntity(_serviceProvider, [NextId(), levelEntityId]); + monsterEntity.OnCreate(); + + return monsterEntity; + } private long NextId() => Interlocked.Increment(ref _entityIdCounter); } diff --git a/GameServer/Systems/Entity/EntitySystem.cs b/GameServer/Systems/Entity/EntitySystem.cs index 9bc8555..0dc6a18 100644 --- a/GameServer/Systems/Entity/EntitySystem.cs +++ b/GameServer/Systems/Entity/EntitySystem.cs @@ -1,13 +1,17 @@ -using Protocol; +using GameServer.Systems.Event; +using GameServer.Systems.Notify; +using Protocol; namespace GameServer.Systems.Entity; internal class EntitySystem { private readonly List _entities; + private readonly IGameActionListener _listener; - public EntitySystem() + public EntitySystem(IGameActionListener listener) { _entities = []; + _listener = listener; } public IEnumerable EnumerateEntities() @@ -15,18 +19,25 @@ internal class EntitySystem return _entities; } - public void Create(EntityBase entity) + public void Add(IEnumerable entities) { - if (_entities.Any(e => e.Id == entity.Id)) - throw new InvalidOperationException($"EntitySystem::Create - entity with id {entity.Id} already exists"); + foreach (EntityBase entity in entities) + { + if (_entities.Any(e => e.Id == entity.Id)) + throw new InvalidOperationException($"EntitySystem::Create - entity with id {entity.Id} already exists"); - entity.OnCreate(); - _entities.Add(entity); + _entities.Add(entity); + } + + _ = _listener.OnEntitiesAdded(entities); } - public void Destroy(EntityBase entity) + public void Destroy(IEnumerable entities) { - _ = _entities.Remove(entity); + foreach (EntityBase entity in entities) + _ = _entities.Remove(entity); + + _ = _listener.OnEntitiesRemoved(entities); } public void Activate(EntityBase entity) diff --git a/GameServer/Systems/Entity/MonsterEntity.cs b/GameServer/Systems/Entity/MonsterEntity.cs index d298df0..bb3d3c3 100644 --- a/GameServer/Systems/Entity/MonsterEntity.cs +++ b/GameServer/Systems/Entity/MonsterEntity.cs @@ -1,10 +1,11 @@ using GameServer.Systems.Entity.Component; +using GameServer.Systems.Notify; using Protocol; namespace GameServer.Systems.Entity; internal class MonsterEntity : EntityBase { - public MonsterEntity(long id, int configId) : base(id) + public MonsterEntity(long id, int configId, IGameActionListener listener) : base(id, listener) { ConfigId = configId; } diff --git a/GameServer/Systems/Entity/PlayerEntity.cs b/GameServer/Systems/Entity/PlayerEntity.cs index 6da3dd6..3e2ab2a 100644 --- a/GameServer/Systems/Entity/PlayerEntity.cs +++ b/GameServer/Systems/Entity/PlayerEntity.cs @@ -1,10 +1,11 @@ using GameServer.Systems.Entity.Component; +using GameServer.Systems.Notify; using Protocol; namespace GameServer.Systems.Entity; internal class PlayerEntity : EntityBase { - public PlayerEntity(long id, int configId, int playerId) : base(id) + public PlayerEntity(long id, int configId, int playerId, IGameActionListener listener) : base(id, listener) { ConfigId = configId; PlayerId = playerId; diff --git a/GameServer/Systems/Notify/IGameActionListener.cs b/GameServer/Systems/Notify/IGameActionListener.cs new file mode 100644 index 0000000..7e11f8e --- /dev/null +++ b/GameServer/Systems/Notify/IGameActionListener.cs @@ -0,0 +1,14 @@ +using GameServer.Systems.Entity; +using Protocol; + +namespace GameServer.Systems.Notify; +internal interface IGameActionListener +{ + Task OnJoinedScene(SceneInformation sceneInformation, TransitionType transitionType); + Task OnEntitiesAdded(IEnumerable entities); + Task OnEntitiesRemoved(IEnumerable entities); + Task OnPlayerFightRoleInfoUpdated(int playerId, IEnumerable fightRoles); + Task OnRolePropertiesUpdated(int roleId, IEnumerable baseProp, IEnumerable addProp); + Task OnEntityEquipmentChanged(long entityId, EquipComponentPb componentPb); + Task OnEntityAttributesChanged(long entityId, IEnumerable attributes); +} diff --git a/GameServer/Systems/Notify/NotifySystem.cs b/GameServer/Systems/Notify/NotifySystem.cs new file mode 100644 index 0000000..bc1cd2e --- /dev/null +++ b/GameServer/Systems/Notify/NotifySystem.cs @@ -0,0 +1,98 @@ +using System.Data; +using GameServer.Models; +using GameServer.Network; +using GameServer.Systems.Entity; +using Protocol; + +namespace GameServer.Systems.Notify; +internal class NotifySystem : IGameActionListener +{ + private readonly PlayerSession _session; + private readonly ModelManager _modelManager; + + public NotifySystem(PlayerSession session, ModelManager modelManager) + { + _session = session; + _modelManager = modelManager; + } + + public Task OnJoinedScene(SceneInformation sceneInformation, TransitionType transitionType) + { + return _session.Push(MessageId.JoinSceneNotify, new JoinSceneNotify + { + SceneInfo = sceneInformation, + TransitionOption = new TransitionOptionPb + { + TransitionType = (int)transitionType + } + }); + } + + public Task OnEntitiesAdded(IEnumerable entities) + { + if (_modelManager.Creature.LoadingWorld) return Task.CompletedTask; + + return _session.Push(MessageId.EntityAddNotify, new EntityAddNotify + { + IsAdd = true, + EntityPbs = { entities.Select(e => e.Pb) } + }); + } + + public Task OnEntitiesRemoved(IEnumerable entities) + { + if (_modelManager.Creature.LoadingWorld) return Task.CompletedTask; + + return _session.Push(MessageId.EntityRemoveNotify, new EntityRemoveNotify + { + IsRemove = true, + RemoveInfos = + { + entities.Select(e => new EntityRemoveInfo + { + EntityId = e.Id, + Type = (int)ERemoveEntityType.RemoveTypeNormal + }) + } + }); + } + + public Task OnPlayerFightRoleInfoUpdated(int playerId, IEnumerable fightRoles) + { + return _session.Push(MessageId.UpdatePlayerAllFightRoleNotify, new UpdatePlayerAllFightRoleNotify + { + PlayerId = playerId, + FightRoleInfos = { fightRoles } + }); + } + + public Task OnRolePropertiesUpdated(int roleId, IEnumerable baseProp, IEnumerable addProp) + { + if (_modelManager.Creature.LoadingWorld) return Task.CompletedTask; + + return _session.Push(MessageId.PbRolePropsNotify, new PbRolePropsNotify + { + RoleId = roleId, + BaseProp = { baseProp }, + AddProp = { addProp } + }); + } + + public Task OnEntityEquipmentChanged(long entityId, EquipComponentPb componentPb) + { + return _session.Push(MessageId.EntityEquipChangeNotify, new EntityEquipChangeNotify + { + EntityId = entityId, + EquipComponent = componentPb + }); + } + + public Task OnEntityAttributesChanged(long entityId, IEnumerable attributes) + { + return _session.Push(MessageId.AttributeChangedNotify, new AttributeChangedNotify + { + Id = entityId, + Attributes = { attributes } + }); + } +}