-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Fix #90 by implementing list players command * Updated docs to represent the change
- Loading branch information
Showing
11 changed files
with
258 additions
and
8 deletions.
There are no files selected for viewing
68 changes: 68 additions & 0 deletions
68
src/PlayFabBuddy.Cli/Commands/Player/ListPlayersCommand.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
using System.Net; | ||
using PlayFabBuddy.Lib.Aggregate; | ||
using PlayFabBuddy.Lib.Interfaces.Adapter; | ||
using PlayFabBuddy.Lib.UseCases.Player; | ||
using Spectre.Console; | ||
using Spectre.Console.Cli; | ||
|
||
namespace PlayFabBuddy.Cli.Commands.Player; | ||
|
||
public class ListPlayersCommand : AsyncCommand<ListPlayersCommandSettings> | ||
{ | ||
private readonly IDataExplorerAdapter _dataAdapter; | ||
private readonly IPlayerAccountAdapter _playerAdapter; | ||
|
||
public ListPlayersCommand(IDataExplorerAdapter dataAdapter, IPlayerAccountAdapter playerAccountAdapter) | ||
{ | ||
_dataAdapter = dataAdapter; | ||
_playerAdapter = playerAccountAdapter; | ||
} | ||
|
||
public async override Task<int> ExecuteAsync(CommandContext context, ListPlayersCommandSettings settings) | ||
{ | ||
var getPlayerUsecase = | ||
new GetPlayersByIpUseCAse(_dataAdapter, _playerAdapter, IPAddress.Parse(settings.IpAddress)); | ||
|
||
var playerList = new List<MasterPlayerAccountAggregate>(); | ||
|
||
await AnsiConsole.Status() | ||
.Spinner(Spinner.Known.Star) | ||
.Start("Searching for Players...", async ctx => | ||
{ | ||
playerList = await getPlayerUsecase.ExecuteAsync(); | ||
}); | ||
|
||
if (playerList.Count == 0) | ||
{ | ||
AnsiConsole.MarkupLine("No Player for given IP have been found."); | ||
return 0; | ||
} | ||
|
||
var playerTable = new Table(); | ||
// Add some columns | ||
playerTable.AddColumn("Master Id"); | ||
playerTable.AddColumn("Last Known IP"); | ||
playerTable.AddColumn("TitlePlayerData"); | ||
|
||
foreach (var aggregate in playerList) | ||
{ | ||
var titlePlayer = ""; | ||
|
||
if (aggregate.MasterPlayerAccount.PlayerAccounts != null) | ||
{ | ||
foreach (var playerAccount in aggregate.MasterPlayerAccount.PlayerAccounts) | ||
{ | ||
titlePlayer += "ID: " + playerAccount.Id + "\n "; | ||
} | ||
} | ||
|
||
playerTable.AddRow(new Text(aggregate.MasterPlayerAccount.Id!), | ||
new Text(aggregate.MasterPlayerAccount.LastKnownIp!), | ||
new Text(titlePlayer)); | ||
} | ||
|
||
AnsiConsole.Write(playerTable); | ||
|
||
return 0; | ||
} | ||
} |
23 changes: 23 additions & 0 deletions
23
src/PlayFabBuddy.Cli/Commands/Player/ListPlayersCommandSettings.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
using System.ComponentModel; | ||
using System.Net; | ||
using Spectre.Console; | ||
using Spectre.Console.Cli; | ||
|
||
namespace PlayFabBuddy.Cli.Commands.Player; | ||
|
||
public class ListPlayersCommandSettings : PlayerSettings | ||
{ | ||
[Description("The IP Address to find Players by")] | ||
[CommandArgument(0, "[IPAddress]")] | ||
public string IpAddress { get; set; } = ""; | ||
|
||
public override ValidationResult Validate() | ||
{ | ||
if (IpAddress.Length == 0 && !IPAddress.TryParse(IpAddress, out _)) | ||
{ | ||
return ValidationResult.Error("Please provide a valid IPAddress"); | ||
} | ||
|
||
return ValidationResult.Success(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
83 changes: 83 additions & 0 deletions
83
src/PlayFabBuddy.Infrastructure/Adapter/PlayFab/Analytics/DataExplorerAdapter.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
using System.Net; | ||
using System.Text.Json; | ||
using Kusto.Data.Common; | ||
using PlayFabBuddy.Lib.Entities.Accounts; | ||
using PlayFabBuddy.Lib.Interfaces.Adapter; | ||
|
||
namespace PlayFabBuddy.Infrastructure.Adapter.PlayFab.Analytics; | ||
|
||
public class DataExplorerAdapter : IDataExplorerAdapter | ||
{ | ||
private readonly ICslQueryProvider _kustoQueryProvider; | ||
|
||
public DataExplorerAdapter(ICslQueryProvider kustoQueryProvider) | ||
{ | ||
_kustoQueryProvider = kustoQueryProvider; | ||
} | ||
|
||
public Task<List<MasterPlayerAccountEntity>> GetPlayersByIp(IPAddress ip) | ||
{ | ||
var query = "['events.all'] " + | ||
"| where FullName_Name == 'player_logged_in' " + | ||
"| where EventData.IPV4Address == '" + ip + "'"; | ||
var clientRequestProperties = new ClientRequestProperties { | ||
Application = "PlayFabBuddy", ClientRequestId = Guid.NewGuid().ToString() | ||
}; | ||
|
||
var entityList = new List<MasterPlayerAccountEntity>(); | ||
|
||
using (var reader = _kustoQueryProvider.ExecuteQuery(query, clientRequestProperties)) | ||
{ | ||
while (reader.Read()) | ||
{ | ||
var rawObjectData = reader.GetValue(6); | ||
|
||
var eventData = JsonSerializer.Deserialize<EventData>(rawObjectData.ToString() ?? string.Empty); | ||
|
||
if (eventData != null) | ||
{ | ||
entityList.Add(new MasterPlayerAccountEntity { | ||
Id = eventData.EntityId, LastKnownIp = eventData.IPV4Address | ||
}); | ||
} | ||
} | ||
} | ||
|
||
return Task.FromResult(entityList); | ||
} | ||
|
||
private class EventData | ||
{ | ||
public PlayFabEnvironment? PlayFabEnvironment { get; set; } | ||
public string? EventNamespace { get; set; } | ||
public DateTime? Timestamp { get; set; } | ||
public string? EntityType { get; set; } | ||
public string? SourceType { get; set; } | ||
public string? EventName { get; set; } | ||
public string? EntityId { get; set; } | ||
public string? EventId { get; set; } | ||
public string? TitleId { get; set; } | ||
public string? Source { get; set; } | ||
public string? PlatformUserId { get; set; } | ||
public List<object>? ExperimentVariants { get; set; } | ||
public string? Platform { get; set; } | ||
public string? IPV4Address { get; set; } | ||
public Location? Location { get; set; } | ||
} | ||
|
||
private class Location | ||
{ | ||
public string? ContinentCode { get; set; } | ||
public string? CountryCode { get; set; } | ||
public double? Longitude { get; set; } | ||
public double? Latitude { get; set; } | ||
public string? City { get; set; } | ||
} | ||
private class PlayFabEnvironment | ||
{ | ||
public string? Application { get; set; } | ||
public string? Vertical { get; set; } | ||
public string? Commit { get; set; } | ||
public string? Cloud { get; set; } | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
10 changes: 10 additions & 0 deletions
10
src/PlayFabBuddy.Lib/Interfaces/Adapter/IDataExplorerAdapter.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
using System.Net; | ||
using PlayFabBuddy.Lib.Aggregate; | ||
using PlayFabBuddy.Lib.Entities.Accounts; | ||
|
||
namespace PlayFabBuddy.Lib.Interfaces.Adapter; | ||
|
||
public interface IDataExplorerAdapter | ||
{ | ||
public Task<List<MasterPlayerAccountEntity>> GetPlayersByIp(IPAddress ip); | ||
} |
35 changes: 35 additions & 0 deletions
35
src/PlayFabBuddy.Lib/UseCases/Player/GetPlayersByIpUseCAse.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
using System.Net; | ||
using PlayFabBuddy.Lib.Aggregate; | ||
using PlayFabBuddy.Lib.Interfaces.Adapter; | ||
|
||
namespace PlayFabBuddy.Lib.UseCases.Player; | ||
|
||
public class GetPlayersByIpUseCAse : UseCase<List<MasterPlayerAccountAggregate>> | ||
{ | ||
private readonly IDataExplorerAdapter _dataExplorerAdapter; | ||
private readonly IPAddress _ip; | ||
private readonly IPlayerAccountAdapter _playerAccountAdapter; | ||
|
||
public GetPlayersByIpUseCAse(IDataExplorerAdapter dataExplorerAdapter, IPlayerAccountAdapter playerAccountAdapter, | ||
IPAddress ip) | ||
{ | ||
_dataExplorerAdapter = dataExplorerAdapter; | ||
_playerAccountAdapter = playerAccountAdapter; | ||
_ip = ip; | ||
} | ||
|
||
public async override Task<List<MasterPlayerAccountAggregate>> ExecuteAsync(IProgress<double>? progress = null) | ||
{ | ||
var entityList = await _dataExplorerAdapter.GetPlayersByIp(_ip); | ||
|
||
var aggregateList = new List<MasterPlayerAccountAggregate>(); | ||
|
||
foreach (var masterPlayerEntity in entityList) | ||
{ | ||
var masterAggregate = new MasterPlayerAccountAggregate(masterPlayerEntity); | ||
aggregateList.Add(await _playerAccountAdapter.GetTitleAccountsAndCustomId(masterAggregate)); | ||
} | ||
|
||
return aggregateList; | ||
} | ||
} |