Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d7c89327a7 | ||
|
|
4614b135a1 |
@@ -4,6 +4,8 @@ using System.Text;
|
|||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Prospect.Server.Api.Services.Database;
|
using Prospect.Server.Api.Services.Database;
|
||||||
|
using Prospect.Server.Api.Services.Database.Models;
|
||||||
|
using Prospect.Server.Api.Services.Steam;
|
||||||
using Prospect.Server.Api.Services.UserData;
|
using Prospect.Server.Api.Services.UserData;
|
||||||
|
|
||||||
namespace Prospect.Server.Api.Controllers;
|
namespace Prospect.Server.Api.Controllers;
|
||||||
@@ -18,14 +20,16 @@ public class AdminController : ControllerBase
|
|||||||
private readonly DbEntityService _entityService;
|
private readonly DbEntityService _entityService;
|
||||||
private readonly DbUserDataService _userDataService;
|
private readonly DbUserDataService _userDataService;
|
||||||
private readonly TitleDataService _titleDataService;
|
private readonly TitleDataService _titleDataService;
|
||||||
|
private readonly SteamWebApiService _steamWebApi;
|
||||||
|
|
||||||
public AdminController(DbUserService userService, DbEntityService entityService,
|
public AdminController(DbUserService userService, DbEntityService entityService,
|
||||||
DbUserDataService userDataService, TitleDataService titleDataService)
|
DbUserDataService userDataService, TitleDataService titleDataService, SteamWebApiService steamWebApi)
|
||||||
{
|
{
|
||||||
_userService = userService;
|
_userService = userService;
|
||||||
_entityService = entityService;
|
_entityService = entityService;
|
||||||
_userDataService = userDataService;
|
_userDataService = userDataService;
|
||||||
_titleDataService = titleDataService;
|
_titleDataService = titleDataService;
|
||||||
|
_steamWebApi = steamWebApi;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------- pages ----------
|
// ---------- pages ----------
|
||||||
@@ -82,7 +86,8 @@ public class AdminController : ControllerBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
var sb = new StringBuilder();
|
var sb = new StringBuilder();
|
||||||
sb.Append($"<form method='get' class='search'><input name='q' placeholder='Rechercher nom / id / steam…' value='{Esc(q ?? "")}'/><button class='btn'>Rechercher</button></form>");
|
sb.Append($"<form method='get' class='search'><input name='q' placeholder='Rechercher nom / id / steam…' value='{Esc(q ?? "")}'/><button class='btn'>Rechercher</button>" +
|
||||||
|
"<a class='btn' href='/admin/backfill-names' title='Récupère les pseudos Steam des comptes sans nom'>Backfill pseudos Steam</a></form>");
|
||||||
sb.Append($"<p class='muted'>{users.Count} joueur(s)</p>");
|
sb.Append($"<p class='muted'>{users.Count} joueur(s)</p>");
|
||||||
sb.Append("<table><thead><tr><th>DisplayName</th><th>PlayFab Id</th><th>Entity Id</th><th>Auth</th><th></th></tr></thead><tbody>");
|
sb.Append("<table><thead><tr><th>DisplayName</th><th>PlayFab Id</th><th>Entity Id</th><th>Auth</th><th></th></tr></thead><tbody>");
|
||||||
foreach (var u in users.OrderBy(u => u.DisplayName))
|
foreach (var u in users.OrderBy(u => u.DisplayName))
|
||||||
@@ -179,6 +184,38 @@ public class AdminController : ControllerBase
|
|||||||
return Html(Layout("TitleData · " + key, $"<h2 class='mono'>{Esc(key)}</h2>" + body));
|
return Html(Layout("TitleData · " + key, $"<h2 class='mono'>{Esc(key)}</h2>" + body));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[HttpGet("backfill-names")]
|
||||||
|
public async Task<IActionResult> BackfillNames()
|
||||||
|
{
|
||||||
|
if (!IsLan()) return Denied();
|
||||||
|
if (!_steamWebApi.Enabled)
|
||||||
|
return Html(Layout("Backfill", "<p class='muted'>Steam Web API non configurée (clé absente).</p><p><a class='btn' href='/admin/players'>← Joueurs</a></p>"));
|
||||||
|
|
||||||
|
var users = await _userService.GetAllAsync();
|
||||||
|
int updated = 0, skipped = 0, failed = 0;
|
||||||
|
var rows = new StringBuilder();
|
||||||
|
foreach (var u in users)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(u.DisplayName) && u.DisplayName != "Unknown") { skipped++; continue; }
|
||||||
|
var steam = u.Auth?.FirstOrDefault(a => a.Type == PlayFabUserAuthType.Steam)?.Key;
|
||||||
|
if (string.IsNullOrEmpty(steam)) { skipped++; continue; }
|
||||||
|
|
||||||
|
var persona = await _steamWebApi.GetPersonaNameAsync(steam);
|
||||||
|
if (!string.IsNullOrWhiteSpace(persona))
|
||||||
|
{
|
||||||
|
await _userService.UpdateDisplayNameAsync(u.Id, persona);
|
||||||
|
updated++;
|
||||||
|
rows.Append($"<tr><td class='mono small'>{Esc(u.Id)}</td><td>{Esc(persona)}</td></tr>");
|
||||||
|
}
|
||||||
|
else { failed++; }
|
||||||
|
}
|
||||||
|
|
||||||
|
var body = $"<h2>Backfill des pseudos Steam</h2><p class='muted'>{updated} mis à jour · {skipped} ignorés · {failed} échec(s)</p>" +
|
||||||
|
(updated > 0 ? $"<table><thead><tr><th>PlayFabId</th><th>Nouveau nom</th></tr></thead><tbody>{rows}</tbody></table>" : "") +
|
||||||
|
"<p><a class='btn' href='/admin/players'>← Joueurs</a></p>";
|
||||||
|
return Html(Layout("Backfill", body));
|
||||||
|
}
|
||||||
|
|
||||||
// ---------- helpers ----------
|
// ---------- helpers ----------
|
||||||
|
|
||||||
private bool IsLan()
|
private bool IsLan()
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ public class ClientController : Controller
|
|||||||
private readonly DbEntityService _entityService;
|
private readonly DbEntityService _entityService;
|
||||||
private readonly UserDataService _userDataService;
|
private readonly UserDataService _userDataService;
|
||||||
private readonly TitleDataService _titleDataService;
|
private readonly TitleDataService _titleDataService;
|
||||||
|
private readonly Prospect.Server.Api.Services.Steam.SteamWebApiService _steamWebApi;
|
||||||
|
|
||||||
public ClientController(ILogger<ClientController> logger,
|
public ClientController(ILogger<ClientController> logger,
|
||||||
IOptions<PlayFabSettings> settings,
|
IOptions<PlayFabSettings> settings,
|
||||||
@@ -39,7 +40,8 @@ public class ClientController : Controller
|
|||||||
DbUserService userService,
|
DbUserService userService,
|
||||||
DbEntityService entityService,
|
DbEntityService entityService,
|
||||||
UserDataService userDataService,
|
UserDataService userDataService,
|
||||||
TitleDataService titleDataService)
|
TitleDataService titleDataService,
|
||||||
|
Prospect.Server.Api.Services.Steam.SteamWebApiService steamWebApi)
|
||||||
{
|
{
|
||||||
_settings = settings.Value;
|
_settings = settings.Value;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
@@ -48,6 +50,7 @@ public class ClientController : Controller
|
|||||||
_entityService = entityService;
|
_entityService = entityService;
|
||||||
_userDataService = userDataService;
|
_userDataService = userDataService;
|
||||||
_titleDataService = titleDataService;
|
_titleDataService = titleDataService;
|
||||||
|
_steamWebApi = steamWebApi;
|
||||||
}
|
}
|
||||||
|
|
||||||
[AllowAnonymous]
|
[AllowAnonymous]
|
||||||
@@ -63,6 +66,19 @@ public class ClientController : Controller
|
|||||||
var userSteamId = ticket.SteamId.ToString();
|
var userSteamId = ticket.SteamId.ToString();
|
||||||
|
|
||||||
var user = await _userService.FindOrCreateAsync(PlayFabUserAuthType.Steam, userSteamId);
|
var user = await _userService.FindOrCreateAsync(PlayFabUserAuthType.Steam, userSteamId);
|
||||||
|
|
||||||
|
// Backfill the display name from the Steam persona when we don't have a real
|
||||||
|
// one yet (accounts are created as "Unknown"; the client never sends a name).
|
||||||
|
if (string.IsNullOrEmpty(user.DisplayName) || user.DisplayName == "Unknown")
|
||||||
|
{
|
||||||
|
var persona = await _steamWebApi.GetPersonaNameAsync(userSteamId);
|
||||||
|
if (!string.IsNullOrWhiteSpace(persona))
|
||||||
|
{
|
||||||
|
await _userService.UpdateDisplayNameAsync(user.Id, persona);
|
||||||
|
user.DisplayName = persona;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var entity = await _entityService.FindOrCreateAsync(user.Id);
|
var entity = await _entityService.FindOrCreateAsync(user.Id);
|
||||||
|
|
||||||
var userTicket = _authTokenService.GenerateUser(entity);
|
var userTicket = _authTokenService.GenerateUser(entity);
|
||||||
|
|||||||
@@ -0,0 +1,55 @@
|
|||||||
|
using System.Text.Json;
|
||||||
|
|
||||||
|
namespace Prospect.Server.Api.Services.Steam;
|
||||||
|
|
||||||
|
// Resolves a Steam persona (display) name from a SteamID64 via the Steam Web API.
|
||||||
|
// PlayFab does this server-side too; our emulator only gets the SteamID from the auth
|
||||||
|
// ticket, so the real name needs an API key. Inert (no-op) when no key is configured.
|
||||||
|
public class SteamWebApiService
|
||||||
|
{
|
||||||
|
private static readonly HttpClient Http = new() { Timeout = TimeSpan.FromSeconds(5) };
|
||||||
|
|
||||||
|
private readonly string? _apiKey;
|
||||||
|
private readonly ILogger<SteamWebApiService> _logger;
|
||||||
|
|
||||||
|
public SteamWebApiService(IConfiguration configuration, ILogger<SteamWebApiService> logger)
|
||||||
|
{
|
||||||
|
_apiKey = configuration["SteamWebApiKey"];
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Enabled => !string.IsNullOrWhiteSpace(_apiKey);
|
||||||
|
|
||||||
|
public async Task<string?> GetPersonaNameAsync(string steamId64)
|
||||||
|
{
|
||||||
|
if (!Enabled)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var url = $"https://api.steampowered.com/ISteamUser/GetPlayerSummaries/v2/?key={_apiKey}&steamids={steamId64}";
|
||||||
|
var json = await Http.GetStringAsync(url);
|
||||||
|
using var doc = JsonDocument.Parse(json);
|
||||||
|
if (doc.RootElement.TryGetProperty("response", out var response) &&
|
||||||
|
response.TryGetProperty("players", out var players) &&
|
||||||
|
players.ValueKind == JsonValueKind.Array)
|
||||||
|
{
|
||||||
|
foreach (var player in players.EnumerateArray())
|
||||||
|
{
|
||||||
|
if (player.TryGetProperty("personaname", out var name))
|
||||||
|
{
|
||||||
|
return name.GetString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
_logger.LogWarning(e, "Steam GetPlayerSummaries failed for {SteamId}", steamId64);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -30,6 +30,8 @@ public class Startup
|
|||||||
services.AddSingleton<UserDataService>();
|
services.AddSingleton<UserDataService>();
|
||||||
services.AddSingleton<TitleDataService>();
|
services.AddSingleton<TitleDataService>();
|
||||||
|
|
||||||
|
services.AddSingleton<Prospect.Server.Api.Services.Steam.SteamWebApiService>();
|
||||||
|
|
||||||
services.AddSingleton<DbUserService>();
|
services.AddSingleton<DbUserService>();
|
||||||
services.AddSingleton<DbEntityService>();
|
services.AddSingleton<DbEntityService>();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user