1
0
mirror of https://github.com/Artemis-RGB/Artemis synced 2025-12-13 05:48:35 +00:00

Initial code commit

This commit is contained in:
Robert Beekman 2016-01-08 20:54:56 +01:00
parent 0e10556848
commit 85c725f1ea
103 changed files with 11758 additions and 0 deletions

22
Artemis/Artemis.sln Normal file
View File

@ -0,0 +1,22 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.23107.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Artemis", "Artemis\Artemis.csproj", "{ED9997A2-E54C-4E9F-9350-62BE672C3ABE}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{ED9997A2-E54C-4E9F-9350-62BE672C3ABE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{ED9997A2-E54C-4E9F-9350-62BE672C3ABE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{ED9997A2-E54C-4E9F-9350-62BE672C3ABE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{ED9997A2-E54C-4E9F-9350-62BE672C3ABE}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

102
Artemis/Artemis/App.config Normal file
View File

@ -0,0 +1,102 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<sectionGroup name="userSettings"
type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<section name="Artemis.Settings.AudioVisualization"
type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
allowExeDefinition="MachineToLocalUser" requirePermission="false" />
<section name="Artemis.Settings.RocketLeague"
type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
allowExeDefinition="MachineToLocalUser" requirePermission="false" />
<section name="Artemis.Properties.Settings"
type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
allowExeDefinition="MachineToLocalUser" requirePermission="false" />
<section name="Artemis.Settings.TypeWave"
type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
allowExeDefinition="MachineToLocalUser" requirePermission="false" />
<section name="Artemis.Settings.General"
type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
allowExeDefinition="MachineToLocalUser" requirePermission="false" />
</sectionGroup>
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
</startup>
<userSettings>
<Artemis.Settings.AudioVisualization>
<setting name="Sensitivity" serializeAs="String">
<value>4</value>
</setting>
<setting name="Bars" serializeAs="String">
<value>21</value>
</setting>
<setting name="Spread" serializeAs="String">
<value>1</value>
</setting>
<setting name="FadeSpeed" serializeAs="String">
<value>3</value>
</setting>
<setting name="MainColor" serializeAs="String">
<value>#FF0000FF</value>
</setting>
<setting name="SecondaryColor" serializeAs="String">
<value>#FF1E90FF</value>
</setting>
</Artemis.Settings.AudioVisualization>
<Artemis.Settings.RocketLeague>
<setting name="Enabled" serializeAs="String">
<value>False</value>
</setting>
<setting name="MainColor" serializeAs="String">
<value>#FFFF5000</value>
</setting>
<setting name="SecondaryColor" serializeAs="String">
<value>#FFFF0000</value>
</setting>
</Artemis.Settings.RocketLeague>
<Artemis.Properties.Settings>
<setting name="LastEffect" serializeAs="String">
<value>TypeWave</value>
</setting>
</Artemis.Properties.Settings>
<Artemis.Settings.TypeWave>
<setting name="IsRandomColors" serializeAs="String">
<value>True</value>
</setting>
<setting name="WaveColor" serializeAs="String">
<value>#FFFF0000</value>
</setting>
<setting name="IsShiftColors" serializeAs="String">
<value>True</value>
</setting>
<setting name="ShiftColorSpeed" serializeAs="String">
<value>20</value>
</setting>
<setting name="TimeToLive" serializeAs="String">
<value>500</value>
</setting>
<setting name="SpreadSpeed" serializeAs="String">
<value>4</value>
</setting>
</Artemis.Settings.TypeWave>
<Artemis.Settings.General>
<setting name="LastEffect" serializeAs="String">
<value>TypeWave</value>
</setting>
<setting name="LastKeyboard" serializeAs="String">
<value>Logitech G910 Orion Spark RGB</value>
</setting>
</Artemis.Settings.General>
</userSettings>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-7.0.0.0" newVersion="7.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

21
Artemis/Artemis/App.xaml Normal file
View File

@ -0,0 +1,21 @@
<Application x:Class="Artemis.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Artemis">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary>
<local:AppBootstrapper x:Key="bootstrapper" />
</ResourceDictionary>
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Fonts.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Colors.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/Teal.xaml" />
<ResourceDictionary
Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/BaseLight.xaml" />
<ResourceDictionary Source="/Resources/Icons.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>

View File

@ -0,0 +1,15 @@
using System.Windows;
namespace Artemis
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
public App()
{
InitializeComponent();
}
}
}

View File

@ -0,0 +1,19 @@
using System.Windows;
using Artemis.ViewModels;
using Caliburn.Micro;
namespace Artemis
{
public class AppBootstrapper : BootstrapperBase
{
public AppBootstrapper()
{
Initialize();
}
protected override void OnStartup(object sender, StartupEventArgs e)
{
DisplayRootViewFor<ShellViewModel>();
}
}
}

View File

@ -0,0 +1,396 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{ED9997A2-E54C-4E9F-9350-62BE672C3ABE}</ProjectGuid>
<OutputType>WinExe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Artemis</RootNamespace>
<AssemblyName>Artemis</AssemblyName>
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<WarningLevel>4</WarningLevel>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<SccProjectName>
</SccProjectName>
<SccLocalPath>
</SccLocalPath>
<SccAuxPath>
</SccAuxPath>
<SccProvider>
</SccProvider>
<IsWebBootstrapper>false</IsWebBootstrapper>
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
<UpdateEnabled>false</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>false</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>2</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<UseApplicationTrust>false</UseApplicationTrust>
<PublishWizardCompleted>true</PublishWizardCompleted>
<BootstrapperEnabled>true</BootstrapperEnabled>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>x64</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<ManifestCertificateThumbprint>EAC088BE27A2DE790AE6F37A020409F4A1B5EC0E</ManifestCertificateThumbprint>
</PropertyGroup>
<PropertyGroup>
<ManifestKeyFile>Artemis_TemporaryKey.pfx</ManifestKeyFile>
</PropertyGroup>
<PropertyGroup>
<GenerateManifests>true</GenerateManifests>
</PropertyGroup>
<PropertyGroup>
<SignManifests>false</SignManifests>
</PropertyGroup>
<ItemGroup>
<Reference Include="Caliburn.Micro, Version=2.0.2.0, Culture=neutral, PublicKeyToken=8e5891231f2ed21f, processorArchitecture=MSIL">
<HintPath>..\packages\Caliburn.Micro.Core.2.0.2\lib\net45\Caliburn.Micro.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Caliburn.Micro.Platform, Version=2.0.2.0, Culture=neutral, PublicKeyToken=8e5891231f2ed21f, processorArchitecture=MSIL">
<HintPath>..\packages\Caliburn.Micro.2.0.2\lib\net45\Caliburn.Micro.Platform.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="MahApps.Metro, Version=1.1.2.0, Culture=neutral, PublicKeyToken=f4fb5a3c4d1e5b4f, processorArchitecture=MSIL">
<HintPath>..\packages\MahApps.Metro.1.1.2.0\lib\net45\MahApps.Metro.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="MyMemory-x64">
<HintPath>E:\Downloads\Chome Downloads\MyMemory-x64.dll</HintPath>
</Reference>
<Reference Include="NAudio, Version=1.7.3.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\NAudio.1.7.3\lib\net35\NAudio.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Newtonsoft.Json, Version=7.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Open.WinKeyboardHook, Version=1.0.10.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Open.WinKeyboardHook.1.0.10.0\lib\net45\Open.WinKeyboardHook.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Drawing" />
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.Web" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Windows.Interactivity, Version=4.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\MahApps.Metro.1.1.2.0\lib\net45\System.Windows.Interactivity.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Xml" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xaml">
<RequiredTargetFramework>4.0</RequiredTargetFramework>
</Reference>
<Reference Include="WindowsBase" />
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
<Reference Include="Xceed.Wpf.AvalonDock, Version=2.5.0.0, Culture=neutral, PublicKeyToken=3e4669d2f30244f4, processorArchitecture=MSIL">
<HintPath>..\packages\Extended.Wpf.Toolkit.2.5\lib\net40\Xceed.Wpf.AvalonDock.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Xceed.Wpf.AvalonDock.Themes.Aero, Version=2.5.0.0, Culture=neutral, PublicKeyToken=3e4669d2f30244f4, processorArchitecture=MSIL">
<HintPath>..\packages\Extended.Wpf.Toolkit.2.5\lib\net40\Xceed.Wpf.AvalonDock.Themes.Aero.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Xceed.Wpf.AvalonDock.Themes.Metro, Version=2.5.0.0, Culture=neutral, PublicKeyToken=3e4669d2f30244f4, processorArchitecture=MSIL">
<HintPath>..\packages\Extended.Wpf.Toolkit.2.5\lib\net40\Xceed.Wpf.AvalonDock.Themes.Metro.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Xceed.Wpf.AvalonDock.Themes.VS2010, Version=2.5.0.0, Culture=neutral, PublicKeyToken=3e4669d2f30244f4, processorArchitecture=MSIL">
<HintPath>..\packages\Extended.Wpf.Toolkit.2.5\lib\net40\Xceed.Wpf.AvalonDock.Themes.VS2010.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Xceed.Wpf.DataGrid, Version=2.5.0.0, Culture=neutral, PublicKeyToken=3e4669d2f30244f4, processorArchitecture=MSIL">
<HintPath>..\packages\Extended.Wpf.Toolkit.2.5\lib\net40\Xceed.Wpf.DataGrid.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Xceed.Wpf.Toolkit, Version=2.5.0.0, Culture=neutral, PublicKeyToken=3e4669d2f30244f4, processorArchitecture=MSIL">
<HintPath>..\packages\Extended.Wpf.Toolkit.2.5\lib\net40\Xceed.Wpf.Toolkit.dll</HintPath>
<Private>True</Private>
</Reference>
</ItemGroup>
<ItemGroup>
<ApplicationDefinition Include="App.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</ApplicationDefinition>
<Compile Include="App.xaml.cs">
<DependentUpon>App.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="AppBootStrapper.cs" />
<Compile Include="Events\ChangeActiveEffect.cs" />
<Compile Include="Events\ChangeBitmap.cs" />
<Compile Include="KeyboardProviders\Corsair\K70.cs" />
<Compile Include="KeyboardProviders\Corsair\K95.cs" />
<Compile Include="KeyboardProviders\KeyboardProvider.cs" />
<Compile Include="KeyboardProviders\Logitech\Orion.cs" />
<Compile Include="KeyboardProviders\Logitech\Utilities\KeyboardNames.cs" />
<Compile Include="KeyboardProviders\Logitech\Utilities\KeyMap.cs" />
<Compile Include="KeyboardProviders\Logitech\Utilities\LogitechGSDK.cs" />
<Compile Include="KeyboardProviders\Logitech\Utilities\OrionUtilities.cs" />
<Compile Include="KeyboardProviders\ProviderHelper.cs" />
<Compile Include="Models\EffectModel.cs" />
<Compile Include="Modules\Effects\AudioVisualizer\AudioVisualizerModel.cs" />
<Compile Include="Modules\Effects\Debug\DebugEffectModel.cs" />
<Compile Include="Modules\Effects\TypeHole\TypeHoleModel.cs" />
<Compile Include="Modules\Effects\TypeWave\TypeWaveModel.cs" />
<Compile Include="Models\GameModel.cs" />
<Compile Include="Modules\Games\CounterStrike\CounterStrikeModel.cs" />
<Compile Include="Modules\Games\RocketLeague\RocketLeagueModel.cs" />
<Compile Include="Modules\Games\Witcher3\Witcher3Model.cs" />
<Compile Include="Models\MainModel.cs" />
<Compile Include="Models\OverlayModel.cs" />
<Compile Include="Modules\Overlays\VolumeDisplay\VolumeDisplay.cs" />
<Compile Include="Modules\Overlays\VolumeDisplay\VolumeDisplayModel.cs" />
<Compile Include="Modules\Effects\AudioVisualizer\AudioVisualizerSettings.cs" />
<Compile Include="Modules\Effects\Debug\DebugEffectSettings.cs" />
<Compile Include="Models\EffectSettings.cs" />
<Compile Include="Modules\Overlays\VolumeDisplay\VolumeDisplaySettings.cs" />
<Compile Include="Modules\Games\RocketLeague\RocketLeagueSettings.cs" />
<Compile Include="Modules\Effects\TypeWave\TypeWaveSettings.cs" />
<Compile Include="Properties\Annotations.cs" />
<Compile Include="Settings\AudioVisualization.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
<DependentUpon>AudioVisualization.settings</DependentUpon>
</Compile>
<Compile Include="Settings\General.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
<DependentUpon>General.settings</DependentUpon>
</Compile>
<Compile Include="Settings\RocketLeague.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
<DependentUpon>RocketLeague.settings</DependentUpon>
</Compile>
<Compile Include="Settings\TypeWave.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
<DependentUpon>TypeWave.settings</DependentUpon>
</Compile>
<Compile Include="Utilities\Audio\FftEventArgs.cs" />
<Compile Include="Utilities\Audio\SampleAggregator.cs" />
<Compile Include="Utilities\ColorHelpers.cs" />
<Compile Include="Utilities\GameSense\GameDataReceivedEventArgs.cs" />
<Compile Include="Utilities\GameSense\GameSenseWebServer.cs" />
<Compile Include="Utilities\GameSense\JsonModels\CounterStrikeJson.cs" />
<Compile Include="Utilities\Memory\Memory.cs" />
<Compile Include="Utilities\Memory\MemoryHelpers.cs" />
<Compile Include="Utilities\Memory\Win32.cs" />
<Compile Include="Utilities\Keyboard\Key.cs" />
<Compile Include="Utilities\Keyboard\KeyboardRectangle.cs" />
<Compile Include="ViewModels\EffectsViewModel.cs" />
<Compile Include="Modules\Effects\AudioVisualizer\AudioVisualizerViewModel.cs" />
<Compile Include="Modules\Effects\Debug\DebugEffectViewModel.cs" />
<Compile Include="Modules\Effects\TypeHole\TypeHoleViewModel.cs" />
<Compile Include="Modules\Effects\TypeWave\TypeWaveViewModel.cs" />
<Compile Include="ViewModels\GamesViewModel.cs" />
<Compile Include="Modules\Games\CounterStrike\CounterStrikeViewModel.cs" />
<Compile Include="Modules\Games\Dota2\Dota2ViewModel.cs" />
<Compile Include="Modules\Games\RocketLeague\RocketLeagueViewModel.cs" />
<Compile Include="Modules\Games\Witcher3\Witcher3ViewModel.cs" />
<Compile Include="ViewModels\OverlaysViewModel.cs" />
<Compile Include="Modules\Overlays\VolumeDisplay\VolumeDisplayViewModel.cs" />
<Compile Include="ViewModels\ShellViewModel.cs" />
<Compile Include="Views\EffectsView.xaml.cs">
<DependentUpon>EffectsView.xaml</DependentUpon>
</Compile>
<Compile Include="Modules\Effects\Debug\DebugEffectView.xaml.cs">
<DependentUpon>DebugEffectView.xaml</DependentUpon>
</Compile>
<Compile Include="Modules\Effects\AudioVisualizer\AudioVisualizerView.xaml.cs">
<DependentUpon>AudioVisualizerView.xaml</DependentUpon>
</Compile>
<Compile Include="Modules\Effects\TypeHole\TypeHoleView.xaml.cs">
<DependentUpon>TypeHoleView.xaml</DependentUpon>
</Compile>
<Compile Include="Modules\Effects\TypeWave\TypeWaveView.xaml.cs">
<DependentUpon>TypeWaveView.xaml</DependentUpon>
</Compile>
<Compile Include="Views\GamesView.xaml.cs">
<DependentUpon>GamesView.xaml</DependentUpon>
</Compile>
<Compile Include="Modules\Games\CounterStrike\CounterStrikeView.xaml.cs">
<DependentUpon>CounterStrikeView.xaml</DependentUpon>
</Compile>
<Compile Include="Modules\Games\Dota2\Dota2View.xaml.cs">
<DependentUpon>Dota2View.xaml</DependentUpon>
</Compile>
<Compile Include="Modules\Games\RocketLeague\RocketLeagueView.xaml.cs">
<DependentUpon>RocketLeagueView.xaml</DependentUpon>
</Compile>
<Compile Include="Modules\Games\Witcher3\Witcher3View.xaml.cs">
<DependentUpon>Witcher3View.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\ShellView.xaml.cs">
<DependentUpon>ShellView.xaml</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
<None Include="packages.config" />
<AppDesigner Include="Properties\" />
<Resource Include="Resources\Entypo.ttf" />
<None Include="Settings\AudioVisualization.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>AudioVisualization.Designer.cs</LastGenOutput>
</None>
<None Include="Settings\General.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>General.Designer.cs</LastGenOutput>
</None>
<None Include="Settings\RocketLeague.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>RocketLeague.Designer.cs</LastGenOutput>
</None>
<None Include="Settings\TypeWave.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>TypeWave.Designer.cs</LastGenOutput>
</None>
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<Page Include="Resources\Icons.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Views\EffectsView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Modules\Effects\Debug\DebugEffectView.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Modules\Effects\AudioVisualizer\AudioVisualizerView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Modules\Effects\TypeHole\TypeHoleView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Modules\Effects\TypeWave\TypeWaveView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\GamesView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Modules\Games\CounterStrike\CounterStrikeView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Modules\Games\Dota2\Dota2View.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Modules\Games\RocketLeague\RocketLeagueView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Modules\Games\Witcher3\Witcher3View.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\OverlaysView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Modules\Overlays\VolumeDisplay\VolumeDisplayView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\ShellView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<ItemGroup />
<ItemGroup>
<Content Include="LogitechLedEnginesWrapper.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Resource Include="Resources\Entypo-license.txt" />
<Resource Include="Resources\WindowsIcons-license.txt" />
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include=".NETFramework,Version=v4.5.2">
<Visible>False</Visible>
<ProductName>Microsoft .NET Framework 4.5.2 %28x86 and x64%29</ProductName>
<Install>true</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1</ProductName>
<Install>false</Install>
</BootstrapperPackage>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@ -0,0 +1,12 @@
namespace Artemis.Events
{
public class ChangeActiveEffect
{
public ChangeActiveEffect(string activeEffect)
{
ActiveEffect = activeEffect;
}
public string ActiveEffect { get; set; }
}
}

View File

@ -0,0 +1,19 @@
using System.Drawing;
namespace Artemis.Events
{
public class ChangeBitmap
{
public ChangeBitmap(Bitmap bitmap)
{
Bitmap = bitmap;
}
public Bitmap Bitmap { get; private set; }
public void ChangeTextMessage(Bitmap bitmap)
{
Bitmap = bitmap;
}
}
}

View File

@ -0,0 +1,24 @@
using System.Drawing;
namespace Artemis.KeyboardProviders.Corsair
{
internal class K95 : KeyboardProvider
{
public K95()
{
Name = "Corsair Gaming K95 RGB";
}
public override void Enable()
{
}
public override void Disable()
{
}
public override void DrawBitmap(Bitmap bitmap)
{
}
}
}

View File

@ -0,0 +1,25 @@
using System.Drawing;
namespace Artemis.KeyboardProviders.Corsair
{
internal class K70 : KeyboardProvider
{
public K70()
{
Name = "Corsair Gaming K70 RGB";
}
public override void Enable()
{
}
public override void Disable()
{
}
public override void DrawBitmap(Bitmap bitmap)
{
// TODO: Convert bitmap to something tasty for CUE.NET
}
}
}

View File

@ -0,0 +1,13 @@
using System.Drawing;
namespace Artemis.KeyboardProviders
{
public abstract class KeyboardProvider
{
public string Name { get; set; }
public abstract void Enable();
public abstract void Disable();
public abstract void DrawBitmap(Bitmap bitmap);
}
}

View File

@ -0,0 +1,34 @@
using System.Drawing;
using System.Threading;
using Artemis.KeyboardProviders.Logitech.Utilities;
namespace Artemis.KeyboardProviders.Logitech
{
internal class Orion : KeyboardProvider
{
public Orion()
{
Name = "Logitech G910 Orion Spark RGB";
}
public override void Enable()
{
// Initialize the SDK
LogitechGSDK.LogiLedInit();
Thread.Sleep(200);
LogitechGSDK.LogiLedSaveCurrentLighting();
}
public override void Disable()
{
// Shutdown the SDK
LogitechGSDK.LogiLedRestoreLighting();
LogitechGSDK.LogiLedShutdown();
}
public override void DrawBitmap(Bitmap bitmap)
{
LogitechGSDK.LogiLedSetLightingFromBitmap(OrionUtilities.BitmapToByteArray(bitmap));
}
}
}

View File

@ -0,0 +1,137 @@
using System.Collections.Generic;
using System.Windows.Forms;
using Artemis.Utilities.Keyboard;
namespace Artemis.KeyboardProviders.Logitech.Utilities
{
public static class KeyMap
{
static KeyMap()
{
// There are several keyboard layouts
// TODO: Implemented more layouts and an option to select them
UsEnglishOrionKeys = new List<Key>
{
// Row 1
new Key(Keys.Escape, 0, 0),
new Key(Keys.F1, 1, 0),
new Key(Keys.F2, 2, 0),
new Key(Keys.F3, 3, 0),
new Key(Keys.F4, 4, 0),
new Key(Keys.F5, 5, 0),
new Key(Keys.F6, 6, 0),
new Key(Keys.F7, 7, 0),
new Key(Keys.F8, 8, 0),
new Key(Keys.F9, 9, 0),
new Key(Keys.F10, 10, 0),
new Key(Keys.F11, 11, 0),
new Key(Keys.F12, 12, 0),
new Key(Keys.PrintScreen, 13, 0),
new Key(Keys.Scroll, 14, 0),
new Key(Keys.Pause, 15, 0),
// Row 2
new Key(Keys.Oemtilde, 0, 1),
new Key(Keys.D1, 1, 1),
new Key(Keys.D2, 2, 1),
new Key(Keys.D3, 3, 1),
new Key(Keys.D4, 4, 1),
new Key(Keys.D5, 5, 1),
new Key(Keys.D6, 6, 1),
new Key(Keys.D7, 7, 1),
new Key(Keys.D8, 8, 1),
new Key(Keys.D9, 9, 1),
new Key(Keys.D0, 10, 1),
new Key(Keys.OemMinus, 11, 1),
new Key(Keys.Oemplus, 12, 1),
new Key(Keys.Back, 13, 1),
new Key(Keys.Insert, 14, 1),
new Key(Keys.Home, 15, 1),
new Key(Keys.PageUp, 16, 1),
new Key(Keys.NumLock, 17, 1),
new Key(Keys.Divide, 18, 1),
new Key(Keys.Multiply, 19, 1),
new Key(Keys.Subtract, 20, 1),
// Row 3
new Key(Keys.Tab, 0, 2),
new Key(Keys.Q, 1, 2),
new Key(Keys.W, 2, 2),
new Key(Keys.E, 3, 2),
new Key(Keys.R, 4, 2),
new Key(Keys.T, 5, 2),
new Key(Keys.Y, 6, 2),
new Key(Keys.U, 7, 2),
new Key(Keys.I, 8, 2),
new Key(Keys.O, 9, 2),
new Key(Keys.P, 10, 2),
new Key(Keys.OemOpenBrackets, 11, 2),
new Key(Keys.Oem6, 12, 2),
new Key(Keys.Delete, 14, 2),
new Key(Keys.End, 15, 2),
new Key(Keys.Next, 16, 2),
new Key(Keys.NumPad7, 17, 2),
new Key(Keys.NumPad8, 18, 2),
new Key(Keys.NumPad9, 19, 2),
new Key(Keys.Add, 20, 2),
// Row 4
new Key(Keys.Capital, 0, 3),
new Key(Keys.A, 1, 3),
new Key(Keys.S, 2, 3),
new Key(Keys.D, 3, 3),
new Key(Keys.F, 4, 3),
new Key(Keys.G, 5, 3),
new Key(Keys.H, 6, 3),
new Key(Keys.J, 7, 3),
new Key(Keys.K, 8, 3),
new Key(Keys.L, 9, 3),
new Key(Keys.Oem1, 10, 3),
new Key(Keys.Oem7, 11, 3),
new Key(Keys.Oem5, 12, 3),
new Key(Keys.Return, 13, 3),
new Key(Keys.NumPad4, 17, 3),
new Key(Keys.NumPad5, 18, 3),
new Key(Keys.NumPad6, 19, 3),
// Row 5
new Key(Keys.LShiftKey, 1, 4),
new Key(Keys.OemBackslash, 2, 4),
new Key(Keys.Z, 2, 4),
new Key(Keys.X, 3, 4),
new Key(Keys.C, 4, 4),
new Key(Keys.V, 5, 4),
new Key(Keys.B, 6, 4),
new Key(Keys.N, 7, 4),
new Key(Keys.M, 8, 4),
new Key(Keys.Oemcomma, 9, 4),
new Key(Keys.OemPeriod, 10, 4),
new Key(Keys.OemQuestion, 11, 4),
new Key(Keys.RShiftKey, 13, 4),
new Key(Keys.Up, 15, 4),
new Key(Keys.NumPad1, 17, 4),
new Key(Keys.NumPad2, 18, 4),
new Key(Keys.NumPad3, 19, 4),
// Both returns return "Return" (Yes...)
// new OrionKey(System.Windows.Forms.Keys.Return, 20, 4),
// Row 6
new Key(Keys.LControlKey, 0, 5),
new Key(Keys.LWin, 1, 5),
new Key(Keys.LMenu, 2, 5),
new Key(Keys.Space, 5, 5),
new Key(Keys.RMenu, 11, 5),
new Key(Keys.RWin, 12, 5),
new Key(Keys.Apps, 13, 5),
new Key(Keys.RControlKey, 14, 5),
new Key(Keys.Left, 15, 5),
new Key(Keys.Down, 16, 5),
new Key(Keys.Right, 17, 5),
new Key(Keys.NumPad0, 18, 5),
new Key(Keys.Decimal, 19, 5)
};
}
public static List<Key> UsEnglishOrionKeys { get; set; }
}
}

View File

@ -0,0 +1,111 @@
namespace Artemis.KeyboardProviders.Logitech.Utilities
{
public enum KeyboardNames
{
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 = 0x45,
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 = 0x145,
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,
TEST = 0x1
};
}

View File

@ -0,0 +1,95 @@
using System.Runtime.InteropServices;
// ReSharper disable InconsistentNaming
namespace Artemis.KeyboardProviders.Logitech.Utilities
{
public class LogitechGSDK
{
//LED SDK
private const int LOGI_DEVICETYPE_MONOCHROME_ORD = 0;
private const int LOGI_DEVICETYPE_RGB_ORD = 1;
private const int LOGI_DEVICETYPE_PERKEY_RGB_ORD = 2;
public const int LOGI_DEVICETYPE_MONOCHROME = (1 << LOGI_DEVICETYPE_MONOCHROME_ORD);
public const int LOGI_DEVICETYPE_RGB = (1 << LOGI_DEVICETYPE_RGB_ORD);
public const int LOGI_DEVICETYPE_PERKEY_RGB = (1 << LOGI_DEVICETYPE_PERKEY_RGB_ORD);
public const int LOGI_LED_BITMAP_WIDTH = 21;
public const int LOGI_LED_BITMAP_HEIGHT = 6;
public const int LOGI_LED_BITMAP_BYTES_PER_KEY = 4;
public const int LOGI_LED_BITMAP_SIZE =
LOGI_LED_BITMAP_WIDTH*LOGI_LED_BITMAP_HEIGHT*LOGI_LED_BITMAP_BYTES_PER_KEY;
public const int LOGI_LED_DURATION_INFINITE = 0;
[DllImport("LogitechLedEnginesWrapper ", CallingConvention = CallingConvention.Cdecl)]
public static extern bool LogiLedInit();
[DllImport("LogitechLedEnginesWrapper ", CallingConvention = CallingConvention.Cdecl)]
public static extern bool LogiLedSetTargetDevice(int targetDevice);
[DllImport("LogitechLedEnginesWrapper ", CallingConvention = CallingConvention.Cdecl)]
public static extern bool LogiLedGetSdkVersion(ref int majorNum, ref int minorNum, ref int buildNum);
[DllImport("LogitechLedEnginesWrapper ", CallingConvention = CallingConvention.Cdecl)]
public static extern bool LogiLedSaveCurrentLighting();
[DllImport("LogitechLedEnginesWrapper ", CallingConvention = CallingConvention.Cdecl)]
public static extern bool LogiLedSetLighting(int redPercentage, int greenPercentage, int bluePercentage);
[DllImport("LogitechLedEnginesWrapper ", CallingConvention = CallingConvention.Cdecl)]
public static extern bool LogiLedRestoreLighting();
[DllImport("LogitechLedEnginesWrapper ", CallingConvention = CallingConvention.Cdecl)]
public static extern bool LogiLedFlashLighting(int redPercentage, int greenPercentage, int bluePercentage,
int milliSecondsDuration, int milliSecondsInterval);
[DllImport("LogitechLedEnginesWrapper ", CallingConvention = CallingConvention.Cdecl)]
public static extern bool LogiLedPulseLighting(int redPercentage, int greenPercentage, int bluePercentage,
int milliSecondsDuration, int milliSecondsInterval);
[DllImport("LogitechLedEnginesWrapper ", CallingConvention = CallingConvention.Cdecl)]
public static extern bool LogiLedStopEffects();
[DllImport("LogitechLedEnginesWrapper ", CallingConvention = CallingConvention.Cdecl)]
public static extern bool LogiLedSetLightingFromBitmap(byte[] bitmap);
[DllImport("LogitechLedEnginesWrapper ", CallingConvention = CallingConvention.Cdecl)]
public static extern bool LogiLedSetLightingForKeyWithScanCode(int keyCode, int redPercentage,
int greenPercentage, int bluePercentage);
[DllImport("LogitechLedEnginesWrapper ", CallingConvention = CallingConvention.Cdecl)]
public static extern bool LogiLedSetLightingForKeyWithHidCode(int keyCode, int redPercentage,
int greenPercentage, int bluePercentage);
[DllImport("LogitechLedEnginesWrapper ", CallingConvention = CallingConvention.Cdecl)]
public static extern bool LogiLedSetLightingForKeyWithQuartzCode(int keyCode, int redPercentage,
int greenPercentage, int bluePercentage);
[DllImport("LogitechLedEnginesWrapper ", CallingConvention = CallingConvention.Cdecl)]
public static extern bool LogiLedSetLightingForKeyWithKeyName(KeyboardNames keyCode, int redPercentage,
int greenPercentage, int bluePercentage);
[DllImport("LogitechLedEnginesWrapper ", CallingConvention = CallingConvention.Cdecl)]
public static extern bool LogiLedSaveLightingForKey(KeyboardNames keyName);
[DllImport("LogitechLedEnginesWrapper ", CallingConvention = CallingConvention.Cdecl)]
public static extern bool LogiLedRestoreLightingForKey(KeyboardNames keyName);
[DllImport("LogitechLedEnginesWrapper ", CallingConvention = CallingConvention.Cdecl)]
public static extern bool LogiLedFlashSingleKey(KeyboardNames keyName, int redPercentage, int greenPercentage,
int bluePercentage, int msDuration, int msInterval);
[DllImport("LogitechLedEnginesWrapper ", CallingConvention = CallingConvention.Cdecl)]
public static extern bool LogiLedPulseSingleKey(KeyboardNames keyName, int startRedPercentage,
int startGreenPercentage, int startBluePercentage, int finishRedPercentage, int finishGreenPercentage,
int finishBluePercentage, int msDuration, bool isInfinite);
[DllImport("LogitechLedEnginesWrapper ", CallingConvention = CallingConvention.Cdecl)]
public static extern bool LogiLedStopEffectsOnKey(KeyboardNames keyName);
[DllImport("LogitechLedEnginesWrapper ", CallingConvention = CallingConvention.Cdecl)]
public static extern void LogiLedShutdown();
}
}

View File

@ -0,0 +1,60 @@
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
namespace Artemis.KeyboardProviders.Logitech.Utilities
{
public static class OrionUtilities
{
public static byte[] BitmapToByteArray(Bitmap b)
{
if (b.Width > 21 || b.Height > 6)
b = ResizeImage(b, 21, 6);
var rect = new Rectangle(0, 0, b.Width, b.Height);
var bitmapData = b.LockBits(rect, ImageLockMode.ReadWrite, b.PixelFormat);
var depth = Image.GetPixelFormatSize(b.PixelFormat);
var step = depth/8;
var pixels = new byte[(21*6)*step];
var iptr = bitmapData.Scan0;
// Copy data from pointer to array
Marshal.Copy(iptr, pixels, 0, pixels.Length);
return pixels;
}
/// <summary>
/// Resize the image to the specified width and height.
/// </summary>
/// <param name="image">The image to resize.</param>
/// <param name="width">The width to resize to.</param>
/// <param name="height">The height to resize to.</param>
/// <returns>The resized image.</returns>
public static Bitmap ResizeImage(Image image, int width, int height)
{
var destRect = new Rectangle(0, 0, width, height);
var destImage = new Bitmap(width, height);
destImage.SetResolution(image.HorizontalResolution, image.VerticalResolution);
using (var graphics = Graphics.FromImage(destImage))
{
graphics.CompositingMode = CompositingMode.SourceCopy;
graphics.CompositingQuality = CompositingQuality.HighQuality;
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphics.SmoothingMode = SmoothingMode.HighQuality;
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
using (var wrapMode = new ImageAttributes())
{
wrapMode.SetWrapMode(WrapMode.TileFlipXY);
graphics.DrawImage(image, destRect, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, wrapMode);
}
}
return destImage;
}
}
}

View File

@ -0,0 +1,19 @@
using System.Collections.Generic;
using Artemis.KeyboardProviders.Corsair;
using Artemis.KeyboardProviders.Logitech;
namespace Artemis.KeyboardProviders
{
public static class ProviderHelper
{
public static List<KeyboardProvider> GetKeyboardProviders()
{
return new List<KeyboardProvider>
{
new Orion(),
new K70(),
new K95()
};
}
}
}

Binary file not shown.

View File

@ -0,0 +1,12 @@
<Window x:Class="Artemis.MainWindow"
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"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
</Grid>
</Window>

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
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
}
}

View File

@ -0,0 +1,20 @@
using System;
using System.Drawing;
namespace Artemis.Models
{
public abstract class EffectModel : IDisposable
{
public string Name;
public abstract void Dispose();
// Called on creation
public abstract void Enable();
// Called every iteration
public abstract void Update();
// Called after every update
public abstract Bitmap GenerateBitmap();
}
}

View File

@ -0,0 +1,20 @@
namespace Artemis.Models
{
public abstract class EffectSettings
{
/// <summary>
/// Loads the settings from the settings file
/// </summary>
public abstract void Load();
/// <summary>
/// Saves the settings to the settings file
/// </summary>
public abstract void Save();
/// <summary>
/// Returns the settings to their default value
/// </summary>
public abstract void ToDefault();
}
}

View File

@ -0,0 +1,8 @@
namespace Artemis.Models
{
public abstract class GameModel : EffectModel
{
public bool Enabled;
public string ProcessName;
}
}

View File

@ -0,0 +1,211 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using Artemis.Events;
using Artemis.KeyboardProviders;
using Artemis.Settings;
using Artemis.Utilities.GameSense;
using Artemis.Utilities.Memory;
using Caliburn.Micro;
namespace Artemis.Models
{
public class MainModel
{
private readonly BackgroundWorker _processWorker;
private readonly BackgroundWorker _updateWorker;
public MainModel(IEventAggregator events)
{
EffectModels = new List<EffectModel>();
KeyboardProviders = ProviderHelper.GetKeyboardProviders();
GameSenseWebServer = new GameSenseWebServer();
Events = events;
Fps = 25;
_updateWorker = new BackgroundWorker {WorkerSupportsCancellation = true};
_processWorker = new BackgroundWorker {WorkerSupportsCancellation = true};
_updateWorker.DoWork += UpdateWorker_DoWork;
_processWorker.DoWork += ProcessWorker_DoWork;
}
public EffectModel ActiveEffect { get; set; }
public List<EffectModel> EffectModels { get; set; }
public KeyboardProvider ActiveKeyboard { get; set; }
public List<KeyboardProvider> KeyboardProviders { get; set; }
public GameSenseWebServer GameSenseWebServer { get; set; }
public IEventAggregator Events { get; set; }
public int Fps { get; set; }
public bool Enabled { get; set; }
#region Effect methods
public void StartEffects()
{
LoadLastKeyboard();
// Start the webserver
GameSenseWebServer.Start();
// Load last non-game effect and enable
LoadLastEffect();
// Start the Background Workers
_updateWorker.RunWorkerAsync();
_processWorker.RunWorkerAsync();
}
public void ShutdownEffects()
{
// Stop the Background Worker
_updateWorker.CancelAsync();
_processWorker.CancelAsync();
// Dispose the current active effect
ActiveEffect?.Dispose();
ActiveEffect = null;
ActiveKeyboard?.Disable();
ActiveKeyboard = null;
}
private void LoadLastKeyboard()
{
var keyboard = KeyboardProviders.FirstOrDefault(k => k.Name == General.Default.LastKeyboard);
ChangeKeyboard(keyboard ?? KeyboardProviders.First(k => k.Name == "Logitech G910 Orion Spark RGB"));
}
private void ChangeKeyboard(KeyboardProvider keyboardProvider)
{
if (ActiveKeyboard != null && keyboardProvider.Name == ActiveKeyboard.Name)
return;
ActiveKeyboard?.Disable();
ActiveKeyboard = keyboardProvider;
ActiveKeyboard.Enable();
General.Default.LastKeyboard = ActiveKeyboard.Name;
General.Default.Save();
}
private void LoadLastEffect()
{
var effect = EffectModels.FirstOrDefault(e => e.Name == General.Default.LastEffect);
ChangeEffect(effect ?? EffectModels.First(e => e.Name == "TypeWave"));
}
private void ChangeEffect(EffectModel effectModel)
{
if (effectModel is OverlayModel)
throw new ArgumentException("Can't set an Overlay effect as the active effect");
if (ActiveEffect != null && effectModel.Name == ActiveEffect.Name)
return;
ActiveEffect?.Dispose();
ActiveEffect = effectModel;
ActiveEffect.Enable();
if (ActiveEffect is GameModel) return;
// Non-game effects are stored as the new LastEffect.
General.Default.LastEffect = ActiveEffect.Name;
General.Default.Save();
// Let the ViewModels know
Events.PublishOnUIThread(new ChangeActiveEffect(ActiveEffect.Name));
}
public void EnableEffect(EffectModel effectModel)
{
if (effectModel is GameModel || effectModel is OverlayModel)
return;
ChangeEffect(effectModel);
}
public bool IsEnabled(EffectModel effectModel)
{
if (effectModel is GameModel)
return false;
return General.Default.LastEffect == effectModel.Name;
}
#endregion Effect methods
#region Workers
private void UpdateWorker_DoWork(object sender, DoWorkEventArgs e)
{
var sw = new Stopwatch();
while (!_updateWorker.CancellationPending)
{
sw.Start();
// Update the current effect
ActiveEffect.Update();
// Get ActiveEffect's bitmap
var bitmap = ActiveEffect.GenerateBitmap();
// Draw enabled overlays on top
foreach (
var overlayModel in EffectModels.OfType<OverlayModel>().Where(overlayModel => overlayModel.Enabled))
{
overlayModel.Update();
bitmap = bitmap != null ? overlayModel.GenerateBitmap(bitmap) : overlayModel.GenerateBitmap();
}
// If it exists, send bitmap to the device
if (bitmap != null && ActiveKeyboard != null)
{
ActiveKeyboard.DrawBitmap(bitmap);
// debugging
Events.PublishOnUIThread(new ChangeBitmap(bitmap));
}
// Sleep according to time left this frame
var sleep = (int) ((1000/Fps) - sw.ElapsedMilliseconds);
if (sleep > 0)
Thread.Sleep(sleep);
sw.Reset();
}
}
private void ProcessWorker_DoWork(object sender, DoWorkEventArgs e)
{
while (!_processWorker.CancellationPending)
{
var foundProcess = false;
// ReSharper disable once LoopCanBePartlyConvertedToQuery
foreach (var effectModel in EffectModels.OfType<GameModel>())
{
var process = MemoryHelpers.GetProcessIfRunning(effectModel.ProcessName);
if (process == null)
continue;
ChangeEffect(effectModel);
foundProcess = true;
}
// If no game process is found, but the active effect still belongs to a game,
// set it to a normal effect
if (!foundProcess && ActiveEffect is GameModel)
LoadLastEffect();
Thread.Sleep(1000);
}
}
#endregion
}
}

View File

@ -0,0 +1,41 @@
using System.Drawing;
namespace Artemis.Models
{
public abstract class OverlayModel : EffectModel
{
private bool _enabled;
public string ProcessName;
public bool Enabled
{
get { return _enabled; }
set
{
if (_enabled == value)
return;
if (value)
Enable();
else
Dispose();
_enabled = value;
}
}
public void SetEnabled(bool enabled)
{
if (Enabled == enabled)
return;
if (enabled)
Enable();
else
Dispose();
Enabled = enabled;
}
public abstract Bitmap GenerateBitmap(Bitmap bitmap);
}
}

View File

@ -0,0 +1,195 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using Artemis.Models;
using Artemis.Utilities;
using Artemis.Utilities.Audio;
using Artemis.Utilities.Keyboard;
using NAudio.CoreAudioApi;
using NAudio.Wave;
namespace Artemis.Modules.Effects.AudioVisualizer
{
public class AudioVisualizerModel : EffectModel
{
private const int FftLength = 2048;
private readonly SampleAggregator _sampleAggregator = new SampleAggregator(FftLength);
private bool _generating;
private IWaveIn _waveIn;
public AudioVisualizerModel(AudioVisualizerSettings settings)
{
Settings = settings;
Name = "Audiovisualizer";
DeviceIds = new List<string>();
SpectrumData = new List<byte>();
SoundRectangles = new List<KeyboardRectangle>();
Scale = 4;
Lines = 21*Scale;
// Fill list with device IDs
// Would rather just store a MMDevice object, but seems NAudio won't let me.
var deviceEnum = new MMDeviceEnumerator();
var devices = deviceEnum.EnumerateAudioEndPoints(DataFlow.All, DeviceState.Active).ToList();
foreach (var mmDevice in devices)
{
DeviceIds.Add(mmDevice.ID);
}
SelectedDeviceId = DeviceIds.FirstOrDefault();
}
public int Lines { get; set; }
public int Scale { get; set; }
public AudioVisualizerSettings Settings { get; set; }
public List<byte> SpectrumData { get; set; }
public List<KeyboardRectangle> SoundRectangles { get; set; }
public List<string> DeviceIds { get; set; }
public string SelectedDeviceId { get; set; }
public override void Dispose()
{
_sampleAggregator.PerformFFT = false;
_sampleAggregator.FftCalculated -= FftCalculated;
_waveIn.StopRecording();
_waveIn.DataAvailable -= OnDataAvailable;
_waveIn = null;
}
public override void Enable()
{
_sampleAggregator.FftCalculated += FftCalculated;
_sampleAggregator.PerformFFT = true;
_waveIn = new WasapiLoopbackCapture();
_waveIn.DataAvailable += OnDataAvailable;
_waveIn.StartRecording();
}
public override void Update()
{
if (SelectedDeviceId == null)
return;
var deviceEnum = new MMDeviceEnumerator();
var devices = deviceEnum.EnumerateAudioEndPoints(DataFlow.All, DeviceState.Active).ToList();
var device = devices.FirstOrDefault(d => d.ID == SelectedDeviceId);
if (device == null)
return;
// Start filling the model
_generating = true;
if (SpectrumData == null)
{
_generating = false;
return;
}
// Clear the rectangle cache on Bars settings change
if (SoundRectangles.Count != Settings.Bars)
SoundRectangles.Clear();
// Parse spectrum data
for (var i = 0; i < Settings.Bars; i++)
{
int height;
if (SpectrumData.Count - 1 < i || SpectrumData[i] == 0)
height = 0;
else
height = (int) (Math.Round(SpectrumData[i]/2.55));
if (SoundRectangles.Count <= i)
SoundRectangles.Add(new KeyboardRectangle(Scale, 0, 0, 21, 6,
new List<Color>
{
ColorHelpers.MediaColorToDrawingColor(Settings.MainColor),
ColorHelpers.MediaColorToDrawingColor(Settings.SecondaryColor)
}, LinearGradientMode.Vertical));
// Apply Sensitivity setting
height = height*Settings.Sensitivity;
if (height > SoundRectangles[i].Height)
SoundRectangles[i].Height = height;
else
SoundRectangles[i].Height = SoundRectangles[i].Height - Settings.FadeSpeed;
// Apply Bars setting
SoundRectangles[i].X = (int) Math.Ceiling((double) Lines/Settings.Bars)*i;
SoundRectangles[i].Width = (int) Math.Ceiling((double) Lines/Settings.Bars);
}
_generating = false;
}
public override Bitmap GenerateBitmap()
{
// Lock the _spectrumData array while busy with it
_generating = true;
if (SpectrumData == null)
{
_generating = false;
return null;
}
var bitmap = new Bitmap(21*Scale, 6*Scale);
using (var g = Graphics.FromImage(bitmap))
{
foreach (var soundRectangle in SoundRectangles)
soundRectangle.Draw(g);
}
_generating = false;
return bitmap;
}
private void OnDataAvailable(object sender, WaveInEventArgs e)
{
var buffer = e.Buffer;
var bytesRecorded = e.BytesRecorded;
var bufferIncrement = _waveIn.WaveFormat.BlockAlign;
for (var index = 0; index < bytesRecorded; index += bufferIncrement)
{
var sample32 = BitConverter.ToSingle(buffer, index);
_sampleAggregator.Add(sample32);
}
}
private void FftCalculated(object sender, FftEventArgs e)
{
if (_generating)
return;
int x;
var b0 = 0;
SpectrumData.Clear();
for (x = 0; x < Lines; x++)
{
float peak = 0;
var b1 = (int) Math.Pow(2, x*10.0/(Lines - 1));
if (b1 > 2047)
b1 = 2047;
if (b1 <= b0)
b1 = b0 + 1;
for (; b0 < b1; b0++)
{
if (peak < e.Result[1 + b0].X)
peak = e.Result[1 + b0].X;
}
var y = (int) (Math.Sqrt(peak)*3*255 - 4);
if (y > 255)
y = 255;
if (y < 0)
y = 0;
SpectrumData.Add((byte) y);
}
}
}
}

View File

@ -0,0 +1,53 @@
using System.Windows.Media;
using Artemis.Models;
using Artemis.Settings;
namespace Artemis.Modules.Effects.AudioVisualizer
{
public class AudioVisualizerSettings : EffectSettings
{
public AudioVisualizerSettings()
{
Load();
}
public int Sensitivity { get; set; }
public int Bars { get; set; }
public int Spread { get; set; }
public int FadeSpeed { get; set; }
public Color MainColor { get; set; }
public Color SecondaryColor { get; set; }
public override sealed void Load()
{
Sensitivity = AudioVisualization.Default.Sensitivity;
Bars = AudioVisualization.Default.Bars;
Spread = AudioVisualization.Default.Spread;
FadeSpeed = AudioVisualization.Default.FadeSpeed;
MainColor = AudioVisualization.Default.MainColor;
SecondaryColor = AudioVisualization.Default.SecondaryColor;
}
public override sealed void Save()
{
AudioVisualization.Default.Sensitivity = Sensitivity;
AudioVisualization.Default.Bars = Bars;
AudioVisualization.Default.Spread = Spread;
AudioVisualization.Default.FadeSpeed = FadeSpeed;
AudioVisualization.Default.MainColor = MainColor;
AudioVisualization.Default.SecondaryColor = SecondaryColor;
AudioVisualization.Default.Save();
}
public override sealed void ToDefault()
{
Sensitivity = 4;
Bars = 21;
Spread = 1;
FadeSpeed = 3;
MainColor = Color.FromArgb(255, 0, 0, 255);
SecondaryColor = Color.FromArgb(255, 30, 144, 255);
}
}
}

View File

@ -0,0 +1,128 @@
<UserControl x:Class="Artemis.Modules.Effects.AudioVisualizer.AudioVisualizerView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:cal="http://www.caliburnproject.org"
xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls"
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
mc:Ignorable="d"
d:DesignHeight="407.812" d:DesignWidth="671.484"
d:DataContext="{d:DesignInstance Type=effects:AudioVisualizerViewModel, IsDesignTimeCreatable=True}"
cal:Bind.AtDesignTime="True">
<Grid Margin="15, 5, 15, 5">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2">
<Label FontSize="20"
Style="{DynamicResource DescriptionHeaderStyle}" HorizontalAlignment="Left">
<Label.Content>
<AccessText TextWrapping="Wrap" Text="Visualizes the selected audio device on the keyboard." />
</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=EffectEnabled, Mode=OneWay}"
Style="{DynamicResource MetroCircleToggleButtonStyle}"
cal:Message.Attach="[Event Click] = [Action ToggleEffect]" />
</StackPanel>
</StackPanel>
<StackPanel Grid.Row="1"
Grid.Column="0"
HorizontalAlignment="Left">
<Label FontSize="16" Content="Main color" Style="{DynamicResource DescriptionHeaderStyle}"
FontFamily="Segoe UI Semibold" Foreground="#535353" Width="130" />
<xctk:ColorPicker x:Name="MainColor"
SelectedColor="{Binding Path=AudioVisualizerSettings.MainColor, Mode=TwoWay}" />
</StackPanel>
<StackPanel Grid.Row="1"
Grid.Column="1"
HorizontalAlignment="Left">
<Label FontSize="16" Content="Secondary color" Style="{DynamicResource DescriptionHeaderStyle}"
FontFamily="Segoe UI Semibold" Foreground="#535353" Width="130" />
<xctk:ColorPicker x:Name="SecondaryColor"
SelectedColor="{Binding Path=AudioVisualizerSettings.SecondaryColor, Mode=TwoWay}" />
</StackPanel>
<!-- Sensitivity slider -->
<StackPanel Grid.Row="2"
Grid.Column="0"
HorizontalAlignment="Left">
<Label FontSize="16" Content="Sensitivity" Style="{DynamicResource DescriptionHeaderStyle}"
Foreground="#535353" FontFamily="Segoe UI Semibold" />
<Slider x:Name="Sensitivity"
VerticalAlignment="top"
HorizontalAlignment="Left"
Width="132"
TickPlacement="BottomRight"
TickFrequency="1"
Value="{Binding Path=AudioVisualizerSettings.Sensitivity, Mode=TwoWay}" Minimum="1" Maximum="10"
SmallChange="1"
IsSnapToTickEnabled="True" />
</StackPanel>
<!-- Bars slider -->
<StackPanel Grid.Row="2"
Grid.Column="1"
HorizontalAlignment="Left">
<Label FontSize="16" Content="Bars" Style="{DynamicResource DescriptionHeaderStyle}"
Foreground="#535353" FontFamily="Segoe UI Semibold" />
<Slider x:Name="Bars"
VerticalAlignment="top"
HorizontalAlignment="Left"
Width="132"
TickPlacement="BottomRight"
TickFrequency="7"
Value="{Binding Path=AudioVisualizerSettings.Bars, Mode=TwoWay}" Minimum="7" Maximum="21"
SmallChange="7"
IsSnapToTickEnabled="True" />
</StackPanel>
<!-- Spread slider -->
<StackPanel Grid.Row="3"
Grid.Column="0"
HorizontalAlignment="Left">
<Label FontSize="16" Content="Spread" Style="{DynamicResource DescriptionHeaderStyle}"
Foreground="#535353" FontFamily="Segoe UI Semibold" />
<Slider x:Name="Spread"
VerticalAlignment="top"
HorizontalAlignment="Left"
Width="132"
TickPlacement="BottomRight"
TickFrequency="1"
Value="{Binding Path=AudioVisualizerSettings.Spread, Mode=TwoWay}" Minimum="0" Maximum="4"
SmallChange="1"
IsSnapToTickEnabled="True" />
</StackPanel>
<!-- Fadeout slider -->
<StackPanel Grid.Row="3"
Grid.Column="1"
HorizontalAlignment="Left">
<Label FontSize="16" Content="Fade speed" Style="{DynamicResource DescriptionHeaderStyle}"
Foreground="#535353" FontFamily="Segoe UI Semibold" />
<Slider x:Name="FadeSpeed"
VerticalAlignment="top"
HorizontalAlignment="Left"
Width="132"
TickPlacement="BottomRight"
TickFrequency="1"
Value="{Binding Path=AudioVisualizerSettings.FadeSpeed, Mode=TwoWay}" Minimum="1" Maximum="10"
SmallChange="1"
IsSnapToTickEnabled="True" />
</StackPanel>
<!-- 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>
</UserControl>

View File

@ -0,0 +1,15 @@
using System.Windows.Controls;
namespace Artemis.Modules.Effects.AudioVisualizer
{
/// <summary>
/// Interaction logic for AudioVisualizerView.xaml
/// </summary>
public partial class AudioVisualizerView : UserControl
{
public AudioVisualizerView()
{
InitializeComponent();
}
}
}

View File

@ -0,0 +1,70 @@
using Artemis.Events;
using Artemis.Models;
using Caliburn.Micro;
namespace Artemis.Modules.Effects.AudioVisualizer
{
public class AudioVisualizerViewModel : Screen, IHandle<ChangeActiveEffect>
{
private AudioVisualizerSettings _audioVisualizerSettings;
public AudioVisualizerViewModel(MainModel mainModel)
{
// Subscribe to main model
MainModel = mainModel;
MainModel.Events.Subscribe(this);
// Settings are loaded from file by class
AudioVisualizerSettings = new AudioVisualizerSettings();
// Create effect model and add it to MainModel
AudioVisualizerModel = new AudioVisualizerModel(AudioVisualizerSettings);
MainModel.EffectModels.Add(AudioVisualizerModel);
}
public MainModel MainModel { get; set; }
public AudioVisualizerModel AudioVisualizerModel { get; set; }
public static string Name => "Audio Visualizer";
public bool EffectEnabled => MainModel.IsEnabled(AudioVisualizerModel);
public AudioVisualizerSettings AudioVisualizerSettings
{
get { return _audioVisualizerSettings; }
set
{
if (Equals(value, _audioVisualizerSettings)) return;
_audioVisualizerSettings = value;
NotifyOfPropertyChange(() => AudioVisualizerSettings);
}
}
public void Handle(ChangeActiveEffect message)
{
NotifyOfPropertyChange(() => EffectEnabled);
}
public void ToggleEffect()
{
MainModel.EnableEffect(AudioVisualizerModel);
NotifyOfPropertyChange(() => EffectEnabled);
}
public void SaveSettings()
{
if (AudioVisualizerModel == null)
return;
AudioVisualizerSettings.Save();
}
public void ResetSettings()
{
// TODO: Confirmation dialog (Generic MVVM approach)
AudioVisualizerSettings.ToDefault();
NotifyOfPropertyChange(() => AudioVisualizerSettings);
SaveSettings();
}
}
}

View File

@ -0,0 +1,30 @@
using System.Drawing;
using Artemis.Models;
namespace Artemis.Modules.Effects.TypeHole
{
public class TypeHoleModel : EffectModel
{
public TypeHoleModel()
{
Name = "TypeHole";
}
public override void Dispose()
{
}
public override void Enable()
{
}
public override void Update()
{
}
public override Bitmap GenerateBitmap()
{
return null;
}
}
}

View File

@ -0,0 +1,40 @@
<UserControl x:Class="Artemis.Modules.Effects.TypeHole.TypeHoleView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:cal="http://www.caliburnproject.org"
xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls"
mc:Ignorable="d"
d:DesignHeight="407.812" d:DesignWidth="671.484"
d:DataContext="{d:DesignInstance Type=effects:TypeHoleViewModel, IsDesignTimeCreatable=True}"
cal:Bind.AtDesignTime="True">
<Grid Margin="15, 5, 15, 5">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2">
<Label FontSize="20"
Style="{DynamicResource DescriptionHeaderStyle}" HorizontalAlignment="Left">
<Label.Content>
<AccessText TextWrapping="Wrap" Text="Creates holes in the keyboard's lightning as you press keys." />
</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=EffectEnabled, Mode=OneWay}"
Style="{DynamicResource MetroCircleToggleButtonStyle}"
cal:Message.Attach="[Event Click] = [Action ToggleEffect]" />
</StackPanel>
</StackPanel>
</Grid>
</UserControl>

View File

@ -0,0 +1,15 @@
using System.Windows.Controls;
namespace Artemis.Modules.Effects.TypeHole
{
/// <summary>
/// Interaction logic for TypeHoleView.xaml
/// </summary>
public partial class TypeHoleView : UserControl
{
public TypeHoleView()
{
InitializeComponent();
}
}
}

View File

@ -0,0 +1,36 @@
using Artemis.Events;
using Artemis.Models;
using Caliburn.Micro;
namespace Artemis.Modules.Effects.TypeHole
{
public class TypeHoleViewModel : Screen, IHandle<ChangeActiveEffect>
{
public TypeHoleViewModel(MainModel mainModel)
{
// Subscribe to main model
MainModel = mainModel;
MainModel.Events.Subscribe(this);
// Create effect model and add it to MainModel
TypeHoleModel = new TypeHoleModel();
MainModel.EffectModels.Add(TypeHoleModel);
}
public MainModel MainModel { get; set; }
public TypeHoleModel TypeHoleModel { get; set; }
public static string Name => "Type Holes (NYI)";
public bool EffectEnabled => MainModel.IsEnabled(TypeHoleModel);
public void Handle(ChangeActiveEffect message)
{
NotifyOfPropertyChange(() => EffectEnabled);
}
public void ToggleEffect()
{
MainModel.EnableEffect(TypeHoleModel);
}
}
}

View File

@ -0,0 +1,137 @@
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using Artemis.KeyboardProviders.Logitech.Utilities;
using Artemis.Models;
using Artemis.Utilities;
using Open.WinKeyboardHook;
namespace Artemis.Modules.Effects.TypeWave
{
public class TypeWaveModel : EffectModel
{
public TypeWaveModel(TypeWaveSettings settings)
{
Name = "TypeWave";
Waves = new List<Wave>();
Settings = settings;
// KeyboardIntercepter won't start untill the effect is active
KeyboardInterceptor = new KeyboardInterceptor();
}
public TypeWaveSettings Settings { get; set; }
public List<Wave> Waves { get; set; }
public KeyboardInterceptor KeyboardInterceptor { get; set; }
public override void Dispose()
{
KeyboardInterceptor.KeyUp -= HandleKeypress;
KeyboardInterceptor.StopCapturing();
}
public override void Enable()
{
KeyboardInterceptor.StartCapturing();
KeyboardInterceptor.KeyUp += HandleKeypress;
}
public override void Update()
{
for (var i = 0; i < Waves.Count; i++)
{
// TODO: Get from settings
var fps = 25;
Waves[i].Size += Settings.SpreadSpeed;
if (Settings.IsShiftColors)
Waves[i].Color = ColorHelpers.ShiftColor(Waves[i].Color, Settings.ShiftColorSpeed);
var decreaseAmount = 255/(Settings.TimeToLive/fps);
Waves[i].Color = Color.FromArgb(Waves[i].Color.A - decreaseAmount, Waves[i].Color.R, Waves[i].Color.G,
Waves[i].Color.B);
if (Waves[i].Color.A >= decreaseAmount)
continue;
Waves.RemoveAt(i);
i--;
}
}
public override Bitmap GenerateBitmap()
{
if (Waves.Count == 0)
return null;
var bitmap = new Bitmap(21, 6);
using (var g = Graphics.FromImage(bitmap))
{
// TODO: Might implement a user-defined background color, but looks ugly most of the time
//g.Clear(Color.FromArgb(100, 255, 0, 255));
g.Clear(Color.Transparent);
g.SmoothingMode = SmoothingMode.HighQuality;
// Don't want a foreach, collection is changed in different thread
// ReSharper disable once ForCanBeConvertedToForeach
for (var i = 0; i < Waves.Count; i++)
{
if (Waves[i].Size == 0)
continue;
var path = new GraphicsPath();
path.AddEllipse(Waves[i].Point.X - Waves[i].Size/2, Waves[i].Point.Y - Waves[i].Size/2,
Waves[i].Size, Waves[i].Size);
var pthGrBrush = new PathGradientBrush(path)
{
SurroundColors = new[] {Waves[i].Color},
CenterColor = Color.Transparent
};
g.FillPath(pthGrBrush, path);
pthGrBrush.FocusScales = new PointF(0.3f, 0.8f);
g.FillPath(pthGrBrush, path);
g.DrawEllipse(new Pen(pthGrBrush, 1), Waves[i].Point.X - Waves[i].Size/2,
Waves[i].Point.Y - Waves[i].Size/2, Waves[i].Size, Waves[i].Size);
}
}
return bitmap;
}
private void HandleKeypress(object sender, KeyEventArgs e)
{
Task.Factory.StartNew(() => KeyPressTask(e));
}
private void KeyPressTask(KeyEventArgs e)
{
var keyMatch = KeyMap.UsEnglishOrionKeys.FirstOrDefault(k => k.KeyCode == e.KeyCode);
if (keyMatch == null)
return;
Waves.Add(Settings.IsRandomColors
? new Wave(new Point(keyMatch.PosX, keyMatch.PosY), 0, ColorHelpers.GetRandomRainbowColor())
: new Wave(new Point(keyMatch.PosX, keyMatch.PosY), 0,
ColorHelpers.MediaColorToDrawingColor(Settings.WaveColor)));
}
}
public class Wave
{
public Wave(Point point, int size, Color color)
{
Point = point;
Size = size;
Color = color;
}
public Point Point { get; set; }
public int Size { get; set; }
public Color Color { get; set; }
}
}

View File

@ -0,0 +1,52 @@
using System.Windows.Media;
using Artemis.Models;
namespace Artemis.Modules.Effects.TypeWave
{
public class TypeWaveSettings : EffectSettings
{
public TypeWaveSettings()
{
Load();
}
public bool IsRandomColors { get; set; }
public Color WaveColor { get; set; }
public bool IsShiftColors { get; set; }
public int ShiftColorSpeed { get; set; }
public int TimeToLive { get; set; }
public int SpreadSpeed { get; set; }
public override sealed void Load()
{
IsRandomColors = Settings.TypeWave.Default.IsRandomColors;
WaveColor = Settings.TypeWave.Default.WaveColor;
IsShiftColors = Settings.TypeWave.Default.IsShiftColors;
ShiftColorSpeed = Settings.TypeWave.Default.ShiftColorSpeed;
TimeToLive = Settings.TypeWave.Default.TimeToLive;
SpreadSpeed = Settings.TypeWave.Default.SpreadSpeed;
}
public override sealed void Save()
{
Settings.TypeWave.Default.IsRandomColors = IsRandomColors;
Settings.TypeWave.Default.WaveColor = WaveColor;
Settings.TypeWave.Default.IsShiftColors = IsShiftColors;
Settings.TypeWave.Default.ShiftColorSpeed = ShiftColorSpeed;
Settings.TypeWave.Default.TimeToLive = TimeToLive;
Settings.TypeWave.Default.SpreadSpeed = SpreadSpeed;
Settings.TypeWave.Default.Save();
}
public override sealed void ToDefault()
{
IsRandomColors = true;
WaveColor = Color.FromArgb(255, 255, 0, 0);
IsShiftColors = true;
ShiftColorSpeed = 20;
TimeToLive = 500;
SpreadSpeed = 4;
}
}
}

View File

@ -0,0 +1,118 @@
<UserControl x:Class="Artemis.Modules.Effects.TypeWave.TypeWaveView"
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:controls="http://metro.mahapps.com/winfx/xaml/controls"
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
xmlns:cal="http://www.caliburnproject.org"
xmlns:typeWave="clr-namespace:Artemis.Modules.Effects.TypeWave"
mc:Ignorable="d"
d:DesignHeight="407.812" d:DesignWidth="671.484"
d:DataContext="{d:DesignInstance Type=typeWave:TypeWaveViewModel, IsDesignTimeCreatable=True}"
cal:Bind.AtDesignTime="True">
<Grid Margin="15, 5, 15, 5">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2">
<Label FontSize="20"
Style="{DynamicResource DescriptionHeaderStyle}" HorizontalAlignment="Left">
<Label.Content>
<AccessText TextWrapping="Wrap" Text="Creates waves on the keyboard as you press keys." />
</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=EffectEnabled, Mode=OneWay}"
Style="{DynamicResource MetroCircleToggleButtonStyle}"
cal:Message.Attach="[Event Click] = [Action ToggleEffect]" />
</StackPanel>
</StackPanel>
<StackPanel Grid.Row="1"
Grid.Column="0"
HorizontalAlignment="Left">
<controls:ToggleSwitch IsChecked="{Binding Path=TypeWaveSettings.IsRandomColors, Mode=TwoWay}"
Header="Random colors" OnLabel="Yes" OffLabel="No"
Margin="0 3 0 0" Width="125" />
</StackPanel>
<StackPanel Grid.Row="2"
Grid.Column="0"
HorizontalAlignment="Left">
<controls:ToggleSwitch IsChecked="{Binding Path=TypeWaveSettings.IsShiftColors, Mode=TwoWay}"
Header="Shift colors"
OnLabel="Yes" OffLabel="No"
Margin="0 3 0 0" Width="125" />
</StackPanel>
<!-- TTL slider -->
<StackPanel Grid.Row="3"
Grid.Column="0"
HorizontalAlignment="Left">
<Label FontSize="16" Content="Time to live" Style="{DynamicResource DescriptionHeaderStyle}"
FontFamily="Segoe UI Semibold" Foreground="#535353" />
<Slider VerticalAlignment="top"
HorizontalAlignment="Left"
Width="132"
TickPlacement="BottomRight"
TickFrequency="100"
x:Name="TypeWaveSettings_TimeToLive"
Value="{Binding Path=TypeWaveSettings.TimeToLive, Mode=TwoWay}" Minimum="100" Maximum="2000"
SmallChange="45"
IsSnapToTickEnabled="True" />
</StackPanel>
<StackPanel Grid.Row="1"
Grid.Column="1"
HorizontalAlignment="Left">
<Label FontSize="16" Content="Wave color" Style="{DynamicResource DescriptionHeaderStyle}"
FontFamily="Segoe UI Semibold" Foreground="#535353" Width="125" />
<xctk:ColorPicker x:Name="WaveColor" SelectedColor="{Binding Path=TypeWaveSettings.WaveColor, Mode=TwoWay}" />
</StackPanel>
<!-- Shift speed slider -->
<StackPanel Grid.Row="2"
Grid.Column="1"
HorizontalAlignment="Left">
<Label FontSize="16" Content="Color shift speed" Style="{DynamicResource DescriptionHeaderStyle}"
Foreground="#535353" FontFamily="Segoe UI Semibold" />
<Slider x:Name="ColorShiftSpeed"
VerticalAlignment="top"
HorizontalAlignment="Left"
Width="132"
TickPlacement="BottomRight"
TickFrequency="10"
Value="{Binding Path=TypeWaveSettings.ShiftColorSpeed, Mode=TwoWay}" Minimum="1" Maximum="200"
SmallChange="5"
IsSnapToTickEnabled="True" />
</StackPanel>
<!-- Spread Speed slider -->
<StackPanel Grid.Row="3"
Grid.Column="1"
HorizontalAlignment="Left">
<Label FontSize="16" Content="Spread speed" Style="{DynamicResource DescriptionHeaderStyle}"
Foreground="#535353" FontFamily="Segoe UI Semibold" />
<Slider x:Name="SpreadSpeed"
VerticalAlignment="top"
HorizontalAlignment="Left"
Width="132"
TickPlacement="BottomRight"
TickFrequency="1"
Value="{Binding Path=TypeWaveSettings.SpreadSpeed, Mode=TwoWay}" Minimum="1" Maximum="6"
SmallChange="1"
IsSnapToTickEnabled="True" />
</StackPanel>
<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>
</UserControl>

View File

@ -0,0 +1,15 @@
using System.Windows.Controls;
namespace Artemis.Modules.Effects.TypeWave
{
/// <summary>
/// Interaction logic for TypeWaveView.xaml
/// </summary>
public partial class TypeWaveView : UserControl
{
public TypeWaveView()
{
InitializeComponent();
}
}
}

View File

@ -0,0 +1,70 @@
using Artemis.Events;
using Artemis.Models;
using Caliburn.Micro;
namespace Artemis.Modules.Effects.TypeWave
{
public class TypeWaveViewModel : Screen, IHandle<ChangeActiveEffect>
{
private TypeWaveSettings _typeWaveSettings;
public TypeWaveViewModel(MainModel mainModel)
{
// Subscribe to main model
MainModel = mainModel;
MainModel.Events.Subscribe(this);
// Settings are loaded from file by class
TypeWaveSettings = new TypeWaveSettings();
// Create effect model and add it to MainModel
TypeWaveModel = new TypeWaveModel(TypeWaveSettings);
MainModel.EffectModels.Add(TypeWaveModel);
}
public MainModel MainModel { get; set; }
public TypeWaveModel TypeWaveModel { get; set; }
public static string Name => "Type Waves";
public bool EffectEnabled => MainModel.IsEnabled(TypeWaveModel);
public TypeWaveSettings TypeWaveSettings
{
get { return _typeWaveSettings; }
set
{
if (Equals(value, _typeWaveSettings)) return;
_typeWaveSettings = value;
NotifyOfPropertyChange(() => TypeWaveSettings);
}
}
public void Handle(ChangeActiveEffect message)
{
NotifyOfPropertyChange(() => EffectEnabled);
}
public void ToggleEffect()
{
MainModel.EnableEffect(TypeWaveModel);
NotifyOfPropertyChange(() => EffectEnabled);
}
public void SaveSettings()
{
if (TypeWaveModel == null)
return;
TypeWaveSettings.Save();
}
public void ResetSettings()
{
// TODO: Confirmation dialog (Generic MVVM approach)
TypeWaveSettings.ToDefault();
NotifyOfPropertyChange(() => TypeWaveSettings);
SaveSettings();
}
}
}

View File

@ -0,0 +1,89 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using Artemis.Models;
using Artemis.Utilities.GameSense;
using Artemis.Utilities.GameSense.JsonModels;
using Artemis.Utilities.Keyboard;
using Newtonsoft.Json;
namespace Artemis.Modules.Games.CounterStrike
{
public class CounterStrikeModel : GameModel
{
private readonly MainModel _mainModel;
// TODO: Make functional (CS' new gamestate intergration broke this)
public CounterStrikeModel(MainModel mainModel)
{
_mainModel = mainModel;
Name = "CounterStrike";
ProcessName = "csgo";
Scale = 4;
AmmoRect = new KeyboardRectangle(Scale, 0, 0, 84, 24, new List<Color> {Color.Blue, Color.Red},
LinearGradientMode.Horizontal);
}
public int Scale { get; set; }
public CounterStrikeJson CsJson { get; set; }
public KeyboardRectangle AmmoRect { get; set; }
public override void Dispose()
{
_mainModel.GameSenseWebServer.GameDataReceived -= HandleGameData;
}
public override void Enable()
{
_mainModel.GameSenseWebServer.GameDataReceived += HandleGameData;
}
public override void Update()
{
if (CsJson?.player.weapons == null)
return;
var activeWeapon = CsJson.player.weapons.FirstOrDefault(w => w.Value.state.Equals("active"));
// Update the ammo display
var ammoPercentage = 0;
if (activeWeapon.Value?.ammo_clip_max > 0)
ammoPercentage =
(int) ((Math.Ceiling(100.00/activeWeapon.Value.ammo_clip_max))*activeWeapon.Value.ammo_clip);
AmmoRect.Height = ammoPercentage;
if (ammoPercentage < 30)
AmmoRect.StartBlink(1000);
else
AmmoRect.StopBlink();
}
public override Bitmap GenerateBitmap()
{
var bitmap = new Bitmap(21, 6);
using (var g = Graphics.FromImage(bitmap))
{
g.Clear(Color.Transparent);
AmmoRect.Draw(g);
}
return bitmap;
}
public void HandleGameData(object sender, GameDataReceivedEventArgs e)
{
var jsonString = e.Json.ToString();
// Ensure it's CS:GO JSON
if (!jsonString.Contains("Counter-Strike: Global Offensive"))
return;
// Parse the JSON
CsJson = JsonConvert.DeserializeObject<CounterStrikeJson>(jsonString);
}
}
}

View File

@ -0,0 +1,11 @@
<UserControl x:Class="Artemis.Modules.Games.CounterStrike.CounterStrikeView"
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"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<TextBlock Text="{Binding Content}" />
</Grid>
</UserControl>

View File

@ -0,0 +1,15 @@
using System.Windows.Controls;
namespace Artemis.Modules.Games.CounterStrike
{
/// <summary>
/// Interaction logic for CounterStrikeView.xaml
/// </summary>
public partial class CounterStrikeView : UserControl
{
public CounterStrikeView()
{
InitializeComponent();
}
}
}

View File

@ -0,0 +1,27 @@
using Artemis.Models;
using Caliburn.Micro;
namespace Artemis.Modules.Games.CounterStrike
{
public class CounterStrikeViewModel : Screen
{
public CounterStrikeViewModel(MainModel mainModel)
{
MainModel = mainModel;
// Settings are loaded from file by class
//CounterStrikeSettings = new CounterStrikeSettings();
// Create effect model and add it to MainModel
CounterStrikeModel = new CounterStrikeModel(MainModel);
MainModel.EffectModels.Add(CounterStrikeModel);
}
public CounterStrikeModel CounterStrikeModel { get; set; }
public MainModel MainModel { get; set; }
public static string Name => "CS:GO (NYI)";
public string Content => "Counter-Strike: GO Content";
}
}

View File

@ -0,0 +1,11 @@
<UserControl x:Class="Artemis.Modules.Games.Dota2.Dota2View"
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"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<TextBlock Text="{Binding Content}" />
</Grid>
</UserControl>

View File

@ -0,0 +1,15 @@
using System.Windows.Controls;
namespace Artemis.Modules.Games.Dota2
{
/// <summary>
/// Interaction logic for Dota2View.xaml
/// </summary>
public partial class Dota2View : UserControl
{
public Dota2View()
{
InitializeComponent();
}
}
}

View File

@ -0,0 +1,18 @@
using Artemis.Models;
using Caliburn.Micro;
namespace Artemis.Modules.Games.Dota2
{
public class Dota2ViewModel : Screen
{
public Dota2ViewModel(MainModel mainModel)
{
MainModel = mainModel;
}
public MainModel MainModel { get; set; }
public static string Name => "Dota 2 (NYI)";
public string Content => "Dota 2 Content";
}
}

View File

@ -0,0 +1,130 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Threading;
using System.Threading.Tasks;
using Artemis.Models;
using Artemis.Utilities;
using Artemis.Utilities.Keyboard;
using Artemis.Utilities.Memory;
namespace Artemis.Modules.Games.RocketLeague
{
public class RocketLeagueModel : GameModel
{
public RocketLeagueModel(RocketLeagueSettings settings)
{
Name = "RocketLeague";
ProcessName = "RocketLeague";
Scale = 4;
Settings = settings;
BoostRectangle = new KeyboardRectangle(Scale, 0, 0, Scale*21, Scale*8,
new List<Color>
{
ColorHelpers.MediaColorToDrawingColor(Settings.MainColor),
ColorHelpers.MediaColorToDrawingColor(Settings.SecondaryColor)
}, LinearGradientMode.Horizontal);
Enabled = Settings.Enabled;
}
public int Scale { get; set; }
public RocketLeagueSettings Settings { get; set; }
private int BoostAmount { get; set; }
private KeyboardRectangle BoostRectangle { get; }
private Process Process { get; set; }
private int PreviousBoost { get; set; }
private bool BoostGrowing { get; set; }
private Memory Memory { get; set; }
public override void Dispose()
{
Process = null;
Memory = null;
}
public override void Enable()
{
Process = MemoryHelpers.GetProcessIfRunning(ProcessName);
Memory = new Memory(Process);
}
public override void Update()
{
if (BoostGrowing)
return;
if (Memory == null)
return;
// TODO: Get address from web on startup
var boostAddress = Memory.GetAddress("\"RocketLeague.exe\"+014FAA04+58+5ac+6f4+21c");
var boostFloat = Memory.ReadFloat(boostAddress)*100/3;
PreviousBoost = BoostAmount;
BoostAmount = (int) Math.Ceiling(boostFloat);
// Take care of any reading errors resulting in an OutOfMemory on draw
if (BoostAmount < 0)
BoostAmount = 0;
if (BoostAmount > 100)
BoostAmount = 100;
BoostRectangle.Width = (int) Math.Ceiling(((Scale*21)/100.00)*BoostAmount);
Task.Run(() => GrowIfHigher());
}
private void GrowIfHigher()
{
if (BoostAmount <= PreviousBoost || BoostGrowing)
return;
BoostGrowing = true;
const int amountOfSteps = 6;
var difference = BoostAmount - PreviousBoost;
var differenceStep = difference/amountOfSteps;
var differenceStepRest = difference%amountOfSteps;
BoostAmount = PreviousBoost;
BoostRectangle.Width = (int) Math.Ceiling(((Scale*21)/100.00)*BoostAmount);
for (var i = 0; i < amountOfSteps; i++)
{
if (differenceStepRest > 0)
{
differenceStepRest -= 1;
BoostAmount += 1;
BoostRectangle.Width = (int) Math.Ceiling(((Scale*21)/100.00)*BoostAmount);
}
BoostAmount += differenceStep;
BoostRectangle.Width = (int) Math.Ceiling(((Scale*21)/100.00)*BoostAmount);
Thread.Sleep(50);
}
BoostGrowing = false;
}
public override Bitmap GenerateBitmap()
{
var bitmap = new Bitmap(Scale*21, Scale*8);
using (var g = Graphics.FromImage(bitmap))
{
g.Clear(Color.Transparent);
BoostRectangle.Draw(g);
}
return bitmap;
}
}
}

View File

@ -0,0 +1,40 @@
using System.Windows.Media;
using Artemis.Models;
namespace Artemis.Modules.Games.RocketLeague
{
public class RocketLeagueSettings : EffectSettings
{
public RocketLeagueSettings()
{
Load();
}
public bool Enabled { get; set; }
public Color MainColor { get; set; }
public Color SecondaryColor { get; set; }
public override sealed void Load()
{
Enabled = Settings.RocketLeague.Default.Enabled;
MainColor = Settings.RocketLeague.Default.MainColor;
SecondaryColor = Settings.RocketLeague.Default.SecondaryColor;
}
public override sealed void Save()
{
Settings.RocketLeague.Default.Enabled = Enabled;
Settings.RocketLeague.Default.MainColor = MainColor;
Settings.RocketLeague.Default.SecondaryColor = SecondaryColor;
Settings.RocketLeague.Default.Save();
}
public override sealed void ToDefault()
{
Enabled = true;
MainColor = Color.FromArgb(255, 255, 80, 0);
SecondaryColor = Color.FromArgb(255, 255, 0, 0);
}
}
}

View File

@ -0,0 +1,72 @@
<UserControl x:Class="Artemis.Modules.Games.RocketLeague.RocketLeagueView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:cal="http://www.caliburnproject.org"
xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls"
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
mc:Ignorable="d"
d:DesignHeight="352.568" d:DesignWidth="490.332"
d:DataContext="{d:DesignInstance Type=games:RocketLeagueViewModel, IsDesignTimeCreatable=True}"
cal:Bind.AtDesignTime="True">
<Grid Margin="15, 5, 15, 5">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2">
<Label FontSize="20" Style="{DynamicResource DescriptionHeaderStyle}" HorizontalAlignment="Left">
<Label.Content>
<AccessText TextWrapping="Wrap"
Text="Fills up the keyboard according to the amount of boost you have." />
</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"
Style="{DynamicResource MetroCircleToggleButtonStyle}" />
</StackPanel>
</StackPanel>
<StackPanel Grid.Row="1"
Grid.Column="0"
HorizontalAlignment="Left">
<Label FontSize="16" Content="Main color" Style="{DynamicResource DescriptionHeaderStyle}"
FontFamily="Segoe UI Semibold" Foreground="#535353" Width="130" />
<xctk:ColorPicker x:Name="MainColor"
SelectedColor="{Binding Path=RocketLeagueSettings.MainColor, Mode=TwoWay}" />
</StackPanel>
<StackPanel Grid.Row="1"
Grid.Column="1"
HorizontalAlignment="Left">
<Label FontSize="16" Content="Secondary color" Style="{DynamicResource DescriptionHeaderStyle}"
FontFamily="Segoe UI Semibold" Foreground="#535353" Width="130" />
<xctk:ColorPicker x:Name="SecondaryColor"
SelectedColor="{Binding Path=RocketLeagueSettings.SecondaryColor, Mode=TwoWay}" />
</StackPanel>
<StackPanel Grid.Column="0" Grid.Row="2" Grid.ColumnSpan="2" VerticalAlignment="Top">
<Label FontSize="16"
Style="{DynamicResource DescriptionHeaderStyle}"
FontFamily="Segoe UI Semibold" Foreground="#535353" Height="79" Margin="0,10,0,0">
<Label.Content>
<AccessText TextWrapping="Wrap"
Text="Tip: To find a color combination you like, start an exhibition match, pickup 100 boost and play around with the colors. They'll appear on your keyboard immediately! Once you're satisfied don't forget to click save changes."
FontStyle="Italic" FontSize="12" />
</Label.Content>
</Label>
</StackPanel>
<StackPanel Grid.Column="0" Grid.Row="3" Orientation="Horizontal" VerticalAlignment="Bottom">
<Button x:Name="ResetSettings" Content="Reset effect" VerticalAlignment="Top" Width="100"
Style="{DynamicResource SquareButtonStyle}" />
<Button x:Name="SaveSettings" Content="Save changes" VerticalAlignment="Top" Width="100" Margin="10,0,0,0"
Style="{DynamicResource SquareButtonStyle}" />
</StackPanel>
</Grid>
</UserControl>

View File

@ -0,0 +1,15 @@
using System.Windows.Controls;
namespace Artemis.Modules.Games.RocketLeague
{
/// <summary>
/// Interaction logic for RocketLeagueView.xaml
/// </summary>
public partial class RocketLeagueView : UserControl
{
public RocketLeagueView()
{
InitializeComponent();
}
}
}

View File

@ -0,0 +1,55 @@
using Artemis.Models;
using Caliburn.Micro;
namespace Artemis.Modules.Games.RocketLeague
{
public class RocketLeagueViewModel : Screen
{
private RocketLeagueSettings _rocketLeagueSettings;
public RocketLeagueViewModel(MainModel mainModel)
{
MainModel = mainModel;
// Settings are loaded from file by class
RocketLeagueSettings = new RocketLeagueSettings();
// Create effect model and add it to MainModel
RocketLeagueModel = new RocketLeagueModel(RocketLeagueSettings);
MainModel.EffectModels.Add(RocketLeagueModel);
}
public static string Name => "Rocket League";
public MainModel MainModel { get; set; }
public RocketLeagueModel RocketLeagueModel { get; set; }
public RocketLeagueSettings RocketLeagueSettings
{
get { return _rocketLeagueSettings; }
set
{
if (Equals(value, _rocketLeagueSettings)) return;
_rocketLeagueSettings = value;
NotifyOfPropertyChange(() => RocketLeagueSettings);
}
}
public void SaveSettings()
{
if (RocketLeagueModel == null)
return;
RocketLeagueSettings.Save();
}
public void ResetSettings()
{
// TODO: Confirmation dialog (Generic MVVM approach)
RocketLeagueSettings.ToDefault();
NotifyOfPropertyChange(() => RocketLeagueSettings);
SaveSettings();
}
}
}

View File

@ -0,0 +1,110 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using Artemis.Models;
using Artemis.Modules.Games.RocketLeague;
using Artemis.Utilities.Keyboard;
using Artemis.Utilities.Memory;
using MyMemory;
namespace Artemis.Modules.Games.Witcher3
{
public class Witcher3Model : GameModel
{
public Witcher3Model(RocketLeagueSettings settings)
{
Name = "Witcher3";
ProcessName = "witcher3";
Scale = 4;
Settings = settings;
SignRect = new KeyboardRectangle(Scale, 0, 0, 84, 24, new List<Color> {Color.Blue, Color.Red},
LinearGradientMode.Horizontal)
{
Rotate = true,
LoopSpeed = 0.5
};
Enabled = Settings.Enabled;
}
public int Scale { get; set; }
public RocketLeagueSettings Settings { get; set; }
public KeyboardRectangle SignRect { get; set; }
private RemoteProcess Process { get; set; }
private Memory Memory { get; set; }
public IntPtr BaseAddress { get; set; }
public override void Dispose()
{
Process = null;
Memory = null;
}
public override void Enable()
{
var tempProcess = MemoryHelpers.GetProcessIfRunning(ProcessName);
BaseAddress = tempProcess.MainModule.BaseAddress;
Process = new RemoteProcess((uint) tempProcess.Id);
}
public override void Update()
{
if (Process == null)
return;
// TODO: Get address from web on startup
var processHandle = Process.ProcessHandle;
var baseAddress = (IntPtr) 0x028F3F60;
int[] offsets = {0x28, 0x10, 0x20, 0xbc0};
var addr = MemoryHelpers.FindAddress(processHandle, BaseAddress, baseAddress, offsets);
var result = Process.MemoryManager.Read<byte>(addr);
switch (result)
{
case 0:
// Aard
SignRect.Colors = new List<Color> {Color.DeepSkyBlue, Color.Blue, Color.DeepSkyBlue, Color.Blue};
break;
case 1:
// Yrden
SignRect.Colors = new List<Color> {Color.Purple, Color.DeepPink, Color.Purple, Color.DeepPink};
break;
case 2:
// Igni
SignRect.Colors = new List<Color> {Color.DarkOrange, Color.Red, Color.DarkOrange, Color.Red};
break;
case 3:
// Quen
SignRect.Colors = new List<Color> {Color.DarkOrange, Color.Yellow, Color.DarkOrange, Color.Yellow};
break;
case 4:
// Axii
SignRect.Colors = new List<Color>
{
Color.LawnGreen,
Color.DarkGreen,
Color.LawnGreen,
Color.DarkGreen
};
break;
}
}
public override Bitmap GenerateBitmap()
{
var bitmap = new Bitmap(21, 6);
using (var g = Graphics.FromImage(bitmap))
{
g.Clear(Color.Transparent);
SignRect.Draw(g);
}
return bitmap;
}
}
}

View File

@ -0,0 +1,11 @@
<UserControl x:Class="Artemis.Modules.Games.Witcher3.Witcher3View"
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"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<TextBlock Text="{Binding Content}" />
</Grid>
</UserControl>

View File

@ -0,0 +1,15 @@
using System.Windows.Controls;
namespace Artemis.Modules.Games.Witcher3
{
/// <summary>
/// Interaction logic for Witcher3View.xaml
/// </summary>
public partial class Witcher3View : UserControl
{
public Witcher3View()
{
InitializeComponent();
}
}
}

View File

@ -0,0 +1,56 @@
using Artemis.Models;
using Artemis.Modules.Games.RocketLeague;
using Caliburn.Micro;
namespace Artemis.Modules.Games.Witcher3
{
public class Witcher3ViewModel : Screen
{
private RocketLeagueSettings _rocketLeagueSettings;
public Witcher3ViewModel(MainModel mainModel)
{
MainModel = mainModel;
// Settings are loaded from file by class
RocketLeagueSettings = new RocketLeagueSettings();
// Create effect model and add it to MainModel
Witcher3Model = new Witcher3Model(RocketLeagueSettings);
MainModel.EffectModels.Add(Witcher3Model);
}
public static string Name => "The Witcher 3";
public MainModel MainModel { get; set; }
public Witcher3Model Witcher3Model { get; set; }
public RocketLeagueSettings RocketLeagueSettings
{
get { return _rocketLeagueSettings; }
set
{
if (Equals(value, _rocketLeagueSettings)) return;
_rocketLeagueSettings = value;
NotifyOfPropertyChange(() => RocketLeagueSettings);
}
}
public void SaveSettings()
{
if (Witcher3Model == null)
return;
RocketLeagueSettings.Save();
}
public void ResetSettings()
{
// TODO: Confirmation dialog (Generic MVVM approach)
RocketLeagueSettings.ToDefault();
NotifyOfPropertyChange(() => RocketLeagueSettings);
SaveSettings();
}
}
}

View File

@ -0,0 +1,33 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using Artemis.Utilities.Keyboard;
namespace Artemis.Modules.Overlays.VolumeDisplay
{
public class VolumeDisplay
{
public VolumeDisplay()
{
Transparancy = 255;
Scale = 4;
}
public int Scale { get; set; }
public int Ttl { get; set; }
public byte Transparancy { get; set; }
public int Volume { get; set; }
public void Draw(Graphics g)
{
var mainColor = Color.FromArgb(Transparancy, 0, 191, 255);
var secondaryColor = Color.FromArgb(Transparancy, 255, 0, 0);
var volumeRect = new KeyboardRectangle(Scale, 0, 0, (int) Math.Ceiling(((Scale*21)/100.00)*Volume),
8*Scale, new List<Color> {mainColor, secondaryColor}, LinearGradientMode.Horizontal);
volumeRect.Draw(g);
}
}
}

View File

@ -0,0 +1,107 @@
using System.Drawing;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using System.Windows.Forms;
using Artemis.Models;
using NAudio.CoreAudioApi;
using Open.WinKeyboardHook;
namespace Artemis.Modules.Overlays.VolumeDisplay
{
public class VolumeDisplayModel : OverlayModel
{
private bool _enabled;
public VolumeDisplayModel(VolumeDisplaySettings settings)
{
Settings = settings;
Name = "VolumeDisplay";
KeyboardInterceptor = new KeyboardInterceptor();
KeyboardInterceptor.StartCapturing();
Enabled = Settings.Enabled;
VolumeDisplay = new VolumeDisplay();
}
public VolumeDisplay VolumeDisplay { get; set; }
public VolumeDisplaySettings Settings { get; set; }
public KeyboardInterceptor KeyboardInterceptor { get; set; }
public override void Dispose()
{
KeyboardInterceptor.KeyUp -= HandleKeypress;
KeyboardInterceptor.StopCapturing();
}
public override void Enable()
{
KeyboardInterceptor.StartCapturing();
KeyboardInterceptor.KeyUp += HandleKeypress;
}
public override void Update()
{
// TODO: Get from settings
var fps = 25;
if (VolumeDisplay == null)
return;
if (VolumeDisplay.Ttl < 1)
return;
var decreaseAmount = 500/fps;
VolumeDisplay.Ttl = VolumeDisplay.Ttl - decreaseAmount;
if (VolumeDisplay.Ttl < 128)
VolumeDisplay.Transparancy = (byte) (VolumeDisplay.Transparancy - 20);
try
{
var enumerator = new MMDeviceEnumerator();
var volumeFloat =
enumerator.GetDefaultAudioEndpoint(DataFlow.Render, Role.Console)
.AudioEndpointVolume.MasterVolumeLevelScalar;
VolumeDisplay.Volume = (int) (volumeFloat*100);
}
catch (COMException)
{
}
}
public override Bitmap GenerateBitmap()
{
return GenerateBitmap(new Bitmap(21, 6));
}
public override Bitmap GenerateBitmap(Bitmap bitmap)
{
if (VolumeDisplay == null)
return bitmap;
if (VolumeDisplay.Ttl < 1)
return bitmap;
using (var g = Graphics.FromImage(bitmap))
{
VolumeDisplay.Draw(g);
}
return bitmap;
}
private void HandleKeypress(object sender, KeyEventArgs e)
{
Task.Factory.StartNew(() => KeyPressTask(e));
}
private void KeyPressTask(KeyEventArgs e)
{
if (e.KeyCode != Keys.VolumeUp && e.KeyCode != Keys.VolumeDown)
return;
VolumeDisplay.Ttl = 1000;
VolumeDisplay.Transparancy = 255;
}
}
}

View File

@ -0,0 +1,36 @@
using Artemis.Models;
namespace Artemis.Modules.Overlays.VolumeDisplay
{
public class VolumeDisplaySettings : EffectSettings
{
public VolumeDisplaySettings()
{
Load();
}
public bool Enabled { get; set; }
public bool DisplayVolume { get; set; }
public bool DisplayPlayPause { get; set; }
public bool DisplayPreviousNext { get; set; }
public bool DisplayStop { get; set; }
public override sealed void Load()
{
ToDefault();
}
public override sealed void Save()
{
}
public override sealed void ToDefault()
{
Enabled = true;
DisplayVolume = true;
DisplayPlayPause = true;
DisplayPreviousNext = true;
DisplayStop = true;
}
}
}

View File

@ -0,0 +1,62 @@
<UserControl x:Class="Artemis.Modules.Overlays.VolumeDisplay.VolumeDisplayView"
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:controls="http://metro.mahapps.com/winfx/xaml/controls"
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
xmlns:cal="http://www.caliburnproject.org"
mc:Ignorable="d"
d:DesignHeight="407.812" d:DesignWidth="671.484"
d:DataContext="{d:DesignInstance Type=overlays:VolumeDisplayViewModel, IsDesignTimeCreatable=True}"
cal:Bind.AtDesignTime="True">
<Grid Margin="15, 5, 15, 5">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2">
<Label FontSize="20"
Style="{DynamicResource DescriptionHeaderStyle}" HorizontalAlignment="Left">
<Label.Content>
<AccessText TextWrapping="Wrap" Text="Displays media key actions on the keyboard." />
</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=VolumeDisplaySettings.Enabled, Mode=TwoWay}"
Style="{DynamicResource MetroCircleToggleButtonStyle}"
cal:Message.Attach="[Event Click] = [Action ToggleEffect]" />
</StackPanel>
</StackPanel>
<StackPanel Grid.Row="1"
Grid.Column="0"
HorizontalAlignment="Left">
<Label FontSize="16" Content="Volume bar color" Style="{DynamicResource DescriptionHeaderStyle}"
FontFamily="Segoe UI Semibold" Foreground="#535353" Width="134" HorizontalAlignment="Left" />
<xctk:ColorPicker x:Name="VolumeBarColor" Width="178" />
</StackPanel>
<StackPanel Grid.Row="1"
Grid.Column="1"
HorizontalAlignment="Left">
<Label FontSize="16" Content="Volume bar border color" Style="{DynamicResource DescriptionHeaderStyle}"
FontFamily="Segoe UI Semibold" Foreground="#535353" />
<xctk:ColorPicker x:Name="VolumeBarBorderColor" Width="178" HorizontalAlignment="Left" />
</StackPanel>
<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>
</UserControl>

View File

@ -0,0 +1,15 @@
using System.Windows.Controls;
namespace Artemis.Modules.Overlays.VolumeDisplay
{
/// <summary>
/// Interaction logic for MediaKeysDisplayView.xaml
/// </summary>
public partial class VolumeDisplayView : UserControl
{
public VolumeDisplayView()
{
InitializeComponent();
}
}
}

View File

@ -0,0 +1,60 @@
using Artemis.Models;
using Caliburn.Micro;
namespace Artemis.Modules.Overlays.VolumeDisplay
{
public class VolumeDisplayViewModel : Screen
{
private VolumeDisplaySettings _volumeDisplaySettings;
public VolumeDisplayViewModel(MainModel mainModel)
{
MainModel = mainModel;
// Settings are loaded from file by class
VolumeDisplaySettings = new VolumeDisplaySettings();
// Create effect model and add it to MainModel
VolumeDisplayModel = new VolumeDisplayModel(VolumeDisplaySettings);
MainModel.EffectModels.Add(VolumeDisplayModel);
}
public static string Name => "Volume Display";
public MainModel MainModel { get; set; }
public VolumeDisplayModel VolumeDisplayModel { get; set; }
public VolumeDisplaySettings VolumeDisplaySettings
{
get { return _volumeDisplaySettings; }
set
{
if (Equals(value, _volumeDisplaySettings)) return;
_volumeDisplaySettings = value;
NotifyOfPropertyChange(() => VolumeDisplaySettings);
}
}
public void ToggleEffect()
{
VolumeDisplayModel.Enabled = VolumeDisplaySettings.Enabled;
}
public void SaveSettings()
{
if (VolumeDisplayModel == null)
return;
VolumeDisplaySettings.Save();
}
public void ResetSettings()
{
// TODO: Confirmation dialog (Generic MVVM approach)
VolumeDisplaySettings.ToDefault();
NotifyOfPropertyChange(() => VolumeDisplaySettings);
SaveSettings();
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,56 @@
using System.Reflection;
using System.Runtime.InteropServices;
using System.Windows;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Artemis")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Artemis")]
[assembly: AssemblyCopyright("Copyright © 2015")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
//In order to begin building localizable applications, set
//<UICulture>CultureYouAreCodingWith</UICulture> in your .csproj file
//inside a <PropertyGroup>. For example, if you are using US english
//in your source files, set the <UICulture> to en-US. Then uncomment
//the NeutralResourceLanguage attribute below. Update the "en-US" in
//the line below to match the UICulture setting in the project file.
//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
[assembly: ThemeInfo(
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
//(used if a resource is not found in the page,
// or application resource dictionaries)
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
//(used if a resource is not found in the page,
// app, or any theme specific resource dictionaries)
)]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@ -0,0 +1,71 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Artemis.Properties
{
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources
{
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources()
{
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager
{
get
{
if ((resourceMan == null))
{
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Artemis.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture
{
get
{
return resourceCulture;
}
set
{
resourceCulture = value;
}
}
}
}

View File

@ -0,0 +1,117 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -0,0 +1,30 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Artemis.Properties
{
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
{
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default
{
get
{
return defaultInstance;
}
}
}
}

View File

@ -0,0 +1,7 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="uri:settings" CurrentProfile="(Default)">
<Profiles>
<Profile Name="(Default)" />
</Profiles>
<Settings />
</SettingsFile>

View File

@ -0,0 +1,3 @@
Entypo (http://www.entypo.com/) is created by Daniel Bruce and released under the Creative Commons, Share Alike/Attribution license.
http://creativecommons.org/licenses/by-sa/3.0/

Binary file not shown.

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,62 @@
# License
Please carefully understand the license and download the latest icons at ModernUIIcons.com.
## Understand Your Rights
No Attribution and No Derived Works
http://creativecommons.org/licenses/by-nd/3.0/ *
- If your project is open source include this license file in the source.
- Nothing is needed in the front facing project (UNLESS you
are using any of the icons listed below in the attribution section).
- Commercial use is not only allowed but encouraged. If it is an icon
in the attribution list below, you still need to attribute those!
- Do not distribute the entire package (I've allowed this dozens of
times for open source projects, but email me first).
## Creator
- Austin Andrews (@templarian)
## Contributor**
- Jay Zawrotny (@JayZawrotny)
- A Bunch
- Oren Nachman
- appbar.chevron.down
- appbar.chevron.up
- appbar.chevron.left
- appbar.chevron.right
## Derived Works
- Alex Peattie
- Social: http://www.alexpeattie.com/projects/justvector_icons/
## Attribution***
- Kris Vandermotten (@kvandermotten)
- appbar.medical.pulse
- Constantin Kichinsky (@kichinsky)
- appbar.currency.rubles
- appbar.currency.grivna
- Massimo Savazzi (@msavazzi)
- List of missing exported icons
- Proletkult Graphik, from The Noun Project
- appbar.draw.pen (inspired)
- Olivier Guin, from The Noun Project
- appbar.draw.marker
- Gibran Bisio, from The Noun Project
- appbar.draw.bucket
Andrew Forrester, from The Noun Project
- appbar.fingerprint
* The license is for attribution, but this is not required.
** Developers and designers that emailed Templarian the source .design icons to be added into the package. PNGs also accepted, but may take longer to be added.
*** Icons I've copied so closely you want to attribute them and are also under the CC license.
Contact
- http://templarian.com/
- admin[@]templarian[.]com
* Does not apply to copyrighted logos
- Skype
- Facebook
- Twitter
- etc...

View File

@ -0,0 +1,98 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Artemis.Settings {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "14.0.0.0")]
internal sealed partial class AudioVisualization : global::System.Configuration.ApplicationSettingsBase {
private static AudioVisualization defaultInstance = ((AudioVisualization)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new AudioVisualization())));
public static AudioVisualization Default {
get {
return defaultInstance;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("4")]
public int Sensitivity {
get {
return ((int)(this["Sensitivity"]));
}
set {
this["Sensitivity"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("21")]
public int Bars {
get {
return ((int)(this["Bars"]));
}
set {
this["Bars"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("1")]
public int Spread {
get {
return ((int)(this["Spread"]));
}
set {
this["Spread"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("3")]
public int FadeSpeed {
get {
return ((int)(this["FadeSpeed"]));
}
set {
this["FadeSpeed"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("#FF0000FF")]
public global::System.Windows.Media.Color MainColor {
get {
return ((global::System.Windows.Media.Color)(this["MainColor"]));
}
set {
this["MainColor"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("#FF1E90FF")]
public global::System.Windows.Media.Color SecondaryColor {
get {
return ((global::System.Windows.Media.Color)(this["SecondaryColor"]));
}
set {
this["SecondaryColor"] = value;
}
}
}
}

View File

@ -0,0 +1,26 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)"
GeneratedClassNamespace="Artemis.Settings" GeneratedClassName="AudioVisualization">
<Profiles />
<Settings>
<Setting Name="Sensitivity" Type="System.Int32" Scope="User">
<Value Profile="(Default)">4</Value>
</Setting>
<Setting Name="Bars" Type="System.Int32" Scope="User">
<Value Profile="(Default)">21</Value>
</Setting>
<Setting Name="Spread" Type="System.Int32" Scope="User">
<Value Profile="(Default)">1</Value>
</Setting>
<Setting Name="FadeSpeed" Type="System.Int32" Scope="User">
<Value Profile="(Default)">3</Value>
</Setting>
<Setting Name="MainColor" Type="System.Windows.Media.Color" Scope="User">
<Value Profile="(Default)">#FF0000FF</Value>
</Setting>
<Setting Name="SecondaryColor" Type="System.Windows.Media.Color" Scope="User">
<Value Profile="(Default)">#FF1E90FF</Value>
</Setting>
</Settings>
</SettingsFile>

View File

@ -0,0 +1,50 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Artemis.Settings {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "14.0.0.0")]
internal sealed partial class General : global::System.Configuration.ApplicationSettingsBase {
private static General defaultInstance = ((General)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new General())));
public static General Default {
get {
return defaultInstance;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("TypeWave")]
public string LastEffect {
get {
return ((string)(this["LastEffect"]));
}
set {
this["LastEffect"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("Logitech G910 Orion Spark RGB")]
public string LastKeyboard {
get {
return ((string)(this["LastKeyboard"]));
}
set {
this["LastKeyboard"] = value;
}
}
}
}

View File

@ -0,0 +1,14 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)"
GeneratedClassNamespace="Artemis.Settings" GeneratedClassName="General">
<Profiles />
<Settings>
<Setting Name="LastEffect" Type="System.String" Scope="User">
<Value Profile="(Default)">TypeWave</Value>
</Setting>
<Setting Name="LastKeyboard" Type="System.String" Scope="User">
<Value Profile="(Default)">Logitech G910 Orion Spark RGB</Value>
</Setting>
</Settings>
</SettingsFile>

View File

@ -0,0 +1,62 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Artemis.Settings {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "14.0.0.0")]
internal sealed partial class RocketLeague : global::System.Configuration.ApplicationSettingsBase {
private static RocketLeague defaultInstance = ((RocketLeague)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new RocketLeague())));
public static RocketLeague Default {
get {
return defaultInstance;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("False")]
public bool Enabled {
get {
return ((bool)(this["Enabled"]));
}
set {
this["Enabled"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("#FFFF5000")]
public global::System.Windows.Media.Color MainColor {
get {
return ((global::System.Windows.Media.Color)(this["MainColor"]));
}
set {
this["MainColor"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("#FFFF0000")]
public global::System.Windows.Media.Color SecondaryColor {
get {
return ((global::System.Windows.Media.Color)(this["SecondaryColor"]));
}
set {
this["SecondaryColor"] = value;
}
}
}
}

View File

@ -0,0 +1,17 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)"
GeneratedClassNamespace="Artemis.Settings" GeneratedClassName="RocketLeague">
<Profiles />
<Settings>
<Setting Name="Enabled" Type="System.Boolean" Scope="User">
<Value Profile="(Default)">False</Value>
</Setting>
<Setting Name="MainColor" Type="System.Windows.Media.Color" Scope="User">
<Value Profile="(Default)">#FFFF5000</Value>
</Setting>
<Setting Name="SecondaryColor" Type="System.Windows.Media.Color" Scope="User">
<Value Profile="(Default)">#FFFF0000</Value>
</Setting>
</Settings>
</SettingsFile>

View File

@ -0,0 +1,98 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Artemis.Settings {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "14.0.0.0")]
internal sealed partial class TypeWave : global::System.Configuration.ApplicationSettingsBase {
private static TypeWave defaultInstance = ((TypeWave)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new TypeWave())));
public static TypeWave Default {
get {
return defaultInstance;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("True")]
public bool IsRandomColors {
get {
return ((bool)(this["IsRandomColors"]));
}
set {
this["IsRandomColors"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("#FFFF0000")]
public global::System.Windows.Media.Color WaveColor {
get {
return ((global::System.Windows.Media.Color)(this["WaveColor"]));
}
set {
this["WaveColor"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("True")]
public bool IsShiftColors {
get {
return ((bool)(this["IsShiftColors"]));
}
set {
this["IsShiftColors"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("20")]
public int ShiftColorSpeed {
get {
return ((int)(this["ShiftColorSpeed"]));
}
set {
this["ShiftColorSpeed"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("500")]
public int TimeToLive {
get {
return ((int)(this["TimeToLive"]));
}
set {
this["TimeToLive"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("4")]
public int SpreadSpeed {
get {
return ((int)(this["SpreadSpeed"]));
}
set {
this["SpreadSpeed"] = value;
}
}
}
}

View File

@ -0,0 +1,26 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)"
GeneratedClassNamespace="Artemis.Settings" GeneratedClassName="TypeWave">
<Profiles />
<Settings>
<Setting Name="IsRandomColors" Type="System.Boolean" Scope="User">
<Value Profile="(Default)">True</Value>
</Setting>
<Setting Name="WaveColor" Type="System.Windows.Media.Color" Scope="User">
<Value Profile="(Default)">#FFFF0000</Value>
</Setting>
<Setting Name="IsShiftColors" Type="System.Boolean" Scope="User">
<Value Profile="(Default)">True</Value>
</Setting>
<Setting Name="ShiftColorSpeed" Type="System.Int32" Scope="User">
<Value Profile="(Default)">20</Value>
</Setting>
<Setting Name="TimeToLive" Type="System.Int32" Scope="User">
<Value Profile="(Default)">500</Value>
</Setting>
<Setting Name="SpreadSpeed" Type="System.Int32" Scope="User">
<Value Profile="(Default)">4</Value>
</Setting>
</Settings>
</SettingsFile>

View File

@ -0,0 +1,17 @@
using System;
using System.Diagnostics;
using NAudio.Dsp;
namespace Artemis.Utilities.Audio
{
public class FftEventArgs : EventArgs
{
[DebuggerStepThrough]
public FftEventArgs(Complex[] result)
{
Result = result;
}
public Complex[] Result { get; private set; }
}
}

View File

@ -0,0 +1,55 @@
using System;
using NAudio.Dsp;
namespace Artemis.Utilities.Audio
{ // The Complex and FFT are here!
public class SampleAggregator
{
private readonly FftEventArgs fftArgs;
// This Complex is NAudio's own!
private readonly Complex[] fftBuffer;
private readonly int fftLength;
private readonly int m;
private int fftPos;
public SampleAggregator(int fftLength)
{
if (!IsPowerOfTwo(fftLength))
{
throw new ArgumentException("FFT Length must be a power of two");
}
m = (int) Math.Log(fftLength, 2.0);
this.fftLength = fftLength;
fftBuffer = new Complex[fftLength];
fftArgs = new FftEventArgs(fftBuffer);
}
public bool PerformFFT { get; set; }
// FFT
public event EventHandler<FftEventArgs> FftCalculated;
private bool IsPowerOfTwo(int x)
{
return (x & (x - 1)) == 0;
}
public void Add(float value)
{
if (PerformFFT && FftCalculated != null)
{
// Remember the window function! There are many others as well.
fftBuffer[fftPos].X = (float) (value*FastFourierTransform.HammingWindow(fftPos, fftLength));
fftBuffer[fftPos].Y = 0; // This is always zero with audio.
fftPos++;
if (fftPos >= fftLength)
{
fftPos = 0;
FastFourierTransform.FFT(true, m, fftBuffer);
FftCalculated(this, fftArgs);
}
}
}
}
}

View File

@ -0,0 +1,83 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
namespace Artemis.Utilities
{
public static class ColorHelpers
{
/// <summary>
/// Comes up with a 'pure' psuedo-random color
/// </summary>
/// <returns>The color</returns>
public static Color GetRandomRainbowColor()
{
var colors = new List<int>();
var rand = new Random();
for (var i = 0; i < 3; i++)
colors.Add(rand.Next(0, 256));
var highest = colors.Max();
var lowest = colors.Min();
colors[colors.FindIndex(c => c == highest)] = 255;
colors[colors.FindIndex(c => c == lowest)] = 0;
var returnColor = Color.FromArgb(255, colors[0], colors[1], colors[2]);
return returnColor;
}
public static Color ShiftColor(Color c, int shiftAmount)
{
int newRed = c.R;
int newGreen = c.G;
int newBlue = c.B;
// Red to purple
if (c.R == 255 && c.B < 255 && c.G == 0)
newBlue = newBlue + shiftAmount;
// Purple to blue
else if (c.B == 255 && c.R > 0)
newRed = newRed - shiftAmount;
// Blue to light-blue
else if (c.B == 255 && c.G < 255)
newGreen = newGreen + shiftAmount;
// Light-blue to green
else if (c.G == 255 && c.B > 0)
newBlue = newBlue - shiftAmount;
// Green to yellow
else if (c.G == 255 && c.R < 255)
newRed = newRed + shiftAmount;
// Yellow to red
else if (c.R == 255 && c.G > 0)
newGreen = newGreen - shiftAmount;
newRed = BringIntInColorRange(newRed);
newGreen = BringIntInColorRange(newGreen);
newBlue = BringIntInColorRange(newBlue);
return Color.FromArgb(c.A, newRed, newGreen, newBlue);
}
private static int BringIntInColorRange(int i)
{
if (i < 0)
return 0;
if (i > 255)
return 255;
return i;
}
public static Color MediaColorToDrawingColor(System.Windows.Media.Color mColor)
{
return Color.FromArgb(mColor.A, mColor.R, mColor.G, mColor.B);
}
public static System.Windows.Media.Color DrawingColorToMediaColor(Color dColor)
{
return System.Windows.Media.Color.FromArgb(dColor.A, dColor.R, dColor.G, dColor.B);
}
}
}

View File

@ -0,0 +1,14 @@
using System;
namespace Artemis.Utilities.GameSense
{
public class GameDataReceivedEventArgs : EventArgs
{
public GameDataReceivedEventArgs(object json)
{
Json = json;
}
public object Json { get; set; }
}
}

View File

@ -0,0 +1,116 @@
using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using Newtonsoft.Json;
namespace Artemis.Utilities.GameSense
{
public class GameSenseWebServer
{
public delegate void GameDataReceivedEventHandler(
object sender, GameDataReceivedEventArgs gameDataReceivedEventArgs);
private readonly HttpListener _listener = new HttpListener();
public GameSenseWebServer()
{
Start();
}
public int Port { get; private set; }
public bool Running { get; private set; }
public event GameDataReceivedEventHandler GameDataReceived;
public void Start()
{
if (Running)
return;
_listener.Prefixes.Clear();
//Port = FreeTcpPort();
Port = 5821;
_listener.Prefixes.Add($"http://127.0.0.1:{Port}/");
_listener.Start();
ThreadPool.QueueUserWorkItem(o =>
{
try
{
while (_listener.IsListening)
{
ThreadPool.QueueUserWorkItem(c =>
{
var ctx = c as HttpListenerContext;
if (ctx == null)
return;
try
{
var rstr = HandleRequest(ctx.Request);
var buf = Encoding.UTF8.GetBytes(rstr);
ctx.Response.ContentLength64 = buf.Length;
ctx.Response.OutputStream.Write(buf, 0, buf.Length);
}
catch
{
// ignored
}
finally
{
// always close the stream
ctx.Response.OutputStream.Close();
}
}, _listener.GetContext());
}
}
catch
{
// ignored
}
});
Running = true;
// Create and store JSON file (Could serialize an object but not worth it)
var path = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) +
@"\SteelSeries\SteelSeries Engine 3";
if (!Directory.Exists(path))
Directory.CreateDirectory(path);
var content = "{\"address\":\"localhost:" + Port + "\"}";
File.WriteAllText(path + @"\coreProps.json", content);
}
private int FreeTcpPort()
{
var l = new TcpListener(IPAddress.Loopback, 0);
l.Start();
var port = ((IPEndPoint) l.LocalEndpoint).Port;
l.Stop();
return port;
}
private string HandleRequest(HttpListenerRequest request)
{
object json;
using (var reader = new StreamReader(request.InputStream, request.ContentEncoding))
{
var result = reader.ReadToEnd();
json = JsonConvert.DeserializeObject<object>(result);
}
if (json != null)
OnGameDataReceived(new GameDataReceivedEventArgs(json));
return JsonConvert.SerializeObject(json);
}
protected virtual void OnGameDataReceived(GameDataReceivedEventArgs e)
{
GameDataReceived?.Invoke(this, e);
}
}
}

View File

@ -0,0 +1,96 @@
using System.Collections.Generic;
namespace Artemis.Utilities.GameSense.JsonModels
{
public class CounterStrikeJson
{
public Provider provider { get; set; }
public Map map { get; set; }
public Round round { get; set; }
public Player player { get; set; }
public Auth auth { get; set; }
}
public class Provider
{
public string name { get; set; }
public int appid { get; set; }
public int version { get; set; }
public string steamid { get; set; }
public int timestamp { get; set; }
}
public class Map
{
public string name { get; set; }
public string phase { get; set; }
public int round { get; set; }
public Team_Ct team_ct { get; set; }
public Team_T team_t { get; set; }
}
public class Team_Ct
{
public int score { get; set; }
}
public class Team_T
{
public int score { get; set; }
}
public class Round
{
public string phase { get; set; }
}
public class Player
{
public string steamid { get; set; }
public string name { get; set; }
public string team { get; set; }
public string activity { get; set; }
public State state { get; set; }
public Dictionary<string, Weapon> weapons { get; set; }
public Match_Stats match_stats { get; set; }
}
public class State
{
public int health { get; set; }
public int armor { get; set; }
public bool helmet { get; set; }
public int flashed { get; set; }
public int smoked { get; set; }
public int burning { get; set; }
public int money { get; set; }
public int round_kills { get; set; }
public int round_killhs { get; set; }
}
public class Match_Stats
{
public int kills { get; set; }
public int assists { get; set; }
public int deaths { get; set; }
public int mvps { get; set; }
public int score { get; set; }
}
public class Weapon
{
public string name { get; set; }
public string paintkit { get; set; }
public string type { get; set; }
public string state { get; set; }
public int ammo_clip { get; set; }
public int ammo_clip_max { get; set; }
public int ammo_reserve { get; set; }
}
public class Auth
{
public string key1 { get; set; }
public string key2 { get; set; }
}
}

View File

@ -0,0 +1,18 @@
using System.Windows.Forms;
namespace Artemis.Utilities.Keyboard
{
public class Key
{
public Key(Keys keyCode, int posX, int posY)
{
KeyCode = keyCode;
PosX = posX;
PosY = posY;
}
public Keys KeyCode { get; set; }
public int PosX { get; set; }
public int PosY { get; set; }
}
}

View File

@ -0,0 +1,145 @@
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace Artemis.Utilities.Keyboard
{
public class KeyboardRectangle
{
private readonly BackgroundWorker _blinkWorker = new BackgroundWorker {WorkerSupportsCancellation = true};
private int _blinkDelay;
private List<Color> _colors;
private double _rotationProgress;
/// <summary>
/// Represents a Rectangle on the keyboard which can be drawn to a Bitmap
/// </summary>
/// <param name="scale">The scale on which the rect should be rendered (Higher means smoother rotation)</param>
/// <param name="x"></param>
/// <param name="y"></param>
/// <param name="width"></param>
/// <param name="height"></param>
/// <param name="colors">An array of colors the ColorBlend will use</param>
/// <param name="gradientMode"></param>
public KeyboardRectangle(int scale, int x, int y, int width, int height, List<Color> colors,
LinearGradientMode gradientMode)
{
Scale = scale;
X = x;
Y = y;
Width = width;
Height = height;
Colors = colors;
GradientMode = gradientMode;
Opacity = 255;
Rotate = false;
LoopSpeed = 1;
Visible = true;
_rotationProgress = 0;
_blinkWorker.DoWork += BlinkWorker_DoWork;
}
public int Scale { get; set; }
public byte Opacity { get; set; }
public int X { get; set; }
public int Y { get; set; }
public int Width { get; set; }
public int Height { get; set; }
public List<Color> Colors
{
get { return _colors; }
set
{
_colors = value;
// Make the list tilable so that we can loop it
_colors.AddRange(value);
_colors.Add(value.FirstOrDefault());
}
}
public LinearGradientMode GradientMode { get; set; }
public bool Rotate { get; set; }
public double LoopSpeed { get; set; }
public bool Visible { get; set; }
public KeyboardRectangle Clone()
{
return (KeyboardRectangle) MemberwiseClone();
}
public void StartBlink(int delay)
{
_blinkDelay = delay;
if (!_blinkWorker.IsBusy)
_blinkWorker.RunWorkerAsync();
}
public void StartBlink(int delay, int time)
{
StartBlink(delay);
Task.Factory.StartNew(() =>
{
Thread.Sleep(delay);
StopBlink();
});
}
public void StopBlink()
{
if (_blinkWorker.IsBusy)
_blinkWorker.CancelAsync();
}
private void BlinkWorker_DoWork(object sender, DoWorkEventArgs e)
{
while (!_blinkWorker.CancellationPending)
{
Thread.Sleep(_blinkDelay);
Visible = !Visible;
}
Visible = true;
}
public void Draw(Graphics g)
{
if (!Visible || Height < 1 || Width < 1 || Colors.Count < 1)
return;
var colorBlend = new ColorBlend {Colors = Colors.ToArray()};
if (Opacity < 255)
for (var i = 0; i < colorBlend.Colors.Length; i++)
colorBlend.Colors[i] = Color.FromArgb(Opacity, colorBlend.Colors[i]);
var devider = (float) Colors.Count - 1;
var positions = new List<float>();
for (var i = 0; i < Colors.Count; i++)
positions.Add(i/devider);
colorBlend.Positions = positions.ToArray();
var baseRect = new Rectangle(X, Y, Width, Height);
var brushRect = new Rectangle((int) _rotationProgress, Y, baseRect.Width*2, baseRect.Height*2);
var baseBrush = new LinearGradientBrush(brushRect, Colors.First(), Colors.Last(), GradientMode)
{InterpolationColors = colorBlend};
g.FillRectangle(baseBrush, baseRect);
if (!Rotate)
return;
_rotationProgress = _rotationProgress + LoopSpeed;
if (_rotationProgress > Width)
_rotationProgress = LoopSpeed;
}
}
}

View File

@ -0,0 +1,425 @@
using System;
using System.Diagnostics;
using System.Text.RegularExpressions;
namespace Artemis.Utilities.Memory
{
/// <summary>
/// Represents an access to a remote process memory
/// </summary>
public class Memory : IDisposable
{
public const string OffsetPattern = "(\\+|\\-){0,1}(0x){0,1}[a-fA-F0-9]{1,}";
private bool isDisposed;
private IntPtr processHandle;
/// <summary>
/// Initializes a new instance of the Memory
/// </summary>
/// <param name="process">Remote process</param>
public Memory(Process process)
{
if (process == null)
throw new ArgumentNullException("process");
Process = process;
processHandle = Win32.OpenProcess(
Win32.ProcessAccessType.PROCESS_VM_READ | Win32.ProcessAccessType.PROCESS_VM_WRITE |
Win32.ProcessAccessType.PROCESS_VM_OPERATION, true, (uint) process.Id);
if (processHandle == IntPtr.Zero)
throw new InvalidOperationException("Could not open the process");
}
#region Properties
/// <summary>
/// Gets the process to which this memory is attached to
/// </summary>
public Process Process { get; private set; }
#endregion
/// <summary>
/// Finds module with the given name
/// </summary>
/// <param name="name">Module name</param>
/// <returns></returns>
protected ProcessModule FindModule(string name)
{
if (string.IsNullOrEmpty(name))
throw new ArgumentNullException("name");
foreach (ProcessModule module in Process.Modules)
{
if (module.ModuleName.ToLower() == name.ToLower())
return module;
}
return null;
}
/// <summary>
/// Gets module based address
/// </summary>
/// <param name="moduleName">Module name</param>
/// <param name="baseAddress">Base address</param>
/// <param name="offsets">Collection of offsets</param>
/// <returns></returns>
public IntPtr GetAddress(string moduleName, IntPtr baseAddress, int[] offsets)
{
if (string.IsNullOrEmpty(moduleName))
throw new ArgumentNullException("moduleName");
var module = FindModule(moduleName);
if (module == null)
return IntPtr.Zero;
var address = module.BaseAddress.ToInt32() + baseAddress.ToInt32();
return GetAddress((IntPtr) address, offsets);
}
/// <summary>
/// Gets module based address
/// </summary>
/// <param name="moduleName">Module name</param>
/// <param name="baseAddress">Base address</param>
/// <param name="offsets">Collection of offsets</param>
/// <returns></returns>
public IntPtr GetAddressX64(string moduleName, IntPtr baseAddress, int[] offsets)
{
if (string.IsNullOrEmpty(moduleName))
throw new ArgumentNullException("moduleName");
var module = FindModule(moduleName);
if (module == null)
return IntPtr.Zero;
var address = module.BaseAddress.ToInt64() + baseAddress.ToInt64();
return GetAddressX64((IntPtr) address, offsets);
}
/// <summary>
/// Gets address
/// </summary>
/// <param name="baseAddress">Base address</param>
/// <param name="offsets">Collection of offsets</param>
/// <returns></returns>
public IntPtr GetAddress(IntPtr baseAddress, int[] offsets)
{
if (baseAddress == IntPtr.Zero)
throw new ArgumentException("Invalid base address");
var address = baseAddress.ToInt32();
if (offsets != null && offsets.Length > 0)
{
var buffer = new byte[4];
foreach (var offset in offsets)
address = ReadInt32((IntPtr) address) + offset;
}
return (IntPtr) address;
}
/// <summary>
/// Gets address
/// </summary>
/// <param name="baseAddress">Base address</param>
/// <param name="offsets">Collection of offsets</param>
/// <returns></returns>
public IntPtr GetAddressX64(IntPtr baseAddress, int[] offsets)
{
if (baseAddress == IntPtr.Zero)
throw new ArgumentException("Invalid base address");
var address = baseAddress.ToInt64();
if (offsets != null && offsets.Length > 0)
{
var buffer = new byte[4];
foreach (var offset in offsets)
address = ReadInt32((IntPtr) address) + offset;
}
return (IntPtr) address;
}
/// <summary>
/// Gets address pointer
/// </summary>
/// <param name="address">Address</param>
/// <returns></returns>
public IntPtr GetAddressX64(string address)
{
if (string.IsNullOrEmpty(address))
throw new ArgumentNullException("address");
string moduleName = null;
var index = address.IndexOf('"');
if (index != -1)
{
// Module name at the beginning
var endIndex = address.IndexOf('"', index + 1);
if (endIndex == -1)
throw new ArgumentException("Invalid module name. Could not find matching \"");
moduleName = address.Substring(index + 1, endIndex - 1);
address = address.Substring(endIndex + 1);
}
var offsets = GetAddressOffsets(address);
int[] _offsets = null;
var baseAddress = offsets != null && offsets.Length > 0
? (IntPtr) offsets[0]
: IntPtr.Zero;
if (offsets != null && offsets.Length > 1)
{
_offsets = new int[offsets.Length - 1];
for (var i = 0; i < offsets.Length - 1; i++)
_offsets[i] = offsets[i + 1];
}
if (moduleName != null)
return GetAddressX64(moduleName, baseAddress, _offsets);
return GetAddressX64(baseAddress, _offsets);
}
/// <summary>
/// Gets address pointer
/// </summary>
/// <param name="address">Address</param>
/// <returns></returns>
public IntPtr GetAddress(string address)
{
if (string.IsNullOrEmpty(address))
throw new ArgumentNullException("address");
string moduleName = null;
var index = address.IndexOf('"');
if (index != -1)
{
// Module name at the beginning
var endIndex = address.IndexOf('"', index + 1);
if (endIndex == -1)
throw new ArgumentException("Invalid module name. Could not find matching \"");
moduleName = address.Substring(index + 1, endIndex - 1);
address = address.Substring(endIndex + 1);
}
var offsets = GetAddressOffsets(address);
int[] _offsets = null;
var baseAddress = offsets != null && offsets.Length > 0
? (IntPtr) offsets[0]
: IntPtr.Zero;
if (offsets != null && offsets.Length > 1)
{
_offsets = new int[offsets.Length - 1];
for (var i = 0; i < offsets.Length - 1; i++)
_offsets[i] = offsets[i + 1];
}
if (moduleName != null)
return GetAddress(moduleName, baseAddress, _offsets);
return GetAddress(baseAddress, _offsets);
}
/// <summary>
/// Gets address offsets
/// </summary>
/// <param name="address">Address</param>
/// <returns></returns>
protected static int[] GetAddressOffsets(string address)
{
if (string.IsNullOrEmpty(address))
return new int[0];
var matches = Regex.Matches(address, OffsetPattern);
var offsets = new int[matches.Count];
string value;
char ch;
for (var i = 0; i < matches.Count; i++)
{
ch = matches[i].Value[0];
if (ch == '+' || ch == '-')
value = matches[i].Value.Substring(1);
else
value = matches[i].Value;
offsets[i] = Convert.ToInt32(value, 16);
if (ch == '-')
offsets[i] = -offsets[i];
}
return offsets;
}
/// <summary>
/// Reads memory at the address
/// </summary>
/// <param name="address">Memory address</param>
/// <param name="buffer">Buffer</param>
/// <param name="size">Size in bytes</param>
public void ReadMemory(IntPtr address, byte[] buffer, int size)
{
if (isDisposed)
throw new ObjectDisposedException("Memory");
if (buffer == null)
throw new ArgumentNullException("buffer");
if (size <= 0)
throw new ArgumentException("Size must be greater than zero");
if (address == IntPtr.Zero)
throw new ArgumentException("Invalid address");
uint read = 0;
Win32.ReadProcessMemory(processHandle, address, buffer, (uint) size, ref read);
}
/// <summary>
/// Writes memory at the address
/// </summary>
/// <param name="address">Memory address</param>
/// <param name="buffer">Buffer</param>
/// <param name="size">Size in bytes</param>
public void WriteMemory(IntPtr address, byte[] buffer, int size)
{
if (isDisposed)
throw new ObjectDisposedException("Memory");
if (buffer == null)
throw new ArgumentNullException("buffer");
if (size <= 0)
throw new ArgumentException("Size must be greater than zero");
if (address == IntPtr.Zero)
throw new ArgumentException("Invalid address");
uint write = 0;
if (!Win32.WriteProcessMemory(processHandle, address, buffer, (uint) size, ref write) ||
write != size)
throw new AccessViolationException();
}
/// <summary>
/// Reads 32 bit signed integer at the address
/// </summary>
/// <param name="address">Memory address</param>
/// <returns></returns>
public int ReadInt32(IntPtr address)
{
var buffer = new byte[4];
ReadMemory(address, buffer, 4);
return BitConverter.ToInt32(buffer, 0);
}
/// <summary>
/// Reads 32 bit signed integer at the address
/// </summary>
/// <param name="address">Memory address</param>
/// <returns></returns>
public long ReadInt64(IntPtr address)
{
var buffer = new byte[8];
ReadMemory(address, buffer, 8);
return BitConverter.ToInt64(buffer, 0);
}
/// <summary>
/// Reads 32 bit unsigned integer at the address
/// </summary>
/// <param name="address">Memory address</param>
/// <returns></returns>
public uint ReadUInt32(IntPtr address)
{
var buffer = new byte[4];
ReadMemory(address, buffer, 4);
return BitConverter.ToUInt32(buffer, 0);
}
/// <summary>
/// Reads single precision value at the address
/// </summary>
/// <param name="address">Memory address</param>
/// <returns></returns>
public float ReadFloat(IntPtr address)
{
var buffer = new byte[4];
ReadMemory(address, buffer, 4);
return BitConverter.ToSingle(buffer, 0);
}
/// <summary>
/// Reads double precision value at the address
/// </summary>
/// <param name="address">Memory address</param>
/// <returns></returns>
public double ReadDouble(IntPtr address)
{
var buffer = new byte[8];
ReadMemory(address, buffer, 8);
return BitConverter.ToDouble(buffer, 0);
}
/// <summary>
/// Writes 32 bit unsigned integer at the address
/// </summary>
/// <param name="address">Memory address</param>
/// <param name="value">Value</param>
/// <returns></returns>
public void WriteUInt32(IntPtr address, uint value)
{
var buffer = BitConverter.GetBytes(value);
WriteMemory(address, buffer, 4);
}
/// <summary>
/// Writes 32 bit signed integer at the address
/// </summary>
/// <param name="address">Memory address</param>
/// <param name="value">Value</param>
/// <returns></returns>
public void WriteInt32(IntPtr address, int value)
{
var buffer = BitConverter.GetBytes(value);
WriteMemory(address, buffer, 4);
}
/// <summary>
/// Writes single precision value at the address
/// </summary>
/// <param name="address">Memory address</param>
/// <param name="value">Value</param>
/// <returns></returns>
public void WriteFloat(IntPtr address, float value)
{
var buffer = BitConverter.GetBytes(value);
WriteMemory(address, buffer, 4);
}
/// <summary>
/// Writes double precision value at the address
/// </summary>
/// <param name="address">Memory address</param>
/// <param name="value">Value</param>
/// <returns></returns>
public void WriteDouble(IntPtr address, double value)
{
var buffer = BitConverter.GetBytes(value);
WriteMemory(address, buffer, 8);
}
#region IDisposable
~Memory()
{
Dispose(false);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing)
{
if (isDisposed)
return;
Win32.CloseHandle(processHandle);
Process = null;
processHandle = IntPtr.Zero;
isDisposed = true;
}
#endregion
}
}

View File

@ -0,0 +1,41 @@
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace Artemis.Utilities.Memory
{
public static class MemoryHelpers
{
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, [Out] byte[] lpBuffer,
int dwSize, ref int lpNumberOfBytesRead);
public static Process GetProcessIfRunning(string processName)
{
var rlProcess = Process.GetProcessesByName(processName);
return rlProcess.Length >= 1 ? rlProcess[0] : null;
}
public static IntPtr FindAddress(IntPtr pHandle, IntPtr baseAddress, IntPtr staticPointer, int[] offsets)
{
// Create a buffer that is 4 bytes on a 32-bit system or 8 bytes on a 64-bit system.
var tmp = new byte[IntPtr.Size];
var address = baseAddress;
// We must check for 32-bit vs 64-bit.
address = IntPtr.Size == 4
? new IntPtr(address.ToInt32() + staticPointer.ToInt32())
: new IntPtr(address.ToInt64() + staticPointer.ToInt64());
// Loop through each offset to find the address
foreach (IntPtr t in offsets)
{
var lpNumberOfBytesRead = 0;
ReadProcessMemory(pHandle, address, tmp, IntPtr.Size, ref lpNumberOfBytesRead);
address = IntPtr.Size == 4
? new IntPtr(BitConverter.ToInt32(tmp, 0) + t.ToInt32())
: new IntPtr(BitConverter.ToInt64(tmp, 0) + t.ToInt64());
}
return address;
}
}
}

View File

@ -0,0 +1,43 @@
using System;
using System.Runtime.InteropServices;
namespace Artemis.Utilities.Memory
{
/// <summary>
/// Win32 methods
/// </summary>
public static class Win32
{
[Flags]
public enum ProcessAccessType
{
PROCESS_TERMINATE = (0x0001),
PROCESS_CREATE_THREAD = (0x0002),
PROCESS_SET_SESSIONID = (0x0004),
PROCESS_VM_OPERATION = (0x0008),
PROCESS_VM_READ = (0x0010),
PROCESS_VM_WRITE = (0x0020),
PROCESS_DUP_HANDLE = (0x0040),
PROCESS_CREATE_PROCESS = (0x0080),
PROCESS_SET_QUOTA = (0x0100),
PROCESS_SET_INFORMATION = (0x0200),
PROCESS_QUERY_INFORMATION = (0x0400)
}
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool WriteProcessMemory(
IntPtr process, IntPtr address, byte[] buffer, uint size, ref uint written);
[DllImport("Kernel32.dll", SetLastError = true)]
public static extern bool ReadProcessMemory(
IntPtr process, IntPtr address, byte[] buffer, uint size, ref uint read);
[DllImport("kernel32.dll")]
public static extern IntPtr OpenProcess(
[MarshalAs(UnmanagedType.U4)] ProcessAccessType access,
[MarshalAs(UnmanagedType.Bool)] bool inheritHandler, uint processId);
[DllImport("kernel32.dll")]
public static extern int CloseHandle(IntPtr objectHandle);
}
}

View File

@ -0,0 +1,20 @@
using Artemis.Models;
using Artemis.Modules.Effects.AudioVisualizer;
using Artemis.Modules.Effects.Debug;
using Artemis.Modules.Effects.TypeHole;
using Artemis.Modules.Effects.TypeWave;
using Caliburn.Micro;
namespace Artemis.ViewModels
{
public class EffectsViewModel : Conductor<IScreen>.Collection.OneActive
{
public EffectsViewModel(MainModel mainModel)
{
ActivateItem(new TypeWaveViewModel(mainModel) {DisplayName = "Type Waves"});
ActivateItem(new TypeHoleViewModel(mainModel) {DisplayName = "Type Holes (NYI)"});
ActivateItem(new AudioVisualizerViewModel(mainModel) {DisplayName = "Audio Visualization"});
ActivateItem(new DebugEffectViewModel(mainModel) {DisplayName = "Debug Effect"});
}
}
}

View File

@ -0,0 +1,20 @@
using Artemis.Models;
using Artemis.Modules.Games.CounterStrike;
using Artemis.Modules.Games.Dota2;
using Artemis.Modules.Games.RocketLeague;
using Artemis.Modules.Games.Witcher3;
using Caliburn.Micro;
namespace Artemis.ViewModels
{
public class GamesViewModel : Conductor<IScreen>.Collection.OneActive
{
public GamesViewModel(MainModel mainModel)
{
ActivateItem(new RocketLeagueViewModel(mainModel) {DisplayName = "Rocket League"});
ActivateItem(new CounterStrikeViewModel(mainModel) {DisplayName = "CS:GO (NYI)"});
ActivateItem(new Dota2ViewModel(mainModel) {DisplayName = "Dota 2 (NYI)"});
ActivateItem(new Witcher3ViewModel(mainModel) {DisplayName = "The Witcher 3"});
}
}
}

View File

@ -0,0 +1,14 @@
using Artemis.Models;
using Artemis.Modules.Overlays.VolumeDisplay;
using Caliburn.Micro;
namespace Artemis.ViewModels
{
public class OverlaysViewModel : Conductor<IScreen>.Collection.OneActive
{
public OverlaysViewModel(MainModel mainModel)
{
ActivateItem(new VolumeDisplayViewModel(mainModel) {DisplayName = "Volume Display"});
}
}
}

View File

@ -0,0 +1,53 @@
using System;
using System.Windows;
using Artemis.Models;
using Caliburn.Micro;
namespace Artemis.ViewModels
{
internal sealed class ShellViewModel : Conductor<IScreen>.Collection.OneActive
{
public ShellViewModel()
{
IEventAggregator events = new EventAggregator();
MainModel = new MainModel(events);
DisplayName = "Artemis";
ActivateItem(new EffectsViewModel(MainModel) {DisplayName = "Effects"});
ActivateItem(new GamesViewModel(MainModel) {DisplayName = "Games"});
ActivateItem(new OverlaysViewModel(MainModel) {DisplayName = "Overlays"});
// By now Effects are added to the MainModel so we can savely start one
ToggleEffects();
}
public bool EffectsEnabled
{
get { return MainModel.Enabled; }
private set
{
MainModel.Enabled = value;
NotifyOfPropertyChange(() => EffectsEnabled);
}
}
public MainModel MainModel { get; set; }
public void ToggleEffects()
{
if (EffectsEnabled)
MainModel.ShutdownEffects();
else
MainModel.StartEffects();
EffectsEnabled = !EffectsEnabled;
}
public void OnClose(EventArgs e)
{
MainModel.ShutdownEffects();
Application.Current.Shutdown();
}
}
}

View File

@ -0,0 +1,20 @@
<UserControl x:Class="Artemis.Views.EffectsView"
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"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<TabControl Margin="0,10" x:Name="Items" controls:TabControlHelper.IsUnderlined="True">
<TabControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding DisplayName}" FontSize="18" />
</StackPanel>
</DataTemplate>
</TabControl.ItemTemplate>
</TabControl>
</UserControl>

View File

@ -0,0 +1,15 @@
using System.Windows.Controls;
namespace Artemis.Views
{
/// <summary>
/// Interaction logic for EffectsView.xaml
/// </summary>
public partial class EffectsView : UserControl
{
public EffectsView()
{
InitializeComponent();
}
}
}

View File

@ -0,0 +1,19 @@
<UserControl x:Class="Artemis.Views.GamesView"
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"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<TabControl Margin="0,10" x:Name="Items" controls:TabControlHelper.IsUnderlined="True">
<TabControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding DisplayName}" FontSize="18" />
</StackPanel>
</DataTemplate>
</TabControl.ItemTemplate>
</TabControl>
</UserControl>

View File

@ -0,0 +1,15 @@
using System.Windows.Controls;
namespace Artemis.Views
{
/// <summary>
/// Interaction logic for GamesView.xaml
/// </summary>
public partial class GamesView : UserControl
{
public GamesView()
{
InitializeComponent();
}
}
}

View File

@ -0,0 +1,19 @@
<UserControl x:Class="Artemis.Views.OverlaysView"
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"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<TabControl Margin="0,10" x:Name="Items" controls:TabControlHelper.IsUnderlined="True">
<TabControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding DisplayName}" FontSize="18" />
</StackPanel>
</DataTemplate>
</TabControl.ItemTemplate>
</TabControl>
</UserControl>

View File

@ -0,0 +1,15 @@
using System.Windows.Controls;
namespace Artemis.Views
{
/// <summary>
/// Interaction logic for OverlaysView.xaml
/// </summary>
public partial class OverlaysView : UserControl
{
public OverlaysView()
{
InitializeComponent();
}
}
}

Some files were not shown because too many files have changed in this diff Show More