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"]