mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-13 05:48:35 +00:00
Major stability improvements
This commit is contained in:
parent
ca6c020385
commit
c0a839fa6f
@ -23,6 +23,7 @@ namespace Artemis.Managers
|
|||||||
|
|
||||||
public List<EffectModel> EffectModels { get; set; }
|
public List<EffectModel> EffectModels { get; set; }
|
||||||
public EffectModel ActiveEffect { get; private set; }
|
public EffectModel ActiveEffect { get; private set; }
|
||||||
|
public EffectModel PauseEffect { get; private set; }
|
||||||
|
|
||||||
public IEnumerable<OverlayModel> EnabledOverlays
|
public IEnumerable<OverlayModel> EnabledOverlays
|
||||||
{
|
{
|
||||||
@ -75,11 +76,33 @@ namespace Artemis.Managers
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If it's not running, change the effect and start it afterwards.
|
// If it's not running start it, and let the next recursion handle changing the effect
|
||||||
ActiveEffect = effectModel;
|
_mainManager.Start(effectModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ChangeEffectWithPause(EffectModel effectModel)
|
||||||
|
{
|
||||||
|
if (PauseEffect != null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
PauseEffect = effectModel;
|
||||||
|
_mainManager.Pause();
|
||||||
|
_mainManager.PauseCallback += MainManagerOnPauseCallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void MainManagerOnPauseCallback()
|
||||||
|
{
|
||||||
|
// Change effect logic
|
||||||
|
ActiveEffect?.Dispose();
|
||||||
|
|
||||||
|
ActiveEffect = PauseEffect;
|
||||||
ActiveEffect.Enable();
|
ActiveEffect.Enable();
|
||||||
|
|
||||||
_mainManager.Start(effectModel);
|
// Let the ViewModels know
|
||||||
|
_events.PublishOnUIThread(new ActiveEffectChanged(ActiveEffect.Name));
|
||||||
|
|
||||||
|
PauseEffect = null;
|
||||||
|
_mainManager.Unpause();
|
||||||
|
|
||||||
if (ActiveEffect is GameModel)
|
if (ActiveEffect is GameModel)
|
||||||
return;
|
return;
|
||||||
@ -87,20 +110,6 @@ namespace Artemis.Managers
|
|||||||
// Non-game effects are stored as the new LastEffect.
|
// Non-game effects are stored as the new LastEffect.
|
||||||
General.Default.LastEffect = ActiveEffect.Name;
|
General.Default.LastEffect = ActiveEffect.Name;
|
||||||
General.Default.Save();
|
General.Default.Save();
|
||||||
|
|
||||||
// Let the ViewModels know
|
|
||||||
_events.PublishOnUIThread(new ActiveEffectChanged(ActiveEffect.Name));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ChangeEffectWithPause(EffectModel effectModel)
|
|
||||||
{
|
|
||||||
_mainManager.Pause(effectModel);
|
|
||||||
_mainManager.PauseCallback += MainManagerOnPauseCallback;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void MainManagerOnPauseCallback(EffectModel callbackEffect)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -108,6 +117,10 @@ namespace Artemis.Managers
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void ClearEffect()
|
public void ClearEffect()
|
||||||
{
|
{
|
||||||
|
// Don't mess with the ActiveEffect if in the process of changing the effect.
|
||||||
|
if (PauseEffect != null)
|
||||||
|
return;
|
||||||
|
|
||||||
if (ActiveEffect == null)
|
if (ActiveEffect == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|||||||
249
Artemis/Artemis/Managers/MainManager.cs
Normal file
249
Artemis/Artemis/Managers/MainManager.cs
Normal file
@ -0,0 +1,249 @@
|
|||||||
|
using System;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading;
|
||||||
|
using Artemis.Events;
|
||||||
|
using Artemis.Models;
|
||||||
|
using Artemis.Utilities.GameState;
|
||||||
|
using Artemis.Utilities.Keyboard;
|
||||||
|
using Caliburn.Micro;
|
||||||
|
|
||||||
|
namespace Artemis.Managers
|
||||||
|
{
|
||||||
|
public class MainManager
|
||||||
|
{
|
||||||
|
public delegate void PauseCallbackHandler();
|
||||||
|
|
||||||
|
private readonly int _fps;
|
||||||
|
private readonly BackgroundWorker _processWorker;
|
||||||
|
private bool _paused;
|
||||||
|
|
||||||
|
public MainManager(IEventAggregator events)
|
||||||
|
{
|
||||||
|
Events = events;
|
||||||
|
|
||||||
|
KeyboardManager = new KeyboardManager(this);
|
||||||
|
EffectManager = new EffectManager(this, Events);
|
||||||
|
KeyboardHook = new KeyboardHook();
|
||||||
|
|
||||||
|
_fps = 25;
|
||||||
|
UpdateWorker = new BackgroundWorker {WorkerSupportsCancellation = true};
|
||||||
|
_processWorker = new BackgroundWorker();
|
||||||
|
UpdateWorker.DoWork += UpdateWorker_DoWork;
|
||||||
|
_processWorker.DoWork += ProcessWorker_DoWork;
|
||||||
|
|
||||||
|
// Process worker will always run (and just do nothing when ProgramEnabled is false)
|
||||||
|
_processWorker.RunWorkerAsync();
|
||||||
|
|
||||||
|
ProgramEnabled = false;
|
||||||
|
Running = false;
|
||||||
|
|
||||||
|
// Create and start the web server
|
||||||
|
GameStateWebServer = new GameStateWebServer();
|
||||||
|
GameStateWebServer.Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public BackgroundWorker UpdateWorker { get; set; }
|
||||||
|
|
||||||
|
public KeyboardManager KeyboardManager { get; set; }
|
||||||
|
public EffectManager EffectManager { get; set; }
|
||||||
|
|
||||||
|
public KeyboardHook KeyboardHook { get; set; }
|
||||||
|
|
||||||
|
public GameStateWebServer GameStateWebServer { get; set; }
|
||||||
|
public IEventAggregator Events { get; set; }
|
||||||
|
|
||||||
|
public bool ProgramEnabled { get; private set; }
|
||||||
|
public bool Suspended { get; set; }
|
||||||
|
|
||||||
|
public bool Running { get; private set; }
|
||||||
|
public event PauseCallbackHandler PauseCallback;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Take control of the keyboard and start sending data to it
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>Whether starting was successful or not</returns>
|
||||||
|
public bool Start(EffectModel effect = null)
|
||||||
|
{
|
||||||
|
// Can't take control when not enabled
|
||||||
|
if (!ProgramEnabled || UpdateWorker.CancellationPending || UpdateWorker.IsBusy || _paused)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Do nothing if already running
|
||||||
|
if (Running)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// Only continue if a keyboard was loaded
|
||||||
|
if (!KeyboardManager.LoadLastKeyboard())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Running = true;
|
||||||
|
if (effect != null)
|
||||||
|
EffectManager.ChangeEffect(effect);
|
||||||
|
|
||||||
|
// Start the update worker
|
||||||
|
if (!UpdateWorker.IsBusy)
|
||||||
|
UpdateWorker.RunWorkerAsync();
|
||||||
|
|
||||||
|
return Running;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Releases control of the keyboard and stop sending data to it
|
||||||
|
/// </summary>
|
||||||
|
public void Stop()
|
||||||
|
{
|
||||||
|
if (!Running || UpdateWorker.CancellationPending || _paused)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Stop the update worker
|
||||||
|
UpdateWorker.CancelAsync();
|
||||||
|
UpdateWorker.RunWorkerCompleted += FinishStop;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void FinishStop(object sender, RunWorkerCompletedEventArgs e)
|
||||||
|
{
|
||||||
|
KeyboardManager.ReleaseActiveKeyboard();
|
||||||
|
Running = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Pause()
|
||||||
|
{
|
||||||
|
if (!Running || UpdateWorker.CancellationPending || _paused)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_paused = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Unpause()
|
||||||
|
{
|
||||||
|
if (!_paused)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_paused = false;
|
||||||
|
PauseCallback = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Loads the last active effect and starts the program
|
||||||
|
/// </summary>
|
||||||
|
public void EnableProgram()
|
||||||
|
{
|
||||||
|
ProgramEnabled = true;
|
||||||
|
Start(EffectManager.GetLastEffect());
|
||||||
|
Events.PublishOnUIThread(new ToggleEnabled(ProgramEnabled));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Stops the program
|
||||||
|
/// </summary>
|
||||||
|
public void DisableProgram()
|
||||||
|
{
|
||||||
|
Stop();
|
||||||
|
ProgramEnabled = false;
|
||||||
|
Events.PublishOnUIThread(new ToggleEnabled(ProgramEnabled));
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Workers
|
||||||
|
|
||||||
|
private void UpdateWorker_DoWork(object sender, DoWorkEventArgs e)
|
||||||
|
{
|
||||||
|
var sw = new Stopwatch();
|
||||||
|
while (!UpdateWorker.CancellationPending)
|
||||||
|
{
|
||||||
|
// Skip frame when paused
|
||||||
|
if (_paused)
|
||||||
|
{
|
||||||
|
PauseCallback?.Invoke();
|
||||||
|
Thread.Sleep(1000 / _fps);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stop if no keyboard/effect are present
|
||||||
|
if (KeyboardManager.ActiveKeyboard == null || EffectManager.ActiveEffect == null)
|
||||||
|
{
|
||||||
|
Thread.Sleep(1000/_fps);
|
||||||
|
Stop();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Don't stop when the effect is still initialized, just skip this frame
|
||||||
|
if (!EffectManager.ActiveEffect.Initialized)
|
||||||
|
{
|
||||||
|
Thread.Sleep(1000/_fps);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
sw.Start();
|
||||||
|
|
||||||
|
// Update the current effect
|
||||||
|
if (EffectManager.ActiveEffect.Initialized)
|
||||||
|
EffectManager.ActiveEffect.Update();
|
||||||
|
|
||||||
|
// Get ActiveEffect's bitmap
|
||||||
|
var bitmap = EffectManager.ActiveEffect.Initialized
|
||||||
|
? EffectManager.ActiveEffect.GenerateBitmap()
|
||||||
|
: null;
|
||||||
|
|
||||||
|
// Draw enabled overlays on top
|
||||||
|
foreach (var overlayModel in EffectManager.EnabledOverlays)
|
||||||
|
{
|
||||||
|
overlayModel.Update();
|
||||||
|
bitmap = bitmap != null ? overlayModel.GenerateBitmap(bitmap) : overlayModel.GenerateBitmap();
|
||||||
|
}
|
||||||
|
|
||||||
|
// If it exists, send bitmap to the device
|
||||||
|
if (bitmap != null && KeyboardManager.ActiveKeyboard != null)
|
||||||
|
{
|
||||||
|
KeyboardManager.ActiveKeyboard.DrawBitmap(bitmap);
|
||||||
|
|
||||||
|
// debugging TODO: Disable when window isn't shown
|
||||||
|
Events.PublishOnUIThread(new ChangeBitmap(bitmap));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sleep according to time left this frame
|
||||||
|
var sleep = (int) (1000/_fps - sw.ElapsedMilliseconds);
|
||||||
|
if (sleep > 0)
|
||||||
|
Thread.Sleep(sleep);
|
||||||
|
sw.Reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ProcessWorker_DoWork(object sender, DoWorkEventArgs e)
|
||||||
|
{
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
if (!ProgramEnabled)
|
||||||
|
{
|
||||||
|
Thread.Sleep(1000);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var runningProcesses = Process.GetProcesses();
|
||||||
|
|
||||||
|
// If the currently active effect is a disabled game, get rid of it.
|
||||||
|
if (EffectManager.ActiveEffect != null)
|
||||||
|
EffectManager.DisableInactiveGame();
|
||||||
|
|
||||||
|
// If the currently active effect is a no longer running game, get rid of it.
|
||||||
|
var activeGame = EffectManager.ActiveEffect as GameModel;
|
||||||
|
if (activeGame != null)
|
||||||
|
if (runningProcesses.All(p => p.ProcessName != activeGame.ProcessName))
|
||||||
|
EffectManager.DisableGame(activeGame);
|
||||||
|
|
||||||
|
// 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));
|
||||||
|
|
||||||
|
// If it's not already enabled, do so.
|
||||||
|
if (newGame != null && EffectManager.ActiveEffect != newGame)
|
||||||
|
EffectManager.ChangeEffect(newGame);
|
||||||
|
|
||||||
|
Thread.Sleep(1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -37,15 +37,8 @@
|
|||||||
<Label Content="Enable effect" Margin="0 3 0 0" HorizontalAlignment="Right" />
|
<Label Content="Enable effect" Margin="0 3 0 0" HorizontalAlignment="Right" />
|
||||||
<ToggleButton x:Name="EffectEnabled" Margin="0 3 0 0" Width="25" Height="25"
|
<ToggleButton x:Name="EffectEnabled" Margin="0 3 0 0" Width="25" Height="25"
|
||||||
Style="{DynamicResource MetroCircleToggleButtonStyle}"
|
Style="{DynamicResource MetroCircleToggleButtonStyle}"
|
||||||
cal:Message.Attach="[Event Click] = [Action ToggleEffect]" />
|
cal:Message.Attach="[Event Click] = [Action ToggleEffect]"
|
||||||
<Popup PlacementTarget="{Binding ElementName=EffectEnabled}"
|
ToolTip="Note: You can't enable an effect when Artemis is disabled"/>
|
||||||
IsOpen="{Binding Path=ShowDisabledPopup, Mode=TwoWay}" Placement="Left" VerticalOffset="-10"
|
|
||||||
PopupAnimation="Fade" StaysOpen="False">
|
|
||||||
<Border Margin="1">
|
|
||||||
<TextBlock Background="{DynamicResource AccentColorBrush}" Foreground="{DynamicResource IdealForegroundColorBrush}"
|
|
||||||
Text="You can't enable an effect when Artemis is disabled" Padding="4" />
|
|
||||||
</Border>
|
|
||||||
</Popup>
|
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
<!-- Top color -->
|
<!-- Top color -->
|
||||||
|
|||||||
@ -35,15 +35,9 @@
|
|||||||
<Label Content="Enable effect" Margin="0 3 0 0" HorizontalAlignment="Right" />
|
<Label Content="Enable effect" Margin="0 3 0 0" HorizontalAlignment="Right" />
|
||||||
<ToggleButton x:Name="EffectEnabled" Margin="0 3 0 0" Width="25" Height="25"
|
<ToggleButton x:Name="EffectEnabled" Margin="0 3 0 0" Width="25" Height="25"
|
||||||
Style="{DynamicResource MetroCircleToggleButtonStyle}"
|
Style="{DynamicResource MetroCircleToggleButtonStyle}"
|
||||||
cal:Message.Attach="[Event Click] = [Action ToggleEffect]" />
|
cal:Message.Attach="[Event Click] = [Action ToggleEffect]"
|
||||||
<Popup PlacementTarget="{Binding ElementName=EffectEnabled}"
|
ToolTip="Note: You can't enable an effect when Artemis is disabled"
|
||||||
IsOpen="{Binding Path=ShowDisabledPopup, Mode=TwoWay}" Placement="Left" VerticalOffset="-10"
|
ToolTipService.ShowOnDisabled="True"/>
|
||||||
PopupAnimation="Fade" StaysOpen="False">
|
|
||||||
<Border Margin="1">
|
|
||||||
<TextBlock Background="{DynamicResource AccentColorBrush}" Foreground="{DynamicResource IdealForegroundColorBrush}"
|
|
||||||
Text="You can't enable an effect when Artemis is disabled" Padding="4" />
|
|
||||||
</Border>
|
|
||||||
</Popup>
|
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
|
|||||||
@ -1,95 +1,93 @@
|
|||||||
<UserControl x:Class="Artemis.Modules.Games.RocketLeague.RocketLeagueView"
|
<UserControl x:Class="Artemis.Modules.Games.RocketLeague.RocketLeagueView"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
|
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
|
||||||
xmlns:cal="http://www.caliburnproject.org"
|
xmlns:cal="http://www.caliburnproject.org"
|
||||||
xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls"
|
xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
d:DesignHeight="476.986" d:DesignWidth="538.772">
|
d:DesignHeight="476.986" d:DesignWidth="538.772">
|
||||||
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto">
|
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto">
|
||||||
<Grid Margin="15, 5, 15, 5">
|
<Grid Margin="15, 5, 15, 5">
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="Auto" />
|
<ColumnDefinition Width="Auto" />
|
||||||
<ColumnDefinition />
|
<ColumnDefinition />
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
<RowDefinition Height="Auto" />
|
<RowDefinition Height="Auto" />
|
||||||
<RowDefinition Height="Auto" />
|
<RowDefinition Height="Auto" />
|
||||||
<RowDefinition Height="Auto" />
|
<RowDefinition Height="Auto" />
|
||||||
<RowDefinition Height="Auto" />
|
<RowDefinition Height="Auto" />
|
||||||
<RowDefinition Height="Auto" />
|
<RowDefinition Height="Auto" />
|
||||||
<RowDefinition Height="Auto" />
|
<RowDefinition Height="Auto" />
|
||||||
<RowDefinition Height="*" />
|
<RowDefinition Height="*" />
|
||||||
|
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
<StackPanel Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" Margin="0,0,1,0">
|
<StackPanel Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" Margin="0,0,1,0">
|
||||||
<Label FontSize="20" HorizontalAlignment="Left">
|
<Label FontSize="20" HorizontalAlignment="Left">
|
||||||
<Label.Content>
|
<Label.Content>
|
||||||
<AccessText TextWrapping="Wrap"
|
<AccessText TextWrapping="Wrap"
|
||||||
Text="Shows your boost amount on the keyboard." />
|
Text="Shows your boost amount on the keyboard." />
|
||||||
</Label.Content>
|
</Label.Content>
|
||||||
</Label>
|
</Label>
|
||||||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
|
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
|
||||||
<Label Content="Enable effect" Margin="0 3 0 0" HorizontalAlignment="Right" />
|
<Label Content="Enable effect" Margin="0 3 0 0" HorizontalAlignment="Right" />
|
||||||
<ToggleButton x:Name="EffectEnabled" Margin="0 3 0 0" Width="25" Height="25"
|
<ToggleButton x:Name="EffectEnabled" Margin="0 3 0 0" Width="25" Height="25"
|
||||||
IsChecked="{Binding Path=RocketLeagueSettings.Enabled, Mode=TwoWay}"
|
IsChecked="{Binding Path=RocketLeagueSettings.Enabled, Mode=TwoWay}"
|
||||||
Style="{DynamicResource MetroCircleToggleButtonStyle}"
|
Style="{DynamicResource MetroCircleToggleButtonStyle}"
|
||||||
cal:Message.Attach="[Event Click] = [Action ToggleEffect]" />
|
cal:Message.Attach="[Event Click] = [Action ToggleEffect]" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
<!-- Main color -->
|
<!-- Main color -->
|
||||||
<TextBlock Grid.Row="1" Grid.Column="0" HorizontalAlignment="Left" VerticalAlignment="Center"
|
<TextBlock Grid.Row="1" Grid.Column="0" HorizontalAlignment="Left" VerticalAlignment="Center"
|
||||||
Height="16" Margin="0,8">
|
Height="16" Margin="0,8">
|
||||||
Main boost display color
|
Main boost display color
|
||||||
</TextBlock>
|
</TextBlock>
|
||||||
<xctk:ColorPicker x:Name="MainColor"
|
<xctk:ColorPicker x:Name="MainColor"
|
||||||
SelectedColor="{Binding Path=RocketLeagueSettings.MainColor, Mode=TwoWay}"
|
SelectedColor="{Binding Path=RocketLeagueSettings.MainColor, Mode=TwoWay}"
|
||||||
Grid.Row="1" Grid.Column="1" Width="110" HorizontalAlignment="Right"
|
Grid.Row="1" Grid.Column="1" Width="110" HorizontalAlignment="Right"
|
||||||
VerticalAlignment="Center" Margin="0,5,-1,5" Height="22" />
|
VerticalAlignment="Center" Margin="0,5,-1,5" Height="22" />
|
||||||
|
|
||||||
<!-- Secondary color -->
|
<!-- Secondary color -->
|
||||||
<TextBlock Grid.Row="2" Grid.Column="0" HorizontalAlignment="Left" VerticalAlignment="Center"
|
<TextBlock Grid.Row="2" Grid.Column="0" HorizontalAlignment="Left" VerticalAlignment="Center"
|
||||||
Height="16" Margin="0,8">
|
Height="16" Margin="0,8">
|
||||||
Secondary boost display color
|
Secondary boost display color
|
||||||
</TextBlock>
|
</TextBlock>
|
||||||
<xctk:ColorPicker x:Name="SecondaryColor"
|
<xctk:ColorPicker x:Name="SecondaryColor"
|
||||||
SelectedColor="{Binding Path=RocketLeagueSettings.SecondaryColor, Mode=TwoWay}"
|
SelectedColor="{Binding Path=RocketLeagueSettings.SecondaryColor, Mode=TwoWay}"
|
||||||
Grid.Row="2" Grid.Column="1" Width="110" HorizontalAlignment="Right"
|
Grid.Row="2" Grid.Column="1" Width="110" HorizontalAlignment="Right"
|
||||||
VerticalAlignment="Center" Margin="0,5,-1,5" Height="22" />
|
VerticalAlignment="Center" Margin="0,5,-1,5" Height="22" />
|
||||||
|
|
||||||
<!-- Secondary color -->
|
<!-- Secondary color -->
|
||||||
<TextBlock Grid.Row="3" Grid.Column="0" HorizontalAlignment="Left" VerticalAlignment="Center"
|
<TextBlock Grid.Row="3" Grid.Column="0" HorizontalAlignment="Left" VerticalAlignment="Center"
|
||||||
Height="16" Margin="0,8">
|
Height="16" Margin="0,8">
|
||||||
Color bar according to boost amount
|
Color bar according to boost amount
|
||||||
</TextBlock>
|
</TextBlock>
|
||||||
<controls:ToggleSwitch IsChecked="{Binding Path=RocketLeagueSettings.ContextualColor, Mode=TwoWay}"
|
<controls:ToggleSwitch IsChecked="{Binding Path=RocketLeagueSettings.ContextualColor, Mode=TwoWay}"
|
||||||
Grid.Row="3" Grid.Column="1" HorizontalAlignment="Right" OnLabel="Yes" OffLabel="No"
|
Grid.Row="3" Grid.Column="1" HorizontalAlignment="Right" OnLabel="Yes" OffLabel="No"
|
||||||
Margin="0,0,-5,0" Width="114" />
|
Margin="0,0,-5,0" Width="114" />
|
||||||
|
|
||||||
<!-- Info text -->
|
<!-- Info text -->
|
||||||
<TextBlock Grid.Row="4" Grid.Column="0" Grid.ColumnSpan="2" VerticalAlignment="Center" Margin="0,8"
|
<TextBlock Grid.Row="4" Grid.Column="0" Grid.ColumnSpan="2" VerticalAlignment="Center" Margin="0,8"
|
||||||
TextWrapping="Wrap" HorizontalAlignment="Left" FontFamily="Segoe UI Semibold"
|
TextWrapping="Wrap" HorizontalAlignment="Left" FontFamily="Segoe UI Semibold"
|
||||||
Foreground="#535353" MaxWidth="510" TextAlignment="Justify">
|
MaxWidth="510" TextAlignment="Justify">
|
||||||
Tip: To find a color combination you like, start an exhibition match, pickup 100 boost and play around with the colors.
|
Tip: To find a color combination you like, start an exhibition match, pickup 100 boost and play around with the colors.
|
||||||
They'll appear on your keyboard immediately! Once you're satisfied don't forget to click save changes.
|
They'll appear on your keyboard immediately! Once you're satisfied don't forget to click save changes.
|
||||||
</TextBlock>
|
</TextBlock>
|
||||||
<TextBlock Grid.Row="5" Grid.Column="0" Grid.ColumnSpan="2" VerticalAlignment="Center" Margin="0,8"
|
<TextBlock x:Name="VersionText" Grid.Row="5" Grid.Column="0" Grid.ColumnSpan="2" VerticalAlignment="Center" Margin="0,8"
|
||||||
TextWrapping="Wrap" HorizontalAlignment="Left" FontFamily="Segoe UI Semibold"
|
TextWrapping="Wrap" HorizontalAlignment="Left" FontFamily="Segoe UI Semibold"
|
||||||
Foreground="#535353" MaxWidth="510" TextAlignment="Justify">
|
Foreground="{DynamicResource HighlightBrush}" MaxWidth="510" TextAlignment="Justify"/>
|
||||||
Note: Requires patch x.x. When a new patch is released Artemis downloads new pointers for the latest version (unless disabled in settings).
|
|
||||||
</TextBlock>
|
<!-- Buttons -->
|
||||||
|
<StackPanel Grid.Column="0" Grid.Row="9" Orientation="Horizontal" VerticalAlignment="Bottom">
|
||||||
<!-- Buttons -->
|
<Button x:Name="ResetSettings" Content="Reset effect" VerticalAlignment="Top" Width="100"
|
||||||
<StackPanel Grid.Column="0" Grid.Row="9" Orientation="Horizontal" VerticalAlignment="Bottom">
|
Style="{DynamicResource SquareButtonStyle}" />
|
||||||
<Button x:Name="ResetSettings" Content="Reset effect" VerticalAlignment="Top" Width="100"
|
<Button x:Name="SaveSettings" Content="Save changes" VerticalAlignment="Top" Width="100"
|
||||||
Style="{DynamicResource SquareButtonStyle}" />
|
Margin="10,0,0,0"
|
||||||
<Button x:Name="SaveSettings" Content="Save changes" VerticalAlignment="Top" Width="100"
|
Style="{DynamicResource SquareButtonStyle}" />
|
||||||
Margin="10,0,0,0"
|
</StackPanel>
|
||||||
Style="{DynamicResource SquareButtonStyle}" />
|
</Grid>
|
||||||
</StackPanel>
|
</ScrollViewer>
|
||||||
</Grid>
|
|
||||||
</ScrollViewer>
|
|
||||||
</UserControl>
|
</UserControl>
|
||||||
@ -1,11 +1,16 @@
|
|||||||
using Artemis.Managers;
|
using Artemis.Managers;
|
||||||
|
using Artemis.Models;
|
||||||
|
using Artemis.Settings;
|
||||||
|
using Artemis.Utilities.Memory;
|
||||||
using Caliburn.Micro;
|
using Caliburn.Micro;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace Artemis.Modules.Games.RocketLeague
|
namespace Artemis.Modules.Games.RocketLeague
|
||||||
{
|
{
|
||||||
public class RocketLeagueViewModel : Screen
|
public class RocketLeagueViewModel : Screen
|
||||||
{
|
{
|
||||||
private RocketLeagueSettings _rocketLeagueSettings;
|
private RocketLeagueSettings _rocketLeagueSettings;
|
||||||
|
private string _versionText;
|
||||||
|
|
||||||
public RocketLeagueViewModel(MainManager mainManager)
|
public RocketLeagueViewModel(MainManager mainManager)
|
||||||
{
|
{
|
||||||
@ -17,6 +22,19 @@ namespace Artemis.Modules.Games.RocketLeague
|
|||||||
// Create effect model and add it to MainManager
|
// Create effect model and add it to MainManager
|
||||||
RocketLeagueModel = new RocketLeagueModel(mainManager, RocketLeagueSettings);
|
RocketLeagueModel = new RocketLeagueModel(mainManager, RocketLeagueSettings);
|
||||||
MainManager.EffectManager.EffectModels.Add(RocketLeagueModel);
|
MainManager.EffectManager.EffectModels.Add(RocketLeagueModel);
|
||||||
|
|
||||||
|
SetVersionText();
|
||||||
|
}
|
||||||
|
|
||||||
|
public string VersionText
|
||||||
|
{
|
||||||
|
get { return _versionText; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value == _versionText) return;
|
||||||
|
_versionText = value;
|
||||||
|
NotifyOfPropertyChange(() => VersionText);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string Name => "Rocket League";
|
public static string Name => "Rocket League";
|
||||||
@ -35,6 +53,23 @@ namespace Artemis.Modules.Games.RocketLeague
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void SetVersionText()
|
||||||
|
{
|
||||||
|
if (!General.Default.EnablePointersUpdate)
|
||||||
|
{
|
||||||
|
VersionText = "Note: You disabled pointer updates, this could result in the " +
|
||||||
|
"Rocket League effect not working after a game update.";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MemoryHelpers.GetPointers();
|
||||||
|
var version = JsonConvert
|
||||||
|
.DeserializeObject<GamePointersCollectionModel>(Offsets.Default.RocketLeague)
|
||||||
|
.GameVersion;
|
||||||
|
VersionText = $"Note: Requires patch {version}. When a new patch is released Artemis downloads " +
|
||||||
|
"new pointers for the latest version (unless disabled in settings).";
|
||||||
|
}
|
||||||
|
|
||||||
public void SaveSettings()
|
public void SaveSettings()
|
||||||
{
|
{
|
||||||
if (RocketLeagueModel == null)
|
if (RocketLeagueModel == null)
|
||||||
|
|||||||
@ -87,21 +87,21 @@ namespace Artemis.Modules.Games.Witcher3
|
|||||||
return;
|
return;
|
||||||
var sign = signRes.Groups[1].Value;
|
var sign = signRes.Groups[1].Value;
|
||||||
|
|
||||||
switch (sign)
|
switch (sign)
|
||||||
{
|
{
|
||||||
case "ST_Aard\r":
|
case "ST_Aard\r":
|
||||||
_signRect.Colors = new List<Color> {Color.DeepSkyBlue, Color.Blue};
|
_signRect.Colors = new List<Color> {Color.DeepSkyBlue, Color.Blue};
|
||||||
break;
|
break;
|
||||||
case "ST_Yrden\r":
|
case "ST_Yrden\r":
|
||||||
_signRect.Colors = new List<Color> {Color.Purple, Color.DeepPink};
|
_signRect.Colors = new List<Color> {Color.Purple, Color.DeepPink};
|
||||||
break;
|
break;
|
||||||
case "ST_Igni\r":
|
case "ST_Igni\r":
|
||||||
_signRect.Colors = new List<Color> {Color.DarkOrange, Color.Red};
|
_signRect.Colors = new List<Color> {Color.DarkOrange, Color.Red};
|
||||||
break;
|
break;
|
||||||
case "ST_Quen\r":
|
case "ST_Quen\r":
|
||||||
_signRect.Colors = new List<Color> {Color.DarkOrange, Color.FromArgb(232, 193, 0)};
|
_signRect.Colors = new List<Color> {Color.DarkOrange, Color.FromArgb(232, 193, 0)};
|
||||||
break;
|
break;
|
||||||
case "ST_Axii\r":
|
case "ST_Axii\r":
|
||||||
_signRect.Colors = new List<Color> {Color.LawnGreen, Color.DarkGreen};
|
_signRect.Colors = new List<Color> {Color.LawnGreen, Color.DarkGreen};
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -36,14 +36,14 @@
|
|||||||
</StackPanel>
|
</StackPanel>
|
||||||
<TextBlock Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" VerticalAlignment="Center" Margin="0,8"
|
<TextBlock Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" VerticalAlignment="Center" Margin="0,8"
|
||||||
TextWrapping="Wrap" HorizontalAlignment="Left" FontFamily="Segoe UI Semibold"
|
TextWrapping="Wrap" HorizontalAlignment="Left" FontFamily="Segoe UI Semibold"
|
||||||
Foreground="#535353" MaxWidth="510" TextAlignment="Justify">
|
MaxWidth="510" TextAlignment="Justify">
|
||||||
Artemis requires the latest Witcher 3 version and mod to be installed in order to work. If you don't use any (conflicting) Witcher 3 mods, the mod can automatically be installed.
|
Artemis requires the latest Witcher 3 version and mod to be installed in order to work. If you don't use any (conflicting) Witcher 3 mods, the mod can automatically be installed.
|
||||||
</TextBlock>
|
</TextBlock>
|
||||||
|
|
||||||
<TextBlock Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2" VerticalAlignment="Center" Margin="0,8"
|
<TextBlock Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2" VerticalAlignment="Center" Margin="0,8"
|
||||||
TextWrapping="Wrap" HorizontalAlignment="Left" FontFamily="Segoe UI Semibold"
|
TextWrapping="Wrap" HorizontalAlignment="Left" FontFamily="Segoe UI Semibold"
|
||||||
Foreground="#535353" MaxWidth="510" TextAlignment="Justify">
|
Foreground="{DynamicResource HighlightBrush}" MaxWidth="510" TextAlignment="Justify">
|
||||||
If you do use conflicting mods, we'll let you know what to do.
|
Note: If you do use conflicting mods, we'll let you know what to do.
|
||||||
</TextBlock>
|
</TextBlock>
|
||||||
<Button Grid.Row="3" Grid.Column="0" x:Name="AutoInstall" Content="Try automatic mod install" Width="160"
|
<Button Grid.Row="3" Grid.Column="0" x:Name="AutoInstall" Content="Try automatic mod install" Width="160"
|
||||||
Style="{DynamicResource SquareButtonStyle}" HorizontalAlignment="Left" Margin="0,20,0,0" />
|
Style="{DynamicResource SquareButtonStyle}" HorizontalAlignment="Left" Margin="0,20,0,0" />
|
||||||
|
|||||||
@ -55,17 +55,23 @@
|
|||||||
<xctk:ColorPicker x:Name="SecondaryColor"
|
<xctk:ColorPicker x:Name="SecondaryColor"
|
||||||
SelectedColor="{Binding Path=VolumeDisplaySettings.SecondaryColor, Mode=TwoWay}"
|
SelectedColor="{Binding Path=VolumeDisplaySettings.SecondaryColor, Mode=TwoWay}"
|
||||||
Grid.Row="2" Grid.Column="1" Width="110" HorizontalAlignment="Right"
|
Grid.Row="2" Grid.Column="1" Width="110" HorizontalAlignment="Right"
|
||||||
VerticalAlignment="Center" Margin="0,5,-1,5" Height="22" />
|
VerticalAlignment="Center" Margin="0,5,-1,5" Height="22" >
|
||||||
|
<xctk:ColorPicker.Template>
|
||||||
|
<ControlTemplate>
|
||||||
|
<Rectangle ></Rectangle>
|
||||||
|
</ControlTemplate>
|
||||||
|
</xctk:ColorPicker.Template>
|
||||||
|
</xctk:ColorPicker>
|
||||||
|
|
||||||
<TextBlock Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="2" VerticalAlignment="Center" Margin="0,8"
|
<TextBlock Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="2" VerticalAlignment="Center" Margin="0,8"
|
||||||
TextWrapping="Wrap" HorizontalAlignment="Left" FontFamily="Segoe UI Semibold"
|
TextWrapping="Wrap" HorizontalAlignment="Left" FontFamily="Segoe UI Semibold"
|
||||||
Foreground="#535353" MaxWidth="520" TextAlignment="Justify">
|
MaxWidth="520" TextAlignment="Justify">
|
||||||
Note: This is an overlay. It will go over any other active effect, and is only shown at certain moments (in this case when changing volume). Please also note that it won't work if there aren't any active effects.
|
Note: This is an overlay. It will go over any other active effect, and is only shown at certain moments (in this case when changing volume). Please also note that it won't work if there aren't any active effects.
|
||||||
</TextBlock>
|
</TextBlock>
|
||||||
|
|
||||||
<TextBlock Grid.Row="4" Grid.Column="0" Grid.ColumnSpan="2" VerticalAlignment="Center" Margin="0,8"
|
<TextBlock Grid.Row="4" Grid.Column="0" Grid.ColumnSpan="2" VerticalAlignment="Center" Margin="0,8"
|
||||||
TextWrapping="Wrap" HorizontalAlignment="Left" FontFamily="Segoe UI Semibold"
|
TextWrapping="Wrap" HorizontalAlignment="Left" FontFamily="Segoe UI Semibold"
|
||||||
Foreground="#B50000" MaxWidth="520" TextAlignment="Justify">
|
Foreground="{DynamicResource HighlightBrush}" MaxWidth="520" TextAlignment="Justify">
|
||||||
Please also note that it won't work if there aren't any active effects.
|
Please also note that it won't work if there aren't any active effects.
|
||||||
</TextBlock>
|
</TextBlock>
|
||||||
|
|
||||||
|
|||||||
@ -48,7 +48,7 @@ namespace Artemis.ViewModels.Abstract
|
|||||||
if (EffectEnabled)
|
if (EffectEnabled)
|
||||||
MainManager.EffectManager.ClearEffect();
|
MainManager.EffectManager.ClearEffect();
|
||||||
else
|
else
|
||||||
MainManager.Restart(EffectModel);
|
MainManager.EffectManager.ChangeEffect(EffectModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SaveSettings()
|
public void SaveSettings()
|
||||||
@ -58,7 +58,7 @@ namespace Artemis.ViewModels.Abstract
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// Restart the effect if it's currently running to apply settings.
|
// Restart the effect if it's currently running to apply settings.
|
||||||
MainManager.Restart(EffectModel);
|
MainManager.EffectManager.ChangeEffect(EffectModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ResetSettings()
|
public void ResetSettings()
|
||||||
|
|||||||
@ -17,7 +17,7 @@ namespace Artemis.ViewModels
|
|||||||
* Thus no property notification is invoked, and system tray context-menu appears
|
* Thus no property notification is invoked, and system tray context-menu appears
|
||||||
* out of sync, still allowing 'Hide' and disabling 'Show'.
|
* out of sync, still allowing 'Hide' and disabling 'Show'.
|
||||||
* Given the purpose of the sample - integrating Caliburn.Micro with WPF NotifyIcon -
|
* Given the purpose of the sample - integrating Caliburn.Micro with WPF NotifyIcon -
|
||||||
* sync'ing the two view-models is not of interest here.
|
* syncing the two view-models is not of interest here.
|
||||||
* */
|
* */
|
||||||
|
|
||||||
public SystemTrayViewModel(IWindowManager windowManager, ShellViewModel shellViewModel)
|
public SystemTrayViewModel(IWindowManager windowManager, ShellViewModel shellViewModel)
|
||||||
@ -25,6 +25,7 @@ namespace Artemis.ViewModels
|
|||||||
_windowManager = windowManager;
|
_windowManager = windowManager;
|
||||||
_shellViewModel = shellViewModel;
|
_shellViewModel = shellViewModel;
|
||||||
_shellViewModel.MainManager.Events.Subscribe(this);
|
_shellViewModel.MainManager.Events.Subscribe(this);
|
||||||
|
_shellViewModel.MainManager.EnableProgram();
|
||||||
|
|
||||||
// TODO: Check if show on startup is enabled, if so, show window.
|
// TODO: Check if show on startup is enabled, if so, show window.
|
||||||
}
|
}
|
||||||
|
|||||||
@ -28,8 +28,8 @@
|
|||||||
</Label>
|
</Label>
|
||||||
|
|
||||||
<TextBlock Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" VerticalAlignment="Center" Margin="0,8"
|
<TextBlock Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" VerticalAlignment="Center" Margin="0,8"
|
||||||
TextWrapping="Wrap" HorizontalAlignment="Left" FontFamily="Segoe UI Semibold"
|
TextWrapping="Wrap" HorizontalAlignment="Left"
|
||||||
Foreground="#070707" MaxWidth="520" TextAlignment="Justify">
|
MaxWidth="520" TextAlignment="Justify">
|
||||||
Hello, <LineBreak /><LineBreak />
|
Hello, <LineBreak /><LineBreak />
|
||||||
Thanks a bunch for downloading this application. You're going to enjoy this! :)<LineBreak />
|
Thanks a bunch for downloading this application. You're going to enjoy this! :)<LineBreak />
|
||||||
<LineBreak />
|
<LineBreak />
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user