Moved from SQLITE to EntityFramework.

Lots of things are broken!
This commit is contained in:
RaidMax 2017-11-25 19:29:58 -06:00
parent c56d98d11c
commit 23eb641113
61 changed files with 1690 additions and 1685 deletions

View File

@ -144,7 +144,6 @@
<Compile Include="Logger.cs" /> <Compile Include="Logger.cs" />
<Compile Include="Main.cs" /> <Compile Include="Main.cs" />
<Compile Include="Manager.cs" /> <Compile Include="Manager.cs" />
<Compile Include="PenaltyList.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Properties\Settings.Designer.cs"> <Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen> <AutoGen>True</AutoGen>
@ -182,12 +181,6 @@
<Content Include="Lib\SharedLibrary.dll"> <Content Include="Lib\SharedLibrary.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content> </Content>
<Content Include="Lib\SQLite.Interop.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Lib\System.Data.SQLite.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="version.txt"> <Content Include="version.txt">
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content> </Content>
@ -245,7 +238,9 @@
<Content Include="Config\web.cfg"> <Content Include="Config\web.cfg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content> </Content>
<None Include="IW4MAdmin.exe.config" /> <None Include="IW4MAdmin.exe.config">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="packages.config" /> <None Include="packages.config" />
<None Include="Properties\app.manifest" /> <None Include="Properties\app.manifest" />
<None Include="Properties\Settings.settings"> <None Include="Properties\Settings.settings">
@ -363,6 +358,7 @@ copy /Y "$(SolutionDir)_customcallbacks.gsc" "$(SolutionDir)BUILD\userraw\script
copy /Y "$(TargetDir)$(TargetName).exe" "$(SolutionDir)BUILD" copy /Y "$(TargetDir)$(TargetName).exe" "$(SolutionDir)BUILD"
copy /Y "$(TargetDir)IW4MAdmin.exe.config" "$(SolutionDir)BUILD" copy /Y "$(TargetDir)IW4MAdmin.exe.config" "$(SolutionDir)BUILD"
copy /Y "$(ProjectDir)lib\Kayak.dll" "$(SolutionDir)BUILD\lib" 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 "$(ProjectDir)webfront\*" "$(SolutionDir)BUILD\Webfront"
xcopy /Y /I /E "$(SolutionDir)Admin\Config\*" "$(SolutionDir)BUILD\Config" xcopy /Y /I /E "$(SolutionDir)Admin\Config\*" "$(SolutionDir)BUILD\Config"

View File

@ -1,11 +1,37 @@
<?xml version="1.0"?> <?xml version="1.0" encoding="utf-8"?>
<configuration> <configuration>
<configSections>
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
</configSections>
<startup> <startup>
<supportedRuntime version="v4.5" sku=".NETFramework,Version=v4.5"/> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/>
</startup> </startup>
<runtime> <runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="lib"/> <probing privatePath="lib"/>
</assemblyBinding> </assemblyBinding>
</runtime> </runtime>
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlCeConnectionFactory, EntityFramework">
<parameters>
<parameter value="System.Data.SqlServerCe.4.0" />
</parameters>
</defaultConnectionFactory>
<providers>
<provider invariantName="System.Data.SqlServerCe.4.0" type="System.Data.Entity.SqlServerCompact.SqlCeProviderServices, EntityFramework.SqlServerCompact" />
</providers>
</entityFramework>
<system.data>
<DbProviderFactories>
<remove invariant="System.Data.SqlServerCe.4.0" />
<add name="Microsoft SQL Server Compact Data Provider 4.0" invariant="System.Data.SqlServerCe.4.0" description=".NET Framework Data Provider for Microsoft SQL Server Compact" type="System.Data.SqlServerCe.SqlCeProviderFactory, System.Data.SqlServerCe, Version=4.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91" />
</DbProviderFactories>
</system.data>
<connectionStrings>
<add name="DefaultConnection"
providerName="System.Data.SqlServerCe.4.0"
connectionString="Data Source=Database\Database.sdf"/>
</connectionStrings>
</configuration> </configuration>

View File

@ -6,6 +6,11 @@ using SharedLibrary;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.IO; using System.IO;
#if DEBUG
using SharedLibrary.Database;
using SharedLibrary.Objects;
#endif
namespace IW4MAdmin namespace IW4MAdmin
{ {
class Program class Program
@ -38,7 +43,7 @@ namespace IW4MAdmin
Task.Run(() => Task.Run(() =>
{ {
String userInput; String userInput;
Player Origin = new Player("IW4MAdmin", "", -1, Player.Permission.Console, -1, "", 0, ""); Player Origin = ServerManager.GetClientService().Get(1).Result.AsPlayer();
do do
{ {
@ -50,8 +55,8 @@ namespace IW4MAdmin
if (ServerManager.Servers.Count == 0) if (ServerManager.Servers.Count == 0)
return; return;
Origin.CurrentServer = ServerManager.Servers[0];
Event E = new Event(Event.GType.Say, userInput, Origin, null, ServerManager.Servers[0]); Event E = new Event(Event.GType.Say, userInput, Origin, null, ServerManager.Servers[0]);
Origin.lastEvent = E;
ServerManager.Servers[0].ExecuteEvent(E); ServerManager.Servers[0].ExecuteEvent(E);
Console.Write('>'); Console.Write('>');
@ -60,7 +65,7 @@ namespace IW4MAdmin
} }
catch(Exception e) catch (Exception e)
{ {
Console.WriteLine($"Fatal Error during initialization: {e.Message}"); Console.WriteLine($"Fatal Error during initialization: {e.Message}");
Console.WriteLine("Press any key to exit..."); Console.WriteLine("Press any key to exit...");

View File

@ -10,6 +10,10 @@ using SharedLibrary.Interfaces;
using SharedLibrary.Commands; using SharedLibrary.Commands;
using SharedLibrary.Helpers; using SharedLibrary.Helpers;
using SharedLibrary.Exceptions; using SharedLibrary.Exceptions;
using SharedLibrary.Objects;
using SharedLibrary.Database;
using SharedLibrary.Database.Models;
using SharedLibrary.Services;
namespace IW4MAdmin namespace IW4MAdmin
{ {
@ -22,14 +26,13 @@ namespace IW4MAdmin
static ApplicationManager Instance; static ApplicationManager Instance;
List<AsyncStatus> TaskStatuses; List<AsyncStatus> TaskStatuses;
Database ClientDatabase;
Database AliasesDatabase;
IPenaltyList ClientPenalties;
List<Command> Commands; List<Command> Commands;
List<MessageToken> MessageTokens; List<MessageToken> MessageTokens;
Kayak.IScheduler webServiceTask; Kayak.IScheduler webServiceTask;
Thread WebThread; Thread WebThread;
List<Player> PrivilegedClients; ClientService ClientSvc;
AliasService AliasSvc;
PenaltyService PenaltySvc;
#if FTP_LOG #if FTP_LOG
const int UPDATE_FREQUENCY = 15000; const int UPDATE_FREQUENCY = 15000;
#else #else
@ -43,10 +46,9 @@ namespace IW4MAdmin
Commands = new List<Command>(); Commands = new List<Command>();
TaskStatuses = new List<AsyncStatus>(); TaskStatuses = new List<AsyncStatus>();
MessageTokens = new List<MessageToken>(); MessageTokens = new List<MessageToken>();
ClientSvc = new ClientService();
ClientDatabase = new ClientsDB("Database/clients.rm", Logger); AliasSvc = new AliasService();
AliasesDatabase = new AliasesDB("Database/aliases.rm", Logger); PenaltySvc = new PenaltyService();
ClientPenalties = new PenaltyList();
} }
public IList<Server> GetServers() public IList<Server> GetServers()
@ -145,7 +147,7 @@ namespace IW4MAdmin
#endregion #endregion
#region COMMANDS #region COMMANDS
if ((ClientDatabase as ClientsDB).GetOwner() == null) if (ClientSvc.GetOwners().Result.Count == 0)
Commands.Add(new COwner()); Commands.Add(new COwner());
Commands.Add(new CQuit()); Commands.Add(new CQuit());
@ -185,11 +187,6 @@ namespace IW4MAdmin
Commands.Add(C); Commands.Add(C);
#endregion #endregion
#region ADMINS
PrivilegedClients = GetClientDatabase().GetAdmins();
#endregion
Running = true; Running = true;
} }
@ -225,21 +222,6 @@ namespace IW4MAdmin
Running = false; Running = false;
} }
public ClientsDB GetClientDatabase()
{
return ClientDatabase as ClientsDB;
}
public AliasesDB GetAliasesDatabase()
{
return AliasesDatabase as AliasesDB;
}
public IPenaltyList GetClientPenalties()
{
return ClientPenalties;
}
public ILogger GetLogger() public ILogger GetLogger()
{ {
return Logger; return Logger;
@ -260,54 +242,8 @@ namespace IW4MAdmin
return ActiveClients; return ActiveClients;
} }
public IList<Player> GetAliasClients(Player Origin) public ClientService GetClientService() => ClientSvc;
{ public AliasService GetAliasService() => AliasSvc;
List<int> databaseIDs = new List<int>(); public PenaltyService GetPenaltyService() => PenaltySvc;
foreach (Aliases A in GetAliases(Origin))
databaseIDs.Add(A.Number);
return GetClientDatabase().GetPlayers(databaseIDs);
}
public IList<Aliases> GetAliases(Player Origin)
{
List<Aliases> allAliases = new List<Aliases>();
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<Player> GetPrivilegedClients()
{
return PrivilegedClients;
}
private void GetAliases(List<Aliases> returnAliases, Aliases currentAlias)
{
foreach (String IP in currentAlias.IPS)
{
List<Aliases> 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);
}
}
}
}
} }
} }

View File

@ -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<Penalty> FindPenalties(Player P)
{
return ApplicationManager.GetInstance().GetClientDatabase().GetClientPenalties(P);
}
public List<Penalty> AsChronoList(int offset, int count, Penalty.Type penaltyType = Penalty.Type.Any)
{
return ApplicationManager.GetInstance().GetClientDatabase().GetPenaltiesChronologically(offset, count, penaltyType);
}
}
}

View File

@ -8,6 +8,8 @@ using System.Threading.Tasks;
using SharedLibrary; using SharedLibrary;
using SharedLibrary.Network; using SharedLibrary.Network;
using SharedLibrary.Interfaces; using SharedLibrary.Interfaces;
using SharedLibrary.Objects;
using System.Text.RegularExpressions;
namespace IW4MAdmin namespace IW4MAdmin
{ {
@ -15,128 +17,109 @@ namespace IW4MAdmin
{ {
public IW4MServer(IManager mgr, ServerConfiguration cfg) : base(mgr, cfg) { } public IW4MServer(IManager mgr, ServerConfiguration cfg) : base(mgr, cfg) { }
override public async Task<bool> AddPlayer(Player P) override public async Task<bool> AddPlayer(Player polledPlayer)
{ {
if (P.ClientID < 0 || P.ClientID > (Players.Count - 1) || P.Ping < 1 || P.Ping == 999) // invalid index if (Players[polledPlayer.ClientNumber] != null &&
return false; Players[polledPlayer.ClientNumber].NetworkId == polledPlayer.NetworkId)
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
{ {
// update their ping // update their ping
Players[P.ClientID].Ping = P.Ping; Players[polledPlayer.ClientNumber].Ping = polledPlayer.Ping;
return true; 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; return false;
} }
Logger.WriteDebug($"Client slot #{P.ClientID} now reserved"); Logger.WriteDebug($"Client slot #{polledPlayer.ClientNumber} now reserved");
try 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"); Logger.WriteDebug($"Client {polledPlayer} first time connecting");
Manager.GetClientDatabase().AddPlayer(P); player = (await Manager.GetClientService().Create(polledPlayer)).AsPlayer();
NewPlayer = Manager.GetClientDatabase().GetPlayer(P.NetworkID, P.ClientID);
Manager.GetAliasesDatabase().AddPlayerAliases(new Aliases(NewPlayer.DatabaseID, NewPlayer.Name, NewPlayer.IP));
} }
List<Player> Admins = Manager.GetClientDatabase().GetAdmins(); // client has connected in the past
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
else 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()); client.Connections += 1;
NewPlayer.Alias.Names.Add(NewPlayer.Name); 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); /*var Admins = Manager.GetDatabase().GetPrivilegedClients();
Manager.GetClientDatabase().UpdatePlayer(NewPlayer); if (Admins.Where(x => x.Name == polledPlayer.Name).Count() > 0)
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
{ {
Logger.WriteInfo($"Banned client {P.Name}::{P.NetworkID} trying to connect..."); if ((Admins.First(x => x.Name == polledPlayer.Name).NetworkId != polledPlayer.NetworkId) && NewPlayer.Level < Player.Permission.Moderator)
await NewPlayer.Kick(NewPlayer.lastOffense != null ? "^7Previously banned for ^5 " + NewPlayer.lastOffense : "^7Previous Ban", NewPlayer); 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; 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 await ExecuteEvent(new Event(Event.GType.Connect, "", player, null, this));
{
if (aP == null)
continue;
if (aP.Level == Player.Permission.Flagged) // if (NewPlayer.Level > Player.Permission.Moderator)
NewPlayer.SetLevel(Player.Permission.Flagged); // await NewPlayer.Tell("There are ^5" + Reports.Count + " ^7recent reports!");
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!");
return true; return true;
} }
catch (Exception E) 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); Manager.GetLogger().WriteDebug(E.StackTrace);
return false; return false;
} }
@ -148,10 +131,10 @@ namespace IW4MAdmin
if (cNum >= 0) if (cNum >= 0)
{ {
Player Leaving = Players[cNum]; Player Leaving = Players[cNum];
Leaving.Connections++; Leaving.TotalConnectionTime += (int)(DateTime.UtcNow - Leaving.ConnectionTime).TotalSeconds;
Manager.GetClientDatabase().UpdatePlayer(Leaving); 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)); await ExecuteEvent(new Event(Event.GType.Disconnect, "", Leaving, null, this));
Players[cNum] = null; Players[cNum] = null;
} }
@ -182,17 +165,6 @@ namespace IW4MAdmin
return Players[pID]; 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 //Process requested command correlating to an event
// todo: this needs to be removed out of here // todo: this needs to be removed out of here
override public async Task<Command> ValidateCommand(Event E) override public async Task<Command> ValidateCommand(Event E)
@ -234,19 +206,16 @@ namespace IW4MAdmin
int cNum = -1; int cNum = -1;
int.TryParse(Args[0], out cNum); int.TryParse(Args[0], out cNum);
if (Args[0] == String.Empty)
return C;
if (Args[0][0] == '@') // user specifying target by database ID if (Args[0][0] == '@') // user specifying target by database ID
{ {
int dbID = -1; int dbID = -1;
int.TryParse(Args[0].Substring(1, Args[0].Length - 1), out dbID); 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) if (found != null)
{ {
E.Target = found; E.Target = found.AsPlayer();
E.Target.lastEvent = E; E.Target.CurrentServer = this as IW4MServer;
E.Owner = 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 else if (Args[0].Length < 3 && cNum > -1 && cNum < 18) // user specifying target by client num
{ {
if (Players[cNum] != null) if (Players[cNum] != null)
{
E.Target = Players[cNum]; E.Target = Players[cNum];
E.Data = String.Join(" ", Args.Skip(1));
}
} }
List<Player> matchingPlayers; List<Player> matchingPlayers;
@ -268,7 +240,10 @@ namespace IW4MAdmin
throw new SharedLibrary.Exceptions.CommandException($"{E.Origin} had multiple players found for {C.Name}"); throw new SharedLibrary.Exceptions.CommandException($"{E.Origin} had multiple players found for {C.Name}");
} }
else if (matchingPlayers.Count == 1) else if (matchingPlayers.Count == 1)
{
E.Target = matchingPlayers.First(); 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 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"); await E.Origin.Tell("Multiple players match that name");
foreach (var p in matchingPlayers) 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}"); throw new SharedLibrary.Exceptions.CommandException($"{E.Origin} had multiple players found for {C.Name}");
} }
else if (matchingPlayers.Count == 1) else if (matchingPlayers.Count == 1)
{
E.Target = matchingPlayers.First(); E.Target = matchingPlayers.First();
E.Data = Regex.Replace(E.Data, $"{E.Target.Name}", "", RegexOptions.IgnoreCase).Trim();
}
} }
if (E.Target == null && C.RequiresTarget) if (E.Target == null && C.RequiresTarget)
@ -327,12 +305,21 @@ namespace IW4MAdmin
for (int i = 0; i < Players.Count; i++) 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); await RemovePlayer(i);
} }
//polledPlayer.ClientNumber < 0 || polledPlayer.ClientNumber > (Players.Count - 1) || polledPlayer.Ping < 1 || polledPlayer.Ping == 999
foreach (var P in CurrentPlayers) 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); await AddPlayer(P);
}
return CurrentPlayers.Count; return CurrentPlayers.Count;
} }
@ -441,8 +428,6 @@ namespace IW4MAdmin
if (event_.Origin == null) if (event_.Origin == null)
continue; continue;
event_.Origin.lastEvent = event_;
event_.Origin.lastEvent.Owner = this;
await ExecuteEvent(event_); await ExecuteEvent(event_);
} }
} }
@ -623,9 +608,6 @@ namespace IW4MAdmin
else // Not a command else // Not a command
{ {
E.Data = E.Data.StripColors(); 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)); 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) public override async Task Warn(String Reason, Player Target, Player Origin)
{ {
if (Target.Warnings >= 4) if (Target.Warnings >= 4)
await Target.Kick("Too many warnings!", Origin); await Target.Kick("Too many warnings!", (await Manager.GetClientService().Get(1)).AsPlayer());
else else
{ {
Penalty newPenalty = new Penalty(Penalty.Type.Warning, Reason.StripColors(), Target.NetworkID, Origin.NetworkID, DateTime.Now, Target.IP, DateTime.Now); Penalty newPenalty = new Penalty()
Manager.GetClientPenalties().AddPenalty(newPenalty); {
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++; 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); await Broadcast(Message);
} }
} }
public override async Task Kick(String Reason, Player Target, Player Origin) 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; 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); await Manager.GetPenaltyService().Create(new Penalty()
Manager.GetClientPenalties().AddPenalty(newPenalty); {
await this.ExecuteCommandAsync($"clientkick {Target.ClientID} \"{Message}^7\""); 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) public override async Task TempBan(String Reason, TimeSpan length, Player Target, Player Origin)
{ {
await this.ExecuteCommandAsync($"clientkick {Target.ClientID } \"^1Player Temporarily Banned: ^5{ Reason }\""); await this.ExecuteCommandAsync($"clientkick {Target.ClientNumber } \"^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); Penalty newPenalty = new Penalty()
await Task.Run(() =>
{ {
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) override public async Task Ban(String Message, Player Target, Player Origin)
{ {
if (Target == null) Penalty newPenalty = new Penalty()
{ {
Logger.WriteError("Ban target is null"); Type = Penalty.PenaltyType.Ban,
Logger.WriteDebug($"Message: {Message}"); Expires = DateTime.MinValue,
Logger.WriteDebug($"Origin: {Origin.Name}::{Origin.NetworkID}"); Offender = Target,
return; 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<Report> toRemove = new List<Report>();
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 // banned from all servers if active
@ -708,65 +742,19 @@ namespace IW4MAdmin
{ {
if (server.GetPlayersAsList().Count > 0) 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) 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; 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<Report> toRemove = new List<Report>();
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) override public async Task Unban(Player Target)
{ {
// database stuff can be time consuming await Manager.GetPenaltyService().RemoveActivePenalties(Target.AliasLink.AliasLinkId);
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);
}
});
} }
public override bool Reload() public override bool Reload()
@ -790,7 +778,7 @@ namespace IW4MAdmin
override public void InitializeTokens() 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)); Manager.GetMessageTokens().Add(new SharedLibrary.Helpers.MessageToken("VERSION", Program.Version.ToString));
} }
} }

View File

@ -9,6 +9,12 @@ using System.Net;
using System.Text; using System.Text;
using System.Threading; using System.Threading;
using SharedLibrary.Objects;
using System.Threading.Tasks;
using SharedLibrary.Services;
using System.Linq.Expressions;
using SharedLibrary.Database.Models;
namespace IW4MAdmin namespace IW4MAdmin
{ {
public class WebService public class WebService
@ -81,7 +87,7 @@ namespace IW4MAdmin
IPage requestedPage = SharedLibrary.WebService.PageList.Find(x => x.GetPath().ToLower() == path.ToLower()); IPage requestedPage = SharedLibrary.WebService.PageList.Find(x => x.GetPath().ToLower() == path.ToLower());
if (requestedPage != null) if (requestedPage != null)
return requestedPage.GetPage(queryset, headers); return Task.Run(async () => await requestedPage.GetPage(queryset, headers)).Result;
else else
{ {
if (File.Exists(path.Replace("/", "\\").Substring(1))) if (File.Exists(path.Replace("/", "\\").Substring(1)))
@ -127,7 +133,7 @@ namespace IW4MAdmin
} }
requestedPage = new Error404(); 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 ""; return "";
} }
public HttpResponse GetPage(System.Collections.Specialized.NameValueCollection querySet, IDictionary<string, string> headers) public async Task<HttpResponse> GetPage(System.Collections.Specialized.NameValueCollection querySet, IDictionary<string, string> headers)
{ {
HttpResponse resp = new HttpResponse() HttpResponse resp = new HttpResponse()
{ {
@ -203,7 +209,7 @@ namespace IW4MAdmin
return "/_servers"; return "/_servers";
} }
public HttpResponse GetPage(System.Collections.Specialized.NameValueCollection querySet, IDictionary<string, string> headers) public async Task<HttpResponse> GetPage(System.Collections.Specialized.NameValueCollection querySet, IDictionary<string, string> headers)
{ {
var info = new List<ServerInfo>(); var info = new List<ServerInfo>();
foreach (Server S in ApplicationManager.GetInstance().Servers) foreach (Server S in ApplicationManager.GetInstance().Servers)
@ -221,8 +227,8 @@ namespace IW4MAdmin
PlayerHistory = S.PlayerHistory.ToArray() PlayerHistory = S.PlayerHistory.ToArray()
}; };
bool authed = ApplicationManager.GetInstance().GetPrivilegedClients() bool authed = (await (ApplicationManager.GetInstance().GetClientService() as ClientService).GetPrivilegedClients())
.Where(x => x.IP == querySet["IP"]) .Where(x => x.IPAddress == querySet["IP"])
.Where(x => x.Level > Player.Permission.Trusted).Count() > 0 .Where(x => x.Level > Player.Permission.Trusted).Count() > 0
|| querySet["IP"] == "127.0.0.1"; || querySet["IP"] == "127.0.0.1";
@ -230,7 +236,7 @@ namespace IW4MAdmin
{ {
PlayerInfo pInfo = new PlayerInfo() PlayerInfo pInfo = new PlayerInfo()
{ {
playerID = P.DatabaseID, playerID = P.ClientNumber,
playerName = P.Name, playerName = P.Name,
playerLevel = authed ? P.Level.ToString() : Player.Permission.User.ToString() playerLevel = authed ? P.Level.ToString() : Player.Permission.User.ToString()
}; };
@ -273,7 +279,7 @@ namespace IW4MAdmin
return "/_playerhistory"; return "/_playerhistory";
} }
public HttpResponse GetPage(System.Collections.Specialized.NameValueCollection querySet, IDictionary<string, string> headers) public async Task<HttpResponse> GetPage(System.Collections.Specialized.NameValueCollection querySet, IDictionary<string, string> headers)
{ {
var history = new SharedLibrary.Helpers.PlayerHistory[0]; var history = new SharedLibrary.Helpers.PlayerHistory[0];
@ -320,7 +326,7 @@ namespace IW4MAdmin
return "/_info"; return "/_info";
} }
public HttpResponse GetPage(System.Collections.Specialized.NameValueCollection querySet, IDictionary<string, string> headers) public async Task<HttpResponse> GetPage(System.Collections.Specialized.NameValueCollection querySet, IDictionary<string, string> headers)
{ {
ApplicationInfo info = new ApplicationInfo() ApplicationInfo info = new ApplicationInfo()
{ {
@ -360,12 +366,9 @@ namespace IW4MAdmin
return "/_console"; return "/_console";
} }
public HttpResponse GetPage(System.Collections.Specialized.NameValueCollection querySet, IDictionary<string, string> headers) public async Task<HttpResponse> GetPage(System.Collections.Specialized.NameValueCollection querySet, IDictionary<string, string> headers)
{ {
CommandInfo cmd = new CommandInfo() var cmd = new List<SharedLibrary.Helpers.CommandResult>();
{
Result = new List<string>()
};
if (querySet["command"] != null) if (querySet["command"] != null)
{ {
@ -376,32 +379,37 @@ namespace IW4MAdmin
if (S != null) if (S != null)
{ {
Player admin = ApplicationManager.GetInstance().GetClientDatabase().GetPlayer(querySet["IP"]); // fixme
Func<EFClient, bool> predicate = c => c.IPAddress == querySet["IP"];
Player admin = (await ApplicationManager.GetInstance().GetClientService().Find(predicate)).First()?.AsPlayer();
if (admin == null) 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) Event remoteEvent = new Event(Event.GType.Say, querySet["command"], admin, null, S)
{ {
Remote = true 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 else
cmd.Result.Add("Invalid server selected."); cmd.Add(new SharedLibrary.Helpers.CommandResult() { Clientd = 0, Message = "Invalid server selected" });
} }
else else
cmd.Result.Add("Invalid server selected."); cmd.Add(new SharedLibrary.Helpers.CommandResult() { Clientd = 0, Message = "No server selected" });
} }
else else
{ {
cmd.Result.Add("No command entered."); cmd.Add(new SharedLibrary.Helpers.CommandResult() { Clientd = 0, Message = "No command entered" });
} }
HttpResponse resp = new HttpResponse() HttpResponse resp = new HttpResponse()
@ -437,51 +445,28 @@ namespace IW4MAdmin
return "/_penalties"; return "/_penalties";
} }
public HttpResponse GetPage(System.Collections.Specialized.NameValueCollection querySet, IDictionary<string, string> headers) public async Task<HttpResponse> GetPage(System.Collections.Specialized.NameValueCollection querySet, IDictionary<string, string> headers)
{ {
int from = 0; int from = 0;
if (querySet["from"] != null) if (querySet["from"] != null)
from = Int32.Parse(querySet["from"]); from = Int32.Parse(querySet["from"]);
List<Penalty> selectedPenalties;
try
{
selectedPenalties = ((ApplicationManager.GetInstance().GetClientPenalties()) as PenaltyList).AsChronoList(Convert.ToInt32(querySet["from"]), 15).OrderByDescending(b => b.When).ToList();
}
catch (Exception)
{
selectedPenalties = new List<Penalty>();
}
List<PenaltyInfo> info = new List<PenaltyInfo>(); List<PenaltyInfo> info = new List<PenaltyInfo>();
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() PenaltyInfo pInfo = new PenaltyInfo()
{ {
adminName = admin.Name, adminName = penalty.Punisher.Name,
adminLevel = admin.Level.ToString(), adminLevel = penalty.Punisher.Level.ToString(),
penaltyReason = p.Reason, penaltyReason = penalty.Offense,
penaltyTime = Utilities.GetTimePassed(p.When), penaltyTime = Utilities.GetTimePassed(penalty.When),
penaltyType = p.BType.ToString(), penaltyType = penalty.Type.ToString(),
playerName = penalized.Name, playerName = penalty.Offender.Name,
playerID = penalized.DatabaseID, playerID = penalty.Offender.ClientId,
Expires = p.Expires > DateTime.Now ? (p.Expires - DateTime.Now).TimeSpanText() : "" 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); info.Add(pInfo);
} }
@ -626,9 +611,11 @@ namespace IW4MAdmin
return "/GetAdmins"; return "/GetAdmins";
} }
public HttpResponse GetPage(System.Collections.Specialized.NameValueCollection querySet, IDictionary<string, string> headers) public async Task<HttpResponse> GetPage(System.Collections.Specialized.NameValueCollection querySet, IDictionary<string, string> 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() HttpResponse resp = new HttpResponse()
{ {
contentType = GetContentType(), contentType = GetContentType(),
@ -661,17 +648,17 @@ namespace IW4MAdmin
return "/pubbans"; return "/pubbans";
} }
public HttpResponse GetPage(System.Collections.Specialized.NameValueCollection querySet, IDictionary<string, string> headers) public async Task<HttpResponse> GetPage(System.Collections.Specialized.NameValueCollection querySet, IDictionary<string, string> headers)
{ {
HttpResponse resp = new HttpResponse() HttpResponse resp = new HttpResponse()
{ {
contentType = GetContentType(), /* contentType = GetContentType(),
content = Newtonsoft.Json.JsonConvert content = Newtonsoft.Json.JsonConvert
.SerializeObject(((ApplicationManager.GetInstance().GetClientPenalties()) as PenaltyList) .SerializeObject(((ApplicationManager.GetInstance().GetClientPenalties()) as PenaltyList)
.AsChronoList(Convert.ToInt32(querySet["from"]), 50, Penalty.Type.Ban), Newtonsoft.Json.Formatting.Indented, new Newtonsoft.Json.JsonConverter[] { .AsChronoList(Convert.ToInt32(querySet["from"]), 50, Penalty.Type.Ban), Newtonsoft.Json.Formatting.Indented, new Newtonsoft.Json.JsonConverter[] {
new Newtonsoft.Json.Converters.StringEnumConverter() new Newtonsoft.Json.Converters.StringEnumConverter()
}), }),
additionalHeaders = new Dictionary<string, string>() additionalHeaders = new Dictionary<string, string>()*/
}; };
return resp; return resp;
} }
@ -699,7 +686,7 @@ namespace IW4MAdmin
return "/pages"; return "/pages";
} }
public HttpResponse GetPage(System.Collections.Specialized.NameValueCollection querySet, IDictionary<string, string> headers) public async Task<HttpResponse> GetPage(System.Collections.Specialized.NameValueCollection querySet, IDictionary<string, string> headers)
{ {
var pages = SharedLibrary.WebService.PageList.Select(p => new var pages = SharedLibrary.WebService.PageList.Select(p => new
@ -746,33 +733,34 @@ namespace IW4MAdmin
return "GetPlayer"; return "GetPlayer";
} }
public HttpResponse GetPage(System.Collections.Specialized.NameValueCollection querySet, IDictionary<string, string> headers) public async Task<HttpResponse> GetPage(System.Collections.Specialized.NameValueCollection querySet, IDictionary<string, string> headers)
{ {
List<PlayerInfo> pInfo = new List<PlayerInfo>(); List<PlayerInfo> pInfo = new List<PlayerInfo>();
List<Player> matchedPlayers = new List<Player>(); IList<SharedLibrary.Database.Models.EFClient> matchedPlayers = new List<SharedLibrary.Database.Models.EFClient>();
HttpResponse resp = new HttpResponse() HttpResponse resp = new HttpResponse()
{ {
contentType = GetContentType(), contentType = GetContentType(),
additionalHeaders = new Dictionary<string, string>() additionalHeaders = new Dictionary<string, string>()
}; };
bool authed = ApplicationManager.GetInstance().GetClientDatabase().GetAdmins().FindAll(x => x.IP == querySet["IP"] && x.Level > Player.Permission.Trusted).Count > 0 Func<EFClient, bool> 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"; || querySet["IP"] == "127.0.0.1";
bool recent = false; bool recent = false;
bool individual = querySet["id"] != null; bool individual = querySet["id"] != null;
if (individual) 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) else if (querySet["npID"] != null)
{ {
matchedPlayers.Add(ApplicationManager.GetInstance().GetClientDatabase().GetPlayers(new List<string> { querySet["npID"] }).First()); matchedPlayers.Add(await ApplicationManager.GetInstance().GetClientService().GetUnique(querySet["npID"]));
} }
else if (querySet["name"] != null) 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) else if (querySet["recent"] != null)
@ -783,7 +771,7 @@ namespace IW4MAdmin
if (offset < 0) if (offset < 0)
throw new FormatException("Invalid offset"); throw new FormatException("Invalid offset");
matchedPlayers = ApplicationManager.GetInstance().GetClientDatabase().GetRecentPlayers(15, offset); matchedPlayers = await ApplicationManager.GetInstance().GetClientService().GetRecentClients(offset, 15);
recent = true; recent = true;
} }
@ -795,26 +783,23 @@ namespace IW4MAdmin
PlayerInfo eachPlayer = new PlayerInfo() PlayerInfo eachPlayer = new PlayerInfo()
{ {
playerID = pp.DatabaseID, playerIP = pp.IPAddress,
playerIP = pp.IP, playerID = pp.ClientId,
playerLevel = pp.Level.ToString(), playerLevel = pp.Level.ToString(),
playerName = pp.Name, playerName = pp.Name,
playernpID = pp.NetworkID, playernpID = pp.NetworkId,
forumID = -1, forumID = -1,
authed = authed, authed = authed,
showV2Features = false, showV2Features = false,
playerAliases = new List<string>(), playerAliases = new List<string>(),
playerIPs = new List<string>() playerIPs = new List<string>()
}; };
if (!recent && individual && authed) if (!recent && individual && authed)
{ {
foreach (var a in ApplicationManager.GetInstance().GetAliases(pp))
{ eachPlayer.playerAliases = pp.AliasLink.Children.OrderBy(a => a.Name).Select(a => a.Name).ToList();
eachPlayer.playerAliases.AddRange(a.Names); eachPlayer.playerIPs = pp.AliasLink.Children.Select(a => a.IP).ToList();
eachPlayer.playerIPs.AddRange(a.IPS);
}
} }
eachPlayer.playerAliases = eachPlayer.playerAliases.Distinct().ToList(); eachPlayer.playerAliases = eachPlayer.playerAliases.Distinct().ToList();

Binary file not shown.

Binary file not shown.

View File

@ -1,6 +1,6 @@
<script> <script>
function printPlayer(player, i) { function printPlayer(player, i) {
var playerText = '<div class="admin-name"><a href="/players?id=' + player.DatabaseID + '">' + player.Name + "</a></div>"; var playerText = '<div class="admin-name"><a href="/players?id=' + player.ClientId + '">' + player.Name + "</a></div>";
switch (player.Level) { switch (player.Level) {
case 6: case 6:
$('#owner-privilege .clients').append(playerText); $('#owner-privilege .clients').append(playerText);

View File

@ -1,77 +1,70 @@
<div id="consoleWrap"> <div id="consoleWrap">
<select id="serverSelection"> <select id="serverSelection"></select>
</select> <hr />
<hr/> <div id="console">
<div id="console"> </div>
</div> <hr />
<hr/> <div class="playerSearchWrap table">
<div class="playerSearchWrap table"> <input type="text" class="search tableCell" placeholder="Enter Command..." />
<input type="text" class="search tableCell" placeholder="Enter Command..."/> <input type="button" class="searchButton tableCell" name="Search" value="Execute" />
<input type="button" class="searchButton tableCell" name="Search" value="Execute"/> </div>
</div>
</div> </div>
<script> <script>
var cmdResultQueue = []; var cmdResultQueue = [];
$( document ).ready(function() { $(document).ready(function () {
cmdResultQueue = []; cmdResultQueue = [];
$.getJSON("/_servers", function(servers) { $.getJSON("/_servers", function (servers) {
$.each(servers, function(i, server) { $.each(servers, function (i, server) {
$('select').append("<option value=\"" + server['serverPort'] + "\">" + server['serverName'] + "</option>"); $('select').append("<option value=\"" + server['serverPort'] + "\">" + server['serverName'] + "</option>");
});
});
}); });
});
}); function addCommandResult(line) {
// $.each(result, function (i, line) {
if (line == "You entered an invalid command!" || line == "All commands must start with '!'") {
line = getColorForLevel("Banned", line);
}
else {
line = getColorForLevel("Trusted", line);
}
if (cmdResultQueue.length > 12)
cmdResultQueue.shift();
function addCommandResult(result) cmdResultQueue.push(line);
{ // });
$.each(result, function(i, line) {
if (line == "You entered an invalid command!" || line == "All commands must start with '!'" )
{
line = getColorForLevel("Banned", line);
} }
else
{
line = getColorForLevel("Trusted", line);
}
if (cmdResultQueue.length > 12)
cmdResultQueue.shift();
cmdResultQueue.push(line); function formatCommandResults() {
}); $('#console').html("");
}
function formatCommandResults() for (i = 0; i < cmdResultQueue.length; i++)
{ $('#console').append("<span class=\"commandResult\">"
$('#console').html(""); + cmdResultQueue[i] + "</span><br/>"
);
for (i = 0; i < cmdResultQueue.length; i++) }
$('#console').append("<span class=\"commandResult\">"
+ cmdResultQueue[i] + "</span><br/>"
);
}
$('.searchButton').click(function() { $('.searchButton').click(function () {
if ($('.search').val().length > 0) if ($('.search').val().length > 0) {
{ if ($('.search').val()[0] != '!') {
if ($('.search').val()[0] != '!') addCommandResult(["All commands must start with '!'"]);
{ formatCommandResults();
addCommandResult(["All commands must start with '!'"]); return false;
formatCommandResults(); }
return false;
$.getJSON("/_console?command=" + $('.search').val() + "&server=" + $('select').val(), function (result) {
$.each(result, function (i, line) {
addCommandResult(line.Message)
});
}).done(function (data) { formatCommandResults(); $('.search').val(""); });
} }
});
$.getJSON("/_console?command=" + $('.search').val() + "&server=" + $('select').val(), function(result) { $(document).keypress(function (e) {
$.each(result, function(i, line) { if (e.which == 13) {
addCommandResult(line) $('.searchButton').click();
}); }
}).done(function (data) { formatCommandResults(); $('.search').val(""); }); });
}
});
$(document).keypress(function(e) {
if(e.which == 13) {
$('.searchButton').click();
}
});
</script> </script>

90
Database/Database.csproj Normal file
View File

@ -0,0 +1,90 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{D076ABC9-DDD6-4E30-9584-E45273950902}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Database</RootNamespace>
<AssemblyName>Database</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release-Nightly|AnyCPU'">
<OutputPath>bin\Release-Nightly\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>AnyCPU</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release-Stable|AnyCPU'">
<OutputPath>bin\Release-Stable\</OutputPath>
</PropertyGroup>
<ItemGroup>
<Reference Include="EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
<HintPath>..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.dll</HintPath>
</Reference>
<Reference Include="EntityFramework.SqlServerCompact, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
<HintPath>..\packages\EntityFramework.SqlServerCompact.6.2.0\lib\net45\EntityFramework.SqlServerCompact.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.ComponentModel.DataAnnotations" />
<Reference Include="System.Core" />
<Reference Include="System.Data.SqlServerCe, Version=4.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.SqlServer.Compact.4.0.8876.1\lib\net40\System.Data.SqlServerCe.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="IW4MAdminDatabaseContext.cs" />
<Compile Include="IW4MAdminDatabase.cs" />
<Compile Include="Models\Alias.cs" />
<Compile Include="Models\Client.cs" />
<Compile Include="Models\Penalty.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\SharedLibrary\SharedLibrary.csproj">
<Project>{d51eeceb-438a-47da-870f-7d7b41bc24d6}</Project>
<Name>SharedLibrary</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PostBuildEvent>
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"</PostBuildEvent>
</PropertyGroup>
</Project>

View File

@ -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<Client> 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<Client> GetOwners() => _context.Clients.Where(c => c.Level == SharedLibrary.Player.Permission.Owner).ToList();
public IList<SharedLibrary.Player> GetPlayers(IList<string> networkIDs) => _context.Clients.Where(c => networkIDs.Contains(c.NetworkId)).Select(c => c.ToPlayer()).ToList();
public IList<Penalty> GetPenalties (int clientID) => _context.Penalties.Where(p => p.OffenderId == clientID).ToList();
public IList<SharedLibrary.Player> GetAdmins() => _context.Clients.Where(c => c.Level > SharedLibrary.Player.Permission.Flagged).Select(c => c.ToPlayer()).ToList();
}
}

View File

@ -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<Client> Clients { get; set; }
public DbSet<Alias> Aliases { get; set; }
public DbSet<Penalty> 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);
}
}
}

18
Database/Models/Alias.cs Normal file
View File

@ -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; }
}
}

43
Database/Models/Client.cs Normal file
View File

@ -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
};
}
}
}

View File

@ -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; }
}
}

View File

@ -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")]

6
Database/packages.config Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="EntityFramework" version="6.2.0" targetFramework="net45" />
<package id="EntityFramework.SqlServerCompact" version="6.2.0" targetFramework="net45" />
<package id="Microsoft.SqlServer.Compact" version="4.0.8876.1" targetFramework="net45" />
</packages>

View File

@ -1,7 +1,7 @@
 
Microsoft Visual Studio Solution File, Format Version 12.00 Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15 # Visual Studio 15
VisualStudioVersion = 15.0.27004.2006 VisualStudioVersion = 15.0.27004.2009
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Application", "Admin\Application.csproj", "{DD5DCDA2-51DB-4B1A-922F-5705546E6115}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Application", "Admin\Application.csproj", "{DD5DCDA2-51DB-4B1A-922F-5705546E6115}"
ProjectSection(ProjectDependencies) = postProject ProjectSection(ProjectDependencies) = postProject
@ -49,6 +49,10 @@ Global
Debug|Mixed Platforms = Debug|Mixed Platforms Debug|Mixed Platforms = Debug|Mixed Platforms
Debug|x64 = Debug|x64 Debug|x64 = Debug|x64
Debug|x86 = Debug|x86 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|Any CPU = Release-Nightly|Any CPU
Release-Nightly|Mixed Platforms = Release-Nightly|Mixed Platforms Release-Nightly|Mixed Platforms = Release-Nightly|Mixed Platforms
Release-Nightly|x64 = Release-Nightly|x64 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|x64.Build.0 = Debug|Any CPU
{DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Debug|x86.ActiveCfg = Debug|x86 {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}.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.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|Any CPU.Build.0 = Release-Nightly|Any CPU
{DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release-Nightly|Mixed Platforms.ActiveCfg = Release-Nightly|x86 {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|x64.Build.0 = Debug|Any CPU
{4785AB75-66F3-4391-985D-63A5A049A0FA}.Debug|x86.ActiveCfg = Debug|x86 {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}.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.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|Any CPU.Build.0 = Release-Nightly|Any CPU
{4785AB75-66F3-4391-985D-63A5A049A0FA}.Release-Nightly|Mixed Platforms.ActiveCfg = Release-Nightly|x86 {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|x64.Build.0 = Debug|Any CPU
{D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Debug|x86.ActiveCfg = Debug|x86 {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}.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.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|Any CPU.Build.0 = Release-Nightly|Any CPU
{D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release-Nightly|Mixed Platforms.ActiveCfg = Release-Nightly|x86 {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|x64.Build.0 = Debug|Any CPU
{AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Debug|x86.ActiveCfg = Debug|x86 {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}.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.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|Any CPU.Build.0 = Release-Nightly|Any CPU
{AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release-Nightly|Mixed Platforms.ActiveCfg = Release-Nightly|x86 {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|x64.Build.0 = Debug|Any CPU
{428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Debug|x86.ActiveCfg = Debug|x86 {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}.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|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.ActiveCfg = Release-Nightly|x86
{428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release-Nightly|Mixed Platforms.Build.0 = 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|x64.ActiveCfg = Release-Stable|Any CPU
{E46C85BD-A99C-484E-BCCE-0F1831C5925E}.Debug|x86.ActiveCfg = Debug|x86 {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}.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|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|Mixed Platforms.ActiveCfg = Release-Stable|Any CPU
{E46C85BD-A99C-484E-BCCE-0F1831C5925E}.Release-Nightly|x64.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|x64.Build.0 = Debug|Any CPU
{C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Debug|x86.ActiveCfg = Debug|x86 {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}.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.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|Any CPU.Build.0 = Release-Nightly|Any CPU
{C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release-Nightly|Mixed Platforms.ActiveCfg = Release-Nightly|x86 {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|x64.Build.0 = Debug|Any CPU
{1479DE87-ACB5-4046-81C8-A0BA5041227D}.Debug|x86.ActiveCfg = Debug|x86 {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}.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|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.ActiveCfg = Release-Nightly|x86
{1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release-Nightly|Mixed Platforms.Build.0 = 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|x64.Build.0 = Debug|Any CPU
{B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Debug|x86.ActiveCfg = Debug|x86 {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}.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|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.ActiveCfg = Release-Nightly|x86
{B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Release-Nightly|Mixed Platforms.Build.0 = Release-Nightly|x86 {B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Release-Nightly|Mixed Platforms.Build.0 = Release-Nightly|x86

View File

@ -1,9 +1,11 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
using System.Threading.Tasks;
using SharedLibrary; using SharedLibrary;
using SharedLibrary.Interfaces; using SharedLibrary.Interfaces;
using System.Threading.Tasks; using SharedLibrary.Objects;
namespace EventAPI namespace EventAPI
{ {
@ -25,7 +27,7 @@ namespace EventAPI
return "/api/events"; return "/api/events";
} }
public HttpResponse GetPage(System.Collections.Specialized.NameValueCollection querySet, IDictionary<string, string> headers) public async Task<HttpResponse> GetPage(System.Collections.Specialized.NameValueCollection querySet, IDictionary<string, string> headers)
{ {
bool shouldQuery = querySet.Get("status") != null; bool shouldQuery = querySet.Get("status") != null;
EventResponse requestedEvent = new EventResponse(); EventResponse requestedEvent = new EventResponse();

View File

@ -6,6 +6,7 @@ using SharedLibrary;
using SharedLibrary.Interfaces; using SharedLibrary.Interfaces;
using SharedLibrary.Network; using SharedLibrary.Network;
using SharedLibrary.Helpers; using SharedLibrary.Helpers;
using SharedLibrary.Objects;
namespace Plugin namespace Plugin
{ {

View File

@ -3,12 +3,14 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using SharedLibrary.Objects;
namespace MessageBoard namespace MessageBoard
{ {
public class Rank : Identifiable public class Rank : Identifiable
{ {
public string name; public string name;
public SharedLibrary.Player.Permission equivalentRank; public Player.Permission equivalentRank;
public int id; public int id;
/// <summary> /// <summary>
@ -17,14 +19,14 @@ namespace MessageBoard
/// <param name="name"></param> /// <param name="name"></param>
/// <param name="equivalentRank"></param> /// <param name="equivalentRank"></param>
/// <param name="permissions"></param> /// <param name="permissions"></param>
public Rank(string name, SharedLibrary.Player.Permission equivalentRank) public Rank(string name, Player.Permission equivalentRank)
{ {
this.name = name; this.name = name;
this.equivalentRank = equivalentRank; this.equivalentRank = equivalentRank;
id = 0; 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.name = name;
this.equivalentRank = equivalentRank; this.equivalentRank = equivalentRank;

View File

@ -5,7 +5,7 @@ using System.Data;
namespace MessageBoard.Storage namespace MessageBoard.Storage
{ {
class Database : SharedLibrary.Database class Database : SharedLibrary._Database
{ {
public Database(String FN, SharedLibrary.Interfaces.ILogger logger) : base(FN, logger) { } public Database(String FN, SharedLibrary.Interfaces.ILogger logger) : base(FN, logger) { }

View File

@ -10,7 +10,7 @@ using System.Data;
namespace StatsPlugin namespace StatsPlugin
{ {
public class ChatDatabase : Database public class ChatDatabase : _Database
{ {
private string[] CommonWords = new string[] { "for", private string[] CommonWords = new string[] { "for",
"with", "with",

View File

@ -67,7 +67,7 @@ namespace StatsPlugin.Chat
public HttpResponse GetPage(NameValueCollection querySet, IDictionary<string, string> headers) public HttpResponse GetPage(NameValueCollection querySet, IDictionary<string, string> headers)
{ {
int clientID = Convert.ToInt32(querySet["clientid"]); 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() HttpResponse resp = new HttpResponse()
{ {
@ -78,7 +78,7 @@ namespace StatsPlugin.Chat
ServerID = c.ServerID, ServerID = c.ServerID,
Message = c.Message, Message = c.Message,
TimeSent = c.TimeSent, TimeSent = c.TimeSent,
ClientName = client.Name, ClientName = name,
}), }),
additionalHeaders = new Dictionary<string, string>() additionalHeaders = new Dictionary<string, string>()
}; };

View File

@ -7,6 +7,8 @@ using System.IO;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using SharedLibrary.Objects;
namespace StatsPlugin namespace StatsPlugin
{ {
public class CViewStats : Command public class CViewStats : Command
@ -74,7 +76,7 @@ namespace StatsPlugin
await E.Origin.Tell("^5--Top Players--"); await E.Origin.Tell("^5--Top Players--");
foreach (KeyValuePair<String, PlayerStats> pStat in pStats) foreach (KeyValuePair<String, PlayerStats> 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) if (P == null)
continue; continue;
await E.Origin.Tell(String.Format("^3{0}^7 - ^5{1} ^7KDR | ^5{2} ^7SKILL", P.Name, pStat.Value.KDR, pStat.Value.Skill)); 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; return;
} }
E.Owner.Manager.GetClientDatabase().PruneAdmins(inactiveDays); var inactiveAdmins = await E.Owner.Manager.GetDatabase().PruneInactivePrivilegedClients(inactiveDays);
await E.Origin.Tell("Pruned inactive privileged users"); await E.Origin.Tell($"Pruned inactive {inactiveAdmins.Count} privileged users");
} }
} }
@ -289,7 +291,7 @@ namespace StatsPlugin
if (E.Type == Event.GType.Connect) if (E.Type == Event.GType.Connect)
{ {
ResetCounters(E.Origin.ClientID, S.GetPort()); ResetCounters(E.Origin.ClientNumber, S.GetPort());
var config = new ConfigurationManager(E.Owner); var config = new ConfigurationManager(E.Owner);
@ -300,8 +302,8 @@ namespace StatsPlugin
//todo: move this out of here!! //todo: move this out of here!!
if (checkForTrusted.TotalPlayTime >= 4320 && E.Origin.Level < Player.Permission.Trusted && E.Origin.Level != Player.Permission.Flagged) if (checkForTrusted.TotalPlayTime >= 4320 && E.Origin.Level < Player.Permission.Trusted && E.Origin.Level != Player.Permission.Flagged)
{ {
E.Origin.SetLevel(Player.Permission.Trusted); E.Origin.Level = Player.Permission.Trusted;
E.Owner.Manager.GetClientDatabase().UpdatePlayer(E.Origin); 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("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!"); await E.Origin.Tell("You earned this by playing for ^53 ^7full days!");
} }
@ -316,10 +318,10 @@ namespace StatsPlugin
continue; continue;
CalculateAndSaveSkill(P, statLists.Find(x => x.Port == S.GetPort())); 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.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) if (E.Type == Event.GType.Disconnect)
{ {
CalculateAndSaveSkill(E.Origin, statLists.Find(x => x.Port == S.GetPort())); 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}"); 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")) 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, KillerPlayer = E.Origin.Name,
VictimPlayer = E.Target.Name, VictimPlayer = E.Target.Name,
@ -366,11 +368,11 @@ namespace StatsPlugin
if (killerStats == null) if (killerStats == null)
killerStats = new PlayerStats(0, 0, 0, 0, 0, 0); killerStats = new PlayerStats(0, 0, 0, 0, 0, 0);
curServer.lastKill[E.Origin.ClientID] = DateTime.Now; curServer.lastKill[E.Origin.ClientNumber] = DateTime.Now;
curServer.Kills[E.Origin.ClientID]++; curServer.Kills[E.Origin.ClientNumber]++;
if ((DateTime.Now - curServer.lastKill[E.Origin.ClientID]).TotalSeconds > 120) if ((DateTime.Now - curServer.lastKill[E.Origin.ClientNumber]).TotalSeconds > 120)
curServer.inactiveMinutes[E.Origin.ClientID] += 2; curServer.inactiveMinutes[E.Origin.ClientNumber] += 2;
killerStats.Kills++; killerStats.Kills++;
@ -378,10 +380,10 @@ namespace StatsPlugin
curServer.playerStats.UpdateStats(Killer, killerStats); curServer.playerStats.UpdateStats(Killer, killerStats);
curServer.killStreaks[Killer.ClientID] += 1; curServer.killStreaks[Killer.ClientNumber] += 1;
curServer.deathStreaks[Killer.ClientID] = 0; 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) if (E.Type == Event.GType.Death)
@ -401,15 +403,15 @@ namespace StatsPlugin
curServer.playerStats.UpdateStats(Victim, victimStats); curServer.playerStats.UpdateStats(Victim, victimStats);
curServer.deathStreaks[Victim.ClientID] += 1; curServer.deathStreaks[Victim.ClientNumber] += 1;
curServer.killStreaks[Victim.ClientID] = 0; 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) 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); PlayerStats DisconnectingPlayerStats = curServer.playerStats.GetStats(P);
if (DisconnectingPlayerStats == null || curServer.Kills[P.ClientID] == 0) if (DisconnectingPlayerStats == null || curServer.Kills[P.ClientNumber] == 0)
return; return;
else if (curServer.lastKill[P.ClientID] > curServer.connectionTime[P.ClientID]) else if (curServer.lastKill[P.ClientNumber] > curServer.connectionTime[P.ClientNumber])
curServer.inactiveMinutes[P.ClientID] += (int)(DateTime.Now - curServer.lastKill[P.ClientID]).TotalMinutes; 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) if (newPlayTime < 2)
return; return;
// calculate the players Score Per Minute for the current session // 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 // calculate how much the KDR should way
// 1.637 is a Eddie-Generated number that weights the KDR nicely // 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); 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) { } public StatsDB(String FN, SharedLibrary.Interfaces.ILogger logger) : base(FN, logger) { }
@ -624,7 +626,7 @@ namespace StatsPlugin
{ {
Dictionary<String, object> newPlayer = new Dictionary<String, object> Dictionary<String, object> newPlayer = new Dictionary<String, object>
{ {
{ "npID", P.NetworkID }, { "npID", P.NetworkId },
{ "KILLS", 0 }, { "KILLS", 0 },
{ "DEATHS", 0 }, { "DEATHS", 0 },
{ "KDR", 0.0 }, { "KDR", 0.0 },
@ -637,7 +639,7 @@ namespace StatsPlugin
public PlayerStats GetStats(Player P) public PlayerStats GetStats(Player P)
{ {
DataTable Result = GetDataTable("STATS", new KeyValuePair<string, object>("npID", P.NetworkID)); DataTable Result = GetDataTable("STATS", new KeyValuePair<string, object>("npID", P.NetworkId));
if (Result != null && Result.Rows.Count > 0) if (Result != null && Result.Rows.Count > 0)
{ {
@ -682,7 +684,7 @@ namespace StatsPlugin
{ "SPM", Math.Round(S.scorePerMinute, 2) }, { "SPM", Math.Round(S.scorePerMinute, 2) },
{ "PLAYTIME", S.TotalPlayTime } { "PLAYTIME", S.TotalPlayTime }
}; };
Update("STATS", updatedPlayer, new KeyValuePair<string, object>("npID", P.NetworkID)); Update("STATS", updatedPlayer, new KeyValuePair<string, object>("npID", P.NetworkId));
} }
public List<KeyValuePair<String, PlayerStats>> GetTopStats() public List<KeyValuePair<String, PlayerStats>> GetTopStats()

View File

@ -4,9 +4,11 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using SharedLibrary; using SharedLibrary;
using SharedLibrary.Interfaces; using SharedLibrary.Interfaces;
using SharedLibrary.Helpers; using SharedLibrary.Helpers;
using SharedLibrary.Objects;
namespace IW4MAdmin.Plugins namespace IW4MAdmin.Plugins
{ {
@ -63,17 +65,20 @@ namespace IW4MAdmin.Plugins
{ {
var rand = new Random(); var rand = new Random();
int index = rand.Next(0, 17); 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) if (S.Players.ElementAt(index) != null)
await S.RemovePlayer(index); await S.RemovePlayer(index);
await S.AddPlayer(p); await S.AddPlayer(p);
/*
Interval = DateTime.Now; Interval = DateTime.Now;
if (S.ClientNum > 0) 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 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)]; 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; string[] eventLine = null;
@ -99,8 +104,8 @@ namespace IW4MAdmin.Plugins
eventLine = new string[] eventLine = new string[]
{ {
"ScriptKill", "ScriptKill",
attackerPlayer.NetworkID, attackerPlayer.NetworkId,
victimPlayer.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(),
new Vector3(rand.Next(minimapInfo.MaxRight, minimapInfo.MaxLeft), rand.Next(minimapInfo.MaxBottom, minimapInfo.MaxTop), rand.Next(0, 100)).ToString(), new Vector3(rand.Next(minimapInfo.MaxRight, minimapInfo.MaxLeft), rand.Next(minimapInfo.MaxBottom, minimapInfo.MaxTop), rand.Next(0, 100)).ToString(),
rand.Next(50, 105).ToString(), rand.Next(50, 105).ToString(),
@ -115,12 +120,12 @@ namespace IW4MAdmin.Plugins
eventLine = new string[] eventLine = new string[]
{ {
"K", "K",
victimPlayer.NetworkID, victimPlayer.NetworkId,
victimPlayer.ClientID.ToString(), victimPlayer.ClientNumber.ToString(),
rand.Next(0, 1) == 0 ? "allies" : "axis", rand.Next(0, 1) == 0 ? "allies" : "axis",
victimPlayer.Name, victimPlayer.Name,
attackerPlayer.NetworkID, attackerPlayer.NetworkId,
attackerPlayer.ClientID.ToString(), attackerPlayer.ClientNumber.ToString(),
rand.Next(0, 1) == 0 ? "allies" : "axis", rand.Next(0, 1) == 0 ? "allies" : "axis",
attackerPlayer.Name.ToString(), attackerPlayer.Name.ToString(),
((StatsPlugin.IW4Info.WeaponName)rand.Next(0, Enum.GetValues(typeof(StatsPlugin.IW4Info.WeaponName)).Length - 1)).ToString(), // Weapon ((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); var _event = Event.ParseEventString(eventLine, S);
await S.ExecuteEvent(_event); await S.ExecuteEvent(_event);
} }
} }*/
} }
} }

View File

@ -1,10 +1,11 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks;
using SharedLibrary; using SharedLibrary;
using SharedLibrary.Network; using SharedLibrary.Network;
using SharedLibrary.Interfaces; using SharedLibrary.Interfaces;
using System.Threading.Tasks; using SharedLibrary.Objects;
namespace Votemap_Plugin namespace Votemap_Plugin
{ {
@ -39,7 +40,7 @@ namespace Votemap_Plugin
// we only want to allow a vote during a vote session // we only want to allow a vote during a vote session
if (voting.voteInSession) if (voting.voteInSession)
{ {
if (voting.ClientHasVoted(E.Origin.NetworkID)) if (voting.ClientHasVoted(E.Origin.NetworkId))
await E.Origin.Tell("You have already voted. Use ^5!vc ^7to ^5cancel ^7your vote"); await E.Origin.Tell("You have already voted. Use ^5!vc ^7to ^5cancel ^7your vote");
else else
{ {
@ -50,7 +51,7 @@ namespace Votemap_Plugin
await E.Origin.Tell("^1" + E.Data + " is not a recognized map"); await E.Origin.Tell("^1" + E.Data + " is not a recognized map");
else else
{ {
voting.CastClientVote(E.Origin.NetworkID, votedMap); voting.CastClientVote(E.Origin.NetworkId, votedMap);
await E.Origin.Tell("You voted for ^5" + votedMap.Alias); await E.Origin.Tell("You voted for ^5" + votedMap.Alias);
} }
} }
@ -71,9 +72,9 @@ namespace Votemap_Plugin
if (voting.voteInSession) 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"); await E.Origin.Tell("Vote cancelled");
} }

View File

@ -5,14 +5,12 @@ using SharedLibrary.Interfaces;
using System.Threading.Tasks; using System.Threading.Tasks;
using SharedLibrary.Network; using SharedLibrary.Network;
using SharedLibrary.Objects;
namespace Welcome_Plugin namespace Welcome_Plugin
{ {
public class Plugin : IPlugin public class Plugin : IPlugin
{ {
Dictionary<int, float> PlayerPings;
int PingAverageCount;
String TimesConnected(Player P) String TimesConnected(Player P)
{ {
int connection = P.Connections; int connection = P.Connections;
@ -68,37 +66,14 @@ namespace Welcome_Plugin
public async Task OnLoadAsync(IManager manager) public async Task OnLoadAsync(IManager manager)
{ {
PlayerPings = new Dictionary<int, float>();
PingAverageCount = 1;
} }
public async Task OnUnloadAsync() public async Task OnUnloadAsync()
{ {
PlayerPings.Clear();
PlayerPings = null;
} }
public async Task OnTickAsync(Server S) public async Task OnTickAsync(Server S)
{ {
return;
// TODO: check if this works
int MaxPing = (await S.GetDvarAsync<int>("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) public async Task OnEventAsync(Event E, Server S)
@ -120,7 +95,7 @@ namespace Welcome_Plugin
try try
{ {
CountryLookupProj.CountryLookup CLT = new CountryLookupProj.CountryLookup("Plugins/GeoIP.dat"); CountryLookupProj.CountryLookup CLT = new CountryLookupProj.CountryLookup("Plugins/GeoIP.dat");
await E.Owner.Broadcast($"^5{newPlayer.Name} ^7hails from ^5{CLT.lookupCountryName(newPlayer.IP)}"); await E.Owner.Broadcast($"^5{newPlayer.Name} ^7hails from ^5{CLT.lookupCountryName(newPlayer.IPAddress)}");
} }
catch (Exception) catch (Exception)
@ -129,13 +104,10 @@ namespace Welcome_Plugin
} }
} }
//PlayerPings.Add(E.Origin.DatabaseID, 1.0f);
} }
if (E.Type == Event.GType.Disconnect) if (E.Type == Event.GType.Disconnect)
{ {
//PlayerPings.Remove(E.Origin.DatabaseID);
} }
} }
} }

View File

@ -2,6 +2,8 @@
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using SharedLibrary.Objects;
namespace SharedLibrary namespace SharedLibrary
{ {
public class CommandArgument public class CommandArgument

View File

@ -2,9 +2,12 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
using System.Linq; using System.Linq;
using System.Threading.Tasks;
using SharedLibrary.Network; using SharedLibrary.Network;
using SharedLibrary.Helpers; using SharedLibrary.Helpers;
using System.Threading.Tasks; using SharedLibrary.Objects;
namespace SharedLibrary.Commands namespace SharedLibrary.Commands
{ {
@ -28,11 +31,11 @@ namespace SharedLibrary.Commands
public override async Task ExecuteAsync(Event E) 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!"); 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 else
await E.Origin.Tell("This server already has an owner!"); await E.Origin.Tell("This server already has an owner!");
@ -59,11 +62,10 @@ namespace SharedLibrary.Commands
public override async Task ExecuteAsync(Event E) public override async Task ExecuteAsync(Event E)
{ {
E.Target.lastOffense = E.Data.RemoveWords(1);
if (E.Origin.Level <= E.Target.Level) if (E.Origin.Level <= E.Target.Level)
await E.Origin.Tell($"You do not have the required privileges to warn {E.Target.Name}"); await E.Origin.Tell($"You do not have the required privileges to warn {E.Target.Name}");
else 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) public override async Task ExecuteAsync(Event E)
{ {
E.Target.lastOffense = String.Empty;
E.Target.Warnings = 0; E.Target.Warnings = 0;
String Message = String.Format("All warning cleared for {0}", E.Target.Name); String Message = String.Format("All warning cleared for {0}", E.Target.Name);
await E.Owner.Broadcast(Message); await E.Owner.Broadcast(Message);
@ -109,11 +110,10 @@ namespace SharedLibrary.Commands
public override async Task ExecuteAsync(Event E) public override async Task ExecuteAsync(Event E)
{ {
E.Target.lastOffense = E.Data.RemoveWords(1);
if (E.Origin.Level > E.Target.Level) 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.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"); await E.Origin.Tell($"^5{E.Target} ^7has been kicked");
} }
else else
@ -165,8 +165,7 @@ namespace SharedLibrary.Commands
public override async Task ExecuteAsync(Event E) public override async Task ExecuteAsync(Event E)
{ {
E.Target.lastOffense = Utilities.RemoveWords(E.Data, 1); String Message = Utilities.RemoveWords(E.Data, 1);
String Message = E.Target.lastOffense;
var length = Message.ParseTimespan(); var length = Message.ParseTimespan();
if (length.TotalHours != 1) if (length.TotalHours != 1)
@ -202,17 +201,9 @@ namespace SharedLibrary.Commands
public override async Task ExecuteAsync(Event E) 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) 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(E.Data, E.Origin);
await E.Target.Ban(Message, E.Origin);
await E.Origin.Tell($"^5{E.Target} ^7has been permanently banned"); await E.Origin.Tell($"^5{E.Target} ^7has been permanently banned");
} }
else else
@ -248,7 +239,7 @@ namespace SharedLibrary.Commands
public override async Task ExecuteAsync(Event E) 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); await E.Origin.Tell(You);
} }
} }
@ -271,9 +262,9 @@ namespace SharedLibrary.Commands
continue; continue;
if (P.Masked) 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 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) if (count == 2 || E.Owner.GetPlayersAsList().Count == 1)
{ {
@ -424,16 +415,16 @@ namespace SharedLibrary.Commands
if (newPerm > Player.Permission.Banned) if (newPerm > Player.Permission.Banned)
{ {
var ActiveClient = E.Owner.Manager.GetActiveClients().FirstOrDefault(p => p.NetworkID == E.Target.NetworkID); var ActiveClient = E.Owner.Manager.GetActiveClients().FirstOrDefault(p => p.NetworkId == E.Target.NetworkId);
ActiveClient?.SetLevel(newPerm); ActiveClient.Level = newPerm;
if (ActiveClient != null) if (ActiveClient != null)
await ActiveClient.Tell("Congratulations! You have been promoted to ^3" + newPerm); await ActiveClient.Tell("Congratulations! You have been promoted to ^3" + newPerm);
await E.Origin.Tell($"{E.Target.Name} was successfully promoted!"); await E.Origin.Tell($"{E.Target.Name} was successfully promoted!");
E.Target.SetLevel(newPerm); E.Target.Level = newPerm;
E.Owner.Manager.GetClientDatabase().UpdatePlayer(E.Target); await E.Owner.Manager.GetClientService().Update(E.Target);
} }
else else
@ -536,9 +527,9 @@ namespace SharedLibrary.Commands
public override async Task ExecuteAsync(Event E) 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"); await E.Origin.Tell("No players found");
return; return;
@ -546,7 +537,7 @@ namespace SharedLibrary.Commands
foreach (Player P in db_players) 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); await E.Origin.Tell(mesg);
} }
} }
@ -575,36 +566,17 @@ namespace SharedLibrary.Commands
return; 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"); await E.Origin.Tell("No players found");
return; return;
} }
foreach (Aliases P in db_aliases) foreach (var P in db_aliases)
{ {
if (P == null) await E.Origin.Tell($"^4{P.Name} ^7now goes by ^5{P.Link.Children.OrderByDescending(a => a.DateAdded).First().Name}");
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);
}
} }
} }
} }
@ -707,21 +679,33 @@ namespace SharedLibrary.Commands
if (E.Target.Level == Player.Permission.Flagged) if (E.Target.Level == Player.Permission.Flagged)
{ {
E.Target.SetLevel(Player.Permission.User); E.Target.Level = Player.Permission.User;
E.Owner.Manager.GetClientPenalties().RemovePenalty(new Penalty(Penalty.Type.Flag, "", E.Target.NetworkID, "", DateTime.Now, "", DateTime.Now)); //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); await E.Origin.Tell("You have ^5unflagged ^7" + E.Target.Name);
} }
else else
{ {
E.Data = Utilities.RemoveWords(E.Data, 1); E.Data = Utilities.RemoveWords(E.Data, 1);
E.Target.SetLevel(Player.Permission.Flagged); E.Target.Level = 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));
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.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); 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) 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"); await E.Origin.Tell("You have already reported this player");
return; return;
@ -824,7 +808,7 @@ namespace SharedLibrary.Commands
await E.Origin.Tell("You are now masked"); 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) public override async Task ExecuteAsync(Event E)
{ {
var B = E.Owner.Manager.GetClientPenalties().FindPenalties(E.Target); var B = await E.Owner.Manager.GetPenaltyService().GetClientPenaltiesAsync(E.Target.ClientId);
var BannedPenalty = B.Find(b => b.BType > Penalty.Type.Kick && b.Expires > DateTime.Now);
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"); await E.Origin.Tell("No active ban was found for that player");
return; 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, penalty.Punisher.Name, penalty.Offense, penalty.Type == Penalty.PenaltyType.TempBan ? $"({(penalty.Expires - DateTime.Now).TimeSpanText()} remaining)" : ""));
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)" : ""));
} }
} }
@ -873,37 +856,19 @@ namespace SharedLibrary.Commands
public override async Task ExecuteAsync(Event E) 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(); StringBuilder message = new StringBuilder();
var names = new List<string>(E.Target.AliasLink.Children.Select(a => a.Name));
var IPs = new List<string>(E.Target.AliasLink.Children.Select(a => a.IP));
var playerAliases = E.Owner.GetAliases(E.Target); await E.Target.Tell($"[^3{E.Target}^7]");
message.Append("Aliases: "); message.Append("Aliases: ");
message.Append(String.Join(" | ", names));
var names = new List<string>();
var ips = new List<string>();
foreach (var alias in playerAliases)
{
names.AddRange(alias.Names);
ips.AddRange(alias.IPS);
}
message.Append(String.Join(" | ", names.Distinct()));
await E.Origin.Tell(message.ToString()); await E.Origin.Tell(message.ToString());
message.Clear(); message.Clear();
message.Append("IPs: "); message.Append("IPs: ");
message.Append(String.Join(" | ", ips.Distinct())); message.Append(String.Join(" | ", IPs));
await E.Origin.Tell(message.ToString()); await E.Origin.Tell(message.ToString());
} }
} }
@ -955,7 +920,7 @@ namespace SharedLibrary.Commands
public override async Task ExecuteAsync(Event E) 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}");
} }
} }
} }

View File

@ -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<String, object> 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<String, object> data, KeyValuePair<string, object> 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<String, object> data, KeyValuePair<string, object> 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<string, object> 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<Player> GetRecentPlayers(int count = 15, int offset = 0)
{
List<Player> returnssss = new List<Player>();
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<Player> GetPlayers(List<String> npIDs)
{
List<Player> returnssss = new List<Player>();
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<Player> GetPlayers(List<int> databaseIDs)
{
List<Player> returnssss = new List<Player>();
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<string, object>("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<string, object>("IP", IP));
if (Result != null && Result.Rows.Count > 0)
{
List<Player> lastKnown = new List<Player>();
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<Player> 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<string, object>("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<Player> 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<Player> Players = new List<Player>();
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<Penalty> GetClientPenalties(Player P)
{
List<Penalty> ClientPenalties = new List<Penalty>();
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<Penalty> GetPenaltiesChronologically(int offset, int count, Penalty.Type penaltyType)
{
List<Penalty> ClientPenalties = new List<Penalty>();
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<Player> GetAdmins()
{
List<Player> Admins = new List<Player>();
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<String, object> newPlayer = new Dictionary<String, object>
{
{ "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<String, Object> updatedPlayer = new Dictionary<String, Object>
{
{ "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<string, object>("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<String, object> newBan = new Dictionary<String, object>
{
{ "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<Aliases> 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<Aliases> players = new List<Aliases>();
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<Aliases> 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<Aliases> players = new List<Aliases>();
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<String, object> newPlayer = new Dictionary<String, object>
{
{ "Number", Alias.Number },
{ "NAMES", String.Join(";", Alias.Names) },
{ "IPS", String.Join(";", Alias.IPS) }
};
Insert("ALIASES", newPlayer);
}
public void UpdatePlayerAliases(Aliases Alias)
{
Dictionary<String, object> updatedPlayer = new Dictionary<String, object>
{
{ "Number", Alias.Number },
{ "NAMES", String.Join(";", Alias.Names) },
{ "IPS", String.Join(";", Alias.IPS) }
};
Update("ALIASES", updatedPlayer, new KeyValuePair<string, object>("Number", Alias.Number));
}
}
}

View File

@ -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<EFClient> Clients { get; set; }
public DbSet<EFAlias> Aliases { get; set; }
public DbSet<EFAliasLink> AliasLinks { get; set; }
public DbSet<EFPenalty> Penalties { get; set; }
public IW4MAdminDatabaseContext() : base("DefaultConnection")
{
System.Data.Entity.Database.SetInitializer(new Initializer());
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<EFPenalty>()
.HasRequired(p => p.Punisher)
.WithMany(c => c.AdministeredPenalties)
.HasForeignKey(c => c.PunisherId)
.WillCascadeOnDelete(false);
modelBuilder.Entity<EFPenalty>()
.HasRequired(p => p.Offender)
.WithMany(c => c.ReceivedPenalties)
.HasForeignKey(c => c.OffenderId)
.WillCascadeOnDelete(false);
modelBuilder.Entity<EFAliasLink>()
.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);
}
}
}

View File

@ -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<IW4MAdminDatabaseContext>
{
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);
}
}
}

View File

@ -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; }
}
}

View File

@ -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<EFAlias> Children { get; set; }
public EFAliasLink()
{
Children = new List<EFAlias>();
}
}
}

View File

@ -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<EFPenalty> ReceivedPenalties { get; set; }
public virtual ICollection<EFPenalty> AdministeredPenalties { get; set; }
public EFClient()
{
ReceivedPenalties = new List<EFPenalty>();
AdministeredPenalties = new List<EFPenalty>();
}
}
}

View File

@ -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; }
}
}

View File

@ -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; }
}
}

View File

@ -4,6 +4,8 @@ using System.Linq;
using System.Text; using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using SharedLibrary.Objects;
namespace SharedLibrary namespace SharedLibrary
{ {
[Serializable] [Serializable]
@ -93,7 +95,7 @@ namespace SharedLibrary
public Event(GType t, string d, Player O, Player T, Server S) public Event(GType t, string d, Player O, Player T, Server S)
{ {
Type = t; Type = t;
Data = d; Data = d.Trim();
Origin = O; Origin = O;
Target = T; Target = T;
Owner = S; Owner = S;
@ -129,14 +131,14 @@ namespace SharedLibrary
if (removeTime.Contains("ScriptKill")) if (removeTime.Contains("ScriptKill"))
{ {
return new Event(GType.Script, String.Join(";", line), SV.Players.FirstOrDefault(p => p != null && p.NetworkID == line[1]), SV.Players.FirstOrDefault(p => p != null && p.NetworkID == line[2]), SV); return new Event(GType.Script, String.Join(";", line), SV.Players.FirstOrDefault(p => p != null && p.NetworkId == line[1]), SV.Players.FirstOrDefault(p => p != null && p.NetworkId == line[2]), SV);
} }
if (removeTime.Contains("ExitLevel")) 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")) 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; return null;

View File

@ -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) { }
}
}

View File

@ -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; }
}
}

View File

@ -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<T>
{
Task<T> CreateProxy();
Task<T> Create(T entity);
Task<T> Delete(T entity);
Task<T> Update(T entity);
Task<T> Get(int entityID);
Task<T> GetUnique(string entityProperty);
Task<IList<T>> Find(Func<T, bool> expression);
}
}

View File

@ -1,4 +1,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using SharedLibrary.Objects;
using SharedLibrary.Database.Models;
using SharedLibrary.Services;
namespace SharedLibrary.Interfaces namespace SharedLibrary.Interfaces
{ {
@ -10,13 +13,10 @@ namespace SharedLibrary.Interfaces
ILogger GetLogger(); ILogger GetLogger();
IList<Server> GetServers(); IList<Server> GetServers();
IList<Command> GetCommands(); IList<Command> GetCommands();
IPenaltyList GetClientPenalties();
ClientsDB GetClientDatabase();
AliasesDB GetAliasesDatabase();
IList<Helpers.MessageToken> GetMessageTokens(); IList<Helpers.MessageToken> GetMessageTokens();
IList<Player> GetActiveClients(); IList<Player> GetActiveClients();
IList<Player> GetAliasClients(Player player); ClientService GetClientService();
IList<Aliases> GetAliases(Player player); AliasService GetAliasService();
IList<Player> GetPrivilegedClients(); PenaltyService GetPenaltyService();
} }
} }

View File

@ -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<Penalty> FindPenalties(Player P);
}
}

View File

@ -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
{
}
}

View File

@ -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"); ;
}
}
}

View File

@ -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; }
}
}

View File

@ -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; }
}
}

View File

@ -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; }
}
}

View File

@ -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<String>(I.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries));
}
public List<String> Names { get; private set; }
public List<String> 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;
}
}

View File

@ -8,6 +8,8 @@ using System.Threading.Tasks;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Net.Sockets; using System.Net.Sockets;
using SharedLibrary.Objects;
namespace SharedLibrary.Network namespace SharedLibrary.Network
{ {
public static class RCON public static class RCON

View File

@ -9,6 +9,7 @@ using SharedLibrary.Network;
using SharedLibrary.Commands; using SharedLibrary.Commands;
using System.Threading.Tasks; using System.Threading.Tasks;
using SharedLibrary.Helpers; using SharedLibrary.Helpers;
using SharedLibrary.Objects;
namespace SharedLibrary namespace SharedLibrary
{ {
@ -106,13 +107,6 @@ namespace SharedLibrary
return Players.Where(p => p != null && p.Name.ToLower().Contains(pName.ToLower())).ToList(); return Players.Where(p => p != null && p.Name.ToLower().Contains(pName.ToLower())).ToList();
} }
/// <summary>
/// Check ban list for every banned player and return ban if match is found
/// </summary>
/// <param name="C">Player to check if banned</param>
/// <returns>Matching ban if found</returns>
abstract public Penalty IsBanned(Player C);
/// <summary> /// <summary>
/// Process requested command correlating to an event /// Process requested command correlating to an event
/// </summary> /// </summary>
@ -126,16 +120,6 @@ namespace SharedLibrary
return null; return null;
} }
/// <summary>
/// Legacy method for the alias command
/// </summary>
/// <param name="P"></param>
/// <returns></returns>
public IList<Aliases> GetAliases(Player P)
{
return Manager.GetAliases(P);
}
/// <summary> /// <summary>
/// Process any server event /// Process any server event
/// </summary> /// </summary>
@ -170,14 +154,10 @@ namespace SharedLibrary
/// <param name="Target">Player to send message to</param> /// <param name="Target">Player to send message to</param>
public async Task Tell(String Message, Player Target) public async Task Tell(String Message, Player Target)
{ {
#if DEBUG
//if (!Target.lastEvent.Remote)
// return;
#endif
string tellCommand = (GameName == Game.IW4) ? "tellraw" : "tell"; string tellCommand = (GameName == Game.IW4) ? "tellraw" : "tell";
if (Target.ClientID > -1 && Message.Length > 0 && Target.Level != Player.Permission.Console && !Target.lastEvent.Remote) if (Target.ClientNumber > -1 && Message.Length > 0 && Target.Level != Player.Permission.Console)
await this.ExecuteCommandAsync($"{tellCommand} {Target.ClientID} {Message}^7"); await this.ExecuteCommandAsync($"{tellCommand} {Target.ClientNumber} {Message}^7");
if (Target.Level == Player.Permission.Console) if (Target.Level == Player.Permission.Console)
{ {
@ -185,9 +165,13 @@ namespace SharedLibrary
Console.WriteLine(Utilities.StripColors(Message)); Console.WriteLine(Utilities.StripColors(Message));
Console.ForegroundColor = ConsoleColor.Gray; Console.ForegroundColor = ConsoleColor.Gray;
} }
if (commandResult.Count > 15)
if (Target.lastEvent.Remote) commandResult.RemoveAt(0);
commandResult.Enqueue(Utilities.StripColors(Message)); commandResult.Add(new CommandResult()
{
Message = Utilities.StripColors(Message),
Clientd = Target.ClientId
});
} }
/// <summary> /// <summary>
@ -353,14 +337,14 @@ namespace SharedLibrary
return $"{IP}_{Port}"; return $"{IP}_{Port}";
} }
protected async Task<bool> ScriptLoaded() protected async Task<bool> ScriptLoaded()
{ {
try try
{ {
return (await this.GetDvarAsync<string>("sv_customcallbacks")).Value == "1"; return (await this.GetDvarAsync<string>("sv_customcallbacks")).Value == "1";
} }
catch(Exceptions.DvarException) catch (Exceptions.DvarException)
{ {
return false; return false;
} }
@ -408,6 +392,6 @@ namespace SharedLibrary
protected DateTime LastPoll; protected DateTime LastPoll;
//Remote //Remote
public Queue<string> commandResult = new Queue<string>(); public IList<CommandResult> commandResult = new List<CommandResult>();
} }
} }

View File

@ -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<EFAlias>
{
public async Task<EFAlias> 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<EFAlias> CreateProxy()
{
return null;
}
public async Task<EFAlias> 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<IList<EFAlias>> Find(Func<EFAlias, bool> expression)
{
using (var context = new IW4MAdminDatabaseContext())
return await Task.Run(() => context.Aliases.Where(expression).ToList());
}
public async Task<EFAlias> Get(int entityID)
{
using (var context = new IW4MAdminDatabaseContext())
return await context.Aliases
.SingleOrDefaultAsync(e => e.AliasId == entityID);
}
public Task<EFAlias> GetUnique(string entityProperty)
{
throw new NotImplementedException();
}
public async Task<EFAlias> 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<EFAliasLink> CreateLink(EFAliasLink link)
{
using (var context = new IW4MAdminDatabaseContext())
{
context.AliasLinks.Add(link);
await context.SaveChangesAsync();
return link;
}
}
}
}

View File

@ -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<EFClient>
{
private Dictionary<int, IW4MAdminDatabaseContext> _context;
public ClientService()
{
_context = new Dictionary<int, IW4MAdminDatabaseContext>();
}
public async Task<EFClient> 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<EFClient> 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<IList<EFClient>> Find(Func<EFClient, bool> e)
{
using (var context = new IW4MAdminDatabaseContext())
return await Task.Run(() => context.Clients
.Include(c => c.AliasLink.Children)
.Where(e).ToList());
}
public async Task<EFClient> 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<EFClient> 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<EFClient> 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<IList<EFClient>> GetOwners()
{
using (var context = new IW4MAdminDatabaseContext())
return await context.Clients.Where(c => c.Level == Objects.Player.Permission.Owner).ToListAsync();
}
public async Task<IList<EFClient>> GetPrivilegedClients()
{
using (var context = new IW4MAdminDatabaseContext())
return await new IW4MAdminDatabaseContext().Clients
.Where(c => c.Level >= Objects.Player.Permission.Trusted)
.ToListAsync();
}
public async Task<IList<EFClient>> 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<IList<EFClient>> 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<int> GetTotalClientsAsync()
{
using (var context = new IW4MAdminDatabaseContext())
return await context.Clients.CountAsync();
}
public Task<EFClient> CreateProxy()
{
throw new NotImplementedException();
}
#endregion
}
}

View File

@ -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<EFPenalty>
{
public async Task<EFPenalty> 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<EFPenalty> CreateProxy()
{
throw new NotImplementedException();
}
public Task<EFPenalty> Delete(EFPenalty entity)
{
throw new NotImplementedException();
}
public async Task<IList<EFPenalty>> Find(Func<EFPenalty, bool> 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<EFPenalty> Get(int entityID)
{
throw new NotImplementedException();
}
public Task<EFPenalty> GetUnique(string entityProperty)
{
throw new NotImplementedException();
}
public Task<EFPenalty> Update(EFPenalty entity)
{
throw new NotImplementedException();
}
public async Task<IList<EFPenalty>> 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<IList<EFPenalty>> 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();
}
}
}
}

View File

@ -66,13 +66,24 @@
<Optimize>true</Optimize> <Optimize>true</Optimize>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
<HintPath>..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.dll</HintPath>
</Reference>
<Reference Include="EntityFramework.SqlServer, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
<HintPath>..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.SqlServer.dll</HintPath>
</Reference>
<Reference Include="EntityFramework.SqlServerCompact, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
<HintPath>..\packages\EntityFramework.SqlServerCompact.6.2.0\lib\net45\EntityFramework.SqlServerCompact.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL"> <Reference Include="Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.10.0.2\lib\net45\Newtonsoft.Json.dll</HintPath> <HintPath>..\packages\Newtonsoft.Json.10.0.2\lib\net45\Newtonsoft.Json.dll</HintPath>
<Private>False</Private>
</Reference> </Reference>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.ComponentModel.DataAnnotations" />
<Reference Include="System.Core" /> <Reference Include="System.Core" />
<Reference Include="System.Data.SQLite, Version=1.0.105.1, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=MSIL"> <Reference Include="System.Data.SqlServerCe, Version=4.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91, processorArchitecture=MSIL">
<HintPath>..\packages\System.Data.SQLite.Core.1.0.105.1\lib\net45\System.Data.SQLite.dll</HintPath> <HintPath>..\packages\Microsoft.SqlServer.Compact.4.0.8876.1\lib\net40\System.Data.SqlServerCe.dll</HintPath>
<Private>True</Private> <Private>True</Private>
</Reference> </Reference>
<Reference Include="System.Web" /> <Reference Include="System.Web" />
@ -83,6 +94,14 @@
<Reference Include="System.Xml" /> <Reference Include="System.Xml" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="Database\Initializer.cs" />
<Compile Include="Database\IW4MAdminDatabaseContext.cs" />
<Compile Include="Database\Models\EFAlias.cs" />
<Compile Include="Database\Models\EFAliasLink.cs" />
<Compile Include="Database\Models\EFClient.cs" />
<Compile Include="Database\Models\EFPenalty.cs" />
<Compile Include="Database\Models\SharedEntity.cs" />
<Compile Include="Exceptions\DatabaseException.cs" />
<Compile Include="Helpers\AsyncStatus.cs" /> <Compile Include="Helpers\AsyncStatus.cs" />
<Compile Include="Commands\NativeCommands.cs" /> <Compile Include="Commands\NativeCommands.cs" />
<Compile Include="Exceptions\CommandException.cs" /> <Compile Include="Exceptions\CommandException.cs" />
@ -90,29 +109,34 @@
<Compile Include="Exceptions\NetworkException.cs" /> <Compile Include="Exceptions\NetworkException.cs" />
<Compile Include="Exceptions\SerializationException.cs" /> <Compile Include="Exceptions\SerializationException.cs" />
<Compile Include="Exceptions\ServerException.cs" /> <Compile Include="Exceptions\ServerException.cs" />
<Compile Include="Helpers\CommandResult.cs" />
<Compile Include="Helpers\ConfigurationManager.cs" /> <Compile Include="Helpers\ConfigurationManager.cs" />
<Compile Include="Helpers\ParseEnum.cs" /> <Compile Include="Helpers\ParseEnum.cs" />
<Compile Include="Helpers\Vector3.cs" /> <Compile Include="Helpers\Vector3.cs" />
<Compile Include="Interfaces\IEntityService.cs" />
<Compile Include="Interfaces\ILogger.cs" /> <Compile Include="Interfaces\ILogger.cs" />
<Compile Include="Interfaces\IManager.cs" /> <Compile Include="Interfaces\IManager.cs" />
<Compile Include="Interfaces\IPenaltyList.cs" />
<Compile Include="Interfaces\ISerializable.cs" /> <Compile Include="Interfaces\ISerializable.cs" />
<Compile Include="Helpers\MessageToken.cs" /> <Compile Include="Helpers\MessageToken.cs" />
<Compile Include="Penalty.cs" /> <Compile Include="Objects\Alias.cs" />
<Compile Include="Objects\Penalty.cs" />
<Compile Include="Command.cs" /> <Compile Include="Command.cs" />
<Compile Include="Database.cs" />
<Compile Include="Event.cs" /> <Compile Include="Event.cs" />
<Compile Include="File.cs" /> <Compile Include="File.cs" />
<Compile Include="Dvar.cs" /> <Compile Include="Dvar.cs" />
<Compile Include="Map.cs" /> <Compile Include="Map.cs" />
<Compile Include="Helpers\PlayerHistory.cs" /> <Compile Include="Helpers\PlayerHistory.cs" />
<Compile Include="Player.cs" /> <Compile Include="Objects\Player.cs" />
<Compile Include="Interfaces\IPlugin.cs" /> <Compile Include="Interfaces\IPlugin.cs" />
<Compile Include="Objects\Report.cs" />
<Compile Include="PluginImporter.cs" /> <Compile Include="PluginImporter.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="RCON.cs" /> <Compile Include="RCON.cs" />
<Compile Include="Server.cs" /> <Compile Include="Server.cs" />
<Compile Include="ServerConfiguration.cs" /> <Compile Include="ServerConfiguration.cs" />
<Compile Include="Services\AliasService.cs" />
<Compile Include="Services\ClientService.cs" />
<Compile Include="Services\PenaltyService.cs" />
<Compile Include="Utilities.cs" /> <Compile Include="Utilities.cs" />
<Compile Include="WebService.cs" /> <Compile Include="WebService.cs" />
</ItemGroup> </ItemGroup>
@ -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)BUILD\lib"
copy /Y "$(TargetDir)$(TargetName).dll" "$(SolutionDir)Admin\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)BUILD\lib"
copy /Y "$(TargetDir)Newtonsoft.Json.dll" "$(SolutionDir)Admin\lib"</PostBuildEvent> 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"</PostBuildEvent>
</PropertyGroup> </PropertyGroup>
<Import Project="..\packages\System.Data.SQLite.Core.1.0.105.1\build\net45\System.Data.SQLite.Core.targets" Condition="Exists('..\packages\System.Data.SQLite.Core.1.0.105.1\build\net45\System.Data.SQLite.Core.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>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}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\System.Data.SQLite.Core.1.0.105.1\build\net45\System.Data.SQLite.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\System.Data.SQLite.Core.1.0.105.1\build\net45\System.Data.SQLite.Core.targets'))" />
</Target>
<PropertyGroup> <PropertyGroup>
<PreBuildEvent>if exist "$(SolutionDir)BUILD\Plugins" rmdir /Q /S "$(SolutionDir)BUILD\Plugins" <PreBuildEvent>if exist "$(SolutionDir)BUILD\Plugins" rmdir /Q /S "$(SolutionDir)BUILD\Plugins"
mkdir "$(SolutionDir)BUILD\Plugins" mkdir "$(SolutionDir)BUILD\Plugins"

View File

@ -4,6 +4,8 @@ using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Linq; using System.Linq;
using System.Collections.Generic; using System.Collections.Generic;
using SharedLibrary.Objects;
using static SharedLibrary.Server; using static SharedLibrary.Server;
namespace SharedLibrary namespace SharedLibrary
@ -60,7 +62,7 @@ namespace SharedLibrary
int.TryParse(playerInfo[0], out cID); int.TryParse(playerInfo[0], out cID);
var regex = Regex.Match(responseLine, @"\d+\.\d+\.\d+.\d+\:\d{1,5}"); var regex = Regex.Match(responseLine, @"\d+\.\d+\.\d+.\d+\:\d{1,5}");
string cIP = regex.Value.Split(':')[0]; 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); StatusPlayers.Add(P);
} }
} }
@ -224,7 +226,7 @@ namespace SharedLibrary
} }
if (Elapsed.TotalDays <= 365) if (Elapsed.TotalDays <= 365)
{ {
if (Elapsed.TotalDays < 1.5) if (Elapsed.TotalDays < 1.5)
return $"1 day{ago}"; return $"1 day{ago}";
return Math.Round(Elapsed.TotalDays, 0) + $" days{ago}"; return Math.Round(Elapsed.TotalDays, 0) + $" days{ago}";
} }
@ -297,5 +299,26 @@ namespace SharedLibrary
{ {
return markdownString.Replace("<", "\\<").Replace(">", "\\>").Replace("|", "\\|"); 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
};
}
} }
} }

View File

@ -2,6 +2,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks;
namespace SharedLibrary namespace SharedLibrary
{ {
@ -27,7 +28,7 @@ namespace SharedLibrary
{ {
string GetPath(); string GetPath();
string GetName(); string GetName();
HttpResponse GetPage(System.Collections.Specialized.NameValueCollection querySet, IDictionary<string, string> headers); Task<HttpResponse> GetPage(System.Collections.Specialized.NameValueCollection querySet, IDictionary<string, string> headers);
bool Visible(); bool Visible();
} }
@ -89,7 +90,7 @@ namespace SharedLibrary
abstract public string GetContent(System.Collections.Specialized.NameValueCollection querySet, IDictionary<string, string> headers); abstract public string GetContent(System.Collections.Specialized.NameValueCollection querySet, IDictionary<string, string> headers);
public HttpResponse GetPage(System.Collections.Specialized.NameValueCollection querySet, IDictionary<string, string> headers) public async Task<HttpResponse> GetPage(System.Collections.Specialized.NameValueCollection querySet, IDictionary<string, string> headers)
{ {
HttpResponse resp = new HttpResponse() HttpResponse resp = new HttpResponse()
{ {

View File

@ -1,5 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<packages> <packages>
<package id="EntityFramework" version="6.2.0" targetFramework="net45" />
<package id="EntityFramework.SqlServerCompact" version="6.2.0" targetFramework="net45" />
<package id="Microsoft.SqlServer.Compact" version="4.0.8876.1" targetFramework="net45" />
<package id="Newtonsoft.Json" version="10.0.2" targetFramework="net45" /> <package id="Newtonsoft.Json" version="10.0.2" targetFramework="net45" />
<package id="System.Data.SQLite.Core" version="1.0.105.1" targetFramework="net45" />
</packages> </packages>