public ReflectionPacketFieldInfo(PropertyInfo property, PacketFieldOptionsAttribute attribute) : base(property, attribute) { var type = property.PropertyType; if (IsPrimitive) { GetFunctions(property, attribute, out var s, out var d); PrimitiveSerializer = s; PrimitiveDeserializer = d; } if (type.IsEnum && type.GetCustomAttribute <FlagsAttribute>() == null) { EnumValidator = val => { if (!Enum.IsDefined(type, val)) { _log.Warning("Found unknown enum value {0} for field {1}.{2} ({3})", val, property.DeclaringType.Name, property.Name, type.Name); } } } ; if (IsArray) { var ctor = type.GetGenericArguments()[0].GetConstructor(Type.EmptyTypes); var empty = Array.Empty <object>(); ElementConstructor = () => ctor.Invoke(empty); } }
protected PacketFieldInfo(PropertyInfo property, PacketFieldOptionsAttribute attribute) { Property = property ?? throw new ArgumentNullException(nameof(property)); Attribute = attribute; var type = property.PropertyType; var isArray = type.IsConstructedGenericType && type.GetGenericTypeDefinition() == typeof(List <>); var elemType = isArray ? type.GetGenericArguments()[0] : null; var isByteArray = elemType == typeof(byte); IsArray = isArray && !isByteArray; IsByteArray = isArray && isByteArray; IsString = type == typeof(string); IsPrimitive = IsPrimitiveType(type); }
protected PacketFieldInfo(PropertyInfo property, PacketFieldOptionsAttribute attribute) { Property = property ?? throw new ArgumentNullException(nameof(property)); Attribute = attribute; var type = property.PropertyType; if (type.IsConstructedGenericType && type.GetGenericTypeDefinition() == typeof(NoNullList <>)) { IsArray = true; } else if (type == typeof(List <byte>)) { IsByteArray = true; } else if (type == typeof(string)) { IsString = true; } else { if (type.IsEnum) { type = type.GetEnumUnderlyingType(); } if (type.IsPrimitive || type == typeof(Vector3) || type == typeof(GameId) || type == typeof(SkillId) || type == typeof(Angle) || type == typeof(TemplateId) || type == typeof(Appearance)) { IsPrimitive = true; } else { throw Assert.Unreachable(); } } }
protected override PacketFieldInfo CreateFieldInfo(PropertyInfo property, PacketFieldOptionsAttribute attribute) { return(new CompilerPacketFieldInfo(property, attribute)); }
public CompilerPacketFieldInfo(PropertyInfo property, PacketFieldOptionsAttribute attribute) : base(property, attribute) { }
protected abstract PacketFieldInfo CreateFieldInfo(PropertyInfo property, PacketFieldOptionsAttribute attribute);
static void GetFunctions(PropertyInfo property, PacketFieldOptionsAttribute attribute, out Action <GameBinaryWriter, object> serializer, out Func <GameBinaryReader, object> deserializer) { var dtype = property.DeclaringType; var type = property.PropertyType; if (type.IsEnum) { type = type.GetEnumUnderlyingType(); } if (type == typeof(bool)) { serializer = (w, v) => w.WriteBoolean((bool)v); deserializer = r => { var b = r.ReadByte(); if (b != 0 && b != 1) { _log.Warning("Found non-Boolean value {0} for field {1}.{2}", b, dtype.Name, property.Name); } return(b != 0); }; } else if (type == typeof(byte)) { serializer = (w, v) => w.WriteByte((byte)v); deserializer = r => r.ReadByte(); } else if (type == typeof(sbyte)) { serializer = (w, v) => w.WriteSByte((sbyte)v); deserializer = r => r.ReadSByte(); } else if (type == typeof(ushort)) { if (attribute?.IsUnknownArray ?? false) { serializer = (w, v) => w.WriteUInt16(0); deserializer = r => { var v = r.ReadUInt16(); if (v != 0) { _log.Warning("Found non-zero value {0} for unknown array field {1}.{2}", v, dtype.Name, property.Name); } return(v); }; } else { serializer = (w, v) => w.WriteUInt16((ushort)v); deserializer = r => r.ReadUInt16(); } } else if (type == typeof(short)) { serializer = (w, v) => w.WriteInt16((short)v); deserializer = r => r.ReadInt16(); } else if (type == typeof(uint)) { serializer = (w, v) => w.WriteUInt32((uint)v); deserializer = r => r.ReadUInt32(); } else if (type == typeof(int)) { serializer = (w, v) => w.WriteInt32((int)v); deserializer = r => r.ReadInt32(); } else if (type == typeof(ulong)) { serializer = (w, v) => w.WriteUInt64((ulong)v); deserializer = r => r.ReadUInt64(); } else if (type == typeof(long)) { serializer = (w, v) => w.WriteInt64((long)v); deserializer = r => r.ReadInt64(); } else if (type == typeof(float)) { serializer = (w, v) => w.WriteSingle((float)v); deserializer = r => r.ReadSingle(); } else if (type == typeof(double)) { serializer = (w, v) => w.WriteDouble((double)v); deserializer = r => r.ReadDouble(); } else if (type == typeof(Vector3)) { serializer = (w, v) => w.WriteVector3((Vector3)v); deserializer = r => r.ReadVector3(); } else if (type == typeof(GameId)) { serializer = (w, v) => w.WriteGameId((GameId)v); deserializer = r => r.ReadGameId(); } else if (type == typeof(SkillId)) { if (attribute?.IsSimpleSkill ?? false) { serializer = (w, v) => w.WriteSimpleSkillId((SkillId)v); deserializer = r => r.ReadSimpleSkillId(); } else { serializer = (w, v) => w.WriteSkillId((SkillId)v); deserializer = r => r.ReadSkillId(); } } else if (type == typeof(Angle)) { serializer = (w, v) => w.WriteAngle((Angle)v); deserializer = r => r.ReadAngle(); } else if (type == typeof(TemplateId)) { serializer = (w, v) => w.WriteTemplateId((TemplateId)v); deserializer = r => r.ReadTemplateId(); } else if (type == typeof(Appearance)) { serializer = (w, v) => w.WriteAppearance((Appearance)v); deserializer = r => r.ReadAppearance(); } else { throw Assert.Unreachable(); } }