/// <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); }