|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|