├── version.txt ├── .gitattributes ├── docs ├── logo.png ├── longbow_fit.png ├── longbow_logo.png ├── longbow_logo_full.png ├── servertoolscreen.png ├── servertoolscreen2.png ├── servertoolscreen3.png └── longbow_text_only_fit.png ├── ArmaReforgerServerTool ├── Resources │ ├── arma_icon.ico │ ├── arma_icon.png │ ├── arma_icon_white.ico │ ├── arma_icon_white.png │ └── NoBackendScenarioLoader_6324F7124A9768FB.zip ├── Components │ ├── ServerParameterString.cs │ ├── BoundListBox.cs │ ├── AdvancedServerParameterBool.cs │ ├── ServerParameterSelect.cs │ ├── ServerParameterText.cs │ ├── ServerParameterList.cs │ ├── ServerParameterBool.cs │ ├── ServerParameterNumeric.cs │ ├── AdvancedServerParameterString.cs │ ├── AdvancedServerParameterTime.cs │ ├── AdvancedServerParameterBool.Designer.cs │ ├── ServerParameter.cs │ ├── AdvancedServerParameterEnumerated.cs │ ├── AdvancedServerParameterString.Designer.cs │ ├── AdvancedServerParameterEnumerated.Designer.cs │ ├── AdvancedServerParameterTime.Designer.cs │ ├── AdvancedServerParameterNumeric.Designer.cs │ ├── ServerParameter.Designer.cs │ ├── AdvancedServerParameterNumeric.cs │ ├── AdvancedServerParameter.cs │ ├── ServerParameterSelect.Designer.cs │ ├── ServerParameterString.Designer.cs │ ├── ServerParameterList.Designer.cs │ ├── ServerParameterText.Designer.cs │ ├── ServerParameterBool.Designer.cs │ ├── AdvancedServerParameterSchedule.cs │ ├── ServerParameterNumeric.Designer.cs │ ├── AdvancedServerParameter.Designer.cs │ ├── AdvancedServerParameterSchedule.Designer.cs │ ├── ServerParameter.resx │ ├── ServerParameterList.resx │ ├── ServerParameterText.resx │ ├── AdvancedServerParameter.resx │ ├── AdvancedServerParameterBool.resx │ ├── AdvancedServerParameterTime.resx │ ├── ServerParameterBool.resx │ └── ServerParameterNumeric.resx ├── Forms │ ├── TextInputForm.cs │ ├── RenameForm.cs │ ├── AboutBox.cs │ ├── ListForm.cs │ ├── TextInputForm.Designer.cs │ ├── AboutBox.Designer.cs │ ├── AddModDialog.cs │ ├── ListForm.Designer.cs │ ├── RenameForm.Designer.cs │ ├── SaveSelector.cs │ ├── ScenarioSelector.Designer.cs │ ├── AboutBox.resx │ ├── AddModDialog.resx │ ├── ListForm.resx │ ├── RenameForm.resx │ ├── ScenarioSelector.resx │ └── TextInputForm.resx ├── ArmaReforgerServerTool.sln ├── Models │ ├── Scenario.cs │ ├── AdvancedSetting.cs │ ├── LaunchArgument.cs │ └── Mod.cs ├── Program.cs ├── Properties │ └── Resources.Designer.cs ├── Longbow.csproj └── Managers │ ├── SavedStateManager.cs │ ├── ToolPropertiesManager.cs │ └── NetworkManager.cs ├── .github ├── dependabot.yml └── FUNDING.yml ├── .editorconfig ├── Longbow.sln ├── scripts └── ArmaReforgerServerTool_NSIS_Install_Build_Script.nsi └── README.md /version.txt: -------------------------------------------------------------------------------- 1 | 1.1.0 -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /docs/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soda3x/ArmaReforgerServerTool/HEAD/docs/logo.png -------------------------------------------------------------------------------- /docs/longbow_fit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soda3x/ArmaReforgerServerTool/HEAD/docs/longbow_fit.png -------------------------------------------------------------------------------- /docs/longbow_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soda3x/ArmaReforgerServerTool/HEAD/docs/longbow_logo.png -------------------------------------------------------------------------------- /docs/longbow_logo_full.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soda3x/ArmaReforgerServerTool/HEAD/docs/longbow_logo_full.png -------------------------------------------------------------------------------- /docs/servertoolscreen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soda3x/ArmaReforgerServerTool/HEAD/docs/servertoolscreen.png -------------------------------------------------------------------------------- /docs/servertoolscreen2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soda3x/ArmaReforgerServerTool/HEAD/docs/servertoolscreen2.png -------------------------------------------------------------------------------- /docs/servertoolscreen3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soda3x/ArmaReforgerServerTool/HEAD/docs/servertoolscreen3.png -------------------------------------------------------------------------------- /docs/longbow_text_only_fit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soda3x/ArmaReforgerServerTool/HEAD/docs/longbow_text_only_fit.png -------------------------------------------------------------------------------- /ArmaReforgerServerTool/Resources/arma_icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soda3x/ArmaReforgerServerTool/HEAD/ArmaReforgerServerTool/Resources/arma_icon.ico -------------------------------------------------------------------------------- /ArmaReforgerServerTool/Resources/arma_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soda3x/ArmaReforgerServerTool/HEAD/ArmaReforgerServerTool/Resources/arma_icon.png -------------------------------------------------------------------------------- /ArmaReforgerServerTool/Resources/arma_icon_white.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soda3x/ArmaReforgerServerTool/HEAD/ArmaReforgerServerTool/Resources/arma_icon_white.ico -------------------------------------------------------------------------------- /ArmaReforgerServerTool/Resources/arma_icon_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soda3x/ArmaReforgerServerTool/HEAD/ArmaReforgerServerTool/Resources/arma_icon_white.png -------------------------------------------------------------------------------- /ArmaReforgerServerTool/Resources/NoBackendScenarioLoader_6324F7124A9768FB.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soda3x/ArmaReforgerServerTool/HEAD/ArmaReforgerServerTool/Resources/NoBackendScenarioLoader_6324F7124A9768FB.zip -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for all configuration options: 4 | # https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file 5 | 6 | version: 2 7 | updates: 8 | - package-ecosystem: "nuget" # See documentation for possible values 9 | directory: "/ArmaReforgerServerTool" # Location of package manifests 10 | schedule: 11 | interval: "weekly" 12 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 4 8 | end_of_line = lf 9 | insert_final_newline = true 10 | trim_trailing_whitespace = true 11 | 12 | 13 | [*.cs] 14 | indent_style = space 15 | indent_size = 2 16 | 17 | 18 | [*.csproj] 19 | indent_style = space 20 | indent_size = 2 21 | 22 | 23 | [*.sln] 24 | indent_style = space 25 | indent_size = 2 26 | 27 | 28 | [*.md] 29 | trim_trailing_whitespace = false 30 | 31 | 32 | # Rider / ReSharper settings 33 | [*Generated.cs] 34 | indent_style = space 35 | indent_size = 4 36 | 37 | 38 | [*.g.cs] 39 | indent_style = space 40 | indent_size = 4 41 | 42 | 43 | [*.g.i.cs] 44 | indent_style = space 45 | indent_size = 4 46 | 47 | 48 | # Visual Studio settings 49 | [*.xaml] 50 | indent_style = space 51 | indent_size = 4 52 | 53 | -------------------------------------------------------------------------------- /ArmaReforgerServerTool/Components/ServerParameterString.cs: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * File Name: ServerParameterString.cs 3 | * Project: Longbow 4 | * Description: The ServerParameterString component represents a graphical 5 | * means to manage string server configuration parameters 6 | * 7 | * Author: Bradley Newman 8 | ******************************************************************************/ 9 | 10 | namespace ReforgerServerApp 11 | { 12 | public partial class ServerParameterString : ServerParameter 13 | { 14 | public ServerParameterString() 15 | { 16 | InitializeComponent(); 17 | underlyingControl = parameterValue; 18 | } 19 | 20 | public override object ParameterValue 21 | { 22 | get => parameterValue.Text; 23 | set => parameterValue.Text = (string)value; 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: soda3x 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry 12 | polar: # Replace with a single Polar username 13 | buy_me_a_coffee: # Replace with a single Buy Me a Coffee username 14 | thanks_dev: # Replace with a single thanks.dev username 15 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 16 | -------------------------------------------------------------------------------- /ArmaReforgerServerTool/Components/BoundListBox.cs: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * File Name: BoundListBox.cs 3 | * Project: Longbow 4 | * Description: The BoundListBox component is an extension of the ListBox 5 | * component with the addition of automatically refreshing its 6 | * contents upon updates to the List Box's underlying data 7 | * source. 8 | * 9 | * Performs the same as a List Box when the DataSource property 10 | * is not set. 11 | * 12 | * Author: Bradley Newman 13 | ******************************************************************************/ 14 | 15 | namespace ReforgerServerApp.Components 16 | { 17 | internal class BoundListBox : ListBox 18 | { 19 | public new void RefreshItems() 20 | { 21 | SelectedIndex = -1; 22 | base.RefreshItems(); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /ArmaReforgerServerTool/Forms/TextInputForm.cs: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * File Name: TextInputForm.cs 3 | * Project: Longbow 4 | * Description: This is a generic form for entering lots of text, either 5 | * formatted or not 6 | * 7 | * Author: Bradley Newman 8 | ******************************************************************************/ 9 | 10 | namespace ReforgerServerApp 11 | { 12 | public partial class TextInputForm : Form 13 | { 14 | 15 | public TextInputForm(string windowTitle, String prefilledText) 16 | { 17 | InitializeComponent(); 18 | this.Text = $"Longbow - {windowTitle}"; 19 | textInputField.Text = prefilledText; 20 | } 21 | 22 | private void OkBtnClicked(object sender, EventArgs e) 23 | { 24 | Close(); 25 | } 26 | 27 | /// 28 | /// Get the text contents of the input form 29 | /// 30 | /// 31 | public String GetText() 32 | { 33 | return textInputField.Text; 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /ArmaReforgerServerTool/Components/AdvancedServerParameterBool.cs: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * File Name: AdvancedServerParameterBool.cs 3 | * Project: Longbow 4 | * Description: The AdvancedServerParameterBool component represents a 5 | * graphical means to manage switch style server launch 6 | * arguments 7 | * 8 | * Author: Bradley Newman 9 | ******************************************************************************/ 10 | 11 | namespace ReforgerServerApp.Components 12 | { 13 | public partial class AdvancedServerParameterBool : AdvancedServerParameter 14 | { 15 | public AdvancedServerParameterBool() 16 | { 17 | InitializeComponent(); 18 | } 19 | 20 | public override object ParameterValue 21 | { 22 | get => CheckBox.Checked; 23 | set => CheckBox.Checked = (bool)value; 24 | } 25 | 26 | override 27 | public void OnCheckChanged(object sender, EventArgs e) 28 | { 29 | // Do nothing, this is a boolean parameter so we only care if it's enabled or not 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /ArmaReforgerServerTool/Components/ServerParameterSelect.cs: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * File Name: ServerParameterSelect.cs 3 | * Project: Longbow 4 | * Description: The ServerParameterSelect component represents a graphical 5 | * means to manage choices 6 | * 7 | * Author: Bradley Newman 8 | ******************************************************************************/ 9 | 10 | namespace ReforgerServerApp 11 | { 12 | public partial class ServerParameterSelect : ServerParameter 13 | { 14 | public ServerParameterSelect() 15 | { 16 | InitializeComponent(); 17 | underlyingControl = parameterValue; 18 | } 19 | 20 | public override object ParameterValue 21 | { 22 | get => parameterValue.Text; 23 | set => parameterValue.DataSource = value; 24 | } 25 | 26 | public void ParameterValueSelection(string selectionString) 27 | { 28 | if (parameterValue.Items.Contains(selectionString)) 29 | { 30 | parameterValue.SelectedIndex = parameterValue.Items.IndexOf(selectionString); 31 | } 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /ArmaReforgerServerTool/Forms/RenameForm.cs: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * File Name: RenameForm.cs 3 | * Project: Longbow 4 | * Description: This file contains the RenameForm class which is a dialog 5 | * that provides the ability to rename text in a listbox 6 | * 7 | * Author: Bradley Newman 8 | ******************************************************************************/ 9 | 10 | namespace Longbow.Forms 11 | { 12 | public partial class RenameForm : Form 13 | { 14 | string m_resultingRename; 15 | public RenameForm(string text) 16 | { 17 | InitializeComponent(); 18 | renameTB.Text = text; 19 | } 20 | 21 | private void CancelBtnPressed(object sender, EventArgs e) 22 | { 23 | this.DialogResult = DialogResult.Cancel; 24 | } 25 | 26 | private void RenameBtnPressed(object sender, EventArgs e) 27 | { 28 | m_resultingRename = renameTB.Text; 29 | this.DialogResult = DialogResult.OK; 30 | } 31 | 32 | public string GetResultingRename() 33 | { 34 | return m_resultingRename; 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /ArmaReforgerServerTool/Components/ServerParameterText.cs: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * File Name: ServerParameterText.cs 3 | * Project: Longbow 4 | * Description: The ServerParameterText component represents long text input 5 | * 6 | * Author: Bradley Newman 7 | ******************************************************************************/ 8 | 9 | namespace ReforgerServerApp 10 | { 11 | public partial class ServerParameterText : ServerParameter 12 | { 13 | public ServerParameterText() 14 | { 15 | InitializeComponent(); 16 | underlyingControl = parameterValue; 17 | ParameterText = String.Empty; 18 | } 19 | 20 | public string ParameterText { get; set; } 21 | 22 | public override object ParameterValue 23 | { 24 | get => ParameterText; 25 | set => ParameterText = (string) value; 26 | } 27 | 28 | private void OnButtonPressed(object sender, EventArgs e) 29 | { 30 | TextInputForm tif = new($"Edit {ParameterFriendlyName}", ParameterText); 31 | tif.ShowDialog(); 32 | ParameterText = tif.GetText(); 33 | } 34 | 35 | 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Longbow.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.2.32210.308 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Longbow", "ArmaReforgerServerTool\Longbow.csproj", "{57B14DD9-F641-4987-AE66-387D1FC6E26B}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {57B14DD9-F641-4987-AE66-387D1FC6E26B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {57B14DD9-F641-4987-AE66-387D1FC6E26B}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {57B14DD9-F641-4987-AE66-387D1FC6E26B}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {57B14DD9-F641-4987-AE66-387D1FC6E26B}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {F1CE606E-614D-4144-B653-997F17DE72A3} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /ArmaReforgerServerTool/ArmaReforgerServerTool.sln: -------------------------------------------------------------------------------- 1 | Microsoft Visual Studio Solution File, Format Version 12.00 2 | # Visual Studio Version 17 3 | VisualStudioVersion = 17.5.2.0 4 | MinimumVisualStudioVersion = 10.0.40219.1 5 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Longbow", "Longbow.csproj", "{39AD1552-B50F-F929-5B24-2AFC8013D677}" 6 | EndProject 7 | Global 8 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 9 | Debug|Any CPU = Debug|Any CPU 10 | Release|Any CPU = Release|Any CPU 11 | EndGlobalSection 12 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 13 | {39AD1552-B50F-F929-5B24-2AFC8013D677}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 14 | {39AD1552-B50F-F929-5B24-2AFC8013D677}.Debug|Any CPU.Build.0 = Debug|Any CPU 15 | {39AD1552-B50F-F929-5B24-2AFC8013D677}.Release|Any CPU.ActiveCfg = Release|Any CPU 16 | {39AD1552-B50F-F929-5B24-2AFC8013D677}.Release|Any CPU.Build.0 = Release|Any CPU 17 | EndGlobalSection 18 | GlobalSection(SolutionProperties) = preSolution 19 | HideSolutionNode = FALSE 20 | EndGlobalSection 21 | GlobalSection(ExtensibilityGlobals) = postSolution 22 | SolutionGuid = {148BA206-4442-49DB-A945-5F14B33B7727} 23 | EndGlobalSection 24 | EndGlobal 25 | -------------------------------------------------------------------------------- /ArmaReforgerServerTool/Components/ServerParameterList.cs: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * File Name: ServerParameterSelect.cs 3 | * Project: Longbow 4 | * Description: The ServerParameterSelect component represents a graphical 5 | * means to manage choices 6 | * 7 | * Author: Bradley Newman 8 | ******************************************************************************/ 9 | 10 | namespace ReforgerServerApp 11 | { 12 | public partial class ServerParameterList : ServerParameter 13 | { 14 | public ServerParameterList() 15 | { 16 | InitializeComponent(); 17 | underlyingControl = parameterValue; 18 | ParameterList = Array.Empty(); 19 | } 20 | 21 | public string[] ParameterList { get; set; } 22 | 23 | public override object ParameterValue 24 | { 25 | get => ParameterList; 26 | set => ParameterList = (string[])value; 27 | } 28 | 29 | private void OnButtonPressed(object sender, EventArgs e) 30 | { 31 | ListForm lf = new(ParameterFriendlyName, ParameterList); 32 | lf.ShowDialog(); 33 | ParameterList = lf.GetItems(); 34 | } 35 | 36 | 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /ArmaReforgerServerTool/Models/Scenario.cs: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * File Name: Scenario.cs 3 | * Project: Longbow 4 | * Description: This file contains the Scenario class which represents 5 | * a default Arma Reforger scenario with a name and path 6 | * for ease of use for the end-user 7 | * 8 | * Author: Bradley Newman 9 | ******************************************************************************/ 10 | 11 | namespace Longbow.Models 12 | { 13 | internal class Scenario 14 | { 15 | 16 | /// 17 | /// The scenario's friendly name 18 | /// 19 | public string Name { get; set; } 20 | /// 21 | /// The scenario's ".conf" path 22 | /// 23 | public string Path { get; set; } 24 | 25 | /// 26 | /// Constructs a Scenario with a name and path 27 | /// 28 | /// 29 | /// 30 | public Scenario(string name, string path) 31 | { 32 | this.Name = name; 33 | this.Path = path; 34 | } 35 | 36 | public override string ToString() 37 | { 38 | return $"{Name} // {Path}"; 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /ArmaReforgerServerTool/Components/ServerParameterBool.cs: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * File Name: ServerParameterBool.cs 3 | * Project: Longbow 4 | * Description: The ServerParameterBool component represents a graphical 5 | * means to manage boolean server configuration parameters 6 | * 7 | * Author: Bradley Newman 8 | ******************************************************************************/ 9 | 10 | namespace ReforgerServerApp 11 | { 12 | public partial class ServerParameterBool : ServerParameter 13 | { 14 | private ServerParameter associatedControl; 15 | 16 | public ServerParameterBool() 17 | { 18 | InitializeComponent(); 19 | underlyingControl = parameterValue; 20 | } 21 | 22 | public override object ParameterValue 23 | { 24 | get => parameterValue.Checked; 25 | set => parameterValue.Checked = (bool)value; 26 | } 27 | 28 | public ServerParameter AssociatedControl 29 | { 30 | get => associatedControl; 31 | set => associatedControl = value; 32 | } 33 | 34 | public void OnCheckChanged(object sender, EventArgs e) 35 | { 36 | if (associatedControl != null) 37 | { 38 | associatedControl.SetFieldEnabled((bool)ParameterValue); 39 | } 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /ArmaReforgerServerTool/Forms/AboutBox.cs: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * File Name: AboutBox.cs 3 | * Project: Longbow 4 | * Description: This is the AboutBox Form 5 | * 6 | * Author: Bradley Newman 7 | ******************************************************************************/ 8 | 9 | using System.Reflection; 10 | using System.Text; 11 | 12 | namespace ReforgerServerApp 13 | { 14 | public partial class AboutBox : Form 15 | { 16 | public AboutBox() 17 | { 18 | InitializeComponent(); 19 | StringBuilder sb = new(); 20 | sb.AppendLine("Longbow - Arma Reforger Dedicated Server Tool by soda3x"); 21 | sb.AppendLine($"Version {Assembly.GetExecutingAssembly().GetName().Version}"); 22 | sb.AppendLine("\r\n\"No Backend Scenario Loader\" mod (v1.0.1) provided by ceo_of_bacon"); 23 | sb.AppendLine("See full list of contributors on GitHub"); 24 | aboutText.Text = sb.ToString(); 25 | } 26 | 27 | private void ReportBtnPressed(object sender, EventArgs e) 28 | { 29 | System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo { FileName = @"https://github.com/soda3x/ArmaReforgerServerTool/issues/", UseShellExecute = true }); 30 | } 31 | 32 | private void OKBtnPressed(object sender, EventArgs e) 33 | { 34 | this.Close(); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /ArmaReforgerServerTool/Components/ServerParameterNumeric.cs: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * File Name: ServerParameterNumeric.cs 3 | * Project: Longbow 4 | * Description: The ServerParameterNumeric component represents a graphical 5 | * means to manage numeric server configuration parameters 6 | * 7 | * Author: Bradley Newman 8 | ******************************************************************************/ 9 | 10 | namespace ReforgerServerApp 11 | { 12 | public partial class ServerParameterNumeric : ServerParameter 13 | { 14 | 15 | public ServerParameterNumeric() 16 | { 17 | InitializeComponent(); 18 | underlyingControl = parameterValue; 19 | } 20 | 21 | public override object ParameterValue 22 | { 23 | get => parameterValue.Value; 24 | set => parameterValue.Value = (Int32)value; 25 | } 26 | 27 | public decimal ParameterMin 28 | { 29 | get => parameterValue.Minimum; 30 | set => parameterValue.Minimum = value; 31 | } 32 | 33 | public decimal ParameterMax 34 | { 35 | get => parameterValue.Maximum; 36 | set => parameterValue.Maximum = value; 37 | } 38 | 39 | public decimal ParameterIncrement 40 | { 41 | get => parameterValue.Increment; 42 | set => parameterValue.Increment = value; 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /scripts/ArmaReforgerServerTool_NSIS_Install_Build_Script.nsi: -------------------------------------------------------------------------------- 1 | !define MUI_PRODUCT "Longbow" 2 | !define MUI_FILE "savefile" 3 | !define MUI_VERSION "" 4 | !define MUI_BRANDINGTEXT "Longbow" 5 | CRCCheck on 6 | 7 | Name "Longbow" 8 | 9 | !include "MUI2.nsh" 10 | 11 | OutFile "install_longbow.exe" 12 | 13 | !define MUI_ICON "${__FILEDIR__}\..\ArmaReforgerServerTool\Resources\arma_icon_white.ico" 14 | !define MUI_ABORTWARNING 15 | 16 | InstallDir $LOCALAPPDATA\Longbow 17 | !insertmacro MUI_PAGE_WELCOME 18 | !insertmacro MUI_PAGE_DIRECTORY 19 | !insertmacro MUI_PAGE_INSTFILES 20 | !insertmacro MUI_UNPAGE_WELCOME 21 | !insertmacro MUI_UNPAGE_CONFIRM 22 | !insertmacro MUI_UNPAGE_INSTFILES 23 | !insertmacro MUI_LANGUAGE "English" 24 | 25 | # Install Section 26 | Section 27 | SetOutPath $INSTDIR 28 | File /r /x *.txt /x *.pdb /x "mod_database.json" /x "state.json" /x "properties.json" /x "logs\*" "${__FILEDIR__}\..\ArmaReforgerServerTool\bin\Release\net8.0-windows\*.*" 29 | WriteUninstaller $INSTDIR\uninstall.exe 30 | CreateShortCut "$SMPROGRAMS\Longbow.lnk" "$INSTDIR\Longbow.exe" 31 | CreateShortCut "$SMPROGRAMS\Uninstall Longbow.lnk" "$INSTDIR\uninstall.exe" 32 | CreateShortCut "$DESKTOP\Longbow.lnk" "$INSTDIR\Longbow.exe" 33 | SectionEnd 34 | 35 | # Uninstall Section 36 | Section "Uninstall" 37 | RMDir /r "$INSTDIR\*.*" 38 | RMDir $INSTDIR 39 | Delete "$SMPROGRAMS\Longbow\Longbow.lnk" 40 | Delete "$SMPROGRAMS\Longbow\Uninstall Longbow.lnk" 41 | Delete "$DESKTOP\Longbow.lnk" 42 | SectionEnd 43 | -------------------------------------------------------------------------------- /ArmaReforgerServerTool/Components/AdvancedServerParameterString.cs: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * File Name: AdvancedServerParameterString.cs 3 | * Project: Longbow 4 | * Description: The AdvancedServerParameterString component represents a 5 | * graphical means to manage string server launch 6 | * arguments 7 | * 8 | * Author: Bradley Newman 9 | ******************************************************************************/ 10 | 11 | namespace ReforgerServerApp.Components 12 | { 13 | public partial class AdvancedServerParameterString : AdvancedServerParameter 14 | { 15 | public AdvancedServerParameterString() 16 | { 17 | InitializeComponent(); 18 | m_underlyingControl = parameterValue; 19 | SetFieldEnabled(Checked()); 20 | } 21 | 22 | public override object ParameterValue 23 | { 24 | get => parameterValue.Text; 25 | set => parameterValue.Text = (string)value; 26 | } 27 | 28 | public string ParameterPlaceholder 29 | { 30 | get => parameterValue.PlaceholderText; 31 | set => parameterValue.PlaceholderText = value; 32 | } 33 | 34 | public override void OnCheckChanged(object sender, EventArgs e) 35 | { 36 | if (CheckBox.Enabled) 37 | { 38 | SetFieldEnabled(Checked()); 39 | } 40 | else 41 | { 42 | SetFieldEnabled(false); 43 | } 44 | 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /ArmaReforgerServerTool/Forms/ListForm.cs: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * File Name: ListForm.cs 3 | * Project: Longbow 4 | * Description: This is a generic form for managing lists graphically 5 | * 6 | * Author: Bradley Newman 7 | ******************************************************************************/ 8 | 9 | namespace ReforgerServerApp 10 | { 11 | public partial class ListForm : Form 12 | { 13 | private List m_items; 14 | public ListForm(string windowTitle, string[] items) 15 | { 16 | InitializeComponent(); 17 | this.Text = $"Longbow - {windowTitle}"; 18 | m_items = new List(items); 19 | itemListView.DataSource = m_items; 20 | } 21 | 22 | private void CloseBtnClicked(object sender, EventArgs e) 23 | { 24 | Close(); 25 | } 26 | 27 | private void AddBtnClicked(object sender, EventArgs e) 28 | { 29 | if (itemTB.Text != string.Empty) 30 | { 31 | m_items.Add(itemTB.Text); 32 | itemTB.Text = string.Empty; 33 | } 34 | 35 | itemListView.RefreshItems(); 36 | } 37 | 38 | private void RemoveBtnClicked(object sender, EventArgs e) 39 | { 40 | if (itemListView.SelectedItems.Count > 0 && itemListView.SelectedItems[0] != null) 41 | { 42 | m_items.Remove(itemListView.Text); 43 | } 44 | 45 | itemListView.RefreshItems(); 46 | } 47 | 48 | public string[] GetItems() { return m_items.ToArray(); } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /ArmaReforgerServerTool/Components/AdvancedServerParameterTime.cs: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * File Name: AdvancedServerParameterTime.cs 3 | * Project: Longbow 4 | * Description: The AdvancedServerParameterTime component represents a 5 | * graphical means to manage numeric server launch 6 | * arguments 7 | * 8 | * Author: Bradley Newman 9 | ******************************************************************************/ 10 | 11 | using static System.Windows.Forms.DataFormats; 12 | 13 | namespace ReforgerServerApp.Components 14 | { 15 | public partial class AdvancedServerParameterTime : AdvancedServerParameter 16 | { 17 | public AdvancedServerParameterTime() 18 | { 19 | InitializeComponent(); 20 | m_underlyingControl = parameterValue; 21 | SetFieldEnabled(Checked()); 22 | } 23 | 24 | public override object ParameterValue 25 | { 26 | get => parameterValue.Value; 27 | set => parameterValue.Value = Convert.ToDateTime(value); 28 | } 29 | 30 | public DateTime ParameterMin 31 | { 32 | get => parameterValue.MinDate; 33 | set => parameterValue.MinDate = value; 34 | } 35 | 36 | public DateTime ParameterMax 37 | { 38 | get => parameterValue.MaxDate; 39 | set => parameterValue.MaxDate = value; 40 | } 41 | 42 | public override void OnCheckChanged(object sender, EventArgs e) 43 | { 44 | if (CheckBox.Enabled) 45 | { 46 | SetFieldEnabled(Checked()); 47 | } 48 | else 49 | { 50 | SetFieldEnabled(false); 51 | } 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /ArmaReforgerServerTool/Components/AdvancedServerParameterBool.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace ReforgerServerApp.Components 2 | { 3 | partial class AdvancedServerParameterBool 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Component Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | SuspendLayout(); 32 | // 33 | // description 34 | // 35 | description.Location = new Point(4, 30); 36 | // 37 | // AdvancedServerParameterBool 38 | // 39 | AutoScaleDimensions = new SizeF(7F, 15F); 40 | MaximumSize = new Size(200, 80); 41 | MinimumSize = new Size(200, 80); 42 | Name = "AdvancedServerParameterBool"; 43 | Size = new Size(200, 80); 44 | ResumeLayout(false); 45 | PerformLayout(); 46 | } 47 | 48 | #endregion 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /ArmaReforgerServerTool/Components/ServerParameter.cs: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * File Name: ServerParameter.cs 3 | * Project: Longbow 4 | * Description: Represents the base class for the ServerParameter components, 5 | * providing the generalisation for concrete implementations 6 | * 7 | * Author: Bradley Newman 8 | ******************************************************************************/ 9 | 10 | namespace ReforgerServerApp 11 | 12 | { 13 | public partial class ServerParameter : UserControl 14 | { 15 | private string parameterProperName = string.Empty; 16 | protected Control underlyingControl; 17 | private ToolTip toolTip; 18 | 19 | public ServerParameter() 20 | { 21 | InitializeComponent(); 22 | toolTip = new(); 23 | } 24 | 25 | public virtual object ParameterValue 26 | { 27 | get { throw new Exception("This method must be overridden"); } 28 | set { throw new Exception("This method must be overridden"); } 29 | } 30 | 31 | public string ParameterName 32 | { 33 | get => parameterProperName; 34 | set => parameterProperName = value; 35 | } 36 | 37 | public string ParameterFriendlyName 38 | { 39 | get => parameterName.Text; 40 | set => parameterName.Text = value; 41 | } 42 | 43 | public Control UnderlyingType 44 | { 45 | get => underlyingControl; 46 | } 47 | 48 | public string ParameterTooltip 49 | { 50 | set { toolTip.SetToolTip(parameterName, value); toolTip.SetToolTip(underlyingControl, value); } 51 | } 52 | 53 | public void SetFieldEnabled(bool fieldEnabled) 54 | { 55 | underlyingControl.Enabled = fieldEnabled; 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /ArmaReforgerServerTool/Program.cs: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * File Name: Program.cs 3 | * Project: Longbow 4 | * Description: Entry point for the application 5 | * 6 | * Author: Bradley Newman 7 | ******************************************************************************/ 8 | 9 | using ReforgerServerApp.Managers; 10 | using ReforgerServerApp.Models; 11 | using ReforgerServerApp.Utils; 12 | using Serilog; 13 | 14 | namespace ReforgerServerApp 15 | { 16 | internal static class Program 17 | { 18 | /// 19 | /// The main entry point for the application. 20 | /// 21 | [STAThread] 22 | static void Main() 23 | { 24 | try 25 | { 26 | Log.Logger = ToolProperties.SetMinimumLogLevel(ToolPropertiesManager.GetInstance().GetToolProperties().minimumLogLevel) 27 | .WriteTo.Console() 28 | .WriteTo.File(ToolPropertiesManager.GetInstance().GetToolProperties().logFile, rollingInterval: RollingInterval.Day) 29 | .CreateLogger(); 30 | } 31 | catch (Exception ex) 32 | { 33 | Utilities.DisplayErrorMessage("Failed to configure logger.", $"Logger configuration failed which prevented the program from launching.\n{ex.Message}"); 34 | Application.Exit(); // We cannot continue, exit gracefully 35 | return; 36 | } 37 | 38 | try 39 | { 40 | Log.Information("Longbow starting..."); 41 | ApplicationConfiguration.Initialize(); 42 | Application.Run(new Main()); 43 | } 44 | catch (Exception ex) 45 | { 46 | Utilities.DisplayErrorMessage("Application failed.", $"An uncaught exception occurred.\n\n" + 47 | $"\"{ex.Message}\""); 48 | Log.Fatal(ex, "Application failed."); 49 | } 50 | finally 51 | { 52 | Log.CloseAndFlush(); 53 | } 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 |

4 | 5 | ## Features 6 | 7 | Create Arma Reforger Dedicated Servers on Windows with this easy to use GUI tool! 8 | 9 | - Load and Save server configuration files 10 | - Automatically schedule your server to restart at a specified time of day 11 | - Powerful mod management with the ability to import mods from saved configurations 12 | - Manage server saves with ease with a powerful _Save Manager_ tool 13 | - Import and Export mod lists to share with your mates! 14 | - Easily select the desired scenario you want to play 15 | - Automatically fetches Scenario IDs for your mods from the Arma Workshop 16 | - Monitors your server and automatically restarts it if it crashes 17 | 18 | ## Requirements 19 | 20 | - [dotNET 8 Runtime](https://dotnet.microsoft.com/en-us/download) 21 | - Any dependencies for the Arma Reforger Dedicated Server (namely Microsoft Visual C++ Runtime) 22 | 23 | ### Developer Dependencies 24 | 25 | If you are contributing to the project, you will also need the following: 26 | 27 | - NSIS (to build the installer) 28 | - Visual Studio 2022 29 | 30 | ## Screenshots 31 | 32 | ![Screenshot](https://github.com/soda3x/ArmaReforgerServerTool/raw/main/docs/servertoolscreen.png) 33 | 34 | ![Screenshot](https://github.com/soda3x/ArmaReforgerServerTool/raw/main/docs/servertoolscreen2.png) 35 | 36 | ![Screenshot](https://github.com/soda3x/ArmaReforgerServerTool/raw/main/docs/servertoolscreen3.png) 37 | 38 | ## Server Parameters 39 | 40 | See [here](docs/PARAMETERS.md) for more information on the parameters in the app. 41 | 42 | ## Building 43 | 44 | - Build using Visual Studio 2022 (be sure to make `Release`) 45 | 46 | - Run `MakeNSISW` and compile the installer script in `scripts/` to make the installer 47 | 48 | ## Discord 49 | 50 | Come discuss with fellow users, seek help etc. on the Discord server [here](https://discord.gg/BPZmmqAvvu) 51 | -------------------------------------------------------------------------------- /ArmaReforgerServerTool/Components/AdvancedServerParameterEnumerated.cs: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * File Name: AdvancedServerParameterEnumerated.cs 3 | * Project: Longbow 4 | * Description: The AdvancedServerParameterEnumerated component represents a 5 | * graphical means to manage enumerated server launch 6 | * arguments 7 | * 8 | * Author: Bradley Newman 9 | ******************************************************************************/ 10 | 11 | namespace ReforgerServerApp.Components 12 | { 13 | public partial class AdvancedServerParameterEnumerated : AdvancedServerParameter 14 | { 15 | public AdvancedServerParameterEnumerated() 16 | { 17 | InitializeComponent(); 18 | m_underlyingControl = parameterValue; 19 | SetFieldEnabled(Checked()); 20 | } 21 | 22 | public override object ParameterValue 23 | { 24 | get => parameterValue; 25 | set => parameterValue = (ComboBox) value; 26 | } 27 | 28 | public List ParameterAvailableValues 29 | { 30 | get => parameterValue.Items.Cast().ToList(); 31 | set 32 | { 33 | // Clear any previous values 34 | parameterValue.Items.Clear(); 35 | foreach (string s in value) 36 | { 37 | parameterValue.Items.Add(s); 38 | } 39 | // Set default to the first item in the collection 40 | parameterValue.SelectedIndex = 0; 41 | } 42 | 43 | } 44 | 45 | public string SelectedItem 46 | { 47 | get => (string) parameterValue.SelectedItem; // Safe to cast to string as we only allow string values 48 | } 49 | 50 | public override void OnCheckChanged(object sender, EventArgs e) 51 | { 52 | if (CheckBox.Enabled) 53 | { 54 | SetFieldEnabled(Checked()); 55 | } 56 | else 57 | { 58 | SetFieldEnabled(false); 59 | } 60 | 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /ArmaReforgerServerTool/Components/AdvancedServerParameterString.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace ReforgerServerApp.Components 2 | { 3 | partial class AdvancedServerParameterString 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Component Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | parameterValue = new TextBox(); 32 | SuspendLayout(); 33 | // 34 | // parameterValue 35 | // 36 | parameterValue.Location = new Point(4, 28); 37 | parameterValue.Name = "parameterValue"; 38 | parameterValue.Size = new Size(191, 23); 39 | parameterValue.TabIndex = 2; 40 | // 41 | // AdvancedServerParameterString 42 | // 43 | AutoScaleDimensions = new SizeF(7F, 15F); 44 | AutoScaleMode = AutoScaleMode.Font; 45 | Controls.Add(parameterValue); 46 | Name = "AdvancedServerParameterString"; 47 | Controls.SetChildIndex(parameterValue, 0); 48 | ResumeLayout(false); 49 | PerformLayout(); 50 | } 51 | 52 | #endregion 53 | 54 | private TextBox parameterValue; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /ArmaReforgerServerTool/Components/AdvancedServerParameterEnumerated.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace ReforgerServerApp.Components 2 | { 3 | partial class AdvancedServerParameterEnumerated 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Component Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | parameterValue = new ComboBox(); 32 | SuspendLayout(); 33 | // 34 | // parameterValue 35 | // 36 | parameterValue.Location = new Point(4, 28); 37 | parameterValue.Name = "parameterValue"; 38 | parameterValue.Size = new Size(191, 23); 39 | parameterValue.TabIndex = 2; 40 | // 41 | // AdvancedServerParameterString 42 | // 43 | AutoScaleDimensions = new SizeF(7F, 15F); 44 | AutoScaleMode = AutoScaleMode.Font; 45 | Controls.Add(parameterValue); 46 | Name = "AdvancedServerParameterString"; 47 | Controls.SetChildIndex(parameterValue, 0); 48 | ResumeLayout(false); 49 | PerformLayout(); 50 | } 51 | 52 | #endregion 53 | 54 | private ComboBox parameterValue; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /ArmaReforgerServerTool/Models/AdvancedSetting.cs: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * File Name: AdvancedSetting.cs 3 | * Project: Longbow 4 | * Description: This file contains the AdvancedSetting class which is a model 5 | * representing the saved / loaded state of an advanced setting 6 | * 7 | * Author: Bradley Newman 8 | ******************************************************************************/ 9 | 10 | using System.Text.Json.Serialization; 11 | using static ReforgerServerApp.Utils.JsonUtils; 12 | 13 | namespace Longbow.Models 14 | { 15 | [JsonConverter(typeof(AdvancedSettingConverter))] 16 | internal class AdvancedSetting 17 | { 18 | public string Name { get; set; } 19 | 20 | public object Value { get; set; } 21 | public bool Enabled { get; set; } 22 | 23 | public AdvancedSetting() 24 | { 25 | // Used for JSON deserialising 26 | } 27 | 28 | /// 29 | /// Constructs and advanced setting 30 | /// 31 | /// 32 | /// 33 | /// 34 | public AdvancedSetting(string name, object value, bool enabled) 35 | { 36 | Name = name; 37 | Value = value; 38 | Enabled = enabled; 39 | } 40 | 41 | /// 42 | /// Constructs a switch style (i.e. no value) advanced setting 43 | /// 44 | /// 45 | /// 46 | public AdvancedSetting(string name, bool enabled) 47 | { 48 | Name = name; 49 | Value = "switch"; 50 | Enabled = enabled; 51 | } 52 | 53 | /// 54 | /// The string literal switch is a reserved word for being 55 | /// a switch-type advanced setting 56 | /// 57 | /// True if advanced setting is to be treated as a switch, 58 | /// False if advanced setting has a real value 59 | public bool IsSwitch() 60 | { 61 | return Value.Equals("switch"); 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /ArmaReforgerServerTool/Components/AdvancedServerParameterTime.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace ReforgerServerApp.Components 2 | { 3 | partial class AdvancedServerParameterTime 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Component Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | parameterValue = new DateTimePicker(); 32 | SuspendLayout(); 33 | // 34 | // parameterValue 35 | // 36 | parameterValue.Location = new Point(4, 28); 37 | parameterValue.Name = "parameterValue"; 38 | parameterValue.Size = new Size(191, 23); 39 | parameterValue.TabIndex = 2; 40 | parameterValue.Format = DateTimePickerFormat.Custom; 41 | parameterValue.CustomFormat = "HH:mm"; 42 | parameterValue.ShowUpDown = true; 43 | // 44 | // AdvancedServerParameterTime 45 | // 46 | AutoScaleDimensions = new SizeF(7F, 15F); 47 | AutoScaleMode = AutoScaleMode.Font; 48 | Controls.Add(parameterValue); 49 | Name = "AdvancedServerParameterTime"; 50 | Controls.SetChildIndex(parameterValue, 0); 51 | ResumeLayout(false); 52 | PerformLayout(); 53 | } 54 | 55 | #endregion 56 | 57 | private DateTimePicker parameterValue; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /ArmaReforgerServerTool/Components/AdvancedServerParameterNumeric.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace ReforgerServerApp.Components 2 | { 3 | partial class AdvancedServerParameterNumeric 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Component Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | parameterValue = new NumericUpDown(); 32 | ((System.ComponentModel.ISupportInitialize) parameterValue).BeginInit(); 33 | SuspendLayout(); 34 | // 35 | // parameterValue 36 | // 37 | parameterValue.Location = new Point(4, 28); 38 | parameterValue.Name = "parameterValue"; 39 | parameterValue.Size = new Size(191, 23); 40 | parameterValue.TabIndex = 2; 41 | parameterValue.ValueChanged += OnValueChanged; 42 | // 43 | // AdvancedServerParameterNumeric 44 | // 45 | AutoScaleDimensions = new SizeF(7F, 15F); 46 | AutoScaleMode = AutoScaleMode.Font; 47 | Controls.Add(parameterValue); 48 | Name = "AdvancedServerParameterNumeric"; 49 | Controls.SetChildIndex(parameterValue, 0); 50 | ((System.ComponentModel.ISupportInitialize) parameterValue).EndInit(); 51 | ResumeLayout(false); 52 | PerformLayout(); 53 | } 54 | 55 | #endregion 56 | 57 | private NumericUpDown parameterValue; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /ArmaReforgerServerTool/Components/ServerParameter.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace ReforgerServerApp 2 | { 3 | partial class ServerParameter 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Component Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | parameterName = new Label(); 32 | SuspendLayout(); 33 | // 34 | // parameterName 35 | // 36 | parameterName.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left; 37 | parameterName.AutoSize = true; 38 | parameterName.Font = new Font("Segoe UI Semibold", 12F, FontStyle.Bold, GraphicsUnit.Point); 39 | parameterName.Location = new Point(15, 4); 40 | parameterName.Name = "parameterName"; 41 | parameterName.Size = new Size(132, 21); 42 | parameterName.TabIndex = 0; 43 | parameterName.Text = ""; 44 | parameterName.TextAlign = ContentAlignment.MiddleLeft; 45 | // 46 | // ServerParameter 47 | // 48 | AutoScaleDimensions = new SizeF(7F, 15F); 49 | AutoScaleMode = AutoScaleMode.Font; 50 | Controls.Add(parameterName); 51 | Name = "ServerParameter"; 52 | Size = new Size(400, 30); 53 | ResumeLayout(false); 54 | PerformLayout(); 55 | } 56 | 57 | #endregion 58 | 59 | private Label parameterName; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /ArmaReforgerServerTool/Components/AdvancedServerParameterNumeric.cs: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * File Name: AdvancedServerParameterNumeric.cs 3 | * Project: Longbow 4 | * Description: The AdvancedServerParameterNumeric component represents a 5 | * graphical means to manage numeric server launch 6 | * arguments 7 | * 8 | * Author: Bradley Newman 9 | ******************************************************************************/ 10 | 11 | using static System.Windows.Forms.DataFormats; 12 | 13 | namespace ReforgerServerApp.Components 14 | { 15 | public partial class AdvancedServerParameterNumeric : AdvancedServerParameter 16 | { 17 | public AdvancedServerParameterNumeric() 18 | { 19 | InitializeComponent(); 20 | m_underlyingControl = parameterValue; 21 | SetFieldEnabled(Checked()); 22 | } 23 | 24 | public override object ParameterValue 25 | { 26 | get => parameterValue.Value; 27 | set => parameterValue.Value = (Int32)value; 28 | } 29 | 30 | public decimal ParameterMin 31 | { 32 | get => parameterValue.Minimum; 33 | set => parameterValue.Minimum = value; 34 | } 35 | 36 | public decimal ParameterMax 37 | { 38 | get => parameterValue.Maximum; 39 | set => parameterValue.Maximum = value; 40 | } 41 | 42 | public decimal ParameterIncrement 43 | { 44 | get => parameterValue.Increment; 45 | set => parameterValue.Increment = value; 46 | } 47 | 48 | private int m_parameterPadding; 49 | public int ParameterPadding 50 | { 51 | get => m_parameterPadding; 52 | set 53 | { 54 | m_parameterPadding = value; 55 | string format = $"D{ParameterPadding}"; 56 | parameterValue.Text = Convert.ToInt32(parameterValue.Value).ToString(format); 57 | } 58 | } 59 | 60 | public override void OnCheckChanged(object sender, EventArgs e) 61 | { 62 | if (CheckBox.Enabled) 63 | { 64 | SetFieldEnabled(Checked()); 65 | } 66 | else 67 | { 68 | SetFieldEnabled(false); 69 | } 70 | } 71 | 72 | private void OnValueChanged(object sender, EventArgs e) 73 | { 74 | string format = $"D{ParameterPadding}"; 75 | parameterValue.Text = Convert.ToInt32(parameterValue.Value).ToString(format); 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /ArmaReforgerServerTool/Forms/TextInputForm.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace ReforgerServerApp 2 | { 3 | partial class TextInputForm 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | textInputField = new TextBox(); 32 | okBtn = new Button(); 33 | SuspendLayout(); 34 | // 35 | // textInputField 36 | // 37 | textInputField.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; 38 | textInputField.Location = new Point(12, 12); 39 | textInputField.Multiline = true; 40 | textInputField.Name = "textInputField"; 41 | textInputField.Size = new Size(600, 390); 42 | textInputField.TabIndex = 0; 43 | // 44 | // okBtn 45 | // 46 | okBtn.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; 47 | okBtn.Location = new Point(537, 408); 48 | okBtn.Name = "okBtn"; 49 | okBtn.Size = new Size(75, 23); 50 | okBtn.TabIndex = 1; 51 | okBtn.Text = "OK"; 52 | okBtn.UseVisualStyleBackColor = true; 53 | okBtn.Click += OkBtnClicked; 54 | // 55 | // TextInputForm 56 | // 57 | AutoScaleDimensions = new SizeF(7F, 15F); 58 | AutoScaleMode = AutoScaleMode.Font; 59 | ClientSize = new Size(624, 441); 60 | Controls.Add(okBtn); 61 | Controls.Add(textInputField); 62 | MinimumSize = new Size(640, 480); 63 | Name = "TextInputForm"; 64 | ShowIcon = false; 65 | StartPosition = FormStartPosition.CenterParent; 66 | Text = "Longbow - Text Input Form"; 67 | ResumeLayout(false); 68 | PerformLayout(); 69 | } 70 | 71 | #endregion 72 | 73 | private TextBox textInputField; 74 | private Button okBtn; 75 | } 76 | } -------------------------------------------------------------------------------- /ArmaReforgerServerTool/Components/AdvancedServerParameter.cs: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * File Name: AdvancedServerParameter.cs 3 | * Project: Longbow 4 | * Description: Represents the base class for the AdvancedServerParameter 5 | * components, providing the generalisation for concrete 6 | * implementations 7 | * 8 | * Author: Bradley Newman 9 | ******************************************************************************/ 10 | 11 | 12 | namespace ReforgerServerApp.Components 13 | { 14 | public partial class AdvancedServerParameter : UserControl 15 | { 16 | private string m_parameterProperName; 17 | 18 | protected Control m_underlyingControl; 19 | 20 | public AdvancedServerParameter() 21 | { 22 | InitializeComponent(); 23 | m_parameterProperName = string.Empty; 24 | } 25 | 26 | public bool Checked() 27 | { 28 | return parameterEnabled.Checked; 29 | } 30 | 31 | public virtual object ParameterValue 32 | { 33 | get { throw new Exception("This method must be overridden"); } 34 | set { throw new Exception("This method must be overridden"); } 35 | } 36 | 37 | public string ParameterName 38 | { 39 | get => m_parameterProperName; 40 | set => m_parameterProperName = value; 41 | } 42 | 43 | public string ParameterFriendlyName 44 | { 45 | get => parameterEnabled.Text; 46 | set => parameterEnabled.Text = value; 47 | } 48 | 49 | public CheckBox CheckBox 50 | { 51 | get => parameterEnabled; 52 | } 53 | 54 | public Control UnderlyingType 55 | { 56 | get => m_underlyingControl; 57 | } 58 | 59 | public string Description 60 | { 61 | get => description.Text; 62 | set => description.Text = value; 63 | } 64 | 65 | /// 66 | /// Sets the checkbox component to be either enabled or disabled 67 | /// 68 | /// 69 | public void SetEnabled(bool fieldEnabled) 70 | { 71 | parameterEnabled.Enabled = fieldEnabled; 72 | OnCheckChanged(new object(), new EventArgs()); 73 | } 74 | 75 | /// 76 | /// Set only the field to be enabled or disabled, the intention 77 | /// is that toggling the checkbox will either enable or 78 | /// disable the field 79 | /// 80 | /// 81 | public void SetFieldEnabled(bool fieldEnabled) 82 | { 83 | m_underlyingControl.Enabled = fieldEnabled; 84 | } 85 | 86 | public virtual void OnCheckChanged(object sender, EventArgs e) 87 | { 88 | throw new Exception("This method must be overridden"); 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /ArmaReforgerServerTool/Components/ServerParameterSelect.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace ReforgerServerApp 2 | { 3 | partial class ServerParameterSelect 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Component Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | parameterName = new Label(); 32 | parameterValue = new ComboBox(); 33 | SuspendLayout(); 34 | // 35 | // parameterName 36 | // 37 | parameterName.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left; 38 | parameterName.AutoSize = true; 39 | parameterName.Font = new Font("Segoe UI Semibold", 12F, FontStyle.Bold, GraphicsUnit.Point); 40 | parameterName.Location = new Point(15, 4); 41 | parameterName.Name = "parameterName"; 42 | parameterName.Size = new Size(0, 21); 43 | parameterName.TabIndex = 0; 44 | parameterName.TextAlign = ContentAlignment.MiddleLeft; 45 | // 46 | // parameterValue 47 | // 48 | parameterValue.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Right; 49 | parameterValue.Location = new Point(264, 5); 50 | parameterValue.Name = "parameterValue"; 51 | parameterValue.Size = new Size(114, 23); 52 | parameterValue.TabIndex = 1; 53 | // 54 | // ServerParameterSelect 55 | // 56 | AutoScaleDimensions = new SizeF(7F, 15F); 57 | AutoScaleMode = AutoScaleMode.Font; 58 | Controls.Add(parameterValue); 59 | Controls.Add(parameterName); 60 | Name = "ServerParameterSelect"; 61 | Size = new Size(400, 30); 62 | ResumeLayout(false); 63 | PerformLayout(); 64 | } 65 | 66 | #endregion 67 | 68 | private Label parameterName; 69 | private ComboBox parameterValue; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /ArmaReforgerServerTool/Components/ServerParameterString.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace ReforgerServerApp 2 | { 3 | partial class ServerParameterString 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Component Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | parameterName = new Label(); 32 | parameterValue = new TextBox(); 33 | SuspendLayout(); 34 | // 35 | // parameterName 36 | // 37 | parameterName.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left; 38 | parameterName.AutoSize = true; 39 | parameterName.Font = new Font("Segoe UI Semibold", 12F, FontStyle.Bold, GraphicsUnit.Point); 40 | parameterName.Location = new Point(15, 4); 41 | parameterName.Name = "parameterName"; 42 | parameterName.Size = new Size(132, 21); 43 | parameterName.TabIndex = 0; 44 | parameterName.Text = ""; 45 | parameterName.TextAlign = ContentAlignment.MiddleLeft; 46 | // 47 | // parameterValue 48 | // 49 | parameterValue.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Right; 50 | parameterValue.Location = new Point(160, 5); 51 | parameterValue.Name = "parameterValue"; 52 | parameterValue.Size = new Size(216, 23); 53 | parameterValue.TabIndex = 1; 54 | // 55 | // ServerParameterString 56 | // 57 | AutoScaleDimensions = new SizeF(7F, 15F); 58 | AutoScaleMode = AutoScaleMode.Font; 59 | Controls.Add(parameterValue); 60 | Controls.Add(parameterName); 61 | Name = "ServerParameterString"; 62 | Size = new Size(400, 30); 63 | ResumeLayout(false); 64 | PerformLayout(); 65 | } 66 | 67 | #endregion 68 | 69 | private Label parameterName; 70 | private TextBox parameterValue; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /ArmaReforgerServerTool/Components/ServerParameterList.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace ReforgerServerApp 2 | { 3 | partial class ServerParameterList 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Component Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | parameterName = new Label(); 32 | parameterValue = new FontAwesome.Sharp.IconButton(); 33 | SuspendLayout(); 34 | // 35 | // parameterName 36 | // 37 | parameterName.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left; 38 | parameterName.AutoSize = true; 39 | parameterName.Font = new Font("Segoe UI Semibold", 12F, FontStyle.Bold, GraphicsUnit.Point); 40 | parameterName.Location = new Point(15, 4); 41 | parameterName.Name = "parameterName"; 42 | parameterName.Size = new Size(0, 21); 43 | parameterName.TabIndex = 0; 44 | parameterName.TextAlign = ContentAlignment.MiddleLeft; 45 | // 46 | // parameterValue 47 | // 48 | parameterValue.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Right; 49 | parameterValue.IconChar = FontAwesome.Sharp.IconChar.List; 50 | parameterValue.IconColor = Color.Black; 51 | parameterValue.IconFont = FontAwesome.Sharp.IconFont.Auto; 52 | parameterValue.IconSize = 16; 53 | parameterValue.Location = new Point(354, 4); 54 | parameterValue.Name = "parameterValue"; 55 | parameterValue.Size = new Size(24, 24); 56 | parameterValue.TabIndex = 1; 57 | parameterValue.Click += OnButtonPressed; 58 | // 59 | // ServerParameterList 60 | // 61 | AutoScaleDimensions = new SizeF(7F, 15F); 62 | AutoScaleMode = AutoScaleMode.Font; 63 | Controls.Add(parameterValue); 64 | Controls.Add(parameterName); 65 | Name = "ServerParameterList"; 66 | Controls.SetChildIndex(parameterName, 0); 67 | Controls.SetChildIndex(parameterValue, 0); 68 | ResumeLayout(false); 69 | PerformLayout(); 70 | } 71 | 72 | #endregion 73 | 74 | private Label parameterName; 75 | private FontAwesome.Sharp.IconButton parameterValue; 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /ArmaReforgerServerTool/Components/ServerParameterText.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace ReforgerServerApp 2 | { 3 | partial class ServerParameterText 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Component Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | parameterName = new Label(); 32 | parameterValue = new FontAwesome.Sharp.IconButton(); 33 | SuspendLayout(); 34 | // 35 | // parameterName 36 | // 37 | parameterName.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left; 38 | parameterName.AutoSize = true; 39 | parameterName.Font = new Font("Segoe UI Semibold", 12F, FontStyle.Bold, GraphicsUnit.Point); 40 | parameterName.Location = new Point(15, 4); 41 | parameterName.Name = "parameterName"; 42 | parameterName.Size = new Size(0, 21); 43 | parameterName.TabIndex = 0; 44 | parameterName.TextAlign = ContentAlignment.MiddleLeft; 45 | // 46 | // parameterValue 47 | // 48 | parameterValue.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Right; 49 | parameterValue.IconChar = FontAwesome.Sharp.IconChar.FileText; 50 | parameterValue.IconColor = Color.Black; 51 | parameterValue.IconFont = FontAwesome.Sharp.IconFont.Auto; 52 | parameterValue.IconSize = 16; 53 | parameterValue.Location = new Point(354, 4); 54 | parameterValue.Name = "parameterValue"; 55 | parameterValue.Size = new Size(24, 24); 56 | parameterValue.TabIndex = 1; 57 | parameterValue.Click += OnButtonPressed; 58 | // 59 | // ServerParameterText 60 | // 61 | AutoScaleDimensions = new SizeF(7F, 15F); 62 | AutoScaleMode = AutoScaleMode.Font; 63 | Controls.Add(parameterValue); 64 | Controls.Add(parameterName); 65 | Name = "ServerParameterText"; 66 | Controls.SetChildIndex(parameterName, 0); 67 | Controls.SetChildIndex(parameterValue, 0); 68 | ResumeLayout(false); 69 | PerformLayout(); 70 | } 71 | 72 | #endregion 73 | 74 | private Label parameterName; 75 | private FontAwesome.Sharp.IconButton parameterValue; 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /ArmaReforgerServerTool/Components/ServerParameterBool.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace ReforgerServerApp 2 | { 3 | partial class ServerParameterBool 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Component Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | parameterName = new Label(); 32 | parameterValue = new CheckBox(); 33 | SuspendLayout(); 34 | // 35 | // parameterName 36 | // 37 | parameterName.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left; 38 | parameterName.AutoSize = true; 39 | parameterName.Font = new Font("Segoe UI Semibold", 12F, FontStyle.Bold, GraphicsUnit.Point); 40 | parameterName.Location = new Point(15, 4); 41 | parameterName.Name = "parameterName"; 42 | parameterName.Size = new Size(132, 21); 43 | parameterName.TabIndex = 0; 44 | parameterName.Text = ""; 45 | parameterName.TextAlign = ContentAlignment.MiddleLeft; 46 | // 47 | // parameterValue 48 | // 49 | parameterValue.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Right; 50 | parameterValue.AutoSize = true; 51 | parameterValue.Location = new Point(364, 10); 52 | parameterValue.Name = "parameterValue"; 53 | parameterValue.Size = new Size(15, 14); 54 | parameterValue.TabIndex = 1; 55 | parameterValue.UseVisualStyleBackColor = true; 56 | parameterValue.CheckedChanged += OnCheckChanged; 57 | // 58 | // ServerParameterBool 59 | // 60 | AutoScaleDimensions = new SizeF(7F, 15F); 61 | AutoScaleMode = AutoScaleMode.Font; 62 | Controls.Add(parameterValue); 63 | Controls.Add(parameterName); 64 | Name = "ServerParameterBool"; 65 | Size = new Size(400, 30); 66 | ResumeLayout(false); 67 | PerformLayout(); 68 | } 69 | 70 | #endregion 71 | 72 | private Label parameterName; 73 | private CheckBox parameterValue; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /ArmaReforgerServerTool/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace Longbow.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// Returns the cached ResourceManager instance used by this class. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Longbow.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Overrides the current thread's CurrentUICulture property for all 51 | /// resource lookups using this strongly typed resource class. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /ArmaReforgerServerTool/Components/AdvancedServerParameterSchedule.cs: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * File Name: AdvancedServerParameterSchedule.cs 3 | * Project: Longbow 4 | * Description: The AdvancedServerParameterSchedule component represents a 5 | * graphical means to manage time intervals 6 | * 7 | * Author: Bradley Newman 8 | ******************************************************************************/ 9 | 10 | using Serilog; 11 | 12 | namespace ReforgerServerApp.Components 13 | { 14 | public partial class AdvancedServerParameterSchedule : AdvancedServerParameter 15 | { 16 | public AdvancedServerParameterSchedule() 17 | { 18 | InitializeComponent(); 19 | m_underlyingControl = parameterValue; 20 | SetFieldEnabled(Checked()); 21 | } 22 | 23 | public override object ParameterValue 24 | { 25 | get => parameterValue.Value; 26 | set => parameterValue.Value = Convert.ToInt32(value); 27 | } 28 | 29 | public decimal ParameterMin 30 | { 31 | get => parameterValue.Minimum; 32 | set => parameterValue.Minimum = value; 33 | } 34 | 35 | public decimal ParameterMax 36 | { 37 | get => parameterValue.Maximum; 38 | set => parameterValue.Maximum = value; 39 | } 40 | 41 | public decimal ParameterIncrement 42 | { 43 | get => parameterValue.Increment; 44 | set => parameterValue.Increment = value; 45 | } 46 | 47 | public string CurrentItem 48 | { 49 | get => timeUnit.Text; 50 | } 51 | 52 | public int CurrentIndex 53 | { 54 | get => timeUnit.SelectedIndex; 55 | } 56 | 57 | public string[] Items 58 | { 59 | get 60 | { 61 | string[] items = new string[] { }; 62 | foreach (object o in timeUnit.Items) 63 | { 64 | _ = items.Append(o as string); 65 | } 66 | return items; 67 | } 68 | set 69 | { 70 | timeUnit.Items.Clear(); 71 | timeUnit.Items.AddRange(value); 72 | timeUnit.SelectedIndex = 0; 73 | } 74 | } 75 | 76 | public override void OnCheckChanged(object sender, EventArgs e) 77 | { 78 | if (CheckBox.Enabled) 79 | { 80 | SetFieldEnabled(Checked()); 81 | } 82 | else 83 | { 84 | SetFieldEnabled(false); 85 | } 86 | } 87 | 88 | /// 89 | /// Because the Schedule advanced server parameter basically 90 | /// has two underlying controls, it has to be treated differently. 91 | /// 92 | /// This method will set both the value and units fields to be either 93 | /// enabled or disabled 94 | /// 95 | /// 96 | public new void SetFieldEnabled(bool enabled) 97 | { 98 | m_underlyingControl.Enabled = enabled; 99 | timeUnit.Enabled = enabled; 100 | } 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /ArmaReforgerServerTool/Components/ServerParameterNumeric.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace ReforgerServerApp 2 | { 3 | partial class ServerParameterNumeric 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Component Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | parameterName = new Label(); 32 | parameterValue = new NumericUpDown(); 33 | ((System.ComponentModel.ISupportInitialize)parameterValue).BeginInit(); 34 | SuspendLayout(); 35 | // 36 | // parameterName 37 | // 38 | parameterName.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left; 39 | parameterName.AutoSize = true; 40 | parameterName.Font = new Font("Segoe UI Semibold", 12F, FontStyle.Bold, GraphicsUnit.Point); 41 | parameterName.Location = new Point(15, 4); 42 | parameterName.Name = "parameterName"; 43 | parameterName.Size = new Size(132, 21); 44 | parameterName.TabIndex = 0; 45 | parameterName.Text = ""; 46 | parameterName.TextAlign = ContentAlignment.MiddleLeft; 47 | // 48 | // parameterValue 49 | // 50 | parameterValue.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Right; 51 | parameterValue.Location = new Point(264, 4); 52 | parameterValue.Name = "parameterValue"; 53 | parameterValue.Size = new Size(114, 23); 54 | parameterValue.TabIndex = 1; 55 | // 56 | // ServerParameterNumeric 57 | // 58 | AutoScaleDimensions = new SizeF(7F, 15F); 59 | AutoScaleMode = AutoScaleMode.Font; 60 | Controls.Add(parameterValue); 61 | Controls.Add(parameterName); 62 | Name = "ServerParameterNumeric"; 63 | Size = new Size(400, 30); 64 | ((System.ComponentModel.ISupportInitialize)parameterValue).EndInit(); 65 | ResumeLayout(false); 66 | PerformLayout(); 67 | } 68 | 69 | #endregion 70 | 71 | private Label parameterName; 72 | private NumericUpDown parameterValue; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /ArmaReforgerServerTool/Longbow.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0-windows 5 | enable 6 | true 7 | enable 8 | False 9 | soda3x 10 | 1.1.0 11 | 1.1.0 12 | Resources\arma_icon_white.ico 13 | true 14 | winexe 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | UserControl 34 | 35 | 36 | UserControl 37 | 38 | 39 | UserControl 40 | 41 | 42 | UserControl 43 | 44 | 45 | UserControl 46 | 47 | 48 | 49 | 50 | True 51 | True 52 | Resources.resx 53 | 54 | 55 | 56 | 57 | 58 | Form 59 | 60 | 61 | 62 | 63 | 64 | ResXFileCodeGenerator 65 | Resources.Designer.cs 66 | 67 | 68 | 69 | 70 | 71 | Always 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /ArmaReforgerServerTool/Managers/SavedStateManager.cs: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * File Name: SavedStateManager.cs 3 | * Project: Longbow 4 | * Description: This file contains the singleton SavedStateManager class 5 | * responsible for keeping track of changes made to the state 6 | * of the application for survival across restarts 7 | * 8 | * Author: Bradley Newman 9 | ******************************************************************************/ 10 | 11 | using Longbow.Models; 12 | using ReforgerServerApp.Utils; 13 | using Serilog; 14 | using System.Text.Json; 15 | 16 | namespace Longbow.Managers 17 | { 18 | internal class SavedStateManager 19 | { 20 | private static SavedStateManager? m_instance; 21 | private readonly SavedState m_savedState; 22 | private readonly string m_savedStateFile = "./state.json"; 23 | 24 | /// 25 | /// Constructs a SavedStateManager object. Intended to only be used within the singleton GetInstance() method. 26 | /// This will check for the state files existence and if its found, loads it, otherwise creates a new default one. 27 | /// Usually the FileIOManager would handle this kind of task but it's a bit of a chicken-egg situation so the SavedStateManager 28 | /// can handle the loading of it's own file. 29 | /// 30 | private SavedStateManager() 31 | { 32 | if (File.Exists(m_savedStateFile)) 33 | { 34 | try 35 | { 36 | using StreamReader sr = File.OpenText(m_savedStateFile); 37 | var savedState = sr.ReadToEnd(); 38 | m_savedState = JsonSerializer.Deserialize(savedState)!; 39 | Log.Information("SavedStateManager - successfully loaded state file."); 40 | } 41 | catch (Exception) 42 | { 43 | string path = Path.GetFullPath(m_savedStateFile); 44 | 45 | Utilities.DisplayErrorMessage( 46 | "State file is malformed. Please check your formatting is valid JSON and try again.", 47 | "Unable to parse state file. Temporarily using default state. " + 48 | $"Delete the state file at {path} and restart the application to permanently revert to default settings." 49 | ); 50 | m_savedState = SavedState.Default; 51 | } 52 | } 53 | else 54 | { 55 | Log.Information("SavedStateManager - State file was not found, a default one was created."); 56 | m_savedState = SavedState.Default; 57 | File.WriteAllText(m_savedStateFile, m_savedState.AsJsonString()); 58 | } 59 | } 60 | 61 | public static SavedStateManager GetInstance() 62 | { 63 | m_instance ??= new SavedStateManager(); 64 | return m_instance; 65 | } 66 | 67 | public Dictionary GetLoadedAdvancedSettings() { return m_savedState.advancedSettings; } 68 | public string GetSavedStateFile() { return m_savedStateFile; } 69 | public SavedState GetSavedState() { return m_savedState; } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /ArmaReforgerServerTool/Forms/AboutBox.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace ReforgerServerApp 2 | { 3 | partial class AboutBox 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | aboutText = new Label(); 32 | okBtn = new Button(); 33 | reportBtn = new Button(); 34 | SuspendLayout(); 35 | // 36 | // aboutText 37 | // 38 | aboutText.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; 39 | aboutText.AutoSize = true; 40 | aboutText.Font = new Font("Segoe UI Semibold", 8F, FontStyle.Bold); 41 | aboutText.Location = new Point(12, 9); 42 | aboutText.Name = "aboutText"; 43 | aboutText.Size = new Size(61, 13); 44 | aboutText.TabIndex = 0; 45 | aboutText.Text = "About text"; 46 | // 47 | // okBtn 48 | // 49 | okBtn.Location = new Point(347, 106); 50 | okBtn.Name = "okBtn"; 51 | okBtn.Size = new Size(75, 23); 52 | okBtn.TabIndex = 1; 53 | okBtn.Text = "OK"; 54 | okBtn.UseVisualStyleBackColor = true; 55 | okBtn.Click += OKBtnPressed; 56 | // 57 | // reportBtn 58 | // 59 | reportBtn.Location = new Point(12, 106); 60 | reportBtn.Name = "reportBtn"; 61 | reportBtn.Size = new Size(113, 23); 62 | reportBtn.TabIndex = 2; 63 | reportBtn.Text = "Report an Issue..."; 64 | reportBtn.UseVisualStyleBackColor = true; 65 | reportBtn.Click += ReportBtnPressed; 66 | // 67 | // AboutBox 68 | // 69 | AutoScaleDimensions = new SizeF(7F, 15F); 70 | AutoScaleMode = AutoScaleMode.Font; 71 | ClientSize = new Size(434, 141); 72 | Controls.Add(reportBtn); 73 | Controls.Add(okBtn); 74 | Controls.Add(aboutText); 75 | MaximizeBox = false; 76 | MaximumSize = new Size(450, 180); 77 | MinimizeBox = false; 78 | MinimumSize = new Size(450, 180); 79 | Name = "AboutBox"; 80 | ShowIcon = false; 81 | StartPosition = FormStartPosition.CenterParent; 82 | Text = "Longbow - About"; 83 | ResumeLayout(false); 84 | PerformLayout(); 85 | } 86 | 87 | #endregion 88 | 89 | private Label aboutText; 90 | private Button okBtn; 91 | private Button reportBtn; 92 | } 93 | } -------------------------------------------------------------------------------- /ArmaReforgerServerTool/Managers/ToolPropertiesManager.cs: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * File Name: ToolPropertiesManager.cs 3 | * Project: Longbow 4 | * Description: This file contains the singleton ToolPropertiesManager class 5 | * responsible for the retrieval and management of the server 6 | * tool properties. 7 | * 8 | * Authors: Kye Seyhun 9 | ******************************************************************************/ 10 | 11 | using System.Text.Json; 12 | using Serilog; 13 | using ReforgerServerApp.Models; 14 | using ReforgerServerApp.Utils; 15 | using Longbow.Models; 16 | 17 | namespace ReforgerServerApp.Managers; 18 | 19 | /// 20 | /// This class manages the application's ToolProperties 21 | /// 22 | internal class ToolPropertiesManager 23 | { 24 | private static ToolPropertiesManager? m_instance; 25 | private readonly ToolProperties m_toolProperties; 26 | private readonly string m_toolPropertiesFile = "./properties.json"; 27 | 28 | /// 29 | /// Constructs a ToolPropertiesManager object. Intended to only be used within the singleton GetInstance() method. 30 | /// This will check for the properties files existence and if its found, loads it, otherwise creates a new default one. 31 | /// Usually the FileIOManager would handle this kind of task but it's a bit of a chicken-egg situation so the ToolPropertiesManager 32 | /// can handle the loading of it's own file. 33 | /// 34 | private ToolPropertiesManager() 35 | { 36 | if (File.Exists(m_toolPropertiesFile)) 37 | { 38 | try 39 | { 40 | using StreamReader sr = File.OpenText(m_toolPropertiesFile); 41 | var toolProperties = sr.ReadToEnd(); 42 | m_toolProperties = JsonSerializer.Deserialize(toolProperties)!; 43 | Log.Information("ToolPropertiesManager - successfully loaded properties file."); 44 | } 45 | catch (Exception) 46 | { 47 | string path = Path.GetFullPath(m_toolPropertiesFile); 48 | 49 | Utilities.DisplayErrorMessage( 50 | "Properties is malformed. Please check your formatting is valid JSON and try again.", 51 | "Unable to parse properties. Temporarily loading default settings. " + 52 | $"Delete the properties file at {path} and restart the application to permanently revert to default settings." 53 | ); 54 | m_toolProperties = ToolProperties.Default; 55 | } 56 | } 57 | else 58 | { 59 | Log.Information("ToolPropertiesManager - Properties file was not found, a default one was created."); 60 | m_toolProperties = ToolProperties.Default; 61 | File.WriteAllText(m_toolPropertiesFile, m_toolProperties.AsJsonString()); 62 | } 63 | } 64 | 65 | public static ToolPropertiesManager GetInstance() 66 | { 67 | m_instance ??= new ToolPropertiesManager(); 68 | return m_instance; 69 | } 70 | 71 | public List GetDefaultScenarios() { return m_toolProperties.defaultScenarios; } 72 | public ToolProperties GetToolProperties() { return m_toolProperties; } 73 | } 74 | -------------------------------------------------------------------------------- /ArmaReforgerServerTool/Forms/AddModDialog.cs: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * File Name: AddModDialog.cs 3 | * Project: Longbow 4 | * Description: This is the Add Mod Dialog Form 5 | * 6 | * Author: Bradley Newman 7 | ******************************************************************************/ 8 | 9 | using ReforgerServerApp.Managers; 10 | 11 | namespace ReforgerServerApp 12 | { 13 | public partial class AddModDialog : Form 14 | { 15 | private readonly Main m_reforgerApp; 16 | private readonly bool m_isEditMode = false; 17 | private readonly int m_idx = -1; 18 | public AddModDialog(Main reforgerApp) 19 | { 20 | InitializeComponent(); 21 | this.Text = "Longbow - Add Mod"; 22 | m_reforgerApp = reforgerApp; 23 | CreateTooltips(); 24 | } 25 | 26 | public AddModDialog(Main reforgerApp, Mod m, int idx) 27 | { 28 | InitializeComponent(); 29 | this.Text = "Longbow - Edit Mod"; 30 | m_reforgerApp = reforgerApp; 31 | modId.Text = m.GetModID(); 32 | modName.Text = m.GetModName(); 33 | modVers.Text = m.GetModVersion().Equals("latest") ? "" : m.GetModVersion(); 34 | required.Checked = m.IsModRequired(); 35 | addBtn.Text = "Edit"; 36 | m_isEditMode = true; 37 | m_idx = idx; 38 | CreateTooltips(); 39 | } 40 | 41 | private void CreateTooltips() 42 | { 43 | ToolTip requiredTooltip = new(); 44 | requiredTooltip.SetToolTip(requiredLabel, "Setting this will make it so that when this mod cannot be downloaded from the Workshop, the server will not start."); 45 | } 46 | 47 | /// 48 | /// Handler for the Close Button. 49 | /// Closes the Add Mod Dialog. 50 | /// 51 | /// 52 | /// 53 | private void CancelBtnPressed(object sender, EventArgs e) 54 | { 55 | Close(); 56 | } 57 | 58 | /// 59 | /// Handler for the Add Mod Button. 60 | /// Adds the mod to the Available Mods ListBox. 61 | /// 62 | /// 63 | /// 64 | private void AddBtnPressed(object sender, EventArgs e) 65 | { 66 | if (!string.IsNullOrWhiteSpace(modId.Text.Trim()) && !string.IsNullOrWhiteSpace(modName.Text.Trim())) 67 | { 68 | Mod mod; 69 | 70 | if (!string.IsNullOrWhiteSpace(modVers.Text.Trim())) 71 | { 72 | mod = new(modId.Text.Trim(), modName.Text.Trim(), modVers.Text.Trim(), required.Checked); 73 | } 74 | else 75 | { 76 | mod = new(modId.Text.Trim(), modName.Text.Trim(), required.Checked); 77 | } 78 | 79 | if (m_isEditMode) 80 | { 81 | ConfigurationManager.GetInstance().GetAvailableMods()[m_idx] = mod; 82 | } 83 | else 84 | { 85 | ConfigurationManager.GetInstance().GetAvailableMods().Add(mod); 86 | } 87 | 88 | FileIOManager.GetInstance().WriteModsDatabase(); 89 | ConfigurationManager.GetInstance().AlphabetiseModLists(); 90 | Close(); 91 | } 92 | } 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /ArmaReforgerServerTool/Components/AdvancedServerParameter.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace ReforgerServerApp.Components 2 | { 3 | partial class AdvancedServerParameter 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Component Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | parameterEnabled = new CheckBox(); 32 | description = new Label(); 33 | SuspendLayout(); 34 | // 35 | // parameterEnabled 36 | // 37 | parameterEnabled.AutoSize = true; 38 | parameterEnabled.Font = new Font("Segoe UI", 9F, FontStyle.Bold, GraphicsUnit.Point); 39 | parameterEnabled.Location = new Point(3, 3); 40 | parameterEnabled.Name = "parameterEnabled"; 41 | parameterEnabled.Size = new Size(168, 19); 42 | parameterEnabled.TabIndex = 0; 43 | parameterEnabled.Text = "Parameter Friendly Name"; 44 | parameterEnabled.UseVisualStyleBackColor = true; 45 | parameterEnabled.CheckedChanged += OnCheckChanged; 46 | // 47 | // description 48 | // 49 | description.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left; 50 | description.Font = new Font("Segoe UI", 6.75F, FontStyle.Bold, GraphicsUnit.Point); 51 | description.Location = new Point(4, 61); 52 | description.Name = "description"; 53 | description.Size = new Size(193, 37); 54 | description.TabIndex = 1; 55 | description.Text = "descriptiondescriptiondescriptiondescriptiondescriptiondescriptiondescriptiondescriptiondescription"; 56 | // 57 | // AdvancedServerParameter 58 | // 59 | AutoScaleDimensions = new SizeF(7F, 15F); 60 | AutoScaleMode = AutoScaleMode.Font; 61 | AutoSize = true; 62 | Controls.Add(description); 63 | Controls.Add(parameterEnabled); 64 | MaximumSize = new Size(200, 100); 65 | MinimumSize = new Size(200, 100); 66 | Name = "AdvancedServerParameter"; 67 | Size = new Size(200, 100); 68 | ResumeLayout(false); 69 | PerformLayout(); 70 | } 71 | 72 | #endregion 73 | 74 | private CheckBox parameterEnabled; 75 | protected Label description; 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /ArmaReforgerServerTool/Components/AdvancedServerParameterSchedule.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace ReforgerServerApp.Components 2 | { 3 | partial class AdvancedServerParameterSchedule 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Component Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | label1 = new Label(); 32 | parameterValue = new NumericUpDown(); 33 | timeUnit = new ComboBox(); 34 | ((System.ComponentModel.ISupportInitialize) parameterValue).BeginInit(); 35 | SuspendLayout(); 36 | // 37 | // label1 38 | // 39 | label1.AutoSize = true; 40 | label1.Font = new Font("Segoe UI", 9F, FontStyle.Bold, GraphicsUnit.Point); 41 | label1.Location = new Point(4, 35); 42 | label1.Name = "label1"; 43 | label1.Size = new Size(38, 15); 44 | label1.TabIndex = 2; 45 | label1.Text = "Every"; 46 | // 47 | // parameterValue 48 | // 49 | parameterValue.Location = new Point(48, 33); 50 | parameterValue.Name = "parameterValue"; 51 | parameterValue.Size = new Size(72, 23); 52 | parameterValue.TabIndex = 3; 53 | // 54 | // timeUnit 55 | // 56 | timeUnit.FormattingEnabled = true; 57 | timeUnit.Location = new Point(126, 33); 58 | timeUnit.Name = "timeUnit"; 59 | timeUnit.Size = new Size(65, 23); 60 | timeUnit.TabIndex = 4; 61 | // 62 | // AdvancedServerParameterSchedule 63 | // 64 | AutoScaleDimensions = new SizeF(7F, 15F); 65 | AutoScaleMode = AutoScaleMode.Font; 66 | Controls.Add(timeUnit); 67 | Controls.Add(parameterValue); 68 | Controls.Add(label1); 69 | Name = "AdvancedServerParameterSchedule"; 70 | Controls.SetChildIndex(label1, 0); 71 | Controls.SetChildIndex(parameterValue, 0); 72 | Controls.SetChildIndex(timeUnit, 0); 73 | ((System.ComponentModel.ISupportInitialize) parameterValue).EndInit(); 74 | ResumeLayout(false); 75 | PerformLayout(); 76 | } 77 | 78 | #endregion 79 | 80 | private Label label1; 81 | private NumericUpDown parameterValue; 82 | private ComboBox timeUnit; 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /ArmaReforgerServerTool/Models/LaunchArgument.cs: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * File Name: LaunchArgument.cs 3 | * Project: Longbow 4 | * Description: This file contains the LaunchArgument class, a model 5 | * representing a launch argument for the Arma Reforger Server, 6 | * it also holds a structure containing all known Launch 7 | * Arguments 8 | * 9 | * Author: Bradley Newman 10 | ******************************************************************************/ 11 | 12 | namespace ReforgerServerApp.Models 13 | { 14 | public class LaunchArgument 15 | { 16 | private readonly Dictionary m_underlyingDict; 17 | private readonly string m_key; 18 | 19 | /// 20 | /// Construct a launch argument with a key and value (e.g. -bindPort 2001) 21 | /// 22 | /// 23 | /// 24 | /// 25 | public LaunchArgument(string key, string val) 26 | { 27 | if (key.Trim().Length < 1) 28 | { 29 | throw new Exception("Key length is invalid"); 30 | } 31 | 32 | m_key = key.Trim(); 33 | m_underlyingDict = new(); 34 | 35 | if (val.Trim().Length > 0) 36 | { 37 | m_underlyingDict[m_key] = val.Trim(); 38 | } 39 | else 40 | { 41 | throw new Exception("Value is empty, use the single argument constructor to create switch arguments"); 42 | } 43 | } 44 | 45 | /// 46 | /// Construct a 'switch' LaunchArgument with only a key (e.g. -nobackend) 47 | /// 48 | /// 49 | /// 50 | public LaunchArgument(string key) 51 | { 52 | if (key.Trim().Length < 1) 53 | { 54 | throw new Exception("Key length is invalid"); 55 | } 56 | 57 | m_key = key.Trim(); 58 | m_underlyingDict = new() 59 | { 60 | [m_key] = string.Empty // the launch arg has no value (switch) 61 | }; 62 | } 63 | 64 | public string Get() 65 | { 66 | return m_underlyingDict[m_key]; 67 | } 68 | 69 | public void Set(string val) 70 | { 71 | m_underlyingDict[m_key] = val; 72 | } 73 | 74 | override public string ToString() 75 | { 76 | return $"-{m_key} {m_underlyingDict[m_key]}".Trim(); 77 | } 78 | } 79 | 80 | public struct LaunchArguments 81 | { 82 | public LaunchArgument config; 83 | public LaunchArgument profile; 84 | public LaunchArgument addonsDir; 85 | public LaunchArgument logStats; 86 | public LaunchArgument maxFPS; 87 | public LaunchArgument bindPort; 88 | public LaunchArgument nds; 89 | public LaunchArgument nwkResolution; 90 | public LaunchArgument staggeringBudget; 91 | public LaunchArgument streamingBudget; 92 | public LaunchArgument streamsDelta; 93 | public LaunchArgument loadSessionSave; 94 | public LaunchArgument logLevel; 95 | public LaunchArgument autoReload; 96 | public LaunchArgument rplTimeoutMs; 97 | public LaunchArgument freezeCheck; 98 | public LaunchArgument freezeCheckMode; 99 | public LaunchArgument addonsRepair; 100 | public LaunchArgument autoShutdown; 101 | public LaunchArgument logVoting; 102 | public LaunchArgument aiPartialSim; 103 | public LaunchArgument createDB; 104 | public LaunchArgument debugger; 105 | public LaunchArgument debuggerPort; 106 | public LaunchArgument disableShadersBuild; 107 | public LaunchArgument generateShaders; 108 | public LaunchArgument rplEncodeAsLongJobs; 109 | public LaunchArgument jobSysShortWorkerCount; 110 | public LaunchArgument jobSysLongWorkerCount; 111 | public LaunchArgument forceDisableNightGrain; 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /ArmaReforgerServerTool/Forms/ListForm.Designer.cs: -------------------------------------------------------------------------------- 1 | using ReforgerServerApp.Components; 2 | 3 | namespace ReforgerServerApp 4 | { 5 | partial class ListForm 6 | { 7 | /// 8 | /// Required designer variable. 9 | /// 10 | private System.ComponentModel.IContainer components = null; 11 | 12 | /// 13 | /// Clean up any resources being used. 14 | /// 15 | /// true if managed resources should be disposed; otherwise, false. 16 | protected override void Dispose(bool disposing) 17 | { 18 | if (disposing && (components != null)) 19 | { 20 | components.Dispose(); 21 | } 22 | base.Dispose(disposing); 23 | } 24 | 25 | #region Windows Form Designer generated code 26 | 27 | /// 28 | /// Required method for Designer support - do not modify 29 | /// the contents of this method with the code editor. 30 | /// 31 | private void InitializeComponent() 32 | { 33 | addBtn = new Button(); 34 | removeBtn = new Button(); 35 | closeBtn = new Button(); 36 | itemTB = new TextBox(); 37 | itemListView = new BoundListBox(); 38 | SuspendLayout(); 39 | // 40 | // addBtn 41 | // 42 | addBtn.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; 43 | addBtn.Location = new Point(392, 415); 44 | addBtn.Name = "addBtn"; 45 | addBtn.Size = new Size(75, 23); 46 | addBtn.TabIndex = 1; 47 | addBtn.Text = "Add"; 48 | addBtn.UseVisualStyleBackColor = true; 49 | addBtn.Click += AddBtnClicked; 50 | // 51 | // removeBtn 52 | // 53 | removeBtn.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; 54 | removeBtn.Location = new Point(473, 415); 55 | removeBtn.Name = "removeBtn"; 56 | removeBtn.Size = new Size(75, 23); 57 | removeBtn.TabIndex = 2; 58 | removeBtn.Text = "Remove"; 59 | removeBtn.UseVisualStyleBackColor = true; 60 | removeBtn.Click += RemoveBtnClicked; 61 | // 62 | // closeBtn 63 | // 64 | closeBtn.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; 65 | closeBtn.Location = new Point(713, 415); 66 | closeBtn.Name = "closeBtn"; 67 | closeBtn.Size = new Size(75, 23); 68 | closeBtn.TabIndex = 3; 69 | closeBtn.Text = "Close"; 70 | closeBtn.UseVisualStyleBackColor = true; 71 | closeBtn.Click += CloseBtnClicked; 72 | // 73 | // itemTB 74 | // 75 | itemTB.Anchor = AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; 76 | itemTB.Location = new Point(12, 415); 77 | itemTB.Name = "itemTB"; 78 | itemTB.Size = new Size(374, 23); 79 | itemTB.TabIndex = 4; 80 | // 81 | // itemListView 82 | // 83 | itemListView.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; 84 | itemListView.ItemHeight = 15; 85 | itemListView.Location = new Point(12, 12); 86 | itemListView.Name = "itemListView"; 87 | itemListView.Size = new Size(776, 379); 88 | itemListView.TabIndex = 0; 89 | // 90 | // ListForm 91 | // 92 | AutoScaleDimensions = new SizeF(7F, 15F); 93 | AutoScaleMode = AutoScaleMode.Font; 94 | ClientSize = new Size(800, 450); 95 | Controls.Add(itemTB); 96 | Controls.Add(closeBtn); 97 | Controls.Add(removeBtn); 98 | Controls.Add(addBtn); 99 | Controls.Add(itemListView); 100 | MinimumSize = new Size(640, 480); 101 | Name = "ListForm"; 102 | ShowIcon = false; 103 | StartPosition = FormStartPosition.CenterParent; 104 | Text = "Longbow - ListForm"; 105 | ResumeLayout(false); 106 | PerformLayout(); 107 | } 108 | 109 | #endregion 110 | private Button addBtn; 111 | private Button removeBtn; 112 | private Button closeBtn; 113 | private TextBox itemTB; 114 | private BoundListBox itemListView; 115 | } 116 | } -------------------------------------------------------------------------------- /ArmaReforgerServerTool/Forms/RenameForm.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace Longbow.Forms 2 | { 3 | partial class RenameForm 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | renameTB = new TextBox(); 32 | renameBtn = new FontAwesome.Sharp.IconButton(); 33 | cancelBtn = new FontAwesome.Sharp.IconButton(); 34 | tableLayoutPanel1 = new TableLayoutPanel(); 35 | tableLayoutPanel1.SuspendLayout(); 36 | SuspendLayout(); 37 | // 38 | // renameTB 39 | // 40 | renameTB.Location = new Point(12, 12); 41 | renameTB.Name = "renameTB"; 42 | renameTB.Size = new Size(260, 23); 43 | renameTB.TabIndex = 0; 44 | // 45 | // renameBtn 46 | // 47 | renameBtn.Dock = DockStyle.Fill; 48 | renameBtn.IconChar = FontAwesome.Sharp.IconChar.None; 49 | renameBtn.IconColor = Color.Black; 50 | renameBtn.IconFont = FontAwesome.Sharp.IconFont.Auto; 51 | renameBtn.Location = new Point(100, 0); 52 | renameBtn.Margin = new Padding(0); 53 | renameBtn.Name = "renameBtn"; 54 | renameBtn.Size = new Size(100, 23); 55 | renameBtn.TabIndex = 1; 56 | renameBtn.Text = "Rename"; 57 | renameBtn.UseVisualStyleBackColor = true; 58 | renameBtn.Click += RenameBtnPressed; 59 | // 60 | // cancelBtn 61 | // 62 | cancelBtn.Dock = DockStyle.Fill; 63 | cancelBtn.IconChar = FontAwesome.Sharp.IconChar.None; 64 | cancelBtn.IconColor = Color.Black; 65 | cancelBtn.IconFont = FontAwesome.Sharp.IconFont.Auto; 66 | cancelBtn.Location = new Point(0, 0); 67 | cancelBtn.Margin = new Padding(0); 68 | cancelBtn.Name = "cancelBtn"; 69 | cancelBtn.Size = new Size(100, 23); 70 | cancelBtn.TabIndex = 2; 71 | cancelBtn.Text = "Cancel"; 72 | cancelBtn.UseVisualStyleBackColor = true; 73 | cancelBtn.Click += CancelBtnPressed; 74 | // 75 | // tableLayoutPanel1 76 | // 77 | tableLayoutPanel1.ColumnCount = 2; 78 | tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50F)); 79 | tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50F)); 80 | tableLayoutPanel1.Controls.Add(cancelBtn, 0, 0); 81 | tableLayoutPanel1.Controls.Add(renameBtn, 1, 0); 82 | tableLayoutPanel1.Location = new Point(72, 41); 83 | tableLayoutPanel1.Name = "tableLayoutPanel1"; 84 | tableLayoutPanel1.RowCount = 1; 85 | tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Percent, 50F)); 86 | tableLayoutPanel1.Size = new Size(200, 23); 87 | tableLayoutPanel1.TabIndex = 3; 88 | // 89 | // RenameForm 90 | // 91 | AutoScaleDimensions = new SizeF(7F, 15F); 92 | AutoScaleMode = AutoScaleMode.Font; 93 | ClientSize = new Size(284, 73); 94 | ControlBox = false; 95 | Controls.Add(tableLayoutPanel1); 96 | Controls.Add(renameTB); 97 | FormBorderStyle = FormBorderStyle.FixedToolWindow; 98 | Name = "RenameForm"; 99 | ShowIcon = false; 100 | StartPosition = FormStartPosition.CenterParent; 101 | Text = "Longbow - Rename Save"; 102 | tableLayoutPanel1.ResumeLayout(false); 103 | ResumeLayout(false); 104 | PerformLayout(); 105 | } 106 | 107 | #endregion 108 | 109 | private TextBox renameTB; 110 | private FontAwesome.Sharp.IconButton renameBtn; 111 | private FontAwesome.Sharp.IconButton cancelBtn; 112 | private TableLayoutPanel tableLayoutPanel1; 113 | } 114 | } -------------------------------------------------------------------------------- /ArmaReforgerServerTool/Models/Mod.cs: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * File Name: Mod.cs 3 | * Project: Longbow 4 | * Description: This file contains the Mod class, a model representing the 5 | * Mod structure in the Arma Reforger server configuration 6 | * 7 | * Author: Bradley Newman 8 | ******************************************************************************/ 9 | 10 | using HtmlAgilityPack; 11 | using ReforgerServerApp.Managers; 12 | using ReforgerServerApp.Utils; 13 | using Serilog; 14 | using System.Text.Json.Serialization; 15 | using HtmlDocument = HtmlAgilityPack.HtmlDocument; 16 | 17 | namespace ReforgerServerApp 18 | { 19 | public class Mod 20 | { 21 | public string modId { get; set; } 22 | public string name { get; set; } 23 | 24 | [JsonConverter(typeof(JsonUtils.ConditionalFieldConverter))] 25 | public string version { get; set; } 26 | public bool required { get; set; } 27 | 28 | private const string LATEST_MOD_VER_STR = "latest"; 29 | 30 | public Mod() { /* Exists only for JSON deserializing */ } 31 | 32 | public Mod(string modId, string modName, string modVersion, bool required = false) 33 | { 34 | this.modId = modId; 35 | this.name = modName; 36 | this.version = modVersion; 37 | this.required = required; 38 | } 39 | 40 | public Mod(string modId, string modName, bool required = false) 41 | { 42 | this.modId = modId; 43 | this.name = modName; 44 | this.version = LATEST_MOD_VER_STR; 45 | this.required = required; 46 | } 47 | 48 | public Mod(Mod m) 49 | { 50 | this.modId = m.modId; 51 | this.name = m.name; 52 | this.version = m.version; 53 | this.required = m.required; 54 | } 55 | 56 | public string GetModID() 57 | { 58 | return modId!; 59 | } 60 | 61 | public string GetModName() 62 | { 63 | return name!; 64 | } 65 | 66 | public string GetModVersion() 67 | { 68 | return version!; 69 | } 70 | 71 | public bool IsModRequired() 72 | { 73 | return required!; 74 | } 75 | 76 | public override string ToString() 77 | { 78 | return $"{name} | {version}"; 79 | } 80 | 81 | public override bool Equals(object? obj) 82 | { 83 | if (obj == this) 84 | { 85 | return true; 86 | } 87 | if (obj == null) 88 | { 89 | return false; 90 | } 91 | if (obj.GetType() == typeof(Mod)) 92 | { 93 | Mod other = (Mod)obj; 94 | bool modSame = name!.Equals(other.name); 95 | modSame &= modId!.Equals(other.modId); 96 | if (version != null) 97 | { 98 | modSame &= version!.Equals(other.version); 99 | } 100 | 101 | return modSame; 102 | } 103 | return false; 104 | } 105 | 106 | public override int GetHashCode() 107 | { 108 | return modId!.GetHashCode() + name!.GetHashCode(); 109 | } 110 | 111 | public static List GetScenariosForMod(string modId) 112 | { 113 | List scenarios = new(); 114 | if (!modId.Equals(Constants.STOCK_MOD_ID)) 115 | { 116 | try 117 | { 118 | string fetchUrl = $"{ToolPropertiesManager.GetInstance().GetToolProperties().armaWorkshopUrl}/{modId}/scenarios"; 119 | HtmlWeb web = new(); 120 | HtmlDocument doc = web.Load(fetchUrl); 121 | const string className = "text-start"; 122 | HtmlNodeCollection rawScenIds = doc.DocumentNode.SelectNodes($"//*[contains(@class,'{className}')]"); 123 | if (rawScenIds != null) 124 | { 125 | foreach (HtmlNode field in rawScenIds) 126 | { 127 | Log.Debug("Mod - Discovered scenario \"{scenario}\" for Mod \"{mod}\"", field.InnerText, modId); 128 | scenarios.Add(field.InnerText); 129 | } 130 | } 131 | else 132 | { 133 | Log.Debug("Mod - Failed to fetch any scenario ids for \"{mod}\". It may not have any.", modId); 134 | } 135 | } 136 | catch (Exception ex) 137 | { 138 | Utilities.DisplayErrorMessage("Unable to fetch Scenario IDs from Arma Reforger Workshop, please check your internet connection.", ex.Message); 139 | } 140 | } 141 | return scenarios; 142 | } 143 | } 144 | } 145 | -------------------------------------------------------------------------------- /ArmaReforgerServerTool/Forms/SaveSelector.cs: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * File Name: SaveSelector.cs 3 | * Project: Longbow 4 | * Description: This is the Save Selector Form 5 | * 6 | * Author: Bradley Newman 7 | ******************************************************************************/ 8 | 9 | using ReforgerServerApp; 10 | using ReforgerServerApp.Managers; 11 | using ReforgerServerApp.Utils; 12 | 13 | namespace Longbow.Forms 14 | { 15 | public partial class SaveSelector : Form 16 | { 17 | Dictionary m_savedGames; 18 | public SaveSelector() 19 | { 20 | InitializeComponent(); 21 | m_savedGames = new(); 22 | RefreshSavedGamesList(); 23 | UpdateSaveLabel(); 24 | } 25 | 26 | /// 27 | /// Utility method for reloading the saved games list 28 | /// 29 | private void RefreshSavedGamesList() 30 | { 31 | m_savedGames = FileIOManager.GetInstance().GetSavedGames(); 32 | savedGamesList.Items.Clear(); 33 | foreach (string save in m_savedGames.Keys) 34 | { 35 | savedGamesList.Items.Add(save); 36 | } 37 | } 38 | 39 | /// 40 | /// Toggle Button Enabled states based on logic required 41 | /// 42 | /// 43 | private void ToggleButtonStates(object? selectedItem) 44 | { 45 | renameSaveBtn.Enabled = selectedItem != null; 46 | loadSelectedSaveBtn.Enabled = selectedItem != null; 47 | renameSaveBtn.Enabled = selectedItem != null; 48 | deleteSaveBtn.Enabled = selectedItem != null && !selectedItem.Equals(string.Empty); 49 | clearSaveBtn.Enabled = ConfigurationManager.GetInstance().usingSave; 50 | 51 | if (selectedItem != null && selectedItem is string saveStr) 52 | { 53 | keepPermanentlyBtn.Enabled = saveStr.Contains(".auto"); 54 | } 55 | } 56 | 57 | /// 58 | /// Update the label stating which save is loaded 59 | /// 60 | private void UpdateSaveLabel() 61 | { 62 | if (ConfigurationManager.GetInstance().usingSave) 63 | { 64 | if (ConfigurationManager.GetInstance().save.Equals(".LatestSave")) 65 | { 66 | loadedSaveLabel.Text = $"Using latest save."; 67 | return; 68 | } 69 | loadedSaveLabel.Text = $"Loaded save: {ConfigurationManager.GetInstance().save}"; 70 | return; 71 | } 72 | loadedSaveLabel.Text = "No save loaded. Your server will not use a save."; 73 | } 74 | 75 | private void SavedGamesListSelectedIndexChanged(object sender, EventArgs e) 76 | { 77 | ToggleButtonStates(savedGamesList.SelectedItem); 78 | } 79 | 80 | private void KeepBtnPressed(object sender, EventArgs e) 81 | { 82 | string origNameKey = (string) savedGamesList.SelectedItem!; 83 | string origName = m_savedGames[origNameKey]; 84 | string newName = origName.Replace(".auto", ""); 85 | FileIOManager.GetInstance().RenameFile(origName, newName); 86 | ToggleButtonStates(savedGamesList.SelectedItem); 87 | RefreshSavedGamesList(); 88 | } 89 | 90 | private void DeleteBtnPressed(object sender, EventArgs e) 91 | { 92 | string selectedSave = (string) savedGamesList.SelectedItem!; 93 | bool confirm = Utilities.DisplayConfirmationMessage($"You are about to delete your saved game '{selectedSave}', are you sure you would like to do this?", true); 94 | if (confirm) 95 | { 96 | FileIOManager.DeleteFile(m_savedGames[selectedSave]); 97 | ToggleButtonStates(savedGamesList.SelectedItem); 98 | RefreshSavedGamesList(); 99 | } 100 | } 101 | 102 | private void RenameBtnPressed(object sender, EventArgs e) 103 | { 104 | string origName = (string) savedGamesList.SelectedItem!; 105 | RenameForm rf = new(origName); 106 | DialogResult result = rf.ShowDialog(); 107 | if (result == DialogResult.OK) 108 | { 109 | string origPath = m_savedGames[origName]; 110 | string newPath = $"{FileIOManager.GetInstance().GetSavesPath()}\\{rf.GetResultingRename()}.json"; 111 | FileIOManager.GetInstance().RenameFile(origPath, newPath); 112 | } 113 | RefreshSavedGamesList(); 114 | } 115 | 116 | private void LoadBtnPressed(object sender, EventArgs e) 117 | { 118 | ConfigurationManager.GetInstance().save = (string) savedGamesList.SelectedItem!; 119 | ConfigurationManager.GetInstance().usingSave = true; 120 | UpdateSaveLabel(); 121 | ToggleButtonStates(savedGamesList.SelectedItem); 122 | } 123 | 124 | private void LatestBtnPressed(object sender, EventArgs e) 125 | { 126 | ConfigurationManager.GetInstance().save = ".LatestSave"; 127 | ConfigurationManager.GetInstance().usingSave = true; 128 | UpdateSaveLabel(); 129 | ToggleButtonStates(savedGamesList.SelectedItem); 130 | } 131 | 132 | private void ClearSaveBtnPressed(object sender, EventArgs e) 133 | { 134 | ConfigurationManager.GetInstance().usingSave = false; 135 | UpdateSaveLabel(); 136 | ToggleButtonStates(savedGamesList.SelectedItem); 137 | } 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /ArmaReforgerServerTool/Managers/NetworkManager.cs: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * File Name: NetworkManager.cs 3 | * Project: Longbow 4 | * Description: This file contains the singleton NetworkManager class 5 | * responsible for networking specific operations. 6 | * 7 | * Authors: Kye Seyhun 8 | ******************************************************************************/ 9 | 10 | using Open.Nat; 11 | using ReforgerServerApp.Utils; 12 | using Serilog; 13 | using System.Net; 14 | using System.Net.Sockets; 15 | 16 | namespace ReforgerServerApp.Managers 17 | { 18 | /// 19 | /// This class manages the application's Networking related logic 20 | /// 21 | internal class NetworkManager 22 | { 23 | private static NetworkManager? m_instance; 24 | private static readonly int INFINITE_LIFETIME = 0; 25 | 26 | public bool useUPnP { get; set; } 27 | 28 | private NetworkManager() 29 | { 30 | // Disable no-args constructor to enforce singleton pattern 31 | } 32 | 33 | public static NetworkManager GetInstance() 34 | { 35 | m_instance ??= new NetworkManager(); 36 | return m_instance; 37 | } 38 | 39 | /// 40 | /// Configure Universal Plug and Play for a list of devices and ports 41 | /// 42 | /// to configure UPnP for 43 | public async Task ConfigurePortMappings(List<(string ipAddress, int port)> mappings) 44 | { 45 | if (!useUPnP) 46 | { 47 | Log.Information("NetworkManager - UPnP is not being used."); 48 | return; 49 | } 50 | 51 | try 52 | { 53 | var discoverer = new NatDiscoverer(); 54 | var device = await discoverer.DiscoverDeviceAsync(); 55 | 56 | foreach (var mapping in mappings) 57 | { 58 | string ipAddr = mapping.ipAddress; 59 | int port = mapping.port; 60 | 61 | // Convert string IP address to IPAddress type 62 | if (IPAddress.TryParse(ipAddr, out IPAddress ip)) 63 | { 64 | // Create port mapping for the specified IP address 65 | var natMapping = new Mapping(Protocol.Tcp, ip, port, port, INFINITE_LIFETIME, $"Mapping for {ipAddr}:{port}"); 66 | try 67 | { 68 | await device.CreatePortMapAsync(natMapping); 69 | Log.Information("NetworkManager - Opened UPnP port mapping {ipAddr}:{port}", ipAddr, port); 70 | } 71 | catch (Exception ex) 72 | { 73 | Log.Error("NetworkManager - Failed to map {ipAddr}:{port} - {ex}", ipAddr, port, ex.Message); 74 | } 75 | } 76 | else 77 | { 78 | Log.Error("NetworkManager - Failed to convert {ipAddr} to IP Address. UPnP will not be configured for port {port}", ipAddr, port); 79 | } 80 | } 81 | } 82 | catch (Exception ex) 83 | { 84 | Log.Error("NetworkManager - Failed to configure UPnP: {msg}", ex.Message); 85 | if (ex.GetType() == typeof(NatDeviceNotFoundException)) 86 | { 87 | Utilities.DisplayErrorMessage("Failed to start server with UPnP", "No UPnP NAT device was found. UPnP is not supported on your system."); 88 | } 89 | 90 | if (ex.GetType() == typeof(SocketException)) 91 | { 92 | Utilities.DisplayErrorMessage("Failed to start server with UPnP", "Failed to start the server with UPnP. You may need to turn it off."); 93 | } 94 | } 95 | } 96 | 97 | /// 98 | /// Remove any created UPnP mappings, given a list 99 | /// 100 | /// to remove UPnP for 101 | public async Task RemovePortMappings(List<(string ipAddress, int port)> mappings) 102 | { 103 | if (!useUPnP) 104 | { 105 | Log.Information("NetworkManager - UPnP is not being used."); 106 | return; 107 | } 108 | 109 | try 110 | { 111 | var discoverer = new NatDiscoverer(); 112 | var device = await discoverer.DiscoverDeviceAsync(); 113 | 114 | Console.WriteLine("Device found: " + device); 115 | 116 | foreach (var mapping in mappings) 117 | { 118 | string ipAddr = mapping.ipAddress; 119 | int port = mapping.port; 120 | 121 | // Convert string IP address to IPAddress type 122 | if (IPAddress.TryParse(ipAddr, out IPAddress ip)) 123 | { 124 | // Create port mapping for the specified IP address 125 | var natMapping = new Mapping(Protocol.Tcp, ip, port, port, INFINITE_LIFETIME, $"Mapping for {ipAddr}:{port}"); 126 | await device.DeletePortMapAsync(natMapping); 127 | 128 | Log.Information("NetworkManager - Removed UPnP port mapping {ipAddr}:{port}", ipAddr, port); 129 | } 130 | else 131 | { 132 | Log.Error("NetworkManager - Failed to convert {ipAddr} to IP Address. UPnP will not be configured for port {port}", ipAddr, port); 133 | } 134 | } 135 | } 136 | catch (Exception ex) 137 | { 138 | Log.Error("NetworkManager - An exception occurred while attempting to remove UPnP port mappings: {msg}", ex.Message); 139 | } 140 | } 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /ArmaReforgerServerTool/Forms/ScenarioSelector.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace ReforgerServerApp 2 | { 3 | partial class ScenarioSelector 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | scenarioList = new ListBox(); 32 | selectScenarioBtn = new Button(); 33 | reloadScenariosBtn = new Button(); 34 | currentlySelectedLbl = new Label(); 35 | manualScenarioIdTextBox = new TextBox(); 36 | loadingAnim = new AnimOfDots.Circular(); 37 | SuspendLayout(); 38 | // 39 | // scenarioList 40 | // 41 | scenarioList.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; 42 | scenarioList.FormattingEnabled = true; 43 | scenarioList.ItemHeight = 15; 44 | scenarioList.Location = new Point(12, 12); 45 | scenarioList.Name = "scenarioList"; 46 | scenarioList.Size = new Size(682, 394); 47 | scenarioList.TabIndex = 0; 48 | scenarioList.SelectedIndexChanged += ScenarioListSelectionChanged; 49 | // 50 | // selectScenarioBtn 51 | // 52 | selectScenarioBtn.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; 53 | selectScenarioBtn.Location = new Point(579, 443); 54 | selectScenarioBtn.Name = "selectScenarioBtn"; 55 | selectScenarioBtn.Size = new Size(115, 23); 56 | selectScenarioBtn.TabIndex = 1; 57 | selectScenarioBtn.Text = "Select Scenario"; 58 | selectScenarioBtn.UseVisualStyleBackColor = true; 59 | selectScenarioBtn.Click += SelectScenarioButtonClicked; 60 | // 61 | // reloadScenariosBtn 62 | // 63 | reloadScenariosBtn.Anchor = AnchorStyles.Bottom | AnchorStyles.Left; 64 | reloadScenariosBtn.Location = new Point(12, 443); 65 | reloadScenariosBtn.Name = "reloadScenariosBtn"; 66 | reloadScenariosBtn.Size = new Size(115, 23); 67 | reloadScenariosBtn.TabIndex = 2; 68 | reloadScenariosBtn.Text = "Reload Scenarios"; 69 | reloadScenariosBtn.UseVisualStyleBackColor = true; 70 | reloadScenariosBtn.Click += ReloadScenariosButtonClicked; 71 | // 72 | // currentlySelectedLbl 73 | // 74 | currentlySelectedLbl.Anchor = AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; 75 | currentlySelectedLbl.AutoEllipsis = true; 76 | currentlySelectedLbl.Location = new Point(165, 447); 77 | currentlySelectedLbl.Name = "currentlySelectedLbl"; 78 | currentlySelectedLbl.Size = new Size(408, 15); 79 | currentlySelectedLbl.TabIndex = 3; 80 | currentlySelectedLbl.Text = "Currently selected Scenario is:"; 81 | currentlySelectedLbl.TextAlign = ContentAlignment.MiddleLeft; 82 | // 83 | // manualScenarioIdTextBox 84 | // 85 | manualScenarioIdTextBox.Anchor = AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; 86 | manualScenarioIdTextBox.Location = new Point(12, 414); 87 | manualScenarioIdTextBox.Name = "manualScenarioIdTextBox"; 88 | manualScenarioIdTextBox.PlaceholderText = "Enter a Scenario ID here to manually set one..."; 89 | manualScenarioIdTextBox.Size = new Size(682, 23); 90 | manualScenarioIdTextBox.TabIndex = 4; 91 | manualScenarioIdTextBox.TextChanged += ManualScenarioIDTextChanged; 92 | // 93 | // loadingAnim 94 | // 95 | loadingAnim.Anchor = AnchorStyles.Bottom | AnchorStyles.Left; 96 | loadingAnim.AnimationSpeed = 10; 97 | loadingAnim.BackColor = Color.Transparent; 98 | loadingAnim.ForeColor = Color.DodgerBlue; 99 | loadingAnim.Location = new Point(133, 443); 100 | loadingAnim.Name = "loadingAnim"; 101 | loadingAnim.Running = true; 102 | loadingAnim.Size = new Size(26, 19); 103 | loadingAnim.TabIndex = 5; 104 | loadingAnim.Visible = false; 105 | // 106 | // ScenarioSelector 107 | // 108 | AutoScaleDimensions = new SizeF(7F, 15F); 109 | AutoScaleMode = AutoScaleMode.Font; 110 | ClientSize = new Size(706, 478); 111 | Controls.Add(loadingAnim); 112 | Controls.Add(manualScenarioIdTextBox); 113 | Controls.Add(currentlySelectedLbl); 114 | Controls.Add(reloadScenariosBtn); 115 | Controls.Add(selectScenarioBtn); 116 | Controls.Add(scenarioList); 117 | MinimumSize = new Size(640, 480); 118 | Name = "ScenarioSelector"; 119 | ShowIcon = false; 120 | StartPosition = FormStartPosition.CenterParent; 121 | Text = "Longbow - Select Scenario"; 122 | FormClosing += OnFormClosing; 123 | ResumeLayout(false); 124 | PerformLayout(); 125 | } 126 | 127 | #endregion 128 | 129 | private ListBox scenarioList; 130 | private Button selectScenarioBtn; 131 | private Button reloadScenariosBtn; 132 | private Label currentlySelectedLbl; 133 | private TextBox manualScenarioIdTextBox; 134 | private AnimOfDots.Circular loadingAnim; 135 | } 136 | } -------------------------------------------------------------------------------- /ArmaReforgerServerTool/Forms/AboutBox.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | -------------------------------------------------------------------------------- /ArmaReforgerServerTool/Forms/AddModDialog.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | -------------------------------------------------------------------------------- /ArmaReforgerServerTool/Forms/ListForm.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | -------------------------------------------------------------------------------- /ArmaReforgerServerTool/Forms/RenameForm.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | -------------------------------------------------------------------------------- /ArmaReforgerServerTool/Forms/ScenarioSelector.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | -------------------------------------------------------------------------------- /ArmaReforgerServerTool/Forms/TextInputForm.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | -------------------------------------------------------------------------------- /ArmaReforgerServerTool/Components/ServerParameter.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | -------------------------------------------------------------------------------- /ArmaReforgerServerTool/Components/ServerParameterList.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | -------------------------------------------------------------------------------- /ArmaReforgerServerTool/Components/ServerParameterText.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | -------------------------------------------------------------------------------- /ArmaReforgerServerTool/Components/AdvancedServerParameter.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | -------------------------------------------------------------------------------- /ArmaReforgerServerTool/Components/AdvancedServerParameterBool.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | -------------------------------------------------------------------------------- /ArmaReforgerServerTool/Components/AdvancedServerParameterTime.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | -------------------------------------------------------------------------------- /ArmaReforgerServerTool/Components/ServerParameterBool.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | -------------------------------------------------------------------------------- /ArmaReforgerServerTool/Components/ServerParameterNumeric.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | --------------------------------------------------------------------------------