diff --git a/Artemis/Artemis/Artemis.csproj b/Artemis/Artemis/Artemis.csproj
index a0da17063..cc6511ec3 100644
--- a/Artemis/Artemis/Artemis.csproj
+++ b/Artemis/Artemis/Artemis.csproj
@@ -175,6 +175,10 @@
..\packages\Newtonsoft.Json.8.0.3\lib\net45\Newtonsoft.Json.dll
True
+
+ ..\packages\NLog.4.3.2\lib\net45\NLog.dll
+ True
+
..\packages\SharpDX.3.0.2\lib\net45\SharpDX.dll
True
@@ -299,6 +303,7 @@
+
TypeWave.settings
@@ -529,6 +534,12 @@
SettingsSingleFileGenerator
VolumeDisplay.Designer.cs
+
+ Always
+
+
+ Designer
+
diff --git a/Artemis/Artemis/Managers/EffectManager.cs b/Artemis/Artemis/Managers/EffectManager.cs
index f7b639406..5c81fc0ec 100644
--- a/Artemis/Artemis/Managers/EffectManager.cs
+++ b/Artemis/Artemis/Managers/EffectManager.cs
@@ -1,29 +1,45 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using System.Threading;
using Artemis.Events;
using Artemis.Models;
+using Artemis.Modules.Effects.ProfilePreview;
using Artemis.Settings;
using Caliburn.Micro;
+using NLog;
+using LogManager = NLog.LogManager;
namespace Artemis.Managers
{
public class EffectManager
{
+ private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
private readonly IEventAggregator _events;
private readonly MainManager _mainManager;
- private bool _clearing;
- private EffectModel _pauseEffect;
private EffectModel _activeEffect;
+ private bool _clearing;
+ public EffectModel PauseEffect { get; set; }
public EffectManager(MainManager mainManager, IEventAggregator events)
{
+ Logger.Info("Intializing EffectManager");
_mainManager = mainManager;
_events = events;
EffectModels = new List();
+ ProfilePreviewModel = new ProfilePreviewModel(_mainManager);
+ Logger.Info("Intialized EffectManager");
}
+ ///
+ /// Used by ViewModels to show a preview of the profile currently being edited
+ ///
+ public ProfilePreviewModel ProfilePreviewModel { get; set; }
+
+ ///
+ /// Holds all the effects the program has
+ ///
public List EffectModels { get; set; }
public EffectModel ActiveEffect
@@ -36,11 +52,17 @@ namespace Artemis.Managers
}
}
+ ///
+ /// Returns all enabled overlays
+ ///
public IEnumerable EnabledOverlays
{
get { return EffectModels.OfType().Where(o => o.Enabled); }
}
+ ///
+ /// Returns all enabled games
+ ///
public IEnumerable EnabledGames
{
get { return EffectModels.OfType().Where(g => g.Enabled); }
@@ -52,13 +74,14 @@ namespace Artemis.Managers
/// Whether enabling was successful or not.
public EffectModel GetLastEffect()
{
+ Logger.Debug("Getting last effect: {0}", General.Default.LastEffect);
if (General.Default.LastEffect == null)
return null;
var effect = EffectModels.FirstOrDefault(e => e.Name == General.Default.LastEffect);
// Fall back to the first effect found, in case settings are messed up
- return effect ?? EffectModels.First();
+ return effect;
}
///
@@ -81,6 +104,7 @@ namespace Artemis.Managers
if (effectModel.Name == ActiveEffect.Name && !force)
return;
+ Logger.Debug("Changing effect to: {0}, force: {1}", effectModel?.Name, force);
// If the main manager is running, pause it and safely change the effect
if (_mainManager.Running)
{
@@ -94,27 +118,40 @@ namespace Artemis.Managers
private void ChangeEffectWithPause(EffectModel effectModel)
{
- if (_pauseEffect != null)
- return;
+ var tryCount = 0;
+ while (PauseEffect != null)
+ {
+ Thread.Sleep(100);
+ tryCount++;
+ if (tryCount > 20)
+ throw new Exception("Couldn't change effect before the time expired");
+ }
- _pauseEffect = effectModel;
+ // Don't interrupt an ongoing effect change
+ if (PauseEffect != null)
+ {
+ Logger.Debug("Change effect with pause cancelled");
+ return;
+ }
+ Logger.Debug("Changing effect with pause: {0}", effectModel?.Name);
+
+ PauseEffect = effectModel;
_mainManager.Pause();
_mainManager.PauseCallback += ChangeEffectPauseCallback;
}
private void ChangeEffectPauseCallback()
{
+ _mainManager.PauseCallback -= ChangeEffectPauseCallback;
+
// Change effect logic
ActiveEffect?.Dispose();
- ActiveEffect = _pauseEffect;
+ ActiveEffect = PauseEffect;
ActiveEffect.Enable();
- // Let the ViewModels know
- //_events.PublishOnUIThread(new ActiveEffectChanged(ActiveEffect.Name));
-
_mainManager.Unpause();
- _pauseEffect = null;
+ PauseEffect = null;
if (ActiveEffect is GameModel)
return;
@@ -122,6 +159,8 @@ namespace Artemis.Managers
// Non-game effects are stored as the new LastEffect.
General.Default.LastEffect = ActiveEffect.Name;
General.Default.Save();
+
+ Logger.Debug("Finishing change effect with pause");
}
///
@@ -133,29 +172,36 @@ namespace Artemis.Managers
return;
// Don't mess with the ActiveEffect if in the process of changing the effect.
- if (_pauseEffect != null)
+ if (PauseEffect != null)
return;
if (ActiveEffect == null)
return;
_clearing = true;
-
+ Logger.Debug("Clearing active effect");
_mainManager.Pause();
_mainManager.PauseCallback += ClearEffectPauseCallback;
}
private void ClearEffectPauseCallback()
{
+ _mainManager.PauseCallback -= ClearEffectPauseCallback;
+ if (PauseEffect != null)
+ {
+ Logger.Debug("Cancelling clearing effect");
+ return;
+ }
+
ActiveEffect.Dispose();
ActiveEffect = null;
General.Default.LastEffect = null;
General.Default.Save();
- //_events.PublishOnUIThread(new ActiveEffectChanged(""));
-
_clearing = false;
+
+ Logger.Debug("Finishing clearing active effect");
_mainManager.Unpause();
}
@@ -165,6 +211,7 @@ namespace Artemis.Managers
///
public void DisableGame(EffectModel activeEffect)
{
+ Logger.Debug("Disabling game: {0}", activeEffect?.Name);
if (GetLastEffect() == null)
ClearEffect();
else
diff --git a/Artemis/Artemis/Managers/KeyboardManager.cs b/Artemis/Artemis/Managers/KeyboardManager.cs
index cc0463332..b298785f2 100644
--- a/Artemis/Artemis/Managers/KeyboardManager.cs
+++ b/Artemis/Artemis/Managers/KeyboardManager.cs
@@ -4,20 +4,25 @@ using Artemis.Events;
using Artemis.KeyboardProviders;
using Artemis.Settings;
using Caliburn.Micro;
+using NLog;
+using LogManager = NLog.LogManager;
namespace Artemis.Managers
{
public class KeyboardManager
{
+ private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
private readonly IEventAggregator _events;
private readonly MainManager _mainManager;
private KeyboardProvider _activeKeyboard;
public KeyboardManager(MainManager mainManager, IEventAggregator events)
{
+ Logger.Info("Intializing KeyboardManager");
_mainManager = mainManager;
_events = events;
KeyboardProviders = ProviderHelper.GetKeyboardProviders();
+ Logger.Info("Intialized KeyboardManager");
}
public List KeyboardProviders { get; set; }
@@ -33,11 +38,14 @@ namespace Artemis.Managers
}
}
+ public bool CanDisable { get; set; }
+
///
/// Enables the last keyboard according to the settings file
///
public void EnableLastKeyboard()
{
+ Logger.Debug("Enabling last keyboard: {0}", General.Default.LastKeyboard);
if (General.Default.LastKeyboard == null)
return;
if (General.Default.LastKeyboard == "")
@@ -53,6 +61,7 @@ namespace Artemis.Managers
///
public void EnableKeyboard(KeyboardProvider keyboardProvider)
{
+ Logger.Debug("Enabling keyboard: {0}", keyboardProvider?.Name);
ReleaseActiveKeyboard();
if (keyboardProvider == null)
@@ -69,22 +78,25 @@ namespace Artemis.Managers
return;
}
+ CanDisable = false;
ActiveKeyboard = keyboardProvider;
- ActiveKeyboard.Enable();
+ keyboardProvider.Enable();
General.Default.LastKeyboard = ActiveKeyboard.Name;
General.Default.Save();
+ CanDisable = true;
}
///
- /// Releases the active keyboard
+ /// Releases the active keyboard, if CanDisable is true
///
public void ReleaseActiveKeyboard()
{
- if (ActiveKeyboard == null)
+ if (ActiveKeyboard == null || !CanDisable)
return;
ActiveKeyboard.Disable();
+ Logger.Debug("Released keyboard: {0}", ActiveKeyboard?.Name);
ActiveKeyboard = null;
}
@@ -94,12 +106,14 @@ namespace Artemis.Managers
///
public void ChangeKeyboard(KeyboardProvider keyboardProvider)
{
+ Logger.Debug("Changing active keyboard");
if (keyboardProvider == ActiveKeyboard)
return;
General.Default.LastKeyboard = keyboardProvider?.Name;
General.Default.Save();
+ Logger.Debug("Restarting for keyboard change");
_mainManager.Restart();
}
}
diff --git a/Artemis/Artemis/Managers/MainManager.cs b/Artemis/Artemis/Managers/MainManager.cs
index 381795d2e..88351ed71 100644
--- a/Artemis/Artemis/Managers/MainManager.cs
+++ b/Artemis/Artemis/Managers/MainManager.cs
@@ -9,6 +9,8 @@ using Artemis.Utilities.GameState;
using Artemis.Utilities.Keyboard;
using Artemis.Utilities.LogitechDll;
using Caliburn.Micro;
+using NLog;
+using LogManager = NLog.LogManager;
namespace Artemis.Managers
{
@@ -16,12 +18,16 @@ namespace Artemis.Managers
{
public delegate void PauseCallbackHandler();
+ private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
+
private readonly int _fps;
private bool _paused;
private bool _restarting;
public MainManager(IEventAggregator events, MetroDialogService dialogService)
{
+ Logger.Info("Intializing MainManager");
+
Events = events;
DialogService = dialogService;
@@ -52,6 +58,8 @@ namespace Artemis.Managers
// Start the named pipe
PipeServer = new PipeServer();
PipeServer.Start("artemis");
+
+ Logger.Info("Intialized MainManager");
}
public PipeServer PipeServer { get; set; }
@@ -80,6 +88,7 @@ namespace Artemis.Managers
/// Whether starting was successful or not
public bool Start(EffectModel effect = null)
{
+ Logger.Debug("Starting MainManager");
// Can't take control when not enabled
if (!ProgramEnabled || UpdateWorker.CancellationPending || UpdateWorker.IsBusy || _paused)
return false;
@@ -109,6 +118,7 @@ namespace Artemis.Managers
///
public void Stop()
{
+ Logger.Debug("Stopping MainManager");
if (!Running || UpdateWorker.CancellationPending || _paused)
return;
@@ -123,6 +133,7 @@ namespace Artemis.Managers
KeyboardManager.ReleaseActiveKeyboard();
Running = false;
+ Logger.Debug("Stopped MainManager");
if (e.Error != null || !_restarting)
return;
@@ -135,6 +146,7 @@ namespace Artemis.Managers
if (!Running || UpdateWorker.CancellationPending || _paused)
return;
+ Logger.Debug("Pausing MainManager");
_paused = true;
}
@@ -143,23 +155,26 @@ namespace Artemis.Managers
if (!_paused)
return;
+ Logger.Debug("Unpausing MainManager");
_paused = false;
- PauseCallback = null;
}
public void Shutdown()
{
+ Logger.Debug("Shutting down MainManager");
Stop();
ProcessWorker.CancelAsync();
ProcessWorker.CancelAsync();
GameStateWebServer.Stop();
- //NamedPipeServer.StopServer();
+ PipeServer.Stop();
}
public void Restart()
{
if (_restarting)
return;
+
+ Logger.Debug("Restarting MainManager");
if (!Running)
{
Start();
@@ -175,6 +190,7 @@ namespace Artemis.Managers
///
public void EnableProgram()
{
+ Logger.Debug("Enabling program");
ProgramEnabled = true;
Start(EffectManager.GetLastEffect());
Events.PublishOnUIThread(new ToggleEnabled(ProgramEnabled));
@@ -185,6 +201,7 @@ namespace Artemis.Managers
///
public void DisableProgram()
{
+ Logger.Debug("Disabling program");
Stop();
ProgramEnabled = false;
Events.PublishOnUIThread(new ToggleEnabled(ProgramEnabled));
@@ -209,7 +226,15 @@ namespace Artemis.Managers
if (KeyboardManager.ActiveKeyboard == null || EffectManager.ActiveEffect == null)
{
Thread.Sleep(1000/_fps);
- Stop();
+ Logger.Debug("No active effect/keyboard, stopping");
+
+ if (EffectManager.PauseEffect != null)
+ {
+ PauseCallback?.Invoke();
+ Thread.Sleep(1000/_fps);
+ }
+ else
+ Stop();
continue;
}
@@ -257,8 +282,11 @@ namespace Artemis.Managers
private void BackgroundWorkerExceptionCatcher(object sender, RunWorkerCompletedEventArgs e)
{
- if (e.Error != null)
- throw e.Error;
+ if (e.Error == null)
+ return;
+
+ Logger.Error(e.Error, "Exception in the BackgroundWorker");
+ throw e.Error;
}
private void ProcessWorker_DoWork(object sender, DoWorkEventArgs e)
@@ -285,7 +313,8 @@ namespace Artemis.Managers
// Look for running games, stopping on the first one that's found.
var newGame = EffectManager.EnabledGames
- .FirstOrDefault(g => runningProcesses.Any(p => p.ProcessName == g.ProcessName && p.HasExited == false));
+ .FirstOrDefault(
+ g => runningProcesses.Any(p => p.ProcessName == g.ProcessName && p.HasExited == false));
// If it's not already enabled, do so.
if (newGame != null && EffectManager.ActiveEffect != newGame)
diff --git a/Artemis/Artemis/Models/GameModel.cs b/Artemis/Artemis/Models/GameModel.cs
index 8500747fc..5e4fcebd8 100644
--- a/Artemis/Artemis/Models/GameModel.cs
+++ b/Artemis/Artemis/Models/GameModel.cs
@@ -1,18 +1,21 @@
using Artemis.Managers;
using Artemis.Models.Interfaces;
using Artemis.Models.Profiles;
+using Artemis.Modules.Games.Witcher3;
namespace Artemis.Models
{
public abstract class GameModel : EffectModel
{
+ public GameSettings Settings { get; set; }
public bool Enabled { get; set; }
public string ProcessName { get; set; }
public IGameDataModel GameDataModel { get; set; }
public ProfileModel Profile { get; set; }
- protected GameModel(MainManager mainManager) : base(mainManager)
+ protected GameModel(MainManager mainManager, GameSettings settings) : base(mainManager)
{
+ Settings = settings;
}
}
}
\ No newline at end of file
diff --git a/Artemis/Artemis/Models/Profiles/LayerModel.cs b/Artemis/Artemis/Models/Profiles/LayerModel.cs
index 23dc597b9..bea0e4f51 100644
--- a/Artemis/Artemis/Models/Profiles/LayerModel.cs
+++ b/Artemis/Artemis/Models/Profiles/LayerModel.cs
@@ -64,10 +64,12 @@ namespace Artemis.Models.Profiles
_mustDraw = false;
}
- public void Draw(IGameDataModel dataModel, DrawingContext c)
+ public void Draw(IGameDataModel dataModel, DrawingContext c, bool preview = false)
{
- if (!ConditionsMet(dataModel))
- return;
+ // Conditions aren't checked during a preview because there is no game data to base them on
+ if (!preview)
+ if (!ConditionsMet(dataModel))
+ return;
if (LayerType == LayerType.Folder)
foreach (var layerModel in Children.OrderByDescending(l => l.Order))
@@ -82,7 +84,7 @@ namespace Artemis.Models.Profiles
_drawer.UpdateHeadset();
}
- public void Update(IGameDataModel dataModel)
+ public void Update(IGameDataModel dataModel, bool preview = false)
{
if (LayerType == LayerType.Folder)
{
@@ -92,6 +94,10 @@ namespace Artemis.Models.Profiles
}
GeneralHelpers.CopyProperties(CalcProps, UserProps);
+
+ // Dynamic properties aren't applied during preview because there is no game data to base them on
+ if (preview)
+ return;
foreach (var dynamicProperty in LayerProperties)
dynamicProperty.ApplyProperty(dataModel, UserProps, CalcProps);
}
diff --git a/Artemis/Artemis/Models/Profiles/ProfileModel.cs b/Artemis/Artemis/Models/Profiles/ProfileModel.cs
index 546dd1c37..27edc4e12 100644
--- a/Artemis/Artemis/Models/Profiles/ProfileModel.cs
+++ b/Artemis/Artemis/Models/Profiles/ProfileModel.cs
@@ -106,7 +106,7 @@ namespace Artemis.Models.Profiles
Layers[i].Order = i;
}
- public Bitmap GenerateBitmap(Rect keyboardRect, IGameDataModel gameDataModel)
+ public Bitmap GenerateBitmap(Rect keyboardRect, IGameDataModel gameDataModel, bool preview = false)
{
Bitmap bitmap = null;
DrawingVisual.Dispatcher.Invoke(delegate
@@ -120,7 +120,7 @@ namespace Artemis.Models.Profiles
// Draw the layers
foreach (var layerModel in Layers.OrderByDescending(l => l.Order))
- layerModel.Draw(gameDataModel, c);
+ layerModel.Draw(gameDataModel, c, preview);
// Remove the clip
c.Pop();
diff --git a/Artemis/Artemis/Modules/Effects/Debug/DebugEffectModel.cs b/Artemis/Artemis/Modules/Effects/Debug/DebugEffectModel.cs
index 034f96077..d8e6fc79f 100644
--- a/Artemis/Artemis/Modules/Effects/Debug/DebugEffectModel.cs
+++ b/Artemis/Artemis/Modules/Effects/Debug/DebugEffectModel.cs
@@ -7,6 +7,7 @@ using Artemis.Utilities.Keyboard;
namespace Artemis.Modules.Effects.Debug
{
+ // TODO: Remove
internal class DebugEffectModel : EffectModel
{
public DebugEffectModel(MainManager mainManager, DebugEffectSettings settings) : base(mainManager)
diff --git a/Artemis/Artemis/Modules/Effects/ProfilePreview/ProfilePreviewModel.cs b/Artemis/Artemis/Modules/Effects/ProfilePreview/ProfilePreviewModel.cs
new file mode 100644
index 000000000..ece8fae49
--- /dev/null
+++ b/Artemis/Artemis/Modules/Effects/ProfilePreview/ProfilePreviewModel.cs
@@ -0,0 +1,62 @@
+using System.Drawing;
+using Artemis.Managers;
+using Artemis.Models;
+using Artemis.Models.Interfaces;
+using Artemis.Models.Profiles;
+
+namespace Artemis.Modules.Effects.ProfilePreview
+{
+ public class ProfilePreviewModel : EffectModel
+ {
+ private readonly ProfilePreviewDataModel _previewDataModel;
+
+ public ProfilePreviewModel(MainManager mainManager) : base(mainManager)
+ {
+ Name = "Profile Preview";
+ _previewDataModel = new ProfilePreviewDataModel();
+ }
+
+ public ProfileModel SelectedProfile { get; set; }
+
+ public override void Dispose()
+ {
+ Initialized = false;
+ SelectedProfile = null;
+ }
+
+ public override void Enable()
+ {
+ Initialized = true;
+ }
+
+ public override void Update()
+ {
+ if (SelectedProfile == null)
+ return;
+
+ foreach (var layerModel in SelectedProfile.Layers)
+ layerModel.Update(_previewDataModel, true);
+ }
+
+ public override Bitmap GenerateBitmap()
+ {
+ var bitmap = MainManager.KeyboardManager.ActiveKeyboard.KeyboardBitmap(4);
+
+ if (SelectedProfile == null)
+ return bitmap;
+
+ var keyboardRect = MainManager.KeyboardManager.ActiveKeyboard.KeyboardRectangle(4);
+ var image = SelectedProfile.GenerateBitmap(keyboardRect, _previewDataModel, true);
+
+ // Draw on top of everything else
+ using (var g = Graphics.FromImage(bitmap))
+ g.DrawImage(image, 0, 0);
+
+ return bitmap;
+ }
+ }
+
+ public class ProfilePreviewDataModel : IGameDataModel
+ {
+ }
+}
\ No newline at end of file
diff --git a/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeModel.cs b/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeModel.cs
index 4bf2f6d78..304b71e5e 100644
--- a/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeModel.cs
+++ b/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeModel.cs
@@ -9,9 +9,8 @@ namespace Artemis.Modules.Games.CounterStrike
{
public class CounterStrikeModel : GameModel
{
- public CounterStrikeModel(MainManager mainManager, CounterStrikeSettings settings) : base(mainManager)
+ public CounterStrikeModel(MainManager mainManager, CounterStrikeSettings settings) : base(mainManager, settings)
{
- Settings = settings;
Name = "CounterStrike";
ProcessName = "csgo";
Scale = 4;
@@ -19,8 +18,6 @@ namespace Artemis.Modules.Games.CounterStrike
Initialized = false;
}
- public CounterStrikeSettings Settings { get; set; }
-
public int Scale { get; set; }
public override void Dispose()
diff --git a/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeViewModel.cs b/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeViewModel.cs
index 982bb1136..5d9188c1e 100644
--- a/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeViewModel.cs
+++ b/Artemis/Artemis/Modules/Games/CounterStrike/CounterStrikeViewModel.cs
@@ -8,33 +8,15 @@ using Artemis.ViewModels.Abstract;
namespace Artemis.Modules.Games.CounterStrike
{
- public class CounterStrikeViewModel : GameViewModel
+ public class CounterStrikeViewModel : GameViewModel
{
- public CounterStrikeViewModel(MainManager mainManager)
+ public CounterStrikeViewModel(MainManager mainManager) : base(mainManager, new CounterStrikeModel(mainManager, new CounterStrikeSettings()))
{
- MainManager = mainManager;
-
- // Settings are loaded from file by class
- GameSettings = new CounterStrikeSettings();
-
// Create effect model and add it to MainManager
- GameModel = new CounterStrikeModel(mainManager, (CounterStrikeSettings) GameSettings);
MainManager.EffectManager.EffectModels.Add(GameModel);
PlaceConfigFile();
-
- ProfileEditor = new ProfileEditorViewModel(MainManager, GameModel);
- ProfileEditor.PropertyChanged += ProfileUpdater;
- GameModel.Profile = ProfileEditor.SelectedProfile;
}
- private void ProfileUpdater(object sender, PropertyChangedEventArgs e)
- {
- if (e.PropertyName == "SelectedProfile")
- GameModel.Profile = ProfileEditor.SelectedProfile;
- }
-
- public ProfileEditorViewModel ProfileEditor { get; set; }
-
public static string Name => "CS:GO";
public string Content => "Counter-Strike: GO Content";
diff --git a/Artemis/Artemis/Modules/Games/Dota2/Dota2DataModel.cs b/Artemis/Artemis/Modules/Games/Dota2/Dota2DataModel.cs
index 39bacb414..28299d535 100644
--- a/Artemis/Artemis/Modules/Games/Dota2/Dota2DataModel.cs
+++ b/Artemis/Artemis/Modules/Games/Dota2/Dota2DataModel.cs
@@ -1,6 +1,6 @@
namespace Artemis.Modules.Games.Dota2
{
- class Dota2DataModel
+ public class Dota2DataModel
{
public class Rootobject
{
diff --git a/Artemis/Artemis/Modules/Games/Dota2/Dota2Model.cs b/Artemis/Artemis/Modules/Games/Dota2/Dota2Model.cs
index fb7d07885..bd99b08c2 100644
--- a/Artemis/Artemis/Modules/Games/Dota2/Dota2Model.cs
+++ b/Artemis/Artemis/Modules/Games/Dota2/Dota2Model.cs
@@ -3,8 +3,6 @@ using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
-using System.Windows.Forms.VisualStyles;
-using System.Windows.Media;
using Artemis.KeyboardProviders;
using Artemis.Managers;
using Artemis.Models;
@@ -12,26 +10,26 @@ using Artemis.Utilities;
using Artemis.Utilities.GameState;
using Artemis.Utilities.Keyboard;
using Newtonsoft.Json;
-using Color = System.Drawing.Color;
namespace Artemis.Modules.Games.Dota2
{
internal class Dota2Model : GameModel
{
- private KeyboardRegion _keyPad;
private KeyboardRegion _abilityKeys;
+ private KeyboardRegion _keyPad;
private KeyboardRegion _topRow;
- public Dota2Model(MainManager mainManager, Dota2Settings settings) : base(mainManager)
+ public Dota2Model(MainManager mainManager, Dota2Settings settings) : base(mainManager, settings)
{
- Settings = settings;
Name = "Dota2";
ProcessName = "dota2";
+ Settings = settings;
Enabled = Settings.Enabled;
Initialized = false;
Scale = 4;
}
+ public new Dota2Settings Settings { get; set; }
public override void Dispose()
{
@@ -72,7 +70,7 @@ namespace Artemis.Modules.Games.Dota2
DayCycleRectangle = new KeyboardRectangle(MainManager.KeyboardManager.ActiveKeyboard
, _keyPad.TopLeft.X*Scale
- , _keyPad.TopLeft.Y* Scale
+ , _keyPad.TopLeft.Y*Scale
, new List()
, LinearGradientMode.Horizontal)
{
@@ -89,19 +87,20 @@ namespace Artemis.Modules.Games.Dota2
private void SetAbilityKeys()
{
#region Long Switch Statement for Keys
+
switch (Settings.KeyboardLayout)
{
case "0":
case "Default": //default
case "4": //Heroes of newearth
case "3": //League of Legends
- for (int i = 0; i < AbilityKeysRectangles.Length; i++)
+ for (var i = 0; i < AbilityKeysRectangles.Length; i++)
{
AbilityKeysRectangles[i] = new KeyboardRectangle(MainManager.KeyboardManager.ActiveKeyboard,
- (_abilityKeys.TopLeft.X + i) * Scale - 2,
- _abilityKeys.TopLeft.Y * Scale,
- new List(),
- LinearGradientMode.Horizontal)
+ (_abilityKeys.TopLeft.X + i)*Scale - 2,
+ _abilityKeys.TopLeft.Y*Scale,
+ new List(),
+ LinearGradientMode.Horizontal)
{
Height = Scale,
Width = Scale
@@ -110,37 +109,37 @@ namespace Artemis.Modules.Games.Dota2
break;
case "2":
AbilityKeysRectangles[0] = new KeyboardRectangle(MainManager.KeyboardManager.ActiveKeyboard,
- (_abilityKeys.TopLeft.X * Scale) - 2,
- _abilityKeys.TopLeft.Y * Scale,
- new List(),
- LinearGradientMode.Horizontal)
+ _abilityKeys.TopLeft.X*Scale - 2,
+ _abilityKeys.TopLeft.Y*Scale,
+ new List(),
+ LinearGradientMode.Horizontal)
{
Height = Scale,
Width = Scale
};
AbilityKeysRectangles[1] = new KeyboardRectangle(MainManager.KeyboardManager.ActiveKeyboard,
- ((_abilityKeys.TopLeft.X + 2) * Scale) - 2,
- _abilityKeys.TopLeft.Y * Scale,
- new List(),
- LinearGradientMode.Horizontal)
+ (_abilityKeys.TopLeft.X + 2)*Scale - 2,
+ _abilityKeys.TopLeft.Y*Scale,
+ new List(),
+ LinearGradientMode.Horizontal)
{
Height = Scale,
Width = Scale
};
AbilityKeysRectangles[2] = new KeyboardRectangle(MainManager.KeyboardManager.ActiveKeyboard,
- ((_abilityKeys.TopLeft.X +3) * Scale) - 2,
- _abilityKeys.TopLeft.Y * Scale,
- new List(),
- LinearGradientMode.Horizontal)
+ (_abilityKeys.TopLeft.X + 3)*Scale - 2,
+ _abilityKeys.TopLeft.Y*Scale,
+ new List(),
+ LinearGradientMode.Horizontal)
{
Height = Scale,
Width = Scale
};
AbilityKeysRectangles[3] = new KeyboardRectangle(MainManager.KeyboardManager.ActiveKeyboard,
- ((_abilityKeys.TopLeft.X +3)* Scale) - 2,
- (_abilityKeys.TopLeft.Y +1)* Scale,
- new List(),
- LinearGradientMode.Horizontal)
+ (_abilityKeys.TopLeft.X + 3)*Scale - 2,
+ (_abilityKeys.TopLeft.Y + 1)*Scale,
+ new List(),
+ LinearGradientMode.Horizontal)
{
Height = Scale,
Width = Scale
@@ -148,22 +147,22 @@ namespace Artemis.Modules.Games.Dota2
break;
case "1": //MMO
case "5": //Smite
- for (int i = 0; i < AbilityKeysRectangles.Length; i++)
+ for (var i = 0; i < AbilityKeysRectangles.Length; i++)
{
AbilityKeysRectangles[i] = new KeyboardRectangle(MainManager.KeyboardManager.ActiveKeyboard,
- (_abilityKeys.TopLeft.X + i) * Scale - 3,
- (_abilityKeys.TopLeft.Y-1) * Scale,
- new List(),
- LinearGradientMode.Horizontal)
+ (_abilityKeys.TopLeft.X + i)*Scale - 3,
+ (_abilityKeys.TopLeft.Y - 1)*Scale,
+ new List(),
+ LinearGradientMode.Horizontal)
{
Height = Scale,
Width = Scale
};
}
break;
-
}
- #endregion
+
+ #endregion
}
public override void Update()
@@ -184,7 +183,6 @@ namespace Artemis.Modules.Games.Dota2
UpdateHealth();
if (Settings.ShowMana)
UpdateMana();
-
}
private void UpdateMainColor()
@@ -202,18 +200,18 @@ namespace Artemis.Modules.Games.Dota2
{
List list = null;
if (!D2Json.hero.alive)
- list = new List { Color.LightGray };
+ list = new List {Color.LightGray};
else if (D2Json.hero.disarmed)
- list = new List { Color.Yellow };
+ list = new List {Color.Yellow};
else if (D2Json.hero.hexed)
- list = new List { Color.Yellow };
+ list = new List {Color.Yellow};
else if (D2Json.hero.silenced)
- list = new List { Color.Yellow };
+ list = new List {Color.Yellow};
else if (D2Json.hero.stunned)
- list = new List { Color.Yellow };
+ list = new List {Color.Yellow};
else if (D2Json.hero.magicimmune)
- list = new List { Color.Lime };
- if(list == null)
+ list = new List {Color.Lime};
+ if (list == null)
return;
EventRectangle.Colors = list;
@@ -257,15 +255,23 @@ namespace Artemis.Modules.Games.Dota2
{
if (AbilityKeysRectangles == null)
return;
-
- AbilityKeysRectangles[0].Colors = D2Json?.abilities?.ability0?.can_cast == true ? new List
- { ColorHelpers.ToDrawingColor(Settings.AbilityReadyColor) } : new List { ColorHelpers.ToDrawingColor(Settings.AbilityCooldownColor) };
- AbilityKeysRectangles[1].Colors = D2Json?.abilities?.ability1?.can_cast == true ? new List
- { ColorHelpers.ToDrawingColor(Settings.AbilityReadyColor) } : new List { ColorHelpers.ToDrawingColor(Settings.AbilityCooldownColor) };
- AbilityKeysRectangles[2].Colors = D2Json?.abilities?.ability2?.can_cast == true ? new List
- { ColorHelpers.ToDrawingColor(Settings.AbilityReadyColor) } : new List { ColorHelpers.ToDrawingColor(Settings.AbilityCooldownColor) };
- AbilityKeysRectangles[3].Colors = D2Json?.abilities?.ability3?.can_cast == true ? new List
- { ColorHelpers.ToDrawingColor(Settings.AbilityReadyColor) } : new List { ColorHelpers.ToDrawingColor(Settings.AbilityCooldownColor) };
+
+ AbilityKeysRectangles[0].Colors = D2Json?.abilities?.ability0?.can_cast == true
+ ? new List
+ {ColorHelpers.ToDrawingColor(Settings.AbilityReadyColor)}
+ : new List {ColorHelpers.ToDrawingColor(Settings.AbilityCooldownColor)};
+ AbilityKeysRectangles[1].Colors = D2Json?.abilities?.ability1?.can_cast == true
+ ? new List
+ {ColorHelpers.ToDrawingColor(Settings.AbilityReadyColor)}
+ : new List {ColorHelpers.ToDrawingColor(Settings.AbilityCooldownColor)};
+ AbilityKeysRectangles[2].Colors = D2Json?.abilities?.ability2?.can_cast == true
+ ? new List
+ {ColorHelpers.ToDrawingColor(Settings.AbilityReadyColor)}
+ : new List {ColorHelpers.ToDrawingColor(Settings.AbilityCooldownColor)};
+ AbilityKeysRectangles[3].Colors = D2Json?.abilities?.ability3?.can_cast == true
+ ? new List
+ {ColorHelpers.ToDrawingColor(Settings.AbilityReadyColor)}
+ : new List {ColorHelpers.ToDrawingColor(Settings.AbilityCooldownColor)};
}
@@ -301,7 +307,6 @@ namespace Artemis.Modules.Games.Dota2
item.Draw(g);
}
DayCycleRectangle.Draw(g);
-
}
return bitmap;
}
@@ -321,7 +326,6 @@ namespace Artemis.Modules.Games.Dota2
#region Variables
- public Dota2Settings Settings { get; set; }
public Dota2DataModel.Rootobject D2Json { get; set; }
public int Scale { get; set; }
public KeyboardRectangle HealthRectangle { get; set; }
@@ -329,7 +333,7 @@ namespace Artemis.Modules.Games.Dota2
public KeyboardRectangle DayCycleRectangle { get; set; }
public KeyboardRectangle ManaRectangle { get; set; }
public KeyboardRectangle[] AbilityKeysRectangles = new KeyboardRectangle[4];
- #endregion
+ #endregion
}
}
\ No newline at end of file
diff --git a/Artemis/Artemis/Modules/Games/Dota2/Dota2ViewModel.cs b/Artemis/Artemis/Modules/Games/Dota2/Dota2ViewModel.cs
index 452be09c7..b7885c311 100644
--- a/Artemis/Artemis/Modules/Games/Dota2/Dota2ViewModel.cs
+++ b/Artemis/Artemis/Modules/Games/Dota2/Dota2ViewModel.cs
@@ -1,46 +1,41 @@
-using System;
-using System.IO;
+using System.IO;
using System.Windows.Forms;
using Artemis.Managers;
-using Artemis.Models;
using Artemis.Properties;
using Artemis.ViewModels.Abstract;
using Caliburn.Micro;
namespace Artemis.Modules.Games.Dota2
{
- public class Dota2ViewModel : GameViewModel
+ public class Dota2ViewModel : GameViewModel
{
- public Dota2ViewModel(MainManager mainManager)
+ public Dota2ViewModel(MainManager mainManager) : base(mainManager, new Dota2Model(mainManager, new Dota2Settings()))
{
-
- MainManager = mainManager;
- GameSettings = new Dota2Settings();
-
- GameModel = new Dota2Model(mainManager, (Dota2Settings) GameSettings);
MainManager.EffectManager.EffectModels.Add(GameModel);
PlaceConfigFile();
}
- public BindableCollection KeyboardLayouts
+ public BindableCollection KeyboardLayouts => new BindableCollection(new[]
{
- get
- {
- return new BindableCollection(new[] {"Default","MMO","WASD","League of Legends","Heros of Newearth","Smite"});
- }
- }
+ "Default",
+ "MMO",
+ "WASD",
+ "League of Legends",
+ "Heros of Newearth",
+ "Smite"
+ });
public static string Name => "Dota 2";
public string Content => "Dota 2 Content";
public void BrowseDirectory()
{
- var dialog = new FolderBrowserDialog { SelectedPath = ((Dota2Settings)GameSettings).GameDirectory };
+ var dialog = new FolderBrowserDialog {SelectedPath = ((Dota2Settings) GameSettings).GameDirectory};
var result = dialog.ShowDialog();
if (result != DialogResult.OK)
return;
- ((Dota2Settings)GameSettings).GameDirectory = dialog.SelectedPath;
+ ((Dota2Settings) GameSettings).GameDirectory = dialog.SelectedPath;
NotifyOfPropertyChange(() => GameSettings);
GameSettings.Save();
@@ -49,33 +44,36 @@ namespace Artemis.Modules.Games.Dota2
public void PlaceConfigFile()
{
- if (((Dota2Settings)GameSettings).GameDirectory == string.Empty)
+ if (((Dota2Settings) GameSettings).GameDirectory == string.Empty)
return;
- if (Directory.Exists(((Dota2Settings)GameSettings).GameDirectory + "/game/dota/cfg"))
+ if (Directory.Exists(((Dota2Settings) GameSettings).GameDirectory + "/game/dota/cfg"))
{
var cfgFile = Resources.dotaGamestateConfiguration.Replace("{{port}}",
MainManager.GameStateWebServer.Port.ToString());
try
{
File.WriteAllText(
- ((Dota2Settings)GameSettings).GameDirectory + "/game/dota/cfg/gamestate_integration/gamestate_integration_artemis.cfg",
- cfgFile);
+ ((Dota2Settings) GameSettings).GameDirectory +
+ "/game/dota/cfg/gamestate_integration/gamestate_integration_artemis.cfg",
+ cfgFile);
}
catch (DirectoryNotFoundException)
{
- Directory.CreateDirectory(((Dota2Settings) GameSettings).GameDirectory + "/game/dota/cfg/gamestate_integration/");
+ Directory.CreateDirectory(((Dota2Settings) GameSettings).GameDirectory +
+ "/game/dota/cfg/gamestate_integration/");
File.WriteAllText(
- ((Dota2Settings)GameSettings).GameDirectory + "/game/dota/cfg/gamestate_integration/gamestate_integration_artemis.cfg",
- cfgFile);
+ ((Dota2Settings) GameSettings).GameDirectory +
+ "/game/dota/cfg/gamestate_integration/gamestate_integration_artemis.cfg",
+ cfgFile);
}
-
+
return;
}
MainManager.DialogService.ShowErrorMessageBox("Please select a valid Dota 2 directory\n\n" +
@"By default Dota 2 is in \SteamApps\common\dota 2 beta");
- ((Dota2Settings)GameSettings).GameDirectory = string.Empty;
+ ((Dota2Settings) GameSettings).GameDirectory = string.Empty;
NotifyOfPropertyChange(() => GameSettings);
GameSettings.Save();
diff --git a/Artemis/Artemis/Modules/Games/RocketLeague/RocketLeagueModel.cs b/Artemis/Artemis/Modules/Games/RocketLeague/RocketLeagueModel.cs
index 089552d02..fdccbda9a 100644
--- a/Artemis/Artemis/Modules/Games/RocketLeague/RocketLeagueModel.cs
+++ b/Artemis/Artemis/Modules/Games/RocketLeague/RocketLeagueModel.cs
@@ -15,9 +15,8 @@ namespace Artemis.Modules.Games.RocketLeague
private Memory _memory;
private GamePointersCollection _pointer;
- public RocketLeagueModel(MainManager mainManager, RocketLeagueSettings settings) : base(mainManager)
+ public RocketLeagueModel(MainManager mainManager, RocketLeagueSettings settings) : base(mainManager, settings)
{
- Settings = settings;
Name = "RocketLeague";
ProcessName = "RocketLeague";
Scale = 4;
@@ -25,8 +24,6 @@ namespace Artemis.Modules.Games.RocketLeague
Initialized = false;
}
- public RocketLeagueSettings Settings { get; set; }
-
public int Scale { get; set; }
public override void Dispose()
diff --git a/Artemis/Artemis/Modules/Games/RocketLeague/RocketLeagueViewModel.cs b/Artemis/Artemis/Modules/Games/RocketLeague/RocketLeagueViewModel.cs
index d91f9a4d3..8332abfc7 100644
--- a/Artemis/Artemis/Modules/Games/RocketLeague/RocketLeagueViewModel.cs
+++ b/Artemis/Artemis/Modules/Games/RocketLeague/RocketLeagueViewModel.cs
@@ -1,37 +1,22 @@
-using System.ComponentModel;
-using Artemis.Managers;
+using Artemis.Managers;
using Artemis.Settings;
using Artemis.Utilities;
using Artemis.Utilities.Memory;
-using Artemis.ViewModels;
using Artemis.ViewModels.Abstract;
using Newtonsoft.Json;
namespace Artemis.Modules.Games.RocketLeague
{
- public class RocketLeagueViewModel : GameViewModel
+ public class RocketLeagueViewModel : GameViewModel
{
private string _versionText;
- public RocketLeagueViewModel(MainManager mainManager)
+ public RocketLeagueViewModel(MainManager mainManager) : base(mainManager, new RocketLeagueModel(mainManager, new RocketLeagueSettings()))
{
- MainManager = mainManager;
-
- // Settings are loaded from file by class
- GameSettings = new RocketLeagueSettings();
-
- // Create effect model and add it to MainManager
- GameModel = new RocketLeagueModel(mainManager, (RocketLeagueSettings) GameSettings);
MainManager.EffectManager.EffectModels.Add(GameModel);
SetVersionText();
-
- ProfileEditor = new ProfileEditorViewModel(MainManager, GameModel);
- ProfileEditor.PropertyChanged += ProfileUpdater;
- GameModel.Profile = ProfileEditor.SelectedProfile;
}
- public ProfileEditorViewModel ProfileEditor { get; set; }
-
public static string Name => "Rocket League";
public string VersionText
@@ -47,12 +32,6 @@ namespace Artemis.Modules.Games.RocketLeague
public RocketLeagueModel RocketLeagueModel { get; set; }
- private void ProfileUpdater(object sender, PropertyChangedEventArgs e)
- {
- if (e.PropertyName == "SelectedProfile")
- GameModel.Profile = ProfileEditor.SelectedProfile;
- }
-
private void SetVersionText()
{
if (!General.Default.EnablePointersUpdate)
diff --git a/Artemis/Artemis/Modules/Games/TheDivision/TheDivisionModel.cs b/Artemis/Artemis/Modules/Games/TheDivision/TheDivisionModel.cs
index 906ab4980..5b39771fd 100644
--- a/Artemis/Artemis/Modules/Games/TheDivision/TheDivisionModel.cs
+++ b/Artemis/Artemis/Modules/Games/TheDivision/TheDivisionModel.cs
@@ -22,9 +22,8 @@ namespace Artemis.Modules.Games.TheDivision
private StickyValue _stickyHp;
private int _trans;
- public TheDivisionModel(MainManager mainManager, TheDivisionSettings settings) : base(mainManager)
+ public TheDivisionModel(MainManager mainManager, TheDivisionSettings settings) : base(mainManager, settings)
{
- Settings = settings;
Name = "TheDivision";
ProcessName = "TheDivision";
Scale = 4;
@@ -32,8 +31,6 @@ namespace Artemis.Modules.Games.TheDivision
Initialized = false;
}
- public TheDivisionSettings Settings { get; set; }
-
public int Scale { get; set; }
public override void Dispose()
diff --git a/Artemis/Artemis/Modules/Games/TheDivision/TheDivisionViewModel.cs b/Artemis/Artemis/Modules/Games/TheDivision/TheDivisionViewModel.cs
index 6038755bd..bfeecf47d 100644
--- a/Artemis/Artemis/Modules/Games/TheDivision/TheDivisionViewModel.cs
+++ b/Artemis/Artemis/Modules/Games/TheDivision/TheDivisionViewModel.cs
@@ -4,24 +4,13 @@ using Artemis.ViewModels.Abstract;
namespace Artemis.Modules.Games.TheDivision
{
- public class TheDivisionViewModel : GameViewModel
+ public class TheDivisionViewModel : GameViewModel
{
- public TheDivisionViewModel(MainManager mainManager)
+ public TheDivisionViewModel(MainManager mainManager) : base(mainManager, new TheDivisionModel(mainManager, new TheDivisionSettings()))
{
- MainManager = mainManager;
-
- // Settings are loaded from file by class
- GameSettings = new TheDivisionSettings();
-
- // Create effect model and add it to MainManager
- GameModel = new TheDivisionModel(mainManager, (TheDivisionSettings) GameSettings);
MainManager.EffectManager.EffectModels.Add(GameModel);
-
- ProfileEditor = new ProfileEditorViewModel(MainManager, GameModel);
}
- public ProfileEditorViewModel ProfileEditor { get; set; }
-
public static string Name => "The Division";
}
}
\ No newline at end of file
diff --git a/Artemis/Artemis/Modules/Games/Witcher3/Witcher3Model.cs b/Artemis/Artemis/Modules/Games/Witcher3/Witcher3Model.cs
index 07fd28af4..693429d74 100644
--- a/Artemis/Artemis/Modules/Games/Witcher3/Witcher3Model.cs
+++ b/Artemis/Artemis/Modules/Games/Witcher3/Witcher3Model.cs
@@ -18,9 +18,8 @@ namespace Artemis.Modules.Games.Witcher3
private KeyboardRectangle _signRect;
private string _witcherSettings;
- public Witcher3Model(MainManager mainManager, Witcher3Settings settings) : base(mainManager)
+ public Witcher3Model(MainManager mainManager, Witcher3Settings settings) : base(mainManager, settings)
{
- Settings = settings;
Name = "Witcher3";
ProcessName = "witcher3";
Scale = 4;
@@ -31,8 +30,6 @@ namespace Artemis.Modules.Games.Witcher3
_signRegex = new Regex("ActiveSign=(.*)", RegexOptions.Compiled);
}
- public Witcher3Settings Settings { get; set; }
-
public int Scale { get; set; }
public override void Dispose()
diff --git a/Artemis/Artemis/Modules/Games/Witcher3/Witcher3ViewModel.cs b/Artemis/Artemis/Modules/Games/Witcher3/Witcher3ViewModel.cs
index 8fcbc1405..0384fd04f 100644
--- a/Artemis/Artemis/Modules/Games/Witcher3/Witcher3ViewModel.cs
+++ b/Artemis/Artemis/Modules/Games/Witcher3/Witcher3ViewModel.cs
@@ -4,14 +4,15 @@ using System.IO;
using System.Linq;
using System.Windows.Forms;
using Artemis.Managers;
+using Artemis.Models.Interfaces;
using Artemis.Properties;
using Artemis.ViewModels.Abstract;
namespace Artemis.Modules.Games.Witcher3
{
- public class Witcher3ViewModel : GameViewModel
+ public class Witcher3ViewModel : GameViewModel
{
- public Witcher3ViewModel(MainManager mainManager)
+ public Witcher3ViewModel(MainManager mainManager) : base(mainManager, new Witcher3Model(mainManager, new Witcher3Settings()))
{
MainManager = mainManager;
@@ -109,4 +110,8 @@ namespace Artemis.Modules.Games.Witcher3
MainManager.DialogService.ShowMessageBox("Success", "The mod was successfully installed!");
}
}
+
+ public class Witcher3DataModel : IGameDataModel
+ {
+ }
}
\ No newline at end of file
diff --git a/Artemis/Artemis/NLog.config b/Artemis/Artemis/NLog.config
new file mode 100644
index 000000000..d32c52835
--- /dev/null
+++ b/Artemis/Artemis/NLog.config
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Artemis/Artemis/NLog.xsd b/Artemis/Artemis/NLog.xsd
new file mode 100644
index 000000000..dc821bc0d
--- /dev/null
+++ b/Artemis/Artemis/NLog.xsd
@@ -0,0 +1,2601 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Watch config file for changes and reload automatically.
+
+
+
+
+ Print internal NLog messages to the console. Default value is: false
+
+
+
+
+ Print internal NLog messages to the console error output. Default value is: false
+
+
+
+
+ Write internal NLog messages to the specified file.
+
+
+
+
+ Log level threshold for internal log messages. Default value is: Info.
+
+
+
+
+ Global log level threshold for application log messages. Messages below this level won't be logged..
+
+
+
+
+ Pass NLog internal exceptions to the application. Default value is: false.
+
+
+
+
+ Write internal NLog messages to the the System.Diagnostics.Trace. Default value is: false
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Make all targets within this section asynchronous (creates additional threads but the calling thread isn't blocked by any target writes).
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Prefix for targets/layout renderers/filters/conditions loaded from this assembly.
+
+
+
+
+ Load NLog extensions from the specified file (*.dll)
+
+
+
+
+ Load NLog extensions from the specified assembly. Assembly name should be fully qualified.
+
+
+
+
+
+
+
+
+
+ Name of the logger. May include '*' character which acts like a wildcard. Allowed forms are: *, Name, *Name, Name* and *Name*
+
+
+
+
+ Comma separated list of levels that this rule matches.
+
+
+
+
+ Minimum level that this rule matches.
+
+
+
+
+ Maximum level that this rule matches.
+
+
+
+
+ Level that this rule matches.
+
+
+
+
+ Comma separated list of target names.
+
+
+
+
+ Ignore further rules if this one matches.
+
+
+
+
+ Enable or disable logging rule. Disabled rules are ignored.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the file to be included. The name is relative to the name of the current config file.
+
+
+
+
+ Ignore any errors in the include file.
+
+
+
+
+
+
+ Variable name.
+
+
+
+
+ Variable value.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Layout used to format log messages.
+
+
+
+
+ Indicates whether to add <!-- --> comments around all written texts.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Number of log events that should be processed in a batch by the lazy writer thread.
+
+
+
+
+ Action to be taken when the lazy writer thread request queue count exceeds the set limit.
+
+
+
+
+ Limit on the number of requests in the lazy writer thread request queue.
+
+
+
+
+ Time in milliseconds to sleep between batches.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Number of log events to be buffered.
+
+
+
+
+ Timeout (in milliseconds) after which the contents of buffer will be flushed if there's no write in the specified period of time. Use -1 to disable timed flushes.
+
+
+
+
+ Indicates whether to use sliding timeout.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Encoding to be used.
+
+
+
+
+ Instance of that is used to format log messages.
+
+
+
+
+ Maximum message size in bytes.
+
+
+
+
+ Indicates whether to append newline at the end of log message.
+
+
+
+
+ Action that should be taken if the will be more connections than .
+
+
+
+
+ Action that should be taken if the message is larger than maxMessageSize.
+
+
+
+
+ Indicates whether to keep connection open whenever possible.
+
+
+
+
+ Size of the connection cache (number of connections which are kept alive).
+
+
+
+
+ Maximum current connections. 0 = no maximum.
+
+
+
+
+ Network address.
+
+
+
+
+ Maximum queue size.
+
+
+
+
+ Indicates whether to include source info (file name and line number) in the information sent over the network.
+
+
+
+
+ NDC item separator.
+
+
+
+
+ Indicates whether to include stack contents.
+
+
+
+
+ Indicates whether to include call site (class and method name) in the information sent over the network.
+
+
+
+
+ AppInfo field. By default it's the friendly name of the current AppDomain.
+
+
+
+
+ Indicates whether to include NLog-specific extensions to log4j schema.
+
+
+
+
+ Indicates whether to include dictionary contents.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Layout that should be use to calcuate the value for the parameter.
+
+
+
+
+ Viewer parameter name.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Text to be rendered.
+
+
+
+
+ Header.
+
+
+
+
+ Footer.
+
+
+
+
+ Indicates whether to use default row highlighting rules.
+
+
+
+
+ The encoding for writing messages to the .
+
+
+
+
+ Indicates whether the error stream (stderr) should be used instead of the output stream (stdout).
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Condition that must be met in order to set the specified foreground and background color.
+
+
+
+
+ Background color.
+
+
+
+
+ Foreground color.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Indicates whether to ignore case when comparing texts.
+
+
+
+
+ Regular expression to be matched. You must specify either text or regex.
+
+
+
+
+ Text to be matched. You must specify either text or regex.
+
+
+
+
+ Indicates whether to match whole words only.
+
+
+
+
+ Compile the ? This can improve the performance, but at the costs of more memory usage. If false, the Regex Cache is used.
+
+
+
+
+ Background color.
+
+
+
+
+ Foreground color.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Text to be rendered.
+
+
+
+
+ Header.
+
+
+
+
+ Footer.
+
+
+
+
+ Indicates whether to send the log messages to the standard error instead of the standard output.
+
+
+
+
+ The encoding for writing messages to the .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Connection string. When provided, it overrides the values specified in DBHost, DBUserName, DBPassword, DBDatabase.
+
+
+
+
+ Name of the connection string (as specified in <connectionStrings> configuration section.
+
+
+
+
+ Database name. If the ConnectionString is not provided this value will be used to construct the "Database=" part of the connection string.
+
+
+
+
+ Database host name. If the ConnectionString is not provided this value will be used to construct the "Server=" part of the connection string.
+
+
+
+
+ Database password. If the ConnectionString is not provided this value will be used to construct the "Password=" part of the connection string.
+
+
+
+
+ Name of the database provider.
+
+
+
+
+ Database user name. If the ConnectionString is not provided this value will be used to construct the "User ID=" part of the connection string.
+
+
+
+
+ Indicates whether to keep the database connection open between the log events.
+
+
+
+
+ Obsolete - value will be ignored! The logging code always runs outside of transaction. Gets or sets a value indicating whether to use database transactions. Some data providers require this.
+
+
+
+
+ Connection string using for installation and uninstallation. If not provided, regular ConnectionString is being used.
+
+
+
+
+ Text of the SQL command to be run on each log level.
+
+
+
+
+ Type of the SQL command to be run on each log level.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Type of the command.
+
+
+
+
+ Connection string to run the command against. If not provided, connection string from the target is used.
+
+
+
+
+ Indicates whether to ignore failures.
+
+
+
+
+ Command text.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Layout that should be use to calcuate the value for the parameter.
+
+
+
+
+ Database parameter name.
+
+
+
+
+ Database parameter precision.
+
+
+
+
+ Database parameter scale.
+
+
+
+
+ Database parameter size.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Text to be rendered.
+
+
+
+
+ Header.
+
+
+
+
+ Footer.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Layout used to format log messages.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Layout used to format log messages.
+
+
+
+
+ Layout that renders event Category.
+
+
+
+
+ Layout that renders event ID.
+
+
+
+
+ Name of the Event Log to write to. This can be System, Application or any user-defined name.
+
+
+
+
+ Name of the machine on which Event Log service is running.
+
+
+
+
+ Value to be used as the event Source.
+
+
+
+
+ Action to take if the message is larger than the option.
+
+
+
+
+ Optional entrytype. When not set, or when not convertable to then determined by
+
+
+
+
+ Message length limit to write to the Event Log.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Indicates whether to return to the first target after any successful write.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Text to be rendered.
+
+
+
+
+ Header.
+
+
+
+
+ Footer.
+
+
+
+
+ File encoding.
+
+
+
+
+ Line ending mode.
+
+
+
+
+ Way file archives are numbered.
+
+
+
+
+ Name of the file to be used for an archive.
+
+
+
+
+ Indicates whether to automatically archive log files every time the specified time passes.
+
+
+
+
+ Size in bytes above which log files will be automatically archived. Warning: combining this with isn't supported. We cannot create multiple archive files, if they should have the same name. Choose:
+
+
+
+
+ Maximum number of archive files that should be kept.
+
+
+
+
+ Indicates whether to compress archive files into the zip archive format.
+
+
+
+
+ Gets or set a value indicating whether a managed file stream is forced, instead of used the native implementation.
+
+
+
+
+ Cleanup invalid values in a filename, e.g. slashes in a filename. If set to true, this can impact the performance of massive writes. If set to false, nothing gets written when the filename is wrong.
+
+
+
+
+ Name of the file to write to.
+
+
+
+
+ Value specifying the date format to use when archiving files.
+
+
+
+
+ Indicates whether to archive old log file on startup.
+
+
+
+
+ Indicates whether to create directories if they do not exist.
+
+
+
+
+ Indicates whether to enable log file(s) to be deleted.
+
+
+
+
+ File attributes (Windows only).
+
+
+
+
+ Indicates whether to delete old log file on startup.
+
+
+
+
+ Indicates whether to replace file contents on each write instead of appending log message at the end.
+
+
+
+
+ Indicates whether concurrent writes to the log file by multiple processes on the same host.
+
+
+
+
+ Delay in milliseconds to wait before attempting to write to the file again.
+
+
+
+
+ Maximum number of log filenames that should be stored as existing.
+
+
+
+
+ Indicates whether concurrent writes to the log file by multiple processes on different network hosts.
+
+
+
+
+ Number of files to be kept open. Setting this to a higher value may improve performance in a situation where a single File target is writing to many files (such as splitting by level or by logger).
+
+
+
+
+ Maximum number of seconds that files are kept open. If this number is negative the files are not automatically closed after a period of inactivity.
+
+
+
+
+ Log file buffer size in bytes.
+
+
+
+
+ Indicates whether to automatically flush the file buffers after each log message.
+
+
+
+
+ Number of times the write is appended on the file before NLog discards the log message.
+
+
+
+
+ Indicates whether to keep log file open instead of opening and closing it on each logging event.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Condition expression. Log events who meet this condition will be forwarded to the wrapped target.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Windows domain name to change context to.
+
+
+
+
+ Required impersonation level.
+
+
+
+
+ Type of the logon provider.
+
+
+
+
+ Logon Type.
+
+
+
+
+ User account password.
+
+
+
+
+ Indicates whether to revert to the credentials of the process instead of impersonating another user.
+
+
+
+
+ Username to change context to.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Endpoint address.
+
+
+
+
+ Name of the endpoint configuration in WCF configuration file.
+
+
+
+
+ Indicates whether to use a WCF service contract that is one way (fire and forget) or two way (request-reply)
+
+
+
+
+ Client ID.
+
+
+
+
+ Indicates whether to include per-event properties in the payload sent to the server.
+
+
+
+
+ Indicates whether to use binary message encoding.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Layout that should be use to calculate the value for the parameter.
+
+
+
+
+ Name of the parameter.
+
+
+
+
+ Type of the parameter.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Text to be rendered.
+
+
+
+
+ Header.
+
+
+
+
+ Footer.
+
+
+
+
+ Indicates whether to send message as HTML instead of plain text.
+
+
+
+
+ Encoding to be used for sending e-mail.
+
+
+
+
+ Indicates whether to add new lines between log entries.
+
+
+
+
+ CC email addresses separated by semicolons (e.g. john@domain.com;jane@domain.com).
+
+
+
+
+ Recipients' email addresses separated by semicolons (e.g. john@domain.com;jane@domain.com).
+
+
+
+
+ BCC email addresses separated by semicolons (e.g. john@domain.com;jane@domain.com).
+
+
+
+
+ Mail message body (repeated for each log message send in one mail).
+
+
+
+
+ Mail subject.
+
+
+
+
+ Sender's email address (e.g. joe@domain.com).
+
+
+
+
+ Indicates whether NewLine characters in the body should be replaced with tags.
+
+
+
+
+ Priority used for sending mails.
+
+
+
+
+ Indicates the SMTP client timeout.
+
+
+
+
+ SMTP Server to be used for sending.
+
+
+
+
+ SMTP Authentication mode.
+
+
+
+
+ Username used to connect to SMTP server (used when SmtpAuthentication is set to "basic").
+
+
+
+
+ Password used to authenticate against SMTP server (used when SmtpAuthentication is set to "basic").
+
+
+
+
+ Indicates whether SSL (secure sockets layer) should be used when communicating with SMTP server.
+
+
+
+
+ Port number that SMTP Server is listening on.
+
+
+
+
+ Indicates whether the default Settings from System.Net.MailSettings should be used.
+
+
+
+
+ Folder where applications save mail messages to be processed by the local SMTP server.
+
+
+
+
+ Specifies how outgoing email messages will be handled.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Layout used to format log messages.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Layout used to format log messages.
+
+
+
+
+ Encoding to be used when writing text to the queue.
+
+
+
+
+ Indicates whether to use the XML format when serializing message. This will also disable creating queues.
+
+
+
+
+ Indicates whether to check if a queue exists before writing to it.
+
+
+
+
+ Indicates whether to create the queue if it doesn't exists.
+
+
+
+
+ Label to associate with each message.
+
+
+
+
+ Name of the queue to write to.
+
+
+
+
+ Indicates whether to use recoverable messages (with guaranteed delivery).
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Class name.
+
+
+
+
+ Method name. The method must be public and static. Use the AssemblyQualifiedName , https://msdn.microsoft.com/en-us/library/system.type.assemblyqualifiedname(v=vs.110).aspx e.g.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Layout used to format log messages.
+
+
+
+
+ Encoding to be used.
+
+
+
+
+ Maximum message size in bytes.
+
+
+
+
+ Indicates whether to append newline at the end of log message.
+
+
+
+
+ Action that should be taken if the will be more connections than .
+
+
+
+
+ Action that should be taken if the message is larger than maxMessageSize.
+
+
+
+
+ Network address.
+
+
+
+
+ Size of the connection cache (number of connections which are kept alive).
+
+
+
+
+ Indicates whether to keep connection open whenever possible.
+
+
+
+
+ Maximum current connections. 0 = no maximum.
+
+
+
+
+ Maximum queue size.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Encoding to be used.
+
+
+
+
+ Instance of that is used to format log messages.
+
+
+
+
+ Maximum message size in bytes.
+
+
+
+
+ Indicates whether to append newline at the end of log message.
+
+
+
+
+ Action that should be taken if the will be more connections than .
+
+
+
+
+ Action that should be taken if the message is larger than maxMessageSize.
+
+
+
+
+ Indicates whether to keep connection open whenever possible.
+
+
+
+
+ Size of the connection cache (number of connections which are kept alive).
+
+
+
+
+ Maximum current connections. 0 = no maximum.
+
+
+
+
+ Network address.
+
+
+
+
+ Maximum queue size.
+
+
+
+
+ Indicates whether to include source info (file name and line number) in the information sent over the network.
+
+
+
+
+ NDC item separator.
+
+
+
+
+ Indicates whether to include stack contents.
+
+
+
+
+ Indicates whether to include call site (class and method name) in the information sent over the network.
+
+
+
+
+ AppInfo field. By default it's the friendly name of the current AppDomain.
+
+
+
+
+ Indicates whether to include NLog-specific extensions to log4j schema.
+
+
+
+
+ Indicates whether to include dictionary contents.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Layout used to format log messages.
+
+
+
+
+ Indicates whether to perform layout calculation.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Layout used to format log messages.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Indicates whether performance counter should be automatically created.
+
+
+
+
+ Name of the performance counter category.
+
+
+
+
+ Counter help text.
+
+
+
+
+ Name of the performance counter.
+
+
+
+
+ Performance counter type.
+
+
+
+
+ The value by which to increment the counter.
+
+
+
+
+ Performance counter instance name.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Default filter to be applied when no specific rule matches.
+
+
+
+
+
+
+
+
+
+
+
+
+ Condition to be tested.
+
+
+
+
+ Resulting filter to be applied when the condition matches.
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Number of times to repeat each log message.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Number of retries that should be attempted on the wrapped target in case of a failure.
+
+
+
+
+ Time to wait between retries in milliseconds.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Layout used to format log messages.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name of the target.
+
+
+
+
+ Should we include the BOM (Byte-order-mark) for UTF? Influences the property. This will only work for UTF-8.
+
+
+
+
+ Encoding.
+
+
+
+
+ Web service method name. Only used with Soap.
+
+
+
+
+ Web service namespace. Only used with Soap.
+
+
+
+
+ Protocol to be used when calling web service.
+
+
+
+
+ Web service URL.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Footer layout.
+
+
+
+
+ Header layout.
+
+
+
+
+ Body layout (can be repeated multiple times).
+
+
+
+
+ Custom column delimiter value (valid when ColumnDelimiter is set to 'Custom').
+
+
+
+
+ Column delimiter.
+
+
+
+
+ Quote Character.
+
+
+
+
+ Quoting mode.
+
+
+
+
+ Indicates whether CVS should include header.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Layout of the column.
+
+
+
+
+ Name of the column.
+
+
+
+
+
+
+
+
+
+
+
+
+ Option to suppress the extra spaces in the output json
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Determines wether or not this attribute will be Json encoded.
+
+
+
+
+ Layout that will be rendered as the attribute's value.
+
+
+
+
+ Name of the attribute.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Footer layout.
+
+
+
+
+ Header layout.
+
+
+
+
+ Body layout (can be repeated multiple times).
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Layout text.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Action to be taken when filter matches.
+
+
+
+
+ Condition expression.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Action to be taken when filter matches.
+
+
+
+
+ Indicates whether to ignore case when comparing strings.
+
+
+
+
+ Layout to be used to filter log messages.
+
+
+
+
+ Substring to be matched.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Action to be taken when filter matches.
+
+
+
+
+ String to compare the layout to.
+
+
+
+
+ Indicates whether to ignore case when comparing strings.
+
+
+
+
+ Layout to be used to filter log messages.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Action to be taken when filter matches.
+
+
+
+
+ Indicates whether to ignore case when comparing strings.
+
+
+
+
+ Layout to be used to filter log messages.
+
+
+
+
+ Substring to be matched.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Action to be taken when filter matches.
+
+
+
+
+ String to compare the layout to.
+
+
+
+
+ Indicates whether to ignore case when comparing strings.
+
+
+
+
+ Layout to be used to filter log messages.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Artemis/Artemis/ViewModels/Abstract/GameViewModel.cs b/Artemis/Artemis/ViewModels/Abstract/GameViewModel.cs
index ba58d6dc6..ef4c9563c 100644
--- a/Artemis/Artemis/ViewModels/Abstract/GameViewModel.cs
+++ b/Artemis/Artemis/ViewModels/Abstract/GameViewModel.cs
@@ -1,17 +1,38 @@
using System.ComponentModel;
+using System.Threading;
+using System.Threading.Tasks;
using Artemis.Managers;
using Artemis.Models;
+using Artemis.Modules.Effects.ProfilePreview;
+using Artemis.Modules.Games.Witcher3;
using Caliburn.Micro;
namespace Artemis.ViewModels.Abstract
{
- public abstract class GameViewModel : Screen
+ public abstract class GameViewModel : Screen
{
+ private bool _doActivate;
+
+ private bool _editorShown;
private GameSettings _gameSettings;
+ private EffectModel _lastEffect;
+
+ protected GameViewModel(MainManager mainManager, GameModel gameModel)
+ {
+ MainManager = mainManager;
+ GameModel = gameModel;
+ GameSettings = gameModel.Settings;
+
+ ProfileEditor = new ProfileEditorViewModel(MainManager, GameModel);
+ GameModel.Profile = ProfileEditor.SelectedProfile;
+ ProfileEditor.PropertyChanged += ProfileUpdater;
+ }
+
+ public ProfileEditorViewModel ProfileEditor { get; set; }
public GameModel GameModel { get; set; }
public MainManager MainManager { get; set; }
- public event OnLayersUpdatedCallback OnLayersUpdatedCallback;
+
public GameSettings GameSettings
{
get { return _gameSettings; }
@@ -54,6 +75,63 @@ namespace Artemis.ViewModels.Abstract
SaveSettings();
}
+
+ protected override void OnActivate()
+ {
+ base.OnActivate();
+
+ // OnActive is triggered at odd moments, only activate the profile
+ // preview if OnDeactivate isn't called right after it
+ _doActivate = true;
+ Task.Factory.StartNew(() =>
+ {
+ Thread.Sleep(100);
+ if (_doActivate)
+ SetEditorShown(true);
+ });
+ }
+
+ protected override void OnDeactivate(bool close)
+ {
+ base.OnDeactivate(close);
+
+ _doActivate = false;
+ SetEditorShown(false);
+ }
+
+ public void SetEditorShown(bool enable)
+ {
+ if (enable == _editorShown)
+ return;
+
+ if (enable)
+ {
+ // Store the current effect so it can be restored later
+ if (!(MainManager.EffectManager.ActiveEffect is ProfilePreviewModel))
+ _lastEffect = MainManager.EffectManager.ActiveEffect;
+
+ MainManager.EffectManager.ProfilePreviewModel.SelectedProfile = ProfileEditor.SelectedProfile;
+ MainManager.EffectManager.ChangeEffect(MainManager.EffectManager.ProfilePreviewModel);
+ }
+ else
+ {
+ if (_lastEffect != null)
+ MainManager.EffectManager.ChangeEffect(_lastEffect, true);
+ else
+ MainManager.EffectManager.ClearEffect();
+ }
+
+ _editorShown = enable;
+ }
+
+ private void ProfileUpdater(object sender, PropertyChangedEventArgs e)
+ {
+ if (e.PropertyName != "SelectedProfile")
+ return;
+
+ GameModel.Profile = ProfileEditor.SelectedProfile;
+ MainManager.EffectManager.ProfilePreviewModel.SelectedProfile = ProfileEditor.SelectedProfile;
+ }
}
public delegate void OnLayersUpdatedCallback(object sender);
diff --git a/Artemis/Artemis/ViewModels/ProfileEditorViewModel.cs b/Artemis/Artemis/ViewModels/ProfileEditorViewModel.cs
index 5bf104d05..7d1ddab4a 100644
--- a/Artemis/Artemis/ViewModels/ProfileEditorViewModel.cs
+++ b/Artemis/Artemis/ViewModels/ProfileEditorViewModel.cs
@@ -9,7 +9,6 @@ using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
-using System.Xml.Serialization;
using Artemis.DAL;
using Artemis.Events;
using Artemis.KeyboardProviders;
@@ -51,6 +50,10 @@ namespace Artemis.ViewModels
LoadProfiles();
}
+ public ProfileEditorViewModel()
+ {
+ }
+
public BindableCollection Profiles
{
get { return _profiles; }
@@ -105,7 +108,8 @@ namespace Artemis.ViewModels
_selectedProfile = value;
Layers.Clear();
- Layers.AddRange(_selectedProfile?.Layers);
+ if (_selectedProfile != null)
+ Layers.AddRange(_selectedProfile.Layers);
NotifyOfPropertyChange(() => SelectedProfile);
NotifyOfPropertyChange(() => CanAddLayer);
diff --git a/Artemis/Artemis/packages.config b/Artemis/Artemis/packages.config
index 137cbc49a..ede4bf51d 100644
--- a/Artemis/Artemis/packages.config
+++ b/Artemis/Artemis/packages.config
@@ -14,6 +14,9 @@
+
+
+