-
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #46 from camalot/topic/fix-thumb-check
Topic/fix thumb check
- Loading branch information
Showing
25 changed files
with
899 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
{ | ||
"files.exclude": { | ||
"MedalRunner/**": true | ||
"MedalRunner/**": true, | ||
"MedalHotkeyListener/**": true | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
|
||
Microsoft Visual Studio Solution File, Format Version 12.00 | ||
# Visual Studio Version 16 | ||
VisualStudioVersion = 16.0.30413.136 | ||
MinimumVisualStudioVersion = 10.0.40219.1 | ||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MedalHotkeyListener", "MedalHotkeyListener\MedalHotkeyListener.csproj", "{40FD525B-7CA4-452E-B2B2-D3BD181C0ED4}" | ||
EndProject | ||
Global | ||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||
Debug|Any CPU = Debug|Any CPU | ||
Release|Any CPU = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(ProjectConfigurationPlatforms) = postSolution | ||
{40FD525B-7CA4-452E-B2B2-D3BD181C0ED4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
{40FD525B-7CA4-452E-B2B2-D3BD181C0ED4}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
{40FD525B-7CA4-452E-B2B2-D3BD181C0ED4}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
{40FD525B-7CA4-452E-B2B2-D3BD181C0ED4}.Release|Any CPU.Build.0 = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(SolutionProperties) = preSolution | ||
HideSolutionNode = FALSE | ||
EndGlobalSection | ||
GlobalSection(ExtensibilityGlobals) = postSolution | ||
SolutionGuid = {38A2ABA7-4F6C-4ADE-920F-269DBD23CE47} | ||
EndGlobalSection | ||
EndGlobal |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
<?xml version="1.0" encoding="utf-8" ?> | ||
<configuration> | ||
<startup> | ||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" /> | ||
</startup> | ||
</configuration> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,241 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Text.RegularExpressions; | ||
using System.Threading.Tasks; | ||
|
||
namespace MedalHotkeyListener { | ||
public sealed class Arguments { | ||
|
||
/// <summary> | ||
/// Initializes a new instance of the <see cref="Arguments"/> class. | ||
/// </summary> | ||
/// <param name="args">The args.</param> | ||
public Arguments ( params string[] args ) | ||
: this ( ) { | ||
Parse ( args ); | ||
} | ||
|
||
public Arguments ( ICollection<string> args ) { | ||
Parse ( args ); | ||
} | ||
|
||
|
||
/// <summary> | ||
/// Initializes a new instance of the <see cref="Arguments"/> class. | ||
/// </summary> | ||
public Arguments ( ) { | ||
Parameters = new Dictionary<string, string> ( ); | ||
} | ||
|
||
private Dictionary<string, string> Parameters { get; set; } | ||
|
||
/// <summary> | ||
/// Parses the specified args. | ||
/// </summary> | ||
/// <param name="args">The args.</param> | ||
private void Parse ( IEnumerable<string> args ) { | ||
Parameters.Clear ( ); | ||
var spliter = new Regex ( @"^-{1,2}|^/|=|:", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.IgnorePatternWhitespace ); | ||
var remover = new Regex ( @"^['""]?(.*?)['""]?$", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.IgnorePatternWhitespace ); | ||
|
||
string parameter = null; | ||
string[] parts; | ||
|
||
// Valid parameters forms: | ||
// {-,/,--}param{ ,=,:}((",')value(",')) | ||
// Examples: | ||
// -param1 value1 --param2 /param3:"Test-:-work" | ||
// /param4=happy -param5 '--=nice=--' | ||
foreach ( string txt in args ) { | ||
// Look for new parameters (-,/ or --) and a | ||
// possible enclosed value (=,:) | ||
parts = spliter.Split ( txt, 3 ); | ||
|
||
switch ( parts.Length ) { | ||
// Found a value (for the last parameter | ||
// found (space separator)) | ||
case 1: | ||
if ( parameter != null ) { | ||
if ( !Parameters.ContainsKey ( parameter ) ) { | ||
parts[0] = remover.Replace ( parts[0], "$1" ); | ||
Parameters.Add ( parameter, parts[0] ); | ||
} | ||
parameter = null; | ||
} | ||
// else Error: no parameter waiting for a value (skipped) | ||
break; | ||
// Found just a parameter | ||
case 2: | ||
// The last parameter is still waiting. | ||
// With no value, set it to true. | ||
if ( parameter != null ) { | ||
if ( !Parameters.ContainsKey ( parameter ) ) { | ||
Parameters.Add ( parameter, "true" ); | ||
} | ||
} | ||
parameter = parts[1]; | ||
break; | ||
|
||
// Parameter with enclosed value | ||
case 3: | ||
// The last parameter is still waiting. | ||
// With no value, set it to true. | ||
if ( parameter != null ) { | ||
if ( !Parameters.ContainsKey ( parameter ) ) { | ||
Parameters.Add ( parameter, "true" ); | ||
} | ||
} | ||
|
||
parameter = parts[1]; | ||
|
||
// Remove possible enclosing characters (",') | ||
if ( !Parameters.ContainsKey ( parameter ) ) { | ||
parts[2] = remover.Replace ( parts[2], "$1" ); | ||
Parameters.Add ( parameter, parts[2] ); | ||
} | ||
|
||
parameter = null; | ||
break; | ||
} | ||
} | ||
// In case a parameter is still waiting | ||
if ( parameter != null ) { | ||
if ( !Parameters.ContainsKey ( parameter ) ) | ||
Parameters.Add ( parameter, "true" ); | ||
} | ||
} | ||
|
||
// Retrieve a parameter value if it exists | ||
// (overriding C# indexer property) | ||
/// <summary> | ||
/// Gets the <see cref="System.String"/> with the specified param. | ||
/// </summary> | ||
/// <value></value> | ||
/// <exception cref="IndexOutOfRangeException">If it does not contain the specified param.</exception> | ||
public string this[String param] { | ||
get { | ||
return Get ( param ); | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// Gets the <see cref="System.String"/> with the specified paramlist. | ||
/// </summary> | ||
/// <value></value> | ||
/// <exception cref="IndexOutOfRangeException">If it does not contain the specified param.</exception> | ||
public string this[params String[] paramlist] { | ||
get { | ||
return Get ( paramlist ); | ||
} | ||
} | ||
|
||
|
||
/// <summary> | ||
/// Gets the specified param value. | ||
/// </summary> | ||
/// <param name="param">The param.</param> | ||
/// <returns>The value of the param.</returns> | ||
/// <exception cref="IndexOutOfRangeException">If it does not contain the specified param.</exception> | ||
public String Get ( String param ) { | ||
if ( ContainsKey ( param ) ) { | ||
return Parameters[param]; | ||
} | ||
|
||
throw new IndexOutOfRangeException ( ); | ||
} | ||
|
||
/// <summary> | ||
/// Gets the value of a param from the specified paramlist. | ||
/// </summary> | ||
/// <param name="paramlist">The paramlist.</param> | ||
/// <returns>The value of the param.</returns> | ||
/// <exception cref="IndexOutOfRangeException">If it does not contain the specified param.</exception> | ||
public String Get ( params String[] paramlist ) { | ||
foreach ( var param in paramlist ) { | ||
if ( Parameters.ContainsKey ( param ) ) { | ||
return Parameters[param]; | ||
} | ||
} | ||
|
||
throw new IndexOutOfRangeException ( ); | ||
} | ||
|
||
/// <summary> | ||
/// Determines whether this instance contains the specified key. | ||
/// </summary> | ||
/// <param name="param">The param.</param> | ||
/// <returns> | ||
/// <c>true</c> if this instance contains the specified key; otherwise, <c>false</c>. | ||
/// </returns> | ||
public bool ContainsKey ( String param ) { | ||
return Parameters.ContainsKey ( param ); | ||
} | ||
|
||
/// <summary> | ||
/// Determines whether this instance contains any of the params in the specified param list. | ||
/// </summary> | ||
/// <param name="paramlist">The paramlist.</param> | ||
/// <returns> | ||
/// <c>true</c> if this instance contains any of the params in the specified param list; otherwise, <c>false</c>. | ||
/// </returns> | ||
public bool ContainsKey ( params String[] paramlist ) { | ||
foreach ( var item in paramlist ) { | ||
if ( Parameters.ContainsKey ( item ) ) { | ||
return true; | ||
} | ||
} | ||
return false; | ||
} | ||
|
||
/// <summary> | ||
/// Determines whether the specified value contains value. | ||
/// </summary> | ||
/// <param name="value">The value.</param> | ||
/// <returns> | ||
/// <c>true</c> if the specified value contains value; otherwise, <c>false</c>. | ||
/// </returns> | ||
public bool ContainsValue ( string value ) { | ||
return Parameters.ContainsValue ( value ); | ||
} | ||
|
||
/// <summary> | ||
/// Gets the keys. | ||
/// </summary> | ||
/// <value>The keys.</value> | ||
public Dictionary<string, string>.KeyCollection Keys { | ||
get { return Parameters.Keys; } | ||
} | ||
|
||
/// <summary> | ||
/// Gets the values. | ||
/// </summary> | ||
/// <value>The values.</value> | ||
public Dictionary<string, string>.ValueCollection Values { | ||
get { return this.Parameters.Values; } | ||
} | ||
|
||
/// <summary> | ||
/// Gets the count. | ||
/// </summary> | ||
/// <value>The count.</value> | ||
public int Count { get { return this.Parameters.Count; } } | ||
|
||
|
||
|
||
/// <summary> | ||
/// Returns a <see cref="T:System.String"></see> that represents the current <see cref="T:System.Object"></see>. | ||
/// </summary> | ||
/// <returns> | ||
/// A <see cref="T:System.String"></see> that represents the current <see cref="T:System.Object"></see>. | ||
/// </returns> | ||
public override string ToString ( ) { | ||
var sb = new StringBuilder ( ); | ||
foreach ( string key in Parameters.Keys ) { | ||
sb.AppendFormat ( "/{0}={1} ", key, Parameters[key] ); | ||
} | ||
return sb.ToString ( ).Trim ( ); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
|
||
|
||
New-Service -Name "MedalHotkeyListener" -BinaryPathName MedalHotkeyListener.exe |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.IO; | ||
using System.Linq; | ||
using System.Net; | ||
using System.Net.Sockets; | ||
using System.Text; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using System.Windows.Forms; | ||
using Newtonsoft.Json; | ||
|
||
namespace MedalHotkeyListener { | ||
public class ListenerServer { | ||
|
||
public ListenerServer ( ) { | ||
Server = new HttpListener ( ); | ||
var host = Dns.GetHostEntry ( Dns.GetHostName ( ) ); | ||
Server.Prefixes.Add ( $"http://+:{Port}/" ); | ||
} | ||
|
||
private HttpListener Server { get; set; } | ||
private int Port { get; set; } = 19191; | ||
private IPAddress Address { get; set; } = IPAddress.Any; | ||
|
||
public void Start ( ) { | ||
try { | ||
Server.Start ( ); | ||
Console.WriteLine ( $"Listening on {Address}:{Port}" ); | ||
var listenThread = new Thread ( new ThreadStart ( StartListen ) ); | ||
listenThread.Start ( ); | ||
} catch ( Exception ex ) { | ||
Console.WriteLine ( ex.ToString ( ) ); | ||
} | ||
} | ||
|
||
public void Stop ( ) { | ||
try { | ||
Server.Stop ( ); | ||
} catch ( Exception ex ) { | ||
Console.WriteLine ( ex.ToString ( ) ); | ||
} | ||
} | ||
private void StartListen ( ) { | ||
while ( Server.IsListening ) { | ||
if ( Server.IsListening ) { | ||
try { | ||
var context = Server.GetContext ( ); | ||
string payloadData; | ||
using ( var strm = context.Request.InputStream ) { | ||
byte[] data = new byte[1024]; | ||
using ( var ms = new MemoryStream ( ) ) { | ||
|
||
int numBytesRead; | ||
while ( ( numBytesRead = strm.Read ( data, 0, data.Length ) ) > 0 ) { | ||
ms.Write ( data, 0, numBytesRead ); | ||
} | ||
payloadData = Encoding.UTF8.GetString ( ms.ToArray ( ) ); | ||
|
||
} | ||
} | ||
using ( var tr = new StringReader ( payloadData ) ) { | ||
using ( var jr = new JsonTextReader ( tr ) ) { | ||
Console.WriteLine ( payloadData ); | ||
var payload = JsonSerializer.CreateDefault ( ).Deserialize<Payload> ( jr ); | ||
ProcessPayload ( payload ); | ||
context.Response.StatusCode = 200; | ||
context.Response.Close ( ); | ||
} | ||
} | ||
} catch( System.Net.HttpListenerException hle ) { | ||
Console.WriteLine ( "Exiting..." ); | ||
}catch ( Exception ex ) { | ||
Console.WriteLine ( ex ); | ||
} | ||
} | ||
} | ||
} | ||
private void ProcessPayload ( Payload payload ) { | ||
SendKeys.SendWait ( payload.Hotkey ); | ||
} | ||
} | ||
} | ||
|
Oops, something went wrong.