示例#1
0
        // Will return any kind of combatant, even if not a mob.
        // This function always returns a combatant object, even if empty.
        public unsafe Combatant GetCombatantFromByteArray(byte[] source, uint mycharID, bool isPlayer, bool exceptEffects = false)
        {
            fixed(byte *p = source)
            {
                CombatantMemory mem = *(CombatantMemory *)&p[0];

                if (isPlayer)
                {
                    mycharID = mem.ID;
                }

                Combatant combatant = new Combatant()
                {
                    Name              = FFXIVMemory.GetStringFromBytes(mem.Name, CombatantMemory.nameBytes),
                    Job               = mem.Job,
                    ID                = mem.ID,
                    OwnerID           = mem.OwnerID == emptyID ? 0 : mem.OwnerID,
                    Type              = (ObjectType)mem.Type,
                    EffectiveDistance = mem.EffectiveDistance,
                    PosX              = mem.PosX,
                    PosY              = mem.PosY,
                    PosZ              = mem.PosZ,
                    TargetID          = mem.TargetID,
                    CurrentHP         = mem.CurrentHP,
                    MaxHP             = mem.MaxHP,
                    Effects           = exceptEffects ? new List <EffectEntry>() : GetEffectEntries(mem.Effects, (ObjectType)mem.Type, mycharID),
                };

                if (combatant.Type != ObjectType.PC && combatant.Type != ObjectType.Monster)
                {
                    // Other types have garbage memory for hp.
                    combatant.CurrentHP = 0;
                    combatant.MaxHP     = 0;
                }
                return(combatant);
            }
        }
 private int GetPartyType(Combatant combatant)
 {
     // The PartyTypeEnum was renamed in 2.6.0.0 to work around that, we use reflection and cast the result to int.
     return((int)combatant.GetType().GetMethod("get_PartyType").Invoke(combatant, new object[] {}));
 }
示例#3
0
        // Converts an EnmityList into a List<AggroEntry>.
        public unsafe List <AggroEntry> GetAggroList(List <Combatant> combatantList)
        {
            Combatant mychar = GetSelfCombatant();

            uint currentTargetID = 0;
            var  targetCombatant = GetTargetCombatant();

            if (targetCombatant != null)
            {
                currentTargetID = targetCombatant.ID;
            }

            var result = new List <AggroEntry>();

            EnmityList list = ReadEnmityList(aggroAddress);

            for (int i = 0; i < list.numEntries; i++)
            {
                EnmityListEntry e = list.GetEntry(i);
                if (e.ID <= 0)
                {
                    continue;
                }
                Combatant c = combatantList.Find(x => x.ID == e.ID);
                if (c == null)
                {
                    continue;
                }

                var entry = new AggroEntry()
                {
                    ID = e.ID,
                    // Rather than storing enmity, this is hate rate for the aggro list.
                    // This is likely because we're reading the memory for the aggro sidebar.
                    HateRate        = (int)e.Enmity,
                    isCurrentTarget = (e.ID == currentTargetID),
                    Name            = c.Name,
                    MaxHP           = c.MaxHP,
                    CurrentHP       = c.CurrentHP,
                    Effects         = c.Effects,
                };

                // TODO: it seems like when your chocobo has aggro, this entry
                // is you, and not your chocobo.  It's not clear if there's
                // anything that can be done about it.
                if (c.TargetID > 0)
                {
                    Combatant t = combatantList.Find(x => x.ID == c.TargetID);
                    if (t != null)
                    {
                        entry.Target = new EnmityEntry()
                        {
                            ID       = t.ID,
                            Name     = t.Name,
                            OwnerID  = t.OwnerID,
                            isMe     = mychar.ID == t.ID ? true : false,
                            Enmity   = 0,
                            HateRate = 0,
                            Job      = t.Job,
                        };
                    }
                }
                result.Add(entry);
            }
            return(result);
        }
示例#4
0
        private bool GetPointerAddress()
        {
            if (!memory.IsValid())
            {
                return(false);
            }

            bool success = true;
            bool bRIP    = true;

            List <string> fail = new List <string>();

            /// CHARMAP
            List <IntPtr> list = memory.SigScan(charmapSignature, 0, bRIP);

            if (list != null && list.Count == 1)
            {
                charmapAddress = list[0] + charmapSignatureOffset;
            }
            else
            {
                charmapAddress = IntPtr.Zero;
                fail.Add(nameof(charmapAddress));
                success = false;
            }

            // ENMITY
            list = memory.SigScan(enmitySignature, 0, bRIP);
            if (list != null && list.Count == 1)
            {
                enmityAddress = list[0] + enmitySignatureOffset;
                aggroAddress  = IntPtr.Add(enmityAddress, aggroEnmityOffset);
            }
            else
            {
                enmityAddress = IntPtr.Zero;
                aggroAddress  = IntPtr.Zero;
                fail.Add(nameof(enmityAddress));
                fail.Add(nameof(aggroAddress));
                success = false;
            }

            /// TARGET
            list = memory.SigScan(targetSignature, 0, bRIP);
            if (list != null && list.Count == 1)
            {
                targetAddress = list[0] + targetSignatureOffset;
            }
            else
            {
                targetAddress = IntPtr.Zero;
                fail.Add(nameof(targetAddress));
                success = false;
            }

            logger.Log(LogLevel.Debug, "charmapAddress: 0x{0:X}", charmapAddress.ToInt64());
            logger.Log(LogLevel.Debug, "enmityAddress: 0x{0:X}", enmityAddress.ToInt64());
            logger.Log(LogLevel.Debug, "targetAddress: 0x{0:X}", targetAddress.ToInt64());
            Combatant c = GetSelfCombatant();

            if (c != null)
            {
                logger.Log(LogLevel.Debug, "MyCharacter: '{0}' (0x{1:X})", c.Name, c.ID);
            }

            if (!success)
            {
                logger.Log(LogLevel.Error, "Failed to memory scan: {0}.", String.Join(",", fail));
            }

            return(success);
        }
        private bool GetPointerAddress()
        {
            if (!memory.IsValid())
            {
                return(false);
            }

            // Don't scan too often to avoid excessive CPU load
            if ((DateTime.Now - lastSigScan) < TimeSpan.FromSeconds(5))
            {
                return(false);
            }

            lastSigScan = DateTime.Now;
            bool success = true;
            bool bRIP    = true;

            List <string> fail = new List <string>();

            /// CHARMAP
            List <IntPtr> list = memory.SigScan(charmapSignature, 0, bRIP);

            if (list != null && list.Count > 0)
            {
                charmapAddress = list[0] + charmapSignatureOffset;
            }
            else
            {
                charmapAddress = IntPtr.Zero;
                fail.Add(nameof(charmapAddress));
                success = false;
            }

            // ENMITY
            list = memory.SigScan(enmitySignature, 0, bRIP);
            if (list != null && list.Count > 0)
            {
                enmityAddress = IntPtr.Add(list[0], enmitySignatureOffset);
                aggroAddress  = IntPtr.Add(list[0], aggroEnmityOffset);
            }
            else
            {
                enmityAddress = IntPtr.Zero;
                aggroAddress  = IntPtr.Zero;
                fail.Add(nameof(enmityAddress));
                fail.Add(nameof(aggroAddress));
                success = false;
            }

            /// TARGET
            list = memory.SigScan(targetSignature, 0, bRIP);
            if (list != null && list.Count > 0)
            {
                targetAddress = list[0] + targetSignatureOffset;
            }
            else
            {
                targetAddress = IntPtr.Zero;
                fail.Add(nameof(targetAddress));
                success = false;
            }

            logger.Log(LogLevel.Debug, "charmapAddress: 0x{0:X}", charmapAddress.ToInt64());
            logger.Log(LogLevel.Debug, "enmityAddress: 0x{0:X}", enmityAddress.ToInt64());
            logger.Log(LogLevel.Debug, "aggroAddress: 0x{0:X}", aggroAddress.ToInt64());
            logger.Log(LogLevel.Debug, "targetAddress: 0x{0:X}", targetAddress.ToInt64());
            Combatant c = GetSelfCombatant();

            if (c != null)
            {
                logger.Log(LogLevel.Debug, "MyCharacter: '{0}' (0x{1:X})", c.Name, c.ID);
            }

            if (!success)
            {
                logger.Log(LogLevel.Error, "Failed to memory scan 5.2: {0}.", String.Join(",", fail));
            }
            else
            {
                logger.Log(LogLevel.Info, "Found enmity memory for 5.2.");
            }

            return(success);
        }