diff --git a/OpenCS2hock.sln.DotSettings.user b/OpenCS2hock.sln.DotSettings.user
index 26eddfc..2aaabe6 100644
--- a/OpenCS2hock.sln.DotSettings.user
+++ b/OpenCS2hock.sln.DotSettings.user
@@ -1,3 +1,3 @@
- True
+
True
\ No newline at end of file
diff --git a/OpenCS2hock/CS2MessageHandler.cs b/OpenCS2hock/CS2MessageHandler.cs
deleted file mode 100644
index 08f8421..0000000
--- a/OpenCS2hock/CS2MessageHandler.cs
+++ /dev/null
@@ -1,72 +0,0 @@
-using Newtonsoft.Json.Linq;
-
-namespace OpenCS2hock;
-
-internal class CS2MessageHandler
-{
- internal delegate void CS2EventHandler();
- internal event CS2EventHandler? OnKill;
- internal event CS2EventHandler? OnDeath;
- internal event CS2EventHandler? OnRoundStart;
- internal event CS2EventHandler? OnRoundEnd;
- internal event CS2EventHandler? OnRoundWin;
- internal event CS2EventHandler? OnRoundLoss;
-
- internal void HandleCS2Message(string message, string mySteamId)
- {
- JObject messageJson = JObject.Parse(message);
- string? previousSteamId = messageJson.SelectToken("previously.player.steamid", false)?.Value();
- string? currentSteamId = messageJson.SelectToken("player.steamid", false)?.Value();
-
- RoundState currentRoundState = ParseRoundStateFromString(messageJson.SelectToken("round.phase", false)?.Value());
- RoundState previousRoundState = ParseRoundStateFromString(messageJson.SelectToken("previously.round.phase", false)?.Value());
- if(previousRoundState == RoundState.Over && currentRoundState == RoundState.Live)
- OnRoundStart?.Invoke();
- if(previousRoundState == RoundState.Live && currentRoundState == RoundState.FreezeTime)
- OnRoundEnd?.Invoke();
- if(previousRoundState == RoundState.Live && currentRoundState == RoundState.Over)
- OnRoundEnd?.Invoke();
-
- Team playerTeam = ParseTeamFromString(messageJson.SelectToken("player.team", false)?.Value());
- Team winnerTeam = ParseTeamFromString(messageJson.SelectToken("round.win_team", false)?.Value());
- if(winnerTeam != Team.None && playerTeam != Team.None && playerTeam == winnerTeam)
- OnRoundWin?.Invoke();
- else if(winnerTeam != Team.None && playerTeam != Team.None && playerTeam != winnerTeam)
- OnRoundLoss?.Invoke();
-
- int? previousDeaths = messageJson.SelectToken("previously.player.match_stats.deaths", false)?.Value();
- int? currentDeaths = messageJson.SelectToken("player.match_stats.deaths", false)?.Value();
- if(previousSteamId is null && currentSteamId == mySteamId && currentDeaths > previousDeaths)
- OnDeath?.Invoke();
-
- int? previousKills = messageJson.SelectToken("previously.player.match_stats.kills", false)?.Value();
- int? currentKills = messageJson.SelectToken("player.match_stats.kills", false)?.Value();
- if(previousSteamId is null && currentSteamId == mySteamId && currentKills > previousKills)
- OnKill?.Invoke();
- }
-
- private RoundState ParseRoundStateFromString(string? str)
- {
- return str switch
- {
- "live" => RoundState.Live,
- "freezetime" => RoundState.FreezeTime,
- "over" => RoundState.Over,
- _ => RoundState.Unknown
- };
- }
-
- private Team ParseTeamFromString(string? str)
- {
- return str switch
- {
- "T" => Team.T,
- "CT" => Team.CT,
- _ => Team.None
- };
- }
-
- private enum RoundState {FreezeTime, Live, Over, Unknown}
-
- private enum Team {T, CT, None}
-}
\ No newline at end of file
diff --git a/OpenCS2hock/GSIServer.cs b/OpenCS2hock/GSIServer.cs
deleted file mode 100644
index 11f30d1..0000000
--- a/OpenCS2hock/GSIServer.cs
+++ /dev/null
@@ -1,51 +0,0 @@
-using System.Net;
-using System.Text;
-
-namespace OpenCS2hock;
-
-internal class GSIServer
-{
- private HttpListener HttpListener { get; init; }
- internal delegate void OnMessageEventHandler(string content);
- internal event OnMessageEventHandler? OnMessage;
-
- private bool _keepRunning = true;
- internal bool IsRunning { get; private set; }
-
- internal GSIServer(int port)
- {
- HttpListener = new HttpListener();
- HttpListener.Prefixes.Add($"http://127.0.0.1:{port}/");
- HttpListener.Start();
-
- Thread connectionListener = new (HandleConnection);
- connectionListener.Start();
-
- IsRunning = true;
- }
-
- private async void HandleConnection()
- {
- while (_keepRunning)
- {
- HttpListenerContext context = await HttpListener.GetContextAsync();
- HttpListenerRequest request = context.Request;
-
- Console.WriteLine($"[{request.HttpMethod}] {request.Url} - {request.UserAgent}");
-
- HttpResponseMessage responseMessage = new (HttpStatusCode.Accepted);
- context.Response.OutputStream.Write(Encoding.UTF8.GetBytes(responseMessage.ToString()));
-
- StreamReader reader = new (request.InputStream, request.ContentEncoding);
- string content = await reader.ReadToEndAsync();
- OnMessage?.Invoke(content);
- }
- HttpListener.Close();
- IsRunning = false;
- }
-
- internal void Dispose()
- {
- _keepRunning = false;
- }
-}
\ No newline at end of file
diff --git a/OpenCS2hock/Installer.cs b/OpenCS2hock/Installer.cs
index 0757ffa..c272ee4 100644
--- a/OpenCS2hock/Installer.cs
+++ b/OpenCS2hock/Installer.cs
@@ -14,46 +14,14 @@ public static class Installer
return JsonConvert.DeserializeObject(File.ReadAllText(settingsFilePath));
}
- internal static List GetShockers(Settings settings)
+ 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)));
+ new ConfiguredInteger(settings.DurationRange.Min, settings.DurationRange.Max),
+ logger));
return shockers;
}
-
- internal static void InstallGsi()
- {
- string installLocation = Path.Combine(GetInstallDirectory(), "game\\csgo\\cfg\\gamestate_integration_opencs2hock.cfg");
- File.WriteAllText(installLocation, Resources.GSI_CFG_Content);
- }
-
- private static string GetInstallDirectory(int appId = 730)
- {
- string steamInstallation =
-#pragma warning disable CA1416 //Registry only available on Windows
- (string)(Registry.GetValue(@"HKEY_CURRENT_USER\SOFTWARE\Valve\Steam", "SteamPath", null) ??
-#pragma warning restore CA1416
- throw new DirectoryNotFoundException("No Steam Installation found."));
- string libraryFolderFilepath = Path.Combine(steamInstallation, "steamapps\\libraryfolders.vdf");
- string? libraryPath = null;
- string? appManifestFolderPath = null;
- foreach (string line in File.ReadAllLines(libraryFolderFilepath))
- if (line.Contains("path"))
- libraryPath = line.Split("\"").Last(split => split.Length > 0);
- else if (line.Contains($"\"{appId}\""))
- appManifestFolderPath = Path.Combine(libraryPath!, $"steamapps\\appmanifest_{appId}.acf");
-
- string installationPath = "";
- if (appManifestFolderPath is null)
- throw new DirectoryNotFoundException($"No {appId} Installation found.");
- foreach(string line in File.ReadAllLines(appManifestFolderPath))
- if (line.Contains("installdir"))
- installationPath = Path.Combine(libraryPath!, "steamapps\\common", line.Split("\"").Last(split => split.Length > 0));
-
- return installationPath;
- }
-
}
\ No newline at end of file
diff --git a/OpenCS2hock/Logger.cs b/OpenCS2hock/Logger.cs
new file mode 100644
index 0000000..8a8c0da
--- /dev/null
+++ b/OpenCS2hock/Logger.cs
@@ -0,0 +1,65 @@
+using Microsoft.Extensions.Logging;
+
+namespace OpenCS2hock;
+
+public class Logger : ILogger
+{
+ private LogLevel _enabledLoglevel;
+ private readonly ConsoleColor _defaultForegroundColor = Console.ForegroundColor;
+ private readonly ConsoleColor _defaultBackgroundColor = Console.BackgroundColor;
+
+ public Logger(LogLevel logLevel = LogLevel.Trace)
+ {
+ _enabledLoglevel = logLevel;
+ }
+
+ public void UpdateLogLevel(LogLevel logLevel)
+ {
+ this._enabledLoglevel = logLevel;
+ }
+
+ public void Log(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func formatter)
+ {
+ if (!IsEnabled(logLevel))
+ return;
+ Console.ForegroundColor = ForegroundColorForLogLevel(logLevel);
+ Console.BackgroundColor = BackgroundColorForLogLevel(logLevel);
+ Console.Write(logLevel.ToString()[..3].ToUpper());
+ Console.ResetColor();
+ // ReSharper disable once LocalizableElement
+ Console.Write($" [{DateTime.UtcNow:HH:mm:ss.fff}] ");
+ Console.WriteLine(formatter.Invoke(state, exception));
+ }
+
+ public bool IsEnabled(LogLevel logLevel)
+ {
+ return logLevel >= _enabledLoglevel;
+ }
+
+ public IDisposable? BeginScope(TState state) where TState : notnull
+ {
+ return null;
+ }
+
+ private ConsoleColor ForegroundColorForLogLevel(LogLevel logLevel)
+ {
+ return logLevel switch
+ {
+ LogLevel.Error or LogLevel.Critical => ConsoleColor.Black,
+ LogLevel.Debug => ConsoleColor.Black,
+ LogLevel.Information => ConsoleColor.White,
+ _ => _defaultForegroundColor
+ };
+ }
+
+ private ConsoleColor BackgroundColorForLogLevel(LogLevel logLevel)
+ {
+ return logLevel switch
+ {
+ LogLevel.Error or LogLevel.Critical => ConsoleColor.Red,
+ LogLevel.Debug => ConsoleColor.Yellow,
+ LogLevel.Information => ConsoleColor.Black,
+ _ => _defaultBackgroundColor
+ };
+ }
+}
\ No newline at end of file
diff --git a/OpenCS2hock/OpenCS2hock.cs b/OpenCS2hock/OpenCS2hock.cs
index 924f9d9..e29b1ee 100644
--- a/OpenCS2hock/OpenCS2hock.cs
+++ b/OpenCS2hock/OpenCS2hock.cs
@@ -1,35 +1,34 @@
-namespace OpenCS2hock;
+using Microsoft.Extensions.Logging;
+
+namespace OpenCS2hock;
public class OpenCS2hock
{
- private GSIServer GSIServer { get; init; }
- private readonly CS2MessageHandler _cs2MessageHandler;
+ private readonly CS2GSI.CS2GSI _cs2GSI;
private readonly List _shockers;
private readonly Settings _settings;
+ private readonly Logger? _logger;
- public OpenCS2hock(string? settingsPath = null)
+ public OpenCS2hock(string? settingsPath = null, 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._shockers = Installer.GetShockers(_settings);
- Console.WriteLine(_settings);
- Installer.InstallGsi();
-
- this._cs2MessageHandler = new CS2MessageHandler();
+ 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._cs2GSI = new CS2GSI.CS2GSI(_logger);
this.SetupEventHandlers();
-
- this.GSIServer = new GSIServer(3000);
- this.GSIServer.OnMessage += OnGSIMessage;
-
- Thread runningThread = new(() =>
- {
- while (GSIServer.IsRunning)
- Thread.Sleep(10);
- });
- runningThread.Start();
+ while(this._cs2GSI.IsRunning)
+ Thread.Sleep(10);
}
private void SetupEventHandlers()
{
+ this._logger?.Log(LogLevel.Information, "Setting up EventHandlers...");
foreach (Shocker shocker in this._shockers)
{
foreach (KeyValuePair kv in _settings.Actions)
@@ -37,33 +36,25 @@ public class OpenCS2hock
switch (kv.Key)
{
case "OnKill":
- this._cs2MessageHandler.OnKill += () => shocker.Control(Settings.StringToAction(kv.Value));
+ this._cs2GSI.OnKill += (cs2EventArgs) => shocker.Control(Settings.StringToAction(kv.Value));
break;
case "OnDeath":
- this._cs2MessageHandler.OnDeath += () => shocker.Control(Settings.StringToAction(kv.Value));
+ this._cs2GSI.OnDeath += (cs2EventArgs) => shocker.Control(Settings.StringToAction(kv.Value));
break;
case "OnRoundStart":
- this._cs2MessageHandler.OnRoundStart += () => shocker.Control(Settings.StringToAction(kv.Value));
+ this._cs2GSI.OnRoundStart += (cs2EventArgs) => shocker.Control(Settings.StringToAction(kv.Value));
break;
case "OnRoundEnd":
- this._cs2MessageHandler.OnRoundEnd += () => shocker.Control(Settings.StringToAction(kv.Value));
+ this._cs2GSI.OnRoundOver += (cs2EventArgs) => shocker.Control(Settings.StringToAction(kv.Value));
break;
case "OnRoundLoss":
- this._cs2MessageHandler.OnRoundLoss += () => shocker.Control(Settings.StringToAction(kv.Value));
+ this._cs2GSI.OnRoundLoss += (cs2EventArgs) => shocker.Control(Settings.StringToAction(kv.Value));
break;
case "OnRoundWin":
- this._cs2MessageHandler.OnRoundWin += () => shocker.Control(Settings.StringToAction(kv.Value));
+ this._cs2GSI.OnRoundWin += (cs2EventArgs) => shocker.Control(Settings.StringToAction(kv.Value));
break;
}
}
}
}
-
- private void OnGSIMessage(string content)
- {
- Directory.CreateDirectory(Path.Combine(Environment.CurrentDirectory, "CS2Events"));
- string fileName = Path.Combine(Environment.CurrentDirectory, "CS2Events" ,$"{DateTime.Now.ToLongTimeString().Replace(':','.')}.json");
- File.WriteAllText(fileName, content);
- _cs2MessageHandler.HandleCS2Message(content, _settings.SteamId);
- }
}
\ No newline at end of file
diff --git a/OpenCS2hock/OpenCS2hock.csproj b/OpenCS2hock/OpenCS2hock.csproj
index 885795a..1f1adf2 100644
--- a/OpenCS2hock/OpenCS2hock.csproj
+++ b/OpenCS2hock/OpenCS2hock.csproj
@@ -9,21 +9,7 @@
-
- ResXFileCodeGenerator
- Resources.Designer.cs
-
-
-
-
-
- True
- True
- Resources.resx
-
-
-
-
+
diff --git a/OpenCS2hock/OpenShock.cs b/OpenCS2hock/OpenShock.cs
index dd2dee2..7ef0945 100644
--- a/OpenCS2hock/OpenShock.cs
+++ b/OpenCS2hock/OpenShock.cs
@@ -1,5 +1,6 @@
using System.Net.Http.Headers;
using System.Text;
+using Microsoft.Extensions.Logging;
namespace OpenCS2hock;
@@ -23,7 +24,7 @@ internal class OpenShock : Shocker
};
request.Headers.Add("OpenShockToken", ApiKey);
HttpResponseMessage response = this.HttpClient.Send(request);
- Console.WriteLine($"{request.RequestUri} response: {response.StatusCode}");
+ this.Logger?.Log(LogLevel.Debug, $"{request.RequestUri} response: {response.StatusCode}");
}
private byte ControlActionToByte(ControlAction action)
@@ -37,7 +38,7 @@ internal class OpenShock : Shocker
};
}
- internal OpenShock(string endpoint, string apiKey, string[] shockerIds, ConfiguredInteger intensity, ConfiguredInteger duration) : base(endpoint, apiKey, shockerIds, intensity, duration)
+ internal OpenShock(string endpoint, string apiKey, string[] shockerIds, ConfiguredInteger intensity, ConfiguredInteger duration, Logger? logger = null) : base(endpoint, apiKey, shockerIds, intensity, duration, logger)
{
}
diff --git a/OpenCS2hock/Program.cs b/OpenCS2hock/Program.cs
index 5ab0d37..0bbee14 100644
--- a/OpenCS2hock/Program.cs
+++ b/OpenCS2hock/Program.cs
@@ -1,9 +1,11 @@
-namespace OpenCS2hock;
+using Microsoft.Extensions.Logging;
+
+namespace OpenCS2hock;
public class Program
{
public static void Main(string[] args)
{
- OpenCS2hock openCS2Hock = new OpenCS2hock();
+ OpenCS2hock openCS2Hock = new OpenCS2hock(logger: new Logger(LogLevel.Information));
}
}
\ No newline at end of file
diff --git a/OpenCS2hock/Resources.Designer.cs b/OpenCS2hock/Resources.Designer.cs
deleted file mode 100644
index fe02fff..0000000
--- a/OpenCS2hock/Resources.Designer.cs
+++ /dev/null
@@ -1,88 +0,0 @@
-//------------------------------------------------------------------------------
-//
-// This code was generated by a tool.
-//
-// Changes to this file may cause incorrect behavior and will be lost if
-// the code is regenerated.
-//
-//------------------------------------------------------------------------------
-
-namespace OpenCS2hock {
- using System;
-
-
- ///
- /// A strongly-typed resource class, for looking up localized strings, etc.
- ///
- // This class was auto-generated by the StronglyTypedResourceBuilder
- // class via a tool like ResGen or Visual Studio.
- // To add or remove a member, edit your .ResX file then rerun ResGen
- // with the /str option, or rebuild your VS project.
- [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
- internal class Resources {
-
- private static global::System.Resources.ResourceManager resourceMan;
-
- private static global::System.Globalization.CultureInfo resourceCulture;
-
- [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
- internal Resources() {
- }
-
- ///
- /// Returns the cached ResourceManager instance used by this class.
- ///
- [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
- internal static global::System.Resources.ResourceManager ResourceManager {
- get {
- if (object.ReferenceEquals(resourceMan, null)) {
- global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("OpenCS2Hock.Resources", typeof(Resources).Assembly);
- resourceMan = temp;
- }
- return resourceMan;
- }
- }
-
- ///
- /// Overrides the current thread's CurrentUICulture property for all
- /// resource lookups using this strongly typed resource class.
- ///
- [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
- internal static global::System.Globalization.CultureInfo Culture {
- get {
- return resourceCulture;
- }
- set {
- resourceCulture = value;
- }
- }
-
- ///
- /// Looks up a localized string similar to "OpenCS2hock"
- ///{
- ///"uri" "http://127.0.0.1:3000"
- ///"timeout" "5.0"
- ///"buffer" "0.1"
- ///"throttle" "0.5"
- ///"heartbeat" "60.0"
- ///"output"
- /// {
- /// "precision_time" "3"
- /// "precision_position" "1"
- /// "precision_vector" "3"
- /// }
- ///"data"
- /// {
- /// "provider" "1" // general info about client being listened to: game name, appid, client steamid, etc.
- /// "map" "1" // map, gamemode, and current match phase ('warmup', 'intermission', 'gameover', 'live') and current score
- /// [rest of string was truncated]";.
- ///
- internal static string GSI_CFG_Content {
- get {
- return ResourceManager.GetString("GSI_CFG_Content", resourceCulture);
- }
- }
- }
-}
diff --git a/OpenCS2hock/Resources.resx b/OpenCS2hock/Resources.resx
deleted file mode 100644
index d80b24a..0000000
--- a/OpenCS2hock/Resources.resx
+++ /dev/null
@@ -1,24 +0,0 @@
-
-
-
-
-
-
-
-
-
- text/microsoft-resx
-
-
- 1.3
-
-
- System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- gamestate_integration_opencs2hock.cfg;System.String, mscorlib, Version=4.0.0.0, Culture=neutral
-
-
\ No newline at end of file
diff --git a/OpenCS2hock/Settings.cs b/OpenCS2hock/Settings.cs
index 2d63653..26f57bd 100644
--- a/OpenCS2hock/Settings.cs
+++ b/OpenCS2hock/Settings.cs
@@ -1,10 +1,11 @@
-using Newtonsoft.Json;
+using Microsoft.Extensions.Logging;
+using Newtonsoft.Json;
namespace OpenCS2hock;
public struct Settings
{
- public string SteamId = "";
+ public LogLevel LogLevel = LogLevel.Information;
public OpenShockSettings OpenShockSettings = new()
{
Endpoint = "https://api.shocklink.net",
diff --git a/OpenCS2hock/Shocker.cs b/OpenCS2hock/Shocker.cs
index ef09f15..a999ba4 100644
--- a/OpenCS2hock/Shocker.cs
+++ b/OpenCS2hock/Shocker.cs
@@ -1,4 +1,6 @@
-namespace OpenCS2hock;
+using Microsoft.Extensions.Logging;
+
+namespace OpenCS2hock;
internal abstract class Shocker
{
@@ -6,6 +8,7 @@ internal abstract class Shocker
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 }
@@ -13,7 +16,7 @@ internal abstract class Shocker
{
int intensity = _intensity.GetValue();
int duration = _duration.GetValue();
- Console.WriteLine($"{action} {intensity} {duration}");
+ this.Logger?.Log(LogLevel.Information, $"{action} {intensity} {duration}");
if (action is ControlAction.Nothing)
return;
if(shockerId is null)
@@ -25,7 +28,7 @@ internal abstract class Shocker
protected abstract void ControlInternal(ControlAction action, string shockerId, int intensity, int duration);
- protected Shocker(string endpoint, string apiKey, string[] shockerIds, ConfiguredInteger intensity, ConfiguredInteger duration)
+ protected Shocker(string endpoint, string apiKey, string[] shockerIds, ConfiguredInteger intensity, ConfiguredInteger duration, Logger? logger = null)
{
this.Endpoint = endpoint;
this.ApiKey = apiKey;
@@ -33,5 +36,6 @@ internal abstract class Shocker
this._shockerIds = shockerIds;
this._intensity = intensity;
this._duration = duration;
+ this.Logger = logger;
}
}
\ No newline at end of file
diff --git a/OpenCS2hock/gamestate_integration_opencs2hock.cfg b/OpenCS2hock/gamestate_integration_opencs2hock.cfg
deleted file mode 100644
index c131ebe..0000000
--- a/OpenCS2hock/gamestate_integration_opencs2hock.cfg
+++ /dev/null
@@ -1,23 +0,0 @@
-"OpenCS2hock"
-{
-"uri" "http://127.0.0.1:3000"
-"timeout" "2.0"
-"buffer" "0.0"
-"throttle" "0.1"
-"heartbeat" "60.0"
-"output"
- {
- "precision_time" "3"
- "precision_position" "1"
- "precision_vector" "3"
- }
-"data"
- {
- "provider" "1" // general info about client being listened to: game name, appid, client steamid, etc.
- "map" "1" // map, gamemode, and current match phase ('warmup', 'intermission', 'gameover', 'live') and current score
- "round" "1" // round phase ('freezetime', 'over', 'live'), bomb state ('planted', 'exploded', 'defused'), and round winner (if any)
- "player_id" "1" // player name, clan tag, observer slot (ie key to press to observe this player) and team
- "player_state" "1" // player state for this current round such as health, armor, kills this round, etc.
- "player_match_stats" "1" // player stats this match such as kill, assists, score, deaths and MVPs
- }
-}
\ No newline at end of file