From 385c0a3c38bd927368ac5a0ed2950e6bd73baf1f Mon Sep 17 00:00:00 2001 From: jupster Date: Wed, 15 May 2024 16:31:40 +1000 Subject: [PATCH 01/45] update to AdvanceOptions Still to add output --- FASTER/Models/ServerCfg.cs | 98 +++++++++++++++++++------------------- 1 file changed, 50 insertions(+), 48 deletions(-) diff --git a/FASTER/Models/ServerCfg.cs b/FASTER/Models/ServerCfg.cs index d96b2df..b8d5f2f 100644 --- a/FASTER/Models/ServerCfg.cs +++ b/FASTER/Models/ServerCfg.cs @@ -47,14 +47,10 @@ public class ServerCfg : INotifyPropertyChanged private bool autoSelectMission = true; private bool randomMissionOrder = true; private int briefingTimeOut = 60; // <- - private int roleTimeOut = 90; // <- These are BI base figues - private int votingTimeOut = 60; // <- + private int roleTimeOut = 90; // <- These are BI base figues + private int votingTimeOut = 60; // <- private int debriefingTimeOut = 45; // <- - private bool LogObjectNotFound = true; // logging enabled - private bool SkipDescriptionParsing = false; // parse description.ext - private bool ignoreMissionLoadErrors = false; // do not ingore errors private int armaUnitsTimeout = 30; // Defines how long the player will be stuck connecting and wait for armaUnits data. Player will be notified if timeout elapsed and no units data was received - private int queueSizeLogG = 1000000; // if a specific players message queue is larger than 1MB and '#monitor' is running, dump his messages to a logfile for analysis private string forcedDifficulty = "Custom"; // By default forcedDifficulty is only applying Custom @@ -97,7 +93,53 @@ public class ServerCfg : INotifyPropertyChanged private string serverCfgContent; + public class AdvancedOptions + { + private bool LogObjectNotFound = true; // logging enabled + private bool SkipDescriptionParsing = false; // parse description.ext + private bool ignoreMissionLoadErrors = false; // do not ingore errors + private int queueSizeLogG = 1000000; // if a specific players message queue is larger than 1MB and '#monitor' is running, dump his messages to a logfile for analysis + public bool LogObjectNotFound + { + get => LogObjectNotFound; + set + { + LogObjectNotFound = value; + RaisePropertyChanged("logObjectNotFound"); + } + } + + public bool SkipDescriptionParsing + { + get => SkipDescriptionParsing; + set + { + SkipDescriptionParsing = value; + RaisePropertyChanged("skipDescriptionParsing"); + } + } + + public bool IgnoreMissionLoadErrors + { + get => ignoreMissionLoadErrors; + set + { + ignoreMissionLoadErrors = value; + RaisePropertyChanged("IgnoreMissionLoadErrors"); + } + } + + public int QueueSizeLogG + { + get => queueSizeLogG; + set + { + queueSizeLogG = value; + RaisePropertyChanged("QueueSizeLogG"); + } + } + } #region Server Options public string PasswordAdmin @@ -394,36 +436,6 @@ public int DebriefingTimeOut } } - public bool logObjectNotFound - { - get => LogObjectNotFound; - set - { - LogObjectNotFound = value; - RaisePropertyChanged("logObjectNotFound"); - } - } - - public bool skipDescriptionParsing - { - get => SkipDescriptionParsing; - set - { - SkipDescriptionParsing = value; - RaisePropertyChanged("skipDescriptionParsing"); - } - } - - public bool IgnoreMissionLoadErrors - { - get => ignoreMissionLoadErrors; - set - { - ignoreMissionLoadErrors = value; - RaisePropertyChanged("IgnoreMissionLoadErrors"); - } - } - public int ArmaUnitsTimeout { get => armaUnitsTimeout; @@ -434,16 +446,6 @@ public int ArmaUnitsTimeout } } - public int QueueSizeLogG - { - get => queueSizeLogG; - set - { - queueSizeLogG = value; - RaisePropertyChanged("QueueSizeLogG"); - } - } - public string ForcedDifficulty { get => forcedDifficulty; @@ -893,8 +895,8 @@ public string ProcessFile() + $"timeStampFormat = \"{timeStampFormat}\";\t\t// Set the timestamp format used on each report line in server-side RPT file. Possible values are \"none\" (default),\"short\",\"full\".\r\n" + $"BattlEye = {battlEye};\t\t\t\t// Server to use BattlEye system\r\n" + $"queueSizeLogG = {queueSizeLogG};\t\t\t// If a specific players message queue is larger than 1MB and #monitor is running, dump his messages to a logfile for analysis \r\n" - + $"LogObjectNotFound = {logObjectNotFound};\t\t// When false to skip logging 'Server: Object not found messages'.\r\n" - + $"SkipDescriptionParsing = {skipDescriptionParsing};\t\t// When true to skip parsing of description.ext/mission.sqm. Will show pbo filename instead of configured missionName. OverviewText and such won't work, but loading the mission list is a lot faster when there are many missions \r\n" + + $"LogObjectNotFound = {LogObjectNotFound};\t\t// When false to skip logging 'Server: Object not found messages'.\r\n" + + $"SkipDescriptionParsing = {SkipDescriptionParsing};\t\t// When true to skip parsing of description.ext/mission.sqm. Will show pbo filename instead of configured missionName. OverviewText and such won't work, but loading the mission list is a lot faster when there are many missions \r\n" + $"ignoreMissionLoadErrors = {ignoreMissionLoadErrors};\t\t// When set to true, the mission will load no matter the amount of loading errors. If set to false, the server will abort mission's loading and return to mission selection.\r\n" + $"forcedDifficulty = {forcedDifficulty};\t\t\t// Forced difficulty (Recruit, Regular, Veteran, Custom)\r\n" + "\r\n" From 99b4ef8a6e462cd65633873985faca50e621b59a Mon Sep 17 00:00:00 2001 From: jupster Date: Wed, 15 May 2024 17:56:44 +1000 Subject: [PATCH 02/45] Update ServerCfg.cs --- FASTER/Models/ServerCfg.cs | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/FASTER/Models/ServerCfg.cs b/FASTER/Models/ServerCfg.cs index b8d5f2f..06fb838 100644 --- a/FASTER/Models/ServerCfg.cs +++ b/FASTER/Models/ServerCfg.cs @@ -93,29 +93,29 @@ public class ServerCfg : INotifyPropertyChanged private string serverCfgContent; - public class AdvancedOptions + public class AdvancedOptions : INotifyPropertyChanged { - private bool LogObjectNotFound = true; // logging enabled - private bool SkipDescriptionParsing = false; // parse description.ext + private bool logObjectNotFound = true; // logging enabled + private bool skipDescriptionParsing = false; // parse description.ext private bool ignoreMissionLoadErrors = false; // do not ingore errors private int queueSizeLogG = 1000000; // if a specific players message queue is larger than 1MB and '#monitor' is running, dump his messages to a logfile for analysis public bool LogObjectNotFound { - get => LogObjectNotFound; + get => logObjectNotFound; set { - LogObjectNotFound = value; + logObjectNotFound = value; RaisePropertyChanged("logObjectNotFound"); } } public bool SkipDescriptionParsing { - get => SkipDescriptionParsing; + get => skipDescriptionParsing; set { - SkipDescriptionParsing = value; + skipDescriptionParsing = value; RaisePropertyChanged("skipDescriptionParsing"); } } @@ -126,7 +126,7 @@ public bool IgnoreMissionLoadErrors set { ignoreMissionLoadErrors = value; - RaisePropertyChanged("IgnoreMissionLoadErrors"); + RaisePropertyChanged("ignoreMissionLoadErrors"); } } @@ -136,11 +136,16 @@ public int QueueSizeLogG set { queueSizeLogG = value; - RaisePropertyChanged("QueueSizeLogG"); + RaisePropertyChanged("queueSizeLogG"); } - } - } + } + public event PropertyChangedEventHandler PropertyChanged; + private void RaisePropertyChanged(string property) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property)); + } + } #region Server Options public string PasswordAdmin { @@ -894,10 +899,10 @@ public string ProcessFile() + $"persistent = {persistent};\t\t\t\t// If 1, missions still run on even after the last player disconnected.\r\n" + $"timeStampFormat = \"{timeStampFormat}\";\t\t// Set the timestamp format used on each report line in server-side RPT file. Possible values are \"none\" (default),\"short\",\"full\".\r\n" + $"BattlEye = {battlEye};\t\t\t\t// Server to use BattlEye system\r\n" - + $"queueSizeLogG = {queueSizeLogG};\t\t\t// If a specific players message queue is larger than 1MB and #monitor is running, dump his messages to a logfile for analysis \r\n" - + $"LogObjectNotFound = {LogObjectNotFound};\t\t// When false to skip logging 'Server: Object not found messages'.\r\n" - + $"SkipDescriptionParsing = {SkipDescriptionParsing};\t\t// When true to skip parsing of description.ext/mission.sqm. Will show pbo filename instead of configured missionName. OverviewText and such won't work, but loading the mission list is a lot faster when there are many missions \r\n" - + $"ignoreMissionLoadErrors = {ignoreMissionLoadErrors};\t\t// When set to true, the mission will load no matter the amount of loading errors. If set to false, the server will abort mission's loading and return to mission selection.\r\n" + + $"queueSizeLogG = {AdvancedOptions.queueSizeLogG};\t\t\t// If a specific players message queue is larger than 1MB and #monitor is running, dump his messages to a logfile for analysis \r\n" + + $"LogObjectNotFound = {AdvancedOptions.logObjectNotFound};\t\t// When false to skip logging 'Server: Object not found messages'.\r\n" + + $"SkipDescriptionParsing = {AdvancedOptions.skipDescriptionParsing};\t\t// When true to skip parsing of description.ext/mission.sqm. Will show pbo filename instead of configured missionName. OverviewText and such won't work, but loading the mission list is a lot faster when there are many missions \r\n" + + $"ignoreMissionLoadErrors = {AdvancedOptions.ignoreMissionLoadErrors};\t\t// When set to true, the mission will load no matter the amount of loading errors. If set to false, the server will abort mission's loading and return to mission selection.\r\n" + $"forcedDifficulty = {forcedDifficulty};\t\t\t// Forced difficulty (Recruit, Regular, Veteran, Custom)\r\n" + "\r\n" + "// TIMEOUTS\r\n" From c6515fca219035fa42d330877194d15c9f40db69 Mon Sep 17 00:00:00 2001 From: jupster Date: Wed, 15 May 2024 19:47:04 +1000 Subject: [PATCH 03/45] Update ServerCfg.cs --- FASTER/Models/ServerCfg.cs | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/FASTER/Models/ServerCfg.cs b/FASTER/Models/ServerCfg.cs index 06fb838..d3a07bf 100644 --- a/FASTER/Models/ServerCfg.cs +++ b/FASTER/Models/ServerCfg.cs @@ -93,6 +93,7 @@ public class ServerCfg : INotifyPropertyChanged private string serverCfgContent; + [Serializable] public class AdvancedOptions : INotifyPropertyChanged { private bool logObjectNotFound = true; // logging enabled @@ -100,51 +101,51 @@ public class AdvancedOptions : INotifyPropertyChanged private bool ignoreMissionLoadErrors = false; // do not ingore errors private int queueSizeLogG = 1000000; // if a specific players message queue is larger than 1MB and '#monitor' is running, dump his messages to a logfile for analysis - public bool LogObjectNotFound + public bool LogObjectNotFound { get => logObjectNotFound; set { logObjectNotFound = value; - RaisePropertyChanged("logObjectNotFound"); + RaisePropertyChanged("LogObjectNotFound"); } } - public bool SkipDescriptionParsing + public bool SkipDescriptionParsing { get => skipDescriptionParsing; set { skipDescriptionParsing = value; - RaisePropertyChanged("skipDescriptionParsing"); + RaisePropertyChanged("SkipDescriptionParsing"); } - } + } - public bool IgnoreMissionLoadErrors + public bool IgnoreMissionLoadErrors { get => ignoreMissionLoadErrors; set { ignoreMissionLoadErrors = value; - RaisePropertyChanged("ignoreMissionLoadErrors"); + RaisePropertyChanged("IgnoreMissionLoadErrors"); } } - public int QueueSizeLogG + public int QueueSizeLogG { get => queueSizeLogG; set { queueSizeLogG = value; - RaisePropertyChanged("queueSizeLogG"); + RaisePropertyChanged("QueueSizeLogG"); } } - public event PropertyChangedEventHandler PropertyChanged; + public event PropertyChangedEventHandler PropertyChanged; - private void RaisePropertyChanged(string property) - { - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property)); - } + private void RaisePropertyChanged(string property) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property)); + } } #region Server Options public string PasswordAdmin @@ -899,10 +900,10 @@ public string ProcessFile() + $"persistent = {persistent};\t\t\t\t// If 1, missions still run on even after the last player disconnected.\r\n" + $"timeStampFormat = \"{timeStampFormat}\";\t\t// Set the timestamp format used on each report line in server-side RPT file. Possible values are \"none\" (default),\"short\",\"full\".\r\n" + $"BattlEye = {battlEye};\t\t\t\t// Server to use BattlEye system\r\n" - + $"queueSizeLogG = {AdvancedOptions.queueSizeLogG};\t\t\t// If a specific players message queue is larger than 1MB and #monitor is running, dump his messages to a logfile for analysis \r\n" - + $"LogObjectNotFound = {AdvancedOptions.logObjectNotFound};\t\t// When false to skip logging 'Server: Object not found messages'.\r\n" - + $"SkipDescriptionParsing = {AdvancedOptions.skipDescriptionParsing};\t\t// When true to skip parsing of description.ext/mission.sqm. Will show pbo filename instead of configured missionName. OverviewText and such won't work, but loading the mission list is a lot faster when there are many missions \r\n" - + $"ignoreMissionLoadErrors = {AdvancedOptions.ignoreMissionLoadErrors};\t\t// When set to true, the mission will load no matter the amount of loading errors. If set to false, the server will abort mission's loading and return to mission selection.\r\n" + + $"queueSizeLogG = {AdvancedOptions.QueueSizeLogG};\t\t\t// If a specific players message queue is larger than 1MB and #monitor is running, dump his messages to a logfile for analysis \r\n" + + $"LogObjectNotFound = {AdvancedOptions.LogObjectNotFound};\t\t// When false to skip logging 'Server: Object not found messages'.\r\n" + + $"SkipDescriptionParsing = {AdvancedOptions.SkipDescriptionParsing};\t\t// When true to skip parsing of description.ext/mission.sqm. Will show pbo filename instead of configured missionName. OverviewText and such won't work, but loading the mission list is a lot faster when there are many missions \r\n" + + $"ignoreMissionLoadErrors = {AdvancedOptions.IgnoreMissionLoadErrors};\t\t// When set to true, the mission will load no matter the amount of loading errors. If set to false, the server will abort mission's loading and return to mission selection.\r\n" + $"forcedDifficulty = {forcedDifficulty};\t\t\t// Forced difficulty (Recruit, Regular, Veteran, Custom)\r\n" + "\r\n" + "// TIMEOUTS\r\n" From da661958878d07f1cde1fbeaa5538a215889de34 Mon Sep 17 00:00:00 2001 From: jupster Date: Wed, 15 May 2024 20:58:27 +1000 Subject: [PATCH 04/45] Update ServerCfg.cs queueSizeLogG is default on 0. --- FASTER/Models/ServerCfg.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/FASTER/Models/ServerCfg.cs b/FASTER/Models/ServerCfg.cs index d3a07bf..37b9fa4 100644 --- a/FASTER/Models/ServerCfg.cs +++ b/FASTER/Models/ServerCfg.cs @@ -99,7 +99,7 @@ public class AdvancedOptions : INotifyPropertyChanged private bool logObjectNotFound = true; // logging enabled private bool skipDescriptionParsing = false; // parse description.ext private bool ignoreMissionLoadErrors = false; // do not ingore errors - private int queueSizeLogG = 1000000; // if a specific players message queue is larger than 1MB and '#monitor' is running, dump his messages to a logfile for analysis + private int queueSizeLogG = 0; // if a specific players message queue is larger than and '#monitor' is running, dump his messages to a logfile for analysis public bool LogObjectNotFound { @@ -119,7 +119,7 @@ public bool SkipDescriptionParsing skipDescriptionParsing = value; RaisePropertyChanged("SkipDescriptionParsing"); } - } + } public bool IgnoreMissionLoadErrors { @@ -146,7 +146,7 @@ private void RaisePropertyChanged(string property) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property)); } - } + } #region Server Options public string PasswordAdmin { @@ -900,7 +900,7 @@ public string ProcessFile() + $"persistent = {persistent};\t\t\t\t// If 1, missions still run on even after the last player disconnected.\r\n" + $"timeStampFormat = \"{timeStampFormat}\";\t\t// Set the timestamp format used on each report line in server-side RPT file. Possible values are \"none\" (default),\"short\",\"full\".\r\n" + $"BattlEye = {battlEye};\t\t\t\t// Server to use BattlEye system\r\n" - + $"queueSizeLogG = {AdvancedOptions.QueueSizeLogG};\t\t\t// If a specific players message queue is larger than 1MB and #monitor is running, dump his messages to a logfile for analysis \r\n" + + $"queueSizeLogG = {AdvancedOptions.QueueSizeLogG};\t\t\t// If a specific players message queue is larger than Value number and #monitor is running, dump his messages to a logfile for analysis \r\n" + $"LogObjectNotFound = {AdvancedOptions.LogObjectNotFound};\t\t// When false to skip logging 'Server: Object not found messages'.\r\n" + $"SkipDescriptionParsing = {AdvancedOptions.SkipDescriptionParsing};\t\t// When true to skip parsing of description.ext/mission.sqm. Will show pbo filename instead of configured missionName. OverviewText and such won't work, but loading the mission list is a lot faster when there are many missions \r\n" + $"ignoreMissionLoadErrors = {AdvancedOptions.IgnoreMissionLoadErrors};\t\t// When set to true, the mission will load no matter the amount of loading errors. If set to false, the server will abort mission's loading and return to mission selection.\r\n" From a56feba32e4b870fa339253814578aa21c02da2a Mon Sep 17 00:00:00 2001 From: jupster Date: Thu, 16 May 2024 19:40:14 +1000 Subject: [PATCH 05/45] Update ServerCfg.cs --- FASTER/Models/ServerCfg.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/FASTER/Models/ServerCfg.cs b/FASTER/Models/ServerCfg.cs index 37b9fa4..6fc6987 100644 --- a/FASTER/Models/ServerCfg.cs +++ b/FASTER/Models/ServerCfg.cs @@ -93,9 +93,11 @@ public class ServerCfg : INotifyPropertyChanged private string serverCfgContent; + private object AdvancedOptions; + [Serializable] public class AdvancedOptions : INotifyPropertyChanged - { + { private bool logObjectNotFound = true; // logging enabled private bool skipDescriptionParsing = false; // parse description.ext private bool ignoreMissionLoadErrors = false; // do not ingore errors @@ -147,6 +149,7 @@ private void RaisePropertyChanged(string property) PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property)); } } + #region Server Options public string PasswordAdmin { From 7f99b46ff6a2504a972cf0db232ffff5dd6abd5a Mon Sep 17 00:00:00 2001 From: jupster Date: Thu, 16 May 2024 21:03:15 +1000 Subject: [PATCH 06/45] Advanced Option update Issue on line 95 with duplication --- FASTER/Models/ServerCfg.cs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/FASTER/Models/ServerCfg.cs b/FASTER/Models/ServerCfg.cs index 6fc6987..c3f19df 100644 --- a/FASTER/Models/ServerCfg.cs +++ b/FASTER/Models/ServerCfg.cs @@ -92,7 +92,6 @@ public class ServerCfg : INotifyPropertyChanged private string commandLineParams; private string serverCfgContent; - private object AdvancedOptions; [Serializable] @@ -142,12 +141,12 @@ public int QueueSizeLogG RaisePropertyChanged("QueueSizeLogG"); } } - public event PropertyChangedEventHandler PropertyChanged; - - private void RaisePropertyChanged(string property) - { - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property)); - } + public event PropertyChangedEventHandler PropertyChanged; + + private void RaisePropertyChanged(string property) + { + PropertyChanged(this, new PropertyChangedEventArgs(property)); + } } #region Server Options From 9ef0c57b6a9f21019b81555ef949ee626f083f0a Mon Sep 17 00:00:00 2001 From: jupster Date: Fri, 17 May 2024 23:47:37 +1000 Subject: [PATCH 07/45] Advanced Options nearly "might" work Output does not. --- FASTER/Models/ServerCfg.cs | 16 ++++++++++------ FASTER/Views/Profile.xaml | 4 ++-- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/FASTER/Models/ServerCfg.cs b/FASTER/Models/ServerCfg.cs index c3f19df..24a7fc2 100644 --- a/FASTER/Models/ServerCfg.cs +++ b/FASTER/Models/ServerCfg.cs @@ -92,7 +92,6 @@ public class ServerCfg : INotifyPropertyChanged private string commandLineParams; private string serverCfgContent; - private object AdvancedOptions; [Serializable] public class AdvancedOptions : INotifyPropertyChanged @@ -142,7 +141,7 @@ public int QueueSizeLogG } } public event PropertyChangedEventHandler PropertyChanged; - + private void RaisePropertyChanged(string property) { PropertyChanged(this, new PropertyChangedEventArgs(property)); @@ -822,6 +821,11 @@ public string ServerCfgContent } } + public object QueueSizeLogG { get; set; } + public object IgnoreMissionLoadErrors { get; set; } + public object LogObjectNotFound { get; set; } + public object SkipDescriptionParsing { get; set; } + public ServerCfg() { if(string.IsNullOrWhiteSpace(serverCfgContent)) @@ -902,10 +906,10 @@ public string ProcessFile() + $"persistent = {persistent};\t\t\t\t// If 1, missions still run on even after the last player disconnected.\r\n" + $"timeStampFormat = \"{timeStampFormat}\";\t\t// Set the timestamp format used on each report line in server-side RPT file. Possible values are \"none\" (default),\"short\",\"full\".\r\n" + $"BattlEye = {battlEye};\t\t\t\t// Server to use BattlEye system\r\n" - + $"queueSizeLogG = {AdvancedOptions.QueueSizeLogG};\t\t\t// If a specific players message queue is larger than Value number and #monitor is running, dump his messages to a logfile for analysis \r\n" - + $"LogObjectNotFound = {AdvancedOptions.LogObjectNotFound};\t\t// When false to skip logging 'Server: Object not found messages'.\r\n" - + $"SkipDescriptionParsing = {AdvancedOptions.SkipDescriptionParsing};\t\t// When true to skip parsing of description.ext/mission.sqm. Will show pbo filename instead of configured missionName. OverviewText and such won't work, but loading the mission list is a lot faster when there are many missions \r\n" - + $"ignoreMissionLoadErrors = {AdvancedOptions.IgnoreMissionLoadErrors};\t\t// When set to true, the mission will load no matter the amount of loading errors. If set to false, the server will abort mission's loading and return to mission selection.\r\n" + + $"queueSizeLogG = {QueueSizeLogG};\t\t\t// If a specific players message queue is larger than Value number and #monitor is running, dump his messages to a logfile for analysis \r\n" + + $"LogObjectNotFound = {LogObjectNotFound};\t\t// When false to skip logging 'Server: Object not found messages'.\r\n" + + $"SkipDescriptionParsing = {SkipDescriptionParsing};\t\t// When true to skip parsing of description.ext/mission.sqm. Will show pbo filename instead of configured missionName. OverviewText and such won't work, but loading the mission list is a lot faster when there are many missions \r\n" + + $"ignoreMissionLoadErrors = {IgnoreMissionLoadErrors};\t\t// When set to true, the mission will load no matter the amount of loading errors. If set to false, the server will abort mission's loading and return to mission selection.\r\n" + $"forcedDifficulty = {forcedDifficulty};\t\t\t// Forced difficulty (Recruit, Regular, Veteran, Custom)\r\n" + "\r\n" + "// TIMEOUTS\r\n" diff --git a/FASTER/Views/Profile.xaml b/FASTER/Views/Profile.xaml index 365a855..cb0e156 100644 --- a/FASTER/Views/Profile.xaml +++ b/FASTER/Views/Profile.xaml @@ -633,8 +633,8 @@ - - + + From 2699755344fb4cf2a70f6593a091038be422128a Mon Sep 17 00:00:00 2001 From: jupster Date: Thu, 26 Sep 2024 10:22:31 +1000 Subject: [PATCH 08/45] Version Bump --- FASTER/FASTER.csproj | 2 +- FASTER_Version.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/FASTER/FASTER.csproj b/FASTER/FASTER.csproj index 8e9ee5c..f2e4637 100644 --- a/FASTER/FASTER.csproj +++ b/FASTER/FASTER.csproj @@ -9,7 +9,7 @@ true false true - 1.9.5.2 + 1.9.6.1 Keelah Fox FoxliCorp. Fox's Arma Server Tool Extended Rewrite diff --git a/FASTER_Version.xml b/FASTER_Version.xml index 3569db0..b1f15c5 100644 --- a/FASTER_Version.xml +++ b/FASTER_Version.xml @@ -1,6 +1,6 @@  - 1.9.5.2 + 1.9.6.1 https://github.com/Foxlider/FASTER/releases/latest/download/Release_x64.zip https://github.com/Foxlider/FASTER/releases true From eb55b44494900efb33de0bef000a136af8197bfe Mon Sep 17 00:00:00 2001 From: jupster Date: Thu, 26 Sep 2024 14:24:02 +1000 Subject: [PATCH 09/45] Updates for AdvancedOptions Close to done just don't have time to finish --- FASTER/Models/ServerCfg.cs | 170 ++++++++++++++++++--------------- FASTER/Models/ServerProfile.cs | 29 ++++-- 2 files changed, 117 insertions(+), 82 deletions(-) diff --git a/FASTER/Models/ServerCfg.cs b/FASTER/Models/ServerCfg.cs index 24a7fc2..8e56545 100644 --- a/FASTER/Models/ServerCfg.cs +++ b/FASTER/Models/ServerCfg.cs @@ -21,12 +21,12 @@ public class ServerCfg : INotifyPropertyChanged private string passwordAdmin; private string password; private string hostname; - private int maxPlayers = 32; - private List motd = new(); + private int maxPlayers = 32; + private List motd = new(); private int motdInterval; - private List admins = new(); - private List headlessClients = new(); - private List localClient = new(); + private List admins = new(); + private List headlessClients = new(); + private List localClient = new(); private bool headlessClientEnabled; private bool votingEnabled; private bool netlogEnabled; @@ -53,7 +53,6 @@ public class ServerCfg : INotifyPropertyChanged private int armaUnitsTimeout = 30; // Defines how long the player will be stuck connecting and wait for armaUnits data. Player will be notified if timeout elapsed and no units data was received private string forcedDifficulty = "Custom"; // By default forcedDifficulty is only applying Custom - //Arma server only private short verifySignatures = 0; // 0 = Disabled (FASTER Default); 1 = Deprecated Activated ; 2 = Activated (Arma Default) private bool drawingInMap = true; @@ -74,14 +73,14 @@ public class ServerCfg : INotifyPropertyChanged private string doubleIdDetected; private string onUserConnected; private string onUserDisconnected; - private string onHackedData = "kick (_this select 0)"; + private string onHackedData = "kick (_this select 0)"; private string onDifferentData; - private string onUnsignedData = "kick (_this select 0)"; + private string onUnsignedData = "kick (_this select 0)"; private string onUserKicked; private bool missionSelectorChecked; private string missionContentOverride; - private List _missions = new(); + private List _missions = new(); private bool autoInit; private string difficulty = "Custom"; @@ -93,61 +92,6 @@ public class ServerCfg : INotifyPropertyChanged private string serverCfgContent; - [Serializable] - public class AdvancedOptions : INotifyPropertyChanged - { - private bool logObjectNotFound = true; // logging enabled - private bool skipDescriptionParsing = false; // parse description.ext - private bool ignoreMissionLoadErrors = false; // do not ingore errors - private int queueSizeLogG = 0; // if a specific players message queue is larger than and '#monitor' is running, dump his messages to a logfile for analysis - - public bool LogObjectNotFound - { - get => logObjectNotFound; - set - { - logObjectNotFound = value; - RaisePropertyChanged("LogObjectNotFound"); - } - } - - public bool SkipDescriptionParsing - { - get => skipDescriptionParsing; - set - { - skipDescriptionParsing = value; - RaisePropertyChanged("SkipDescriptionParsing"); - } - } - - public bool IgnoreMissionLoadErrors - { - get => ignoreMissionLoadErrors; - set - { - ignoreMissionLoadErrors = value; - RaisePropertyChanged("IgnoreMissionLoadErrors"); - } - } - - public int QueueSizeLogG - { - get => queueSizeLogG; - set - { - queueSizeLogG = value; - RaisePropertyChanged("QueueSizeLogG"); - } - } - public event PropertyChangedEventHandler PropertyChanged; - - private void RaisePropertyChanged(string property) - { - PropertyChanged(this, new PropertyChangedEventArgs(property)); - } - } - #region Server Options public string PasswordAdmin { @@ -820,18 +764,94 @@ public string ServerCfgContent RaisePropertyChanged("ServerCfgContent"); } } - - public object QueueSizeLogG { get; set; } - public object IgnoreMissionLoadErrors { get; set; } - public object LogObjectNotFound { get; set; } - public object SkipDescriptionParsing { get; set; } - + public ServerCfg() { if(string.IsNullOrWhiteSpace(serverCfgContent)) { ServerCfgContent = ProcessFile(); } } + public object LogObjectNotFound { get; private set; } + public object SkipDescriptionParsing { get; private set; } + public object IgnoreMissionLoadErrors { get; private set; } + public object QueueSizeLogG { get; private set; } + + [Serializable] + public class AdvancedOptions : INotifyPropertyChanged + { + private bool logObjectNotFound = true; // logging enabled + private bool skipDescriptionParsing = false; // Parse description.ext + private bool ignoreMissionLoadErrors = false; // Do not ingore errors + private int queueSizeLogG = 0; // If a specific players message queue is larger than and '#monitor' is running, dump his messages to a logfile for analysis + + public bool LogObjectNotFound + { + get => logObjectNotFound; + set + { + logObjectNotFound = value; + RaisePropertyChanged("LogObjectNotFound"); + } + } + + public bool SkipDescriptionParsing + { + get => skipDescriptionParsing; + set + { + skipDescriptionParsing = value; + RaisePropertyChanged("SkipDescriptionParsing"); + } + } + + public bool IgnoreMissionLoadErrors + { + get => ignoreMissionLoadErrors; + set + { + ignoreMissionLoadErrors = value; + RaisePropertyChanged("IgnoreMissionLoadErrors"); + } + } + + public int QueueSizeLogG + { + get => queueSizeLogG; + set + { + queueSizeLogG = value; + RaisePropertyChanged("QueueSizeLogG"); + } + } + + private string advancedOptionsContent; + + public string AdvancedOptionsContent + { + get => AdvancedOptionsContent; + set + { + AdvancedOptionsContent = value; + RaisePropertyChanged("AdvancedOptionsContent"); + } + } + + public Advancedoptions() + { + if(string.IsNullOrWhiteSpace(AdvancedOptionsContent)) + { AdvancedOptionsContent = ProcessFile(); } + } + + public event PropertyChangedEventHandler PropertyChanged; + + private void RaisePropertyChanged(string property) + { + if (PropertyChanged == null) return; + PropertyChanged(this, new PropertyChangedEventArgs(property)); + if(property != "AdvancedOptionsContent") AdvancedOptionsContent = ProcessFile(); + } + } + private void Item_PropertyChanged(object sender, PropertyChangedEventArgs e) { RaisePropertyChanged("MissionChecked"); @@ -902,7 +922,7 @@ public string ProcessFile() + $"disableVoN = {disableVoN};\t\t\t\t// If set to 1, Voice over Net will not be available\r\n" + $"vonCodec = {vonCodec};\t\t\t\t// If set to 1 then it uses IETF standard OPUS codec, if to 0 then it uses SPEEX codec (since Arma 3 update 1.58+) \r\n" + $"skipLobby = {(skipLobby ? "1" : "0")};\t\t\t\t// Overridden by mission parameters\r\n" - + $"vonCodecQuality = {vonCodecQuality};\t\t\t// since 1.62.95417 supports range 1-20 //since 1.63.x will supports range 1-30 //8kHz is 0-10, 16kHz is 11-20, 32kHz(48kHz) is 21-30 \r\n" + + $"vonCodecQuality = {vonCodecQuality};\t\t\t// Since 1.62.95417 supports range 1-20 //since 1.63.x will supports range 1-30 //8kHz is 0-10, 16kHz is 11-20, 32kHz(48kHz) is 21-30 \r\n" + $"persistent = {persistent};\t\t\t\t// If 1, missions still run on even after the last player disconnected.\r\n" + $"timeStampFormat = \"{timeStampFormat}\";\t\t// Set the timestamp format used on each report line in server-side RPT file. Possible values are \"none\" (default),\"short\",\"full\".\r\n" + $"BattlEye = {battlEye};\t\t\t\t// Server to use BattlEye system\r\n" @@ -931,9 +951,9 @@ public string ProcessFile() + $"doubleIdDetected = \"{doubleIdDetected}\";\t\t\t//\r\n" + "\r\n" + "// SIGNATURE VERIFICATION\r\n" - + $"onUnsignedData = \"{onUnsignedData}\";\t// unsigned data detected\r\n" - + $"onHackedData = \"{onHackedData}\";\t// tampering of the signature detected\r\n" - + $"onDifferentData = \"{onDifferentData}\";\t\t\t// data with a valid signature, but different version than the one present on server detected\r\n" + + $"onUnsignedData = \"{onUnsignedData}\";\t// Unsigned data detected\r\n" + + $"onHackedData = \"{onHackedData}\";\t// Tampering of the signature detected\r\n" + + $"onDifferentData = \"{onDifferentData}\";\t\t\t// Data with a valid signature, but different version than the one present on server detected\r\n" + "\r\n" + "\r\n" + "// MISSIONS CYCLE (see below)\r\n" @@ -1005,4 +1025,4 @@ private void RaisePropertyChanged(string property) PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property)); } } -} +} \ No newline at end of file diff --git a/FASTER/Models/ServerProfile.cs b/FASTER/Models/ServerProfile.cs index b74a42c..d61f9ad 100644 --- a/FASTER/Models/ServerProfile.cs +++ b/FASTER/Models/ServerProfile.cs @@ -22,13 +22,14 @@ public ServerProfileCollection() internal static void AddServerProfile(string profileName) { - var currentProfiles = Properties.Settings.Default.Profiles; + var currentProfiles = Properties.Settings.Default.Profiles; var p = new ServerProfile(profileName); - p.ServerCfg.ServerCfgContent = p.ServerCfg.ProcessFile(); - p.BasicCfg.BasicContent = p.BasicCfg.ProcessFile(); - p.ArmaProfile.ArmaProfileContent = p.ArmaProfile.ProcessFile(); + p.ServerCfg.ServerCfgContent = p.ServerCfg.ProcessFile(); + p.ServerCfg.ServerCfgContent = p.AdvancedOptions.ProcessFile(); + p.BasicCfg.BasicContent = p.BasicCfg.ProcessFile(); + p.ArmaProfile.ArmaProfileContent = p.ArmaProfile.ProcessFile(); currentProfiles.Add(p); - Properties.Settings.Default.Profiles = currentProfiles; + Properties.Settings.Default.Profiles = currentProfiles; Properties.Settings.Default.Save(); MainWindow.Instance.LoadServerProfiles(); } @@ -71,6 +72,7 @@ public class ServerProfile : INotifyPropertyChanged private bool _profileModsFilterIsRegex = false; private bool _profileModsFilterIsInvalid = false; private ServerCfg _serverCfg; + private ServerCfg _advancedOptions; private Arma3Profile _armaProfile; private BasicCfg _basicCfg; @@ -367,8 +369,8 @@ public bool ProfileModsFilterIsInvalid } } - public ServerCfg ServerCfg - { + public ServerCfg ServerCfg + { get => _serverCfg; set { @@ -379,6 +381,19 @@ public ServerCfg ServerCfg RaisePropertyChanged("ServerCfg"); } } + + public ServerCfg AdvancedOptions + { + get => _advancedOptions; + set + { + if(_advancedOptions != null) + _advancedOptions.PropertyChanged -= Class_PropertyChanged; + _advancedOptions = value; + _advancedOptions.PropertyChanged += Class_PropertyChanged; + RaisePropertyChanged("AdvancedOptions"); + } + } public Arma3Profile ArmaProfile { From 0261dded168a6af124a0f79713c3358474f3c3cb Mon Sep 17 00:00:00 2001 From: jupster Date: Sun, 13 Oct 2024 22:18:49 +1000 Subject: [PATCH 10/45] Clean code --- FASTER/FASTER.csproj | 2 -- FASTER/Models/ServerCfg.cs | 4 ++-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/FASTER/FASTER.csproj b/FASTER/FASTER.csproj index 49ae76f..70a663f 100644 --- a/FASTER/FASTER.csproj +++ b/FASTER/FASTER.csproj @@ -1,5 +1,4 @@ - WinExe net8.0-windows @@ -58,7 +57,6 @@ Settings.Designer.cs - diff --git a/FASTER/Models/ServerCfg.cs b/FASTER/Models/ServerCfg.cs index ac5e79c..dbde091 100644 --- a/FASTER/Models/ServerCfg.cs +++ b/FASTER/Models/ServerCfg.cs @@ -764,7 +764,7 @@ public string ServerCfgContent RaisePropertyChanged("ServerCfgContent"); } } - + public ServerCfg() { if(string.IsNullOrWhiteSpace(serverCfgContent)) @@ -836,7 +836,7 @@ public string AdvancedOptionsContent } } - public Advancedoptions() + public AdvancedOptions() { if(string.IsNullOrWhiteSpace(AdvancedOptionsContent)) { AdvancedOptionsContent = ProcessFile(); } From ed25c1914634b18a578c0dd9d89d165810e396f7 Mon Sep 17 00:00:00 2001 From: jupster Date: Sat, 5 Jul 2025 13:37:22 +1000 Subject: [PATCH 11/45] Refactor model classes and fix property assignments Aligned variable declarations for consistency in Arma3Profile and BasicCfg. Removed unused properties and redundant event handling from ServerCfg. Ensured AdvancedOptions and its content are properly initialized in ServerProfile constructors. --- FASTER/Models/Arma3Profile.cs | 2 +- FASTER/Models/BasicCfg.cs | 16 ++++++++-------- FASTER/Models/ServerCfg.cs | 18 ++---------------- FASTER/Models/ServerProfile.cs | 5 ++++- 4 files changed, 15 insertions(+), 26 deletions(-) diff --git a/FASTER/Models/Arma3Profile.cs b/FASTER/Models/Arma3Profile.cs index 66c0c67..2ffcce7 100644 --- a/FASTER/Models/Arma3Profile.cs +++ b/FASTER/Models/Arma3Profile.cs @@ -41,7 +41,7 @@ public class Arma3Profile : INotifyPropertyChanged private ushort mapContentMines = 1; private ushort autoReport = 0; private ushort multipleSaves = 0; - private int tacticalPing = 1; + private int tacticalPing = 1; private ushort aiLevelPreset = 3; private double skillAi = 0.5; diff --git a/FASTER/Models/BasicCfg.cs b/FASTER/Models/BasicCfg.cs index fa3cf7f..4ed760a 100644 --- a/FASTER/Models/BasicCfg.cs +++ b/FASTER/Models/BasicCfg.cs @@ -14,8 +14,8 @@ public static class BasicCfgArrays [Serializable] public class BasicCfg : INotifyPropertyChanged { - private uint viewDistance = 2000; - private double terrainGrid = 25; + private uint viewDistance = 2000; + private double terrainGrid = 25; private ushort maxMsgSend = 128; private ushort maxSizeGuaranteed = 256; @@ -158,10 +158,10 @@ public string PerfPreset MaxMsgSend = 256; MaxSizeGuaranteed = 512; MaxSizeNonGuaranteed = 256; - MinErrorToSend = 0.001; - MinErrorToSendNear = 0.01; - MaxPacketSize = 1400; - MaxCustomFileSize = 160; + MinErrorToSend = 0.001; + MinErrorToSendNear = 0.01; + MaxPacketSize = 1400; + MaxCustomFileSize = 160; switch ((short)Array.IndexOf(BasicCfgArrays.PerfPresets, value)) @@ -177,8 +177,8 @@ public string PerfPreset MinBandwidth = 250000000; break; case 4: - MaxMsgSend = 512; - MinBandwidth = 1000000000; + MaxMsgSend = 512; + MinBandwidth = 1000000000; break; } RaisePropertyChanged("PerfPreset"); diff --git a/FASTER/Models/ServerCfg.cs b/FASTER/Models/ServerCfg.cs index dbde091..ee967cf 100644 --- a/FASTER/Models/ServerCfg.cs +++ b/FASTER/Models/ServerCfg.cs @@ -771,11 +771,6 @@ public ServerCfg() { ServerCfgContent = ProcessFile(); } } - public object LogObjectNotFound { get; private set; } - public object SkipDescriptionParsing { get; private set; } - public object IgnoreMissionLoadErrors { get; private set; } - public object QueueSizeLogG { get; private set; } - [Serializable] public class AdvancedOptions : INotifyPropertyChanged { @@ -824,7 +819,7 @@ public int QueueSizeLogG } } - private string advancedOptionsContent; + private string advancedOptionsContent; public string AdvancedOptionsContent { @@ -842,16 +837,6 @@ public AdvancedOptions() { AdvancedOptionsContent = ProcessFile(); } } - public event PropertyChangedEventHandler PropertyChanged; - - private void RaisePropertyChanged(string property) - { - if (PropertyChanged == null) return; - PropertyChanged(this, new PropertyChangedEventArgs(property)); - if(property != "AdvancedOptionsContent") AdvancedOptionsContent = ProcessFile(); - } - } - private void Item_PropertyChanged(object sender, PropertyChangedEventArgs e) { RaisePropertyChanged("MissionChecked"); @@ -1025,4 +1010,5 @@ private void RaisePropertyChanged(string property) PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property)); } } + } } \ No newline at end of file diff --git a/FASTER/Models/ServerProfile.cs b/FASTER/Models/ServerProfile.cs index aed0df6..ce222d6 100644 --- a/FASTER/Models/ServerProfile.cs +++ b/FASTER/Models/ServerProfile.cs @@ -428,12 +428,14 @@ public ServerProfile(string name, bool createFolder = true) Name = name; Executable = Path.Combine(Properties.Settings.Default.serverPath, "arma3server_x64.exe"); ServerCfg = new ServerCfg(){ Hostname = name}; + AdvancedOptions = new AdvancedOptions(); ArmaProfile = new Arma3Profile(); BasicCfg = new BasicCfg(); ServerCfg.ServerCfgContent = ServerCfg.ProcessFile(); + ServerCfg.AdvancedOptionsContent = AdvancedOptions.ProcessFile(); ArmaProfile.ArmaProfileContent = ArmaProfile.ProcessFile(); BasicCfg.BasicContent = BasicCfg.ProcessFile(); - + ServerCfg.AdvancedOptionsContent = AdvancedOptions.ProcessFile(); if (createFolder) { Directory.CreateDirectory(Path.Combine(Properties.Settings.Default.serverPath, "Servers", Id)); } } @@ -446,6 +448,7 @@ public ServerProfile() ArmaProfile = new Arma3Profile(); BasicCfg = new BasicCfg(); ServerCfg.ServerCfgContent = ServerCfg.ProcessFile(); + ServerCfg.AdvancedOptionsContent = AdvancedOptions.ProcessFile(); ArmaProfile.ArmaProfileContent = ArmaProfile.ProcessFile(); BasicCfg.BasicContent = BasicCfg.ProcessFile(); } From fb605ccfd9fc1e6c059eedb201826f44fc0b90da Mon Sep 17 00:00:00 2001 From: jupster Date: Sat, 5 Jul 2025 13:51:45 +1000 Subject: [PATCH 12/45] Fix indentation in ServerProfile.cs constructor Corrected inconsistent indentation for assignment of AdvancedOptionsContent in the ServerProfile class constructor to improve code readability. --- FASTER/Models/ServerProfile.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FASTER/Models/ServerProfile.cs b/FASTER/Models/ServerProfile.cs index ce222d6..34bb3c3 100644 --- a/FASTER/Models/ServerProfile.cs +++ b/FASTER/Models/ServerProfile.cs @@ -432,7 +432,7 @@ public ServerProfile(string name, bool createFolder = true) ArmaProfile = new Arma3Profile(); BasicCfg = new BasicCfg(); ServerCfg.ServerCfgContent = ServerCfg.ProcessFile(); - ServerCfg.AdvancedOptionsContent = AdvancedOptions.ProcessFile(); + ServerCfg.AdvancedOptionsContent = AdvancedOptions.ProcessFile(); ArmaProfile.ArmaProfileContent = ArmaProfile.ProcessFile(); BasicCfg.BasicContent = BasicCfg.ProcessFile(); ServerCfg.AdvancedOptionsContent = AdvancedOptions.ProcessFile(); From 50ecf0b5ef3ad3ac54b8d626a35e09f4dfd40913 Mon Sep 17 00:00:00 2001 From: jupster Date: Sat, 5 Jul 2025 21:27:18 +1000 Subject: [PATCH 13/45] Fix typos and improve comments in ServerCfg.cs Corrected typos in comments and property change notifications. --- FASTER/Models/ServerCfg.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/FASTER/Models/ServerCfg.cs b/FASTER/Models/ServerCfg.cs index ee967cf..9405f66 100644 --- a/FASTER/Models/ServerCfg.cs +++ b/FASTER/Models/ServerCfg.cs @@ -53,7 +53,7 @@ public class ServerCfg : INotifyPropertyChanged private int armaUnitsTimeout = 30; // Defines how long the player will be stuck connecting and wait for armaUnits data. Player will be notified if timeout elapsed and no units data was received private string forcedDifficulty = "Custom"; // By default forcedDifficulty is only applying Custom - //Arma server only + //Arma Server Only private short verifySignatures = 0; // 0 = Disabled (FASTER Default); 1 = Deprecated Activated ; 2 = Activated (Arma Default) private bool drawingInMap = true; private short disableVoN; // 0 = VoN activated ; 1 = VoN Disabled @@ -78,12 +78,14 @@ public class ServerCfg : INotifyPropertyChanged private string onUnsignedData = "kick (_this select 0)"; private string onUserKicked; + //Mision Settings private bool missionSelectorChecked; private string missionContentOverride; private List _missions = new(); private bool autoInit; private string difficulty = "Custom"; + //Performance private bool maxMemOverride; private uint maxMem = 1024; private bool cpuCountOverride; @@ -283,7 +285,7 @@ public string AllowedFilePatching set { allowedFilePatching = (short)Array.IndexOf(ServerCfgArrays.AllowFilePatchingStrings, value); - RaisePropertyChanged("Password"); + RaisePropertyChanged("AllowedFilePatching"); } } @@ -776,7 +778,7 @@ public class AdvancedOptions : INotifyPropertyChanged { private bool logObjectNotFound = true; // logging enabled private bool skipDescriptionParsing = false; // Parse description.ext - private bool ignoreMissionLoadErrors = false; // Do not ingore errors + private bool ignoreMissionLoadErrors = false; // Do not ignore errors private int queueSizeLogG = 0; // If a specific players message queue is larger than and '#monitor' is running, dump his messages to a logfile for analysis public bool LogObjectNotFound From b8022f46da3735ccdb99ef49223c43cdb34a2957 Mon Sep 17 00:00:00 2001 From: jupster Date: Sun, 6 Jul 2025 17:40:52 +1000 Subject: [PATCH 14/45] Fix assignment of AdvancedOptionsContent in ServerProfile Corrects the assignment to set AdvancedOptionsContent instead of overwriting ServerCfgContent with advanced options in ServerProfile.cs. --- FASTER/Models/ServerProfile.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FASTER/Models/ServerProfile.cs b/FASTER/Models/ServerProfile.cs index 34bb3c3..71a1be1 100644 --- a/FASTER/Models/ServerProfile.cs +++ b/FASTER/Models/ServerProfile.cs @@ -25,7 +25,7 @@ internal static void AddServerProfile(string profileName) var currentProfiles = Properties.Settings.Default.Profiles; var p = new ServerProfile(profileName); p.ServerCfg.ServerCfgContent = p.ServerCfg.ProcessFile(); - p.ServerCfg.ServerCfgContent = p.AdvancedOptions.ProcessFile(); + p.ServerCfg.AdvancedOptionsContent = p.AdvancedOptions.ProcessFile(); p.BasicCfg.BasicContent = p.BasicCfg.ProcessFile(); p.ArmaProfile.ArmaProfileContent = p.ArmaProfile.ProcessFile(); currentProfiles.Add(p); From f8da3ba199bbc70a18b6b45986cd6d33428997eb Mon Sep 17 00:00:00 2001 From: jupster Date: Sun, 20 Jul 2025 15:14:37 +1000 Subject: [PATCH 15/45] Reformat FASTER.csproj and clean up property groups Reorganized the FASTER.csproj file for improved readability and maintainability by properly indenting and grouping properties. No functional changes were made. Minor whitespace adjustments were also made in the CodeQL workflow YAML. --- .github/workflows/codeql-analysis.yml | 4 +- FASTER/FASTER.csproj | 106 +++++++++++++------------- 2 files changed, 55 insertions(+), 55 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 612e270..6e1b0a3 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -39,12 +39,12 @@ jobs: uses: github/codeql-action/init@v3 with: languages: ${{ matrix.language }} - + - name: Setup .NET Core SDK uses: actions/setup-dotnet@v4.0.0 with: dotnet-version: ${{env.DOTNET_VERSION}} - + - name: Restore Solution run: dotnet restore ./FASTER.sln diff --git a/FASTER/FASTER.csproj b/FASTER/FASTER.csproj index c79a75a..6c4d618 100644 --- a/FASTER/FASTER.csproj +++ b/FASTER/FASTER.csproj @@ -1,64 +1,64 @@ - - WinExe net9.0-windows true - enable - enable - true - Resources\FASTER.ico - Properties\FASTER.manifest - True - FASTERKey.snk - Keelah Fox, Jupster, Canno.n 1.9.7.1 - FoxliCorp. - Fox's Arma Server Tool Extended Rewrite - Copyright © 2019 - https://github.com/Foxlider/FASTER - README.md - https://github.com/Foxlider/FASTER - LICENSE - - true - true - true - false - + + WinExe + enable + enable + true + Resources\FASTER.ico + Properties\FASTER.manifest + True + FASTERKey.snk + Keelah Fox, Jupster, Canno.n + FoxliCorp. + Fox's Arma Server Tool Extended Rewrite + Copyright © 2019 + https://github.com/Foxlider/FASTER + README.md + https://github.com/Foxlider/FASTER + LICENSE + true + true + true + false + - - portable - 1701;1702;NU1701;CS8002;CS8618;CS8622 - - - none - 1701;1702;NU1701;CS8002;CS8618;CS8622 - + + portable + 1701;1702;NU1701;CS8002;CS8618;CS8622 + - - - PreserveNewest - - - - - - - - True - True - Settings.settings - - - - - SettingsSingleFileGenerator - Settings.Designer.cs - - - + + none + 1701;1702;NU1701;CS8002;CS8618;CS8622 + + + + + PreserveNewest + + + + + + + + True + True + Settings.settings + + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + From 06710f9659b2cb58496484bf25f3822c91bc5dab Mon Sep 17 00:00:00 2001 From: jupster Date: Sun, 20 Jul 2025 15:16:03 +1000 Subject: [PATCH 16/45] Drop to .NET 8 and bump version to 1.9.7.2 Changed target framework from net9.0-windows to net8.0-windows in both FASTER and FASTERTests projects. Updated version to 1.9.7.2 in project and version files to reflect the framework change. --- FASTER/FASTER.csproj | 5 ++--- FASTERTests/FASTERTests.csproj | 2 +- FASTER_Version.xml | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/FASTER/FASTER.csproj b/FASTER/FASTER.csproj index 6c4d618..973bdb1 100644 --- a/FASTER/FASTER.csproj +++ b/FASTER/FASTER.csproj @@ -1,9 +1,7 @@ - net9.0-windows - true - 1.9.7.1 WinExe + net8.0-windows enable enable true @@ -12,6 +10,7 @@ True FASTERKey.snk Keelah Fox, Jupster, Canno.n + 1.9.7.2 FoxliCorp. Fox's Arma Server Tool Extended Rewrite Copyright © 2019 diff --git a/FASTERTests/FASTERTests.csproj b/FASTERTests/FASTERTests.csproj index d5436c0..e56945d 100644 --- a/FASTERTests/FASTERTests.csproj +++ b/FASTERTests/FASTERTests.csproj @@ -1,6 +1,6 @@  - net9.0-windows + net8.0-windows false diff --git a/FASTER_Version.xml b/FASTER_Version.xml index 7fd63a9..62703b8 100644 --- a/FASTER_Version.xml +++ b/FASTER_Version.xml @@ -1,6 +1,6 @@  - 1.9.7.1 + 1.9.7.2 https://github.com/Foxlider/FASTER/releases/latest/download/Release_x64.zip https://github.com/Foxlider/FASTER/releases true From d45b2c212ed8ca251b07dab51b0f07466b39b6de Mon Sep 17 00:00:00 2001 From: jupster Date: Sun, 20 Jul 2025 15:21:01 +1000 Subject: [PATCH 17/45] Enable Windows targeting in project file Added true to make Actions happy even though it isn't needed for net8 :shurg: --- FASTER/FASTER.csproj | 1 + 1 file changed, 1 insertion(+) diff --git a/FASTER/FASTER.csproj b/FASTER/FASTER.csproj index 973bdb1..8f1e513 100644 --- a/FASTER/FASTER.csproj +++ b/FASTER/FASTER.csproj @@ -2,6 +2,7 @@ WinExe net8.0-windows + true enable enable true From b84d9be0b138e99889b6a54017caebd75d426988 Mon Sep 17 00:00:00 2001 From: jupster Date: Sun, 20 Jul 2025 15:28:30 +1000 Subject: [PATCH 18/45] Enable Windows targeting in project files x2 Added true to both FASTER - Backup.csproj and FASTERTests.csproj to explicitly enable Windows-specific APIs and features during build and development :shrug: --- FASTER/FASTER - Backup.csproj | 1 + FASTERTests/FASTERTests.csproj | 1 + 2 files changed, 2 insertions(+) diff --git a/FASTER/FASTER - Backup.csproj b/FASTER/FASTER - Backup.csproj index 6dd452e..d82765a 100644 --- a/FASTER/FASTER - Backup.csproj +++ b/FASTER/FASTER - Backup.csproj @@ -2,6 +2,7 @@ WinExe net6.0-windows + true true true win-x64 diff --git a/FASTERTests/FASTERTests.csproj b/FASTERTests/FASTERTests.csproj index e56945d..42592d9 100644 --- a/FASTERTests/FASTERTests.csproj +++ b/FASTERTests/FASTERTests.csproj @@ -1,6 +1,7 @@  net8.0-windows + true false From decc343c29382c52a06c1f631a81dceb5324382c Mon Sep 17 00:00:00 2001 From: jupster Date: Sun, 20 Jul 2025 15:42:30 +1000 Subject: [PATCH 19/45] Fix BytexDigital.Steam project path in solution file Corrected the path to BytexDigital.Steam.csproj in FASTER.sln to remove a duplicate folder segment. --- FASTER.sln | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FASTER.sln b/FASTER.sln index c858ee9..122218c 100644 --- a/FASTER.sln +++ b/FASTER.sln @@ -23,7 +23,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FASTERTests", "FASTERTests\ EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FASTER Maintenance", "FASTER Maintenance\FASTER Maintenance.csproj", "{465FB100-A08C-4E4F-A321-EC85C5C177B3}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BytexDigital.Steam", "BytexDigital.Steam\BytexDigital.Steam\BytexDigital.Steam.csproj", "{22F5B346-B3B2-302D-9D68-35A2DFCE2081}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BytexDigital.Steam", "BytexDigital.Steam\BytexDigital.Steam.csproj", "{22F5B346-B3B2-302D-9D68-35A2DFCE2081}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution From 42ea5cae9705968028a6b3ec150b4e32cc3fcd86 Mon Sep 17 00:00:00 2001 From: jupster Date: Sun, 20 Jul 2025 15:51:05 +1000 Subject: [PATCH 20/45] Revert "Fix BytexDigital.Steam project path in solution file" This reverts commit decc343c29382c52a06c1f631a81dceb5324382c. --- FASTER.sln | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FASTER.sln b/FASTER.sln index 122218c..c858ee9 100644 --- a/FASTER.sln +++ b/FASTER.sln @@ -23,7 +23,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FASTERTests", "FASTERTests\ EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FASTER Maintenance", "FASTER Maintenance\FASTER Maintenance.csproj", "{465FB100-A08C-4E4F-A321-EC85C5C177B3}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BytexDigital.Steam", "BytexDigital.Steam\BytexDigital.Steam.csproj", "{22F5B346-B3B2-302D-9D68-35A2DFCE2081}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BytexDigital.Steam", "BytexDigital.Steam\BytexDigital.Steam\BytexDigital.Steam.csproj", "{22F5B346-B3B2-302D-9D68-35A2DFCE2081}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution From 94cf349f1362ead56cb6e7a1a8b76668a7971d51 Mon Sep 17 00:00:00 2001 From: jupster Date: Sun, 20 Jul 2025 16:21:36 +1000 Subject: [PATCH 21/45] Update checkout action to use recursive submodules Changed the checkout step in the CodeQL workflow to use 'submodules: recursive' and added a token for authentication. This ensures all nested submodules are checked out and authenticated properly. --- .github/workflows/codeql-analysis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 6e1b0a3..57e652d 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -33,7 +33,8 @@ jobs: - name: Checkout repository uses: actions/checkout@v4 with: - submodules: true + submodules: recursive + token: ${{ secrets.GITHUB_TOKEN }} - name: Initialize CodeQL uses: github/codeql-action/init@v3 From 96e492b0208af057947658ce36ab031915c568ae Mon Sep 17 00:00:00 2001 From: jupster Date: Sun, 20 Jul 2025 16:43:41 +1000 Subject: [PATCH 22/45] Add file listing step to CodeQL workflow Introduced a debugging step to list all files before checking out the repository in the CodeQL analysis workflow. This helps diagnose issues related to file structure or missing files during CI runs. (unlikely to keep in) --- .github/workflows/codeql-analysis.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 57e652d..a41cc62 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -30,6 +30,10 @@ jobs: language: [ 'csharp' ] steps: + - name: List files for debugging + run: | + ls -R + - name: Checkout repository uses: actions/checkout@v4 with: From 05f9585f7c7100e3db6c007570289e341c558d7a Mon Sep 17 00:00:00 2001 From: jupster Date: Sun, 20 Jul 2025 17:00:04 +1000 Subject: [PATCH 23/45] Update CodeQL workflow to improve submodule handling Removed the debugging file listing step and added an explicit step to initialize and update submodules using git. This ensures submodules are properly set up before running CodeQL analysis. --- .github/workflows/codeql-analysis.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index a41cc62..741e0a2 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -30,16 +30,15 @@ jobs: language: [ 'csharp' ] steps: - - name: List files for debugging - run: | - ls -R - - name: Checkout repository uses: actions/checkout@v4 with: submodules: recursive token: ${{ secrets.GITHUB_TOKEN }} + - name: Init & update submodules + run: git submodule update --init --recursive + - name: Initialize CodeQL uses: github/codeql-action/init@v3 with: From c3e8601f284270a3b274628b8f46affe7f88b66a Mon Sep 17 00:00:00 2001 From: jupster Date: Sun, 20 Jul 2025 18:44:32 +1000 Subject: [PATCH 24/45] Downgrade .NET SDK version to 8.0.0 in global.json The SDK version specified in global.json has been changed from 9.0.0 to 8.0.0, likely to ensure compatibility with projects or tooling that require .NET 8.0.0. --- global.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/global.json b/global.json index 20c2667..bbf2a79 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { "rollForward": "latestFeature", - "version": "9.0.0" + "version": "8.0.0" } } \ No newline at end of file From 984712431004a5331b4aff8aa7e8a000620705fd Mon Sep 17 00:00:00 2001 From: jupster Date: Fri, 25 Jul 2025 15:57:55 +1000 Subject: [PATCH 25/45] Revert "Merge pull request #186 from Foxlider/hotfix/logobjectsnotfound" This reverts commit 788a8a7ae285d2db7dc37d75b60e0cfc7e556f5f, reversing changes made to c3e8601f284270a3b274628b8f46affe7f88b66a. --- FASTER/Models/Arma3Profile.cs | 2 +- FASTER/Models/BasicCfg.cs | 16 ++-- FASTER/Models/ServerCfg.cs | 158 ++++++++++++++------------------- FASTER/Models/ServerProfile.cs | 34 ++----- FASTER/Views/Profile.xaml | 4 +- 5 files changed, 87 insertions(+), 127 deletions(-) diff --git a/FASTER/Models/Arma3Profile.cs b/FASTER/Models/Arma3Profile.cs index 2ffcce7..66c0c67 100644 --- a/FASTER/Models/Arma3Profile.cs +++ b/FASTER/Models/Arma3Profile.cs @@ -41,7 +41,7 @@ public class Arma3Profile : INotifyPropertyChanged private ushort mapContentMines = 1; private ushort autoReport = 0; private ushort multipleSaves = 0; - private int tacticalPing = 1; + private int tacticalPing = 1; private ushort aiLevelPreset = 3; private double skillAi = 0.5; diff --git a/FASTER/Models/BasicCfg.cs b/FASTER/Models/BasicCfg.cs index 4ed760a..fa3cf7f 100644 --- a/FASTER/Models/BasicCfg.cs +++ b/FASTER/Models/BasicCfg.cs @@ -14,8 +14,8 @@ public static class BasicCfgArrays [Serializable] public class BasicCfg : INotifyPropertyChanged { - private uint viewDistance = 2000; - private double terrainGrid = 25; + private uint viewDistance = 2000; + private double terrainGrid = 25; private ushort maxMsgSend = 128; private ushort maxSizeGuaranteed = 256; @@ -158,10 +158,10 @@ public string PerfPreset MaxMsgSend = 256; MaxSizeGuaranteed = 512; MaxSizeNonGuaranteed = 256; - MinErrorToSend = 0.001; - MinErrorToSendNear = 0.01; - MaxPacketSize = 1400; - MaxCustomFileSize = 160; + MinErrorToSend = 0.001; + MinErrorToSendNear = 0.01; + MaxPacketSize = 1400; + MaxCustomFileSize = 160; switch ((short)Array.IndexOf(BasicCfgArrays.PerfPresets, value)) @@ -177,8 +177,8 @@ public string PerfPreset MinBandwidth = 250000000; break; case 4: - MaxMsgSend = 512; - MinBandwidth = 1000000000; + MaxMsgSend = 512; + MinBandwidth = 1000000000; break; } RaisePropertyChanged("PerfPreset"); diff --git a/FASTER/Models/ServerCfg.cs b/FASTER/Models/ServerCfg.cs index 9405f66..d5f14f3 100644 --- a/FASTER/Models/ServerCfg.cs +++ b/FASTER/Models/ServerCfg.cs @@ -21,12 +21,12 @@ public class ServerCfg : INotifyPropertyChanged private string passwordAdmin; private string password; private string hostname; - private int maxPlayers = 32; - private List motd = new(); + private int maxPlayers = 32; + private List motd = new(); private int motdInterval; - private List admins = new(); - private List headlessClients = new(); - private List localClient = new(); + private List admins = new(); + private List headlessClients = new(); + private List localClient = new(); private bool headlessClientEnabled; private bool votingEnabled; private bool netlogEnabled; @@ -47,13 +47,18 @@ public class ServerCfg : INotifyPropertyChanged private bool autoSelectMission = true; private bool randomMissionOrder = true; private int briefingTimeOut = 60; // <- - private int roleTimeOut = 90; // <- These are BI base figues - private int votingTimeOut = 60; // <- + private int roleTimeOut = 90; // <- These are BI base figues + private int votingTimeOut = 60; // <- private int debriefingTimeOut = 45; // <- + private bool LogObjectNotFound = true; // logging enabled + private bool SkipDescriptionParsing = false; // parse description.ext + private bool ignoreMissionLoadErrors = false; // do not ingore errors private int armaUnitsTimeout = 30; // Defines how long the player will be stuck connecting and wait for armaUnits data. Player will be notified if timeout elapsed and no units data was received + private int queueSizeLogG = 1000000; // if a specific players message queue is larger than 1MB and '#monitor' is running, dump his messages to a logfile for analysis private string forcedDifficulty = "Custom"; // By default forcedDifficulty is only applying Custom - //Arma Server Only + + //Arma server only private short verifySignatures = 0; // 0 = Disabled (FASTER Default); 1 = Deprecated Activated ; 2 = Activated (Arma Default) private bool drawingInMap = true; private short disableVoN; // 0 = VoN activated ; 1 = VoN Disabled @@ -73,19 +78,17 @@ public class ServerCfg : INotifyPropertyChanged private string doubleIdDetected; private string onUserConnected; private string onUserDisconnected; - private string onHackedData = "kick (_this select 0)"; + private string onHackedData = "kick (_this select 0)"; private string onDifferentData; - private string onUnsignedData = "kick (_this select 0)"; + private string onUnsignedData = "kick (_this select 0)"; private string onUserKicked; - //Mision Settings private bool missionSelectorChecked; private string missionContentOverride; - private List _missions = new(); + private List _missions = new(); private bool autoInit; private string difficulty = "Custom"; - //Performance private bool maxMemOverride; private uint maxMem = 1024; private bool cpuCountOverride; @@ -94,6 +97,8 @@ public class ServerCfg : INotifyPropertyChanged private string serverCfgContent; + + #region Server Options public string PasswordAdmin { @@ -285,7 +290,7 @@ public string AllowedFilePatching set { allowedFilePatching = (short)Array.IndexOf(ServerCfgArrays.AllowFilePatchingStrings, value); - RaisePropertyChanged("AllowedFilePatching"); + RaisePropertyChanged("Password"); } } @@ -389,6 +394,36 @@ public int DebriefingTimeOut } } + public bool logObjectNotFound + { + get => LogObjectNotFound; + set + { + LogObjectNotFound = value; + RaisePropertyChanged("logObjectNotFound"); + } + } + + public bool skipDescriptionParsing + { + get => SkipDescriptionParsing; + set + { + SkipDescriptionParsing = value; + RaisePropertyChanged("skipDescriptionParsing"); + } + } + + public bool IgnoreMissionLoadErrors + { + get => ignoreMissionLoadErrors; + set + { + ignoreMissionLoadErrors = value; + RaisePropertyChanged("IgnoreMissionLoadErrors"); + } + } + public int ArmaUnitsTimeout { get => armaUnitsTimeout; @@ -399,6 +434,16 @@ public int ArmaUnitsTimeout } } + public int QueueSizeLogG + { + get => queueSizeLogG; + set + { + queueSizeLogG = value; + RaisePropertyChanged("QueueSizeLogG"); + } + } + public string ForcedDifficulty { get => forcedDifficulty; @@ -773,72 +818,6 @@ public ServerCfg() { ServerCfgContent = ProcessFile(); } } - [Serializable] - public class AdvancedOptions : INotifyPropertyChanged - { - private bool logObjectNotFound = true; // logging enabled - private bool skipDescriptionParsing = false; // Parse description.ext - private bool ignoreMissionLoadErrors = false; // Do not ignore errors - private int queueSizeLogG = 0; // If a specific players message queue is larger than and '#monitor' is running, dump his messages to a logfile for analysis - - public bool LogObjectNotFound - { - get => logObjectNotFound; - set - { - logObjectNotFound = value; - RaisePropertyChanged("LogObjectNotFound"); - } - } - - public bool SkipDescriptionParsing - { - get => skipDescriptionParsing; - set - { - skipDescriptionParsing = value; - RaisePropertyChanged("SkipDescriptionParsing"); - } - } - - public bool IgnoreMissionLoadErrors - { - get => ignoreMissionLoadErrors; - set - { - ignoreMissionLoadErrors = value; - RaisePropertyChanged("IgnoreMissionLoadErrors"); - } - } - - public int QueueSizeLogG - { - get => queueSizeLogG; - set - { - queueSizeLogG = value; - RaisePropertyChanged("QueueSizeLogG"); - } - } - - private string advancedOptionsContent; - - public string AdvancedOptionsContent - { - get => AdvancedOptionsContent; - set - { - AdvancedOptionsContent = value; - RaisePropertyChanged("AdvancedOptionsContent"); - } - } - - public AdvancedOptions() - { - if(string.IsNullOrWhiteSpace(AdvancedOptionsContent)) - { AdvancedOptionsContent = ProcessFile(); } - } - private void Item_PropertyChanged(object sender, PropertyChangedEventArgs e) { RaisePropertyChanged("MissionChecked"); @@ -909,14 +888,14 @@ public string ProcessFile() + $"disableVoN = {disableVoN};\t\t\t\t// If set to 1, Voice over Net will not be available\r\n" + $"vonCodec = {vonCodec};\t\t\t\t// If set to 1 then it uses IETF standard OPUS codec, if to 0 then it uses SPEEX codec (since Arma 3 update 1.58+) \r\n" + $"skipLobby = {(skipLobby ? "1" : "0")};\t\t\t\t// Overridden by mission parameters\r\n" - + $"vonCodecQuality = {vonCodecQuality};\t\t\t// Since 1.62.95417 supports range 1-20 //since 1.63.x will supports range 1-30 //8kHz is 0-10, 16kHz is 11-20, 32kHz(48kHz) is 21-30 \r\n" + + $"vonCodecQuality = {vonCodecQuality};\t\t\t// since 1.62.95417 supports range 1-20 //since 1.63.x will supports range 1-30 //8kHz is 0-10, 16kHz is 11-20, 32kHz(48kHz) is 21-30 \r\n" + $"persistent = {persistent};\t\t\t\t// If 1, missions still run on even after the last player disconnected.\r\n" + $"timeStampFormat = \"{timeStampFormat}\";\t\t// Set the timestamp format used on each report line in server-side RPT file. Possible values are \"none\" (default),\"short\",\"full\".\r\n" + $"BattlEye = {battlEye};\t\t\t\t// Server to use BattlEye system\r\n" - + $"queueSizeLogG = {QueueSizeLogG};\t\t\t// If a specific players message queue is larger than Value number and #monitor is running, dump his messages to a logfile for analysis \r\n" - + $"LogObjectNotFound = {LogObjectNotFound};\t\t// When false to skip logging 'Server: Object not found messages'.\r\n" - + $"SkipDescriptionParsing = {SkipDescriptionParsing};\t\t// When true to skip parsing of description.ext/mission.sqm. Will show pbo filename instead of configured missionName. OverviewText and such won't work, but loading the mission list is a lot faster when there are many missions \r\n" - + $"ignoreMissionLoadErrors = {IgnoreMissionLoadErrors};\t\t// When set to true, the mission will load no matter the amount of loading errors. If set to false, the server will abort mission's loading and return to mission selection.\r\n" + + $"queueSizeLogG = {queueSizeLogG};\t\t\t// If a specific players message queue is larger than 1MB and #monitor is running, dump his messages to a logfile for analysis \r\n" + + $"LogObjectNotFound = {logObjectNotFound};\t\t// When false to skip logging 'Server: Object not found messages'.\r\n" + + $"SkipDescriptionParsing = {skipDescriptionParsing};\t\t// When true to skip parsing of description.ext/mission.sqm. Will show pbo filename instead of configured missionName. OverviewText and such won't work, but loading the mission list is a lot faster when there are many missions \r\n" + + $"ignoreMissionLoadErrors = {ignoreMissionLoadErrors};\t\t// When set to true, the mission will load no matter the amount of loading errors. If set to false, the server will abort mission's loading and return to mission selection.\r\n" + $"forcedDifficulty = {forcedDifficulty};\t\t\t// Forced difficulty (Recruit, Regular, Veteran, Custom)\r\n" + "\r\n" + "// TIMEOUTS\r\n" @@ -938,9 +917,9 @@ public string ProcessFile() + $"doubleIdDetected = \"{doubleIdDetected}\";\t\t\t//\r\n" + "\r\n" + "// SIGNATURE VERIFICATION\r\n" - + $"onUnsignedData = \"{onUnsignedData}\";\t// Unsigned data detected\r\n" - + $"onHackedData = \"{onHackedData}\";\t// Tampering of the signature detected\r\n" - + $"onDifferentData = \"{onDifferentData}\";\t\t\t// Data with a valid signature, but different version than the one present on server detected\r\n" + + $"onUnsignedData = \"{onUnsignedData}\";\t// unsigned data detected\r\n" + + $"onHackedData = \"{onHackedData}\";\t// tampering of the signature detected\r\n" + + $"onDifferentData = \"{onDifferentData}\";\t\t\t// data with a valid signature, but different version than the one present on server detected\r\n" + "\r\n" + "\r\n" + "// MISSIONS CYCLE (see below)\r\n" @@ -1012,5 +991,4 @@ private void RaisePropertyChanged(string property) PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property)); } } - } -} \ No newline at end of file +} diff --git a/FASTER/Models/ServerProfile.cs b/FASTER/Models/ServerProfile.cs index 9f1241d..c9015a4 100644 --- a/FASTER/Models/ServerProfile.cs +++ b/FASTER/Models/ServerProfile.cs @@ -22,14 +22,13 @@ public ServerProfileCollection() internal static void AddServerProfile(string profileName) { - var currentProfiles = Properties.Settings.Default.Profiles; + var currentProfiles = Properties.Settings.Default.Profiles; var p = new ServerProfile(profileName); - p.ServerCfg.ServerCfgContent = p.ServerCfg.ProcessFile(); - p.ServerCfg.AdvancedOptionsContent = p.AdvancedOptions.ProcessFile(); - p.BasicCfg.BasicContent = p.BasicCfg.ProcessFile(); - p.ArmaProfile.ArmaProfileContent = p.ArmaProfile.ProcessFile(); + p.ServerCfg.ServerCfgContent = p.ServerCfg.ProcessFile(); + p.BasicCfg.BasicContent = p.BasicCfg.ProcessFile(); + p.ArmaProfile.ArmaProfileContent = p.ArmaProfile.ProcessFile(); currentProfiles.Add(p); - Properties.Settings.Default.Profiles = currentProfiles; + Properties.Settings.Default.Profiles = currentProfiles; Properties.Settings.Default.Save(); MainWindow.Instance.LoadServerProfiles(); } @@ -73,7 +72,6 @@ public class ServerProfile : INotifyPropertyChanged private bool _profileModsFilterIsRegex = false; private bool _profileModsFilterIsInvalid = false; private ServerCfg _serverCfg; - private ServerCfg _advancedOptions; private Arma3Profile _armaProfile; private BasicCfg _basicCfg; @@ -380,8 +378,8 @@ public bool ProfileModsFilterIsInvalid } } - public ServerCfg ServerCfg - { + public ServerCfg ServerCfg + { get => _serverCfg; set { @@ -392,19 +390,6 @@ public ServerCfg ServerCfg RaisePropertyChanged("ServerCfg"); } } - - public ServerCfg AdvancedOptions - { - get => _advancedOptions; - set - { - if(_advancedOptions != null) - _advancedOptions.PropertyChanged -= Class_PropertyChanged; - _advancedOptions = value; - _advancedOptions.PropertyChanged += Class_PropertyChanged; - RaisePropertyChanged("AdvancedOptions"); - } - } public Arma3Profile ArmaProfile { @@ -439,14 +424,12 @@ public ServerProfile(string name, bool createFolder = true) Name = name; Executable = Path.Combine(Properties.Settings.Default.serverPath, "arma3server_x64.exe"); ServerCfg = new ServerCfg(){ Hostname = name}; - AdvancedOptions = new AdvancedOptions(); ArmaProfile = new Arma3Profile(); BasicCfg = new BasicCfg(); ServerCfg.ServerCfgContent = ServerCfg.ProcessFile(); - ServerCfg.AdvancedOptionsContent = AdvancedOptions.ProcessFile(); ArmaProfile.ArmaProfileContent = ArmaProfile.ProcessFile(); BasicCfg.BasicContent = BasicCfg.ProcessFile(); - ServerCfg.AdvancedOptionsContent = AdvancedOptions.ProcessFile(); + if (createFolder) { Directory.CreateDirectory(Path.Combine(Properties.Settings.Default.serverPath, "Servers", Id)); } } @@ -459,7 +442,6 @@ public ServerProfile() ArmaProfile = new Arma3Profile(); BasicCfg = new BasicCfg(); ServerCfg.ServerCfgContent = ServerCfg.ProcessFile(); - ServerCfg.AdvancedOptionsContent = AdvancedOptions.ProcessFile(); ArmaProfile.ArmaProfileContent = ArmaProfile.ProcessFile(); BasicCfg.BasicContent = BasicCfg.ProcessFile(); } diff --git a/FASTER/Views/Profile.xaml b/FASTER/Views/Profile.xaml index 57eb536..0d82afc 100644 --- a/FASTER/Views/Profile.xaml +++ b/FASTER/Views/Profile.xaml @@ -649,8 +649,8 @@ - - + + From 57598226a697fd8930d74969fb4917f4e0265bd1 Mon Sep 17 00:00:00 2001 From: jupster Date: Fri, 25 Jul 2025 17:08:08 +1000 Subject: [PATCH 26/45] Reapply "Merge pull request #186 from Foxlider/hotfix/logobjectsnotfound" This reverts commit 984712431004a5331b4aff8aa7e8a000620705fd. --- FASTER/Models/Arma3Profile.cs | 2 +- FASTER/Models/BasicCfg.cs | 16 ++-- FASTER/Models/ServerCfg.cs | 158 +++++++++++++++++++-------------- FASTER/Models/ServerProfile.cs | 34 +++++-- FASTER/Views/Profile.xaml | 4 +- 5 files changed, 127 insertions(+), 87 deletions(-) diff --git a/FASTER/Models/Arma3Profile.cs b/FASTER/Models/Arma3Profile.cs index 66c0c67..2ffcce7 100644 --- a/FASTER/Models/Arma3Profile.cs +++ b/FASTER/Models/Arma3Profile.cs @@ -41,7 +41,7 @@ public class Arma3Profile : INotifyPropertyChanged private ushort mapContentMines = 1; private ushort autoReport = 0; private ushort multipleSaves = 0; - private int tacticalPing = 1; + private int tacticalPing = 1; private ushort aiLevelPreset = 3; private double skillAi = 0.5; diff --git a/FASTER/Models/BasicCfg.cs b/FASTER/Models/BasicCfg.cs index fa3cf7f..4ed760a 100644 --- a/FASTER/Models/BasicCfg.cs +++ b/FASTER/Models/BasicCfg.cs @@ -14,8 +14,8 @@ public static class BasicCfgArrays [Serializable] public class BasicCfg : INotifyPropertyChanged { - private uint viewDistance = 2000; - private double terrainGrid = 25; + private uint viewDistance = 2000; + private double terrainGrid = 25; private ushort maxMsgSend = 128; private ushort maxSizeGuaranteed = 256; @@ -158,10 +158,10 @@ public string PerfPreset MaxMsgSend = 256; MaxSizeGuaranteed = 512; MaxSizeNonGuaranteed = 256; - MinErrorToSend = 0.001; - MinErrorToSendNear = 0.01; - MaxPacketSize = 1400; - MaxCustomFileSize = 160; + MinErrorToSend = 0.001; + MinErrorToSendNear = 0.01; + MaxPacketSize = 1400; + MaxCustomFileSize = 160; switch ((short)Array.IndexOf(BasicCfgArrays.PerfPresets, value)) @@ -177,8 +177,8 @@ public string PerfPreset MinBandwidth = 250000000; break; case 4: - MaxMsgSend = 512; - MinBandwidth = 1000000000; + MaxMsgSend = 512; + MinBandwidth = 1000000000; break; } RaisePropertyChanged("PerfPreset"); diff --git a/FASTER/Models/ServerCfg.cs b/FASTER/Models/ServerCfg.cs index d5f14f3..9405f66 100644 --- a/FASTER/Models/ServerCfg.cs +++ b/FASTER/Models/ServerCfg.cs @@ -21,12 +21,12 @@ public class ServerCfg : INotifyPropertyChanged private string passwordAdmin; private string password; private string hostname; - private int maxPlayers = 32; - private List motd = new(); + private int maxPlayers = 32; + private List motd = new(); private int motdInterval; - private List admins = new(); - private List headlessClients = new(); - private List localClient = new(); + private List admins = new(); + private List headlessClients = new(); + private List localClient = new(); private bool headlessClientEnabled; private bool votingEnabled; private bool netlogEnabled; @@ -47,18 +47,13 @@ public class ServerCfg : INotifyPropertyChanged private bool autoSelectMission = true; private bool randomMissionOrder = true; private int briefingTimeOut = 60; // <- - private int roleTimeOut = 90; // <- These are BI base figues - private int votingTimeOut = 60; // <- + private int roleTimeOut = 90; // <- These are BI base figues + private int votingTimeOut = 60; // <- private int debriefingTimeOut = 45; // <- - private bool LogObjectNotFound = true; // logging enabled - private bool SkipDescriptionParsing = false; // parse description.ext - private bool ignoreMissionLoadErrors = false; // do not ingore errors private int armaUnitsTimeout = 30; // Defines how long the player will be stuck connecting and wait for armaUnits data. Player will be notified if timeout elapsed and no units data was received - private int queueSizeLogG = 1000000; // if a specific players message queue is larger than 1MB and '#monitor' is running, dump his messages to a logfile for analysis private string forcedDifficulty = "Custom"; // By default forcedDifficulty is only applying Custom - - //Arma server only + //Arma Server Only private short verifySignatures = 0; // 0 = Disabled (FASTER Default); 1 = Deprecated Activated ; 2 = Activated (Arma Default) private bool drawingInMap = true; private short disableVoN; // 0 = VoN activated ; 1 = VoN Disabled @@ -78,17 +73,19 @@ public class ServerCfg : INotifyPropertyChanged private string doubleIdDetected; private string onUserConnected; private string onUserDisconnected; - private string onHackedData = "kick (_this select 0)"; + private string onHackedData = "kick (_this select 0)"; private string onDifferentData; - private string onUnsignedData = "kick (_this select 0)"; + private string onUnsignedData = "kick (_this select 0)"; private string onUserKicked; + //Mision Settings private bool missionSelectorChecked; private string missionContentOverride; - private List _missions = new(); + private List _missions = new(); private bool autoInit; private string difficulty = "Custom"; + //Performance private bool maxMemOverride; private uint maxMem = 1024; private bool cpuCountOverride; @@ -97,8 +94,6 @@ public class ServerCfg : INotifyPropertyChanged private string serverCfgContent; - - #region Server Options public string PasswordAdmin { @@ -290,7 +285,7 @@ public string AllowedFilePatching set { allowedFilePatching = (short)Array.IndexOf(ServerCfgArrays.AllowFilePatchingStrings, value); - RaisePropertyChanged("Password"); + RaisePropertyChanged("AllowedFilePatching"); } } @@ -394,36 +389,6 @@ public int DebriefingTimeOut } } - public bool logObjectNotFound - { - get => LogObjectNotFound; - set - { - LogObjectNotFound = value; - RaisePropertyChanged("logObjectNotFound"); - } - } - - public bool skipDescriptionParsing - { - get => SkipDescriptionParsing; - set - { - SkipDescriptionParsing = value; - RaisePropertyChanged("skipDescriptionParsing"); - } - } - - public bool IgnoreMissionLoadErrors - { - get => ignoreMissionLoadErrors; - set - { - ignoreMissionLoadErrors = value; - RaisePropertyChanged("IgnoreMissionLoadErrors"); - } - } - public int ArmaUnitsTimeout { get => armaUnitsTimeout; @@ -434,16 +399,6 @@ public int ArmaUnitsTimeout } } - public int QueueSizeLogG - { - get => queueSizeLogG; - set - { - queueSizeLogG = value; - RaisePropertyChanged("QueueSizeLogG"); - } - } - public string ForcedDifficulty { get => forcedDifficulty; @@ -818,6 +773,72 @@ public ServerCfg() { ServerCfgContent = ProcessFile(); } } + [Serializable] + public class AdvancedOptions : INotifyPropertyChanged + { + private bool logObjectNotFound = true; // logging enabled + private bool skipDescriptionParsing = false; // Parse description.ext + private bool ignoreMissionLoadErrors = false; // Do not ignore errors + private int queueSizeLogG = 0; // If a specific players message queue is larger than and '#monitor' is running, dump his messages to a logfile for analysis + + public bool LogObjectNotFound + { + get => logObjectNotFound; + set + { + logObjectNotFound = value; + RaisePropertyChanged("LogObjectNotFound"); + } + } + + public bool SkipDescriptionParsing + { + get => skipDescriptionParsing; + set + { + skipDescriptionParsing = value; + RaisePropertyChanged("SkipDescriptionParsing"); + } + } + + public bool IgnoreMissionLoadErrors + { + get => ignoreMissionLoadErrors; + set + { + ignoreMissionLoadErrors = value; + RaisePropertyChanged("IgnoreMissionLoadErrors"); + } + } + + public int QueueSizeLogG + { + get => queueSizeLogG; + set + { + queueSizeLogG = value; + RaisePropertyChanged("QueueSizeLogG"); + } + } + + private string advancedOptionsContent; + + public string AdvancedOptionsContent + { + get => AdvancedOptionsContent; + set + { + AdvancedOptionsContent = value; + RaisePropertyChanged("AdvancedOptionsContent"); + } + } + + public AdvancedOptions() + { + if(string.IsNullOrWhiteSpace(AdvancedOptionsContent)) + { AdvancedOptionsContent = ProcessFile(); } + } + private void Item_PropertyChanged(object sender, PropertyChangedEventArgs e) { RaisePropertyChanged("MissionChecked"); @@ -888,14 +909,14 @@ public string ProcessFile() + $"disableVoN = {disableVoN};\t\t\t\t// If set to 1, Voice over Net will not be available\r\n" + $"vonCodec = {vonCodec};\t\t\t\t// If set to 1 then it uses IETF standard OPUS codec, if to 0 then it uses SPEEX codec (since Arma 3 update 1.58+) \r\n" + $"skipLobby = {(skipLobby ? "1" : "0")};\t\t\t\t// Overridden by mission parameters\r\n" - + $"vonCodecQuality = {vonCodecQuality};\t\t\t// since 1.62.95417 supports range 1-20 //since 1.63.x will supports range 1-30 //8kHz is 0-10, 16kHz is 11-20, 32kHz(48kHz) is 21-30 \r\n" + + $"vonCodecQuality = {vonCodecQuality};\t\t\t// Since 1.62.95417 supports range 1-20 //since 1.63.x will supports range 1-30 //8kHz is 0-10, 16kHz is 11-20, 32kHz(48kHz) is 21-30 \r\n" + $"persistent = {persistent};\t\t\t\t// If 1, missions still run on even after the last player disconnected.\r\n" + $"timeStampFormat = \"{timeStampFormat}\";\t\t// Set the timestamp format used on each report line in server-side RPT file. Possible values are \"none\" (default),\"short\",\"full\".\r\n" + $"BattlEye = {battlEye};\t\t\t\t// Server to use BattlEye system\r\n" - + $"queueSizeLogG = {queueSizeLogG};\t\t\t// If a specific players message queue is larger than 1MB and #monitor is running, dump his messages to a logfile for analysis \r\n" - + $"LogObjectNotFound = {logObjectNotFound};\t\t// When false to skip logging 'Server: Object not found messages'.\r\n" - + $"SkipDescriptionParsing = {skipDescriptionParsing};\t\t// When true to skip parsing of description.ext/mission.sqm. Will show pbo filename instead of configured missionName. OverviewText and such won't work, but loading the mission list is a lot faster when there are many missions \r\n" - + $"ignoreMissionLoadErrors = {ignoreMissionLoadErrors};\t\t// When set to true, the mission will load no matter the amount of loading errors. If set to false, the server will abort mission's loading and return to mission selection.\r\n" + + $"queueSizeLogG = {QueueSizeLogG};\t\t\t// If a specific players message queue is larger than Value number and #monitor is running, dump his messages to a logfile for analysis \r\n" + + $"LogObjectNotFound = {LogObjectNotFound};\t\t// When false to skip logging 'Server: Object not found messages'.\r\n" + + $"SkipDescriptionParsing = {SkipDescriptionParsing};\t\t// When true to skip parsing of description.ext/mission.sqm. Will show pbo filename instead of configured missionName. OverviewText and such won't work, but loading the mission list is a lot faster when there are many missions \r\n" + + $"ignoreMissionLoadErrors = {IgnoreMissionLoadErrors};\t\t// When set to true, the mission will load no matter the amount of loading errors. If set to false, the server will abort mission's loading and return to mission selection.\r\n" + $"forcedDifficulty = {forcedDifficulty};\t\t\t// Forced difficulty (Recruit, Regular, Veteran, Custom)\r\n" + "\r\n" + "// TIMEOUTS\r\n" @@ -917,9 +938,9 @@ public string ProcessFile() + $"doubleIdDetected = \"{doubleIdDetected}\";\t\t\t//\r\n" + "\r\n" + "// SIGNATURE VERIFICATION\r\n" - + $"onUnsignedData = \"{onUnsignedData}\";\t// unsigned data detected\r\n" - + $"onHackedData = \"{onHackedData}\";\t// tampering of the signature detected\r\n" - + $"onDifferentData = \"{onDifferentData}\";\t\t\t// data with a valid signature, but different version than the one present on server detected\r\n" + + $"onUnsignedData = \"{onUnsignedData}\";\t// Unsigned data detected\r\n" + + $"onHackedData = \"{onHackedData}\";\t// Tampering of the signature detected\r\n" + + $"onDifferentData = \"{onDifferentData}\";\t\t\t// Data with a valid signature, but different version than the one present on server detected\r\n" + "\r\n" + "\r\n" + "// MISSIONS CYCLE (see below)\r\n" @@ -991,4 +1012,5 @@ private void RaisePropertyChanged(string property) PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property)); } } -} + } +} \ No newline at end of file diff --git a/FASTER/Models/ServerProfile.cs b/FASTER/Models/ServerProfile.cs index c9015a4..9f1241d 100644 --- a/FASTER/Models/ServerProfile.cs +++ b/FASTER/Models/ServerProfile.cs @@ -22,13 +22,14 @@ public ServerProfileCollection() internal static void AddServerProfile(string profileName) { - var currentProfiles = Properties.Settings.Default.Profiles; + var currentProfiles = Properties.Settings.Default.Profiles; var p = new ServerProfile(profileName); - p.ServerCfg.ServerCfgContent = p.ServerCfg.ProcessFile(); - p.BasicCfg.BasicContent = p.BasicCfg.ProcessFile(); - p.ArmaProfile.ArmaProfileContent = p.ArmaProfile.ProcessFile(); + p.ServerCfg.ServerCfgContent = p.ServerCfg.ProcessFile(); + p.ServerCfg.AdvancedOptionsContent = p.AdvancedOptions.ProcessFile(); + p.BasicCfg.BasicContent = p.BasicCfg.ProcessFile(); + p.ArmaProfile.ArmaProfileContent = p.ArmaProfile.ProcessFile(); currentProfiles.Add(p); - Properties.Settings.Default.Profiles = currentProfiles; + Properties.Settings.Default.Profiles = currentProfiles; Properties.Settings.Default.Save(); MainWindow.Instance.LoadServerProfiles(); } @@ -72,6 +73,7 @@ public class ServerProfile : INotifyPropertyChanged private bool _profileModsFilterIsRegex = false; private bool _profileModsFilterIsInvalid = false; private ServerCfg _serverCfg; + private ServerCfg _advancedOptions; private Arma3Profile _armaProfile; private BasicCfg _basicCfg; @@ -378,8 +380,8 @@ public bool ProfileModsFilterIsInvalid } } - public ServerCfg ServerCfg - { + public ServerCfg ServerCfg + { get => _serverCfg; set { @@ -390,6 +392,19 @@ public ServerCfg ServerCfg RaisePropertyChanged("ServerCfg"); } } + + public ServerCfg AdvancedOptions + { + get => _advancedOptions; + set + { + if(_advancedOptions != null) + _advancedOptions.PropertyChanged -= Class_PropertyChanged; + _advancedOptions = value; + _advancedOptions.PropertyChanged += Class_PropertyChanged; + RaisePropertyChanged("AdvancedOptions"); + } + } public Arma3Profile ArmaProfile { @@ -424,12 +439,14 @@ public ServerProfile(string name, bool createFolder = true) Name = name; Executable = Path.Combine(Properties.Settings.Default.serverPath, "arma3server_x64.exe"); ServerCfg = new ServerCfg(){ Hostname = name}; + AdvancedOptions = new AdvancedOptions(); ArmaProfile = new Arma3Profile(); BasicCfg = new BasicCfg(); ServerCfg.ServerCfgContent = ServerCfg.ProcessFile(); + ServerCfg.AdvancedOptionsContent = AdvancedOptions.ProcessFile(); ArmaProfile.ArmaProfileContent = ArmaProfile.ProcessFile(); BasicCfg.BasicContent = BasicCfg.ProcessFile(); - + ServerCfg.AdvancedOptionsContent = AdvancedOptions.ProcessFile(); if (createFolder) { Directory.CreateDirectory(Path.Combine(Properties.Settings.Default.serverPath, "Servers", Id)); } } @@ -442,6 +459,7 @@ public ServerProfile() ArmaProfile = new Arma3Profile(); BasicCfg = new BasicCfg(); ServerCfg.ServerCfgContent = ServerCfg.ProcessFile(); + ServerCfg.AdvancedOptionsContent = AdvancedOptions.ProcessFile(); ArmaProfile.ArmaProfileContent = ArmaProfile.ProcessFile(); BasicCfg.BasicContent = BasicCfg.ProcessFile(); } diff --git a/FASTER/Views/Profile.xaml b/FASTER/Views/Profile.xaml index 0d82afc..57eb536 100644 --- a/FASTER/Views/Profile.xaml +++ b/FASTER/Views/Profile.xaml @@ -649,8 +649,8 @@ - - + + From 3174513e8bce08a0e1d60ac67abbb8636b741910 Mon Sep 17 00:00:00 2001 From: jupster Date: Fri, 25 Jul 2025 17:58:21 +1000 Subject: [PATCH 27/45] Fix property backing field casing in ServerCfg Corrects the casing of the backing field for AdvancedOptionsContent to follow C# conventions and resolves property getter/setter logic. --- FASTER/Models/ServerCfg.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/FASTER/Models/ServerCfg.cs b/FASTER/Models/ServerCfg.cs index 9405f66..c4c99ee 100644 --- a/FASTER/Models/ServerCfg.cs +++ b/FASTER/Models/ServerCfg.cs @@ -821,11 +821,11 @@ public int QueueSizeLogG } } - private string advancedOptionsContent; + private string AdvancedOptionsContent; public string AdvancedOptionsContent { - get => AdvancedOptionsContent; + get => advancedOptionsContent; set { AdvancedOptionsContent = value; From 5edf07f91f2b2b617acb6916d302d013bef1f96c Mon Sep 17 00:00:00 2001 From: jupster Date: Fri, 25 Jul 2025 18:06:21 +1000 Subject: [PATCH 28/45] Fix property setter recursion in ServerCfg Corrected the setter for AdvancedOptionsContent to assign the value to the backing field instead of recursively calling the property, preventing a stack overflow. --- FASTER/Models/ServerCfg.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/FASTER/Models/ServerCfg.cs b/FASTER/Models/ServerCfg.cs index c4c99ee..95b6968 100644 --- a/FASTER/Models/ServerCfg.cs +++ b/FASTER/Models/ServerCfg.cs @@ -821,14 +821,14 @@ public int QueueSizeLogG } } - private string AdvancedOptionsContent; + private string advancedOptionsContent; public string AdvancedOptionsContent { get => advancedOptionsContent; set { - AdvancedOptionsContent = value; + advancedOptionsContent = value; RaisePropertyChanged("AdvancedOptionsContent"); } } From bbbd24b740c623384fc5b7df81cdb3804d44d293 Mon Sep 17 00:00:00 2001 From: jupster Date: Fri, 25 Jul 2025 18:14:45 +1000 Subject: [PATCH 29/45] Remove duplicate assignment in ServerProfile Eliminated a redundant assignment to ServerCfg.AdvancedOptionsContent in the ProcessProfile method of ServerProfile.cs. --- FASTER/Models/ServerProfile.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/FASTER/Models/ServerProfile.cs b/FASTER/Models/ServerProfile.cs index 9f1241d..85b15ba 100644 --- a/FASTER/Models/ServerProfile.cs +++ b/FASTER/Models/ServerProfile.cs @@ -446,7 +446,6 @@ public ServerProfile(string name, bool createFolder = true) ServerCfg.AdvancedOptionsContent = AdvancedOptions.ProcessFile(); ArmaProfile.ArmaProfileContent = ArmaProfile.ProcessFile(); BasicCfg.BasicContent = BasicCfg.ProcessFile(); - ServerCfg.AdvancedOptionsContent = AdvancedOptions.ProcessFile(); if (createFolder) { Directory.CreateDirectory(Path.Combine(Properties.Settings.Default.serverPath, "Servers", Id)); } } From 4b34bd3b9dc74823aef43bb4dbe0a4532f975a7d Mon Sep 17 00:00:00 2001 From: jupster Date: Fri, 25 Jul 2025 21:26:23 +1000 Subject: [PATCH 30/45] Bump version to 1.9.7.3 Updated project and version XML files to reflect new release version 1.9.7.3. --- FASTER/FASTER.csproj | 2 +- FASTER_Version.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/FASTER/FASTER.csproj b/FASTER/FASTER.csproj index 8f1e513..4ef605b 100644 --- a/FASTER/FASTER.csproj +++ b/FASTER/FASTER.csproj @@ -11,7 +11,7 @@ True FASTERKey.snk Keelah Fox, Jupster, Canno.n - 1.9.7.2 + 1.9.7.3 FoxliCorp. Fox's Arma Server Tool Extended Rewrite Copyright © 2019 diff --git a/FASTER_Version.xml b/FASTER_Version.xml index 62703b8..e999469 100644 --- a/FASTER_Version.xml +++ b/FASTER_Version.xml @@ -1,6 +1,6 @@  - 1.9.7.2 + 1.9.7.3 https://github.com/Foxlider/FASTER/releases/latest/download/Release_x64.zip https://github.com/Foxlider/FASTER/releases true From 8982499fb0027c807d74d9f8f819ad366a97cdc7 Mon Sep 17 00:00:00 2001 From: jupster Date: Fri, 25 Jul 2025 21:27:07 +1000 Subject: [PATCH 31/45] Add path for advanced server config in SaveProfile Introduced a new variable 'advanced' to store the path for the advanced server configuration file in the SaveProfile method of ProfileViewModel. --- FASTER/ViewModel/ProfileViewModel.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/FASTER/ViewModel/ProfileViewModel.cs b/FASTER/ViewModel/ProfileViewModel.cs index b9b6f71..ee04841 100644 --- a/FASTER/ViewModel/ProfileViewModel.cs +++ b/FASTER/ViewModel/ProfileViewModel.cs @@ -210,6 +210,7 @@ internal void DeleteProfile() internal void SaveProfile() { string config = Path.Combine(Profile.ArmaPath, "Servers", Profile.Id, "server_config.cfg"); + string advanced = Path.Combine(Profile.ArmaPath, "servers", Profile.Id, "Server_advanced string basic = Path.Combine(Profile.ArmaPath, "Servers", Profile.Id, "server_basic.cfg"); string serverProfile = Path.Combine(Profile.ArmaPath, "Servers", Profile.Id, "users", Profile.Id, $"{Profile.Id}.Arma3Profile"); From 8c90880986ee727460daeac42f15360dab18f1b6 Mon Sep 17 00:00:00 2001 From: jupster Date: Fri, 25 Jul 2025 21:27:32 +1000 Subject: [PATCH 32/45] Refactor AdvancedOptions to use correct type Changed AdvancedOptions from ServerCfg to AdvancedOptions type in ServerProfile. Updated related property assignments and command line generation to use the new advanced options file. This improves type safety and ensures advanced options are handled separately from server configuration. --- FASTER/Models/ServerProfile.cs | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/FASTER/Models/ServerProfile.cs b/FASTER/Models/ServerProfile.cs index 85b15ba..221942d 100644 --- a/FASTER/Models/ServerProfile.cs +++ b/FASTER/Models/ServerProfile.cs @@ -25,7 +25,7 @@ internal static void AddServerProfile(string profileName) var currentProfiles = Properties.Settings.Default.Profiles; var p = new ServerProfile(profileName); p.ServerCfg.ServerCfgContent = p.ServerCfg.ProcessFile(); - p.ServerCfg.AdvancedOptionsContent = p.AdvancedOptions.ProcessFile(); + p.AdvancedOptions.AdvancedOptionsContent = p.AdvancedOptions.ProcessFile(); p.BasicCfg.BasicContent = p.BasicCfg.ProcessFile(); p.ArmaProfile.ArmaProfileContent = p.ArmaProfile.ProcessFile(); currentProfiles.Add(p); @@ -73,7 +73,7 @@ public class ServerProfile : INotifyPropertyChanged private bool _profileModsFilterIsRegex = false; private bool _profileModsFilterIsInvalid = false; private ServerCfg _serverCfg; - private ServerCfg _advancedOptions; + private AdvancedOptions _advancedOptions; private Arma3Profile _armaProfile; private BasicCfg _basicCfg; @@ -393,7 +393,7 @@ public ServerCfg ServerCfg } } - public ServerCfg AdvancedOptions + public AdvancedOptions AdvancedOptions { get => _advancedOptions; set @@ -443,7 +443,7 @@ public ServerProfile(string name, bool createFolder = true) ArmaProfile = new Arma3Profile(); BasicCfg = new BasicCfg(); ServerCfg.ServerCfgContent = ServerCfg.ProcessFile(); - ServerCfg.AdvancedOptionsContent = AdvancedOptions.ProcessFile(); + AdvancedOptions.AdvancedOptionsContent = AdvancedOptions.ProcessFile(); ArmaProfile.ArmaProfileContent = ArmaProfile.ProcessFile(); BasicCfg.BasicContent = BasicCfg.ProcessFile(); if (createFolder) @@ -454,11 +454,12 @@ public ServerProfile() { _id = $"_{Guid.NewGuid():N}"; Name = _id; - ServerCfg = new ServerCfg(){ Hostname = Name}; - ArmaProfile = new Arma3Profile(); - BasicCfg = new BasicCfg(); + ServerCfg = new ServerCfg(){ Hostname = Name}; + ArmaProfile = new Arma3Profile(); + BasicCfg = new BasicCfg(); + AdvancedOptions = new AdvancedOptions(); ServerCfg.ServerCfgContent = ServerCfg.ProcessFile(); - ServerCfg.AdvancedOptionsContent = AdvancedOptions.ProcessFile(); + AdvancedOptions.AdvancedOptionsContent = AdvancedOptions.ProcessFile(); ArmaProfile.ArmaProfileContent = ArmaProfile.ProcessFile(); BasicCfg.BasicContent = BasicCfg.ProcessFile(); } @@ -543,8 +544,9 @@ private string GetCommandLine() { - string config = Path.Combine(ArmaPath, "Servers", Id, "server_config.cfg"); - string basic = Path.Combine(ArmaPath, "Servers", Id, "server_basic.cfg"); + string config = Path.Combine(ArmaPath, "Servers", Id, "server_config.cfg"); + string advanced = Path.Combine(ArmaPath, "Servers", Id, "server_advanced.cfg"); + string basic = Path.Combine(ArmaPath, "Servers", Id, "server_basic.cfg"); string playerMods = string.Join(";", ProfileMods.Where(m => m.ClientSideChecked).OrderBy(m => m.LoadPriority).Select(m => $"@{Functions.SafeName(m.Name)}")); string serverMods = string.Join(";", ProfileMods.Where(m => m.ServerSideChecked).OrderBy(m => m.LoadPriority).Select(m => $"@{Functions.SafeName(m.Name)}")); @@ -552,6 +554,7 @@ private string GetCommandLine() { $"-port={Port}", $" \"-config={config}\"", + $" \"-advanced={advanced}\"", $" \"-cfg={basic}\"", $" \"-profiles={Path.Combine(ArmaPath, "Servers", Id)}\"", $" -name={Id}", @@ -695,4 +698,4 @@ public override string ToString() private void RaisePropertyChanged(string property) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property)); } } -} +} \ No newline at end of file From 243e26f631f6300c0c4383bff1cc867e0e7166ad Mon Sep 17 00:00:00 2001 From: jupster Date: Fri, 25 Jul 2025 21:27:55 +1000 Subject: [PATCH 33/45] Refactor AdvancedOptions to separate class Moved the AdvancedOptions class from ServerCfg.cs to its own file AdvancedOptions.cs for better separation of concerns and maintainability. Updated ServerCfg to use the new AdvancedOptions property and adjusted related logic to reference the new class. --- FASTER/Models/AdvancedOptions.cs | 100 +++++++++++++++++++++++++++++++ FASTER/Models/ServerCfg.cs | 82 ++++--------------------- 2 files changed, 110 insertions(+), 72 deletions(-) create mode 100644 FASTER/Models/AdvancedOptions.cs diff --git a/FASTER/Models/AdvancedOptions.cs b/FASTER/Models/AdvancedOptions.cs new file mode 100644 index 0000000..b55a5a3 --- /dev/null +++ b/FASTER/Models/AdvancedOptions.cs @@ -0,0 +1,100 @@ +using System; +using System.ComponentModel; + +namespace FASTER.Models +{ + [Serializable] + public class AdvancedOptions : INotifyPropertyChanged + { + private bool logObjectNotFound = true; // logging enabled + private bool skipDescriptionParsing = false; // Parse description.ext + private bool ignoreMissionLoadErrors = false; // Do not ignore errors + private int queueSizeLogG = 0; // If a specific players message queue is larger than and '#monitor' is running, dump his messages to a logfile for analysis + private string advancedOptionsContent; + + public bool LogObjectNotFound + { + get => logObjectNotFound; + set + { + logObjectNotFound = value; + RaisePropertyChanged(nameof("LogObjectNotFound")); + } + } + + public bool SkipDescriptionParsing + { + get => skipDescriptionParsing; + set + { + skipDescriptionParsing = value; + RaisePropertyChanged(nameof("SkipDescriptionParsing")); + } + } + + public bool IgnoreMissionLoadErrors + { + get => ignoreMissionLoadErrors; + set + { + ignoreMissionLoadErrors = value; + RaisePropertyChanged(nameof("IgnoreMissionLoadErrors")); + } + } + + public int QueueSizeLogG + { + get => queueSizeLogG; + set + { + queueSizeLogG = value; + RaisePropertyChanged(nameof("QueueSizeLogG")); + } + } + + public string AdvancedOptionsContent + { + get => advancedOptionsContent; + set + { + advancedOptionsContent = value; + RaisePropertyChanged(nameof("AdvancedOptionsContent")); + } + } + + public AdvancedOptions() + { + if(string.IsNullOrWhiteSpace(AdvancedOptionsContent)) + { + AdvancedOptionsContent = ProcessFile(); + } + } + + public string ProcessFile() + { + string output = "//\r\n" + + "// AdvancedOptions\r\n" + + "//\r\n" + + "// comments are written with \"//\" in front of them.\r\n" + + "\r\n" + + "\r\n" + + $"queueSizeLogG = {QueueSizeLogG};\t\t\t// If a specific players message queue is larger than Value number and #monitor is running, dump his messages to a logfile for analysis\r\n" + + $"LogObjectNotFound = {LogObjectNotFound};\t\t// When false to skip logging 'Server: Object not found messages'.\r\n" + + $"SkipDescriptionParsing = {SkipDescriptionParsing};\t\t// When true to skip parsing of description.ext/mission.sqm. Will show pbo filename instead of configured missionName. OverviewText and such won't work, but loading the mission list is a lot faster when there are many missions\r\n" + + $"ignoreMissionLoadErrors = {IgnoreMissionLoadErrors};\t\t// When set to true, the mission will load no matter the amount of loading errors. If set to false, the server will abort mission's loading and return to mission selection.\r\n" + + "\r\n" + + "\r\n"; + return output; + } + public event PropertyChangedEventHandler? PropertyChanged; + + private void RaisePropertyChanged(string property) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property)); + if (property != nameof(AdvancedOptionsContent)) + { + AdvancedOptionsContent = ProcessFile(); + } + } + } +} \ No newline at end of file diff --git a/FASTER/Models/ServerCfg.cs b/FASTER/Models/ServerCfg.cs index 95b6968..89d43fa 100644 --- a/FASTER/Models/ServerCfg.cs +++ b/FASTER/Models/ServerCfg.cs @@ -773,78 +773,18 @@ public ServerCfg() { ServerCfgContent = ProcessFile(); } } - [Serializable] - public class AdvancedOptions : INotifyPropertyChanged - { - private bool logObjectNotFound = true; // logging enabled - private bool skipDescriptionParsing = false; // Parse description.ext - private bool ignoreMissionLoadErrors = false; // Do not ignore errors - private int queueSizeLogG = 0; // If a specific players message queue is larger than and '#monitor' is running, dump his messages to a logfile for analysis - - public bool LogObjectNotFound - { - get => logObjectNotFound; - set - { - logObjectNotFound = value; - RaisePropertyChanged("LogObjectNotFound"); - } - } - - public bool SkipDescriptionParsing - { - get => skipDescriptionParsing; - set - { - skipDescriptionParsing = value; - RaisePropertyChanged("SkipDescriptionParsing"); - } - } - - public bool IgnoreMissionLoadErrors - { - get => ignoreMissionLoadErrors; - set - { - ignoreMissionLoadErrors = value; - RaisePropertyChanged("IgnoreMissionLoadErrors"); - } - } - - public int QueueSizeLogG - { - get => queueSizeLogG; - set - { - queueSizeLogG = value; - RaisePropertyChanged("QueueSizeLogG"); - } - } - - private string advancedOptionsContent; - - public string AdvancedOptionsContent - { - get => advancedOptionsContent; - set - { - advancedOptionsContent = value; - RaisePropertyChanged("AdvancedOptionsContent"); - } - } - - public AdvancedOptions() - { - if(string.IsNullOrWhiteSpace(AdvancedOptionsContent)) - { AdvancedOptionsContent = ProcessFile(); } - } - private void Item_PropertyChanged(object sender, PropertyChangedEventArgs e) { RaisePropertyChanged("MissionChecked"); RaisePropertyChanged("MissionContentOverride"); } + // Grab Advanced output + public AdvancedOptions AdvancedOptions { get; set; } = new(); + + // Optional convenience property to expose the raw content + public string AdvancedOptionsContent => AdvancedOptions.AdvancedOptionsContent; + public string ProcessFile() { if (!missionSelectorChecked) @@ -867,6 +807,8 @@ public string ProcessFile() { MissionContentOverride = compiledMission; } } + public string GenerateCfgFile() + { string output = "//\r\n" + "// server.cfg\r\n" + "//\r\n" @@ -913,10 +855,6 @@ public string ProcessFile() + $"persistent = {persistent};\t\t\t\t// If 1, missions still run on even after the last player disconnected.\r\n" + $"timeStampFormat = \"{timeStampFormat}\";\t\t// Set the timestamp format used on each report line in server-side RPT file. Possible values are \"none\" (default),\"short\",\"full\".\r\n" + $"BattlEye = {battlEye};\t\t\t\t// Server to use BattlEye system\r\n" - + $"queueSizeLogG = {QueueSizeLogG};\t\t\t// If a specific players message queue is larger than Value number and #monitor is running, dump his messages to a logfile for analysis \r\n" - + $"LogObjectNotFound = {LogObjectNotFound};\t\t// When false to skip logging 'Server: Object not found messages'.\r\n" - + $"SkipDescriptionParsing = {SkipDescriptionParsing};\t\t// When true to skip parsing of description.ext/mission.sqm. Will show pbo filename instead of configured missionName. OverviewText and such won't work, but loading the mission list is a lot faster when there are many missions \r\n" - + $"ignoreMissionLoadErrors = {IgnoreMissionLoadErrors};\t\t// When set to true, the mission will load no matter the amount of loading errors. If set to false, the server will abort mission's loading and return to mission selection.\r\n" + $"forcedDifficulty = {forcedDifficulty};\t\t\t// Forced difficulty (Recruit, Regular, Veteran, Custom)\r\n" + "\r\n" + "// TIMEOUTS\r\n" @@ -955,9 +893,10 @@ public string ProcessFile() + "// HEADLESS CLIENT\r\n" + $"{(headlessClientEnabled && !headlessClients.Exists(string.IsNullOrWhiteSpace) ? $"headlessClients[] = { "{\n\t\"" + string.Join("\",\n\t \"", headlessClients) + "\"\n}" };\r\n" : "")}" + $"{(headlessClientEnabled && !localClient.Exists(string.IsNullOrWhiteSpace)? $"localClient[] = { "{\n\t\"" + string.Join("\",\n\t \"", localClient) + "\"\n}" };" : "")}"; + output + = AdvancedOptionsContent; return output; + } } - public event PropertyChangedEventHandler PropertyChanged; private void RaisePropertyChanged(string property) @@ -1012,5 +951,4 @@ private void RaisePropertyChanged(string property) PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property)); } } - } } \ No newline at end of file From e025bfd0a30260d028e9bcfb6e165509399c6a09 Mon Sep 17 00:00:00 2001 From: jupster Date: Sat, 26 Jul 2025 08:50:09 +1000 Subject: [PATCH 34/45] Update ServerProfile.cs --- FASTER/Models/ServerProfile.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/FASTER/Models/ServerProfile.cs b/FASTER/Models/ServerProfile.cs index 221942d..fa36f9f 100644 --- a/FASTER/Models/ServerProfile.cs +++ b/FASTER/Models/ServerProfile.cs @@ -1,5 +1,4 @@ - -using System; +using System; using System.Collections.Generic; using System.ComponentModel; using System.IO; From 54deb4db5d0f3fb0b16410194535e6cd826e086e Mon Sep 17 00:00:00 2001 From: jupster Date: Sat, 26 Jul 2025 08:51:05 +1000 Subject: [PATCH 35/45] Advanced File exists --- FASTER/ViewModel/ProfileViewModel.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/FASTER/ViewModel/ProfileViewModel.cs b/FASTER/ViewModel/ProfileViewModel.cs index ee04841..0e54763 100644 --- a/FASTER/ViewModel/ProfileViewModel.cs +++ b/FASTER/ViewModel/ProfileViewModel.cs @@ -189,7 +189,8 @@ private bool ProfileFilesExist(string profile) if (!Directory.Exists(Path.Combine(path, "Servers", profile))) { return false; } - return File.Exists(Path.Combine(path, "Servers", profile, "server_config.cfg")) + return File.Exists(Path.Combine(path, "Servers", profile, "server_config.cfg")) + && File.Exists(Path.Combine(path, "Servers", profile, "server_advanced.cfg")) && File.Exists(Path.Combine(path, "Servers", profile, "server_basic.cfg")); } @@ -210,7 +211,7 @@ internal void DeleteProfile() internal void SaveProfile() { string config = Path.Combine(Profile.ArmaPath, "Servers", Profile.Id, "server_config.cfg"); - string advanced = Path.Combine(Profile.ArmaPath, "servers", Profile.Id, "Server_advanced + string advanced = Path.Combine(Profile.ArmaPath, "Servers", Profile.Id, "server_advanced"); string basic = Path.Combine(Profile.ArmaPath, "Servers", Profile.Id, "server_basic.cfg"); string serverProfile = Path.Combine(Profile.ArmaPath, "Servers", Profile.Id, "users", Profile.Id, $"{Profile.Id}.Arma3Profile"); @@ -221,6 +222,7 @@ internal void SaveProfile() try { File.WriteAllLines(config, Profile.ServerCfg.ServerCfgContent.Replace("\r", "").Split('\n')); + File.WriteAllLines(advanced, Profile.AdvancedOptions.AdvancedOptionsContent.Replace("\r", "").Split('\n')); File.WriteAllLines(basic, Profile.BasicCfg.BasicContent.Replace("\r", "").Split('\n')); File.WriteAllLines(serverProfile, Profile.ArmaProfile.ArmaProfileContent.Replace("\r", "").Split('\n')); } From 9ff7583a46807ca511e08a7d0de617856751a1e7 Mon Sep 17 00:00:00 2001 From: jupster Date: Sat, 26 Jul 2025 19:05:12 +1000 Subject: [PATCH 36/45] =?UTF-8?q?Spelling=20Good=20=F0=9F=91=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FASTER/ViewModel/SteamUpdaterViewModel.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FASTER/ViewModel/SteamUpdaterViewModel.cs b/FASTER/ViewModel/SteamUpdaterViewModel.cs index ee740d8..5039088 100644 --- a/FASTER/ViewModel/SteamUpdaterViewModel.cs +++ b/FASTER/ViewModel/SteamUpdaterViewModel.cs @@ -458,7 +458,7 @@ public async Task RunModsUpdater(ObservableCollection mods) return; } - if (!SteamClient.Credentials.IsAnonymous) //IS SYNC NEABLED + if (!SteamClient.Credentials.IsAnonymous) //IS SYNC ENABLED { Parameters.Output += $"\n Getting manifest for {mod.WorkshopId}"; manifestId = SteamContentClient.GetPublishedFileDetailsAsync(mod.WorkshopId).Result.hcontent_file; From d965529284008260219a74cda5d2a86f83be374e Mon Sep 17 00:00:00 2001 From: jupster Date: Sat, 26 Jul 2025 19:11:00 +1000 Subject: [PATCH 37/45] Improve RaisePropertyChanged calls using nameof Replaced hard-coded string literals in RaisePropertyChanged calls with the nameof operator. Ensures compile-time checking of property names Prevents runtime bugs if properties are renamed Makes the code more maintainable and refactor-friendly --- FASTER/Models/AdvancedOptions.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/FASTER/Models/AdvancedOptions.cs b/FASTER/Models/AdvancedOptions.cs index b55a5a3..a37de8d 100644 --- a/FASTER/Models/AdvancedOptions.cs +++ b/FASTER/Models/AdvancedOptions.cs @@ -18,7 +18,7 @@ public bool LogObjectNotFound set { logObjectNotFound = value; - RaisePropertyChanged(nameof("LogObjectNotFound")); + RaisePropertyChanged(nameof(LogObjectNotFound)); } } @@ -28,7 +28,7 @@ public bool SkipDescriptionParsing set { skipDescriptionParsing = value; - RaisePropertyChanged(nameof("SkipDescriptionParsing")); + RaisePropertyChanged(nameof(SkipDescriptionParsing)); } } @@ -38,7 +38,7 @@ public bool IgnoreMissionLoadErrors set { ignoreMissionLoadErrors = value; - RaisePropertyChanged(nameof("IgnoreMissionLoadErrors")); + RaisePropertyChanged(nameof(IgnoreMissionLoadErrors)); } } @@ -48,7 +48,7 @@ public int QueueSizeLogG set { queueSizeLogG = value; - RaisePropertyChanged(nameof("QueueSizeLogG")); + RaisePropertyChanged(nameof(QueueSizeLogG)); } } @@ -58,7 +58,7 @@ public string AdvancedOptionsContent set { advancedOptionsContent = value; - RaisePropertyChanged(nameof("AdvancedOptionsContent")); + RaisePropertyChanged(nameof(AdvancedOptionsContent)); } } From 1cc455bf4c398adeaae6a6f91c3b238e3e284125 Mon Sep 17 00:00:00 2001 From: jupster Date: Sat, 26 Jul 2025 19:13:39 +1000 Subject: [PATCH 38/45] Refactor ProfileViewModel - Replaced hard-coded paths with local variables - Added checks for missing mod directories and handled failures - Used Distinct() to avoid duplicate mod key processing - Improved error reporting with more precise file names - Updated ClearModKeys to skip ignored keys by file name instead of partial string match - General cleanup for better readability and reliability --- FASTER/ViewModel/ProfileViewModel.cs | 65 ++++++++++++++++++++-------- 1 file changed, 47 insertions(+), 18 deletions(-) diff --git a/FASTER/ViewModel/ProfileViewModel.cs b/FASTER/ViewModel/ProfileViewModel.cs index 0e54763..152eadc 100644 --- a/FASTER/ViewModel/ProfileViewModel.cs +++ b/FASTER/ViewModel/ProfileViewModel.cs @@ -245,7 +245,6 @@ internal void SaveProfile() MissingMods++; } - var index = Properties.Settings.Default.Profiles.FindIndex(p => p.Id == Profile.Id); if (index != -1) { Properties.Settings.Default.Profiles[index] = Profile; } @@ -256,7 +255,6 @@ internal void SaveProfile() if (MissingMods > 0) DisplayMessage($"{MissingMods} mods were not found in the Arma directory.\nMake sure you have deployed the correct mods"); - } public ObservableCollection FadeOutStrings { get; } = new ObservableCollection(ProfileCfgArrays.FadeOutStrings); @@ -355,51 +353,82 @@ internal void SelectServerFile() internal async Task CopyModKeys() { var mods = new List(); + var failedMods = new List(); + + string stagingDir = Properties.Settings.Default.modStagingDirectory; + string keysDir = Path.Combine(Profile.ArmaPath, "keys"); - if (!Directory.Exists(Properties.Settings.Default.modStagingDirectory)) + if (!Directory.Exists(stagingDir)) { MainWindow.Instance.IFlyout.IsOpen = true; - MainWindow.Instance.IFlyoutMessage.Content = $"The SteamCMD path does not exist :\n{Properties.Settings.Default.modStagingDirectory}"; + MainWindow.Instance.IFlyoutMessage.Content = $"The SteamCMD path does not exist:\n{stagingDir}"; return; } var clientMods = Profile.ProfileMods.Where(p => p.ClientSideChecked).ToList(); var optionalMods = Profile.ProfileMods.Where(p => p.OptChecked).ToList(); - var steamMods = clientMods.Union(optionalMods).ToList(); + var steamMods = clientMods.Union(optionalMods).Distinct().ToList(); - foreach (var line in steamMods) + foreach (var mod in steamMods) { + string modPath = Path.Combine(stagingDir, mod.Id.ToString()); + try - { mods.AddRange(Directory.GetDirectories(Path.Combine(Properties.Settings.Default.modStagingDirectory, line.Id.ToString())) - .SelectMany(subDir => Directory.GetFiles(subDir, "*.bikey", SearchOption.TopDirectoryOnly))); } + { + if (!Directory.Exists(modPath)) + { + failedMods.Add(mod.Name); + continue; + } + mods.AddRange(Directory.GetDirectories(modPath) + .SelectMany(subDir => Directory.GetFiles(subDir, "*.bikey", SearchOption.TopDirectoryOnly))); + } catch (DirectoryNotFoundException) - { /*there was no directory*/ } + { + failedMods.Add(mod.Name); + } + catch (IOException) + { + failedMods.Add(mod.Name); + } } await ClearModKeys(); - Directory.CreateDirectory(Path.Combine(Profile.ArmaPath, "keys")); - - foreach (var link in mods) + Directory.CreateDirectory(keysDir); + foreach (var link in mods.Distinct()) { - try { File.Copy(link, Path.Combine(Profile.ArmaPath, "keys", Path.GetFileName(link)), true); } + try { File.Copy(link, Path.Combine(keysDir, Path.GetFileName(link)), true); } catch (IOException) { MainWindow.Instance.IFlyout.IsOpen = true; MainWindow.Instance.IFlyoutMessage.Content = $"Some keys could not be copied : {Path.GetFileName(link)}"; } } + + if (failedMods.Count > 0) + { + DisplayMessage("Failed to read keys for these mods:\n" + string.Join("\n", failedMods.Distinct())); + } + else + { + DisplayMessage("All mod keys copied successfully."); + } + await Task.Delay(1000); - } + } internal async Task ClearModKeys() { var ignoredKeys = new[] {"a3.bikey", "a3c.bikey", "gm.bikey", "ws.bikey", "csla.bikey", "vn.bikey", "spe.bikey", "rf.bikey", "ef.bikey" }; - if (Directory.Exists(Path.Combine(Profile.ArmaPath, "keys"))) + string keysDir = Path.Combine(Profile.ArmaPath, "keys"); + + if (Directory.Exists(keysDir)) { - foreach (var keyFile in Directory.GetFiles(Path.Combine(Profile.ArmaPath, "keys"))) + foreach (var keyFile in Directory.GetFiles(keysDir)) { - if (Array.Exists(ignoredKeys, x => keyFile.Contains(x))) + var fileName = Path.GetFileName(keyFile); + if (ignoredKeys.Contains(fileName)) continue; try { @@ -408,7 +437,7 @@ internal async Task ClearModKeys() catch (Exception) { MainWindow.Instance.IFlyout.IsOpen = true; - MainWindow.Instance.IFlyoutMessage.Content = $"Some keys could not be cleared : {Path.GetFileName(keyFile)}"; + MainWindow.Instance.IFlyoutMessage.Content = $"Some keys could not be cleared : {fileName}"; } } } From 7d37e3fb8b725c9bffd286530b0c05feede25e98 Mon Sep 17 00:00:00 2001 From: jupster Date: Sat, 26 Jul 2025 19:36:26 +1000 Subject: [PATCH 39/45] Update AdvancedOptions.cs --- FASTER/Models/AdvancedOptions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FASTER/Models/AdvancedOptions.cs b/FASTER/Models/AdvancedOptions.cs index a37de8d..a9e1c7f 100644 --- a/FASTER/Models/AdvancedOptions.cs +++ b/FASTER/Models/AdvancedOptions.cs @@ -9,7 +9,7 @@ public class AdvancedOptions : INotifyPropertyChanged private bool logObjectNotFound = true; // logging enabled private bool skipDescriptionParsing = false; // Parse description.ext private bool ignoreMissionLoadErrors = false; // Do not ignore errors - private int queueSizeLogG = 0; // If a specific players message queue is larger than and '#monitor' is running, dump his messages to a logfile for analysis + private int queueSizeLogG = 0; // If a specific players message queue is larger than and '#monitor' is running, dump the messages to a logfile for analysis private string advancedOptionsContent; public bool LogObjectNotFound From 6cc25d7209af15fe0f9ca6440c1cd61e5fff0e91 Mon Sep 17 00:00:00 2001 From: jupster Date: Sat, 26 Jul 2025 20:53:37 +1000 Subject: [PATCH 40/45] Output pls --- FASTER/Models/ServerCfg.cs | 8 -------- 1 file changed, 8 deletions(-) diff --git a/FASTER/Models/ServerCfg.cs b/FASTER/Models/ServerCfg.cs index 89d43fa..e5f5cc2 100644 --- a/FASTER/Models/ServerCfg.cs +++ b/FASTER/Models/ServerCfg.cs @@ -779,12 +779,6 @@ private void Item_PropertyChanged(object sender, PropertyChangedEventArgs e) RaisePropertyChanged("MissionContentOverride"); } - // Grab Advanced output - public AdvancedOptions AdvancedOptions { get; set; } = new(); - - // Optional convenience property to expose the raw content - public string AdvancedOptionsContent => AdvancedOptions.AdvancedOptionsContent; - public string ProcessFile() { if (!missionSelectorChecked) @@ -807,7 +801,6 @@ public string ProcessFile() { MissionContentOverride = compiledMission; } } - public string GenerateCfgFile() { string output = "//\r\n" + "// server.cfg\r\n" @@ -893,7 +886,6 @@ public string GenerateCfgFile() + "// HEADLESS CLIENT\r\n" + $"{(headlessClientEnabled && !headlessClients.Exists(string.IsNullOrWhiteSpace) ? $"headlessClients[] = { "{\n\t\"" + string.Join("\",\n\t \"", headlessClients) + "\"\n}" };\r\n" : "")}" + $"{(headlessClientEnabled && !localClient.Exists(string.IsNullOrWhiteSpace)? $"localClient[] = { "{\n\t\"" + string.Join("\",\n\t \"", localClient) + "\"\n}" };" : "")}"; - output + = AdvancedOptionsContent; return output; } } From 02c7cb2f32606b3247445718ff6374dbc966d14d Mon Sep 17 00:00:00 2001 From: jupster Date: Sun, 27 Jul 2025 17:34:37 +1000 Subject: [PATCH 41/45] Align UI checkboxes with AdvancedOptions --- FASTER/Views/Profile.xaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/FASTER/Views/Profile.xaml b/FASTER/Views/Profile.xaml index 57eb536..33457a9 100644 --- a/FASTER/Views/Profile.xaml +++ b/FASTER/Views/Profile.xaml @@ -649,9 +649,9 @@ - - - + + + @@ -660,7 +660,7 @@ - + From 02e5fa3e4688440cc146d59745b4462bd628ad76 Mon Sep 17 00:00:00 2001 From: jupster Date: Sun, 27 Jul 2025 18:48:18 +1000 Subject: [PATCH 42/45] Update ProfileViewModel.cs --- FASTER/ViewModel/ProfileViewModel.cs | 34 ++++++++++------------------ 1 file changed, 12 insertions(+), 22 deletions(-) diff --git a/FASTER/ViewModel/ProfileViewModel.cs b/FASTER/ViewModel/ProfileViewModel.cs index 152eadc..4dc6f75 100644 --- a/FASTER/ViewModel/ProfileViewModel.cs +++ b/FASTER/ViewModel/ProfileViewModel.cs @@ -355,13 +355,10 @@ internal async Task CopyModKeys() var mods = new List(); var failedMods = new List(); - string stagingDir = Properties.Settings.Default.modStagingDirectory; - string keysDir = Path.Combine(Profile.ArmaPath, "keys"); - - if (!Directory.Exists(stagingDir)) + if (!Directory.Exists(Properties.Settings.Default.modStagingDirectory)) { MainWindow.Instance.IFlyout.IsOpen = true; - MainWindow.Instance.IFlyoutMessage.Content = $"The SteamCMD path does not exist:\n{stagingDir}"; + MainWindow.Instance.IFlyoutMessage.Content = $"The SteamCMD path does not exist:\n{Properties.Settings.Default.modStagingDirectory}"; return; } @@ -369,36 +366,30 @@ internal async Task CopyModKeys() var optionalMods = Profile.ProfileMods.Where(p => p.OptChecked).ToList(); var steamMods = clientMods.Union(optionalMods).Distinct().ToList(); - foreach (var mod in steamMods) + foreach (var line in steamMods) { - string modPath = Path.Combine(stagingDir, mod.Id.ToString()); - try { - if (!Directory.Exists(modPath)) + if (!Directory.Exists(Properties.Settings.Default.modStagingDirectory)) { - failedMods.Add(mod.Name); + failedMods.Add(line.Name); continue; } - mods.AddRange(Directory.GetDirectories(modPath) + mods.AddRange(Directory.GetDirectories(Path.Combine(Properties.Settings.Default.modStagingDirectory, line.Id.ToString())) .SelectMany(subDir => Directory.GetFiles(subDir, "*.bikey", SearchOption.TopDirectoryOnly))); } catch (DirectoryNotFoundException) { - failedMods.Add(mod.Name); - } - catch (IOException) - { - failedMods.Add(mod.Name); + failedMods.Add(line.Name); } } await ClearModKeys(); - Directory.CreateDirectory(keysDir); + Directory.CreateDirectory(Path.Combine(Profile.ArmaPath, "keys")); foreach (var link in mods.Distinct()) { - try { File.Copy(link, Path.Combine(keysDir, Path.GetFileName(link)), true); } + try { File.Copy(link, Path.Combine(Profile.ArmaPath, "keys", Path.GetFileName(link)), true); } catch (IOException) { MainWindow.Instance.IFlyout.IsOpen = true; @@ -421,11 +412,10 @@ internal async Task CopyModKeys() internal async Task ClearModKeys() { var ignoredKeys = new[] {"a3.bikey", "a3c.bikey", "gm.bikey", "ws.bikey", "csla.bikey", "vn.bikey", "spe.bikey", "rf.bikey", "ef.bikey" }; - string keysDir = Path.Combine(Profile.ArmaPath, "keys"); - if (Directory.Exists(keysDir)) + if (Directory.Exists(Path.Combine(Profile.ArmaPath, "keys"))) { - foreach (var keyFile in Directory.GetFiles(keysDir)) + foreach (var keyFile in Directory.GetFiles((Path.Combine(Profile.ArmaPath, "keys")))) { var fileName = Path.GetFileName(keyFile); if (ignoredKeys.Contains(fileName)) @@ -437,7 +427,7 @@ internal async Task ClearModKeys() catch (Exception) { MainWindow.Instance.IFlyout.IsOpen = true; - MainWindow.Instance.IFlyoutMessage.Content = $"Some keys could not be cleared : {fileName}"; + MainWindow.Instance.IFlyoutMessage.Content = $"Some keys could not be cleared : {Path.GetFileName(keyFile)}"; } } } From d485ebfebc8aaf5b6cf6d88f50d70ba00a305a66 Mon Sep 17 00:00:00 2001 From: jupster Date: Sun, 27 Jul 2025 20:13:39 +1000 Subject: [PATCH 43/45] I'm stupid --- FASTER/ViewModel/ProfileViewModel.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FASTER/ViewModel/ProfileViewModel.cs b/FASTER/ViewModel/ProfileViewModel.cs index 4dc6f75..06c0dad 100644 --- a/FASTER/ViewModel/ProfileViewModel.cs +++ b/FASTER/ViewModel/ProfileViewModel.cs @@ -211,7 +211,7 @@ internal void DeleteProfile() internal void SaveProfile() { string config = Path.Combine(Profile.ArmaPath, "Servers", Profile.Id, "server_config.cfg"); - string advanced = Path.Combine(Profile.ArmaPath, "Servers", Profile.Id, "server_advanced"); + string advanced = Path.Combine(Profile.ArmaPath, "Servers", Profile.Id, "server_advanced.cfg"); string basic = Path.Combine(Profile.ArmaPath, "Servers", Profile.Id, "server_basic.cfg"); string serverProfile = Path.Combine(Profile.ArmaPath, "Servers", Profile.Id, "users", Profile.Id, $"{Profile.Id}.Arma3Profile"); From 397cc486d87eb1bd79e1901e78b02583d07b2a34 Mon Sep 17 00:00:00 2001 From: jupster Date: Sun, 27 Jul 2025 20:40:03 +1000 Subject: [PATCH 44/45] Fix nested code --- FASTER/Models/ServerCfg.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/FASTER/Models/ServerCfg.cs b/FASTER/Models/ServerCfg.cs index e5f5cc2..e50b1eb 100644 --- a/FASTER/Models/ServerCfg.cs +++ b/FASTER/Models/ServerCfg.cs @@ -801,7 +801,6 @@ public string ProcessFile() { MissionContentOverride = compiledMission; } } - { string output = "//\r\n" + "// server.cfg\r\n" + "//\r\n" @@ -887,8 +886,8 @@ public string ProcessFile() + $"{(headlessClientEnabled && !headlessClients.Exists(string.IsNullOrWhiteSpace) ? $"headlessClients[] = { "{\n\t\"" + string.Join("\",\n\t \"", headlessClients) + "\"\n}" };\r\n" : "")}" + $"{(headlessClientEnabled && !localClient.Exists(string.IsNullOrWhiteSpace)? $"localClient[] = { "{\n\t\"" + string.Join("\",\n\t \"", localClient) + "\"\n}" };" : "")}"; return output; - } } + public event PropertyChangedEventHandler PropertyChanged; private void RaisePropertyChanged(string property) From 98a2259aa84dcef42e90a0d8d3e320b7a3e3f075 Mon Sep 17 00:00:00 2001 From: jupster Date: Mon, 28 Jul 2025 15:14:50 +1000 Subject: [PATCH 45/45] Update ServerCfg.cs --- FASTER/Models/ServerCfg.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/FASTER/Models/ServerCfg.cs b/FASTER/Models/ServerCfg.cs index e50b1eb..3659802 100644 --- a/FASTER/Models/ServerCfg.cs +++ b/FASTER/Models/ServerCfg.cs @@ -885,6 +885,7 @@ public string ProcessFile() + "// HEADLESS CLIENT\r\n" + $"{(headlessClientEnabled && !headlessClients.Exists(string.IsNullOrWhiteSpace) ? $"headlessClients[] = { "{\n\t\"" + string.Join("\",\n\t \"", headlessClients) + "\"\n}" };\r\n" : "")}" + $"{(headlessClientEnabled && !localClient.Exists(string.IsNullOrWhiteSpace)? $"localClient[] = { "{\n\t\"" + string.Join("\",\n\t \"", localClient) + "\"\n}" };" : "")}"; + + "\r\n" return output; } @@ -901,7 +902,7 @@ private void RaisePropertyChanged(string property) [Serializable] public class ProfileMission : INotifyPropertyChanged { - private bool missionChecked; + private bool missionChecked; private string name; private string path;