added 'none' and extra m16 variants to weapon list

moved killstreak/deathstreak messages into configuration file
cleaned up configuration manager
fixed misc startup issue and threading
added more importing stuff
network id is a ulong now
ip str is now ip
added time played (per server)
This commit is contained in:
RaidMax 2018-02-10 22:33:42 -06:00
parent d331d998c0
commit 1dbacd2188
33 changed files with 418 additions and 213 deletions

View File

@ -207,6 +207,12 @@ namespace IW4MAdmin
if (Status.RunAverage > 1000 + UPDATE_FREQUENCY) if (Status.RunAverage > 1000 + UPDATE_FREQUENCY)
Logger.WriteWarning($"Update task average execution is longer than desired for {(Status.Dependant as Server)} [{Status.RunAverage}ms]"); Logger.WriteWarning($"Update task average execution is longer than desired for {(Status.Dependant as Server)} [{Status.RunAverage}ms]");
} }
if (Status.RequestedTask.Status == TaskStatus.Faulted)
{
Logger.WriteWarning($"Update task for {(Status.Dependant as Server)} faulted, restarting");
Status.Abort();
}
} }
Thread.Sleep(UPDATE_FREQUENCY); Thread.Sleep(UPDATE_FREQUENCY);

View File

@ -380,6 +380,7 @@ namespace IW4MAdmin
DateTime playerCountStart = DateTime.Now; DateTime playerCountStart = DateTime.Now;
DateTime lastCount = DateTime.Now; DateTime lastCount = DateTime.Now;
DateTime tickTime = DateTime.Now; DateTime tickTime = DateTime.Now;
bool firstRun = true;
override public async Task<bool> ProcessUpdatesAsync(CancellationToken cts) override public async Task<bool> ProcessUpdatesAsync(CancellationToken cts)
{ {
@ -388,6 +389,13 @@ namespace IW4MAdmin
try try
#endif #endif
{ {
// first start
if (firstRun)
{
await ExecuteEvent(new Event(Event.GType.Start, "Server started", null, null, this));
firstRun = false;
}
if ((DateTime.Now - LastPoll).TotalMinutes < 2 && ConnectionErrors >= 1) if ((DateTime.Now - LastPoll).TotalMinutes < 2 && ConnectionErrors >= 1)
return true; return true;
@ -596,7 +604,6 @@ namespace IW4MAdmin
LogFile = new RemoteFile("https://raidmax.org/IW4MAdmin/getlog.php"); LogFile = new RemoteFile("https://raidmax.org/IW4MAdmin/getlog.php");
#endif #endif
Logger.WriteInfo("Log file is " + logPath); Logger.WriteInfo("Log file is " + logPath);
await ExecuteEvent(new Event(Event.GType.Start, "Server started", null, null, this));
#if !DEBUG #if !DEBUG
Broadcast("IW4M Admin is now ^2ONLINE"); Broadcast("IW4M Admin is now ^2ONLINE");
#endif #endif
@ -617,13 +624,13 @@ namespace IW4MAdmin
else if (E.Type == Event.GType.Script) else if (E.Type == Event.GType.Script)
{ {
if (E.Origin == E.Target)// suicide/falling /* if (E.Origin == E.Target)// suicide/falling
await ExecuteEvent(new Event(Event.GType.Death, E.Data, E.Target, E.Target, this)); await ExecuteEvent(new Event(Event.GType.Death, E.Data, E.Target, E.Target, this));
else else
{ {*/
await ExecuteEvent(new Event(Event.GType.Kill, E.Data, E.Origin, E.Target, this)); await ExecuteEvent(new Event(Event.GType.Kill, E.Data, E.Origin, E.Target, this));
await ExecuteEvent(new Event(Event.GType.Death, E.Data, E.Target, E.Origin, this)); //await ExecuteEvent(new Event(Event.GType.Death, E.Data, E.Target, E.Origin, this));
} // }
} }
if (E.Type == Event.GType.Say && E.Data.Length >= 2) if (E.Type == Event.GType.Say && E.Data.Length >= 2)
@ -806,7 +813,7 @@ namespace IW4MAdmin
} }
else else
await Target.CurrentServer.ExecuteCommandAsync($"clientkick {Target.ClientNumber } \"^1Player Temporarily Banned: ^5{ Reason }\""); await Target.CurrentServer.ExecuteCommandAsync($"clientkick {Target.ClientNumber } \"^7Player Temporarily Banned: ^5{ Reason }\"");
#if DEBUG #if DEBUG
await Target.CurrentServer.RemovePlayer(Target.ClientNumber); await Target.CurrentServer.RemovePlayer(Target.ClientNumber);

View File

@ -232,7 +232,7 @@ namespace IW4MAdmin
bool authed = querySet["IP"] == "127.0.0.1" bool authed = querySet["IP"] == "127.0.0.1"
|| (await (ApplicationManager.GetInstance().GetClientService() as ClientService).GetPrivilegedClients()) || (await (ApplicationManager.GetInstance().GetClientService() as ClientService).GetPrivilegedClients())
.Where(x => x.IPAddress == querySet["IP"]) .Where(x => x.IPAddress == querySet["IP"].ConvertToIP())
.Where(x => x.Level > Player.Permission.Trusted).Count() > 0; .Where(x => x.Level > Player.Permission.Trusted).Count() > 0;
@ -384,7 +384,7 @@ namespace IW4MAdmin
if (S != null) if (S != null)
{ {
// fixme // fixme
Func<EFClient, bool> predicate = c => c.IPAddress == querySet["IP"]; Func<EFClient, bool> predicate = c => c.IPAddress == querySet["IP"].ConvertToIP();
Player admin = (await ApplicationManager.GetInstance().GetClientService().Find(predicate)).FirstOrDefault()?.AsPlayer(); Player admin = (await ApplicationManager.GetInstance().GetClientService().Find(predicate)).FirstOrDefault()?.AsPlayer();
if (admin == null) if (admin == null)
@ -752,7 +752,7 @@ namespace IW4MAdmin
contentType = GetContentType(), contentType = GetContentType(),
additionalHeaders = new Dictionary<string, string>() additionalHeaders = new Dictionary<string, string>()
}; };
Func<EFClient, bool> predicate = c => c.IPAddress == querySet["IP"] && c.Level > Player.Permission.Trusted; Func<EFClient, bool> predicate = c => c.IPAddress == querySet["IP"].ConvertToIP() && c.Level > Player.Permission.Trusted;
bool authed = (await ApplicationManager.GetInstance().GetClientService().Find(predicate)).Count > 0 bool authed = (await ApplicationManager.GetInstance().GetClientService().Find(predicate)).Count > 0
|| querySet["IP"] == "127.0.0.1"; || querySet["IP"] == "127.0.0.1";
bool recent = false; bool recent = false;
@ -765,7 +765,7 @@ namespace IW4MAdmin
else if (querySet["npID"] != null) else if (querySet["npID"] != null)
{ {
matchedPlayers.Add(await ApplicationManager.GetInstance().GetClientService().GetUnique(querySet["npID"])); matchedPlayers.Add(await ApplicationManager.GetInstance().GetClientService().GetUnique(querySet["npID"].ConvertLong()));
} }
else if (querySet["name"] != null) else if (querySet["name"] != null)
@ -793,11 +793,11 @@ namespace IW4MAdmin
PlayerInfo eachPlayer = new PlayerInfo() PlayerInfo eachPlayer = new PlayerInfo()
{ {
playerIP = pp.IPAddress, playerIP = pp.IPAddressString,
playerID = pp.ClientId, playerID = pp.ClientId,
playerLevel = pp.Level.ToString(), playerLevel = pp.Level.ToString(),
playerName = pp.Name, playerName = pp.Name,
playernpID = pp.NetworkId, playernpID = pp.NetworkId.ToString(),
forumID = -1, forumID = -1,
authed = authed, authed = authed,
showV2Features = false, showV2Features = false,
@ -815,7 +815,7 @@ namespace IW4MAdmin
if (authed) if (authed)
eachPlayer.playerIPs = pp.AliasLink.Children eachPlayer.playerIPs = pp.AliasLink.Children
.Select(a => a.IPAddress) .Select(a => a.IPAddress.ConvertIPtoString())
.Distinct() .Distinct()
.ToList(); .ToList();
} }

Binary file not shown.

View File

@ -15,13 +15,16 @@ namespace StatsPlugin.Helpers
{ {
private Dictionary<int, ServerStats> Servers; private Dictionary<int, ServerStats> Servers;
private Dictionary<int, ThreadSafeStatsService> ContextThreads; private Dictionary<int, ThreadSafeStatsService> ContextThreads;
private Dictionary<int, StreakMessage> StreakMessages;
private ILogger Log; private ILogger Log;
private IManager Manager; private IManager Manager;
public StatManager(IManager mgr) public StatManager(IManager mgr)
{ {
Servers = new Dictionary<int, ServerStats>(); Servers = new Dictionary<int, ServerStats>();
ContextThreads = new Dictionary<int, ThreadSafeStatsService>(); ContextThreads = new Dictionary<int, ThreadSafeStatsService>();
StreakMessages= new Dictionary<int, StreakMessage>();
Log = mgr.GetLogger(); Log = mgr.GetLogger();
Manager = mgr; Manager = mgr;
} }
@ -44,6 +47,7 @@ namespace StatsPlugin.Helpers
int serverId = sv.GetHashCode(); int serverId = sv.GetHashCode();
var statsSvc = new ThreadSafeStatsService(); var statsSvc = new ThreadSafeStatsService();
ContextThreads.Add(serverId, statsSvc); ContextThreads.Add(serverId, statsSvc);
StreakMessages.Add(serverId, new StreakMessage(sv));
// get the server from the database if it exists, otherwise create and insert a new one // get the server from the database if it exists, otherwise create and insert a new one
var server = statsSvc.ServerSvc.Find(c => c.ServerId == serverId).FirstOrDefault(); var server = statsSvc.ServerSvc.Find(c => c.ServerId == serverId).FirstOrDefault();
@ -157,7 +161,7 @@ namespace StatsPlugin.Helpers
public async Task AddScriptKill(Player attacker, Player victim, int serverId, string map, string hitLoc, string type, public async Task AddScriptKill(Player attacker, Player victim, int serverId, string map, string hitLoc, string type,
string damage, string weapon, string killOrigin, string deathOrigin) string damage, string weapon, string killOrigin, string deathOrigin)
{ {
AddStandardKill(attacker, victim); await AddStandardKill(attacker, victim);
var statsSvc = ContextThreads[serverId]; var statsSvc = ContextThreads[serverId];
@ -180,12 +184,19 @@ namespace StatsPlugin.Helpers
await statsSvc.KillStatsSvc.SaveChangesAsync(); await statsSvc.KillStatsSvc.SaveChangesAsync();
} }
public void AddStandardKill(Player attacker, Player victim) public async Task AddStandardKill(Player attacker, Player victim)
{ {
int serverId = attacker.CurrentServer.GetHashCode(); int serverId = attacker.CurrentServer.GetHashCode();
var attackerStats = Servers[serverId].PlayerStats[attacker.ClientNumber]; var attackerStats = Servers[serverId].PlayerStats[attacker.ClientNumber];
// set to access total time played // set to access total time played
attackerStats.Client = attacker; attackerStats.Client = attacker;
if (victim == null)
{
Log.WriteError($"Stats: Victim is null");
return;
}
var victimStats = Servers[serverId].PlayerStats[victim.ClientNumber]; var victimStats = Servers[serverId].PlayerStats[victim.ClientNumber];
// update the total stats // update the total stats
@ -194,6 +205,15 @@ namespace StatsPlugin.Helpers
// calculate for the clients // calculate for the clients
CalculateKill(attackerStats, victimStats); CalculateKill(attackerStats, victimStats);
// show encouragement/discouragement
var streakMessageGen = StreakMessages[serverId];
string streakMessage = (attackerStats.ClientId != victimStats.ClientId) ?
streakMessageGen.MessageOnStreak(attackerStats.KillStreak, attackerStats.DeathStreak) :
streakMessageGen.MessageOnStreak(-1, -1);
if (streakMessage != string.Empty)
await attacker.Tell(streakMessage);
// immediately write changes in debug // immediately write changes in debug
#if DEBUG #if DEBUG
var statsSvc = ContextThreads[serverId]; var statsSvc = ContextThreads[serverId];
@ -208,11 +228,17 @@ namespace StatsPlugin.Helpers
/// <param name="attackerStats">Stats of the attacker</param> /// <param name="attackerStats">Stats of the attacker</param>
/// <param name="victimStats">Stats of the victim</param> /// <param name="victimStats">Stats of the victim</param>
public void CalculateKill(EFClientStatistics attackerStats, EFClientStatistics victimStats) public void CalculateKill(EFClientStatistics attackerStats, EFClientStatistics victimStats)
{
bool suicide = attackerStats.ClientId == victimStats.ClientId;
// only update their kills if they didn't kill themselves
if (!suicide)
{ {
attackerStats.Kills += 1; attackerStats.Kills += 1;
attackerStats.SessionKills += 1; attackerStats.SessionKills += 1;
attackerStats.KillStreak += 1; attackerStats.KillStreak += 1;
attackerStats.DeathStreak = 0; attackerStats.DeathStreak = 0;
}
victimStats.Deaths += 1; victimStats.Deaths += 1;
victimStats.SessionDeaths += 1; victimStats.SessionDeaths += 1;
@ -224,6 +250,8 @@ namespace StatsPlugin.Helpers
attackerStats.Client = null; attackerStats.Client = null;
// update after calculation // update after calculation
attackerStats.TimePlayed += (int)(DateTime.UtcNow - attackerStats.LastActive).TotalSeconds;
victimStats.TimePlayed += (int)(DateTime.UtcNow - victimStats.LastActive).TotalSeconds;
attackerStats.LastActive = DateTime.UtcNow; attackerStats.LastActive = DateTime.UtcNow;
victimStats.LastActive = DateTime.UtcNow; victimStats.LastActive = DateTime.UtcNow;
} }

View File

@ -1,4 +1,6 @@
using System; using SharedLibrary;
using SharedLibrary.Helpers;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
@ -8,30 +10,55 @@ namespace StatsPlugin.Helpers
{ {
public class StreakMessage public class StreakMessage
{ {
public static string MessageOnStreak(int killStreak, int deathStreak) private ConfigurationManager config;
public StreakMessage(Server sv)
{ {
String Message = ""; config = new ConfigurationManager(sv);
switch (killStreak)
// initialize default messages
if (config.GetProperty<Dictionary<int, string>>("KillstreakMessages") == null)
{ {
case 5: var killstreakMessages = new Dictionary<int, string>()
Message = "Great job! You're on a ^55 killstreak!"; {
break; { -1, "Try not to kill yourself anymore" },
case 10: { 5, "Great job! You're on a ^55 killstreak!" },
Message = "Amazing! ^510 kills ^7without dying!"; { 10, "Amazing! ^510 kills ^7without dying!" },
break; { 25, "You better call in that nuke, ^525 killstreak!" }
};
config.AddProperty(new KeyValuePair<string, object>("KillstreakMessages", killstreakMessages));
} }
switch (deathStreak) if (config.GetProperty<Dictionary<int, string>>("DeathstreakMessages") == null)
{ {
case 5: var deathstreakMessages = new Dictionary<int, string>()
Message = "Pick it up soldier, you've died ^55 times ^7in a row..."; {
break; { 5, "Pick it up soldier, you've died ^55 times ^7in a row..." },
case 10: { 10, "Seriously? ^510 deaths ^7without getting a kill?" },
Message = "Seriously? ^510 deaths ^7without getting a kill?"; };
break; config.AddProperty(new KeyValuePair<string, object>("DeathstreakMessages", deathstreakMessages));
}
} }
return Message; /// <summary>
/// Get a message from the configuration encouraging or discouraging clients
/// </summary>
/// <param name="killStreak">how many kills the client has without dying</param>
/// <param name="deathStreak">how many deaths the client has without getting a kill</param>
/// <returns>message to send to the client</returns>
public string MessageOnStreak(int killStreak, int deathStreak)
{
var killstreakMessage = config.GetProperty<Dictionary<int, string>>("KillstreakMessages");
var deathstreakMessage = config.GetProperty<Dictionary<int, string>>("DeathstreakMessages");
string message = "";
if (killstreakMessage.ContainsKey(killStreak))
message =killstreakMessage[killStreak];
else if (deathstreakMessage.ContainsKey(deathStreak))
message = deathstreakMessage[deathStreak];
return message;
} }
} }
} }

View File

@ -60,6 +60,7 @@ namespace StatsPlugin
public enum WeaponName public enum WeaponName
{ {
none = 0,
defaultweapon_mp = 1, defaultweapon_mp = 1,
riotshield_mp = 2, riotshield_mp = 2,
beretta_mp = 3, beretta_mp = 3,
@ -1333,7 +1334,27 @@ namespace StatsPlugin
ak74u_silencer_thermal_mp, ak74u_silencer_thermal_mp,
ak74u_silencer_xmags_mp, ak74u_silencer_xmags_mp,
ak74u_thermal_xmags_mp, ak74u_thermal_xmags_mp,
m16_fmj_thermal_mp,
m16_fmj_xmags_mp,
m16_gl_heartbeat_mp,
m16_gl_reflex_mp,
m16_gl_silencer_mp,
m16_gl_thermal_mp,
m16_gl_xmags_mp,
m16_reflex_silencer_mp, m16_reflex_silencer_mp,
m16_heartbeat_reflex_mp,
m16_heartbeat_shotgun_mp,
m16_heartbeat_silencer_mp,
m16_heartbeat_thermal_mp,
m16_heartbeat_xmags_mp,
m16_reflex_shotgun_mp,
m16_reflex_xmags_mp,
m16_shotgun_silencer_mp,
m16_shotgun_thermal_mp,
m16_shotgun_xmags_mp,
m16_silencer_thermal_mp,
m16_silencer_xmags_mp,
m16_thermal_xmags_mp,
m40a3_mp, m40a3_mp,
peacekeeper_mp, peacekeeper_mp,
dragunov_mp, dragunov_mp,

View File

@ -28,12 +28,14 @@ namespace StatsPlugin.Models
[NotMapped] [NotMapped]
public double KDR public double KDR
{ {
get => Deaths == 0 ? Kills : Math.Round((float)Kills / (float)Deaths, 2); get => Deaths == 0 ? Kills : Math.Round(Kills / (double)Deaths, 2);
} }
[Required] [Required]
public double SPM { get; set; } public double SPM { get; set; }
[Required] [Required]
public double Skill { get; set; } public double Skill { get; set; }
[Required]
public int TimePlayed { get; set; }
[NotMapped] [NotMapped]
public int SessionKills { get; set; } public int SessionKills { get; set; }

View File

@ -10,6 +10,8 @@ namespace StatsPlugin.Pages
{ {
public class ClientMessages : HTMLPage public class ClientMessages : HTMLPage
{ {
public ClientMessages() : base(false) { }
public override string GetContent(NameValueCollection querySet, IDictionary<string, string> headers) public override string GetContent(NameValueCollection querySet, IDictionary<string, string> headers)
{ {
StringBuilder S = new StringBuilder(); StringBuilder S = new StringBuilder();

View File

@ -10,6 +10,8 @@ namespace StatsPlugin.Pages
{ {
public class LiveStats : HTMLPage public class LiveStats : HTMLPage
{ {
public LiveStats() : base(false) { }
public override string GetContent(NameValueCollection querySet, IDictionary<string, string> headers) public override string GetContent(NameValueCollection querySet, IDictionary<string, string> headers)
{ {
StringBuilder S = new StringBuilder(); StringBuilder S = new StringBuilder();

View File

@ -71,6 +71,8 @@ namespace StatsPlugin
string[] killInfo = (E.Data != null) ? E.Data.Split(';') : new string[0]; string[] killInfo = (E.Data != null) ? E.Data.Split(';') : new string[0];
if (killInfo.Length >= 9 && killInfo[0].Contains("ScriptKill")) if (killInfo.Length >= 9 && killInfo[0].Contains("ScriptKill"))
await Manager.AddScriptKill(E.Origin, E.Target, S.GetHashCode(), S.CurrentMap.Name, killInfo[7], killInfo[8], killInfo[5], killInfo[6], killInfo[3], killInfo[4]); await Manager.AddScriptKill(E.Origin, E.Target, S.GetHashCode(), S.CurrentMap.Name, killInfo[7], killInfo[8], killInfo[5], killInfo[6], killInfo[3], killInfo[4]);
else
await Manager.AddStandardKill(E.Origin, E.Target);
break; break;
case Event.GType.Death: case Event.GType.Death:
break; break;
@ -84,14 +86,14 @@ namespace StatsPlugin
{ {
var serverStats = new GenericRepository<EFServerStatistics>(); var serverStats = new GenericRepository<EFServerStatistics>();
return serverStats.Find(s => s.Active) return serverStats.Find(s => s.Active)
.Sum(c => c.TotalKills).ToString(); .Sum(c => c.TotalKills).ToString("#,##0");
} }
string totalPlayTime() string totalPlayTime()
{ {
var serverStats = new GenericRepository<EFServerStatistics>(); var serverStats = new GenericRepository<EFServerStatistics>();
return serverStats.GetQuery(s => s.Active) return Math.Ceiling((serverStats.GetQuery(s => s.Active)
.Sum(c => c.TotalPlayTime).ToString(); .Sum(c => c.TotalPlayTime) / 3600.0)).ToString("#,##0");
} }
manager.GetMessageTokens().Add(new MessageToken("TOTALKILLS", totalKills)); manager.GetMessageTokens().Add(new MessageToken("TOTALKILLS", totalKills));

View File

@ -66,7 +66,7 @@ namespace StatsPlugin
ManagerInstance.GetMessageTokens().Add(new MessageToken("TOTALPLAYTIME", GetTotalPlaytime)); ManagerInstance.GetMessageTokens().Add(new MessageToken("TOTALPLAYTIME", GetTotalPlaytime));
ClientStatsSvc = new SharedLibrary.Services.GenericService<Models.EFClientStatistics>(); ClientStatsSvc = new SharedLibrary.Services.GenericService<Models.EFClientStatistics>();
ServerSvc = new SharedLibrary.Services.GenericService<Models.EFServer>() ServerSvc = new SharedLibrary.Services.GenericService<Models.EFServer>();
ChatDB = new ChatDatabase("Database/ChatHistory.rm", ManagerInstance.GetLogger()); ChatDB = new ChatDatabase("Database/ChatHistory.rm", ManagerInstance.GetLogger());

View File

@ -11,6 +11,7 @@ using SharedLibrary.Interfaces;
using SharedLibrary.Helpers; using SharedLibrary.Helpers;
using SharedLibrary.Objects; using SharedLibrary.Objects;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using StatsPlugin.Models;
namespace IW4MAdmin.Plugins namespace IW4MAdmin.Plugins
{ {
@ -59,10 +60,11 @@ namespace IW4MAdmin.Plugins
public async Task OnLoadAsync(IManager manager) public async Task OnLoadAsync(IManager manager)
{ {
Interval = DateTime.Now; Interval = DateTime.Now;
var clients = new List<Player>();
var oldClients = new Dictionary<int, Player>();
#region CLIENTS #region CLIENTS
if (File.Exists("import_clients.csv")) if (File.Exists("import_clients.csv"))
{ {
var clients = new List<Player>();
manager.GetLogger().WriteVerbose("Beginning import of existing clients"); manager.GetLogger().WriteVerbose("Beginning import of existing clients");
var lines = File.ReadAllLines("import_clients.csv").Skip(1); var lines = File.ReadAllLines("import_clients.csv").Skip(1);
@ -81,34 +83,38 @@ namespace IW4MAdmin.Plugins
return; return;
} }
if (fields[1].Contains("0110") || fields[0] == string.Empty || fields[1] == string.Empty || fields[6] == string.Empty) if (fields[1].Substring(0, 5) == "01100" || fields[0] == string.Empty || fields[1] == string.Empty || fields[6] == string.Empty)
continue; continue;
if (!Regex.Match(fields[6], @"^\d+\.\d+\.\d+.\d+$").Success) if (!Regex.Match(fields[6], @"^\d+\.\d+\.\d+.\d+$").Success)
continue; fields[6] = "0";
var client = new Player() var client = new Player()
{ {
// for link
ClientId = Convert.ToInt32(fields[2]),
Name = fields[0], Name = fields[0],
NetworkId = fields[1], NetworkId = fields[1].Trim().ConvertLong(),
IPAddress = fields[6], IPAddress = fields[6].ConvertToIP(),
Level = (Player.Permission)Convert.ToInt32(fields[3]), Level = (Player.Permission)Convert.ToInt32(fields[3]),
Connections = Convert.ToInt32(fields[5]), Connections = Convert.ToInt32(fields[5]),
LastConnection = DateTime.Parse(fields[7]), LastConnection = DateTime.Parse(fields[7]),
}; };
clients.Add(client); clients.Add(client);
oldClients.Add(client.ClientId, client);
} }
//#if DO_IMPORT
clients = clients clients = clients.Distinct().ToList();
.GroupBy(c => c.NetworkId, (key, c) => c.FirstOrDefault())
.ToList();
clients = clients clients = clients
.GroupBy(c => new { c.Name, c.IPAddress }) .GroupBy(c => new { c.Name, c.IPAddress })
.Select(c => c.FirstOrDefault()) .Select(c => c.FirstOrDefault())
.ToList(); .ToList();
//newClients = clients.ToList();
//newClients.ForEach(c => c.ClientId = 0);
manager.GetLogger().WriteVerbose($"Read {clients.Count} clients for import"); manager.GetLogger().WriteVerbose($"Read {clients.Count} clients for import");
try try
@ -116,10 +122,11 @@ namespace IW4MAdmin.Plugins
SharedLibrary.Database.Importer.ImportClients(clients); SharedLibrary.Database.Importer.ImportClients(clients);
} }
catch(Exception e) catch (Exception e)
{ {
manager.GetLogger().WriteError("Saving imported clients failed"); manager.GetLogger().WriteError("Saving imported clients failed");
} }
//#endif
} }
#endregion #endregion
#region PENALTIES #region PENALTIES
@ -144,7 +151,7 @@ namespace IW4MAdmin.Plugins
return; return;
} }
if (fields[2].Contains("0110") || fields[2].Contains("0000000") || fields.Any(p => p == string.Empty)) if (fields[2].Contains("0110") || fields[2].Contains("0000000"))
continue; continue;
try try
{ {
@ -156,8 +163,8 @@ namespace IW4MAdmin.Plugins
{ {
Type = (Penalty.PenaltyType)Int32.Parse(fields[0]), Type = (Penalty.PenaltyType)Int32.Parse(fields[0]),
Expires = expires == DateTime.MinValue ? when : expires, Expires = expires == DateTime.MinValue ? when : expires,
Punisher = new SharedLibrary.Database.Models.EFClient() { NetworkId = fields[3]}, Punisher = new SharedLibrary.Database.Models.EFClient() { NetworkId = fields[3].ConvertLong() },
Offender = new SharedLibrary.Database.Models.EFClient() { NetworkId = fields[2]}, Offender = new SharedLibrary.Database.Models.EFClient() { NetworkId = fields[2].ConvertLong() },
Offense = fields[1], Offense = fields[1],
Active = true, Active = true,
When = when, When = when,
@ -172,15 +179,133 @@ namespace IW4MAdmin.Plugins
manager.GetLogger().WriteVerbose($"Could not import penalty with line {line}"); manager.GetLogger().WriteVerbose($"Could not import penalty with line {line}");
} }
} }
//#if DO_IMPORT
SharedLibrary.Database.Importer.ImportPenalties(penalties); SharedLibrary.Database.Importer.ImportPenalties(penalties);
manager.GetLogger().WriteVerbose($"Imported {penalties.Count} penalties"); manager.GetLogger().WriteVerbose($"Imported {penalties.Count} penalties");
//#endif
}
#endregion
#region CHATHISTORY
// load the entire database lol
var cls = manager.GetClientService().Find(c => c.Active).Result;
if (File.Exists("import_chathistory.csv"))
{
var chatHistory = new List<EFClientMessage>();
manager.GetLogger().WriteVerbose("Beginning import of existing messages");
foreach (string line in File.ReadAllLines("import_chathistory.csv").Skip(1))
{
string comma = Regex.Match(line, "\".*,.*\"").Value.Replace(",", "");
string[] fields = Regex.Replace(line, "\".*,.*\"", comma).Split(',');
fields.All(f =>
{
f = f.StripColors().Trim();
return true;
});
if (fields.Length != 4)
{
manager.GetLogger().WriteError("Invalid chat history import file... aborting import");
return;
}
try
{
int cId = Convert.ToInt32(fields[0]);
var linkedClient = oldClients[cId];
var newcl = cls.FirstOrDefault(c => c.NetworkId == linkedClient.NetworkId);
if (newcl == null)
newcl = cls.FirstOrDefault(c => c.Name == linkedClient.Name && c.IPAddress == linkedClient.IPAddress);
int newCId = newcl.ClientId;
var chatMessage = new EFClientMessage()
{
Active = true,
ClientId = newCId,
Message = fields[1],
TimeSent = DateTime.Parse(fields[3]),
ServerId = Math.Abs($"127.0.0.1:{Convert.ToInt32(fields[2]).ToString()}".GetHashCode())
};
chatHistory.Add(chatMessage);
}
catch (Exception e)
{
manager.GetLogger().WriteVerbose($"Could not import chatmessage with line {line}");
}
}
manager.GetLogger().WriteVerbose($"Read {chatHistory.Count} messages for import");
SharedLibrary.Database.Importer.ImportSQLite(chatHistory);
}
#endregion
#region STATS
if (File.Exists("import_stats.csv"))
{
var stats = new List<EFClientStatistics>();
manager.GetLogger().WriteVerbose("Beginning import of existing client stats");
var lines = File.ReadAllLines("import_stats.csv").Skip(1);
foreach (string line in lines)
{
string[] fields = line.Split(',');
if (fields.Length != 9)
{
manager.GetLogger().WriteError("Invalid client import file... aborting import");
return;
}
try
{
if (fields[0].Substring(0, 5) == "01100")
continue;
long id = fields[0].ConvertLong();
var client = cls.First(c => c.NetworkId == id);
var time = Convert.ToInt32(fields[8]);
double spm = time < 60 ? 0 : Math.Round(Convert.ToInt32(fields[1]) * 100.0 / time, 3);
if (spm > 1000)
spm = 0;
var st = new EFClientStatistics()
{
Active = true,
ClientId = client.ClientId,
ServerId = Math.Abs("127.0.0.1:28965".GetHashCode()),
Kills = Convert.ToInt32(fields[1]),
Deaths = Convert.ToInt32(fields[2]),
SPM = spm,
Skill = 0
};
stats.Add(st);
}
catch (Exception e)
{
continue;
}
}
manager.GetLogger().WriteVerbose($"Read {stats.Count} clients stats for import");
try
{
SharedLibrary.Database.Importer.ImportSQLite<EFClientStatistics>(stats);
}
catch (Exception e)
{
manager.GetLogger().WriteError("Saving imported stats failed");
}
} }
#endregion #endregion
} }
public async Task OnTickAsync(Server S) public async Task OnTickAsync(Server S)
{ {
return;
if ((DateTime.Now - Interval).TotalSeconds > 1) if ((DateTime.Now - Interval).TotalSeconds > 1)
{ {
var rand = new Random(); var rand = new Random();
@ -188,10 +313,10 @@ namespace IW4MAdmin.Plugins
var p = new Player() var p = new Player()
{ {
Name = $"Test_{index}", Name = $"Test_{index}",
NetworkId = $"_test_{index}", NetworkId = (long)$"_test_{index}".GetHashCode(),
ClientNumber = index, ClientNumber = index,
Ping = 1, Ping = 1,
IPAddress = $"127.0.0.{index}" IPAddress = $"127.0.0.{index}".ConvertToIP()
}; };
if (S.Players.ElementAt(index) != null) if (S.Players.ElementAt(index) != null)
@ -221,8 +346,8 @@ namespace IW4MAdmin.Plugins
eventLine = new string[] eventLine = new string[]
{ {
"ScriptKill", "ScriptKill",
attackerPlayer.NetworkId, attackerPlayer.NetworkId.ToString(),
victimPlayer.NetworkId, victimPlayer.NetworkId.ToString(),
new Vector3(rand.Next(minimapInfo.MaxRight, minimapInfo.MaxLeft), rand.Next(minimapInfo.MaxBottom, minimapInfo.MaxTop), rand.Next(0, 100)).ToString(), new Vector3(rand.Next(minimapInfo.MaxRight, minimapInfo.MaxLeft), rand.Next(minimapInfo.MaxBottom, minimapInfo.MaxTop), rand.Next(0, 100)).ToString(),
new Vector3(rand.Next(minimapInfo.MaxRight, minimapInfo.MaxLeft), rand.Next(minimapInfo.MaxBottom, minimapInfo.MaxTop), rand.Next(0, 100)).ToString(), new Vector3(rand.Next(minimapInfo.MaxRight, minimapInfo.MaxLeft), rand.Next(minimapInfo.MaxBottom, minimapInfo.MaxTop), rand.Next(0, 100)).ToString(),
rand.Next(50, 105).ToString(), rand.Next(50, 105).ToString(),
@ -237,11 +362,11 @@ namespace IW4MAdmin.Plugins
eventLine = new string[] eventLine = new string[]
{ {
"K", "K",
victimPlayer.NetworkId, victimPlayer.NetworkId.ToString(),
victimPlayer.ClientNumber.ToString(), victimPlayer.ClientNumber.ToString(),
rand.Next(0, 1) == 0 ? "allies" : "axis", rand.Next(0, 1) == 0 ? "allies" : "axis",
victimPlayer.Name, victimPlayer.Name,
attackerPlayer.NetworkId, attackerPlayer.NetworkId.ToString(),
attackerPlayer.ClientNumber.ToString(), attackerPlayer.ClientNumber.ToString(),
rand.Next(0, 1) == 0 ? "allies" : "axis", rand.Next(0, 1) == 0 ? "allies" : "axis",
attackerPlayer.Name.ToString(), attackerPlayer.Name.ToString(),

View File

@ -40,7 +40,7 @@ namespace Votemap_Plugin
// we only want to allow a vote during a vote session // we only want to allow a vote during a vote session
if (voting.voteInSession) if (voting.voteInSession)
{ {
if (voting.ClientHasVoted(E.Origin.NetworkId)) if (voting.ClientHasVoted(E.Origin.NetworkId.ToString()))
await E.Origin.Tell("You have already voted. Use ^5!vc ^7to ^5cancel ^7your vote"); await E.Origin.Tell("You have already voted. Use ^5!vc ^7to ^5cancel ^7your vote");
else else
{ {
@ -51,7 +51,7 @@ namespace Votemap_Plugin
await E.Origin.Tell("^1" + E.Data + " is not a recognized map"); await E.Origin.Tell("^1" + E.Data + " is not a recognized map");
else else
{ {
voting.CastClientVote(E.Origin.NetworkId, votedMap); voting.CastClientVote(E.Origin.NetworkId.ToString(), votedMap);
await E.Origin.Tell("You voted for ^5" + votedMap.Alias); await E.Origin.Tell("You voted for ^5" + votedMap.Alias);
} }
} }
@ -72,9 +72,9 @@ namespace Votemap_Plugin
if (voting.voteInSession) if (voting.voteInSession)
{ {
if (voting.ClientHasVoted(E.Origin.NetworkId)) if (voting.ClientHasVoted(E.Origin.NetworkId.ToString()))
{ {
voting.CancelClientVote(E.Origin.NetworkId); voting.CancelClientVote(E.Origin.NetworkId.ToString());
await E.Origin.Tell("Vote cancelled"); await E.Origin.Tell("Vote cancelled");
} }

View File

@ -95,7 +95,7 @@ namespace Welcome_Plugin
try try
{ {
CountryLookupProj.CountryLookup CLT = new CountryLookupProj.CountryLookup("Plugins/GeoIP.dat"); CountryLookupProj.CountryLookup CLT = new CountryLookupProj.CountryLookup("Plugins/GeoIP.dat");
await E.Owner.Broadcast($"^5{newPlayer.Name} ^7hails from ^5{CLT.lookupCountryName(newPlayer.IPAddress)}"); await E.Owner.Broadcast($"^5{newPlayer.Name} ^7hails from ^5{CLT.lookupCountryName(newPlayer.IPAddressString)}");
} }
catch (Exception) catch (Exception)

View File

@ -854,7 +854,7 @@ namespace SharedLibrary.Commands
{ {
StringBuilder message = new StringBuilder(); StringBuilder message = new StringBuilder();
var names = new List<string>(E.Target.AliasLink.Children.Select(a => a.Name)); var names = new List<string>(E.Target.AliasLink.Children.Select(a => a.Name));
var IPs = new List<string>(E.Target.AliasLink.Children.Select(a => a.IPAddress).Distinct()); var IPs = new List<string>(E.Target.AliasLink.Children.Select(a => a.IPAddress.ConvertIPtoString()).Distinct());
await E.Target.Tell($"[^3{E.Target}^7]"); await E.Target.Tell($"[^3{E.Target}^7]");

View File

@ -19,6 +19,8 @@ namespace SharedLibrary.Database
{ {
context = new DatabaseContext(); context = new DatabaseContext();
context.Configuration.AutoDetectChangesEnabled = false; context.Configuration.AutoDetectChangesEnabled = false;
context.Configuration.LazyLoadingEnabled = false;
context.Configuration.ProxyCreationEnabled = false;
int count = 0; int count = 0;
foreach (var entityToInsert in clients) foreach (var entityToInsert in clients)
@ -96,6 +98,8 @@ namespace SharedLibrary.Database
{ {
context = new DatabaseContext(); context = new DatabaseContext();
context.Configuration.AutoDetectChangesEnabled = false; context.Configuration.AutoDetectChangesEnabled = false;
context.Configuration.LazyLoadingEnabled = false;
context.Configuration.ProxyCreationEnabled = false;
int count = 0; int count = 0;
foreach (var entityToInsert in penalties) foreach (var entityToInsert in penalties)
@ -161,5 +165,59 @@ namespace SharedLibrary.Database
return context; return context;
} }
public static void ImportSQLite<T>(IList<T> SQLiteData) where T : class
{
DatabaseContext context = null;
try
{
context = new DatabaseContext();
context.Configuration.AutoDetectChangesEnabled = false;
context.Configuration.LazyLoadingEnabled = false;
context.Configuration.ProxyCreationEnabled = false;
int count = 0;
foreach (var entityToInsert in SQLiteData)
{
++count;
context = AddSQLite(context, entityToInsert, count, 100, true);
}
context.SaveChanges();
}
finally
{
if (context != null)
context.Dispose();
}
}
private static DatabaseContext AddSQLite<T>(DatabaseContext context, T entity, int count, int commitCount, bool recreateContext) where T : class
{
context.Set<T>().Add(entity);
if (count % commitCount == 0)
{
try
{
context.SaveChanges();
}
catch (Exception e)
{
var a = 1;
}
if (recreateContext)
{
context.Dispose();
context = new DatabaseContext();
context.Configuration.AutoDetectChangesEnabled = false;
}
}
return context;
}
} }
} }

View File

@ -17,7 +17,7 @@ namespace SharedLibrary.Database
{ {
Active = true, Active = true,
DateAdded = DateTime.UtcNow, DateAdded = DateTime.UtcNow,
IPAddress = "0.0.0.0", IPAddress = 0,
Name = "IW4MAdmin", Name = "IW4MAdmin",
Link = aliasLink Link = aliasLink
}; };
@ -30,7 +30,7 @@ namespace SharedLibrary.Database
LastConnection = DateTime.UtcNow, LastConnection = DateTime.UtcNow,
Level = Objects.Player.Permission.Console, Level = Objects.Player.Permission.Console,
Masked = true, Masked = true,
NetworkId = "0000000000000000", NetworkId = 0,
AliasLink = aliasLink, AliasLink = aliasLink,
CurrentAlias = currentAlias CurrentAlias = currentAlias
}); });

View File

@ -14,10 +14,12 @@ namespace SharedLibrary.Database.Models
public virtual EFAliasLink Link { get; set; } public virtual EFAliasLink Link { get; set; }
// [Index("IX_IPandName", 0, IsUnique = true)] // [Index("IX_IPandName", 0, IsUnique = true)]
//[MaxLength(24)] //[MaxLength(24)]
[Required]
public string Name { get; set; } public string Name { get; set; }
// [Index("IX_IPandName", 1, IsUnique = true)] // [Index("IX_IPandName", 1, IsUnique = true)]
// [MaxLength(24)] // [MaxLength(24)]
public string IPAddress { get; set; } [Required]
public int IPAddress { get; set; }
[Required] [Required]
public DateTime DateAdded { get; set; } public DateTime DateAdded { get; set; }
} }

View File

@ -13,8 +13,7 @@ namespace SharedLibrary.Database.Models
[Key] [Key]
public int ClientId { get; set; } public int ClientId { get; set; }
[Index(IsUnique = true)] [Index(IsUnique = true)]
public string NetworkId { get; set; } public long NetworkId { get; set; }
[Required] [Required]
public int Connections { get; set; } public int Connections { get; set; }
[Required] [Required]
@ -44,12 +43,15 @@ namespace SharedLibrary.Database.Models
set { } set { }
} }
[NotMapped] [NotMapped]
public virtual string IPAddress public virtual int IPAddress
{ {
get { return CurrentAlias.IPAddress; } get { return CurrentAlias.IPAddress; }
set { } set { }
} }
[NotMapped]
public string IPAddressString => new System.Net.IPAddress(BitConverter.GetBytes(IPAddress)).ToString();
public virtual ICollection<EFPenalty> ReceivedPenalties { get; set; } public virtual ICollection<EFPenalty> ReceivedPenalties { get; set; }
public virtual ICollection<EFPenalty> AdministeredPenalties { get; set; } public virtual ICollection<EFPenalty> AdministeredPenalties { get; set; }

View File

@ -131,7 +131,7 @@ namespace SharedLibrary
if (removeTime.Contains("ScriptKill")) if (removeTime.Contains("ScriptKill"))
{ {
return new Event(GType.Script, String.Join(";", line), SV.Players.FirstOrDefault(p => p != null && p.NetworkId == line[1]), SV.Players.FirstOrDefault(p => p != null && p.NetworkId == line[2]), SV); return new Event(GType.Script, String.Join(";", line), SV.Players.FirstOrDefault(p => p != null && p.NetworkId == line[1].ConvertLong()), SV.Players.FirstOrDefault(p => p != null && p.NetworkId == line[2].ConvertLong()), SV);
} }
if (removeTime.Contains("ExitLevel")) if (removeTime.Contains("ExitLevel"))

View File

@ -53,5 +53,10 @@ namespace SharedLibrary.Helpers
RunAverage = RunAverage + ((DateTime.Now - StartTime).TotalMilliseconds - RunAverage - UpdateFrequency) / TimesRun; RunAverage = RunAverage + ((DateTime.Now - StartTime).TotalMilliseconds - RunAverage - UpdateFrequency) / TimesRun;
StartTime = DateTime.Now; StartTime = DateTime.Now;
} }
public void Abort()
{
RequestedTask = null;
}
} }
} }

View File

@ -6,65 +6,32 @@ namespace SharedLibrary.Helpers
{ {
public class ConfigurationManager public class ConfigurationManager
{ {
ConcurrentDictionary<string, Dictionary<string, object>> ConfigurationSet; ConcurrentDictionary<string, dynamic> ConfigSet;
ConcurrentDictionary<string, object> ConfigSet;
Type PluginType;
Server ServerInstance; Server ServerInstance;
public ConfigurationManager(Type PluginType)
{
ConfigurationSet = new ConcurrentDictionary<string, Dictionary<string, object>>();
this.PluginType = PluginType;
}
public ConfigurationManager(Server S) public ConfigurationManager(Server S)
{ {
try try
{ {
ConfigSet = Interfaces.Serialize<ConcurrentDictionary<string, object>>.Read($"config/Plugins_{S}.cfg"); ConfigSet = Interfaces.Serialize<ConcurrentDictionary<string, dynamic>>.Read($"config/plugins_{S.ToString()}.cfg");
} }
catch (Exception) catch (Exception)
{ {
S.Logger.WriteInfo("ConfigurationManager could not deserialize configuration file, so initializing default config set"); S.Logger.WriteInfo("ConfigurationManager could not deserialize configuration file, so initializing default config set");
ConfigSet = new ConcurrentDictionary<string, object>(); ConfigSet = new ConcurrentDictionary<string, dynamic>();
} }
ServerInstance = S; ServerInstance = S;
SaveChanges();
} }
private void SaveChanges() private void SaveChanges()
{ {
Interfaces.Serialize<ConcurrentDictionary<string, object>>.Write($"config/Plugins_{ServerInstance}.cfg", ConfigSet); Interfaces.Serialize<ConcurrentDictionary<string, dynamic>>.Write($"config/plugins_{ServerInstance.ToString()}.cfg", ConfigSet);
} }
public void AddConfiguration(Server S) public void AddProperty(KeyValuePair<string, dynamic> prop)
{
/* if (ConfigurationSet.ContainsKey(S.ToString()))
{
S.Logger.WriteWarning($"not adding server configuration for {S} as it already exists");
return;
}*/
try
{
var Config = Interfaces.Serialize<Dictionary<string, object>>.Read($"config/{PluginType.ToString()}_{S.ToString()}.cfg");
ConfigurationSet.TryAdd(S.ToString(), Config);
}
catch (Exceptions.SerializeException)
{
ConfigurationSet.TryAdd(S.ToString(), new Dictionary<string, object>());
}
}
public void AddProperty(Server S, KeyValuePair<string, object> Property)
{
ConfigurationSet[S.ToString()].Add(Property.Key, Property.Value);
Interfaces.Serialize<Dictionary<string, object>>.Write($"config/{PluginType.ToString()}_{S.ToString()}.cfg", ConfigurationSet[S.ToString()]);
}
public void AddProperty(KeyValuePair<string, object> prop)
{ {
if (!ConfigSet.ContainsKey(prop.Key)) if (!ConfigSet.ContainsKey(prop.Key))
ConfigSet.TryAdd(prop.Key, prop.Value); ConfigSet.TryAdd(prop.Key, prop.Value);
@ -72,13 +39,7 @@ namespace SharedLibrary.Helpers
SaveChanges(); SaveChanges();
} }
public void UpdateProperty(Server S, KeyValuePair<string, object> Property) public void UpdateProperty(KeyValuePair<string, dynamic> prop)
{
ConfigurationSet[S.ToString()][Property.Key] = Property.Value;
Interfaces.Serialize<Dictionary<string, object>>.Write($"config/{PluginType.ToString()}_{S.ToString()}.cfg", ConfigurationSet[S.ToString()]);
}
public void UpdateProperty(KeyValuePair<string, object> prop)
{ {
if (ConfigSet.ContainsKey(prop.Key)) if (ConfigSet.ContainsKey(prop.Key))
ConfigSet[prop.Key] = prop.Value; ConfigSet[prop.Key] = prop.Value;
@ -86,21 +47,16 @@ namespace SharedLibrary.Helpers
SaveChanges(); SaveChanges();
} }
public IDictionary<string, object> GetConfiguration(Server S) public T GetProperty<T>(string prop)
{
return ConfigurationSet[S.ToString()];
}
public object GetProperty(string prop)
{ {
try try
{ {
return ConfigSet[prop]; return ConfigSet[prop].ToObject<T>();
} }
catch (Exception) catch (Exception)
{ {
return null; return default(T);
} }
} }
} }

View File

@ -14,7 +14,7 @@ namespace SharedLibrary.Interfaces
Task<T> Delete(T entity); Task<T> Delete(T entity);
Task<T> Update(T entity); Task<T> Update(T entity);
Task<T> Get(int entityID); Task<T> Get(int entityID);
Task<T> GetUnique(string entityProperty); Task<T> GetUnique(long entityProperty);
Task<IList<T>> Find(Func<T, bool> expression); Task<IList<T>> Find(Func<T, bool> expression);
} }
} }

View File

@ -45,7 +45,7 @@ namespace SharedLibrary.Interfaces
{ {
try try
{ {
string configText = Newtonsoft.Json.JsonConvert.SerializeObject(data); string configText = Newtonsoft.Json.JsonConvert.SerializeObject(data, Newtonsoft.Json.Formatting.Indented);
File.WriteAllText(filename, configText); File.WriteAllText(filename, configText);
} }

View File

@ -76,8 +76,8 @@ namespace SharedLibrary.Objects
[NotMapped] [NotMapped]
public int Score { get; set; } public int Score { get; set; }
private string _ipaddress; private int _ipaddress;
public override string IPAddress public override int IPAddress
{ {
get { return _ipaddress; } get { return _ipaddress; }
set { _ipaddress = value; } set { _ipaddress = value; }
@ -88,5 +88,15 @@ namespace SharedLibrary.Objects
get { return _name; } get { return _name; }
set { _name = value; } set { _name = value; }
} }
public override bool Equals(object obj)
{
return ((Player)obj).NetworkId == NetworkId;
}
public override int GetHashCode()
{
return NetworkId.GetHashCode();
}
} }
} }

View File

@ -39,7 +39,7 @@ namespace SharedLibrary
Reports = new List<Report>(); Reports = new List<Report>();
PlayerHistory = new Queue<Helpers.PlayerHistory>(); PlayerHistory = new Queue<Helpers.PlayerHistory>();
ChatHistory = new List<Chat>(); ChatHistory = new List<Chat>();
Configuration = new ConfigurationManager(this.GetType()); //Configuration = new ConfigurationManager(this.GetType());
NextMessage = 0; NextMessage = 0;
InitializeTokens(); InitializeTokens();
InitializeAutoMessages(); InitializeAutoMessages();

View File

@ -73,7 +73,7 @@ namespace SharedLibrary.Services
.SingleOrDefaultAsync(e => e.AliasId == entityID); .SingleOrDefaultAsync(e => e.AliasId == entityID);
} }
public Task<EFAlias> GetUnique(string entityProperty) public Task<EFAlias> GetUnique(long entityProperty)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }

View File

@ -102,14 +102,18 @@ namespace SharedLibrary.Services
public async Task<EFClient> Get(int entityID) public async Task<EFClient> Get(int entityID)
{ {
using (var context = new DatabaseContext()) using (var context = new DatabaseContext())
{
context.Configuration.LazyLoadingEnabled = false;
context.Configuration.ProxyCreationEnabled = false;
return await new DatabaseContext().Clients return await new DatabaseContext().Clients
.AsNoTracking() .AsNoTracking()
.Include(c => c.CurrentAlias) .Include(c => c.CurrentAlias)
.Include(c => c.AliasLink.Children) .Include(c => c.AliasLink.Children)
.SingleOrDefaultAsync(e => e.ClientId == entityID); .SingleOrDefaultAsync(e => e.ClientId == entityID);
} }
}
public async Task<EFClient> GetUnique(string entityAttribute) public async Task<EFClient> GetUnique(long entityAttribute)
{ {
using (var context = new DatabaseContext()) using (var context = new DatabaseContext())
{ {
@ -117,7 +121,7 @@ namespace SharedLibrary.Services
.AsNoTracking() .AsNoTracking()
.Include(c => c.CurrentAlias) .Include(c => c.CurrentAlias)
.Include(c => c.AliasLink.Children) .Include(c => c.AliasLink.Children)
.SingleOrDefaultAsync(c => c.NetworkId == entityAttribute); .SingleOrDefaultAsync(c => c.NetworkId == (long)entityAttribute);
} }
} }

View File

@ -1,68 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SharedLibrary.Database;
namespace SharedLibrary.Services
{
public class GenericService<T> : Interfaces.IEntityService<T>
{
public async Task<T> Create(T entity)
{
using (var context = new DatabaseContext())
{
var dbSet = context.Set(entity.GetType());
T addedEntity = (T)dbSet.Add(entity);
await context.SaveChangesAsync();
return addedEntity;
}
}
public Task<T> CreateProxy()
{
throw new NotImplementedException();
}
public Task<T> Delete(T entity)
{
throw new NotImplementedException();
}
public Task<IList<T>> Find(Func<T, bool> expression)
{
throw new NotImplementedException();
}
public async Task<T> Get(int entityID)
{
using (var context = new DatabaseContext())
{
var dbSet = context.Set(typeof(T));
return (T)(await dbSet.FindAsync(entityID));
}
}
public async Task<T> Get(params object[] entityKeys)
{
using (var context = new DatabaseContext())
{
var dbSet = context.Set(typeof(T));
return (T)(await dbSet.FindAsync(entityKeys));
}
}
public Task<T> GetUnique(string entityProperty)
{
throw new NotImplementedException();
}
public Task<T> Update(T entity)
{
throw new NotImplementedException();
}
}
}

View File

@ -73,7 +73,7 @@ namespace SharedLibrary.Services
throw new NotImplementedException(); throw new NotImplementedException();
} }
public Task<EFPenalty> GetUnique(string entityProperty) public Task<EFPenalty> GetUnique(long entityProperty)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }

View File

@ -139,7 +139,6 @@
<Compile Include="Services\AliasService.cs" /> <Compile Include="Services\AliasService.cs" />
<Compile Include="Services\ClientService.cs" /> <Compile Include="Services\ClientService.cs" />
<Compile Include="Services\GenericRepository.cs" /> <Compile Include="Services\GenericRepository.cs" />
<Compile Include="Services\GenericService.cs" />
<Compile Include="Services\PenaltyService.cs" /> <Compile Include="Services\PenaltyService.cs" />
<Compile Include="Utilities.cs" /> <Compile Include="Utilities.cs" />
<Compile Include="WebService.cs" /> <Compile Include="WebService.cs" />

View File

@ -58,10 +58,10 @@ namespace SharedLibrary
int Ping = -1; int Ping = -1;
Int32.TryParse(playerInfo[2], out Ping); Int32.TryParse(playerInfo[2], out Ping);
String cName = Utilities.StripColors(responseLine.Substring(46, 18)).Trim(); String cName = Utilities.StripColors(responseLine.Substring(46, 18)).Trim();
string npID = Regex.Match(responseLine, @"([a-z]|[0-9]){16}", RegexOptions.IgnoreCase).Value; long npID = Regex.Match(responseLine, @"([a-z]|[0-9]){16}", RegexOptions.IgnoreCase).Value.ConvertLong();
int.TryParse(playerInfo[0], out cID); int.TryParse(playerInfo[0], out cID);
var regex = Regex.Match(responseLine, @"\d+\.\d+\.\d+.\d+\:\d{1,5}"); var regex = Regex.Match(responseLine, @"\d+\.\d+\.\d+.\d+\:\d{1,5}");
string cIP = regex.Value.Split(':')[0]; int cIP = regex.Value.Split(':')[0].ConvertToIP();
regex = Regex.Match(responseLine, @"[0-9]{1,2}\s+[0-9]+\s+"); regex = Regex.Match(responseLine, @"[0-9]{1,2}\s+[0-9]+\s+");
int score = Int32.Parse(regex.Value.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)[1]); 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}; Player P = new Player() { Name = cName, NetworkId = npID, ClientNumber = cID, IPAddress = cIP, Ping = Ping, Score = score};
@ -197,6 +197,21 @@ namespace SharedLibrary
} }
} }
public static long ConvertLong(this string str)
{
return Int64.Parse(str, System.Globalization.NumberStyles.HexNumber);
}
public static int ConvertToIP(this string str)
{
return BitConverter.ToInt32(System.Net.IPAddress.Parse(str).GetAddressBytes(), 0);
}
public static string ConvertIPtoString(this int ip)
{
return new System.Net.IPAddress(BitConverter.GetBytes(ip)).ToString();
}
public static String DateTimeSQLite(DateTime datetime) public static String DateTimeSQLite(DateTime datetime)
{ {
return datetime.ToString("yyyy-MM-dd H:mm:ss"); return datetime.ToString("yyyy-MM-dd H:mm:ss");