diff --git a/.gitignore b/.gitignore
index 63041f7803c8d..329db73f99e8e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -12,6 +12,9 @@ ArchiSteamFarm/config/*
ArchiSteamFarm/log.txt
ArchiSteamFarm/debug/*
+# Ignore out
+out/
+
#################
## Eclipse
#################
diff --git a/ArchiSteamFarm.sln b/ArchiSteamFarm.sln
index 82055061cbe2a..b74f8f9f2d20b 100644
--- a/ArchiSteamFarm.sln
+++ b/ArchiSteamFarm.sln
@@ -1,12 +1,17 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
-VisualStudioVersion = 14.0.23107.0
+VisualStudioVersion = 14.0.24720.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ArchiSteamFarm", "ArchiSteamFarm\ArchiSteamFarm.csproj", "{35AF7887-08B9-40E8-A5EA-797D8B60B30C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SteamAuth", "SteamAuth\SteamAuth.csproj", "{5AD0934E-F6C4-4AE5-83AF-C788313B2A87}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConfigGenerator", "ConfigGenerator\ConfigGenerator.csproj", "{C3F6FE68-5E75-415E-BEA1-1E7C16D6A433}"
+ ProjectSection(ProjectDependencies) = postProject
+ {35AF7887-08B9-40E8-A5EA-797D8B60B30C} = {35AF7887-08B9-40E8-A5EA-797D8B60B30C}
+ EndProjectSection
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -21,6 +26,10 @@ Global
{5AD0934E-F6C4-4AE5-83AF-C788313B2A87}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5AD0934E-F6C4-4AE5-83AF-C788313B2A87}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5AD0934E-F6C4-4AE5-83AF-C788313B2A87}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C3F6FE68-5E75-415E-BEA1-1E7C16D6A433}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C3F6FE68-5E75-415E-BEA1-1E7C16D6A433}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C3F6FE68-5E75-415E-BEA1-1E7C16D6A433}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C3F6FE68-5E75-415E-BEA1-1E7C16D6A433}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/ArchiSteamFarm/ArchiSteamFarm.csproj b/ArchiSteamFarm/ArchiSteamFarm.csproj
index 404e4a7fe78f1..dd373f886f135 100644
--- a/ArchiSteamFarm/ArchiSteamFarm.csproj
+++ b/ArchiSteamFarm/ArchiSteamFarm.csproj
@@ -160,20 +160,20 @@
- mkdir "$(TargetDir)out" "$(TargetDir)out\config"
- copy "$(TargetDir)config\ASF.json" "$(TargetDir)out\config"
- copy "$(TargetDir)config\example.json" "$(TargetDir)out\config"
- copy "$(TargetDir)config\minimal.json" "$(TargetDir)out\config"
- "$(SolutionDir)tools\ILRepack.exe" /ndebug /internalize /parallel /targetplatform:v4 /wildcards /out:"$(TargetDir)out\ASF.exe" "$(TargetDir)$(TargetName).exe" "$(TargetDir)*.dll"
- del "$(TargetDir)out\ASF.exe.config"
+ mkdir "$(SolutionDir)out" "$(SolutionDir)out\config"
+ copy "$(TargetDir)config\ASF.json" "$(SolutionDir)out\config"
+ copy "$(TargetDir)config\example.json" "$(SolutionDir)out\config"
+ copy "$(TargetDir)config\minimal.json" "$(SolutionDir)out\config"
+ "$(SolutionDir)tools\ILRepack.exe" /ndebug /internalize /parallel /targetplatform:v4 /wildcards /out:"$(SolutionDir)out\ASF.exe" "$(TargetDir)$(TargetName).exe" "$(TargetDir)*.dll"
+ del "$(SolutionDir)out\ASF.exe.config"
- mkdir -p "$(TargetDir)out" "$(TargetDir)out/config"
- cp "$(TargetDir)config/ASF.json" "$(TargetDir)out/config"
- cp "$(TargetDir)config/example.json" "$(TargetDir)out/config"
- cp "$(TargetDir)config/minimal.json" "$(TargetDir)out/config"
- mono -O=all "$(SolutionDir)tools/ILRepack.exe" /ndebug /internalize /parallel /targetplatform:v4 /wildcards /out:"$(TargetDir)out/ASF.exe" "$(TargetDir)$(TargetName).exe" "$(TargetDir)*.dll"
- rm "$(TargetDir)out/ASF.exe.config"
+ mkdir -p "$(SolutionDir)out" "$(SolutionDir)out/config"
+ cp "$(TargetDir)config/ASF.json" "$(SolutionDir)out/config"
+ cp "$(TargetDir)config/example.json" "$(SolutionDir)out/config"
+ cp "$(TargetDir)config/minimal.json" "$(SolutionDir)out/config"
+ mono -O=all "$(SolutionDir)tools/ILRepack.exe" /ndebug /internalize /parallel /targetplatform:v4 /wildcards /out:"$(SolutionDir)out/ASF.exe" "$(TargetDir)$(TargetName).exe" "$(TargetDir)*.dll"
+ rm "$(SolutionDir)out/ASF.exe.config"
+
\ No newline at end of file
diff --git a/ConfigGenerator/Debugging.cs b/ConfigGenerator/Debugging.cs
new file mode 100644
index 0000000000000..62242322b0b9d
--- /dev/null
+++ b/ConfigGenerator/Debugging.cs
@@ -0,0 +1,38 @@
+/*
+ _ _ _ ____ _ _____
+ / \ _ __ ___ | |__ (_)/ ___| | |_ ___ __ _ _ __ ___ | ___|__ _ _ __ _ __ ___
+ / _ \ | '__|/ __|| '_ \ | |\___ \ | __|/ _ \ / _` || '_ ` _ \ | |_ / _` || '__|| '_ ` _ \
+ / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
+/_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
+
+ Copyright 2015-2016 Łukasz "JustArchi" Domeradzki
+ Contact: JustArchi@JustArchi.net
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+*/
+
+using System;
+using System.IO;
+
+namespace ConfigGenerator {
+ internal static class Debugging {
+#if DEBUG
+ internal static readonly bool IsDebugBuild = true;
+#else
+ internal static readonly bool IsDebugBuild = false;
+#endif
+
+ internal static bool IsReleaseBuild => !IsDebugBuild;
+ }
+}
diff --git a/ConfigGenerator/EnhancedPropertyGrid.cs b/ConfigGenerator/EnhancedPropertyGrid.cs
new file mode 100644
index 0000000000000..e97741c7603e9
--- /dev/null
+++ b/ConfigGenerator/EnhancedPropertyGrid.cs
@@ -0,0 +1,20 @@
+using System.Windows.Forms;
+
+namespace ConfigGenerator {
+ internal sealed class EnhancedPropertyGrid : PropertyGrid {
+ private GlobalConfig GlobalConfig;
+ internal EnhancedPropertyGrid(GlobalConfig globalConfig) : base() {
+ if (globalConfig == null) {
+ return;
+ }
+
+ GlobalConfig = globalConfig;
+
+ SelectedObject = globalConfig;
+ Anchor = AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Top;
+ Dock = DockStyle.Fill;
+ HelpVisible = false;
+ ToolbarVisible = false;
+ }
+ }
+}
diff --git a/ConfigGenerator/GlobalConfig.cs b/ConfigGenerator/GlobalConfig.cs
new file mode 100644
index 0000000000000..d0fa1f95226d9
--- /dev/null
+++ b/ConfigGenerator/GlobalConfig.cs
@@ -0,0 +1,154 @@
+/*
+ _ _ _ ____ _ _____
+ / \ _ __ ___ | |__ (_)/ ___| | |_ ___ __ _ _ __ ___ | ___|__ _ _ __ _ __ ___
+ / _ \ | '__|/ __|| '_ \ | |\___ \ | __|/ _ \ / _` || '_ ` _ \ | |_ / _` || '__|| '_ ` _ \
+ / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
+/_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
+
+ Copyright 2015-2016 Łukasz "JustArchi" Domeradzki
+ Contact: JustArchi@JustArchi.net
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+*/
+
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Net.Sockets;
+
+namespace ConfigGenerator {
+ internal sealed class GlobalConfig {
+ internal enum EUpdateChannel : byte {
+ Unknown,
+ Stable,
+ Experimental
+ }
+
+ // This is hardcoded blacklist which should not be possible to change
+ internal static readonly HashSet GlobalBlacklist = new HashSet { 267420, 303700, 335590, 368020, 425280 };
+
+ [JsonProperty(Required = Required.DisallowNull)]
+ public bool Debug { get; set; } = false;
+
+ [JsonProperty(Required = Required.DisallowNull)]
+ public bool AutoUpdates { get; set; } = true;
+
+ [JsonProperty(Required = Required.DisallowNull)]
+ public EUpdateChannel UpdateChannel { get; set; } = EUpdateChannel.Stable;
+
+ [JsonProperty(Required = Required.DisallowNull)]
+ public ProtocolType SteamProtocol { get; set; } = ProtocolType.Tcp;
+
+ [JsonProperty(Required = Required.DisallowNull)]
+ public ulong SteamOwnerID { get; set; } = 0;
+
+ [JsonProperty(Required = Required.DisallowNull)]
+ public byte MaxFarmingTime { get; set; } = 10;
+
+ [JsonProperty(Required = Required.DisallowNull)]
+ public byte IdleFarmingPeriod { get; set; } = 3;
+
+ [JsonProperty(Required = Required.DisallowNull)]
+ public byte FarmingDelay { get; set; } = 5;
+
+ [JsonProperty(Required = Required.DisallowNull)]
+ public byte AccountPlayingDelay { get; set; } = 5;
+
+ [JsonProperty(Required = Required.DisallowNull)]
+ public byte LoginLimiterDelay { get; set; } = 7;
+
+ [JsonProperty(Required = Required.DisallowNull)]
+ public byte InventoryLimiterDelay { get; set; } = 3;
+
+ [JsonProperty(Required = Required.DisallowNull)]
+ public bool ForceHttp { get; set; } = false;
+
+ [JsonProperty(Required = Required.DisallowNull)]
+ public byte HttpTimeout { get; set; } = 60;
+
+ [JsonProperty(Required = Required.DisallowNull)]
+ public string WCFHostname { get; set; } = "localhost";
+
+ [JsonProperty(Required = Required.DisallowNull)]
+ public ushort WCFPort { get; set; } = 1242;
+
+ [JsonProperty(Required = Required.DisallowNull)]
+ public bool LogToFile { get; set; } = true;
+
+ [JsonProperty(Required = Required.DisallowNull)]
+ public bool Statistics { get; set; } = true;
+
+ // TODO: Please remove me immediately after https://github.com/SteamRE/SteamKit/issues/254 gets fixed
+ [JsonProperty(Required = Required.DisallowNull)]
+ public bool HackIgnoreMachineID { get; set; } = false;
+
+ [JsonProperty(Required = Required.DisallowNull)]
+ public List Blacklist { get; set; } = new List();
+
+ private string FilePath;
+
+ internal static GlobalConfig Load(string filePath) {
+ if (string.IsNullOrEmpty(filePath)) {
+ return null;
+ }
+
+ if (!File.Exists(filePath)) {
+ return new GlobalConfig(filePath);
+ }
+
+ GlobalConfig globalConfig;
+ try {
+ globalConfig = JsonConvert.DeserializeObject(File.ReadAllText(filePath));
+ } catch (Exception e) {
+ Logging.LogGenericException(e);
+ return null;
+ }
+
+ globalConfig.FilePath = filePath;
+
+ // SK2 supports only TCP and UDP steam protocols
+ // Make sure that user can't screw this up
+ switch (globalConfig.SteamProtocol) {
+ case ProtocolType.Tcp:
+ case ProtocolType.Udp:
+ break;
+ default:
+ Logging.LogGenericWarning("Configured SteamProtocol is invalid: " + globalConfig.SteamProtocol + ", default TCP protocol will be used instead");
+ globalConfig.SteamProtocol = ProtocolType.Tcp;
+ break;
+ }
+
+ return globalConfig;
+ }
+
+ internal void Save() {
+ lock (FilePath) {
+ try {
+ File.WriteAllText(FilePath, JsonConvert.SerializeObject(this, Formatting.Indented));
+ } catch (Exception e) {
+ Logging.LogGenericException(e);
+ }
+ }
+ }
+
+ // This constructor is used only by deserializer
+ private GlobalConfig() { }
+
+ private GlobalConfig(string filePath) {
+ FilePath = filePath;
+ Blacklist.AddRange(GlobalBlacklist);
+ }
+ }
+}
diff --git a/ConfigGenerator/GlobalConfigPage.cs b/ConfigGenerator/GlobalConfigPage.cs
new file mode 100644
index 0000000000000..97d902ae38ca9
--- /dev/null
+++ b/ConfigGenerator/GlobalConfigPage.cs
@@ -0,0 +1,51 @@
+using System.IO;
+using System.Windows.Forms;
+
+namespace ConfigGenerator {
+ internal sealed class GlobalConfigPage : TabPage {
+
+ internal GlobalConfig GlobalConfig { get; private set; }
+
+ private EnhancedPropertyGrid EnhancedPropertyGrid;
+
+ internal GlobalConfigPage(string filePath) : base() {
+ if (string.IsNullOrEmpty(filePath)) {
+ return;
+ }
+
+ GlobalConfig = GlobalConfig.Load(filePath);
+ if (GlobalConfig == null) {
+ Logging.LogNullError("GlobalConfig");
+ return;
+ }
+
+ Text = Path.GetFileNameWithoutExtension(filePath);
+
+ EnhancedPropertyGrid = new EnhancedPropertyGrid(GlobalConfig);
+ Controls.Add(EnhancedPropertyGrid);
+
+ Panel panel = new Panel() {
+ Height = 20,
+ Dock = DockStyle.Bottom,
+ };
+
+ panel.Controls.Add(new Button() {
+ Dock = DockStyle.Left,
+ Text = "Load"
+ });
+
+ panel.Controls.Add(new Button() {
+ Dock = DockStyle.Right,
+ Text = "Save"
+ });
+
+ Controls.Add(panel);
+ }
+
+ private void InitializeComponent() {
+ this.SuspendLayout();
+ this.ResumeLayout(false);
+
+ }
+ }
+}
diff --git a/ConfigGenerator/GlobalConfigPage.resx b/ConfigGenerator/GlobalConfigPage.resx
new file mode 100644
index 0000000000000..e5858cc294d2f
--- /dev/null
+++ b/ConfigGenerator/GlobalConfigPage.resx
@@ -0,0 +1,123 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ False
+
+
\ No newline at end of file
diff --git a/ConfigGenerator/Logging.cs b/ConfigGenerator/Logging.cs
new file mode 100644
index 0000000000000..2fe524aba8004
--- /dev/null
+++ b/ConfigGenerator/Logging.cs
@@ -0,0 +1,93 @@
+/*
+ _ _ _ ____ _ _____
+ / \ _ __ ___ | |__ (_)/ ___| | |_ ___ __ _ _ __ ___ | ___|__ _ _ __ _ __ ___
+ / _ \ | '__|/ __|| '_ \ | |\___ \ | __|/ _ \ / _` || '_ ` _ \ | |_ / _` || '__|| '_ ` _ \
+ / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | |
+/_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_|
+
+ Copyright 2015-2016 Łukasz "JustArchi" Domeradzki
+ Contact: JustArchi@JustArchi.net
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+*/
+
+using System;
+using System.Diagnostics;
+using System.Runtime.CompilerServices;
+using System.Windows.Forms;
+
+namespace ConfigGenerator {
+ internal static class Logging {
+ internal static void LogGenericWTF(string message, [CallerMemberName] string previousMethodName = "") {
+ if (string.IsNullOrEmpty(message)) {
+ return;
+ }
+
+ MessageBox.Show(previousMethodName + "() " + message, "WTF", MessageBoxButtons.OK, MessageBoxIcon.Error);
+ }
+
+ internal static void LogGenericError(string message, [CallerMemberName] string previousMethodName = "") {
+ if (string.IsNullOrEmpty(message)) {
+ return;
+ }
+
+ MessageBox.Show(previousMethodName + "() " + message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
+ }
+
+ internal static void LogGenericException(Exception exception, [CallerMemberName] string previousMethodName = "") {
+ if (exception == null) {
+ return;
+ }
+
+ MessageBox.Show(previousMethodName + "() " + exception.Message + Environment.NewLine + exception.StackTrace, "Exception", MessageBoxButtons.OK, MessageBoxIcon.Error);
+
+ if (exception.InnerException != null) {
+ LogGenericException(exception.InnerException, previousMethodName);
+ }
+ }
+
+ internal static void LogGenericWarning(string message, [CallerMemberName] string previousMethodName = "") {
+ if (string.IsNullOrEmpty(message)) {
+ return;
+ }
+
+ MessageBox.Show(previousMethodName + "() " + message, "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
+ }
+
+ internal static void LogGenericInfo(string message, [CallerMemberName] string previousMethodName = "") {
+ if (string.IsNullOrEmpty(message)) {
+ return;
+ }
+
+ MessageBox.Show(previousMethodName + "() " + message, "Info", MessageBoxButtons.OK, MessageBoxIcon.Information);
+ }
+
+ internal static void LogNullError(string nullObjectName, [CallerMemberName] string previousMethodName = "") {
+ if (string.IsNullOrEmpty(nullObjectName)) {
+ return;
+ }
+
+ LogGenericError(nullObjectName + " is null!", previousMethodName);
+ }
+
+ [Conditional("DEBUG")]
+ internal static void LogGenericDebug(string message, [CallerMemberName] string previousMethodName = "") {
+ if (string.IsNullOrEmpty(message)) {
+ return;
+ }
+
+ MessageBox.Show(previousMethodName + "() " + message, "Debug", MessageBoxButtons.OK, MessageBoxIcon.Information);
+ }
+ }
+}
diff --git a/ConfigGenerator/MainForm.Designer.cs b/ConfigGenerator/MainForm.Designer.cs
new file mode 100644
index 0000000000000..18330a47ebd56
--- /dev/null
+++ b/ConfigGenerator/MainForm.Designer.cs
@@ -0,0 +1,135 @@
+namespace ConfigGenerator {
+ partial class MainForm {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing) {
+ if (disposing && (components != null)) {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent() {
+ this.MenuPanel = new System.Windows.Forms.MenuStrip();
+ this.FileMenu = new System.Windows.Forms.ToolStripMenuItem();
+ this.FileMenuHelp = new System.Windows.Forms.ToolStripMenuItem();
+ this.BotMenu = new System.Windows.Forms.ToolStripMenuItem();
+ this.BotMenuNew = new System.Windows.Forms.ToolStripMenuItem();
+ this.BotMenuDelete = new System.Windows.Forms.ToolStripMenuItem();
+ this.MainTab = new System.Windows.Forms.TabControl();
+ this.FileMenuExit = new System.Windows.Forms.ToolStripMenuItem();
+ this.MenuPanel.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // MenuPanel
+ //
+ this.MenuPanel.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
+ this.FileMenu,
+ this.BotMenu});
+ this.MenuPanel.Location = new System.Drawing.Point(0, 0);
+ this.MenuPanel.Name = "MenuPanel";
+ this.MenuPanel.Size = new System.Drawing.Size(784, 24);
+ this.MenuPanel.TabIndex = 0;
+ this.MenuPanel.Text = "menuStrip1";
+ //
+ // FileMenu
+ //
+ this.FileMenu.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
+ this.FileMenuHelp,
+ this.FileMenuExit});
+ this.FileMenu.Name = "FileMenu";
+ this.FileMenu.Size = new System.Drawing.Size(37, 20);
+ this.FileMenu.Text = "File";
+ //
+ // FileMenuHelp
+ //
+ this.FileMenuHelp.Name = "FileMenuHelp";
+ this.FileMenuHelp.Size = new System.Drawing.Size(152, 22);
+ this.FileMenuHelp.Text = "Help";
+ this.FileMenuHelp.Click += new System.EventHandler(this.FileMenuHelp_Click);
+ //
+ // BotMenu
+ //
+ this.BotMenu.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
+ this.BotMenuNew,
+ this.BotMenuDelete});
+ this.BotMenu.Name = "BotMenu";
+ this.BotMenu.Size = new System.Drawing.Size(37, 20);
+ this.BotMenu.Text = "Bot";
+ //
+ // BotMenuNew
+ //
+ this.BotMenuNew.Name = "BotMenuNew";
+ this.BotMenuNew.Size = new System.Drawing.Size(107, 22);
+ this.BotMenuNew.Text = "New";
+ this.BotMenuNew.Click += new System.EventHandler(this.BotMenuNew_Click);
+ //
+ // BotMenuDelete
+ //
+ this.BotMenuDelete.Name = "BotMenuDelete";
+ this.BotMenuDelete.Size = new System.Drawing.Size(107, 22);
+ this.BotMenuDelete.Text = "Delete";
+ this.BotMenuDelete.Click += new System.EventHandler(this.BotMenuDelete_Click);
+ //
+ // MainTab
+ //
+ this.MainTab.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+ | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.MainTab.Location = new System.Drawing.Point(12, 27);
+ this.MainTab.Name = "MainTab";
+ this.MainTab.SelectedIndex = 0;
+ this.MainTab.Size = new System.Drawing.Size(760, 522);
+ this.MainTab.TabIndex = 1;
+ //
+ // FileMenuExit
+ //
+ this.FileMenuExit.Name = "FileMenuExit";
+ this.FileMenuExit.Size = new System.Drawing.Size(152, 22);
+ this.FileMenuExit.Text = "Exit";
+ this.FileMenuExit.Click += new System.EventHandler(this.FileMenuExit_Click);
+ //
+ // MainForm
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(784, 561);
+ this.Controls.Add(this.MainTab);
+ this.Controls.Add(this.MenuPanel);
+ this.MainMenuStrip = this.MenuPanel;
+ this.Name = "MainForm";
+ this.Text = "Form1";
+ this.Load += new System.EventHandler(this.MainForm_Load);
+ this.MenuPanel.ResumeLayout(false);
+ this.MenuPanel.PerformLayout();
+ this.ResumeLayout(false);
+ this.PerformLayout();
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.MenuStrip MenuPanel;
+ private System.Windows.Forms.ToolStripMenuItem BotMenu;
+ private System.Windows.Forms.ToolStripMenuItem BotMenuNew;
+ private System.Windows.Forms.ToolStripMenuItem BotMenuDelete;
+ private System.Windows.Forms.TabControl MainTab;
+ private System.Windows.Forms.ToolStripMenuItem FileMenu;
+ private System.Windows.Forms.ToolStripMenuItem FileMenuHelp;
+ private System.Windows.Forms.ToolStripMenuItem FileMenuExit;
+ }
+}
+
diff --git a/ConfigGenerator/MainForm.cs b/ConfigGenerator/MainForm.cs
new file mode 100644
index 0000000000000..300b229078b60
--- /dev/null
+++ b/ConfigGenerator/MainForm.cs
@@ -0,0 +1,52 @@
+using System;
+using System.Diagnostics;
+using System.IO;
+using System.Windows.Forms;
+
+namespace ConfigGenerator {
+ public partial class MainForm : Form {
+ public MainForm() {
+ InitializeComponent();
+ }
+
+ private void BotMenuNew_Click(object sender, EventArgs e) {
+ if (sender == null || e == null) {
+ return;
+ }
+
+ Logging.LogGenericError("This option is not ready yet!");
+ }
+
+ private void BotMenuDelete_Click(object sender, EventArgs e) {
+ if (sender == null || e == null) {
+ return;
+ }
+
+ Logging.LogGenericError("This option is not ready yet!");
+ }
+
+ private void FileMenuHelp_Click(object sender, EventArgs e) {
+ if (sender == null || e == null) {
+ return;
+ }
+
+ Process.Start("https://github.com/JustArchi/ArchiSteamFarm/wiki/Configuration");
+ }
+
+ private void FileMenuExit_Click(object sender, EventArgs e) {
+ if (sender == null || e == null) {
+ return;
+ }
+
+ Application.Exit();
+ }
+
+ private void MainForm_Load(object sender, EventArgs e) {
+ if (sender == null || e == null) {
+ return;
+ }
+
+ MainTab.TabPages.Add(new GlobalConfigPage(Path.Combine(Program.ConfigDirectory, Program.GlobalConfigFile)));
+ }
+ }
+}
diff --git a/ConfigGenerator/MainForm.resx b/ConfigGenerator/MainForm.resx
new file mode 100644
index 0000000000000..07ba40be52357
--- /dev/null
+++ b/ConfigGenerator/MainForm.resx
@@ -0,0 +1,123 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ 17, 17
+
+
\ No newline at end of file
diff --git a/ConfigGenerator/Program.cs b/ConfigGenerator/Program.cs
new file mode 100644
index 0000000000000..c09b6a9ae0c12
--- /dev/null
+++ b/ConfigGenerator/Program.cs
@@ -0,0 +1,77 @@
+using System;
+using System.IO;
+using System.Reflection;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+namespace ConfigGenerator {
+ internal static class Program {
+ internal const string ASF = "ASF";
+ internal const string ConfigDirectory = "config";
+ internal const string GlobalConfigFile = ASF + ".json";
+
+ private const string ASFDirectory = "ArchiSteamFarm";
+
+ private static readonly Assembly Assembly = Assembly.GetExecutingAssembly();
+ private static readonly string ExecutableFile = Assembly.Location;
+ private static readonly string ExecutableName = Path.GetFileName(ExecutableFile);
+ private static readonly string ExecutableDirectory = Path.GetDirectoryName(ExecutableFile);
+
+ ///
+ /// The main entry point for the application.
+ ///
+ [STAThread]
+ private static void Main() {
+ Init();
+ Application.EnableVisualStyles();
+ Application.SetCompatibleTextRenderingDefault(false);
+ Application.Run(new MainForm());
+ }
+
+ private static void Init() {
+ AppDomain.CurrentDomain.UnhandledException += UnhandledExceptionHandler;
+ TaskScheduler.UnobservedTaskException += UnobservedTaskExceptionHandler;
+
+ Directory.SetCurrentDirectory(ExecutableDirectory);
+
+ // Allow loading configs from source tree if it's a debug build
+ if (Debugging.IsDebugBuild) {
+
+ // Common structure is bin/(x64/)Debug/ArchiSteamFarm.exe, so we allow up to 4 directories up
+ for (byte i = 0; i < 4; i++) {
+ Directory.SetCurrentDirectory("..");
+ if (Directory.Exists(ASFDirectory)) {
+ Directory.SetCurrentDirectory(ASFDirectory);
+ break;
+ }
+ }
+
+ // If config directory doesn't exist after our adjustment, abort all of that
+ if (!Directory.Exists(ConfigDirectory)) {
+ Directory.SetCurrentDirectory(ExecutableDirectory);
+ }
+ }
+
+ if (!Directory.Exists(ConfigDirectory)) {
+ Logging.LogGenericError("Config directory could not be found!");
+ Application.Exit();
+ }
+ }
+
+ private static void UnhandledExceptionHandler(object sender, UnhandledExceptionEventArgs args) {
+ if (sender == null || args == null) {
+ return;
+ }
+
+ Logging.LogGenericException((Exception) args.ExceptionObject);
+ }
+
+ private static void UnobservedTaskExceptionHandler(object sender, UnobservedTaskExceptionEventArgs args) {
+ if (sender == null || args == null) {
+ return;
+ }
+
+ Logging.LogGenericException(args.Exception);
+ }
+ }
+}
diff --git a/ConfigGenerator/Properties/AssemblyInfo.cs b/ConfigGenerator/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000000..43a73bcc5c2d7
--- /dev/null
+++ b/ConfigGenerator/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("ConfigGenerator")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("ConfigGenerator")]
+[assembly: AssemblyCopyright("Copyright © 2016")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("c3f6fe68-5e75-415e-bea1-1e7c16d6a433")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/ConfigGenerator/Properties/Resources.Designer.cs b/ConfigGenerator/Properties/Resources.Designer.cs
new file mode 100644
index 0000000000000..b27842b2b1e1a
--- /dev/null
+++ b/ConfigGenerator/Properties/Resources.Designer.cs
@@ -0,0 +1,62 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.42000
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace ConfigGenerator.Properties {
+
+
+ ///
+ /// A strongly-typed resource class, for looking up localized strings, etc.
+ ///
+ // This class was auto-generated by the StronglyTypedResourceBuilder
+ // class via a tool like ResGen or Visual Studio.
+ // To add or remove a member, edit your .ResX file then rerun ResGen
+ // with the /str option, or rebuild your VS project.
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ internal class Resources {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal Resources() {
+ }
+
+ ///
+ /// Returns the cached ResourceManager instance used by this class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Resources.ResourceManager ResourceManager {
+ get {
+ if ((resourceMan == null)) {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ConfigGenerator.Properties.Resources", typeof(Resources).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ ///
+ /// Overrides the current thread's CurrentUICulture property for all
+ /// resource lookups using this strongly typed resource class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Globalization.CultureInfo Culture {
+ get {
+ return resourceCulture;
+ }
+ set {
+ resourceCulture = value;
+ }
+ }
+ }
+}
diff --git a/ConfigGenerator/Properties/Resources.resx b/ConfigGenerator/Properties/Resources.resx
new file mode 100644
index 0000000000000..af7dbebbacef5
--- /dev/null
+++ b/ConfigGenerator/Properties/Resources.resx
@@ -0,0 +1,117 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/ConfigGenerator/Properties/Settings.Designer.cs b/ConfigGenerator/Properties/Settings.Designer.cs
new file mode 100644
index 0000000000000..2f1862a55ab1e
--- /dev/null
+++ b/ConfigGenerator/Properties/Settings.Designer.cs
@@ -0,0 +1,26 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.42000
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace ConfigGenerator.Properties {
+
+
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
+ internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
+
+ private static Settings defaultInstance = ((Settings) (global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
+
+ public static Settings Default {
+ get {
+ return defaultInstance;
+ }
+ }
+ }
+}
diff --git a/ConfigGenerator/Properties/Settings.settings b/ConfigGenerator/Properties/Settings.settings
new file mode 100644
index 0000000000000..39645652af629
--- /dev/null
+++ b/ConfigGenerator/Properties/Settings.settings
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/ConfigGenerator/packages.config b/ConfigGenerator/packages.config
new file mode 100644
index 0000000000000..db6731103e679
--- /dev/null
+++ b/ConfigGenerator/packages.config
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file