Files
netris-nestri/packages/steam/SteamService.cs
Wanjohi f62fc1fb4b feat(www): Finish up on the onboarding (#210)
Merging this prematurely to make sure the team is on the same boat... like dang! We need to find a better way to do this. 

Plus it has become too big
2025-03-26 02:21:53 +03:00

156 lines
5.1 KiB
C#

using SteamKit2;
using SteamKit2.Authentication;
using Microsoft.EntityFrameworkCore;
using System.Collections.Concurrent;
// Steam Service
public class SteamService
{
private readonly ConcurrentDictionary<string, SteamClientHandler> _clientHandlers = new();
private readonly IServiceProvider _serviceProvider;
public SteamService(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
public Action SubscribeToEvents(string clientId, Action<ServerSentEvent> callback)
{
if (_clientHandlers.TryGetValue(clientId, out var handler))
{
return handler.Subscribe(callback);
}
return () => { }; // Empty unsubscribe function
}
public async Task StartAuthentication(string teamId, string userId)
{
var clientId = $"{teamId}:{userId}";
// Check if we already have stored credentials
using var scope = _serviceProvider.CreateScope();
var dbContext = scope.ServiceProvider.GetRequiredService<SteamDbContext>();
var storedCredential = await dbContext.SteamUserCredentials
.FirstOrDefaultAsync(c => c.TeamId == teamId && c.UserId == userId);
var handler = _clientHandlers.GetOrAdd(clientId, id => new SteamClientHandler(id,
async (accountName, refreshToken) => await SaveCredentials(teamId, userId, accountName, refreshToken)));
if (storedCredential != null)
{
// We have stored credentials, try to use them
var success = await handler.LoginWithStoredCredentialsAsync(storedCredential.AccountName, storedCredential.RefreshToken);
// If login failed, start fresh authentication
if (!success)
{
await handler.StartAuthenticationAsync();
}
return;
}
// No stored credentials, start fresh authentication
await handler.StartAuthenticationAsync();
}
private async Task SaveCredentials(string teamId, string userId, string accountName, string refreshToken)
{
try
{
using var scope = _serviceProvider.CreateScope();
var dbContext = scope.ServiceProvider.GetRequiredService<SteamDbContext>();
var existingCredential = await dbContext.SteamUserCredentials
.FirstOrDefaultAsync(c => c.TeamId == teamId && c.UserId == userId);
if (existingCredential != null)
{
// Update existing record
existingCredential.AccountName = accountName;
existingCredential.RefreshToken = refreshToken;
existingCredential.UpdatedAt = DateTime.UtcNow;
}
else
{
// Create new record
dbContext.SteamUserCredentials.Add(new SteamUserCredential
{
TeamId = teamId,
UserId = userId,
AccountName = accountName,
RefreshToken = refreshToken
});
}
await dbContext.SaveChangesAsync();
Console.WriteLine($"Saved Steam credentials for {teamId}:{userId}");
}
catch (Exception ex)
{
Console.WriteLine($"Error saving credentials: {ex.Message}");
}
}
public async Task<SteamUserInfo?> GetUserInfoFromStoredCredentials(string teamId, string userId)
{
var clientId = $"{teamId}:{userId}";
// Check if we have an active session
if (_clientHandlers.TryGetValue(clientId, out var activeHandler) && activeHandler.UserInfo != null)
{
return activeHandler.UserInfo;
}
// Try to get stored credentials
using var scope = _serviceProvider.CreateScope();
var dbContext = scope.ServiceProvider.GetRequiredService<SteamDbContext>();
var storedCredential = await dbContext.SteamUserCredentials
.FirstOrDefaultAsync(c => c.TeamId == teamId && c.UserId == userId);
if (storedCredential == null)
{
return null; // No stored credentials
}
// Create a new handler and try to log in
var handler = new SteamClientHandler(clientId);
var success = await handler.LoginWithStoredCredentialsAsync(
storedCredential.AccountName,
storedCredential.RefreshToken);
if (success)
{
_clientHandlers.TryAdd(clientId, handler);
return handler.UserInfo;
}
// Login failed, credentials might be invalid
return null;
}
public Action Subscribe(string clientId, Action<string> callback)
{
if (_clientHandlers.TryGetValue(clientId, out var handler))
{
return handler.Subscribe(callback);
}
return () => { }; // Empty unsubscribe function
}
public void Unsubscribe(string clientId, Action unsubscribeAction)
{
unsubscribeAction();
}
public SteamUserInfo? GetUserInfo(string clientId)
{
if (_clientHandlers.TryGetValue(clientId, out var handler))
{
return handler.UserInfo;
}
return null;
}
}