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

Added Overwatch module, progress on MMF with C++

This commit is contained in:
SpoinkyNL 2016-05-28 23:32:41 +02:00
parent c80c87dce7
commit f1b7c667a7
15 changed files with 377 additions and 31 deletions

View File

@ -15,8 +15,8 @@ namespace Artemis
{ {
public App() public App()
{ {
if (!IsRunAsAdministrator()) //if (!IsRunAsAdministrator())
GeneralHelpers.RunAsAdministrator(); // GeneralHelpers.RunAsAdministrator();
InitializeComponent(); InitializeComponent();
} }

View File

@ -359,6 +359,9 @@
<Compile Include="Modules\Games\Dota2\Dota2DataModel.cs" /> <Compile Include="Modules\Games\Dota2\Dota2DataModel.cs" />
<Compile Include="Modules\Games\Dota2\Dota2Model.cs" /> <Compile Include="Modules\Games\Dota2\Dota2Model.cs" />
<Compile Include="Modules\Games\Dota2\Dota2Settings.cs" /> <Compile Include="Modules\Games\Dota2\Dota2Settings.cs" />
<Compile Include="Modules\Games\Overwatch\OverwatchView.xaml.cs">
<DependentUpon>OverwatchView.xaml</DependentUpon>
</Compile>
<Compile Include="Modules\Games\RocketLeague\RocketLeague.Designer.cs"> <Compile Include="Modules\Games\RocketLeague\RocketLeague.Designer.cs">
<DependentUpon>RocketLeague.settings</DependentUpon> <DependentUpon>RocketLeague.settings</DependentUpon>
<AutoGen>True</AutoGen> <AutoGen>True</AutoGen>
@ -378,6 +381,15 @@
<DependentUpon>TheDivisionView.xaml</DependentUpon> <DependentUpon>TheDivisionView.xaml</DependentUpon>
</Compile> </Compile>
<Compile Include="Modules\Games\TheDivision\TheDivisionViewModel.cs" /> <Compile Include="Modules\Games\TheDivision\TheDivisionViewModel.cs" />
<Compile Include="Modules\Games\Overwatch\OverwatchDataModel.cs" />
<Compile Include="Modules\Games\Overwatch\Overwatch.Designer.cs">
<DependentUpon>Overwatch.settings</DependentUpon>
<AutoGen>True</AutoGen>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
<Compile Include="Modules\Games\Overwatch\OverwatchModel.cs" />
<Compile Include="Modules\Games\Overwatch\OverwatchSettings.cs" />
<Compile Include="Modules\Games\Overwatch\OverwatchViewModel.cs" />
<Compile Include="Modules\Games\Witcher3\TheWitcherDataModel.cs" /> <Compile Include="Modules\Games\Witcher3\TheWitcherDataModel.cs" />
<Compile Include="Modules\Games\Witcher3\Witcher3DataModel.cs" /> <Compile Include="Modules\Games\Witcher3\Witcher3DataModel.cs" />
<Compile Include="Modules\Games\Witcher3\Witcher3Settings.cs" /> <Compile Include="Modules\Games\Witcher3\Witcher3Settings.cs" />
@ -582,6 +594,10 @@
<Generator>SettingsSingleFileGenerator</Generator> <Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>TheDivision.Designer.cs</LastGenOutput> <LastGenOutput>TheDivision.Designer.cs</LastGenOutput>
</None> </None>
<None Include="Modules\Games\Overwatch\Overwatch.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Overwatch.Designer.cs</LastGenOutput>
</None>
<None Include="Modules\Games\Witcher3\Witcher3.settings"> <None Include="Modules\Games\Witcher3\Witcher3.settings">
<Generator>SettingsSingleFileGenerator</Generator> <Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Witcher3.Designer.cs</LastGenOutput> <LastGenOutput>Witcher3.Designer.cs</LastGenOutput>
@ -637,6 +653,10 @@
<SubType>Designer</SubType> <SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
</Page> </Page>
<Page Include="Modules\Games\Overwatch\OverwatchView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Modules\Games\TheDivision\TheDivisionView.xaml"> <Page Include="Modules\Games\TheDivision\TheDivisionView.xaml">
<SubType>Designer</SubType> <SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>

View File

@ -20,7 +20,7 @@ namespace Artemis
public ArtemisBootstrapper() public ArtemisBootstrapper()
{ {
CheckDuplicateInstances(); //CheckDuplicateInstances();
Initialize(); Initialize();
BindSpecialValues(); BindSpecialValues();
} }

View File

@ -7,6 +7,7 @@ using Artemis.Modules.Effects.Debug;
using Artemis.Modules.Effects.TypeWave; using Artemis.Modules.Effects.TypeWave;
using Artemis.Modules.Games.CounterStrike; using Artemis.Modules.Games.CounterStrike;
using Artemis.Modules.Games.Dota2; using Artemis.Modules.Games.Dota2;
using Artemis.Modules.Games.Overwatch;
using Artemis.Modules.Games.RocketLeague; using Artemis.Modules.Games.RocketLeague;
using Artemis.Modules.Games.TheDivision; using Artemis.Modules.Games.TheDivision;
using Artemis.Modules.Games.Witcher3; using Artemis.Modules.Games.Witcher3;
@ -34,6 +35,7 @@ namespace Artemis.InjectionModules
Bind<GameViewModel>().To<RocketLeagueViewModel>().InSingletonScope(); Bind<GameViewModel>().To<RocketLeagueViewModel>().InSingletonScope();
Bind<GameViewModel>().To<TheDivisionViewModel>().InSingletonScope(); Bind<GameViewModel>().To<TheDivisionViewModel>().InSingletonScope();
Bind<GameViewModel>().To<Witcher3ViewModel>().InSingletonScope(); Bind<GameViewModel>().To<Witcher3ViewModel>().InSingletonScope();
Bind<GameViewModel>().To<OverwatchViewModel>().InSingletonScope();
// Overlays // Overlays
Bind<OverlayViewModel>().To<VolumeDisplayViewModel>().InSingletonScope(); Bind<OverlayViewModel>().To<VolumeDisplayViewModel>().InSingletonScope();

View File

@ -0,0 +1,38 @@
//------------------------------------------------------------------------------
// <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.Modules.Games.Overwatch {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "14.0.0.0")]
internal sealed partial class Overwatch : global::System.Configuration.ApplicationSettingsBase {
private static Overwatch defaultInstance = ((Overwatch)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Overwatch())));
public static Overwatch Default {
get {
return defaultInstance;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("True")]
public bool Enabled {
get {
return ((bool)(this["Enabled"]));
}
set {
this["Enabled"] = value;
}
}
}
}

View File

@ -0,0 +1,11 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)"
GeneratedClassNamespace="Artemis.Modules.Games.Witcher3" GeneratedClassName="Witcher3">
<Profiles />
<Settings>
<Setting Name="Enabled" Type="System.Boolean" Scope="User">
<Value Profile="(Default)">True</Value>
</Setting>
</Settings>
</SettingsFile>

View File

@ -0,0 +1,8 @@
using Artemis.Models.Interfaces;
namespace Artemis.Modules.Games.Overwatch
{
public class OverwatchDataModel : IGameDataModel
{
}
}

View File

@ -0,0 +1,94 @@
using System.Drawing;
using System.IO;
using System.IO.MemoryMappedFiles;
using Artemis.Managers;
using Artemis.Models;
using Artemis.Models.Profiles;
using Brush = System.Windows.Media.Brush;
namespace Artemis.Modules.Games.Overwatch
{
public class OverwatchModel : GameModel
{
public OverwatchModel(MainManager mainManager, OverwatchSettings settings)
: base(mainManager, settings, new OverwatchDataModel())
{
Name = "Overwatch";
ProcessName = "notepad";
Scale = 4;
Enabled = Settings.Enabled;
Initialized = false;
}
public int Scale { get; set; }
public override void Dispose()
{
Initialized = false;
}
public override void Enable()
{
Initialized = true;
}
public override void Update()
{
var gameDataModel = (OverwatchDataModel) GameDataModel;
var mffData = ReadMmf("overwatchMmf");
if (mffData == null)
return;
var data = mffData.Split(' ');
}
private string ReadMmf(string overwatchmff)
{
try
{
// opening not-persistent, pagefile-based memory-mapped file
using (var mmf = MemoryMappedFile.OpenExisting(overwatchmff))
{
// open the stream to read from the file
using (var stream = mmf.CreateViewStream())
{
// Read from the shared memory, just for this example we know there is a string
var reader = new BinaryReader(stream);
var res = string.Empty;
string str;
do
{
str = reader.ReadString();
if (!string.IsNullOrEmpty(str) && str[0] != 0)
res = res + str;
} while (!string.IsNullOrEmpty(str));
return res;
}
}
}
catch (FileNotFoundException)
{
return null;
//ignored
}
}
public override Bitmap GenerateBitmap()
{
if (Profile == null || GameDataModel == null)
return null;
var keyboardRect = MainManager.DeviceManager.ActiveKeyboard.KeyboardRectangle(Scale);
return Profile.GenerateBitmap<OverwatchDataModel>(keyboardRect, GameDataModel, false, true);
}
public override Brush GenerateMouseBrush()
{
return Profile?.GenerateBrush<OverwatchDataModel>(GameDataModel, LayerType.Mouse, false, true);
}
public override Brush GenerateHeadsetBrush()
{
return Profile?.GenerateBrush<OverwatchDataModel>(GameDataModel, LayerType.Headset, false, true);
}
}
}

View File

@ -0,0 +1,29 @@
using Artemis.Models;
namespace Artemis.Modules.Games.Overwatch
{
public class OverwatchSettings : GameSettings
{
public OverwatchSettings()
{
Load();
}
public sealed override void Load()
{
Enabled = Overwatch.Default.Enabled;
}
public sealed override void Save()
{
Overwatch.Default.Enabled = Enabled;
Overwatch.Default.Save();
}
public sealed override void ToDefault()
{
Enabled = true;
}
}
}

View File

@ -0,0 +1,54 @@
<UserControl x:Class="Artemis.Modules.Games.Overwatch.OverwatchView"
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"
mc:Ignorable="d"
d:DesignHeight="410.933" d:DesignWidth="732.154">
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto">
<Grid Margin="15, 5, 15, 5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" Margin="0,0,1,0">
<Label FontSize="20" HorizontalAlignment="Left">
<Label.Content>
<AccessText TextWrapping="Wrap"
Text="Allows you to create layers based on ingame cooldown and your hero." />
</Label.Content>
</Label>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
<Label Content="Enable effect" Margin="0 3 0 0" HorizontalAlignment="Right" />
<ToggleButton x:Name="EffectEnabled" Margin="0 3 0 0" Width="25" Height="25"
IsChecked="{Binding Path=GameSettings.Enabled, Mode=TwoWay}"
Style="{DynamicResource MetroCircleToggleButtonStyle}"
cal:Message.Attach="[Event Click] = [Action ToggleEffect]" />
</StackPanel>
</StackPanel>
<!-- Profile editor -->
<ContentControl Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="2" x:Name="ProfileEditor" Margin="0,0,-30,0" />
<!-- Buttons -->
<StackPanel Grid.Column="0" Grid.Row="9" Orientation="Horizontal" VerticalAlignment="Bottom">
<Button x:Name="ResetSettings" Content="Reset effect" VerticalAlignment="Top" Width="100"
Style="{DynamicResource SquareButtonStyle}" />
<Button x:Name="SaveSettings" Content="Save changes" VerticalAlignment="Top" Width="100"
Margin="10,0,0,0"
Style="{DynamicResource SquareButtonStyle}" />
</StackPanel>
</Grid>
</ScrollViewer>
</UserControl>

View File

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

View File

@ -0,0 +1,17 @@
using Artemis.InjectionFactories;
using Artemis.Managers;
using Artemis.ViewModels.Abstract;
using Caliburn.Micro;
namespace Artemis.Modules.Games.Overwatch
{
public sealed class OverwatchViewModel : GameViewModel
{
public OverwatchViewModel(MainManager main, IEventAggregator events, IProfileEditorViewModelFactory pFactory)
: base(main, new OverwatchModel(main, new OverwatchSettings()), events, pFactory)
{
DisplayName = "Overwatch";
MainManager.EffectManager.EffectModels.Add(GameModel);
}
}
}

View File

@ -49,6 +49,8 @@ namespace Artemis.Utilities.GameState
{ {
MessageBox.Show("Couldn't start the webserver. CS:GO/Dota2 effects won't work :c \n\n" + MessageBox.Show("Couldn't start the webserver. CS:GO/Dota2 effects won't work :c \n\n" +
"Try changing the port in Settings and restart Artemis."); "Try changing the port in Settings and restart Artemis.");
Running = false;
return;
} }
Running = true; Running = true;

View File

@ -42,12 +42,12 @@ namespace Artemis.Utilities.LogitechDll
while (Running) while (Running)
{ {
var namedPipeServerStream = new NamedPipeServerStream(_pipeName, PipeDirection.In, 100, var namedPipeServerStream = new NamedPipeServerStream(_pipeName, PipeDirection.In, 254,
PipeTransmissionMode.Byte, PipeOptions.None, 100, 100, security); PipeTransmissionMode.Byte, PipeOptions.None, 254, 254, security);
namedPipeServerStream.WaitForConnection(); namedPipeServerStream.WaitForConnection();
var buffer = new byte[100]; var buffer = new byte[254];
namedPipeServerStream.Read(buffer, 0, 100); namedPipeServerStream.Read(buffer, 0, 254);
namedPipeServerStream.Close(); namedPipeServerStream.Close();
var task = new Task(() => HandleMessage(buffer)); var task = new Task(() => HandleMessage(buffer));
@ -63,6 +63,7 @@ namespace Artemis.Utilities.LogitechDll
private void HandleMessage(byte[] buffer) private void HandleMessage(byte[] buffer)
{ {
var request = Encoding.ASCII.GetString(buffer); var request = Encoding.ASCII.GetString(buffer);
Debug.WriteLine(request);
PipeMessage?.Invoke(request); PipeMessage?.Invoke(request);
} }
@ -77,8 +78,8 @@ namespace Artemis.Utilities.LogitechDll
// Set to class level var so we can re-use in the async callback method // Set to class level var so we can re-use in the async callback method
_pipeName = pipeName; _pipeName = pipeName;
// Create the new async pipe // Create the new async pipe
var pipeServer = new NamedPipeServerStream(pipeName, PipeDirection.In, 100, PipeTransmissionMode.Byte, var pipeServer = new NamedPipeServerStream(pipeName, PipeDirection.In, 254, PipeTransmissionMode.Byte,
PipeOptions.Asynchronous, 100, 100, security); PipeOptions.Asynchronous, 254, 254, security);
// Wait for a connection // Wait for a connection
pipeServer.BeginWaitForConnection(WaitForConnectionCallBack, pipeServer); pipeServer.BeginWaitForConnection(WaitForConnectionCallBack, pipeServer);
@ -117,8 +118,8 @@ namespace Artemis.Utilities.LogitechDll
var sid = new SecurityIdentifier(WellKnownSidType.WorldSid, null); var sid = new SecurityIdentifier(WellKnownSidType.WorldSid, null);
security.AddAccessRule(new PipeAccessRule(sid, PipeAccessRights.FullControl, AccessControlType.Allow)); security.AddAccessRule(new PipeAccessRule(sid, PipeAccessRights.FullControl, AccessControlType.Allow));
pipeServer = new NamedPipeServerStream(_pipeName, PipeDirection.In, 100, PipeTransmissionMode.Byte, pipeServer = new NamedPipeServerStream(_pipeName, PipeDirection.In, 254, PipeTransmissionMode.Byte,
PipeOptions.Asynchronous, 100, 100, security); PipeOptions.Asynchronous, 254, 254, security);
// Recursively wait for the connection again and again.... // Recursively wait for the connection again and again....
pipeServer.BeginWaitForConnection(WaitForConnectionCallBack, pipeServer); pipeServer.BeginWaitForConnection(WaitForConnectionCallBack, pipeServer);

View File

@ -32,7 +32,11 @@
#include "Logger.h" #include "Logger.h"
#include <filesystem> #include <filesystem>
#include <sstream>
TCHAR szName[] = TEXT("overwatchMmf");
TCHAR szMsg[] = TEXT("Message from first process.");
#define BUF_SIZE 2000
static bool g_hasInitialised = false; static bool g_hasInitialised = false;
const char* game = ""; const char* game = "";
@ -42,41 +46,77 @@ void cleanup()
CLogger::EndLogging(); CLogger::EndLogging();
} }
HANDLE hMapFile;
BOOL WINAPI DllMain(HINSTANCE hInst, DWORD fdwReason, LPVOID) BOOL WINAPI DllMain(HINSTANCE hInst, DWORD fdwReason, LPVOID)
{ {
switch (fdwReason) switch (fdwReason)
{ {
case DLL_PROCESS_ATTACH: case DLL_PROCESS_ATTACH:
{ {
atexit(cleanup); atexit(cleanup);
CLogger::InitLogging("Log.txt"); CLogger::InitLogging("Log.txt");
CLogger::SetLogLevel(LogLevel::Debug); CLogger::SetLogLevel(LogLevel::Debug);
// Get the process that loaded the DLL // Get the process that loaded the DLL
TCHAR overwatchFind[] = _T("Overwatch"); TCHAR overwatchFind[] = _T("Overwatch");
TCHAR szPath[MAX_PATH]; TCHAR szPath[MAX_PATH];
GetModuleFileName(NULL, szPath, MAX_PATH); GetModuleFileName(nullptr, szPath, MAX_PATH);
if (_tcscmp(szPath, overwatchFind) != 0) if (_tcscmp(szPath, overwatchFind) != 0)
game = "overwatch"; game = "overwatch";
CLogger::OutputLog("Attached to process.", LogLevel::Debug); CLogger::OutputLog("Attached to process.", LogLevel::Debug);
}
break; // Setup mmf
hMapFile = CreateFileMapping(INVALID_HANDLE_VALUE, nullptr, PAGE_READWRITE, 0, BUF_SIZE, szName);
if (hMapFile == nullptr)
{
CLogger::OutputLog("Could not create file mapping object (error %i)", LogLevel::Debug, GetLastError());
}
}
break;
case DLL_PROCESS_DETACH: case DLL_PROCESS_DETACH:
{ {
cleanup(); CLogger::OutputLog_s("Detached from process.", LogLevel::Debug);
CloseHandle(hMapFile);
CLogger::OutputLog_s("Detached from process.", LogLevel::Debug); cleanup();
} }
break; break;
} }
return true; return true;
} }
void WriteMmf(const char* msg)
{
if (hMapFile == nullptr)
{
CLogger::OutputLog_s("Could not write to mmf", LogLevel::Debug);
return;
}
LPCTSTR pBuf;
pBuf = static_cast<LPTSTR>(MapViewOfFile(hMapFile, // handle to map object
FILE_MAP_ALL_ACCESS, // read/write permission
0,
0,
BUF_SIZE));
if (pBuf == nullptr)
{
CLogger::OutputLog("Could not map view of file (error %i)", LogLevel::Debug, GetLastError());
CloseHandle(hMapFile);
return;
}
CopyMemory((PVOID)pBuf, msg, (_tcslen(msg) * sizeof(TCHAR)));
UnmapViewOfFile(pBuf);
}
RZRESULT Init() RZRESULT Init()
{ {
CLogger::OutputLog_s("Razer Init called.", LogLevel::Debug); CLogger::OutputLog_s("Razer Init called.", LogLevel::Debug);
@ -98,7 +138,22 @@ RZRESULT CreateEffect(RZDEVICEID DeviceId, ChromaSDK::EFFECT_TYPE Effect, PRZPAR
RZRESULT CreateKeyboardEffect(ChromaSDK::Keyboard::EFFECT_TYPE Effect, PRZPARAM pParam, RZEFFECTID* pEffectId) RZRESULT CreateKeyboardEffect(ChromaSDK::Keyboard::EFFECT_TYPE Effect, PRZPARAM pParam, RZEFFECTID* pEffectId)
{ {
CLogger::OutputLog_s("Razer CreateKeyboardEffect called.", LogLevel::Debug); std::ostringstream os;
auto keys = *static_cast<struct CUSTOM_KEY_EFFECT_TYPE*>(pParam);
for (auto y = 0; y < 6; y++)
{
for (auto x = 0; x < 22; x++)
{
auto r = (int) GetRValue(keys.Color[y][x]);
auto g = (int) GetGValue(keys.Color[y][x]);
auto b = (int) GetGValue(keys.Color[y][x]);
os << " [" << x << "][" << y << "](" << r << "," << g << "," << b << ")";
}
}
CLogger::OutputLog_s("Razer CreateKeyboardEffect called", LogLevel::Debug);
WriteMmf(os.str().c_str());
return 0; return 0;
} }