using SharedLibrary;
using SharedLibrary.Helpers;
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using SharedLibrary.Objects;
using System.Linq;
using StatsPlugin.Models;
namespace StatsPlugin
{
///
/// Each server runs from the same plugin ( for easier reloading and reduced memory usage ).
/// So, to have multiple stat tracking, we must store a stat struct for each server
///
public class Stats : SharedLibrary.Interfaces.IPlugin
{
public static SharedLibrary.Interfaces.IManager ManagerInstance;
public static int MAX_KILLEVENTS = 1000;
public static Dictionary ServerStats { get; private set; }
public static SharedLibrary.Services.GenericService ClientStatsSvc;
public static SharedLibrary.Services.GenericService ServerSvc;
public class ServerStatInfo
{
public ServerStatInfo()
{
KillQueue = new Queue();
ServerStartTime = DateTime.Now;
}
public DateTime ServerStartTime { get; private set; }
public DateTime RoundStartTime { get; set; }
public string Uptime => Utilities.GetTimePassed(ServerStartTime, false);
public string ElapsedRoundTime => Utilities.GetTimePassed(RoundStartTime);
private Queue KillQueue { get; set; }
public Queue GetKillQueue() { return KillQueue; }
}
public string Name => "Basic Stats";
public float Version => 1.1f;
public string Author => "RaidMax";
public async Task OnLoadAsync(SharedLibrary.Interfaces.IManager manager)
{
statLists = new List();
ServerStats = new Dictionary();
ManagerInstance = manager;
WebService.PageList.Add(new StatsPage());
WebService.PageList.Add(new KillStatsJSON());
WebService.PageList.Add(new Chat.WordCloudJSON());
WebService.PageList.Add(new Chat.ClientChatJSON());
WebService.PageList.Add(new Chat.ChatPage());
ManagerInstance.GetMessageTokens().Add(new MessageToken("TOTALKILLS", GetTotalKills));
ManagerInstance.GetMessageTokens().Add(new MessageToken("TOTALPLAYTIME", GetTotalPlaytime));
ClientStatsSvc = new SharedLibrary.Services.GenericService();
ServerSvc = new SharedLibrary.Services.GenericService()
ChatDB = new ChatDatabase("Database/ChatHistory.rm", ManagerInstance.GetLogger());
try
{
var minimapConfig = MinimapConfig.Read("Config/minimaps.cfg");
}
catch (SharedLibrary.Exceptions.SerializeException e)
{
MinimapConfig.Write("Config/minimaps.cfg", MinimapConfig.IW4Minimaps());
}
}
public async Task OnUnloadAsync()
{
statLists.Clear();
}
public async Task OnTickAsync(Server S)
{
return;
}
public async Task OnEventAsync(Event E, Server S)
{
try
{
if (E.Type == Event.GType.Start)
{
statLists.Add(new StatTracking(S.GetPort()));
ServerStats.Add(S.GetPort(), new ServerStatInfo());
var config = new ConfigurationManager(S);
if (config.GetProperty("EnableTrusted") == null)
config.AddProperty(new KeyValuePair("EnableTrusted", true));
}
if (E.Type == Event.GType.Stop)
{
statLists.RemoveAll(s => s.Port == S.GetPort());
ServerStats.Remove(S.GetPort());
}
if (E.Type == Event.GType.Connect)
{
ResetCounters(E.Origin.ClientNumber, S.GetPort());
var serverStats = statLists.First(s => s.Port == E.Owner.GetPort());
var clientStats = await ClientStatsSvc.Get(new int[] { E.Origin.ClientNumber });
var server = (await ServerSvc.Find(s => s.Port == E.Owner.GetPort())).First();
// create stats if not exist already
serverStats.clientStats[E.Origin.ClientNumber] = clientStats ?? await ClientStatsSvc.Create(new Models.EFClientStatistics()
{
Active = false,
Client = E.Target,
ClientId = E.Target.ClientId,
Deaths = 0,
KDR = 0,
Kills = 0,
Server = (await ServerSvc.Find(s => s.Port == E.Owner.GetPort())).First(),
ServerId = server.ServerId,
Skill = 0,
SPM = 0,
});
/* var config = new ConfigurationManager(E.Owner);
if (!(bool)config.GetProperty("EnableTrusted"))
return;
PlayerStats checkForTrusted = statLists.Find(x => x.Port == S.GetPort()).playerStats.GetStats(E.Origin);
//todo: move this out of here!!
if (checkForTrusted.TotalPlayTime >= 4320 && E.Origin.Level < Player.Permission.Trusted && E.Origin.Level != Player.Permission.Flagged)
{
E.Origin.Level = Player.Permission.Trusted;
await E.Owner.Manager.GetDatabase().UpdateClient(E.Origin);
await E.Origin.Tell("Congratulations, you are now a ^5trusted ^7player! Type ^5!help ^7to view new commands.");
await E.Origin.Tell("You earned this by playing for ^53 ^7full days!");
}*/
}
if (E.Type == Event.GType.MapEnd || E.Type == Event.GType.Stop)
{
foreach (Player P in S.GetPlayersAsList())
{
if (P == null)
continue;
CalculateAndSaveSkill(P, statLists.Find(x => x.Port == S.GetPort()));
ResetCounters(P.ClientNumber, S.GetPort());
E.Owner.Logger.WriteInfo($"Updated skill for {P}");
//E.Owner.Log.Write(String.Format("\r\nJoin: {0}\r\nInactive Minutes: {1}\r\nnewPlayTime: {2}\r\nnewSPM: {3}\r\nkdrWeight: {4}\r\nMultiplier: {5}\r\nscoreWeight: {6}\r\nnewSkillFactor: {7}\r\nprojectedNewSkill: {8}\r\nKills: {9}\r\nDeaths: {10}", connectionTime[P.ClientNumber].ToShortTimeString(), inactiveMinutes[P.ClientNumber], newPlayTime, newSPM, kdrWeight, Multiplier, scoreWeight, newSkillFactor, disconnectStats.Skill, disconnectStats.Kills, disconnectStats.Deaths));
}
}
if (E.Type == Event.GType.MapChange)
{
ServerStats[S.GetPort()].GetKillQueue().Clear();
ServerStats[S.GetPort()].RoundStartTime = DateTime.Now;
}
}
}