public NetworkPayloadWriter WritePacket(IMessage message, Connection connection) { NetworkPayloadWriter npw = new NetworkPayloadWriter(connection); WritePacket(message, npw); return(npw); }
public void Encrypt(NetworkPayloadWriter npw) { lock (locky) { npw.vStream.Position = connection.HEADER_SIZE; CryptoStream CryptoStream = new CryptoStream(npw.vStream, Encryptor, CryptoStreamMode.Write); CryptoStream.Write(npw.GetBuffer(), connection.HEADER_SIZE, npw.Length - connection.HEADER_SIZE); CryptoStream.FlushFinalBlock(); } }
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 void SendMessage(IPeerMessage message) { if (!Connected) { return; } message.ConnectionId = this.ConnectionId; Connection conn = _client.Connection; NetworkPayloadWriter temp = message.WritePacket(message, conn); message.RawSize = temp.Length - _client.Connection.HEADER_SIZE; //apply compression, encryption, masks here conn.SendPayload(temp, conn.messageHandler.GetMessageId(message.GetType()), PacketId.RootSocket_Payload, false, null, null, VirtualIpInt); }
/// <summary> /// /// </summary> /// <param name="npw">The input data</param> /// <param name="Data">The data that is being cached</param> /// <returns>Is data cached</returns> public unsafe uint Write(NetworkPayloadWriter npw, ref byte[] Data) { byte[] payload = npw.GetBuffer(); uint UsedBytes = (uint)connection.HEADER_SIZE; Data = new byte[payload.Length + 5000]; //+5kb space Array.Copy(payload, Data, connection.HEADER_SIZE); //copy SSP header int length = (npw.Length - connection.HEADER_SIZE); int loops = (int)Math.Ceiling((double)length / 4D); fixed(byte *tempPtr = &(payload[connection.HEADER_SIZE]), dataPtr = &(Data[connection.HEADER_SIZE + 4])) { if ((npw.Length - connection.HEADER_SIZE) > 0) { uint *payloadPtr = (uint *)tempPtr; byte *DataPtr = (byte *)dataPtr; for (int i = 0; i < loops; i++) { if (UsedBytes > payload.Length) { //stop caching Flush(); return(0); } CacheInfo info = new CacheInfo(payloadPtr); CacheInfo temp = null; int ListIndex = 0; if (TryGetCacheInfo(ref temp, info.Hash, ref ListIndex)) { //read from cache temp.UseCount++; //check index size for write if (info.CacheIndex > 254) { UsedBytes += 3; *DataPtr = (byte)CacheType.ReadFromCacheBig; DataPtr[1] = (byte)info.CacheIndex; DataPtr[2] = (byte)(info.CacheIndex >> 8); DataPtr += 3; } else { UsedBytes += 3; *DataPtr = (byte)CacheType.ReadFromCacheSmall; DataPtr[1] = (byte)info.CacheIndex; DataPtr[2] = (byte)ListIndex; DataPtr += 3; } } else { //new data info.UseCount = 1; UsedBytes += 5; cache[info.CacheIndex].Add(info); *DataPtr = (byte)CacheType.NewData; *(uint *)(DataPtr + 1) = info.Hash; UsedMemory += CacheInfoSize; DataPtr += 5; } payloadPtr++; } } *(uint *)(dataPtr - 4) = (uint)(npw.Length - connection.HEADER_SIZE); } Flush(); return(UsedBytes); }
/// <summary> /// This method gets triggered if any data was going to be send /// </summary> /// <param name="data">The Data</param> /// <param name="Offset">The index of where the data starts</param> /// <param name="Length">The length of data</param> public abstract void onSendData(ref NetworkPayloadWriter npw);
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); } }