diff --git a/ArchiSteamFarm b/ArchiSteamFarm index 716b253..e4c20df 160000 --- a/ArchiSteamFarm +++ b/ArchiSteamFarm @@ -1 +1 @@ -Subproject commit 716b253a044c9560bea1e9a77cb34afede93c6a3 +Subproject commit e4c20df4a896209636078c7acf33fbcaa8ad35bc diff --git a/CS2Interface/AdapterBridge.cs b/CS2Interface/AdapterBridge.cs new file mode 100644 index 0000000..9080dde --- /dev/null +++ b/CS2Interface/AdapterBridge.cs @@ -0,0 +1,32 @@ +using System; +using System.Reflection; +using ArchiSteamFarm.Core; + +// ASFEnhanced Adapter https://github.com/chr233/ASFEnhanceAdapterDemoPlugin + +namespace CS2Interface; +internal static class AdapterBridge { + public static bool InitAdapter(string pluginName, string pluginId, string? cmdPrefix, string? repoName, MethodInfo? cmdHandler) { + try { + var adapterEndpoint = Assembly.Load("ASFEnhance").GetType("ASFEnhance._Adapter_.Endpoint"); + var registerModule = adapterEndpoint?.GetMethod("RegisterModule", BindingFlags.Static | BindingFlags.Public); + var pluinVersion = Assembly.GetExecutingAssembly().GetName().Version; + + if (registerModule != null && adapterEndpoint != null) { + var result = registerModule?.Invoke(null, new object?[] { pluginName, pluginId, cmdPrefix, repoName, pluinVersion, cmdHandler }); + + if (result is string str) { + if (str == pluginName) { + return true; + } else { + ASF.ArchiLogger.LogGenericWarning(str); + } + } + } + } catch (Exception ex) { + ASF.ArchiLogger.LogGenericException(ex, "Community with ASFEnhance failed"); + } + + return false; + } +} diff --git a/CS2Interface/CS/Client.cs b/CS2Interface/CS/Client.cs index 8f1af41..7dc14d1 100644 --- a/CS2Interface/CS/Client.cs +++ b/CS2Interface/CS/Client.cs @@ -125,6 +125,10 @@ private void OnGCMessage(SteamGameCoordinator.MessageCallback callback) { return; } +#if DEBUG + Bot.ArchiLogger.LogGenericDebug(String.Format("Message Received: {0}", callback.EMsg)); +#endif + OnGCMessageRecieved?.Invoke(callback); var messageMap = new Dictionary> { diff --git a/CS2Interface/CS2Interface.cs b/CS2Interface/CS2Interface.cs index 1e7c612..ae2ab93 100644 --- a/CS2Interface/CS2Interface.cs +++ b/CS2Interface/CS2Interface.cs @@ -5,9 +5,10 @@ using ArchiSteamFarm.Core; using ArchiSteamFarm.Steam; using ArchiSteamFarm.Plugins.Interfaces; -using Newtonsoft.Json.Linq; using SteamKit2; using System.Collections.Concurrent; +using System.Text.Json; +using System.Reflection; namespace CS2Interface { [Export(typeof(IPlugin))] @@ -15,17 +16,33 @@ public sealed class CS2Interface : IASF, IBotModules, IBotSteamClient, IBotComma internal static ConcurrentDictionary AutoStart = new(); public string Name => nameof(CS2Interface); public Version Version => typeof(CS2Interface).Assembly.GetName().Version ?? new Version("0"); + private bool ASFEnhanceEnabled = false; public Task OnLoaded() { ASF.ArchiLogger.LogGenericInfo("Counter-Strike 2 Interface ASF Plugin by Citrinate"); GameData.Update(); + // ASFEnhanced Adapter https://github.com/chr233/ASFEnhanceAdapterDemoPlugin + var flag = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; + var handler = typeof(Commands).GetMethod(nameof(Commands.Response), flag); + const string pluginId = nameof(CS2Interface); + const string cmdPrefix = "CS2INTERFACE"; + const string repoName = "Citrinate/CS2Interface"; + var registered = AdapterBridge.InitAdapter(Name, pluginId, cmdPrefix, repoName, handler); + ASFEnhanceEnabled = registered; + return Task.CompletedTask; } - public async Task OnBotCommand(Bot bot, EAccess access, string message, string[] args, ulong steamID = 0) => await Commands.Response(bot, access, steamID, message, args).ConfigureAwait(false); + public async Task OnBotCommand(Bot bot, EAccess access, string message, string[] args, ulong steamID = 0) { + if (ASFEnhanceEnabled) { + return null; + } + + return await Commands.Response(bot, access, steamID, message, args).ConfigureAwait(false); + } - public Task OnASFInit(IReadOnlyDictionary? additionalConfigProperties = null) { + public Task OnASFInit(IReadOnlyDictionary? additionalConfigProperties = null) { if (additionalConfigProperties == null) { return Task.FromResult(0); } @@ -33,16 +50,16 @@ public Task OnASFInit(IReadOnlyDictionary? additionalConfigPrope return Task.FromResult(0); } - public Task OnBotInitModules(Bot bot, IReadOnlyDictionary? additionalConfigProperties = null) { + public Task OnBotInitModules(Bot bot, IReadOnlyDictionary? additionalConfigProperties = null) { if (additionalConfigProperties == null) { return Task.FromResult(0); } - foreach (KeyValuePair configProperty in additionalConfigProperties) { + foreach (KeyValuePair configProperty in additionalConfigProperties) { switch (configProperty.Key) { - case "AutoStartCS2Interface" when configProperty.Value.Type == JTokenType.Boolean: { - bot.ArchiLogger.LogGenericInfo("AutoStartCS2Interface : " + configProperty.Value); - AutoStart[bot.BotName] = configProperty.Value.ToObject(); + case "AutoStartCS2Interface" when (configProperty.Value.ValueKind == JsonValueKind.True || configProperty.Value.ValueKind == JsonValueKind.False): { + bot.ArchiLogger.LogGenericInfo("AutoStartCS2Interface : " + configProperty.Value.GetBoolean()); + AutoStart[bot.BotName] = configProperty.Value.GetBoolean(); break; } } diff --git a/CS2Interface/CS2Interface.csproj b/CS2Interface/CS2Interface.csproj index 78d8440..b797c32 100644 --- a/CS2Interface/CS2Interface.csproj +++ b/CS2Interface/CS2Interface.csproj @@ -2,7 +2,7 @@ Citrinate - 1.0.6 + 1.0.7 enable latest net8.0 diff --git a/CS2Interface/Commands.cs b/CS2Interface/Commands.cs index a824a3b..dff0efc 100644 --- a/CS2Interface/Commands.cs +++ b/CS2Interface/Commands.cs @@ -21,12 +21,17 @@ internal static class Commands { switch (args.Length) { case 1: switch (args[0].ToUpperInvariant()) { + case "CS2INTERFACE" when access >= EAccess.FamilySharing: + return String.Format("{0} {1}", nameof(CS2Interface), (typeof(CS2Interface).Assembly.GetName().Version ?? new Version("0")).ToString()); + case "CSTART" or "CSSTART" or "CS2START" or "CRUN" or "CSRUN" or "CS2RUN": return await ResponseRun(bot, access).ConfigureAwait(false); case "CSTOP" or "CSSTOP" or "CS2STOP": return ResponseStop(bot, access); + case "CSA": + return ResponseStatus(access, steamID, "ASF"); case "CSTATUS" or "CSSTATUS" or "CS2STATUS": return ResponseStatus(bot, access); diff --git a/CS2Interface/Data/InspectItem.cs b/CS2Interface/Data/InspectItem.cs index f61e50f..45d8345 100644 --- a/CS2Interface/Data/InspectItem.cs +++ b/CS2Interface/Data/InspectItem.cs @@ -1,16 +1,17 @@ using System; using System.Linq; -using Newtonsoft.Json; +using System.Text.Json.Serialization; using SteamKit2.GC.CSGO.Internal; namespace CS2Interface { - internal sealed class InspectItem : Item { - [JsonProperty(PropertyName = "iteminfo")] - internal CEconItemPreviewDataBlock ItemInfo; - internal string s; - internal string a; - internal string d; - internal string m; + public sealed class InspectItem : Item { + [JsonInclude] + [JsonPropertyName("iteminfo")] + public CEconItemPreviewDataBlock ItemInfo { get; private init; } + public string s; + public string a; + public string d; + public string m; internal InspectItem(CMsgGCCStrike15_v2_Client2GCEconPreviewDataBlockResponse item, ulong param_s, ulong param_a, ulong param_d, ulong param_m) { ItemInfo = item.iteminfo; diff --git a/CS2Interface/Data/InventoryItem.cs b/CS2Interface/Data/InventoryItem.cs index 9cd624e..498dfe2 100644 --- a/CS2Interface/Data/InventoryItem.cs +++ b/CS2Interface/Data/InventoryItem.cs @@ -2,28 +2,33 @@ using System.Collections.Generic; using System.Linq; using System.Text; +using System.Text.Json.Serialization; using ArchiSteamFarm.Core; -using Newtonsoft.Json; using SteamKit2; using SteamKit2.GC.CSGO.Internal; namespace CS2Interface { - internal sealed class InventoryItem : Item { - [JsonProperty(PropertyName = "iteminfo")] - internal CSOEconItem ItemInfo; + public sealed class InventoryItem : Item { + [JsonInclude] + [JsonPropertyName("iteminfo")] + public CSOEconItem ItemInfo { get; private init; } - [JsonProperty(PropertyName = "attributes")] + [JsonInclude] + [JsonPropertyName("attributes")] [JsonConverter (typeof(AttributeConverter))] - Dictionary? Attributes; + public Dictionary? Attributes { get; private set; } - [JsonProperty(PropertyName = "position")] - internal uint? Position; + [JsonInclude] + [JsonPropertyName("position")] + public uint? Position { get; private set; } - [JsonProperty(PropertyName = "casket_id")] - internal ulong? CasketID; + [JsonInclude] + [JsonPropertyName("casket_id")] + public ulong? CasketID { get; private set; } - [JsonProperty(PropertyName = "moveable")] - internal bool? Moveable; + [JsonInclude] + [JsonPropertyName("moveable")] + public bool? Moveable { get; private set; } public bool ShouldSerializeAttributes() => Attributes != null && ShouldSerializeAdditionalProperties; public bool ShouldSerializePosition() => Position != null && ShouldSerializeAdditionalProperties; diff --git a/CS2Interface/Data/Item.cs b/CS2Interface/Data/Item.cs index bee1645..8cd26cb 100644 --- a/CS2Interface/Data/Item.cs +++ b/CS2Interface/Data/Item.cs @@ -1,87 +1,110 @@ using System; using System.Linq; -using Newtonsoft.Json; +using System.Text.Json.Serialization; using SteamKit2; namespace CS2Interface { - internal class Item { - internal uint DefIndex; - internal uint PaintIndex; - internal uint? StickerID; - internal uint? TintID; - internal uint? MusicID; - internal uint Quality; - internal uint Rarity; - internal uint Origin; - - [JsonProperty(PropertyName = "full_name")] - internal string? FullName; - - [JsonProperty(PropertyName = "full_type_name")] - internal string? FullTypeName; - - [JsonProperty(PropertyName = "rarity_name")] - internal string? RarityName; - - [JsonProperty(PropertyName = "quality_name")] - internal string? QualityName; - - [JsonProperty(PropertyName = "origin_name")] - internal string? OriginName; - - [JsonProperty(PropertyName = "type_name")] - internal string? TypeName; - - [JsonProperty(PropertyName = "item_name")] - internal string? ItemName; - - [JsonProperty(PropertyName = "tool_name")] - internal string? ToolName; - - [JsonProperty(PropertyName = "tint_name")] - internal string? TintName; - - [JsonProperty(PropertyName = "weapon_image_url")] - internal string? WeaponImageURL; - - [JsonProperty(PropertyName = "weapon_name")] - internal string? WeaponName; - - [JsonProperty(PropertyName = "wear_name")] - internal string? WearName; - - [JsonProperty(PropertyName = "wear")] - internal double? Wear; - - [JsonProperty(PropertyName = "wear_min")] - internal float? WearMin; - - [JsonProperty(PropertyName = "wear_max")] - internal float? WearMax; - - [JsonProperty(PropertyName = "name_id")] - internal string? NameID; - - [JsonProperty(PropertyName = "set_name_id")] - internal string? SetNameID; - - [JsonProperty(PropertyName = "set_name")] - internal string? SetName; - - [JsonProperty(PropertyName = "crate_name_id")] - internal string? CrateNameID; - - [JsonProperty(PropertyName = "crate_defindex")] - internal uint? CrateDefIndex; - - [JsonProperty(PropertyName = "crate_supply_series")] - internal uint? CrateSupplySeries; - - [JsonProperty(PropertyName = "crate_name")] - internal string? CrateName; - - [JsonProperty(PropertyName = "defs")] - internal ItemData? ItemData; + public class Item { + public uint DefIndex; + public uint PaintIndex; + public uint? StickerID; + public uint? TintID; + public uint? MusicID; + public uint Quality; + public uint Rarity; + public uint Origin; + + [JsonInclude] + [JsonPropertyName("full_name")] + public string? FullName { get; private set; } + + [JsonInclude] + [JsonPropertyName("full_type_name")] + public string? FullTypeName { get; private set; } + + [JsonInclude] + [JsonPropertyName("rarity_name")] + public string? RarityName { get; private set; } + + [JsonInclude] + [JsonPropertyName("quality_name")] + public string? QualityName { get; private set; } + + [JsonInclude] + [JsonPropertyName("origin_name")] + public string? OriginName { get; private set; } + + [JsonInclude] + [JsonPropertyName("type_name")] + public string? TypeName { get; private set; } + + [JsonInclude] + [JsonPropertyName("item_name")] + public string? ItemName { get; private set; } + + [JsonInclude] + [JsonPropertyName("tool_name")] + public string? ToolName { get; private set; } + + [JsonInclude] + [JsonPropertyName("tint_name")] + public string? TintName { get; private set; } + + [JsonInclude] + [JsonPropertyName("weapon_image_url")] + public string? WeaponImageURL { get; private set; } + + [JsonInclude] + [JsonPropertyName("weapon_name")] + public string? WeaponName { get; private set; } + + [JsonInclude] + [JsonPropertyName("wear_name")] + public string? WearName { get; private set; } + + [JsonInclude] + [JsonPropertyName("wear")] + public double? Wear { get; set; } + + [JsonInclude] + [JsonPropertyName("wear_min")] + public float? WearMin { get; private set; } + + [JsonInclude] + [JsonPropertyName("wear_max")] + public float? WearMax { get; private set; } + + [JsonInclude] + [JsonPropertyName("name_id")] + public string? NameID { get; private set; } + + [JsonInclude] + [JsonPropertyName("set_name_id")] + public string? SetNameID { get; private set; } + + [JsonInclude] + [JsonPropertyName("set_name")] + public string? SetName { get; private set; } + + [JsonInclude] + [JsonPropertyName("crate_name_id")] + public string? CrateNameID { get; private set; } + + [JsonInclude] + [JsonPropertyName("crate_defindex")] + public uint? CrateDefIndex { get; private set; } + + [JsonInclude] + [JsonPropertyName("crate_supply_series")] + public uint? CrateSupplySeries { get; private set; } + + [JsonInclude] + [JsonPropertyName("crate_name")] + public string? CrateName { get; private set; } + + [JsonInclude] + [JsonPropertyName("defs")] + public ItemData? ItemData { get; private set; } protected static bool ShouldSerializeAdditionalProperties = true; protected static bool ShouldSerializeDefs = true; diff --git a/CS2Interface/Data/ItemData.cs b/CS2Interface/Data/ItemData.cs index cc65669..9dfa04a 100644 --- a/CS2Interface/Data/ItemData.cs +++ b/CS2Interface/Data/ItemData.cs @@ -1,21 +1,25 @@ using System; +using System.Text.Json.Serialization; using ArchiSteamFarm.Core; -using Newtonsoft.Json; using SteamKit2; namespace CS2Interface { - internal class ItemData { - [JsonProperty(PropertyName = "item_def")] - internal ItemDef ItemDef; + public class ItemData { + [JsonInclude] + [JsonPropertyName("item_def")] + public ItemDef ItemDef { get; private init; } - [JsonProperty(PropertyName = "paint_kit_def")] - internal ItemDef? PaintKitDef; + [JsonInclude] + [JsonPropertyName("paint_kit_def")] + public ItemDef? PaintKitDef { get; private init; } - [JsonProperty(PropertyName = "sticker_kit_def")] - internal ItemDef? StickerKitDef; + [JsonInclude] + [JsonPropertyName("sticker_kit_def")] + public ItemDef? StickerKitDef { get; private init; } - [JsonProperty(PropertyName = "music_def")] - internal ItemDef? MusicDef; + [JsonInclude] + [JsonPropertyName("music_def")] + public ItemDef? MusicDef { get; private init; } public bool ShouldSerializeItemDef() => ItemDef != null; public bool ShouldSerializePaintKitDef() => PaintKitDef != null; @@ -48,8 +52,6 @@ private bool MergePrefab(ItemDef itemDef, string? prefab) { return true; } - // STACK OVERFLOW HERE - // Some items have multiple prefabs separated by a space, but only one is valid (it has an entry in ItemsGame) // Ex: "valve weapon_case_key": "valve" isn't valid, but "weapon_case_key" is // Ex: "antwerp2022_sticker_capsule_prefab antwerp2022_sellable_item_with_payment_rules": "antwerp2022_sticker_capsule_prefab" is valid, but "antwerp2022_sellable_item_with_payment_rules" isn't diff --git a/CS2Interface/Data/ItemDef.cs b/CS2Interface/Data/ItemDef.cs index 49162e9..62ed4f3 100644 --- a/CS2Interface/Data/ItemDef.cs +++ b/CS2Interface/Data/ItemDef.cs @@ -1,13 +1,15 @@ using System; using System.Collections.Generic; using System.Linq; -using Newtonsoft.Json; +using System.Text.Json.Serialization; using SteamKit2; namespace CS2Interface { - internal class ItemDef { - [JsonProperty(PropertyName = "defs", ItemConverterType = typeof(KVConverter))] - internal List Defs = new(); + public class ItemDef { + [JsonInclude] + [JsonPropertyName("defs")] + [JsonConverter(typeof(JsonListItemConverter))] + internal List Defs { get; private init; } = new(); internal ItemDef(KeyValue? def) { AddDef(def); diff --git a/CS2Interface/Helpers/AttributeConverter.cs b/CS2Interface/Helpers/AttributeConverter.cs index 574bcbb..f51fdc5 100644 --- a/CS2Interface/Helpers/AttributeConverter.cs +++ b/CS2Interface/Helpers/AttributeConverter.cs @@ -1,43 +1,33 @@ using System; using System.Collections.Generic; +using System.Text.Json; +using System.Text.Json.Serialization; using ArchiSteamFarm.Core; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; namespace CS2Interface { - public sealed class AttributeConverter : JsonConverter { - public override bool CanConvert(Type objectType) { - return objectType == typeof(Dictionary); + public sealed class AttributeConverter : JsonConverter> { + + public override Dictionary Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { + throw new NotImplementedException(); } - - public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer) { - JObject json = new(); - if (value is Dictionary attributes) { - foreach (var kvp in attributes) { - var attribute = kvp.Value; - try { - if (attribute.Type == typeof(uint)) { - json.Add(attribute.Name, attribute.ToUInt32()); - } if (attribute.Type == typeof(float)) { - json.Add(attribute.Name, attribute.ToSingle()); - } else if (attribute.Type == typeof(string)) { - json.Add(attribute.Name, attribute.ToString()); - } - } catch (Exception e) { - ASF.ArchiLogger.LogGenericException(e); + + public override void Write(Utf8JsonWriter writer, Dictionary value, JsonSerializerOptions options) { + writer.WriteStartObject(); + foreach (var kvp in value) { + var attribute = kvp.Value; + try { + if (attribute.Type == typeof(uint)) { + writer.WriteNumber(attribute.Name, attribute.ToUInt32()); + } if (attribute.Type == typeof(float)) { + writer.WriteNumber(attribute.Name, attribute.ToSingle()); + } else if (attribute.Type == typeof(string)) { + writer.WriteString(attribute.Name, attribute.ToString()); } + } catch (Exception e) { + ASF.ArchiLogger.LogGenericException(e); } } - - json.WriteTo(writer); + writer.WriteEndObject(); } - - public override bool CanRead { - get { return false; } - } - - public override object ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer) { - throw new NotImplementedException(); - } } } \ No newline at end of file diff --git a/CS2Interface/Helpers/IAttribute.cs b/CS2Interface/Helpers/IAttribute.cs index 689c9b6..691c168 100644 --- a/CS2Interface/Helpers/IAttribute.cs +++ b/CS2Interface/Helpers/IAttribute.cs @@ -2,29 +2,28 @@ namespace CS2Interface { public abstract partial class IAttribute { - public abstract string Name { get; } - public abstract Type Type { get; } + internal abstract string Name { get; } + internal abstract Type Type { get; } - public abstract uint ToUInt32(); + internal abstract uint ToUInt32(); - public abstract float ToSingle(); + internal abstract float ToSingle(); public override abstract string ToString(); } public sealed class Attribute : IAttribute where TObject : notnull { - public override string Name { get; } - public override Type Type { get => typeof(TObject); } - public TObject Value; + internal override string Name { get; } + internal override Type Type { get => typeof(TObject); } + internal TObject Value; public Attribute(string name, TObject value) { Name = name; Value = value; } - public override uint ToUInt32() => (uint) Convert.ChangeType(Value, typeof(uint)); - public override float ToSingle() => (float) Convert.ChangeType(Value, typeof(float)); - + internal override uint ToUInt32() => (uint) Convert.ChangeType(Value, typeof(uint)); + internal override float ToSingle() => (float) Convert.ChangeType(Value, typeof(float)); public override string ToString() => (string) Convert.ChangeType(Value, typeof(string)); } } \ No newline at end of file diff --git a/CS2Interface/Helpers/KVConverter.cs b/CS2Interface/Helpers/KVConverter.cs index ceebb16..d01b796 100644 --- a/CS2Interface/Helpers/KVConverter.cs +++ b/CS2Interface/Helpers/KVConverter.cs @@ -1,71 +1,88 @@ using System; +using System.Collections.Generic; using System.Globalization; +using System.Text.Json; +using System.Text.Json.Nodes; +using System.Text.Json.Serialization; using ArchiSteamFarm.Core; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; using SteamKit2; namespace CS2Interface { - public sealed class KVConverter : JsonConverter { - public override bool CanConvert(Type objectType) { - return objectType == typeof(KeyValue); + public sealed class KVConverter : JsonConverter { + public override KeyValue Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { + throw new NotImplementedException(); } - - public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer) { - JToken? json = null; - if (value is KeyValue vdf) { - json = ConvertKVObjectToJson(vdf); - } - if (json == null) { - writer.WriteNull(); - - return; - } - - json.WriteTo(writer); + public override void Write(Utf8JsonWriter writer, KeyValue value, JsonSerializerOptions options) { + ConvertKVObjectToJson(ref writer, value); } - private JToken? ConvertKVObjectToJson (KeyValue vdf) { + private void ConvertKVObjectToJson (ref Utf8JsonWriter writer, KeyValue vdf) { if (vdf.Children.Count > 0) { - JObject json = new(); + writer.WriteStartObject(); foreach (KeyValue child in vdf.Children) { if (child.Name == null) { continue; } try { - json.Add(child.Name, ConvertKVObjectToJson(child)); + writer.WritePropertyName(child.Name); + ConvertKVObjectToJson(ref writer, child); } catch (Exception e) { // item["523"] (Talon Knife) has duplicates of "inventory_image_data", just ignore the duplicates ASF.ArchiLogger.LogGenericException(e); } - } + } + writer.WriteEndObject(); - return json; + return; } if (int.TryParse(vdf.Value, out int intValue)) { - return intValue; + writer.WriteNumberValue(intValue); + + return; } if (long.TryParse(vdf.Value, out long longValue)) { - return longValue; + writer.WriteNumberValue(longValue); + + return; } if (float.TryParse(vdf.Value, NumberStyles.Float | NumberStyles.AllowThousands, CultureInfo.InvariantCulture, out float floatValue)) { - return floatValue; + writer.WriteNumberValue(floatValue); + + return; } - return vdf.Value; + writer.WriteStringValue(vdf.Value); } - - public override bool CanRead { - get { return false; } - } - - public override object ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer) { + } + + // https://github.com/dotnet/runtime/issues/54189#issuecomment-861628532 + public class JsonListItemConverter : JsonConverter> where TConverterType : JsonConverter { + public override List Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { throw new NotImplementedException(); - } + } + + public override void Write(Utf8JsonWriter writer, List value, JsonSerializerOptions options) { + if (value == null) { + writer.WriteNullValue(); + return; + } + + JsonSerializerOptions jsonSerializerOptions = new JsonSerializerOptions(options); + jsonSerializerOptions.Converters.Clear(); + jsonSerializerOptions.Converters.Add(Activator.CreateInstance()); + + writer.WriteStartArray(); + + foreach (TDatatype data in value) { + JsonSerializer.Serialize(writer, data, jsonSerializerOptions); + } + + writer.WriteEndArray(); + } } } \ No newline at end of file diff --git a/CS2Interface/IPC/Api/CS2InterfaceController.cs b/CS2Interface/IPC/Api/CS2InterfaceController.cs index 1f4e72f..b1e3d47 100644 --- a/CS2Interface/IPC/Api/CS2InterfaceController.cs +++ b/CS2Interface/IPC/Api/CS2InterfaceController.cs @@ -136,24 +136,24 @@ public async Task> InspectItem( return Ok(new GenericResponse(true, item)); } - [HttpGet("{botNames:required}/PlayerProfile/{steamID:required}")] - [SwaggerOperation (Summary = "Get a CS2 player profile")] + [HttpGet("{botName:required}/PlayerProfile/{steamID:required}")] + [SwaggerOperation (Summary = "Get a friend's CS2 player profile")] [ProducesResponseType(typeof(GenericResponse), (int) HttpStatusCode.OK)] [ProducesResponseType(typeof(GenericResponse), (int) HttpStatusCode.BadRequest)] [ProducesResponseType(typeof(GenericResponse), (int) HttpStatusCode.GatewayTimeout)] - public async Task> PlayerProfile([FromRoute] string botNames, [FromRoute] ulong steamID) { - if (string.IsNullOrEmpty(botNames)) { - throw new ArgumentNullException(nameof(botNames)); + public async Task> PlayerProfile([FromRoute] string botName, [FromRoute] ulong steamID) { + if (string.IsNullOrEmpty(botName)) { + throw new ArgumentNullException(nameof(botName)); } - HashSet? bots = Bot.GetBots(botNames); - if ((bots == null) || (bots.Count == 0)) { - return BadRequest(new GenericResponse(false, string.Format(Strings.BotNotFound, botNames))); + Bot? bot = Bot.GetBot(botName); + if (bot == null) { + return BadRequest(new GenericResponse(false, string.Format(Strings.BotNotFound, botName))); } - (Bot? bot, Client? client, string status) = ClientHandler.GetAvailableClient(bots); - if (bot == null || client == null) { - return BadRequest(new GenericResponse(false, status)); + (Client? client, string client_status) = ClientHandler.ClientHandlers[bot.BotName].GetClient(); + if (client == null) { + return BadRequest(new GenericResponse(false, client_status)); } CMsgGCCStrike15_v2_PlayersProfile player; diff --git a/README.md b/README.md index f919b8e..936fc2c 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,12 @@ Command | Access | Description `cstop [Bots]`|`Master`|Stops the CS2 Interface `cstatus [Bots]`|`Master`|Displays the status of the CS2 Interface +#### Command Aliases + +Command | Alias | +--- | --- | +`cstatus asf`|`csa` + --- ### AutoStartCS2Interface