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

View File

@ -1,11 +1,37 @@
<?xml version="1.0"?>
<?xml version="1.0" encoding="utf-8"?>
<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>
<supportedRuntime version="v4.5" sku=".NETFramework,Version=v4.5"/>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/>
</startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="lib"/>
</assemblyBinding>
</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>

View File

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

View File

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

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.Network;
using SharedLibrary.Interfaces;
using SharedLibrary.Objects;
using System.Text.RegularExpressions;
namespace IW4MAdmin
{
@ -15,128 +17,109 @@ namespace IW4MAdmin
{
public IW4MServer(IManager mgr, ServerConfiguration cfg) : base(mgr, cfg) { }
override public async Task<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
return false;
if (Players[P.ClientID] != null && Players[P.ClientID].NetworkID == P.NetworkID) // if someone has left and a new person has taken their spot between polls
if (Players[polledPlayer.ClientNumber] != null &&
Players[polledPlayer.ClientNumber].NetworkId == polledPlayer.NetworkId)
{
// update their ping
Players[P.ClientID].Ping = P.Ping;
Players[polledPlayer.ClientNumber].Ping = polledPlayer.Ping;
return true;
}
if (P.Name.Length < 3)
if (polledPlayer.Name.Length < 3)
{
await this.ExecuteCommandAsync($"clientkick {P.ClientID} \"Your name must contain atleast 3 characters.\"");
await this.ExecuteCommandAsync($"clientkick {polledPlayer.ClientNumber} \"Your name must contain atleast 3 characters.\"");
return false;
}
Logger.WriteDebug($"Client slot #{P.ClientID} now reserved");
Logger.WriteDebug($"Client slot #{polledPlayer.ClientNumber} now reserved");
try
{
Player NewPlayer = Manager.GetClientDatabase().GetPlayer(P.NetworkID, P.ClientID);
Player player = null;
var client = (await Manager.GetClientService().GetUnique(polledPlayer.NetworkId));
if (NewPlayer == null) // first time connecting
// first time client is connecting to server
if (client == null)
{
Logger.WriteDebug($"Client slot #{P.ClientID} first time connecting");
Manager.GetClientDatabase().AddPlayer(P);
NewPlayer = Manager.GetClientDatabase().GetPlayer(P.NetworkID, P.ClientID);
Manager.GetAliasesDatabase().AddPlayerAliases(new Aliases(NewPlayer.DatabaseID, NewPlayer.Name, NewPlayer.IP));
Logger.WriteDebug($"Client {polledPlayer} first time connecting");
player = (await Manager.GetClientService().Create(polledPlayer)).AsPlayer();
}
List<Player> Admins = Manager.GetClientDatabase().GetAdmins();
if (Admins.Find(x => x.Name == P.Name) != null)
{
if ((Admins.Find(x => x.Name == P.Name).NetworkID != P.NetworkID) && NewPlayer.Level < Player.Permission.Moderator)
await this.ExecuteCommandAsync("clientkick " + P.ClientID + " \"Please do not impersonate an admin^7\"");
}
// below this needs to be optimized ~ 425ms runtime
NewPlayer.UpdateName(P.Name.Trim());
NewPlayer.Alias = Manager.GetAliasesDatabase().GetPlayerAliases(NewPlayer.DatabaseID);
if (NewPlayer.Alias == null)
{
Manager.GetAliasesDatabase().AddPlayerAliases(new Aliases(NewPlayer.DatabaseID, NewPlayer.Name, NewPlayer.IP));
NewPlayer.Alias = Manager.GetAliasesDatabase().GetPlayerAliases(NewPlayer.DatabaseID);
}
if (P.lastEvent == null || P.lastEvent.Owner == null)
NewPlayer.lastEvent = new Event(Event.GType.Say, null, NewPlayer, null, this); // this is messy but its throwing an error when they've started in too late
// client has connected in the past
else
NewPlayer.lastEvent = P.lastEvent;
// lets check aliases
if ((NewPlayer.Alias.Names.Find(m => m.Equals(P.Name))) == null || NewPlayer.Name == null || NewPlayer.Name == String.Empty)
{
NewPlayer.UpdateName(P.Name.Trim());
NewPlayer.Alias.Names.Add(NewPlayer.Name);
client.Connections += 1;
bool aliasExists = client.AliasLink.Children
.FirstOrDefault(a => a.Name == polledPlayer.Name && a.IP == polledPlayer.IPAddress) != null;
if (!aliasExists)
{
Logger.WriteDebug($"Client {polledPlayer} has connected previously under a different alias");
await Manager.GetAliasService().Create(new SharedLibrary.Database.Models.EFAlias()
{
Active = true,
IP = polledPlayer.IPAddress,
Name = polledPlayer.Name,
DateAdded = DateTime.UtcNow,
Link = client.AliasLink,
});
}
client.Name = polledPlayer.Name;
client.IPAddress = polledPlayer.IPAddress;
player = client.AsPlayer();
}
// and ips
if (NewPlayer.Alias.IPS.Find(i => i.Equals(P.IP)) == null || P.IP == null || P.IP == String.Empty)
NewPlayer.Alias.IPS.Add(P.IP);
NewPlayer.SetIP(P.IP);
Manager.GetAliasesDatabase().UpdatePlayerAliases(NewPlayer.Alias);
Manager.GetClientDatabase().UpdatePlayer(NewPlayer);
await ExecuteEvent(new Event(Event.GType.Connect, "", NewPlayer, null, this));
if (NewPlayer.Level == Player.Permission.Banned) // their guid is already banned so no need to check aliases
/*var Admins = Manager.GetDatabase().GetPrivilegedClients();
if (Admins.Where(x => x.Name == polledPlayer.Name).Count() > 0)
{
Logger.WriteInfo($"Banned client {P.Name}::{P.NetworkID} trying to connect...");
await NewPlayer.Kick(NewPlayer.lastOffense != null ? "^7Previously banned for ^5 " + NewPlayer.lastOffense : "^7Previous Ban", NewPlayer);
if ((Admins.First(x => x.Name == polledPlayer.Name).NetworkId != polledPlayer.NetworkId) && NewPlayer.Level < Player.Permission.Moderator)
await this.ExecuteCommandAsync("clientkick " + polledPlayer.ClientNumber + " \"Please do not impersonate an admin^7\"");
}*/
player.CurrentServer = this;
var ban = (await Manager.GetPenaltyService().Find(p => p.LinkId == player.AliasLink.AliasLinkId
&& p.Expires > DateTime.UtcNow)).FirstOrDefault();
if (ban != null)
{
Logger.WriteInfo($"Banned client {player} trying to connect...");
var autoKickClient = (await Manager.GetClientService().Get(1)).AsPlayer();
autoKickClient.CurrentServer = this;
if (ban.Type == Penalty.PenaltyType.TempBan)
await this.ExecuteCommandAsync($"clientkick {player.ClientNumber} \"You are temporarily banned. ({(ban.Expires - DateTime.Now).TimeSpanText()} left)\"");
else
await player.Kick($"previously banned for {ban.Offense}", autoKickClient);
if (player.Level != Player.Permission.Banned && ban.Type == Penalty.PenaltyType.Ban)
await player.Ban($"previously banned for {ban.Offense}", autoKickClient);
return true;
}
var newPlayerAliases = Manager.GetAliasClients(NewPlayer);
// if (aP.Level == Player.Permission.Flagged)
// NewPlayer.Level = Player.Permission.Flagged;
// Do the player specific stuff
player.ClientNumber = polledPlayer.ClientNumber;
Players[player.ClientNumber] = player;
await Manager.GetClientService().Update(player);
Logger.WriteInfo($"Client {player} connecting..."); // they're clean
foreach (Player aP in newPlayerAliases) // lets check their aliases
{
if (aP == null)
continue;
await ExecuteEvent(new Event(Event.GType.Connect, "", player, null, this));
if (aP.Level == Player.Permission.Flagged)
NewPlayer.SetLevel(Player.Permission.Flagged);
Penalty B = IsBanned(aP);
if (B != null && B.BType == Penalty.Type.Ban)
{
Logger.WriteDebug($"Banned client {aP.Name}::{aP.NetworkID} is connecting with new alias {NewPlayer.Name}");
NewPlayer.lastOffense = String.Format("Evading ( {0} )", aP.Name);
await NewPlayer.Ban(B.Reason != null ? "^7Previously banned for ^5 " + B.Reason : "^7Previous Ban", NewPlayer);
Players[NewPlayer.ClientID] = null;
return true;
}
var activeTB = IsTempBanned(aP);
if (activeTB != null)
{
await this.ExecuteCommandAsync($"clientkick {NewPlayer.ClientID} \"You are temporarily banned. ({(activeTB.Expires - DateTime.Now).TimeSpanText()} left)\"");
}
}
Players[NewPlayer.ClientID] = NewPlayer;
Logger.WriteInfo($"Client {NewPlayer.Name}::{NewPlayer.NetworkID} connecting..."); // they're clean
if (NewPlayer.Level > Player.Permission.Moderator)
await NewPlayer.Tell("There are ^5" + Reports.Count + " ^7recent reports!");
// if (NewPlayer.Level > Player.Permission.Moderator)
// await NewPlayer.Tell("There are ^5" + Reports.Count + " ^7recent reports!");
return true;
}
catch (Exception E)
{
Manager.GetLogger().WriteError($"Unable to add player {P.Name}::{P.NetworkID}");
Manager.GetLogger().WriteError($"Unable to add player {polledPlayer.Name}::{polledPlayer.NetworkId}");
Manager.GetLogger().WriteDebug(E.StackTrace);
return false;
}
@ -148,10 +131,10 @@ namespace IW4MAdmin
if (cNum >= 0)
{
Player Leaving = Players[cNum];
Leaving.Connections++;
Manager.GetClientDatabase().UpdatePlayer(Leaving);
Leaving.TotalConnectionTime += (int)(DateTime.UtcNow - Leaving.ConnectionTime).TotalSeconds;
await Manager.GetClientService().Update(Leaving);
Logger.WriteInfo($"Client {Leaving.Name}::{Leaving.NetworkID} disconnecting...");
Logger.WriteInfo($"Client {Leaving} disconnecting...");
await ExecuteEvent(new Event(Event.GType.Disconnect, "", Leaving, null, this));
Players[cNum] = null;
}
@ -182,17 +165,6 @@ namespace IW4MAdmin
return Players[pID];
}
//Check ban list for every banned player and return ban if match is found
override public Penalty IsBanned(Player C)
{
return Manager.GetClientPenalties().FindPenalties(C).Where(b => b.BType == Penalty.Type.Ban).FirstOrDefault();
}
public Penalty IsTempBanned(Player C)
{
return Manager.GetClientPenalties().FindPenalties(C).FirstOrDefault(b => b.BType == Penalty.Type.TempBan && b.Expires > DateTime.Now);
}
//Process requested command correlating to an event
// todo: this needs to be removed out of here
override public async Task<Command> ValidateCommand(Event E)
@ -234,19 +206,16 @@ namespace IW4MAdmin
int cNum = -1;
int.TryParse(Args[0], out cNum);
if (Args[0] == String.Empty)
return C;
if (Args[0][0] == '@') // user specifying target by database ID
{
int dbID = -1;
int.TryParse(Args[0].Substring(1, Args[0].Length - 1), out dbID);
Player found = Manager.GetClientDatabase().GetPlayer(dbID);
var found = await Manager.GetClientService().Get(dbID);
if (found != null)
{
E.Target = found;
E.Target.lastEvent = E;
E.Target = found.AsPlayer();
E.Target.CurrentServer = this as IW4MServer;
E.Owner = this as IW4MServer;
}
}
@ -254,7 +223,10 @@ namespace IW4MAdmin
else if (Args[0].Length < 3 && cNum > -1 && cNum < 18) // user specifying target by client num
{
if (Players[cNum] != null)
{
E.Target = Players[cNum];
E.Data = String.Join(" ", Args.Skip(1));
}
}
List<Player> matchingPlayers;
@ -268,7 +240,10 @@ namespace IW4MAdmin
throw new SharedLibrary.Exceptions.CommandException($"{E.Origin} had multiple players found for {C.Name}");
}
else if (matchingPlayers.Count == 1)
{
E.Target = matchingPlayers.First();
E.Data = Regex.Replace(E.Data, $"\"{E.Target.Name}\"", "", RegexOptions.IgnoreCase).Trim();
}
}
if (E.Target == null) // Find active player as single word
@ -278,11 +253,14 @@ namespace IW4MAdmin
{
await E.Origin.Tell("Multiple players match that name");
foreach (var p in matchingPlayers)
await E.Origin.Tell($"[^3{p.ClientID}^7] {p.Name}");
await E.Origin.Tell($"[^3{p.ClientNumber}^7] {p.Name}");
throw new SharedLibrary.Exceptions.CommandException($"{E.Origin} had multiple players found for {C.Name}");
}
else if (matchingPlayers.Count == 1)
{
E.Target = matchingPlayers.First();
E.Data = Regex.Replace(E.Data, $"{E.Target.Name}", "", RegexOptions.IgnoreCase).Trim();
}
}
if (E.Target == null && C.RequiresTarget)
@ -327,12 +305,21 @@ namespace IW4MAdmin
for (int i = 0; i < Players.Count; i++)
{
if (CurrentPlayers.Find(p => p.ClientID == i) == null && Players[i] != null)
if (CurrentPlayers.Find(p => p.ClientNumber == i) == null && Players[i] != null)
await RemovePlayer(i);
}
//polledPlayer.ClientNumber < 0 || polledPlayer.ClientNumber > (Players.Count - 1) || polledPlayer.Ping < 1 || polledPlayer.Ping == 999
foreach (var P in CurrentPlayers)
{
if (P.Ping == 999 || P.ClientNumber > MaxClients - 1 || P.ClientNumber < 0)
{
Logger.WriteDebug($"Skipping client not in connected state {P}");
continue;
}
await AddPlayer(P);
}
return CurrentPlayers.Count;
}
@ -441,8 +428,6 @@ namespace IW4MAdmin
if (event_.Origin == null)
continue;
event_.Origin.lastEvent = event_;
event_.Origin.lastEvent.Owner = this;
await ExecuteEvent(event_);
}
}
@ -623,9 +608,6 @@ namespace IW4MAdmin
else // Not a command
{
E.Data = E.Data.StripColors();
// this should not be done for all messages.
//if (E.Data.Length > 50)
// E.Data = E.Data.Substring(0, 50) + "...";
ChatHistory.Add(new Chat(E.Origin.Name, E.Data, DateTime.Now));
}
@ -661,46 +643,98 @@ namespace IW4MAdmin
public override async Task Warn(String Reason, Player Target, Player Origin)
{
if (Target.Warnings >= 4)
await Target.Kick("Too many warnings!", Origin);
await Target.Kick("Too many warnings!", (await Manager.GetClientService().Get(1)).AsPlayer());
else
{
Penalty newPenalty = new Penalty(Penalty.Type.Warning, Reason.StripColors(), Target.NetworkID, Origin.NetworkID, DateTime.Now, Target.IP, DateTime.Now);
Manager.GetClientPenalties().AddPenalty(newPenalty);
Penalty newPenalty = new Penalty()
{
Type = Penalty.PenaltyType.Warning,
Expires = DateTime.UtcNow,
Offender = Target,
Offense = Reason,
Punisher = Origin,
Active = true,
When = DateTime.UtcNow,
Link = Target.AliasLink
};
await Manager.GetPenaltyService().Create(newPenalty);
Target.Warnings++;
String Message = String.Format("^1WARNING ^7[^3{0}^7]: ^3{1}^7, {2}", Target.Warnings, Target.Name, Target.lastOffense);
String Message = String.Format("^1WARNING ^7[^3{0}^7]: ^3{1}^7, {2}", Target.Warnings, Target.Name, Reason);
await Broadcast(Message);
}
}
public override async Task Kick(String Reason, Player Target, Player Origin)
{
if (Target.ClientID > -1)
if (Target.ClientNumber > -1)
{
String Message = "^1Player Kicked: ^5" + Reason;
Penalty newPenalty = new Penalty(Penalty.Type.Kick, Reason.StripColors().Trim(), Target.NetworkID, Origin.NetworkID, DateTime.Now, Target.IP, DateTime.Now);
Manager.GetClientPenalties().AddPenalty(newPenalty);
await this.ExecuteCommandAsync($"clientkick {Target.ClientID} \"{Message}^7\"");
await Manager.GetPenaltyService().Create(new Penalty()
{
Type = Penalty.PenaltyType.Kick,
Expires = DateTime.UtcNow,
Offender = Target,
Offense = Reason,
Punisher = Origin,
Active = true,
When = DateTime.UtcNow,
Link = Target.AliasLink
});
await this.ExecuteCommandAsync($"clientkick {Target.ClientNumber} \"{Message}^7\"");
}
}
public override async Task TempBan(String Reason, TimeSpan length, Player Target, Player Origin)
{
await this.ExecuteCommandAsync($"clientkick {Target.ClientID } \"^1Player Temporarily Banned: ^5{ Reason }\"");
Penalty newPenalty = new Penalty(Penalty.Type.TempBan, Reason.StripColors(), Target.NetworkID, Origin.NetworkID, DateTime.Now, Target.IP, DateTime.Now + length);
await Task.Run(() =>
await this.ExecuteCommandAsync($"clientkick {Target.ClientNumber } \"^1Player Temporarily Banned: ^5{ Reason }\"");
Penalty newPenalty = new Penalty()
{
Manager.GetClientPenalties().AddPenalty(newPenalty);
});
Type = Penalty.PenaltyType.TempBan,
Expires = DateTime.UtcNow + length,
Offender = Target,
Offense = Reason,
Punisher = Origin,
Active = true,
When = DateTime.UtcNow,
Link = Target.AliasLink
};
await Manager.GetPenaltyService().Create(newPenalty);
}
override public async Task Ban(String Message, Player Target, Player Origin)
{
if (Target == null)
Penalty newPenalty = new Penalty()
{
Logger.WriteError("Ban target is null");
Logger.WriteDebug($"Message: {Message}");
Logger.WriteDebug($"Origin: {Origin.Name}::{Origin.NetworkID}");
return;
Type = Penalty.PenaltyType.Ban,
Expires = DateTime.MinValue,
Offender = Target,
Offense = Message,
Punisher = Origin,
Active = true,
When = DateTime.UtcNow,
Link = Target.AliasLink
};
await Manager.GetPenaltyService().Create(newPenalty);
Target.Level = Player.Permission.Banned;
await Manager.GetClientService().Update(Target);
lock (Reports) // threading seems to do something weird here
{
List<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
@ -708,65 +742,19 @@ namespace IW4MAdmin
{
if (server.GetPlayersAsList().Count > 0)
{
var activeClient = server.GetPlayersAsList().SingleOrDefault(x => x.NetworkID == Target.NetworkID);
var activeClient = server.GetPlayersAsList().SingleOrDefault(x => x.NetworkId == Target.NetworkId);
if (activeClient != null)
{
await server.ExecuteCommandAsync($"clientkick {activeClient.ClientID} \"{Message} ^7 ({Website}) ^7\"");
await server.ExecuteCommandAsync($"clientkick {activeClient.ClientNumber} \"Player Banned: ^5{Message} ^7(appeal at {Website}) ^7\"");
break;
}
}
}
if (Origin != null)
{
Target.SetLevel(Player.Permission.Banned);
Penalty newBan = new Penalty(Penalty.Type.Ban, Target.lastOffense, Target.NetworkID, Origin.NetworkID, DateTime.Now, Target.IP, DateTime.MaxValue);
await Task.Run(() =>
{
Manager.GetClientPenalties().AddPenalty(newBan);
Manager.GetClientDatabase().UpdatePlayer(Target);
});
lock (Reports) // threading seems to do something weird here
{
List<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)
{
// database stuff can be time consuming
await Task.Run(() =>
{
var FoundPenalties = Manager.GetClientPenalties().FindPenalties(Target);
FoundPenalties.Where(p => p.BType > Penalty.Type.Kick)
.All(p =>
{
Manager.GetClientPenalties().RemovePenalty(p);
return true;
});
Player P = Manager.GetClientDatabase().GetPlayer(Target.NetworkID, -1);
if (P.Level < Player.Permission.Trusted)
{
P.SetLevel(Player.Permission.User);
Manager.GetClientDatabase().UpdatePlayer(P);
}
});
await Manager.GetPenaltyService().RemoveActivePenalties(Target.AliasLink.AliasLinkId);
}
public override bool Reload()
@ -790,7 +778,7 @@ namespace IW4MAdmin
override public void InitializeTokens()
{
Manager.GetMessageTokens().Add(new SharedLibrary.Helpers.MessageToken("TOTALPLAYERS", Manager.GetClientDatabase().TotalPlayers().ToString));
Manager.GetMessageTokens().Add(new SharedLibrary.Helpers.MessageToken("TOTALPLAYERS", Manager.GetClientService().GetTotalClientsAsync().Result.ToString));
Manager.GetMessageTokens().Add(new SharedLibrary.Helpers.MessageToken("VERSION", Program.Version.ToString));
}
}

View File

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

Binary file not shown.

Binary file not shown.

View File

@ -1,6 +1,6 @@
<script>
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) {
case 6:
$('#owner-privilege .clients').append(playerText);

View File

@ -1,77 +1,70 @@
<div id="consoleWrap">
<select id="serverSelection">
</select>
<hr/>
<div id="console">
</div>
<hr/>
<div class="playerSearchWrap table">
<input type="text" class="search tableCell" placeholder="Enter Command..."/>
<input type="button" class="searchButton tableCell" name="Search" value="Execute"/>
</div>
<select id="serverSelection"></select>
<hr />
<div id="console">
</div>
<hr />
<div class="playerSearchWrap table">
<input type="text" class="search tableCell" placeholder="Enter Command..." />
<input type="button" class="searchButton tableCell" name="Search" value="Execute" />
</div>
</div>
<script>
var cmdResultQueue = [];
$( document ).ready(function() {
cmdResultQueue = [];
$.getJSON("/_servers", function(servers) {
$.each(servers, function(i, server) {
$('select').append("<option value=\"" + server['serverPort'] + "\">" + server['serverName'] + "</option>");
var cmdResultQueue = [];
$(document).ready(function () {
cmdResultQueue = [];
$.getJSON("/_servers", function (servers) {
$.each(servers, function (i, server) {
$('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)
{
$.each(result, function(i, line) {
if (line == "You entered an invalid command!" || line == "All commands must start with '!'" )
{
line = getColorForLevel("Banned", line);
cmdResultQueue.push(line);
// });
}
else
{
line = getColorForLevel("Trusted", line);
}
if (cmdResultQueue.length > 12)
cmdResultQueue.shift();
cmdResultQueue.push(line);
});
}
function formatCommandResults() {
$('#console').html("");
function formatCommandResults()
{
$('#console').html("");
for (i = 0; i < cmdResultQueue.length; i++)
$('#console').append("<span class=\"commandResult\">"
+ cmdResultQueue[i] + "</span><br/>"
);
}
for (i = 0; i < cmdResultQueue.length; i++)
$('#console').append("<span class=\"commandResult\">"
+ cmdResultQueue[i] + "</span><br/>"
);
}
$('.searchButton').click(function() {
if ($('.search').val().length > 0)
{
if ($('.search').val()[0] != '!')
{
addCommandResult(["All commands must start with '!'"]);
formatCommandResults();
return false;
$('.searchButton').click(function () {
if ($('.search').val().length > 0) {
if ($('.search').val()[0] != '!') {
addCommandResult(["All commands must start with '!'"]);
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) {
$.each(result, function(i, line) {
addCommandResult(line)
});
}).done(function (data) { formatCommandResults(); $('.search').val(""); });
}
});
$(document).keypress(function(e) {
if(e.which == 13) {
$('.searchButton').click();
}
});
$(document).keypress(function (e) {
if (e.which == 13) {
$('.searchButton').click();
}
});
</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
# Visual Studio 15
VisualStudioVersion = 15.0.27004.2006
VisualStudioVersion = 15.0.27004.2009
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Application", "Admin\Application.csproj", "{DD5DCDA2-51DB-4B1A-922F-5705546E6115}"
ProjectSection(ProjectDependencies) = postProject
@ -49,6 +49,10 @@ Global
Debug|Mixed Platforms = Debug|Mixed Platforms
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|Mixed Platforms = Release|Mixed Platforms
Release|x64 = Release|x64
Release|x86 = Release|x86
Release-Nightly|Any CPU = Release-Nightly|Any CPU
Release-Nightly|Mixed Platforms = Release-Nightly|Mixed Platforms
Release-Nightly|x64 = Release-Nightly|x64
@ -67,6 +71,14 @@ Global
{DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Debug|x64.Build.0 = Debug|Any CPU
{DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Debug|x86.ActiveCfg = Debug|x86
{DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Debug|x86.Build.0 = Debug|x86
{DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release|Any CPU.ActiveCfg = Release-Stable|Any CPU
{DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release|Any CPU.Build.0 = Release-Stable|Any CPU
{DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release|Mixed Platforms.ActiveCfg = Release-Stable|x86
{DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release|Mixed Platforms.Build.0 = Release-Stable|x86
{DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release|x64.ActiveCfg = Release-Stable|Any CPU
{DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release|x64.Build.0 = Release-Stable|Any CPU
{DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release|x86.ActiveCfg = Release-Stable|x86
{DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release|x86.Build.0 = Release-Stable|x86
{DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release-Nightly|Any CPU.ActiveCfg = Release-Nightly|Any CPU
{DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release-Nightly|Any CPU.Build.0 = Release-Nightly|Any CPU
{DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release-Nightly|Mixed Platforms.ActiveCfg = Release-Nightly|x86
@ -91,6 +103,14 @@ Global
{4785AB75-66F3-4391-985D-63A5A049A0FA}.Debug|x64.Build.0 = Debug|Any CPU
{4785AB75-66F3-4391-985D-63A5A049A0FA}.Debug|x86.ActiveCfg = Debug|x86
{4785AB75-66F3-4391-985D-63A5A049A0FA}.Debug|x86.Build.0 = Debug|x86
{4785AB75-66F3-4391-985D-63A5A049A0FA}.Release|Any CPU.ActiveCfg = Release-Stable|Any CPU
{4785AB75-66F3-4391-985D-63A5A049A0FA}.Release|Any CPU.Build.0 = Release-Stable|Any CPU
{4785AB75-66F3-4391-985D-63A5A049A0FA}.Release|Mixed Platforms.ActiveCfg = Release-Stable|x86
{4785AB75-66F3-4391-985D-63A5A049A0FA}.Release|Mixed Platforms.Build.0 = Release-Stable|x86
{4785AB75-66F3-4391-985D-63A5A049A0FA}.Release|x64.ActiveCfg = Release-Stable|Any CPU
{4785AB75-66F3-4391-985D-63A5A049A0FA}.Release|x64.Build.0 = Release-Stable|Any CPU
{4785AB75-66F3-4391-985D-63A5A049A0FA}.Release|x86.ActiveCfg = Release-Stable|x86
{4785AB75-66F3-4391-985D-63A5A049A0FA}.Release|x86.Build.0 = Release-Stable|x86
{4785AB75-66F3-4391-985D-63A5A049A0FA}.Release-Nightly|Any CPU.ActiveCfg = Release-Nightly|Any CPU
{4785AB75-66F3-4391-985D-63A5A049A0FA}.Release-Nightly|Any CPU.Build.0 = Release-Nightly|Any CPU
{4785AB75-66F3-4391-985D-63A5A049A0FA}.Release-Nightly|Mixed Platforms.ActiveCfg = Release-Nightly|x86
@ -115,6 +135,14 @@ Global
{D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Debug|x64.Build.0 = Debug|Any CPU
{D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Debug|x86.ActiveCfg = Debug|x86
{D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Debug|x86.Build.0 = Debug|x86
{D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release|Any CPU.ActiveCfg = Release-Stable|Any CPU
{D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release|Any CPU.Build.0 = Release-Stable|Any CPU
{D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release|Mixed Platforms.ActiveCfg = Release-Stable|x86
{D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release|Mixed Platforms.Build.0 = Release-Stable|x86
{D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release|x64.ActiveCfg = Release-Stable|Any CPU
{D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release|x64.Build.0 = Release-Stable|Any CPU
{D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release|x86.ActiveCfg = Release-Stable|x86
{D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release|x86.Build.0 = Release-Stable|x86
{D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release-Nightly|Any CPU.ActiveCfg = Release-Nightly|Any CPU
{D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release-Nightly|Any CPU.Build.0 = Release-Nightly|Any CPU
{D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release-Nightly|Mixed Platforms.ActiveCfg = Release-Nightly|x86
@ -139,6 +167,14 @@ Global
{AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Debug|x64.Build.0 = Debug|Any CPU
{AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Debug|x86.ActiveCfg = Debug|x86
{AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Debug|x86.Build.0 = Debug|x86
{AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release|Any CPU.ActiveCfg = Release-Stable|Any CPU
{AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release|Any CPU.Build.0 = Release-Stable|Any CPU
{AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release|Mixed Platforms.ActiveCfg = Release-Stable|x86
{AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release|Mixed Platforms.Build.0 = Release-Stable|x86
{AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release|x64.ActiveCfg = Release-Stable|Any CPU
{AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release|x64.Build.0 = Release-Stable|Any CPU
{AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release|x86.ActiveCfg = Release-Stable|x86
{AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release|x86.Build.0 = Release-Stable|x86
{AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release-Nightly|Any CPU.ActiveCfg = Release-Nightly|Any CPU
{AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release-Nightly|Any CPU.Build.0 = Release-Nightly|Any CPU
{AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release-Nightly|Mixed Platforms.ActiveCfg = Release-Nightly|x86
@ -163,6 +199,14 @@ Global
{428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Debug|x64.Build.0 = Debug|Any CPU
{428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Debug|x86.ActiveCfg = Debug|x86
{428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Debug|x86.Build.0 = Debug|x86
{428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release|Any CPU.ActiveCfg = Release-Stable|Any CPU
{428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release|Any CPU.Build.0 = Release-Stable|Any CPU
{428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release|Mixed Platforms.ActiveCfg = Release-Stable|x86
{428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release|Mixed Platforms.Build.0 = Release-Stable|x86
{428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release|x64.ActiveCfg = Release-Stable|Any CPU
{428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release|x64.Build.0 = Release-Stable|Any CPU
{428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release|x86.ActiveCfg = Release-Stable|x86
{428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release|x86.Build.0 = Release-Stable|x86
{428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release-Nightly|Any CPU.ActiveCfg = Release-Nightly|Any CPU
{428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release-Nightly|Mixed Platforms.ActiveCfg = Release-Nightly|x86
{428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release-Nightly|Mixed Platforms.Build.0 = Release-Nightly|x86
@ -183,6 +227,14 @@ Global
{E46C85BD-A99C-484E-BCCE-0F1831C5925E}.Debug|x64.ActiveCfg = Release-Stable|Any CPU
{E46C85BD-A99C-484E-BCCE-0F1831C5925E}.Debug|x86.ActiveCfg = Debug|x86
{E46C85BD-A99C-484E-BCCE-0F1831C5925E}.Debug|x86.Build.0 = Debug|x86
{E46C85BD-A99C-484E-BCCE-0F1831C5925E}.Release|Any CPU.ActiveCfg = Release-Nightly|Any CPU
{E46C85BD-A99C-484E-BCCE-0F1831C5925E}.Release|Any CPU.Build.0 = Release-Nightly|Any CPU
{E46C85BD-A99C-484E-BCCE-0F1831C5925E}.Release|Mixed Platforms.ActiveCfg = Release-Stable|x86
{E46C85BD-A99C-484E-BCCE-0F1831C5925E}.Release|Mixed Platforms.Build.0 = Release-Stable|x86
{E46C85BD-A99C-484E-BCCE-0F1831C5925E}.Release|x64.ActiveCfg = Release-Nightly|Any CPU
{E46C85BD-A99C-484E-BCCE-0F1831C5925E}.Release|x64.Build.0 = Release-Nightly|Any CPU
{E46C85BD-A99C-484E-BCCE-0F1831C5925E}.Release|x86.ActiveCfg = Release-Stable|x86
{E46C85BD-A99C-484E-BCCE-0F1831C5925E}.Release|x86.Build.0 = Release-Stable|x86
{E46C85BD-A99C-484E-BCCE-0F1831C5925E}.Release-Nightly|Any CPU.ActiveCfg = Release-Nightly|Any CPU
{E46C85BD-A99C-484E-BCCE-0F1831C5925E}.Release-Nightly|Mixed Platforms.ActiveCfg = Release-Stable|Any CPU
{E46C85BD-A99C-484E-BCCE-0F1831C5925E}.Release-Nightly|x64.ActiveCfg = Release-Stable|Any CPU
@ -201,6 +253,14 @@ Global
{C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Debug|x64.Build.0 = Debug|Any CPU
{C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Debug|x86.ActiveCfg = Debug|x86
{C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Debug|x86.Build.0 = Debug|x86
{C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release|Any CPU.ActiveCfg = Release-Stable|Any CPU
{C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release|Any CPU.Build.0 = Release-Stable|Any CPU
{C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release|Mixed Platforms.ActiveCfg = Release-Stable|x86
{C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release|Mixed Platforms.Build.0 = Release-Stable|x86
{C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release|x64.ActiveCfg = Release-Stable|Any CPU
{C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release|x64.Build.0 = Release-Stable|Any CPU
{C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release|x86.ActiveCfg = Release-Stable|x86
{C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release|x86.Build.0 = Release-Stable|x86
{C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release-Nightly|Any CPU.ActiveCfg = Release-Nightly|Any CPU
{C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release-Nightly|Any CPU.Build.0 = Release-Nightly|Any CPU
{C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release-Nightly|Mixed Platforms.ActiveCfg = Release-Nightly|x86
@ -225,6 +285,14 @@ Global
{1479DE87-ACB5-4046-81C8-A0BA5041227D}.Debug|x64.Build.0 = Debug|Any CPU
{1479DE87-ACB5-4046-81C8-A0BA5041227D}.Debug|x86.ActiveCfg = Debug|x86
{1479DE87-ACB5-4046-81C8-A0BA5041227D}.Debug|x86.Build.0 = Debug|x86
{1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release|Any CPU.ActiveCfg = Release-Stable|Any CPU
{1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release|Any CPU.Build.0 = Release-Stable|Any CPU
{1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release|Mixed Platforms.ActiveCfg = Release-Stable|x86
{1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release|Mixed Platforms.Build.0 = Release-Stable|x86
{1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release|x64.ActiveCfg = Release-Stable|Any CPU
{1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release|x64.Build.0 = Release-Stable|Any CPU
{1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release|x86.ActiveCfg = Release-Stable|x86
{1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release|x86.Build.0 = Release-Stable|x86
{1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release-Nightly|Any CPU.ActiveCfg = Release-Nightly|Any CPU
{1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release-Nightly|Mixed Platforms.ActiveCfg = Release-Nightly|x86
{1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release-Nightly|Mixed Platforms.Build.0 = Release-Nightly|x86
@ -247,6 +315,14 @@ Global
{B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Debug|x64.Build.0 = Debug|Any CPU
{B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Debug|x86.ActiveCfg = Debug|x86
{B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Debug|x86.Build.0 = Debug|x86
{B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Release|Any CPU.ActiveCfg = Release-Stable|Any CPU
{B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Release|Any CPU.Build.0 = Release-Stable|Any CPU
{B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Release|Mixed Platforms.ActiveCfg = Release-Stable|x86
{B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Release|Mixed Platforms.Build.0 = Release-Stable|x86
{B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Release|x64.ActiveCfg = Release-Stable|Any CPU
{B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Release|x64.Build.0 = Release-Stable|Any CPU
{B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Release|x86.ActiveCfg = Release-Stable|x86
{B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Release|x86.Build.0 = Release-Stable|x86
{B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Release-Nightly|Any CPU.ActiveCfg = Release-Nightly|Any CPU
{B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Release-Nightly|Mixed Platforms.ActiveCfg = Release-Nightly|x86
{B8C2A759-8663-4F6F-9BA4-19595F5E12C1}.Release-Nightly|Mixed Platforms.Build.0 = Release-Nightly|x86

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -7,6 +7,8 @@ using System.IO;
using System.Text;
using System.Threading.Tasks;
using SharedLibrary.Objects;
namespace StatsPlugin
{
public class CViewStats : Command
@ -74,7 +76,7 @@ namespace StatsPlugin
await E.Origin.Tell("^5--Top Players--");
foreach (KeyValuePair<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)
continue;
await E.Origin.Tell(String.Format("^3{0}^7 - ^5{1} ^7KDR | ^5{2} ^7SKILL", P.Name, pStat.Value.KDR, pStat.Value.Skill));
@ -132,8 +134,8 @@ namespace StatsPlugin
return;
}
E.Owner.Manager.GetClientDatabase().PruneAdmins(inactiveDays);
await E.Origin.Tell("Pruned inactive privileged users");
var inactiveAdmins = await E.Owner.Manager.GetDatabase().PruneInactivePrivilegedClients(inactiveDays);
await E.Origin.Tell($"Pruned inactive {inactiveAdmins.Count} privileged users");
}
}
@ -289,7 +291,7 @@ namespace StatsPlugin
if (E.Type == Event.GType.Connect)
{
ResetCounters(E.Origin.ClientID, S.GetPort());
ResetCounters(E.Origin.ClientNumber, S.GetPort());
var config = new ConfigurationManager(E.Owner);
@ -300,8 +302,8 @@ namespace StatsPlugin
//todo: move this out of here!!
if (checkForTrusted.TotalPlayTime >= 4320 && E.Origin.Level < Player.Permission.Trusted && E.Origin.Level != Player.Permission.Flagged)
{
E.Origin.SetLevel(Player.Permission.Trusted);
E.Owner.Manager.GetClientDatabase().UpdatePlayer(E.Origin);
E.Origin.Level = Player.Permission.Trusted;
await E.Owner.Manager.GetDatabase().UpdateClient(E.Origin);
await E.Origin.Tell("Congratulations, you are now a ^5trusted ^7player! Type ^5!help ^7to view new commands.");
await E.Origin.Tell("You earned this by playing for ^53 ^7full days!");
}
@ -316,10 +318,10 @@ namespace StatsPlugin
continue;
CalculateAndSaveSkill(P, statLists.Find(x => x.Port == S.GetPort()));
ResetCounters(P.ClientID, S.GetPort());
ResetCounters(P.ClientNumber, S.GetPort());
E.Owner.Logger.WriteInfo($"Updated skill for {P}");
//E.Owner.Log.Write(String.Format("\r\nJoin: {0}\r\nInactive Minutes: {1}\r\nnewPlayTime: {2}\r\nnewSPM: {3}\r\nkdrWeight: {4}\r\nMultiplier: {5}\r\nscoreWeight: {6}\r\nnewSkillFactor: {7}\r\nprojectedNewSkill: {8}\r\nKills: {9}\r\nDeaths: {10}", connectionTime[P.clientID].ToShortTimeString(), inactiveMinutes[P.clientID], newPlayTime, newSPM, kdrWeight, Multiplier, scoreWeight, newSkillFactor, disconnectStats.Skill, disconnectStats.Kills, disconnectStats.Deaths));
//E.Owner.Log.Write(String.Format("\r\nJoin: {0}\r\nInactive Minutes: {1}\r\nnewPlayTime: {2}\r\nnewSPM: {3}\r\nkdrWeight: {4}\r\nMultiplier: {5}\r\nscoreWeight: {6}\r\nnewSkillFactor: {7}\r\nprojectedNewSkill: {8}\r\nKills: {9}\r\nDeaths: {10}", connectionTime[P.ClientNumber].ToShortTimeString(), inactiveMinutes[P.ClientNumber], newPlayTime, newSPM, kdrWeight, Multiplier, scoreWeight, newSkillFactor, disconnectStats.Skill, disconnectStats.Kills, disconnectStats.Deaths));
}
}
@ -332,7 +334,7 @@ namespace StatsPlugin
if (E.Type == Event.GType.Disconnect)
{
CalculateAndSaveSkill(E.Origin, statLists.Find(x => x.Port == S.GetPort()));
ResetCounters(E.Origin.ClientID, S.GetPort());
ResetCounters(E.Origin.ClientNumber, S.GetPort());
E.Owner.Logger.WriteInfo($"Updated skill for disconnecting client {E.Origin}");
}
@ -345,7 +347,7 @@ namespace StatsPlugin
if (killInfo.Length >= 9 && killInfo[0].Contains("ScriptKill"))
{
var killEvent = new KillInfo(E.Origin.DatabaseID, E.Target.DatabaseID, S.CurrentMap.Name, killInfo[7], killInfo[8], killInfo[5], killInfo[6], killInfo[3], killInfo[4])
var killEvent = new KillInfo(E.Origin.ClientNumber, E.Target.ClientNumber, S.CurrentMap.Name, killInfo[7], killInfo[8], killInfo[5], killInfo[6], killInfo[3], killInfo[4])
{
KillerPlayer = E.Origin.Name,
VictimPlayer = E.Target.Name,
@ -366,11 +368,11 @@ namespace StatsPlugin
if (killerStats == null)
killerStats = new PlayerStats(0, 0, 0, 0, 0, 0);
curServer.lastKill[E.Origin.ClientID] = DateTime.Now;
curServer.Kills[E.Origin.ClientID]++;
curServer.lastKill[E.Origin.ClientNumber] = DateTime.Now;
curServer.Kills[E.Origin.ClientNumber]++;
if ((DateTime.Now - curServer.lastKill[E.Origin.ClientID]).TotalSeconds > 120)
curServer.inactiveMinutes[E.Origin.ClientID] += 2;
if ((DateTime.Now - curServer.lastKill[E.Origin.ClientNumber]).TotalSeconds > 120)
curServer.inactiveMinutes[E.Origin.ClientNumber] += 2;
killerStats.Kills++;
@ -378,10 +380,10 @@ namespace StatsPlugin
curServer.playerStats.UpdateStats(Killer, killerStats);
curServer.killStreaks[Killer.ClientID] += 1;
curServer.deathStreaks[Killer.ClientID] = 0;
curServer.killStreaks[Killer.ClientNumber] += 1;
curServer.deathStreaks[Killer.ClientNumber] = 0;
await Killer.Tell(MessageOnStreak(curServer.killStreaks[Killer.ClientID], curServer.deathStreaks[Killer.ClientID]));
await Killer.Tell(MessageOnStreak(curServer.killStreaks[Killer.ClientNumber], curServer.deathStreaks[Killer.ClientNumber]));
}
if (E.Type == Event.GType.Death)
@ -401,15 +403,15 @@ namespace StatsPlugin
curServer.playerStats.UpdateStats(Victim, victimStats);
curServer.deathStreaks[Victim.ClientID] += 1;
curServer.killStreaks[Victim.ClientID] = 0;
curServer.deathStreaks[Victim.ClientNumber] += 1;
curServer.killStreaks[Victim.ClientNumber] = 0;
await Victim.Tell(MessageOnStreak(curServer.killStreaks[Victim.ClientID], curServer.deathStreaks[Victim.ClientID]));
await Victim.Tell(MessageOnStreak(curServer.killStreaks[Victim.ClientNumber], curServer.deathStreaks[Victim.ClientNumber]));
}
if (E.Type == Event.GType.Say)
{
ChatDB.AddChatHistory(E.Origin.DatabaseID, E.Owner.GetPort(), E.Data);
ChatDB.AddChatHistory(E.Origin.ClientNumber, E.Owner.GetPort(), E.Data);
}
}
@ -444,19 +446,19 @@ namespace StatsPlugin
PlayerStats DisconnectingPlayerStats = curServer.playerStats.GetStats(P);
if (DisconnectingPlayerStats == null || curServer.Kills[P.ClientID] == 0)
if (DisconnectingPlayerStats == null || curServer.Kills[P.ClientNumber] == 0)
return;
else if (curServer.lastKill[P.ClientID] > curServer.connectionTime[P.ClientID])
curServer.inactiveMinutes[P.ClientID] += (int)(DateTime.Now - curServer.lastKill[P.ClientID]).TotalMinutes;
else if (curServer.lastKill[P.ClientNumber] > curServer.connectionTime[P.ClientNumber])
curServer.inactiveMinutes[P.ClientNumber] += (int)(DateTime.Now - curServer.lastKill[P.ClientNumber]).TotalMinutes;
int newPlayTime = (int)(DateTime.Now - curServer.connectionTime[P.ClientID]).TotalMinutes - curServer.inactiveMinutes[P.ClientID];
int newPlayTime = (int)(DateTime.Now - curServer.connectionTime[P.ClientNumber]).TotalMinutes - curServer.inactiveMinutes[P.ClientNumber];
if (newPlayTime < 2)
return;
// calculate the players Score Per Minute for the current session
double SessionSPM = curServer.Kills[P.ClientID] * 100 / Math.Max(1, newPlayTime);
double SessionSPM = curServer.Kills[P.ClientNumber] * 100 / Math.Max(1, newPlayTime);
// calculate how much the KDR should way
// 1.637 is a Eddie-Generated number that weights the KDR nicely
double KDRWeight = Math.Round(Math.Pow(DisconnectingPlayerStats.KDR, 1.637 / Math.E), 3);
@ -520,7 +522,7 @@ namespace StatsPlugin
}
}
public class StatsDB : Database
public class StatsDB : _Database
{
public StatsDB(String FN, SharedLibrary.Interfaces.ILogger logger) : base(FN, logger) { }
@ -624,7 +626,7 @@ namespace StatsPlugin
{
Dictionary<String, object> newPlayer = new Dictionary<String, object>
{
{ "npID", P.NetworkID },
{ "npID", P.NetworkId },
{ "KILLS", 0 },
{ "DEATHS", 0 },
{ "KDR", 0.0 },
@ -637,7 +639,7 @@ namespace StatsPlugin
public PlayerStats GetStats(Player P)
{
DataTable Result = GetDataTable("STATS", new KeyValuePair<string, object>("npID", P.NetworkID));
DataTable Result = GetDataTable("STATS", new KeyValuePair<string, object>("npID", P.NetworkId));
if (Result != null && Result.Rows.Count > 0)
{
@ -682,7 +684,7 @@ namespace StatsPlugin
{ "SPM", Math.Round(S.scorePerMinute, 2) },
{ "PLAYTIME", S.TotalPlayTime }
};
Update("STATS", updatedPlayer, new KeyValuePair<string, object>("npID", P.NetworkID));
Update("STATS", updatedPlayer, new KeyValuePair<string, object>("npID", P.NetworkId));
}
public List<KeyValuePair<String, PlayerStats>> GetTopStats()

View File

@ -4,9 +4,11 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SharedLibrary;
using SharedLibrary.Interfaces;
using SharedLibrary.Helpers;
using SharedLibrary.Objects;
namespace IW4MAdmin.Plugins
{
@ -63,17 +65,20 @@ namespace IW4MAdmin.Plugins
{
var rand = new Random();
int index = rand.Next(0, 17);
var p = new Player($"?!'\"\"'<>Test_{index}", $"_test{index}", index, (int)Player.Permission.User)
var p = new Player()
{
Ping = 1
Name = $"Test{index}",
NetworkId = $"_test{index}",
ClientNumber = index,
Level = Player.Permission.User,
Ping = 1,
IPAddress = "127.0.0.1"
};
p.SetIP("127.0.0.1");
if (S.Players.ElementAt(index) != null)
await S.RemovePlayer(index);
await S.AddPlayer(p);
/*
Interval = DateTime.Now;
if (S.ClientNum > 0)
@ -83,7 +88,7 @@ namespace IW4MAdmin.Plugins
var victimPlayer = S.Players.Where(pl => pl != null).ToList()[rand.Next(0, S.ClientNum - 1)];
var attackerPlayer = S.Players.Where(pl => pl != null).ToList()[rand.Next(0, S.ClientNum - 1)];
await S.ExecuteEvent(new Event(Event.GType.Say, $"test_{attackerPlayer.ClientID}", victimPlayer, attackerPlayer, S));
await S.ExecuteEvent(new Event(Event.GType.Say, $"test_{attackerPlayer.ClientNumber}", victimPlayer, attackerPlayer, S));
string[] eventLine = null;
@ -99,8 +104,8 @@ namespace IW4MAdmin.Plugins
eventLine = new string[]
{
"ScriptKill",
attackerPlayer.NetworkID,
victimPlayer.NetworkID,
attackerPlayer.NetworkId,
victimPlayer.NetworkId,
new Vector3(rand.Next(minimapInfo.MaxRight, minimapInfo.MaxLeft), rand.Next(minimapInfo.MaxBottom, minimapInfo.MaxTop), rand.Next(0, 100)).ToString(),
new Vector3(rand.Next(minimapInfo.MaxRight, minimapInfo.MaxLeft), rand.Next(minimapInfo.MaxBottom, minimapInfo.MaxTop), rand.Next(0, 100)).ToString(),
rand.Next(50, 105).ToString(),
@ -115,12 +120,12 @@ namespace IW4MAdmin.Plugins
eventLine = new string[]
{
"K",
victimPlayer.NetworkID,
victimPlayer.ClientID.ToString(),
victimPlayer.NetworkId,
victimPlayer.ClientNumber.ToString(),
rand.Next(0, 1) == 0 ? "allies" : "axis",
victimPlayer.Name,
attackerPlayer.NetworkID,
attackerPlayer.ClientID.ToString(),
attackerPlayer.NetworkId,
attackerPlayer.ClientNumber.ToString(),
rand.Next(0, 1) == 0 ? "allies" : "axis",
attackerPlayer.Name.ToString(),
((StatsPlugin.IW4Info.WeaponName)rand.Next(0, Enum.GetValues(typeof(StatsPlugin.IW4Info.WeaponName)).Length - 1)).ToString(), // Weapon
@ -133,7 +138,7 @@ namespace IW4MAdmin.Plugins
var _event = Event.ParseEventString(eventLine, S);
await S.ExecuteEvent(_event);
}
}
}*/
}
}

View File

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

View File

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

View File

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

View File

@ -2,9 +2,12 @@
using System.Collections.Generic;
using System.Text;
using System.Linq;
using System.Threading.Tasks;
using SharedLibrary.Network;
using SharedLibrary.Helpers;
using System.Threading.Tasks;
using SharedLibrary.Objects;
namespace SharedLibrary.Commands
{
@ -28,11 +31,11 @@ namespace SharedLibrary.Commands
public override async Task ExecuteAsync(Event E)
{
if (E.Owner.Manager.GetClientDatabase().GetOwner() == null)
if ((await (E.Owner.Manager.GetClientService() as Services.ClientService).GetOwners()).Count == 0)
{
E.Origin.SetLevel(Player.Permission.Owner);
E.Origin.Level = Player.Permission.Owner;
await E.Origin.Tell("Congratulations, you have claimed ownership of this server!");
E.Owner.Manager.GetClientDatabase().UpdatePlayer(E.Origin);
await E.Owner.Manager.GetClientService().Update(E.Origin);
}
else
await E.Origin.Tell("This server already has an owner!");
@ -59,11 +62,10 @@ namespace SharedLibrary.Commands
public override async Task ExecuteAsync(Event E)
{
E.Target.lastOffense = E.Data.RemoveWords(1);
if (E.Origin.Level <= E.Target.Level)
await E.Origin.Tell($"You do not have the required privileges to warn {E.Target.Name}");
else
await E.Target.Warn(E.Target.lastOffense, E.Origin);
await E.Target.Warn(E.Data.RemoveWords(1), E.Origin);
}
}
@ -82,7 +84,6 @@ namespace SharedLibrary.Commands
public override async Task ExecuteAsync(Event E)
{
E.Target.lastOffense = String.Empty;
E.Target.Warnings = 0;
String Message = String.Format("All warning cleared for {0}", E.Target.Name);
await E.Owner.Broadcast(Message);
@ -109,11 +110,10 @@ namespace SharedLibrary.Commands
public override async Task ExecuteAsync(Event E)
{
E.Target.lastOffense = E.Data.RemoveWords(1);
if (E.Origin.Level > E.Target.Level)
{
await E.Owner.ExecuteEvent(new Event(Event.GType.Kick, E.Data, E.Origin, E.Target, E.Owner));
await E.Target.Kick(E.Target.lastOffense, E.Origin);
await E.Target.Kick(E.Data.RemoveWords(1), E.Origin);
await E.Origin.Tell($"^5{E.Target} ^7has been kicked");
}
else
@ -165,8 +165,7 @@ namespace SharedLibrary.Commands
public override async Task ExecuteAsync(Event E)
{
E.Target.lastOffense = Utilities.RemoveWords(E.Data, 1);
String Message = E.Target.lastOffense;
String Message = Utilities.RemoveWords(E.Data, 1);
var length = Message.ParseTimespan();
if (length.TotalHours != 1)
@ -202,17 +201,9 @@ namespace SharedLibrary.Commands
public override async Task ExecuteAsync(Event E)
{
E.Target.lastOffense = Utilities.RemoveWords(E.Data, 1);
E.Target.lastEvent = E; // needs to be fixed
String Message;
if (E.Owner.Website == null)
Message = "^1Player Banned: ^5" + E.Target.lastOffense;
else
Message = "^1Player Banned: ^5" + E.Target.lastOffense;
if (E.Origin.Level > E.Target.Level)
{
await E.Owner.ExecuteEvent(new Event(Event.GType.Ban, E.Data, E.Origin, E.Target, E.Owner));
await E.Target.Ban(Message, E.Origin);
await E.Target.Ban(E.Data, E.Origin);
await E.Origin.Tell($"^5{E.Target} ^7has been permanently banned");
}
else
@ -248,7 +239,7 @@ namespace SharedLibrary.Commands
public override async Task ExecuteAsync(Event E)
{
String You = String.Format("{0} [^3#{1}^7] {2} [^3@{3}^7] [{4}^7] IP: {5}", E.Origin.Name, E.Origin.ClientID, E.Origin.NetworkID, E.Origin.DatabaseID, Utilities.ConvertLevelToColor(E.Origin.Level), E.Origin.IP);
String You = String.Format("{0} [^3#{1}^7] {2} [^3@{3}^7] [{4}^7] IP: {5}", E.Origin.Name, E.Origin.ClientNumber, E.Origin.NetworkId, E.Origin.ClientNumber, Utilities.ConvertLevelToColor(E.Origin.Level), E.Origin.IPAddress);
await E.Origin.Tell(You);
}
}
@ -271,9 +262,9 @@ namespace SharedLibrary.Commands
continue;
if (P.Masked)
playerList.AppendFormat("[^3{0}^7]{3}[^3{1}^7] {2}", Utilities.ConvertLevelToColor(Player.Permission.User), P.ClientID, P.Name, Utilities.GetSpaces(Player.Permission.SeniorAdmin.ToString().Length - Player.Permission.User.ToString().Length));
playerList.AppendFormat("[^3{0}^7]{3}[^3{1}^7] {2}", Utilities.ConvertLevelToColor(Player.Permission.User), P.ClientNumber, P.Name, Utilities.GetSpaces(Player.Permission.SeniorAdmin.ToString().Length - Player.Permission.User.ToString().Length));
else
playerList.AppendFormat("[^3{0}^7]{3}[^3{1}^7] {2}", Utilities.ConvertLevelToColor(P.Level), P.ClientID, P.Name, Utilities.GetSpaces(Player.Permission.SeniorAdmin.ToString().Length - P.Level.ToString().Length));
playerList.AppendFormat("[^3{0}^7]{3}[^3{1}^7] {2}", Utilities.ConvertLevelToColor(P.Level), P.ClientNumber, P.Name, Utilities.GetSpaces(Player.Permission.SeniorAdmin.ToString().Length - P.Level.ToString().Length));
if (count == 2 || E.Owner.GetPlayersAsList().Count == 1)
{
@ -424,16 +415,16 @@ namespace SharedLibrary.Commands
if (newPerm > Player.Permission.Banned)
{
var ActiveClient = E.Owner.Manager.GetActiveClients().FirstOrDefault(p => p.NetworkID == E.Target.NetworkID);
ActiveClient?.SetLevel(newPerm);
var ActiveClient = E.Owner.Manager.GetActiveClients().FirstOrDefault(p => p.NetworkId == E.Target.NetworkId);
ActiveClient.Level = newPerm;
if (ActiveClient != null)
await ActiveClient.Tell("Congratulations! You have been promoted to ^3" + newPerm);
await E.Origin.Tell($"{E.Target.Name} was successfully promoted!");
E.Target.SetLevel(newPerm);
E.Owner.Manager.GetClientDatabase().UpdatePlayer(E.Target);
E.Target.Level = newPerm;
await E.Owner.Manager.GetClientService().Update(E.Target);
}
else
@ -536,9 +527,9 @@ namespace SharedLibrary.Commands
public override async Task ExecuteAsync(Event E)
{
var db_players = E.Owner.Manager.GetClientDatabase().FindPlayers(E.Data.Trim());
var db_players = await E.Owner.Manager.GetClientService().Find(c => c.Name.Contains(E.Data));
if (db_players == null)
if (db_players.Count == 0)
{
await E.Origin.Tell("No players found");
return;
@ -546,7 +537,7 @@ namespace SharedLibrary.Commands
foreach (Player P in db_players)
{
String mesg = String.Format("[^3{0}^7] [^3@{1}^7] - [{2}^7] - {3} | last seen {4}", P.Name, P.DatabaseID, Utilities.ConvertLevelToColor(P.Level), P.IP, P.GetLastConnection());
String mesg = String.Format("[^3{0}^7] [^3@{1}^7] - [{2}^7] - {3} | last seen {4}", P.Name, P.ClientNumber, Utilities.ConvertLevelToColor(P.Level), P.IPAddress, P.GetLastConnection());
await E.Origin.Tell(mesg);
}
}
@ -575,36 +566,17 @@ namespace SharedLibrary.Commands
return;
}
var db_aliases = E.Owner.Manager.GetAliasesDatabase().FindPlayerAliases(E.Data);
var db_aliases = await E.Owner.Manager.GetAliasService().Find(a => a.Name.Contains(E.Data));
if (db_aliases == null || db_aliases.Count() == 0)
if (db_aliases.Count == 0)
{
await E.Origin.Tell("No players found");
return;
}
foreach (Aliases P in db_aliases)
foreach (var P in db_aliases)
{
if (P == null)
continue;
String lookingFor = null;
foreach (String S in P.Names)
{
if (S.ToLower().Contains(E.Data.ToLower()))
lookingFor = S;
}
lookingFor = lookingFor ?? P.Names.First();
Player Current = E.Owner.Manager.GetClientDatabase().GetPlayer(P.Number);
if (Current != null && Current.Name != lookingFor)
{
String mesg = String.Format("^1{0} ^7now goes by ^5{1}^7 [^3{2}^7]", lookingFor, Current.Name, Current.DatabaseID);
await E.Origin.Tell(mesg);
}
await E.Origin.Tell($"^4{P.Name} ^7now goes by ^5{P.Link.Children.OrderByDescending(a => a.DateAdded).First().Name}");
}
}
}
@ -707,21 +679,33 @@ namespace SharedLibrary.Commands
if (E.Target.Level == Player.Permission.Flagged)
{
E.Target.SetLevel(Player.Permission.User);
E.Owner.Manager.GetClientPenalties().RemovePenalty(new Penalty(Penalty.Type.Flag, "", E.Target.NetworkID, "", DateTime.Now, "", DateTime.Now));
E.Target.Level = Player.Permission.User;
//E.Owner.Manager.GetClientPenalties().RemovePenalty(new Penalty(Penalty.PenaltyType.Flag, "", E.Target.NetworkId, "", DateTime.Now, "", DateTime.Now));
await E.Origin.Tell("You have ^5unflagged ^7" + E.Target.Name);
}
else
{
E.Data = Utilities.RemoveWords(E.Data, 1);
E.Target.SetLevel(Player.Permission.Flagged);
E.Owner.Manager.GetClientPenalties().AddPenalty(new Penalty(Penalty.Type.Flag, E.Data, E.Target.NetworkID, E.Origin.NetworkID, DateTime.Now, E.Target.IP, DateTime.Now));
E.Target.Level = Player.Permission.Flagged;
Penalty newPenalty = new Penalty()
{
Type = Penalty.PenaltyType.Flag,
Expires = DateTime.UtcNow,
Offender = E.Target,
Offense = E.Data,
Punisher = E.Origin,
Active = true,
When = DateTime.UtcNow
};
await E.Owner.Manager.GetPenaltyService().Create(newPenalty);
await E.Owner.ExecuteEvent(new Event(Event.GType.Flag, E.Data, E.Origin, E.Target, E.Owner));
await E.Origin.Tell("You have ^5flagged ^7" + E.Target.Name);
}
E.Owner.Manager.GetClientDatabase().UpdatePlayer(E.Target);
await E.Owner.Manager.GetClientService().Update(E.Target);
}
}
@ -745,7 +729,7 @@ namespace SharedLibrary.Commands
public override async Task ExecuteAsync(Event E)
{
if (E.Owner.Reports.Find(x => (x.Origin == E.Origin && x.Target.NetworkID == E.Target.NetworkID)) != null)
if (E.Owner.Reports.Find(x => (x.Origin == E.Origin && x.Target.NetworkId == E.Target.NetworkId)) != null)
{
await E.Origin.Tell("You have already reported this player");
return;
@ -824,7 +808,7 @@ namespace SharedLibrary.Commands
await E.Origin.Tell("You are now masked");
}
E.Owner.Manager.GetClientDatabase().UpdatePlayer(E.Origin);
await E.Owner.Manager.GetClientService().Update(E.Origin);
}
}
@ -843,18 +827,17 @@ namespace SharedLibrary.Commands
public override async Task ExecuteAsync(Event E)
{
var B = E.Owner.Manager.GetClientPenalties().FindPenalties(E.Target);
var BannedPenalty = B.Find(b => b.BType > Penalty.Type.Kick && b.Expires > DateTime.Now);
var B = await E.Owner.Manager.GetPenaltyService().GetClientPenaltiesAsync(E.Target.ClientId);
if (BannedPenalty == null)
var penalty = B.FirstOrDefault(b => b.Type > Penalty.PenaltyType.Kick && b.Expires > DateTime.UtcNow);
if (penalty == null)
{
await E.Origin.Tell("No active ban was found for that player");
return;
}
Player Banner = E.Owner.Manager.GetClientDatabase().GetPlayer(BannedPenalty.PenaltyOriginID, -1);
await E.Origin.Tell(String.Format("^1{0} ^7was banned by ^5{1} ^7for: {2} {3}", E.Target.Name, Banner?.Name ?? "IW4MAdmin", BannedPenalty.Reason, BannedPenalty.BType == Penalty.Type.TempBan ? $"({(BannedPenalty.Expires - DateTime.Now).TimeSpanText()} remaining)" : ""));
await E.Origin.Tell(String.Format("^1{0} ^7was banned by ^5{1} ^7for: {2} {3}", E.Target.Name, penalty.Punisher.Name, penalty.Offense, penalty.Type == Penalty.PenaltyType.TempBan ? $"({(penalty.Expires - DateTime.Now).TimeSpanText()} remaining)" : ""));
}
}
@ -873,37 +856,19 @@ namespace SharedLibrary.Commands
public override async Task ExecuteAsync(Event E)
{
E.Target.Alias = E.Owner.Manager.GetAliasesDatabase().GetPlayerAliases(E.Target.DatabaseID);
if (E.Target.Alias == null)
{
await E.Target.Tell("Could not find alias info for that player");
return;
}
await E.Target.Tell("[^3" + E.Target.Name + "^7]");
StringBuilder message = new StringBuilder();
var names = new List<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: ");
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()));
message.Append(String.Join(" | ", names));
await E.Origin.Tell(message.ToString());
message.Clear();
message.Append("IPs: ");
message.Append(String.Join(" | ", ips.Distinct()));
message.Append(String.Join(" | ", IPs));
await E.Origin.Tell(message.ToString());
}
}
@ -955,7 +920,7 @@ namespace SharedLibrary.Commands
public override async Task ExecuteAsync(Event E)
{
await E.Origin.Tell($"Your external IP is ^5{E.Origin.IP}");
await E.Origin.Tell($"Your external IP is ^5{E.Origin.IPAddress}");
}
}
}

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

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 SharedLibrary.Objects;
using SharedLibrary.Database.Models;
using SharedLibrary.Services;
namespace SharedLibrary.Interfaces
{
@ -10,13 +13,10 @@ namespace SharedLibrary.Interfaces
ILogger GetLogger();
IList<Server> GetServers();
IList<Command> GetCommands();
IPenaltyList GetClientPenalties();
ClientsDB GetClientDatabase();
AliasesDB GetAliasesDatabase();
IList<Helpers.MessageToken> GetMessageTokens();
IList<Player> GetActiveClients();
IList<Player> GetAliasClients(Player player);
IList<Aliases> GetAliases(Player player);
IList<Player> GetPrivilegedClients();
ClientService GetClientService();
AliasService GetAliasService();
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.Net.Sockets;
using SharedLibrary.Objects;
namespace SharedLibrary.Network
{
public static class RCON

View File

@ -9,6 +9,7 @@ using SharedLibrary.Network;
using SharedLibrary.Commands;
using System.Threading.Tasks;
using SharedLibrary.Helpers;
using SharedLibrary.Objects;
namespace SharedLibrary
{
@ -106,13 +107,6 @@ namespace SharedLibrary
return Players.Where(p => p != null && p.Name.ToLower().Contains(pName.ToLower())).ToList();
}
/// <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>
/// Process requested command correlating to an event
/// </summary>
@ -126,16 +120,6 @@ namespace SharedLibrary
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>
/// Process any server event
/// </summary>
@ -170,14 +154,10 @@ namespace SharedLibrary
/// <param name="Target">Player to send message to</param>
public async Task Tell(String Message, Player Target)
{
#if DEBUG
//if (!Target.lastEvent.Remote)
// return;
#endif
string tellCommand = (GameName == Game.IW4) ? "tellraw" : "tell";
if (Target.ClientID > -1 && Message.Length > 0 && Target.Level != Player.Permission.Console && !Target.lastEvent.Remote)
await this.ExecuteCommandAsync($"{tellCommand} {Target.ClientID} {Message}^7");
if (Target.ClientNumber > -1 && Message.Length > 0 && Target.Level != Player.Permission.Console)
await this.ExecuteCommandAsync($"{tellCommand} {Target.ClientNumber} {Message}^7");
if (Target.Level == Player.Permission.Console)
{
@ -185,9 +165,13 @@ namespace SharedLibrary
Console.WriteLine(Utilities.StripColors(Message));
Console.ForegroundColor = ConsoleColor.Gray;
}
if (Target.lastEvent.Remote)
commandResult.Enqueue(Utilities.StripColors(Message));
if (commandResult.Count > 15)
commandResult.RemoveAt(0);
commandResult.Add(new CommandResult()
{
Message = Utilities.StripColors(Message),
Clientd = Target.ClientId
});
}
/// <summary>
@ -353,14 +337,14 @@ namespace SharedLibrary
return $"{IP}_{Port}";
}
protected async Task<bool> ScriptLoaded()
protected async Task<bool> ScriptLoaded()
{
try
{
return (await this.GetDvarAsync<string>("sv_customcallbacks")).Value == "1";
}
catch(Exceptions.DvarException)
catch (Exceptions.DvarException)
{
return false;
}
@ -408,6 +392,6 @@ namespace SharedLibrary
protected DateTime LastPoll;
//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>
</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.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">
<HintPath>..\packages\Newtonsoft.Json.10.0.2\lib\net45\Newtonsoft.Json.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.ComponentModel.DataAnnotations" />
<Reference Include="System.Core" />
<Reference Include="System.Data.SQLite, Version=1.0.105.1, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=MSIL">
<HintPath>..\packages\System.Data.SQLite.Core.1.0.105.1\lib\net45\System.Data.SQLite.dll</HintPath>
<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.Web" />
@ -83,6 +94,14 @@
<Reference Include="System.Xml" />
</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="Commands\NativeCommands.cs" />
<Compile Include="Exceptions\CommandException.cs" />
@ -90,29 +109,34 @@
<Compile Include="Exceptions\NetworkException.cs" />
<Compile Include="Exceptions\SerializationException.cs" />
<Compile Include="Exceptions\ServerException.cs" />
<Compile Include="Helpers\CommandResult.cs" />
<Compile Include="Helpers\ConfigurationManager.cs" />
<Compile Include="Helpers\ParseEnum.cs" />
<Compile Include="Helpers\Vector3.cs" />
<Compile Include="Interfaces\IEntityService.cs" />
<Compile Include="Interfaces\ILogger.cs" />
<Compile Include="Interfaces\IManager.cs" />
<Compile Include="Interfaces\IPenaltyList.cs" />
<Compile Include="Interfaces\ISerializable.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="Database.cs" />
<Compile Include="Event.cs" />
<Compile Include="File.cs" />
<Compile Include="Dvar.cs" />
<Compile Include="Map.cs" />
<Compile Include="Helpers\PlayerHistory.cs" />
<Compile Include="Player.cs" />
<Compile Include="Objects\Player.cs" />
<Compile Include="Interfaces\IPlugin.cs" />
<Compile Include="Objects\Report.cs" />
<Compile Include="PluginImporter.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="RCON.cs" />
<Compile Include="Server.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="WebService.cs" />
</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)Admin\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>
<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>
<PreBuildEvent>if exist "$(SolutionDir)BUILD\Plugins" rmdir /Q /S "$(SolutionDir)BUILD\Plugins"
mkdir "$(SolutionDir)BUILD\Plugins"

View File

@ -4,6 +4,8 @@ using System.Text;
using System.Text.RegularExpressions;
using System.Linq;
using System.Collections.Generic;
using SharedLibrary.Objects;
using static SharedLibrary.Server;
namespace SharedLibrary
@ -60,7 +62,7 @@ namespace SharedLibrary
int.TryParse(playerInfo[0], out cID);
var regex = Regex.Match(responseLine, @"\d+\.\d+\.\d+.\d+\:\d{1,5}");
string cIP = regex.Value.Split(':')[0];
Player P = new Player(cName, npID, cID, cIP) { Ping = Ping };
Player P = new Player() { Name = cName, NetworkId = npID, ClientNumber = cID, IPAddress = cIP, Ping = Ping };
StatusPlayers.Add(P);
}
}
@ -224,7 +226,7 @@ namespace SharedLibrary
}
if (Elapsed.TotalDays <= 365)
{
if (Elapsed.TotalDays < 1.5)
if (Elapsed.TotalDays < 1.5)
return $"1 day{ago}";
return Math.Round(Elapsed.TotalDays, 0) + $" days{ago}";
}
@ -297,5 +299,26 @@ namespace SharedLibrary
{
return markdownString.Replace("<", "\\<").Replace(">", "\\>").Replace("|", "\\|");
}
public static Player AsPlayer(this Database.Models.EFClient client)
{
return client == null ? null : new Player()
{
Active = client.Active,
AliasLink =client.AliasLink,
AliasLinkId = client.AliasLinkId,
ClientId = client.ClientId,
ClientNumber = 0,
FirstConnection = client.FirstConnection,
Connections = client.Connections,
IPAddress = client.IPAddress,
NetworkId = client.NetworkId,
Name = client.Name,
Level = client.Level,
TotalConnectionTime = client.TotalConnectionTime,
Masked = client.Masked,
LastConnection = DateTime.UtcNow
};
}
}
}

View File

@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SharedLibrary
{
@ -27,7 +28,7 @@ namespace SharedLibrary
{
string GetPath();
string GetName();
HttpResponse GetPage(System.Collections.Specialized.NameValueCollection querySet, IDictionary<string, string> headers);
Task<HttpResponse> GetPage(System.Collections.Specialized.NameValueCollection querySet, IDictionary<string, string> headers);
bool Visible();
}
@ -89,7 +90,7 @@ namespace SharedLibrary
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()
{

View File

@ -1,5 +1,7 @@
<?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" />
<package id="Newtonsoft.Json" version="10.0.2" targetFramework="net45" />
<package id="System.Data.SQLite.Core" version="1.0.105.1" targetFramework="net45" />
</packages>