├── DailyArenaDeckAdvisor
├── Properties
│ ├── Resources.en.Designer.cs
│ ├── Resources.es.Designer.cs
│ ├── Resources.ru.Designer.cs
│ ├── Settings.settings
│ ├── Settings.Designer.cs
│ └── AssemblyInfo.cs
├── Resources
│ ├── cog.png
│ ├── vault.png
│ ├── DA_tiny.ico
│ ├── refresh.png
│ ├── detailed_logs.png
│ └── hard_refresh.png
├── App.xaml
├── packages.config
├── App.config
├── App.xaml.cs
├── TabTemplateSelector.cs
├── ContentTemplateSelector.cs
├── FiltersDialog.xaml.cs
├── SettingsDialog.xaml.cs
├── SettingsDialog.xaml
├── CardStats.cs
└── FiltersDialog.xaml
├── DailyArenaDeckAdvisorLauncher
├── Properties
│ ├── Resources.en.Designer.cs
│ ├── Resources.es.Designer.cs
│ ├── Resources.ru.Designer.cs
│ ├── Settings.settings
│ ├── Settings.Designer.cs
│ ├── AssemblyInfo.cs
│ ├── Resources.Designer.cs
│ ├── Resources.resx
│ ├── Resources.en.resx
│ ├── Resources.ru.resx
│ └── Resources.es.resx
├── DA_tiny.ico
├── App.xaml
├── packages.config
├── App.config
├── MainWindow.xaml
├── App.xaml.cs
└── MainWindow.xaml.cs
├── DailyArenaDeckAdvisorUpdater
├── Properties
│ ├── Resources.en.Designer.cs
│ ├── Resources.es.Designer.cs
│ ├── Resources.ru.Designer.cs
│ ├── Settings.settings
│ ├── Settings.Designer.cs
│ ├── AssemblyInfo.cs
│ ├── Resources.Designer.cs
│ ├── Resources.resx
│ ├── Resources.en.resx
│ ├── Resources.ru.resx
│ └── Resources.es.resx
├── DA_tiny.ico
├── app.manifest
├── packages.config
├── App.xaml
├── App.config
├── MainWindow.xaml
├── App.xaml.cs
├── FileLogger.cs
└── MainWindow.xaml.cs
├── DailyArenaDeckAdvisorConsole
├── appsettings.json
├── publishandsign.bat
├── DailyArenaDeckAdvisorConsole.csproj
└── Program.cs
├── libraries
├── DailyArena.Common.dll
└── DailyArena.Common.Core.dll
├── DailyArenaDeckAdvisorSetup
├── images
│ ├── app.ico
│ ├── Dialog.bmp
│ └── BannerTop.bmp
├── Product_en-us.wxl
├── Product_ru-RU.wxl
├── Product_es-ES.wxl
├── LicenseAgreementDlg_HK.wxs
├── WixUI_HK.wxs
├── Eula-en.rtf
├── Eula-es.rtf
└── DailyArenaDeckAdvisorSetup.wixproj
├── SolutionInfo.proj
├── AssemblyVersion.cs
├── DailyArena.DeckAdvisor.Common
├── IDeckAdvisorApp.cs
├── CachedState.cs
├── DailyArena.DeckAdvisor.Common.csproj
├── IDeckAdvisorProgram.cs
├── ClientVersion.cs
└── Extensions
│ ├── ProgramExtensions.cs
│ └── AppExtensions.cs
├── DailyArenaDeckAdvisor.GetData
├── Loader.cs
├── DailyArena.DeckAdvisor.GetData.csproj
└── DADAGetData.cs
├── .gitattributes
├── README.md
├── .gitignore
└── DailyArenaDeckAdvisor.sln
/DailyArenaDeckAdvisor/Properties/Resources.en.Designer.cs:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisor/Properties/Resources.es.Designer.cs:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisor/Properties/Resources.ru.Designer.cs:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisorLauncher/Properties/Resources.en.Designer.cs:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisorLauncher/Properties/Resources.es.Designer.cs:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisorLauncher/Properties/Resources.ru.Designer.cs:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisorUpdater/Properties/Resources.en.Designer.cs:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisorUpdater/Properties/Resources.es.Designer.cs:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisorUpdater/Properties/Resources.ru.Designer.cs:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisorConsole/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | //"UICulture": "ru-RU"
3 | }
4 |
--------------------------------------------------------------------------------
/libraries/DailyArena.Common.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jceddy/DailyArenaDeckAdvisor/HEAD/libraries/DailyArena.Common.dll
--------------------------------------------------------------------------------
/libraries/DailyArena.Common.Core.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jceddy/DailyArenaDeckAdvisor/HEAD/libraries/DailyArena.Common.Core.dll
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisor/Resources/cog.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jceddy/DailyArenaDeckAdvisor/HEAD/DailyArenaDeckAdvisor/Resources/cog.png
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisor/Resources/vault.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jceddy/DailyArenaDeckAdvisor/HEAD/DailyArenaDeckAdvisor/Resources/vault.png
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisorLauncher/DA_tiny.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jceddy/DailyArenaDeckAdvisor/HEAD/DailyArenaDeckAdvisorLauncher/DA_tiny.ico
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisorSetup/images/app.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jceddy/DailyArenaDeckAdvisor/HEAD/DailyArenaDeckAdvisorSetup/images/app.ico
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisorUpdater/DA_tiny.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jceddy/DailyArenaDeckAdvisor/HEAD/DailyArenaDeckAdvisorUpdater/DA_tiny.ico
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisor/Resources/DA_tiny.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jceddy/DailyArenaDeckAdvisor/HEAD/DailyArenaDeckAdvisor/Resources/DA_tiny.ico
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisor/Resources/refresh.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jceddy/DailyArenaDeckAdvisor/HEAD/DailyArenaDeckAdvisor/Resources/refresh.png
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisorSetup/images/Dialog.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jceddy/DailyArenaDeckAdvisor/HEAD/DailyArenaDeckAdvisorSetup/images/Dialog.bmp
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisorSetup/images/BannerTop.bmp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jceddy/DailyArenaDeckAdvisor/HEAD/DailyArenaDeckAdvisorSetup/images/BannerTop.bmp
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisor/Resources/detailed_logs.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jceddy/DailyArenaDeckAdvisor/HEAD/DailyArenaDeckAdvisor/Resources/detailed_logs.png
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisor/Resources/hard_refresh.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jceddy/DailyArenaDeckAdvisor/HEAD/DailyArenaDeckAdvisor/Resources/hard_refresh.png
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisor/Properties/Settings.settings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisorUpdater/Properties/Settings.settings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisorLauncher/Properties/Settings.settings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/SolutionInfo.proj:
--------------------------------------------------------------------------------
1 |
2 |
3 | 1.0.9.2
4 | 1.0.9.2
5 | 1.0.9.2
6 | © 2019-2022 DailyArena
7 | Joseph Eddy
8 |
9 |
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisorUpdater/app.manifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisor/App.xaml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisorUpdater/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisorUpdater/App.xaml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisorLauncher/App.xaml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisorLauncher/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/AssemblyVersion.cs:
--------------------------------------------------------------------------------
1 |
2 | using System.Reflection;
3 |
4 | // Version information for an assembly consists of the following four values:
5 | //
6 | // Major Version
7 | // Minor Version
8 | // Build Number
9 | // Revision
10 | //
11 | // You can specify all the values or you can default the Build and Revision Numbers
12 | // by using the '*' as shown below:
13 | // [assembly: AssemblyVersion("1.0.*")]
14 |
15 | [assembly: AssemblyVersion("1.0.9.2")]
16 | [assembly: AssemblyFileVersion("1.0.9.2")]
17 | [assembly: AssemblyCopyright("© 2019-2022 DailyArena")]
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisor/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/DailyArena.DeckAdvisor.Common/IDeckAdvisorApp.cs:
--------------------------------------------------------------------------------
1 | using DailyArena.Common.Core;
2 | using Serilog;
3 |
4 | namespace DailyArena.DeckAdvisor.Common
5 | {
6 | ///
7 | /// Interface implemented by all Deck Advisor Application/Program classes.
8 | ///
9 | public interface IDeckAdvisorApp : IApp
10 | {
11 | ///
12 | /// The application's Cached State.
13 | ///
14 | CachedState State { get; set; }
15 |
16 | ///
17 | /// Logger for first chance exceptions.
18 | ///
19 | ILogger FirstChanceLogger { get; set; }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisor.GetData/Loader.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 |
3 | namespace DailyArena.DeckAdvisor.GetData
4 | {
5 | public class Loader
6 | {
7 | static GameObject gameObject;
8 | public static void Load()
9 | {
10 | if(GameObject.Find("DADADataGetter") == null)
11 | {
12 | gameObject = new GameObject("DADADataGetter");
13 | gameObject.AddComponent();
14 | Object.DontDestroyOnLoad(gameObject);
15 | }
16 | else
17 | {
18 | Debug.Log($"[DailyArena.DeckAdvisor.GetData] Logger is already in place, no need to embed it again!");
19 | }
20 | }
21 |
22 | public static void Unload()
23 | {
24 | Object.Destroy(gameObject);
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisorLauncher/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisorUpdater/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisor/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisor/App.xaml.cs:
--------------------------------------------------------------------------------
1 | using DailyArena.DeckAdvisor.Common;
2 | using DailyArena.DeckAdvisor.Common.Extensions;
3 | using Serilog;
4 | using System.Windows;
5 |
6 | namespace DailyArena.DeckAdvisor
7 | {
8 | ///
9 | /// Interaction logic for App.xaml
10 | ///
11 | public partial class App : Application, IDeckAdvisorApp
12 | {
13 | ///
14 | /// The application's Cached State.
15 | ///
16 | public CachedState State { get; set; } = new CachedState();
17 |
18 | ///
19 | /// The application's Logger.
20 | ///
21 | public ILogger Logger { get; set; }
22 |
23 | ///
24 | /// Logger for first chance exceptions.
25 | ///
26 | public ILogger FirstChanceLogger { get; set; }
27 |
28 | ///
29 | /// The application constructor.
30 | ///
31 | public App()
32 | {
33 | this.InitializeApp();
34 |
35 | DispatcherUnhandledException += (sender, e) =>
36 | {
37 | Logger.Error(e.Exception, "DispatcherUnhandledException");
38 | };
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisor/TabTemplateSelector.cs:
--------------------------------------------------------------------------------
1 | using System.Windows;
2 | using System.Windows.Controls;
3 |
4 | namespace DailyArena.DeckAdvisor
5 | {
6 | ///
7 | /// Class that selects the template used for tab details (switches between templates for Meta Report vs. Archetype).
8 | ///
9 | public class TabTemplateSelector : DataTemplateSelector
10 | {
11 | ///
12 | /// Select the data template to use for the item being displayed.
13 | ///
14 | /// The item being displayed.
15 | /// The item's container.
16 | /// ArchetypeTabTemplate if the item is an Archetype object, MetaReportTabTemplate otherwise.
17 | public override DataTemplate SelectTemplate(object item, DependencyObject container)
18 | {
19 | Window win = Application.Current.MainWindow;
20 |
21 | if (item is Archetype)
22 | {
23 | return win.FindResource("ArchetypeTabTemplate") as DataTemplate;
24 | }
25 | else
26 | {
27 | return win.FindResource("MetaReportTabTemplate") as DataTemplate;
28 | }
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisor/ContentTemplateSelector.cs:
--------------------------------------------------------------------------------
1 | using System.Windows;
2 | using System.Windows.Controls;
3 |
4 | namespace DailyArena.DeckAdvisor
5 | {
6 | ///
7 | /// Class to select a Xaml template for the archetype tab detail view, depending on whether it's showing a deck, or a meta report.
8 | ///
9 | public class ContentTemplateSelector : DataTemplateSelector
10 | {
11 | ///
12 | /// Select the template to use depending on the item type.
13 | ///
14 | /// The item being shown in the detail view.
15 | /// The container the view is in (not used).
16 | /// ArchetypeContentTemplate if the item is an Archetype, otherwise MetaReportContentTemplate.
17 | public override DataTemplate SelectTemplate(object item, DependencyObject container)
18 | {
19 | Window win = Application.Current.MainWindow;
20 |
21 | if (item is Archetype)
22 | {
23 | return win.FindResource("ArchetypeContentTemplate") as DataTemplate;
24 | }
25 | else
26 | {
27 | return win.FindResource("MetaReportContentTemplate") as DataTemplate;
28 | }
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisor/Properties/Settings.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace DailyArena.DeckAdvisor.Properties {
12 |
13 |
14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.9.0.0")]
16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
17 |
18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
19 |
20 | public static Settings Default {
21 | get {
22 | return defaultInstance;
23 | }
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisorUpdater/Properties/Settings.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace DailyArenaDeckAdvisorUpdater.Properties {
12 |
13 |
14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.9.0.0")]
16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
17 |
18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
19 |
20 | public static Settings Default {
21 | get {
22 | return defaultInstance;
23 | }
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisorLauncher/Properties/Settings.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace DailyArenaDeckAdvisorLauncher.Properties {
12 |
13 |
14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.9.0.0")]
16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
17 |
18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
19 |
20 | public static Settings Default {
21 | get {
22 | return defaultInstance;
23 | }
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisorUpdater/MainWindow.xaml:
--------------------------------------------------------------------------------
1 |
11 |
12 | Daily ArenaDeck Advisor
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisorLauncher/MainWindow.xaml:
--------------------------------------------------------------------------------
1 |
11 |
12 | Daily ArenaDeck Advisor
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisorUpdater/App.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Reflection;
4 | using System.Windows;
5 |
6 | namespace DailyArenaDeckAdvisorUpdater
7 | {
8 | ///
9 | /// Interaction logic for App.xaml
10 | ///
11 | public partial class App : Application
12 | {
13 | ///
14 | /// Default constructer, sets up the data folder, current directory, and logging.
15 | ///
16 | public App()
17 | {
18 | var dataFolder = string.Format("{0}Low\\DailyArena\\DailyArenaDeckAdvisor", Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData));
19 | if (!Directory.Exists(dataFolder))
20 | {
21 | Directory.CreateDirectory(dataFolder);
22 | }
23 | if (!Directory.Exists($"{dataFolder}\\logs"))
24 | {
25 | Directory.CreateDirectory($"{dataFolder}\\logs");
26 | }
27 |
28 | FileLogger.FilePath = $"{dataFolder}\\logs\\updater.txt";
29 | if(File.Exists(FileLogger.FilePath))
30 | {
31 | File.Delete(FileLogger.FilePath);
32 | }
33 |
34 | string codeBase = Assembly.GetExecutingAssembly().CodeBase;
35 | UriBuilder uri = new UriBuilder(codeBase);
36 | string path = Uri.UnescapeDataString(uri.Path);
37 | Directory.SetCurrentDirectory(Path.GetDirectoryName(path));
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisorSetup/Product_en-us.wxl:
--------------------------------------------------------------------------------
1 |
2 |
3 | 1033
4 |
5 |
6 | DailyArenaDeckAdvisor
7 | DailyArena
8 | DailyArena
9 | MTGA Deck Advisor Companion App
10 |
11 |
12 | Eula-en.rtf
13 |
14 | This product requires at least Windows Vista / Server 2008.
15 | The same or a newer version of this product is already installed.
16 | You need to install the 64-bit version of this product on 64-bit Windows.
17 | You need to install the 32-bit version of this product on 32-bit Windows.
18 |
19 | The complete package.
20 | The main version including all dependencies.
21 | Main program
22 |
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisorSetup/Product_ru-RU.wxl:
--------------------------------------------------------------------------------
1 |
2 |
3 | 1033
4 |
5 |
6 | DailyArenaDeckAdvisor
7 | DailyArena
8 | DailyArena
9 | MTGA Deck Advisor Компаньон приложение
10 |
11 |
12 | Eula-ru.rtf
13 |
14 | Этот продукт требует как минимум Windows Vista / Server 2008.
15 | Та же или более новая версия этого продукта уже установлена.
16 | Вам необходимо установить 64-bit версия этого продукта на 64-bit Windows.
17 | Вам необходимо установить 32-bit версия этого продукта на 32-bit Windows.
18 |
19 | Полный пакет.
20 | Основная версия, включающая все зависимости.
21 | Основная программа
22 |
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisor.GetData/DailyArena.DeckAdvisor.GetData.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | netstandard2.0
4 |
5 |
6 |
7 |
8 |
9 |
10 | ..\..\..\..\..\..\Program Files\Wizards of the Coast\MTGA\MTGA_Data\Managed\Assembly-CSharp.dll
11 |
12 |
13 | ..\..\..\..\..\..\Program Files\Wizards of the Coast\MTGA\MTGA_Data\Managed\Newtonsoft.Json.dll
14 |
15 |
16 | ..\..\..\..\..\..\Program Files\Wizards of the Coast\MTGA\MTGA_Data\Managed\UnityEngine.dll
17 |
18 |
19 | ..\..\..\..\..\..\Program Files\Wizards of the Coast\MTGA\MTGA_Data\Managed\UnityEngine.CoreModule.dll
20 |
21 |
22 | ..\..\..\..\..\..\Program Files\Wizards of the Coast\MTGA\MTGA_Data\Managed\UnityEngine.IMGUIModule.dll
23 |
24 |
25 | ..\..\..\..\..\..\Program Files\Wizards of the Coast\MTGA\MTGA_Data\Managed\Wizards.MDN.GreProtobuf.Unity.dll
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisorSetup/Product_es-ES.wxl:
--------------------------------------------------------------------------------
1 |
2 |
3 | 1033
4 |
5 |
6 | DailyArenaDeckAdvisor
7 | DailyArena
8 | DailyArena
9 | MTGA Deck Advisor Aplicación Complementaria
10 |
11 |
12 | Eula-es.rtf
13 |
14 | Este producto requiere al menos Windows Vista / Server 2008.
15 | La misma o una versión más nueva de este producto ya está instalada.
16 | Debe instalar la versión de 64 bits de este producto en Windows de 64 bits.
17 | Debe instalar la versión de 32 bits de este producto en Windows de 32 bits.
18 |
19 | El paquete completo.
20 | La versión principal que incluye todas las dependencias.
21 | Programa principal
22 |
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisorUpdater/FileLogger.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 |
4 | namespace DailyArenaDeckAdvisorUpdater
5 | {
6 | ///
7 | /// Lightweight file logger for the updater.
8 | ///
9 | ///
10 | /// Can't use the full logger class here because the updater may have to update it.
11 | ///
12 | public static class FileLogger
13 | {
14 | ///
15 | /// The path of the log file to write to.
16 | ///
17 | public static string FilePath { get; set; }
18 |
19 | ///
20 | /// Write a debug message to the log file.
21 | ///
22 | /// The message to write.
23 | /// Arguments to include with the message.
24 | public static void Log(string message, params object[] arg)
25 | {
26 | using (StreamWriter streamWriter = new StreamWriter(FilePath, true))
27 | {
28 | streamWriter.WriteLine(message, arg);
29 | }
30 | }
31 |
32 | ///
33 | /// Write an exception message to the log file.
34 | ///
35 | /// The exception to log.
36 | /// The messate to write.
37 | /// Arguments to include wiht the message.
38 | public static void Log(Exception e, string message, params object[] arg)
39 | {
40 | using (StreamWriter streamWriter = new StreamWriter(FilePath, true))
41 | {
42 | streamWriter.WriteLine(message, arg);
43 | streamWriter.WriteLine("{0}", e.ToString());
44 | }
45 | }
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/DailyArena.DeckAdvisor.Common/CachedState.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace DailyArena.DeckAdvisor.Common
4 | {
5 | ///
6 | /// Class to Cache state information for the application.
7 | ///
8 | public class CachedState
9 | {
10 | ///
11 | /// Gets or sets the last value selected from the Format drop-down.
12 | ///
13 | public string LastFormat { get; set; }
14 |
15 | ///
16 | /// Gets or sets the last value selcted by the deck Sort drop-down.
17 | ///
18 | public string LastSort { get; set; }
19 |
20 | ///
21 | /// Gets or sets the last value selected by the deck Sort Dir drop-down.
22 | ///
23 | public string LastSortDir { get; set; }
24 |
25 | ///
26 | /// Gets or sets the State of the "rotation-proof" toggle button.
27 | ///
28 | public bool RotationProof { get; set; }
29 |
30 | ///
31 | /// Gets or sets the selected font size for the application.
32 | ///
33 | public int FontSize { get; set; }
34 |
35 | ///
36 | /// Gets or sets the fingerprint for usage stats.
37 | ///
38 | public Guid Fingerprint { get; set; } = Guid.NewGuid();
39 |
40 | ///
41 | /// Gets or sets the deck filter values set by the user.
42 | ///
43 | public DeckFilters Filters { get; set; } = new DeckFilters();
44 |
45 | ///
46 | /// Gets or sets the card text filter value.
47 | ///
48 | public string CardTextFilter { get; set; } = string.Empty;
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisorConsole/publishandsign.bat:
--------------------------------------------------------------------------------
1 | dotnet publish -f netcoreapp2.2 -r win-x86 -c Release --self-contained false
2 | dotnet publish -f netcoreapp2.2 -r win-x64 -c Release --self-contained false
3 | dotnet publish -f netcoreapp2.2 -r win-arm -c Release --self-contained false
4 | dotnet publish -f netcoreapp2.2 -r win-arm64 -c Release --self-contained false
5 | dotnet publish -f netcoreapp2.2 -r osx-x64 -c Release --self-contained false
6 | dotnet publish -f netcoreapp2.2 -r linux-x64 -c Release --self-contained false
7 | dotnet publish -f netcoreapp2.2 -r linux-musl-x64 -c Release --self-contained false
8 | dotnet publish -f netcoreapp2.2 -r linux-arm -c Release --self-contained false
9 | "C:\Program Files (x86)\Windows Kits\8.1\bin\x86\signtool.exe" sign /t http://timestamp.comodoca.com /sha1 9CFAD3D9DCDE70DC56909D3927A0DD5CB7DA1A83 ".\bin\Release\netcoreapp2.2\win-x86\DailyArena.DeckAdvisor.Console.exe"
10 | "C:\Program Files (x86)\Windows Kits\8.1\bin\x86\signtool.exe" sign /t http://timestamp.comodoca.com /sha1 9CFAD3D9DCDE70DC56909D3927A0DD5CB7DA1A83 ".\bin\Release\netcoreapp2.2\win-x86\publish\DailyArena.DeckAdvisor.Console.exe"
11 | "C:\Program Files (x86)\Windows Kits\8.1\bin\x64\signtool.exe" sign /t http://timestamp.comodoca.com /sha1 9CFAD3D9DCDE70DC56909D3927A0DD5CB7DA1A83 ".\bin\Release\netcoreapp2.2\win-x64\DailyArena.DeckAdvisor.Console.exe"
12 | "C:\Program Files (x86)\Windows Kits\8.1\bin\x64\signtool.exe" sign /t http://timestamp.comodoca.com /sha1 9CFAD3D9DCDE70DC56909D3927A0DD5CB7DA1A83 ".\bin\Release\netcoreapp2.2\win-x64\publish\DailyArena.DeckAdvisor.Console.exe"
13 |
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisorLauncher/App.xaml.cs:
--------------------------------------------------------------------------------
1 | using Serilog;
2 | using Serilog.Debugging;
3 | using Serilog.Formatting.Compact;
4 | using System;
5 | using System.Diagnostics;
6 | using System.IO;
7 | using System.Reflection;
8 | using System.Windows;
9 |
10 | namespace DailyArenaDeckAdvisorLauncher
11 | {
12 | ///
13 | /// Interaction logic for App.xaml
14 | ///
15 | public partial class App : Application
16 | {
17 | ///
18 | /// The logger for the launcher app.
19 | ///
20 | public ILogger Logger { get; private set; }
21 |
22 | ///
23 | /// Default constructer, sets up the data folder, current directory, and logging.
24 | ///
25 | public App()
26 | {
27 | var dataFolder = string.Format("{0}Low\\DailyArena\\DailyArenaDeckAdvisor", Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData));
28 | if (!Directory.Exists(dataFolder))
29 | {
30 | Directory.CreateDirectory(dataFolder);
31 | }
32 | if (!Directory.Exists($"{dataFolder}\\logs"))
33 | {
34 | Directory.CreateDirectory($"{dataFolder}\\logs");
35 | }
36 |
37 | SelfLog.Enable(msg => Debug.WriteLine(msg));
38 | SelfLog.Enable(Console.Error);
39 | Logger = new LoggerConfiguration().MinimumLevel.Debug().WriteTo.
40 | File(new CompactJsonFormatter(), $"{dataFolder}\\logs\\log.txt",
41 | rollingInterval: RollingInterval.Hour,
42 | retainedFileCountLimit: 5,
43 | fileSizeLimitBytes: 10485760,
44 | rollOnFileSizeLimit: true).
45 | CreateLogger();
46 |
47 | string codeBase = Assembly.GetExecutingAssembly().CodeBase;
48 | UriBuilder uri = new UriBuilder(codeBase);
49 | string path = Uri.UnescapeDataString(uri.Path);
50 | Directory.SetCurrentDirectory(Path.GetDirectoryName(path));
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisor/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.InteropServices;
3 | using System.Windows;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("DailyArenaDeckAdvisor")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("DailyArena")]
12 | [assembly: AssemblyProduct("DailyArenaDeckAdvisor")]
13 | [assembly: AssemblyTrademark("")]
14 | [assembly: AssemblyCulture("")]
15 |
16 | // Setting ComVisible to false makes the types in this assembly not visible
17 | // to COM components. If you need to access a type in this assembly from
18 | // COM, set the ComVisible attribute to true on that type.
19 | [assembly: ComVisible(false)]
20 |
21 | //In order to begin building localizable applications, set
22 | //CultureYouAreCodingWith in your .csproj file
23 | //inside a . For example, if you are using US english
24 | //in your source files, set the to en-US. Then uncomment
25 | //the NeutralResourceLanguage attribute below. Update the "en-US" in
26 | //the line below to match the UICulture setting in the project file.
27 |
28 | //[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
29 |
30 |
31 | [assembly: ThemeInfo(
32 | ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
33 | //(used if a resource is not found in the page,
34 | // or application resource dictionaries)
35 | ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
36 | //(used if a resource is not found in the page,
37 | // app, or any theme specific resource dictionaries)
38 | )]
39 |
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisorUpdater/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Resources;
3 | using System.Runtime.CompilerServices;
4 | using System.Runtime.InteropServices;
5 | using System.Windows;
6 |
7 | // General Information about an assembly is controlled through the following
8 | // set of attributes. Change these attribute values to modify the information
9 | // associated with an assembly.
10 | [assembly: AssemblyTitle("DailyArenaDeckAdvisorUpdater")]
11 | [assembly: AssemblyDescription("")]
12 | [assembly: AssemblyConfiguration("")]
13 | [assembly: AssemblyCompany("DailyArena")]
14 | [assembly: AssemblyProduct("DailyArenaDeckAdvisorUpdater")]
15 | [assembly: AssemblyTrademark("")]
16 | [assembly: AssemblyCulture("")]
17 |
18 | // Setting ComVisible to false makes the types in this assembly not visible
19 | // to COM components. If you need to access a type in this assembly from
20 | // COM, set the ComVisible attribute to true on that type.
21 | [assembly: ComVisible(false)]
22 |
23 | //In order to begin building localizable applications, set
24 | //CultureYouAreCodingWith in your .csproj file
25 | //inside a . For example, if you are using US english
26 | //in your source files, set the to en-US. Then uncomment
27 | //the NeutralResourceLanguage attribute below. Update the "en-US" in
28 | //the line below to match the UICulture setting in the project file.
29 |
30 | //[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
31 |
32 |
33 | [assembly: ThemeInfo(
34 | ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
35 | //(used if a resource is not found in the page,
36 | // or application resource dictionaries)
37 | ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
38 | //(used if a resource is not found in the page,
39 | // app, or any theme specific resource dictionaries)
40 | )]
41 |
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisorLauncher/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Resources;
3 | using System.Runtime.CompilerServices;
4 | using System.Runtime.InteropServices;
5 | using System.Windows;
6 |
7 | // General Information about an assembly is controlled through the following
8 | // set of attributes. Change these attribute values to modify the information
9 | // associated with an assembly.
10 | [assembly: AssemblyTitle("DailyArenaDeckAdvisorLauncher")]
11 | [assembly: AssemblyDescription("")]
12 | [assembly: AssemblyConfiguration("")]
13 | [assembly: AssemblyCompany("DailyArena")]
14 | [assembly: AssemblyProduct("DailyArenaDeckAdvisorLauncher")]
15 | [assembly: AssemblyTrademark("")]
16 | [assembly: AssemblyCulture("")]
17 |
18 | // Setting ComVisible to false makes the types in this assembly not visible
19 | // to COM components. If you need to access a type in this assembly from
20 | // COM, set the ComVisible attribute to true on that type.
21 | [assembly: ComVisible(false)]
22 |
23 | //In order to begin building localizable applications, set
24 | //CultureYouAreCodingWith in your .csproj file
25 | //inside a . For example, if you are using US english
26 | //in your source files, set the to en-US. Then uncomment
27 | //the NeutralResourceLanguage attribute below. Update the "en-US" in
28 | //the line below to match the UICulture setting in the project file.
29 |
30 | //[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
31 |
32 |
33 | [assembly: ThemeInfo(
34 | ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
35 | //(used if a resource is not found in the page,
36 | // or application resource dictionaries)
37 | ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
38 | //(used if a resource is not found in the page,
39 | // app, or any theme specific resource dictionaries)
40 | )]
41 |
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisorConsole/DailyArenaDeckAdvisorConsole.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | netcoreapp2.2
6 | win-x86;win-x64;osx-x64
7 | DailyArena.DeckAdvisor.Console
8 | DailyArena.DeckAdvisor.Console
9 | DailyArena.DeckAdvisor.Console.Program
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 | ..\libraries\DailyArena.Common.Core.dll
30 |
31 |
32 |
33 |
34 |
35 | True
36 | True
37 | Localization.resx
38 |
39 |
40 |
41 |
42 |
43 | ResXFileCodeGenerator
44 | Localization.Designer.cs
45 |
46 |
47 |
48 |
49 |
50 | PreserveNewest
51 |
52 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisorSetup/LicenseAgreementDlg_HK.wxs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisor/FiltersDialog.xaml.cs:
--------------------------------------------------------------------------------
1 | using DailyArena.DeckAdvisor.Common;
2 | using DailyArena.DeckAdvisor.Common.Extensions;
3 | using System.Windows;
4 |
5 | namespace DailyArena.DeckAdvisor
6 | {
7 | ///
8 | /// Interaction logic for SettingsDialog.xaml
9 | ///
10 | public partial class FiltersDialog : Window
11 | {
12 | ///
13 | /// Gets or sets the temporary filters object that belongs to this window.
14 | ///
15 | public DeckFilters Filters { get; private set; }
16 |
17 | ///
18 | /// Constructor. Initializes the component and sets the data context.
19 | ///
20 | public FiltersDialog()
21 | {
22 | App application = (App)Application.Current;
23 | Filters = application.State.Filters.Clone();
24 |
25 | InitializeComponent();
26 | DataContext = this;
27 | }
28 |
29 | ///
30 | /// Handle clicks of the Apply Button.
31 | ///
32 | /// The button that was clicked.
33 | /// The routed event arguments.
34 | private void Apply_Click(object sender, RoutedEventArgs e)
35 | {
36 | IDeckAdvisorApp application = (IDeckAdvisorApp)Application.Current;
37 | if (application.State.Filters != Filters)
38 | {
39 | application.State.Filters.SetAllFields(Filters);
40 | application.SaveState();
41 | ((MainWindow)Owner).ApplyFilters(Filters);
42 | }
43 | Close();
44 | }
45 |
46 | ///
47 | /// Handle clicks of the Close Button.
48 | ///
49 | /// The button that was clicked.
50 | /// The routed event arguments.
51 | private void Close_Click(object sender, RoutedEventArgs e)
52 | {
53 | bool close = true;
54 | App application = (App)Application.Current;
55 | if (application.State.Filters != Filters)
56 | {
57 | MessageBoxResult messageBoxResult = MessageBox.Show(Properties.Resources.Message_CloseConfirmation, Properties.Resources.Title_CloseConfirmation, MessageBoxButton.YesNo);
58 | if(messageBoxResult == MessageBoxResult.No)
59 | {
60 | close = false;
61 | }
62 | }
63 | if (close)
64 | {
65 | Close();
66 | }
67 | }
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/DailyArena.DeckAdvisor.Common/DailyArena.DeckAdvisor.Common.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netstandard2.0
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | ..\libraries\DailyArena.Common.Core.dll
19 |
20 |
21 | C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.2\System.Configuration.dll
22 |
23 |
24 | C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.2\System.Management.dll
25 |
26 |
27 |
28 |
29 | true
30 | x64\Debug\
31 | DEBUG;TRACE
32 | full
33 | x64
34 | prompt
35 | MinimumRecommendedRules.ruleset
36 | true
37 |
38 |
39 | x64\Release\
40 | TRACE
41 | true
42 | pdbonly
43 | x64
44 | prompt
45 | MinimumRecommendedRules.ruleset
46 | true
47 |
48 |
49 | x86
50 | x86\Debug\
51 |
52 |
53 | x86
54 | x86\Release\
55 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/DailyArena.DeckAdvisor.Common/IDeckAdvisorProgram.cs:
--------------------------------------------------------------------------------
1 | using DailyArena.Common.Core.Bindable;
2 | using Serilog;
3 | using System;
4 | using System.Collections.Generic;
5 |
6 | namespace DailyArena.DeckAdvisor.Common
7 | {
8 | ///
9 | /// Interface implemented by classes the run the core Deck Advisor program functionality.
10 | ///
11 | public interface IDeckAdvisorProgram
12 | {
13 | ///
14 | /// Gets or sets a reference to the application logger.
15 | ///
16 | ILogger Logger { get; set; }
17 |
18 | ///
19 | /// Gets the application name to use while logging.
20 | ///
21 | string ApplicationName { get; }
22 |
23 | ///
24 | /// Gets the application name to use while sending Usage Statistics.
25 | ///
26 | string ApplicationUsageName { get; }
27 |
28 | ///
29 | /// Implementation-specific method to query a configuration setting value.
30 | ///
31 | ///
32 | string GetConfigurationSetting(string key);
33 |
34 | ///
35 | /// A dictionary mapping the Format names shown on the GUI drop-down to the name to use when querying archetype data from the server.
36 | ///
37 | Dictionary> FormatMappings { get; set; }
38 |
39 | ///
40 | /// Method to get a localized string based on the resource name.
41 | ///
42 | /// The resource name to get a localized string for.
43 | /// The localized string for the requested resource name.
44 | string GetLocalizedString(string name);
45 |
46 | ///
47 | /// Gets the currently running app.
48 | ///
49 | IDeckAdvisorApp CurrentApp { get; }
50 |
51 | ///
52 | /// Gets or the selected format being viewed.
53 | ///
54 | Bindable Format { get; }
55 |
56 | ///
57 | /// Gets the selected deck sort field.
58 | ///
59 | Bindable Sort { get; }
60 |
61 | ///
62 | /// Gets the selected deck sort direction.
63 | ///
64 | Bindable SortDir { get; }
65 |
66 | ///
67 | /// Gets the state of the "Rotation" toggle button.
68 | ///
69 | BindableBool RotationProof { get; }
70 |
71 | ///
72 | /// Gets the card text filter value.
73 | ///
74 | Bindable CardText { get; }
75 |
76 | ///
77 | /// Gets the selected font size for the display.
78 | ///
79 | Bindable SelectedFontSize { get; }
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Set default behavior to automatically normalize line endings.
3 | ###############################################################################
4 | * text=auto
5 |
6 | ###############################################################################
7 | # Set default behavior for command prompt diff.
8 | #
9 | # This is need for earlier builds of msysgit that does not have it on by
10 | # default for csharp files.
11 | # Note: This is only used by command line
12 | ###############################################################################
13 | #*.cs diff=csharp
14 |
15 | ###############################################################################
16 | # Set the merge driver for project and solution files
17 | #
18 | # Merging from the command prompt will add diff markers to the files if there
19 | # are conflicts (Merging from VS is not affected by the settings below, in VS
20 | # the diff markers are never inserted). Diff markers may cause the following
21 | # file extensions to fail to load in VS. An alternative would be to treat
22 | # these files as binary and thus will always conflict and require user
23 | # intervention with every merge. To do so, just uncomment the entries below
24 | ###############################################################################
25 | #*.sln merge=binary
26 | #*.csproj merge=binary
27 | #*.vbproj merge=binary
28 | #*.vcxproj merge=binary
29 | #*.vcproj merge=binary
30 | #*.dbproj merge=binary
31 | #*.fsproj merge=binary
32 | #*.lsproj merge=binary
33 | #*.wixproj merge=binary
34 | #*.modelproj merge=binary
35 | #*.sqlproj merge=binary
36 | #*.wwaproj merge=binary
37 |
38 | ###############################################################################
39 | # behavior for image files
40 | #
41 | # image files are treated as binary by default.
42 | ###############################################################################
43 | #*.jpg binary
44 | #*.png binary
45 | #*.gif binary
46 |
47 | ###############################################################################
48 | # diff behavior for common document formats
49 | #
50 | # Convert binary document formats to text before diffing them. This feature
51 | # is only available from the command line. Turn it on by uncommenting the
52 | # entries below.
53 | ###############################################################################
54 | #*.doc diff=astextplain
55 | #*.DOC diff=astextplain
56 | #*.docx diff=astextplain
57 | #*.DOCX diff=astextplain
58 | #*.dot diff=astextplain
59 | #*.DOT diff=astextplain
60 | #*.pdf diff=astextplain
61 | #*.PDF diff=astextplain
62 | #*.rtf diff=astextplain
63 | #*.RTF diff=astextplain
64 |
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisor/SettingsDialog.xaml.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.ObjectModel;
2 | using System.Diagnostics;
3 | using System.Windows;
4 |
5 | namespace DailyArena.DeckAdvisor
6 | {
7 | ///
8 | /// Interaction logic for SettingsDialog.xaml
9 | ///
10 | public partial class SettingsDialog : Window
11 | {
12 | ///
13 | /// Xaml-bindable font sizes setting field.
14 | ///
15 | public ObservableCollection FontSizes { get; private set; } = new ObservableCollection() { 8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24 };
16 |
17 | ///
18 | /// Constructor. Initializes the component and sets the data context.
19 | ///
20 | public SettingsDialog()
21 | {
22 | InitializeComponent();
23 | DataContext = this;
24 | }
25 |
26 | ///
27 | /// Handle clicks of the Github Button.
28 | ///
29 | /// The button that was clicked.
30 | /// The routed event arguments.
31 | private void GithubButton_Click(object sender, RoutedEventArgs e)
32 | {
33 | Process.Start("https://github.com/jceddy/DailyArenaDeckAdvisor");
34 | }
35 |
36 | ///
37 | /// Handle clicks of the Issues Button.
38 | ///
39 | /// The button that was clicked.
40 | /// The routed event arguments.
41 | private void IssuesButton_Click(object sender, RoutedEventArgs e)
42 | {
43 | Process.Start("https://github.com/jceddy/DailyArenaDeckAdvisor/issues");
44 | }
45 |
46 | ///
47 | /// Handle clicks of the Wiki Button.
48 | ///
49 | /// The button that was clicked.
50 | /// The routed event arguments.
51 | private void WikiButton_Click(object sender, RoutedEventArgs e)
52 | {
53 | Process.Start("https://github.com/jceddy/DailyArenaDeckAdvisor/wiki");
54 | }
55 |
56 | ///
57 | /// Handle clicks of the Patreon Button.
58 | ///
59 | /// The button that was clicked.
60 | /// The routed event arguments.
61 | private void PatreonButton_Click(object sender, RoutedEventArgs e)
62 | {
63 | Process.Start("https://www.patreon.com/DailyArena");
64 | }
65 |
66 | ///
67 | /// Handle clicks of the MTGAZone Button.
68 | ///
69 | /// The button that was clicked.
70 | /// The routed event arguments.
71 | private void MTGAZoneButton_Click(object sender, RoutedEventArgs e)
72 | {
73 | Process.Start("https://mtgazone.com");
74 | }
75 |
76 | ///
77 | /// Handle clicks of the Close Button.
78 | ///
79 | /// The button that was clicked.
80 | /// The routed event arguments.
81 | private void Close_Click(object sender, RoutedEventArgs e)
82 | {
83 | Close();
84 | }
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisor/SettingsDialog.xaml:
--------------------------------------------------------------------------------
1 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/DailyArena.DeckAdvisor.Common/ClientVersion.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 |
6 | namespace DailyArena.DeckAdvisor.Common
7 | {
8 | ///
9 | /// Class that holds client version information for MTGA.
10 | ///
11 | public class ClientVersion
12 | {
13 | ///
14 | /// The parts of the client version (separated by dots in the version string).
15 | ///
16 | private int[] _versionParts;
17 |
18 | ///
19 | /// The underlying version string.
20 | ///
21 | public string VersionString { get; private set; }
22 |
23 | ///
24 | /// ClientVersion constructor that takes a string argument.
25 | ///
26 | /// The underlying version string.
27 | public ClientVersion(string versionString)
28 | {
29 | if(string.IsNullOrWhiteSpace(versionString))
30 | {
31 | versionString = "0";
32 | }
33 |
34 | _versionParts = versionString.Split('.').Select(x => Math.Abs(int.Parse(x))).ToArray();
35 | VersionString = string.Join(".", _versionParts);
36 | }
37 |
38 | ///
39 | /// ClientVersion constructor that takes an array argument.
40 | ///
41 | /// The parts of the client version (separated by dots in the version string).
42 | public ClientVersion(params int[] versionParts)
43 | {
44 | if(versionParts.Length == 0)
45 | {
46 | versionParts = new int[] { 0 };
47 | }
48 |
49 | _versionParts = versionParts.Select(x => Math.Abs(x)).ToArray();
50 | VersionString = string.Join(".", _versionParts);
51 | }
52 |
53 | ///
54 | /// ClientVersion default constructor.
55 | ///
56 | public ClientVersion()
57 | {
58 | VersionString = "0";
59 | _versionParts = new int[] { 0 };
60 | }
61 |
62 | ///
63 | /// ClientVersion greater than operator.
64 | ///
65 | /// The first ClientVersion to compare.
66 | /// The second ClientVersion to compare.
67 | /// True if a > b, false otherwise.
68 | public static bool operator >(ClientVersion a, ClientVersion b)
69 | {
70 | for(int i = 0; i < Math.Min(a._versionParts.Length, b._versionParts.Length); i++)
71 | {
72 | if (a._versionParts[i] > b._versionParts[i])
73 | return true;
74 | else if (b._versionParts[i] > a._versionParts[i])
75 | return false;
76 | }
77 |
78 | return a._versionParts.Length > b._versionParts.Length;
79 | }
80 |
81 | ///
82 | /// ClientVersion less than operator.
83 | ///
84 | /// The first ClientVersion to compare.
85 | /// The second ClientVersion to compare.
86 | /// True if a < b, false otherwise.
87 | public static bool operator <(ClientVersion a, ClientVersion b)
88 | {
89 | for (int i = 0; i < Math.Min(a._versionParts.Length, b._versionParts.Length); i++)
90 | {
91 | if (a._versionParts[i] < b._versionParts[i])
92 | return true;
93 | else if (b._versionParts[i] < a._versionParts[i])
94 | return false;
95 | }
96 |
97 | return a._versionParts.Length < b._versionParts.Length;
98 | }
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisorUpdater/Properties/Resources.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace DailyArenaDeckAdvisorUpdater.Properties {
12 | using System;
13 |
14 |
15 | ///
16 | /// A strongly-typed resource class, for looking up localized strings, etc.
17 | ///
18 | // This class was auto-generated by the StronglyTypedResourceBuilder
19 | // class via a tool like ResGen or Visual Studio.
20 | // To add or remove a member, edit your .ResX file then rerun ResGen
21 | // with the /str option, or rebuild your VS project.
22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")]
23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
25 | public class Resources {
26 |
27 | private static global::System.Resources.ResourceManager resourceMan;
28 |
29 | private static global::System.Globalization.CultureInfo resourceCulture;
30 |
31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
32 | internal Resources() {
33 | }
34 |
35 | ///
36 | /// Returns the cached ResourceManager instance used by this class.
37 | ///
38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
39 | public static global::System.Resources.ResourceManager ResourceManager {
40 | get {
41 | if (object.ReferenceEquals(resourceMan, null)) {
42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("DailyArenaDeckAdvisorUpdater.Properties.Resources", typeof(Resources).Assembly);
43 | resourceMan = temp;
44 | }
45 | return resourceMan;
46 | }
47 | }
48 |
49 | ///
50 | /// Overrides the current thread's CurrentUICulture property for all
51 | /// resource lookups using this strongly typed resource class.
52 | ///
53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
54 | public static global::System.Globalization.CultureInfo Culture {
55 | get {
56 | return resourceCulture;
57 | }
58 | set {
59 | resourceCulture = value;
60 | }
61 | }
62 |
63 | ///
64 | /// Looks up a localized string similar to Installing updates....
65 | ///
66 | public static string TextBlock_InstallingUpdates {
67 | get {
68 | return ResourceManager.GetString("TextBlock_InstallingUpdates", resourceCulture);
69 | }
70 | }
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisorLauncher/Properties/Resources.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace DailyArenaDeckAdvisorLauncher.Properties {
12 | using System;
13 |
14 |
15 | ///
16 | /// A strongly-typed resource class, for looking up localized strings, etc.
17 | ///
18 | // This class was auto-generated by the StronglyTypedResourceBuilder
19 | // class via a tool like ResGen or Visual Studio.
20 | // To add or remove a member, edit your .ResX file then rerun ResGen
21 | // with the /str option, or rebuild your VS project.
22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")]
23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
25 | public class Resources {
26 |
27 | private static global::System.Resources.ResourceManager resourceMan;
28 |
29 | private static global::System.Globalization.CultureInfo resourceCulture;
30 |
31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
32 | internal Resources() {
33 | }
34 |
35 | ///
36 | /// Returns the cached ResourceManager instance used by this class.
37 | ///
38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
39 | public static global::System.Resources.ResourceManager ResourceManager {
40 | get {
41 | if (object.ReferenceEquals(resourceMan, null)) {
42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("DailyArenaDeckAdvisorLauncher.Properties.Resources", typeof(Resources).Assembly);
43 | resourceMan = temp;
44 | }
45 | return resourceMan;
46 | }
47 | }
48 |
49 | ///
50 | /// Overrides the current thread's CurrentUICulture property for all
51 | /// resource lookups using this strongly typed resource class.
52 | ///
53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
54 | public static global::System.Globalization.CultureInfo Culture {
55 | get {
56 | return resourceCulture;
57 | }
58 | set {
59 | resourceCulture = value;
60 | }
61 | }
62 |
63 | ///
64 | /// Looks up a localized string similar to Checking for updates....
65 | ///
66 | public static string TextBlock_CheckingForUpdates {
67 | get {
68 | return ResourceManager.GetString("TextBlock_CheckingForUpdates", resourceCulture);
69 | }
70 | }
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisorSetup/WixUI_HK.wxs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
25 |
26 |
27 | 1
28 | "1"]]>
29 |
30 | 1
31 |
32 | NOT Installed
33 | Installed AND PATCH
34 |
35 | 1
36 | LicenseAccepted = "1"
37 |
38 | 1
39 | 1
40 | NOT WIXUI_DONTVALIDATEPATH
41 | "1"]]>
42 | 1
43 | 1
44 | 1
45 |
46 | Installed
47 |
48 | 1
49 |
50 | 1
51 | 1
52 | 1
53 |
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # DailyArenaDeckAdvisor
2 | A Deck Advisor companion App for Magic Arena.
3 |
4 | Visit our Patreon: https://www.patreon.com/DailyArena
5 | Visit MTG Arena Zone: https://mtgazone.com
6 | Visit Daily Arena: https://www.dailyarena.net
7 |
8 | # Installer Links and User Guide
9 | https://mtgazone.com/deck-advisor
10 |
11 | # Developer Guide
12 | https://github.com/jceddy/DailyArenaDeckAdvisor/wiki/Getting-Started:-Developing-DADA
13 |
14 | # Dependent Libraries
15 | Libraries used by this project:
16 | https://github.com/jceddy/DailyArenaCommon
17 |
18 | # Release 1.0.6.4 Changes
19 | - Mac/Linux Support Continued (Command Line Only)
20 | - Player Decks for Multiple Accounts
21 | - Deck Scoring for Win Rate
22 | - Historic Anthology
23 |
24 | # Release 1.0.6.2 Changes
25 | - Mac/Linux Support Started (Command Line Only)
26 | - Spanish Support
27 | - Windows Defender Nag Screen
28 | - Minor and Under-the-Hood Changes
29 | - Blank Standard Deck Names
30 | - Historic Anthology
31 | - Code Reorganization
32 | - Error Handling
33 | - Banned Cards
34 |
35 | # Release 1.0.5.9 Changes
36 | - Card Name Filter
37 | - Minor and Under-the-Hood Changes
38 | - Arena Log
39 | - Bug Fixes
40 |
41 | # Release 1.0.5.6 Changes
42 | - Tab List Headings
43 | - Localization Support/Russian
44 | - Minor and Under-the-Hood Changes
45 | - Command Zone
46 | - No Player Inventory Info Screen
47 | - Bitmap Scaling
48 | - Brawl Player Decks
49 | - Seven Dwarves
50 | - Card Meta-Stats
51 | - Fixed typose in comments
52 |
53 | # Release 1.0.5.2 Changes
54 | - Deck Sorting
55 | - Brawl Commander Replacement Suggestions
56 | - More Localization Support
57 | - Minor and Under-the-Hood Changes
58 | - Fixed some small bugs with the Updater relating to language resource files.
59 | - Additional error handling and automatic Github issue creation.
60 | - Bug fix for application crash when "Rotation Proof" toggle is on.
61 |
62 | # Release 1.0.4.4 Changes
63 | - Deck Filters
64 | - More Localization Support
65 | - Fixed bug due to trailing spaces on the card name for Mefolk Secretkeeper.
66 |
67 | # Release 1.0.4.0 Changes
68 | - More Support for Localization
69 | - Minor and Under-the-Hood Changes
70 | - Fixed a bug that can cause a crash when generating replacement suggestions for decks missing a lot of colorless lands.
71 | - Increased timeouts for various web operations, and added retries (some users are having issues due to network problems).
72 |
73 | # Release 1.0.3.8/1.0.3.9 Changes
74 | - Historic Format
75 | - Support for Localization
76 | - Minor and Under-the-Hood Changes
77 | - Added code to keep Historic decks in the player’s inventory from showing up in the “unfinished decks” list in Standard formats.
78 | - Added code to ignore non-Standard Legal cards in the player’s collection unless a Historic format is selected.
79 | - Fixed a bug with Adventure cards.
80 |
81 | # Release 1.0.3.5 Changes
82 | - Suggestions for Imported Decks
83 | - Additional Default Deck Ordering Tweak for Arena Standard
84 | - Minor and Under-the-Hood Changes
85 | - Fixed a server-side issue that broke the application after rotation.
86 | - Fixed an issue that was casing basic land replacement suggestions for nonbasic lands not to work correctly.
87 | - Improved the “loading” screens, added progress bars.
88 |
89 | # Release 1.0.3.3 Changes
90 | - Alternate Deck Configurations (for Standard)
91 | - Default Deck Ordering Tweak for Arena Standard
92 | - Minor and Under-the-Hood Changes
93 | - Default window size increased
94 | - Max number of cards shown on Meta Report increased to 98 (from 70)
95 | - Additional logging added in the code that loads the deck library, to help with debuggind issues related to that code in the future
96 | - Some basic functionality has been broken out into a separate "Common" library that can be used in other applications
97 | - .NET Framework version increased from 4.6.1 to 4.6.2
98 |
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisorSetup/Eula-en.rtf:
--------------------------------------------------------------------------------
1 | {\rtf1\ansi\ansicpg1252\deff0\nouicompat\deflang1033{\fonttbl{\f0\fswiss\fprq2\fcharset0 Arial;}{\f1\fnil\fcharset0 Calibri;}}
2 | {\colortbl ;\red0\green0\blue0;\red255\green242\blue204;}
3 | {\stylesheet{ Normal;}{\s1 heading 1;}}
4 | {\*\generator Riched20 10.0.14393}\viewkind4\uc1
5 | \pard\keep\keepn\widctlpar\sa60\sl276\slmult1\qc\cf1\f0\fs52 Daily Arena Deck Advisor\par
6 |
7 | \pard\widctlpar\sl276\slmult1\f1\fs22{\pict{\*\picprop}\wmetafile8\picw7620\pich7620\picwgoal43\pichgoal43
8 | 010009000003c800000006001c00000000000400000003010800050000000b0200000000050000
9 | 000c020f00c902040000002e0118001c000000fb02f1ff00000000000090010000000004400022
10 | 43616c6962726900000000000000000000000000000000000000000000000000040000002d0100
11 | 00040000002d010000040000002d0100000400000002010100050000000902000000020d000000
12 | 320a0d0000000100040000000000c8020e002000090005000000090200000002030000001e0007
13 | 000000fc020000a0a0a0000000040000002d01010008000000fa02050000000000ffffff000400
14 | 00002d0102000e00000024030500ffffffffffff0e00c8020e00c802ffffffffffff08000000fa
15 | 0200000000000000000000040000002d01030007000000fc020000ffffff000000040000002d01
16 | 0400040000002701ffff1c000000fb021000070000000000bc0200000000010202225379737465
17 | 6d000040cb971401000000a43b0f010f3875735acd9114b43b0f01040000002d01050004000000
18 | 2d010500030000000000
19 | }\f0\par
20 |
21 | \pard\keep\keepn\widctlpar\s1\sb400\sa120\sl276\slmult1\fs40 End-User License Agreement ("Agreement")\par
22 |
23 | \pard\widctlpar\sl276\slmult1\fs22\par
24 | Last updated: \highlight2 2019-08-08\par
25 | \highlight0\par
26 | Please read this End-User License Agreement ("Agreement") carefully before clicking the "I Agree" button, downloading or using \highlight2 Daily Arena Deck Advisor \highlight0 ("Application").\par
27 | \par
28 | By clicking the "I Agree" button, downloading or using the Application, you are agreeing to be bound by the terms and conditions of this Agreement.\par
29 | \par
30 | If you do not agree to the terms of this Agreement, do not click on the "I Agree" button and do not download or use the Application.\par
31 | \par
32 | \b License\par
33 | \b0\par
34 | \highlight2 DailyArena \highlight0 grants you a revocable, non-exclusive, non-transferable, limited license to download, install and use the Application solely for your personal, non-commercial purposes strictly in accordance with the terms of this Agreement.\par
35 | \par
36 | \b Restrictions\par
37 | \b0\par
38 | You agree not to, and you will not permit others to:\par
39 | \par
40 | a) license, sell, rent, lease, assign, distribute, transmit, host, outsource, disclose or otherwise commercially exploit the Application or make the Application available to any third party.\par
41 | \par
42 | \b Modifications to Application\par
43 | \b0\par
44 | \highlight2 DailyArena \highlight0 reserves the right to modify, suspend or discontinue, temporarily or permanently, the Application or any service to which it connects, with or without notice and without liability to you.\par
45 | \par
46 | \b Term and Termination\par
47 | \b0\par
48 | This Agreement shall remain in effect until terminated by you or \highlight2 DailyArena\highlight0 . \par
49 | \par
50 | \highlight2 DailyArena\highlight0 may, in its sole discretion, at any time and for any or no reason, suspend or terminate this Agreement with or without prior notice.\par
51 | \par
52 | This Agreement will terminate immediately, without prior notice from \highlight2 DailyArena\highlight0 , in the event that you fail to comply with any provision of this Agreement. You may also terminate this Agreement by deleting the Application and all copies thereof from your mobile device or from your desktop.\par
53 | \par
54 | Upon termination of this Agreement, you shall cease all use of the Application and delete all copies of the Application from your mobile device or from your desktop.\par
55 | \par
56 | \b Severability\par
57 | \b0\par
58 | If any provision of this Agreement is held to be unenforceable or invalid, such provision will be changed and interpreted to accomplish the objectives of such provision to the greatest extent possible under applicable law and the remaining provisions will continue in full force and effect.\par
59 | \par
60 | \b Amendments to this Agreement\par
61 | \b0\par
62 | \highlight2 DailyArena\highlight0 reserves the right, at its sole discretion, to modify or replace this Agreement at any time. If a revision is material we will provide at least \highlight2 30\highlight0 days' notice prior to any new terms taking effect. What constitutes a material change will be determined at our sole discretion.\par
63 | \par
64 | \b Contact Information\par
65 | \b0\par
66 | If you have any questions about this Agreement, please contact us.\par
67 |
68 | \pard\nowidctlpar\par
69 |
70 | \pard\sa200\sl276\slmult1\cf0\f1\lang9\par
71 | }
72 |
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisorSetup/Eula-es.rtf:
--------------------------------------------------------------------------------
1 | {\rtf1\ansi\ansicpg1252\deff0\nouicompat\deflang1033{\fonttbl{\f0\fswiss\fprq2\fcharset0 Arial;}{\f1\fnil\fcharset0 Calibri;}}
2 | {\colortbl ;\red0\green0\blue0;\red255\green242\blue204;}
3 | {\stylesheet{ Normal;}{\s1 heading 1;}}
4 | {\*\generator Riched20 10.0.14393}\viewkind4\uc1
5 | \pard\keep\keepn\widctlpar\sa60\sl276\slmult1\qc\cf1\f0\fs52 Daily Arena Deck Advisor\par
6 |
7 | \pard\widctlpar\sl276\slmult1\f1\fs22{\pict{\*\picprop}\wmetafile8\picw7620\pich7620\picwgoal43\pichgoal43
8 | 010009000003c800000006001c00000000000400000003010800050000000b0200000000050000
9 | 000c020f00c902040000002e0118001c000000fb02f1ff00000000000090010000000004400022
10 | 43616c6962726900000000000000000000000000000000000000000000000000040000002d0100
11 | 00040000002d010000040000002d0100000400000002010100050000000902000000020d000000
12 | 320a0d0000000100040000000000c8020e002000090005000000090200000002030000001e0007
13 | 000000fc020000a0a0a0000000040000002d01010008000000fa02050000000000ffffff000400
14 | 00002d0102000e00000024030500ffffffffffff0e00c8020e00c802ffffffffffff08000000fa
15 | 0200000000000000000000040000002d01030007000000fc020000ffffff000000040000002d01
16 | 0400040000002701ffff1c000000fb021000070000000000bc0200000000010202225379737465
17 | 6d000040cb971401000000a43b0f010f3875735acd9114b43b0f01040000002d01050004000000
18 | 2d010500030000000000
19 | }\f0\par
20 |
21 | \pard\keep\keepn\widctlpar\s1\sb400\sa120\sl276\slmult1\fs40 Acuerdo de Licencia de Usuario Final ("Acuerdo")\par
22 |
23 | \pard\widctlpar\sl276\slmult1\fs22\par
24 | \'daltima actualizaci\'f3n: \highlight2 2019-11-08\par
25 | \highlight0\par
26 | Lea este Acuerdo de Licencia de Usuario Final ("Acuerdo") cuidadosamente antes de hacer clic en el bot\'f3n "Acepto", descargar o usar \highlight2 Daily Arena Deck Advisor \highlight0 ("Aplicaci\'f3n").\par
27 | \par
28 | Al hacer clic en el bot\'f3n "Acepto", descargar o usar la Aplicaci\'f3n, usted acepta estar sujeto a los t\'e9rminos y condiciones de este Acuerdo.\par
29 | \par
30 | Si no est\'e1 de acuerdo con los t\'e9rminos de este Acuerdo, no haga clic en el bot\'f3n "Acepto" y no descargue ni use la Aplicaci\'f3n.\par
31 | \par
32 | \b Licencia\par
33 | \b0\par
34 | \highlight2 DailyArena \highlight0 le otorga una licencia limitada, revocable, no exclusiva e intransferible para descargar, instalar y usar la Aplicaci\'f3n \'fanicamente para sus fines personales y no comerciales, estrictamente de acuerdo con los t\'e9rminos de este Acuerdo.\par
35 | \par
36 | \b Restricciones\par
37 | \b0\par
38 | Usted acepta no hacerlo y no permitir\'e1 que otros:\par
39 | \par
40 | a) licenciar, vender, alquilar, arrendar, asignar, distribuir, transmitir, alojar, externalizar, divulgar o explotar comercialmente la Aplicaci\'f3n o poner la Aplicaci\'f3n a disposici\'f3n de terceros.\par
41 | \par
42 | \b Modificaciones a la Aplicaci\'f3n\par
43 | \b0\par
44 | \highlight2 DailyArena \highlight0 se reserva el derecho de modificar, suspender o descontinuar, temporal o permanentemente, la Aplicaci\'f3n o cualquier servicio al que se conecte, con o sin aviso y sin responsabilidad para con usted.\par
45 | \par
46 | \b Duraci\'f3n y Terminaci\'f3n\par
47 | \b0\par
48 | Este Acuerdo permanecer\'e1 en vigencia hasta que sea rescindido por usted o \highlight2 DailyArena\highlight0 . \par
49 | \par
50 | \highlight2 DailyArena\highlight0 puede, a su exclusivo criterio, en cualquier momento y por cualquier motivo, suspender o rescindir este Acuerdo con o sin previo aviso.\par
51 | \par
52 | Este Acuerdo terminar\'e1 de inmediato, sin previo aviso de \highlight2 DailyArena\highlight0 , en caso de que no cumpla con alguna disposici\'f3n de este Acuerdo. Tambi\'e9n puede rescindir este Acuerdo eliminando la Aplicaci\'f3n y todas sus copias de su dispositivo m\'f3vil o de su escritorio.\par
53 | \par
54 | Al finalizar este Acuerdo, deber\'e1 dejar de usar la Aplicaci\'f3n y eliminar todas las copias de la Aplicaci\'f3n de su dispositivo m\'f3vil o de su escritorio.\par
55 | \par
56 | \b Divisibilidad\par
57 | \b0\par
58 | Si alguna disposici\'f3n de este Acuerdo se considera inaplicable o inv\'e1lida, dicha disposici\'f3n se cambiar\'e1 e interpretar\'e1 para cumplir los objetivos de dicha disposici\'f3n en la mayor medida posible seg\'fan la ley aplicable y las disposiciones restantes continuar\'e1n en pleno vigor y efecto.\par
59 | \par
60 | \b Enmiendas a este Acuerdo\par
61 | \b0\par
62 | \highlight2 DailyArena\highlight0 se reserva el derecho, a su exclusivo criterio, de modificar o reemplazar este Acuerdo en cualquier momento. Si una revisi\'f3n es material, proporcionaremos al menos \highlight2 30\highlight0 aviso de d\'edas antes de que entren en vigencia nuevos t\'e9rminos. Lo que constituye un cambio material se determinar\'e1 a nuestro exclusivo criterio.\par
63 | \par
64 | \b Informaci\'f3n del Contacto\par
65 | \b0\par
66 | Si tiene alguna pregunta sobre este Acuerdo, cont\'e1ctenos.\par
67 |
68 | \pard\nowidctlpar\par
69 |
70 | \pard\sa200\sl276\slmult1\cf0\f1\lang9\par
71 | }
72 |
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisor.GetData/DADAGetData.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading;
6 | using System.Threading.Tasks;
7 | using Newtonsoft.Json;
8 | using UnityEngine;
9 | using Wizards.Mtga.Decks;
10 | using Wizards.Mtga.FrontDoorModels;
11 |
12 | namespace DailyArena.DeckAdvisor.GetData
13 | {
14 | public class LogElement
15 | {
16 | public string timestamp;
17 | public object Payload;
18 | }
19 |
20 | public class DeckForLog
21 | {
22 | public string Name;
23 | public List Cards;
24 | }
25 |
26 | public class DADAGetData : MonoBehaviour
27 | {
28 | private static bool gotInventoryData = false;
29 | private static List dataWrittenHashes = new List();
30 | private static readonly UnityCrossThreadLogger DADALogger = new UnityCrossThreadLogger("Daily Arena Deck Advisor Logger");
31 |
32 | public void Start()
33 | {
34 | try
35 | {
36 | System.Random RNG = new System.Random();
37 | int length = 32;
38 | StringBuilder randomString = new StringBuilder(length);
39 | for (var i = 0; i < length; i++)
40 | {
41 | randomString.Append(((char)(RNG.Next(1, 26) + 64)).ToString().ToLower());
42 | }
43 | DADALogger.Debug($"Unique Log Identifier: {randomString}");
44 | Task task = new Task(() => Get());
45 | task.Start();
46 | }
47 | catch(Exception e)
48 | {
49 | WriteToLog("Error", e);
50 | }
51 | }
52 |
53 | public static string CreateMD5(string input)
54 | {
55 | // Use input string to calculate MD5 hash
56 | using (System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create())
57 | {
58 | byte[] inputBytes = Encoding.ASCII.GetBytes(input);
59 | byte[] hashBytes = md5.ComputeHash(inputBytes);
60 |
61 | // Convert the byte array to hexadecimal string
62 | StringBuilder sb = new StringBuilder();
63 | for(int i = 0; i < hashBytes.Length; i++)
64 | {
65 | sb.Append(hashBytes[i].ToString("X2"));
66 | }
67 | return sb.ToString();
68 | }
69 | }
70 |
71 | public void Get()
72 | {
73 | try
74 | {
75 | while (!gotInventoryData)
76 | {
77 | Thread.Sleep(10000);
78 |
79 | WriteToLog("DADA Debug", "Checking for Inventory Data");
80 | if (!gotInventoryData && WrapperController.Instance != null && WrapperController.Instance.InventoryManager != null && WrapperController.Instance.InventoryManager.Cards != null && WrapperController.Instance.InventoryManager.Cards.Count > 0)
81 | {
82 | GetInventoryData();
83 | }
84 | }
85 | }
86 | catch (Exception e)
87 | {
88 | WriteToLog("Error - Get()", e);
89 | }
90 | }
91 |
92 | private void WriteToLog(string indicator, object report)
93 | {
94 | try
95 | {
96 | LogElement logElem = new LogElement
97 | {
98 | Payload = report,
99 | timestamp = new DateTimeOffset(DateTime.UtcNow).ToUnixTimeSeconds().ToString()
100 | };
101 | string hashMD5 = CreateMD5(JsonConvert.SerializeObject(report));
102 | if(!dataWrittenHashes.Contains(hashMD5))
103 | {
104 | DADALogger.Debug($" **{indicator}** {JsonConvert.SerializeObject(logElem)}");
105 | dataWrittenHashes.Add(hashMD5);
106 | }
107 | }
108 | catch(Exception e)
109 | {
110 | DADALogger.Debug($" **WriteToLogError** {e}");
111 | }
112 | }
113 |
114 | private void GetInventoryData()
115 | {
116 | try
117 | {
118 | gotInventoryData = true;
119 | WriteToLog("DADA Debug", "Resubscribing Inventory Change Handler...");
120 | WrapperController.Instance.InventoryManager.UnsubscribeFromAll(InventoryChangeHandler);
121 | WrapperController.Instance.InventoryManager.SubscribeToAll(InventoryChangeHandler);
122 | WriteToLog("DADA Debug", "Finished Resubscribing Inventory Change Handler");
123 |
124 | Task task = new Task(() => PeriodicCollectionPrinter());
125 | task.Start();
126 | }
127 | catch(Exception e)
128 | {
129 | WriteToLog("Error - GetInventoryData()", e);
130 | }
131 | }
132 |
133 | private Client_Deck GetFullDeck(Guid id)
134 | {
135 | var deckPromise = WrapperController.Instance.DecksManager.GetFullDeck(id);
136 | deckPromise.AsTask.Wait();
137 | return deckPromise.Result;
138 | }
139 |
140 | private void PeriodicCollectionPrinter()
141 | {
142 | try
143 | {
144 | while (true)
145 | {
146 | WriteToLog("Collection", WrapperController.Instance.InventoryManager.Cards);
147 | WriteToLog("InventoryContent", WrapperController.Instance.InventoryManager.Inventory);
148 | var deckPromise = WrapperController.Instance.DecksManager.GetAllDecks();
149 | deckPromise.AsTask.Wait();
150 | WriteToLog("Decks", deckPromise.Result.Select((x) => GetFullDeck(x.Id)));
151 | Thread.Sleep(600000);
152 | }
153 | }
154 | catch(Exception e)
155 | {
156 | WriteToLog("Error - PeriodicCollectionPrinter()", e);
157 | }
158 | }
159 |
160 | private void InventoryChangeHandler(ClientInventoryUpdateReportItem obj)
161 | {
162 | try
163 | {
164 | WriteToLog("InventoryUpdate", obj);
165 | }
166 | catch(Exception e)
167 | {
168 | WriteToLog("Error - InventoryChangeHandler()", e);
169 | }
170 | }
171 | }
172 | }
173 |
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisor/CardStats.cs:
--------------------------------------------------------------------------------
1 | using DailyArena.Common.Core.Database;
2 | using DailyArena.Common.Database;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 |
6 | namespace DailyArena.DeckAdvisor
7 | {
8 | ///
9 | /// Class that represent non-static meta statistics computed for a Card.
10 | ///
11 | public class CardStats
12 | {
13 | ///
14 | /// Gets or sets the Card these stats are linked to.
15 | ///
16 | public Card Card { get; set; }
17 |
18 | ///
19 | /// Gets or sets the number of decks the card is contained in.
20 | ///
21 | public int DeckCount { get; set; } = 0;
22 |
23 | ///
24 | /// Gets or sets the overall percentage of decks the card is contained in.
25 | ///
26 | public double DeckPercentage { get; set; }
27 |
28 | ///
29 | /// Gets or sets the total copies of the card played in all decks.
30 | ///
31 | public int TotalCopies { get; set; } = 0;
32 |
33 | ///
34 | /// Gets the average number of copies of the card played over all decks that play it.
35 | ///
36 | public double AverageCopies
37 | {
38 | get
39 | {
40 | if(DeckCount == 0)
41 | {
42 | return 0;
43 | }
44 | return (double)TotalCopies / DeckCount;
45 | }
46 | }
47 |
48 | ///
49 | /// Gets or sets the maximim number of copies of the card played in any given deck.
50 | ///
51 | public int MaxCopies { get; set; } = 0;
52 |
53 | ///
54 | /// Gets a formatted string view of the card's meta statistics, useful for Xaml binding.
55 | ///
56 | public string MetaStatsView
57 | {
58 | get
59 | {
60 | if (Card.Rarity == CardRarity.BasicLand)
61 | {
62 | return string.Empty;
63 | }
64 | return string.Format("({0:0%}, {1:0.0})", DeckPercentage, AverageCopies);
65 | }
66 | }
67 |
68 | ///
69 | /// Dictionary that keeps track of deck associations between cards.
70 | ///
71 | private static Dictionary> _associationStats = new Dictionary>();
72 |
73 | ///
74 | /// Cache of pre-computed association modfiers;
75 | ///
76 | private static Dictionary> _associationModifiers = new Dictionary>();
77 |
78 | ///
79 | /// Get an "association modifier" score from 0-1 that reflects the percentage of decks this card is in with the supplied card.
80 | ///
81 | /// The first card to get an association modifier for.
82 | /// The second card to get an association modifier for.
83 | /// Object containing deck statistics for all cards.
84 | /// The association modifier for the specified card.
85 | public static double GetAssociationModifier(string card1, string card2, Dictionary cardStats)
86 | {
87 | if (card1 == card2)
88 | {
89 | return 1.0;
90 | }
91 | else {
92 | if (_associationModifiers.ContainsKey(card1) && _associationModifiers[card1].ContainsKey(card2))
93 | {
94 | return _associationModifiers[card1][card2];
95 | }
96 | else
97 | {
98 | double modifier = 0.0;
99 |
100 | if (_associationStats.ContainsKey(card1) && _associationStats[card1].ContainsKey(card2))
101 | {
102 | modifier = (double)_associationStats[card1][card2] / cardStats.Where(x => x.Key.Name == card1).First().Value.DeckCount;
103 | }
104 |
105 | if(!_associationModifiers.ContainsKey(card1))
106 | {
107 | _associationModifiers[card1] = new Dictionary();
108 | }
109 | _associationModifiers[card1][card1] = modifier;
110 | return modifier;
111 | }
112 | }
113 | }
114 |
115 | ///
116 | /// Update all deck association data for cards in a given archetype.
117 | ///
118 | ///
119 | public static void UpdateDeckAssociations(Archetype archetype)
120 | {
121 | List allCardNames = archetype.MainDeck.Select(x => x.Key).Union(archetype.Sideboard.Select(x => x.Key)).ToList();
122 |
123 | for(int i = 0; i < allCardNames.Count; i++)
124 | {
125 | for(int j = i + 1; j < allCardNames.Count; j++)
126 | {
127 | string card1 = allCardNames[i];
128 | string card2 = allCardNames[j];
129 |
130 | if(!_associationStats.ContainsKey(card1))
131 | {
132 | _associationStats[card1] = new Dictionary();
133 | }
134 | if (!_associationStats.ContainsKey(card2))
135 | {
136 | _associationStats[card2] = new Dictionary();
137 | }
138 |
139 | if(_associationStats[card1].ContainsKey(card2))
140 | {
141 | _associationStats[card1][card2]++;
142 | }
143 | else
144 | {
145 | _associationStats[card1][card2] = 1;
146 | }
147 |
148 | if (_associationStats[card2].ContainsKey(card1))
149 | {
150 | _associationStats[card2][card1]++;
151 | }
152 | else
153 | {
154 | _associationStats[card2][card1] = 1;
155 | }
156 | }
157 | }
158 | }
159 | }
160 | }
161 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 |
4 | # User-specific files
5 | *.suo
6 | *.user
7 | *.userosscache
8 | *.sln.docstates
9 |
10 | # User-specific files (MonoDevelop/Xamarin Studio)
11 | *.userprefs
12 |
13 | # Build results
14 | [Dd]ebug/
15 | [Dd]ebugPublic/
16 | [Rr]elease/
17 | [Rr]eleases/
18 | x64/
19 | x86/
20 | bld/
21 | [Bb]in/
22 | [Oo]bj/
23 | [Ll]og/
24 |
25 | # Visual Studio 2015 cache/options directory
26 | .vs/
27 | # Uncomment if you have tasks that create the project's static files in wwwroot
28 | #wwwroot/
29 |
30 | # MSTest test Results
31 | [Tt]est[Rr]esult*/
32 | [Bb]uild[Ll]og.*
33 |
34 | # NUNIT
35 | *.VisualState.xml
36 | TestResult.xml
37 |
38 | # Build Results of an ATL Project
39 | [Dd]ebugPS/
40 | [Rr]eleasePS/
41 | dlldata.c
42 |
43 | # DNX
44 | project.lock.json
45 | project.fragment.lock.json
46 | artifacts/
47 |
48 | *_i.c
49 | *_p.c
50 | *_i.h
51 | *.ilk
52 | *.meta
53 | *.obj
54 | *.pch
55 | *.pdb
56 | *.pgc
57 | *.pgd
58 | *.rsp
59 | *.sbr
60 | *.tlb
61 | *.tli
62 | *.tlh
63 | *.tmp
64 | *.tmp_proj
65 | *.log
66 | *.vspscc
67 | *.vssscc
68 | .builds
69 | *.pidb
70 | *.svclog
71 | *.scc
72 |
73 | # Chutzpah Test files
74 | _Chutzpah*
75 |
76 | # Visual C++ cache files
77 | ipch/
78 | *.aps
79 | *.ncb
80 | *.opendb
81 | *.opensdf
82 | *.sdf
83 | *.cachefile
84 | *.VC.db
85 | *.VC.VC.opendb
86 |
87 | # Visual Studio profiler
88 | *.psess
89 | *.vsp
90 | *.vspx
91 | *.sap
92 |
93 | # TFS 2012 Local Workspace
94 | $tf/
95 |
96 | # Guidance Automation Toolkit
97 | *.gpState
98 |
99 | # ReSharper is a .NET coding add-in
100 | _ReSharper*/
101 | *.[Rr]e[Ss]harper
102 | *.DotSettings.user
103 |
104 | # JustCode is a .NET coding add-in
105 | .JustCode
106 |
107 | # TeamCity is a build add-in
108 | _TeamCity*
109 |
110 | # DotCover is a Code Coverage Tool
111 | *.dotCover
112 |
113 | # NCrunch
114 | _NCrunch_*
115 | .*crunch*.local.xml
116 | nCrunchTemp_*
117 |
118 | # MightyMoose
119 | *.mm.*
120 | AutoTest.Net/
121 |
122 | # Web workbench (sass)
123 | .sass-cache/
124 |
125 | # Installshield output folder
126 | [Ee]xpress/
127 |
128 | # DocProject is a documentation generator add-in
129 | DocProject/buildhelp/
130 | DocProject/Help/*.HxT
131 | DocProject/Help/*.HxC
132 | DocProject/Help/*.hhc
133 | DocProject/Help/*.hhk
134 | DocProject/Help/*.hhp
135 | DocProject/Help/Html2
136 | DocProject/Help/html
137 |
138 | # Click-Once directory
139 | publish/
140 |
141 | # Publish Web Output
142 | *.[Pp]ublish.xml
143 | *.azurePubxml
144 | # TODO: Comment the next line if you want to checkin your web deploy settings
145 | # but database connection strings (with potential passwords) will be unencrypted
146 | #*.pubxml
147 | *.publishproj
148 |
149 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
150 | # checkin your Azure Web App publish settings, but sensitive information contained
151 | # in these scripts will be unencrypted
152 | PublishScripts/
153 |
154 | # NuGet Packages
155 | *.nupkg
156 | # The packages folder can be ignored because of Package Restore
157 | **/packages/*
158 | # except build/, which is used as an MSBuild target.
159 | !**/packages/build/
160 | # Uncomment if necessary however generally it will be regenerated when needed
161 | #!**/packages/repositories.config
162 | # NuGet v3's project.json files produces more ignoreable files
163 | *.nuget.props
164 | *.nuget.targets
165 |
166 | # Microsoft Azure Build Output
167 | csx/
168 | *.build.csdef
169 |
170 | # Microsoft Azure Emulator
171 | ecf/
172 | rcf/
173 |
174 | # Windows Store app package directories and files
175 | AppPackages/
176 | BundleArtifacts/
177 | Package.StoreAssociation.xml
178 | _pkginfo.txt
179 |
180 | # Visual Studio cache files
181 | # files ending in .cache can be ignored
182 | *.[Cc]ache
183 | # but keep track of directories ending in .cache
184 | !*.[Cc]ache/
185 |
186 | # Others
187 | ClientBin/
188 | ~$*
189 | *~
190 | *.dbmdl
191 | *.dbproj.schemaview
192 | *.jfm
193 | *.pfx
194 | *.publishsettings
195 | node_modules/
196 | orleans.codegen.cs
197 |
198 | # Since there are multiple workflows, uncomment next line to ignore bower_components
199 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
200 | #bower_components/
201 |
202 | # RIA/Silverlight projects
203 | Generated_Code/
204 |
205 | # Backup & report files from converting an old project file
206 | # to a newer Visual Studio version. Backup files are not needed,
207 | # because we have git ;-)
208 | _UpgradeReport_Files/
209 | Backup*/
210 | UpgradeLog*.XML
211 | UpgradeLog*.htm
212 |
213 | # SQL Server files
214 | *.mdf
215 | *.ldf
216 |
217 | # Business Intelligence projects
218 | *.rdl.data
219 | *.bim.layout
220 | *.bim_*.settings
221 |
222 | # Microsoft Fakes
223 | FakesAssemblies/
224 |
225 | # GhostDoc plugin setting file
226 | *.GhostDoc.xml
227 |
228 | # Node.js Tools for Visual Studio
229 | .ntvs_analysis.dat
230 |
231 | # Visual Studio 6 build log
232 | *.plg
233 |
234 | # Visual Studio 6 workspace options file
235 | *.opt
236 |
237 | # Visual Studio LightSwitch build output
238 | **/*.HTMLClient/GeneratedArtifacts
239 | **/*.DesktopClient/GeneratedArtifacts
240 | **/*.DesktopClient/ModelManifest.xml
241 | **/*.Server/GeneratedArtifacts
242 | **/*.Server/ModelManifest.xml
243 | _Pvt_Extensions
244 |
245 | # Paket dependency manager
246 | .paket/paket.exe
247 | paket-files/
248 |
249 | # FAKE - F# Make
250 | .fake/
251 |
252 | # JetBrains Rider
253 | .idea/
254 | *.sln.iml
255 |
256 | # CodeRush
257 | .cr/
258 |
259 | # Python Tools for Visual Studio (PTVS)
260 | __pycache__/
261 | *.pyc
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisorSetup/DailyArenaDeckAdvisorSetup.wixproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | x86
6 | 3.10
7 | 54173857-c11e-49c8-8cdc-46fd269e506a
8 | 2.0
9 | DailyArenaDeckAdvisorSetup
10 | Package
11 |
12 |
13 | x86\Debug\
14 | obj\$(Platform)\$(Configuration)\
15 | Debug
16 |
17 |
18 | x86\Release\
19 | obj\$(Platform)\$(Configuration)\
20 |
21 |
22 | Debug
23 | x64\Debug\
24 | obj\$(Platform)\$(Configuration)\
25 |
26 |
27 | x64\Release\
28 | obj\$(Platform)\$(Configuration)\
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 | DailyArenaDeckAdvisorLauncher
38 | {1aa67122-abbb-49de-b260-3c658728ad4e}
39 | True
40 | True
41 | Binaries;Content;Satellites
42 | INSTALLFOLDER
43 |
44 |
45 | DailyArenaDeckAdvisorUpdater
46 | {986235b3-f7d9-4607-8cf8-7d8649fa1f23}
47 | True
48 | True
49 | Binaries;Content;Satellites
50 | INSTALLFOLDER
51 |
52 |
53 | DailyArenaDeckAdvisor
54 | {7a3a0a04-3697-479e-8ec9-6d2b944fabd1}
55 | True
56 | True
57 | Binaries;Content;Satellites
58 | INSTALLFOLDER
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 | $(WixExtDir)\WixUIExtension.dll
69 | WixUIExtension
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 | "C:\Program Files (x86)\Windows Kits\8.1\bin\$(PlatformName)\signtool.exe" sign /t http://timestamp.comodoca.com /sha1 9CFAD3D9DCDE70DC56909D3927A0DD5CB7DA1A83 "$(ProjectDir)$(OutDir)en-us\DailyArenaDeckAdvisorSetup.msi"
90 | "C:\Program Files (x86)\Windows Kits\8.1\bin\$(PlatformName)\signtool.exe" sign /t http://timestamp.comodoca.com /sha1 9CFAD3D9DCDE70DC56909D3927A0DD5CB7DA1A83 "$(ProjectDir)$(OutDir)ru-RU\DailyArenaDeckAdvisorSetup.msi"
91 | "C:\Program Files (x86)\Windows Kits\8.1\bin\$(PlatformName)\signtool.exe" sign /t http://timestamp.comodoca.com /sha1 9CFAD3D9DCDE70DC56909D3927A0DD5CB7DA1A83 "$(ProjectDir)$(OutDir)es-ES\DailyArenaDeckAdvisorSetup.msi"
92 |
93 |
101 |
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisorUpdater/MainWindow.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Configuration;
3 | using System.Diagnostics;
4 | using System.Globalization;
5 | using System.IO;
6 | using System.IO.Compression;
7 | using System.Linq;
8 | using System.Net;
9 | using System.Reflection;
10 | using System.Threading;
11 | using System.Threading.Tasks;
12 | using System.Windows;
13 |
14 | namespace DailyArenaDeckAdvisorUpdater
15 | {
16 | ///
17 | /// Interaction logic for MainWindow.xaml
18 | ///
19 | public partial class MainWindow : Window
20 | {
21 | ///
22 | /// Default constructer, initializes the GUI components.
23 | ///
24 | public MainWindow()
25 | {
26 | App application = (App)Application.Current;
27 | FileLogger.Log("Main Window Constructor Called - {0}", "Updater");
28 |
29 | SetCulture();
30 | InitializeComponent();
31 | }
32 |
33 | ///
34 | /// Sets the current UI culture from DailyArenaDeckAdvisor.exe.config if it's set there.
35 | ///
36 | private void SetCulture()
37 | {
38 | FileLogger.Log("SetCulture() Called - {0}", "Launcher");
39 |
40 | try
41 | {
42 | var appSettings = ConfigurationManager.OpenExeConfiguration("DailyArenaDeckAdvisor.exe");
43 | if (appSettings == null)
44 | {
45 | FileLogger.Log("No AppSettings Found, Using Default UI Culture");
46 | }
47 | else
48 | {
49 | var cultureSetting = appSettings.AppSettings.Settings["UICulture"];
50 | if (cultureSetting != null)
51 | {
52 | var culture = cultureSetting.Value;
53 | FileLogger.Log("Setting UI Culture to {0}", culture);
54 | Thread.CurrentThread.CurrentUICulture = new CultureInfo(culture);
55 | }
56 | else
57 | {
58 | FileLogger.Log("UICulture not set in AppSettings, Using Default UI Culture");
59 | }
60 | }
61 | }
62 | catch (ConfigurationErrorsException e)
63 | {
64 | FileLogger.Log(e, "Exception in SetCulture(), Using Default UI Culture");
65 | }
66 | }
67 |
68 | ///
69 | /// Event handler that is called when the window closes. Shuts down the executable.
70 | ///
71 | /// The Window.
72 | /// The event arguments.
73 | private void Window_Closed(object sender, EventArgs e)
74 | {
75 | FileLogger.Log("Window Closed, Shutting Down - {0}", "Updater");
76 | Application.Current.Shutdown();
77 | }
78 |
79 | ///
80 | /// Event handler that is called when the window is loaded. Fires off updater activities.
81 | ///
82 | /// The Window.
83 | /// The routed event arguments.
84 | private void Window_Loaded(object sender, RoutedEventArgs e)
85 | {
86 | FileLogger.Log("Main Window Loaded - {0}", "Updater");
87 |
88 | Task updateTask = new Task(() =>
89 | {
90 | var updaterPath = string.Format("{0}Low\\DailyArena\\DailyArenaDeckAdvisor", Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData));
91 | var zipFile = $"{updaterPath}\\DailyArenaDeckAdvisor.zip";
92 | AssemblyName assemblyName = Assembly.GetExecutingAssembly().GetName();
93 | string assemblyVersion = assemblyName.Version.ToString();
94 | string assemblyArchitecture = assemblyName.ProcessorArchitecture.ToString();
95 | FileLogger.Log("Assembly Version: {0}, Assembly Architecture: {1}", assemblyVersion, assemblyArchitecture);
96 | using (WebClient client = new WebClient())
97 | {
98 | FileLogger.Log("Downloading Updater Zip File");
99 | string ver = Guid.NewGuid().ToString();
100 | try
101 | {
102 | if (assemblyArchitecture == "X86")
103 | {
104 | client.DownloadFile($"https://clans.dailyarena.net/download/advisor/x86/DailyArenaDeckAdvisor.zip?ver={ver}", zipFile);
105 | }
106 | else
107 | {
108 | client.DownloadFile($"https://clans.dailyarena.net/download/advisor/x64/DailyArenaDeckAdvisor.zip?ver={ver}", zipFile);
109 | }
110 |
111 | FileLogger.Log("Extracting Updater Zip Entries");
112 | using (ZipArchive archive = ZipFile.Open(zipFile, ZipArchiveMode.Read))
113 | {
114 | var entries = archive.Entries.Where(x => !x.Name.StartsWith("DailyArenaDeckAdvisorUpdater"));
115 | foreach (var entry in entries)
116 | {
117 | if (entry.FullName.EndsWith("/"))
118 | {
119 | Directory.CreateDirectory(entry.FullName);
120 | }
121 | else
122 | {
123 | entry.ExtractToFile(entry.FullName, true);
124 | }
125 | }
126 | }
127 | }
128 | catch (WebException we)
129 | {
130 | FileLogger.Log(we, "WebException in {0}, {1} - {2}", "updateTask", "Re-Running Launcher", "Updater");
131 | }
132 |
133 | FileLogger.Log("Starting Launcher");
134 | using (Process advisorApp = new Process())
135 | {
136 | advisorApp.StartInfo.FileName = "DailyArenaDeckAdvisorLauncher.exe";
137 | advisorApp.StartInfo.WorkingDirectory = Directory.GetCurrentDirectory();
138 | advisorApp.Start();
139 | }
140 |
141 | FileLogger.Log("Closing Updater Window");
142 | Dispatcher.Invoke(() => { Close(); });
143 | }
144 | });
145 | updateTask.ContinueWith(t =>
146 | {
147 | if (t.Exception != null)
148 | {
149 | FileLogger.Log(t.Exception, "Exception in {0} ({1} - {2})", "updateTask", "Window_Loaded", "Updater");
150 | Dispatcher.Invoke(() => {
151 | var result = MessageBox.Show(t.Exception.InnerException.ToString(), "Updater Exception", MessageBoxButton.OK, MessageBoxImage.Warning);
152 | Close();
153 | });
154 | }
155 | },
156 | TaskContinuationOptions.OnlyOnFaulted
157 | );
158 | updateTask.Start();
159 | }
160 | }
161 | }
162 |
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisorUpdater/Properties/Resources.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
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 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | Installing updates...
122 | "Installing updates" string.
123 |
124 |
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisorLauncher/Properties/Resources.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
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 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | Checking for updates...
122 | "Checking for updates" string.
123 |
124 |
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisorUpdater/Properties/Resources.en.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
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 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | Installing updates...
122 | "Installing updates" string.
123 |
124 |
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisorUpdater/Properties/Resources.ru.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
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 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | Установка обновлений...
122 | "Installing updates" string.
123 |
124 |
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisorLauncher/Properties/Resources.en.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
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 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | Checking for updates...
122 | "Checking for updates" string.
123 |
124 |
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisorLauncher/Properties/Resources.ru.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
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 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | Проверка обновлений...
122 | "Checking for updates" string.
123 |
124 |
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisorUpdater/Properties/Resources.es.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
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 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | Instalando actualizaciones...
122 | "Installing updates" string.
123 |
124 |
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisorLauncher/Properties/Resources.es.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
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 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | Comprobando actualizaciones...
122 | "Checking for updates" string.
123 |
124 |
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisorConsole/Program.cs:
--------------------------------------------------------------------------------
1 | using DailyArena.Common.Core.Bindable;
2 | using DailyArena.Common.Core.Cryptography;
3 | using DailyArena.Common.Core.Database;
4 | using DailyArena.DeckAdvisor.Common;
5 | using DailyArena.DeckAdvisor.Common.Extensions;
6 | using DailyArena.DeckAdvisor.Console.Resources;
7 | using Microsoft.Extensions.Configuration;
8 | using Serilog;
9 | using System;
10 | using System.Collections.Generic;
11 | using System.IO;
12 | using System.Reflection;
13 | using System.Security.Cryptography;
14 | using System.Text;
15 | using System.Text.RegularExpressions;
16 | using S = System;
17 |
18 | namespace DailyArena.DeckAdvisor.Console
19 | {
20 | ///
21 | /// The main program for the platform-independent console version of the application.
22 | ///
23 | public class Program : IDeckAdvisorApp, IDeckAdvisorProgram
24 | {
25 | ///
26 | /// The application's Cached State.
27 | ///
28 | public CachedState State { get; set; } = new CachedState();
29 |
30 | ///
31 | /// The application's Logger.
32 | ///
33 | public ILogger Logger { get; set; }
34 |
35 | ///
36 | /// Gets the application name string to use while logging.
37 | ///
38 | public string ApplicationName { get { return "Console Application"; } }
39 |
40 | ///
41 | /// Gets the application name to use while sending Usage Statistics.
42 | ///
43 | public string ApplicationUsageName { get { return "DailyArenaDeckAdvisorConsole"; } }
44 |
45 | ///
46 | /// Logger for first chance exceptions.
47 | ///
48 | public ILogger FirstChanceLogger { get; set; }
49 |
50 | ///
51 | /// The Program constructor.
52 | ///
53 | public Program()
54 | {
55 | this.InitializeApp("-console", false);
56 | this.InitializeProgram();
57 | }
58 |
59 | ///
60 | /// Gets or sets the current executing program.
61 | ///
62 | public static Program CurrentProgram { get; private set; }
63 |
64 | ///
65 | /// Field to store the configuration from appsettings.json
66 | ///
67 | private IConfigurationRoot _configuration;
68 |
69 | ///
70 | /// Gets or sets a dictionary mapping the Format names shown on the GUI drop-down to the name to use when querying archetype data from the server.
71 | ///
72 | public Dictionary> FormatMappings { get; set; }
73 |
74 | ///
75 | /// Method to query a configuration setting.
76 | ///
77 | /// The setting key.
78 | /// The setting value.
79 | public string GetConfigurationSetting(string key)
80 | {
81 | Logger.Debug("GetConfigurationSetting() Called - {key} ({ApplicationName})", key, ApplicationName);
82 |
83 | if (_configuration == null)
84 | {
85 | var exePath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().CodeBase);
86 | Logger.Debug("CodeBase: {exePath}", exePath);
87 |
88 | var appRoot = exePath;
89 | if(appRoot.Contains("\\"))
90 | {
91 | Regex appPathMatcher = new Regex(@"(?
106 | /// Method to get a localized string based on the resource name.
107 | ///
108 | /// The resource name to get a localized string for.
109 | /// The localized string for the requested resource name.
110 | public string GetLocalizedString(string name)
111 | {
112 | return Localization.ResourceManager.GetString(name);
113 | }
114 |
115 | ///
116 | /// Gets the currently running app.
117 | ///
118 | public IDeckAdvisorApp CurrentApp
119 | {
120 | get
121 | {
122 | return CurrentProgram;
123 | }
124 | }
125 |
126 | ///
127 | /// Gets or sets the selected format being viewed.
128 | ///
129 | public Bindable Format { get; private set; } = new Bindable();
130 |
131 | ///
132 | /// Gets or sets the selected deck sort field.
133 | ///
134 | public Bindable Sort { get; private set; } = new Bindable();
135 |
136 | ///
137 | /// Gets or sets the selected deck sort direction.
138 | ///
139 | public Bindable SortDir { get; private set; } = new Bindable();
140 |
141 | ///
142 | /// Gets or sets the state of the "Rotation" toggle button.
143 | ///
144 | public BindableBool RotationProof { get; private set; } = new BindableBool();
145 |
146 | ///
147 | /// Gets or sets the card text filter value.
148 | ///
149 | public Bindable CardText { get; private set; } = new Bindable() { Value = string.Empty };
150 |
151 | ///
152 | /// Gets or sets the selected font size for the display.
153 | ///
154 | public Bindable SelectedFontSize { get; private set; } = new Bindable() { Value = 12 };
155 |
156 | ///
157 | /// Method to run the program.
158 | ///
159 | public void Run()
160 | {
161 | S.Console.OutputEncoding = Encoding.UTF8;
162 | S.Console.WriteLine(CurrentProgram.GetLocalizedString("Loading_LoadingCardDatabase"));
163 |
164 | Logger.Debug("Application Running - {0}", ApplicationName);
165 |
166 | AssemblyName assemblyName = Assembly.GetExecutingAssembly().GetName();
167 | string assemblyVersion = assemblyName.Version.ToString();
168 | string assemblyArchitecture = assemblyName.ProcessorArchitecture.ToString();
169 |
170 | S.Console.WriteLine($"Assembly Version: {assemblyVersion}, Assembly Architecture: {assemblyArchitecture})");
171 |
172 | this.InitializeState();
173 |
174 | Logger.Debug("Initializing Card Database");
175 | CardDatabase.Initialize(false);
176 |
177 | S.Console.WriteLine(Localization.Message_PressToExit);
178 | S.Console.ReadKey();
179 | }
180 |
181 | ///
182 | /// The execution entry point.
183 | ///
184 | /// Arguments passed on the command line.
185 | static void Main(string[] args)
186 | {
187 | CurrentProgram = new Program();
188 | CurrentProgram.Run();
189 | }
190 | }
191 | }
192 |
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisor/FiltersDialog.xaml:
--------------------------------------------------------------------------------
1 |
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 |
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisorLauncher/MainWindow.xaml.cs:
--------------------------------------------------------------------------------
1 | using Newtonsoft.Json;
2 | using Serilog;
3 | using System;
4 | using System.Configuration;
5 | using System.Diagnostics;
6 | using System.Globalization;
7 | using System.IO;
8 | using System.IO.Compression;
9 | using System.Linq;
10 | using System.Net;
11 | using System.Reflection;
12 | using System.Threading;
13 | using System.Threading.Tasks;
14 | using System.Windows;
15 | using System.Windows.Controls;
16 |
17 | namespace DailyArenaDeckAdvisorLauncher
18 | {
19 | ///
20 | /// Interaction logic for MainWindow.xaml
21 | ///
22 | public partial class MainWindow : Window
23 | {
24 | ///
25 | /// The logger for the launcher app.
26 | ///
27 | ILogger _logger;
28 |
29 | ///
30 | /// Default constructer, saves a reference to the application logger and initializes the GUI components.
31 | ///
32 | public MainWindow()
33 | {
34 | App application = (App)Application.Current;
35 | _logger = application.Logger;
36 | _logger.Debug("Main Window Constructor Called - {0}", "Launcher");
37 |
38 | SetCulture();
39 | InitializeComponent();
40 | }
41 |
42 | ///
43 | /// Event handler that is called when the window closes. Shuts down the executable.
44 | ///
45 | /// The Window.
46 | /// The event arguments.
47 | private void Window_Closed(object sender, EventArgs e)
48 | {
49 | _logger.Debug("Window Closed, Shutting Down - {0}", "Launcher");
50 | Application.Current.Shutdown();
51 | }
52 |
53 | ///
54 | /// Sets the current UI culture from DailyArenaDeckAdvisor.exe.config if it's set there.
55 | ///
56 | private void SetCulture()
57 | {
58 | _logger.Debug("SetCulture() Called - {0}", "Launcher");
59 |
60 | try
61 | {
62 | var appSettings = ConfigurationManager.OpenExeConfiguration("DailyArenaDeckAdvisor.exe");
63 | if (appSettings == null)
64 | {
65 | _logger.Debug("No AppSettings Found, Using Default UI Culture");
66 | }
67 | else
68 | {
69 | var cultureSetting = appSettings.AppSettings.Settings["UICulture"];
70 | if (cultureSetting != null)
71 | {
72 | var culture = cultureSetting.Value;
73 | _logger.Debug("Setting UI Culture to {culture}", culture);
74 | Thread.CurrentThread.CurrentUICulture = new CultureInfo(culture);
75 | }
76 | else
77 | {
78 | _logger.Debug("UICulture not set in AppSettings, Using Default UI Culture");
79 | }
80 | }
81 | }
82 | catch (ConfigurationErrorsException e)
83 | {
84 | _logger.Error(e, "Exception in SetCulture(), Using Default UI Culture");
85 | }
86 | }
87 |
88 | ///
89 | /// Event handler that is called when the window is loaded. Fires off launcher activities.
90 | ///
91 | /// The Window.
92 | /// The routed event arguments.
93 | private void Window_Loaded(object sender, RoutedEventArgs e)
94 | {
95 | _logger.Debug("Main Window Loaded - {0}", "Launcher");
96 |
97 | Task updateTask = new Task(() =>
98 | {
99 | _logger.Debug("Checking for Updates");
100 | AssemblyName assemblyName = Assembly.GetExecutingAssembly().GetName();
101 | string assemblyVersion = assemblyName.Version.ToString();
102 | string assemblyArchitecture = assemblyName.ProcessorArchitecture.ToString();
103 | _logger.Debug("Assembly Version: {0}, Assembly Architecture: {1}", assemblyVersion, assemblyArchitecture);
104 | bool forceUpdate = false;
105 | using (WebClient client = new WebClient())
106 | {
107 | string ver = Guid.NewGuid().ToString();
108 |
109 | var updaterFileLocation = string.Format("{0}Low\\DailyArena\\DailyArenaDeckAdvisor\\DailyArenaDeckAdvisor.zip", Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData));
110 | if (File.Exists(updaterFileLocation))
111 | {
112 | _logger.Debug("Updater Zip Found, Updating Updater Executable");
113 | bool deleteSuccess = false;
114 | for (int i = 0; i < 30; i++)
115 | {
116 | try
117 | {
118 | foreach(string path in Directory.EnumerateDirectories(Directory.GetCurrentDirectory()))
119 | {
120 | foreach(string filePath in Directory.EnumerateFiles(path))
121 | {
122 | if(filePath.EndsWith("DailyArenaDeckAdvisorUpdater.resources.dll"))
123 | {
124 | File.Delete(filePath);
125 | }
126 | }
127 | }
128 | File.Delete("DailyArenaDeckAdvisorUpdater.exe");
129 | deleteSuccess = true;
130 | break;
131 | }
132 | catch (Exception)
133 | {
134 | Thread.Sleep(200); // give updater up to 6 seconds or so to close
135 | }
136 | }
137 | if(deleteSuccess)
138 | {
139 | _logger.Debug("Successfully Deleted DailyArenaDeckAdvisorUpdater.exe, updating from Zip");
140 |
141 | using (ZipArchive archive = ZipFile.Open(updaterFileLocation, ZipArchiveMode.Read))
142 | {
143 | var entries = archive.Entries.Where(x => x.Name.StartsWith("DailyArenaDeckAdvisorUpdater"));
144 | foreach (var entry in entries)
145 | {
146 | entry.ExtractToFile(entry.Name, true);
147 | }
148 | }
149 | }
150 | else
151 | {
152 | _logger.Debug("Failed to Delete DailyArenaDeckAdvisorUpdater.exe");
153 | forceUpdate = true;
154 | }
155 |
156 | _logger.Debug("Deleting Updater Zip");
157 | File.Delete(updaterFileLocation);
158 | }
159 |
160 | if(forceUpdate)
161 | {
162 | _logger.Debug("Detected a Problem with the previous update, forcing a new one");
163 | }
164 |
165 | try
166 | {
167 | string s = client.DownloadString($"https://clans.dailyarena.net/download/advisor/version.json?ver={ver}");
168 | dynamic versionObj = JsonConvert.DeserializeObject(s);
169 | string version = versionObj.version;
170 | _logger.Debug("Latest Version: {0}", version);
171 |
172 | if ((version == assemblyVersion) && !forceUpdate)
173 | {
174 | _logger.Debug("Starting Main Application");
175 | using (Process advisorApp = new Process())
176 | {
177 | advisorApp.StartInfo.FileName = "DailyArenaDeckAdvisor.exe";
178 | advisorApp.StartInfo.WorkingDirectory = Directory.GetCurrentDirectory();
179 | advisorApp.Start();
180 | }
181 | }
182 | else
183 | {
184 | _logger.Debug("Starting Updater");
185 | using (Process advisorApp = new Process())
186 | {
187 | advisorApp.StartInfo.FileName = "DailyArenaDeckAdvisorUpdater.exe";
188 | advisorApp.StartInfo.WorkingDirectory = Directory.GetCurrentDirectory();
189 | advisorApp.Start();
190 | }
191 | }
192 | }
193 | catch(WebException we)
194 | {
195 | _logger.Error(we, "WebException in {0}, {1} - {2}", "updateTask", "Starting Main Application", "Launcher");
196 | using (Process advisorApp = new Process())
197 | {
198 | advisorApp.StartInfo.FileName = "DailyArenaDeckAdvisor.exe";
199 | advisorApp.StartInfo.WorkingDirectory = Directory.GetCurrentDirectory();
200 | advisorApp.Start();
201 | }
202 | }
203 |
204 | _logger.Debug("Closing Launcher Window");
205 | Dispatcher.Invoke(() => { Close(); });
206 | }
207 | });
208 | updateTask.ContinueWith(t =>
209 | {
210 | if (t.Exception != null)
211 | {
212 | _logger.Error(t.Exception, "Exception in {0} ({1} - {2})", "updateTask", "Window_Loaded", "Launcher");
213 | Dispatcher.Invoke(() => {
214 | var result = MessageBox.Show(t.Exception.InnerException.ToString(), "Launcher Exception", MessageBoxButton.OK, MessageBoxImage.Warning);
215 | Close();
216 | });
217 | }
218 | },
219 | TaskContinuationOptions.OnlyOnFaulted
220 | );
221 | updateTask.Start();
222 | }
223 | }
224 | }
225 |
--------------------------------------------------------------------------------
/DailyArena.DeckAdvisor.Common/Extensions/ProgramExtensions.cs:
--------------------------------------------------------------------------------
1 | using DailyArena.Common.Core.Database;
2 | using DailyArena.Common.Core.Utility;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Collections.Specialized;
6 | using System.Globalization;
7 | using System.Net;
8 | using System.Reflection;
9 | using System.Threading;
10 | using System.Threading.Tasks;
11 |
12 | namespace DailyArena.DeckAdvisor.Common.Extensions
13 | {
14 | ///
15 | /// Common class extension for Deck Advisor Program classes.
16 | ///
17 | public static class ProgramExtensions
18 | {
19 | ///
20 | /// Initialization extension for IDeckAdvisorProgram.
21 | ///
22 | /// The program.
23 | public static void InitializeProgram(this IDeckAdvisorProgram program)
24 | {
25 | program.Logger.Debug("InitializeProgram() Called - {0}", program.ApplicationName);
26 |
27 | program.SetCulture();
28 |
29 | // these have to happen after SetCulture()
30 | program.FormatMappings = new Dictionary>()
31 | {
32 | { program.GetLocalizedString("Item_Standard"), new Tuple("standard", "Standard") },
33 | { program.GetLocalizedString("Item_ArenaStandard"), new Tuple("arena_standard", "ArenaStandard") },
34 | { program.GetLocalizedString("Item_Brawl"), new Tuple("brawl", "Brawl") },
35 | { program.GetLocalizedString("Item_Historic_Bo3"), new Tuple("historic_bo3", "Historic") },
36 | { program.GetLocalizedString("Item_Historic_Bo1"), new Tuple("historic_bo1", "Historic") }
37 | };
38 |
39 | program.SendUsageStats();
40 | }
41 |
42 | ///
43 | /// Sets the current UI culture from app.config if it's set there.
44 | ///
45 | /// The program.
46 | private static void SetCulture(this IDeckAdvisorProgram program)
47 | {
48 | program.Logger.Debug("SetCulture() Called - {0}", program.ApplicationName);
49 |
50 | string culture = program.GetConfigurationSetting("UICulture");
51 | if(culture != null)
52 | {
53 | program.Logger.Debug("Setting UI Culture to {culture}", culture);
54 | Thread.CurrentThread.CurrentUICulture = new CultureInfo(culture);
55 | }
56 | else
57 | {
58 | program.Logger.Debug("UICulture not set in configuration settings, Using Default UI Culture");
59 | }
60 |
61 | program.Logger.Debug("Current UI Culture: {CurrentUICulture}", Thread.CurrentThread.CurrentUICulture);
62 | }
63 |
64 | ///
65 | /// Send usage stats to server.
66 | ///
67 | /// The program.
68 | private static void SendUsageStats(this IDeckAdvisorProgram program)
69 | {
70 | program.Logger.Debug("SendUsageStats() Called - {0}", program.ApplicationName);
71 |
72 | new Task(() =>
73 | {
74 | AssemblyName assemblyName = Assembly.GetExecutingAssembly().GetName();
75 | string assemblyVersion = assemblyName.Version.ToString();
76 | string assemblyArchitecture = assemblyName.ProcessorArchitecture.ToString();
77 |
78 | NameValueCollection inputs = new NameValueCollection
79 | {
80 | { "application", program.ApplicationUsageName },
81 | { "fingerprint", program.CurrentApp.State.Fingerprint.ToString() },
82 | { "version", assemblyVersion },
83 | { "architecture", assemblyArchitecture }
84 | };
85 | string response = WebUtilities.UploadValues("https://clans.dailyarena.net/usage_stats.php", inputs, "POST", true, out List exceptions);
86 | program.Logger.Debug("Usage Statistics Response: {response}", response);
87 | if (response == null)
88 | {
89 | foreach (WebException exception in exceptions)
90 | {
91 | program.Logger.Error(exception, "Exception from UploadValues in {method}", "SendUsageStats");
92 | }
93 | }
94 | }).Start();
95 | }
96 |
97 | ///
98 | /// Initialize various state variables.
99 | ///
100 | /// The program.
101 | public static void InitializeState(this IDeckAdvisorProgram program)
102 | {
103 | program.Logger.Debug("InitializeState() Called - {0}", program.ApplicationName);
104 |
105 | bool saveState = false;
106 | program.Format.Value = program.CurrentApp.State.LastFormat;
107 | if (string.IsNullOrWhiteSpace(program.Format.Value) || !program.FormatMappings.ContainsKey(program.Format.Value))
108 | {
109 | program.Format.Value = program.GetLocalizedString("Item_Standard");
110 | program.CurrentApp.State.LastFormat = program.Format.Value;
111 | saveState = true;
112 | }
113 |
114 | program.Sort.Value = program.CurrentApp.State.LastSort;
115 | List sortStrings = new List()
116 | {
117 | program.GetLocalizedString("Item_Default"),
118 | program.GetLocalizedString("Item_BoosterCost"),
119 | program.GetLocalizedString("Item_BoosterCostIgnoringWildcards"),
120 | program.GetLocalizedString("Item_BoosterCostIgnoringCollection"),
121 | program.GetLocalizedString("Item_DeckScore"),
122 | program.GetLocalizedString("Item_WinRate"),
123 | program.GetLocalizedString("Item_MythicRareCount"),
124 | program.GetLocalizedString("Item_RareCount"),
125 | program.GetLocalizedString("Item_UncommonCount"),
126 | program.GetLocalizedString("Item_CommonCount")
127 | };
128 | if (string.IsNullOrWhiteSpace(program.Sort.Value) || !sortStrings.Contains(program.Sort.Value))
129 | {
130 | program.Sort.Value = program.GetLocalizedString("Item_Default");
131 | program.CurrentApp.State.LastSort = program.Sort.Value;
132 | saveState = true;
133 | }
134 |
135 | program.SortDir.Value = program.CurrentApp.State.LastSortDir;
136 | List sortDirStrings = new List()
137 | {
138 | program.GetLocalizedString("Item_Default"),
139 | program.GetLocalizedString("Item_Ascending"),
140 | program.GetLocalizedString("Item_Descending")
141 | };
142 | if (string.IsNullOrWhiteSpace(program.SortDir.Value) || !sortDirStrings.Contains(program.SortDir.Value))
143 | {
144 | program.SortDir.Value = program.GetLocalizedString("Item_Default");
145 | program.CurrentApp.State.LastSortDir = program.SortDir.Value;
146 | saveState = true;
147 | }
148 |
149 | program.RotationProof.Value = program.CurrentApp.State.RotationProof;
150 | program.CardText.Value = program.CurrentApp.State.CardTextFilter;
151 |
152 | int fontSize = program.CurrentApp.State.FontSize;
153 | if (fontSize < 8 || fontSize > 24)
154 | {
155 | program.SelectedFontSize.Value = 12;
156 | program.CurrentApp.State.FontSize = program.SelectedFontSize.Value;
157 | saveState = true;
158 | }
159 | else
160 | {
161 | program.SelectedFontSize.Value = fontSize;
162 | }
163 |
164 | if (saveState)
165 | {
166 | program.CurrentApp.SaveState();
167 | }
168 | }
169 |
170 | ///
171 | /// Initialize the card database, and populate objects that are loaded from the back-end server.
172 | ///
173 | /// The program.
174 | /*public static Task InitializeDatabaseAndPopulate(this IDeckAdvisorProgram program)
175 | {
176 | program.Logger.Debug("InitializeDatabaseAndPopulate() Called - {0}", program.ApplicationName);
177 |
178 | Task loadTask = new Task(() => {
179 | program.Logger.Debug("Initializing Card Database");
180 | CardDatabase.Initialize(false);
181 | LoadingValue.Value = 20;
182 |
183 | PopulateColorsByLand();
184 | LoadingValue.Value = 30;
185 |
186 | PopulateStandardBannings();
187 | LoadingValue.Value = 40;
188 |
189 | PopulateSetTranslations();
190 | LoadingValue.Value = 50;
191 |
192 | ReloadAndCrunchAllData();
193 | });
194 | loadTask.ContinueWith(t =>
195 | {
196 | if (t.Exception != null)
197 | {
198 | Logger.Error(t.Exception, "Exception in {0} ({1} - {2})", "loadTask", "Window_Loaded", ApplicationName);
199 |
200 | ReportException("loadTask", "Window_Loaded", t.Exception);
201 | }
202 | },
203 | TaskContinuationOptions.OnlyOnFaulted
204 | );
205 | loadTask.Start();
206 |
207 | return loadTask;
208 | }*/
209 | }
210 | }
211 |
--------------------------------------------------------------------------------
/DailyArena.DeckAdvisor.Common/Extensions/AppExtensions.cs:
--------------------------------------------------------------------------------
1 | using DailyArena.Common.Core.Extensions;
2 | using DailyArena.Common.Core.Utility;
3 | using Newtonsoft.Json;
4 | using Serilog;
5 | using Serilog.Debugging;
6 | using Serilog.Formatting.Compact;
7 | using System;
8 | using System.Diagnostics;
9 | using System.IO;
10 | using System.Management;
11 |
12 | namespace DailyArena.DeckAdvisor.Common.Extensions
13 | {
14 | ///
15 | /// Common class extension for Deck Advisor App classes.
16 | ///
17 | public static class AppExtensions
18 | {
19 | ///
20 | /// Save the Cached State out to a file.
21 | ///
22 | /// The application object.
23 | public static void SaveState(this IDeckAdvisorApp app)
24 | {
25 | string stateJson = JsonConvert.SerializeObject(app.State);
26 | File.WriteAllText("state.json", stateJson);
27 | }
28 |
29 | ///
30 | /// Load the Cached State from a file, or create a new one.
31 | ///
32 | /// The application object.
33 | public static void LoadState(this IDeckAdvisorApp app)
34 | {
35 | if (File.Exists("state.json"))
36 | {
37 | string stateJson = File.ReadAllText("state.json");
38 | app.State = JsonConvert.DeserializeObject(stateJson);
39 |
40 | bool saveState = false;
41 | if (app.State.Fingerprint == Guid.Empty)
42 | {
43 | app.State.Fingerprint = Guid.NewGuid();
44 | saveState = true;
45 | }
46 | if (app.State.Filters == null)
47 | {
48 | app.State.Filters = new DeckFilters();
49 | saveState = true;
50 | }
51 | if (saveState)
52 | {
53 | app.SaveState();
54 | }
55 | }
56 | else
57 | {
58 | app.State = new CachedState();
59 | }
60 | }
61 |
62 | ///
63 | /// Clear the Cached State and delete the corresponding file if it exists.
64 | ///
65 | /// The application object.
66 | public static void ClearState(this IDeckAdvisorApp app)
67 | {
68 | app.State = new CachedState();
69 | if (File.Exists("state.json"))
70 | {
71 | File.Delete("state.json");
72 | }
73 | }
74 |
75 | ///
76 | /// Logs information about the system the application is running on.
77 | ///
78 | /// The application object.
79 | public static void LogSystemInfo(this IDeckAdvisorApp app)
80 | {
81 | ManagementObjectSearcher videoController = new ManagementObjectSearcher("select * from Win32_VideoController");
82 |
83 | foreach (ManagementObject obj in videoController.Get())
84 | {
85 | app.Logger.Debug("Video Controller Info:\nName:{Name}\nStatus:{Status}\nCaption:{Caption}\nDeviceID:{DeviceID}\nAdapterRAM:{AdapterRAM}\nAdapterDACType:{AdapterDACType}\nMonochrome:{Monochrome}\n" +
86 | "InstalledDisplayDrivers:{InstalledDisplayDrivers}\nDriverVersion:{DriverVersion}\nVideoProcessor:{VideoProcessor}\nVideoArchitecture:{VideoArchitecture}\nVideoMemoryType:{VideoMemoryType}",
87 | obj.TryGetProperty("Name"), obj.TryGetProperty("Status"), obj.TryGetProperty("Caption"), obj.TryGetProperty("DeviceID"), SizeSuffix((long)Convert.ToDouble(obj.TryGetProperty("AdapterRAM"))), obj.TryGetProperty("AdapterDACType"), obj.TryGetProperty("Monochrome"),
88 | obj.TryGetProperty("InstalledDisplayDrivers"), obj.TryGetProperty("DriverVersion"), obj.TryGetProperty("VideoProcessor"), obj.TryGetProperty("VideoArchitecture"), obj.TryGetProperty("VideoMemoryType"));
89 | }
90 |
91 | ManagementObjectSearcher processor = new ManagementObjectSearcher("select * from Win32_Processor");
92 |
93 | foreach (ManagementObject obj in processor.Get())
94 | {
95 | app.Logger.Debug("Processor Info:\nName:{Name}\nDeviceID:{DeviceID}\nManufacturer:{Manufacturer}\nCurrentClockSpeed:{CurrentClockSpeed}\nCaption:{Caption}\nNumberOfCores:{NumberOfCores}\nNumberOfEnabledCore:{NumberOfEnabledCore}\n" +
96 | "NumberOfLogicalProcessors:{NumberOfLogicalProcessors}\nArchitecture:{Architecture}\nFamily:{Family}\nProcessorType:{ProcessorType}\nCharacteristics:{Characteristics}\nAddressWidth:{AddressWidth}",
97 | obj.TryGetProperty("Name"), obj.TryGetProperty("DeviceID"), obj.TryGetProperty("Manufacturer"), obj.TryGetProperty("CurrentClockSpeed"), obj.TryGetProperty("Caption"), obj.TryGetProperty("NumberOfCores"), obj.TryGetProperty("NumberOfEnabledCore"),
98 | obj.TryGetProperty("NumberOfLogicalProcessors"), obj.TryGetProperty("Architecture"), obj.TryGetProperty("Family"), obj.TryGetProperty("ProcessorType"), obj.TryGetProperty("Characteristics"), obj.TryGetProperty("AddressWidth"));
99 | }
100 |
101 | ManagementObjectSearcher operatingSystem = new ManagementObjectSearcher("select * from Win32_OperatingSystem");
102 |
103 | foreach (ManagementObject obj in operatingSystem.Get())
104 | {
105 | app.Logger.Debug("Operating System Info:\nCaption:{Caption}\nWindowsDirectory:{WindowsDirectory}\nProductType:{ProductType}\nSerialNumber:{SerialNumber}\nSystemDirectory:{SystemDirectory}\nCountryCode:{CountryCode}\nCurrentTimeZone:{CurrentTimeZone}\n" +
106 | "EncryptionLevel:{EncryptionLevel}\nOSType:{OSType}\nVersion:{Version}",
107 | obj.TryGetProperty("Caption"), obj.TryGetProperty("WindowsDirectory"), obj.TryGetProperty("ProductType"), obj.TryGetProperty("SerialNumber"), obj.TryGetProperty("SystemDirectory"), obj.TryGetProperty("CountryCode"), obj.TryGetProperty("CurrentTimeZone"),
108 | obj.TryGetProperty("EncryptionLevel"), obj.TryGetProperty("OSType"), obj.TryGetProperty("Version"));
109 | }
110 | }
111 |
112 | ///
113 | /// Size suffixes for human-readable RAM strings.
114 | ///
115 | static readonly string[] SizeSuffixes = { "bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB" };
116 |
117 | ///
118 | /// Convert RAM value to human-readable format.
119 | ///
120 | /// The bare value.
121 | /// The passed value as a human-readable stirng.
122 | static string SizeSuffix(long value)
123 | {
124 | if (value < 0) { return "-" + SizeSuffix(-value); }
125 | if (value == 0) { return "0.0 bytes"; }
126 |
127 | int mag = (int)Math.Log(value, 1024);
128 | decimal adjustedSize = (decimal)value / (1L << (mag * 10));
129 |
130 | return string.Format("{0:n1} {1}", adjustedSize, SizeSuffixes[mag]);
131 | }
132 |
133 | ///
134 | /// Initialization extension for IDeckAdvisorApp.
135 | ///
136 | /// The app.
137 | /// The postfix for log files.
138 | /// Whether to log system info (don't do this in the .NET Core application)
139 | public static void InitializeApp(this IDeckAdvisorApp app, string postfix = "", bool logSystemInfo = true)
140 | {
141 | ApplicationUtilities.CurrentApp = app;
142 |
143 | var dataFolder = string.Format("{0}Low{1}DailyArena{1}DailyArenaDeckAdvisor", Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), Path.DirectorySeparatorChar);
144 | if (!Directory.Exists(dataFolder))
145 | {
146 | Directory.CreateDirectory(dataFolder);
147 | }
148 | var logFolder = string.Format($"{dataFolder}{Path.DirectorySeparatorChar}logs");
149 | if (!Directory.Exists(logFolder))
150 | {
151 | Directory.CreateDirectory(logFolder);
152 | }
153 | Directory.SetCurrentDirectory(dataFolder);
154 |
155 | SelfLog.Enable(msg => Debug.WriteLine(msg));
156 | SelfLog.Enable(Console.Error);
157 | app.Logger = new LoggerConfiguration().MinimumLevel.Debug().WriteTo.
158 | File(new CompactJsonFormatter(), $"{dataFolder}{Path.DirectorySeparatorChar}logs{Path.DirectorySeparatorChar}log{postfix}.txt",
159 | rollingInterval: RollingInterval.Hour,
160 | retainedFileCountLimit: 5,
161 | fileSizeLimitBytes: 10485760,
162 | rollOnFileSizeLimit: true,
163 | shared: true).
164 | CreateLogger();
165 | app.FirstChanceLogger = new LoggerConfiguration().MinimumLevel.Debug().WriteTo.
166 | File(new CompactJsonFormatter(), $"{dataFolder}{Path.DirectorySeparatorChar}logs{Path.DirectorySeparatorChar}firstChanceExceptions{postfix}.txt",
167 | rollingInterval: RollingInterval.Hour,
168 | retainedFileCountLimit: 2,
169 | fileSizeLimitBytes: 10485760,
170 | rollOnFileSizeLimit: true,
171 | shared: true).
172 | CreateLogger();
173 |
174 | AppDomain.CurrentDomain.UnhandledException += (sender, e) =>
175 | {
176 | app.Logger.Error((Exception)e.ExceptionObject, "UnhandledException");
177 | };
178 |
179 | AppDomain.CurrentDomain.FirstChanceException += (source, e) =>
180 | {
181 | app.FirstChanceLogger.Debug(e.Exception, "FirstChanceException");
182 | };
183 |
184 | if (logSystemInfo)
185 | {
186 | // only log system info when running on Windows
187 | app.LogSystemInfo();
188 | }
189 | app.LoadState();
190 | }
191 | }
192 | }
193 |
--------------------------------------------------------------------------------
/DailyArenaDeckAdvisor.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | VisualStudioVersion = 15.0.28307.572
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DailyArenaDeckAdvisor", "DailyArenaDeckAdvisor\DailyArenaDeckAdvisor.csproj", "{7A3A0A04-3697-479E-8EC9-6D2B944FABD1}"
7 | EndProject
8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{661EA5CB-B016-4206-A05A-6454B21F77EC}"
9 | ProjectSection(SolutionItems) = preProject
10 | AssemblyVersion.cs = AssemblyVersion.cs
11 | SolutionInfo.proj = SolutionInfo.proj
12 | EndProjectSection
13 | EndProject
14 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DailyArenaDeckAdvisorLauncher", "DailyArenaDeckAdvisorLauncher\DailyArenaDeckAdvisorLauncher.csproj", "{1AA67122-ABBB-49DE-B260-3C658728AD4E}"
15 | EndProject
16 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DailyArenaDeckAdvisorUpdater", "DailyArenaDeckAdvisorUpdater\DailyArenaDeckAdvisorUpdater.csproj", "{986235B3-F7D9-4607-8CF8-7D8649FA1F23}"
17 | EndProject
18 | Project("{930C7802-8A8C-48F9-8165-68863BCCD9DD}") = "DailyArenaDeckAdvisorSetup", "DailyArenaDeckAdvisorSetup\DailyArenaDeckAdvisorSetup.wixproj", "{54173857-C11E-49C8-8CDC-46FD269E506A}"
19 | EndProject
20 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "libraries", "libraries", "{DB7BDEFC-DD2B-4083-8B63-4A777E490E5C}"
21 | ProjectSection(SolutionItems) = preProject
22 | libraries\DailyArena.Common.Core.dll = libraries\DailyArena.Common.Core.dll
23 | libraries\DailyArena.Common.dll = libraries\DailyArena.Common.dll
24 | EndProjectSection
25 | EndProject
26 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DailyArenaDeckAdvisorConsole", "DailyArenaDeckAdvisorConsole\DailyArenaDeckAdvisorConsole.csproj", "{2FEB82DF-993C-4D1A-8306-7EB6A63BC397}"
27 | EndProject
28 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DailyArena.DeckAdvisor.Common", "DailyArena.DeckAdvisor.Common\DailyArena.DeckAdvisor.Common.csproj", "{CF1EE6D1-3ED2-4B73-A8DA-71FBBE22593E}"
29 | EndProject
30 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DailyArena.DeckAdvisor.GetData", "DailyArenaDeckAdvisor.GetData\DailyArena.DeckAdvisor.GetData.csproj", "{CA4081DD-18DA-41D1-B0DB-8DF9AAA6B13F}"
31 | EndProject
32 | Global
33 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
34 | Debug|Any CPU = Debug|Any CPU
35 | Debug|x64 = Debug|x64
36 | Debug|x86 = Debug|x86
37 | Release|Any CPU = Release|Any CPU
38 | Release|x64 = Release|x64
39 | Release|x86 = Release|x86
40 | EndGlobalSection
41 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
42 | {7A3A0A04-3697-479E-8EC9-6D2B944FABD1}.Debug|Any CPU.ActiveCfg = Debug|x86
43 | {7A3A0A04-3697-479E-8EC9-6D2B944FABD1}.Debug|x64.ActiveCfg = Debug|x64
44 | {7A3A0A04-3697-479E-8EC9-6D2B944FABD1}.Debug|x64.Build.0 = Debug|x64
45 | {7A3A0A04-3697-479E-8EC9-6D2B944FABD1}.Debug|x86.ActiveCfg = Debug|x86
46 | {7A3A0A04-3697-479E-8EC9-6D2B944FABD1}.Debug|x86.Build.0 = Debug|x86
47 | {7A3A0A04-3697-479E-8EC9-6D2B944FABD1}.Release|Any CPU.ActiveCfg = Release|x86
48 | {7A3A0A04-3697-479E-8EC9-6D2B944FABD1}.Release|x64.ActiveCfg = Release|x64
49 | {7A3A0A04-3697-479E-8EC9-6D2B944FABD1}.Release|x64.Build.0 = Release|x64
50 | {7A3A0A04-3697-479E-8EC9-6D2B944FABD1}.Release|x86.ActiveCfg = Release|x86
51 | {7A3A0A04-3697-479E-8EC9-6D2B944FABD1}.Release|x86.Build.0 = Release|x86
52 | {1AA67122-ABBB-49DE-B260-3C658728AD4E}.Debug|Any CPU.ActiveCfg = Debug|x86
53 | {1AA67122-ABBB-49DE-B260-3C658728AD4E}.Debug|x64.ActiveCfg = Debug|x64
54 | {1AA67122-ABBB-49DE-B260-3C658728AD4E}.Debug|x64.Build.0 = Debug|x64
55 | {1AA67122-ABBB-49DE-B260-3C658728AD4E}.Debug|x86.ActiveCfg = Debug|x86
56 | {1AA67122-ABBB-49DE-B260-3C658728AD4E}.Debug|x86.Build.0 = Debug|x86
57 | {1AA67122-ABBB-49DE-B260-3C658728AD4E}.Release|Any CPU.ActiveCfg = Release|x86
58 | {1AA67122-ABBB-49DE-B260-3C658728AD4E}.Release|x64.ActiveCfg = Release|x64
59 | {1AA67122-ABBB-49DE-B260-3C658728AD4E}.Release|x64.Build.0 = Release|x64
60 | {1AA67122-ABBB-49DE-B260-3C658728AD4E}.Release|x86.ActiveCfg = Release|x86
61 | {1AA67122-ABBB-49DE-B260-3C658728AD4E}.Release|x86.Build.0 = Release|x86
62 | {986235B3-F7D9-4607-8CF8-7D8649FA1F23}.Debug|Any CPU.ActiveCfg = Debug|x86
63 | {986235B3-F7D9-4607-8CF8-7D8649FA1F23}.Debug|x64.ActiveCfg = Debug|x64
64 | {986235B3-F7D9-4607-8CF8-7D8649FA1F23}.Debug|x64.Build.0 = Debug|x64
65 | {986235B3-F7D9-4607-8CF8-7D8649FA1F23}.Debug|x86.ActiveCfg = Debug|x86
66 | {986235B3-F7D9-4607-8CF8-7D8649FA1F23}.Debug|x86.Build.0 = Debug|x86
67 | {986235B3-F7D9-4607-8CF8-7D8649FA1F23}.Release|Any CPU.ActiveCfg = Release|x86
68 | {986235B3-F7D9-4607-8CF8-7D8649FA1F23}.Release|x64.ActiveCfg = Release|x64
69 | {986235B3-F7D9-4607-8CF8-7D8649FA1F23}.Release|x64.Build.0 = Release|x64
70 | {986235B3-F7D9-4607-8CF8-7D8649FA1F23}.Release|x86.ActiveCfg = Release|x86
71 | {986235B3-F7D9-4607-8CF8-7D8649FA1F23}.Release|x86.Build.0 = Release|x86
72 | {54173857-C11E-49C8-8CDC-46FD269E506A}.Debug|Any CPU.ActiveCfg = Debug|x86
73 | {54173857-C11E-49C8-8CDC-46FD269E506A}.Debug|x64.ActiveCfg = Debug|x64
74 | {54173857-C11E-49C8-8CDC-46FD269E506A}.Debug|x64.Build.0 = Debug|x64
75 | {54173857-C11E-49C8-8CDC-46FD269E506A}.Debug|x86.ActiveCfg = Debug|x86
76 | {54173857-C11E-49C8-8CDC-46FD269E506A}.Debug|x86.Build.0 = Debug|x86
77 | {54173857-C11E-49C8-8CDC-46FD269E506A}.Release|Any CPU.ActiveCfg = Release|x86
78 | {54173857-C11E-49C8-8CDC-46FD269E506A}.Release|x64.ActiveCfg = Release|x64
79 | {54173857-C11E-49C8-8CDC-46FD269E506A}.Release|x64.Build.0 = Release|x64
80 | {54173857-C11E-49C8-8CDC-46FD269E506A}.Release|x86.ActiveCfg = Release|x86
81 | {54173857-C11E-49C8-8CDC-46FD269E506A}.Release|x86.Build.0 = Release|x86
82 | {2FEB82DF-993C-4D1A-8306-7EB6A63BC397}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
83 | {2FEB82DF-993C-4D1A-8306-7EB6A63BC397}.Debug|Any CPU.Build.0 = Debug|Any CPU
84 | {2FEB82DF-993C-4D1A-8306-7EB6A63BC397}.Debug|x64.ActiveCfg = Debug|Any CPU
85 | {2FEB82DF-993C-4D1A-8306-7EB6A63BC397}.Debug|x64.Build.0 = Debug|Any CPU
86 | {2FEB82DF-993C-4D1A-8306-7EB6A63BC397}.Debug|x86.ActiveCfg = Debug|Any CPU
87 | {2FEB82DF-993C-4D1A-8306-7EB6A63BC397}.Debug|x86.Build.0 = Debug|Any CPU
88 | {2FEB82DF-993C-4D1A-8306-7EB6A63BC397}.Release|Any CPU.ActiveCfg = Release|Any CPU
89 | {2FEB82DF-993C-4D1A-8306-7EB6A63BC397}.Release|Any CPU.Build.0 = Release|Any CPU
90 | {2FEB82DF-993C-4D1A-8306-7EB6A63BC397}.Release|x64.ActiveCfg = Release|Any CPU
91 | {2FEB82DF-993C-4D1A-8306-7EB6A63BC397}.Release|x64.Build.0 = Release|Any CPU
92 | {2FEB82DF-993C-4D1A-8306-7EB6A63BC397}.Release|x86.ActiveCfg = Release|Any CPU
93 | {2FEB82DF-993C-4D1A-8306-7EB6A63BC397}.Release|x86.Build.0 = Release|Any CPU
94 | {CF1EE6D1-3ED2-4B73-A8DA-71FBBE22593E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
95 | {CF1EE6D1-3ED2-4B73-A8DA-71FBBE22593E}.Debug|Any CPU.Build.0 = Debug|Any CPU
96 | {CF1EE6D1-3ED2-4B73-A8DA-71FBBE22593E}.Debug|x64.ActiveCfg = Debug|Any CPU
97 | {CF1EE6D1-3ED2-4B73-A8DA-71FBBE22593E}.Debug|x64.Build.0 = Debug|Any CPU
98 | {CF1EE6D1-3ED2-4B73-A8DA-71FBBE22593E}.Debug|x86.ActiveCfg = Debug|Any CPU
99 | {CF1EE6D1-3ED2-4B73-A8DA-71FBBE22593E}.Debug|x86.Build.0 = Debug|Any CPU
100 | {CF1EE6D1-3ED2-4B73-A8DA-71FBBE22593E}.Release|Any CPU.ActiveCfg = Release|Any CPU
101 | {CF1EE6D1-3ED2-4B73-A8DA-71FBBE22593E}.Release|Any CPU.Build.0 = Release|Any CPU
102 | {CF1EE6D1-3ED2-4B73-A8DA-71FBBE22593E}.Release|x64.ActiveCfg = Release|Any CPU
103 | {CF1EE6D1-3ED2-4B73-A8DA-71FBBE22593E}.Release|x64.Build.0 = Release|Any CPU
104 | {CF1EE6D1-3ED2-4B73-A8DA-71FBBE22593E}.Release|x86.ActiveCfg = Release|Any CPU
105 | {CF1EE6D1-3ED2-4B73-A8DA-71FBBE22593E}.Release|x86.Build.0 = Release|Any CPU
106 | {CA4081DD-18DA-41D1-B0DB-8DF9AAA6B13F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
107 | {CA4081DD-18DA-41D1-B0DB-8DF9AAA6B13F}.Debug|Any CPU.Build.0 = Debug|Any CPU
108 | {CA4081DD-18DA-41D1-B0DB-8DF9AAA6B13F}.Debug|x64.ActiveCfg = Debug|Any CPU
109 | {CA4081DD-18DA-41D1-B0DB-8DF9AAA6B13F}.Debug|x64.Build.0 = Debug|Any CPU
110 | {CA4081DD-18DA-41D1-B0DB-8DF9AAA6B13F}.Debug|x86.ActiveCfg = Debug|Any CPU
111 | {CA4081DD-18DA-41D1-B0DB-8DF9AAA6B13F}.Debug|x86.Build.0 = Debug|Any CPU
112 | {CA4081DD-18DA-41D1-B0DB-8DF9AAA6B13F}.Release|Any CPU.ActiveCfg = Release|Any CPU
113 | {CA4081DD-18DA-41D1-B0DB-8DF9AAA6B13F}.Release|Any CPU.Build.0 = Release|Any CPU
114 | {CA4081DD-18DA-41D1-B0DB-8DF9AAA6B13F}.Release|x64.ActiveCfg = Release|Any CPU
115 | {CA4081DD-18DA-41D1-B0DB-8DF9AAA6B13F}.Release|x64.Build.0 = Release|Any CPU
116 | {CA4081DD-18DA-41D1-B0DB-8DF9AAA6B13F}.Release|x86.ActiveCfg = Release|Any CPU
117 | {CA4081DD-18DA-41D1-B0DB-8DF9AAA6B13F}.Release|x86.Build.0 = Release|Any CPU
118 | EndGlobalSection
119 | GlobalSection(SolutionProperties) = preSolution
120 | HideSolutionNode = FALSE
121 | EndGlobalSection
122 | GlobalSection(ExtensibilityGlobals) = postSolution
123 | SolutionGuid = {DAA6E113-4A06-42E0-8DA7-0615C89EF4E1}
124 | EndGlobalSection
125 | EndGlobal
126 |
--------------------------------------------------------------------------------