示例#1
0
        public static ActorReadResult GetActors()
        {
            var result = new ActorReadResult();

            if (!Scanner.Instance.Locations.ContainsKey("CHARMAP"))
            {
                return(result);
            }

            try
            {
                #region Ensure Target

                var targetAddress = IntPtr.Zero;

                #endregion

                var endianSize = MemoryHandler.Instance.ProcessModel.IsWin64 ? 8 : 4;

                var limit = MemoryHandler.Instance.Structures.ActorInfo.Size;

                var characterAddressMap = MemoryHandler.Instance.GetByteArray(Scanner.Instance.Locations["CHARMAP"], endianSize * limit);
                var uniqueAddresses     = new Dictionary <IntPtr, IntPtr>();
                var firstAddress        = IntPtr.Zero;

                var firstTime = true;

                for (var i = 0; i < limit; i++)
                {
                    IntPtr characterAddress;

                    if (MemoryHandler.Instance.ProcessModel.IsWin64)
                    {
                        characterAddress = new IntPtr(BitConverter.TryToInt64(characterAddressMap, i * endianSize));
                    }
                    else
                    {
                        characterAddress = new IntPtr(BitConverter.TryToInt32(characterAddressMap, i * endianSize));
                    }
                    if (characterAddress == IntPtr.Zero)
                    {
                        continue;
                    }

                    if (firstTime)
                    {
                        firstAddress = characterAddress;
                        firstTime    = false;
                    }
                    uniqueAddresses[characterAddress] = characterAddress;
                }

                #region ActorEntity Handlers

                result.RemovedMonster = MonsterWorkerDelegate.EntitiesDictionary.Keys.ToDictionary(key => key);
                result.RemovedNPC     = NPCWorkerDelegate.EntitiesDictionary.Keys.ToDictionary(key => key);
                result.RemovedPC      = PCWorkerDelegate.EntitiesDictionary.Keys.ToDictionary(key => key);

                foreach (var kvp in uniqueAddresses)
                {
                    try
                    {
                        var source = MemoryHandler.Instance.GetByteArray(new IntPtr(kvp.Value.ToInt64()), 0x23F0);
                        //var source = MemoryHandler.Instance.GetByteArray(characterAddress, 0x3F40);

                        var         ID       = BitConverter.TryToUInt32(source, MemoryHandler.Instance.Structures.ActorEntity.ID);
                        var         NPCID2   = BitConverter.TryToUInt32(source, MemoryHandler.Instance.Structures.ActorEntity.NPCID2);
                        var         Type     = (Actor.Type)source[MemoryHandler.Instance.Structures.ActorEntity.Type];
                        ActorEntity existing = null;
                        var         newEntry = false;

                        switch (Type)
                        {
                        case Actor.Type.Monster:
                            if (result.RemovedMonster.ContainsKey(ID))
                            {
                                result.RemovedMonster.Remove(ID);
                                existing = MonsterWorkerDelegate.GetEntity(ID);
                            }
                            else
                            {
                                result.NewMonster.Add(ID);
                                newEntry = true;
                            }
                            break;

                        case Actor.Type.PC:
                            if (result.RemovedPC.ContainsKey(ID))
                            {
                                result.RemovedPC.Remove(ID);
                                existing = PCWorkerDelegate.GetEntity(ID);
                            }
                            else
                            {
                                result.NewPC.Add(ID);
                                newEntry = true;
                            }
                            break;

                        case Actor.Type.NPC:
                        case Actor.Type.Aetheryte:
                        case Actor.Type.EObj:
                            if (result.RemovedNPC.ContainsKey(NPCID2))
                            {
                                result.RemovedNPC.Remove(NPCID2);
                                existing = NPCWorkerDelegate.GetEntity(NPCID2);
                            }
                            else
                            {
                                result.NewNPC.Add(NPCID2);
                                newEntry = true;
                            }
                            break;

                        default:
                            if (result.RemovedNPC.ContainsKey(ID))
                            {
                                result.RemovedNPC.Remove(ID);
                                existing = NPCWorkerDelegate.GetEntity(ID);
                            }
                            else
                            {
                                result.NewNPC.Add(ID);
                                newEntry = true;
                            }
                            break;
                        }

                        var isFirstEntry = kvp.Value.ToInt64() == firstAddress.ToInt64();

                        var entry = ActorEntityHelper.ResolveActorFromBytes(source, isFirstEntry, existing);

                        #region Ensure Map & Zone

                        EnsureMapAndZone(entry);

                        #endregion

                        if (isFirstEntry)
                        {
                            if (targetAddress.ToInt64() > 0)
                            {
                                var targetInfoSource = MemoryHandler.Instance.GetByteArray(targetAddress, 128);
                                entry.TargetID = (int)BitConverter.TryToUInt32(targetInfoSource, MemoryHandler.Instance.Structures.ActorEntity.ID);
                            }
                        }
                        if (!entry.IsValid)
                        {
                            result.NewMonster.Remove(entry.ID);
                            result.NewMonster.Remove(entry.NPCID2);
                            result.NewNPC.Remove(entry.ID);
                            result.NewNPC.Remove(entry.NPCID2);
                            result.NewPC.Remove(entry.ID);
                            result.NewPC.Remove(entry.NPCID2);
                            continue;
                        }
                        if (existing != null)
                        {
                            continue;
                        }

                        if (newEntry)
                        {
                            switch (entry.Type)
                            {
                            case Actor.Type.Monster:
                                MonsterWorkerDelegate.EnsureEntity(entry.ID, entry);
                                break;

                            case Actor.Type.PC:
                                PCWorkerDelegate.EnsureEntity(entry.ID, entry);
                                break;

                            case Actor.Type.Aetheryte:
                            case Actor.Type.EObj:
                            case Actor.Type.NPC:
                                NPCWorkerDelegate.EnsureEntity(entry.NPCID2, entry);
                                break;

                            default:
                                NPCWorkerDelegate.EnsureEntity(entry.ID, entry);
                                break;
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        MemoryHandler.Instance.RaiseException(Logger, ex, true);
                    }
                }

                try
                {
                    // REMOVE OLD MONSTERS FROM LIVE CURRENT DICTIONARY
                    foreach (var kvp in result.RemovedMonster)
                    {
                        MonsterWorkerDelegate.RemoveEntity(kvp.Key);
                    }

                    // REMOVE OLD NPC'S FROM LIVE CURRENT DICTIONARY
                    foreach (var kvp in result.RemovedNPC)
                    {
                        NPCWorkerDelegate.RemoveEntity(kvp.Key);
                    }

                    // REMOVE OLD PC'S FROM LIVE CURRENT DICTIONARY
                    foreach (var kvp in result.RemovedPC)
                    {
                        PCWorkerDelegate.RemoveEntity(kvp.Key);
                    }
                }
                catch (Exception ex)
                {
                    MemoryHandler.Instance.RaiseException(Logger, ex, true);
                }

                MemoryHandler.Instance.ScanCount++;

                #endregion
            }
            catch (Exception ex)
            {
                MemoryHandler.Instance.RaiseException(Logger, ex, true);
            }

            return(result);
        }