Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
carlst99 committed Dec 16, 2024
2 parents f1fb2f2 + e0a244b commit 74ff82a
Show file tree
Hide file tree
Showing 21 changed files with 187 additions and 157 deletions.
12 changes: 6 additions & 6 deletions Assets/README.nuget.md
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
# DbgCensus

DbgCensus is a C# wrapper for [Daybreak Game Company's Census API](https://census.daybreakgames.com). It was built with PlanetSide 2's endpoints in mind, but should work across all namespaces.
DbgCensus is a C# wrapper for [Daybreak Game Company's Census API](https://census.daybreakgames.com), and other unofficial Census-compatible implementations.

**This package is unofficial and is not affiliated with Daybreak Games Company in any way.**
**This package is not affiliated with Daybreak Games Company in any way.**

[![Nuget | DbgCensus.Core](https://img.shields.io/nuget/v/DbgCensus.Core?label=DbgCensus.Core)](https://www.nuget.org/packages/DbgCensus.Core) - Core data types and utilities.\
[![Nuget | DbgCensus.Rest](https://img.shields.io/nuget/v/DbgCensus.Rest?label=DbgCensus.Rest)](https://www.nuget.org/packages/DbgCensus.Rest) - Services for interacting with the query endpoints.\
[![Nuget | DbgCensus.EventStream](https://img.shields.io/nuget/v/DbgCensus.EventStream?label=DbgCensus.EventStream)](https://www.nuget.org/packages/DbgCensus.EventStream) - Base services for interacting with the event streaming API.\
[![Nuget | DbgCensus.EventStream.EventHandlers](https://img.shields.io/nuget/v/DbgCensus.EventStream.EventHandlers?label=DbgCensus.EventStream.EventHandlers)](https://www.nuget.org/packages/DbgCensus.EventStream.EventHandlers) - An abstraction of DbgCensus.EventStream providing an asynchronous and decoupled event handling model.
[![Nuget | DbgCensus.EventStream.EventHandlers](https://img.shields.io/nuget/v/DbgCensus.EventStream.EventHandlers?label=DbgCensus.EventStream.EventHandlers)](https://www.nuget.org/packages/DbgCensus.EventStream.EventHandlers) - An abstraction of DbgCensus.EventStream providing an
asynchronous and decoupled event handling model.

# Features

- Fluent query building API.
- Event dispatch/handling system and built-in event stream types.
- Fully asynchronous.
- Built around the `Microsoft.Extensions` framework.
- Targeting .NET 6.0.


- Native AOT Compatibility (Core and Rest only).
- Targeting .NET 6.0, .NET8.0 and .NET 9.0.

# [Visit the GitHub repository page for more documentation.](https://github.com/carlst99/DbgCensus)

30 changes: 30 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,36 @@

Date format: YYYY/MM/DD (ISO)

## 2024/11/30

#### Core-v3.1.1

- `ZoneID` now implements `IEquatable<ZoneID>, IEquatable<uint>`.
- Update dependencies.
- Add target for net9.0.

#### EventStream-v3.2.1

- Update dependencies.
- Add target for net9.0.

#### EventHandlers-v3.9.1

- Update dependencies.
- Add target for net9.0.

#### Rest-v4.0.1

- 🚨 Breaking Change: Removed `CensusQueryOptions.ServiceIDs`, and associated service-id rotation behaviour. This
has been noted to have no effect by the Census developers.
- 🐛 Bugfix: `QueryBuilder.WithCustomParameter` no longer results in invalid query strings - thanks @bigwoke.
- `QueryBuilder` now allows `WithDistinctFieldValues` to be used with any other commands/filters.
- `QueryBuilder` no longer ignores `WithLimit` when `WithLimitPerDatabase` is specified.
- `QueryBuilder` has a new constructor that allows specifying the collection to query.
- New `IQueryBuilderFactory.Get` overload that allows specifying the collection to query.
- Update dependencies.
- Add target for net9.0.

## 2024/09/21

#### Core-v3.0.0
Expand Down
8 changes: 2 additions & 6 deletions DbgCensus.Core/DbgCensus.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,13 @@

<PropertyGroup>
<!-- Package info -->
<Version>3.0.0</Version>
<Version>3.1.1</Version>
<Description>
Contains core data types and utilities for the DbgCensus.* libraries -
wrappers for interacting with Daybreak Game Company's Census API.
</Description>
<PackageReleaseNotes>See CHANGELOG.md for release notes.</PackageReleaseNotes>
<IsAotCompatible>true</IsAotCompatible>
<IsAotCompatible Condition="$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net7.0'))">true</IsAotCompatible>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.1" />
</ItemGroup>

</Project>
16 changes: 13 additions & 3 deletions DbgCensus.Core/Objects/ZoneId.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
namespace DbgCensus.Core.Objects;
using System;

namespace DbgCensus.Core.Objects;

/// <summary>
/// Represents Census' special zone ID format.
/// A zone ID is a <see cref="uint"/> where the upper two bytes represent the instance of the zone
/// and the lower two bytes represent the <see cref="ZoneDefinition"/>.
/// </summary>
public readonly struct ZoneID
public readonly struct ZoneID : IEquatable<ZoneID>, IEquatable<uint>
{
/// <summary>
/// Gets the actual Census ID, a combination of the <see cref="Instance"/> and <see cref="Definition"/>
Expand Down Expand Up @@ -46,7 +48,15 @@ public override string ToString()

public override bool Equals(object? obj)
=> obj is ZoneID zoneId
&& zoneId.CombinedId == CombinedId;
&& Equals(zoneId);

/// <inheritdoc />
public bool Equals(ZoneID zoneId)
=> zoneId.CombinedId == CombinedId;

/// <inheritdoc />
public bool Equals(uint combinedId)
=> combinedId == CombinedId;

public override int GetHashCode()
=> CombinedId.GetHashCode();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<!-- Package info -->
<Version>3.8.0</Version>
<Version>3.9.1</Version>
<Description>An abstraction of DbgCensus.EventStream to provide an asynchronous and decoupled event handling model.</Description>
<PackageReleaseNotes>See CHANGELOG.md for release notes.</PackageReleaseNotes>
</PropertyGroup>
Expand Down
8 changes: 4 additions & 4 deletions DbgCensus.EventStream/DbgCensus.EventStream.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@

<PropertyGroup>
<!-- Package info -->
<Version>3.1.0</Version>
<Version>3.2.1</Version>
<Description>A library for receiving data from the websocket event stream of Daybreak Game Company's Census API.</Description>
<PackageReleaseNotes>See CHANGELOG.md for release notes.</PackageReleaseNotes>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.1" />
<PackageReference Include="Microsoft.Extensions.Options" Version="8.0.2" />
<PackageReference Include="OneOf" Version="3.0.263" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="9.0.0" />
<PackageReference Include="Microsoft.Extensions.Options" Version="9.0.0" />
<PackageReference Include="OneOf" Version="3.0.271" />
</ItemGroup>

<ItemGroup>
Expand Down
3 changes: 2 additions & 1 deletion DbgCensus.Rest/Abstractions/Queries/IQueryBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ public interface IQueryBuilder
IQueryBuilder OnCollection(string collection);

/// <summary>
/// Limits the number of items returned by the query.
/// Limits the number of items returned by the query. If used in tandem with <see cref="WithDistinctFieldValues"/>,
/// limits the number of distinct values returned.
/// </summary>
/// <param name="limit">The maximum number of items.</param>
/// <returns>The <see cref="IQueryBuilder"/> instance so that calls may be chained.</returns>
Expand Down
8 changes: 8 additions & 0 deletions DbgCensus.Rest/Abstractions/Queries/IQueryBuilderFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,12 @@ public interface IQueryBuilderFactory
/// <param name="options">Overriding options to apply instead of the factory defaults.</param>
/// <returns>An <see cref="IQueryBuilder"/> instance.</returns>
IQueryBuilder Get(CensusQueryOptions? options = null);

/// <summary>
/// Constructs an <see cref="IQueryBuilder"/> instance.
/// </summary>
/// <param name="onCollection">The collection to perform the query on.</param>
/// <param name="options">Overriding options to apply instead of the factory defaults.</param>
/// <returns>An <see cref="IQueryBuilder"/> instance.</returns>
IQueryBuilder Get(string onCollection, CensusQueryOptions? options = null);
}
23 changes: 4 additions & 19 deletions DbgCensus.Rest/CensusQueryOptions.cs
Original file line number Diff line number Diff line change
@@ -1,28 +1,21 @@
using System.Collections.Generic;

namespace DbgCensus.Rest;
namespace DbgCensus.Rest;

public class CensusQueryOptions
{
/// <summary>
/// The root endpoint of the Census API.
/// </summary>
public string RootEndpoint { get; set; }
public string RootEndpoint { get; set; } = "https://census.daybreakgames.com";

/// <summary>
/// The service ID used to authenticate with the Census API.
/// </summary>
public string ServiceId { get; set; }

/// <summary>
/// Gets a list of service IDs that can be used to authenticate with the Census API.
/// </summary>
public List<string> ServiceIDs { get; }
public string ServiceId { get; set; } = "example";

/// <summary>
/// The Census namespace to retrieve data from.
/// </summary>
public string Namespace { get; set; }
public string Namespace { get; set; } = "ps2";

/// <summary>
/// Optionally remove all translations by default from internationalized strings except the one specified.
Expand All @@ -33,12 +26,4 @@ public class CensusQueryOptions
/// Optionally set a default limit for each query.
/// </summary>
public int? Limit { get; set; }

public CensusQueryOptions()
{
RootEndpoint = "https://census.daybreakgames.com";
ServiceId = "example";
ServiceIDs = new List<string>();
Namespace = "ps2";
}
}
10 changes: 5 additions & 5 deletions DbgCensus.Rest/DbgCensus.Rest.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@

<PropertyGroup>
<!-- Package info -->
<Version>3.9.0</Version>
<Version>4.0.1</Version>
<Description>A wrapper for interacting with the query endpoints of Daybreak Game Company's Census API.</Description>
<PackageReleaseNotes>See CHANGELOG.md for release notes.</PackageReleaseNotes>
<IsAotCompatible>true</IsAotCompatible>
<IsAotCompatible Condition="$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net7.0'))">true</IsAotCompatible>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Http" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Http.Polly" Version="8.0.4" />
<PackageReference Include="Microsoft.Extensions.Options" Version="8.0.2" />
<PackageReference Include="Microsoft.Extensions.Http" Version="9.0.0" />
<PackageReference Include="Microsoft.Extensions.Http.Polly" Version="9.0.0" />
<PackageReference Include="Microsoft.Extensions.Options" Version="9.0.0" />
<PackageReference Include="Polly.Contrib.WaitAndRetry" Version="1.1.1" />
</ItemGroup>

Expand Down
29 changes: 2 additions & 27 deletions DbgCensus.Rest/Extensions/IServiceCollectionExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,17 @@
using DbgCensus.Rest.Queries;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Options;
using Polly;
using Polly.Contrib.WaitAndRetry;
using Polly.Extensions.Http;
using System;
using System.Net.Http;
using System.Text.Json;
using System.Threading;

namespace DbgCensus.Rest.Extensions;

public static class IServiceCollectionExtensions
{
private static volatile int _serviceIDIndex;

/// <summary>
/// Adds required services for interacting with the Census REST API.
/// </summary>
Expand All @@ -43,29 +39,8 @@ public static IServiceCollection AddCensusRestServices
.ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler { AllowAutoRedirect = false })
.AddPolicyHandler
(
(services, _) => HttpPolicyExtensions.HandleTransientHttpError()
.WaitAndRetryAsync
(
Backoff.DecorrelatedJitterBackoffV2(TimeSpan.FromSeconds(1), maxRetryAttempts),
onRetry: (_, _, retryAttempt, _) =>
{
if (retryAttempt != maxRetryAttempts)
return;

CensusQueryOptions qOptions = services.GetRequiredService<IOptionsMonitor<CensusQueryOptions>>().CurrentValue;
if (qOptions.ServiceIDs.Count == 0)
return;

int serviceIDIndex = Interlocked.Increment(ref _serviceIDIndex);
if (serviceIDIndex >= qOptions.ServiceIDs.Count)
{
Interlocked.Exchange(ref _serviceIDIndex, 0);
serviceIDIndex = 0;
}

qOptions.ServiceId = qOptions.ServiceIDs[serviceIDIndex];
}
)
HttpPolicyExtensions.HandleTransientHttpError()
.WaitAndRetryAsync(Backoff.DecorrelatedJitterBackoffV2(TimeSpan.FromSeconds(1), maxRetryAttempts))
);

serviceCollection.TryAddSingleton<IQueryBuilderFactory, QueryBuilderFactory>();
Expand Down
76 changes: 35 additions & 41 deletions DbgCensus.Rest/Queries/QueryBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,17 @@ public QueryBuilder(CensusQueryOptions queryOptions)
WithLimit((int)queryOptions.Limit);
}

/// <summary>
/// Provides functions to build a query string for the Census REST API.
/// </summary>
/// <param name="onCollection">The collection to perform the query on.</param>
/// <param name="queryOptions">The default configuration for the query.</param>
public QueryBuilder(string onCollection, CensusQueryOptions queryOptions)
: this(queryOptions)
{
OnCollection(onCollection);
}

/// <inheritdoc />
public Uri ConstructEndpoint()
{
Expand All @@ -87,47 +98,30 @@ public Uri ConstructEndpoint()
return builder.Uri;
builder.Path += $"/{CollectionName}";

// Add any custom parameters
if (_customParameters.Count > 0)
builder.Query += string.Join('&', _customParameters);

// Add distinct command
if (_distinctField.HasArgument)
{
builder.Query = _distinctField;
return builder.Uri; // Querying doesn't work in tandem with the distinct command
}

// Add filters
foreach (QueryFilter filter in _filters)
builder.Query += $"{filter}&";

// Add commands
string commandsJoin = StringUtils.JoinWithoutNullOrEmptyValues
(
'&',
_hasFields,
_showHideFields?.ToString(),
_resolves,
_joins,
_sortKeys,
_startIndex,
_language,
_exactMatchesFirst,
_isCaseSensitive,
_withNullFields,
_withTimings,
_retry
);

if (!string.IsNullOrEmpty(commandsJoin))
builder.Query += commandsJoin;

// Add relevant limit command
if (_limitPerDb.HasArgument)
builder.Query += '&' + _limitPerDb;
else if (_limit.HasArgument)
builder.Query += '&' + _limit;
// Combine any customer parameters, filters and commands into a string array, such that we can join them
// into a query string
IEnumerable<string?> arguments = _customParameters
.Concat(_filters.Select(x => x.ToString()))
.Concat(new[]
{
_distinctField,
_hasFields,
_showHideFields?.ToString(),
_resolves,
_joins,
_sortKeys,
_startIndex,
_language,
_exactMatchesFirst,
_isCaseSensitive,
_withNullFields,
_withTimings,
_retry,
_limit,
_limitPerDb
});

builder.Query = StringUtils.JoinWithoutNullOrEmptyValues('&', arguments);

return builder.Uri;
}
Expand Down
4 changes: 4 additions & 0 deletions DbgCensus.Rest/Queries/QueryBuilderFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,8 @@ public QueryBuilderFactory(IOptionsMonitor<CensusQueryOptions> queryOptions)
/// <inheritdoc />
public IQueryBuilder Get(CensusQueryOptions? options = null)
=> new QueryBuilder(options ?? _defaultOptions.CurrentValue);

/// <inheritdoc />
public IQueryBuilder Get(string onCollection, CensusQueryOptions? options = null)
=> new QueryBuilder(onCollection, options ?? _defaultOptions.CurrentValue);
}
Loading

0 comments on commit 74ff82a

Please sign in to comment.