public override void Parse()
        {
            AppendFormatLine("Monster GUID: 0x{0:X16}", Reader.ReadPackedGuid());

            if (Packet.Code == OpCodes.SMSG_MONSTER_MOVE_TRANSPORT)
            {
                AppendFormatLine("Transport GUID: 0x{0:X16}", Reader.ReadPackedGuid());
                AppendFormatLine("Transport Seat: 0x{0:X2}", Reader.ReadByte());
            }

            AppendFormatLine("Monster unk byte: {0}", Reader.ReadByte()); // toggle MOVEFLAG2 & 0x40

            var curr = Reader.ReadCoords3();

            AppendFormatLine("Current Position: {0}", curr);
            AppendFormatLine("Ticks Count: 0x{0:X8}", Reader.ReadUInt32());

            var movementType = (SplineType)Reader.ReadByte(); // 0-4

            AppendFormatLine("SplineType: {0}", movementType);

            switch (movementType)
            {
            case SplineType.Normal:
                break;

            case SplineType.Stop:
                // client sets following values to:
                // movementFlags = 0x1000;
                // moveTime = 0;
                // splinesCount = 1;
                // and returns
                return;

            case SplineType.FacingSpot:
                AppendFormatLine("Facing Point: {0}", Reader.ReadCoords3());
                break;

            case SplineType.FacingTarget:
                AppendFormatLine("Facing GUID: 0x{0:X16}", Reader.ReadUInt64());
                break;

            case SplineType.FacingAngle:
                AppendFormatLine("Facing Angle: {0}", Reader.ReadSingle());
                break;

            default:
                break;
            }

            #region Block1

            // block1
            var splineFlags = (SplineFlags)Reader.ReadUInt32();
            AppendFormatLine("Spline Flags: {0}", splineFlags);

            if (splineFlags.HasFlag(SplineFlags.UNK3))
            {
                var unk_0x200000         = Reader.ReadByte();   // anim type
                var unk_0x200000_ms_time = Reader.ReadUInt32(); // time

                AppendFormatLine("SplineFlags 0x200000: anim type 0x{0:X8} and time 0x{1:X8}", unk_0x200000, unk_0x200000_ms_time);
            }

            var moveTime = Reader.ReadUInt32();
            AppendFormatLine("Spline Time: 0x{0:X8}", moveTime);

            if (splineFlags.HasFlag(SplineFlags.TRAJECTORY))
            {
                var unk_float_0x800 = Reader.ReadSingle();
                var unk_int_0x800   = Reader.ReadUInt32();

                AppendFormatLine("SplineFlags 0x800: float {0} and int 0x{1:X8}", unk_float_0x800, unk_int_0x800);
            }

            var splinesCount = Reader.ReadUInt32();
            AppendFormatLine("Splines Count: {0}", splinesCount);

            #endregion

            #region Block2

            // block2
            if (splineFlags.HasFlag(SplineFlags.FLYING) || splineFlags.HasFlag(SplineFlags.CATMULLROM))
            {
                var startPos = Reader.ReadCoords3();
                AppendFormatLine("Splines Start Point: {0}", startPos);

                if (splinesCount > 1)
                {
                    for (var i = 0; i < splinesCount - 1; ++i)
                    {
                        AppendFormatLine("Spline Point {0}: {1}", i, Reader.ReadCoords3());
                    }
                }
            }
            else
            {
                var dest = Reader.ReadCoords3();

                var mid = new Coords3();
                mid.X = (curr.X + dest.X) * 0.5f;
                mid.Y = (curr.Y + dest.Y) * 0.5f;
                mid.Z = (curr.Z + dest.Z) * 0.5f;

                AppendFormatLine("Dest position: {0}", dest);

                if (splinesCount > 1)
                {
                    for (var i = 0; i < splinesCount - 1; ++i)
                    {
                        var packedOffset = Reader.ReadInt32();
                        AppendFormatLine("Packed Vector: 0x{0:X8}", packedOffset);

                        #region Unpack

                        var x = ((packedOffset & 0x7FF) << 21 >> 21) * 0.25f;
                        var y = ((((packedOffset >> 11) & 0x7FF) << 21) >> 21) * 0.25f;
                        var z = ((packedOffset >> 22 << 22) >> 22) * 0.25f;
                        AppendFormatLine("Path Point {0}: {1}, {2}, {3}", i, mid.X - x, mid.Y - y, mid.Z - z);

                        #endregion

                        #region Pack

                        var packed = 0;
                        packed |= ((int)(x / 0.25f) & 0x7FF);
                        packed |= ((int)(y / 0.25f) & 0x7FF) << 11;
                        packed |= ((int)(z / 0.25f) & 0x3FF) << 22;
                        AppendFormatLine("Test packing 0x{0:X8}", packed);

                        if (packedOffset != packed)
                        {
                            AppendFormatLine("Not equal!");
                        }

                        #endregion
                    }
                }
            }

            #endregion
        }
        /// <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);
        }
Exemple #3
0
        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);
        }