diff --git a/Project-Aurora/Project-Aurora/ConfigUI.xaml.cs b/Project-Aurora/Project-Aurora/ConfigUI.xaml.cs index ee165ba2b..976174a54 100755 --- a/Project-Aurora/Project-Aurora/ConfigUI.xaml.cs +++ b/Project-Aurora/Project-Aurora/ConfigUI.xaml.cs @@ -46,7 +46,8 @@ partial class ConfigUI : Window, INotifyPropertyChanged private bool settingsloaded = false; private bool shownHiddenMessage = false; - private string saved_preview_key = ""; + private string saved_preview_key = null; + public string preview_key => saved_preview_key; private Timer virtual_keyboard_timer; private Stopwatch recording_stopwatch = new Stopwatch(); @@ -66,7 +67,9 @@ public Profiles.Application FocusedApplication set { SetValue(FocusedApplicationProperty, value); - Global.LightingStateManager.PreviewProfileKey = value != null ? value.Config.ID : string.Empty; + saved_preview_key = value != null ? value.Config.ID : null; + + Global.LightingStateManager.FocusedApplicationChanged(saved_preview_key); } } @@ -334,8 +337,6 @@ private void minimizeApp() shownHiddenMessage = true; } - Global.LightingStateManager.PreviewProfileKey = string.Empty; - //Hide Window System.Windows.Application.Current.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Background, (System.Windows.Threading.DispatcherOperationCallback)delegate (object o) { @@ -347,13 +348,12 @@ private void minimizeApp() private void Window_Activated(object sender, EventArgs e) { - Global.LightingStateManager.PreviewProfileKey = saved_preview_key; + Global.LightingStateManager.FocusedApplicationChanged(saved_preview_key); } private void Window_Deactivated(object sender, EventArgs e) { - saved_preview_key = Global.LightingStateManager.PreviewProfileKey; - Global.LightingStateManager.PreviewProfileKey = string.Empty; + Global.LightingStateManager.FocusedApplicationChanged(null); } private Image profile_add; diff --git a/Project-Aurora/Project-Aurora/Controls/ColorZones.xaml.cs b/Project-Aurora/Project-Aurora/Controls/ColorZones.xaml.cs index 56fbc7fb1..894fca34d 100644 --- a/Project-Aurora/Project-Aurora/Controls/ColorZones.xaml.cs +++ b/Project-Aurora/Project-Aurora/Controls/ColorZones.xaml.cs @@ -168,7 +168,8 @@ private void effect_settings_button_Click(object sender, RoutedEventArgs e) if (cz_list.SelectedItem != null) { EffectSettingsWindow effect_settings = new EffectSettingsWindow(((ColorZone)cz_list.SelectedItem).effect_config); - effect_settings.preview_key = Global.LightingStateManager.PreviewProfileKey; + + effect_settings.preview_key = ((ConfigUI)System.Windows.Application.Current.MainWindow).preview_key; effect_settings.EffectConfigUpdated += Effect_settings_EffectConfigUpdated; effect_settings.ShowDialog(); diff --git a/Project-Aurora/Project-Aurora/Controls/EffectSettingsWindow.xaml.cs b/Project-Aurora/Project-Aurora/Controls/EffectSettingsWindow.xaml.cs index 3099c6b5b..cf6da3426 100644 --- a/Project-Aurora/Project-Aurora/Controls/EffectSettingsWindow.xaml.cs +++ b/Project-Aurora/Project-Aurora/Controls/EffectSettingsWindow.xaml.cs @@ -122,12 +122,12 @@ private void accept_button_Click(object sender, RoutedEventArgs e) private void Window_Activated(object sender, EventArgs e) { - Global.LightingStateManager.PreviewProfileKey = preview_key; + Global.LightingStateManager.FocusedApplicationChanged(null); } private void Window_Deactivated(object sender, EventArgs e) { - Global.LightingStateManager.PreviewProfileKey = null; + Global.LightingStateManager.FocusedApplicationChanged(preview_key); } private void effect_angle_ValueChanged(object sender, RoutedPropertyChangedEventArgs e) diff --git a/Project-Aurora/Project-Aurora/Profiles/Application.cs b/Project-Aurora/Project-Aurora/Profiles/Application.cs index bd92adbfc..fabfe3ef1 100755 --- a/Project-Aurora/Project-Aurora/Profiles/Application.cs +++ b/Project-Aurora/Project-Aurora/Profiles/Application.cs @@ -44,8 +44,6 @@ public class LightEventConfig : INotifyPropertyChanged public LightEvent Event { get; set; } - public int? UpdateInterval { get; set; } = null; - public string IconURI { get; set; } public HashSet ExtraAvailableLayers { get; } = new HashSet(); diff --git a/Project-Aurora/Project-Aurora/Profiles/Desktop/Event_Desktop.cs b/Project-Aurora/Project-Aurora/Profiles/Desktop/Event_Desktop.cs index e03baf93b..140a43c7b 100755 --- a/Project-Aurora/Project-Aurora/Profiles/Desktop/Event_Desktop.cs +++ b/Project-Aurora/Project-Aurora/Profiles/Desktop/Event_Desktop.cs @@ -25,7 +25,7 @@ public Event_Desktop() : base() public override void UpdateLights(EffectFrame frame) { var layers = new Queue(Application.Profile.Layers.Where(l => l.Enabled).Reverse().Select(l => l.Render(_game_state))); - + //Scripts before interactive and shortcut assistant layers //ProfilesManager.DesktopProfile.UpdateEffectScripts(layers); @@ -42,6 +42,14 @@ public override void UpdateLights(EffectFrame frame) } frame.AddLayers(layers.ToArray()); + + } + public override void UpdateOverlayLights(EffectFrame frame) + { + var overlayLayers = new Queue(Application.Profile.OverlayLayers.Where(l => l.Enabled).Reverse().Select(l => l.Render(_game_state))); + + frame.AddOverlayLayers(overlayLayers.ToArray()); + } public override void SetGameState(IGameState new_game_state) diff --git a/Project-Aurora/Project-Aurora/Profiles/EliteDangerous/EliteDangerousApplication.cs b/Project-Aurora/Project-Aurora/Profiles/EliteDangerous/EliteDangerousApplication.cs index ebc2942ac..7a5a26948 100644 --- a/Project-Aurora/Project-Aurora/Profiles/EliteDangerous/EliteDangerousApplication.cs +++ b/Project-Aurora/Project-Aurora/Profiles/EliteDangerous/EliteDangerousApplication.cs @@ -10,7 +10,6 @@ public EliteDangerous() Name = "Elite: Dangerous", ID = "EliteDangerous", ProcessNames = new[] { "EliteDangerous64.exe" }, - UpdateInterval = 16, SettingsType = typeof(EliteDangerousSettings), ProfileType = typeof(EliteDangerousProfile), OverviewControlType = typeof(Control_EliteDangerous), diff --git a/Project-Aurora/Project-Aurora/Profiles/LeagueOfLegends/GameEvent_LoL.cs b/Project-Aurora/Project-Aurora/Profiles/LeagueOfLegends/GameEvent_LoL.cs index 0d351d76b..e0cbcb684 100644 --- a/Project-Aurora/Project-Aurora/Profiles/LeagueOfLegends/GameEvent_LoL.cs +++ b/Project-Aurora/Project-Aurora/Profiles/LeagueOfLegends/GameEvent_LoL.cs @@ -197,12 +197,6 @@ private static SlotNode GetItem(_AllPlayer p, int slot) private async void UpdateData(object sender, ElapsedEventArgs e) { - if (!Global.LightingStateManager.RunningProcessMonitor.IsProcessRunning("league of legends.exe")) - { - allGameData = null; - return; - } - string jsonData = ""; try diff --git a/Project-Aurora/Project-Aurora/Profiles/LightEvent.cs b/Project-Aurora/Project-Aurora/Profiles/LightEvent.cs index d3c85797e..bf6e6d7f6 100644 --- a/Project-Aurora/Project-Aurora/Profiles/LightEvent.cs +++ b/Project-Aurora/Project-Aurora/Profiles/LightEvent.cs @@ -8,12 +8,6 @@ namespace Aurora.Profiles { - public enum LightEventType - { - Normal, - Underlay, - Overlay - } public interface ILightEvent : IInit { diff --git a/Project-Aurora/Project-Aurora/Profiles/LightingEngine.cs b/Project-Aurora/Project-Aurora/Profiles/LightingEngine.cs new file mode 100644 index 000000000..ecf3a8371 --- /dev/null +++ b/Project-Aurora/Project-Aurora/Profiles/LightingEngine.cs @@ -0,0 +1,208 @@ +using Aurora.EffectsEngine; +using Aurora.Settings; +using Aurora.Settings.Layers; +using Aurora.Utils; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Drawing; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; + + +namespace Aurora.Profiles +{ + public interface ILightingEngine + { + void ActiveProfileChanged(ILightEvent profile); + void RefreshOverLayerProfiles(List profiles); + } + + public class LightingEngine : ILightingEngine, IInit + { + private ILightEvent ActiveProfile; + private List OverlayProfiles = new List(); + + private Timer updateTimer; + + private int timerInterval = 33; + + private long currentTick; + + public event EventHandler PreUpdate; + public event EventHandler PostUpdate; + + private List TimedLayers = new List(); + + public LightingEngine(ILightEvent profile) + { + ActiveProfile = profile; + } + public bool Initialized { get; private set; } + + public bool Initialize() + { + if (Initialized) + return true; + + this.InitUpdate(); + + // Listen for profile keybind triggers + Global.InputEvents.KeyDown += CheckProfileKeybinds; + + Initialized = true; + return Initialized; + } + + private void InitUpdate() + { + updateTimer = new System.Threading.Timer(g => { + Stopwatch watch = new Stopwatch(); + watch.Start(); + if (Global.isDebug) + Update(); + else + { + try + { + Update(); + } + catch (Exception exc) + { + Global.logger.Error("ProfilesManager.Update() Exception, " + exc); + } + } + + watch.Stop(); + currentTick += timerInterval + watch.ElapsedMilliseconds; + updateTimer?.Change(Math.Max(timerInterval, 0), Timeout.Infinite); + }, null, 0, System.Threading.Timeout.Infinite); + GC.KeepAlive(updateTimer); + } + + private void RefreshLightningFrame() + { + EffectsEngine.EffectFrame newFrame = new EffectsEngine.EffectFrame(); + + if (ActiveProfile.IsEnabled) + { + ActiveProfile.UpdateLights(newFrame); + } + foreach (ILightEvent prof in OverlayProfiles) + { + if (prof.IsOverlayEnabled) + prof.UpdateOverlayLights(newFrame); + } + if (ActiveProfile.IsEnabled) + { + ActiveProfile.UpdateOverlayLights(newFrame); + } + + var timedLayers = TimedLayers.ToList(); + var layers = new Queue(timedLayers.Select(l => ((Layer)l.item).Render(null))); + newFrame.AddOverlayLayers(layers.ToArray()); + + Global.effengine.PushFrame(newFrame); + } + + private void Update() + { + PreUpdate?.Invoke(this, null); + + //Blackout. TODO: Cleanup this a bit. Maybe push blank effect frame to keyboard incase it has existing stuff displayed + if ((Global.Configuration.time_based_dimming_enabled && + Utils.Time.IsCurrentTimeBetween(Global.Configuration.time_based_dimming_start_hour, Global.Configuration.time_based_dimming_start_minute, Global.Configuration.time_based_dimming_end_hour, Global.Configuration.time_based_dimming_end_minute))) + { + return; + } + + Global.dev_manager.InitializeOnce(); + + timerInterval = 1000 / Global.Configuration.FrameRate; + + + RefreshLightningFrame(); + + + PostUpdate?.Invoke(this, null); + } + + public void Dispose() + { + updateTimer.Dispose(); + updateTimer = null; + } + + public void ActiveProfileChanged(ILightEvent profile) + { + if (Global.Configuration.ProfileChangeAnimation) + { + AddOverlayForDuration(new Layer("Profile Close Helper Layer", new GradientFillLayerHandler() + { + Properties = new GradientFillLayerHandlerProperties() + { + _FillEntireKeyboard = true, + _GradientConfig = new LayerEffectConfig(Color.FromArgb(0, 0, 0, 0), Color.FromArgb(255, 0, 0, 0)) { AnimationType = AnimationType.Translate_XY, speed = 10 } + + } + }), 600); + Task.Factory.StartNew(() => + { + Thread.Sleep(450); + + ActiveProfile = profile; + AddOverlayForDuration(new Layer("Profile Open Helper Layer", new GradientFillLayerHandler() + { + Properties = new GradientFillLayerHandlerProperties() + { + _FillEntireKeyboard = true, + _GradientConfig = new LayerEffectConfig(Color.FromArgb(255, 0, 0, 0), Color.FromArgb(0, 0, 0, 0)) { AnimationType = AnimationType.Translate_XY, speed = 10 } + } + }), 900); + + }); + } + else + { + ActiveProfile = profile; + } + } + + public void RefreshOverLayerProfiles(List profiles) + { + OverlayProfiles = profiles; + } + + /// KeyDown handler that checks the current application's profiles for keybinds. + /// In the case of multiple profiles matching the keybind, it will pick the next one as specified in the Application.Profile order. + public void CheckProfileKeybinds(object sender, SharpDX.RawInput.KeyboardInputEventArgs e) + { + ILightEvent profile = ActiveProfile; + + // Check profile is valid and do not switch profiles if the user is trying to enter a keybind + if (profile is Application && Controls.Control_Keybind._ActiveKeybind == null) + { + + // Find all profiles that have their keybinds pressed + List possibleProfiles = new List(); + foreach (var prof in (profile as Application).Profiles) + if (prof.TriggerKeybind.IsPressed()) + possibleProfiles.Add(prof); + + // If atleast one profile has it's key pressed + if (possibleProfiles.Count > 0) + { + // The target profile is the NEXT valid profile after the currently selected one (or the first valid one if the currently selected one doesn't share this keybind) + int trg = (possibleProfiles.IndexOf((profile as Application).Profile) + 1) % possibleProfiles.Count; + (profile as Application).SwitchToProfile(possibleProfiles[trg]); + } + } + } + public void AddOverlayForDuration(Layer overlay_event, int duration) + { + TimedLayers.Add(new TimedListObject(overlay_event, duration, TimedLayers)); + } + + } +} diff --git a/Project-Aurora/Project-Aurora/Profiles/LightingStateManager.cs b/Project-Aurora/Project-Aurora/Profiles/LightingStateManager.cs index ccc6c47df..2d239df59 100755 --- a/Project-Aurora/Project-Aurora/Profiles/LightingStateManager.cs +++ b/Project-Aurora/Project-Aurora/Profiles/LightingStateManager.cs @@ -1,4 +1,4 @@ -using Aurora.Profiles.Aurora_Wrapper; +using Aurora.Profiles.Aurora_Wrapper; using Aurora.Profiles.Desktop; using Aurora.Profiles.Generic_Application; using Aurora.Settings; @@ -18,9 +18,9 @@ using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; -using System.Windows; using System.Windows.Data; using System.Globalization; +using System.Windows; using System.ComponentModel; namespace Aurora.Profiles @@ -39,37 +39,33 @@ void OnDeserialized(StreamingContext context) } } - public class LightingStateManager : ObjectSettings, IInit + public class LightingStateManager : ObjectSettings, IInit, IProcessChanged { - public Dictionary Events { get; private set; } = new Dictionary { { "desktop", new Desktop.Desktop() } }; - public Desktop.Desktop DesktopProfile { get { return (Desktop.Desktop)Events["desktop"]; } } + private ProcessManager ProcessManager; + public LightingEngine LightingEngine; - private List StartedEvents = new List(); - private List UpdatedEvents = new List(); + public Dictionary Events { get; private set; } = new Dictionary { { DesktopProfileName, new Desktop.Desktop() } }; + public Dictionary LayerHandlers { get; private set; } = new Dictionary(); - private Dictionary EventProcesses { get; set; } = new Dictionary(); + public Desktop.Desktop DesktopProfile { get { return (Desktop.Desktop)Events[DesktopProfileName]; } } - private Dictionary EventTitles { get; set; } = new Dictionary(); + private List BackgroundProfile = new List(); + private string CurrentProfile = DesktopProfileName; + private bool PreviewMode = false; + private const string DesktopProfileName = "desktop"; + private Dictionary EventProcesses { get; set; } = new Dictionary(); private Dictionary EventAppIDs { get; set; } = new Dictionary(); - - public Dictionary LayerHandlers { get; private set; } = new Dictionary(); - public string AdditionalProfilesPath = Path.Combine(Global.AppDataDirectory, "AdditionalProfiles"); - public event EventHandler PreUpdate; - public event EventHandler PostUpdate; - - private ActiveProcessMonitor processMonitor; - private RunningProcessMonitor runningProcessMonitor; - public RunningProcessMonitor RunningProcessMonitor => runningProcessMonitor; - public LightingStateManager() { + Global.logger.LogLine("ProfileManager::ProfileManager()"); SettingsSavePath = Path.Combine(Global.AppDataDirectory, "ProfilesSettings.json"); + ProcessManager = new ProcessManager(this); + LightingEngine = new LightingEngine(DesktopProfile); } - public bool Initialized { get; private set; } public bool Initialize() @@ -77,9 +73,6 @@ public bool Initialize() if (Initialized) return true; - processMonitor = new ActiveProcessMonitor(); - runningProcessMonitor = new RunningProcessMonitor(); - // Register all Application types in the assembly var profileTypes = from type in Assembly.GetExecutingAssembly().GetTypes() where type.BaseType == typeof(Application) && type != typeof(GenericApplication) @@ -103,7 +96,7 @@ where type.GetInterfaces().Contains(typeof(ILayerHandler)) LoadSettings(); - LoadPlugins(); + this.LoadPlugins(); if (Directory.Exists(AdditionalProfilesPath)) { @@ -123,10 +116,11 @@ where type.GetInterfaces().Contains(typeof(ILayerHandler)) profile.Value.Initialize(); } - this.InitUpdate(); + LightingEngine.Initialize(); + OpenBackgroundProcess(DesktopProfileName); - // Listen for profile keybind triggers - Global.InputEvents.KeyDown += CheckProfileKeybinds; + //Global.logger.LogLine("ProcessManager::Start()"); + ProcessManager.Start(); Initialized = true; return Initialized; @@ -147,21 +141,21 @@ protected override void LoadSettings(Type settingsType) Global.Configuration.ProfileOrder.Add(kvp.Key); } - foreach(string key in Global.Configuration.ProfileOrder.ToList()) + foreach (string key in Global.Configuration.ProfileOrder.ToList()) { if (!Events.ContainsKey(key) || !(Events[key] is Application)) Global.Configuration.ProfileOrder.Remove(key); } - Global.Configuration.ProfileOrder.Remove("desktop"); - Global.Configuration.ProfileOrder.Insert(0, "desktop"); + Global.Configuration.ProfileOrder.Remove(DesktopProfileName); + Global.Configuration.ProfileOrder.Insert(0, DesktopProfileName); } public void SaveAll() { SaveSettings(); - foreach(var profile in Events) + foreach (var profile in Events) { if (profile.Value is Application) ((Application)profile.Value).SaveAll(); @@ -181,6 +175,8 @@ public bool RegisterEvent(ILightEvent @event) Events.Add(key, @event); + ProcessManager.SubsribeForChange(@event.Config); + if (@event.Config.ProcessNames != null) { foreach (string exe in @event.Config.ProcessNames) @@ -190,10 +186,6 @@ public bool RegisterEvent(ILightEvent @event) } } - if (@event.Config.ProcessTitles != null) - foreach (string titleRx in @event.Config.ProcessTitles) - EventTitles.Add(titleRx, key); - if (!String.IsNullOrWhiteSpace(@event.Config.AppID)) EventAppIDs.Add(@event.Config.AppID, key); @@ -245,31 +237,20 @@ public void RemoveGenericProfile(string key) } } - // Used to match a process's name and optional window title to a profile - public ILightEvent GetProfileFromProcessData(string processName, string processTitle = null) + /// + /// Manually registers a layer. Only needed externally. + /// + public bool RegisterLayer() where T : ILayerHandler { - var processNameProfile = GetProfileFromProcessName(processName); - - if (processNameProfile == null) - return null; - - // Is title matching required? - if (processNameProfile.Config.ProcessTitles != null) - { - var processTitleProfile = GetProfileFromProcessTitle(processTitle); - - if (processTitleProfile != null && processTitleProfile.Equals(processNameProfile)) - { - return processTitleProfile; - } - } else - { - return processNameProfile; - } + var t = typeof(T); + if (LayerHandlers.ContainsKey(t)) return false; + var meta = t.GetCustomAttribute() as LayerHandlerMetaAttribute; + LayerHandlers.Add(t, new LayerHandlerMeta(t, meta)); - return null; + return true; } + public ILightEvent GetProfileFromProcessName(string process) { if (EventProcesses.ContainsKey(process)) @@ -285,18 +266,6 @@ public ILightEvent GetProfileFromProcessName(string process) return null; } - public ILightEvent GetProfileFromProcessTitle(string title) { - foreach (var entry in EventTitles) { - if (Regex.IsMatch(title, entry.Key, RegexOptions.IgnoreCase)) { - if (!Events.ContainsKey(entry.Value)) - Global.logger.Warn($"GetProfileFromProcess: The process with title '{title}' matchs an item in EventTitles but subsequently '{entry.Value}' does not in Events!"); - else - return Events[entry.Value]; // added in an else so we keep searching for more valid regexes. - } - } - return null; - } - public ILightEvent GetProfileFromAppID(string appid) { if (EventAppIDs.ContainsKey(appid)) @@ -311,353 +280,164 @@ public ILightEvent GetProfileFromAppID(string appid) return null; } - /// - /// Manually registers a layer. Only needed externally. - /// - public bool RegisterLayer() where T : ILayerHandler + public void GameStateUpdate(IGameState gs) { - var t = typeof(T); - if (LayerHandlers.ContainsKey(t)) return false; - var meta = t.GetCustomAttribute() as LayerHandlerMetaAttribute; - LayerHandlers.Add(t, new LayerHandlerMeta(t, meta)); - return true; - } + //Debug.WriteLine("Received gs!"); - private Timer updateTimer; + //Global.logger.LogLine(gs.ToString(), Logging_Level.None, false); - private const int defaultTimerInterval = 33; - private int timerInterval = defaultTimerInterval; + //UpdateProcess(); - private long nextProcessNameUpdate; - private long currentTick; - private string previewModeProfileKey = ""; + //string process_name = System.IO.Path.GetFileName(processMonitor.ProcessPath).ToLowerInvariant(); - private List overlays = new List(); - private Event_Idle idle_e = new Event_Idle(); + //EffectsEngine.EffectFrame newFrame = new EffectsEngine.EffectFrame(); +#if DEBUG +#else + try + { +#endif + ILightEvent profile;// = this.GetProfileFromProcess(process_name); - public string PreviewProfileKey { get { return previewModeProfileKey; } set { previewModeProfileKey = value ?? string.Empty; } } - private void InitUpdate() - { - updateTimer = new System.Threading.Timer(g => { - Stopwatch watch = new Stopwatch(); - watch.Start(); - if (Global.isDebug) - Update(); - else - { - try - { - Update(); - } - catch (Exception exc) - { - Global.logger.Error("ProfilesManager.Update() Exception, " + exc); - } - } + JObject provider = Newtonsoft.Json.Linq.JObject.Parse(gs.GetNode("provider")); + string appid = provider.GetValue("appid").ToString(); + string name = provider.GetValue("name").ToString().ToLowerInvariant(); - watch.Stop(); - currentTick += timerInterval + watch.ElapsedMilliseconds; - updateTimer?.Change(Math.Max(timerInterval, 0), Timeout.Infinite); - }, null, 0, System.Threading.Timeout.Infinite); - GC.KeepAlive(updateTimer); - } - - private void UpdateProcess() - { - if (Global.Configuration.detection_mode == ApplicationDetectionMode.ForegroroundApp && (currentTick >= nextProcessNameUpdate)) + if ((profile = GetProfileFromAppID(appid)) != null || (profile = GetProfileFromProcessName(name)) != null) { - processMonitor.GetActiveWindowsProcessname(); - nextProcessNameUpdate = currentTick + 1000L; + IGameState gameState = gs; + if (profile.Config.GameStateType != null) + gameState = (IGameState)Activator.CreateInstance(profile.Config.GameStateType, gs.Json); + profile.SetGameState(gameState); } - } - - private void UpdateIdleEffects(EffectsEngine.EffectFrame newFrame) - { - tagLASTINPUTINFO LastInput = new tagLASTINPUTINFO(); - Int32 IdleTime; - LastInput.cbSize = (uint)Marshal.SizeOf(LastInput); - LastInput.dwTime = 0; - - if (ActiveProcessMonitor.GetLastInputInfo(ref LastInput)) + else if (gs is GameState_Wrapper && Global.Configuration.allow_all_logitech_bitmaps) { - IdleTime = System.Environment.TickCount - LastInput.dwTime; - - if (IdleTime >= Global.Configuration.idle_delay * 60 * 1000) + string gs_process_name = Newtonsoft.Json.Linq.JObject.Parse(gs.GetNode("provider")).GetValue("name").ToString().ToLowerInvariant(); + lock (Events) { - if (!(Global.Configuration.time_based_dimming_enabled && - Utils.Time.IsCurrentTimeBetween(Global.Configuration.time_based_dimming_start_hour, Global.Configuration.time_based_dimming_start_minute, Global.Configuration.time_based_dimming_end_hour, Global.Configuration.time_based_dimming_end_minute)) - ) + profile = profile ?? GetProfileFromProcessName(gs_process_name); + + if (profile == null) { - UpdateEvent(idle_e, newFrame); + Events.Add(gs_process_name, new GameEvent_Aurora_Wrapper(new LightEventConfig { GameStateType = typeof(GameState_Wrapper), ProcessNames = new[] { gs_process_name } })); + profile = Events[gs_process_name]; } + + profile.SetGameState(gs); } } +#if DEBUG +#else + } + catch (Exception e) + { + Global.logger.LogLine("Exception during GameStateUpdate(), error: " + e, Logging_Level.Warning); + } +#endif } - - private void UpdateEvent(ILightEvent @event, EffectsEngine.EffectFrame frame) + + public void ResetGameState(string process) { - StartEvent(@event); - @event.UpdateLights(frame); + ILightEvent profile; + if (((profile = GetProfileFromProcessName(process)) != null)) + profile.ResetGameState(); } - private bool StartEvent(ILightEvent @event) + public void Dispose() { - UpdatedEvents.Add(@event); - - // Skip if event was already started - if (StartedEvents.Contains(@event)) return false; - - StartedEvents.Add(@event); - @event.OnStart(); + ProcessManager.Finish(); + LightingEngine.Dispose(); - return true; + foreach (var app in this.Events) + app.Value.Dispose(); } - private bool StopUnUpdatedEvents() + public void FocusedApplicationChanged(string key) { - // Skip if there are no started events or started events are the same since last update - if (!StartedEvents.Any() || StartedEvents.SequenceEqual(UpdatedEvents)) return false; - - List eventsToStop = StartedEvents.Except(UpdatedEvents).ToList(); - foreach (var eventToStop in eventsToStop) - eventToStop.OnStop(); - - StartedEvents.Clear(); - StartedEvents.AddRange(UpdatedEvents); - - return true; + //Global.logger.LogLine("Focused:FocusedApplicationChanged" + key); + if (key == null) + { + LightingEngine.ActiveProfileChanged(Events[CurrentProfile]); + PreviewMode = false; + } + else + { + LightingEngine.ActiveProfileChanged(Events[key]); + PreviewMode = true; + } + } - private void Update() + public void ActiveProcessChanged(string key) { - PreUpdate?.Invoke(this, null); - UpdatedEvents.Clear(); + key = key ?? DesktopProfileName; + //Global.logger.LogLine("Focused:ActiveProcessChanged" + key); - //Blackout. TODO: Cleanup this a bit. Maybe push blank effect frame to keyboard incase it has existing stuff displayed - if ((Global.Configuration.time_based_dimming_enabled && - Utils.Time.IsCurrentTimeBetween(Global.Configuration.time_based_dimming_start_hour, Global.Configuration.time_based_dimming_start_minute, Global.Configuration.time_based_dimming_end_hour, Global.Configuration.time_based_dimming_end_minute))) + if (Global.Configuration.excluded_programs.Contains(key)) { - StopUnUpdatedEvents(); return; } - - string raw_process_name = Path.GetFileName(processMonitor.ProcessPath); - - UpdateProcess(); - EffectsEngine.EffectFrame newFrame = new EffectsEngine.EffectFrame(); - - - - //TODO: Move these IdleEffects to an event - //this.UpdateIdleEffects(newFrame); + CurrentProfile = Events.Keys.Contains(key) ? key : DesktopProfileName; - ILightEvent profile = GetCurrentProfile(out bool preview); - - timerInterval = profile?.Config?.UpdateInterval ?? defaultTimerInterval; - - // If the current foreground process is excluded from Aurora, disable the lighting manager - if ((profile is Desktop.Desktop && !profile.IsEnabled) || Global.Configuration.excluded_programs.Contains(raw_process_name)) + if (Events[CurrentProfile].IsEnabled) { - StopUnUpdatedEvents(); - Global.dev_manager.Shutdown(); - Global.effengine.PushFrame(newFrame); - return; + LightingEngine.ActiveProfileChanged(Events[CurrentProfile]); } else - Global.dev_manager.InitializeOnce(); - - //Need to do another check in case Desktop is disabled or the selected preview is disabled - if (profile.IsEnabled) - UpdateEvent(profile, newFrame); - - // Overlay layers - if (!preview || Global.Configuration.OverlaysInPreview) { - foreach (var @event in GetOverlayActiveProfiles()) - @event.UpdateOverlayLights(newFrame); - - //Add the Light event that we're previewing to be rendered as an overlay (assuming it's not already active) - if (preview && Global.Configuration.OverlaysInPreview && !GetOverlayActiveProfiles().Contains(profile)) - profile.UpdateOverlayLights(newFrame); - - UpdateIdleEffects(newFrame); + { + LightingEngine.ActiveProfileChanged(Events[DesktopProfileName]); } - - Global.effengine.PushFrame(newFrame); - - StopUnUpdatedEvents(); - PostUpdate?.Invoke(this, null); + //(Global.Configuration.allow_wrappers_in_background && Global.net_listener != null && Global.net_listener.IsWrapperConnected && ((tempProfile = GetProfileFromProcessName(Global.net_listener.WrappedProcess)) != null) && tempProfile.Config.Type == LightEventType.Normal && tempProfile.IsEnabled) } - /// Gets the current application. - /// Boolean indicating whether the application is selected because it is previewing (true) or because the process is open (false). - public ILightEvent GetCurrentProfile(out bool preview) { - string process_name = Path.GetFileName(processMonitor.ProcessPath).ToLower(); - string process_title = processMonitor.GetActiveWindowsProcessTitle(); - ILightEvent profile = null; - ILightEvent tempProfile = null; - preview = false; - - //TODO: GetProfile that checks based on event type - if ((tempProfile = GetProfileFromProcessData(process_name, process_title)) != null && tempProfile.IsEnabled) - profile = tempProfile; - else if ((tempProfile = GetProfileFromProcessName(previewModeProfileKey)) != null) //Don't check for it being Enabled as a preview should always end-up with the previewed profile regardless of it being disabled + public void OpenBackgroundProcess(string key) + { + //Global.logger.LogLine("Focused:OpenBackgroundProcess" + key); + if (Global.Configuration.excluded_programs.Contains(key)) { - profile = tempProfile; - preview = true; - } else if (Global.Configuration.allow_wrappers_in_background && Global.net_listener != null && Global.net_listener.IsWrapperConnected && ((tempProfile = GetProfileFromProcessName(Global.net_listener.WrappedProcess)) != null) && tempProfile.IsEnabled) - profile = tempProfile; - - profile = profile ?? DesktopProfile; - - return profile; - } - /// Gets the current application. - public ILightEvent GetCurrentProfile() => GetCurrentProfile(out bool _); - - /// - /// Returns a list of all profiles that should have their overlays active. This will include processes that running but not in the foreground. - /// - /// - public IEnumerable GetOverlayActiveProfiles() => Events.Values - .Where(evt => evt.IsOverlayEnabled) - .Where(evt => evt.Config.ProcessNames == null || evt.Config.ProcessNames.Any(name => runningProcessMonitor.IsProcessRunning(name))); - //.Where(evt => evt.Config.ProcessTitles == null || ProcessUtils.AnyProcessWithTitleExists(evt.Config.ProcessTitles)); - - /// KeyDown handler that checks the current application's profiles for keybinds. - /// In the case of multiple profiles matching the keybind, it will pick the next one as specified in the Application.Profile order. - public void CheckProfileKeybinds(object sender, SharpDX.RawInput.KeyboardInputEventArgs e) { - ILightEvent profile = GetCurrentProfile(); - - // Check profile is valid and do not switch profiles if the user is trying to enter a keybind - if (profile is Application && Controls.Control_Keybind._ActiveKeybind == null) { - - // Find all profiles that have their keybinds pressed - List possibleProfiles = new List(); - foreach (var prof in (profile as Application).Profiles) - if (prof.TriggerKeybind.IsPressed()) - possibleProfiles.Add(prof); - - // If atleast one profile has it's key pressed - if (possibleProfiles.Count > 0) { - // The target profile is the NEXT valid profile after the currently selected one (or the first valid one if the currently selected one doesn't share this keybind) - int trg = (possibleProfiles.IndexOf((profile as Application).Profile) + 1) % possibleProfiles.Count; - (profile as Application).SwitchToProfile(possibleProfiles[trg]); - } + return; } + BackgroundProfile.Add(key); + Events[key].OnStart(); + RefreshBackroundProfile(); } - - public void GameStateUpdate(IGameState gs) + public void CloseBackgroundProcess(string key) { - //Debug.WriteLine("Received gs!"); - -//Global.logger.LogLine(gs.ToString(), Logging_Level.None, false); - -//UpdateProcess(); - -//string process_name = System.IO.Path.GetFileName(processMonitor.ProcessPath).ToLowerInvariant(); - -//EffectsEngine.EffectFrame newFrame = new EffectsEngine.EffectFrame(); -#if DEBUG -#else - try + //Global.logger.LogLine("Focused:CloseBackgroundProcess" + key); + if(BackgroundProfile.Contains(key)) { -#endif - ILightEvent profile;// = this.GetProfileFromProcess(process_name); - - - JObject provider = Newtonsoft.Json.Linq.JObject.Parse(gs.GetNode("provider")); - string appid = provider.GetValue("appid").ToString(); - string name = provider.GetValue("name").ToString().ToLowerInvariant(); - - if ((profile = GetProfileFromAppID(appid)) != null || (profile = GetProfileFromProcessName(name)) != null) - { - IGameState gameState = gs; - if (profile.Config.GameStateType != null) - gameState = (IGameState)Activator.CreateInstance(profile.Config.GameStateType, gs.Json); - profile.SetGameState(gameState); - } - else if (gs is GameState_Wrapper && Global.Configuration.allow_all_logitech_bitmaps) - { - string gs_process_name = Newtonsoft.Json.Linq.JObject.Parse(gs.GetNode("provider")).GetValue("name").ToString().ToLowerInvariant(); - lock (Events) - { - profile = profile ?? GetProfileFromProcessName(gs_process_name); - - if (profile == null) - { - Events.Add(gs_process_name, new GameEvent_Aurora_Wrapper(new LightEventConfig { GameStateType = typeof(GameState_Wrapper), ProcessNames = new[] { gs_process_name } })); - profile = Events[gs_process_name]; - } - - profile.SetGameState(gs); - } - } -#if DEBUG -#else + BackgroundProfile.Remove(key); + Events[key].OnStop(); + RefreshBackroundProfile(); } - catch (Exception e) - { - Global.logger.LogLine("Exception during GameStateUpdate(), error: " + e, Logging_Level.Warning); - } -#endif - } - - public void ResetGameState(string process) - { - ILightEvent profile; - if (((profile = GetProfileFromProcessName(process)) != null)) - profile.ResetGameState(); + } - public void AddOverlayForDuration(LightEvent overlay_event, int duration, bool isUnique = true) + private void RefreshBackroundProfile() { - if (isUnique) + if (Global.Configuration.OverlaysInPreview || PreviewMode) { - TimedListObject[] overlays_array = overlays.ToArray(); - bool isFound = false; - - foreach (TimedListObject obj in overlays_array) - { - if (obj.item.GetType() == overlay_event.GetType()) - { - isFound = true; - obj.AdjustDuration(duration); - break; - } - } - - if (!isFound) - { - overlays.Add(new TimedListObject(overlay_event, duration, overlays)); - } + LightingEngine.RefreshOverLayerProfiles(Events.Values.Where(p => BackgroundProfile.Contains(p.Config.ID) && p.IsOverlayEnabled).ToList()); } else { - overlays.Add(new TimedListObject(overlay_event, duration, overlays)); + List defaultOverlayerProfile = DesktopProfile.IsOverlayEnabled ? new List { DesktopProfile } : new List(); + LightingEngine.RefreshOverLayerProfiles(defaultOverlayerProfile); } } - - public void Dispose() - { - updateTimer.Dispose(); - updateTimer = null; - - foreach (var app in this.Events) - app.Value.Dispose(); - } } - /// /// POCO that stores data about a type of layer. /// - public class LayerHandlerMeta { + public class LayerHandlerMeta + { /// Creates a new LayerHandlerMeta object from the given meta attribute and type. - public LayerHandlerMeta(Type type, LayerHandlerMetaAttribute attribute) { + public LayerHandlerMeta(Type type, LayerHandlerMetaAttribute attribute) + { Name = attribute?.Name ?? type.Name.CamelCaseToSpaceCase().TrimEndStr(" Layer Handler"); Type = type; IsDefault = attribute?.IsDefault ?? type.Namespace == "Aurora.Settings.Layers"; // if the layer is in the Aurora.Settings.Layers namespace, make the IsDefault true unless otherwise specified. If it is in another namespace, it's probably a custom application layer and so make IsDefault false unless otherwise specified @@ -675,7 +455,8 @@ public LayerHandlerMeta(Type type, LayerHandlerMetaAttribute attribute) { /// Attribute to provide additional meta data about layers for them to be registered. /// [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)] - public class LayerHandlerMetaAttribute : Attribute { + public class LayerHandlerMetaAttribute : Attribute + { /// A different name for the layer. If not specified, will automatically take it from the layer's class name. public string Name { get; set; } @@ -689,3 +470,4 @@ public class LayerHandlerMetaAttribute : Attribute { public int Order { get; set; } = 0; } } + diff --git a/Project-Aurora/Project-Aurora/Profiles/ProcessManager.cs b/Project-Aurora/Project-Aurora/Profiles/ProcessManager.cs new file mode 100644 index 000000000..73ade123e --- /dev/null +++ b/Project-Aurora/Project-Aurora/Profiles/ProcessManager.cs @@ -0,0 +1,183 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Runtime.InteropServices; +using System.Runtime.Serialization; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Data; +using System.Globalization; +using Aurora.Utils; +using Aurora.Settings; + +namespace Aurora.Profiles +{ + public interface IProcessChanged + { + void ActiveProcessChanged(string key); + void OpenBackgroundProcess(string key); + void CloseBackgroundProcess(string key); + } + public class ProcessManager + { + + private static readonly int SleepTime = 3000; + private static bool IsExit = false; + private static Dictionary EventConfigs { get; set; } = new Dictionary(); + private static List RunningBackgroundProcess = new List(); + private static string PreviousActiveProcessKey = null; + + private static ActiveProcessMonitor ProcessMonitor; + private static IProcessChanged Listener; + + public ProcessManager() + { + + } + + public ProcessManager(IProcessChanged listener) + { + Listener = listener; + ProcessMonitor = new ActiveProcessMonitor(); + } + + + public void SubsribeForChange(LightEventConfig processConfig) + { + string key = processConfig.ID; + if (string.IsNullOrWhiteSpace(key) || EventConfigs.ContainsKey(key)) + return; + //Global.logger.LogLine("ProcessManager::SubsribeForChange()" + key); + EventConfigs.Add(key, processConfig); + if (processConfig.ProcessNames != null) + { + for (int i = 0; i < processConfig.ProcessNames.Length; i++) + { + processConfig.ProcessNames[i] = processConfig.ProcessNames[i].ToLower(); + } + } + } + public void Start() + { + IsExit = false; + Thread thread1 = new Thread(UpdateActiveProcess); + Thread thread2 = new Thread(UpdateBackgroundProcess); + thread1.Start(); + thread2.Start(); + } + public void Finish() + { + //Global.logger.LogLine("ProcessManager::Finished()"); + IsExit = true; + } + private static bool TryToMatchProcessTitle(string[] processTitles, string processTitle) + { + // Is title matching required? + if (processTitles != null) + { + if (processTitles.Where(title => Regex.IsMatch(processTitle, title, RegexOptions.IgnoreCase)).Any()) + { + return true; + } + } + else + { + return true; + } + return false; + } + + // Used to match a process's name and optional window title to a profile + private static string GetProfileKeyFromProcessData(string processName, string processTitle = null) + { + string processKeyByName = EventConfigs.Where(ec => ec.Value.ProcessNames.Contains(processName)).Select(ec => ec.Key).First(); + + if (processKeyByName == null) + return null; + + if(TryToMatchProcessTitle(EventConfigs[processKeyByName].ProcessTitles, processTitle)) + { + return processKeyByName; + } + + return null; + } + + private static void UpdateActiveProcess() + { + while (!IsExit) + { + if (Global.Configuration.detection_mode == ApplicationDetectionMode.ForegroroundApp) + { + ProcessMonitor.GetActiveWindowsProcessname(); + string process_name = Path.GetFileName(ProcessMonitor.ProcessPath).ToLower(); + string process_title = ProcessMonitor.GetActiveWindowsProcessTitle(); + + //(Global.Configuration.allow_wrappers_in_background && Global.net_listener != null && Global.net_listener.IsWrapperConnected && ((tempProfile = GetProfileFromProcessName(Global.net_listener.WrappedProcess)) != null) && tempProfile.Config.Type == LightEventType.Normal && tempProfile.IsEnabled) + string process_key = GetProfileKeyFromProcessData(process_name, process_title); + if (process_key != PreviousActiveProcessKey) + { + Listener.ActiveProcessChanged(process_key); + PreviousActiveProcessKey = process_key; + } + + } + Thread.Sleep(SleepTime); + } + + } + private bool IsProcessRunningBackground(LightEventConfig processConfig) + { + foreach (var processName in processConfig.ProcessNames) + { + var processArray = Process.GetProcessesByName(Path.GetFileNameWithoutExtension(processName)); + if (processArray.Length > 0) + { + foreach (var process in processArray) + { + if (TryToMatchProcessTitle(processConfig.ProcessTitles, process.MainWindowTitle)) + { + return true; + } + } + } + } + return false; + } + private void UpdateBackgroundProcess() + { + while (!IsExit) + { + foreach (var config in EventConfigs) + { + if (IsProcessRunningBackground(config.Value)) + { + if (!RunningBackgroundProcess.Contains(config.Key)) + { + RunningBackgroundProcess.Add(config.Key); + Listener.OpenBackgroundProcess(config.Key); + } + } + else + { + if (RunningBackgroundProcess.Contains(config.Key)) + { + RunningBackgroundProcess.Remove(config.Key); + Listener.CloseBackgroundProcess(config.Key); + } + } + } + Thread.Sleep(SleepTime); + } + + } + + } +} + diff --git a/Project-Aurora/Project-Aurora/Project-Aurora.csproj b/Project-Aurora/Project-Aurora/Project-Aurora.csproj index e0b45ea4a..6d55a9019 100644 --- a/Project-Aurora/Project-Aurora/Project-Aurora.csproj +++ b/Project-Aurora/Project-Aurora/Project-Aurora.csproj @@ -177,6 +177,7 @@ Window_Prompt.xaml + @@ -202,7 +203,6 @@ Control_LayerPreview.xaml - Control_CSGODeathLayer.xaml @@ -982,6 +982,8 @@ + + Control_WormsWMD.xaml diff --git a/Project-Aurora/Project-Aurora/Settings/Configuration.cs b/Project-Aurora/Project-Aurora/Settings/Configuration.cs index 2c6040e22..5cf7b8c82 100755 --- a/Project-Aurora/Project-Aurora/Settings/Configuration.cs +++ b/Project-Aurora/Project-Aurora/Settings/Configuration.cs @@ -472,6 +472,8 @@ public class Configuration : INotifyPropertyChanged public bool unified_hid_disabled = false; public HashSet devices_disabled; public bool OverlaysInPreview; + public int FrameRate; + public bool ProfileChangeAnimation; //Blackout and Night theme public bool time_based_dimming_enabled; @@ -556,6 +558,9 @@ public Configuration() devices_disabled.Add(typeof(Devices.AtmoOrbDevice.AtmoOrbDevice)); devices_disabled.Add(typeof(Devices.NZXT.NZXTDevice)); OverlaysInPreview = true; + FrameRate = 30; + ProfileChangeAnimation = true; + //Blackout and Night theme time_based_dimming_enabled = false; diff --git a/Project-Aurora/Project-Aurora/Settings/Control_Settings.xaml b/Project-Aurora/Project-Aurora/Settings/Control_Settings.xaml index b5de9fc0a..723495329 100755 --- a/Project-Aurora/Project-Aurora/Settings/Control_Settings.xaml +++ b/Project-Aurora/Project-Aurora/Settings/Control_Settings.xaml @@ -182,6 +182,11 @@ + + + + + diff --git a/Project-Aurora/Project-Aurora/Settings/Control_Settings.xaml.cs b/Project-Aurora/Project-Aurora/Settings/Control_Settings.xaml.cs index 2b87647a1..35db1ea26 100755 --- a/Project-Aurora/Project-Aurora/Settings/Control_Settings.xaml.cs +++ b/Project-Aurora/Project-Aurora/Settings/Control_Settings.xaml.cs @@ -109,6 +109,9 @@ public Control_Settings() this.nighttime_end_hour_updown.Value = Global.Configuration.nighttime_end_hour; this.nighttime_end_minute_updown.Value = Global.Configuration.nighttime_end_minute; + this.frame_rate_updown.Value = Global.Configuration.FrameRate; + this.profile_change_animation_Checkbox.IsChecked = Global.Configuration.ProfileChangeAnimation; + this.idle_effects_type.SelectedIndex = (int)Global.Configuration.idle_type; this.idle_effects_delay.Value = Global.Configuration.idle_delay; this.idle_effects_primary_color_colorpicker.SelectedColor = Utils.ColorUtils.DrawingColorToMediaColor(Global.Configuration.idle_effect_primary_color); @@ -948,7 +951,15 @@ private void startDelayAmount_ValueChanged(object sender, RoutedPropertyChangedE } } } - + private void chkProfileChangeAnimation_IsCheckedChanged(object sender, RoutedEventArgs e) + { + Global.Configuration.ProfileChangeAnimation = (bool)((CheckBox) sender).IsChecked; + } + private void frame_rate_updown_ValueChanged(object sender, RoutedEventArgs e) + { + Global.Configuration.FrameRate = (int)((IntegerUpDown)sender).Value; + Process.GetCurrentProcess().PriorityClass = Global.Configuration.HighPriority ? ProcessPriorityClass.High : ProcessPriorityClass.Normal; + } private void btnDumpSensors_Click(object sender, RoutedEventArgs e) { if (HardwareMonitor.TryDump()) diff --git a/Project-Aurora/Project-Aurora/Settings/KeyboardLayoutManager.cs b/Project-Aurora/Project-Aurora/Settings/KeyboardLayoutManager.cs index cdbd7419d..80aac4abb 100755 --- a/Project-Aurora/Project-Aurora/Settings/KeyboardLayoutManager.cs +++ b/Project-Aurora/Project-Aurora/Settings/KeyboardLayoutManager.cs @@ -1044,14 +1044,14 @@ private void Configuration_PropertyChanged(object sender, System.ComponentModel. { if (e.PropertyName.Equals(nameof(Configuration.BitmapAccuracy))) { - Global.LightingStateManager.PostUpdate += this.LightingStateManager_PostUpdate; + Global.LightingStateManager.LightingEngine.PostUpdate += this.LightingStateManager_PostUpdate; } } private void LightingStateManager_PostUpdate(object sender, EventArgs e) { this.LoadBrandDefault(); - Global.LightingStateManager.PostUpdate -= this.LightingStateManager_PostUpdate; + Global.LightingStateManager.LightingEngine.PostUpdate -= this.LightingStateManager_PostUpdate; } public void CalculateBitmap() diff --git a/Project-Aurora/Project-Aurora/Settings/Overrides/Logic/Boolean/Boolean_ProcessRunning.cs b/Project-Aurora/Project-Aurora/Settings/Overrides/Logic/Boolean/Boolean_ProcessRunning.cs index 41df0ec8f..54344f487 100644 --- a/Project-Aurora/Project-Aurora/Settings/Overrides/Logic/Boolean/Boolean_ProcessRunning.cs +++ b/Project-Aurora/Project-Aurora/Settings/Overrides/Logic/Boolean/Boolean_ProcessRunning.cs @@ -1,5 +1,8 @@ using Aurora.Profiles; using Aurora.Utils; + +using System.Diagnostics; +using System.IO; using System.ComponentModel; using System.Windows.Controls; using System.Windows.Data; @@ -37,8 +40,9 @@ public override Visual GetControl() { } protected override bool Execute(IGameState gameState) - => Global.LightingStateManager.RunningProcessMonitor.IsProcessRunning(ProcessName); - + => Process.GetProcessesByName(Path.GetFileNameWithoutExtension(ProcessName)).Length > 0; + public override Evaluatable Clone() => new BooleanProcessRunning { ProcessName = ProcessName }; + } } \ No newline at end of file