void XteaDecrypt(InputMessage message) { int encryptedSize = message.GetUnreadSize(); if (encryptedSize % 8 != 0) { throw new Exception("invalid encrypted network message with size: " + (encryptedSize % 8) + ", " + message.GetU16()); } byte[] unreadBuffer = message.GetUnreadBuffer(); int readPos = 0; while (readPos < encryptedSize / 4) { uint v0 = BitConverter.ToUInt32(unreadBuffer, readPos * 4); uint v1 = BitConverter.ToUInt32(unreadBuffer, (readPos + 1) * 4); uint delta = 0x61C88647; uint sum = 0xC6EF3720; for (int i = 0; i < 32; i++) { v1 -= ((v0 << 4 ^ v0 >> 5) + v0) ^ (sum + m_XteaKey[sum >> 11 & 3]); sum += delta; v0 -= ((v1 << 4 ^ v1 >> 5) + v1) ^ (sum + m_XteaKey[sum & 3]); } int tmpReadPos = 0; byte[] v0Array = BitConverter.GetBytes(v0); byte[] v1Array = BitConverter.GetBytes(v1); foreach (byte v in v0Array) { unreadBuffer[readPos * 4 + tmpReadPos++] = v; } foreach (byte v in v1Array) { unreadBuffer[readPos * 4 + tmpReadPos++] = v; } readPos = readPos + 2; } ushort decryptedSize = (ushort)(BitConverter.ToUInt16(unreadBuffer, 0) + 2); int sizeDelta = decryptedSize - encryptedSize; if (sizeDelta > 0 || -sizeDelta > encryptedSize) { throw new Exception("invalid decrypted network message with sizeDelta: " + sizeDelta); } byte[] newBuffer = new byte[decryptedSize - 2]; Array.Copy(unreadBuffer, 2, newBuffer, 0, decryptedSize - 2); message.SetBuffer(newBuffer); }
protected override void OnRecv(InputMessage message) { OpenTibiaUnity.GameManager.InvokeOnMainThread(delegate { try { base.OnRecv(message); } catch (Exception e) { string err = string.Format("ProtocolGame.OnRecv: {0}\nStackTrace: {1}", e.Message, new System.Diagnostics.StackTrace(e, true)); m_ChatStorage.AddDebugMessage(err); return; } if (m_FirstRecv) { m_FirstRecv = false; ushort size = message.GetU16(); int unreadSize = message.GetUnreadSize(); if (unreadSize != size) { string err = string.Format("ProtocolGame.OnRecv: Invalid message size (size: {0}, unread: {1})", size, unreadSize); m_ChatStorage.AddDebugMessage(err); return; } } bool read = false; while (message.CanRead(1)) { read = true; byte opcode = message.PeekU8(); try { if (!ParsePacket(message)) { break; } } catch (Exception e) { string err = string.Format("ProtocolGame: Opcode: {0}, last Opcode ({1}), prev Opcode ({2}).\n{3}\nStackTrace: {4}", opcode, m_LastOpcode, m_PrevOpcode, e.Message, new System.Diagnostics.StackTrace(e, true)); m_ChatStorage.AddDebugMessage(err); break; } } if (read) { m_WorldMapStorage.ProtocolGameMessageProcessingFinished(); } }); }