/// <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 partyEntities = new List<PartyEntity>(); var partyCount = MemoryHandler.Instance.GetByte(PartyCountMap); if (partyCount > 0 && partyCount < 9) { for (uint i = 0; i < partyCount; i++) { uint size; switch (Settings.Default.GameLanguage) { case "Chinese": size = 594; break; default: size = 544; break; } var address = PartyInfoMap + (i * size); var actor = MemoryHandler.Instance.GetStructure<Structures.PartyMember>(address); var entry = new PartyEntity { Name = MemoryHandler.Instance.GetString(address, 32), ID = actor.ID, Coordinate = new Coordinate(actor.X, actor.Z, actor.Y), X = actor.X, Z = actor.Z, Y = actor.Y, Level = actor.Level, HPCurrent = actor.HPCurrent, HPMax = actor.HPMax, MPCurrent = actor.MPCurrent, MPMax = actor.MPMax, Job = actor.Job }; if (entry.HPMax == 0) { entry.HPMax = 1; } foreach (var status in actor.Statuses) { var statusEntry = new StatusEntry { TargetName = entry.Name, StatusID = status.StatusID, Duration = status.Duration, CasterID = status.CasterID }; 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); } } if (entry.IsValid) { partyEntities.Add(entry); } } } AppContextHelper.Instance.RaiseNewPartyEntries(partyEntities); } catch (Exception ex) { } } } } _isScanning = false; return true; }; scannerWorker.BeginInvoke(delegate { }, scannerWorker); }
public static void EnsureNPCEntity(UInt32 key, PartyEntity entity) { NPCEntities.AddOrUpdate(key, entity, (k, v) => entity); }
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; } }
private static void CleanXPValue(ref PartyEntity entity) { if (entity.HPCurrent < 0 || entity.HPMax < 0) { entity.HPCurrent = 1; entity.HPMax = 1; } if (entity.HPCurrent > entity.HPMax) { if (entity.HPMax == 0) { entity.HPCurrent = 1; entity.HPMax = 1; } else { entity.HPCurrent = entity.HPMax; } } if (entity.MPCurrent < 0 || entity.MPMax < 0) { entity.MPCurrent = 1; entity.MPMax = 1; } if (entity.MPCurrent > entity.MPMax) { if (entity.MPMax == 0) { entity.MPCurrent = 1; entity.MPMax = 1; } else { entity.MPCurrent = entity.MPMax; } } }
public void CapturePartyMember(PartyEntity partyMember) { try { var partyMemberEntity = new PartyMemberEntity { EncounterId = EncounterId, Job = partyMember.Job.ToString(), Name = partyMember.Name, PlayerId = partyMember.ID, TimeOffset = Convert.ToUInt32(EncounterTimer.ElapsedMilliseconds) }; _sqLiteConnection.InsertAsync(partyMemberEntity) .ContinueWith(t => LogHelper.Log(Logger, "Party member " + partyMemberEntity.Name + "( " + partyMemberEntity.PlayerId + " ) captured for encounter " + EncounterId + ".", LogLevel.Trace)); foreach (var statusEntry in partyMember.StatusEntries) { NewPartyMemberStatusEntry(statusEntry, partyMemberEntity.PlayerId); } } catch (Exception ex) { LogHelper.Log(Logger, ex, LogLevel.Error); } }
private static PartyEntity GetPartyEntity(uint address, Structures.PartyMember partyMember, ActorEntity currentUser = null) { var actor = currentUser ?? (dynamic) partyMember; try { var entry = new PartyEntity { ID = actor.ID, X = actor.X, Z = actor.Z, Y = actor.Y, Level = actor.Level, HPCurrent = actor.HPCurrent, HPMax = actor.HPMax, MPCurrent = actor.MPCurrent, MPMax = actor.MPMax, Job = actor.Job }; if (entry.HPMax == 0) { entry.HPMax = 1; } if (currentUser == null) { entry.Name = MemoryHandler.Instance.GetString(address, 32); entry.Coordinate = new Coordinate(actor.X, actor.Z, actor.Y); foreach (var status in actor.Statuses) { var statusEntry = new StatusEntry { TargetName = entry.Name, StatusID = status.StatusID, Duration = status.Duration, CasterID = status.CasterID }; 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); } } } else { entry.Name = actor.Name; entry.Coordinate = actor.Coordinate; entry.StatusEntries = actor.StatusEntries; } return entry; } catch (Exception ex) { } return new PartyEntity(); }