예제 #1
0
 public static ZonePacket?TryParse(byte[] rawData, Int32 secureKey)
 {
     try
     {
         return(ZonePacket.Parse(ref rawData, secureKey));
     }
     catch
     {
         return(null);
     }
 }
예제 #2
0
        public byte[] GetBytes(Int32 secureKey)
        {
            var memoryStream = new MemoryStream();

            memoryStream.Write(BitConverter.GetBytes(Signature), 0, 4);
            memoryStream.Write(BitConverter.GetBytes(UnionType), 0, 4);
            memoryStream.Write(BitConverter.GetBytes(SecureKey), 0, 4);
            memoryStream.Write(BitConverter.GetBytes(SequenceID), 0, 4);
            byte[] packetBytes = memoryStream.ToArray();

            ZonePacket.xorBytes(ref packetBytes, ZoneClient.DEFAULT_SECURE_KEY);
            return(packetBytes);
        }
예제 #3
0
        public static IZonePacket FromMessage(MessageServer message, ZoneClient zoneClientState)
        {
            Int32  secureKey  = zoneClientState.SecureKey;
            UInt32 sequenceID = zoneClientState.SequenceID++;

            var messageBytes  = message.GetBytes();
            var newZonePacket = new ZonePacket();

            newZonePacket.Signature  = ZONE_SIGNATURE;
            newZonePacket.Size       = messageBytes.Length;
            newZonePacket.SequenceID = sequenceID;
            newZonePacket.CRC        = calculateCRC(messageBytes);
            newZonePacket.Data       = message.GetBytes();
            return(newZonePacket);
        }
예제 #4
0
 public CRCMismatchException(ZonePacket ParsedPacket, Int32 ComputedCRC)
 {
     this.ParsedPacket = ParsedPacket;
     this.ComputedCRC  = ComputedCRC;
 }
예제 #5
0
        public static ZonePacket Parse(ref byte[] rawData, Int32 secureKey)
        {
            if (rawData.Length < 16)
            {
                throw new NotEnoughBytesException();
            }

            xorBytes(ref rawData, secureKey);

            var parsedPacket = new ZonePacket();

            parsedPacket.Signature  = BitConverter.ToInt32(rawData, 0);
            parsedPacket.Size       = BitConverter.ToInt32(rawData, 4);
            parsedPacket.SequenceID = BitConverter.ToUInt32(rawData, 8);
            parsedPacket.CRC        = BitConverter.ToInt32(rawData, 12);

            parsedPacket.Data = new byte[parsedPacket.Size];
            if (parsedPacket.Data.Length > rawData.Length - 16)
            {
                throw new NotEnoughBytesException();
                // not enough bytes to parse message. This can happen. What do to?
            }
            else
            {
                Array.Copy(rawData, 16, parsedPacket.Data, 0, parsedPacket.Data.Length);

                if (rawData.Length - (parsedPacket.Size + 16) > 0)
                {
                    // This means the packets were nagled, and the key was applied to ending bytes unnecessarily
                    xorBytesFixTail(ref parsedPacket.Data, secureKey);
                }
            }
            // remove from rawData the parsed ZonePacket
            Array.Reverse(rawData);
            Array.Resize(ref rawData, rawData.Length - (parsedPacket.Size + 16));
            Array.Reverse(rawData);
            xorBytes(ref rawData, secureKey);

            // Check CRC
            Int32 computedCRC = calculateCRC(parsedPacket.Data);

            if (computedCRC != parsedPacket.CRC)
            {
                // this might mean the key was applied to the ending bytes unnecessarily. Let's attempt to fix it
                xorBytesFixTail(ref parsedPacket.Data, secureKey, 1);
                if (calculateCRC(parsedPacket.Data) != parsedPacket.CRC)
                {
                    xorBytesFixTail(ref parsedPacket.Data, secureKey, 1); // unapply xor because it wasn't effective
                    xorBytesFixTail(ref parsedPacket.Data, secureKey, 2);
                    if (calculateCRC(parsedPacket.Data) != parsedPacket.CRC)
                    {
                        xorBytesFixTail(ref parsedPacket.Data, secureKey, 2);
                        xorBytesFixTail(ref parsedPacket.Data, secureKey, 3);
                        if (calculateCRC(parsedPacket.Data) != parsedPacket.CRC)
                        {
                            xorBytesFixTail(ref parsedPacket.Data, secureKey, 3);
                            throw new CRCMismatchException(parsedPacket, computedCRC);
                        }
                    }
                }
            }

            return(parsedPacket);
        }