1
0
mirror of https://github.com/Artemis-RGB/Artemis synced 2025-12-12 21:38:38 +00:00

Implemented keyboard preview, added logging

This commit is contained in:
SpoinkyNL 2016-04-27 19:11:56 +02:00
parent 9d966b9321
commit 32a651ffec
25 changed files with 3015 additions and 193 deletions

View File

@ -175,6 +175,10 @@
<HintPath>..\packages\Newtonsoft.Json.8.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
<HintPath>..\packages\NLog.4.3.2\lib\net45\NLog.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="SharpDX, Version=3.0.2.0, Culture=neutral, PublicKeyToken=b4dcf0f35e5521f1, processorArchitecture=MSIL">
<HintPath>..\packages\SharpDX.3.0.2\lib\net45\SharpDX.dll</HintPath>
<Private>True</Private>
@ -299,6 +303,7 @@
<Compile Include="Modules\Effects\AudioVisualizer\Utilities\FftEventArgs.cs" />
<Compile Include="Modules\Effects\AudioVisualizer\Utilities\SampleAggregator.cs" />
<Compile Include="Modules\Effects\Debug\DebugEffectModel.cs" />
<Compile Include="Modules\Effects\ProfilePreview\ProfilePreviewModel.cs" />
<Compile Include="Modules\Effects\TypeHole\TypeHoleModel.cs" />
<Compile Include="Modules\Effects\TypeWave\TypeWave.Designer.cs">
<DependentUpon>TypeWave.settings</DependentUpon>
@ -529,6 +534,12 @@
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>VolumeDisplay.Designer.cs</LastGenOutput>
</None>
<Content Include="NLog.config">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<None Include="NLog.xsd">
<SubType>Designer</SubType>
</None>
<None Include="packages.config" />
<AppDesigner Include="Properties\" />
<Resource Include="Resources\bow.png" />

View File

@ -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<EffectModel>();
ProfilePreviewModel = new ProfilePreviewModel(_mainManager);
Logger.Info("Intialized EffectManager");
}
/// <summary>
/// Used by ViewModels to show a preview of the profile currently being edited
/// </summary>
public ProfilePreviewModel ProfilePreviewModel { get; set; }
/// <summary>
/// Holds all the effects the program has
/// </summary>
public List<EffectModel> EffectModels { get; set; }
public EffectModel ActiveEffect
@ -36,11 +52,17 @@ namespace Artemis.Managers
}
}
/// <summary>
/// Returns all enabled overlays
/// </summary>
public IEnumerable<OverlayModel> EnabledOverlays
{
get { return EffectModels.OfType<OverlayModel>().Where(o => o.Enabled); }
}
/// <summary>
/// Returns all enabled games
/// </summary>
public IEnumerable<GameModel> EnabledGames
{
get { return EffectModels.OfType<GameModel>().Where(g => g.Enabled); }
@ -52,13 +74,14 @@ namespace Artemis.Managers
/// <returns>Whether enabling was successful or not.</returns>
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;
}
/// <summary>
@ -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");
}
/// <summary>
@ -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
/// <param name="activeEffect"></param>
public void DisableGame(EffectModel activeEffect)
{
Logger.Debug("Disabling game: {0}", activeEffect?.Name);
if (GetLastEffect() == null)
ClearEffect();
else

View File

@ -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<KeyboardProvider> KeyboardProviders { get; set; }
@ -33,11 +38,14 @@ namespace Artemis.Managers
}
}
public bool CanDisable { get; set; }
/// <summary>
/// Enables the last keyboard according to the settings file
/// </summary>
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
/// <param name="keyboardProvider"></param>
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;
}
/// <summary>
/// Releases the active keyboard
/// Releases the active keyboard, if CanDisable is true
/// </summary>
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
/// <param name="keyboardProvider"></param>
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();
}
}

View File

@ -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
/// <returns>Whether starting was successful or not</returns>
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
/// </summary>
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
/// </summary>
public void EnableProgram()
{
Logger.Debug("Enabling program");
ProgramEnabled = true;
Start(EffectManager.GetLastEffect());
Events.PublishOnUIThread(new ToggleEnabled(ProgramEnabled));
@ -185,6 +201,7 @@ namespace Artemis.Managers
/// </summary>
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)

View File

@ -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;
}
}
}

View File

@ -64,10 +64,12 @@ namespace Artemis.Models.Profiles
_mustDraw = false;
}
public void Draw<T>(IGameDataModel dataModel, DrawingContext c)
public void Draw<T>(IGameDataModel dataModel, DrawingContext c, bool preview = false)
{
if (!ConditionsMet<T>(dataModel))
return;
// Conditions aren't checked during a preview because there is no game data to base them on
if (!preview)
if (!ConditionsMet<T>(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<T>(IGameDataModel dataModel)
public void Update<T>(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<T>(dataModel, UserProps, CalcProps);
}

View File

@ -106,7 +106,7 @@ namespace Artemis.Models.Profiles
Layers[i].Order = i;
}
public Bitmap GenerateBitmap<T>(Rect keyboardRect, IGameDataModel gameDataModel)
public Bitmap GenerateBitmap<T>(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<T>(gameDataModel, c);
layerModel.Draw<T>(gameDataModel, c, preview);
// Remove the clip
c.Pop();

View File

@ -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)

View File

@ -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<ProfilePreviewDataModel>(_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<ProfilePreviewDataModel>(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
{
}
}

View File

@ -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()

View File

@ -8,33 +8,15 @@ using Artemis.ViewModels.Abstract;
namespace Artemis.Modules.Games.CounterStrike
{
public class CounterStrikeViewModel : GameViewModel
public class CounterStrikeViewModel : GameViewModel<CounterStrikeDataModel>
{
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<CounterStrikeDataModel>(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<CounterStrikeDataModel> ProfileEditor { get; set; }
public static string Name => "CS:GO";
public string Content => "Counter-Strike: GO Content";

View File

@ -1,6 +1,6 @@
namespace Artemis.Modules.Games.Dota2
{
class Dota2DataModel
public class Dota2DataModel
{
public class Rootobject
{

View File

@ -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<Color>()
, 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<Color>(),
LinearGradientMode.Horizontal)
(_abilityKeys.TopLeft.X + i)*Scale - 2,
_abilityKeys.TopLeft.Y*Scale,
new List<Color>(),
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<Color>(),
LinearGradientMode.Horizontal)
_abilityKeys.TopLeft.X*Scale - 2,
_abilityKeys.TopLeft.Y*Scale,
new List<Color>(),
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<Color>(),
LinearGradientMode.Horizontal)
(_abilityKeys.TopLeft.X + 2)*Scale - 2,
_abilityKeys.TopLeft.Y*Scale,
new List<Color>(),
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<Color>(),
LinearGradientMode.Horizontal)
(_abilityKeys.TopLeft.X + 3)*Scale - 2,
_abilityKeys.TopLeft.Y*Scale,
new List<Color>(),
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<Color>(),
LinearGradientMode.Horizontal)
(_abilityKeys.TopLeft.X + 3)*Scale - 2,
(_abilityKeys.TopLeft.Y + 1)*Scale,
new List<Color>(),
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<Color>(),
LinearGradientMode.Horizontal)
(_abilityKeys.TopLeft.X + i)*Scale - 3,
(_abilityKeys.TopLeft.Y - 1)*Scale,
new List<Color>(),
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<Color> list = null;
if (!D2Json.hero.alive)
list = new List<Color> { Color.LightGray };
list = new List<Color> {Color.LightGray};
else if (D2Json.hero.disarmed)
list = new List<Color> { Color.Yellow };
list = new List<Color> {Color.Yellow};
else if (D2Json.hero.hexed)
list = new List<Color> { Color.Yellow };
list = new List<Color> {Color.Yellow};
else if (D2Json.hero.silenced)
list = new List<Color> { Color.Yellow };
list = new List<Color> {Color.Yellow};
else if (D2Json.hero.stunned)
list = new List<Color> { Color.Yellow };
list = new List<Color> {Color.Yellow};
else if (D2Json.hero.magicimmune)
list = new List<Color> { Color.Lime };
if(list == null)
list = new List<Color> {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<Color>
{ ColorHelpers.ToDrawingColor(Settings.AbilityReadyColor) } : new List<Color> { ColorHelpers.ToDrawingColor(Settings.AbilityCooldownColor) };
AbilityKeysRectangles[1].Colors = D2Json?.abilities?.ability1?.can_cast == true ? new List<Color>
{ ColorHelpers.ToDrawingColor(Settings.AbilityReadyColor) } : new List<Color> { ColorHelpers.ToDrawingColor(Settings.AbilityCooldownColor) };
AbilityKeysRectangles[2].Colors = D2Json?.abilities?.ability2?.can_cast == true ? new List<Color>
{ ColorHelpers.ToDrawingColor(Settings.AbilityReadyColor) } : new List<Color> { ColorHelpers.ToDrawingColor(Settings.AbilityCooldownColor) };
AbilityKeysRectangles[3].Colors = D2Json?.abilities?.ability3?.can_cast == true ? new List<Color>
{ ColorHelpers.ToDrawingColor(Settings.AbilityReadyColor) } : new List<Color> { ColorHelpers.ToDrawingColor(Settings.AbilityCooldownColor) };
AbilityKeysRectangles[0].Colors = D2Json?.abilities?.ability0?.can_cast == true
? new List<Color>
{ColorHelpers.ToDrawingColor(Settings.AbilityReadyColor)}
: new List<Color> {ColorHelpers.ToDrawingColor(Settings.AbilityCooldownColor)};
AbilityKeysRectangles[1].Colors = D2Json?.abilities?.ability1?.can_cast == true
? new List<Color>
{ColorHelpers.ToDrawingColor(Settings.AbilityReadyColor)}
: new List<Color> {ColorHelpers.ToDrawingColor(Settings.AbilityCooldownColor)};
AbilityKeysRectangles[2].Colors = D2Json?.abilities?.ability2?.can_cast == true
? new List<Color>
{ColorHelpers.ToDrawingColor(Settings.AbilityReadyColor)}
: new List<Color> {ColorHelpers.ToDrawingColor(Settings.AbilityCooldownColor)};
AbilityKeysRectangles[3].Colors = D2Json?.abilities?.ability3?.can_cast == true
? new List<Color>
{ColorHelpers.ToDrawingColor(Settings.AbilityReadyColor)}
: new List<Color> {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
}
}

View File

@ -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<Dota2DataModel>
{
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<string> KeyboardLayouts
public BindableCollection<string> KeyboardLayouts => new BindableCollection<string>(new[]
{
get
{
return new BindableCollection<string>(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();

View File

@ -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()

View File

@ -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<RocketLeagueDataModel>
{
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<RocketLeagueDataModel>(MainManager, GameModel);
ProfileEditor.PropertyChanged += ProfileUpdater;
GameModel.Profile = ProfileEditor.SelectedProfile;
}
public ProfileEditorViewModel<RocketLeagueDataModel> 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)

View File

@ -22,9 +22,8 @@ namespace Artemis.Modules.Games.TheDivision
private StickyValue<bool> _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()

View File

@ -4,24 +4,13 @@ using Artemis.ViewModels.Abstract;
namespace Artemis.Modules.Games.TheDivision
{
public class TheDivisionViewModel : GameViewModel
public class TheDivisionViewModel : GameViewModel<TheDivisionDataModel>
{
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<TheDivisionDataModel>(MainManager, GameModel);
}
public ProfileEditorViewModel<TheDivisionDataModel> ProfileEditor { get; set; }
public static string Name => "The Division";
}
}

View File

@ -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()

View File

@ -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<Witcher3DataModel>
{
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
{
}
}

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.nlog-project.org/schemas/NLog.xsd NLog.xsd"
autoReload="false"
throwExceptions="false"
internalLogLevel="Off" internalLogFile="c:\temp\nlog-internal.log" >
<targets>
<target name="file" xsi:type="File" maxArchiveFiles="7" fileName="${specialfolder:folder=MyDocuments}/Artemis/logs/${shortdate}.txt"/>
<target name="debugger" xsi:type="Debugger" layout="${logger:shortName=True} - ${uppercase:${level}}: ${message}"/>
</targets>
<rules>
<logger name="*" minlevel="Debug" writeTo="file" />
<logger name="*" minlevel="Debug" writeTo="debugger" />
</rules>
</nlog>

2601
Artemis/Artemis/NLog.xsd Normal file

File diff suppressed because it is too large Load Diff

View File

@ -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<T> : 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<T>(MainManager, GameModel);
GameModel.Profile = ProfileEditor.SelectedProfile;
ProfileEditor.PropertyChanged += ProfileUpdater;
}
public ProfileEditorViewModel<T> 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);

View File

@ -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<ProfileModel> 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);

View File

@ -14,6 +14,9 @@
<package id="MahApps.Metro.Resources" version="0.5.0.0" targetFramework="net452" />
<package id="NAudio" version="1.7.3" targetFramework="net452" />
<package id="Newtonsoft.Json" version="8.0.3" targetFramework="net452" />
<package id="NLog" version="4.3.2" targetFramework="net452" />
<package id="NLog.Config" version="4.3.2" targetFramework="net452" />
<package id="NLog.Schema" version="4.3.0" targetFramework="net452" />
<package id="SharpDX" version="3.0.2" targetFramework="net452" />
<package id="SharpDX.Direct3D11" version="3.0.2" targetFramework="net452" />
<package id="SharpDX.DXGI" version="3.0.2" targetFramework="net452" />