public byte[] changeRsi(string part, int value) { string[] keys = { "sex", "body", "hat", "face", "shirt", "coat", "pants", "shoes", "gloves", "glasses", "hair", "facialdetail", "shirtcolor", "pantscolor", "coatcolor", "shoecolor", "glassescolor", "haircolor", "skintone", "tattoo", "facialdetailcolor", "leggins" }; int pos = -1; for (int i = 0; i < keys.Length; i++) { if (part.Equals(keys[i].ToLower())) { pos = i; break; } } if (pos >= 0) { int[] current = Store.currentClient.playerData.getRsiValues(); current[pos] = value; Store.currentClient.playerData.setRsiValues(current); byte[] rsiData = PacketsUtils.getRSIBytes(current); DynamicArray din = new DynamicArray(); byte[] rsiChangeHeader = { 0x02, 0x00, 0x02, 0x80, 0x89 }; din.append(rsiChangeHeader); din.append(rsiData); return din.getBytes(); } else { throw new FormatException("body part or clothes not found"); } }
public void sendMarketPlaceList(WorldClient client) { // ToDo: make it dynamic with database later (but the "handler" should give the items as arguments for this method // List Marketplace Items byte[] headerSeperator = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; // Should foreach this later on "Real Server" DynamicArray listItems = new DynamicArray(); listItems.append(StringUtils.hexStringToBytes("8703000000000034bdcf1200401f00000310db6a4a")); // Foot Wear listItems.append(0x00); // Seperate each item listItems.append(StringUtils.hexStringToBytes("2e00000003a04a000bd012000000FFFF01aedc6a4a")); // Google listItems.append(0x00); // Seperate each item listItems.append(StringUtils.hexStringToBytes("721a000003a04a000bd012000000FFFF01aedc6a4a")); // Item Data listItems.append(0x00); // Seperate each item listItems.append(StringUtils.hexStringToBytes("2e00000003a04a000bd01200000000FF01aedc6a4a")); // Item Data listItems.append(0x00); // Seperate each item // get data size byte[] itemSize = NumericalUtils.uint16ToByteArray((UInt16)listItems.getBytes().Length, 1); PacketContent pak = new PacketContent(); pak.addUint16((UInt16)RPCResponseHeaders.SERVER_LOAD_MARKERPLACE, 0); pak.addUintShort(9); // list offset pak.addByteArray(headerSeperator); pak.addUint16((UInt16)listItems.getBytes().Length,1); pak.addByteArray(listItems.getBytes()); client.messageQueue.addRpcMessage(pak.returnFinalPacket()); }
public byte[] getBytesWithHeader(bool timedRPC) { DynamicArray rpcStructure = new DynamicArray(); byte[] noTimedHeader = {0x04}; byte[] timedHeader = new byte[6]; byte[] time = TimeUtils.getUnixTime(); timedHeader[0] = 0x82; ArrayUtils.copy(time,0,timedHeader,1,4); timedHeader[5] = 0x04; // This makes it "82aabbccdd04" if(timedRPC) rpcStructure.append(timedHeader); else rpcStructure.append(noTimedHeader); // Calculate blocks number if (rpcInside==0){ // Is just 1 group of msgblocks rpcInside=1; rpcStructure.append(NumericalUtils.uint16ToByteArrayShort((UInt16)rpcInside)); rpcStructure.append(getBytes()); //Append our own content } else{ rpcStructure.append(NumericalUtils.uint16ToByteArrayShort((UInt16)rpcInside)); rpcStructure.append(din.getBytes()); //Append our own content } return rpcStructure.getBytes(); }
public RPCPacket(WorldClient _client) { destClient = _client; din = new DynamicArray(); this.addedMsgBlocks = 0; this.rpcInside = 0; }
public void processHyperJump(ref byte[] packet) { byte[] destXBytes = new byte[8]; byte[] destYBytes = new byte[8]; byte[] destZBytes = new byte[8]; byte[] maxHeight = new byte[4]; byte[] theLast4 = new byte[4]; // we dont know what this is lol DynamicArray restBytes = new DynamicArray(); ArrayUtils.copy(packet, 0, destXBytes, 0, 8); ArrayUtils.copy(packet, 8, destYBytes, 0, 8); ArrayUtils.copy(packet, 16, destZBytes, 0, 8); ArrayUtils.copy(packet, 30, maxHeight, 0, 4); ArrayUtils.copy(packet, packet.Length - 4,theLast4, 0, 4); // Players current X Z Y 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); int rotation = (int)Store.currentClient.playerInstance.YawInterval.getValue()[0]; float xPos = (float)x; float yPos = (float)y; float zPos = (float)z; float xDestFloat = (float)NumericalUtils.byteArrayToDouble(destXBytes,1); float yDestFloat = (float)NumericalUtils.byteArrayToDouble(destYBytes, 1); float zDestFloat = (float)NumericalUtils.byteArrayToDouble(destZBytes, 1); float distance = getDistance(xPos, yPos, zPos, xDestFloat, yDestFloat, zDestFloat); UInt16 duration = (UInt16)(distance * 1.5); //UInt32 startTime = TimeUtils.getUnixTimeUint32() - 100000; //UInt32 endTime = startTime + duration; UInt32 startTime = TimeUtils.getUnixTimeUint32(); UInt32 endTime = startTime + duration; PacketContent pak = new PacketContent(); pak.addByte(0x02); pak.addByte(0x00); pak.addByte(0x03); pak.addByte(0x09); pak.addByte(0x08); pak.addByte(0x00); pak.addFloatLtVector3f(xPos, yPos, zPos); pak.addUint32(startTime, 1); pak.addByte(0x80); pak.addByte(0x80); pak.addByte(0xb8); pak.addByte(0x14); // if 0xb8 pak.addByte(0x00); // if 0xb8 pak.addUint32(endTime, 1); pak.addByteArray(destXBytes); pak.addByteArray(destYBytes); pak.addByteArray(destZBytes); pak.addByteArray(new byte[] { 0x10, 0xe3, 0x00 }); pak.addByte(0x00); pak.addByte(0x00); pak.addByte(0x00); Store.currentClient.messageQueue.addObjectMessage(pak.returnFinalPacket(), true); }
public CharacterPack() { charData = new DynamicArray(); charNames = new DynamicArray(); numChars = 0; totalChars = 0; }
public byte[] getByteContents() { DynamicArray response = new DynamicArray(); byte[] numWorldsH = NumericalUtils.uint16ToByteArray((UInt16)numWorlds, 1); response.append(numWorldsH); response.append(worlds.getBytes()); return response.getBytes(); }
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(); }
public byte[] getByteContents() { DynamicArray response = new DynamicArray(); byte[] totalCharsH = NumericalUtils.uint16ToByteArray((UInt16)totalChars, 1); response.append(totalCharsH); response.append(charData.getBytes()); response.append(charNames.getBytes()); return response.getBytes(); }
// ToDo: Move it to player Packets and make a ?moa command for it public void processChangeMoaRSI(byte[] rsi) { DynamicArray din = new DynamicArray(); din.append(0x03); din.append(0x02); din.append(0x00); din.append(StringUtils.hexStringToBytes("028100808080b052c7de12ab04")); din.append(rsi); din.append(0x41); din.append(0x00); }
public byte[] getCreationAttributes() { DynamicArray din = new DynamicArray(); bool lastGroupEmpty = true; int attribCounter = 0; for (int i = (creationGroups-1);i>=0;i--){ int attribOffset = i*7; bool anyAttribEnabled = false; byte tempHeader = 0x00; for (int j = 6;j>=0;j--){ int position = attribOffset+j; // This verifies that the attribute is in a group but groups has not 7 attributes if (position<attributesCreation.Length){ Attribute temp = attributesCreation[attribOffset+j]; if (temp.isActive()){ anyAttribEnabled = true; attribCounter++; tempHeader = (byte) (tempHeader + (1<<j)); // Displacement din.insertBefore(temp.getValue()); } } } // Updating last attribute group, set it as 0b0XXXXXXX if (i == (creationGroups-1)){ if (anyAttribEnabled){ din.insertBefore(tempHeader); lastGroupEmpty = false; } } // Updating other than last attribute group else{ if (!lastGroupEmpty){ tempHeader = (byte) (tempHeader+0x80); din.insertBefore(tempHeader); }else{ if(anyAttribEnabled){ din.insertBefore(tempHeader); lastGroupEmpty = false; } } } } //add the counter of attributes sent din.insertBefore((byte)attribCounter); return din.getBytes(); }
public byte[] getBytes() { DynamicArray rpcStructure = new DynamicArray(); byte [] totalMsgBlocks= NumericalUtils.uint16ToByteArrayShort((UInt16)addedMsgBlocks); byte [] currentCounter = getRpcBytes(); rpcStructure.append(currentCounter); rpcStructure.append(totalMsgBlocks); rpcStructure.append(din.getBytes()); // Increment RPC Counter incrementRpcCounter(addedMsgBlocks); return rpcStructure.getBytes(); }
public void processDecreaseCash(UInt16 amount, UInt16 type) { // send 02 04 01 00 16 01 0a 80 e4 ff 00 00 00 02 00 00 00; byte[] header = { 0x80, 0xe4 }; long newCash = Store.currentClient.playerData.getInfo() - (long)amount; Store.currentClient.playerData.setInfo(newCash); Store.dbManager.WorldDbHandler.savePlayer(Store.currentClient); DynamicArray din = new DynamicArray(); din.append(header); din.append(NumericalUtils.uint32ToByteArray((UInt32)newCash, 1)); din.append(NumericalUtils.uint16ToByteArray(type, 1)); din.append(0x00); din.append(0x00); Store.currentClient.messageQueue.addRpcMessage(din.getBytes()); }
/* * Add a RPC Message with size byte automatically to the queue */ public void addRpcMessage(byte[] messageBlock) { byte[] rpcSizeByte; if (messageBlock.Length > 127) { rpcSizeByte = NumericalUtils.uint16ToByteArray((UInt16)(messageBlock.Length + 0x8000), 0); } else { rpcSizeByte = NumericalUtils.uint16ToByteArrayShort((UInt16)messageBlock.Length); } DynamicArray content = new DynamicArray(); content.append(rpcSizeByte); content.append(messageBlock); SequencedMessage message = new SequencedMessage(content.getBytes()); RPCMessagesQueue.Add(message); }
private static void playerRSIPacket(out DynamicArray rsiPacket, out DynamicArray creationPacket, WorldClient client, ushort spawnIdCounter) { //Create the packet for the player rsiPacket = new DynamicArray(); byte[] rsi = PacketsUtils.getRSIBytes(client.playerData.getRsiValues()); byte[] CurCombatExclusiveAbility = { 0x00, 0x10, 0x00, 0x00 }; //TODO: fix this 03 01 00 rsiPacket.append(new byte[] { 0x01, 0x00 }); ///////////////////////////////////////////// client.playerInstance.disableAllAttributes(); //Predisable to just send what we need to spawn client.playerInstance.RealFirstName.enable(); client.playerInstance.RealLastName.enable(); client.playerInstance.Health.enable(); client.playerInstance.MaxHealth.enable(); client.playerInstance.YawInterval.enable(); //ROTATION client.playerInstance.OrganizationID.enable(); client.playerInstance.StealthAwareness.setValue((byte)0x01); // TODO: See what's stealth awareness client.playerInstance.InnerStrengthAvailable.enable(); client.playerInstance.CharacterName.enable(); client.playerInstance.TitleAbility.enable(); client.playerInstance.CharacterID.enable(); // It was set when grabbing from database client.playerInstance.RSIDescription.setValue(rsi); client.playerInstance.InnerStrengthMax.enable(); client.playerInstance.Position.enable(); client.playerInstance.Level.enable(); client.playerInstance.CombatantMode.setValue((byte)0x22); //TODO: see what's combatantmode client.playerInstance.CurExclusiveAbility.setValue(CurCombatExclusiveAbility); //TODO: see what's this // ok we set all our values - lets get the generated packet for us DynamicArray creationPacketWithoutView = Store.world.objMan.generateCreationPacket(client.playerInstance, 0x0000,(byte)spawnIdCounter); creationPacket = Store.world.objMan.generateCreationPacket(client.playerInstance, 0x0000,(byte)spawnIdCounter); }
// Shows the Animation of a target Player public void processFXfromPlayer(UInt16 viewID, byte[] animation) { Random rand = new Random(); ushort updateViewCounter = (ushort)rand.Next(3, 200); byte[] updateCount = NumericalUtils.uint16ToByteArrayShort(updateViewCounter); DynamicArray din = new DynamicArray(); din.append(NumericalUtils.uint16ToByteArray(viewID, 1)); din.append(0x00); din.append(0x80); din.append(0x80); din.append(0x80); din.append(0x0c); din.append(animation); // uint32 anim ID din.append(updateCount); din.append(0x00); din.append(0x00); Store.currentClient.messageQueue.addObjectMessage(din.getBytes(), false); }
public void processHyperJumpTest(ref byte[] packet) { // The working pak : send 82 9a f3 25 49 03 02 00 03 08 f3 fa 84 46 bb 2e 0d 46 3e 22 51 c6 33 f9 83 28 ff 01 64 01 00 00 00 00 00 00 00 00 00 00 00 08 41 6e 64 65 72 73 6f 6e 06 54 68 6f 6d 61 73 ff 04 80 73 1a e9 82 80 60 04 00 02 8e 00 00 00 01 00 00 00 00 00 00 8f 01 00 02 00 2a 03 02 ff 28 0a 32 00 f0 20 46 04 00 8e 16 84 28 00 00 00 60 50 85 d6 40 00 00 00 00 00 7e a3 40 00 00 00 80 25 da c9 c0 00 ff 00 00 00 00 00 f7 00 00 00 eb 00 00 00 00 00 28 0a ff 00 31 5e 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ff 00 00 00 00 00 00 00 00 00 00 00 00 80 3f 11 00 00 00 4b b1 00 00 71 02 00 00 3f 00 00 00 01 22 00 00 00 00 00 00 00 05 00 01 00 04 f3 fa 84 46 bb 2e 0d 46 3e 22 51 c6 00 00; //this.testHyperJumpPaket(); //return; // REMOVE THIS LATER!!! /* destX = (string.join(data[9:17],"")).decode('hex') destY = (string.join(data[17:25],"")).decode('hex') destZ = (string.join(data[25:33],"")).decode('hex') maxHeight = (string.join(data[39:43],"")).decode('hex') lastBytes = (string.join(data[-4:],"")).decode('hex') (viewData,newX,newY,newZ) = self.hyperjMan.processHyperJump(x,y,z,destX,destY,destZ,maxHeight,lastBytes) */ byte[] destXBytes = new byte[8]; byte[] destYBytes = new byte[8]; byte[] destZBytes = new byte[8]; byte[] maxHeight = new byte[4]; DynamicArray restBytes = new DynamicArray(); ArrayUtils.copy(packet, 0, destXBytes, 0, 8); ArrayUtils.copy(packet, 0, destYBytes, 8, 8); ArrayUtils.copy(packet, 0, destZBytes, 16, 8); ArrayUtils.copy(packet, 0, maxHeight, 30, 4); /* int packetSize = packet.Length - 28; byte[] restBytes = new byte[packetSize]; ArrayUtils.copy(packet, 0, restBytes, 28, packetSize); */ // Players current X Z Y 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); int rotation = (int)Store.currentClient.playerInstance.YawInterval.getValue()[0]; float xPos = (float)x; float yPos = (float)y; float zPos = (float)z; Store.currentClient.playerData.incrementJumpID(); // Okay we know have what we need to test hyperjump - lets do it // Normally we would loop and increase the player pos..but for test we dont do it DynamicArray din = new DynamicArray(); din.append(StringUtils.hexStringToBytes("02000308")); // The 03 header (update myself) din.append(NumericalUtils.floatToByteArray(xPos, 1)); // Current X din.append(NumericalUtils.floatToByteArray(yPos, 1)); // Current Y din.append(NumericalUtils.floatToByteArray(zPos, 1)); // Current Z din.append(StringUtils.hexStringToBytes("00008328FF016401000000000000000000000008416E646572736F6E0654686F6D6173FFE018400C4105E0020400CD01000000010000000000008F010002002A0302FF280A3200")); din.append(StringUtils.hexStringToBytes("F0204604")); // Max height //din.append(maxHeight); // From Source Packet din.append(StringUtils.hexStringToBytes("00")); din.append(NumericalUtils.uint16ToByteArray(Store.currentClient.playerData.getJumpID(), 0)); // Must be increment in the loop din.append(StringUtils.hexStringToBytes("8428")); din.append(destXBytes); din.append(destYBytes); din.append(destZBytes); din.append(StringUtils.hexStringToBytes("00FF0000000000F7000000E70000000000280AFF00315E00000000000000000000000000000000FF000000000000000000000000803F110000004BB10000710200003F0000000022000000000000000500010004")); din.append(NumericalUtils.floatToByteArray(xPos, 1)); // Current X din.append(NumericalUtils.floatToByteArray(yPos, 1)); // Current Y din.append(NumericalUtils.floatToByteArray(zPos, 1)); // Current Z din.append(0x00); din.append(0x00); Output.writeToLogForConsole("HJ PACKET DUMP : " + StringUtils.bytesToString(din.getBytes())); Store.currentClient.messageQueue.addObjectMessage(din.getBytes(), true); }
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 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()); }
public WorldsPack() { worlds = new DynamicArray(); }
public void certConnectRequest(byte[] packet, NetworkStream client) { int firstnum = BitConverter.ToInt16(packet, 3); int authstart = BitConverter.ToInt16(packet, 5); if (firstnum != 3) { //showMarginDebug("FirstNum is not 3, it is" + firstnum); } if (authstart != 310) { //showMarginDebug("AuthStart is not 0x3601"); } // Get the Signature byte[] signature = new byte[128]; ArrayUtils.copy(packet, 7, signature, 0, 128); // TODO MD5 Signature and verify it with RSA to check if everything is correct // Get the signedData byte[] signedData = new byte[packet.Length - 135]; ArrayUtils.copy(packet, 135, signedData, 0, packet.Length - 135); int userid = BitConverter.ToInt32(signedData, 1); this.userID = (UInt32)userid; // Stripout Exponent and Modulus byte[] exponent = { 0x00, 0x00, 0x00, 0x11 }; byte[] modulus = new byte[96]; ArrayUtils.copy(signedData, 82, modulus, 0, 96); // Init our encryptor with users modulus and exponent marginEncr.setUserPubKey(exponent, modulus); // build the final packet, it consists of 1 byte 0x00 + twofish key for world and margin + encryptIV byte[] encryptMeResponse = new byte[33]; encryptMeResponse[0] = 0x00; ArrayUtils.copy(marginEncr.getTFKey(), 0, encryptMeResponse, 1, 16); ArrayUtils.copy(marginEncr.getIV(), 0, encryptMeResponse, 17, 16); byte[] encryptedShit = { }; encryptedShit = marginEncr.encryptUsersPublic(encryptMeResponse); byte[] blobSize = NumericalUtils.uint16ToByteArray((UInt16)encryptedShit.Length, 1); byte[] header = { 0x02, 0x03, 0x00 }; // Write final packet DynamicArray din = new DynamicArray(); din.append(header); din.append(blobSize); din.append(encryptedShit); sendTCPVariableLenPacket(din.getBytes(), client); }
public void processSelfUpdateHealthIS(UInt16 viewID, UInt16 healthC, UInt16 isC) { DynamicArray din = new DynamicArray(); din.append(0x03); din.append(NumericalUtils.uint16ToByteArray(viewID, 1)); din.append(0x02); din.append(0x80); din.append(0x80); din.append(0x80); din.append(0x50); din.append(NumericalUtils.uint16ToByteArray(isC, 1)); din.append(NumericalUtils.uint16ToByteArray(healthC, 1)); din.append(0x00); // ToDO SEND PAK and get real health and IS }
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); if (decrypted == null) { // This shouldnt happen - but can happen tcpClient.Close(); clientStream.Close(); return; } // 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(data, "MARGINCLIENT", "0", "0", "0"); if (data.Length >= 3) { 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; } } }
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 void parseCommand(string 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); ServerPackets pak = new ServerPackets(); pak.sendSystemChatMessage(Store.currentClient, "Trying to fix!", "BROADCAST"); } } 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); ServerPackets pak = new ServerPackets(); pak.sendSystemChatMessage(Store.currentClient, "Teleported!", "BROADCAST"); } 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); ServerPackets pak = new ServerPackets(); pak.sendSystemChatMessage(Store.currentClient, "Rsi changed!", "BROADCAST"); } if (command.Contains("?updatersi")) { int[] current = Store.currentClient.playerData.getRsiValues(); byte[] rsiData = PacketsUtils.getRSIBytes(current); ServerPackets packets = new ServerPackets(); packets.sendAppeareanceUpdate(Store.currentClient, rsiData); } if (command.StartsWith("?spawndatanode")) { ServerPackets pak = new ServerPackets(); pak.sendSystemChatMessage(Store.currentClient, "Spawn Datanode!", "BROADCAST"); pak.spawnDataNodeView(Store.currentClient); } if (command.StartsWith("?message")) { byte[] theMessage = PacketsUtils.createSystemMessageWithoutRPC(commands[1]); Store.world.sendRPCToAllPlayers(theMessage); } if (command.Contains("?loot")) { UInt32 objectId = UInt32.Parse(commands[1]); ServerPackets packets = new ServerPackets(); packets.sendLootWindowTest(Store.currentClient, objectId); } if (command.Contains("?moa")) { string hexMoa = commands[1]; byte[] moaRSI = StringUtils.hexStringToBytes(hexMoa); Array.Reverse(moaRSI, 0, moaRSI.Length); ServerPackets pak = new ServerPackets(); pak.sendSystemChatMessage(Store.currentClient, "Changed MOA to hexMoa d!", "BROADCAST"); pak.sendChangeChangeMoaRSI(Store.currentClient, moaRSI); } if (command.Equals("?playanim")) { string animId = commands[1]; if (animId.Length == 4) { ServerPackets pak = new ServerPackets(); pak.sendPlayerAnimation(Store.currentClient, animId); } } if (command.Equals("?playmove")) { string animIdString = commands[1]; // Should just one byte if (animIdString.Length == 2) { byte animId = Byte.Parse(animIdString); ServerPackets pak = new ServerPackets(); pak.sendPlayerMoveAnim(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); 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; Mob theMob = new Mob(); 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); lock (WorldSocket.npcs) { WorldSocket.npcs.Add(theMob); } lock (WorldSocket.gameServerEntities) { WorldSocket.gameServerEntities.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); 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()); #if DEBUG ServerPackets pak = new ServerPackets(); pak.sendSystemChatMessage(Store.currentClient, "Test RPC Header : " + Store.currentClient.playerData.currentTestRPC.ToString(), "MODAL"); #endif 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)); #if DEBUG Output.WriteLine("[CHAT COMMAND PARSER] Error parsing request: " + data); Output.WriteLine("[CHAT COMMAND PARSER] DEBUG: " + e.Message + "\n" + e.StackTrace); #endif } }
public void processUpdateExp() { Random rand = new Random(); UInt32 expval = (UInt32)rand.Next(1000, 200000); ArrayList content = new ArrayList(); // ToDo : Save new EXP Value in the Database and update mpm exp // ToDo2 : Check if exp events are running to multiple the EXP // The Animation DynamicArray expanim = new DynamicArray(); expanim.append(0x80); expanim.append(0xe6); expanim.append(NumericalUtils.uint32ToByteArray(expval, 1)); expanim.append(0x01); // Gain Type expanim.append(StringUtils.hexStringToBytes("000000")); Store.currentClient.messageQueue.addRpcMessage(expanim.getBytes()); // The BAR DynamicArray expbar = new DynamicArray(); expbar.append(0x80); expbar.append(0xe5); expbar.append(NumericalUtils.uint32ToByteArray(expval, 1)); expbar.append(0x01); // Gain Type expbar.append(StringUtils.hexStringToBytes("000000")); Store.currentClient.messageQueue.addRpcMessage(expbar.getBytes()); }
public byte[] loadEquippedAbilities() { DynamicArray din = new DynamicArray(); //AbilityItem abTemp = AbilityDB.Find(delegate(AbilityItem a) { return a.getAbilityID() == id; }); foreach (MarginAbilityItem ability in Abilities) { if (ability.getLoaded() == true) { Int32 finalAblityID = ability.getAbilityID() + ability.getLevel(); din.append(NumericalUtils.uint16ToByteArray(ability.getSlot(), 1)); // slot din.append(NumericalUtils.int32ToByteArray(finalAblityID, 1)); } } return din.getBytes(); }
public void sendTCPVariableLenPacket(byte[] packet, NetworkStream client) { byte[] size = { }; byte[] bytesize = { }; if (packet.Length > 127){ //Do NOT reverse here :P bytesize = NumericalUtils.uint16ToByteArray((UInt16)(packet.Length + 0x8000),0); } else{ bytesize = NumericalUtils.uint16ToByteArrayShort((ushort)packet.Length); } byte[] finalPacket = new byte[packet.Length+bytesize.Length]; DynamicArray din = new DynamicArray(); din.append(bytesize); din.append(packet); finalPacket = din.getBytes(); try { client.Write(finalPacket, 0, finalPacket.Length); } catch (Exception ex) { Console.WriteLine("ERROR ex: " + ex.ToString()); throw; } client.Flush(); }
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 byte[] loadInventory(int charID) { List<MarginInventoryItem> Inventory = new List<MarginInventoryItem>(); Inventory = Store.dbManager.MarginDbHandler.loadInventory(charID); DynamicArray din = new DynamicArray(); foreach (MarginInventoryItem item in Inventory) { din.append(NumericalUtils.uint16ToByteArrayShort(item.getSlot())); // slot din.append(NumericalUtils.uint32ToByteArray(item.getItemID(),1)); din.append(0x00); din.append(0x00); din.append(0x00); // ToDo : Figure out the bit flags shit thing for amount din.append(0x0c); // ToDo : same for purity } return din.getBytes(); }
public byte[] GetCreationAttributes() { DynamicArray din = new DynamicArray(); bool lastGroupEmpty = true; int attribCounter = 0; for (int i = (creationGroups - 1); i >= 0; i--) { int attribOffset = i * 7; bool anyAttribEnabled = false; byte tempHeader = 0x00; for (int j = 6; j >= 0; j--) { int position = attribOffset + j; // This verifies that the attribute is in a group but groups has not 7 attributes if (position < attributesCreation.Length) { Attribute temp = attributesCreation[attribOffset + j]; if (temp.isActive()) { anyAttribEnabled = true; attribCounter++; tempHeader = (byte)(tempHeader + (1 << j)); // Displacement din.insertBefore(temp.getValue()); } } } // Updating last attribute group, set it as 0b0XXXXXXX if (i == (creationGroups - 1)) { if (anyAttribEnabled) { din.insertBefore(tempHeader); lastGroupEmpty = false; } } // Updating other than last attribute group else { if (!lastGroupEmpty) { tempHeader = (byte)(tempHeader + 0x80); din.insertBefore(tempHeader); } else { if (anyAttribEnabled) { din.insertBefore(tempHeader); lastGroupEmpty = false; } } } } //add the counter of attributes sent din.insertBefore((byte)attribCounter); return(din.getBytes()); }
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; } }
public static byte[] doublesToLtVector3d(double x,double y,double z) { DynamicArray din = new DynamicArray(); din.append(NumericalUtils.doubleToByteArray(x,1)); din.append(NumericalUtils.doubleToByteArray(y,1)); din.append(NumericalUtils.doubleToByteArray(z,1)); return din.getBytes(); }
public void certConnectRequest(byte[] packet, NetworkStream client) { int firstnum = BitConverter.ToInt16(packet, 3); int authstart = BitConverter.ToInt16(packet, 5); if (firstnum != 3) { //showMarginDebug("FirstNum is not 3, it is" + firstnum); } if (authstart != 310) { //showMarginDebug("AuthStart is not 0x3601"); } // Get the Signature byte[] signature= new byte[128]; ArrayUtils.copy(packet,7,signature,0,128); // TODO MD5 Signature and verify it with RSA to check if everything is correct // Get the signedData byte[] signedData = new byte[packet.Length - 135]; ArrayUtils.copy(packet,135,signedData,0,packet.Length-135); int userid = BitConverter.ToInt32(signedData, 1); this.userID = (UInt32)userid; // Stripout Exponent and Modulus byte[] exponent = {0x00, 0x00, 0x00, 0x11}; byte[] modulus = new byte[96]; ArrayUtils.copy(signedData,82,modulus,0,96); // Init our encryptor with users modulus and exponent marginEncr.setUserPubKey(exponent, modulus); // build the final packet, it consists of 1 byte 0x00 + twofish key for world and margin + encryptIV byte[] encryptMeResponse = new byte[33]; encryptMeResponse[0] = 0x00; ArrayUtils.copy(marginEncr.getTFKey(),0,encryptMeResponse,1,16); ArrayUtils.copy(marginEncr.getIV(),0,encryptMeResponse,17,16); byte[] encryptedShit = { }; encryptedShit = marginEncr.encryptUsersPublic(encryptMeResponse); byte[] blobSize = NumericalUtils.uint16ToByteArray((UInt16)encryptedShit.Length,1); byte[] header = { 0x02, 0x03, 0x00 }; // Write final packet DynamicArray din = new DynamicArray(); din.append(header); din.append(blobSize); din.append(encryptedShit); sendTCPVariableLenPacket(din.getBytes(), client); }
public static byte[] floatsToLtVector3f(float x,float y,float z) { DynamicArray din = new DynamicArray(); din.append(NumericalUtils.floatToByteArray(x,1)); din.append(NumericalUtils.floatToByteArray(y,1)); din.append(NumericalUtils.floatToByteArray(z,1)); return din.getBytes(); }