/// <summary> /// </summary> /// <param name="sender"> </param> /// <param name="e"> </param> private void ScanTimerElapsed(object sender, ElapsedEventArgs e) { if (_isScanning) { return; } _isScanning = true; double refresh = 1000; if (Double.TryParse(Settings.Default.PartyInfoWorkerRefresh.ToString(CultureInfo.InvariantCulture), out refresh)) { _scanTimer.Interval = refresh; } Func <bool> scannerWorker = delegate { if (MemoryHandler.Instance.SigScanner.Locations.ContainsKey("CHARMAP")) { if (MemoryHandler.Instance.SigScanner.Locations.ContainsKey("PARTYMAP")) { if (MemoryHandler.Instance.SigScanner.Locations.ContainsKey("PARTYCOUNT")) { PartyInfoMap = MemoryHandler.Instance.SigScanner.Locations["PARTYMAP"]; PartyCountMap = MemoryHandler.Instance.SigScanner.Locations["PARTYCOUNT"]; try { var partyCount = MemoryHandler.Instance.GetByte(PartyCountMap); var currentPartyEntries = PartyInfoWorkerDelegate.NPCEntities.Keys.ToDictionary(key => key); var newPartyEntries = new List <UInt32>(); if (partyCount > 1 && partyCount < 9) { for (uint i = 0; i < partyCount; i++) { UInt32 ID; uint size; switch (Settings.Default.GameLanguage) { case "Chinese": size = 594; break; default: size = 544; break; } var address = PartyInfoMap + (i * size); var source = MemoryHandler.Instance.GetByteArray(address, (int)size); switch (Settings.Default.GameLanguage) { case "Chinese": ID = BitConverter.ToUInt32(source, 0x10); break; default: ID = BitConverter.ToUInt32(source, 0x10); break; } ActorEntity existing = null; if (currentPartyEntries.ContainsKey(ID)) { currentPartyEntries.Remove(ID); if (MonsterWorkerDelegate.NPCEntities.ContainsKey(ID)) { existing = MonsterWorkerDelegate.GetNPCEntity(ID); } if (PCWorkerDelegate.NPCEntities.ContainsKey(ID)) { existing = PCWorkerDelegate.GetNPCEntity(ID); } } else { newPartyEntries.Add(ID); } var entry = PartyEntityHelper.ResolvePartyMemberFromBytes(source, existing); if (!entry.IsValid) { continue; } if (existing != null) { continue; } PartyInfoWorkerDelegate.EnsureNPCEntity(entry.ID, entry); } } else if (partyCount == 0 || partyCount == 1) { var entry = PartyEntityHelper.ResolvePartyMemberFromBytes(new byte[0], PCWorkerDelegate.CurrentUser); if (entry.IsValid) { var exists = false; if (currentPartyEntries.ContainsKey(entry.ID)) { currentPartyEntries.Remove(entry.ID); exists = true; } else { newPartyEntries.Add(entry.ID); } if (!exists) { PartyInfoWorkerDelegate.EnsureNPCEntity(entry.ID, entry); } } } if (!ReferencesSet) { ReferencesSet = true; AppContextHelper.Instance.RaiseNewPartyEntries(PartyInfoWorkerDelegate.NPCEntities); } if (newPartyEntries.Any()) { AppContextHelper.Instance.RaiseNewPartyAddedEntries(newPartyEntries); } if (currentPartyEntries.Any()) { AppContextHelper.Instance.RaiseNewPartyRemovedEntries(currentPartyEntries.Keys.ToList()); foreach (var key in currentPartyEntries.Keys) { PartyInfoWorkerDelegate.RemoveNPCEntity(key); } } } catch (Exception ex) { } } } } _isScanning = false; return(true); }; scannerWorker.BeginInvoke(delegate { }, scannerWorker); }
public static PartyInfoReadResult GetPartyMembers() { var result = new PartyInfoReadResult(); if (!Scanner.Instance.Locations.ContainsKey("CHARMAP")) { return(result); } if (!Scanner.Instance.Locations.ContainsKey("PARTYMAP")) { return(result); } if (!Scanner.Instance.Locations.ContainsKey("PARTYCOUNT")) { return(result); } PartyInfoMap = Scanner.Instance.Locations["PARTYMAP"]; PartyCountMap = Scanner.Instance.Locations["PARTYCOUNT"]; try { var partyCount = MemoryHandler.Instance.GetByte(PartyCountMap); if (partyCount > 1 && partyCount < 9) { for (uint i = 0; i < partyCount; i++) { var size = (uint)MemoryHandler.Instance.Structures.PartyInfo.Size; var address = PartyInfoMap.ToInt64() + i * size; var source = MemoryHandler.Instance.GetByteArray(new IntPtr(address), (int)size); var ID = BitConverter.TryToUInt32(source, MemoryHandler.Instance.Structures.PartyEntity.ID); ActorEntity existing = null; if (result.RemovedParty.ContainsKey(ID)) { result.RemovedParty.Remove(ID); if (MonsterWorkerDelegate.EntitiesDictionary.ContainsKey(ID)) { existing = MonsterWorkerDelegate.GetEntity(ID); } if (PCWorkerDelegate.EntitiesDictionary.ContainsKey(ID)) { existing = PCWorkerDelegate.GetEntity(ID); } } else { result.NewParty.Add(ID); } var entry = PartyEntityHelper.ResolvePartyMemberFromBytes(source, existing); if (!entry.IsValid) { continue; } if (existing != null) { continue; } PartyInfoWorkerDelegate.EnsureEntity(entry.ID, entry); } } else if (partyCount == 0 || partyCount == 1) { var entry = PartyEntityHelper.ResolvePartyMemberFromBytes(new byte[0], PCWorkerDelegate.CurrentUser); if (entry.IsValid) { var exists = false; if (result.RemovedParty.ContainsKey(entry.ID)) { result.RemovedParty.Remove(entry.ID); exists = true; } else { result.NewParty.Add(entry.ID); } if (!exists) { PartyInfoWorkerDelegate.EnsureEntity(entry.ID, entry); } } } } catch (Exception ex) { MemoryHandler.Instance.RaiseException(Logger, ex, true); } try { // REMOVE OLD PARTY MEMBERS FROM LIVE CURRENT DICTIONARY foreach (var kvp in result.RemovedParty) { PartyInfoWorkerDelegate.RemoveEntity(kvp.Key); } } catch (Exception ex) { MemoryHandler.Instance.RaiseException(Logger, ex, true); } return(result); }