Exemple #1
0
        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);
            }
        }
Exemple #2
0
        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);
            }
        }