diff --git a/Bloxstrap/Bootstrapper.cs b/Bloxstrap/Bootstrapper.cs index 232081f..409c8d0 100644 --- a/Bloxstrap/Bootstrapper.cs +++ b/Bloxstrap/Bootstrapper.cs @@ -125,15 +125,14 @@ namespace Bloxstrap App.Logger.WriteLine(LOG_IDENT, "Connectivity check failed"); App.Logger.WriteException(LOG_IDENT, exception); - string message = Strings.Dialog_Connectivity_Preventing; + string message = Strings.Dialog_Connectivity_BadConnection; - if (exception.GetType() == typeof(AggregateException)) + if (exception is AggregateException) exception = exception.InnerException!; - if (exception.GetType() == typeof(HttpRequestException)) + // https://gist.github.com/pizzaboxer/4b58303589ee5b14cc64397460a8f386 + if (exception is HttpRequestException && exception.InnerException is null) message = String.Format(Strings.Dialog_Connectivity_RobloxDown, "[status.roblox.com](https://status.roblox.com)"); - else if (exception.GetType() == typeof(TaskCanceledException)) - message = Strings.Dialog_Connectivity_TimedOut; if (_mustUpgrade) message += $"\n\n{Strings.Dialog_Connectivity_RobloxUpgradeNeeded}\n\n{Strings.Dialog_Connectivity_TryAgainLater}"; @@ -252,6 +251,10 @@ namespace Bloxstrap Dialog?.CloseBootstrapper(); } + /// + /// Will throw whatever HttpClient can throw + /// + /// private async Task GetLatestVersionInfo() { const string LOG_IDENT = "Bootstrapper::GetLatestVersionInfo"; @@ -262,7 +265,11 @@ namespace Bloxstrap using var key = Registry.CurrentUser.CreateSubKey($"SOFTWARE\\ROBLOX Corporation\\Environments\\{AppData.RegistryName}\\Channel"); - var match = Regex.Match(App.LaunchSettings.RobloxLaunchArgs, "channel:([a-zA-Z0-9-_]+)", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant); + var match = Regex.Match( + App.LaunchSettings.RobloxLaunchArgs, + "channel:([a-zA-Z0-9-_]+)", + RegexOptions.IgnoreCase | RegexOptions.CultureInvariant + ); if (match.Groups.Count == 2) { @@ -273,9 +280,12 @@ namespace Bloxstrap Deployment.Channel = value.ToLowerInvariant(); } - App.Logger.WriteLine(LOG_IDENT, "Got channel as " + (String.IsNullOrEmpty(Deployment.Channel) ? Deployment.DefaultChannel : Deployment.Channel)); + if (String.IsNullOrEmpty(Deployment.Channel)) + Deployment.Channel = Deployment.DefaultChannel; - if (Deployment.Channel != "production") + App.Logger.WriteLine(LOG_IDENT, $"Got channel as {Deployment.DefaultChannel}"); + + if (!Deployment.IsDefaultChannel) App.SendStat("robloxChannel", Deployment.Channel); ClientVersion clientVersion; @@ -284,14 +294,9 @@ namespace Bloxstrap { clientVersion = await Deployment.GetInfo(); } - catch (HttpRequestException ex) + catch (InvalidChannelException ex) { - if (ex.StatusCode is not HttpStatusCode.Unauthorized - and not HttpStatusCode.Forbidden - and not HttpStatusCode.NotFound) - throw; - - App.Logger.WriteLine(LOG_IDENT, $"Changing channel from {Deployment.Channel} to {Deployment.DefaultChannel} because HTTP {(int)ex.StatusCode}"); + App.Logger.WriteLine(LOG_IDENT, $"Resetting channel from {Deployment.Channel} because {ex.StatusCode}"); Deployment.Channel = Deployment.DefaultChannel; clientVersion = await Deployment.GetInfo(); @@ -299,7 +304,7 @@ namespace Bloxstrap if (clientVersion.IsBehindDefaultChannel) { - App.Logger.WriteLine(LOG_IDENT, $"Changing channel from {Deployment.Channel} to {Deployment.DefaultChannel} because channel is behind production"); + App.Logger.WriteLine(LOG_IDENT, $"Resetting channel from {Deployment.Channel} because it's behind production"); Deployment.Channel = Deployment.DefaultChannel; clientVersion = await Deployment.GetInfo(); diff --git a/Bloxstrap/Exceptions/InvalidChannelException.cs b/Bloxstrap/Exceptions/InvalidChannelException.cs new file mode 100644 index 0000000..eff6d79 --- /dev/null +++ b/Bloxstrap/Exceptions/InvalidChannelException.cs @@ -0,0 +1,10 @@ +namespace Bloxstrap.Exceptions +{ + public class InvalidChannelException : Exception + { + public HttpStatusCode? StatusCode; + + public InvalidChannelException(HttpStatusCode? statusCode) : base() + => StatusCode = statusCode; + } +} diff --git a/Bloxstrap/Resources/Strings.Designer.cs b/Bloxstrap/Resources/Strings.Designer.cs index 0201300..f50f201 100644 --- a/Bloxstrap/Resources/Strings.Designer.cs +++ b/Bloxstrap/Resources/Strings.Designer.cs @@ -838,6 +838,15 @@ namespace Bloxstrap.Resources { } } + /// + /// Looks up a localized string similar to A connection could not be made, which likely indicates a poor internet connection or a firewall block. If your connection is fine, please ensure that your antivirus isn't blocking Bloxstrap.. + /// + public static string Dialog_Connectivity_BadConnection { + get { + return ResourceManager.GetString("Dialog.Connectivity.BadConnection", resourceCulture); + } + } + /// /// Looks up a localized string similar to More information:. /// @@ -847,15 +856,6 @@ namespace Bloxstrap.Resources { } } - /// - /// Looks up a localized string similar to Something is likely preventing Bloxstrap from connecting to the internet.. - /// - public static string Dialog_Connectivity_Preventing { - get { - return ResourceManager.GetString("Dialog.Connectivity.Preventing", resourceCulture); - } - } - /// /// Looks up a localized string similar to Roblox may be down right now. See {0} for more information.. /// @@ -883,15 +883,6 @@ namespace Bloxstrap.Resources { } } - /// - /// Looks up a localized string similar to The connection timed out, which could indicate a poor internet connection or a firewall block.. - /// - public static string Dialog_Connectivity_TimedOut { - get { - return ResourceManager.GetString("Dialog.Connectivity.TimedOut", resourceCulture); - } - } - /// /// Looks up a localized string similar to Connectivity error. /// diff --git a/Bloxstrap/Resources/Strings.resx b/Bloxstrap/Resources/Strings.resx index aea14a5..96f6d0b 100644 --- a/Bloxstrap/Resources/Strings.resx +++ b/Bloxstrap/Resources/Strings.resx @@ -123,14 +123,11 @@ Roblox is currently running, and launching another instance will close it. Are you sure you want to continue launching? - - Something is likely preventing Bloxstrap from connecting to the internet. - Roblox may be down right now. See {0} for more information. - - The connection timed out, which could indicate a poor internet connection or a firewall block. + + A connection could not be made, which likely indicates a poor internet connection or a firewall block. If your connection is fine, please ensure that your antivirus isn't blocking Bloxstrap. You must first install Bloxstrap before uninstalling. diff --git a/Bloxstrap/RobloxInterfaces/Deployment.cs b/Bloxstrap/RobloxInterfaces/Deployment.cs index f6ee997..da88c14 100644 --- a/Bloxstrap/RobloxInterfaces/Deployment.cs +++ b/Bloxstrap/RobloxInterfaces/Deployment.cs @@ -10,10 +10,17 @@ public static string BinaryType = "WindowsPlayer"; - public static bool IsDefaultChannel => String.Compare(Channel, DefaultChannel, StringComparison.OrdinalIgnoreCase) == 0; + public static bool IsDefaultChannel => Channel.Equals(DefaultChannel, StringComparison.OrdinalIgnoreCase); public static string BaseUrl { get; private set; } = null!; - + + public static readonly List BadChannelCodes = new() + { + HttpStatusCode.Unauthorized, + HttpStatusCode.Forbidden, + HttpStatusCode.NotFound + }; + private static readonly Dictionary ClientVersionCache = new(); // a list of roblox deployment locations that we check for, in case one of them don't work @@ -97,7 +104,9 @@ { if (exceptions.Any()) return exceptions[0]; - return new TaskCanceledException("All tasks have been cancelled"); // we can't add TaskCanceledExceptions to the list + + // task cancellation exceptions don't get added to the list + return new TaskCanceledException("All connection attempts timed out."); } App.Logger.WriteLine(LOG_IDENT, $"Got {BaseUrl} as the optimal base URL"); @@ -157,10 +166,10 @@ { clientVersion = await Http.GetJson("https://clientsettingscdn.roblox.com" + path); } - catch (HttpRequestException) + catch (HttpRequestException httpEx) + when (!isDefaultChannel && BadChannelCodes.Contains(httpEx.StatusCode)) { - // throw up the exception handler chain, as we shouldn't be the one handling it - throw; + throw new InvalidChannelException(httpEx.StatusCode); } catch (Exception ex) {