public MaplePacket Read(DateTime pTransmitted, ushort pBuild, byte pLocale)
        {
            if (mCursor < 4)
            {
                return(null);
            }
            if (!mAES.ConfirmHeader(mBuffer, 0))
            {
                throw new Exception("Failed to confirm packet header");
            }

            ushort packetSize = mAES.GetHeaderLength(mBuffer, 0, pBuild == 255 && pLocale == 1);

            if (mCursor < (packetSize + 4))
            {
                return(null);
            }
            byte[] packetBuffer = new byte[packetSize];
            Buffer.BlockCopy(mBuffer, 4, packetBuffer, 0, packetSize);

            bool byteheader = false;

            if (pBuild == 40 && pLocale == 5)
            {
                // WvsBeta
                Decrypt(packetBuffer, pBuild, pLocale, TransformLocale.MCRYPTO);
                byteheader = true;
            }
            else if (pLocale == 1 && pBuild == 255)
            {
                // KMSB lol
                Decrypt(packetBuffer, pBuild, pLocale, TransformLocale.OLDEST_MCRYPTO);
                byteheader = true;
                // Still reset header.
                mAES.ShiftIVOld();
            }
            else if (pLocale == 1 || pLocale == 2)
            {
                // KMS / KMST
                Decrypt(packetBuffer, pBuild, pLocale, TransformLocale.SPECIAL);
            }
            else
            {
                // All others lol
                Decrypt(packetBuffer, pBuild, pLocale, TransformLocale.AES_MCRYPTO);
            }

            mCursor -= (packetSize + 4);
            if (mCursor > 0)
            {
                Buffer.BlockCopy(mBuffer, packetSize + 4, mBuffer, 0, mCursor);
            }
            ushort opcode;

            if (byteheader)
            {
                opcode = (ushort)(packetBuffer[0]);
                Buffer.BlockCopy(packetBuffer, 1, packetBuffer, 0, packetSize - 1);
                Array.Resize(ref packetBuffer, packetSize - 1);
            }
            else
            {
                opcode = (ushort)(packetBuffer[0] | (packetBuffer[1] << 8));
                Buffer.BlockCopy(packetBuffer, 2, packetBuffer, 0, packetSize - 2);
                Array.Resize(ref packetBuffer, packetSize - 2);
            }

            Definition definition = Config.Instance.GetDefinition(pBuild, pLocale, mOutbound, opcode);

            return(new MaplePacket(pTransmitted, mOutbound, pBuild, pLocale, opcode, definition == null ? "" : definition.Name, packetBuffer));
        }
Exemple #2
0
        private void Decrypt(byte[] pBuffer, TransformMethod pTransformLocale)
        {
            if ((pTransformLocale & TransformMethod.AES) != 0)
            {
                mAES.TransformAES(pBuffer);
            }

            if ((pTransformLocale & TransformMethod.MAPLE_CRYPTO) != 0)
            {
                for (int index1 = 1; index1 <= 6; ++index1)
                {
                    byte firstFeedback  = 0;
                    byte secondFeedback = 0;
                    byte length         = (byte)(pBuffer.Length & 0xFF);
                    if ((index1 % 2) == 0)
                    {
                        for (int index2 = 0; index2 < pBuffer.Length; ++index2)
                        {
                            byte temp = pBuffer[index2];
                            temp           -= 0x48;
                            temp            = (byte)(~temp);
                            temp            = RollLeft(temp, length & 0xFF);
                            secondFeedback  = temp;
                            temp           ^= firstFeedback;
                            firstFeedback   = secondFeedback;
                            temp           -= length;
                            temp            = RollRight(temp, 3);
                            pBuffer[index2] = temp;
                            --length;
                        }
                    }
                    else
                    {
                        for (int index2 = pBuffer.Length - 1; index2 >= 0; --index2)
                        {
                            byte temp = pBuffer[index2];
                            temp            = RollLeft(temp, 3);
                            temp           ^= 0x13;
                            secondFeedback  = temp;
                            temp           ^= firstFeedback;
                            firstFeedback   = secondFeedback;
                            temp           -= length;
                            temp            = RollRight(temp, 4);
                            pBuffer[index2] = temp;
                            --length;
                        }
                    }
                }
            }

            if ((pTransformLocale & TransformMethod.KMS_CRYPTO) != 0)
            {
                mAES.TransformKMS(pBuffer);
            }
            if ((pTransformLocale & TransformMethod.OLD_KMS_CRYPTO) != 0)
            {
                mAES.TransformOldKMS(pBuffer);
            }

            if ((pTransformLocale & TransformMethod.SHIFT_IV) != 0)
            {
                mAES.ShiftIV();
            }
            if ((pTransformLocale & TransformMethod.SHIFT_IV_OLD) != 0)
            {
                mAES.ShiftIVOld();
            }
        }