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)); }
static void Main(string[] args) { // Ищем файл wow.exe сначала в текущей папке, // затем лезем в реестр и смотрим папку там. // TODO: взять путь к wow.exe из аргументов ком. строки var wowPath = "WoW.exe"; if(!File.Exists(wowPath)) { wowPath = (string)Registry.GetValue(@"HKEY_CURRENT_USER\Software\Blizzard Entertainment\World of Warcraft", "InstallPath", null); wowPath = Path.Combine(wowPath ?? string.Empty, "WoW.exe"); } var wowExe = new FileInfo(wowPath); if(!wowExe.Exists) { Console.WriteLine("File {0} not found!", wowExe.Name); } else { Console.WriteLine("File {0} found in {1}", wowExe.Name, wowExe.DirectoryName); Console.WriteLine("Extracting..."); using (var stream = wowExe.Open(FileMode.Open, FileAccess.Read)) { gr = new GenericReader(stream, Encoding.ASCII); tr = new StreamReader(stream, Encoding.ASCII); streamString = tr.ReadToEnd(); ExtractEnum("ChatMsg", "CHAT_MSG_GUILD_ACHIEVEMENT", "CHAT_MSG_ADDON", s => ToCamelCase(s.Substring("CHAT_MSG_".Length)), -1); ExtractEnum("ResponseCodes", "CHAR_NAME_DECLENSION_DOESNT_MATCH_BASE_NAME", "RESPONSE_SUCCESS"); ExtractEnum("ChatNotify", "VOICE_OFF", "YOU_CHANGED", a => string.Format("CHAT_{0}_NOTICE", a), 0); ExtractEnum("OpCodes", "NUM_MSG_TYPES", "MSG_NULL_ACTION"); ExtractEnum("SpellFailedReason", "SPELL_FAILED_UNKNOWN", "SPELL_FAILED_SUCCESS"); ExtractEnum("EnchantConditions", "ENCHANT_CONDITION_REQUIRES", "ENCHANT_CONDITION_EQUAL_VALUE"); ExtractEnum("ItemModType", "ITEM_MOD_SPELL_POWER", "ITEM_MOD_MANA"); tr.Close(); gr.Close(); } Console.WriteLine("Done"); } Console.Write("Press any key to exit..."); Console.ReadKey(); }
private static bool ParseFile(FileInfo f) { DateTime filestarttime = DateTime.Now; Console.Write("Parsing {0}...", f.Name); SQLiteConnection connection = new SQLiteConnection("Data Source=" + f.FullName); SQLiteCommand command = new SQLiteCommand(connection); connection.Open(); command.CommandText = "SELECT id, sess_id, timestamp, direction, opcode, data FROM packets ORDER BY id;"; command.Prepare(); SQLiteDataReader reader = command.ExecuteReader(); MemoryStream ms = new MemoryStream(); while (reader.Read()) { uint id = (uint)reader.GetInt32(0); uint sess_id = (uint)reader.GetInt32(1); string timestamp = reader.GetString(2); byte direction = reader.GetByte(3); ushort opcode = (ushort)reader.GetInt32(4); if (opcode > 1054) { Console.WriteLine(opcode); throw new Exception("Test"); } byte[] data_ = (byte[])reader.GetValue(5); uint size = sizeof(uint) + sizeof(uint) + (uint)timestamp.Length + 1 + sizeof(byte) + sizeof(ushort) + (uint)data_.Length; byte[] id_arr = BitConverter.GetBytes(id); byte[] sessid_arr = BitConverter.GetBytes(sess_id); byte[] time_arr = Encoding.ASCII.GetBytes(timestamp); byte[] op = BitConverter.GetBytes(opcode); byte[] sz = BitConverter.GetBytes(size); ms.Write(sz, 0, sz.Length); ms.Write(id_arr, 0, id_arr.Length); ms.Write(sessid_arr, 0, sessid_arr.Length); ms.Write(time_arr, 0, time_arr.Length); ms.WriteByte(0); ms.WriteByte(direction); ms.Write(op, 0, op.Length); ms.Write(data_, 0, data_.Length); } reader.Close(); connection.Close(); GenericReader gr = new GenericReader(ms, Encoding.ASCII); gr.BaseStream.Position = 0; string error_log = f.FullName + ".errors.txt"; StreamWriter swe = new StreamWriter(error_log); string database_log = f.FullName + ".data.txt"; StreamWriter data = new StreamWriter(database_log); string hex_log = f.FullName + ".hex.log"; StreamWriter hex = new StreamWriter(hex_log); string ofn = f.FullName + ".data_out.txt"; StreamWriter sw = new StreamWriter(ofn); sw.AutoFlush = true; swe.AutoFlush = true; data.AutoFlush = true; hex.AutoFlush = true; while (gr.PeekChar() >= 0) { //try //{ if (ParseHeader(gr, sw, swe, data, hex)) packet++; //} //catch (Exception exc) //{ // MessageBox.Show(exc.ToString()); // swe.WriteLine("error in pos " + gr.BaseStream.Position.ToString("X16")); //} } // clear objects list... m_objects.Clear(); sw.Close(); swe.Close(); data.Close(); hex.Close(); gr.Close(); TimeSpan fileworktime = DateTime.Now - filestarttime; Console.WriteLine(" Parsed in {0}", fileworktime); return true; }
/// <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 void ReadAndDumpField(UpdateField uf, StringBuilder sb, GenericReader gr, UpdateTypes updatetype, StreamWriter data, WoWObject obj) { MemoryStream ms = new MemoryStream(gr.ReadBytes(4)); GenericReader gr2 = new GenericReader(ms); if (updatetype == UpdateTypes.UPDATETYPE_CREATE_OBJECT || updatetype == UpdateTypes.UPDATETYPE_CREATE_OBJECT2) { obj.SetUInt32Value(uf.Identifier, gr2.ReadUInt32()); gr2.BaseStream.Position -= 4; } switch (uf.Type) { // TODO: add data writing /*case 3: string val1 = gr.ReadSingle().ToString().Replace(",", "."); if (updatetype == UpdateTypes.UPDATETYPE_CREATE_OBJECT || updatetype == UpdateTypes.UPDATETYPE_CREATE_OBJECT2) data.WriteLine(uf.Name + " (" + uf.Identifier + "): " + val1); sb.AppendLine(uf.Name + " (" + index + "): " + val1); break; default: uint val2 = gr.ReadUInt32(); if (updatetype == UpdateTypes.UPDATETYPE_CREATE_OBJECT || updatetype == UpdateTypes.UPDATETYPE_CREATE_OBJECT2) data.WriteLine(uf.Name + " (" + uf.Identifier + "): " + val2); sb.AppendLine(uf.Name + " (" + uf.Identifier + "): " + val2); break;*/ case 1: // uint32 sb.AppendLine(uf.Name + " (" + uf.Identifier + "): " + gr2.ReadUInt32().ToString("X8")); break; case 2: // uint16+uint16 ushort value1 = gr2.ReadUInt16(); ushort value2 = gr2.ReadUInt16(); sb.AppendLine(uf.Name + " (" + uf.Identifier + "): " + "first " + value1.ToString("X4") + ", second " + value2.ToString("X4")); if (uf.Name.StartsWith("PLAYER_SKILL_INFO_1_")) { int num = uf.Identifier - 858; if ((num % 3) == 0) { ushort skill = value1; ushort flag = value2; string str = String.Format("skill {0}, flag {1}", skill, (ProfessionFlags)flag); sb.AppendLine(str); } else if (((num - 1) % 3) == 0) { ushort minskill = value1; ushort maxskill = value2; string str = String.Format("minskill {0}, maxskill {1}", minskill, maxskill); sb.AppendLine(str); } else { ushort minbonus = value1; ushort maxbonus = value2; string str = String.Format("minbonus {0}, maxbonus {1}", minbonus, maxbonus); sb.AppendLine(str); } } break; case 3: // float sb.AppendLine(uf.Name + " (" + uf.Identifier + "): " + gr2.ReadSingle()); //sb.AppendLine(uf.Name + " (" + uf.Identifier + "): " + gr.ReadSingle().ToString().Replace(",", ".")); break; case 4: // uint64 (can be only low part) sb.AppendLine(uf.Name + " (" + uf.Identifier + "): " + gr2.ReadUInt32().ToString("X8")); break; case 5: // bytes uint value = gr2.ReadUInt32(); sb.AppendLine(uf.Name + " (" + uf.Identifier + "): " + value.ToString("X8")); if (uf.Identifier == 36) // UNIT_FIELD_BYTES_0 { byte[] bytes = BitConverter.GetBytes(value); Races race = (Races)bytes[0]; Class class_ = (Class)bytes[1]; Gender gender = (Gender)bytes[2]; Powers powertype = (Powers)bytes[3]; string str = String.Format("Race: {0}, class: {1}, gender: {2}, powertype: {3}", race, class_, gender, powertype); sb.AppendLine(str); } break; default: sb.AppendLine(uf.Name + " (" + uf.Identifier + "): " + "unknown type " + gr2.ReadUInt32().ToString("X8")); break; } gr2.Close(); }