// Flush the MessageQueue Lists to the Client public void flushQueue() { // This resend the MessageQueue - should be called after parsing or after sending something out // or in a timed interval (keep alive for example) // Sends RAW MEssages sendRawMessages(); Output.WriteLine("[CLIENT] In Queue Messages : " + messageQueue.ObjectMessagesQueue.Count.ToString() + " Object and " + messageQueue.RPCMessagesQueue.Count.ToString() + " RPC Messages"); ArrayList worldPackets = new ArrayList(); WorldPacket packet = new WorldPacket(playerData); // Init encrypted Packet if we have MPM Messages if (messageQueue.RPCMessagesQueue.Count > 0 || messageQueue.ObjectMessagesQueue.Count > 0 && flushingQueueInProgress == false) { flushingQueueInProgress = true; // we currently dont know if we send something out so we need to proove that in a way if (messageQueue.ObjectMessagesQueue.Count > 0) { UInt16 sendingSSeq = playerData.calculateNextPossibleSseq(); lock (messageQueue.ObjectMessagesQueue.SyncRoot) { foreach (SequencedMessage messageObjects in messageQueue.ObjectMessagesQueue) { // Just append each message... if (messageObjects.getResendTime() >= TimeUtils.getUnixTimeUint32() || messageObjects.getResendTime() == 0) { // Check if this really save the resendtime or not messageObjects.increaseResendTime(); bool canAddThePak = packet.addObjectContent(messageObjects); if (canAddThePak == false) { packet.isFinal = true; // if one sub has a timed param set, we just set it here too worldPackets.Add(packet); // Start new packet and add it to the queue packet = new WorldPacket(playerData); packet.addRPCContent(messageObjects); } if (messageObjects.isTimed == true) { packet.timed = true; } } } } } // Workaround: complete the packet so we dont mix up if (packet.ObjectMessages.Count > 0) { packet.isFinal = true; worldPackets.Add(packet); packet = new WorldPacket(playerData); packet.timed = false; } if (messageQueue.RPCMessagesQueue.Count > 0) { lock (messageQueue.RPCMessagesQueue.SyncRoot) { foreach (SequencedMessage messageRPC in messageQueue.RPCMessagesQueue) { // First do stuff on messages // Just append each message... if (messageRPC.getResendTime() >= TimeUtils.getUnixTimeUint32() || messageRPC.getResendTime() == 0) { // Check if this really save the resendtime or not messageRPC.increaseResendTime(); if (packet.addRPCContent(messageRPC) == false) { packet.isFinal = true; worldPackets.Add(packet); // Start new packet and add it to the queue packet = new WorldPacket(playerData); packet.addRPCContent(messageRPC); } if (messageRPC.isTimed == true) { packet.timed = true; } } } } } // Check if the current not finalize packet has content and needs to be send if ((packet.isFinal == false) && (packet.ObjectMessages.Count > 0 || packet.RPCMessages.Count > 0)) { worldPackets.Add(packet); } } // We have nothing - but we should really ack this if (messageQueue.ackOnlyCount > 0) { for (int i = 0; i < messageQueue.ackOnlyCount; i++) { WorldPacket ackPacket = new WorldPacket(playerData); packet.isFinal = true; packet.timed = false; worldPackets.Add(ackPacket); } messageQueue.ackOnlyCount = 0; } // We have now PacketObjects - time to send them if (worldPackets.Count > 0) { Output.WriteLine("[CLIENT] Flush the final Queue with " + worldPackets.Count.ToString() + " Packets"); foreach (WorldPacket thePacket in worldPackets) { playerData.IncrementSseq(); byte[] finalData = thePacket.getFinalData(playerData); Output.WritePacketLog(StringUtils.bytesToString(finalData), "SERVER", playerData.getPss().ToString(), playerData.getCseq().ToString(), playerData.getSseq().ToString()); byte[] encryptedData = cypher.encrypt(finalData, finalData.Length, playerData.getPss(), playerData.getCseq(), playerData.getSseq()); sendPacket(encryptedData); Output.WriteDebugLog("PACKET SEND FINALLY (WC AFTER sendPacket):" + StringUtils.bytesToString(finalData)); } } flushingQueueInProgress = false; }
public byte[] encrypt(byte[] packet) { // Get timestamp byte[] timestamp = TimeUtils.getUnixTime(); // get size int psize = packet.Length; byte[] size = NumericalUtils.uint16ToByteArray((UInt16)psize, 1); //showPacket(size, " Size "); // final Packet DynamicArray temp = new DynamicArray(); temp.append(size); temp.append(timestamp); temp.append(packet); // compute CRC32 byte[] crc32pax = crc32.checksumB(temp.getBytes(), 1); // Padding int totalLength = temp.getSize() + 4; int padding = 16 - (totalLength % 16); byte[] paddingBytes = new byte[padding]; for (int i = 0; i < padding; i++) { paddingBytes[i] = (byte)padding; } temp.append(paddingBytes); tf.setIV(IV); tf.setKey(TF_Key); // We init with 2 more than needed, so no memory reservation is done on dyn array DynamicArray finalPlainData = new DynamicArray(); finalPlainData.append(crc32pax); finalPlainData.append(temp.getBytes()); temp = null; // Cleaning the house byte[] encryptedData = new byte[finalPlainData.getSize()]; tf.encrypt(finalPlainData.getBytes(), encryptedData); finalPlainData = null; // Cleaning the house (2) // add IV before the results DynamicArray response = new DynamicArray(); response.append(IV); response.append(encryptedData); // Display HEX Values after Encryption return(response.getBytes()); }
private void loadCharacter(byte[] packet, NetworkStream client, UInt32 theCharId) { byte[] charIDB = new byte[4]; if (theCharId == 0) { ArrayUtils.copy(packet, 3, charIDB, 0, 4); //Offset for charID is 3 in request uint charId = (uint)NumericalUtils.ByteArrayToUint32(charIDB, 1); // Remove current instances for this character if (Store.margin.isAnotherClientActive(charId) == true) { CharacterAlreadyInUseReply(client); return; } this.newCharID = charId; } charIDB = NumericalUtils.uint32ToByteArray(this.newCharID, 1); //New harcoded sessionID is: ac 53 02 00 //Old is: 28 A9 02 00 string [] marginValues = new string[0x0e]; marginValues[8] = "000b10001e000700000001000800000000000a00000003000d00000000001c0000000100"; marginValues[0xc] = "000e10000000"; marginValues[0xd] = "010f10000000"; // Some Items string itemData = "0170A7000000000010" + "020B8F00000000001803B80200000000001804EE9900000000000005F399000000000000065F0900000000100007C80900000000000008D59D000000000C0009EA040000000000480AD61E0000000000380BF21800000000001C0C66900000000000140DB30400000000001C0E04A80000000018000F3743000000000028108D2200000000002411441A00000000004415808C00000000004462EB0300000000001C63CC5A00000000004464ECB2000000000048651CB3000000000038663E9500000000006868EA0400000000001C"; byte[] inventory = StringUtils.hexStringToBytes(itemData); // Loaded Abilities string loadedAbs = "000032080080070000E400800B0000E002800C00006403800E0000340180110032B400801600322C0080290032D404802B0000DC04802F00322800803000323000803E0001E404804200322005805D0000E800805E0032D000805F00327C01806B00008801806F00001C0580990001280580A40000A40080A60000AC0080AC0000EC0080B00000000180B10000040180B80032240180BB0032300180BC00004C0180C50000A00080D80001EC0480DD00012C0580EA0001E80480F400013005800D01013405801D0101680780200132740580280100E004802C01013805803601018C05803801017805803A01325C0780490100840180520100D8088056010124"; byte[] loadAbilitys = StringUtils.hexStringToBytes(loadedAbs); // Known Abilities string abilityData = "0000320800800100014800800200017C0080030000080280040000140380050001300480060001B40080070000E4008008000018038009000F9400800A0000E002800B0000E002800C00006403800D00009000800E00003401800F00018C00801000006C0080110032B40080120000E402801300001003801400016400801500322004801600322C0080170001AC09801800012C008019000F9400801A0032C401801B00010800801C00018400801D0000F803801E001A3802801F00010400802000006C0280210001240580220032B40980230032640680240001680080250087DF11842600000400802700001C0080280032540480290032D404802A003210"; byte[] knownAbilitiys = StringUtils.hexStringToBytes(abilityData); // Known Hardlines //string hardlineData = "0207000000021f000000022300000002240000000225000000022600000002270000000229000000022b000000022f00000002300000000231000000023200000002340000000235000000023600000002370000000238000000023b000000023f000000024000000002410000000243000000024500000002480000000249000000024a000000024b000000024d000000024e000000024f000000025000000002510000000252000000025400000002550000000256000000025700000002580000000259000000025a000000025b000000025c000000025d000000025e000000025f000000026000000002610000000262000000026300000002640000000265000000026600000002670000000269000000026a000000026b000000026c000000026d000000026e000000026f000000027000000002710000000130000000013100000001370000000141000000014500000001480000000149000000014a000000014b000000014c000000014e000000014f0000000150000000015100000001520000000163000000016400000001650000000166000000016700000001680000000169000000016a000000016b000000016d000000016f00000001700000000171000000017200000001730000000174000000017700000001780000000179000000017a000000017b000000017c000000017d000000017e000000017f000000018000000001810000000182000000018300000001840000000185000000018600000001870000000188000000018a000000018b000000018c000000018d000000018e000000019000000001910000000192000000019300000001940000000195000000019600000001970000000198000000019900000003020000000303000000030400000003050000000306000000030700000003080000000309000000030a000000030b000000030c000000030d000000030e000000030f000000031000000003110000000312000000031300000003140000000315000000031600000003170000000318000000"; //string hardlineData = Store.dbManager.MarginDbHandler.loadAllHardlines(); string hardlineData = "0130000000013100000001370000000141000000014500000001480000000149000000014A000000014B000000014C000000014E000000014F00000001500000000151000000015200000001530000000163000000016400000001650000000166000000016700000001680000000169000000016A000000016B000000016D000000016F00000001700000000171000000017200000001730000000174000000017700000001780000000179000000017A000000017B000000017C000000017D000000017E000000017F000000018000000001810000000182000000018300000001840000000185000000018600000001870000000188000000018A000000018B000000018C000000018D000000018E000000018F00000001900000000191000000019200000001930000000194000000019500000001960000000197000000019800000001990000000207000000021F000000022300000002240000000225000000022600000002270000000229000000022B000000022F00000002300000000231000000023200000002340000000235000000023600000002370000000238000000023B000000023F000000024000000002410000000243000000024500000002480000000249000000024A000000024B000000024D000000024E000000024F000000025000000002510000000252000000025400000002550000000256000000025700000002580000000259000000025A000000025B000000025C000000025D000000025E000000025F000000026000000002610000000262000000026300000002640000000265000000026600000002670000000269000000026A000000026B000000026C000000026D000000026E000000026F0000000270000000027100000003020000000303000000030400000003050000000306000000030700000003080000000309000000030A000000030B000000030C000000030D000000030E000000030F00000003100000000311000000031200000003130000000314000000031500000003160000000317000000031800000011010000000E010000000F0100000010020000000C010000000D01000000"; byte[] knownHardlines = StringUtils.hexStringToBytes(hardlineData); // Contacts string missionContacts = "0700000001000800000000000a00000003000d00000000001c0000000100"; byte[] knownContacts = StringUtils.hexStringToBytes(missionContacts); byte[] codeArchiveTest = StringUtils.hexStringToBytes("04000000A7010000AC010000CC010000D1010000D60100001302000019020000650200006602000068020000B4020000B5020000B6020000BB020000BC020000C2020000C4020000D5020000D6020000DE020000E2020000E3020000E6020000E7020000E90200003F03000086030000A0030000AA030000E3030000FC030000FE030000030400000604000008040000090400000A040000270400004C0400004E040000BB040000C2040000CE040000EB040000EC040000EE040000F5040000F6040000F7040000F9040000540900005F09000082090000BE090000BF090000C1090000C4090000C7090000C8090000C9090000040A0000080A0000B0120000"); byte[] empty = new byte[0]; // New Margin Method to send Data // Pre-Load Abilities so that we just need to filter the result later loadAbilities((int)this.newCharID); sendMarginCharData(empty, 0x01, client, 0, false); sendMarginCharData(loadBackgroundInfo((int)this.newCharID), 0x02, client, 0, false); sendMarginCharData(empty, 0x03, client, 0, false); // BuddyList (but old one) sendMarginCharData(empty, 0x04, client, 0, false); // Unknown - no one has data there so ignore it sendMarginCharData(loadInventory((int)this.newCharID), 0x05, client, 0, false); // Inventory //sendMarginCharData(StringUtils.hexStringToBytes(itemData), 0x05, client); // Inventory CR1 sendMarginCharData(loadEquippedAbilities(), 0x06, client, 0, false); // Loaded Abilitys //sendMarginCharData(empty, 0x06, client); // Loaded Abilitys CR1 sendMarginCharData(loadKnownAbilities(), 0x07, client, 0, false); // Known Abilities sendMarginCharData(knownHardlines, 0x08, client, 0, false); // Hardlines sendMarginCharData(empty, 0x09, client, 0, false); // Access Nodes? //sendMarginCharData(codeArchiveTest, 0x0a, client); // Code Storage sendMarginCharData(empty, 0x0a, client, 0, false); // Code Storage CR1 sendMarginCharData(knownContacts, 0x0b, client, 0, false); // Contacts sendMarginCharData(empty, 0x0e, client, 0, false); // MotD has a special handling DbParams _dbParams; XmlParser.loadDBParams("Config.xml", out _dbParams); string motd = _dbParams.Motd; if (!motd.Equals("")) // if MOTD not empty { DynamicArray announcement = new DynamicArray(); byte[] currentTime = TimeUtils.getUnixTime(); //Load motd from file byte[] text = StringUtils.stringToBytes(motd); byte[] size = NumericalUtils.uint16ToByteArrayShort((UInt16)(currentTime.Length + text.Length)); //announcement.append(size); announcement.append(currentTime); announcement.append(text); sendMarginCharData(announcement.getBytes(), 0x0d, client, 10000, true); } /* End of the MOTD */ }
public npc() { this.next_move_time = TimeUtils.getUnixTimeUint32() + (30); // 30 seconds for a move to test }