From 99dbef815a9327bf71f313afdf143415d5d7a03b Mon Sep 17 00:00:00 2001 From: Doriel Rivalet <100863878+DorielRivalet@users.noreply.github.com> Date: Sun, 7 May 2023 21:31:10 -0300 Subject: [PATCH] refactor: add discord manager --- MHFZ_Overlay/ConfigWindow.xaml.cs | 116 +- .../Class/Application/ApplicationManager.cs | 17 +- .../Class/DataAccessLayer/DatabaseManager.cs | 20 +- .../Core/Class/Discord/DiscordManager.cs | 1256 ++++++++++++++ MHFZ_Overlay/Core/Class/Log/LoggingManager.cs | 5 +- MHFZ_Overlay/DataLoader.cs | 5 +- MHFZ_Overlay/MainWindow.xaml.cs | 1506 +---------------- MHFZ_Overlay/addresses/AddressModel.cs | 347 +++- 8 files changed, 1645 insertions(+), 1627 deletions(-) create mode 100644 MHFZ_Overlay/Core/Class/Discord/DiscordManager.cs diff --git a/MHFZ_Overlay/ConfigWindow.xaml.cs b/MHFZ_Overlay/ConfigWindow.xaml.cs index a0223ffc..8f56682e 100644 --- a/MHFZ_Overlay/ConfigWindow.xaml.cs +++ b/MHFZ_Overlay/ConfigWindow.xaml.cs @@ -61,6 +61,8 @@ public partial class ConfigWindow : Window private static string randomMonsterImage = "https://raw.githubusercontent.com/DorielRivalet/mhfz-overlay/main/img/monster/random.png"; + private static readonly DatabaseManager databaseManager = DatabaseManager.GetInstance(); + public static Uri MonsterInfoLink { get { return new Uri(randomMonsterImage, UriKind.RelativeOrAbsolute); } @@ -558,7 +560,7 @@ public ConfigWindow(MainWindow mainWindow) replaceAllMonsterInfoFeriasLinks(); - weaponUsageData = DatabaseManager.GetInstance().CalculateTotalWeaponUsage(this, MainWindow.DataLoader); + weaponUsageData = databaseManager.CalculateTotalWeaponUsage(this, MainWindow.DataLoader); } private List weaponUsageData = new(); @@ -1176,7 +1178,7 @@ private void questLoggingToggle_Check(object sender, RoutedEventArgs e) MainWindow.DataLoader.model.ValidateGameFolder(); - DatabaseManager.GetInstance().CheckIfSchemaChanged(MainWindow.DataLoader); + databaseManager.CheckIfSchemaChanged(MainWindow.DataLoader); } private void CountryComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e) @@ -1204,7 +1206,7 @@ private void QuestIDButton_Click(object sender, RoutedEventArgs e) if (!string.IsNullOrEmpty(QuestIDTextBox.Text)) { SetDefaultInfoInQuestIDWeaponSection(); - DatabaseManager.GetInstance().QuestIDButton_Click(sender, e, this); + databaseManager.QuestIDButton_Click(sender, e, this); } } @@ -1325,11 +1327,11 @@ private void WeaponUsageGraphComboBox_SelectionChanged(object sender, SelectionC if (comboBox.SelectedIndex == 0) { - weaponUsageData = DatabaseManager.GetInstance().CalculateTotalWeaponUsage(this, MainWindow.DataLoader); + weaponUsageData = databaseManager.CalculateTotalWeaponUsage(this, MainWindow.DataLoader); } else if (comboBox.SelectedIndex == 1) { - weaponUsageData = DatabaseManager.GetInstance().CalculateTotalWeaponUsage(this, MainWindow.DataLoader, true); + weaponUsageData = databaseManager.CalculateTotalWeaponUsage(this, MainWindow.DataLoader, true); } else { @@ -1410,7 +1412,7 @@ private void UpdateYoutubeLink_ButtonClick(object sender, RoutedEventArgs e) // Get the quest ID and new YouTube link from the textboxes long runID = long.Parse(RunIDTextBox.Text.Trim()); string youtubeLink = youtubeLinkTextBox.Text.Trim(); - if (DatabaseManager.GetInstance().UpdateYoutubeLink(sender, e, runID, youtubeLink)) + if (databaseManager.UpdateYoutubeLink(sender, e, runID, youtubeLink)) MessageBox.Show(String.Format("Updated run {0} with link https://youtube.com/watch?v={1}", runID, youtubeLink), "Success", MessageBoxButton.OK, MessageBoxImage.Information); else MessageBox.Show(String.Format("Could not update run {0} with link https://youtube.com/watch?v={1}. The link may have already been set to the same value, or the run ID and link input are invalid.", runID, youtubeLink), LoggingManager.ERROR_TITLE, MessageBoxButton.OK, MessageBoxImage.Error); @@ -1424,7 +1426,7 @@ private void UpdateYoutubeLink_Loaded(object sender, RoutedEventArgs e) private void YoutubeIconButton_Click(object sender, RoutedEventArgs e) { long runID = long.Parse(RunIDTextBox.Text.Trim()); - string youtubeLink = DatabaseManager.GetInstance().GetYoutubeLinkForRunID(runID); + string youtubeLink = databaseManager.GetYoutubeLinkForRunID(runID); if (youtubeLink != "") { var sInfo = new System.Diagnostics.ProcessStartInfo(youtubeLink) @@ -1447,7 +1449,7 @@ private void YoutubeLinkTextBox_Loaded(object sender, RoutedEventArgs e) private void MostRecentRuns_ListViewLoaded(object sender, RoutedEventArgs e) { mostRecentRunsListView = (ListView)sender; - MainWindow.DataLoader.model.RecentRuns = DatabaseManager.GetInstance().GetRecentRuns(); + MainWindow.DataLoader.model.RecentRuns = databaseManager.GetRecentRuns(); mostRecentRunsListView.ItemsSource = MainWindow.DataLoader.model.RecentRuns; mostRecentRunsListView.DataContext = MainWindow.DataLoader.model.RecentRuns; mostRecentRunsListView.Items.Refresh(); @@ -1456,7 +1458,7 @@ private void MostRecentRuns_ListViewLoaded(object sender, RoutedEventArgs e) private void Top20Runs_ListViewLoaded(object sender, RoutedEventArgs e) { top20RunsListView = (ListView)sender; - MainWindow.DataLoader.model.FastestRuns = DatabaseManager.GetInstance().GetFastestRuns(this); + MainWindow.DataLoader.model.FastestRuns = databaseManager.GetFastestRuns(this); top20RunsListView.ItemsSource = MainWindow.DataLoader.model.FastestRuns; top20RunsListView.DataContext = MainWindow.DataLoader.model.FastestRuns; top20RunsListView.Items.Refresh(); @@ -1476,7 +1478,7 @@ private void weaponListTop20RunsComboBox_SelectionChanged(object sender, Selecti selectedWeapon = selectedWeapon.Replace("System.Windows.Controls.ComboBoxItem: ", ""); if (selectedWeapon == "") return; - MainWindow.DataLoader.model.FastestRuns = DatabaseManager.GetInstance().GetFastestRuns(this, selectedWeapon); + MainWindow.DataLoader.model.FastestRuns = databaseManager.GetFastestRuns(this, selectedWeapon); top20RunsListView.ItemsSource = MainWindow.DataLoader.model.FastestRuns; top20RunsListView.DataContext = MainWindow.DataLoader.model.FastestRuns; top20RunsListView.Items.Refresh(); @@ -2245,8 +2247,8 @@ private void CreateQuestDurationStackedChart(Dictionary questDurations private Dictionary GetMostCommonInputs(long runID) { - var keystrokesDictionary = DatabaseManager.GetInstance().GetKeystrokesDictionary(runID); - var mouseInputDictionary = DatabaseManager.GetInstance().GetMouseInputDictionary(runID); + var keystrokesDictionary = databaseManager.GetKeystrokesDictionary(runID); + var mouseInputDictionary = databaseManager.GetMouseInputDictionary(runID); var combinedDictionary = keystrokesDictionary.Concat(mouseInputDictionary) .GroupBy(kvp => kvp.Value) .ToDictionary(g => g.Key, g => g.Count()); @@ -2557,119 +2559,119 @@ private void GraphsComboBox_SelectionChanged(object sender, SelectionChangedEven switch (selectedOption) { case "(General) Most Quest Completions": - SetColumnSeriesForDictionaryIntInt(DatabaseManager.GetInstance().GetMostQuestCompletions()); + SetColumnSeriesForDictionaryIntInt(databaseManager.GetMostQuestCompletions()); break; case "(General) Quest Durations": - CreateQuestDurationStackedChart(DatabaseManager.GetInstance().GetTotalTimeSpentInQuests()); + CreateQuestDurationStackedChart(databaseManager.GetTotalTimeSpentInQuests()); break; case "(General) Most Common Objective Types": - SetColumnSeriesForDictionaryStringInt(DatabaseManager.GetInstance().GetMostCommonObjectiveTypes()); + SetColumnSeriesForDictionaryStringInt(databaseManager.GetMostCommonObjectiveTypes()); break; case "(General) Most Common Star Grades": - SetColumnSeriesForDictionaryIntInt(DatabaseManager.GetInstance().GetMostCommonStarGrades()); + SetColumnSeriesForDictionaryIntInt(databaseManager.GetMostCommonStarGrades()); break; case "(General) Most Common Rank Bands": - SetColumnSeriesForDictionaryStringInt(DatabaseManager.GetInstance().GetMostCommonRankBands()); + SetColumnSeriesForDictionaryStringInt(databaseManager.GetMostCommonRankBands()); break; case "(General) Most Common Objective": - SetColumnSeriesForDictionaryStringInt(DatabaseManager.GetInstance().GetMostCommonObjectives()); + SetColumnSeriesForDictionaryStringInt(databaseManager.GetMostCommonObjectives()); break; case "(General) Quests Completed by Date": - SetColumnSeriesForDictionaryDateInt(DatabaseManager.GetInstance().GetQuestsCompletedByDate()); + SetColumnSeriesForDictionaryDateInt(databaseManager.GetQuestsCompletedByDate()); break; case "(General) Most Common Party Size": - SetColumnSeriesForDictionaryIntInt(DatabaseManager.GetInstance().GetMostCommonPartySize()); + SetColumnSeriesForDictionaryIntInt(databaseManager.GetMostCommonPartySize()); break; case "(General) Most Common Set Name": - SetColumnSeriesForDictionaryStringInt(DatabaseManager.GetInstance().GetMostCommonSetNames()); + SetColumnSeriesForDictionaryStringInt(databaseManager.GetMostCommonSetNames()); break; case "(General) Most Common Weapon Name": - SetColumnSeriesForDictionaryStringInt(DatabaseManager.GetInstance().GetMostCommonWeaponNames()); + SetColumnSeriesForDictionaryStringInt(databaseManager.GetMostCommonWeaponNames()); break; case "(General) Most Common Head Piece": - SetColumnSeriesForDictionaryStringInt(DatabaseManager.GetInstance().GetMostCommonHeadPieces()); + SetColumnSeriesForDictionaryStringInt(databaseManager.GetMostCommonHeadPieces()); break; case "(General) Most Common Chest Piece": - SetColumnSeriesForDictionaryStringInt(DatabaseManager.GetInstance().GetMostCommonChestPieces()); + SetColumnSeriesForDictionaryStringInt(databaseManager.GetMostCommonChestPieces()); break; case "(General) Most Common Arms Piece": - SetColumnSeriesForDictionaryStringInt(DatabaseManager.GetInstance().GetMostCommonArmsPieces()); + SetColumnSeriesForDictionaryStringInt(databaseManager.GetMostCommonArmsPieces()); break; case "(General) Most Common Waist Piece": - SetColumnSeriesForDictionaryStringInt(DatabaseManager.GetInstance().GetMostCommonWaistPieces()); + SetColumnSeriesForDictionaryStringInt(databaseManager.GetMostCommonWaistPieces()); break; case "(General) Most Common Legs Piece": - SetColumnSeriesForDictionaryStringInt(DatabaseManager.GetInstance().GetMostCommonLegsPieces()); + SetColumnSeriesForDictionaryStringInt(databaseManager.GetMostCommonLegsPieces()); break; case "(General) Most Common Diva Skill": - SetColumnSeriesForDictionaryStringInt(DatabaseManager.GetInstance().GetMostCommonDivaSkill()); + SetColumnSeriesForDictionaryStringInt(databaseManager.GetMostCommonDivaSkill()); break; case "(General) Most Common Guild Food": - SetColumnSeriesForDictionaryStringInt(DatabaseManager.GetInstance().GetMostCommonGuildFood()); + SetColumnSeriesForDictionaryStringInt(databaseManager.GetMostCommonGuildFood()); break; case "(General) Most Common Style Rank Skills": - SetColumnSeriesForDictionaryStringInt(DatabaseManager.GetInstance().GetMostCommonStyleRankSkills()); + SetColumnSeriesForDictionaryStringInt(databaseManager.GetMostCommonStyleRankSkills()); break; case "(General) Most Common Caravan Skills": - SetColumnSeriesForDictionaryStringInt(DatabaseManager.GetInstance().GetMostCommonCaravanSkills()); + SetColumnSeriesForDictionaryStringInt(databaseManager.GetMostCommonCaravanSkills()); break; case "(General) Most Common Category": - SetColumnSeriesForDictionaryStringInt(DatabaseManager.GetInstance().GetMostCommonCategory()); + SetColumnSeriesForDictionaryStringInt(databaseManager.GetMostCommonCategory()); break; case "(Run ID) Attack Buff": - SetLineSeriesForDictionaryIntInt(DatabaseManager.GetInstance().GetAttackBuffDictionary(runID)); + SetLineSeriesForDictionaryIntInt(databaseManager.GetAttackBuffDictionary(runID)); return; case "(Run ID) Hit Count": - SetLineSeriesForDictionaryIntInt(DatabaseManager.GetInstance().GetHitCountDictionary(runID)); + SetLineSeriesForDictionaryIntInt(databaseManager.GetHitCountDictionary(runID)); return; case "(Run ID) Hits per Second": - SetLineSeriesForDictionaryIntDouble(DatabaseManager.GetInstance().GetHitsPerSecondDictionary(runID)); + SetLineSeriesForDictionaryIntDouble(databaseManager.GetHitsPerSecondDictionary(runID)); return; case "(Run ID) Damage Dealt": - SetLineSeriesForDictionaryIntInt(DatabaseManager.GetInstance().GetDamageDealtDictionary(runID)); + SetLineSeriesForDictionaryIntInt(databaseManager.GetDamageDealtDictionary(runID)); return; case "(Run ID) Damage per Second": - SetLineSeriesForDictionaryIntDouble(DatabaseManager.GetInstance().GetDamagePerSecondDictionary(runID)); + SetLineSeriesForDictionaryIntDouble(databaseManager.GetDamagePerSecondDictionary(runID)); return; case "(Run ID) Carts": - SetLineSeriesForDictionaryIntInt(DatabaseManager.GetInstance().GetCartsDictionary(runID)); + SetLineSeriesForDictionaryIntInt(databaseManager.GetCartsDictionary(runID)); return; case "(Run ID) Hits Taken/Blocked": - SetHitsTakenBlocked(DatabaseManager.GetInstance().GetHitsTakenBlockedDictionary(runID)); + SetHitsTakenBlocked(databaseManager.GetHitsTakenBlockedDictionary(runID)); return; case "(Run ID) Hits Taken/Blocked per Second": - SetLineSeriesForDictionaryIntDouble(DatabaseManager.GetInstance().GetHitsTakenBlockedPerSecondDictionary(runID)); + SetLineSeriesForDictionaryIntDouble(databaseManager.GetHitsTakenBlockedPerSecondDictionary(runID)); return; case "(Run ID) Player Health and Stamina": - SetPlayerHealthStamina(DatabaseManager.GetInstance().GetPlayerHPDictionary(runID), DatabaseManager.GetInstance().GetPlayerStaminaDictionary(runID)); + SetPlayerHealthStamina(databaseManager.GetPlayerHPDictionary(runID), databaseManager.GetPlayerStaminaDictionary(runID)); return; case "(Run ID) Most Common Player Input": SetColumnSeriesForDictionaryStringInt(GetMostCommonInputs(runID)); break; case "(Run ID) Actions per Minute": - SetLineSeriesForDictionaryIntDouble(DatabaseManager.GetInstance().GetActionsPerMinuteDictionary(runID)); + SetLineSeriesForDictionaryIntDouble(databaseManager.GetActionsPerMinuteDictionary(runID)); return; case "(Run ID) Monster HP": - SetMonsterHP(CalculateMonsterHP(DatabaseManager.GetInstance().GetMonster1HPDictionary(runID)), CalculateMonsterHP(DatabaseManager.GetInstance().GetMonster2HPDictionary(runID)), CalculateMonsterHP(DatabaseManager.GetInstance().GetMonster3HPDictionary(runID)), CalculateMonsterHP(DatabaseManager.GetInstance().GetMonster4HPDictionary(runID))); + SetMonsterHP(CalculateMonsterHP(databaseManager.GetMonster1HPDictionary(runID)), CalculateMonsterHP(databaseManager.GetMonster2HPDictionary(runID)), CalculateMonsterHP(databaseManager.GetMonster3HPDictionary(runID)), CalculateMonsterHP(databaseManager.GetMonster4HPDictionary(runID))); return; case "(Run ID) Monster Attack Multiplier": - SetMonsterAttackMultiplier(CalculateMonsterMultiplier(DatabaseManager.GetInstance().GetMonster1AttackMultiplierDictionary(runID))); + SetMonsterAttackMultiplier(CalculateMonsterMultiplier(databaseManager.GetMonster1AttackMultiplierDictionary(runID))); return; case "(Run ID) Monster Defense Rate": - SetMonsterDefenseRate(CalculateMonsterMultiplier(DatabaseManager.GetInstance().GetMonster1DefenseRateDictionary(runID))); + SetMonsterDefenseRate(CalculateMonsterMultiplier(databaseManager.GetMonster1DefenseRateDictionary(runID))); return; case "(Run ID) Monster Status Ailments Thresholds": SetMonsterStatusAilmentsThresholds( CalculateMonsterStatusAilmentThresholds( - DatabaseManager.GetInstance().GetMonster1PoisonThresholdDictionary(runID)), + databaseManager.GetMonster1PoisonThresholdDictionary(runID)), CalculateMonsterStatusAilmentThresholds( - DatabaseManager.GetInstance().GetMonster1SleepThresholdDictionary(runID)), + databaseManager.GetMonster1SleepThresholdDictionary(runID)), CalculateMonsterStatusAilmentThresholds( - DatabaseManager.GetInstance().GetMonster1ParalysisThresholdDictionary(runID)), + databaseManager.GetMonster1ParalysisThresholdDictionary(runID)), CalculateMonsterStatusAilmentThresholds( - DatabaseManager.GetInstance().GetMonster1BlastThresholdDictionary(runID)), + databaseManager.GetMonster1BlastThresholdDictionary(runID)), CalculateMonsterStatusAilmentThresholds( - DatabaseManager.GetInstance().GetMonster1StunThresholdDictionary(runID) + databaseManager.GetMonster1StunThresholdDictionary(runID) ) ); return; @@ -2808,16 +2810,16 @@ private void StatsTextComboBox_SelectionChanged(object sender, SelectionChangedE switch (selectedOption) { case "Inventory": - statsTextTextBlock.Text = FormatInventory(DatabaseManager.GetInstance().GetPlayerInventoryDictionary(runID)); + statsTextTextBlock.Text = FormatInventory(databaseManager.GetPlayerInventoryDictionary(runID)); break; case "Ammo": - statsTextTextBlock.Text = FormatInventory(DatabaseManager.GetInstance().GetAmmoDictionary(runID)); + statsTextTextBlock.Text = FormatInventory(databaseManager.GetAmmoDictionary(runID)); break; case "Partnya Bag": - statsTextTextBlock.Text = FormatInventory(DatabaseManager.GetInstance().GetPartnyaBagDictionary(runID)); + statsTextTextBlock.Text = FormatInventory(databaseManager.GetPartnyaBagDictionary(runID)); break; case "Area Changes": - statsTextTextBlock.Text = DisplayAreaChanges(DatabaseManager.GetInstance().GetAreaChangesDictionary(runID)); + statsTextTextBlock.Text = DisplayAreaChanges(databaseManager.GetAreaChangesDictionary(runID)); break; } } @@ -3021,10 +3023,10 @@ private void RefreshButton_Click(object sender, RoutedEventArgs e) switch (personalBestSelectedType) { case "(Quest ID) Personal Best by Date": - SetStepLineSeriesForPersonalBestByDate(DatabaseManager.GetInstance().GetPersonalBestsByDate(questID, weaponTypeID, OverlayModeComboBox.Text)); + SetStepLineSeriesForPersonalBestByDate(databaseManager.GetPersonalBestsByDate(questID, weaponTypeID, OverlayModeComboBox.Text)); break; case "(Quest ID) Personal Best by Attempts": - SetStepLineSeriesForPersonalBestByAttempts(DatabaseManager.GetInstance().GetPersonalBestsByAttempts(questID, weaponTypeID, OverlayModeComboBox.Text)); + SetStepLineSeriesForPersonalBestByAttempts(databaseManager.GetPersonalBestsByAttempts(questID, weaponTypeID, OverlayModeComboBox.Text)); break; default: personalBestChart.Series = PersonalBestSeries; @@ -3038,7 +3040,7 @@ private void HunterPerformancePolarChart_Loaded(object sender, RoutedEventArgs e { var chart = sender as PolarChart; hunterPerformanceChart = chart; - SetPolarLineSeriesForHunterPerformance(DatabaseManager.GetInstance().GetPerformanceCompendium()); + SetPolarLineSeriesForHunterPerformance(databaseManager.GetPerformanceCompendium()); } private void CompendiumInformationStackPanel_Loaded(object sender, RoutedEventArgs e) diff --git a/MHFZ_Overlay/Core/Class/Application/ApplicationManager.cs b/MHFZ_Overlay/Core/Class/Application/ApplicationManager.cs index d353fc52..fb0fb2f3 100644 --- a/MHFZ_Overlay/Core/Class/Application/ApplicationManager.cs +++ b/MHFZ_Overlay/Core/Class/Application/ApplicationManager.cs @@ -1,4 +1,5 @@ using DiscordRPC; +using MHFZ_Overlay.Core.Class.Discord; using NLog; using System; using System.Collections.Generic; @@ -18,7 +19,7 @@ public static void HandleShutdown() { //https://stackoverflow.com/a/9050477/18859245 databaseManager.StoreSessionTime(databaseManager.DatabaseStartTime); - ApplicationManager.DiscordRPCCleanup(); + DiscordManager.DiscordRPCCleanup(); DisposeNotifyIcon(); logger.Info("Closing overlay"); Environment.Exit(0); @@ -35,23 +36,11 @@ public static void DisposeNotifyIcon() public static void HandleRestart() { databaseManager.StoreSessionTime(databaseManager.DatabaseStartTime); + DiscordManager.DiscordRPCCleanup(); DisposeNotifyIcon(); logger.Info("Restarting overlay"); System.Windows.Forms.Application.Restart(); System.Windows.Application.Current.Shutdown(); } - - //Dispose client - /// - /// Cleanups the Discord RPC instance. - /// - public static void DiscordRPCCleanup() - { - if (MainWindow.discordRPCClient != null)//&& ShowDiscordRPC) - { - MainWindow.discordRPCClient.Dispose(); - logger.Info("Disposed Discord RPC"); - } - } } } diff --git a/MHFZ_Overlay/Core/Class/DataAccessLayer/DatabaseManager.cs b/MHFZ_Overlay/Core/Class/DataAccessLayer/DatabaseManager.cs index ca13a5a0..cb352c08 100644 --- a/MHFZ_Overlay/Core/Class/DataAccessLayer/DatabaseManager.cs +++ b/MHFZ_Overlay/Core/Class/DataAccessLayer/DatabaseManager.cs @@ -98,9 +98,11 @@ public static DatabaseManager GetInstance() { if (instance == null) { + logger.Info("Singleton not found, creating instance."); instance = new DatabaseManager(); } - + logger.Info("Singleton found, returning instance."); + logger.Trace(new StackTrace().ToString()); return instance; } @@ -172,7 +174,7 @@ public bool SetupLocalDatabase(DataLoader dataLoader) conn.Open(); // Toggle comment this for testing the error handling - ThrowException(conn); + //ThrowException(conn); CreateDatabaseTables(conn, dataLoader); CreateDatabaseIndexes(conn); @@ -438,18 +440,18 @@ public int InsertQuestData(DataLoader dataLoader, int attempts) //Gathering/etc if ((dataLoader.model.ObjectiveType() == 0x0 || dataLoader.model.ObjectiveType() == 0x02 || dataLoader.model.ObjectiveType() == 0x1002) && (dataLoader.model.QuestID() != 23527 && dataLoader.model.QuestID() != 23628 && dataLoader.model.QuestID() != 21731 && dataLoader.model.QuestID() != 21749 && dataLoader.model.QuestID() != 21746 && dataLoader.model.QuestID() != 21750)) { - objectiveImage = MainWindow.GetAreaIconFromID(dataLoader.model.AreaID()); + objectiveImage = dataLoader.model.GetAreaIconFromID(dataLoader.model.AreaID()); } //Tenrou Sky Corridor areas else if (dataLoader.model.AreaID() == 391 || dataLoader.model.AreaID() == 392 || dataLoader.model.AreaID() == 394 || dataLoader.model.AreaID() == 415 || dataLoader.model.AreaID() == 416) { - objectiveImage = MainWindow.GetAreaIconFromID(dataLoader.model.AreaID()); + objectiveImage = dataLoader.model.GetAreaIconFromID(dataLoader.model.AreaID()); } //Duremudira Doors else if (dataLoader.model.AreaID() == 399 || dataLoader.model.AreaID() == 414) { - objectiveImage = MainWindow.GetAreaIconFromID(dataLoader.model.AreaID()); + objectiveImage = dataLoader.model.GetAreaIconFromID(dataLoader.model.AreaID()); } //Duremudira Arena else if (dataLoader.model.AreaID() == 398) @@ -459,7 +461,7 @@ public int InsertQuestData(DataLoader dataLoader, int attempts) //Hunter's Road Base Camp else if (dataLoader.model.AreaID() == 459) { - objectiveImage = MainWindow.GetAreaIconFromID(dataLoader.model.AreaID()); + objectiveImage = dataLoader.model.GetAreaIconFromID(dataLoader.model.AreaID()); } //Raviente else if (dataLoader.model.AreaID() == 309 || (dataLoader.model.AreaID() >= 311 && dataLoader.model.AreaID() <= 321) || (dataLoader.model.AreaID() >= 417 && dataLoader.model.AreaID() <= 422) || dataLoader.model.AreaID() == 437 || (dataLoader.model.AreaID() >= 440 && dataLoader.model.AreaID() <= 444)) @@ -2392,10 +2394,8 @@ private void HandleError(SQLiteTransaction? transaction, Exception ex) if (transaction != null) transaction.Rollback(); - logger.Error(ex, "An error occurred"); - // Handle the exception and show an error message to the user - LoggingManager.PromptForOpeningLogs(); + LoggingManager.WriteCrashLog(ex); } public void MakeDeserealizedQuestInfoDictionariesFromRunID(SQLiteConnection conn, DataLoader dataLoader, int runID) @@ -5495,8 +5495,6 @@ public ZenithSkills GetZenithSkills(long runID) return zenithSkills; } - - public CaravanSkills GetCaravanSkills(long runID) { CaravanSkills caravanSkills = new CaravanSkills(); diff --git a/MHFZ_Overlay/Core/Class/Discord/DiscordManager.cs b/MHFZ_Overlay/Core/Class/Discord/DiscordManager.cs new file mode 100644 index 00000000..e5b18405 --- /dev/null +++ b/MHFZ_Overlay/Core/Class/Discord/DiscordManager.cs @@ -0,0 +1,1256 @@ +using Dictionary; +using DiscordRPC; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MHFZ_Overlay.Core.Class.Discord +{ + internal class DiscordManager + { + + #region constructor + + private static DiscordManager instance; + private static readonly NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger(); + private static bool StartedRoadElapsedTime = false; + private static bool inDuremudiraArena = false; + private static bool inDuremudiraDoorway = false; + /// + /// Is the main loop currently running? + /// + private static bool isDiscordRPCRunning = false; + + private DiscordManager() + { + logger.Info($"DiscordManager initialized"); + } + + public static DiscordManager GetInstance() + { + if (instance == null) + { + logger.Info("Singleton not found, creating instance."); + instance = new DiscordManager(); + } + logger.Info("Singleton found, returning instance."); + logger.Trace(new StackTrace().ToString()); + return instance; + } + + #endregion + + #region client setup + + /// + /// Gets the client. + /// + /// + /// The client. + /// + private static DiscordRpcClient discordRPCClient; + + //Called when your application first starts. + //For example, just before your main loop, on OnEnable for unity. + private static void SetupDiscordRPC() + { + /* + Create a Discord client + NOTE: If you are using Unity3D, you must use the full constructor and define + the pipe connection. + */ + discordRPCClient = new DiscordRpcClient(GetDiscordClientID); + + //Set the logger + + //Subscribe to events + + //Connect to the RPC + discordRPCClient.Initialize(); + + //Set the rich presence + //Call this as many times as you want and anywhere in your code. + logger.Info("Set up Discord RPC"); + } + + /// + /// Gets a value indicating whether [show discord RPC]. + /// + /// + /// true if [show discord RPC]; otherwise, false. + /// + private static bool ShowDiscordRPC + { + get + { + Settings s = (Settings)System.Windows.Application.Current.TryFindResource("Settings"); + if (s.EnableRichPresence) + return true; + else + return false; + } + } + + /// + /// Gets the discord client identifier. + /// + /// + /// The discord client identifier. + /// + private static string GetDiscordClientID + { + get + { + Settings s = (Settings)System.Windows.Application.Current.TryFindResource("Settings"); + if (s.DiscordClientID.Length == 19) + return s.DiscordClientID; + else + return ""; + } + } + + /// + /// Gets the discord server invite. + /// + /// + /// The discord server invite. + /// + private static string GetDiscordServerInvite + { + get + { + Settings s = (Settings)System.Windows.Application.Current.TryFindResource("Settings"); + if (s.DiscordServerInvite.Length >= 8) + return s.DiscordServerInvite; + else + return ""; + } + } + + /// + /// Gets the name of the hunter. + /// + /// + /// The name of the hunter. + /// + private static string GetHunterName + { + get + { + Settings s = (Settings)System.Windows.Application.Current.TryFindResource("Settings"); + if (s.HunterName.Length >= 1) + return s.HunterName; + else + return "Hunter Name"; + } + } + + /// + /// Gets the name of the guild. + /// + /// + /// The name of the guild. + /// + private static string GetGuildName + { + get + { + Settings s = (Settings)System.Windows.Application.Current.TryFindResource("Settings"); + if (s.GuildName.Length >= 1) + return s.GuildName; + else + return "Guild Name"; + } + } + + private static string GetServerName + { + get + { + Settings s = (Settings)System.Windows.Application.Current.TryFindResource("Settings"); + bool serverNameFound = Dictionary.DiscordServersList.DiscordServerID.TryGetValue(s.DiscordServerID, out string? value); + if (serverNameFound) + return value; + else + return "Unknown Server"; + } + } + + /// + /// The current presence to send to discord. + /// + private static RichPresence presenceTemplate = new RichPresence() + { + Details = "【MHF-Z】Overlay " + MainWindow.CurrentProgramVersion, + State = "Loading...", + //check img folder + Assets = new Assets() + { + LargeImageKey = "cattleya", + LargeImageText = "Please Wait", + SmallImageKey = "https://i.imgur.com/9OkLYAz.png", + SmallImageText = "Hunter Name | Guild Name" + }, + Buttons = new DiscordRPC.Button[] + { + new DiscordRPC.Button() {Label = "【MHF-Z】Overlay "+ MainWindow.CurrentProgramVersion, Url = "https://github.com/DorielRivalet/mhfz-overlay"}, + new DiscordRPC.Button() { Label = "Discord RPC C# Dev Site", Url = "https://lachee.dev/" } + } + }; + + /// + /// Initializes the discord RPC. + /// + public static void InitializeDiscordRPC() + { + if (isDiscordRPCRunning) + return; + + if (ShowDiscordRPC && GetDiscordClientID != "") + { + SetupDiscordRPC(); + + //Set Presence + presenceTemplate.Timestamps = Timestamps.Now; + + if (GetHunterName != "" && GetGuildName != "" && GetServerName != "") + { + presenceTemplate.Assets = new Assets() + { + LargeImageKey = "cattleya", + LargeImageText = "Please Wait", + SmallImageKey = "https://i.imgur.com/9OkLYAz.png", + SmallImageText = GetHunterName + " | " + GetGuildName + " | " + GetServerName + }; + } + + //should work fine + presenceTemplate.Buttons = new DiscordRPC.Button[] { }; + presenceTemplate.Buttons = new DiscordRPC.Button[] + { + new DiscordRPC.Button() {Label = "【MHF-Z】Overlay "+ MainWindow.CurrentProgramVersion, Url = "https://github.com/DorielRivalet/mhfz-overlay"}, + new DiscordRPC.Button() { Label = "Discord RPC C# Dev Site", Url = "https://lachee.dev/" } + }; + + if (GetDiscordServerInvite != "") + { + presenceTemplate.Buttons = new DiscordRPC.Button[] { }; + presenceTemplate.Buttons = new DiscordRPC.Button[] + { + new DiscordRPC.Button() {Label = "【MHF-Z】Overlay "+ MainWindow.CurrentProgramVersion, Url = "https://github.com/DorielRivalet/mhfz-overlay"}, + new DiscordRPC.Button() { Label = "Join Discord Server", Url = String.Format("https://discord.com/invite/{0}",GetDiscordServerInvite)} + }; + } + + discordRPCClient.SetPresence(presenceTemplate); + isDiscordRPCRunning = true; + logger.Info("Discord RPC is now running"); + } + } + + //Dispose client + /// + /// Cleanups the Discord RPC instance. + /// + public static void DiscordRPCCleanup() + { + if (discordRPCClient != null)//&& ShowDiscordRPC) + { + discordRPCClient.Dispose(); + logger.Info("Disposed Discord RPC"); + } + } + + #endregion + + #region discord info + + //dure and road + /// + /// In the arena? + /// + /// + private static bool InArena(DataLoader dataLoader) + { + if (dataLoader.model.AreaID() == 398 || dataLoader.model.AreaID() == 458) + return true; + else + return false; + } + + /// + /// Gets a value indicating whether [show discord quest names]. + /// + /// + /// true if [show discord quest names]; otherwise, false. + /// + public static bool ShowDiscordQuestNames() + { + Settings s = (Settings)System.Windows.Application.Current.TryFindResource("Settings"); + if (s.DiscordQuestNameShown) + return true; + else + return false; + } + + /// + /// Gets the quest information. + /// + /// + private string GetQuestInformation(DataLoader dataLoader) + { + if (ShowDiscordQuestNames()) + { + switch (dataLoader.model.QuestID()) + { + case 23648://arrogant repel + return "Repel Arrogant Duremudira | "; + case 23649://arrogant slay + return "Slay Arrogant Duremudira | "; + case 23527:// Hunter's Road Multiplayer + return ""; + case 23628://solo road + return ""; + case 21731://1st district dure + case 21749://sky corridor version + return "Slay 1st District Duremudira | "; + case 21746://2nd district dure + case 21750://sky corridor version + return "Slay 2nd District Duremudira | "; + default: + if ((dataLoader.model.ObjectiveType() == 0x0 || dataLoader.model.ObjectiveType() == 0x02 || dataLoader.model.ObjectiveType() == 0x1002 || dataLoader.model.ObjectiveType() == 0x10) && (dataLoader.model.QuestID() != 23527 && dataLoader.model.QuestID() != 23628 && dataLoader.model.QuestID() != 21731 && dataLoader.model.QuestID() != 21749 && dataLoader.model.QuestID() != 21746 && dataLoader.model.QuestID() != 21750)) + return string.Format("{0}{1}{2}{3}{4}{5} | ", dataLoader.model.GetObjectiveNameFromID(dataLoader.model.ObjectiveType(), true), dataLoader.model.GetObjective1CurrentQuantity(true), dataLoader.model.GetObjective1Quantity(true), dataLoader.model.GetRankNameFromID(dataLoader.model.RankBand(), true), dataLoader.model.GetStarGrade(true), dataLoader.model.GetObjective1Name(dataLoader.model.Objective1ID(), true)); + else + return string.Format("{0}{1}{2}{3}{4}{5} | ", dataLoader.model.GetObjectiveNameFromID(dataLoader.model.ObjectiveType(), true), "", dataLoader.model.GetObjective1Quantity(true), dataLoader.model.GetRankNameFromID(dataLoader.model.RankBand(), true), dataLoader.model.GetStarGrade(true), dataLoader.model.GetRealMonsterName(dataLoader.model.CurrentMonster1Icon, true)); + } + } + else + { + return ""; + } + } + + /// + /// Gets the raviente event. + /// + /// The identifier. + /// + private static string GetRavienteEvent(int id, DataLoader dataLoader) + { + Dictionary.RavienteTriggerEvents.RavienteTriggerEventIDs.TryGetValue(id, out string? EventValue1); + Dictionary.ViolentRavienteTriggerEvents.ViolentRavienteTriggerEventIDs.TryGetValue(id, out string? EventValue2); + Dictionary.BerserkRavienteTriggerEvents.BerserkRavienteTriggerEventIDs.TryGetValue(id, out string? EventValue3); + Dictionary.BerserkRavientePracticeTriggerEvents.BerserkRavientePracticeTriggerEventIDs.TryGetValue(id, out string? EventValue4); + + switch (dataLoader.model.getRaviName()) + { + default: + return ""; + case "Raviente": + return EventValue1 + ""; + case "Violent Raviente": + return EventValue2 + ""; + case "Berserk Raviente Practice": + return EventValue4 + ""; + case "Berserk Raviente": + return EventValue3 + ""; + case "Extreme Raviente": + return EventValue3 + ""; + } + } + + /// + /// Gets the road timer reset mode. + /// + /// + private string GetRoadTimerResetMode() + { + Settings s = (Settings)System.Windows.Application.Current.TryFindResource("Settings"); + if (s.DiscordRoadTimerReset == "Never") + return "Never"; + else if (s.DiscordRoadTimerReset == "Always") + return "Always"; + else return "Never"; + } + + /// + /// Get quest state + /// + /// + private static string GetQuestState(DataLoader dataLoader) + { + if (dataLoader.model.isInLauncherBool) //works? + return ""; + + switch (dataLoader.model.QuestState()) + { + default: + return ""; + case 0: + return ""; + case 1: + return String.Format("Achieved Main Objective | {0} | ", dataLoader.model.Time); + case 129: + return String.Format("Quest Clear! | {0} | ", dataLoader.model.Time); + } + } + + /// + /// Gets the size of the party. + /// + /// + private string GetPartySize(DataLoader dataLoader) + { + if (dataLoader.model.QuestID() == 0 || dataLoader.model.PartySize() == 0 || dataLoader.model.isInLauncher() == "NULL" || dataLoader.model.isInLauncher() == "Yes") + { + return ""; + } + else + { + return string.Format("Party: {0}/{1} | ", dataLoader.model.PartySize(), GetPartySizeMax(dataLoader)); + } + } + + private int GetPartySizeMax(DataLoader dataLoader) + { + if (dataLoader.model.PartySize() >= dataLoader.model.PartySizeMax()) + return dataLoader.model.PartySize(); + else + return dataLoader.model.PartySizeMax(); + } + + private bool IsInHubAreaID(DataLoader dataLoader) + { + switch (dataLoader.model.AreaID()) + { + default: + return false; + case 200://Mezeporta + case 210://Private Bar + case 260://Pallone Caravan + case 282://Cities Map + case 202://Guild Halls + case 203: + case 204: + return true; + } + } + + /// + /// Gets the caravan score. + /// + /// + private string GetCaravanScore(DataLoader dataLoader) + { + if (ShowCaravanScore()) + return string.Format("Caravan Score: {0} | ", dataLoader.model.CaravanScore()); + else + return ""; + } + + private static bool ShowCaravanScore() + { + Settings s = (Settings)System.Windows.Application.Current.TryFindResource("Settings"); + if (s.EnableCaravanScore) + return true; + else + return false; + } + + /// + /// Gets the game mode. + /// + /// if set to true [is high grade edition]. + /// + private static string GetGameMode(bool isHighGradeEdition) + { + if (isHighGradeEdition) + return " [High-Grade Edition]"; + else + return ""; + } + + /// + /// Gets the discord timer mode. + /// + /// + private static string GetDiscordTimerMode() + { + Settings s = (Settings)System.Windows.Application.Current.TryFindResource("Settings"); + if (s.DiscordTimerMode == "Time Left") + return "Time Left"; + else if (s.DiscordTimerMode == "Time Elapsed") + return "Time Elapsed"; + else return "Time Left"; + } + + /// + /// Gets the weapon name from identifier. + /// + /// The identifier. + /// + private static string GetWeaponNameFromID(int id) + { + Dictionary.WeaponTypes.WeaponTypeID.TryGetValue(id, out string? weaponname); + return weaponname + ""; + } + + /// + /// Gets the weapon icon from identifier. + /// + /// The identifier. + /// + private string GetWeaponIconFromID(int id, DataLoader dataLoader) + { + string weaponName = GetWeaponNameFromID(id); + string colorName = dataLoader.model.GetArmorColor(); + + string weaponIconName = ""; + + switch (weaponName) + { + case "Sword and Shield": + weaponIconName += "sns"; + break; + case "Dual Swords": + weaponIconName += "ds"; + break; + case "Great Sword": + weaponIconName += "gs"; + break; + case "Long Sword": + weaponIconName += "ls"; + break; + case "Hammer": + weaponIconName += "hammer"; + break; + case "Hunting Horn": + weaponIconName += "hh"; + break; + case "Lance": + weaponIconName += "lance"; + break; + case "Gunlance": + weaponIconName += "gl"; + break; + case "Switch Axe F": + weaponIconName += "saf"; + break; + case "Tonfa": + weaponIconName += "tonfa"; + break; + case "Magnet Spike": + weaponIconName += "ms"; + break; + case "Light Bowgun": + weaponIconName += "lbg"; + break; + case "Heavy Bowgun": + weaponIconName += "hbg"; + break; + case "Bow": + weaponIconName += "bow"; + break; + default: + weaponIconName = "https://i.imgur.com/9OkLYAz.png";//transcend + break; + } + + if (weaponIconName != "https://i.imgur.com/9OkLYAz.png" && !(colorName.Contains("White"))) + weaponIconName += "_"; + + if (colorName.Contains("Green")) + { + weaponIconName += "green"; + } + else if (colorName.Contains("Red")) + { + weaponIconName += "red"; + } + + else if (colorName.Contains("Pink")) + { + weaponIconName += "pink"; + } + else if (colorName.Contains("Blue")) + { + weaponIconName += "blue"; + } + else if (colorName.Contains("Navy")) + { + weaponIconName += "navy"; + } + else if (colorName.Contains("Cyan")) + { + weaponIconName += "cyan"; + } + else if (colorName.Contains("Purple")) + { + weaponIconName += "purple"; + } + else if (colorName.Contains("Orange")) + { + weaponIconName += "orange"; + } + else if (colorName.Contains("Yellow")) + { + weaponIconName += "yellow"; + } + else if (colorName.Contains("Grey")) + { + weaponIconName += "grey"; + } + else if (colorName.Contains("Rainbow")) + { + weaponIconName += "rainbow"; + } + + return weaponIconName switch + { + "sns" => "https://i.imgur.com/hVCDfnA.png", + "sns_green" => "https://i.imgur.com/U61zPJa.png", + "sns_red" => "https://i.imgur.com/ZGCd1lH.png", + "sns_pink" => "https://i.imgur.com/O4qyBfI.png", + "sns_blue" => "https://i.imgur.com/dQvflcw.png", + "sns_navy" => "https://i.imgur.com/vdeSnZh.png", + "sns_cyan" => "https://i.imgur.com/37gfP8P.png", + "sns_purple" => "https://i.imgur.com/x7dFt4G.png", + "sns_orange" => "https://i.imgur.com/bz22IiF.png", + "sns_yellow" => "https://i.imgur.com/wKItSbP.png", + "sns_grey" => "https://i.imgur.com/U25Xxfj.png", + "sns_rainbow" => "https://i.imgur.com/3a6OI1V.gif", + "ds" => "https://i.imgur.com/JIFNgz9.png", + "ds_green" => "https://i.imgur.com/MEWrHcC.png", + "ds_red" => "https://i.imgur.com/dzIoOF2.png", + "ds_pink" => "https://i.imgur.com/OfUVJy6.png", + "ds_blue" => "https://i.imgur.com/fUvIuCl.png", + "ds_navy" => "https://i.imgur.com/oPz7WAA.png", + "ds_cyan" => "https://i.imgur.com/Lkf6v4A.png", + "ds_purple" => "https://i.imgur.com/b5Ly09E.png", + "ds_orange" => "https://i.imgur.com/LdHWvui.png", + "ds_yellow" => "https://i.imgur.com/2A8UXdT.png", + "ds_grey" => "https://i.imgur.com/snw6dPs.png", + "ds_rainbow" => "https://i.imgur.com/eWTRTJl.gif", + "gs" => "https://i.imgur.com/vLxcWM8.png", + "gs_green" => "https://i.imgur.com/9puI44e.png", + "gs_red" => "https://i.imgur.com/Xhs5yJj.png", + "gs_pink" => "https://i.imgur.com/DXI9FHs.png", + "gs_blue" => "https://i.imgur.com/GxWofdH.png", + "gs_navy" => "https://i.imgur.com/ZM1Isqt.png", + "gs_cyan" => "https://i.imgur.com/tO2TrkB.png", + "gs_purple" => "https://i.imgur.com/ijgJ69Y.png", + "gs_orange" => "https://i.imgur.com/CWHEhAi.png", + "gs_yellow" => "https://i.imgur.com/ZpGOD3z.png", + "gs_grey" => "https://i.imgur.com/82HhSFD.png", + "gs_rainbow" => "https://i.imgur.com/WnRuqll.gif", + "ls" => "https://i.imgur.com/qdA0x3k.png", + "ls_green" => "https://i.imgur.com/9LvQVQ7.png", + "ls_red" => "https://i.imgur.com/oc0ExLi.png", + "ls_pink" => "https://i.imgur.com/jjBGbGu.png", + "ls_blue" => "https://i.imgur.com/AZ606vb.png", + "ls_navy" => "https://i.imgur.com/M6mmOpO.png", + "ls_cyan" => "https://i.imgur.com/qHFbpoJ.png", + "ls_purple" => "https://i.imgur.com/ICgTu6S.png", + "ls_orange" => "https://i.imgur.com/XPYDego.png", + "ls_yellow" => "https://i.imgur.com/H4vJFd1.png", + "ls_grey" => "https://i.imgur.com/1v7T5Hm.png", + "ls_rainbow" => "https://i.imgur.com/BUYVOih.gif", + "hammer" => "https://i.imgur.com/hnY1HC0.png", + "hammer_green" => "https://i.imgur.com/iOGBcmQ.png", + "hammer_red" => "https://i.imgur.com/Z5QGsTO.png", + "hammer_pink" => "https://i.imgur.com/WHkXOoC.png", + "hammer_blue" => "https://i.imgur.com/fb7bxlw.png", + "hammer_navy" => "https://i.imgur.com/oaLfSIP.png", + "hammer_cyan" => "https://i.imgur.com/N2N0Uib.png", + "hammer_purple" => "https://i.imgur.com/CqNUgtg.png", + "hammer_orange" => "https://i.imgur.com/PzYNYZh.png", + "hammer_yellow" => "https://i.imgur.com/Ujpj7WL.png", + "hammer_grey" => "https://i.imgur.com/R0xCYk5.png", + "hammer_rainbow" => "https://i.imgur.com/GIAbKkO.gif", + "hh" => "https://i.imgur.com/EmjAq37.png", + "hh_green" => "https://i.imgur.com/LWCOXI4.png", + "hh_red" => "https://i.imgur.com/lwtBV09.png", + "hh_pink" => "https://i.imgur.com/tZBuDi2.png", + "hh_blue" => "https://i.imgur.com/7qncIzQ.png", + "hh_navy" => "https://i.imgur.com/yaFS4N0.png", + "hh_cyan" => "https://i.imgur.com/GvHKg1u.png", + "hh_purple" => "https://i.imgur.com/33FpZMA.png", + "hh_orange" => "https://i.imgur.com/5ZHbR8K.png", + "hh_yellow" => "https://i.imgur.com/2YdtoVI.png", + "hh_grey" => "https://i.imgur.com/pyPzmJI.png", + "hh_rainbow" => "https://i.imgur.com/VuRLWWG.gif", + "lance" => "https://i.imgur.com/M8fmT4f.png", + "lance_green" => "https://i.imgur.com/zSyyIZY.png", + "lance_red" => "https://i.imgur.com/ZFeN3aA.png", + "lance_pink" => "https://i.imgur.com/X1EncHA.png", + "lance_blue" => "https://i.imgur.com/qMM2gqG.png", + "lance_navy" => "https://i.imgur.com/F7vp82x.png", + "lance_cyan" => "https://i.imgur.com/9q1rqfF.png", + "lance_purple" => "https://i.imgur.com/qF9JMEE.png", + "lance_orange" => "https://i.imgur.com/s1Agqri.png", + "lance_yellow" => "https://i.imgur.com/EcOCe50.png", + "lance_grey" => "https://i.imgur.com/jKPcLtN.png", + "lance_rainbow" => "https://i.imgur.com/BXgEuDy.gif", + "gl" => "https://i.imgur.com/9wq3LQe.png", + "gl_green" => "https://i.imgur.com/bQdGiiB.png", + "gl_red" => "https://i.imgur.com/QorzUm5.png", + "gl_pink" => "https://i.imgur.com/OqkXeZy.png", + "gl_blue" => "https://i.imgur.com/lsFZSnT.png", + "gl_navy" => "https://i.imgur.com/2fkkHVd.png", + "gl_cyan" => "https://i.imgur.com/MzqTO9c.png", + "gl_purple" => "https://i.imgur.com/QqDN0jm.png", + "gl_orange" => "https://i.imgur.com/GowSPSA.png", + "gl_yellow" => "https://i.imgur.com/az9QfWH.png", + "gl_grey" => "https://i.imgur.com/Q5lK9Nw.png", + "gl_rainbow" => "https://i.imgur.com/47VsWHj.gif", + "saf" => "https://i.imgur.com/fVbaN34.png", + "saf_green" => "https://i.imgur.com/V3x8aaf.png", + "saf_red" => "https://i.imgur.com/3l8TO9T.png", + "saf_pink" => "https://i.imgur.com/DTXXEb9.png", + "saf_blue" => "https://i.imgur.com/Dgr9oQg.png", + "saf_navy" => "https://i.imgur.com/Tv40lQg.png", + "saf_cyan" => "https://i.imgur.com/uKxiYhr.png", + "saf_purple" => "https://i.imgur.com/x3RC716.png", + "saf_orange" => "https://i.imgur.com/GU2eOdb.png", + "saf_yellow" => "https://i.imgur.com/f0jrcYq.png", + "saf_grey" => "https://i.imgur.com/jIRe9fA.png", + "saf_rainbow" => "https://i.imgur.com/icBF5lS.gif", + "tonfa" => "https://i.imgur.com/8YpLQ5G.png", + "tonfa_green" => "https://i.imgur.com/0VflTRd.png", + "tonfa_red" => "https://i.imgur.com/f5mIJgU.png", + "tonfa_pink" => "https://i.imgur.com/M6ANARX.png", + "tonfa_blue" => "https://i.imgur.com/BrCnJbs.png", + "tonfa_navy" => "https://i.imgur.com/b2lbCN1.png", + "tonfa_cyan" => "https://i.imgur.com/7bm8xyW.png", + "tonfa_purple" => "https://i.imgur.com/BOcCFhU.png", + "tonfa_orange" => "https://i.imgur.com/vi8qGs5.png", + "tonfa_yellow" => "https://i.imgur.com/qDR1aJZ.png", + "tonfa_grey" => "https://i.imgur.com/GxFrQm6.png", + "tonfa_rainbow" => "https://i.imgur.com/2StcKCZ.gif", + "ms" => "https://i.imgur.com/s3OaNkP.png", + "ms_green" => "https://i.imgur.com/7c8pPow.png", + "ms_red" => "https://i.imgur.com/zA4wMON.png", + "ms_pink" => "https://i.imgur.com/dOc22Dm.png", + "ms_blue" => "https://i.imgur.com/rz4anE4.png", + "ms_navy" => "https://i.imgur.com/dvghN1a.png", + "ms_cyan" => "https://i.imgur.com/gCWBOWm.png", + "ms_purple" => "https://i.imgur.com/UI3KO1c.png", + "ms_orange" => "https://i.imgur.com/9Bg0QzE.png", + "ms_yellow" => "https://i.imgur.com/rAKEtTa.png", + "ms_grey" => "https://i.imgur.com/dNkcRIR.png", + "ms_rainbow" => "https://i.imgur.com/TyZFrvK.gif", + "lbg" => "https://i.imgur.com/txp2GsM.png", + "lbg_green" => "https://i.imgur.com/CMf9U6x.png", + "lbg_red" => "https://i.imgur.com/aKLv0na.png", + "lbg_pink" => "https://i.imgur.com/theTGWy.png", + "lbg_blue" => "https://i.imgur.com/IgXj7vl.png", + "lbg_navy" => "https://i.imgur.com/N8vleIL.png", + "lbg_cyan" => "https://i.imgur.com/4iF0Kex.png", + "lbg_purple" => "https://i.imgur.com/V36MwUh.png", + "lbg_orange" => "https://i.imgur.com/FZ3sAAr.png", + "lbg_yellow" => "https://i.imgur.com/l0Fga4q.png", + "lbg_grey" => "https://i.imgur.com/WE1oZuG.png", + "lbg_rainbow" => "https://i.imgur.com/Q0Firpd.gif", + "hbg" => "https://i.imgur.com/8WD2bI7.png", + "hbg_green" => "https://i.imgur.com/j6qe1uh.png", + "hbg_red" => "https://i.imgur.com/hd8cwCa.png", + "hbg_pink" => "https://i.imgur.com/PDfABOO.png", + "hbg_blue" => "https://i.imgur.com/qURblCM.png", + "hbg_navy" => "https://i.imgur.com/FxInecI.png", + "hbg_cyan" => "https://i.imgur.com/UclnhBS.png", + "hbg_purple" => "https://i.imgur.com/IHifTBB.png", + "hbg_orange" => "https://i.imgur.com/7JRHNzp.png", + "hbg_yellow" => "https://i.imgur.com/rihlgaB.png", + "hbg_grey" => "https://i.imgur.com/mKpJc0p.png", + "hbg_rainbow" => "https://i.imgur.com/TgPORx6.gif", + "bow" => "https://i.imgur.com/haCsXQr.png", + "bow_green" => "https://i.imgur.com/vykrGg9.png", + "bow_red" => "https://i.imgur.com/01nEtNy.png", + "bow_pink" => "https://i.imgur.com/DLIYT8G.png", + "bow_blue" => "https://i.imgur.com/THX3O3X.png", + "bow_navy" => "https://i.imgur.com/DGHifcq.png", + "bow_cyan" => "https://i.imgur.com/sXnzQrG.png", + "bow_purple" => "https://i.imgur.com/D6NYg8r.png", + "bow_orange" => "https://i.imgur.com/fy47m6l.png", + "bow_yellow" => "https://i.imgur.com/ExGTxvl.png", + "bow_grey" => "https://i.imgur.com/Y5vOofE.png", + "bow_rainbow" => "https://i.imgur.com/rsEycVk.gif", + _ => "https://i.imgur.com/9OkLYAz.png",//transcend + }; + } + + //quest ids: + //mp road: 23527 + //solo road: 23628 + //1st district dure: 21731 + //2nd district dure: 21746 + //1st district dure sky corridor: 21749 + //2nd district dure sky corridor: 21750 + //arrogant dure repel: 23648 + //arrogant dure slay: 23649 + //urgent tower: 21751 + //4th district dure: 21748 + //3rd district dure: 21747 + //3rd district dure 2: 21734 + //UNUSED sky corridor: 21730 + //sky corridor prologue: 21729 + //raviente 62105 + //raviente carve 62108 + ///violent raviente 62101 + ///violent carve 62104 + //berserk slay practice 55796 + //berserk support practice 1 55802 + //berserk support practice 2 55803 + //berserk support practice 3 55804 + //berserk support practice 4 55805 + //berserk support practice 5 55806 + //berserk practice carve 55807 + //berserk slay 54751 + //berserk support 1 54756 + //berserk support 2 54757 + //berserk support 3 54758 + //berserk support 4 54759 + //berserk support 5 54760 + //berserk carve 54761 + //extreme slay (musou table 54) 55596 + //extreme support 1 55602 + //extreme support 2 55603 + //extreme support 3 55604 + //extreme support 4 55605 + //extreme support 5 55606 + //extreme carve 55607 + + const int MAX_DISCORD_RPC_STRING_LENGTH = 127; // or any other maximum length specified by Discord + + /// + /// Updates the discord RPC. + /// + public void UpdateDiscordRPC(DataLoader dataLoader) + { + if (!(isDiscordRPCRunning)) + { + return; + } + + // TODO also need to handle the other fields lengths + if (string.Format("{0}{1}{2}{3}{4}{5}", GetPartySize(dataLoader), GetQuestState(dataLoader), GetCaravanScore(dataLoader), dataLoader.model.GetOverlayModeForRPC(), dataLoader.model.GetAreaName(dataLoader.model.AreaID()), GetGameMode(dataLoader.isHighGradeEdition)).Length >= 95) + presenceTemplate.Details = string.Format("{0}{1}{2}", GetQuestState(dataLoader), dataLoader.model.GetOverlayModeForRPC(), dataLoader.model.GetAreaName(dataLoader.model.AreaID())); + else + presenceTemplate.Details = string.Format("{0}{1}{2}{3}{4}{5}", GetPartySize(dataLoader), GetQuestState(dataLoader), GetCaravanScore(dataLoader), dataLoader.model.GetOverlayModeForRPC(), dataLoader.model.GetAreaName(dataLoader.model.AreaID()), GetGameMode(dataLoader.isHighGradeEdition)); + + // TODO should this be outside UpdateDiscordRPC? + if (IsInHubAreaID(dataLoader) && dataLoader.model.QuestID() == 0) + dataLoader.model.PreviousHubAreaID = dataLoader.model.AreaID(); + + string stateString = ""; + string largeImageTextString = ""; + string smallImageTextString = ""; + + //Info + if ((dataLoader.model.QuestID() != 0 && dataLoader.model.TimeDefInt() != dataLoader.model.TimeInt() && int.Parse(dataLoader.model.ATK) > 0) || ((dataLoader.model.QuestID() == 21731 || dataLoader.model.QuestID() == 21746 || dataLoader.model.QuestID() == 21749 || dataLoader.model.QuestID() == 21750 || dataLoader.model.QuestID() == 23648 || dataLoader.model.QuestID() == 23649 || dataLoader.model.QuestID() == 21748 || dataLoader.model.QuestID() == 21747 || dataLoader.model.QuestID() == 21734) && int.Parse(dataLoader.model.ATK) > 0)) + { + switch (dataLoader.model.QuestID()) + { + case 23527:// Hunter's Road Multiplayer + stateString = String.Format("Multiplayer Floor: {0} ({1}/{2} Max/Total) | RP: {3} | White Fatalis: {4}/{5} (Slain/Encounters)", dataLoader.model.RoadFloor() + 1, dataLoader.model.RoadMaxStagesMultiplayer(), dataLoader.model.RoadTotalStagesMultiplayer(), dataLoader.model.RoadPoints(), dataLoader.model.RoadFatalisSlain(), dataLoader.model.RoadFatalisEncounters()); + presenceTemplate.State = stateString.Length <= MAX_DISCORD_RPC_STRING_LENGTH ? stateString : stateString.Substring(0, MAX_DISCORD_RPC_STRING_LENGTH - 3) + "..."; + break; + case 23628://solo road + stateString = String.Format("Solo Floor: {0} ({1}/{2} Max/Total) | RP: {3} | White Fatalis: {4}/{5} (Slain/Encounters)", dataLoader.model.RoadFloor() + 1, dataLoader.model.RoadMaxStagesSolo(), dataLoader.model.RoadTotalStagesSolo(), dataLoader.model.RoadPoints(), dataLoader.model.RoadFatalisSlain(), dataLoader.model.RoadFatalisEncounters()); + presenceTemplate.State = stateString.Length <= MAX_DISCORD_RPC_STRING_LENGTH ? stateString : stateString.Substring(0, MAX_DISCORD_RPC_STRING_LENGTH - 3) + "..."; + break; + case 21731://1st district dure + case 21749://sky corridor version + stateString = String.Format("{0}{1}{2}{3}{4}{5} | Slain: {6} | Encounters: {7}", dataLoader.model.GetQuestNameFromID(dataLoader.model.QuestID()), dataLoader.model.GetObjectiveNameFromID(dataLoader.model.ObjectiveType()), "", dataLoader.model.GetObjective1Quantity(), dataLoader.model.GetRankNameFromID(dataLoader.model.RankBand()), dataLoader.model.GetRealMonsterName(dataLoader.model.CurrentMonster1Icon), dataLoader.model.FirstDistrictDuremudiraSlays(), dataLoader.model.FirstDistrictDuremudiraEncounters()); + presenceTemplate.State = stateString.Length <= MAX_DISCORD_RPC_STRING_LENGTH ? stateString : stateString.Substring(0, MAX_DISCORD_RPC_STRING_LENGTH - 3) + "..."; + break; + case 21746://2nd district dure + case 21750://sky corridor version + stateString = String.Format("{0}{1}{2}{3}{4}{5} | Slain: {6} | Encounters: {7}", dataLoader.model.GetQuestNameFromID(dataLoader.model.QuestID()), dataLoader.model.GetObjectiveNameFromID(dataLoader.model.ObjectiveType()), "", dataLoader.model.GetObjective1Quantity(), dataLoader.model.GetRankNameFromID(dataLoader.model.RankBand()), dataLoader.model.GetRealMonsterName(dataLoader.model.CurrentMonster1Icon), dataLoader.model.SecondDistrictDuremudiraSlays(), dataLoader.model.SecondDistrictDuremudiraEncounters()); + presenceTemplate.State = stateString.Length <= MAX_DISCORD_RPC_STRING_LENGTH ? stateString : stateString.Substring(0, MAX_DISCORD_RPC_STRING_LENGTH - 3) + "..."; + break; + case 62105://raviente quests + case 62108: + case 62101: + case 62104: + case 55796: + case 55802: + case 55803: + case 55804: + case 55805: + case 55806: + case 55807: + case 54751: + case 54756: + case 54757: + case 54758: + case 54759: + case 54760: + case 54761: + case 55596://extreme + case 55602: + case 55603: + case 55604: + case 55605: + case 55606: + case 55607: + stateString = String.Format("{0}{1}{2}{3}{4}{5}{6} | True Raw: {7} (Max {8}) | Hits: {9}", dataLoader.model.GetQuestNameFromID(dataLoader.model.QuestID()), dataLoader.model.GetObjectiveNameFromID(dataLoader.model.ObjectiveType()), "", dataLoader.model.GetObjective1Quantity(), dataLoader.model.GetRankNameFromID(dataLoader.model.RankBand()), dataLoader.model.GetStarGrade(), dataLoader.model.GetRealMonsterName(dataLoader.model.CurrentMonster1Icon), dataLoader.model.ATK, dataLoader.model.HighestAtk, dataLoader.model.HitCountInt()); + presenceTemplate.State = stateString.Length <= MAX_DISCORD_RPC_STRING_LENGTH ? stateString : stateString.Substring(0, MAX_DISCORD_RPC_STRING_LENGTH - 3) + "..."; + + break; + default: + if ((dataLoader.model.ObjectiveType() == 0x0 || dataLoader.model.ObjectiveType() == 0x02 || dataLoader.model.ObjectiveType() == 0x1002 || dataLoader.model.ObjectiveType() == 0x10) && (dataLoader.model.QuestID() != 23527 && dataLoader.model.QuestID() != 23628 && dataLoader.model.QuestID() != 21731 && dataLoader.model.QuestID() != 21749 && dataLoader.model.QuestID() != 21746 && dataLoader.model.QuestID() != 21750)) + { + stateString = String.Format("{0}{1}{2}{3}{4}{5}{6} | True Raw: {7} (Max {8}) | Hits: {9}", dataLoader.model.GetQuestNameFromID(dataLoader.model.QuestID()), dataLoader.model.GetObjectiveNameFromID(dataLoader.model.ObjectiveType()), dataLoader.model.GetObjective1CurrentQuantity(), dataLoader.model.GetObjective1Quantity(), dataLoader.model.GetRankNameFromID(dataLoader.model.RankBand()), dataLoader.model.GetStarGrade(), dataLoader.model.GetObjective1Name(dataLoader.model.Objective1ID()), dataLoader.model.ATK, dataLoader.model.HighestAtk, dataLoader.model.HitCountInt()); + presenceTemplate.State = stateString.Length <= MAX_DISCORD_RPC_STRING_LENGTH ? stateString : stateString.Substring(0, MAX_DISCORD_RPC_STRING_LENGTH - 3) + "..."; + } + else + { + stateString = String.Format("{0}{1}{2}{3}{4}{5}{6} | True Raw: {7} (Max {8}) | Hits: {9}", dataLoader.model.GetQuestNameFromID(dataLoader.model.QuestID()), dataLoader.model.GetObjectiveNameFromID(dataLoader.model.ObjectiveType()), "", dataLoader.model.GetObjective1Quantity(), dataLoader.model.GetRankNameFromID(dataLoader.model.RankBand()), dataLoader.model.GetStarGrade(), dataLoader.model.GetRealMonsterName(dataLoader.model.CurrentMonster1Icon), dataLoader.model.ATK, dataLoader.model.HighestAtk, dataLoader.model.HitCountInt()); + presenceTemplate.State = stateString.Length <= MAX_DISCORD_RPC_STRING_LENGTH ? stateString : stateString.Substring(0, MAX_DISCORD_RPC_STRING_LENGTH - 3) + "..."; + } + break; + } + + //Gathering/etc + if ((dataLoader.model.ObjectiveType() == 0x0 || dataLoader.model.ObjectiveType() == 0x02 || dataLoader.model.ObjectiveType() == 0x1002) && (dataLoader.model.QuestID() != 23527 && dataLoader.model.QuestID() != 23628 && dataLoader.model.QuestID() != 21731 && dataLoader.model.QuestID() != 21749 && dataLoader.model.QuestID() != 21746 && dataLoader.model.QuestID() != 21750)) + { + largeImageTextString = string.Format("{0}{1}", GetQuestInformation(dataLoader), dataLoader.model.GetAreaName(dataLoader.model.AreaID())); + presenceTemplate.Assets.LargeImageKey = dataLoader.model.GetAreaIconFromID(dataLoader.model.AreaID()); + presenceTemplate.Assets.LargeImageText = largeImageTextString.Length <= MAX_DISCORD_RPC_STRING_LENGTH ? largeImageTextString : largeImageTextString.Substring(0, MAX_DISCORD_RPC_STRING_LENGTH - 3) + "..."; + } + //Tenrou Sky Corridor areas + else if (dataLoader.model.AreaID() == 391 || dataLoader.model.AreaID() == 392 || dataLoader.model.AreaID() == 394 || dataLoader.model.AreaID() == 415 || dataLoader.model.AreaID() == 416) + { + largeImageTextString = string.Format("{0}{1}", GetQuestInformation(dataLoader), dataLoader.model.GetAreaName(dataLoader.model.AreaID())); + presenceTemplate.Assets.LargeImageKey = dataLoader.model.GetAreaIconFromID(dataLoader.model.AreaID()); + presenceTemplate.Assets.LargeImageText = largeImageTextString.Length <= MAX_DISCORD_RPC_STRING_LENGTH ? largeImageTextString : largeImageTextString.Substring(0, MAX_DISCORD_RPC_STRING_LENGTH - 3) + "..."; + } + //Duremudira Doors + else if (dataLoader.model.AreaID() == 399 || dataLoader.model.AreaID() == 414) + { + presenceTemplate.Assets.LargeImageKey = dataLoader.model.GetAreaIconFromID(dataLoader.model.AreaID()); + largeImageTextString = string.Format("{0}{1}", GetQuestInformation(dataLoader), dataLoader.model.GetAreaName(dataLoader.model.AreaID())); + presenceTemplate.Assets.LargeImageText = largeImageTextString.Length <= MAX_DISCORD_RPC_STRING_LENGTH ? largeImageTextString : largeImageTextString.Substring(0, MAX_DISCORD_RPC_STRING_LENGTH - 3) + "..."; + } + //Duremudira Arena + else if (dataLoader.model.AreaID() == 398) + { + presenceTemplate.Assets.LargeImageKey = dataLoader.model.getMonsterIcon(dataLoader.model.LargeMonster1ID()); + largeImageTextString = string.Format("{0}{1}/{2}{3}", GetQuestInformation(dataLoader), dataLoader.model.GetMonster1EHP(), dataLoader.model.GetMonster1MaxEHP(), dataLoader.model.GetMonster1EHPPercent()); + presenceTemplate.Assets.LargeImageText = largeImageTextString.Length <= MAX_DISCORD_RPC_STRING_LENGTH ? largeImageTextString : largeImageTextString.Substring(0, MAX_DISCORD_RPC_STRING_LENGTH - 3) + "..."; + } + //Hunter's Road Base Camp + else if (dataLoader.model.AreaID() == 459) + { + presenceTemplate.Assets.LargeImageKey = dataLoader.model.GetAreaIconFromID(dataLoader.model.AreaID()); + largeImageTextString = string.Format("{0}{1} | Faints: {2}/{3}", GetQuestInformation(dataLoader), dataLoader.model.GetAreaName(dataLoader.model.AreaID()), dataLoader.model.CurrentFaints(), dataLoader.model.GetMaxFaints()); + presenceTemplate.Assets.LargeImageText = largeImageTextString.Length <= MAX_DISCORD_RPC_STRING_LENGTH ? largeImageTextString : largeImageTextString.Substring(0, MAX_DISCORD_RPC_STRING_LENGTH - 3) + "..."; + } + //Raviente + else if (dataLoader.model.AreaID() == 309 || (dataLoader.model.AreaID() >= 311 && dataLoader.model.AreaID() <= 321) || (dataLoader.model.AreaID() >= 417 && dataLoader.model.AreaID() <= 422) || dataLoader.model.AreaID() == 437 || (dataLoader.model.AreaID() >= 440 && dataLoader.model.AreaID() <= 444)) + { + presenceTemplate.Assets.LargeImageKey = dataLoader.model.getMonsterIcon(dataLoader.model.LargeMonster1ID()); + largeImageTextString = string.Format("{0}{1}/{2}{3} | Faints: {4}/{5} | Points: {6} | {7}", GetQuestInformation(dataLoader), dataLoader.model.GetMonster1EHP(), dataLoader.model.GetMonster1MaxEHP(), dataLoader.model.GetMonster1EHPPercent(), dataLoader.model.CurrentFaints(), dataLoader.model.GetMaxFaints(), dataLoader.model.GreatSlayingPoints(), GetRavienteEvent(dataLoader.model.RavienteTriggeredEvent(), dataLoader)); + presenceTemplate.Assets.LargeImageText = largeImageTextString.Length <= MAX_DISCORD_RPC_STRING_LENGTH ? largeImageTextString : largeImageTextString.Substring(0, MAX_DISCORD_RPC_STRING_LENGTH - 3) + "..."; + } + else + { + presenceTemplate.Assets.LargeImageKey = dataLoader.model.getMonsterIcon(dataLoader.model.LargeMonster1ID()); + largeImageTextString = string.Format("{0}{1}/{2}{3} | Faints: {4}/{5}", GetQuestInformation(dataLoader), dataLoader.model.GetMonster1EHP(), dataLoader.model.GetMonster1MaxEHP(), dataLoader.model.GetMonster1EHPPercent(), dataLoader.model.CurrentFaints(), dataLoader.model.GetMaxFaints()); + presenceTemplate.Assets.LargeImageText = largeImageTextString.Length <= MAX_DISCORD_RPC_STRING_LENGTH ? largeImageTextString : largeImageTextString.Substring(0, MAX_DISCORD_RPC_STRING_LENGTH - 3) + "..."; + } + } + else if (dataLoader.model.QuestID() == 0) + { + + switch (dataLoader.model.AreaID()) + { + case 0: //Loading + presenceTemplate.State = "Loading..."; + break; + case 87: //Kokoto Village + case 131: //Dundorma areas + case 132: + case 133: + case 134: + case 135: + case 136: + case 200: //Mezeporta + case 201://Hairdresser + case 206://Old Town Areas + case 207: + case 210://Private Bar + case 211://Rasta Bar + case 244://Code Claiming Room + case 282://Cities Map + case 340://SR Rooms + case 341: + case 397://Mezeporta Dupe(non-HD) + stateString = string.Format("GR: {0} | GCP: {1} | Guild Food: {2} | Diva Skill: {3} ({4} Left) | Poogie Item: {5}", dataLoader.model.GRankNumber(), dataLoader.model.GCP(), dataLoader.model.GetArmorSkillWithNull(dataLoader.model.GuildFoodSkill()), dataLoader.model.GetDivaSkillNameFromID(dataLoader.model.DivaSkill()), dataLoader.model.DivaSkillUsesLeft(), dataLoader.model.GetItemName(dataLoader.model.PoogieItemUseID())); + presenceTemplate.State = stateString.Length <= MAX_DISCORD_RPC_STRING_LENGTH ? stateString : stateString.Substring(0, MAX_DISCORD_RPC_STRING_LENGTH - 3) + "..."; + break; + case 173:// My House (original) + case 175://My House (MAX) + stateString = string.Format("GR: {0} | Partner Lv: {1} | Armor Color: {2} | GCP: {3}", dataLoader.model.GRankNumber(), dataLoader.model.PartnerLevel(), dataLoader.model.GetArmorColor(), dataLoader.model.GCP()); + presenceTemplate.State = stateString.Length <= MAX_DISCORD_RPC_STRING_LENGTH ? stateString : stateString.Substring(0, MAX_DISCORD_RPC_STRING_LENGTH - 3) + "..."; + break; + case 202://Guild Halls + case 203: + case 204: + stateString = string.Format("GR: {0} | GCP: {1} | Guild Food: {2} | Poogie Item: {3}", dataLoader.model.GRankNumber(), dataLoader.model.GCP(), dataLoader.model.GetArmorSkill(dataLoader.model.GuildFoodSkill()), dataLoader.model.GetItemName(dataLoader.model.PoogieItemUseID())); + presenceTemplate.State = stateString.Length <= MAX_DISCORD_RPC_STRING_LENGTH ? stateString : stateString.Substring(0, MAX_DISCORD_RPC_STRING_LENGTH - 3) + "..."; + break; + case 205://Pugi Farm + stateString = string.Format("GR: {0} | Poogie Points: {1} | Poogie Clothes: {2} | Poogie Item: {3}", dataLoader.model.GRankNumber(), dataLoader.model.PoogiePoints(), dataLoader.model.GetPoogieClothes(dataLoader.model.PoogieCostume()), dataLoader.model.GetItemName(dataLoader.model.PoogieItemUseID())); + presenceTemplate.State = stateString.Length <= MAX_DISCORD_RPC_STRING_LENGTH ? stateString : stateString.Substring(0, MAX_DISCORD_RPC_STRING_LENGTH - 3) + "..."; + break; + case 256://Caravan Areas + case 260: + case 261: + case 262: + case 263: + stateString = string.Format("CP: {0} | Gg: {1} | g: {2} | Gem Lv: {3} | Great Slaying Points: {4}", dataLoader.model.CaravanPoints(), dataLoader.model.RaviGg(), dataLoader.model.Ravig(), dataLoader.model.CaravenGemLevel() + 1, dataLoader.model.GreatSlayingPointsSaved()); + presenceTemplate.State = stateString.Length <= MAX_DISCORD_RPC_STRING_LENGTH ? stateString : stateString.Substring(0, MAX_DISCORD_RPC_STRING_LENGTH - 3) + "..."; + break; + case 257://Blacksmith + stateString = string.Format("GR: {0} | GCP: {1} | Guild Food: {2} | GZenny: {3}", dataLoader.model.GRankNumber(), dataLoader.model.GCP(), dataLoader.model.GetArmorSkill(dataLoader.model.GuildFoodSkill()), dataLoader.model.GZenny()); + presenceTemplate.State = stateString.Length <= MAX_DISCORD_RPC_STRING_LENGTH ? stateString : stateString.Substring(0, MAX_DISCORD_RPC_STRING_LENGTH - 3) + "..."; + break; + case 264://Gallery + stateString = string.Format("GR: {0} | GCP: {1} | Guild Food: {2} | Score: {3}", dataLoader.model.GRankNumber(), dataLoader.model.GCP(), dataLoader.model.GetArmorSkill(dataLoader.model.GuildFoodSkill()), dataLoader.model.GalleryEvaluationScore()); + presenceTemplate.State = stateString.Length <= MAX_DISCORD_RPC_STRING_LENGTH ? stateString : stateString.Substring(0, MAX_DISCORD_RPC_STRING_LENGTH - 3) + "..."; + break; + case 265://Guuku Farm + stateString = string.Format("GR: {0} | GCP: {1} | Guild Food: {2} | Poogie Item: {3}", dataLoader.model.GRankNumber(), dataLoader.model.GCP(), dataLoader.model.GetArmorSkill(dataLoader.model.GuildFoodSkill()), dataLoader.model.GetItemName(dataLoader.model.PoogieItemUseID())); + presenceTemplate.State = stateString.Length <= MAX_DISCORD_RPC_STRING_LENGTH ? stateString : stateString.Substring(0, MAX_DISCORD_RPC_STRING_LENGTH - 3) + "..."; + break; + case 283://Halk Area TODO partnya lv + stateString = string.Format("GR: {0} | GCP: {1} | PNRP: {2} | Halk Fullness: {3}", dataLoader.model.GRankNumber(), dataLoader.model.GCP(), dataLoader.model.PartnyaRankPoints(), dataLoader.model.HalkFullness()); + presenceTemplate.State = stateString.Length <= MAX_DISCORD_RPC_STRING_LENGTH ? stateString : stateString.Substring(0, MAX_DISCORD_RPC_STRING_LENGTH - 3) + "..."; + break; + case 286://PvP Room + stateString = string.Format("GR: {0} | GCP: {1} | Guild Food: {2} | Poogie Item: {3}", dataLoader.model.GRankNumber(), dataLoader.model.GCP(), dataLoader.model.GetArmorSkill(dataLoader.model.GuildFoodSkill()), dataLoader.model.GetItemName(dataLoader.model.PoogieItemUseID())); + presenceTemplate.State = stateString.Length <= MAX_DISCORD_RPC_STRING_LENGTH ? stateString : stateString.Substring(0, MAX_DISCORD_RPC_STRING_LENGTH - 3) + "..."; + break; + case 379://Diva Hall + case 445: + stateString = string.Format("GR: {0} | Diva Skill: {1} ({2} Left) | Diva Bond: {3} | Items Given: {4}", dataLoader.model.GRankNumber(), dataLoader.model.GetDivaSkillNameFromID(dataLoader.model.DivaSkill()), dataLoader.model.DivaSkillUsesLeft(), dataLoader.model.DivaBond(), dataLoader.model.DivaItemsGiven()); + presenceTemplate.State = stateString.Length <= MAX_DISCORD_RPC_STRING_LENGTH ? stateString : stateString.Substring(0, MAX_DISCORD_RPC_STRING_LENGTH - 3) + "..."; + break; + case 462://MezFez Entrance + case 463: //Volpkun Together + case 465://MezFez Minigame + stateString = string.Format("GR: {0} | MezFes Points: {1} | Guild Food: {2} | Poogie Item: {3}", dataLoader.model.GRankNumber(), dataLoader.model.MezeportaFestivalPoints(), dataLoader.model.GetArmorSkill(dataLoader.model.GuildFoodSkill()), dataLoader.model.GetItemName(dataLoader.model.PoogieItemUseID())); + presenceTemplate.State = stateString.Length <= MAX_DISCORD_RPC_STRING_LENGTH ? stateString : stateString.Substring(0, MAX_DISCORD_RPC_STRING_LENGTH - 3) + "..."; + break; + case 464://Uruki Pachinko + stateString = string.Format("Score: {0} | Chain: {1} | Fish: {2} | Mushroom: {3} | Seed: {4} | Meat: {5}", dataLoader.model.UrukiPachinkoScore() + dataLoader.model.UrukiPachinkoBonusScore(), dataLoader.model.UrukiPachinkoChain(), dataLoader.model.UrukiPachinkoFish(), dataLoader.model.UrukiPachinkoMushroom(), dataLoader.model.UrukiPachinkoSeed(), dataLoader.model.UrukiPachinkoMeat()); + presenceTemplate.State = stateString.Length <= MAX_DISCORD_RPC_STRING_LENGTH ? stateString : stateString.Substring(0, MAX_DISCORD_RPC_STRING_LENGTH - 3) + "..."; + break; + case 466://Guuku Scoop + stateString = string.Format("Score: {0} | Small Guuku: {1} | Medium Guuku: {2} | Large Guuku: {3} | Golden Guuku: {4}", dataLoader.model.GuukuScoopScore(), dataLoader.model.GuukuScoopSmall(), dataLoader.model.GuukuScoopMedium(), dataLoader.model.GuukuScoopLarge(), dataLoader.model.GuukuScoopGolden()); + presenceTemplate.State = stateString.Length <= MAX_DISCORD_RPC_STRING_LENGTH ? stateString : stateString.Substring(0, MAX_DISCORD_RPC_STRING_LENGTH - 3) + "..."; + break; + case 467://Nyanrendo + stateString = string.Format("Score: {0}", dataLoader.model.NyanrendoScore()); + presenceTemplate.State = stateString.Length <= MAX_DISCORD_RPC_STRING_LENGTH ? stateString : stateString.Substring(0, MAX_DISCORD_RPC_STRING_LENGTH - 3) + "..."; + break; + case 468://Panic Honey + stateString = string.Format("Honey: {0}", dataLoader.model.PanicHoneyScore()); + presenceTemplate.State = stateString.Length <= MAX_DISCORD_RPC_STRING_LENGTH ? stateString : stateString.Substring(0, MAX_DISCORD_RPC_STRING_LENGTH - 3) + "..."; + break; + case 469://Dokkan Battle Cats + stateString = string.Format("Score: {0} | Scale: {1} | Shell: {2} | Camp: {3}", dataLoader.model.DokkanBattleCatsScore(), dataLoader.model.DokkanBattleCatsScale(), dataLoader.model.DokkanBattleCatsShell(), dataLoader.model.DokkanBattleCatsCamp()); + presenceTemplate.State = stateString.Length <= MAX_DISCORD_RPC_STRING_LENGTH ? stateString : stateString.Substring(0, MAX_DISCORD_RPC_STRING_LENGTH - 3) + "..."; + break; + default: //same as Mezeporta + stateString = string.Format("GR: {0} | GCP: {1} | Guild Food: {2} | Poogie Item: {3}", dataLoader.model.GRankNumber(), dataLoader.model.GCP(), dataLoader.model.GetArmorSkill(dataLoader.model.GuildFoodSkill()), dataLoader.model.GetItemName(dataLoader.model.PoogieItemUseID())); + presenceTemplate.State = stateString.Length <= MAX_DISCORD_RPC_STRING_LENGTH ? stateString : stateString.Substring(0, MAX_DISCORD_RPC_STRING_LENGTH - 3) + "..."; + break; + } + + presenceTemplate.Assets.LargeImageKey = dataLoader.model.GetAreaIconFromID(dataLoader.model.AreaID()); + largeImageTextString = dataLoader.model.GetAreaName(dataLoader.model.AreaID()); + presenceTemplate.Assets.LargeImageText = largeImageTextString.Length <= MAX_DISCORD_RPC_STRING_LENGTH ? largeImageTextString : largeImageTextString.Substring(0, MAX_DISCORD_RPC_STRING_LENGTH - 3) + "..."; + } + + //Timer + if ((dataLoader.model.QuestID() != 0 && !dataLoader.model.inQuest && dataLoader.model.TimeDefInt() > dataLoader.model.TimeInt() && int.Parse(dataLoader.model.ATK) > 0) || (dataLoader.model.IsRoad() || dataLoader.model.IsDure())) + { + dataLoader.model.inQuest = true; + + if (!(dataLoader.model.IsRoad() || dataLoader.model.IsDure())) + { + presenceTemplate.Timestamps = GetDiscordTimerMode() switch + { + "Time Left" => Timestamps.FromTimeSpan((double)dataLoader.model.TimeDefInt() / 30.0), + "Time Elapsed" => Timestamps.Now, + //dure doorway too + _ => Timestamps.FromTimeSpan((double)dataLoader.model.TimeDefInt() / 30.0), + }; + } + + if (dataLoader.model.IsRoad()) + { + switch (GetRoadTimerResetMode()) + { + case "Always": + if (dataLoader.model.AreaID() == 458)//Hunter's Road Area 1 + { + break; + } + + else if (dataLoader.model.AreaID() == 459)//Hunter's Road Base Camp + { + if (dataLoader.model.RoadFloor() + 1 > dataLoader.model.previousRoadFloor) + { + // reset values + dataLoader.model.inQuest = false; + dataLoader.model.currentMonster1MaxHP = 0; + //dataLoader.model.previousRoadFloor = dataLoader.model.RoadFloor() + 1; + presenceTemplate.Timestamps = GetDiscordTimerMode() switch + { + "Time Left" => Timestamps.FromTimeSpan((double)dataLoader.model.TimeInt() / 30.0), + "Time Elapsed" => Timestamps.Now, + _ => Timestamps.FromTimeSpan((double)dataLoader.model.TimeInt() / 30.0), + }; + } + break; + } + else + { + break; + } + case "Never": + if (dataLoader.model.AreaID() == 458)//Hunter's Road Area 1 + { + break; + } + + else if (dataLoader.model.AreaID() == 459)//Hunter's Road Base Camp + { + if (dataLoader.model.RoadFloor() + 1 > dataLoader.model.previousRoadFloor) + { + // reset values + dataLoader.model.inQuest = false; + dataLoader.model.currentMonster1MaxHP = 0; + //dataLoader.model.previousRoadFloor = dataLoader.model.RoadFloor() + 1; + + if (!(StartedRoadElapsedTime)) + { + StartedRoadElapsedTime = true; + presenceTemplate.Timestamps = Timestamps.Now; + } + } + break; + } + else + { + break; + } + default: + if (dataLoader.model.AreaID() == 458)//Hunter's Road Area 1 + { + break; + } + + else if (dataLoader.model.AreaID() == 459)//Hunter's Road Base Camp + { + if (dataLoader.model.RoadFloor() + 1 > dataLoader.model.previousRoadFloor) + { + // reset values + dataLoader.model.inQuest = false; + dataLoader.model.currentMonster1MaxHP = 0; + //dataLoader.model.previousRoadFloor = dataLoader.model.RoadFloor() + 1; + + if (!(StartedRoadElapsedTime)) + { + StartedRoadElapsedTime = true; + presenceTemplate.Timestamps = Timestamps.Now; + } + } + break; + } + else + { + break; + } + } + } + + if (dataLoader.model.IsDure()) + { + + switch (dataLoader.model.AreaID()) + { + case 398://Duremudira Arena + + if (!(inDuremudiraArena)) + { + inDuremudiraArena = true; + + if (dataLoader.model.QuestID() == 23649)//Arrogant Dure Slay + { + presenceTemplate.Timestamps = GetDiscordTimerMode() switch + { + "Time Left" => Timestamps.FromTimeSpan(600), + "Time Elapsed" => Timestamps.Now, + _ => Timestamps.FromTimeSpan(600), + }; + + } + else + { + presenceTemplate.Timestamps = GetDiscordTimerMode() switch + { + "Time Left" => Timestamps.FromTimeSpan(1200), + "Time Elapsed" => Timestamps.Now, + _ => Timestamps.FromTimeSpan(1200), + }; + } + } + break; + + default: + if (!(inDuremudiraDoorway)) + { + inDuremudiraDoorway = true; + presenceTemplate.Timestamps = Timestamps.Now; + } + break; + } + } + } + // going back to Mezeporta or w/e + else if (dataLoader.model.QuestState() != 1 && dataLoader.model.QuestID() == 0 && dataLoader.model.inQuest && int.Parse(dataLoader.model.ATK) == 0) + { + //reset values + dataLoader.model.inQuest = false; + dataLoader.model.currentMonster1MaxHP = 0; + //dataLoader.model.previousRoadFloor = 0; + StartedRoadElapsedTime = false; + inDuremudiraArena = false; + inDuremudiraDoorway = false; + + presenceTemplate.Timestamps = Timestamps.Now; + } + + //SmallInfo + presenceTemplate.Assets.SmallImageKey = GetWeaponIconFromID(dataLoader.model.WeaponType(), dataLoader); + + if (GetHunterName != "" && GetGuildName != "" && GetServerName != "") + { + smallImageTextString = String.Format("{0} | {1} | {2} | GSR: {3} | {4} Style | Caravan Skills: {5}", GetHunterName, GetGuildName, GetServerName, dataLoader.model.GSR(), dataLoader.model.GetWeaponStyleFromID(dataLoader.model.WeaponStyle()), dataLoader.model.GetCaravanSkillsWithoutMarkdown(dataLoader)); + presenceTemplate.Assets.SmallImageText = smallImageTextString.Length <= MAX_DISCORD_RPC_STRING_LENGTH ? smallImageTextString : smallImageTextString.Substring(0, MAX_DISCORD_RPC_STRING_LENGTH - 3) + "..."; + } + + discordRPCClient.SetPresence(presenceTemplate); + } + + #endregion + } +} diff --git a/MHFZ_Overlay/Core/Class/Log/LoggingManager.cs b/MHFZ_Overlay/Core/Class/Log/LoggingManager.cs index 402293ca..6d775a6b 100644 --- a/MHFZ_Overlay/Core/Class/Log/LoggingManager.cs +++ b/MHFZ_Overlay/Core/Class/Log/LoggingManager.cs @@ -30,9 +30,10 @@ public static void WriteCrashLog(Exception ex, string logMessage = "Program cras System.Windows.MessageBox.Show(@"Fatal error, closing overlay. See the crash log in the overlay\logs folder for more information.", FATAL_TITLE, System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Error); logger.Fatal(ex, logMessage); PromptForOpeningLogs(); + ApplicationManager.HandleShutdown(); } - public static void PromptForOpeningLogs() + private static void PromptForOpeningLogs() { var logFilePath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "logs", "logs.log"); @@ -58,8 +59,6 @@ public static void PromptForOpeningLogs() System.Windows.MessageBox.Show("Could not open the log file: " + ex.Message, LoggingManager.ERROR_TITLE, MessageBoxButton.OK, MessageBoxImage.Error); } } - - ApplicationManager.HandleShutdown(); } } } diff --git a/MHFZ_Overlay/DataLoader.cs b/MHFZ_Overlay/DataLoader.cs index 46773dc5..616bae00 100644 --- a/MHFZ_Overlay/DataLoader.cs +++ b/MHFZ_Overlay/DataLoader.cs @@ -63,8 +63,7 @@ private static void RestoreSettings() // this loads first before MainWindow constructor is called. meaning this runs twice. public DataLoader() { - Debug.WriteLine("DataLoader constructor called. Call stack:"); - Debug.WriteLine(new StackTrace().ToString()); + logger.Trace("DataLoader constructor called. Call stack: {0}", new StackTrace().ToString()); // run Squirrel first, as the app may exit after these run SquirrelAwareApp.HandleEvents( @@ -351,7 +350,7 @@ The overlay might take some time to start due to databases. Happy Hunting!", "MHF-Z Overlay Installation", MessageBoxButton.OK, MessageBoxImage.Information); } - readonly DatabaseManager databaseManager = DatabaseManager.GetInstance(); + private static readonly DatabaseManager databaseManager = DatabaseManager.GetInstance(); /// /// Creates the code cave. diff --git a/MHFZ_Overlay/MainWindow.xaml.cs b/MHFZ_Overlay/MainWindow.xaml.cs index 52c83ca3..cf9f74ab 100644 --- a/MHFZ_Overlay/MainWindow.xaml.cs +++ b/MHFZ_Overlay/MainWindow.xaml.cs @@ -7,6 +7,7 @@ using LiveChartsCore.SkiaSharpView.Painting; using Memory; using MHFZ_Overlay.Core.Class.Application; +using MHFZ_Overlay.Core.Class.Discord; using MHFZ_Overlay.Core.Class.Log; using MHFZ_Overlay.UI.Class; using Microsoft.Extensions.DependencyModel; @@ -60,6 +61,10 @@ public partial class MainWindow : Window public DataLoader DataLoader { get; set; } private static readonly NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger(); + private static readonly DatabaseManager databaseManager = DatabaseManager.GetInstance(); + private static readonly DiscordManager discordManager = DiscordManager.GetInstance(); + + private readonly Mem m = new(); #region system tray @@ -129,7 +134,7 @@ protected override void OnSourceInitialized(EventArgs e) public const int GWL_EXSTYLE = (-20); /// - /// The current program version + /// The current program version. TODO: put in env var /// public const string CurrentProgramVersion = "v0.22.0"; @@ -141,221 +146,6 @@ protected override void OnSourceInitialized(EventArgs e) #endregion - // TODO add discord manager class - #region discord rpc - - /// - /// Gets the client. - /// - /// - /// The client. - /// - public static DiscordRpcClient discordRPCClient; - - //Called when your application first starts. - //For example, just before your main loop, on OnEnable for unity. - void SetupDiscordRPC() - { - /* - Create a Discord client - NOTE: If you are using Unity3D, you must use the full constructor and define - the pipe connection. - */ - discordRPCClient = new DiscordRpcClient(GetDiscordClientID); - - //Set the logger - - //Subscribe to events - - //Connect to the RPC - discordRPCClient.Initialize(); - - //Set the rich presence - //Call this as many times as you want and anywhere in your code. - - } - - /// - /// Gets a value indicating whether [show discord RPC]. - /// - /// - /// true if [show discord RPC]; otherwise, false. - /// - public static bool ShowDiscordRPC - { - get - { - Settings s = (Settings)Application.Current.TryFindResource("Settings"); - if (s.EnableRichPresence) - return true; - else - return false; - } - } - - /// - /// Gets the discord client identifier. - /// - /// - /// The discord client identifier. - /// - public static string GetDiscordClientID - { - get - { - Settings s = (Settings)Application.Current.TryFindResource("Settings"); - if (s.DiscordClientID.Length == 19) - return s.DiscordClientID; - else - return ""; - } - } - - /// - /// Gets the discord server invite. - /// - /// - /// The discord server invite. - /// - public static string GetDiscordServerInvite - { - get - { - Settings s = (Settings)Application.Current.TryFindResource("Settings"); - if (s.DiscordServerInvite.Length >= 8) - return s.DiscordServerInvite; - else - return ""; - } - } - - /// - /// Gets the name of the hunter. - /// - /// - /// The name of the hunter. - /// - public static string GetHunterName - { - get - { - Settings s = (Settings)Application.Current.TryFindResource("Settings"); - if (s.HunterName.Length >= 1) - return s.HunterName; - else - return "Hunter Name"; - } - } - - /// - /// Gets the name of the guild. - /// - /// - /// The name of the guild. - /// - public static string GetGuildName - { - get - { - Settings s = (Settings)Application.Current.TryFindResource("Settings"); - if (s.GuildName.Length >= 1) - return s.GuildName; - else - return "Guild Name"; - } - } - - public static string GetServerName - { - get - { - Settings s = (Settings)Application.Current.TryFindResource("Settings"); - bool serverNameFound = Dictionary.DiscordServersList.DiscordServerID.TryGetValue(s.DiscordServerID, out string? value); - if (serverNameFound) - return value; - else - return "Unknown Server"; - } - } - - /// - /// The current presence to send to discord. - /// - private RichPresence presenceTemplate = new RichPresence() - { - Details = "【MHF-Z】Overlay " + CurrentProgramVersion, - State = "Loading...", - //check img folder - Assets = new Assets() - { - LargeImageKey = "cattleya", - LargeImageText = "Please Wait", - SmallImageKey = "https://i.imgur.com/9OkLYAz.png", - SmallImageText = "Hunter Name | Guild Name" - }, - Buttons = new DiscordRPC.Button[] - { - new DiscordRPC.Button() {Label = "【MHF-Z】Overlay "+CurrentProgramVersion, Url = "https://github.com/DorielRivalet/mhfz-overlay"}, - new DiscordRPC.Button() { Label = "Discord RPC C# Dev Site", Url = "https://lachee.dev/" } - } - }; - - /// - /// Is the main loop currently running? - /// - private bool isDiscordRPCRunning = false; - - /// - /// Initializes the discord RPC. - /// - private void InitializeDiscordRPC() - { - if (isDiscordRPCRunning) - return; - - if (ShowDiscordRPC && GetDiscordClientID != "") - { - SetupDiscordRPC(); - - //Set Presence - presenceTemplate.Timestamps = Timestamps.Now; - - if (GetHunterName != "" && GetGuildName != "" && GetServerName != "") - { - presenceTemplate.Assets = new Assets() - { - LargeImageKey = "cattleya", - LargeImageText = "Please Wait", - SmallImageKey = "https://i.imgur.com/9OkLYAz.png", - SmallImageText = GetHunterName + " | " + GetGuildName + " | " + GetServerName - }; - } - - //should work fine - presenceTemplate.Buttons = new DiscordRPC.Button[] { }; - presenceTemplate.Buttons = new DiscordRPC.Button[] - { - new DiscordRPC.Button() {Label = "【MHF-Z】Overlay "+CurrentProgramVersion, Url = "https://github.com/DorielRivalet/mhfz-overlay"}, - new DiscordRPC.Button() { Label = "Discord RPC C# Dev Site", Url = "https://lachee.dev/" } - }; - - if (GetDiscordServerInvite != "") - { - presenceTemplate.Buttons = new DiscordRPC.Button[] { }; - presenceTemplate.Buttons = new DiscordRPC.Button[] - { - new DiscordRPC.Button() {Label = "【MHF-Z】Overlay "+CurrentProgramVersion, Url = "https://github.com/DorielRivalet/mhfz-overlay"}, - new DiscordRPC.Button() { Label = "Join Discord Server", Url = String.Format("https://discord.com/invite/{0}",GetDiscordServerInvite)} - }; - } - - discordRPCClient.SetPresence(presenceTemplate); - isDiscordRPCRunning = true; - } - } - - #endregion - #region main public DateTime ProgramStart; @@ -388,6 +178,7 @@ public MainWindow() InitializeComponent(); logger.Info($"MainWindow initialized"); + logger.Trace(new StackTrace().ToString()); Left = 0; Top = 0; @@ -406,7 +197,7 @@ public MainWindow() ReloadButton.Visibility = Visibility.Hidden; CloseButton.Visibility = Visibility.Hidden; - InitializeDiscordRPC(); + DiscordManager.InitializeDiscordRPC(); CheckGameState(); _ = LoadOctoKit(); @@ -562,8 +353,6 @@ private static void OpenLink(string destinationurl) System.Diagnostics.Process.Start(sInfo); } - readonly DatabaseManager databaseManager = DatabaseManager.GetInstance(); - /// /// Checks the state of the game. /// @@ -615,7 +404,6 @@ public void CheckGameState() logger.Info("Detected closed game"); //https://stackoverflow.com/a/9050477/18859245 - ApplicationManager.DiscordRPCCleanup(); ApplicationManager.HandleShutdown(); } else @@ -652,7 +440,7 @@ public void Timer_Tick(object? obj, EventArgs e) CreateDamageNumber(); - UpdateDiscordRPC(); + discordManager.UpdateDiscordRPC(DataLoader); CheckQuestStateForDatabaseLogging(); @@ -1216,1279 +1004,7 @@ private void SetPlayerStatsVisibility(bool v, Settings s) #region get info - /// - /// Gets the caravan score. - /// - /// - public string GetCaravanScore() - { - if (ShowCaravanScore()) - return string.Format("Caravan Score: {0} | ", DataLoader.model.CaravanScore()); - else - return ""; - } - - public static bool ShowCaravanScore() - { - Settings s = (Settings)Application.Current.TryFindResource("Settings"); - if (s.EnableCaravanScore) - return true; - else - return false; - } - - /// - /// Gets the caravan skills. - /// - /// - public string GetCaravanSkills() - { - int id1 = DataLoader.model.CaravanSkill1(); - int id2 = DataLoader.model.CaravanSkill2(); - int id3 = DataLoader.model.CaravanSkill3(); - - Dictionary.CaravanSkillList.CaravanSkillID.TryGetValue(id1, out string? caravanSkillName1); - Dictionary.CaravanSkillList.CaravanSkillID.TryGetValue(id2, out string? caravanSkillName2); - Dictionary.CaravanSkillList.CaravanSkillID.TryGetValue(id3, out string? caravanSkillName3); - - if (caravanSkillName1 == "" || caravanSkillName1 == "None") - return "None"; - else if (caravanSkillName2 == "" || caravanSkillName2 == "None") - return caravanSkillName1 + ""; - else if (caravanSkillName3 == "" || caravanSkillName3 == "None") - return caravanSkillName1 + ", " + caravanSkillName2; - else - return caravanSkillName1 + ", " + caravanSkillName2 + ", " + caravanSkillName3; - } - /// - /// Gets the diva skill name from identifier. - /// - /// The identifier. - /// - public static string GetDivaSkillNameFromID(int id) - { - Dictionary.DivaSkillList.DivaSkillID.TryGetValue(id, out string? divaskillaname); - return divaskillaname + ""; - } - - /// - /// Gets the discord timer mode. - /// - /// - public static string GetDiscordTimerMode() - { - Settings s = (Settings)Application.Current.TryFindResource("Settings"); - if (s.DiscordTimerMode == "Time Left") - return "Time Left"; - else if (s.DiscordTimerMode == "Time Elapsed") - return "Time Elapsed"; - else return "Time Left"; - } - - /// - /// Gets the weapon style from identifier. - /// - /// The identifier. - /// - public static string GetWeaponStyleFromID(int id) - { - return id switch - { - 0 => "Earth", - 1 => "Heaven", - 2 => "Storm", - 3 => "Extreme", - _ => "None", - }; - } - - /// - /// Gets the armor skill. - /// - /// The identifier. - /// - public static string getArmorSkill(int id) - { - Dictionary.ArmorSkillList.ArmorSkillID.TryGetValue(id, out string? skillname); - if (skillname == "") - return "None"; - else - return skillname + ""; - } - - /// - /// Gets the name of the item. - /// - /// The identifier. - /// - public static string GetItemName(int id) - { - string itemValue1; -#pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type. - Dictionary.Items.ItemIDs.TryGetValue(id, out itemValue1); //returns true -#pragma warning restore CS8600 // Converting null literal or possible null value to non-nullable type. - - return itemValue1 + ""; - } - - /// - /// Gets the weapon name from identifier. - /// - /// The identifier. - /// - public static string getWeaponNameFromID(int id) - { - Dictionary.WeaponTypes.WeaponTypeID.TryGetValue(id, out string? weaponname); - return weaponname + ""; - } - - /// - /// Gets the color of the armor. - /// - /// - public string getArmorColor() - { - Dictionary.ArmorColorList.ArmorColorID.TryGetValue(DataLoader.model.ArmorColor(), out string? colorname); - return colorname + ""; - } - - /// - /// Gets the weapon icon from identifier. - /// - /// The identifier. - /// - public string getWeaponIconFromID(int id) - { - string weaponName = getWeaponNameFromID(id); - string colorName = getArmorColor(); - - string weaponIconName = ""; - - switch (weaponName) - { - case "Sword and Shield": - weaponIconName += "sns"; - break; - case "Dual Swords": - weaponIconName += "ds"; - break; - case "Great Sword": - weaponIconName += "gs"; - break; - case "Long Sword": - weaponIconName += "ls"; - break; - case "Hammer": - weaponIconName += "hammer"; - break; - case "Hunting Horn": - weaponIconName += "hh"; - break; - case "Lance": - weaponIconName += "lance"; - break; - case "Gunlance": - weaponIconName += "gl"; - break; - case "Switch Axe F": - weaponIconName += "saf"; - break; - case "Tonfa": - weaponIconName += "tonfa"; - break; - case "Magnet Spike": - weaponIconName += "ms"; - break; - case "Light Bowgun": - weaponIconName += "lbg"; - break; - case "Heavy Bowgun": - weaponIconName += "hbg"; - break; - case "Bow": - weaponIconName += "bow"; - break; - default: - weaponIconName = "https://i.imgur.com/9OkLYAz.png";//transcend - break; - } - - if (weaponIconName != "https://i.imgur.com/9OkLYAz.png" && !(colorName.Contains("White"))) - weaponIconName += "_"; - - if (colorName.Contains("Green")) - { - weaponIconName += "green"; - } - else if (colorName.Contains("Red")) - { - weaponIconName += "red"; - } - - else if (colorName.Contains("Pink")) - { - weaponIconName += "pink"; - } - else if (colorName.Contains("Blue")) - { - weaponIconName += "blue"; - } - else if (colorName.Contains("Navy")) - { - weaponIconName += "navy"; - } - else if (colorName.Contains("Cyan")) - { - weaponIconName += "cyan"; - } - else if (colorName.Contains("Purple")) - { - weaponIconName += "purple"; - } - else if (colorName.Contains("Orange")) - { - weaponIconName += "orange"; - } - else if (colorName.Contains("Yellow")) - { - weaponIconName += "yellow"; - } - else if (colorName.Contains("Grey")) - { - weaponIconName += "grey"; - } - else if (colorName.Contains("Rainbow")) - { - weaponIconName += "rainbow"; - } - - return weaponIconName switch - { - "sns" => "https://i.imgur.com/hVCDfnA.png", - "sns_green" => "https://i.imgur.com/U61zPJa.png", - "sns_red" => "https://i.imgur.com/ZGCd1lH.png", - "sns_pink" => "https://i.imgur.com/O4qyBfI.png", - "sns_blue" => "https://i.imgur.com/dQvflcw.png", - "sns_navy" => "https://i.imgur.com/vdeSnZh.png", - "sns_cyan" => "https://i.imgur.com/37gfP8P.png", - "sns_purple" => "https://i.imgur.com/x7dFt4G.png", - "sns_orange" => "https://i.imgur.com/bz22IiF.png", - "sns_yellow" => "https://i.imgur.com/wKItSbP.png", - "sns_grey" => "https://i.imgur.com/U25Xxfj.png", - "sns_rainbow" => "https://i.imgur.com/3a6OI1V.gif", - "ds" => "https://i.imgur.com/JIFNgz9.png", - "ds_green" => "https://i.imgur.com/MEWrHcC.png", - "ds_red" => "https://i.imgur.com/dzIoOF2.png", - "ds_pink" => "https://i.imgur.com/OfUVJy6.png", - "ds_blue" => "https://i.imgur.com/fUvIuCl.png", - "ds_navy" => "https://i.imgur.com/oPz7WAA.png", - "ds_cyan" => "https://i.imgur.com/Lkf6v4A.png", - "ds_purple" => "https://i.imgur.com/b5Ly09E.png", - "ds_orange" => "https://i.imgur.com/LdHWvui.png", - "ds_yellow" => "https://i.imgur.com/2A8UXdT.png", - "ds_grey" => "https://i.imgur.com/snw6dPs.png", - "ds_rainbow" => "https://i.imgur.com/eWTRTJl.gif", - "gs" => "https://i.imgur.com/vLxcWM8.png", - "gs_green" => "https://i.imgur.com/9puI44e.png", - "gs_red" => "https://i.imgur.com/Xhs5yJj.png", - "gs_pink" => "https://i.imgur.com/DXI9FHs.png", - "gs_blue" => "https://i.imgur.com/GxWofdH.png", - "gs_navy" => "https://i.imgur.com/ZM1Isqt.png", - "gs_cyan" => "https://i.imgur.com/tO2TrkB.png", - "gs_purple" => "https://i.imgur.com/ijgJ69Y.png", - "gs_orange" => "https://i.imgur.com/CWHEhAi.png", - "gs_yellow" => "https://i.imgur.com/ZpGOD3z.png", - "gs_grey" => "https://i.imgur.com/82HhSFD.png", - "gs_rainbow" => "https://i.imgur.com/WnRuqll.gif", - "ls" => "https://i.imgur.com/qdA0x3k.png", - "ls_green" => "https://i.imgur.com/9LvQVQ7.png", - "ls_red" => "https://i.imgur.com/oc0ExLi.png", - "ls_pink" => "https://i.imgur.com/jjBGbGu.png", - "ls_blue" => "https://i.imgur.com/AZ606vb.png", - "ls_navy" => "https://i.imgur.com/M6mmOpO.png", - "ls_cyan" => "https://i.imgur.com/qHFbpoJ.png", - "ls_purple" => "https://i.imgur.com/ICgTu6S.png", - "ls_orange" => "https://i.imgur.com/XPYDego.png", - "ls_yellow" => "https://i.imgur.com/H4vJFd1.png", - "ls_grey" => "https://i.imgur.com/1v7T5Hm.png", - "ls_rainbow" => "https://i.imgur.com/BUYVOih.gif", - "hammer" => "https://i.imgur.com/hnY1HC0.png", - "hammer_green" => "https://i.imgur.com/iOGBcmQ.png", - "hammer_red" => "https://i.imgur.com/Z5QGsTO.png", - "hammer_pink" => "https://i.imgur.com/WHkXOoC.png", - "hammer_blue" => "https://i.imgur.com/fb7bxlw.png", - "hammer_navy" => "https://i.imgur.com/oaLfSIP.png", - "hammer_cyan" => "https://i.imgur.com/N2N0Uib.png", - "hammer_purple" => "https://i.imgur.com/CqNUgtg.png", - "hammer_orange" => "https://i.imgur.com/PzYNYZh.png", - "hammer_yellow" => "https://i.imgur.com/Ujpj7WL.png", - "hammer_grey" => "https://i.imgur.com/R0xCYk5.png", - "hammer_rainbow" => "https://i.imgur.com/GIAbKkO.gif", - "hh" => "https://i.imgur.com/EmjAq37.png", - "hh_green" => "https://i.imgur.com/LWCOXI4.png", - "hh_red" => "https://i.imgur.com/lwtBV09.png", - "hh_pink" => "https://i.imgur.com/tZBuDi2.png", - "hh_blue" => "https://i.imgur.com/7qncIzQ.png", - "hh_navy" => "https://i.imgur.com/yaFS4N0.png", - "hh_cyan" => "https://i.imgur.com/GvHKg1u.png", - "hh_purple" => "https://i.imgur.com/33FpZMA.png", - "hh_orange" => "https://i.imgur.com/5ZHbR8K.png", - "hh_yellow" => "https://i.imgur.com/2YdtoVI.png", - "hh_grey" => "https://i.imgur.com/pyPzmJI.png", - "hh_rainbow" => "https://i.imgur.com/VuRLWWG.gif", - "lance" => "https://i.imgur.com/M8fmT4f.png", - "lance_green" => "https://i.imgur.com/zSyyIZY.png", - "lance_red" => "https://i.imgur.com/ZFeN3aA.png", - "lance_pink" => "https://i.imgur.com/X1EncHA.png", - "lance_blue" => "https://i.imgur.com/qMM2gqG.png", - "lance_navy" => "https://i.imgur.com/F7vp82x.png", - "lance_cyan" => "https://i.imgur.com/9q1rqfF.png", - "lance_purple" => "https://i.imgur.com/qF9JMEE.png", - "lance_orange" => "https://i.imgur.com/s1Agqri.png", - "lance_yellow" => "https://i.imgur.com/EcOCe50.png", - "lance_grey" => "https://i.imgur.com/jKPcLtN.png", - "lance_rainbow" => "https://i.imgur.com/BXgEuDy.gif", - "gl" => "https://i.imgur.com/9wq3LQe.png", - "gl_green" => "https://i.imgur.com/bQdGiiB.png", - "gl_red" => "https://i.imgur.com/QorzUm5.png", - "gl_pink" => "https://i.imgur.com/OqkXeZy.png", - "gl_blue" => "https://i.imgur.com/lsFZSnT.png", - "gl_navy" => "https://i.imgur.com/2fkkHVd.png", - "gl_cyan" => "https://i.imgur.com/MzqTO9c.png", - "gl_purple" => "https://i.imgur.com/QqDN0jm.png", - "gl_orange" => "https://i.imgur.com/GowSPSA.png", - "gl_yellow" => "https://i.imgur.com/az9QfWH.png", - "gl_grey" => "https://i.imgur.com/Q5lK9Nw.png", - "gl_rainbow" => "https://i.imgur.com/47VsWHj.gif", - "saf" => "https://i.imgur.com/fVbaN34.png", - "saf_green" => "https://i.imgur.com/V3x8aaf.png", - "saf_red" => "https://i.imgur.com/3l8TO9T.png", - "saf_pink" => "https://i.imgur.com/DTXXEb9.png", - "saf_blue" => "https://i.imgur.com/Dgr9oQg.png", - "saf_navy" => "https://i.imgur.com/Tv40lQg.png", - "saf_cyan" => "https://i.imgur.com/uKxiYhr.png", - "saf_purple" => "https://i.imgur.com/x3RC716.png", - "saf_orange" => "https://i.imgur.com/GU2eOdb.png", - "saf_yellow" => "https://i.imgur.com/f0jrcYq.png", - "saf_grey" => "https://i.imgur.com/jIRe9fA.png", - "saf_rainbow" => "https://i.imgur.com/icBF5lS.gif", - "tonfa" => "https://i.imgur.com/8YpLQ5G.png", - "tonfa_green" => "https://i.imgur.com/0VflTRd.png", - "tonfa_red" => "https://i.imgur.com/f5mIJgU.png", - "tonfa_pink" => "https://i.imgur.com/M6ANARX.png", - "tonfa_blue" => "https://i.imgur.com/BrCnJbs.png", - "tonfa_navy" => "https://i.imgur.com/b2lbCN1.png", - "tonfa_cyan" => "https://i.imgur.com/7bm8xyW.png", - "tonfa_purple" => "https://i.imgur.com/BOcCFhU.png", - "tonfa_orange" => "https://i.imgur.com/vi8qGs5.png", - "tonfa_yellow" => "https://i.imgur.com/qDR1aJZ.png", - "tonfa_grey" => "https://i.imgur.com/GxFrQm6.png", - "tonfa_rainbow" => "https://i.imgur.com/2StcKCZ.gif", - "ms" => "https://i.imgur.com/s3OaNkP.png", - "ms_green" => "https://i.imgur.com/7c8pPow.png", - "ms_red" => "https://i.imgur.com/zA4wMON.png", - "ms_pink" => "https://i.imgur.com/dOc22Dm.png", - "ms_blue" => "https://i.imgur.com/rz4anE4.png", - "ms_navy" => "https://i.imgur.com/dvghN1a.png", - "ms_cyan" => "https://i.imgur.com/gCWBOWm.png", - "ms_purple" => "https://i.imgur.com/UI3KO1c.png", - "ms_orange" => "https://i.imgur.com/9Bg0QzE.png", - "ms_yellow" => "https://i.imgur.com/rAKEtTa.png", - "ms_grey" => "https://i.imgur.com/dNkcRIR.png", - "ms_rainbow" => "https://i.imgur.com/TyZFrvK.gif", - "lbg" => "https://i.imgur.com/txp2GsM.png", - "lbg_green" => "https://i.imgur.com/CMf9U6x.png", - "lbg_red" => "https://i.imgur.com/aKLv0na.png", - "lbg_pink" => "https://i.imgur.com/theTGWy.png", - "lbg_blue" => "https://i.imgur.com/IgXj7vl.png", - "lbg_navy" => "https://i.imgur.com/N8vleIL.png", - "lbg_cyan" => "https://i.imgur.com/4iF0Kex.png", - "lbg_purple" => "https://i.imgur.com/V36MwUh.png", - "lbg_orange" => "https://i.imgur.com/FZ3sAAr.png", - "lbg_yellow" => "https://i.imgur.com/l0Fga4q.png", - "lbg_grey" => "https://i.imgur.com/WE1oZuG.png", - "lbg_rainbow" => "https://i.imgur.com/Q0Firpd.gif", - "hbg" => "https://i.imgur.com/8WD2bI7.png", - "hbg_green" => "https://i.imgur.com/j6qe1uh.png", - "hbg_red" => "https://i.imgur.com/hd8cwCa.png", - "hbg_pink" => "https://i.imgur.com/PDfABOO.png", - "hbg_blue" => "https://i.imgur.com/qURblCM.png", - "hbg_navy" => "https://i.imgur.com/FxInecI.png", - "hbg_cyan" => "https://i.imgur.com/UclnhBS.png", - "hbg_purple" => "https://i.imgur.com/IHifTBB.png", - "hbg_orange" => "https://i.imgur.com/7JRHNzp.png", - "hbg_yellow" => "https://i.imgur.com/rihlgaB.png", - "hbg_grey" => "https://i.imgur.com/mKpJc0p.png", - "hbg_rainbow" => "https://i.imgur.com/TgPORx6.gif", - "bow" => "https://i.imgur.com/haCsXQr.png", - "bow_green" => "https://i.imgur.com/vykrGg9.png", - "bow_red" => "https://i.imgur.com/01nEtNy.png", - "bow_pink" => "https://i.imgur.com/DLIYT8G.png", - "bow_blue" => "https://i.imgur.com/THX3O3X.png", - "bow_navy" => "https://i.imgur.com/DGHifcq.png", - "bow_cyan" => "https://i.imgur.com/sXnzQrG.png", - "bow_purple" => "https://i.imgur.com/D6NYg8r.png", - "bow_orange" => "https://i.imgur.com/fy47m6l.png", - "bow_yellow" => "https://i.imgur.com/ExGTxvl.png", - "bow_grey" => "https://i.imgur.com/Y5vOofE.png", - "bow_rainbow" => "https://i.imgur.com/rsEycVk.gif", - _ => "https://i.imgur.com/9OkLYAz.png",//transcend - }; - } - - /// - /// Gets the area icon from identifier. - /// - /// The identifier. - /// - public static string GetAreaIconFromID(int id) //TODO: are highlands, tidal island or painted falls icons correct? - { - if (id >= 470 && id < 0) - return "https://raw.githubusercontent.com/DorielRivalet/mhfz-overlay/main/img/icon/cattleya.png"; - else - return FindAreaIcon(id); - } - - private static string FindAreaIcon(int id) - { - List AreaGroup = new List { 0 }; - - foreach (KeyValuePair, string> kvp in AreaIconDictionary.AreaIconID) - { - List areaIDs = kvp.Key; - - if (areaIDs.Contains(id)) - { - AreaGroup = kvp.Key; - break; - } - } - return DetermineAreaIcon(AreaGroup); - } - - private static string DetermineAreaIcon(List key) - { - bool areaIcon = AreaIconDictionary.AreaIconID.ContainsKey(key); - if (!areaIcon) - return "https://raw.githubusercontent.com/DorielRivalet/mhfz-overlay/main/img/icon/cattleya.png"; - else - return AreaIconDictionary.AreaIconID[key]; - } - - /// - /// Gets the game mode. - /// - /// if set to true [is high grade edition]. - /// - public static string GetGameMode(bool isHighGradeEdition) - { - if (isHighGradeEdition) - return " [High-Grade Edition]"; - else - return ""; - } - - readonly Mem m = new(); - - /// - /// Shows the current hp percentage. - /// - /// - public static bool ShowCurrentHPPercentage() - { - Settings s = (Settings)Application.Current.TryFindResource("Settings"); - if (s.EnableCurrentHPPercentage) - return true; - else - return false; - } - - private int currentMonster1MaxHP = 0; - - /// - /// Gets the monster1 ehp percent. - /// - /// - public string GetMonster1EHPPercent() - { - if (currentMonster1MaxHP < int.Parse(DataLoader.model.Monster1HP)) - currentMonster1MaxHP = int.Parse(DataLoader.model.Monster1HP); - - if (currentMonster1MaxHP == 0 || GetMonster1EHP() == 0) //should be OK - currentMonster1MaxHP = 1; - - if (!(ShowCurrentHPPercentage())) - return ""; - - return string.Format(" ({0:0}%)", (float)int.Parse(DataLoader.model.Monster1HP) / currentMonster1MaxHP * 100.0); - } - - /// - /// Gets the monster1 ehp. - /// - /// - public int GetMonster1EHP() - { - return DataLoader.model.DisplayMonsterEHP(DataLoader.model.Monster1DefMult(), DataLoader.model.Monster1HPInt(), DataLoader.model.Monster1DefMult()); - } - - /// - /// Gets the monster1 maximum ehp. - /// - /// - public int GetMonster1MaxEHP() - { - return currentMonster1MaxHP; - } - - /// - /// Gets the poogie clothes. - /// - /// The identifier. - /// - public static string GetPoogieClothes(int id) - { - string? clothesValue1; - _ = Dictionary.PoogieCostumeList.PoogieCostumeID.TryGetValue(id, out clothesValue1); //returns true - return clothesValue1 + ""; - } - - /// - /// Gets the objective1 current quantity. - /// - /// - public string GetObjective1CurrentQuantity(bool isLargeImageText = false) - { - if (DataLoader.model.ShowDiscordQuestNames() && !(isLargeImageText)) return ""; - if (DataLoader.model.ObjectiveType() == 0x0 || DataLoader.model.ObjectiveType() == 0x02 || DataLoader.model.ObjectiveType() == 0x1002) - { - if (DataLoader.model.Objective1Quantity() <= 1) - return ""; - else - return DataLoader.model.Objective1CurrentQuantityItem().ToString() + "/"; - } - else - { - if (DataLoader.model.Objective1Quantity() <= 1) - return ""; - else - //increases when u hit a dead large monster - return DataLoader.model.Objective1CurrentQuantityMonster().ToString() + "/"; - } - } - - /// - /// Gets the max faints - /// - /// - public string GetMaxFaints() - { - Settings s = (Settings)Application.Current.TryFindResource("Settings"); - - switch (s.MaxFaintsOverride) - { - default: - return DataLoader.model.MaxFaints().ToString(); - case "Normal Quests": - return DataLoader.model.MaxFaints().ToString(); - case "Shiten/Conquest/Pioneer/Daily/Caravan/Interception Quests": - return DataLoader.model.AlternativeMaxFaints().ToString(); - case "Automatic": - if (DataLoader.model.roadOverride() != null && DataLoader.model.roadOverride() == false) - return DataLoader.model.MaxFaints().ToString(); - - if ( - ( - DataLoader.model.CaravanOverride() && ! - ( - DataLoader.model.QuestID() == 23603 || - DataLoader.model.RankBand() == 70 || - DataLoader.model.QuestID() == 23602 || - DataLoader.model.QuestID() == 23604 || - DataLoader.model.QuestID() == 23588 || - DataLoader.model.QuestID() == 23592 || - DataLoader.model.QuestID() == 23596 || - DataLoader.model.QuestID() == 23601 || - DataLoader.model.QuestID() == 23599 || - DataLoader.model.QuestID() == 23595 || - DataLoader.model.QuestID() == 23591 || - DataLoader.model.QuestID() == 23587 || - DataLoader.model.QuestID() == 23598 || - DataLoader.model.QuestID() == 23594 || - DataLoader.model.QuestID() == 23590 || - DataLoader.model.QuestID() == 23586 || - DataLoader.model.QuestID() == 23597 || - DataLoader.model.QuestID() == 23593 || - DataLoader.model.QuestID() == 23589 || - DataLoader.model.QuestID() == 23585 - ) - ) - - || - - DataLoader.model.QuestID() == 23603 || - DataLoader.model.RankBand() == 70 || - DataLoader.model.QuestID() == 23602 || - DataLoader.model.QuestID() == 23604 || - DataLoader.model.QuestID() == 23588 || - DataLoader.model.QuestID() == 23592 || - DataLoader.model.QuestID() == 23596 || - DataLoader.model.QuestID() == 23601 || - DataLoader.model.QuestID() == 23599 || - DataLoader.model.QuestID() == 23595 || - DataLoader.model.QuestID() == 23591 || - DataLoader.model.QuestID() == 23587 || - DataLoader.model.QuestID() == 23598 || - DataLoader.model.QuestID() == 23594 || - DataLoader.model.QuestID() == 23590 || - DataLoader.model.QuestID() == 23586 || - DataLoader.model.QuestID() == 23597 || - DataLoader.model.QuestID() == 23593 || - DataLoader.model.QuestID() == 23589 || - DataLoader.model.QuestID() == 23585 - ) - { - return DataLoader.model.AlternativeMaxFaints().ToString(); - } - else - { - return DataLoader.model.MaxFaints().ToString(); - } - } - } - - #endregion - - #region discord info - - //dure and road - /// - /// In the arena? - /// - /// - public bool InArena() - { - if (DataLoader.model.AreaID() == 398 || DataLoader.model.AreaID() == 458) - return true; - else - return false; - } - - private bool StartedRoadElapsedTime = false; - - private bool inDuremudiraArena = false; - - private bool inDuremudiraDoorway = false; - - /// - /// Gets the quest information. - /// - /// - public string GetQuestInformation() - { - if (DataLoader.model.ShowDiscordQuestNames()) - { - switch (DataLoader.model.QuestID()) - { - case 23648://arrogant repel - return "Repel Arrogant Duremudira | "; - case 23649://arrogant slay - return "Slay Arrogant Duremudira | "; - case 23527:// Hunter's Road Multiplayer - return ""; - case 23628://solo road - return ""; - case 21731://1st district dure - case 21749://sky corridor version - return "Slay 1st District Duremudira | "; - case 21746://2nd district dure - case 21750://sky corridor version - return "Slay 2nd District Duremudira | "; - default: - if ((DataLoader.model.ObjectiveType() == 0x0 || DataLoader.model.ObjectiveType() == 0x02 || DataLoader.model.ObjectiveType() == 0x1002 || DataLoader.model.ObjectiveType() == 0x10) && (DataLoader.model.QuestID() != 23527 && DataLoader.model.QuestID() != 23628 && DataLoader.model.QuestID() != 21731 && DataLoader.model.QuestID() != 21749 && DataLoader.model.QuestID() != 21746 && DataLoader.model.QuestID() != 21750)) - return string.Format("{0}{1}{2}{3}{4}{5} | ", DataLoader.model.GetObjectiveNameFromID(DataLoader.model.ObjectiveType(), true), GetObjective1CurrentQuantity(true), DataLoader.model.GetObjective1Quantity(true), DataLoader.model.GetRankNameFromID(DataLoader.model.RankBand(), true), DataLoader.model.GetStarGrade(true), DataLoader.model.GetObjective1Name(DataLoader.model.Objective1ID(), true)); - else - return string.Format("{0}{1}{2}{3}{4}{5} | ", DataLoader.model.GetObjectiveNameFromID(DataLoader.model.ObjectiveType(), true), "", DataLoader.model.GetObjective1Quantity(true), DataLoader.model.GetRankNameFromID(DataLoader.model.RankBand(), true), DataLoader.model.GetStarGrade(true), DataLoader.model.GetRealMonsterName(DataLoader.model.CurrentMonster1Icon, true)); - } - } - else - { - return ""; - } - } - - /// - /// Gets the raviente event. - /// - /// The identifier. - /// - public string GetRavienteEvent(int id) - { - Dictionary.RavienteTriggerEvents.RavienteTriggerEventIDs.TryGetValue(id, out string? EventValue1); - Dictionary.ViolentRavienteTriggerEvents.ViolentRavienteTriggerEventIDs.TryGetValue(id, out string? EventValue2); - Dictionary.BerserkRavienteTriggerEvents.BerserkRavienteTriggerEventIDs.TryGetValue(id, out string? EventValue3); - Dictionary.BerserkRavientePracticeTriggerEvents.BerserkRavientePracticeTriggerEventIDs.TryGetValue(id, out string? EventValue4); - - switch (DataLoader.model.getRaviName()) - { - default: - return ""; - case "Raviente": - return EventValue1 + ""; - case "Violent Raviente": - return EventValue2 + ""; - case "Berserk Raviente Practice": - return EventValue4 + ""; - case "Berserk Raviente": - return EventValue3 + ""; - case "Extreme Raviente": - return EventValue3 + ""; - } - } - - private string GetRoadTimerResetMode() - { - Settings s = (Settings)Application.Current.TryFindResource("Settings"); - if (s.DiscordRoadTimerReset == "Never") - return "Never"; - else if (s.DiscordRoadTimerReset == "Always") - return "Always"; - else return "Never"; - } - - - /// - /// Get quest state - /// - /// - public string GetQuestState() - { - if (DataLoader.model.isInLauncherBool) //works? - return ""; - - switch (DataLoader.model.QuestState()) - { - default: - return ""; - case 0: - return ""; - case 1: - return String.Format("Achieved Main Objective | {0} | ", DataLoader.model.Time); - case 129: - return String.Format("Quest Clear! | {0} | ", DataLoader.model.Time); - } - } - - /// - /// Gets the size of the party. - /// - /// - public string GetPartySize() - { - if (DataLoader.model.QuestID() == 0 || DataLoader.model.PartySize() == 0 || DataLoader.model.isInLauncher() == "NULL" || DataLoader.model.isInLauncher() == "Yes") - { - return ""; - } - else - { - return string.Format("Party: {0}/{1} | ", DataLoader.model.PartySize(), GetPartySizeMax()); - } - } - - public int GetPartySizeMax() - { - if (DataLoader.model.PartySize() >= DataLoader.model.PartySizeMax()) - return DataLoader.model.PartySize(); - else - return DataLoader.model.PartySizeMax(); - } - - private bool IsInHubAreaID() - { - switch (DataLoader.model.AreaID()) - { - default: - return false; - case 200://Mezeporta - case 210://Private Bar - case 260://Pallone Caravan - case 282://Cities Map - case 202://Guild Halls - case 203: - case 204: - return true; - } - } - - //quest ids: - //mp road: 23527 - //solo road: 23628 - //1st district dure: 21731 - //2nd district dure: 21746 - //1st district dure sky corridor: 21749 - //2nd district dure sky corridor: 21750 - //arrogant dure repel: 23648 - //arrogant dure slay: 23649 - //urgent tower: 21751 - //4th district dure: 21748 - //3rd district dure: 21747 - //3rd district dure 2: 21734 - //UNUSED sky corridor: 21730 - //sky corridor prologue: 21729 - //raviente 62105 - //raviente carve 62108 - ///violent raviente 62101 - ///violent carve 62104 - //berserk slay practice 55796 - //berserk support practice 1 55802 - //berserk support practice 2 55803 - //berserk support practice 3 55804 - //berserk support practice 4 55805 - //berserk support practice 5 55806 - //berserk practice carve 55807 - //berserk slay 54751 - //berserk support 1 54756 - //berserk support 2 54757 - //berserk support 3 54758 - //berserk support 4 54759 - //berserk support 5 54760 - //berserk carve 54761 - //extreme slay (musou table 54) 55596 - //extreme support 1 55602 - //extreme support 2 55603 - //extreme support 3 55604 - //extreme support 4 55605 - //extreme support 5 55606 - //extreme carve 55607 - - const int MAX_DISCORD_RPC_STRING_LENGTH = 127; // or any other maximum length specified by Discord - - /// - /// Updates the discord RPC. - /// - private void UpdateDiscordRPC() - { - if (!(isDiscordRPCRunning)) - { - return; - } - - // TODO also need to handle the other fields lengths - if (string.Format("{0}{1}{2}{3}{4}{5}", GetPartySize(), GetQuestState(), GetCaravanScore(), DataLoader.model.GetOverlayModeForRPC(), DataLoader.model.GetAreaName(DataLoader.model.AreaID()), GetGameMode(DataLoader.isHighGradeEdition)).Length >= 95) - presenceTemplate.Details = string.Format("{0}{1}{2}", GetQuestState(), DataLoader.model.GetOverlayModeForRPC(), DataLoader.model.GetAreaName(DataLoader.model.AreaID())); - else - presenceTemplate.Details = string.Format("{0}{1}{2}{3}{4}{5}", GetPartySize(), GetQuestState(), GetCaravanScore(), DataLoader.model.GetOverlayModeForRPC(), DataLoader.model.GetAreaName(DataLoader.model.AreaID()), GetGameMode(DataLoader.isHighGradeEdition)); - - // TODO should this be outside UpdateDiscordRPC? - if (IsInHubAreaID() && DataLoader.model.QuestID() == 0) - DataLoader.model.PreviousHubAreaID = DataLoader.model.AreaID(); - - string stateString = ""; - string largeImageTextString = ""; - string smallImageTextString = ""; - - //Info - if ((DataLoader.model.QuestID() != 0 && DataLoader.model.TimeDefInt() != DataLoader.model.TimeInt() && int.Parse(DataLoader.model.ATK) > 0) || ((DataLoader.model.QuestID() == 21731 || DataLoader.model.QuestID() == 21746 || DataLoader.model.QuestID() == 21749 || DataLoader.model.QuestID() == 21750 || DataLoader.model.QuestID() == 23648 || DataLoader.model.QuestID() == 23649 || DataLoader.model.QuestID() == 21748 || DataLoader.model.QuestID() == 21747 || DataLoader.model.QuestID() == 21734) && int.Parse(DataLoader.model.ATK) > 0)) - { - switch (DataLoader.model.QuestID()) - { - case 23527:// Hunter's Road Multiplayer - stateString = String.Format("Multiplayer Floor: {0} ({1}/{2} Max/Total) | RP: {3} | White Fatalis: {4}/{5} (Slain/Encounters)", DataLoader.model.RoadFloor() + 1, DataLoader.model.RoadMaxStagesMultiplayer(), DataLoader.model.RoadTotalStagesMultiplayer(), DataLoader.model.RoadPoints(), DataLoader.model.RoadFatalisSlain(), DataLoader.model.RoadFatalisEncounters()); - presenceTemplate.State = stateString.Length <= MAX_DISCORD_RPC_STRING_LENGTH ? stateString : stateString.Substring(0, MAX_DISCORD_RPC_STRING_LENGTH - 3) + "..."; - break; - case 23628://solo road - stateString = String.Format("Solo Floor: {0} ({1}/{2} Max/Total) | RP: {3} | White Fatalis: {4}/{5} (Slain/Encounters)", DataLoader.model.RoadFloor() + 1, DataLoader.model.RoadMaxStagesSolo(), DataLoader.model.RoadTotalStagesSolo(), DataLoader.model.RoadPoints(), DataLoader.model.RoadFatalisSlain(), DataLoader.model.RoadFatalisEncounters()); - presenceTemplate.State = stateString.Length <= MAX_DISCORD_RPC_STRING_LENGTH ? stateString : stateString.Substring(0, MAX_DISCORD_RPC_STRING_LENGTH - 3) + "..."; - break; - case 21731://1st district dure - case 21749://sky corridor version - stateString = String.Format("{0}{1}{2}{3}{4}{5} | Slain: {6} | Encounters: {7}", DataLoader.model.GetQuestNameFromID(DataLoader.model.QuestID()), DataLoader.model.GetObjectiveNameFromID(DataLoader.model.ObjectiveType()), "", DataLoader.model.GetObjective1Quantity(), DataLoader.model.GetRankNameFromID(DataLoader.model.RankBand()), DataLoader.model.GetRealMonsterName(DataLoader.model.CurrentMonster1Icon), DataLoader.model.FirstDistrictDuremudiraSlays(), DataLoader.model.FirstDistrictDuremudiraEncounters()); - presenceTemplate.State = stateString.Length <= MAX_DISCORD_RPC_STRING_LENGTH ? stateString : stateString.Substring(0, MAX_DISCORD_RPC_STRING_LENGTH - 3) + "..."; - break; - case 21746://2nd district dure - case 21750://sky corridor version - stateString = String.Format("{0}{1}{2}{3}{4}{5} | Slain: {6} | Encounters: {7}", DataLoader.model.GetQuestNameFromID(DataLoader.model.QuestID()), DataLoader.model.GetObjectiveNameFromID(DataLoader.model.ObjectiveType()), "", DataLoader.model.GetObjective1Quantity(), DataLoader.model.GetRankNameFromID(DataLoader.model.RankBand()), DataLoader.model.GetRealMonsterName(DataLoader.model.CurrentMonster1Icon), DataLoader.model.SecondDistrictDuremudiraSlays(), DataLoader.model.SecondDistrictDuremudiraEncounters()); - presenceTemplate.State = stateString.Length <= MAX_DISCORD_RPC_STRING_LENGTH ? stateString : stateString.Substring(0, MAX_DISCORD_RPC_STRING_LENGTH - 3) + "..."; - break; - case 62105://raviente quests - case 62108: - case 62101: - case 62104: - case 55796: - case 55802: - case 55803: - case 55804: - case 55805: - case 55806: - case 55807: - case 54751: - case 54756: - case 54757: - case 54758: - case 54759: - case 54760: - case 54761: - case 55596://extreme - case 55602: - case 55603: - case 55604: - case 55605: - case 55606: - case 55607: - stateString = String.Format("{0}{1}{2}{3}{4}{5}{6} | True Raw: {7} (Max {8}) | Hits: {9}", DataLoader.model.GetQuestNameFromID(DataLoader.model.QuestID()), DataLoader.model.GetObjectiveNameFromID(DataLoader.model.ObjectiveType()), "", DataLoader.model.GetObjective1Quantity(), DataLoader.model.GetRankNameFromID(DataLoader.model.RankBand()), DataLoader.model.GetStarGrade(), DataLoader.model.GetRealMonsterName(DataLoader.model.CurrentMonster1Icon), DataLoader.model.ATK, DataLoader.model.HighestAtk, DataLoader.model.HitCountInt()); - presenceTemplate.State = stateString.Length <= MAX_DISCORD_RPC_STRING_LENGTH ? stateString : stateString.Substring(0, MAX_DISCORD_RPC_STRING_LENGTH - 3) + "..."; - - break; - default: - if ((DataLoader.model.ObjectiveType() == 0x0 || DataLoader.model.ObjectiveType() == 0x02 || DataLoader.model.ObjectiveType() == 0x1002 || DataLoader.model.ObjectiveType() == 0x10) && (DataLoader.model.QuestID() != 23527 && DataLoader.model.QuestID() != 23628 && DataLoader.model.QuestID() != 21731 && DataLoader.model.QuestID() != 21749 && DataLoader.model.QuestID() != 21746 && DataLoader.model.QuestID() != 21750)) - { - stateString = String.Format("{0}{1}{2}{3}{4}{5}{6} | True Raw: {7} (Max {8}) | Hits: {9}", DataLoader.model.GetQuestNameFromID(DataLoader.model.QuestID()), DataLoader.model.GetObjectiveNameFromID(DataLoader.model.ObjectiveType()), GetObjective1CurrentQuantity(), DataLoader.model.GetObjective1Quantity(), DataLoader.model.GetRankNameFromID(DataLoader.model.RankBand()), DataLoader.model.GetStarGrade(), DataLoader.model.GetObjective1Name(DataLoader.model.Objective1ID()), DataLoader.model.ATK, DataLoader.model.HighestAtk, DataLoader.model.HitCountInt()); - presenceTemplate.State = stateString.Length <= MAX_DISCORD_RPC_STRING_LENGTH ? stateString : stateString.Substring(0, MAX_DISCORD_RPC_STRING_LENGTH - 3) + "..."; - } - else - { - stateString = String.Format("{0}{1}{2}{3}{4}{5}{6} | True Raw: {7} (Max {8}) | Hits: {9}", DataLoader.model.GetQuestNameFromID(DataLoader.model.QuestID()), DataLoader.model.GetObjectiveNameFromID(DataLoader.model.ObjectiveType()), "", DataLoader.model.GetObjective1Quantity(), DataLoader.model.GetRankNameFromID(DataLoader.model.RankBand()), DataLoader.model.GetStarGrade(), DataLoader.model.GetRealMonsterName(DataLoader.model.CurrentMonster1Icon), DataLoader.model.ATK, DataLoader.model.HighestAtk, DataLoader.model.HitCountInt()); - presenceTemplate.State = stateString.Length <= MAX_DISCORD_RPC_STRING_LENGTH ? stateString : stateString.Substring(0, MAX_DISCORD_RPC_STRING_LENGTH - 3) + "..."; - } - break; - } - - //Gathering/etc - if ((DataLoader.model.ObjectiveType() == 0x0 || DataLoader.model.ObjectiveType() == 0x02 || DataLoader.model.ObjectiveType() == 0x1002) && (DataLoader.model.QuestID() != 23527 && DataLoader.model.QuestID() != 23628 && DataLoader.model.QuestID() != 21731 && DataLoader.model.QuestID() != 21749 && DataLoader.model.QuestID() != 21746 && DataLoader.model.QuestID() != 21750)) - { - largeImageTextString = string.Format("{0}{1}", GetQuestInformation(), DataLoader.model.GetAreaName(DataLoader.model.AreaID())); - presenceTemplate.Assets.LargeImageKey = GetAreaIconFromID(DataLoader.model.AreaID()); - presenceTemplate.Assets.LargeImageText = largeImageTextString.Length <= MAX_DISCORD_RPC_STRING_LENGTH ? largeImageTextString : largeImageTextString.Substring(0, MAX_DISCORD_RPC_STRING_LENGTH - 3) + "..."; - } - //Tenrou Sky Corridor areas - else if (DataLoader.model.AreaID() == 391 || DataLoader.model.AreaID() == 392 || DataLoader.model.AreaID() == 394 || DataLoader.model.AreaID() == 415 || DataLoader.model.AreaID() == 416) - { - largeImageTextString = string.Format("{0}{1}", GetQuestInformation(), DataLoader.model.GetAreaName(DataLoader.model.AreaID())); - presenceTemplate.Assets.LargeImageKey = GetAreaIconFromID(DataLoader.model.AreaID()); - presenceTemplate.Assets.LargeImageText = largeImageTextString.Length <= MAX_DISCORD_RPC_STRING_LENGTH ? largeImageTextString : largeImageTextString.Substring(0, MAX_DISCORD_RPC_STRING_LENGTH - 3) + "..."; - } - //Duremudira Doors - else if (DataLoader.model.AreaID() == 399 || DataLoader.model.AreaID() == 414) - { - presenceTemplate.Assets.LargeImageKey = GetAreaIconFromID(DataLoader.model.AreaID()); - largeImageTextString = string.Format("{0}{1}", GetQuestInformation(), DataLoader.model.GetAreaName(DataLoader.model.AreaID())); - presenceTemplate.Assets.LargeImageText = largeImageTextString.Length <= MAX_DISCORD_RPC_STRING_LENGTH ? largeImageTextString : largeImageTextString.Substring(0, MAX_DISCORD_RPC_STRING_LENGTH - 3) + "..."; - } - //Duremudira Arena - else if (DataLoader.model.AreaID() == 398) - { - presenceTemplate.Assets.LargeImageKey = DataLoader.model.getMonsterIcon(DataLoader.model.LargeMonster1ID()); - largeImageTextString = string.Format("{0}{1}/{2}{3}", GetQuestInformation(), GetMonster1EHP(), GetMonster1MaxEHP(), GetMonster1EHPPercent()); - presenceTemplate.Assets.LargeImageText = largeImageTextString.Length <= MAX_DISCORD_RPC_STRING_LENGTH ? largeImageTextString : largeImageTextString.Substring(0, MAX_DISCORD_RPC_STRING_LENGTH - 3) + "..."; - } - //Hunter's Road Base Camp - else if (DataLoader.model.AreaID() == 459) - { - presenceTemplate.Assets.LargeImageKey = GetAreaIconFromID(DataLoader.model.AreaID()); - largeImageTextString = string.Format("{0}{1} | Faints: {2}/{3}", GetQuestInformation(), DataLoader.model.GetAreaName(DataLoader.model.AreaID()), DataLoader.model.CurrentFaints(), GetMaxFaints()); - presenceTemplate.Assets.LargeImageText = largeImageTextString.Length <= MAX_DISCORD_RPC_STRING_LENGTH ? largeImageTextString : largeImageTextString.Substring(0, MAX_DISCORD_RPC_STRING_LENGTH - 3) + "..."; - } - //Raviente - else if (DataLoader.model.AreaID() == 309 || (DataLoader.model.AreaID() >= 311 && DataLoader.model.AreaID() <= 321) || (DataLoader.model.AreaID() >= 417 && DataLoader.model.AreaID() <= 422) || DataLoader.model.AreaID() == 437 || (DataLoader.model.AreaID() >= 440 && DataLoader.model.AreaID() <= 444)) - { - presenceTemplate.Assets.LargeImageKey = DataLoader.model.getMonsterIcon(DataLoader.model.LargeMonster1ID()); - largeImageTextString = string.Format("{0}{1}/{2}{3} | Faints: {4}/{5} | Points: {6} | {7}", GetQuestInformation(), GetMonster1EHP(), GetMonster1MaxEHP(), GetMonster1EHPPercent(), DataLoader.model.CurrentFaints(), GetMaxFaints(), DataLoader.model.GreatSlayingPoints(), GetRavienteEvent(DataLoader.model.RavienteTriggeredEvent())); - presenceTemplate.Assets.LargeImageText = largeImageTextString.Length <= MAX_DISCORD_RPC_STRING_LENGTH ? largeImageTextString : largeImageTextString.Substring(0, MAX_DISCORD_RPC_STRING_LENGTH - 3) + "..."; - } - else - { - presenceTemplate.Assets.LargeImageKey = DataLoader.model.getMonsterIcon(DataLoader.model.LargeMonster1ID()); - largeImageTextString = string.Format("{0}{1}/{2}{3} | Faints: {4}/{5}", GetQuestInformation(), GetMonster1EHP(), GetMonster1MaxEHP(), GetMonster1EHPPercent(), DataLoader.model.CurrentFaints(), GetMaxFaints()); - presenceTemplate.Assets.LargeImageText = largeImageTextString.Length <= MAX_DISCORD_RPC_STRING_LENGTH ? largeImageTextString : largeImageTextString.Substring(0, MAX_DISCORD_RPC_STRING_LENGTH - 3) + "..."; - } - } - else if (DataLoader.model.QuestID() == 0) - { - - switch (DataLoader.model.AreaID()) - { - case 0: //Loading - presenceTemplate.State = "Loading..."; - break; - case 87: //Kokoto Village - case 131: //Dundorma areas - case 132: - case 133: - case 134: - case 135: - case 136: - case 200: //Mezeporta - case 201://Hairdresser - case 206://Old Town Areas - case 207: - case 210://Private Bar - case 211://Rasta Bar - case 244://Code Claiming Room - case 282://Cities Map - case 340://SR Rooms - case 341: - case 397://Mezeporta Dupe(non-HD) - stateString = string.Format("GR: {0} | GCP: {1} | Guild Food: {2} | Diva Skill: {3} ({4} Left) | Poogie Item: {5}", DataLoader.model.GRankNumber(), DataLoader.model.GCP(), getArmorSkill(DataLoader.model.GuildFoodSkill()), GetDivaSkillNameFromID(DataLoader.model.DivaSkill()), DataLoader.model.DivaSkillUsesLeft(), GetItemName(DataLoader.model.PoogieItemUseID())); - presenceTemplate.State = stateString.Length <= MAX_DISCORD_RPC_STRING_LENGTH ? stateString : stateString.Substring(0, MAX_DISCORD_RPC_STRING_LENGTH - 3) + "..."; - break; - case 173:// My House (original) - case 175://My House (MAX) - stateString = string.Format("GR: {0} | Partner Lv: {1} | Armor Color: {2} | GCP: {3}", DataLoader.model.GRankNumber(), DataLoader.model.PartnerLevel(), getArmorColor(), DataLoader.model.GCP()); - presenceTemplate.State = stateString.Length <= MAX_DISCORD_RPC_STRING_LENGTH ? stateString : stateString.Substring(0, MAX_DISCORD_RPC_STRING_LENGTH - 3) + "..."; - break; - case 202://Guild Halls - case 203: - case 204: - stateString = string.Format("GR: {0} | GCP: {1} | Guild Food: {2} | Poogie Item: {3}", DataLoader.model.GRankNumber(), DataLoader.model.GCP(), getArmorSkill(DataLoader.model.GuildFoodSkill()), GetItemName(DataLoader.model.PoogieItemUseID())); - presenceTemplate.State = stateString.Length <= MAX_DISCORD_RPC_STRING_LENGTH ? stateString : stateString.Substring(0, MAX_DISCORD_RPC_STRING_LENGTH - 3) + "..."; - break; - case 205://Pugi Farm - stateString = string.Format("GR: {0} | Poogie Points: {1} | Poogie Clothes: {2} | Poogie Item: {3}", DataLoader.model.GRankNumber(), DataLoader.model.PoogiePoints(), GetPoogieClothes(DataLoader.model.PoogieCostume()), GetItemName(DataLoader.model.PoogieItemUseID())); - presenceTemplate.State = stateString.Length <= MAX_DISCORD_RPC_STRING_LENGTH ? stateString : stateString.Substring(0, MAX_DISCORD_RPC_STRING_LENGTH - 3) + "..."; - break; - case 256://Caravan Areas - case 260: - case 261: - case 262: - case 263: - stateString = string.Format("CP: {0} | Gg: {1} | g: {2} | Gem Lv: {3} | Great Slaying Points: {4}", DataLoader.model.CaravanPoints(), DataLoader.model.RaviGg(), DataLoader.model.Ravig(), DataLoader.model.CaravenGemLevel() + 1, DataLoader.model.GreatSlayingPointsSaved()); - presenceTemplate.State = stateString.Length <= MAX_DISCORD_RPC_STRING_LENGTH ? stateString : stateString.Substring(0, MAX_DISCORD_RPC_STRING_LENGTH - 3) + "..."; - break; - case 257://Blacksmith - stateString = string.Format("GR: {0} | GCP: {1} | Guild Food: {2} | GZenny: {3}", DataLoader.model.GRankNumber(), DataLoader.model.GCP(), getArmorSkill(DataLoader.model.GuildFoodSkill()), DataLoader.model.GZenny()); - presenceTemplate.State = stateString.Length <= MAX_DISCORD_RPC_STRING_LENGTH ? stateString : stateString.Substring(0, MAX_DISCORD_RPC_STRING_LENGTH - 3) + "..."; - break; - case 264://Gallery - stateString = string.Format("GR: {0} | GCP: {1} | Guild Food: {2} | Score: {3}", DataLoader.model.GRankNumber(), DataLoader.model.GCP(), getArmorSkill(DataLoader.model.GuildFoodSkill()), DataLoader.model.GalleryEvaluationScore()); - presenceTemplate.State = stateString.Length <= MAX_DISCORD_RPC_STRING_LENGTH ? stateString : stateString.Substring(0, MAX_DISCORD_RPC_STRING_LENGTH - 3) + "..."; - break; - case 265://Guuku Farm - stateString = string.Format("GR: {0} | GCP: {1} | Guild Food: {2} | Poogie Item: {3}", DataLoader.model.GRankNumber(), DataLoader.model.GCP(), getArmorSkill(DataLoader.model.GuildFoodSkill()), GetItemName(DataLoader.model.PoogieItemUseID())); - presenceTemplate.State = stateString.Length <= MAX_DISCORD_RPC_STRING_LENGTH ? stateString : stateString.Substring(0, MAX_DISCORD_RPC_STRING_LENGTH - 3) + "..."; - break; - case 283://Halk Area TODO partnya lv - stateString = string.Format("GR: {0} | GCP: {1} | PNRP: {2} | Halk Fullness: {3}", DataLoader.model.GRankNumber(), DataLoader.model.GCP(), DataLoader.model.PartnyaRankPoints(), DataLoader.model.HalkFullness()); - presenceTemplate.State = stateString.Length <= MAX_DISCORD_RPC_STRING_LENGTH ? stateString : stateString.Substring(0, MAX_DISCORD_RPC_STRING_LENGTH - 3) + "..."; - break; - case 286://PvP Room - stateString = string.Format("GR: {0} | GCP: {1} | Guild Food: {2} | Poogie Item: {3}", DataLoader.model.GRankNumber(), DataLoader.model.GCP(), getArmorSkill(DataLoader.model.GuildFoodSkill()), GetItemName(DataLoader.model.PoogieItemUseID())); - presenceTemplate.State = stateString.Length <= MAX_DISCORD_RPC_STRING_LENGTH ? stateString : stateString.Substring(0, MAX_DISCORD_RPC_STRING_LENGTH - 3) + "..."; - break; - case 379://Diva Hall - case 445: - stateString = string.Format("GR: {0} | Diva Skill: {1} ({2} Left) | Diva Bond: {3} | Items Given: {4}", DataLoader.model.GRankNumber(), GetDivaSkillNameFromID(DataLoader.model.DivaSkill()), DataLoader.model.DivaSkillUsesLeft(), DataLoader.model.DivaBond(), DataLoader.model.DivaItemsGiven()); - presenceTemplate.State = stateString.Length <= MAX_DISCORD_RPC_STRING_LENGTH ? stateString : stateString.Substring(0, MAX_DISCORD_RPC_STRING_LENGTH - 3) + "..."; - break; - case 462://MezFez Entrance - case 463: //Volpkun Together - case 465://MezFez Minigame - stateString = string.Format("GR: {0} | MezFes Points: {1} | Guild Food: {2} | Poogie Item: {3}", DataLoader.model.GRankNumber(), DataLoader.model.MezeportaFestivalPoints(), getArmorSkill(DataLoader.model.GuildFoodSkill()), GetItemName(DataLoader.model.PoogieItemUseID())); - presenceTemplate.State = stateString.Length <= MAX_DISCORD_RPC_STRING_LENGTH ? stateString : stateString.Substring(0, MAX_DISCORD_RPC_STRING_LENGTH - 3) + "..."; - break; - case 464://Uruki Pachinko - stateString = string.Format("Score: {0} | Chain: {1} | Fish: {2} | Mushroom: {3} | Seed: {4} | Meat: {5}", DataLoader.model.UrukiPachinkoScore() + DataLoader.model.UrukiPachinkoBonusScore(), DataLoader.model.UrukiPachinkoChain(), DataLoader.model.UrukiPachinkoFish(), DataLoader.model.UrukiPachinkoMushroom(), DataLoader.model.UrukiPachinkoSeed(), DataLoader.model.UrukiPachinkoMeat()); - presenceTemplate.State = stateString.Length <= MAX_DISCORD_RPC_STRING_LENGTH ? stateString : stateString.Substring(0, MAX_DISCORD_RPC_STRING_LENGTH - 3) + "..."; - break; - case 466://Guuku Scoop - stateString = string.Format("Score: {0} | Small Guuku: {1} | Medium Guuku: {2} | Large Guuku: {3} | Golden Guuku: {4}", DataLoader.model.GuukuScoopScore(), DataLoader.model.GuukuScoopSmall(), DataLoader.model.GuukuScoopMedium(), DataLoader.model.GuukuScoopLarge(), DataLoader.model.GuukuScoopGolden()); - presenceTemplate.State = stateString.Length <= MAX_DISCORD_RPC_STRING_LENGTH ? stateString : stateString.Substring(0, MAX_DISCORD_RPC_STRING_LENGTH - 3) + "..."; - break; - case 467://Nyanrendo - stateString = string.Format("Score: {0}", DataLoader.model.NyanrendoScore()); - presenceTemplate.State = stateString.Length <= MAX_DISCORD_RPC_STRING_LENGTH ? stateString : stateString.Substring(0, MAX_DISCORD_RPC_STRING_LENGTH - 3) + "..."; - break; - case 468://Panic Honey - stateString = string.Format("Honey: {0}", DataLoader.model.PanicHoneyScore()); - presenceTemplate.State = stateString.Length <= MAX_DISCORD_RPC_STRING_LENGTH ? stateString : stateString.Substring(0, MAX_DISCORD_RPC_STRING_LENGTH - 3) + "..."; - break; - case 469://Dokkan Battle Cats - stateString = string.Format("Score: {0} | Scale: {1} | Shell: {2} | Camp: {3}", DataLoader.model.DokkanBattleCatsScore(), DataLoader.model.DokkanBattleCatsScale(), DataLoader.model.DokkanBattleCatsShell(), DataLoader.model.DokkanBattleCatsCamp()); - presenceTemplate.State = stateString.Length <= MAX_DISCORD_RPC_STRING_LENGTH ? stateString : stateString.Substring(0, MAX_DISCORD_RPC_STRING_LENGTH - 3) + "..."; - break; - default: //same as Mezeporta - stateString = string.Format("GR: {0} | GCP: {1} | Guild Food: {2} | Poogie Item: {3}", DataLoader.model.GRankNumber(), DataLoader.model.GCP(), getArmorSkill(DataLoader.model.GuildFoodSkill()), GetItemName(DataLoader.model.PoogieItemUseID())); - presenceTemplate.State = stateString.Length <= MAX_DISCORD_RPC_STRING_LENGTH ? stateString : stateString.Substring(0, MAX_DISCORD_RPC_STRING_LENGTH - 3) + "..."; - break; - } - - presenceTemplate.Assets.LargeImageKey = GetAreaIconFromID(DataLoader.model.AreaID()); - largeImageTextString = DataLoader.model.GetAreaName(DataLoader.model.AreaID()); - presenceTemplate.Assets.LargeImageText = largeImageTextString.Length <= MAX_DISCORD_RPC_STRING_LENGTH ? largeImageTextString : largeImageTextString.Substring(0, MAX_DISCORD_RPC_STRING_LENGTH - 3) + "..."; - } - - //Timer - if ((DataLoader.model.QuestID() != 0 && !DataLoader.model.inQuest && DataLoader.model.TimeDefInt() > DataLoader.model.TimeInt() && int.Parse(DataLoader.model.ATK) > 0) || (DataLoader.model.IsRoad() || DataLoader.model.IsDure())) - { - DataLoader.model.inQuest = true; - - if (!(DataLoader.model.IsRoad() || DataLoader.model.IsDure())) - { - presenceTemplate.Timestamps = GetDiscordTimerMode() switch - { - "Time Left" => Timestamps.FromTimeSpan((double)DataLoader.model.TimeDefInt() / 30.0), - "Time Elapsed" => Timestamps.Now, - //dure doorway too - _ => Timestamps.FromTimeSpan((double)DataLoader.model.TimeDefInt() / 30.0), - }; - } - - if (DataLoader.model.IsRoad()) - { - switch (GetRoadTimerResetMode()) - { - case "Always": - if (DataLoader.model.AreaID() == 458)//Hunter's Road Area 1 - { - break; - } - - else if (DataLoader.model.AreaID() == 459)//Hunter's Road Base Camp - { - if (DataLoader.model.RoadFloor() + 1 > DataLoader.model.previousRoadFloor) - { - // reset values - DataLoader.model.inQuest = false; - currentMonster1MaxHP = 0; - //DataLoader.model.previousRoadFloor = DataLoader.model.RoadFloor() + 1; - presenceTemplate.Timestamps = GetDiscordTimerMode() switch - { - "Time Left" => Timestamps.FromTimeSpan((double)DataLoader.model.TimeInt() / 30.0), - "Time Elapsed" => Timestamps.Now, - _ => Timestamps.FromTimeSpan((double)DataLoader.model.TimeInt() / 30.0), - }; - } - break; - } - else - { - break; - } - case "Never": - if (DataLoader.model.AreaID() == 458)//Hunter's Road Area 1 - { - break; - } - - else if (DataLoader.model.AreaID() == 459)//Hunter's Road Base Camp - { - if (DataLoader.model.RoadFloor() + 1 > DataLoader.model.previousRoadFloor) - { - // reset values - DataLoader.model.inQuest = false; - currentMonster1MaxHP = 0; - //DataLoader.model.previousRoadFloor = DataLoader.model.RoadFloor() + 1; - - if (!(StartedRoadElapsedTime)) - { - StartedRoadElapsedTime = true; - presenceTemplate.Timestamps = Timestamps.Now; - } - } - break; - } - else - { - break; - } - default: - if (DataLoader.model.AreaID() == 458)//Hunter's Road Area 1 - { - break; - } - - else if (DataLoader.model.AreaID() == 459)//Hunter's Road Base Camp - { - if (DataLoader.model.RoadFloor() + 1 > DataLoader.model.previousRoadFloor) - { - // reset values - DataLoader.model.inQuest = false; - currentMonster1MaxHP = 0; - //DataLoader.model.previousRoadFloor = DataLoader.model.RoadFloor() + 1; - - if (!(StartedRoadElapsedTime)) - { - StartedRoadElapsedTime = true; - presenceTemplate.Timestamps = Timestamps.Now; - } - } - break; - } - else - { - break; - } - } - } - - if (DataLoader.model.IsDure()) - { - - switch (DataLoader.model.AreaID()) - { - case 398://Duremudira Arena - - if (!(inDuremudiraArena)) - { - inDuremudiraArena = true; - - if (DataLoader.model.QuestID() == 23649)//Arrogant Dure Slay - { - presenceTemplate.Timestamps = GetDiscordTimerMode() switch - { - "Time Left" => Timestamps.FromTimeSpan(600), - "Time Elapsed" => Timestamps.Now, - _ => Timestamps.FromTimeSpan(600), - }; - - } - else - { - presenceTemplate.Timestamps = GetDiscordTimerMode() switch - { - "Time Left" => Timestamps.FromTimeSpan(1200), - "Time Elapsed" => Timestamps.Now, - _ => Timestamps.FromTimeSpan(1200), - }; - } - } - break; - - default: - if (!(inDuremudiraDoorway)) - { - inDuremudiraDoorway = true; - presenceTemplate.Timestamps = Timestamps.Now; - } - break; - } - } - } - // going back to Mezeporta or w/e - else if (DataLoader.model.QuestState() != 1 && DataLoader.model.QuestID() == 0 && DataLoader.model.inQuest && int.Parse(DataLoader.model.ATK) == 0) - { - //reset values - DataLoader.model.inQuest = false; - currentMonster1MaxHP = 0; - //DataLoader.model.previousRoadFloor = 0; - StartedRoadElapsedTime = false; - inDuremudiraArena = false; - inDuremudiraDoorway = false; - - presenceTemplate.Timestamps = Timestamps.Now; - } - - //SmallInfo - presenceTemplate.Assets.SmallImageKey = getWeaponIconFromID(DataLoader.model.WeaponType()); - - if (GetHunterName != "" && GetGuildName != "" && GetServerName != "") - { - smallImageTextString = String.Format("{0} | {1} | {2} | GSR: {3} | {4} Style | Caravan Skills: {5}", GetHunterName, GetGuildName, GetServerName, DataLoader.model.GSR(), GetWeaponStyleFromID(DataLoader.model.WeaponStyle()), GetCaravanSkills()); - presenceTemplate.Assets.SmallImageText = smallImageTextString.Length <= MAX_DISCORD_RPC_STRING_LENGTH ? smallImageTextString : smallImageTextString.Substring(0, MAX_DISCORD_RPC_STRING_LENGTH - 3) + "..."; - } - - discordRPCClient.SetPresence(presenceTemplate); - } #endregion @@ -2711,7 +1227,6 @@ private void ElementMouseLeftButtonDown(object sender, MouseButtonEventArgs e) #region clickbuttons private void ReloadButton_Click(object sender, RoutedEventArgs e) { - ApplicationManager.DiscordRPCCleanup(); ApplicationManager.HandleRestart(); } @@ -2727,14 +1242,12 @@ private void OpenConfigButton_Click(object sender, RoutedEventArgs e) private void CloseButton_Click(object sender, RoutedEventArgs e) { - ApplicationManager.DiscordRPCCleanup(); ApplicationManager.HandleShutdown(); } //https://stackoverflow.com/questions/4773632/how-do-i-restart-a-wpf-application private void ReloadButton_Key() { - ApplicationManager.DiscordRPCCleanup(); ApplicationManager.HandleRestart(); } @@ -2764,7 +1277,6 @@ private void OpenConfigButton_Key() private void CloseButton_Key() { - ApplicationManager.DiscordRPCCleanup(); ApplicationManager.HandleShutdown(); } diff --git a/MHFZ_Overlay/addresses/AddressModel.cs b/MHFZ_Overlay/addresses/AddressModel.cs index 41ab45e8..01f88a61 100644 --- a/MHFZ_Overlay/addresses/AddressModel.cs +++ b/MHFZ_Overlay/addresses/AddressModel.cs @@ -4,6 +4,7 @@ using LiveChartsCore.SkiaSharpView; using LiveChartsCore.SkiaSharpView.Painting; using Memory; +using MHFZ_Overlay.Core.Class.Discord; using MHFZ_Overlay.UI.Class; using NLog; using RESTCountries.NET.Models; @@ -13,6 +14,7 @@ using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; +using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; @@ -31,6 +33,8 @@ public abstract class AddressModel : INotifyPropertyChanged { private static readonly NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger(); + private static readonly DatabaseManager databaseManager = DatabaseManager.GetInstance(); + #region properties public readonly Mem M; @@ -46,7 +50,7 @@ public abstract class AddressModel : INotifyPropertyChanged public AddressModel(Mem m) { logger.Info($"AddressModel initialized"); - + logger.Trace(new StackTrace().ToString()); M = m; } @@ -857,21 +861,6 @@ public bool ShowOverlayStatIcon return null; } - /// - /// Gets a value indicating whether [show discord quest names]. - /// - /// - /// true if [show discord quest names]; otherwise, false. - /// - public bool ShowDiscordQuestNames() - { - Settings s = (Settings)Application.Current.TryFindResource("Settings"); - if (s.DiscordQuestNameShown) - return true; - else - return false; - } - /// /// Gets the name of the quest. /// @@ -879,7 +868,7 @@ public bool ShowDiscordQuestNames() /// public string GetQuestNameFromID(int id) { - if (!(ShowDiscordQuestNames())) return ""; + if (!(DiscordManager.ShowDiscordQuestNames())) return ""; string QuestValue1; #pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type. Dictionary.Quests.QuestIDs.TryGetValue(id, out QuestValue1); //returns true @@ -4500,7 +4489,7 @@ public string GetArmorSkillsForRunID(int skill1, int skill2, int skill3, int ski /// /// The identifier. /// - public static string GetDivaSkillNameFromID(int id) + public string GetDivaSkillNameFromID(int id) { Dictionary.DivaSkillList.DivaSkillID.TryGetValue(id, out string? divaskillaname); return divaskillaname + ""; @@ -4511,7 +4500,7 @@ public static string GetDivaSkillNameFromID(int id) /// /// The identifier. /// - public static string GetItemName(int id) + public string GetItemName(int id) { string itemValue1; #pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type. @@ -4526,7 +4515,7 @@ public static string GetItemName(int id) /// /// The identifier. /// - public static string GetArmorSkill(int id) + public string GetArmorSkill(int id) { Dictionary.ArmorSkillList.ArmorSkillID.TryGetValue(id, out string? skillname); if (skillname == "" || skillname == null) @@ -4535,6 +4524,20 @@ public static string GetArmorSkill(int id) return skillname + ""; } + /// + /// Gets the armor skill. + /// + /// The identifier. + /// + public string GetArmorSkillWithNull(int id) + { + Dictionary.ArmorSkillList.ArmorSkillID.TryGetValue(id, out string? skillname); + if (skillname == "") + return "None"; + else + return skillname + ""; + } + /// /// Gets the goushou boost skill /// @@ -6108,16 +6111,16 @@ public string GenerateGearStats(long? runID = null) } else { - ActiveSkills activeSkills = DatabaseManager.GetInstance().GetActiveSkills((long)runID); - AmmoPouch ammoPouch = DatabaseManager.GetInstance().GetAmmoPouch((long)runID); - AutomaticSkills automaticSkills = DatabaseManager.GetInstance().GetAutomaticSkills((long)runID); - CaravanSkills caravanSkills = DatabaseManager.GetInstance().GetCaravanSkills((long)runID); - PlayerGear playerGear = DatabaseManager.GetInstance().GetPlayerGear((long)runID); - PlayerInventory playerInventory = DatabaseManager.GetInstance().GetPlayerInventory((long)runID); - UI.Class.RoadDureSkills roadDureSkills = DatabaseManager.GetInstance().GetRoadDureSkills((long)runID); - StyleRankSkills styleRankSkills = DatabaseManager.GetInstance().GetStyleRankSkills((long)runID); - ZenithSkills zenithSkills = DatabaseManager.GetInstance().GetZenithSkills((long)runID); - Quest quest = DatabaseManager.GetInstance().GetQuest((long)runID); + ActiveSkills activeSkills = databaseManager.GetActiveSkills((long)runID); + AmmoPouch ammoPouch = databaseManager.GetAmmoPouch((long)runID); + AutomaticSkills automaticSkills = databaseManager.GetAutomaticSkills((long)runID); + CaravanSkills caravanSkills = databaseManager.GetCaravanSkills((long)runID); + PlayerGear playerGear = databaseManager.GetPlayerGear((long)runID); + PlayerInventory playerInventory = databaseManager.GetPlayerInventory((long)runID); + UI.Class.RoadDureSkills roadDureSkills = databaseManager.GetRoadDureSkills((long)runID); + StyleRankSkills styleRankSkills = databaseManager.GetStyleRankSkills((long)runID); + ZenithSkills zenithSkills = databaseManager.GetZenithSkills((long)runID); + Quest quest = databaseManager.GetQuest((long)runID); var createdBy = playerGear.CreatedBy; if (createdBy == null) @@ -6452,12 +6455,12 @@ public string GenerateCompendium(DataLoader dataLoader) if (createdBy == null) return "Program Version Not Found.\n\nReload the section."; - QuestCompendium questCompendium = DatabaseManager.GetInstance().GetQuestCompendium(); - GearCompendium gearCompendium = DatabaseManager.GetInstance().GetGearCompendium(); - PerformanceCompendium performanceCompendium = DatabaseManager.GetInstance().GetPerformanceCompendium(); - MezFesCompendium mezeportaFestivalCompendium = DatabaseManager.GetInstance().GetMezFesCompendium(); - MiscellaneousCompendium miscellaneousCompendium = DatabaseManager.GetInstance().GetMiscellaneousCompendium(); - MonsterCompendium monsterCompendium = DatabaseManager.GetInstance().GetMonsterCompendium(); + QuestCompendium questCompendium = databaseManager.GetQuestCompendium(); + GearCompendium gearCompendium = databaseManager.GetGearCompendium(); + PerformanceCompendium performanceCompendium = databaseManager.GetPerformanceCompendium(); + MezFesCompendium mezeportaFestivalCompendium = databaseManager.GetMezFesCompendium(); + MiscellaneousCompendium miscellaneousCompendium = databaseManager.GetMiscellaneousCompendium(); + MonsterCompendium monsterCompendium = databaseManager.GetMonsterCompendium(); var mostCompletedQuest = questCompendium.MostCompletedQuestRuns; @@ -9383,7 +9386,7 @@ public string GetMinutesSecondsMillisecondsFromFrames(long frames) /// public string GetObjectiveNameFromID(int id, bool isLargeImageText = false) { - if (ShowDiscordQuestNames() && !(isLargeImageText)) return ""; + if (DiscordManager.ShowDiscordQuestNames() && !(isLargeImageText)) return ""; //TODO dictionary return id switch { @@ -9409,7 +9412,7 @@ public string GetObjectiveNameFromID(int id, bool isLargeImageText = false) /// public string GetObjective1Quantity(bool isLargeImageText = false) { - if (ShowDiscordQuestNames() && !(isLargeImageText)) return ""; + if (DiscordManager.ShowDiscordQuestNames() && !(isLargeImageText)) return ""; if (Objective1Quantity() <= 1) return ""; // hunt / capture / slay @@ -9421,6 +9424,30 @@ public string GetObjective1Quantity(bool isLargeImageText = false) return Objective1Quantity().ToString() + " "; } + /// + /// Gets the objective1 current quantity. + /// + /// + public string GetObjective1CurrentQuantity(bool isLargeImageText = false) + { + if (DiscordManager.ShowDiscordQuestNames() && !(isLargeImageText)) return ""; + if (ObjectiveType() == 0x0 || ObjectiveType() == 0x02 || ObjectiveType() == 0x1002) + { + if (Objective1Quantity() <= 1) + return ""; + else + return Objective1CurrentQuantityItem().ToString() + "/"; + } + else + { + if (Objective1Quantity() <= 1) + return ""; + else + //increases when u hit a dead large monster + return Objective1CurrentQuantityMonster().ToString() + "/"; + } + } + /// /// Gets the rank name from identifier. /// @@ -9428,7 +9455,7 @@ public string GetObjective1Quantity(bool isLargeImageText = false) /// public string GetRankNameFromID(int id, bool isLargeImageText = false) { - if (ShowDiscordQuestNames() && !(isLargeImageText)) return ""; + if (DiscordManager.ShowDiscordQuestNames() && !(isLargeImageText)) return ""; return GetRankName(id); } @@ -9474,7 +9501,7 @@ public string getMonsterIcon(int id) /// public string GetStarGrade(bool isLargeImageText = false) { - if ((ShowDiscordQuestNames() && !(isLargeImageText)) || CaravanOverride()) + if ((DiscordManager.ShowDiscordQuestNames() && !(isLargeImageText)) || CaravanOverride()) return ""; if (IsToggeableDifficulty()) @@ -9585,7 +9612,7 @@ public bool IsRavi() /// public string GetRealMonsterName(string iconName, bool isLargeImageText = false) { - if (ShowDiscordQuestNames() && !(isLargeImageText)) return ""; + if (DiscordManager.ShowDiscordQuestNames() && !(isLargeImageText)) return ""; //quest ids: //mp road: 23527 //solo road: 23628 @@ -9650,7 +9677,7 @@ public string GetRealMonsterName(string iconName, bool isLargeImageText = false) /// public string GetObjective1Name(int id, bool isLargeImageText = false) { - if (ShowDiscordQuestNames() && !(isLargeImageText)) return ""; + if (DiscordManager.ShowDiscordQuestNames() && !(isLargeImageText)) return ""; string? objValue1; Dictionary.Items.ItemIDs.TryGetValue(id, out objValue1); //returns true return objValue1 + ""; @@ -11311,6 +11338,242 @@ public TimeSpan CurrentSessionTime } } + #region ehp + public int currentMonster1MaxHP { get; set; } = 0; + /// + /// Shows the current hp percentage. + /// + /// + public static bool ShowCurrentHPPercentage() + { + Settings s = (Settings)Application.Current.TryFindResource("Settings"); + if (s.EnableCurrentHPPercentage) + return true; + else + return false; + } + + /// + /// Gets the monster1 ehp percent. + /// + /// + public string GetMonster1EHPPercent() + { + if (currentMonster1MaxHP < int.Parse(Monster1HP)) + currentMonster1MaxHP = int.Parse(Monster1HP); + + if (currentMonster1MaxHP == 0 || GetMonster1EHP() == 0) //should be OK + currentMonster1MaxHP = 1; + + if (!(ShowCurrentHPPercentage())) + return ""; + + return string.Format(" ({0:0}%)", (float)int.Parse(Monster1HP) / currentMonster1MaxHP * 100.0); + } + + /// + /// Gets the monster1 ehp. + /// + /// + public int GetMonster1EHP() + { + return DisplayMonsterEHP(Monster1DefMult(), Monster1HPInt(), Monster1DefMult()); + } + + /// + /// Gets the monster1 maximum ehp. + /// + /// + public int GetMonster1MaxEHP() + { + return currentMonster1MaxHP; + } + + #endregion + + /// + /// Gets the max faints + /// + /// + public string GetMaxFaints() + { + Settings s = (Settings)Application.Current.TryFindResource("Settings"); + + switch (s.MaxFaintsOverride) + { + default: + return MaxFaints().ToString(); + case "Normal Quests": + return MaxFaints().ToString(); + case "Shiten/Conquest/Pioneer/Daily/Caravan/Interception Quests": + return AlternativeMaxFaints().ToString(); + case "Automatic": + if (roadOverride() != null && roadOverride() == false) + return MaxFaints().ToString(); + + if + ( + ( + CaravanOverride() && ! + ( + QuestID() == 23603 || + RankBand() == 70 || + QuestID() == 23602 || + QuestID() == 23604 || + QuestID() == 23588 || + QuestID() == 23592 || + QuestID() == 23596 || + QuestID() == 23601 || + QuestID() == 23599 || + QuestID() == 23595 || + QuestID() == 23591 || + QuestID() == 23587 || + QuestID() == 23598 || + QuestID() == 23594 || + QuestID() == 23590 || + QuestID() == 23586 || + QuestID() == 23597 || + QuestID() == 23593 || + QuestID() == 23589 || + QuestID() == 23585 + ) + ) + + || + + QuestID() == 23603 || + RankBand() == 70 || + QuestID() == 23602 || + QuestID() == 23604 || + QuestID() == 23588 || + QuestID() == 23592 || + QuestID() == 23596 || + QuestID() == 23601 || + QuestID() == 23599 || + QuestID() == 23595 || + QuestID() == 23591 || + QuestID() == 23587 || + QuestID() == 23598 || + QuestID() == 23594 || + QuestID() == 23590 || + QuestID() == 23586 || + QuestID() == 23597 || + QuestID() == 23593 || + QuestID() == 23589 || + QuestID() == 23585 + ) + { + return AlternativeMaxFaints().ToString(); + } + else + { + return MaxFaints().ToString(); + } + } + } + + /// + /// Gets the color of the armor. + /// + /// + public string GetArmorColor() + { + Dictionary.ArmorColorList.ArmorColorID.TryGetValue(ArmorColor(), out string? colorname); + return colorname + ""; + } + + /// + /// Gets the weapon style from identifier. + /// + /// The identifier. + /// + public string GetWeaponStyleFromID(int id) + { + return id switch + { + 0 => "Earth", + 1 => "Heaven", + 2 => "Storm", + 3 => "Extreme", + _ => "None", + }; + } + + /// + /// Gets the area icon from identifier. + /// + /// The identifier. + /// + public string GetAreaIconFromID(int id) //TODO: are highlands, tidal island or painted falls icons correct? + { + if (id >= 470 && id < 0) + return "https://raw.githubusercontent.com/DorielRivalet/mhfz-overlay/main/img/icon/cattleya.png"; + else + return FindAreaIcon(id); + } + + public static string FindAreaIcon(int id) + { + List AreaGroup = new List { 0 }; + + foreach (KeyValuePair, string> kvp in AreaIconDictionary.AreaIconID) + { + List areaIDs = kvp.Key; + + if (areaIDs.Contains(id)) + { + AreaGroup = kvp.Key; + break; + } + } + return DetermineAreaIcon(AreaGroup); + } + + public static string DetermineAreaIcon(List key) + { + bool areaIcon = AreaIconDictionary.AreaIconID.ContainsKey(key); + if (!areaIcon) + return "https://raw.githubusercontent.com/DorielRivalet/mhfz-overlay/main/img/icon/cattleya.png"; + else + return AreaIconDictionary.AreaIconID[key]; + } + + /// + /// Gets the poogie clothes. + /// + /// The identifier. + /// + public string GetPoogieClothes(int id) + { + string? clothesValue1; + _ = Dictionary.PoogieCostumeList.PoogieCostumeID.TryGetValue(id, out clothesValue1); //returns true + return clothesValue1 + ""; + } + + /// + /// Gets the caravan skills. + /// + /// + public string GetCaravanSkillsWithoutMarkdown(DataLoader dataLoader) + { + int id1 = dataLoader.model.CaravanSkill1(); + int id2 = dataLoader.model.CaravanSkill2(); + int id3 = dataLoader.model.CaravanSkill3(); + + Dictionary.CaravanSkillList.CaravanSkillID.TryGetValue(id1, out string? caravanSkillName1); + Dictionary.CaravanSkillList.CaravanSkillID.TryGetValue(id2, out string? caravanSkillName2); + Dictionary.CaravanSkillList.CaravanSkillID.TryGetValue(id3, out string? caravanSkillName3); + + if (caravanSkillName1 == "" || caravanSkillName1 == "None") + return "None"; + else if (caravanSkillName2 == "" || caravanSkillName2 == "None") + return caravanSkillName1 + ""; + else if (caravanSkillName3 == "" || caravanSkillName3 == "None") + return caravanSkillName1 + ", " + caravanSkillName2; + else + return caravanSkillName1 + ", " + caravanSkillName2 + ", " + caravanSkillName3; + } + public event PropertyChangedEventHandler? PropertyChanged; ///