LogGenericError() private method

private LogGenericError ( string message, [ previousMethodName = null ) : void
message string
previousMethodName [
return void
Example #1
0
        internal static string GetFilePath(EFileType fileType)
        {
            if (!Enum.IsDefined(typeof(EFileType), fileType))
            {
                ArchiLogger.LogNullError(nameof(fileType));

                return(null);
            }

            switch (fileType)
            {
            case EFileType.Config:

                return(Path.Combine(SharedInfo.ConfigDirectory, SharedInfo.GlobalConfigFileName));

            case EFileType.Database:

                return(Path.Combine(SharedInfo.ConfigDirectory, SharedInfo.GlobalDatabaseFileName));

            default:
                ArchiLogger.LogGenericError(string.Format(Strings.WarningUnknownValuePleaseReport, nameof(fileType), fileType));

                return(null);
            }
        }
Example #2
0
		private async Task<HttpResponseMessage> UrlRequest(string request, HttpMethod httpMethod, IEnumerable<KeyValuePair<string, string>> data = null, string referer = null) {
			if (string.IsNullOrEmpty(request) || (httpMethod == null)) {
				ArchiLogger.LogNullError(nameof(request) + " || " + nameof(httpMethod));
				return null;
			}

			if (request.StartsWith("https://", StringComparison.Ordinal) && Program.GlobalConfig.ForceHttp) {
				return null;
			}

			HttpResponseMessage responseMessage;
			using (HttpRequestMessage requestMessage = new HttpRequestMessage(httpMethod, request)) {
				if (data != null) {
					try {
						requestMessage.Content = new FormUrlEncodedContent(data);
					} catch (UriFormatException e) {
						ArchiLogger.LogGenericException(e);
						return null;
					}
				}

				if (!string.IsNullOrEmpty(referer)) {
					requestMessage.Headers.Referrer = new Uri(referer);
				}

				try {
					responseMessage = await HttpClient.SendAsync(requestMessage).ConfigureAwait(false);
				} catch (Exception e) {
					// This exception is really common, don't bother with it unless debug mode is enabled
					if (Debugging.IsDebugBuild || Program.GlobalConfig.Debug) {
						ArchiLogger.LogGenericException(e);
					}

					return null;
				}
			}

			if (responseMessage == null) {
				return null;
			}

			if (responseMessage.IsSuccessStatusCode) {
				return responseMessage;
			}

			if (Debugging.IsDebugBuild || Program.GlobalConfig.Debug) {
				ArchiLogger.LogGenericError("Request: " + request + " failed!");
				ArchiLogger.LogGenericError("Status code: " + responseMessage.StatusCode);
				ArchiLogger.LogGenericError("Content: " + Environment.NewLine + await responseMessage.Content.ReadAsStringAsync().ConfigureAwait(false));
			}

			responseMessage.Dispose();
			return null;
		}
Example #3
0
        private static void Init()
        {
            AppDomain.CurrentDomain.UnhandledException += UnhandledExceptionHandler;
            TaskScheduler.UnobservedTaskException      += UnobservedTaskExceptionHandler;

            Logging.InitCoreLoggers();

            if (!Runtime.IsRuntimeSupported)
            {
                ArchiLogger.LogGenericError("ASF detected unsupported runtime version, program might NOT run correctly in current environment. You're running it at your own risk!");
            }

            string homeDirectory = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);

            if (!string.IsNullOrEmpty(homeDirectory))
            {
                Directory.SetCurrentDirectory(homeDirectory);

                // 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(SharedInfo.ASFDirectory))
                        {
                            continue;
                        }

                        Directory.SetCurrentDirectory(SharedInfo.ASFDirectory);
                        break;
                    }

                    // If config directory doesn't exist after our adjustment, abort all of that
                    if (!Directory.Exists(SharedInfo.ConfigDirectory))
                    {
                        Directory.SetCurrentDirectory(homeDirectory);
                    }
                }
            }

            InitServices();

            // If debugging is on, we prepare debug directory prior to running
            if (GlobalConfig.Debug)
            {
                if (Directory.Exists(SharedInfo.DebugDirectory))
                {
                    Directory.Delete(SharedInfo.DebugDirectory, true);
                    Thread.Sleep(1000);                     // Dirty workaround giving Windows some time to sync
                }

                Directory.CreateDirectory(SharedInfo.DebugDirectory);

                DebugLog.AddListener(new Debugging.DebugListener());
                DebugLog.Enabled = true;
            }

            Logging.InitEnhancedLoggers();
        }
Example #4
0
        internal static async Task <Version> Update(bool updateOverride = false)
        {
            if (!SharedInfo.BuildInfo.CanUpdate || (Program.GlobalConfig.UpdateChannel == GlobalConfig.EUpdateChannel.None))
            {
                return(null);
            }

            await UpdateSemaphore.WaitAsync().ConfigureAwait(false);

            try {
                ArchiLogger.LogGenericInfo(Strings.UpdateCheckingNewVersion);

                // If backup directory from previous update exists, it's a good idea to purge it now
                string backupDirectory = Path.Combine(SharedInfo.HomeDirectory, SharedInfo.UpdateDirectory);

                if (Directory.Exists(backupDirectory))
                {
                    // It's entirely possible that old process is still running, wait a short moment for eventual cleanup
                    await Task.Delay(5000).ConfigureAwait(false);

                    try {
                        Directory.Delete(backupDirectory, true);
                    } catch (Exception e) {
                        ArchiLogger.LogGenericException(e);

                        return(null);
                    }
                }

                GitHub.ReleaseResponse releaseResponse = await GitHub.GetLatestRelease(Program.GlobalConfig.UpdateChannel == GlobalConfig.EUpdateChannel.Stable).ConfigureAwait(false);

                if (releaseResponse == null)
                {
                    ArchiLogger.LogGenericWarning(Strings.ErrorUpdateCheckFailed);

                    return(null);
                }

                if (string.IsNullOrEmpty(releaseResponse.Tag))
                {
                    ArchiLogger.LogGenericWarning(Strings.ErrorUpdateCheckFailed);

                    return(null);
                }

                Version newVersion = new Version(releaseResponse.Tag);

                ArchiLogger.LogGenericInfo(string.Format(Strings.UpdateVersionInfo, SharedInfo.Version, newVersion));

                if (SharedInfo.Version == newVersion)
                {
                    return(SharedInfo.Version);
                }

                if (SharedInfo.Version > newVersion)
                {
                    ArchiLogger.LogGenericWarning(Strings.WarningPreReleaseVersion);
                    await Task.Delay(15 * 1000).ConfigureAwait(false);

                    return(SharedInfo.Version);
                }

                if (!updateOverride && (Program.GlobalConfig.UpdatePeriod == 0))
                {
                    ArchiLogger.LogGenericInfo(Strings.UpdateNewVersionAvailable);
                    await Task.Delay(5000).ConfigureAwait(false);

                    return(null);
                }

                // Auto update logic starts here
                if (releaseResponse.Assets == null)
                {
                    ArchiLogger.LogGenericWarning(Strings.ErrorUpdateNoAssets);

                    return(null);
                }

                string targetFile = SharedInfo.ASF + "-" + SharedInfo.BuildInfo.Variant + ".zip";
                GitHub.ReleaseResponse.Asset binaryAsset = releaseResponse.Assets.FirstOrDefault(asset => asset.Name.Equals(targetFile, StringComparison.OrdinalIgnoreCase));

                if (binaryAsset == null)
                {
                    ArchiLogger.LogGenericWarning(Strings.ErrorUpdateNoAssetForThisVersion);

                    return(null);
                }

                if (string.IsNullOrEmpty(binaryAsset.DownloadURL))
                {
                    ArchiLogger.LogNullError(nameof(binaryAsset.DownloadURL));

                    return(null);
                }

                if (!string.IsNullOrEmpty(releaseResponse.ChangelogPlainText))
                {
                    ArchiLogger.LogGenericInfo(releaseResponse.ChangelogPlainText);
                }

                ArchiLogger.LogGenericInfo(string.Format(Strings.UpdateDownloadingNewVersion, newVersion, binaryAsset.Size / 1024 / 1024));

                WebBrowser.BinaryResponse response = await Program.WebBrowser.UrlGetToBinaryWithProgress(binaryAsset.DownloadURL).ConfigureAwait(false);

                if (response?.Content == null)
                {
                    return(null);
                }

                try {
                    using (ZipArchive zipArchive = new ZipArchive(new MemoryStream(response.Content))) {
                        if (!UpdateFromArchive(zipArchive, SharedInfo.HomeDirectory))
                        {
                            ArchiLogger.LogGenericError(Strings.WarningFailed);
                        }
                    }
                } catch (Exception e) {
                    ArchiLogger.LogGenericException(e);

                    return(null);
                }

                if (OS.IsUnix)
                {
                    string executable = Path.Combine(SharedInfo.HomeDirectory, SharedInfo.AssemblyName);

                    if (File.Exists(executable))
                    {
                        OS.UnixSetFileAccessExecutable(executable);
                    }
                }

                ArchiLogger.LogGenericInfo(Strings.UpdateFinished);

                return(newVersion);
            } finally {
                UpdateSemaphore.Release();
            }
        }
Example #5
0
        private static async Task OnDeletedConfigFile(string name, string fullPath)
        {
            if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(fullPath))
            {
                ArchiLogger.LogNullError(nameof(name) + " || " + nameof(fullPath));
                return;
            }

            string botName = Path.GetFileNameWithoutExtension(name);

            if (string.IsNullOrEmpty(botName))
            {
                return;
            }

            DateTime lastWriteTime = DateTime.UtcNow;

            if (LastWriteTimes.TryGetValue(name, out DateTime savedLastWriteTime))
            {
                if (savedLastWriteTime >= lastWriteTime)
                {
                    return;
                }
            }

            LastWriteTimes[name] = lastWriteTime;

            // It's entirely possible that some process is still accessing our file, allow at least a second before trying to read it
            await Task.Delay(1000).ConfigureAwait(false);

            // It's also possible that we got some other event in the meantime
            if (LastWriteTimes.TryGetValue(name, out savedLastWriteTime))
            {
                if (lastWriteTime != savedLastWriteTime)
                {
                    return;
                }

                if (LastWriteTimes.TryRemove(name, out savedLastWriteTime))
                {
                    if (lastWriteTime != savedLastWriteTime)
                    {
                        return;
                    }
                }
            }

            if (botName.Equals(SharedInfo.ASF))
            {
                if (File.Exists(fullPath))
                {
                    return;
                }

                // Some editors might decide to delete file and re-create it in order to modify it
                // If that's the case, we wait for maximum of 5 seconds before shutting down
                await Task.Delay(5000).ConfigureAwait(false);

                if (File.Exists(fullPath))
                {
                    return;
                }

                ArchiLogger.LogGenericError(Strings.ErrorGlobalConfigRemoved);
                await Program.Exit(1).ConfigureAwait(false);

                return;
            }

            if (!IsValidBotName(botName))
            {
                return;
            }

            if (Bot.Bots.TryGetValue(botName, out Bot bot))
            {
                await bot.OnConfigChanged(true).ConfigureAwait(false);
            }
        }
Example #6
0
        internal static async Task <Version> CheckAndUpdateProgram(bool updateOverride = false)
        {
            if (!SharedInfo.BuildInfo.CanUpdate || (Program.GlobalConfig.UpdateChannel == GlobalConfig.EUpdateChannel.None))
            {
                return(null);
            }

            if ((AutoUpdatesTimer == null) && (Program.GlobalConfig.UpdatePeriod > 0))
            {
                TimeSpan autoUpdatePeriod = TimeSpan.FromHours(Program.GlobalConfig.UpdatePeriod);

                AutoUpdatesTimer = new Timer(
                    async e => await CheckAndUpdateProgram().ConfigureAwait(false),
                    null,
                    autoUpdatePeriod,                    // Delay
                    autoUpdatePeriod                     // Period
                    );

                ArchiLogger.LogGenericInfo(string.Format(Strings.AutoUpdateCheckInfo, autoUpdatePeriod.ToHumanReadable()));
            }

            ArchiLogger.LogGenericInfo(Strings.UpdateCheckingNewVersion);

            // Cleanup from previous update - update directory for old in-use runtime files
            string backupDirectory = Path.Combine(SharedInfo.HomeDirectory, SharedInfo.UpdateDirectory);

            if (Directory.Exists(backupDirectory))
            {
                // It's entirely possible that old process is still running, wait a short moment for eventual cleanup
                await Task.Delay(5000).ConfigureAwait(false);

                try {
                    Directory.Delete(backupDirectory, true);
                } catch (Exception e) {
                    ArchiLogger.LogGenericException(e);
                    return(null);
                }
            }

            // Cleanup from previous update - old non-runtime in-use files
            try {
                foreach (string file in Directory.EnumerateFiles(SharedInfo.HomeDirectory, "*.old", SearchOption.AllDirectories))
                {
                    File.Delete(file);
                }
            } catch (Exception e) {
                ArchiLogger.LogGenericException(e);
                return(null);
            }

            string releaseURL = SharedInfo.GithubReleaseURL + (Program.GlobalConfig.UpdateChannel == GlobalConfig.EUpdateChannel.Stable ? "/latest" : "?per_page=1");

            GitHub.ReleaseResponse releaseResponse;

            if (Program.GlobalConfig.UpdateChannel == GlobalConfig.EUpdateChannel.Stable)
            {
                WebBrowser.ObjectResponse <GitHub.ReleaseResponse> objectResponse = await Program.WebBrowser.UrlGetToJsonObject <GitHub.ReleaseResponse>(releaseURL).ConfigureAwait(false);

                if (objectResponse?.Content == null)
                {
                    ArchiLogger.LogGenericWarning(Strings.ErrorUpdateCheckFailed);
                    return(null);
                }

                releaseResponse = objectResponse.Content;
            }
            else
            {
                WebBrowser.ObjectResponse <List <GitHub.ReleaseResponse> > objectResponse = await Program.WebBrowser.UrlGetToJsonObject <List <GitHub.ReleaseResponse> >(releaseURL).ConfigureAwait(false);

                if ((objectResponse?.Content == null) || (objectResponse.Content.Count == 0))
                {
                    ArchiLogger.LogGenericWarning(Strings.ErrorUpdateCheckFailed);
                    return(null);
                }

                releaseResponse = objectResponse.Content[0];
            }

            if (string.IsNullOrEmpty(releaseResponse.Tag))
            {
                ArchiLogger.LogGenericWarning(Strings.ErrorUpdateCheckFailed);
                return(null);
            }

            Version newVersion = new Version(releaseResponse.Tag);

            ArchiLogger.LogGenericInfo(string.Format(Strings.UpdateVersionInfo, SharedInfo.Version, newVersion));

            if (SharedInfo.Version == newVersion)
            {
                return(SharedInfo.Version);
            }

            if (SharedInfo.Version > newVersion)
            {
                ArchiLogger.LogGenericWarning(Strings.WarningPreReleaseVersion);
                await Task.Delay(15 * 1000).ConfigureAwait(false);

                return(SharedInfo.Version);
            }

            if (!updateOverride && (Program.GlobalConfig.UpdatePeriod == 0))
            {
                ArchiLogger.LogGenericInfo(Strings.UpdateNewVersionAvailable);
                await Task.Delay(5000).ConfigureAwait(false);

                return(null);
            }

            // Auto update logic starts here
            if (releaseResponse.Assets == null)
            {
                ArchiLogger.LogGenericWarning(Strings.ErrorUpdateNoAssets);
                return(null);
            }

            string targetFile = SharedInfo.ASF + "-" + SharedInfo.BuildInfo.Variant + ".zip";

            GitHub.ReleaseResponse.Asset binaryAsset = releaseResponse.Assets.FirstOrDefault(asset => asset.Name.Equals(targetFile, StringComparison.OrdinalIgnoreCase));

            if (binaryAsset == null)
            {
                ArchiLogger.LogGenericWarning(Strings.ErrorUpdateNoAssetForThisVersion);
                return(null);
            }

            if (string.IsNullOrEmpty(binaryAsset.DownloadURL))
            {
                ArchiLogger.LogNullError(nameof(binaryAsset.DownloadURL));
                return(null);
            }

            ArchiLogger.LogGenericInfo(string.Format(Strings.UpdateDownloadingNewVersion, newVersion, binaryAsset.Size / 1024 / 1024));

            WebBrowser.BinaryResponse response = await Program.WebBrowser.UrlGetToBinaryWithProgress(binaryAsset.DownloadURL).ConfigureAwait(false);

            if (response?.Content == null)
            {
                return(null);
            }

            try {
                using (ZipArchive zipArchive = new ZipArchive(new MemoryStream(response.Content))) {
                    if (!UpdateFromArchive(zipArchive, SharedInfo.HomeDirectory))
                    {
                        ArchiLogger.LogGenericError(Strings.WarningFailed);
                    }
                }
            } catch (Exception e) {
                ArchiLogger.LogGenericException(e);
                return(null);
            }

            if (OS.IsUnix)
            {
                string executable = Path.Combine(SharedInfo.HomeDirectory, SharedInfo.AssemblyName);
                if (File.Exists(executable))
                {
                    OS.UnixSetFileAccessExecutable(executable);
                }
            }

            ArchiLogger.LogGenericInfo(Strings.UpdateFinished);
            await RestartOrExit().ConfigureAwait(false);

            return(newVersion);
        }
Example #7
0
        internal static async Task CheckForUpdate(bool updateOverride = false)
        {
            string exeFile = Assembly.GetEntryAssembly().Location;

            if (string.IsNullOrEmpty(exeFile))
            {
                ArchiLogger.LogNullError(nameof(exeFile));
                return;
            }

            string oldExeFile = exeFile + ".old";

            // We booted successfully so we can now remove old exe file
            if (File.Exists(oldExeFile))
            {
                // It's entirely possible that old process is still running, allow at least a second before trying to remove the file
                await Task.Delay(1000).ConfigureAwait(false);

                try {
                    File.Delete(oldExeFile);
                } catch (Exception e) {
                    ArchiLogger.LogGenericException(e);
                    ArchiLogger.LogGenericError("Could not remove old ASF binary, please remove " + oldExeFile + " manually in order for update function to work!");
                }
            }

            if (Program.GlobalConfig.UpdateChannel == GlobalConfig.EUpdateChannel.None)
            {
                return;
            }

            if ((AutoUpdatesTimer == null) && Program.GlobalConfig.AutoUpdates)
            {
                AutoUpdatesTimer = new Timer(
                    async e => await CheckForUpdate().ConfigureAwait(false),
                    null,
                    TimeSpan.FromDays(1),                    // Delay
                    TimeSpan.FromDays(1)                     // Period
                    );

                ArchiLogger.LogGenericInfo("ASF will automatically check for new versions every 24 hours");
            }

            string releaseURL = SharedInfo.GithubReleaseURL;

            if (Program.GlobalConfig.UpdateChannel == GlobalConfig.EUpdateChannel.Stable)
            {
                releaseURL += "/latest";
            }

            ArchiLogger.LogGenericInfo("Checking new version...");

            GitHub.ReleaseResponse releaseResponse;

            if (Program.GlobalConfig.UpdateChannel == GlobalConfig.EUpdateChannel.Stable)
            {
                releaseResponse = await Program.WebBrowser.UrlGetToJsonResultRetry <GitHub.ReleaseResponse>(releaseURL).ConfigureAwait(false);

                if (releaseResponse == null)
                {
                    ArchiLogger.LogGenericWarning("Could not check latest version!");
                    return;
                }
            }
            else
            {
                List <GitHub.ReleaseResponse> releases = await Program.WebBrowser.UrlGetToJsonResultRetry <List <GitHub.ReleaseResponse> >(releaseURL).ConfigureAwait(false);

                if ((releases == null) || (releases.Count == 0))
                {
                    ArchiLogger.LogGenericWarning("Could not check latest version!");
                    return;
                }

                releaseResponse = releases[0];
            }

            if (string.IsNullOrEmpty(releaseResponse.Tag))
            {
                ArchiLogger.LogGenericWarning("Could not check latest version!");
                return;
            }

            Version newVersion = new Version(releaseResponse.Tag);

            ArchiLogger.LogGenericInfo("Local version: " + SharedInfo.Version + " | Remote version: " + newVersion);

            if (SharedInfo.Version.CompareTo(newVersion) >= 0)               // If local version is the same or newer than remote version
            {
                return;
            }

            if (!updateOverride && !Program.GlobalConfig.AutoUpdates)
            {
                ArchiLogger.LogGenericInfo("New version is available!");
                ArchiLogger.LogGenericInfo("Consider updating yourself!");
                await Task.Delay(5000).ConfigureAwait(false);

                return;
            }

            if (File.Exists(oldExeFile))
            {
                ArchiLogger.LogGenericWarning("Refusing to proceed with auto update as old " + oldExeFile + " binary could not be removed, please remove it manually");
                return;
            }

            // Auto update logic starts here
            if (releaseResponse.Assets == null)
            {
                ArchiLogger.LogGenericWarning("Could not proceed with update because that version doesn't include assets!");
                return;
            }

            string exeFileName = Path.GetFileName(exeFile);

            GitHub.ReleaseResponse.Asset binaryAsset = releaseResponse.Assets.FirstOrDefault(asset => !string.IsNullOrEmpty(asset.Name) && asset.Name.Equals(exeFileName, StringComparison.OrdinalIgnoreCase));

            if (binaryAsset == null)
            {
                ArchiLogger.LogGenericWarning("Could not proceed with update because there is no asset that relates to currently running binary!");
                return;
            }

            if (string.IsNullOrEmpty(binaryAsset.DownloadURL))
            {
                ArchiLogger.LogGenericWarning("Could not proceed with update because download URL is empty!");
                return;
            }

            ArchiLogger.LogGenericInfo("Downloading new version...");
            ArchiLogger.LogGenericInfo("While waiting, consider donating if you appreciate the work being done :)");

            byte[] result = await Program.WebBrowser.UrlGetToBytesRetry(binaryAsset.DownloadURL).ConfigureAwait(false);

            if (result == null)
            {
                return;
            }

            string newExeFile = exeFile + ".new";

            // Firstly we create new exec
            try {
                File.WriteAllBytes(newExeFile, result);
            } catch (Exception e) {
                ArchiLogger.LogGenericException(e);
                return;
            }

            // Now we move current -> old
            try {
                File.Move(exeFile, oldExeFile);
            } catch (Exception e) {
                ArchiLogger.LogGenericException(e);
                try {
                    // Cleanup
                    File.Delete(newExeFile);
                } catch {
                    // Ignored
                }
                return;
            }

            // Now we move new -> current
            try {
                File.Move(newExeFile, exeFile);
            } catch (Exception e) {
                ArchiLogger.LogGenericException(e);
                try {
                    // Cleanup
                    File.Move(oldExeFile, exeFile);
                    File.Delete(newExeFile);
                } catch {
                    // Ignored
                }
                return;
            }

            ArchiLogger.LogGenericInfo("Update process finished!");

            if (Program.GlobalConfig.AutoRestart)
            {
                ArchiLogger.LogGenericInfo("Restarting...");
                await Task.Delay(5000).ConfigureAwait(false);

                Program.Restart();
            }
            else
            {
                ArchiLogger.LogGenericInfo("Exiting...");
                await Task.Delay(5000).ConfigureAwait(false);

                Program.Exit();
            }
        }