Skip to content

Commit

Permalink
work on steam parser completed
Browse files Browse the repository at this point in the history
  • Loading branch information
k1tbyte committed Jun 16, 2024
1 parent 8db4a0d commit b5d9091
Show file tree
Hide file tree
Showing 12 changed files with 253 additions and 100 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -369,4 +369,4 @@ FodyWeavers.xsd

# User
.idea/
Tests/
/Tests/
49 changes: 35 additions & 14 deletions SteamOrganizer.Server/Controllers/Steam/WebApiController.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using System.ComponentModel.DataAnnotations;
using System.Text.Json;
using Microsoft.AspNetCore.Mvc;
using SteamOrganizer.Server.Filters;
using SteamOrganizer.Server.Services;
using SteamOrganizer.Server.Services.SteamParser;
using SteamOrganizer.Server.Services.SteamParser.Responses;

Expand All @@ -16,38 +16,59 @@ public sealed class WebApiController(SteamParser parser) : ControllerBase
{
return await parser
.SetCurrency(request.Currency)
.GetInfo(request.Ids.First(), request.IncludeGames);
.GetPlayerInfo(request.Ids.First(), request.IncludeGames);
}

[HttpPost]
public async Task GetSummariesStream([FromBody] SummariesRequest request)
{
Response.ContentType = "text/event-stream";

using var locker = new SemaphoreSlim(1,1);

await using var responseStream = Response.BodyWriter.AsStream();

var result = await parser
.SetCurrency(request.Currency)
.GetPlayerInfo(request.Ids, request.IncludeGames, async (player,token) =>
{
await locker.WaitAsync(token);
await Response.WriteAsync("data: ",token);
await JsonSerializer.SerializeAsync(responseStream, player, Defines.JsonOptions, token);
await Response.WriteAsync("\r\r", token);
await Response.Body.FlushAsync(token);
locker.Release();
});

if (result == ESteamApiResult.OK)
{
Ok();
return;
}

BadRequest(result.ToString());
}

[HttpGet]
public async Task<PlayerGames?> GetGames(GamesRequest request)
{
var response = await parser.SetCurrency(request.Currency).GetGames(
request.SteamId!.Value,
HttpContext.RequestAborted,
request.WithDetails
).ConfigureAwait(false);

return response;
}

[HttpGet]
public async Task GetFriends([Required] ulong? steamId)
{

}

[HttpPost]
public async Task GetSummariesStream([FromBody] SummariesRequest request)
public async Task<PlayerFriend[]?> GetFriends([Required] ulong? steamId)
{
var httpResponse = HttpContext.Response;
httpResponse.ContentType = "text/event-stream";

return await parser.GetFriendsInfo(steamId!.Value);
}
}

public sealed record SummariesRequest(
[Required,Length(1, 1000)] HashSet<ulong> Ids,
[Required,Length(1, 100)] HashSet<ulong> Ids,
bool IncludeGames,
string? Currency
);
Expand Down
27 changes: 27 additions & 0 deletions SteamOrganizer.Server/Filters/ApiKeyAttribute.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;

namespace SteamOrganizer.Server.Filters;

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public sealed class ApiKeyAttribute : Attribute, IActionFilter
{
public void OnActionExecuting(ActionExecutingContext context)
{
if (!context.HttpContext.Request.Query.TryGetValue(Defines.ApiKeyParamName, out var extractedApiKey))
{
context.Result = new BadRequestObjectResult(new { Message = "Api key was not provided" });
return;
}

var key = extractedApiKey.ToString();
if(key.Length != Defines.SteamApiKeyLength)
{
context.Result = new BadRequestObjectResult(new { Message = "Invalid api key" });
}
}

public void OnActionExecuted(ActionExecutedContext context)
{
}
}
16 changes: 5 additions & 11 deletions SteamOrganizer.Server/Lib/Extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,13 @@ namespace SteamOrganizer.Server.Lib;

public static class Extensions
{
public static async Task<string?> TryGetString(this HttpClient client, string url)
public static async Task<string?> TryGetString(this HttpClient client, string url, CancellationToken token = default)
{
try
{
using var response = await client.GetAsync(url).ConfigureAwait(false);
if (response.IsSuccessStatusCode)
{
return await response.Content.ReadAsStringAsync();
}
}
catch

using var response = await client.GetAsync(url, token).ConfigureAwait(false);
if (response.IsSuccessStatusCode)
{
// TODO: Handle status code
return await response.Content.ReadAsStringAsync(token);
}

return null;
Expand Down
21 changes: 21 additions & 0 deletions SteamOrganizer.Server/Lib/JsonConverters/ToNumberConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using System.Text.Json;
using System.Text.Json.Serialization;

namespace SteamOrganizer.Server.Lib.JsonConverters;

public sealed class ToNumberConverter : JsonConverter<ulong>
{
public override ulong Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType == JsonTokenType.String && ulong.TryParse(reader.GetString(), out var value))
{
return value;
}
throw new JsonException("Unable to convert string to ulong.");
}

public override void Write(Utf8JsonWriter writer, ulong value, JsonSerializerOptions options)
{
writer.WriteNumberValue(value);
}
}
6 changes: 3 additions & 3 deletions SteamOrganizer.Server/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,11 @@ public static void Main(string[] args)
builder.Services.AddHttpClient();
builder.Services.AddScoped<SteamParser>(o =>
{
var apiKey = o.GetService<IHttpContextAccessor>()!
.HttpContext!.Request.Query[Defines.ApiKeyParamName].ToString();
var context = o.GetService<IHttpContextAccessor>()!.HttpContext;
var apiKey = context!.Request.Query[Defines.ApiKeyParamName].ToString();
var client = o.GetService<HttpClient>()!;
client.BaseAddress = new Uri(Defines.SteamApiBaseUrl);
return new SteamParser(client, o.GetService<CacheManager>()!, apiKey);
return new SteamParser(client, o.GetService<CacheManager>()!, apiKey, context.RequestAborted);
});
builder.Services.AddSingleton<CacheManager>(o => new CacheManager("global"));

Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,25 @@
using System.Text.Json.Serialization;
using SteamOrganizer.Server.Lib.JsonConverters;

namespace SteamOrganizer.Server.Services.SteamParser.Responses;

public sealed class PlayerBans
public sealed class PlayerBans : IIdentifiable
{
public bool CommunityBanned { get; set; }
public int NumberOfVacBans { get; set; }
public int NumberOfGameBans { get; set; }
public int DaysSinceLastBan { get; set; }
public string? EconomyBan { get; set; }

[JsonConverter(typeof(ToNumberConverter))]
[JsonPropertyName("SteamId")]
public ulong Id
{
set => SteamId = value;
}

[JsonIgnore]
public ulong SteamId { get; private set; }
}

public sealed class PlayerBansResponse
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@

namespace SteamOrganizer.Server.Services.SteamParser.Responses;

public sealed class PlayerFriend
public sealed class PlayerFriend : IIdentifiable
{
public required string SteamId { get; set; }
[JsonConverter(typeof(ToNumberConverter))]
public required ulong SteamId { get; set; }

[JsonConverter(typeof(UnixToDateTimeConverter))]
[JsonPropertyName("friend_since")]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,16 @@

namespace SteamOrganizer.Server.Services.SteamParser.Responses;

public sealed class PlayerSummaries
public interface IIdentifiable
{
public required string SteamId { get; set; }
public ulong SteamId { get; }
}

public sealed class PlayerSummaries : IIdentifiable
{
[JsonConverter(typeof(ToNumberConverter))]
public required ulong SteamId { get; set; }

public string? AvatarHash { get; set; }
public string? PersonaName { get; set; }

Expand Down
Loading

0 comments on commit b5d9091

Please sign in to comment.