From c1faf8a02e0d0c5168db9588e5e81eee732a5aad Mon Sep 17 00:00:00 2001 From: RaidMax Date: Sat, 27 May 2017 17:08:04 -0500 Subject: [PATCH] Moved client database into manager, as it should be.. Some more transitional things and a few fixes. --- Admin/IW4M ADMIN.csproj | 5 +- Admin/Manager.cs | 17 +++- Admin/PenaltyList.cs | 36 +++++++ Admin/Plugins.cs | 2 +- Admin/Properties/AssemblyInfo.cs | 8 +- Admin/Server.cs | 100 ++++++------------- Admin/WebService.cs | 27 +++-- Admin/lib/SharedLibrary.dll | Bin 94208 -> 94720 bytes Auto Restart Plugin/Main.cs | 8 +- EventAPI/EventAPI.csproj | 5 +- EventAPI/Plugin.cs | 11 +- EventAPI/packages.config | 2 +- MessageboardPlugin/Forum.cs | 2 +- MessageboardPlugin/MessageboardPlugin.csproj | 5 +- MessageboardPlugin/Plugin.cs | 8 +- MessageboardPlugin/packages.config | 2 +- SharedLibrary/Commands/NativeCommands.cs | 34 ++++--- SharedLibrary/Database.cs | 57 ++++++----- SharedLibrary/Interfaces/IManager.cs | 2 + SharedLibrary/Interfaces/IPenaltyList.cs | 15 +++ SharedLibrary/Interfaces/IPlugin.cs | 8 +- SharedLibrary/Server.cs | 16 +-- SharedLibrary/SharedLibrary.csproj | 1 + Stats Plugin/Plugin.cs | 14 +-- Votemap Plugin/Plugin.cs | 8 +- Welcome Plugin/Plugin.cs | 8 +- 26 files changed, 215 insertions(+), 186 deletions(-) create mode 100644 Admin/PenaltyList.cs create mode 100644 SharedLibrary/Interfaces/IPenaltyList.cs diff --git a/Admin/IW4M ADMIN.csproj b/Admin/IW4M ADMIN.csproj index 1c9d9a23..9aff25eb 100644 --- a/Admin/IW4M ADMIN.csproj +++ b/Admin/IW4M ADMIN.csproj @@ -31,7 +31,7 @@ true publish.htm 6 - 0.9.1.%2a + 1.3.1.%2a false true true @@ -55,7 +55,7 @@ bin\Release\ TRACE prompt - 0 + 3 true On false @@ -115,6 +115,7 @@ + diff --git a/Admin/Manager.cs b/Admin/Manager.cs index a6027495..556a9658 100644 --- a/Admin/Manager.cs +++ b/Admin/Manager.cs @@ -17,6 +17,8 @@ namespace IW4MAdmin { static Manager Instance; public List Servers { get; private set; } + Database ClientDatabase; + SharedLibrary.Interfaces.IPenaltyList ClientPenalties; List Commands; Kayak.IScheduler webServiceTask; Thread WebThread; @@ -35,6 +37,9 @@ namespace IW4MAdmin Logger = new Log(logFile, Log.Level.Production, 0); Servers = new List(); Commands = new List(); + + ClientDatabase = new ClientsDB("Database/clients.rm"); + ClientPenalties = new PenaltyList(); } public List GetServers() @@ -59,6 +64,7 @@ namespace IW4MAdmin if (Configs.Count() == 0) Config.Generate(); + SharedLibrary.WebService.Init(); PluginImporter.Load(); foreach (var file in Configs) @@ -87,7 +93,6 @@ namespace IW4MAdmin } - SharedLibrary.WebService.Init(); webServiceTask = WebService.getScheduler(); WebThread = new Thread(webServiceTask.Start); @@ -136,5 +141,15 @@ namespace IW4MAdmin { Running = false; } + + public ClientsDB GetClientDatabase() + { + return ClientDatabase as ClientsDB; + } + + public SharedLibrary.Interfaces.IPenaltyList GetClientPenalties() + { + return ClientPenalties; + } } } diff --git a/Admin/PenaltyList.cs b/Admin/PenaltyList.cs new file mode 100644 index 00000000..76eb4b03 --- /dev/null +++ b/Admin/PenaltyList.cs @@ -0,0 +1,36 @@ +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) + { + Manager.GetInstance().GetClientDatabase().addBan(P); + } + + public void RemovePenalty(Penalty P) + { + Manager.GetInstance().GetClientDatabase().removeBan(P.npID); + } + + public List FindPenalties(Player P) + { + return Manager.GetInstance().GetClientDatabase().GetClientPenalties(P); + } + + public List AsChronoList(int offset, int count) + { + return Manager.GetInstance().GetClientDatabase().GetPenaltiesChronologically(offset, count); + } + } +} diff --git a/Admin/Plugins.cs b/Admin/Plugins.cs index 243d536c..202a4abf 100644 --- a/Admin/Plugins.cs +++ b/Admin/Plugins.cs @@ -70,7 +70,7 @@ namespace IW4MAdmin if (potentialPlugins.Find(x => x.Name == newNotify.Name) == null) { potentialPlugins.Add(newNotify); - newNotify.OnLoad(); + newNotify.OnLoadAsync(); Manager.GetInstance().Logger.Write("Loaded plugin \"" + newNotify.Name + "\"" + " [" + newNotify.Version + "]", Log.Level.Debug); totalLoaded++; } diff --git a/Admin/Properties/AssemblyInfo.cs b/Admin/Properties/AssemblyInfo.cs index 81f067e1..da5918dd 100644 --- a/Admin/Properties/AssemblyInfo.cs +++ b/Admin/Properties/AssemblyInfo.cs @@ -7,11 +7,11 @@ using System.Resources; // set of attributes. Change these attribute values to modify the information // associated with an assembly. [assembly: AssemblyTitle("IW4M Admin")] -[assembly: AssemblyDescription("Server admin for your IW4M Servers")] +[assembly: AssemblyDescription("Server administration for your IW4X Servers")] [assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("RaidMax LLC")] +[assembly: AssemblyCompany("ForeverNone LLC")] [assembly: AssemblyProduct("")] -[assembly: AssemblyCopyright("2016")] +[assembly: AssemblyCopyright("2017")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] @@ -33,5 +33,5 @@ using System.Resources; // 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.2.*")] +[assembly: AssemblyVersion("1.3.*")] [assembly: NeutralResourcesLanguageAttribute("en")] diff --git a/Admin/Server.cs b/Admin/Server.cs index 1bb49780..6e823871 100644 --- a/Admin/Server.cs +++ b/Admin/Server.cs @@ -68,18 +68,18 @@ namespace IW4MAdmin try #endif { - Player NewPlayer = clientDB.getPlayer(P.npID, P.clientID); + Player NewPlayer = Manager.GetClientDatabase().getPlayer(P.npID, P.clientID); if (NewPlayer == null) // first time connecting { Log.Write("Client slot #" + P.clientID + " first time connecting", Log.Level.All); - clientDB.addPlayer(P); - NewPlayer = clientDB.getPlayer(P.npID, P.clientID); + Manager.GetClientDatabase().addPlayer(P); + NewPlayer = Manager.GetClientDatabase().getPlayer(P.npID, P.clientID); aliasDB.addPlayer(new Aliases(NewPlayer.databaseID, NewPlayer.Name, NewPlayer.IP)); } - List Admins = clientDB.getAdmins(); + List Admins = Manager.GetClientDatabase().getAdmins(); if (Admins.Find(x => x.Name == P.Name) != null) { if ((Admins.Find(x => x.Name == P.Name).npID != P.npID) && NewPlayer.Level < Player.Permission.Moderator) @@ -116,7 +116,7 @@ namespace IW4MAdmin NewPlayer.updateIP(P.IP); aliasDB.updatePlayer(NewPlayer.Alias); - clientDB.updatePlayer(NewPlayer); + Manager.GetClientDatabase().updatePlayer(NewPlayer); await ExecuteEvent(new Event(Event.GType.Connect, "", NewPlayer, null, this)); @@ -214,7 +214,7 @@ namespace IW4MAdmin { Player Leaving = Players[cNum]; Leaving.Connections++; - clientDB.updatePlayer(Leaving); + Manager.GetClientDatabase().updatePlayer(Leaving); Log.Write("Client at " + cNum + " disconnecting...", Log.Level.Debug); await ExecuteEvent(new Event(Event.GType.Disconnect, "", Leaving, null, this)); @@ -266,28 +266,7 @@ namespace IW4MAdmin //Check ban list for every banned player and return ban if match is found override public Penalty isBanned(Player C) { - if (C.Level == Player.Permission.Banned) - return Bans.Find(p => p.npID.Equals(C.npID)); - - foreach (Penalty B in Bans) - { - if (B.npID.Length < 5 || B.IP.Length < 5) - continue; - - if (B.npID == null || C.npID == null) - continue; - - if (B.npID == C.npID) - return B; - - if (B.IP == null || C.IP == null) - continue; - - if (C.IP == B.IP) - return B; - } - - return null; + return Manager.GetClientPenalties().FindPenalties(C).Where(b => b.BType == Penalty.Type.Ban).FirstOrDefault(); } //Process requested command correlating to an event @@ -328,7 +307,7 @@ namespace IW4MAdmin int.TryParse(Args[0].Substring(1, Args[0].Length-1), out dbID); IW4MServer castServer = (IW4MServer)(E.Owner); - Player found = castServer.clientDB.getPlayer(dbID); + Player found = Manager.GetClientDatabase().getPlayer(dbID); if (found != null) { E.Target = found; @@ -363,7 +342,7 @@ namespace IW4MAdmin { try { - await P.OnEvent(E, this); + await P.OnEventAsync(E, this); } catch (Exception Except) @@ -413,7 +392,7 @@ namespace IW4MAdmin if ((DateTime.Now - tickTime).TotalMilliseconds >= 1000) { foreach (var Plugin in PluginImporter.potentialPlugins) - await Plugin.OnTick(this); + await Plugin.OnTickAsync(this); tickTime = DateTime.Now; } @@ -555,7 +534,7 @@ namespace IW4MAdmin logFile = new IFile(logPath); Log.Write("Log file is " + logPath, Log.Level.Debug); await ExecuteEvent(new Event(Event.GType.Start, "Server started", null, null, this)); - //Bans = clientDB.getBans(); + //Bans = Manager.GetClientDatabase().getBans(); #if !DEBUG Broadcast("IW4M Admin is now ^2ONLINE"); #endif @@ -706,10 +685,8 @@ namespace IW4MAdmin await Target.Kick("Too many warnings!", Origin); else { - Penalty newPenalty = new Penalty(Penalty.Type.Warning, SharedLibrary.Utilities.StripColors(Reason), Target.npID, Origin.npID, DateTime.Now, Target.IP); - clientDB.addBan(newPenalty); - foreach (var S in Manager.GetServers()) // make sure bans show up on the webfront - S.Bans = S.clientDB.getBans(); + Penalty newPenalty = new Penalty(Penalty.Type.Warning, Reason.StripColors(), Target.npID, Origin.npID, DateTime.Now, Target.IP); + Manager.GetClientPenalties().AddPenalty(newPenalty); Target.Warnings++; String Message = String.Format("^1WARNING ^7[^3{0}^7]: ^3{1}^7, {2}", Target.Warnings, Target.Name, Target.lastOffense); await Broadcast(Message); @@ -721,10 +698,8 @@ namespace IW4MAdmin if (Target.clientID > -1) { String Message = "^1Player Kicked: ^5" + Reason; - Penalty newPenalty = new Penalty(Penalty.Type.Kick, SharedLibrary.Utilities.StripColors(Reason.Trim()), Target.npID, Origin.npID, DateTime.Now, Target.IP); - clientDB.addBan(newPenalty); - foreach (Server S in Manager.GetServers()) // make sure bans show up on the webfront - S.Bans = S.clientDB.getBans(); + Penalty newPenalty = new Penalty(Penalty.Type.Kick, Reason.StripColors().Trim(), Target.npID, Origin.npID, DateTime.Now, Target.IP); + Manager.GetClientPenalties().AddPenalty(newPenalty); await this.ExecuteCommandAsync("clientkick " + Target.clientID + " \"" + Message + "^7\""); } } @@ -737,10 +712,7 @@ namespace IW4MAdmin Penalty newPenalty = new Penalty(Penalty.Type.TempBan, SharedLibrary.Utilities.StripColors(Reason), Target.npID, Origin.npID, DateTime.Now, Target.IP); await Task.Run(() => { - // todo: single database.. again - foreach (Server S in Manager.GetServers()) // make sure bans show up on the webfront - S.Bans = S.clientDB.getBans(); - clientDB.addBan(newPenalty); + Manager.GetClientPenalties().AddPenalty(newPenalty); }); } } @@ -778,11 +750,8 @@ namespace IW4MAdmin await Task.Run(() => { - clientDB.addBan(newBan); - clientDB.updatePlayer(Target); - - foreach (Server S in Manager.GetServers()) // make sure bans show up on the webfront - S.Bans = S.clientDB.getBans(); + Manager.GetClientPenalties().AddPenalty(newBan); + Manager.GetClientDatabase().updatePlayer(Target); }); lock (Reports) // threading seems to do something weird here @@ -803,27 +772,24 @@ namespace IW4MAdmin } } - override public async Task Unban(String GUID, Player Target) + override public async Task Unban(Player Target) { - foreach (Penalty B in Bans) + // database stuff can be time consuming + await Task.Run(() => { - if (B.npID == Target.npID) - { - // database stuff can be time consuming - await Task.Run(() => - { - clientDB.removeBan(Target.npID, Target.IP); + var FoundPenalaties = Manager.GetClientPenalties().FindPenalties(Target); + var PenaltyToRemove = FoundPenalaties.Find(b => b.BType == Penalty.Type.Ban); - Player P = clientDB.getPlayer(Target.npID, -1); - P.setLevel(Player.Permission.User); - clientDB.updatePlayer(P); + if (PenaltyToRemove == null) + return; + + Manager.GetClientPenalties().RemovePenalty(PenaltyToRemove); + + Player P = Manager.GetClientDatabase().getPlayer(Target.npID, -1); + P.setLevel(Player.Permission.User); + Manager.GetClientDatabase().updatePlayer(P); + }); - // todo: single database - foreach (Server S in Manager.GetServers()) // make sure bans show up on the webfront - S.Bans = S.clientDB.getBans(); - }); - } - } } public override bool Reload() @@ -856,7 +822,7 @@ namespace IW4MAdmin override public void initMacros() { Macros = new Dictionary(); - Macros.Add("TOTALPLAYERS", clientDB.totalPlayers()); + Macros.Add("TOTALPLAYERS", Manager.GetClientDatabase().totalPlayers()); Macros.Add("TOTALKILLS", totalKills); Macros.Add("VERSION", IW4MAdmin.Program.Version); } diff --git a/Admin/WebService.cs b/Admin/WebService.cs index 174f270d..20113123 100644 --- a/Admin/WebService.cs +++ b/Admin/WebService.cs @@ -288,7 +288,7 @@ namespace IW4MAdmin if (S != null) { - Player admin = Manager.GetInstance().Servers.First().clientDB.getPlayer(querySet["IP"]); + Player admin = Manager.GetInstance().GetClientDatabase().getPlayer(querySet["IP"]); if (admin == null) admin = new Player("RestUser", "-1", -1, (int)Player.Permission.User); @@ -354,7 +354,8 @@ namespace IW4MAdmin try { - selectedPenalties = Manager.GetInstance().Servers.First().Bans.OrderByDescending(x => x.When).ToList().GetRange(Convert.ToInt32(querySet["from"]), 15); + //selectedPenalties = Manager.GetInstance().Servers.First().Bans.OrderByDescending(x => x.When).ToList().GetRange(Convert.ToInt32(querySet["from"]), 15); + selectedPenalties = ((Manager.GetInstance().GetClientPenalties()) as PenaltyList).AsChronoList(Convert.ToInt32(querySet["from"]), 15).OrderByDescending(b => b.When).ToList(); } catch (Exception) @@ -366,8 +367,8 @@ namespace IW4MAdmin foreach (var p in selectedPenalties) { - Player admin = Manager.GetInstance().Servers.First().clientDB.getPlayer(p.bannedByID, 0); - Player penalized = Manager.GetInstance().Servers.First().clientDB.getPlayer(p.npID, 0); + Player admin = Manager.GetInstance().GetClientDatabase().getPlayer(p.bannedByID, 0); + Player penalized = Manager.GetInstance().GetClientDatabase().getPlayer(p.npID, 0); if (admin == null && penalized == null) continue; if (admin == null) @@ -503,7 +504,7 @@ namespace IW4MAdmin { HttpResponse resp = new HttpResponse(); resp.contentType = getContentType(); - resp.content = Newtonsoft.Json.JsonConvert.SerializeObject(Manager.GetInstance().Servers[0].Bans.Where(x => x.BType == Penalty.Type.Ban), Newtonsoft.Json.Formatting.Indented, new Newtonsoft.Json.JsonConverter[] { new Newtonsoft.Json.Converters.StringEnumConverter() }); + resp.content = Newtonsoft.Json.JsonConvert.SerializeObject(((Manager.GetInstance().GetClientPenalties()) as PenaltyList).AsChronoList(Convert.ToInt32(querySet["from"]), 15), Newtonsoft.Json.Formatting.Indented, new Newtonsoft.Json.JsonConverter[] { new Newtonsoft.Json.Converters.StringEnumConverter() }); resp.additionalHeaders = new Dictionary(); return resp; } @@ -591,29 +592,26 @@ namespace IW4MAdmin resp.contentType = getContentType(); resp.additionalHeaders = new Dictionary(); - bool authed = Manager.GetInstance().Servers.First().clientDB.getAdmins().FindAll(x => x.IP == querySet["IP"]).Count > 0; + bool authed = Manager.GetInstance().GetClientDatabase().getAdmins().FindAll(x => x.IP == querySet["IP"]).Count > 0; if (querySet["id"] != null) { - matchedPlayers.Add(Manager.GetInstance().Servers.First().clientDB.getPlayer(Convert.ToInt32(querySet["id"]))); + matchedPlayers.Add(Manager.GetInstance().GetClientDatabase().getPlayer(Convert.ToInt32(querySet["id"]))); } else if (querySet["npID"] != null) { - matchedPlayers.Add(Manager.GetInstance().Servers.First().clientDB.getPlayers(new List { querySet["npID"] }).First()); + matchedPlayers.Add(Manager.GetInstance().GetClientDatabase().getPlayers(new List { querySet["npID"] }).First()); } else if (querySet["name"] != null) { - matchedPlayers = Manager.GetInstance().Servers.First().clientDB.findPlayers(querySet["name"]); + matchedPlayers = Manager.GetInstance().GetClientDatabase().findPlayers(querySet["name"]); } else if (querySet["recent"] != null) { - if (Manager.GetInstance().Servers.Count > 0) - matchedPlayers = Manager.GetInstance().Servers.First().clientDB.getRecentPlayers(); - else - resp.content = Newtonsoft.Json.JsonConvert.SerializeObject(null); + matchedPlayers = Manager.GetInstance().GetClientDatabase().getRecentPlayers(); } if (matchedPlayers != null && matchedPlayers.Count > 0) @@ -631,8 +629,7 @@ namespace IW4MAdmin eachPlayer.playernpID = pp.npID; eachPlayer.forumID = -1; eachPlayer.authed = authed; - if (eachPlayer.forumID < 500000) - eachPlayer.showV2Features = true; + eachPlayer.showV2Features = false; foreach (var a in playerAliases) { diff --git a/Admin/lib/SharedLibrary.dll b/Admin/lib/SharedLibrary.dll index e1a0d44ca168b051b0c9e3ecf0858c82d706e024..0ca9621d0b5d590b855b32783b78cc3e2236054d 100644 GIT binary patch literal 94720 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 - - ..\packages\Newtonsoft.Json.9.0.1\lib\net40\Newtonsoft.Json.dll - False + + ..\packages\Newtonsoft.Json.10.0.2\lib\net45\Newtonsoft.Json.dll diff --git a/EventAPI/Plugin.cs b/EventAPI/Plugin.cs index 04dd0c23..9715adaf 100644 --- a/EventAPI/Plugin.cs +++ b/EventAPI/Plugin.cs @@ -95,7 +95,7 @@ namespace EventAPI } } - public async Task OnLoad() + public async Task OnLoadAsync() { apiEvents = new Queue(); flaggedMessagesText = new List(); @@ -103,29 +103,28 @@ namespace EventAPI WebService.pageList.Add(new EventsJSON()); } - public async Task OnUnload() + public async Task OnUnloadAsync() { apiEvents.Clear(); activeServers.Clear(); } - public async Task OnTick(Server S) + public async Task OnTickAsync(Server S) { return; } - public async Task OnEvent(Event E, Server S) + public async Task OnEventAsync(Event E, Server S) { if (E.Type == Event.GType.Start) { activeServers.Add(S); - S.Log.Write("Event API now running on " + S.getName(), Log.Level.Production); } if (E.Type == Event.GType.Stop) { + // fixme: this will be bad once FTP is working and there can be multiple servers on the same port. activeServers.RemoveAll(s => s.getPort() == S.getPort()); - S.Log.Write("Event API no longer running on " + S.getName(), Log.Level.Production); } if (E.Type == Event.GType.Connect) diff --git a/EventAPI/packages.config b/EventAPI/packages.config index 0cdd293b..a272c64d 100644 --- a/EventAPI/packages.config +++ b/EventAPI/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file diff --git a/MessageboardPlugin/Forum.cs b/MessageboardPlugin/Forum.cs index f6345a6c..03678950 100644 --- a/MessageboardPlugin/Forum.cs +++ b/MessageboardPlugin/Forum.cs @@ -54,7 +54,7 @@ namespace MessageBoard.Forum { forumPages = new List(); activeSessions = new List(); - database = new Storage.Database("forum.db"); + database = new Storage.Database("Database/forum.db"); } public void startSession(string sessionID) diff --git a/MessageboardPlugin/MessageboardPlugin.csproj b/MessageboardPlugin/MessageboardPlugin.csproj index decbd7f0..0f897a32 100644 --- a/MessageboardPlugin/MessageboardPlugin.csproj +++ b/MessageboardPlugin/MessageboardPlugin.csproj @@ -62,9 +62,8 @@ ..\packages\DNA.Text.2.1.1.10633\lib\DNA.Text.dll True - - ..\packages\Newtonsoft.Json.9.0.1\lib\net40\Newtonsoft.Json.dll - False + + ..\packages\Newtonsoft.Json.10.0.2\lib\net45\Newtonsoft.Json.dll diff --git a/MessageboardPlugin/Plugin.cs b/MessageboardPlugin/Plugin.cs index 14a6f319..79abe994 100644 --- a/MessageboardPlugin/Plugin.cs +++ b/MessageboardPlugin/Plugin.cs @@ -34,23 +34,23 @@ namespace MessageBoard.Plugin } } - public async Task OnLoad() + public async Task OnLoadAsync() { forum = new Forum.Manager(); forum.Start(); } - public async Task OnUnload() + public async Task OnUnloadAsync() { forum.Stop(); } - public async Task OnTick(Server S) + public async Task OnTickAsync(Server S) { return; } - public async Task OnEvent(Event E, Server S) + public async Task OnEventAsync(Event E, Server S) { if (E.Type == Event.GType.Start) { diff --git a/MessageboardPlugin/packages.config b/MessageboardPlugin/packages.config index 2cc52d7e..bb9bbeec 100644 --- a/MessageboardPlugin/packages.config +++ b/MessageboardPlugin/packages.config @@ -3,5 +3,5 @@ - + \ No newline at end of file diff --git a/SharedLibrary/Commands/NativeCommands.cs b/SharedLibrary/Commands/NativeCommands.cs index 7a2e9fcc..8f743a21 100644 --- a/SharedLibrary/Commands/NativeCommands.cs +++ b/SharedLibrary/Commands/NativeCommands.cs @@ -24,12 +24,12 @@ namespace SharedLibrary.Commands public override async Task ExecuteAsync(Event E) { - if (E.Owner.clientDB.getOwner() == null) + if (E.Owner.Manager.GetClientDatabase().getOwner() == null) { E.Origin.setLevel(Player.Permission.Owner); await E.Origin.Tell("Congratulations, you have claimed ownership of this server!"); E.Owner.owner = E.Origin; - E.Owner.clientDB.updatePlayer(E.Origin); + E.Owner.Manager.GetClientDatabase().updatePlayer(E.Origin); } else await E.Origin.Tell("This server already has an owner!"); @@ -131,7 +131,7 @@ namespace SharedLibrary.Commands public override async Task ExecuteAsync(Event E) { - await E.Owner.Unban(E.Data.Trim(), E.Target); + await E.Owner.Unban(E.Target); await E.Origin.Tell($"Successfully unbanned {E.Target.Name}::{E.Target.npID}"); } } @@ -236,7 +236,7 @@ namespace SharedLibrary.Commands public override async Task ExecuteAsync(Event E) { - await E.Owner.Broadcast("Performing fast restart..."); + await E.Owner.Broadcast($"Fast restarting in ^53 ^7seconds [^5{E.Origin.Name}]"); await Task.Delay(3000); await E.Owner.ExecuteCommandAsync("fast_restart"); } @@ -248,8 +248,8 @@ namespace SharedLibrary.Commands public override async Task ExecuteAsync(Event E) { - await E.Owner.Broadcast("Performing map rotate..."); - await Task.Delay(3000); + await E.Owner.Broadcast($"Map rotating in ^55 ^7seconds [^5{E.Origin.Name}]"); + await Task.Delay(5000); await E.Owner.ExecuteCommandAsync("map_rotate"); } } @@ -296,7 +296,7 @@ namespace SharedLibrary.Commands await E.Origin.Tell(E.Target.Name + " was successfully promoted!"); //NEEED TO MOVE - E.Owner.clientDB.updatePlayer(E.Target); + E.Owner.Manager.GetClientDatabase().updatePlayer(E.Target); } else @@ -370,7 +370,7 @@ namespace SharedLibrary.Commands public override async Task ExecuteAsync(Event E) { - var db_players = E.Owner.clientDB.findPlayers(E.Data.Trim()); + var db_players = E.Owner.Manager.GetClientDatabase().findPlayers(E.Data.Trim()); if (db_players == null) { @@ -400,7 +400,7 @@ namespace SharedLibrary.Commands return; } - //var db_players = E.Owner.clientDB.findPlayers(E.Data.Trim()); + //var db_players = E.Owner.Manager.GetClientDatabase().findPlayers(E.Data.Trim()); var db_aliases = E.Owner.aliasDB.findPlayers(E.Data); if (db_aliases == null) @@ -422,7 +422,7 @@ namespace SharedLibrary.Commands lookingFor = S; } - Player Current = E.Owner.clientDB.getPlayer(P.Number); + Player Current = E.Owner.Manager.GetClientDatabase().getPlayer(P.Number); if (Current != null) { @@ -498,7 +498,7 @@ namespace SharedLibrary.Commands await E.Origin.Tell("You have ^5flagged ^7" + E.Target.Name); } - E.Owner.clientDB.updatePlayer(E.Target); + E.Owner.Manager.GetClientDatabase().updatePlayer(E.Target); } } @@ -591,15 +591,17 @@ namespace SharedLibrary.Commands return; } - Penalty B = E.Owner.Bans.Find(b => b.npID.Equals(E.Target.npID)); - - if (B == null) + var B = E.Owner.Manager.GetClientPenalties().FindPenalties(E.Target); + var BannedPenalty = B.Find(b => b.BType == Penalty.Type.Ban); + + + if (BannedPenalty == null) { await E.Origin.Tell("No active ban was found for that player."); return; } - Player Banner = E.Owner.clientDB.getPlayer(B.bannedByID, -1); + Player Banner = E.Owner.Manager.GetClientDatabase().getPlayer(BannedPenalty.bannedByID, -1); if (Banner == null) { @@ -607,7 +609,7 @@ namespace SharedLibrary.Commands return; } - await E.Origin.Tell(String.Format("^1{0} ^7was banned by ^5{1} ^7for: {2}", E.Target.Name, Banner.Name, B.Reason)); + await E.Origin.Tell(String.Format("^1{0} ^7was banned by ^5{1} ^7for: {2}", E.Target.Name, Banner.Name, BannedPenalty.Reason)); } } diff --git a/SharedLibrary/Database.cs b/SharedLibrary/Database.cs index be6504e1..6f8cfb75 100644 --- a/SharedLibrary/Database.cs +++ b/SharedLibrary/Database.cs @@ -157,7 +157,7 @@ namespace SharedLibrary catch (Exception e) { //LOGME - Console.Write("Could not execute"); + Console.WriteLine($"Line 160: {e.Message}"); } return dt; @@ -178,7 +178,7 @@ namespace SharedLibrary catch (Exception e) { //LOGME - Console.Write("Couldnotexecute"); + Console.Write($"Line 181: {e.Message}"); } return dt; @@ -263,7 +263,7 @@ namespace SharedLibrary public List getRecentPlayers() { List returnssss = new List(); - String Query = String.Format("SELECT * FROM CLIENTS ORDER BY Connections desc LIMIT 25"); + String Query = String.Format($"SELECT * FROM CLIENTS LIMIT 15 OFFSET (SELECT COUNT(*) FROM CLIENTS)-15"); DataTable Result = GetDataTable(Query); if (Result != null && Result.Rows.Count > 0) @@ -277,25 +277,9 @@ namespace SharedLibrary } } - return returnssss; + return returnssss.OrderByDescending(p => p.LastConnection).ToList(); ; } - public List getReservedNPIDs() - { - List npIDs = new List(); - String Query = String.Format("SELECT npID FROM CLIENTS WHERE Reserved = 1"); - DataTable Result = GetDataTable(Query); - - if (Result != null && Result.Rows.Count > 0) - foreach (DataRow ResponseRow in Result.Rows) - npIDs.Add(ResponseRow["npID"].ToString()); - - - return npIDs; - } - - - public List getPlayers(List npIDs) { List returnssss = new List(); @@ -459,11 +443,11 @@ namespace SharedLibrary return null; } - //Returns list of bans in database - public List getBans() + public List GetClientPenalties(Player P) { - List Bans = new List(); - DataTable Result = GetDataTable("SELECT * FROM BANS ORDER BY TIME DESC"); + List ClientPenalties = new List(); + String Query = $"SELECT * FROM `BANS` WHERE `npID` = '{P.npID}' OR `IP` = '{P.IP}'"; + DataTable Result = GetDataTable(Query); foreach (DataRow Row in Result.Rows) { @@ -474,11 +458,32 @@ namespace SharedLibrary if (Row["TYPE"].ToString().Length != 0) BanType = (Penalty.Type)Enum.Parse(typeof(Penalty.Type), Row["TYPE"].ToString()); - Bans.Add(new Penalty(BanType, Row["Reason"].ToString().Trim(), Row["npID"].ToString(), Row["bannedByID"].ToString(), DateTime.Parse(Row["TIME"].ToString()), Row["IP"].ToString())); + ClientPenalties.Add(new Penalty(BanType, Row["Reason"].ToString().Trim(), Row["npID"].ToString(), Row["bannedByID"].ToString(), DateTime.Parse(Row["TIME"].ToString()), Row["IP"].ToString())); } - return Bans; + return ClientPenalties; + } + + public List GetPenaltiesChronologically(int offset, int count) + { + List ClientPenalties = new List(); + DataTable Result = GetDataTable($"SELECT * FROM BANS LIMIT {count} OFFSET (SELECT COUNT(*) FROM BANS)-{offset + 10}"); + + foreach (DataRow Row in Result.Rows) + { + if (Row["TIME"].ToString().Length < 2) //compatibility with my old database + Row["TIME"] = DateTime.Now.ToString(); + + SharedLibrary.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())); + + } + + return ClientPenalties; } //Returns all players with level > Flagged diff --git a/SharedLibrary/Interfaces/IManager.cs b/SharedLibrary/Interfaces/IManager.cs index 6a3b4e46..4eae7cde 100644 --- a/SharedLibrary/Interfaces/IManager.cs +++ b/SharedLibrary/Interfaces/IManager.cs @@ -13,5 +13,7 @@ namespace SharedLibrary.Interfaces void Stop(); List GetServers(); List GetCommands(); + IPenaltyList GetClientPenalties(); + ClientsDB GetClientDatabase(); } } diff --git a/SharedLibrary/Interfaces/IPenaltyList.cs b/SharedLibrary/Interfaces/IPenaltyList.cs new file mode 100644 index 00000000..3a85b9f6 --- /dev/null +++ b/SharedLibrary/Interfaces/IPenaltyList.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SharedLibrary.Interfaces +{ + public interface IPenaltyList + { + void AddPenalty(Penalty P); + void RemovePenalty(Penalty P); + List FindPenalties(Player P); + } +} diff --git a/SharedLibrary/Interfaces/IPlugin.cs b/SharedLibrary/Interfaces/IPlugin.cs index e12b7f24..f6e5d752 100644 --- a/SharedLibrary/Interfaces/IPlugin.cs +++ b/SharedLibrary/Interfaces/IPlugin.cs @@ -5,10 +5,10 @@ namespace SharedLibrary.Interfaces { public interface IPlugin { - Task OnLoad(); - Task OnUnload(); - Task OnEvent(Event E, Server S); - Task OnTick(Server S); + Task OnLoadAsync(); + Task OnUnloadAsync(); + Task OnEventAsync(Event E, Server S); + Task OnTickAsync(Server S); //for logging purposes String Name { get; } diff --git a/SharedLibrary/Server.cs b/SharedLibrary/Server.cs index 5f9978ee..94c6e3b7 100644 --- a/SharedLibrary/Server.cs +++ b/SharedLibrary/Server.cs @@ -27,10 +27,8 @@ namespace SharedLibrary #else Log = new Log(logFile, Log.Level.Production, port); #endif - clientDB = new ClientsDB("Database/clients.rm"); aliasDB = new AliasesDB("Database/aliases.rm"); - Bans = new List(); Players = new List(new Player[18]); events = new Queue(); Macros = new Dictionary(); @@ -47,7 +45,7 @@ namespace SharedLibrary var commands = mgr.GetCommands(); - owner = clientDB.getOwner(); + owner = Manager.GetClientDatabase().getOwner(); if (owner == null) commands.Add(new Owner("owner", "claim ownership of the server", "owner", Player.Permission.User, 0, false)); @@ -118,11 +116,6 @@ namespace SharedLibrary return Players.FindAll(x => x != null); } - //Returns list of all active bans (loaded at runtime) - public List getBans() - { - return Bans; - } public int pID() { @@ -142,7 +135,7 @@ namespace SharedLibrary foreach (Aliases A in getAliases(Origin)) databaseIDs.Add(A.Number); - return clientDB.getPlayers(databaseIDs); + return Manager.GetClientDatabase().getPlayers(databaseIDs); } /// @@ -303,7 +296,7 @@ namespace SharedLibrary /// npID of the player /// I don't remember what this is for /// - abstract public Task Unban(String npID, Player Target); + abstract public Task Unban(Player Target); /// /// Change the current searver map @@ -437,7 +430,6 @@ namespace SharedLibrary //Objects public Interfaces.IManager Manager { get; protected set; } public Log Log { get; private set; } - public List Bans; public Player owner; public List maps; public List rules; @@ -479,7 +471,7 @@ namespace SharedLibrary protected String Mod; // Databases - public ClientsDB clientDB; + //public ClientsDB clientDB; public AliasesDB aliasDB; //Remote diff --git a/SharedLibrary/SharedLibrary.csproj b/SharedLibrary/SharedLibrary.csproj index 53401e0f..578c6e34 100644 --- a/SharedLibrary/SharedLibrary.csproj +++ b/SharedLibrary/SharedLibrary.csproj @@ -60,6 +60,7 @@ + diff --git a/Stats Plugin/Plugin.cs b/Stats Plugin/Plugin.cs index 8521e9b0..64786b86 100644 --- a/Stats Plugin/Plugin.cs +++ b/Stats Plugin/Plugin.cs @@ -46,7 +46,7 @@ namespace StatsPlugin await E.Origin.Tell("^5--Top Players--"); foreach (KeyValuePair pStat in pStats) { - Player P = E.Owner.clientDB.getPlayer(pStat.Key, -1); + Player P = E.Owner.Manager.GetClientDatabase().getPlayer(pStat.Key, -1); 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)); @@ -71,7 +71,7 @@ namespace StatsPlugin public StatTracking(int port) { - playerStats = new StatsDB("stats_" + port + ".rm"); + playerStats = new StatsDB("Database/stats_" + port + ".rm"); inactiveMinutes = new int[18]; Kills = new int[18]; deathStreaks = new int[18]; @@ -97,22 +97,22 @@ namespace StatsPlugin get { return "RaidMax"; } } - public async Task OnLoad() + public async Task OnLoadAsync() { statLists = new List(); } - public async Task OnUnload() + public async Task OnUnloadAsync() { statLists.Clear(); } - public async Task OnTick(Server S) + public async Task OnTickAsync(Server S) { return; } - public async Task OnEvent(Event E, Server S) + public async Task OnEventAsync(Event E, Server S) { if (E.Type == Event.GType.Start) { @@ -132,7 +132,7 @@ namespace StatsPlugin if (checkForTrusted.playTime >= 4320 && E.Origin.Level < Player.Permission.Trusted) { E.Origin.setLevel(Player.Permission.Trusted); - E.Owner.clientDB.updatePlayer(E.Origin); + E.Owner.Manager.GetClientDatabase().updatePlayer(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!"); } diff --git a/Votemap Plugin/Plugin.cs b/Votemap Plugin/Plugin.cs index 40622aa3..92154705 100644 --- a/Votemap Plugin/Plugin.cs +++ b/Votemap Plugin/Plugin.cs @@ -204,12 +204,12 @@ namespace Votemap_Plugin } } - public async Task OnLoad() + public async Task OnLoadAsync() { serverVotingList = new List(); } - public async Task OnUnload() + public async Task OnUnloadAsync() { serverVotingList.Clear(); } @@ -219,7 +219,7 @@ namespace Votemap_Plugin /// This is not high-precision, but will run 1 time per second /// /// - public async Task OnTick(Server S) + public async Task OnTickAsync(Server S) { var serverVotes = getServerVotes(S.getPort()); @@ -277,7 +277,7 @@ namespace Votemap_Plugin } } - public async Task OnEvent(Event E, Server S) + public async Task OnEventAsync(Event E, Server S) { if (E.Type == Event.GType.Start) { diff --git a/Welcome Plugin/Plugin.cs b/Welcome Plugin/Plugin.cs index 20d951ac..68584c9f 100644 --- a/Welcome Plugin/Plugin.cs +++ b/Welcome Plugin/Plugin.cs @@ -31,22 +31,22 @@ namespace Welcome_Plugin } } - public async Task OnLoad() + public async Task OnLoadAsync() { return; } - public async Task OnUnload() + public async Task OnUnloadAsync() { return; } - public async Task OnTick(Server S) + public async Task OnTickAsync(Server S) { return; } - public async Task OnEvent(Event E, Server S) + public async Task OnEventAsync(Event E, Server S) { if (E.Type == Event.GType.Connect) {