diff --git a/Application/Application.csproj b/Application/Application.csproj
index 000c5ede5..0165f96fb 100644
--- a/Application/Application.csproj
+++ b/Application/Application.csproj
@@ -6,7 +6,7 @@
2.1.5
false
RaidMax.IW4MAdmin.Application
- 2.2.4.3
+ 2.2.4.4
RaidMax
Forever None
IW4MAdmin
@@ -31,8 +31,8 @@
true
true
- 2.2.4.3
- 2.2.4.3
+ 2.2.4.4
+ 2.2.4.4
diff --git a/Application/ApplicationManager.cs b/Application/ApplicationManager.cs
index 693ee5bdb..bc6519036 100644
--- a/Application/ApplicationManager.cs
+++ b/Application/ApplicationManager.cs
@@ -210,6 +210,25 @@ namespace IW4MAdmin.Application
{
Running = true;
+
+ #region PLUGINS
+ SharedLibraryCore.Plugins.PluginImporter.Load(this);
+
+ foreach (var Plugin in SharedLibraryCore.Plugins.PluginImporter.ActivePlugins)
+ {
+ try
+ {
+ await Plugin.OnLoadAsync(this);
+ }
+
+ catch (Exception ex)
+ {
+ Logger.WriteError($"{Utilities.CurrentLocalization.LocalizationIndex["SERVER_ERROR_PLUGIN"]} {Plugin.Name}");
+ Logger.WriteDebug(ex.GetExceptionInfo());
+ }
+ }
+ #endregion
+
#region CONFIG
var config = ConfigHandler.Configuration();
@@ -232,7 +251,18 @@ namespace IW4MAdmin.Application
do
{
- newConfig.Servers.Add((ServerConfiguration)new ServerConfiguration().Generate());
+ var serverConfig = new ServerConfiguration();
+ foreach (var parser in AdditionalRConParsers)
+ {
+ serverConfig.AddRConParser(parser);
+ }
+
+ foreach (var parser in AdditionalEventParsers)
+ {
+ serverConfig.AddEventParser(parser);
+ }
+
+ newConfig.Servers.Add((ServerConfiguration)serverConfig.Generate());
} while (Utilities.PromptBool(Utilities.CurrentLocalization.LocalizationIndex["SETUP_SERVER_SAVE"]));
config = newConfig;
@@ -275,24 +305,6 @@ namespace IW4MAdmin.Application
PrivilegedClients = (await ClientSvc.GetPrivilegedClients()).ToDictionary(_client => _client.ClientId);
#endregion
- #region PLUGINS
- SharedLibraryCore.Plugins.PluginImporter.Load(this);
-
- foreach (var Plugin in SharedLibraryCore.Plugins.PluginImporter.ActivePlugins)
- {
- try
- {
- await Plugin.OnLoadAsync(this);
- }
-
- catch (Exception ex)
- {
- Logger.WriteError($"{Utilities.CurrentLocalization.LocalizationIndex["SERVER_ERROR_PLUGIN"]} {Plugin.Name}");
- Logger.WriteDebug(ex.GetExceptionInfo());
- }
- }
- #endregion
-
#region COMMANDS
if (ClientSvc.GetOwners().Result.Count == 0)
{
diff --git a/Application/RconParsers/BaseRConParser.cs b/Application/RconParsers/BaseRConParser.cs
index d477b9ad4..b84ff0eff 100644
--- a/Application/RconParsers/BaseRConParser.cs
+++ b/Application/RconParsers/BaseRConParser.cs
@@ -42,7 +42,7 @@ namespace IW4MAdmin.Application.RconParsers
Configuration.Status.AddMapping(ParserRegex.GroupType.RConName, 5);
Configuration.Status.AddMapping(ParserRegex.GroupType.RConIpAddress, 7);
- Configuration.Dvar.Pattern = "^\"(.+)\" is: \"(.+)\" default: \"(.+)\"\n(?:latched: \"(.+)\"\n)? *(.+)$";
+ Configuration.Dvar.Pattern = "^\"(.+)\" is: \"(.+)\" default: \"(.+)?\"\n(?:latched: \"(.+)?\"\n)? *(.+)$";
Configuration.Dvar.AddMapping(ParserRegex.GroupType.RConDvarName, 1);
Configuration.Dvar.AddMapping(ParserRegex.GroupType.RConDvarValue, 2);
Configuration.Dvar.AddMapping(ParserRegex.GroupType.RConDvarDefaultValue, 3);
diff --git a/SharedLibraryCore/Configuration/ServerConfiguration.cs b/SharedLibraryCore/Configuration/ServerConfiguration.cs
index 4e8aa744a..a302787bc 100644
--- a/SharedLibraryCore/Configuration/ServerConfiguration.cs
+++ b/SharedLibraryCore/Configuration/ServerConfiguration.cs
@@ -1,6 +1,7 @@
using SharedLibraryCore.Interfaces;
using System;
using System.Collections.Generic;
+using System.Linq;
namespace SharedLibraryCore.Configuration
{
@@ -11,11 +12,22 @@ namespace SharedLibraryCore.Configuration
public string Password { get; set; }
public IList Rules { get; set; }
public IList AutoMessages { get; set; }
- public bool UseT6MParser { get; set; }
public string ManualLogPath { get; set; }
public string CustomParserVersion { get; set; }
public int ReservedSlotNumber { get; set; }
+ private readonly IList rconParsers;
+ private readonly IList eventParsers;
+
+ public ServerConfiguration()
+ {
+ rconParsers = new List();
+ eventParsers = new List();
+ }
+
+ public void AddRConParser(IRConParser parser) => rconParsers.Add(parser);
+ public void AddEventParser(IEventParser parser) => eventParsers.Add(parser);
+
public IBaseConfiguration Generate()
{
var loc = Utilities.CurrentLocalization.LocalizationIndex;
@@ -38,9 +50,24 @@ namespace SharedLibraryCore.Configuration
Password = Utilities.PromptString(loc["SETUP_SERVER_RCON"]);
AutoMessages = new List();
Rules = new List();
- UseT6MParser = Utilities.PromptBool(loc["SETUP_SERVER_USET6M"]);
ReservedSlotNumber = loc["SETUP_SERVER_RESERVEDSLOT"].PromptInt(null, 0, 32);
+ var parserVersions = rconParsers.Select(_parser => _parser.Version).ToArray();
+ var selection = Utilities.PromptSelection(loc["SETUP_SERVER_RCON_PARSER_VERSION"], $"{loc["SETUP_PROMPT_DEFAULT"]} (IW4x)", null, parserVersions);
+
+ if (selection.Item1 > 0)
+ {
+ CustomParserVersion = selection.Item2;
+ }
+
+ parserVersions = eventParsers.Select(_parser => _parser.Version).ToArray();
+ selection = Utilities.PromptSelection(loc["SETUP_SERVER_EVENT_PARSER_VERSION"], $"{loc["SETUP_PROMPT_DEFAULT"]} (IW4x)", null, parserVersions);
+
+ if (selection.Item1 > 0)
+ {
+ CustomParserVersion = selection.Item2;
+ }
+
return this;
}
diff --git a/SharedLibraryCore/Helpers/Vector3.cs b/SharedLibraryCore/Helpers/Vector3.cs
index b7850ecdd..d38b6d86d 100644
--- a/SharedLibraryCore/Helpers/Vector3.cs
+++ b/SharedLibraryCore/Helpers/Vector3.cs
@@ -21,6 +21,7 @@ namespace SharedLibraryCore.Helpers
{
}
+
public Vector3(float x, float y, float z)
{
X = x;
diff --git a/SharedLibraryCore/RCon/Connection.cs b/SharedLibraryCore/RCon/Connection.cs
index b09012c21..5d09f3e3a 100644
--- a/SharedLibraryCore/RCon/Connection.cs
+++ b/SharedLibraryCore/RCon/Connection.cs
@@ -81,13 +81,13 @@ namespace SharedLibraryCore.RCon
{
case StaticHelpers.QueryType.GET_DVAR:
waitForResponse |= true;
- payload = (string.Format(Config.CommandPrefixes.RConGetDvar, RConPassword, parameters + '\0')).Select(Convert.ToByte).ToArray();
+ payload = Utilities.EncodingType.GetBytes(string.Format(Config.CommandPrefixes.RConGetDvar, RConPassword, parameters + '\0'));
break;
case StaticHelpers.QueryType.SET_DVAR:
- payload = (string.Format(Config.CommandPrefixes.RConSetDvar, RConPassword, parameters + '\0')).Select(Convert.ToByte).ToArray();
+ payload = Utilities.EncodingType.GetBytes(string.Format(Config.CommandPrefixes.RConSetDvar, RConPassword, parameters + '\0'));
break;
case StaticHelpers.QueryType.COMMAND:
- payload = (string.Format(Config.CommandPrefixes.RConCommand, RConPassword, parameters + '\0')).Select(Convert.ToByte).ToArray();
+ payload = Utilities.EncodingType.GetBytes(string.Format(Config.CommandPrefixes.RConCommand, RConPassword, parameters + '\0'));
break;
case StaticHelpers.QueryType.GET_STATUS:
waitForResponse |= true;
diff --git a/SharedLibraryCore/Utilities.cs b/SharedLibraryCore/Utilities.cs
index b030f25f6..08cb7052a 100644
--- a/SharedLibraryCore/Utilities.cs
+++ b/SharedLibraryCore/Utilities.cs
@@ -492,6 +492,45 @@ namespace SharedLibraryCore
return response != 0 ? response == 'y' : defaultValue;
}
+ ///
+ /// prompt user to make a selection
+ ///
+ /// type of selection
+ /// question to prompt the user with
+ /// default value to set if no input is entered
+ /// description of the question's value
+ /// array of possible selections (should be able to convert to string)
+ ///
+ public static Tuple PromptSelection(string question, T defaultValue, string description = null, params T[] selections)
+ {
+ bool hasDefault = false;
+
+ if (defaultValue != null)
+ {
+ hasDefault = true;
+ selections = (new T[] { defaultValue }).Union(selections).ToArray();
+ }
+
+ Console.WriteLine($"{question}{(string.IsNullOrEmpty(description) ? "" : $" [{ description}:]")}");
+ Console.WriteLine(new string('=', 52));
+ for (int index = 0; index < selections.Length; index++)
+ {
+ Console.WriteLine($"{(hasDefault ? index : index + 1)}] {selections[index]}");
+ }
+ Console.WriteLine(new string('=', 52));
+
+ int selectionIndex = PromptInt(CurrentLocalization.LocalizationIndex["SETUP_PROMPT_MAKE_SELECTION"], null, hasDefault ? 0 : 1, selections.Length, hasDefault ? 0 : (int?)null);
+
+ if (!hasDefault)
+ {
+ selectionIndex--;
+ }
+
+ T selection = selections[selectionIndex ];
+
+ return Tuple.Create(selectionIndex, selection);
+ }
+
///
/// prompt user to enter a number
///
@@ -503,7 +542,7 @@ namespace SharedLibraryCore
/// integer from user's input
public static int PromptInt(this string question, string description = null, int minValue = 0, int maxValue = int.MaxValue, int? defaultValue = null)
{
- Console.Write($"{question}{(string.IsNullOrEmpty(description) ? "" : $" ({description})")}{(defaultValue == null ? "" : $" [{CurrentLocalization.LocalizationIndex["SETUP_PROMPT_DEFAULT"]} {defaultValue.Value.ToString()}")}]: ");
+ Console.Write($"{question}{(string.IsNullOrEmpty(description) ? "" : $" ({description})")}{(defaultValue == null ? "" : $" [{CurrentLocalization.LocalizationIndex["SETUP_PROMPT_DEFAULT"]} {defaultValue.Value.ToString()}]")}: ");
int response;
string inputOrDefault()