From 3fb04bedc1a600b75495ac9bd05e89c87eddbf5b Mon Sep 17 00:00:00 2001 From: Bagus Nur Listiyono <28079733+bagusnl@users.noreply.github.com> Date: Fri, 30 Jun 2023 15:17:44 +0700 Subject: [PATCH] Implement Genshin Impact Game Settings (#183) * GI GameSettings: Initial Implementation for ScreenManager * GI GameSettings: add debug line for ScreenManager Load() * GI GameSettings: Introduce locales * GI GameSettings: Initial implementation for frontend page * GI GameSettings: add override for isfullScreen * GI GameSettings: Initial implementation for GeneralData root tree * GI GameSettings: Force load for ScreenManager * GI GameSettings: Initial implementation for GraphicsData tree * GI GameSettings: Misc information * GI GameSettings: Fix page crashing * GI GameSettings: Fix namespaces names * GI GameSettings: Fix SettingScreen not saving * GI GameSettings: Implement RegistryWatcher * GI GameSettings: Fix missing GeneralData Equals * GI GameSettings: Use Debug LogType * GI GameSettings: Fix GeneralData.cs - Implement fallback for globalPerfData and _overrideControllerMapValueList - Fix some wrong Json keys * GI GameSettings: Fix GeneralData.cs - globalPerfData not saved properly * GI GameSettings: Fix value types for GeneralData feat. @Cryotechnic * GI GameSettings: Adjusted graphicsData key order * GI GameSettings: UI * GI GameSettings: Frontend Improvements - Add audio settings - Adjusted locales - Adjusted margins * GI GameSettings: also set globalPerfData * Fix StarRail Localization - Unsure how it got yeeted off there and still works... * GI GameSettings: Add Language Settings * GI GameSettings: Implement Exclusive Fullscreen toggle - Also added necessary warning for its use * Get ordered FPS list programmatically * GI GameSettings: Disable General Data dumping in Load/Save - Because its huuuuge * GI GameSettings: Locales Cleanup * GI GameSettings: Locales Cleanup pt. 2 * GI GameSettings: Code Cleanup - Removed unused usings - Adjusted log console strings * GI GameSettings: Implement Gamma slider * GI GameSettings: Implement Gamma slider * Disable Exclusive Fullscreen on both Genshin and StarRail * GI GameSettings: Attempt to fix Gamma slider * fixed gamma behaving in reverse because ofc mhy would do that, thanks mhy <3 --------- Co-authored-by: Myp3a Co-authored-by: Kemal Setya Adhi Co-authored-by: Ron Friedman Co-authored-by: Iskandar Montano --- .../GameSettings/Genshin/Context.cs | 17 + .../Genshin/RegistryClass/Enums/Enums.cs | 123 +++++ .../Genshin/RegistryClass/GeneralData.cs | 446 ++++++++++++++++++ .../Genshin/RegistryClass/GlobalPerfData.cs | 68 +++ .../Genshin/RegistryClass/GraphicsData.cs | 256 ++++++++++ .../Genshin/RegistryClass/ScreenManager.cs | 164 +++++++ .../GameSettings/Genshin/Settings.cs | 8 + .../XAMLs/MainApp/MainPage.xaml.cs | 10 + .../Pages/GenshinGameSettingsPage.Ext.cs | 298 ++++++++++++ .../Pages/GenshinGameSettingsPage.xaml | 435 +++++++++++++++++ .../Pages/GenshinGameSettingsPage.xaml.cs | 205 ++++++++ .../XAMLs/MainApp/Pages/HomePage.xaml.cs | 23 + .../Pages/StarRailGameSettingsPage.xaml | 6 +- .../Locale/LangGenshinGameSettingsPage.cs | 104 ++++ Hi3Helper.Core/Lang/en-us.json | 77 +++ 15 files changed, 2239 insertions(+), 1 deletion(-) create mode 100644 CollapseLauncher/Classes/GameManagement/GameSettings/Genshin/Context.cs create mode 100644 CollapseLauncher/Classes/GameManagement/GameSettings/Genshin/RegistryClass/Enums/Enums.cs create mode 100644 CollapseLauncher/Classes/GameManagement/GameSettings/Genshin/RegistryClass/GeneralData.cs create mode 100644 CollapseLauncher/Classes/GameManagement/GameSettings/Genshin/RegistryClass/GlobalPerfData.cs create mode 100644 CollapseLauncher/Classes/GameManagement/GameSettings/Genshin/RegistryClass/GraphicsData.cs create mode 100644 CollapseLauncher/Classes/GameManagement/GameSettings/Genshin/RegistryClass/ScreenManager.cs create mode 100644 CollapseLauncher/XAMLs/MainApp/Pages/GenshinGameSettingsPage.Ext.cs create mode 100644 CollapseLauncher/XAMLs/MainApp/Pages/GenshinGameSettingsPage.xaml create mode 100644 CollapseLauncher/XAMLs/MainApp/Pages/GenshinGameSettingsPage.xaml.cs create mode 100644 Hi3Helper.Core/Lang/Locale/LangGenshinGameSettingsPage.cs diff --git a/CollapseLauncher/Classes/GameManagement/GameSettings/Genshin/Context.cs b/CollapseLauncher/Classes/GameManagement/GameSettings/Genshin/Context.cs new file mode 100644 index 000000000..8bf35b30e --- /dev/null +++ b/CollapseLauncher/Classes/GameManagement/GameSettings/Genshin/Context.cs @@ -0,0 +1,17 @@ +using CollapseLauncher.GameSettings.Genshin; +using System.Text.Json.Serialization; + +namespace CollapseLauncher.GameSettings.Genshin.Context +{ + [JsonSourceGenerationOptions(IncludeFields = false, GenerationMode = JsonSourceGenerationMode.Metadata, IgnoreReadOnlyFields = true)] + [JsonSerializable(typeof(GeneralData))] + internal sealed partial class GeneralDataContext : JsonSerializerContext { } + + [JsonSourceGenerationOptions(IncludeFields = false, GenerationMode = JsonSourceGenerationMode.Metadata, IgnoreReadOnlyFields = true)] + [JsonSerializable(typeof(GraphicsData))] + internal sealed partial class GraphicsDataContext : JsonSerializerContext { } + + [JsonSourceGenerationOptions(IncludeFields = false, GenerationMode = JsonSourceGenerationMode.Metadata, IgnoreReadOnlyFields = true)] + [JsonSerializable(typeof(GlobalPerfData))] + internal sealed partial class GlobalPerfDataContext : JsonSerializerContext { } +} diff --git a/CollapseLauncher/Classes/GameManagement/GameSettings/Genshin/RegistryClass/Enums/Enums.cs b/CollapseLauncher/Classes/GameManagement/GameSettings/Genshin/RegistryClass/Enums/Enums.cs new file mode 100644 index 000000000..03293732e --- /dev/null +++ b/CollapseLauncher/Classes/GameManagement/GameSettings/Genshin/RegistryClass/Enums/Enums.cs @@ -0,0 +1,123 @@ +namespace CollapseLauncher.GameSettings.Genshin.Enums +{ + enum FPSOption : int + { + f30 = 1, + f60 = 2, + f45 = 3 + } + + enum RenderResolutionOption + { + x06 = 1, + x08 = 2, + x10 = 3, + x11 = 4, + x12 = 5, + x13 = 6, + x14 = 7, + x15 = 8 + } + + enum ShadowQualityOption + { + Lowest = 1, + Low = 2, + Medium = 3, + High = 4 + } + + enum VisualEffectsOption + { + Lowest = 1, + Low = 2, + Medium = 3, + High = 4 + } + + enum SFXQualityOption + { + Lowest = 1, + Low = 2, + Medium = 3, + High = 4 + } + + enum EnvironmentDetailOption + { + Lowest = 1, + Low = 2, + Medium = 3, + High = 4, + Highest = 5 + } + + enum VerticalSyncOption + { + Off = 1, + On = 2 + } + + enum AntialiasingOption + { + Off = 1, + FSR2 = 2, + SMAA = 3 + } + + enum VolumetricFogOption + { + Off = 1, + On = 2 + } + + enum ReflectionsOption + { + Off = 1, + On = 2 + } + + enum MotionBlurOption + { + Off = 1, + Low = 2, + High = 3, + Extreme = 4 + } + + enum BloomOption + { + Off = 1, + On = 2 + } + + enum CrowdDensityOption + { + Low = 1, + High = 2 + } + + enum SubsurfaceScatteringOption + { + Off = 1, + Medium = 2, + High = 3 + } + + enum CoOpTeammateEffectsOption + { + Off = 1, + PartiallyOff = 2, + On = 3 + } + + enum AnisotropicFilteringOption + { + x1 = 1, + x2 = 2, + x4 = 3, + x8 = 4, + x16 = 5 + } +} + diff --git a/CollapseLauncher/Classes/GameManagement/GameSettings/Genshin/RegistryClass/GeneralData.cs b/CollapseLauncher/Classes/GameManagement/GameSettings/Genshin/RegistryClass/GeneralData.cs new file mode 100644 index 000000000..699e7d785 --- /dev/null +++ b/CollapseLauncher/Classes/GameManagement/GameSettings/Genshin/RegistryClass/GeneralData.cs @@ -0,0 +1,446 @@ +using CollapseLauncher.GameSettings.Genshin; +using CollapseLauncher.GameSettings.Genshin.Context; +using CollapseLauncher.Interfaces; +using Hi3Helper; +using Microsoft.Win32; +using System; +using System.Collections.Generic; +using System.Text; +using System.Text.Json; +using System.Text.Json.Serialization; +using static CollapseLauncher.GameSettings.Statics; +using static Hi3Helper.Logger; + +namespace CollapseLauncher.GameSettings.Genshin +{ + internal class GeneralData + { + #region Fields + private const string _ValueName = "GENERAL_DATA_h2389025596"; + #endregion + + #region Properties + //in need of help,, + //Using guide from https://github.com/Myp3a/GenshinConfigurator/wiki/Config-format + //Thanks Myp3a! + + /// + /// deviceUUID
+ /// This is supposed to be empty + ///
+ public string deviceUUID { get; set; } = ""; + + /// + /// userLocalDataVersionId
+ /// This should be static
+ /// Value: 0.0.1 + ///
+ public string userLocalDataVersionId { get; set; } = "0.0.1"; + + /// + /// This define "Text Language" in-game settings.
+ /// Valid values: 1-13 + /// Default: 1 + /// English(1) + /// Simplified Chinese(2) + /// Traditional Chinese(3) + /// French(4) + /// German(5) + /// Spanish(6) + /// Portugese(7) + /// Russian(8) + /// Japanese(9) + /// Korean(10) + /// Thai(11) + /// Vietnamese(12) + /// Indonesian(13) + /// Turkish(14) + /// Italy(15) + ///
+ public int deviceLanguageType { get; set; } = 1; + + /// + /// This define "Voice Language" in-game settings.
+ /// Valid values: 0-3 + /// Default: 1 + /// Chinese(0) + /// English(1) + /// Japanese(2) + /// Korean(3) + ///
+ public int deviceVoiceLanguageType { get; set; } = 1; + + /// + /// This define "Server Name" last selected in loading menu.
+ ///
+ public string selectedServerName { get; set; } = "os_usa"; + + /// + /// I don't know what this do + /// + public int localLevelIndex { get; set; } = 0; + public string deviceID { get; set; } = ""; + public string targetUID { get; set; } = ""; + public string curAccountName { get; set; } = ""; + + /// + /// This define "Resolution" index selected in-game.
+ /// Valid value: 0-? + /// Default: 0 + ///
+ public string uiSaveData { get; set; } + + /// + /// This holds settings for input sens and stuff.
+ /// Please look at https://github.com/Myp3a/GenshinConfigurator/wiki/Config-format#input-data-format + ///
+ public string inputData { get; set; } + + /// + /// This holds settings that holds Graphics Settings settings. YEP!
+ /// Needs to be serialized again with its keys and values in dictionary
+ /// https://github.com/Myp3a/GenshinConfigurator/wiki/Config-format#graphics-data-format + ///
+ [JsonPropertyName("graphicsData")] + public string _graphicsData { get; set; } + + [JsonIgnore] + public GraphicsData graphicsData { get; set; } + + /// + /// This is a dict that keeps track of graphics settings changes.
+ /// Save to ignore (?) + ///
+ // Temporary for fallback before the implementation is made + [JsonIgnore] + public GlobalPerfData globalPerfData { get; set; } + + [JsonPropertyName("globalPerfData")] + public string _globalPerfData { get; set; } + + //[JsonIgnore] + //public globalPerfData globalPerfData { get; set; } + + /// + /// Something about minimap config ? + /// + public int miniMapConfig { get; set; } = 1; + + /// + /// This defines "Automatic View Height" in-game settings.
+ /// Default: true + ///
+ public bool enableCameraSlope { get; set; } = true; + + /// + /// This defines "Smart combat camera" whatever that is.
+ /// Default: true + ///
+ public bool enableCameraCombatLock { get; set; } = true; + + /// + /// not sure either what these does. + /// + public bool completionPkg { get; set; } = false; + public bool completionPlayGoPkg { get; set; } = false; + + /// + /// Could be for PlayStation multiplayer stuff + /// + public bool onlyPlayWithPSPlayer { get; set; } = false; + + /// + /// Mysterious~ + /// + public bool needPlayGoFullPkgPatch { get; set; } = false; + + /// + /// Mobile notification stuff + /// + public bool resinNotification { get; set; } = true; + public bool exploreNotification { get; set; } = true; + + /// + /// This define "Global Volume" slider in-game.
+ /// Valid values: 0-10 + /// Default: 10 + ///
+ public int volumeGlobal { get; set; } = 10; + + /// + /// This define "SFX Volume" slider in-game.
+ /// Valid values: 0-10 + /// Default: 10 + ///
+ public int volumeSFX { get; set; } = 10; + + /// + /// This define "Music Volume" slider in-game.
+ /// Valid values: 0-10 + /// Default: 10 + ///
+ public int volumeMusic { get; set; } = 10; + + /// + /// This define "Voice Volume" slider in-game.
+ /// Valid values: 0-10 + /// Default: 10 + ///
+ public int volumeVoice { get; set; } = 10; + + /// + /// Probably just leave it alone... + /// + public int audioAPI { get; set; } = -1; + + /// + /// This defines "Dynamic Range" audio combo box in-game. + /// Valid values: 0 (full), 1 (limited) + /// Default: 0 + /// + public int audioDynamicRange { get; set; } = 0; + + /// + /// This defines "Audio Output" combo box in-game. + /// Valid Values: 0 (stereo), 1 (surround) + /// Default: 0 + /// + public int audioOutput { get; set; } = 0; + + /// + /// Audio related stuff... + /// + public bool _audioSuccessInit { get; set; } = true; + public bool enableAudioChangeAndroidMinimumBufferCapacity { get; set; } = true; + public int audioAndroidMiniumBufferCapacity { get; set; } = 2048; + + /// + /// This define vibration level for certain controller probably ? + /// Valid Values: 0 (Full), 1 (Partial), 2 (Off) + /// Default: 0 + /// + public int vibrationLevel { get; set; } = 0; + + /// + /// This defines "Vibration Intensity" slider in-game.
+ /// Valid Values: 1-5 + /// Default: 5 + ///
+ public int vibrationIntensity { get; set; } = 5; + + /// + /// Some vibration related stuff ? + /// + public bool usingNewVibrationSetting { get; set; } = true; + + /// + /// Is not an actual blur setting + /// + public bool motionBlur { get; set; } = true; + + /// + /// Gyro Aiming stuff, most likely not used in PC. + /// + public bool gyroAiming { get; set; } = false; + + //unsure what these does, probably HDR stuff? doesn't have HDR monitor to test... + public bool firstHDRSetting { get; set; } = true; + public decimal maxLuminosity { get; set; } = 0.0m; + public decimal uiPaperWhite { get; set; } = 0.0m; + public decimal scenePaperWhite { get; set; } = 0.0m; + + /// + /// This defines "Gamma" slider in-game.
+ ///
+ public double gammaValue { get; set; } = 2.2f; + + /// + /// This holds value for controllers input that has been customized. + /// + public List _overrideControllerMapKeyList { get; set; } + + + /// + /// This holds said override for those controllers. + /// + // Temporary for fallback before the implementation is made + public List _overrideControllerMapValueList { get; set; } + + //[JsonPropertyName("_overrideControllerMapValueList")] + //public List __overrideControllerMapValueList { get; set; } + + //[JsonIgnore] + //public Controllers _overrideControllerMapValueList { get; set; } + + //misc values + //just, idk, ignore? + public bool rewiredDisableKeyboard { get; set; } = false; + public bool rewiredEnableKeyboard { get; set; } = false; + public bool rewiredEnableEDS { get; set; } = false; + public bool disableRewiredDelayInit { get; set; } = false; + public bool disableRewiredInitProtection { get; set; } = false; + public int lastSeenPreDownloadTime { get; set; } = 0; + public bool enableEffectAssembleInEditor { get; set; } = true; + public bool forceDisableQuestResourceManagement { get; set; } = false; + public bool needReportQuestResourceDeleteStatusFiles { get; set; } = false; + public bool mtrCached { get; set; } = true; + public bool mtrIsOpen { get; set; } = true; + public int mtrMaxTTL { get; set; } = 32; + public int mtrTimeOut { get; set; } = 5000; + public int mtrTraceCount { get; set; } = 5; + public int mtrAbortTimeOutCount { get; set; } = 3; + public int mtrAutoTraceInterval { get; set; } = 3600; + public int mtrTraceCDEachReason { get; set; } = 600; + public int mtrTimeInterval { get; set; } = 1000; + public List mtrBanReasons { get; set; } + public List _customDataKeyList { get; set; } + public List _customDataValueList { get; set; } + public List _serializedCodeSwitches { get; set; } + public bool urlCheckCached { get; set; } = false; + public bool urlCheckIsOpen { get; set; } = false; + public bool urlCheckAllIP { get; set; } = false; + public int urlCheckTimeOut { get; set; } = 5000; + public int urlCheckSueecssTraceCount { get; set; } = 5; + public int urlCheckErrorTraceCount { get; set; } = 30; + public int urlCheckAbortTimeOutCount { get; set; } = 3; + public int urlCheckTimeInterval { get; set; } = 1000; + public int urlCheckCDEachReason { get; set; } = 600; + public List urlCheckBanReasons { get; set; } + public bool mtrUseOldWinVersion { get; set; } = false; + public string greyTestDeviceUniqueId { get; set; } = ""; + #endregion + + #region Methods +#nullable enable + public static GeneralData Load() + { + try + { + if (RegistryRoot == null) throw new NullReferenceException($"Cannot load {_ValueName} RegistryKey is unexpectedly not initialized!"); + object? value = RegistryRoot.GetValue(_ValueName, null); + + if (value != null) + { + ReadOnlySpan byteStr = (byte[])value; + LogWriteLine($"Loaded Genshin Settings: {_ValueName}", LogType.Debug, true); + GeneralData data = (GeneralData?)JsonSerializer.Deserialize(byteStr.Slice(0, byteStr.Length - 1), typeof(GeneralData), GeneralDataContext.Default) ?? new GeneralData(); + data.graphicsData = GraphicsData.Load(data._graphicsData); + data.globalPerfData = new(); + return data; + } + } + catch (Exception ex) + { + LogWriteLine($"Failed while reading {_ValueName}\r\n{ex}", LogType.Error, true); + } + + return new GeneralData(); + } + + public void Save() + { + try + { + if (RegistryRoot == null) throw new NullReferenceException($"Cannot save {_ValueName} since RegistryKey is unexpectedly not initialized!"); + + _graphicsData = graphicsData.Save(); + _globalPerfData = globalPerfData.Create(graphicsData, graphicsData.volatileVersion); + LogWriteLine($"Saved Gamma Value {gammaValue}", LogType.Debug); + string data = JsonSerializer.Serialize(this, typeof(GeneralData), GeneralDataContext.Default) + '\0'; + byte[] dataByte = Encoding.UTF8.GetBytes(data); + LogWriteLine($"Saved Genshin Settings: {_ValueName}", LogType.Debug, true); + RegistryRoot.SetValue(_ValueName, dataByte, RegistryValueKind.Binary); + } + catch (Exception ex) + { + LogWriteLine($"Failed to save {_ValueName}!\r\n{ex}", LogType.Error, true); + } + } + + public bool Equals(GeneralData? comparedTo) + { + if (ReferenceEquals(this, comparedTo)) return true; + if (comparedTo == null) return false; + //todo add properties + + return comparedTo.deviceUUID == deviceUUID && + comparedTo.userLocalDataVersionId == userLocalDataVersionId && + comparedTo.deviceLanguageType == deviceLanguageType && + comparedTo.deviceVoiceLanguageType == deviceVoiceLanguageType && + comparedTo.selectedServerName == selectedServerName && + comparedTo.localLevelIndex == localLevelIndex && + comparedTo.deviceID == deviceID && + comparedTo.targetUID == targetUID && + comparedTo.uiSaveData == uiSaveData && + comparedTo.inputData == inputData && + comparedTo.graphicsData == graphicsData && + comparedTo.globalPerfData == globalPerfData && + comparedTo.miniMapConfig == miniMapConfig && + comparedTo.enableCameraSlope == enableCameraSlope && + comparedTo.enableCameraCombatLock == enableCameraCombatLock && + comparedTo.completionPkg == completionPkg && + comparedTo.completionPlayGoPkg == completionPlayGoPkg && + comparedTo.onlyPlayWithPSPlayer == onlyPlayWithPSPlayer && + comparedTo.needPlayGoFullPkgPatch == needPlayGoFullPkgPatch && + comparedTo.resinNotification == resinNotification && + comparedTo.exploreNotification == exploreNotification && + comparedTo.volumeGlobal == volumeGlobal && + comparedTo.volumeSFX == volumeSFX && + comparedTo.volumeVoice == volumeVoice && + comparedTo.audioAPI == audioAPI && + comparedTo.audioDynamicRange == audioDynamicRange && + comparedTo.audioOutput == audioOutput && + comparedTo._audioSuccessInit == _audioSuccessInit && + comparedTo.enableAudioChangeAndroidMinimumBufferCapacity == enableAudioChangeAndroidMinimumBufferCapacity && + comparedTo.audioAndroidMiniumBufferCapacity == audioAndroidMiniumBufferCapacity && + comparedTo.vibrationLevel == vibrationLevel && + comparedTo.vibrationIntensity == vibrationIntensity && + comparedTo.usingNewVibrationSetting == usingNewVibrationSetting && + comparedTo.motionBlur == motionBlur && + comparedTo.gyroAiming == gyroAiming && + comparedTo.firstHDRSetting == firstHDRSetting && + comparedTo.maxLuminosity == maxLuminosity && + comparedTo.uiPaperWhite == uiPaperWhite && + comparedTo.scenePaperWhite == scenePaperWhite && + comparedTo.gammaValue == gammaValue && + comparedTo._overrideControllerMapKeyList == _overrideControllerMapKeyList && + comparedTo._overrideControllerMapValueList == _overrideControllerMapValueList && + comparedTo.rewiredDisableKeyboard == rewiredDisableKeyboard && + comparedTo.rewiredEnableKeyboard == rewiredEnableKeyboard && + comparedTo.rewiredEnableEDS == rewiredEnableEDS && + comparedTo.disableRewiredDelayInit == disableRewiredDelayInit && + comparedTo.disableRewiredInitProtection == disableRewiredInitProtection && + comparedTo.lastSeenPreDownloadTime == lastSeenPreDownloadTime && + comparedTo.enableEffectAssembleInEditor == enableEffectAssembleInEditor && + comparedTo.forceDisableQuestResourceManagement == forceDisableQuestResourceManagement && + comparedTo.needReportQuestResourceDeleteStatusFiles == needReportQuestResourceDeleteStatusFiles && + comparedTo.mtrCached == mtrCached && + comparedTo.mtrIsOpen == mtrIsOpen && + comparedTo.mtrMaxTTL == mtrMaxTTL && + comparedTo.mtrTimeOut == mtrTimeOut && + comparedTo.mtrTraceCount == mtrTraceCount && + comparedTo.mtrAbortTimeOutCount == mtrAbortTimeOutCount && + comparedTo.mtrAutoTraceInterval == mtrAutoTraceInterval && + comparedTo.mtrTraceCDEachReason == mtrTraceCDEachReason && + comparedTo.mtrTimeInterval == mtrTimeInterval && + comparedTo.mtrBanReasons == mtrBanReasons && + comparedTo._customDataKeyList == _customDataKeyList && + comparedTo._customDataValueList == _customDataValueList && + comparedTo._serializedCodeSwitches == _serializedCodeSwitches && + comparedTo.urlCheckCached == urlCheckCached && + comparedTo.urlCheckIsOpen == urlCheckIsOpen && + comparedTo.urlCheckAllIP == urlCheckAllIP && + comparedTo.urlCheckTimeOut == urlCheckTimeOut && + comparedTo.urlCheckSueecssTraceCount == urlCheckSueecssTraceCount && + comparedTo.urlCheckErrorTraceCount == urlCheckErrorTraceCount && + comparedTo.urlCheckAbortTimeOutCount == urlCheckAbortTimeOutCount && + comparedTo.urlCheckTimeInterval == urlCheckTimeInterval && + comparedTo.urlCheckCDEachReason == urlCheckCDEachReason && + comparedTo.urlCheckBanReasons == urlCheckBanReasons && + comparedTo.mtrUseOldWinVersion == mtrUseOldWinVersion && + comparedTo.greyTestDeviceUniqueId == greyTestDeviceUniqueId; + } +#nullable disable + #endregion + } +} diff --git a/CollapseLauncher/Classes/GameManagement/GameSettings/Genshin/RegistryClass/GlobalPerfData.cs b/CollapseLauncher/Classes/GameManagement/GameSettings/Genshin/RegistryClass/GlobalPerfData.cs new file mode 100644 index 000000000..e0fd2e910 --- /dev/null +++ b/CollapseLauncher/Classes/GameManagement/GameSettings/Genshin/RegistryClass/GlobalPerfData.cs @@ -0,0 +1,68 @@ +using CollapseLauncher.GameSettings.Genshin; +using CollapseLauncher.GameSettings.Genshin.Context; +using CollapseLauncher.GameSettings.Genshin.Enums; +using Hi3Helper; +using System; +using System.Collections.Generic; +using System.Text.Json; +using static Hi3Helper.Logger; + +namespace CollapseLauncher.GameSettings.Genshin +{ + internal class PerfDataItem + { + #region Properties + public int entryType { get; set; } + public int index { get; set; } + public string itemVersion { get; set; } + #endregion + + #region Methods + public PerfDataItem(int entryType, int index, string itemVersion) { + this.entryType = entryType; + this.index = index; + this.itemVersion = itemVersion; + } + #endregion + } + internal class GlobalPerfData + { + #region Properties + public List saveItems { get; set; } = new(); + public bool truePortedFromGraphicData { get; set; } = true; + public string portedVersion { get; set; } = "OSRELWin3.7.0"; + public bool portedFromGraphicsData { get; set; } = false; + #endregion + + #region Methods + + public string Create(GraphicsData graphics, string version) + { + LogWriteLine($"Created Genshin GlobalPerfData\r\n{graphics}", LogType.Debug, true); + + saveItems = new() + { + new PerfDataItem (1, (int)graphics.FPS - 1, version), + new PerfDataItem (2, (int)graphics.RenderResolution - 1, version), + new PerfDataItem (3,(int) graphics.ShadowQuality - 1, version), + new PerfDataItem (4,(int) graphics.VisualEffects - 1, version), + new PerfDataItem (5,(int) graphics.SFXQuality - 1, version), + new PerfDataItem (6,(int) graphics.EnvironmentDetail - 1, version), + new PerfDataItem (7,(int) graphics.VerticalSync - 1, version), + new PerfDataItem (8,(int) graphics.Antialiasing - 1, version), + new PerfDataItem (9,(int) graphics.VolumetricFog - 1, version), + new PerfDataItem (10,(int) graphics.Reflections - 1, version), + new PerfDataItem (11,(int) graphics.MotionBlur - 1, version), + new PerfDataItem (12,(int) graphics.Bloom - 1, version), + new PerfDataItem (13,(int) graphics.CrowdDensity - 1, version), + new PerfDataItem (16,(int) graphics.CoOpTeammateEffects - 1, version), + new PerfDataItem (15,(int) graphics.SubsurfaceScattering - 1, version), + new PerfDataItem (17,(int) graphics.AnisotropicFiltering - 1, version), + }; + string data = JsonSerializer.Serialize(this, typeof(GlobalPerfData), GlobalPerfDataContext.Default); + LogWriteLine($"Created Genshin GlobalPerfData\r\n{data}", LogType.Debug, true); + return data; + } + #endregion + } +} diff --git a/CollapseLauncher/Classes/GameManagement/GameSettings/Genshin/RegistryClass/GraphicsData.cs b/CollapseLauncher/Classes/GameManagement/GameSettings/Genshin/RegistryClass/GraphicsData.cs new file mode 100644 index 000000000..723639add --- /dev/null +++ b/CollapseLauncher/Classes/GameManagement/GameSettings/Genshin/RegistryClass/GraphicsData.cs @@ -0,0 +1,256 @@ +using CollapseLauncher.GameSettings.Genshin.Context; +using CollapseLauncher.GameSettings.Genshin.Enums; +using Hi3Helper; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text.Json; +using static Hi3Helper.Logger; + +namespace CollapseLauncher.GameSettings.Genshin +{ + internal class GraphicsData + { + #region Properties + // Generate the list of the FPSOption value and order by ascending it. + public static readonly FPSOption[] FPSOptionsList = Enum.GetValues().OrderBy(GetFPSOptionNumber).ToArray(); + // Generate the list of the FPS number to be displayed on FPS Combobox + public static readonly int[] FPSIndex = FPSOptionsList.Select(GetFPSOptionNumber).ToArray(); + + private static int GetFPSOptionNumber(FPSOption value) + { + // Get the string of the number by trimming the 'f' letter at the beginning + string fpsStrNum = value.ToString().TrimStart('f'); + // Try parse the fpsStrNum as a number + _ = int.TryParse(fpsStrNum, out int number); + // Return the number + return number; + } + + public static readonly decimal[] RenderScaleIndex = new decimal[] { 0.6m, 0.8m, 1.0m, 1.1m, 1.2m, 1.3m, 1.4m, 1.5m }; + public int currentVolatielGrade { get; set; } = -1; + public List> customVolatileGrades { get; set; } = new(); + public string volatileVersion { get; set; } = ""; + #endregion + + #region Settings + /// + /// This defines "FPS" combobox In-game settings.
+ /// Options: 30, 60, 45 + /// Default: 60 [1] + ///
+ public FPSOption FPS = FPSOption.f60; + + /// + /// This defines "Render Resolution" combobox In-game settings.
+ /// Options: 0.6, 0.8, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5 + /// Default: 1.0 [3] + ///
+ public RenderResolutionOption RenderResolution = RenderResolutionOption.x10; + + /// + /// This defines "Shadow Quality" combobox In-game settings.
+ /// Options: Lowest, Low, Medium, High + /// Default: High [4] + ///
+ public ShadowQualityOption ShadowQuality = ShadowQualityOption.High; + + /// + /// This defines "Visual Effects" combobox In-game settings.
+ /// Options: Lowest, Low, Medium, High + /// Default: High [4] + ///
+ public VisualEffectsOption VisualEffects = VisualEffectsOption.High; + + /// + /// This defines "SFX Quality" combobox In-game settings.
+ /// Options: Lowest, Low, Medium, High + /// Default: High [4] + ///
+ public SFXQualityOption SFXQuality = SFXQualityOption.High; + + /// + /// This defines "Environment Detail" combobox In-game settings.
+ /// Options: Lowest, Low, Medium, High, Highest + /// Default: High [4] + ///
+ public EnvironmentDetailOption EnvironmentDetail = EnvironmentDetailOption.High; + + /// + /// This defines "Vertical Sync" combobox In-game settings.
+ /// Options: Off, On + /// Default: On [2] + ///
+ public VerticalSyncOption VerticalSync = VerticalSyncOption.On; + + /// + /// This defines "Antialiasing" combobox In-game settings.
+ /// Options: Off, FSR 2, SMAA + /// Default: FSR 2 [2] + ///
+ public AntialiasingOption Antialiasing = AntialiasingOption.FSR2; + + /// + /// This defines "Volumetric Fog" combobox In-game settings.
+ /// Options: Off, On + /// Default: On [2] + /// Game prohibits enabling this if "Shadow Quality" on Low or Lowest + ///
+ public VolumetricFogOption VolumetricFog = VolumetricFogOption.On; + + /// + /// This defines "Reflections" combobox In-game settings.
+ /// Options: Off, On + /// Default: On [2] + ///
+ public ReflectionsOption Reflections = ReflectionsOption.On; + + /// + /// This defines "Motion Blur" combobox In-game settings.
+ /// Options: Off, Low, High, Extreme + /// Default: Extreme [4] + ///
+ public MotionBlurOption MotionBlur = MotionBlurOption.Extreme; + + /// + /// This defines "Bloom" combobox In-game settings.
+ /// Options: Off, On + /// Default: On [2] + ///
+ public BloomOption Bloom = BloomOption.On; + + /// + /// This defines "Crowd Density" combobox In-game settings.
+ /// Options: Low, High + /// Default: High [2] + ///
+ public CrowdDensityOption CrowdDensity = CrowdDensityOption.High; + + /// + /// This defines "Subsurface Scattering" combobox In-game settings.
+ /// Options: Off, Medium, High + /// Default: High [3] + ///
+ public SubsurfaceScatteringOption SubsurfaceScattering = SubsurfaceScatteringOption.High; + + /// + /// This defines "Co-Op Teammate Effects" combobox In-game settings.
+ /// Options: Off, Partially Off, On + /// Default: On [3] + ///
+ public CoOpTeammateEffectsOption CoOpTeammateEffects = CoOpTeammateEffectsOption.On; + + /// + /// This defines "Anisotropic Filtering" combobox In-game settings.
+ /// Options: 1x, 2x, 4x, 8x, 16x + /// Default: 8x [4] + ///
+ public AnisotropicFilteringOption AnisotropicFiltering = AnisotropicFilteringOption.x8; + #endregion + + #region Methods + public static GraphicsData Load(string graphicsJson) + { + GraphicsData graphics = (GraphicsData?)JsonSerializer.Deserialize(graphicsJson, typeof(GraphicsData), GraphicsDataContext.Default) ?? new GraphicsData(); + foreach (Dictionary setting in graphics.customVolatileGrades) + { + switch (setting["key"]) + { + case 1: + LogWriteLine($"Loaded Genshin Settings: Graphics - FPS: {setting["value"]}", LogType.Debug, true); + graphics.FPS = (FPSOption)setting["value"]; + break; + case 2: + LogWriteLine($"Loaded Genshin Settings: Graphics - Render Resolution: {setting["value"]}", LogType.Debug, true); + graphics.RenderResolution = (RenderResolutionOption)setting["value"]; + break; + case 3: + LogWriteLine($"Loaded Genshin Settings: Graphics - Shadow Quality: {setting["value"]}", LogType.Debug, true); + graphics.ShadowQuality = (ShadowQualityOption)setting["value"]; + break; + case 4: + LogWriteLine($"Loaded Genshin Settings: Graphics - Visual Effects: {setting["value"]}", LogType.Debug, true); + graphics.VisualEffects = (VisualEffectsOption)setting["value"]; + break; + case 5: + LogWriteLine($"Loaded Genshin Settings: Graphics - SFX Quality: {setting["value"]}", LogType.Debug, true); + graphics.SFXQuality = (SFXQualityOption)setting["value"]; + break; + case 6: + LogWriteLine($"Loaded Genshin Settings: Graphics - Environment Detail: {setting["value"]}", LogType.Debug, true); + graphics.EnvironmentDetail = (EnvironmentDetailOption)setting["value"]; + break; + case 7: + LogWriteLine($"Loaded Genshin Settings: Graphics - Vertical Sync: {setting["value"]}", LogType.Debug, true); + graphics.VerticalSync = (VerticalSyncOption)setting["value"]; + break; + case 8: + LogWriteLine($"Loaded Genshin Settings: Graphics - Antialiasing: {setting["value"]}", LogType.Debug, true); + graphics.Antialiasing = (AntialiasingOption)setting["value"]; + break; + case 9: + LogWriteLine($"Loaded Genshin Settings: Graphics - Volumetric Fog: {setting["value"]}", LogType.Debug, true); + graphics.VolumetricFog = (VolumetricFogOption)setting["value"]; + break; + case 10: + LogWriteLine($"Loaded Genshin Settings: Graphics - Reflections: {setting["value"]}", LogType.Debug, true); + graphics.Reflections = (ReflectionsOption)setting["value"]; + break; + case 11: + LogWriteLine($"Loaded Genshin Settings: Graphics - Motion Blur: {setting["value"]}", LogType.Debug, true); + graphics.MotionBlur = (MotionBlurOption)setting["value"]; + break; + case 12: + LogWriteLine($"Loaded Genshin Settings: Graphics - Bloom: {setting["value"]}", LogType.Debug, true); + graphics.Bloom = (BloomOption)setting["value"]; + break; + case 13: + LogWriteLine($"Loaded Genshin Settings: Graphics - Crowd Density: {setting["value"]}", LogType.Debug, true); + graphics.CrowdDensity = (CrowdDensityOption)setting["value"]; + break; + case 16: + LogWriteLine($"Loaded Genshin Settings: Graphics - Co-Op Teammate Effects: {setting["value"]}", LogType.Debug, true); + graphics.CoOpTeammateEffects = (CoOpTeammateEffectsOption)setting["value"]; + break; + /// 14 is missing from settings + case 15: + LogWriteLine($"Loaded Genshin Settings: Graphics - Subsurface Scattering: {setting["value"]}", LogType.Debug, true); + graphics.SubsurfaceScattering = (SubsurfaceScatteringOption)setting["value"]; + break; + case 17: + LogWriteLine($"Loaded Genshin Settings: Graphics - Anisotropic Filtering: {setting["value"]}", LogType.Debug, true); + graphics.AnisotropicFiltering = (AnisotropicFilteringOption)setting["value"]; + break; + } + } + return graphics; + } + + public string Save() + { + customVolatileGrades = new() + { + new Dictionary() { { "key", 1 }, { "value", (int)FPS } }, + new Dictionary() { { "key", 2 }, { "value", (int)RenderResolution } }, + new Dictionary() { { "key", 3 }, { "value", (int)ShadowQuality } }, + new Dictionary() { { "key", 4 }, { "value", (int)VisualEffects } }, + new Dictionary() { { "key", 5 }, { "value", (int)SFXQuality } }, + new Dictionary() { { "key", 6 }, { "value", (int)EnvironmentDetail } }, + new Dictionary() { { "key", 7 }, { "value", (int)VerticalSync } }, + new Dictionary() { { "key", 8 }, { "value", (int)Antialiasing } }, + new Dictionary() { { "key", 9 }, { "value", (int)VolumetricFog } }, + new Dictionary() { { "key", 10 }, { "value", (int)Reflections } }, + new Dictionary() { { "key", 11 }, { "value", (int)MotionBlur } }, + new Dictionary() { { "key", 12 }, { "value", (int)Bloom } }, + new Dictionary() { { "key", 13 }, { "value", (int)CrowdDensity } }, + new Dictionary() { { "key", 16 }, { "value", (int)CoOpTeammateEffects } }, + new Dictionary() { { "key", 15 }, { "value", (int)SubsurfaceScattering } }, + new Dictionary() { { "key", 17 }, { "value", (int)AnisotropicFiltering } }, + }; + string data = JsonSerializer.Serialize(this, typeof(GraphicsData), GraphicsDataContext.Default); + LogWriteLine($"Saved Genshin GraphicsData\r\n{data}", LogType.Debug, true); + return data; + } + #endregion + } +} diff --git a/CollapseLauncher/Classes/GameManagement/GameSettings/Genshin/RegistryClass/ScreenManager.cs b/CollapseLauncher/Classes/GameManagement/GameSettings/Genshin/RegistryClass/ScreenManager.cs new file mode 100644 index 000000000..ab4437353 --- /dev/null +++ b/CollapseLauncher/Classes/GameManagement/GameSettings/Genshin/RegistryClass/ScreenManager.cs @@ -0,0 +1,164 @@ +using CollapseLauncher.GameSettings.Base; +using CollapseLauncher.Interfaces; +using Hi3Helper; +using Hi3Helper.Screen; +using Microsoft.Win32; +using System; +using System.Drawing; +using static CollapseLauncher.GameSettings.Statics; +using static Hi3Helper.Logger; + +namespace CollapseLauncher.GameSettings.Genshin +{ + internal class ScreenManager : BaseScreenSettingData, IGameSettingsValue + { + #region Fields + private const string _ValueNameScreenManagerWidth = "Screenmanager Resolution Width_h182942802"; + private const string _ValueNameScreenManagerHeight = "Screenmanager Resolution Height_h2627697771"; + private const string _ValueNameScreenManagerFullscreen = "Screenmanager Is Fullscreen mode_h3981298716"; + private static Size currentRes = ScreenProp.currentResolution; + #endregion + + #region Properties + /// + /// This value references values from inner width and height.

+ /// Range: 64 x 64 - int.MaxValue x int.MaxValue
+ /// Default: Your screen resolution + ///
+ public override Size sizeRes + { + get => new Size(width, height); + set + { + width = value.Width < 64 ? currentRes.Width : value.Width; + height = value.Height < 64 ? currentRes.Height : value.Height; + } + } + + /// + /// This value references values from inner width and height as string.

+ /// Range: 64 x 64 - int.MaxValue x int.MaxValue
+ /// Default: Your screen resolution + ///
+ public override string sizeResString + { + get => $"{width}x{height}"; + set + { + string[] size = value.Split('x'); + int w; + int h; + if (!int.TryParse(size[0], out w) || !int.TryParse(size[1], out h)) + { + width = currentRes.Width; + height = currentRes.Height; + } + else + { + width = w; + height = h; + } + } + } + + /// + /// This defines "Game Resolution's Width" combobox In-game settings -> Video.

+ /// Range: 0 - int.MaxValue
+ /// Default: Your screen width + ///
+ public override int width { get; set; } = currentRes.Width; + + /// + /// This defines "Game Resolution's Height" combobox In-game settings -> Video.

+ /// Range: 0 - int.MaxValue
+ /// Default: Your screen Height + ///
+ public override int height { get; set; } = currentRes.Height; + + /// + /// This defines "Fullscreen" checkbox In-game settings -> Video.

+ /// Range: 0 - 1 + /// Default: 1 + ///
+ public int fullscreen { get; set; } = 1; + + public override bool isfullScreen + { + get => fullscreen switch + { + 1 => true, + _ => false, + }; + set => fullscreen = value switch + { + true => 1, + _ => 0, + }; + } + #endregion +#nullable enable + #region Methods + public static ScreenManager Load() + { + try + { + if (RegistryRoot == null) throw new NullReferenceException($"Cannot load {_ValueNameScreenManagerWidth} RegistryKey is unexpectedly not initialized!"); + if (RegistryRoot == null) throw new NullReferenceException($"Cannot load {_ValueNameScreenManagerHeight} RegistryKey is unexpectedly not initialized!"); + if (RegistryRoot == null) throw new NullReferenceException($"Cannot load {_ValueNameScreenManagerFullscreen} RegistryKey is unexpectedly not initialized!"); + + object? valueWidth = RegistryRoot.GetValue(_ValueNameScreenManagerWidth, null); + object? valueHeight = RegistryRoot.GetValue(_ValueNameScreenManagerHeight, null); + object? valueFullscreen = RegistryRoot.GetValue(_ValueNameScreenManagerFullscreen, null); + if (valueWidth != null && valueHeight != null && valueFullscreen != null) + { + int width = (int)valueWidth; + int height = (int)valueHeight; + int fullscreen = (int)valueFullscreen; + LogWriteLine($"Loaded Genshin Settings: {_ValueNameScreenManagerWidth} : {width}", LogType.Debug, true); + LogWriteLine($"Loaded Genshin Settings: {_ValueNameScreenManagerHeight} : {height}", LogType.Debug, true); + LogWriteLine($"Loaded Genshin Settings: {_ValueNameScreenManagerFullscreen} : {fullscreen}", LogType.Debug, true); + return new ScreenManager { width = width, height = height, fullscreen = fullscreen }; + } + } + catch (Exception ex) + { + LogWriteLine($"Failed while reading Genshin Impact ScreenManager Values\r\n{ex}", LogType.Error, true); + } + + return new ScreenManager(); + } + + public override void Save() + { + try + { + RegistryRoot?.SetValue(_ValueNameScreenManagerFullscreen, fullscreen, RegistryValueKind.DWord); + LogWriteLine($"Saved Genshin Settings: {_ValueNameScreenManagerFullscreen} : {RegistryRoot.GetValue(_ValueNameScreenManagerFullscreen, null)}", LogType.Debug, true); + + RegistryRoot?.SetValue(_ValueNameScreenManagerWidth, width, RegistryValueKind.DWord); + LogWriteLine($"Saved Genshin Settings: {_ValueNameScreenManagerWidth} : {RegistryRoot.GetValue(_ValueNameScreenManagerWidth, null)}", LogType.Debug, true); + + RegistryRoot?.SetValue(_ValueNameScreenManagerHeight, height, RegistryValueKind.DWord); + LogWriteLine($"Saved Genshin Settings: {_ValueNameScreenManagerHeight} : {RegistryRoot.GetValue(_ValueNameScreenManagerHeight, null)}", LogType.Debug, true); + } + catch (Exception ex) + { + LogWriteLine($"Failed to save Genshin Impact ScreenManager Values!\r\n{ex}", LogType.Error, true); + } + } + + public bool Equals(ScreenManager? comparedTo) + { + if (ReferenceEquals(this, comparedTo)) return true; + if (comparedTo == null) return false; + + return comparedTo.sizeRes == this.sizeRes && + comparedTo.height == this.height && + comparedTo.width == this.width && + comparedTo.fullscreen == this.fullscreen; + } + #endregion +#nullable disable + + } +} \ No newline at end of file diff --git a/CollapseLauncher/Classes/GameManagement/GameSettings/Genshin/Settings.cs b/CollapseLauncher/Classes/GameManagement/GameSettings/Genshin/Settings.cs index dd134d763..cba9d337f 100644 --- a/CollapseLauncher/Classes/GameManagement/GameSettings/Genshin/Settings.cs +++ b/CollapseLauncher/Classes/GameManagement/GameSettings/Genshin/Settings.cs @@ -1,4 +1,5 @@ using CollapseLauncher.GameSettings.Base; +using CollapseLauncher.GameSettings.Genshin; using CollapseLauncher.GameSettings.Universal; using CollapseLauncher.Interfaces; using CollapseLauncher.Statics; @@ -13,6 +14,7 @@ internal class GenshinSettings : ImportExportBase, IGameSettings, IGameSettingsU public CustomArgs SettingsCustomArgument { get; set; } public BaseScreenSettingData SettingsScreen { get; set; } public CollapseScreenSetting SettingsCollapseScreen { get; set; } + public GeneralData SettingsGeneralData { get; set; } public GenshinSettings() { @@ -34,6 +36,9 @@ private void InitializeSettings() { // Load Settings SettingsCustomArgument = CustomArgs.Load(); + SettingsCollapseScreen = CollapseScreenSetting.Load(); + SettingsScreen = ScreenManager.Load(); + SettingsGeneralData = GeneralData.Load(); } public void ReloadSettings() => InitializeSettings(); @@ -42,6 +47,9 @@ public void SaveSettings() { // Save Settings SettingsCustomArgument.Save(); + SettingsCollapseScreen.Save(); + SettingsScreen.Save(); + SettingsGeneralData.Save(); } public IGameSettingsUniversal AsIGameSettingsUniversal() => this; diff --git a/CollapseLauncher/XAMLs/MainApp/MainPage.xaml.cs b/CollapseLauncher/XAMLs/MainApp/MainPage.xaml.cs index 635d0ca77..06bfd3c57 100644 --- a/CollapseLauncher/XAMLs/MainApp/MainPage.xaml.cs +++ b/CollapseLauncher/XAMLs/MainApp/MainPage.xaml.cs @@ -905,6 +905,12 @@ private void InitializeNavigationItems() break; } + if (PageStatics._GameVersion.GameType == GameType.Genshin) + { + NavigationViewControl.MenuItems.Add(new NavigationViewItem() + { Content = Lang._GenshinGameSettingsPage.PageTitle, Icon = IconGameSettings, Tag = "genshingamesettings" }); + } + NavigationViewControl.SelectedItem = (NavigationViewItem)NavigationViewControl.MenuItems[0]; (NavigationViewControl.SettingsItem as NavigationViewItem).Content = Lang._SettingsPage.PageTitle; (NavigationViewControl.SettingsItem as NavigationViewItem).Icon = IconAppSettings; @@ -987,6 +993,10 @@ private void NavView_Navigate(NavigationViewItem item) case "starrailgamesettings": Navigate(IsGameInstalled() ? typeof(StarRailGameSettingsPage) : typeof(NotInstalledPage), true, item); break; + + case "genshingamesettings": + Navigate(IsGameInstalled() ? typeof(GenshinGameSettingsPage) : typeof(NotInstalledPage), true, item); + break; } LogWriteLine($"Page changed to {item.Content}", LogType.Scheme); } diff --git a/CollapseLauncher/XAMLs/MainApp/Pages/GenshinGameSettingsPage.Ext.cs b/CollapseLauncher/XAMLs/MainApp/Pages/GenshinGameSettingsPage.Ext.cs new file mode 100644 index 000000000..052f12b80 --- /dev/null +++ b/CollapseLauncher/XAMLs/MainApp/Pages/GenshinGameSettingsPage.Ext.cs @@ -0,0 +1,298 @@ +using CollapseLauncher.GameSettings.Genshin; +using CollapseLauncher.GameSettings.Genshin.Enums; +using Microsoft.UI.Xaml.Controls; +using System; +using System.Drawing; + +namespace CollapseLauncher.Pages +{ + public sealed partial class GenshinGameSettingsPage : Page + { + #region GameResolution + public bool IsFullscreenEnabled + { + get => Settings.SettingsScreen.isfullScreen; + set + { + Settings.SettingsScreen.isfullScreen = value; + if (value) + { + GameResolutionFullscreenExclusive.IsEnabled = !IsCustomResolutionEnabled; + return; + } + GameResolutionFullscreenExclusive.IsEnabled = false; + GameResolutionFullscreenExclusive.IsChecked = false; + } + } + + public bool IsCustomResolutionEnabled + { + get => Settings.SettingsCollapseScreen.UseCustomResolution; + set + { + Settings.SettingsCollapseScreen.UseCustomResolution = value; + if (value) + { + GameResolutionFullscreenExclusive.IsEnabled = false; + GameResolutionSelector.IsEnabled = false; + GameCustomResolutionWidth.IsEnabled = true; + GameCustomResolutionHeight.IsEnabled = true; + + string[] _size = ResolutionSelected.Split('x'); + GameCustomResolutionWidth.Value = int.Parse(_size[0]); + GameCustomResolutionHeight.Value = int.Parse(_size[1]); + + return; + } + GameCustomResolutionWidth.IsEnabled = false; + GameCustomResolutionHeight.IsEnabled = false; + GameResolutionFullscreenExclusive.IsEnabled = IsFullscreenEnabled; + GameResolutionSelector.IsEnabled = true; + + Size size = Hi3Helper.Screen.ScreenProp.GetScreenSize(); + GameResolutionSelector.SelectedItem = $"{size.Width}x{size.Height}"; + } + } + + public bool IsCanExclusiveFullscreen + { + get => !(!IsFullscreenEnabled || IsCustomResolutionEnabled); + } + + public bool IsExclusiveFullscreenEnabled + { + get + { + if (!IsFullscreenEnabled) + { + return false; + } + return Settings.SettingsCollapseScreen.UseExclusiveFullscreen; + } + set + { + Settings.SettingsCollapseScreen.UseExclusiveFullscreen = value; + if (value) + { + GameCustomResolutionCheckbox.IsEnabled = false; + GameCustomResolutionCheckbox.IsChecked = false; + GameCustomResolutionWidth.IsEnabled = false; + GameCustomResolutionHeight.IsEnabled = false; + return; + } + GameCustomResolutionCheckbox.IsEnabled = true; + } + } + + public int ResolutionW + { + get => Settings.SettingsScreen.sizeRes.Width; + set => Settings.SettingsScreen.sizeRes = new Size(value, ResolutionH); + } + + public int ResolutionH + { + get => Settings.SettingsScreen.sizeRes.Height; + set => Settings.SettingsScreen.sizeRes = new Size(ResolutionW, value); + } + + public bool IsCanResolutionWH + { + get => IsCustomResolutionEnabled; + } + + public string ResolutionSelected + { + get + { + string res = Settings.SettingsScreen.sizeResString; + if (string.IsNullOrEmpty(res)) + { + Size size = Hi3Helper.Screen.ScreenProp.GetScreenSize(); + return $"{size.Width}x{size.Height}"; + } + return res; + } + set => Settings.SettingsScreen.sizeResString = value; + } + + #endregion + + #region Graphics Settings + public double Gamma + { + get => (double)Math.Round(Settings.SettingsGeneralData.gammaValue*-1+4.4, 5); + set => Settings.SettingsGeneralData.gammaValue = Math.Round(value*-1+4.4, 5); + // This should belong in programmer horror stories, *DO NOT EVER DO THIS* + // Basically, calculate the stepper function which amounts to y = -x + 4.4, so we inverse the value and add 4.4 + // DON'T ASK HOW WE DID THIS, IT'S a 4AM THING :) + // Round it to x.xxxxx because floating point + } + + public bool VerticalSync + { + get => Convert.ToBoolean((int)Settings.SettingsGeneralData.graphicsData.VerticalSync - 1); + set => Settings.SettingsGeneralData.graphicsData.VerticalSync = (VerticalSyncOption)(Convert.ToInt32(value) + 1); + } + + public bool VolumetricFog + { + get => Convert.ToBoolean((int)Settings.SettingsGeneralData.graphicsData.VolumetricFog - 1); + set => Settings.SettingsGeneralData.graphicsData.VolumetricFog = (VolumetricFogOption)(Convert.ToInt32(value) + 1); + } + + public bool Reflections + { + get => Convert.ToBoolean((int)Settings.SettingsGeneralData.graphicsData.Reflections - 1); + set => Settings.SettingsGeneralData.graphicsData.Reflections = (ReflectionsOption)(Convert.ToInt32(value) + 1); + } + + public bool Bloom + { + get => Convert.ToBoolean((int)Settings.SettingsGeneralData.graphicsData.Bloom - 1); + set => Settings.SettingsGeneralData.graphicsData.Bloom = (BloomOption)(Convert.ToInt32(value) + 1); + } + + public int FPS + { + get + { + // Get the current value + FPSOption curValue = Settings.SettingsGeneralData.graphicsData.FPS; + // Get the index of the current value in FPSOptionsList array + int indexOfValue = Array.IndexOf(GraphicsData.FPSOptionsList, curValue); + // Return the index of the value + return indexOfValue; + } + set + { + // [HACK]: Fix some rare occasion where the "value" turned into -1. If so, then return + if (value < 0) return; + + // Get the FPSOption based on the selected index by the "value" + FPSOption valueFromIndex = GraphicsData.FPSOptionsList[value]; + // Set the actual value to its property + Settings.SettingsGeneralData.graphicsData.FPS = valueFromIndex; + } + } + + public int RenderScale + { + get => (int)Settings.SettingsGeneralData.graphicsData.RenderResolution - 1; + set => Settings.SettingsGeneralData.graphicsData.RenderResolution = (RenderResolutionOption)(value + 1); + } + + public int ShadowQuality + { + get => (int)Settings.SettingsGeneralData.graphicsData.ShadowQuality - 1; + set => Settings.SettingsGeneralData.graphicsData.ShadowQuality = (ShadowQualityOption)(value + 1); + } + + public int VisualEffects + { + get => (int)Settings.SettingsGeneralData.graphicsData.VisualEffects - 1; + set => Settings.SettingsGeneralData.graphicsData.VisualEffects = (VisualEffectsOption)(value + 1); + } + + public int SFXQuality + { + get => (int)Settings.SettingsGeneralData.graphicsData.SFXQuality - 1; + set => Settings.SettingsGeneralData.graphicsData.SFXQuality = (SFXQualityOption)(value + 1); + } + + public int EnvironmentDetail + { + get => (int)Settings.SettingsGeneralData.graphicsData.EnvironmentDetail - 1; + set => Settings.SettingsGeneralData.graphicsData.EnvironmentDetail = (EnvironmentDetailOption)(value + 1); + } + + public int MotionBlur + { + get => (int)Settings.SettingsGeneralData.graphicsData.MotionBlur - 1; + set => Settings.SettingsGeneralData.graphicsData.MotionBlur = (MotionBlurOption)(value + 1); + } + + public int CrowdDensity + { + get => (int)Settings.SettingsGeneralData.graphicsData.CrowdDensity - 1; + set => Settings.SettingsGeneralData.graphicsData.CrowdDensity = (CrowdDensityOption)(value + 1); + } + + public int SubsurfaceScattering + { + get => (int)Settings.SettingsGeneralData.graphicsData.SubsurfaceScattering - 1; + set => Settings.SettingsGeneralData.graphicsData.SubsurfaceScattering = (SubsurfaceScatteringOption)(value + 1); + } + + public int CoOpTeammateEffects + { + get => (int)Settings.SettingsGeneralData.graphicsData.CoOpTeammateEffects - 1; + set => Settings.SettingsGeneralData.graphicsData.CoOpTeammateEffects = (CoOpTeammateEffectsOption)(value + 1); + } + + public int AnisotropicFiltering + { + get => (int)Settings.SettingsGeneralData.graphicsData.AnisotropicFiltering - 1; + set => Settings.SettingsGeneralData.graphicsData.AnisotropicFiltering = (AnisotropicFilteringOption)(value + 1); + } + + public int Antialiasing + { + get => (int)Settings.SettingsGeneralData.graphicsData.Antialiasing - 1; + set => Settings.SettingsGeneralData.graphicsData.Antialiasing = (AntialiasingOption)(value + 1); + } + #endregion + + #region Audio + public int Audio_Global + { + get => (int)Settings.SettingsGeneralData.volumeGlobal; + set => Settings.SettingsGeneralData.volumeGlobal = value; + } + + public int Audio_SFX + { + get => (int)Settings.SettingsGeneralData.volumeSFX; + set => Settings.SettingsGeneralData.volumeSFX = value; + } + + public int Audio_Music + { + get => (int)Settings.SettingsGeneralData.volumeMusic; + set => Settings.SettingsGeneralData.volumeMusic = value; + } + + public int Audio_Voice + { + get => (int)Settings.SettingsGeneralData.volumeVoice; + set => Settings.SettingsGeneralData.volumeVoice = value; + } + + public bool Audio_DynamicRange + { + get => !Convert.ToBoolean((int)Settings.SettingsGeneralData.audioDynamicRange); + set => Settings.SettingsGeneralData.audioDynamicRange = Convert.ToInt32(!value); + } + + public bool Audio_Surround + { + get => Convert.ToBoolean((int)Settings.SettingsGeneralData.audioOutput); + set => Settings.SettingsGeneralData.audioOutput = Convert.ToInt32(value); + } + #endregion + + #region Language + public int AudioLang + { + get => (int)Settings.SettingsGeneralData.deviceVoiceLanguageType; + set => Settings.SettingsGeneralData.deviceVoiceLanguageType = value; + } + + public int TextLang + { + get => (int)Settings.SettingsGeneralData.deviceLanguageType - 1; + set => Settings.SettingsGeneralData.deviceLanguageType = value + 1; + } + #endregion + } +} diff --git a/CollapseLauncher/XAMLs/MainApp/Pages/GenshinGameSettingsPage.xaml b/CollapseLauncher/XAMLs/MainApp/Pages/GenshinGameSettingsPage.xaml new file mode 100644 index 000000000..882b999fd --- /dev/null +++ b/CollapseLauncher/XAMLs/MainApp/Pages/GenshinGameSettingsPage.xaml @@ -0,0 +1,435 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/CollapseLauncher/XAMLs/MainApp/Pages/GenshinGameSettingsPage.xaml.cs b/CollapseLauncher/XAMLs/MainApp/Pages/GenshinGameSettingsPage.xaml.cs new file mode 100644 index 000000000..5b502b536 --- /dev/null +++ b/CollapseLauncher/XAMLs/MainApp/Pages/GenshinGameSettingsPage.xaml.cs @@ -0,0 +1,205 @@ +using CollapseLauncher.GameSettings.Genshin; +using CollapseLauncher.Interfaces; +using CollapseLauncher.Statics; +#if !DISABLEDISCORD +using Hi3Helper.DiscordPresence; +#endif +using Hi3Helper.Shared.ClassStruct; +using Microsoft.UI.Xaml; +using Microsoft.UI.Xaml.Controls; +using Microsoft.UI.Xaml.Media; +using Microsoft.UI.Xaml.Navigation; +using Microsoft.Win32; +using RegistryUtils; +using System; +using System.IO; +using static Hi3Helper.Locale; +using static Hi3Helper.Logger; +using static Hi3Helper.Shared.Region.LauncherConfig; +using static CollapseLauncher.GameSettings.Statics; +using Hi3Helper; +using Microsoft.UI.Xaml.Controls.Primitives; +using Microsoft.UI.Xaml.Data; +using Windows.Globalization.NumberFormatting; + +namespace CollapseLauncher.Pages +{ + public partial class GenshinGameSettingsPage : Page + { + private GenshinSettings Settings { get => (GenshinSettings)PageStatics._GameSettings; } + private Brush InheritApplyTextColor { get; set; } + private RegistryMonitor RegistryWatcher { get; set; } + private bool IsNoReload = false; + public GenshinGameSettingsPage() + { + try + { + DispatcherQueue.TryEnqueue(() => + { + RegistryWatcher = new RegistryMonitor(RegistryHive.CurrentUser, Path.Combine(RegistryRootPath, PageStatics._GameVersion.GamePreset.InternalGameNameInConfig)); + RegistryWatcher.RegChanged += RegistryListener; + RegistryWatcher.Start(); + + }); + + LoadPage(); + } + catch (Exception ex) + { + LogWriteLine($"{ex}", LogType.Error, true); + ErrorSender.SendException(ex); + } + } + + private void RegistryListener(object sender, EventArgs e) + { + if (!IsNoReload) + { + LogWriteLine("Module: RegistryMonitor has detected registry change outside of the launcher! Reloading the page...", LogType.Warning, true); + DispatcherQueue.TryEnqueue(MainFrameChanger.ReloadCurrentMainFrame); + } + } + + private void LoadPage() + { + Settings.ReloadSettings(); + + this.InitializeComponent(); + this.NavigationCacheMode = NavigationCacheMode.Disabled; + ApplyButton.Translation = Shadow32; + GameSettingsApplyGrid.Translation = new System.Numerics.Vector3(0, 0, 64); + + InheritApplyTextColor = ApplyText.Foreground; + } + + private void RegistryExportClick(object sender, RoutedEventArgs e) + { + try + { + Exception exc = Settings.ExportSettings(); + + if (exc != null) throw exc; + + ApplyText.Foreground = InheritApplyTextColor; + ApplyText.Text = Lang._GameSettingsPage.SettingsRegExported; + ApplyText.Visibility = Visibility.Visible; + } + catch (Exception ex) + { + LogWriteLine($"Error has occurred while exporting registry!\r\n{ex}", LogType.Error, true); + ApplyText.Foreground = new SolidColorBrush(new Windows.UI.Color { A = 255, R = 255, B = 0, G = 0 }); + ApplyText.Text = ex.Message; + ApplyText.Visibility = Visibility.Visible; + } + } + + private void RegistryImportClick(object sender, RoutedEventArgs e) + { + try + { + Exception exc = Settings.ImportSettings(); + + if (exc != null) throw exc; + + ApplyText.Foreground = InheritApplyTextColor; + ApplyText.Text = Lang._GameSettingsPage.SettingsRegImported; + ApplyText.Visibility = Visibility.Visible; + } + catch (Exception ex) + { + LogWriteLine($"Error has occurred while importing registry!\r\n{ex}", LogType.Error, true); + ApplyText.Foreground = new SolidColorBrush(new Windows.UI.Color { A = 255, R = 255, B = 0, G = 0 }); + ApplyText.Text = ex.Message; + ApplyText.Visibility = Visibility.Visible; + } + } + + private void InitializeSettings(object sender, RoutedEventArgs e) + { + try + { + GameResolutionSelector.ItemsSource = ScreenResolutionsList; + + if (App.IsGameRunning) + { + Overlay.Visibility = Visibility.Visible; + PageContent.Visibility = Visibility.Collapsed; + OverlayTitle.Text = Lang._StarRailGameSettingsPage.OverlayGameRunningTitle; + OverlaySubtitle.Text = Lang._StarRailGameSettingsPage.OverlayGameRunningSubtitle; + + return; + } + else if (GameInstallationState == GameInstallStateEnum.NotInstalled + || GameInstallationState == GameInstallStateEnum.NeedsUpdate + || GameInstallationState == GameInstallStateEnum.GameBroken) + { + Overlay.Visibility = Visibility.Visible; + PageContent.Visibility = Visibility.Collapsed; + OverlayTitle.Text = Lang._StarRailGameSettingsPage.OverlayNotInstalledTitle; + OverlaySubtitle.Text = Lang._StarRailGameSettingsPage.OverlayNotInstalledSubtitle; + + return; + } +#if !DISABLEDISCORD + AppDiscordPresence.SetActivity(ActivityType.GameSettings); +#endif + } + catch (Exception ex) + { + LogWriteLine($"FATAL ERROR!!!\r\n{ex}", LogType.Error, true); + ErrorSender.SendException(ex); + } + } + + private void ApplyButton_Click(object sender, RoutedEventArgs e) + { + try + { + ApplyText.Foreground = InheritApplyTextColor; + ApplyText.Text = Lang._StarRailGameSettingsPage.SettingsApplied; + ApplyText.Visibility = Visibility.Visible; + + Settings.SaveSettings(); + IsNoReload = true; + } + catch (Exception ex) + { + LogWriteLine($"{ex}", Hi3Helper.LogType.Error, true); + ErrorSender.SendException(ex); + } + } + + private void OnUnload(object sender, RoutedEventArgs e) + { + DispatcherQueue.TryEnqueue(() => + { + RegistryWatcher.Stop(); + RegistryWatcher.Dispose(); + }); + } + + private void GammaValue_ValueChanged(NumberBox sender, NumberBoxValueChangedEventArgs args) + { + IncrementNumberRounder rounder = new IncrementNumberRounder(); + rounder.Increment = 0.0000001; + + DecimalFormatter formatter = new DecimalFormatter(); + formatter.IntegerDigits = 1; + formatter.FractionDigits = 5; + formatter.NumberRounder = rounder; + + GammaValue.NumberFormatter = formatter; + } + + private void GammaSlider_ValueChanged(object sender, RangeBaseValueChangedEventArgs e) + { + GammaValue.Value = Math.Round(e.NewValue, 5); + } + + public string CustomArgsValue + { + get => ((IGameSettingsUniversal)PageStatics._GameSettings).SettingsCustomArgument.CustomArgumentValue; + set => ((IGameSettingsUniversal)PageStatics._GameSettings).SettingsCustomArgument.CustomArgumentValue = value; + } + } +} diff --git a/CollapseLauncher/XAMLs/MainApp/Pages/HomePage.xaml.cs b/CollapseLauncher/XAMLs/MainApp/Pages/HomePage.xaml.cs index ed6557bd5..176c9e4a3 100644 --- a/CollapseLauncher/XAMLs/MainApp/Pages/HomePage.xaml.cs +++ b/CollapseLauncher/XAMLs/MainApp/Pages/HomePage.xaml.cs @@ -934,7 +934,30 @@ public string GetLaunchArguments() else parameter.AppendFormat("-screen-width {0} -screen-height {1} ", screenSize.Width, screenSize.Height); } + if (PageStatics._GameVersion.GameType == GameType.Genshin) + { + if (_Settings.SettingsCollapseScreen.UseExclusiveFullscreen) + { + parameter.Append("-window-mode exclusive -screen-fullscreen 1 "); + RequireWindowExclusivePayload = true; + LogWriteLine($"Exclusive mode is enabled in Genshin Impact, stability may suffer!\r\nTry not to Alt+Tab when game is on its loading screen :)", LogType.Warning, true); + } + System.Drawing.Size screenSize = _Settings.SettingsScreen.sizeRes; + + byte apiID = _Settings.SettingsCollapseScreen.GameGraphicsAPI; + + if (apiID == 4) + { + LogWriteLine($"You are going to use DX12 mode in your game.\r\n\tUsing CustomScreenResolution or FullscreenExclusive value may break the game!", LogType.Warning); + if (_Settings.SettingsCollapseScreen.UseCustomResolution && _Settings.SettingsScreen.isfullScreen) + parameter.AppendFormat("-screen-width {0} -screen-height {1} ", ScreenProp.GetScreenSize().Width, ScreenProp.GetScreenSize().Height); + else + parameter.AppendFormat("-screen-width {0} -screen-height {1} ", screenSize.Width, screenSize.Height); + } + else + parameter.AppendFormat("-screen-width {0} -screen-height {1} ", screenSize.Width, screenSize.Height); + } string customArgs = _Settings.SettingsCustomArgument.CustomArgumentValue; if (!string.IsNullOrEmpty(customArgs)) diff --git a/CollapseLauncher/XAMLs/MainApp/Pages/StarRailGameSettingsPage.xaml b/CollapseLauncher/XAMLs/MainApp/Pages/StarRailGameSettingsPage.xaml index ab6baaca7..eda98dff4 100644 --- a/CollapseLauncher/XAMLs/MainApp/Pages/StarRailGameSettingsPage.xaml +++ b/CollapseLauncher/XAMLs/MainApp/Pages/StarRailGameSettingsPage.xaml @@ -35,9 +35,13 @@ + diff --git a/Hi3Helper.Core/Lang/Locale/LangGenshinGameSettingsPage.cs b/Hi3Helper.Core/Lang/Locale/LangGenshinGameSettingsPage.cs new file mode 100644 index 000000000..7b4b59ae1 --- /dev/null +++ b/Hi3Helper.Core/Lang/Locale/LangGenshinGameSettingsPage.cs @@ -0,0 +1,104 @@ +namespace Hi3Helper +{ + public sealed partial class Locale + { + #region GenshinGameSettingsPage + public sealed partial class LocalizationParams + { + public LangGenshinGameSettingsPage _GenshinGameSettingsPage { get; set; } = LangFallback?._GenshinGameSettingsPage; + public sealed class LangGenshinGameSettingsPage + { + public string PageTitle { get; set; } = LangFallback?._GenshinGameSettingsPage.PageTitle; + #region Overlay + public string OverlayNotInstalledTitle { get; set; } = LangFallback?._GenshinGameSettingsPage.OverlayNotInstalledTitle; + public string OverlayNotInstalledSubtitle { get; set; } = LangFallback?._GenshinGameSettingsPage.OverlayNotInstalledSubtitle; + public string OverlayGameRunningTitle { get; set; } = LangFallback?._GenshinGameSettingsPage.OverlayGameRunningTitle; + public string OverlayGameRunningSubtitle { get; set; } = LangFallback?._GenshinGameSettingsPage.OverlayGameRunningSubtitle; + public string OverlayFirstTimeTitle { get; set; } = LangFallback?._GenshinGameSettingsPage.OverlayFirstTimeTitle; + public string OverlayFirstTimeSubtitle { get; set; } = LangFallback?._GenshinGameSettingsPage.OverlayFirstTimeSubtitle; + #endregion + + #region CustomArgs + public string CustomArgs_Title { get; set; } = LangFallback?._GenshinGameSettingsPage.CustomArgs_Title; + public string CustomArgs_Subtitle { get; set; } = LangFallback?._GenshinGameSettingsPage.CustomArgs_Subtitle; + public string CustomArgs_Footer1 { get; set; } = LangFallback?._GenshinGameSettingsPage.CustomArgs_Footer1; + public string CustomArgs_Footer2 { get; set; } = LangFallback?._GenshinGameSettingsPage.CustomArgs_Footer2; + public string CustomArgs_Footer3 { get; set; } = LangFallback?._GenshinGameSettingsPage.CustomArgs_Footer3; + #endregion + + #region Misc + public string ApplyBtn { get; set; } = LangFallback?._GenshinGameSettingsPage.ApplyBtn; + public string SettingsApplied { get; set; } = LangFallback?._GenshinGameSettingsPage.SettingsApplied; + #endregion + + #region Audio + public string Audio_Title { get; set; } = LangFallback?._GenshinGameSettingsPage.Audio_Title; + + public string Audio_Master { get; set; } = LangFallback?._GenshinGameSettingsPage.Audio_Master; + public string Audio_BGM { get; set; } = LangFallback?._GenshinGameSettingsPage.Audio_BGM; + public string Audio_SFX { get; set; } = LangFallback?._GenshinGameSettingsPage.Audio_SFX; + public string Audio_VO { get; set; } = LangFallback?._GenshinGameSettingsPage.Audio_VO; + + public string Audio_Output_Surround { get; set; } = LangFallback?._GenshinGameSettingsPage.Audio_Output_Surround; + public string Audio_DynamicRange { get; set; } = LangFallback?._GenshinGameSettingsPage.Audio_DynamicRange; + #endregion + + #region Graphics + public string Graphics_Title { get; set; } = LangFallback?._GenshinGameSettingsPage.Graphics_Title; + + public string Graphics_ResolutionPanel { get; set; } = LangFallback?._GenshinGameSettingsPage.Graphics_ResolutionPanel; + public string Graphics_SpecPanel { get; set; } = LangFallback?._GenshinGameSettingsPage.Graphics_SpecPanel; + public string Graphics_Fullscreen { get; set; } = LangFallback?._GenshinGameSettingsPage.Graphics_Fullscreen; + public string Graphics_ExclusiveFullscreen { get; set; } = LangFallback?._GenshinGameSettingsPage.Graphics_ExclusiveFullscreen; + public string Graphics_ExclusiveFullscreen_Help { get; set; } = LangFallback?._GenshinGameSettingsPage.Graphics_ExclusiveFullscreen_Help; + public string Graphics_ResSelectPlaceholder { get; set; } = LangFallback?._GenshinGameSettingsPage.Graphics_ResSelectPlaceholder; + public string Graphics_ResCustom { get; set; } = LangFallback?._GenshinGameSettingsPage.Graphics_ResCustom; + public string Graphics_ResCustomW { get; set; } = LangFallback?._GenshinGameSettingsPage.Graphics_ResCustomW; + public string Graphics_ResCustomH { get; set; } = LangFallback?._GenshinGameSettingsPage.Graphics_ResCustomH; + + public string Graphics_Gamma { get; set; } = LangFallback?._GenshinGameSettingsPage.Graphics_Gamma; + public string Graphics_FPS { get; set; } = LangFallback?._GenshinGameSettingsPage.Graphics_FPS; + public string Graphics_RenderScale { get; set; } = LangFallback?._GenshinGameSettingsPage.Graphics_RenderScale; + public string Graphics_ShadowQuality { get; set; } = LangFallback?._GenshinGameSettingsPage.Graphics_ShadowQuality; + public string Graphics_VisualFX { get; set; } = LangFallback?._GenshinGameSettingsPage.Graphics_VisualFX; + public string Graphics_SFXQuality { get; set; } = LangFallback?._GenshinGameSettingsPage.Graphics_SFXQuality; + public string Graphics_EnvDetailQuality { get; set; } = LangFallback?._GenshinGameSettingsPage.Graphics_EnvDetailQuality; + public string Graphics_VSync { get; set; } = LangFallback?._GenshinGameSettingsPage.Graphics_VSync; + public string Graphics_AAMode { get; set; } = LangFallback?._GenshinGameSettingsPage.Graphics_AAMode; + public string Graphics_VolFogs { get; set; } = LangFallback?._GenshinGameSettingsPage.Graphics_VolFogs; + public string Graphics_ReflectionQuality { get; set; } = LangFallback?._GenshinGameSettingsPage.Graphics_ReflectionQuality; + public string Graphics_MotionBlur { get; set; } = LangFallback?._GenshinGameSettingsPage.Graphics_MotionBlur; + public string Graphics_BloomQuality { get; set; } = LangFallback?._GenshinGameSettingsPage.Graphics_BloomQuality; + public string Graphics_CrowdDensity { get; set; } = LangFallback?._GenshinGameSettingsPage.Graphics_CrowdDensity; + public string Graphics_SubsurfaceScattering { get; set; } = LangFallback?._GenshinGameSettingsPage.Graphics_SubsurfaceScattering; + public string Graphics_TeammateFX { get; set; } = LangFallback?._GenshinGameSettingsPage.Graphics_TeammateFX; + public string Graphics_AnisotropicFiltering { get; set; } = LangFallback?._GenshinGameSettingsPage.Graphics_AnisotropicFiltering; + #endregion + + #region Specs + public string SpecEnabled { get; set; } = LangFallback?._GenshinGameSettingsPage.SpecEnabled; + public string SpecDisabled { get; set; } = LangFallback?._GenshinGameSettingsPage.SpecDisabled; + public string SpecVeryLow { get; set; } = LangFallback?._GenshinGameSettingsPage.SpecVeryLow; + public string SpecLow { get; set; } = LangFallback?._GenshinGameSettingsPage.SpecLow; + public string SpecMedium { get; set; } = LangFallback?._GenshinGameSettingsPage.SpecMedium; + public string SpecHigh { get; set; } = LangFallback?._GenshinGameSettingsPage.SpecHigh; + public string SpecVeryHigh { get; set; } = LangFallback?._GenshinGameSettingsPage.SpecVeryHigh; + public string SpecPartiallyOff { get; set; } = LangFallback?._GenshinGameSettingsPage.SpecPartiallyOff; + #endregion + + #region Language + public string Language { get; set; } = LangFallback?._GenshinGameSettingsPage.Language; + public string Language_Help1 { get; set; } = LangFallback?._GenshinGameSettingsPage.Language_Help1; + public string Language_Help2 { get; set; } = LangFallback?._GenshinGameSettingsPage.Language_Help2; + public string LanguageAudio { get; set; } = LangFallback?._GenshinGameSettingsPage.LanguageAudio; + public string LanguageText { get; set; } = LangFallback?._GenshinGameSettingsPage.LanguageText; + public string VO_en { get; set; } = LangFallback?._GenshinGameSettingsPage.VO_en; + public string VO_cn { get; set; } = LangFallback?._GenshinGameSettingsPage.VO_cn; + public string VO_jp { get; set; } = LangFallback?._GenshinGameSettingsPage.VO_jp; + public string VO_kr { get; set; } = LangFallback?._GenshinGameSettingsPage.VO_kr; + #endregion + } + } + #endregion + } +} \ No newline at end of file diff --git a/Hi3Helper.Core/Lang/en-us.json b/Hi3Helper.Core/Lang/en-us.json index a46734e0d..7ea9a4011 100644 --- a/Hi3Helper.Core/Lang/en-us.json +++ b/Hi3Helper.Core/Lang/en-us.json @@ -745,6 +745,83 @@ "Audio_VO": "Voice Over Volume", "Audio_Mute": "Mute Audio", + "Language": "Language Settings", + "Language_Help1": "Collapse currently cannot download Audio package directly.", + "Language_Help2": "Audio package will be downloaded in-game next time you launch the game.", + "LanguageAudio": "Audio", + "LanguageText": "Text", + "VO_en": "English", + "VO_cn": "Chinese", + "VO_jp": "Japanese", + "VO_kr": "Korean" + }, + + "_GenshinGameSettingsPage": { + "PageTitle": "Game Settings", + + "Graphics_Title": "Graphics Settings", + "Graphics_ResolutionPanel": "Game Resolution", + "Graphics_Fullscreen": "Fullscreen", + "Graphics_ExclusiveFullscreen": "Use Exclusive Fullscreen", + "Graphics_ExclusiveFullscreen_Help": "Exclusive Fullscreen might cause random game freezes!", + "Graphics_ResSelectPlaceholder": "Select", + "Graphics_ResCustom": "Use Custom Resolution", + "Graphics_ResCustomW": "W", + "Graphics_ResCustomH": "H", + + "Graphics_Gamma": "Gamma", + "Graphics_FPS": "FPS", + "Graphics_RenderScale": "Render Scale", + "Graphics_ShadowQuality": "Shadow Quality", + "Graphics_VisualFX": "Visual Effects", + "Graphics_SFXQuality": "SFX Quality", + "Graphics_EnvDetailQuality": "Environment Detail", + "Graphics_VSync": "VSync", + "Graphics_AAMode": "Anti-Aliasing Mode", + "Graphics_VolFogs": "Volumetric Fogs", + "Graphics_ReflectionQuality": "Reflection", + "Graphics_MotionBlur": "Motion Blur", + "Graphics_BloomQuality": "Bloom", + "Graphics_CrowdDensity": "Crowd Density", + "Graphics_SubsurfaceScattering": "Subsurface Scattering", + "Graphics_TeammateFX": "Teammate Effects", + "Graphics_AnisotropicFiltering": "Anisotropic Filtering", + + "Graphics_SpecPanel": "Global Graphics Settings", + "SpecEnabled": "Enabled", + "SpecDisabled": "Disabled", + "SpecVeryLow": "Very Low", + "SpecLow": "Low", + "SpecMedium": "Medium", + "SpecHigh": "High", + "SpecVeryHigh": "Very High", + "SpecPartiallyOff": "Partially Off", + + "ApplyBtn": "Apply Settings", + "SettingsApplied": "Changes have been saved!", + + "OverlayNotInstalledTitle": "You cannot use this feature as the region isn't installed or needs to be updated!", + "OverlayNotInstalledSubtitle": "Please download/update the game first on the game's launcher page!", + "OverlayGameRunningTitle": "Game is Currently Running!", + "OverlayGameRunningSubtitle": "Please close the game first to use this feature!", + "OverlayFirstTimeTitle": "You have never played this game before!", + "OverlayFirstTimeSubtitle": "Please run the game first to generate the necessary files, then come back here to use this feature.", + + "CustomArgs_Title": "Custom Start-up Arguments (Advanced)", + "CustomArgs_Subtitle": "Start-up Arguments", + "CustomArgs_Footer1": "For more information about the Start-up Argument, please check the", + "CustomArgs_Footer2": "Unity Standalone Player command line documentation", + "CustomArgs_Footer3": "to see more parameters.", + + "Audio_Title": "Audio Settings", + "Audio_Master": "Master Volume", + "Audio_BGM": "BGM Volume", + "Audio_SFX": "Sound Effects Volume", + "Audio_VO": "Voice Over Volume", + + "Audio_Output_Surround": "Surround", + "Audio_DynamicRange": "Dynamic Range", + "Language": "Language Settings", "Language_Help1": "Collapse currently cannot download Audio package directly.", "Language_Help2": "Audio package will be downloaded in-game next time you launch the game.",