add tooltip timestamp to max concurrent players
This commit is contained in:
parent
54e39fabb1
commit
68c1151191
@ -10,7 +10,6 @@ using Microsoft.EntityFrameworkCore;
|
|||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using SharedLibraryCore;
|
using SharedLibraryCore;
|
||||||
using SharedLibraryCore.Dtos;
|
using SharedLibraryCore.Dtos;
|
||||||
using SharedLibraryCore.Helpers;
|
|
||||||
using SharedLibraryCore.Interfaces;
|
using SharedLibraryCore.Interfaces;
|
||||||
using ILogger = Microsoft.Extensions.Logging.ILogger;
|
using ILogger = Microsoft.Extensions.Logging.ILogger;
|
||||||
|
|
||||||
@ -20,14 +19,14 @@ namespace IW4MAdmin.Application.Misc
|
|||||||
public class ServerDataViewer : IServerDataViewer
|
public class ServerDataViewer : IServerDataViewer
|
||||||
{
|
{
|
||||||
private readonly ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
private readonly IDataValueCache<EFServerSnapshot, int> _snapshotCache;
|
private readonly IDataValueCache<EFServerSnapshot, (int?, DateTime?)> _snapshotCache;
|
||||||
private readonly IDataValueCache<EFClient, (int, int)> _serverStatsCache;
|
private readonly IDataValueCache<EFClient, (int, int)> _serverStatsCache;
|
||||||
private readonly IDataValueCache<EFServerSnapshot, List<ClientHistoryInfo>> _clientHistoryCache;
|
private readonly IDataValueCache<EFServerSnapshot, List<ClientHistoryInfo>> _clientHistoryCache;
|
||||||
|
|
||||||
private readonly TimeSpan? _cacheTimeSpan =
|
private readonly TimeSpan? _cacheTimeSpan =
|
||||||
Utilities.IsDevelopment ? TimeSpan.FromSeconds(1) : (TimeSpan?) TimeSpan.FromMinutes(1);
|
Utilities.IsDevelopment ? TimeSpan.FromSeconds(1) : (TimeSpan?) TimeSpan.FromMinutes(1);
|
||||||
|
|
||||||
public ServerDataViewer(ILogger<ServerDataViewer> logger, IDataValueCache<EFServerSnapshot, int> snapshotCache,
|
public ServerDataViewer(ILogger<ServerDataViewer> logger, IDataValueCache<EFServerSnapshot, (int?, DateTime?)> snapshotCache,
|
||||||
IDataValueCache<EFClient, (int, int)> serverStatsCache,
|
IDataValueCache<EFClient, (int, int)> serverStatsCache,
|
||||||
IDataValueCache<EFServerSnapshot, List<ClientHistoryInfo>> clientHistoryCache)
|
IDataValueCache<EFServerSnapshot, List<ClientHistoryInfo>> clientHistoryCache)
|
||||||
{
|
{
|
||||||
@ -37,7 +36,7 @@ namespace IW4MAdmin.Application.Misc
|
|||||||
_clientHistoryCache = clientHistoryCache;
|
_clientHistoryCache = clientHistoryCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<int> MaxConcurrentClientsAsync(long? serverId = null, TimeSpan? overPeriod = null,
|
public async Task<(int?, DateTime?)> MaxConcurrentClientsAsync(long? serverId = null, TimeSpan? overPeriod = null,
|
||||||
CancellationToken token = default)
|
CancellationToken token = default)
|
||||||
{
|
{
|
||||||
_snapshotCache.SetCacheItem(async (snapshots, cancellationToken) =>
|
_snapshotCache.SetCacheItem(async (snapshots, cancellationToken) =>
|
||||||
@ -45,26 +44,45 @@ namespace IW4MAdmin.Application.Misc
|
|||||||
var oldestEntry = overPeriod.HasValue
|
var oldestEntry = overPeriod.HasValue
|
||||||
? DateTime.UtcNow - overPeriod.Value
|
? DateTime.UtcNow - overPeriod.Value
|
||||||
: DateTime.UtcNow.AddDays(-1);
|
: DateTime.UtcNow.AddDays(-1);
|
||||||
var maxClients = 0;
|
|
||||||
|
int? maxClients;
|
||||||
|
DateTime? maxClientsTime;
|
||||||
|
|
||||||
if (serverId != null)
|
if (serverId != null)
|
||||||
{
|
{
|
||||||
maxClients = await snapshots.Where(snapshot => snapshot.ServerId == serverId)
|
var clients = await snapshots.Where(snapshot => snapshot.ServerId == serverId)
|
||||||
.Where(snapshot => snapshot.CapturedAt >= oldestEntry)
|
.Where(snapshot => snapshot.CapturedAt >= oldestEntry)
|
||||||
.MaxAsync(snapshot => (int?) snapshot.ClientCount, cancellationToken) ?? 0;
|
.OrderByDescending(snapshot => snapshot.ClientCount)
|
||||||
|
.Select(snapshot => new
|
||||||
|
{
|
||||||
|
snapshot.ClientCount,
|
||||||
|
snapshot.CapturedAt
|
||||||
|
})
|
||||||
|
.FirstOrDefaultAsync(cancellationToken);
|
||||||
|
|
||||||
|
maxClients = clients?.ClientCount;
|
||||||
|
maxClientsTime = clients?.CapturedAt;
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
maxClients = await snapshots.Where(snapshot => snapshot.CapturedAt >= oldestEntry)
|
var clients = await snapshots.Where(snapshot => snapshot.CapturedAt >= oldestEntry)
|
||||||
.GroupBy(snapshot => snapshot.PeriodBlock)
|
.GroupBy(snapshot => snapshot.PeriodBlock)
|
||||||
.Select(grp => grp.Sum(snapshot => (int?) snapshot.ClientCount))
|
.Select(grp => new
|
||||||
.MaxAsync(cancellationToken) ?? 0;
|
{
|
||||||
|
ClientCount = grp.Sum(snapshot => (int?) snapshot.ClientCount),
|
||||||
|
Time = grp.Max(snapshot => (DateTime?) snapshot.CapturedAt)
|
||||||
|
})
|
||||||
|
.OrderByDescending(snapshot => snapshot.ClientCount)
|
||||||
|
.FirstOrDefaultAsync(cancellationToken);
|
||||||
|
|
||||||
|
maxClients = clients?.ClientCount;
|
||||||
|
maxClientsTime = clients?.Time;
|
||||||
}
|
}
|
||||||
|
|
||||||
_logger.LogDebug("Max concurrent clients since {Start} is {Clients}", oldestEntry, maxClients);
|
_logger.LogDebug("Max concurrent clients since {Start} is {Clients}", oldestEntry, maxClients);
|
||||||
|
|
||||||
return maxClients;
|
return (maxClients, maxClientsTime);
|
||||||
}, nameof(MaxConcurrentClientsAsync), _cacheTimeSpan);
|
}, nameof(MaxConcurrentClientsAsync), _cacheTimeSpan);
|
||||||
|
|
||||||
try
|
try
|
||||||
@ -74,7 +92,7 @@ namespace IW4MAdmin.Application.Misc
|
|||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.LogError(ex, "Could not retrieve data for {Name}", nameof(MaxConcurrentClientsAsync));
|
_logger.LogError(ex, "Could not retrieve data for {Name}", nameof(MaxConcurrentClientsAsync));
|
||||||
return 0;
|
return (null, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using static SharedLibraryCore.Server;
|
using System;
|
||||||
|
using static SharedLibraryCore.Server;
|
||||||
|
|
||||||
namespace SharedLibraryCore.Dtos
|
namespace SharedLibraryCore.Dtos
|
||||||
{
|
{
|
||||||
@ -9,6 +10,7 @@ namespace SharedLibraryCore.Dtos
|
|||||||
public int TotalOccupiedClientSlots { get; set; }
|
public int TotalOccupiedClientSlots { get; set; }
|
||||||
public int TotalAvailableClientSlots { get; set; }
|
public int TotalAvailableClientSlots { get; set; }
|
||||||
public int MaxConcurrentClients { get; set; }
|
public int MaxConcurrentClients { get; set; }
|
||||||
|
public DateTime MaxConcurrentClientsTime { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// specifies the game name filter
|
/// specifies the game name filter
|
||||||
|
@ -19,7 +19,7 @@ namespace SharedLibraryCore.Interfaces
|
|||||||
/// <param name="overPeriod">how far in the past to search</param>
|
/// <param name="overPeriod">how far in the past to search</param>
|
||||||
/// <param name="token">CancellationToken</param>
|
/// <param name="token">CancellationToken</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<int> MaxConcurrentClientsAsync(long? serverId = null, TimeSpan? overPeriod = null, CancellationToken token = default);
|
Task<(int?, DateTime?)> MaxConcurrentClientsAsync(long? serverId = null, TimeSpan? overPeriod = null, CancellationToken token = default);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the total number of clients connected and total clients connected in the given time frame
|
/// Gets the total number of clients connected and total clients connected in the given time frame
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using Microsoft.AspNetCore.Diagnostics;
|
using System;
|
||||||
|
using Microsoft.AspNetCore.Diagnostics;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using SharedLibraryCore;
|
using SharedLibraryCore;
|
||||||
using SharedLibraryCore.Dtos;
|
using SharedLibraryCore.Dtos;
|
||||||
@ -33,7 +34,7 @@ namespace WebfrontCore.Controllers
|
|||||||
ViewBag.Keywords = Localization["WEBFRONT_KEWORDS_HOME"];
|
ViewBag.Keywords = Localization["WEBFRONT_KEWORDS_HOME"];
|
||||||
|
|
||||||
var servers = Manager.GetServers().Where(_server => !game.HasValue || _server.GameName == game);
|
var servers = Manager.GetServers().Where(_server => !game.HasValue || _server.GameName == game);
|
||||||
var maxConcurrentClients = await _serverDataViewer.MaxConcurrentClientsAsync(token: cancellationToken);
|
var (clientCount, time) = await _serverDataViewer.MaxConcurrentClientsAsync(token: cancellationToken);
|
||||||
var (count, recentCount) = await _serverDataViewer.ClientCountsAsync(token: cancellationToken);
|
var (count, recentCount) = await _serverDataViewer.ClientCountsAsync(token: cancellationToken);
|
||||||
|
|
||||||
var model = new IW4MAdminInfo()
|
var model = new IW4MAdminInfo()
|
||||||
@ -42,7 +43,8 @@ namespace WebfrontCore.Controllers
|
|||||||
TotalOccupiedClientSlots = servers.SelectMany(_server => _server.GetClientsAsList()).Count(),
|
TotalOccupiedClientSlots = servers.SelectMany(_server => _server.GetClientsAsList()).Count(),
|
||||||
TotalClientCount = count,
|
TotalClientCount = count,
|
||||||
RecentClientCount = recentCount,
|
RecentClientCount = recentCount,
|
||||||
MaxConcurrentClients = maxConcurrentClients,
|
MaxConcurrentClients = clientCount ?? 0,
|
||||||
|
MaxConcurrentClientsTime = time ?? DateTime.UtcNow,
|
||||||
Game = game,
|
Game = game,
|
||||||
ActiveServerGames = Manager.GetServers().Select(_server => _server.GameName).Distinct().ToArray()
|
ActiveServerGames = Manager.GetServers().Select(_server => _server.GameName).Distinct().ToArray()
|
||||||
};
|
};
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
<div class="col-xl-3 col-12">
|
<div class="col-xl-3 col-12">
|
||||||
<div class="text-muted text-center text-xl-left">@Html.Raw(formatTranslation("WEBFRONT_HOME_CLIENTS_ONLINE", Model.TotalOccupiedClientSlots, Model.TotalAvailableClientSlots))</div>
|
<div class="text-muted text-center text-xl-left">@Html.Raw(formatTranslation("WEBFRONT_HOME_CLIENTS_ONLINE", Model.TotalOccupiedClientSlots, Model.TotalAvailableClientSlots))</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-xl-3 col-12">
|
<div class="col-xl-3 col-12 moment-date" title="@Model.MaxConcurrentClientsTime">
|
||||||
<div class="text-muted text-center text-xl-left">@Html.Raw(formatTranslation("WEBFRONT_HOME_MAX_CONCURRENT_CLIENTS", Model.MaxConcurrentClients.ToString("#,##0")))</div>
|
<div class="text-muted text-center text-xl-left">@Html.Raw(formatTranslation("WEBFRONT_HOME_MAX_CONCURRENT_CLIENTS", Model.MaxConcurrentClients.ToString("#,##0")))</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-xl-3 col-12">
|
<div class="col-xl-3 col-12">
|
||||||
|
@ -95,6 +95,15 @@ $(document).ready(function () {
|
|||||||
historyChart.render();
|
historyChart.render();
|
||||||
charts[serverId] = historyChart;
|
charts[serverId] = historyChart;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$('.moment-date').each((index, element) => {
|
||||||
|
const title = $(element).attr('title');
|
||||||
|
|
||||||
|
if (title !== undefined) {
|
||||||
|
const date = new Date(title);
|
||||||
|
$(element).attr('title', moment.utc(date).calendar());
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
setInterval(refreshClientActivity, 2000);
|
setInterval(refreshClientActivity, 2000);
|
||||||
|
Loading…
Reference in New Issue
Block a user