From 88ea5086acf5d6fdf70b62e50a7ca424f56a5631 Mon Sep 17 00:00:00 2001 From: Jos Date: Mon, 14 Mar 2022 12:15:49 +0100 Subject: [PATCH] Added cooldown overview and extra servers. --- NewWorldCompanion.Entities/CooldownTimer.cs | 32 ++++ NewWorldCompanion.Entities/PriceServer.cs | 2 +- NewWorldCompanion.Entities/SettingsNWC.cs | 2 +- NewWorldCompanion.Events/PriceServerEvents.cs | 13 ++ NewWorldCompanion.Helpers/ScreenCapture.cs | 2 +- .../ICooldownManager.cs | 22 +++ .../INewWorldDataStore.cs | 1 + NewWorldCompanion.Services/CooldownManager.cs | 98 ++++++++++ .../CraftingRecipeManager.cs | 7 +- ...javelindata_itemdefinitions_master.loc.xml | 2 + .../NewWorldDataStore.cs | 12 ++ NewWorldCompanion.Services/OverlayHandler.cs | 1 + NewWorldCompanion.Services/PriceManager.cs | 115 ++++++------ NewWorldCompanion.Services/SettingsManager.cs | 7 +- NewWorldCompanion/App.xaml.cs | 7 +- NewWorldCompanion/NewWorldCompanion.csproj | 1 + .../Dialogs/CooldownConfigViewModel.cs | 59 ++++++ .../Tabs/Config/ConfigOverlayViewModel.cs | 15 +- .../ViewModels/Tabs/CooldownViewModel.cs | 173 ++++++++++++++++++ .../ViewModels/Tabs/CraftingViewModel.cs | 8 +- .../Views/Dialogs/CooldownConfigView.xaml | 31 ++++ .../Views/Dialogs/CooldownConfigView.xaml.cs | 36 ++++ NewWorldCompanion/Views/MainWindow.xaml | 3 + NewWorldCompanion/Views/MainWindow.xaml.cs | 9 +- .../Views/Tabs/CooldownView.xaml | 78 ++++++++ .../Views/Tabs/CooldownView.xaml.cs | 28 +++ NewWorldCompanion/common.props | 4 +- 27 files changed, 694 insertions(+), 74 deletions(-) create mode 100644 NewWorldCompanion.Entities/CooldownTimer.cs create mode 100644 NewWorldCompanion.Events/PriceServerEvents.cs create mode 100644 NewWorldCompanion.Interfaces/ICooldownManager.cs create mode 100644 NewWorldCompanion.Services/CooldownManager.cs create mode 100644 NewWorldCompanion/ViewModels/Dialogs/CooldownConfigViewModel.cs create mode 100644 NewWorldCompanion/ViewModels/Tabs/CooldownViewModel.cs create mode 100644 NewWorldCompanion/Views/Dialogs/CooldownConfigView.xaml create mode 100644 NewWorldCompanion/Views/Dialogs/CooldownConfigView.xaml.cs create mode 100644 NewWorldCompanion/Views/Tabs/CooldownView.xaml create mode 100644 NewWorldCompanion/Views/Tabs/CooldownView.xaml.cs diff --git a/NewWorldCompanion.Entities/CooldownTimer.cs b/NewWorldCompanion.Entities/CooldownTimer.cs new file mode 100644 index 0000000..3386dc1 --- /dev/null +++ b/NewWorldCompanion.Entities/CooldownTimer.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.Json.Serialization; +using System.Threading.Tasks; + +namespace NewWorldCompanion.Entities +{ + public class CooldownTimer + { + public string Name { get; set; } = string.Empty; + public TimeSpan Duration { get; set; } = TimeSpan.FromHours(24); + public DateTime StartTime { get; set; } = DateTime.Now; + + [JsonIgnore] + public bool Ready + { + get { return DateTime.Now > StartTime + Duration; } + } + + [JsonIgnore] + public TimeSpan RemainingTime + { + get + { + TimeSpan remainder = Duration - (DateTime.Now - StartTime); + return remainder > TimeSpan.Zero ? remainder : TimeSpan.Zero; + } + } + } +} diff --git a/NewWorldCompanion.Entities/PriceServer.cs b/NewWorldCompanion.Entities/PriceServer.cs index 4deed1b..68ba6f5 100644 --- a/NewWorldCompanion.Entities/PriceServer.cs +++ b/NewWorldCompanion.Entities/PriceServer.cs @@ -9,6 +9,6 @@ namespace NewWorldCompanion.Entities public class PriceServer { public string Name { get; set; } = string.Empty; - public string Id { get; set; } = string.Empty; + public int Id { get; set; } = 1; } } diff --git a/NewWorldCompanion.Entities/SettingsNWC.cs b/NewWorldCompanion.Entities/SettingsNWC.cs index d44caae..27c7b66 100644 --- a/NewWorldCompanion.Entities/SettingsNWC.cs +++ b/NewWorldCompanion.Entities/SettingsNWC.cs @@ -12,7 +12,7 @@ public class SettingsNWC public bool DebugModeActive { get; set; } = false; // Overlay - public string ServerId { get; set; } = "1"; + public int PriceServerId { get; set; } = 1; // Shape detection public int EmguAreaLower { get; set; } = 10000; diff --git a/NewWorldCompanion.Events/PriceServerEvents.cs b/NewWorldCompanion.Events/PriceServerEvents.cs new file mode 100644 index 0000000..6bd382d --- /dev/null +++ b/NewWorldCompanion.Events/PriceServerEvents.cs @@ -0,0 +1,13 @@ +using Prism.Events; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NewWorldCompanion.Events +{ + public class PriceServerListUpdatedEvent : PubSubEvent + { + } +} diff --git a/NewWorldCompanion.Helpers/ScreenCapture.cs b/NewWorldCompanion.Helpers/ScreenCapture.cs index 5f2cf02..2941982 100644 --- a/NewWorldCompanion.Helpers/ScreenCapture.cs +++ b/NewWorldCompanion.Helpers/ScreenCapture.cs @@ -55,7 +55,7 @@ public Bitmap GetScreenCapture(IntPtr windowHandle) PInvoke.User32.GetWindowRect(windowHandle, out region); int width = (int)((region.right - region.left) * 0.75); - int height = 400; + int height = (int)((region.bottom - region.top) * 0.50); PInvoke.User32.CURSORINFO cursorInfo = new PInvoke.User32.CURSORINFO(); cursorInfo.cbSize = Marshal.SizeOf(cursorInfo); diff --git a/NewWorldCompanion.Interfaces/ICooldownManager.cs b/NewWorldCompanion.Interfaces/ICooldownManager.cs new file mode 100644 index 0000000..824e8b3 --- /dev/null +++ b/NewWorldCompanion.Interfaces/ICooldownManager.cs @@ -0,0 +1,22 @@ +using NewWorldCompanion.Entities; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NewWorldCompanion.Interfaces +{ + public interface ICooldownManager + { + List CooldownTimers + { + get; + } + + void AddCooldown(CooldownTimer cooldownTimer); + void RemoveCooldown(CooldownTimer cooldownTimer); + + void SaveCooldowns(); + } +} diff --git a/NewWorldCompanion.Interfaces/INewWorldDataStore.cs b/NewWorldCompanion.Interfaces/INewWorldDataStore.cs index 1e7d4ad..d18a074 100644 --- a/NewWorldCompanion.Interfaces/INewWorldDataStore.cs +++ b/NewWorldCompanion.Interfaces/INewWorldDataStore.cs @@ -11,5 +11,6 @@ public interface INewWorldDataStore { List GetCraftingRecipes(); bool IsBindOnPickup(string itemName); + string GetItemId(string itemName); } } diff --git a/NewWorldCompanion.Services/CooldownManager.cs b/NewWorldCompanion.Services/CooldownManager.cs new file mode 100644 index 0000000..129dc52 --- /dev/null +++ b/NewWorldCompanion.Services/CooldownManager.cs @@ -0,0 +1,98 @@ +using NewWorldCompanion.Entities; +using NewWorldCompanion.Interfaces; +using Prism.Events; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Text.Json; +using System.Threading.Tasks; + +namespace NewWorldCompanion.Services +{ + public class CooldownManager : ICooldownManager + { + private readonly IEventAggregator _eventAggregator; + + private List _cooldownTimers = new List(); + + // Start of Constructor region + + #region Constructor + + public CooldownManager(IEventAggregator eventAggregator) + { + // Init IEventAggregator + _eventAggregator = eventAggregator; + + // Init cooldowns + LoadCooldowns(); + } + + #endregion + + // Start of Properties region + + #region Properties + + public List CooldownTimers { get => _cooldownTimers; } + + #endregion + + // Start of Events region + + #region Events + + #endregion + + // Start of Methods region + + #region Methods + + public void AddCooldown(CooldownTimer cooldownTimer) + { + _cooldownTimers.Add(cooldownTimer); + } + + public void RemoveCooldown(CooldownTimer cooldownTimer) + { + _cooldownTimers.Remove(cooldownTimer); + } + + private void LoadCooldowns() + { + _cooldownTimers.Clear(); + + string fileName = "Config/Cooldowns.json"; + if (File.Exists(fileName)) + { + using FileStream stream = File.OpenRead(fileName); + _cooldownTimers = JsonSerializer.Deserialize>(stream) ?? new List(); + } + + // Sort list + _cooldownTimers.Sort((x, y) => + { + int result = x.RemainingTime - y.RemainingTime > TimeSpan.Zero ? 1 : -1; + return result != 0 ? result : string.Compare(x.Name, y.Name, StringComparison.Ordinal); + }); + + SaveCooldowns(); + } + + public void SaveCooldowns() + { + string fileName = "Config/Cooldowns.json"; + string path = Path.GetDirectoryName(fileName) ?? string.Empty; + Directory.CreateDirectory(path); + + using FileStream stream = File.Create(fileName); + var options = new JsonSerializerOptions { WriteIndented = true }; + JsonSerializer.Serialize(stream, CooldownTimers, options); + } + + #endregion + + } +} diff --git a/NewWorldCompanion.Services/CraftingRecipeManager.cs b/NewWorldCompanion.Services/CraftingRecipeManager.cs index 746de30..d14f348 100644 --- a/NewWorldCompanion.Services/CraftingRecipeManager.cs +++ b/NewWorldCompanion.Services/CraftingRecipeManager.cs @@ -56,7 +56,7 @@ private void LoadRecipes() { _craftingRecipes.Clear(); - string fileName = "CraftingRecipeProgress.json"; + string fileName = "Config/CraftingRecipeProgress.json"; if (File.Exists(fileName)) { using FileStream stream = File.OpenRead(fileName); @@ -93,7 +93,10 @@ private void LoadRecipes() public void SaveRecipes() { - string fileName = "CraftingRecipeProgress.json"; + string fileName = "Config/CraftingRecipeProgress.json"; + string path = Path.GetDirectoryName(fileName) ?? string.Empty; + Directory.CreateDirectory(path); + using FileStream stream = File.Create(fileName); var options = new JsonSerializerOptions { WriteIndented = true }; JsonSerializer.Serialize(stream, CraftingRecipes, options); diff --git a/NewWorldCompanion.Services/Data/javelindata_itemdefinitions_master.loc.xml b/NewWorldCompanion.Services/Data/javelindata_itemdefinitions_master.loc.xml index cf46d1b..6207402 100644 --- a/NewWorldCompanion.Services/Data/javelindata_itemdefinitions_master.loc.xml +++ b/NewWorldCompanion.Services/Data/javelindata_itemdefinitions_master.loc.xml @@ -28420,5 +28420,7 @@ What was previously a standard hunter's bow has been warped by the Land. It serves as a reminder to its wielder to fear the Earth. Royal Executioner's Axe With the fall of this blade I pray that this sinner be redeemed. + The Indigo Flame + The Flame of your dedication burns bright within you. diff --git a/NewWorldCompanion.Services/NewWorldDataStore.cs b/NewWorldCompanion.Services/NewWorldDataStore.cs index 4d27928..fd42f99 100644 --- a/NewWorldCompanion.Services/NewWorldDataStore.cs +++ b/NewWorldCompanion.Services/NewWorldDataStore.cs @@ -145,6 +145,7 @@ public List GetCraftingRecipes() public bool IsBindOnPickup(string itemName) { + //TODO Needs improvement. Look into more properties like IsTradable, quests, etc. var localisationId = _itemDefinitionsLocalisation.FirstOrDefault(x => x.Value.Equals(itemName, StringComparison.OrdinalIgnoreCase)).Key; var item = _masterItemDefinitionsCraftingJson.FirstOrDefault(i => i.Name.Equals($"@{localisationId}", StringComparison.OrdinalIgnoreCase)); if (item != null) @@ -154,6 +155,17 @@ public bool IsBindOnPickup(string itemName) return true; } + public string GetItemId(string itemName) + { + var localisationId = _itemDefinitionsLocalisation.FirstOrDefault(x => x.Value.Equals(itemName, StringComparison.OrdinalIgnoreCase)).Key; + var item = _masterItemDefinitionsCraftingJson.FirstOrDefault(i => i.Name.Equals($"@{localisationId}", StringComparison.OrdinalIgnoreCase)); + if (item != null) + { + return item.ItemID; + } + return string.Empty; + } + #endregion diff --git a/NewWorldCompanion.Services/OverlayHandler.cs b/NewWorldCompanion.Services/OverlayHandler.cs index 085687c..c12d108 100644 --- a/NewWorldCompanion.Services/OverlayHandler.cs +++ b/NewWorldCompanion.Services/OverlayHandler.cs @@ -201,6 +201,7 @@ private void Timer_Tick(object? sender, EventArgs e) private void HandleOcrTextReadyEvent() { _itemName = _ocrHandler.OcrText; + //TODO Cleanup name. For example Toilvium -> Tolvium if (!_itemName.Equals(_itemNamePrevious)) { _priceManager.UpdatePriceData(_itemName); diff --git a/NewWorldCompanion.Services/PriceManager.cs b/NewWorldCompanion.Services/PriceManager.cs index 7981afa..b9d42bd 100644 --- a/NewWorldCompanion.Services/PriceManager.cs +++ b/NewWorldCompanion.Services/PriceManager.cs @@ -1,12 +1,11 @@ using NewWorldCompanion.Entities; +using NewWorldCompanion.Events; using NewWorldCompanion.Interfaces; using Prism.Events; using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; -using System.Net.Http; -using System.Text; using System.Text.Json; using System.Threading.Tasks; @@ -17,8 +16,8 @@ public class PriceManager : IPriceManager private readonly IEventAggregator _eventAggregator; private readonly ISettingsManager _settingsManager; private readonly IHttpClientHandler _httpClientHandler; + private readonly INewWorldDataStore _newWorldDataStore; - private Dictionary _itemMappings = new Dictionary(); private Dictionary _priceCache = new Dictionary(); private List _priceRequestQueue = new List(); private bool _priceRequestQueueBusy = false; @@ -28,7 +27,7 @@ public class PriceManager : IPriceManager #region Constructor - public PriceManager(IEventAggregator eventAggregator, ISettingsManager settingsManager, IHttpClientHandler httpClientHandler) + public PriceManager(IEventAggregator eventAggregator, ISettingsManager settingsManager, IHttpClientHandler httpClientHandler, INewWorldDataStore newWorldDataStore) { // Init IEventAggregator _eventAggregator = eventAggregator; @@ -36,42 +35,10 @@ public PriceManager(IEventAggregator eventAggregator, ISettingsManager settingsM // Init services _settingsManager = settingsManager; _httpClientHandler = httpClientHandler; + _newWorldDataStore = newWorldDataStore; // Init servers - _servers.Add(new PriceServer() - { - Id = "1", - Name = "Camelot" - }); - _servers.Add(new PriceServer() - { - Id = "2", - Name = "El Dorado" - }); - - Task.Run(async () => - { - try - { - string json = await _httpClientHandler.GetRequest("https://nwmarketprices.com/cn/") ?? string.Empty; - var root = JsonSerializer.Deserialize(json); - var mappings = JsonSerializer.Deserialize>>(root?.cn ?? string.Empty) ?? new List>(); - foreach (var mapping in mappings) - { - string key = ((JsonElement)mapping[0]).GetString() ?? string.Empty; - int value = ((JsonElement)mapping[1]).GetInt32(); - - if (!string.IsNullOrWhiteSpace(key)) - { - _itemMappings.TryAdd(key, value); - } - } - } - catch (Exception) - { - - } - }); + UpdateServerList(); } #endregion @@ -80,7 +47,7 @@ public PriceManager(IEventAggregator eventAggregator, ISettingsManager settingsM #region Properties - public string ServerId { get => _settingsManager.Settings.ServerId; } + public int ServerId { get => _settingsManager.Settings.PriceServerId; } public List Servers { get => _servers; set => _servers = value; } #endregion @@ -95,6 +62,37 @@ public PriceManager(IEventAggregator eventAggregator, ISettingsManager settingsM #region Methods + private async void UpdateServerList() + { + try + { + string json = await _httpClientHandler.GetRequest("https://nwmarketprices.com/servers/") ?? string.Empty; + var root = JsonSerializer.Deserialize(json); + var mappings = JsonSerializer.Deserialize>>(root?.servers ?? string.Empty) ?? new List>(); + foreach (var mapping in mappings) + { + string serverName = ((JsonElement)mapping[0]).GetString() ?? string.Empty; + int serverId = ((JsonElement)mapping[1]).GetInt32(); + + if (!string.IsNullOrWhiteSpace(serverName)) + { + _servers.Add(new PriceServer() + { + Id = serverId, + Name = serverName + }); + + } + } + } + catch (Exception) + { + + } + + _eventAggregator.GetEvent().Publish(); + } + public NwmarketpriceJson GetPriceData(string itemName) { var nwmarketpriceJson = new NwmarketpriceJson(); @@ -111,22 +109,33 @@ public void UpdatePriceData(string itemName) _priceRequestQueueBusy = true; Task task = Task.Run(async () => { - bool isValid = _itemMappings.TryGetValue(itemName, out var itemId); - if (isValid) + string itemId = _newWorldDataStore.GetItemId(itemName); + if (!string.IsNullOrWhiteSpace(itemId)) { try { - string uri = $"https://nwmarketprices.com/{itemId}/{ServerId}?cn_id={itemId}"; - string json = await _httpClientHandler.GetRequest(uri) ?? string.Empty; - - var nwmarketpriceJson = JsonSerializer.Deserialize(json); - if (nwmarketpriceJson != null) + string uri = $"https://nwmarketprices.com/0/{ServerId}?cn_id={itemId.ToLower()}"; + string json = await _httpClientHandler.GetRequest(uri); + if (!string.IsNullOrWhiteSpace(json)) { - Debug.WriteLine($"item_name: {nwmarketpriceJson.item_name}"); - Debug.WriteLine($"recent_lowest_price: {nwmarketpriceJson.recent_lowest_price}"); - Debug.WriteLine($"last_checked: {nwmarketpriceJson.last_checked}"); - - _priceCache[itemName] = nwmarketpriceJson; + var nwmarketpriceJson = JsonSerializer.Deserialize(json); + if (nwmarketpriceJson != null) + { + Debug.WriteLine($"item_name: {nwmarketpriceJson.item_name}"); + Debug.WriteLine($"recent_lowest_price: {nwmarketpriceJson.recent_lowest_price}"); + Debug.WriteLine($"last_checked: {nwmarketpriceJson.last_checked}"); + + _priceCache[itemName] = nwmarketpriceJson; + } + } + else + { + _priceCache[itemName] = new NwmarketpriceJson + { + item_name = itemName, + recent_lowest_price = "no data", + last_checked = "no data" + }; } } catch (Exception){}; @@ -147,9 +156,9 @@ public void UpdatePriceData(string itemName) #endregion - private class RootCn + private class RootServers { - public string cn { get; set; } = string.Empty; + public string servers { get; set; } = string.Empty; } } } diff --git a/NewWorldCompanion.Services/SettingsManager.cs b/NewWorldCompanion.Services/SettingsManager.cs index 586e936..da68c2f 100644 --- a/NewWorldCompanion.Services/SettingsManager.cs +++ b/NewWorldCompanion.Services/SettingsManager.cs @@ -51,7 +51,7 @@ public SettingsManager(IEventAggregator eventAggregator) private void LoadSettings() { - string fileName = "Settings.json"; + string fileName = "Config/Settings.json"; if (File.Exists(fileName)) { using FileStream stream = File.OpenRead(fileName); @@ -63,7 +63,10 @@ private void LoadSettings() public void SaveSettings() { - string fileName = "Settings.json"; + string fileName = "Config/Settings.json"; + string path = Path.GetDirectoryName(fileName) ?? string.Empty; + Directory.CreateDirectory(path); + using FileStream stream = File.Create(fileName); var options = new JsonSerializerOptions { WriteIndented = true }; JsonSerializer.Serialize(stream, _settings, options); diff --git a/NewWorldCompanion/App.xaml.cs b/NewWorldCompanion/App.xaml.cs index 8528a0c..bf92622 100644 --- a/NewWorldCompanion/App.xaml.cs +++ b/NewWorldCompanion/App.xaml.cs @@ -1,4 +1,5 @@ -using NewWorldCompanion.Interfaces; +using MahApps.Metro.Controls.Dialogs; +using NewWorldCompanion.Interfaces; using NewWorldCompanion.Services; using NewWorldCompanion.Views; using Prism.Ioc; @@ -21,6 +22,7 @@ public partial class App : PrismApplication protected override void RegisterTypes(IContainerRegistry containerRegistry) { // Register services + containerRegistry.RegisterSingleton(); containerRegistry.RegisterSingleton(); containerRegistry.RegisterSingleton(); containerRegistry.RegisterSingleton(); @@ -30,6 +32,9 @@ protected override void RegisterTypes(IContainerRegistry containerRegistry) containerRegistry.RegisterSingleton(); containerRegistry.RegisterSingleton(); containerRegistry.RegisterSingleton(); + + // Register Metro + containerRegistry.RegisterSingleton(); } protected override Window CreateShell() diff --git a/NewWorldCompanion/NewWorldCompanion.csproj b/NewWorldCompanion/NewWorldCompanion.csproj index 95fe413..32973f9 100644 --- a/NewWorldCompanion/NewWorldCompanion.csproj +++ b/NewWorldCompanion/NewWorldCompanion.csproj @@ -33,6 +33,7 @@ + diff --git a/NewWorldCompanion/ViewModels/Dialogs/CooldownConfigViewModel.cs b/NewWorldCompanion/ViewModels/Dialogs/CooldownConfigViewModel.cs new file mode 100644 index 0000000..1856312 --- /dev/null +++ b/NewWorldCompanion/ViewModels/Dialogs/CooldownConfigViewModel.cs @@ -0,0 +1,59 @@ +using NewWorldCompanion.Entities; +using Prism.Commands; +using Prism.Mvvm; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NewWorldCompanion.ViewModels.Dialogs +{ + public class CooldownConfigViewModel : BindableBase + { + private CooldownTimer _cooldownTimer = new CooldownTimer(); + + // Start of Constructor region + + #region Constructor + + public CooldownConfigViewModel(Action closeHandler, CooldownTimer cooldownTimer) + { + // Init View commands + CooldownConfigDoneCommand = new DelegateCommand(CooldownConfigDoneExecute); + CloseCommand = new DelegateCommand(closeHandler); + + _cooldownTimer = cooldownTimer; + } + + #endregion + + // Start of Properties region + + #region Properties + + public DelegateCommand CooldownConfigDoneCommand { get; } + public DelegateCommand CloseCommand { get; } + + public CooldownTimer CooldownTimer { get => _cooldownTimer; set => _cooldownTimer = value; } + + #endregion + + // Start of Events region + + #region Events + + #endregion + + // Start of Methods region + + #region Methods + + private void CooldownConfigDoneExecute() + { + CloseCommand.Execute(this); + } + + #endregion + } +} \ No newline at end of file diff --git a/NewWorldCompanion/ViewModels/Tabs/Config/ConfigOverlayViewModel.cs b/NewWorldCompanion/ViewModels/Tabs/Config/ConfigOverlayViewModel.cs index e27f181..84742b8 100644 --- a/NewWorldCompanion/ViewModels/Tabs/Config/ConfigOverlayViewModel.cs +++ b/NewWorldCompanion/ViewModels/Tabs/Config/ConfigOverlayViewModel.cs @@ -1,4 +1,5 @@ using NewWorldCompanion.Entities; +using NewWorldCompanion.Events; using NewWorldCompanion.Interfaces; using Prism.Events; using Prism.Mvvm; @@ -29,13 +30,11 @@ public ConfigOverlayViewModel(IEventAggregator eventAggregator, ISettingsManager { // Init IEventAggregator _eventAggregator = eventAggregator; + _eventAggregator.GetEvent().Subscribe(HandlePriceServerListUpdatedEvent); // Init services _settingsManager = settingsManager; _priceManager = priceManager; - - // Init servers - updateServerList(); } #endregion @@ -59,7 +58,7 @@ public int ServerIndex if (_serverIndex >= 0 && Servers.Count > _serverIndex) { - _settingsManager.Settings.ServerId = Servers[value].Id; + _settingsManager.Settings.PriceServerId = Servers[value].Id; _settingsManager.SaveSettings(); } } @@ -71,19 +70,23 @@ public int ServerIndex #region Events + private void HandlePriceServerListUpdatedEvent() + { + updateServerList(); + } + #endregion // Start of Methods region #region Methods - private void updateServerList() { Servers.Clear(); Servers.AddRange(_priceManager.Servers); - int serverIndex = Servers.ToList().FindIndex(s => s.Id == _settingsManager.Settings.ServerId); + int serverIndex = Servers.ToList().FindIndex(s => s.Id == _settingsManager.Settings.PriceServerId); if (serverIndex != -1) { ServerIndex = serverIndex; diff --git a/NewWorldCompanion/ViewModels/Tabs/CooldownViewModel.cs b/NewWorldCompanion/ViewModels/Tabs/CooldownViewModel.cs new file mode 100644 index 0000000..c2e9dad --- /dev/null +++ b/NewWorldCompanion/ViewModels/Tabs/CooldownViewModel.cs @@ -0,0 +1,173 @@ +using MahApps.Metro.Controls.Dialogs; +using NewWorldCompanion.Entities; +using NewWorldCompanion.Interfaces; +using NewWorldCompanion.ViewModels.Dialogs; +using NewWorldCompanion.Views.Dialogs; +using Prism.Commands; +using Prism.Events; +using Prism.Mvvm; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Data; + +namespace NewWorldCompanion.ViewModels.Tabs +{ + public class CooldownViewModel : BindableBase + { + private readonly IEventAggregator _eventAggregator; + private readonly IDialogCoordinator _dialogCoordinator; + private readonly ICooldownManager _cooldownManager; + + private ObservableCollection _cooldownTimers = new ObservableCollection(); + + private string _cooldownTimerName = string.Empty; + private CooldownTimer _selectedCooldownTimer = new CooldownTimer(); + + // Start of Constructor region + + #region Constructor + + public CooldownViewModel(IEventAggregator eventAggregator, IDialogCoordinator dialogCoordinator, ICooldownManager cooldownManager) + { + // Init IEventAggregator + _eventAggregator = eventAggregator; + + // Init services + _dialogCoordinator = dialogCoordinator; + _cooldownManager = cooldownManager; + + // Init View commands + AddCooldownTimerCommand = new DelegateCommand(AddCooldownTimerExecute, CanAddCooldownTimerExecute); + RefreshCooldownCommand = new DelegateCommand(RefreshCooldownExecute); + ConfigCooldownCommand = new DelegateCommand(ConfigCooldownExecute); + DeleteCooldownCommand = new DelegateCommand(DeleteCooldownCommandExecute); + + // Update cooldown timers + var updateCooldownTimer = new System.Windows.Threading.DispatcherTimer + { + Interval = TimeSpan.FromSeconds(1), + IsEnabled = true + }; + updateCooldownTimer.Tick += UpdateCooldownTimer_Tick; + + // DispatcherTimer after ctor + var dispatcherTimer = new System.Windows.Threading.DispatcherTimer + { + Interval = TimeSpan.FromSeconds(1), + IsEnabled = true + }; + dispatcherTimer.Tick += DispatcherTimer_Tick; + } + + #endregion + + // Start of Properties region + + #region Properties + + public DelegateCommand AddCooldownTimerCommand { get; } + public DelegateCommand RefreshCooldownCommand { get; } + public DelegateCommand ConfigCooldownCommand { get; } + public DelegateCommand DeleteCooldownCommand { get; } + + public ObservableCollection CooldownTimers { get => _cooldownTimers; set => _cooldownTimers = value; } + + public string CooldownTimerName + { + get => _cooldownTimerName; + set + { + SetProperty(ref _cooldownTimerName, value, () => { RaisePropertyChanged(nameof(CooldownTimerName)); }); + AddCooldownTimerCommand?.RaiseCanExecuteChanged(); + } + } + + public CooldownTimer SelectedCooldownTimer { get => _selectedCooldownTimer; set => _selectedCooldownTimer = value; } + + #endregion + + // Start of Events region + + #region Events + + private void DispatcherTimer_Tick(object? sender, EventArgs e) + { + (sender as System.Windows.Threading.DispatcherTimer)?.Stop(); + UpdateCooldowns(); + } + + private void UpdateCooldownTimer_Tick(object? sender, EventArgs e) + { + CollectionViewSource.GetDefaultView(CooldownTimers).Refresh(); + } + + #endregion + + // Start of Methods region + + #region Methods + + private void UpdateCooldowns() + { + if (Application.Current?.Dispatcher != null) + { + Application.Current?.Dispatcher.Invoke(() => + { + CooldownTimers.Clear(); + CooldownTimers.AddRange(_cooldownManager.CooldownTimers); + }); + } + } + + private bool CanAddCooldownTimerExecute() + { + return !string.IsNullOrWhiteSpace(CooldownTimerName) && + !_cooldownTimers.Any(cooldown => cooldown.Name.Equals(CooldownTimerName)); + } + + private void AddCooldownTimerExecute() + { + _cooldownTimers.Add(new CooldownTimer + { + Name = CooldownTimerName + }); + AddCooldownTimerCommand?.RaiseCanExecuteChanged(); + _cooldownManager.AddCooldown(_cooldownTimers.Last()); + _cooldownManager.SaveCooldowns(); + } + + private void RefreshCooldownExecute(object obj) + { + ((CooldownTimer)obj).StartTime = DateTime.Now; + CollectionViewSource.GetDefaultView(CooldownTimers).Refresh(); + _cooldownManager.SaveCooldowns(); + } + + private void DeleteCooldownCommandExecute(object obj) + { + CooldownTimers.Remove((CooldownTimer)obj); + _cooldownManager.RemoveCooldown((CooldownTimer)obj); + _cooldownManager.SaveCooldowns(); + } + + private async void ConfigCooldownExecute(object obj) + { + var cooldownConfigDialog = new CustomDialog() { Title = "Cooldown config" }; + var dataContext = new CooldownConfigViewModel(async instance => + { + await cooldownConfigDialog.WaitUntilUnloadedAsync(); + },(CooldownTimer)obj); + cooldownConfigDialog.Content = new CooldownConfigView() { DataContext = dataContext }; + await _dialogCoordinator.ShowMetroDialogAsync(this, cooldownConfigDialog); + await cooldownConfigDialog.WaitUntilUnloadedAsync(); + _cooldownManager.SaveCooldowns(); + } + + #endregion + } +} \ No newline at end of file diff --git a/NewWorldCompanion/ViewModels/Tabs/CraftingViewModel.cs b/NewWorldCompanion/ViewModels/Tabs/CraftingViewModel.cs index aec1a17..5b0c9a1 100644 --- a/NewWorldCompanion/ViewModels/Tabs/CraftingViewModel.cs +++ b/NewWorldCompanion/ViewModels/Tabs/CraftingViewModel.cs @@ -224,7 +224,13 @@ private void HandleOcrTextReadyEvent() // As the view is accessed by the UI it will need to be created on the UI thread Application.Current?.Dispatcher?.Invoke(() => { - ItemNameFilter = _ocrHandler.OcrText; + //TODO Cleanup name. For example Toilvium -> Tolvium + + // Only set filter for recipe items. + if (CraftingRecipes.Any(recipe => recipe.Localisation.ToLower().Contains(_ocrHandler.OcrText))) + { + ItemNameFilter = _ocrHandler.OcrText; + } }); } diff --git a/NewWorldCompanion/Views/Dialogs/CooldownConfigView.xaml b/NewWorldCompanion/Views/Dialogs/CooldownConfigView.xaml new file mode 100644 index 0000000..09fd344 --- /dev/null +++ b/NewWorldCompanion/Views/Dialogs/CooldownConfigView.xaml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/NewWorldCompanion/Views/Tabs/CooldownView.xaml.cs b/NewWorldCompanion/Views/Tabs/CooldownView.xaml.cs new file mode 100644 index 0000000..cf6bd3a --- /dev/null +++ b/NewWorldCompanion/Views/Tabs/CooldownView.xaml.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace NewWorldCompanion.Views.Tabs +{ + /// + /// Interaction logic for CooldownView.xaml + /// + public partial class CooldownView : UserControl + { + public CooldownView() + { + InitializeComponent(); + } + } +} diff --git a/NewWorldCompanion/common.props b/NewWorldCompanion/common.props index 4cc4511..e6972ff 100644 --- a/NewWorldCompanion/common.props +++ b/NewWorldCompanion/common.props @@ -1,7 +1,7 @@ - 1.0.1.0 - 1.0.1.0 + 1.0.2.0 + 1.0.2.0 Copyright © 2022 \ No newline at end of file