public static PartyMember ResolvePartyMemberFromBytes(byte[] source, ActorItem actorItem = null) { if (actorItem != null) { var entry = new PartyMember { X = actorItem.X, Y = actorItem.Y, Z = actorItem.Z, Coordinate = actorItem.Coordinate, ID = actorItem.ID, UUID = actorItem.UUID, Name = actorItem.Name, Job = actorItem.Job, Level = actorItem.Level, HPCurrent = actorItem.HPCurrent, HPMax = actorItem.HPMax, MPCurrent = actorItem.MPCurrent, MPMax = actorItem.MPMax, HitBoxRadius = actorItem.HitBoxRadius, }; entry.StatusItems.AddRange(actorItem.StatusItems); CleanXPValue(ref entry); return(entry); } else { var defaultStatusEffectOffset = MemoryHandler.Instance.Structures.PartyMember.DefaultStatusEffectOffset; var entry = new PartyMember(); try { entry.X = BitConverter.TryToSingle(source, MemoryHandler.Instance.Structures.PartyMember.X); entry.Z = BitConverter.TryToSingle(source, MemoryHandler.Instance.Structures.PartyMember.Z); entry.Y = BitConverter.TryToSingle(source, MemoryHandler.Instance.Structures.PartyMember.Y); entry.Coordinate = new Coordinate(entry.X, entry.Z, entry.Z); entry.ID = BitConverter.TryToUInt32(source, MemoryHandler.Instance.Structures.PartyMember.ID); entry.UUID = Guid.NewGuid().ToString(); entry.Name = MemoryHandler.Instance.GetStringFromBytes(source, MemoryHandler.Instance.Structures.PartyMember.Name); entry.JobID = source[MemoryHandler.Instance.Structures.PartyMember.Job]; entry.Job = (Actor.Job)entry.JobID; entry.HitBoxRadius = 0.5f; entry.Level = source[MemoryHandler.Instance.Structures.PartyMember.Level]; entry.HPCurrent = BitConverter.TryToInt32(source, MemoryHandler.Instance.Structures.PartyMember.HPCurrent); entry.HPMax = BitConverter.TryToInt32(source, MemoryHandler.Instance.Structures.PartyMember.HPMax); entry.MPCurrent = BitConverter.TryToInt16(source, MemoryHandler.Instance.Structures.PartyMember.MPCurrent); entry.MPMax = BitConverter.TryToInt16(source, MemoryHandler.Instance.Structures.PartyMember.MPMax); const int limit = 15; int statusSize = MemoryHandler.Instance.Structures.StatusItem.SourceSize; byte[] statusesSource = new byte[limit * statusSize]; List <StatusItem> foundStatuses = new List <StatusItem>(); Buffer.BlockCopy(source, defaultStatusEffectOffset, statusesSource, 0, limit * statusSize); for (var i = 0; i < limit; i++) { bool isNewStatus = false; byte[] statusSource = new byte[statusSize]; Buffer.BlockCopy(statusesSource, i * statusSize, statusSource, 0, statusSize); short StatusID = BitConverter.TryToInt16(statusSource, MemoryHandler.Instance.Structures.StatusItem.StatusID); uint CasterID = BitConverter.TryToUInt32(statusSource, MemoryHandler.Instance.Structures.StatusItem.CasterID); var statusEntry = entry.StatusItems.FirstOrDefault(x => x.CasterID == CasterID && x.StatusID == StatusID); if (statusEntry == null) { statusEntry = new StatusItem(); isNewStatus = true; } statusEntry.TargetEntity = null; statusEntry.TargetName = entry.Name; statusEntry.StatusID = StatusID; statusEntry.Stacks = statusSource[MemoryHandler.Instance.Structures.StatusItem.Stacks]; statusEntry.Duration = BitConverter.TryToSingle(statusSource, MemoryHandler.Instance.Structures.StatusItem.Duration); statusEntry.CasterID = CasterID; foundStatuses.Add(statusEntry); try { ActorItem pc = PCWorkerDelegate.GetActorItem(statusEntry.CasterID); ActorItem npc = NPCWorkerDelegate.GetActorItem(statusEntry.CasterID); ActorItem monster = MonsterWorkerDelegate.GetActorItem(statusEntry.CasterID); statusEntry.SourceEntity = (pc ?? npc) ?? monster; } catch (Exception ex) { MemoryHandler.Instance.RaiseException(Logger, ex, true); } try { if (statusEntry.StatusID > 0) { Models.XIVDatabase.StatusItem statusInfo = StatusEffectLookup.GetStatusInfo((uint)statusEntry.StatusID); statusEntry.IsCompanyAction = statusInfo.CompanyAction; var statusKey = statusInfo.Name.English; switch (MemoryHandler.Instance.GameLanguage) { case "French": statusKey = statusInfo.Name.French; break; case "Japanese": statusKey = statusInfo.Name.Japanese; break; case "German": statusKey = statusInfo.Name.German; break; case "Chinese": statusKey = statusInfo.Name.Chinese; break; case "Korean": statusKey = statusInfo.Name.Korean; break; } statusEntry.StatusName = statusKey; } } catch (Exception) { statusEntry.StatusName = "UNKNOWN"; } if (statusEntry.IsValid()) { if (isNewStatus) { entry.StatusItems.Add(statusEntry); } foundStatuses.Add(statusEntry); } } entry.StatusItems.RemoveAll(x => !foundStatuses.Contains(x)); } catch (Exception ex) { MemoryHandler.Instance.RaiseException(Logger, ex, true); } CleanXPValue(ref entry); return(entry); } }
public LineHistory(Line line) { TimeStamp = DateTime.Now; Line = line; SourceStatusEntries = new List <StatusEntry>(); TargetStatusEntries = new List <StatusEntry>(); uint PlayerID = 0; try { var monsterEntries = MonsterWorkerDelegate.GetNPCEntities(); var pcEntries = PCWorkerDelegate.GetNPCEntities(); // process you => monster foreach (var actorEntity in pcEntries) { if (!String.Equals(actorEntity.Name, line.Source, Constants.InvariantComparer)) { continue; } PlayerID = actorEntity.ID; foreach (var statusEntry in actorEntity.StatusEntries) { SourceStatusEntries.Add(statusEntry); } } foreach (var actorEntity in monsterEntries) { if (!String.Equals(actorEntity.Name, line.Target, Constants.InvariantComparer)) { return; } foreach (var statusEntry in actorEntity.StatusEntries) { if (statusEntry.CasterID == PlayerID) { TargetStatusEntries.Add(statusEntry); } } } // process monster => you foreach (var actorEntity in pcEntries) { if (!String.Equals(actorEntity.Name, line.Target, Constants.InvariantComparer)) { continue; } PlayerID = actorEntity.ID; foreach (var statusEntry in actorEntity.StatusEntries) { TargetStatusEntries.Add(statusEntry); } } foreach (var actorEntity in monsterEntries) { if (!String.Equals(actorEntity.Name, line.Source, Constants.InvariantComparer)) { return; } foreach (var statusEntry in actorEntity.StatusEntries) { if (statusEntry.CasterID == PlayerID) { SourceStatusEntries.Add(statusEntry); } } } } catch (Exception ex) { } }
/// <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); }
private void StatusUpdateTimerOnElapsed(object sender, ElapsedEventArgs elapsedEventArgs) { if (StatusUpdateTimerProcessing) { return; } StatusUpdateTimerProcessing = true; var monsterEntries = MonsterWorkerDelegate.GetNPCEntities(); var pcEntries = PCWorkerDelegate.GetNPCEntities(); StatusEntriesSelf.Clear(); StatusEntriesPlayers.Clear(); StatusEntriesMonsters.Clear(); if (pcEntries.Any()) { try { var cleanedName = Regex.Replace(Name, @"\[[\w]+\]", "") .Trim(); var isYou = Regex.IsMatch(cleanedName, @"^(([Dd](ich|ie|u))|You|Vous)$") || String.Equals(cleanedName, Constants.CharacterName, Constants.InvariantComparer); var isPet = false; try { NPCEntry = isYou ? PCWorkerDelegate.CurrentUser : null; if (!isYou) { try { NPCEntry = pcEntries.First(p => String.Equals(p.Name, cleanedName, Constants.InvariantComparer)); } catch (Exception ex) { isPet = true; } } } catch (Exception ex) { } if (NPCEntry != null) { ID = NPCEntry.ID; if (ID > 0) { StatusEntriesSelf = NPCEntry.StatusEntries; try { foreach (var statusEntry in monsterEntries.ToList() .Where(p => p.HPCurrent > 0) .SelectMany(monster => monster.StatusEntries) .Where(statusEntry => statusEntry.CasterID == ID)) { StatusEntriesMonsters.Add(statusEntry); } } catch (Exception ex) { } try { foreach (var statusEntry in pcEntries.ToList() .Where(p => p.HPCurrent > 0) .SelectMany(pc => pc.StatusEntries) .Where(statusEntry => statusEntry.CasterID == ID)) { StatusEntriesPlayers.Add(statusEntry); } } catch (Exception ex) { } } } } catch (Exception ex) { } } if (!StatusEntriesMonsters.Any() && !StatusEntriesPlayers.Any()) { StatusUpdateTimerProcessing = false; return; } if (StatusEntriesMonsters.Any()) { ProcessDamageOverTime(StatusEntriesMonsters); } if (StatusEntriesPlayers.Any()) { ProcessHealingOverTime(StatusEntriesPlayers); ProcessBuffs(StatusEntriesPlayers); } StatusUpdateTimerProcessing = false; }
/// <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 PartyResult GetPartyMembers() { var result = new PartyResult(); if (!CanGetPartyMembers() || !MemoryHandler.Instance.IsAttached) { return(result); } var PartyInfoMap = (IntPtr)Scanner.Instance.Locations[Signatures.PartyMapKey]; Signature PartyCountMap = Scanner.Instance.Locations[Signatures.PartyCountKey]; foreach (KeyValuePair <uint, PartyMember> kvp in PartyWorkerDelegate.PartyMembers) { result.RemovedPartyMembers.TryAdd(kvp.Key, kvp.Value.Clone()); } try { var partyCount = MemoryHandler.Instance.GetByte(PartyCountMap); var sourceSize = MemoryHandler.Instance.Structures.PartyMember.SourceSize; if (partyCount > 1 && partyCount < 9) { for (uint i = 0; i < partyCount; i++) { var address = PartyInfoMap.ToInt64() + i * (uint)sourceSize; byte[] source = MemoryHandler.Instance.GetByteArray(new IntPtr(address), sourceSize); var ID = BitConverter.TryToUInt32(source, MemoryHandler.Instance.Structures.PartyMember.ID); ActorItem existing = null; var newEntry = false; if (result.RemovedPartyMembers.ContainsKey(ID)) { result.RemovedPartyMembers.TryRemove(ID, out PartyMember removedPartyMember); if (MonsterWorkerDelegate.ActorItems.ContainsKey(ID)) { existing = MonsterWorkerDelegate.GetActorItem(ID); } if (PCWorkerDelegate.ActorItems.ContainsKey(ID)) { existing = PCWorkerDelegate.GetActorItem(ID); } } else { newEntry = true; } PartyMember entry = PartyMemberResolver.ResolvePartyMemberFromBytes(source, existing); if (!entry.IsValid) { continue; } if (existing != null) { continue; } if (newEntry) { PartyWorkerDelegate.EnsurePartyMember(entry.ID, entry); result.NewPartyMembers.TryAdd(entry.ID, entry.Clone()); } } } if (partyCount <= 1) { PartyMember entry = PartyMemberResolver.ResolvePartyMemberFromBytes(Array.Empty <byte>(), PCWorkerDelegate.CurrentUser); if (result.RemovedPartyMembers.ContainsKey(entry.ID)) { result.RemovedPartyMembers.TryRemove(entry.ID, out PartyMember removedPartyMember); } PartyWorkerDelegate.EnsurePartyMember(entry.ID, entry); } } catch (Exception ex) { MemoryHandler.Instance.RaiseException(Logger, ex, true); } try { // REMOVE OLD PARTY MEMBERS FROM LIVE CURRENT DICTIONARY foreach (KeyValuePair <uint, PartyMember> kvp in result.RemovedPartyMembers) { PartyWorkerDelegate.RemovePartyMember(kvp.Key); } } catch (Exception ex) { MemoryHandler.Instance.RaiseException(Logger, ex, true); } return(result); }
public static async Task <ActorResult> GetActors() { var result = new ActorResult(); if (!CanGetActors() || !MemoryHandler.Instance.IsAttached) { return(result); } try { IntPtr targetAddress = IntPtr.Zero; var endianSize = MemoryHandler.Instance.ProcessModel.IsWin64 ? 8 : 4; var sourceSize = MemoryHandler.Instance.Structures.ActorItem.SourceSize; var limit = MemoryHandler.Instance.Structures.ActorItem.EntityCount; byte[] characterAddressMap = MemoryHandler.Instance.GetByteArray(Scanner.Instance.Locations[Signatures.CharacterMapKey], endianSize * limit); Dictionary <IntPtr, IntPtr> uniqueAddresses = new Dictionary <IntPtr, IntPtr>(); IntPtr firstAddress = IntPtr.Zero; DateTime now = DateTime.Now; TimeSpan staleActorRemovalTime = TimeSpan.FromSeconds(0.25); 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; } foreach (KeyValuePair <uint, ActorItem> kvp in MonsterWorkerDelegate.ActorItems) { result.RemovedMonsters.TryAdd(kvp.Key, kvp.Value.Clone()); } foreach (KeyValuePair <uint, ActorItem> kvp in NPCWorkerDelegate.ActorItems) { result.RemovedNPCs.TryAdd(kvp.Key, kvp.Value.Clone()); } foreach (KeyValuePair <uint, ActorItem> kvp in PCWorkerDelegate.ActorItems) { result.RemovedPCs.TryAdd(kvp.Key, kvp.Value.Clone()); } foreach (KeyValuePair <IntPtr, IntPtr> kvp in uniqueAddresses) { try { var characterAddress = new IntPtr(kvp.Value.ToInt64()); byte[] source = MemoryHandler.Instance.GetByteArray(characterAddress, sourceSize); // var source = MemoryHandler.Instance.GetByteArray(characterAddress, 0x3F40); var ID = BitConverter.TryToUInt32(source, MemoryHandler.Instance.Structures.ActorItem.ID); var NPCID2 = BitConverter.TryToUInt32(source, MemoryHandler.Instance.Structures.ActorItem.NPCID2); var Type = (Actor.Type)source[MemoryHandler.Instance.Structures.ActorItem.Type]; ActorItem existing = null; var newEntry = false; switch (Type) { case Actor.Type.Monster: if (result.RemovedMonsters.ContainsKey(ID)) { result.RemovedMonsters.TryRemove(ID, out ActorItem removedMonster); existing = MonsterWorkerDelegate.GetActorItem(ID); } else { newEntry = true; } break; case Actor.Type.PC: if (result.RemovedPCs.ContainsKey(ID)) { result.RemovedPCs.TryRemove(ID, out ActorItem removedPC); existing = PCWorkerDelegate.GetActorItem(ID); } else { newEntry = true; } break; case Actor.Type.NPC: case Actor.Type.Aetheryte: case Actor.Type.EventObject: if (result.RemovedNPCs.ContainsKey(NPCID2)) { result.RemovedNPCs.TryRemove(NPCID2, out ActorItem removedNPC); existing = NPCWorkerDelegate.GetActorItem(NPCID2); } else { newEntry = true; } break; default: if (result.RemovedNPCs.ContainsKey(ID)) { result.RemovedNPCs.TryRemove(ID, out ActorItem removedNPC); existing = NPCWorkerDelegate.GetActorItem(ID); } else { newEntry = true; } break; } var isFirstEntry = kvp.Value.ToInt64() == firstAddress.ToInt64(); ActorItem entry = await ActorItemResolver.ResolveActorFromBytes(source, isFirstEntry, existing); if (entry != null && entry.IsValid) { if (expiringActors.ContainsKey(ID)) { expiringActors.Remove(ID); } } if (entry.Type == Actor.Type.EventObject) { var(EventObjectTypeID, EventObjectType) = GetEventObjectType(targetAddress); entry.EventObjectTypeID = EventObjectTypeID; entry.EventObjectType = EventObjectType; } EnsureMapAndZone(entry); if (isFirstEntry) { if (targetAddress.ToInt64() > 0) { byte[] targetInfoSource = MemoryHandler.Instance.GetByteArray(targetAddress, 128); entry.TargetID = (int)BitConverter.TryToUInt32(targetInfoSource, MemoryHandler.Instance.Structures.ActorItem.ID); } } // it doesn't matter what this is set to; it won't be used in code below ActorItem removed; if (!entry.IsValid) { result.NewMonsters.TryRemove(entry.ID, out removed); result.NewMonsters.TryRemove(entry.NPCID2, out removed); result.NewNPCs.TryRemove(entry.ID, out removed); result.NewNPCs.TryRemove(entry.NPCID2, out removed); result.NewPCs.TryRemove(entry.ID, out removed); result.NewPCs.TryRemove(entry.NPCID2, out removed); continue; } if (existing != null) { continue; } if (newEntry) { switch (entry.Type) { case Actor.Type.Monster: MonsterWorkerDelegate.EnsureActorItem(entry.ID, entry); result.NewMonsters.TryAdd(entry.ID, entry.Clone()); break; case Actor.Type.PC: PCWorkerDelegate.EnsureActorItem(entry.ID, entry); result.NewPCs.TryAdd(entry.ID, entry.Clone()); break; case Actor.Type.Aetheryte: case Actor.Type.EventObject: case Actor.Type.NPC: NPCWorkerDelegate.EnsureActorItem(entry.NPCID2, entry); result.NewNPCs.TryAdd(entry.NPCID2, entry.Clone()); break; default: NPCWorkerDelegate.EnsureActorItem(entry.ID, entry); result.NewNPCs.TryAdd(entry.ID, entry.Clone()); break; } } } catch (Exception ex) { MemoryHandler.Instance.RaiseException(Logger, ex, true); } } try { // add the "removed" actors to the expiring list foreach (KeyValuePair <uint, ActorItem> kvp in result.RemovedMonsters) { if (!expiringActors.ContainsKey(kvp.Key)) { expiringActors[kvp.Key] = now + staleActorRemovalTime; } } foreach (KeyValuePair <uint, ActorItem> kvp in result.RemovedNPCs) { if (!expiringActors.ContainsKey(kvp.Key)) { expiringActors[kvp.Key] = now + staleActorRemovalTime; } } foreach (KeyValuePair <uint, ActorItem> kvp in result.RemovedPCs) { if (!expiringActors.ContainsKey(kvp.Key)) { expiringActors[kvp.Key] = now + staleActorRemovalTime; } } // check expiring list for stale actors foreach (var kvp in expiringActors.ToList()) { if (now > kvp.Value) { // Stale actor. Remove it. MonsterWorkerDelegate.RemoveActorItem(kvp.Key); NPCWorkerDelegate.RemoveActorItem(kvp.Key); PCWorkerDelegate.RemoveActorItem(kvp.Key); expiringActors.Remove(kvp.Key); } else { // Not stale enough yet. We're not actually removing it. result.RemovedMonsters.TryRemove(kvp.Key, out ActorItem _); result.RemovedNPCs.TryRemove(kvp.Key, out ActorItem _); result.RemovedPCs.TryRemove(kvp.Key, out ActorItem _); } } } catch (Exception ex) { MemoryHandler.Instance.RaiseException(Logger, ex, true); } MemoryHandler.Instance.ScanCount++; } catch (Exception ex) { MemoryHandler.Instance.RaiseException(Logger, ex, true); } return(result); }
public static TargetReadResult GetTargetInfo() { var result = new TargetReadResult(); if (!Scanner.Instance.Locations.ContainsKey("CHARMAP")) { return(result); } try { var enmityEntries = new List <EnmityEntry>(); var agroPointersFound = Scanner.Instance.Locations.ContainsKey("AGROMAP") && Scanner.Instance.Locations.ContainsKey("AGRO_COUNT"); if (!Scanner.Instance.Locations.ContainsKey("TARGET")) { return(result); } var targetAddress = (IntPtr)Scanner.Instance.Locations["TARGET"]; if (targetAddress.ToInt64() > 0) { var targetInfoSource = MemoryHandler.Instance.GetByteArray(targetAddress, MemoryHandler.Instance.Structures.TargetInfo.SourceSize); var currentTarget = MemoryHandler.Instance.GetPlatformIntFromBytes(targetInfoSource, MemoryHandler.Instance.Structures.TargetInfo.Current); var mouseOverTarget = MemoryHandler.Instance.GetPlatformIntFromBytes(targetInfoSource, MemoryHandler.Instance.Structures.TargetInfo.MouseOver); var focusTarget = MemoryHandler.Instance.GetPlatformIntFromBytes(targetInfoSource, MemoryHandler.Instance.Structures.TargetInfo.Focus); var previousTarget = MemoryHandler.Instance.GetPlatformIntFromBytes(targetInfoSource, MemoryHandler.Instance.Structures.TargetInfo.Previous); var currentTargetID = BitConverter.TryToUInt32(targetInfoSource, MemoryHandler.Instance.Structures.TargetInfo.CurrentID); if (currentTarget > 0) { try { var entry = GetTargetActorEntityFromSource(currentTarget); currentTargetID = entry.ID; if (entry.IsValid) { result.TargetsFound = true; result.TargetEntity.CurrentTarget = entry; } } catch (Exception ex) { MemoryHandler.Instance.RaiseException(Logger, ex, true); } } if (mouseOverTarget > 0) { try { var entry = GetTargetActorEntityFromSource(mouseOverTarget); if (entry.IsValid) { result.TargetsFound = true; result.TargetEntity.MouseOverTarget = entry; } } catch (Exception ex) { MemoryHandler.Instance.RaiseException(Logger, ex, true); } } if (focusTarget > 0) { try { var entry = GetTargetActorEntityFromSource(focusTarget); if (entry.IsValid) { result.TargetsFound = true; result.TargetEntity.FocusTarget = entry; } } catch (Exception ex) { MemoryHandler.Instance.RaiseException(Logger, ex, true); } } if (previousTarget > 0) { try { var entry = GetTargetActorEntityFromSource(previousTarget); if (entry.IsValid) { result.TargetsFound = true; result.TargetEntity.PreviousTarget = entry; } } catch (Exception ex) { MemoryHandler.Instance.RaiseException(Logger, ex, true); } } if (currentTargetID > 0) { result.TargetsFound = true; result.TargetEntity.CurrentTargetID = currentTargetID; } } if (result.TargetEntity.CurrentTargetID > 0) { if (agroPointersFound) { var agroCount = MemoryHandler.Instance.GetInt16(Scanner.Instance.Locations["ENMITY_COUNT"]); if (agroCount > 0) { var agroStructure = (IntPtr)Scanner.Instance.Locations["ENMITYMAP"]; for (uint i = 0; i < 16; i++) { try { var address = new IntPtr(agroStructure.ToInt64() + i * 72); var enmityEntry = new EnmityEntry { ID = (uint)MemoryHandler.Instance.GetPlatformInt(address, MemoryHandler.Instance.Structures.EnmityEntry.ID), Name = MemoryHandler.Instance.GetString(address + MemoryHandler.Instance.Structures.EnmityEntry.Name), Enmity = MemoryHandler.Instance.GetUInt32(address + MemoryHandler.Instance.Structures.EnmityEntry.Enmity) }; if (enmityEntry.ID <= 0) { continue; } if (string.IsNullOrWhiteSpace(enmityEntry.Name)) { var pc = PCWorkerDelegate.GetEntity(enmityEntry.ID); var npc = NPCWorkerDelegate.GetEntity(enmityEntry.ID); var monster = MonsterWorkerDelegate.GetEntity(enmityEntry.ID); try { enmityEntry.Name = (pc ?? npc).Name ?? monster.Name; } catch (Exception ex) { MemoryHandler.Instance.RaiseException(Logger, ex, true); } } enmityEntries.Add(enmityEntry); } catch (Exception ex) { MemoryHandler.Instance.RaiseException(Logger, ex, true); } } } } } result.TargetEntity.EnmityEntries = enmityEntries; } catch (Exception ex) { MemoryHandler.Instance.RaiseException(Logger, ex, true); } return(result); }
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); }
public static ActorEntity ResolveActorFromBytes(byte[] source, bool isCurrentUser = false, ActorEntity entry = null) { entry = entry ?? new ActorEntity(); try { uint targetID; uint pcTargetID; entry.MapIndex = 0; entry.TargetID = 0; switch (Settings.Default.GameLanguage) { case "Chinese": entry.Name = MemoryHandler.Instance.GetStringFromBytes(source, 48); entry.ID = BitConverter.ToUInt32(source, 0x74); entry.NPCID1 = BitConverter.ToUInt32(source, 0x78); entry.NPCID2 = BitConverter.ToUInt32(source, 0x80); entry.OwnerID = BitConverter.ToUInt32(source, 0x84); entry.Type = (Actor.Type)source[0x8A]; entry.TargetType = (Actor.TargetType)source[0x8C]; entry.GatheringStatus = source[0x8E]; entry.Distance = source[0x8F]; entry.X = BitConverter.ToSingle(source, 0xA0); entry.Z = BitConverter.ToSingle(source, 0xA4); entry.Y = BitConverter.ToSingle(source, 0xA8); entry.Heading = BitConverter.ToSingle(source, 0xB0); entry.Fate = BitConverter.ToUInt32(source, 0xE4); // ?? entry.GatheringInvisible = source[0x11C]; // ?? entry.ModelID = BitConverter.ToUInt32(source, 0x174); entry.ActionStatus = (Actor.ActionStatus)source[0x17C]; entry.IsGM = BitConverter.ToBoolean(source, 0x183); // ? entry.Icon = (Actor.Icon)source[0x18C]; entry.Status = (Actor.Status)source[0x18E]; entry.ClaimedByID = BitConverter.ToUInt32(source, 0x1A0); targetID = BitConverter.ToUInt32(source, 0x1A8); pcTargetID = BitConverter.ToUInt32(source, 0xAA8); entry.Job = (Actor.Job)source[0x17C0]; entry.Level = source[0x17C1]; entry.GrandCompany = source[0x17C3]; entry.GrandCompanyRank = source[0x17C4]; entry.Title = source[0x17C6]; entry.HPCurrent = BitConverter.ToInt32(source, 0x17C8); entry.HPMax = BitConverter.ToInt32(source, 0x17CC); entry.MPCurrent = BitConverter.ToInt32(source, 0x17D0); entry.MPMax = BitConverter.ToInt32(source, 0x17D4); entry.TPCurrent = BitConverter.ToInt16(source, 0x17D8); entry.TPMax = 1000; entry.GPCurrent = BitConverter.ToInt16(source, 0x17DA); entry.GPMax = BitConverter.ToInt16(source, 0x17DC); entry.CPCurrent = BitConverter.ToInt16(source, 0x17DE); entry.CPMax = BitConverter.ToInt16(source, 0x17E0); entry.Race = source[0x2E58]; // ?? entry.Sex = (Actor.Sex)source[0x2E59]; //? entry.IsCasting = BitConverter.ToBoolean(source, 0x32E0); entry.CastingID = BitConverter.ToInt16(source, 0x32E4); entry.CastingTargetID = BitConverter.ToUInt32(source, 0x32F0); entry.CastingProgress = BitConverter.ToSingle(source, 0x3314); entry.CastingTime = BitConverter.ToSingle(source, 0x33F8); entry.Coordinate = new Coordinate(entry.X, entry.Z, entry.Y); break; default: entry.Name = MemoryHandler.Instance.GetStringFromBytes(source, 48); entry.ID = BitConverter.ToUInt32(source, 0x74); entry.NPCID1 = BitConverter.ToUInt32(source, 0x7C); entry.NPCID2 = BitConverter.ToUInt32(source, 0x80); entry.OwnerID = BitConverter.ToUInt32(source, 0x84); entry.Type = (Actor.Type)source[0x8A]; entry.TargetType = (Actor.TargetType)source[0x8C]; entry.GatheringStatus = source[0x8F]; entry.Distance = source[0x91]; var defaultBaseOffset = MemoryHandler.Instance.ProcessModel.IsWin64 ? 0x10 : 0; entry.X = BitConverter.ToSingle(source, 0xA0 + defaultBaseOffset); entry.Z = BitConverter.ToSingle(source, 0xA4 + defaultBaseOffset); entry.Y = BitConverter.ToSingle(source, 0xA8 + defaultBaseOffset); entry.Heading = BitConverter.ToSingle(source, 0xB0 + defaultBaseOffset); entry.HitBoxRadius = BitConverter.ToSingle(source, 0xC0 + defaultBaseOffset); entry.Fate = BitConverter.ToUInt32(source, 0xE4 + defaultBaseOffset); // ?? entry.GatheringInvisible = source[0x11C]; // ?? entry.ModelID = BitConverter.ToUInt32(source, 0x174); entry.ActionStatus = (Actor.ActionStatus)source[0x17C]; // 0x17D - 0 = Green name, 4 = non-agro (yellow name) entry.IsGM = BitConverter.ToBoolean(source, 0x183); // ? entry.Icon = (Actor.Icon)source[0x18C]; entry.Status = (Actor.Status)source[0x17E]; //0x18E]; entry.ClaimedByID = BitConverter.ToUInt32(source, 0x180); // 0x1A0); targetID = BitConverter.ToUInt32(source, 0x188); // 0x1A8); pcTargetID = BitConverter.ToUInt32(source, 0x938); // 0xAA8); var defaultStatOffset = MemoryHandler.Instance.ProcessModel.IsWin64 ? 0x230 : 0; entry.Job = (Actor.Job)source[0x14C0 + defaultStatOffset]; // 0x17C0]; entry.Level = source[0x14C1 + defaultStatOffset]; // 0x17C1]; entry.GrandCompany = source[0x14C3 + defaultStatOffset]; // 0x17C3]; entry.GrandCompanyRank = source[0x14C4 + defaultStatOffset]; //0x17C4]; entry.Title = source[0x1546 + defaultStatOffset]; //0x17C6]; entry.HPCurrent = BitConverter.ToInt32(source, 0x14C8 + defaultStatOffset); // 0x17C8); entry.HPMax = BitConverter.ToInt32(source, 0x14CC + defaultStatOffset); // 0x17CC); entry.MPCurrent = BitConverter.ToInt32(source, 0x14D0 + defaultStatOffset); // 0x17D0); entry.MPMax = BitConverter.ToInt32(source, 0x14D4 + defaultStatOffset); // 0x17D4); entry.TPCurrent = BitConverter.ToInt16(source, 0x14D8 + defaultStatOffset); // 0x17D8); entry.TPMax = 1000; entry.GPCurrent = BitConverter.ToInt16(source, 0x14DA + defaultStatOffset); // 0x17DA); entry.GPMax = BitConverter.ToInt16(source, 0x14DC + defaultStatOffset); // 0x17DC); entry.CPCurrent = BitConverter.ToInt16(source, 0x14DE + defaultStatOffset); // 0x17DE); entry.CPMax = BitConverter.ToInt16(source, 0x14E0 + defaultStatOffset); // 0x17E0); entry.Race = source[0x2808]; // ?? entry.Sex = (Actor.Sex)source[0x2809]; //? entry.IsCasting = BitConverter.ToBoolean(source, 0x2A30); // 0x2C90); entry.CastingID = BitConverter.ToInt16(source, 0x2A34); // 0x2C94); entry.CastingTargetID = BitConverter.ToUInt32(source, 0x2A40); // 0x2CA0); entry.CastingProgress = BitConverter.ToSingle(source, 0x2A64); // 0x2CC4); entry.CastingTime = BitConverter.ToSingle(source, 0x2A68); // 0x2DA8); entry.Coordinate = new Coordinate(entry.X, entry.Z, entry.Y); break; } if (targetID > 0) { entry.TargetID = (int)targetID; } else { if (pcTargetID > 0) { entry.TargetID = (int)pcTargetID; } } if (entry.CastingTargetID == 3758096384) { entry.CastingTargetID = 0; } entry.MapIndex = 0; var limit = 60; switch (entry.Type) { case Actor.Type.PC: limit = 30; break; } entry.StatusEntries = new List <StatusEntry>(); const int statusSize = 12; var statusesSource = new byte[limit * statusSize]; switch (Settings.Default.GameLanguage) { case "Chinese": Buffer.BlockCopy(source, 0x3168, statusesSource, 0, limit * 12); break; default: var defaultStatusEffectOffset = MemoryHandler.Instance.ProcessModel.IsWin64 ? 0x3740 : 0x2878; Buffer.BlockCopy(source, defaultStatusEffectOffset, statusesSource, 0, limit * 12); break; } for (var i = 0; i < limit; i++) { var statusSource = new byte[statusSize]; Buffer.BlockCopy(statusesSource, i * statusSize, statusSource, 0, statusSize); var statusEntry = new StatusEntry { TargetEntity = entry, TargetName = entry.Name, StatusID = BitConverter.ToInt16(statusSource, 0x0), Stacks = statusSource[0x2], Duration = BitConverter.ToSingle(statusSource, 0x4), CasterID = BitConverter.ToUInt32(statusSource, 0x8) }; try { var pc = PCWorkerDelegate.GetNPCEntity(statusEntry.CasterID); var npc = NPCWorkerDelegate.GetNPCEntity(statusEntry.CasterID); var monster = MonsterWorkerDelegate.GetNPCEntity(statusEntry.CasterID); statusEntry.SourceEntity = (pc ?? npc) ?? monster; } catch (Exception ex) { } try { var statusInfo = StatusEffectHelper.StatusInfo(statusEntry.StatusID); statusEntry.IsCompanyAction = statusInfo.CompanyAction; var statusKey = statusInfo.Name.English; switch (Settings.Default.GameLanguage) { case "French": statusKey = statusInfo.Name.French; break; case "Japanese": statusKey = statusInfo.Name.Japanese; break; case "German": statusKey = statusInfo.Name.German; break; case "Chinese": statusKey = statusInfo.Name.Chinese; break; } statusEntry.StatusName = statusKey; } catch (Exception ex) { statusEntry.StatusName = "UNKNOWN"; } if (statusEntry.IsValid()) { entry.StatusEntries.Add(statusEntry); } } } catch (Exception ex) { } CleanXPValue(ref entry); if (isCurrentUser) { PCWorkerDelegate.CurrentUser = entry; } entry.CurrentUser = PCWorkerDelegate.CurrentUser; return(entry); }
public static ActorItem ResolveActorFromBytes(byte[] source, bool isCurrentUser = false, ActorItem entry = null) { entry = entry ?? new ActorItem(); var defaultBaseOffset = MemoryHandler.Instance.Structures.ActorItem.DefaultBaseOffset; var defaultStatOffset = MemoryHandler.Instance.Structures.ActorItem.DefaultStatOffset; var defaultStatusEffectOffset = MemoryHandler.Instance.Structures.ActorItem.DefaultStatusEffectOffset; try { entry.MapTerritory = 0; entry.MapIndex = 0; entry.MapID = 0; entry.TargetID = 0; entry.Name = MemoryHandler.Instance.GetStringFromBytes(source, MemoryHandler.Instance.Structures.ActorItem.Name); entry.ID = BitConverter.TryToUInt32(source, MemoryHandler.Instance.Structures.ActorItem.ID); entry.UUID = string.IsNullOrEmpty(entry.UUID) ? Guid.NewGuid().ToString() : entry.UUID; entry.NPCID1 = BitConverter.TryToUInt32(source, MemoryHandler.Instance.Structures.ActorItem.NPCID1); entry.NPCID2 = BitConverter.TryToUInt32(source, MemoryHandler.Instance.Structures.ActorItem.NPCID2); entry.OwnerID = BitConverter.TryToUInt32(source, MemoryHandler.Instance.Structures.ActorItem.OwnerID); entry.TypeID = source[MemoryHandler.Instance.Structures.ActorItem.Type]; entry.Type = (Actor.Type)entry.TypeID; entry.TargetTypeID = source[MemoryHandler.Instance.Structures.ActorItem.TargetType]; entry.TargetType = (Actor.TargetType)entry.TargetTypeID; entry.GatheringStatus = source[MemoryHandler.Instance.Structures.ActorItem.GatheringStatus]; entry.Distance = source[MemoryHandler.Instance.Structures.ActorItem.Distance]; entry.X = BitConverter.TryToSingle(source, MemoryHandler.Instance.Structures.ActorItem.X + defaultBaseOffset); entry.Z = BitConverter.TryToSingle(source, MemoryHandler.Instance.Structures.ActorItem.Z + defaultBaseOffset); entry.Y = BitConverter.TryToSingle(source, MemoryHandler.Instance.Structures.ActorItem.Y + defaultBaseOffset); entry.Heading = BitConverter.TryToSingle(source, MemoryHandler.Instance.Structures.ActorItem.Heading + defaultBaseOffset); entry.HitBoxRadius = BitConverter.TryToSingle(source, MemoryHandler.Instance.Structures.ActorItem.HitBoxRadius + defaultBaseOffset); entry.Fate = BitConverter.TryToUInt32(source, MemoryHandler.Instance.Structures.ActorItem.Fate + defaultBaseOffset); // ?? entry.TargetFlags = source[MemoryHandler.Instance.Structures.ActorItem.TargetFlags]; // ?? entry.GatheringInvisible = source[MemoryHandler.Instance.Structures.ActorItem.GatheringInvisible]; // ?? entry.ModelID = BitConverter.TryToUInt32(source, MemoryHandler.Instance.Structures.ActorItem.ModelID); entry.ActionStatusID = source[MemoryHandler.Instance.Structures.ActorItem.ActionStatus]; entry.ActionStatus = (Actor.ActionStatus)entry.ActionStatusID; // 0x17D - 0 = Green name, 4 = non-agro (yellow name) entry.IsGM = BitConverter.TryToBoolean(source, MemoryHandler.Instance.Structures.ActorItem.IsGM); // ? entry.IconID = source[MemoryHandler.Instance.Structures.ActorItem.Icon]; entry.Icon = (Actor.Icon)entry.IconID; entry.StatusID = source[MemoryHandler.Instance.Structures.ActorItem.Status]; entry.Status = (Actor.Status)entry.StatusID; entry.ClaimedByID = BitConverter.TryToUInt32(source, MemoryHandler.Instance.Structures.ActorItem.ClaimedByID); var targetID = BitConverter.TryToUInt32(source, MemoryHandler.Instance.Structures.ActorItem.TargetID); var pcTargetID = targetID; entry.JobID = source[MemoryHandler.Instance.Structures.ActorItem.Job + defaultStatOffset]; entry.Job = (Actor.Job)entry.JobID; entry.Level = source[MemoryHandler.Instance.Structures.ActorItem.Level + defaultStatOffset]; entry.GrandCompany = source[MemoryHandler.Instance.Structures.ActorItem.GrandCompany + defaultStatOffset]; entry.GrandCompanyRank = source[MemoryHandler.Instance.Structures.ActorItem.GrandCompanyRank + defaultStatOffset]; entry.Title = source[MemoryHandler.Instance.Structures.ActorItem.Title + defaultStatOffset]; entry.HPCurrent = BitConverter.TryToInt32(source, MemoryHandler.Instance.Structures.ActorItem.HPCurrent + defaultStatOffset); entry.HPMax = BitConverter.TryToInt32(source, MemoryHandler.Instance.Structures.ActorItem.HPMax + defaultStatOffset); entry.MPCurrent = BitConverter.TryToInt32(source, MemoryHandler.Instance.Structures.ActorItem.MPCurrent + defaultStatOffset); entry.MPMax = 10000; entry.TPCurrent = BitConverter.TryToInt16(source, MemoryHandler.Instance.Structures.ActorItem.TPCurrent + defaultStatOffset); entry.TPMax = 1000; entry.GPCurrent = BitConverter.TryToInt16(source, MemoryHandler.Instance.Structures.ActorItem.GPCurrent + defaultStatOffset); entry.GPMax = BitConverter.TryToInt16(source, MemoryHandler.Instance.Structures.ActorItem.GPMax + defaultStatOffset); entry.CPCurrent = BitConverter.TryToInt16(source, MemoryHandler.Instance.Structures.ActorItem.CPCurrent + defaultStatOffset); entry.CPMax = BitConverter.TryToInt16(source, MemoryHandler.Instance.Structures.ActorItem.CPMax + defaultStatOffset); // entry.Race = source[0x2578]; // ?? // entry.Sex = (Actor.Sex) source[0x2579]; //? entry.AgroFlags = source[MemoryHandler.Instance.Structures.ActorItem.AgroFlags]; entry.CombatFlags = source[MemoryHandler.Instance.Structures.ActorItem.CombatFlags]; entry.DifficultyRank = source[MemoryHandler.Instance.Structures.ActorItem.DifficultyRank]; entry.CastingID = BitConverter.TryToInt16(source, MemoryHandler.Instance.Structures.ActorItem.CastingID); // 0x2C94); entry.CastingTargetID = BitConverter.TryToUInt32(source, MemoryHandler.Instance.Structures.ActorItem.CastingTargetID); // 0x2CA0); entry.CastingProgress = BitConverter.TryToSingle(source, MemoryHandler.Instance.Structures.ActorItem.CastingProgress); // 0x2CC4); entry.CastingTime = BitConverter.TryToSingle(source, MemoryHandler.Instance.Structures.ActorItem.CastingTime); // 0x2DA8); entry.Coordinate = new Coordinate(entry.X, entry.Z, entry.Y); if (targetID > 0) { entry.TargetID = (int)targetID; } else { if (pcTargetID > 0) { entry.TargetID = (int)pcTargetID; } } if (entry.CastingTargetID == 3758096384) { entry.CastingTargetID = 0; } entry.MapIndex = 0; var limit = 60; switch (entry.Type) { case Actor.Type.PC: limit = 30; break; } int statusSize = MemoryHandler.Instance.Structures.StatusItem.SourceSize; byte[] statusesSource = new byte[limit * statusSize]; List <StatusItem> foundStatuses = new List <StatusItem>(); Buffer.BlockCopy(source, defaultStatusEffectOffset, statusesSource, 0, limit * statusSize); for (var i = 0; i < limit; i++) { bool isNewStatus = false; byte[] statusSource = new byte[statusSize]; Buffer.BlockCopy(statusesSource, i * statusSize, statusSource, 0, statusSize); short StatusID = BitConverter.TryToInt16(statusSource, MemoryHandler.Instance.Structures.StatusItem.StatusID); uint CasterID = BitConverter.TryToUInt32(statusSource, MemoryHandler.Instance.Structures.StatusItem.CasterID); var statusEntry = entry.StatusItems.FirstOrDefault(x => x.CasterID == CasterID && x.StatusID == StatusID); if (statusEntry == null) { statusEntry = new StatusItem(); isNewStatus = true; } statusEntry.TargetEntity = entry; statusEntry.TargetName = entry.Name; statusEntry.StatusID = StatusID; statusEntry.Stacks = statusSource[MemoryHandler.Instance.Structures.StatusItem.Stacks]; statusEntry.Duration = BitConverter.TryToSingle(statusSource, MemoryHandler.Instance.Structures.StatusItem.Duration); statusEntry.CasterID = CasterID; try { ActorItem pc = PCWorkerDelegate.GetActorItem(statusEntry.CasterID); ActorItem npc = NPCWorkerDelegate.GetActorItem(statusEntry.CasterID); ActorItem monster = MonsterWorkerDelegate.GetActorItem(statusEntry.CasterID); statusEntry.SourceEntity = (pc ?? npc) ?? monster; } catch (Exception ex) { MemoryHandler.Instance.RaiseException(Logger, ex, true); } try { Models.XIVDatabase.StatusItem statusInfo = StatusEffectLookup.GetStatusInfo((uint)statusEntry.StatusID); if (statusInfo != null) { statusEntry.IsCompanyAction = statusInfo.CompanyAction; var statusKey = statusInfo.Name.English; switch (MemoryHandler.Instance.GameLanguage) { case "French": statusKey = statusInfo.Name.French; break; case "Japanese": statusKey = statusInfo.Name.Japanese; break; case "German": statusKey = statusInfo.Name.German; break; case "Chinese": statusKey = statusInfo.Name.Chinese; break; case "Korean": statusKey = statusInfo.Name.Korean; break; } statusEntry.StatusName = statusKey; } } catch (Exception) { statusEntry.StatusName = "UNKNOWN"; } if (statusEntry.IsValid()) { if (isNewStatus) { entry.StatusItems.Add(statusEntry); } foundStatuses.Add(statusEntry); } } entry.StatusItems.RemoveAll(x => !foundStatuses.Contains(x)); // handle empty names if (string.IsNullOrEmpty(entry.Name)) { if (entry.Type == Actor.Type.EventObject) { entry.Name = $"{nameof(entry.EventObjectTypeID)}: {entry.EventObjectTypeID}"; } else { entry.Name = $"{nameof(entry.TypeID)}: {entry.TypeID}"; } } } catch (Exception ex) { MemoryHandler.Instance.RaiseException(Logger, ex, true); } CleanXPValue(ref entry); if (isCurrentUser) { PCWorkerDelegate.CurrentUser = entry; } return(entry); }
public static PartyEntity ResolvePartyMemberFromBytes(byte[] source, ActorEntity actorEntity = null) { if (actorEntity != null) { var entry = new PartyEntity { X = actorEntity.X, Y = actorEntity.Y, Z = actorEntity.Z, Coordinate = actorEntity.Coordinate, ID = actorEntity.ID, UUID = actorEntity.UUID, Name = actorEntity.Name, Job = actorEntity.Job, Level = actorEntity.Level, HPCurrent = actorEntity.HPCurrent, HPMax = actorEntity.HPMax, MPCurrent = actorEntity.MPCurrent, MPMax = actorEntity.MPMax, StatusEntries = actorEntity.StatusEntries }; CleanXPValue(ref entry); return(entry); } else { var defaultStatusEffectOffset = MemoryHandler.Instance.Structures.PartyEntity.DefaultStatusEffectOffset; var entry = new PartyEntity(); try { entry.X = BitConverter.TryToSingle(source, MemoryHandler.Instance.Structures.PartyEntity.X); entry.Z = BitConverter.TryToSingle(source, MemoryHandler.Instance.Structures.PartyEntity.Z); entry.Y = BitConverter.TryToSingle(source, MemoryHandler.Instance.Structures.PartyEntity.Y); entry.Coordinate = new Coordinate(entry.X, entry.Z, entry.Z); entry.ID = BitConverter.TryToUInt32(source, MemoryHandler.Instance.Structures.PartyEntity.ID); entry.UUID = Guid.NewGuid() .ToString(); entry.Name = MemoryHandler.Instance.GetStringFromBytes(source, MemoryHandler.Instance.Structures.PartyEntity.Name); entry.JobID = source[MemoryHandler.Instance.Structures.PartyEntity.Job]; entry.Job = (Actor.Job)entry.JobID; entry.Level = source[MemoryHandler.Instance.Structures.PartyEntity.Level]; entry.HPCurrent = BitConverter.TryToInt32(source, MemoryHandler.Instance.Structures.PartyEntity.HPCurrent); entry.HPMax = BitConverter.TryToInt32(source, MemoryHandler.Instance.Structures.PartyEntity.HPMax); entry.MPCurrent = BitConverter.TryToInt16(source, MemoryHandler.Instance.Structures.PartyEntity.MPCurrent); entry.MPMax = BitConverter.TryToInt16(source, MemoryHandler.Instance.Structures.PartyEntity.MPMax); const int limit = 15; entry.StatusEntries = new List <StatusEntry>(); const int statusSize = 12; var statusesSource = new byte[limit * statusSize]; Buffer.BlockCopy(source, defaultStatusEffectOffset, statusesSource, 0, limit * 12); for (var i = 0; i < limit; i++) { var statusSource = new byte[statusSize]; Buffer.BlockCopy(statusesSource, i * statusSize, statusSource, 0, statusSize); var statusEntry = new StatusEntry { TargetName = entry.Name, StatusID = BitConverter.TryToInt16(statusSource, MemoryHandler.Instance.Structures.StatusEntry.StatusID), Stacks = statusSource[MemoryHandler.Instance.Structures.StatusEntry.Stacks], Duration = BitConverter.TryToSingle(statusSource, MemoryHandler.Instance.Structures.StatusEntry.Duration), CasterID = BitConverter.TryToUInt32(statusSource, MemoryHandler.Instance.Structures.StatusEntry.CasterID) }; try { var pc = PCWorkerDelegate.GetEntity(statusEntry.CasterID); var npc = NPCWorkerDelegate.GetEntity(statusEntry.CasterID); var monster = MonsterWorkerDelegate.GetEntity(statusEntry.CasterID); statusEntry.SourceEntity = (pc ?? npc) ?? monster; } catch (Exception ex) { MemoryHandler.Instance.RaiseException(Logger, ex, true); } try { if (statusEntry.StatusID > 0) { var statusInfo = StatusEffectHelper.StatusInfo((uint)statusEntry.StatusID); statusEntry.IsCompanyAction = statusInfo.CompanyAction; var statusKey = statusInfo.Name.English; switch (MemoryHandler.Instance.GameLanguage) { case "French": statusKey = statusInfo.Name.French; break; case "Japanese": statusKey = statusInfo.Name.Japanese; break; case "German": statusKey = statusInfo.Name.German; break; case "Chinese": statusKey = statusInfo.Name.Chinese; break; case "Korean": statusKey = statusInfo.Name.Korean; break; } statusEntry.StatusName = statusKey; } } catch (Exception) { statusEntry.StatusName = "UNKNOWN"; } if (statusEntry.IsValid()) { entry.StatusEntries.Add(statusEntry); } } } catch (Exception ex) { MemoryHandler.Instance.RaiseException(Logger, ex, true); } CleanXPValue(ref entry); return(entry); } }
public static PartyEntity ResolvePartyMemberFromBytes(byte[] source, ActorEntity actorEntity = null) { if (actorEntity != null) { var entry = new PartyEntity { X = actorEntity.X, Y = actorEntity.Y, Z = actorEntity.Z, Coordinate = actorEntity.Coordinate, ID = actorEntity.ID, Name = actorEntity.Name, Job = actorEntity.Job, Level = actorEntity.Level, HPCurrent = actorEntity.HPCurrent, HPMax = actorEntity.HPMax, MPCurrent = actorEntity.MPCurrent, MPMax = actorEntity.MPMax, StatusEntries = actorEntity.StatusEntries, }; CleanXPValue(ref entry); return(entry); } else { var entry = new PartyEntity(); try { switch (Settings.Default.GameLanguage) { case "Chinese": default: entry.X = BitConverter.ToSingle(source, 0x0); entry.Z = BitConverter.ToSingle(source, 0x4); entry.Y = BitConverter.ToSingle(source, 0x8); entry.Coordinate = new Coordinate(entry.X, entry.Z, entry.Z); entry.ID = BitConverter.ToUInt32(source, 0x10); entry.Name = MemoryHandler.Instance.GetStringFromBytes(source, 0x20); entry.Job = (Actor.Job)source[0x61]; entry.Level = source[0x63]; entry.HPCurrent = BitConverter.ToInt32(source, 0x68); entry.HPMax = BitConverter.ToInt32(source, 0x6C); entry.MPCurrent = BitConverter.ToInt16(source, 0x70); entry.MPMax = BitConverter.ToInt16(source, 0x72); break; } const int limit = 15; entry.StatusEntries = new List <StatusEntry>(); const int statusSize = 12; var statusesSource = new byte[limit * statusSize]; switch (Settings.Default.GameLanguage) { case "Chinese": default: var defaultStatusEffectOffset = MemoryHandler.Instance.ProcessModel.IsWin64 ? 0x88 : 0x80; Buffer.BlockCopy(source, defaultStatusEffectOffset, statusesSource, 0, limit * 12); break; } for (var i = 0; i < limit; i++) { var statusSource = new byte[statusSize]; Buffer.BlockCopy(statusesSource, i * statusSize, statusSource, 0, statusSize); var statusEntry = new StatusEntry { TargetName = entry.Name, StatusID = BitConverter.ToInt16(statusSource, 0x0), Stacks = statusSource[0x2], Duration = BitConverter.ToSingle(statusSource, 0x4), CasterID = BitConverter.ToUInt32(statusSource, 0x8) }; try { var pc = PCWorkerDelegate.GetNPCEntity(statusEntry.CasterID); var npc = NPCWorkerDelegate.GetNPCEntity(statusEntry.CasterID); var monster = MonsterWorkerDelegate.GetNPCEntity(statusEntry.CasterID); statusEntry.SourceEntity = (pc ?? npc) ?? monster; } catch (Exception ex) { } try { if (statusEntry.StatusID > 0) { var statusInfo = StatusEffectHelper.StatusInfo(statusEntry.StatusID); statusEntry.IsCompanyAction = statusInfo.CompanyAction; var statusKey = statusInfo.Name.English; switch (Settings.Default.GameLanguage) { case "French": statusKey = statusInfo.Name.French; break; case "Japanese": statusKey = statusInfo.Name.Japanese; break; case "German": statusKey = statusInfo.Name.German; break; case "Chinese": statusKey = statusInfo.Name.Chinese; break; } statusEntry.StatusName = statusKey; } } catch (Exception ex) { statusEntry.StatusName = "UNKNOWN"; } if (statusEntry.IsValid()) { entry.StatusEntries.Add(statusEntry); } } } catch (Exception ex) { } CleanXPValue(ref entry); return(entry); } }
public static TargetResult GetTargetInfo() { var result = new TargetResult(); if (!CanGetTargetInfo() || !MemoryHandler.Instance.IsAttached) { return(result); } try { var targetAddress = (IntPtr)Scanner.Instance.Locations[Signatures.TargetKey]; if (targetAddress.ToInt64() > 0) { byte[] targetInfoSource = MemoryHandler.Instance.GetByteArray(targetAddress, MemoryHandler.Instance.Structures.TargetInfo.SourceSize); var currentTarget = MemoryHandler.Instance.GetPlatformIntFromBytes(targetInfoSource, MemoryHandler.Instance.Structures.TargetInfo.Current); var mouseOverTarget = MemoryHandler.Instance.GetPlatformIntFromBytes(targetInfoSource, MemoryHandler.Instance.Structures.TargetInfo.MouseOver); var focusTarget = MemoryHandler.Instance.GetPlatformIntFromBytes(targetInfoSource, MemoryHandler.Instance.Structures.TargetInfo.Focus); var previousTarget = MemoryHandler.Instance.GetPlatformIntFromBytes(targetInfoSource, MemoryHandler.Instance.Structures.TargetInfo.Previous); var currentTargetID = BitConverter.TryToUInt32(targetInfoSource, MemoryHandler.Instance.Structures.TargetInfo.CurrentID); if (currentTarget > 0) { try { ActorItem entry = GetTargetActorItemFromSource(currentTarget); currentTargetID = entry.ID; if (entry.IsValid) { result.TargetsFound = true; result.TargetInfo.CurrentTarget = entry; } } catch (Exception ex) { MemoryHandler.Instance.RaiseException(Logger, ex, true); } } if (mouseOverTarget > 0) { try { ActorItem entry = GetTargetActorItemFromSource(mouseOverTarget); if (entry.IsValid) { result.TargetsFound = true; result.TargetInfo.MouseOverTarget = entry; } } catch (Exception ex) { MemoryHandler.Instance.RaiseException(Logger, ex, true); } } if (focusTarget > 0) { try { ActorItem entry = GetTargetActorItemFromSource(focusTarget); if (entry.IsValid) { result.TargetsFound = true; result.TargetInfo.FocusTarget = entry; } } catch (Exception ex) { MemoryHandler.Instance.RaiseException(Logger, ex, true); } } if (previousTarget > 0) { try { ActorItem entry = GetTargetActorItemFromSource(previousTarget); if (entry.IsValid) { result.TargetsFound = true; result.TargetInfo.PreviousTarget = entry; } } catch (Exception ex) { MemoryHandler.Instance.RaiseException(Logger, ex, true); } } if (currentTargetID > 0) { result.TargetsFound = true; result.TargetInfo.CurrentTargetID = currentTargetID; } } if (result.TargetInfo.CurrentTargetID > 0) { try { if (CanGetEnmityEntities()) { var enmityCount = MemoryHandler.Instance.GetInt16(Scanner.Instance.Locations[Signatures.EnmityCountKey]); var enmityStructure = (IntPtr)Scanner.Instance.Locations[Signatures.EnmityMapKey]; if (enmityCount > 0 && enmityCount < 16 && enmityStructure.ToInt64() > 0) { var enmitySourceSize = MemoryHandler.Instance.Structures.EnmityItem.SourceSize; for (uint i = 0; i < enmityCount; i++) { try { var address = new IntPtr(enmityStructure.ToInt64() + i * enmitySourceSize); var enmityEntry = new EnmityItem { ID = (uint)MemoryHandler.Instance.GetPlatformInt(address, MemoryHandler.Instance.Structures.EnmityItem.ID), Name = MemoryHandler.Instance.GetString(address + MemoryHandler.Instance.Structures.EnmityItem.Name), Enmity = MemoryHandler.Instance.GetUInt32(address + MemoryHandler.Instance.Structures.EnmityItem.Enmity) }; if (enmityEntry.ID <= 0) { continue; } if (string.IsNullOrWhiteSpace(enmityEntry.Name)) { ActorItem pc = PCWorkerDelegate.GetActorItem(enmityEntry.ID); ActorItem npc = NPCWorkerDelegate.GetActorItem(enmityEntry.ID); ActorItem monster = MonsterWorkerDelegate.GetActorItem(enmityEntry.ID); try { enmityEntry.Name = (pc ?? npc).Name ?? monster.Name; } catch (Exception ex) { MemoryHandler.Instance.RaiseException(Logger, ex, true); } } result.TargetInfo.EnmityItems.Add(enmityEntry); } catch (Exception ex) { MemoryHandler.Instance.RaiseException(Logger, ex, true); } } } } } catch (Exception ex) { MemoryHandler.Instance.RaiseException(Logger, ex, true); } } } catch (Exception ex) { MemoryHandler.Instance.RaiseException(Logger, ex, true); } return(result); }
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); }
/// <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.TargetWorkerRefresh.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 { uint targetHateStructure; switch (Settings.Default.GameLanguage) { case "Chinese": targetHateStructure = MemoryHandler.Instance.SigScanner.Locations["CHARMAP"] + 1136; break; default: targetHateStructure = MemoryHandler.Instance.SigScanner.Locations["CHARMAP"] - 120664; break; } var enmityEntries = new List <EnmityEntry>(); var targetEntity = new TargetEntity(); if (MemoryHandler.Instance.SigScanner.Locations.ContainsKey("TARGET")) { var targetAddress = MemoryHandler.Instance.SigScanner.Locations["TARGET"]; var somethingFound = false; if (targetAddress > 0) { //var targetInfo = MemoryHandler.Instance.GetStructure<Structures.Target>(targetAddress); uint currentTarget; uint mouseOverTarget; uint focusTarget; uint previousTarget; uint currentTargetID; var targetInfoSource = MemoryHandler.Instance.GetByteArray(targetAddress, 128); switch (Settings.Default.GameLanguage) { case "Chinese": currentTarget = BitConverter.ToUInt32(targetInfoSource, 0x0); mouseOverTarget = BitConverter.ToUInt32(targetInfoSource, 0x18); focusTarget = BitConverter.ToUInt32(targetInfoSource, 0x48); previousTarget = BitConverter.ToUInt32(targetInfoSource, 0x54); currentTargetID = BitConverter.ToUInt32(targetInfoSource, 0x68); break; default: currentTarget = BitConverter.ToUInt32(targetInfoSource, 0x0); mouseOverTarget = BitConverter.ToUInt32(targetInfoSource, 0xC); focusTarget = BitConverter.ToUInt32(targetInfoSource, 0x3C); previousTarget = BitConverter.ToUInt32(targetInfoSource, 0x48); currentTargetID = BitConverter.ToUInt32(targetInfoSource, 0x5C); break; } if (currentTarget > 0) { try { var source = MemoryHandler.Instance.GetByteArray(currentTarget, 0x3F40); var entry = ActorEntityHelper.ResolveActorFromBytes(source); if (MemoryHandler.Instance.SigScanner.Locations.ContainsKey("MAP")) { try { entry.MapIndex = MemoryHandler.Instance.GetUInt32(MemoryHandler.Instance.SigScanner.Locations["MAP"]); } catch (Exception ex) { } } if (entry.IsValid) { somethingFound = true; targetEntity.CurrentTarget = entry; } } catch (Exception ex) { } } if (mouseOverTarget > 0) { try { var source = MemoryHandler.Instance.GetByteArray(mouseOverTarget, 0x3F40); var entry = ActorEntityHelper.ResolveActorFromBytes(source); if (MemoryHandler.Instance.SigScanner.Locations.ContainsKey("MAP")) { try { entry.MapIndex = MemoryHandler.Instance.GetUInt32(MemoryHandler.Instance.SigScanner.Locations["MAP"]); } catch (Exception ex) { } } if (entry.IsValid) { somethingFound = true; targetEntity.MouseOverTarget = entry; } } catch (Exception ex) { } } if (focusTarget > 0) { var source = MemoryHandler.Instance.GetByteArray(focusTarget, 0x3F40); var entry = ActorEntityHelper.ResolveActorFromBytes(source); if (MemoryHandler.Instance.SigScanner.Locations.ContainsKey("MAP")) { try { entry.MapIndex = MemoryHandler.Instance.GetUInt32(MemoryHandler.Instance.SigScanner.Locations["MAP"]); } catch (Exception ex) { } } if (entry.IsValid) { somethingFound = true; targetEntity.FocusTarget = entry; } } if (previousTarget > 0) { try { var source = MemoryHandler.Instance.GetByteArray(previousTarget, 0x3F40); var entry = ActorEntityHelper.ResolveActorFromBytes(source); if (MemoryHandler.Instance.SigScanner.Locations.ContainsKey("MAP")) { try { entry.MapIndex = MemoryHandler.Instance.GetUInt32(MemoryHandler.Instance.SigScanner.Locations["MAP"]); } catch (Exception ex) { } } if (entry.IsValid) { somethingFound = true; targetEntity.PreviousTarget = entry; } } catch (Exception ex) { } } if (currentTargetID > 0) { somethingFound = true; targetEntity.CurrentTargetID = currentTargetID; } } if (targetEntity.CurrentTargetID > 0) { for (uint i = 0; i < 16; i++) { var address = targetHateStructure + (i * 72); var enmityEntry = new EnmityEntry { ID = (uint)MemoryHandler.Instance.GetInt32(address), Enmity = (uint)MemoryHandler.Instance.GetInt32(address, 4) }; if (enmityEntry.ID <= 0) { continue; } if (PCWorkerDelegate.GetUniqueNPCEntities() .Any()) { if (PCWorkerDelegate.GetUniqueNPCEntities() .Any(a => a.ID == enmityEntry.ID)) { enmityEntry.Name = PCWorkerDelegate.GetUniqueNPCEntities() .First(a => a.ID == enmityEntry.ID) .Name; } } if (String.IsNullOrWhiteSpace(enmityEntry.Name)) { if (NPCWorkerDelegate.GetUniqueNPCEntities() .Any()) { if (NPCWorkerDelegate.GetUniqueNPCEntities() .Any(a => a.ID == enmityEntry.ID)) { enmityEntry.Name = NPCWorkerDelegate.GetUniqueNPCEntities() .First(a => a.NPCID2 == enmityEntry.ID) .Name; } } } if (String.IsNullOrWhiteSpace(enmityEntry.Name)) { if (MonsterWorkerDelegate.GetUniqueNPCEntities() .Any()) { if (MonsterWorkerDelegate.GetUniqueNPCEntities() .Any(a => a.ID == enmityEntry.ID)) { enmityEntry.Name = MonsterWorkerDelegate.GetUniqueNPCEntities() .First(a => a.ID == enmityEntry.ID) .Name; } } } enmityEntries.Add(enmityEntry); } } targetEntity.EnmityEntries = enmityEntries; if (somethingFound) { AppContextHelper.Instance.RaiseNewTargetEntity(targetEntity); } } } catch (Exception ex) { } } } _isScanning = false; return(true); }; scannerWorker.BeginInvoke(delegate { }, scannerWorker); }
public PartyMemberResolver(MemoryHandler memoryHandler, PCWorkerDelegate pcWorkerDelegate, NPCWorkerDelegate npcWorkerDelegate, MonsterWorkerDelegate monsterWorkerDelegate) { this._memoryHandler = memoryHandler; this._pcWorkerDelegate = pcWorkerDelegate; this._npcWorkerDelegate = npcWorkerDelegate; this._monsterWorkerDelegate = monsterWorkerDelegate; this._foundStatuses = new List <StatusItem>(); }