From f6782ce14085d644b7f57ca0f101091e6c1c07bb Mon Sep 17 00:00:00 2001 From: Highbyte Date: Thu, 12 Mar 2026 15:03:28 +0100 Subject: [PATCH 1/2] Change default cors proxy server --- .../SystemSetup/C64HostConfig.cs | 3 ++- .../Emulator/SystemSetup/C64HostConfig.cs | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/apps/Avalonia/Highbyte.DotNet6502.App.Avalonia.Core/SystemSetup/C64HostConfig.cs b/src/apps/Avalonia/Highbyte.DotNet6502.App.Avalonia.Core/SystemSetup/C64HostConfig.cs index 6d3c7668..0d0a010b 100644 --- a/src/apps/Avalonia/Highbyte.DotNet6502.App.Avalonia.Core/SystemSetup/C64HostConfig.cs +++ b/src/apps/Avalonia/Highbyte.DotNet6502.App.Avalonia.Core/SystemSetup/C64HostConfig.cs @@ -15,7 +15,8 @@ public class C64HostConfig : IHostSystemConfig, ICloneable //public const string DefaultCorsProxyURL = "https://api.allorigins.win/raw?url="; // Doesn't work reliably //public const string DefaultCorsProxyURL = "https://corsproxy.io/?url="; // Stopped being possible to download binary files on free tier //public const string DefaultCorsProxyURL = "https://proxy.corsfix.com/?url="; // Only free from localhost - public const string DefaultCorsProxyURL = "https://cors-anywhere.com/"; + //public const string DefaultCorsProxyURL = "https://cors-anywhere.com/"; // Only works from localhost + public const string DefaultCorsProxyURL = "https://api.codetabs.com/v1/proxy?quest="; private C64SystemConfig _systemConfig = new(); ISystemConfig IHostSystemConfig.SystemConfig => _systemConfig; diff --git a/src/apps/Highbyte.DotNet6502.App.WASM/Emulator/SystemSetup/C64HostConfig.cs b/src/apps/Highbyte.DotNet6502.App.WASM/Emulator/SystemSetup/C64HostConfig.cs index 00fdd8ee..f2140d1b 100644 --- a/src/apps/Highbyte.DotNet6502.App.WASM/Emulator/SystemSetup/C64HostConfig.cs +++ b/src/apps/Highbyte.DotNet6502.App.WASM/Emulator/SystemSetup/C64HostConfig.cs @@ -14,7 +14,8 @@ public class C64HostConfig : IHostSystemConfig, ICloneable //public const string DefaultCorsProxyURL = "https://thingproxy.freeboard.io/fetch/"; // Doesn't seem to work with redirects //public const string DefaultCorsProxyURL = "https://corsproxy.io/?url="; // Stopped being possible to download binary files on free tier //public const string DefaultCorsProxyURL = "https://proxy.corsfix.com/?url="; // Only free from localhost - public const string DefaultCorsProxyURL = "https://cors-anywhere.com/"; + //public const string DefaultCorsProxyURL = "https://cors-anywhere.com/"; // Only works from localhost + public const string DefaultCorsProxyURL = "https://api.codetabs.com/v1/proxy?quest="; private C64SystemConfig _systemConfig; ISystemConfig IHostSystemConfig.SystemConfig => _systemConfig; From 490720a52414872e226d74b982af62edd318e9a1 Mon Sep 17 00:00:00 2001 From: Highbyte Date: Thu, 12 Mar 2026 17:42:41 +0100 Subject: [PATCH 2/2] Change CORS Proxy handling in Avalonia Browser app. Now the cors proxy URL is a override. If nothing is set a default proxy is used. --- .../SystemSetup/C64HostConfig.cs | 27 ++++++++++++++- .../ViewModels/C64ConfigDialogViewModel.cs | 33 +++++++++++++++++-- .../ViewModels/C64MenuViewModel.cs | 2 +- .../Views/C64ConfigUserControl.axaml | 29 ++++++++++++++++ .../Views/C64ConfigUserControl.axaml.cs | 29 ++++++++++++++++ 5 files changed, 116 insertions(+), 4 deletions(-) diff --git a/src/apps/Avalonia/Highbyte.DotNet6502.App.Avalonia.Core/SystemSetup/C64HostConfig.cs b/src/apps/Avalonia/Highbyte.DotNet6502.App.Avalonia.Core/SystemSetup/C64HostConfig.cs index 0d0a010b..7c5bdec1 100644 --- a/src/apps/Avalonia/Highbyte.DotNet6502.App.Avalonia.Core/SystemSetup/C64HostConfig.cs +++ b/src/apps/Avalonia/Highbyte.DotNet6502.App.Avalonia.Core/SystemSetup/C64HostConfig.cs @@ -32,7 +32,32 @@ public C64SystemConfig SystemConfig public C64AvaloniaInputConfig InputConfig { get; set; } = new C64AvaloniaInputConfig(); - public string CorsProxyURL { get; set; } = DefaultCorsProxyURL; + /// + /// Cors Proxy address override. + /// If set to null or empty, the default CORS proxy URL will be used when running in WebAssembly. When running on desktop, this setting is ignored and no CORS proxy will be used. + /// + /// + public string? CorsProxyOverrideURL { get; set; } = null; + + /// + /// Return the current CORS proxy URL to use. + /// If running in WebAssembly, this will return the CorsProxyOverrideURL if set, or the DefaultCorsProxyURL if CorsProxyOverrideURL is null or empty. + /// If not running in WebAssembly, this will return null to indicate that no CORS proxy should be used. + /// + /// + /// + /// + /// + public string GetCorsProxyURL() + { + if (!PlatformDetection.IsRunningInWebAssembly()) + { + // CORS proxy is only needed when running in WebAssembly, so return null to not use any proxy when running on desktop + return null!; + } + // If running in WebAssembly, return the configured CORS proxy URL, or the default if not set + return string.IsNullOrEmpty(CorsProxyOverrideURL) ? DefaultCorsProxyURL : CorsProxyOverrideURL; + } private bool _basicAIAssistantDefaultEnabled; [JsonIgnore] diff --git a/src/apps/Avalonia/Highbyte.DotNet6502.App.Avalonia.Core/ViewModels/C64ConfigDialogViewModel.cs b/src/apps/Avalonia/Highbyte.DotNet6502.App.Avalonia.Core/ViewModels/C64ConfigDialogViewModel.cs index c5581e1a..58609da4 100644 --- a/src/apps/Avalonia/Highbyte.DotNet6502.App.Avalonia.Core/ViewModels/C64ConfigDialogViewModel.cs +++ b/src/apps/Avalonia/Highbyte.DotNet6502.App.Avalonia.Core/ViewModels/C64ConfigDialogViewModel.cs @@ -48,6 +48,8 @@ public class C64ConfigDialogViewModel : ViewModelBase private RenderTargetOption? _selectedRenderTarget; private bool _suppressRenderTargetUpdate; + private string _corsProxyOverrideURL = string.Empty; + // AI Coding Assistant properties - now using config objects private CodeSuggestionBackendTypeEnum _selectedAIBackendType; private ApiConfig _openAIConfig = new(); @@ -61,6 +63,7 @@ public class C64ConfigDialogViewModel : ViewModelBase public ReactiveCommand DownloadRomsToFilesCommand { get; } public ReactiveCommand ClearRomsCommand { get; } public ReactiveCommand TestAIBackendCommand { get; } + public ReactiveCommand ResetCorsProxyOverrideURLCommand { get; } public ReactiveCommand SaveCommand { get; } public ReactiveCommand CancelCommand { get; } @@ -86,6 +89,7 @@ public C64ConfigDialogViewModel( AudioEnabled = _workingConfig.SystemConfig.AudioEnabled; RomDirectory = _workingConfig.SystemConfig.ROMDirectory; + CorsProxyOverrideURL = _workingConfig.CorsProxyOverrideURL ?? string.Empty; // Initialize AI Coding Assistant properties SelectedAIBackendType = _workingConfig.CodeSuggestionBackendType; @@ -117,6 +121,14 @@ public C64ConfigDialogViewModel( TestAIBackendAsync, outputScheduler: RxApp.MainThreadScheduler); + ResetCorsProxyOverrideURLCommand = ReactiveCommandHelper.CreateSafeCommand( + () => + { + CorsProxyOverrideURL = string.Empty; + return Task.CompletedTask; + }, + outputScheduler: RxApp.MainThreadScheduler); + SaveCommand = ReactiveCommandHelper.CreateSafeCommand( async () => { @@ -269,6 +281,21 @@ public string RomDirectory } } + public string CorsProxyOverrideURL + { + get => _corsProxyOverrideURL; + set + { + if (_corsProxyOverrideURL == value) + return; + + this.RaiseAndSetIfChanged(ref _corsProxyOverrideURL, value); + _workingConfig.CorsProxyOverrideURL = string.IsNullOrEmpty(value) ? null : value; + } + } + + public static string CorsProxyOverrideURLWatermark => C64HostConfig.DefaultCorsProxyURL; + public RenderProviderOption? SelectedRenderProvider { get => _selectedRenderProvider; @@ -331,8 +358,9 @@ public async Task AutoDownloadRomsToByteArrayAsync() foreach (var romDownload in _workingConfig.SystemConfig.ROMDownloadUrls) { - var fullROMUrl = !string.IsNullOrEmpty(_workingConfig.CorsProxyURL) - ? $"{_workingConfig.CorsProxyURL}{Uri.EscapeDataString(romDownload.Value)}" + var proxyUrl = _workingConfig.GetCorsProxyURL(); + var fullROMUrl = !string.IsNullOrEmpty(proxyUrl) + ? $"{proxyUrl}{Uri.EscapeDataString(romDownload.Value)}" : romDownload.Value; var romBytes = await _httpClient.GetByteArrayAsync(fullROMUrl); @@ -1034,6 +1062,7 @@ private void UpdateValidationMessageFromConfig() private void ApplyWorkingConfigToOriginal() { _originalConfig.SystemConfig.ROMDirectory = _workingConfig.SystemConfig.ROMDirectory; + _originalConfig.CorsProxyOverrideURL = _workingConfig.CorsProxyOverrideURL; _originalConfig.SystemConfig.AudioEnabled = _workingConfig.SystemConfig.AudioEnabled; _originalConfig.SystemConfig.KeyboardJoystickEnabled = _workingConfig.SystemConfig.KeyboardJoystickEnabled; _originalConfig.SystemConfig.KeyboardJoystick = _workingConfig.SystemConfig.KeyboardJoystick; diff --git a/src/apps/Avalonia/Highbyte.DotNet6502.App.Avalonia.Core/ViewModels/C64MenuViewModel.cs b/src/apps/Avalonia/Highbyte.DotNet6502.App.Avalonia.Core/ViewModels/C64MenuViewModel.cs index 2803afcd..c5b1dde3 100644 --- a/src/apps/Avalonia/Highbyte.DotNet6502.App.Avalonia.Core/ViewModels/C64MenuViewModel.cs +++ b/src/apps/Avalonia/Highbyte.DotNet6502.App.Avalonia.Core/ViewModels/C64MenuViewModel.cs @@ -528,7 +528,7 @@ private async Task LoadPreloadedDiskImage() _loggerFactory, _httpClient, HostApp!, - corsProxyUrl: PlatformDetection.IsRunningInWebAssembly() ? c64HostConfig.CorsProxyURL : null); + corsProxyUrl: c64HostConfig.GetCorsProxyURL()); } await _d64AutoDownloadAndRun.DownloadAndRunDiskImage( diff --git a/src/apps/Avalonia/Highbyte.DotNet6502.App.Avalonia.Core/Views/C64ConfigUserControl.axaml b/src/apps/Avalonia/Highbyte.DotNet6502.App.Avalonia.Core/Views/C64ConfigUserControl.axaml index 6e678efc..28951042 100644 --- a/src/apps/Avalonia/Highbyte.DotNet6502.App.Avalonia.Core/Views/C64ConfigUserControl.axaml +++ b/src/apps/Avalonia/Highbyte.DotNet6502.App.Avalonia.Core/Views/C64ConfigUserControl.axaml @@ -229,6 +229,35 @@ + + + + + + + + + +