private void parseRpc() { int length = BufferHandler.readByte(ref buffer, ref offset); if (length >= 0x80) //2 bytes as size { length = (length - 0x80) << 8; length = length + (int)BufferHandler.readByte(ref buffer, ref offset); } int header = BufferHandler.readByte(ref buffer, ref offset); length--; //discount 1 byte for the header if (header >= 0x80) //2 bytes as size { header = (header - 0x80) << 8; header = header + (int)BufferHandler.readByte(ref buffer, ref offset); length--; // discount another byte for the header (2nd byte) } byte[] rpcValues = BufferHandler.readBytes(ref buffer, ref offset, length); #if DEBUG Output.WriteLine("RPC (Header " + header + " | Content:" + StringUtils.bytesToString(rpcValues)); #endif rpcManager.HandleRpc(header, ref rpcValues); }
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(); } }
private int twofishEncrypt() { ArrayUtils au = new ArrayUtils(); byte[] key = { 0xa4, 0x46, 0xdc, 0x73, 0x25, 0x08, 0xee, 0xb7, 0x6c, 0x9e, 0xb4, 0x4a, 0xb8, 0xe7, 0x11, 0x03 }; byte[] iv = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; byte[] plainText = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; byte[] knownResult = { 0xba, 0x05, 0xf5, 0x6e, 0x86, 0x5f, 0xb6, 0xc9, 0xb2, 0x1d, 0xe1, 0x00, 0xb6, 0xec, 0x46, 0xe9 }; byte[] result = new byte[16]; MxoTwofish tf = new MxoTwofish(); tf.setIV(iv); tf.setKey(key); tf.encrypt(plainText, result); if (!ArrayUtils.equal(knownResult, result)) { Output.Write("Failed\n"); Output.WriteLine(StringUtils.bytesToString(knownResult)); Output.WriteLine(StringUtils.bytesToString(result)); return(0); } Output.Write("OK\n"); return(1); }
public void processCharacterAnimationSelf(UInt16 abilityID) { ServerPackets pak = new ServerPackets(); // 2904 0429 = Hacker_VirusLaunch_A // 2a04 042a = Hacker_VirusLaunch_D // see movementAnims.tx - its for codes something (0x31) if (currentAbility.getAbilityExecutionFX() > 0) { pak.sendCastAbilityOnEntityId(2, currentAbility.getAbilityExecutionFX(), 200); } if (currentAbility.getCastingTime() > 0) { byte[] castAnimStart = currentAbility.getCastAnimStart(); // Cast pak.sendSystemChatMessage(Store.currentClient, "Animation Starts with Byte ID " + StringUtils.bytesToString(castAnimStart), "BROADCAST"); pak.sendPlayerAnimation(Store.currentClient, StringUtils.bytesToString_NS(castAnimStart)); // And Time a "Damage" or "Buff" Animation int castingTime = (int)this.currentAbility.getCastingTime() * 1000; this.damageTimer = new Timer(abilityAnimateTheTarget, this, castingTime, 0); } }
public void generateRpcMessageData() { // Example : 04 01 00 15 01 + submessages // Strcut: uint8 04 header + uint8 listcount + uint16 currentRPCCounter + submessageCounter (list1) // If you have 2 lists , the data struct is : uint8 submessagecount + submessages // TODO!!! FINALIZE!! // Here goes code from RPCPacket (As it should be generated on the fly) if (RPCMessages.Count > 0) { content.append((byte)ProtocolHeaders.RPC_PROTOCOL); // ToDo: Figure out what the "Lists" Count should handle ...maybe different types? // Why not having just one List and adding them all ? Maybe a list has a limit ? content.append(0x01); // List Count for RPC Messages Output.WriteLine(" RPC COUNTER BYTES :" + StringUtils.bytesToString(NumericalUtils.uint16ToByteArray(playerData.getRPCCounter(), 0))); content.append(NumericalUtils.uint16ToByteArray(playerData.getRPCCounter(), 0)); content.append(NumericalUtils.uint16ToByteArrayShort((UInt16)RPCMessages.Count)); foreach (SequencedMessage message in RPCMessages) { content.append(message.content); } // Set new RPC Counter UInt16 incrementRpcCounter = playerData.getRPCCounter(); Output.WriteDebugLog("Before RPC Counter :" + incrementRpcCounter.ToString()); incrementRpcCounter += (ushort)RPCMessages.Count; playerData.setRPCCounter(incrementRpcCounter); Output.WriteDebugLog("After RPC Counter :" + incrementRpcCounter.ToString() + " (should added " + RPCMessages.Count.ToString() + ")"); } }
public void SendNpcUpdateData(UInt16 viewId, WorldClient client, byte[] updateData) { PacketContent pak = new PacketContent(); pak.addUint16(viewId, 1); pak.addByteArray(updateData); string hexStringTest = StringUtils.bytesToString(pak.returnFinalPacket()); client.messageQueue.addObjectMessage(pak.returnFinalPacket(), false); client.FlushQueue(); }
public void sendSetMissionObjective(ushort id, ushort state, string missionObjective, WorldClient client) { //format : rpcsize+uint16header+ uint8(0) + uint16(0600), + uint8 state + sizedString (uint16 size + string + 00?) PacketContent pak = new PacketContent(); pak.addUint16((UInt16)RPCResponseHeaders.SERVER_MISSION_SET_OBJECTIVE, 0); pak.addUintShort(id); pak.addUint16(6, 1); pak.addUintShort(state); pak.addSizedTerminatedString(missionObjective); Output.WriteRpcLog("MISSION PAK: " + StringUtils.bytesToString(pak.returnFinalPacket())); // Now send the message to the player queue client.messageQueue.addRpcMessage(pak.returnFinalPacket()); }
public byte[] loadKnownAbilities() { DynamicArray din = new DynamicArray(); foreach (MarginAbilityItem ability in Abilities) { Int32 finalAblityID = ability.getAbilityID() + ability.getLevel(); string debugAbility = StringUtils.bytesToString(NumericalUtils.int32ToByteArray(finalAblityID, 1)); din.append(NumericalUtils.uint16ToByteArray(ability.getSlot(), 1)); // slot din.append(NumericalUtils.int32ToByteArray(finalAblityID, 1)); } return(din.getBytes()); }
public void processMissionaccept(ref byte[] packet) { byte[] contactBytes = { packet[0], packet[1] }; UInt16 contactId = NumericalUtils.ByteArrayToUint16(contactBytes, 1); ushort missionId = packet[2]; Output.WriteRpcLog("Mission Accept Data:" + StringUtils.bytesToString(packet)); ServerPackets pak = new ServerPackets(); pak.sendMissionAccept(Store.currentClient, contactId, missionId); pak.sendSetMissionObjective(1, 0, "This is the test Mission, mate", Store.currentClient); pak.sendSetMissionObjective(2, 0, "Success", Store.currentClient); //pak.sendSetMissionObjective(3, 2, "Failed Remain", Store.currentClient); //pak.sendSetMissionObjective(4, 3, "Failed Clear", Store.currentClient); }
public byte[] getFinalData(ClientData playerData) { // TODO: Sim Time with Client (not real time) on every 4 Local SSEQ we send playerData.IncrementSseq(); this.neededAckSSeq = playerData.getSseq(); if ((NumericalUtils.ByteArrayToUint32(TimeUtils.getCurrentSimTime(), 1) - playerData.lastSimTimeUpdate) > 3) { timed = true; playerData.lastSimTimeUpdate = NumericalUtils.ByteArrayToUint32(TimeUtils.getCurrentSimTime(), 1); } playerData.getRPCShutDown(); if (timed) { if (playerData.waitForRPCShutDown == true) { content.append((byte)0xc2); } else { content.append((byte)0x82); } content.append(TimeUtils.getCurrentSimTime()); } else { if (playerData.waitForRPCShutDown == true) { content.append((byte)0x42); } else { content.append((byte)0x02); } } // Merge all Message together and generate the Final Packet Header generateObjectMessageData(); generateRpcMessageData(); Output.WriteDebugLog("PACKET DATA (getFinalData):" + StringUtils.bytesToString(content.getBytes())); return(content.getBytes()); }
static public string ConvertByteToReadablePacket(byte[] packet) { ArrayList hexStrings = new ArrayList(); ArrayList readablePacketStrings = new ArrayList(); PacketReader reader = new PacketReader(packet); while (reader.getOffset() < packet.Length) { int offsetCount = reader.getOffset(); int lengofPak = packet.Length; string lineHex = ""; string lineHuman = ""; if (packet.Length - reader.getOffset() >= 32) { byte[] lineData = reader.readBytes(32); lineHex = StringUtils.bytesToString(lineData); lineHuman = StringUtils.charBytesToString_NZ(lineData); } else { byte[] lineData = reader.readBytes(packet.Length - reader.getOffset()); lineHex = StringUtils.bytesToString(lineData); lineHuman = StringUtils.charBytesToString_NZ(lineData); } hexStrings.Add(lineHex); readablePacketStrings.Add(lineHuman); } // Now build final packet string returnPacketString = ""; foreach (string hexString in hexStrings) { returnPacketString += hexString + "\r\n"; } return(returnPacketString); }
public byte[] encrypt(byte[] plainData, int length, ushort pss, ushort cseq, ushort sseq) { UInt32 seqValue = (uint)pss << 24 | (uint)cseq << 12 | (uint)sseq; byte[] sequences = BitConverter.GetBytes(seqValue); Array.Reverse(sequences); // Create the packet that needs to be CRC32 checksummed PacketContent packet = new PacketContent(); packet.addUint16((UInt16)(plainData.Length + 4), 1); packet.addByteArray(TimeUtils.getCurrentTime()); packet.addByteArray(sequences); packet.addByteArray(plainData); byte[] paddingBytes = getPaddedBytes(packet.returnFinalPacket()); // Final Packet which needs to be encrypted PacketContent packetWithCrc = new PacketContent(); packetWithCrc.addByteArray(crc32.checksumB(packet.returnFinalPacket(), 1)); packetWithCrc.addByteArray(packet.returnFinalPacket()); packetWithCrc.addByteArray(paddingBytes); string hexPackCrcedPlain = StringUtils.bytesToString(packetWithCrc.returnFinalPacket()); string paddingBytesHex = StringUtils.bytesToString(paddingBytes); innerBuffer = new byte[packetWithCrc.returnFinalPacket().Length]; tf.encrypt(packetWithCrc.returnFinalPacket(), innerBuffer); PacketContent encryptedPacket = new PacketContent(); encryptedPacket.addByte(0x01); encryptedPacket.addByteArray(IV); encryptedPacket.addByteArray(innerBuffer); innerBuffer = new byte [2048]; string hexPackEncrypt = StringUtils.bytesToString(encryptedPacket.returnFinalPacket()); return(encryptedPacket.returnFinalPacket()); }
private int twofishEncrypt() { byte[] key = { 0x6C, 0xAB, 0x8E, 0xCC, 0xE7, 0x3C, 0x22, 0x47, 0xDB, 0xEB, 0xDE, 0x1A, 0xA8, 0xE7, 0x5F, 0xB8 }; byte[] iv = { 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30 }; byte[] plainText = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }; byte[] knownResult = { 0x77, 0x7f, 0x54, 0xc6, 0xc9, 0x9e, 0x35, 0x56, 0x26, 0x4b, 0xc0, 0x17, 0x96, 0x33, 0x79, 0xe8 }; byte[] result = new byte[16]; MxoTwofish tf = new MxoTwofish(); tf.setIV(iv); tf.setKey(key); tf.encrypt(plainText, result); if (!ArrayUtils.equal(knownResult, result)) { Output.Write("Failed\n"); Output.WriteLine(StringUtils.bytesToString(knownResult)); Output.WriteLine(StringUtils.bytesToString(result)); return(0); } Output.Write("OK\n"); return(1); }
public void sendCastAbilityOnEntityId(UInt16 viewId, UInt32 animationId, UInt16 value) { ClientView theView = Store.currentClient.viewMan.getViewById(viewId); Random randomObject = new Random(); ushort randomHealth = (ushort)randomObject.Next(3, 1800); // RSI Health FX "send 02 03 02 00 02 80 80 80 90 ed 00 30 22 0a 00 28 06 00 00;" PacketContent pak = new PacketContent(); if (viewId == 0) { viewId = 2; } pak.addUint16(viewId, 1); UInt32 theGoID = 12; if (theView != null) { theGoID = theView.GoID; } switch (theGoID) { case 12: pak.addByte(0x02); pak.addByte(0x80); pak.addByte(0x80); pak.addByte(0x80); if (viewId == 2) { pak.addByte(0x80); pak.addByte(0xb0); } else { pak.addByte(0x0c); } pak.addUint32(animationId, 1); pak.addUintShort(Store.currentClient.playerData.assignSpawnIdCounter()); break; case 599: // Its more a demo - we "one hit" the mob currently so we must update this lock (WorldSocket.npcs.SyncRoot) { for (int i = 0; i < WorldSocket.npcs.Count; i++) { Mob thismob = (Mob)WorldSocket.npcs[i]; if (theView != null && thismob.getEntityId() == theView.entityId) { thismob.HitEnemyWithDamage(value, animationId); if (thismob.getHealthC() <= 0) { thismob.setIsDead(true); this.SendNpcDies(theView.ViewID, Store.currentClient, thismob); // We got some Exp for it - currently we just make a simple trick to calculate some exp // Just take currentLevel * modifier Random rand = new Random(); UInt32 expModifier = (UInt32)rand.Next(100, 500); UInt32 expGained = thismob.getLevel() * expModifier; // Update EXP new PlayerHandler().IncrementPlayerExp(expGained); thismob.setIsLootable(true); } WorldSocket.npcs[i] = thismob; } } } break; default: pak.addByte(0x02); pak.addByte(0x80); pak.addByte(0x80); pak.addByte(0x80); if (viewId == 2) { pak.addByte(0x80); pak.addByte(0xb0); } else { pak.addByte(0x0c); } pak.addUint32(animationId, 1); pak.addUintShort(Store.currentClient.playerData.assignSpawnIdCounter()); break; } string hex = StringUtils.bytesToString(pak.returnFinalPacket()); Store.currentClient.messageQueue.addObjectMessage(pak.returnFinalPacket(), false); Store.currentClient.FlushQueue(); }
public void sendCastAbilityOnEntityId(UInt16 viewId, UInt32 animationId) { ClientView theView = Store.currentClient.viewMan.getViewById(viewId); byte[] updateCount = NumericalUtils.uint16ToByteArrayShort(Store.currentClient.playerData.assignSpawnIdCounter()); Random rand = new Random(); ushort randomHealth = (ushort)rand.Next(3, 1800); // RSI Health FX "send 02 03 02 00 02 80 80 80 90 ed 00 30 22 0a 00 28 06 00 00;" PacketContent pak = new PacketContent(); if (viewId == 0) { viewId = 2; } pak.addUint16(viewId, 1); UInt32 theGoID = 12; if (theView != null) { theGoID = theView.GoID; } switch (theGoID) { case 12: pak.addByte(0x02); pak.addByte(0x80); pak.addByte(0x80); pak.addByte(0x80); if (viewId == 2) { pak.addByte(0x80); pak.addByte(0xb0); } else { pak.addByte(0x0c); } pak.addUint32(animationId, 1); pak.addByteArray(updateCount); break; case 599: pak.addByte(0x04); pak.addByte(0x80); pak.addByte(0x80); pak.addByte(0x80); pak.addByte(0xc0); pak.addUint16(randomHealth, 1); // health pak.addByte(0xc0); pak.addUint32(animationId, 1); pak.addByteArray(updateCount); pak.addByte(0x05); pak.addByte(0x00); pak.addByte(0x00); string hexNPC = StringUtils.bytesToString(pak.returnFinalPacket()); // Its more a demo - we "one hit" the mob currently so we must update this lock (WorldSocket.npcs.SyncRoot) { for (int i = 0; i < WorldSocket.npcs.Count; i++) { npc thismob = (npc)WorldSocket.npcs[i]; if (thismob.getEntityId() == theView.entityId) { thismob.setIsDead(true); thismob.setIsLootable(true); WorldSocket.npcs[i] = thismob; this.sendNPCDies(theView.ViewID, Store.currentClient, thismob); } } } break; default: pak.addByte(0x02); pak.addByte(0x80); pak.addByte(0x80); pak.addByte(0x80); if (viewId == 2) { pak.addByte(0x80); pak.addByte(0xb0); } else { pak.addByte(0x0c); } pak.addUint32(animationId, 1); pak.addByteArray(updateCount); break; } string hex = StringUtils.bytesToString(pak.returnFinalPacket()); Store.currentClient.messageQueue.addObjectMessage(pak.returnFinalPacket(), false); Store.currentClient.flushQueue(); }
private void sendMarginCharData(byte[] data, byte opcode, NetworkStream client, UInt16 shortAfterId, bool isLast) { // 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 numCharacterReplies++; PacketContent pak = new PacketContent(); pak.addByte(0x10); pak.addUint32(0, 1); pak.addUint32(newCharID, 1); pak.addUint16(shortAfterId, 1); pak.addUintShort(numCharacterReplies); if (isLast) { pak.addUintShort(1); } else { pak.addUintShort(0); } pak.addUintShort(opcode); if (data.Length > 0) { pak.addByteArray(new byte[] { 0x10, 0x00 }); pak.addUint16((UInt16)data.Length, 1); pak.addByteArray(data); } else { pak.addByteArray(new byte[] { 0x00, 0x00 }); } Output.WriteDebugLog("[MARGIN SERVER RESPONSE] for OPCODE " + opcode + " : " + StringUtils.bytesToString(pak.returnFinalPacket())); byte[] encryptedResponse = marginEncr.encrypt(pak.returnFinalPacket()); sendTCPVariableLenPacket(encryptedResponse, client); System.Threading.Thread.Sleep(50); }
public void parseCommand(string data) { Output.WriteLine("[Chat Command helper] Chat command is: '" + data + "'"); string[] commands = data.Split(' '); string command = commands[0].ToLower(); try{ if (command.Equals("?fix") && commands.Length > 1) { int maxRPC = int.Parse(commands[1]); for (int i = 0; i < maxRPC; i++) { Store.currentClient.playerData.setRPCCounter((UInt16)i); Store.currentClient.messageQueue.addRpcMessage(PacketsUtils.createSystemMessage("Trying to fix! " + i, Store.currentClient)); } } if (command.Equals("?teleport") && commands.Length == 4) { // parse the coord parameters parameters as int Store.currentClient.messageQueue.addObjectMessage(new PlayerHelper().teleport(int.Parse(commands[1]), int.Parse(commands[2]), int.Parse(commands[3])), false); Store.currentClient.messageQueue.addRpcMessage(PacketsUtils.createSystemMessage("Teleported!", Store.currentClient)); } if (command.Equals("?rsi") && commands.Length == 3) { //parse the rsi part and value Store.currentClient.messageQueue.addObjectMessage(new PlayerHelper().changeRsi(commands[1], int.Parse(commands[2])), false); Store.currentClient.messageQueue.addRpcMessage(PacketsUtils.createSystemMessage("Rsi changed!", Store.currentClient)); } if (command.StartsWith("?message")) { Output.WriteLine("[COMMAND HELPER]MESSAGE RECEIVED"); byte[] theMessage = PacketsUtils.createSystemMessageWithoutRPC(commands[1]); Store.world.sendRPCToAllPlayers(theMessage); } if (command.Equals("?playanim")) { string animId = commands[1]; if (animId.Length == 4) { ServerPackets pak = new ServerPackets(); pak.sendPlayerAnimation(Store.currentClient, animId); } } if (command.StartsWith("?playfx")) { string fxHEDID = commands[1]; DynamicArray din = new DynamicArray(); byte[] animationId = StringUtils.hexStringToBytes(fxHEDID); byte[] viewID = { 0x02, 0x00 }; Random rand = new Random(); ushort updateViewCounter = (ushort)rand.Next(3, 200); byte[] updateCount = NumericalUtils.uint16ToByteArrayShort(updateViewCounter); Output.WriteLine("Check if its really one byte or two : " + StringUtils.bytesToString(updateCount)); din.append(viewID); din.append(0x02); din.append(0x80); din.append(0x80); din.append(0x80); din.append(0x90); din.append(0xed); din.append(0x00); din.append(0x30); din.append(animationId); din.append(updateCount); Store.currentClient.messageQueue.addObjectMessage(din.getBytes(), false); } if (command.Contains("?send")) { // Sends a packet from a file string filename = "packet.txt"; TextReader tr = new StreamReader(filename); string hexContent = tr.ReadToEnd(); hexContent = hexContent.Replace(" ", string.Empty); hexContent = hexContent.Replace(" ", Environment.NewLine); tr.Close(); if (hexContent.Length > 0) { Store.currentClient.messageQueue.addObjectMessage(StringUtils.hexStringToBytes(hexContent), false); Output.writeToLogForConsole("[SENDPACK FROM FILE] Content : " + hexContent); } } if (command.Contains("?combat")) { byte[] dummypak = new byte[4]; TestUnitHandler test = new TestUnitHandler(); test.testCloseCombat(ref dummypak); } if (command.Contains("?mob")) { UInt32[] rsiIDs = new UInt32[10]; rsiIDs[0] = 0xB7010058; rsiIDs[1] = 0x89090058; rsiIDs[2] = 0xB5010058; rsiIDs[3] = 0x3A030008; rsiIDs[4] = 0x32030008; rsiIDs[5] = 0xD0010058; rsiIDs[6] = 0xD4010058; rsiIDs[7] = 0xB8040004; // Smith rsiIDs[8] = 0x92010058; // Seraph rsiIDs[9] = 0x56050004; Random rand = new Random(); int index = rand.Next(0, 9); double x = 0; double y = 0; double z = 0; byte[] Ltvector3d = Store.currentClient.playerInstance.Position.getValue(); NumericalUtils.LtVector3dToDoubles(Ltvector3d, ref x, ref y, ref z); byte[] xPos = NumericalUtils.floatToByteArray((float)x, 1); byte[] yPos = NumericalUtils.floatToByteArray((float)y, 1); byte[] zPos = NumericalUtils.floatToByteArray((float)z, 1); UInt64 currentEntityId = WorldSocket.entityIdCounter; WorldSocket.entityIdCounter++; uint rotation = 0; npc theMob = new npc(); theMob.setEntityId(currentEntityId); theMob.setDistrict(Convert.ToUInt16(data[0].ToString())); theMob.setDistrictName(Store.currentClient.playerData.getDistrict()); theMob.setName("HD Protector"); theMob.setLevel(255); theMob.setHealthM(UInt16.Parse(data[4].ToString())); theMob.setHealthC(UInt16.Parse(data[5].ToString())); theMob.setMobId((ushort)rsiIDs[index]); theMob.setRsiHex(StringUtils.bytesToString_NS(NumericalUtils.uint32ToByteArray(rsiIDs[index], 1))); theMob.setXPos(x); theMob.setYPos(y); theMob.setZPos(z); theMob.xBase = x; theMob.yBase = y; theMob.zBase = z; theMob.setRotation(rotation); theMob.setIsDead(false); theMob.setIsLootable(false); WorldSocket.npcs.Add(theMob); // we use this for a test to see if we can spawn mobs and how we can handle them // We refactor this } if (command.Contains("?sendrpc")) { // sends a RPC Packet from a File string filename = "rpcpacket.txt"; TextReader tr = new StreamReader(filename); string hexContent = tr.ReadToEnd(); hexContent = hexContent.Replace(" ", string.Empty); hexContent = hexContent.Replace(" ", Environment.NewLine); Output.Write("SEND RPC COMMAND : CONTENT : " + hexContent); tr.Close(); if (hexContent.Length > 0) { Store.currentClient.messageQueue.addRpcMessage(StringUtils.hexStringToBytes(hexContent)); Output.writeToLogForConsole("[SENDRPC FROM FILE] Content : " + hexContent); } } if (command.Contains("?checkrpc")) { DynamicArray din = new DynamicArray(); din.append(StringUtils.hexStringToBytes("2E1000FF7D020024000000310000000000000000000000000000000000000000000000000B0053796E61707A65373737001D004F6E2079656168204920646F2072656D656D62657220796F75203A2900")); Store.currentClient.messageQueue.addRpcMessage(din.getBytes()); } if (command.Contains("?testrpc")) { UInt16 maxRPC = 33279; // Just to reference if (Store.currentClient.playerData.currentTestRPC <= maxRPC) { // Only if it is below we send it - we test with a 5 size packet DynamicArray din = new DynamicArray(); if (Store.currentClient.playerData.currentTestRPC < 127) { din.append(NumericalUtils.uint16ToByteArrayShort(Store.currentClient.playerData.currentTestRPC)); } else { din.append(NumericalUtils.uint16ToByteArray(Store.currentClient.playerData.currentTestRPC, 0)); } din.append(0x00); din.append(0x00); din.append(0x00); Store.currentClient.messageQueue.addRpcMessage(din.getBytes()); ServerPackets pak = new ServerPackets(); pak.sendSystemChatMessage(Store.currentClient, "Test RPC Header : " + Store.currentClient.playerData.currentTestRPC.ToString(), "MODAL"); Store.currentClient.playerData.currentTestRPC++; } } if (command.Equals("?save")) { new PlayerHelper().savePlayerInfo(Store.currentClient); ServerPackets pak = new ServerPackets(); pak.sendSaveCharDataMessage(Store.currentClient, StringUtils.charBytesToString_NZ(Store.currentClient.playerInstance.CharacterName.getValue())); } } catch (Exception e) { Store.currentClient.messageQueue.addRpcMessage(PacketsUtils.createSystemMessage("Error parsing command!", Store.currentClient)); Output.WriteLine("[CHAT COMMAND PARSER] Error parsing request: " + data); Output.WriteLine("[CHAT COMMAND PARSER] DEBUG: " + e.Message + "\n" + e.StackTrace); } }
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; } }
// 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 int parseAttributes(ref byte[] buffer, int _offset) { _offset++; byte flag = 0x00; flag = BufferHandler.readByte(ref buffer, ref _offset); byte[] stateData = new byte[buffer.Length - _offset + 2]; ArrayUtils.copy(buffer, _offset - 2, stateData, 0, buffer.Length - _offset + 2); //Flag Bits{0,0,0,0,Vector3f Position Update, Yaw Update,Animation Update, AttributesPacked Update?} double x = 0; double y = 0; double z = 0; switch (flag) { case 0x02: Action.setValue(BufferHandler.readBytes(ref buffer, ref _offset, Action.getSize())); break; case 0x04: YawInterval.setValue(BufferHandler.readBytes(ref buffer, ref _offset, YawInterval.getSize())); break; case 0x08: x = (double)NumericalUtils.byteArrayToFloat(BufferHandler.readBytes(ref buffer, ref _offset, 4), 1); y = (double)NumericalUtils.byteArrayToFloat(BufferHandler.readBytes(ref buffer, ref _offset, 4), 1); z = (double)NumericalUtils.byteArrayToFloat(BufferHandler.readBytes(ref buffer, ref _offset, 4), 1); Position.setValue(NumericalUtils.doublesToLtVector3d(x, y, z)); break; case 0x0a: YawInterval.setValue(BufferHandler.readByte(ref buffer, ref _offset)); x = (double)NumericalUtils.byteArrayToFloat(BufferHandler.readBytes(ref buffer, ref _offset, 4), 1); y = (double)NumericalUtils.byteArrayToFloat(BufferHandler.readBytes(ref buffer, ref _offset, 4), 1); z = (double)NumericalUtils.byteArrayToFloat(BufferHandler.readBytes(ref buffer, ref _offset, 4), 1); Position.setValue(NumericalUtils.doublesToLtVector3d(x, y, z)); break; case 0x0e: // UInt16 unknown + LtVector3f UInt16 unknown = NumericalUtils.ByteArrayToUint16(BufferHandler.readBytes(ref buffer, ref _offset, 2), 1); x = NumericalUtils.byteArrayToFloat(BufferHandler.readBytes(ref buffer, ref _offset, 4), 1); y = NumericalUtils.byteArrayToFloat(BufferHandler.readBytes(ref buffer, ref _offset, 4), 1); z = NumericalUtils.byteArrayToFloat(BufferHandler.readBytes(ref buffer, ref _offset, 4), 1); Position.setValue(NumericalUtils.doublesToLtVector3d(x, y, z)); break; default: // ToDo: we need a proper way to proove if there is a 00 00 04 somewhere (and if set the offset to it) // If this doesnt match we need to write this somewhere... string message = "RPCMAIN : Unknown Client 03 Request Packet \r\n" + "Flag: " + flag + "\r\n " + "Content: \n" + StringUtils.bytesToString(stateData) + "\r\n"; Output.WriteClientViewRequestLog(message); // ...and we dont want to crash so we just say "offset is full packet" _offset = buffer.Length - 1; break; } // TODO: update player attribute packets someday (announce it to my spawners) Store.world.sendViewPacketToAllPlayers(stateData, Store.currentClient.playerData.getCharID(), NumericalUtils.ByteArrayToUint16(Store.currentClient.playerInstance.GetGoid(), 1), Store.currentClient.playerData.getEntityId()); return(_offset); }