diff --git a/OpenCS2hock.sln.DotSettings b/OpenCS2hock.sln.DotSettings
index 15ea657..78d8485 100644
--- a/OpenCS2hock.sln.DotSettings
+++ b/OpenCS2hock.sln.DotSettings
@@ -4,5 +4,7 @@
True
True
True
+ True
+ True
True
True
\ No newline at end of file
diff --git a/OpenCS2hock.sln.DotSettings.user b/OpenCS2hock.sln.DotSettings.user
index 2aaabe6..87e528f 100644
--- a/OpenCS2hock.sln.DotSettings.user
+++ b/OpenCS2hock.sln.DotSettings.user
@@ -1,3 +1,4 @@
+ True
True
\ No newline at end of file
diff --git a/OpenCS2hock/Configuration.cs b/OpenCS2hock/Configuration.cs
new file mode 100644
index 0000000..34f0560
--- /dev/null
+++ b/OpenCS2hock/Configuration.cs
@@ -0,0 +1,44 @@
+using CShocker.Shockers.Abstract;
+using Microsoft.Extensions.Logging;
+using Newtonsoft.Json;
+
+namespace OpenCS2hock;
+
+public struct Configuration
+{
+ public LogLevel LogLevel = LogLevel.Information;
+
+ public List Shockers = new();
+
+ public List ShockerActions = new ();
+
+ public Configuration()
+ {
+
+ }
+
+ public override string ToString()
+ {
+ return $"Loglevel: {Enum.GetName(typeof(LogLevel), LogLevel)}\n" +
+ $"Shockers: {string.Join("\n---", Shockers)}\n" +
+ $"Actions: {string.Join("\n---", ShockerActions)}";
+ }
+
+ internal static Configuration GetConfigurationFromFile(string? path = null, ILogger? logger = null)
+ {
+ string settingsFilePath = path ?? "config.json";
+ if (!File.Exists(settingsFilePath))
+ Setup.Run().SaveConfiguration();
+
+ Configuration c = JsonConvert.DeserializeObject(File.ReadAllText(settingsFilePath), new CShocker.Shockers.ShockerJsonConverter());
+ foreach (Shocker cShocker in c.Shockers)
+ cShocker.SetLogger(logger);
+ return c;
+ }
+
+ internal void SaveConfiguration(string? path = null)
+ {
+ string settingsFilePath = path ?? "config.json";
+ File.WriteAllText(settingsFilePath, JsonConvert.SerializeObject(this, Formatting.Indented));
+ }
+}
\ No newline at end of file
diff --git a/OpenCS2hock/ConfiguredInteger.cs b/OpenCS2hock/ConfiguredInteger.cs
deleted file mode 100644
index 53bc2d8..0000000
--- a/OpenCS2hock/ConfiguredInteger.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-namespace OpenCS2hock;
-
-internal class ConfiguredInteger
-{
- private readonly int _min, _max;
-
- internal ConfiguredInteger(int min = 0, int max = 50)
- {
- this._min = min;
- this._max = max;
- }
-
- internal int GetValue()
- {
- return Random.Shared.Next(_min, _max);
- }
-}
\ No newline at end of file
diff --git a/OpenCS2hock/Installer.cs b/OpenCS2hock/Installer.cs
deleted file mode 100644
index c272ee4..0000000
--- a/OpenCS2hock/Installer.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-using Microsoft.Win32;
-using Newtonsoft.Json;
-
-namespace OpenCS2hock;
-
-public static class Installer
-{
- internal static Settings GetSettings(string? path = null)
- {
- string settingsFilePath = path ?? "config.json";
- if (!File.Exists(settingsFilePath))
- File.WriteAllText(settingsFilePath, JsonConvert.SerializeObject(new Settings(), Formatting.Indented));
-
- return JsonConvert.DeserializeObject(File.ReadAllText(settingsFilePath));
- }
-
- internal static List GetShockers(Settings settings, Logger? logger = null)
- {
- List shockers = new();
- shockers.Add(new OpenShock(settings.OpenShockSettings.Endpoint, settings.OpenShockSettings.ApiKey,
- settings.OpenShockSettings.Shockers,
- new ConfiguredInteger(settings.IntensityRange.Min, settings.IntensityRange.Max),
- new ConfiguredInteger(settings.DurationRange.Min, settings.DurationRange.Max),
- logger));
- return shockers;
- }
-}
\ No newline at end of file
diff --git a/OpenCS2hock/OpenCS2hock.cs b/OpenCS2hock/OpenCS2hock.cs
index e9082d7..7d8a871 100644
--- a/OpenCS2hock/OpenCS2hock.cs
+++ b/OpenCS2hock/OpenCS2hock.cs
@@ -1,25 +1,29 @@
using Microsoft.Extensions.Logging;
+using CS2GSI;
+using CShocker.Ranges;
+using CShocker.Shockers.Abstract;
+using CS2Event = CS2GSI.CS2GSI.CS2Event;
namespace OpenCS2hock;
+// ReSharper disable once InconsistentNaming
public class OpenCS2hock
{
private readonly CS2GSI.CS2GSI _cs2GSI;
- private readonly List _shockers;
- private readonly Settings _settings;
+ private readonly Configuration _configuration;
private readonly Logger? _logger;
- public OpenCS2hock(string? settingsPath = null, Logger? logger = null)
+ public OpenCS2hock(string? configPath = null, bool editConfig = false, Logger? logger = null)
{
this._logger = logger;
this._logger?.Log(LogLevel.Information, "Starting OpenCS2hock...");
- this._logger?.Log(LogLevel.Information, "Loading Settings...");
- _settings = Installer.GetSettings(settingsPath);
- this._logger?.Log(LogLevel.Information, $"Loglevel set to {_settings.LogLevel}");
- this._logger?.UpdateLogLevel(_settings.LogLevel);
- this._logger?.Log(LogLevel.Information, _settings.ToString());
- this._logger?.Log(LogLevel.Information, "Setting up Shockers...");
- this._shockers = Installer.GetShockers(_settings, logger);
+ this._logger?.Log(LogLevel.Information, "Loading Configuration...");
+ this._configuration = Configuration.GetConfigurationFromFile(configPath, this._logger);
+ if(editConfig)
+ Setup.EditConfig(ref this._configuration);
+ this._logger?.Log(LogLevel.Information, $"Loglevel set to {_configuration.LogLevel}");
+ this._logger?.UpdateLogLevel(_configuration.LogLevel);
+ this._logger?.Log(LogLevel.Information, _configuration.ToString());
this._cs2GSI = new CS2GSI.CS2GSI(_logger);
this.SetupEventHandlers();
while(this._cs2GSI.IsRunning)
@@ -29,41 +33,74 @@ public class OpenCS2hock
private void SetupEventHandlers()
{
this._logger?.Log(LogLevel.Information, "Setting up EventHandlers...");
- foreach (Shocker shocker in this._shockers)
+ foreach (ShockerAction shockerAction in this._configuration.ShockerActions)
{
- foreach (KeyValuePair kv in _settings.Actions)
+ foreach (string shockerId in shockerAction.ShockerIds)
{
- switch (kv.Key)
+ Shocker shocker = this._configuration.Shockers.First(s => s.ShockerIds.Contains(shockerId));
+ switch (shockerAction.TriggerEvent)
{
- case "OnKill":
- this._cs2GSI.OnKill += (cs2EventArgs) => shocker.Control(Settings.StringToAction(kv.Value));
- break;
- case "OnDeath":
- this._cs2GSI.OnDeath += (cs2EventArgs) => shocker.Control(Settings.StringToAction(kv.Value));
- break;
- case "OnRoundStart":
- this._cs2GSI.OnRoundStart += (cs2EventArgs) => shocker.Control(Settings.StringToAction(kv.Value));
- break;
- case "OnRoundEnd":
- this._cs2GSI.OnRoundOver += (cs2EventArgs) => shocker.Control(Settings.StringToAction(kv.Value));
- break;
- case "OnRoundLoss":
- this._cs2GSI.OnRoundLoss += (cs2EventArgs) => shocker.Control(Settings.StringToAction(kv.Value));
- break;
- case "OnRoundWin":
- this._cs2GSI.OnRoundWin += (cs2EventArgs) => shocker.Control(Settings.StringToAction(kv.Value));
- break;
- case "OnDamageTaken":
- this._cs2GSI.OnDamageTaken += (cs2EventArgs) =>
- shocker.Control(Settings.StringToAction(kv.Value),
- intensity: MapInt(cs2EventArgs.ValueAsOrDefault(), 0, 100,
- _settings.IntensityRange.Min, _settings.IntensityRange.Max));
- break;
+ case CS2Event.OnKill: this._cs2GSI.OnKill += args => EventHandler(args, shockerId, shocker, shockerAction); break;
+ case CS2Event.OnHeadshot: this._cs2GSI.OnHeadshot += args => EventHandler(args, shockerId, shocker, shockerAction); break;
+ case CS2Event.OnDeath: this._cs2GSI.OnDeath += args => EventHandler(args, shockerId, shocker, shockerAction); break;
+ case CS2Event.OnFlashed: this._cs2GSI.OnFlashed += args => EventHandler(args, shockerId, shocker, shockerAction); break;
+ case CS2Event.OnBurning: this._cs2GSI.OnBurning += args => EventHandler(args, shockerId, shocker, shockerAction); break;
+ case CS2Event.OnSmoked: this._cs2GSI.OnSmoked += args => EventHandler(args, shockerId, shocker, shockerAction); break;
+ case CS2Event.OnRoundStart: this._cs2GSI.OnRoundStart += args => EventHandler(args, shockerId, shocker, shockerAction); break;
+ case CS2Event.OnRoundOver: this._cs2GSI.OnRoundOver += args => EventHandler(args, shockerId, shocker, shockerAction); break;
+ case CS2Event.OnRoundWin: this._cs2GSI.OnRoundWin += args => EventHandler(args, shockerId, shocker, shockerAction); break;
+ case CS2Event.OnRoundLoss: this._cs2GSI.OnRoundLoss += args => EventHandler(args, shockerId, shocker, shockerAction); break;
+ case CS2Event.OnDamageTaken: this._cs2GSI.OnDamageTaken += args => EventHandler(args, shockerId, shocker, shockerAction); break;
+ case CS2Event.OnMatchStart: this._cs2GSI.OnMatchStart += args => EventHandler(args, shockerId, shocker, shockerAction); break;
+ case CS2Event.OnMatchOver: this._cs2GSI.OnMatchOver += args => EventHandler(args, shockerId, shocker, shockerAction); break;
+ case CS2Event.OnMoneyChange: this._cs2GSI.OnMoneyChange += args => EventHandler(args, shockerId, shocker, shockerAction); break;
+ case CS2Event.OnHealthChange: this._cs2GSI.OnHealthChange += args => EventHandler(args, shockerId, shocker, shockerAction); break;
+ case CS2Event.OnArmorChange: this._cs2GSI.OnArmorChange += args => EventHandler(args, shockerId, shocker, shockerAction); break;
+ case CS2Event.OnHelmetChange: this._cs2GSI.OnHelmetChange += args => EventHandler(args, shockerId, shocker, shockerAction); break;
+ case CS2Event.OnEquipmentValueChange: this._cs2GSI.OnEquipmentValueChange += args => EventHandler(args, shockerId, shocker, shockerAction); break;
+ case CS2Event.OnTeamChange: this._cs2GSI.OnTeamChange += args => EventHandler(args, shockerId, shocker, shockerAction); break;
+ case CS2Event.OnPlayerChange: this._cs2GSI.OnPlayerChange += args => EventHandler(args, shockerId, shocker, shockerAction); break;
+ case CS2Event.OnHalfTime: this._cs2GSI.OnHalfTime += args => EventHandler(args, shockerId, shocker, shockerAction); break;
+ case CS2Event.OnFreezeTime: this._cs2GSI.OnFreezeTime += args => EventHandler(args, shockerId, shocker, shockerAction); break;
+ case CS2Event.OnBombPlanted: this._cs2GSI.OnBombPlanted += args => EventHandler(args, shockerId, shocker, shockerAction); break;
+ case CS2Event.OnBombDefused: this._cs2GSI.OnBombDefused += args => EventHandler(args, shockerId, shocker, shockerAction); break;
+ case CS2Event.OnBombExploded: this._cs2GSI.OnBombExploded += args => EventHandler(args, shockerId, shocker, shockerAction); break;
+ case CS2Event.AnyEvent: this._cs2GSI.AnyEvent += args => EventHandler(args, shockerId, shocker, shockerAction); break;
+ case CS2Event.AnyMessage: this._cs2GSI.AnyMessage += args => EventHandler(args, shockerId, shocker, shockerAction); break;
+ default: this._logger?.Log(LogLevel.Debug, $"CS2Event {nameof(shockerAction.TriggerEvent)} unknown."); break;
}
}
}
}
+ private void EventHandler(CS2EventArgs cs2EventArgs, string shockerId, Shocker shocker, ShockerAction shockerAction)
+ {
+ this._logger?.Log(LogLevel.Information, $"Shocker: {shocker}\nID: {shockerId}\nAction: {shockerAction}\nEventArgs: {cs2EventArgs}");
+ shocker.Control(shockerAction.Action, shockerId,
+ GetIntensity(shockerAction.ValueFromInput, shockerAction.TriggerEvent, cs2EventArgs, shockerId));
+ }
+
+ private int GetIntensity(bool valueFromInput, CS2Event cs2Event, CS2EventArgs eventArgs, string shockerId)
+ {
+ return valueFromInput
+ ? IntensityFromCS2Event(cs2Event, eventArgs, shockerId)
+ : this._configuration.Shockers.First(shocker => shocker.ShockerIds.Contains(shockerId))
+ .IntensityRange.GetRandomRangeValue();
+ }
+
+ private int IntensityFromCS2Event(CS2Event cs2Event, CS2EventArgs eventArgs, string shockerId)
+ {
+ IntensityRange configuredRangeForShocker = this._configuration.Shockers
+ .First(shocker => shocker.ShockerIds.Contains(shockerId))
+ .IntensityRange;
+ return cs2Event switch
+ {
+ CS2Event.OnDamageTaken => MapInt(eventArgs.ValueAsOrDefault(), 0, 100, configuredRangeForShocker.Min, configuredRangeForShocker.Max),
+ CS2Event.OnArmorChange => MapInt(eventArgs.ValueAsOrDefault(), 0, 100, configuredRangeForShocker.Min, configuredRangeForShocker.Max),
+ _ => configuredRangeForShocker.GetRandomRangeValue()
+ };
+ }
+
private int MapInt(int input, int fromLow, int fromHigh, int toLow, int toHigh)
{
int mappedValue = (input - fromLow) * (toHigh - toLow) / (fromHigh - fromLow) + toLow;
diff --git a/OpenCS2hock/OpenCS2hock.csproj b/OpenCS2hock/OpenCS2hock.csproj
index 3301029..e762ad9 100644
--- a/OpenCS2hock/OpenCS2hock.csproj
+++ b/OpenCS2hock/OpenCS2hock.csproj
@@ -6,10 +6,12 @@
enable
enable
OpenCS2Hock
+ false
-
+
+
diff --git a/OpenCS2hock/OpenShock.cs b/OpenCS2hock/OpenShock.cs
deleted file mode 100644
index 7ef0945..0000000
--- a/OpenCS2hock/OpenShock.cs
+++ /dev/null
@@ -1,45 +0,0 @@
-using System.Net.Http.Headers;
-using System.Text;
-using Microsoft.Extensions.Logging;
-
-namespace OpenCS2hock;
-
-internal class OpenShock : Shocker
-{
- protected override void ControlInternal(ControlAction action, string shockerId, int intensity, int duration)
- {
- HttpRequestMessage request = new (HttpMethod.Post, $"{Endpoint}/1/shockers/control")
- {
- Headers =
- {
- UserAgent = { new ProductInfoHeaderValue("OpenCS2hock", "1") },
- Accept = { new MediaTypeWithQualityHeaderValue("application/json") }
- },
- Content = new StringContent(@"[ { "+
- $"\"id\": \"{shockerId}\"," +
- $"\"type\": {ControlActionToByte(action)},"+
- $"\"intensity\": {intensity},"+
- $"\"duration\": {duration}"+
- "}]", Encoding.UTF8, new MediaTypeHeaderValue("application/json"))
- };
- request.Headers.Add("OpenShockToken", ApiKey);
- HttpResponseMessage response = this.HttpClient.Send(request);
- this.Logger?.Log(LogLevel.Debug, $"{request.RequestUri} response: {response.StatusCode}");
- }
-
- private byte ControlActionToByte(ControlAction action)
- {
- return action switch
- {
- ControlAction.Beep => 3,
- ControlAction.Vibrate => 2,
- ControlAction.Shock => 1,
- _ => 0
- };
- }
-
- internal OpenShock(string endpoint, string apiKey, string[] shockerIds, ConfiguredInteger intensity, ConfiguredInteger duration, Logger? logger = null) : base(endpoint, apiKey, shockerIds, intensity, duration, logger)
- {
-
- }
-}
\ No newline at end of file
diff --git a/OpenCS2hock/Program.cs b/OpenCS2hock/Program.cs
index 0bbee14..aa27900 100644
--- a/OpenCS2hock/Program.cs
+++ b/OpenCS2hock/Program.cs
@@ -6,6 +6,6 @@ public class Program
{
public static void Main(string[] args)
{
- OpenCS2hock openCS2Hock = new OpenCS2hock(logger: new Logger(LogLevel.Information));
+ OpenCS2hock openCS2Hock = new OpenCS2hock(editConfig: true, logger: new Logger(LogLevel.Information));
}
}
\ No newline at end of file
diff --git a/OpenCS2hock/Settings.cs b/OpenCS2hock/Settings.cs
deleted file mode 100644
index e0cae3d..0000000
--- a/OpenCS2hock/Settings.cs
+++ /dev/null
@@ -1,70 +0,0 @@
-using Microsoft.Extensions.Logging;
-using Newtonsoft.Json;
-
-namespace OpenCS2hock;
-
-public struct Settings
-{
- public LogLevel LogLevel = LogLevel.Information;
- public OpenShockSettings OpenShockSettings = new()
- {
- Endpoint = "https://api.shocklink.net",
- ApiKey = "",
- Shockers = Array.Empty()
- };
-
- public Range IntensityRange = new ()
- {
- Min = 20,
- Max = 60
- };
-
- public Range DurationRange = new()
- {
- Min = 1000,
- Max = 1000
- };
-
- public Dictionary Actions = new()
- {
- {"OnKill", "Nothing"},
- {"OnDeath", "Shock"},
- {"OnRoundStart", "Vibrate"},
- {"OnRoundEnd", "Nothing"},
- {"OnRoundWin", "Beep"},
- {"OnRoundLoss", "Nothing"},
- {"OnDamageTaken", "Vibrate"}
- };
-
- public Settings()
- {
-
- }
-
- public override string ToString()
- {
- return JsonConvert.SerializeObject(this, Formatting.Indented);
- }
-
- internal static Shocker.ControlAction StringToAction(string str)
- {
- return str.ToLower() switch
- {
- "shock" => Shocker.ControlAction.Shock,
- "vibrate" => Shocker.ControlAction.Vibrate,
- "beep" => Shocker.ControlAction.Beep,
- _ => Shocker.ControlAction.Nothing
- };
- }
-}
-
-public struct OpenShockSettings
-{
- public string Endpoint, ApiKey;
- public string[] Shockers;
-}
-
-public struct Range
-{
- public short Min, Max;
-}
\ No newline at end of file
diff --git a/OpenCS2hock/Setup.cs b/OpenCS2hock/Setup.cs
new file mode 100644
index 0000000..89f81ad
--- /dev/null
+++ b/OpenCS2hock/Setup.cs
@@ -0,0 +1,242 @@
+using System.Text.RegularExpressions;
+using CShocker.Ranges;
+using CShocker.Shockers;
+using CShocker.Shockers.Abstract;
+using CShocker.Shockers.APIS;
+using Microsoft.Extensions.Logging;
+using CS2Event = CS2GSI.CS2GSI.CS2Event;
+
+namespace OpenCS2hock;
+
+public static class Setup
+{
+
+ internal static Configuration Run()
+ {
+ Console.Clear();
+ Console.WriteLine("Running first-time setup.");
+ Configuration c = new();
+
+ Console.WriteLine("First adding APIs:");
+ Console.WriteLine("Press Enter.");
+ while (Console.ReadKey().Key != ConsoleKey.Enter)
+ {//NYAA
+ }
+
+ bool addShocker = true;
+ while (c.Shockers.Count < 1 || addShocker)
+ {
+ Console.Clear();
+ AddShockerApi(ref c);
+ Console.WriteLine("Add another Shocker-API (Y/N):");
+ addShocker = Console.ReadKey().Key == ConsoleKey.Y;
+ }
+
+ Console.Clear();
+ Console.WriteLine("Now adding Actions:");
+ Console.WriteLine("Press Enter.");
+ while (Console.ReadKey().Key != ConsoleKey.Enter)
+ {//NYAA
+ }
+ bool addAction = true;
+ while (c.ShockerActions.Count < 1 || addAction)
+ {
+ Console.Clear();
+ AddAction(ref c);
+ Console.WriteLine("Add another Action (Y/N):");
+ addAction = Console.ReadKey().Key == ConsoleKey.Y;
+ }
+ return c;
+ }
+
+ internal static void EditConfig(ref Configuration c)
+ {
+ ConsoleKey? pressedKey = null;
+ while (pressedKey is not ConsoleKey.X && pressedKey is not ConsoleKey.Q)
+ {
+ Console.Clear();
+ Console.WriteLine("Config Edit Mode.");
+ Console.WriteLine("What do you want to edit?");
+ Console.WriteLine("1) LogLevel");
+ Console.WriteLine("2) Shocker-APIs");
+ Console.WriteLine("3) Event Actions");
+ Console.WriteLine("\nq) Quit Edit Mode");
+ pressedKey = Console.ReadKey().Key;
+ switch (pressedKey)
+ {
+ case ConsoleKey.D1:
+ Console.WriteLine("New LogLevel:");
+ string[] levels = Enum.GetNames();
+ for(int i = 0; i < levels.Length; i++)
+ Console.WriteLine($"{i}) {levels[i]}");
+ int selected;
+ while (!int.TryParse(Console.ReadKey().KeyChar.ToString(), out selected) || selected < 0 ||
+ selected >= levels.Length)
+ {//NYAA
+ }
+ c.LogLevel = Enum.Parse(levels[selected]);
+ break;
+ case ConsoleKey.D2:
+ bool addShocker = true;
+ while (c.Shockers.Count < 1 || addShocker)
+ {
+ Console.Clear();
+ AddShockerApi(ref c);
+ Console.WriteLine("Add another Shocker-API (Y/N):");
+ addShocker = Console.ReadKey().Key == ConsoleKey.Y;
+ }
+ break;
+ case ConsoleKey.D3:
+ bool addAction = true;
+ while (c.ShockerActions.Count < 1 || addAction)
+ {
+ Console.Clear();
+ AddAction(ref c);
+ Console.WriteLine("Add another Action (Y/N):");
+ addAction = Console.ReadKey().Key == ConsoleKey.Y;
+ }
+ break;
+ }
+ }
+ c.SaveConfiguration();
+ }
+
+ private static void AddShockerApi(ref Configuration c)
+ {
+ Console.WriteLine("Select API:");
+ Console.WriteLine("1) OpenShock (HTTP)");
+ Console.WriteLine("2) OpenShock (Serial)");
+ Console.WriteLine("3) PiShock (HTTP)");
+ Console.WriteLine("4) PiShock (Serial)");
+ string? selectedChar = Console.ReadLine();
+ int selected;
+ while (!int.TryParse(selectedChar, out selected) || selected < 1 || selected > 1)
+ selectedChar = Console.ReadLine();
+
+ Shocker newShocker;
+ switch (selected)
+ {
+ case 1: //OpenShock (HTTP)
+ string apiUri = QueryString("OpenShock API-Endpoint (https://api.shocklink.net):",
+ "https://api.shocklink.net");
+ string apiKey = QueryString("OpenShock API-Key:","");
+ Console.WriteLine("Shocker IDs associated with this API:");
+ List shockerIds = GetShockerIds(c.Shockers);
+ IntensityRange intensityRange = GetIntensityRange();
+ DurationRange durationRange = GetDurationRange();
+
+ newShocker = new OpenShockHttp(shockerIds, intensityRange, durationRange, apiUri, apiKey);
+ break;
+ // ReSharper disable thrice RedundantCaseLabel
+ case 2: //OpenShock (Serial)
+ case 3: //PiShock (HTTP)
+ case 4: //PiShock (Serial)
+ default:
+ throw new NotImplementedException();
+ }
+ c.Shockers.Add(newShocker);
+ }
+
+ private static void AddAction(ref Configuration c)
+ {
+ CS2Event triggerEvent = GetTrigger();
+ Console.WriteLine("Shocker IDs to trigger when Event occurs:");
+ List shockerIds = GetShockerIds(c.Shockers);
+ ControlAction action = GetControlAction();
+ bool useEventArgsValue = QueryBool("Try using EventArgs to control Intensity (within set limits)?", "false");
+
+ c.ShockerActions.Add(new ShockerAction(triggerEvent, shockerIds, action, useEventArgsValue));
+ }
+
+ private static bool QueryBool(string queryString, string defaultResult)
+ {
+ string value = QueryString(queryString, defaultResult);
+ bool ret;
+ while (bool.TryParse(value, out ret))
+ value = QueryString(queryString, defaultResult);
+ return ret;
+ }
+
+ private static string QueryString(string queryString, string defaultResult)
+ {
+ Console.WriteLine(queryString);
+ string? userInput = Console.ReadLine();
+ return userInput?.Length > 0 ? userInput : defaultResult;
+ }
+
+ private static IntensityRange GetIntensityRange()
+ {
+ Regex intensityRangeRex = new (@"([0-9]{1,3})\-(1?[0-9]{1,2})");
+ string intensityRangeStr = "";
+ while(!intensityRangeRex.IsMatch(intensityRangeStr))
+ intensityRangeStr = QueryString("Intensity Range (0-100) in %:", "0-100");
+ short min = short.Parse(intensityRangeRex.Match(intensityRangeStr).Groups[1].Value);
+ short max = short.Parse(intensityRangeRex.Match(intensityRangeStr).Groups[2].Value);
+ return new IntensityRange(min, max);
+ }
+
+ private static DurationRange GetDurationRange()
+ {
+ Regex intensityRangeRex = new (@"([0-9]{1,4})\-([0-9]{1,5})");
+ string intensityRangeStr = "";
+ while(!intensityRangeRex.IsMatch(intensityRangeStr))
+ intensityRangeStr = QueryString("Duration Range (500-30000) in ms:", "500-30000");
+ short min = short.Parse(intensityRangeRex.Match(intensityRangeStr).Groups[1].Value);
+ short max = short.Parse(intensityRangeRex.Match(intensityRangeStr).Groups[2].Value);
+ return new DurationRange(min, max);
+ }
+
+ private static List GetShockerIds(List shockers)
+ {
+ List allShockerIds = new();
+ foreach(Shocker shocker in shockers)
+ allShockerIds.AddRange(shocker.ShockerIds);
+
+ List ids = new();
+ bool addAnother = true;
+ while (ids.Count < 1 || addAnother)
+ {
+
+ for (int i = 0; i < allShockerIds.Count; i++)
+ Console.WriteLine($"{i}) {allShockerIds[i]}");
+
+ int selectedIndex;
+ while (!int.TryParse(Console.ReadLine(), out selectedIndex) || selectedIndex < 0 || selectedIndex >= allShockerIds.Count)
+ Console.WriteLine("Select ID:");
+
+ ids.Add(allShockerIds[selectedIndex]);
+
+ Console.WriteLine("Add another ID? (Y/N):");
+ addAnother = Console.ReadKey().Key == ConsoleKey.Y;
+ }
+ return ids;
+ }
+
+ private static CS2Event GetTrigger()
+ {
+ string[] names = Enum.GetNames(typeof(CS2Event));
+ Console.WriteLine("Select CS2 Trigger-Event:");
+ for (int i = 0; i < names.Length; i++)
+ Console.WriteLine($"{i}) {names[i]}");
+
+ int selectedIndex;
+ while (!int.TryParse(Console.ReadLine(), out selectedIndex))
+ Console.WriteLine("Select CS2 Trigger-Event:");
+
+ return Enum.Parse(names[selectedIndex]);
+ }
+
+ private static ControlAction GetControlAction()
+ {
+ string[] names = Enum.GetNames(typeof(ControlAction));
+ Console.WriteLine("Select Action:");
+ for (int i = 0; i < names.Length; i++)
+ Console.WriteLine($"{i}) {names[i]}");
+
+ int selectedIndex;
+ while (!int.TryParse(Console.ReadLine(), out selectedIndex))
+ Console.WriteLine("Select Action:");
+
+ return Enum.Parse(names[selectedIndex]);
+ }
+}
\ No newline at end of file
diff --git a/OpenCS2hock/Shocker.cs b/OpenCS2hock/Shocker.cs
deleted file mode 100644
index 3fd3a35..0000000
--- a/OpenCS2hock/Shocker.cs
+++ /dev/null
@@ -1,41 +0,0 @@
-using Microsoft.Extensions.Logging;
-
-namespace OpenCS2hock;
-
-internal abstract class Shocker
-{
- protected readonly HttpClient HttpClient;
- protected readonly string ApiKey,Endpoint;
- private readonly string[] _shockerIds;
- private readonly ConfiguredInteger _intensity, _duration;
- protected readonly Logger? Logger;
-
- internal enum ControlAction { Beep, Vibrate, Shock, Nothing }
-
- internal void Control(ControlAction action, string? shockerId = null, int? intensity = null, int? duration = null)
- {
- int i = intensity ?? _intensity.GetValue();
- int d = duration ?? _duration.GetValue();
- this.Logger?.Log(LogLevel.Information, $"{action} {(intensity is not null ? "Overwrite " : "")}{i} {(duration is not null ? "Overwrite " : "")}{d}");
- if (action is ControlAction.Nothing)
- return;
- if(shockerId is null)
- foreach (string shocker in _shockerIds)
- ControlInternal(action, shocker, i, d);
- else
- ControlInternal(action, shockerId, i, d);
- }
-
- protected abstract void ControlInternal(ControlAction action, string shockerId, int intensity, int duration);
-
- protected Shocker(string endpoint, string apiKey, string[] shockerIds, ConfiguredInteger intensity, ConfiguredInteger duration, Logger? logger = null)
- {
- this.Endpoint = endpoint;
- this.ApiKey = apiKey;
- this.HttpClient = new HttpClient();
- this._shockerIds = shockerIds;
- this._intensity = intensity;
- this._duration = duration;
- this.Logger = logger;
- }
-}
\ No newline at end of file
diff --git a/OpenCS2hock/ShockerAction.cs b/OpenCS2hock/ShockerAction.cs
new file mode 100644
index 0000000..d68eddb
--- /dev/null
+++ b/OpenCS2hock/ShockerAction.cs
@@ -0,0 +1,29 @@
+using CShocker.Shockers;
+using CS2Event = CS2GSI.CS2GSI.CS2Event;
+
+namespace OpenCS2hock;
+
+public struct ShockerAction
+{
+ public CS2Event TriggerEvent;
+ // ReSharper disable thrice FieldCanBeMadeReadOnly.Global JsonDeserializer will throw a fit
+ public List ShockerIds;
+ public ControlAction Action;
+ public bool ValueFromInput;
+
+ public ShockerAction(CS2Event trigger, List shockerIds, ControlAction action, bool valueFromInput = false)
+ {
+ this.TriggerEvent = trigger;
+ this.ShockerIds = shockerIds;
+ this.Action = action;
+ this.ValueFromInput = valueFromInput;
+ }
+
+ public override string ToString()
+ {
+ return $"Trigger Event: {Enum.GetName(typeof(CS2Event), this.TriggerEvent)}\n" +
+ $"ShockerIds: {string.Join(", ", ShockerIds)}\n" +
+ $"Action: {Enum.GetName(typeof(ControlAction), this.Action)}\n" +
+ $"ValueFromInput: {ValueFromInput}";
+ }
+}
\ No newline at end of file
diff --git a/README.md b/README.md
index 00cdc6a..7f3b33b 100644
--- a/README.md
+++ b/README.md
@@ -12,35 +12,41 @@ Example `config.json`. Place next to executable. Will also be generated on first
```json
{
"LogLevel": 2,
- "OpenShockSettings": {
- "Endpoint": "https://api.shocklink.net",
- "ApiKey": "",
- "Shockers": [ " comma seperated" ]
- },
- "IntensityRange": {
- "Min": 30,
- "Max": 60
- },
- "DurationRange": {
- "Min": 1000,
- "Max": 1000
- },
- "Actions": {
- "OnKill": "Nothing",
- "OnDeath": "Shock",
- "OnRoundStart": "Nothing",
- "OnRoundEnd": "Vibrate",
- "OnRoundWin": "Nothing",
- "OnRoundLoss": "Shock",
- "OnDamageTaken": "Vibrate"
- }
+ "Shockers": [
+ {
+ "ShockerIds": [
+ "ID HERE"
+ ],
+ "IntensityRange": {
+ "Min": 30,
+ "Max": 50
+ },
+ "DurationRange": {
+ "Min": 1000,
+ "Max": 1000
+ },
+ "ApiType": 0,
+ "Endpoint": "https://api.shocklink.net",
+ "ApiKey": "API KEY HERE"
+ }
+ ],
+ "ShockerActions": [
+ {
+ "TriggerEvent": 2,
+ "ShockerIds": [
+ "SAME ID HERE"
+ ],
+ "Action": 2,
+ "ValueFromInput": false
+ }
+ ]
}
```
### ApiKey
For OpenShock get token [here](https://shocklink.net/#/dashboard/tokens)
-### Shockers
+### ShockerIds
List of Shocker-Ids, comma seperated. Get Id [here](https://shocklink.net/#/dashboard/shockers/own). Press the three dots -> Edit
Example `[ "ID-1", "ID-2" ]`
@@ -56,5 +62,15 @@ in ms
- Beep
- Shock
- Vibrate
+- Nothing
-# Using [CS2GSI](https://github.com/C9Glax/CS2GSI)
\ No newline at end of file
+# Using
+### CS2GSI
+[![GitHub License](https://img.shields.io/github/license/c9glax/CS2GSI)](/LICENSE)
+[![NuGet Version](https://img.shields.io/nuget/v/CS2GSI)](https://www.nuget.org/packages/CS2GSI/)
+[![Github](https://img.shields.io/badge/Github-8A2BE2)](https://github.com/C9Glax/CS2GSI)
+[![GitHub Release](https://img.shields.io/github/v/release/c9glax/CS2GSI)](https://github.com/C9Glax/CS2GSI/releases/latest)
+### CShocker
+[![GitHub License](https://img.shields.io/github/license/c9glax/cshocker)](https://github.com/C9Glax/CShocker)
+[![Github](https://img.shields.io/badge/Github-8A2BE2)](https://github.com/C9Glax/cshocker)
+[![NuGet Version](https://img.shields.io/nuget/v/CShocker)](https://shields.io/badges/nu-get-version)
\ No newline at end of file