diff --git a/Admin/Main.cs b/Admin/Main.cs index b0d0b61f3..9c623f3d6 100644 --- a/Admin/Main.cs +++ b/Admin/Main.cs @@ -15,18 +15,15 @@ namespace IW4MAdmin static void Main(string[] args) { - Version = 1.3; + Version = 1.4; handler = new ConsoleEventDelegate(OnProcessExit); SetConsoleCtrlHandler(handler, true); - double.TryParse(CheckUpdate(), out double latestVersion); + //double.TryParse(CheckUpdate(), out double latestVersion); Console.WriteLine("====================================================="); Console.WriteLine(" IW4M ADMIN"); Console.WriteLine(" by RaidMax "); - if (latestVersion != 0) - Console.WriteLine(" Version " + Version + " (latest " + latestVersion + ")"); - else - Console.WriteLine(" Version " + Version + " (unable to retrieve latest)"); + Console.WriteLine($" Version {Version}"); Console.WriteLine("====================================================="); try @@ -45,7 +42,7 @@ namespace IW4MAdmin { userInput = Console.ReadLine(); - if (userInput.ToLower() == "quit") + if (userInput?.ToLower() == "quit") ServerManager.Stop(); if (ServerManager.Servers.Count == 0) @@ -92,13 +89,6 @@ namespace IW4MAdmin [DllImport("kernel32.dll", SetLastError = true)] private static extern bool SetConsoleCtrlHandler(ConsoleEventDelegate callback, bool add); - static private String CheckUpdate() - { - //Connection Ver = new Connection("http://raidmax.org/IW4M/Admin/version.php"); - //return Ver.Read(); - return "0"; - } - static void CheckDirectories() { if (!Directory.Exists("Lib")) diff --git a/Admin/Manager.cs b/Admin/Manager.cs index 219279dc0..ac9b46711 100644 --- a/Admin/Manager.cs +++ b/Admin/Manager.cs @@ -95,7 +95,7 @@ namespace IW4MAdmin if (e.GetType() == typeof(DvarException)) Logger.WriteError($"Could not get the dvar value for {(e as DvarException).Data["dvar_name"]} (ensure the server has a map loaded)"); else if (e.GetType() == typeof(NetworkException)) - Logger.WriteError("Could not communicate with the server (ensure the configuration is correct)"); + Logger.WriteError(e.Message); } }); } @@ -121,7 +121,7 @@ namespace IW4MAdmin #endregion #region COMMANDS - if ((ClientDatabase as ClientsDB).GetOwner() != null) + 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)); diff --git a/Admin/Server.cs b/Admin/Server.cs index 3ac34efc3..9300c186c 100644 --- a/Admin/Server.cs +++ b/Admin/Server.cs @@ -147,7 +147,6 @@ namespace IW4MAdmin } } - Players[NewPlayer.ClientID] = null; Players[NewPlayer.ClientID] = NewPlayer; Logger.WriteInfo($"Client {NewPlayer.Name}::{NewPlayer.NetworkID} connecting..."); // they're clean @@ -348,6 +347,9 @@ namespace IW4MAdmin try { await PollPlayersAsync(); + + if (ConnectionErrors > 0) + Logger.WriteInfo($"Connection has been reestablished with {IP}:{Port}"); ConnectionErrors = 0; LastPoll = DateTime.Now; } @@ -355,7 +357,7 @@ namespace IW4MAdmin catch(SharedLibrary.Exceptions.NetworkException e) { ConnectionErrors++; - if (ConnectionErrors > 1) + if (ConnectionErrors == 1) Logger.WriteError($"{e.Message} {IP}:{Port}, reducing polling rate"); } @@ -380,10 +382,7 @@ namespace IW4MAdmin if (LastMessage.TotalSeconds > MessageTime && BroadcastMessages.Count > 0 && Players.Count > 0) { await Broadcast(Utilities.ProcessMessageToken(Manager.GetMessageTokens(), BroadcastMessages[NextMessage])); - if (NextMessage == (BroadcastMessages.Count - 1)) - NextMessage = 0; - else - NextMessage++; + NextMessage = NextMessage == (BroadcastMessages.Count - 1) ? 0 : NextMessage++; start = DateTime.Now; } @@ -450,16 +449,27 @@ namespace IW4MAdmin public async Task Initialize() { + var version = await this.GetDvarAsync("version"); + GameName = Utilities.GetGame(version.Value); + + if (GameName == Game.UKN) + Logger.WriteWarning($"Game name not recognized: {version}"); + var shortversion = await this.GetDvarAsync("shortversion"); var hostname = await this.GetDvarAsync("sv_hostname"); var mapname = await this.GetDvarAsync("mapname"); - var maxplayers = await this.GetDvarAsync("party_maxplayers"); + var maxplayers = (GameName == Game.IW4) ? // gotta love IW4 idiosyncrasies + await this.GetDvarAsync("party_maxplayers") : + await this.GetDvarAsync("sv_maxclients"); var gametype = await this.GetDvarAsync("g_gametype"); var basepath = await this.GetDvarAsync("fs_basepath"); var game = await this.GetDvarAsync("fs_game"); var logfile = await this.GetDvarAsync("g_log"); var logsync = await this.GetDvarAsync("g_logsync"); - var onelog = await this.GetDvarAsync("iw4x_onelog"); + + DVAR onelog = null; + if (GameName == Game.IW4) + onelog = await this.GetDvarAsync("iw4x_onelog"); try { @@ -481,19 +491,26 @@ namespace IW4MAdmin await this.SetDvarAsync("sv_network_fps", 1000); await this.SetDvarAsync("com_maxfps", 1000); - if (logsync.Value != 1 || logfile.Value == string.Empty) + if (logsync.Value == 0 || logfile.Value == string.Empty) { // this DVAR isn't set until the a map is loaded - await this.SetDvarAsync("g_logsync", 1); - await this.SetDvarAsync("g_log", "logs/games_mp.log"); + await this.SetDvarAsync("logfile", 2); + await this.SetDvarAsync("g_logsync", 2); // set to 2 for continous in other games, clamps to 1 for IW4 + await this.SetDvarAsync("g_log", "games_mp.log"); Logger.WriteWarning("Game log file not properly initialized, restarting map..."); await this.ExecuteCommandAsync("map_restart"); logfile = await this.GetDvarAsync("g_log"); } #if DEBUG - basepath.Value = @"\\tsclient\K\MW2"; + basepath.Value = (GameName == Game.IW4) ? + @"\\tsclient\K\MW2" : + @"\\tsclient\G\Program Files (x86)\Steam\SteamApps\common\Call of Duty 4"; #endif - string logPath = (game.Value == "" || onelog.Value == 1) ? $"{basepath.Value.Replace("\\", "/")}/userraw/{logfile.Value}" : $"{basepath.Value.Replace("\\", "/")}/{game.Value}/{logfile.Value}"; + string mainPath = (GameName == Game.IW4) ? "userraw" : "main"; + + string logPath = (game.Value == "" || onelog?.Value == 1) ? + $"{ basepath.Value.Replace("\\", "/")}/{mainPath}/{logfile.Value}" : + $"{basepath.Value.Replace("\\", "/")}/{game.Value}/{logfile.Value}"; if (!File.Exists(logPath)) { @@ -521,12 +538,12 @@ namespace IW4MAdmin ChatHistory.Add(new Chat(E.Origin.Name, "CONNECTED", DateTime.Now)); } - if (E.Type == Event.GType.Disconnect) + else if (E.Type == Event.GType.Disconnect) { ChatHistory.Add(new Chat(E.Origin.Name, "DISCONNECTED", DateTime.Now)); } - if (E.Type == Event.GType.Kill) + else if (E.Type == Event.GType.Kill) { if (E.Origin != E.Target) await ExecuteEvent(new Event(Event.GType.Death, E.Data, E.Target, null, this)); @@ -535,20 +552,8 @@ namespace IW4MAdmin 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 && E.Data.Length >= 2) { - if (E.Data.Length < 2) // ITS A LIE! - return; - if (E.Data.Substring(0, 1) == "!" || E.Data.Substring(0, 1) == "@" || E.Origin.Level == Player.Permission.Console) { Command C = null; @@ -561,7 +566,6 @@ namespace IW4MAdmin catch (SharedLibrary.Exceptions.CommandException e) { Logger.WriteInfo(e.Message); - return; } if (C != null) @@ -569,7 +573,6 @@ namespace IW4MAdmin if (C.RequiresTarget && E.Target == null) { Logger.WriteWarning("Requested event (command) requiring target does not have a target!"); - return; } try @@ -586,10 +589,8 @@ namespace IW4MAdmin #if DEBUG await E.Origin.Tell(Except.Message); #endif - return; } } - return; } else // Not a command @@ -599,8 +600,6 @@ namespace IW4MAdmin E.Data = E.Data.Substring(0, 50) + "..."; ChatHistory.Add(new Chat(E.Origin.Name, E.Data, DateTime.Now)); - - return; } } @@ -614,15 +613,21 @@ namespace IW4MAdmin string mapname = this.GetDvarAsync("mapname").Result.Value; CurrentMap = Maps.Find(m => m.Name == mapname) ?? new Map(mapname, mapname); - - return; } if (E.Type == Event.GType.MapEnd) { Logger.WriteInfo("Game ending..."); - return; - }; + } + + //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(); } public override async Task Warn(String Reason, Player Target, Player Origin) @@ -646,7 +651,7 @@ namespace IW4MAdmin String Message = "^1Player Kicked: ^5" + Reason; Penalty newPenalty = new Penalty(Penalty.Type.Kick, Reason.StripColors().Trim(), Target.NetworkID, Origin.NetworkID, DateTime.Now, Target.IP); Manager.GetClientPenalties().AddPenalty(newPenalty); - await this.ExecuteCommandAsync("clientkick " + Target.ClientID + " \"" + Message + "^7\""); + await this.ExecuteCommandAsync($"clientkick {Target.ClientID} \"{Message}^7\""); } } @@ -663,11 +668,6 @@ namespace IW4MAdmin } } - private String GetWebsiteString() - { - return Website != null ? $" (appeal at {Website}" : " (appeal at this server's website)"; - } - override public async Task Ban(String Message, Player Target, Player Origin) { if (Target == null) @@ -685,7 +685,10 @@ namespace IW4MAdmin { var activeClient = server.GetPlayersAsList().Find(x => x.NetworkID == Target.NetworkID); if (activeClient != null) - await server.ExecuteCommandAsync("tempbanclient " + activeClient.ClientID + " \"" + Message + "^7" + GetWebsiteString() + "^7\""); + { + await server.ExecuteCommandAsync($"tempbanclient {activeClient.ClientID} \"{Message} ^7 ({Website}) ^7\""); + break; + } } } diff --git a/Admin/WebService.cs b/Admin/WebService.cs index 45fb6b15d..11ad1d4b0 100644 --- a/Admin/WebService.cs +++ b/Admin/WebService.cs @@ -394,19 +394,19 @@ namespace IW4MAdmin foreach (var p in selectedPenalties) { - Player admin = ApplicationManager.GetInstance().GetClientDatabase().GetPlayer(p.PenaltyOriginID, 0); + Player admin = ApplicationManager.GetInstance().GetClientDatabase().GetPlayer(p.PenaltyOriginID, 0) ?? + new Player("IW4MAdmin", "-1", -1, (int)Player.Permission.Banned); + Player penalized = ApplicationManager.GetInstance().GetClientDatabase().GetPlayer(p.OffenderID, 0); if (admin == null && penalized == null) continue; - if (admin == null) - admin = new Player("Unknown", "-1", -1, (int)Player.Permission.Banned); PenaltyInfo pInfo = new PenaltyInfo() { adminName = admin.Name, adminLevel = admin.Level.ToString(), penaltyReason = p.Reason, - penaltyTime = SharedLibrary.Utilities.GetTimePassed(p.When), + penaltyTime = Utilities.GetTimePassed(p.When), penaltyType = p.BType.ToString(), playerName = penalized.Name, playerID = penalized.DatabaseID diff --git a/Admin/lib/SharedLibrary.dll b/Admin/lib/SharedLibrary.dll index f580f357a..254333803 100644 Binary files a/Admin/lib/SharedLibrary.dll and b/Admin/lib/SharedLibrary.dll differ diff --git a/Admin/version.txt b/Admin/version.txt index 7f195044f..166c109e7 100644 --- a/Admin/version.txt +++ b/Admin/version.txt @@ -1,8 +1,17 @@ -VERSION 1.3 +VERSION 1.4 +CHANGELOG: +-works: with COD, WaW, MW3, BO1 (preliminary without extensive testing) +-fixed the issue with webfront chat history +-fixed console issue of spamming 'polling rate decreased' when server goes offline +-'unknown' admin in webfront defaults to 'IW4MAdmin' + + +VERSION 1.3 CHANGELOG: -complete rewrite of lots of parts -async EVERYTHING!!! -designed to work with IW4X (funny how the GitHub description is now 100% accurate after almost 3 years) +-gsc features deprecated VERSION 1.2 CHANGELOG: diff --git a/IW4MAdmin.sln b/IW4MAdmin.sln index 8d9d19a6d..cd072ce42 100644 --- a/IW4MAdmin.sln +++ b/IW4MAdmin.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 -VisualStudioVersion = 15.0.26430.12 +VisualStudioVersion = 15.0.26403.7 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Application", "Admin\Application.csproj", "{DD5DCDA2-51DB-4B1A-922F-5705546E6115}" ProjectSection(ProjectDependencies) = postProject @@ -60,240 +60,244 @@ Global {DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Debug|Mixed Platforms.Build.0 = Release|Any CPU {DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Debug|x64.ActiveCfg = Release|Any CPU {DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Debug|x64.Build.0 = Release|Any CPU - {DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Debug|x86.ActiveCfg = Release|Any CPU - {DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Debug|x86.Build.0 = Release|Any CPU + {DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Debug|x86.ActiveCfg = Release-Stable|Any CPU + {DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Debug|x86.Build.0 = Release-Stable|Any CPU {DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release|Any CPU.ActiveCfg = Release|Any CPU {DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release|Any CPU.Build.0 = Release|Any CPU {DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU {DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release|Mixed Platforms.Build.0 = Release|Any CPU {DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release|x64.ActiveCfg = Release|Any CPU {DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release|x64.Build.0 = Release|Any CPU - {DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release|x86.ActiveCfg = Release|Any CPU - {DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release|x86.Build.0 = Release|Any CPU + {DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release|x86.ActiveCfg = Release-Stable|Any CPU + {DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release|x86.Build.0 = Release-Stable|Any CPU {DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release-Nightly|Any CPU.ActiveCfg = Release|Any CPU {DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release-Nightly|Any CPU.Build.0 = Release|Any CPU {DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release-Nightly|Mixed Platforms.ActiveCfg = Release|Any CPU {DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release-Nightly|Mixed Platforms.Build.0 = Release|Any CPU {DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release-Nightly|x64.ActiveCfg = Release|Any CPU {DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release-Nightly|x64.Build.0 = Release|Any CPU - {DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release-Nightly|x86.ActiveCfg = Release|Any CPU - {DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release-Nightly|x86.Build.0 = Release|Any CPU + {DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release-Nightly|x86.ActiveCfg = Release-Stable|Any CPU + {DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release-Nightly|x86.Build.0 = Release-Stable|Any CPU {DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release-Stable|Any CPU.ActiveCfg = Release|Any CPU {DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release-Stable|Any CPU.Build.0 = Release|Any CPU {DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release-Stable|Mixed Platforms.ActiveCfg = Release|Any CPU {DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release-Stable|Mixed Platforms.Build.0 = Release|Any CPU {DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release-Stable|x64.ActiveCfg = Release|Any CPU {DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release-Stable|x64.Build.0 = Release|Any CPU - {DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release-Stable|x86.ActiveCfg = Release|Any CPU - {DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release-Stable|x86.Build.0 = Release|Any CPU + {DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release-Stable|x86.ActiveCfg = Release-Stable|Any CPU + {DD5DCDA2-51DB-4B1A-922F-5705546E6115}.Release-Stable|x86.Build.0 = Release-Stable|Any CPU {4785AB75-66F3-4391-985D-63A5A049A0FA}.Debug|Any CPU.ActiveCfg = Release|Any CPU {4785AB75-66F3-4391-985D-63A5A049A0FA}.Debug|Any CPU.Build.0 = Release|Any CPU {4785AB75-66F3-4391-985D-63A5A049A0FA}.Debug|Mixed Platforms.ActiveCfg = Release|Any CPU {4785AB75-66F3-4391-985D-63A5A049A0FA}.Debug|Mixed Platforms.Build.0 = Release|Any CPU {4785AB75-66F3-4391-985D-63A5A049A0FA}.Debug|x64.ActiveCfg = Release|Any CPU {4785AB75-66F3-4391-985D-63A5A049A0FA}.Debug|x64.Build.0 = Release|Any CPU - {4785AB75-66F3-4391-985D-63A5A049A0FA}.Debug|x86.ActiveCfg = Release|Any CPU - {4785AB75-66F3-4391-985D-63A5A049A0FA}.Debug|x86.Build.0 = Release|Any CPU + {4785AB75-66F3-4391-985D-63A5A049A0FA}.Debug|x86.ActiveCfg = Release-Stable|Any CPU + {4785AB75-66F3-4391-985D-63A5A049A0FA}.Debug|x86.Build.0 = Release-Stable|Any CPU {4785AB75-66F3-4391-985D-63A5A049A0FA}.Release|Any CPU.ActiveCfg = Release|Any CPU {4785AB75-66F3-4391-985D-63A5A049A0FA}.Release|Any CPU.Build.0 = Release|Any CPU {4785AB75-66F3-4391-985D-63A5A049A0FA}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU {4785AB75-66F3-4391-985D-63A5A049A0FA}.Release|Mixed Platforms.Build.0 = Release|Any CPU {4785AB75-66F3-4391-985D-63A5A049A0FA}.Release|x64.ActiveCfg = Release|Any CPU {4785AB75-66F3-4391-985D-63A5A049A0FA}.Release|x64.Build.0 = Release|Any CPU - {4785AB75-66F3-4391-985D-63A5A049A0FA}.Release|x86.ActiveCfg = Release|Any CPU - {4785AB75-66F3-4391-985D-63A5A049A0FA}.Release|x86.Build.0 = Release|Any CPU + {4785AB75-66F3-4391-985D-63A5A049A0FA}.Release|x86.ActiveCfg = Release-Stable|Any CPU + {4785AB75-66F3-4391-985D-63A5A049A0FA}.Release|x86.Build.0 = Release-Stable|Any CPU {4785AB75-66F3-4391-985D-63A5A049A0FA}.Release-Nightly|Any CPU.ActiveCfg = Release|Any CPU {4785AB75-66F3-4391-985D-63A5A049A0FA}.Release-Nightly|Any CPU.Build.0 = Release|Any CPU {4785AB75-66F3-4391-985D-63A5A049A0FA}.Release-Nightly|Mixed Platforms.ActiveCfg = Release|Any CPU {4785AB75-66F3-4391-985D-63A5A049A0FA}.Release-Nightly|Mixed Platforms.Build.0 = Release|Any CPU {4785AB75-66F3-4391-985D-63A5A049A0FA}.Release-Nightly|x64.ActiveCfg = Release|Any CPU {4785AB75-66F3-4391-985D-63A5A049A0FA}.Release-Nightly|x64.Build.0 = Release|Any CPU - {4785AB75-66F3-4391-985D-63A5A049A0FA}.Release-Nightly|x86.ActiveCfg = Release|Any CPU - {4785AB75-66F3-4391-985D-63A5A049A0FA}.Release-Nightly|x86.Build.0 = Release|Any CPU + {4785AB75-66F3-4391-985D-63A5A049A0FA}.Release-Nightly|x86.ActiveCfg = Release-Stable|Any CPU + {4785AB75-66F3-4391-985D-63A5A049A0FA}.Release-Nightly|x86.Build.0 = Release-Stable|Any CPU {4785AB75-66F3-4391-985D-63A5A049A0FA}.Release-Stable|Any CPU.ActiveCfg = Release|Any CPU {4785AB75-66F3-4391-985D-63A5A049A0FA}.Release-Stable|Any CPU.Build.0 = Release|Any CPU {4785AB75-66F3-4391-985D-63A5A049A0FA}.Release-Stable|Mixed Platforms.ActiveCfg = Release|Any CPU {4785AB75-66F3-4391-985D-63A5A049A0FA}.Release-Stable|Mixed Platforms.Build.0 = Release|Any CPU {4785AB75-66F3-4391-985D-63A5A049A0FA}.Release-Stable|x64.ActiveCfg = Release|Any CPU {4785AB75-66F3-4391-985D-63A5A049A0FA}.Release-Stable|x64.Build.0 = Release|Any CPU - {4785AB75-66F3-4391-985D-63A5A049A0FA}.Release-Stable|x86.ActiveCfg = Release|Any CPU - {4785AB75-66F3-4391-985D-63A5A049A0FA}.Release-Stable|x86.Build.0 = Release|Any CPU + {4785AB75-66F3-4391-985D-63A5A049A0FA}.Release-Stable|x86.ActiveCfg = Release-Stable|Any CPU + {4785AB75-66F3-4391-985D-63A5A049A0FA}.Release-Stable|x86.Build.0 = Release-Stable|Any CPU {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Debug|Any CPU.ActiveCfg = Release|Any CPU {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Debug|Any CPU.Build.0 = Release|Any CPU {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Debug|Mixed Platforms.ActiveCfg = Release|Any CPU {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Debug|Mixed Platforms.Build.0 = Release|Any CPU {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Debug|x64.ActiveCfg = Release|Any CPU {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Debug|x64.Build.0 = Release|Any CPU - {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Debug|x86.ActiveCfg = Release|Any CPU - {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Debug|x86.Build.0 = Release|Any CPU + {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Debug|x86.ActiveCfg = Release-Stable|Any CPU + {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Debug|x86.Build.0 = Release-Stable|Any CPU {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release|Any CPU.ActiveCfg = Release|Any CPU {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release|Any CPU.Build.0 = Release|Any CPU {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release|Mixed Platforms.Build.0 = Release|Any CPU {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release|x64.ActiveCfg = Release|Any CPU {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release|x64.Build.0 = Release|Any CPU - {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release|x86.ActiveCfg = Release|Any CPU - {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release|x86.Build.0 = Release|Any CPU + {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release|x86.ActiveCfg = Release-Stable|Any CPU + {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release|x86.Build.0 = Release-Stable|Any CPU {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release-Nightly|Any CPU.ActiveCfg = Release|Any CPU {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release-Nightly|Any CPU.Build.0 = Release|Any CPU {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release-Nightly|Mixed Platforms.ActiveCfg = Release|Any CPU {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release-Nightly|Mixed Platforms.Build.0 = Release|Any CPU {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release-Nightly|x64.ActiveCfg = Release|Any CPU {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release-Nightly|x64.Build.0 = Release|Any CPU - {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release-Nightly|x86.ActiveCfg = Release|Any CPU - {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release-Nightly|x86.Build.0 = Release|Any CPU + {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release-Nightly|x86.ActiveCfg = Release-Stable|Any CPU + {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release-Nightly|x86.Build.0 = Release-Stable|Any CPU {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release-Stable|Any CPU.ActiveCfg = Release|Any CPU {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release-Stable|Any CPU.Build.0 = Release|Any CPU {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release-Stable|Mixed Platforms.ActiveCfg = Release|Any CPU {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release-Stable|Mixed Platforms.Build.0 = Release|Any CPU {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release-Stable|x64.ActiveCfg = Release|Any CPU {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release-Stable|x64.Build.0 = Release|Any CPU - {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release-Stable|x86.ActiveCfg = Release|Any CPU - {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release-Stable|x86.Build.0 = Release|Any CPU + {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release-Stable|x86.ActiveCfg = Release-Stable|Any CPU + {D51EECEB-438A-47DA-870F-7D7B41BC24D6}.Release-Stable|x86.Build.0 = Release-Stable|Any CPU {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Debug|Any CPU.ActiveCfg = Release|Any CPU {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Debug|Any CPU.Build.0 = Release|Any CPU {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Debug|Mixed Platforms.ActiveCfg = Release|Any CPU {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Debug|Mixed Platforms.Build.0 = Release|Any CPU {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Debug|x64.ActiveCfg = Release|Any CPU {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Debug|x64.Build.0 = Release|Any CPU - {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Debug|x86.ActiveCfg = Release|Any CPU - {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Debug|x86.Build.0 = Release|Any CPU + {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Debug|x86.ActiveCfg = Release-Stable|Any CPU + {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Debug|x86.Build.0 = Release-Stable|Any CPU {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release|Any CPU.ActiveCfg = Release|Any CPU {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release|Any CPU.Build.0 = Release|Any CPU {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release|Mixed Platforms.Build.0 = Release|Any CPU {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release|x64.ActiveCfg = Release|Any CPU {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release|x64.Build.0 = Release|Any CPU - {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release|x86.ActiveCfg = Release|Any CPU - {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release|x86.Build.0 = Release|Any CPU + {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release|x86.ActiveCfg = Release-Stable|Any CPU + {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release|x86.Build.0 = Release-Stable|Any CPU {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release-Nightly|Any CPU.ActiveCfg = Release|Any CPU {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release-Nightly|Any CPU.Build.0 = Release|Any CPU {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release-Nightly|Mixed Platforms.ActiveCfg = Release|Any CPU {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release-Nightly|Mixed Platforms.Build.0 = Release|Any CPU {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release-Nightly|x64.ActiveCfg = Release|Any CPU {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release-Nightly|x64.Build.0 = Release|Any CPU - {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release-Nightly|x86.ActiveCfg = Release|Any CPU - {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release-Nightly|x86.Build.0 = Release|Any CPU + {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release-Nightly|x86.ActiveCfg = Release-Stable|Any CPU + {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release-Nightly|x86.Build.0 = Release-Stable|Any CPU {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release-Stable|Any CPU.ActiveCfg = Release|Any CPU {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release-Stable|Any CPU.Build.0 = Release|Any CPU {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release-Stable|Mixed Platforms.ActiveCfg = Release|Any CPU {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release-Stable|Mixed Platforms.Build.0 = Release|Any CPU {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release-Stable|x64.ActiveCfg = Release|Any CPU {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release-Stable|x64.Build.0 = Release|Any CPU - {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release-Stable|x86.ActiveCfg = Release|Any CPU - {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release-Stable|x86.Build.0 = Release|Any CPU + {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release-Stable|x86.ActiveCfg = Release-Stable|Any CPU + {AF097E6B-48D5-4452-9CCF-0A81A21F341D}.Release-Stable|x86.Build.0 = Release-Stable|Any CPU {428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Debug|Any CPU.ActiveCfg = Release|Any CPU {428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Debug|Any CPU.Build.0 = Release|Any CPU {428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Debug|Mixed Platforms.ActiveCfg = Release|Any CPU {428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Debug|Mixed Platforms.Build.0 = Release|Any CPU {428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Debug|x64.ActiveCfg = Release|Any CPU {428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Debug|x64.Build.0 = Release|Any CPU - {428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Debug|x86.ActiveCfg = Release|Any CPU - {428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Debug|x86.Build.0 = Release|Any CPU + {428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Debug|x86.ActiveCfg = Debug|Any CPU + {428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Debug|x86.Build.0 = Debug|Any CPU {428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release|Any CPU.ActiveCfg = Release|Any CPU {428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release|Any CPU.Build.0 = Release|Any CPU {428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU {428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release|Mixed Platforms.Build.0 = Release|Any CPU {428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release|x64.ActiveCfg = Release|Any CPU {428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release|x64.Build.0 = Release|Any CPU - {428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release|x86.ActiveCfg = Release|Any CPU - {428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release|x86.Build.0 = Release|Any CPU + {428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release|x86.ActiveCfg = Debug|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|Any CPU {428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release-Nightly|Any CPU.Build.0 = Release|Any CPU {428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release-Nightly|Mixed Platforms.ActiveCfg = Release|Any CPU {428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release-Nightly|Mixed Platforms.Build.0 = Release|Any CPU {428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release-Nightly|x64.ActiveCfg = Release|Any CPU {428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release-Nightly|x64.Build.0 = Release|Any CPU - {428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release-Nightly|x86.ActiveCfg = Release|Any CPU - {428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release-Nightly|x86.Build.0 = Release|Any CPU + {428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release-Nightly|x86.ActiveCfg = Debug|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|Any CPU {428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release-Stable|Any CPU.Build.0 = Release|Any CPU {428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release-Stable|Mixed Platforms.ActiveCfg = Release|Any CPU {428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release-Stable|Mixed Platforms.Build.0 = Release|Any CPU {428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release-Stable|x64.ActiveCfg = Release|Any CPU {428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release-Stable|x64.Build.0 = Release|Any CPU - {428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release-Stable|x86.ActiveCfg = Release|Any CPU - {428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release-Stable|x86.Build.0 = Release|Any CPU + {428D8EB9-ECA3-4A66-AA59-3A944378C33F}.Release-Stable|x86.ActiveCfg = Debug|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|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|x86.ActiveCfg = Release-Stable|Any CPU + {E46C85BD-A99C-484E-BCCE-0F1831C5925E}.Debug|x86.Build.0 = Release-Stable|Any CPU {E46C85BD-A99C-484E-BCCE-0F1831C5925E}.Release|Any CPU.ActiveCfg = Release-Stable|Any CPU {E46C85BD-A99C-484E-BCCE-0F1831C5925E}.Release|Mixed Platforms.ActiveCfg = Release-Stable|Any CPU {E46C85BD-A99C-484E-BCCE-0F1831C5925E}.Release|x64.ActiveCfg = Release-Stable|Any CPU {E46C85BD-A99C-484E-BCCE-0F1831C5925E}.Release|x86.ActiveCfg = Release-Stable|Any CPU + {E46C85BD-A99C-484E-BCCE-0F1831C5925E}.Release|x86.Build.0 = Release-Stable|Any CPU {E46C85BD-A99C-484E-BCCE-0F1831C5925E}.Release-Nightly|Any CPU.ActiveCfg = Release-Stable|Any CPU {E46C85BD-A99C-484E-BCCE-0F1831C5925E}.Release-Nightly|Mixed Platforms.ActiveCfg = Release-Stable|Any CPU {E46C85BD-A99C-484E-BCCE-0F1831C5925E}.Release-Nightly|x64.ActiveCfg = Release-Stable|Any CPU {E46C85BD-A99C-484E-BCCE-0F1831C5925E}.Release-Nightly|x86.ActiveCfg = Release-Stable|Any CPU + {E46C85BD-A99C-484E-BCCE-0F1831C5925E}.Release-Nightly|x86.Build.0 = Release-Stable|Any CPU {E46C85BD-A99C-484E-BCCE-0F1831C5925E}.Release-Stable|Any CPU.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|x86.ActiveCfg = Release-Stable|Any CPU + {E46C85BD-A99C-484E-BCCE-0F1831C5925E}.Release-Stable|x86.Build.0 = Release-Stable|Any CPU {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Debug|Any CPU.ActiveCfg = Release|Any CPU {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Debug|Any CPU.Build.0 = Release|Any CPU {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Debug|Mixed Platforms.ActiveCfg = Release|Any CPU {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Debug|Mixed Platforms.Build.0 = Release|Any CPU {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Debug|x64.ActiveCfg = Release|Any CPU {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Debug|x64.Build.0 = Release|Any CPU - {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Debug|x86.ActiveCfg = Release|Any CPU - {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Debug|x86.Build.0 = Release|Any CPU + {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Debug|x86.ActiveCfg = Release-Stable|Any CPU + {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Debug|x86.Build.0 = Release-Stable|Any CPU {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release|Any CPU.ActiveCfg = Release|Any CPU {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release|Any CPU.Build.0 = Release|Any CPU {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release|Mixed Platforms.Build.0 = Release|Any CPU {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release|x64.ActiveCfg = Release|Any CPU {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release|x64.Build.0 = Release|Any CPU - {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release|x86.ActiveCfg = Release|Any CPU - {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release|x86.Build.0 = Release|Any CPU + {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release|x86.ActiveCfg = Release-Stable|Any CPU + {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release|x86.Build.0 = Release-Stable|Any CPU {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release-Nightly|Any CPU.ActiveCfg = Release|Any CPU {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release-Nightly|Any CPU.Build.0 = Release|Any CPU {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release-Nightly|Mixed Platforms.ActiveCfg = Release|Any CPU {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release-Nightly|Mixed Platforms.Build.0 = Release|Any CPU {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release-Nightly|x64.ActiveCfg = Release|Any CPU {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release-Nightly|x64.Build.0 = Release|Any CPU - {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release-Nightly|x86.ActiveCfg = Release|Any CPU - {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release-Nightly|x86.Build.0 = Release|Any CPU + {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release-Nightly|x86.ActiveCfg = Release-Stable|Any CPU + {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release-Nightly|x86.Build.0 = Release-Stable|Any CPU {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release-Stable|Any CPU.ActiveCfg = Release|Any CPU {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release-Stable|Any CPU.Build.0 = Release|Any CPU {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release-Stable|Mixed Platforms.ActiveCfg = Release|Any CPU {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release-Stable|Mixed Platforms.Build.0 = Release|Any CPU {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release-Stable|x64.ActiveCfg = Release|Any CPU {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release-Stable|x64.Build.0 = Release|Any CPU - {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release-Stable|x86.ActiveCfg = Release|Any CPU - {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release-Stable|x86.Build.0 = Release|Any CPU + {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release-Stable|x86.ActiveCfg = Release-Stable|Any CPU + {C9E821BF-23AD-4CB5-B7F9-B3B99B606650}.Release-Stable|x86.Build.0 = Release-Stable|Any CPU {1479DE87-ACB5-4046-81C8-A0BA5041227D}.Debug|Any CPU.ActiveCfg = Release|Any CPU {1479DE87-ACB5-4046-81C8-A0BA5041227D}.Debug|Any CPU.Build.0 = Release|Any CPU {1479DE87-ACB5-4046-81C8-A0BA5041227D}.Debug|Mixed Platforms.ActiveCfg = Release|Any CPU {1479DE87-ACB5-4046-81C8-A0BA5041227D}.Debug|Mixed Platforms.Build.0 = Release|Any CPU {1479DE87-ACB5-4046-81C8-A0BA5041227D}.Debug|x64.ActiveCfg = Release|Any CPU {1479DE87-ACB5-4046-81C8-A0BA5041227D}.Debug|x64.Build.0 = Release|Any CPU - {1479DE87-ACB5-4046-81C8-A0BA5041227D}.Debug|x86.ActiveCfg = Release|Any CPU - {1479DE87-ACB5-4046-81C8-A0BA5041227D}.Debug|x86.Build.0 = Release|Any CPU + {1479DE87-ACB5-4046-81C8-A0BA5041227D}.Debug|x86.ActiveCfg = Debug|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.Build.0 = Release|Any CPU {1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU {1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release|Mixed Platforms.Build.0 = Release|Any CPU {1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release|x64.ActiveCfg = Release|Any CPU {1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release|x64.Build.0 = Release|Any CPU - {1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release|x86.ActiveCfg = Release|Any CPU - {1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release|x86.Build.0 = Release|Any CPU + {1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release|x86.ActiveCfg = Debug|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.Build.0 = Release|Any CPU {1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release-Nightly|Mixed Platforms.ActiveCfg = Release|Any CPU {1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release-Nightly|Mixed Platforms.Build.0 = Release|Any CPU {1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release-Nightly|x64.ActiveCfg = Release|Any CPU {1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release-Nightly|x64.Build.0 = Release|Any CPU - {1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release-Nightly|x86.ActiveCfg = Release|Any CPU - {1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release-Nightly|x86.Build.0 = 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 = 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.Build.0 = Release|Any CPU {1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release-Stable|Mixed Platforms.ActiveCfg = Release|Any CPU {1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release-Stable|Mixed Platforms.Build.0 = Release|Any CPU {1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release-Stable|x64.ActiveCfg = Release|Any CPU {1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release-Stable|x64.Build.0 = Release|Any CPU - {1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release-Stable|x86.ActiveCfg = Release|Any CPU - {1479DE87-ACB5-4046-81C8-A0BA5041227D}.Release-Stable|x86.Build.0 = 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 = Debug|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/SharedLibrary/RCON.cs b/SharedLibrary/RCON.cs index 4df31b5dd..e46cdfbfb 100644 --- a/SharedLibrary/RCON.cs +++ b/SharedLibrary/RCON.cs @@ -23,8 +23,8 @@ namespace SharedLibrary.Network static string[] SendQuery(QueryType Type, Server QueryServer, string Parameters = "") { var ServerOOBConnection = new UdpClient(); - ServerOOBConnection.Client.SendTimeout = 1000; - ServerOOBConnection.Client.ReceiveTimeout = 1000; + ServerOOBConnection.Client.SendTimeout = 3000; + ServerOOBConnection.Client.ReceiveTimeout = 3000; var Endpoint = new IPEndPoint(IPAddress.Parse(QueryServer.GetIP()), QueryServer.GetPort()); string QueryString = String.Empty; @@ -63,18 +63,25 @@ namespace SharedLibrary.Network if (QueryResponseString.ToString().Contains("Invalid password")) throw new Exceptions.NetworkException("RCON password is invalid"); + if (QueryResponseString.ToString().Contains("rcon_password")) + throw new Exceptions.NetworkException("RCON password has not been set"); int num = int.Parse("0a", System.Globalization.NumberStyles.AllowHexSpecifier); string[] SplitResponse = QueryResponseString.ToString().Split(new char[] { (char)num }, StringSplitOptions.RemoveEmptyEntries); return SplitResponse; } + catch (Exceptions.NetworkException e) + { + throw e; + } + catch (Exception) { attempts++; if (attempts > 5) { - var e = new Exceptions.NetworkException("Cannot communicate with server"); + var e = new Exceptions.NetworkException("Could not communicate with the server (ensure the configuration is correct)"); e.Data["server_address"] = ServerOOBConnection.Client.RemoteEndPoint.ToString(); ServerOOBConnection.Close(); throw e; diff --git a/SharedLibrary/Server.cs b/SharedLibrary/Server.cs index 30934cc7f..7a9795cb7 100644 --- a/SharedLibrary/Server.cs +++ b/SharedLibrary/Server.cs @@ -14,6 +14,16 @@ namespace SharedLibrary [Guid("61d3829e-fcbe-44d3-bb7c-51db8c2d7ac5")] public abstract class Server { + public enum Game + { + UKN, + IW3, + IW4, + IW5, + T4, + T5, + } + public Server(Interfaces.IManager mgr, ServerConfiguration config) { Password = config.Password; @@ -146,9 +156,10 @@ namespace SharedLibrary public async Task Broadcast(String Message) { #if DEBUG - return; + //return; #endif - await this.ExecuteCommandAsync($"sayraw {Message}"); + string sayCommand = (GameName == Game.IW4) ? "sayraw" : "say"; + await this.ExecuteCommandAsync($"{sayCommand} {Message}"); } /// @@ -159,11 +170,13 @@ namespace SharedLibrary public async Task Tell(String Message, Player Target) { #if DEBUG - if (!Target.lastEvent.Remote) - return; + //if (!Target.lastEvent.Remote) + // return; #endif + string tellCommand = (GameName == Game.IW4) ? "tellraw" : "tell"; + if (Target.ClientID > -1 && Message.Length > 0 && Target.Level != Player.Permission.Console && !Target.lastEvent.Remote) - await this.ExecuteCommandAsync($"tellraw {Target.ClientID} {Message}^7"); + await this.ExecuteCommandAsync($"{tellCommand} {Target.ClientID} {Message}^7"); if (Target.Level == Player.Permission.Console) { @@ -346,6 +359,7 @@ namespace SharedLibrary public List Reports { get; set; } public List ChatHistory { get; protected set; } public Queue PlayerHistory { get; private set; } + public Game GameName { get; protected set; } // Info public string Hostname { get; protected set; } diff --git a/SharedLibrary/Utilities.cs b/SharedLibrary/Utilities.cs index 2287e33ae..cb197c9ae 100644 --- a/SharedLibrary/Utilities.cs +++ b/SharedLibrary/Utilities.cs @@ -4,6 +4,7 @@ using System.Text; using System.Text.RegularExpressions; using System.Linq; using System.Collections.Generic; +using static SharedLibrary.Server; namespace SharedLibrary { @@ -246,5 +247,21 @@ namespace SharedLibrary else return "a very long time"; } + + public static Game GetGame(string gameName) + { + if (gameName.Contains("IW4")) + return Game.IW4; + if (gameName.Contains("CoD4")) + return Game.IW3; + if (gameName.Contains("WaW")) + return Game.T4; + if (gameName.Contains("COD_T5_S")) + return Game.T5; + if (gameName.Contains("IW5")) + return Game.IW5; + + return Game.UKN; + } } }