IW4M-Admin/Admin/WebService.cs
RaidMax 7dfc2bbc1b I apparently initialized the commands for each server, which result in 114 commands being added. That is now fixed.
Hopefully this is the final fix for chat remaining on empty servers. (order matters!)
Configuration setting to allow multiple owners.
Fixed setlevel issues.
Organized Server class variables
2017-06-19 13:58:01 -04:00

768 lines
23 KiB
C#

using Kayak;
using Kayak.Http;
using SharedLibrary;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
namespace IW4MAdmin
{
public class WebService
{
public static IServer webService;
public static IScheduler GetScheduler()
{
var webScheduler = Kayak.KayakScheduler.Factory.Create(new Scheduler());
webService = KayakServer.Factory.CreateHttp(new Request(), webScheduler);
SharedLibrary.WebService.PageList.Add(new Pages());
SharedLibrary.WebService.PageList.Add(new Homepage());
SharedLibrary.WebService.PageList.Add(new ServersJSON());
SharedLibrary.WebService.PageList.Add(new Penalties());
SharedLibrary.WebService.PageList.Add(new PenaltiesJSON());
SharedLibrary.WebService.PageList.Add(new Players());
SharedLibrary.WebService.PageList.Add(new GetPlayer());
SharedLibrary.WebService.PageList.Add(new WebConsole());
SharedLibrary.WebService.PageList.Add(new ConsoleJSON());
SharedLibrary.WebService.PageList.Add(new PubbansJSON());
Thread scheduleThread = new Thread(() => { ScheduleThreadStart(webScheduler, webService); })
{
Name = "Web Service Thread"
};
scheduleThread.Start();
return webScheduler;
}
private static void ScheduleThreadStart(IScheduler S, IServer ss)
{
try
{
string[] webConfig = System.IO.File.ReadAllLines("config\\web.cfg");
var address = Dns.GetHostAddresses(webConfig[0])[0];
int port = Convert.ToInt32(webConfig[1]);
try
{
using (ss.Listen(new IPEndPoint(address, port)))
S.Start();
}
catch (Exception e)
{
ApplicationManager.GetInstance().Logger.WriteError($"Unable to start webservice ( port is probably in use ): {e.Message}");
}
}
catch (Exception)
{
using (ss.Listen(new IPEndPoint(IPAddress.Any, 1624)))
S.Start();
}
}
public static HttpResponse GetPage(string path, System.Collections.Specialized.NameValueCollection queryset, IDictionary<string, string> headers)
{
if (SharedLibrary.WebService.PageList == null || SharedLibrary.WebService.PageList.Count == 0)
return new HttpResponse() { content = "Error: page list not initialized!", contentType = "text/plaintext" };
if (path == null)
return new HttpResponse() { content = "Error: no path specified", contentType = "text/plaintext" };
IPage requestedPage = SharedLibrary.WebService.PageList.Find(x => x.GetPath().ToLower() == path.ToLower());
if (requestedPage != null)
return requestedPage.GetPage(queryset, headers);
else
{
if (System.IO.File.Exists(path.Replace("/", "\\").Substring(1)))
{
IFile f = new IFile(path.Replace("/", "\\").Substring(1));
if (path.Contains(".css"))
{
HttpResponse css = new HttpResponse()
{
additionalHeaders = new Dictionary<string, string>(),
content = f.GetText(),
contentType = "text/css"
};
f.Close();
return css;
}
else if (path.Contains(".js"))
{
HttpResponse css = new HttpResponse()
{
additionalHeaders = new Dictionary<string, string>(),
content = f.GetText(),
contentType = "application/javascript"
};
f.Close();
return css;
}
f.Close();
}
requestedPage = new Error404();
return requestedPage.GetPage(queryset, headers);
}
}
}
class Error404 : IPage
{
public string GetName()
{
return "404";
}
public string GetPath()
{
return "";
}
public HttpResponse GetPage(System.Collections.Specialized.NameValueCollection querySet, IDictionary<string, string> headers)
{
HttpResponse resp = new HttpResponse()
{
additionalHeaders = new Dictionary<string, string>(),
content = "404 not found!",
contentType = GetContentType()
};
return resp;
}
public string GetContentType()
{
return "text/html";
}
public bool Visible()
{
return false;
}
}
class Homepage : HTMLPage
{
public override string GetName()
{
return "Home";
}
public override string GetPath()
{
return "/";
}
public override string GetContent(System.Collections.Specialized.NameValueCollection querySet, IDictionary<string, string> headers)
{
StringBuilder S = new StringBuilder();
S.Append(LoadHeader());
IFile p = new IFile("webfront\\main.html");
S.Append(p.GetText());
p.Close();
S.Append(LoadFooter());
return S.ToString();
}
}
class ServersJSON : IPage
{
public string GetName()
{
return "Servers";
}
public string GetPath()
{
return "/_servers";
}
public HttpResponse GetPage(System.Collections.Specialized.NameValueCollection querySet, IDictionary<string, string> headers)
{
var info = new List<ServerInfo>();
foreach (Server S in ApplicationManager.GetInstance().Servers)
{
ServerInfo eachServer = new ServerInfo()
{
serverName = S.Hostname,
serverPort = S.GetPort(),
maxPlayers = S.MaxClients,
mapName = S.CurrentMap.Alias,
gameType = Utilities.GetLocalizedGametype(S.Gametype),
currentPlayers = S.GetPlayersAsList().Count,
chatHistory = S.ChatHistory,
players = new List<PlayerInfo>()
};
foreach (Player P in S.GetPlayersAsList())
{
PlayerInfo pInfo = new PlayerInfo()
{
playerID = P.DatabaseID,
playerName = P.Name,
playerLevel = P.Level.ToString()
};
eachServer.players.Add(pInfo);
}
info.Add(eachServer);
}
HttpResponse resp = new HttpResponse()
{
contentType = GetContentType(),
content = Newtonsoft.Json.JsonConvert.SerializeObject(info),
additionalHeaders = new Dictionary<string, string>()
};
return resp;
}
public string GetContentType()
{
return "application/json";
}
public bool Visible()
{
return false;
}
}
class Info : IPage
{
public string GetName()
{
return "Info";
}
public string GetPath()
{
return "/_info";
}
public HttpResponse GetPage(System.Collections.Specialized.NameValueCollection querySet, IDictionary<string, string> headers)
{
ApplicationInfo info = new ApplicationInfo()
{
name = "IW4MAdmin",
version = Program.Version
};
HttpResponse resp = new HttpResponse()
{
contentType = GetContentType(),
content = Newtonsoft.Json.JsonConvert.SerializeObject(info),
additionalHeaders = new Dictionary<string, string>()
};
return resp;
}
public string GetContentType()
{
return "application/json";
}
public bool Visible()
{
return false;
}
}
class ConsoleJSON : IPage
{
public string GetName()
{
return "_Console";
}
public string GetPath()
{
return "/_console";
}
public HttpResponse GetPage(System.Collections.Specialized.NameValueCollection querySet, IDictionary<string, string> headers)
{
CommandInfo cmd = new CommandInfo()
{
Result = new List<string>()
};
if (querySet["command"] != null)
{
if (querySet["server"] != null)
{
Server S = ApplicationManager.GetInstance().Servers.ToList().Find(x => (x.GetPort().ToString() == querySet["server"]));
if (S != null)
{
Player admin = ApplicationManager.GetInstance().GetClientDatabase().GetPlayer(querySet["IP"]);
if (admin == null)
admin = new Player("RestUser", "-1", -1, (int)Player.Permission.User);
Event remoteEvent = new Event(Event.GType.Say, querySet["command"], admin, null, S)
{
Remote = true
};
admin.lastEvent = remoteEvent;
S.ExecuteEvent(remoteEvent);
while (S.commandResult.Count > 0)
cmd.Result.Add(S.commandResult.Dequeue());
}
else
cmd.Result.Add("Invalid server selected.");
}
else
cmd.Result.Add("Invalid server selected.");
}
else
{
cmd.Result.Add("No command entered.");
}
HttpResponse resp = new HttpResponse()
{
contentType = GetContentType(),
content = Newtonsoft.Json.JsonConvert.SerializeObject(cmd),
additionalHeaders = new Dictionary<string, string>()
};
return resp;
}
public string GetContentType()
{
return "application/json";
}
public bool Visible()
{
return false;
}
}
class PenaltiesJSON : IPage
{
public string GetName()
{
return "Penalties";
}
public string GetPath()
{
return "/_penalties";
}
public HttpResponse GetPage(System.Collections.Specialized.NameValueCollection querySet, IDictionary<string, string> headers)
{
int from = 0;
if (querySet["from"] != null)
from = Int32.Parse(querySet["from"]);
List<Penalty> selectedPenalties;
try
{
//selectedPenalties = Manager.GetInstance().Servers.First().Bans.OrderByDescending(x => x.When).ToList().GetRange(Convert.ToInt32(querySet["from"]), 15);
selectedPenalties = ((ApplicationManager.GetInstance().GetClientPenalties()) as PenaltyList).AsChronoList(Convert.ToInt32(querySet["from"]), 15).OrderByDescending(b => b.When).ToList();
}
catch (Exception)
{
selectedPenalties = new List<Penalty>();
}
List<PenaltyInfo> info = new List<PenaltyInfo>();
foreach (var p in selectedPenalties)
{
Player admin = ApplicationManager.GetInstance().GetClientDatabase().GetPlayer(p.PenaltyOriginID, 0);
Player penalized = ApplicationManager.GetInstance().GetClientDatabase().GetPlayer(p.OffenderID, 0);
if (admin == null && penalized == null)
continue;
if (admin == null)
admin = new Player("Unknown", "-1", -1, (int)Player.Permission.Banned);
PenaltyInfo pInfo = new PenaltyInfo()
{
adminName = admin.Name,
adminLevel = admin.Level.ToString(),
penaltyReason = p.Reason,
penaltyTime = SharedLibrary.Utilities.GetTimePassed(p.When),
penaltyType = p.BType.ToString(),
playerName = penalized.Name,
playerID = penalized.DatabaseID
};
if (admin.NetworkID == penalized.NetworkID)
{
pInfo.adminName = "IW4MAdmin";
pInfo.adminLevel = Player.Permission.Console.ToString();
}
info.Add(pInfo);
}
HttpResponse resp = new HttpResponse()
{
contentType = GetContentType(),
content = Newtonsoft.Json.JsonConvert.SerializeObject(info),
additionalHeaders = new Dictionary<string, string>()
};
return resp;
}
public string GetContentType()
{
return "application/json";
}
public bool Visible()
{
return false;
}
}
class Penalties : HTMLPage
{
public override string GetName()
{
return "Penalties";
}
public override string GetPath()
{
return "/penalties";
}
public override string GetContent(System.Collections.Specialized.NameValueCollection querySet, IDictionary<string, string> headers)
{
StringBuilder S = new StringBuilder();
S.Append(LoadHeader());
IFile penalities = new IFile("webfront\\penalties.html");
S.Append(penalities.GetText());
penalities.Close();
S.Append(LoadFooter());
return S.ToString();
}
}
class WebConsole : HTMLPage
{
public override string GetName()
{
return "Console";
}
public override string GetPath()
{
return "/console";
}
public override string GetContent(System.Collections.Specialized.NameValueCollection querySet, IDictionary<string, string> headers)
{
StringBuilder S = new StringBuilder();
S.Append(LoadHeader());
IFile console = new IFile("webfront\\console.html");
S.Append(console.GetText());
console.Close();
S.Append(LoadFooter());
return S.ToString();
}
}
class Players : HTMLPage
{
public override string GetName()
{
return "Players";
}
public override string GetPath()
{
return "/players";
}
public override string GetContent(System.Collections.Specialized.NameValueCollection querySet, IDictionary<string, string> headers)
{
StringBuilder S = new StringBuilder();
S.Append(LoadHeader());
IFile penalities = new IFile("webfront\\players.html");
S.Append(penalities.GetText());
penalities.Close();
S.Append(LoadFooter());
return S.ToString();
}
}
class PubbansJSON : IPage
{
public string GetName()
{
return "Public Ban List";
}
public string GetPath()
{
return "/pubbans";
}
public HttpResponse GetPage(System.Collections.Specialized.NameValueCollection querySet, IDictionary<string, string> headers)
{
HttpResponse resp = new HttpResponse()
{
contentType = GetContentType(),
content = Newtonsoft.Json.JsonConvert.SerializeObject(((ApplicationManager.GetInstance().GetClientPenalties()) as PenaltyList).AsChronoList(Convert.ToInt32(querySet["from"]), 15), Newtonsoft.Json.Formatting.Indented, new Newtonsoft.Json.JsonConverter[] { new Newtonsoft.Json.Converters.StringEnumConverter() }),
additionalHeaders = new Dictionary<string, string>()
};
return resp;
}
public string GetContentType()
{
return "application/json";
}
public bool Visible()
{
return false;
}
}
class Pages : IPage
{
public string GetName()
{
return "Pages";
}
public string GetPath()
{
return "/pages";
}
public HttpResponse GetPage(System.Collections.Specialized.NameValueCollection querySet, IDictionary<string, string> headers)
{
List<PageInfo> pages = new List<PageInfo>();
foreach (var p in SharedLibrary.WebService.PageList.Where(x => x.Visible()))
{
if (p == this)
continue;
PageInfo pi = new PageInfo()
{
pagePath = p.GetPath(),
pageName = p.GetName(),
visible = p.Visible()
};
pages.Add(pi);
}
HttpResponse resp = new HttpResponse()
{
contentType = GetContentType(),
content = Newtonsoft.Json.JsonConvert.SerializeObject(pages),
additionalHeaders = new Dictionary<string, string>()
};
return resp;
}
public string GetContentType()
{
return "application/json";
}
public bool Visible()
{
return false;
}
}
class GetPlayer : IPage
{
public string GetContentType()
{
return "application/json";
}
public string GetPath()
{
return "/getplayer";
}
public string GetName()
{
return "GetPlayer";
}
public HttpResponse GetPage(System.Collections.Specialized.NameValueCollection querySet, IDictionary<string, string> headers)
{
List<PlayerInfo> pInfo = new List<PlayerInfo>();
List<Player> matchedPlayers = new List<Player>();
HttpResponse resp = new HttpResponse()
{
contentType = GetContentType(),
additionalHeaders = new Dictionary<string, string>()
};
bool authed = ApplicationManager.GetInstance().GetClientDatabase().GetAdmins().FindAll(x => x.IP == querySet["IP"]).Count > 0;
bool recent = false;
if (querySet["id"] != null)
{
matchedPlayers.Add(ApplicationManager.GetInstance().GetClientDatabase().GetPlayer(Convert.ToInt32(querySet["id"])));
}
else if (querySet["npID"] != null)
{
matchedPlayers.Add(ApplicationManager.GetInstance().GetClientDatabase().GetPlayers(new List<string> { querySet["npID"] }).First());
}
else if (querySet["name"] != null)
{
matchedPlayers = ApplicationManager.GetInstance().GetClientDatabase().FindPlayers(querySet["name"]);
}
else if (querySet["recent"] != null)
{
matchedPlayers = ApplicationManager.GetInstance().GetClientDatabase().GetRecentPlayers();
recent = true;
}
if (matchedPlayers != null && matchedPlayers.Count > 0)
{
foreach (var pp in matchedPlayers)
{
if (pp == null) continue;
PlayerInfo eachPlayer = new PlayerInfo()
{
playerID = pp.DatabaseID,
playerIP = pp.IP,
playerLevel = pp.Level.ToString(),
playerName = pp.Name,
playernpID = pp.NetworkID,
forumID = -1,
authed = authed,
showV2Features = false
};
if (!recent)
{
foreach (var a in ApplicationManager.GetInstance().Servers.First().GetAliases(pp))
{
eachPlayer.playerAliases = a.Names;
eachPlayer.playerIPs = a.IPS;
}
}
eachPlayer.playerConnections = pp.Connections;
eachPlayer.lastSeen = Utilities.GetTimePassed(pp.LastConnection);
pInfo.Add(eachPlayer);
}
resp.content = Newtonsoft.Json.JsonConvert.SerializeObject(pInfo);
return resp;
}
resp.content = Newtonsoft.Json.JsonConvert.SerializeObject(null);
return resp;
}
public bool Visible()
{
return false;
}
}
[Serializable]
struct ServerInfo
{
public string serverName;
public int serverPort;
public string mapName;
public string gameType;
public int currentPlayers;
public int maxPlayers;
public List<Chat> chatHistory;
public List<PlayerInfo> players;
}
[Serializable]
struct ApplicationInfo
{
public double version;
public string name;
}
[Serializable]
struct PageInfo
{
public string pageName;
public string pagePath;
public string pageType;
public bool visible;
}
[Serializable]
struct PlayerInfo
{
public string playerName;
public int playerID;
public string playerLevel;
public string playerIP;
public string playernpID;
public Int64 forumID;
public List<string> playerAliases;
public List<string> playerIPs;
public int playerConnections;
public string lastSeen;
public bool showV2Features;
public bool authed;
}
[Serializable]
struct PenaltyInfo
{
public string playerName;
public int playerID;
public string adminName;
public string adminLevel;
public string penaltyType;
public string penaltyReason;
public string penaltyTime;
}
[Serializable]
struct CommandInfo
{
public List<string> Result;
}
}