示例#1
0
        public Object(IObjectGUID guid, ParsingContext context)
        {
            _context = context;

            Guid       = guid;
            ObjectData = context.Helper.UpdateFieldProvider.CreateObjectData(guid) !;
        }
示例#2
0
        public Player(IObjectGUID guid, ParsingContext context, bool isSelf) : base(guid, context)
        {
            var playerData = context.Helper.UpdateFieldProvider.CreatePlayerData(guid);

            PlayerData = playerData ?? throw new InvalidOperationException();

            if (isSelf)
            {
                var activePlayerData = context.Helper.UpdateFieldProvider.CreateActivePlayerData(guid);
                ActivePlayerData = activePlayerData ?? throw new InvalidOperationException();
            }

            UnitData.Level.Take(1).Subscribe(tuple => {
                Level = tuple.Value;
            });
        }
示例#3
0
        public ObjectGuidType Resolve(IObjectGUID guid, ClientBuild clientBuild)
        {
            if (guid.Parts[0] == 0)
            {
                return(ObjectGuidType.Null);
            }

            var highGUID = (guid.Parts[0] & 0xF0F0000000000000) >> 52;

            return(highGUID switch
            {
                0x000 => ObjectGuidType.Player,
                0x101 => ObjectGuidType.Battleground,
                0x104 => ObjectGuidType.InstanceSave,
                0x105 => ObjectGuidType.Party,
                0x109 => ObjectGuidType.Battleground, // 2
                0x10E => ObjectGuidType.Unknown,
                0x10F => ObjectGuidType.Guild,
                0x400 => ObjectGuidType.Item,
                0xF00 => ObjectGuidType.DynamicObject,
                0xF01 => ObjectGuidType.GameObject,
                0x10C => ObjectGuidType.Transport, // MO Transport
                0xF02 => ObjectGuidType.Transport,
                0xF03 => ObjectGuidType.Creature,
                0xF04 => ObjectGuidType.Pet,
                0xF05 => ObjectGuidType.Vehicle,
                //
                _ => (highGUID & 0xF00) switch
                {
                    // TODO: Players sometimes have high guid 0x048 for reasons
                    // TODO: unbeknownst to me. Just check the high byte. If zero,
                    // TODO: the high guid will be 0x0??, aka Player.
                    0x000 => ObjectGuidType.Player,
                    _ => ObjectGuidType.Unknown
                }
            });
示例#4
0
 public IAreaTriggerData?CreateAreaTriggerData(IObjectGUID guid)
 => _areaTriggerDataBuilder?.Invoke(_context);
示例#5
0
 public IActivePlayerData?CreateActivePlayerData(IObjectGUID guid)
 => _activePlayerDataBuilder?.Invoke(_context);
示例#6
0
 public IPlayerData?CreatePlayerData(IObjectGUID guid)
 => _playerDataBuilder?.Invoke(_context);
示例#7
0
 public IUnitData?CreateUnitData(IObjectGUID guid)
 => _unitDataBuilder?.Invoke(_context);
示例#8
0
 public IContainerData?CreateContainerData(IObjectGUID guid)
 => _containerDataBuilder?.Invoke(_context);
示例#9
0
            public SpellCastData(Packet packet)
            {
                Caster      = packet.ReadPackedGUID();
                UnitCaster  = packet.ReadPackedGUID();
                CastID      = packet.ReadUInt8();
                SpellID     = packet.ReadUInt32();
                CastFlags   = (CastFlags)packet.ReadUInt32();
                CastFlagsEx = (CastFlagsEx)packet.ReadUInt32();
                CastTime    = packet.ReadUInt32();

                if (packet.Opcode == Opcode.SMSG_SPELL_GO)
                {
                    HitTargets = new IObjectGUID[packet.ReadUInt8()];
                    for (var i = 0; i < HitTargets.Length; ++i)
                    {
                        HitTargets[i] = packet.ReadGUID();
                    }

                    MissedTargets = new MissInfo[packet.ReadUInt8()];
                    for (var i = 0; i < MissedTargets.Length; ++i)
                    {
                        var missTarget = packet.ReadGUID();
                        var missType   = packet.ReadUInt8();

                        if (missType == 11) // Reflect
                        {
                            MissedTargets[i] = new(missTarget, missType, packet.ReadUInt8());
                        }
                        else
                        {
                            MissedTargets[i] = new(missTarget, missType);
                        }
                    }
                }

                TargetFlags = (TargetFlags)packet.ReadUInt32();
                if (TargetFlags.HasFlag(TargetFlags.Unit | TargetFlags.CorpseAlly | TargetFlags.CorpseEnemy | TargetFlags.GameObject | TargetFlags.Minipet))
                {
                    ExplicitTarget = packet.ReadPackedGUID();
                }
                else if (TargetFlags.HasFlag(TargetFlags.Item | TargetFlags.TradeItem))
                {
                    ExplicitTarget = packet.ReadPackedGUID();
                }

                if (TargetFlags.HasFlag(TargetFlags.SourceLocation))
                {
                    Source = new(packet);
                }

                if (TargetFlags.HasFlag(TargetFlags.DestinationLocation))
                {
                    Destination = new(packet);
                }

                if (TargetFlags.HasFlag(TargetFlags.String))
                {
                    var @string = packet.ReadCString(128);
                }

                if (TargetFlags.HasFlag(TargetFlags.ExtraTargets))
                {
                    var extraTargetCount = packet.ReadInt32();
                    for (var i = 0; i < extraTargetCount; ++i)
                    {
                        var i1   = packet.ReadUInt32();
                        var i2   = packet.ReadUInt32();
                        var i3   = packet.ReadUInt32();
                        var guid = packet.ReadGUID();
                    }
                }

                if (CastFlags.HasFlag(CastFlags.Power))
                {
                    Power = packet.ReadUInt32();
                }

                if (CastFlags.HasFlag(CastFlags.Runes))
                {
                    Runes = new(packet);
                }

                if (CastFlags.HasFlag(CastFlags.Missile))
                {
                    MissileInfo = new(packet);
                }

                if (CastFlags.HasFlag(CastFlags.Ammo))
                {
                    var displayID     = packet.ReadUInt32();
                    var inventoryType = packet.ReadUInt32();
                }

                if (CastFlags.HasFlag(CastFlags.VisualChain))
                {
                    var i0 = packet.ReadUInt32();
                    var i1 = packet.ReadUInt32();
                }

                if (TargetFlags.HasFlag(TargetFlags.DestinationLocation)) // Wrong mask, cba fixing rn
                {
                    var destLocationCastIndex = packet.ReadUInt8();
                }

                if (CastFlags.HasFlag(CastFlags.Immunities))
                {
                    var mechanicImmunity = packet.ReadUInt32();
                    var immunity         = packet.ReadUInt32();
                }

                // More data (prediction)
            }
 public bool CanResolve(IObjectGUID objectGuid, ClientBuild clientBuild)
 => true;
示例#11
0
        public Item(IObjectGUID guid, ParsingContext context) : base(guid, context)
        {
            var itemData = context.Helper.UpdateFieldProvider.CreateItemData(guid);

            ItemData = itemData ?? throw new InvalidOperationException();
        }
示例#12
0
 public IDynamicObjectData?CreateDynamicObjectData(IObjectGUID guid)
 => _dynamicObjectDataBuilder?.Invoke(_context);
示例#13
0
        private static void HandleCreateObject(ParsingContext context, Packet packet, IObjectGUID guid, ushort map, UpdateType updateType)
        {
            var objectType = context.Helper.ResolveTypeID(packet.ReadUInt8());

            var entity = HandleMovementUpdate(context, packet, guid, objectType, map);

            HandleValuesUpdate(context, packet, entity, map);
        }
示例#14
0
 private static void HandleValuesUpdate(ParsingContext context, Packet packet, IObjectGUID guid, ushort map)
 {
     HandleValuesUpdate(context, packet, context.ObjectManager[guid], map);
 }
示例#15
0
        private static IEntity HandleMovementUpdate(ParsingContext context, Packet packet, IObjectGUID guid, EntityTypeID entityTypeID, ushort map)
        {
            var playHoverAnim       = packet.ReadBit();
            var suppressedGreetings = packet.ReadBit();
            var hasRotation         = packet.ReadBit();
            var hasAnimKits         = packet.ReadBit();
            var hasTargetGUID       = packet.ReadBit();

            var entity           = context.ObjectManager[guid, entityTypeID, packet.ReadBit()];
            var movementSnapshot = entity.MovementInfo[packet.Moment];

            movementSnapshot.PlayHoverAnim       = playHoverAnim;
            movementSnapshot.SuppressedGreetings = suppressedGreetings;

            var hasVehicleData = packet.ReadBit();
            var hasLivingData  = packet.ReadBit();
            var stopFrameCount = packet.ReadBits(24);

            movementSnapshot.NoBirthAnim = packet.ReadBit();
            var hasGoTransportPosition = packet.ReadBit();
            var hasStationaryPosition  = packet.ReadBit();
            var hasAreaTrigger         = packet.ReadBit();

            movementSnapshot.EnablePortals = packet.ReadBit();
            var hasTransport = packet.ReadBit();

            // Readers
            var livingReader      = new LivingReader();
            var goTransportReader = new GoTransportReader();
            var animKitReader     = new AnimKitsReader();

            if (hasLivingData)
            {
                livingReader.FirstPass(movementSnapshot, packet, context);
            }

            if (hasGoTransportPosition)
            {
                goTransportReader.FirstPass(movementSnapshot, packet, context);
            }

            if (hasTargetGUID) // 446
            {
                movementSnapshot.TargetGUID = context.Helper.GuidResolver.CreateGUID();
                movementSnapshot.TargetGUID !.AsBitStream().Initialize(packet, 2, 7, 0, 4, 5, 6, 1, 3);
            }

            if (hasAnimKits)
            {
                animKitReader.FirstPass(movementSnapshot, packet, context);
            }

            packet.ResetBitReader();

            // Exit out early if stop frames received for a non-transport
            if (stopFrameCount != 0 && movementSnapshot.Transport == null)
            {
                throw new InvalidOperationException();
            }

            // Shove them in trnasport even though they aren't in the data block itself.
            if (movementSnapshot.Transport == null)
            {
                for (var i = 0; i < stopFrameCount; ++i)
                {
                    packet.ReadUInt32();
                }
            }
            else
            {
                movementSnapshot.Transport !.StopFrames = new uint[stopFrameCount];
                for (var i = 0; i < stopFrameCount; ++i)
                {
                    movementSnapshot.Transport !.StopFrames[i] = packet.ReadUInt32();
                }
            }

            if (hasLivingData)
            {
                livingReader.SecondPass(movementSnapshot, packet, context);
            }

            if (hasVehicleData)
            {
                movementSnapshot.Vehicle = new MovementInfo.VehicleData();

                movementSnapshot.Vehicle.Orientation = packet.ReadSingle();
                movementSnapshot.Vehicle.ID          = packet.ReadUInt32();
            }

            if (hasGoTransportPosition)
            {
                goTransportReader.SecondPass(movementSnapshot, packet, context);
            }

            if (hasRotation)
            {
                // Packed Quaternion
                // TODO
                var packedRotation = packet.ReadUInt64();
            }

            if (hasAreaTrigger)
            {
                packet.ReadSingle();
                packet.ReadSingle();
                packet.ReadSingle();
                packet.ReadSingle();
                packet.ReadUInt8();
                packet.ReadSingle();
                packet.ReadSingle();
                packet.ReadSingle();
                packet.ReadSingle();
                packet.ReadSingle();
                packet.ReadSingle();
                packet.ReadSingle();
                packet.ReadSingle();
                packet.ReadSingle();
                packet.ReadSingle();
                packet.ReadSingle();
                packet.ReadSingle();
            }

            if (hasStationaryPosition)
            {
                movementSnapshot.Stationary = new Vector4()
                {
                    O = packet.ReadSingle(),
                    X = packet.ReadSingle(),
                    Y = packet.ReadSingle(),
                    Z = packet.ReadSingle()
                };
            }

            if (hasTargetGUID)
            {
                movementSnapshot.TargetGUID !.AsBitStream().Parse(packet, 4, 0, 3, 5, 7, 6, 2, 1);
            }

            if (hasAnimKits)
            {
                animKitReader.SecondPass(movementSnapshot, packet, context);
            }

            if (hasTransport)
            {
                movementSnapshot.PathProgress = packet.ReadUInt32();
            }

            return(entity);
        }
 internal ObjectGuidStream(IObjectGUID guid, int size, ByteAccessor accessor)
 {
     _flags    = new bool[size];
     _accessor = accessor;
 }
示例#17
0
 public bool CanResolve(IObjectGUID objectGuid, ClientBuild clientBuild)
 => clientBuild.Expansion == Expansion.Cataclysm;
示例#18
0
 public Location(Packet packet)
 {
     Transport = packet.ReadPackedGUID();
     Position  = packet.ReadVector3();
 }
示例#19
0
        public AreaTrigger(IObjectGUID guid, ParsingContext context) : base(guid, context)
        {
            var areaTriggerData = context.Helper.UpdateFieldProvider.CreateAreaTriggerData(guid);

            AreaTriggerData = areaTriggerData ?? throw new InvalidOperationException();
        }
示例#20
0
 public abstract IEntity CreateEntity(IObjectGUID objectGUID, EntityTypeID typeID, bool isSelf);
示例#21
0
        public DynamicObject(IObjectGUID guid, ParsingContext context) : base(guid, context)
        {
            var dynamicObjectData = context.Helper.UpdateFieldProvider.CreateDynamicObjectData(guid);

            DynamicObjectData = dynamicObjectData ?? throw new InvalidOperationException();
        }
示例#22
0
 public IObjectData?CreateObjectData(IObjectGUID guid)
 => _objectDataBuilder?.Invoke(_context);
示例#23
0
 public IItemData?CreateItemData(IObjectGUID guid)
 => _itemDataBuilder?.Invoke(_context);
示例#24
0
        public Corpse(IObjectGUID guid, ParsingContext context) : base(guid, context)
        {
            var corpseData = context.Helper.UpdateFieldProvider.CreateCorpseData(guid);

            CorpseData = corpseData ?? throw new InvalidOperationException();
        }