public static charBytesToString_NZ ( byte data ) : string | ||
data | byte | |
return | string |
public void SendWhoCMD(WorldClient client) { PacketContent pak = new PacketContent(); pak.addUint16((UInt16)RPCResponseHeaders.SERVER_CHAT_WHO_RESPONSE, 0); pak.addUint16(5, 1); // Alsways there pak.addByte(0x00); // We are not sure why but as its just 3 bytes for the nums we need "space" bytes pak.addUint16((UInt16)WorldSocket.Clients.Count, 1); pak.addByte(0x00); // Again there is space foreach (string clientKey in WorldSocket.Clients.Keys) { WorldClient theClient = WorldSocket.Clients[clientKey] as WorldClient; // ToDo: this is not complete implemented - the first is maybe an offset- needs more research firstex pak.addHexBytes("3c014801"); // This is just from logs pak.addByte(0xef); // profession pak.addHexBytes("010000"); pak.addByteArray(theClient.playerInstance.Level.getValue()); pak.addByte(0x01); pak.addByte(0x00); } foreach (string clientKey in WorldSocket.Clients.Keys) { WorldClient theClient = WorldSocket.Clients[clientKey] as WorldClient; // ToDo: this is really dirty hacky string charname = StringUtils.charBytesToString_NZ(theClient.playerInstance.CharacterName.getValue()); pak.addSizedTerminatedString(charname); } Store.currentClient.messageQueue.addRpcMessage(pak.returnFinalPacket()); }
public void processInvitePlayerToCrew(ref byte[] rpcData) { // Request Packet: 80 84 19 00 07 00 02 10 00 54 72 69 6e 69 74 79 73 27 73 20 43 72 65 77 00 07 00 54 68 65 4e 65 6f 00 // Request Packet: 80 84 22 00 07 00 03 19 00 54 68 69 73 20 69 73 20 74 68 65 20 41 77 65 73 6f 6d 65 20 43 72 65 77 00 09 00 54 72 69 6e 69 74 79 73 00 // Response // ToDO: add it to the tempCrews and check if name is reserved on DB (and check if double names are possible) // ToDo: Questions 1. should we persist it directly to reserve crewname in the DB ? maybe its better PacketReader pakRead = new PacketReader(rpcData); UInt16 someUint16 = pakRead.readUInt16(1); UInt16 someUint162 = pakRead.readUInt16(1); uint orgId = pakRead.readUint8(); string crewName = pakRead.readSizedZeroTerminatedString().Trim(); string playerHandle = pakRead.readSizedZeroTerminatedString().Trim(); bool isCrewNameAvailable = Store.dbManager.WorldDbHandler.isCrewNameAvailable(crewName); // ToDo: Just "reserve" the crewName - so if crewName exists and membercount is just one or zero and its older than a day - delete it (this can be done by the "isCrewNameAvailable" too). ServerPackets pak = new ServerPackets(); if (isCrewNameAvailable) { Store.dbManager.WorldDbHandler.addCrew(crewName, StringUtils.charBytesToString_NZ(Store.currentClient.playerInstance.CharacterName.getValue())); pak.sendCrewInviteToPlayer(playerHandle, crewName); } else { pak.sendSystemChatMessage(Store.currentClient, "Crewname was already taken - please choose a new one", "BROADCAST"); } }
private static void SavePlayers() { foreach (string clientKey in WorldSocket.Clients.Keys) { WorldClient thisclient = WorldSocket.Clients[clientKey] as WorldClient; if (thisclient != null && thisclient.playerData.lastSaveTime == 0) { thisclient.playerData.lastSaveTime = TimeUtils.getUnixTimeUint32(); } if (thisclient != null && (TimeUtils.getUnixTimeUint32() - thisclient.playerData.lastSaveTime) > 20) { thisclient.playerData.lastSaveTime = TimeUtils.getUnixTimeUint32(); // Save Player new PlayerHelper().savePlayerInfo(thisclient); // Notify Player about save ServerPackets pak = new ServerPackets(); pak.sendSaveCharDataMessage(thisclient, StringUtils.charBytesToString_NZ(thisclient.playerInstance.CharacterName.getValue())); } // Handle Jackout exit if (thisclient.playerData.isJackoutInProgress == true && (thisclient.playerData.jackoutStartTime - TimeUtils.getUnixTimeUint32()) > 5) { ServerPackets packets = new ServerPackets(); packets.sendExitGame(thisclient); } } }
public void processTeamInviteAnswer(ref byte[] packet) { // read the important things byte[] unknownUint16_1 = new byte[2]; byte[] sizeString = new byte[2]; ArrayUtils.copyTo(packet, 3, unknownUint16_1, 0, 2); ArrayUtils.copyTo(packet, 7, sizeString, 0, 2); UInt16 sizeCharName = NumericalUtils.ByteArrayToUint16(sizeString, 1); byte[] characterNameBytes = new byte[sizeCharName]; ArrayUtils.copyTo(packet, 9, characterNameBytes, 0, sizeCharName); string characterName = StringUtils.charBytesToString(characterNameBytes); // if it is 0 - then he has accepted the request - otherwise decline and ..we dont care if (NumericalUtils.ByteArrayToUint16(unknownUint16_1, 1) == 0) { lock (WorldSocket.missionTeams) { foreach (MissionTeam team in WorldSocket.missionTeams) { if (team.characterMasterName.Equals(characterName)) { team.addMember(StringUtils.charBytesToString_NZ(Store.currentClient.playerInstance.CharacterName.getValue())); } } } } }
public void sendCrewInviteToPlayer(string playerHandle, string crewName) { // ToDo: fix the name display issue ? string charname = StringUtils.charBytesToString_NZ(Store.currentClient.playerInstance.CharacterName.getValue()); UInt16 crewOffset = (UInt16)(charname.Length + 7 + 3); PacketContent pak = new PacketContent(); pak.addHexBytes("8088"); // ToDo: is this the RPC Response Header ? pak.addUint16(7, 1); // Start Offsset for Charactername pak.addUint16(crewOffset, 1); pak.addByte(0x01); pak.addSizedTerminatedString(StringUtils.charBytesToString_NZ(Store.currentClient.playerInstance.CharacterName.getValue())); pak.addSizedTerminatedString(crewName); Store.world.sendRPCToOnePlayerByHandle(pak.returnFinalPacket(), playerHandle); }
// Checks and create a mission Team if you are not on a mission public void checkAndCreateMissionTeam(WorldClient client) { if (client.playerData.getMissionTeam() == null) { string missionTeamName = StringUtils.charBytesToString_NZ(client.playerInstance.CharacterName.getValue()) + "'s Mission Team"; ServerPackets packets = new ServerPackets(); packets.sendTeamCreation(client, missionTeamName); // Add the Team to our global Team List MissionTeam team = new MissionTeam(missionTeamName, StringUtils.charBytesToString_NZ(client.playerInstance.CharacterName.getValue())); lock (WorldSocket.missionTeams) { WorldSocket.missionTeams.Add(team); } } }
/// <summary> /// Send a Message to One Player (like private Message by Handle) /// </summary> /// <param name="packet">Packet Stream</param> /// <param name="playerHandle">Player Handle to send the Packet</param> public void sendRPCToOnePlayerByHandle(byte[] packet, string playerHandle) { lock (Clients.SyncRoot) { foreach (string clientKey in Clients.Keys) { WorldClient client = Clients[clientKey] as WorldClient; string charname = StringUtils.charBytesToString_NZ(client.playerInstance.CharacterName.getValue()); Output.writeToLogForConsole("Charname |" + charname + "| PlayerHandle |" + playerHandle + "|"); int lenCharname = charname.Length; int playerHandleLen = playerHandle.Length; if (charname == playerHandle) { client.messageQueue.addRpcMessage(packet); client.FlushQueue(); } } } }
// This is for team and crew invites public void processInviteAnswer(ref byte[] packet) { // read the important things byte[] maybeType = new byte[2]; byte[] sizeString = new byte[2]; ArrayUtils.copyTo(packet, 3, maybeType, 0, 2); ArrayUtils.copyTo(packet, 7, sizeString, 0, 2); UInt16 sizeCharName = NumericalUtils.ByteArrayToUint16(sizeString, 1); byte[] characterNameBytes = new byte[sizeCharName]; ArrayUtils.copyTo(packet, 9, characterNameBytes, 0, sizeCharName); string characterName = StringUtils.charBytesToString(characterNameBytes); // if it is 0 - then he has accepted the request - otherwise decline and ..we dont care switch (NumericalUtils.ByteArrayToUint16(maybeType, 1)) { // Team Invites case 0: lock (WorldSocket.missionTeams) { foreach (MissionTeam team in WorldSocket.missionTeams) { if (team.characterMasterName.Equals(characterName)) { team.addMember(StringUtils.charBytesToString_NZ(Store.currentClient.playerInstance.CharacterName.getValue())); } } } break; // Crew Invites case 2: // ToDo: add to Crew and maybe to faction (if crew is part of faction) // ToDo: Generate Repsonse for all connected crew mates and the new member // ToDo: add to crew and figure out the responses that are necessary (like crew message , player update etc.) // ToDo: for this the "2_player_action" logs could be useful. break; } }
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 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); } }
private static void CheckPlayerViews() { // Check for Player Views lock (WorldSocket.Clients.SyncRoot) { foreach (string clientKey in WorldSocket.Clients.Keys) { // get Current client WorldClient currentClient = WorldSocket.Clients[clientKey] as WorldClient; // Loop all Clients and check if we need to create a view for it foreach (string clientOtherKey in WorldSocket.Clients.Keys) { WorldClient otherClient = WorldSocket.Clients[clientOtherKey] as WorldClient; if (otherClient != currentClient) { ClientView clientView = currentClient.viewMan.getViewForEntityAndGo( otherClient.playerData.getEntityId(), NumericalUtils.ByteArrayToUint16(otherClient.playerInstance.GetGoid(), 1)); // Create Maths math = new Maths(); double currentPlayerX = 0; double currentPlayerY = 0; double currentPlayerZ = 0; double otherPlayerX = 0; double otherPlayerY = 0; double otherPlayerZ = 0; NumericalUtils.LtVector3dToDoubles(currentClient.playerInstance.Position.getValue(), ref currentPlayerX, ref currentPlayerY, ref currentPlayerZ); NumericalUtils.LtVector3dToDoubles(currentClient.playerInstance.Position.getValue(), ref otherPlayerX, ref otherPlayerY, ref otherPlayerZ); Maths mathUtils = new Maths(); bool playerIsInCircle = mathUtils.IsInCircle((float)currentPlayerX, (float)currentPlayerZ, (float)otherPlayerX, (float)otherPlayerZ, 5000); if (clientView.viewCreated == false && currentClient.playerData.getDistrictId() == otherClient.playerData.getDistrictId() && otherClient.playerData.getOnWorld() && currentClient.playerData.getOnWorld() && playerIsInCircle) { // Spawn player ServerPackets pak = new ServerPackets(); pak.sendSystemChatMessage(currentClient, "Player " + StringUtils.charBytesToString_NZ(otherClient.playerInstance.CharacterName.getValue()) + " with new View ID " + clientView.ViewID + " jacked in", "BROADCAST"); pak.sendPlayerSpawn(currentClient, otherClient, clientView.ViewID); clientView.spawnId = currentClient.playerData.spawnViewUpdateCounter; clientView.viewCreated = true; } if (clientView.viewCreated && !playerIsInCircle) { // ToDo: delete mob ServerPackets packets = new ServerPackets(); packets.sendSystemChatMessage(currentClient, "Player " + StringUtils.charBytesToString_NZ(otherClient.playerInstance.CharacterName.getValue()) + " with View ID " + clientView.ViewID + " jacked out!", "MODAL"); packets.sendDeleteViewPacket(currentClient, clientView.ViewID); currentClient.viewMan.removeViewByViewId(clientView.ViewID); } } } } } }
public void processChat(ref byte[] packetData) { chatCommands = new ChatCommandsHelper(); int offset = 0; //10 00 08 00 00 00 00 06 00 3f 53 61 76 65 00 int length = (int)packetData[7]; offset = 9; //Move to length +2 if (length > 0) { byte[] textB = new byte[length - 1]; ArrayUtils.copy(packetData, offset, textB, 0, length - 1); string text = StringUtils.charBytesToString(textB); if (text[0] == '?') { //Maybe a parameter chatCommands.parseCommand(text); // Parse for commands } else { // Not a Param - lets distribute the Message throw our Area ServerPackets pak = new ServerPackets(); pak.sendChatMessage(Store.currentClient, text, Store.currentClient.playerData.getCharID(), StringUtils.charBytesToString_NZ(Store.currentClient.playerInstance.CharacterName.getValue()), "AREA"); // ToDo: Send the ChatMessage to the Scope of Players } } }