public int Unknown4; // 0 /// <summary> /// Reads the <see cref="VillageData"/> from the specified <see cref="MessageReader"/>. /// </summary> /// <param name="reader"> /// <see cref="MessageReader"/> that will be used to read the <see cref="VillageData"/>. /// </param> /// <exception cref="NotImplementedException">Compressed set to false.</exception> /// <exception cref="InvalidMessageException">Home data array is null.</exception> public void Read(MessageReader reader) { if (!Compressed) throw new NotImplementedException("Uncompressed Village definition is not implemented."); Unknown1 = reader.ReadInt32(); // 0 UserID = reader.ReadInt64(); ShieldDuration = TimeSpan.FromSeconds(reader.ReadInt32()); Unknown2 = reader.ReadInt32(); // 1200 Unknown3 = reader.ReadInt32(); // 60 Compressed = reader.ReadBoolean(); var homeData = reader.ReadBytes(); if (homeData == null) throw new InvalidMessageException("No data was provided about Village."); using (var br = new BinaryReader(new MemoryStream(homeData))) // little endian { var decompressedLength = br.ReadInt32(); var compressedHome = br.ReadBytes(homeData.Length - 4); // -4 to remove the decompressedLength bytes read var homeJson = ZlibStream.UncompressString(compressedHome); Home = Village.FromJson(homeJson); } Unknown4 = reader.ReadInt32(); }
/// <summary> /// Reads the <see cref="NpcElixirSlot"/> from the specified <see cref="MessageReader"/>. /// </summary> /// <param name="reader"> /// <see cref="MessageReader"/> that will be used to read the <see cref="NpcElixirSlot"/>. /// </param> public override void ReadSlot(MessageReader reader) { ID = reader.ReadInt32(); Elixir = reader.ReadInt32(); }
/// <summary> /// Reads the <see cref="AchievementProgessSlot"/> from the specified <see cref="MessageReader"/>. /// </summary> /// <param name="reader"> /// <see cref="MessageReader"/> that will be used to read the <see cref="AchievementProgessSlot"/>. /// </param> public override void ReadSlot(MessageReader reader) { ID = reader.ReadInt32(); Progress = reader.ReadInt32(); }
/// <summary> /// Reads the <see cref="UnitUpgradeSlot"/> from the specified <see cref="MessageReader"/>. /// </summary> /// <param name="reader"> /// <see cref="MessageReader"/> that will be used to read the <see cref="UnitUpgradeSlot"/>. /// </param> public override void ReadSlot(MessageReader reader) { ID = reader.ReadInt32(); Level = reader.ReadInt32(); }
public static void DumpBuffer(MessageReader reader) { File.WriteAllBytes("dump", ((MemoryStream)reader.BaseStream).ToArray()); }
/// <summary> /// Reads the <see cref="HeroUpgradeSlot"/> from the specified <see cref="MessageReader"/>. /// </summary> /// <param name="reader"> /// <see cref="MessageReader"/> that will be used to read the <see cref="HeroUpgradeSlot"/>. /// </param> public override void ReadSlot(MessageReader reader) { ID = reader.ReadInt32(); Health = reader.ReadInt32(); }
/// <summary> /// Reads the <see cref="AvatarData"/> from the specified <see cref="MessageReader"/>. /// </summary> /// <param name="reader"> /// <see cref="MessageReader"/> that will be used to read the <see cref="AvatarData"/>. /// </param> public void Read(MessageReader reader) { OwnVillageData = new VillageData(); OwnVillageData.Read(reader); UserID = reader.ReadInt64(); UserID2 = reader.ReadInt64(); OwnClanData = new ClanData(); if (reader.ReadBoolean()) { OwnClanData.ID = reader.ReadInt64(); OwnClanData.Name = reader.ReadString(); OwnClanData.Badge = reader.ReadInt32(); OwnClanData.Role = reader.ReadInt32(); OwnClanData.Level = reader.ReadInt32(); OwnClanData.Unknown1 = reader.ReadByte(); } Unknown1 = reader.ReadInt32(); Unknown2 = reader.ReadInt32(); Unknown3 = reader.ReadInt32(); Unknown4 = reader.ReadInt32(); Unknown5 = reader.ReadInt32(); Unknown6 = reader.ReadInt32(); Unknown7 = reader.ReadInt32(); Unknown8 = reader.ReadInt32(); Unknown9 = reader.ReadInt32(); Unknown10 = reader.ReadInt32(); Unknown11 = reader.ReadInt32(); League = reader.ReadInt32(); AllianceCastleLevel = reader.ReadInt32(); AllianceCastleTotalCapacity = reader.ReadInt32(); AllianceCastleUsedCapacity = reader.ReadInt32(); TownHallLevel = reader.ReadInt32(); Name = reader.ReadString(); Unknown12 = reader.ReadInt32(); Level = reader.ReadInt32(); Experience = reader.ReadInt32(); Gems = reader.ReadInt32(); FreeGems = reader.ReadInt32(); Unknown13 = reader.ReadInt32(); Unknown14 = reader.ReadInt32(); Trophies = reader.ReadInt32(); AttacksWon = reader.ReadInt32(); AttacksLost = reader.ReadInt32(); DefensesWon = reader.ReadInt32(); DefensesLost = reader.ReadInt32(); Unknown19 = reader.ReadInt32(); Unknown20 = reader.ReadInt32(); Unknown21 = reader.ReadInt32(); Unknown22 = reader.ReadByte(); Unknown23 = reader.ReadInt64(); IsNamed = reader.ReadBoolean(); Unknown24 = reader.ReadInt32(); Unknown25 = reader.ReadInt32(); Unknown26 = reader.ReadInt32(); Unknown27 = reader.ReadInt32(); ResourcesCapacity = Slot.ReadSlotArray<ResourceCapacitySlot>(reader); ResourcesAmount = Slot.ReadSlotArray<ResourceAmountSlot>(reader); Units = Slot.ReadSlotArray<UnitSlot>(reader); Spells = Slot.ReadSlotArray<SpellSlot>(reader); UnitUpgrades = Slot.ReadSlotArray<UnitUpgradeSlot>(reader); SpellUpgrades = Slot.ReadSlotArray<SpellUpgradeSlot>(reader); HeroUpgrades = Slot.ReadSlotArray<HeroUpgradeSlot>(reader); HeroHealths = Slot.ReadSlotArray<HeroHealthSlot>(reader); HeroStates = Slot.ReadSlotArray<HeroStateSlot>(reader); TutorialProgess = Slot.ReadSlotArray<TutorialProgressSlot>(reader); Acheivements = Slot.ReadSlotArray<AchievementSlot>(reader); AcheivementProgress = Slot.ReadSlotArray<AchievementProgessSlot>(reader); NpcStars = Slot.ReadSlotArray<NpcStarSlot>(reader); NpcGold = Slot.ReadSlotArray<NpcGoldSlot>(reader); NpcElixir = Slot.ReadSlotArray<NpcElixirSlot>(reader); Unknown28 = reader.ReadInt32(); }
/// <summary> /// Reads the <see cref="ResourceCapacitySlot"/> from the specified <see cref="MessageReader"/>. /// </summary> /// <param name="reader"> /// <see cref="MessageReader"/> that will be used to read the <see cref="ResourceCapacitySlot"/>. /// </param> public override void ReadSlot(MessageReader reader) { ID = reader.ReadInt32(); Capacity = reader.ReadInt32(); }
/// <summary> /// Reads the <see cref="UnitSlot"/> from the specified <see cref="MessageReader"/>. /// </summary> /// <param name="reader"> /// <see cref="MessageReader"/> that will be used to read the <see cref="UnitSlot"/>. /// </param> public override void ReadSlot(MessageReader reader) { ID = reader.ReadInt32(); Amount = reader.ReadInt32(); }
private void ProcessReceive(SocketAsyncEventArgs args) { var bytesToProcess = args.BytesTransferred; var token = args.UserToken as MessageReceiveToken; Statistics.TotalByteReceived += args.BytesTransferred; while (bytesToProcess != 0) { // copy header from buffer if (Message.HeaderSize != token.HeaderOffset) // if we dont have the header yet { if (bytesToProcess < token.HeaderRemaining) // if we dont have the header in a single receive op { //Console.WriteLine("Reusing args: {0}", token.TokenID); Buffer.BlockCopy(args.Buffer, token.Offset, token.Header, token.HeaderOffset, bytesToProcess); token.Offset += bytesToProcess; token.HeaderOffset += bytesToProcess; bytesToProcess = 0; token.Offset = args.Offset; StartReceive(args); // reuse same op return; } else { Buffer.BlockCopy(args.Buffer, token.Offset, token.Header, token.HeaderOffset, token.HeaderRemaining); bytesToProcess -= token.HeaderRemaining; token.Offset += token.HeaderRemaining; token.HeaderOffset += token.HeaderRemaining; ProcessReceiveToken(token); } } // copy body from buffer if (token.Length != token.BodyOffset) // if we dont have the body yet { if (bytesToProcess < token.BodyRemaining) // if we dont have the body in a single receive op { //Console.WriteLine("Reusing args: {0}", token.TokenID); Buffer.BlockCopy(args.Buffer, token.Offset, token.Body, token.BodyOffset, bytesToProcess); token.Offset += bytesToProcess; token.BodyOffset += bytesToProcess; bytesToProcess = 0; token.Offset = args.Offset; StartReceive(args); return; } else { Buffer.BlockCopy(args.Buffer, token.Offset, token.Body, token.BodyOffset, token.BodyRemaining); bytesToProcess -= token.BodyRemaining; token.Offset += token.BodyRemaining; token.BodyOffset += token.BodyRemaining; } } var message = MessageFactory.Create(token.ID); var messageEnBody = (byte[])null; var messageDeBody = (byte[])null; // after encryption (was added after encryption) if (message is LoginRequestMessage) // we're the server { var publicKey = new byte[CoCKeyPair.KeyLength]; // copy clientKey(pk) from raw message, token.Body[:32] Buffer.BlockCopy(token.Body, 0, publicKey, 0, CoCKeyPair.KeyLength); messageEnBody = new byte[token.Length - CoCKeyPair.KeyLength]; // copy remaining bytes token.Body[32:] Buffer.BlockCopy(token.Body, CoCKeyPair.KeyLength, messageEnBody, 0, messageEnBody.Length); var lrMessage = message as LoginRequestMessage; lrMessage.PublicKey = publicKey; Crypto.UpdateSharedKey(publicKey); // update with clientKey(pk), _cryptoState = InitialKey } else { messageEnBody = token.Body; } messageDeBody = (byte[])messageEnBody.Clone(); // cloning cuz we dont want a reference var messageData = new byte[token.Length + Message.HeaderSize]; // full message data Buffer.BlockCopy(token.Header, 0, messageData, 0, Message.HeaderSize); Buffer.BlockCopy(token.Body, 0, messageData, Message.HeaderSize, token.Length); if (!(message is NewServerEncryptionMessage || message is NewClientEncryptionMessage)) Crypto.Decrypt(ref messageDeBody); if (message is UnknownMessage) { var unknownMessage = (UnknownMessage)message; unknownMessage.Length = token.Length; unknownMessage.Version = token.Version; unknownMessage.DecryptedBytes = messageDeBody; unknownMessage.EncryptedBytes = messageEnBody; OnMessageReceived(new MessageReceivedEventArgs() { Message = message, MessageData = messageData, MessageBody = messageDeBody, MessageFullyRead = true }); token.Reset(); continue; } using (var reader = new MessageReader(new MemoryStream(messageDeBody))) { var exception = (Exception)null; try { message.ReadMessage(reader); } catch (Exception ex) { exception = ex; } // before encryption (was added before encryption) if (message is LoginRequestMessage) // we're the server { var lrMessage = message as LoginRequestMessage; Crypto.UpdateNonce(lrMessage.Nonce, UpdateNonceType.Decrypt); // update with snonce, decryptnonce = snonce Crypto.UpdateNonce(lrMessage.Nonce, UpdateNonceType.Blake); } else if (message is LoginSuccessMessage) // we're the client { var lsMessage = message as LoginSuccessMessage; Crypto.UpdateNonce(lsMessage.Nonce, UpdateNonceType.Decrypt); // update with rnonce, decryptnonce = rnonce Crypto.UpdateSharedKey(lsMessage.PublicKey); // update crypto with k } OnMessageReceived(new MessageReceivedEventArgs() { Message = message, MessageData = messageData, MessageBody = messageDeBody, MessageFullyRead = reader.BaseStream.Position == reader.BaseStream.Length, Exception = exception }); } token.Reset(); } token.Offset = args.Offset; _receivePool.Push(args); StartReceive(_receivePool.Pop()); }