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

Merge pull request #74 from SpoinkyNL/profiles

Old branch into new one
This commit is contained in:
Robert Beekman 2016-03-27 14:46:51 +02:00
commit 4087cf6b0d
47 changed files with 2391 additions and 279 deletions

1
.gitignore vendored
View File

@ -189,3 +189,4 @@ FakesAssemblies/
# Visual Studio 6 workspace options file
*.opt
*.opendb

View File

@ -5,6 +5,8 @@ VisualStudioVersion = 14.0.24720.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Artemis", "Artemis\Artemis.csproj", "{ED9997A2-E54C-4E9F-9350-62BE672C3ABE}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LogiLed2Artemis", "LogiLed2Artemis\LogiLed2Artemis.vcxproj", "{D2EDB8F3-F0CB-4670-B472-0B46D5800D2C}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
CD_ROM|Any CPU = CD_ROM|Any CPU
@ -54,6 +56,34 @@ Global
{ED9997A2-E54C-4E9F-9350-62BE672C3ABE}.SingleImage|x64.Build.0 = Release|x64
{ED9997A2-E54C-4E9F-9350-62BE672C3ABE}.SingleImage|x86.ActiveCfg = Release|x86
{ED9997A2-E54C-4E9F-9350-62BE672C3ABE}.SingleImage|x86.Build.0 = Release|x86
{D2EDB8F3-F0CB-4670-B472-0B46D5800D2C}.CD_ROM|Any CPU.ActiveCfg = Release|x64
{D2EDB8F3-F0CB-4670-B472-0B46D5800D2C}.CD_ROM|Any CPU.Build.0 = Release|x64
{D2EDB8F3-F0CB-4670-B472-0B46D5800D2C}.CD_ROM|x64.ActiveCfg = Release|x64
{D2EDB8F3-F0CB-4670-B472-0B46D5800D2C}.CD_ROM|x64.Build.0 = Release|x64
{D2EDB8F3-F0CB-4670-B472-0B46D5800D2C}.CD_ROM|x86.ActiveCfg = Release|Win32
{D2EDB8F3-F0CB-4670-B472-0B46D5800D2C}.CD_ROM|x86.Build.0 = Release|Win32
{D2EDB8F3-F0CB-4670-B472-0B46D5800D2C}.Debug|Any CPU.ActiveCfg = Debug|Win32
{D2EDB8F3-F0CB-4670-B472-0B46D5800D2C}.Debug|x64.ActiveCfg = Debug|x64
{D2EDB8F3-F0CB-4670-B472-0B46D5800D2C}.Debug|x64.Build.0 = Debug|x64
{D2EDB8F3-F0CB-4670-B472-0B46D5800D2C}.Debug|x86.ActiveCfg = Debug|Win32
{D2EDB8F3-F0CB-4670-B472-0B46D5800D2C}.Debug|x86.Build.0 = Debug|Win32
{D2EDB8F3-F0CB-4670-B472-0B46D5800D2C}.DVD-5|Any CPU.ActiveCfg = Release|x64
{D2EDB8F3-F0CB-4670-B472-0B46D5800D2C}.DVD-5|Any CPU.Build.0 = Release|x64
{D2EDB8F3-F0CB-4670-B472-0B46D5800D2C}.DVD-5|x64.ActiveCfg = Debug|x64
{D2EDB8F3-F0CB-4670-B472-0B46D5800D2C}.DVD-5|x64.Build.0 = Debug|x64
{D2EDB8F3-F0CB-4670-B472-0B46D5800D2C}.DVD-5|x86.ActiveCfg = Debug|Win32
{D2EDB8F3-F0CB-4670-B472-0B46D5800D2C}.DVD-5|x86.Build.0 = Debug|Win32
{D2EDB8F3-F0CB-4670-B472-0B46D5800D2C}.Release|Any CPU.ActiveCfg = Release|Win32
{D2EDB8F3-F0CB-4670-B472-0B46D5800D2C}.Release|x64.ActiveCfg = Release|x64
{D2EDB8F3-F0CB-4670-B472-0B46D5800D2C}.Release|x64.Build.0 = Release|x64
{D2EDB8F3-F0CB-4670-B472-0B46D5800D2C}.Release|x86.ActiveCfg = Release|Win32
{D2EDB8F3-F0CB-4670-B472-0B46D5800D2C}.Release|x86.Build.0 = Release|Win32
{D2EDB8F3-F0CB-4670-B472-0B46D5800D2C}.SingleImage|Any CPU.ActiveCfg = Release|x64
{D2EDB8F3-F0CB-4670-B472-0B46D5800D2C}.SingleImage|Any CPU.Build.0 = Release|x64
{D2EDB8F3-F0CB-4670-B472-0B46D5800D2C}.SingleImage|x64.ActiveCfg = Release|x64
{D2EDB8F3-F0CB-4670-B472-0B46D5800D2C}.SingleImage|x64.Build.0 = Release|x64
{D2EDB8F3-F0CB-4670-B472-0B46D5800D2C}.SingleImage|x86.ActiveCfg = Release|Win32
{D2EDB8F3-F0CB-4670-B472-0B46D5800D2C}.SingleImage|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@ -190,6 +190,10 @@
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Drawing" />
<Reference Include="System.Linq.Dynamic, Version=1.0.5840.25917, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\System.Linq.Dynamic.1.0.6\lib\net40\System.Linq.Dynamic.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.Web" />
<Reference Include="System.Windows.Forms" />
@ -249,6 +253,7 @@
<SubType>Code</SubType>
</Compile>
<Compile Include="ArtemisBootstrapper.cs" />
<Compile Include="DAL\ProfileProvider.cs" />
<Compile Include="Events\ToggleEnabled.cs" />
<Compile Include="Events\ActiveEffectChanged.cs" />
<Compile Include="Events\ChangeBitmap.cs" />
@ -269,6 +274,12 @@
<Compile Include="Models\EffectModel.cs" />
<Compile Include="Models\EffectSettings.cs" />
<Compile Include="Models\GameSettings.cs" />
<Compile Include="Models\Interfaces\GameDataModel.cs" />
<Compile Include="Models\Profiles\LayerConditionModel.cs" />
<Compile Include="Models\Profiles\LayerModel.cs" />
<Compile Include="Models\Profiles\LayerDynamicPropertiesModel.cs" />
<Compile Include="Models\Profiles\LayerPropertiesModel.cs" />
<Compile Include="Models\Profiles\ProfileModel.cs" />
<Compile Include="Modules\Effects\AmbientLightning\AmbientLightningEffectModel.cs" />
<Compile Include="Modules\Effects\AmbientLightning\AmbientLightningEffectSettings.cs" />
<Compile Include="Modules\Effects\AmbientLightning\AmbientLightningEffectView.xaml.cs">
@ -313,6 +324,7 @@
<AutoGen>True</AutoGen>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
<Compile Include="Modules\Games\RocketLeague\RocketLeagueDataModel.cs" />
<Compile Include="Modules\Games\RocketLeague\RocketLeagueModel.cs" />
<Compile Include="Modules\Games\TheDivision\TheDivision.Designer.cs">
<AutoGen>True</AutoGen>
@ -371,6 +383,7 @@
<Compile Include="Utilities\GeneralHelpers.cs" />
<Compile Include="Utilities\ImageUtilities.cs" />
<Compile Include="Utilities\Keyboard\KeyboardHook.cs" />
<Compile Include="Utilities\LayerDrawer.cs" />
<Compile Include="Utilities\LogitechDll\DllManager.cs" />
<Compile Include="Utilities\LogitechDll\NamedPipeServer.cs" />
<Compile Include="Utilities\LogitechDll\PipeServer.cs" />
@ -397,8 +410,11 @@
<Compile Include="Modules\Games\Dota2\Dota2ViewModel.cs" />
<Compile Include="Modules\Games\RocketLeague\RocketLeagueViewModel.cs" />
<Compile Include="Modules\Games\Witcher3\Witcher3ViewModel.cs" />
<Compile Include="ViewModels\LayerEditorViewModel.cs" />
<Compile Include="ViewModels\LayerEditor\LayerConditionViewModel.cs" />
<Compile Include="ViewModels\OverlaysViewModel.cs" />
<Compile Include="Modules\Overlays\VolumeDisplay\VolumeDisplayViewModel.cs" />
<Compile Include="ViewModels\ProfileEditorViewModel.cs" />
<Compile Include="ViewModels\ShellViewModel.cs" />
<Compile Include="ViewModels\SystemTrayViewModel.cs" />
<Compile Include="ViewModels\WelcomeViewModel.cs" />
@ -435,12 +451,21 @@
<Compile Include="Modules\Games\Witcher3\Witcher3View.xaml.cs">
<DependentUpon>Witcher3View.xaml</DependentUpon>
</Compile>
<Compile Include="Views\LayerEditorView.xaml.cs">
<DependentUpon>LayerEditorView.xaml</DependentUpon>
</Compile>
<Compile Include="Views\LayerEditor\LayerConditionView.xaml.cs">
<DependentUpon>LayerConditionView.xaml</DependentUpon>
</Compile>
<Compile Include="Views\OverlaysView.xaml.cs">
<DependentUpon>OverlaysView.xaml</DependentUpon>
</Compile>
<Compile Include="Modules\Overlays\VolumeDisplay\VolumeDisplayView.xaml.cs">
<DependentUpon>VolumeDisplayView.xaml</DependentUpon>
</Compile>
<Compile Include="Views\ProfileEditorView.xaml.cs">
<DependentUpon>ProfileEditorView.xaml</DependentUpon>
</Compile>
<Compile Include="Views\ShellView.xaml.cs">
<DependentUpon>ShellView.xaml</DependentUpon>
</Compile>
@ -504,6 +529,7 @@
<Resource Include="Resources\logo-disabled.ico" />
<Resource Include="Resources\Dota2\dotaGamestateConfiguration.txt" />
<None Include="Resources\LogitechLED.dll" />
<None Include="Resources\folder.png" />
<Content Include="Resources\Witcher3\playerWitcher.txt" />
<Content Include="Resources\Witcher3\artemis.txt" />
<Resource Include="Resources\Entypo.ttf" />
@ -532,6 +558,10 @@
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Styles\Accents\CorsairYellow.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\EffectsView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
@ -576,6 +606,14 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\LayerEditorView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\LayerEditor\LayerConditionView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\OverlaysView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
@ -584,6 +622,10 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\ProfileEditorView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\ShellView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>

View File

@ -2,8 +2,6 @@
using System.Linq;
using System.Windows;
using System.Windows.Forms;
using Artemis.Utilities;
using Artemis.Utilities.LogitechDll;
using Artemis.ViewModels;
using Autofac;
using Caliburn.Micro;

View File

@ -0,0 +1,83 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using Artemis.Models;
using Artemis.Models.Profiles;
using Newtonsoft.Json;
namespace Artemis.DAL
{
public static class ProfileProvider
{
private static readonly string ProfileFolder =
Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + @"\Artemis\profiles";
/// <summary>
/// Get all profiles
/// </summary>
/// <returns>All profiles</returns>
public static List<ProfileModel> GetAll()
{
return ReadProfiles();
}
/// <summary>
/// Get all profiles matching the provided game
/// </summary>
/// <param name="game">The game to match</param>
/// <returns>All profiles matching the provided game</returns>
public static List<ProfileModel> GetAll(GameModel game)
{
return GetAll().Where(g => g.GameName.Equals(game.Name)).ToList();
}
/// <summary>
/// Adds or update the given profile.
/// Updates occur when a profile with the same name and game exist.
/// </summary>
/// <param name="prof">The profile to add or update</param>
public static void AddOrUpdate(ProfileModel prof)
{
if (!(prof.GameName?.Length > 1) || !(prof.KeyboardName?.Length > 1) || !(prof.Name?.Length > 1))
throw new ArgumentException("Profile is invalid. Name, GameName and KeyboardName are required");
var path = ProfileFolder + $@"\{prof.KeyboardName}\{prof.GameName}";
if (!Directory.Exists(path))
Directory.CreateDirectory(path);
var serialized = JsonConvert.SerializeObject(prof, Formatting.Indented);
File.WriteAllText(path + $@"\{prof.Name}.json", serialized);
}
private static List<ProfileModel> ReadProfiles()
{
CheckProfiles();
var profiles = new List<ProfileModel>();
// Create the directory structure
var profileFiles = Directory.GetFiles(ProfileFolder, "*.json", SearchOption.AllDirectories);
// Parse the JSON files into objects and add them if they are valid
foreach (var file in profileFiles)
{
var prof = JsonConvert.DeserializeObject<ProfileModel>(File.ReadAllText(file));
if (prof.GameName?.Length > 1 && prof.KeyboardName?.Length > 1 && prof.Name?.Length > 1)
profiles.Add(prof);
}
return profiles;
}
private static void CheckProfiles()
{
// Create the directory structure
if (Directory.Exists(ProfileFolder))
return;
Directory.CreateDirectory(ProfileFolder);
Debug.WriteLine("Place presets");
}
}
}

View File

@ -11,12 +11,14 @@ namespace Artemis.KeyboardProviders.Logitech
{
internal class Orion : KeyboardProvider
{
private string _versionString;
public Orion()
{
Name = "Logitech G910 RGB";
CantEnableText = "Couldn't connect to your Logitech G910.\n" +
"Please check your cables and updating the Logitech Gaming Software\n" +
"A minimum version of 8.81.15 is required).\n\n" +
"A minimum version of 8.81.15 is required.\n\n" +
"If needed, you can select a different keyboard in Artemis under settings.";
Height = 6;
Width = 21;
@ -40,6 +42,12 @@ namespace Artemis.KeyboardProviders.Logitech
// Turn it into one long number...
var version = int.Parse($"{majorNum}{minorNum}{buildNum}");
CantEnableText = "Couldn't connect to your Logitech G910.\n" +
"Please check your cables and updating the Logitech Gaming Software\n" +
$"A minimum version of 8.81.15 is required (detected {majorNum}.{minorNum}.{buildNum}).\n\n" +
"If the detected version differs from the version LGS is reporting, reinstall LGS or see the FAQ.\n\n" +
"If needed, you can select a different keyboard in Artemis under settings.";
return version >= 88115;
}

View File

@ -13,8 +13,8 @@ namespace Artemis.KeyboardProviders.Razer
public BlackWidow()
{
Name = "Razer BlackWidow Chroma";
CantEnableText = "Couldn't connect to your Razer BlackWidow Chroma.\n " +
"Please check your cables and try updating Razer Synapse.\n\n " +
CantEnableText = "Couldn't connect to your Razer BlackWidow Chroma.\n" +
"Please check your cables and try updating Razer Synapse.\n\n" +
"If needed, you can select a different keyboard in Artemis under settings.";
}

View File

@ -2,7 +2,6 @@
using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Windows.Forms;
using Artemis.Events;
using Artemis.Models;
using Artemis.Services;

View File

@ -0,0 +1,6 @@
namespace Artemis.Models.Interfaces
{
public interface IGameDataModel
{
}
}

View File

@ -0,0 +1,21 @@
using System.Collections.Generic;
using System.Linq.Dynamic;
using Artemis.Models.Interfaces;
namespace Artemis.Models.Profiles
{
public class LayerConditionModel
{
public string Field { get; set; }
public string Value { get; set; }
public string Operator { get; set; }
public bool ConditionMet<T>(IGameDataModel subject)
{
// Put the subject in a list, allowing Dynamic Linq to be used.
var subjectList = new List<T> {(T) subject};
var res = subjectList.Where($"{Field} {Operator} {Value}").Any();
return res;
}
}
}

View File

@ -0,0 +1,86 @@
using System.Collections.Generic;
using System.Drawing;
using System.Linq.Dynamic;
using System.Reflection;
using Artemis.Models.Interfaces;
namespace Artemis.Models.Profiles
{
public class LayerDynamicPropertiesModel
{
public string LayerProperty { get; set; }
public string GameProperty { get; set; }
public string RequiredOperator { get; set; }
public string RequiredValue { get; set; }
public LayerPopertyType LayerPopertyType { get; set; }
/// <summary>
/// Only used when LayerPropertyType is PercentageOf or PercentageOfProperty
/// </summary>
public string PercentageSource { get; set; }
/// <summary>
/// Only used when LayerPropertyType is Color
/// </summary>
public List<Color> LayerColors { get; set; }
internal void ApplyProperty<T>(IGameDataModel dataModel, LayerPropertiesModel userProps,
LayerPropertiesModel props)
{
var dataList = new List<T> {(T) dataModel};
// Attempt to set the property
var layerProp = props.GetType().GetProperty(LayerProperty);
var layerUserProp = userProps.GetType().GetProperty(LayerProperty);
if (LayerPopertyType == LayerPopertyType.PercentageOf)
SetPercentageOf(props, userProps, dataModel, int.Parse(PercentageSource));
if (LayerPopertyType == LayerPopertyType.PercentageOfProperty)
SetPercentageOfProperty(props, userProps, dataModel);
if (LayerPopertyType == LayerPopertyType.Color)
{
if (dataList.Where($"{GameProperty} {RequiredOperator} {RequiredValue}").Any())
SetColor(layerProp, dataModel);
}
}
private void SetPercentageOf(LayerPropertiesModel props, LayerPropertiesModel userProps,
IGameDataModel dataModel, int percentageSource)
{
// Property that will be set
var layerProp = props.GetType().GetProperty(LayerProperty);
// Property to use as a 100%
var userProp = userProps.GetType().GetProperty(LayerProperty);
// Value to use as a source
var source = dataModel.GetType().GetProperty(GameProperty)?.GetValue(dataModel, null);
if (layerProp == null || userProp == null || source == null)
return;
var percentage = double.Parse(source.ToString())/percentageSource;
layerProp.SetValue(props, (int) (percentage*(int) userProp.GetValue(userProps, null)));
}
private void SetPercentageOfProperty(LayerPropertiesModel props, LayerPropertiesModel userProps,
IGameDataModel dataModel)
{
var value = dataModel.GetType().GetProperty(PercentageSource)?.GetValue(dataModel, null);
if (value != null)
SetPercentageOf(props, userProps, dataModel, (int) value);
}
private void SetColor(PropertyInfo layerProp, IGameDataModel dataModel)
{
if (layerProp == null)
return;
if (layerProp.PropertyType == typeof (List<Color>))
layerProp.SetValue(dataModel, LayerColors, null);
}
}
public enum LayerPopertyType
{
PercentageOf,
PercentageOfProperty,
Color
}
}

View File

@ -0,0 +1,91 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Windows.Media;
using Artemis.Models.Interfaces;
using Artemis.Utilities;
using Newtonsoft.Json;
namespace Artemis.Models.Profiles
{
public class LayerModel
{
[JsonIgnore] private readonly LayerDrawer _drawer;
public LayerModel(string name, LayerType layerType)
{
Name = name;
LayerType = layerType;
LayerUserProperties = new LayerPropertiesModel();
LayerCalculatedProperties = new LayerPropertiesModel();
Children = new List<LayerModel>();
LayerConditions = new List<LayerConditionModel>();
LayerProperties = new List<LayerDynamicPropertiesModel>();
_drawer = new LayerDrawer(this);
}
public string Name { get; set; }
public LayerType LayerType { get; set; }
public LayerPropertiesModel LayerUserProperties { get; set; }
public List<LayerModel> Children { get; set; }
public List<LayerConditionModel> LayerConditions { get; set; }
public List<LayerDynamicPropertiesModel> LayerProperties { get; set; }
[JsonIgnore]
public LayerPropertiesModel LayerCalculatedProperties { get; }
[JsonIgnore]
public ImageSource LayerImage => _drawer.GetPreviewImage();
public bool ConditionsMet<T>(IGameDataModel dataModel)
{
return LayerConditions.All(cm => cm.ConditionMet<T>(dataModel));
}
public void Draw<T>(IGameDataModel dataModel, Graphics g)
{
if (!ConditionsMet<T>(dataModel))
return;
Update<T>(dataModel);
switch (LayerType)
{
case LayerType.Folder:
DrawChildren<T>(dataModel, g);
break;
case LayerType.Rectangle:
_drawer.DrawRectangle(g);
break;
case LayerType.Ellipse:
_drawer.DrawEllipse(g);
break;
default:
throw new ArgumentOutOfRangeException();
}
}
private void Update<T>(IGameDataModel dataModel)
{
GeneralHelpers.CopyProperties(LayerCalculatedProperties, LayerUserProperties);
foreach (var dynamicProperty in LayerProperties)
dynamicProperty.ApplyProperty<T>(dataModel, LayerUserProperties, LayerCalculatedProperties);
}
private void DrawChildren<T>(IGameDataModel dataModel, Graphics g)
{
foreach (var layerModel in Children)
layerModel.Draw<T>(dataModel, g);
}
}
public enum LayerType
{
Folder,
Rectangle,
Ellipse
}
}

View File

@ -0,0 +1,25 @@
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
namespace Artemis.Models.Profiles
{
public class LayerPropertiesModel
{
public int X { get; set; }
public int Y { get; set; }
public int Width { get; set; }
public int Height { get; set; }
public int Opacity { get; set; }
public bool ContainedBrush { get; set; }
public LinearGradientMode GradientMode { get; set; }
public bool Rotate { get; set; }
public double RotateSpeed { get; set; }
public List<Color> Colors { get; set; }
public LayerPropertiesModel()
{
Colors = new List<Color>();
}
}
}

View File

@ -0,0 +1,44 @@
using System.Collections.Generic;
namespace Artemis.Models.Profiles
{
public class ProfileModel
{
public ProfileModel(string name, string keyboardName, string gameName)
{
Name = name;
KeyboardName = keyboardName;
GameName = gameName;
}
public string Name { get; set; }
public string KeyboardName { get; set; }
public string GameName { get; set; }
public List<LayerModel> Layers { get; set; }
protected bool Equals(ProfileModel other)
{
return string.Equals(Name, other.Name) && string.Equals(KeyboardName, other.KeyboardName) && string.Equals(GameName, other.GameName);
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != GetType()) return false;
return Equals((ProfileModel) obj);
}
public override int GetHashCode()
{
unchecked
{
var hashCode = Name?.GetHashCode() ?? 0;
hashCode = (hashCode*397) ^ (KeyboardName?.GetHashCode() ?? 0);
hashCode = (hashCode*397) ^ (GameName?.GetHashCode() ?? 0);
return hashCode;
}
}
}
}

View File

@ -0,0 +1,12 @@
using System.Collections.Generic;
using Artemis.Models.Interfaces;
using Artemis.Utilities;
namespace Artemis.Modules.Games.RocketLeague
{
internal class RocketLeagueDataModel : IGameDataModel
{
public int Boost { get; set; }
public List<GeneralHelpers.PropertyCollection> Properties { get; }
}
}

View File

@ -1,29 +1,31 @@
using System.Collections.Generic;
using System;
using Artemis.Models.Interfaces;
namespace Artemis.Modules.Games.TheDivision
{
public class TheDivisionDataModel
public class TheDivisionDataModel : IGameDataModel
{
public List<DivisionPlayer> DivisionPlayers { get; set; }
public GrenadeState GrenadeState { get; set; }
public bool LowAmmo { get; set; }
public bool LowHp { get; set; }
public TheDivisionDataModel()
{
DivisionPlayers = new List<DivisionPlayer>();
TestyTest = new TestTest();
}
public PlayerState PartyMember1 { get; set; }
public PlayerState PartyMember2 { get; set; }
public PlayerState PartyMember3 { get; set; }
public bool LowAmmo { get; set; }
public bool LowHp { get; set; }
public GrenadeState GrenadeState { get; set; }
public TestTest TestyTest { get; set; }
}
public class DivisionPlayer
public class TestTest
{
public int Id { get; set; }
public PlayerState PlayerState { get; set; }
public DivisionPlayer(int id)
{
Id = id;
}
public string TestS { get; set; }
public int TestI { get; set; }
}
public enum GrenadeState

View File

@ -1,14 +1,12 @@
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using Artemis.Managers;
using Artemis.Models;
using Artemis.Modules.Effects.TypeWave;
using Artemis.Utilities;
using Artemis.Utilities.Keyboard;
using Artemis.Utilities.LogitechDll;
using CUE.NET;
namespace Artemis.Modules.Games.TheDivision
{
@ -95,8 +93,6 @@ namespace Artemis.Modules.Games.TheDivision
DllManager.PlaceDll();
_dataModel = new TheDivisionDataModel();
for (var i = 1; i < 5; i++)
_dataModel.DivisionPlayers.Add(new DivisionPlayer(i));
MainManager.PipeServer.PipeMessage += PipeServerOnPipeMessage;
Initialized = true;
@ -118,7 +114,7 @@ namespace Artemis.Modules.Games.TheDivision
}
// Parses Division key data to game data
private void InterpertrateDivisionKey(int[] parts)
private void InterpertrateDivisionKey(IReadOnlyList<int> parts)
{
var keyCode = parts[1];
var rPer = parts[2];
@ -129,16 +125,21 @@ namespace Artemis.Modules.Games.TheDivision
if (keyCode >= 59 && keyCode <= 62)
{
var playerId = keyCode - 58;
var playerDataModel = _dataModel.DivisionPlayers.FirstOrDefault(p => p.Id == playerId);
if (playerDataModel == null)
return;
PlayerState newState;
if (gPer > 10)
playerDataModel.PlayerState = PlayerState.Online;
newState = PlayerState.Online;
else if (rPer > 10)
playerDataModel.PlayerState = PlayerState.Hit;
newState = PlayerState.Hit;
else
playerDataModel.PlayerState = PlayerState.Offline;
newState = PlayerState.Offline;
if (playerId == 1)
_dataModel.PartyMember1 = newState;
else if (playerId == 2)
_dataModel.PartyMember2 = newState;
else if (playerId == 3)
_dataModel.PartyMember3 = newState;
}
// R blinks white when low on ammo
else if (keyCode == 19)
@ -180,40 +181,28 @@ namespace Artemis.Modules.Games.TheDivision
_hpRect.Colors = _dataModel.LowHp
? new List<Color> {Color.Red, Color.Orange}
: new List<Color> {Color.FromArgb(10, 255, 0), Color.FromArgb(80, 255, 45) };
: new List<Color> {Color.FromArgb(10, 255, 0), Color.FromArgb(80, 255, 45)};
if (_dataModel.DivisionPlayers[1].PlayerState == PlayerState.Offline)
if (_dataModel.PartyMember1 == PlayerState.Offline)
_p2.Colors = new List<Color> {Color.Gray, Color.White};
else if (_dataModel.DivisionPlayers[1].PlayerState == PlayerState.Online)
_p2.Colors = new List<Color> { Color.FromArgb(10, 255, 0), Color.FromArgb(80, 255, 45) };
else if (_dataModel.PartyMember1 == PlayerState.Online)
_p2.Colors = new List<Color> {Color.FromArgb(10, 255, 0), Color.FromArgb(80, 255, 45)};
else
_p2.Colors = new List<Color> {Color.Red, Color.Orange};
if (_dataModel.DivisionPlayers[2].PlayerState == PlayerState.Offline)
if (_dataModel.PartyMember2 == PlayerState.Offline)
_p3.Colors = new List<Color> {Color.Gray, Color.White};
else if (_dataModel.DivisionPlayers[2].PlayerState == PlayerState.Online)
_p3.Colors = new List<Color> { Color.FromArgb(10, 255, 0), Color.FromArgb(80, 255, 45) };
else if (_dataModel.PartyMember2 == PlayerState.Online)
_p3.Colors = new List<Color> {Color.FromArgb(10, 255, 0), Color.FromArgb(80, 255, 45)};
else
_p3.Colors = new List<Color> {Color.Red, Color.Orange};
if (_dataModel.DivisionPlayers[3].PlayerState == PlayerState.Offline)
if (_dataModel.PartyMember3 == PlayerState.Offline)
_p4.Colors = new List<Color> {Color.Gray, Color.White};
else if (_dataModel.DivisionPlayers[3].PlayerState == PlayerState.Online)
_p4.Colors = new List<Color> { Color.FromArgb(10, 255, 0), Color.FromArgb(80, 255, 45) };
else if (_dataModel.PartyMember3 == PlayerState.Online)
_p4.Colors = new List<Color> {Color.FromArgb(10, 255, 0), Color.FromArgb(80, 255, 45)};
else
_p4.Colors = new List<Color> {Color.Red, Color.Orange};
if (!_dataModel.LowAmmo)
{
foreach (var corsairLed in CueSDK.MouseSDK.Leds)
corsairLed.Color = Color.Green;
}
else
{
foreach (var corsairLed in CueSDK.MouseSDK.Leds)
corsairLed.Color = Color.Red;
}
CueSDK.MouseSDK.Update();
}
public override Bitmap GenerateBitmap()

View File

@ -7,48 +7,52 @@
xmlns:cal="http://www.caliburnproject.org"
mc:Ignorable="d"
d:DesignHeight="416.495" d:DesignWidth="553.608">
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto">
<Grid Margin="15, 5, 15, 5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2">
<Label FontSize="20" HorizontalAlignment="Left">
<Label.Content>
<AccessText TextWrapping="Wrap"
Text="Shows lots of things, I should change this." />
</Label.Content>
</Label>
<StackPanel Orientation="Horizontal" 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"
IsChecked="{Binding Path=GameSettings.Enabled, Mode=TwoWay}"
Style="{DynamicResource MetroCircleToggleButtonStyle}"
cal:Message.Attach="[Event Click] = [Action ToggleEffect]" />
</StackPanel>
</StackPanel>
<TextBlock Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2" VerticalAlignment="Center" Margin="0,8"
TextWrapping="Wrap" HorizontalAlignment="Left" FontFamily="Segoe UI Semibold"
Foreground="{DynamicResource HighlightBrush}" MaxWidth="510" TextAlignment="Justify">
Note: For this game to work with Artemis, please open up your Division settings, navigate to 3rd Party and set LED keyboard support to Yes. (This only works if you have Artemis running before starting the game)
</TextBlock>
<!-- Buttons -->
<StackPanel Grid.Column="0" Grid.Row="4" 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>
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto">
<Grid Margin="15, 5, 15, 5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2">
<Label FontSize="20" HorizontalAlignment="Left">
<Label.Content>
<AccessText TextWrapping="Wrap"
Text="Shows lots of things, I should change this." />
</Label.Content>
</Label>
<StackPanel Orientation="Horizontal" 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"
IsChecked="{Binding Path=GameSettings.Enabled, Mode=TwoWay}"
Style="{DynamicResource MetroCircleToggleButtonStyle}"
cal:Message.Attach="[Event Click] = [Action ToggleEffect]" />
</StackPanel>
</StackPanel>
<TextBlock Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2" VerticalAlignment="Center" Margin="0,8"
TextWrapping="Wrap" HorizontalAlignment="Left" FontFamily="Segoe UI Semibold"
Foreground="{DynamicResource HighlightBrush}" MaxWidth="510" TextAlignment="Justify">
Note: For this game to work with Artemis, please open up your Division settings, navigate to 3rd Party and set LED keyboard support to Yes. (This only works if you have Artemis running before starting the game)
</TextBlock>
<!-- Profile editor -->
<ContentControl Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="2" x:Name="ProfileEditor" />
<!-- Buttons -->
<StackPanel Grid.Column="0" Grid.Row="4" 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>
</ScrollViewer>
</UserControl>

View File

@ -1,4 +1,5 @@
using Artemis.Managers;
using Artemis.ViewModels;
using Artemis.ViewModels.Abstract;
namespace Artemis.Modules.Games.TheDivision
@ -15,8 +16,12 @@ namespace Artemis.Modules.Games.TheDivision
// Create effect model and add it to MainManager
GameModel = new TheDivisionModel(mainManager, (TheDivisionSettings) GameSettings);
MainManager.EffectManager.EffectModels.Add(GameModel);
ProfileEditor = new ProfileEditorViewModel<TheDivisionDataModel>(MainManager, GameModel);
}
public ProfileEditorViewModel<TheDivisionDataModel> ProfileEditor { get; set; }
public static string Name => "The Division";
}
}

View File

@ -61,14 +61,14 @@ namespace Artemis.Properties {
}
/// <summary>
/// Looks up a localized string similar to &lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-16&quot;?&gt;
///&lt;!-- Used by Artemis to get the active Sign --&gt;
///&lt;UserConfig&gt;
/// &lt;Group id=&quot;Artemis&quot; displayName=&quot;Artemis&quot;&gt;
/// &lt;VisibleVars&gt;
/// &lt;Var id=&quot;ActiveSign&quot; displayName=&quot;ActiveSign&quot; displayType=&quot;SLIDER:0:1:1000000&quot;/&gt;
/// &lt;/VisibleVars&gt;
/// &lt;/Group&gt;
/// Looks up a localized string similar to &lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-16&quot;?&gt;
///&lt;!-- Used by Artemis to get the active Sign --&gt;
///&lt;UserConfig&gt;
/// &lt;Group id=&quot;Artemis&quot; displayName=&quot;Artemis&quot;&gt;
/// &lt;VisibleVars&gt;
/// &lt;Var id=&quot;ActiveSign&quot; displayName=&quot;ActiveSign&quot; displayType=&quot;SLIDER:0:1:1000000&quot;/&gt;
/// &lt;/VisibleVars&gt;
/// &lt;/Group&gt;
///&lt;/UserConfig&gt;.
/// </summary>
internal static string artemisXml {
@ -88,23 +88,23 @@ namespace Artemis.Properties {
}
/// <summary>
/// Looks up a localized string similar to &quot;Artemis&quot;
///{
/// &quot;uri&quot; &quot;http://localhost:{{port}}/csgo_game_event&quot;
/// &quot;timeout&quot; &quot;5.0&quot;
/// &quot;buffer&quot; &quot;0.1&quot;
/// &quot;throttle&quot; &quot;0.1&quot;
/// &quot;heartbeat&quot; &quot;30.0&quot;
/// &quot;data&quot;
/// {
/// &quot;provider&quot; &quot;1&quot;
/// &quot;map&quot; &quot;1&quot;
/// &quot;round&quot; &quot;1&quot;
/// &quot;player_id&quot; &quot;1&quot;
/// &quot;player_state&quot; &quot;1&quot;
/// &quot;player_weapons&quot; &quot;1&quot;
/// &quot;player_match_stats&quot; &quot;1&quot;
/// }
/// Looks up a localized string similar to &quot;Artemis&quot;
///{
/// &quot;uri&quot; &quot;http://localhost:{{port}}/csgo_game_event&quot;
/// &quot;timeout&quot; &quot;5.0&quot;
/// &quot;buffer&quot; &quot;0.1&quot;
/// &quot;throttle&quot; &quot;0.1&quot;
/// &quot;heartbeat&quot; &quot;30.0&quot;
/// &quot;data&quot;
/// {
/// &quot;provider&quot; &quot;1&quot;
/// &quot;map&quot; &quot;1&quot;
/// &quot;round&quot; &quot;1&quot;
/// &quot;player_id&quot; &quot;1&quot;
/// &quot;player_state&quot; &quot;1&quot;
/// &quot;player_weapons&quot; &quot;1&quot;
/// &quot;player_match_stats&quot; &quot;1&quot;
/// }
///}.
/// </summary>
internal static string csgoGamestateConfiguration {
@ -116,7 +116,7 @@ namespace Artemis.Properties {
/// <summary>
/// Looks up a localized string similar to &quot;Artemis&quot;
///{
/// &quot;uri&quot; &quot;http://localhost:4000/&quot;
/// &quot;uri&quot; &quot;http://localhost:{{port}}/&quot;
/// &quot;timeout&quot; &quot;5.0&quot;
/// &quot;buffer&quot; &quot;0.1&quot;
/// &quot;throttle&quot; &quot;0.1&quot;
@ -138,6 +138,16 @@ namespace Artemis.Properties {
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap folder {
get {
object obj = ResourceManager.GetObject("folder", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Byte[].
/// </summary>

View File

@ -142,4 +142,7 @@
<data name="playerWitcherWs" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\resources\witcher3\playerwitcher.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-16</value>
</data>
<data name="folder" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\folder.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
</root>

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View File

@ -1,24 +1,24 @@
//The MIT License(MIT)
//Copyright(c) 2015 ihtfw
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:
//The above copyright notice and this permission notice shall be included in all
//copies or substantial portions of the Software.
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
//SOFTWARE.
// The MIT License(MIT)
// Copyright(c) 2015 ihtfw
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
using System.Linq;
using System.Threading.Tasks;

View File

@ -0,0 +1,53 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:options="http://schemas.microsoft.com/winfx/2006/xaml/presentation/options"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="options">
<Color x:Key="HighlightColor">#C0A200</Color>
<Color x:Key="AccentBaseColor">#FFF0CF1E</Color>
<!--80%-->
<Color x:Key="AccentColor">#FFF0CF1E</Color>
<!--60%-->
<Color x:Key="AccentColor2">#FFF0CF1E</Color>
<!--40%-->
<Color x:Key="AccentColor3">#FFF0CF1E</Color>
<!--20%-->
<Color x:Key="AccentColor4">#FFF0CF1E</Color>
<!-- re-set brushes too -->
<SolidColorBrush x:Key="HighlightBrush" Color="{StaticResource HighlightColor}" options:Freeze="True" />
<SolidColorBrush x:Key="AccentBaseColorBrush" Color="{StaticResource AccentBaseColor}" options:Freeze="True" />
<SolidColorBrush x:Key="AccentColorBrush" Color="{StaticResource AccentColor}" options:Freeze="True" />
<SolidColorBrush x:Key="AccentColorBrush2" Color="{StaticResource AccentColor2}" options:Freeze="True" />
<SolidColorBrush x:Key="AccentColorBrush3" Color="{StaticResource AccentColor3}" options:Freeze="True" />
<SolidColorBrush x:Key="AccentColorBrush4" Color="{StaticResource AccentColor4}" options:Freeze="True" />
<SolidColorBrush x:Key="WindowTitleColorBrush" Color="{StaticResource AccentColor}" options:Freeze="True" />
<LinearGradientBrush x:Key="ProgressBrush" EndPoint="0.001,0.5" StartPoint="1.002,0.5" options:Freeze="True">
<GradientStop Color="{StaticResource HighlightColor}" Offset="0" />
<GradientStop Color="{StaticResource AccentColor3}" Offset="1" />
</LinearGradientBrush>
<SolidColorBrush x:Key="CheckmarkFill" Color="{StaticResource AccentColor}" options:Freeze="True" />
<SolidColorBrush x:Key="RightArrowFill" Color="{StaticResource AccentColor}" options:Freeze="True" />
<Color x:Key="IdealForegroundColor">White</Color>
<SolidColorBrush x:Key="IdealForegroundColorBrush" Color="{StaticResource IdealForegroundColor}" options:Freeze="True" />
<SolidColorBrush x:Key="IdealForegroundDisabledBrush" Color="{StaticResource IdealForegroundColor}" Opacity="0.4" options:Freeze="True" />
<SolidColorBrush x:Key="AccentSelectedColorBrush" Color="{StaticResource IdealForegroundColor}" options:Freeze="True" />
<!-- DataGrid brushes -->
<SolidColorBrush x:Key="MetroDataGrid.HighlightBrush" Color="{StaticResource AccentColor}" options:Freeze="True" />
<SolidColorBrush x:Key="MetroDataGrid.HighlightTextBrush" Color="{StaticResource IdealForegroundColor}" options:Freeze="True" />
<SolidColorBrush x:Key="MetroDataGrid.MouseOverHighlightBrush" Color="{StaticResource AccentColor3}" options:Freeze="True" />
<SolidColorBrush x:Key="MetroDataGrid.FocusBorderBrush" Color="{StaticResource AccentColor}" options:Freeze="True" />
<SolidColorBrush x:Key="MetroDataGrid.InactiveSelectionHighlightBrush" Color="{StaticResource AccentColor2}" options:Freeze="True" />
<SolidColorBrush x:Key="MetroDataGrid.InactiveSelectionHighlightTextBrush" Color="{StaticResource IdealForegroundColor}" options:Freeze="True" />
<SolidColorBrush x:Key="MahApps.Metro.Brushes.ToggleSwitchButton.OnSwitchBrush.Win10" Color="{StaticResource AccentColor}" options:Freeze="True" />
<SolidColorBrush x:Key="MahApps.Metro.Brushes.ToggleSwitchButton.OnSwitchMouseOverBrush.Win10" Color="{StaticResource AccentColor2}" options:Freeze="True" />
<SolidColorBrush x:Key="MahApps.Metro.Brushes.ToggleSwitchButton.ThumbIndicatorCheckedBrush.Win10" Color="{StaticResource IdealForegroundColor}" options:Freeze="True" />
</ResourceDictionary>

View File

@ -1,12 +1,14 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Security.Principal;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using static System.String;
namespace Artemis.Utilities
{
@ -37,12 +39,74 @@ namespace Artemis.Utilities
Environment.Exit(0);
}
public static bool IsRunAsAdministrator()
{
var wi = WindowsIdentity.GetCurrent();
var wp = new WindowsPrincipal(wi);
return wp.IsInRole(WindowsBuiltInRole.Administrator);
public static bool IsRunAsAdministrator()
{
var wi = WindowsIdentity.GetCurrent();
var wp = new WindowsPrincipal(wi);
return wp.IsInRole(WindowsBuiltInRole.Administrator);
}
public static void CopyProperties(object dest, object src)
{
foreach (PropertyDescriptor item in TypeDescriptor.GetProperties(src))
{
item.SetValue(dest, item.GetValue(src));
}
}
public static List<PropertyCollection> GenerateTypeMap(object o) => GenerateTypeMap(o.GetType().GetProperties());
public static List<PropertyCollection> GenerateTypeMap<T>() => GenerateTypeMap(typeof (T).GetProperties());
private static List<PropertyCollection> GenerateTypeMap(IEnumerable<PropertyInfo> getProperties,
string path = "")
{
var list = new List<PropertyCollection>();
foreach (var propertyInfo in getProperties)
{
var friendlyName = Empty;
if (propertyInfo.PropertyType.Name == "Int32")
friendlyName = "(Number) ";
else if (propertyInfo.PropertyType.Name == "String")
friendlyName = "(Text) ";
if (propertyInfo.PropertyType.BaseType?.Name == "Enum")
friendlyName = "(Choice) ";
var parent = new PropertyCollection
{
Type = propertyInfo.PropertyType.Name,
DisplayType = friendlyName,
Display = $"{path.Replace(".", " ")}{propertyInfo.Name}",
Path = $"{path}{propertyInfo.Name}"
};
if (propertyInfo.PropertyType.BaseType?.Name == "Enum")
{
parent.EnumValues = Enum.GetNames(propertyInfo.PropertyType);
parent.Type = "Enum";
}
if (friendlyName != Empty)
list.Add(parent);
list.AddRange(GenerateTypeMap(propertyInfo.PropertyType.GetProperties(), path + $"{propertyInfo.Name}."));
}
return list;
}
public struct PropertyCollection
{
public string Display { get; set; }
public string Path { get; set; }
public string Type { get; set; }
/// <summary>
/// Only used if Type is an enumerable
/// </summary>
public string[] EnumValues { get; set; }
public List<PropertyCollection> Children { get; set; }
public string DisplayType { get; set; }
}
}
}
}

View File

@ -0,0 +1,173 @@
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Windows.Media.Imaging;
using Artemis.Models.Profiles;
using Artemis.Properties;
namespace Artemis.Utilities
{
internal class LayerDrawer
{
private readonly LayerModel _layerModel;
private Rectangle _rectangle;
private double _rotationProgress;
private Rectangle _userRectangle;
public LayerDrawer(LayerModel layerModel)
{
_layerModel = layerModel;
_rotationProgress = 0;
}
public void Draw(Graphics graphics)
{
_rectangle = new Rectangle(
_layerModel.LayerCalculatedProperties.X,
_layerModel.LayerCalculatedProperties.Y,
_layerModel.LayerCalculatedProperties.Width,
_layerModel.LayerCalculatedProperties.Height);
_userRectangle = new Rectangle(
_layerModel.LayerUserProperties.X,
_layerModel.LayerUserProperties.Y,
_layerModel.LayerUserProperties.Width,
_layerModel.LayerUserProperties.Height);
if (_layerModel.LayerType == LayerType.Ellipse)
DrawEllipse(graphics);
else if (_layerModel.LayerType == LayerType.Ellipse)
DrawRectangle(graphics);
// Update the rotation progress
_rotationProgress = _rotationProgress + _layerModel.LayerCalculatedProperties.RotateSpeed;
if (_layerModel.LayerCalculatedProperties.ContainedBrush && _rotationProgress > _rectangle.Width)
_rotationProgress = _layerModel.LayerCalculatedProperties.RotateSpeed;
else if (!_layerModel.LayerCalculatedProperties.ContainedBrush && _rotationProgress > _userRectangle.Width)
_rotationProgress = _layerModel.LayerCalculatedProperties.RotateSpeed;
}
public BitmapImage GetPreviewImage()
{
_rectangle = new Rectangle(0, 0, 18, 18);
_userRectangle = new Rectangle(0, 0, 18, 18);
_layerModel.LayerCalculatedProperties.Opacity = 255;
var brush = CreateGradientBrush(_layerModel.LayerUserProperties.Colors);
var bitmap = new Bitmap(18, 18);
using (var g = Graphics.FromImage(bitmap))
{
g.SmoothingMode = SmoothingMode.AntiAlias;
if (_layerModel.LayerType == LayerType.Ellipse)
{
g.FillEllipse(brush, _rectangle);
g.DrawEllipse(new Pen(Color.Black, 1), 0, 0, 17, 17);
}
else if (_layerModel.LayerType == LayerType.Rectangle)
{
g.FillRectangle(brush, _rectangle);
g.DrawRectangle(new Pen(Color.Black, 1), 0, 0, 17, 17);
}
else
bitmap = Resources.folder;
}
using (var memory = new MemoryStream())
{
bitmap.Save(memory, ImageFormat.Png);
memory.Position = 0;
var bitmapImage = new BitmapImage();
bitmapImage.BeginInit();
bitmapImage.StreamSource = memory;
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
bitmapImage.EndInit();
return bitmapImage;
}
}
public void DrawRectangle(Graphics graphics)
{
}
public void DrawEllipse(Graphics graphics)
{
}
private LinearGradientBrush CreateGradientBrush(List<Color> colors)
{
ColorBlend colorBlend;
var props = _layerModel.LayerCalculatedProperties;
// Create a ColorBlend
if (colors.Count == 0)
{
colorBlend = new ColorBlend
{
Colors = new[] {Color.Transparent, Color.Transparent},
Positions = new[] {0F, 1F}
};
}
else if (colors.Count == 1)
{
colorBlend = new ColorBlend
{
Colors = new[] {colors[0], colors[0]},
Positions = new[] {0F, 1F}
};
}
else
{
colorBlend = props.Rotate
? new ColorBlend {Colors = CreateTilebleColors(colors).ToArray()}
: new ColorBlend {Colors = colors.ToArray()};
}
// If needed, apply opacity to the colors in the blend
if (props.Opacity < 255)
for (var i = 0; i < colorBlend.Colors.Length; i++)
colorBlend.Colors[i] = Color.FromArgb(props.Opacity, colorBlend.Colors[i]);
// Devide the colors over the colorblend
var devider = (float) colorBlend.Colors.Length - 1;
var positions = new List<float>();
for (var i = 0; i < colorBlend.Colors.Length; i++)
positions.Add(i/devider);
// Apply the devided positions
colorBlend.Positions = positions.ToArray();
RectangleF rect;
if (props.Rotate)
rect = _layerModel.LayerCalculatedProperties.ContainedBrush
? new Rectangle((int) _rotationProgress + _rectangle.X, _rectangle.Y, _rectangle.Width*2,
_rectangle.Height*2)
: new Rectangle((int) _rotationProgress + _userRectangle.X, _userRectangle.Y, _userRectangle.Width*2,
_userRectangle.Height*2);
else
rect = _layerModel.LayerCalculatedProperties.ContainedBrush
? new Rectangle(_rectangle.X, _rectangle.Y, _rectangle.Width, _rectangle.Height)
: new Rectangle(_userRectangle.X, _userRectangle.Y, _userRectangle.Width, _userRectangle.Height);
return new LinearGradientBrush(rect, Color.Transparent, Color.Transparent,
_layerModel.LayerCalculatedProperties.GradientMode)
{
InterpolationColors = colorBlend
};
}
private List<Color> CreateTilebleColors(List<Color> sourceColors)
{
// Create a list using the original colors
var tilebleColors = new List<Color>(sourceColors);
// Add the original colors again
tilebleColors.AddRange(sourceColors);
// Add the first color, smoothing the transition
tilebleColors.Add(sourceColors.FirstOrDefault());
return tilebleColors;
}
}
}

View File

@ -0,0 +1,100 @@
using System.Linq;
using Artemis.Models.Profiles;
using Artemis.Utilities;
using Caliburn.Micro;
namespace Artemis.ViewModels.LayerEditor
{
public class LayerConditionViewModel<T> : Screen
{
private readonly LayerEditorViewModel<T> _conditionModel;
private GeneralHelpers.PropertyCollection _selectedDataModelProp;
private string _selectedOperator;
private bool _userValueIsVisible;
public LayerConditionViewModel(LayerEditorViewModel<T> conditionModel, LayerConditionModel layerConditionModel,
BindableCollection<GeneralHelpers.PropertyCollection> dataModelProps)
{
_conditionModel = conditionModel;
LayerConditionModel = layerConditionModel;
DataModelProps = dataModelProps;
Operators = new BindableCollection<string>();
}
public LayerConditionModel LayerConditionModel { get; set; }
public BindableCollection<GeneralHelpers.PropertyCollection> DataModelProps { get; set; }
public BindableCollection<string> Operators { get; set; }
public GeneralHelpers.PropertyCollection SelectedDataModelProp
{
get { return _selectedDataModelProp; }
set
{
if (value.Equals(_selectedDataModelProp)) return;
_selectedDataModelProp = value;
OnSelectedItemChangedAction(_selectedDataModelProp);
NotifyOfPropertyChange(() => SelectedDataModelProp);
}
}
public string SelectedOperator
{
get { return _selectedOperator; }
set
{
if (value == _selectedOperator) return;
_selectedOperator = value;
NotifyOfPropertyChange(() => SelectedOperator);
}
}
public bool UserValueIsVisible
{
get { return _userValueIsVisible; }
set
{
if (value == _userValueIsVisible) return;
_userValueIsVisible = value;
NotifyOfPropertyChange(() => UserValueIsVisible);
}
}
public void OnSelectedItemChangedAction(GeneralHelpers.PropertyCollection prop)
{
Operators.Clear();
if (prop.EnumValues != null)
{
Operators.AddRange(prop.EnumValues);
UserValueIsVisible = false;
}
else
switch (prop.Type)
{
case "Int32":
Operators.AddRange(new[]
{
"Lower than", "Lower or equal to", "Higher than", "Higher or equal to", "Equal to",
"Not equal to"
});
UserValueIsVisible = true;
break;
case "Boolean":
Operators.AddRange(new[] {"False", "True"});
UserValueIsVisible = false;
break;
default:
Operators.AddRange(new[] {"Equal to", "Not equal to"});
UserValueIsVisible = true;
break;
}
SelectedOperator = Operators.First();
}
public void Delete()
{
_conditionModel.DeleteCondition(this, LayerConditionModel);
}
}
}

View File

@ -0,0 +1,62 @@
using System.Linq;
using Artemis.Models.Profiles;
using Artemis.Utilities;
using Artemis.ViewModels.LayerEditor;
using Caliburn.Micro;
namespace Artemis.ViewModels
{
public class LayerEditorViewModel<T> : Screen
{
private LayerModel _layer;
public LayerEditorViewModel(LayerModel layer)
{
Layer = layer;
DataModelProps = new BindableCollection<GeneralHelpers.PropertyCollection>();
DataModelProps.AddRange(GeneralHelpers.GenerateTypeMap<T>());
LayerConditionVms =
new BindableCollection<LayerConditionViewModel<T>>(
layer.LayerConditions.Select(c => new LayerConditionViewModel<T>(this, c, DataModelProps)));
ProposedProperties = new LayerPropertiesModel();
GeneralHelpers.CopyProperties(ProposedProperties, Layer.LayerUserProperties);
}
public BindableCollection<LayerConditionViewModel<T>> LayerConditionVms { get; set; }
public LayerModel Layer
{
get { return _layer; }
set
{
if (Equals(value, _layer)) return;
_layer = value;
NotifyOfPropertyChange(() => Layer);
}
}
public BindableCollection<GeneralHelpers.PropertyCollection> DataModelProps { get; set; }
public LayerPropertiesModel ProposedProperties { get; set; }
public void AddCondition()
{
var condition = new LayerConditionModel();
Layer.LayerConditions.Add(condition);
LayerConditionVms.Add(new LayerConditionViewModel<T>(this, condition, DataModelProps));
}
public void Apply()
{
GeneralHelpers.CopyProperties(Layer.LayerUserProperties, ProposedProperties);
}
public void DeleteCondition(LayerConditionViewModel<T> layerConditionViewModel, LayerConditionModel layerConditionModel)
{
LayerConditionVms.Remove(layerConditionViewModel);
Layer.LayerConditions.Remove(layerConditionModel);
}
}
}

View File

@ -0,0 +1,102 @@
using System.Dynamic;
using System.Linq;
using System.Windows.Media;
using Artemis.DAL;
using Artemis.Managers;
using Artemis.Models;
using Artemis.Models.Profiles;
using Caliburn.Micro;
namespace Artemis.ViewModels
{
public class ProfileEditorViewModel<T> : Screen
{
private readonly GameModel _gameModel;
private readonly MainManager _mainManager;
private BindableCollection<ProfileModel> _profileModels;
private ProfileModel _selectedProfileModel;
private LayerEditorViewModel<T> _editorVm;
public ProfileEditorViewModel(MainManager mainManager, GameModel gameModel)
{
_mainManager = mainManager;
_gameModel = gameModel;
ProfileModels = new BindableCollection<ProfileModel>();
LoadProfiles();
}
public BindableCollection<ProfileModel> ProfileModels
{
get { return _profileModels; }
set
{
if (Equals(value, _profileModels)) return;
_profileModels = value;
NotifyOfPropertyChange(() => ProfileModels);
}
}
public ProfileModel SelectedProfileModel
{
get { return _selectedProfileModel; }
set
{
if (Equals(value, _selectedProfileModel)) return;
_selectedProfileModel = value;
NotifyOfPropertyChange();
}
}
private void LoadProfiles()
{
ProfileModels.Clear();
ProfileModels.AddRange(ProfileProvider.GetAll(_gameModel));
SelectedProfileModel = ProfileModels.FirstOrDefault();
}
public async void AddProfile()
{
var name =
await
_mainManager.DialogService.ShowInputDialog("Add new profile",
"Please provide a profile name unique to this game and keyboard.");
if (name.Length < 1)
{
_mainManager.DialogService.ShowMessageBox("Invalid profile name", "Please provide a valid profile name");
return;
}
var profile = new ProfileModel(name, _mainManager.KeyboardManager.ActiveKeyboard.Name, _gameModel.Name);
if (ProfileProvider.GetAll().Contains(profile))
{
var overwrite =
await
_mainManager.DialogService.ShowQuestionMessageBox("Overwrite existing profile",
"A profile with this name already exists for this game. Would you like to overwrite it?");
if (!overwrite.Value)
return;
}
ProfileProvider.AddOrUpdate(profile);
LoadProfiles();
SelectedProfileModel = profile;
}
public void LayerEditor(LayerModel layer)
{
IWindowManager manager = new WindowManager();
_editorVm = new LayerEditorViewModel<T>(layer);
dynamic settings = new ExpandoObject();
settings.Title = "Artemis | Edit " + layer.Name;
manager.ShowDialog(_editorVm, null, settings);
}
private ImageSource GenerateKeyboardImage()
{
return null;
}
}
}

View File

@ -1,54 +1,53 @@
using System;
using System.Windows;
using Artemis.Events;
using Artemis.Properties;
using Artemis.Settings;
using Artemis.Utilities;
using Caliburn.Micro;
namespace Artemis.ViewModels
{
public class SystemTrayViewModel : Screen, IHandle<ToggleEnabled>
{
private readonly ShellViewModel _shellViewModel;
private readonly IWindowManager _windowManager;
private string _activeIcon;
private bool _checkedForUpdate;
private bool _enabled;
private string _toggleText;
public SystemTrayViewModel(IWindowManager windowManager, ShellViewModel shellViewModel)
{
_windowManager = windowManager;
_shellViewModel = shellViewModel;
_shellViewModel.MainManager.Events.Subscribe(this);
_shellViewModel.MainManager.EnableProgram();
_checkedForUpdate = false;
//ActiveIcon = "../logo.ico";
if (General.Default.ShowOnStartup)
ShowWindow();
}
public bool CanShowWindow => !_shellViewModel.IsActive;
public bool CanHideWindow => _shellViewModel.IsActive;
public bool Enabled
{
get { return _enabled; }
set
{
if (value == _enabled) return;
_enabled = value;
ToggleText = _enabled ? "Disable Artemis" : "Enable Artemis";
ActiveIcon = _enabled ? "../Resources/logo.ico" : "../Resources/logo-disabled.ico";
NotifyOfPropertyChange(() => Enabled);
}
}
using System;
using System.Windows;
using Artemis.Events;
using Artemis.Properties;
using Artemis.Settings;
using Artemis.Utilities;
using Caliburn.Micro;
namespace Artemis.ViewModels
{
public class SystemTrayViewModel : Screen, IHandle<ToggleEnabled>
{
private readonly ShellViewModel _shellViewModel;
private readonly IWindowManager _windowManager;
private string _activeIcon;
private bool _checkedForUpdate;
private bool _enabled;
private string _toggleText;
public SystemTrayViewModel(IWindowManager windowManager, ShellViewModel shellViewModel)
{
_windowManager = windowManager;
_shellViewModel = shellViewModel;
_shellViewModel.MainManager.Events.Subscribe(this);
_shellViewModel.MainManager.EnableProgram();
_checkedForUpdate = false;
if (General.Default.ShowOnStartup)
ShowWindow();
}
public bool CanShowWindow => !_shellViewModel.IsActive;
public bool CanHideWindow => _shellViewModel.IsActive;
public bool Enabled
{
get { return _enabled; }
set
{
if (value == _enabled) return;
_enabled = value;
ToggleText = _enabled ? "Disable Artemis" : "Enable Artemis";
ActiveIcon = _enabled ? "../Resources/logo.ico" : "../Resources/logo-disabled.ico";
NotifyOfPropertyChange(() => Enabled);
}
}
public string ActiveIcon
{
get { return _activeIcon; }
@ -57,77 +56,77 @@ namespace Artemis.ViewModels
_activeIcon = value;
NotifyOfPropertyChange();
}
}
public string ToggleText
{
get { return _toggleText; }
set
{
if (value == _toggleText) return;
_toggleText = value;
NotifyOfPropertyChange(() => ToggleText);
}
}
public void Handle(ToggleEnabled message)
{
Enabled = message.Enabled;
}
public void ToggleEnabled()
{
if (Enabled)
_shellViewModel.MainManager.DisableProgram();
else
_shellViewModel.MainManager.EnableProgram();
}
protected override void OnActivate()
{
base.OnActivate();
NotifyOfPropertyChange(() => CanShowWindow);
NotifyOfPropertyChange(() => CanHideWindow);
}
public void ShowWindow()
{
if (!CanShowWindow)
return;
// manually show the next window view-model
_windowManager.ShowWindow(_shellViewModel);
NotifyOfPropertyChange(() => CanShowWindow);
NotifyOfPropertyChange(() => CanHideWindow);
if (_checkedForUpdate)
return;
_checkedForUpdate = true;
Updater.CheckForUpdate(_shellViewModel.MainManager.DialogService);
}
public void HideWindow()
{
if (!CanHideWindow)
return;
_shellViewModel.TryClose();
NotifyOfPropertyChange(() => CanShowWindow);
NotifyOfPropertyChange(() => CanHideWindow);
}
public void ExitApplication()
{
_shellViewModel.MainManager.Shutdown();
Application.Current.Shutdown();
// Sometimes you need to be rough.
Environment.Exit(0);
}
}
}
public string ToggleText
{
get { return _toggleText; }
set
{
if (value == _toggleText) return;
_toggleText = value;
NotifyOfPropertyChange(() => ToggleText);
}
}
public void Handle(ToggleEnabled message)
{
Enabled = message.Enabled;
}
public void ToggleEnabled()
{
if (Enabled)
_shellViewModel.MainManager.DisableProgram();
else
_shellViewModel.MainManager.EnableProgram();
}
protected override void OnActivate()
{
base.OnActivate();
NotifyOfPropertyChange(() => CanShowWindow);
NotifyOfPropertyChange(() => CanHideWindow);
}
public void ShowWindow()
{
if (!CanShowWindow)
return;
// manually show the next window view-model
_windowManager.ShowWindow(_shellViewModel);
NotifyOfPropertyChange(() => CanShowWindow);
NotifyOfPropertyChange(() => CanHideWindow);
if (_checkedForUpdate)
return;
_checkedForUpdate = true;
Updater.CheckForUpdate(_shellViewModel.MainManager.DialogService);
}
public void HideWindow()
{
if (!CanHideWindow)
return;
_shellViewModel.TryClose();
NotifyOfPropertyChange(() => CanShowWindow);
NotifyOfPropertyChange(() => CanHideWindow);
}
public void ExitApplication()
{
_shellViewModel.MainManager.Shutdown();
Application.Current.Shutdown();
// Sometimes you need to be rough.
Environment.Exit(0);
}
}
}

View File

@ -0,0 +1,63 @@
<UserControl x:Class="Artemis.Views.LayerEditor.LayerConditionView"
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.Views.LayerEditor"
xmlns:cal="http://www.caliburnproject.org"
xmlns:utilities="clr-namespace:Artemis.Utilities"
mc:Ignorable="d" d:DesignWidth="613.296" Height="46">
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Resources/Icons.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
<Grid Margin="10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="30" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<!-- Left -->
<ComboBox x:Name="DataModelProps" Grid.Column="0" Width="250" MaxDropDownHeight="125"
HorizontalAlignment="Center" VerticalAlignment="Top">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel DataContext="{Binding}" Orientation="Horizontal">
<TextBlock FontWeight="Bold" Text="{Binding Path=DisplayType}"/>
<TextBlock Text="{Binding Path=Display}"/>
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<!-- Center -->
<TextBlock Grid.Column="1" Text="is" VerticalAlignment="Top" HorizontalAlignment="Center" Margin="0,3,0,0" />
<ComboBox x:Name="Operators" Grid.Column="2" Width="150" MaxDropDownHeight="125" HorizontalAlignment="Center"
VerticalAlignment="Top" />
<!-- Right -->
<Grid Grid.Column="3" HorizontalAlignment="Left" Margin="10,0,0,0" Width="152">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="125"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0" x:Name="UserValueIsVisible" HorizontalAlignment="Left" VerticalAlignment="Top">
<TextBox x:Name="UserValue" VerticalAlignment="Center" HorizontalAlignment="Left" Width="115"/>
</StackPanel>
<Button Grid.Column="1" x:Name="Delete" Width="26" Height="26" Style="{DynamicResource SquareButtonStyle}" VerticalAlignment="Top" HorizontalAlignment="Right" >
<Button.Content>
<Rectangle Fill="Black" Width="12" Height="12">
<Rectangle.OpacityMask>
<VisualBrush Visual="{StaticResource appbar_delete}" Stretch="Fill" />
</Rectangle.OpacityMask>
</Rectangle>
</Button.Content>
</Button>
</Grid>
</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.Views.LayerEditor
{
/// <summary>
/// Interaction logic for LayerConditionView.xaml
/// </summary>
public partial class LayerConditionView : UserControl
{
public LayerConditionView()
{
InitializeComponent();
}
}
}

View File

@ -0,0 +1,32 @@
<controls:MetroWindow x:Class="Artemis.Views.LayerEditorView"
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.Views"
xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls"
xmlns:cal="http://www.caliburnproject.org"
mc:Ignorable="d"
Title="Artemis | Edit Layer" Height="800" Width="630"
GlowBrush="{DynamicResource AccentColorBrush}" Icon="../logo.ico" ResizeMode="NoResize">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" Margin="10" FontSize="16" Text="Display if.." />
<ListBox Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" x:Name="LayerConditionVms" />
<Button Grid.Row="2" Grid.Column="0" x:Name="AddCondition" Content="Add condition" VerticalAlignment="Top"
Style="{DynamicResource SquareButtonStyle}" Width="95" HorizontalAlignment="Left" Margin="10" />
<Button Grid.Row="3" Grid.Column="0" x:Name="Apply" Content="Apply" VerticalAlignment="Bottom"
Style="{DynamicResource SquareButtonStyle}" Width="95" HorizontalAlignment="Left" Margin="10" />
</Grid>
</controls:MetroWindow>

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.Shapes;
using MahApps.Metro.Controls;
namespace Artemis.Views
{
/// <summary>
/// Interaction logic for LayerEditorView.xaml
/// </summary>
public partial class LayerEditorView : MetroWindow
{
public LayerEditorView()
{
InitializeComponent();
}
}
}

View File

@ -0,0 +1,85 @@
<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:local="clr-namespace:Artemis.Views"
xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls"
xmlns:cal="http://www.caliburnproject.org"
mc:Ignorable="d"
d:DesignHeight="772.5" d:DesignWidth="1335">
<Grid Width="Auto" Height="Auto">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<!-- Preview -->
<Label Grid.Column="0" Grid.Row="0" FontSize="20" HorizontalAlignment="Left" Content="Preview" />
<Border Grid.Column="0" Grid.Row="1" Background="#FF232323" BorderBrush="{DynamicResource HighlightBrush}"
BorderThickness="3" Width="750" Height="400">
<Border>
<Border.Effect>
<!-- TODO: Pulse 10-20 -->
<DropShadowEffect ShadowDepth="0"
Color="{DynamicResource HighlightColor}"
Opacity="1"
BlurRadius="20" />
</Border.Effect>
<Image Source="D:\Gebruiker folder\Mijn afbeeldingen\Artemis logo\keyboards\k95.png" Margin="50" />
</Border>
</Border>
<!-- Profile management -->
<StackPanel Grid.Column="0" Grid.Row="2" Orientation="Horizontal" Margin="0,5,0,0">
<Label Content="Active profile" />
<ComboBox Grid.Row="1" Grid.Column="1" Width="110" VerticalAlignment="Top" x:Name="ProfileModels"
DisplayMemberPath="Name" Margin="5,0,0,0" />
<Button x:Name="AddProfile" Content="Add profile" VerticalAlignment="Top"
Style="{DynamicResource SquareButtonStyle}" Width="95" HorizontalAlignment="Left"
Margin="10,0,0,0" />
<Button x:Name="RemoveProfile" Content="Remove profile" VerticalAlignment="Top"
Style="{DynamicResource SquareButtonStyle}" Width="95" HorizontalAlignment="Right"
Margin="10,0,0,0" />
</StackPanel>
<!-- Layer list -->
<Label Grid.Column="1" Grid.Row="0" FontSize="20" HorizontalAlignment="Left" Content="Layers"
Margin="10,0,0,0" />
<Border Grid.Column="1" Grid.Row="1" Background="#FF232323" BorderBrush="{DynamicResource HighlightBrush}"
BorderThickness="3" Margin="10,0,0,0" Height="400" Width="250">
<TreeView x:Name="ProfileTree" ItemsSource="{Binding Path=SelectedProfileModel.Layers}">
<TreeView.Resources>
<ResourceDictionary
Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/BaseDark.xaml" />
</TreeView.Resources>
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Children}">
<StackPanel Orientation="Horizontal" Tag="{Binding DataContext, ElementName=ProfileTree}">
<StackPanel.ContextMenu>
<ContextMenu cal:Action.TargetWithoutContext="{Binding Path=PlacementTarget.Tag, RelativeSource={RelativeSource Self}}">
<MenuItem Header="Rename" />
<MenuItem Header="Delete" />
<MenuItem Header="Properties" cal:Message.Attach="LayerEditor($datacontext)"/>
</ContextMenu>
</StackPanel.ContextMenu>
<CheckBox VerticalAlignment="Center" ToolTip="Layer enabled" />
<Image Height="18" Width="18" Source="{Binding LayerImage}" />
<TextBlock Margin="5,0,0,0" Text="{Binding Name}" VerticalAlignment="Center" />
</StackPanel>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
</Border>
<Grid Grid.Column="1" Grid.Row="2" Margin="10,5,0,0">
<Button x:Name="AddLayer" Content="Add layer" VerticalAlignment="Top"
Style="{DynamicResource SquareButtonStyle}" Width="95" HorizontalAlignment="Left" />
<Button x:Name="RemoveLayer" Content="Remove layer" VerticalAlignment="Top"
Style="{DynamicResource SquareButtonStyle}" Width="95" HorizontalAlignment="Right" />
</Grid>
</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.Views
{
/// <summary>
/// Interaction logic for ProfileEditorView.xaml
/// </summary>
public partial class ProfileEditorView : UserControl
{
public ProfileEditorView()
{
InitializeComponent();
}
}
}

View File

@ -8,7 +8,7 @@
xmlns:dialogs="clr-namespace:MahApps.Metro.Controls.Dialogs;assembly=MahApps.Metro"
dialogs:DialogParticipation.Register="{Binding RelativeSource={RelativeSource Self}, Path=DataContext}"
mc:Ignorable="d"
Title="Artemis" Height="670" Width="690"
Title="Artemis" Height="800" Width="1200"
MinWidth="500" MinHeight="400"
GlowBrush="{DynamicResource AccentColorBrush}" Icon="../logo.ico">
<!-- Bit of extra code to use a different icon than in the taskbar -->

View File

@ -18,6 +18,7 @@
<package id="SharpDX" version="3.0.2" targetFramework="net452" />
<package id="SharpDX.Direct3D11" version="3.0.2" targetFramework="net452" />
<package id="SharpDX.DXGI" version="3.0.2" targetFramework="net452" />
<package id="System.Linq.Dynamic" version="1.0.6" targetFramework="net452" />
<package id="VirtualInput" version="1.0.1" targetFramework="net452" />
<package id="WpfExceptionViewer" version="1.0.0.0" targetFramework="net452" />
</packages>

View File

@ -0,0 +1,104 @@
// Original work by VRocker https://github.com/VRocker/LogiLed2Corsair
// I'm mainly a C# developer, and these modification aren't a piece of art, but it suits our needs.
// The MIT License (MIT)
//
// Copyright (c) 2015 VRocker
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
#include "Logger.h"
#include <time.h>
#include <stdlib.h>
#include <stdarg.h>
// Ok this looks butt-ugleh but its just to force the default log level to debug if we compile in debug
#ifdef _DEBUG
LogLevel CLogger::m_eLogLevel = LogLevel::Debug;
#else
LogLevel CLogger::m_eLogLevel = LogLevel::All;
#endif
FILE* CLogger::m_pFile = 0;
void CLogger::InitLogging(const char* szFile)
{
if (!m_pFile)
{
m_pFile = fopen(szFile, "a+");
if (!m_pFile)
{
// Hum, we couldn't open the file for writing
printf("ERROR: Unable to open log file %s.\n", szFile);
}
}
}
void CLogger::EndLogging(void)
{
if (m_pFile)
{
fclose(m_pFile);
m_pFile = 0;
}
}
void CLogger::OutputLog_s(const char* sz, const LogLevel eLevel)
{
// If the level of this log entry is less important than what we are told to log, just return
if (eLevel < m_eLogLevel)
return;
// If we don't have a file to write to, bail.
if (!m_pFile)
return;
char szOutput[512] = {0};
time_t rawtime;
struct tm* timeinfo;
time(&rawtime);
timeinfo = localtime(&rawtime);
// Timestamp the log entry
size_t uiLen = sprintf(szOutput, "<%.2d/%.2d/%.2d - %.2d:%.2d:%.2d> %s\n", timeinfo->tm_mday, timeinfo->tm_mon + 1, timeinfo->tm_year + 1900, timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, sz);
// Write the text to the file
fwrite(szOutput, 1, uiLen, m_pFile);
// Flush the log file to the disk. May move this to a seperate function
fflush(m_pFile);
// Output the text to any console that may be attached
printf("%s", szOutput);
}
void CLogger::OutputLog(const char* sz, const LogLevel eLevel, ...)
{
char szText[1024] = {0};
va_list marker;
va_start(marker, eLevel);
vsprintf(szText, sz, marker);
va_end(marker);
// Since this function is pretty much the same as the safer function, we'll just redirect it there
OutputLog_s(szText, eLevel);
}

View File

@ -0,0 +1,82 @@
// Original work by VRocker https://github.com/VRocker/LogiLed2Corsair
// I'm mainly a C# developer, and these modification aren't a piece of art, but it suits our needs.
// The MIT License (MIT)
//
// Copyright (c) 2015 VRocker
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
#pragma once
#ifndef _LOGGER_H
#define _LOGGER_H
#include <stdio.h>
enum class LogLevel
{
Debug,
All,
Critical,
Warning,
Information,
User,
Internal,
None,
// Just to force the compiler to treat the enum options as an int
FORCE_32BIT = 0x7fffffff
};
class CLogger
{
public:
static LogLevel GetLogLevel(void)
{
return m_eLogLevel;
}
static void SetLogLevel(const LogLevel e)
{
#ifndef _DEBUG
if ( e == LogLevel::Debug ) return;
#endif
m_eLogLevel = e;
}
static void InitLogging(const char* szFile);
// Always remember to end logging when you are finished otherwise you will have file handles floating around
static void EndLogging(void);
// Output the text to a log file.
static void OutputLog_s(const char* sz, const LogLevel eLevel);
static void OutputLog(const char* sz, const LogLevel eLevel, ...);
static FILE* GetFile()
{
return m_pFile;
}
private:
static LogLevel m_eLogLevel;
static FILE* m_pFile;
};
#endif

View File

@ -0,0 +1,49 @@
// Original work by VRocker https://github.com/VRocker/LogiLed2Corsair
// I'm mainly a C# developer, and these modification aren't a piece of art, but it suits our needs.
// The MIT License (MIT)
//
// Copyright (c) 2015 VRocker
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
LIBRARY LogiLed2Artemis.dll
EXPORTS
LogiLedInit
LogiLedGetSdkVersion
LogiLedSetTargetDevice
LogiLedSaveCurrentLighting
LogiLedSetLighting
LogiLedRestoreLighting
LogiLedFlashLighting
LogiLedPulseLighting
LogiLedStopEffects
LogiLedSetLightingFromBitmap
LogiLedSetLightingForKeyWithScanCode
LogiLedSetLightingForKeyWithHidCode
LogiLedSetLightingForKeyWithQuartzCode
LogiLedSetLightingForKeyWithKeyName
LogiLedSaveLightingForKey
LogiLedRestoreLightingForKey
LogiLedFlashSingleKey
LogiLedPulseSingleKey
LogiLedStopEffectsOnKey
LogiLedShutdown

View File

@ -0,0 +1,168 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{D2EDB8F3-F0CB-4670-B472-0B46D5800D2C}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>LogiLed2Artemis</RootNamespace>
<ProjectName>LogiLed2Artemis</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<LibraryPath>$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<TargetName>$(ProjectName)</TargetName>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;LOGILEDCORSAIR_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ModuleDefinitionFile>LogiLed2Artemis.def</ModuleDefinitionFile>
<AdditionalDependencies>../CUESDK/lib/i386/CUESDK_2013.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;LOGILEDCORSAIR_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ModuleDefinitionFile>LogiLed2Artemis.def</ModuleDefinitionFile>
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;LOGILEDCORSAIR_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<ModuleDefinitionFile>LogiLed2Artemis.def</ModuleDefinitionFile>
<AdditionalDependencies>../CUESDK/lib/i386/CUESDK_2013.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;LOGILEDCORSAIR_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<ModuleDefinitionFile>LogiLed2Artemis.def</ModuleDefinitionFile>
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="Logger.h" />
<ClInclude Include="LogiLedDefs.h" />
<ClInclude Include="main.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="Logger.cpp" />
<ClCompile Include="main.cpp" />
</ItemGroup>
<ItemGroup>
<None Include="LogiLed2Artemis.def" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="main.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="LogiLedDefs.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Logger.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Logger.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="LogiLed2Artemis.def">
<Filter>Source Files</Filter>
</None>
</ItemGroup>
</Project>

View File

@ -0,0 +1,135 @@
#pragma once
const int LOGITECH_LED_MOUSE = 0x0001;
const int LOGITECH_LED_KEYBOARD = 0x0002;
const int LOGITECH_LED_ALL = LOGITECH_LED_MOUSE | LOGITECH_LED_KEYBOARD;
#define LOGI_LED_BITMAP_WIDTH 21
#define LOGI_LED_BITMAP_HEIGHT 6
#define LOGI_LED_BITMAP_BYTES_PER_KEY 4
#define LOGI_LED_BITMAP_SIZE LOGI_LED_BITMAP_WIDTH*LOGI_LED_BITMAP_HEIGHT*LOGI_LED_BITMAP_BYTES_PER_KEY
#define LOGI_LED_DURATION_INFINITE 0
#define LOGI_DEVICETYPE_MONOCHROME_ORD 0
#define LOGI_DEVICETYPE_RGB_ORD 1
#define LOGI_DEVICETYPE_PERKEY_RGB_ORD 2
#define LOGI_DEVICETYPE_MONOCHROME (1 << LOGI_DEVICETYPE_MONOCHROME_ORD)
#define LOGI_DEVICETYPE_RGB (1 << LOGI_DEVICETYPE_RGB_ORD)
#define LOGI_DEVICETYPE_PERKEY_RGB (1 << LOGI_DEVICETYPE_PERKEY_RGB_ORD)
#define LOGI_DEVICETYPE_ALL (LOGI_DEVICETYPE_MONOCHROME | LOGI_DEVICETYPE_RGB | LOGI_DEVICETYPE_PERKEY_RGB)
namespace LogiLed
{
typedef enum
{
ESC = 0x01,
F1 = 0x3b,
F2 = 0x3c,
F3 = 0x3d,
F4 = 0x3e,
F5 = 0x3f,
F6 = 0x40,
F7 = 0x41,
F8 = 0x42,
F9 = 0x43,
F10 = 0x44,
F11 = 0x57,
F12 = 0x58,
PRINT_SCREEN = 0x137,
SCROLL_LOCK = 0x46,
PAUSE_BREAK = 0x145,
TILDE = 0x29,
ONE = 0x02,
TWO = 0x03,
THREE = 0x04,
FOUR = 0x05,
FIVE = 0x06,
SIX = 0x07,
SEVEN = 0x08,
EIGHT = 0x09,
NINE = 0x0A,
ZERO = 0x0B,
MINUS = 0x0C,
EQUALS = 0x0D,
BACKSPACE = 0x0E,
INSERT = 0x152,
HOME = 0x147,
PAGE_UP = 0x149,
NUM_LOCK = 0x45,
NUM_SLASH = 0x135,
NUM_ASTERISK = 0x37,
NUM_MINUS = 0x4A,
TAB = 0x0F,
Q = 0x10,
W = 0x11,
E = 0x12,
R = 0x13,
T = 0x14,
Y = 0x15,
U = 0x16,
I = 0x17,
O = 0x18,
P = 0x19,
OPEN_BRACKET = 0x1A,
CLOSE_BRACKET = 0x1B,
BACKSLASH = 0x2B,
KEYBOARD_DELETE = 0x153,
END = 0x14F,
PAGE_DOWN = 0x151,
NUM_SEVEN = 0x47,
NUM_EIGHT = 0x48,
NUM_NINE = 0x49,
NUM_PLUS = 0x4E,
CAPS_LOCK = 0x3A,
A = 0x1E,
S = 0x1F,
D = 0x20,
F = 0x21,
G = 0x22,
H = 0x23,
J = 0x24,
K = 0x25,
L = 0x26,
SEMICOLON = 0x27,
APOSTROPHE = 0x28,
ENTER = 0x1C,
NUM_FOUR = 0x4B,
NUM_FIVE = 0x4C,
NUM_SIX = 0x4D,
LEFT_SHIFT = 0x2A,
Z = 0x2C,
X = 0x2D,
C = 0x2E,
V = 0x2F,
B = 0x30,
N = 0x31,
M = 0x32,
COMMA = 0x33,
PERIOD = 0x34,
FORWARD_SLASH = 0x35,
RIGHT_SHIFT = 0x36,
ARROW_UP = 0x148,
NUM_ONE = 0x4F,
NUM_TWO = 0x50,
NUM_THREE = 0x51,
NUM_ENTER = 0x11C,
LEFT_CONTROL = 0x1D,
LEFT_WINDOWS = 0x15B,
LEFT_ALT = 0x38,
SPACE = 0x39,
RIGHT_ALT = 0x138,
RIGHT_WINDOWS = 0x15C,
APPLICATION_SELECT = 0x15D,
RIGHT_CONTROL = 0x11D,
ARROW_LEFT = 0x14B,
ARROW_DOWN = 0x150,
ARROW_RIGHT = 0x14D,
NUM_ZERO = 0x52,
NUM_PERIOD = 0x53,
} KeyName;
}

View File

@ -0,0 +1,254 @@
// Original work by VRocker https://github.com/VRocker/LogiLed2Corsair
// I'm mainly a C# developer, and these modification aren't a piece of art, but it suits our needs.
// The MIT License (MIT)
//
// Copyright (c) 2015 VRocker
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
#include "main.h"
#include <stdio.h>
#include <tchar.h>
#include <thread>
#include "LogiLedDefs.h"
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include "Logger.h"
#include <complex>
#include <filesystem>
static bool g_hasInitialised = false;
const char* game = "";
void cleanup()
{
CLogger::EndLogging();
}
BOOL WINAPI DllMain(HINSTANCE hInst, DWORD fdwReason, LPVOID)
{
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
{
atexit(cleanup);
CLogger::InitLogging("Log.txt");
CLogger::SetLogLevel(LogLevel::None);
// Get the process that loaded the DLL
TCHAR divisionFind[] = _T("Division");
TCHAR gtaFind[] = _T("GTA");
TCHAR szPath[MAX_PATH];
GetModuleFileName(NULL, szPath, MAX_PATH);
if (_tcscmp(szPath, divisionFind) != 0)
game = "division";
else if (_tcscmp(szPath, gtaFind) != 0)
game = "gta";
CLogger::OutputLog("Attached to process.", LogLevel::Debug);
}
break;
case DLL_PROCESS_DETACH:
{
cleanup();
CLogger::OutputLog_s("Detached from process.", LogLevel::Debug);
}
break;
}
return true;
}
bool LogiLedInit()
{
CLogger::OutputLog_s("Logitech LED init called.", LogLevel::Debug);
g_hasInitialised = true;
return true;
}
bool LogiLedGetSdkVersion(int* majorNum, int* minorNum, int* buildNum)
{
CLogger::OutputLog("LogiLedGetSdkVersion called.", LogLevel::Debug);
// Mimic the SDK version
*majorNum = 8;
*minorNum = 81;
*buildNum = 15;
return true;
}
bool LogiLedSetTargetDevice(int targetDevice)
{
CLogger::OutputLog("LogiLedSetTargetDevice called (%i)", LogLevel::Debug, targetDevice);
// Logitech SDK says this function returns false if LogiLedInit hasn't been called
return g_hasInitialised;
}
bool LogiLedSaveCurrentLighting()
{
CLogger::OutputLog("LogiLedSaveCurrentLighting called (%i)", LogLevel::Debug);
return true;
}
void Transmit(const char* msg)
{
//Pipe Init Data
HANDLE hPipe1;
char buf[100];
LPTSTR lpszPipename1 = TEXT("\\\\.\\pipe\\artemis");
hPipe1 = CreateFile(lpszPipename1, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
if (hPipe1 == NULL || hPipe1 == INVALID_HANDLE_VALUE)
{
CLogger::OutputLog("Could not open the pipe - (error %i)", LogLevel::Debug, GetLastError());
return;
}
DWORD cbWritten;
WriteFile(hPipe1, msg, strlen(msg), &cbWritten, NULL);
CLogger::OutputLog_s("Transmitted to pipe", LogLevel::Debug);
}
bool LogiLedSetLighting(int redPercentage, int greenPercentage, int bluePercentage)
{
CLogger::OutputLog("LogiLedSetLighting called (%i %i %i)", LogLevel::Debug, redPercentage, greenPercentage, bluePercentage);
std::ostringstream os;
os << "0 0 " << redPercentage << " " << greenPercentage << " " << bluePercentage;
Transmit(os.str().c_str());
return true;
}
bool LogiLedRestoreLighting()
{
CLogger::OutputLog("LogiLedRestoreLighting called", LogLevel::Debug);
return true;
}
bool LogiLedFlashLighting(int redPercentage, int greenPercentage, int bluePercentage, int milliSecondsDuration, int milliSecondsInterval)
{
CLogger::OutputLog("LogiLedFlashLighting called (%i %i %i %i %i)", LogLevel::Debug, redPercentage, greenPercentage, bluePercentage, milliSecondsDuration, milliSecondsInterval);
return true;
}
bool LogiLedPulseLighting(int redPercentage, int greenPercentage, int bluePercentage, int milliSecondsDuration, int milliSecondsInterval)
{
CLogger::OutputLog("LogiLedPulseLighting called (%i %i %i %i %i)", LogLevel::Debug, redPercentage, greenPercentage, bluePercentage, milliSecondsDuration, milliSecondsInterval);
return true;
}
bool LogiLedStopEffects()
{
CLogger::OutputLog_s("LogiLedStopEffects called", LogLevel::Debug);
return true;
}
bool LogiLedSetLightingFromBitmap(unsigned char bitmap[])
{
CLogger::OutputLog_s("LogiLedSetLightingFromBitmap called", LogLevel::Debug);
return true;
}
bool LogiLedSetLightingForKeyWithScanCode(int keyCode, int redPercentage, int greenPercentage, int bluePercentage)
{
CLogger::OutputLog("LogiLedSetLightingForKeyWithScanCode called [Key: %i] (%i %i %i)", LogLevel::Debug, keyCode, redPercentage, greenPercentage, bluePercentage);
return true;
}
bool LogiLedSetLightingForKeyWithHidCode(int keyCode, int redPercentage, int greenPercentage, int bluePercentage)
{
CLogger::OutputLog("LogiLedSetLightingForKeyWithHidCode called [Key: %i] (%i %i %i)", LogLevel::Debug, keyCode, redPercentage, greenPercentage, bluePercentage);
return true;
}
bool LogiLedSetLightingForKeyWithQuartzCode(int keyCode, int redPercentage, int greenPercentage, int bluePercentage)
{
CLogger::OutputLog("LogiLedSetLightingForKeyWithQuartzCode called [Key: %i] (%i %i %i)", LogLevel::Debug, keyCode, redPercentage, greenPercentage, bluePercentage);
return true;
}
bool LogiLedSetLightingForKeyWithKeyName(LogiLed::KeyName keyName, int redPercentage, int greenPercentage, int bluePercentage)
{
CLogger::OutputLog("LogiLedSetLightingForKeyWithKeyName called [Key: %i] (%i %i %i)", LogLevel::Debug, keyName, redPercentage, greenPercentage, bluePercentage);
// Only transmit interesting keys. This can most likely be done prettier, but I'm no C++ dev.
if (game == "division" &&
(keyName == LogiLed::F1 ||
keyName == LogiLed::F2 ||
keyName == LogiLed::F3 ||
keyName == LogiLed::F4 ||
keyName == LogiLed::R ||
keyName == LogiLed::G ||
keyName == LogiLed::V)
)
{
std::ostringstream os;
os << "1 " << keyName << " " << redPercentage << " " << greenPercentage << " " << bluePercentage;
std::string s = os.str();
Transmit(os.str().c_str());
}
return true;
}
bool LogiLedSaveLightingForKey(LogiLed::KeyName keyName)
{
CLogger::OutputLog("LogiLedSaveLightingForKey called [Key: %i]", LogLevel::Debug, keyName);
return true;
}
bool LogiLedRestoreLightingForKey(LogiLed::KeyName keyName)
{
CLogger::OutputLog("LogiLedRestoreLightingForKey called [Key: %i]", LogLevel::Debug, keyName);
return true;
}
bool LogiLedFlashSingleKey(LogiLed::KeyName keyName, int redPercentage, int greenPercentage, int bluePercentage, int msDuration, int msInterval)
{
CLogger::OutputLog("LogiLedFlashSingleKey called [Key: %i] (%i %i %i %i %i)", LogLevel::Debug, keyName, redPercentage, greenPercentage, bluePercentage, msDuration, msInterval);
return true;
}
bool LogiLedPulseSingleKey(LogiLed::KeyName keyName, int startRedPercentage, int startGreenPercentage, int startBluePercentage, int finishRedPercentage, int finishGreenPercentage, int finishBluePercentage, int msDuration, bool isInfinite)
{
CLogger::OutputLog("LogiLedPulseSingleKey called [Key: %i] (%i %i %i %i %i %i %i %i)", LogLevel::Debug, keyName, startRedPercentage, startGreenPercentage, startBluePercentage, finishRedPercentage, finishGreenPercentage, finishBluePercentage, msDuration, isInfinite);
return true;
}
bool LogiLedStopEffectsOnKey(LogiLed::KeyName keyName)
{
CLogger::OutputLog("LogiLedStopEffectsOnKey called [Key: %i]", LogLevel::Debug, keyName);
return true;
}
void LogiLedShutdown()
{
CLogger::OutputLog_s("LogiLedShutdown called.", LogLevel::Debug);
g_hasInitialised = false;
}

View File

@ -0,0 +1,2 @@
#pragma once