mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-12 21:38:38 +00:00
Merge branch 'development' of https://github.com/SpoinkyNL/Artemis.git
This commit is contained in:
commit
dca0aa8f33
@ -163,10 +163,6 @@
|
||||
<Reference Include="Microsoft.QualityTools.Testing.Fakes, Version=12.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
</Reference>
|
||||
<Reference Include="NamedPipeWrapper, Version=1.4.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\NamedPipeWrapper.1.4.0\lib\net40\NamedPipeWrapper.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</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>
|
||||
@ -371,7 +367,8 @@
|
||||
<Compile Include="Utilities\ImageUtilities.cs" />
|
||||
<Compile Include="Utilities\Keyboard\KeyboardHook.cs" />
|
||||
<Compile Include="Utilities\LogitechDll\DllManager.cs" />
|
||||
<Compile Include="Utilities\LogitechDll\LogitechNamedPipe.cs" />
|
||||
<Compile Include="Utilities\LogitechDll\NamedPipeServer.cs" />
|
||||
<Compile Include="Utilities\LogitechDll\PipeServer.cs" />
|
||||
<Compile Include="Utilities\Memory\GamePointer.cs" />
|
||||
<Compile Include="Utilities\Memory\Memory.cs" />
|
||||
<Compile Include="Utilities\Memory\MemoryHelpers.cs" />
|
||||
|
||||
@ -68,7 +68,7 @@ namespace Artemis.KeyboardProviders.Logitech.Utilities
|
||||
int greenPercentage, int bluePercentage);
|
||||
|
||||
[DllImport("LogitechLedEnginesWrapper ", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern bool LogiLedSetLightingForKeyWithKeyName(KeyboardNames keyCode, int redPercentage,
|
||||
public static extern bool LogiLedSetLightingForKeyWithKeyName(int keyCode, int redPercentage,
|
||||
int greenPercentage, int bluePercentage);
|
||||
|
||||
[DllImport("LogitechLedEnginesWrapper ", CallingConvention = CallingConvention.Cdecl)]
|
||||
|
||||
@ -2,11 +2,13 @@
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Windows.Forms;
|
||||
using Artemis.Events;
|
||||
using Artemis.Models;
|
||||
using Artemis.Services;
|
||||
using Artemis.Utilities.GameState;
|
||||
using Artemis.Utilities.Keyboard;
|
||||
using Artemis.Utilities.LogitechDll;
|
||||
using Caliburn.Micro;
|
||||
|
||||
namespace Artemis.Managers
|
||||
@ -47,8 +49,13 @@ namespace Artemis.Managers
|
||||
// Create and start the web server
|
||||
GameStateWebServer = new GameStateWebServer();
|
||||
GameStateWebServer.Start();
|
||||
|
||||
// Start the named pipe
|
||||
PipeServer = new PipeServer();
|
||||
PipeServer.Start("artemis");
|
||||
}
|
||||
|
||||
public PipeServer PipeServer { get; set; }
|
||||
public BackgroundWorker UpdateWorker { get; set; }
|
||||
public BackgroundWorker ProcessWorker { get; set; }
|
||||
|
||||
@ -65,6 +72,7 @@ namespace Artemis.Managers
|
||||
public bool Suspended { get; set; }
|
||||
|
||||
public bool Running { get; private set; }
|
||||
|
||||
public event PauseCallbackHandler PauseCallback;
|
||||
|
||||
/// <summary>
|
||||
@ -137,7 +145,9 @@ namespace Artemis.Managers
|
||||
{
|
||||
Stop();
|
||||
ProcessWorker.CancelAsync();
|
||||
ProcessWorker.CancelAsync();
|
||||
GameStateWebServer.Stop();
|
||||
//NamedPipeServer.StopServer();
|
||||
}
|
||||
|
||||
public void Restart()
|
||||
|
||||
@ -1,6 +1,10 @@
|
||||
using System.Drawing;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
using Artemis.KeyboardProviders.Logitech.Utilities;
|
||||
using Artemis.Managers;
|
||||
using Artemis.Models;
|
||||
using Artemis.Utilities.LogitechDll;
|
||||
|
||||
namespace Artemis.Modules.Games.TheDivision
|
||||
{
|
||||
@ -23,17 +27,42 @@ namespace Artemis.Modules.Games.TheDivision
|
||||
public override void Dispose()
|
||||
{
|
||||
Initialized = false;
|
||||
DllManager.RestoreDll();
|
||||
}
|
||||
|
||||
public override void Enable()
|
||||
{
|
||||
Initialized = false;
|
||||
|
||||
// Enable logic, if any
|
||||
|
||||
DllManager.PlaceDll();
|
||||
MainManager.PipeServer.PipeMessage += PipeServerOnPipeMessage;
|
||||
Initialized = true;
|
||||
}
|
||||
|
||||
private void PipeServerOnPipeMessage(string reply)
|
||||
{
|
||||
// Convert the given string to a list of ints
|
||||
var stringParts = reply.Split(' ');
|
||||
var parts = new int[stringParts.Length];
|
||||
for (var i = 0; i < stringParts.Length; i++)
|
||||
parts[i] = int.Parse(stringParts[i]);
|
||||
|
||||
if (parts[0] == 1)
|
||||
InterpertrateDivisionKey(parts);
|
||||
|
||||
}
|
||||
|
||||
// Parses Division key data to game data
|
||||
private void InterpertrateDivisionKey(int[] parts)
|
||||
{
|
||||
// F1 to F4 indicate the player and his party. Blinks red on damage taken
|
||||
|
||||
// R blinks white when low on ammo
|
||||
|
||||
// G turns white when holding a grenade, turns off when out of grenades
|
||||
|
||||
// V blinks on low HP
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
}
|
||||
|
||||
Binary file not shown.
@ -10,14 +10,17 @@ namespace Artemis.Utilities.LogitechDll
|
||||
|
||||
public static bool RestoreDll()
|
||||
{
|
||||
if (!File.Exists(LogitechPath + @"\LogitechLed.dll.bak"))
|
||||
if (!File.Exists(LogitechPath + @"\LogitechLed.dll") || !File.Exists(LogitechPath + @"\artemis.txt"))
|
||||
return false;
|
||||
|
||||
|
||||
// Get rid of our own DLL
|
||||
File.Delete(LogitechPath + @"\LogitechLed.dll");
|
||||
|
||||
// Restore the backup
|
||||
File.Move(LogitechPath + @"\LogitechLed.dll.bak",
|
||||
LogitechPath + @"\LogitechLed.dll");
|
||||
if (File.Exists(LogitechPath + @"\LogitechLed.dll.bak"))
|
||||
File.Move(LogitechPath + @"\LogitechLed.dll.bak", LogitechPath + @"\LogitechLed.dll");
|
||||
|
||||
File.Delete(LogitechPath + @"\artemis.txt");
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -43,6 +46,9 @@ namespace Artemis.Utilities.LogitechDll
|
||||
File.WriteAllBytes(LogitechPath + @"\LogitechLED.dll",
|
||||
Resources.LogitechLED);
|
||||
|
||||
// A token to show the file is placed
|
||||
File.Create(LogitechPath + @"\artemis.txt");
|
||||
|
||||
// If the user doesn't have a Logitech device, the CLSID will be missing
|
||||
// and we should create it ourselves.
|
||||
if (!RegistryKeyPlaced())
|
||||
@ -56,7 +62,7 @@ namespace Artemis.Utilities.LogitechDll
|
||||
if (!RegistryKeyPlaced())
|
||||
return false;
|
||||
|
||||
return File.Exists(LogitechPath + @"\LogitechLed.dll");
|
||||
return File.Exists(LogitechPath + @"\artemis.txt");
|
||||
}
|
||||
|
||||
private static bool RegistryKeyPlaced()
|
||||
|
||||
@ -1,23 +0,0 @@
|
||||
using System.Diagnostics;
|
||||
using NamedPipeWrapper;
|
||||
|
||||
namespace Artemis.Utilities.LogitechDll
|
||||
{
|
||||
public class LogitechNamedPipe
|
||||
{
|
||||
public LogitechNamedPipe()
|
||||
{
|
||||
LogitechPipe = new NamedPipeServer<string>("ArtemisLogitech");
|
||||
|
||||
LogitechPipe.ClientMessage += LogitechPipeOnClientMessage;
|
||||
LogitechPipe.Start();
|
||||
}
|
||||
|
||||
public NamedPipeServer<string> LogitechPipe { get; set; }
|
||||
|
||||
private void LogitechPipeOnClientMessage(NamedPipeConnection<string, string> connection, string message)
|
||||
{
|
||||
Debug.WriteLine(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
189
Artemis/Artemis/Utilities/LogitechDll/NamedPipeServer.cs
Normal file
189
Artemis/Artemis/Utilities/LogitechDll/NamedPipeServer.cs
Normal file
@ -0,0 +1,189 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.IO.Pipes;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using Microsoft.Win32.SafeHandles;
|
||||
|
||||
namespace Artemis.Utilities.LogitechDll
|
||||
{
|
||||
public class NamedPipeServer
|
||||
{
|
||||
public const uint DUPLEX = 0x00000003;
|
||||
public const uint FILE_FLAG_OVERLAPPED = 0x40000000;
|
||||
|
||||
public const int BUFFER_SIZE = 100;
|
||||
private SafeFileHandle clientHandle;
|
||||
public Client clientse;
|
||||
public int ClientType;
|
||||
private Thread listenThread;
|
||||
|
||||
public string pipeName;
|
||||
|
||||
public NamedPipeServer(string PName, int Mode)
|
||||
{
|
||||
pipeName = PName;
|
||||
ClientType = Mode; //0 Reading Pipe, 1 Writing Pipe
|
||||
}
|
||||
|
||||
public event PipeDataReceivedEventHandler PipeDataReceived;
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
public static extern SafeFileHandle CreateNamedPipe(
|
||||
string pipeName,
|
||||
uint dwOpenMode,
|
||||
uint dwPipeMode,
|
||||
uint nMaxInstances,
|
||||
uint nOutBufferSize,
|
||||
uint nInBufferSize,
|
||||
uint nDefaultTimeOut,
|
||||
IntPtr lpSecurityAttributes);
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
public static extern int ConnectNamedPipe(
|
||||
SafeFileHandle hNamedPipe,
|
||||
IntPtr lpOverlapped);
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
public static extern int DisconnectNamedPipe(
|
||||
SafeFileHandle hNamedPipe);
|
||||
|
||||
public void Start()
|
||||
{
|
||||
listenThread = new Thread(ListenForClients);
|
||||
listenThread.Start();
|
||||
}
|
||||
|
||||
private void ListenForClients()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
clientHandle = CreateNamedPipe(pipeName, DUPLEX | FILE_FLAG_OVERLAPPED, 0, 255, BUFFER_SIZE, BUFFER_SIZE,
|
||||
0, IntPtr.Zero);
|
||||
//could not create named pipe
|
||||
if (clientHandle.IsInvalid)
|
||||
return;
|
||||
|
||||
var success = ConnectNamedPipe(clientHandle, IntPtr.Zero);
|
||||
|
||||
//could not connect client
|
||||
if (success == 0)
|
||||
return;
|
||||
|
||||
clientse = new Client();
|
||||
clientse.handle = clientHandle;
|
||||
clientse.stream = new FileStream(clientse.handle, FileAccess.ReadWrite, BUFFER_SIZE, true);
|
||||
|
||||
if (ClientType == 0)
|
||||
{
|
||||
var readThread = new Thread(Read);
|
||||
readThread.Start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void Read()
|
||||
{
|
||||
//Client client = (Client)clientObj;
|
||||
//clientse.stream = new FileStream(clientse.handle, FileAccess.ReadWrite, BUFFER_SIZE, true);
|
||||
byte[] buffer = null;
|
||||
var encoder = new ASCIIEncoding();
|
||||
|
||||
while (true)
|
||||
{
|
||||
var bytesRead = 0;
|
||||
|
||||
try
|
||||
{
|
||||
buffer = new byte[BUFFER_SIZE];
|
||||
bytesRead = clientse.stream.Read(buffer, 0, BUFFER_SIZE);
|
||||
}
|
||||
catch
|
||||
{
|
||||
//read error has occurred
|
||||
break;
|
||||
}
|
||||
|
||||
//client has disconnected
|
||||
if (bytesRead == 0)
|
||||
break;
|
||||
|
||||
//fire message received event
|
||||
//if (this.MessageReceived != null)
|
||||
// this.MessageReceived(clientse, encoder.GetString(buffer, 0, bytesRead));
|
||||
|
||||
var ReadLength = 0;
|
||||
for (var i = 0; i < BUFFER_SIZE; i++)
|
||||
{
|
||||
if (buffer[i].ToString("x2") != "cc")
|
||||
{
|
||||
ReadLength++;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
if (ReadLength > 0)
|
||||
{
|
||||
var Rc = new byte[ReadLength];
|
||||
Buffer.BlockCopy(buffer, 0, Rc, 0, ReadLength);
|
||||
OnPipeDataReceived(new PipeDataReceivedEventArgs(encoder.GetString(Rc, 0, ReadLength)));
|
||||
|
||||
buffer.Initialize();
|
||||
}
|
||||
}
|
||||
|
||||
//clean up resources
|
||||
clientse.stream.Close();
|
||||
clientse.handle.Close();
|
||||
}
|
||||
|
||||
public void SendMessage(string message, Client client)
|
||||
{
|
||||
var encoder = new ASCIIEncoding();
|
||||
var messageBuffer = encoder.GetBytes(message);
|
||||
|
||||
if (client.stream.CanWrite)
|
||||
{
|
||||
client.stream.Write(messageBuffer, 0, messageBuffer.Length);
|
||||
client.stream.Flush();
|
||||
}
|
||||
}
|
||||
|
||||
public void StopServer()
|
||||
{
|
||||
//clean up resources
|
||||
|
||||
DisconnectNamedPipe(clientHandle);
|
||||
|
||||
|
||||
listenThread.Abort();
|
||||
}
|
||||
|
||||
private void OnPipeDataReceived(PipeDataReceivedEventArgs e)
|
||||
{
|
||||
PipeDataReceived?.Invoke(this, e);
|
||||
}
|
||||
|
||||
public class Client
|
||||
{
|
||||
public SafeFileHandle handle;
|
||||
public FileStream stream;
|
||||
}
|
||||
}
|
||||
|
||||
public delegate void PipeDataReceivedEventHandler(
|
||||
object sender, PipeDataReceivedEventArgs pipeDataReceivedEventArgs);
|
||||
|
||||
public class PipeDataReceivedEventArgs
|
||||
{
|
||||
public PipeDataReceivedEventArgs(string data)
|
||||
{
|
||||
Data = data;
|
||||
}
|
||||
|
||||
public string Data { get; set; }
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
132
Artemis/Artemis/Utilities/LogitechDll/PipeServer.cs
Normal file
132
Artemis/Artemis/Utilities/LogitechDll/PipeServer.cs
Normal file
@ -0,0 +1,132 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO.Pipes;
|
||||
using System.Security.AccessControl;
|
||||
using System.Security.Principal;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Artemis.Utilities.LogitechDll
|
||||
{
|
||||
// Delegate for passing received message back to caller
|
||||
public delegate void DelegateMessage(string reply);
|
||||
|
||||
public class PipeServer
|
||||
{
|
||||
private string _pipeName;
|
||||
|
||||
public bool Running { get; set; }
|
||||
public event DelegateMessage PipeMessage;
|
||||
|
||||
public void Start(string pipeName)
|
||||
{
|
||||
Running = true;
|
||||
_pipeName = pipeName;
|
||||
var task = new Task(PipeLoop);
|
||||
task.Start();
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
Running = false;
|
||||
}
|
||||
|
||||
private void PipeLoop()
|
||||
{
|
||||
try
|
||||
{
|
||||
var security = new PipeSecurity();
|
||||
var sid = new SecurityIdentifier(WellKnownSidType.WorldSid, null);
|
||||
security.AddAccessRule(new PipeAccessRule(sid, PipeAccessRights.FullControl,
|
||||
AccessControlType.Allow));
|
||||
|
||||
while (Running)
|
||||
{
|
||||
var namedPipeServerStream = new NamedPipeServerStream(_pipeName, PipeDirection.In, 100,
|
||||
PipeTransmissionMode.Byte, PipeOptions.None, 100, 100, security);
|
||||
|
||||
namedPipeServerStream.WaitForConnection();
|
||||
var buffer = new byte[100];
|
||||
namedPipeServerStream.Read(buffer, 0, 100);
|
||||
namedPipeServerStream.Close();
|
||||
|
||||
var task = new Task(() => HandleMessage(buffer));
|
||||
task.Start();
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleMessage(byte[] buffer)
|
||||
{
|
||||
var request = Encoding.ASCII.GetString(buffer);
|
||||
PipeMessage?.Invoke(request);
|
||||
}
|
||||
|
||||
public void Listen(string pipeName)
|
||||
{
|
||||
try
|
||||
{
|
||||
var security = new PipeSecurity();
|
||||
var sid = new SecurityIdentifier(WellKnownSidType.WorldSid, null);
|
||||
security.AddAccessRule(new PipeAccessRule(sid, PipeAccessRights.FullControl, AccessControlType.Allow));
|
||||
|
||||
// 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);
|
||||
|
||||
// Wait for a connection
|
||||
pipeServer.BeginWaitForConnection(WaitForConnectionCallBack, pipeServer);
|
||||
}
|
||||
catch (Exception oEx)
|
||||
{
|
||||
Debug.WriteLine(oEx.Message);
|
||||
}
|
||||
}
|
||||
|
||||
private void WaitForConnectionCallBack(IAsyncResult iar)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Get the pipe
|
||||
var pipeServer = (NamedPipeServerStream) iar.AsyncState;
|
||||
// End waiting for the connection
|
||||
pipeServer.EndWaitForConnection(iar);
|
||||
|
||||
var buffer = new byte[255];
|
||||
|
||||
// Read the incoming message
|
||||
pipeServer.Read(buffer, 0, 255);
|
||||
|
||||
// Convert byte buffer to string
|
||||
var stringData = Encoding.UTF8.GetString(buffer, 0, buffer.Length);
|
||||
Debug.WriteLine(stringData + Environment.NewLine);
|
||||
|
||||
// Pass message back to calling form
|
||||
PipeMessage?.Invoke(stringData);
|
||||
|
||||
// Kill original sever and create new wait server
|
||||
pipeServer.Close();
|
||||
|
||||
var security = new PipeSecurity();
|
||||
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);
|
||||
|
||||
// Recursively wait for the connection again and again....
|
||||
pipeServer.BeginWaitForConnection(WaitForConnectionCallBack, pipeServer);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -12,7 +12,6 @@
|
||||
<package id="log4net" version="2.0.5" targetFramework="net452" />
|
||||
<package id="MahApps.Metro" version="1.2.4.0" targetFramework="net452" />
|
||||
<package id="MahApps.Metro.Resources" version="0.4.0.0" targetFramework="net452" />
|
||||
<package id="NamedPipeWrapper" version="1.4.0" targetFramework="net452" />
|
||||
<package id="NAudio" version="1.7.3" targetFramework="net452" />
|
||||
<package id="Newtonsoft.Json" version="8.0.2" targetFramework="net452" />
|
||||
<package id="SharpDX" version="3.0.1" targetFramework="net452" />
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user