/// <inheritdoc />
        public override Task HandleMessage(IPeerMessageContext <GameClientPacketPayload> context, FieldValueUpdateEvent payload)
        {
            //Assume the update fields aren't null and there is at least 1
            foreach (EntityAssociatedData <FieldValueUpdate> update in payload.FieldValueUpdates)
            {
                //TODO: We shouldn't assume we know the entity, but technically we should based on order of server-side events.
                IEntityDataFieldContainer entityDataContainer = null;
                try
                {
                    entityDataContainer = EntityDataContainerMap[update.EntityGuid];
                }
                catch (Exception e)
                {
                    if (Logger.IsWarnEnabled)
                    {
                        Logger.Warn($"Encountered Entity FieldValueUpdate for Unknown Entity: {update.EntityGuid.EntityType}:{update.EntityGuid.EntityId}. Error: {e.Message}");
                    }

                    throw;
                }

                //We have to lock here otherwise we could encounter race conditions with the
                //change tracking system.
                lock (entityDataContainer.SyncObj)
                    foreach (var entry in update.Data.FieldValueUpdateMask
                             .EnumerateSetBitsByIndex()
                             .Zip(update.Data.FieldValueUpdates, (setIndex, value) => new { setIndex, value }))
                    {
                        entityDataContainer.SetFieldValue(entry.setIndex, entry.value);
                    }
            }

            return(Task.CompletedTask);
        }
Exemplo n.º 2
0
        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));
            }
        }
Exemplo n.º 3
0
 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));
 }
Exemplo n.º 4
0
        /// <summary>
        /// Helper extension for setting entity data in <see cref="IEntityDataFieldContainer"/>
        /// based on the int value of a specified Enum value <see cref="index"/>.
        /// </summary>
        /// <param name="container"></param>
        /// <param name="index"></param>
        /// <param name="guid"></param>
        public static void SetFieldValue(this IEntityDataFieldContainer container, int index, NetworkEntityGuid guid)
        {
            if (container == null)
            {
                throw new ArgumentNullException(nameof(container));
            }

            container.SetFieldValue(index, guid.RawGuidValue);
        }
Exemplo n.º 5
0
        /// <summary>
        /// TODO: Doc
        /// </summary>
        /// <param name="container"></param>
        /// <param name="flag"></param>
        public static void RemoveBaseObjectFieldFlag(this IEntityDataFieldContainer container, BaseObjectFieldFlags flag)
        {
            if (container == null)
            {
                throw new ArgumentNullException(nameof(container));
            }

            container.SetFieldValue(BaseObjectField.UNIT_FIELD_FLAGS, (int)((BaseObjectFieldFlags)container.GetFieldValue <int>(BaseObjectField.UNIT_FIELD_FLAGS) & ~flag));
        }
Exemplo n.º 6
0
        protected override void OnEntityCreationFinished(EntityCreationFinishedEventArgs args)
        {
            IEntityDataFieldContainer entityData          = EntityDataMappable.RetrieveEntity(args.EntityGuid);
            GameObjectTemplateModel   objectTemplateModel = GameObjectTemplateMappable.RetrieveEntity(args.EntityGuid);

            //We should generally consider this field static. I cannot even IMAGINE how we'd handle a change to this field on either
            //client or server.
            entityData.SetFieldValue(GameObjectField.GAMEOBJECT_TYPE_ID, (int)objectTemplateModel.ObjectType);
        }
Exemplo n.º 7
0
        /// <summary>
        /// TODO: Doc
        /// </summary>
        /// <param name="container"></param>
        /// <param name="flag"></param>
        public static bool HasBaseObjectFieldFlag(this IEntityDataFieldContainer container, BaseObjectFieldFlags flag)
        {
            if (container == null)
            {
                throw new ArgumentNullException(nameof(container));
            }

            return(((BaseObjectFieldFlags)container.GetFieldValue <int>(BaseObjectField.UNIT_FIELD_FLAGS) & flag) == flag);
        }
Exemplo n.º 8
0
 public DefaultAvatarPedestalGameObjectBehaviour(NetworkEntityGuid targetEntity,
                                                 GameObject rootSceneObject,
                                                 IEntityDataFieldContainer data,
                                                 [NotNull] IFactoryCreatable <CustomModelLoaderCancelable, CustomModelLoaderCreationContext> avatarLoaderFactory,
                                                 [NotNull] ILog logger)
     : base(targetEntity, rootSceneObject, data)
 {
     AvatarLoaderFactory = avatarLoaderFactory ?? throw new ArgumentNullException(nameof(avatarLoaderFactory));
     Logger = logger ?? throw new ArgumentNullException(nameof(logger));
 }
Exemplo n.º 9
0
        /// <summary>
        /// Helper extension for setting entity data in <see cref="IEntityDataFieldContainer"/>
        /// based on the int value of a specified Enum value <see cref="index"/>.
        /// </summary>
        /// <typeparam name="TEnumType"></typeparam>
        /// <param name="container"></param>
        /// <param name="index"></param>
        /// <param name="guid"></param>
        public static void SetFieldValue <TEnumType>(this IEntityDataFieldContainer container, TEnumType index, NetworkEntityGuid guid)
            where TEnumType : Enum
        {
            if (container == null)
            {
                throw new ArgumentNullException(nameof(container));
            }

            container.SetFieldValue(GenericMath.Convert <TEnumType, int>(index), guid.RawGuidValue);
        }
Exemplo n.º 10
0
 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));
 }
Exemplo n.º 11
0
        private void GenericInitialValueTest(int index)
        {
            //arrange
            IEntityDataFieldContainer collection = CreateEntityDataCollection();

            //act
            int value = collection.GetFieldValue <int>(index);

            //assert
            Assert.AreEqual(default(int), value, $"Value at Index: {index} is suppose to be zero or default value: {default(int)}.");
        }
Exemplo n.º 12
0
        private void OnTargetEntityHealthChanged(NetworkEntityGuid entity, EntityDataChangedArgs <int> args)
        {
            IEntityDataFieldContainer entityData = EntityDataMappable.RetrieveEntity(entity);

            //Ignore the changed value.
            int health    = entityData.GetFieldValue <int>(EntityObjectField.UNIT_FIELD_HEALTH);
            int maxHealth = entityData.GetFieldValue <int>(EntityObjectField.UNIT_FIELD_MAXHEALTH);

            TargetUnitFrame.HealthBar.BarText.Text           = $"{health} / {maxHealth}";
            TargetUnitFrame.HealthBar.BarFillable.FillAmount = (float)health / maxHealth;
        }
Exemplo n.º 13
0
 /// <inheritdoc />
 public DefaultEntityCreationContext(NetworkEntityGuid entityGuid, IMovementData movementData, EntityPrefab prefabType, [NotNull] IEntityDataFieldContainer entityData)
 {
     if (!Enum.IsDefined(typeof(EntityPrefab), prefabType))
     {
         throw new InvalidEnumArgumentException(nameof(prefabType), (int)prefabType, typeof(EntityPrefab));
     }
     EntityGuid   = entityGuid ?? throw new ArgumentNullException(nameof(entityGuid));
     MovementData = movementData ?? throw new ArgumentNullException(nameof(movementData));
     PrefabType   = prefabType;
     EntityData   = entityData ?? throw new ArgumentNullException(nameof(entityData));
 }
Exemplo n.º 14
0
        protected override void HandleMessage(EntityActorMessageContext messageContext, DefaultEntityActorStateContainer state, EntityActorInitializationSuccessMessage message)
        {
            //We should send ourselves the level initialization message because it takes care of stats
            CharacterDataInstance     entity = InitialCharacterDataMappable.RetrieveEntity(state.EntityGuid);
            IEntityDataFieldContainer entityDataFieldContainer = state.EntityData;

            entityDataFieldContainer.SetFieldValue((int)PlayerObjectField.PLAYER_TOTAL_EXPERIENCE, entity.Experience);

            //Set the level from the initial experience data.
            messageContext.Entity.Tell(new SetEntityActorLevelMessage(LevelStrategy.ComputeLevelFromExperience(entity.Experience)));
        }
Exemplo n.º 15
0
        /// <summary>
        /// Helper extension for setting entity data in <see cref="IEntityDataFieldContainer"/>
        /// based on the int value of a specified Enum value <see cref="index"/>.
        /// </summary>
        /// <typeparam name="TEnumType"></typeparam>
        /// <typeparam name="TValueType"></typeparam>
        /// <param name="container"></param>
        /// <param name="index"></param>
        /// <param name="value"></param>
        public static void SetFieldValue <TEnumType, TValueType>(this IEntityDataFieldContainer container, TEnumType index, TValueType value)
            where TValueType : struct
            where TEnumType : Enum
        {
            if (container == null)
            {
                throw new ArgumentNullException(nameof(container));
            }

            container.SetFieldValue(GenericMath.Convert <TEnumType, int>(index), value);
        }
Exemplo n.º 16
0
        protected override void OnEntityCreationFinished(EntityCreationFinishedEventArgs args)
        {
            IMovementData             movementData       = MovementDataMappable.RetrieveEntity(args.EntityGuid);
            IEntityDataFieldContainer dataFieldContainer = EntityDataMappable.RetrieveEntity(args.EntityGuid);

            EntityCreationData data = new EntityCreationData(args.EntityGuid, movementData, EntityDataUpdateFactory.Create(new EntityFieldUpdateCreationContext(dataFieldContainer, dataFieldContainer.DataSetIndicationArray)));

            var senderContext = new GenericSingleTargetMessageContext <PlayerSelfSpawnEventPayload>(args.EntityGuid, new PlayerSelfSpawnEventPayload(data));

            Sender.Send(senderContext);
        }
Exemplo n.º 17
0
        public void Test_Value_Set_Same_Read_Value([EntityDataCollectionTestRange] int index, [Values(1, 2, 3, 4, 5, 6, 7, 8)] int value)
        {
            //arrange
            IEntityDataFieldContainer collection = CreateEntityDataCollection();

            //act
            collection.SetFieldValue <int>(index, value);
            int getValue = collection.GetFieldValue <int>(index);

            //assert
            Assert.AreEqual(value, getValue, $"Set Value: {value} at Index: {index} was wrong Value: {getValue} instead.");
        }
Exemplo n.º 18
0
        private void GenericInitialValueTest <TValueType>(int index)
            where TValueType : struct
        {
            //arrange
            IEntityDataFieldContainer <TestFieldType> collection = CreateEntityDataCollection();

            //act
            TValueType value = collection.GetFieldValue <TValueType>(index);

            //assert
            Assert.AreEqual(default(TValueType), value, $"Value at Index: {index} is suppose to be zero or default value: {default(TValueType)}.");
        }
Exemplo n.º 19
0
        /// <inheritdoc />
        public NetworkEntityNowVisibleEventArgs Create(EntityCreationData context)
        {
            NetworkEntityGuid guid = context.EntityGuid;

            IEntityDataFieldContainer container = CreateInitialEntityFieldContainer(context.InitialFieldValues);
            ChangeTrackingEntityFieldDataCollectionDecorator trackingEntityFieldDataCollectionDecorator = new ChangeTrackingEntityFieldDataCollectionDecorator(container, context.InitialFieldValues.FieldValueUpdateMask);

            ChangeTrackableCollection.AddObject(guid, trackingEntityFieldDataCollectionDecorator);
            MovementBlockMappable.AddObject(guid, context.InitialMovementData);

            return(new NetworkEntityNowVisibleEventArgs(guid));
        }
Exemplo n.º 20
0
        protected override void OnLocalPlayerTargetChanged(LocalPlayerTargetChangedEventArgs args)
        {
            IEntityDataFieldContainer entityData = EntityDataMappable.RetrieveEntity(args.TargetedEntity);

            EntityDataChangeCallbackService.RegisterCallback <int>(args.TargetedEntity, (int)BaseObjectField.UNIT_FIELD_LEVEL, OnTargetEntityLevelChanged);

            //Only initialize if we have their values
            if (entityData.DataSetIndicationArray.Get((int)BaseObjectField.UNIT_FIELD_LEVEL))
            {
                OnTargetEntityLevelChanged(args.TargetedEntity, new EntityDataChangedArgs <int>(0, entityData.GetFieldValue <int>(BaseObjectField.UNIT_FIELD_LEVEL)));
            }
        }
Exemplo n.º 21
0
        public void Test_Value_Set_Multiple_Times_Is_Latest_Value([EntityDataCollectionTestRange] int index, [Values(1, 2, 3, 4, 5, 6, 7, 8)] int value)
        {
            //arrange
            IEntityDataFieldContainer collection = CreateEntityDataCollection();

            //act
            collection.SetFieldValue <int>(index, 5000);            //test set to 5000, will check the resulting end value
            collection.SetFieldValue <int>(index, value);
            int getValue = collection.GetFieldValue <int>(index);

            //assert
            Assert.AreEqual(value, getValue, $"Set Value: {value} at Index: {index} was wrong Value: {getValue} instead.");
        }
Exemplo n.º 22
0
        /// <inheritdoc />
        protected override Task HandleMessage(IPeerSessionMessageContext <GameServerPacketPayload> context, PlayerModelChangeRequestPayload payload, NetworkEntityGuid guid)
        {
            //At this point, the player wants to change his model.
            //However we really can't be sure it's a valid model
            //so we validate it before setting the model id.
            //TODO: Validate the model id.
            ProjectVersionStage.AssertAlpha();
            IEntityDataFieldContainer entityDataFieldContainer = EntityFieldMap.RetrieveEntity(guid);

            //This change will be broadcast to anyone interested.
            entityDataFieldContainer.SetFieldValue(BaseObjectField.UNIT_FIELD_DISPLAYID, payload.ModelId);

            return(Task.CompletedTask);
        }
Exemplo n.º 23
0
        /// <inheritdoc />
        public void InvokeChangeEvents(NetworkEntityGuid entity, IEntityDataFieldContainer fieldContainer, int field)
        {
            //We aren't watching ANY data changes for this particular entity.
            if (!CallbackMap.ContainsKey(entity))
            {
                return;
            }

            //If we have any registered callbacks for this entity's data change we should dispatch it (they will all be called)
            if (CallbackMap[entity].ContainsKey(field))
            {
                CallbackMap[entity][field]?.Invoke(fieldContainer);
            }
        }
Exemplo n.º 24
0
        protected override void OnEventFired(object source, EntityCreationStartingEventArgs args)
        {
            //Only do creatures.
            if (args.EntityGuid.EntityType != EntityType.Creature)
            {
                return;
            }

            IEntityDataFieldContainer dataContainer = EntityDataMappable.RetrieveEntity(args.EntityGuid);
            CreatureTemplateModel     template      = CreatureTemplateMappable.RetrieveEntity(args.EntityGuid);

            //Initialize the creature display model ID.
            dataContainer.SetFieldValue(BaseObjectField.UNIT_FIELD_DISPLAYID, template.ModelId);
        }
Exemplo n.º 25
0
        public void Test_DataIndexSetTracking_Indicates_Set_Indicies([EntityDataCollectionTestRange] int index1, [EntityDataCollectionTestRange] int index2, [Values(-1, 0, 1, 2)] int value1, [Values(-1, 0, 1, 2)] int value2)
        {
            //arrange
            IEntityDataFieldContainer collection = CreateEntityDataCollection();

            //act
            collection.SetFieldValue <int>(index1, value1);
            collection.SetFieldValue <int>(index2, value2);
            bool isSet1 = collection.DataSetIndicationArray.Get(index1);
            bool isSet2 = collection.DataSetIndicationArray.Get(index2);

            //assert
            Assert.True(isSet1, $"Index: {index1} being set should have caused indication array to be set.");
            Assert.True(isSet2, $"Index: {index2} being set should have caused indication array to be set.");
        }
Exemplo n.º 26
0
        protected override void OnEntityCreationFinished(EntityCreationFinishedEventArgs args)
        {
            IEntityDataFieldContainer dataContainer = EntityDataMappable.RetrieveEntity(args.EntityGuid);

            switch (dataContainer.GetEnumFieldValue <GameObjectType>(GameObjectField.GAMEOBJECT_TYPE_ID))
            {
            //Visual doesn't have behaviours
            case GameObjectType.Visual:
                return;

            default:
                CreateBehaviourComponent(args.EntityGuid);
                break;
            }
        }
Exemplo n.º 27
0
        protected override void OnEntityCreationFinished(EntityCreationFinishedEventArgs args)
        {
            IEntityDataFieldContainer data = EntityDataContainer.RetrieveEntity(args.EntityGuid);

            UnityAsyncHelper.UnityMainThreadContext.PostAsync(async() =>
            {
                var characterAppearance = await CharacterService.GetCharacterAppearance(args.EntityGuid.EntityId);

                //Even if the character has logged off we're just setting an unused data container so it's ok.
                if (characterAppearance.isSuccessful)
                {
                    data.SetFieldValue(BaseObjectField.UNIT_FIELD_DISPLAYID, characterAppearance.Result.AvatarModelId);
                }
            });
        }
Exemplo n.º 28
0
        /// <summary>
        /// Overloaded constructor which will actually take an initial <see cref="ChangeTrackingArray"/>.
        /// Useful for initial creation if you want initial values to be viewed as changes.
        /// </summary>
        /// <param name="entityDataCollection"></param>
        /// <param name="initialChangeTrackBitArray"></param>
        public ChangeTrackingEntityFieldDataCollectionDecorator(IEntityDataFieldContainer entityDataCollection, [NotNull] WireReadyBitArray initialChangeTrackBitArray)
        {
            if (initialChangeTrackBitArray == null)
            {
                throw new ArgumentNullException(nameof(initialChangeTrackBitArray));
            }
            if (initialChangeTrackBitArray.Length != entityDataCollection.DataSetIndicationArray.Length)
            {
                throw new InvalidOperationException($"Cannot set fields in {nameof(ChangeTrackingEntityFieldDataCollectionDecorator)} since provided collections {nameof(entityDataCollection)} and {nameof(initialChangeTrackBitArray)} do not have matching lengths.");
            }

            EntityDataCollection = entityDataCollection ?? throw new ArgumentNullException(nameof(entityDataCollection));
            ChangeTrackingArray  = initialChangeTrackBitArray;            //just the size of the initial data indiciation bitarray

            //TODO: Technically we can't ASSUME it has any changes, but probably more efficient to than to check.
            HasPendingChanges = true;
        }
Exemplo n.º 29
0
        protected override void OnLocalPlayerTargetChanged(LocalPlayerTargetChangedEventArgs args)
        {
            IEntityDataFieldContainer entityData = EntityDataMappable.RetrieveEntity(args.TargetedEntity);

            foreach (var unreg in Unregisterables)
            {
                unreg.Unregister();
            }

            Unregisterables.Clear();

            //Listen for both max and current health.
            Unregisterables.Add(EntityDataChangeCallbackService.RegisterCallback <int>(args.TargetedEntity, (int)EntityObjectField.UNIT_FIELD_HEALTH, OnTargetEntityHealthChanged));
            Unregisterables.Add(EntityDataChangeCallbackService.RegisterCallback <int>(args.TargetedEntity, (int)EntityObjectField.UNIT_FIELD_MAXHEALTH, OnTargetEntityHealthChanged));

            //Only initialize if we have their values
            if (entityData.DataSetIndicationArray.Get((int)EntityObjectField.UNIT_FIELD_HEALTH))
            {
                OnTargetEntityHealthChanged(args.TargetedEntity, new EntityDataChangedArgs <int>(0, 0));
            }
        }
Exemplo n.º 30
0
        public void Test_ChangeTracker_Doesnt_Set_Change_Bits_On_Same_Value_After_Clear_FieldValueUpdate()
        {
            //arrange
            WireReadyBitArray bitArray = new WireReadyBitArray(1328);

            bitArray.Set(1, true);
            bitArray.Set(2, true);
            bitArray.Set(4, true);

            //Reference the actual client's visibile field update computation.
            IEntityDataFieldContainer dataCollection = NetworkVisibilityCreationBlockToVisibilityEventFactory.CreateInitialEntityFieldContainer(new FieldValueUpdate(bitArray, new int[] { 5, 4, 7 }));

            ChangeTrackingEntityFieldDataCollectionDecorator collection = new ChangeTrackingEntityFieldDataCollectionDecorator(dataCollection, bitArray);
            FieldValueUpdateFactory updateFactory = new FieldValueUpdateFactory();

            //act
            FieldValueUpdate fieldValueUpdate = updateFactory.Create(new EntityFieldUpdateCreationContext(collection, collection.ChangeTrackingArray));

            Assert.AreEqual(3, fieldValueUpdate.FieldValueUpdateMask.EnumerateSetBitsByIndex().Count(), $"Found more than 1 set bit.");
            Assert.AreEqual(5, fieldValueUpdate.FieldValueUpdates.First(), $"Serialized value was not expected value.");
            Assert.AreEqual(1, fieldValueUpdate.FieldValueUpdateMask.EnumerateSetBitsByIndex().First(), $"Index: {1} was expected to be first index.");

            collection.ClearTrackedChanges();


            //Check they're event before setting them again
            Assert.AreEqual(collection.GetFieldValue <int>(1), 5, $"Values not the same.");
            Assert.AreEqual(collection.GetFieldValue <int>(2), 4, $"Values not the same.");
            collection.SetFieldValue(1, 5);
            collection.SetFieldValue(2, 4);

            fieldValueUpdate = updateFactory.Create(new EntityFieldUpdateCreationContext(collection, collection.ChangeTrackingArray));

            //assert
            Assert.AreEqual(0, fieldValueUpdate.FieldValueUpdateMask.EnumerateSetBitsByIndex().Count(), $"Found more than 1 set bit.");
            Assert.AreEqual(0, fieldValueUpdate.FieldValueUpdates.Count, $"Field updates should be empty due to no changes..");
        }