public void Parse(byte[] data, int type, bool isUsed = true) { // Guard against packet size = 0. if (data.Length == 0 && type != 0xBF && type != 0xBE) { Console.WriteLine("Packet of size 0?"); return; } // List of items found on the map. List <MapItem> list = new List <MapItem>(); // New Parse = reset cursor position. bPosition = 0; // Current Position on the map; cursor position for the packet data. currOffset.Set(0, 0, 0); // Current Offset on the grid; position relative to the origin for the cursor. DrawPosition.Set(0, 0, 0); // Reset isInitialized, isInitialized = false; if (type == 0x64) { // Parse target = complete map with position header. // TEST ONLY //isInitialized = InitializeMap(); // Parse the MapPosition and set the CharPosition. ParseMapPosition(data, mapStartPosition); charPosition.Set(mapStartPosition.X, mapStartPosition.Y, mapStartPosition.Z); // Set the floor to set appropriate variables. SetFloor(mapStartPosition.Z); // Shift the position in the direction we just moved. charPosition.Shift(0, 0, 0); // Moved none // Set the boundaries the cursor should have (w x h x d). CursorBoundaries.Set(18, 14, 15); // Set the offset the cursor should have. CursorOffset.X = CursorOffset.Y = 0; //CursorOffset.Set(0, 0, 0); } else if (type == 0x65) { // Moved north. // North movements don't initialize map. //InitializeMap(); // Shift the position in the direction we just moved. charPosition.Shift(0, -1, 0); //mapPosition.Shift(0, -1, 0); // Set the boundaries the cursor should have (w x h x d). CursorBoundaries.Set(18, 1, 15); // Set the offset the cursor should have. // These were the expected values. CursorOffset.X = CursorOffset.Y = 0; CursorOffset.Set(0, 0, (charPosition.Z > 7 ? -2 : 0)); // I don't understand why we need these values though. //CursorOffset.Set(-1, -1, 0); } else if (type == 0x66) { // Moved east. // East movements don't initialize map. //InitializeMap(); // Shift the position in the direction we just moved. charPosition.Shift(1, 0, 0); //mapPosition.Shift(1, 0, 0); // Set the offset the cursor should have. // These were the expected values. CursorOffset.X = 17; CursorOffset.Y = 0; CursorOffset.Set(17, 0, (charPosition.Z > 7 ? -2 : 0)); // Set the boundaries the cursor should have (w x h x d). CursorBoundaries.Set(1, 14, 15); } else if (type == 0x67) { // Moved south. // South movements don't initialize map. //InitializeMap(); // Shift the position in the direction we just moved. charPosition.Shift(0, 1, 0); //mapPosition.Shift(0, 1, 0); // Set the offset the cursor should have. CursorOffset.X = 0; CursorOffset.Y = 13; CursorOffset.Set(0, 13, (charPosition.Z > 7 ? -2 : 0)); // Set the boundaries the cursor should have (w x h x d). CursorBoundaries.Set(18, 1, 15); } else if (type == 0x68) { // Moved west. // West movements don't initialize map. //isInitialized = InitializeMap(); // Shift the position in the direction we just moved. charPosition.Shift(-1, 0, 0); //mapPosition.Shift(-1, 0, 0); // Set the offset the cursor should have. CursorOffset.X = CursorOffset.Y = 0; CursorOffset.Set(0, 0, (charPosition.Z > 7 ? -2 : 0)); // Set the boundaries the cursor should have (w x h x d). CursorBoundaries.Set(1, 14, 15); } else if (type == 0xBF) { // Moved down a floor. SetFloor(charPosition.Z + 1); charPosition.Shift(-1, -1, 0); if (mapPosition.Z <= 7) { // ??? CursorOffset.Z = 0; } else { // ??? CursorOffset.Set(0, 0, 0); } } else if (type == 0xBE) { // Moved up a floor. SetFloor(charPosition.Z - 1); charPosition.Shift(1, 1, 0); if (mapPosition.Z <= 7) { // ??? CursorOffset.Z = -2; } else { // ??? CursorOffset.Z = -2; } } if (!isUsed) { return; } // Create a tile, to avoid potential errors & compiler issues. GetDrawPosition(DrawPosition); MapTile tile = new MapTile(); // Parse the data while (bPosition < data.Length) { // Ensure CurrPosition has the current position. GetDrawPosition(DrawPosition); // Perform checks on the following data. if (lookAhead(data, CreaturePattern3)) { // We found a creature. // Don't care about creatures, just consume & dispose. MapCreature creature = ParseCreature(data); // Record the creature. if (!Creatures.ContainsKey(creature.ID)) { Creatures[creature.ID] = creature; } tile.Creatures.Add(creature); // Experimental... if (lookAhead(data, EndTile)) { ConsumeBytes(EndTile.Length); } } else if (lookAhead(data, CreaturePattern)) { // We found a creature, fixed width 8b. // Don't care about creatures, just consume, record & dispose. // Debug only. //ByteRecordStream.RecordByteStream(ConsumeBytes(8, data), "frag-99.txt"); ConsumeBytes(8, data); } else if (lookAhead(data, CreaturePattern2)) { // Creature with info, length depends on contents. // Don't care about creatures, just consume & dispose. MapCreature creature = ParseCreature98(data); // Record the creature. if (Creatures.ContainsKey(creature.ID)) { tile.Creatures.Add(creature); } else { // This happens because(?) the first block, 0x07, contains a list of creatures. //Console.WriteLine("Found unknown creature. Bug?"); } // Experimental... if (lookAhead(data, EndTile)) { ConsumeBytes(EndTile.Length); } } else if (lookAhead(data, PatternTile)) { // We are dealing with a new tile. Initialize or move the cursor. if (!isInitialized) { InitializeMap(); } else { MoveCursor(1); } // Ensure we have the current position. GetDrawPosition(DrawPosition); // Consume the bytes of the pattern. ConsumeBytes(PatternTile.Length); // New tile = new Tile()! tile = new MapTile(); Map.AddTile(DrawPosition, tile); } else if (lookAhead(data, SkipAhead, 1)) { // If the map is not initialized, initialize it. InitializeMap(); // We are dealing with a skip 0x__ 0xFF. // Move the cursor based on the skip type. MoveCursor(data[bPosition]); // Consume the pattern. ConsumeBytes(2); } else if (lookAhead(data, EndTile)) { } else { // We found an item. GetDrawPosition(DrawPosition); ParseResult result = ParseItem(data); if (result.Item != null) { if (DrawPosition.Z < 0 || 15 < DrawPosition.Z) { Console.WriteLine("Z out of bounds>"); } tile.Items.Add(result.Item); // Experimental... if (lookAhead(data, EndTile)) { ConsumeBytes(EndTile.Length); } } else { //Console.WriteLine("Found no item..."); } } } return; }
public MapCreature ParseCreature(byte[] data) { // 2b - Creature header. int header = 0; for (int i = 0; i < 2; i++, bPosition++) { header += data[bPosition] << (i * 8); } // 4b - Unknown. int ukheader = 0; for (int i = 0; i < 4; i++, bPosition++) { ukheader += data[bPosition] << (i * 8); } // 4b - Creature ID. int id = 0; for (int i = 0; i < 4; i++, bPosition++) { id += data[bPosition] << (i * 8); } // 1b - unknown. int uk1 = 0; for (int i = 0; i < 1; i++, bPosition++) { uk1 += data[bPosition] << (i * 8); } // 1b - character name length. int charNameLength = 0; for (int i = 0; i < 2; i++, bPosition++) { charNameLength += data[bPosition] << (i * 8); } // [charNameLength]b - char name. string charName = ""; for (int i = 0; i < charNameLength; i++, bPosition++) { charName += char.ConvertFromUtf32(data[bPosition]); } // 1b - health percentage. int healthPercent = 0; for (int i = 0; i < 1; i++, bPosition++) { healthPercent += data[bPosition] << (i * 8); } // 1b - direction. int direction = 0; for (int i = 0; i < 1; i++, bPosition++) { direction += data[bPosition] << (i * 8); } // 2b - outfit. int outfit = 0; for (int i = 0; i < 2; i++, bPosition++) { outfit += data[bPosition] << (i * 8); } // 1b - color head. int colorHead = 0; for (int i = 0; i < 1; i++, bPosition++) { colorHead += data[bPosition] << (i * 8); } // 1b - color body. int colorBody = 0; for (int i = 0; i < 1; i++, bPosition++) { colorBody += data[bPosition] << (i * 8); } // 1b - color legs. int colorLegs = 0; for (int i = 0; i < 1; i++, bPosition++) { colorLegs += data[bPosition] << (i * 8); } // 1b - color feet. int colorFeet = 0; for (int i = 0; i < 1; i++, bPosition++) { colorFeet += data[bPosition] << (i * 8); } // If there's no oufit then addons and mount are not included. int addons = 0; int mount = 0; if (outfit != 0) { // 1b - addons. for (int i = 0; i < 1; i++, bPosition++) { addons += data[bPosition] << (i * 8); } // 1b - mount. for (int i = 0; i < 2; i++, bPosition++) { mount += data[bPosition] << (i * 8); } } // 1b - light radius. int lightRadius = 0; for (int i = 0; i < 1; i++, bPosition++) { lightRadius += data[bPosition] << (i * 8); } // 1b - light color. int lightColor = 0; for (int i = 0; i < 1; i++, bPosition++) { lightColor += data[bPosition] << (i * 8); } // 2b - speed. int speed = 0; for (int i = 0; i < 2; i++, bPosition++) { speed += data[bPosition] << (i * 8); } // 1b - skull. int skull = 0; for (int i = 0; i < 1; i++, bPosition++) { skull += data[bPosition] << (i * 8); } // 1b - party shield. int partyShield = 0; for (int i = 0; i < 1; i++, bPosition++) { partyShield += data[bPosition] << (i * 8); } // 1b - guild shield. int guildShield = 0; int ukend1 = 0; // 1b - unknown. int ukend2 = 0; for (int i = 0; i < 1; i++, bPosition++) { ukend2 += data[bPosition] << (i * 8); } // 1b - unknown. int ukend3 = 0; for (int i = 0; i < 1; i++, bPosition++) { ukend3 += data[bPosition] << (i * 8); } // 10.01+, 10.0? int ukend4 = 0; int ukend5 = 0; int ukend6 = 0; int ukend7 = 0; if (10.01F <= DatContextInput.Version) { // Possibly PvP frames. // 1b - unknown. for (int i = 0; i < 1; i++, bPosition++) { ukend4 += data[bPosition] << (i * 8); } // 1b - unknown. for (int i = 0; i < 1; i++, bPosition++) { ukend5 += data[bPosition] << (i * 8); } // 1b - unknown. for (int i = 0; i < 1; i++, bPosition++) { ukend6 += data[bPosition] << (i * 8); } // 1b - unknown. for (int i = 0; i < 1; i++, bPosition++) { ukend7 += data[bPosition] << (i * 8); } //bPosition += 4; } // Experimental. int ukend8 = 0; if (10.39F <= DatContextInput.Version) { // 1b - unknown. for (int i = 0; i < 1; i++, bPosition++) { ukend8 += data[bPosition] << (i * 8); } //bPosition += 1; } MapCreature creature = new MapCreature( header: header, ukheader: ukheader, id: id, type: uk1, charNameLength: charNameLength, charName: charName, healthPercent: healthPercent, direction: direction, outfit: outfit, colorHead: colorHead, colorBody: colorBody, colorLegs: colorLegs, colorFeet: colorFeet, addons: addons, mount: mount, lightRadius: lightRadius, lightColor: lightColor, speed: speed, skull: skull, partyShield: partyShield, guildShield: guildShield, ukend1: ukend1, ukend2: ukend2, ukend3: ukend3, ukend4: ukend4, ukend5: ukend5, ukend6: ukend6, ukend7: ukend7, ukend8: ukend8 ); return(creature); }