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
This commit is contained in:
RaidMax 2017-06-19 13:58:01 -04:00
parent 622a0a8ddc
commit 7dfc2bbc1b
17 changed files with 503 additions and 514 deletions

View File

@ -122,7 +122,6 @@
<Reference Include="System.Xml" /> <Reference Include="System.Xml" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="ServerConfig.cs" />
<Compile Include="Kayak.cs" /> <Compile Include="Kayak.cs" />
<Compile Include="Logger.cs" /> <Compile Include="Logger.cs" />
<Compile Include="Main.cs" /> <Compile Include="Main.cs" />
@ -135,6 +134,7 @@
<DependentUpon>Settings.settings</DependentUpon> <DependentUpon>Settings.settings</DependentUpon>
</Compile> </Compile>
<Compile Include="Server.cs" /> <Compile Include="Server.cs" />
<Compile Include="ServerConfigurationGenerator.cs" />
<Compile Include="WebService.cs" /> <Compile Include="WebService.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -18,20 +18,20 @@ namespace IW4MAdmin
if (e.GetType() == typeof(NullReferenceException)) if (e.GetType() == typeof(NullReferenceException))
return; return;
Manager.GetInstance().Logger.WriteWarning("Web service has encountered an error - " + e.Message); ApplicationManager.GetInstance().Logger.WriteWarning("Web service has encountered an error - " + e.Message);
Manager.GetInstance().Logger.WriteDebug($"Stack Trace: {e.StackTrace}"); ApplicationManager.GetInstance().Logger.WriteDebug($"Stack Trace: {e.StackTrace}");
if (e.InnerException != null) if (e.InnerException != null)
{ {
Manager.GetInstance().Logger.WriteDebug($"Inner Exception: {e.InnerException.Message}"); ApplicationManager.GetInstance().Logger.WriteDebug($"Inner Exception: {e.InnerException.Message}");
Manager.GetInstance().Logger.WriteDebug($"Inner Stack Trace: {e.InnerException.StackTrace}"); ApplicationManager.GetInstance().Logger.WriteDebug($"Inner Stack Trace: {e.InnerException.StackTrace}");
} }
} }
public void OnStop(IScheduler scheduler) public void OnStop(IScheduler scheduler)
{ {
Manager.GetInstance().Logger.WriteInfo("Web service has been stopped..."); ApplicationManager.GetInstance().Logger.WriteInfo("Web service has been stopped...");
} }
} }

View File

@ -11,7 +11,7 @@ namespace IW4MAdmin
class Program class Program
{ {
static public double Version { get; private set; } static public double Version { get; private set; }
static private Manager ServerManager; static private ApplicationManager ServerManager;
static void Main(string[] args) static void Main(string[] args)
{ {
@ -33,7 +33,7 @@ namespace IW4MAdmin
{ {
CheckDirectories(); CheckDirectories();
ServerManager = Manager.GetInstance(); ServerManager = ApplicationManager.GetInstance();
ServerManager.Init(); ServerManager.Init();
Task.Run(() => Task.Run(() =>

View File

@ -2,39 +2,44 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
using SharedLibrary;
using System.IO; using System.IO;
using System.Threading.Tasks; using System.Threading.Tasks;
using SharedLibrary;
using SharedLibrary.Interfaces;
using SharedLibrary.Commands;
using SharedLibrary.Helpers;
namespace IW4MAdmin namespace IW4MAdmin
{ {
class Manager : SharedLibrary.Interfaces.IManager class ApplicationManager : IManager
{ {
static Manager Instance;
public List<Server> Servers { get; private set; } public List<Server> Servers { get; private set; }
List<SharedLibrary.Helpers.AsyncStatus> TaskStatuses; public ILogger Logger { get; private set; }
public bool Running { get; private set; }
static ApplicationManager Instance;
List<AsyncStatus> TaskStatuses;
Database ClientDatabase; Database ClientDatabase;
Database AliasesDatabase; Database AliasesDatabase;
SharedLibrary.Interfaces.IPenaltyList ClientPenalties; IPenaltyList ClientPenalties;
List<Command> Commands; List<Command> Commands;
List<SharedLibrary.Helpers.MessageToken> MessageTokens; List<MessageToken> MessageTokens;
Kayak.IScheduler webServiceTask; Kayak.IScheduler webServiceTask;
Thread WebThread; Thread WebThread;
public SharedLibrary.Interfaces.ILogger Logger { get; private set; }
public bool Running { get; private set; }
#if FTP_LOG #if FTP_LOG
const int UPDATE_FREQUENCY = 15000; const int UPDATE_FREQUENCY = 15000;
#else #else
const int UPDATE_FREQUENCY = 300; const int UPDATE_FREQUENCY = 300;
#endif #endif
private Manager() private ApplicationManager()
{ {
Logger = new Logger("Logs/IW4MAdmin.log"); Logger = new Logger("Logs/IW4MAdmin.log");
Servers = new List<Server>(); Servers = new List<Server>();
Commands = new List<Command>(); Commands = new List<Command>();
TaskStatuses = new List<SharedLibrary.Helpers.AsyncStatus>(); TaskStatuses = new List<AsyncStatus>();
MessageTokens = new List<SharedLibrary.Helpers.MessageToken>(); MessageTokens = new List<MessageToken>();
ClientDatabase = new ClientsDB("Database/clients.rm"); ClientDatabase = new ClientsDB("Database/clients.rm");
AliasesDatabase = new AliasesDB("Database/aliases.rm"); AliasesDatabase = new AliasesDB("Database/aliases.rm");
@ -51,40 +56,23 @@ namespace IW4MAdmin
return Commands; return Commands;
} }
public static Manager GetInstance() public static ApplicationManager GetInstance()
{ {
return Instance ?? (Instance = new Manager()); return Instance ?? (Instance = new ApplicationManager());
} }
public void Init() public void Init()
{ {
SharedLibrary.WebService.Init(); #region CONFIG
SharedLibrary.Plugins.PluginImporter.Load(this);
foreach (var Plugin in SharedLibrary.Plugins.PluginImporter.ActivePlugins)
{
try
{
Plugin.OnLoadAsync();
}
catch (Exception e)
{
Logger.WriteError($"An error occured loading plugin {Plugin.Name}");
Logger.WriteDebug($"Exception: {e.Message}");
Logger.WriteDebug($"Stack Trace: {e.StackTrace}");
}
}
var Configs = Directory.EnumerateFiles("config/servers").Where(x => x.Contains(".cfg")); var Configs = Directory.EnumerateFiles("config/servers").Where(x => x.Contains(".cfg"));
if (Configs.Count() == 0) if (Configs.Count() == 0)
ServerConfig.Generate(); ServerConfigurationGenerator.Generate();
foreach (var file in Configs) foreach (var file in Configs)
{ {
var Conf = ServerConfig.Read(file); var Conf = ServerConfiguration.Read(file);
var ServerInstance = new IW4MServer(this, Conf.IP, Conf.Port, Conf.Password); var ServerInstance = new IW4MServer(this, Conf);
Task.Run(async () => Task.Run(async () =>
{ {
@ -111,7 +99,68 @@ namespace IW4MAdmin
}); });
} }
#endregion
#region PLUGINS
SharedLibrary.Plugins.PluginImporter.Load(this);
foreach (var Plugin in SharedLibrary.Plugins.PluginImporter.ActivePlugins)
{
try
{
Plugin.OnLoadAsync();
}
catch (Exception e)
{
Logger.WriteError($"An error occured loading plugin {Plugin.Name}");
Logger.WriteDebug($"Exception: {e.Message}");
Logger.WriteDebug($"Stack Trace: {e.StackTrace}");
}
}
#endregion
#region COMMANDS
if ((ClientDatabase as ClientsDB).GetOwner() != null)
Commands.Add(new COwner("owner", "claim ownership of the server", "owner", Player.Permission.User, 0, false));
Commands.Add(new CQuit("quit", "quit IW4MAdmin", "q", Player.Permission.Owner, 0, false));
Commands.Add(new CKick("kick", "kick a player by name. syntax: !kick <player> <reason>.", "k", Player.Permission.Trusted, 2, true));
Commands.Add(new CSay("say", "broadcast message to all players. syntax: !say <message>.", "s", Player.Permission.Moderator, 1, false));
Commands.Add(new CTempBan("tempban", "temporarily ban a player for 1 hour. syntax: !tempban <player> <reason>.", "tb", Player.Permission.Moderator, 2, true));
Commands.Add(new CBan("ban", "permanently ban a player from the server. syntax: !ban <player> <reason>", "b", Player.Permission.SeniorAdmin, 2, true));
Commands.Add(new CWhoAmI("whoami", "give information about yourself. syntax: !whoami.", "who", Player.Permission.User, 0, false));
Commands.Add(new CList("list", "list active clients syntax: !list.", "l", Player.Permission.Moderator, 0, false));
Commands.Add(new CHelp("help", "list all available commands. syntax: !help.", "h", Player.Permission.User, 0, false));
Commands.Add(new CFastRestart("fastrestart", "fast restart current map. syntax: !fastrestart.", "fr", Player.Permission.Moderator, 0, false));
Commands.Add(new CMapRotate("maprotate", "cycle to the next map in rotation. syntax: !maprotate.", "mr", Player.Permission.Administrator, 0, false));
Commands.Add(new CSetLevel("setlevel", "set player to specified administration level. syntax: !setlevel <player> <level>.", "sl", Player.Permission.Owner, 2, true));
Commands.Add(new CUsage("usage", "get current application memory usage. syntax: !usage.", "us", Player.Permission.Moderator, 0, false));
Commands.Add(new CUptime("uptime", "get current application running time. syntax: !uptime.", "up", Player.Permission.Moderator, 0, false));
Commands.Add(new Cwarn("warn", "warn player for infringing rules syntax: !warn <player> <reason>.", "w", Player.Permission.Trusted, 2, true));
Commands.Add(new CWarnClear("warnclear", "remove all warning for a player syntax: !warnclear <player>.", "wc", Player.Permission.Trusted, 1, true));
Commands.Add(new CUnban("unban", "unban player by database id. syntax: !unban @<id>.", "ub", Player.Permission.SeniorAdmin, 1, true));
Commands.Add(new CListAdmins("admins", "list currently connected admins. syntax: !admins.", "a", Player.Permission.User, 0, false));
Commands.Add(new CLoadMap("map", "change to specified map. syntax: !map", "m", Player.Permission.Administrator, 1, false));
Commands.Add(new CFindPlayer("find", "find player in database. syntax: !find <player>", "f", Player.Permission.SeniorAdmin, 1, false));
Commands.Add(new CListRules("rules", "list server rules. syntax: !rules", "r", Player.Permission.User, 0, false));
Commands.Add(new CPrivateMessage("privatemessage", "send message to other player. syntax: !pm <player> <message>", "pm", Player.Permission.User, 2, true));
Commands.Add(new CFlag("flag", "flag a suspicious player and announce to admins on join . syntax !flag <player> <reason>:", "flag", Player.Permission.Moderator, 2, true));
Commands.Add(new CReport("report", "report a player for suspicious behaivor. syntax !report <player> <reason>", "rep", Player.Permission.User, 2, true));
Commands.Add(new CListReports("reports", "get most recent reports. syntax !reports", "reports", Player.Permission.Moderator, 0, false));
Commands.Add(new CMask("mask", "hide your online presence from online admin list. syntax: !mask", "mask", Player.Permission.Administrator, 0, false));
Commands.Add(new CListBanInfo("baninfo", "get information about a ban for a player. syntax: !baninfo <player>", "bi", Player.Permission.Moderator, 1, true));
Commands.Add(new CListAlias("alias", "get past aliases and ips of a player. syntax: !alias <player>", "known", Player.Permission.Moderator, 1, true));
Commands.Add(new CExecuteRCON("rcon", "send rcon command to server. syntax: !rcon <command>", "rcon", Player.Permission.Owner, 1, false));
Commands.Add(new CFindAllPlayers("findall", "find a player by their aliase(s). syntax: !findall <player>", "fa", Player.Permission.Moderator, 1, false));
Commands.Add(new CPlugins("plugins", "view all loaded plugins. syntax: !plugins", "p", Player.Permission.Administrator, 0, false));
foreach (Command C in SharedLibrary.Plugins.PluginImporter.ActiveCommands)
Commands.Add(C);
#endregion
#region WEBSERVICE
SharedLibrary.WebService.Init();
webServiceTask = WebService.GetScheduler(); webServiceTask = WebService.GetScheduler();
WebThread = new Thread(webServiceTask.Start) WebThread = new Thread(webServiceTask.Start)
@ -120,6 +169,7 @@ namespace IW4MAdmin
}; };
WebThread.Start(); WebThread.Start();
#endregion
Running = true; Running = true;
} }
@ -165,17 +215,17 @@ namespace IW4MAdmin
return AliasesDatabase as AliasesDB; return AliasesDatabase as AliasesDB;
} }
public SharedLibrary.Interfaces.IPenaltyList GetClientPenalties() public IPenaltyList GetClientPenalties()
{ {
return ClientPenalties; return ClientPenalties;
} }
public SharedLibrary.Interfaces.ILogger GetLogger() public ILogger GetLogger()
{ {
return Logger; return Logger;
} }
public IList<SharedLibrary.Helpers.MessageToken> GetMessageTokens() public IList<MessageToken> GetMessageTokens()
{ {
return MessageTokens; return MessageTokens;
} }

View File

@ -15,22 +15,22 @@ namespace IW4MAdmin
public void AddPenalty(Penalty P) public void AddPenalty(Penalty P)
{ {
Manager.GetInstance().GetClientDatabase().AddBan(P); ApplicationManager.GetInstance().GetClientDatabase().AddBan(P);
} }
public void RemovePenalty(Penalty P) public void RemovePenalty(Penalty P)
{ {
Manager.GetInstance().GetClientDatabase().RemoveBan(P.OffenderID); ApplicationManager.GetInstance().GetClientDatabase().RemoveBan(P.OffenderID);
} }
public List<Penalty> FindPenalties(Player P) public List<Penalty> FindPenalties(Player P)
{ {
return Manager.GetInstance().GetClientDatabase().GetClientPenalties(P); return ApplicationManager.GetInstance().GetClientDatabase().GetClientPenalties(P);
} }
public List<Penalty> AsChronoList(int offset, int count) public List<Penalty> AsChronoList(int offset, int count)
{ {
return Manager.GetInstance().GetClientDatabase().GetPenaltiesChronologically(offset, count); return ApplicationManager.GetInstance().GetClientDatabase().GetPenaltiesChronologically(offset, count);
} }
} }
} }

View File

@ -3,18 +3,17 @@ using System.Collections.Generic;
using System.Threading; using System.Threading;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Threading.Tasks;
using SharedLibrary; using SharedLibrary;
using SharedLibrary.Network; using SharedLibrary.Network;
using System.Threading.Tasks; using SharedLibrary.Interfaces;
namespace IW4MAdmin namespace IW4MAdmin
{ {
public class IW4MServer : Server public class IW4MServer : Server
{ {
public IW4MServer(SharedLibrary.Interfaces.IManager mgr, string address, int port, string password) : base(mgr, address, port, password) public IW4MServer(IManager mgr, ServerConfiguration cfg) : base(mgr, cfg) { }
{
InitializeCommands();
}
private void GetAliases(List<Aliases> returnAliases, Aliases currentAlias) private void GetAliases(List<Aliases> returnAliases, Aliases currentAlias)
{ {
@ -76,7 +75,6 @@ namespace IW4MAdmin
Manager.GetAliasesDatabase().AddPlayerAliases(new Aliases(NewPlayer.DatabaseID, NewPlayer.Name, NewPlayer.IP)); Manager.GetAliasesDatabase().AddPlayerAliases(new Aliases(NewPlayer.DatabaseID, NewPlayer.Name, NewPlayer.IP));
} }
List<Player> Admins = Manager.GetClientDatabase().GetAdmins(); List<Player> Admins = Manager.GetClientDatabase().GetAdmins();
if (Admins.Find(x => x.Name == P.Name) != null) if (Admins.Find(x => x.Name == P.Name) != null)
{ {
@ -108,9 +106,7 @@ namespace IW4MAdmin
// and ips // and ips
if (NewPlayer.Alias.IPS.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.IPS.Add(P.IP); NewPlayer.Alias.IPS.Add(P.IP);
}
NewPlayer.SetIP(P.IP); NewPlayer.SetIP(P.IP);
@ -127,7 +123,7 @@ namespace IW4MAdmin
return true; return true;
} }
List<Player> newPlayerAliases = GetPlayerAliases(NewPlayer); var newPlayerAliases = GetPlayerAliases(NewPlayer);
foreach (Player aP in newPlayerAliases) // lets check their aliases foreach (Player aP in newPlayerAliases) // lets check their aliases
{ {
@ -209,21 +205,7 @@ namespace IW4MAdmin
return null; return null;
} }
else return Players[pID];
{
Player P = null;
try
{
P = Players[pID];
return P;
}
catch (Exception)
{
Logger.WriteError("Client index is invalid - " + pID);
Logger.WriteDebug(L.ToString());
return null;
}
}
} }
//Check ban list for every banned player and return ban if match is found //Check ban list for every banned player and return ban if match is found
@ -272,7 +254,6 @@ namespace IW4MAdmin
int cNum = -1; int cNum = -1;
int.TryParse(Args[0], out cNum); int.TryParse(Args[0], out cNum);
if (Args[0] == String.Empty) if (Args[0] == String.Empty)
return C; return C;
@ -296,9 +277,10 @@ namespace IW4MAdmin
E.Target = Players[cNum]; E.Target = Players[cNum];
} }
E.Target = GetClientByName(E.Data.Trim()); if (E.Target == null) // Find active player including quotes (multiple words)
E.Target = GetClientByName(E.Data.Trim());
if (E.Target == null) if (E.Target == null) // Find active player as single word
E.Target = GetClientByName(Args[0]); E.Target = GetClientByName(Args[0]);
if (E.Target == null && C.RequiresTarget) if (E.Target == null && C.RequiresTarget)
@ -312,17 +294,13 @@ namespace IW4MAdmin
public override async Task ExecuteEvent(Event E) public override async Task ExecuteEvent(Event E)
{ {
await ProcessEvent(E); await ProcessEvent(E);
foreach (SharedLibrary.Interfaces.IPlugin P in SharedLibrary.Plugins.PluginImporter.ActivePlugins) foreach (IPlugin P in SharedLibrary.Plugins.PluginImporter.ActivePlugins)
{ {
try try
{ {
#if DEBUG
await P.OnEventAsync(E, this); await P.OnEventAsync(E, this);
#else
P.OnEventAsync(E, this);
#endif
} }
catch (Exception Except) catch (Exception Except)
@ -381,19 +359,13 @@ namespace IW4MAdmin
Logger.WriteError($"{e.Message} {IP}:{Port}, reducing polling rate"); Logger.WriteError($"{e.Message} {IP}:{Port}, reducing polling rate");
} }
lastMessage = DateTime.Now - start; LastMessage = DateTime.Now - start;
lastCount = DateTime.Now; lastCount = DateTime.Now;
if ((DateTime.Now - tickTime).TotalMilliseconds >= 1000) 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 SharedLibrary.Plugins.PluginImporter.ActivePlugins) foreach (var Plugin in SharedLibrary.Plugins.PluginImporter.ActivePlugins)
#if !DEBUG
Plugin.OnTickAsync(this);
#else
await Plugin.OnTickAsync(this); await Plugin.OnTickAsync(this);
#endif
tickTime = DateTime.Now; tickTime = DateTime.Now;
} }
@ -405,24 +377,24 @@ namespace IW4MAdmin
playerCountStart = DateTime.Now; playerCountStart = DateTime.Now;
} }
if (lastMessage.TotalSeconds > messageTime && messages.Count > 0 && Players.Count > 0) if (LastMessage.TotalSeconds > MessageTime && BroadcastMessages.Count > 0 && Players.Count > 0)
{ {
await Broadcast(Utilities.ProcessMessageToken(Manager.GetMessageTokens(), messages[nextMessage])); await Broadcast(Utilities.ProcessMessageToken(Manager.GetMessageTokens(), BroadcastMessages[NextMessage]));
if (nextMessage == (messages.Count - 1)) if (NextMessage == (BroadcastMessages.Count - 1))
nextMessage = 0; NextMessage = 0;
else else
nextMessage++; NextMessage++;
start = DateTime.Now; start = DateTime.Now;
} }
//logFile = new IFile(); //logFile = new IFile();
if (l_size != logFile.Length()) if (l_size != LogFile.Length())
{ {
// this should be the longest running task // this should be the longest running task
await Task.FromResult(lines = logFile.Tail(12)); await Task.FromResult(lines = LogFile.Tail(12));
if (lines != oldLines) if (lines != oldLines)
{ {
l_size = logFile.Length(); l_size = LogFile.Length();
int end; int end;
if (lines.Length == oldLines.Length) if (lines.Length == oldLines.Length)
end = lines.Length - 1; end = lines.Length - 1;
@ -459,7 +431,7 @@ namespace IW4MAdmin
} }
} }
oldLines = lines; oldLines = lines;
l_size = logFile.Length(); l_size = LogFile.Length();
} }
#if DEBUG == false #if DEBUG == false
catch (SharedLibrary.Exceptions.NetworkException) catch (SharedLibrary.Exceptions.NetworkException)
@ -501,7 +473,7 @@ namespace IW4MAdmin
} }
this.Hostname = hostname.Value.StripColors(); this.Hostname = hostname.Value.StripColors();
this.CurrentMap = maps.Find(m => m.Name == mapname.Value) ?? new Map(mapname.Value, mapname.Value); this.CurrentMap = Maps.Find(m => m.Name == mapname.Value) ?? new Map(mapname.Value, mapname.Value);
this.MaxClients = maxplayers.Value; this.MaxClients = maxplayers.Value;
this.FSGame = game.Value; this.FSGame = game.Value;
@ -531,7 +503,7 @@ namespace IW4MAdmin
#endif #endif
} }
else else
logFile = new IFile(logPath); LogFile = new IFile(logPath);
Logger.WriteInfo("Log file is " + logPath); Logger.WriteInfo("Log file is " + logPath);
await ExecuteEvent(new Event(Event.GType.Start, "Server started", null, null, this)); await ExecuteEvent(new Event(Event.GType.Start, "Server started", null, null, this));
@ -543,26 +515,15 @@ namespace IW4MAdmin
//Process any server event //Process any server event
override protected async Task ProcessEvent(Event E) override protected async Task ProcessEvent(Event E)
{ {
//todo: move
while (ChatHistory.Count > Math.Ceiling((double)ClientNum / 2))
ChatHistory.RemoveAt(0);
if (E.Type == Event.GType.Connect) if (E.Type == Event.GType.Connect)
{ {
ChatHistory.Add(new Chat(E.Origin.Name, "<i>CONNECTED</i>", DateTime.Now)); ChatHistory.Add(new Chat(E.Origin.Name, "<i>CONNECTED</i>", DateTime.Now));
return;
} }
if (E.Type == Event.GType.Disconnect) if (E.Type == Event.GType.Disconnect)
{ {
ChatHistory.Add(new Chat(E.Origin.Name, "<i>DISCONNECTED</i>", DateTime.Now)); ChatHistory.Add(new Chat(E.Origin.Name, "<i>DISCONNECTED</i>", DateTime.Now));
// the last client hasn't fully disconnected yet
// so there will still be at least 1 client left
if (ClientNum < 2)
ChatHistory.Clear();
return;
} }
if (E.Type == Event.GType.Kill) if (E.Type == Event.GType.Kill)
@ -574,6 +535,15 @@ namespace IW4MAdmin
await ExecuteEvent(new Event(Event.GType.Death, "suicide", E.Target, null, this)); await ExecuteEvent(new Event(Event.GType.Death, "suicide", E.Target, null, this));
} }
//todo: move
while (ChatHistory.Count > Math.Ceiling((double)ClientNum / 2))
ChatHistory.RemoveAt(0);
// the last client hasn't fully disconnected yet
// so there will still be at least 1 client left
if (ClientNum < 2)
ChatHistory.Clear();
if (E.Type == Event.GType.Say) if (E.Type == Event.GType.Say)
{ {
if (E.Data.Length < 2) // ITS A LIE! if (E.Data.Length < 2) // ITS A LIE!
@ -643,7 +613,7 @@ namespace IW4MAdmin
FSGame = (await this.GetDvarAsync<string>("fs_game")).Value.StripColors(); FSGame = (await this.GetDvarAsync<string>("fs_game")).Value.StripColors();
string mapname = this.GetDvarAsync<string>("mapname").Result.Value; string mapname = this.GetDvarAsync<string>("mapname").Result.Value;
CurrentMap = maps.Find(m => m.Name == mapname) ?? new Map(mapname, mapname); CurrentMap = Maps.Find(m => m.Name == mapname) ?? new Map(mapname, mapname);
return; return;
} }
@ -779,9 +749,9 @@ namespace IW4MAdmin
catch (Exception E) catch (Exception E)
{ {
Logger.WriteError("Unable to reload configs! - " + E.Message); Logger.WriteError("Unable to reload configs! - " + E.Message);
messages = new List<String>(); BroadcastMessages = new List<String>();
maps = new List<Map>(); Maps = new List<Map>();
rules = new List<String>(); Rules = new List<String>();
return false; return false;
} }
} }

View File

@ -1,33 +1,23 @@
using System; using SharedLibrary;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text;
using System.Net; using System.Net;
using System.Text;
using SharedLibrary.Interfaces; using System.Threading.Tasks;
namespace IW4MAdmin namespace IW4MAdmin
{ {
public class ServerConfig : Serialize<ServerConfig> class ServerConfigurationGenerator
{ {
public string IP; public static ServerConfiguration Generate()
public int Port;
public string Password;
public string FtpPrefix;
public override string Filename()
{
return $"config/servers/{IP}_{Port}.cfg";
}
public static ServerConfig Generate()
{ {
string IP = String.Empty; string IP = String.Empty;
int Port = 0; int Port = 0;
string Password; string Password;
bool AllowMultipleOwners;
while(IP == String.Empty) while (IP == String.Empty)
{ {
try try
{ {
@ -43,7 +33,7 @@ namespace IW4MAdmin
} }
} }
while(Port == 0) while (Port == 0)
{ {
try try
{ {
@ -60,10 +50,13 @@ namespace IW4MAdmin
Console.Write("Enter server RCON password: "); Console.Write("Enter server RCON password: ");
Password = Console.ReadLine(); Password = Console.ReadLine();
var config = new ServerConfig() { IP = IP, Password = Password, Port = Port }; Console.Write("Allow multiple owners? [y/n]: ");
AllowMultipleOwners = (Console.ReadLine().ToLower().FirstOrDefault() as char?) == 'y';
var config = new ServerConfiguration() { IP = IP, Password = Password, Port = Port, AllowMultipleOwners = AllowMultipleOwners };
config.Write(); config.Write();
Console.WriteLine("Config saved, add another? [y/n]:"); Console.Write("Configuration saved, add another? [y/n]:");
if (Console.ReadLine().ToLower().First() == 'y') if (Console.ReadLine().ToLower().First() == 'y')
Generate(); Generate();

View File

@ -55,7 +55,7 @@ namespace IW4MAdmin
catch (Exception e) catch (Exception e)
{ {
Manager.GetInstance().Logger.WriteError($"Unable to start webservice ( port is probably in use ): {e.Message}"); ApplicationManager.GetInstance().Logger.WriteError($"Unable to start webservice ( port is probably in use ): {e.Message}");
} }
} }
@ -194,7 +194,7 @@ namespace IW4MAdmin
{ {
var info = new List<ServerInfo>(); var info = new List<ServerInfo>();
foreach (Server S in Manager.GetInstance().Servers) foreach (Server S in ApplicationManager.GetInstance().Servers)
{ {
ServerInfo eachServer = new ServerInfo() ServerInfo eachServer = new ServerInfo()
{ {
@ -307,11 +307,11 @@ namespace IW4MAdmin
if (querySet["server"] != null) if (querySet["server"] != null)
{ {
Server S = Manager.GetInstance().Servers.ToList().Find(x => (x.GetPort().ToString() == querySet["server"])); Server S = ApplicationManager.GetInstance().Servers.ToList().Find(x => (x.GetPort().ToString() == querySet["server"]));
if (S != null) if (S != null)
{ {
Player admin = Manager.GetInstance().GetClientDatabase().GetPlayer(querySet["IP"]); Player admin = ApplicationManager.GetInstance().GetClientDatabase().GetPlayer(querySet["IP"]);
if (admin == null) if (admin == null)
admin = new Player("RestUser", "-1", -1, (int)Player.Permission.User); admin = new Player("RestUser", "-1", -1, (int)Player.Permission.User);
@ -382,7 +382,7 @@ namespace IW4MAdmin
try try
{ {
//selectedPenalties = Manager.GetInstance().Servers.First().Bans.OrderByDescending(x => x.When).ToList().GetRange(Convert.ToInt32(querySet["from"]), 15); //selectedPenalties = Manager.GetInstance().Servers.First().Bans.OrderByDescending(x => x.When).ToList().GetRange(Convert.ToInt32(querySet["from"]), 15);
selectedPenalties = ((Manager.GetInstance().GetClientPenalties()) as PenaltyList).AsChronoList(Convert.ToInt32(querySet["from"]), 15).OrderByDescending(b => b.When).ToList(); selectedPenalties = ((ApplicationManager.GetInstance().GetClientPenalties()) as PenaltyList).AsChronoList(Convert.ToInt32(querySet["from"]), 15).OrderByDescending(b => b.When).ToList();
} }
catch (Exception) catch (Exception)
@ -394,8 +394,8 @@ namespace IW4MAdmin
foreach (var p in selectedPenalties) foreach (var p in selectedPenalties)
{ {
Player admin = Manager.GetInstance().GetClientDatabase().GetPlayer(p.PenaltyOriginID, 0); Player admin = ApplicationManager.GetInstance().GetClientDatabase().GetPlayer(p.PenaltyOriginID, 0);
Player penalized = Manager.GetInstance().GetClientDatabase().GetPlayer(p.OffenderID, 0); Player penalized = ApplicationManager.GetInstance().GetClientDatabase().GetPlayer(p.OffenderID, 0);
if (admin == null && penalized == null) if (admin == null && penalized == null)
continue; continue;
if (admin == null) if (admin == null)
@ -538,7 +538,7 @@ namespace IW4MAdmin
HttpResponse resp = new HttpResponse() HttpResponse resp = new HttpResponse()
{ {
contentType = GetContentType(), contentType = GetContentType(),
content = Newtonsoft.Json.JsonConvert.SerializeObject(((Manager.GetInstance().GetClientPenalties()) as PenaltyList).AsChronoList(Convert.ToInt32(querySet["from"]), 15), Newtonsoft.Json.Formatting.Indented, new Newtonsoft.Json.JsonConverter[] { new Newtonsoft.Json.Converters.StringEnumConverter() }), 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>() additionalHeaders = new Dictionary<string, string>()
}; };
return resp; return resp;
@ -631,27 +631,27 @@ namespace IW4MAdmin
contentType = GetContentType(), contentType = GetContentType(),
additionalHeaders = new Dictionary<string, string>() additionalHeaders = new Dictionary<string, string>()
}; };
bool authed = Manager.GetInstance().GetClientDatabase().GetAdmins().FindAll(x => x.IP == querySet["IP"]).Count > 0; bool authed = ApplicationManager.GetInstance().GetClientDatabase().GetAdmins().FindAll(x => x.IP == querySet["IP"]).Count > 0;
bool recent = false; bool recent = false;
if (querySet["id"] != null) if (querySet["id"] != null)
{ {
matchedPlayers.Add(Manager.GetInstance().GetClientDatabase().GetPlayer(Convert.ToInt32(querySet["id"]))); matchedPlayers.Add(ApplicationManager.GetInstance().GetClientDatabase().GetPlayer(Convert.ToInt32(querySet["id"])));
} }
else if (querySet["npID"] != null) else if (querySet["npID"] != null)
{ {
matchedPlayers.Add(Manager.GetInstance().GetClientDatabase().GetPlayers(new List<string> { querySet["npID"] }).First()); matchedPlayers.Add(ApplicationManager.GetInstance().GetClientDatabase().GetPlayers(new List<string> { querySet["npID"] }).First());
} }
else if (querySet["name"] != null) else if (querySet["name"] != null)
{ {
matchedPlayers = Manager.GetInstance().GetClientDatabase().FindPlayers(querySet["name"]); matchedPlayers = ApplicationManager.GetInstance().GetClientDatabase().FindPlayers(querySet["name"]);
} }
else if (querySet["recent"] != null) else if (querySet["recent"] != null)
{ {
matchedPlayers = Manager.GetInstance().GetClientDatabase().GetRecentPlayers(); matchedPlayers = ApplicationManager.GetInstance().GetClientDatabase().GetRecentPlayers();
recent = true; recent = true;
} }
@ -675,7 +675,7 @@ namespace IW4MAdmin
if (!recent) if (!recent)
{ {
foreach (var a in Manager.GetInstance().Servers.First().GetAliases(pp)) foreach (var a in ApplicationManager.GetInstance().Servers.First().GetAliases(pp))
{ {
eachPlayer.playerAliases = a.Names; eachPlayer.playerAliases = a.Names;
eachPlayer.playerIPs = a.IPS; eachPlayer.playerIPs = a.IPS;

Binary file not shown.

View File

@ -54,166 +54,166 @@ Global
Release-Stable|x86 = Release-Stable|x86 Release-Stable|x86 = Release-Stable|x86
EndGlobalSection EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution GlobalSection(ProjectConfigurationPlatforms) = postSolution
{DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Debug|Any CPU.ActiveCfg = Release-Stable|Any CPU {DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Debug|Any CPU.Build.0 = Release-Stable|Any CPU {DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Debug|Mixed Platforms.ActiveCfg = Release-Stable|Any CPU {DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Debug|Mixed Platforms.Build.0 = Release-Stable|Any CPU {DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Debug|x64.ActiveCfg = Release-Stable|Any CPU {DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Debug|x64.ActiveCfg = Debug|Any CPU
{DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Debug|x64.Build.0 = Release-Stable|Any CPU {DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Debug|x64.Build.0 = Debug|Any CPU
{DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Debug|x86.ActiveCfg = Release-Stable|Any CPU {DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Debug|x86.ActiveCfg = Debug|Any CPU
{DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Debug|x86.Build.0 = Release-Stable|Any CPU {DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Debug|x86.Build.0 = Debug|Any CPU
{DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release|Any CPU.ActiveCfg = Release-Stable|Any CPU {DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release|Any CPU.ActiveCfg = Debug|Any CPU
{DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release|Any CPU.Build.0 = Release-Stable|Any CPU {DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release|Any CPU.Build.0 = Debug|Any CPU
{DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release|Mixed Platforms.ActiveCfg = Release-Stable|Any CPU {DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release|Mixed Platforms.ActiveCfg = Debug|Any CPU
{DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release|Mixed Platforms.Build.0 = Release-Stable|Any CPU {DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release|Mixed Platforms.Build.0 = Debug|Any CPU
{DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release|x64.ActiveCfg = Release-Stable|Any CPU {DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release|x64.ActiveCfg = Debug|Any CPU
{DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release|x64.Build.0 = Release-Stable|Any CPU {DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release|x64.Build.0 = Debug|Any CPU
{DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release|x86.ActiveCfg = Release-Stable|Any CPU {DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release|x86.ActiveCfg = Debug|Any CPU
{DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release|x86.Build.0 = Release-Stable|Any CPU {DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release|x86.Build.0 = Debug|Any CPU
{DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release-Nightly|Any CPU.ActiveCfg = Release-Stable|Any CPU {DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release-Nightly|Any CPU.ActiveCfg = Debug|Any CPU
{DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release-Nightly|Any CPU.Build.0 = Release-Stable|Any CPU {DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release-Nightly|Any CPU.Build.0 = Debug|Any CPU
{DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release-Nightly|Mixed Platforms.ActiveCfg = Release-Stable|Any CPU {DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release-Nightly|Mixed Platforms.ActiveCfg = Debug|Any CPU
{DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release-Nightly|Mixed Platforms.Build.0 = Release-Stable|Any CPU {DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release-Nightly|Mixed Platforms.Build.0 = Debug|Any CPU
{DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release-Nightly|x64.ActiveCfg = Release-Stable|Any CPU {DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release-Nightly|x64.ActiveCfg = Debug|Any CPU
{DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release-Nightly|x64.Build.0 = Release-Stable|Any CPU {DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release-Nightly|x64.Build.0 = Debug|Any CPU
{DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release-Nightly|x86.ActiveCfg = Release-Stable|Any CPU {DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release-Nightly|x86.ActiveCfg = Debug|Any CPU
{DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release-Nightly|x86.Build.0 = Release-Stable|Any CPU {DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release-Nightly|x86.Build.0 = Debug|Any CPU
{DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release-Stable|Any CPU.ActiveCfg = Release-Stable|Any CPU {DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release-Stable|Any CPU.ActiveCfg = Debug|Any CPU
{DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release-Stable|Any CPU.Build.0 = Release-Stable|Any CPU {DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release-Stable|Any CPU.Build.0 = Debug|Any CPU
{DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release-Stable|Mixed Platforms.ActiveCfg = Release-Stable|Any CPU {DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release-Stable|Mixed Platforms.ActiveCfg = Debug|Any CPU
{DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release-Stable|Mixed Platforms.Build.0 = Release-Stable|Any CPU {DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release-Stable|Mixed Platforms.Build.0 = Debug|Any CPU
{DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release-Stable|x64.ActiveCfg = Release-Stable|Any CPU {DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release-Stable|x64.ActiveCfg = Debug|Any CPU
{DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release-Stable|x64.Build.0 = Release-Stable|Any CPU {DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release-Stable|x64.Build.0 = Debug|Any CPU
{DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release-Stable|x86.ActiveCfg = Release-Stable|Any CPU {DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release-Stable|x86.ActiveCfg = Debug|Any CPU
{DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release-Stable|x86.Build.0 = Release-Stable|Any CPU {DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release-Stable|x86.Build.0 = Debug|Any CPU
{4785AB75-66F3-4391-985D-63A5A049A0FA}.Debug|Any CPU.ActiveCfg = Release-Stable|Any CPU {4785AB75-66F3-4391-985D-63A5A049A0FA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4785AB75-66F3-4391-985D-63A5A049A0FA}.Debug|Any CPU.Build.0 = Release-Stable|Any CPU {4785AB75-66F3-4391-985D-63A5A049A0FA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4785AB75-66F3-4391-985D-63A5A049A0FA}.Debug|Mixed Platforms.ActiveCfg = Release-Stable|Any CPU {4785AB75-66F3-4391-985D-63A5A049A0FA}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{4785AB75-66F3-4391-985D-63A5A049A0FA}.Debug|Mixed Platforms.Build.0 = Release-Stable|Any CPU {4785AB75-66F3-4391-985D-63A5A049A0FA}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{4785AB75-66F3-4391-985D-63A5A049A0FA}.Debug|x64.ActiveCfg = Release-Stable|Any CPU {4785AB75-66F3-4391-985D-63A5A049A0FA}.Debug|x64.ActiveCfg = Debug|Any CPU
{4785AB75-66F3-4391-985D-63A5A049A0FA}.Debug|x64.Build.0 = Release-Stable|Any CPU {4785AB75-66F3-4391-985D-63A5A049A0FA}.Debug|x64.Build.0 = Debug|Any CPU
{4785AB75-66F3-4391-985D-63A5A049A0FA}.Debug|x86.ActiveCfg = Release-Stable|Any CPU {4785AB75-66F3-4391-985D-63A5A049A0FA}.Debug|x86.ActiveCfg = Debug|Any CPU
{4785AB75-66F3-4391-985D-63A5A049A0FA}.Debug|x86.Build.0 = Release-Stable|Any CPU {4785AB75-66F3-4391-985D-63A5A049A0FA}.Debug|x86.Build.0 = Debug|Any CPU
{4785AB75-66F3-4391-985D-63A5A049A0FA}.Release|Any CPU.ActiveCfg = Release-Stable|Any CPU {4785AB75-66F3-4391-985D-63A5A049A0FA}.Release|Any CPU.ActiveCfg = Debug|Any CPU
{4785AB75-66F3-4391-985D-63A5A049A0FA}.Release|Any CPU.Build.0 = Release-Stable|Any CPU {4785AB75-66F3-4391-985D-63A5A049A0FA}.Release|Any CPU.Build.0 = Debug|Any CPU
{4785AB75-66F3-4391-985D-63A5A049A0FA}.Release|Mixed Platforms.ActiveCfg = Release-Stable|Any CPU {4785AB75-66F3-4391-985D-63A5A049A0FA}.Release|Mixed Platforms.ActiveCfg = Debug|Any CPU
{4785AB75-66F3-4391-985D-63A5A049A0FA}.Release|Mixed Platforms.Build.0 = Release-Stable|Any CPU {4785AB75-66F3-4391-985D-63A5A049A0FA}.Release|Mixed Platforms.Build.0 = Debug|Any CPU
{4785AB75-66F3-4391-985D-63A5A049A0FA}.Release|x64.ActiveCfg = Release-Stable|Any CPU {4785AB75-66F3-4391-985D-63A5A049A0FA}.Release|x64.ActiveCfg = Debug|Any CPU
{4785AB75-66F3-4391-985D-63A5A049A0FA}.Release|x64.Build.0 = Release-Stable|Any CPU {4785AB75-66F3-4391-985D-63A5A049A0FA}.Release|x64.Build.0 = Debug|Any CPU
{4785AB75-66F3-4391-985D-63A5A049A0FA}.Release|x86.ActiveCfg = Release-Stable|Any CPU {4785AB75-66F3-4391-985D-63A5A049A0FA}.Release|x86.ActiveCfg = Debug|Any CPU
{4785AB75-66F3-4391-985D-63A5A049A0FA}.Release|x86.Build.0 = Release-Stable|Any CPU {4785AB75-66F3-4391-985D-63A5A049A0FA}.Release|x86.Build.0 = Debug|Any CPU
{4785AB75-66F3-4391-985D-63A5A049A0FA}.Release-Nightly|Any CPU.ActiveCfg = Release-Stable|Any CPU {4785AB75-66F3-4391-985D-63A5A049A0FA}.Release-Nightly|Any CPU.ActiveCfg = Debug|Any CPU
{4785AB75-66F3-4391-985D-63A5A049A0FA}.Release-Nightly|Any CPU.Build.0 = Release-Stable|Any CPU {4785AB75-66F3-4391-985D-63A5A049A0FA}.Release-Nightly|Any CPU.Build.0 = Debug|Any CPU
{4785AB75-66F3-4391-985D-63A5A049A0FA}.Release-Nightly|Mixed Platforms.ActiveCfg = Release-Stable|Any CPU {4785AB75-66F3-4391-985D-63A5A049A0FA}.Release-Nightly|Mixed Platforms.ActiveCfg = Debug|Any CPU
{4785AB75-66F3-4391-985D-63A5A049A0FA}.Release-Nightly|Mixed Platforms.Build.0 = Release-Stable|Any CPU {4785AB75-66F3-4391-985D-63A5A049A0FA}.Release-Nightly|Mixed Platforms.Build.0 = Debug|Any CPU
{4785AB75-66F3-4391-985D-63A5A049A0FA}.Release-Nightly|x64.ActiveCfg = Release-Stable|Any CPU {4785AB75-66F3-4391-985D-63A5A049A0FA}.Release-Nightly|x64.ActiveCfg = Debug|Any CPU
{4785AB75-66F3-4391-985D-63A5A049A0FA}.Release-Nightly|x64.Build.0 = Release-Stable|Any CPU {4785AB75-66F3-4391-985D-63A5A049A0FA}.Release-Nightly|x64.Build.0 = Debug|Any CPU
{4785AB75-66F3-4391-985D-63A5A049A0FA}.Release-Nightly|x86.ActiveCfg = Release-Stable|Any CPU {4785AB75-66F3-4391-985D-63A5A049A0FA}.Release-Nightly|x86.ActiveCfg = Debug|Any CPU
{4785AB75-66F3-4391-985D-63A5A049A0FA}.Release-Nightly|x86.Build.0 = Release-Stable|Any CPU {4785AB75-66F3-4391-985D-63A5A049A0FA}.Release-Nightly|x86.Build.0 = Debug|Any CPU
{4785AB75-66F3-4391-985D-63A5A049A0FA}.Release-Stable|Any CPU.ActiveCfg = Release-Stable|Any CPU {4785AB75-66F3-4391-985D-63A5A049A0FA}.Release-Stable|Any CPU.ActiveCfg = Debug|Any CPU
{4785AB75-66F3-4391-985D-63A5A049A0FA}.Release-Stable|Any CPU.Build.0 = Release-Stable|Any CPU {4785AB75-66F3-4391-985D-63A5A049A0FA}.Release-Stable|Any CPU.Build.0 = Debug|Any CPU
{4785AB75-66F3-4391-985D-63A5A049A0FA}.Release-Stable|Mixed Platforms.ActiveCfg = Release-Stable|Any CPU {4785AB75-66F3-4391-985D-63A5A049A0FA}.Release-Stable|Mixed Platforms.ActiveCfg = Debug|Any CPU
{4785AB75-66F3-4391-985D-63A5A049A0FA}.Release-Stable|Mixed Platforms.Build.0 = Release-Stable|Any CPU {4785AB75-66F3-4391-985D-63A5A049A0FA}.Release-Stable|Mixed Platforms.Build.0 = Debug|Any CPU
{4785AB75-66F3-4391-985D-63A5A049A0FA}.Release-Stable|x64.ActiveCfg = Release-Stable|Any CPU {4785AB75-66F3-4391-985D-63A5A049A0FA}.Release-Stable|x64.ActiveCfg = Debug|Any CPU
{4785AB75-66F3-4391-985D-63A5A049A0FA}.Release-Stable|x64.Build.0 = Release-Stable|Any CPU {4785AB75-66F3-4391-985D-63A5A049A0FA}.Release-Stable|x64.Build.0 = Debug|Any CPU
{4785AB75-66F3-4391-985D-63A5A049A0FA}.Release-Stable|x86.ActiveCfg = Release-Stable|Any CPU {4785AB75-66F3-4391-985D-63A5A049A0FA}.Release-Stable|x86.ActiveCfg = Debug|Any CPU
{4785AB75-66F3-4391-985D-63A5A049A0FA}.Release-Stable|x86.Build.0 = Release-Stable|Any CPU {4785AB75-66F3-4391-985D-63A5A049A0FA}.Release-Stable|x86.Build.0 = Debug|Any CPU
{D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Debug|Any CPU.ActiveCfg = Release-Stable|Any CPU {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Debug|Any CPU.Build.0 = Release-Stable|Any CPU {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Debug|Mixed Platforms.ActiveCfg = Release-Stable|Any CPU {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Debug|Mixed Platforms.Build.0 = Release-Stable|Any CPU {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Debug|x64.ActiveCfg = Release-Stable|Any CPU {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Debug|x64.ActiveCfg = Debug|Any CPU
{D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Debug|x64.Build.0 = Release-Stable|Any CPU {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Debug|x64.Build.0 = Debug|Any CPU
{D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Debug|x86.ActiveCfg = Release-Stable|Any CPU {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Debug|x86.ActiveCfg = Debug|Any CPU
{D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Debug|x86.Build.0 = Release-Stable|Any CPU {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Debug|x86.Build.0 = Debug|Any CPU
{D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release|Any CPU.ActiveCfg = Release-Stable|Any CPU {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release|Any CPU.ActiveCfg = Debug|Any CPU
{D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release|Any CPU.Build.0 = Release-Stable|Any CPU {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release|Any CPU.Build.0 = Debug|Any CPU
{D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release|Mixed Platforms.ActiveCfg = Release-Stable|Any CPU {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release|Mixed Platforms.ActiveCfg = Debug|Any CPU
{D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release|Mixed Platforms.Build.0 = Release-Stable|Any CPU {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release|Mixed Platforms.Build.0 = Debug|Any CPU
{D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release|x64.ActiveCfg = Release-Stable|Any CPU {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release|x64.ActiveCfg = Debug|Any CPU
{D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release|x64.Build.0 = Release-Stable|Any CPU {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release|x64.Build.0 = Debug|Any CPU
{D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release|x86.ActiveCfg = Release-Stable|Any CPU {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release|x86.ActiveCfg = Debug|Any CPU
{D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release|x86.Build.0 = Release-Stable|Any CPU {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release|x86.Build.0 = Debug|Any CPU
{D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release-Nightly|Any CPU.ActiveCfg = Release-Stable|Any CPU {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release-Nightly|Any CPU.ActiveCfg = Debug|Any CPU
{D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release-Nightly|Any CPU.Build.0 = Release-Stable|Any CPU {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release-Nightly|Any CPU.Build.0 = Debug|Any CPU
{D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release-Nightly|Mixed Platforms.ActiveCfg = Release-Stable|Any CPU {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release-Nightly|Mixed Platforms.ActiveCfg = Debug|Any CPU
{D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release-Nightly|Mixed Platforms.Build.0 = Release-Stable|Any CPU {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release-Nightly|Mixed Platforms.Build.0 = Debug|Any CPU
{D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release-Nightly|x64.ActiveCfg = Release-Stable|Any CPU {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release-Nightly|x64.ActiveCfg = Debug|Any CPU
{D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release-Nightly|x64.Build.0 = Release-Stable|Any CPU {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release-Nightly|x64.Build.0 = Debug|Any CPU
{D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release-Nightly|x86.ActiveCfg = Release-Stable|Any CPU {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release-Nightly|x86.ActiveCfg = Debug|Any CPU
{D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release-Nightly|x86.Build.0 = Release-Stable|Any CPU {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release-Nightly|x86.Build.0 = Debug|Any CPU
{D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release-Stable|Any CPU.ActiveCfg = Release-Stable|Any CPU {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release-Stable|Any CPU.ActiveCfg = Debug|Any CPU
{D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release-Stable|Any CPU.Build.0 = Release-Stable|Any CPU {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release-Stable|Any CPU.Build.0 = Debug|Any CPU
{D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release-Stable|Mixed Platforms.ActiveCfg = Release-Stable|Any CPU {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release-Stable|Mixed Platforms.ActiveCfg = Debug|Any CPU
{D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release-Stable|Mixed Platforms.Build.0 = Release-Stable|Any CPU {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release-Stable|Mixed Platforms.Build.0 = Debug|Any CPU
{D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release-Stable|x64.ActiveCfg = Release-Stable|Any CPU {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release-Stable|x64.ActiveCfg = Debug|Any CPU
{D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release-Stable|x64.Build.0 = Release-Stable|Any CPU {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release-Stable|x64.Build.0 = Debug|Any CPU
{D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release-Stable|x86.ActiveCfg = Release-Stable|Any CPU {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release-Stable|x86.ActiveCfg = Debug|Any CPU
{D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release-Stable|x86.Build.0 = Release-Stable|Any CPU {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release-Stable|x86.Build.0 = Debug|Any CPU
{AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Debug|Any CPU.ActiveCfg = Release-Stable|Any CPU {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Debug|Any CPU.Build.0 = Release-Stable|Any CPU {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Debug|Mixed Platforms.ActiveCfg = Release-Stable|Any CPU {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Debug|Mixed Platforms.Build.0 = Release-Stable|Any CPU {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Debug|x64.ActiveCfg = Release-Stable|Any CPU {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Debug|x64.ActiveCfg = Debug|Any CPU
{AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Debug|x64.Build.0 = Release-Stable|Any CPU {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Debug|x64.Build.0 = Debug|Any CPU
{AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Debug|x86.ActiveCfg = Release-Stable|Any CPU {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Debug|x86.ActiveCfg = Debug|Any CPU
{AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Debug|x86.Build.0 = Release-Stable|Any CPU {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Debug|x86.Build.0 = Debug|Any CPU
{AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release|Any CPU.ActiveCfg = Release-Stable|Any CPU {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release|Any CPU.ActiveCfg = Debug|Any CPU
{AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release|Any CPU.Build.0 = Release-Stable|Any CPU {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release|Any CPU.Build.0 = Debug|Any CPU
{AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release|Mixed Platforms.ActiveCfg = Release-Stable|Any CPU {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release|Mixed Platforms.ActiveCfg = Debug|Any CPU
{AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release|Mixed Platforms.Build.0 = Release-Stable|Any CPU {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release|Mixed Platforms.Build.0 = Debug|Any CPU
{AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release|x64.ActiveCfg = Release-Stable|Any CPU {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release|x64.ActiveCfg = Debug|Any CPU
{AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release|x64.Build.0 = Release-Stable|Any CPU {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release|x64.Build.0 = Debug|Any CPU
{AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release|x86.ActiveCfg = Release-Stable|Any CPU {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release|x86.ActiveCfg = Debug|Any CPU
{AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release|x86.Build.0 = Release-Stable|Any CPU {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release|x86.Build.0 = Debug|Any CPU
{AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release-Nightly|Any CPU.ActiveCfg = Release-Stable|Any CPU {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release-Nightly|Any CPU.ActiveCfg = Debug|Any CPU
{AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release-Nightly|Any CPU.Build.0 = Release-Stable|Any CPU {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release-Nightly|Any CPU.Build.0 = Debug|Any CPU
{AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release-Nightly|Mixed Platforms.ActiveCfg = Release-Stable|Any CPU {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release-Nightly|Mixed Platforms.ActiveCfg = Debug|Any CPU
{AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release-Nightly|Mixed Platforms.Build.0 = Release-Stable|Any CPU {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release-Nightly|Mixed Platforms.Build.0 = Debug|Any CPU
{AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release-Nightly|x64.ActiveCfg = Release-Stable|Any CPU {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release-Nightly|x64.ActiveCfg = Debug|Any CPU
{AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release-Nightly|x64.Build.0 = Release-Stable|Any CPU {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release-Nightly|x64.Build.0 = Debug|Any CPU
{AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release-Nightly|x86.ActiveCfg = Release-Stable|Any CPU {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release-Nightly|x86.ActiveCfg = Debug|Any CPU
{AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release-Nightly|x86.Build.0 = Release-Stable|Any CPU {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release-Nightly|x86.Build.0 = Debug|Any CPU
{AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release-Stable|Any CPU.ActiveCfg = Release-Stable|Any CPU {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release-Stable|Any CPU.ActiveCfg = Debug|Any CPU
{AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release-Stable|Any CPU.Build.0 = Release-Stable|Any CPU {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release-Stable|Any CPU.Build.0 = Debug|Any CPU
{AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release-Stable|Mixed Platforms.ActiveCfg = Release-Stable|Any CPU {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release-Stable|Mixed Platforms.ActiveCfg = Debug|Any CPU
{AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release-Stable|Mixed Platforms.Build.0 = Release-Stable|Any CPU {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release-Stable|Mixed Platforms.Build.0 = Debug|Any CPU
{AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release-Stable|x64.ActiveCfg = Release-Stable|Any CPU {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release-Stable|x64.ActiveCfg = Debug|Any CPU
{AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release-Stable|x64.Build.0 = Release-Stable|Any CPU {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release-Stable|x64.Build.0 = Debug|Any CPU
{AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release-Stable|x86.ActiveCfg = Release-Stable|Any CPU {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release-Stable|x86.ActiveCfg = Debug|Any CPU
{AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release-Stable|x86.Build.0 = Release-Stable|Any CPU {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release-Stable|x86.Build.0 = Debug|Any CPU
{428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Debug|Any CPU.ActiveCfg = Release-Stable|Any CPU {428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Debug|Any CPU.Build.0 = Release-Stable|Any CPU {428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Debug|Mixed Platforms.ActiveCfg = Release-Stable|Any CPU {428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Debug|Mixed Platforms.Build.0 = Release-Stable|Any CPU {428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Debug|x64.ActiveCfg = Release-Stable|Any CPU {428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Debug|x64.ActiveCfg = Debug|Any CPU
{428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Debug|x64.Build.0 = Release-Stable|Any CPU {428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Debug|x64.Build.0 = Debug|Any CPU
{428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Debug|x86.ActiveCfg = Release-Stable|Any CPU {428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Debug|x86.ActiveCfg = Debug|Any CPU
{428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Debug|x86.Build.0 = Release-Stable|Any CPU {428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Debug|x86.Build.0 = Debug|Any CPU
{428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release|Any CPU.ActiveCfg = Release-Stable|Any CPU {428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release|Any CPU.ActiveCfg = Debug|Any CPU
{428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release|Any CPU.Build.0 = Release-Stable|Any CPU {428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release|Any CPU.Build.0 = Debug|Any CPU
{428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release|Mixed Platforms.ActiveCfg = Release-Stable|Any CPU {428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release|Mixed Platforms.ActiveCfg = Debug|Any CPU
{428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release|Mixed Platforms.Build.0 = Release-Stable|Any CPU {428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release|Mixed Platforms.Build.0 = Debug|Any CPU
{428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release|x64.ActiveCfg = Release-Stable|Any CPU {428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release|x64.ActiveCfg = Debug|Any CPU
{428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release|x64.Build.0 = Release-Stable|Any CPU {428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release|x64.Build.0 = Debug|Any CPU
{428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release|x86.ActiveCfg = Release-Stable|Any CPU {428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release|x86.ActiveCfg = Debug|Any CPU
{428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release|x86.Build.0 = Release-Stable|Any CPU {428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release|x86.Build.0 = Debug|Any CPU
{428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release-Nightly|Any CPU.ActiveCfg = Release-Stable|Any CPU {428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release-Nightly|Any CPU.ActiveCfg = Debug|Any CPU
{428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release-Nightly|Any CPU.Build.0 = Release-Stable|Any CPU {428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release-Nightly|Any CPU.Build.0 = Debug|Any CPU
{428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release-Nightly|Mixed Platforms.ActiveCfg = Release-Stable|Any CPU {428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release-Nightly|Mixed Platforms.ActiveCfg = Debug|Any CPU
{428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release-Nightly|Mixed Platforms.Build.0 = Release-Stable|Any CPU {428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release-Nightly|Mixed Platforms.Build.0 = Debug|Any CPU
{428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release-Nightly|x64.ActiveCfg = Release-Stable|Any CPU {428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release-Nightly|x64.ActiveCfg = Debug|Any CPU
{428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release-Nightly|x64.Build.0 = Release-Stable|Any CPU {428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release-Nightly|x64.Build.0 = Debug|Any CPU
{428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release-Nightly|x86.ActiveCfg = Release-Stable|Any CPU {428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release-Nightly|x86.ActiveCfg = Debug|Any CPU
{428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release-Nightly|x86.Build.0 = Release-Stable|Any CPU {428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release-Nightly|x86.Build.0 = Debug|Any CPU
{428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release-Stable|Any CPU.ActiveCfg = Release-Stable|Any CPU {428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release-Stable|Any CPU.ActiveCfg = Debug|Any CPU
{428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release-Stable|Any CPU.Build.0 = Release-Stable|Any CPU {428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release-Stable|Any CPU.Build.0 = Debug|Any CPU
{428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release-Stable|Mixed Platforms.ActiveCfg = Release-Stable|Any CPU {428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release-Stable|Mixed Platforms.ActiveCfg = Debug|Any CPU
{428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release-Stable|Mixed Platforms.Build.0 = Release-Stable|Any CPU {428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release-Stable|Mixed Platforms.Build.0 = Debug|Any CPU
{428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release-Stable|x64.ActiveCfg = Release-Stable|Any CPU {428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release-Stable|x64.ActiveCfg = Debug|Any CPU
{428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release-Stable|x64.Build.0 = Release-Stable|Any CPU {428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release-Stable|x64.Build.0 = Debug|Any CPU
{428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release-Stable|x86.ActiveCfg = Release-Stable|Any CPU {428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release-Stable|x86.ActiveCfg = Debug|Any CPU
{428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release-Stable|x86.Build.0 = Release-Stable|Any CPU {428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release-Stable|x86.Build.0 = Debug|Any CPU
{E46C85BD-A99C-484E-BCCE-0F1831C5925E}.Debug|Any CPU.ActiveCfg = Release-Stable|Any CPU {E46C85BD-A99C-484E-BCCE-0F1831C5925E}.Debug|Any CPU.ActiveCfg = Release-Stable|Any CPU
{E46C85BD-A99C-484E-BCCE-0F1831C5925E}.Debug|Mixed Platforms.ActiveCfg = Release-Stable|Any CPU {E46C85BD-A99C-484E-BCCE-0F1831C5925E}.Debug|Mixed Platforms.ActiveCfg = Release-Stable|Any CPU
{E46C85BD-A99C-484E-BCCE-0F1831C5925E}.Debug|x64.ActiveCfg = Release-Stable|Any CPU {E46C85BD-A99C-484E-BCCE-0F1831C5925E}.Debug|x64.ActiveCfg = Release-Stable|Any CPU
@ -230,70 +230,70 @@ Global
{E46C85BD-A99C-484E-BCCE-0F1831C5925E}.Release-Stable|Mixed Platforms.ActiveCfg = Release-Stable|Any CPU {E46C85BD-A99C-484E-BCCE-0F1831C5925E}.Release-Stable|Mixed Platforms.ActiveCfg = Release-Stable|Any CPU
{E46C85BD-A99C-484E-BCCE-0F1831C5925E}.Release-Stable|x64.ActiveCfg = Release-Stable|Any CPU {E46C85BD-A99C-484E-BCCE-0F1831C5925E}.Release-Stable|x64.ActiveCfg = Release-Stable|Any CPU
{E46C85BD-A99C-484E-BCCE-0F1831C5925E}.Release-Stable|x86.ActiveCfg = Release-Stable|Any CPU {E46C85BD-A99C-484E-BCCE-0F1831C5925E}.Release-Stable|x86.ActiveCfg = Release-Stable|Any CPU
{C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Debug|Any CPU.ActiveCfg = Release-Stable|Any CPU {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Debug|Any CPU.Build.0 = Release-Stable|Any CPU {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Debug|Mixed Platforms.ActiveCfg = Release-Stable|Any CPU {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Debug|Mixed Platforms.Build.0 = Release-Stable|Any CPU {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Debug|x64.ActiveCfg = Release-Stable|Any CPU {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Debug|x64.ActiveCfg = Debug|Any CPU
{C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Debug|x64.Build.0 = Release-Stable|Any CPU {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Debug|x64.Build.0 = Debug|Any CPU
{C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Debug|x86.ActiveCfg = Release-Stable|Any CPU {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Debug|x86.ActiveCfg = Debug|Any CPU
{C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Debug|x86.Build.0 = Release-Stable|Any CPU {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Debug|x86.Build.0 = Debug|Any CPU
{C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release|Any CPU.ActiveCfg = Release-Stable|Any CPU {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release|Any CPU.ActiveCfg = Debug|Any CPU
{C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release|Any CPU.Build.0 = Release-Stable|Any CPU {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release|Any CPU.Build.0 = Debug|Any CPU
{C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release|Mixed Platforms.ActiveCfg = Release-Stable|Any CPU {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release|Mixed Platforms.ActiveCfg = Debug|Any CPU
{C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release|Mixed Platforms.Build.0 = Release-Stable|Any CPU {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release|Mixed Platforms.Build.0 = Debug|Any CPU
{C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release|x64.ActiveCfg = Release-Stable|Any CPU {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release|x64.ActiveCfg = Debug|Any CPU
{C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release|x64.Build.0 = Release-Stable|Any CPU {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release|x64.Build.0 = Debug|Any CPU
{C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release|x86.ActiveCfg = Release-Stable|Any CPU {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release|x86.ActiveCfg = Debug|Any CPU
{C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release|x86.Build.0 = Release-Stable|Any CPU {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release|x86.Build.0 = Debug|Any CPU
{C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release-Nightly|Any CPU.ActiveCfg = Release-Stable|Any CPU {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release-Nightly|Any CPU.ActiveCfg = Debug|Any CPU
{C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release-Nightly|Any CPU.Build.0 = Release-Stable|Any CPU {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release-Nightly|Any CPU.Build.0 = Debug|Any CPU
{C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release-Nightly|Mixed Platforms.ActiveCfg = Release-Stable|Any CPU {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release-Nightly|Mixed Platforms.ActiveCfg = Debug|Any CPU
{C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release-Nightly|Mixed Platforms.Build.0 = Release-Stable|Any CPU {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release-Nightly|Mixed Platforms.Build.0 = Debug|Any CPU
{C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release-Nightly|x64.ActiveCfg = Release-Stable|Any CPU {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release-Nightly|x64.ActiveCfg = Debug|Any CPU
{C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release-Nightly|x64.Build.0 = Release-Stable|Any CPU {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release-Nightly|x64.Build.0 = Debug|Any CPU
{C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release-Nightly|x86.ActiveCfg = Release-Stable|Any CPU {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release-Nightly|x86.ActiveCfg = Debug|Any CPU
{C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release-Nightly|x86.Build.0 = Release-Stable|Any CPU {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release-Nightly|x86.Build.0 = Debug|Any CPU
{C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release-Stable|Any CPU.ActiveCfg = Release-Stable|Any CPU {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release-Stable|Any CPU.ActiveCfg = Debug|Any CPU
{C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release-Stable|Any CPU.Build.0 = Release-Stable|Any CPU {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release-Stable|Any CPU.Build.0 = Debug|Any CPU
{C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release-Stable|Mixed Platforms.ActiveCfg = Release-Stable|Any CPU {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release-Stable|Mixed Platforms.ActiveCfg = Debug|Any CPU
{C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release-Stable|Mixed Platforms.Build.0 = Release-Stable|Any CPU {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release-Stable|Mixed Platforms.Build.0 = Debug|Any CPU
{C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release-Stable|x64.ActiveCfg = Release-Stable|Any CPU {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release-Stable|x64.ActiveCfg = Debug|Any CPU
{C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release-Stable|x64.Build.0 = Release-Stable|Any CPU {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release-Stable|x64.Build.0 = Debug|Any CPU
{C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release-Stable|x86.ActiveCfg = Release-Stable|Any CPU {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release-Stable|x86.ActiveCfg = Debug|Any CPU
{C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release-Stable|x86.Build.0 = Release-Stable|Any CPU {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release-Stable|x86.Build.0 = Debug|Any CPU
{1479DE87-ACB5-4046-81C8-A0BA5041227D}.Debug|Any CPU.ActiveCfg = Release|Any CPU {1479DE87-ACB5-4046-81C8-A0BA5041227D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1479DE87-ACB5-4046-81C8-A0BA5041227D}.Debug|Any CPU.Build.0 = Release|Any CPU {1479DE87-ACB5-4046-81C8-A0BA5041227D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1479DE87-ACB5-4046-81C8-A0BA5041227D}.Debug|Mixed Platforms.ActiveCfg = Release|Any CPU {1479DE87-ACB5-4046-81C8-A0BA5041227D}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{1479DE87-ACB5-4046-81C8-A0BA5041227D}.Debug|Mixed Platforms.Build.0 = Release|Any CPU {1479DE87-ACB5-4046-81C8-A0BA5041227D}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{1479DE87-ACB5-4046-81C8-A0BA5041227D}.Debug|x64.ActiveCfg = Release|Any CPU {1479DE87-ACB5-4046-81C8-A0BA5041227D}.Debug|x64.ActiveCfg = Debug|Any CPU
{1479DE87-ACB5-4046-81C8-A0BA5041227D}.Debug|x64.Build.0 = Release|Any CPU {1479DE87-ACB5-4046-81C8-A0BA5041227D}.Debug|x64.Build.0 = Debug|Any CPU
{1479DE87-ACB5-4046-81C8-A0BA5041227D}.Debug|x86.ActiveCfg = Release|Any CPU {1479DE87-ACB5-4046-81C8-A0BA5041227D}.Debug|x86.ActiveCfg = Debug|Any CPU
{1479DE87-ACB5-4046-81C8-A0BA5041227D}.Debug|x86.Build.0 = Release|Any CPU {1479DE87-ACB5-4046-81C8-A0BA5041227D}.Debug|x86.Build.0 = Debug|Any CPU
{1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release|Any CPU.ActiveCfg = Release|Any CPU {1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release|Any CPU.ActiveCfg = Debug|Any CPU
{1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release|Any CPU.Build.0 = Release|Any CPU {1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release|Any CPU.Build.0 = Debug|Any CPU
{1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU {1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release|Mixed Platforms.ActiveCfg = Debug|Any CPU
{1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release|Mixed Platforms.Build.0 = Release|Any CPU {1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release|Mixed Platforms.Build.0 = Debug|Any CPU
{1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release|x64.ActiveCfg = Release|Any CPU {1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release|x64.ActiveCfg = Debug|Any CPU
{1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release|x64.Build.0 = Release|Any CPU {1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release|x64.Build.0 = Debug|Any CPU
{1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release|x86.ActiveCfg = Release|Any CPU {1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release|x86.ActiveCfg = Debug|Any CPU
{1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release|x86.Build.0 = Release|Any CPU {1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release|x86.Build.0 = Debug|Any CPU
{1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release-Nightly|Any CPU.ActiveCfg = Release|Any CPU {1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release-Nightly|Any CPU.ActiveCfg = Debug|Any CPU
{1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release-Nightly|Any CPU.Build.0 = Release|Any CPU {1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release-Nightly|Any CPU.Build.0 = Debug|Any CPU
{1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release-Nightly|Mixed Platforms.ActiveCfg = Release|Any CPU {1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release-Nightly|Mixed Platforms.ActiveCfg = Debug|Any CPU
{1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release-Nightly|Mixed Platforms.Build.0 = Release|Any CPU {1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release-Nightly|Mixed Platforms.Build.0 = Debug|Any CPU
{1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release-Nightly|x64.ActiveCfg = Release|Any CPU {1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release-Nightly|x64.ActiveCfg = Debug|Any CPU
{1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release-Nightly|x64.Build.0 = Release|Any CPU {1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release-Nightly|x64.Build.0 = Debug|Any CPU
{1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release-Nightly|x86.ActiveCfg = Release|Any CPU {1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release-Nightly|x86.ActiveCfg = Debug|Any CPU
{1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release-Nightly|x86.Build.0 = Release|Any CPU {1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release-Nightly|x86.Build.0 = Debug|Any CPU
{1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release-Stable|Any CPU.ActiveCfg = Release|Any CPU {1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release-Stable|Any CPU.ActiveCfg = Debug|Any CPU
{1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release-Stable|Any CPU.Build.0 = Release|Any CPU {1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release-Stable|Any CPU.Build.0 = Debug|Any CPU
{1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release-Stable|Mixed Platforms.ActiveCfg = Release|Any CPU {1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release-Stable|Mixed Platforms.ActiveCfg = Debug|Any CPU
{1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release-Stable|Mixed Platforms.Build.0 = Release|Any CPU {1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release-Stable|Mixed Platforms.Build.0 = Debug|Any CPU
{1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release-Stable|x64.ActiveCfg = Release|Any CPU {1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release-Stable|x64.ActiveCfg = Debug|Any CPU
{1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release-Stable|x64.Build.0 = Release|Any CPU {1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release-Stable|x64.Build.0 = Debug|Any CPU
{1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release-Stable|x86.ActiveCfg = Release|Any CPU {1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release-Stable|x86.ActiveCfg = Debug|Any CPU
{1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release-Stable|x86.Build.0 = Release|Any CPU {1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release-Stable|x86.Build.0 = Debug|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE

View File

@ -38,7 +38,7 @@ namespace Votemap_Plugin
{ {
string mapSearch = E.Data.ToLower().Trim(); string mapSearch = E.Data.ToLower().Trim();
// probably not the most optimized way to match the map.. but nothing is time critical here // probably not the most optimized way to match the map.. but nothing is time critical here
Map votedMap = E.Owner.maps.Find(m => (m.Alias.ToLower().Contains(mapSearch) || m.Name.Contains(mapSearch))); Map votedMap = E.Owner.Maps.Find(m => (m.Alias.ToLower().Contains(mapSearch) || m.Name.Contains(mapSearch)));
if (votedMap == null) if (votedMap == null)
await E.Origin.Tell("^1" + E.Data + " is not a recognized map"); await E.Origin.Tell("^1" + E.Data + " is not a recognized map");
else else

View File

@ -7,7 +7,7 @@ using System.Threading.Tasks;
namespace SharedLibrary.Commands namespace SharedLibrary.Commands
{ {
class CQuit : Command public class CQuit : Command
{ {
public CQuit(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { } public CQuit(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { }
@ -17,7 +17,7 @@ namespace SharedLibrary.Commands
} }
} }
class COwner : Command public 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 COwner(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { }
@ -27,7 +27,6 @@ namespace SharedLibrary.Commands
{ {
E.Origin.SetLevel(Player.Permission.Owner); E.Origin.SetLevel(Player.Permission.Owner);
await E.Origin.Tell("Congratulations, you have claimed ownership of this server!"); await E.Origin.Tell("Congratulations, you have claimed ownership of this server!");
E.Owner.owner = E.Origin;
E.Owner.Manager.GetClientDatabase().UpdatePlayer(E.Origin); E.Owner.Manager.GetClientDatabase().UpdatePlayer(E.Origin);
} }
else else
@ -35,7 +34,7 @@ namespace SharedLibrary.Commands
} }
} }
class Cwarn : Command public class Cwarn : Command
{ {
public Cwarn(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { } public Cwarn(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { }
@ -43,13 +42,13 @@ namespace SharedLibrary.Commands
{ {
E.Target.lastOffense = E.Data.RemoveWords(1); E.Target.lastOffense = E.Data.RemoveWords(1);
if (E.Origin.Level <= E.Target.Level) if (E.Origin.Level <= E.Target.Level)
await E.Origin.Tell("You cannot warn " + E.Target.Name); await E.Origin.Tell($"You do not have the required privileges to warn {E.Target.Name}");
else else
await E.Target.Warn(E.Target.lastOffense, E.Origin); await E.Target.Warn(E.Target.lastOffense, E.Origin);
} }
} }
class CWarnClear : Command public class CWarnClear : Command
{ {
public CWarnClear(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { } public CWarnClear(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { }
@ -62,7 +61,7 @@ namespace SharedLibrary.Commands
} }
} }
class CKick : Command public class CKick : Command
{ {
public CKick(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { } public CKick(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { }
@ -70,13 +69,16 @@ namespace SharedLibrary.Commands
{ {
E.Target.lastOffense = E.Data.RemoveWords(1); E.Target.lastOffense = E.Data.RemoveWords(1);
if (E.Origin.Level > E.Target.Level) if (E.Origin.Level > E.Target.Level)
{
await E.Owner.ExecuteEvent(new Event(Event.GType.Kick, E.Data, E.Origin, E.Target, E.Owner));
await E.Target.Kick(E.Target.lastOffense, E.Origin); await E.Target.Kick(E.Target.lastOffense, E.Origin);
}
else else
await E.Origin.Tell($"You cannot kick {E.Target.Name}"); await E.Origin.Tell($"You do not have the required privileges to kick {E.Target.Name}");
} }
} }
class CSay : Command public class CSay : Command
{ {
public CSay(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { } public CSay(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { }
@ -86,13 +88,13 @@ namespace SharedLibrary.Commands
} }
} }
class CTempBan : Command public class CTempBan : Command
{ {
public CTempBan(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { } public CTempBan(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) public override async Task ExecuteAsync(Event E)
{ {
E.Target.lastOffense = SharedLibrary.Utilities.RemoveWords(E.Data, 1); E.Target.lastOffense = Utilities.RemoveWords(E.Data, 1);
String Message = E.Target.lastOffense; String Message = E.Target.lastOffense;
if (E.Origin.Level > E.Target.Level) if (E.Origin.Level > E.Target.Level)
{ {
@ -104,7 +106,7 @@ namespace SharedLibrary.Commands
} }
} }
class CBan : Command public class CBan : Command
{ {
public CBan(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { } public CBan(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { }
@ -119,6 +121,7 @@ namespace SharedLibrary.Commands
Message = "^1Player Banned: ^5" + E.Target.lastOffense; Message = "^1Player Banned: ^5" + E.Target.lastOffense;
if (E.Origin.Level > E.Target.Level) if (E.Origin.Level > E.Target.Level)
{ {
await E.Owner.ExecuteEvent(new Event(Event.GType.Ban, E.Data, E.Origin, E.Target, E.Owner));
await E.Target.Ban(Message, E.Origin); await E.Target.Ban(Message, E.Origin);
await E.Origin.Tell(String.Format("Sucessfully banned ^5{0} ^7({1})", E.Target.Name, E.Target.NetworkID)); await E.Origin.Tell(String.Format("Sucessfully banned ^5{0} ^7({1})", E.Target.Name, E.Target.NetworkID));
} }
@ -127,7 +130,7 @@ namespace SharedLibrary.Commands
} }
} }
class CUnban : Command public class CUnban : Command
{ {
public CUnban(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { } public CUnban(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { }
@ -138,7 +141,7 @@ namespace SharedLibrary.Commands
} }
} }
class CWhoAmI : Command public class CWhoAmI : Command
{ {
public CWhoAmI(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { } public CWhoAmI(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { }
@ -149,7 +152,7 @@ namespace SharedLibrary.Commands
} }
} }
class CList : Command public class CList : Command
{ {
public CList(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { } public CList(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { }
@ -182,7 +185,7 @@ namespace SharedLibrary.Commands
} }
} }
class CHelp : Command public class CHelp : Command
{ {
public CHelp(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { } public CHelp(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { }
@ -235,7 +238,7 @@ namespace SharedLibrary.Commands
} }
} }
class CFastRestart : Command public class CFastRestart : Command
{ {
public CFastRestart(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { } public CFastRestart(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { }
@ -250,7 +253,7 @@ namespace SharedLibrary.Commands
} }
} }
class CMapRotate : Command public class CMapRotate : Command
{ {
public CMapRotate(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { } public CMapRotate(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { }
@ -265,7 +268,7 @@ namespace SharedLibrary.Commands
} }
} }
class CSetLevel : Command public class CSetLevel : Command
{ {
public CSetLevel(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { } public CSetLevel(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { }
@ -282,12 +285,20 @@ namespace SharedLibrary.Commands
if (newPerm == Player.Permission.Owner && E.Origin.Level != Player.Permission.Console) if (newPerm == Player.Permission.Owner && E.Origin.Level != Player.Permission.Console)
newPerm = Player.Permission.Banned; newPerm = Player.Permission.Banned;
if (newPerm == Player.Permission.Owner && !E.Owner.Config.AllowMultipleOwners)
{
await E.Origin.Tell("There can only be 1 owner. Modify your server configuration if multiple owners are required");
return;
}
if (newPerm > Player.Permission.Banned) if (newPerm > Player.Permission.Banned)
{ {
var ActiveClient = E.Owner.Manager.GetActiveClients().First(p => p.NetworkID == E.Target.NetworkID); var ActiveClient = E.Owner.Manager.GetActiveClients().FirstOrDefault(p => p.NetworkID == E.Target.NetworkID);
ActiveClient?.SetLevel(newPerm); ActiveClient?.SetLevel(newPerm);
await ActiveClient?.Tell("Congratulations! You have been promoted to ^3" + newPerm); if (ActiveClient != null)
await ActiveClient.Tell("Congratulations! You have been promoted to ^3" + newPerm);
await E.Origin.Tell($"{E.Target.Name} was successfully promoted!"); await E.Origin.Tell($"{E.Target.Name} was successfully promoted!");
E.Target.SetLevel(newPerm); E.Target.SetLevel(newPerm);
@ -299,7 +310,7 @@ namespace SharedLibrary.Commands
} }
} }
class CUsage : Command public class CUsage : Command
{ {
public CUsage(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { } public CUsage(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { }
@ -309,7 +320,7 @@ namespace SharedLibrary.Commands
} }
} }
class CUptime : Command public class CUptime : Command
{ {
public CUptime(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { } public CUptime(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { }
@ -320,7 +331,7 @@ namespace SharedLibrary.Commands
} }
} }
class CListAdmins : Command public class CListAdmins : Command
{ {
public CListAdmins(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { } public CListAdmins(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { }
@ -340,14 +351,14 @@ namespace SharedLibrary.Commands
} }
} }
class CLoadMap : Command public class CLoadMap : Command
{ {
public CLoadMap(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { } public CLoadMap(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) public override async Task ExecuteAsync(Event E)
{ {
string newMap = E.Data.Trim().ToLower(); string newMap = E.Data.Trim().ToLower();
foreach (Map m in E.Owner.maps) foreach (Map m in E.Owner.Maps)
{ {
if (m.Name.ToLower() == newMap || m.Alias.ToLower() == newMap) if (m.Name.ToLower() == newMap || m.Alias.ToLower() == newMap)
{ {
@ -364,7 +375,7 @@ namespace SharedLibrary.Commands
} }
} }
class CFindPlayer : Command public class CFindPlayer : Command
{ {
public CFindPlayer(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { } public CFindPlayer(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { }
@ -386,7 +397,7 @@ namespace SharedLibrary.Commands
} }
} }
class CFindAllPlayers : Command public class CFindAllPlayers : Command
{ {
public CFindAllPlayers(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { } public CFindAllPlayers(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { }
@ -432,13 +443,13 @@ namespace SharedLibrary.Commands
} }
} }
class CListRules : Command public class CListRules : Command
{ {
public CListRules(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { } public CListRules(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) public override async Task ExecuteAsync(Event E)
{ {
if (E.Owner.rules.Count < 1) if (E.Owner.Rules.Count < 1)
{ {
if (E.Message.IsBroadcastCommand()) if (E.Message.IsBroadcastCommand())
await E.Owner.Broadcast("The server owner has not set any rules."); await E.Owner.Broadcast("The server owner has not set any rules.");
@ -448,7 +459,7 @@ namespace SharedLibrary.Commands
else else
{ {
foreach (String r in E.Owner.rules) foreach (String r in E.Owner.Rules)
{ {
if (E.Message.IsBroadcastCommand()) if (E.Message.IsBroadcastCommand())
await E.Owner.Broadcast("- " + r); await E.Owner.Broadcast("- " + r);
@ -459,7 +470,7 @@ namespace SharedLibrary.Commands
} }
} }
class CPrivateMessage : Command public class CPrivateMessage : Command
{ {
public CPrivateMessage(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { } public CPrivateMessage(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { }
@ -471,7 +482,7 @@ namespace SharedLibrary.Commands
} }
} }
class CReload : Command public class CReload : Command
{ {
public CReload(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { } public CReload(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { }
@ -484,7 +495,7 @@ namespace SharedLibrary.Commands
} }
} }
class CFlag : Command public class CFlag : Command
{ {
public CFlag(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { } public CFlag(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { }
@ -507,6 +518,7 @@ namespace SharedLibrary.Commands
E.Data = Utilities.RemoveWords(E.Data, 1); E.Data = Utilities.RemoveWords(E.Data, 1);
E.Target.SetLevel(Player.Permission.Flagged); E.Target.SetLevel(Player.Permission.Flagged);
E.Owner.Manager.GetClientPenalties().AddPenalty(new Penalty(Penalty.Type.Flag, E.Data, E.Target.NetworkID, E.Origin.NetworkID, DateTime.Now, E.Target.IP)); E.Owner.Manager.GetClientPenalties().AddPenalty(new Penalty(Penalty.Type.Flag, E.Data, E.Target.NetworkID, E.Origin.NetworkID, DateTime.Now, E.Target.IP));
await E.Owner.ExecuteEvent(new Event(Event.GType.Flag, E.Data, E.Origin, E.Target, E.Owner));
await E.Origin.Tell("You have ^5flagged ^7" + E.Target.Name); await E.Origin.Tell("You have ^5flagged ^7" + E.Target.Name);
} }
@ -514,7 +526,7 @@ namespace SharedLibrary.Commands
} }
} }
class CReport : Command public class CReport : Command
{ {
public CReport(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { } public CReport(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { }
@ -543,12 +555,11 @@ namespace SharedLibrary.Commands
await E.Origin.Tell("Successfully reported " + E.Target.Name); await E.Origin.Tell("Successfully reported " + E.Target.Name);
await E.Owner.ExecuteEvent(new Event(Event.GType.Report, E.Data, E.Origin, E.Target, E.Owner)); await E.Owner.ExecuteEvent(new Event(Event.GType.Report, E.Data, E.Origin, E.Target, E.Owner));
await E.Owner.ToAdmins(String.Format("^5{0}^7->^1{1}^7: {2}", E.Origin.Name, E.Target.Name, E.Data)); await E.Owner.ToAdmins(String.Format("^5{0}^7->^1{1}^7: {2}", E.Origin.Name, E.Target.Name, E.Data));
} }
} }
class CListReports : Command public class CListReports : Command
{ {
public CListReports(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { } public CListReports(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { }
@ -572,7 +583,7 @@ namespace SharedLibrary.Commands
} }
} }
class CMask : Command public class CMask : Command
{ {
public CMask(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { } public CMask(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { }
@ -588,10 +599,12 @@ namespace SharedLibrary.Commands
E.Origin.Masked = true; E.Origin.Masked = true;
await E.Origin.Tell("You are now masked"); await E.Origin.Tell("You are now masked");
} }
E.Owner.Manager.GetClientDatabase().UpdatePlayer(E.Origin);
} }
} }
class CListBanInfo : Command public class CListBanInfo : Command
{ {
public CListBanInfo(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { } public CListBanInfo(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { }
@ -624,7 +637,7 @@ namespace SharedLibrary.Commands
} }
} }
class CListAlias : Command public class CListAlias : Command
{ {
public CListAlias(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { } public CListAlias(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { }
@ -665,7 +678,7 @@ namespace SharedLibrary.Commands
} }
} }
class CExecuteRCON : Command public class CExecuteRCON : Command
{ {
public CExecuteRCON(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { } public CExecuteRCON(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { }
@ -679,7 +692,7 @@ namespace SharedLibrary.Commands
} }
} }
class CPlugins : Command public 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 CPlugins(String N, String D, String U, Player.Permission P, int args, bool nT) : base(N, D, U, P, args, nT) { }

View File

@ -82,7 +82,8 @@ namespace SharedLibrary
Unknown, Unknown,
//FROM PLAYER //FROM PLAYER
Report Report,
Flag
} }
public Event(GType t, string d, Player O, Player T, Server S) public Event(GType t, string d, Player O, Player T, Server S)

View File

@ -14,64 +14,25 @@ namespace SharedLibrary
[Guid("61d3829e-fcbe-44d3-bb7c-51db8c2d7ac5")] [Guid("61d3829e-fcbe-44d3-bb7c-51db8c2d7ac5")]
public abstract class Server public abstract class Server
{ {
public Server(Interfaces.IManager mgr, string address, int port, string password) public Server(Interfaces.IManager mgr, ServerConfiguration config)
{ {
Password = password; Password = config.Password;
IP = address; IP = config.IP;
Port = port; Port = config.Port;
Manager = mgr; Manager = mgr;
Logger = Manager.GetLogger(); Logger = Manager.GetLogger();
ClientNum = 0; ClientNum = 0;
Config = config;
Players = new List<Player>(new Player[18]); Players = new List<Player>(new Player[18]);
events = new Queue<Event>();
Reports = new List<Report>(); Reports = new List<Report>();
PlayerHistory = new Queue<Helpers.PlayerHistory>(); PlayerHistory = new Queue<Helpers.PlayerHistory>();
ChatHistory = new List<Chat>(); ChatHistory = new List<Chat>();
lastWebChat = DateTime.Now; NextMessage = 0;
nextMessage = 0;
InitializeTokens(); InitializeTokens();
InitializeAutoMessages(); InitializeAutoMessages();
InitializeMaps(); InitializeMaps();
InitializeRules(); InitializeRules();
var commands = mgr.GetCommands();
owner = Manager.GetClientDatabase().GetOwner();
if (owner == null)
commands.Add(new COwner("owner", "claim ownership of the server", "owner", Player.Permission.User, 0, false));
commands.Add(new CQuit("quit", "quit IW4MAdmin", "q", Player.Permission.Owner, 0, false));
commands.Add(new CKick("kick", "kick a player by name. syntax: !kick <player> <reason>.", "k", Player.Permission.Trusted, 2, true));
commands.Add(new CSay("say", "broadcast message to all players. syntax: !say <message>.", "s", Player.Permission.Moderator, 1, false));
commands.Add(new CTempBan("tempban", "temporarily ban a player for 1 hour. syntax: !tempban <player> <reason>.", "tb", Player.Permission.Moderator, 2, true));
commands.Add(new CBan("ban", "permanently ban a player from the server. syntax: !ban <player> <reason>", "b", Player.Permission.SeniorAdmin, 2, true));
commands.Add(new CWhoAmI("whoami", "give information about yourself. syntax: !whoami.", "who", Player.Permission.User, 0, false));
commands.Add(new CList("list", "list active clients syntax: !list.", "l", Player.Permission.Moderator, 0, false));
commands.Add(new CHelp("help", "list all available commands. syntax: !help.", "h", Player.Permission.User, 0, false));
commands.Add(new CFastRestart("fastrestart", "fast restart current map. syntax: !fastrestart.", "fr", Player.Permission.Moderator, 0, false));
commands.Add(new CMapRotate("maprotate", "cycle to the next map in rotation. syntax: !maprotate.", "mr", Player.Permission.Administrator, 0, false));
commands.Add(new CSetLevel("setlevel", "set player to specified administration level. syntax: !setlevel <player> <level>.", "sl", Player.Permission.Owner, 2, true));
commands.Add(new CUsage("usage", "get current application memory usage. syntax: !usage.", "us", Player.Permission.Moderator, 0, false));
commands.Add(new CUptime("uptime", "get current application running time. syntax: !uptime.", "up", Player.Permission.Moderator, 0, false));
commands.Add(new Cwarn("warn", "warn player for infringing rules syntax: !warn <player> <reason>.", "w", Player.Permission.Trusted, 2, true));
commands.Add(new CWarnClear("warnclear", "remove all warning for a player syntax: !warnclear <player>.", "wc", Player.Permission.Trusted, 1, true));
commands.Add(new CUnban("unban", "unban player by database id. syntax: !unban @<id>.", "ub", Player.Permission.SeniorAdmin, 1, true));
commands.Add(new CListAdmins("admins", "list currently connected admins. syntax: !admins.", "a", Player.Permission.User, 0, false));
commands.Add(new CLoadMap("map", "change to specified map. syntax: !map", "m", Player.Permission.Administrator, 1, false));
commands.Add(new CFindPlayer("find", "find player in database. syntax: !find <player>", "f", Player.Permission.SeniorAdmin, 1, false));
commands.Add(new CListRules("rules", "list server rules. syntax: !rules", "r", Player.Permission.User, 0, false));
commands.Add(new CPrivateMessage("privatemessage", "send message to other player. syntax: !pm <player> <message>", "pm", Player.Permission.User, 2, true));
commands.Add(new CFlag("flag", "flag a suspicious player and announce to admins on join . syntax !flag <player> <reason>:", "flag", Player.Permission.Moderator, 2, true));
commands.Add(new CReport("report", "report a player for suspicious behaivor. syntax !report <player> <reason>", "rep", Player.Permission.User, 2, true));
commands.Add(new CListReports("reports", "get most recent reports. syntax !reports", "reports", Player.Permission.Moderator, 0, false));
commands.Add(new CMask("mask", "hide your online presence from online admin list. syntax: !mask", "mask", Player.Permission.Administrator, 0, false));
commands.Add(new CListBanInfo("baninfo", "get information about a ban for a player. syntax: !baninfo <player>", "bi", Player.Permission.Moderator, 1, true));
commands.Add(new CListAlias("alias", "get past aliases and ips of a player. syntax: !alias <player>", "known", Player.Permission.Moderator, 1, true));
commands.Add(new CExecuteRCON("rcon", "send rcon command to server. syntax: !rcon <command>", "rcon", Player.Permission.Owner, 1, false));
commands.Add(new CFindAllPlayers("findall", "find a player by their aliase(s). syntax: !findall <player>", "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* //Returns current server IP set by `net_ip` -- *STRING*
@ -287,7 +248,7 @@ namespace SharedLibrary
/// </summary> /// </summary>
protected void InitializeMaps() protected void InitializeMaps()
{ {
maps = new List<Map>(); Maps = new List<Map>();
IFile mapfile = new IFile("config/maps.cfg"); IFile mapfile = new IFile("config/maps.cfg");
String[] _maps = mapfile.ReadAllLines(); String[] _maps = mapfile.ReadAllLines();
@ -300,7 +261,7 @@ namespace SharedLibrary
if (m2.Length > 1) if (m2.Length > 1)
{ {
Map map = new Map(m2[0].Trim(), m2[1].Trim()); Map map = new Map(m2[0].Trim(), m2[1].Trim());
maps.Add(map); Maps.Add(map);
} }
} }
} }
@ -314,7 +275,7 @@ namespace SharedLibrary
/// </summary> /// </summary>
protected void InitializeAutoMessages() protected void InitializeAutoMessages()
{ {
messages = new List<String>(); BroadcastMessages = new List<String>();
IFile messageCFG = new IFile("config/messages.cfg"); IFile messageCFG = new IFile("config/messages.cfg");
String[] lines = messageCFG.ReadAllLines(); String[] lines = messageCFG.ReadAllLines();
@ -329,15 +290,15 @@ namespace SharedLibrary
int mTime = -1; int mTime = -1;
int.TryParse(lines[0], out mTime); int.TryParse(lines[0], out mTime);
if (messageTime == -1) if (MessageTime == -1)
messageTime = 60; MessageTime = 60;
else else
messageTime = mTime; MessageTime = mTime;
foreach (String l in lines) foreach (String l in lines)
{ {
if (lines[0] != l && l.Length > 1) if (lines[0] != l && l.Length > 1)
messages.Add(l); BroadcastMessages.Add(l);
} }
messageCFG.Close(); messageCFG.Close();
@ -352,7 +313,7 @@ namespace SharedLibrary
/// </summary> /// </summary>
protected void InitializeRules() protected void InitializeRules()
{ {
rules = new List<String>(); Rules = new List<String>();
IFile ruleFile = new IFile("config/rules.cfg"); IFile ruleFile = new IFile("config/rules.cfg");
String[] _rules = ruleFile.ReadAllLines(); String[] _rules = ruleFile.ReadAllLines();
@ -362,7 +323,7 @@ namespace SharedLibrary
foreach (String r in _rules) foreach (String r in _rules)
{ {
if (r.Length > 1) if (r.Length > 1)
rules.Add(r); Rules.Add(r);
} }
} }
else else
@ -376,55 +337,39 @@ namespace SharedLibrary
return $"{IP}_{Port}"; return $"{IP}_{Port}";
} }
/// <summary> // Objects
/// Load up the built in commands
/// </summary>
public void InitializeCommands()
{
foreach (Command C in Plugins.PluginImporter.ActiveCommands)
Manager.GetCommands().Add(C);
}
//Objects
public Interfaces.IManager Manager { get; protected set; } public Interfaces.IManager Manager { get; protected set; }
public Interfaces.ILogger Logger { get; private set; } public Interfaces.ILogger Logger { get; private set; }
public Player owner; public ServerConfiguration Config { get; private set; }
public List<Map> maps; public List<Map> Maps { get; protected set; }
public List<String> rules; public List<string> Rules { get; protected set; }
public Queue<Event> events; public List<Report> Reports { get; protected set; }
public String Website; public List<Chat> ChatHistory { get; protected set; }
public String Gametype;
public int totalKills = 0;
public List<Report> Reports;
public List<Chat> ChatHistory;
public Queue<Helpers.PlayerHistory> PlayerHistory { get; private set; } public Queue<Helpers.PlayerHistory> PlayerHistory { get; private set; }
protected int ConnectionErrors; // Info
protected DateTime LastPoll; public string Hostname { get; protected set; }
public string Website { get; protected set; }
//Info public string Gametype { get; protected set; }
protected String IP;
protected int Port;
public String Hostname { get; protected set; }
public Map CurrentMap { get; protected set; } public Map CurrentMap { get; protected set; }
protected string FSGame;
public int ClientNum { get; protected set; } public int ClientNum { get; protected set; }
public int MaxClients { get; protected set; } public int MaxClients { get; protected set; }
public List<Player> Players { get; protected set; } public List<Player> Players { get; protected set; }
protected List<String> messages;
protected int messageTime;
protected TimeSpan lastMessage;
protected DateTime lastPoll;
protected int nextMessage;
protected DateTime lastWebChat;
public string Password { get; private set; } public string Password { get; private set; }
protected IFile logFile;
// Log stuff // Internal
protected String Mod; protected string IP;
protected int Port;
protected string FSGame;
protected int MessageTime;
protected int NextMessage;
protected int ConnectionErrors;
protected List<string> BroadcastMessages;
protected TimeSpan LastMessage;
protected IFile LogFile;
protected DateTime LastPoll;
//Remote //Remote
public Queue<String> commandResult = new Queue<string>(); public Queue<string> commandResult = new Queue<string>();
} }
} }

View File

@ -0,0 +1,18 @@
using SharedLibrary.Interfaces;
namespace SharedLibrary
{
public class ServerConfiguration : Serialize<ServerConfiguration>
{
public string IP;
public int Port;
public string Password;
public string FtpPrefix;
public bool AllowMultipleOwners;
public override string Filename()
{
return $"config/servers/{IP}_{Port}.cfg";
}
}
}

View File

@ -93,6 +93,7 @@
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="RCON.cs" /> <Compile Include="RCON.cs" />
<Compile Include="Server.cs" /> <Compile Include="Server.cs" />
<Compile Include="ServerConfiguration.cs" />
<Compile Include="Utilities.cs" /> <Compile Include="Utilities.cs" />
<Compile Include="WebService.cs" /> <Compile Include="WebService.cs" />
</ItemGroup> </ItemGroup>

View File

@ -72,11 +72,9 @@ namespace SharedLibrary
{ {
String lookingFor = str.ToLower(); String lookingFor = str.ToLower();
for (Player.Permission Perm = Player.Permission.User; Perm < Player.Permission.Owner; Perm++) for (Player.Permission Perm = Player.Permission.User; Perm < Player.Permission.Console; Perm++)
{
if (lookingFor.Contains(Perm.ToString().ToLower())) if (lookingFor.Contains(Perm.ToString().ToLower()))
return Perm; return Perm;
}
return Player.Permission.Banned; return Player.Permission.Banned;
} }