forked from HearthSim/Hearthstone-Deck-Tracker
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Core.cs
346 lines (306 loc) · 11.2 KB
/
Core.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
#region
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Net;
using System.Threading.Tasks;
using System.Windows;
using HearthMirror;
using Hearthstone_Deck_Tracker.Controls.Stats;
using Hearthstone_Deck_Tracker.Enums;
using Hearthstone_Deck_Tracker.Hearthstone;
using Hearthstone_Deck_Tracker.HsReplay;
using Hearthstone_Deck_Tracker.LogReader;
using Hearthstone_Deck_Tracker.Plugins;
using Hearthstone_Deck_Tracker.Utility;
using Hearthstone_Deck_Tracker.Utility.Analytics;
using Hearthstone_Deck_Tracker.Utility.Extensions;
using Hearthstone_Deck_Tracker.Utility.HotKeys;
using Hearthstone_Deck_Tracker.Utility.LogConfig;
using Hearthstone_Deck_Tracker.Utility.Logging;
using Hearthstone_Deck_Tracker.Windows;
using MahApps.Metro.Controls.Dialogs;
using Hearthstone_Deck_Tracker.Utility.Themes;
using Hearthstone_Deck_Tracker.Utility.Updating;
using WPFLocalizeExtension.Engine;
#endregion
namespace Hearthstone_Deck_Tracker
{
public static class Core
{
internal const int UpdateDelay = 16;
private static TrayIcon _trayIcon;
private static OverlayWindow _overlay;
private static Overview _statsOverview;
private static int _updateRequestsPlayer;
private static int _updateRequestsOpponent;
private static DateTime _startUpTime;
private static readonly LogWatcherManager LogWatcherManger = new LogWatcherManager();
public static Version Version { get; set; }
public static GameV2 Game { get; set; }
public static MainWindow MainWindow { get; set; }
public static Overview StatsOverview => _statsOverview ?? (_statsOverview = new Overview());
public static bool Initialized { get; private set; }
public static TrayIcon TrayIcon => _trayIcon ?? (_trayIcon = new TrayIcon());
public static OverlayWindow Overlay => _overlay ?? (_overlay = new OverlayWindow(Game));
internal static bool UpdateOverlay { get; set; } = true;
internal static bool Update { get; set; }
internal static bool CanShutdown { get; set; }
internal static event Action<bool> GameIsRunningChanged;
#pragma warning disable 1998
public static async void Initialize()
#pragma warning restore 1998
{
LocalizeDictionary.Instance.Culture = CultureInfo.GetCultureInfo("en-US");
_startUpTime = DateTime.UtcNow;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
Directory.SetCurrentDirectory(AppDomain.CurrentDomain.BaseDirectory);
Config.Load();
Log.Info($"HDT: {Helper.GetCurrentVersion()}, Operating System: {Helper.GetWindowsVersion()}, .NET Framework: {Helper.GetInstalledDotNetVersion()}");
var splashScreenWindow = new SplashScreenWindow();
#if(SQUIRREL)
if(Config.Instance.CheckForUpdates)
{
var updateCheck = Updater.StartupUpdateCheck(splashScreenWindow);
while(!updateCheck.IsCompleted)
{
await Task.Delay(500);
if(splashScreenWindow.SkipUpdate)
break;
}
}
#endif
splashScreenWindow.ShowConditional();
Log.Initialize();
Reflection.Exception += e => Log.Warn("HearthMirror Exception: " + e);
ConfigManager.Run();
LocUtil.UpdateCultureInfo();
var newUser = ConfigManager.PreviousVersion == null;
LogConfigUpdater.Run().Forget();
LogConfigWatcher.Start();
UITheme.InitializeTheme().Forget();
ThemeManager.Run();
ResourceMonitor.Run();
Game = new GameV2();
Game.SecretsManager.OnSecretsChanged += cards => Overlay.ShowSecrets(cards);
MainWindow = new MainWindow();
MainWindow.LoadConfigSettings();
MainWindow.Show();
splashScreenWindow.Close();
if(Config.Instance.DisplayHsReplayNoteLive && ConfigManager.PreviousVersion != null && ConfigManager.PreviousVersion < new Version(1, 1, 0))
MainWindow.FlyoutHsReplayNote.IsOpen = true;
if(ConfigManager.UpdatedVersion != null)
{
#if(!SQUIRREL)
Updater.Cleanup();
#endif
MainWindow.FlyoutUpdateNotes.IsOpen = true;
MainWindow.UpdateNotesControl.SetHighlight(ConfigManager.PreviousVersion);
#if(SQUIRREL && !DEV)
if(Config.Instance.CheckForDevUpdates && !Config.Instance.AllowDevUpdates.HasValue)
MainWindow.ShowDevUpdatesMessage();
#endif
}
DataIssueResolver.Run();
#if(!SQUIRREL)
Helper.CopyReplayFiles();
#endif
BackupManager.Run();
if(Config.Instance.PlayerWindowOnStart)
Windows.PlayerWindow.Show();
if(Config.Instance.OpponentWindowOnStart)
Windows.OpponentWindow.Show();
if(Config.Instance.TimerWindowOnStartup)
Windows.TimerWindow.Show();
PluginManager.Instance.LoadPluginsFromDefaultPath();
MainWindow.Options.OptionsTrackerPlugins.Load();
PluginManager.Instance.StartUpdateAsync();
UpdateOverlayAsync();
if(Config.Instance.ShowCapturableOverlay)
{
Windows.CapturableOverlay = new CapturableOverlayWindow();
Windows.CapturableOverlay.Show();
}
if(LogConfigUpdater.LogConfigUpdateFailed)
MainWindow.ShowLogConfigUpdateFailedMessage().Forget();
else if(LogConfigUpdater.LogConfigUpdated && Game.IsRunning)
{
ShowRestartRequiredMessageAsync().Forget();
Overlay.ShowRestartRequiredWarning();
}
LogWatcherManger.Start(Game).Forget();
RemoteConfig.Instance.Load();
HotKeyManager.Load();
if(Helper.HearthstoneDirExists && Config.Instance.StartHearthstoneWithHDT && !Game.IsRunning)
HearthstoneRunner.StartHearthstone().Forget();
HSReplayNetHelper.UpdateAccount().Forget();
Initialized = true;
Influx.OnAppStart(
Helper.GetCurrentVersion(),
newUser,
HSReplayNetOAuth.IsFullyAuthenticated,
HSReplayNetOAuth.AccountData?.IsPremium?.Equals("true", StringComparison.InvariantCultureIgnoreCase) ?? false,
(int)(DateTime.UtcNow - _startUpTime).TotalSeconds,
PluginManager.Instance.Plugins.Count
);
}
private static async Task ShowRestartRequiredMessageAsync()
{
MainWindow.ActivateWindow();
while(MainWindow.Visibility != Visibility.Visible || MainWindow.WindowState == WindowState.Minimized)
await Task.Delay(100);
await MainWindow.ShowMessageAsync("Hearthstone restart required", "The log.config file has been updated. HDT may not work properly until Hearthstone has been restarted.");
}
private static async void UpdateOverlayAsync()
{
#if(!SQUIRREL)
if(Config.Instance.CheckForUpdates)
Updater.CheckForUpdates(true);
#endif
var hsForegroundChanged = false;
while(UpdateOverlay)
{
if(Config.Instance.CheckForUpdates)
Updater.CheckForUpdates();
if(User32.GetHearthstoneWindow() != IntPtr.Zero)
{
if(Game.CurrentRegion == Region.UNKNOWN)
{
//game started
Helper.VerifyHearthstonePath();
Game.CurrentRegion = await Helper.GetCurrentRegion();
if(Game.CurrentRegion != Region.UNKNOWN)
{
BackupManager.Run();
Game.MetaData.HearthstoneBuild = null;
}
}
Overlay.UpdatePosition();
if(!Game.IsRunning)
{
Overlay.Update(true);
Windows.CapturableOverlay?.UpdateContentVisibility();
}
TrayIcon.MenuItemStartHearthstone.Visible = false;
Game.IsRunning = true;
GameIsRunningChanged?.Invoke(true);
Helper.GameWindowState = User32.GetHearthstoneWindowState();
Windows.CapturableOverlay?.Update();
if(User32.IsHearthstoneInForeground() && Helper.GameWindowState != WindowState.Minimized)
{
if(hsForegroundChanged)
{
Overlay.Update(true);
if(Config.Instance.WindowsTopmostIfHsForeground && Config.Instance.WindowsTopmost)
{
//if player topmost is set to true before opponent:
//clicking on the playerwindow and back to hs causes the playerwindow to be behind hs.
//other way around it works for both windows... what?
Windows.OpponentWindow.Topmost = true;
Windows.PlayerWindow.Topmost = true;
Windows.TimerWindow.Topmost = true;
}
hsForegroundChanged = false;
}
}
else if(!hsForegroundChanged)
{
if(Config.Instance.WindowsTopmostIfHsForeground && Config.Instance.WindowsTopmost)
{
Windows.PlayerWindow.Topmost = false;
Windows.OpponentWindow.Topmost = false;
Windows.TimerWindow.Topmost = false;
}
hsForegroundChanged = true;
}
}
else if(Game.IsRunning)
{
Game.IsRunning = false;
GameIsRunningChanged?.Invoke(false);
Overlay.ShowOverlay(false);
Watchers.Stop();
if(Windows.CapturableOverlay != null)
{
Windows.CapturableOverlay.UpdateContentVisibility();
await Task.Delay(100);
Windows.CapturableOverlay.ForcedWindowState = WindowState.Minimized;
Windows.CapturableOverlay.WindowState = WindowState.Minimized;
}
Log.Info("Exited game");
Game.CurrentRegion = Region.UNKNOWN;
Log.Info("Reset region");
await Reset();
Game.IsInMenu = true;
Game.InvalidateMatchInfoCache();
Overlay.HideRestartRequiredWarning();
Helper.ClearCachedHearthstoneBuild();
TurnTimer.Instance.Stop();
TrayIcon.MenuItemStartHearthstone.Visible = true;
if(Config.Instance.CloseWithHearthstone)
MainWindow.Close();
}
await Task.Delay(UpdateDelay);
}
CanShutdown = true;
}
private static bool _resetting;
public static async Task Reset()
{
if(_resetting)
{
Log.Warn("Reset already in progress.");
return;
}
_resetting = true;
var stoppedReader = await LogWatcherManger.Stop();
Game.Reset();
if(DeckList.Instance.ActiveDeck != null)
Game.IsUsingPremade = true;
await Task.Delay(1000);
if(stoppedReader)
LogWatcherManger.Start(Game).Forget();
Overlay.HideSecrets();
Overlay.Update(false);
UpdatePlayerCards(true);
_resetting = false;
}
internal static async void UpdatePlayerCards(bool reset = false)
{
_updateRequestsPlayer++;
await Task.Delay(100);
_updateRequestsPlayer--;
if(_updateRequestsPlayer > 0)
return;
Overlay.UpdatePlayerCards(new List<Card>(Game.Player.PlayerCardList), reset);
if(Windows.PlayerWindow.IsVisible)
Windows.PlayerWindow.UpdatePlayerCards(new List<Card>(Game.Player.PlayerCardList), reset);
}
internal static async void UpdateOpponentCards(bool reset = false)
{
_updateRequestsOpponent++;
await Task.Delay(100);
_updateRequestsOpponent--;
if(_updateRequestsOpponent > 0)
return;
Overlay.UpdateOpponentCards(new List<Card>(Game.Opponent.OpponentCardList), reset);
if(Windows.OpponentWindow.IsVisible)
Windows.OpponentWindow.UpdateOpponentCards(new List<Card>(Game.Opponent.OpponentCardList), reset);
}
internal static async Task StopLogWacher() => await LogWatcherManger.Stop(true);
public static class Windows
{
private static PlayerWindow _playerWindow;
private static OpponentWindow _opponentWindow;
private static TimerWindow _timerWindow;
private static StatsWindow _statsWindow;
public static PlayerWindow PlayerWindow => _playerWindow ?? (_playerWindow = new PlayerWindow(Game));
public static OpponentWindow OpponentWindow => _opponentWindow ?? (_opponentWindow = new OpponentWindow(Game));
public static TimerWindow TimerWindow => _timerWindow ?? (_timerWindow = new TimerWindow(Config.Instance));
public static StatsWindow StatsWindow => _statsWindow ?? (_statsWindow = new StatsWindow());
public static CapturableOverlayWindow CapturableOverlay;
}
internal static bool StatsOverviewInitialized => _statsOverview != null;
}
}