1
0
Fork 0
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

107 lines
4.5 KiB

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using PhilExampleCrawler.Common.Models;
using PhilExampleCrawler.Common.TCP.Enums;
using PhilExampleCrawler.Common.TCP.Packets;
namespace PhilExampleCrawler.TCPAPI.Services
{
internal class UserSessionService
{
internal IReadOnlyDictionary<int, UserSession> RunningSessions => new Dictionary<int, UserSession>(_openSessions);
/// <summary> represents connectionID, UserSession </summary>
private readonly Dictionary<int, UserSession> _openSessions = new();
private readonly List<UserSession> _suspendedSessions = new();
private static int _lastSessionID = 0;
private static int NextSessionID() => _lastSessionID++;
private static DateTime NextValidUntil() => DateTime.Now.AddMinutes(60);
internal UserSessionService()
{
if (Program.TCPServer == null)
throw new InvalidOperationException("Program.TCPServer must not be null when using UserService.");
Program.TCPServer.OnDataReceived += TCPServer_OnDataReceived;
Program.TCPServer.OnUserDisconnected += TCPServer_OnUserDisconnected;
}
private void TCPServer_OnUserDisconnected(object? sender, int connectionID)
{
if(_openSessions.TryGetValue(connectionID, out UserSession? sess))
{
if (sess == null)
_openSessions.Remove(connectionID);
else
{
_openSessions.Remove(connectionID);
_suspendedSessions.Add(sess);
}
}
}
private async void TCPServer_OnDataReceived(object? sender, (int connectionID, BasePacket bp) e)
{
if(e.bp.LoadData.Type == LoadType.RegisterUserSessionLoad && e.bp.LoadData is RegisterUserSessionLoad regLoad)
{
var newSess = await RegisterUserSession(e.connectionID, regLoad);
if (newSess != null) {
if (Program.TCPServer.Send(e.connectionID,
new BasePacket(
new RegisterUserSessionOKLoad()
{
ForAuthCode = regLoad.AuthCode,
ValidUntil = newSess.ValidUntil
})))
Console.WriteLine("sent back RegisterUserSessionOKLoad to connectionID:" + e.connectionID);
else
Console.WriteLine("[Error2] TODO: could not send back RegisterUserSessionOKLoad to connectionID:" + e.connectionID);
}
else
Console.WriteLine("[Error2] TODO: could not send back RegisterUserSessionOKLoad to connectionID:" + e.connectionID);
}
}
private async Task<UserSession?> RegisterUserSession(int connectionID, RegisterUserSessionLoad regLoad)
{
if(TryUnsuspendSession(regLoad.AuthCode, out UserSession? unsuspendedSess) && unsuspendedSess != null)
{
_openSessions.Add(connectionID, unsuspendedSess);
return unsuspendedSess;
}
var sessID = NextSessionID();
var validUntil = NextValidUntil();
var user = await Program.DB_UserAcces.GetUserAsync(regLoad.AuthCode);
var crawlSessions = await Program.DB_CrawlSessionAccess.GetCrawlSessionsAsync(user.ID);
var newSess = new UserSession(sessID, user, crawlSessions, validUntil);
if (_openSessions.TryGetValue(connectionID, out UserSession? _))
_openSessions[connectionID] = newSess;
else
_openSessions.Add(connectionID, newSess);
return newSess;
}
/// <summary> Removes a session with given authCode from _suspendedSessions and updates its ValidUntil </summary>
private bool TryUnsuspendSession(string authCode, out UserSession? unsuspendedSess)
{
unsuspendedSess = _suspendedSessions.FirstOrDefault(x => x.User.AuthCode == authCode);
if (unsuspendedSess != null)
{
unsuspendedSess.ValidUntil = NextValidUntil();
_suspendedSessions.Remove(unsuspendedSess);
return true;
}
else
return false;
}
}
}