@PageName
diff --git a/MP.Land/Components/CmpTop.razor.cs b/MP.Land/Components/CmpTop.razor.cs
index 1706938e..7b3b7d14 100644
--- a/MP.Land/Components/CmpTop.razor.cs
+++ b/MP.Land/Components/CmpTop.razor.cs
@@ -1,4 +1,5 @@
using Microsoft.AspNetCore.Components;
+using Microsoft.AspNetCore.Components.Authorization;
using System;
using System.Threading.Tasks;
@@ -62,20 +63,16 @@ namespace MP.Land.Components
private async Task forceReload()
{
userName = "N.A.";
- await Task.Delay(1);
-#if false
-var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
-var user = authState.User;
-
-if (user.Identity.IsAuthenticated)
-{
-userName = $"{user.Identity.Name}";
-}
-else
-{
-userName = "N.A.";
-}
-#endif
+ await Task.Delay(1); var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
+ var user = authState.User;
+ if (user.Identity != null && user.Identity.IsAuthenticated)
+ {
+ userName = $"{user.Identity.Name}";
+ }
+ else
+ {
+ userName = "N.A.";
+ }
}
#endregion Private Methods
diff --git a/MP.Land/Data/LicenseService.cs b/MP.Land/Data/LicenseService.cs
index baeb055c..ede92400 100644
--- a/MP.Land/Data/LicenseService.cs
+++ b/MP.Land/Data/LicenseService.cs
@@ -12,6 +12,8 @@ using System.Text;
using System.Threading.Tasks;
using System.Web;
+#nullable enable
+
namespace MP.Land.Data
{
///
@@ -19,56 +21,6 @@ namespace MP.Land.Data
///
public class LicenseService
{
- #region Private Fields
-
- private static IConfiguration? _configuration;
- private static ILogger
? _logger;
-
- ///
- /// URL dell'API x chiamate gestione licenze
- ///
- private static string apiUrl = "https://liman.egalware.com/ELM.API/";
- //private static string apiUrl = "https://localhost:44351/";
-
- ///
- /// Chiave redis x info della licenza
- ///
- private static string rkeyAppInfo = "LongCache:AppInfo";
-
- private readonly IDistributedCache distributedCache;
-
- ///
- /// Elenco obj in cache
- ///
- private List cachedDataList = new List();
-
- ///
- /// Fattorte conversione cache sliding --> 1 h
- ///
- private int cacheFact = 12;
-
- ///
- /// Durata assoluta massima della cache IN SECONDI
- ///
- private int chAbsExp = 60 * 5;
-
- ///
- /// Durata della cache IN SECONDI in modalità inattiva (non acceduta) prima di venire rimossa
- /// NON estende oltre il tempo massimo di validità della cache (chAbsExp)
- ///
- private int chSliExp = 60 * 1;
-
- #endregion Private Fields
-
- #region Protected Fields
-
- ///
- /// Chiave redis x attivazioni della licenza
- ///
- protected const string rKeyAttByLic = "LongCache:AttByLic";
-
- #endregion Protected Fields
-
#region Public Constructors
///
@@ -95,9 +47,7 @@ namespace MP.Land.Data
#region Public Properties
public List ActivList { get; set; } = new List();
-
public List AKVList { get; set; } = new List();
-
public string Applicazione { get; set; } = "";
public bool HasActivData
@@ -158,74 +108,212 @@ namespace MP.Land.Data
#endregion Public Properties
- #region Private Methods
+ #region Public Methods
- ///
- /// Opzioni cache con moltiplicatore durata risp durata base (1/5 minuti)
- ///
- ///
- ///
- private DistributedCacheEntryOptions cacheOpt(int multFact)
+ public async Task> ActivListCache()
{
- var numSecAbsExp = chAbsExp * multFact;
- var numSecSliExp = chSliExp * multFact;
- return new DistributedCacheEntryOptions().SetAbsoluteExpiration(DateTime.Now.AddSeconds(numSecAbsExp)).SetSlidingExpiration(TimeSpan.FromSeconds(numSecSliExp));
- }
-
- ///
- /// Elenco attivazioni attuali
- ///
- private async Task?> OnlineActivationList()
- {
- List? answ = new List();
- // cerco online
- RestClient client = new RestClient(apiUrl);
- //client.Authenticator = new HttpBasicAuthenticator("username", "password");
- string MKeyEnc = HttpUtility.UrlEncode(MasterKey);
- var request = new RestRequest($"api/attivazioni/?chiave={MKeyEnc}", Method.Get);
- var response = await client.GetAsync(request);
- // controllo risposta
- if (response.StatusCode == System.Net.HttpStatusCode.OK)
+ List dbResult = new List();
+ string cacheKey = $"{rKeyAttByLic}:{MasterKey}";
+ trackCache(cacheKey);
+ string rawData = await getRSV(cacheKey);
+ if (!string.IsNullOrEmpty(rawData))
{
- // salvo in redis contenuto serializzato
- string rawData = $"{response.Content}";
- answ = JsonConvert.DeserializeObject?>(rawData);
+ var cacheRes = JsonConvert.DeserializeObject?>(rawData);
+ if (cacheRes != null)
+ {
+ dbResult = cacheRes;
+ }
}
- return await Task.FromResult(answ);
+
+ return await Task.FromResult(dbResult);
}
///
- /// Recupera info licenza da remoto
+ /// Verifica attivazione licenza
///
- private async Task> OnlineAppInfo()
+ ///
+ ///
+ public bool checkLicenseActive(string authKey)
{
- List answ = new List();
+ bool answ = false;
+ //cerco anche nelle info AKV
+ if (AKVList != null)
+ {
+ var recLic = AKVList.Where(x => x.ValString == authKey).FirstOrDefault();
+ int numLic = 0;
+ //cerco in record
+ if (recLic != null && recLic.ValInt != null)
+ {
+ numLic = (int)recLic.ValInt;
+ // verifico scadenza licenza!
+ DateTime scadenza = licenseManGLS.expiryDateByAuthKey(Installazione, recLic.NomeVar, numLic, authKey);
+ answ = scadenza > DateTime.Today;
+ }
+ else
+ {
+ _logger.LogInformation($"checkLicenseActive | Record non trovato per {authKey}");
+ }
+ }
+ return answ;
+ }
+
+ ///
+ /// Stato server gestione licenze
+ ///
+ public async Task checkLimanServer()
+ {
+ string answ = "ND";
// cerco online
RestClient client = new RestClient(apiUrl);
- string MKeyEnc = HttpUtility.UrlEncode(MasterKey);
- //string mKey = System.Net.WebUtility.UrlEncode(MasterKey);
- string reqUrl = $"api/licenza/{Installazione}?CodApp={Applicazione}&Chiave={MKeyEnc}";
- var request = new RestRequest(reqUrl, Method.Get);
+ var request = new RestRequest($"api/health", Method.Get);
var response = await client.GetAsync(request);
// controllo risposta
if (response.StatusCode == System.Net.HttpStatusCode.OK)
{
// verifico risposta
- string rawData = $"{response.Content}";
- answ = JsonConvert.DeserializeObject?>(rawData);
+ if (response.Content != null)
+ {
+ answ = response.Content.Replace("\"", "");
+ }
}
return await Task.FromResult(answ);
}
- private void ReportUpdated()
+ ///
+ /// Verifica scadenza licenza
+ ///
+ ///
+ ///
+ public DateTime getLicenseExpiry(string authKey)
{
+ DateTime answ = DateTime.Today.AddDays(-1);
+ //cerco anche nelle info AKV
+ if (AKVList != null)
+ {
+ var recLic = AKVList.Where(x => x.ValString == authKey).FirstOrDefault();
+ int numLic = 0;
+ //cerco in record
+ if (recLic != null && recLic.ValInt != null)
+ {
+ numLic = (int)recLic.ValInt;
+ // verifico scadenza licenza!
+ DateTime scadenza = licenseManGLS.expiryDateByAuthKey(Installazione, recLic.NomeVar, numLic, authKey);
+ answ = scadenza;
+ }
+ else
+ {
+ _logger.LogInformation($"getLicenseExpiry | Record non trovato per {authKey}");
+ }
+ }
+ return answ;
+ }
+
+ ///
+ /// Init della classe con variabili di base da Redis/DB
+ ///
+ public bool InitAkv()
+ {
+ bool fatto = false;
+ Applicazione = "MAPO";
+ Installazione = getAVKStr("Installazione");
+ MasterKey = getAVKStr(Applicazione);
+ NumLicDb = getAVKInt(Applicazione);
+ fatto = !string.IsNullOrEmpty($"{Installazione}{MasterKey}");
+ return fatto;
+ }
+
+ public async Task> LicAppCache()
+ {
+ List dbResult = new List();
+ string cacheKey = $"{rkeyAppInfo}:{MasterKey}";
+ trackCache(cacheKey);
+ string rawData = await getRSV(cacheKey);
+ if (!string.IsNullOrEmpty(rawData))
+ {
+ var cacheRes = JsonConvert.DeserializeObject?>(rawData);
+ if (cacheRes != null)
+ {
+ dbResult = cacheRes;
+ }
+ }
+
+ return await Task.FromResult(dbResult);
+ }
+
+ ///
+ /// Init della classe con variabili di base da Redis/DB
+ ///
+ public async Task RefreshLicense()
+ {
+ bool fatto = false;
+ // scadenza info a 15 gg...
+ int numDays = 15;
+
+ // dati applicativo
+ var appData = await OnlineAppInfo();
+ if (appData != null)
+ {
+ if (appData.Count > 0)
+ {
+ fatto = await setAppInfo(appData, numDays);
+ // salvo info licenza...
+ NumLicRemote = appData[0].NumLicenze;
+ }
+ }
+
+ // dati attivazioni
+ var onlineAct = await OnlineActivationList();
+ if (onlineAct != null)
+ {
+ if (onlineAct.Count > 0)
+ {
+ infoExpiry = DateTime.Now.AddDays(numDays);
+ ActivList = onlineAct;
+ fatto = await setActivList(onlineAct, numDays);
+ }
+ }
+ await Task.Delay(1);
+ return fatto;
+ }
+
+ public async Task setActivList(List newActList, int numDays)
+ {
+ bool fatto = false;
+ string cacheKey = $"{rKeyAttByLic}:{MasterKey}";
+ var rawData = JsonConvert.SerializeObject(newActList);
+ await setRSV(cacheKey, rawData, numDays * cacheFact * 24);
+ fatto = true;
if (EA_InfoUpdated != null)
{
EA_InfoUpdated?.Invoke();
}
+ return fatto;
}
- #endregion Private Methods
+ public async Task setAppInfo(List newAppInfo, int numDays)
+ {
+ bool fatto = false;
+ string cacheKey = $"{rkeyAppInfo}:{MasterKey}";
+ var rawData = JsonConvert.SerializeObject(newAppInfo);
+ await setRSV(cacheKey, rawData, numDays * cacheFact * 24);
+ fatto = true;
+ if (EA_InfoUpdated != null)
+ {
+ EA_InfoUpdated?.Invoke();
+ }
+ return fatto;
+ }
+
+ #endregion Public Methods
+
+ #region Protected Fields
+
+ ///
+ /// Chiave redis x attivazioni della licenza
+ ///
+ protected const string rKeyAttByLic = "LongCache:AttByLic";
+
+ #endregion Protected Fields
#region Protected Methods
@@ -329,198 +417,120 @@ namespace MP.Land.Data
#endregion Protected Methods
- #region Public Methods
+ #region Private Fields
- public async Task> ActivListCache()
- {
- List dbResult = new List();
- string cacheKey = $"{rKeyAttByLic}:{MasterKey}";
- trackCache(cacheKey);
- string rawData = await getRSV(cacheKey);
- if (!string.IsNullOrEmpty(rawData))
- {
- var cacheRes = JsonConvert.DeserializeObject?>(rawData);
- if (cacheRes != null)
- {
- dbResult = cacheRes;
- }
- }
-
- return await Task.FromResult(dbResult);
- }
+ private static IConfiguration? _configuration;
///
- /// Verifica attivazione licenza
+ /// URL dell'API x chiamate gestione licenze
///
- ///
+ private static string apiUrl = "https://liman.egalware.com/ELM.API/";
+
+ ///
+ /// Chiave redis x info della licenza
+ ///
+ private static string rkeyAppInfo = "LongCache:AppInfo";
+
+ //private static string apiUrl = "https://localhost:44351/";
+ private readonly IDistributedCache distributedCache;
+
+ ///
+ /// Elenco obj in cache
+ ///
+ private List cachedDataList = new List();
+
+ ///
+ /// Fattorte conversione cache sliding --> 1 h
+ ///
+ private int cacheFact = 12;
+
+ ///
+ /// Durata assoluta massima della cache IN SECONDI
+ ///
+ private int chAbsExp = 60 * 5;
+
+ ///
+ /// Durata della cache IN SECONDI in modalità inattiva (non acceduta) prima di venire
+ /// rimossa NON estende oltre il tempo massimo di validità della cache (chAbsExp)
+ ///
+ private int chSliExp = 60 * 1;
+
+ #endregion Private Fields
+
+ #region Private Properties
+
+ private static ILogger _logger { get; set; } = null!;
+
+ #endregion Private Properties
+
+ #region Private Methods
+
+ ///
+ /// Opzioni cache con moltiplicatore durata risp durata base (1/5 minuti)
+ ///
+ ///
///
- public bool checkLicenseActive(string authKey)
+ private DistributedCacheEntryOptions cacheOpt(int multFact)
{
- bool answ = false;
- //cerco anche nelle info AKV
- if (AKVList != null)
- {
- var recLic = AKVList.Where(x => x.ValString == authKey).FirstOrDefault();
- int numLic = 0;
- //cerco in record
- if (recLic != null)
- {
- numLic = (int)recLic.ValInt;
- // verifico scadenza licenza!
- DateTime scadenza = licenseManGLS.expiryDateByAuthKey(Installazione, recLic.NomeVar, numLic, authKey);
- answ = scadenza > DateTime.Today;
- }
- else
- {
- _logger.LogInformation($"checkLicenseActive | Record non trovato per {authKey}");
- }
- }
- return answ;
- }
- ///
- /// Verifica scadenza licenza
- ///
- ///
- ///
- public DateTime getLicenseExpiry(string authKey)
- {
- DateTime answ = DateTime.Today.AddDays(-1);
- //cerco anche nelle info AKV
- if (AKVList != null)
- {
- var recLic = AKVList.Where(x => x.ValString == authKey).FirstOrDefault();
- int numLic = 0;
- //cerco in record
- if (recLic != null)
- {
- numLic = (int)recLic.ValInt;
- // verifico scadenza licenza!
- DateTime scadenza = licenseManGLS.expiryDateByAuthKey(Installazione, recLic.NomeVar, numLic, authKey);
- answ = scadenza;
- }
- else
- {
- _logger.LogInformation($"getLicenseExpiry | Record non trovato per {authKey}");
- }
- }
- return answ;
+ var numSecAbsExp = chAbsExp * multFact;
+ var numSecSliExp = chSliExp * multFact;
+ return new DistributedCacheEntryOptions().SetAbsoluteExpiration(DateTime.Now.AddSeconds(numSecAbsExp)).SetSlidingExpiration(TimeSpan.FromSeconds(numSecSliExp));
}
///
- /// Stato server gestione licenze
+ /// Elenco attivazioni attuali
///
- public async Task checkLimanServer()
+ private async Task?> OnlineActivationList()
{
- string answ = "ND";
+ List? answ = new List();
// cerco online
RestClient client = new RestClient(apiUrl);
- var request = new RestRequest($"api/health", Method.Get);
+ //client.Authenticator = new HttpBasicAuthenticator("username", "password");
+ string MKeyEnc = HttpUtility.UrlEncode(MasterKey);
+ var request = new RestRequest($"api/attivazioni/?chiave={MKeyEnc}", Method.Get);
var response = await client.GetAsync(request);
// controllo risposta
if (response.StatusCode == System.Net.HttpStatusCode.OK)
{
- // verifico risposta
- answ = response.Content.Replace("\"", "");
+ // salvo in redis contenuto serializzato
+ string rawData = $"{response.Content}";
+ answ = JsonConvert.DeserializeObject?>(rawData);
}
return await Task.FromResult(answ);
}
///
- /// Init della classe con variabili di base da Redis/DB
+ /// Recupera info licenza da remoto
///
- public bool InitAkv()
+ private async Task> OnlineAppInfo()
{
- bool fatto = false;
- Applicazione = "MAPO";
- Installazione = getAVKStr("Installazione");
- MasterKey = getAVKStr(Applicazione);
- NumLicDb = getAVKInt(Applicazione);
- fatto = !string.IsNullOrEmpty($"{Installazione}{MasterKey}");
- return fatto;
+ List? answ = new List();
+ // cerco online
+ RestClient client = new RestClient(apiUrl);
+ string MKeyEnc = HttpUtility.UrlEncode(MasterKey);
+ //string mKey = System.Net.WebUtility.UrlEncode(MasterKey);
+ string reqUrl = $"api/licenza/{Installazione}?CodApp={Applicazione}&Chiave={MKeyEnc}";
+ var request = new RestRequest(reqUrl, Method.Get);
+ var response = await client.GetAsync(request);
+ // controllo risposta
+ if (response.StatusCode == System.Net.HttpStatusCode.OK)
+ {
+ // verifico risposta
+ string rawData = $"{response.Content}";
+ answ = JsonConvert.DeserializeObject?>(rawData);
+ }
+ // restituisce valori o insieme vuoto
+ return await Task.FromResult(answ ?? new List());
}
- public async Task> LicAppCache()
+ private void ReportUpdated()
{
- List dbResult = new List();
- string cacheKey = $"{rkeyAppInfo}:{MasterKey}";
- trackCache(cacheKey);
- string rawData = await getRSV(cacheKey);
- if (!string.IsNullOrEmpty(rawData))
- {
- var cacheRes = JsonConvert.DeserializeObject?>(rawData);
- if (cacheRes != null)
- {
- dbResult = cacheRes;
- }
- }
-
- return await Task.FromResult(dbResult);
- }
-
- ///
- /// Init della classe con variabili di base da Redis/DB
- ///
- public async Task RefreshLicense()
- {
- bool fatto = false;
- // scadenza info a 15 gg...
- int numDays = 15;
-
- // dati applicativo
- var appData = await OnlineAppInfo();
- if (appData != null)
- {
- if (appData.Count > 0)
- {
- fatto = await setAppInfo(appData, numDays);
- // salvo info licenza...
- NumLicRemote = appData[0].NumLicenze;
- }
- }
-
- // dati attivazioni
- var onlineAct = await OnlineActivationList();
- if (onlineAct != null)
- {
- if (onlineAct.Count > 0)
- {
- infoExpiry = DateTime.Now.AddDays(numDays);
- ActivList = onlineAct;
- fatto = await setActivList(onlineAct, numDays);
- }
- }
- await Task.Delay(1);
- return fatto;
- }
-
- public async Task setActivList(List newActList, int numDays)
- {
- bool fatto = false;
- string cacheKey = $"{rKeyAttByLic}:{MasterKey}";
- var rawData = JsonConvert.SerializeObject(newActList);
- await setRSV(cacheKey, rawData, numDays * cacheFact * 24);
- fatto = true;
if (EA_InfoUpdated != null)
{
EA_InfoUpdated?.Invoke();
}
- return fatto;
}
- public async Task setAppInfo(List newAppInfo, int numDays)
- {
- bool fatto = false;
- string cacheKey = $"{rkeyAppInfo}:{MasterKey}";
- var rawData = JsonConvert.SerializeObject(newAppInfo);
- await setRSV(cacheKey, rawData, numDays * cacheFact * 24);
- fatto = true;
- if (EA_InfoUpdated != null)
- {
- EA_InfoUpdated?.Invoke();
- }
- return fatto;
- }
-
- #endregion Public Methods
+ #endregion Private Methods
}
}
\ No newline at end of file
diff --git a/MP.Land/MP.Land.csproj b/MP.Land/MP.Land.csproj
index e5d244a5..f9e55a89 100644
--- a/MP.Land/MP.Land.csproj
+++ b/MP.Land/MP.Land.csproj
@@ -3,7 +3,7 @@
net6.0
MP.Land
- 6.16.2211.0416
+ 6.16.2211.1518
@@ -45,6 +45,7 @@
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/MP.Land/Properties/launchSettings.json b/MP.Land/Properties/launchSettings.json
index aeaf5b5b..7f84d546 100644
--- a/MP.Land/Properties/launchSettings.json
+++ b/MP.Land/Properties/launchSettings.json
@@ -1,7 +1,7 @@
{
"iisSettings": {
- "windowsAuthentication": false,
- "anonymousAuthentication": true,
+ "windowsAuthentication": true,
+ "anonymousAuthentication": false,
"iisExpress": {
"applicationUrl": "http://localhost:7314",
"sslPort": 44311
diff --git a/MP.Land/Resources/ChangeLog.html b/MP.Land/Resources/ChangeLog.html
index 9fbcacb8..d340f879 100644
--- a/MP.Land/Resources/ChangeLog.html
+++ b/MP.Land/Resources/ChangeLog.html
@@ -1,6 +1,6 @@
Modulo gestione Programmi MAPO
- Versione: 6.16.2211.0416
+ Versione: 6.16.2211.1518
Note di rilascio:
diff --git a/MP.Land/Resources/VersNum.txt b/MP.Land/Resources/VersNum.txt
index 3af0d134..b3babe51 100644
--- a/MP.Land/Resources/VersNum.txt
+++ b/MP.Land/Resources/VersNum.txt
@@ -1 +1 @@
-6.16.2211.0416
+6.16.2211.1518
diff --git a/MP.Land/Resources/manifest.xml b/MP.Land/Resources/manifest.xml
index 2f81485a..3baa45d2 100644
--- a/MP.Land/Resources/manifest.xml
+++ b/MP.Land/Resources/manifest.xml
@@ -1,6 +1,6 @@
-
- 6.16.2211.0416
+ 6.16.2211.1518
https://nexus.steamware.net/repository/SWS/MP-LAND/stable/LAST/MP.Land.zip
https://nexus.steamware.net/repository/SWS/MP-LAND/stable/LAST/ChangeLog.html
false
diff --git a/MP.Land/Startup.cs b/MP.Land/Startup.cs
index c599a8b6..e8f91d80 100644
--- a/MP.Land/Startup.cs
+++ b/MP.Land/Startup.cs
@@ -1,3 +1,4 @@
+using Microsoft.AspNetCore.Authentication.Negotiate;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Hosting;
@@ -75,8 +76,8 @@ namespace MP.Land
app.UseRouting();
- //app.UseAuthentication();
- //app.UseAuthorization();
+ app.UseAuthentication();
+ app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
@@ -103,6 +104,17 @@ namespace MP.Land
o.SlidingExpiration = true;
});
+
+ services.AddAuthentication(NegotiateDefaults.AuthenticationScheme)
+ .AddNegotiate();
+
+ services.AddAuthorization(options =>
+ {
+ // By default, all incoming requests will be authorized according to the default policy.
+ options.FallbackPolicy = options.DefaultPolicy;
+ });
+
+
services.AddStackExchangeRedisCache(options =>
{
//options.ConfigurationOptions = new StackExchange.Redis.ConfigurationOptions() { KeepAlive = 180, DefaultDatabase = 1, EndPoints = { { "localhost", 6379 } } };
diff --git a/MP.Stats/MP.Stats.csproj b/MP.Stats/MP.Stats.csproj
index 8683fb68..39ac2560 100644
--- a/MP.Stats/MP.Stats.csproj
+++ b/MP.Stats/MP.Stats.csproj
@@ -4,7 +4,7 @@
net6.0
MP.Stats
826e877c-ba70-4253-84cb-d0b1cafd4440
- 6.16.2210.2110
+ 6.16.2211.1517
diff --git a/MP.Stats/Resources/ChangeLog.html b/MP.Stats/Resources/ChangeLog.html
index c3a834ed..5e47116b 100644
--- a/MP.Stats/Resources/ChangeLog.html
+++ b/MP.Stats/Resources/ChangeLog.html
@@ -1,6 +1,6 @@
Modulo statistiche MAPO
-
Versione: 6.16.2210.2110
+ Versione: 6.16.2211.1517
Note di rilascio:
diff --git a/MP.Stats/Resources/VersNum.txt b/MP.Stats/Resources/VersNum.txt
index 148d3a17..b5d4a429 100644
--- a/MP.Stats/Resources/VersNum.txt
+++ b/MP.Stats/Resources/VersNum.txt
@@ -1 +1 @@
-6.16.2210.2110
+6.16.2211.1517
diff --git a/MP.Stats/Resources/manifest.xml b/MP.Stats/Resources/manifest.xml
index b9e7e7bc..920440d2 100644
--- a/MP.Stats/Resources/manifest.xml
+++ b/MP.Stats/Resources/manifest.xml
@@ -1,6 +1,6 @@
-
- 6.16.2210.2110
+ 6.16.2211.1517
https://nexus.steamware.net/repository/SWS/MP-STATS/stable/LAST/MP.Stats.zip
https://nexus.steamware.net/repository/SWS/MP-STATS/stable/LAST/ChangeLog.html
false