IW4M-Admin/Webfront Plugin/Framework.cs

621 lines
23 KiB
C#
Raw Normal View History

using System;
using System.Collections.Generic;
using SharedLibrary;
using System.Text;
using System.Text.RegularExpressions;
using System.Linq;
using System.Collections.Specialized;
namespace Webfront_Plugin
{
class Framework
{
private List<Server> activeServers;
public Framework()
{
activeServers = new List<Server>();
}
public void addServer(Server S)
{
activeServers.Add(S);
}
public void removeServer(Server S)
{
if (S != null && activeServers.Contains(S))
{
S.Stop();
activeServers.Remove(S);
}
}
public List<Server> getServers()
{
return activeServers;
}
private String processTemplate(String Input, String Param)
{
try
{
Server requestedServer = null;
int requestPageNum = 0;
int ID = 0;
String Query = "";
if (Param != null)
{
NameValueCollection querySet = System.Web.HttpUtility.ParseQueryString(Param);
if (querySet["server"] != null)
requestedServer = activeServers.Find(x => x.pID() == Int32.Parse(querySet["server"]));
else
requestedServer = activeServers.First();
if (querySet["page"] != null)
requestPageNum = Int32.Parse(querySet["page"]);
if (querySet["id"] != null)
ID = Int32.Parse(querySet["id"]);
if (querySet["query"] != null)
Query = querySet["query"];
}
String Pattern = @"\{\{.+\}\}";
Regex Search = new Regex(Pattern, RegexOptions.IgnoreCase);
MatchCollection Matches = Search.Matches(Input);
foreach (Match match in Matches)
{
Input = processReplacements(Input, match.Value, requestPageNum, ID, Query, requestedServer);
}
return Input;
}
catch (Exception E)
{
Page Error = new error();
return Error.Load().Replace("{{ERROR}}", E.Message);
}
}
private String parsePagination(int totalItems, int itemsPerPage, int currentPage, String Page)
{
StringBuilder output = new StringBuilder();
output.Append("<div id=pages>");
if (currentPage > 0)
output.AppendFormat("<a href=/{0}?page={1}>PREV</a>", Page, currentPage - 1);
double totalPages = Math.Ceiling(((float)totalItems / itemsPerPage));
output.Append("<span id=pagination>" + (currentPage + 1) + "/" + totalPages + "</span>");
if ((currentPage + 1) < totalPages)
output.AppendFormat("<a href=/{0}?page={1}>NEXT</a>", Page, currentPage + 1);
output.Append("</div>");
return output.ToString();
}
private String processReplacements(String Input, String Macro, int curPage, int ID, String Query, params Server[] Servers)
{
2015-08-23 17:58:48 -04:00
bool Authenticated = false;
2015-08-26 01:49:47 -04:00
bool UserPrivelege = false;
2015-08-23 17:58:48 -04:00
if (Servers[0] != null && Manager.lastIP != null)
{
Player User = Servers[0].clientDB.getPlayer(Manager.lastIP.ToString());
if (User != null && User.Level > Player.Permission.Flagged)
Authenticated = true;
2015-08-26 01:49:47 -04:00
if (User != null && User.Level == Player.Permission.User)
UserPrivelege = true;
2015-08-23 17:58:48 -04:00
}
if (Macro.Length < 5)
return "";
String Looking = Macro.Substring(2, Macro.Length - 4);
if (Looking == "SERVERS")
{
int cycleFix = 0;
StringBuilder buffer = new StringBuilder();
foreach (Server S in activeServers)
{
StringBuilder players = new StringBuilder();
2015-08-23 17:58:48 -04:00
if (S.getClientNum() > 0)
{
int count = 0;
double currentPlayers = S.statusPlayers.Count;
2015-08-23 17:58:48 -04:00
players.Append("<table cellpadding='0' cellspacing='0' class='players'>");
foreach (Player P in S.getPlayers())
{
if (P == null)
continue;
if (count % 2 == 0)
{
switch (cycleFix)
{
case 0:
players.Append("<tr class='row-grey'>");
cycleFix = 1;
break;
case 1:
players.Append("<tr class='row-white'>");
cycleFix = 0;
break;
}
}
players.AppendFormat("<td><a href='/player?id={0}'>{1}</a></td>", P.databaseID, SharedLibrary.Utilities.nameHTMLFormatted(P));
if (count % 2 != 0)
{
players.Append("</tr>");
}
count++;
}
2015-08-23 17:58:48 -04:00
players.Append("</table>");
}
buffer.AppendFormat(@"<table cellpadding=0 cellspacing=0 class=server>
<tr>
<th class=server_title><span>{0}</span></th>
<th class=server_map><span>{1}</span></th>
<th class=server_players><span>{2}</span></th>
<th class=server_gametype><span>{3}</span></th>
<th><a href=/bans>Penalties</a></th>
<th><a class='history' href='/graph?server={4}'>History</a></th>
</tr>
</table>
2015-08-23 17:58:48 -04:00
{5}",
S.getName(), S.getMap(), S.getClientNum() + "/" + S.getMaxClients(), SharedLibrary.Utilities.gametypeLocalized(S.getGametype()), S.pID(), players.ToString());
2015-08-26 01:49:47 -04:00
2015-08-23 17:58:48 -04:00
if (S.getClientNum() > 0)
2015-08-26 01:49:47 -04:00
{
2015-08-23 17:58:48 -04:00
buffer.AppendFormat("<div class='chatHistory' id='chatHistory_{0}'></div><script type='text/javascript'>$( document ).ready(function() {{ setInterval({1}loadChatMessages({0}, '#chatHistory_{0}'){1}, 2500); }});</script><div class='null' style='clear:both;'></div>", S.pID(), '\"');
2015-08-26 01:49:47 -04:00
if (UserPrivelege || Authenticated)
buffer.AppendFormat("<form class='chatOutFormat' action={1}javascript:chatRequest({0}, 'chatEntry_{0}'){1}><input class='chatFormat_text' type='text' placeholder='Enter a message...' id='chatEntry_{0}'/><input class='chatFormat_submit' type='submit'/></form>", S.pID(), '\"');
}
buffer.Append("<hr/>");
}
return Input.Replace(Macro, buffer.ToString());
}
if(Looking == "CHAT")
{
StringBuilder chatMessages = new StringBuilder();
chatMessages.Append("<table id='table_chatHistory'>");
if (Servers.Length > 0 && Servers[0] != null)
{
foreach (Chat Message in Servers[0].chatHistory)
chatMessages.AppendFormat("<tr><td class='chat_name' style='text-align: left;'>{0}</td><td class='chat_message'>{1}</td><td class='chat_time' style='text-align: right;'>{2}</td></tr>", SharedLibrary.Utilities.nameHTMLFormatted(Message.Origin), Message.Message, Message.timeString());
}
chatMessages.Append("</table>");
return chatMessages.ToString();
}
if (Looking == "PLAYER")
{
StringBuilder buffer = new StringBuilder();
Server S = activeServers[0];
buffer.Append("<table class='player_info'><tr><th>Name</th><th>Aliases</th><th>IP</th><th>Rating</th><th>Level</th><th>Connections</th><th>Last Seen</th><th>Profile</th>");
List<Player> matchingPlayers = new List<Player>();
if (ID > 0)
matchingPlayers.Add(S.clientDB.getPlayer(ID));
else if (Query.Length > 2)
{
matchingPlayers = S.clientDB.findPlayers(Query);
if (matchingPlayers == null)
matchingPlayers = new List<Player>();
List<int> matchedDatabaseIDs = new List<int>();
foreach (Aliases matchingAlias in S.aliasDB.findPlayers(Query))
matchedDatabaseIDs.Add(matchingAlias.Number);
foreach (Player matchingP in S.clientDB.getPlayers(matchedDatabaseIDs))
{
if (matchingPlayers.Find(x => x.databaseID == matchingP.databaseID) == null)
matchingPlayers.Add(matchingP);
}
}
if (matchingPlayers == null)
buffer.Append("</table>");
else
{
foreach (Player Player in matchingPlayers)
{
if (Player == null)
continue;
buffer.Append("<tr>");
StringBuilder Names = new StringBuilder();
List<String> nameAlias = new List<String>();
2015-08-23 17:58:48 -04:00
List<String> IPAlias = new List<String>();
StringBuilder IPs = new StringBuilder();
if (Authenticated)
{
List<Aliases> allAlliases = S.getAliases(Player);
foreach (Aliases A in allAlliases)
2015-08-23 17:58:48 -04:00
{
foreach (String Name in A.Names.Distinct())
nameAlias.Add(Name);
2015-08-23 17:58:48 -04:00
foreach (String IP in A.IPS.Distinct())
IPAlias.Add(IP);
2015-08-23 17:58:48 -04:00
}
Names.Append("<a href='#' class='pseudoLinkAlias'>Show Aliases</a>");
Names.Append("<div class='playerAlias'>");
foreach (String Name in nameAlias.Distinct())
Names.AppendFormat("<span>{0}</span><br/>", Utilities.stripColors(Name));
Names.Append("</div>");
IPs.Append("<a href='#' class='pseudoLinkIP'>Show IPs</a>");
2015-08-23 17:58:48 -04:00
IPs.Append("<div class='playerIPs'>");
foreach (String IP in IPAlias)
IPs.AppendFormat("<span>{0}</span><br/>", IP);
IPs.Append("</div>");
}
if (!Authenticated)
{
Names.Append("Hidden");
IPs.Append("Hidden");
}
Int64 forumID = 0;
if (Player.npID.Length == 16)
{
forumID = Int64.Parse(Player.npID.Substring(0, 16), System.Globalization.NumberStyles.AllowHexSpecifier);
forumID = forumID - 76561197960265728;
}
String Screenshot = String.Empty;
//if (logged)
Screenshot = String.Format("<a href='http://server.nbsclan.org/screen.php?id={0}&name={1}' target='_blank'><div style='background-image:url(http://server.nbsclan.org/shutter.png); width: 20px; height: 20px;float: right; position:relative; right: 21%; background-size: contain;'></div></a>", forumID, Player.Name);
buffer.AppendFormat("<td><a style='float: left;' href='{9}'>{0}</a>{10}</td><td>{1}</td><td>{2}</td><td>{3}</td><td>{4}</td><td>{5}</td><td>{6} ago</td><td><a href='https://repziw4.de/forum/memberlist.php?mode=viewprofile&u={7}'>{8}</a></td>", Player.Name, Names, IPs, 0, SharedLibrary.Utilities.levelHTMLFormatted(Player.Level), Player.Connections, Player.getLastConnection(), forumID, Player.Name, "/player?id=" + Player.databaseID, Screenshot);
buffer.Append("</tr>");
}
buffer.Append("</table>");
return Input.Replace(Macro, buffer.ToString());
}
}
if (Looking == "BANS")
{
StringBuilder buffer = new StringBuilder();
Server S = activeServers[0];
buffer.Append("<table cellspacing=0 class=bans>");
int limitPerPage = 30;
int Pagination = curPage;
int totalBans = S.Bans.Count;
int range;
int start = Pagination * limitPerPage;
int cycleFix = 0;
if (totalBans <= limitPerPage)
range = totalBans;
else if ((totalBans - start) < limitPerPage)
range = (totalBans - start);
else
range = limitPerPage;
List<Penalty> Bans = new List<Penalty>();
if (totalBans > 0)
Bans = S.Bans.OrderByDescending(x => x.When).ToList().GetRange(start, range);
if (Bans.Count == 0)
buffer.Append("<span style='font-size: 16pt;'>No bans yet.</span>");
else
{
buffer.Append("<h1 style=margin-top: 0;>{{TIME}}</h1><hr /><tr><th>Name</th><th>Type</th><th style=text-align:left;>Offense</th><th style=text-align:left;>Penalty By</th><th style='width: 175px; text-align:right;padding-right: 80px;'>Time</th></tr>");
if (Bans[0] != null)
buffer = buffer.Replace("{{TIME}}", "From " + SharedLibrary.Utilities.timePassed(Bans[0].When) + " ago" + " &mdash; " + totalBans + " total");
List<String> npIDs = new List<string>();
foreach (Penalty B in Bans)
npIDs.Add(B.npID);
List<Player> bannedPlayers = S.clientDB.getPlayers(npIDs);
for (int i = 0; i < Bans.Count; i++)
{
if (Bans[i] == null)
continue;
Player P = bannedPlayers.Where(x => x.npID == Bans[i].npID).First();
Player B;
if (P.npID == Bans[i].bannedByID || Bans[i].bannedByID == "")
B = new Player("IW4MAdmin", "", 0, SharedLibrary.Player.Permission.Banned, 0, "", 0, "");
else
B = S.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)
{
String Prefix;
if (cycleFix % 2 == 0)
Prefix = "class=row-grey";
else
Prefix = "class=row-white";
String Link = "/player?id=" + P.databaseID;
buffer.AppendFormat("<tr {4}><td><a href='{5}'>{0}</a></td><td style='width: 150px; border-left: 3px solid #bbb; text-align:left;'>{6}</td><td style='border-left: 3px solid #bbb; text-align:left;'>{1}</td><td style='border-left: 3px solid #bbb;text-align:left;'>{2}</td><td style='width: 175px; text-align:right;'>{3}</td></tr></div>", P.Name, Bans[i].Reason.Substring(0, Math.Min(70, Bans[i].Reason.Length)), SharedLibrary.Utilities.nameHTMLFormatted(B), Bans[i].getWhen(), Prefix, Link, Utilities.penaltyHTMLFormatted(Bans[i].BType));
cycleFix++;
}
}
}
buffer.Append("</table><hr/>");
if (totalBans > limitPerPage)
buffer.Append(parsePagination(totalBans, limitPerPage, Pagination, "bans"));
return Input.Replace(Macro, buffer.ToString());
}
if (Looking == "GRAPH")
{
StringBuilder buffer = new StringBuilder();
buffer.Append("<script type='text/javascript' src='//www.google.com/jsapi'></script><div id='chart_div'></div>");
buffer.Append("<script> var players = [");
int count = 1;
List<PlayerHistory> run = Servers[0].playerHistory.ToList();
foreach (PlayerHistory i in run) //need to reverse for proper timeline
{
buffer.AppendFormat("[new Date({0}, {1}, {2}, {3}, {4}), {5}]", i.When.Year, i.When.Month - 1, i.When.Day, i.When.Hour, i.When.Minute, i.Players);
if (count < run.Count)
buffer.Append(",\n");
count++;
}
buffer.Append("];\n");
buffer.Append("</script>");
return Input.Replace(Macro, buffer.ToString());
}
if (Looking == "TITLE")
return Input.Replace(Macro, "IW4MAdmin by RaidMax");
if (Looking == "VERSION")
return Input.Replace(Macro, "1.1");
if (Looking == "PUBBANS" || Looking == "PUBBANSR")
{
String pubBans = "=========================================\r\nIW4MAdmin Public Banlist\r\n=========================================\r\n";
foreach (Penalty P in activeServers[0].Bans.OrderByDescending(x => x.When).ToList())
{
if (P.BType == Penalty.Type.Ban)
pubBans += String.Format("{0};{1};{2};{3}\r\n",P.npID, P.IP, P.Reason.Trim(), P.When);
if (Looking == "PUBBANSR")
pubBans += "<br/>";
}
return Input.Replace(Macro, pubBans);
}
return "PLACEHOLDER";
}
public String processRequest(Kayak.Http.HttpRequestHead request)
{
Page requestedPage = new notfound();
Page Header = new header();
Page Footer = new footer();
if (request.Path == "/")
requestedPage = new main();
else
{
string p = request.Path.ToLower().Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries)[0];
switch (p)
{
case "bans":
requestedPage = new bans();
break;
case "player":
requestedPage = new player();
break;
case "graph":
requestedPage = new graph();
return processTemplate(requestedPage.Load(), request.QueryString);
case "chat":
requestedPage = new chat();
return processTemplate(requestedPage.Load(), request.QueryString);
case "error":
requestedPage = new error();
break;
case "pubbans":
return processTemplate("{{PUBBANS}}", null);
case "pubbansr":
return processTemplate("{{PUBBANSR}}", null);
default:
requestedPage = new notfound();
break;
}
}
return processTemplate(Header.Load(), null) + processTemplate(requestedPage.Load(), request.QueryString) + processTemplate(Footer.Load(), null);
}
}
abstract class Page
{
public abstract String Load();
public abstract String Name { get; }
protected String loadHTML()
{
IFile HTML = new IFile("webfront\\" + this.Name + ".html");
String Contents = HTML.getLines();
HTML.Close();
return Contents;
}
}
class notfound : Page
{
public override String Name
{
get { return "notfound"; }
}
public override String Load()
{
return loadHTML();
}
}
class main : Page
{
public override String Name
{
get { return "main"; }
}
public override String Load()
{
return loadHTML();
}
}
class bans : Page
{
public override String Name
{
get { return "bans"; }
}
public override String Load()
{
return loadHTML();
}
}
class header : Page
{
public override String Name
{
get { return "header"; }
}
public override String Load()
{
return loadHTML();
}
}
class footer : Page
{
public override String Name
{
get { return "footer"; }
}
public override String Load()
{
return loadHTML();
}
}
class player : Page
{
public override String Name
{
get { return "player"; }
}
public override String Load()
{
return loadHTML();
}
}
class graph : Page
{
public override String Name
{
get { return "graph"; }
}
public override String Load()
{
return loadHTML();
}
}
class chat : Page
{
public override String Name
{
get { return "chat"; }
}
public override String Load()
{
return "{{CHAT}}";
}
}
class error : Page
{
public override String Name
{
get { return "error"; }
}
public override String Load()
{
return loadHTML();
}
}
}