internal static void Serialize(object instance, BitWriter writer) { FieldInfo[] sortedFields; MethodInfo preMethod; if (cachedFields.ContainsKey(instance.GetType().FullName)) { sortedFields = cachedFields[instance.GetType().FullName]; } else { sortedFields = instance.GetType().GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).OrderBy(x => x.Name).Where(x => !x.IsDefined(typeof(BinaryIgnore), true)).ToArray(); cachedFields.Add(instance.GetType().FullName, sortedFields); } if (preSerialize.ContainsKey(instance.GetType().FullName)) { preMethod = preSerialize[instance.GetType().FullName]; } else { preMethod = instance.GetType().GetMethod("PreSerialize", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); preSerialize.Add(instance.GetType().FullName, preMethod); } if (preMethod != null) { preMethod.Invoke(instance, null); } for (int i = 0; i < sortedFields.Length; i++) { FieldTypeHelper.WriteFieldType(writer, sortedFields[i].GetValue(instance)); } }
internal static void HandleTargetRpc(uint clientId, BitReader reader, int channelId) { if (NetworkingManager.singleton.NetworkConfig.AttributeMessageMode == AttributeMessageMode.Disabled) { return; } uint networkId = reader.ReadUInt(); ushort orderId = reader.ReadUShort(); ulong hash = reader.ReadULong(); NetworkedBehaviour behaviour = SpawnManager.spawnedObjects[networkId].GetBehaviourAtOrderIndex(orderId); MethodInfo targetMethod = null; if (behaviour.cachedMethods.ContainsKey(hash)) { targetMethod = behaviour.cachedMethods[hash]; } else { return; //No method } ParameterInfo[] parameters = targetMethod.GetParameters(); object[] methodParams = new object[parameters.Length]; for (int i = 0; i < parameters.Length; i++) { methodParams[i] = FieldTypeHelper.ReadFieldType(reader, parameters[i].ParameterType); } targetMethod.Invoke(behaviour, methodParams); }
/// <summary> /// Deserializes binary and turns it back into the original class /// </summary> /// <typeparam name="T">The type to return</typeparam> /// <param name="binary">The binary to deserialize</param> /// <returns>An instance of T</returns> public static T Deserialize <T>(byte[] binary) where T : new() { T instance = new T(); FieldInfo[] sortedFields; if (cachedFields.ContainsKey(instance.GetType().FullName)) { sortedFields = cachedFields[instance.GetType().FullName]; } else { sortedFields = instance.GetType().GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).OrderBy(x => x.Name).Where(x => !x.IsDefined(typeof(BinaryIgnore), true)).ToArray(); cachedFields.Add(instance.GetType().FullName, sortedFields); } BitReader reader = new BitReader(binary); for (int i = 0; i < sortedFields.Length; i++) { FieldType fieldType = FieldTypeHelper.GetFieldType(sortedFields[i].FieldType); if (fieldType == FieldType.Invalid) { Debug.LogWarning("MLAPI: The field " + sortedFields[i].Name + " will not be deserialized as it's not of a supported type. Add the BinaryIgnore attribute to prevent this message from shwoing up."); continue; } sortedFields[i].SetValue(instance, FieldTypeHelper.ReadFieldType(reader, fieldType)); } return(instance); }
public static IfdEntry ParseFromByte(byte[] imageData, int startIndex, ByteOrder byteOrder) { var typeValue = BitConverterExtension.ToUInt16(imageData, startIndex + 2, byteOrder, BitConverterExtension.SystemByteOrder); if (!typeof(FieldType).IsEnumDefined(typeValue)) { throw new ArgumentOutOfRangeException("Invalid field type value"); } var tag = BitConverterExtension.ToUInt16(imageData, startIndex, byteOrder, BitConverterExtension.SystemByteOrder); var count = BitConverterExtension.ToUInt32(imageData, startIndex + 4, byteOrder, BitConverterExtension.SystemByteOrder); var value = BitConverterExtension.CopyArrayEndianness(imageData, startIndex + 8, byteOrder, BitConverterExtension.SystemByteOrder, IfdEntryValueByteLength); var valueLength = FieldTypeHelper.GetFieldTypeByteLength((FieldType)typeValue) * (int)count; if (valueLength > IfdEntryValueByteLength) { var valueOffset = BitConverterExtension.ToUInt32(value, 0, byteOrder, BitConverterExtension.SystemByteOrder); value = BitConverterExtension.CopyArrayEndianness(imageData, (int)valueOffset, byteOrder, BitConverterExtension.SystemByteOrder, valueLength); } return(new IfdEntry(tag, typeValue, count, value)); }
public void TestForReferenceTypes() { object o = (int)2; //Boxed to ref type. But the type of the value is a value type. Assert.That(FieldTypeHelper.IsRefType(o.GetType()), Is.False); int i = 3; //Value type Assert.That(FieldTypeHelper.IsRefType(i.GetType()), Is.False); string s = "123"; //Actually ref type. But it's immutable so the method should return true. Assert.That(FieldTypeHelper.IsRefType(s.GetType()), Is.False); byte[] bs = new byte[5]; Assert.That(FieldTypeHelper.IsRefType(bs.GetType()), Is.True); }
//Writes SyncedVar data in a formatted way so that the SetFormattedSyncedVarData method can read it. //The format doesn't NECCECARLY correspond with the "general syncedVar message layout" //as this should only be used for reading SyncedVar data that is to be read by the SetFormattedData method //* //The data contains every syncedvar on every behaviour that belongs to this object internal void WriteFormattedSyncedVarData(BitWriter writer) { for (int i = 0; i < childNetworkedBehaviours.Count; i++) { childNetworkedBehaviours[i].SyncVarInit(); if (childNetworkedBehaviours[i].syncedVarFields.Count == 0) { continue; } writer.WriteUShort(GetOrderIndex(childNetworkedBehaviours[i])); //Write the behaviourId for (int j = 0; j < childNetworkedBehaviours[i].syncedVarFields.Count; j++) { FieldTypeHelper.WriteFieldType(writer, childNetworkedBehaviours[i].syncedVarFields[j].FieldValue); } } }
internal static void HandleTargetRpc(uint clientId, byte[] incommingData, int channelId) { BitReader reader = new BitReader(incommingData); uint networkId = reader.ReadUInt(); ushort orderId = reader.ReadUShort(); ulong hash = reader.ReadULong(); NetworkedBehaviour behaviour = SpawnManager.spawnedObjects[networkId].GetBehaviourAtOrderIndex(orderId); MethodInfo targetMethod = null; if (behaviour.cachedMethods.ContainsKey(Data.Cache.GetAttributeMethodName(hash))) { targetMethod = behaviour.cachedMethods[Data.Cache.GetAttributeMethodName(hash)]; } byte paramCount = reader.ReadBits(5); object[] methodParams = FieldTypeHelper.ReadObjects(reader, paramCount); targetMethod.Invoke(behaviour, methodParams); }
public void TestSequenceEquals() { Random rnd = new Random(0); byte[] byteArray = new byte[50]; rnd.NextBytes(byteArray); Assert.That(FieldTypeHelper.SequenceEquals(byteArray, null), Is.False); Assert.That(FieldTypeHelper.SequenceEquals(null, byteArray), Is.False); Random rnd1 = new Random(0); for (int i = 0; i < 500; i++) { rnd = new Random(0); int length = rnd1.Next(100); if (length == 50) { length++; } byte[] diffLengthArray = new byte[length]; rnd.NextBytes(diffLengthArray); Assert.That(FieldTypeHelper.SequenceEquals(diffLengthArray, byteArray), Is.False); Assert.That(FieldTypeHelper.SequenceEquals(byteArray, diffLengthArray), Is.False); } rnd1 = new Random(0); for (int i = 0; i < 500; i++) { rnd = new Random(0); byte[] sameLengthDiffValues = new byte[50]; rnd.NextBytes(byteArray); sameLengthDiffValues[rnd1.Next(50)] = (byte)rnd.Next(255); Assert.That(FieldTypeHelper.SequenceEquals(sameLengthDiffValues, byteArray), Is.False); Assert.That(FieldTypeHelper.SequenceEquals(byteArray, sameLengthDiffValues), Is.False); } rnd = new Random(0); byte[] copyOfTheArray = new byte[50]; rnd.NextBytes(copyOfTheArray); Assert.That(FieldTypeHelper.SequenceEquals(copyOfTheArray, byteArray), Is.True); Assert.That(FieldTypeHelper.SequenceEquals(byteArray, copyOfTheArray), Is.True); }
/// <summary> /// Deserializes binary and turns it back into the original class /// </summary> /// <typeparam name="T">The type to return</typeparam> /// <param name="binary">The binary to deserialize</param> /// <returns>An instance of T</returns> public static T Deserialize <T>(byte[] binary) where T : new() { T instance = new T(); FieldInfo[] sortedFields; MethodInfo postMethod; if (cachedFields.ContainsKey(instance.GetType().FullName)) { sortedFields = cachedFields[instance.GetType().FullName]; } else { sortedFields = instance.GetType().GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).OrderBy(x => x.Name).Where(x => !x.IsDefined(typeof(BinaryIgnore), true)).ToArray(); cachedFields.Add(instance.GetType().FullName, sortedFields); } if (postDeserialize.ContainsKey(instance.GetType().FullName)) { postMethod = postDeserialize[instance.GetType().FullName]; } else { postMethod = instance.GetType().GetMethod("PostDeserialize", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); postDeserialize.Add(instance.GetType().FullName, postMethod); } using (BitReader reader = BitReader.Get(binary)) { for (int i = 0; i < sortedFields.Length; i++) { sortedFields[i].SetValue(instance, FieldTypeHelper.ReadFieldType(reader, sortedFields[i].FieldType)); } if (postMethod != null) { postMethod.Invoke(instance, null); } return(instance); } }
internal static object Deserialize(BitReader reader, Type type) { object instance = Activator.CreateInstance(type); FieldInfo[] sortedFields; MethodInfo postMethod; if (cachedFields.ContainsKey(type.FullName)) { sortedFields = cachedFields[instance.GetType().FullName]; } else { sortedFields = instance.GetType().GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).OrderBy(x => x.Name).Where(x => !x.IsDefined(typeof(BinaryIgnore), true)).ToArray(); cachedFields.Add(instance.GetType().FullName, sortedFields); } if (postDeserialize.ContainsKey(instance.GetType().FullName)) { postMethod = postDeserialize[instance.GetType().FullName]; } else { postMethod = instance.GetType().GetMethod("PostDeserialize", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); postDeserialize.Add(instance.GetType().FullName, postMethod); } for (int i = 0; i < sortedFields.Length; i++) { sortedFields[i].SetValue(instance, FieldTypeHelper.ReadFieldType(reader, sortedFields[i].FieldType)); } if (postMethod != null) { postMethod.Invoke(instance, null); } return(instance); }
private bool ParseRowData(Unmarshal context, BinaryReader source) { var objex = Header as PyObjectEx; if (objex == null) { return(false); } var header = objex.Header as PyTuple; if (header == null || header.Items.Count < 2) { return(false); } var columns = header.Items[1] as PyTuple; if (columns == null) { return(false); } columns = columns.Items[0] as PyTuple; if (columns == null) { return(false); } Columns = new List <Column>(columns.Items.Count); foreach (var obj in columns.Items) { var fieldData = obj as PyTuple; if (fieldData == null || fieldData.Items.Count < 2) { continue; } var name = fieldData.Items[0] as PyString; if (name == null) { continue; } Columns.Add(new Column(name.Value, (FieldType)fieldData.Items[1].IntValue)); } var sizeList = Columns.OrderByDescending(c => FieldTypeHelper.GetTypeBits(c.Type)); var sizeSum = sizeList.Sum(c => FieldTypeHelper.GetTypeBits(c.Type)); // align sizeSum = (sizeSum + 7) >> 3; var rawStream = new MemoryStream(); // fill up rawStream.Write(RawData, 0, RawData.Length); for (int i = 0; i < (sizeSum - RawData.Length); i++) { rawStream.WriteByte(0); } rawStream.Seek(0, SeekOrigin.Begin); var reader = new BinaryReader(rawStream); int bitOffset = 0; foreach (var column in sizeList) { switch (column.Type) { case FieldType.I8: case FieldType.UI8: case FieldType.CY: case FieldType.FileTime: column.Value = new PyLongLong(reader.ReadInt64()); break; case FieldType.I4: case FieldType.UI4: column.Value = new PyInt(reader.ReadInt32()); break; case FieldType.I2: case FieldType.UI2: column.Value = new PyInt(reader.ReadInt16()); break; case FieldType.I1: case FieldType.UI1: column.Value = new PyInt(reader.ReadByte()); break; case FieldType.R8: column.Value = new PyFloat(reader.ReadDouble()); break; case FieldType.R4: column.Value = new PyFloat(reader.ReadSingle()); break; case FieldType.Bytes: case FieldType.Str: case FieldType.WStr: column.Value = context.ReadObject(source); break; case FieldType.Bool: { if (7 < bitOffset) { bitOffset = 0; reader.ReadByte(); } var b = reader.ReadByte(); reader.BaseStream.Seek(-1, SeekOrigin.Current); column.Value = new PyInt((b >> bitOffset++) & 0x01); break; } default: throw new Exception("No support for " + column.Type); } } return(true); }
internal static void HandleSyncVarUpdate(uint clientId, BitReader reader, int channelId) { uint netId = reader.ReadUInt(); ushort orderIndex = reader.ReadUShort(); if (!SpawnManager.spawnedObjects.ContainsKey(netId)) { if (LogHelper.CurrentLogLevel <= LogLevel.Normal) { LogHelper.LogWarning("Sync message recieved for a non existant object with id: " + netId); } return; } else if (SpawnManager.spawnedObjects[netId].GetBehaviourAtOrderIndex(orderIndex) == null) { if (LogHelper.CurrentLogLevel <= LogLevel.Normal) { LogHelper.LogWarning("Sync message recieved for a non existant behaviour"); } return; } for (int i = 0; i < SpawnManager.spawnedObjects[netId].GetBehaviourAtOrderIndex(orderIndex).syncedVarFields.Count; i++) { if (!reader.ReadBool()) { continue; } SyncedVarField field = SpawnManager.spawnedObjects[netId].GetBehaviourAtOrderIndex(orderIndex).syncedVarFields[i]; SpawnManager.spawnedObjects[netId].GetBehaviourAtOrderIndex(orderIndex).OnSyncVarUpdate(FieldTypeHelper.ReadFieldType(reader, field.FieldInfo.FieldType, field.FieldValue), i); } SpawnManager.spawnedObjects[netId].GetBehaviourAtOrderIndex(orderIndex).OnSyncVarUpdate(); }
//Reads formatted data that the "WriteFormattedSyncedVarData" has written and applies the values to SyncedVar fields internal void SetFormattedSyncedVarData(BitReader reader) { for (int i = 0; i < childNetworkedBehaviours.Count; i++) { childNetworkedBehaviours[i].SyncVarInit(); if (childNetworkedBehaviours[i].syncedVarFields.Count == 0) { continue; } NetworkedBehaviour behaviour = GetBehaviourAtOrderIndex(reader.ReadUShort()); for (int j = 0; j < childNetworkedBehaviours[i].syncedVarFields.Count; j++) { childNetworkedBehaviours[i].syncedVarFields[j].FieldInfo.SetValue(behaviour, FieldTypeHelper.ReadFieldType(reader, childNetworkedBehaviours[i].syncedVarFields[j].FieldInfo.FieldType)); } behaviour.OnSyncVarUpdate(); } }
protected override void EncodeInternal(BinaryWriter output) { output.Write((byte)MarshalOpcode.PackedRow); Header.Encode(output); int cc = Columns.Count; var rawStream = new MemoryStream(); var writer = new BinaryWriter(rawStream); var reader = new BinaryReader(rawStream); var sizeList = Columns.OrderByDescending(c => FieldTypeHelper.GetTypeBits(c.Type)); foreach (Column col in sizeList) { switch (col.Type) { case FieldType.I8: case FieldType.UI8: case FieldType.CY: case FieldType.FileTime: writer.Write(col.Value.IntValue); break; case FieldType.I4: case FieldType.UI4: writer.Write((int)(col.Value.IntValue)); break; case FieldType.I2: case FieldType.UI2: writer.Write((short)(col.Value.IntValue)); break; case FieldType.I1: case FieldType.UI1: writer.Write((byte)(col.Value.IntValue)); break; case FieldType.R8: writer.Write((double)(col.Value.FloatValue)); break; case FieldType.R4: writer.Write((float)(col.Value.FloatValue)); break; case FieldType.Bool: writer.Write((byte)(col.Value.IntValue)); break; case FieldType.Bytes: writer.Write((col.Value as PyBuffer).Data); break; case FieldType.Str: case FieldType.WStr: col.Value.Encode(output); break; default: throw new Exception("Unsupported FieldType"); } } long bitByte = 0; byte bitOffset = 0; byte[] unpacked = rawStream.ToArray(); rawStream.Close(); foreach (Column col in Columns) { if (FieldTypeHelper.GetTypeBits(col.Type) != 1) { continue; } PyBool value = col.Value as PyBool; if (bitOffset > 7) { bitOffset = 0; } if (bitOffset == 0) { bitByte = unpacked.Length + 1; Array.Resize <byte>(ref unpacked, (int)(bitByte)); } unpacked[bitByte] |= (byte)(((value.Value == true) ? 1 : 0) << bitOffset++); } rawStream = new MemoryStream(unpacked); reader = new BinaryReader(rawStream); ZeroCompress(reader, rawStream, output); foreach (Column col in Columns) { col.Value.Encode(output); } reader.Close(); }
private bool ParseRowData(Unmarshal context, BinaryReader source) { if (Descriptor == null) { return(false); } values = new PyRep[Descriptor.Columns.Count]; var sizeList = Descriptor.Columns.OrderByDescending(c => FieldTypeHelper.GetTypeBits(c.Type)); var sizeSum = sizeList.Sum(c => FieldTypeHelper.GetTypeBits(c.Type)); // align sizeSum = (sizeSum + 7) >> 3; var rawStream = new MemoryStream(); // fill up rawStream.Write(RawData, 0, RawData.Length); for (int i = 0; i < (sizeSum - RawData.Length); i++) { rawStream.WriteByte(0); } rawStream.Seek(0, SeekOrigin.Begin); var reader = new BinaryReader(rawStream); int bitOffset = 0; foreach (var column in sizeList) { PyRep value = null; switch (column.Type) { case FieldType.I8: case FieldType.UI8: case FieldType.CY: case FieldType.FileTime: value = new PyLongLong(reader.ReadInt64()); break; case FieldType.I4: case FieldType.UI4: value = new PyInt(reader.ReadInt32()); break; case FieldType.I2: case FieldType.UI2: value = new PyInt(reader.ReadInt16()); break; case FieldType.I1: case FieldType.UI1: value = new PyInt(reader.ReadByte()); break; case FieldType.R8: value = new PyFloat(reader.ReadDouble()); break; case FieldType.R4: value = new PyFloat(reader.ReadSingle()); break; case FieldType.Bytes: case FieldType.Str: case FieldType.WStr: value = context.ReadObject(source); break; case FieldType.Bool: { if (7 < bitOffset) { bitOffset = 0; reader.ReadByte(); } var b = reader.ReadByte(); reader.BaseStream.Seek(-1, SeekOrigin.Current); value = new PyInt((b >> bitOffset++) & 0x01); break; } case FieldType.Token: value = new PyToken(column.Token); break; default: throw new Exception("No support for " + column.Type); } int index = Descriptor.Columns.FindIndex(x => x.Name == column.Name); values[index] = value; } return(true); }
public static ModelData Create(CacheFile file) { var ret = new ModelData { Name = ShortenName(file.Name) }; var rows = file.GetRows(); ret.Rows = rows; if (rows.Count() == 0) { throw new InvalidDataException("Cache is empty"); } var singleRow = rows.First(); ret.SingleRow = singleRow; // we need to go through all rows to find the maximum size type of all columns var fieldTypes = new FieldType[singleRow.Columns.Count]; for (int i = 0; i < singleRow.Columns.Count; i++) { fieldTypes[i] = singleRow.Columns[i].Type; } foreach (var row in rows) { for (int i = 0; i < row.Columns.Count; i++) { if (FieldTypeHelper.GetTypeBits(row.Columns[i].Type) > FieldTypeHelper.GetTypeBits(fieldTypes[i])) { fieldTypes[i] = row.Columns[i].Type; } } } ret.FieldTypes = fieldTypes; // now build the creation query - fields, primary key, indices, cleanup var query = new StringBuilder(); query.AppendLine("DROP TABLE IF EXISTS " + ret.Name + ";"); query.AppendLine("CREATE TABLE " + ret.Name + " ("); bool createAutoIncrement = !IsColumnUnique(rows, 0); string autoIncrementName = createAutoIncrement ? (singleRow.Columns.Any(c => c.Name == "id") ? "index" : "id") : ""; if (createAutoIncrement) { query.AppendLine(Indention + autoIncrementName + " INT AUTO_INCREMENT,"); } for (int i = 0; i < singleRow.Columns.Count; i++) { query.AppendLine(Indention + singleRow.Columns[i].Name + " " + GetSQLType(fieldTypes[i]) + ","); } if (createAutoIncrement) { query.AppendLine(Indention + "PRIMARY KEY (" + autoIncrementName + "),"); } else { query.AppendLine(Indention + "PRIMARY KEY (" + singleRow.Columns[0].Name + "),"); } for (int i = 1; i < singleRow.Columns.Count; i++) { if (singleRow.Columns[i].Name.EndsWith("ID")) { query.AppendLine(Indention + "INDEX " + singleRow.Columns[i].Name + " (" + singleRow.Columns[i].Name + "),"); } } if (query[query.Length - 1] == '\n' && query[query.Length - 2] == '\r' && query[query.Length - 3] == ',') { query.Remove(query.Length - 3, 1); } query.AppendLine(");"); ret.CreationQuery = query.ToString(); return(ret); }