diff --git a/Admin/Application.csproj b/Admin/Application.csproj
index 2e92bb4b0..e5faee5df 100644
--- a/Admin/Application.csproj
+++ b/Admin/Application.csproj
@@ -144,7 +144,6 @@
-
True
@@ -182,12 +181,6 @@
PreserveNewest
-
- PreserveNewest
-
-
- PreserveNewest
-
Always
@@ -245,7 +238,9 @@
PreserveNewest
-
+
+ PreserveNewest
+
@@ -363,6 +358,7 @@ copy /Y "$(SolutionDir)_customcallbacks.gsc" "$(SolutionDir)BUILD\userraw\script
copy /Y "$(TargetDir)$(TargetName).exe" "$(SolutionDir)BUILD"
copy /Y "$(TargetDir)IW4MAdmin.exe.config" "$(SolutionDir)BUILD"
copy /Y "$(ProjectDir)lib\Kayak.dll" "$(SolutionDir)BUILD\lib"
+xcopy /Y /I /E "$(SolutionDir)SharedLibrary\$(OutDir)*" "$(TargetDir)Lib"
xcopy /Y /I /E "$(ProjectDir)webfront\*" "$(SolutionDir)BUILD\Webfront"
xcopy /Y /I /E "$(SolutionDir)Admin\Config\*" "$(SolutionDir)BUILD\Config"
diff --git a/Admin/IW4MAdmin.exe.config b/Admin/IW4MAdmin.exe.config
index 2e57e9ad8..ee80f1361 100644
--- a/Admin/IW4MAdmin.exe.config
+++ b/Admin/IW4MAdmin.exe.config
@@ -1,11 +1,37 @@
-
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Admin/Main.cs b/Admin/Main.cs
index 823a01474..72a91df4d 100644
--- a/Admin/Main.cs
+++ b/Admin/Main.cs
@@ -6,6 +6,11 @@ using SharedLibrary;
using System.Threading.Tasks;
using System.IO;
+#if DEBUG
+using SharedLibrary.Database;
+using SharedLibrary.Objects;
+#endif
+
namespace IW4MAdmin
{
class Program
@@ -38,7 +43,7 @@ namespace IW4MAdmin
Task.Run(() =>
{
String userInput;
- Player Origin = new Player("IW4MAdmin", "", -1, Player.Permission.Console, -1, "", 0, "");
+ Player Origin = ServerManager.GetClientService().Get(1).Result.AsPlayer();
do
{
@@ -50,8 +55,8 @@ namespace IW4MAdmin
if (ServerManager.Servers.Count == 0)
return;
+ Origin.CurrentServer = ServerManager.Servers[0];
Event E = new Event(Event.GType.Say, userInput, Origin, null, ServerManager.Servers[0]);
- Origin.lastEvent = E;
ServerManager.Servers[0].ExecuteEvent(E);
Console.Write('>');
@@ -60,7 +65,7 @@ namespace IW4MAdmin
}
- catch(Exception e)
+ catch (Exception e)
{
Console.WriteLine($"Fatal Error during initialization: {e.Message}");
Console.WriteLine("Press any key to exit...");
diff --git a/Admin/Manager.cs b/Admin/Manager.cs
index cb4635fe0..758971fba 100644
--- a/Admin/Manager.cs
+++ b/Admin/Manager.cs
@@ -10,6 +10,10 @@ using SharedLibrary.Interfaces;
using SharedLibrary.Commands;
using SharedLibrary.Helpers;
using SharedLibrary.Exceptions;
+using SharedLibrary.Objects;
+using SharedLibrary.Database;
+using SharedLibrary.Database.Models;
+using SharedLibrary.Services;
namespace IW4MAdmin
{
@@ -22,14 +26,13 @@ namespace IW4MAdmin
static ApplicationManager Instance;
List TaskStatuses;
- Database ClientDatabase;
- Database AliasesDatabase;
- IPenaltyList ClientPenalties;
List Commands;
List MessageTokens;
Kayak.IScheduler webServiceTask;
Thread WebThread;
- List PrivilegedClients;
+ ClientService ClientSvc;
+ AliasService AliasSvc;
+ PenaltyService PenaltySvc;
#if FTP_LOG
const int UPDATE_FREQUENCY = 15000;
#else
@@ -43,10 +46,9 @@ namespace IW4MAdmin
Commands = new List();
TaskStatuses = new List();
MessageTokens = new List();
-
- ClientDatabase = new ClientsDB("Database/clients.rm", Logger);
- AliasesDatabase = new AliasesDB("Database/aliases.rm", Logger);
- ClientPenalties = new PenaltyList();
+ ClientSvc = new ClientService();
+ AliasSvc = new AliasService();
+ PenaltySvc = new PenaltyService();
}
public IList GetServers()
@@ -145,7 +147,7 @@ namespace IW4MAdmin
#endregion
#region COMMANDS
- if ((ClientDatabase as ClientsDB).GetOwner() == null)
+ if (ClientSvc.GetOwners().Result.Count == 0)
Commands.Add(new COwner());
Commands.Add(new CQuit());
@@ -185,11 +187,6 @@ namespace IW4MAdmin
Commands.Add(C);
#endregion
- #region ADMINS
- PrivilegedClients = GetClientDatabase().GetAdmins();
- #endregion
-
-
Running = true;
}
@@ -225,21 +222,6 @@ namespace IW4MAdmin
Running = false;
}
- public ClientsDB GetClientDatabase()
- {
- return ClientDatabase as ClientsDB;
- }
-
- public AliasesDB GetAliasesDatabase()
- {
- return AliasesDatabase as AliasesDB;
- }
-
- public IPenaltyList GetClientPenalties()
- {
- return ClientPenalties;
- }
-
public ILogger GetLogger()
{
return Logger;
@@ -260,54 +242,8 @@ namespace IW4MAdmin
return ActiveClients;
}
- public IList GetAliasClients(Player Origin)
- {
- List databaseIDs = new List();
-
- foreach (Aliases A in GetAliases(Origin))
- databaseIDs.Add(A.Number);
-
- return GetClientDatabase().GetPlayers(databaseIDs);
- }
-
- public IList GetAliases(Player Origin)
- {
- List allAliases = new List();
-
- if (Origin == null)
- return allAliases;
-
- Aliases currentIdentityAliases = GetAliasesDatabase().GetPlayerAliases(Origin.DatabaseID);
-
- if (currentIdentityAliases == null)
- return allAliases;
-
- GetAliases(allAliases, currentIdentityAliases);
- if (Origin.Alias != null)
- allAliases.Add(Origin.Alias);
- allAliases.Add(currentIdentityAliases);
- return allAliases;
- }
-
- public IList GetPrivilegedClients()
- {
- return PrivilegedClients;
- }
-
- private void GetAliases(List returnAliases, Aliases currentAlias)
- {
- foreach (String IP in currentAlias.IPS)
- {
- List Matching = GetAliasesDatabase().GetPlayerAliases(IP);
- foreach (Aliases I in Matching)
- {
- if (!returnAliases.Contains(I) && returnAliases.Find(x => x.Number == I.Number) == null)
- {
- returnAliases.Add(I);
- GetAliases(returnAliases, I);
- }
- }
- }
- }
+ public ClientService GetClientService() => ClientSvc;
+ public AliasService GetAliasService() => AliasSvc;
+ public PenaltyService GetPenaltyService() => PenaltySvc;
}
}
diff --git a/Admin/PenaltyList.cs b/Admin/PenaltyList.cs
deleted file mode 100644
index 3279a1989..000000000
--- a/Admin/PenaltyList.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using SharedLibrary;
-
-namespace IW4MAdmin
-{
- class PenaltyList : SharedLibrary.Interfaces.IPenaltyList
- {
- public PenaltyList()
- {
- }
-
- public void AddPenalty(Penalty P)
- {
- ApplicationManager.GetInstance().GetClientDatabase().AddPenalty(P);
- }
-
- public void RemovePenalty(Penalty P)
- {
- ApplicationManager.GetInstance().GetClientDatabase().RemoveBan(P.OffenderID);
- }
-
- public List FindPenalties(Player P)
- {
- return ApplicationManager.GetInstance().GetClientDatabase().GetClientPenalties(P);
- }
-
- public List AsChronoList(int offset, int count, Penalty.Type penaltyType = Penalty.Type.Any)
- {
- return ApplicationManager.GetInstance().GetClientDatabase().GetPenaltiesChronologically(offset, count, penaltyType);
- }
- }
-}
diff --git a/Admin/Server.cs b/Admin/Server.cs
index 796882cc4..c30ced944 100644
--- a/Admin/Server.cs
+++ b/Admin/Server.cs
@@ -8,6 +8,8 @@ using System.Threading.Tasks;
using SharedLibrary;
using SharedLibrary.Network;
using SharedLibrary.Interfaces;
+using SharedLibrary.Objects;
+using System.Text.RegularExpressions;
namespace IW4MAdmin
{
@@ -15,128 +17,109 @@ namespace IW4MAdmin
{
public IW4MServer(IManager mgr, ServerConfiguration cfg) : base(mgr, cfg) { }
- override public async Task AddPlayer(Player P)
+ override public async Task AddPlayer(Player polledPlayer)
{
- if (P.ClientID < 0 || P.ClientID > (Players.Count - 1) || P.Ping < 1 || P.Ping == 999) // invalid index
- return false;
-
- if (Players[P.ClientID] != null && Players[P.ClientID].NetworkID == P.NetworkID) // if someone has left and a new person has taken their spot between polls
+ if (Players[polledPlayer.ClientNumber] != null &&
+ Players[polledPlayer.ClientNumber].NetworkId == polledPlayer.NetworkId)
{
// update their ping
- Players[P.ClientID].Ping = P.Ping;
+ Players[polledPlayer.ClientNumber].Ping = polledPlayer.Ping;
return true;
}
- if (P.Name.Length < 3)
+ if (polledPlayer.Name.Length < 3)
{
- await this.ExecuteCommandAsync($"clientkick {P.ClientID} \"Your name must contain atleast 3 characters.\"");
+ await this.ExecuteCommandAsync($"clientkick {polledPlayer.ClientNumber} \"Your name must contain atleast 3 characters.\"");
return false;
}
- Logger.WriteDebug($"Client slot #{P.ClientID} now reserved");
+ Logger.WriteDebug($"Client slot #{polledPlayer.ClientNumber} now reserved");
try
{
- Player NewPlayer = Manager.GetClientDatabase().GetPlayer(P.NetworkID, P.ClientID);
+ Player player = null;
+ var client = (await Manager.GetClientService().GetUnique(polledPlayer.NetworkId));
- if (NewPlayer == null) // first time connecting
+ // first time client is connecting to server
+ if (client == null)
{
- Logger.WriteDebug($"Client slot #{P.ClientID} first time connecting");
- Manager.GetClientDatabase().AddPlayer(P);
- NewPlayer = Manager.GetClientDatabase().GetPlayer(P.NetworkID, P.ClientID);
- Manager.GetAliasesDatabase().AddPlayerAliases(new Aliases(NewPlayer.DatabaseID, NewPlayer.Name, NewPlayer.IP));
+ Logger.WriteDebug($"Client {polledPlayer} first time connecting");
+ player = (await Manager.GetClientService().Create(polledPlayer)).AsPlayer();
}
- List Admins = Manager.GetClientDatabase().GetAdmins();
- if (Admins.Find(x => x.Name == P.Name) != null)
- {
- if ((Admins.Find(x => x.Name == P.Name).NetworkID != P.NetworkID) && NewPlayer.Level < Player.Permission.Moderator)
- await this.ExecuteCommandAsync("clientkick " + P.ClientID + " \"Please do not impersonate an admin^7\"");
- }
-
- // below this needs to be optimized ~ 425ms runtime
- NewPlayer.UpdateName(P.Name.Trim());
- NewPlayer.Alias = Manager.GetAliasesDatabase().GetPlayerAliases(NewPlayer.DatabaseID);
-
- if (NewPlayer.Alias == null)
- {
- Manager.GetAliasesDatabase().AddPlayerAliases(new Aliases(NewPlayer.DatabaseID, NewPlayer.Name, NewPlayer.IP));
- NewPlayer.Alias = Manager.GetAliasesDatabase().GetPlayerAliases(NewPlayer.DatabaseID);
- }
-
- if (P.lastEvent == null || P.lastEvent.Owner == null)
- NewPlayer.lastEvent = new Event(Event.GType.Say, null, NewPlayer, null, this); // this is messy but its throwing an error when they've started in too late
+ // client has connected in the past
else
- NewPlayer.lastEvent = P.lastEvent;
-
- // lets check aliases
- if ((NewPlayer.Alias.Names.Find(m => m.Equals(P.Name))) == null || NewPlayer.Name == null || NewPlayer.Name == String.Empty)
{
- NewPlayer.UpdateName(P.Name.Trim());
- NewPlayer.Alias.Names.Add(NewPlayer.Name);
+ client.Connections += 1;
+ bool aliasExists = client.AliasLink.Children
+ .FirstOrDefault(a => a.Name == polledPlayer.Name && a.IP == polledPlayer.IPAddress) != null;
+
+ if (!aliasExists)
+ {
+ Logger.WriteDebug($"Client {polledPlayer} has connected previously under a different alias");
+ await Manager.GetAliasService().Create(new SharedLibrary.Database.Models.EFAlias()
+ {
+ Active = true,
+ IP = polledPlayer.IPAddress,
+ Name = polledPlayer.Name,
+ DateAdded = DateTime.UtcNow,
+ Link = client.AliasLink,
+ });
+ }
+
+ client.Name = polledPlayer.Name;
+ client.IPAddress = polledPlayer.IPAddress;
+ player = client.AsPlayer();
}
- // and ips
- if (NewPlayer.Alias.IPS.Find(i => i.Equals(P.IP)) == null || P.IP == null || P.IP == String.Empty)
- NewPlayer.Alias.IPS.Add(P.IP);
- NewPlayer.SetIP(P.IP);
- Manager.GetAliasesDatabase().UpdatePlayerAliases(NewPlayer.Alias);
- Manager.GetClientDatabase().UpdatePlayer(NewPlayer);
-
- await ExecuteEvent(new Event(Event.GType.Connect, "", NewPlayer, null, this));
-
- if (NewPlayer.Level == Player.Permission.Banned) // their guid is already banned so no need to check aliases
+ /*var Admins = Manager.GetDatabase().GetPrivilegedClients();
+ if (Admins.Where(x => x.Name == polledPlayer.Name).Count() > 0)
{
- Logger.WriteInfo($"Banned client {P.Name}::{P.NetworkID} trying to connect...");
- await NewPlayer.Kick(NewPlayer.lastOffense != null ? "^7Previously banned for ^5 " + NewPlayer.lastOffense : "^7Previous Ban", NewPlayer);
+ if ((Admins.First(x => x.Name == polledPlayer.Name).NetworkId != polledPlayer.NetworkId) && NewPlayer.Level < Player.Permission.Moderator)
+ await this.ExecuteCommandAsync("clientkick " + polledPlayer.ClientNumber + " \"Please do not impersonate an admin^7\"");
+ }*/
+ player.CurrentServer = this;
+ var ban = (await Manager.GetPenaltyService().Find(p => p.LinkId == player.AliasLink.AliasLinkId
+ && p.Expires > DateTime.UtcNow)).FirstOrDefault();
+
+ if (ban != null)
+ {
+ Logger.WriteInfo($"Banned client {player} trying to connect...");
+ var autoKickClient = (await Manager.GetClientService().Get(1)).AsPlayer();
+ autoKickClient.CurrentServer = this;
+
+ if (ban.Type == Penalty.PenaltyType.TempBan)
+ await this.ExecuteCommandAsync($"clientkick {player.ClientNumber} \"You are temporarily banned. ({(ban.Expires - DateTime.Now).TimeSpanText()} left)\"");
+ else
+ await player.Kick($"previously banned for {ban.Offense}", autoKickClient);
+
+ if (player.Level != Player.Permission.Banned && ban.Type == Penalty.PenaltyType.Ban)
+ await player.Ban($"previously banned for {ban.Offense}", autoKickClient);
return true;
}
- var newPlayerAliases = Manager.GetAliasClients(NewPlayer);
+ // if (aP.Level == Player.Permission.Flagged)
+ // NewPlayer.Level = Player.Permission.Flagged;
+ // Do the player specific stuff
+ player.ClientNumber = polledPlayer.ClientNumber;
+ Players[player.ClientNumber] = player;
+ await Manager.GetClientService().Update(player);
+ Logger.WriteInfo($"Client {player} connecting..."); // they're clean
- foreach (Player aP in newPlayerAliases) // lets check their aliases
- {
- if (aP == null)
- continue;
+ await ExecuteEvent(new Event(Event.GType.Connect, "", player, null, this));
- if (aP.Level == Player.Permission.Flagged)
- NewPlayer.SetLevel(Player.Permission.Flagged);
-
- Penalty B = IsBanned(aP);
-
- if (B != null && B.BType == Penalty.Type.Ban)
- {
- Logger.WriteDebug($"Banned client {aP.Name}::{aP.NetworkID} is connecting with new alias {NewPlayer.Name}");
- NewPlayer.lastOffense = String.Format("Evading ( {0} )", aP.Name);
-
- await NewPlayer.Ban(B.Reason != null ? "^7Previously banned for ^5 " + B.Reason : "^7Previous Ban", NewPlayer);
- Players[NewPlayer.ClientID] = null;
-
- return true;
- }
-
- var activeTB = IsTempBanned(aP);
- if (activeTB != null)
- {
- await this.ExecuteCommandAsync($"clientkick {NewPlayer.ClientID} \"You are temporarily banned. ({(activeTB.Expires - DateTime.Now).TimeSpanText()} left)\"");
- }
- }
-
- Players[NewPlayer.ClientID] = NewPlayer;
- Logger.WriteInfo($"Client {NewPlayer.Name}::{NewPlayer.NetworkID} connecting..."); // they're clean
-
- if (NewPlayer.Level > Player.Permission.Moderator)
- await NewPlayer.Tell("There are ^5" + Reports.Count + " ^7recent reports!");
+ // if (NewPlayer.Level > Player.Permission.Moderator)
+ // await NewPlayer.Tell("There are ^5" + Reports.Count + " ^7recent reports!");
return true;
}
catch (Exception E)
{
- Manager.GetLogger().WriteError($"Unable to add player {P.Name}::{P.NetworkID}");
+ Manager.GetLogger().WriteError($"Unable to add player {polledPlayer.Name}::{polledPlayer.NetworkId}");
Manager.GetLogger().WriteDebug(E.StackTrace);
return false;
}
@@ -148,10 +131,10 @@ namespace IW4MAdmin
if (cNum >= 0)
{
Player Leaving = Players[cNum];
- Leaving.Connections++;
- Manager.GetClientDatabase().UpdatePlayer(Leaving);
+ Leaving.TotalConnectionTime += (int)(DateTime.UtcNow - Leaving.ConnectionTime).TotalSeconds;
+ await Manager.GetClientService().Update(Leaving);
- Logger.WriteInfo($"Client {Leaving.Name}::{Leaving.NetworkID} disconnecting...");
+ Logger.WriteInfo($"Client {Leaving} disconnecting...");
await ExecuteEvent(new Event(Event.GType.Disconnect, "", Leaving, null, this));
Players[cNum] = null;
}
@@ -182,17 +165,6 @@ namespace IW4MAdmin
return Players[pID];
}
- //Check ban list for every banned player and return ban if match is found
- override public Penalty IsBanned(Player C)
- {
- return Manager.GetClientPenalties().FindPenalties(C).Where(b => b.BType == Penalty.Type.Ban).FirstOrDefault();
- }
-
- public Penalty IsTempBanned(Player C)
- {
- return Manager.GetClientPenalties().FindPenalties(C).FirstOrDefault(b => b.BType == Penalty.Type.TempBan && b.Expires > DateTime.Now);
- }
-
//Process requested command correlating to an event
// todo: this needs to be removed out of here
override public async Task ValidateCommand(Event E)
@@ -234,19 +206,16 @@ namespace IW4MAdmin
int cNum = -1;
int.TryParse(Args[0], out cNum);
- if (Args[0] == String.Empty)
- return C;
-
if (Args[0][0] == '@') // user specifying target by database ID
{
int dbID = -1;
int.TryParse(Args[0].Substring(1, Args[0].Length - 1), out dbID);
- Player found = Manager.GetClientDatabase().GetPlayer(dbID);
+ var found = await Manager.GetClientService().Get(dbID);
if (found != null)
{
- E.Target = found;
- E.Target.lastEvent = E;
+ E.Target = found.AsPlayer();
+ E.Target.CurrentServer = this as IW4MServer;
E.Owner = this as IW4MServer;
}
}
@@ -254,7 +223,10 @@ namespace IW4MAdmin
else if (Args[0].Length < 3 && cNum > -1 && cNum < 18) // user specifying target by client num
{
if (Players[cNum] != null)
+ {
E.Target = Players[cNum];
+ E.Data = String.Join(" ", Args.Skip(1));
+ }
}
List matchingPlayers;
@@ -268,7 +240,10 @@ namespace IW4MAdmin
throw new SharedLibrary.Exceptions.CommandException($"{E.Origin} had multiple players found for {C.Name}");
}
else if (matchingPlayers.Count == 1)
+ {
E.Target = matchingPlayers.First();
+ E.Data = Regex.Replace(E.Data, $"\"{E.Target.Name}\"", "", RegexOptions.IgnoreCase).Trim();
+ }
}
if (E.Target == null) // Find active player as single word
@@ -278,11 +253,14 @@ namespace IW4MAdmin
{
await E.Origin.Tell("Multiple players match that name");
foreach (var p in matchingPlayers)
- await E.Origin.Tell($"[^3{p.ClientID}^7] {p.Name}");
+ await E.Origin.Tell($"[^3{p.ClientNumber}^7] {p.Name}");
throw new SharedLibrary.Exceptions.CommandException($"{E.Origin} had multiple players found for {C.Name}");
}
else if (matchingPlayers.Count == 1)
+ {
E.Target = matchingPlayers.First();
+ E.Data = Regex.Replace(E.Data, $"{E.Target.Name}", "", RegexOptions.IgnoreCase).Trim();
+ }
}
if (E.Target == null && C.RequiresTarget)
@@ -327,12 +305,21 @@ namespace IW4MAdmin
for (int i = 0; i < Players.Count; i++)
{
- if (CurrentPlayers.Find(p => p.ClientID == i) == null && Players[i] != null)
+ if (CurrentPlayers.Find(p => p.ClientNumber == i) == null && Players[i] != null)
await RemovePlayer(i);
}
+ //polledPlayer.ClientNumber < 0 || polledPlayer.ClientNumber > (Players.Count - 1) || polledPlayer.Ping < 1 || polledPlayer.Ping == 999
foreach (var P in CurrentPlayers)
+ {
+ if (P.Ping == 999 || P.ClientNumber > MaxClients - 1 || P.ClientNumber < 0)
+ {
+ Logger.WriteDebug($"Skipping client not in connected state {P}");
+ continue;
+ }
+
await AddPlayer(P);
+ }
return CurrentPlayers.Count;
}
@@ -441,8 +428,6 @@ namespace IW4MAdmin
if (event_.Origin == null)
continue;
- event_.Origin.lastEvent = event_;
- event_.Origin.lastEvent.Owner = this;
await ExecuteEvent(event_);
}
}
@@ -623,9 +608,6 @@ namespace IW4MAdmin
else // Not a command
{
E.Data = E.Data.StripColors();
- // this should not be done for all messages.
- //if (E.Data.Length > 50)
- // E.Data = E.Data.Substring(0, 50) + "...";
ChatHistory.Add(new Chat(E.Origin.Name, E.Data, DateTime.Now));
}
@@ -661,46 +643,98 @@ namespace IW4MAdmin
public override async Task Warn(String Reason, Player Target, Player Origin)
{
if (Target.Warnings >= 4)
- await Target.Kick("Too many warnings!", Origin);
+ await Target.Kick("Too many warnings!", (await Manager.GetClientService().Get(1)).AsPlayer());
else
{
- Penalty newPenalty = new Penalty(Penalty.Type.Warning, Reason.StripColors(), Target.NetworkID, Origin.NetworkID, DateTime.Now, Target.IP, DateTime.Now);
- Manager.GetClientPenalties().AddPenalty(newPenalty);
+ Penalty newPenalty = new Penalty()
+ {
+ Type = Penalty.PenaltyType.Warning,
+ Expires = DateTime.UtcNow,
+ Offender = Target,
+ Offense = Reason,
+ Punisher = Origin,
+ Active = true,
+ When = DateTime.UtcNow,
+ Link = Target.AliasLink
+ };
+
+ await Manager.GetPenaltyService().Create(newPenalty);
Target.Warnings++;
- String Message = String.Format("^1WARNING ^7[^3{0}^7]: ^3{1}^7, {2}", Target.Warnings, Target.Name, Target.lastOffense);
+
+ String Message = String.Format("^1WARNING ^7[^3{0}^7]: ^3{1}^7, {2}", Target.Warnings, Target.Name, Reason);
await Broadcast(Message);
}
}
public override async Task Kick(String Reason, Player Target, Player Origin)
{
- if (Target.ClientID > -1)
+ if (Target.ClientNumber > -1)
{
String Message = "^1Player Kicked: ^5" + Reason;
- Penalty newPenalty = new Penalty(Penalty.Type.Kick, Reason.StripColors().Trim(), Target.NetworkID, Origin.NetworkID, DateTime.Now, Target.IP, DateTime.Now);
- Manager.GetClientPenalties().AddPenalty(newPenalty);
- await this.ExecuteCommandAsync($"clientkick {Target.ClientID} \"{Message}^7\"");
+ await Manager.GetPenaltyService().Create(new Penalty()
+ {
+ Type = Penalty.PenaltyType.Kick,
+ Expires = DateTime.UtcNow,
+ Offender = Target,
+ Offense = Reason,
+ Punisher = Origin,
+ Active = true,
+ When = DateTime.UtcNow,
+ Link = Target.AliasLink
+ });
+ await this.ExecuteCommandAsync($"clientkick {Target.ClientNumber} \"{Message}^7\"");
}
}
public override async Task TempBan(String Reason, TimeSpan length, Player Target, Player Origin)
{
- await this.ExecuteCommandAsync($"clientkick {Target.ClientID } \"^1Player Temporarily Banned: ^5{ Reason }\"");
- Penalty newPenalty = new Penalty(Penalty.Type.TempBan, Reason.StripColors(), Target.NetworkID, Origin.NetworkID, DateTime.Now, Target.IP, DateTime.Now + length);
- await Task.Run(() =>
+ await this.ExecuteCommandAsync($"clientkick {Target.ClientNumber } \"^1Player Temporarily Banned: ^5{ Reason }\"");
+ Penalty newPenalty = new Penalty()
{
- Manager.GetClientPenalties().AddPenalty(newPenalty);
- });
+ Type = Penalty.PenaltyType.TempBan,
+ Expires = DateTime.UtcNow + length,
+ Offender = Target,
+ Offense = Reason,
+ Punisher = Origin,
+ Active = true,
+ When = DateTime.UtcNow,
+ Link = Target.AliasLink
+ };
+
+ await Manager.GetPenaltyService().Create(newPenalty);
}
override public async Task Ban(String Message, Player Target, Player Origin)
{
- if (Target == null)
+ Penalty newPenalty = new Penalty()
{
- Logger.WriteError("Ban target is null");
- Logger.WriteDebug($"Message: {Message}");
- Logger.WriteDebug($"Origin: {Origin.Name}::{Origin.NetworkID}");
- return;
+ Type = Penalty.PenaltyType.Ban,
+ Expires = DateTime.MinValue,
+ Offender = Target,
+ Offense = Message,
+ Punisher = Origin,
+ Active = true,
+ When = DateTime.UtcNow,
+ Link = Target.AliasLink
+ };
+ await Manager.GetPenaltyService().Create(newPenalty);
+ Target.Level = Player.Permission.Banned;
+ await Manager.GetClientService().Update(Target);
+
+ lock (Reports) // threading seems to do something weird here
+ {
+ List toRemove = new List();
+ foreach (Report R in Reports)
+ {
+ if (R.Target.NetworkId == Target.NetworkId)
+ toRemove.Add(R);
+ }
+
+ foreach (Report R in toRemove)
+ {
+ Reports.Remove(R);
+ Logger.WriteInfo("Removing report for banned GUID - " + R.Origin.NetworkId);
+ }
}
// banned from all servers if active
@@ -708,65 +742,19 @@ namespace IW4MAdmin
{
if (server.GetPlayersAsList().Count > 0)
{
- var activeClient = server.GetPlayersAsList().SingleOrDefault(x => x.NetworkID == Target.NetworkID);
+ var activeClient = server.GetPlayersAsList().SingleOrDefault(x => x.NetworkId == Target.NetworkId);
if (activeClient != null)
{
- await server.ExecuteCommandAsync($"clientkick {activeClient.ClientID} \"{Message} ^7 ({Website}) ^7\"");
+ await server.ExecuteCommandAsync($"clientkick {activeClient.ClientNumber} \"Player Banned: ^5{Message} ^7(appeal at {Website}) ^7\"");
break;
}
}
}
-
- if (Origin != null)
- {
- Target.SetLevel(Player.Permission.Banned);
- Penalty newBan = new Penalty(Penalty.Type.Ban, Target.lastOffense, Target.NetworkID, Origin.NetworkID, DateTime.Now, Target.IP, DateTime.MaxValue);
-
- await Task.Run(() =>
- {
- Manager.GetClientPenalties().AddPenalty(newBan);
- Manager.GetClientDatabase().UpdatePlayer(Target);
- });
-
- lock (Reports) // threading seems to do something weird here
- {
- List toRemove = new List();
- foreach (Report R in Reports)
- {
- if (R.Target.NetworkID == Target.NetworkID)
- toRemove.Add(R);
- }
-
- foreach (Report R in toRemove)
- {
- Reports.Remove(R);
- Logger.WriteInfo("Removing report for banned GUID - " + R.Origin.NetworkID);
- }
- }
- }
}
override public async Task Unban(Player Target)
{
- // database stuff can be time consuming
- await Task.Run(() =>
- {
- var FoundPenalties = Manager.GetClientPenalties().FindPenalties(Target);
-
- FoundPenalties.Where(p => p.BType > Penalty.Type.Kick)
- .All(p =>
- {
- Manager.GetClientPenalties().RemovePenalty(p);
- return true;
- });
-
- Player P = Manager.GetClientDatabase().GetPlayer(Target.NetworkID, -1);
- if (P.Level < Player.Permission.Trusted)
- {
- P.SetLevel(Player.Permission.User);
- Manager.GetClientDatabase().UpdatePlayer(P);
- }
- });
+ await Manager.GetPenaltyService().RemoveActivePenalties(Target.AliasLink.AliasLinkId);
}
public override bool Reload()
@@ -790,7 +778,7 @@ namespace IW4MAdmin
override public void InitializeTokens()
{
- Manager.GetMessageTokens().Add(new SharedLibrary.Helpers.MessageToken("TOTALPLAYERS", Manager.GetClientDatabase().TotalPlayers().ToString));
+ Manager.GetMessageTokens().Add(new SharedLibrary.Helpers.MessageToken("TOTALPLAYERS", Manager.GetClientService().GetTotalClientsAsync().Result.ToString));
Manager.GetMessageTokens().Add(new SharedLibrary.Helpers.MessageToken("VERSION", Program.Version.ToString));
}
}
diff --git a/Admin/WebService.cs b/Admin/WebService.cs
index da77339cc..73d376c09 100644
--- a/Admin/WebService.cs
+++ b/Admin/WebService.cs
@@ -9,6 +9,12 @@ using System.Net;
using System.Text;
using System.Threading;
+using SharedLibrary.Objects;
+using System.Threading.Tasks;
+using SharedLibrary.Services;
+using System.Linq.Expressions;
+using SharedLibrary.Database.Models;
+
namespace IW4MAdmin
{
public class WebService
@@ -81,7 +87,7 @@ namespace IW4MAdmin
IPage requestedPage = SharedLibrary.WebService.PageList.Find(x => x.GetPath().ToLower() == path.ToLower());
if (requestedPage != null)
- return requestedPage.GetPage(queryset, headers);
+ return Task.Run(async () => await requestedPage.GetPage(queryset, headers)).Result;
else
{
if (File.Exists(path.Replace("/", "\\").Substring(1)))
@@ -127,7 +133,7 @@ namespace IW4MAdmin
}
requestedPage = new Error404();
- return requestedPage.GetPage(queryset, headers);
+ return Task.Run(async () => await requestedPage.GetPage(queryset, headers)).Result;
}
}
}
@@ -144,7 +150,7 @@ namespace IW4MAdmin
return "";
}
- public HttpResponse GetPage(System.Collections.Specialized.NameValueCollection querySet, IDictionary headers)
+ public async Task GetPage(System.Collections.Specialized.NameValueCollection querySet, IDictionary headers)
{
HttpResponse resp = new HttpResponse()
{
@@ -203,7 +209,7 @@ namespace IW4MAdmin
return "/_servers";
}
- public HttpResponse GetPage(System.Collections.Specialized.NameValueCollection querySet, IDictionary headers)
+ public async Task GetPage(System.Collections.Specialized.NameValueCollection querySet, IDictionary headers)
{
var info = new List();
foreach (Server S in ApplicationManager.GetInstance().Servers)
@@ -221,8 +227,8 @@ namespace IW4MAdmin
PlayerHistory = S.PlayerHistory.ToArray()
};
- bool authed = ApplicationManager.GetInstance().GetPrivilegedClients()
- .Where(x => x.IP == querySet["IP"])
+ bool authed = (await (ApplicationManager.GetInstance().GetClientService() as ClientService).GetPrivilegedClients())
+ .Where(x => x.IPAddress == querySet["IP"])
.Where(x => x.Level > Player.Permission.Trusted).Count() > 0
|| querySet["IP"] == "127.0.0.1";
@@ -230,7 +236,7 @@ namespace IW4MAdmin
{
PlayerInfo pInfo = new PlayerInfo()
{
- playerID = P.DatabaseID,
+ playerID = P.ClientNumber,
playerName = P.Name,
playerLevel = authed ? P.Level.ToString() : Player.Permission.User.ToString()
};
@@ -249,7 +255,7 @@ namespace IW4MAdmin
return resp;
}
- public string GetContentType()
+ public string GetContentType()
{
return "application/json";
}
@@ -273,7 +279,7 @@ namespace IW4MAdmin
return "/_playerhistory";
}
- public HttpResponse GetPage(System.Collections.Specialized.NameValueCollection querySet, IDictionary headers)
+ public async Task GetPage(System.Collections.Specialized.NameValueCollection querySet, IDictionary headers)
{
var history = new SharedLibrary.Helpers.PlayerHistory[0];
@@ -320,7 +326,7 @@ namespace IW4MAdmin
return "/_info";
}
- public HttpResponse GetPage(System.Collections.Specialized.NameValueCollection querySet, IDictionary headers)
+ public async Task GetPage(System.Collections.Specialized.NameValueCollection querySet, IDictionary headers)
{
ApplicationInfo info = new ApplicationInfo()
{
@@ -360,12 +366,9 @@ namespace IW4MAdmin
return "/_console";
}
- public HttpResponse GetPage(System.Collections.Specialized.NameValueCollection querySet, IDictionary headers)
+ public async Task GetPage(System.Collections.Specialized.NameValueCollection querySet, IDictionary headers)
{
- CommandInfo cmd = new CommandInfo()
- {
- Result = new List()
- };
+ var cmd = new List();
if (querySet["command"] != null)
{
@@ -376,32 +379,37 @@ namespace IW4MAdmin
if (S != null)
{
- Player admin = ApplicationManager.GetInstance().GetClientDatabase().GetPlayer(querySet["IP"]);
+ // fixme
+ Func predicate = c => c.IPAddress == querySet["IP"];
+ Player admin = (await ApplicationManager.GetInstance().GetClientService().Find(predicate)).First()?.AsPlayer();
if (admin == null)
- admin = new Player("RestUser", "-1", -1, (int)Player.Permission.User);
+ admin = new Player() { Name = "RestUser", Level = Player.Permission.User };
Event remoteEvent = new Event(Event.GType.Say, querySet["command"], admin, null, S)
{
Remote = true
};
- admin.lastEvent = remoteEvent;
+ admin.CurrentServer = S;
+ await S.ExecuteEvent(remoteEvent);
- S.ExecuteEvent(remoteEvent);
+ var results = S.commandResult.Where(c => c.Clientd == admin.ClientId).ToList();
+ cmd.AddRange(results);
+
+ for (int i = 0; i < results.Count(); i++)
+ S.commandResult.Remove(results[i]);
- while (S.commandResult.Count > 0)
- cmd.Result.Add(S.commandResult.Dequeue());
}
else
- cmd.Result.Add("Invalid server selected.");
+ cmd.Add(new SharedLibrary.Helpers.CommandResult() { Clientd = 0, Message = "Invalid server selected" });
}
else
- cmd.Result.Add("Invalid server selected.");
+ cmd.Add(new SharedLibrary.Helpers.CommandResult() { Clientd = 0, Message = "No server selected" });
}
else
{
- cmd.Result.Add("No command entered.");
+ cmd.Add(new SharedLibrary.Helpers.CommandResult() { Clientd = 0, Message = "No command entered" });
}
HttpResponse resp = new HttpResponse()
@@ -437,51 +445,28 @@ namespace IW4MAdmin
return "/_penalties";
}
- public HttpResponse GetPage(System.Collections.Specialized.NameValueCollection querySet, IDictionary headers)
+ public async Task GetPage(System.Collections.Specialized.NameValueCollection querySet, IDictionary headers)
{
int from = 0;
if (querySet["from"] != null)
from = Int32.Parse(querySet["from"]);
- List selectedPenalties;
-
- try
- {
- selectedPenalties = ((ApplicationManager.GetInstance().GetClientPenalties()) as PenaltyList).AsChronoList(Convert.ToInt32(querySet["from"]), 15).OrderByDescending(b => b.When).ToList();
- }
-
- catch (Exception)
- {
- selectedPenalties = new List();
- }
List info = new List();
- foreach (var p in selectedPenalties)
+ foreach (var penalty in await ApplicationManager.GetInstance().GetPenaltyService().GetRecentPenalties(15, from))
{
- Player admin = ApplicationManager.GetInstance().GetClientDatabase().GetPlayer(p.PenaltyOriginID, 0) ??
- new Player("IW4MAdmin", "-1", -1, (int)Player.Permission.Banned);
-
- Player penalized = ApplicationManager.GetInstance().GetClientDatabase().GetPlayer(p.OffenderID, 0);
- if (admin == null && penalized == null)
- continue;
PenaltyInfo pInfo = new PenaltyInfo()
{
- adminName = admin.Name,
- adminLevel = admin.Level.ToString(),
- penaltyReason = p.Reason,
- penaltyTime = Utilities.GetTimePassed(p.When),
- penaltyType = p.BType.ToString(),
- playerName = penalized.Name,
- playerID = penalized.DatabaseID,
- Expires = p.Expires > DateTime.Now ? (p.Expires - DateTime.Now).TimeSpanText() : ""
+ adminName = penalty.Punisher.Name,
+ adminLevel = penalty.Punisher.Level.ToString(),
+ penaltyReason = penalty.Offense,
+ penaltyTime = Utilities.GetTimePassed(penalty.When),
+ penaltyType = penalty.Type.ToString(),
+ playerName = penalty.Offender.Name,
+ playerID = penalty.Offender.ClientId,
+ Expires = penalty.Expires > DateTime.Now ? (penalty.Expires - DateTime.Now).TimeSpanText() : ""
};
-
- if (admin.NetworkID == penalized.NetworkID)
- {
- pInfo.adminName = "IW4MAdmin";
- pInfo.adminLevel = Player.Permission.Console.ToString();
- }
info.Add(pInfo);
}
@@ -626,9 +611,11 @@ namespace IW4MAdmin
return "/GetAdmins";
}
- public HttpResponse GetPage(System.Collections.Specialized.NameValueCollection querySet, IDictionary headers)
+ public async Task GetPage(System.Collections.Specialized.NameValueCollection querySet, IDictionary headers)
{
- var Admins = ApplicationManager.GetInstance().GetClientDatabase().GetAdmins().OrderByDescending(a => a.Level);
+ var Admins = (await (ApplicationManager.GetInstance().GetClientService() as ClientService)
+ .GetPrivilegedClients())
+ .OrderByDescending(a => a.Level).ToList();
HttpResponse resp = new HttpResponse()
{
contentType = GetContentType(),
@@ -661,17 +648,17 @@ namespace IW4MAdmin
return "/pubbans";
}
- public HttpResponse GetPage(System.Collections.Specialized.NameValueCollection querySet, IDictionary headers)
+ public async Task GetPage(System.Collections.Specialized.NameValueCollection querySet, IDictionary headers)
{
HttpResponse resp = new HttpResponse()
{
- contentType = GetContentType(),
- content = Newtonsoft.Json.JsonConvert
- .SerializeObject(((ApplicationManager.GetInstance().GetClientPenalties()) as PenaltyList)
- .AsChronoList(Convert.ToInt32(querySet["from"]), 50, Penalty.Type.Ban), Newtonsoft.Json.Formatting.Indented, new Newtonsoft.Json.JsonConverter[] {
- new Newtonsoft.Json.Converters.StringEnumConverter()
- }),
- additionalHeaders = new Dictionary()
+ /* contentType = GetContentType(),
+ content = Newtonsoft.Json.JsonConvert
+ .SerializeObject(((ApplicationManager.GetInstance().GetClientPenalties()) as PenaltyList)
+ .AsChronoList(Convert.ToInt32(querySet["from"]), 50, Penalty.Type.Ban), Newtonsoft.Json.Formatting.Indented, new Newtonsoft.Json.JsonConverter[] {
+ new Newtonsoft.Json.Converters.StringEnumConverter()
+ }),
+ additionalHeaders = new Dictionary()*/
};
return resp;
}
@@ -699,9 +686,9 @@ namespace IW4MAdmin
return "/pages";
}
- public HttpResponse GetPage(System.Collections.Specialized.NameValueCollection querySet, IDictionary headers)
+ public async Task GetPage(System.Collections.Specialized.NameValueCollection querySet, IDictionary headers)
{
-
+
var pages = SharedLibrary.WebService.PageList.Select(p => new
{
pagePath = p.GetPath(),
@@ -746,33 +733,34 @@ namespace IW4MAdmin
return "GetPlayer";
}
- public HttpResponse GetPage(System.Collections.Specialized.NameValueCollection querySet, IDictionary headers)
+ public async Task GetPage(System.Collections.Specialized.NameValueCollection querySet, IDictionary headers)
{
List pInfo = new List();
- List matchedPlayers = new List();
+ IList matchedPlayers = new List();
HttpResponse resp = new HttpResponse()
{
contentType = GetContentType(),
additionalHeaders = new Dictionary()
};
- bool authed = ApplicationManager.GetInstance().GetClientDatabase().GetAdmins().FindAll(x => x.IP == querySet["IP"] && x.Level > Player.Permission.Trusted).Count > 0
+ Func predicate = c => c.IPAddress == querySet["IP"] && c.Level > Player.Permission.Trusted;
+ bool authed = (await ApplicationManager.GetInstance().GetClientService().Find(predicate)).Count > 0
|| querySet["IP"] == "127.0.0.1";
bool recent = false;
bool individual = querySet["id"] != null;
if (individual)
{
- matchedPlayers.Add(ApplicationManager.GetInstance().GetClientDatabase().GetPlayer(Convert.ToInt32(querySet["id"])));
+ matchedPlayers.Add(await ApplicationManager.GetInstance().GetClientService().Get(Convert.ToInt32(querySet["id"])));
}
else if (querySet["npID"] != null)
{
- matchedPlayers.Add(ApplicationManager.GetInstance().GetClientDatabase().GetPlayers(new List { querySet["npID"] }).First());
+ matchedPlayers.Add(await ApplicationManager.GetInstance().GetClientService().GetUnique(querySet["npID"]));
}
else if (querySet["name"] != null)
{
- matchedPlayers = ApplicationManager.GetInstance().GetClientDatabase().FindPlayers(querySet["name"]);
+ matchedPlayers = await ApplicationManager.GetInstance().GetClientService().Find(c => c.Name.Contains(querySet["name"]));
}
else if (querySet["recent"] != null)
@@ -783,7 +771,7 @@ namespace IW4MAdmin
if (offset < 0)
throw new FormatException("Invalid offset");
- matchedPlayers = ApplicationManager.GetInstance().GetClientDatabase().GetRecentPlayers(15, offset);
+ matchedPlayers = await ApplicationManager.GetInstance().GetClientService().GetRecentClients(offset, 15);
recent = true;
}
@@ -795,26 +783,23 @@ namespace IW4MAdmin
PlayerInfo eachPlayer = new PlayerInfo()
{
- playerID = pp.DatabaseID,
- playerIP = pp.IP,
+ playerIP = pp.IPAddress,
+ playerID = pp.ClientId,
playerLevel = pp.Level.ToString(),
playerName = pp.Name,
- playernpID = pp.NetworkID,
+ playernpID = pp.NetworkId,
forumID = -1,
authed = authed,
showV2Features = false,
playerAliases = new List(),
playerIPs = new List()
-
};
if (!recent && individual && authed)
{
- foreach (var a in ApplicationManager.GetInstance().GetAliases(pp))
- {
- eachPlayer.playerAliases.AddRange(a.Names);
- eachPlayer.playerIPs.AddRange(a.IPS);
- }
+
+ eachPlayer.playerAliases = pp.AliasLink.Children.OrderBy(a => a.Name).Select(a => a.Name).ToList();
+ eachPlayer.playerIPs = pp.AliasLink.Children.Select(a => a.IP).ToList();
}
eachPlayer.playerAliases = eachPlayer.playerAliases.Distinct().ToList();
diff --git a/Admin/lib/SharedLibrary.dll b/Admin/lib/SharedLibrary.dll
index 116e0d226..c6107f87f 100644
Binary files a/Admin/lib/SharedLibrary.dll and b/Admin/lib/SharedLibrary.dll differ
diff --git a/Admin/lib/System.Data.SQLite.dll b/Admin/lib/System.Data.SQLite.dll
deleted file mode 100644
index 54fba4e66..000000000
Binary files a/Admin/lib/System.Data.SQLite.dll and /dev/null differ
diff --git a/Admin/webfront/admins.html b/Admin/webfront/admins.html
index 7d964f154..4b69216c8 100644
--- a/Admin/webfront/admins.html
+++ b/Admin/webfront/admins.html
@@ -1,6 +1,6 @@
diff --git a/Database/Database.csproj b/Database/Database.csproj
new file mode 100644
index 000000000..17e44be3b
--- /dev/null
+++ b/Database/Database.csproj
@@ -0,0 +1,90 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {D076ABC9-DDD6-4E30-9584-E45273950902}
+ Library
+ Properties
+ Database
+ Database
+ v4.5
+ 512
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+ bin\Release-Nightly\
+ TRACE
+ true
+ pdbonly
+ AnyCPU
+ prompt
+ MinimumRecommendedRules.ruleset
+
+
+ bin\Release-Stable\
+
+
+
+ ..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.dll
+
+
+ ..\packages\EntityFramework.SqlServerCompact.6.2.0\lib\net45\EntityFramework.SqlServerCompact.dll
+
+
+
+
+
+ ..\packages\Microsoft.SqlServer.Compact.4.0.8876.1\lib\net40\System.Data.SqlServerCe.dll
+ True
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {d51eeceb-438a-47da-870f-7d7b41bc24d6}
+ SharedLibrary
+
+
+
+
+
+
+
+
+ if not exist "$(TargetDir)x86" md "$(TargetDir)x86"
+ xcopy /s /y "$(SolutionDir)packages\Microsoft.SqlServer.Compact.4.0.8876.1\NativeBinaries\x86\*.*" "$(TargetDir)x86"
+ if not exist "$(TargetDir)amd64" md "$(TargetDir)amd64"
+ xcopy /s /y "$(SolutionDir)packages\Microsoft.SqlServer.Compact.4.0.8876.1\NativeBinaries\amd64\*.*" "$(TargetDir)amd64"
+
+
\ No newline at end of file
diff --git a/Database/IW4MAdminDatabase.cs b/Database/IW4MAdminDatabase.cs
new file mode 100644
index 000000000..9147a7576
--- /dev/null
+++ b/Database/IW4MAdminDatabase.cs
@@ -0,0 +1,38 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+using Database.Models;
+
+namespace Database
+{
+ public class IW4MAdminDatabase : SharedLibrary.Interfaces.IDatabase
+ {
+ private IW4MAdminDatabaseContext _context;
+
+ public IW4MAdminDatabase()
+ {
+ _context = new IW4MAdminDatabaseContext();
+ }
+
+ public SharedLibrary.Interfaces.IDatabaseContext GetContext() => _context;
+
+ public async Task AddClient(Client newClient)
+ {
+ var client = _context.Clients.Add(newClient);
+ await _context.SaveChangesAsync();
+ return client;
+ }
+
+ public Client GetClient(int clientID) => _context.Clients.SingleOrDefault(c => c.ClientId == clientID);
+ public Client GetClient(string networkID) => _context.Clients.SingleOrDefault(c => c.NetworkId == networkID);
+ public IList GetOwners() => _context.Clients.Where(c => c.Level == SharedLibrary.Player.Permission.Owner).ToList();
+ public IList GetPlayers(IList networkIDs) => _context.Clients.Where(c => networkIDs.Contains(c.NetworkId)).Select(c => c.ToPlayer()).ToList();
+ public IList GetPenalties (int clientID) => _context.Penalties.Where(p => p.OffenderId == clientID).ToList();
+ public IList GetAdmins() => _context.Clients.Where(c => c.Level > SharedLibrary.Player.Permission.Flagged).Select(c => c.ToPlayer()).ToList();
+
+
+ }
+}
diff --git a/Database/IW4MAdminDatabaseContext.cs b/Database/IW4MAdminDatabaseContext.cs
new file mode 100644
index 000000000..e30898b73
--- /dev/null
+++ b/Database/IW4MAdminDatabaseContext.cs
@@ -0,0 +1,27 @@
+using System;
+using System.Collections.Generic;
+using System.Data.Entity;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Database.Models;
+using System.Data.SqlServerCe;
+
+namespace Database
+{
+ public class IW4MAdminDatabaseContext : DbContext, SharedLibrary.Interfaces.IDatabaseContext
+ {
+ public DbSet Clients { get; set; }
+ public DbSet Aliases { get; set; }
+ public DbSet Penalties { get; set; }
+
+ public IW4MAdminDatabaseContext() : base("DefaultConnection") { }
+ protected override void OnModelCreating(DbModelBuilder modelBuilder)
+ {
+ var instance = System.Data.Entity.SqlServerCompact.SqlCeProviderServices.Instance;
+ // todo custom load DBSets from plugins
+ // https://aleemkhan.wordpress.com/2013/02/28/dynamically-adding-dbset-properties-in-dbcontext-for-entity-framework-code-first/
+ base.OnModelCreating(modelBuilder);
+ }
+ }
+}
diff --git a/Database/Models/Alias.cs b/Database/Models/Alias.cs
new file mode 100644
index 000000000..e670deb8d
--- /dev/null
+++ b/Database/Models/Alias.cs
@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Database.Models
+{
+ public class Alias
+ {
+ [Key]
+ public int AliasId { get; set; }
+ public int ClientId { get; set; }
+ public string Name { get; set; }
+ public string IP { get; set; }
+ }
+}
diff --git a/Database/Models/Client.cs b/Database/Models/Client.cs
new file mode 100644
index 000000000..2e6e10e84
--- /dev/null
+++ b/Database/Models/Client.cs
@@ -0,0 +1,43 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Database.Models
+{
+ public class Client
+ {
+ [Key]
+ public int ClientId { get; set; }
+
+ [Required]
+ public string Name { get; set; }
+ [Required]
+ public string NetworkId { get; set; }
+ [Required]
+ public SharedLibrary.Player.Permission Level { get; set; }
+ public int Connections { get; set; }
+ [Required]
+ public string IPAddress { get; set; }
+ [Required]
+ public DateTime LastConnection { get; set; }
+ public bool Masked { get; set; }
+
+ public SharedLibrary.Player ToPlayer()
+ {
+ return new SharedLibrary.Player()
+ {
+ Name = Name,
+ Connections = Connections,
+ DatabaseID = ClientId,
+ NetworkID = NetworkId,
+ Level = Level,
+ IP = IPAddress,
+ LastConnection = LastConnection,
+ Masked = Masked
+ };
+ }
+ }
+}
diff --git a/Database/Models/Penalty.cs b/Database/Models/Penalty.cs
new file mode 100644
index 000000000..4b841a6e3
--- /dev/null
+++ b/Database/Models/Penalty.cs
@@ -0,0 +1,23 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations.Schema;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Database.Models
+{
+ public class Penalty
+ {
+ [Key]
+ public int PenaltyId { get; set; }
+ public int OffenderId { get; set; }
+ public Client Offender { get; set; }
+ public int PunisherId { get; set; }
+ public Client Punisher { get; set; }
+ public DateTime When { get; set; }
+ public DateTime Expires { get; set; }
+ public SharedLibrary.Penalty.Type Type { get; set; }
+ }
+}
diff --git a/Database/Properties/AssemblyInfo.cs b/Database/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000..18e5f7e50
--- /dev/null
+++ b/Database/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Database")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("Database")]
+[assembly: AssemblyCopyright("Copyright © 2017")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("d076abc9-ddd6-4e30-9584-e45273950902")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/Database/packages.config b/Database/packages.config
new file mode 100644
index 000000000..82f88f367
--- /dev/null
+++ b/Database/packages.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/IW4MAdmin.sln b/IW4MAdmin.sln
index 5fce63708..03226e498 100644
--- a/IW4MAdmin.sln
+++ b/IW4MAdmin.sln
@@ -1,7 +1,7 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
-VisualStudioVersion = 15.0.27004.2006
+VisualStudioVersion = 15.0.27004.2009
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Application", "Admin\Application.csproj", "{DD5DCDA2-51DB-4B1A-922F-5705546E6115}"
ProjectSection(ProjectDependencies) = postProject
@@ -49,6 +49,10 @@ Global
Debug|Mixed Platforms = Debug|Mixed Platforms
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
+ Release|Any CPU = Release|Any CPU
+ Release|Mixed Platforms = Release|Mixed Platforms
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
Release-Nightly|Any CPU = Release-Nightly|Any CPU
Release-Nightly|Mixed Platforms = Release-Nightly|Mixed Platforms
Release-Nightly|x64 = Release-Nightly|x64
@@ -67,6 +71,14 @@ Global
{DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Debug|x64.Build.0 = Debug|Any CPU
{DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Debug|x86.ActiveCfg = Debug|x86
{DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Debug|x86.Build.0 = Debug|x86
+ {DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release|Any CPU.ActiveCfg = Release-Stable|Any CPU
+ {DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release|Any CPU.Build.0 = Release-Stable|Any CPU
+ {DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release|Mixed Platforms.ActiveCfg = Release-Stable|x86
+ {DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release|Mixed Platforms.Build.0 = Release-Stable|x86
+ {DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release|x64.ActiveCfg = Release-Stable|Any CPU
+ {DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release|x64.Build.0 = Release-Stable|Any CPU
+ {DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release|x86.ActiveCfg = Release-Stable|x86
+ {DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release|x86.Build.0 = Release-Stable|x86
{DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release-Nightly|Any CPU.ActiveCfg = Release-Nightly|Any CPU
{DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release-Nightly|Any CPU.Build.0 = Release-Nightly|Any CPU
{DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release-Nightly|Mixed Platforms.ActiveCfg = Release-Nightly|x86
@@ -91,6 +103,14 @@ Global
{4785AB75-66F3-4391-985D-63A5A049A0FA}.Debug|x64.Build.0 = Debug|Any CPU
{4785AB75-66F3-4391-985D-63A5A049A0FA}.Debug|x86.ActiveCfg = Debug|x86
{4785AB75-66F3-4391-985D-63A5A049A0FA}.Debug|x86.Build.0 = Debug|x86
+ {4785AB75-66F3-4391-985D-63A5A049A0FA}.Release|Any CPU.ActiveCfg = Release-Stable|Any CPU
+ {4785AB75-66F3-4391-985D-63A5A049A0FA}.Release|Any CPU.Build.0 = Release-Stable|Any CPU
+ {4785AB75-66F3-4391-985D-63A5A049A0FA}.Release|Mixed Platforms.ActiveCfg = Release-Stable|x86
+ {4785AB75-66F3-4391-985D-63A5A049A0FA}.Release|Mixed Platforms.Build.0 = Release-Stable|x86
+ {4785AB75-66F3-4391-985D-63A5A049A0FA}.Release|x64.ActiveCfg = Release-Stable|Any CPU
+ {4785AB75-66F3-4391-985D-63A5A049A0FA}.Release|x64.Build.0 = Release-Stable|Any CPU
+ {4785AB75-66F3-4391-985D-63A5A049A0FA}.Release|x86.ActiveCfg = Release-Stable|x86
+ {4785AB75-66F3-4391-985D-63A5A049A0FA}.Release|x86.Build.0 = Release-Stable|x86
{4785AB75-66F3-4391-985D-63A5A049A0FA}.Release-Nightly|Any CPU.ActiveCfg = Release-Nightly|Any CPU
{4785AB75-66F3-4391-985D-63A5A049A0FA}.Release-Nightly|Any CPU.Build.0 = Release-Nightly|Any CPU
{4785AB75-66F3-4391-985D-63A5A049A0FA}.Release-Nightly|Mixed Platforms.ActiveCfg = Release-Nightly|x86
@@ -115,6 +135,14 @@ Global
{D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Debug|x64.Build.0 = Debug|Any CPU
{D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Debug|x86.ActiveCfg = Debug|x86
{D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Debug|x86.Build.0 = Debug|x86
+ {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release|Any CPU.ActiveCfg = Release-Stable|Any CPU
+ {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release|Any CPU.Build.0 = Release-Stable|Any CPU
+ {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release|Mixed Platforms.ActiveCfg = Release-Stable|x86
+ {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release|Mixed Platforms.Build.0 = Release-Stable|x86
+ {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release|x64.ActiveCfg = Release-Stable|Any CPU
+ {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release|x64.Build.0 = Release-Stable|Any CPU
+ {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release|x86.ActiveCfg = Release-Stable|x86
+ {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release|x86.Build.0 = Release-Stable|x86
{D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release-Nightly|Any CPU.ActiveCfg = Release-Nightly|Any CPU
{D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release-Nightly|Any CPU.Build.0 = Release-Nightly|Any CPU
{D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release-Nightly|Mixed Platforms.ActiveCfg = Release-Nightly|x86
@@ -139,6 +167,14 @@ Global
{AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Debug|x64.Build.0 = Debug|Any CPU
{AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Debug|x86.ActiveCfg = Debug|x86
{AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Debug|x86.Build.0 = Debug|x86
+ {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release|Any CPU.ActiveCfg = Release-Stable|Any CPU
+ {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release|Any CPU.Build.0 = Release-Stable|Any CPU
+ {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release|Mixed Platforms.ActiveCfg = Release-Stable|x86
+ {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release|Mixed Platforms.Build.0 = Release-Stable|x86
+ {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release|x64.ActiveCfg = Release-Stable|Any CPU
+ {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release|x64.Build.0 = Release-Stable|Any CPU
+ {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release|x86.ActiveCfg = Release-Stable|x86
+ {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release|x86.Build.0 = Release-Stable|x86
{AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release-Nightly|Any CPU.ActiveCfg = Release-Nightly|Any CPU
{AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release-Nightly|Any CPU.Build.0 = Release-Nightly|Any CPU
{AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release-Nightly|Mixed Platforms.ActiveCfg = Release-Nightly|x86
@@ -163,6 +199,14 @@ Global
{428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Debug|x64.Build.0 = Debug|Any CPU
{428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Debug|x86.ActiveCfg = Debug|x86
{428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Debug|x86.Build.0 = Debug|x86
+ {428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release|Any CPU.ActiveCfg = Release-Stable|Any CPU
+ {428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release|Any CPU.Build.0 = Release-Stable|Any CPU
+ {428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release|Mixed Platforms.ActiveCfg = Release-Stable|x86
+ {428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release|Mixed Platforms.Build.0 = Release-Stable|x86
+ {428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release|x64.ActiveCfg = Release-Stable|Any CPU
+ {428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release|x64.Build.0 = Release-Stable|Any CPU
+ {428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release|x86.ActiveCfg = Release-Stable|x86
+ {428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release|x86.Build.0 = Release-Stable|x86
{428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release-Nightly|Any CPU.ActiveCfg = Release-Nightly|Any CPU
{428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release-Nightly|Mixed Platforms.ActiveCfg = Release-Nightly|x86
{428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release-Nightly|Mixed Platforms.Build.0 = Release-Nightly|x86
@@ -183,6 +227,14 @@ Global
{E46C85BD-A99C-484E-BCCE-0F1831C5925E}.Debug|x64.ActiveCfg = Release-Stable|Any CPU
{E46C85BD-A99C-484E-BCCE-0F1831C5925E}.Debug|x86.ActiveCfg = Debug|x86
{E46C85BD-A99C-484E-BCCE-0F1831C5925E}.Debug|x86.Build.0 = Debug|x86
+ {E46C85BD-A99C-484E-BCCE-0F1831C5925E}.Release|Any CPU.ActiveCfg = Release-Nightly|Any CPU
+ {E46C85BD-A99C-484E-BCCE-0F1831C5925E}.Release|Any CPU.Build.0 = Release-Nightly|Any CPU
+ {E46C85BD-A99C-484E-BCCE-0F1831C5925E}.Release|Mixed Platforms.ActiveCfg = Release-Stable|x86
+ {E46C85BD-A99C-484E-BCCE-0F1831C5925E}.Release|Mixed Platforms.Build.0 = Release-Stable|x86
+ {E46C85BD-A99C-484E-BCCE-0F1831C5925E}.Release|x64.ActiveCfg = Release-Nightly|Any CPU
+ {E46C85BD-A99C-484E-BCCE-0F1831C5925E}.Release|x64.Build.0 = Release-Nightly|Any CPU
+ {E46C85BD-A99C-484E-BCCE-0F1831C5925E}.Release|x86.ActiveCfg = Release-Stable|x86
+ {E46C85BD-A99C-484E-BCCE-0F1831C5925E}.Release|x86.Build.0 = Release-Stable|x86
{E46C85BD-A99C-484E-BCCE-0F1831C5925E}.Release-Nightly|Any CPU.ActiveCfg = Release-Nightly|Any CPU
{E46C85BD-A99C-484E-BCCE-0F1831C5925E}.Release-Nightly|Mixed Platforms.ActiveCfg = Release-Stable|Any CPU
{E46C85BD-A99C-484E-BCCE-0F1831C5925E}.Release-Nightly|x64.ActiveCfg = Release-Stable|Any CPU
@@ -201,6 +253,14 @@ Global
{C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Debug|x64.Build.0 = Debug|Any CPU
{C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Debug|x86.ActiveCfg = Debug|x86
{C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Debug|x86.Build.0 = Debug|x86
+ {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release|Any CPU.ActiveCfg = Release-Stable|Any CPU
+ {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release|Any CPU.Build.0 = Release-Stable|Any CPU
+ {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release|Mixed Platforms.ActiveCfg = Release-Stable|x86
+ {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release|Mixed Platforms.Build.0 = Release-Stable|x86
+ {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release|x64.ActiveCfg = Release-Stable|Any CPU
+ {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release|x64.Build.0 = Release-Stable|Any CPU
+ {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release|x86.ActiveCfg = Release-Stable|x86
+ {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release|x86.Build.0 = Release-Stable|x86
{C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release-Nightly|Any CPU.ActiveCfg = Release-Nightly|Any CPU
{C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release-Nightly|Any CPU.Build.0 = Release-Nightly|Any CPU
{C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release-Nightly|Mixed Platforms.ActiveCfg = Release-Nightly|x86
@@ -225,6 +285,14 @@ Global
{1479DE87-ACB5-4046-81C8-A0BA5041227D}.Debug|x64.Build.0 = Debug|Any CPU
{1479DE87-ACB5-4046-81C8-A0BA5041227D}.Debug|x86.ActiveCfg = Debug|x86
{1479DE87-ACB5-4046-81C8-A0BA5041227D}.Debug|x86.Build.0 = Debug|x86
+ {1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release|Any CPU.ActiveCfg = Release-Stable|Any CPU
+ {1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release|Any CPU.Build.0 = Release-Stable|Any CPU
+ {1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release|Mixed Platforms.ActiveCfg = Release-Stable|x86
+ {1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release|Mixed Platforms.Build.0 = Release-Stable|x86
+ {1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release|x64.ActiveCfg = Release-Stable|Any CPU
+ {1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release|x64.Build.0 = Release-Stable|Any CPU
+ {1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release|x86.ActiveCfg = Release-Stable|x86
+ {1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release|x86.Build.0 = Release-Stable|x86
{1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release-Nightly|Any CPU.ActiveCfg = Release-Nightly|Any CPU
{1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release-Nightly|Mixed Platforms.ActiveCfg = Release-Nightly|x86
{1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release-Nightly|Mixed Platforms.Build.0 = Release-Nightly|x86
@@ -247,6 +315,14 @@ Global
{B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Debug|x64.Build.0 = Debug|Any CPU
{B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Debug|x86.ActiveCfg = Debug|x86
{B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Debug|x86.Build.0 = Debug|x86
+ {B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Release|Any CPU.ActiveCfg = Release-Stable|Any CPU
+ {B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Release|Any CPU.Build.0 = Release-Stable|Any CPU
+ {B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Release|Mixed Platforms.ActiveCfg = Release-Stable|x86
+ {B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Release|Mixed Platforms.Build.0 = Release-Stable|x86
+ {B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Release|x64.ActiveCfg = Release-Stable|Any CPU
+ {B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Release|x64.Build.0 = Release-Stable|Any CPU
+ {B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Release|x86.ActiveCfg = Release-Stable|x86
+ {B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Release|x86.Build.0 = Release-Stable|x86
{B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Release-Nightly|Any CPU.ActiveCfg = Release-Nightly|Any CPU
{B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Release-Nightly|Mixed Platforms.ActiveCfg = Release-Nightly|x86
{B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Release-Nightly|Mixed Platforms.Build.0 = Release-Nightly|x86
diff --git a/Plugins/EventAPI/Plugin.cs b/Plugins/EventAPI/Plugin.cs
index dd64eaadd..8cf79cd5b 100644
--- a/Plugins/EventAPI/Plugin.cs
+++ b/Plugins/EventAPI/Plugin.cs
@@ -1,9 +1,11 @@
using System;
using System.Collections.Generic;
using System.Text;
+using System.Threading.Tasks;
+
using SharedLibrary;
using SharedLibrary.Interfaces;
-using System.Threading.Tasks;
+using SharedLibrary.Objects;
namespace EventAPI
{
@@ -25,7 +27,7 @@ namespace EventAPI
return "/api/events";
}
- public HttpResponse GetPage(System.Collections.Specialized.NameValueCollection querySet, IDictionary headers)
+ public async Task GetPage(System.Collections.Specialized.NameValueCollection querySet, IDictionary headers)
{
bool shouldQuery = querySet.Get("status") != null;
EventResponse requestedEvent = new EventResponse();
diff --git a/Plugins/FastRestart/Plugin.cs b/Plugins/FastRestart/Plugin.cs
index 11ed699c0..14599452d 100644
--- a/Plugins/FastRestart/Plugin.cs
+++ b/Plugins/FastRestart/Plugin.cs
@@ -6,6 +6,7 @@ using SharedLibrary;
using SharedLibrary.Interfaces;
using SharedLibrary.Network;
using SharedLibrary.Helpers;
+using SharedLibrary.Objects;
namespace Plugin
{
diff --git a/Plugins/MessageBoard/Rank.cs b/Plugins/MessageBoard/Rank.cs
index eb725d779..c438f68bb 100644
--- a/Plugins/MessageBoard/Rank.cs
+++ b/Plugins/MessageBoard/Rank.cs
@@ -3,12 +3,14 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
+using SharedLibrary.Objects;
+
namespace MessageBoard
{
public class Rank : Identifiable
{
public string name;
- public SharedLibrary.Player.Permission equivalentRank;
+ public Player.Permission equivalentRank;
public int id;
///
@@ -17,14 +19,14 @@ namespace MessageBoard
///
///
///
- public Rank(string name, SharedLibrary.Player.Permission equivalentRank)
+ public Rank(string name, Player.Permission equivalentRank)
{
this.name = name;
this.equivalentRank = equivalentRank;
id = 0;
}
- public Rank(int id, string name, SharedLibrary.Player.Permission equivalentRank)
+ public Rank(int id, string name, Player.Permission equivalentRank)
{
this.name = name;
this.equivalentRank = equivalentRank;
diff --git a/Plugins/MessageBoard/Storage.cs b/Plugins/MessageBoard/Storage.cs
index 4dfe3ee53..7d89c6fc8 100644
--- a/Plugins/MessageBoard/Storage.cs
+++ b/Plugins/MessageBoard/Storage.cs
@@ -5,7 +5,7 @@ using System.Data;
namespace MessageBoard.Storage
{
- class Database : SharedLibrary.Database
+ class Database : SharedLibrary._Database
{
public Database(String FN, SharedLibrary.Interfaces.ILogger logger) : base(FN, logger) { }
diff --git a/Plugins/SimpleStats/Chat/ChatDatabase.cs b/Plugins/SimpleStats/Chat/ChatDatabase.cs
index 8acc07dbf..e3089b5b0 100644
--- a/Plugins/SimpleStats/Chat/ChatDatabase.cs
+++ b/Plugins/SimpleStats/Chat/ChatDatabase.cs
@@ -10,7 +10,7 @@ using System.Data;
namespace StatsPlugin
{
- public class ChatDatabase : Database
+ public class ChatDatabase : _Database
{
private string[] CommonWords = new string[] { "for",
"with",
diff --git a/Plugins/SimpleStats/Chat/ChatHistoryPage.cs b/Plugins/SimpleStats/Chat/ChatHistoryPage.cs
index ce0c16bf7..6dd91c1fb 100644
--- a/Plugins/SimpleStats/Chat/ChatHistoryPage.cs
+++ b/Plugins/SimpleStats/Chat/ChatHistoryPage.cs
@@ -67,7 +67,7 @@ namespace StatsPlugin.Chat
public HttpResponse GetPage(NameValueCollection querySet, IDictionary headers)
{
int clientID = Convert.ToInt32(querySet["clientid"]);
- var client = Stats.ManagerInstance.GetClientDatabase().GetPlayer(clientID);
+ var name = Stats.ManagerInstance.GetDatabase().GetClient(clientID).Name;
HttpResponse resp = new HttpResponse()
{
@@ -78,7 +78,7 @@ namespace StatsPlugin.Chat
ServerID = c.ServerID,
Message = c.Message,
TimeSent = c.TimeSent,
- ClientName = client.Name,
+ ClientName = name,
}),
additionalHeaders = new Dictionary()
};
diff --git a/Plugins/SimpleStats/Plugin.cs b/Plugins/SimpleStats/Plugin.cs
index 6dc73be56..564f93533 100644
--- a/Plugins/SimpleStats/Plugin.cs
+++ b/Plugins/SimpleStats/Plugin.cs
@@ -7,6 +7,8 @@ using System.IO;
using System.Text;
using System.Threading.Tasks;
+using SharedLibrary.Objects;
+
namespace StatsPlugin
{
public class CViewStats : Command
@@ -74,7 +76,7 @@ namespace StatsPlugin
await E.Origin.Tell("^5--Top Players--");
foreach (KeyValuePair pStat in pStats)
{
- Player P = E.Owner.Manager.GetClientDatabase().GetPlayer(pStat.Key, -1);
+ Player P = E.Owner.Manager.GetDatabase().GetClient(pStat.Key) as Player;
if (P == null)
continue;
await E.Origin.Tell(String.Format("^3{0}^7 - ^5{1} ^7KDR | ^5{2} ^7SKILL", P.Name, pStat.Value.KDR, pStat.Value.Skill));
@@ -132,8 +134,8 @@ namespace StatsPlugin
return;
}
- E.Owner.Manager.GetClientDatabase().PruneAdmins(inactiveDays);
- await E.Origin.Tell("Pruned inactive privileged users");
+ var inactiveAdmins = await E.Owner.Manager.GetDatabase().PruneInactivePrivilegedClients(inactiveDays);
+ await E.Origin.Tell($"Pruned inactive {inactiveAdmins.Count} privileged users");
}
}
@@ -289,7 +291,7 @@ namespace StatsPlugin
if (E.Type == Event.GType.Connect)
{
- ResetCounters(E.Origin.ClientID, S.GetPort());
+ ResetCounters(E.Origin.ClientNumber, S.GetPort());
var config = new ConfigurationManager(E.Owner);
@@ -300,8 +302,8 @@ namespace StatsPlugin
//todo: move this out of here!!
if (checkForTrusted.TotalPlayTime >= 4320 && E.Origin.Level < Player.Permission.Trusted && E.Origin.Level != Player.Permission.Flagged)
{
- E.Origin.SetLevel(Player.Permission.Trusted);
- E.Owner.Manager.GetClientDatabase().UpdatePlayer(E.Origin);
+ 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!");
}
@@ -316,10 +318,10 @@ namespace StatsPlugin
continue;
CalculateAndSaveSkill(P, statLists.Find(x => x.Port == S.GetPort()));
- ResetCounters(P.ClientID, 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.clientID].ToShortTimeString(), inactiveMinutes[P.clientID], newPlayTime, newSPM, kdrWeight, Multiplier, scoreWeight, newSkillFactor, disconnectStats.Skill, disconnectStats.Kills, disconnectStats.Deaths));
+ //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));
}
}
@@ -332,7 +334,7 @@ namespace StatsPlugin
if (E.Type == Event.GType.Disconnect)
{
CalculateAndSaveSkill(E.Origin, statLists.Find(x => x.Port == S.GetPort()));
- ResetCounters(E.Origin.ClientID, S.GetPort());
+ ResetCounters(E.Origin.ClientNumber, S.GetPort());
E.Owner.Logger.WriteInfo($"Updated skill for disconnecting client {E.Origin}");
}
@@ -345,7 +347,7 @@ namespace StatsPlugin
if (killInfo.Length >= 9 && killInfo[0].Contains("ScriptKill"))
{
- var killEvent = new KillInfo(E.Origin.DatabaseID, E.Target.DatabaseID, S.CurrentMap.Name, killInfo[7], killInfo[8], killInfo[5], killInfo[6], killInfo[3], killInfo[4])
+ var killEvent = new KillInfo(E.Origin.ClientNumber, E.Target.ClientNumber, S.CurrentMap.Name, killInfo[7], killInfo[8], killInfo[5], killInfo[6], killInfo[3], killInfo[4])
{
KillerPlayer = E.Origin.Name,
VictimPlayer = E.Target.Name,
@@ -366,11 +368,11 @@ namespace StatsPlugin
if (killerStats == null)
killerStats = new PlayerStats(0, 0, 0, 0, 0, 0);
- curServer.lastKill[E.Origin.ClientID] = DateTime.Now;
- curServer.Kills[E.Origin.ClientID]++;
+ curServer.lastKill[E.Origin.ClientNumber] = DateTime.Now;
+ curServer.Kills[E.Origin.ClientNumber]++;
- if ((DateTime.Now - curServer.lastKill[E.Origin.ClientID]).TotalSeconds > 120)
- curServer.inactiveMinutes[E.Origin.ClientID] += 2;
+ if ((DateTime.Now - curServer.lastKill[E.Origin.ClientNumber]).TotalSeconds > 120)
+ curServer.inactiveMinutes[E.Origin.ClientNumber] += 2;
killerStats.Kills++;
@@ -378,10 +380,10 @@ namespace StatsPlugin
curServer.playerStats.UpdateStats(Killer, killerStats);
- curServer.killStreaks[Killer.ClientID] += 1;
- curServer.deathStreaks[Killer.ClientID] = 0;
+ curServer.killStreaks[Killer.ClientNumber] += 1;
+ curServer.deathStreaks[Killer.ClientNumber] = 0;
- await Killer.Tell(MessageOnStreak(curServer.killStreaks[Killer.ClientID], curServer.deathStreaks[Killer.ClientID]));
+ await Killer.Tell(MessageOnStreak(curServer.killStreaks[Killer.ClientNumber], curServer.deathStreaks[Killer.ClientNumber]));
}
if (E.Type == Event.GType.Death)
@@ -401,15 +403,15 @@ namespace StatsPlugin
curServer.playerStats.UpdateStats(Victim, victimStats);
- curServer.deathStreaks[Victim.ClientID] += 1;
- curServer.killStreaks[Victim.ClientID] = 0;
+ curServer.deathStreaks[Victim.ClientNumber] += 1;
+ curServer.killStreaks[Victim.ClientNumber] = 0;
- await Victim.Tell(MessageOnStreak(curServer.killStreaks[Victim.ClientID], curServer.deathStreaks[Victim.ClientID]));
+ await Victim.Tell(MessageOnStreak(curServer.killStreaks[Victim.ClientNumber], curServer.deathStreaks[Victim.ClientNumber]));
}
if (E.Type == Event.GType.Say)
{
- ChatDB.AddChatHistory(E.Origin.DatabaseID, E.Owner.GetPort(), E.Data);
+ ChatDB.AddChatHistory(E.Origin.ClientNumber, E.Owner.GetPort(), E.Data);
}
}
@@ -444,19 +446,19 @@ namespace StatsPlugin
PlayerStats DisconnectingPlayerStats = curServer.playerStats.GetStats(P);
- if (DisconnectingPlayerStats == null || curServer.Kills[P.ClientID] == 0)
+ if (DisconnectingPlayerStats == null || curServer.Kills[P.ClientNumber] == 0)
return;
- else if (curServer.lastKill[P.ClientID] > curServer.connectionTime[P.ClientID])
- curServer.inactiveMinutes[P.ClientID] += (int)(DateTime.Now - curServer.lastKill[P.ClientID]).TotalMinutes;
+ else if (curServer.lastKill[P.ClientNumber] > curServer.connectionTime[P.ClientNumber])
+ curServer.inactiveMinutes[P.ClientNumber] += (int)(DateTime.Now - curServer.lastKill[P.ClientNumber]).TotalMinutes;
- int newPlayTime = (int)(DateTime.Now - curServer.connectionTime[P.ClientID]).TotalMinutes - curServer.inactiveMinutes[P.ClientID];
+ int newPlayTime = (int)(DateTime.Now - curServer.connectionTime[P.ClientNumber]).TotalMinutes - curServer.inactiveMinutes[P.ClientNumber];
if (newPlayTime < 2)
return;
// calculate the players Score Per Minute for the current session
- double SessionSPM = curServer.Kills[P.ClientID] * 100 / Math.Max(1, newPlayTime);
+ double SessionSPM = curServer.Kills[P.ClientNumber] * 100 / Math.Max(1, newPlayTime);
// calculate how much the KDR should way
// 1.637 is a Eddie-Generated number that weights the KDR nicely
double KDRWeight = Math.Round(Math.Pow(DisconnectingPlayerStats.KDR, 1.637 / Math.E), 3);
@@ -520,7 +522,7 @@ namespace StatsPlugin
}
}
- public class StatsDB : Database
+ public class StatsDB : _Database
{
public StatsDB(String FN, SharedLibrary.Interfaces.ILogger logger) : base(FN, logger) { }
@@ -624,7 +626,7 @@ namespace StatsPlugin
{
Dictionary newPlayer = new Dictionary
{
- { "npID", P.NetworkID },
+ { "npID", P.NetworkId },
{ "KILLS", 0 },
{ "DEATHS", 0 },
{ "KDR", 0.0 },
@@ -637,7 +639,7 @@ namespace StatsPlugin
public PlayerStats GetStats(Player P)
{
- DataTable Result = GetDataTable("STATS", new KeyValuePair("npID", P.NetworkID));
+ DataTable Result = GetDataTable("STATS", new KeyValuePair("npID", P.NetworkId));
if (Result != null && Result.Rows.Count > 0)
{
@@ -682,7 +684,7 @@ namespace StatsPlugin
{ "SPM", Math.Round(S.scorePerMinute, 2) },
{ "PLAYTIME", S.TotalPlayTime }
};
- Update("STATS", updatedPlayer, new KeyValuePair("npID", P.NetworkID));
+ Update("STATS", updatedPlayer, new KeyValuePair("npID", P.NetworkId));
}
public List> GetTopStats()
diff --git a/Plugins/Tests/Plugin.cs b/Plugins/Tests/Plugin.cs
index c743a2fa7..f920433af 100644
--- a/Plugins/Tests/Plugin.cs
+++ b/Plugins/Tests/Plugin.cs
@@ -4,9 +4,11 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
+
using SharedLibrary;
using SharedLibrary.Interfaces;
using SharedLibrary.Helpers;
+using SharedLibrary.Objects;
namespace IW4MAdmin.Plugins
{
@@ -63,17 +65,20 @@ namespace IW4MAdmin.Plugins
{
var rand = new Random();
int index = rand.Next(0, 17);
- var p = new Player($"?!'\"\"'<>Test_{index}", $"_test{index}", index, (int)Player.Permission.User)
+ var p = new Player()
{
- Ping = 1
+ Name = $"Test{index}",
+ NetworkId = $"_test{index}",
+ ClientNumber = index,
+ Level = Player.Permission.User,
+ Ping = 1,
+ IPAddress = "127.0.0.1"
};
- p.SetIP("127.0.0.1");
-
if (S.Players.ElementAt(index) != null)
await S.RemovePlayer(index);
await S.AddPlayer(p);
-
+ /*
Interval = DateTime.Now;
if (S.ClientNum > 0)
@@ -83,7 +88,7 @@ namespace IW4MAdmin.Plugins
var victimPlayer = S.Players.Where(pl => pl != null).ToList()[rand.Next(0, S.ClientNum - 1)];
var attackerPlayer = S.Players.Where(pl => pl != null).ToList()[rand.Next(0, S.ClientNum - 1)];
- await S.ExecuteEvent(new Event(Event.GType.Say, $"test_{attackerPlayer.ClientID}", victimPlayer, attackerPlayer, S));
+ await S.ExecuteEvent(new Event(Event.GType.Say, $"test_{attackerPlayer.ClientNumber}", victimPlayer, attackerPlayer, S));
string[] eventLine = null;
@@ -99,8 +104,8 @@ namespace IW4MAdmin.Plugins
eventLine = new string[]
{
"ScriptKill",
- attackerPlayer.NetworkID,
- victimPlayer.NetworkID,
+ attackerPlayer.NetworkId,
+ victimPlayer.NetworkId,
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(),
@@ -115,12 +120,12 @@ namespace IW4MAdmin.Plugins
eventLine = new string[]
{
"K",
- victimPlayer.NetworkID,
- victimPlayer.ClientID.ToString(),
+ victimPlayer.NetworkId,
+ victimPlayer.ClientNumber.ToString(),
rand.Next(0, 1) == 0 ? "allies" : "axis",
victimPlayer.Name,
- attackerPlayer.NetworkID,
- attackerPlayer.ClientID.ToString(),
+ attackerPlayer.NetworkId,
+ attackerPlayer.ClientNumber.ToString(),
rand.Next(0, 1) == 0 ? "allies" : "axis",
attackerPlayer.Name.ToString(),
((StatsPlugin.IW4Info.WeaponName)rand.Next(0, Enum.GetValues(typeof(StatsPlugin.IW4Info.WeaponName)).Length - 1)).ToString(), // Weapon
@@ -133,7 +138,7 @@ namespace IW4MAdmin.Plugins
var _event = Event.ParseEventString(eventLine, S);
await S.ExecuteEvent(_event);
}
- }
+ }*/
}
}
diff --git a/Plugins/VoteMap/Plugin.cs b/Plugins/VoteMap/Plugin.cs
index 99696d209..e47c32425 100644
--- a/Plugins/VoteMap/Plugin.cs
+++ b/Plugins/VoteMap/Plugin.cs
@@ -1,10 +1,11 @@
using System;
using System.Collections.Generic;
+using System.Threading.Tasks;
using SharedLibrary;
using SharedLibrary.Network;
using SharedLibrary.Interfaces;
-using System.Threading.Tasks;
+using SharedLibrary.Objects;
namespace Votemap_Plugin
{
@@ -39,7 +40,7 @@ namespace Votemap_Plugin
// we only want to allow a vote during a vote session
if (voting.voteInSession)
{
- if (voting.ClientHasVoted(E.Origin.NetworkID))
+ if (voting.ClientHasVoted(E.Origin.NetworkId))
await E.Origin.Tell("You have already voted. Use ^5!vc ^7to ^5cancel ^7your vote");
else
{
@@ -50,7 +51,7 @@ namespace Votemap_Plugin
await E.Origin.Tell("^1" + E.Data + " is not a recognized map");
else
{
- voting.CastClientVote(E.Origin.NetworkID, votedMap);
+ voting.CastClientVote(E.Origin.NetworkId, votedMap);
await E.Origin.Tell("You voted for ^5" + votedMap.Alias);
}
}
@@ -71,9 +72,9 @@ namespace Votemap_Plugin
if (voting.voteInSession)
{
- if (voting.ClientHasVoted(E.Origin.NetworkID))
+ if (voting.ClientHasVoted(E.Origin.NetworkId))
{
- voting.CancelClientVote(E.Origin.NetworkID);
+ voting.CancelClientVote(E.Origin.NetworkId);
await E.Origin.Tell("Vote cancelled");
}
diff --git a/Plugins/Welcome/Plugin.cs b/Plugins/Welcome/Plugin.cs
index caec2f11a..412214e76 100644
--- a/Plugins/Welcome/Plugin.cs
+++ b/Plugins/Welcome/Plugin.cs
@@ -5,14 +5,12 @@ using SharedLibrary.Interfaces;
using System.Threading.Tasks;
using SharedLibrary.Network;
+using SharedLibrary.Objects;
namespace Welcome_Plugin
{
public class Plugin : IPlugin
{
- Dictionary PlayerPings;
- int PingAverageCount;
-
String TimesConnected(Player P)
{
int connection = P.Connections;
@@ -68,37 +66,14 @@ namespace Welcome_Plugin
public async Task OnLoadAsync(IManager manager)
{
- PlayerPings = new Dictionary();
- PingAverageCount = 1;
}
public async Task OnUnloadAsync()
{
- PlayerPings.Clear();
- PlayerPings = null;
}
public async Task OnTickAsync(Server S)
{
- return;
-
- // TODO: check if this works
-
- int MaxPing = (await S.GetDvarAsync("sv_maxping")).Value;
-
- if (MaxPing == 0)
- return;
-
- foreach (int PlayerID in PlayerPings.Keys)
- {
- var Player = S.Players.Find(p => p.DatabaseID == PlayerID);
- PlayerPings[PlayerID] = PlayerPings[PlayerID] + (Player.Ping - PlayerPings[PlayerID]) / PingAverageCount;
- if (PlayerPings[PlayerID] > MaxPing)
- await Player.Kick($"Your average ping of ^5{PlayerPings[PlayerID]} ^7is too high for this server", null);
- }
-
- if (PingAverageCount > 100)
- PingAverageCount = 1;
}
public async Task OnEventAsync(Event E, Server S)
@@ -120,7 +95,7 @@ namespace Welcome_Plugin
try
{
CountryLookupProj.CountryLookup CLT = new CountryLookupProj.CountryLookup("Plugins/GeoIP.dat");
- await E.Owner.Broadcast($"^5{newPlayer.Name} ^7hails from ^5{CLT.lookupCountryName(newPlayer.IP)}");
+ await E.Owner.Broadcast($"^5{newPlayer.Name} ^7hails from ^5{CLT.lookupCountryName(newPlayer.IPAddress)}");
}
catch (Exception)
@@ -129,13 +104,10 @@ namespace Welcome_Plugin
}
}
-
- //PlayerPings.Add(E.Origin.DatabaseID, 1.0f);
}
if (E.Type == Event.GType.Disconnect)
{
- //PlayerPings.Remove(E.Origin.DatabaseID);
}
}
}
diff --git a/SharedLibrary/Command.cs b/SharedLibrary/Command.cs
index e4680df50..768967f55 100644
--- a/SharedLibrary/Command.cs
+++ b/SharedLibrary/Command.cs
@@ -2,6 +2,8 @@
using System.Linq;
using System.Threading.Tasks;
+using SharedLibrary.Objects;
+
namespace SharedLibrary
{
public class CommandArgument
diff --git a/SharedLibrary/Commands/NativeCommands.cs b/SharedLibrary/Commands/NativeCommands.cs
index fd794d970..1a80af5b9 100644
--- a/SharedLibrary/Commands/NativeCommands.cs
+++ b/SharedLibrary/Commands/NativeCommands.cs
@@ -2,9 +2,12 @@
using System.Collections.Generic;
using System.Text;
using System.Linq;
+using System.Threading.Tasks;
+
using SharedLibrary.Network;
using SharedLibrary.Helpers;
-using System.Threading.Tasks;
+using SharedLibrary.Objects;
+
namespace SharedLibrary.Commands
{
@@ -28,11 +31,11 @@ namespace SharedLibrary.Commands
public override async Task ExecuteAsync(Event E)
{
- if (E.Owner.Manager.GetClientDatabase().GetOwner() == null)
+ if ((await (E.Owner.Manager.GetClientService() as Services.ClientService).GetOwners()).Count == 0)
{
- E.Origin.SetLevel(Player.Permission.Owner);
+ E.Origin.Level = Player.Permission.Owner;
await E.Origin.Tell("Congratulations, you have claimed ownership of this server!");
- E.Owner.Manager.GetClientDatabase().UpdatePlayer(E.Origin);
+ await E.Owner.Manager.GetClientService().Update(E.Origin);
}
else
await E.Origin.Tell("This server already has an owner!");
@@ -59,11 +62,10 @@ namespace SharedLibrary.Commands
public override async Task ExecuteAsync(Event E)
{
- E.Target.lastOffense = E.Data.RemoveWords(1);
if (E.Origin.Level <= E.Target.Level)
await E.Origin.Tell($"You do not have the required privileges to warn {E.Target.Name}");
else
- await E.Target.Warn(E.Target.lastOffense, E.Origin);
+ await E.Target.Warn(E.Data.RemoveWords(1), E.Origin);
}
}
@@ -82,7 +84,6 @@ namespace SharedLibrary.Commands
public override async Task ExecuteAsync(Event E)
{
- E.Target.lastOffense = String.Empty;
E.Target.Warnings = 0;
String Message = String.Format("All warning cleared for {0}", E.Target.Name);
await E.Owner.Broadcast(Message);
@@ -109,11 +110,10 @@ namespace SharedLibrary.Commands
public override async Task ExecuteAsync(Event E)
{
- E.Target.lastOffense = E.Data.RemoveWords(1);
if (E.Origin.Level > E.Target.Level)
{
await E.Owner.ExecuteEvent(new Event(Event.GType.Kick, E.Data, E.Origin, E.Target, E.Owner));
- await E.Target.Kick(E.Target.lastOffense, E.Origin);
+ await E.Target.Kick(E.Data.RemoveWords(1), E.Origin);
await E.Origin.Tell($"^5{E.Target} ^7has been kicked");
}
else
@@ -165,8 +165,7 @@ namespace SharedLibrary.Commands
public override async Task ExecuteAsync(Event E)
{
- E.Target.lastOffense = Utilities.RemoveWords(E.Data, 1);
- String Message = E.Target.lastOffense;
+ String Message = Utilities.RemoveWords(E.Data, 1);
var length = Message.ParseTimespan();
if (length.TotalHours != 1)
@@ -202,17 +201,9 @@ namespace SharedLibrary.Commands
public override async Task ExecuteAsync(Event E)
{
- E.Target.lastOffense = Utilities.RemoveWords(E.Data, 1);
- E.Target.lastEvent = E; // needs to be fixed
- String Message;
- if (E.Owner.Website == null)
- Message = "^1Player Banned: ^5" + E.Target.lastOffense;
- else
- Message = "^1Player Banned: ^5" + E.Target.lastOffense;
if (E.Origin.Level > E.Target.Level)
{
- await E.Owner.ExecuteEvent(new Event(Event.GType.Ban, E.Data, E.Origin, E.Target, E.Owner));
- await E.Target.Ban(Message, E.Origin);
+ await E.Target.Ban(E.Data, E.Origin);
await E.Origin.Tell($"^5{E.Target} ^7has been permanently banned");
}
else
@@ -248,7 +239,7 @@ namespace SharedLibrary.Commands
public override async Task ExecuteAsync(Event E)
{
- String You = String.Format("{0} [^3#{1}^7] {2} [^3@{3}^7] [{4}^7] IP: {5}", E.Origin.Name, E.Origin.ClientID, E.Origin.NetworkID, E.Origin.DatabaseID, Utilities.ConvertLevelToColor(E.Origin.Level), E.Origin.IP);
+ String You = String.Format("{0} [^3#{1}^7] {2} [^3@{3}^7] [{4}^7] IP: {5}", E.Origin.Name, E.Origin.ClientNumber, E.Origin.NetworkId, E.Origin.ClientNumber, Utilities.ConvertLevelToColor(E.Origin.Level), E.Origin.IPAddress);
await E.Origin.Tell(You);
}
}
@@ -271,9 +262,9 @@ namespace SharedLibrary.Commands
continue;
if (P.Masked)
- playerList.AppendFormat("[^3{0}^7]{3}[^3{1}^7] {2}", Utilities.ConvertLevelToColor(Player.Permission.User), P.ClientID, P.Name, Utilities.GetSpaces(Player.Permission.SeniorAdmin.ToString().Length - Player.Permission.User.ToString().Length));
+ playerList.AppendFormat("[^3{0}^7]{3}[^3{1}^7] {2}", Utilities.ConvertLevelToColor(Player.Permission.User), P.ClientNumber, P.Name, Utilities.GetSpaces(Player.Permission.SeniorAdmin.ToString().Length - Player.Permission.User.ToString().Length));
else
- playerList.AppendFormat("[^3{0}^7]{3}[^3{1}^7] {2}", Utilities.ConvertLevelToColor(P.Level), P.ClientID, P.Name, Utilities.GetSpaces(Player.Permission.SeniorAdmin.ToString().Length - P.Level.ToString().Length));
+ playerList.AppendFormat("[^3{0}^7]{3}[^3{1}^7] {2}", Utilities.ConvertLevelToColor(P.Level), P.ClientNumber, P.Name, Utilities.GetSpaces(Player.Permission.SeniorAdmin.ToString().Length - P.Level.ToString().Length));
if (count == 2 || E.Owner.GetPlayersAsList().Count == 1)
{
@@ -424,16 +415,16 @@ namespace SharedLibrary.Commands
if (newPerm > Player.Permission.Banned)
{
- var ActiveClient = E.Owner.Manager.GetActiveClients().FirstOrDefault(p => p.NetworkID == E.Target.NetworkID);
- ActiveClient?.SetLevel(newPerm);
+ var ActiveClient = E.Owner.Manager.GetActiveClients().FirstOrDefault(p => p.NetworkId == E.Target.NetworkId);
+ ActiveClient.Level = newPerm;
if (ActiveClient != null)
await ActiveClient.Tell("Congratulations! You have been promoted to ^3" + newPerm);
await E.Origin.Tell($"{E.Target.Name} was successfully promoted!");
- E.Target.SetLevel(newPerm);
- E.Owner.Manager.GetClientDatabase().UpdatePlayer(E.Target);
+ E.Target.Level = newPerm;
+ await E.Owner.Manager.GetClientService().Update(E.Target);
}
else
@@ -536,9 +527,9 @@ namespace SharedLibrary.Commands
public override async Task ExecuteAsync(Event E)
{
- var db_players = E.Owner.Manager.GetClientDatabase().FindPlayers(E.Data.Trim());
+ var db_players = await E.Owner.Manager.GetClientService().Find(c => c.Name.Contains(E.Data));
- if (db_players == null)
+ if (db_players.Count == 0)
{
await E.Origin.Tell("No players found");
return;
@@ -546,7 +537,7 @@ namespace SharedLibrary.Commands
foreach (Player P in db_players)
{
- String mesg = String.Format("[^3{0}^7] [^3@{1}^7] - [{2}^7] - {3} | last seen {4}", P.Name, P.DatabaseID, Utilities.ConvertLevelToColor(P.Level), P.IP, P.GetLastConnection());
+ String mesg = String.Format("[^3{0}^7] [^3@{1}^7] - [{2}^7] - {3} | last seen {4}", P.Name, P.ClientNumber, Utilities.ConvertLevelToColor(P.Level), P.IPAddress, P.GetLastConnection());
await E.Origin.Tell(mesg);
}
}
@@ -575,36 +566,17 @@ namespace SharedLibrary.Commands
return;
}
- var db_aliases = E.Owner.Manager.GetAliasesDatabase().FindPlayerAliases(E.Data);
+ var db_aliases = await E.Owner.Manager.GetAliasService().Find(a => a.Name.Contains(E.Data));
- if (db_aliases == null || db_aliases.Count() == 0)
+ if (db_aliases.Count == 0)
{
await E.Origin.Tell("No players found");
return;
}
- foreach (Aliases P in db_aliases)
+ foreach (var P in db_aliases)
{
- if (P == null)
- continue;
-
- String lookingFor = null;
-
- foreach (String S in P.Names)
- {
- if (S.ToLower().Contains(E.Data.ToLower()))
- lookingFor = S;
- }
-
- lookingFor = lookingFor ?? P.Names.First();
-
- Player Current = E.Owner.Manager.GetClientDatabase().GetPlayer(P.Number);
-
- if (Current != null && Current.Name != lookingFor)
- {
- String mesg = String.Format("^1{0} ^7now goes by ^5{1}^7 [^3{2}^7]", lookingFor, Current.Name, Current.DatabaseID);
- await E.Origin.Tell(mesg);
- }
+ await E.Origin.Tell($"^4{P.Name} ^7now goes by ^5{P.Link.Children.OrderByDescending(a => a.DateAdded).First().Name}");
}
}
}
@@ -707,21 +679,33 @@ namespace SharedLibrary.Commands
if (E.Target.Level == Player.Permission.Flagged)
{
- E.Target.SetLevel(Player.Permission.User);
- E.Owner.Manager.GetClientPenalties().RemovePenalty(new Penalty(Penalty.Type.Flag, "", E.Target.NetworkID, "", DateTime.Now, "", DateTime.Now));
+ E.Target.Level = Player.Permission.User;
+ //E.Owner.Manager.GetClientPenalties().RemovePenalty(new Penalty(Penalty.PenaltyType.Flag, "", E.Target.NetworkId, "", DateTime.Now, "", DateTime.Now));
await E.Origin.Tell("You have ^5unflagged ^7" + E.Target.Name);
}
else
{
E.Data = Utilities.RemoveWords(E.Data, 1);
- E.Target.SetLevel(Player.Permission.Flagged);
- E.Owner.Manager.GetClientPenalties().AddPenalty(new Penalty(Penalty.Type.Flag, E.Data, E.Target.NetworkID, E.Origin.NetworkID, DateTime.Now, E.Target.IP, DateTime.Now));
+ E.Target.Level = Player.Permission.Flagged;
+
+ Penalty newPenalty = new Penalty()
+ {
+ Type = Penalty.PenaltyType.Flag,
+ Expires = DateTime.UtcNow,
+ Offender = E.Target,
+ Offense = E.Data,
+ Punisher = E.Origin,
+ Active = true,
+ When = DateTime.UtcNow
+ };
+
+ await E.Owner.Manager.GetPenaltyService().Create(newPenalty);
await E.Owner.ExecuteEvent(new Event(Event.GType.Flag, E.Data, E.Origin, E.Target, E.Owner));
await E.Origin.Tell("You have ^5flagged ^7" + E.Target.Name);
}
- E.Owner.Manager.GetClientDatabase().UpdatePlayer(E.Target);
+ await E.Owner.Manager.GetClientService().Update(E.Target);
}
}
@@ -745,7 +729,7 @@ namespace SharedLibrary.Commands
public override async Task ExecuteAsync(Event E)
{
- if (E.Owner.Reports.Find(x => (x.Origin == E.Origin && x.Target.NetworkID == E.Target.NetworkID)) != null)
+ if (E.Owner.Reports.Find(x => (x.Origin == E.Origin && x.Target.NetworkId == E.Target.NetworkId)) != null)
{
await E.Origin.Tell("You have already reported this player");
return;
@@ -824,7 +808,7 @@ namespace SharedLibrary.Commands
await E.Origin.Tell("You are now masked");
}
- E.Owner.Manager.GetClientDatabase().UpdatePlayer(E.Origin);
+ await E.Owner.Manager.GetClientService().Update(E.Origin);
}
}
@@ -843,18 +827,17 @@ namespace SharedLibrary.Commands
public override async Task ExecuteAsync(Event E)
{
- var B = E.Owner.Manager.GetClientPenalties().FindPenalties(E.Target);
- var BannedPenalty = B.Find(b => b.BType > Penalty.Type.Kick && b.Expires > DateTime.Now);
+ var B = await E.Owner.Manager.GetPenaltyService().GetClientPenaltiesAsync(E.Target.ClientId);
- if (BannedPenalty == null)
+ var penalty = B.FirstOrDefault(b => b.Type > Penalty.PenaltyType.Kick && b.Expires > DateTime.UtcNow);
+
+ if (penalty == null)
{
await E.Origin.Tell("No active ban was found for that player");
return;
}
- Player Banner = E.Owner.Manager.GetClientDatabase().GetPlayer(BannedPenalty.PenaltyOriginID, -1);
-
- await E.Origin.Tell(String.Format("^1{0} ^7was banned by ^5{1} ^7for: {2} {3}", E.Target.Name, Banner?.Name ?? "IW4MAdmin", BannedPenalty.Reason, BannedPenalty.BType == Penalty.Type.TempBan ? $"({(BannedPenalty.Expires - DateTime.Now).TimeSpanText()} remaining)" : ""));
+ await E.Origin.Tell(String.Format("^1{0} ^7was banned by ^5{1} ^7for: {2} {3}", E.Target.Name, penalty.Punisher.Name, penalty.Offense, penalty.Type == Penalty.PenaltyType.TempBan ? $"({(penalty.Expires - DateTime.Now).TimeSpanText()} remaining)" : ""));
}
}
@@ -873,37 +856,19 @@ namespace SharedLibrary.Commands
public override async Task ExecuteAsync(Event E)
{
- E.Target.Alias = E.Owner.Manager.GetAliasesDatabase().GetPlayerAliases(E.Target.DatabaseID);
-
- if (E.Target.Alias == null)
- {
- await E.Target.Tell("Could not find alias info for that player");
- return;
- }
-
- await E.Target.Tell("[^3" + E.Target.Name + "^7]");
StringBuilder message = new StringBuilder();
+ var names = new List(E.Target.AliasLink.Children.Select(a => a.Name));
+ var IPs = new List(E.Target.AliasLink.Children.Select(a => a.IP));
- var playerAliases = E.Owner.GetAliases(E.Target);
+ await E.Target.Tell($"[^3{E.Target}^7]");
message.Append("Aliases: ");
-
- var names = new List();
- var ips = new List();
-
- foreach (var alias in playerAliases)
- {
- names.AddRange(alias.Names);
- ips.AddRange(alias.IPS);
- }
- message.Append(String.Join(" | ", names.Distinct()));
-
+ message.Append(String.Join(" | ", names));
await E.Origin.Tell(message.ToString());
message.Clear();
message.Append("IPs: ");
- message.Append(String.Join(" | ", ips.Distinct()));
-
+ message.Append(String.Join(" | ", IPs));
await E.Origin.Tell(message.ToString());
}
}
@@ -955,7 +920,7 @@ namespace SharedLibrary.Commands
public override async Task ExecuteAsync(Event E)
{
- await E.Origin.Tell($"Your external IP is ^5{E.Origin.IP}");
+ await E.Origin.Tell($"Your external IP is ^5{E.Origin.IPAddress}");
}
}
}
diff --git a/SharedLibrary/Database.cs b/SharedLibrary/Database.cs
deleted file mode 100644
index 9c0928ad3..000000000
--- a/SharedLibrary/Database.cs
+++ /dev/null
@@ -1,735 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Data.SQLite;
-using System.Data;
-using System.IO;
-
-namespace SharedLibrary
-{
- public abstract class Database
- {
- private Interfaces.ILogger Logger;
-
- public Database(String FN, Interfaces.ILogger logger)
- {
- FileName = FN;
- Logger = logger;
- Init();
- }
-
- protected SQLiteConnection GetNewConnection()
- {
- return new SQLiteConnection($"Data Source={FileName}");
- }
-
- abstract public void Init();
-
- protected bool Insert(String tableName, Dictionary data, bool ignore = false)
- {
- string names = "";
- string parameters = "";
- foreach (string key in data.Keys)
- {
- names += key + ',';
- parameters += '@' + key + ',';
- }
- names = names.Substring(0, names.Length - 1);
- parameters = parameters.Substring(0, parameters.Length - 1);
-
- var Con = GetNewConnection();
-
- string ignoreCmd = ignore ? " OR IGNORE " : " ";
-
- SQLiteCommand insertcmd = new SQLiteCommand()
- {
- Connection = Con,
- CommandText = String.Format("INSERT{0}INTO `{1}` ({2}) VALUES ({3});", ignoreCmd, tableName, names, parameters)
- };
- foreach (string key in data.Keys)
- {
- insertcmd.Parameters.AddWithValue('@' + key, data[key]);
- }
-
- try
- {
- Con.Open();
- insertcmd.ExecuteNonQuery();
- Con.Close();
- return true;
- }
-
- catch (Exception E)
- {
- Logger.WriteWarning($"Database Insert failed");
- Logger.WriteDebug($"Exception Message: {E.Message}");
- Logger.WriteDebug($"SQL command: {insertcmd.CommandText}");
- Logger.WriteDebug($"Database File: {FileName}");
- return false;
- }
-
- }
-
- protected void UpdateIncrement(String tableName, string columnName, Dictionary data, KeyValuePair where)
- {
- string parameters = "";
- foreach (string key in data.Keys)
- {
- parameters += $"{key}={key}+1,";
- }
-
- parameters = parameters.Substring(0, parameters.Length - 1);
- var Con = GetNewConnection();
-
- SQLiteCommand updatecmd = new SQLiteCommand()
- {
- Connection = Con,
- CommandText = String.Format("UPDATE `{0}` SET {1} WHERE {2}=@{2}", tableName, parameters, where.Key)
- };
- foreach (string key in data.Keys)
- {
- updatecmd.Parameters.AddWithValue('@' + key, data[key]);
- }
-
- updatecmd.Parameters.AddWithValue('@' + where.Key, where.Value);
-
- try
- {
- Con.Open();
- updatecmd.ExecuteNonQuery();
- Con.Close();
- }
-
- catch (Exception E)
- {
- Logger.WriteWarning($"Database UpdateIncrement failed");
- Logger.WriteDebug($"Exception Message: {E.Message}");
- Logger.WriteDebug($"SQL command: {updatecmd?.CommandText}");
- Logger.WriteDebug($"Database File: {FileName}");
- }
- }
-
- protected bool Update(String tableName, Dictionary data, KeyValuePair where)
- {
- string parameters = "";
- foreach (string key in data.Keys)
- {
- parameters += key + '=' + '@' + key + ',';
- }
-
- parameters = parameters.Substring(0, parameters.Length - 1);
- var Con = GetNewConnection();
-
- SQLiteCommand updatecmd = new SQLiteCommand()
- {
- Connection = Con,
- CommandText = String.Format("UPDATE `{0}` SET {1} WHERE {2}=@{2}", tableName, parameters, where.Key)
- };
- foreach (string key in data.Keys)
- {
- updatecmd.Parameters.AddWithValue('@' + key, data[key]);
- }
-
- updatecmd.Parameters.AddWithValue('@' + where.Key, where.Value);
-
- try
- {
- Con.Open();
- updatecmd.ExecuteNonQuery();
- Con.Close();
- return true;
- }
-
- catch (Exception E)
- {
- Logger.WriteWarning($"Database update failed");
- Logger.WriteDebug($"Exception Message: {E.Message}");
- Logger.WriteDebug($"SQL Query: {updatecmd.CommandText}");
- Logger.WriteDebug($"Database File: {FileName}");
- return false;
- }
- }
-
- protected DataRow GetDataRow(String Q)
- {
- DataRow Result = GetDataTable(Q).Rows[0];
- return Result;
- }
-
- protected int ExecuteNonQuery(String Request)
- {
- int rowsUpdated = 0;
- Request = Request.Replace("!'", "").Replace("!", "");
- var Con = GetNewConnection();
- SQLiteCommand CMD = null;
- try
- {
-
- Con.Open();
- CMD = new SQLiteCommand(Con)
- {
- CommandText = Request
- };
- rowsUpdated = CMD.ExecuteNonQuery();
- Con.Close();
- return rowsUpdated;
- }
-
- catch (Exception E)
- {
- Logger.WriteWarning($"Database command failed");
- Logger.WriteDebug($"Exception Message: {E.Message}");
- Logger.WriteDebug($"SQL command: {CMD?.CommandText}");
- Logger.WriteDebug($"Database File: {FileName}");
- return 0;
- }
- }
-
- protected DataTable GetDataTable(string tableName, KeyValuePair where)
- {
- DataTable dt = new DataTable();
- SQLiteCommand updatecmd = new SQLiteCommand()
- {
- CommandText = String.Format("SELECT * FROM {0} WHERE `{1}`=@{1};", tableName, where.Key)
- };
- var Con = GetNewConnection();
- updatecmd.Parameters.AddWithValue('@' + where.Key, where.Value);
- updatecmd.Connection = Con;
-
-
- try
- {
- Con.Open();
- SQLiteDataReader reader = updatecmd.ExecuteReader();
- dt.Load(reader);
- reader.Close();
- Con.Close();
- }
-
- catch (Exception E)
- {
- Logger.WriteWarning($"Database GetDataTable failed");
- Logger.WriteDebug($"Exception Message: {E.Message}");
- Logger.WriteDebug($"SQL command: {updatecmd.CommandText}");
- Logger.WriteDebug($"Database File: {FileName}");
- }
-
- return dt;
- }
-
- protected DataTable GetDataTable(SQLiteCommand cmd)
- {
- DataTable dt = new DataTable();
- var Con = GetNewConnection();
- cmd.Connection = Con;
- try
- {
- Con.Open();
- SQLiteDataReader reader = cmd.ExecuteReader();
- dt.Load(reader);
- reader.Close();
- Con.Close();
- }
-
- catch (Exception E)
- {
- Logger.WriteWarning($"Database GetDataTable failed");
- Logger.WriteDebug($"Exception Message: {E.Message}");
- Logger.WriteDebug($"SQL command: {cmd.CommandText}");
- Logger.WriteDebug($"Database File: {FileName}");
- }
-
- return dt;
- }
-
- protected DataTable GetDataTable(String sql)
- {
- DataTable dt = new DataTable();
- var Con = GetNewConnection();
- SQLiteCommand cmd = null;
-
- try
- {
-
- Con.Open();
- cmd = new SQLiteCommand(Con)
- {
- CommandText = sql
- };
- SQLiteDataReader reader = cmd.ExecuteReader();
- dt.Load(reader);
- reader.Close();
- Con.Close();
-
- }
- catch (Exception E)
- {
- Logger.WriteWarning($"Database GetDataTable failed");
- Logger.WriteDebug($"Exception Message: {E.Message}");
- Logger.WriteDebug($"SQL command: {cmd?.CommandText}");
- Logger.WriteDebug($"Database File: {FileName}");
- return new DataTable();
- }
- return dt;
- }
-
- protected String FileName;
- }
-
- public class ClientsDB : Database
- {
- public ClientsDB(String FN, Interfaces.ILogger logger) : base(FN, logger) { }
-
- public override void Init()
- {
- if (!File.Exists(FileName))
- {
- String Create = "CREATE TABLE [CLIENTS] ( [Name] TEXT NULL, [npID] TEXT NULL, [Number] INTEGER PRIMARY KEY AUTOINCREMENT, [Level] INT DEFAULT 0 NULL, [LastOffense] TEXT NULL, [Connections] INT DEFAULT 1 NULL, [IP] TEXT NULL, [LastConnection] TEXT NULL, [UID] TEXT NULL, [Masked] INT DEFAULT 0, [Reserved] INT DEFAULT 0);";
- ExecuteNonQuery(Create);
- Create = "CREATE TABLE [BANS] ( [TYPE] TEXT NULL, [Reason] TEXT NULL, [npID] TEXT NULL, [bannedByID] TEXT NULL, [IP] TEXT NULL, [TIME] TEXT NULL, [EXPIRES] TEXT);";
- ExecuteNonQuery(Create);
- }
- }
-
-
- public List GetRecentPlayers(int count = 15, int offset = 0)
- {
- List returnssss = new List();
- var Result = GetDataTable($"SELECT * FROM CLIENTS LIMIT {count} OFFSET (SELECT COUNT(*) FROM CLIENTS)-{offset + count}");
-
- if (Result != null && Result.Rows.Count > 0)
- {
- foreach (DataRow ResponseRow in Result.Rows)
- {
- DateTime lastCon = DateTime.MinValue;
- DateTime.TryParse(ResponseRow["LastConnection"].ToString(), out lastCon);
-
- returnssss.Add(new Player(ResponseRow["Name"].ToString(), ResponseRow["npID"].ToString(), -1, (Player.Permission)(ResponseRow["Level"]), Convert.ToInt32(ResponseRow["Number"]), ResponseRow["LastOffense"].ToString(), (int)ResponseRow["Connections"], ResponseRow["IP"].ToString(), lastCon, ResponseRow["UID"].ToString(), ResponseRow["Masked"].ToString() == "1"));
- }
- }
-
- return returnssss.OrderByDescending(p => p.LastConnection).ToList(); ;
- }
-
- public List GetPlayers(List npIDs)
- {
- List returnssss = new List();
- String test = String.Join("' OR npID = '", npIDs);
-
- String Query = String.Format("SELECT * FROM CLIENTS WHERE npID = '{0}'", test);
- DataTable Result = GetDataTable(Query);
-
- if (Result != null && Result.Rows.Count > 0)
- {
- foreach (DataRow ResponseRow in Result.Rows)
- {
- DateTime lastCon = DateTime.MinValue;
- DateTime.TryParse(ResponseRow["LastConnection"].ToString(), out lastCon);
-
- returnssss.Add(new Player(ResponseRow["Name"].ToString(), ResponseRow["npID"].ToString(), -1, (Player.Permission)(ResponseRow["Level"]), Convert.ToInt32(ResponseRow["Number"]), ResponseRow["LastOffense"].ToString(), (int)ResponseRow["Connections"], ResponseRow["IP"].ToString(), lastCon, ResponseRow["UID"].ToString(), ResponseRow["Masked"].ToString() == "1"));
- }
- }
-
- return returnssss;
- }
-
- public List GetPlayers(List databaseIDs)
- {
- List returnssss = new List();
- String Condition = String.Join("' OR Number = '", databaseIDs);
-
- String Query = String.Format("SELECT * FROM CLIENTS WHERE Number = '{0}'", Condition);
- DataTable Result = GetDataTable(Query);
-
- if (Result != null && Result.Rows.Count > 0)
- {
- foreach (DataRow ResponseRow in Result.Rows)
- {
- DateTime lastCon = DateTime.MinValue;
- DateTime.TryParse(ResponseRow["LastConnection"].ToString(), out lastCon);
-
- returnssss.Add(new Player(ResponseRow["Name"].ToString(), ResponseRow["npID"].ToString(), -1, (Player.Permission)(ResponseRow["Level"]), Convert.ToInt32(ResponseRow["Number"]), ResponseRow["LastOffense"].ToString(), (int)ResponseRow["Connections"], ResponseRow["IP"].ToString(), lastCon, ResponseRow["UID"].ToString(), ResponseRow["Masked"].ToString() == "1"));
- }
- }
-
- return returnssss;
- }
-
- //Overloaded method for getPlayer, returns Client with matching DBIndex, null if none found
- public Player GetPlayer(int dbIndex)
- {
- DataTable Result = GetDataTable("CLIENTS", new KeyValuePair("Number", dbIndex));
-
- if (Result != null && Result.Rows.Count > 0)
- {
- DataRow p = Result.Rows[0];
- DateTime LC;
- try
- {
- LC = DateTime.Parse(p["LastConnection"].ToString());
- }
- catch (Exception)
- {
- LC = DateTime.MinValue;
- }
-
- return new Player(p["Name"].ToString(), p["npID"].ToString(), -1, (Player.Permission)(p["Level"]), Convert.ToInt32(p["Number"]), p["LastOffense"].ToString(), Convert.ToInt32(p["Connections"]), p["IP"].ToString(), LC, p["UID"].ToString(), p["Masked"].ToString() == "1");
- }
-
- else
- return null;
- }
-
- //get player by ip, (used for webfront)
- public Player GetPlayer(String IP)
- {
- DataTable Result = GetDataTable("CLIENTS", new KeyValuePair("IP", IP));
-
- if (Result != null && Result.Rows.Count > 0)
- {
- List lastKnown = new List();
- foreach (DataRow p in Result.Rows)
- {
- DateTime LC;
- try
- {
- LC = DateTime.Parse(p["LastConnection"].ToString());
- lastKnown.Add(new Player(p["Name"].ToString(), p["npID"].ToString(), -1, (Player.Permission)(p["Level"]), Convert.ToInt32(p["Number"]), p["LastOffense"].ToString(), Convert.ToInt32((DateTime.Now - LC).TotalSeconds), p["IP"].ToString(), LC, p["UID"].ToString(), p["Masked"].ToString() == "1"));
- }
-
- catch (Exception)
- {
- continue;
- }
- }
-
- if (lastKnown.Count > 0)
- {
- List Returning = lastKnown.OrderBy(t => t.Connections).ToList();
- return Returning[0];
- }
-
- else
- return null;
- }
-
- else
- return null;
- }
-
- //Returns a single player object with matching GUID, false if no matches
- public Player GetPlayer(String ID, int cNum)
- {
- DataTable Result = GetDataTable("CLIENTS", new KeyValuePair("npID", ID));
-
- if (Result != null && Result.Rows.Count > 0)
- {
- DataRow ResponseRow = Result.Rows[0];
- DateTime lastCon = DateTime.MinValue;
- DateTime.TryParse(ResponseRow["LastConnection"].ToString(), out lastCon);
-
- return new Player(ResponseRow["Name"].ToString(), ResponseRow["npID"].ToString(), cNum, (Player.Permission)(ResponseRow["Level"]), Convert.ToInt32(ResponseRow["Number"]), ResponseRow["LastOffense"].ToString(), (int)ResponseRow["Connections"], ResponseRow["IP"].ToString(), lastCon, ResponseRow["UID"].ToString(), ResponseRow["Masked"].ToString() == "1");
- }
-
- else
- return null;
- }
-
- //Returns a list of players matching name parameter, null if no players found matching
- public List FindPlayers(String name)
- {
- var Con = GetNewConnection();
- SQLiteCommand cmd = new SQLiteCommand(Con)
- {
- CommandText = "SELECT * FROM CLIENTS WHERE Name LIKE @Name"
- };
- cmd.Parameters.AddWithValue("@Name", '%' + name + '%');
-
- var Result = GetDataTable(cmd);
-
- List Players = new List();
-
- if (Result != null && Result.Rows.Count > 0)
- {
- foreach (DataRow p in Result.Rows)
- {
- DateTime LC;
- string Masked = null;
- try
- {
- LC = DateTime.Parse(p["LastConnection"].ToString());
- Masked = p["Masked"].ToString();
-
- }
- catch (Exception)
- {
- if (Masked == null)
- Masked = "0";
-
- LC = DateTime.MinValue;
- }
- Players.Add(new Player(p["Name"].ToString(), p["npID"].ToString(), -1, (Player.Permission)(p["Level"]), Convert.ToInt32(p["Number"]), p["LastOffense"].ToString(), Convert.ToInt32(p["Connections"]), p["IP"].ToString(), LC, p["IP"].ToString(), Masked == "1"));
- }
- return Players;
- }
-
- else
- return null;
- }
-
- //Returns any player with level 4 permissions, null if no owner found
- public Player GetOwner()
- {
- String Query = String.Format("SELECT * FROM CLIENTS WHERE Level > '{0}'", 4);
- DataTable Result = GetDataTable(Query);
-
- if (Result != null && Result.Rows.Count > 0)
- {
- DataRow ResponseRow = Result.Rows[0];
- if (ResponseRow["IP"].ToString().Length < 6)
- ResponseRow["IP"] = "0";
- return new Player(ResponseRow["Name"].ToString(), ResponseRow["npID"].ToString(), -1, (Player.Permission)(ResponseRow["Level"]), Convert.ToInt32(ResponseRow["Number"]), null, 0, ResponseRow["IP"].ToString());
- }
-
- else
- return null;
- }
-
- public List GetClientPenalties(Player P)
- {
- List ClientPenalties = new List();
- String Query = $"SELECT * FROM `BANS` WHERE `npID` = '{P.NetworkID}' OR `IP` = '{P.IP}'";
- DataTable Result = GetDataTable(Query);
-
- foreach (DataRow Row in Result.Rows)
- {
- if (Row["TIME"].ToString().Length < 2) //compatibility with my old database
- Row["TIME"] = DateTime.Now.ToString();
-
- Penalty.Type BanType = Penalty.Type.Ban;
- if (Row["TYPE"].ToString().Length != 0)
- BanType = (Penalty.Type)Enum.Parse(typeof(Penalty.Type), Row["TYPE"].ToString());
-
- ClientPenalties.Add(new Penalty(BanType, Row["Reason"].ToString().Trim(), Row["npID"].ToString(), Row["bannedByID"].ToString(), DateTime.Parse(Row["TIME"].ToString()), Row["IP"].ToString(), DateTime.Parse(Row["EXPIRES"].ToString())));
-
- }
-
- return ClientPenalties;
- }
-
- public List GetPenaltiesChronologically(int offset, int count, Penalty.Type penaltyType)
- {
- List ClientPenalties = new List();
- DataTable Result = GetDataTable($"SELECT * FROM BANS {(penaltyType != Penalty.Type.Any ? $"WHERE `TYPE`={(int)penaltyType}" : "")} LIMIT {count} OFFSET (SELECT COUNT(*) FROM BANS {(penaltyType != Penalty.Type.Any ? $"WHERE `TYPE`={(int)penaltyType}" : "")})-{offset + count}");
-
- foreach (DataRow Row in Result.Rows)
- {
- if (Row["TIME"].ToString().Length < 2) //compatibility with my old database
- Row["TIME"] = DateTime.Now.ToString();
-
- var BanType = (Penalty.Type)Enum.Parse(typeof(Penalty.Type), Row["TYPE"].ToString());
- ClientPenalties.Add(new Penalty(BanType, Row["Reason"].ToString().Trim(), Row["npID"].ToString(), Row["bannedByID"].ToString(), DateTime.Parse(Row["TIME"].ToString()), Row["IP"].ToString(), DateTime.Parse(Row["EXPIRES"].ToString())));
- }
-
- return ClientPenalties;
- }
-
- //Returns all players with level > Flagged
- public List GetAdmins()
- {
- List Admins = new List();
- String Query = String.Format("SELECT * FROM CLIENTS WHERE Level >= '{0}' ORDER BY Name", (int)Player.Permission.Trusted);
- DataTable Result = GetDataTable(Query);
-
- foreach (DataRow P in Result.Rows)
- Admins.Add(new Player(P["Name"].ToString(), P["npID"].ToString(), (Player.Permission)P["Level"], P["IP"].ToString(), P["UID"].ToString(), Convert.ToInt32(P["Number"].ToString())));
-
- return Admins;
- }
-
- //Returns total number of player entries in database
- public int TotalPlayers()
- {
- DataTable Result = GetDataTable("SELECT * from CLIENTS ORDER BY Number DESC LIMIT 1");
- if (Result.Rows.Count > 0)
- return Convert.ToInt32(Result.Rows[0]["Number"]);
- else
- return 0;
- }
-
- //Add specified player to database
- public void AddPlayer(Player P)
- {
- Dictionary newPlayer = new Dictionary
- {
- { "Name", P.Name },
- { "npID", P.NetworkID },
- { "Level", (int)P.Level },
- { "LastOffense", "" },
- { "Connections", 1 },
- { "IP", P.IP },
- { "LastConnection", Utilities.DateTimeSQLite(DateTime.Now) },
- { "UID", P.UID },
- { "Masked", Convert.ToInt32(P.Masked) }
- };
- Insert("CLIENTS", newPlayer);
- }
-
- ///Update information of specified player
- public void UpdatePlayer(Player P)
- {
- Dictionary updatedPlayer = new Dictionary
- {
- { "Name", P.Name },
- { "npID", P.NetworkID },
- { "Level", (int)P.Level },
- { "LastOffense", P.lastOffense },
- { "Connections", P.Connections },
- { "IP", P.IP },
- { "LastConnection", Utilities.DateTimeSQLite(DateTime.Now) },
- { "UID", P.UID },
- { "Masked", Convert.ToInt32(P.Masked) }
- };
- Update("CLIENTS", updatedPlayer, new KeyValuePair("npID", P.NetworkID));
- }
-
-
- public void PruneAdmins(int inactiveDays)
- {
- ExecuteNonQuery($"UPDATE CLIENTS SET Level={(int)Player.Permission.User} WHERE LastConnection < '{Utilities.DateTimeSQLite(DateTime.Now.AddDays(-inactiveDays))}'");
- }
-
- //Add specified ban to database
- public void AddPenalty(Penalty B)
- {
- Dictionary newBan = new Dictionary
- {
- { "Reason", B.Reason },
- { "npID", B.OffenderID },
- { "bannedByID", B.PenaltyOriginID },
- { "IP", B.IP },
- { "TIME", Utilities.DateTimeSQLite(DateTime.Now) },
- { "TYPE", B.BType },
- { "EXPIRES", B.Expires }
- };
- Insert("BANS", newBan);
- }
-
-
- //Deletes ban with matching GUID
- public void RemoveBan(String GUID)
- {
- String Query = String.Format("DELETE FROM BANS WHERE npID = '{0}'", GUID);
- ExecuteNonQuery(Query);
- }
-
- public void RemoveBan(String GUID, String IP)
- {
- String Query = String.Format("DELETE FROM BANS WHERE npID = '{0}' or IP = '{1}'", GUID, IP);
- ExecuteNonQuery(Query);
- }
- }
-
- public class AliasesDB : Database
- {
- public AliasesDB(String FN, Interfaces.ILogger logger) : base(FN, logger) { }
-
- public override void Init()
- {
- if (!File.Exists(FileName))
- {
- String Create = "CREATE TABLE [ALIASES] ( [Number] INTEGER, [NAMES] TEXT NULL, [IPS] TEXTNULL );";
- ExecuteNonQuery(Create);
- }
- }
-
- public Aliases GetPlayerAliases(int dbIndex)
- {
- String Query = String.Format("SELECT * FROM ALIASES WHERE Number = '{0}' LIMIT 1", dbIndex);
- DataTable Result = GetDataTable(Query);
-
- if (Result != null && Result.Rows.Count > 0)
- {
- DataRow p = Result.Rows[0];
- return new Aliases(Convert.ToInt32(p["Number"]), p["NAMES"].ToString(), p["IPS"].ToString());
- }
-
- else
- return null;
- }
-
- public List GetPlayerAliases(String IP)
- {
- var Con = GetNewConnection();
- SQLiteCommand cmd = new SQLiteCommand(Con)
- {
- CommandText = "SELECT * FROM ALIASES WHERE IPS LIKE @IP"
- };
- cmd.Parameters.AddWithValue("@IP", $"%{IP}%");
-
- var Result = GetDataTable(cmd);
-
- List players = new List();
-
- if (Result != null && Result.Rows.Count > 0)
- {
- foreach (DataRow p in Result.Rows)
- players.Add(new Aliases(Convert.ToInt32(p["Number"]), p["NAMES"].ToString(), p["IPS"].ToString()));
- }
-
- return players;
- }
-
- public List FindPlayerAliases(String name)
- {
- name = name.Replace("'", "");
- String[] IP = name.Split('.');
- String DefaultIP = "LEGACY_INVALID_IP";
- if (IP.Length > 1)
- DefaultIP = (IP[0] + '.' + IP[1] + '.');
- var Con = GetNewConnection();
-
- SQLiteCommand cmd = new SQLiteCommand(Con)
- {
- CommandText = "SELECT * FROM ALIASES WHERE NAMES LIKE @name OR IPS LIKE @ip LIMIT 15"
- };
- cmd.Parameters.AddWithValue("@name", '%' + name + '%');
- cmd.Parameters.AddWithValue("@ip", '%' + DefaultIP + '%');
-
- var Result = GetDataTable(cmd);
-
-
- List players = new List();
-
- if (Result != null && Result.Rows.Count > 0)
- {
- foreach (DataRow p in Result.Rows)
- players.Add(new Aliases(Convert.ToInt32(p["Number"]), p["NAMES"].ToString(), p["IPS"].ToString()));
- }
-
- return players;
- }
-
- public void AddPlayerAliases(Aliases Alias)
- {
- Dictionary newPlayer = new Dictionary
- {
- { "Number", Alias.Number },
- { "NAMES", String.Join(";", Alias.Names) },
- { "IPS", String.Join(";", Alias.IPS) }
- };
- Insert("ALIASES", newPlayer);
- }
-
- public void UpdatePlayerAliases(Aliases Alias)
- {
- Dictionary updatedPlayer = new Dictionary
- {
- { "Number", Alias.Number },
- { "NAMES", String.Join(";", Alias.Names) },
- { "IPS", String.Join(";", Alias.IPS) }
- };
- Update("ALIASES", updatedPlayer, new KeyValuePair("Number", Alias.Number));
- }
- }
-}
diff --git a/SharedLibrary/Database/IW4MAdminDatabaseContext.cs b/SharedLibrary/Database/IW4MAdminDatabaseContext.cs
new file mode 100644
index 000000000..9ad8d5918
--- /dev/null
+++ b/SharedLibrary/Database/IW4MAdminDatabaseContext.cs
@@ -0,0 +1,49 @@
+using System;
+using System.Collections.Generic;
+using System.Data.Entity;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using SharedLibrary.Database.Models;
+using System.Data.SqlServerCe;
+
+namespace SharedLibrary.Database
+{
+ public class IW4MAdminDatabaseContext : DbContext
+ {
+ public DbSet Clients { get; set; }
+ public DbSet Aliases { get; set; }
+ public DbSet AliasLinks { get; set; }
+ public DbSet Penalties { get; set; }
+
+ public IW4MAdminDatabaseContext() : base("DefaultConnection")
+ {
+ System.Data.Entity.Database.SetInitializer(new Initializer());
+ }
+
+ protected override void OnModelCreating(DbModelBuilder modelBuilder)
+ {
+ modelBuilder.Entity()
+ .HasRequired(p => p.Punisher)
+ .WithMany(c => c.AdministeredPenalties)
+ .HasForeignKey(c => c.PunisherId)
+ .WillCascadeOnDelete(false);
+
+ modelBuilder.Entity()
+ .HasRequired(p => p.Offender)
+ .WithMany(c => c.ReceivedPenalties)
+ .HasForeignKey(c => c.OffenderId)
+ .WillCascadeOnDelete(false);
+
+ modelBuilder.Entity()
+ .HasMany(e => e.Children)
+ .WithRequired(a => a.Link)
+ .HasForeignKey(a => a.LinkId)
+ .WillCascadeOnDelete(true);
+
+ // todo custom load DBSets from plugins
+ // https://aleemkhan.wordpress.com/2013/02/28/dynamically-adding-dbset-properties-in-dbcontext-for-entity-framework-code-first/
+ base.OnModelCreating(modelBuilder);
+ }
+ }
+}
diff --git a/SharedLibrary/Database/Initializer.cs b/SharedLibrary/Database/Initializer.cs
new file mode 100644
index 000000000..a15e6af29
--- /dev/null
+++ b/SharedLibrary/Database/Initializer.cs
@@ -0,0 +1,32 @@
+using System;
+using System.Collections.Generic;
+using System.Data.Entity;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace SharedLibrary.Database
+{
+ public class Initializer : DropCreateDatabaseIfModelChanges
+ {
+ protected override void Seed(IW4MAdminDatabaseContext context)
+ {
+ context.Clients.Add(new Models.EFClient()
+ {
+ Active = false,
+ Connections = 0,
+ AliasLink = new Models.EFAliasLink(),
+ FirstConnection = DateTime.UtcNow,
+ IPAddress = "127.0.0.1",
+ LastConnection = DateTime.UtcNow,
+ Level = Objects.Player.Permission.Console,
+ Name = "IW4MAdmin",
+ Masked = true,
+ NetworkId = "0000000000000000",
+ });
+
+ base.Seed(context);
+ }
+
+ }
+}
diff --git a/SharedLibrary/Database/Models/EFAlias.cs b/SharedLibrary/Database/Models/EFAlias.cs
new file mode 100644
index 000000000..49d035b67
--- /dev/null
+++ b/SharedLibrary/Database/Models/EFAlias.cs
@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations.Schema;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace SharedLibrary.Database.Models
+{
+ public class EFAlias : SharedEntity
+ {
+ [Key]
+ public int AliasId { get; set; }
+ [Required]
+ public int LinkId { get; set; }
+ [ForeignKey("LinkId")]
+ public virtual EFAliasLink Link { get; set; }
+ [Required]
+ public string Name { get; set; }
+ [Required]
+ public string IP { get; set; }
+ [Required]
+ public DateTime DateAdded { get; set; }
+ }
+}
diff --git a/SharedLibrary/Database/Models/EFAliasLink.cs b/SharedLibrary/Database/Models/EFAliasLink.cs
new file mode 100644
index 000000000..fcbc1f838
--- /dev/null
+++ b/SharedLibrary/Database/Models/EFAliasLink.cs
@@ -0,0 +1,17 @@
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+
+namespace SharedLibrary.Database.Models
+{
+ public class EFAliasLink : SharedEntity
+ {
+ [Key]
+ public int AliasLinkId { get; set; }
+ public virtual ICollection Children { get; set; }
+
+ public EFAliasLink()
+ {
+ Children = new List();
+ }
+ }
+}
diff --git a/SharedLibrary/Database/Models/EFClient.cs b/SharedLibrary/Database/Models/EFClient.cs
new file mode 100644
index 000000000..d8cfbfa24
--- /dev/null
+++ b/SharedLibrary/Database/Models/EFClient.cs
@@ -0,0 +1,46 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations.Schema;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace SharedLibrary.Database.Models
+{
+ public class EFClient : SharedEntity
+ {
+ [Key]
+ public int ClientId { get; set; }
+ [Index(IsUnique = true)]
+ public string NetworkId { get; set; }
+
+ [Required]
+ public string Name { get; set; }
+ [Required]
+ public Objects.Player.Permission Level { get; set; }
+ [Required]
+ public int Connections { get; set; }
+ [Required]
+ public int TotalConnectionTime { get; set; }
+ [Required]
+ public string IPAddress { get; set; }
+ [Required]
+ public DateTime FirstConnection { get; set; }
+ [Required]
+ public DateTime LastConnection { get; set; }
+ public bool Masked { get; set; }
+ [Required]
+ public int AliasLinkId { get; set; }
+ [ForeignKey("AliasLinkId")]
+ public virtual EFAliasLink AliasLink { get; set; }
+ public virtual ICollection ReceivedPenalties { get; set; }
+ public virtual ICollection AdministeredPenalties { get; set; }
+
+ public EFClient()
+ {
+ ReceivedPenalties = new List();
+ AdministeredPenalties = new List();
+ }
+ }
+}
diff --git a/SharedLibrary/Database/Models/EFPenalty.cs b/SharedLibrary/Database/Models/EFPenalty.cs
new file mode 100644
index 000000000..624594b19
--- /dev/null
+++ b/SharedLibrary/Database/Models/EFPenalty.cs
@@ -0,0 +1,35 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations.Schema;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace SharedLibrary.Database.Models
+{
+ public class EFPenalty : SharedEntity
+ {
+ [Key]
+ public int PenaltyId { get; set; }
+ [Required]
+ public int LinkId { get; set; }
+ [ForeignKey("LinkId")]
+ public virtual EFAliasLink Link { get; set; }
+ [Required]
+ public int OffenderId { get; set; }
+ [ForeignKey("OffenderId")]
+ public virtual EFClient Offender { get; set; }
+ [Required]
+ public int PunisherId { get; set; }
+ [ForeignKey("PunisherId")]
+ public virtual EFClient Punisher { get; set; }
+ [Required]
+ public DateTime When { get; set; }
+ [Required]
+ public DateTime Expires { get; set; }
+ [Required]
+ public string Offense { get; set; }
+ public Objects.Penalty.PenaltyType Type { get; set; }
+ }
+}
diff --git a/SharedLibrary/Database/Models/SharedEntity.cs b/SharedLibrary/Database/Models/SharedEntity.cs
new file mode 100644
index 000000000..6def65bdb
--- /dev/null
+++ b/SharedLibrary/Database/Models/SharedEntity.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace SharedLibrary.Database.Models
+{
+ public class SharedEntity
+ {
+ public bool Active { get; set; }
+ }
+}
diff --git a/SharedLibrary/Event.cs b/SharedLibrary/Event.cs
index b19dad0d0..9609d863f 100644
--- a/SharedLibrary/Event.cs
+++ b/SharedLibrary/Event.cs
@@ -4,6 +4,8 @@ using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
+using SharedLibrary.Objects;
+
namespace SharedLibrary
{
[Serializable]
@@ -93,7 +95,7 @@ namespace SharedLibrary
public Event(GType t, string d, Player O, Player T, Server S)
{
Type = t;
- Data = d;
+ Data = d.Trim();
Origin = O;
Target = T;
Owner = S;
@@ -129,14 +131,14 @@ namespace SharedLibrary
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]), SV.Players.FirstOrDefault(p => p != null && p.NetworkId == line[2]), SV);
}
if (removeTime.Contains("ExitLevel"))
- return new Event(GType.MapEnd, line[0], new Player("WORLD", "WORLD", 0, 0), null, SV);
+ return new Event(GType.MapEnd, line[0], null, null, SV);
if (removeTime.Contains("InitGame"))
- return new Event(GType.MapChange, line[0], new Player("WORLD", "WORLD", 0, 0), null, SV);
+ return new Event(GType.MapChange, line[0], null, null, SV);
return null;
diff --git a/SharedLibrary/Exceptions/DatabaseException.cs b/SharedLibrary/Exceptions/DatabaseException.cs
new file mode 100644
index 000000000..f4229a5be
--- /dev/null
+++ b/SharedLibrary/Exceptions/DatabaseException.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace SharedLibrary.Exceptions
+{
+ public class DatabaseException : Exception
+ {
+ public DatabaseException(string msg) : base(msg) { }
+ }
+}
diff --git a/SharedLibrary/Helpers/CommandResult.cs b/SharedLibrary/Helpers/CommandResult.cs
new file mode 100644
index 000000000..61c7db18f
--- /dev/null
+++ b/SharedLibrary/Helpers/CommandResult.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace SharedLibrary.Helpers
+{
+ public class CommandResult
+ {
+ public string Message { get; set; }
+ public int Clientd { get; set; }
+ }
+}
diff --git a/SharedLibrary/Interfaces/IEntityService.cs b/SharedLibrary/Interfaces/IEntityService.cs
new file mode 100644
index 000000000..3621e957c
--- /dev/null
+++ b/SharedLibrary/Interfaces/IEntityService.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Linq.Expressions;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace SharedLibrary.Interfaces
+{
+ public interface IEntityService
+ {
+ Task CreateProxy();
+ Task Create(T entity);
+ Task Delete(T entity);
+ Task Update(T entity);
+ Task Get(int entityID);
+ Task GetUnique(string entityProperty);
+ Task> Find(Func expression);
+ }
+}
diff --git a/SharedLibrary/Interfaces/IManager.cs b/SharedLibrary/Interfaces/IManager.cs
index 943984873..99344b486 100644
--- a/SharedLibrary/Interfaces/IManager.cs
+++ b/SharedLibrary/Interfaces/IManager.cs
@@ -1,4 +1,7 @@
using System.Collections.Generic;
+using SharedLibrary.Objects;
+using SharedLibrary.Database.Models;
+using SharedLibrary.Services;
namespace SharedLibrary.Interfaces
{
@@ -10,13 +13,10 @@ namespace SharedLibrary.Interfaces
ILogger GetLogger();
IList GetServers();
IList GetCommands();
- IPenaltyList GetClientPenalties();
- ClientsDB GetClientDatabase();
- AliasesDB GetAliasesDatabase();
IList GetMessageTokens();
IList GetActiveClients();
- IList GetAliasClients(Player player);
- IList GetAliases(Player player);
- IList GetPrivilegedClients();
+ ClientService GetClientService();
+ AliasService GetAliasService();
+ PenaltyService GetPenaltyService();
}
}
diff --git a/SharedLibrary/Interfaces/IPenaltyList.cs b/SharedLibrary/Interfaces/IPenaltyList.cs
deleted file mode 100644
index 3a85b9f65..000000000
--- a/SharedLibrary/Interfaces/IPenaltyList.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace SharedLibrary.Interfaces
-{
- public interface IPenaltyList
- {
- void AddPenalty(Penalty P);
- void RemovePenalty(Penalty P);
- List FindPenalties(Player P);
- }
-}
diff --git a/SharedLibrary/Objects/Alias.cs b/SharedLibrary/Objects/Alias.cs
new file mode 100644
index 000000000..c38554876
--- /dev/null
+++ b/SharedLibrary/Objects/Alias.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace SharedLibrary.Objects
+{
+ public class Alias : Database.Models.EFAlias
+ {
+
+ }
+}
diff --git a/SharedLibrary/Objects/Penalty.cs b/SharedLibrary/Objects/Penalty.cs
new file mode 100644
index 000000000..d4b69a933
--- /dev/null
+++ b/SharedLibrary/Objects/Penalty.cs
@@ -0,0 +1,24 @@
+using System;
+using SharedLibrary;
+
+namespace SharedLibrary.Objects
+{
+ public class Penalty : Database.Models.EFPenalty
+ {
+ public enum PenaltyType
+ {
+ Report,
+ Warning,
+ Flag,
+ Kick,
+ TempBan,
+ Ban,
+ Any,
+ }
+
+ public String GetWhenFormatted()
+ {
+ return When.ToString("MM/dd/yy HH:mm:ss"); ;
+ }
+ }
+}
diff --git a/SharedLibrary/Objects/Player.cs b/SharedLibrary/Objects/Player.cs
new file mode 100644
index 000000000..a642b9bb9
--- /dev/null
+++ b/SharedLibrary/Objects/Player.cs
@@ -0,0 +1,76 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations.Schema;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace SharedLibrary.Objects
+{
+ public class Player : Database.Models.EFClient
+ {
+ public enum Permission
+ {
+ Banned = -1,
+ User = 0,
+ Flagged = 1,
+ Trusted = 2,
+ Moderator = 3,
+ Administrator = 4,
+ SeniorAdmin = 5,
+ Owner = 6,
+ Creator = 7,
+ Console = 8,
+ }
+
+ public Player()
+ {
+ ConnectionTime = DateTime.UtcNow;
+ }
+
+ public override string ToString()
+ {
+ return $"{Name}::{NetworkId}";
+ }
+
+ public String GetLastConnection()
+ {
+ return Utilities.GetTimePassed(LastConnection);
+ }
+
+ public async Task Tell(String Message)
+ {
+ await CurrentServer.Tell(Message, this);
+ }
+
+ public async Task Kick(String Message, Player Sender)
+ {
+ await CurrentServer.Kick(Message, this, Sender);
+ }
+
+ public async Task TempBan(String Message, TimeSpan Length, Player Sender)
+ {
+ await CurrentServer.TempBan(Message, Length, this, Sender);
+ }
+
+ public async Task Warn(String Message, Player Sender)
+ {
+ await CurrentServer.Warn(Message, this, Sender);
+ }
+
+ public async Task Ban(String Message, Player Sender)
+ {
+ await CurrentServer.Ban(Message, this, Sender);
+ }
+
+ [NotMapped]
+ public int ClientNumber { get; set; }
+ [NotMapped]
+ public int Ping { get; set; }
+ [NotMapped]
+ public int Warnings { get; set; }
+ [NotMapped]
+ public DateTime ConnectionTime { get; set; }
+ [NotMapped]
+ public Server CurrentServer { get; set; }
+ }
+}
diff --git a/SharedLibrary/Objects/Report.cs b/SharedLibrary/Objects/Report.cs
new file mode 100644
index 000000000..e1955dff1
--- /dev/null
+++ b/SharedLibrary/Objects/Report.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace SharedLibrary.Objects
+{
+ public class Report
+ {
+ public Report(Player T, Player O, String R)
+ {
+ Target = T;
+ Origin = O;
+ Reason = R;
+ }
+
+ public Player Target { get; private set; }
+ public Player Origin { get; private set; }
+ public String Reason { get; private set; }
+ }
+}
diff --git a/SharedLibrary/Penalty.cs b/SharedLibrary/Penalty.cs
deleted file mode 100644
index e2b5627ed..000000000
--- a/SharedLibrary/Penalty.cs
+++ /dev/null
@@ -1,57 +0,0 @@
-using System;
-using SharedLibrary;
-
-namespace SharedLibrary
-{
- public class Penalty
- {
- public Penalty(Type BType, String Reas, String TargID, String From, DateTime time, String ip, DateTime exp)
- {
- Reason = Reas.StripColors();
- OffenderID = TargID;
- PenaltyOriginID = From;
- When = time;
- Expires = exp;
- IP = ip;
- this.BType = BType;
- }
-
- public String GetWhenFormatted()
- {
- return When.ToString("MM/dd/yy HH:mm:ss"); ;
- }
-
- public enum Type
- {
- Report,
- Warning,
- Flag,
- Kick,
- TempBan,
- Ban,
- Any,
- }
-
- public String Reason { get; private set; }
- public String OffenderID { get; private set; }
- public String PenaltyOriginID { get; private set; }
- public DateTime When { get; private set; }
- public DateTime Expires { get; private set; }
- public String IP { get; private set; }
- public Type BType { get; private set; }
- }
-
- public class Report
- {
- public Report(Player T, Player O, String R)
- {
- Target = T;
- Origin = O;
- Reason = R;
- }
-
- public Player Target { get; private set; }
- public Player Origin { get; private set; }
- public String Reason { get; private set; }
- }
-}
diff --git a/SharedLibrary/Player.cs b/SharedLibrary/Player.cs
deleted file mode 100644
index 9513a0856..000000000
--- a/SharedLibrary/Player.cs
+++ /dev/null
@@ -1,184 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
-
-namespace SharedLibrary
-{
- public class Aliases
- {
- public Aliases(int Num, String N, String I)
- {
- Number = Num;
- Names = N.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries).Select(s => s.Trim()).ToList();
- IPS = new List(I.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries));
- }
-
- public List Names { get; private set; }
- public List IPS { get; private set; }
- public int Number { get; private set; }
- }
-
- public class Player
- {
- public enum Permission
- {
- Banned = -1,
- User = 0,
- Flagged = 1,
- Trusted = 2,
- Moderator = 3,
- Administrator = 4,
- SeniorAdmin = 5,
- Owner = 6,
- Creator = 7,
- Console = 8,
- }
-
- public override int GetHashCode()
- {
- return base.GetHashCode();
- }
-
- public Player(string n, string id, int num, int l)
- {
- Name = n;
- NetworkID = id;
- ClientID = num;
- Level = (Player.Permission)l;
- lastOffense = String.Empty;
- Connections = 0;
- IP = "";
- Warnings = 0;
- Alias = new Aliases(0, "", "");
- LastConnection = DateTime.Now;
-
- }
-
- public Player(string n, string id, int num, String I)
- {
- Name = n;
- NetworkID = id;
- ClientID = num;
- IP = I;
- LastConnection = DateTime.Now;
- }
-
- public Player(String n, String id, Player.Permission P, String I, String UID, int dbid)
- {
- Name = n;
- NetworkID = id;
- Level = P;
- IP = I;
- ClientID = -1;
- this.UID = UID;
- DatabaseID = dbid;
- }
-
- public Player(string n, string id, int num, Player.Permission l, int cind, String lo, int con, String IP2)
- {
- Name = n;
- NetworkID = id;
- ClientID = num;
- Level = l;
- DatabaseID = cind;
- if (lo == null)
- lastOffense = String.Empty;
- else
- lastOffense = lo;
- Connections = con;
- IP = IP2;
- Warnings = 0;
- Masked = false;
- LastConnection = DateTime.Now;
- }
-
- public Player(string n, string id, int num, Player.Permission l, int cind, String lo, int con, String IP2, DateTime LC, string UID, bool masked)
- {
- Name = n;
- NetworkID = id;
- ClientID = num;
- Level = l;
- DatabaseID = cind;
- if (lo == null)
- lastOffense = String.Empty;
- else
- lastOffense = lo;
- Connections = con;
- IP = IP2;
- Warnings = 0;
- Masked = false;
- LastConnection = LC;
- this.UID = UID.Trim();
- Masked = masked;
- }
-
- public override string ToString()
- {
- return $"{Name}::{NetworkID}";
- }
-
- public String GetLastConnection()
- {
- return Utilities.GetTimePassed(LastConnection);
- }
-
- public void UpdateName(String n)
- {
- if (n.Trim() != String.Empty)
- Name = n;
- }
-
- public void SetIP(String I)
- {
- IP = I;
- }
-
- public void SetLevel(Permission Perm)
- {
- Level = Perm;
- }
-
- public async Task Tell(String Message)
- {
- await lastEvent.Owner.Tell(Message, this);
- }
-
- public async Task Kick(String Message, Player Sender)
- {
- await lastEvent.Owner.Kick(Message, this, Sender);
- }
-
- public async Task TempBan(String Message, TimeSpan Length, Player Sender)
- {
- await lastEvent.Owner.TempBan(Message, Length, this, Sender);
- }
-
- public async Task Warn(String Message, Player Sender)
- {
- await lastEvent.Owner.Warn(Message, this, Sender);
- }
-
- public async Task Ban(String Message, Player Sender)
- {
- await lastEvent.Owner.Ban(Message, this, Sender);
- }
-
- public String Name { get; private set; }
- public string NetworkID { get; private set; }
- public int ClientID { get; private set; }
- public Permission Level { get; private set; }
- public int DatabaseID { get; private set; }
- public int Connections { get; set; }
- public String IP { get; private set; }
- public String UID { get; private set; }
- public DateTime LastConnection { get; private set; }
- public int Ping;
-
- public Event lastEvent;
- public String lastOffense;
- public int Warnings;
- public Aliases Alias;
- public bool Masked;
- }
-}
diff --git a/SharedLibrary/RCON.cs b/SharedLibrary/RCON.cs
index afc1c4217..138f82849 100644
--- a/SharedLibrary/RCON.cs
+++ b/SharedLibrary/RCON.cs
@@ -8,6 +8,8 @@ using System.Threading.Tasks;
using System.Text.RegularExpressions;
using System.Net.Sockets;
+using SharedLibrary.Objects;
+
namespace SharedLibrary.Network
{
public static class RCON
diff --git a/SharedLibrary/Server.cs b/SharedLibrary/Server.cs
index b83ddb44f..2335eac31 100644
--- a/SharedLibrary/Server.cs
+++ b/SharedLibrary/Server.cs
@@ -9,6 +9,7 @@ using SharedLibrary.Network;
using SharedLibrary.Commands;
using System.Threading.Tasks;
using SharedLibrary.Helpers;
+using SharedLibrary.Objects;
namespace SharedLibrary
{
@@ -106,13 +107,6 @@ namespace SharedLibrary
return Players.Where(p => p != null && p.Name.ToLower().Contains(pName.ToLower())).ToList();
}
- ///
- /// Check ban list for every banned player and return ban if match is found
- ///
- /// Player to check if banned
- /// Matching ban if found
- abstract public Penalty IsBanned(Player C);
-
///
/// Process requested command correlating to an event
///
@@ -126,16 +120,6 @@ namespace SharedLibrary
return null;
}
- ///
- /// Legacy method for the alias command
- ///
- ///
- ///
- public IList GetAliases(Player P)
- {
- return Manager.GetAliases(P);
- }
-
///
/// Process any server event
///
@@ -170,14 +154,10 @@ namespace SharedLibrary
/// Player to send message to
public async Task Tell(String Message, Player Target)
{
-#if DEBUG
- //if (!Target.lastEvent.Remote)
- // return;
-#endif
string tellCommand = (GameName == Game.IW4) ? "tellraw" : "tell";
- if (Target.ClientID > -1 && Message.Length > 0 && Target.Level != Player.Permission.Console && !Target.lastEvent.Remote)
- await this.ExecuteCommandAsync($"{tellCommand} {Target.ClientID} {Message}^7");
+ if (Target.ClientNumber > -1 && Message.Length > 0 && Target.Level != Player.Permission.Console)
+ await this.ExecuteCommandAsync($"{tellCommand} {Target.ClientNumber} {Message}^7");
if (Target.Level == Player.Permission.Console)
{
@@ -185,9 +165,13 @@ namespace SharedLibrary
Console.WriteLine(Utilities.StripColors(Message));
Console.ForegroundColor = ConsoleColor.Gray;
}
-
- if (Target.lastEvent.Remote)
- commandResult.Enqueue(Utilities.StripColors(Message));
+ if (commandResult.Count > 15)
+ commandResult.RemoveAt(0);
+ commandResult.Add(new CommandResult()
+ {
+ Message = Utilities.StripColors(Message),
+ Clientd = Target.ClientId
+ });
}
///
@@ -353,14 +337,14 @@ namespace SharedLibrary
return $"{IP}_{Port}";
}
- protected async Task ScriptLoaded()
+ protected async Task ScriptLoaded()
{
try
{
return (await this.GetDvarAsync("sv_customcallbacks")).Value == "1";
}
-
- catch(Exceptions.DvarException)
+
+ catch (Exceptions.DvarException)
{
return false;
}
@@ -408,6 +392,6 @@ namespace SharedLibrary
protected DateTime LastPoll;
//Remote
- public Queue commandResult = new Queue();
+ public IList commandResult = new List();
}
}
diff --git a/SharedLibrary/Services/AliasService.cs b/SharedLibrary/Services/AliasService.cs
new file mode 100644
index 000000000..a19c17fe9
--- /dev/null
+++ b/SharedLibrary/Services/AliasService.cs
@@ -0,0 +1,84 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Linq.Expressions;
+using System.Data.Entity;
+
+using SharedLibrary.Interfaces;
+using SharedLibrary.Database.Models;
+using SharedLibrary.Database;
+
+namespace SharedLibrary.Services
+{
+ public class AliasService : IEntityService
+ {
+ public async Task Create(EFAlias entity)
+ {
+ using (var context = new IW4MAdminDatabaseContext())
+ {
+ entity.Link = await context.AliasLinks.FirstAsync(a => a.AliasLinkId == entity.Link.AliasLinkId);
+ var addedEntity = context.Aliases.Add(entity);
+ await context.SaveChangesAsync();
+ return addedEntity;
+ }
+ }
+
+ public Task CreateProxy()
+ {
+ return null;
+ }
+
+ public async Task Delete(EFAlias entity)
+ {
+ using (var context = new IW4MAdminDatabaseContext())
+ {
+ entity = context.Aliases.Single(e => e.AliasId == entity.AliasId);
+ entity.Active = false;
+ context.Entry(entity).State = EntityState.Modified;
+ await context.SaveChangesAsync();
+ return entity;
+ }
+ }
+
+ public async Task> Find(Func expression)
+ {
+ using (var context = new IW4MAdminDatabaseContext())
+ return await Task.Run(() => context.Aliases.Where(expression).ToList());
+ }
+
+ public async Task Get(int entityID)
+ {
+ using (var context = new IW4MAdminDatabaseContext())
+ return await context.Aliases
+ .SingleOrDefaultAsync(e => e.AliasId == entityID);
+ }
+
+ public Task GetUnique(string entityProperty)
+ {
+ throw new NotImplementedException();
+ }
+
+ public async Task Update(EFAlias entity)
+ {
+ using (var context = new IW4MAdminDatabaseContext())
+ {
+ entity = context.Aliases.Attach(entity);
+ context.Entry(entity).State = EntityState.Modified;
+ await context.SaveChangesAsync();
+ return entity;
+ }
+ }
+
+ public async Task CreateLink(EFAliasLink link)
+ {
+ using (var context = new IW4MAdminDatabaseContext())
+ {
+ context.AliasLinks.Add(link);
+ await context.SaveChangesAsync();
+ return link;
+ }
+ }
+ }
+}
diff --git a/SharedLibrary/Services/ClientService.cs b/SharedLibrary/Services/ClientService.cs
new file mode 100644
index 000000000..214fe9c99
--- /dev/null
+++ b/SharedLibrary/Services/ClientService.cs
@@ -0,0 +1,158 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Data.Entity;
+
+using SharedLibrary.Database;
+using SharedLibrary.Database.Models;
+using System.Linq.Expressions;
+
+namespace SharedLibrary.Services
+{
+ public class ClientService : Interfaces.IEntityService
+ {
+ private Dictionary _context;
+
+ public ClientService()
+ {
+ _context = new Dictionary();
+ }
+ public async Task Create(EFClient entity)
+ {
+ using (var context = new IW4MAdminDatabaseContext())
+ {
+
+ // get all aliases by IP
+ var alias = await context.Aliases.FirstOrDefaultAsync(a => a.IP == entity.IPAddress);
+ EFAliasLink link = alias?.Link;
+
+ var client = new EFClient()
+ {
+ Active = true,
+ Name = entity.Name,
+ FirstConnection = DateTime.UtcNow,
+ Connections = 1,
+ IPAddress = entity.IPAddress,
+ LastConnection = DateTime.UtcNow,
+ Level = Objects.Player.Permission.User,
+ Masked = false,
+ NetworkId = entity.NetworkId,
+ AliasLink = link ?? new EFAliasLink() { Active = true }
+ };
+
+ client.AliasLink.Children.Add(new EFAlias()
+ {
+ Active = true,
+ DateAdded = DateTime.UtcNow,
+ IP = entity.IPAddress,
+ Link = client.AliasLink,
+ Name = entity.Name
+ });
+
+ context.Clients.Add(client);
+ await context.SaveChangesAsync();
+
+ return client;
+ }
+ }
+
+ public async Task Delete(EFClient entity)
+ {
+ using (var context = new IW4MAdminDatabaseContext())
+ {
+ entity = context.Clients.Single(e => e.ClientId == entity.ClientId);
+ entity.Active = false;
+ entity.Level = Objects.Player.Permission.User;
+ context.Entry(entity).State = EntityState.Modified;
+ await context.SaveChangesAsync();
+ return entity;
+ }
+ }
+
+ public async Task> Find(Func e)
+ {
+ using (var context = new IW4MAdminDatabaseContext())
+ return await Task.Run(() => context.Clients
+ .Include(c => c.AliasLink.Children)
+ .Where(e).ToList());
+ }
+
+ public async Task Get(int entityID)
+ {
+ using (var context = new IW4MAdminDatabaseContext())
+ return await new IW4MAdminDatabaseContext().Clients
+ .Include(c => c.AliasLink.Children)
+ .SingleOrDefaultAsync(e => e.ClientId == entityID);
+ }
+
+ public async Task GetUnique(string entityAttribute)
+ {
+ using (var context = new IW4MAdminDatabaseContext())
+ {
+ return await context.Clients
+ .Include(c => c.AliasLink.Children)
+ .SingleOrDefaultAsync(c => c.NetworkId == entityAttribute);
+ }
+ }
+
+ public async Task Update(EFClient entity)
+ {
+ using (var context = new IW4MAdminDatabaseContext())
+ {
+ entity = context.Clients.Attach(entity);
+ context.Entry(entity).State = EntityState.Modified;
+ await context.SaveChangesAsync();
+ return entity;
+ }
+ }
+
+ #region ServiceSpecific
+ public async Task> GetOwners()
+ {
+ using (var context = new IW4MAdminDatabaseContext())
+ return await context.Clients.Where(c => c.Level == Objects.Player.Permission.Owner).ToListAsync();
+ }
+
+ public async Task> GetPrivilegedClients()
+ {
+ using (var context = new IW4MAdminDatabaseContext())
+ return await new IW4MAdminDatabaseContext().Clients
+ .Where(c => c.Level >= Objects.Player.Permission.Trusted)
+ .ToListAsync();
+ }
+
+
+ public async Task> GetRecentClients(int offset, int count)
+ {
+ using (var context = new IW4MAdminDatabaseContext())
+ return await context.Clients.OrderByDescending(p => p.ClientId).Skip(offset).Take(count).ToListAsync();
+ }
+
+ public async Task> PruneInactivePrivilegedClients(int inactiveDays)
+ {
+ using (var context = new IW4MAdminDatabaseContext())
+ {
+ var inactive = await context.Clients.Where(c => c.Level > Objects.Player.Permission.Flagged)
+ .Where(c => (DateTime.UtcNow - c.LastConnection).TotalDays >= inactiveDays)
+ .ToListAsync();
+ inactive.ForEach(c => c.Level = Objects.Player.Permission.User);
+ await context.SaveChangesAsync();
+ return inactive;
+ }
+ }
+
+ public async Task GetTotalClientsAsync()
+ {
+ using (var context = new IW4MAdminDatabaseContext())
+ return await context.Clients.CountAsync();
+ }
+
+ public Task CreateProxy()
+ {
+ throw new NotImplementedException();
+ }
+ #endregion
+ }
+}
diff --git a/SharedLibrary/Services/PenaltyService.cs b/SharedLibrary/Services/PenaltyService.cs
new file mode 100644
index 000000000..d2237b36b
--- /dev/null
+++ b/SharedLibrary/Services/PenaltyService.cs
@@ -0,0 +1,117 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Data.Entity;
+
+using SharedLibrary.Database;
+using SharedLibrary.Database.Models;
+using System.Linq.Expressions;
+
+namespace SharedLibrary.Services
+{
+ public class PenaltyService : Interfaces.IEntityService
+ {
+ public async Task Create(EFPenalty entity)
+ {
+ using (var context = new IW4MAdminDatabaseContext())
+ {
+ entity.Offender = context.Clients.First(e => e.ClientId == entity.Offender.ClientId);
+ entity.Punisher = context.Clients.First(e => e.ClientId == entity.Punisher.ClientId);
+ entity.Link = context.AliasLinks.First(l => l.AliasLinkId == entity.Link.AliasLinkId);
+ if (entity.Expires == DateTime.MinValue)
+ entity.Expires = DateTime.Parse(System.Data.SqlTypes.SqlDateTime.MaxValue.ToString());
+ context.Penalties.Add(entity);
+ await context.SaveChangesAsync();
+ return entity;
+ }
+ }
+
+ public Task CreateProxy()
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task Delete(EFPenalty entity)
+ {
+ throw new NotImplementedException();
+ }
+
+ public async Task> Find(Func expression)
+ {
+ using (var context = new IW4MAdminDatabaseContext())
+ {
+ return await Task.Run(() => context.Penalties
+ .Include(p => p.Offender)
+ .Include(p => p.Punisher)
+ .Where(expression)
+ .Where(p => p.Active)
+ .ToList());
+ }
+ }
+
+ public Task Get(int entityID)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task GetUnique(string entityProperty)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task Update(EFPenalty entity)
+ {
+ throw new NotImplementedException();
+ }
+
+ public async Task> GetRecentPenalties(int count, int offset)
+ {
+ using (var context = new IW4MAdminDatabaseContext())
+ return await context.Penalties
+ .Include(p => p.Offender)
+ .Include(p => p.Punisher)
+ .Where(p => p.Active)
+ .OrderByDescending(p => p.When)
+ .Skip(offset)
+ .Take(count)
+ .ToListAsync();
+ }
+
+ public async Task> GetClientPenaltiesAsync(int clientId)
+ {
+ using (var context = new IW4MAdminDatabaseContext())
+ return await context.Penalties
+ .Where(p => p.OffenderId == clientId)
+ .Where(p => p.Active)
+ .Include(p => p.Offender)
+ .Include(p => p.Punisher)
+ .ToListAsync();
+ }
+
+ public async Task RemoveActivePenalties(int aliasLinkId)
+ {
+ using (var context = new IW4MAdminDatabaseContext())
+ {
+ var now = DateTime.UtcNow;
+ var penalties = await context.Penalties
+ .Include(p => p.Link.Children)
+ .Where(p => p.LinkId == aliasLinkId)
+ .Where(p => p.Expires > now)
+ .ToListAsync();
+
+ penalties.ForEach(async p =>
+ {
+ p.Active = false;
+ var clients = await context.Clients.Where(cl => cl.AliasLinkId == p.LinkId).ToListAsync();
+ foreach (var c in clients)
+ if (c.Level == Objects.Player.Permission.Banned)
+ c.Level = Objects.Player.Permission.User;
+ });
+
+ await context.SaveChangesAsync();
+ }
+ }
+ }
+}
diff --git a/SharedLibrary/SharedLibrary.csproj b/SharedLibrary/SharedLibrary.csproj
index 77a372a3e..51b5e1f02 100644
--- a/SharedLibrary/SharedLibrary.csproj
+++ b/SharedLibrary/SharedLibrary.csproj
@@ -66,13 +66,24 @@
true
+
+ ..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.dll
+
+
+ ..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.SqlServer.dll
+
+
+ ..\packages\EntityFramework.SqlServerCompact.6.2.0\lib\net45\EntityFramework.SqlServerCompact.dll
+
..\packages\Newtonsoft.Json.10.0.2\lib\net45\Newtonsoft.Json.dll
+ False
+
-
- ..\packages\System.Data.SQLite.Core.1.0.105.1\lib\net45\System.Data.SQLite.dll
+
+ ..\packages\Microsoft.SqlServer.Compact.4.0.8876.1\lib\net40\System.Data.SqlServerCe.dll
True
@@ -83,6 +94,14 @@
+
+
+
+
+
+
+
+
@@ -90,29 +109,34 @@
+
+
-
-
+
+
-
-
+
+
+
+
+
@@ -134,15 +158,12 @@ copy /Y "$(TargetDir)System.Data.SQLite.dll" "$(SolutionDir)Admin\lib"
copy /Y "$(TargetDir)$(TargetName).dll" "$(SolutionDir)BUILD\lib"
copy /Y "$(TargetDir)$(TargetName).dll" "$(SolutionDir)Admin\lib"
copy /Y "$(TargetDir)Newtonsoft.Json.dll" "$(SolutionDir)BUILD\lib"
-copy /Y "$(TargetDir)Newtonsoft.Json.dll" "$(SolutionDir)Admin\lib"
+copy /Y "$(TargetDir)Newtonsoft.Json.dll" "$(SolutionDir)Admin\lib"
+ if not exist "$(TargetDir)x86" md "$(TargetDir)x86"
+ xcopy /s /y "$(SolutionDir)packages\Microsoft.SqlServer.Compact.4.0.8876.1\NativeBinaries\x86\*.*" "$(TargetDir)x86"
+ if not exist "$(TargetDir)amd64" md "$(TargetDir)amd64"
+ xcopy /s /y "$(SolutionDir)packages\Microsoft.SqlServer.Compact.4.0.8876.1\NativeBinaries\amd64\*.*" "$(TargetDir)amd64"
-
-
-
- This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
-
-
-
if exist "$(SolutionDir)BUILD\Plugins" rmdir /Q /S "$(SolutionDir)BUILD\Plugins"
mkdir "$(SolutionDir)BUILD\Plugins"
diff --git a/SharedLibrary/Utilities.cs b/SharedLibrary/Utilities.cs
index 8df15c780..9dddeb6c4 100644
--- a/SharedLibrary/Utilities.cs
+++ b/SharedLibrary/Utilities.cs
@@ -4,6 +4,8 @@ using System.Text;
using System.Text.RegularExpressions;
using System.Linq;
using System.Collections.Generic;
+
+using SharedLibrary.Objects;
using static SharedLibrary.Server;
namespace SharedLibrary
@@ -60,7 +62,7 @@ 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(cName, npID, cID, cIP) { Ping = Ping };
+ Player P = new Player() { Name = cName, NetworkId = npID, ClientNumber = cID, IPAddress = cIP, Ping = Ping };
StatusPlayers.Add(P);
}
}
@@ -224,7 +226,7 @@ namespace SharedLibrary
}
if (Elapsed.TotalDays <= 365)
{
- if (Elapsed.TotalDays < 1.5)
+ if (Elapsed.TotalDays < 1.5)
return $"1 day{ago}";
return Math.Round(Elapsed.TotalDays, 0) + $" days{ago}";
}
@@ -297,5 +299,26 @@ namespace SharedLibrary
{
return markdownString.Replace("<", "\\<").Replace(">", "\\>").Replace("|", "\\|");
}
+
+ public static Player AsPlayer(this Database.Models.EFClient client)
+ {
+ return client == null ? null : new Player()
+ {
+ Active = client.Active,
+ AliasLink =client.AliasLink,
+ AliasLinkId = client.AliasLinkId,
+ ClientId = client.ClientId,
+ ClientNumber = 0,
+ FirstConnection = client.FirstConnection,
+ Connections = client.Connections,
+ IPAddress = client.IPAddress,
+ NetworkId = client.NetworkId,
+ Name = client.Name,
+ Level = client.Level,
+ TotalConnectionTime = client.TotalConnectionTime,
+ Masked = client.Masked,
+ LastConnection = DateTime.UtcNow
+ };
+ }
}
}
diff --git a/SharedLibrary/WebService.cs b/SharedLibrary/WebService.cs
index 0f9d36a0a..7b1bcc126 100644
--- a/SharedLibrary/WebService.cs
+++ b/SharedLibrary/WebService.cs
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Text;
+using System.Threading.Tasks;
namespace SharedLibrary
{
@@ -27,7 +28,7 @@ namespace SharedLibrary
{
string GetPath();
string GetName();
- HttpResponse GetPage(System.Collections.Specialized.NameValueCollection querySet, IDictionary headers);
+ Task GetPage(System.Collections.Specialized.NameValueCollection querySet, IDictionary headers);
bool Visible();
}
@@ -89,7 +90,7 @@ namespace SharedLibrary
abstract public string GetContent(System.Collections.Specialized.NameValueCollection querySet, IDictionary headers);
- public HttpResponse GetPage(System.Collections.Specialized.NameValueCollection querySet, IDictionary headers)
+ public async Task GetPage(System.Collections.Specialized.NameValueCollection querySet, IDictionary headers)
{
HttpResponse resp = new HttpResponse()
{
diff --git a/SharedLibrary/packages.config b/SharedLibrary/packages.config
index 9c77c3fa3..975fcdfe8 100644
--- a/SharedLibrary/packages.config
+++ b/SharedLibrary/packages.config
@@ -1,5 +1,7 @@
+