public static void Decompress(ref GenericReader gr) { int uncompressedLength = gr.ReadInt32(); byte[] output = new byte[gr.ReadInt32()]; byte[] temp = gr.ReadBytes((int)gr.Remaining); gr.Close(); Stream s = new InflaterInputStream(new MemoryStream(temp)); int offset = 0; while (true) { int size = s.Read(output, offset, uncompressedLength); if (size == uncompressedLength) break; offset += size; uncompressedLength -= size; } gr = new GenericReader(new MemoryStream(output)); //gr.BaseStream.Position = 0; }
public static GenericReader Decompress(GenericReader gr) { int uncompressedLength = gr.ReadInt32(); byte[] input = gr.ReadBytes((int)gr.Remaining); byte[] output = new byte[uncompressedLength]; gr.Close(); InflaterInputStream istream = new InflaterInputStream(new MemoryStream(input)); int offset = 0; while (true) { int size = istream.Read(output, offset, uncompressedLength); if (size == uncompressedLength) break; offset += size; uncompressedLength -= size; } return new GenericReader(new MemoryStream(output)); }
/// <summary> /// Packet header parser. /// </summary> /// <param name="gr">Main stream reader.</param> /// <param name="sw">Data stream writer.</param> /// <param name="swe">Error logger writer.</param> /// <param name="data">Data logger writer.</param> /// <param name="hex">HEX logger writer.</param> /// <returns>Successful</returns> private static bool ParseHeader(GenericReader gr, StreamWriter sw, StreamWriter swe, StreamWriter data, StreamWriter hex) { StringBuilder sb = new StringBuilder(); int datasize = gr.ReadInt32(); //sb.AppendLine("Packet offset " + (gr.BaseStream.Position - 4).ToString("X2")); //sb.AppendLine("Packet number: " + packet); //sb.AppendLine("Data size " + datasize); byte[] temp = gr.ReadBytes(datasize); MemoryStream ms = new MemoryStream(temp); GenericReader gr2 = new GenericReader(ms); uint id = 0; uint sess_id = 0; string time = ""; byte direction = 0; // 0-CMSG, 1-SMSG OpCodes opcode = OpCodes.MSG_NULL_ACTION; id = gr2.ReadUInt32(); sess_id = gr2.ReadUInt32(); time = gr2.ReadStringNull(); direction = gr2.ReadByte(); opcode = (OpCodes)gr2.ReadUInt16(); long cur_pos = gr2.BaseStream.Position; HexLike(gr2, hex, id, sess_id, time, direction, opcode); gr2.BaseStream.Position = cur_pos; switch (opcode) { /*case OpCodes.SMSG_MONSTER_MOVE: OpcodeParser.ParseMonsterMoveOpcode(gr, gr2, sb, swe, direction); break;*/ /*case OpCodes.SMSG_INITIAL_SPELLS: OpcodeParser.ParseInitialSpellsOpcode(gr, gr2, sb, swe, direction); break; case OpCodes.SMSG_AUCTION_LIST_RESULT: OpcodeParser.ParseAuctionListResultOpcode(gr, gr2, sb, swe, direction); break;*/ /*case OpCodes.SMSG_PARTY_MEMBER_STATS: case OpCodes.SMSG_PARTY_MEMBER_STATS_FULL: OpcodeParser.ParsePartyMemberStatsOpcode(gr, gr2, sb, swe, direction); break;*/ case OpCodes.SMSG_UPDATE_OBJECT: case OpCodes.SMSG_COMPRESSED_UPDATE_OBJECT: if (opcode == OpCodes.SMSG_COMPRESSED_UPDATE_OBJECT) { gr2 = A9.Decompress(gr2); gr2.BaseStream.Position = 0; hex.WriteLine("Decompressed SMSG_COMPRESSED_UPDATE_OBJECT:"); HexLike(gr2, hex, id, sess_id, time, direction, OpCodes.SMSG_UPDATE_OBJECT); gr2.BaseStream.Position = 0; } A9.ParseUpdatePacket(gr, gr2, sb, swe); break; /*case OpCodes.SMSG_SPELLNONMELEEDAMAGELOG: OpcodeParser.ParseSpellNonMeleeDamageLogOpcode(gr, gr2, sb, swe, direction); break; case OpCodes.SMSG_SPELLLOGEXECUTE: OpcodeParser.ParseSpellLogExecuteOpcode(gr, gr2, sb, swe, direction); break;*/ /*case OpCodes.SMSG_LOGIN_SETTIMESPEED: OpcodeParser.ParseLoginSetTimeSpeedOpcode(gr, gr2, sb, swe, direction); break; case OpCodes.SMSG_TRAINER_LIST: OpcodeParser.ParseTrainerListOpcode(gr, gr2, sb, swe, direction); break; case OpCodes.SMSG_ATTACKERSTATEUPDATE: OpcodeParser.ParseAttackerStateUpdateOpcode(gr, gr2, sb, swe, direction); break; case OpCodes.MSG_CORPSE_QUERY: OpcodeParser.ParseCorpseQueryOpcode(gr, gr2, sb, swe, direction); break; case OpCodes.SMSG_LOGIN_VERIFY_WORLD: OpcodeParser.ParseLoginVerifyWorldOpcode(gr, gr2, sb, swe, direction); break; default: // unhandled opcode return false;*/ } if (sb.ToString().Length != 0) sw.WriteLine(sb.ToString()); ms.Close(); gr2.Close(); return true; }
private static bool ParseValuesUpdateBlock(GenericReader gr, StringBuilder sb, StreamWriter swe, StreamWriter data, ObjectTypes objectTypeId, UpdateTypes updatetype, WoWObject obj) { sb.AppendLine("=== values_update_block_start ==="); byte blocks_count = gr.ReadByte(); // count of update blocks (4 bytes for each update block) sb.AppendLine("Bit mask blocks count: " + blocks_count); int[] updatemask = new int[blocks_count]; // create array of update blocks for (int j = 0; j < blocks_count; j++) updatemask[j] = gr.ReadInt32(); // populate array of update blocks with data Mask = new BitArray(updatemask); int reallength = Mask.Count; // bitmask size (bits) int bitmask_max_size = 0; uint values_end = 0; switch (objectTypeId) { case ObjectTypes.TYPEID_ITEM: bitmask_max_size = 64; values_end = UpdateFieldsLoader.ITEM_END; break; case ObjectTypes.TYPEID_CONTAINER: bitmask_max_size = 160; values_end = UpdateFieldsLoader.CONTAINER_END; break; case ObjectTypes.TYPEID_UNIT: bitmask_max_size = 256; values_end = UpdateFieldsLoader.UNIT_END; break; case ObjectTypes.TYPEID_PLAYER: bitmask_max_size = 1536; // 2.3.2 - 1472 values_end = UpdateFieldsLoader.PLAYER_END; break; case ObjectTypes.TYPEID_GAMEOBJECT: bitmask_max_size = 32; values_end = UpdateFieldsLoader.GO_END; break; case ObjectTypes.TYPEID_DYNAMICOBJECT: bitmask_max_size = 32; values_end = UpdateFieldsLoader.DO_END; break; case ObjectTypes.TYPEID_CORPSE: bitmask_max_size = 64; values_end = UpdateFieldsLoader.CORPSE_END; break; } if (reallength > bitmask_max_size) { long pos = gr.BaseStream.Position; swe.WriteLine("error position {0}", pos.ToString("X2")); swe.WriteLine("error while parsing {0} values update block, count {1}", objectTypeId, reallength); return false; } for (int index = 0; index < reallength; index++) { if (index > values_end) break; if (Mask[index]) { UpdateField uf = new UpdateField(); switch (objectTypeId) { case ObjectTypes.TYPEID_ITEM: case ObjectTypes.TYPEID_CONTAINER: uf = UpdateFieldsLoader.item_uf[index]; break; case ObjectTypes.TYPEID_UNIT: case ObjectTypes.TYPEID_PLAYER: uf = UpdateFieldsLoader.unit_uf[index]; break; case ObjectTypes.TYPEID_GAMEOBJECT: uf = UpdateFieldsLoader.go_uf[index]; break; case ObjectTypes.TYPEID_DYNAMICOBJECT: uf = UpdateFieldsLoader.do_uf[index]; break; case ObjectTypes.TYPEID_CORPSE: uf = UpdateFieldsLoader.corpse_uf[index]; break; } ReadAndDumpField(uf, sb, gr, updatetype, data, obj); } } if ((objectTypeId == ObjectTypes.TYPEID_GAMEOBJECT || objectTypeId == ObjectTypes.TYPEID_UNIT) && (updatetype == UpdateTypes.UPDATETYPE_CREATE_OBJECT || updatetype == UpdateTypes.UPDATETYPE_CREATE_OBJECT2) && obj.IsNew) obj.Save(); sb.AppendLine("=== values_update_block_end ==="); return true; }
/// <summary> /// Monster move opcode parser method. /// </summary> /// <param name="gr">Main stream reader.</param> /// <param name="gr2">Packet stream reader.</param> /// <param name="sb">Logger string builder.</param> /// <param name="swe">Error logger writer.</param> /// <returns>Successful</returns> public static bool ParseMonsterMoveOpcode(GenericReader gr, GenericReader gr2, StringBuilder sb, StreamWriter swe, byte direction) { sb.AppendLine("Packet offset " + gr.BaseStream.Position.ToString("X2")); sb.AppendLine("Opcode SMSG_MONSTER_MOVE (0x00DD)"); ulong guid = gr2.ReadPackedGuid(); sb.AppendLine("GUID " + guid.ToString("X16")); Coords3 coords = gr2.ReadCoords3(); sb.AppendLine("Start point " + coords.GetCoords()); uint time = gr2.ReadUInt32(); sb.AppendLine("Time " + time); byte unk = gr2.ReadByte(); sb.AppendLine("unk_byte " + unk); switch (unk) { case 0: // обычный пакет break; case 1: // стоп, конец пакета... sb.AppendLine("stop"); return true; case 2: Coords3 point = gr2.ReadCoords3(); sb.AppendLine("unk point " + point.GetCoords()); break; case 3: // чей-то гуид, скорее всего таргета... ulong target_guid = gr2.ReadUInt64(); sb.AppendLine("GUID unknown " + target_guid.ToString("X16")); break; case 4: // похоже на ориентацию... float orientation = gr2.ReadSingle(); sb.AppendLine("Orientation " + orientation.ToString().Replace(",", ".")); break; default: swe.WriteLine("Error in position " + gr.BaseStream.Position.ToString("X2")); swe.WriteLine("unknown unk " + unk); break; } Flags flags = (Flags)gr2.ReadUInt32(); sb.AppendLine("Flags " + flags); uint movetime = gr2.ReadUInt32(); sb.AppendLine("MoveTime " + movetime); uint points = gr2.ReadUInt32(); sb.AppendLine("Points " + points); List<Node> nodes = new List<Node>((int)points); if ((flags & Flags.flag10) != 0) // 0x200 { sb.AppendLine("Taxi"); for (uint i = 0; i < points; i++) { Node node = new Node(); node.x = gr2.ReadSingle(); node.y = gr2.ReadSingle(); node.z = gr2.ReadSingle(); nodes.Add(node); //Coords3 path = gr2.ReadCoords3(); //sb.AppendLine("Path point" + i + ": " + path.GetCoords()); } } else { if ((flags & Flags.flag09) == 0 && (flags & Flags.flag10) == 0 && flags != 0) { swe.WriteLine("Unknown flags " + flags); } if ((flags & Flags.flag09) != 0) sb.AppendLine("Running"); Coords3 end = gr2.ReadCoords3(); sb.AppendLine("End point " + end.GetCoords()); for (uint i = 0; i < (points - 1); i++) { int mask = gr2.ReadInt32(); sb.AppendLine("shift mask" + i + " " + mask.ToString("X8")); int temp1, temp2, temp3; temp1 = (mask & 0x07FF) << 0x15; temp2 = ((mask >> 0x0B) & 0x07FF) << 0x15; temp3 = (mask >> 0x16) << 0x16; temp1 >>= 0x15; temp2 >>= 0x15; temp3 >>= 0x16; float x = temp1 * 0.25f; float y = temp2 * 0.25f; float z = temp3 * 0.25f; sb.AppendLine("shift is " + x + " " + y + " " + z + "."); } } if ((flags & Flags.flag10) != 0) { StreamWriter sw = new StreamWriter("taxiinfo.txt", true); sw.WriteLine("GUID: 0x" + guid.ToString("X16")); sw.WriteLine(string.Format("Position: {0} {1} {2}", coords.X, coords.Y, coords.Z)); sw.WriteLine("Time: " + time); sw.WriteLine("Movetime: " + movetime); sw.WriteLine("Nodes: " + points); for (int i = 0; i < points; i++) sw.WriteLine(string.Format("Node {0}: {1} {2} {3}", i, nodes[i].x, nodes[i].y, nodes[i].z)); uint mangos_time = 0; float len = 0, xd, yd, zd; /*xd = nodes[0].x - coords.X; yd = nodes[0].y - coords.Y; zd = nodes[0].z - coords.Z; len += (float)Math.Sqrt((xd * xd + yd * yd + zd * zd));*/ for (int i = 1; i < points; i++) { xd = nodes[i].x - nodes[i - 1].x; yd = nodes[i].y - nodes[i - 1].y; zd = nodes[i].z - nodes[i - 1].z; len += (float)Math.Sqrt((xd * xd + yd * yd + zd * zd)); } mangos_time = (uint)(len * 33.360f); // 33.373f / 33.336 sw.WriteLine("Mangostime 3D: " + mangos_time); mangos_time = 0; len = 0; for (int i = 1; i < points; i++) { xd = nodes[i].x - nodes[i - 1].x; yd = nodes[i].y - nodes[i - 1].y; len += (float)Math.Sqrt((xd * xd + yd * yd)); } mangos_time = (uint)(len * 33.360f); sw.WriteLine("Mangostime 2D: " + mangos_time); sw.WriteLine(); sw.Flush(); sw.Close(); } return true; }