Exemplo n.º 1
0
        /// <summary>
        /// Returns a list of packet properties for writing and reading packets.
        ///
        /// </summary>
        /// <param name="type">Type to check the properties of.</param>
        /// <returns>List of properties to write.</returns>
        /// <exception cref="InvalidOperationException">Properties are invalid.</exception>
        public static StructPacketProperty GetPacketProperties(Type type)
        {
            // Populate the cache entry if needed.
            CachePacketPropertiesSemaphore.Wait();
            if (!CachePacketProperties.ContainsKey(type))
            {
                CachePacketProperties[type] = new StructPacketProperty(type);
            }
            CachePacketPropertiesSemaphore.Release();

            // Return the cache entry.
            return(CachePacketProperties[type]);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Creates the struct packet property.
        /// </summary>
        /// <param name="structType">Type of the struct.</param>
        public StructPacketProperty(Type structType)
        {
            // Add the packet information.
            if (structType.GetCustomAttribute(typeof(PacketStructAttribute)) is PacketStructAttribute packetStruct)
            {
                this.Properties.Add(new PacketInformation(packetStruct.MessageIdentifier, packetStruct.RemoteConnectionType, packetStruct.PacketId));
            }

            // Convert the properties to PacketProperties.
            foreach (var property in structType?.GetProperties())
            {
                // Create the base packet property.
                IPacketProperty packetProperty = null;
                if (property.PropertyType == typeof(string))
                {
                    packetProperty = new StringPacketProperty(property);
                }
                else if (property.PropertyType == typeof(Quaternion) && property.GetCustomAttribute <NiQuaternionAttribute>() != null)
                {
                    packetProperty = new NiQuaternionProperty(property);
                }
                else if (property.PropertyType.IsValueType && property.PropertyType.GetCustomAttribute <StructAttribute>() != null)
                {
                    packetProperty = new StructPacketProperty(property);
                }
                else
                {
                    packetProperty = new PacketProperty(property);
                }
                if ((property.GetCustomAttribute(typeof(DefaultAttribute)) is DefaultAttribute defaultAttribute))
                {
                    packetProperty = new FlagPacketProperty(packetProperty, defaultAttribute.ValueToIgnore);
                }

                // Wrap the required properties.
                var requiredProperties = new Dictionary <string, RequiredPacketProperty>();
                foreach (var requiredAttribute in property.GetCustomAttributes <RequiresAttribute>())
                {
                    if (!requiredProperties.ContainsKey(requiredAttribute.PropertyName))
                    {
                        var requiredPacketProperty = new RequiredPacketProperty(packetProperty, requiredAttribute.PropertyName);
                        requiredProperties.Add(requiredAttribute.PropertyName, requiredPacketProperty);
                        packetProperty = requiredPacketProperty;
                    }
                    requiredProperties[requiredAttribute.PropertyName].RequiredValues.Add(requiredAttribute.ValueToRequire);
                }

                // Add the packet property.
                this.Properties.Add(packetProperty);
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// Creates the packet property.
        /// </summary>
        /// <param name="property">Property to write.</param>
        public PacketProperty(PropertyInfo property)
        {
            // Store the property.
            this.StructProperty = property;

            // Get the type to write.
            if (property == null)
            {
                return;
            }
            this._propertyType = property.PropertyType;
            if (this._propertyType.IsEnum)
            {
                this._propertyType = Enum.GetUnderlyingType(this._propertyType);
            }

            // Get the custom writer and reader.
            var readerWriterType = this._propertyType;

            if (readerWriterType.IsArray)
            {
                readerWriterType = readerWriterType.GetElementType();
            }
            if (readerWriterType != null)
            {
                // Set the writer and reader for types.
                foreach (var(customWriterType, customWriter) in CustomWriters)
                {
                    if (customWriterType == readerWriterType || readerWriterType.IsSubclassOf(customWriterType))
                    {
                        this._customWriter = customWriter;
                    }
                }
                foreach (var(customReaderType, customReader) in CustomReaders)
                {
                    if (customReaderType == readerWriterType || readerWriterType.IsSubclassOf(customReaderType))
                    {
                        this._customReader = customReader;
                    }
                }

                // Set the writer and reader for structs.
                if (readerWriterType.IsValueType && readerWriterType.GetCustomAttribute <StructAttribute>() != null)
                {
                    var structPacketProperty = new StructPacketProperty(readerWriterType);
                    this._customWriter = ((writer, o) =>
                    {
                        structPacketProperty.Write(o, writer, null);
                    });
                    this._customReader = ((reader, context) =>
                    {
                        var o = Activator.CreateInstance(readerWriterType);
                        var writtenProperties = new Dictionary <string, object>();
                        structPacketProperty.Read(o, reader, writtenProperties, context);
                        return(o);
                    });
                }
            }

            // Get the array length type.
            if (property.GetCustomAttribute(typeof(StoreLengthAsAttribute)) is StoreLengthAsAttribute storeLengthAs)
            {
                this._arrayLengthPropertyType = storeLengthAs.Type;
            }
        }