public static bool ParseAttackerStateUpdateOpcode(GenericReader gr, GenericReader gr2, StringBuilder sb, StreamWriter swe, byte direction) { sb.AppendLine("Packet offset " + gr.BaseStream.Position.ToString("X2")); sb.AppendLine("Opcode SMSG_ATTACKERSTATEUPDATE (0x01B1)"); StreamWriter sw = new StreamWriter("attacker_state.log", true, Encoding.ASCII); HitInfo hi = (HitInfo)gr2.ReadUInt32(); ulong attacker = gr2.ReadPackedGuid(); ulong target = gr2.ReadPackedGuid(); uint damage = gr2.ReadUInt32(); sw.WriteLine("HitInfo {0}", hi); sw.WriteLine("attacker {0}", attacker.ToString("X16")); sw.WriteLine("target {0}", target.ToString("X16")); sw.WriteLine("damage {0}", damage); byte count = gr2.ReadByte(); sw.WriteLine("count {0}", count); for (byte i = 0; i < count; i++) { ITEM_DAMAGE_TYPE damagetype = (ITEM_DAMAGE_TYPE)gr2.ReadUInt32(); float damage2 = gr2.ReadSingle(); uint damage3 = gr2.ReadUInt32(); uint adsorb = gr2.ReadUInt32(); uint resist = gr2.ReadUInt32(); sw.WriteLine("damagetype {0}", damagetype); sw.WriteLine("damage2 {0}", damage2); sw.WriteLine("damage3 {0}", damage3); sw.WriteLine("adsorb {0}", adsorb); sw.WriteLine("resist {0}", resist); } VictimState targetstate = (VictimState)gr2.ReadUInt32(); uint unk1 = gr2.ReadUInt32(); uint unk2 = gr2.ReadUInt32(); uint blocked = gr2.ReadUInt32(); sw.WriteLine("targetstate {0}", targetstate); sw.WriteLine("unk1 {0}", unk1); sw.WriteLine("unk2 {0}", unk2); sw.WriteLine("blocked {0}", blocked); sw.WriteLine(); sw.Flush(); sw.Close(); if (gr2.BaseStream.Position == gr2.BaseStream.Length) sb.AppendLine("parsed: ok..."); else sb.AppendLine("parsed: error..."); return true; }
private static bool ParseBlock(GenericReader gr, StringBuilder sb, StreamWriter swe, StreamWriter data) { ulong guid = 0; UpdateTypes updatetype = (UpdateTypes)gr.ReadByte(); sb.AppendLine("Updatetype: " + updatetype); // check if updatetype is valid if (updatetype < UpdateTypes.UPDATETYPE_VALUES || updatetype > UpdateTypes.UPDATETYPE_NEAR_OBJECTS) { long pos = gr.BaseStream.Position; swe.WriteLine("wrong updatetype at position {0}", pos.ToString("X16")); // we there only if we read packet wrong way swe.WriteLine("Updatetype {0} is not supported", updatetype); return false; } switch (updatetype) { case UpdateTypes.UPDATETYPE_VALUES: guid = gr.ReadPackedGuid(); sb.AppendLine("Object guid: " + guid.ToString("X16")); if (guid == 0) { long pos = gr.BaseStream.Position; swe.WriteLine("wrong guid at position {0}", pos.ToString("X2")); // we there only if we read packet wrong way swe.WriteLine("Updatetype {0} can't be with NULL guid", updatetype); return false; } ObjectTypes objecttype = ObjectTypes.TYPEID_OBJECT; // 0 if (Binparser.m_objects.ContainsKey(guid)) objecttype = Binparser.m_objects[guid]; else // try old method... { // object type auto detection: // F00C0000, F02B0000 - gameobjects // F00CXXXX, F02BXXXX - units (XXXX == 0000 for pets etc...) // F02B00000000XXXX - corpses // F02B00000000XXXX - dynamicobjects if (guid.ToString("X16").Substring(0, 8).Equals("40000000")) objecttype = ObjectTypes.TYPEID_ITEM; else if (guid.ToString("X16").Substring(0, 8).Equals("00000000")) objecttype = ObjectTypes.TYPEID_PLAYER; else objecttype = ObjectTypes.TYPEID_UNIT; // also can be go, do, corpse swe.WriteLine("problem with objecttypeid detection for UPDATETYPE_VALUES"); } sb.AppendLine("objectTypeId " + objecttype); if (!ParseValuesUpdateBlock(gr, sb, swe, data, objecttype, updatetype, null)) return false; return true; case UpdateTypes.UPDATETYPE_MOVEMENT: guid = gr.ReadPackedGuid(); sb.AppendLine("Object guid: " + guid.ToString("X16")); if (!ParseMovementUpdateBlock(gr, sb, swe, data, ObjectTypes.TYPEID_UNIT, null)) return false; return true; case UpdateTypes.UPDATETYPE_CREATE_OBJECT: case UpdateTypes.UPDATETYPE_CREATE_OBJECT2: guid = gr.ReadPackedGuid(); sb.AppendLine("Object guid: " + guid.ToString("X16")); ObjectTypes objectTypeId = (ObjectTypes)gr.ReadByte(); sb.AppendLine("objectTypeId " + objectTypeId); // check object existance and remove it if needed... //if (Binparser.m_objects.ContainsKey(guid)) // Binparser.m_objects.Remove(guid); // now we can add this object to Dictionary to get correct object type later... //Binparser.m_objects.Add(guid, objectTypeId); WoWObject obj = new WoWObject(0, objectTypeId); // add new object only if we not have it already if (!Binparser.m_objects.ContainsKey(guid)) { obj.IsNew = true; Binparser.m_objects.Add(guid, objectTypeId); } switch (objectTypeId) { case ObjectTypes.TYPEID_OBJECT: case ObjectTypes.TYPEID_AIGROUP: case ObjectTypes.TYPEID_AREATRIGGER: swe.WriteLine("Unhandled object type {0}", objectTypeId); return false; case ObjectTypes.TYPEID_ITEM: case ObjectTypes.TYPEID_CONTAINER: case ObjectTypes.TYPEID_UNIT: case ObjectTypes.TYPEID_PLAYER: case ObjectTypes.TYPEID_GAMEOBJECT: case ObjectTypes.TYPEID_DYNAMICOBJECT: case ObjectTypes.TYPEID_CORPSE: if (!ParseMovementUpdateBlock(gr, sb, swe, data, objectTypeId, obj)) return false; if (!ParseValuesUpdateBlock(gr, sb, swe, data, objectTypeId, updatetype, obj)) return false; return true; default: swe.WriteLine("Unknown object type {0}", objectTypeId); return false; } case UpdateTypes.UPDATETYPE_OUT_OF_RANGE_OBJECTS: case UpdateTypes.UPDATETYPE_NEAR_OBJECTS: uint objects_count = gr.ReadUInt32(); if (objects_count > 1000) // we read packet wrong way { long pos = gr.BaseStream.Position; swe.WriteLine("error position {0}", pos.ToString("X2")); swe.WriteLine("Too many {0} objects", updatetype); return false; } sb.AppendLine("guids_count " + objects_count); for (uint i = 0; i < objects_count; i++) sb.AppendLine("Guid" + i + ": " + gr.ReadPackedGuid().ToString("X16")); return true; default: swe.WriteLine("Unknown updatetype {0}", updatetype); return false; } }
private static bool ParseMovementUpdateBlock(GenericReader gr, StringBuilder sb, StreamWriter swe, StreamWriter data, ObjectTypes objectTypeId, WoWObject obj) { Coords4 coords; coords.X = 0; coords.Y = 0; coords.Z = 0; coords.O = 0; sb.AppendLine("=== movement_update_block_start ==="); MovementFlags mf = MovementFlags.MOVEMENTFLAG_NONE; // movement flags UpdateFlags flags = (UpdateFlags)gr.ReadByte(); sb.AppendLine("Update Flags: " + flags.ToString("X") + " : " + flags); if ((UpdateFlags.UPDATEFLAG_LIVING & flags) != 0) // 0x20 { mf = (MovementFlags)gr.ReadUInt32(); sb.AppendLine("Movement Flags: " + mf.ToString("X") + " : " + mf); byte unk = gr.ReadByte(); sb.AppendLine("Unknown Byte: " + unk.ToString("X2")); uint time = gr.ReadUInt32(); sb.AppendLine("Time: " + time.ToString("X8")); } if ((UpdateFlags.UPDATEFLAG_HASPOSITION & flags) != 0) // 0x40 { coords = gr.ReadCoords4(); sb.AppendLine("Coords: " + coords.GetCoordsAsString()); if (objectTypeId == ObjectTypes.TYPEID_UNIT || objectTypeId == ObjectTypes.TYPEID_GAMEOBJECT) { if (obj != null) obj.SetPosition(coords.X, coords.Y, coords.Z, coords.O); } } if ((flags & UpdateFlags.UPDATEFLAG_LIVING) != 0) // 0x20 { /*if (objectTypeId == ObjectTypes.TYPEID_UNIT || objectTypeId == ObjectTypes.TYPEID_GAMEOBJECT) { data.WriteLine(); data.WriteLine(objectTypeId + ": " + coords.GetCoordsAsString()); }*/ if ((mf & MovementFlags.MOVEMENTFLAG_ONTRANSPORT) != 0) // transport { ulong t_guid = gr.ReadUInt64(); sb.Append("Transport GUID: " + t_guid.ToString("X16") + ", "); Coords4 transport = gr.ReadCoords4(); sb.AppendLine("Transport Coords: " + transport.GetCoordsAsString()); uint unk2 = gr.ReadUInt32(); // unk, probably timestamp sb.AppendLine("Transport Unk: " + unk2.ToString("X8")); } if ((mf & (MovementFlags.MOVEMENTFLAG_SWIMMING | MovementFlags.MOVEMENTFLAG_UNK5)) != 0) { float unkf1 = gr.ReadSingle(); sb.AppendLine("MovementFlags & (MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_UNK5): " + unkf1); } uint unk1 = gr.ReadUInt32(); sb.AppendLine("Unk1: " + unk1.ToString("X8")); if ((mf & MovementFlags.MOVEMENTFLAG_JUMPING) != 0) { // looks like orientation/coords/speed float unk3 = gr.ReadSingle(); sb.AppendLine("unk3: " + unk3); float unk4 = gr.ReadSingle(); sb.AppendLine("unk4: " + unk4); float unk5 = gr.ReadSingle(); sb.AppendLine("unk5: " + unk5); float unk6 = gr.ReadSingle(); sb.AppendLine("unk6: " + unk6); } if ((mf & MovementFlags.MOVEMENTFLAG_SPLINE) != 0) { float unkf2 = gr.ReadSingle(); sb.AppendLine("MovementFlags & MOVEMENTFLAG_SPLINE: " + unkf2); } float ws = gr.ReadSingle(); sb.AppendLine("Walk speed: " + ws); float rs = gr.ReadSingle(); sb.AppendLine("Run speed: " + rs); float sbs = gr.ReadSingle(); sb.AppendLine("Swimback speed: " + sbs); float ss = gr.ReadSingle(); sb.AppendLine("Swim speed: " + ss); float wbs = gr.ReadSingle(); sb.AppendLine("Walkback speed: " + wbs); float fs = gr.ReadSingle(); sb.AppendLine("Fly speed: " + fs); float fbs = gr.ReadSingle(); sb.AppendLine("Flyback speed: " + fbs); float ts = gr.ReadSingle(); sb.AppendLine("Turn speed: " + ts); // pi = 3.14 if ((mf & MovementFlags.MOVEMENTFLAG_SPLINE2) != 0) { uint flags3 = gr.ReadUInt32(); sb.AppendLine("SplineFlags " + flags3.ToString("X8")); if ((flags3 & 0x10000) != 0) { Coords3 c = gr.ReadCoords3(); sb.AppendLine("SplineFlags & 0x10000: " + c.GetCoords()); } if ((flags3 & 0x20000) != 0) { ulong g3 = gr.ReadUInt64(); sb.AppendLine("flags3_guid: " + g3.ToString("X16")); // ???? } if ((flags3 & 0x40000) != 0) { uint f3_3 = gr.ReadUInt32(); sb.AppendLine("flags3_unk_value3: " + f3_3.ToString("X8")); } uint t1 = gr.ReadUInt32(); sb.AppendLine("curr tick: " + t1.ToString("X8")); uint t2 = gr.ReadUInt32(); sb.AppendLine("last tick: " + t2.ToString("X8")); uint t3 = gr.ReadUInt32(); sb.AppendLine("tick count " + t3.ToString("X8")); uint coords_count = gr.ReadUInt32(); sb.AppendLine("coords_count: " + coords_count.ToString("X8")); for (uint i = 0; i < coords_count; i++) { Coords3 v = gr.ReadCoords3(); sb.AppendLine("coord" + i + ": " + v.GetCoords()); } Coords3 end = gr.ReadCoords3(); sb.AppendLine("end: " + end.GetCoords()); } } if ((flags & UpdateFlags.UPDATEFLAG_LOWGUID) != 0) // 0x08 { uint temp = gr.ReadUInt32(); // timestamp or something like it sb.AppendLine("UpdateFlags & 0x08 (lowguid): " + temp.ToString("X8")); } if ((UpdateFlags.UPDATEFLAG_HIGHGUID & flags) != 0) // 0x10 { uint guid_high = gr.ReadUInt32(); // timestamp or something like it sb.AppendLine("UpdateFlags & 0x10 (highguid): " + guid_high.ToString("X8")); } if ((UpdateFlags.UPDATEFLAG_FULLGUID & flags) != 0) // 0x04 { ulong guid2 = gr.ReadPackedGuid(); // guid, but what guid? sb.AppendLine("UpdateFlags & 0x04 guid: " + guid2.ToString("X16")); } if ((UpdateFlags.UPDATEFLAG_TRANSPORT & flags) != 0) // 0x02 { uint time = gr.ReadUInt32(); // time sb.AppendLine("UpdateFlags & 0x02 t_time: " + time.ToString("X8")); } if ((UpdateFlags.UPDATEFLAG_SELFTARGET & flags) != 0) // 0x01 { sb.AppendLine("updating self!"); } sb.AppendLine("=== movement_update_block_end ==="); return true; }
public static bool ParseSpellNonMeleeDamageLogOpcode(GenericReader gr, GenericReader gr2, StringBuilder sb, StreamWriter swe, byte direction) { StreamWriter sw = new StreamWriter("SpellNonMeleeDamageLog.log", true, Encoding.ASCII); sw.WriteLine("Packet offset {0}", gr.BaseStream.Position.ToString("X2")); sw.WriteLine("Opcode SpellNonMeleeDamageLog (0x0250)"); ulong target = gr2.ReadPackedGuid(); ulong caster = gr2.ReadPackedGuid(); sw.WriteLine("target {0}, caster {1}", target, caster); uint spellid = gr2.ReadUInt32(); sw.WriteLine("spell {0}", spellid); uint damage = gr2.ReadUInt32(); sw.WriteLine("damage {0}", damage); byte unk1 = gr2.ReadByte(); sw.WriteLine("unk1 {0}", unk1); uint adsorb = gr2.ReadUInt32(); sw.WriteLine("adsorb {0}", adsorb); uint resist = gr2.ReadUInt32(); sw.WriteLine("resist {0}", resist); byte unk2 = gr2.ReadByte(); sw.WriteLine("unk2 {0}", unk2); byte unk3 = gr2.ReadByte(); sw.WriteLine("unk3 {0}", unk3); uint blocked = gr2.ReadUInt32(); sw.WriteLine("blocked {0}", blocked); uint flags = gr2.ReadUInt32(); sw.WriteLine("flags {0}", flags.ToString("X8")); byte unk4 = gr2.ReadByte(); sw.WriteLine("unk4 {0}", unk4); if ((flags & 0x1) != 0) { float a = gr2.ReadSingle(); float b = gr2.ReadSingle(); sw.WriteLine("0x1: a {0}, b {1}", a, b); } if ((flags & 0x4) != 0) { float a = gr2.ReadSingle(); float b = gr2.ReadSingle(); sw.WriteLine("0x4: a {0}, b {1}", a, b); } if ((flags & 0x20) != 0) { float a = gr2.ReadSingle(); float b = gr2.ReadSingle(); float c = gr2.ReadSingle(); float d = gr2.ReadSingle(); float e = gr2.ReadSingle(); float f = gr2.ReadSingle(); sw.WriteLine("0x20: a {0}, b {1}, c {2}, d {3}, e {4}, f {5}", a, b, c, d, e, f); } if (gr2.BaseStream.Position != gr2.BaseStream.Length) sw.WriteLine("F**K!: " + flags.ToString("X8")); sw.WriteLine(); sw.Flush(); sw.Close(); return true; }
public static bool ParseSpellLogExecuteOpcode(GenericReader gr, GenericReader gr2, StringBuilder sb, StreamWriter swe, byte direction) { StreamWriter sw = new StreamWriter("SpellLogExecute.log", true, Encoding.ASCII); sw.WriteLine("Packet offset {0}", gr.BaseStream.Position.ToString("X2")); sw.WriteLine("Opcode SMSG_SPELLLOGEXECUTE (0x024C)"); ulong caster = gr2.ReadPackedGuid(); sw.WriteLine("caster {0}", caster.ToString("X16")); uint spellid = gr2.ReadUInt32(); sw.WriteLine("spellid {0}", spellid); uint count1 = gr2.ReadUInt32(); sw.WriteLine("count1 {0}", count1); for (uint i = 0; i < count1; ++i) { uint spelleffect = gr2.ReadUInt32(); sw.WriteLine("spelleffect {0}", spelleffect); uint count2 = gr2.ReadUInt32(); sw.WriteLine("count2 {0}", count2); for (uint j = 0; j < count2; ++j) { ulong guid; uint unk1; uint unk2; float unk3; switch (spelleffect) { case 0x08: // SPELL_EFFECT_MANA_DRAIN guid = gr2.ReadPackedGuid(); unk1 = gr2.ReadUInt32(); unk2 = gr2.ReadUInt32(); unk3 = gr2.ReadSingle(); sw.WriteLine("0x08: {0} {1} {2} {3}", guid.ToString("X16"), unk1, unk2, unk3); break; case 0x13: // SPELL_EFFECT_ADD_EXTRA_ATTACKS guid = gr2.ReadPackedGuid(); unk1 = gr2.ReadUInt32(); sw.WriteLine("0x13: {0} {1}", guid.ToString("X16"), unk1); break; case 0x44: // SPELL_EFFECT_INTERRUPT_CAST guid = gr2.ReadPackedGuid(); unk1 = gr2.ReadUInt32(); sw.WriteLine("0x44: {0} {1}", guid.ToString("X16"), unk1); break; case 0x6F: // SPELL_EFFECT_DURABILITY_DAMAGE guid = gr2.ReadPackedGuid(); unk1 = gr2.ReadUInt32(); unk2 = gr2.ReadUInt32(); sw.WriteLine("0x6F: {0} {1} {2}", guid.ToString("X16"), unk1, unk2); break; case 0x21: // SPELL_EFFECT_OPEN_LOCK case 0x3B: // SPELL_EFFECT_OPEN_LOCK_ITEM guid = gr2.ReadPackedGuid(); sw.WriteLine("0x21,0x3B: {0}", guid.ToString("X16")); break; case 0x18: // SPELL_EFFECT_CREATE_ITEM unk1 = gr2.ReadUInt32(); sw.WriteLine("0x18: {0}", unk1); break; case 0x1C: // SPELL_EFFECT_SUMMON case 0x29: // SPELL_EFFECT_SUMMON_WILD case 0x2A: // SPELL_EFFECT_SUMMON_GUARDIAN case 0x32: // SPELL_EFFECT_TRANS_DOOR case 0x38: // SPELL_EFFECT_SUMMON_PET case 0x49: // SPELL_EFFECT_SUMMON_POSSESSED case 0x4A: // SPELL_EFFECT_SUMMON_TOTEM case 0x4C: // SPELL_EFFECT_SUMMON_OBJECT_WILD case 0x51: // SPELL_EFFECT_CREATE_HOUSE case 0x53: // SPELL_EFFECT_DUEL case 0x57: // SPELL_EFFECT_SUMMON_TOTEM_SLOT1 case 0x58: // SPELL_EFFECT_SUMMON_TOTEM_SLOT2 case 0x59: // SPELL_EFFECT_SUMMON_TOTEM_SLOT3 case 0x5A: // SPELL_EFFECT_SUMMON_TOTEM_SLOT4 case 0x5D: // SPELL_EFFECT_SUMMON_PHANTASM case 0x61: // SPELL_EFFECT_SUMMON_CRITTER case 0x68: // SPELL_EFFECT_SUMMON_OBJECT_SLOT1 case 0x69: // SPELL_EFFECT_SUMMON_OBJECT_SLOT2 case 0x6A: // SPELL_EFFECT_SUMMON_OBJECT_SLOT3 case 0x6B: // SPELL_EFFECT_SUMMON_OBJECT_SLOT4 case 0x70: // SPELL_EFFECT_SUMMON_DEMON case 0x96: // SPELL_EFFECT_150 guid = gr2.ReadPackedGuid(); sw.WriteLine("summon: {0}", guid.ToString("X16")); break; case 0x65: // SPELL_EFFECT_FEED_PET unk1 = gr2.ReadUInt32(); sw.WriteLine("0x65: {0}", unk1); break; case 0x66: // SPELL_EFFECT_DISMISS_PET guid = gr2.ReadPackedGuid(); sw.WriteLine("0x66: {0}", guid.ToString("X16")); break; default: sw.WriteLine("unknown spell effect {0}", spelleffect); break; } } } if (gr2.BaseStream.Position != gr2.BaseStream.Length) sw.WriteLine("F**K!"); sw.WriteLine(); sw.Flush(); sw.Close(); return true; }
/// <summary> /// /// </summary> /// <param name="gr"></param> /// <param name="gr2"></param> /// <param name="sb"></param> /// <param name="swe"></param> /// <returns></returns> public static bool ParsePartyMemberStatsOpcode(GenericReader gr, GenericReader gr2, StringBuilder sb, StreamWriter swe, byte direction) { sb.AppendLine("Packet offset " + gr.BaseStream.Position.ToString("X2")); sb.AppendLine("Opcode SMSG_PARTY_MEMBER_STATS (0x007E)"); byte MAX_AURAS = 56; ulong guid = gr2.ReadPackedGuid(); sb.AppendLine("GUID " + guid.ToString("X16")); GroupUpdateFlags flags = (GroupUpdateFlags)gr2.ReadUInt32(); sb.AppendLine("Flags " + flags); if ((flags & GroupUpdateFlags.GROUP_UPDATE_FLAG_ONLINE) != 0) { GroupMemberOnlineStatus online = (GroupMemberOnlineStatus)gr2.ReadUInt16(); // flag sb.AppendLine("Online state " + online); } if ((flags & GroupUpdateFlags.GROUP_UPDATE_FLAG_CUR_HP) != 0) { ushort hp = gr2.ReadUInt16(); sb.AppendLine("Cur. health " + hp); } if ((flags & GroupUpdateFlags.GROUP_UPDATE_FLAG_MAX_HP) != 0) { ushort maxhp = gr2.ReadUInt16(); sb.AppendLine("Max health " + maxhp); } if ((flags & GroupUpdateFlags.GROUP_UPDATE_FLAG_POWER_TYPE) != 0) { Powers power = (Powers)gr2.ReadByte(); sb.AppendLine("Power type " + power); } if ((flags & GroupUpdateFlags.GROUP_UPDATE_FLAG_CUR_POWER) != 0) { ushort curpower = gr2.ReadUInt16(); sb.AppendLine("Cur. power " + curpower); } if ((flags & GroupUpdateFlags.GROUP_UPDATE_FLAG_MAX_POWER) != 0) { ushort maxpower = gr2.ReadUInt16(); sb.AppendLine("Max power " + maxpower); } if ((flags & GroupUpdateFlags.GROUP_UPDATE_FLAG_LEVEL) != 0) { ushort level = gr2.ReadUInt16(); sb.AppendLine("Level " + level); } if ((flags & GroupUpdateFlags.GROUP_UPDATE_FLAG_ZONE) != 0) { ushort zone = gr2.ReadUInt16(); sb.AppendLine("Zone " + zone); } if ((flags & GroupUpdateFlags.GROUP_UPDATE_FLAG_POSITION) != 0) { short x = gr2.ReadInt16(); short y = gr2.ReadInt16(); sb.AppendLine("Position: " + x + ", " + y); } if ((flags & GroupUpdateFlags.GROUP_UPDATE_FLAG_AURAS) != 0) { ulong mask = gr2.ReadUInt64(); sb.AppendLine("Auras mask " + mask.ToString("X16")); BitArray bitArr = new BitArray(BitConverter.GetBytes(mask)); for (int i = 0; i < bitArr.Length; i++) { if (i >= MAX_AURAS) // we can have only 56 auras break; if (bitArr[i]) { ushort spellid = gr2.ReadUInt16(); sb.AppendLine("Aura " + i.ToString() + ": " + spellid.ToString()); byte unk = gr2.ReadByte(); sb.AppendLine("Aura unk " + i.ToString() + ": " + unk.ToString()); } } } if ((flags & GroupUpdateFlags.GROUP_UPDATE_FLAG_PET_GUID) != 0) { ulong petguid = gr2.ReadUInt64(); sb.AppendLine("Pet guid " + petguid.ToString("X16")); } if ((flags & GroupUpdateFlags.GROUP_UPDATE_FLAG_PET_NAME) != 0) { string name = gr2.ReadStringNull(); sb.AppendLine("Pet name " + name); } if ((flags & GroupUpdateFlags.GROUP_UPDATE_FLAG_PET_MODEL_ID) != 0) { ushort modelid = gr2.ReadUInt16(); sb.AppendLine("Pet model id " + modelid); } if ((flags & GroupUpdateFlags.GROUP_UPDATE_FLAG_PET_CUR_HP) != 0) { ushort pethp = gr2.ReadUInt16(); sb.AppendLine("Pet cur. HP " + pethp); } if ((flags & GroupUpdateFlags.GROUP_UPDATE_FLAG_PET_MAX_HP) != 0) { ushort petmaxhp = gr2.ReadUInt16(); sb.AppendLine("Pet max HP " + petmaxhp); } if ((flags & GroupUpdateFlags.GROUP_UPDATE_FLAG_PET_POWER_TYPE) != 0) { Powers power = (Powers)gr2.ReadByte(); sb.AppendLine("Pet power type " + power); } if ((flags & GroupUpdateFlags.GROUP_UPDATE_FLAG_PET_CUR_POWER) != 0) { ushort petpower = gr2.ReadUInt16(); sb.AppendLine("Pet cur. power " + petpower); } if ((flags & GroupUpdateFlags.GROUP_UPDATE_FLAG_PET_MAX_POWER) != 0) { ushort petmaxpower = gr2.ReadUInt16(); sb.AppendLine("Pet max power " + petmaxpower); } if ((flags & GroupUpdateFlags.GROUP_UPDATE_FLAG_PET_AURAS) != 0) { ulong mask = gr2.ReadUInt64(); sb.AppendLine("Pet auras mask " + mask.ToString("X16")); BitArray bitArr = new BitArray(BitConverter.GetBytes(mask)); for (int i = 0; i < bitArr.Length; i++) { if (i >= MAX_AURAS) // we can have only 56 auras break; if (bitArr[i]) { ushort spellid = gr2.ReadUInt16(); sb.AppendLine("Pet aura " + i.ToString() + ": " + spellid.ToString()); byte unk = gr2.ReadByte(); sb.AppendLine("Pet aura unk " + i.ToString() + ": " + unk.ToString()); } i++; } } if (gr2.BaseStream.Position == gr2.BaseStream.Length) sb.AppendLine("parsed: ok..."); else sb.AppendLine("parsed: error..."); 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; }