From 5d1c9bd218b7f8a9647063feda83f84afa56fefd Mon Sep 17 00:00:00 2001 From: RaidMax Date: Mon, 12 Jun 2017 17:47:31 -0400 Subject: [PATCH] More cleanup project renaming moved PluginImporter to SharedLibrary config writer abstracted for plugins --- .../{IW4M ADMIN.csproj => Application.csproj} | 2 - Admin/Commands.cs | 24 ---- Admin/Kayak.cs | 2 +- Admin/Manager.cs | 23 ++-- Admin/Plugins.cs | 117 ------------------ Admin/Server.cs | 18 +-- Admin/WebService.cs | 6 +- Admin/lib/SharedLibrary.dll | Bin 102912 -> 105984 bytes IW4M Admin.sln => IW4MAdmin.sln | 10 +- Plugins/EventAPI/Plugin.cs | 6 +- Plugins/FastRestart/Plugin.cs | 39 +++--- Plugins/MessageBoard/Thread.cs | 4 +- Plugins/MessageBoard/User.cs | 2 +- Plugins/SimpleStats/Plugin.cs | 8 +- ...Stats Plugin.csproj => StatsPlugin.csproj} | 0 Plugins/VoteMap/Plugin.cs | 4 +- ...map Plugin.csproj => VotemapPlugin.csproj} | 0 Plugins/Welcome/Plugin.cs | 55 +++++++- ...ome Plugin.csproj => WelcomePlugin.csproj} | 0 SharedLibrary/Commands/NativeCommands.cs | 31 +++-- SharedLibrary/Database.cs | 6 +- SharedLibrary/Event.cs | 2 +- SharedLibrary/{ => Helpers}/AsyncStatus.cs | 2 +- SharedLibrary/Helpers/Configuration.cs | 50 ++++++++ SharedLibrary/{ => Helpers}/MessageToken.cs | 2 +- .../PlayerHistory.cs} | 2 +- SharedLibrary/Interfaces/IManager.cs | 2 +- SharedLibrary/Interfaces/IPlugin.cs | 4 +- SharedLibrary/Penalty.cs | 17 ++- SharedLibrary/Player.cs | 2 +- SharedLibrary/PluginImporter.cs | 78 ++++++++++++ SharedLibrary/RCON.cs | 3 +- SharedLibrary/Report.cs | 18 --- SharedLibrary/Server.cs | 11 +- SharedLibrary/SharedLibrary.csproj | 9 +- SharedLibrary/Utilities.cs | 74 ++--------- 36 files changed, 303 insertions(+), 330 deletions(-) rename Admin/{IW4M ADMIN.csproj => Application.csproj} (99%) delete mode 100644 Admin/Commands.cs delete mode 100644 Admin/Plugins.cs rename IW4M Admin.sln => IW4MAdmin.sln (97%) rename Plugins/SimpleStats/{Stats Plugin.csproj => StatsPlugin.csproj} (100%) rename Plugins/VoteMap/{Votemap Plugin.csproj => VotemapPlugin.csproj} (100%) rename Plugins/Welcome/{Welcome Plugin.csproj => WelcomePlugin.csproj} (100%) rename SharedLibrary/{ => Helpers}/AsyncStatus.cs (97%) create mode 100644 SharedLibrary/Helpers/Configuration.cs rename SharedLibrary/{ => Helpers}/MessageToken.cs (92%) rename SharedLibrary/{Miscellaneous.cs => Helpers/PlayerHistory.cs} (89%) create mode 100644 SharedLibrary/PluginImporter.cs delete mode 100644 SharedLibrary/Report.cs diff --git a/Admin/IW4M ADMIN.csproj b/Admin/Application.csproj similarity index 99% rename from Admin/IW4M ADMIN.csproj rename to Admin/Application.csproj index 3251bc472..599b29c85 100644 --- a/Admin/IW4M ADMIN.csproj +++ b/Admin/Application.csproj @@ -122,14 +122,12 @@ - - True diff --git a/Admin/Commands.cs b/Admin/Commands.cs deleted file mode 100644 index 37b65645c..000000000 --- a/Admin/Commands.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using SharedLibrary; -using SharedLibrary.Network; -using System.Threading.Tasks; - -namespace IW4MAdmin -{ - class Plugins : Command - { - public Plugins(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { } - - public override async Task ExecuteAsync(Event E) - { - await E.Origin.Tell("^5Loaded Plugins:"); - foreach (SharedLibrary.Interfaces.IPlugin P in PluginImporter.potentialPlugins) - { - await E.Origin.Tell(String.Format("^3{0} ^7[v^3{1}^7] by ^5{2}^7", P.Name, P.Version, P.Author)); - } - } - } -} - \ No newline at end of file diff --git a/Admin/Kayak.cs b/Admin/Kayak.cs index 432b9d91d..82d7cedac 100644 --- a/Admin/Kayak.cs +++ b/Admin/Kayak.cs @@ -42,7 +42,7 @@ namespace IW4MAdmin NameValueCollection querySet = new NameValueCollection(); if (request.QueryString != null) - querySet = System.Web.HttpUtility.ParseQueryString(SharedLibrary.Utilities.removeNastyChars(request.QueryString)); + querySet = System.Web.HttpUtility.ParseQueryString(SharedLibrary.Utilities.StripIllegalCharacters(request.QueryString)); querySet.Set("IP", IP); SharedLibrary.HttpResponse requestedPage = WebService.GetPage(request.Path, querySet, request.Headers); diff --git a/Admin/Manager.cs b/Admin/Manager.cs index 1641f4513..84e8f8b1b 100644 --- a/Admin/Manager.cs +++ b/Admin/Manager.cs @@ -1,14 +1,9 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Text; -using System.Diagnostics; -using System.Runtime.InteropServices; -using System.Net; using System.Threading; using SharedLibrary; using System.IO; -using SharedLibrary.Network; using System.Threading.Tasks; namespace IW4MAdmin @@ -17,12 +12,12 @@ namespace IW4MAdmin { static Manager Instance; public List Servers { get; private set; } - List TaskStatuses; + List TaskStatuses; Database ClientDatabase; Database AliasesDatabase; SharedLibrary.Interfaces.IPenaltyList ClientPenalties; List Commands; - List MessageTokens; + List MessageTokens; Kayak.IScheduler webServiceTask; Thread WebThread; public SharedLibrary.Interfaces.ILogger Logger { get; private set; } @@ -38,8 +33,8 @@ namespace IW4MAdmin Logger = new Logger("Logs/IW4MAdmin.log"); Servers = new List(); Commands = new List(); - TaskStatuses = new List(); - MessageTokens = new List(); + TaskStatuses = new List(); + MessageTokens = new List(); ClientDatabase = new ClientsDB("Database/clients.rm"); AliasesDatabase = new AliasesDB("Database/aliases.rm"); @@ -69,7 +64,7 @@ namespace IW4MAdmin ServerConfig.Generate(); SharedLibrary.WebService.Init(); - PluginImporter.Load(); + SharedLibrary.Plugins.PluginImporter.Load(this); foreach (var file in Configs) { @@ -84,9 +79,12 @@ namespace IW4MAdmin Servers.Add(ServerInstance); // this way we can keep track of execution time and see if problems arise. - var Status = new AsyncStatus(ServerInstance, UPDATE_FREQUENCY); + var Status = new SharedLibrary.Helpers.AsyncStatus(ServerInstance, UPDATE_FREQUENCY); TaskStatuses.Add(Status); + foreach (var Plugin in SharedLibrary.Plugins.PluginImporter.ActivePlugins) + await Plugin.OnLoadAsync(ServerInstance); + Logger.WriteVerbose($"Now monitoring {ServerInstance.Hostname}"); } @@ -114,7 +112,6 @@ namespace IW4MAdmin Running = true; } - public void Start() { while (Running) @@ -166,7 +163,7 @@ namespace IW4MAdmin return Logger; } - public IList GetMessageTokens() + public IList GetMessageTokens() { return MessageTokens; } diff --git a/Admin/Plugins.cs b/Admin/Plugins.cs deleted file mode 100644 index 25d3c56a3..000000000 --- a/Admin/Plugins.cs +++ /dev/null @@ -1,117 +0,0 @@ -using System; -using System.IO; -using System.Collections.Generic; -using System.Reflection; -using SharedLibrary; -using SharedLibrary.Interfaces; - -namespace IW4MAdmin -{ - public class PluginImporter - { - public static List potentialCommands = new List(); - public static List potentialPlugins = new List(); - public static IPlugin webFront = null; - //private static AppDomain pluginDomain; - - public static bool Load() - { - //pluginDomain = AppDomain.CreateDomain("Plugins"); - string[] dllFileNames = null; - - if (Directory.Exists(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location) + "\\plugins")) - dllFileNames = Directory.GetFiles(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location) + "\\plugins", "*.dll"); - - else - { - Manager.GetInstance().Logger.WriteWarning("Plugin folder does not exist!"); - return false; - } - - if (dllFileNames == null || dllFileNames.Length == 0) - { - Manager.GetInstance().Logger.WriteDebug("No plugins to load"); - return true; - } - - ICollection assemblies = new List(dllFileNames.Length); - foreach (string dllFile in dllFileNames) - { - byte[] rawDLL = File.ReadAllBytes(dllFile); // because we want to update the plugin without restarting - Assembly assembly = Assembly.Load(rawDLL); - assemblies.Add(assembly); - } - - int LoadedPlugins = 0; - int LoadedCommands = 0; - foreach (Assembly Plugin in assemblies) - { - if (Plugin != null) - { - Type[] types = Plugin.GetTypes(); - foreach(Type assemblyType in types) - { - if (assemblyType.IsClass && assemblyType.BaseType.Name == "Command") - { - Object commandObject = Activator.CreateInstance(assemblyType); - Command newCommand = (Command)commandObject; - potentialCommands.Add(newCommand); - Manager.GetInstance().Logger.WriteDebug("Registered command \"" + newCommand.Name + "\""); - LoadedCommands++; - continue; - } - - try - { - if (assemblyType.GetInterface("IPlugin", false) == null) - continue; - - Object notifyObject = Activator.CreateInstance(assemblyType); - IPlugin newNotify = (IPlugin)notifyObject; - if (potentialPlugins.Find(x => x.Name == newNotify.Name) == null) - { - potentialPlugins.Add(newNotify); - newNotify.OnLoadAsync(); - Manager.GetInstance().Logger.WriteDebug($"Loaded plugin \"{ newNotify.Name }\" [{newNotify.Version}]"); - LoadedPlugins++; - } - } - - catch (Exception E) - { - Manager.GetInstance().Logger.WriteWarning($"Could not load plugin {Plugin.Location} - {E.Message}"); - } - } - } - } - - Manager.GetInstance().Logger.WriteInfo($"Loaded {LoadedPlugins} plugins and registered {LoadedCommands} commands."); - return true; - } - - /* - public static void Unload() - { - - foreach (IPlugin P in potentialPlugins) - { - try - { - P.onUnload(); - } - - catch (Exception E) - { - Manager.GetInstance().mainLog.Write("There was an error unloading \"" + P.Name + "\" plugin", Log.Level.Debug); - Manager.GetInstance().mainLog.Write("Error Message: " + E.Message, Log.Level.Debug); - Manager.GetInstance().mainLog.Write("Error Trace: " + E.StackTrace, Log.Level.Debug); - continue; - } - } - - potentialCommands = new List(); - potentialPlugins = new List(); - AppDomain.Unload(pluginDomain); - }*/ - } -} diff --git a/Admin/Server.cs b/Admin/Server.cs index a9d2ce600..a93c31386 100644 --- a/Admin/Server.cs +++ b/Admin/Server.cs @@ -313,7 +313,7 @@ namespace IW4MAdmin { await ProcessEvent(E); - foreach (SharedLibrary.Interfaces.IPlugin P in PluginImporter.potentialPlugins) + foreach (SharedLibrary.Interfaces.IPlugin P in SharedLibrary.Plugins.PluginImporter.ActivePlugins) { try { @@ -386,7 +386,7 @@ namespace IW4MAdmin if ((DateTime.Now - tickTime).TotalMilliseconds >= 1000) { // We don't want to await here, just in case user plugins are really slow :c - foreach (var Plugin in PluginImporter.potentialPlugins) + foreach (var Plugin in SharedLibrary.Plugins.PluginImporter.ActivePlugins) #if !DEBUG Plugin.OnTickAsync(this); #else @@ -400,7 +400,7 @@ namespace IW4MAdmin { while (PlayerHistory.Count > 144) // 12 times a minute for 12 hours PlayerHistory.Dequeue(); - PlayerHistory.Enqueue(new PlayerHistory(lastCount, ClientNum)); + PlayerHistory.Enqueue(new SharedLibrary.Helpers.PlayerHistory(lastCount, ClientNum)); playerCountStart = DateTime.Now; } @@ -786,16 +786,8 @@ namespace IW4MAdmin override public void InitializeTokens() { - Manager.GetMessageTokens().Add(new MessageToken("TOTALPLAYERS", Manager.GetClientDatabase().TotalPlayers().ToString)); - Manager.GetMessageTokens().Add(new MessageToken("VERSION", Program.Version.ToString)); - } - - override public void InitializeCommands() - { - foreach (Command C in PluginImporter.potentialCommands) - Manager.GetCommands().Add(C); - - Manager.GetCommands().Add(new Plugins("plugins", "view all loaded plugins. syntax: !plugins", "p", Player.Permission.Administrator, 0, false)); + Manager.GetMessageTokens().Add(new SharedLibrary.Helpers.MessageToken("TOTALPLAYERS", Manager.GetClientDatabase().TotalPlayers().ToString)); + Manager.GetMessageTokens().Add(new SharedLibrary.Helpers.MessageToken("VERSION", Program.Version.ToString)); } } } diff --git a/Admin/WebService.cs b/Admin/WebService.cs index 4acddff24..4c0ff6fca 100644 --- a/Admin/WebService.cs +++ b/Admin/WebService.cs @@ -202,7 +202,7 @@ namespace IW4MAdmin serverPort = S.GetPort(), maxPlayers = S.MaxClients, mapName = S.CurrentMap.Alias, - gameType = Utilities.gametypeLocalized(S.Gametype), + gameType = Utilities.GetLocalizedGametype(S.Gametype), currentPlayers = S.GetPlayersAsList().Count, chatHistory = S.ChatHistory, players = new List() @@ -406,7 +406,7 @@ namespace IW4MAdmin adminName = admin.Name, adminLevel = admin.Level.ToString(), penaltyReason = p.Reason, - penaltyTime = SharedLibrary.Utilities.timePassed(p.When), + penaltyTime = SharedLibrary.Utilities.GetTimePassed(p.When), penaltyType = p.BType.ToString(), playerName = penalized.Name, playerID = penalized.DatabaseID @@ -683,7 +683,7 @@ namespace IW4MAdmin } eachPlayer.playerConnections = pp.Connections; - eachPlayer.lastSeen = Utilities.timePassed(pp.LastConnection); + eachPlayer.lastSeen = Utilities.GetTimePassed(pp.LastConnection); pInfo.Add(eachPlayer); } diff --git a/Admin/lib/SharedLibrary.dll b/Admin/lib/SharedLibrary.dll index ad3b75cee96ca92afb229c2a49f3c61474b2b45c..215d26768d6e6d3c66316adfb4e3b9fffebfe451 100644 GIT binary patch literal 105984 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 literal 102912 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 diff --git a/IW4M Admin.sln b/IW4MAdmin.sln similarity index 97% rename from IW4M Admin.sln rename to IW4MAdmin.sln index 6ed66584d..51c859a68 100644 --- a/IW4M Admin.sln +++ b/IW4MAdmin.sln @@ -1,9 +1,9 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 -VisualStudioVersion = 15.0.26403.7 +VisualStudioVersion = 15.0.26430.12 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IW4M ADMIN", "Admin\IW4M ADMIN.csproj", "{DD5DCDA2-51DB-4B1A-922F-5705546E6115}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Application", "Admin\Application.csproj", "{DD5DCDA2-51DB-4B1A-922F-5705546E6115}" ProjectSection(ProjectDependencies) = postProject {AF097E6B-48D5-4452-9CCF-0A81A21F341D} = {AF097E6B-48D5-4452-9CCF-0A81A21F341D} {4785AB75-66F3-4391-985D-63A5A049A0FA} = {4785AB75-66F3-4391-985D-63A5A049A0FA} @@ -13,19 +13,19 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IW4M ADMIN", "Admin\IW4M AD {D51EECEB-438A-47DA-870F-7D7B41BC24D6} = {D51EECEB-438A-47DA-870F-7D7B41BC24D6} EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stats Plugin", "Plugins\SimpleStats\Stats Plugin.csproj", "{4785AB75-66F3-4391-985D-63A5A049A0FA}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StatsPlugin", "Plugins\SimpleStats\StatsPlugin.csproj", "{4785AB75-66F3-4391-985D-63A5A049A0FA}" ProjectSection(ProjectDependencies) = postProject {D51EECEB-438A-47DA-870F-7D7B41BC24D6} = {D51EECEB-438A-47DA-870F-7D7B41BC24D6} EndProjectSection EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharedLibrary", "SharedLibrary\SharedLibrary.csproj", "{D51EECEB-438A-47DA-870F-7D7B41BC24D6}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Welcome Plugin", "Plugins\Welcome\Welcome Plugin.csproj", "{AF097E6B-48D5-4452-9CCF-0A81A21F341D}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WelcomePlugin", "Plugins\Welcome\WelcomePlugin.csproj", "{AF097E6B-48D5-4452-9CCF-0A81A21F341D}" ProjectSection(ProjectDependencies) = postProject {D51EECEB-438A-47DA-870F-7D7B41BC24D6} = {D51EECEB-438A-47DA-870F-7D7B41BC24D6} EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Votemap Plugin", "Plugins\VoteMap\Votemap Plugin.csproj", "{428D8EB9-ECA3-4A66-AA59-3A944378C33F}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VotemapPlugin", "Plugins\VoteMap\VotemapPlugin.csproj", "{428D8EB9-ECA3-4A66-AA59-3A944378C33F}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MessageboardPlugin", "Plugins\MessageBoard\MessageboardPlugin.csproj", "{E46C85BD-A99C-484E-BCCE-0F1831C5925E}" EndProject diff --git a/Plugins/EventAPI/Plugin.cs b/Plugins/EventAPI/Plugin.cs index aa76d99a9..a9c64d2d2 100644 --- a/Plugins/EventAPI/Plugin.cs +++ b/Plugins/EventAPI/Plugin.cs @@ -35,7 +35,7 @@ namespace EventAPI { StringBuilder s = new StringBuilder(); foreach (var S in Events.ActiveServers) - s.Append(String.Format("{0} has {1}/{4} players playing {2} on {3}\n", S.Hostname, S.GetPlayersAsList().Count, Utilities.gametypeLocalized(S.Gametype), S.CurrentMap.Name, S.MaxClients)); + s.Append(String.Format("{0} has {1}/{4} players playing {2} on {3}\n", S.Hostname, S.GetPlayersAsList().Count, Utilities.GetLocalizedGametype(S.Gametype), S.CurrentMap.Name, S.MaxClients)); requestedEvent.Event = new RestEvent(RestEvent.EventType.STATUS, RestEvent.EventVersion.IW4MAdmin, s.ToString(), "Status", "", ""); requestedEvent.eventCount = 1; } @@ -95,7 +95,7 @@ namespace EventAPI } } - public async Task OnLoadAsync() + public async Task OnLoadAsync(Server S) { APIEvents = new Queue(); flaggedMessagesText = new List(); @@ -103,7 +103,7 @@ namespace EventAPI WebService.PageList.Add(new EventsJSON()); } - public async Task OnUnloadAsync() + public async Task OnUnloadAsync(Server S) { APIEvents.Clear(); ActiveServers.Clear(); diff --git a/Plugins/FastRestart/Plugin.cs b/Plugins/FastRestart/Plugin.cs index 5fc3ff823..8137a786c 100644 --- a/Plugins/FastRestart/Plugin.cs +++ b/Plugins/FastRestart/Plugin.cs @@ -1,12 +1,10 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Threading.Tasks; using SharedLibrary; using SharedLibrary.Interfaces; using SharedLibrary.Network; +using SharedLibrary.Helpers; namespace Plugin { @@ -21,9 +19,11 @@ namespace Plugin public override async Task ExecuteAsync(Event E) { - FastRestartPlugin.Config = new FastRestartConfig() { Enabled = true }; - Serialize.Write($"config/fastrestartconfig_{E.Owner}.cfg", FastRestartPlugin.Config); - await E.Origin.Tell("Fast restarting is now enabled for this server"); + var Config = new FastRestartConfig() { Enabled = true }; + if (!new Configuration(E.Owner).Write(Config)) + await E.Origin.Tell("Failed to save the configuration file for fast restart"); + else + await E.Origin.Tell("Fast restarting is now enabled for this server"); } } @@ -33,9 +33,11 @@ namespace Plugin public override async Task ExecuteAsync(Event E) { - FastRestartPlugin.Config = new FastRestartConfig() { Enabled = false }; - Serialize.Write($"config/fastrestartconfig_{E.Owner}.cfg", FastRestartPlugin.Config); - await E.Origin.Tell("Fast restarting is now disabled for this server"); + var Config = new FastRestartConfig() { Enabled = false }; + if (!new Configuration(E.Owner).Write(Config)) + await E.Origin.Tell("Failed to save the configuration file for fast restart"); + else + await E.Origin.Tell("Fast restarting is now disabled for this server"); } } @@ -43,7 +45,6 @@ namespace Plugin { bool MatchEnded; DateTime MatchEndTime; - public static FastRestartConfig Config; public string Name { get { return "Fast Restarter"; } } @@ -58,30 +59,24 @@ namespace Plugin try { await S.GetDvarAsync("scr_intermission_time"); - Config = Serialize.Read($"config/fastrestartconfig_{E.Owner}.cfg"); } catch (SharedLibrary.Exceptions.DvarException) { - await S.ExecuteCommandAsync("set scr_intermission_time 20"); - } - - catch (SharedLibrary.Exceptions.SerializeException) - { - Config = new FastRestartConfig() { Enabled = false }; - Serialize.Write($"config/fastrestartconfig_{E.Owner}.cfg", Config); + await S.SetDvarAsync("scr_intermission_time", 20); } } } - public Task OnLoadAsync() + public async Task OnLoadAsync(Server S) { - return null; + // this initializes the file if it doesn't exist already + new Configuration(S).Read(); } public async Task OnTickAsync(Server S) { - if (!Config.Enabled) + if (!new Configuration(S).Read().Enabled) return; MatchEnded = (await S.GetDvarAsync("scr_gameended")).Value == 1; @@ -97,7 +92,7 @@ namespace Plugin } } - public Task OnUnloadAsync() + public Task OnUnloadAsync(Server S) { return null; } diff --git a/Plugins/MessageBoard/Thread.cs b/Plugins/MessageBoard/Thread.cs index 2959479d8..e52172c61 100644 --- a/Plugins/MessageBoard/Thread.cs +++ b/Plugins/MessageBoard/Thread.cs @@ -24,7 +24,7 @@ namespace MessageBoard public Post(int id, int threadid, bool visible, string title, string content, User author, DateTime creationDate, DateTime updatedDate) : base(id, title, visible, content, 0, author, null, creationDate, updatedDate) { - this.lastModificationString = SharedLibrary.Utilities.timePassed(creationDate); + this.lastModificationString = SharedLibrary.Utilities.GetTimePassed(creationDate); this.threadid = threadid; } @@ -118,7 +118,7 @@ namespace MessageBoard this.threadCategory = threadCategory; this.creationDate = creationDate; this.updatedDate = updatedDate; - this.lastModificationString = SharedLibrary.Utilities.timePassed(updatedDate); + this.lastModificationString = SharedLibrary.Utilities.GetTimePassed(updatedDate); this.visible = visible; } diff --git a/Plugins/MessageBoard/User.cs b/Plugins/MessageBoard/User.cs index db4ceeba5..51d3f5b19 100644 --- a/Plugins/MessageBoard/User.cs +++ b/Plugins/MessageBoard/User.cs @@ -77,7 +77,7 @@ namespace MessageBoard this.avatarURL = avatarURL; this.posts = posts; - this.lastLoginString = SharedLibrary.Utilities.timePassed(lastLogin); + this.lastLoginString = SharedLibrary.Utilities.GetTimePassed(lastLogin); } public int getID() diff --git a/Plugins/SimpleStats/Plugin.cs b/Plugins/SimpleStats/Plugin.cs index 547656d63..1dc94c0f6 100644 --- a/Plugins/SimpleStats/Plugin.cs +++ b/Plugins/SimpleStats/Plugin.cs @@ -133,12 +133,12 @@ namespace StatsPlugin get { return "RaidMax"; } } - public async Task OnLoadAsync() + public async Task OnLoadAsync(Server S) { statLists = new List(); } - public async Task OnUnloadAsync() + public async Task OnUnloadAsync(Server S) { statLists.Clear(); } @@ -155,8 +155,8 @@ namespace StatsPlugin statLists.Add(new StatTracking(S.GetPort())); if (statLists.Count == 1) { - S.Manager.GetMessageTokens().Add(new MessageToken("TOTALKILLS", GetTotalKills)); - S.Manager.GetMessageTokens().Add(new MessageToken("TOTALPLAYTIME", GetTotalPlaytime)); + S.Manager.GetMessageTokens().Add(new SharedLibrary.Helpers.MessageToken("TOTALKILLS", GetTotalKills)); + S.Manager.GetMessageTokens().Add(new SharedLibrary.Helpers.MessageToken("TOTALPLAYTIME", GetTotalPlaytime)); } } diff --git a/Plugins/SimpleStats/Stats Plugin.csproj b/Plugins/SimpleStats/StatsPlugin.csproj similarity index 100% rename from Plugins/SimpleStats/Stats Plugin.csproj rename to Plugins/SimpleStats/StatsPlugin.csproj diff --git a/Plugins/VoteMap/Plugin.cs b/Plugins/VoteMap/Plugin.cs index e3c3ec209..f8a1afe29 100644 --- a/Plugins/VoteMap/Plugin.cs +++ b/Plugins/VoteMap/Plugin.cs @@ -205,12 +205,12 @@ namespace Votemap_Plugin } } - public async Task OnLoadAsync() + public async Task OnLoadAsync(Server S) { serverVotingList = new List(); } - public async Task OnUnloadAsync() + public async Task OnUnloadAsync(Server S) { serverVotingList.Clear(); } diff --git a/Plugins/VoteMap/Votemap Plugin.csproj b/Plugins/VoteMap/VotemapPlugin.csproj similarity index 100% rename from Plugins/VoteMap/Votemap Plugin.csproj rename to Plugins/VoteMap/VotemapPlugin.csproj diff --git a/Plugins/Welcome/Plugin.cs b/Plugins/Welcome/Plugin.cs index 64ec163da..099766df1 100644 --- a/Plugins/Welcome/Plugin.cs +++ b/Plugins/Welcome/Plugin.cs @@ -13,6 +13,53 @@ namespace Welcome_Plugin Dictionary PlayerPings; int PingAverageCount; + String TimesConnected(Player P) + { + int connection = P.Connections; + String Prefix = String.Empty; + if (connection % 10 > 3 || connection % 10 == 0 || (connection % 100 > 9 && connection % 100 < 19)) + Prefix = "th"; + else + { + switch (connection % 10) + { + case 1: + Prefix = "st"; + break; + case 2: + Prefix = "nd"; + break; + case 3: + Prefix = "rd"; + break; + } + } + + switch (connection) + { + case 0: + case 1: + return "first"; + case 2: + return "second"; + case 3: + return "third"; + case 4: + return "fourth"; + case 5: + return "fifth"; + case 100: + return "One-Hundreth (amazing!)"; + case 500: + return "you're really ^5dedicated ^7to this server! This is your ^5500th^7"; + case 1000: + return "you deserve a medal. it's your ^11000th^7"; + + default: + return connection.ToString() + Prefix; + } + } + public string Author { get @@ -37,13 +84,13 @@ namespace Welcome_Plugin } } - public async Task OnLoadAsync() + public async Task OnLoadAsync(Server S) { PlayerPings = new Dictionary(); PingAverageCount = 1; } - public async Task OnUnloadAsync() + public async Task OnUnloadAsync(Server S) { PlayerPings.Clear(); PlayerPings = null; @@ -75,9 +122,9 @@ namespace Welcome_Plugin Player newPlayer = E.Origin; if (newPlayer.Level >= Player.Permission.Trusted && !E.Origin.Masked) - await E.Owner.Broadcast(Utilities.levelToColor(newPlayer.Level) + " ^5" + newPlayer.Name + " ^7has joined the server."); + await E.Owner.Broadcast(Utilities.ConvertLevelToColor(newPlayer.Level) + " ^5" + newPlayer.Name + " ^7has joined the server."); - await newPlayer.Tell($"Welcome ^5{newPlayer.Name}^7, this your ^5{newPlayer.TimesConnected()} ^7time connecting!"); + await newPlayer.Tell($"Welcome ^5{newPlayer.Name}^7, this your ^5{TimesConnected(newPlayer)} ^7time connecting!"); if (newPlayer.Level == Player.Permission.Flagged) await E.Owner.ToAdmins($"^1NOTICE: ^7Flagged player ^5{newPlayer.Name}^7 has joined!"); diff --git a/Plugins/Welcome/Welcome Plugin.csproj b/Plugins/Welcome/WelcomePlugin.csproj similarity index 100% rename from Plugins/Welcome/Welcome Plugin.csproj rename to Plugins/Welcome/WelcomePlugin.csproj diff --git a/SharedLibrary/Commands/NativeCommands.cs b/SharedLibrary/Commands/NativeCommands.cs index 2c1993957..88a3785c5 100644 --- a/SharedLibrary/Commands/NativeCommands.cs +++ b/SharedLibrary/Commands/NativeCommands.cs @@ -18,8 +18,7 @@ namespace SharedLibrary.Commands } class COwner : Command - { - + { public COwner(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { } public override async Task ExecuteAsync(Event E) @@ -145,7 +144,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, SharedLibrary.Utilities.levelToColor(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.ClientID, E.Origin.NetworkID, E.Origin.DatabaseID, SharedLibrary.Utilities.ConvertLevelToColor(E.Origin.Level), E.Origin.IP); await E.Origin.Tell(You); } } @@ -166,9 +165,9 @@ namespace SharedLibrary.Commands continue; if (P.Masked) - playerList.AppendFormat("[^3{0}^7]{3}[^3{1}^7] {2}", Utilities.levelToColor(Player.Permission.User), P.ClientID, P.Name, SharedLibrary.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.ClientID, P.Name, SharedLibrary.Utilities.GetSpaces(Player.Permission.SeniorAdmin.ToString().Length - Player.Permission.User.ToString().Length)); else - playerList.AppendFormat("[^3{0}^7]{3}[^3{1}^7] {2}", Utilities.levelToColor(P.Level), P.ClientID, P.Name, SharedLibrary.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.ClientID, P.Name, SharedLibrary.Utilities.GetSpaces(Player.Permission.SeniorAdmin.ToString().Length - P.Level.ToString().Length)); if (count == 2 || E.Owner.GetPlayersAsList().Count == 1) { @@ -278,7 +277,7 @@ namespace SharedLibrary.Commands return; } - Player.Permission newPerm = Utilities.matchPermission(Utilities.RemoveWords(E.Data, 1)); + Player.Permission newPerm = Utilities.MatchPermission(Utilities.RemoveWords(E.Data, 1)); if (newPerm == Player.Permission.Owner && E.Origin.Level != Player.Permission.Console) newPerm = Player.Permission.Banned; @@ -333,9 +332,9 @@ namespace SharedLibrary.Commands if (P != null && P.Level > Player.Permission.Flagged && !P.Masked) { if (E.Message[0] == '@') - await E.Owner.Broadcast(String.Format("[^3{0}^7] {1}", Utilities.levelToColor(P.Level), P.Name)); + await E.Owner.Broadcast(String.Format("[^3{0}^7] {1}", Utilities.ConvertLevelToColor(P.Level), P.Name)); else - await E.Origin.Tell(String.Format("[^3{0}^7] {1}", Utilities.levelToColor(P.Level), P.Name)); + await E.Origin.Tell(String.Format("[^3{0}^7] {1}", Utilities.ConvertLevelToColor(P.Level), P.Name)); } } } @@ -381,7 +380,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} ago", P.Name, P.DatabaseID, SharedLibrary.Utilities.levelToColor(P.Level), P.IP, P.GetLastConnection()); + String mesg = String.Format("[^3{0}^7] [^3@{1}^7] - [{2}^7] - {3} | last seen {4} ago", P.Name, P.DatabaseID, SharedLibrary.Utilities.ConvertLevelToColor(P.Level), P.IP, P.GetLastConnection()); await E.Origin.Tell(mesg); } } @@ -679,5 +678,19 @@ namespace SharedLibrary.Commands await E.Origin.Tell("Successfully sent RCON command!"); } } + + class CPlugins : Command + { + public CPlugins(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { } + + public override async Task ExecuteAsync(Event E) + { + await E.Origin.Tell("^5Loaded Plugins:"); + foreach (var P in Plugins.PluginImporter.ActivePlugins) + { + await E.Origin.Tell(String.Format("^3{0} ^7[v^3{1}^7] by ^5{2}^7", P.Name, P.Version, P.Author)); + } + } + } } \ No newline at end of file diff --git a/SharedLibrary/Database.cs b/SharedLibrary/Database.cs index 47d013bed..7d29d0653 100644 --- a/SharedLibrary/Database.cs +++ b/SharedLibrary/Database.cs @@ -509,7 +509,7 @@ namespace SharedLibrary { Dictionary newPlayer = new Dictionary { - { "Name", Utilities.removeNastyChars(P.Name) }, + { "Name", Utilities.StripIllegalCharacters(P.Name) }, { "npID", P.NetworkID }, { "Level", (int)P.Level }, { "LastOffense", "" }, @@ -546,7 +546,7 @@ namespace SharedLibrary { Dictionary newBan = new Dictionary { - { "Reason", Utilities.removeNastyChars(B.Reason) }, + { "Reason", Utilities.StripIllegalCharacters(B.Reason) }, { "npID", B.OffenderID }, { "bannedByID", B.PenaltyOriginID }, { "IP", B.IP }, @@ -656,7 +656,7 @@ namespace SharedLibrary Dictionary newPlayer = new Dictionary { { "Number", Alias.Number }, - { "NAMES", Utilities.removeNastyChars(String.Join(";", Alias.Names)) }, + { "NAMES", Utilities.StripIllegalCharacters(String.Join(";", Alias.Names)) }, { "IPS", String.Join(";", Alias.IPS) } }; Insert("ALIASES", newPlayer); diff --git a/SharedLibrary/Event.cs b/SharedLibrary/Event.cs index d182d72e7..245c95035 100644 --- a/SharedLibrary/Event.cs +++ b/SharedLibrary/Event.cs @@ -119,7 +119,7 @@ namespace SharedLibrary { Regex rgx = new Regex("[^a-zA-Z0-9 -! -_]"); string message = rgx.Replace(line[4], ""); - return new Event(GType.Say, Utilities.removeNastyChars(message).StripColors(), SV.ParseClientFromString(line, 2), null, SV) { Message = Utilities.removeNastyChars(message).StripColors() }; + return new Event(GType.Say, Utilities.StripIllegalCharacters(message).StripColors(), SV.ParseClientFromString(line, 2), null, SV) { Message = Utilities.StripIllegalCharacters(message).StripColors() }; } if (eventType == ":") diff --git a/SharedLibrary/AsyncStatus.cs b/SharedLibrary/Helpers/AsyncStatus.cs similarity index 97% rename from SharedLibrary/AsyncStatus.cs rename to SharedLibrary/Helpers/AsyncStatus.cs index 543a20778..384c303ce 100644 --- a/SharedLibrary/AsyncStatus.cs +++ b/SharedLibrary/Helpers/AsyncStatus.cs @@ -5,7 +5,7 @@ using System.Text; using System.Threading; using System.Threading.Tasks; -namespace SharedLibrary +namespace SharedLibrary.Helpers { public sealed class AsyncStatus { diff --git a/SharedLibrary/Helpers/Configuration.cs b/SharedLibrary/Helpers/Configuration.cs new file mode 100644 index 000000000..d8bdec09b --- /dev/null +++ b/SharedLibrary/Helpers/Configuration.cs @@ -0,0 +1,50 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SharedLibrary.Helpers +{ + public class Configuration : Interfaces.Serialize + { + string FilePostfix; + public Configuration(Server S) + { + FilePostfix = $"_{S.GetIP()}_{S.GetPort()}.cfg"; + } + + public T Read() + { + try + { + return Read(); + } + + catch (Exceptions.SerializeException) + { + return default(T); + } + } + + public bool Write(T Data) + { + try + { + Write(Filename(), Data); + return true; + } + + catch(Exceptions.SerializeException) + { + return false; + } + } + + public override string Filename() + { + return $"config/{typeof(T).ToString()}_{FilePostfix}"; + } + + } +} diff --git a/SharedLibrary/MessageToken.cs b/SharedLibrary/Helpers/MessageToken.cs similarity index 92% rename from SharedLibrary/MessageToken.cs rename to SharedLibrary/Helpers/MessageToken.cs index 2cc88d341..285ba9c73 100644 --- a/SharedLibrary/MessageToken.cs +++ b/SharedLibrary/Helpers/MessageToken.cs @@ -1,6 +1,6 @@ using System; -namespace SharedLibrary +namespace SharedLibrary.Helpers { public class MessageToken { diff --git a/SharedLibrary/Miscellaneous.cs b/SharedLibrary/Helpers/PlayerHistory.cs similarity index 89% rename from SharedLibrary/Miscellaneous.cs rename to SharedLibrary/Helpers/PlayerHistory.cs index 10ac37aab..427f4a119 100644 --- a/SharedLibrary/Miscellaneous.cs +++ b/SharedLibrary/Helpers/PlayerHistory.cs @@ -1,6 +1,6 @@ using System; -namespace SharedLibrary +namespace SharedLibrary.Helpers { public class PlayerHistory { diff --git a/SharedLibrary/Interfaces/IManager.cs b/SharedLibrary/Interfaces/IManager.cs index b5d80ea15..27f8ea4d7 100644 --- a/SharedLibrary/Interfaces/IManager.cs +++ b/SharedLibrary/Interfaces/IManager.cs @@ -13,7 +13,7 @@ namespace SharedLibrary.Interfaces IPenaltyList GetClientPenalties(); ClientsDB GetClientDatabase(); AliasesDB GetAliasesDatabase(); - IList GetMessageTokens(); + IList GetMessageTokens(); IList GetActiveClients(); } } diff --git a/SharedLibrary/Interfaces/IPlugin.cs b/SharedLibrary/Interfaces/IPlugin.cs index f6e5d7521..32e37d506 100644 --- a/SharedLibrary/Interfaces/IPlugin.cs +++ b/SharedLibrary/Interfaces/IPlugin.cs @@ -5,8 +5,8 @@ namespace SharedLibrary.Interfaces { public interface IPlugin { - Task OnLoadAsync(); - Task OnUnloadAsync(); + Task OnLoadAsync(Server S); + Task OnUnloadAsync(Server S); Task OnEventAsync(Event E, Server S); Task OnTickAsync(Server S); diff --git a/SharedLibrary/Penalty.cs b/SharedLibrary/Penalty.cs index 45d116cd0..dceccf321 100644 --- a/SharedLibrary/Penalty.cs +++ b/SharedLibrary/Penalty.cs @@ -1,4 +1,5 @@ using System; +using SharedLibrary; namespace SharedLibrary { @@ -6,7 +7,7 @@ namespace SharedLibrary { public Penalty(Type BType, String Reas, String TargID, String From, DateTime time, String ip) { - Reason = Reas.Replace("!",""); + Reason = Reas.CleanChars().StripColors(); OffenderID = TargID; PenaltyOriginID = From; When = time; @@ -36,4 +37,18 @@ namespace SharedLibrary public String IP { get; private set; } public Type BType { get; private set; } } + + public class Report + { + public Report(Player T, Player O, String R) + { + Target = T; + Origin = O; + Reason = R; + } + + public Player Target { get; private set; } + public Player Origin { get; private set; } + public String Reason { get; private set; } + } } diff --git a/SharedLibrary/Player.cs b/SharedLibrary/Player.cs index df986b9d0..c9f51837e 100644 --- a/SharedLibrary/Player.cs +++ b/SharedLibrary/Player.cs @@ -124,7 +124,7 @@ namespace SharedLibrary public String GetLastConnection() { - return Utilities.timePassed(LastConnection); + return Utilities.GetTimePassed(LastConnection); } public void UpdateName(String n) diff --git a/SharedLibrary/PluginImporter.cs b/SharedLibrary/PluginImporter.cs new file mode 100644 index 000000000..8696d5ce9 --- /dev/null +++ b/SharedLibrary/PluginImporter.cs @@ -0,0 +1,78 @@ +using System; +using System.IO; +using System.Collections.Generic; +using System.Reflection; +using SharedLibrary.Interfaces; + +namespace SharedLibrary.Plugins +{ + public class PluginImporter + { + public static List ActiveCommands = new List(); + public static List ActivePlugins = new List(); + + public static bool Load(IManager Manager) + { + string[] dllFileNames = Directory.GetFiles(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location) + "\\plugins", "*.dll"); + + if (dllFileNames.Length == 0) + { + Manager.GetLogger().WriteDebug("No plugins found to load"); + return true; + } + + ICollection assemblies = new List(dllFileNames.Length); + foreach (string dllFile in dllFileNames) + { + byte[] rawDLL = File.ReadAllBytes(dllFile); + Assembly assembly = Assembly.Load(rawDLL); + assemblies.Add(assembly); + } + + int LoadedPlugins = 0; + int LoadedCommands = 0; + foreach (Assembly Plugin in assemblies) + { + if (Plugin != null) + { + Type[] types = Plugin.GetTypes(); + foreach (Type assemblyType in types) + { + if (assemblyType.IsClass && assemblyType.BaseType.Name == "Command") + { + Object commandObject = Activator.CreateInstance(assemblyType); + Command newCommand = (Command)commandObject; + ActiveCommands.Add(newCommand); + Manager.GetLogger().WriteDebug("Registered command \"" + newCommand.Name + "\""); + LoadedCommands++; + continue; + } + + try + { + if (assemblyType.GetInterface("IPlugin", false) == null) + continue; + + Object notifyObject = Activator.CreateInstance(assemblyType); + IPlugin newNotify = (IPlugin)notifyObject; + if (ActivePlugins.Find(x => x.Name == newNotify.Name) == null) + { + ActivePlugins.Add(newNotify); + Manager.GetLogger().WriteDebug($"Loaded plugin \"{ newNotify.Name }\" [{newNotify.Version}]"); + LoadedPlugins++; + } + } + + catch (Exception E) + { + Manager.GetLogger().WriteWarning($"Could not load plugin {Plugin.Location} - {E.Message}"); + } + } + } + } + + Manager.GetLogger().WriteInfo($"Loaded {LoadedPlugins} plugins and registered {LoadedCommands} commands."); + return true; + } + } +} diff --git a/SharedLibrary/RCON.cs b/SharedLibrary/RCON.cs index 07eef67b6..4df31b5dd 100644 --- a/SharedLibrary/RCON.cs +++ b/SharedLibrary/RCON.cs @@ -114,7 +114,7 @@ namespace SharedLibrary.Network public static async Task SetDvarAsync(this Server server, string dvarName, object dvarValue) { - await Task.FromResult(SendQuery(QueryType.DVAR, server, $"{dvarName} {dvarValue}")); + await Task.FromResult(SendQuery(QueryType.DVAR, server, $"set {dvarName} {dvarValue}")); } public static async Task ExecuteCommandAsync(this Server server, string commandName) @@ -139,7 +139,6 @@ namespace SharedLibrary.Network fixedRequest[i / 2] = initialRequestBytes[i]; return fixedRequest; - } } } diff --git a/SharedLibrary/Report.cs b/SharedLibrary/Report.cs deleted file mode 100644 index ff50854fe..000000000 --- a/SharedLibrary/Report.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System; - -namespace SharedLibrary -{ - public class Report - { - public Report(Player T, Player O, String R) - { - Target = T; - Origin = O; - Reason = R; - } - - public Player Target { get; private set; } - public Player Origin { get; private set; } - public String Reason { get; private set; } - } -} diff --git a/SharedLibrary/Server.cs b/SharedLibrary/Server.cs index ae77ffd0d..2081baff5 100644 --- a/SharedLibrary/Server.cs +++ b/SharedLibrary/Server.cs @@ -26,7 +26,7 @@ namespace SharedLibrary Players = new List(new Player[18]); events = new Queue(); Reports = new List(); - PlayerHistory = new Queue(); + PlayerHistory = new Queue(); ChatHistory = new List(); lastWebChat = DateTime.Now; nextMessage = 0; @@ -71,6 +71,7 @@ namespace SharedLibrary commands.Add(new CListAlias("alias", "get past aliases and ips of a player. syntax: !alias ", "known", Player.Permission.Moderator, 1, true)); commands.Add(new CExecuteRCON("rcon", "send rcon command to server. syntax: !rcon ", "rcon", Player.Permission.Owner, 1, false)); commands.Add(new CFindAllPlayers("findall", "find a player by their aliase(s). syntax: !findall ", "fa", Player.Permission.Moderator, 1, false)); + commands.Add(new CPlugins("plugins", "view all loaded plugins. syntax: !plugins", "p", Player.Permission.Administrator, 0, false)); } //Returns current server IP set by `net_ip` -- *STRING* @@ -375,7 +376,11 @@ namespace SharedLibrary /// /// Load up the built in commands /// - abstract public void InitializeCommands(); + public void InitializeCommands() + { + foreach (Command C in Plugins.PluginImporter.ActiveCommands) + Manager.GetCommands().Add(C); + } //Objects public Interfaces.IManager Manager { get; protected set; } @@ -389,7 +394,7 @@ namespace SharedLibrary public int totalKills = 0; public List Reports; public List ChatHistory; - public Queue PlayerHistory { get; private set; } + public Queue PlayerHistory { get; private set; } protected int ConnectionErrors; protected DateTime LastPoll; diff --git a/SharedLibrary/SharedLibrary.csproj b/SharedLibrary/SharedLibrary.csproj index e677ad20e..9715bf8f3 100644 --- a/SharedLibrary/SharedLibrary.csproj +++ b/SharedLibrary/SharedLibrary.csproj @@ -66,18 +66,19 @@ - + + - + @@ -85,12 +86,12 @@ - + + - diff --git a/SharedLibrary/Utilities.cs b/SharedLibrary/Utilities.cs index 5cefe7c3b..ebd518f7c 100644 --- a/SharedLibrary/Utilities.cs +++ b/SharedLibrary/Utilities.cs @@ -10,7 +10,7 @@ namespace SharedLibrary public static class Utilities { //Get string with specified number of spaces -- really only for visual output - public static String getSpaces(int Num) + public static String GetSpaces(int Num) { String SpaceString = String.Empty; while (Num > 0) @@ -22,12 +22,6 @@ namespace SharedLibrary return SpaceString; } - //Sleep for x amount of seconds - public static void Wait(double time) - { - Thread.Sleep((int)Math.Ceiling(time * 1000)); - } - //Remove words from a space delimited string public static String RemoveWords(this string str, int num) { @@ -74,14 +68,11 @@ namespace SharedLibrary return StatusPlayers; } - public static Player.Permission matchPermission(String str) + public static Player.Permission MatchPermission(String str) { String lookingFor = str.ToLower(); -#if REPZ_BUILD - for (Player.Permission Perm = Player.Permission.User; Perm <= Player.Permission.Owner; Perm++) -#else + for (Player.Permission Perm = Player.Permission.User; Perm < Player.Permission.Owner; Perm++) -#endif { if (lookingFor.Contains(Perm.ToString().ToLower())) return Perm; @@ -90,12 +81,10 @@ namespace SharedLibrary return Player.Permission.Banned; } - public static String removeNastyChars(String str) + public static String StripIllegalCharacters(String str) { if (str != null) - { return str.Replace("`", "").Replace("\\", "").Replace("\"", "").Replace(""", "").Replace("&", "&").Replace("\"", "''").Replace("'", "").Replace("?", ""); - } else return String.Empty; @@ -130,7 +119,7 @@ namespace SharedLibrary /// /// Specified player level /// - public static String levelToColor(Player.Permission level) + public static String ConvertLevelToColor(Player.Permission level) { switch (level) { @@ -149,7 +138,7 @@ namespace SharedLibrary } } - public static String ProcessMessageToken(IList tokens, String str) + public static String ProcessMessageToken(IList tokens, String str) { MatchCollection RegexMatches = Regex.Matches(str, @"\{\{[A-Z]+\}\}", RegexOptions.IgnoreCase); foreach (Match M in RegexMatches) @@ -176,7 +165,7 @@ namespace SharedLibrary /// /// Shorthand gametype reported from server /// - public static String gametypeLocalized(String input) + public static String GetLocalizedGametype(String input) { switch (input) { @@ -232,7 +221,7 @@ namespace SharedLibrary return datetime.ToString("yyyy-MM-dd H:mm:ss"); } - public static String timePassed(DateTime start) + public static String GetTimePassed(DateTime start) { TimeSpan Elapsed = DateTime.Now - start; @@ -259,52 +248,5 @@ namespace SharedLibrary else return "a very long time"; } - - public static String TimesConnected(this Player P) - { - int connection = P.Connections; - String Prefix = String.Empty; - if (connection % 10 > 3 || connection % 10 == 0 || (connection % 100 > 9 && connection % 100 < 19)) - Prefix = "th"; - else - { - switch (connection % 10) - { - case 1: - Prefix = "st"; - break; - case 2: - Prefix = "nd"; - break; - case 3: - Prefix = "rd"; - break; - } - } - - switch (connection) - { - case 0: - case 1: - return "first"; - case 2: - return "second"; - case 3: - return "third"; - case 4: - return "fourth"; - case 5: - return "fifth"; - case 100: - return "One-Hundreth (amazing!)"; - case 500: - return "you're really ^5dedicated ^7to this server! This is your ^5500th^7"; - case 1000: - return "you deserve a medal. it's your ^11000th^7"; - - default: - return connection.ToString() + Prefix; - } - } } }