From b53e08fdcb4e2bcc8cd0ddbefdb9a9e39e12adcf Mon Sep 17 00:00:00 2001 From: SpoinkyNL Date: Tue, 7 Feb 2017 23:39:47 +0100 Subject: [PATCH] Added LUA keybind module --- Artemis/Artemis/Artemis.csproj | 1 + .../Layers/Conditions/EventCondition.cs | 116 +++++++++--------- .../Profiles/Lua/Modules/LuaKeybindModule.cs | 91 ++++++++++++++ Artemis/Artemis/Profiles/ProfileModel.cs | 26 ++-- .../ViewModels/ProfileEditorViewModel.cs | 4 +- 5 files changed, 165 insertions(+), 73 deletions(-) create mode 100644 Artemis/Artemis/Profiles/Lua/Modules/LuaKeybindModule.cs diff --git a/Artemis/Artemis/Artemis.csproj b/Artemis/Artemis/Artemis.csproj index fa1c89fff..802b21a7b 100644 --- a/Artemis/Artemis/Artemis.csproj +++ b/Artemis/Artemis/Artemis.csproj @@ -548,6 +548,7 @@ + diff --git a/Artemis/Artemis/Profiles/Layers/Conditions/EventCondition.cs b/Artemis/Artemis/Profiles/Layers/Conditions/EventCondition.cs index 699f9f810..f7cb9ada3 100644 --- a/Artemis/Artemis/Profiles/Layers/Conditions/EventCondition.cs +++ b/Artemis/Artemis/Profiles/Layers/Conditions/EventCondition.cs @@ -1,60 +1,60 @@ -using System.Linq; -using Artemis.Modules.Abstract; -using Artemis.Profiles.Layers.Interfaces; -using Artemis.Profiles.Layers.Models; -using Newtonsoft.Json; - -namespace Artemis.Profiles.Layers.Conditions -{ - public class EventCondition : ILayerCondition - { - [JsonIgnore] - public bool HotKeyMet { get;set; } - - public bool ConditionsMet(LayerModel layerModel, ModuleDataModel dataModel) - { - lock (layerModel.Properties.Conditions) - { - var checkConditions = layerModel.Properties.Conditions.Where(c => !c.Field.Contains("hotkey")); - var conditionsMet = false; - switch (layerModel.Properties.ConditionType) - { - case ConditionType.AnyMet: - conditionsMet = HotKeyMet || checkConditions.Any(cm => cm.ConditionMet(dataModel)); - break; - case ConditionType.AllMet: - conditionsMet = HotKeyMet && checkConditions.All(cm => cm.ConditionMet(dataModel)); - break; - case ConditionType.NoneMet: - conditionsMet = !HotKeyMet && !checkConditions.Any(cm => cm.ConditionMet(dataModel)); - break; - } - - layerModel.EventProperties.Update(layerModel, conditionsMet); - - if (conditionsMet) +using System.Linq; +using Artemis.Modules.Abstract; +using Artemis.Profiles.Layers.Interfaces; +using Artemis.Profiles.Layers.Models; +using Newtonsoft.Json; + +namespace Artemis.Profiles.Layers.Conditions +{ + public class EventCondition : ILayerCondition + { + [JsonIgnore] + public bool HotKeyMet { get;set; } + + public bool ConditionsMet(LayerModel layerModel, ModuleDataModel dataModel) + { + lock (layerModel.Properties.Conditions) + { + var checkConditions = layerModel.Properties.Conditions.Where(c => !c.Field.Contains("hotkey")); + var conditionsMet = false; + switch (layerModel.Properties.ConditionType) + { + case ConditionType.AnyMet: + conditionsMet = HotKeyMet || checkConditions.Any(cm => cm.ConditionMet(dataModel)); + break; + case ConditionType.AllMet: + conditionsMet = HotKeyMet && checkConditions.All(cm => cm.ConditionMet(dataModel)); + break; + case ConditionType.NoneMet: + conditionsMet = !HotKeyMet && !checkConditions.Any(cm => cm.ConditionMet(dataModel)); + break; + } + + layerModel.EventProperties.Update(layerModel, conditionsMet); + + if (conditionsMet) layerModel.EventProperties.TriggerEvent(layerModel); - if (layerModel.EventProperties.MustStop(layerModel)) - HotKeyMet = false; - - return layerModel.EventProperties.MustDraw; - } - } - - public void KeybindTask(LayerConditionModel condition) - { - switch (condition.Field) - { - case "hotkeyEnable": - HotKeyMet = true; - break; - case "hotkeyDisable": - HotKeyMet = false; - break; - case "hotkeyToggle": - HotKeyMet = !HotKeyMet; - break; - } - } - } + if (layerModel.EventProperties.MustStop(layerModel)) + HotKeyMet = false; + + return layerModel.EventProperties.MustDraw; + } + } + + public void KeybindTask(LayerConditionModel condition) + { + switch (condition.Field) + { + case "hotkeyEnable": + HotKeyMet = true; + break; + case "hotkeyDisable": + HotKeyMet = false; + break; + case "hotkeyToggle": + HotKeyMet = !HotKeyMet; + break; + } + } + } } \ No newline at end of file diff --git a/Artemis/Artemis/Profiles/Lua/Modules/LuaKeybindModule.cs b/Artemis/Artemis/Profiles/Lua/Modules/LuaKeybindModule.cs new file mode 100644 index 000000000..54c9a3ab8 --- /dev/null +++ b/Artemis/Artemis/Profiles/Lua/Modules/LuaKeybindModule.cs @@ -0,0 +1,91 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Windows.Input; +using Artemis.Managers; +using Artemis.Models; +using MahApps.Metro.Controls; +using MoonSharp.Interpreter; + +namespace Artemis.Profiles.Lua.Modules +{ + [MoonSharpUserData] + public class LuaKeybindModule : LuaModule + { + private readonly List _keybindModels; + + public LuaKeybindModule(LuaManager luaManager) : base(luaManager) + { + _keybindModels = new List(); + LuaManager.ProfileModel.OnProfileUpdatedEvent += ProfileModelOnOnProfileUpdatedEvent; + } + + public override string ModuleName => "Keybind"; + + private void ProfileModelOnOnProfileUpdatedEvent(object sender, EventArgs e) + { + foreach (var keybindModel in _keybindModels) + KeybindManager.AddOrUpdate(keybindModel); + } + + /// + /// Sets a keybind to call the provided function + /// + /// Name of the keybind + /// Hotkey in string format, per example: ALT+CTRL+SHIFT+D + /// LUA function to call + /// Optional arguments for the passed function + public void SetKeybind(string name, string hotKey, DynValue function, params DynValue[] args) + { + var modifierKeys = ModifierKeys.None; + var key = Key.System; + var hotKeyParts = hotKey.Split('+').Select(p => p.Trim()); + foreach (var hotKeyPart in hotKeyParts) + if (hotKeyPart == "ALT") + modifierKeys |= ModifierKeys.Alt; + else if (hotKeyPart == "CTRL") + modifierKeys |= ModifierKeys.Control; + else if (hotKeyPart == "SHIFT") + modifierKeys |= ModifierKeys.Shift; + else + Enum.TryParse(hotKeyPart, true, out key); + + if (key == Key.System) + throw new ScriptRuntimeException($"Hotkey '{hotKey}' couldn't be parsed."); + + var hk = new HotKey(key, modifierKeys); + var model = args != null + ? new KeybindModel("LUA-" + name, hk, () => LuaManager.Call(function, args)) + : new KeybindModel("LUA-" + name, hk, () => LuaManager.Call(function)); + + KeybindManager.AddOrUpdate(model); + + var existing = _keybindModels.FirstOrDefault(k => k.Name == model.Name); + if (existing != null) + _keybindModels.Remove(existing); + + _keybindModels.Add(model); + } + + /// + /// If found, removes a keybind with the given name + /// + /// + public void RemoveKeybind(string name) + { + var existing = _keybindModels.FirstOrDefault(k => k.Name == name); + if (existing != null) + _keybindModels.Remove(existing); + + KeybindManager.Remove(name); + } + + public override void Dispose() + { + foreach (var keybindModel in _keybindModels) + KeybindManager.Remove(keybindModel); + + LuaManager.ProfileModel.OnProfileUpdatedEvent -= ProfileModelOnOnProfileUpdatedEvent; + } + } +} \ No newline at end of file diff --git a/Artemis/Artemis/Profiles/ProfileModel.cs b/Artemis/Artemis/Profiles/ProfileModel.cs index 9cf4c7fd4..9abcbb4ba 100644 --- a/Artemis/Artemis/Profiles/ProfileModel.cs +++ b/Artemis/Artemis/Profiles/ProfileModel.cs @@ -1,7 +1,5 @@ using System; using System.Collections.Generic; -using System.Diagnostics; -using System.Drawing; using System.IO; using System.Linq; using System.Windows; @@ -13,12 +11,8 @@ using Artemis.Models; using Artemis.Modules.Abstract; using Artemis.Profiles.Layers.Interfaces; using Artemis.Profiles.Layers.Models; -using Artemis.Utilities; using Artemis.Utilities.ParentChild; using Newtonsoft.Json; -using Color = System.Windows.Media.Color; -using Point = System.Windows.Point; -using Size = System.Windows.Size; namespace Artemis.Profiles { @@ -30,6 +24,7 @@ namespace Artemis.Profiles { _invalidFileNameChars = Path.GetInvalidFileNameChars(); Layers = new ChildItemCollection(this); + OnProfileUpdatedEvent += OnOnProfileUpdatedEvent; } public ChildItemCollection Layers { get; } @@ -44,8 +39,14 @@ namespace Artemis.Profiles [JsonIgnore] public string Slug => new string(Name.Where(ch => !_invalidFileNameChars.Contains(ch)).ToArray()); + private void OnOnProfileUpdatedEvent(object sender, EventArgs e) + { + ApplyKeybinds(); + } + public event EventHandler OnDeviceUpdatedEvent; public event EventHandler OnDeviceDrawnEvent; + public event EventHandler OnProfileUpdatedEvent; public void FixOrder() { @@ -133,14 +134,17 @@ namespace Artemis.Profiles private void RaiseDeviceUpdatedEvent(ProfileDeviceEventsArg e) { - var handler = OnDeviceUpdatedEvent; - handler?.Invoke(this, e); + OnDeviceUpdatedEvent?.Invoke(this, e); } public void RaiseDeviceDrawnEvent(ProfileDeviceEventsArg e) { - var handler = OnDeviceDrawnEvent; - handler?.Invoke(this, e); + OnDeviceDrawnEvent?.Invoke(this, e); + } + + public virtual void OnOnProfileUpdatedEvent() + { + OnProfileUpdatedEvent?.Invoke(this, EventArgs.Empty); } /// @@ -216,7 +220,6 @@ namespace Artemis.Profiles public void ApplyKeybinds() { foreach (var layerModel in Layers) - { for (var index = 0; index < layerModel.Properties.Conditions.Count; index++) { var condition = layerModel.Properties.Conditions[index]; @@ -228,7 +231,6 @@ namespace Artemis.Profiles var kb = new KeybindModel($"{GameName}-{Name}-{layerModel.Name}-{index}", condition.HotKey, action); KeybindManager.AddOrUpdate(kb); } - } } #region Compare diff --git a/Artemis/Artemis/ViewModels/ProfileEditorViewModel.cs b/Artemis/Artemis/ViewModels/ProfileEditorViewModel.cs index 1092c51d9..149dc30d1 100644 --- a/Artemis/Artemis/ViewModels/ProfileEditorViewModel.cs +++ b/Artemis/Artemis/ViewModels/ProfileEditorViewModel.cs @@ -319,9 +319,7 @@ namespace Artemis.ViewModels { Thread.Sleep(100); SelectedLayer = selectModel; - - // Let the profile reapply keybinds after messing with layers - SelectedProfile.ApplyKeybinds(); + SelectedProfile?.OnOnProfileUpdatedEvent(); }); }