//Uncompress and process update private static void ProcessUnreliableClientUpdate(Session MySession, List <byte> MyPacket) { //Get Unreliable length UnreliableLength = MyPacket[0]; //Get Message # we are acknowledging XorMessage = (ushort)(MyPacket[2] << 8 | MyPacket[1]); //Get xor byte /Technically not needed...? Tells us what message to xor with but that should be the last message we xor'd... right? XorByte = MyPacket[3]; //Remove read bytes MyPacket.RemoveRange(0, 4); //This means that this is a deprecated packet that may of got lost on the way, base xor is behind current basexor //Let's not bother to even process it if (MySession.Channel40Base.ThisMessagenumber > (XorMessage - XorByte)) { //clear packet MyPacket.Clear(); return; } //Uncompress the packet Compression.UncompressUnreliable(MyPacket, UnreliableLength); //First 0x4029 from client if (XorByte == 0) { MySession.MyCharacter.World = MyPacket[0]; //This should match what we have stored for the character? Let's verify this? MySession.MyCharacter.XCoord = ConvertXZ(Get3ByteInt(MyPacket.GetRange(1, 3))); MySession.MyCharacter.YCoord = ConvertY(Get3ByteInt(MyPacket.GetRange(4, 3))); MySession.MyCharacter.ZCoord = ConvertXZ(Get3ByteInt(MyPacket.GetRange(7, 3))); //Skip 12 bytes... MySession.MyCharacter.Facing = ConvertFacing(MyPacket[22]); //Skip 12 bytes... MySession.MyCharacter.Animation = (short)(GetShort(MyPacket.GetRange(35, 2))); MySession.MyCharacter.Target = Get4ByteInt(MyPacket.GetRange(37, 4)); //Indicates character is appearing on screen/in world MySession.InGame = true; //Add xor base message to our list to track MySession.Channel40Base = new Message(XorMessage, MyPacket); //Should we generate a C9 here? List <byte> MyObject = Compression.CompressUnreliable(new List <byte>(ObjectUpdate.GatherObjectUpdate(MySession.MyCharacter, MySession.sessionIDUp))); MyObject.Insert(0, 0); MyObject.InsertRange(0, BitConverter.GetBytes(MySession.Channel0Message)); MyObject.Insert(0, 0xC9); MyObject.Insert(0, 0); //Add 0 on to end to denote end of this channel MyObject.Add(0); lock (MySession.SessionMessages) { MySession.SessionMessages.AddRange(MyObject); } MyObject.Clear(); } //Following client updates MySession.Channel40Base.ThisMessage //Lots of xor'ing... else { MySession.MyCharacter.World = (byte)(MySession.Channel40Base.ThisMessage[0] ^ MyPacket[0]); //This should match what we have stored for the character? Let's verify this? MySession.MyCharacter.XCoord = ConvertXZ(Get3ByteIntXOR((byte)(MySession.Channel40Base.ThisMessage[1] ^ MyPacket[1]), (byte)(MySession.Channel40Base.ThisMessage[2] ^ MyPacket[2]), (byte)(MySession.Channel40Base.ThisMessage[3] ^ MyPacket[3]))); MySession.MyCharacter.YCoord = ConvertY(Get3ByteIntXOR((byte)(MySession.Channel40Base.ThisMessage[4] ^ MyPacket[4]), (byte)(MySession.Channel40Base.ThisMessage[5] ^ MyPacket[5]), (byte)(MySession.Channel40Base.ThisMessage[6] ^ MyPacket[6]))); MySession.MyCharacter.ZCoord = ConvertXZ(Get3ByteIntXOR((byte)(MySession.Channel40Base.ThisMessage[7] ^ MyPacket[7]), (byte)(MySession.Channel40Base.ThisMessage[8] ^ MyPacket[8]), (byte)(MySession.Channel40Base.ThisMessage[9] ^ MyPacket[9]))); //Skip 12 bytes... MySession.MyCharacter.Facing = ConvertFacing((byte)(MySession.Channel40Base.ThisMessage[22] ^ MyPacket[22])); //Skip 12 bytes... MySession.MyCharacter.Animation = (short)(GetShortXOR((byte)(MySession.Channel40Base.ThisMessage[35] ^ MyPacket[35]), (byte)(MySession.Channel40Base.ThisMessage[36] ^ MyPacket[36]))); MySession.MyCharacter.Target = Get4ByteIntXOR((byte)(MySession.Channel40Base.ThisMessage[37] ^ MyPacket[37]), (byte)(MySession.Channel40Base.ThisMessage[38] ^ MyPacket[38]), (byte)(MySession.Channel40Base.ThisMessage[39] ^ MyPacket[39]), (byte)(MySession.Channel40Base.ThisMessage[40] ^ MyPacket[40])); //Means client has started a new basemessage, follow suit if (MySession.Channel40Base.ThisMessagenumber < (XorMessage - XorByte)) { //Grab new base message to xor against Message NewBaseMessage = MySession.Channel40BaseList.Find(i => i.ThisMessagenumber == (XorMessage - XorByte)); //Add our new xor'd base message and start over MySession.Channel40Base = new Message(XorMessage, GetArrayXOR(NewBaseMessage.ThisMessage, MyPacket)); //Remove all other possible base messages MySession.Channel40BaseList.Clear(); } //Means update is based off same xor base else if (MySession.Channel40Base.ThisMessagenumber == (XorMessage - XorByte)) { MySession.Channel40BaseList.Add(new Message(XorMessage, GetArrayXOR(MySession.Channel40Base.ThisMessage, MyPacket))); } } //Let outbound rdpreport know to include this to outbound ack's //This is purely as inbetween for message ack's MySession.Channel40Message = XorMessage; MySession.Channel40Ack = true; MyPacket.Clear(); }