public static WritePacketLog ( Object obj, string type, string pss, string cseq, string sseq ) : void | ||
obj | Object | |
type | string | |
pss | string | |
cseq | string | |
sseq | string | |
return | void |
public void processPacket(byte[] packet) { // Update the last time we are called lastUsedTime = TimeUtils.getUnixTimeUint32(); // Decryption start bool encrypted = false; byte[] processedPacket = null; if (packet.Length > 0) { if (packet[0] == 0x00) { // Plain text packet processedPacket = packet; } else { encrypted = true; processedPacket = decryptReceivedPacket(packet); } Output.WriteLine("\n" + key + " PSS = " + playerData.getPss() + ", Cseq = " + playerData.getCseq() + ", AckSSeq = " + playerData.getACK()); Output.WriteLine("D: " + StringUtils.bytesToString(processedPacket)); Output.WritePacketLog(StringUtils.bytesToString(processedPacket), "CLIENT", playerData.getPss().ToString(), playerData.getCseq().ToString(), playerData.getACK().ToString()); Store.Mpm.Parse(encrypted, processedPacket); flushQueue(); } }
public void processPacket(byte[] packet) { // Update the last time we are called lastUsedTime = TimeUtils.getUnixTimeUint32(); // Decryption start bool encrypted = false; byte[] processedPacket = null; Stopwatch stopwatch = new Stopwatch(); if (packet.Length > 0) { if (packet[0] == 0x00) { // Plain text packet processedPacket = packet; Output.WritePacketLog(processedPacket, "CLIENT", playerData.getPss().ToString(), playerData.getCseq().ToString(), playerData.getACK().ToString()); } else { encrypted = true; stopwatch.Start(); processedPacket = DecryptReceivedPacket(packet); stopwatch.Stop(); TimeSpan ts = stopwatch.Elapsed; Output.WritePacketLog(processedPacket, "CLIENT", playerData.getPss().ToString(), playerData.getCseq().ToString(), playerData.getACK().ToString(), ts.TotalMilliseconds.ToString(), "DECRYPT"); } // Output.WriteLine("\n" + key + " PSS = " + playerData.getPss() + ", Cseq = " + playerData.getCseq() + // ", AckSSeq = " + playerData.getACK()); Store.Mpm.Parse(encrypted, processedPacket); FlushQueue(); } }
// 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; }
private void sendMarginCharData(byte[] data, byte opcode, NetworkStream client) { // This Method will be used to send the real Data to the client // Format for general LoadCharacterReply Responses: // 10 00 00 00 <- everytime the same // 00 f9 76 04 <- uint32 Char ID // 00 00 00 09 <- uint32 number of Character Replys (just raise one up) // 00 05 <- viewData opcode (what data is inside) uint16 // 10 00 <- if it has Data it is 10 00 if not is just 00 00 (and no Data can follow up and packet ends here) // e1 00 <- short / uint16 data size // DATA byte[] header = { 0x10, 0x00, 0x00, 0x00 }; // Raise one up loadCharCounter++; // Add the counter byte[] counterByte = new byte[4]; counterByte = NumericalUtils.uint32ToByteArray(loadCharCounter, 1); // get the datasize for the packet byte[] dataSize = NumericalUtils.uint16ToByteArray((UInt16)data.Length, 1); // charId byte[] charID = NumericalUtils.uint32ToByteArray(this.newCharID, 0); // viewData code byte[] responseCode = { 0x00, opcode }; string pakData = StringUtils.bytesToString_NS(header) + StringUtils.bytesToString_NS(charID) + StringUtils.bytesToString_NS(counterByte) + StringUtils.bytesToString_NS(responseCode); string hasData; // this needs improvement... if (data.Length == 0 && opcode == 0x01) { hasData = "0000"; } else { hasData = "1000" + StringUtils.bytesToString_NS(dataSize) + StringUtils.bytesToString_NS(data); } pakData += hasData; PacketContent pak = new PacketContent(); // Dump the Packet Data to see whats in //Console.WriteLine("Response Load Pak : " + pakData); // Do the viewData byte[] response = StringUtils.hexStringToBytes(pakData); Output.WritePacketLog(StringUtils.bytesToString(response), "MARGINSERVER", "0", "0", "0"); Output.WriteDebugLog("[MARGIN SERVER RESPONSE] for OPCODE " + opcode + " : " + StringUtils.bytesToString(response)); byte[] encryptedResponse = marginEncr.encrypt(response); sendTCPVariableLenPacket(encryptedResponse, client); System.Threading.Thread.Sleep(50); }
public void packetHandler(byte[] packet, NetworkStream client) { bool encrypted = true; byte opcode = packet[2]; byte[] data = { }; byte pointer = packet[0]; if (opcode == 0x01) { // Packet is unencrypted encrypted = false; data = packet; } // This overrides the above IF for packets where 3rd position is a "01" // Happened someday, and screwed login... yeah, really if (pointer != 0x81) { encrypted = true; } if (encrypted == true) { byte[] encryptedPacket = { }; if (packet[0] >= 0x80) { // try to readjust the packet for one byte less if the lenght is too long // just a crappy way encryptedPacket = new byte[packet.Length - 1]; ArrayUtils.copy(packet, 1, encryptedPacket, 0, packet.Length - 1); } else { encryptedPacket = packet; } // Get the IV from encrypted Packet and set it in encryptor/decryptor byte[] decrypted = marginEncr.decryptMargin(encryptedPacket); // Just 2 zero bytes for opcode handling later (As we use third byte for both state, encrypted or not byte[] spacer = { 0x00, 0x00 }; DynamicArray din = new DynamicArray(); din.append(spacer); din.append(decrypted); data = din.getBytes(); } else { data = packet; } Output.WritePacketLog(StringUtils.bytesToString(data), "MARGINCLIENT", "0", "0", "0"); opcode = data[2]; //TODO: check if this needs "packet" or "data" switch (opcode) { case 0x01: certConnectRequest(packet, client); break; case 0x03: certConnectReply(packet, client); break; case 0x06: connectChallenge(packet, client); break; case 0x08: ConnectChallengeResponse(packet, client); break; case 0x0a: //CharNameRequest charNameRequest(data, client); break; case 0x0c: //TODO: this is creation. must be done someday Output.writeToLogForConsole("CREATECHAR RSI VALUES:" + StringUtils.bytesToString(data)); //loadCharacter(data, client); createCharacterRSI(data, client); // Add the first abilitys // AbilityID : 2147485696 (Awakened) Level 2 // AbilityID : break; case 0x0d: // Delete Charname Request deleteCharName(data, client); break; case 0x0f: loadCharacter(data, client, 0); break; } }