diff --git a/Artemis/Artemis/App.xaml.cs b/Artemis/Artemis/App.xaml.cs
index e2b94fb9c..8b35c5e93 100644
--- a/Artemis/Artemis/App.xaml.cs
+++ b/Artemis/Artemis/App.xaml.cs
@@ -15,8 +15,8 @@ namespace Artemis
{
public App()
{
- if (!IsRunAsAdministrator())
- GeneralHelpers.RunAsAdministrator();
+ //if (!IsRunAsAdministrator())
+ // GeneralHelpers.RunAsAdministrator();
InitializeComponent();
}
diff --git a/Artemis/Artemis/Artemis.csproj b/Artemis/Artemis/Artemis.csproj
index 955cc87d2..632701d8b 100644
--- a/Artemis/Artemis/Artemis.csproj
+++ b/Artemis/Artemis/Artemis.csproj
@@ -359,6 +359,9 @@
+
+ OverwatchView.xaml
+
RocketLeague.settings
True
@@ -378,6 +381,15 @@
TheDivisionView.xaml
+
+
+ Overwatch.settings
+ True
+ True
+
+
+
+
@@ -582,6 +594,10 @@
SettingsSingleFileGenerator
TheDivision.Designer.cs
+
+ SettingsSingleFileGenerator
+ Overwatch.Designer.cs
+
SettingsSingleFileGenerator
Witcher3.Designer.cs
@@ -637,6 +653,10 @@
Designer
MSBuild:Compile
+
+ Designer
+ MSBuild:Compile
+
Designer
MSBuild:Compile
diff --git a/Artemis/Artemis/ArtemisBootstrapper.cs b/Artemis/Artemis/ArtemisBootstrapper.cs
index 52719ec46..116221d3c 100644
--- a/Artemis/Artemis/ArtemisBootstrapper.cs
+++ b/Artemis/Artemis/ArtemisBootstrapper.cs
@@ -20,7 +20,7 @@ namespace Artemis
public ArtemisBootstrapper()
{
- CheckDuplicateInstances();
+ //CheckDuplicateInstances();
Initialize();
BindSpecialValues();
}
diff --git a/Artemis/Artemis/InjectionModules/ArtemisModules.cs b/Artemis/Artemis/InjectionModules/ArtemisModules.cs
index 4f013698d..13f0c3772 100644
--- a/Artemis/Artemis/InjectionModules/ArtemisModules.cs
+++ b/Artemis/Artemis/InjectionModules/ArtemisModules.cs
@@ -7,6 +7,7 @@ using Artemis.Modules.Effects.Debug;
using Artemis.Modules.Effects.TypeWave;
using Artemis.Modules.Games.CounterStrike;
using Artemis.Modules.Games.Dota2;
+using Artemis.Modules.Games.Overwatch;
using Artemis.Modules.Games.RocketLeague;
using Artemis.Modules.Games.TheDivision;
using Artemis.Modules.Games.Witcher3;
@@ -34,6 +35,7 @@ namespace Artemis.InjectionModules
Bind().To().InSingletonScope();
Bind().To().InSingletonScope();
Bind().To().InSingletonScope();
+ Bind().To().InSingletonScope();
// Overlays
Bind().To().InSingletonScope();
diff --git a/Artemis/Artemis/Modules/Games/Overwatch/Overwatch.Designer.cs b/Artemis/Artemis/Modules/Games/Overwatch/Overwatch.Designer.cs
new file mode 100644
index 000000000..48ef16045
--- /dev/null
+++ b/Artemis/Artemis/Modules/Games/Overwatch/Overwatch.Designer.cs
@@ -0,0 +1,38 @@
+//------------------------------------------------------------------------------
+//
+// 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.
+//
+//------------------------------------------------------------------------------
+
+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;
+ }
+ }
+ }
+}
diff --git a/Artemis/Artemis/Modules/Games/Overwatch/Overwatch.settings b/Artemis/Artemis/Modules/Games/Overwatch/Overwatch.settings
new file mode 100644
index 000000000..adbc00bca
--- /dev/null
+++ b/Artemis/Artemis/Modules/Games/Overwatch/Overwatch.settings
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+ True
+
+
+
\ No newline at end of file
diff --git a/Artemis/Artemis/Modules/Games/Overwatch/OverwatchDataModel.cs b/Artemis/Artemis/Modules/Games/Overwatch/OverwatchDataModel.cs
new file mode 100644
index 000000000..12b9c2879
--- /dev/null
+++ b/Artemis/Artemis/Modules/Games/Overwatch/OverwatchDataModel.cs
@@ -0,0 +1,8 @@
+using Artemis.Models.Interfaces;
+
+namespace Artemis.Modules.Games.Overwatch
+{
+ public class OverwatchDataModel : IGameDataModel
+ {
+ }
+}
\ No newline at end of file
diff --git a/Artemis/Artemis/Modules/Games/Overwatch/OverwatchModel.cs b/Artemis/Artemis/Modules/Games/Overwatch/OverwatchModel.cs
new file mode 100644
index 000000000..cbcab9824
--- /dev/null
+++ b/Artemis/Artemis/Modules/Games/Overwatch/OverwatchModel.cs
@@ -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(keyboardRect, GameDataModel, false, true);
+ }
+
+ public override Brush GenerateMouseBrush()
+ {
+ return Profile?.GenerateBrush(GameDataModel, LayerType.Mouse, false, true);
+ }
+
+ public override Brush GenerateHeadsetBrush()
+ {
+ return Profile?.GenerateBrush(GameDataModel, LayerType.Headset, false, true);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Artemis/Artemis/Modules/Games/Overwatch/OverwatchSettings.cs b/Artemis/Artemis/Modules/Games/Overwatch/OverwatchSettings.cs
new file mode 100644
index 000000000..bb21734fb
--- /dev/null
+++ b/Artemis/Artemis/Modules/Games/Overwatch/OverwatchSettings.cs
@@ -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;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Artemis/Artemis/Modules/Games/Overwatch/OverwatchView.xaml b/Artemis/Artemis/Modules/Games/Overwatch/OverwatchView.xaml
new file mode 100644
index 000000000..c999b204f
--- /dev/null
+++ b/Artemis/Artemis/Modules/Games/Overwatch/OverwatchView.xaml
@@ -0,0 +1,54 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Artemis/Artemis/Modules/Games/Overwatch/OverwatchView.xaml.cs b/Artemis/Artemis/Modules/Games/Overwatch/OverwatchView.xaml.cs
new file mode 100644
index 000000000..be25055fc
--- /dev/null
+++ b/Artemis/Artemis/Modules/Games/Overwatch/OverwatchView.xaml.cs
@@ -0,0 +1,15 @@
+using System.Windows.Controls;
+
+namespace Artemis.Modules.Games.Overwatch
+{
+ ///
+ /// Interaction logic for OverwatchView.xaml
+ ///
+ public partial class OverwatchView : UserControl
+ {
+ public OverwatchView()
+ {
+ InitializeComponent();
+ }
+ }
+}
\ No newline at end of file
diff --git a/Artemis/Artemis/Modules/Games/Overwatch/OverwatchViewModel.cs b/Artemis/Artemis/Modules/Games/Overwatch/OverwatchViewModel.cs
new file mode 100644
index 000000000..df080abfa
--- /dev/null
+++ b/Artemis/Artemis/Modules/Games/Overwatch/OverwatchViewModel.cs
@@ -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);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Artemis/Artemis/Utilities/GameState/GameStateWebServer.cs b/Artemis/Artemis/Utilities/GameState/GameStateWebServer.cs
index 151cfa7de..edd96c1e2 100644
--- a/Artemis/Artemis/Utilities/GameState/GameStateWebServer.cs
+++ b/Artemis/Artemis/Utilities/GameState/GameStateWebServer.cs
@@ -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" +
"Try changing the port in Settings and restart Artemis.");
+ Running = false;
+ return;
}
Running = true;
diff --git a/Artemis/Artemis/Utilities/LogitechDll/PipeServer.cs b/Artemis/Artemis/Utilities/LogitechDll/PipeServer.cs
index bb0ac497e..66bd751ee 100644
--- a/Artemis/Artemis/Utilities/LogitechDll/PipeServer.cs
+++ b/Artemis/Artemis/Utilities/LogitechDll/PipeServer.cs
@@ -42,12 +42,12 @@ namespace Artemis.Utilities.LogitechDll
while (Running)
{
- var namedPipeServerStream = new NamedPipeServerStream(_pipeName, PipeDirection.In, 100,
- PipeTransmissionMode.Byte, PipeOptions.None, 100, 100, security);
+ var namedPipeServerStream = new NamedPipeServerStream(_pipeName, PipeDirection.In, 254,
+ PipeTransmissionMode.Byte, PipeOptions.None, 254, 254, security);
namedPipeServerStream.WaitForConnection();
- var buffer = new byte[100];
- namedPipeServerStream.Read(buffer, 0, 100);
+ var buffer = new byte[254];
+ namedPipeServerStream.Read(buffer, 0, 254);
namedPipeServerStream.Close();
var task = new Task(() => HandleMessage(buffer));
@@ -63,6 +63,7 @@ namespace Artemis.Utilities.LogitechDll
private void HandleMessage(byte[] buffer)
{
var request = Encoding.ASCII.GetString(buffer);
+ Debug.WriteLine(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
_pipeName = pipeName;
// Create the new async pipe
- var pipeServer = new NamedPipeServerStream(pipeName, PipeDirection.In, 100, PipeTransmissionMode.Byte,
- PipeOptions.Asynchronous, 100, 100, security);
+ var pipeServer = new NamedPipeServerStream(pipeName, PipeDirection.In, 254, PipeTransmissionMode.Byte,
+ PipeOptions.Asynchronous, 254, 254, security);
// Wait for a connection
pipeServer.BeginWaitForConnection(WaitForConnectionCallBack, pipeServer);
@@ -117,8 +118,8 @@ namespace Artemis.Utilities.LogitechDll
var sid = new SecurityIdentifier(WellKnownSidType.WorldSid, null);
security.AddAccessRule(new PipeAccessRule(sid, PipeAccessRights.FullControl, AccessControlType.Allow));
- pipeServer = new NamedPipeServerStream(_pipeName, PipeDirection.In, 100, PipeTransmissionMode.Byte,
- PipeOptions.Asynchronous, 100, 100, security);
+ pipeServer = new NamedPipeServerStream(_pipeName, PipeDirection.In, 254, PipeTransmissionMode.Byte,
+ PipeOptions.Asynchronous, 254, 254, security);
// Recursively wait for the connection again and again....
pipeServer.BeginWaitForConnection(WaitForConnectionCallBack, pipeServer);
diff --git a/Artemis/Razer2Artemis/main.cpp b/Artemis/Razer2Artemis/main.cpp
index 6a6ec9564..8383b0a9b 100644
--- a/Artemis/Razer2Artemis/main.cpp
+++ b/Artemis/Razer2Artemis/main.cpp
@@ -32,7 +32,11 @@
#include "Logger.h"
#include
+#include
+TCHAR szName[] = TEXT("overwatchMmf");
+TCHAR szMsg[] = TEXT("Message from first process.");
+#define BUF_SIZE 2000
static bool g_hasInitialised = false;
const char* game = "";
@@ -42,41 +46,77 @@ void cleanup()
CLogger::EndLogging();
}
+HANDLE hMapFile;
+
BOOL WINAPI DllMain(HINSTANCE hInst, DWORD fdwReason, LPVOID)
{
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
- {
- atexit(cleanup);
+ {
+ atexit(cleanup);
- CLogger::InitLogging("Log.txt");
- CLogger::SetLogLevel(LogLevel::Debug);
+ CLogger::InitLogging("Log.txt");
+ CLogger::SetLogLevel(LogLevel::Debug);
- // Get the process that loaded the DLL
- TCHAR overwatchFind[] = _T("Overwatch");
- TCHAR szPath[MAX_PATH];
- GetModuleFileName(NULL, szPath, MAX_PATH);
+ // Get the process that loaded the DLL
+ TCHAR overwatchFind[] = _T("Overwatch");
+ TCHAR szPath[MAX_PATH];
+ GetModuleFileName(nullptr, szPath, MAX_PATH);
- if (_tcscmp(szPath, overwatchFind) != 0)
- game = "overwatch";
+ if (_tcscmp(szPath, overwatchFind) != 0)
+ game = "overwatch";
- CLogger::OutputLog("Attached to process.", LogLevel::Debug);
- }
- break;
+ CLogger::OutputLog("Attached to process.", LogLevel::Debug);
+
+ // 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:
- {
- cleanup();
-
- CLogger::OutputLog_s("Detached from process.", LogLevel::Debug);
- }
- break;
+ {
+ CLogger::OutputLog_s("Detached from process.", LogLevel::Debug);
+ CloseHandle(hMapFile);
+ cleanup();
+ }
+ break;
}
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(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()
{
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)
{
- CLogger::OutputLog_s("Razer CreateKeyboardEffect called.", LogLevel::Debug);
+ std::ostringstream os;
+ auto keys = *static_cast(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;
}