From 41d06e6a23a594e3f7396c64abe52cdb443731a3 Mon Sep 17 00:00:00 2001 From: weter11 Date: Fri, 13 Feb 2026 09:46:14 +0200 Subject: [PATCH] Add opt-in update/verify actions and upgrade egui/eframe to 0.33 --- AvaloniaCommon/Assets/error.ico | Bin 92478 -> 0 bytes AvaloniaCommon/Assets/information.ico | Bin 92478 -> 0 bytes AvaloniaCommon/Assets/question.ico | Bin 92478 -> 0 bytes AvaloniaCommon/Assets/warning.ico | Bin 92478 -> 0 bytes AvaloniaCommon/AvaloniaCommon.csproj | 19 - AvaloniaCommon/Enums/MessageBoxButton.cs | 12 - AvaloniaCommon/Enums/MessageBoxIcon.cs | 12 - AvaloniaCommon/MessageBox.cs | 91 - AvaloniaCommon/Theme.cs | 63 - AvaloniaCommon/ViewModelBase.cs | 10 - .../ViewModels/MessageBoxViewModel.cs | 112 - AvaloniaCommon/Views/MessageBox.axaml | 110 - AvaloniaCommon/Views/MessageBox.axaml.cs | 47 - AvaloniaCommon/nuget.config | 6 - ChromeTestClient/ChromeIPCClient.cs | 140 -- ChromeTestClient/ChromeTestClient.csproj | 17 - ChromeTestClient/EHTMLCommands.cs | 7 - ChromeTestClient/HTMLProtoMsg.cs | 2 - ChromeTestClient/LiteHTMLHost.cs | 161 -- ChromeTestClient/Platform/Globals.cs | 18 - ChromeTestClient/Platform/IIPCImpl.cs | 28 - .../Platform/Linux/ErrnoException.cs | 23 - ChromeTestClient/Platform/Linux/IPCImpl.cs | 364 --- ChromeTestClient/Platform/Linux/LinuxData.cs | 89 - ChromeTestClient/Platform/Linux/LinuxEvent.cs | 72 - ChromeTestClient/Platform/Linux/LinuxMutex.cs | 20 - .../Platform/Linux/LinuxSharedMemory.cs | 74 - .../Platform/Linux/MutexDisposable.cs | 31 - .../Platform/Linux/SteamLinuxMutex.cs | 206 -- ChromeTestClient/Program.cs | 69 - ChromeTestClient/README.md | 3 - ChromeTestClient/SharedMemStream.cs | 180 -- ChromeTestClient/nuget.config | 6 - GameOverlayDebugTarget/App.axaml | 8 - GameOverlayDebugTarget/App.axaml.cs | 23 - .../GameOverlayDebugTarget.csproj | 22 - GameOverlayDebugTarget/MainWindow.axaml | 24 - GameOverlayDebugTarget/MainWindow.axaml.cs | 295 --- GameOverlayDebugTarget/Program.cs | 80 - GameOverlayDebugTarget/app.manifest | 18 - GameOverlayDebugTarget/nuget.config | 6 - GameOverlayUI/AvaloniaApp.axaml | 18 - GameOverlayUI/AvaloniaApp.axaml.cs | 311 --- GameOverlayUI/GameOverlayUI.csproj | 18 - GameOverlayUI/IPC/DynDisplayData.cs | 36 - GameOverlayUI/IPC/DynInputData.cs | 45 - GameOverlayUI/IPC/EInputType.cs | 13 - GameOverlayUI/IPC/EOverlayState.cs | 29 - GameOverlayUI/IPC/InputData.cs | 53 - GameOverlayUI/IPC/OverlayControlData.cs | 39 - GameOverlayUI/IPC/SharedMemoryManager.cs | 154 -- GameOverlayUI/Impl/OverlayLauncher.cs | 91 - GameOverlayUI/Impl/OverlayLauncherFactory.cs | 17 - GameOverlayUI/Program.cs | 108 - .../ViewModels/AvaloniaAppViewModel.cs | 7 - .../ViewModels/CustomWindowViewModel.cs | 81 - GameOverlayUI/ViewModels/MainViewViewModel.cs | 27 - GameOverlayUI/Views/CustomWindowView.axaml | 76 - GameOverlayUI/Views/CustomWindowView.axaml.cs | 11 - GameOverlayUI/Views/MainView.axaml | 31 - GameOverlayUI/Views/MainView.axaml.cs | 111 - GameOverlayUI/nuget.config | 6 - Installer/Assets/opensteam-logo.ico | Bin 45839 -> 0 bytes Installer/AvaloniaApp.axaml | 28 - Installer/AvaloniaApp.axaml.cs | 66 - Installer/Controls/Translatable.cs | 36 - Installer/Core/InstallationManager.cs | 215 -- Installer/Core/LocalizedException.cs | 13 - Installer/Core/SteamManifest.cs | 7 - Installer/Enums/InstallAction.cs | 11 - Installer/Extensions/ControlExtensions.cs | 68 - Installer/Extensions/HttpClientExtensions.cs | 79 - Installer/Extensions/RegistryKeyExtensions.cs | 17 - Installer/Extensions/StreamExtensions.cs | 43 - Installer/Extensions/VisualExtensions.cs | 29 - Installer/Extensions/ZipArchiveExtensions.cs | 47 - Installer/Installer.csproj | 69 - Installer/Program.cs | 54 - Installer/Translation/ELanguage.cs | 91 - Installer/Translation/TranslationManager.cs | 285 --- Installer/Translations/english.json | 48 - Installer/Translations/finnish.json | 49 - Installer/ViewModels/AvaloniaAppViewModel.cs | 5 - Installer/ViewModels/LanguageViewModel.cs | 12 - Installer/ViewModels/MainWindowViewModel.cs | 269 --- .../Pages/ChooseActionPageViewModel.cs | 55 - .../ChooseInstallDirectoryPageViewModel.cs | 91 - .../Pages/InstallingPageViewModel.cs | 5 - .../Pages/PlaceholderPageViewModel.cs | 9 - .../ViewModels/Pages/ProgressPageViewModel.cs | 7 - .../ViewModels/Pages/WelcomePageViewModel.cs | 36 - Installer/ViewModels/ViewModelBase.cs | 8 - Installer/Views/Pages/ChooseActionPage.axaml | 23 - .../Views/Pages/ChooseActionPage.axaml.cs | 16 - .../Pages/ChooseInstallDirectoryPage.axaml | 28 - .../Pages/ChooseInstallDirectoryPage.axaml.cs | 16 - Installer/Views/Pages/InstallingPage.axaml | 21 - Installer/Views/Pages/InstallingPage.axaml.cs | 16 - Installer/Views/Pages/PlaceholderPage.axaml | 19 - .../Views/Pages/PlaceholderPage.axaml.cs | 16 - Installer/Views/Pages/WelcomePage.axaml | 33 - Installer/Views/Pages/WelcomePage.axaml.cs | 16 - Installer/Views/Windows/MainWindow.axaml | 44 - Installer/Views/Windows/MainWindow.axaml.cs | 16 - Installer/WindowToolbar.cs | 44 - Installer/app.manifest | 26 - OpenSteamClient/Assets/arrow_back.svg | 1 - OpenSteamClient/Assets/arrow_forward.svg | 1 - OpenSteamClient/Assets/error.ico | Bin 92478 -> 0 bytes OpenSteamClient/Assets/information.ico | Bin 92478 -> 0 bytes OpenSteamClient/Assets/opensteam-logo.ico | Bin 45839 -> 0 bytes OpenSteamClient/Assets/plus.png | Bin 3845 -> 0 bytes OpenSteamClient/Assets/question.ico | Bin 92478 -> 0 bytes OpenSteamClient/Assets/refresh.svg | 1 - OpenSteamClient/Assets/unknown.png | Bin 5588 -> 0 bytes OpenSteamClient/Assets/warning.ico | Bin 92478 -> 0 bytes OpenSteamClient/AvaloniaApp.axaml | 54 - OpenSteamClient/AvaloniaApp.axaml.cs | 410 ---- OpenSteamClient/Controls/BasePage.cs | 19 - OpenSteamClient/Controls/BaseWebPage.axaml | 46 - OpenSteamClient/Controls/BaseWebPage.axaml.cs | 216 -- OpenSteamClient/Controls/HTMLSurface.axaml | 11 - OpenSteamClient/Controls/HTMLSurface.axaml.cs | 686 ------ OpenSteamClient/Controls/Translatable.cs | 57 - OpenSteamClient/Entry.cs | 126 - .../Extensions/ControlExtensions.cs | 80 - .../Extensions/VisualExtensions.cs | 29 - OpenSteamClient/JsonContext.cs | 8 - OpenSteamClient/OpenSteamClient.csproj | 48 - OpenSteamClient/PlatformSpecific/X11Key.cs | 2104 ----------------- .../PlatformSpecific/X11KeyTransform.cs | 142 -- OpenSteamClient/Program.cs | 62 - .../Properties/launchSettings.json | 8 - .../Translation/TranslationManager.cs | 302 --- OpenSteamClient/Translations/english.json | 142 -- OpenSteamClient/Translations/finnish.json | 137 -- OpenSteamClient/UIImpl/FriendsUI.cs | 66 - .../AccountPickerWindowViewModel.cs | 74 - .../ViewModels/AppSettingsWindowViewModel.cs | 181 -- .../ViewModels/AvaloniaAppViewModel.cs | 128 - .../ViewModels/ConsolePageViewModel.cs | 121 - .../Downloads/DownloadItemViewModel.cs | 70 - .../Downloads/DownloadsPageViewModel.cs | 110 - .../ViewModels/Friends/FriendViewModel.cs | 440 ---- .../Friends/FriendsListViewModel.cs | 44 - .../Friends/RichPresenceViewModel.cs | 18 - OpenSteamClient/ViewModels/IDNameViewModel.cs | 20 - .../ViewModels/LaunchOptionViewModel.cs | 17 - .../Library/CollectionItemViewModel.cs | 37 - .../Library/FocusedAppPaneViewModel.cs | 351 --- .../ViewModels/Library/LibraryAppViewModel.cs | 151 -- OpenSteamClient/ViewModels/Library/Node.cs | 67 - .../ViewModels/LibraryFolderViewModel.cs | 41 - .../ViewModels/LibraryPageViewModel.cs | 152 -- .../ViewModels/LoginWindowViewModel.cs | 136 -- .../ViewModels/MainWindowViewModel.cs | 248 -- .../ViewModels/MenuItemViewModel.cs | 31 - .../ViewModels/PageHeaderViewModel.cs | 106 - .../PickLaunchOptionDialogViewModel.cs | 76 - .../ViewModels/ProgressWindowViewModel.cs | 45 - OpenSteamClient/ViewModels/README.md | 3 - .../ViewModels/SavedAccountViewModel.cs | 30 - .../SecondFactorNeededDialogViewModel.cs | 67 - .../SelectInstallDirectoryDialogViewModel.cs | 57 - .../ViewModels/SettingsWindowViewModel.cs | 206 -- .../ViewModels/WebviewPageViewModel.cs | 9 - .../Debugging/Borked/InterfaceDebugger.axaml | 15 - .../Borked/InterfaceDebugger.axaml.cs | 211 -- .../Debugging/Borked/InterfaceList.axaml | 17 - .../Debugging/Borked/InterfaceList.axaml.cs | 90 - .../Views/Debugging/HTMLSurfaceTest.axaml | 15 - .../Views/Debugging/HTMLSurfaceTest.axaml.cs | 52 - .../Dialogs/PickLaunchOptionDialog.axaml | 35 - .../Dialogs/PickLaunchOptionDialog.axaml.cs | 13 - .../Dialogs/SecondFactorNeededDialog.axaml | 41 - .../Dialogs/SecondFactorNeededDialog.axaml.cs | 13 - .../SelectInstallDirectoryDialog.axaml | 35 - .../SelectInstallDirectoryDialog.axaml.cs | 13 - .../Views/Friends/FriendsList.axaml | 84 - .../Views/Friends/FriendsList.axaml.cs | 23 - .../Views/Library/FocusedAppPane.axaml | 31 - .../Views/Library/FocusedAppPane.axaml.cs | 40 - OpenSteamClient/Views/Pages/ConsolePage.axaml | 31 - .../Views/Pages/ConsolePage.axaml.cs | 17 - .../Views/Pages/DownloadsPage.axaml | 97 - .../Views/Pages/DownloadsPage.axaml.cs | 13 - OpenSteamClient/Views/Pages/LibraryPage.axaml | 83 - .../Views/Pages/LibraryPage.axaml.cs | 17 - .../Pages/WebBased/CommunityPage.axaml.cs | 17 - .../Views/Pages/WebBased/StorePage.axaml.cs | 17 - OpenSteamClient/Views/README.md | 10 - .../Views/Windows/AccountPickerWindow.axaml | 58 - .../Windows/AccountPickerWindow.axaml.cs | 17 - .../Views/Windows/AppSettingsWindow.axaml | 29 - .../Views/Windows/AppSettingsWindow.axaml.cs | 15 - .../Views/Windows/LoginWindow.axaml | 43 - .../Views/Windows/LoginWindow.axaml.cs | 31 - .../Views/Windows/MainWindow.axaml | 90 - .../Views/Windows/MainWindow.axaml.cs | 16 - .../Views/Windows/ProgressWindow.axaml | 26 - .../Views/Windows/ProgressWindow.axaml.cs | 21 - .../Views/Windows/SettingsWindow.axaml | 77 - .../Views/Windows/SettingsWindow.axaml.cs | 16 - OpenSteamClient/app.manifest | 18 - OpenSteamClient/nuget.config | 6 - OpenSteamworks.Client/Apps/AppsManager.cs | 134 -- .../Apps/Assets/ELibraryAssetType.cs | 15 - .../Apps/Assets/LibraryAssetsFile.cs | 176 -- .../Apps/Assets/LibraryAssetsGenerator.cs | 244 -- OpenSteamworks.Client/Apps/BannedApp.cs | 18 - .../Apps/CloudConfigStore.cs | 416 ---- OpenSteamworks.Client/Apps/IApp.cs | 34 - .../Apps/IAppAssetsInterface.cs | 86 - .../Apps/IAppConfigInterface.cs | 60 - .../Apps/IAppInfoAccessInterface.cs | 28 - .../Apps/IAppInfoUpdateInterface.cs | 20 - .../Apps/IAppInstallInterface.cs | 23 - .../Apps/IAppLaunchInterface.cs | 22 - OpenSteamworks.Client/Apps/ILaunchOption.cs | 11 - .../Apps/LaunchProgressEventArgs.cs | 28 - .../Apps/Library/Collection.cs | 260 -- .../Apps/Library/FilterGroup.cs | 40 - .../Apps/Library/JSONCollection.cs | 15 - .../Apps/Library/JSONFilterGroup.cs | 12 - .../Apps/Library/JSONFilterSpec.cs | 33 - OpenSteamworks.Client/Apps/Library/Library.cs | 391 --- .../Apps/Library/LibraryManager.cs | 500 ---- OpenSteamworks.Client/Apps/ShortcutApp.cs | 75 - OpenSteamworks.Client/Apps/SteamApp.cs | 365 --- OpenSteamworks.Client/Client.cs | 136 -- .../CommonEventArgs/EResultEventArgs.cs | 8 - .../CommonEventArgs/README.md | 2 - .../Config/AdvancedConfig.cs | 43 - .../Attributes/ConfigAdvancedAttribute.cs | 7 - .../Attributes/ConfigCategoryAttribute.cs | 14 - .../Attributes/ConfigDescriptionAttribute.cs | 14 - .../Config/Attributes/ConfigNameAttribute.cs | 14 - .../Attributes/ConfigNeverVisibleAttribute.cs | 10 - .../Config/BootstrapperState.cs | 49 - .../Config/ConfigJsonContext.cs | 20 - OpenSteamworks.Client/Config/ConfigManager.cs | 209 -- .../Config/GlobalSettings.cs | 66 - OpenSteamworks.Client/Config/IConfigFile.cs | 10 - .../Config/LibrarySettings.cs | 16 - OpenSteamworks.Client/Config/LoginUsers.cs | 79 - .../Config/NotificationSettings.cs | 16 - OpenSteamworks.Client/Config/UserSettings.cs | 25 - OpenSteamworks.Client/DI/Container.cs | 164 -- OpenSteamworks.Client/DI/LifetimeManager.cs | 238 -- .../DI/OverridingContainer.cs | 32 - OpenSteamworks.Client/Enums/DataRateUnit.cs | 54 - OpenSteamworks.Client/Enums/DataSizeUnit.cs | 29 - .../Enums/ELibraryAppFeaturesFilter.cs | 18 - .../Enums/ELibraryAppStateFilter.cs | 8 - .../Enums/EUserConfigStoreNamespace.cs | 6 - .../Experimental/TransportManager.cs | 299 --- .../Friends/FriendsManager.cs | 231 -- OpenSteamworks.Client/Friends/IFriendsUI.cs | 9 - OpenSteamworks.Client/GlobalUsings.cs | 0 OpenSteamworks.Client/JsonContext.cs | 19 - OpenSteamworks.Client/Login/LoginManager.cs | 623 ----- OpenSteamworks.Client/Login/LoginPoll.cs | 98 - OpenSteamworks.Client/Login/LoginUser.cs | 57 - .../Managers/InstallManager.cs | 106 - .../Managers/ShaderManager.cs | 39 - .../Notifications/INotificationUI.cs | 11 - .../Notifications/NotificationManager.cs | 22 - .../OpenSteamworks.Client.csproj | 60 - OpenSteamworks.Client/README.md | 2 - OpenSteamworks.Client/Startup/Bootstrapper.cs | 994 -------- OpenSteamworks.Client/Startup/SteamHTML.cs | 269 --- OpenSteamworks.Client/Startup/SteamService.cs | 144 -- .../Utils/DataUnitStrings.cs | 91 - OpenSteamworks.Client/Utils/Logger.cs | 301 --- OpenSteamworks.Client/Utils/LoggerFactory.cs | 19 - OpenSteamworks.Client/Utils/OSCheck.cs | 32 - .../Utils/OSSpecific/IOSSpecifics.cs | 7 - .../Utils/OSSpecific/LinuxSpecifics.cs | 37 - .../Utils/OSSpecific/MacOSSpecifics.cs | 9 - .../Utils/OSSpecific/WindowsSpecifics.cs | 10 - OpenSteamworks.Client/Utils/OSSpecifics.cs | 18 - .../Utils/TemporaryEnvVars.cs | 33 - SteamFlow/Cargo.lock | 817 ++++--- SteamFlow/Cargo.toml | 4 +- SteamFlow/ROADMAP.md | 1 + SteamFlow/src/cloud_sync.rs | 346 +++ SteamFlow/src/config.rs | 122 +- SteamFlow/src/download_pipeline.rs | 56 +- SteamFlow/src/lib.rs | 1 + SteamFlow/src/library.rs | 37 +- SteamFlow/src/models.rs | 17 + SteamFlow/src/steam_client.rs | 564 ++++- SteamFlow/src/ui.rs | 416 +++- docs/MakeSig.java | 218 -- 294 files changed, 1945 insertions(+), 23608 deletions(-) delete mode 100644 AvaloniaCommon/Assets/error.ico delete mode 100644 AvaloniaCommon/Assets/information.ico delete mode 100644 AvaloniaCommon/Assets/question.ico delete mode 100644 AvaloniaCommon/Assets/warning.ico delete mode 100644 AvaloniaCommon/AvaloniaCommon.csproj delete mode 100644 AvaloniaCommon/Enums/MessageBoxButton.cs delete mode 100644 AvaloniaCommon/Enums/MessageBoxIcon.cs delete mode 100644 AvaloniaCommon/MessageBox.cs delete mode 100644 AvaloniaCommon/Theme.cs delete mode 100644 AvaloniaCommon/ViewModelBase.cs delete mode 100644 AvaloniaCommon/ViewModels/MessageBoxViewModel.cs delete mode 100644 AvaloniaCommon/Views/MessageBox.axaml delete mode 100644 AvaloniaCommon/Views/MessageBox.axaml.cs delete mode 100644 AvaloniaCommon/nuget.config delete mode 100644 ChromeTestClient/ChromeIPCClient.cs delete mode 100644 ChromeTestClient/ChromeTestClient.csproj delete mode 100644 ChromeTestClient/EHTMLCommands.cs delete mode 100644 ChromeTestClient/HTMLProtoMsg.cs delete mode 100644 ChromeTestClient/LiteHTMLHost.cs delete mode 100644 ChromeTestClient/Platform/Globals.cs delete mode 100644 ChromeTestClient/Platform/IIPCImpl.cs delete mode 100644 ChromeTestClient/Platform/Linux/ErrnoException.cs delete mode 100644 ChromeTestClient/Platform/Linux/IPCImpl.cs delete mode 100644 ChromeTestClient/Platform/Linux/LinuxData.cs delete mode 100644 ChromeTestClient/Platform/Linux/LinuxEvent.cs delete mode 100644 ChromeTestClient/Platform/Linux/LinuxMutex.cs delete mode 100644 ChromeTestClient/Platform/Linux/LinuxSharedMemory.cs delete mode 100644 ChromeTestClient/Platform/Linux/MutexDisposable.cs delete mode 100644 ChromeTestClient/Platform/Linux/SteamLinuxMutex.cs delete mode 100644 ChromeTestClient/Program.cs delete mode 100644 ChromeTestClient/README.md delete mode 100644 ChromeTestClient/SharedMemStream.cs delete mode 100644 ChromeTestClient/nuget.config delete mode 100644 GameOverlayDebugTarget/App.axaml delete mode 100644 GameOverlayDebugTarget/App.axaml.cs delete mode 100644 GameOverlayDebugTarget/GameOverlayDebugTarget.csproj delete mode 100644 GameOverlayDebugTarget/MainWindow.axaml delete mode 100644 GameOverlayDebugTarget/MainWindow.axaml.cs delete mode 100644 GameOverlayDebugTarget/Program.cs delete mode 100644 GameOverlayDebugTarget/app.manifest delete mode 100644 GameOverlayDebugTarget/nuget.config delete mode 100644 GameOverlayUI/AvaloniaApp.axaml delete mode 100644 GameOverlayUI/AvaloniaApp.axaml.cs delete mode 100644 GameOverlayUI/GameOverlayUI.csproj delete mode 100644 GameOverlayUI/IPC/DynDisplayData.cs delete mode 100644 GameOverlayUI/IPC/DynInputData.cs delete mode 100644 GameOverlayUI/IPC/EInputType.cs delete mode 100644 GameOverlayUI/IPC/EOverlayState.cs delete mode 100644 GameOverlayUI/IPC/InputData.cs delete mode 100644 GameOverlayUI/IPC/OverlayControlData.cs delete mode 100644 GameOverlayUI/IPC/SharedMemoryManager.cs delete mode 100644 GameOverlayUI/Impl/OverlayLauncher.cs delete mode 100644 GameOverlayUI/Impl/OverlayLauncherFactory.cs delete mode 100644 GameOverlayUI/Program.cs delete mode 100644 GameOverlayUI/ViewModels/AvaloniaAppViewModel.cs delete mode 100644 GameOverlayUI/ViewModels/CustomWindowViewModel.cs delete mode 100644 GameOverlayUI/ViewModels/MainViewViewModel.cs delete mode 100644 GameOverlayUI/Views/CustomWindowView.axaml delete mode 100644 GameOverlayUI/Views/CustomWindowView.axaml.cs delete mode 100644 GameOverlayUI/Views/MainView.axaml delete mode 100644 GameOverlayUI/Views/MainView.axaml.cs delete mode 100644 GameOverlayUI/nuget.config delete mode 100644 Installer/Assets/opensteam-logo.ico delete mode 100644 Installer/AvaloniaApp.axaml delete mode 100644 Installer/AvaloniaApp.axaml.cs delete mode 100644 Installer/Controls/Translatable.cs delete mode 100644 Installer/Core/InstallationManager.cs delete mode 100644 Installer/Core/LocalizedException.cs delete mode 100644 Installer/Core/SteamManifest.cs delete mode 100644 Installer/Enums/InstallAction.cs delete mode 100644 Installer/Extensions/ControlExtensions.cs delete mode 100644 Installer/Extensions/HttpClientExtensions.cs delete mode 100644 Installer/Extensions/RegistryKeyExtensions.cs delete mode 100644 Installer/Extensions/StreamExtensions.cs delete mode 100644 Installer/Extensions/VisualExtensions.cs delete mode 100644 Installer/Extensions/ZipArchiveExtensions.cs delete mode 100644 Installer/Installer.csproj delete mode 100644 Installer/Program.cs delete mode 100644 Installer/Translation/ELanguage.cs delete mode 100644 Installer/Translation/TranslationManager.cs delete mode 100644 Installer/Translations/english.json delete mode 100644 Installer/Translations/finnish.json delete mode 100644 Installer/ViewModels/AvaloniaAppViewModel.cs delete mode 100644 Installer/ViewModels/LanguageViewModel.cs delete mode 100644 Installer/ViewModels/MainWindowViewModel.cs delete mode 100644 Installer/ViewModels/Pages/ChooseActionPageViewModel.cs delete mode 100644 Installer/ViewModels/Pages/ChooseInstallDirectoryPageViewModel.cs delete mode 100644 Installer/ViewModels/Pages/InstallingPageViewModel.cs delete mode 100644 Installer/ViewModels/Pages/PlaceholderPageViewModel.cs delete mode 100644 Installer/ViewModels/Pages/ProgressPageViewModel.cs delete mode 100644 Installer/ViewModels/Pages/WelcomePageViewModel.cs delete mode 100644 Installer/ViewModels/ViewModelBase.cs delete mode 100644 Installer/Views/Pages/ChooseActionPage.axaml delete mode 100644 Installer/Views/Pages/ChooseActionPage.axaml.cs delete mode 100644 Installer/Views/Pages/ChooseInstallDirectoryPage.axaml delete mode 100644 Installer/Views/Pages/ChooseInstallDirectoryPage.axaml.cs delete mode 100644 Installer/Views/Pages/InstallingPage.axaml delete mode 100644 Installer/Views/Pages/InstallingPage.axaml.cs delete mode 100644 Installer/Views/Pages/PlaceholderPage.axaml delete mode 100644 Installer/Views/Pages/PlaceholderPage.axaml.cs delete mode 100644 Installer/Views/Pages/WelcomePage.axaml delete mode 100644 Installer/Views/Pages/WelcomePage.axaml.cs delete mode 100644 Installer/Views/Windows/MainWindow.axaml delete mode 100644 Installer/Views/Windows/MainWindow.axaml.cs delete mode 100644 Installer/WindowToolbar.cs delete mode 100644 Installer/app.manifest delete mode 100644 OpenSteamClient/Assets/arrow_back.svg delete mode 100644 OpenSteamClient/Assets/arrow_forward.svg delete mode 100644 OpenSteamClient/Assets/error.ico delete mode 100644 OpenSteamClient/Assets/information.ico delete mode 100644 OpenSteamClient/Assets/opensteam-logo.ico delete mode 100644 OpenSteamClient/Assets/plus.png delete mode 100644 OpenSteamClient/Assets/question.ico delete mode 100644 OpenSteamClient/Assets/refresh.svg delete mode 100644 OpenSteamClient/Assets/unknown.png delete mode 100644 OpenSteamClient/Assets/warning.ico delete mode 100644 OpenSteamClient/AvaloniaApp.axaml delete mode 100644 OpenSteamClient/AvaloniaApp.axaml.cs delete mode 100644 OpenSteamClient/Controls/BasePage.cs delete mode 100644 OpenSteamClient/Controls/BaseWebPage.axaml delete mode 100644 OpenSteamClient/Controls/BaseWebPage.axaml.cs delete mode 100644 OpenSteamClient/Controls/HTMLSurface.axaml delete mode 100644 OpenSteamClient/Controls/HTMLSurface.axaml.cs delete mode 100644 OpenSteamClient/Controls/Translatable.cs delete mode 100644 OpenSteamClient/Entry.cs delete mode 100644 OpenSteamClient/Extensions/ControlExtensions.cs delete mode 100644 OpenSteamClient/Extensions/VisualExtensions.cs delete mode 100644 OpenSteamClient/JsonContext.cs delete mode 100644 OpenSteamClient/OpenSteamClient.csproj delete mode 100644 OpenSteamClient/PlatformSpecific/X11Key.cs delete mode 100644 OpenSteamClient/PlatformSpecific/X11KeyTransform.cs delete mode 100644 OpenSteamClient/Program.cs delete mode 100644 OpenSteamClient/Properties/launchSettings.json delete mode 100644 OpenSteamClient/Translation/TranslationManager.cs delete mode 100644 OpenSteamClient/Translations/english.json delete mode 100644 OpenSteamClient/Translations/finnish.json delete mode 100644 OpenSteamClient/UIImpl/FriendsUI.cs delete mode 100644 OpenSteamClient/ViewModels/AccountPickerWindowViewModel.cs delete mode 100644 OpenSteamClient/ViewModels/AppSettingsWindowViewModel.cs delete mode 100644 OpenSteamClient/ViewModels/AvaloniaAppViewModel.cs delete mode 100644 OpenSteamClient/ViewModels/ConsolePageViewModel.cs delete mode 100644 OpenSteamClient/ViewModels/Downloads/DownloadItemViewModel.cs delete mode 100644 OpenSteamClient/ViewModels/Downloads/DownloadsPageViewModel.cs delete mode 100644 OpenSteamClient/ViewModels/Friends/FriendViewModel.cs delete mode 100644 OpenSteamClient/ViewModels/Friends/FriendsListViewModel.cs delete mode 100644 OpenSteamClient/ViewModels/Friends/RichPresenceViewModel.cs delete mode 100644 OpenSteamClient/ViewModels/IDNameViewModel.cs delete mode 100644 OpenSteamClient/ViewModels/LaunchOptionViewModel.cs delete mode 100644 OpenSteamClient/ViewModels/Library/CollectionItemViewModel.cs delete mode 100644 OpenSteamClient/ViewModels/Library/FocusedAppPaneViewModel.cs delete mode 100644 OpenSteamClient/ViewModels/Library/LibraryAppViewModel.cs delete mode 100644 OpenSteamClient/ViewModels/Library/Node.cs delete mode 100644 OpenSteamClient/ViewModels/LibraryFolderViewModel.cs delete mode 100644 OpenSteamClient/ViewModels/LibraryPageViewModel.cs delete mode 100644 OpenSteamClient/ViewModels/LoginWindowViewModel.cs delete mode 100644 OpenSteamClient/ViewModels/MainWindowViewModel.cs delete mode 100644 OpenSteamClient/ViewModels/MenuItemViewModel.cs delete mode 100644 OpenSteamClient/ViewModels/PageHeaderViewModel.cs delete mode 100644 OpenSteamClient/ViewModels/PickLaunchOptionDialogViewModel.cs delete mode 100644 OpenSteamClient/ViewModels/ProgressWindowViewModel.cs delete mode 100644 OpenSteamClient/ViewModels/README.md delete mode 100644 OpenSteamClient/ViewModels/SavedAccountViewModel.cs delete mode 100644 OpenSteamClient/ViewModels/SecondFactorNeededDialogViewModel.cs delete mode 100644 OpenSteamClient/ViewModels/SelectInstallDirectoryDialogViewModel.cs delete mode 100644 OpenSteamClient/ViewModels/SettingsWindowViewModel.cs delete mode 100644 OpenSteamClient/ViewModels/WebviewPageViewModel.cs delete mode 100644 OpenSteamClient/Views/Debugging/Borked/InterfaceDebugger.axaml delete mode 100644 OpenSteamClient/Views/Debugging/Borked/InterfaceDebugger.axaml.cs delete mode 100644 OpenSteamClient/Views/Debugging/Borked/InterfaceList.axaml delete mode 100644 OpenSteamClient/Views/Debugging/Borked/InterfaceList.axaml.cs delete mode 100644 OpenSteamClient/Views/Debugging/HTMLSurfaceTest.axaml delete mode 100644 OpenSteamClient/Views/Debugging/HTMLSurfaceTest.axaml.cs delete mode 100644 OpenSteamClient/Views/Dialogs/PickLaunchOptionDialog.axaml delete mode 100644 OpenSteamClient/Views/Dialogs/PickLaunchOptionDialog.axaml.cs delete mode 100644 OpenSteamClient/Views/Dialogs/SecondFactorNeededDialog.axaml delete mode 100644 OpenSteamClient/Views/Dialogs/SecondFactorNeededDialog.axaml.cs delete mode 100644 OpenSteamClient/Views/Dialogs/SelectInstallDirectoryDialog.axaml delete mode 100644 OpenSteamClient/Views/Dialogs/SelectInstallDirectoryDialog.axaml.cs delete mode 100644 OpenSteamClient/Views/Friends/FriendsList.axaml delete mode 100644 OpenSteamClient/Views/Friends/FriendsList.axaml.cs delete mode 100644 OpenSteamClient/Views/Library/FocusedAppPane.axaml delete mode 100644 OpenSteamClient/Views/Library/FocusedAppPane.axaml.cs delete mode 100644 OpenSteamClient/Views/Pages/ConsolePage.axaml delete mode 100644 OpenSteamClient/Views/Pages/ConsolePage.axaml.cs delete mode 100644 OpenSteamClient/Views/Pages/DownloadsPage.axaml delete mode 100644 OpenSteamClient/Views/Pages/DownloadsPage.axaml.cs delete mode 100644 OpenSteamClient/Views/Pages/LibraryPage.axaml delete mode 100644 OpenSteamClient/Views/Pages/LibraryPage.axaml.cs delete mode 100644 OpenSteamClient/Views/Pages/WebBased/CommunityPage.axaml.cs delete mode 100644 OpenSteamClient/Views/Pages/WebBased/StorePage.axaml.cs delete mode 100644 OpenSteamClient/Views/README.md delete mode 100644 OpenSteamClient/Views/Windows/AccountPickerWindow.axaml delete mode 100644 OpenSteamClient/Views/Windows/AccountPickerWindow.axaml.cs delete mode 100644 OpenSteamClient/Views/Windows/AppSettingsWindow.axaml delete mode 100644 OpenSteamClient/Views/Windows/AppSettingsWindow.axaml.cs delete mode 100644 OpenSteamClient/Views/Windows/LoginWindow.axaml delete mode 100644 OpenSteamClient/Views/Windows/LoginWindow.axaml.cs delete mode 100644 OpenSteamClient/Views/Windows/MainWindow.axaml delete mode 100644 OpenSteamClient/Views/Windows/MainWindow.axaml.cs delete mode 100644 OpenSteamClient/Views/Windows/ProgressWindow.axaml delete mode 100644 OpenSteamClient/Views/Windows/ProgressWindow.axaml.cs delete mode 100644 OpenSteamClient/Views/Windows/SettingsWindow.axaml delete mode 100644 OpenSteamClient/Views/Windows/SettingsWindow.axaml.cs delete mode 100644 OpenSteamClient/app.manifest delete mode 100644 OpenSteamClient/nuget.config delete mode 100644 OpenSteamworks.Client/Apps/AppsManager.cs delete mode 100644 OpenSteamworks.Client/Apps/Assets/ELibraryAssetType.cs delete mode 100644 OpenSteamworks.Client/Apps/Assets/LibraryAssetsFile.cs delete mode 100644 OpenSteamworks.Client/Apps/Assets/LibraryAssetsGenerator.cs delete mode 100644 OpenSteamworks.Client/Apps/BannedApp.cs delete mode 100644 OpenSteamworks.Client/Apps/CloudConfigStore.cs delete mode 100644 OpenSteamworks.Client/Apps/IApp.cs delete mode 100644 OpenSteamworks.Client/Apps/IAppAssetsInterface.cs delete mode 100644 OpenSteamworks.Client/Apps/IAppConfigInterface.cs delete mode 100644 OpenSteamworks.Client/Apps/IAppInfoAccessInterface.cs delete mode 100644 OpenSteamworks.Client/Apps/IAppInfoUpdateInterface.cs delete mode 100644 OpenSteamworks.Client/Apps/IAppInstallInterface.cs delete mode 100644 OpenSteamworks.Client/Apps/IAppLaunchInterface.cs delete mode 100644 OpenSteamworks.Client/Apps/ILaunchOption.cs delete mode 100644 OpenSteamworks.Client/Apps/LaunchProgressEventArgs.cs delete mode 100644 OpenSteamworks.Client/Apps/Library/Collection.cs delete mode 100644 OpenSteamworks.Client/Apps/Library/FilterGroup.cs delete mode 100644 OpenSteamworks.Client/Apps/Library/JSONCollection.cs delete mode 100644 OpenSteamworks.Client/Apps/Library/JSONFilterGroup.cs delete mode 100644 OpenSteamworks.Client/Apps/Library/JSONFilterSpec.cs delete mode 100644 OpenSteamworks.Client/Apps/Library/Library.cs delete mode 100644 OpenSteamworks.Client/Apps/Library/LibraryManager.cs delete mode 100644 OpenSteamworks.Client/Apps/ShortcutApp.cs delete mode 100644 OpenSteamworks.Client/Apps/SteamApp.cs delete mode 100644 OpenSteamworks.Client/Client.cs delete mode 100644 OpenSteamworks.Client/CommonEventArgs/EResultEventArgs.cs delete mode 100644 OpenSteamworks.Client/CommonEventArgs/README.md delete mode 100644 OpenSteamworks.Client/Config/AdvancedConfig.cs delete mode 100644 OpenSteamworks.Client/Config/Attributes/ConfigAdvancedAttribute.cs delete mode 100644 OpenSteamworks.Client/Config/Attributes/ConfigCategoryAttribute.cs delete mode 100644 OpenSteamworks.Client/Config/Attributes/ConfigDescriptionAttribute.cs delete mode 100644 OpenSteamworks.Client/Config/Attributes/ConfigNameAttribute.cs delete mode 100644 OpenSteamworks.Client/Config/Attributes/ConfigNeverVisibleAttribute.cs delete mode 100644 OpenSteamworks.Client/Config/BootstrapperState.cs delete mode 100644 OpenSteamworks.Client/Config/ConfigJsonContext.cs delete mode 100644 OpenSteamworks.Client/Config/ConfigManager.cs delete mode 100644 OpenSteamworks.Client/Config/GlobalSettings.cs delete mode 100644 OpenSteamworks.Client/Config/IConfigFile.cs delete mode 100644 OpenSteamworks.Client/Config/LibrarySettings.cs delete mode 100644 OpenSteamworks.Client/Config/LoginUsers.cs delete mode 100644 OpenSteamworks.Client/Config/NotificationSettings.cs delete mode 100644 OpenSteamworks.Client/Config/UserSettings.cs delete mode 100644 OpenSteamworks.Client/DI/Container.cs delete mode 100644 OpenSteamworks.Client/DI/LifetimeManager.cs delete mode 100644 OpenSteamworks.Client/DI/OverridingContainer.cs delete mode 100644 OpenSteamworks.Client/Enums/DataRateUnit.cs delete mode 100644 OpenSteamworks.Client/Enums/DataSizeUnit.cs delete mode 100644 OpenSteamworks.Client/Enums/ELibraryAppFeaturesFilter.cs delete mode 100644 OpenSteamworks.Client/Enums/ELibraryAppStateFilter.cs delete mode 100644 OpenSteamworks.Client/Enums/EUserConfigStoreNamespace.cs delete mode 100644 OpenSteamworks.Client/Experimental/TransportManager.cs delete mode 100644 OpenSteamworks.Client/Friends/FriendsManager.cs delete mode 100644 OpenSteamworks.Client/Friends/IFriendsUI.cs delete mode 100644 OpenSteamworks.Client/GlobalUsings.cs delete mode 100644 OpenSteamworks.Client/JsonContext.cs delete mode 100644 OpenSteamworks.Client/Login/LoginManager.cs delete mode 100644 OpenSteamworks.Client/Login/LoginPoll.cs delete mode 100644 OpenSteamworks.Client/Login/LoginUser.cs delete mode 100644 OpenSteamworks.Client/Managers/InstallManager.cs delete mode 100644 OpenSteamworks.Client/Managers/ShaderManager.cs delete mode 100644 OpenSteamworks.Client/Notifications/INotificationUI.cs delete mode 100644 OpenSteamworks.Client/Notifications/NotificationManager.cs delete mode 100644 OpenSteamworks.Client/OpenSteamworks.Client.csproj delete mode 100644 OpenSteamworks.Client/README.md delete mode 100644 OpenSteamworks.Client/Startup/Bootstrapper.cs delete mode 100644 OpenSteamworks.Client/Startup/SteamHTML.cs delete mode 100644 OpenSteamworks.Client/Startup/SteamService.cs delete mode 100644 OpenSteamworks.Client/Utils/DataUnitStrings.cs delete mode 100644 OpenSteamworks.Client/Utils/Logger.cs delete mode 100644 OpenSteamworks.Client/Utils/LoggerFactory.cs delete mode 100644 OpenSteamworks.Client/Utils/OSCheck.cs delete mode 100644 OpenSteamworks.Client/Utils/OSSpecific/IOSSpecifics.cs delete mode 100644 OpenSteamworks.Client/Utils/OSSpecific/LinuxSpecifics.cs delete mode 100644 OpenSteamworks.Client/Utils/OSSpecific/MacOSSpecifics.cs delete mode 100644 OpenSteamworks.Client/Utils/OSSpecific/WindowsSpecifics.cs delete mode 100644 OpenSteamworks.Client/Utils/OSSpecifics.cs delete mode 100644 OpenSteamworks.Client/Utils/TemporaryEnvVars.cs create mode 100644 SteamFlow/src/cloud_sync.rs delete mode 100644 docs/MakeSig.java diff --git a/AvaloniaCommon/Assets/error.ico b/AvaloniaCommon/Assets/error.ico deleted file mode 100644 index 529371fe4fa7bddc09f59d71ea20f335b46198fd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 92478 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 diff --git a/AvaloniaCommon/Assets/information.ico b/AvaloniaCommon/Assets/information.ico deleted file mode 100644 index 3a7f9bddcb9d1316af29df3d69e617220f9d3736..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 92478 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 diff --git a/AvaloniaCommon/Assets/question.ico b/AvaloniaCommon/Assets/question.ico deleted file mode 100644 index db04d421e835684c40cdba8eebb553109f453b9a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 92478 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 MRjwnk7MREXA7p5i82|tP diff --git a/AvaloniaCommon/Assets/warning.ico b/AvaloniaCommon/Assets/warning.ico deleted file mode 100644 index d4bd0f53f0ece5348fd19bb499f195cb0ac6423b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 92478 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 - - - $(CommonNetVersion) - enable - enable - true - - - - - - - - - - - - diff --git a/AvaloniaCommon/Enums/MessageBoxButton.cs b/AvaloniaCommon/Enums/MessageBoxButton.cs deleted file mode 100644 index 9dbd3571..00000000 --- a/AvaloniaCommon/Enums/MessageBoxButton.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; - -namespace AvaloniaCommon.Enums; - -[Flags] -public enum MessageBoxButton -{ - No = 1, - Yes = 2, - Ok = 4, - Cancel = 8 -} \ No newline at end of file diff --git a/AvaloniaCommon/Enums/MessageBoxIcon.cs b/AvaloniaCommon/Enums/MessageBoxIcon.cs deleted file mode 100644 index 7d35f0fc..00000000 --- a/AvaloniaCommon/Enums/MessageBoxIcon.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; - -namespace AvaloniaCommon.Enums; - -[Flags] -public enum MessageBoxIcon -{ - QUESTION = 1, - INFORMATION = 2, - WARNING = 4, - ERROR = 8 -} \ No newline at end of file diff --git a/AvaloniaCommon/MessageBox.cs b/AvaloniaCommon/MessageBox.cs deleted file mode 100644 index f88d7b51..00000000 --- a/AvaloniaCommon/MessageBox.cs +++ /dev/null @@ -1,91 +0,0 @@ -namespace AvaloniaCommon; - -using Avalonia.Controls; -using Avalonia.Threading; -using AvaloniaCommon.Enums; -using AvaloniaCommon.ViewModels; - -public static class MessageBox -{ - public static MessageBoxButton? Show(string title, string message) - { - return Show(title, "", message); - } - - public static MessageBoxButton? Error(string title, string message) - { - return Error(title, "", message); - } - - public static MessageBoxButton? Error(Exception e) - { - return Error(string.IsNullOrEmpty(e.Message) ? "Unknown error" : e.Message, e.Message, e.ToString()); - } - public static MessageBoxButton? QuestionYesNo(string title, string header, string message) - { - return Show(title, header, message, MessageBoxIcon.QUESTION, MessageBoxButton.No | MessageBoxButton.Yes); - } - public static MessageBoxButton? QuestionYesNoCancel(string title, string header, string message) - { - return Show(title, header, message, MessageBoxIcon.QUESTION, MessageBoxButton.No | MessageBoxButton.Yes | MessageBoxButton.Cancel); - } - public static MessageBoxButton? Info(string title, string header, string message) - { - return Show(title, header, message, MessageBoxIcon.INFORMATION); - } - public static MessageBoxButton? Warning(string title, string header, string message) - { - return Show(title, header, message, MessageBoxIcon.WARNING); - } - public static MessageBoxButton? Error(string title, string header, string message) - { - return Show(title, header, message, MessageBoxIcon.ERROR); - } - - public static MessageBoxButton? Show(string title, string header, string message) - { - return Show(title, header, message, MessageBoxIcon.INFORMATION); - } - - public static MessageBoxButton? Show(string title, string header, string message, MessageBoxIcon icon = MessageBoxIcon.INFORMATION, MessageBoxButton buttons = MessageBoxButton.Ok) - { - if (!Dispatcher.UIThread.CheckAccess()) - { - return Dispatcher.UIThread.Invoke(() => ShowInternal(title, header, message, icon, buttons)); - } - else - { - return ShowInternal(title, header, message, icon, buttons); - } - } - - internal static MessageBoxButton? ShowInternal(string title, string header, string message, MessageBoxIcon icon, MessageBoxButton buttons) - { - var messageBoxViewModel = new MessageBoxViewModel(icon, buttons) - { - Title = title, - Header = header, - Content = message - }; - - var messageBox = new Views.MessageBox(); - messageBoxViewModel.SetMessageBox(messageBox); - messageBox.DataContext = messageBoxViewModel; - - using (var source = new CancellationTokenSource()) - { - var tcs = new TaskCompletionSource(); - messageBox.Closing += (object? sender, WindowClosingEventArgs args) => - { - tcs.TrySetResult(messageBoxViewModel.ButtonClicked); - args.Cancel = false; - }; - - messageBox.Show(); - - tcs.Task.ContinueWith(t => source.Cancel(), TaskScheduler.FromCurrentSynchronizationContext()); - Dispatcher.UIThread.MainLoop(source.Token); - return tcs.Task.Result; - } - } -} diff --git a/AvaloniaCommon/Theme.cs b/AvaloniaCommon/Theme.cs deleted file mode 100644 index 8583c3f4..00000000 --- a/AvaloniaCommon/Theme.cs +++ /dev/null @@ -1,63 +0,0 @@ -using System; -using System.Diagnostics.CodeAnalysis; -using Avalonia; -using Avalonia.Media; -using Avalonia.Styling; - -namespace AvaloniaCommon; - -public class Theme -{ - public IBrush AccentButtonBackground - { - get - { - return (IBrush)GetResource("AccentButtonBackground"); - } - } - - public IBrush AccentButtonForeground - { - get - { - return (IBrush)GetResource("AccentButtonForeground"); - } - } - - public IBrush ButtonBackground - { - get - { - return (IBrush)GetResource("ButtonBackground"); - } - } - - public IBrush ButtonForeground - { - get - { - return (IBrush)GetResource("ButtonForeground"); - } - } - - private object GetResource(string key) - { - app.TryGetResource(key, ThemeVariant.Default, out object? val); - ThrowIfNull(val); - return val; - } - - private void ThrowIfNull([NotNull] object? val) - { - if (val == null) - { - throw new Exception("No styles where there should be"); - } - } - - private Application app; - public Theme(Application app) - { - this.app = app; - } -} \ No newline at end of file diff --git a/AvaloniaCommon/ViewModelBase.cs b/AvaloniaCommon/ViewModelBase.cs deleted file mode 100644 index 31430754..00000000 --- a/AvaloniaCommon/ViewModelBase.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System; -using System.Diagnostics; -using CommunityToolkit.Mvvm.ComponentModel; - -namespace AvaloniaCommon; - -public partial class ViewModelBase : ObservableObject -{ - -} diff --git a/AvaloniaCommon/ViewModels/MessageBoxViewModel.cs b/AvaloniaCommon/ViewModels/MessageBoxViewModel.cs deleted file mode 100644 index 356eb700..00000000 --- a/AvaloniaCommon/ViewModels/MessageBoxViewModel.cs +++ /dev/null @@ -1,112 +0,0 @@ -using System; -using Avalonia.Controls; -using Avalonia.Media.Imaging; -using Avalonia.Platform; -using Avalonia.Threading; -using AvaloniaCommon.Enums; -using CommunityToolkit.Mvvm.ComponentModel; - -namespace AvaloniaCommon.ViewModels; - -public partial class MessageBoxViewModel : ViewModelBase -{ - [ObservableProperty] - private string title = ""; - - [ObservableProperty] - [NotifyPropertyChangedFor("HasHeader")] - private string header = ""; - public bool HasHeader => !string.IsNullOrEmpty(this.Header); - - [ObservableProperty] - private string content = ""; - - [ObservableProperty] - private string iconPath; - - [ObservableProperty] - private Bitmap icon; - - [ObservableProperty] - private WindowIcon windowIcon; - - [NotifyPropertyChangedFor("IsOkShowed")] - [NotifyPropertyChangedFor("IsYesShowed")] - [NotifyPropertyChangedFor("IsNoShowed")] - [NotifyPropertyChangedFor("IsCancelShowed")] - - [ObservableProperty] - private MessageBoxButton enabledButtons; - public MessageBoxButton? ButtonClicked { get; private set; } - public bool IsOkShowed => EnabledButtons.HasFlag(MessageBoxButton.Ok); - public bool IsYesShowed => EnabledButtons.HasFlag(MessageBoxButton.Yes); - public bool IsNoShowed => EnabledButtons.HasFlag(MessageBoxButton.No); - public bool IsCancelShowed => EnabledButtons.HasFlag(MessageBoxButton.Cancel); - public Action? Copy { get; set; } - public Action? EnterPressed { get; set; } - public Action? EscPressed { get; set; } - private AvaloniaCommon.Views.MessageBox? messageBox; - public MessageBoxViewModel(MessageBoxIcon icon, MessageBoxButton enabledButtons) - { - - this.enabledButtons = enabledButtons; - this.EnterPressed = PressDefaultIfPossible; - this.IconPath = $"avares://AvaloniaCommon/Assets/{icon.ToString().ToLowerInvariant()}.ico"; - this.Icon = new Bitmap(AssetLoader.Open(new Uri(this.iconPath))); - this.WindowIcon = new WindowIcon(this.Icon); - } - - // Clipboard isn't accessible from App, instead it's available from every Control, so do this hack which is totally against mvvm principles - public void SetMessageBox(AvaloniaCommon.Views.MessageBox messageBox) - { - this.messageBox = messageBox; - this.Copy = messageBox.Copy; - this.EscPressed = messageBox.Close; - } - - public void PressDefaultIfPossible() - { - // If there's only one button enabled, then click it - switch (EnabledButtons) - { - case MessageBoxButton.No: - NoClicked(); - break; - case MessageBoxButton.Yes: - YesClicked(); - break; - case MessageBoxButton.Cancel: - CancelClicked(); - break; - case MessageBoxButton.Ok: - OkClicked(); - break; - } - // If there's multiple, try to cancel, never take a yes action automatically - if (EnabledButtons.HasFlag(MessageBoxButton.Cancel)) - { - CancelClicked(); - } - } - public void OkClicked() - { - ButtonClicked = MessageBoxButton.Ok; - messageBox?.QueueClose(); - } - public void YesClicked() - { - ButtonClicked = MessageBoxButton.Yes; - messageBox?.QueueClose(); - } - public void NoClicked() - { - ButtonClicked = MessageBoxButton.No; - messageBox?.QueueClose(); - } - public void CancelClicked() - { - ButtonClicked = MessageBoxButton.Cancel; - messageBox?.QueueClose(); - } - -} \ No newline at end of file diff --git a/AvaloniaCommon/Views/MessageBox.axaml b/AvaloniaCommon/Views/MessageBox.axaml deleted file mode 100644 index 6e2eefb1..00000000 --- a/AvaloniaCommon/Views/MessageBox.axaml +++ /dev/null @@ -1,110 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/GameOverlayUI/Views/CustomWindowView.axaml.cs b/GameOverlayUI/Views/CustomWindowView.axaml.cs deleted file mode 100644 index 5532e098..00000000 --- a/GameOverlayUI/Views/CustomWindowView.axaml.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Avalonia.Controls; - -namespace GameOverlayUI.Views; - -public partial class CustomWindowView : UserControl -{ - public CustomWindowView() - { - InitializeComponent(); - } -} \ No newline at end of file diff --git a/GameOverlayUI/Views/MainView.axaml b/GameOverlayUI/Views/MainView.axaml deleted file mode 100644 index e1a78e21..00000000 --- a/GameOverlayUI/Views/MainView.axaml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - OSC Overlay Test - - - - - - - - - - diff --git a/GameOverlayUI/Views/MainView.axaml.cs b/GameOverlayUI/Views/MainView.axaml.cs deleted file mode 100644 index 09d8c369..00000000 --- a/GameOverlayUI/Views/MainView.axaml.cs +++ /dev/null @@ -1,111 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using Avalonia; -using Avalonia.Controls; -using Avalonia.VisualTree; -using GameOverlayUI.ViewModels; - -namespace GameOverlayUI.Views; - -public partial class MainView : Window { - private MainViewViewModel vm => (DataContext as MainViewViewModel)!; - public MainView() { - InitializeComponent(); - } - - [MemberNotNull(nameof(draggingWindowViewModel))] - private CustomWindowView? draggingWindow { get; set; } - - // The corner point where the dragging was initiated - private Point dragPoint; - private CustomWindowViewModel? draggingWindowViewModel => draggingWindow?.DataContext as CustomWindowViewModel; - - private void OnPointerPressed(object? sender, Avalonia.Input.PointerPressedEventArgs e) { - if (!e.GetCurrentPoint(null).Properties.IsLeftButtonPressed) { - return; - } - - var pos = e.GetPosition(Desktop); - Visual? vis = Desktop.GetVisualAt(pos); - Console.WriteLine("PRESSED at " + pos); - Console.WriteLine("Element is " + vis); - CustomWindowView? window = null; - bool isDrag = false; - while (window == null && vis != null) - { - Console.WriteLine("DC: " + vis.DataContext?.GetType()); - if (vis.DataContext is CustomWindowViewModel) { - isDrag = vis.Classes.Contains("draggable"); - window = vis.FindAncestorOfType(); - break; - } - - vis = vis?.Parent as Visual; - } - - var vm = window?.DataContext as CustomWindowViewModel; - - Console.WriteLine("Window is " + vm?.Title); - - if (window != null) { - ChangeFocusedWindow(vm); - } - - if (isDrag) { - draggingWindow = window; - - // This stops the window "teleporting" when it's being moved, and allows it to move wherever from a draggable area - dragPoint = e.GetPosition(Desktop) - new Point(draggingWindowViewModel.X, draggingWindowViewModel.Y); - } - } - - private void OnPointerMoved(object? sender, Avalonia.Input.PointerEventArgs e) { - var pos = e.GetPosition(Desktop); - if (draggingWindow != null) { - Console.WriteLine("MOVED to " + pos); - Console.WriteLine("W: " + draggingWindow.Bounds.Width); - Console.WriteLine("H: " + draggingWindow.Bounds.Height); - - Console.WriteLine("MW: " + Desktop.Bounds.Width); - Console.WriteLine("MH: " + Desktop.Bounds.Height); - - Console.WriteLine("DPX: " + dragPoint.X + ", DPY: " + dragPoint.Y); - - // This function does some advanced math to: - // 1. Ensure the window doesn't clip out of bounds at all - // 2. Move the window to the correct location upon dragging - // 3. Some other things I can't decipher from this code - // Don't ask me about this math, I wrote it half asleep at 3:30am, but work it does! Improve if needed. - double targetX = pos.X + draggingWindow.Bounds.Width - dragPoint.X; - double targetY = pos.Y + draggingWindow.Bounds.Height - dragPoint.Y; - - double X = Math.Clamp(targetX, 0.0 + draggingWindow.Bounds.Width, Desktop.Bounds.Width) - draggingWindow.Bounds.Width; - double Y = Math.Clamp(targetY, 0.0 + draggingWindow.Bounds.Height, Desktop.Bounds.Height) - draggingWindow.Bounds.Height; - draggingWindowViewModel.X = X; - draggingWindowViewModel.Y = Y; - - Console.WriteLine("CX: " + draggingWindowViewModel.X); - Console.WriteLine("CY: " + draggingWindowViewModel.Y); - } - } - - private CustomWindowViewModel? focusedWindow; - private void ChangeFocusedWindow(CustomWindowViewModel? newWindow) { - if (newWindow == focusedWindow) { - return; - } - - if (newWindow != null) { - newWindow.GotFocus(); - focusedWindow?.LostFocus(); - - focusedWindow = newWindow; - } - } - - private void OnPointerReleased(object? sender, Avalonia.Input.PointerReleasedEventArgs e) { - var pos = e.GetPosition(Desktop); - Console.WriteLine("RELEASED at " + pos); - draggingWindow = null; - dragPoint = new Point(0, 0); - } -} \ No newline at end of file diff --git a/GameOverlayUI/nuget.config b/GameOverlayUI/nuget.config deleted file mode 100644 index 42c6aa46..00000000 --- a/GameOverlayUI/nuget.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/Installer/Assets/opensteam-logo.ico b/Installer/Assets/opensteam-logo.ico deleted file mode 100644 index 4b4c15466f28b5c3b432fb8bdfab87abe6ec3cc3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 45839 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 diff --git a/Installer/AvaloniaApp.axaml b/Installer/AvaloniaApp.axaml deleted file mode 100644 index a8ffd692..00000000 --- a/Installer/AvaloniaApp.axaml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - - - - - - - - M18.25,3 C18.6296958,3 18.943491,3.28215388 18.9931534,3.64822944 L19,3.75 L19,20.25 C19,20.6642136 18.6642136,21 18.25,21 C17.8703042,21 17.556509,20.7178461 17.5068466,20.3517706 L17.5,20.25 L17.5,3.75 C17.5,3.33578644 17.8357864,3 18.25,3 Z M5.21966991,3.21966991 C5.48593648,2.95340335 5.90260016,2.9291973 6.19621165,3.14705176 L6.28033009,3.21966991 L14.5303301,11.4696699 C14.7965966,11.7359365 14.8208027,12.1526002 14.6029482,12.4462117 L14.5303301,12.5303301 L6.28033009,20.7803301 C5.98743687,21.0732233 5.51256313,21.0732233 5.21966991,20.7803301 C4.95340335,20.5140635 4.9291973,20.0973998 5.14705176,19.8037883 L5.21966991,19.7196699 L12.9393398,12 L5.21966991,4.28033009 C4.9267767,3.98743687 4.9267767,3.51256313 5.21966991,3.21966991 Z - M5.75,3 C5.37030423,3 5.05650904,3.28215388 5.00684662,3.64822944 L5,3.75 L5,20.25 C5,20.6642136 5.33578644,21 5.75,21 C6.12969577,21 6.44349096,20.7178461 6.49315338,20.3517706 L6.5,20.25 L6.5,3.75 C6.5,3.33578644 6.16421356,3 5.75,3 Z M18.7803301,3.21966991 C18.5140635,2.95340335 18.0973998,2.9291973 17.8037883,3.14705176 L17.7196699,3.21966991 L9.46966991,11.4696699 C9.20340335,11.7359365 9.1791973,12.1526002 9.39705176,12.4462117 L9.46966991,12.5303301 L17.7196699,20.7803301 C18.0125631,21.0732233 18.4874369,21.0732233 18.7803301,20.7803301 C19.0465966,20.5140635 19.0708027,20.0973998 18.8529482,19.8037883 L18.7803301,19.7196699 L11.0606602,12 L18.7803301,4.28033009 C19.0732233,3.98743687 19.0732233,3.51256313 18.7803301,3.21966991 Z - M12,2 C17.5228,2 22,6.47715 22,12 C22,17.5228 17.5228,22 12,22 C6.47715,22 2,17.5228 2,12 C2,6.47715 6.47715,2 12,2 Z M12,3.5 C7.30558,3.5 3.5,7.30558 3.5,12 C3.5,16.6944 7.30558,20.5 12,20.5 C16.6944,20.5 20.5,16.6944 20.5,12 C20.5,7.30558 16.6944,3.5 12,3.5 Z M16.75,12 C17.1296833,12 17.4434889,12.2821653 17.4931531,12.6482323 L17.5,12.75 L17.5,15.75 C17.5,16.1642 17.1642,16.5 16.75,16.5 C16.3703167,16.5 16.0565111,16.2178347 16.0068469,15.8517677 L16,15.75 L16,15 C15.0881,16.2143 13.6362,17 11.9999,17 C10.4748,17 9.09587,16.316 8.17857,15.237 C7.91028,14.9214 7.94862,14.4481 8.2642,14.1798 C8.57979,13.9115 9.05311,13.9499 9.3214,14.2655 C9.96322,15.0204 10.9293,15.5 11.9999,15.5 C13.32553,15.5 14.4803167,14.7625672 15.0742404,13.6746351 L15.1633,13.5 L14,13.5 C13.5858,13.5 13.25,13.1642 13.25,12.75 C13.25,12.3703167 13.5321653,12.0565111 13.8982323,12.0068469 L14,12 L16.75,12 Z M11.9999,7 C13.5368,7 14.9041,7.66036 15.8268,8.77062 C16.0915,9.08918 16.0479,9.56205 15.7294,9.8268 C15.4108,10.0916 14.9379,10.0479 14.6732,9.72938 C14.0368,8.96361 13.093,8.5 11.9999,8.5 C10.5754318,8.5 9.34895806,9.35140335 8.80281957,10.5730172 L8.72948,10.75 L10,10.75 C10.4142,10.75 10.75,11.0858 10.75,11.5 C10.75,11.8796833 10.4678347,12.1934889 10.1017677,12.2431531 L10,12.25 L7.25,12.25 C6.8703075,12.25 6.55650958,11.9678347 6.50684668,11.6017677 L6.5,11.5 L6.5,8.25 C6.5,7.83579 6.83579,7.5 7.25,7.5 C7.6296925,7.5 7.94349042,7.78215688 7.99315332,8.14823019 L8,8.25 L8,8.99955 C8.9121,7.78531 10.364,7 11.9999,7 Z - M10.5001 7.7514C10.5001 4.57577 13.0745 2.0014 16.2501 2.0014C17.196 2.0014 18.0906 2.23039 18.8794 2.6366C19.0924 2.74625 19.2401 2.95101 19.2771 3.18765C19.314 3.42429 19.2358 3.66435 19.0664 3.83371L16.3006 6.59949L17.3613 7.66015L20.1398 4.8816C20.3081 4.71337 20.5461 4.63494 20.7814 4.67023C21.0167 4.70551 21.2213 4.85033 21.3327 5.06051C21.759 5.86417 22.0001 6.78074 22.0001 7.7514C22.0001 10.927 19.4258 13.5014 16.2501 13.5014C15.7895 13.5014 15.3408 13.4471 14.9104 13.3443L7.54552 20.9632C6.42372 22.1237 4.59212 22.2096 3.36665 21.1592C2.03293 20.016 1.93771 17.9855 3.15859 16.7225L10.6339 8.98943C10.5462 8.59014 10.5001 8.17579 10.5001 7.7514ZM16.2501 3.5014C13.9029 3.5014 12.0001 5.40419 12.0001 7.7514C12.0001 8.18337 12.0643 8.59897 12.1832 8.98991C12.2624 9.25049 12.1942 9.53355 12.0049 9.72937L4.23708 17.765C3.61648 18.407 3.66488 19.4392 4.34283 20.0203C4.96577 20.5542 5.8968 20.5106 6.46704 19.9207L14.1435 11.9795C14.3435 11.7726 14.6443 11.6984 14.9176 11.7885C15.3358 11.9265 15.7834 12.0014 16.2501 12.0014C18.5973 12.0014 20.5001 10.0986 20.5001 7.7514C20.5001 7.40926 20.4598 7.07703 20.3838 6.75896L17.8916 9.25114C17.5987 9.54403 17.1238 9.54403 16.831 9.25114L14.7096 7.12982C14.4167 6.83692 14.4167 6.36205 14.7096 6.06916L17.1763 3.60246C16.8785 3.53632 16.5686 3.5014 16.2501 3.5014Z - M24,7.25 C27.1017853,7.25 29.629937,9.70601719 29.7458479,12.7794443 L29.75,13 L37,13 C37.6903559,13 38.25,13.5596441 38.25,14.25 C38.25,14.8972087 37.7581253,15.4295339 37.1278052,15.4935464 L37,15.5 L35.909,15.5 L34.2058308,38.0698451 C34.0385226,40.2866784 32.1910211,42 29.9678833,42 L18.0321167,42 C15.8089789,42 13.9614774,40.2866784 13.7941692,38.0698451 L12.09,15.5 L11,15.5 C10.3527913,15.5 9.8204661,15.0081253 9.75645361,14.3778052 L9.75,14.25 C9.75,13.6027913 10.2418747,13.0704661 10.8721948,13.0064536 L11,13 L18.25,13 C18.25,9.82436269 20.8243627,7.25 24,7.25 Z M33.4021054,15.5 L14.5978946,15.5 L16.2870795,37.8817009 C16.3559711,38.7945146 17.116707,39.5 18.0321167,39.5 L29.9678833,39.5 C30.883293,39.5 31.6440289,38.7945146 31.7129205,37.8817009 L33.4021054,15.5 Z M27.25,20.75 C27.8972087,20.75 28.4295339,21.2418747 28.4935464,21.8721948 L28.5,22 L28.5,33 C28.5,33.6903559 27.9403559,34.25 27.25,34.25 C26.6027913,34.25 26.0704661,33.7581253 26.0064536,33.1278052 L26,33 L26,22 C26,21.3096441 26.5596441,20.75 27.25,20.75 Z M20.75,20.75 C21.3972087,20.75 21.9295339,21.2418747 21.9935464,21.8721948 L22,22 L22,33 C22,33.6903559 21.4403559,34.25 20.75,34.25 C20.1027913,34.25 19.5704661,33.7581253 19.5064536,33.1278052 L19.5,33 L19.5,22 C19.5,21.3096441 20.0596441,20.75 20.75,20.75 Z M24,9.75 C22.2669685,9.75 20.8507541,11.1064548 20.7551448,12.8155761 L20.75,13 L27.25,13 C27.25,11.2050746 25.7949254,9.75 24,9.75 Z - - \ No newline at end of file diff --git a/Installer/AvaloniaApp.axaml.cs b/Installer/AvaloniaApp.axaml.cs deleted file mode 100644 index 965db194..00000000 --- a/Installer/AvaloniaApp.axaml.cs +++ /dev/null @@ -1,66 +0,0 @@ -using Avalonia; -using Avalonia.Controls.ApplicationLifetimes; -using Avalonia.Input.Platform; -using Avalonia.Markup.Xaml; -using Installer.Translation; -using Installer.ViewModels; -using Installer.Views; -using System.Threading.Tasks; -using System; -using Avalonia.Controls; -using System.Diagnostics.CodeAnalysis; -using System.Linq; -using Avalonia.Input; -using Avalonia.Styling; -using System.Text; -using Avalonia.Threading; - -namespace Installer; - -public class AvaloniaApp : Application -{ - public static TranslationManager TranslationManager { get; } = new(); - public new static AvaloniaApp? Current; - public new IClassicDesktopStyleApplicationLifetime ApplicationLifetime => (base.ApplicationLifetime as IClassicDesktopStyleApplicationLifetime)!; - public static bool DebugEnabled = false; - public static bool InLinuxDevelopment = false; - public Window? MainWindow => ApplicationLifetime.MainWindow; - - public override void Initialize() - { - AvaloniaXamlLoader.Load(this); - } - - public override void OnFrameworkInitializationCompleted() - { - TranslationManager.LoadCurrentSystemTranslation(); - base.OnFrameworkInitializationCompleted(); - OpenMainWindow(); - } - - public void OpenMainWindow() - { - if (ApplicationLifetime.MainWindow != null) - { - if (ApplicationLifetime.MainWindow.IsActive) - { - // Not closed but maybe hidden, maybe shown in background - ApplicationLifetime.MainWindow.Show(); - ApplicationLifetime.MainWindow.Activate(); - return; - } - } else { - var wnd = new MainWindow(); - wnd.DataContext = new MainWindowViewModel(wnd); - ApplicationLifetime.MainWindow = wnd; - ApplicationLifetime.MainWindow.Show(); - } - } - - public AvaloniaApp() - { - Current = this; - Name = "Installer"; - DataContext = new AvaloniaAppViewModel(); - } -} diff --git a/Installer/Controls/Translatable.cs b/Installer/Controls/Translatable.cs deleted file mode 100644 index f7965218..00000000 --- a/Installer/Controls/Translatable.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Windows.Input; -using Avalonia; -using Avalonia.Data; -using Avalonia.Input; -using Avalonia.Interactivity; - -namespace Installer.Controls; - -public class Translatable : AvaloniaObject -{ - public static readonly AttachedProperty TranslationKeyProperty = - AvaloniaProperty.RegisterAttached("TranslationKey", "", false, Avalonia.Data.BindingMode.OneWay); - - public static readonly AttachedProperty DefaultTextProperty = - AvaloniaProperty.RegisterAttached("DefaultText", "", false, Avalonia.Data.BindingMode.OneWay); - - public static void SetTranslationKey(AvaloniaObject element, string val) - { - element.SetValue(TranslationKeyProperty, val); - } - - public static string GetTranslationKey(AvaloniaObject element) - { - return element.GetValue(TranslationKeyProperty); - } - - public static void SetDefaultText(AvaloniaObject element, string val) - { - element.SetValue(DefaultTextProperty, val); - } - - public static string GetDefaultText(AvaloniaObject element) - { - return element.GetValue(DefaultTextProperty); - } -} \ No newline at end of file diff --git a/Installer/Core/InstallationManager.cs b/Installer/Core/InstallationManager.cs deleted file mode 100644 index 92f034b8..00000000 --- a/Installer/Core/InstallationManager.cs +++ /dev/null @@ -1,215 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Diagnostics; -using System.IO; -using System.IO.Compression; -using System.Linq; -using System.Net.Http; -using System.Security.AccessControl; -using System.Security.Principal; -using System.ServiceProcess; -using System.Threading.Tasks; -using Installer.Extensions; -using Installer.Translation; -using Microsoft.Win32; - -namespace Installer.Core; - -public static class InstallationManager { - public const string CommonFilesPath = "C:\\Program Files (x86)\\Common Files\\Steam"; - public static string InstallDir { - get { - if (AvaloniaApp.InLinuxDevelopment) { - return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "OpenSteamClient_Installer_TargetDir_Dev"); - } - - var val = (string?)Registry.GetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\WOW6432Node\\OpenSteamClient", "InstallPath", ""); - if (string.IsNullOrEmpty(val)) { - return ""; - } - - return val; - } - - set { - if (AvaloniaApp.InLinuxDevelopment) { - // Don't save it anywhere on linux - return; - } - - Registry.SetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\WOW6432Node\\OpenSteamClient", "InstallPath", value); - } - } - - public static void CreateRegKeys(string installPath) { - if (AvaloniaApp.InLinuxDevelopment) { - return; - } - - var node = Registry.LocalMachine.OpenSubKey("SOFTWARE")!; - var steamSecurity = new RegistrySecurity(); - RegistryAccessRule rule = new("Users", - RegistryRights.ReadKey | RegistryRights.SetValue | RegistryRights.QueryValues | RegistryRights.ReadPermissions - | RegistryRights.Delete | RegistryRights.FullControl | RegistryRights.CreateSubKey | RegistryRights.EnumerateSubKeys | RegistryRights.Notify | RegistryRights.CreateLink | RegistryRights.WriteKey | RegistryRights.ExecuteKey, - InheritanceFlags.ContainerInherit, - PropagationFlags.None, - AccessControlType.Allow - ); - - steamSecurity.AddAccessRule(rule); - var opensteamnode = node.CreateOrOpen("OpenSteamClient", RegistryKeyPermissionCheck.Default, RegistryOptions.None, out bool _, steamSecurity); - var valvenode = node.OpenSubKey("WOW6432Node")!.CreateOrOpen("Valve", RegistryKeyPermissionCheck.Default, RegistryOptions.None, out bool _); - CreateSteamRegKeys(valvenode, steamSecurity, "Steam", "SteamService", ""); - CreateSteamRegKeys(opensteamnode, steamSecurity, "thiskey", serviceSubkey: "", installPath); - } - - private static void CreateSteamRegKeys(RegistryKey key, RegistrySecurity steamSecurity, string clientSubkey, string serviceSubkey, string installPath) { - if (!string.IsNullOrEmpty(serviceSubkey)) { - var serviceKey = key.CreateOrOpen(serviceSubkey, RegistryKeyPermissionCheck.Default, RegistryOptions.None, out bool createdService); - if (createdService) { - serviceKey.SetValue("installpath_default", installPath, RegistryValueKind.String); - } - } - - if (!string.IsNullOrEmpty(clientSubkey)) { - bool createdClient = true; - RegistryKey? clientKey; - if (clientSubkey == "thiskey") { - clientKey = key; - } else { - clientKey = key.CreateOrOpen(clientSubkey, RegistryKeyPermissionCheck.Default, RegistryOptions.None, out createdClient, steamSecurity); - } - - if (createdClient) { - clientKey.SetValue("InstallPath", installPath, RegistryValueKind.String); - clientKey.SetValue("language", ELanguageConversion.APINameFromELanguage(AvaloniaApp.TranslationManager.CurrentTranslation.Language), RegistryValueKind.String); - // This is the important one, this allows the service to start up - clientKey.SetValue("SteamPID", 0, RegistryValueKind.DWord); - clientKey.SetValue("TempAppCmdLine", "", RegistryValueKind.String); - clientKey.SetValue("ReLaunchCmdLine", "", RegistryValueKind.String); - clientKey.SetValue("ClientLauncherType", 0, RegistryValueKind.DWord); - clientKey.SetValue("Universe", "Public", RegistryValueKind.String); - clientKey.SetValue("BetaName", "", RegistryValueKind.String); - } - } - - - } - - /// - /// Install the Steam Service. - /// - /// The path to the extracted/existing Program Files (x86)/Common Files/Steam/steamservice.exe - public static async Task InstallSteamService(string steamServiceExePath) { - if (AvaloniaApp.InLinuxDevelopment) { - return; - } - - if (DoesServiceExist()) { - return; - } - - if (!File.Exists(steamServiceExePath)) { - throw new LocalizedException("#InstallError_ServiceInstallFailed"); - } - - var installproc = Process.Start(steamServiceExePath, "/install"); - await installproc.WaitForExitAsync(); - if (installproc.ExitCode != 0) { - // Uninstall and reinstall to fix permission issues - var uninstallproc = Process.Start(steamServiceExePath, "/uninstall"); - await uninstallproc.WaitForExitAsync(); - - // Try to install a second time - installproc = Process.Start(steamServiceExePath, "/install"); - await installproc.WaitForExitAsync(); - if (installproc.ExitCode != 0) { - // Give up after the second error - throw new LocalizedException("#InstallError_ServiceInstallFailed"); - } - } - } - - public static bool DoesServiceExist() - { - ServiceController[] services = ServiceController.GetServices(); - var service = services.FirstOrDefault(s => s.ServiceName == "Steam Client Service"); - return service != null; - } - - - public static void CreateUninstallRegs(string uninstallExe) { - if (AvaloniaApp.InLinuxDevelopment) { - return; - } - - var node = Registry.LocalMachine.OpenSubKey("SOFTWARE")!.OpenSubKey("Microsoft")!.OpenSubKey("Windows")!.OpenSubKey("CurrentVersion")!.OpenSubKey("Uninstall")!; - node.SetValue("DisplayName", "OpenSteamClient", RegistryValueKind.String); - node.SetValue("DisplayVersion", "", RegistryValueKind.String); - node.SetValue("Publisher", "Rosentti", RegistryValueKind.String); - node.SetValue("URLInfoAbout", "https://github.com/OpenSteamClient/OpenSteamClient", RegistryValueKind.String); - node.SetValue("HelpLink", "https://github.com/OpenSteamClient/OpenSteamClient/issues", RegistryValueKind.String); - node.SetValue("DisplayIcon", uninstallExe, RegistryValueKind.String); - node.SetValue("UninstallString", uninstallExe, RegistryValueKind.String); - node.SetValue("NoModify", 1, RegistryValueKind.DWord); - } - - public static async Task ExtractOpenSteamClientToPath(string path, IProgress progress) { - - } - - // If other files ever start mattering, copy them over too, but for now this seems to be enough - // drivers.exe, steamservice.dll and others just magically appear after Steam starts - public static readonly ReadOnlyCollection CommonFiles = new(new List() - { - "steamservice.exe", - }); - - public static bool CommonFilesNeedsSetup() { - if (Directory.Exists(CommonFilesPath)) { - foreach (var item in CommonFiles) - { - if (!File.Exists(Path.Combine(CommonFilesPath, item))) { - return true; - } - } - } else { - return true; - } - - return false; - } - - public static async Task SetupCommonFiles(IProgress progress, IProgress currentOperationLocToken) { - currentOperationLocToken.Report("#InstallProgress_DownloadingService"); - using var stream = new MemoryStream(); - await HttpClient.DownloadAsync(SteamManifest.bins_win32, stream, progress); - Directory.CreateDirectory(CommonFilesPath); - - currentOperationLocToken.Report("#InstallProgress_ExtractingService"); - progress.Report(0); - using var archive = new ZipArchive(stream, ZipArchiveMode.Read, true); - await archive.ExtractToDirectory(CommonFilesPath, progress); - } - - public static readonly HttpClient HttpClient = new(); - - static InstallationManager() { - HttpClient.DefaultRequestHeaders.Add("User-Agent", "opensteamclient-installer/1.0"); - } - - public static async Task RunAllInstallSteps(string targetPath, IProgress progress, IProgress currentOperationLocToken) { - // Do the things that are more likely to fail first - if (CommonFilesNeedsSetup()) { - await SetupCommonFiles(progress, currentOperationLocToken); - } - - if (!DoesServiceExist()) { - currentOperationLocToken.Report("#InstallProgress_InstallingService"); - await InstallSteamService(Path.Combine(CommonFilesPath, "steamservice.exe")); - } - - - } -} \ No newline at end of file diff --git a/Installer/Core/LocalizedException.cs b/Installer/Core/LocalizedException.cs deleted file mode 100644 index 0efba394..00000000 --- a/Installer/Core/LocalizedException.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace Installer.Core; - -//TODO: copy this to OpenSteamworks? -[System.Serializable] -public class LocalizedException : System.Exception -{ - public LocalizedException() { } - public LocalizedException(string loctoken) : base(AvaloniaApp.TranslationManager.GetTranslationForKey(loctoken)) { } - public LocalizedException(string loctoken, System.Exception inner) : base(AvaloniaApp.TranslationManager.GetTranslationForKey(loctoken), inner) { } - protected LocalizedException( - System.Runtime.Serialization.SerializationInfo info, - System.Runtime.Serialization.StreamingContext context) : base(info, context) { } -} \ No newline at end of file diff --git a/Installer/Core/SteamManifest.cs b/Installer/Core/SteamManifest.cs deleted file mode 100644 index 9d9d80cb..00000000 --- a/Installer/Core/SteamManifest.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Installer.Core; - -//TODO: auto update this with OSWUpdater -public static class SteamManifest { - public const string bins_win32 = "bins_win32.zip.91ea83c7794514f93f01180f9a07d2edf1589ab6"; - public const int bins_win32_size = 51784912; -} \ No newline at end of file diff --git a/Installer/Enums/InstallAction.cs b/Installer/Enums/InstallAction.cs deleted file mode 100644 index 24065377..00000000 --- a/Installer/Enums/InstallAction.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System; - -namespace Installer.Enums; - -[Flags] -public enum InstallAction { - None = 0, - Install = 1 << 1, - Repair = 1 << 2, - Uninstall = 1 << 3 -} \ No newline at end of file diff --git a/Installer/Extensions/ControlExtensions.cs b/Installer/Extensions/ControlExtensions.cs deleted file mode 100644 index bb992559..00000000 --- a/Installer/Extensions/ControlExtensions.cs +++ /dev/null @@ -1,68 +0,0 @@ -using System; -using Avalonia.Controls; -using Avalonia.VisualTree; -using Installer.Translation; - -namespace Installer.Extensions; - -public static class ControlExtensions -{ - // - // Summary: - // Finds the named control under all of this Control's children - // - // Parameters: - // control: - // The control to look in. - // - // name: - // The name of the control to find. - // - // Type parameters: - // T: - // The type of the control to find. - // - // Returns: - // The control or null if not found. - public static T? FindControlNested(this Control control, string name) where T : Control - { - foreach (var item in control.GetVisualChildren()) - { - if (item is Control c) { - var ctrl = FindControlNested(c, name); - if (ctrl != null) { - return ctrl; - } - } - } - - return control.FindControl(name); - } - - public static bool TryTranslateSelf(this Control control, bool dueToLayoutChange = false) - { - if (AvaloniaApp.TranslationManager.CurrentTranslation.Language == ELanguage.None) - { - return false; - } - - Console.WriteLine($"Translating control {control.GetType().Name}{(dueToLayoutChange ? " (due to layout change)" : "")}"); - AvaloniaApp.TranslationManager.TranslateVisual(control); - return true; - } - - public static void TranslatableInit(this Control control) - { - control.TryTranslateSelf(); - // Disable this for now, until I can find a way to filter out mouseover etc events from affecting this - // Ideally we should never need to re-update translations during runtime except on language change, but if objects get added to the visual tree, they might not be translated yet (such as in ItemsControl cases, where you can't translate the fundamental template object since it gets removed at compile time) - //control.LayoutUpdated += (object? sender, EventArgs e) => { control.TryTranslateSelf(true); }; - control.Initialized += (object? sender, EventArgs e) => { control.TryTranslateSelf(true); }; - - // Register some events for auto-retranslate - if (control is TopLevel) - { - (control as TopLevel)!.Opened += (object? sender, System.EventArgs e) => control.TryTranslateSelf(); - } - } -} \ No newline at end of file diff --git a/Installer/Extensions/HttpClientExtensions.cs b/Installer/Extensions/HttpClientExtensions.cs deleted file mode 100644 index a6a37037..00000000 --- a/Installer/Extensions/HttpClientExtensions.cs +++ /dev/null @@ -1,79 +0,0 @@ -using System; -using System.IO; -using System.Net.Http; -using System.Threading; -using System.Threading.Tasks; -using System.Timers; - -namespace Installer.Extensions; - -public static class HttpClientExtensions -{ - public static async Task DownloadAsync(this HttpClient client, string requestUri, Stream destination, IProgress progress, long knownLength = 0, CancellationToken cancellationToken = default) - { - // Get the http headers first to examine the content length - using (var response = await client.GetAsync(requestUri, HttpCompletionOption.ResponseHeadersRead)) - { - long contentLength = 0; - if (knownLength > 0) { - contentLength = knownLength; - } else if (response.Content.Headers.ContentLength != null) { - contentLength = (long)response.Content.Headers.ContentLength; - } - - using (var download = await response.Content.ReadAsStreamAsync()) - { - // Ignore progress reporting when no progress reporter was - // passed or when the content length is unknown - if (progress == null || contentLength == 0) - { - await download.CopyToAsync(destination); - return; - } - - bool cancelledDueToTimeout = false; - - using (CancellationTokenSource source = new CancellationTokenSource()) - { - System.Timers.Timer timer = new System.Timers.Timer(15000); - timer.AutoReset = false; - timer.Start(); - timer.Elapsed += (object? sender, ElapsedEventArgs args) => { - cancelledDueToTimeout = true; - source.Cancel(); - }; - - // Convert absolute progress (bytes downloaded) into relative progress (0% - 100%) - // Also reset the timer by setting it's interval - var relativeProgress = new Progress((long totalBytes) => { - progress.Report((int)(((float)totalBytes / contentLength)*100)); - timer.Interval = 20000; - }); - - CancellationToken token = source.Token; - cancellationToken.Register(() => { - cancelledDueToTimeout = false; - source.Cancel(); - }); - - try - { - // Use extension method to report progress while downloading - await download.CopyToAsync(destination, 81920, relativeProgress, token); - // If download finished, stop the timer - timer.Stop(); - } - catch (OperationCanceledException) - { - if (!cancelledDueToTimeout) { - throw; - } - throw new Exception("Lost connection to server"); - } - } - - progress.Report(100); - } - } - } -} \ No newline at end of file diff --git a/Installer/Extensions/RegistryKeyExtensions.cs b/Installer/Extensions/RegistryKeyExtensions.cs deleted file mode 100644 index 11235bf7..00000000 --- a/Installer/Extensions/RegistryKeyExtensions.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System.Security.AccessControl; -using Microsoft.Win32; - -namespace Installer.Extensions; - -public static class RegistryKeyExtensions { - public static RegistryKey CreateOrOpen(this RegistryKey regkey, string subkey, RegistryKeyPermissionCheck permissionCheck, RegistryOptions registryOptions, out bool created, RegistrySecurity? security = null) { - var key = regkey.OpenSubKey(subkey, permissionCheck); - - created = key == null; - if (key == null) { - key = regkey.CreateSubKey(subkey, permissionCheck, registryOptions, security); - } - - return key; - } -} \ No newline at end of file diff --git a/Installer/Extensions/StreamExtensions.cs b/Installer/Extensions/StreamExtensions.cs deleted file mode 100644 index 401a8890..00000000 --- a/Installer/Extensions/StreamExtensions.cs +++ /dev/null @@ -1,43 +0,0 @@ -using System; -using System.IO; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; - -namespace Installer; - -public static class StreamExtensions -{ - public static async Task CopyToAsync(this Stream source, Stream destination, int bufferSize, IProgress progress, CancellationToken cancellationToken = default) { - if (source == null) - throw new ArgumentNullException(nameof(source)); - if (!source.CanRead) - throw new ArgumentException("Has to be readable", nameof(source)); - if (destination == null) - throw new ArgumentNullException(nameof(destination)); - if (!destination.CanWrite) - throw new ArgumentException("Has to be writable", nameof(destination)); - if (bufferSize < 0) - throw new ArgumentOutOfRangeException(nameof(bufferSize)); - - var buffer = new byte[bufferSize]; - long totalBytesRead = 0; - int bytesRead; - while ((bytesRead = await source.ReadAsync(buffer, 0, buffer.Length, cancellationToken).ConfigureAwait(false)) != 0) { - await destination.WriteAsync(buffer, 0, bytesRead, cancellationToken).ConfigureAwait(false); - totalBytesRead += bytesRead; - progress.Report(totalBytesRead); - } - } - - public static bool AreEqual(this MemoryStream first, MemoryStream second) { - if (first.Length != second.Length) { - return false; - } - - first.Position = 0; - second.Position = 0; - - return first.ToArray().SequenceEqual(second.ToArray()); - } -} diff --git a/Installer/Extensions/VisualExtensions.cs b/Installer/Extensions/VisualExtensions.cs deleted file mode 100644 index 96b7a0f4..00000000 --- a/Installer/Extensions/VisualExtensions.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System.Collections.Generic; -using Avalonia; -using Avalonia.LogicalTree; -using Avalonia.VisualTree; - -namespace Installer.Extensions; - -public static class VisualExtensions -{ - public static IEnumerable GetAllVisualChildrenTree(this Visual visual) - { - List allVisuals = new() - { - visual - }; - - // First get all logical children - foreach (var item in visual.GetLogicalChildren()) - { - // Then try to cast them to Visual (most of the time should be valid) - if (item is Visual) - { - allVisuals.AddRange(GetAllVisualChildrenTree((Visual)item!)); - } - } - - return allVisuals; - } -} \ No newline at end of file diff --git a/Installer/Extensions/ZipArchiveExtensions.cs b/Installer/Extensions/ZipArchiveExtensions.cs deleted file mode 100644 index e451d542..00000000 --- a/Installer/Extensions/ZipArchiveExtensions.cs +++ /dev/null @@ -1,47 +0,0 @@ -using System; -using System.IO; -using System.IO.Compression; -using System.Text; -using System.Threading.Tasks; - -namespace Installer; - -public static class ZipArchiveExtensions -{ - public static async Task ExtractToDirectory(this ZipArchive source, string destinationDirectoryName, IProgress prog, Action? afterExtractHook = null) - { - foreach (ZipArchiveEntry entry in source.Entries) - { - var FullNameFixed = entry.FullName; - - // Fixup slashes for Non-Windows platforms - if (!OperatingSystem.IsWindows()) - { - FullNameFixed = FullNameFixed.Replace('\\', '/'); - } - - var FullPath = Path.Combine(destinationDirectoryName, FullNameFixed); - - if (entry.Length == 0 && (FullNameFixed.EndsWith('/') || FullNameFixed.EndsWith('\\'))) - { - Directory.CreateDirectory(FullPath); - continue; - } - - Directory.CreateDirectory(Path.GetDirectoryName(FullPath)!); - - using (Stream zipstream = entry.Open()) - { - using (var file = new FileStream(FullPath, FileMode.Create, FileAccess.Write, FileShare.None)) - { - // Convert absolute progress (bytes unzipped) into relative progress (0% - 100%) - var relativeProgress = new Progress(totalBytes => prog.Report((int)(((float)totalBytes / entry.Length) * 100))); - - // Use extension method to report progress while downloading - await zipstream.CopyToAsync(file, 81920, relativeProgress, default); - afterExtractHook?.Invoke(entry, FullNameFixed); - } - } - } - } -} \ No newline at end of file diff --git a/Installer/Installer.csproj b/Installer/Installer.csproj deleted file mode 100644 index fb531602..00000000 --- a/Installer/Installer.csproj +++ /dev/null @@ -1,69 +0,0 @@ - - - WinExe - $(CommonNetVersion)-windows - enable - true - full - app.manifest - true - - - en - true - false - - - - - - win-x64 - false - None - true - true - - - - win-x64;linux-x64;osx-x64 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Installer/Program.cs b/Installer/Program.cs deleted file mode 100644 index b2cd3e2d..00000000 --- a/Installer/Program.cs +++ /dev/null @@ -1,54 +0,0 @@ -using Avalonia; -using System; -using System.Linq; -using System.Security.Principal; - -namespace Installer; - -public static class Program -{ - // Initialization code. Don't use any Avalonia, third-party APIs or any - // SynchronizationContext-reliant code before AppMain is called: things aren't initialized - // yet and stuff might break. - [STAThread] - public static void Main(string[] args) - { -#if DEBUG - if (!OperatingSystem.IsWindows()) { - AvaloniaApp.InLinuxDevelopment = true; - } -#endif - - if (args.Contains("-debug")) - { - AvaloniaApp.DebugEnabled = true; - } -#if DEBUG - Console.WriteLine("Running DEBUG build, debug mode forced on"); - AvaloniaApp.DebugEnabled = true; -#endif - - if (!AvaloniaApp.InLinuxDevelopment) { - if (!IsAdministrator()) { - return; - } - } - - BuildAvaloniaApp().StartWithClassicDesktopLifetime(args, Avalonia.Controls.ShutdownMode.OnMainWindowClose); - } - - public static bool IsAdministrator() - { - var identity = WindowsIdentity.GetCurrent(); - var principal = new WindowsPrincipal(identity); - return principal.IsInRole(WindowsBuiltInRole.Administrator); - } - - // Avalonia configuration, don't remove; also used by visual designer. - public static AppBuilder BuildAvaloniaApp() - => AppBuilder.Configure() - .UsePlatformDetect() - .WithInterFont() - .UseSkia() - .LogToTrace(); -} diff --git a/Installer/Translation/ELanguage.cs b/Installer/Translation/ELanguage.cs deleted file mode 100644 index dec8a4fb..00000000 --- a/Installer/Translation/ELanguage.cs +++ /dev/null @@ -1,91 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; - -namespace Installer.Translation; - -public enum ELanguage -{ - None = -1, - English = 0, - German = 1, - French = 2, - Italian = 3, - Korean = 4, - Spanish = 5, - Simplified_Chinese = 6, - Traditional_Chinese = 7, - Russian = 8, - Thai = 9, - Japanese = 10, - Portuguese = 11, - Polish = 12, - Danish = 13, - Dutch = 14, - Finnish = 15, - Norwegian = 16, - Swedish = 17, - Hungarian = 18, - Czech = 19, - Romanian = 20, - Turkish = 21, - Brazilian = 22, - Bulgarian = 23, - Greek = 24, - Arabic = 25, - Ukrainian = 26, - Latam_Spanish = 27, - Vietnamese = 28, -} - -public static class ELanguageConversion { - private static readonly Dictionary ELanguageToAPINameMap = new() { - {ELanguage.None, ""}, - {ELanguage.English, "english"}, - {ELanguage.German, "german"}, - {ELanguage.French, "french"}, - {ELanguage.Italian, "italian"}, - {ELanguage.Korean, "korean"}, - {ELanguage.Spanish, "spanish"}, - {ELanguage.Simplified_Chinese, "schinese"}, // Is this correct? - {ELanguage.Traditional_Chinese, "tchinese"}, // Is this correct? - {ELanguage.Russian, "russian"}, - {ELanguage.Thai, "thai"}, - {ELanguage.Japanese, "japanese"}, - {ELanguage.Portuguese, "portuguese"}, - {ELanguage.Polish, "polish"}, - {ELanguage.Danish, "danish"}, - {ELanguage.Dutch, "dutch"}, - {ELanguage.Finnish, "finnish"}, - {ELanguage.Norwegian, "norwegian"}, - {ELanguage.Swedish, "swedish"}, - {ELanguage.Hungarian, "hungarian"}, - {ELanguage.Czech, "czech"}, - {ELanguage.Romanian, "romanian"}, - {ELanguage.Turkish, "turkish"}, - {ELanguage.Brazilian, "brazilian"}, - {ELanguage.Bulgarian, "bulgarian"}, - {ELanguage.Greek, "greek"}, - {ELanguage.Arabic, "arabic"}, - {ELanguage.Ukrainian, "ukrainian"}, - {ELanguage.Latam_Spanish, "latam_spanish"}, - {ELanguage.Vietnamese, "vietnamese"}, - }; - - // Add language here when making a translation - public static Dictionary TwoLetterISOCodesToLanguages = new() { - {"iv", ELanguage.None}, - {"en", ELanguage.English}, - {"fi", ELanguage.Finnish}, - }; - - public readonly static Dictionary APINameToELanguageMap = ELanguageToAPINameMap.ToDictionary(x => x.Value, x => x.Key); - - public static ELanguage ELanguageFromAPIName(string apiName) { - return APINameToELanguageMap[apiName]; - } - - public static string APINameFromELanguage(ELanguage eLanguage) { - return ELanguageToAPINameMap[eLanguage]; - } -} \ No newline at end of file diff --git a/Installer/Translation/TranslationManager.cs b/Installer/Translation/TranslationManager.cs deleted file mode 100644 index 0db1ffb0..00000000 --- a/Installer/Translation/TranslationManager.cs +++ /dev/null @@ -1,285 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Globalization; -using System.IO; -using System.Linq; -using System.Reflection; -using System.Text.Json; -using System.Text.Json.Serialization; -using System.Threading.Tasks; -using Avalonia; -using Avalonia.Controls; -using Avalonia.LogicalTree; -using Avalonia.Threading; -using Avalonia.VisualTree; -using Installer.Extensions; -using Microsoft.Extensions.FileProviders; - -namespace Installer.Translation; - -[JsonSourceGenerationOptions(WriteIndented = true)] -[JsonSerializable(typeof(Translation))] -internal partial class SourceGenerationContext : JsonSerializerContext -{ -} - -public class Translation -{ - public ELanguage Language { get; set; } = ELanguage.None; - public string LanguageFriendlyName { get; set; } = ""; - public string ISOCode { get; set; } = ""; - public Dictionary TranslationKeys { get; set; } = new(); -} - -public class TranslationManager -{ - public Translation CurrentTranslation = new(); - private readonly List RefreshableObjects = new(); - public static IEnumerable ValidUILanguages => new ELanguage[] { ELanguage.English, ELanguage.Finnish }; - - public event EventHandler? TranslationChanged; - - public TranslationManager() - { - - } - - public void SetLanguage(ELanguage language) - { - var lang = ELanguageToString(language); - if (lang == null) - { - throw new ArgumentException($"Language {language} was not valid."); - } - - if (!ValidUILanguages.Contains(language)) { - throw new InvalidOperationException("No translation for " + language); - } - - CurrentTranslation = GetForLanguage(language); - - Dispatcher.UIThread.Invoke(() => - { - foreach (var obj in RefreshableObjects) - { - TranslateAvaloniaObject(obj); - } - }); - - TranslationChanged?.Invoke(this, EventArgs.Empty); - } - - public string GetTranslationForKey(string key) - { - this.CurrentTranslation.TranslationKeys.TryGetValue(key, out string? val); - if (val == null) - { - val = $"TRANSLATION FAILED (key '{key}')"; - } - - return val; - } - - private Translation GetForLanguage(ELanguage language) - { - string? langname = ELanguageToString(language); - if (langname == null) - { - throw new ArgumentOutOfRangeException("Invalid ELanguage " + language + " specified."); - } - - // Fetch the translations from this assembly. The translations are embedded in the installer - var embeddedProvider = new EmbeddedFileProvider(Assembly.GetExecutingAssembly()); - string filename = "Translations/" + langname + ".json"; - IFileInfo fileInfo = embeddedProvider.GetFileInfo(filename); - if (!fileInfo.Exists) { - if (language == ELanguage.English) - { - throw new Exception("Base language not found!"); - } - - throw new Exception("Language " + language + " not found"); - } - - string text; - using (var stream = fileInfo.CreateReadStream()) - { - using (var reader = new StreamReader(stream)) - { - text = reader.ReadToEnd(); - } - } - - var newTranslation = JsonSerializer.Deserialize(text, SourceGenerationContext.Default.Translation); - ArgumentNullException.ThrowIfNull(newTranslation); - return newTranslation; - } - - /// - /// This function is for creating and translating elements in code behind - /// - public T CreateTranslated(T visualCreated, string translationKey, string? defaultStr = null) where T : Visual - { - visualCreated[Controls.Translatable.TranslationKeyProperty] = translationKey; - visualCreated[Controls.Translatable.DefaultTextProperty] = defaultStr; - TranslateVisual(visualCreated); - return visualCreated; - } - - public void TranslateVisual(Visual visual) - { - foreach (var vis in visual.GetAllVisualChildrenTree()) - { - Console.WriteLine("vis " + vis.Name); - TranslateAvaloniaObject(vis); - } - } - - public void TranslateTrayIcon(TrayIcon icon) - { - List objs = new() - { - icon - }; - - if (icon.Menu != null) - { - objs.Add(icon.Menu); - foreach (var item in icon.Menu.Items) - { - objs.Add(item); - } - } - - foreach (var item in objs) - { - TranslateAvaloniaObject(item); - } - } - public void TranslateAvaloniaObject(AvaloniaObject obj) - { - if (!RefreshableObjects.Contains(obj)) - { - RefreshableObjects.Add(obj); - } - - string? translationKey = (string?)obj[Controls.Translatable.TranslationKeyProperty]; - string? defaultStr = (string?)obj[Controls.Translatable.DefaultTextProperty]; - if (!string.IsNullOrEmpty(translationKey)) - { - bool translationFailed = false; - string translatedText = $"TRANSLATION FAILED (key '{translationKey}')"; - if (!this.CurrentTranslation.TranslationKeys.ContainsKey(translationKey)) - { - translationFailed = true; - Console.WriteLine("Cannot translate " + translationKey + ", no key!"); - } - else - { - translatedText = this.CurrentTranslation.TranslationKeys[translationKey]; - Console.WriteLine("Got translation " + translatedText); - } - - void TranslateTextInternal(StyledProperty property) - { - bool isEmptyOrNull = false; - T val = obj.GetValue(property); - if (val == null) - { - isEmptyOrNull = true; - } - else if (val is string str) - { - isEmptyOrNull = string.IsNullOrEmpty(str); - } - - if (!translationKey.StartsWith('#')) - { - // User probably meant to set the text directly. - obj.SetValue(property, translationKey); - return; - } - - // Don't replace text with TRANSLATION FAILED if there's pre-existing text in the control - if (translationFailed && !isEmptyOrNull) - { - return; - } - else - { - // And if there's no pre existing text, but the translation failed, show the default string if it is not empty - if (!string.IsNullOrEmpty(defaultStr)) - { - obj.SetValue(property, defaultStr); - return; - } - } - - Console.WriteLine("Set property " + property + " to " + translatedText + " for " + obj.GetType()); - if (obj is Control c) { - Console.WriteLine("with name " + c.Name); - } - - obj.SetValue(property, translatedText); - } - - // Window eventually inherits from ContentControl, as do lots of other controls. We don't want to override a window's content... - if (obj is Window) - { - TranslateTextInternal(Window.TitleProperty); - } - else if (obj is MenuItem) - { - TranslateTextInternal(MenuItem.HeaderProperty); - } - else if (obj is TextBox) - { - TranslateTextInternal(TextBox.WatermarkProperty); - } - else if (obj is ContentControl) - { - TranslateTextInternal(ContentControl.ContentProperty); - } - else if (obj is TextBlock) - { - TranslateTextInternal(TextBlock.TextProperty); - } - else if (obj is NativeMenuItem) - { - TranslateTextInternal(NativeMenuItem.HeaderProperty); - } - else if (obj is TrayIcon) - { - TranslateTextInternal(TrayIcon.ToolTipTextProperty); - } - } - } - - public static string? ELanguageToString(ELanguage lang) - { - try - { - return ELanguageConversion.APINameFromELanguage(lang); - } - catch (System.Exception) - { - return null; - } - } - - public string GetPrettyNameForLanguage(ELanguage lang) - { - return GetForLanguage(lang).LanguageFriendlyName; - } - - //TODO: we should copy this over to OpenSteamClient as well - public void LoadCurrentSystemTranslation() - { - if (ELanguageConversion.TwoLetterISOCodesToLanguages.TryGetValue(CultureInfo.CurrentUICulture.TwoLetterISOLanguageName, out ELanguage lang)) { - SetLanguage(lang); - } else { - SetLanguage(ELanguage.English); - } - } -} \ No newline at end of file diff --git a/Installer/Translations/english.json b/Installer/Translations/english.json deleted file mode 100644 index 4ce1bd37..00000000 --- a/Installer/Translations/english.json +++ /dev/null @@ -1,48 +0,0 @@ -{ - "Language": 0, - "LanguageFriendlyName": "English", - "ISOCode": "en", - "TranslationKeys": { - "#LanguageNameTranslated": "English", - "#Dialog_Cancel": "Cancel", - "#Dialog_OK": "OK", - "#Dialog_Yes": "Yes", - "#Dialog_No": "No", - "#Dialog_Next": "Next", - "#Dialog_Previous": "Previous", - "#Dialog_Finish": "Finish", - "#Dialog_Install": "Install", - "#MainWindow_Title": "OpenSteamClient Installer", - "#LocalizedSteamSSALink": "https://store.steampowered.com/subscriber_agreement/", - "#Welcome_WindowTitle": "Welcome", - "#Welcome_Title": "Welcome to the OpenSteamClient setup", - "#Welcome_FeatureText": "OpenSteamClient is a community alternative to the official Steam Client. Here are some of it's features: ", - "#Welcome_Features": " - Lightweight\n - Not browser based\n - Extensive customization\n - Community support\n - 64-bit", - "#Welcome_AgreeText": "Please agree to the below terms to use OpenSteamClient.", - "#Welcome_ViewSSAButton": "View Steam Subscriber Agreement", - "#Welcome_AgreeSSACheckbox": "I agree to the Steam Subscriber Agreement", - "#Welcome_AgreeOSCDevelopersCheckbox": "I agree to not hold OpenSteamClient's developers responsible if my Steam account gets terminated for any reason", - "#ChooseActionPage_Install": "Install", - "#ChooseActionPage_InstallSubtext": "Install OpenSteamClient", - "#ChooseActionPage_Repair": "Repair", - "#ChooseActionPage_RepairSubtext": "Repair OpenSteamClient", - "#ChooseActionPage_Uninstall": "Uninstall", - "#ChooseActionPage_UninstallSubtext": "Uninstall OpenSteamClient", - "#PickInstallDirectory_WindowTitle": "Choose install directory", - "#PickInstallDirectory_ButtonText": "Browse", - "#PickInstallDirectory_Title": "Choose an install directory to install OpenSteamClient", - "#PickInstallDirectory_FolderPickerTitle": "Select an install directory to install OpenSteamClient", - "#PickInstallDirectory_Text": "Games and apps may be installed in this directory, but you can also add alternative directories and drives later.", - "#InstallError_NoSpaceError": "Selected drive does not have enough space. At least 1GB is required.", - "#InstallError_DirectoryNotFoundError": "Install folder does not exist", - "#InstallError_ContainsFilesError": "Install folder contains files", - "#InstallError_PathNotAbsoluteError": "Provided path is not absolute", - "#InstallError_ServiceInstallFailed": "Service installation failed with code {0}, error: {1}", - "#InstallError_GenericErrorCode": "Got error code {0} while installing", - "#InstallError_GenericError": "Got error {0} while installing", - "#InstallProgress_DownloadingService": "Downloading Steam Client Service", - "#InstallProgress_InstallingService": "Installing Steam Client Service", - "#InstallProgress_UnzippingOSC": "Unzipping OpenSteamClient", - "#InstallProgress_WritingRegistryKeys": "Writing registry keys" - } -} \ No newline at end of file diff --git a/Installer/Translations/finnish.json b/Installer/Translations/finnish.json deleted file mode 100644 index 8bd500c8..00000000 --- a/Installer/Translations/finnish.json +++ /dev/null @@ -1,49 +0,0 @@ -{ - "Language": 15, - "LanguageFriendlyName": "Finnish", - "ISOCode": "fi", - "TranslationKeys": { - "#SettingsWindow_YourCurrentLanguage": "Tämänhetkinen kielesi on {0} ({1})", - "#LanguageNameTranslated": "Suomi", - "#Dialog_Cancel": "Peruuta", - "#Dialog_OK": "OK", - "#Dialog_Yes": "Kyllä", - "#Dialog_No": "Ei", - "#Dialog_Next": "Seuraava", - "#Dialog_Previous": "Edellinen", - "#Dialog_Finish": "Lopeta", - "#Dialog_Install": "Asenna", - "#LocalizedSteamSSALink": "https://store.steampowered.com/subscriber_agreement/?l=finnish", - "#MainWindow_Title": "OpenSteamClient -asennusohjelma", - "#Welcome_WindowTitle": "Tervetuloa", - "#Welcome_Title": "Tervetuloa OpenSteamClient -asennusohjelmaan", - "#Welcome_FeatureText": "OpenSteamClient on vaihtoehtoinen yhteisön rakentama Steam-ohjelma. Sen ominaisuuksiin kuuluu: ", - "#Welcome_Features": " - Kevyt\n - Ei selainpohjainen\n - Laajat kustomointivaihtoehdot\n - Yhteisön tuki\n - 64-bittinen", - "#Welcome_AgreeText": "Hyväksy alla olevat ehdot käyttääksesi OpenSteamClient:ia", - "#Welcome_ViewSSAButton": "Katso Steam-tilaussopimus", - "#Welcome_AgreeSSACheckbox": "Hyväksyn Steam-tilaussopimuksen ehdot", - "#Welcome_AgreeOSCDevelopersCheckbox": "Hyväksyn, etten pidä OpenSteamClient:in kehittäjiä vastuullisena, jos Steam-tilini lakkautetaan mistään syystä", - "#ChooseActionPage_Install": "Asenna", - "#ChooseActionPage_InstallSubtext": "Asenna OpenSteamClient", - "#ChooseActionPage_Repair": "Korjaa", - "#ChooseActionPage_RepairSubtext": "Korjaa OpenSteamClient", - "#ChooseActionPage_Uninstall": "Poista asennus", - "#ChooseActionPage_UninstallSubtext": "Poista OpenSteamClient:in asennus", - "#PickInstallDirectory_WindowTitle": "Valitse asennuskansio", - "#PickInstallDirectory_ButtonText": "Selaa", - "#PickInstallDirectory_Title": "Valitse kansio minne OpenSteamClient asennetaan", - "#PickInstallDirectory_FolderPickerTitle": "Valitse kansio minne OpenSteamClient asennetaan", - "#PickInstallDirectory_Text": "Pelit ja sovellukset voidaan asennetaan tähänkin kansioon, mutta voit myös lisätä muita kansioita ja asemia myöhemmin. ", - "#InstallError_NoSpaceError": "Valitulla levyllä ei ole tarpeeksi tilaa asentaa OpenSteamClient:iä. Vaaditaan ainakin 1GB.", - "#InstallError_DirectoryNotFoundError": "Asennuskansioa ei ole olemassa.", - "#InstallError_ContainsFilesError": "Asennuskansio sisältää tiedostoja", - "#InstallError_PathNotAbsoluteError": "Polku ei ole absoluutti", - "#InstallError_GenericErrorCode": "Tapahtui virhekoodi {0}", - "#InstallError_GenericError": "Tapahtui virhe {0}", - "#InstallError_ServiceInstallFailed": "Palvelun asennus epäonnistui virhekoodilla {0}, virhe: {1}", - "#InstallProgress_DownloadingService": "Ladataan Steam-palvelua", - "#InstallProgress_InstallingService": "Asennetaan Steam-palvelua", - "#InstallProgress_UnzippingOSC": "Puretaan OpenSteamClient:ia", - "#InstallProgress_WritingRegistryKeys": "Kirjoitetaan rekisteriarvoja" - } -} \ No newline at end of file diff --git a/Installer/ViewModels/AvaloniaAppViewModel.cs b/Installer/ViewModels/AvaloniaAppViewModel.cs deleted file mode 100644 index 14887a41..00000000 --- a/Installer/ViewModels/AvaloniaAppViewModel.cs +++ /dev/null @@ -1,5 +0,0 @@ -namespace Installer.ViewModels; - -public partial class AvaloniaAppViewModel : AvaloniaCommon.ViewModelBase { - -} \ No newline at end of file diff --git a/Installer/ViewModels/LanguageViewModel.cs b/Installer/ViewModels/LanguageViewModel.cs deleted file mode 100644 index ae305a41..00000000 --- a/Installer/ViewModels/LanguageViewModel.cs +++ /dev/null @@ -1,12 +0,0 @@ -using Installer.Translation; - -namespace Installer.ViewModels; - -public partial class LanguageViewModel : AvaloniaCommon.ViewModelBase { - public string Name { get; init; } - public ELanguage ELang { get; init; } - public LanguageViewModel(ELanguage lang) { - this.ELang = lang; - this.Name = AvaloniaApp.TranslationManager.GetPrettyNameForLanguage(lang); - } -} \ No newline at end of file diff --git a/Installer/ViewModels/MainWindowViewModel.cs b/Installer/ViewModels/MainWindowViewModel.cs deleted file mode 100644 index f82dbcca..00000000 --- a/Installer/ViewModels/MainWindowViewModel.cs +++ /dev/null @@ -1,269 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.ComponentModel; -using System.Globalization; -using System.Linq; -using System.Windows.Input; -using Avalonia.Controls; -using Avalonia.Media; -using Avalonia.Media.Imaging; -using Avalonia.Platform; -using CommunityToolkit.Mvvm.ComponentModel; -using CommunityToolkit.Mvvm.Input; -using Installer.Enums; -using Installer.Extensions; -using Installer.Translation; -using Installer.ViewModels.Pages; -using Installer.Views; - -namespace Installer.ViewModels; - -public partial class MainWindowViewModel : AvaloniaCommon.ViewModelBase { - [ObservableProperty] - private UserControl currentPage; - - [ObservableProperty] - private Bitmap openSteamLogo; - - public bool CanClose => OnCancel != null; - public bool PreviousEnabled => CanClose && OnPrevious != null; - public bool NextEnabled => CanClose && OnNext != null; - - [NotifyPropertyChangedFor(nameof(CanClose))] - [NotifyPropertyChangedFor(nameof(PreviousEnabled))] - [NotifyPropertyChangedFor(nameof(NextEnabled))] - [ObservableProperty] - private ICommand? onCancel; - - [NotifyPropertyChangedFor(nameof(PreviousEnabled))] - [ObservableProperty] - private ICommand? onPrevious; - - [NotifyPropertyChangedFor(nameof(NextEnabled))] - [ObservableProperty] - private ICommand? onNext; - - [ObservableProperty] - private LanguageViewModel selectedLanguage; - - public LinearGradientBrush PanelBackground { get; init; } - public ObservableCollection Languages { get; init; } = new(); - - private readonly MainWindow window; - private readonly List Pages = new(); - - private bool canGoBack = true; - public bool CanGoBack { - get => canGoBack; - set { - canGoBack = value; - UpdateActions(); - } - } - - public InstallAction AvailableActions { get; set; } - private InstallAction selectedAction = InstallAction.None; - public InstallAction SelectedAction { - get => selectedAction; - set { - selectedAction = value; - UpdateActions(); - } - } - - private bool canGoNext = false; - public bool CanGoNext { - get => canGoNext; - set { - canGoNext = value; - UpdateActions(); - } - } - - private bool HasPrevious => CanGoBack && Pages.IndexOf(CurrentPage) > 0; - private bool HasNext => CanGoNext && Pages.IndexOf(CurrentPage) + 1 < Pages.Count; - private readonly UserControl chooseActionPage; - private readonly UserControl placeholderPage; - private readonly PlaceholderPageViewModel placeholderPageViewModel; - - public MainWindowViewModel(MainWindow window) { - this.PanelBackground = new LinearGradientBrush(); - PanelBackground.StartPoint = new Avalonia.RelativePoint(0, 0, Avalonia.RelativeUnit.Relative); - PanelBackground.EndPoint = new Avalonia.RelativePoint(1, 1, Avalonia.RelativeUnit.Relative); - PanelBackground.GradientStops.Add(new GradientStop() { - Offset = 0, - Color = Color.Parse("#ff0000"), - }); - - PanelBackground.GradientStops.Add(new GradientStop() { - Offset = 1, - Color = Color.Parse("#7b0000"), - }); - - foreach (var item in TranslationManager.ValidUILanguages) - { - Languages.Add(new LanguageViewModel(item)); - } - - SelectedLanguage = Languages.First(l => AvaloniaApp.TranslationManager.CurrentTranslation.Language == l.ELang); - - this.window = window; - - //TODO: check install status here and determine the available actions - AvailableActions = InstallAction.Install | InstallAction.Repair | InstallAction.Uninstall; - - { - var page = new WelcomePage(); - page.DataContext = new WelcomePageViewModel(this); - Pages.Add(page); - } - - { - chooseActionPage = new ChooseActionPage(); - chooseActionPage.DataContext = new ChooseActionPageViewModel(this); - Pages.Add(chooseActionPage); - } - - { - placeholderPage = new PlaceholderPage(); - placeholderPageViewModel = new PlaceholderPageViewModel(); - placeholderPage.DataContext = placeholderPageViewModel; - Pages.Add(placeholderPage); - } - - { - var page = new InstallingPage(); - page.DataContext = new InstallingPageViewModel(); - Pages.Add(page); - } - - this.CurrentPage = Pages.First(); - - this.OpenSteamLogo = new Bitmap(AssetLoader.Open(new Uri("avares://Installer/Assets/opensteam-logo.ico"))); - this.PropertyChanged += InternalOnPropertyChanged; - this.OnCancel = new RelayCommand(Cancel); - this.OnNext = new RelayCommand(Next); - - window.Closing += OnClosing; - - UpdateActions(); - } - - private void OnClosing(object? sender, WindowClosingEventArgs e) - { - e.Cancel = !CanClose; - } - - private void InternalOnPropertyChanged(object? sender, PropertyChangedEventArgs e) - { - if (e.PropertyName == nameof(CanClose)) { - if (CanClose) { - WindowToolbar.EnableCloseButton(window); - } else { - WindowToolbar.DisableCloseButton(window); - } - } - - if (e.PropertyName == nameof(SelectedLanguage)) { - AvaloniaApp.TranslationManager.SetLanguage(SelectedLanguage.ELang); - } - } - - private void Cancel() { - AvaloniaApp.Current?.MainWindow?.Close(); - } - - private void Previous() { - if (HasPrevious) { - CurrentPage = Pages.ElementAt(Pages.IndexOf(CurrentPage) - 1); - } - - UpdateActions(); - } - - private void Next() { - if (HasNext) { - var nextPage = Pages.ElementAt(Pages.IndexOf(CurrentPage) + 1); - if (nextPage is PlaceholderPage) { - switch (SelectedAction) - { - case InstallAction.None: - placeholderPageViewModel.InternalControl = new TextBlock() { - Text = "No install action selected! (You should not be able to see this screen)" - }; - break; - case InstallAction.Install: - var page = new ChooseInstallDirectoryPage(); - page.DataContext = new ChooseInstallDirectoryPageViewModel(page, this); - placeholderPageViewModel.InternalControl = page; - break; - case InstallAction.Repair: - placeholderPageViewModel.InternalControl = new TextBlock() { - Text = "Repair page" - }; - break; - case InstallAction.Uninstall: - placeholderPageViewModel.InternalControl = new TextBlock() { - Text = "Uninstall page" - }; - break; - } - } - - if (nextPage is InstallingPage) { - OnCancel = null; - } - - CurrentPage = nextPage; - } - - UpdateActions(); - } - - private void UpdateActions() { - if (HasPrevious) { - OnPrevious = new RelayCommand(Previous); - } else { - OnPrevious = null; - } - - if (CurrentPage is ChooseActionPage) { - if (SelectedAction == InstallAction.None) { - OnNext = null; - return; - } - } - - if (!CanGoNext) { - OnNext = null; - return; - } - - Console.WriteLine("CurrentPage is " + (CurrentPage == null ? "null" : CurrentPage.GetType().Name)); - Console.WriteLine("InternalControl is " + (placeholderPageViewModel.InternalControl == null ? "null" : placeholderPageViewModel.InternalControl!.GetType().Name)); - - if (HasNext) { - OnNext = new RelayCommand(Next); - - var nextBtn = window.FindControlNested - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/OpenSteamClient/Controls/BaseWebPage.axaml.cs b/OpenSteamClient/Controls/BaseWebPage.axaml.cs deleted file mode 100644 index 41e0e238..00000000 --- a/OpenSteamClient/Controls/BaseWebPage.axaml.cs +++ /dev/null @@ -1,216 +0,0 @@ -using System; -using System.Collections.Generic; -using OpenSteamClient.Extensions; -using Avalonia.Controls; -using Avalonia.Markup.Xaml; -using Avalonia.Controls.Primitives; -using Avalonia; -using CommunityToolkit.Mvvm.ComponentModel; -using OpenSteamClient.Controls; -using Avalonia.Interactivity; -using System.Diagnostics.CodeAnalysis; -using OpenSteamworks; -using OpenSteamworks.Callbacks; -using OpenSteamworks.Callbacks.Structs; -using Avalonia.Threading; -using CommunityToolkit.Mvvm.Input; -using OpenSteamClient.DI; - -namespace OpenSteamClient.Controls; - -public partial class BaseWebPage : BasePage -{ - /// - /// Defines the property. - /// - public static readonly AttachedProperty URLProperty = - AvaloniaProperty.RegisterAttached(nameof(URL), typeof(BaseWebPage), "", true); - - /// - /// Defines the property. - /// - public static readonly AttachedProperty CustomCSSProperty = - AvaloniaProperty.RegisterAttached(nameof(CustomCSS), typeof(BaseWebPage), "", true); - - /// - /// Defines the property. - /// - public static readonly AttachedProperty UserAgentProperty = - AvaloniaProperty.RegisterAttached(nameof(UserAgent), typeof(BaseWebPage), "Valve Steam Client", true); - - /// - /// Defines the property. - /// - public static readonly AttachedProperty SetSteamCookiesProperty = - AvaloniaProperty.RegisterAttached(nameof(SetSteamCookies), typeof(BaseWebPage), false, true); - - /// - /// Gets or sets the url of the page to display. - /// - public string URL - { - get => this.GetValue(URLProperty); - set => this.SetValue(URLProperty, value); - } - - /// - /// Gets or sets the custom css. - /// - public string? CustomCSS - { - get => this.GetValue(CustomCSSProperty); - set => this.SetValue(CustomCSSProperty, value); - } - - /// - /// Gets or sets the user agent. - /// - public string UserAgent - { - get => this.GetValue(UserAgentProperty); - set => this.SetValue(UserAgentProperty, value); - } - - /// - /// Gets or sets if the webview should set steam cookies for auth. - /// - public bool SetSteamCookies - { - get => this.GetValue(SetSteamCookiesProperty); - set => this.SetValue(SetSteamCookiesProperty, value); - } - - private HTMLSurface? webviewControl; - - //I'd love to use bindings here, but due to us being inherited from control we can't. - private readonly ContentControl webviewContainer; - private readonly Button prevButton; - private readonly Button nextButton; - private readonly Button refreshButton; - private readonly Button openDevToolsButton; - private readonly TextBox currentURLTextBox; - private bool hasLoaded = false; - - public BaseWebPage() : base() - { - AvaloniaXamlLoader.Load(this); - this.TranslatableInit(); - - var webviewContainer = this.FindControl("WebviewContainer"); - if (webviewContainer == null) - { - throw new NullReferenceException("webviewContainer not found"); - } - this.webviewContainer = webviewContainer; - - var prevButton = this.FindControl - - - diff --git a/OpenSteamClient/Views/Debugging/HTMLSurfaceTest.axaml.cs b/OpenSteamClient/Views/Debugging/HTMLSurfaceTest.axaml.cs deleted file mode 100644 index d46332bc..00000000 --- a/OpenSteamClient/Views/Debugging/HTMLSurfaceTest.axaml.cs +++ /dev/null @@ -1,52 +0,0 @@ -using System; -using System.Threading.Tasks; -using Avalonia.Controls; -using Avalonia.Interactivity; -using Avalonia.Threading; -using OpenSteamClient.DI; -using OpenSteamClient.PlatformSpecific; -using OpenSteamworks; -using OpenSteamworks.Callbacks; -using OpenSteamworks.Callbacks.Structs; -using OpenSteamworks.Client.Startup; -using static OpenSteamworks.Callbacks.CallbackManager; - -namespace OpenSteamClient.Views; - -public partial class HTMLSurfaceTest : Window -{ - private Controls.HTMLSurface surfaceControl; - private ISteamClient client; - public HTMLSurfaceTest() : base() - { - InitializeComponent(); - - this.client = AvaloniaApp.Container.Get(); - surfaceControl = new(); - this.FindControl("webviewContainer")!.Children.Add(surfaceControl); - - this.Closing += (object? sender, WindowClosingEventArgs e) => - { - surfaceControl.RemoveBrowser(); - }; - - this.client.CallbackManager.Register(OnHTML_ChangedTitle_t); - } - - public async Task Init(string userAgent, string url) - { - var handle = await this.surfaceControl.CreateBrowserAsync(userAgent, ""); - this.client.IClientHTMLSurface.LoadURL(handle, url, null); - } - - private void OnHTML_ChangedTitle_t(ICallbackHandler handler, HTML_ChangedTitle_t data) - { - if (surfaceControl.BrowserHandle == data.unBrowserHandle) - { - Dispatcher.UIThread.InvokeAsync(() => - { - this.Title = data.pchTitle; - }); - } - } -} diff --git a/OpenSteamClient/Views/Dialogs/PickLaunchOptionDialog.axaml b/OpenSteamClient/Views/Dialogs/PickLaunchOptionDialog.axaml deleted file mode 100644 index 3f896bfc..00000000 --- a/OpenSteamClient/Views/Dialogs/PickLaunchOptionDialog.axaml +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/OpenSteamClient/Views/Library/FocusedAppPane.axaml.cs b/OpenSteamClient/Views/Library/FocusedAppPane.axaml.cs deleted file mode 100644 index 8fd02add..00000000 --- a/OpenSteamClient/Views/Library/FocusedAppPane.axaml.cs +++ /dev/null @@ -1,40 +0,0 @@ -using System; -using System.Collections.Generic; -using OpenSteamClient.Extensions; -using Avalonia.Controls; -using Avalonia.Interactivity; -using Avalonia.Markup.Xaml; -using OpenSteamClient.Controls; -using Avalonia.Media.Imaging; -using OpenSteamClient.DI; -using OpenSteamClient.ViewModels; -using OpenSteamClient.ViewModels.Library; -using OpenSteamClient.Views.Windows; -using OpenSteamworks; -using OpenSteamworks.Data.Structs; -using OpenSteamworks.Client.Apps; -using OpenSteamworks.Helpers; - -namespace OpenSteamClient.Views.Library; - -public partial class FocusedAppPane : BasePage -{ - public FocusedAppPane() : base() - { - InitializeComponent(); - this.TranslatableInit(); - } - - public void OpenSettingsForApp(object? sender, RoutedEventArgs routedEventArgs) - { - if (DataContext is not FocusedAppPaneViewModel vm) - return; - - var wnd = new AppSettingsWindow - { - DataContext = new AppSettingsWindowViewModel(AvaloniaApp.Container.Get(), vm.App) - }; - - wnd.Show(AvaloniaApp.Current!.MainWindow!); - } -} diff --git a/OpenSteamClient/Views/Pages/ConsolePage.axaml b/OpenSteamClient/Views/Pages/ConsolePage.axaml deleted file mode 100644 index 6deb88ed..00000000 --- a/OpenSteamClient/Views/Pages/ConsolePage.axaml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/OpenSteamClient/Views/Pages/LibraryPage.axaml.cs b/OpenSteamClient/Views/Pages/LibraryPage.axaml.cs deleted file mode 100644 index a7ad14d0..00000000 --- a/OpenSteamClient/Views/Pages/LibraryPage.axaml.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; -using System.Collections.Generic; -using OpenSteamClient.Extensions; -using Avalonia.Controls; -using Avalonia.Markup.Xaml; -using OpenSteamClient.Controls; - -namespace OpenSteamClient.Views; - -public partial class LibraryPage : BasePage -{ - public LibraryPage() : base() - { - InitializeComponent(); - this.TranslatableInit(); - } -} \ No newline at end of file diff --git a/OpenSteamClient/Views/Pages/WebBased/CommunityPage.axaml.cs b/OpenSteamClient/Views/Pages/WebBased/CommunityPage.axaml.cs deleted file mode 100644 index 2a30bb2c..00000000 --- a/OpenSteamClient/Views/Pages/WebBased/CommunityPage.axaml.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; -using System.Collections.Generic; -using OpenSteamClient.Extensions; -using Avalonia.Controls; -using Avalonia.Markup.Xaml; -using OpenSteamClient.Controls; - -namespace OpenSteamClient.Views; - -public partial class CommunityPage : BaseWebPage -{ - public CommunityPage() : base() - { - this.URL = "https://steamcommunity.com"; - this.SetSteamCookies = true; - } -} \ No newline at end of file diff --git a/OpenSteamClient/Views/Pages/WebBased/StorePage.axaml.cs b/OpenSteamClient/Views/Pages/WebBased/StorePage.axaml.cs deleted file mode 100644 index 92d2817f..00000000 --- a/OpenSteamClient/Views/Pages/WebBased/StorePage.axaml.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; -using System.Collections.Generic; -using OpenSteamClient.Extensions; -using Avalonia.Controls; -using Avalonia.Markup.Xaml; -using OpenSteamClient.Controls; - -namespace OpenSteamClient.Views; - -public partial class StorePage : BaseWebPage -{ - public StorePage() : base() - { - this.URL = "https://store.steampowered.com"; - this.SetSteamCookies = true; - } -} \ No newline at end of file diff --git a/OpenSteamClient/Views/README.md b/OpenSteamClient/Views/README.md deleted file mode 100644 index f72a4016..00000000 --- a/OpenSteamClient/Views/README.md +++ /dev/null @@ -1,10 +0,0 @@ -# Views -Views define the UI. They don't define any logic, that is driven by properties and methods in ViewModels, which all views should bind to. -In something like a login window with multiple possible "sub-views" like an account picker and credential input, you can use a property in a ViewModel to define what View should be visible. Then use a ContentControl and bind it's Content property to that ViewModel. - -# Windows vs Dialogs -Windows are non-blocking, meaning they don't prevent input to the window that summoned them. -Dialogs are blocking, until the user takes action by closing the dialog, where they will stop input to the window that summoned them. - -# I don't know where I should put my View -Just place it in the Views folder if unsure. It'll be handled when reviewing your PR, or kept there if needed. \ No newline at end of file diff --git a/OpenSteamClient/Views/Windows/AccountPickerWindow.axaml b/OpenSteamClient/Views/Windows/AccountPickerWindow.axaml deleted file mode 100644 index 0e823b87..00000000 --- a/OpenSteamClient/Views/Windows/AccountPickerWindow.axaml +++ /dev/null @@ -1,58 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/OpenSteamClient/Views/Windows/AccountPickerWindow.axaml.cs b/OpenSteamClient/Views/Windows/AccountPickerWindow.axaml.cs deleted file mode 100644 index 00d56782..00000000 --- a/OpenSteamClient/Views/Windows/AccountPickerWindow.axaml.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System.IO; -using Avalonia.Controls; -using OpenSteamClient.Extensions; -using OpenSteamClient.ViewModels; -using QRCoder; - -namespace OpenSteamClient.Views; - -public partial class AccountPickerWindow : Window -{ - public AccountPickerWindow() - { - InitializeComponent(); - this.TranslatableInit(); - } - -} \ No newline at end of file diff --git a/OpenSteamClient/Views/Windows/AppSettingsWindow.axaml b/OpenSteamClient/Views/Windows/AppSettingsWindow.axaml deleted file mode 100644 index 655af82f..00000000 --- a/OpenSteamClient/Views/Windows/AppSettingsWindow.axaml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - - - diff --git a/OpenSteamClient/Views/Windows/AppSettingsWindow.axaml.cs b/OpenSteamClient/Views/Windows/AppSettingsWindow.axaml.cs deleted file mode 100644 index 2a04fa89..00000000 --- a/OpenSteamClient/Views/Windows/AppSettingsWindow.axaml.cs +++ /dev/null @@ -1,15 +0,0 @@ -using Avalonia; -using Avalonia.Controls; -using Avalonia.Markup.Xaml; -using OpenSteamworks.Client.Apps; - -namespace OpenSteamClient.Views.Windows; - -public partial class AppSettingsWindow : Window -{ - public AppSettingsWindow() - { - InitializeComponent(); - } -} - diff --git a/OpenSteamClient/Views/Windows/LoginWindow.axaml b/OpenSteamClient/Views/Windows/LoginWindow.axaml deleted file mode 100644 index 8f1b1ef9..00000000 --- a/OpenSteamClient/Views/Windows/LoginWindow.axaml +++ /dev/null @@ -1,43 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/OpenSteamClient/Views/Windows/MainWindow.axaml.cs b/OpenSteamClient/Views/Windows/MainWindow.axaml.cs deleted file mode 100644 index 6cc1856e..00000000 --- a/OpenSteamClient/Views/Windows/MainWindow.axaml.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; -using System.Collections.Generic; -using OpenSteamClient.Extensions; -using Avalonia.Controls; -using Avalonia.Markup.Xaml; - -namespace OpenSteamClient.Views; - -public partial class MainWindow : Window -{ - public MainWindow() - { - InitializeComponent(); - this.TranslatableInit(); - } -} \ No newline at end of file diff --git a/OpenSteamClient/Views/Windows/ProgressWindow.axaml b/OpenSteamClient/Views/Windows/ProgressWindow.axaml deleted file mode 100644 index 4a581f24..00000000 --- a/OpenSteamClient/Views/Windows/ProgressWindow.axaml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - diff --git a/OpenSteamClient/Views/Windows/ProgressWindow.axaml.cs b/OpenSteamClient/Views/Windows/ProgressWindow.axaml.cs deleted file mode 100644 index bfb67043..00000000 --- a/OpenSteamClient/Views/Windows/ProgressWindow.axaml.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System; -using Avalonia.Controls; -using OpenSteamClient.ViewModels; -using OpenSteamworks.Client.Utils; - -namespace OpenSteamClient.Views; - -public partial class ProgressWindow : Window -{ - public ProgressWindow(ProgressWindowViewModel vm) - { - this.DataContext = vm; - InitializeComponent(); - } - - private void Window_OnClosing(object? sender, WindowClosingEventArgs e) - { - if (this.DataContext is ProgressWindowViewModel progVm) - progVm.OnClosed?.Invoke(e); - } -} diff --git a/OpenSteamClient/Views/Windows/SettingsWindow.axaml b/OpenSteamClient/Views/Windows/SettingsWindow.axaml deleted file mode 100644 index 7a9c441f..00000000 --- a/OpenSteamClient/Views/Windows/SettingsWindow.axaml +++ /dev/null @@ -1,77 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - -