Пример #1
0
        /// <summary>
        /// </summary>
        /// <param name="sender"> </param>
        /// <param name="e"> </param>
        private void ScanTimerElapsed(object sender, ElapsedEventArgs e)
        {
            if (_isScanning)
            {
                return;
            }
            _isScanning = true;
            double refresh = 100;

            if (Double.TryParse(Settings.Default.ActorWorkerRefresh.ToString(CultureInfo.InvariantCulture), out refresh))
            {
                _scanTimer.Interval = refresh;
            }
            Func <bool> scannerWorker = delegate
            {
                if (MemoryHandler.Instance.SigScanner.Locations.ContainsKey("GAMEMAIN"))
                {
                    if (MemoryHandler.Instance.SigScanner.Locations.ContainsKey("CHARMAP"))
                    {
                        try
                        {
                            #region Ensure Target & Map

                            long targetAddress = 0;
                            uint mapIndex      = 0;
                            if (MemoryHandler.Instance.SigScanner.Locations.ContainsKey("TARGET"))
                            {
                                try
                                {
                                    targetAddress = MemoryHandler.Instance.SigScanner.Locations["TARGET"];
                                }
                                catch (Exception ex)
                                {
                                }
                            }
                            if (MemoryHandler.Instance.SigScanner.Locations.ContainsKey("MAP"))
                            {
                                try
                                {
                                    mapIndex = (uint)MemoryHandler.Instance.GetPlatformUInt(MemoryHandler.Instance.SigScanner.Locations["MAP"]);
                                }
                                catch (Exception ex)
                                {
                                }
                            }

                            #endregion

                            var       endianSize = MemoryHandler.Instance.ProcessModel.IsWin64 ? 8 : 4;
                            const int limit      = 1372;

                            var characterAddressMap = MemoryHandler.Instance.GetByteArray(MemoryHandler.Instance.SigScanner.Locations["CHARMAP"], endianSize * limit);

                            var uniqueAddresses = new Dictionary <IntPtr, IntPtr>();

                            for (var i = 0; i < limit; i++)
                            {
                                IntPtr characterAddress;
                                if (MemoryHandler.Instance.ProcessModel.IsWin64)
                                {
                                    characterAddress = new IntPtr(BitConverter.ToInt64(characterAddressMap, i * endianSize));
                                }
                                else
                                {
                                    characterAddress = new IntPtr(BitConverter.ToInt32(characterAddressMap, i * endianSize));
                                }
                                if (characterAddress == IntPtr.Zero)
                                {
                                    continue;
                                }
                                uniqueAddresses[characterAddress] = characterAddress;
                            }

                            var sourceData = uniqueAddresses.Select(kvp => MemoryHandler.Instance.GetByteArray((long)kvp.Value, 0x3F40))
                                             .ToList();

                            #region ActorEntity Handlers

                            var firstTime = true;

                            var currentMonsterEntries = MonsterWorkerDelegate.NPCEntities.Keys.ToDictionary(key => key);
                            var currentNPCEntries     = NPCWorkerDelegate.NPCEntities.Keys.ToDictionary(key => key);
                            var currentPCEntries      = PCWorkerDelegate.NPCEntities.Keys.ToDictionary(key => key);

                            var newMonsterEntries = new List <UInt32>();
                            var newNPCEntries     = new List <UInt32>();
                            var newPCEntries      = new List <UInt32>();

                            for (var i = 0; i < sourceData.Count; i++)
                            {
                                try
                                {
                                    var source = sourceData[i];
                                    //var source = MemoryHandler.Instance.GetByteArray(characterAddress, 0x3F40);

                                    UInt32     ID;
                                    UInt32     NPCID2;
                                    Actor.Type Type;

                                    switch (Settings.Default.GameLanguage)
                                    {
                                    case "Chinese":
                                        ID     = BitConverter.ToUInt32(source, 0x74);
                                        NPCID2 = BitConverter.ToUInt32(source, 0x80);
                                        Type   = (Actor.Type)source[0x8A];
                                        break;

                                    default:
                                        ID     = BitConverter.ToUInt32(source, 0x74);
                                        NPCID2 = BitConverter.ToUInt32(source, 0x80);
                                        Type   = (Actor.Type)source[0x8A];
                                        break;
                                    }

                                    ActorEntity existing = null;

                                    switch (Type)
                                    {
                                    case Actor.Type.Monster:
                                        if (currentMonsterEntries.ContainsKey(ID))
                                        {
                                            currentMonsterEntries.Remove(ID);
                                            existing = MonsterWorkerDelegate.GetNPCEntity(ID);
                                        }
                                        else
                                        {
                                            newMonsterEntries.Add(ID);
                                        }
                                        break;

                                    case Actor.Type.PC:
                                        if (currentPCEntries.ContainsKey(ID))
                                        {
                                            currentPCEntries.Remove(ID);
                                            existing = PCWorkerDelegate.GetNPCEntity(ID);
                                        }
                                        else
                                        {
                                            newPCEntries.Add(ID);
                                        }
                                        break;

                                    case Actor.Type.NPC:
                                        if (currentNPCEntries.ContainsKey(NPCID2))
                                        {
                                            currentNPCEntries.Remove(NPCID2);
                                            existing = NPCWorkerDelegate.GetNPCEntity(NPCID2);
                                        }
                                        else
                                        {
                                            newNPCEntries.Add(NPCID2);
                                        }
                                        break;

                                    default:
                                        if (currentNPCEntries.ContainsKey(ID))
                                        {
                                            currentNPCEntries.Remove(ID);
                                            existing = NPCWorkerDelegate.GetNPCEntity(ID);
                                        }
                                        else
                                        {
                                            newNPCEntries.Add(ID);
                                        }
                                        break;
                                    }

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

                                    firstTime = false;

                                    //var actor = MemoryHandler.Instance.GetStructureFromBytes<Structures.NPCEntry>(source);
                                    //var actor = MemoryHandler.Instance.GetStructure<Structures.NPCEntry>(characterAddress);
                                    //var name = MemoryHandler.Instance.GetString(characterAddress, 48);
                                    //var entry = ActorEntityHelper.ResolveActorFromMemory(actor, name);
                                    entry.MapIndex = mapIndex;
                                    if (i == 0)
                                    {
                                        var name = Settings.Default.CharacterName;
                                        if (name != entry.Name || String.IsNullOrWhiteSpace(name))
                                        {
                                            Settings.Default.CharacterName = entry.Name;
                                        }
                                        if (targetAddress > 0)
                                        {
                                            uint currentTargetID;
                                            var  targetInfoSource = MemoryHandler.Instance.GetByteArray(targetAddress, 128);
                                            switch (Settings.Default.GameLanguage)
                                            {
                                            case "Chinese":
                                                currentTargetID = BitConverter.ToUInt32(targetInfoSource, 0x68);
                                                break;

                                            default:
                                                currentTargetID = BitConverter.ToUInt32(targetInfoSource, 0x68);
                                                break;
                                            }
                                            entry.TargetID = (int)currentTargetID;
                                        }
                                    }
                                    if (!entry.IsValid)
                                    {
                                        newMonsterEntries.Remove(entry.ID);
                                        newMonsterEntries.Remove(entry.NPCID2);
                                        newNPCEntries.Remove(entry.ID);
                                        newNPCEntries.Remove(entry.NPCID2);
                                        newPCEntries.Remove(entry.ID);
                                        newPCEntries.Remove(entry.NPCID2);
                                        continue;
                                    }
                                    if (existing != null)
                                    {
                                        continue;
                                    }
                                    switch (entry.Type)
                                    {
                                    case Actor.Type.Monster:
                                        MonsterWorkerDelegate.EnsureNPCEntity(entry.ID, entry);
                                        break;

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

                                    case Actor.Type.NPC:
                                        NPCWorkerDelegate.EnsureNPCEntity(entry.NPCID2, entry);
                                        break;

                                    default:
                                        NPCWorkerDelegate.EnsureNPCEntity(entry.ID, entry);
                                        break;
                                    }
                                }
                                catch (Exception ex)
                                {
                                }
                            }

                            if (!ReferencesSet)
                            {
                                ReferencesSet = true;
                                AppContextHelper.Instance.RaiseNewMonsterEntries(MonsterWorkerDelegate.NPCEntities);
                                AppContextHelper.Instance.RaiseNewNPCEntries(NPCWorkerDelegate.NPCEntities);
                                AppContextHelper.Instance.RaiseNewPCEntries(PCWorkerDelegate.NPCEntities);
                            }

                            if (newMonsterEntries.Any())
                            {
                                AppContextHelper.Instance.RaiseNewMonsterAddedEntries(newMonsterEntries);
                            }
                            if (newNPCEntries.Any())
                            {
                                AppContextHelper.Instance.RaiseNewNPCAddedEntries(newNPCEntries);
                            }
                            if (newPCEntries.Any())
                            {
                                AppContextHelper.Instance.RaiseNewPCAddedEntries(newPCEntries);
                            }

                            if (currentMonsterEntries.Any())
                            {
                                AppContextHelper.Instance.RaiseNewMonsterRemovedEntries(currentMonsterEntries.Keys.ToList());
                                foreach (var key in currentMonsterEntries.Keys)
                                {
                                    MonsterWorkerDelegate.RemoveNPCEntity(key);
                                }
                            }
                            if (currentNPCEntries.Any())
                            {
                                AppContextHelper.Instance.RaiseNewNPCRemovedEntries(currentNPCEntries.Keys.ToList());
                                foreach (var key in currentNPCEntries.Keys)
                                {
                                    NPCWorkerDelegate.RemoveNPCEntity(key);
                                }
                            }
                            if (currentPCEntries.Any())
                            {
                                AppContextHelper.Instance.RaiseNewPCRemovedEntries(currentPCEntries.Keys.ToList());
                                foreach (var key in currentPCEntries.Keys)
                                {
                                    PCWorkerDelegate.RemoveNPCEntity(key);
                                }
                            }

                            #endregion
                        }
                        catch (Exception ex)
                        {
                        }
                    }
                }
                _isScanning = false;
                return(true);
            };

            scannerWorker.BeginInvoke(delegate { }, scannerWorker);
        }