diff --git a/Bloxstrap/App.xaml.cs b/Bloxstrap/App.xaml.cs index dfc11ca..81cecce 100644 --- a/Bloxstrap/App.xaml.cs +++ b/Bloxstrap/App.xaml.cs @@ -65,6 +65,20 @@ namespace Bloxstrap ); private static bool _showingExceptionDialog = false; + + private static string? _webUrl = null; + public static string WebUrl + { + get { + if (_webUrl != null) + return _webUrl; + + string url = ConstructBloxstrapWebUrl(); + if (Settings.Loaded) // only cache if settings are done loading + _webUrl = url; + return url; + } + } public static void Terminate(ErrorCode exitCode = ErrorCode.ERROR_SUCCESS) { @@ -126,6 +140,25 @@ namespace Bloxstrap Terminate(ErrorCode.ERROR_INSTALL_FAILURE); } + public static string ConstructBloxstrapWebUrl() + { + // dont let user switch web environment if debug mode is not on + if (Settings.Prop.WebEnvironment == WebEnvironment.Production || !Settings.Prop.DeveloperMode) + return "bloxstraplabs.com"; + + string? sub = Settings.Prop.WebEnvironment.GetDescription(); + return $"web-{sub}.bloxstraplabs.com"; + } + + public static bool CanSendLogs() + { + // non developer mode always uses production + if (!Settings.Prop.DeveloperMode || Settings.Prop.WebEnvironment == WebEnvironment.Production) + return IsProductionBuild; + + return true; + } + public static async Task GetLatestRelease() { const string LOG_IDENT = "App::GetLatestRelease"; @@ -157,7 +190,7 @@ namespace Bloxstrap try { - await HttpClient.GetAsync($"https://bloxstraplabs.com/metrics/post?key={key}&value={value}"); + await HttpClient.GetAsync($"https://{WebUrl}/metrics/post?key={key}&value={value}"); } catch (Exception ex) { @@ -167,13 +200,13 @@ namespace Bloxstrap public static async void SendLog() { - if (!Settings.Prop.EnableAnalytics || !IsProductionBuild) + if (!Settings.Prop.EnableAnalytics || !CanSendLogs()) return; try { await HttpClient.PostAsync( - $"https://bloxstraplabs.com/metrics/post-exception", + $"https://{WebUrl}/metrics/post-exception", new StringContent(Logger.AsDocument) ); } @@ -347,6 +380,9 @@ namespace Bloxstrap Settings.Save(); } + Logger.WriteLine(LOG_IDENT, $"Developer mode: {Settings.Prop.DeveloperMode}"); + Logger.WriteLine(LOG_IDENT, $"Web environment: {Settings.Prop.WebEnvironment}"); + Locale.Set(Settings.Prop.Locale); if (!LaunchSettings.BypassUpdateCheck) diff --git a/Bloxstrap/Enums/WebEnvironment.cs b/Bloxstrap/Enums/WebEnvironment.cs new file mode 100644 index 0000000..5bf857a --- /dev/null +++ b/Bloxstrap/Enums/WebEnvironment.cs @@ -0,0 +1,26 @@ +using System.ComponentModel; + +namespace Bloxstrap.Enums +{ + [JsonConverter(typeof(JsonStringEnumConverter))] + public enum WebEnvironment + { + [Description("prod")] + Production, + + [Description("stage")] + Staging, + + [Description("dev")] + Dev, + + [Description("pizza")] + DevPizza, + + [Description("matt")] + DevMatt, + + [Description("local")] + Local + } +} diff --git a/Bloxstrap/Extensions/TEnumEx.cs b/Bloxstrap/Extensions/TEnumEx.cs new file mode 100644 index 0000000..ddefb8f --- /dev/null +++ b/Bloxstrap/Extensions/TEnumEx.cs @@ -0,0 +1,22 @@ +using System.ComponentModel; +using System.Reflection; + +namespace Bloxstrap.Extensions +{ + internal static class TEnumEx + { + public static string? GetDescription(this TEnum e) + { + string? enumName = e.ToString(); + if (enumName == null) + return null; + + FieldInfo? field = e.GetType().GetField(enumName); + if (field == null) + return null; + + DescriptionAttribute? attribute = field.GetCustomAttribute(); + return attribute?.Description; + } + } +} diff --git a/Bloxstrap/JsonManager.cs b/Bloxstrap/JsonManager.cs index 6c04a2a..2bf55cf 100644 --- a/Bloxstrap/JsonManager.cs +++ b/Bloxstrap/JsonManager.cs @@ -13,6 +13,8 @@ namespace Bloxstrap /// public string? LastFileHash { get; private set; } + public bool Loaded { get; set; } = false; + public virtual string ClassName => typeof(T).Name; public virtual string FileLocation => Path.Combine(Paths.Base, $"{ClassName}.json"); @@ -35,6 +37,7 @@ namespace Bloxstrap throw new ArgumentNullException("Deserialization returned null"); Prop = settings; + Loaded = true; LastFileHash = MD5Hash.FromString(contents); App.Logger.WriteLine(LOG_IDENT, "Loaded successfully!"); diff --git a/Bloxstrap/Models/Persistable/Settings.cs b/Bloxstrap/Models/Persistable/Settings.cs index eb9c273..13f834c 100644 --- a/Bloxstrap/Models/Persistable/Settings.cs +++ b/Bloxstrap/Models/Persistable/Settings.cs @@ -10,6 +10,8 @@ namespace Bloxstrap.Models.Persistable public string BootstrapperTitle { get; set; } = App.ProjectName; public string BootstrapperIconCustomLocation { get; set; } = ""; public Theme Theme { get; set; } = Theme.Default; + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] + public bool DeveloperMode { get; set; } = false; public bool CheckForUpdates { get; set; } = true; public bool MultiInstanceLaunching { get; set; } = false; public bool ConfirmLaunches { get; set; } = false; @@ -21,6 +23,7 @@ namespace Bloxstrap.Models.Persistable public bool BackgroundUpdatesEnabled { get; set; } = true; public bool DebugDisableVersionPackageCleanup { get; set; } = false; public string? SelectedCustomTheme { get; set; } = null; + public WebEnvironment WebEnvironment { get; set; } = WebEnvironment.Production; // integration configuration public bool EnableActivityTracking { get; set; } = true; diff --git a/Bloxstrap/UI/Elements/Settings/Pages/BloxstrapPage.xaml b/Bloxstrap/UI/Elements/Settings/Pages/BloxstrapPage.xaml index d4f731a..326f859 100644 --- a/Bloxstrap/UI/Elements/Settings/Pages/BloxstrapPage.xaml +++ b/Bloxstrap/UI/Elements/Settings/Pages/BloxstrapPage.xaml @@ -29,6 +29,14 @@ + + + + + diff --git a/Bloxstrap/UI/ViewModels/Settings/BloxstrapViewModel.cs b/Bloxstrap/UI/ViewModels/Settings/BloxstrapViewModel.cs index 63ce62f..b1eb626 100644 --- a/Bloxstrap/UI/ViewModels/Settings/BloxstrapViewModel.cs +++ b/Bloxstrap/UI/ViewModels/Settings/BloxstrapViewModel.cs @@ -1,4 +1,5 @@ -using System.Windows.Input; +using System.Windows; +using System.Windows.Input; using CommunityToolkit.Mvvm.Input; using ICSharpCode.SharpZipLib.Zip; using Microsoft.Win32; @@ -7,6 +8,8 @@ namespace Bloxstrap.UI.ViewModels.Settings { public class BloxstrapViewModel : NotifyPropertyChangedViewModel { + public WebEnvironment[] WebEnvironments => Enum.GetValues(); + public bool UpdateCheckingEnabled { get => App.Settings.Prop.CheckForUpdates; @@ -19,6 +22,14 @@ namespace Bloxstrap.UI.ViewModels.Settings set => App.Settings.Prop.EnableAnalytics = value; } + public WebEnvironment WebEnvironment + { + get => App.Settings.Prop.WebEnvironment; + set => App.Settings.Prop.WebEnvironment = value; + } + + public Visibility WebEnvironmentVisibility => App.Settings.Prop.DeveloperMode ? Visibility.Visible : Visibility.Collapsed; + public bool ShouldExportConfig { get; set; } = true; public bool ShouldExportLogs { get; set; } = true;