using System.Diagnostics.CodeAnalysis; using System.Net; using System.Net.Http; using System.Net.Http.Json; using System.Threading.Tasks; using Content.Shared.CCVar; using Content.Shared._White; using Content.Shared._White.Sponsors; using Robust.Shared.Configuration; using Robust.Shared.Network; using Robust.Shared.Utility; namespace Content.Server._White.Sponsors; public sealed class SponsorsManager { [Dependency] private readonly IServerNetManager _netMgr = default!; [Dependency] private readonly IConfigurationManager _cfg = default!; [Dependency] private readonly IEntityManager _entityManager = default!; private readonly HttpClient _httpClient = new(); private ISawmill _sawmill = default!; private string _apiUrl = string.Empty; private readonly Dictionary _cachedSponsors = new(); public void Initialize() { _sawmill = Logger.GetSawmill("sponsors"); _cfg.OnValueChanged(WhiteCVars.SponsorsApiUrl, s => _apiUrl = s, true); _netMgr.RegisterNetMessage(); _netMgr.Connecting += OnConnecting; _netMgr.Connected += OnConnected; _netMgr.Disconnect += OnDisconnect; } public bool TryGetInfo(NetUserId userId, [NotNullWhen(true)] out SponsorInfo? sponsor) { return _cachedSponsors.TryGetValue(userId, out sponsor); } private async Task OnConnecting(NetConnectingArgs e) { var info = await LoadSponsorInfo(e.UserId); if (info?.Tier == null) { _cachedSponsors.Remove(e.UserId); // Remove from cache if sponsor expired return; } //AMOUR START var ev = new SponsorInfoLoadEvent(info); _entityManager.EventBus.RaiseEvent(EventSource.Local,ref ev); //AMOUR END DebugTools.Assert(!_cachedSponsors.ContainsKey(e.UserId), "Cached data was found on client connect"); _cachedSponsors[e.UserId] = info; } private void OnConnected(object? sender, NetChannelArgs e) { var info = _cachedSponsors.TryGetValue(e.Channel.UserId, out var sponsor) ? sponsor : null; var msg = new MsgSponsorInfo() { Info = info }; _netMgr.ServerSendMessage(msg, e.Channel); } private void OnDisconnect(object? sender, NetDisconnectedArgs e) { _cachedSponsors.Remove(e.Channel.UserId); } private async Task LoadSponsorInfo(NetUserId userId) { if (string.IsNullOrEmpty(_apiUrl)) return null; var url = $"{_apiUrl}/sponsors/{userId.ToString()}"; var response = await _httpClient.GetAsync(url); if (response.StatusCode == HttpStatusCode.NotFound) return null; if (response.StatusCode != HttpStatusCode.OK) { var errorText = await response.Content.ReadAsStringAsync(); _sawmill.Error( "Failed to get player sponsor OOC color from API: [{StatusCode}] {Response}", response.StatusCode, errorText); return null; } return await response.Content.ReadFromJsonAsync(); } } //AMOUR CLASS [ByRefEvent] public record struct SponsorInfoLoadEvent(SponsorInfo SponsorInfo);