diff --git a/ArchiSteamFarm/ASF.cs b/ArchiSteamFarm/ASF.cs
index fe08f7060..79c4ac2bc 100644
--- a/ArchiSteamFarm/ASF.cs
+++ b/ArchiSteamFarm/ASF.cs
@@ -511,7 +511,7 @@ namespace ArchiSteamFarm {
}
private static async Task RestartOrExit() {
- if (!Program.ServiceMode && Program.GlobalConfig.AutoRestart) {
+ if (Program.RestartAllowed && Program.GlobalConfig.AutoRestart) {
ArchiLogger.LogGenericInfo(Strings.Restarting);
await Task.Delay(5000).ConfigureAwait(false);
await Program.Restart().ConfigureAwait(false);
diff --git a/ArchiSteamFarm/Events.cs b/ArchiSteamFarm/Events.cs
index f430a440f..7a7b8e389 100644
--- a/ArchiSteamFarm/Events.cs
+++ b/ArchiSteamFarm/Events.cs
@@ -26,7 +26,7 @@ using ArchiSteamFarm.Localization;
namespace ArchiSteamFarm {
internal static class Events {
internal static async Task OnBotShutdown() {
- if (Program.ServiceMode || IPC.IsRunning || Bot.Bots.Values.Any(bot => bot.KeepRunning)) {
+ if (Program.ProcessRequired || Bot.Bots.Values.Any(bot => bot.KeepRunning)) {
return;
}
@@ -35,7 +35,7 @@ namespace ArchiSteamFarm {
// We give user extra 5 seconds for eventual config changes
await Task.Delay(5000).ConfigureAwait(false);
- if (Program.ServiceMode || IPC.IsRunning || Bot.Bots.Values.Any(bot => bot.KeepRunning)) {
+ if (Program.ProcessRequired || Bot.Bots.Values.Any(bot => bot.KeepRunning)) {
return;
}
diff --git a/ArchiSteamFarm/GlobalConfig.cs b/ArchiSteamFarm/GlobalConfig.cs
index b306cb5f8..144f80711 100644
--- a/ArchiSteamFarm/GlobalConfig.cs
+++ b/ArchiSteamFarm/GlobalConfig.cs
@@ -81,6 +81,9 @@ namespace ArchiSteamFarm {
[JsonProperty(Required = Required.DisallowNull)]
internal readonly byte InventoryLimiterDelay = 3;
+ [JsonProperty(Required = Required.DisallowNull)]
+ internal readonly bool IPC;
+
[JsonProperty]
internal readonly string IPCPassword;
diff --git a/ArchiSteamFarm/IPC.cs b/ArchiSteamFarm/IPC.cs
index be5f9faee..43e60bd13 100644
--- a/ArchiSteamFarm/IPC.cs
+++ b/ArchiSteamFarm/IPC.cs
@@ -110,6 +110,10 @@ namespace ArchiSteamFarm {
return;
}
+ if (IsListening) {
+ return;
+ }
+
HttpListener = new HttpListener { IgnoreWriteExceptions = true };
try {
@@ -141,6 +145,11 @@ namespace ArchiSteamFarm {
}
internal static void Stop() {
+ if (!HttpListener.IsSupported) {
+ ASF.ArchiLogger.LogGenericError(string.Format(Strings.WarningFailedWithError, "!HttpListener.IsSupported"));
+ return;
+ }
+
if (!IsListening) {
return;
}
diff --git a/ArchiSteamFarm/Localization/Strings.Designer.cs b/ArchiSteamFarm/Localization/Strings.Designer.cs
index baf477242..6c263515a 100644
--- a/ArchiSteamFarm/Localization/Strings.Designer.cs
+++ b/ArchiSteamFarm/Localization/Strings.Designer.cs
@@ -1386,6 +1386,15 @@ namespace ArchiSteamFarm.Localization {
}
}
+ ///
+ /// Wyszukuje zlokalizowany ciąg podobny do ciągu Usage of {0} is deprecated and will be removed in future versions of the program. Please use {1} instead..
+ ///
+ internal static string WarningDeprecated {
+ get {
+ return ResourceManager.GetString("WarningDeprecated", resourceCulture);
+ }
+ }
+
///
/// Wyszukuje zlokalizowany ciąg podobny do ciągu Failed!.
///
diff --git a/ArchiSteamFarm/Localization/Strings.resx b/ArchiSteamFarm/Localization/Strings.resx
index 905b4eb75..041a93b0d 100644
--- a/ArchiSteamFarm/Localization/Strings.resx
+++ b/ArchiSteamFarm/Localization/Strings.resx
@@ -657,4 +657,8 @@ StackTrace:
Refreshing packages data...
+
+ Usage of {0} is deprecated and will be removed in future versions of the program. Please use {1} instead.
+ {0} will be replaced by the name of deprecated property (such as argument, config property or likewise), {1} will be replaced by the name of valid replacement (such as another argument or config property)
+
\ No newline at end of file
diff --git a/ArchiSteamFarm/OS.cs b/ArchiSteamFarm/OS.cs
index 61b2030ca..fd96ab18d 100644
--- a/ArchiSteamFarm/OS.cs
+++ b/ArchiSteamFarm/OS.cs
@@ -27,11 +27,11 @@ using ArchiSteamFarm.Localization;
namespace ArchiSteamFarm {
internal static class OS {
- internal static void Init(bool service) {
+ internal static void Init(bool systemRequired) {
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) {
DisableQuickEditMode();
- if (service) {
+ if (systemRequired) {
KeepWindowsSystemActive();
}
}
diff --git a/ArchiSteamFarm/Program.cs b/ArchiSteamFarm/Program.cs
index 5739c95f9..af3b4bf7d 100644
--- a/ArchiSteamFarm/Program.cs
+++ b/ArchiSteamFarm/Program.cs
@@ -46,7 +46,8 @@ namespace ArchiSteamFarm {
internal static GlobalConfig GlobalConfig { get; private set; }
internal static GlobalDatabase GlobalDatabase { get; private set; }
- internal static bool ServiceMode { get; private set; }
+ internal static bool ProcessRequired { get; private set; }
+ internal static bool RestartAllowed { get; private set; } = true;
internal static WebBrowser WebBrowser { get; private set; }
private static readonly object ConsoleLock = new object();
@@ -54,7 +55,7 @@ namespace ArchiSteamFarm {
// We need to keep this one assigned and not calculated on-demand
private static readonly string ProcessFileName = Process.GetCurrentProcess().MainModule.FileName;
- private static readonly TaskCompletionSource ShutdownResetEvent = new TaskCompletionSource();
+ private static readonly TaskCompletionSource ShutdownResetEvent = new TaskCompletionSource();
private static bool ShutdownSequenceInitialized;
@@ -63,7 +64,7 @@ namespace ArchiSteamFarm {
ASF.ArchiLogger.LogGenericError(Strings.ErrorExitingWithNonZeroErrorCode);
}
- await Shutdown().ConfigureAwait(false);
+ await Shutdown(exitCode).ConfigureAwait(false);
Environment.Exit(exitCode);
}
@@ -147,7 +148,7 @@ namespace ArchiSteamFarm {
// Give new process some time to take over the window (if needed)
await Task.Delay(2000).ConfigureAwait(false);
- ShutdownResetEvent.TrySetResult(true);
+ ShutdownResetEvent.TrySetResult(0);
Environment.Exit(0);
}
@@ -192,25 +193,6 @@ namespace ArchiSteamFarm {
await InitGlobalConfigAndLanguage().ConfigureAwait(false);
await InitGlobalDatabaseAndServices().ConfigureAwait(false);
- // If debugging is on, we prepare debug directory prior to running
- if (GlobalConfig.Debug) {
- Logging.EnableTraceLogging();
-
- if (Directory.Exists(SharedInfo.DebugDirectory)) {
- try {
- Directory.Delete(SharedInfo.DebugDirectory, true);
- await Task.Delay(1000).ConfigureAwait(false); // Dirty workaround giving Windows some time to sync
- } catch (IOException e) {
- ASF.ArchiLogger.LogGenericException(e);
- }
- }
-
- Directory.CreateDirectory(SharedInfo.DebugDirectory);
-
- DebugLog.AddListener(new Debugging.DebugListener());
- DebugLog.Enabled = true;
- }
-
// Parse post-init args
if (args != null) {
ParsePostInitArgs(args);
@@ -340,10 +322,31 @@ namespace ArchiSteamFarm {
return;
}
- OS.Init(ServiceMode || GlobalConfig.Headless);
- WebBrowser.Init();
+ // If debugging is on, we prepare debug directory prior to running
+ if (GlobalConfig.Debug) {
+ Logging.EnableTraceLogging();
+ if (Directory.Exists(SharedInfo.DebugDirectory)) {
+ try {
+ Directory.Delete(SharedInfo.DebugDirectory, true);
+ await Task.Delay(1000).ConfigureAwait(false); // Dirty workaround giving Windows some time to sync
+ } catch (IOException e) {
+ ASF.ArchiLogger.LogGenericException(e);
+ }
+ }
+
+ Directory.CreateDirectory(SharedInfo.DebugDirectory);
+
+ DebugLog.AddListener(new Debugging.DebugListener());
+ DebugLog.Enabled = true;
+ }
+
+ WebBrowser.Init();
WebBrowser = new WebBrowser(ASF.ArchiLogger, true);
+
+ if (GlobalConfig.IPC && (GlobalConfig.IPCPrefixes.Count > 0)) {
+ IPC.Start(GlobalConfig.IPCPrefixes);
+ }
}
private static async Task InitShutdownSequence() {
@@ -386,12 +389,12 @@ namespace ArchiSteamFarm {
return true;
}
- private static async Task Main(string[] args) {
+ private static async Task Main(string[] args) {
// Initialize
await Init(args).ConfigureAwait(false);
// Wait for shutdown event
- await ShutdownResetEvent.Task.ConfigureAwait(false);
+ return await ShutdownResetEvent.Task.ConfigureAwait(false);
}
private static async void OnProcessExit(object sender, EventArgs e) => await Shutdown().ConfigureAwait(false);
@@ -426,57 +429,51 @@ namespace ArchiSteamFarm {
}
bool cryptKeyNext = false;
+ bool systemRequired = false;
foreach (string arg in args) {
switch (arg) {
- case "":
- break;
- case "--path":
- if (cryptKeyNext) {
- goto default;
- }
-
- // Not handled in PostInit
- break;
- case "--cryptkey":
- if (cryptKeyNext) {
- goto default;
- }
-
+ case "--cryptkey" when !cryptKeyNext:
cryptKeyNext = true;
break;
- case "--server":
- if (cryptKeyNext) {
- goto default;
- }
-
- if (GlobalConfig.IPCPrefixes.Count == 0) {
- ASF.ArchiLogger.LogGenericError(string.Format(Strings.ErrorIsEmpty, nameof(GlobalConfig.IPCPrefixes)));
- break;
- }
-
- IPC.Start(GlobalConfig.IPCPrefixes);
+ case "--no-restart" when !cryptKeyNext:
+ RestartAllowed = false;
break;
- case "--service":
- if (cryptKeyNext) {
- goto default;
+ case "--process-required" when !cryptKeyNext:
+ ProcessRequired = true;
+ break;
+ case "--server" when !cryptKeyNext:
+ // TODO: Deprecate further in the next version
+ ASF.ArchiLogger.LogGenericWarning(string.Format(Strings.WarningDeprecated, "--server", "GlobalConfig.IPC"));
+
+ if (GlobalConfig.IPCPrefixes.Count > 0) {
+ IPC.Start(GlobalConfig.IPCPrefixes);
}
- ServiceMode = true;
+ break;
+ case "--service" when !cryptKeyNext:
+ // TODO: Deprecate further in the next version
+ ASF.ArchiLogger.LogGenericWarning(string.Format(Strings.WarningDeprecated, "--service", "--no-restart --process-required --system-required"));
+ RestartAllowed = false;
+ ProcessRequired = true;
+ systemRequired = true;
+ break;
+ case "--system-required" when !cryptKeyNext:
+ systemRequired = true;
break;
default:
if (cryptKeyNext) {
cryptKeyNext = false;
HandleCryptKeyArgument(arg);
- } else if (arg.StartsWith("--", StringComparison.Ordinal)) {
- if (arg.StartsWith("--cryptkey=", StringComparison.Ordinal) && (arg.Length > 11)) {
- HandleCryptKeyArgument(arg.Substring(11));
- }
+ } else if ((arg.Length > 11) && arg.StartsWith("--cryptkey=", StringComparison.Ordinal)) {
+ HandleCryptKeyArgument(arg.Substring(11));
}
break;
}
}
+
+ OS.Init(systemRequired);
}
private static void ParsePreInitArgs(IReadOnlyCollection args) {
@@ -489,32 +486,15 @@ namespace ArchiSteamFarm {
foreach (string arg in args) {
switch (arg) {
- case "":
- break;
- case "--cryptkey":
- case "--server":
- case "--service":
- if (pathNext) {
- goto default;
- }
-
- // Not handled in PreInit
- break;
- case "--path":
- if (pathNext) {
- goto default;
- }
-
+ case "--path" when !pathNext:
pathNext = true;
break;
default:
if (pathNext) {
pathNext = false;
HandlePathArgument(arg);
- } else if (arg.StartsWith("--", StringComparison.Ordinal)) {
- if (arg.StartsWith("--path=", StringComparison.Ordinal) && (arg.Length > 7)) {
- HandlePathArgument(arg.Substring(7));
- }
+ } else if ((arg.Length > 7) && arg.StartsWith("--path=", StringComparison.Ordinal)) {
+ HandlePathArgument(arg.Substring(7));
}
break;
@@ -522,12 +502,12 @@ namespace ArchiSteamFarm {
}
}
- private static async Task Shutdown() {
+ private static async Task Shutdown(byte exitCode = 0) {
if (!await InitShutdownSequence().ConfigureAwait(false)) {
return;
}
- ShutdownResetEvent.TrySetResult(true);
+ ShutdownResetEvent.TrySetResult(exitCode);
}
}
}
\ No newline at end of file
diff --git a/ArchiSteamFarm/config/ASF.json b/ArchiSteamFarm/config/ASF.json
index 70df93b78..b06ca4bdd 100644
--- a/ArchiSteamFarm/config/ASF.json
+++ b/ArchiSteamFarm/config/ASF.json
@@ -12,6 +12,7 @@
"Headless": false,
"IdleFarmingPeriod": 8,
"InventoryLimiterDelay": 3,
+ "IPC": false,
"IPCPassword": null,
"IPCPrefixes": [
"http://127.0.0.1:1242/"
diff --git a/ArchiSteamFarm/scripts/generic/ArchiSteamFarm-Service.sh b/ArchiSteamFarm/scripts/generic/ArchiSteamFarm-Service.sh
index f0cd8036e..06c0e3336 100755
--- a/ArchiSteamFarm/scripts/generic/ArchiSteamFarm-Service.sh
+++ b/ArchiSteamFarm/scripts/generic/ArchiSteamFarm-Service.sh
@@ -17,7 +17,6 @@ PARSE_ARG() {
BINARY_ARGS+=("$1")
case "$1" in
- --cryptkey|--server|--service) ;;
--path) PATH_NEXT=1 ;;
--path=*) cd "$(echo "$1" | cut -d '=' -f 2-)" ;;
*)
diff --git a/ArchiSteamFarm/scripts/generic/ArchiSteamFarm.sh b/ArchiSteamFarm/scripts/generic/ArchiSteamFarm.sh
index e541cfe09..34505367f 100755
--- a/ArchiSteamFarm/scripts/generic/ArchiSteamFarm.sh
+++ b/ArchiSteamFarm/scripts/generic/ArchiSteamFarm.sh
@@ -17,7 +17,6 @@ PARSE_ARG() {
BINARY_ARGS+=("$1")
case "$1" in
- --cryptkey|--server|--service) ;;
--path) PATH_NEXT=1 ;;
--path=*) cd "$(echo "$1" | cut -d '=' -f 2-)" ;;
*)
diff --git a/Dockerfile.Service.arm b/Dockerfile.Service.arm
index 7e2b4b86b..16fb9a8c9 100644
--- a/Dockerfile.Service.arm
+++ b/Dockerfile.Service.arm
@@ -10,4 +10,4 @@ LABEL maintainer="JustArchi "
EXPOSE 1242
WORKDIR /app
COPY --from=build-env /app/ArchiSteamFarm/out ./
-ENTRYPOINT ["./ArchiSteamFarm-Service.sh", "--service"]
+ENTRYPOINT ["./ArchiSteamFarm-Service.sh", "--no-restart", "--process-required", "--system-required"]
diff --git a/Dockerfile.Service.x64 b/Dockerfile.Service.x64
index a0f4d8ccc..e900818e3 100644
--- a/Dockerfile.Service.x64
+++ b/Dockerfile.Service.x64
@@ -10,4 +10,4 @@ LABEL maintainer="JustArchi "
EXPOSE 1242
WORKDIR /app
COPY --from=build-env /app/ArchiSteamFarm/out ./
-ENTRYPOINT ["./ArchiSteamFarm-Service.sh", "--service"]
+ENTRYPOINT ["./ArchiSteamFarm-Service.sh", "--no-restart", "--process-required", "--system-required"]
diff --git a/Dockerfile.arm b/Dockerfile.arm
index a59c8f568..01384dd85 100644
--- a/Dockerfile.arm
+++ b/Dockerfile.arm
@@ -10,4 +10,4 @@ LABEL maintainer="JustArchi "
EXPOSE 1242
WORKDIR /app
COPY --from=build-env /app/ArchiSteamFarm/out ./
-ENTRYPOINT ["./ArchiSteamFarm.sh", "--service"]
+ENTRYPOINT ["./ArchiSteamFarm.sh", "--no-restart", "--process-required", "--system-required"]
diff --git a/Dockerfile.x64 b/Dockerfile.x64
index 4f6481817..39889aad1 100644
--- a/Dockerfile.x64
+++ b/Dockerfile.x64
@@ -10,4 +10,4 @@ LABEL maintainer="JustArchi "
EXPOSE 1242
WORKDIR /app
COPY --from=build-env /app/ArchiSteamFarm/out ./
-ENTRYPOINT ["./ArchiSteamFarm.sh", "--service"]
+ENTRYPOINT ["./ArchiSteamFarm.sh", "--no-restart", "--process-required", "--system-required"]