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)); }
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(); } }