1
0
mirror of https://github.com/Artemis-RGB/Artemis synced 2025-12-12 21:38:38 +00:00
This commit is contained in:
Logan Saso 2016-03-14 19:50:28 -07:00
commit dca0aa8f33
10 changed files with 378 additions and 39 deletions

View File

@ -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" />

View File

@ -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)]

View File

@ -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()

View File

@ -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()
{
}

View File

@ -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()

View File

@ -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);
}
}
}

View 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; }
}
}

View 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
}
}
}
}

View File

@ -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" />