/// <summary> /// Prepares to read. /// </summary> /// <param name="xtea">The XTEA key.</param> /// <returns>Whether the stream is prepared to read.</returns> public bool PrepareToRead(Xtea xtea) { if (!Decrypt(xtea)) { return(false); } Position = 8; return(true); }
private byte[] Encrypt(uint[] keys, byte[] bytes) { int padding = bytes.Length % 8; if (padding > 0) { bytes = bytes.Combine(new byte[8 - padding]); } return(Xtea.Encrypt(bytes, 32, keys)); }
/// <summary> /// Called when [login message received]. /// </summary> /// <param name="result">The result.</param> private void OnLoginMessageReceived(IAsyncResult result) { LoginConnection connection = new LoginConnection(Xtea.Create()); connection.Authenticate += OnAuthenticate; connection.RequestLoginData += OnRequestedLoginData; connection.OnMessageReceived(result); _loginConnections.Add(connection); _loginListener.BeginAcceptSocket(OnLoginMessageReceived, _loginListener); }
/// <summary> /// Called when [game message received]. /// </summary> /// <param name="result">The result.</param> private void OnGameMessageReceived(IAsyncResult result) { GameConnection connection = new GameConnection(Xtea.Create(), _chatService, _creatureSpawnService, _tileService, _spellService, _commandService, _outfitService, _mountService); connection.Authenticate += OnAuthenticate; connection.LoggingIn += OnLoggingIn; connection.RequestOnlineTime += OnRequestOnlineTime; connection.RequestLightInfo += OnRequestLightInfo; connection.OnMessageReceived(result); _gameConnections.Add(connection); _gameListener.BeginAcceptSocket(OnGameMessageReceived, _gameListener); }
/// <summary> /// Prepares to send. /// </summary> /// <param name="xtea">The xtea.</param> /// <returns>Whether the message is prepared to send.</returns> public bool PrepareToSend(Xtea xtea) { // Must be before Xtea, because the packet Length is encrypted as well InsertPacketLength(); if (!Encrypt(xtea)) { return(false); } // Must be after Xtea, because takes the checksum of the encrypted packet InsertAdler32Checksum(); InsertTotalLength(); return(true); }
/// <inheritdoc /> /// <summary> /// Initializes a new instance of the <see cref="T:Tibia.Network.Login.LoginConnection" /> class. /// </summary> /// <param name="xtea">The XTEA key.</param> public LoginConnection(Xtea xtea) : base(xtea) { }
public bool XteaEncrypt(uint[] key) { return(Xtea.Encrypt(ref _buffer, ref _length, 2, key)); }
private bool XteaEncrypt(uint[] key) { return(Xtea.Encrypt(ref this.buffer, ref this.length, 2, key)); }
public bool XteaDecrypt(uint[] key) { return(Xtea.Decrypt(ref this.buffer, ref this.length, 2, key)); }
/// <summary> /// Initializes a new instance of the <see cref="NetworkMessage" /> class. /// </summary> /// <param name="xtea">The XTEA key.</param> /// <param name="startIndex">The start index.</param> public NetworkMessage(Xtea xtea, int startIndex) { Xtea = xtea; Reset(startIndex); }
/// <summary> /// Initializes a new instance of the <see cref="Connection" /> class. /// </summary> /// <param name="xtea">The XTEA key.</param> protected Connection(Xtea xtea) { Xtea = xtea; IsInTransaction = false; IncomingMessage = new NetworkMessage(xtea, 0); }
/// <summary> /// Processes files packed as type 2 (encrypted & compressed) /// </summary> /// <param name="packFilePath">Path to EPK file (name included)</param> /// <param name="saveFilesPath">Path to where the file should be saved (name not included)</param> /// <param name="item">Item from deserialized list</param> /// <param name="packKey">Pack XTEA key</param> /// <param name="hashMismatchFiles">Vector holding files with CRC mismatch</param> /// <param name="errorFiles">Vector holding files ignored</param> /// <returns></returns> public static int ProcessFileType2(string packFilePath, string saveFilesPath, IndexItem item, byte[] packKey, Action<ErrorItem, string> fileLoggingCallback) { int valueToReturn = 0; byte[] fileHeaderBuffer = IOHelper.ReadFileOffsetToLength(packFilePath, item.Offset, 16); // Read FourCC value var fourCc = new byte[4]; Array.Copy(fileHeaderBuffer, 0, fourCc, 0, 4); // Get sizes from header int encryptedSize = IOHelper.ReadIntFromArray(fileHeaderBuffer, 4, 4); int compressedSize = IOHelper.ReadIntFromArray(fileHeaderBuffer, 8, 4); int decompressedSize = IOHelper.ReadIntFromArray(fileHeaderBuffer, 12, 4); if (encryptedSize <= 0 || compressedSize <= 0 || decompressedSize <= 0) { fileLoggingCallback(new ErrorItem(item.Filename, "Invalid encrypted/compressed/decompressed size."), null); return 2; } #region Cap Check if (encryptedSize > 629145600) { fileLoggingCallback(new ErrorItem(item.Filename, String.Format("Max memory allocation reached, tried to allocate: {0} mb", Math.Round(encryptedSize / 1024.0 / 1024.0, 2))), null); return 2; } if (compressedSize > 629145600) { fileLoggingCallback(new ErrorItem(item.Filename, String.Format("Max memory allocation reached, tried to allocate: {0} mb", Math.Round(encryptedSize / 1024.0 / 1024.0, 2))), null); return 2; } if (decompressedSize > 629145600) { fileLoggingCallback(new ErrorItem(item.Filename, String.Format("Max memory allocation reached, tried to allocate: {0} mb", Math.Round(encryptedSize / 1024.0 / 1024.0, 2))), null); return 2; } #endregion // Is header correct? if (!fourCc.SequenceEqual(ConstantsBase.LzoFourCc)) { // Show error msg and cancel operation // AppLog.SendMessage(8, item.Filename, item.ParentFile); TODO fileLoggingCallback(new ErrorItem(item.Filename, String.Format("Invalid FourCC: {0}. Expected: {1} ({2})", BitConverter.ToString(fourCc), BitConverter.ToString(ConstantsBase.LzoFourCc), Encoding.ASCII.GetString(ConstantsBase.LzoFourCc))), ""); return 2; } // Get actual data byte[] rawDataBuffer = IOHelper.ReadFileOffsetToLength(packFilePath, item.Offset + 16, encryptedSize); // Take care of relative path and folders string path = DrivePointManager.RemoveDrivePoints((saveFilesPath + item.Filename).Replace("\\", "/")); // uh, I've found a bug. This should be changed... The program now detects new drive points, for example string foldersPath = path.Substring(0, path.LastIndexOf("/", StringComparison.Ordinal)); // Check if paths exist Directory.CreateDirectory(foldersPath); // Overwrite file TODO SAME AS TYPE 2 if (File.Exists(path)) { if (IOHelper.IsFileLocked(path)) { //WindowLog.LogOutputMessage(Log.LogId.FILE_OPENED_BY_EXTERNAL_PROCESS_LOG, args: path); TODO return 2; } File.Delete(path); } // Create encryption and encryption without header buffers var decryptedBuffer = new byte[encryptedSize]; var decryptedBufferWithoutHeader = new byte[encryptedSize - 4]; // It should never return false if (Xtea.Decrypt(packKey, rawDataBuffer, decryptedBuffer, (uint)encryptedSize) == false) { throw new Exception("INTERNAL ERROR - DECRYPTION FAILED"); } // Get header after decryption var headerAfterDecryption = new byte[4]; Array.Copy(decryptedBuffer, 0, headerAfterDecryption, 0, 4); // Was the encryption key correct? if (!headerAfterDecryption.SequenceEqual(ConstantsBase.LzoFourCc)) { // Send message and return error //WindowLog.LogOutputMessage(Log.LogId.DECRYPTION_FAILED_LOG, args: item.Filename); TODO fileLoggingCallback(new ErrorItem(item.Filename, String.Format("Invalid header after decryption: {0}. Expected: {1} ({2})", BitConverter.ToString(fourCc), BitConverter.ToString(ConstantsBase.LzoFourCc), Encoding.ASCII.GetString(ConstantsBase.LzoFourCc))), ""); valueToReturn = 2; } // Get actual decrypted data Array.Copy(decryptedBuffer, 4, decryptedBufferWithoutHeader, 0, decryptedBuffer.Length - 4); // Check hash if (!CompareCrcHashes(decryptedBufferWithoutHeader, item.CRCHash)) { // Log CRC mismatch // AppLog.SendMessage(2, item.Filename); fileLoggingCallback(null, item.Filename); valueToReturn = 1; } byte[] decompressedData = LzoHelper.DecompressData(decompressedSize, compressedSize, decryptedBufferWithoutHeader); // Write file File.WriteAllBytes(path, decompressedData); return valueToReturn; }
/// <summary> /// Buils EIX and EPK files /// </summary> /// <param name="list">Deserialized list</param> /// <param name="packFilePath">Path to EPK file, including the name</param> /// <param name="unpackedFilesPath">Path to unpacked files</param> /// <param name="indexKey">Index XTEA key</param> /// <param name="packKey">Pack XTEA key</param> /// <param name="errorLogCallBack"></param> /// <param name="progressCallback">Callback if progress updates are needed</param> /// <returns></returns> public static bool BuildIndexAndPackFiles( List<IndexItem> list, string packFilePath, string unpackedFilesPath, byte[] indexKey, byte[] packKey, Action<ErrorItem> errorLogCallBack, Action<int, int> progressCallback, Action fatalErrorCallback) { using (var fStream = new MemoryStream()) { packFilePath = packFilePath.Replace("\\", "/"); // Check if directory exists string directoryPath = packFilePath.Substring(0, packFilePath.LastIndexOf("/")); Directory.CreateDirectory(directoryPath); // Create stream to EPK file var epkStream = new FileStream(EterHelper.ReplaceWithEpkExt(packFilePath), FileMode.Create); // Size from header for each file int decompressedSize = 0; int compressedSize = 0; uint encryptedSize = 0; // File counter to index files int indexCount = 0; // Progress variables double actionProgress = 0; // FileOffset holder (EPK stream's length) int fileOffset = 0; // Write first header to EIX file fStream.Write(ConstantsBase.EterFourCc, 0, ConstantsBase.EterFourCc.Length); fStream.Write(BitConverter.GetBytes(2), 0, 4); fStream.Write(BitConverter.GetBytes(list.Count), 0, 4); try { foreach (IndexItem item in list) { // Loop through items var fileName = new byte[161]; var fileNameCrc = new byte[4]; //Index item's structure (totalizing 192 bytes) #region Byte Holders var fileIndex = new byte[4]; var realDataSize = new byte[4]; var dataSize = new byte[4]; var dataCrc = new byte[4]; var dataOffset = new byte[4]; var padding3B = new byte[3]; #endregion // Set all backslashs to forwards slashes item.Filename = item.Filename.Replace('\\', '/'); // Get raw data byte[] rawData = IOHelper.ReadFile(unpackedFilesPath + item.Filename); // Header sizees int encryptedFileSize = 0; int compressedFileSize = 0; int decompressedFileSize = 0; // Set real data & decompressed size to raw data's lenth realDataSize = BitConverter.GetBytes(rawData.Length); decompressedFileSize = rawData.Length; // Set fileoffset to actual stream's length fileOffset = (int)epkStream.Length; #region File Type Processing // Switch through the 3 possible cases switch (item.PackType) { case 0: // Write data to EPK stream epkStream.Write(rawData, 0, rawData.Length); // Set data size equal to raw data since no compression nor encrypted occured dataSize = BitConverter.GetBytes(rawData.Length); break; case 1: case 2: // Compress data byte[] compressedDataBuffer = LzoHelper.CompressData(rawData.Length, rawData); // Create buffer to hold header + compressedData byte[] compressedDataWithHeaderBuffer = new byte[compressedDataBuffer.Length + 4]; // Copy header and compressedData to previously created buffer Array.Copy(ConstantsBase.LzoFourCc, 0, compressedDataWithHeaderBuffer, 0, 4); Array.Copy(compressedDataBuffer, 0, compressedDataWithHeaderBuffer, 4, compressedDataBuffer.Length); // Set dataSize to compressedSize (since it assumes it's type 1) dataSize = BitConverter.GetBytes(compressedDataWithHeaderBuffer.Length + 16); // Set compressedSize compressedFileSize = compressedDataBuffer.Length; // If type 2 if (item.PackType == 2) { // Get encrypted size (ALWAYS the upper multiple) encryptedFileSize = GetUpperMultiple(compressedDataWithHeaderBuffer.Length); // Resize data to fit encryptedSize Array.Resize(ref compressedDataWithHeaderBuffer, encryptedFileSize); // Encrypt Data Xtea.Encrypt2(ref compressedDataWithHeaderBuffer, packKey); // Set dataSize to encryptedData + header dataSize = BitConverter.GetBytes(compressedDataWithHeaderBuffer.Length + 16); } // Write header of file to EPK stream epkStream.Write(ConstantsBase.LzoFourCc, 0, 4); epkStream.Write(BitConverter.GetBytes(encryptedFileSize), 0, 4); epkStream.Write(BitConverter.GetBytes(compressedFileSize), 0, 4); epkStream.Write(BitConverter.GetBytes(decompressedFileSize), 0, 4); // Write actual data epkStream.Write(compressedDataWithHeaderBuffer, 0, compressedDataWithHeaderBuffer.Length); break; } #endregion #region Building index file // Check if string replacment is needed string virtualPathFile = DrivePointManager.InsertDrivePoints(item.Filename); // Populate byte[] with data fileIndex = BitConverter.GetBytes(item.Index); byte[] fileNameTemp = Encoding.Default.GetBytes(virtualPathFile); fileNameCrc = CrcHelper.GetCrc32HashFromMemoryToByteArray(Encoding.Default.GetBytes(virtualPathFile)); realDataSize = (realDataSize == null) ? BitConverter.GetBytes(item.DiskSize) : realDataSize; dataSize = (dataSize == null) ? BitConverter.GetBytes(item.Size) : dataSize; dataCrc = CrcHelper.GetCrc32HashToByteArray(unpackedFilesPath + item.Filename); dataOffset = BitConverter.GetBytes(fileOffset); var compressedType = (byte)item.PackType; // Check if filename buffer is expectedSize if (fileNameTemp.Length != 161) { Array.Copy(fileNameTemp, 0, fileName, 0, fileNameTemp.Length); } // Write data to EIX's stream fStream.Write(fileIndex, 0, fileIndex.Length); fStream.Write(fileName, 0, 161); fStream.Write(padding3B, 0, padding3B.Length); fStream.Write(fileNameCrc.Reverse().ToArray(), 0, fileNameCrc.Length); fStream.Write(realDataSize, 0, realDataSize.Length); fStream.Write(dataSize, 0, dataSize.Length); fStream.Write(dataCrc.Reverse().ToArray(), 0, dataCrc.Length); fStream.Write(dataOffset, 0, dataOffset.Length); fStream.WriteByte(compressedType); fStream.Write(padding3B, 0, padding3B.Length); indexCount++; #endregion // Update progress actionProgress = (indexCount / (double)list.Count * 100.0); progressCallback(0, (int)actionProgress); } } catch (Exception ex) { //WindowLog.LogExceptioToFile(ex.ToString()); TODO fatalErrorCallback(); throw; } // Assign current stream's lenght to decmopressedSize decompressedSize = (int)fStream.Length; // Buffer to hold compressedData byte[] compressedData = LzoHelper.CompressData(decompressedSize, fStream.ToArray()); // Buffer with compressedData + MCOZ header byte[] compressedDataWithHeader = new byte[compressedData.Length + 4]; // Copy Header to buffer Array.Copy(ConstantsBase.LzoFourCc, 0, compressedDataWithHeader, 0, 4); // Copy data to buffer Array.Copy(compressedData, 0, compressedDataWithHeader, 4, compressedData.Length); // Save compressedSize compressedSize = compressedData.Length; // Save encryptedSize (round to upper multiple) encryptedSize = (uint)GetUpperMultiple(compressedSize + 4); // Resize array to fit new size Array.Resize(ref compressedDataWithHeader, (int)encryptedSize); // Encrypt data Xtea.Encrypt2(ref compressedDataWithHeader, indexKey); // Create buffer to hold final data + header var outputFileBuffer = new byte[compressedDataWithHeader.Length + 16]; // Copy header to buffer Array.Copy(ConstantsBase.LzoFourCc, 0, outputFileBuffer, 0, 4); Array.Copy(BitConverter.GetBytes(encryptedSize), 0, outputFileBuffer, 4, 4); Array.Copy(BitConverter.GetBytes(compressedSize), 0, outputFileBuffer, 8, 4); Array.Copy(BitConverter.GetBytes(decompressedSize), 0, outputFileBuffer, 12, 4); // Copy data to buffer Array.Copy(compressedDataWithHeader, 0, outputFileBuffer, 16, compressedDataWithHeader.Length); // Close stream epkStream.Close(); epkStream.Dispose(); // Save file File.WriteAllBytes(EterHelper.ReplaceWithEixExt(packFilePath), outputFileBuffer); return true; } }
/// <summary> /// Normalize index data /// </summary> /// <param name="filePath">File path</param> /// <param name="indexKey">Index XTEA key</param> /// <returns></returns> public static byte[] NormalizeIndexFile(string filePath, byte[] indexKey) { //File exists? if (!File.Exists(filePath)) { //WindowLog.LogOutputMessage(Log.LogId.FILE_NOT_FOUND, args: filePath); TODO throw new FileNotFoundException(filePath); } //Read file byte[] rawFileBuffer = IOHelper.ReadFile(filePath); if (rawFileBuffer.Length < 16) return null; //Read header value var headerCCBuffer = new byte[4]; Array.Copy(rawFileBuffer, 0, headerCCBuffer, 0, 4); int encryptedSize = IOHelper.ReadIntFromArray(rawFileBuffer, 4, 4); int compressedSize = IOHelper.ReadIntFromArray(rawFileBuffer, 8, 4); int decompressedSize = IOHelper.ReadIntFromArray(rawFileBuffer, 12, 4); //Preparing buffer to decrypt var dataPtr = new byte[rawFileBuffer.Length - 16]; Array.Copy(rawFileBuffer, 16, dataPtr, 0, rawFileBuffer.Length - 16); var decryptedBuffer = new byte[encryptedSize]; //Decryption if (Xtea.Decrypt(indexKey, dataPtr, decryptedBuffer, (uint)encryptedSize)) { if (decryptedBuffer.Length < 8) return null; //Decryption failed? Array.Copy(decryptedBuffer, 0, headerCCBuffer, 0, 4); if (!headerCCBuffer.SequenceEqual(ConstantsBase.LzoFourCc)) { throw new ErrorReadingIndexException("Wrong index decryption key"); } //Create buffer without header byte[] afterDecryptionBuffer = new byte[decryptedBuffer.Length - 4]; Array.Copy(decryptedBuffer, 4, afterDecryptionBuffer, 0, decryptedBuffer.Length - 4); //Decompress data byte[] normalizedFileBuffer = LzoHelper.DecompressData(decompressedSize, compressedSize, afterDecryptionBuffer); Array.Copy(normalizedFileBuffer, 0, headerCCBuffer, 0, 4); //Decompression failed? if (!headerCCBuffer.SequenceEqual(ConstantsBase.EterFourCc)) { throw new ErrorReadingIndexException("An internal error occured when decompressing"); } //Return normalized data return normalizedFileBuffer; } //Should NEVER happen return null; }
/// <summary> /// Encrypts the buffer with the specified XTEA key. /// </summary> /// <param name="xtea">The XTEA key.</param> /// <returns>Whether the encryption is completed successfully.</returns> public bool Encrypt(Xtea xtea) { return(Xtea.Encrypt(ref _buffer, ref _length, 6, xtea.Key)); }
protected override void OnReceived(byte[] body) { ByteArrayArrayStream stream = new ByteArrayArrayStream(body); ByteArrayStreamReader reader = new ByteArrayStreamReader(stream); try { if (Adler32.Generate(body, 4) == reader.ReadUInt()) { if (Keys == null) { Rsa.DecryptAndReplace(body, 9); } else { Xtea.DecryptAndReplace(body, 4, 32, Keys); stream.Seek(Origin.Current, 2); } Command command = null; switch (reader.ReadByte()) { case 0x0A: { var packet = server.PacketsFactory.Create <SelectedCharacterIncomingPacket>(reader); command = new LogInCommand(this, packet); } break; case 0x14: command = new LogOutCommand(Client.Player); break; case 0x1E: command = new PongCommand(Client.Player); break; case 0x64: { var packet = server.PacketsFactory.Create <WalkToIncomingPacket>(reader); command = new WalkToKnownPathCommand(Client.Player, packet.MoveDirections); } break; case 0x65: command = new WalkCommand(Client.Player, MoveDirection.North); break; case 0x66: command = new WalkCommand(Client.Player, MoveDirection.East); break; case 0x67: command = new WalkCommand(Client.Player, MoveDirection.South); break; case 0x68: command = new WalkCommand(Client.Player, MoveDirection.West); break; case 0x69: command = new StopWalkCommand(Client.Player); break; case 0x6A: command = new WalkCommand(Client.Player, MoveDirection.NorthEast); break; case 0x6B: command = new WalkCommand(Client.Player, MoveDirection.SouthEast); break; case 0x6C: command = new WalkCommand(Client.Player, MoveDirection.SouthWest); break; case 0x6D: command = new WalkCommand(Client.Player, MoveDirection.NorthWest); break; case 0x6F: command = new TurnCommand(Client.Player, Direction.North); break; case 0x70: command = new TurnCommand(Client.Player, Direction.East); break; case 0x71: command = new TurnCommand(Client.Player, Direction.South); break; case 0x72: command = new TurnCommand(Client.Player, Direction.West); break; case 0x78: { var packet = server.PacketsFactory.Create <MoveItemIncomingPacket>(reader); Position fromPosition = new Position(packet.FromX, packet.FromY, packet.FromZ); Position toPosition = new Position(packet.ToX, packet.ToY, packet.ToZ); if (fromPosition.IsContainer) { if (toPosition.IsContainer) { command = new MoveItemFromContainerToContainerCommand(Client.Player, fromPosition.ContainerId, fromPosition.ContainerIndex, packet.FromItemId, toPosition.ContainerId, toPosition.ContainerIndex, packet.Count); } else if (toPosition.IsInventory) { command = new MoveItemFromContainerToInventoryCommand(Client.Player, fromPosition.ContainerId, fromPosition.ContainerIndex, packet.FromItemId, toPosition.InventoryIndex, packet.Count); } else { command = new MoveItemFromContainerToTileCommand(Client.Player, fromPosition.ContainerId, fromPosition.ContainerIndex, packet.FromItemId, toPosition, packet.Count); } } else if (fromPosition.IsInventory) { if (toPosition.IsContainer) { command = new MoveItemFromInventoryToContainerCommand(Client.Player, fromPosition.InventoryIndex, packet.FromItemId, toPosition.ContainerId, toPosition.ContainerIndex, packet.Count); } else if (toPosition.IsInventory) { command = new MoveItemFromInventoryToInventoryCommand(Client.Player, fromPosition.InventoryIndex, packet.FromItemId, toPosition.InventoryIndex, packet.Count); } else { command = new MoveItemFromInventoryToTileCommand(Client.Player, fromPosition.InventoryIndex, packet.FromItemId, toPosition, packet.Count); } } else { if (toPosition.IsContainer) { command = new MoveItemFromTileToContainerCommand(Client.Player, fromPosition, packet.FromIndex, packet.FromItemId, toPosition.ContainerId, toPosition.ContainerIndex, packet.Count); } else if (toPosition.IsInventory) { command = new MoveItemFromTileToInventoryCommand(Client.Player, fromPosition, packet.FromIndex, packet.FromItemId, toPosition.InventoryIndex, packet.Count); } else { command = new MoveItemFromTileToTileCommand(Client.Player, fromPosition, packet.FromIndex, packet.FromItemId, toPosition, packet.Count); } } } break; case 0x79: { var packet = server.PacketsFactory.Create <LookItemNpcTradeIncommingPacket>(reader); command = new LookFromNpcTradeCommand(Client.Player, packet.ItemId, packet.Type); } break; case 0x7A: { var packet = server.PacketsFactory.Create <BuyNpcTradeIncommingPacket>(reader); command = new BuyNpcTradeCommand(Client.Player, packet); } break; case 0x7B: { var packet = server.PacketsFactory.Create <SellNpcTradeIncommingPacket>(reader); command = new SellNpcTradeCommand(Client.Player, packet); } break; case 0x7C: command = new CloseNpcTradeCommand(Client.Player); break; case 0x7D: { var packet = server.PacketsFactory.Create <TradeWithIncommingPacket>(reader); Position fromPosition = new Position(packet.X, packet.Y, packet.Z); if (fromPosition.IsContainer) { command = new TradeWithFromContainerCommand(Client.Player, fromPosition.ContainerId, fromPosition.ContainerIndex, packet.ItemId, packet.CreatureId); } else if (fromPosition.IsInventory) { command = new TradeWithFromInventoryCommand(Client.Player, fromPosition.InventoryIndex, packet.ItemId, packet.CreatureId); } else { command = new TradeWithFromTileCommand(Client.Player, fromPosition, packet.Index, packet.ItemId, packet.CreatureId); } } break; case 0x7E: { var packet = server.PacketsFactory.Create <LookItemTradeIncommingPacket>(reader); command = new LookFromTradeCommand(Client.Player, packet.WindowId, packet.Index); } break; case 0x7F: command = new AcceptTradeCommand(Client.Player); break; case 0x80: command = new CancelTradeCommand(Client.Player); break; case 0x82: { var packet = server.PacketsFactory.Create <UseItemIncomingPacket>(reader); Position fromPosition = new Position(packet.X, packet.Y, packet.Z); if (fromPosition.IsContainer) { command = new UseItemFromContainerCommand(Client.Player, fromPosition.ContainerId, fromPosition.ContainerIndex, packet.ItemId, packet.ContainerId); } else if (fromPosition.IsInventory) { command = new UseItemFromInventoryCommand(Client.Player, fromPosition.InventoryIndex, packet.ItemId); } else { command = new UseItemFromTileCommand(Client.Player, fromPosition, packet.Index, packet.ItemId); } } break; case 0x83: { var packet = server.PacketsFactory.Create <UseItemWithItemIncomingPacket>(reader); Position fromPosition = new Position(packet.FromX, packet.FromY, packet.FromZ); Position toPosition = new Position(packet.ToX, packet.ToY, packet.ToZ); if (fromPosition.IsContainer) { if (toPosition.IsContainer) { command = new UseItemWithItemFromContainerToContainerCommand(Client.Player, fromPosition.ContainerId, fromPosition.ContainerIndex, packet.FromItemId, toPosition.ContainerId, toPosition.ContainerIndex, packet.ToItemId); } else if (toPosition.IsInventory) { command = new UseItemWithItemFromContainerToInventoryCommand(Client.Player, fromPosition.ContainerId, fromPosition.ContainerIndex, packet.FromItemId, toPosition.InventoryIndex, packet.ToItemId); } else { command = new UseItemWithItemFromContainerToTileCommand(Client.Player, fromPosition.ContainerId, fromPosition.ContainerIndex, packet.FromItemId, toPosition, packet.ToIndex, packet.ToItemId); } } else if (fromPosition.IsInventory) { if (toPosition.IsContainer) { command = new UseItemWithItemFromInventoryToContainerCommand(Client.Player, fromPosition.InventoryIndex, packet.FromItemId, toPosition.ContainerId, toPosition.ContainerIndex, packet.ToItemId); } else if (toPosition.IsInventory) { command = new UseItemWithItemFromInventoryToInventoryCommand(Client.Player, fromPosition.InventoryIndex, packet.FromItemId, toPosition.InventoryIndex, packet.ToItemId); } else { command = new UseItemWithItemFromInventoryToTileCommand(Client.Player, fromPosition.InventoryIndex, packet.FromItemId, toPosition, packet.ToIndex, packet.ToItemId); } } else { if (toPosition.IsContainer) { command = new UseItemWithItemFromTileToContainerCommand(Client.Player, fromPosition, packet.FromIndex, packet.FromItemId, toPosition.ContainerId, toPosition.ContainerIndex, packet.ToItemId); } else if (toPosition.IsInventory) { command = new UseItemWithItemFromTileToInventoryCommand(Client.Player, fromPosition, packet.FromIndex, packet.FromItemId, toPosition.InventoryIndex, packet.ToItemId); } else { command = new UseItemWithItemFromTileToTileCommand(Client.Player, fromPosition, packet.FromIndex, packet.FromItemId, toPosition, packet.ToIndex, packet.ToItemId); } } } break; case 0x84: { var packet = server.PacketsFactory.Create <UseItemWithCreatureIncomingPacket>(reader); Position fromPosition = new Position(packet.X, packet.Y, packet.Z); if (fromPosition.IsContainer) { command = new UseItemWithCreatureFromContainerCommand(Client.Player, fromPosition.ContainerId, fromPosition.ContainerIndex, packet.ItemId, packet.CreatureId); } else if (fromPosition.IsInventory) { command = new UseItemWithCreatureFromInventoryCommand(Client.Player, fromPosition.InventoryIndex, packet.ItemId, packet.CreatureId); } else { command = new UseItemWithCreatureFromTileCommand(Client.Player, fromPosition, packet.Index, packet.ItemId, packet.CreatureId); } } break; case 0x85: { var packet = server.PacketsFactory.Create <RotateItemIncomingPacket>(reader); var fromPosition = new Position(packet.X, packet.Y, packet.Z); if (fromPosition.IsContainer) { command = new RotateItemFromContainerCommand(Client.Player, fromPosition.ContainerId, fromPosition.ContainerIndex, packet.ItemId); } else if (fromPosition.IsInventory) { command = new RotateItemFromInventoryCommand(Client.Player, fromPosition.InventoryIndex, packet.ItemId); } else { command = new RotateItemFromTileCommand(Client.Player, fromPosition, packet.Index, packet.ItemId); } } break; case 0x87: { var packet = server.PacketsFactory.Create <CloseContainerIncommingPacket>(reader); command = new CloseContainerCommand(Client.Player, packet.ContainerId); } break; case 0x88: { var packet = server.PacketsFactory.Create <OpenParentIncommingPacket>(reader); command = new OpenParentContainerCommand(Client.Player, packet.ContainerId); } break; case 0x8C: { var packet = server.PacketsFactory.Create <LookIncomingPacket>(reader); var fromPosition = new Position(packet.X, packet.Y, packet.Z); if (fromPosition.IsContainer) { command = new LookFromContainerCommand(Client.Player, fromPosition.ContainerId, fromPosition.ContainerIndex, packet.ItemId); } else if (fromPosition.IsInventory) { command = new LookFromInventoryCommand(Client.Player, fromPosition.InventoryIndex, packet.ItemId); } else { command = new LookFromTileCommand(Client.Player, fromPosition, packet.Index, packet.ItemId); } } break; case 0x96: { var packet = server.PacketsFactory.Create <TalkIncommingPacket>(reader); switch (packet.TalkType) { case TalkType.Say: command = new SayCommand(Client.Player, packet.Message); break; case TalkType.Whisper: command = new WhisperCommand(Client.Player, packet.Message); break; case TalkType.Yell: command = new YellCommand(Client.Player, packet.Message); break; case TalkType.Private: command = new SendMessageToPlayerCommand(Client.Player, packet.Name, packet.Message); break; case TalkType.ChannelYellow: command = new SendMessageToChannel(Client.Player, packet.ChannelId, packet.Message); break; case TalkType.ReportRuleViolationOpen: command = new CreateReportRuleViolationCommand(Client.Player, packet.Message); break; case TalkType.ReportRuleViolationAnswer: command = new AnswerInReportRuleViolationChannelCommand(Client.Player, packet.Name, packet.Message); break; case TalkType.ReportRuleViolationQuestion: command = new AskInReportRuleViolationChannelCommand(Client.Player, packet.Message); break; case TalkType.Broadcast: command = new BroadcastMessageCommand(Client.Player, packet.Message); break; } } break; case 0x97: command = new OpenNewChannelCommand(Client.Player); break; case 0x98: { var packet = server.PacketsFactory.Create <OpenedNewChannelIncomingPacket>(reader); command = new OpenedNewChannelCommand(Client.Player, packet.ChannelId); } break; case 0x99: { var packet = server.PacketsFactory.Create <CloseChannelIncommingPacket>(reader); command = new CloseChannelCommand(Client.Player, packet.ChannelId); } break; case 0x9A: { var packet = server.PacketsFactory.Create <OpenedPrivateChannelIncomingPacket>(reader); command = new OpenedPrivateChannelCommand(Client.Player, packet.Name); } break; case 0x9B: { var packet = server.PacketsFactory.Create <ProcessReportRuleViolationIncommingPacket>(reader); command = new ProcessReportRuleViolationCommand(Client.Player, packet.Name); } break; case 0x9C: { var packet = server.PacketsFactory.Create <CloseReportRuleViolationChannelAnswerIncommingPacket>(reader); command = new CloseReportRuleViolationChannelAnswerCommand(Client.Player, packet.Name); } break; case 0x9D: command = new CloseReportRuleViolationChannelQuestionCommand(Client.Player); break; case 0x9E: command = new CloseNpcsChannelCommand(Client.Player); break; case 0xA0: { var packet = server.PacketsFactory.Create <CombatControlsIncommingPacket>(reader); command = new CombatControlsCommand(Client.Player, packet.FightMode, packet.ChaseMode, packet.SafeMode); } break; case 0xA1: { var packet = server.PacketsFactory.Create <AttackIncommingPacket>(reader); if (packet.CreatureId == 0) { command = new StopAttackCommand(Client.Player); } else { command = new StartAttackCommand(Client.Player, packet.CreatureId, packet.Nonce); } } break; case 0xA2: { var packet = server.PacketsFactory.Create <FollowIncommingPacket>(reader); if (packet.CreatureId == 0) { command = new StopFollowCommand(Client.Player); } else { command = new StartFollowCommand(Client.Player, packet.CreatureId, packet.Nonce); } } break; case 0xA3: { var packet = server.PacketsFactory.Create <InviteToPartyIncomingPacket>(reader); command = new InviteToPartyCommand(Client.Player, packet.CreatureId); } break; case 0xA4: { var packet = server.PacketsFactory.Create <JoinPartyIncomingPacket>(reader); command = new JoinPartyCommand(Client.Player, packet.CreatureId); } break; case 0xA5: { var packet = server.PacketsFactory.Create <RevokePartyIncomingPacket>(reader); command = new RevokePartyCommand(Client.Player, packet.CreatureId); } break; case 0xA6: { var packet = server.PacketsFactory.Create <PassLeadershipToIncomingPacket>(reader); command = new PassLeaderShipToCommand(Client.Player, packet.CreatureId); } break; case 0xA7: command = new LeavePartyCommand(Client.Player); break; case 0xA8: { var packet = server.PacketsFactory.Create <SharedExperienceIncomingPacket>(reader); command = new SharedExperienceCommand(Client.Player, packet.Enabled); } break; case 0xAA: command = new OpenedMyPrivateChannelCommand(Client.Player); break; case 0xAB: { var packet = server.PacketsFactory.Create <InvitePlayerIncommingPacket>(reader); command = new InvitePlayerCommand(Client.Player, packet.Name); } break; case 0xAC: { var packet = server.PacketsFactory.Create <ExcludePlayerIncommingPacket>(reader); command = new ExcludePlayerCommand(Client.Player, packet.Name); } break; case 0xBE: command = new StopCommand(Client.Player); break; case 0xD2: command = new SelectOutfitCommand(Client.Player); break; case 0xD3: { var packet = server.PacketsFactory.Create <SelectedOutfitIncomingPacket>(reader); command = new SelectedOutfitCommand(Client.Player, packet.Outfit); } break; case 0xDC: { var packet = server.PacketsFactory.Create <AddVipIncommingPacket>(reader); command = new AddVipCommand(Client.Player, packet.Name); } break; case 0xDD: { var packet = server.PacketsFactory.Create <RemoveVipIncommingPacket>(reader); command = new RemoveVipCommand(Client.Player, packet.CreatureId); } break; case 0xE6: { var packet = server.PacketsFactory.Create <ReportBugIncomingPacket>(reader); command = new ReportBugCommand(Client.Player, packet.Message); } break; case 0xF0: command = new OpenQuestsCommand(Client.Player); break; case 0xF1: { var packet = server.PacketsFactory.Create <OpenQuestIncomingPacket>(reader); command = new OpenQuestCommand(Client.Player, packet.QuestId); } break; } if (command != null) { server.QueueForExecution(command); } } } catch (Exception ex) { server.Logger.WriteLine(ex.ToString()); } base.OnReceived(body); }
public static byte[] Load(Stream stream, uint[] keys) { byte[] int32t = new byte[4], fourcc = new byte[4]; stream.Read(fourcc, 0, 4); if (fourcc[0] == 'M' && fourcc[1] == 'C' && fourcc[2] == 'O' && fourcc[3] == 'Z') { } // @todo: Snappy else { return(null); } stream.Read(int32t, 0, 4); uint cryptedSize = BitConverter.ToUInt32(int32t, 0); stream.Read(int32t, 0, 4); uint compressSize = BitConverter.ToUInt32(int32t, 0); stream.Read(int32t, 0, 4); uint realSize = BitConverter.ToUInt32(int32t, 0); byte[] cdata; if (cryptedSize == 0) { if (stream.Length < compressSize) { return(null); } cdata = new byte[compressSize]; stream.Read(cdata, 0, (int)compressSize); if (cdata[0] != fourcc[0] || cdata[1] != fourcc[1] || cdata[2] != fourcc[2] || cdata[3] != fourcc[3]) { return(null); } } else { if (stream.Length < cryptedSize) { return(null); } byte[] data = new byte[cryptedSize]; stream.Read(data, 0, (int)cryptedSize); cdata = Xtea.XteaDecrypt(data, cryptedSize, keys); if (cdata[0] != fourcc[0] || cdata[1] != fourcc[1] || cdata[2] != fourcc[2] || cdata[3] != fourcc[3]) { return(null); } } return(Lzo.Decompress(cdata, compressSize, realSize)); }
/// <summary> /// Initializes a new instance of the <see cref="NetworkMessage" /> class. /// </summary> /// <param name="xtea">The XTEA key.</param> public NetworkMessage(Xtea xtea) { Xtea = xtea; Reset(); }