mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-13 05:48:35 +00:00
Implemented basic Overwatch parsing
This commit is contained in:
parent
f1b7c667a7
commit
0b889c3b0c
@ -437,6 +437,7 @@
|
||||
<Compile Include="Styles\DropTargetAdorners\DropTargetMetroHighlightAdorner.cs" />
|
||||
<Compile Include="Styles\DropTargetAdorners\DropTargetMetroInsertionAdorner.cs" />
|
||||
<Compile Include="Utilities\ColorHelpers.cs" />
|
||||
<Compile Include="Utilities\DataReaders\MmfReader.cs" />
|
||||
<Compile Include="Utilities\ExtensionMethods.cs" />
|
||||
<Compile Include="Utilities\GameState\GameDataReceivedEventArgs.cs" />
|
||||
<Compile Include="Utilities\GameState\GameStateWebServer.cs" />
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
using Artemis.DeviceProviders.Razer.Utilities;
|
||||
using Corale.Colore.Core;
|
||||
using Corale.Colore.Razer;
|
||||
using Corale.Colore.Razer.Keyboard;
|
||||
using Constants = Corale.Colore.Razer.Keyboard.Constants;
|
||||
|
||||
namespace Artemis.DeviceProviders.Razer
|
||||
@ -42,7 +43,6 @@ namespace Artemis.DeviceProviders.Razer
|
||||
public override void DrawBitmap(Bitmap bitmap)
|
||||
{
|
||||
var razerArray = RazerUtilities.BitmapColorArray(bitmap, Height, Width);
|
||||
|
||||
Chroma.Instance.Keyboard.SetCustom(razerArray);
|
||||
}
|
||||
}
|
||||
|
||||
@ -155,7 +155,7 @@ namespace Artemis.Managers
|
||||
headset.UpdateDevice(renderEffect.GenerateHeadsetBrush());
|
||||
|
||||
// debugging TODO: Disable when window isn't shown (in Debug VM, or get rid of it, w/e)
|
||||
_events.PublishOnUIThread(new ChangeBitmap(bitmap));
|
||||
//_events.PublishOnUIThread(new ChangeBitmap(bitmap));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,5 +4,14 @@ namespace Artemis.Modules.Games.Overwatch
|
||||
{
|
||||
public class OverwatchDataModel : IGameDataModel
|
||||
{
|
||||
public OverwatchStatus Status { get; set; }
|
||||
}
|
||||
|
||||
public enum OverwatchStatus
|
||||
{
|
||||
Unkown,
|
||||
InMainMenu,
|
||||
InCharacterSelection,
|
||||
InGame
|
||||
}
|
||||
}
|
||||
@ -1,25 +1,37 @@
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.IO.MemoryMappedFiles;
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Linq.Dynamic;
|
||||
using Artemis.Events;
|
||||
using Artemis.Managers;
|
||||
using Artemis.Models;
|
||||
using Artemis.Models.Profiles;
|
||||
using Artemis.Utilities;
|
||||
using Artemis.Utilities.DataReaders;
|
||||
using Caliburn.Micro;
|
||||
using Brush = System.Windows.Media.Brush;
|
||||
using Color = System.Windows.Media.Color;
|
||||
|
||||
namespace Artemis.Modules.Games.Overwatch
|
||||
{
|
||||
public class OverwatchModel : GameModel
|
||||
{
|
||||
public OverwatchModel(MainManager mainManager, OverwatchSettings settings)
|
||||
private readonly IEventAggregator _events;
|
||||
|
||||
public OverwatchModel(IEventAggregator events, MainManager mainManager, OverwatchSettings settings)
|
||||
: base(mainManager, settings, new OverwatchDataModel())
|
||||
{
|
||||
_events = events;
|
||||
Name = "Overwatch";
|
||||
ProcessName = "notepad";
|
||||
ProcessName = "Overwatch";
|
||||
Scale = 4;
|
||||
Enabled = Settings.Enabled;
|
||||
Initialized = false;
|
||||
|
||||
MmfReader = new MmfReader("overwatchMmf");
|
||||
}
|
||||
|
||||
public MmfReader MmfReader { get; set; }
|
||||
|
||||
public int Scale { get; set; }
|
||||
|
||||
public override void Dispose()
|
||||
@ -35,41 +47,27 @@ namespace Artemis.Modules.Games.Overwatch
|
||||
public override void Update()
|
||||
{
|
||||
var gameDataModel = (OverwatchDataModel) GameDataModel;
|
||||
var mffData = ReadMmf("overwatchMmf");
|
||||
if (mffData == null)
|
||||
var colors = MmfReader.GetColorArray();
|
||||
if (colors == null)
|
||||
return;
|
||||
var data = mffData.Split(' ');
|
||||
}
|
||||
|
||||
private string ReadMmf(string overwatchmff)
|
||||
{
|
||||
try
|
||||
var bitmap = new Bitmap(22, 6);
|
||||
|
||||
using (var g = Graphics.FromImage(bitmap))
|
||||
{
|
||||
// opening not-persistent, pagefile-based memory-mapped file
|
||||
using (var mmf = MemoryMappedFile.OpenExisting(overwatchmff))
|
||||
for (var y = 0; y < 6; y++)
|
||||
{
|
||||
// open the stream to read from the file
|
||||
using (var stream = mmf.CreateViewStream())
|
||||
for (var x = 0; x < 22; x++)
|
||||
{
|
||||
// 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;
|
||||
g.DrawRectangle(new Pen(ColorHelpers.ToDrawingColor(colors[y, x])), y, x, 1, 1 );
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (FileNotFoundException)
|
||||
{
|
||||
return null;
|
||||
//ignored
|
||||
}
|
||||
_events.PublishOnUIThread(new ChangeBitmap(bitmap));
|
||||
if (colors[0, 0].Equals(Color.FromRgb(55, 30, 0)))
|
||||
gameDataModel.Status = OverwatchStatus.InMainMenu;
|
||||
else if (colors[0, 0].Equals(Color.FromRgb(3, 5, 11)))
|
||||
gameDataModel.Status = OverwatchStatus.InGame;
|
||||
}
|
||||
|
||||
public override Bitmap GenerateBitmap()
|
||||
|
||||
@ -8,7 +8,7 @@ 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)
|
||||
: base(main, new OverwatchModel(events, main, new OverwatchSettings()), events, pFactory)
|
||||
{
|
||||
DisplayName = "Overwatch";
|
||||
MainManager.EffectManager.EffectModels.Add(GameModel);
|
||||
|
||||
96
Artemis/Artemis/Utilities/DataReaders/MmfReader.cs
Normal file
96
Artemis/Artemis/Utilities/DataReaders/MmfReader.cs
Normal file
@ -0,0 +1,96 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.IO.MemoryMappedFiles;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace Artemis.Utilities.DataReaders
|
||||
{
|
||||
/// <summary>
|
||||
/// A helper class for reading memory managed files
|
||||
/// </summary>
|
||||
public class MmfReader
|
||||
{
|
||||
private DateTime _lastFailure;
|
||||
|
||||
public MmfReader(string mmfName)
|
||||
{
|
||||
MmfName = mmfName;
|
||||
}
|
||||
|
||||
public string MmfName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Turns the MMF into an color array
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public Color[,] GetColorArray()
|
||||
{
|
||||
var mffString = ReadMmf(MmfName);
|
||||
if (string.IsNullOrEmpty(mffString))
|
||||
return null;
|
||||
var intermediateArray = mffString.Split('|');
|
||||
if (intermediateArray[0] == "1")
|
||||
return null;
|
||||
var array = intermediateArray[1].Substring(1).Split(' ');
|
||||
if (!array.Any())
|
||||
return null;
|
||||
|
||||
try
|
||||
{
|
||||
var colors = new Color[6, 22];
|
||||
foreach (var intermediate in array)
|
||||
{
|
||||
if (intermediate.Length > 16)
|
||||
continue;
|
||||
|
||||
// Can't parse to a byte directly since it may contain values >254
|
||||
var parts = intermediate.Split(',').Select(int.Parse).ToArray();
|
||||
if (parts[0] >= 5 && parts[1] >= 21)
|
||||
continue;
|
||||
|
||||
colors[parts[0], parts[1]] = Color.FromRgb((byte) parts[2], (byte) parts[3], (byte) parts[4]);
|
||||
}
|
||||
return colors;
|
||||
}
|
||||
catch (FormatException)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads the contents of the given MFF into a string
|
||||
/// </summary>
|
||||
/// <param name="fileName"></param>
|
||||
/// <returns></returns>
|
||||
private string ReadMmf(string fileName)
|
||||
{
|
||||
// Don't read the file within one second after failing
|
||||
//if (DateTime.Now - _lastFailure > new TimeSpan(0, 0, 1))
|
||||
// return null;
|
||||
|
||||
try
|
||||
{
|
||||
using (var mmf = MemoryMappedFile.OpenExisting(fileName))
|
||||
{
|
||||
using (var stream = mmf.CreateViewStream())
|
||||
{
|
||||
using (var binReader = new BinaryReader(stream))
|
||||
{
|
||||
var allBytes = binReader.ReadBytes((int) stream.Length);
|
||||
return Encoding.UTF8.GetString(allBytes, 0, allBytes.Length);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (FileNotFoundException)
|
||||
{
|
||||
_lastFailure = DateTime.Now;
|
||||
return null;
|
||||
//ignored
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,104 +0,0 @@
|
||||
// Original work by VRocker https://github.com/VRocker/LogiLed2Corsair
|
||||
// I'm mainly a C# developer, and these modification aren't a piece of art, but it suits our needs.
|
||||
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2015 VRocker
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
#include "Logger.h"
|
||||
|
||||
#include <time.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
|
||||
// Ok this looks butt-ugleh but its just to force the default log level to debug if we compile in debug
|
||||
#ifdef _DEBUG
|
||||
LogLevel CLogger::m_eLogLevel = LogLevel::Debug;
|
||||
#else
|
||||
LogLevel CLogger::m_eLogLevel = LogLevel::All;
|
||||
#endif
|
||||
FILE* CLogger::m_pFile = 0;
|
||||
|
||||
void CLogger::InitLogging(const char* szFile)
|
||||
{
|
||||
if (!m_pFile)
|
||||
{
|
||||
m_pFile = fopen(szFile, "a+");
|
||||
if (!m_pFile)
|
||||
{
|
||||
// Hum, we couldn't open the file for writing
|
||||
printf("ERROR: Unable to open log file %s.\n", szFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CLogger::EndLogging(void)
|
||||
{
|
||||
if (m_pFile)
|
||||
{
|
||||
fclose(m_pFile);
|
||||
m_pFile = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void CLogger::OutputLog_s(const char* sz, const LogLevel eLevel)
|
||||
{
|
||||
// If the level of this log entry is less important than what we are told to log, just return
|
||||
if (eLevel < m_eLogLevel)
|
||||
return;
|
||||
|
||||
// If we don't have a file to write to, bail.
|
||||
if (!m_pFile)
|
||||
return;
|
||||
|
||||
char szOutput[512] = { 0 };
|
||||
|
||||
time_t rawtime;
|
||||
struct tm* timeinfo;
|
||||
|
||||
time(&rawtime);
|
||||
timeinfo = localtime(&rawtime);
|
||||
|
||||
// Timestamp the log entry
|
||||
size_t uiLen = sprintf(szOutput, "<%.2d/%.2d/%.2d - %.2d:%.2d:%.2d> %s\n", timeinfo->tm_mday, timeinfo->tm_mon + 1, timeinfo->tm_year + 1900, timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, sz);
|
||||
|
||||
// Write the text to the file
|
||||
fwrite(szOutput, 1, uiLen, m_pFile);
|
||||
// Flush the log file to the disk. May move this to a seperate function
|
||||
fflush(m_pFile);
|
||||
|
||||
// Output the text to any console that may be attached
|
||||
printf("%s", szOutput);
|
||||
}
|
||||
|
||||
void CLogger::OutputLog(const char* sz, const LogLevel eLevel, ...)
|
||||
{
|
||||
char szText[1024] = { 0 };
|
||||
va_list marker;
|
||||
va_start(marker, eLevel);
|
||||
vsprintf(szText, sz, marker);
|
||||
va_end(marker);
|
||||
|
||||
// Since this function is pretty much the same as the safer function, we'll just redirect it there
|
||||
OutputLog_s(szText, eLevel);
|
||||
}
|
||||
|
||||
@ -1,82 +0,0 @@
|
||||
// Original work by VRocker https://github.com/VRocker/LogiLed2Corsair
|
||||
// I'm mainly a C# developer, and these modification aren't a piece of art, but it suits our needs.
|
||||
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2015 VRocker
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
#ifndef _LOGGER_H
|
||||
#define _LOGGER_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
enum class LogLevel
|
||||
{
|
||||
Debug,
|
||||
All,
|
||||
Critical,
|
||||
Warning,
|
||||
Information,
|
||||
User,
|
||||
Internal,
|
||||
None,
|
||||
|
||||
// Just to force the compiler to treat the enum options as an int
|
||||
FORCE_32BIT = 0x7fffffff
|
||||
};
|
||||
|
||||
class CLogger
|
||||
{
|
||||
public:
|
||||
static LogLevel GetLogLevel(void)
|
||||
{
|
||||
return m_eLogLevel;
|
||||
}
|
||||
|
||||
static void SetLogLevel(const LogLevel e)
|
||||
{
|
||||
#ifndef _DEBUG
|
||||
if (e == LogLevel::Debug) return;
|
||||
#endif
|
||||
m_eLogLevel = e;
|
||||
}
|
||||
|
||||
static void InitLogging(const char* szFile);
|
||||
// Always remember to end logging when you are finished otherwise you will have file handles floating around
|
||||
static void EndLogging(void);
|
||||
|
||||
// Output the text to a log file.
|
||||
static void OutputLog_s(const char* sz, const LogLevel eLevel);
|
||||
static void OutputLog(const char* sz, const LogLevel eLevel, ...);
|
||||
|
||||
static FILE* GetFile()
|
||||
{
|
||||
return m_pFile;
|
||||
}
|
||||
|
||||
private:
|
||||
static LogLevel m_eLogLevel;
|
||||
static FILE* m_pFile;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -126,11 +126,9 @@
|
||||
<None Include="Razer2Artemis.def" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Logger.cpp" />
|
||||
<ClCompile Include="main.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Logger.h" />
|
||||
<ClInclude Include="main.h" />
|
||||
<ClInclude Include="RzChromaSDKDefines.h" />
|
||||
<ClInclude Include="RzChromaSDKTypes.h" />
|
||||
|
||||
@ -23,17 +23,11 @@
|
||||
<ClCompile Include="main.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Logger.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="main.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Logger.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="RzChromaSDKDefines.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
|
||||
@ -1,212 +1,165 @@
|
||||
// Original work by VRocker https://github.com/VRocker/LogiLed2Corsair
|
||||
// I'm mainly a C# developer, and these modification aren't a piece of art, but it suits our needs.
|
||||
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Copyright (c) 2015 VRocker
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
#include "main.h"
|
||||
#include <stdio.h>
|
||||
#include <tchar.h>
|
||||
#include <thread>
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <Windows.h>
|
||||
#include "Logger.h"
|
||||
|
||||
#include <filesystem>
|
||||
#include <sstream>
|
||||
|
||||
TCHAR szName[] = TEXT("overwatchMmf");
|
||||
TCHAR szMsg[] = TEXT("Message from first process.");
|
||||
#define BUF_SIZE 2000
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#define BUF_SIZE 4096
|
||||
|
||||
static bool g_hasInitialised = false;
|
||||
const char* game = "";
|
||||
|
||||
void cleanup()
|
||||
{
|
||||
CLogger::EndLogging();
|
||||
}
|
||||
|
||||
HANDLE hMapFile;
|
||||
|
||||
BOOL WINAPI DllMain(HINSTANCE hInst, DWORD fdwReason, LPVOID)
|
||||
{
|
||||
switch (fdwReason)
|
||||
if (fdwReason == DLL_PROCESS_ATTACH)
|
||||
{
|
||||
case DLL_PROCESS_ATTACH:
|
||||
{
|
||||
atexit(cleanup);
|
||||
// Get the process that loaded the DLL
|
||||
TCHAR overwatchFind[] = _T("Overwatch");
|
||||
TCHAR szPath[MAX_PATH];
|
||||
GetModuleFileName(nullptr, szPath, MAX_PATH);
|
||||
|
||||
CLogger::InitLogging("Log.txt");
|
||||
CLogger::SetLogLevel(LogLevel::Debug);
|
||||
if (_tcscmp(szPath, overwatchFind) != 0)
|
||||
game = "overwatch";
|
||||
|
||||
// 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";
|
||||
|
||||
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:
|
||||
{
|
||||
CLogger::OutputLog_s("Detached from process.", LogLevel::Debug);
|
||||
CloseHandle(hMapFile);
|
||||
cleanup();
|
||||
}
|
||||
break;
|
||||
// Setup mmf
|
||||
hMapFile = CreateFileMapping(INVALID_HANDLE_VALUE, nullptr, PAGE_READWRITE, 0, BUF_SIZE, szName);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void WriteMmf(const char* msg)
|
||||
template <typename ... Args>
|
||||
std::string string_format(const std::string& format, Args ... args)
|
||||
{
|
||||
size_t size = snprintf(nullptr, 0, format.c_str(), args ...) + 1; // Extra space for '\0'
|
||||
std::unique_ptr<char[]> buf(new char[size]);
|
||||
snprintf(buf.get(), size, format.c_str(), args ...);
|
||||
return std::string(buf.get(), buf.get() + size - 1); // We don't want the '\0' inside
|
||||
}
|
||||
|
||||
|
||||
void WriteMmf(std::string 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));
|
||||
pBuf = static_cast<LPTSTR>(MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 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)));
|
||||
CopyMemory((PVOID)pBuf, msg.c_str(), msg.size());
|
||||
UnmapViewOfFile(pBuf);
|
||||
}
|
||||
|
||||
RZRESULT Init()
|
||||
{
|
||||
CLogger::OutputLog_s("Razer Init called.", LogLevel::Debug);
|
||||
g_hasInitialised = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
RZRESULT UnInit()
|
||||
{
|
||||
CLogger::OutputLog_s("Razer UnInit called.", LogLevel::Debug);
|
||||
return 0;
|
||||
}
|
||||
|
||||
RZRESULT CreateEffect(RZDEVICEID DeviceId, ChromaSDK::EFFECT_TYPE Effect, PRZPARAM pParam, RZEFFECTID* pEffectId)
|
||||
{
|
||||
CLogger::OutputLog_s("Razer CreateEffect called.", LogLevel::Debug);
|
||||
return 0;
|
||||
}
|
||||
|
||||
RZRESULT CreateKeyboardEffect(ChromaSDK::Keyboard::EFFECT_TYPE Effect, PRZPARAM pParam, RZEFFECTID* pEffectId)
|
||||
{
|
||||
std::ostringstream os;
|
||||
auto keys = *static_cast<struct CUSTOM_KEY_EFFECT_TYPE*>(pParam);
|
||||
std::string res = "";
|
||||
if (Effect == Keyboard::CHROMA_CUSTOM) {
|
||||
res += "0|";
|
||||
auto keys = *static_cast<struct Keyboard::CUSTOM_EFFECT_TYPE*>(pParam);
|
||||
|
||||
for (auto y = 0; y < 6; y++)
|
||||
{
|
||||
for (auto x = 0; x < 22; x++)
|
||||
for (auto y = 0; y < 6; y++)
|
||||
{
|
||||
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 << ")";
|
||||
for (auto x = 0; x < 22; x++)
|
||||
{
|
||||
auto r = GetRValue(keys.Color[y][x]);
|
||||
auto g = GetGValue(keys.Color[y][x]);
|
||||
auto b = GetBValue(keys.Color[y][x]);
|
||||
res += string_format(" %d,%d,%d,%d,%d", y, x, r, g, b);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (Effect == Keyboard::CHROMA_CUSTOM_KEY) {
|
||||
res += "1|";
|
||||
auto keys = *static_cast<struct Keyboard::CUSTOM_KEY_EFFECT_TYPE*>(pParam);
|
||||
|
||||
for (auto y = 0; y < 6; y++)
|
||||
{
|
||||
for (auto x = 0; x < 22; x++)
|
||||
{
|
||||
auto r = GetRValue(keys.Color[y][x]);
|
||||
auto g = GetGValue(keys.Color[y][x]);
|
||||
auto b = GetBValue(keys.Color[y][x]);
|
||||
res += string_format(" %d,%d,%d,%d,%d", y, x, r, g, b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CLogger::OutputLog_s("Razer CreateKeyboardEffect called", LogLevel::Debug);
|
||||
WriteMmf(os.str().c_str());
|
||||
WriteMmf(res);
|
||||
return 0;
|
||||
}
|
||||
|
||||
RZRESULT CreateMouseEffect(ChromaSDK::Mouse::EFFECT_TYPE Effect, PRZPARAM pParam, RZEFFECTID* pEffectId)
|
||||
{
|
||||
CLogger::OutputLog_s("Razer CreateMouseEffect called.", LogLevel::Debug);
|
||||
return 0;
|
||||
}
|
||||
|
||||
RZRESULT CreateHeadsetEffect(ChromaSDK::Headset::EFFECT_TYPE Effect, PRZPARAM pParam, RZEFFECTID* pEffectId)
|
||||
{
|
||||
CLogger::OutputLog_s("Razer CreateHeadsetEffect called.", LogLevel::Debug);
|
||||
return 0;
|
||||
}
|
||||
|
||||
RZRESULT CreateMousepadEffect(ChromaSDK::Mousepad::EFFECT_TYPE Effect, PRZPARAM pParam, RZEFFECTID* pEffectId)
|
||||
{
|
||||
CLogger::OutputLog_s("Razer CreateMousepadEffect called.", LogLevel::Debug);
|
||||
return 0;
|
||||
}
|
||||
|
||||
RZRESULT CreateKeypadEffect(ChromaSDK::Keypad::EFFECT_TYPE Effect, PRZPARAM pParam, RZEFFECTID* pEffectId)
|
||||
{
|
||||
CLogger::OutputLog_s("Razer CreateKeypadEffect called.", LogLevel::Debug);
|
||||
return 0;
|
||||
}
|
||||
|
||||
RZRESULT DeleteEffect(RZEFFECTID EffectId)
|
||||
{
|
||||
CLogger::OutputLog_s("Razer DeleteEffect called.", LogLevel::Debug);
|
||||
return 0;
|
||||
}
|
||||
|
||||
RZRESULT SetEffect(RZEFFECTID EffectId)
|
||||
{
|
||||
CLogger::OutputLog_s("Razer SetEffect called.", LogLevel::Debug);
|
||||
return 0;
|
||||
}
|
||||
|
||||
RZRESULT RegisterEventNotification(HWND hWnd)
|
||||
{
|
||||
CLogger::OutputLog_s("Razer RegisterEventNotification called.", LogLevel::Debug);
|
||||
return 0;
|
||||
}
|
||||
|
||||
RZRESULT UnregisterEventNotification()
|
||||
{
|
||||
CLogger::OutputLog_s("Razer UnregisterEventNotification called.", LogLevel::Debug);
|
||||
return 0;
|
||||
}
|
||||
|
||||
RZRESULT QueryDevice(RZDEVICEID DeviceId, DEVICE_INFO_TYPE& DeviceInfo)
|
||||
{
|
||||
CLogger::OutputLog_s("Razer QueryDevice called.", LogLevel::Debug);
|
||||
return 0;
|
||||
}
|
||||
|
||||
15
Artemis/Razer2Artemis/utils.cpp
Normal file
15
Artemis/Razer2Artemis/utils.cpp
Normal file
@ -0,0 +1,15 @@
|
||||
#include <memory>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <cstdio>
|
||||
|
||||
using namespace std;
|
||||
|
||||
template <typename ... Args>
|
||||
string string_format(const std::string& format, Args ... args)
|
||||
{
|
||||
size_t size = snprintf(nullptr, 0, format.c_str(), args ...) + 1; // Extra space for '\0'
|
||||
unique_ptr<char[]> buf(new char[size]);
|
||||
snprintf(buf.get(), size, format.c_str(), args ...);
|
||||
return string(buf.get(), buf.get() + size - 1); // We don't want the '\0' inside
|
||||
}
|
||||
12
Artemis/Razer2Artemis/utils.h
Normal file
12
Artemis/Razer2Artemis/utils.h
Normal file
@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
template <typename ... Args>
|
||||
std::string string_format(const std::string& format, Args ... args)
|
||||
{
|
||||
size_t size = snprintf(nullptr, 0, format.c_str(), args ...) + 1; // Extra space for '\0'
|
||||
std::unique_ptr<char[]> buf(new char[size]);
|
||||
snprintf(buf.get(), size, format.c_str(), args ...);
|
||||
return std::string(buf.get(), buf.get() + size - 1); // We don't want the '\0' inside
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user