From 7af9c31ea0edc0628f9b6cde5102cbbe78fbedf9 Mon Sep 17 00:00:00 2001 From: RaidMax Date: Fri, 21 Aug 2015 20:11:35 -0500 Subject: [PATCH] Almost finished moving Webfront to a plugin. --- Admin/Command.cs | 13 +- Admin/IW4M ADMIN.csproj | 15 +- Admin/Main.cs | 10 +- Admin/Plugins.cs | 8 +- Admin/Server.cs | 54 +- Admin/WebFront.cs | 680 --------------------- Admin/lib/SharedLibary.dll | Bin 35840 -> 37888 bytes Admin/plugins/SamplePlugin.dll | Bin 7680 -> 7680 bytes Admin/plugins/Webfront Plugin.dll | Bin 0 -> 24576 bytes Admin/webfront/bans.html | 6 +- Admin/webfront/error.html | 11 + Admin/webfront/header.html | 6 +- Admin/webfront/notfound.html | 5 + Admin/webfront/player.html | 2 +- IW4M Admin.sln | 7 + Release Build/lib/SharedLibary.dll | Bin 35840 -> 37888 bytes Release Build/plugins/SamplePlugin.dll | Bin 0 -> 7680 bytes SamplePlugin/Main.cs | 5 +- SharedLibary/Database.cs | 219 ++----- SharedLibary/Event.cs | 8 +- SharedLibary/Player.cs | 49 +- SharedLibary/Plugin.cs | 17 + SharedLibary/Server.cs | 14 +- SharedLibary/SharedLibrary.csproj | 1 + SharedLibary/Utilities.cs | 25 + Webfront Plugin/Properties/AssemblyInfo.cs | 36 ++ 26 files changed, 252 insertions(+), 939 deletions(-) delete mode 100644 Admin/WebFront.cs create mode 100644 Admin/plugins/Webfront Plugin.dll create mode 100644 Admin/webfront/error.html create mode 100644 Admin/webfront/notfound.html create mode 100644 Release Build/plugins/SamplePlugin.dll create mode 100644 SharedLibary/Plugin.cs create mode 100644 Webfront Plugin/Properties/AssemblyInfo.cs diff --git a/Admin/Command.cs b/Admin/Command.cs index dddf40baf..e6cf9c71a 100644 --- a/Admin/Command.cs +++ b/Admin/Command.cs @@ -378,13 +378,13 @@ namespace IW4MAdmin String lookingFor = String.Empty; - foreach(String S in P.getNames()) + foreach(String S in P.Names) { if (S.Contains(E.Data)) lookingFor = S; } - Player Current = E.Owner.clientDB.getPlayer(P.getNumber()); + Player Current = E.Owner.clientDB.getPlayer(P.Number); if (Current != null) { @@ -613,14 +613,13 @@ namespace IW4MAdmin E.Target.Tell("[^3" + E.Target.Name + "^7]"); StringBuilder message = new StringBuilder(); - List playerAliases = new List(); - E.Owner.getAliases(playerAliases, E.Target); + List playerAliases = E.Owner.getPlayerAliases(E.Target); message.Append("Aliases: "); foreach (Player P in playerAliases) { - foreach (String S in P.Alias.getNames()) + foreach (String S in P.Alias.Names) { if (S != String.Empty && S != E.Target.Name) message.Append(S + " | "); @@ -630,13 +629,13 @@ namespace IW4MAdmin message = new StringBuilder(); - if (E.Target.Alias.getIPS() != null) + if (E.Target.Alias.IPS != null) { message.Append("IPs: "); foreach (Player P2 in playerAliases) { - foreach (String IP in P2.Alias.getIPS()) + foreach (String IP in P2.Alias.IPS) { if (IP.Split('.').Length > 3 && IP != String.Empty && !message.ToString().Contains(IP)) message.Append (IP + " | "); diff --git a/Admin/IW4M ADMIN.csproj b/Admin/IW4M ADMIN.csproj index 49eed84f2..71362e7a0 100644 --- a/Admin/IW4M ADMIN.csproj +++ b/Admin/IW4M ADMIN.csproj @@ -88,10 +88,6 @@ app.manifest - - ..\packages\Kayak.0.7.2\lib\Kayak.dll - False - ..\SharedLibary\SharedLibary\bin\Debug\SharedLibary.dll False @@ -123,7 +119,6 @@ - @@ -146,12 +141,18 @@ PreserveNewest + + PreserveNewest + Always Always + + PreserveNewest + Always @@ -164,6 +165,9 @@ Always + + PreserveNewest + Always @@ -305,7 +309,6 @@ del *.pdb del *.dll del app.config del *.manifest -del *.rm del *.log xcopy /E /Y "$(ProjectDir)bin\Release" "$(SolutionDir)Release Build" diff --git a/Admin/Main.cs b/Admin/Main.cs index 80cf95f76..3d38694d0 100644 --- a/Admin/Main.cs +++ b/Admin/Main.cs @@ -12,7 +12,6 @@ namespace IW4MAdmin { static public double Version { get; private set; } static private Manager serverManager; - static private IW4MAdmin_Web.WebFront frontEnd; static void Main(string[] args) { @@ -43,13 +42,8 @@ namespace IW4MAdmin } if (serverManager.getServers() != null) - Program.getManager().mainLog.Write("IW4M Now Initialized! Visit http://127.0.0.1:1624 for server overview.", Log.Level.Production); + Program.getManager().mainLog.Write("IW4M Now Initialized!", Log.Level.Production); - if (serverManager.getServers().Count > 0) - { - frontEnd = new IW4MAdmin_Web.WebFront(); - frontEnd.Init(); - } serverMGRThread.Join(); serverManager.mainLog.Write("Shutting down IW4MAdmin...", Log.Level.Debug); @@ -76,8 +70,6 @@ namespace IW4MAdmin } Program.getManager().shutDown(); - frontEnd.webSchedule.Stop(); - frontEnd.webSchedule.Dispose(); return false; } diff --git a/Admin/Plugins.cs b/Admin/Plugins.cs index cc68916d7..9b73557a7 100644 --- a/Admin/Plugins.cs +++ b/Admin/Plugins.cs @@ -9,13 +9,13 @@ namespace IW4MAdmin public class PluginImporter { public static List potentialCommands; - public static List potentialNotifies; + public static List potentialNotifies; public static bool Load() { string[] dllFileNames = null; potentialCommands = new List(); - potentialNotifies = new List(); + potentialNotifies = new List(); if (Directory.Exists(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location) + "\\plugins")) dllFileNames = Directory.GetFiles(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location) + "\\plugins", "*.dll"); @@ -47,10 +47,10 @@ namespace IW4MAdmin Type[] types = Plugin.GetTypes(); foreach(Type assemblyType in types) { - if(assemblyType.IsClass && assemblyType.BaseType.Name == "EventNotify") + if(assemblyType.IsClass && assemblyType.BaseType.Name == "Notify") { Object notifyObject = Activator.CreateInstance(assemblyType); - EventNotify newNotify = (EventNotify)notifyObject; + Plugin newNotify = (Plugin)notifyObject; potentialNotifies.Add(newNotify); newNotify.onLoad(); Program.getManager().mainLog.Write("Loaded event plugin \"" + assemblyType.Name + "\"", Log.Level.All); diff --git a/Admin/Server.cs b/Admin/Server.cs index 678c6a4ed..7b35cb76a 100644 --- a/Admin/Server.cs +++ b/Admin/Server.cs @@ -18,11 +18,39 @@ namespace IW4MAdmin commandQueue = new Queue(); } - override public void getAliases(List returnPlayers, Player Origin) - { - if (Origin == null) - return; + + private void getAliases(List returnAliases, Aliases currentAlias) + { + foreach(String IP in currentAlias.IPS) + { + List Matching = aliasDB.getPlayer(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 override List getAliases(Player Origin) + { + List allAliases = new List(); + + if (Origin == null) + return allAliases; + + Aliases currentIdentityAliases = aliasDB.getPlayer(Origin.databaseID); + + if (currentIdentityAliases == null) + return allAliases; + + getAliases(allAliases, currentIdentityAliases); + return allAliases; + + /* List aliasAliases = new List(); Aliases currentAliases = aliasDB.getPlayer(Origin.databaseID); @@ -56,7 +84,7 @@ namespace IW4MAdmin } } } - } + } */ } //Add player object p to `players` list @@ -102,16 +130,16 @@ namespace IW4MAdmin NewPlayer.lastEvent = P.lastEvent; // lets check aliases - if ((NewPlayer.Alias.getNames().Find(m => m.Equals(P.Name))) == null || NewPlayer.Name == null || NewPlayer.Name == String.Empty) + 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.addName(NewPlayer.Name); + NewPlayer.Alias.Names.Add(NewPlayer.Name); } // and ips - if (NewPlayer.Alias.getIPS().Find(i => i.Equals(P.IP)) == null || P.IP == null || P.IP == String.Empty) + if (NewPlayer.Alias.IPS.Find(i => i.Equals(P.IP)) == null || P.IP == null || P.IP == String.Empty) { - NewPlayer.Alias.addIP(P.IP); + NewPlayer.Alias.IPS.Add(P.IP); } NewPlayer.updateIP(P.IP); @@ -146,8 +174,7 @@ namespace IW4MAdmin return true; } - List newPlayerAliases = new List(); - getAliases(newPlayerAliases, NewPlayer); + List newPlayerAliases = getPlayerAliases(NewPlayer); foreach (Player aP in newPlayerAliases) // lets check their aliases { @@ -402,7 +429,7 @@ namespace IW4MAdmin { Event curEvent = events.Peek(); processEvent(curEvent); - foreach (EventNotify E in PluginImporter.potentialNotifies) + foreach (Notify E in PluginImporter.potentialNotifies) E.onEvent(curEvent); events.Dequeue(); } @@ -562,6 +589,7 @@ namespace IW4MAdmin #endif } + events.Enqueue(new Event(Event.GType.Stop, "Server monitoring stopped", null, null, this)); isRunning = false; eventQueueThread.Join(); } @@ -623,6 +651,8 @@ namespace IW4MAdmin logFile = new IFile(logPath); Log.Write("Log file is " + logPath, Log.Level.Debug); Log.Write("Now monitoring " + getName(), Log.Level.Production); + events.Enqueue(new Event(Event.GType.Start, "Server started", null, null, this)); + Bans = clientDB.getBans(); return true; } catch (Exception E) diff --git a/Admin/WebFront.cs b/Admin/WebFront.cs deleted file mode 100644 index 6c0d33b4d..000000000 --- a/Admin/WebFront.cs +++ /dev/null @@ -1,680 +0,0 @@ -#define ENABLED_CRAP_CODE_THAT_NEEDS_TO_BE_REWRITTEN -using System; -using System.Globalization; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Web; -using Kayak; -using Kayak.Http; -using System.Net; -using SharedLibrary; -using IW4MAdmin; - - -#if ENABLED_CRAP_CODE_THAT_NEEDS_TO_BE_REWRITTEN -namespace IW4MAdmin_Web -{ - class Client - { - public Client ( WebFront.Page req, int cur, IDictionary inc, String D, Player P) - { - requestedPage = req; - requestedPageNumber = cur; - requestOrigin = inc; - requestData = D; - playerRequesting = P; - } - - public WebFront.Page requestedPage { get; private set; } - public int requestedPageNumber { get; private set; } - public IDictionary requestOrigin { get; private set; } - public String requestData { get; private set; } - public Player playerRequesting { get; private set; } - - } - - class WebFront - { - private Server[] Servers; - - public enum Page - { - main, - stats, - bans, - player - } - - public WebFront() - { - Servers = Program.getServers(); - } - - public void Init() - { - webSchedule = KayakScheduler.Factory.Create(new SchedulerDelegate()); - webServer = KayakServer.Factory.CreateHttp(new RequestDelegate(), webSchedule); - - using (webServer.Listen(new IPEndPoint(IPAddress.Any, 1624))) - { - // runs scheduler on calling thread. this method will block until - // someone calls Stop() on the scheduler. - webSchedule.Start(); - } - } - - public IScheduler webSchedule; - private IServer webServer; - } - - static class Macro - { - static public String parsePagination(int server, int totalItems, int itemsPerPage, int currentPage, String Page) - { - StringBuilder output = new StringBuilder(); - - output.Append("
"); - - if ( currentPage > 0) - output.AppendFormat("PREV", server, currentPage - 1, Page); - double totalPages = Math.Ceiling(((float)totalItems / itemsPerPage)); - output.Append("" + (currentPage + 1) + "/" + totalPages + ""); - if ((currentPage + 1) < totalPages) - output.AppendFormat("NEXT", server, currentPage + 1, Page); - output.Append("
"); - - return output.ToString(); - } - - static public String parseMacros(String input, WebFront.Page Page, int server, int Pagination, bool logged, String Data) - { - StringBuilder buffer = new StringBuilder(); - Server[] Servers= Program.getServers(); - switch (input) - { - case "SERVERS": - int cycleFix = 0; - for (int i = 0; i < Servers.Count(); i++) - { - if (Program.getServers()[i] == null) - continue; - - StringBuilder players = new StringBuilder(); - if (Servers[i].getClientNum() < 1) - players.Append("

No Players

"); - else - { - int count = 0; - double currentPlayers = Servers[i].statusPlayers.Count; - - foreach (Player P in Servers[i].getPlayers()) - { - if (P == null) - continue; - - if (count % 2 == 0) - { - switch (cycleFix) - { - case 0: - players.Append(""); - cycleFix = 1; - break; - case 1: - players.Append(""); - cycleFix = 0; - break; - } - } - - players.AppendFormat("{2}", i, P.databaseID, SharedLibrary.Utilities.nameHTMLFormatted(P)); - - if (count % 2 != 0) - { - players.Append(""); - } - - count++; - - } - } - buffer.AppendFormat(@" - - - - - - - - - -
{0}{1}{2}{3}StatsBansHistory
- - {5} -
", - Servers[i].getName(), Servers[i].getMap(), Servers[i].getClientNum() + "/" + Servers[i].getMaxClients(), SharedLibrary.Utilities.gametypeLocalized(Servers[i].getGametype()), i, players.ToString()); - buffer.AppendFormat("
", i, '\"'); - if (Servers[i].getClientNum() > 0) - buffer.AppendFormat("
", i, '\"'); - buffer.Append("
"); - } - return buffer.ToString(); - case "TITLE": - return "IW4M Administration"; - case "BANS": - buffer.Append(""); - int totalBans = Program.getServers()[0].Bans.Count; - int range; - int start = Pagination*30; - cycleFix = 0; - - if (totalBans <= 30) - range = totalBans - 1; - else if ((totalBans - start) < 30) - range = (totalBans - start); - else - range = 30; - - List Bans = new List(); - - if (totalBans > 0) - Bans = Program.getServers()[0].Bans.GetRange(start, range).OrderByDescending(x => x.When).ToList(); - else - Bans.Add(new Ban("No Bans", "0", "0", DateTime.Now, "")); - - - buffer.Append("

{{TIME}}


"); - - if (Bans[0] != null) - buffer = buffer.Replace("{{TIME}}", "From " + SharedLibrary.Utilities.timePassed(Bans[0].When) + " ago" + " — " + totalBans + " total"); - - for (int i = 0; i < Bans.Count; i++) - { - if (Bans[i] == null) - continue; - - Player P = Program.getServers()[0].clientDB.getPlayer(Bans[i].npID, -1); - Player B = Program.getServers()[0].clientDB.getPlayer(Bans[i].bannedByID, -1); - - if (P == null) - P = new Player("Unknown", "n/a", 0, 0, 0, "Unknown", 0, ""); - if (B == null) - B = new Player("Unknown", "n/a", 0, 0, 0, "Unknown", 0, ""); - - if (P.lastOffense == String.Empty) - P.lastOffense = "Evade"; - - if (P != null && B != null) - { - if (B.npID == P.npID) - B.updateName("IW4MAdmin"); // shh it will all be over soon - - String Prefix; - if (cycleFix % 2 == 0) - Prefix = "class=row-grey"; - else - Prefix = "class=row-white"; - String Link = "/" + server + "/" + P.databaseID + "/userip/?player"; - buffer.AppendFormat("", P.Name, P.lastOffense, SharedLibrary.Utilities.nameHTMLFormatted(B), Bans[i].getWhen(), Prefix, Link); - cycleFix++; - } - } - buffer.Append("
NameOffenseBanned ByTime
{0}{1}{2}{3}

"); - - buffer.Append(parsePagination(server, Servers[0].Bans.Count, 30, Pagination, "bans")); - return buffer.ToString(); - case "PAGE": - buffer.Append("
"); - return buffer.ToString(); - case "STATS": - int totalStats = 0; - buffer.Append("

Starting at #{{TOP}}


"); - buffer.Append(""); - - start = Pagination*30; - if (totalStats <= 30) - range = totalStats - 1; - else if ((totalStats - start) < 30 ) - range = (totalStats - start); - else - range = 30; - //List Stats = Servers[server].statDB.getMultipleStats(start, range).OrderByDescending(x => x.Skill).ToList(); - buffer.Append(""); - cycleFix = 0; - /*for (int i = 0; i < totalStats; i++) - { - if (i >= Stats.Count -1 || Stats[i] == null ) - continue; - - Player P = Servers[server].clientDB.getPlayer(Stats[i].statIndex); - - if (P == null) - continue; - - P.stats = Stats[i]; - - - if (P.stats != null) - { - String Prefix; - if (cycleFix % 2 == 0) - Prefix = "class=row-grey"; - else - Prefix = "class=row-white"; - - String Link = "/" + server + "/" + P.databaseID + "/userip/?player"; - buffer.AppendFormat("", P.Name, P.stats.Kills, P.stats.Deaths, P.stats.KDR, P.stats.Skill, Prefix, Link); - cycleFix++; - } - }*/ - buffer.Append("
NameKillsDeathsKDRRating
{0}{1}{2}{3}{4}

"); - buffer.Append(parsePagination(server, totalStats, 30, Pagination, "stats")); - return buffer.ToString().Replace("{{TOP}}", (start + 1).ToString()); - case "PLAYER": - buffer.Append(""); - List matchingPlayers = new List(); - - if (Data == null) - matchingPlayers.Add(Servers[server].clientDB.getPlayer(Pagination)); - else - { - var alias = Servers[server].aliasDB.findPlayers(Data); - - foreach (var a in alias) - { - var p = Servers[server].clientDB.getPlayer(a.getNumber()); - if (p != null) - { - List aliases = new List(); - Servers[server].getAliases(aliases, p); - - foreach (var pa in aliases) - { - if (!matchingPlayers.Exists(x => x.databaseID == pa.databaseID)) - matchingPlayers.Add(pa); - } - } - } - } - - if (matchingPlayers == null) - buffer.Append("
NameAliasesIPRatingLevelConnectionsLast SeenProfile
"); - - else - { - foreach (Player Player in matchingPlayers) - { - if (Player == null) - continue; - - buffer.Append(""); - StringBuilder str = new StringBuilder(); - List aliases = new List(); - Servers[server].getAliases(aliases, Player); - - foreach (Player a in aliases) - { - if (Data != null) - { - if (a.Alias.getNames().Exists(p => p.ToLower().Contains(Data.ToLower())) && a.databaseID != Player.databaseID) - { - str.AppendFormat("{0}
", a.Name); - break; - } - } - else - str.AppendFormat("{0}
", a.Name); - } - - StringBuilder IPs = new StringBuilder(); - - if (logged) - { - foreach (Player a in aliases) - { - foreach (String ip in a.Alias.getIPS()) - { - if (!IPs.ToString().Contains(ip)) - IPs.AppendFormat("{0}
", ip); - } - } - - } - else - IPs.Append("XXX.XXX.XXX.XXX"); - - Int64 forumID = 0; - if (Player.npID.Length == 16) - { - forumID = Int64.Parse(Player.npID.Substring(0, 16), NumberStyles.AllowHexSpecifier); - forumID = forumID - 76561197960265728; - } - - String Screenshot = String.Empty; - - if (logged) - Screenshot = String.Format("
", forumID, Player.Name); - - buffer.AppendFormat("{0}{10}{1}{2}{3}{4}{5}{6} ago{8}", Player.Name, str, IPs, 0, SharedLibrary.Utilities.nameHTMLFormatted(Player), Player.Connections, Player.getLastConnection(), forumID, Player.Name, "/0/" + Player.databaseID + "/userip/?player", Screenshot); - buffer.Append(""); - } - - buffer.Append(""); - } - - return buffer.ToString(); - default: - return input; - } - } - - static public String findMacros(String input, Client C, int server) - { - String output = input; - - bool logged = Program.getServers()[server].clientDB.getAdmins().Exists(player => player.IP == C.requestOrigin["Host"].Split(':')[0]); - - switch (C.requestedPage) - { - case WebFront.Page.main: - output = output.Replace("{{SERVERS}}", parseMacros("SERVERS", C.requestedPage, server, C.requestedPageNumber, logged, C.requestData)); - break; - case WebFront.Page.bans: - output = output.Replace("{{BANS}}", parseMacros("BANS", C.requestedPage, server, C.requestedPageNumber, logged, C.requestData)); - break; - case WebFront.Page.stats: - output = output.Replace("{{STATS}}", parseMacros("STATS", C.requestedPage, server, C.requestedPageNumber, logged, C.requestData)); - break; - case WebFront.Page.player: - output = output.Replace("{{PLAYER}}", parseMacros("PLAYER", C.requestedPage, server, C.requestedPageNumber, (C.playerRequesting.Level > Player.Permission.Flagged), C.requestData)); - break; - } - - output = output.Replace("{{TITLE}}", "IW4M Administration"); - output = output.Replace("{{VERSION}}", Program.Version.ToString()); - - return output; - } - } - - class SchedulerDelegate : ISchedulerDelegate - { - public void OnException(IScheduler scheduler, Exception e) - { - //Program.getManager().mainLog.Write(e.InnerException.Message); - //Console.Write(e.InnerException); - // e.DebugStackTrace(); - Program.getManager().mainLog.Write("Web front encountered an error!"); - } - - public void OnStop(IScheduler scheduler) - { - - } - } - - class RequestDelegate : IHttpRequestDelegate - { - public void OnRequest(HttpRequestHead request, IDataProducer requestBody, IHttpResponseDelegate response) - { - String type = "text/html"; - if (request.Uri.StartsWith("/")) - { - //Program.getManager().mainLog.Write("[WEBFRONT] Processing Request for " + request.Uri); - var body = String.Empty; - - if (request.Uri.StartsWith("/")) - { - IFile Header = new IFile("webfront\\header.html"); - var header = Header.getLines(); - Header.Close(); - - IFile Footer = new IFile("webfront\\footer.html"); - var footer = Footer.getLines(); - Footer.Close(); - - String[] req = request.Path.Split(new char[] {'/'}, StringSplitOptions.RemoveEmptyEntries); - - int server = 0; - int page = 0; - - if (req.Length > 1) - { - Int32.TryParse(req[0], out server); - Int32.TryParse(req[1], out page); - } - - if (Program.getServers().Length < 1) - { - body = "

IT SEEMS LIKE THERE ARE NO LONGER ANY SERVERS BEING MONITORED!

"; - } - - else if (request.QueryString == "bans") - { - IFile Bans = new IFile("webfront\\bans.html"); - var bans = Bans.getLines(); - Bans.Close(); - Client toSend = new Client(WebFront.Page.bans, page, request.Headers, null, null); - body = Macro.findMacros((header + bans + footer), toSend, server); - } - - else if (request.QueryString == "stats") - { - IFile Stats = new IFile("webfront\\stats.html"); - var stats = Stats.getLines(); - Stats.Close(); - Client toSend = new Client(WebFront.Page.stats, page, request.Headers, null, null); - body = Macro.findMacros(header + stats + footer, toSend, server); - } - - else if (request.QueryString == "playerhistory") - { - //type = "text/plain"; - if (Program.getServers().Length < server) - return; - - StringBuilder test = new StringBuilder(); - test.Append("
"); - test.Append(""); - IFile Graph = new IFile("webfront\\graph.html"); - var graph = Graph.getLines(); - Graph.Close(); - body = test.ToString() + graph ; - } - - else if (request.QueryString == "player") - { - IFile Player = new IFile("webfront\\player.html"); - var player = Player.getLines(); - Player.Close(); - String Data = null, IP = null, ID = null; - if (req.Length > 3) - { - ID = req[1]; - IP = req[2]; - Data = req[3]; - } - - else if (req.Length >2) - { - ID = req[1]; - IP = req[2]; - } - - if (Program.getServers().Length < server) - return; - - Player P = Program.getServers()[server].clientDB.getPlayer(IP); - if (P == null) - P = new Player("Guest", "Guest", 0, 0); - - Client toSend = new Client(WebFront.Page.player, page, request.Headers, Data, P); - body = Macro.findMacros(header + player + footer, toSend, server); - } - - else if (request.QueryString == "chat") - { - StringBuilder chatMessages = new StringBuilder(); -#if DEBUG - // if (Program.Servers[server].chatHistory.Count < 8) - // Program.Servers[server].chatHistory.Add(new Chat(new Player("TEST", "xuid", 0, 0), "TEST MESSAGE", DateTime.Now)); -#endif - if (Program.getServers().Length < server) - return; - - String IP, Text; - if (req.Length > 3) - { - IP = req[2]; - Text = SharedLibrary.Utilities.cleanChars(HttpUtility.UrlDecode(req[3])); - } - - else - { - IP = null; - Text = null; - } - - if (IP == null && Program.getServers()[server].getClientNum() > 0) - { - chatMessages.Append(""); - foreach (Chat Message in Program.getServers()[server].chatHistory) - chatMessages.AppendFormat("", SharedLibrary.Utilities.nameHTMLFormatted(Message.Origin), Message.Message, Message.timeString()); - chatMessages.Append("
{0}{1}{2}
"); - body = chatMessages.ToString(); - } - - else if (Text != null && Text.Length > 4) - { - Player requestPlayer = Program.getServers()[server].clientDB.getPlayer(IP); - - if (requestPlayer != null) - Program.getServers()[server].webChat(requestPlayer, Text); - } - } - - else if (request.QueryString == "pubbans") - { - type = "text/plain"; - StringBuilder banTXT = new StringBuilder(); - banTXT.AppendFormat("===========================================\nIW4M ADMIN PUBLIC BAN LIST\nGENERATED {0}\nIP---GUID---REASON---TIME\n===========================================\n", DateTime.Now.ToString()); - foreach (Ban B in Program.getServers()[0].Bans) - { - if (B.IP != null && B.IP != String.Empty && B.Reason != null && B.Reason != String.Empty) - banTXT.AppendFormat("{0}---{1}---{2}---{3}\n", B.IP, B.npID, B.Reason.Trim(), Math.Round((B.When-DateTime.MinValue).TotalSeconds, 0)); - } - body = banTXT.ToString(); - } - - else - { - IFile Main = new IFile("webfront\\main.html"); - var main = Main.getLines(); - Main.Close(); - Client toSend = new Client(WebFront.Page.main, page, request.Headers, null, null); - body = Macro.findMacros(header + main + footer, toSend, server); - } - - //Program.getServers()[server].Log.Write("Webfront processed request for " + request.Uri, Log.Level.Debug); - } - - var headers = new HttpResponseHead() - { - Status = "200 OK", - Headers = new Dictionary() - { - { "Content-Type", type }, - { "Content-Length", body.Length.ToString() }, - } - }; - - response.OnResponse(headers, new BufferedProducer(body)); - } - - else - { - var responseBody = "The resource you requested ('" + request.Uri + "') could not be found."; - var headers = new HttpResponseHead() - { - Status = "404 Not Found", - Headers = new Dictionary() - { - { "Content-Type", type }, - { "Content-Length", responseBody.Length.ToString() } - } - }; - var body = new BufferedProducer(responseBody); - - response.OnResponse(headers, body); - } - } - - class BufferedProducer : IDataProducer - { - ArraySegment data; - - public BufferedProducer(string data) : this(data, Encoding.UTF8) { } - public BufferedProducer(string data, Encoding encoding) : this(encoding.GetBytes(data)) { } - public BufferedProducer(byte[] data) : this(new ArraySegment(data)) { } - public BufferedProducer(ArraySegment data) - { - this.data = data; - } - - public IDisposable Connect(IDataConsumer channel) - { - // null continuation, consumer must swallow the data immediately. - channel.OnData(data, null); - channel.OnEnd(); - return null; - } - } - - class BufferedConsumer : IDataConsumer - { - List> buffer = new List>(); - Action resultCallback; - Action errorCallback; - - public BufferedConsumer(Action resultCallback, Action errorCallback) - { - this.resultCallback = resultCallback; - this.errorCallback = errorCallback; - } - public bool OnData(ArraySegment data, Action continuation) - { - // since we're just buffering, ignore the continuation. - buffer.Add(data); - return false; - } - public void OnError(Exception error) - { - errorCallback(error); - } - - public void OnEnd() - { - // turn the buffer into a string. - var str = buffer - .Select(b => Encoding.UTF8.GetString(b.Array, b.Offset, b.Count)) - .Aggregate((result, next) => result + next); - - resultCallback(str); - } - } - } - } -#endif \ No newline at end of file diff --git a/Admin/lib/SharedLibary.dll b/Admin/lib/SharedLibary.dll index 5c8a3a2090262f0c50d37f2f70cf416a6e062aa0..e2fd68cffc2f1d8f0b3f043b500da62c72fccfbb 100644 GIT binary patch literal 37888 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%0Dx{DrlIe+c8K-?D14m{TRee~~j*)le;+hS; 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 dkj9|MK&I`n~^FoHqZz&;NZI_}>R;KR^Hg literal 35840 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

    %uI5bqw-{eqM;1F%+`%4>1;$vLxB777elPF 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 delta 2006 zcmZ9Ne{54#6vw~!-P<3$ZQZ)DZrzG>D{OBYEX+*_!V>uv0jCa^NtUUw$O3b?LN^gI zS&RIR1Dr2lP>dxJaY_iLV4}gFF^dU_@`nl`fB^%d7%+;&A0+yHw^bZ%-shh4J?EZ# z?|FTFi5ZC*FKm@tn!Xu&ew?^EG`vV8Z6PXM%jd;E4w4&pgtA z3zs86A{P+$`ogJpv+?Gv(>elw>?E*K_6GoS@D3(eMYOD9A}t2%m&^Wqx~3%ow>z3e zX1Qg5&<@K*qQqV!7sP*Kjb1MUmLjU}Fsu^Js4h38Rq7Z8Qw)T-AS?Kdep;qAj+pF= zc?4FPhTG!OW(D&kx|qi*{@(GFOm}RJ!Tm+UbfRU1JN6ufz#tb88DU5Kc4hDF!t0|2 zBX*dA+bY+qa>0TrE(~&XapBl8#?mWVY@6w9Zvw|G&!i4dbRw;21rexgNqd3ltV;UX zUcIxZMcb+(ys;fD^nc&kR@$%Dac5T<-&U@P@yv;x1Lhk22KzATm}!|k93?wNna!4| zVylLA2ifv}TjQ+2AdjVP$(hr~OgZYDmY8G@yY6pHvQ%UM$mXmDUXhl*SXa-oUbYAK zn!p6^Akx}`r8z(zwa9&~^XG8vqn~Zpxho5KdZ&~6qKIr>lkKP6)8p&V4imev6K=dg z+YP^PlmW3+m>3o>ksoWG)x4=$XgGSU=6ubintP3PhKa+PA8O^Krbk{kT2RV;nphyK zrHLoWQf!TD>1DZ-fqj|>G!JQh!lWXc(K%POQlj#diG}KJ<->rAk-IbxYkp0dxTKtF ze{1?(&W0*Uo*2Rb>3s80ib~i?&z7TSW5qBOlgw zEj>mWSWHTEkc#>=Bw=Bu=6ubCnr)gLnq8W!G}mgbC!4WN+e4arH20CMc!zAqd!)&& zCgWIwD%i3c=W$d(>+0d)~&;<$=mK~S7k*HA^?K%Ka%{vvNE zh-pH(azzlPt5D1oNtBB+yo~|Wq8_V6Ev91|xdA_t1zIV^2HFwL8qF5XELN|@Y;AYr zIPHF%C)=^FfkQ7&i6y#pLUT1<#9R0RE+Kgjo!c4Vt&#i+-WG{N_S5FHz-A{x|JFw! zrtA^(8Q0v^ojrZ2#;jGcXm+&ciH<&S=#8%E#G+VNUuRQSPwJrWE@6M0dnz=p6RXjQ z9`qs1Yb{pN3-f=!7va>=ygDPVrg7e-JzrjEdTnZLQ^%2#vm#kUK2$6We^QF!B@IWf)#9?DDFx2>DpR>r~0%H0fhr zeqtA=<>Yv?!_x3&3i&ui_!Il>z}QQ*;5)a~Ikdqm#QtpL8+T(N@NmnVmV!qsQm_2- z!OV{?k1b#K(6hs1QdNZ>k@I=x1?)^aXEz2)#fel~V6I5{ivN_x&kZSm=$aUs;`s;d C^IO#b diff --git a/Admin/plugins/Webfront Plugin.dll b/Admin/plugins/Webfront Plugin.dll new file mode 100644 index 0000000000000000000000000000000000000000..448aa95fb889b9d07f4d430b5096e7f2ffe777cb GIT binary patch literal 24576 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 literal 0 HcmV?d00001 diff --git a/Admin/webfront/bans.html b/Admin/webfront/bans.html index 42c12395a..c5701ceb2 100644 --- a/Admin/webfront/bans.html +++ b/Admin/webfront/bans.html @@ -1,5 +1,5 @@ 
    -
    BANS
    Back
    -
    - {{BANS}} +
    BANS
    Back
    +
    + {{BANS}}
    \ No newline at end of file diff --git a/Admin/webfront/error.html b/Admin/webfront/error.html new file mode 100644 index 000000000..06af03051 --- /dev/null +++ b/Admin/webfront/error.html @@ -0,0 +1,11 @@ +
    +
    ERROR!
    Back
    +
    +
    +
    +
    +
    + Uh Oh, it looks like there was an error processing your request.
    + Reason: {{ERROR}} +
    +
    diff --git a/Admin/webfront/header.html b/Admin/webfront/header.html index 182f5853f..81dac35b7 100644 --- a/Admin/webfront/header.html +++ b/Admin/webfront/header.html @@ -394,7 +394,7 @@ \ No newline at end of file +
diff --git a/IW4M Admin.sln b/IW4M Admin.sln index 214a3f6e7..58fcd2a2a 100644 --- a/IW4M Admin.sln +++ b/IW4M Admin.sln @@ -6,6 +6,7 @@ MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IW4M ADMIN", "Admin\IW4M ADMIN.csproj", "{DD5DCDA2-51DB-4B1A-922F-5705546E6115}" ProjectSection(ProjectDependencies) = postProject {4785AB75-66F3-4391-985D-63A5A049A0FA} = {4785AB75-66F3-4391-985D-63A5A049A0FA} + {99E36EBD-1FA1-494C-8A66-BECE64EFF378} = {99E36EBD-1FA1-494C-8A66-BECE64EFF378} {D51EECEB-438A-47DA-870F-7D7B41BC24D6} = {D51EECEB-438A-47DA-870F-7D7B41BC24D6} EndProjectSection EndProject @@ -16,6 +17,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SamplePlugin", "SamplePlugi {D51EECEB-438A-47DA-870F-7D7B41BC24D6} = {D51EECEB-438A-47DA-870F-7D7B41BC24D6} EndProjectSection EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Webfront Plugin", "Webfront Plugin\Webfront Plugin.csproj", "{99E36EBD-1FA1-494C-8A66-BECE64EFF378}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -34,6 +37,10 @@ Global {4785AB75-66F3-4391-985D-63A5A049A0FA}.Debug|Any CPU.Build.0 = Debug|Any CPU {4785AB75-66F3-4391-985D-63A5A049A0FA}.Release|Any CPU.ActiveCfg = Release|Any CPU {4785AB75-66F3-4391-985D-63A5A049A0FA}.Release|Any CPU.Build.0 = Release|Any CPU + {99E36EBD-1FA1-494C-8A66-BECE64EFF378}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {99E36EBD-1FA1-494C-8A66-BECE64EFF378}.Debug|Any CPU.Build.0 = Debug|Any CPU + {99E36EBD-1FA1-494C-8A66-BECE64EFF378}.Release|Any CPU.ActiveCfg = Release|Any CPU + {99E36EBD-1FA1-494C-8A66-BECE64EFF378}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Release Build/lib/SharedLibary.dll b/Release Build/lib/SharedLibary.dll index 5c8a3a2090262f0c50d37f2f70cf416a6e062aa0..e2fd68cffc2f1d8f0b3f043b500da62c72fccfbb 100644 GIT binary patch literal 37888 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%0Dx{DrlIe+c8K-?D14m{TRee~~j*)le;+hS; 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 dkj9|MK&I`n~^FoHqZz&;NZI_}>R;KR^Hg literal 35840 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

    %uI5bqw-{eqM;1F%+`%4>1;$vLxB777elPF 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 0) { DataRow ResponseRow = Result.Rows[0]; - DateTime LC; + DateTime lastCon = DateTime.MinValue; + DateTime.TryParse(ResponseRow["LastConnection"].ToString(), out lastCon); - try - { - LC = DateTime.Parse(ResponseRow["LastConnection"].ToString()); - } - catch (Exception) - { - LC = DateTime.Now; - } - - 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(), LC); + 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); } else return null; } + public List getPlayers(List npIDs) + { + List returnssss = new List(); + String test = String.Join("' OR npID = '", npIDs); + + String Query = String.Format("SELECT * FROM CLIENTS WHERE npID = '{0}'", test); + DataTable Result = GetDataTable(Query); + + if (Result != null && Result.Rows.Count > 0) + { + foreach (DataRow ResponseRow in Result.Rows) + { + DateTime lastCon = DateTime.MinValue; + DateTime.TryParse(ResponseRow["LastConnection"].ToString(), out lastCon); + + returnssss.Add(new Player(ResponseRow["Name"].ToString(), ResponseRow["npID"].ToString(), -1, (Player.Permission)(ResponseRow["Level"]), Convert.ToInt32(ResponseRow["Number"]), ResponseRow["LastOffense"].ToString(), (int)ResponseRow["Connections"], ResponseRow["IP"].ToString(), lastCon)); + } + } + + return returnssss; + } + + public List getPlayers(List databaseIDs) + { + List returnssss = new List(); + String test = String.Join("' OR Number = '", databaseIDs); + + String Query = String.Format("SELECT * FROM CLIENTS WHERE Number = '{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)); + } + } + + return returnssss; + } + //Overloaded method for getPlayer, returns Client with matching DBIndex, null if none found public Player getPlayer(int dbIndex) { @@ -204,7 +241,7 @@ namespace SharedLibrary } catch (Exception) { - LC = DateTime.Now; + 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); @@ -217,7 +254,7 @@ namespace SharedLibrary //get player by ip, (used for webfront) public Player getPlayer(String IP) { - String Query = String.Format("SELECT * FROM CLIENTS WHERE IP='{0}'", IP); + String Query = String.Format("SELECT * FROM CLIENTS WHERE IP = '{0}'", IP); DataTable Result = GetDataTable(Query); if (Result != null && Result.Rows.Count > 0) @@ -255,7 +292,7 @@ namespace SharedLibrary //Returns a list of players matching name parameter, null if no players found matching public List findPlayers(String name) { - String Query = String.Format("SELECT * FROM CLIENTS WHERE Name LIKE '%{0}%' LIMIT 8", name); + String Query = String.Format("SELECT * FROM CLIENTS WHERE Name LIKE '%{0}%' LIMIT 32", name); DataTable Result = GetDataTable(Query); List Players = new List(); @@ -271,7 +308,7 @@ namespace SharedLibrary } catch (Exception) { - LC = DateTime.Now; + 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)); @@ -403,144 +440,6 @@ namespace SharedLibrary } } - /*public class StatsDB : Database - { - public StatsDB(String FN) : base(FN) { } - - public override void Init() - { - if (!File.Exists(FileName)) - { - String Create = "CREATE TABLE [STATS] ( [Number] INTEGER, [KILLS] INTEGER DEFAULT 0, [DEATHS] INTEGER DEFAULT 0, [KDR] REAL DEFAULT 0, [SKILL] REAL DEFAULT 0, [MEAN] REAL DEFAULT 0, [DEV] REAL DEFAULT 0 );"; - ExecuteNonQuery(Create); - } - } - - // Return stats for player specified by Database ID, null if no matches - public Stats getStats(int DBID) - { - String Query = String.Format("SELECT * FROM STATS WHERE Number = '{0}'", DBID); - DataTable Result = GetDataTable(Query); - - if (Result != null && Result.Rows.Count > 0) - { - DataRow ResponseRow = Result.Rows[0]; - if (ResponseRow["MEAN"] == DBNull.Value) - ResponseRow["MEAN"] = 0; // Moserware.Skills.GameInfo.DefaultGameInfo.DefaultRating.Mean; - if (ResponseRow["DEV"] == DBNull.Value) - ResponseRow["DEV"] = 0; // Moserware.Skills.GameInfo.DefaultGameInfo.DefaultRating.StandardDeviation; - if (ResponseRow["SKILL"] == DBNull.Value) - ResponseRow["SKILL"] = 0; - - return new Stats(Convert.ToInt32(ResponseRow["Number"]), Convert.ToInt32(ResponseRow["KILLS"]), Convert.ToInt32(ResponseRow["DEATHS"]), Convert.ToDouble(ResponseRow["KDR"]), Convert.ToDouble(ResponseRow["SKILL"]), Convert.ToDouble(ResponseRow["MEAN"]), Convert.ToDouble(ResponseRow["DEV"])); - } - - else - return null; - } - - public void addPlayer(Player P) - { - Dictionary newPlayer = new Dictionary(); - - newPlayer.Add("Number", P.databaseID); - newPlayer.Add("KILLS", 0); - newPlayer.Add("DEATHS", 0); - newPlayer.Add("KDR", 0); - newPlayer.Add("SKILL", 0); //Moserware.Skills.GameInfo.DefaultGameInfo.DefaultRating.ConservativeRating); - newPlayer.Add("MEAN", 0); //Moserware.Skills.GameInfo.DefaultGameInfo.DefaultRating.Mean); - newPlayer.Add("DEV", 0); //Moserware.Skills.GameInfo.DefaultGameInfo.DefaultRating.StandardDeviation); - - Insert("STATS", newPlayer); - } - - //Update stat information of specified player - public void updatePlayer(Player P) - { - if (P.stats == null) - return; - - Dictionary updatedPlayer = new Dictionary(); - - updatedPlayer.Add("KILLS", P.stats.Kills); - updatedPlayer.Add("DEATHS", P.stats.Deaths); - updatedPlayer.Add("KDR", Math.Round(P.stats.KDR, 2)); - updatedPlayer.Add("SKILL", P.stats.Skill); - //updatedPlayer.Add("MEAN", P.stats.Rating.Mean); - //updatedPlayer.Add("DEV", P.stats.Rating.StandardDeviation); - - Update("STATS", updatedPlayer, String.Format("Number = '{0}'", P.databaseID)); - } - - //Returns top 5 players (we filter through them later) - public List topStats() - { - String Query = String.Format("SELECT * FROM STATS WHERE KILLS > '{0}' AND KDR < '{1}' AND SKILL > '{2}' ORDER BY SKILL DESC LIMIT 5", 250, 7, 245); - DataTable Result = GetDataTable(Query); - - List Top = new List(); - - if (Result != null && Result.Rows.Count > 0) - { - foreach (DataRow D in Result.Rows) - { - if (D["MEAN"] == DBNull.Value || D["DEV"] == DBNull.Value || D["SKILL"] == DBNull.Value) - continue; - - Stats S = new Stats(Convert.ToInt32(D["Number"]), Convert.ToInt32(D["KILLS"]), Convert.ToInt32(D["DEATHS"]), Convert.ToDouble(D["KDR"]), Convert.ToDouble(D["SKILL"]), Convert.ToDouble(D["MEAN"]), Convert.ToDouble(D["DEV"])); - Top.Add(S); - } - } - - return Top; - } - - public List getMultipleStats(int start, int length) - { - String Query = String.Format("SELECT * FROM STATS ORDER BY SKILL DESC LIMIT '{0}' OFFSET '{1}'", length, start); - DataTable Result = GetDataTable(Query); - - List Stats = new List(); - - if (Result != null && Result.Rows.Count > 0) - { - foreach (DataRow D in Result.Rows) - { - if (D["MEAN"] == DBNull.Value) - continue; - if (D["DEV"] == DBNull.Value) - continue; - - if (D["SKILL"] == DBNull.Value) - D["SKILL"] = 0; - - Stats S = new Stats(Convert.ToInt32(D["Number"]), Convert.ToInt32(D["KILLS"]), Convert.ToInt32(D["DEATHS"]), Convert.ToDouble(D["KDR"]), Convert.ToDouble(D["SKILL"]), Convert.ToDouble(D["MEAN"]), Convert.ToDouble(D["DEV"])); - Stats.Add(S); - } - } - - return Stats; - } - - public int totalStats() - { - DataTable Result = GetDataTable("SELECT * FROM STATS"); - return Result.Rows.Count; - } - - public void clearSkill() - { - String Query = "SELECT * FROM STATS"; - DataTable Result = GetDataTable(Query); - - if (Result != null && Result.Rows.Count > 0) - { - foreach (DataRow D in Result.Rows) - Update("STATS", new Dictionary() { { "SKILL", 1 } }, String.Format("Number = '{0}'", D["Number"])); - } - } - }*/ - public class AliasesDB : Database { public AliasesDB(String FN) : base(FN) { } @@ -609,9 +508,9 @@ namespace SharedLibrary { Dictionary newPlayer = new Dictionary(); - newPlayer.Add("Number", Alias.getNumber()); - newPlayer.Add("NAMES", Alias.getNamesDB()); - newPlayer.Add("IPS", Alias.getIPSDB()); + newPlayer.Add("Number", Alias.Number); + newPlayer.Add("NAMES", String.Join(";", Alias.Names)); + newPlayer.Add("IPS", String.Join(";", Alias.IPS)); Insert("ALIASES", newPlayer); } @@ -620,11 +519,11 @@ namespace SharedLibrary { Dictionary updatedPlayer = new Dictionary(); - updatedPlayer.Add("Number", Alias.getNumber()); - updatedPlayer.Add("NAMES", Alias.getNamesDB()); - updatedPlayer.Add("IPS", Alias.getIPSDB()); + updatedPlayer.Add("Number", Alias.Number); + updatedPlayer.Add("NAMES", String.Join(";", Alias.Names)); + updatedPlayer.Add("IPS", String.Join(";", Alias.IPS)); - Update("ALIASES", updatedPlayer, String.Format("Number = '{0}'", Alias.getNumber())); + Update("ALIASES", updatedPlayer, String.Format("Number = '{0}'", Alias.Number)); } } } diff --git a/SharedLibary/Event.cs b/SharedLibary/Event.cs index 158f1bd28..3e8ce6f50 100644 --- a/SharedLibary/Event.cs +++ b/SharedLibary/Event.cs @@ -29,6 +29,8 @@ namespace SharedLibrary public enum GType { //FROM SERVER + Start, + Stop, Connect, Disconnect, Say, @@ -126,10 +128,4 @@ namespace SharedLibrary public Player Target; public Server Owner; } - - public abstract class EventNotify - { - public abstract void onEvent(Event E); - public abstract void onLoad(); - } } diff --git a/SharedLibary/Player.cs b/SharedLibary/Player.cs index 2b9ac82fc..98087df71 100644 --- a/SharedLibary/Player.cs +++ b/SharedLibary/Player.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Text; +using System.Linq; namespace SharedLibrary { @@ -9,50 +10,13 @@ namespace SharedLibrary public Aliases(int Num, String N, String I) { Number = Num; - Names = N; - IPS = I; + Names = N.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries).Select(s => s.Trim()).ToList(); + IPS = new List(I.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries)); } - public List getNames() - { - return new List(Names.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries)); - } - - public List getIPS() - { - return new List(IPS.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries)); - } - - public String getIPSDB() - { - return IPS; - } - - public String getNamesDB() - { - return Names; - } - - public int getNumber() - { - return Number; - } - - public void addName(String Name) - { - if (Name.Trim() != String.Empty && Name != null) - Names += ';' + Name; - } - - public void addIP(String IP) - { - if (IP.Trim() != String.Empty && IP != null) - IPS += ';' + IP; - } - - private String Names; - private String IPS; - private int Number; + public List Names { get; private set; } + public List IPS { get; private set; } + public int Number { get; private set; } } public class Player @@ -80,7 +44,6 @@ namespace SharedLibrary IP = ""; Warnings = 0; Alias = new Aliases(0, "", ""); - //stats = new Stats(0, 0, 0, 0, Moserware.Skills.GameInfo.DefaultGameInfo.DefaultRating.ConservativeRating, Moserware.Skills.GameInfo.DefaultGameInfo.DefaultRating.Mean, Moserware.Skills.GameInfo.DefaultGameInfo.DefaultRating.StandardDeviation); LastConnection = DateTime.Now; } diff --git a/SharedLibary/Plugin.cs b/SharedLibary/Plugin.cs new file mode 100644 index 000000000..cb4a3ca67 --- /dev/null +++ b/SharedLibary/Plugin.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace SharedLibrary +{ + public abstract class Plugin + { + public abstract void onLoad(); + } + + public abstract class Notify : Plugin + { + public abstract void onEvent(Event E); + } +} diff --git a/SharedLibary/Server.cs b/SharedLibary/Server.cs index 2ac49b1b5..30c4c8803 100644 --- a/SharedLibary/Server.cs +++ b/SharedLibary/Server.cs @@ -23,6 +23,7 @@ namespace SharedLibrary clientDB = new ClientsDB("clients.rm"); aliasDB = new AliasesDB("aliases.rm"); + Bans = new List(); players = new List(new Player[18]); events = new Queue(); Macros = new Dictionary(); @@ -108,9 +109,18 @@ namespace SharedLibrary /// /// Get any know aliases ( name or ip based ) from the database /// - /// List of aliases matching given player /// Player to scan for aliases - abstract public void getAliases(List returnPlayers, Player Origin); + abstract public List getAliases(Player Origin); + + public List getPlayerAliases(Player Origin) + { + List databaseIDs = new List(); + + foreach (Aliases A in getAliases(Origin)) + databaseIDs.Add(A.Number); + + return clientDB.getPlayers(databaseIDs); + } /// /// Add a player to the server's player list diff --git a/SharedLibary/SharedLibrary.csproj b/SharedLibary/SharedLibrary.csproj index ffe265930..909f93254 100644 --- a/SharedLibary/SharedLibrary.csproj +++ b/SharedLibary/SharedLibrary.csproj @@ -56,6 +56,7 @@ + diff --git a/SharedLibary/Utilities.cs b/SharedLibary/Utilities.cs index e9739b458..a4ce52603 100644 --- a/SharedLibary/Utilities.cs +++ b/SharedLibary/Utilities.cs @@ -114,6 +114,31 @@ namespace SharedLibrary } } + public static String levelHTMLFormatted(Player.Permission Level) + { + switch (Level) + { + case Player.Permission.User: + return "" + Level + ""; + case Player.Permission.Moderator: + return "" + Level + ""; + case Player.Permission.Administrator: + return "" + Level + ""; + case Player.Permission.SeniorAdmin: + return "" + Level + ""; + case Player.Permission.Owner: + return "" + Level + ""; + case Player.Permission.Creator: + return "" + Level + ""; + case Player.Permission.Banned: + return "" + Level + ""; + case Player.Permission.Flagged: + return "" + Level + ""; + default: + return "" + Level + ""; + } + } + public static String nameHTMLFormatted(Player P) { switch (P.Level) diff --git a/Webfront Plugin/Properties/AssemblyInfo.cs b/Webfront Plugin/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..13bcddb9d --- /dev/null +++ b/Webfront Plugin/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Webfront Plugin")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Webfront Plugin")] +[assembly: AssemblyCopyright("Copyright © 2015")] +[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("03a62b7b-361a-4232-8db7-4e00b9e7a31a")] + +// 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")]