More stats polishing
fixed player specification for commands with multiple words
This commit is contained in:
parent
f929e606f4
commit
b9900707b5
@ -1,5 +1,4 @@
|
||||
|
||||
#define USINGMEMORY
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using SharedLibrary;
|
||||
|
@ -199,6 +199,12 @@ namespace IW4MAdmin
|
||||
var Status = TaskStatuses[i];
|
||||
if (Status.RequestedTask == null || Status.RequestedTask.Status == TaskStatus.RanToCompletion)
|
||||
{
|
||||
if (Status.ElapsedMillisecondsTime() > 60000)
|
||||
{
|
||||
Logger.WriteWarning($"Task took longer than 60 seconds to complete, killing");
|
||||
//Status.RequestedTask.
|
||||
}
|
||||
|
||||
Status.Update(new Task<bool>(() => { return (Status.Dependant as Server).ProcessUpdatesAsync(Status.GetToken()).Result; }));
|
||||
if (Status.RunAverage > 1000 + UPDATE_FREQUENCY)
|
||||
Logger.WriteWarning($"Update task average execution is longer than desired for {(Status.Dependant as Server)} [{Status.RunAverage}ms]");
|
||||
|
@ -34,6 +34,7 @@ namespace IW4MAdmin
|
||||
{
|
||||
// update their ping
|
||||
Players[polledPlayer.ClientNumber].Ping = polledPlayer.Ping;
|
||||
Players[polledPlayer.ClientNumber].Score = polledPlayer.Score;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -112,6 +113,7 @@ namespace IW4MAdmin
|
||||
// NewPlayer.Level = Player.Permission.Flagged;
|
||||
// Do the player specific stuff
|
||||
player.ClientNumber = polledPlayer.ClientNumber;
|
||||
player.Score = polledPlayer.Score;
|
||||
Players[player.ClientNumber] = player;
|
||||
Logger.WriteInfo($"Client {player} connecting...");
|
||||
|
||||
@ -210,7 +212,15 @@ namespace IW4MAdmin
|
||||
if (C.RequiresTarget || Args.Length > 0)
|
||||
{
|
||||
int cNum = -1;
|
||||
int.TryParse(Args[0], out cNum);
|
||||
try
|
||||
{
|
||||
cNum = Convert.ToInt32(Args[0]);
|
||||
}
|
||||
|
||||
catch(FormatException)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
if (Args[0][0] == '@') // user specifying target by database ID
|
||||
{
|
||||
@ -227,7 +237,7 @@ namespace IW4MAdmin
|
||||
}
|
||||
}
|
||||
|
||||
else if (Args[0].Length < 3 && cNum > -1 && cNum < 18) // user specifying target by client num
|
||||
else if (Args[0].Length < 3 && cNum > -1 && cNum < MaxClients) // user specifying target by client num
|
||||
{
|
||||
if (Players[cNum] != null)
|
||||
{
|
||||
@ -250,6 +260,13 @@ namespace IW4MAdmin
|
||||
{
|
||||
E.Target = matchingPlayers.First();
|
||||
E.Data = Regex.Replace(E.Data, $"\"{E.Target.Name}\"", "", RegexOptions.IgnoreCase).Trim();
|
||||
|
||||
if (E.Data.ToLower().Trim() == E.Target.Name.ToLower().Trim())
|
||||
{
|
||||
await E.Origin.Tell($"Not enough arguments supplied!");
|
||||
await E.Origin.Tell(C.Syntax);
|
||||
throw new SharedLibrary.Exceptions.CommandException($"{E.Origin} did not supply enough arguments for \"{C.Name}\"");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -267,6 +284,13 @@ namespace IW4MAdmin
|
||||
{
|
||||
E.Target = matchingPlayers.First();
|
||||
E.Data = Regex.Replace(E.Data, $"{E.Target.Name}", "", RegexOptions.IgnoreCase).Trim();
|
||||
|
||||
if (E.Data.Trim() == E.Target.Name.ToLower().Trim())
|
||||
{
|
||||
await E.Origin.Tell($"Not enough arguments supplied!");
|
||||
await E.Origin.Tell(C.Syntax);
|
||||
throw new SharedLibrary.Exceptions.CommandException($"{E.Origin} did not supply enough arguments for \"{C.Name}\"");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Binary file not shown.
@ -11,11 +11,13 @@ namespace StatsPlugin.Helpers
|
||||
public class ServerStats
|
||||
{
|
||||
public Dictionary<int, EFClientStatistics> PlayerStats { get; set; }
|
||||
public EFServerStatistics ServerStatistics { get; private set; }
|
||||
public EFServer Server { get; private set; }
|
||||
|
||||
public ServerStats(EFServer sv)
|
||||
public ServerStats(EFServer sv, EFServerStatistics st)
|
||||
{
|
||||
PlayerStats = new Dictionary<int, EFClientStatistics>();
|
||||
ServerStatistics = st;
|
||||
Server = sv;
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using SharedLibrary;
|
||||
using SharedLibrary.Helpers;
|
||||
@ -19,7 +18,8 @@ namespace StatsPlugin.Helpers
|
||||
private IManager Manager;
|
||||
private GenericRepository<EFClientStatistics> ClientStatSvc;
|
||||
private GenericRepository<EFServer> ServerSvc;
|
||||
private GenericRepository<EFClientKill> KillSvc;
|
||||
private GenericRepository<EFClientKill> KillStatsSvc;
|
||||
private GenericRepository<EFServerStatistics> ServerStatsSvc;
|
||||
|
||||
public StatManager(IManager mgr)
|
||||
{
|
||||
@ -28,13 +28,13 @@ namespace StatsPlugin.Helpers
|
||||
Manager = mgr;
|
||||
ClientStatSvc = new GenericRepository<EFClientStatistics>();
|
||||
ServerSvc = new GenericRepository<EFServer>();
|
||||
KillSvc = new GenericRepository<EFClientKill>();
|
||||
KillStatsSvc = new GenericRepository<EFClientKill>();
|
||||
ServerStatsSvc = new GenericRepository<EFServerStatistics>();
|
||||
}
|
||||
|
||||
~StatManager()
|
||||
{
|
||||
Servers.Clear();
|
||||
Log.WriteInfo("Cleared StatManager servers");
|
||||
Log = null;
|
||||
Servers = null;
|
||||
}
|
||||
@ -48,6 +48,7 @@ namespace StatsPlugin.Helpers
|
||||
try
|
||||
{
|
||||
int serverId = sv.GetHashCode();
|
||||
|
||||
// get the server from the database if it exists, otherwise create and insert a new one
|
||||
var server = ServerSvc.Find(c => c.ServerId == serverId).FirstOrDefault();
|
||||
if (server == null)
|
||||
@ -64,7 +65,13 @@ namespace StatsPlugin.Helpers
|
||||
|
||||
// this doesn't need to be async as it's during initialization
|
||||
ServerSvc.SaveChanges();
|
||||
Servers.Add(sv.GetHashCode(), new ServerStats(server));
|
||||
InitializeServerStats(sv);
|
||||
ServerStatsSvc.SaveChanges();
|
||||
|
||||
var serverStats = ServerStatsSvc.Find(c => c.ServerId == serverId).FirstOrDefault();
|
||||
// check to see if the stats have ever been initialized
|
||||
|
||||
Servers.Add(serverId, new ServerStats(server, serverStats));
|
||||
}
|
||||
|
||||
catch (Exception e)
|
||||
@ -102,6 +109,10 @@ namespace StatsPlugin.Helpers
|
||||
clientStats = ClientStatSvc.Insert(clientStats);
|
||||
}
|
||||
|
||||
// set these on connecting
|
||||
clientStats.LastActive = DateTime.UtcNow;
|
||||
clientStats.LastStatCalculation = DateTime.UtcNow;
|
||||
|
||||
lock (playerStats)
|
||||
{
|
||||
if (playerStats.ContainsKey(pl.ClientNumber))
|
||||
@ -123,17 +134,9 @@ namespace StatsPlugin.Helpers
|
||||
// remove the client from the stats dictionary as they're leaving
|
||||
lock (playerStats)
|
||||
playerStats.Remove(pl.ClientNumber);
|
||||
// allow accessing certain properties
|
||||
//clientStats.Client = pl;
|
||||
// update skill
|
||||
// clientStats = UpdateStats(clientStats);
|
||||
// reset for EF cache
|
||||
//clientStats.SessionDeaths = 0;
|
||||
// clientStats.SessionKills = 0;
|
||||
// prevent mismatched primary key
|
||||
//clientStats.Client = null;
|
||||
// update in database
|
||||
//await ClientStatSvc.SaveChangesAsync();
|
||||
|
||||
var serverStats = ServerStatsSvc.Find(sv => sv.ServerId == serverId).FirstOrDefault();
|
||||
serverStats.TotalPlayTime += (int)(DateTime.UtcNow - pl.LastConnection).TotalSeconds;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -160,18 +163,29 @@ namespace StatsPlugin.Helpers
|
||||
Weapon = ParseEnum<IW4Info.WeaponName>.Get(weapon, typeof(IW4Info.WeaponName))
|
||||
};
|
||||
|
||||
KillSvc.Insert(kill);
|
||||
await KillSvc.SaveChangesAsync();
|
||||
KillStatsSvc.Insert(kill);
|
||||
await KillStatsSvc.SaveChangesAsync();
|
||||
}
|
||||
|
||||
public void AddStandardKill(Player attacker, Player victim)
|
||||
{
|
||||
var attackerStats = Servers[attacker.CurrentServer.GetHashCode()].PlayerStats[attacker.ClientNumber];
|
||||
// set to access total time
|
||||
int serverId = attacker.CurrentServer.GetHashCode();
|
||||
var attackerStats = Servers[serverId].PlayerStats[attacker.ClientNumber];
|
||||
// set to access total time played
|
||||
attackerStats.Client = attacker;
|
||||
var victimStats = Servers[victim.CurrentServer.GetHashCode()].PlayerStats[victim.ClientNumber];
|
||||
var victimStats = Servers[serverId].PlayerStats[victim.ClientNumber];
|
||||
|
||||
// update the total stats
|
||||
Servers[serverId].ServerStatistics.TotalKills += 1;
|
||||
|
||||
// calculate for the clients
|
||||
CalculateKill(attackerStats, victimStats);
|
||||
|
||||
// immediately write changes in debug
|
||||
#if DEBUG
|
||||
ClientStatSvc.SaveChanges();
|
||||
ServerStatsSvc.SaveChanges();
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -195,10 +209,9 @@ namespace StatsPlugin.Helpers
|
||||
UpdateStats(attackerStats);
|
||||
attackerStats.Client = null;
|
||||
|
||||
// immediately write changes in debug
|
||||
#if DEBUG
|
||||
ClientStatSvc.SaveChanges();
|
||||
#endif
|
||||
// update after calculation
|
||||
attackerStats.LastActive = DateTime.UtcNow;
|
||||
victimStats.LastActive = DateTime.UtcNow;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -208,44 +221,83 @@ namespace StatsPlugin.Helpers
|
||||
/// <returns></returns>
|
||||
private EFClientStatistics UpdateStats(EFClientStatistics clientStats)
|
||||
{
|
||||
// if it's their first kill we need to set the last kill as the time they joined
|
||||
clientStats.LastStatCalculation = (clientStats.LastStatCalculation == DateTime.MinValue) ? DateTime.UtcNow : clientStats.LastStatCalculation;
|
||||
double timeSinceLastCalc = (DateTime.UtcNow - clientStats.LastStatCalculation).TotalSeconds / 60.0;
|
||||
double timeSinceLastActive = (DateTime.UtcNow - clientStats.LastActive).TotalSeconds / 60.0;
|
||||
|
||||
// each 'session' is one minute
|
||||
if (timeSinceLastCalc >= 1)
|
||||
{
|
||||
Log.WriteDebug($"Updated stats for {clientStats.ClientId} ({clientStats.SessionKills})");
|
||||
// calculate the players Score Per Minute for the current session
|
||||
// todo: score should be based on gamemode
|
||||
double killSPM = clientStats.SessionKills * 100.0;
|
||||
// prevent NaN or inactive time lowering SPM
|
||||
if (timeSinceLastCalc == 0 || timeSinceLastActive > 3)
|
||||
return clientStats;
|
||||
|
||||
// calculate how much the KDR should weigh
|
||||
// 1.637 is a Eddie-Generated number that weights the KDR nicely
|
||||
double KDRWeight = Math.Round(Math.Pow(clientStats.KDR, 1.637 / Math.E), 3);
|
||||
// calculate the players Score Per Minute for the current session
|
||||
int currentScore = Manager.GetActiveClients()
|
||||
.First(c => c.ClientId == clientStats.ClientId)
|
||||
.Score;
|
||||
double killSPM = currentScore / (timeSinceLastCalc * 60.0);
|
||||
|
||||
// if no SPM, weight is 1 else the weight ishe current session's spm / lifetime average score per minute
|
||||
double SPMWeightAgainstAverage = (clientStats.SPM < 1) ? 1 : killSPM / clientStats.SPM;
|
||||
// calculate how much the KDR should weigh
|
||||
// 1.637 is a Eddie-Generated number that weights the KDR nicely
|
||||
double KDRWeight = Math.Round(Math.Pow(clientStats.KDR, 1.637 / Math.E), 3);
|
||||
|
||||
// calculate the weight of the new play time against last 10 hours of gameplay
|
||||
int totalConnectionTime = (clientStats.Client.TotalConnectionTime == 0) ?
|
||||
(int)(DateTime.UtcNow - clientStats.Client.FirstConnection).TotalSeconds :
|
||||
clientStats.Client.TotalConnectionTime + (int)(DateTime.UtcNow - clientStats.Client.LastConnection).TotalSeconds;
|
||||
// if no SPM, weight is 1 else the weight ishe current session's spm / lifetime average score per minute
|
||||
double SPMWeightAgainstAverage = (clientStats.SPM < 1) ? 1 : killSPM / clientStats.SPM;
|
||||
|
||||
double SPMAgainstPlayWeight = timeSinceLastCalc / Math.Min(600, (totalConnectionTime / 60.0));
|
||||
// calculate the weight of the new play time against last 10 hours of gameplay
|
||||
int totalConnectionTime = (clientStats.Client.TotalConnectionTime == 0) ?
|
||||
(int)(DateTime.UtcNow - clientStats.Client.FirstConnection).TotalSeconds :
|
||||
clientStats.Client.TotalConnectionTime + (int)(DateTime.UtcNow - clientStats.Client.LastConnection).TotalSeconds;
|
||||
|
||||
// calculate the new weight against average times the weight against play time
|
||||
clientStats.SPM = (killSPM * SPMAgainstPlayWeight) + (clientStats.SPM * (1 - SPMAgainstPlayWeight));
|
||||
clientStats.SPM = Math.Round(clientStats.SPM, 3);
|
||||
clientStats.Skill = Math.Round((clientStats.SPM * KDRWeight) / 10.0, 3);
|
||||
double SPMAgainstPlayWeight = timeSinceLastCalc / Math.Min(600, (totalConnectionTime / 60.0));
|
||||
|
||||
clientStats.SessionKills = 0;
|
||||
clientStats.SessionDeaths = 0;
|
||||
// calculate the new weight against average times the weight against play time
|
||||
clientStats.SPM = (killSPM * SPMAgainstPlayWeight) + (clientStats.SPM * (1 - SPMAgainstPlayWeight));
|
||||
clientStats.SPM = Math.Round(clientStats.SPM, 3);
|
||||
clientStats.Skill = Math.Round((clientStats.SPM * KDRWeight), 3);
|
||||
|
||||
clientStats.LastStatCalculation = DateTime.UtcNow;
|
||||
}
|
||||
clientStats.LastStatCalculation = DateTime.UtcNow;
|
||||
clientStats.LastScore = currentScore;
|
||||
|
||||
return clientStats;
|
||||
}
|
||||
|
||||
public void InitializeServerStats(Server sv)
|
||||
{
|
||||
int serverId = sv.GetHashCode();
|
||||
var serverStats = ServerStatsSvc.Find(s => s.ServerId == serverId).FirstOrDefault();
|
||||
if (serverStats == null)
|
||||
{
|
||||
Log.WriteDebug($"Initializing server stats for {sv}");
|
||||
// server stats have never been generated before
|
||||
serverStats = new EFServerStatistics()
|
||||
{
|
||||
Active = true,
|
||||
ServerId = serverId,
|
||||
TotalKills = 0,
|
||||
TotalPlayTime = 0,
|
||||
};
|
||||
|
||||
var ieClientStats = ClientStatSvc.Find(cs => cs.ServerId == serverId);
|
||||
|
||||
// set these incase they've we've imported settings
|
||||
serverStats.TotalKills = ieClientStats.Sum(cs => cs.Kills);
|
||||
serverStats.TotalPlayTime = Manager.GetClientService().GetTotalPlayTime().Result;
|
||||
|
||||
ServerStatsSvc.Insert(serverStats);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task Sync()
|
||||
{
|
||||
Log.WriteDebug("Syncing server stats");
|
||||
await ServerStatsSvc.SaveChangesAsync();
|
||||
|
||||
Log.WriteDebug("Syncing client stats");
|
||||
await ClientStatSvc.SaveChangesAsync();
|
||||
|
||||
Log.WriteDebug("Syncing kill stats");
|
||||
await KillStatsSvc.SaveChangesAsync();
|
||||
|
||||
Log.WriteDebug("Syncing servers");
|
||||
await ServerSvc.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
37
Plugins/SimpleStats/Helpers/StreakMessage.cs
Normal file
37
Plugins/SimpleStats/Helpers/StreakMessage.cs
Normal file
@ -0,0 +1,37 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace StatsPlugin.Helpers
|
||||
{
|
||||
public class StreakMessage
|
||||
{
|
||||
public static string MessageOnStreak(int killStreak, int deathStreak)
|
||||
{
|
||||
String Message = "";
|
||||
switch (killStreak)
|
||||
{
|
||||
case 5:
|
||||
Message = "Great job! You're on a ^55 killstreak!";
|
||||
break;
|
||||
case 10:
|
||||
Message = "Amazing! ^510 kills ^7without dying!";
|
||||
break;
|
||||
}
|
||||
|
||||
switch (deathStreak)
|
||||
{
|
||||
case 5:
|
||||
Message = "Pick it up soldier, you've died ^55 times ^7in a row...";
|
||||
break;
|
||||
case 10:
|
||||
Message = "Seriously? ^510 deaths ^7without getting a kill?";
|
||||
break;
|
||||
}
|
||||
|
||||
return Message;
|
||||
}
|
||||
}
|
||||
}
|
@ -1333,7 +1333,8 @@ namespace StatsPlugin
|
||||
ak74u_silencer_thermal_mp,
|
||||
ak74u_silencer_xmags_mp,
|
||||
ak74u_thermal_xmags_mp,
|
||||
m40a3_mp = 1194,
|
||||
m16_reflex_silencer_mp,
|
||||
m40a3_mp,
|
||||
peacekeeper_mp,
|
||||
dragunov_mp,
|
||||
cobra_player_minigun_mp
|
||||
|
@ -45,5 +45,9 @@ namespace StatsPlugin.Models
|
||||
public int DeathStreak { get; set; }
|
||||
[NotMapped]
|
||||
public DateTime LastStatCalculation { get; set; }
|
||||
[NotMapped]
|
||||
public int LastScore { get; set; }
|
||||
[NotMapped]
|
||||
public DateTime LastActive { get; set; }
|
||||
}
|
||||
}
|
||||
|
17
Plugins/SimpleStats/Models/EFServerStatistics.cs
Normal file
17
Plugins/SimpleStats/Models/EFServerStatistics.cs
Normal file
@ -0,0 +1,17 @@
|
||||
using SharedLibrary.Database.Models;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace StatsPlugin.Models
|
||||
{
|
||||
public class EFServerStatistics : SharedEntity
|
||||
{
|
||||
[Key]
|
||||
public int StatisticId { get; set; }
|
||||
public int ServerId { get; set; }
|
||||
[ForeignKey("ServerId")]
|
||||
public virtual EFServer Server { get; set; }
|
||||
public long TotalKills { get; set; }
|
||||
public long TotalPlayTime { get; set; }
|
||||
}
|
||||
}
|
@ -5,8 +5,11 @@ using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using SharedLibrary;
|
||||
using SharedLibrary.Helpers;
|
||||
using SharedLibrary.Interfaces;
|
||||
using SharedLibrary.Services;
|
||||
using StatsPlugin.Helpers;
|
||||
using StatsPlugin.Models;
|
||||
|
||||
namespace StatsPlugin
|
||||
{
|
||||
@ -40,6 +43,7 @@ namespace StatsPlugin
|
||||
case Event.GType.MapChange:
|
||||
break;
|
||||
case Event.GType.MapEnd:
|
||||
await Manager.Sync();
|
||||
break;
|
||||
case Event.GType.Broadcast:
|
||||
break;
|
||||
@ -71,6 +75,27 @@ namespace StatsPlugin
|
||||
|
||||
public Task OnLoadAsync(IManager manager)
|
||||
{
|
||||
/*
|
||||
*
|
||||
ManagerInstance.GetMessageTokens().Add(new MessageToken("TOTALKILLS", GetTotalKills));
|
||||
ManagerInstance.GetMessageTokens().Add(new MessageToken("TOTALPLAYTIME", GetTotalPlaytime));
|
||||
*/
|
||||
string totalKills()
|
||||
{
|
||||
var serverStats = new GenericRepository<EFServerStatistics>();
|
||||
return serverStats.GetQuery(s => s.Active)
|
||||
.Sum(c => c.TotalKills).ToString();
|
||||
}
|
||||
|
||||
string totalPlayTime()
|
||||
{
|
||||
var serverStats = new GenericRepository<EFServerStatistics>();
|
||||
return serverStats.GetQuery(s => s.Active)
|
||||
.Sum(c => c.TotalPlayTime).ToString();
|
||||
}
|
||||
|
||||
manager.GetMessageTokens().Add(new MessageToken("TOTALKILLS", totalKills));
|
||||
manager.GetMessageTokens().Add(new MessageToken("TOTALPLAYTIME", totalPlayTime));
|
||||
return Task.FromResult(
|
||||
Manager = new StatManager(manager)
|
||||
);
|
||||
|
@ -72,11 +72,13 @@
|
||||
<None Include="Chat\ChatHistoryPage.cs" />
|
||||
<Compile Include="Helpers\ServerStats.cs" />
|
||||
<Compile Include="Helpers\StatManager.cs" />
|
||||
<Compile Include="Helpers\StreakMessage.cs" />
|
||||
<Compile Include="IW4Info.cs" />
|
||||
<Compile Include="MinimapConfig.cs" />
|
||||
<Compile Include="Models\EFClientKill.cs" />
|
||||
<Compile Include="Models\EFServer.cs" />
|
||||
<Compile Include="Models\EFClientStatistics.cs" />
|
||||
<Compile Include="Models\EFServerStatistics.cs" />
|
||||
<Compile Include="Plugin.cs" />
|
||||
<None Include="_Plugin.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
|
@ -744,7 +744,7 @@ namespace SharedLibrary.Commands
|
||||
E.Data = E.Data.RemoveWords(1);
|
||||
E.Owner.Reports.Add(new Report(E.Target, E.Origin, E.Data));
|
||||
|
||||
await E.Origin.Tell($"Thank you for your report, and administrator has been notified");
|
||||
await E.Origin.Tell($"Thank you for your report, an administrator has been notified");
|
||||
await E.Owner.ExecuteEvent(new Event(Event.GType.Report, E.Data, E.Origin, E.Target, E.Owner));
|
||||
await E.Owner.ToAdmins(String.Format("^5{0}^7->^1{1}^7: {2}", E.Origin.Name, E.Target.Name, E.Data));
|
||||
}
|
||||
|
@ -73,6 +73,8 @@ namespace SharedLibrary.Objects
|
||||
public DateTime ConnectionTime { get; set; }
|
||||
[NotMapped]
|
||||
public Server CurrentServer { get; set; }
|
||||
[NotMapped]
|
||||
public int Score { get; set; }
|
||||
|
||||
private string _ipaddress;
|
||||
public override string IPAddress
|
||||
|
@ -26,8 +26,8 @@ namespace SharedLibrary.Network
|
||||
|
||||
static string[] SendQuery(QueryType Type, Server QueryServer, string Parameters = "")
|
||||
{
|
||||
if ((DateTime.Now - LastQuery).TotalMilliseconds < 100)
|
||||
Task.Delay(100).Wait();
|
||||
if ((DateTime.Now - LastQuery).TotalMilliseconds < 300)
|
||||
Task.Delay(300).Wait();
|
||||
LastQuery = DateTime.Now;
|
||||
var ServerOOBConnection = new UdpClient();
|
||||
ServerOOBConnection.Client.SendTimeout = 1000;
|
||||
|
@ -233,6 +233,12 @@ namespace SharedLibrary.Services
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public async Task<int> GetTotalPlayTime()
|
||||
{
|
||||
using (var context = new DatabaseContext())
|
||||
return await context.Clients.SumAsync(c => c.TotalConnectionTime);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
@ -62,7 +62,9 @@ namespace SharedLibrary
|
||||
int.TryParse(playerInfo[0], out cID);
|
||||
var regex = Regex.Match(responseLine, @"\d+\.\d+\.\d+.\d+\:\d{1,5}");
|
||||
string cIP = regex.Value.Split(':')[0];
|
||||
Player P = new Player() { Name = cName, NetworkId = npID, ClientNumber = cID, IPAddress = cIP, Ping = Ping };
|
||||
regex = Regex.Match(responseLine, @"[0-9]{1,2}\s+[0-9]+\s+");
|
||||
int score = Int32.Parse(regex.Value.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)[1]);
|
||||
Player P = new Player() { Name = cName, NetworkId = npID, ClientNumber = cID, IPAddress = cIP, Ping = Ping, Score = score};
|
||||
StatusPlayers.Add(P);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user