public void WritePacket(IMessage message, NetworkPayloadWriter npw) { //if (connection.messageHandler.SendCache.CacheMessage(npw, message)) // return; FieldInfo[] fields = message.GetType().GetFields(); for (int i = 0; i < fields.Length; i++) { object obj = fields[i].GetValue(message); Type type = (obj == null ? null : obj.GetType()); npw.WriteObject(obj); } }
public unsafe bool CacheMessage(NetworkPayloadWriter npw, IMessage message) { lock (Messages) { uint Id = MessageHandler.GetMessageId(message.GetType()); IMessage CachedMessage = null; npw.WriteBool(false); if (!Messages.TryGetValue(Id, out CachedMessage)) { Messages.Add(Id, (IMessage)Activator.CreateInstance(message.GetType())); FieldInfo[] tmpFields = message.GetType().GetFields(); for (int i = 0; i < tmpFields.Length; i++) { object obj = tmpFields[i].GetValue(message); Type type = (obj == null ? null : obj.GetType()); npw.WriteObject(obj); } return(false); } FieldInfo[] fields = message.GetType().GetFields(); FieldInfo[] CachedFields = CachedMessage.GetType().GetFields(); for (int i = 0; i < fields.Length; i++) { object obj = fields[i].GetValue(message); object cached = CachedFields[i].GetValue(CachedMessage); Type type = (obj == null ? null : obj.GetType()); Type cacheType = (cached == null ? null : cached.GetType()); //set new value in cache CachedFields[i].SetValue(CachedMessage, obj); if (obj == null) { npw.WriteByte((byte)MessageCacheType.NULL); continue; } MessageCacheType CacheType = MessageCacheType.NotUpdated; long pos = npw.vStream.Position; npw.WriteByte((byte)CacheType); if (type == typeof(byte)) { if (cached != null) { if ((byte)obj != (byte)cached) { npw.WriteByte((byte)obj); CacheType = MessageCacheType.Byte; } } else { npw.WriteByte((byte)obj); CacheType = MessageCacheType.Byte; } } if (type == typeof(byte[])) { //can be optimized ALOT by using cache for this too //by only uploading the changed bytes byte[] objBytes = (byte[])obj; if (cached != null) { byte[] cachedBytes = (byte[])cached; if (objBytes.Length == cachedBytes.Length) { fixed(byte *ptr1 = objBytes, ptr2 = cachedBytes) { if (NativeMethods.memcmp(ptr1, ptr2, (uint)objBytes.Length) != 0) { CacheType = MessageCacheType.ByteArray; npw.WriteUInteger((uint)objBytes.Length); npw.WriteBytes(objBytes); } } } else { CacheType = MessageCacheType.ByteArray; npw.WriteUInteger((uint)objBytes.Length); npw.WriteBytes(objBytes); } } else { CacheType = MessageCacheType.ByteArray; npw.WriteUInteger((uint)objBytes.Length); npw.WriteBytes(objBytes); } } else if (type == typeof(bool)) { if (cached != null) { if ((bool)obj != (bool)cached) { npw.WriteBool((bool)obj); CacheType = MessageCacheType.Bool; } } else { npw.WriteBool((bool)obj); CacheType = MessageCacheType.Bool; } } else if (type == typeof(short)) { if (cached != null) { if ((short)obj != (short)cached) { npw.WriteShort((short)obj); CacheType = MessageCacheType.Short; } } else { npw.WriteShort((short)obj); CacheType = MessageCacheType.Short; } } else if (type == typeof(ushort)) { if (cached != null) { if ((ushort)obj != (ushort)cached) { npw.WriteUShort((ushort)obj); CacheType = MessageCacheType.UShort; } } else { npw.WriteUShort((ushort)obj); CacheType = MessageCacheType.UShort; } } else if (type == typeof(int)) { if (cached != null) { if ((int)obj != (int)cached) { npw.WriteInteger((int)obj); CacheType = MessageCacheType.Integer; } } else { npw.WriteInteger((int)obj); CacheType = MessageCacheType.Integer; } } else if (type == typeof(uint)) { if (cached != null) { if ((uint)obj != (uint)cached) { npw.WriteUInteger((uint)obj); CacheType = MessageCacheType.UInteger; } } else { npw.WriteUInteger((uint)obj); CacheType = MessageCacheType.UInteger; } } else if (type == typeof(decimal)) { if (cached != null) { if ((decimal)obj != (decimal)cached) { npw.WriteDecimal((decimal)obj); CacheType = MessageCacheType.Decimal; } } else { npw.WriteDecimal((decimal)obj); CacheType = MessageCacheType.Decimal; } } else if (type == typeof(double)) { if (cached != null) { if ((double)obj != (double)cached) { npw.WriteDouble((double)obj); CacheType = MessageCacheType.Double; } } else { npw.WriteDouble((double)obj); CacheType = MessageCacheType.Double; } } else if (type == typeof(float)) { if (cached != null) { if ((float)obj != (float)cached) { npw.WriteFloat((float)obj); CacheType = MessageCacheType.Float; } } else { npw.WriteFloat((float)obj); CacheType = MessageCacheType.Float; } } else if (type == typeof(long)) { if (cached != null) { if ((long)obj != (long)cached) { npw.WriteLong((long)obj); CacheType = MessageCacheType.Long; } } else { npw.WriteLong((long)obj); CacheType = MessageCacheType.Long; } } else if (type == typeof(ulong)) { if (cached != null) { if ((ulong)obj != (ulong)cached) { npw.WriteULong((ulong)obj); CacheType = MessageCacheType.ULong; } } else { npw.WriteULong((ulong)obj); CacheType = MessageCacheType.ULong; } } else if (type == typeof(string)) { if (cached != null) { if ((string)obj != (string)cached) { npw.WriteString((string)obj); CacheType = MessageCacheType.String; } } else { npw.WriteString((string)obj); CacheType = MessageCacheType.String; } } else { //serialize both objects and see at the bytes if they're different if (cached != null) { using (MemoryStream ms = new MemoryStream()) using (MemoryStream CacheMS = new MemoryStream()) { BinaryFormatter bf = new BinaryFormatter(); bf.Serialize(ms, obj); bf.Serialize(CacheMS, cached); if (ms.Length == CacheMS.Length) { fixed(byte *ptr1 = ms.GetBuffer(), ptr2 = CacheMS.GetBuffer()) { if (NativeMethods.memcmp(ptr1, ptr2, (uint)ms.Length) != 0) { CacheType = MessageCacheType.OtherObject; npw.WriteObject(obj); } } } else { CacheType = MessageCacheType.OtherObject; npw.WriteObject(obj); } } } else { CacheType = MessageCacheType.OtherObject; npw.WriteObject(obj); } } if (CacheType != MessageCacheType.NotUpdated) { long oldPos = npw.vStream.Position; npw.vStream.Position = pos; npw.WriteByte((byte)CacheType); npw.vStream.Position = oldPos; //jump back where we left } } npw.ResetPosition(); npw.WriteBool(true); //cached=true return(true); } }