1
0
mirror of https://github.com/Artemis-RGB/Artemis synced 2026-01-02 10:43:31 +00:00

Merge pull request #355 from SpoinkyNL/development

1.10.0.0
This commit is contained in:
Robert Beekman 2017-05-06 23:48:48 +02:00 committed by GitHub
commit 2edbf093a7
65 changed files with 1872 additions and 774 deletions

View File

@ -384,6 +384,13 @@
<DependentUpon>AssettoCorsaView.xaml</DependentUpon>
</Compile>
<Compile Include="Modules\Games\AssettoCorsa\AssettoCorsaViewModel.cs" />
<Compile Include="Modules\Games\Terraria\TerrariaDataModel.cs" />
<Compile Include="Modules\Games\Terraria\TerrariaSettings.cs" />
<Compile Include="Modules\Games\Terraria\TerrariaModel.cs" />
<Compile Include="Modules\Games\Terraria\TerrariaView.xaml.cs">
<DependentUpon>TerrariaView.xaml</DependentUpon>
</Compile>
<Compile Include="Modules\Games\Terraria\TerrariaViewModel.cs" />
<Compile Include="Modules\General\GeneralProfile\PerformanceInfo.cs" />
<Compile Include="Modules\Games\EurotruckSimulator2\Data\Ets2TelemetryData.cs" />
<Compile Include="Modules\Games\EurotruckSimulator2\Data\Ets2TelemetryDataReader.cs" />
@ -561,15 +568,27 @@
<Compile Include="Profiles\Lua\Modules\Events\LuaKeyPressEventArgs.cs" />
<Compile Include="Profiles\Lua\Modules\Events\LuaDeviceDrawingEventArgs.cs" />
<Compile Include="Profiles\Lua\Modules\Events\LuaDeviceUpdatingEventArgs.cs" />
<Compile Include="Profiles\Lua\Modules\Gui\EditorButton.cs" />
<Compile Include="Profiles\Lua\Modules\Gui\LuaButton.cs" />
<Compile Include="Profiles\Lua\Modules\Gui\LuaCheckBox.cs" />
<Compile Include="Profiles\Lua\Modules\Gui\LuaComboBox.cs" />
<Compile Include="Profiles\Lua\Modules\Gui\LuaLabel.cs" />
<Compile Include="Profiles\Lua\Modules\Gui\LuaTextBox.cs" />
<Compile Include="Profiles\Lua\Modules\Gui\LuaWindowView.xaml.cs">
<DependentUpon>LuaWindowView.xaml</DependentUpon>
</Compile>
<Compile Include="Profiles\Lua\Modules\Gui\LuaWindowViewModel.cs" />
<Compile Include="Profiles\Lua\Modules\LuaEventsModule.cs" />
<Compile Include="Profiles\Lua\Modules\LuaBrushesModule.cs" />
<Compile Include="Profiles\Lua\LuaModule.cs" />
<Compile Include="Profiles\Lua\Modules\Brushes\LuaSolidColorBrush.cs" />
<Compile Include="Profiles\Lua\Modules\LuaGuiModule.cs" />
<Compile Include="Profiles\Lua\Modules\LuaKeybindModule.cs" />
<Compile Include="Profiles\Lua\Modules\LuaKeyboardModule.cs" />
<Compile Include="Profiles\Lua\Modules\LuaLayerModule.cs" />
<Compile Include="Profiles\Lua\Modules\LuaMouseModule.cs" />
<Compile Include="Profiles\Lua\Modules\LuaProfileModule.cs" />
<Compile Include="Profiles\Lua\Modules\LuaStorageModule.cs" />
<Compile Include="Profiles\Lua\Modules\Timer\LuaTimer.cs" />
<Compile Include="Profiles\Lua\Modules\LuaTimerModule.cs" />
<Compile Include="Profiles\Lua\Wrappers\LuaDrawWrapper.cs" />
@ -645,6 +664,7 @@
<DesignTime>True</DesignTime>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Include="Services\CompatibilityService.cs" />
<Compile Include="Services\DialogService.cs" />
<Compile Include="Services\MetroDialogService.cs" />
<Compile Include="Services\WindowService.cs" />
@ -653,7 +673,11 @@
<Compile Include="Settings\OffsetSettings.cs" />
<Compile Include="Styles\DropTargetAdorners\DropTargetMetroHighlightAdorner.cs" />
<Compile Include="Styles\DropTargetAdorners\DropTargetMetroInsertionAdorner.cs" />
<Compile Include="Utilities\ActiveWindowHelper.cs" />
<Compile Include="Utilities\ActiveWindowDetection\ActiveWindowDetectionType.cs" />
<Compile Include="Utilities\ActiveWindowDetection\ActiveWindowHelper.cs" />
<Compile Include="Utilities\ActiveWindowDetection\EventActiveWindowDetector.cs" />
<Compile Include="Utilities\ActiveWindowDetection\IActiveWindowDetector.cs" />
<Compile Include="Utilities\ActiveWindowDetection\TimerActiveWindowDetector.cs" />
<Compile Include="Utilities\ColorHelpers.cs" />
<Compile Include="Utilities\Converters\JsonConverters.cs" />
<Compile Include="Utilities\Converters\NinjectCustomConverter.cs" />
@ -856,6 +880,10 @@
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Modules\Games\Terraria\TerrariaView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Modules\General\Bubbles\BubblesView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
@ -924,6 +952,10 @@
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Profiles\Lua\Modules\Gui\LuaWindowView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Resources\Icons.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>

View File

@ -8,8 +8,10 @@ using System.Windows.Controls;
using System.Windows.Input;
using Artemis.DAL;
using Artemis.InjectionModules;
using Artemis.Services;
using Artemis.Settings;
using Artemis.Utilities;
using Artemis.Utilities.ActiveWindowDetection;
using Artemis.Utilities.Converters;
using Artemis.Utilities.DataReaders;
using Artemis.ViewModels;
@ -31,10 +33,11 @@ namespace Artemis
Logging.SetupLogging(SettingsProvider.Load<GeneralSettings>().LogLevel);
// Restore DDLs before interacting with any SDKs
DllManager.RestoreLogitechDll();
// Check compatibility before trying to boot further
CompatibilityService.CheckRivaTuner();
Initialize();
BindSpecialValues();
InputHook.Start();
AppDomain.CurrentDomain.UnhandledException += CurrentDomainOnUnhandledException;
}
@ -61,7 +64,7 @@ namespace Artemis
}
// If there is another type of of IInputControl get the non-scaled position - or do some processing to get a scaled position, whatever needs to happen
if ((e != null) && (input != null))
if (e != null && input != null)
return e.GetPosition(input).X;
// Return 0 if no processing could be done
@ -98,6 +101,7 @@ namespace Artemis
logger.Info("Artemis was run using the autorun shortcut, sleeping for 15 sec.");
Thread.Sleep(15000);
}
_kernel = new StandardKernel(new BaseModules(), new ManagerModules());
_kernel.Bind<IWindowManager>().To<WindowManager>().InSingletonScope();
@ -113,7 +117,7 @@ namespace Artemis
//TODO DarthAffe 17.12.2016: Is this the right location for this?
//TODO Move to Mainmanager and make disposable
ActiveWindowHelper.Initialize();
ActiveWindowHelper.SetActiveWindowDetectionType(SettingsProvider.Load<GeneralSettings>().ActiveWindowDetection);
}
protected override void OnExit(object sender, EventArgs e)
@ -144,6 +148,7 @@ namespace Artemis
protected override void OnStartup(object sender, StartupEventArgs e)
{
DisplayRootViewFor<ShellViewModel>();
InputHook.Start();
}
}
}

View File

@ -134,7 +134,7 @@ namespace Artemis.DAL
return null;
return prof;
}
catch (JsonSerializationException)
catch (JsonException)
{
return null;
}

View File

@ -1,4 +1,5 @@
using System.Drawing;
using System;
using System.Drawing;
using System.Linq;
using System.Threading;
using System.Windows;
@ -67,6 +68,8 @@ namespace Artemis.DeviceProviders.CoolerMaster
for (var y = 0; y < Height; y++)
{
var c = b.GetPixel(x, y);
if (c.R != 0)
Console.WriteLine();
matrix.KeyColor[y, x] = new KEY_COLOR(c.R, c.G, c.B);
}
}

View File

@ -42,9 +42,16 @@ namespace Artemis.DeviceProviders.CoolerMaster
CmSdk.SetControlDevice(DEVICE_INDEX.DEV_MMouse_L);
// Doesn't seem reliable but better than nothing I suppose
try
{
CanUse = CmSdk.IsDevicePlug();
if (CanUse)
CmSdk.EnableLedControl(true);
}
catch (Exception)
{
CanUse = false;
}
Logger.Debug("Attempted to enable Mastermouse Pro L. CanUse: {0}", CanUse);
return CanUse;

View File

@ -38,9 +38,16 @@ namespace Artemis.DeviceProviders.CoolerMaster
CmSdk.SetControlDevice(DEVICE_INDEX.DEV_MMouse_S);
// Doesn't seem reliable but better than nothing I suppose
try
{
CanUse = CmSdk.IsDevicePlug();
if (CanUse)
CmSdk.EnableLedControl(true);
}
catch (Exception)
{
CanUse = false;
}
Logger.Debug("Attempted to enable Mastermouse Pro S. CanUse: {0}", CanUse);
return CanUse;

View File

@ -81,10 +81,10 @@ namespace Artemis.DeviceProviders.Corsair
PreviewSettings = new PreviewSettings(new Rect(15, 30, 751, 284), Resources.k65);
break;
case "STRAFE RGB":
Height = 7;
Height = 8;
Width = 22;
Slug = "corsair-strafe-rgb";
PreviewSettings = new PreviewSettings(new Rect(23, 30, 940, 303), Resources.strafe);
PreviewSettings = new PreviewSettings(new Rect(23, 12, 937, 324), Resources.strafe);
break;
}
@ -113,32 +113,11 @@ namespace Artemis.DeviceProviders.Corsair
/// </summary>
/// <param name="bitmap"></param>
public override void DrawBitmap(Bitmap bitmap)
{
// For STRAFE, stretch the image on row 2.
if (_keyboard.DeviceInfo.Model == "STRAFE RGB")
{
using (var strafeBitmap = new Bitmap(22, 8))
{
using (var g = Graphics.FromImage(strafeBitmap))
{
g.DrawImage(bitmap, new Point(0, 0));
g.DrawImage(bitmap, new Rectangle(0, 3, 22, 7), new Rectangle(0, 2, 22, 7),
GraphicsUnit.Pixel);
_keyboardBrush.Image = strafeBitmap;
_keyboard.Update();
}
}
}
else
{
_keyboardBrush.Image = bitmap;
_keyboard.Update();
}
}
public override KeyMatch? GetKeyPosition(Keys keyCode)
{
var widthMultiplier = Width / _keyboard.Brush.RenderedRectangle.Width;

View File

@ -14,8 +14,7 @@ namespace Artemis.DeviceProviders.Logitech
DllManager.RestoreLogitechDll();
// Check to see if VC++ 2012 x64 is installed.
if (Registry.LocalMachine.OpenSubKey(
@"SOFTWARE\Classes\Installer\Dependencies\{ca67548a-5ebe-413a-b50c-4b9ceb6d66c6}") == null)
if (Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Classes\Installer\Dependencies\{ca67548a-5ebe-413a-b50c-4b9ceb6d66c6}") == null)
{
CantEnableText = "Couldn't connect to your Logitech keyboard.\n" +
"The Visual C++ 2012 Redistributable v11.0.61030.0 could not be found, which is required.\n" +

View File

@ -37,8 +37,11 @@ namespace Artemis.DeviceProviders.Razer
return false;
// Some people have Synapse installed, but not a Chroma keyboard, deal with this
Chroma.Instance.Initialize();
var blackWidowFound = Chroma.Instance.Query(Devices.Blackwidow).Connected;
var blackWidowTeFound = Chroma.Instance.Query(Devices.BlackwidowTe).Connected;
Chroma.Instance.Uninitialize();
return blackWidowFound || blackWidowTeFound;
}

View File

@ -6,6 +6,7 @@ using Artemis.Profiles.Layers.Abstract;
using Artemis.Profiles.Layers.Interfaces;
using Artemis.Profiles.Layers.Types.Audio.AudioCapturing;
using Artemis.Profiles.Lua;
using Artemis.Profiles.Lua.Modules.Gui;
using Artemis.Services;
using Artemis.Utilities.DataReaders;
using Artemis.Utilities.GameState;
@ -116,6 +117,8 @@ namespace Artemis.InjectionModules
.InheritedFrom<LuaModule>()
.BindAllBaseClasses());
Bind<LuaWindowViewModel>().ToSelf();
#endregion
}
}

View File

@ -1,10 +1,12 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Artemis.DeviceProviders;
using Artemis.Profiles;
using Artemis.Profiles.Lua;
using Artemis.Profiles.Lua.Modules;
using Artemis.Profiles.Lua.Modules.Gui;
using Castle.Core.Internal;
using MoonSharp.Interpreter;
using Ninject;
@ -17,7 +19,6 @@ namespace Artemis.Managers
private readonly DeviceManager _deviceManager;
private readonly IKernel _kernel;
private readonly ILogger _logger;
private readonly Script _luaScript;
private List<LuaModule> _luaModules;
public LuaManager(IKernel kernel, ILogger logger, DeviceManager deviceManager)
@ -25,13 +26,17 @@ namespace Artemis.Managers
_kernel = kernel;
_logger = logger;
_deviceManager = deviceManager;
_luaScript = new Script(CoreModules.Preset_SoftSandbox);
EditorButtons = new ObservableCollection<EditorButton>();
LuaScript = new Script(CoreModules.Preset_SoftSandbox);
}
public ProfileModel ProfileModel { get; private set; }
public KeyboardProvider KeyboardProvider { get; private set; }
public LuaProfileModule ProfileModule { get; private set; }
public LuaEventsModule EventsModule { get; private set; }
public Script LuaScript { get; }
public ObservableCollection<EditorButton> EditorButtons { get; set; }
public void SetupLua(ProfileModel profileModel)
{
@ -52,11 +57,11 @@ namespace Artemis.Managers
EventsModule = (LuaEventsModule) _luaModules.First(m => m.ModuleName == "Events");
// Setup new state
_luaScript.Options.DebugPrint = LuaPrint;
LuaScript.Options.DebugPrint = LuaPrint;
// Insert each module into the script's globals
foreach (var luaModule in _luaModules)
_luaScript.Globals[luaModule.ModuleName] = luaModule;
// Insert each module with a ModuleName into the script's globals
foreach (var luaModule in _luaModules.Where(m => m.ModuleName != null))
LuaScript.Globals[luaModule.ModuleName] = luaModule;
// If there is no LUA script, don't bother executing the string
if (ProfileModel.LuaScript.IsNullOrEmpty())
@ -66,9 +71,9 @@ namespace Artemis.Managers
{
lock (EventsModule.InvokeLock)
{
lock (_luaScript)
lock (LuaScript)
{
_luaScript.DoString(ProfileModel.LuaScript);
LuaScript.DoString(ProfileModel.LuaScript);
}
}
}
@ -97,12 +102,12 @@ namespace Artemis.Managers
try
{
_luaScript.Globals.Clear();
_luaScript.Registry.Clear();
_luaScript.Registry.RegisterConstants();
_luaScript.Registry.RegisterCoreModules(CoreModules.Preset_SoftSandbox);
_luaScript.Globals.RegisterConstants();
_luaScript.Globals.RegisterCoreModules(CoreModules.Preset_SoftSandbox);
LuaScript.Globals.Clear();
LuaScript.Registry.Clear();
LuaScript.Registry.RegisterConstants();
LuaScript.Registry.RegisterCoreModules(CoreModules.Preset_SoftSandbox);
LuaScript.Globals.RegisterConstants();
LuaScript.Globals.RegisterCoreModules(CoreModules.Preset_SoftSandbox);
}
catch (NullReferenceException)
{
@ -112,15 +117,15 @@ namespace Artemis.Managers
if (EventsModule != null)
lock (EventsModule.InvokeLock)
{
lock (_luaScript)
lock (LuaScript)
{
_luaScript.DoString("");
LuaScript.DoString("");
}
}
else
lock (_luaScript)
lock (LuaScript)
{
_luaScript.DoString("");
LuaScript.DoString("");
}
}
@ -138,12 +143,12 @@ namespace Artemis.Managers
{
lock (EventsModule.InvokeLock)
{
lock (_luaScript)
lock (LuaScript)
{
if (args != null)
_luaScript.Call(function, args);
LuaScript.Call(function, args);
else
_luaScript.Call(function);
LuaScript.Call(function);
}
}
}

View File

@ -108,6 +108,7 @@ namespace Artemis.Managers
public async void EnableProgram()
{
Logger.Debug("Enabling program");
ProgramEnabled = true;
await LoopManager.StartAsync();
@ -121,9 +122,12 @@ namespace Artemis.Managers
public void DisableProgram()
{
Logger.Debug("Disabling program");
foreach (var overlayModule in ModuleManager.OverlayModules)
{
if (overlayModule.Settings.IsEnabled)
overlayModule.Dispose();
}
LoopManager.Stop();
ProgramEnabled = false;
RaiseEnabledChangedEvent(new EnabledChangedEventArgs(ProgramEnabled));

View File

@ -5,6 +5,7 @@ using Artemis.DAL;
using Artemis.Modules.Abstract;
using Artemis.Settings;
using Artemis.Utilities;
using Artemis.Utilities.ActiveWindowDetection;
using Ninject.Extensions.Logging;
namespace Artemis.Managers

View File

@ -27,8 +27,7 @@ namespace Artemis.Models
private FileSystemWatcher _watcher;
private ModuleModel _luaModule;
public ProfileEditorModel(WindowService windowService, MetroDialogService dialogService,
DeviceManager deviceManager, LuaManager luaManager)
public ProfileEditorModel(WindowService windowService, MetroDialogService dialogService, DeviceManager deviceManager, LuaManager luaManager)
{
_windowService = windowService;
_dialogService = dialogService;
@ -50,7 +49,7 @@ namespace Artemis.Models
new ConstructorArgument("dataModel", dataModel),
new ConstructorArgument("layer", layer)
};
_windowService.ShowDialog<LayerEditorViewModel>("Artemis | Edit layer", args);
_windowService.ShowDialog<LayerEditorViewModel>("Artemis | Edit layer", null, args);
// If the layer was a folder, but isn't anymore, assign it's children to it's parent.
if (layer.LayerType is FolderType || !layer.Children.Any())
@ -345,7 +344,8 @@ namespace Artemis.Models
private void DisposeLuaWatcher()
{
if (_watcher == null) return;
if (_watcher == null)
return;
_watcher.Changed -= LuaFileChanged;
_watcher.Dispose();
_watcher = null;
@ -360,8 +360,6 @@ namespace Artemis.Models
#region Rendering
#endregion
}
}

View File

@ -22,7 +22,7 @@
<!-- Header -->
<Label Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" FontSize="20" HorizontalAlignment="Left">
<Label.Content>
<AccessText TextWrapping="Wrap" Text="By default shows RPM on the F-keys, gear on the other keys and track flags on the numpad." />
<AccessText TextWrapping="Wrap" Text="By default shows RPM on bottom half of the keyboard, engine stats on the top half and DRS on the numpad" />
</Label.Content>
</Label>

View File

@ -29,7 +29,6 @@ namespace Artemis.Modules.Games.GtaV
public override void Enable()
{
var process = System.Diagnostics.Process.GetProcessesByName("GTA5").First();
DllManager.PlaceLogitechDll();
_pipeServer.PipeMessage += PipeServerOnPipeMessage;
base.Enable();

View File

@ -36,7 +36,7 @@ namespace Artemis.Modules.Games.RocketLeague
{
if (!SettingsProvider.Load<GeneralSettings>().EnablePointersUpdate)
{
VersionText = "You disabled pointer updates, this could result in the Rocket League effect not working after a game update.";
VersionText = "You disabled pointer updates, this could result in the Rocket League module not working after a game update.";
return;
}

View File

@ -0,0 +1,18 @@
using Artemis.Modules.Abstract;
using MoonSharp.Interpreter;
namespace Artemis.Modules.Games.Terraria
{
[MoonSharpUserData]
public class TerrariaDataModel : ModuleDataModel
{
public int Hp { get; set; }
public int MaxHp { get; set; }
public int Mana { get; set; }
public int MaxMana { get; set; }
public int Breath { get; set; }
public int MaxBreath { get; set; }
public bool InWater { get; set; }
public bool InLava { get; set; }
}
}

View File

@ -0,0 +1,91 @@
using System;
using System.Linq;
using Artemis.DAL;
using Artemis.Managers;
using Artemis.Modules.Abstract;
using Artemis.Settings;
using Artemis.Utilities;
using Artemis.Utilities.Memory;
namespace Artemis.Modules.Games.Terraria
{
public class TerrariaModel : ModuleModel
{
private Memory _memory;
private GamePointersCollection _pointer;
public TerrariaModel(DeviceManager deviceManager, LuaManager luaManager) : base(deviceManager, luaManager)
{
Settings = SettingsProvider.Load<TerrariaSettings>();
DataModel = new TerrariaDataModel();
ProcessNames.Add("Terraria");
// Generate a new offset when the game is updated
//_pointer = new GamePointersCollection
//{
// Game = "Terraria",
// GameVersion = "1.3.4.4",
// GameAddresses = new List<GamePointer>
// {
// new GamePointer
// {
// Description = "PlayerBase",
// BasePointer = new IntPtr(0x0039C078),
// Offsets = new[] {0x280, 0x6C0, 0x674, 0x3C}
// }
// }
//};
//var res = JsonConvert.SerializeObject(_pointer, Formatting.Indented);
}
public override string Name => "Terraria";
public override bool IsOverlay => false;
public override bool IsBoundToProcess => true;
public override void Dispose()
{
base.Dispose();
_memory?.Dispose();
_memory = null;
}
public override void Enable()
{
Updater.GetPointers();
_pointer = SettingsProvider.Load<OffsetSettings>().Terraria;
base.Enable();
}
public override void Update()
{
if (_memory == null)
{
var tempProcess = MemoryHelpers.GetProcessIfRunning(ProcessNames[0]);
if (tempProcess == null)
return;
_memory = new Memory(tempProcess);
}
if (ProfileModel == null || DataModel == null || _memory == null)
return;
var offsets = _pointer.GameAddresses.First(ga => ga.Description == "PlayerBase").ToString();
var baseAddress = _memory.GetAddress("\"Terraria.exe\"" + offsets);
var basePointer = new IntPtr(_memory.ReadInt32(baseAddress));
var playerPointer = new IntPtr(_memory.ReadInt32(basePointer + 0x18));
var dataModel = (TerrariaDataModel) DataModel;
dataModel.Hp = _memory.ReadInt32(playerPointer + 0x340);
dataModel.MaxHp = _memory.ReadInt32(playerPointer + 0x338);
dataModel.Mana = _memory.ReadInt32(playerPointer + 0x344);
dataModel.MaxMana = _memory.ReadInt32(playerPointer + 0x348);
dataModel.Breath = _memory.ReadInt32(playerPointer + 0x2B4);
dataModel.MaxBreath = _memory.ReadInt32(playerPointer + 0x2B0);
dataModel.InWater = Convert.ToBoolean(_memory.ReadInt32(playerPointer + 0x1D));
dataModel.InLava = Convert.ToBoolean(_memory.ReadInt32(playerPointer + 0x20));
}
}
}

View File

@ -0,0 +1,8 @@
using Artemis.Modules.Abstract;
namespace Artemis.Modules.Games.Terraria
{
public class TerrariaSettings : ModuleSettings
{
}
}

View File

@ -0,0 +1,48 @@
<UserControl x:Class="Artemis.Modules.Games.Terraria.TerrariaView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Artemis.Modules.Games.Terraria"
xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls"
xmlns:cal="http://www.caliburnproject.org"
mc:Ignorable="d" d:DesignWidth="714.667" d:DesignHeight="384.667" >
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="30" />
</Grid.RowDefinitions>
<!-- Header -->
<Label Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" FontSize="20" HorizontalAlignment="Left">
<Label.Content>
<AccessText TextWrapping="Wrap" Text="By default does nothing! (default profiles coming soon)" />
</Label.Content>
</Label>
<!-- Sub header -->
<TextBlock x:Name="VersionText" Grid.Row="1" Grid.Column="0" VerticalAlignment="Bottom" TextWrapping="Wrap" HorizontalAlignment="Left" FontFamily="Segoe UI Semibold" TextAlignment="Justify" Margin="5,0,0,10" />
<!-- Enable -->
<StackPanel Grid.Row="1" Grid.Column="1" HorizontalAlignment="Right" Orientation="Horizontal">
<Label Content="Enable module" HorizontalAlignment="Right" Margin="0,0,0,3" />
<controls:ToggleSwitchButton IsChecked="{Binding Path=IsModuleEnabled, Mode=OneWay}" cal:Message.Attach="[Event Click] = [Action ToggleModule]"
Style="{StaticResource MahApps.Metro.Styles.ToggleSwitchButton.Win10}" ToolTip="Note: You can't enable an module when Artemis is disabled" />
</StackPanel>
<!-- Profile editor -->
<ContentControl Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2" x:Name="ProfileEditor" />
<!-- Buttons -->
<StackPanel Grid.Column="0" Grid.Row="3" Orientation="Horizontal" VerticalAlignment="Bottom">
<Button x:Name="ResetSettings" Content="Reset effect" VerticalAlignment="Top" Width="100" Style="{DynamicResource SquareButtonStyle}" />
<Button x:Name="SaveSettings" Content="Save changes" VerticalAlignment="Top" Width="100" Margin="10,0,0,0" Style="{DynamicResource SquareButtonStyle}" />
</StackPanel>
</Grid>
</UserControl>

View File

@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace Artemis.Modules.Games.Terraria
{
/// <summary>
/// Interaction logic for TerrariaView.xaml
/// </summary>
public partial class TerrariaView : UserControl
{
public TerrariaView()
{
InitializeComponent();
}
}
}

View File

@ -0,0 +1,47 @@
using Artemis.DAL;
using Artemis.Managers;
using Artemis.Modules.Abstract;
using Artemis.Settings;
using Artemis.Utilities;
using Ninject;
namespace Artemis.Modules.Games.Terraria
{
public sealed class TerrariaViewModel : ModuleViewModel
{
private string _versionText;
public TerrariaViewModel(MainManager mainManager, [Named(nameof(TerrariaModel))] ModuleModel moduleModel, IKernel kernel) : base(mainManager, moduleModel, kernel)
{
DisplayName = "Terraria";
SetVersionText();
}
public override bool UsesProfileEditor => true;
public string VersionText
{
get { return _versionText; }
set
{
if (value == _versionText) return;
_versionText = value;
NotifyOfPropertyChange(() => VersionText);
}
}
private void SetVersionText()
{
if (!SettingsProvider.Load<GeneralSettings>().EnablePointersUpdate)
{
VersionText = "You disabled pointer updates, this could result in the Terraria module not working after a game update.";
return;
}
Updater.GetPointers();
var version = SettingsProvider.Load<OffsetSettings>().Terraria?.GameVersion;
VersionText = $"Requires patch {version}. When a new patch is released Artemis downloads new pointers for the latest version (unless disabled in settings).";
}
}
}

View File

@ -11,6 +11,7 @@ using Artemis.Events;
using Artemis.Managers;
using Artemis.Modules.Abstract;
using Artemis.Utilities;
using Artemis.Utilities.ActiveWindowDetection;
using CSCore.CoreAudioAPI;
using Newtonsoft.Json;
using SpotifyAPI.Local;

View File

@ -1,12 +1,6 @@
<UserControl x:Class="Artemis.Modules.General.GeneralProfile.GeneralProfileView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:cal="http://www.caliburnproject.org"
xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls"
mc:Ignorable="d"
d:DesignHeight="476.986" d:DesignWidth="538.772">
<UserControl x:Class="Artemis.Modules.General.GeneralProfile.GeneralProfileView" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:cal="http://www.caliburnproject.org" xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls" mc:Ignorable="d" d:DesignHeight="476.986" d:DesignWidth="538.772">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />

View File

@ -63,9 +63,15 @@ namespace Artemis.Profiles.Layers.Models
switch (ToggleType)
{
case ToggleType.Enable:
// Apply RenderAllowed only if this is the first keybind
if (index == 0)
layerModel.RenderAllowed = false;
action = () => layerModel.RenderAllowed = true;
break;
case ToggleType.Disable:
// Apply RenderAllowed only if this is the first keybind
if (index == 0)
layerModel.RenderAllowed = false;
action = () => layerModel.RenderAllowed = false;
break;
case ToggleType.Toggle:

View File

@ -2,6 +2,7 @@
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Windows.Media;
using Microsoft.Win32;
using SharpDX.Direct3D9;
namespace Artemis.Profiles.Layers.Types.AmbientLight.ScreenCapturing
@ -15,6 +16,14 @@ namespace Artemis.Profiles.Layers.Types.AmbientLight.ScreenCapturing
Width = Screen.PrimaryScreen.Bounds.Width;
Height = Screen.PrimaryScreen.Bounds.Height;
//DarthAffe 08.04.2017: Fix for systems using windows-scaling. The primary screen size is reported 'wrong'.
double scaling = GetScaling();
if (Math.Abs(scaling - 1.0) > 0.01)
{
Width = (int)(Width / scaling);
Height = (int)(Height / scaling);
}
var presentParams = new PresentParameters(Width, Height)
{
Windowed = true,
@ -43,6 +52,19 @@ namespace Artemis.Profiles.Layers.Types.AmbientLight.ScreenCapturing
#region Methods
private double GetScaling()
{
try
{
int currentDpi = (int)Registry.GetValue("HKEY_CURRENT_USER\\Control Panel\\Desktop", "LogPixels", 96);
return 96.0 / currentDpi;
}
catch
{
return 1.0;
}
}
public byte[] CaptureScreen()
{
_device.GetFrontBufferData(0, _surface);

View File

@ -97,11 +97,14 @@ namespace Artemis.Profiles.Layers.Types.Audio.AudioCapturing
}
}
private LineSpectrum _lineSpectrum;
public LineSpectrum GetLineSpectrum(int barCount, ScalingStrategy scalingStrategy)
{
if (_spectrumProvider == null)
if (_spectrumProvider == null || barCount <= 0)
return null;
return new LineSpectrum(FftSize)
if (_lineSpectrum == null)
_lineSpectrum = new LineSpectrum(FftSize)
{
SpectrumProvider = _spectrumProvider,
UseAverage = true,
@ -109,6 +112,8 @@ namespace Artemis.Profiles.Layers.Types.Audio.AudioCapturing
IsXLogScale = true,
ScalingStrategy = scalingStrategy
};
return _lineSpectrum;
}
/// <summary>
@ -182,6 +187,7 @@ namespace Artemis.Profiles.Layers.Types.Audio.AudioCapturing
}
};
_lineSpectrum = null;
_singleSpectrum = new SingleSpectrum(FftSize, _spectrumProvider);
_mayStop = false;

View File

@ -1,4 +1,5 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Media;
@ -26,6 +27,7 @@ namespace Artemis.Profiles.Layers.Types.Audio
private List<double> _lineValues;
private AudioPropertiesModel _properties;
private bool _subscribed;
private DateTime _lastRender;
public AudioType(AudioCaptureManager audioCaptureManager)
{
@ -123,8 +125,7 @@ namespace Artemis.Profiles.Layers.Types.Audio
SubscribeToAudioChange();
if (_audioCapture == null || newProperties.Device != _properties.Device ||
newProperties.DeviceType != _properties.DeviceType)
if (_audioCapture == null || newProperties.Device != _properties.Device || newProperties.DeviceType != _properties.DeviceType)
{
var device = GetMmDevice();
if (device != null)
@ -153,17 +154,19 @@ namespace Artemis.Profiles.Layers.Types.Audio
currentHeight = layerModel.Width;
}
if (_lines != currentLines || _lineSpectrum == null)
// Get a new line spectrum if the lines changed, it is null or the layer hasn't rendered for a few frames
if (_lines != currentLines || _lineSpectrum == null || DateTime.Now - _lastRender > TimeSpan.FromMilliseconds(100))
{
_lines = currentLines;
_lineSpectrum = _audioCapture.GetLineSpectrum(_lines, ScalingStrategy.Decibel);
if (_lineSpectrum == null)
return;
}
var newLineValues = _lineSpectrum?.GetLineValues(currentHeight);
var newLineValues = _audioCapture.GetLineSpectrum(_lines, ScalingStrategy.Decibel)?.GetLineValues(currentHeight);
if (newLineValues != null)
{
_lineValues = newLineValues;
_lastRender = DateTime.Now;
}
}
public void SetupProperties(LayerModel layerModel)

View File

@ -0,0 +1,25 @@
using Artemis.Managers;
using MoonSharp.Interpreter;
namespace Artemis.Profiles.Lua.Modules.Gui
{
public class EditorButton
{
private readonly LuaManager _luaManager;
public EditorButton(LuaManager luaManager, string text, DynValue action)
{
_luaManager = luaManager;
Text = text;
Action = action;
}
public void Invoke()
{
_luaManager.Call(Action);
}
public string Text { get; }
public DynValue Action { get; }
}
}

View File

@ -0,0 +1,49 @@
using System;
using System.Windows;
using System.Windows.Controls;
using Artemis.Managers;
using MoonSharp.Interpreter;
using MoonSharp.Interpreter.Interop;
namespace Artemis.Profiles.Lua.Modules.Gui
{
[MoonSharpUserData]
public class LuaButton
{
private readonly LuaManager _luaManager;
public LuaButton(LuaManager luaManager, string text, double x, double y, double? width, double? height)
{
_luaManager = luaManager;
Button = new Button {Content = text};
if (width != null)
Button.Width = width.Value;
if (height != null)
Button.Height = height.Value;
Button.Click += ButtonOnClick;
}
[MoonSharpVisible(false)]
public Button Button { get; }
public string Text
{
get => Button.Dispatcher.Invoke(() => (string) Button.Content);
set => Button.Dispatcher.Invoke(() => Button.Content = value);
}
private void ButtonOnClick(object sender, RoutedEventArgs routedEventArgs)
{
_luaManager.EventsModule.LuaInvoke(_luaManager.ProfileModel, () => OnClick(this));
}
public event EventHandler<EventArgs> Click;
protected virtual void OnClick(LuaButton button)
{
Click?.Invoke(button, null);
}
}
}

View File

@ -0,0 +1,55 @@
using System;
using System.Windows;
using System.Windows.Controls;
using Artemis.Managers;
using MoonSharp.Interpreter;
using MoonSharp.Interpreter.Interop;
namespace Artemis.Profiles.Lua.Modules.Gui
{
[MoonSharpUserData]
public class LuaCheckBox
{
private readonly LuaManager _luaManager;
public LuaCheckBox(LuaManager luaManager, string text, bool isChecked, double x, double y, double? width, double? height)
{
_luaManager = luaManager;
CheckBox = new CheckBox {Content = text, IsChecked = isChecked};
if (width != null)
CheckBox.Width = width.Value;
if (height != null)
CheckBox.Height = height.Value;
CheckBox.Click += CheckBoxOnClick;
}
[MoonSharpVisible(false)]
public CheckBox CheckBox { get; }
public string Text
{
get => CheckBox.Dispatcher.Invoke(() => (string) CheckBox.Content);
set => CheckBox.Dispatcher.Invoke(() => CheckBox.Content = value);
}
public bool IsChecked
{
get => CheckBox.Dispatcher.Invoke(() => CheckBox.IsChecked != null && (bool) CheckBox.IsChecked);
set => CheckBox.Dispatcher.Invoke(() => CheckBox.IsChecked = value);
}
private void CheckBoxOnClick(object sender, RoutedEventArgs routedEventArgs)
{
_luaManager.EventsModule.LuaInvoke(_luaManager.ProfileModel, () => OnClick(this));
}
public event EventHandler<EventArgs> Click;
protected virtual void OnClick(LuaCheckBox checkBox)
{
Click?.Invoke(checkBox, null);
}
}
}

View File

@ -0,0 +1,70 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Windows.Controls;
using Artemis.Managers;
using MoonSharp.Interpreter;
using MoonSharp.Interpreter.Interop;
namespace Artemis.Profiles.Lua.Modules.Gui
{
[MoonSharpUserData]
public class LuaComboBox
{
private readonly LuaManager _luaManager;
public LuaComboBox(LuaManager luaManager, string value, List<string> values, double x, double y, double? width, double? height)
{
_luaManager = luaManager;
ComboBox = new ComboBox {ItemsSource = new ObservableCollection<string>(values), SelectedItem = value};
if (width != null)
ComboBox.Width = (double) width;
if (height != null)
ComboBox.Height = (double) height;
ComboBox.SelectionChanged += ComboBoxOnSelectionChanged;
}
[MoonSharpVisible(false)]
public ComboBox ComboBox { get; }
public string Value
{
get => ComboBox.Dispatcher.Invoke(() => (string) ComboBox.SelectedItem);
set => ComboBox.Dispatcher.Invoke(() => ComboBox.SelectedItem = value);
}
public void SetValues(string[] values)
{
var collection = (ObservableCollection<string>) ComboBox.ItemsSource;
collection.Clear();
foreach (var value in values)
collection.Add(value);
}
public void AddValue(string value)
{
((ObservableCollection<string>) ComboBox.ItemsSource).Add(value);
}
public void RemoveValue(string value)
{
var collection = (ObservableCollection<string>) ComboBox.ItemsSource;
if (collection.Contains(value))
collection.Remove(value);
}
private void ComboBoxOnSelectionChanged(object sender, SelectionChangedEventArgs selectionChangedEventArgs)
{
_luaManager.EventsModule.LuaInvoke(_luaManager.ProfileModel, () => OnSelectionChanged(this));
}
public event EventHandler<EventArgs> SelectionChanged;
protected virtual void OnSelectionChanged(LuaComboBox comboBox)
{
SelectionChanged?.Invoke(comboBox, null);
}
}
}

View File

@ -0,0 +1,30 @@
using System.Windows;
using System.Windows.Controls;
using MoonSharp.Interpreter;
using MoonSharp.Interpreter.Interop;
namespace Artemis.Profiles.Lua.Modules.Gui
{
[MoonSharpUserData]
public class LuaLabel
{
public LuaLabel(string text, double x, double y, double fontSize = 12, int fontWeight = 400)
{
Label = new Label
{
Content = text,
FontSize = fontSize,
FontWeight = FontWeight.FromOpenTypeWeight(fontWeight)
};
}
[MoonSharpVisible(false)]
public Label Label { get; }
public string Text
{
get => Label.Dispatcher.Invoke(() => (string) Label.Content);
set => Label.Dispatcher.Invoke(() => Label.Content = value);
}
}
}

View File

@ -0,0 +1,48 @@
using System;
using System.Windows.Controls;
using Artemis.Managers;
using MoonSharp.Interpreter;
using MoonSharp.Interpreter.Interop;
namespace Artemis.Profiles.Lua.Modules.Gui
{
[MoonSharpUserData]
public class LuaTextBox
{
private readonly LuaManager _luaManager;
public LuaTextBox(LuaManager luaManager, string text, double x, double y, double? width, double? height)
{
_luaManager = luaManager;
TextBox = new TextBox {Text = text};
if (width != null)
TextBox.Width = width.Value;
if (height != null)
TextBox.Height = height.Value;
TextBox.TextChanged += TextBoxOnTextChanged;
}
[MoonSharpVisible(false)]
public TextBox TextBox { get; }
public string Text
{
get => TextBox.Dispatcher.Invoke(() => TextBox.Text);
set => TextBox.Dispatcher.Invoke(() => TextBox.Text = value);
}
private void TextBoxOnTextChanged(object sender, TextChangedEventArgs textChangedEventArgs)
{
_luaManager.EventsModule.LuaInvoke(_luaManager.ProfileModel, () => OnTextChanged(this));
}
public event EventHandler<EventArgs> TextChanged;
protected virtual void OnTextChanged(LuaTextBox button)
{
TextChanged?.Invoke(button, null);
}
}
}

View File

@ -0,0 +1,8 @@
<controls:MetroWindow x:Class="Artemis.Profiles.Lua.Modules.Gui.LuaWindowView" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:Artemis.Profiles.Lua.Modules.Gui"
xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls" mc:Ignorable="d" Title="LuaWindowView" Height="300" Width="300" WindowStartupLocation="CenterScreen"
GlowBrush="{DynamicResource AccentColorBrush}">
<Grid>
<ItemsControl ItemsSource="{Binding Path=Content}" ScrollViewer.HorizontalScrollBarVisibility="Auto" ScrollViewer.VerticalScrollBarVisibility="Auto" />
</Grid>
</controls:MetroWindow>

View File

@ -0,0 +1,15 @@
using MahApps.Metro.Controls;
namespace Artemis.Profiles.Lua.Modules.Gui
{
/// <summary>
/// Interaction logic for LuaWindowView.xaml
/// </summary>
public partial class LuaWindowView : MetroWindow
{
public LuaWindowView()
{
InitializeComponent();
}
}
}

View File

@ -0,0 +1,93 @@
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using Artemis.Managers;
using Caliburn.Micro;
using MoonSharp.Interpreter;
namespace Artemis.Profiles.Lua.Modules.Gui
{
[MoonSharpUserData]
public class LuaWindowViewModel : Screen
{
private readonly LuaManager _luaManager;
public LuaWindowViewModel(LuaManager luaManager)
{
_luaManager = luaManager;
Canvas = new Canvas();
Content = new List<UIElement> {Canvas};
}
public Canvas Canvas { get; set; }
public List<UIElement> Content { get; set; }
public LuaLabel CreateLabel(string text, double x, double y, double fontSize = 12, int fontWeight = 400)
{
LuaLabel element = null;
Execute.OnUIThread(() =>
{
element = new LuaLabel(text, x, y, fontSize, fontWeight);
AddControl(element.Label, x, y);
});
return element;
}
public LuaButton CreateButton(string text, double x, double y, double? width, double? height)
{
LuaButton element = null;
Execute.OnUIThread(() =>
{
element = new LuaButton(_luaManager, text, x, y, width, height);
AddControl(element.Button, x, y);
});
return element;
}
public LuaTextBox CreateTextBox(string text, double x, double y, double? width, double? height)
{
LuaTextBox element = null;
Execute.OnUIThread(() =>
{
element = new LuaTextBox(_luaManager, text, x, y, width, height);
AddControl(element.TextBox, x, y);
});
return element;
}
public LuaComboBox CreateComboBox(string value, List<string> values, double x, double y, double? width, double? height)
{
LuaComboBox element = null;
Execute.OnUIThread(() =>
{
element = new LuaComboBox(_luaManager, value, values, x, y, width, height);
AddControl(element.ComboBox, x, y);
});
return element;
}
public LuaCheckBox CreateCheckBox(string text, bool isChecked, double x, double y, double? width, double? height)
{
LuaCheckBox element = null;
Execute.OnUIThread(() =>
{
element = new LuaCheckBox(_luaManager, text, isChecked, x, y, width, height);
AddControl(element.CheckBox, x, y);
});
return element;
}
private void AddControl(UIElement uiElement, double x, double y)
{
Canvas.Children.Add(uiElement);
Canvas.SetLeft(uiElement, x);
Canvas.SetTop(uiElement, y);
}
}
}

View File

@ -73,7 +73,7 @@ namespace Artemis.Profiles.Lua.Modules
}
}
private void LuaInvoke(ProfileModel profileModel, Action action)
public void LuaInvoke(ProfileModel profileModel, Action action)
{
lock (InvokeLock)
{

View File

@ -0,0 +1,64 @@
using System.Collections.Generic;
using System.Dynamic;
using System.Linq;
using Artemis.Managers;
using Artemis.Profiles.Lua.Modules.Gui;
using Artemis.Services;
using Caliburn.Micro;
using MoonSharp.Interpreter;
using Ninject.Parameters;
namespace Artemis.Profiles.Lua.Modules
{
[MoonSharpUserData]
public class LuaGuiModule : LuaModule
{
private readonly WindowService _windowService;
private readonly List<LuaWindowViewModel> _windows;
public LuaGuiModule(LuaManager luaManager, WindowService windowService) : base(luaManager)
{
_windowService = windowService;
_windows = new List<LuaWindowViewModel>();
}
public override string ModuleName => "Gui";
public LuaWindowViewModel CreateWindow(string title, double width, double height)
{
lock (_windows)
{
dynamic settings = new ExpandoObject();
settings.Width = width;
settings.Height = height;
IParameter[] args =
{
new ConstructorArgument("luaManager", LuaManager)
};
Execute.OnUIThread(() => _windows.Add(_windowService.ShowWindow<LuaWindowViewModel>("Artemis | " + title, settings, args)));
return _windows.Last();
}
}
public void AddEditorButton(string name, DynValue action)
{
Execute.OnUIThread(() => LuaManager.EditorButtons.Add(new EditorButton(LuaManager, name, action)));
}
public void RemoveEditorButton(string name)
{
var button = LuaManager.EditorButtons.FirstOrDefault(b => b.Text == name);
if (button != null)
Execute.OnUIThread(() => LuaManager.EditorButtons.Remove(button));
}
public override void Dispose()
{
foreach (var window in _windows)
window.TryClose();
Execute.OnUIThread(() => LuaManager.EditorButtons.Clear());
}
}
}

View File

@ -0,0 +1,68 @@
using Artemis.DAL;
using Artemis.Managers;
using Artemis.Settings;
using MoonSharp.Interpreter;
using static MoonSharp.Interpreter.Serialization.Json.JsonTableConverter;
namespace Artemis.Profiles.Lua.Modules
{
[MoonSharpUserData]
public class LuaStorageModule : LuaModule
{
private readonly Table _globalValues;
private readonly Table _profileValues;
private readonly LuaGlobalSettings _globalSettings;
public LuaStorageModule(LuaManager luaManager) : base(luaManager)
{
_globalSettings = SettingsProvider.Load<LuaGlobalSettings>();
// Load profile values
if (LuaManager.ProfileModel.LuaStorage != null)
_profileValues = JsonToTable(LuaManager.ProfileModel.LuaStorage, LuaManager.LuaScript);
else
_profileValues = new Table(LuaManager.LuaScript);
// Load global values
if (_globalSettings.GlobalValues != null)
_globalValues = JsonToTable(_globalSettings.GlobalValues, LuaManager.LuaScript);
else
_globalValues = new Table(LuaManager.LuaScript);
// Set the values onto the globals table so scripters can access them
LuaManager.LuaScript.Globals["ProfileStorage"] = _profileValues;
LuaManager.LuaScript.Globals["GlobalStorage"] = _globalValues;
}
public override string ModuleName => null;
public override void Dispose()
{
// Store profile values
LuaManager.ProfileModel.LuaStorage = _profileValues.TableToJson();
ProfileProvider.AddOrUpdate(LuaManager.ProfileModel);
// Store global values
_globalSettings.GlobalValues = _globalValues.TableToJson();
_globalSettings.Save();
}
}
public class LuaGlobalSettings : IArtemisSettings
{
public string GlobalValues { get; set; }
public void Save()
{
SettingsProvider.Save(this);
}
public void Reset(bool save = false)
{
GlobalValues = null;
if (save)
Save();
}
}
}

View File

@ -38,6 +38,7 @@ namespace Artemis.Profiles
public int Width { get; set; }
public int Height { get; set; }
public string LuaScript { get; set; }
public string LuaStorage { get; set; }
[JsonIgnore]
public string Slug => new string(Name.Where(ch => !_invalidFileNameChars.Contains(ch)).ToArray());

View File

@ -53,7 +53,7 @@ using System.Windows;
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.9.0.0")]
[assembly: AssemblyFileVersion("1.9.0.0")]
[assembly: AssemblyVersion("1.10.0.0")]
[assembly: AssemblyFileVersion("1.10.0.0")]
[assembly: InternalsVisibleTo("Artemis.Explorables")]

View File

@ -0,0 +1,41 @@
using System.IO;
using System.Linq;
using System.Threading;
using Microsoft.Win32;
using NLog;
namespace Artemis.Services
{
public static class CompatibilityService
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
// Checks to see if RivaTuner Statistics Server is installed and if so places a profile disabling it for Artemis
public static void CheckRivaTuner()
{
// Find the installation path in the registry
var key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\WOW6432Node\Unwinder\RTSS");
var value = key?.GetValue("InstallPath");
var installDir = Path.GetDirectoryName(value?.ToString());
if (installDir == null)
return;
var profilePath = Path.Combine(installDir, "ProfileTemplates\\Artemis.exe.cfg");
if (File.Exists(profilePath))
return;
File.WriteAllText(profilePath, "[Hooking]\r\nEnableHooking\t\t= 0");
// It's kill or be killed...
var rtssProcess = System.Diagnostics.Process.GetProcessesByName("RTSS").FirstOrDefault();
var rtssHookProcess = System.Diagnostics.Process.GetProcessesByName("RTSSHooksLoader64").FirstOrDefault();
rtssProcess?.Kill();
rtssHookProcess?.Kill();
// Funnily enough sleeping prevents the RTSS injection so that the process gets killed in time
Thread.Sleep(1000);
Logger.Info("Detected that RivaTuner Statistics Server is installed, inserted a profile to prevent crashes.");
}
}
}

View File

@ -14,23 +14,25 @@ namespace Artemis.Services
_kernel = kernel;
}
public T ShowWindow<T>(string windowName, params IParameter[] param) where T : class
public T ShowWindow<T>(string windowName, dynamic settings = null, params IParameter[] param) where T : class
{
var windowManager = new WindowManager();
var viewModel = _kernel.Get<T>(param);
dynamic settings = new ExpandoObject();
if (settings == null)
settings = new ExpandoObject();
settings.Title = windowName;
windowManager.ShowWindow(viewModel, null, settings);
return viewModel;
}
public T ShowDialog<T>(string dialogName, params IParameter[] param) where T : class
public T ShowDialog<T>(string dialogName, dynamic settings = null, params IParameter[] param) where T : class
{
var windowManager = new WindowManager();
var viewModel = _kernel.Get<T>(param);
dynamic settings = new ExpandoObject();
if (settings == null)
settings = new ExpandoObject();
settings.Title = dialogName;
windowManager.ShowDialog(viewModel, null, settings);
return viewModel;

View File

@ -5,9 +5,11 @@ using System.Windows;
using Artemis.DAL;
using Artemis.Profiles.Layers.Types.AmbientLight.ScreenCapturing;
using Artemis.Utilities;
using Artemis.Utilities.ActiveWindowDetection;
using Caliburn.Micro;
using MahApps.Metro;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Squirrel;
namespace Artemis.Settings
@ -68,6 +70,11 @@ namespace Artemis.Settings
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate)]
public string LogLevel { get; set; }
[DefaultValue(ActiveWindowDetectionType.Events)]
[JsonConverter(typeof(StringEnumConverter))]
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate)]
public ActiveWindowDetectionType ActiveWindowDetection { get; set; }
public Version LastRanVersion { get; set; }
public void Save()
@ -75,6 +82,7 @@ namespace Artemis.Settings
SettingsProvider.Save(this);
Logging.SetupLogging(LogLevel);
ActiveWindowHelper.SetActiveWindowDetectionType(ActiveWindowDetection);
ApplyAutorun();
ApplyTheme();
ApplyGamestatePort();

View File

@ -8,6 +8,7 @@ namespace Artemis.Settings
{
public GamePointersCollection RocketLeague { get; set; }
public GamePointersCollection WorldOfWarcraft { get; set; }
public GamePointersCollection Terraria { get; set; }
public void Save()
{

View File

@ -210,7 +210,7 @@
ItemsSource="{Binding AvailableBrushTypes, RelativeSource={RelativeSource TemplatedParent}}" HorizontalAlignment="Center">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Rows="1" Columns="4" />
<UniformGrid Rows="1" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemContainerStyle>

View File

@ -0,0 +1,9 @@
namespace Artemis.Utilities.ActiveWindowDetection
{
public enum ActiveWindowDetectionType
{
Disabled = -1,
Events = 0,
Timer = 1,
}
}

View File

@ -0,0 +1,48 @@
namespace Artemis.Utilities.ActiveWindowDetection
{
public static class ActiveWindowHelper
{
#region Properties & Fields
private static ActiveWindowDetectionType _currentDetectionType = ActiveWindowDetectionType.Disabled;
private static IActiveWindowDetector _activeWindowDetector;
public static string ActiveWindowProcessName => _activeWindowDetector?.ActiveWindowProcessName ?? string.Empty;
public static string ActiveWindowWindowTitle => _activeWindowDetector?.ActiveWindowWindowTitle ?? string.Empty;
public static bool MainWindowActive => ActiveWindowProcessName.Contains("Artemis");
#endregion
#region Methods
public static void Dispose()
{
_activeWindowDetector?.Dispose();
}
public static void SetActiveWindowDetectionType(ActiveWindowDetectionType detectionType)
{
if (detectionType == _currentDetectionType) return;
_activeWindowDetector?.Dispose();
switch (detectionType)
{
case ActiveWindowDetectionType.Events:
_activeWindowDetector = new EventActiveWindowDetector();
break;
case ActiveWindowDetectionType.Timer:
_activeWindowDetector = new TimerActiveWindowDetector();
break;
case ActiveWindowDetectionType.Disabled:
_activeWindowDetector = null;
break;
}
_activeWindowDetector?.Initialize();
_currentDetectionType = detectionType;
}
#endregion
}
}

View File

@ -2,9 +2,9 @@
using System.Runtime.InteropServices;
using System.Text;
namespace Artemis.Utilities
namespace Artemis.Utilities.ActiveWindowDetection
{
public static class ActiveWindowHelper
public class EventActiveWindowDetector : IActiveWindowDetector
{
#region DLL-Imports
@ -41,39 +41,38 @@ namespace Artemis.Utilities
#region Properties & Fields
// DarthAffe 17.12.2016: We need to keep a reference to this or it might get collected by the garbage collector and cause some random crashes afterwards.
private static WinEventDelegate _activeWindowChangedDelegate;
private static IntPtr _activeWindowEventHook;
private WinEventDelegate _activeWindowChangedDelegate;
private IntPtr _activeWindowEventHook;
private static WinEventDelegate _windowTitleChangedDelegate;
private static IntPtr _windowTitleEventHook;
private WinEventDelegate _windowTitleChangedDelegate;
private IntPtr _windowTitleEventHook;
private static WinEventDelegate _windowMinimizedChangedDelegate;
private static IntPtr _windowMinimizedEventHook;
private WinEventDelegate _windowMinimizedChangedDelegate;
private IntPtr _windowMinimizedEventHook;
private static IntPtr _activeWindow;
private IntPtr _activeWindow;
public static string ActiveWindowProcessName { get; private set; } = string.Empty;
public static string ActiveWindowWindowTitle { get; private set; } = string.Empty;
public static bool MainWindowActive => ActiveWindowProcessName.Contains("Artemis");
public string ActiveWindowProcessName { get; private set; } = string.Empty;
public string ActiveWindowWindowTitle { get; private set; } = string.Empty;
#endregion
#region Methods
private static void ActiveWindowChanged(IntPtr hWinEventHook, uint eventType,
private void ActiveWindowChanged(IntPtr hWinEventHook, uint eventType,
IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime)
{
UpdateForWindow(hwnd);
}
private static void WindowTitleChanged(IntPtr hWinEventHook, uint eventType,
private void WindowTitleChanged(IntPtr hWinEventHook, uint eventType,
IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime)
{
if (_activeWindow == hwnd)
UpdateForWindow(hwnd);
}
private static void WindowMinimizedChanged(IntPtr hWinEventHook, uint eventType,
private void WindowMinimizedChanged(IntPtr hWinEventHook, uint eventType,
IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime)
{
// DarthAffe 19.12.2016: We expect currently un-minimized windows to be active.
@ -81,7 +80,7 @@ namespace Artemis.Utilities
UpdateForWindow(hwnd);
}
private static void UpdateForWindow(IntPtr hwnd)
private void UpdateForWindow(IntPtr hwnd)
{
_activeWindow = hwnd;
@ -89,7 +88,7 @@ namespace Artemis.Utilities
ActiveWindowWindowTitle = GetActiveWindowTitle(hwnd) ?? string.Empty;
}
private static string GetActiveWindowProcessName(IntPtr hwnd)
private string GetActiveWindowProcessName(IntPtr hwnd)
{
try
{
@ -103,7 +102,7 @@ namespace Artemis.Utilities
}
}
private static string GetActiveWindowTitle(IntPtr hwnd)
private string GetActiveWindowTitle(IntPtr hwnd)
{
try
{
@ -116,7 +115,7 @@ namespace Artemis.Utilities
}
}
public static void Initialize()
public void Initialize()
{
try
{
@ -147,7 +146,7 @@ namespace Artemis.Utilities
}
}
public static void Dispose()
public void Dispose()
{
try
{

View File

@ -0,0 +1,12 @@
using System;
namespace Artemis.Utilities.ActiveWindowDetection
{
public interface IActiveWindowDetector : IDisposable
{
string ActiveWindowProcessName { get; }
string ActiveWindowWindowTitle { get; }
void Initialize();
}
}

View File

@ -0,0 +1,91 @@
using System;
using System.Runtime.InteropServices;
using System.Text;
using System.Timers;
namespace Artemis.Utilities.ActiveWindowDetection
{
public class TimerActiveWindowDetector : IActiveWindowDetector
{
#region DLL-Imports
[DllImport("user32.dll")]
static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll")]
private static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int count);
[DllImport("user32.dll")]
private static extern IntPtr GetWindowThreadProcessId(IntPtr hWnd, out uint processId);
#endregion
#region Constants
private const int TIMER_INTERVAL = 1000;
private const int MAX_TITLE_LENGTH = 256;
#endregion
#region Properties & Fields
private Timer _timer;
public string ActiveWindowProcessName { get; private set; }
public string ActiveWindowWindowTitle { get; private set; }
#endregion
#region Methods
private void TimerOnElapsed(object sender, ElapsedEventArgs elapsedEventArgs)
{
IntPtr activeWindow = GetForegroundWindow();
ActiveWindowProcessName = GetActiveWindowProcessName(activeWindow);
ActiveWindowWindowTitle = GetActiveWindowTitle(activeWindow);
}
private string GetActiveWindowProcessName(IntPtr hwnd)
{
try
{
uint pid;
GetWindowThreadProcessId(hwnd, out pid);
return System.Diagnostics.Process.GetProcessById((int)pid).ProcessName;
}
catch
{
return null;
}
}
private string GetActiveWindowTitle(IntPtr hwnd)
{
try
{
StringBuilder buffer = new StringBuilder(MAX_TITLE_LENGTH);
return GetWindowText(hwnd, buffer, MAX_TITLE_LENGTH) > 0 ? buffer.ToString() : null;
}
catch
{
return null;
}
}
public void Initialize()
{
_timer = new Timer(TIMER_INTERVAL) { AutoReset = true };
_timer.Elapsed += TimerOnElapsed;
_timer.Start();
}
public void Dispose()
{
_timer?.Stop();
_timer?.Dispose();
_timer = null;
}
#endregion
}
}

View File

@ -37,8 +37,11 @@ namespace Artemis.Utilities.DataReaders
try
{
// Change the registry key to point to the fake DLL
var key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Classes\CLSID\{a6519e67-7632-4375-afdf-caa889744403}\ServerBinary", true);
key?.SetValue(null, DllPath + @"\LogitechLed.dll");
// Key doesn't exist yet on systems without LGS installed
var key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Classes\CLSID\{a6519e67-7632-4375-afdf-caa889744403}\ServerBinary", true) ??
Registry.LocalMachine.CreateSubKey(@"SOFTWARE\Classes\CLSID\{a6519e67-7632-4375-afdf-caa889744403}\ServerBinary", true);
key.SetValue(null, DllPath + @"\LogitechLed.dll");
// Make sure the fake DLL is in place
if (!Directory.Exists(DllPath))

View File

@ -148,6 +148,8 @@ namespace Artemis.Utilities
offsetSettings.RocketLeague = pointers.FirstOrDefault(p => p.Game == "RocketLeague");
if (pointers.FirstOrDefault(p => p.Game == "WorldOfWarcraft") != null)
offsetSettings.WorldOfWarcraft = pointers.FirstOrDefault(p => p.Game == "WorldOfWarcraft");
if (pointers.FirstOrDefault(p => p.Game == "Terraria") != null)
offsetSettings.Terraria = pointers.FirstOrDefault(p => p.Game == "Terraria");
offsetSettings.Save();
}

View File

@ -8,6 +8,7 @@ using Artemis.Events;
using Artemis.Managers;
using Artemis.Services;
using Artemis.Settings;
using Artemis.Utilities.ActiveWindowDetection;
using Caliburn.Micro;
using MahApps.Metro.Controls;
using NLog;
@ -37,6 +38,8 @@ namespace Artemis.ViewModels.Flyouts
LogLevels = new BindableCollection<string>();
LogLevels.AddRange(LogLevel.AllLoggingLevels.Select(l => l.Name));
ActiveWindowDetections = new BindableCollection<ActiveWindowDetectionType>(Enum.GetValues(typeof(ActiveWindowDetectionType)).Cast<ActiveWindowDetectionType>());
PropertyChanged += KeyboardUpdater;
mainManager.EnabledChanged += MainManagerEnabledChanged;
mainManager.ModuleManager.EffectChanged += EffectManagerEffectChanged;
@ -96,6 +99,7 @@ namespace Artemis.ViewModels.Flyouts
public string VersionText => "Artemis " + Assembly.GetExecutingAssembly().GetName().Version;
public BindableCollection<string> LogLevels { get; set; }
public BindableCollection<ActiveWindowDetectionType> ActiveWindowDetections { get; set; }
public string SelectedTheme
{
@ -130,6 +134,17 @@ namespace Artemis.ViewModels.Flyouts
}
}
public ActiveWindowDetectionType SelectedActiveWindowDetection
{
get { return GeneralSettings.ActiveWindowDetection; }
set
{
if (value == GeneralSettings.ActiveWindowDetection) return;
GeneralSettings.ActiveWindowDetection = value;
NotifyOfPropertyChange(() => SelectedActiveWindowDetection);
}
}
public string SelectedKeyboardProvider
{
get { return _selectedKeyboardProvider; }

View File

@ -2,7 +2,6 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
@ -12,7 +11,6 @@ using System.Windows.Forms;
using System.Windows.Input;
using System.Windows.Media;
using Artemis.DAL;
using Artemis.DeviceProviders;
using Artemis.Events;
using Artemis.Managers;
using Artemis.Models;
@ -21,10 +19,12 @@ using Artemis.Profiles;
using Artemis.Profiles.Layers.Interfaces;
using Artemis.Profiles.Layers.Models;
using Artemis.Profiles.Layers.Types.Folder;
using Artemis.Profiles.Lua.Modules.Gui;
using Artemis.Properties;
using Artemis.Services;
using Artemis.Styles.DropTargetAdorners;
using Artemis.Utilities;
using Artemis.Utilities.ActiveWindowDetection;
using Caliburn.Micro;
using Castle.Components.DictionaryAdapter;
using GongSolutions.Wpf.DragDrop;
@ -46,21 +46,20 @@ namespace Artemis.ViewModels
{
public sealed class ProfileEditorViewModel : Screen, IDropTarget
{
private readonly KeybindModel _copyKeybind;
private readonly DeviceManager _deviceManager;
private readonly MetroDialogService _dialogService;
private readonly LoopManager _loopManager;
private readonly ModuleModel _moduleModel;
private readonly KeybindModel _copyKeybind;
private readonly KeybindModel _pasteKeybind;
private ImageSource _keyboardPreview;
private ObservableCollection<LayerModel> _layers;
private readonly KeybindModel _pasteKeybind;
private ObservableCollection<string> _profileNames;
private bool _saving;
private LayerModel _selectedLayer;
private bool _showAll;
public ProfileEditorViewModel(ProfileEditorModel profileEditorModel, DeviceManager deviceManager,
LoopManager loopManager, ModuleModel moduleModel, MetroDialogService dialogService)
public ProfileEditorViewModel(ProfileEditorModel profileEditorModel, DeviceManager deviceManager, LoopManager loopManager, LuaManager luaManager, ModuleModel moduleModel, MetroDialogService dialogService)
{
_deviceManager = deviceManager;
_loopManager = loopManager;
@ -72,6 +71,7 @@ namespace Artemis.ViewModels
ProfileNames = new ObservableCollection<string>();
Layers = new ObservableCollection<LayerModel>();
ProfileEditorModel = profileEditorModel;
LuaManager = luaManager;
ShowAll = true;
PropertyChanged += EditorStateHandler;
@ -102,6 +102,11 @@ namespace Artemis.ViewModels
#region LUA
public void ClickedLuaButton(EditorButton button)
{
button.Invoke();
}
public void EditLua()
{
if (SelectedProfile == null)
@ -123,6 +128,7 @@ namespace Artemis.ViewModels
#region Properties
public ProfileEditorModel ProfileEditorModel { get; }
public LuaManager LuaManager { get; }
public ObservableCollection<string> ProfileNames
{
@ -325,7 +331,7 @@ namespace Artemis.ViewModels
public void LayerToClipboard()
{
if (SelectedLayer == null || !ActiveWindowHelper.MainWindowActive)
if (SelectedLayer == null || !ActiveWindowHelper.MainWindowActive || !IsActive)
return;
// Probably not how the cool kids do it but leveraging on JsonConvert gives flawless serialization
@ -334,9 +340,11 @@ namespace Artemis.ViewModels
public void ClipboardToLayer()
{
if (!ActiveWindowHelper.MainWindowActive)
if (!ActiveWindowHelper.MainWindowActive || !IsActive)
return;
try
{
GeneralHelpers.ExecuteSta(() =>
{
var data = (string) Clipboard.GetData("layer");
@ -348,9 +356,7 @@ namespace Artemis.ViewModels
return;
if (SelectedLayer != null)
{
SelectedLayer.InsertAfter(layerModel);
}
else
{
SelectedProfile.Layers.Add(layerModel);
@ -359,6 +365,11 @@ namespace Artemis.ViewModels
Execute.OnUIThread(() => UpdateLayerList(layerModel));
});
}
catch (Exception)
{
// ignored
}
}
private void UpdateLayerList(LayerModel selectModel)
{
@ -405,6 +416,9 @@ namespace Artemis.ViewModels
if (_saving || SelectedProfile == null || _deviceManager.ChangingKeyboard)
return;
SelectedProfile.Width = _deviceManager.ActiveKeyboard.Width;
SelectedProfile.Height = _deviceManager.ActiveKeyboard.Height;
_saving = true;
try
{
@ -421,8 +435,7 @@ namespace Artemis.ViewModels
{
if (_deviceManager.ActiveKeyboard == null)
{
_dialogService.ShowMessageBox("Cannot add profile.",
"To add a profile, please select a keyboard in the options menu first.");
_dialogService.ShowMessageBox("Cannot add profile.", "To add a profile, please select a keyboard in the options menu first.");
return;
}
@ -666,7 +679,7 @@ namespace Artemis.ViewModels
return;
var pos = GetScaledPosition(e);
var hoverLayer = GetLayers().Where(l => l.MustDraw()).FirstOrDefault(l => l.Properties.PropertiesRect(1).Contains(pos.X, pos.Y));
var hoverLayer = GetHoverLayer(pos.X, pos.Y);
if (hoverLayer != null)
SelectedLayer = hoverLayer;
@ -682,7 +695,7 @@ namespace Artemis.ViewModels
return;
var pos = GetScaledPosition(e);
var hoverLayer = GetLayers().Where(l => l.MustDraw()).FirstOrDefault(l => l.Properties.PropertiesRect(1).Contains(pos.X, pos.Y));
var hoverLayer = GetHoverLayer(pos.X, pos.Y);
HandleDragging(e, pos.X, pos.Y, hoverLayer);
@ -701,10 +714,9 @@ namespace Artemis.ViewModels
: Cursors.SizeAll;
}
else
{
KeyboardPreviewCursor = Cursors.Hand;
}
}
private Point GetScaledPosition(MouseEventArgs e)
{
@ -716,8 +728,8 @@ namespace Artemis.ViewModels
var heightScale = sourceImage.ActualHeight / _deviceManager.ActiveKeyboard.PreviewSettings.BackgroundRectangle.Height;
// Remove the preview settings' offset from the cursor postion
pos.X = pos.X - (previewSettings.OverlayRectangle.X * widthScale);
pos.Y = pos.Y - (previewSettings.OverlayRectangle.Y * heightScale);
pos.X = pos.X - previewSettings.OverlayRectangle.X * widthScale;
pos.Y = pos.Y - previewSettings.OverlayRectangle.Y * heightScale;
// Scale the X and Y position down to match the keyboard's physical size and thus the layer positions
pos.X = pos.X * (SelectedProfile.Width / (previewSettings.OverlayRectangle.Width * widthScale));
@ -726,6 +738,15 @@ namespace Artemis.ViewModels
return pos;
}
private LayerModel GetHoverLayer(double x, double y)
{
// Prefer the selected layer as the hover layer even if it's underneath something else
if (SelectedLayer != null && SelectedLayer.Properties.PropertiesRect(1).Contains(x, y))
return SelectedLayer;
return GetLayers().Where(l => l.MustDraw()).FirstOrDefault(l => l.Properties.PropertiesRect(1).Contains(x, y));
}
public Cursor KeyboardPreviewCursor
{
get { return _keyboardPreviewCursor; }

View File

@ -6,7 +6,7 @@
xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls"
xmlns:cal="http://www.caliburnproject.org"
mc:Ignorable="d"
d:DesignHeight="600" d:DesignWidth="300">
d:DesignHeight="600" d:DesignWidth="310">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
@ -25,6 +25,7 @@
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
@ -95,29 +96,35 @@
HorizontalAlignment="Right" Width="140" Minimum="1" Maximum="60"
Value="{Binding Path=GeneralSettings.ScreenCaptureFPS, Mode=TwoWay}" />
<!-- Logging -->
<Label Grid.Row="9" Grid.Column="0" Margin="5" VerticalAlignment="Center" HorizontalAlignment="Left"
Content="Log level:" />
<ComboBox Grid.Row="9" Grid.Column="1" x:Name="LogLevels" Margin="10" VerticalAlignment="Center"
Content="Active window detection" />
<ComboBox Grid.Row="9" Grid.Column="1" x:Name="ActiveWindowDetections" Margin="10" VerticalAlignment="Center"
HorizontalAlignment="Right"
Width="140" />
<Button Grid.Row="10" Grid.Column="0" Margin="10" x:Name="ShowLogs" Content="Show logs"
<!-- Logging -->
<Label Grid.Row="10" Grid.Column="0" Margin="5" VerticalAlignment="Center" HorizontalAlignment="Left"
Content="Log level:" />
<ComboBox Grid.Row="10" Grid.Column="1" x:Name="LogLevels" Margin="10" VerticalAlignment="Center"
HorizontalAlignment="Right"
Width="140" />
<Button Grid.Row="11" Grid.Column="0" Margin="10" x:Name="ShowLogs" Content="Show logs"
VerticalAlignment="Center" Width="100" HorizontalAlignment="Left"
Style="{DynamicResource SquareButtonStyle}" />
<Button Grid.Row="10" Grid.Column="1" Margin="10" x:Name="ShowDebug" Content="Show debugger"
<Button Grid.Row="11" Grid.Column="1" Margin="10" x:Name="ShowDebug" Content="Show debugger"
VerticalAlignment="Center" Width="100" HorizontalAlignment="Right"
Style="{DynamicResource SquareButtonStyle}" />
<!-- Buttons -->
<Button Grid.Row="11" Grid.Column="0" Margin="10" x:Name="ResetSettings" Content="Reset settings"
<Button Grid.Row="12" Grid.Column="0" Margin="10" x:Name="ResetSettings" Content="Reset settings"
VerticalAlignment="Center" HorizontalAlignment="Left" Width="100"
Style="{DynamicResource SquareButtonStyle}" />
<Button Grid.Row="11" Grid.Column="1" Margin="11" x:Name="SaveSettings" Content="Save changes"
<Button Grid.Row="12" Grid.Column="1" Margin="11" x:Name="SaveSettings" Content="Save changes"
VerticalAlignment="Center" HorizontalAlignment="Right" Width="100"
Style="{DynamicResource SquareButtonStyle}" />
<!-- Version -->
<Grid Grid.Row="12" Grid.Column="0" Grid.ColumnSpan="2" Margin="10" VerticalAlignment="Bottom">
<Grid Grid.Row="13" Grid.Column="0" Grid.ColumnSpan="2" Margin="10" VerticalAlignment="Bottom">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />

View File

@ -1,16 +1,8 @@
<UserControl x:Class="Artemis.Views.ProfileEditorView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:cal="http://www.caliburnproject.org"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:itemBehaviours="clr-namespace:Artemis.ItemBehaviours"
xmlns:dragDrop="clr-namespace:GongSolutions.Wpf.DragDrop;assembly=GongSolutions.Wpf.DragDrop"
xmlns:converters="clr-namespace:Artemis.Utilities.Converters"
xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls"
mc:Ignorable="d"
d:DesignHeight="400" d:DesignWidth="1060">
<UserControl x:Class="Artemis.Views.ProfileEditorView" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:cal="http://www.caliburnproject.org"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" xmlns:itemBehaviours="clr-namespace:Artemis.ItemBehaviours"
xmlns:dragDrop="clr-namespace:GongSolutions.Wpf.DragDrop;assembly=GongSolutions.Wpf.DragDrop" xmlns:converters="clr-namespace:Artemis.Utilities.Converters"
xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls" mc:Ignorable="d" d:DesignHeight="400" d:DesignWidth="1060">
<UserControl.Resources>
<converters:LayerOrderConverter x:Key="LayerOrderConverter" />
</UserControl.Resources>
@ -22,7 +14,8 @@
<Grid.RowDefinitions>
<RowDefinition Height="40" />
<RowDefinition Height="*" />
<RowDefinition Height="60" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<!-- Preview -->
@ -32,7 +25,9 @@
<Border.Effect>
<DropShadowEffect x:Name="ShadowEffect" ShadowDepth="0" Color="{DynamicResource HighlightColor}" Opacity="1" BlurRadius="25" />
</Border.Effect>
<Image Source="{Binding Path=KeyboardPreview}" MinHeight="10" MinWidth="10" Stretch="Uniform" Cursor="{Binding Path=KeyboardPreviewCursor}" IsEnabled="{Binding Path=EditorEnabled, Mode=OneWay}" cal:Message.Attach="
<Image Source="{Binding Path=KeyboardPreview}" MinHeight="10" MinWidth="10" Stretch="Uniform" Cursor="{Binding Path=KeyboardPreviewCursor}"
IsEnabled="{Binding Path=EditorEnabled, Mode=OneWay}"
cal:Message.Attach="
[Event MouseMove] = [Action MouseMoveKeyboardPreview($eventArgs)];
[Event MouseDown] = [Action MouseDownKeyboardPreview($eventArgs)];
[Event MouseUp] = [Action MouseUpKeyboardPreview($eventArgs)]" />
@ -43,8 +38,8 @@
<StackPanel Orientation="Horizontal" Margin="0,5,0,0">
<Label Content="Active profile" />
<ComboBox Width="220" VerticalAlignment="Top" x:Name="ProfileNames" Margin="5,0,0,0" />
<Button x:Name="AddProfile" VerticalAlignment="Top" Style="{DynamicResource SquareButtonStyle}"
Width="26" Height="26" HorizontalAlignment="Right" Margin="10,0,0,0" ToolTip="Add profile">
<Button x:Name="AddProfile" VerticalAlignment="Top" Style="{DynamicResource SquareButtonStyle}" Width="26" Height="26" HorizontalAlignment="Right" Margin="10,0,0,0"
ToolTip="Add profile">
<Button.Content>
<Rectangle Fill="{Binding Path=Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}" Width="12" Height="12">
<Rectangle.OpacityMask>
@ -53,9 +48,8 @@
</Rectangle>
</Button.Content>
</Button>
<Button x:Name="RenameProfile" VerticalAlignment="Top" Style="{DynamicResource SquareButtonStyle}"
Width="26" Height="26" HorizontalAlignment="Right" Margin="10,0,0,0" ToolTip="Rename profile"
IsEnabled="{Binding Path=EditorEnabled, Mode=OneWay}">
<Button x:Name="RenameProfile" VerticalAlignment="Top" Style="{DynamicResource SquareButtonStyle}" Width="26" Height="26" HorizontalAlignment="Right" Margin="10,0,0,0"
ToolTip="Rename profile" IsEnabled="{Binding Path=EditorEnabled, Mode=OneWay}">
<Button.Content>
<Rectangle Fill="{Binding Path=Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}" Width="12" Height="12">
<Rectangle.OpacityMask>
@ -74,7 +68,8 @@
</Rectangle>
</Button.Content>
</Button>
<Button x:Name="DeleteProfile" VerticalAlignment="Top" Style="{DynamicResource SquareButtonStyle}" Width="26" Height="26" HorizontalAlignment="Right" Margin="10,0,0,0" ToolTip="Delete profile" IsEnabled="{Binding Path=EditorEnabled, Mode=OneWay}">
<Button x:Name="DeleteProfile" VerticalAlignment="Top" Style="{DynamicResource SquareButtonStyle}" Width="26" Height="26" HorizontalAlignment="Right" Margin="10,0,0,0"
ToolTip="Delete profile" IsEnabled="{Binding Path=EditorEnabled, Mode=OneWay}">
<Button.Content>
<Rectangle Fill="{Binding Path=Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}" Width="12" Height="12">
<Rectangle.OpacityMask>
@ -84,17 +79,12 @@
</Button.Content>
</Button>
</StackPanel>
<TextBlock VerticalAlignment="Top" Foreground="{DynamicResource HighlightBrush}" HorizontalAlignment="Left" Margin="5,5,0,0" Text="Note: To edit a default profile, duplicate it first." FontWeight="Bold" />
</StackPanel>
<StackPanel Grid.Column="0" Grid.Row="2" Orientation="Horizontal" Margin="0,5,0,0" HorizontalAlignment="Right">
<Button x:Name="ImportProfile" VerticalAlignment="Top" Style="{DynamicResource SquareButtonStyle}"
Height="26" HorizontalAlignment="Right">
<Button x:Name="ImportProfile" VerticalAlignment="Top" Style="{DynamicResource SquareButtonStyle}" Height="26" HorizontalAlignment="Right">
<Button.Content>
<StackPanel Orientation="Horizontal">
<Rectangle
Fill="{Binding Path=Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}"
Width="12" Height="12" Margin="3,0">
<Rectangle Fill="{Binding Path=Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}" Width="12" Height="12" Margin="3,0">
<Rectangle.OpacityMask>
<VisualBrush Visual="{StaticResource appbar_cabinet_in}" Stretch="Fill" />
</Rectangle.OpacityMask>
@ -103,13 +93,11 @@
</StackPanel>
</Button.Content>
</Button>
<Button x:Name="ExportProfile" VerticalAlignment="Top" Style="{DynamicResource SquareButtonStyle}"
Height="26" HorizontalAlignment="Right" Margin="10,0,0,0" IsEnabled="{Binding ProfileSelected}">
<Button x:Name="ExportProfile" VerticalAlignment="Top" Style="{DynamicResource SquareButtonStyle}" Height="26" HorizontalAlignment="Right" Margin="10,0,0,0"
IsEnabled="{Binding ProfileSelected}">
<Button.Content>
<StackPanel Orientation="Horizontal">
<Rectangle
Fill="{Binding Path=Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}"
Width="12" Height="12" Margin="3,0">
<Rectangle Fill="{Binding Path=Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}" Width="12" Height="12" Margin="3,0">
<Rectangle.OpacityMask>
<VisualBrush Visual="{StaticResource appbar_cabinet_out}" Stretch="Fill" />
</Rectangle.OpacityMask>
@ -118,14 +106,11 @@
</StackPanel>
</Button.Content>
</Button>
<Button x:Name="EditLua" VerticalAlignment="Top" Style="{DynamicResource SquareButtonStyle}" Height="26"
HorizontalAlignment="Right" Margin="10,0,0,0" IsEnabled="{Binding Path=EditorEnabled, Mode=OneWay}"
Visibility="{Binding Path=LuaButtonVisible, Converter={StaticResource BoolToVis} }">
<Button x:Name="EditLua" VerticalAlignment="Top" Style="{DynamicResource SquareButtonStyle}" Height="26" HorizontalAlignment="Right" Margin="10,0,0,0"
IsEnabled="{Binding Path=EditorEnabled, Mode=OneWay}" Visibility="{Binding Path=LuaButtonVisible, Converter={StaticResource BoolToVis} }">
<Button.Content>
<StackPanel Orientation="Horizontal">
<Rectangle
Fill="{Binding Path=Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}"
Width="12" Height="12" Margin="3,0">
<Rectangle Fill="{Binding Path=Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}" Width="12" Height="12" Margin="3,0">
<Rectangle.OpacityMask>
<VisualBrush Visual="{StaticResource appbar_code_xml}" Stretch="Fill" />
</Rectangle.OpacityMask>
@ -154,8 +139,7 @@
ItemsSource="{Binding Path=Layers, Converter={StaticResource LayerOrderConverter}, ConverterParameter=Order}" IsEnabled="{Binding Path=EditorEnabled, Mode=OneWay}"
cal:Message.Attach="[Event MouseDoubleClick] = [Action EditLayerFromDoubleClick]">
<i:Interaction.Behaviors>
<itemBehaviours:BindableSelectedItemBehavior
SelectedItem="{Binding SelectedLayer, Mode=TwoWay}" />
<itemBehaviours:BindableSelectedItemBehavior SelectedItem="{Binding SelectedLayer, Mode=TwoWay}" />
</i:Interaction.Behaviors>
<TreeView.Resources>
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/BaseDark.xaml" />
@ -185,9 +169,8 @@
</TreeView>
</Border>
<StackPanel Grid.Column="1" Grid.Row="2" Orientation="Horizontal" Margin="0,5,0,0" HorizontalAlignment="Right">
<Button x:Name="AddLayer" VerticalAlignment="Top"
Style="{DynamicResource SquareButtonStyle}" IsEnabled="{Binding Path=EditorEnabled, Mode=OneWay}"
Width="26" Height="26" ToolTip="Add layer" HorizontalAlignment="Left">
<Button x:Name="AddLayer" VerticalAlignment="Top" Style="{DynamicResource SquareButtonStyle}" IsEnabled="{Binding Path=EditorEnabled, Mode=OneWay}" Width="26" Height="26"
ToolTip="Add layer" HorizontalAlignment="Left">
<Button.Content>
<Rectangle Fill="{Binding Path=Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}" Width="12" Height="12">
<Rectangle.OpacityMask>
@ -196,9 +179,8 @@
</Rectangle>
</Button.Content>
</Button>
<Button x:Name="AddFolder" VerticalAlignment="Top"
Style="{DynamicResource SquareButtonStyle}" IsEnabled="{Binding Path=EditorEnabled, Mode=OneWay}"
Width="26" Height="26" ToolTip="Add folder" HorizontalAlignment="Left" Margin="10,0,0,0">
<Button x:Name="AddFolder" VerticalAlignment="Top" Style="{DynamicResource SquareButtonStyle}" IsEnabled="{Binding Path=EditorEnabled, Mode=OneWay}" Width="26" Height="26"
ToolTip="Add folder" HorizontalAlignment="Left" Margin="10,0,0,0">
<Button.Content>
<Rectangle Fill="{Binding Path=Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}" Width="12" Height="12">
<Rectangle.OpacityMask>
@ -207,8 +189,7 @@
</Rectangle>
</Button.Content>
</Button>
<Button x:Name="EditLayer" VerticalAlignment="Top" Style="{DynamicResource SquareButtonStyle}"
Width="26" Height="26" HorizontalAlignment="Right" Margin="10,0,0,0" ToolTip="Edit layer"
<Button x:Name="EditLayer" VerticalAlignment="Top" Style="{DynamicResource SquareButtonStyle}" Width="26" Height="26" HorizontalAlignment="Right" Margin="10,0,0,0" ToolTip="Edit layer"
IsEnabled="{Binding Path=LayerSelected}">
<Button.Content>
<Rectangle Fill="{Binding Path=Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}" Width="12" Height="12">
@ -218,9 +199,8 @@
</Rectangle>
</Button.Content>
</Button>
<Button x:Name="CloneLayer" VerticalAlignment="Top" Style="{DynamicResource SquareButtonStyle}"
Width="26" Height="26" HorizontalAlignment="Right" Margin="10,0,0,0" ToolTip="Duplicate layer"
IsEnabled="{Binding Path=LayerSelected}">
<Button x:Name="CloneLayer" VerticalAlignment="Top" Style="{DynamicResource SquareButtonStyle}" Width="26" Height="26" HorizontalAlignment="Right" Margin="10,0,0,0"
ToolTip="Duplicate layer" IsEnabled="{Binding Path=LayerSelected}">
<Button.Content>
<Rectangle Fill="{Binding Path=Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}" Width="12" Height="12">
<Rectangle.OpacityMask>
@ -229,9 +209,8 @@
</Rectangle>
</Button.Content>
</Button>
<Button x:Name="RemoveLayer" VerticalAlignment="Top" Style="{DynamicResource SquareButtonStyle}"
Width="26" Height="26" HorizontalAlignment="Right" Margin="10,0,0,0" ToolTip="Delete layer"
IsEnabled="{Binding Path=LayerSelected}">
<Button x:Name="RemoveLayer" VerticalAlignment="Top" Style="{DynamicResource SquareButtonStyle}" Width="26" Height="26" HorizontalAlignment="Right" Margin="10,0,0,0"
ToolTip="Delete layer" IsEnabled="{Binding Path=LayerSelected}">
<Button.Content>
<Rectangle Fill="{Binding Path=Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}" Width="12" Height="12">
<Rectangle.OpacityMask>
@ -241,5 +220,21 @@
</Button.Content>
</Button>
</StackPanel>
<TextBlock VerticalAlignment="Top" Grid.Column="0" Grid.Row="3" Foreground="{DynamicResource HighlightBrush}" Margin="0,5" HorizontalAlignment="Left"
Text="Note: To edit a default profile, duplicate it first." FontWeight="Bold" />
<ItemsControl ItemsSource="{Binding Path=LuaManager.EditorButtons}" Grid.Column="1" Grid.Row="3" Margin="0,5" HorizontalAlignment="Right">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Content="{Binding Text}" cal:Message.Attach="ClickedLuaButton($dataContext)" Style="{DynamicResource SquareButtonStyle}" Height="26" Margin="5,0,0,0" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</UserControl>

View File

@ -22,7 +22,7 @@
<ProjectGuid>{1A349CF5-2008-41E8-AC13-874CBBCDFA0A}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>LightFX2Artemis</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
<WindowsTargetPlatformVersion>10.0.14393.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">

View File

@ -23,6 +23,7 @@
<Keyword>Win32Proj</Keyword>
<RootNamespace>LogiLed2Artemis</RootNamespace>
<ProjectName>LogiLed2Artemis</ProjectName>
<WindowsTargetPlatformVersion>10.0.14393.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">

View File

@ -21,7 +21,7 @@
<PropertyGroup Label="Globals">
<ProjectGuid>{39711909-C1D5-46CE-A9EA-2D561692EA47}</ProjectGuid>
<RootNamespace>Razer2Artemis</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
<WindowsTargetPlatformVersion>10.0.14393.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">