/// <inheritdoc /> public async Task <string> RetrieveAsync(NetworkEntityGuid entity) { using (await SyncObj.ReaderLockAsync()) { if (LocalNameMap.ContainsKey(entity)) { return(LocalNameMap[entity]); //do not call Retrieve, old versions of Unity3D don't support recursive readwrite locking. } } //If we're here, it wasn't contained var result = await QueryRemoteNameService(entity); if (!result.isSuccessful) { throw new InvalidOperationException($"Failed to query name for Entity: {entity}. Result: {result.ResultCode}."); } //Add it using (await SyncObj.WriterLockAsync()) { //Check if some other thing already initialized it if (LocalNameMap.ContainsKey(entity)) { return(LocalNameMap[entity]); //do not call Retrieve, old versions of Unity3D don't support recursive readwrite locking. } return(LocalNameMap[entity] = result.isSuccessful ? result.Result.EntityName : "Unknown"); } }
private void InterestTriggerEnter([NotNull] object sender, [NotNull] PhysicsTriggerEventArgs args) { if (sender == null) { throw new ArgumentNullException(nameof(sender)); } if (args == null) { throw new ArgumentNullException(nameof(args)); } GameObject rootObject = args.ColliderThatTriggered.GetRootGameObject(); //TODO: This WON'T work if you parent the object. We NEED a better way to handle looking up the guid from collision //TODO: Should entites be interested in themselves? //Right now the way this is set up we don't check if this is the entity itself. //Which means an entity is always interested in itself, unless manually removed //because when it enters the world it will enter its own interest radius //This behavior MAY change. NetworkEntityGuid me = ObjectToEntityMapper.ObjectToEntityMap[args.GameObjectTriggered.transform.GetRootGameObject()]; if (!ObjectToEntityMapper.ObjectToEntityMap.ContainsKey(rootObject)) { if (Logger.IsWarnEnabled) { Logger.Warn($"Tried to enter Entity: {rootObject.name} to Entity interest ID: {me} but does not exist. Is not owned."); } return; } OnEntityInterestChanged?.Invoke(this, new EntityInterestChangeEventArgs(me, ObjectToEntityMapper.ObjectToEntityMap[rootObject], EntityInterestChangeEventArgs.ChangeType.Enter)); }
public bool Exists(NetworkEntityGuid entity) { using (SyncObj.ReaderLock()) { return(LocalNameMap.ContainsKey(entity)); } }
private void InterestTriggerExit([NotNull] object sender, [NotNull] PhysicsTriggerEventArgs args) { if (sender == null) { throw new ArgumentNullException(nameof(sender)); } if (args == null) { throw new ArgumentNullException(nameof(args)); } GameObject rootObject = args.ColliderThatTriggered.GetRootGameObject(); NetworkEntityGuid me = ObjectToEntityMapper.ObjectToEntityMap[args.GameObjectTriggered.transform.GetRootGameObject()]; if (!ObjectToEntityMapper.ObjectToEntityMap.ContainsKey(rootObject)) { if (Logger.IsWarnEnabled) { Logger.Warn($"Tried to remove Entity: {rootObject.name} from Entity interest ID: {me} but does not exist. Is not owned."); } return; } OnEntityInterestChanged?.Invoke(this, new EntityInterestChangeEventArgs(me, ObjectToEntityMapper.ObjectToEntityMap[rootObject], EntityInterestChangeEventArgs.ChangeType.Exit)); }
protected override void OnGuildStatusChanged(GuildStatusChangedEventModel changeArgs) { //Don't need to get the guild list if we're guildless. if (changeArgs.IsGuildless) { return; } UnityAsyncHelper.UnityMainThreadContext.PostAsync(async() => { var rosterResponseModel = await SocialService.GetGuildListAsync(); if (!rosterResponseModel.isSuccessful) { if (Logger.IsWarnEnabled) { Logger.Warn($"Failed to query guild roster. Reason: {rosterResponseModel.ResultCode}"); } return; } //Now we can publish the roster. foreach (int rosterCharacterId in rosterResponseModel.Result.GuildedCharacterIds) { NetworkEntityGuid characterGuid = NetworkEntityGuidBuilder.New() .WithType(EntityType.Player) .WithId(rosterCharacterId) .Build(); //This is a hidden join, or the alerts would be spammed. GuildJoinEventPublisher.PublishEvent(this, new CharacterJoinedGuildEventArgs(characterGuid, true)); } }); }
private void OnPlayerTargetEntityDatChanged(NetworkEntityGuid entity, EntityDataChangedArgs <ulong> changeArgs) { NetworkEntityGuid guid = new NetworkEntityGuid(changeArgs.NewValue); if (Logger.IsDebugEnabled) { Logger.Debug($"Player Target Changed to: {guid}"); } CurrentTarget = guid; if (guid == NetworkEntityGuid.Empty) { //target was cleared. if (Logger.IsDebugEnabled) { Logger.Debug($"Player cleared target."); } //TODO: We should register listener events to increase UI performance for untargeted callbacks } else { OnPlayerTargetChanged?.Invoke(this, new LocalPlayerTargetChangedEventArgs(guid)); //We can at least set this active here I guess. TargetUnitFrame.SetElementActive(true); } }
public CustomModelLoaderCreationContext(long contentId, [NotNull] NetworkEntityGuid entityGuid) { if (contentId <= 0) { throw new ArgumentOutOfRangeException(nameof(contentId)); } ContentId = contentId; EntityGuid = entityGuid ?? throw new ArgumentNullException(nameof(entityGuid)); switch (EntityGuid.EntityType) { case EntityType.Player: ContentType = UserContentType.Avatar; break; case EntityType.GameObject: ContentType = UserContentType.GameObject; break; case EntityType.Creature: ContentType = UserContentType.Creature; break; default: throw new ArgumentOutOfRangeException(); } }
protected override EntityPrefab ComputePrefabType(NetworkEntityGuid entityGuid) { switch (entityGuid.EntityType) { case EntityType.Player: //It could be remote player or local player. if (entityGuid.EntityId == CharacterDataRepository.CharacterId) { return(EntityPrefab.LocalPlayer); } else { return(EntityPrefab.RemotePlayer); } case EntityType.Creature: return(EntityPrefab.NetworkNpc); case EntityType.GameObject: return(EntityPrefab.NetworkGameObject); } //TODO: Handle other cases. throw new NotSupportedException($"TODO: Implement support for: {entityGuid} creation."); }
public async Task <IActionResult> EntityNameQuery([FromRoute(Name = "id")] ulong id) { //Since this is a GET we can't send a JSON model. We have to use this process instead, sending the raw guid value. NetworkEntityGuid entityGuid = new NetworkEntityGuid(id); return(await EntityNameQuery(entityGuid)); }
protected override bool ValidateTargeting(SpellDefinitionDataModel spellDefinition, SpellEffectDefinitionDataModel spellEffect, DefaultEntityActorStateContainer actorState) { if (spellDefinition == null) { throw new ArgumentNullException(nameof(spellDefinition)); } if (spellEffect == null) { throw new ArgumentNullException(nameof(spellEffect)); } if (actorState == null) { throw new ArgumentNullException(nameof(actorState)); } NetworkEntityGuid guid = GetEntityTarget(actorState); //Does the entity exist, small window of time between valid cast start and now where entity can despawn //so minor chance it doesn't exist anymore. if (!KnownEntitySet.isEntityKnown(guid)) { return(false); } //TODO: We shouldn't assume they are enemies just because they aren't use. We need a system for hostility masking for entities return(guid != NetworkEntityGuid.Empty && guid.EntityType == EntityType.Creature && guid != actorState.EntityGuid); }
private void OnChatMessageRecieved(ChatChannelType channelType, [NotNull] IChannelTextMessage args) { if (args == null) { throw new ArgumentNullException(nameof(args)); } if (!Enum.IsDefined(typeof(ChatChannelType), channelType)) { throw new InvalidEnumArgumentException(nameof(channelType), (int)channelType, typeof(ChatChannelType)); } AccountId id = args.Sender; int characterId = int.Parse(id.Name); //TODO: We need to translate the guid to a name. NetworkEntityGuid guid = NetworkEntityGuidBuilder.New() .WithType(EntityType.Player) .WithId(characterId) .Build(); if (NameQueryService.Exists(guid)) { PublishTextData(channelType, args, guid, NameQueryService.Retrieve(guid)); } else { UnityAsyncHelper.UnityMainThreadContext.PostAsync(async() => { string queryResponse = await NameQueryService.RetrieveAsync(guid) .ConfigureAwaitFalse(); PublishTextData(channelType, args, guid, queryResponse); }); } }
/// <inheritdoc /> public GroupUnitFrameIssueResult TryClaimUnitFrame(NetworkEntityGuid guid) { if (guid.EntityType != EntityType.Player) { return(GroupUnitFrameIssueResult.FailedNotAPlayer); } lock (SyncObj) { if (OwnedGroupUnitFrames.ContainsKey(guid)) { return(GroupUnitFrameIssueResult.FailedAlreadyClaimedUnitframe); } if (!AvailableUnitFrames.Any()) { return(GroupUnitFrameIssueResult.FailedUnitframeUnavailable); } //Otherwise, at this point we're in a proper state to associate a unitframe OwnedGroupUnitFrames.Add(guid, new ClaimedGroupUnitFrame(AvailableUnitFrames.Pop())); } return(GroupUnitFrameIssueResult.Success); }
private async Task <bool> CheckIfGuilded(NetworkEntityGuid guid) { var guildStatus = await SocialService.GetCharacterMembershipGuildStatus(guid.EntityId); //If the query was successful then they ARE in a guild. return(guildStatus.ResultCode == CharacterGuildMembershipStatusResponseCode.Success); }
private async Task <HubOnConnectionState> TryRequestCharacterGuildStatus(NetworkEntityGuid guid, string userIdentifier) { ResponseModel <CharacterGuildMembershipStatusResponse, CharacterGuildMembershipStatusResponseCode> response = null; try { response = await SocialService.GetCharacterMembershipGuildStatus(int.Parse(userIdentifier)) .ConfigureAwaitFalse(); } catch (Exception e) { if (Logger.IsEnabled(LogLevel.Error)) { Logger.LogError($"Failed to get guild status of Connection: {userIdentifier}. Exception: {e.Message}\n\nStack:{e.StackTrace}"); } return(HubOnConnectionState.Abort); } //Don't ADD, we have to assume that we might have an entity, maybe web or mobile, already connected //and merely just update the guild status if (response.isSuccessful) { GuildStatusMappable.Add(guid, response.Result); } return(HubOnConnectionState.Success); }
protected override EntityPrefab ComputePrefabType([NotNull] NetworkEntityGuid entityGuid) { if (entityGuid == null) { throw new ArgumentNullException(nameof(entityGuid)); } switch (entityGuid.EntityType) { case EntityType.None: break; case EntityType.Player: return(EntityPrefab.RemotePlayer); case EntityType.GameObject: return(EntityPrefab.NetworkGameObject); break; case EntityType.Creature: return(EntityPrefab.NetworkNpc); default: throw new ArgumentOutOfRangeException(); } throw new InvalidOperationException($"Failed to compute {nameof(EntityPrefab)} from Guid: {entityGuid}"); }
private void ThrowIfNoEntityInterestManaged(NetworkEntityGuid entryContext, NetworkEntityGuid entityGuid) { if (!ManagedInterestCollections.ContainsKey(entryContext)) { throw new InvalidOperationException($"Guid: {entityGuid} tried to enter Entity: {entryContext} interest. But Entity does not maintain interest. Does not exist in interest collection."); } }
public BaseEntityBehaviourComponent Create([NotNull] NetworkEntityGuid context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } IEntityDataFieldContainer dataFieldContainer = EntityDataMappable.RetrieveEntity(context); GameObject worldObject = WorldObjectMappable.RetrieveEntity(context); Type behaviourType = ComputeExpectedBehaviourType(dataFieldContainer.GetEnumFieldValue <GameObjectType>(GameObjectField.GAMEOBJECT_TYPE_ID)); using (var scope = ReflectionContainer.BeginLifetimeScope(cb => { cb.RegisterInstance(context) .AsSelf(); cb.RegisterInstance(worldObject) .As <GameObject>(); cb.RegisterInstance(dataFieldContainer) .As <IEntityDataFieldContainer>() .As <IReadonlyEntityDataFieldContainer>() .SingleInstance(); cb.RegisterType(behaviourType); })) { return((BaseEntityBehaviourComponent)scope.Resolve(behaviourType)); } }
/// <inheritdoc /> public void Add(NetworkEntityGuid key, IMovementData value) { lock (SyncObject) { DirtyChangesTracker[key] = true; InternallyManagedMovementDictionary.Add(key, value); } }
public BaseClientGameObjectEntityBehaviourComponent(NetworkEntityGuid targetEntity, [NotNull] GameObject rootSceneObject, [NotNull] IEntityDataFieldContainer data) : base(targetEntity) { RootSceneObject = rootSceneObject ?? throw new ArgumentNullException(nameof(rootSceneObject)); Data = data ?? throw new ArgumentNullException(nameof(data)); }
/// <inheritdoc /> public bool Remove(NetworkEntityGuid key) { lock (SyncObject) { DirtyChangesTracker.Remove(key); return(InternallyManagedMovementDictionary.RemoveEntityEntry(key)); } }
/// <inheritdoc /> public NetworkEntityGuid Retrieve(NetworkEntityGuid key) { if (!_ContainedEntities.Contains(key)) { throw new InvalidOperationException($"Provided Key: {key} does not exist in the tile."); } return(key); }
//This was brought over from the TrinityCore times, it used to be more complex to determine. private bool IsSpawningEntityLocalPlayer([NotNull] NetworkEntityGuid guid) { if (guid == null) { throw new ArgumentNullException(nameof(guid)); } return(guid.EntityType == EntityType.Player && CharacterDateRepository.CharacterId == guid.EntityId); }
/// <inheritdoc /> public bool Remove([NotNull] NetworkEntityGuid guid) { if (guid == null) { throw new ArgumentNullException(nameof(guid)); } return(_ContainedEntities.Remove(guid)); }
/// <inheritdoc /> public bool Contains([NotNull] NetworkEntityGuid key) { if (key == null) { throw new ArgumentNullException(nameof(key)); } return(_ContainedEntities.Contains(key)); }
private void RecalulateHealthUI(NetworkEntityGuid player, int currentHealth) { float healthPercentage = (float)currentHealth / EntityDataMappable[player].GetFieldValue <int>((int)EntityObjectField.UNIT_FIELD_MAXHEALTH); GroupUnitframeManager[player].HealthBar.BarFillable.FillAmount = healthPercentage; //Also we want to see the percentage text GroupUnitframeManager[player].HealthBar.BarText.Text = $"{currentHealth} / {EntityDataMappable.RetrieveEntity(player).GetFieldValue<int>((int)EntityObjectField.UNIT_FIELD_MAXHEALTH)}"; }
private void CreateBehaviourComponent(NetworkEntityGuid entityGuid) { BaseEntityBehaviourComponent behaviourComponent = BehaviourFactory.Create(entityGuid); if (behaviourComponent is IBehaviourComponentInitializable init) { init.Initialize(); } }
private static void CreateEntityDoesNotExistException <TReturnType>(NetworkEntityGuid guid) { if (guid == null) { throw new ArgumentNullException(nameof(guid), $"Found that provided entity guid in {nameof(CreateEntityCollectionException)} was null."); } throw new InvalidOperationException($"Entity does not exist in Collection {typeof(TReturnType).Name} from Entity: {guid}."); }
public DefaultGameObjectActorState([NotNull] IEntityDataFieldContainer entityData, [NotNull] NetworkEntityGuid entityGuid, [NotNull] GameObjectInstanceModel instanceModel, [NotNull] GameObjectTemplateModel templateModel, [NotNull] InterestCollection interest) : base(entityData, entityGuid, interest) { InstanceModel = instanceModel ?? throw new ArgumentNullException(nameof(instanceModel)); TemplateModel = templateModel ?? throw new ArgumentNullException(nameof(templateModel)); }
public ZoneServerWorldTeleportCharacterRequest([NotNull] NetworkEntityGuid characterGuid, int worldTeleporterId) { if (worldTeleporterId <= 0) { throw new ArgumentOutOfRangeException(nameof(worldTeleporterId)); } CharacterGuid = characterGuid ?? throw new ArgumentNullException(nameof(characterGuid)); WorldTeleporterId = worldTeleporterId; }
public PendingSpellCastCreationContext(int spellId, [NotNull] NetworkEntityGuid currentTarget) { if (spellId < 0) { throw new ArgumentOutOfRangeException(nameof(spellId)); } SpellId = spellId; CurrentTarget = currentTarget ?? throw new ArgumentNullException(nameof(currentTarget)); }