Skip to content

Commit

Permalink
Merge pull request #8 from rufo123/code
Browse files Browse the repository at this point in the history
Code Merge
  • Loading branch information
rufo123 authored Aug 5, 2023
2 parents 077aef7 + 4ecc882 commit 20a5ebd
Show file tree
Hide file tree
Showing 51 changed files with 17,142 additions and 11,463 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,8 @@
/TeamspeakStats/Properties/PublishProfiles
/TeamspeakStats
/TeamspeakStatsNew/TeamspeakStatsNew/ClientApp/.angular/cache/14.0.3
/TeamspeakStatsNew/TeamspeakStatsNew/ClientApp/.angular/cache/15.2.9/angular-webpack/ec35a561741b11a18fe0779f77fbfd74b497351a
/TeamspeakStatsNew/TeamspeakStatsNew/ClientApp/.angular/cache/15.2.9/babel-webpack
/TeamspeakStatsNew/TeamspeakStatsNew/ClientApp/.angular/cache/16.1.5/angular-webpack/038b8175c7e600ab53e36ff7af607abac7c5ad7c
/TeamspeakStatsNew/TeamspeakStatsNew/ClientApp/.angular/cache/16.1.5/angular-webpack
/TeamspeakStatsNew/TeamspeakStatsNew/ClientApp/.angular/cache/16.1.5/babel-webpack
12 changes: 12 additions & 0 deletions TeamspeakStatsNew/TeamspeakStatsNew/.config/dotnet-tools.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"version": 1,
"isRoot": true,
"tools": {
"dotnet-ef": {
"version": "7.0.9",
"commands": [
"dotnet-ef"
]
}
}
}
17 changes: 17 additions & 0 deletions TeamspeakStatsNew/TeamspeakStatsNew/Backend/AverageHoursManager.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
namespace TeamspeakStatsNew.Backend
{
public enum IntervalTypes
{
Yearly = 0,
Monthly = 1,
Daily = 2,
}

public class AverageHoursManager
{
public AverageHoursManager()
{
}

}
}
8 changes: 4 additions & 4 deletions TeamspeakStatsNew/TeamspeakStatsNew/Backend/Client.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ public class Client
private double aHoursTotal;
private bool aBot;
private bool aOnline;
private List<DateTime[]> aConnectedDates;
//private List<DateTime[]> aConnectedDates;

public Client(int parId)
{
Expand All @@ -19,7 +19,7 @@ public Client(int parId)
aHoursTotal = 0;
aBot = false;
aOnline = false;
aConnectedDates = new List<DateTime[]>();
//aConnectedDates = new List<DateTime[]>();
}


Expand All @@ -37,7 +37,7 @@ public void AddTotalTime(DateTime parDisconnectedTime)
if (parDisconnectedTime >= LastConnected)
{
aHoursTotal += (parDisconnectedTime - LastConnected).TotalHours;
aConnectedDates.Add(new DateTime[] { parDisconnectedTime, LastConnected });
//aConnectedDates.Add(new DateTime[] { parDisconnectedTime, LastConnected });
}
}

Expand Down Expand Up @@ -84,6 +84,6 @@ public bool Online
set => aOnline = value;
}

public List<DateTime[]> ConnectedDates => aConnectedDates;
// public List<DateTime[]> ConnectedDates => aConnectedDates;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
using System.Diagnostics;

namespace TeamspeakStatsNew.Backend
{
public class CountOfClientsRelativeToPeriod
{
private SortedDictionary<DateTime, int>? aDictionaryCountHours;
private SortedDictionary<DateTime, int>? aDictionaryCountDays;
private SortedDictionary<DateTime, int>? aDictionaryCountMonths;
private SortedDictionary<DateTime, int>? aDictionaryCountYears;

public SortedDictionary<DateTime, int>? DictionaryCountHours => aDictionaryCountHours;

public SortedDictionary<DateTime, int>? DictionaryCountDays => aDictionaryCountDays;

public SortedDictionary<DateTime, int>? DictionaryCountMonths => aDictionaryCountMonths;

public SortedDictionary<DateTime, int>? DictionaryCountYears => aDictionaryCountYears;

private SortedDictionary<DateTime, List<int>> aDictionaryOfAlreadyCountedClientIds;


public CountOfClientsRelativeToPeriod()
{
aDictionaryOfAlreadyCountedClientIds = new SortedDictionary<DateTime, List<int>>();
}

public void Initialise(
Dictionary<int, ClientConnectedData> parDictionaryClientConnectedData,
Dictionary<int, Client> parDictionaryOfClients
)
{
aDictionaryOfAlreadyCountedClientIds = new SortedDictionary<DateTime, List<int>>();
aDictionaryCountHours = CalculateCountOfPlayerHoursRelativeToPeriod(Periods.Hour, parDictionaryClientConnectedData, parDictionaryOfClients);
aDictionaryCountDays = CalculateCountOfPlayerHoursRelativeToPeriod(Periods.Day, parDictionaryClientConnectedData, parDictionaryOfClients);
aDictionaryCountMonths = CalculateCountOfPlayerHoursRelativeToPeriod(Periods.Month, parDictionaryClientConnectedData, parDictionaryOfClients);
aDictionaryCountYears = CalculateCountOfPlayerHoursRelativeToPeriod(Periods.Year, parDictionaryClientConnectedData, parDictionaryOfClients);
}

private DateTime AddDateTimeHelper(Periods parPeriod, DateTime parDateTime, bool skipAddition)
{
if (skipAddition)
{
return parDateTime;
}

switch (parPeriod)
{
case Periods.Hour:
return parDateTime.AddHours(1);
case Periods.Day:
return parDateTime.AddDays(1);
case Periods.Month:
return parDateTime.AddMonths(1);
case Periods.Year:
return parDateTime.AddYears(1);
default:
throw new ArgumentOutOfRangeException(nameof(parPeriod), parPeriod, null);
}
}

public SortedDictionary<DateTime, int>? CalculateCountOfPlayerHoursRelativeToPeriod(
Periods parPeriod,
Dictionary<int, ClientConnectedData> parDictionaryClientConnectedData,
Dictionary<int, Client> parDictionaryOfClients)
{

SortedDictionary<DateTime, int>? countOfPlayersRelativeToPeriod = new SortedDictionary<DateTime, int>();
aDictionaryOfAlreadyCountedClientIds = new SortedDictionary<DateTime, List<int>>();


foreach (var values in parDictionaryClientConnectedData.Values)
{
LoopConnectedTimesAndAssignConnectedBetweenPeriod(values, parDictionaryOfClients, parPeriod, ref countOfPlayersRelativeToPeriod);

}

return countOfPlayersRelativeToPeriod;
}

private void LoopConnectedTimesAndAssignConnectedBetweenPeriod(
ClientConnectedData parClientConnectedData,
Dictionary<int, Client> parClientDataDictionary,
Periods parPeriod,
ref SortedDictionary<DateTime, int>? parRefSortedDictToSaveTo)
{

DateTime lastDisconnectedTime = DateTime.UnixEpoch;

foreach (var connectedTimes in parClientConnectedData.ConnectionsDataListOfArrays)
{

DateTime connected = connectedTimes[1];
DateTime disconnected = connectedTimes[0];

IterateEachHourAndAssignConnectedTimes(connected, disconnected, parPeriod, parClientConnectedData.Id, ref parRefSortedDictToSaveTo);

lastDisconnectedTime = disconnected;

}

if (lastDisconnectedTime != DateTime.UnixEpoch && parClientDataDictionary[parClientConnectedData.Id].Online)
{
IterateEachHourAndAssignConnectedTimes(lastDisconnectedTime, DateTime.Now, parPeriod, parClientConnectedData.Id, ref parRefSortedDictToSaveTo);
}

}

private void IterateEachHourAndAssignConnectedTimes(DateTime parConnected, DateTime parDisconnected, Periods parPeriod, int parClientId, ref SortedDictionary<DateTime, int>? parRefSortedDictToSaveTo)
{
bool isFirstIteration = true;

// Iterate through each hour between connected and disconnected times
for (DateTime time = parConnected; time <= parDisconnected; time = AddDateTimeHelper(parPeriod, time, isFirstIteration))
{

isFirstIteration = false;
DateTime roundedTime;

switch (parPeriod)
{
case Periods.Hour:
roundedTime = new DateTime(time.Year, time.Month, time.Day, time.Hour, 0, 0);
break;
case Periods.Day:
roundedTime = new DateTime(time.Year, time.Month, time.Day, 0, 0, 0);
break;
case Periods.Month:
roundedTime = new DateTime(time.Year, time.Month, 1, 0, 0, 0);
break;
case Periods.Year:
roundedTime = new DateTime(time.Year, 1, 1, 0, 0, 0);
break;
default:
throw new ArgumentOutOfRangeException(nameof(parPeriod), parPeriod, null);
}

if (parRefSortedDictToSaveTo is null)
{
throw new ArgumentNullException(nameof(parRefSortedDictToSaveTo), "parRefSortedDictToSaveTo cannot be null.");
}

// Update the count of connected players for the rounded hour

if (aDictionaryOfAlreadyCountedClientIds.ContainsKey(roundedTime))
{
foreach (var clientId in aDictionaryOfAlreadyCountedClientIds[roundedTime])
{
if (clientId == parClientId)
{
return;
}
}

aDictionaryOfAlreadyCountedClientIds[roundedTime].Add(parClientId);
}
else
{
aDictionaryOfAlreadyCountedClientIds.Add(roundedTime, new List<int>());
}

if (parRefSortedDictToSaveTo.ContainsKey(roundedTime))
parRefSortedDictToSaveTo[roundedTime]++;
else
parRefSortedDictToSaveTo[roundedTime] = 1;
}
}


}
}
70 changes: 70 additions & 0 deletions TeamspeakStatsNew/TeamspeakStatsNew/Backend/Helpers.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
using System.Security.Cryptography;
using Microsoft.AspNetCore.Mvc;
using System.Text;
using System.Text.Json;

namespace TeamspeakStatsNew.Backend
{
public static class Helpers
{

public static bool IsETagValid(Client[] parClientArray, HttpRequest parRequest, HttpResponse parResponse)
{
var hash = ComputeHash(parClientArray); // Compute a hash of the clients array
var etag = Convert.ToBase64String(Encoding.UTF8.GetBytes(hash)); // Convert the hash to a base64 string

// Set the ETag header in the response
parResponse.Headers.Add("ETag", etag);

// Check if the If-None-Match header matches the current ETag
var ifNoneMatch = parRequest.Headers["If-None-Match"].FirstOrDefault();
if (ifNoneMatch != null && ifNoneMatch.Equals(etag))
{
return true; // ETag is valid, return true
}

return false; // ETag is not valid, return false
}

public static bool IsETagValid(SortedDictionary<DateTime, int>? sortedDictionary, HttpRequest parRequest, HttpResponse parResponse)
{

var hash = ComputeHash(sortedDictionary); // Compute a hash of the clients array
var etag = Convert.ToBase64String(Encoding.UTF8.GetBytes(hash)); // Convert the hash to a base64 string

// Set the ETag header in the response
parResponse.Headers.Add("ETag", etag);

// Check if the If-None-Match header matches the current ETag
var ifNoneMatch = parRequest.Headers["If-None-Match"].FirstOrDefault();

if (ifNoneMatch != null && ifNoneMatch.Equals(etag))
{
return true; // ETag is valid, return true
}

return false; // ETag is not valid, return false
}


private static string ComputeHash(IEnumerable<Client> parClientsArray)
{
using SHA256? sha256 = SHA256.Create();
string json = JsonSerializer.Serialize(parClientsArray);
byte[] bytes = Encoding.UTF8.GetBytes(json);
byte[] hashBytes = sha256.ComputeHash(bytes);
string hash = Convert.ToBase64String(hashBytes);
return hash;
}

private static string ComputeHash(SortedDictionary<DateTime, int>? parSortedDictionary)
{
using SHA256 sha256 = SHA256.Create();
string json = JsonSerializer.Serialize(parSortedDictionary);
byte[] bytes = Encoding.UTF8.GetBytes(json);
byte[] hashBytes = sha256.ComputeHash(bytes);
string hash = Convert.ToBase64String(hashBytes);
return hash;
}
}
}
19 changes: 10 additions & 9 deletions TeamspeakStatsNew/TeamspeakStatsNew/Backend/LogsReader.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
using System;
using System.Diagnostics;
using System.Numerics;
using System.Diagnostics;
using System.Text.RegularExpressions;

namespace TeamspeakStatsNew.Backend
Expand All @@ -17,23 +15,27 @@ public class LogsReader
public Dictionary<int, Client>? ClientsDictionary => aClientsDictionary;
public Dictionary<int, ClientConnectedData>? ClientConnectedDataDictionary => aClientConnectedDataDictionary;

public CountOfClientsRelativeToPeriod aCountOfClientsRelativeToPeriod;

public string LogsPath => aLogsPath;

public LogsReader()
{
aClientsDictionary = null;
aClientConnectedDataDictionary = null;
aCountOfClientsRelativeToPeriod = new CountOfClientsRelativeToPeriod();
aLogsPath = File.ReadAllText("Configuration/logs_path.txt");
aMergedIdsDictionary = CreateMergedIdsDictionary(ReadMergedIds());
aBotsHashSet = ReadBots();

Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
ReadLogs(aLogsPath);
stopwatch.Stop();
if (aClientConnectedDataDictionary != null && ClientsDictionary != null)
{
aCountOfClientsRelativeToPeriod.Initialise(aClientConnectedDataDictionary, ClientsDictionary);
}



TimeSpan elapsedTime = stopwatch.Elapsed;
Debug.WriteLine($"Execution time: {elapsedTime}");
}

public HashSet<int> ReadBots()
Expand Down Expand Up @@ -167,7 +169,6 @@ public void ReadLogs(string parLogsPath)

Client? client = GetClient(Int32.Parse(id), clientDictionaryTmp);


if (action == "connected")
{
if (client != null)
Expand Down
11 changes: 11 additions & 0 deletions TeamspeakStatsNew/TeamspeakStatsNew/Backend/Periods.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace TeamspeakStatsNew.Backend
{
public enum Periods
{
Hour = 0,
Day = 1,
Month = 2,
Year = 3
}

}
17 changes: 0 additions & 17 deletions TeamspeakStatsNew/TeamspeakStatsNew/ClientApp/.browserslistrc

This file was deleted.

Loading

0 comments on commit 20a5ebd

Please sign in to comment.