mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-12 18:27:23 +01:00
Add GameConfig service
This commit is contained in:
parent
03f33adbce
commit
1f262ce7d5
11 changed files with 6879 additions and 0 deletions
19
Dalamud/Game/Config/ConfigOptionNotFoundException.cs
Normal file
19
Dalamud/Game/Config/ConfigOptionNotFoundException.cs
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
using System;
|
||||
|
||||
namespace Dalamud.Game.Config;
|
||||
|
||||
/// <summary>
|
||||
/// An exception thrown when a matching config option is not present in the config section.
|
||||
/// </summary>
|
||||
public class ConfigOptionNotFoundException : Exception
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ConfigOptionNotFoundException"/> class.
|
||||
/// </summary>
|
||||
/// <param name="sectionName">Name of the section being accessed.</param>
|
||||
/// <param name="configOptionName">Name of the config option that was not found.</param>
|
||||
public ConfigOptionNotFoundException(string sectionName, string configOptionName)
|
||||
: base($"The option '{configOptionName}' is not available in {sectionName}.")
|
||||
{
|
||||
}
|
||||
}
|
||||
261
Dalamud/Game/Config/GameConfig.cs
Normal file
261
Dalamud/Game/Config/GameConfig.cs
Normal file
|
|
@ -0,0 +1,261 @@
|
|||
using System.Diagnostics;
|
||||
|
||||
using Dalamud.IoC;
|
||||
using Dalamud.IoC.Internal;
|
||||
using Serilog;
|
||||
|
||||
namespace Dalamud.Game.Config;
|
||||
|
||||
/// <summary>
|
||||
/// This class represents the game's configuration.
|
||||
/// </summary>
|
||||
[InterfaceVersion("1.0")]
|
||||
[PluginInterface]
|
||||
[ServiceManager.EarlyLoadedService]
|
||||
public sealed class GameConfig : IServiceType
|
||||
{
|
||||
[ServiceManager.ServiceConstructor]
|
||||
private unsafe GameConfig(Framework framework)
|
||||
{
|
||||
framework.RunOnTick(() =>
|
||||
{
|
||||
Log.Verbose("[GameConfig] Initalizing");
|
||||
var csFramework = FFXIVClientStructs.FFXIV.Client.System.Framework.Framework.Instance();
|
||||
var commonConfig = &csFramework->SystemConfig.CommonSystemConfig;
|
||||
this.System = new GameConfigSection("System", framework, &commonConfig->ConfigBase);
|
||||
this.UiConfig = new GameConfigSection("UiConfig", framework, &commonConfig->UiConfig);
|
||||
this.UiControl = new GameConfigSection("UiControl", framework, () => this.UiConfig.TryGetBool("PadMode", out var padMode) && padMode ? &commonConfig->UiControlGamepadConfig : &commonConfig->UiControlConfig);
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the collection of config options that persist between characters.
|
||||
/// </summary>
|
||||
public GameConfigSection System { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the collection of config options that are character specific.
|
||||
/// </summary>
|
||||
public GameConfigSection UiConfig { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the collection of config options that are control mode specific. (Mouse & Keyboard / Gamepad).
|
||||
/// </summary>
|
||||
public GameConfigSection UiControl { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to get a boolean config value from the System section.
|
||||
/// </summary>
|
||||
/// <param name="option">Option to get the value of.</param>
|
||||
/// <param name="value">The returned value of the config option.</param>
|
||||
/// <returns>A value representing the success.</returns>
|
||||
public bool TryGet(SystemConfigOption option, out bool value) => this.System.TryGet(option.GetName(), out value);
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to get a uint config value from the System section.
|
||||
/// </summary>
|
||||
/// <param name="option">Option to get the value of.</param>
|
||||
/// <param name="value">The returned value of the config option.</param>
|
||||
/// <returns>A value representing the success.</returns>
|
||||
public bool TryGet(SystemConfigOption option, out uint value) => this.System.TryGet(option.GetName(), out value);
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to get a float config value from the System section.
|
||||
/// </summary>
|
||||
/// <param name="option">Option to get the value of.</param>
|
||||
/// <param name="value">The returned value of the config option.</param>
|
||||
/// <returns>A value representing the success.</returns>
|
||||
public bool TryGet(SystemConfigOption option, out float value) => this.System.TryGet(option.GetName(), out value);
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to get a string config value from the System section.
|
||||
/// </summary>
|
||||
/// <param name="option">Option to get the value of.</param>
|
||||
/// <param name="value">The returned value of the config option.</param>
|
||||
/// <returns>A value representing the success.</returns>
|
||||
public bool TryGet(SystemConfigOption option, out string value) => this.System.TryGet(option.GetName(), out value);
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to get a boolean config value from the UiConfig section.
|
||||
/// </summary>
|
||||
/// <param name="option">Option to get the value of.</param>
|
||||
/// <param name="value">The returned value of the config option.</param>
|
||||
/// <returns>A value representing the success.</returns>
|
||||
public bool TryGet(UiConfigOption option, out bool value) => this.UiConfig.TryGet(option.GetName(), out value);
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to get a uint config value from the UiConfig section.
|
||||
/// </summary>
|
||||
/// <param name="option">Option to get the value of.</param>
|
||||
/// <param name="value">The returned value of the config option.</param>
|
||||
/// <returns>A value representing the success.</returns>
|
||||
public bool TryGet(UiConfigOption option, out uint value) => this.UiConfig.TryGet(option.GetName(), out value);
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to get a float config value from the UiConfig section.
|
||||
/// </summary>
|
||||
/// <param name="option">Option to get the value of.</param>
|
||||
/// <param name="value">The returned value of the config option.</param>
|
||||
/// <returns>A value representing the success.</returns>
|
||||
public bool TryGet(UiConfigOption option, out float value) => this.UiConfig.TryGet(option.GetName(), out value);
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to get a string config value from the UiConfig section.
|
||||
/// </summary>
|
||||
/// <param name="option">Option to get the value of.</param>
|
||||
/// <param name="value">The returned value of the config option.</param>
|
||||
/// <returns>A value representing the success.</returns>
|
||||
public bool TryGet(UiConfigOption option, out string value) => this.UiControl.TryGet(option.GetName(), out value);
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to get a boolean config value from the UiControl section.
|
||||
/// </summary>
|
||||
/// <param name="option">Option to get the value of.</param>
|
||||
/// <param name="value">The returned value of the config option.</param>
|
||||
/// <returns>A value representing the success.</returns>
|
||||
public bool TryGet(UiControlOption option, out bool value) => this.UiControl.TryGet(option.GetName(), out value);
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to get a uint config value from the UiControl section.
|
||||
/// </summary>
|
||||
/// <param name="option">Option to get the value of.</param>
|
||||
/// <param name="value">The returned value of the config option.</param>
|
||||
/// <returns>A value representing the success.</returns>
|
||||
public bool TryGet(UiControlOption option, out uint value) => this.UiControl.TryGet(option.GetName(), out value);
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to get a float config value from the UiControl section.
|
||||
/// </summary>
|
||||
/// <param name="option">Option to get the value of.</param>
|
||||
/// <param name="value">The returned value of the config option.</param>
|
||||
/// <returns>A value representing the success.</returns>
|
||||
public bool TryGet(UiControlOption option, out float value) => this.UiControl.TryGet(option.GetName(), out value);
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to get a string config value from the UiControl section.
|
||||
/// </summary>
|
||||
/// <param name="option">Option to get the value of.</param>
|
||||
/// <param name="value">The returned value of the config option.</param>
|
||||
/// <returns>A value representing the success.</returns>
|
||||
public bool TryGet(UiControlOption option, out string value) => this.System.TryGet(option.GetName(), out value);
|
||||
|
||||
/// <summary>
|
||||
/// Set a boolean config option in the System config section.
|
||||
/// Note: Not all config options will be be immediately reflected in the game.
|
||||
/// </summary>
|
||||
/// <param name="option">Name of the config option.</param>
|
||||
/// <param name="value">New value of the config option.</param>
|
||||
/// <exception cref="ConfigOptionNotFoundException">Throw if the config option is not found.</exception>
|
||||
/// <exception cref="UnreachableException">Thrown if the name of the config option is found, but the struct was not.</exception>
|
||||
public void Set(SystemConfigOption option, bool value) => this.System.Set(option.GetName(), value);
|
||||
|
||||
/// <summary>
|
||||
/// Set a unsigned integer config option in the System config section.
|
||||
/// Note: Not all config options will be be immediately reflected in the game.
|
||||
/// </summary>
|
||||
/// <param name="option">Name of the config option.</param>
|
||||
/// <param name="value">New value of the config option.</param>
|
||||
/// <exception cref="ConfigOptionNotFoundException">Throw if the config option is not found.</exception>
|
||||
/// <exception cref="UnreachableException">Thrown if the name of the config option is found, but the struct was not.</exception>
|
||||
public void Set(SystemConfigOption option, uint value) => this.System.Set(option.GetName(), value);
|
||||
|
||||
/// <summary>
|
||||
/// Set a float config option in the System config section.
|
||||
/// Note: Not all config options will be be immediately reflected in the game.
|
||||
/// </summary>
|
||||
/// <param name="option">Name of the config option.</param>
|
||||
/// <param name="value">New value of the config option.</param>
|
||||
/// <exception cref="ConfigOptionNotFoundException">Throw if the config option is not found.</exception>
|
||||
/// <exception cref="UnreachableException">Thrown if the name of the config option is found, but the struct was not.</exception>
|
||||
public void Set(SystemConfigOption option, float value) => this.System.Set(option.GetName(), value);
|
||||
|
||||
/// <summary>
|
||||
/// Set a string config option in the System config section.
|
||||
/// Note: Not all config options will be be immediately reflected in the game.
|
||||
/// </summary>
|
||||
/// <param name="option">Name of the config option.</param>
|
||||
/// <param name="value">New value of the config option.</param>
|
||||
/// <exception cref="ConfigOptionNotFoundException">Throw if the config option is not found.</exception>
|
||||
/// <exception cref="UnreachableException">Thrown if the name of the config option is found, but the struct was not.</exception>
|
||||
public void Set(SystemConfigOption option, string value) => this.System.Set(option.GetName(), value);
|
||||
|
||||
/// <summary>
|
||||
/// Set a boolean config option in the UiConfig section.
|
||||
/// Note: Not all config options will be be immediately reflected in the game.
|
||||
/// </summary>
|
||||
/// <param name="option">Name of the config option.</param>
|
||||
/// <param name="value">New value of the config option.</param>
|
||||
/// <exception cref="ConfigOptionNotFoundException">Throw if the config option is not found.</exception>
|
||||
/// <exception cref="UnreachableException">Thrown if the name of the config option is found, but the struct was not.</exception>
|
||||
public void Set(UiConfigOption option, bool value) => this.UiConfig.Set(option.GetName(), value);
|
||||
|
||||
/// <summary>
|
||||
/// Set a unsigned integer config option in the UiConfig section.
|
||||
/// Note: Not all config options will be be immediately reflected in the game.
|
||||
/// </summary>
|
||||
/// <param name="option">Name of the config option.</param>
|
||||
/// <param name="value">New value of the config option.</param>
|
||||
/// <exception cref="ConfigOptionNotFoundException">Throw if the config option is not found.</exception>
|
||||
/// <exception cref="UnreachableException">Thrown if the name of the config option is found, but the struct was not.</exception>
|
||||
public void Set(UiConfigOption option, uint value) => this.UiConfig.Set(option.GetName(), value);
|
||||
|
||||
/// <summary>
|
||||
/// Set a float config option in the UiConfig section.
|
||||
/// Note: Not all config options will be be immediately reflected in the game.
|
||||
/// </summary>
|
||||
/// <param name="option">Name of the config option.</param>
|
||||
/// <param name="value">New value of the config option.</param>
|
||||
/// <exception cref="ConfigOptionNotFoundException">Throw if the config option is not found.</exception>
|
||||
/// <exception cref="UnreachableException">Thrown if the name of the config option is found, but the struct was not.</exception>
|
||||
public void Set(UiConfigOption option, float value) => this.UiConfig.Set(option.GetName(), value);
|
||||
|
||||
/// <summary>
|
||||
/// Set a string config option in the UiConfig section.
|
||||
/// Note: Not all config options will be be immediately reflected in the game.
|
||||
/// </summary>
|
||||
/// <param name="option">Name of the config option.</param>
|
||||
/// <param name="value">New value of the config option.</param>
|
||||
/// <exception cref="ConfigOptionNotFoundException">Throw if the config option is not found.</exception>
|
||||
/// <exception cref="UnreachableException">Thrown if the name of the config option is found, but the struct was not.</exception>
|
||||
public void Set(UiConfigOption option, string value) => this.UiConfig.Set(option.GetName(), value);
|
||||
|
||||
/// <summary>
|
||||
/// Set a boolean config option in the UiControl config section.
|
||||
/// Note: Not all config options will be be immediately reflected in the game.
|
||||
/// </summary>
|
||||
/// <param name="option">Name of the config option.</param>
|
||||
/// <param name="value">New value of the config option.</param>
|
||||
/// <exception cref="ConfigOptionNotFoundException">Throw if the config option is not found.</exception>
|
||||
/// <exception cref="UnreachableException">Thrown if the name of the config option is found, but the struct was not.</exception>
|
||||
public void Set(UiControlOption option, bool value) => this.UiControl.Set(option.GetName(), value);
|
||||
|
||||
/// <summary>
|
||||
/// Set a uint config option in the UiControl config section.
|
||||
/// Note: Not all config options will be be immediately reflected in the game.
|
||||
/// </summary>
|
||||
/// <param name="option">Name of the config option.</param>
|
||||
/// <param name="value">New value of the config option.</param>
|
||||
/// <exception cref="ConfigOptionNotFoundException">Throw if the config option is not found.</exception>
|
||||
/// <exception cref="UnreachableException">Thrown if the name of the config option is found, but the struct was not.</exception>
|
||||
public void Set(UiControlOption option, uint value) => this.UiControl.Set(option.GetName(), value);
|
||||
|
||||
/// <summary>
|
||||
/// Set a float config option in the UiControl config section.
|
||||
/// Note: Not all config options will be be immediately reflected in the game.
|
||||
/// </summary>
|
||||
/// <param name="option">Name of the config option.</param>
|
||||
/// <param name="value">New value of the config option.</param>
|
||||
/// <exception cref="ConfigOptionNotFoundException">Throw if the config option is not found.</exception>
|
||||
/// <exception cref="UnreachableException">Thrown if the name of the config option is found, but the struct was not.</exception>
|
||||
public void Set(UiControlOption option, float value) => this.UiControl.Set(option.GetName(), value);
|
||||
|
||||
/// <summary>
|
||||
/// Set a string config option in the UiControl config section.
|
||||
/// Note: Not all config options will be be immediately reflected in the game.
|
||||
/// </summary>
|
||||
/// <param name="option">Name of the config option.</param>
|
||||
/// <param name="value">New value of the config option.</param>
|
||||
/// <exception cref="ConfigOptionNotFoundException">Throw if the config option is not found.</exception>
|
||||
/// <exception cref="UnreachableException">Thrown if the name of the config option is found, but the struct was not.</exception>
|
||||
public void Set(UiControlOption option, string value) => this.UiControl.Set(option.GetName(), value);
|
||||
}
|
||||
39
Dalamud/Game/Config/GameConfigEnumExtensions.cs
Normal file
39
Dalamud/Game/Config/GameConfigEnumExtensions.cs
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
using Dalamud.Utility;
|
||||
|
||||
namespace Dalamud.Game.Config;
|
||||
|
||||
/// <summary>
|
||||
/// Helper functions for accessing GameConfigOptions.
|
||||
/// </summary>
|
||||
internal static class GameConfigEnumExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the name of a SystemConfigOption from it's attribute.
|
||||
/// </summary>
|
||||
/// <param name="systemConfigOption">The SystemConfigOption.</param>
|
||||
/// <returns>Name of the option.</returns>
|
||||
public static string GetName(this SystemConfigOption systemConfigOption)
|
||||
{
|
||||
return systemConfigOption.GetAttribute<GameConfigOptionAttribute>()?.Name ?? $"{systemConfigOption}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of a UiConfigOption from it's attribute.
|
||||
/// </summary>
|
||||
/// <param name="uiConfigOption">The UiConfigOption.</param>
|
||||
/// <returns>Name of the option.</returns>
|
||||
public static string GetName(this UiConfigOption uiConfigOption)
|
||||
{
|
||||
return uiConfigOption.GetAttribute<GameConfigOptionAttribute>()?.Name ?? $"{uiConfigOption}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of a UiControlOption from it's attribute.
|
||||
/// </summary>
|
||||
/// <param name="uiControlOption">The UiControlOption.</param>
|
||||
/// <returns>Name of the option.</returns>
|
||||
public static string GetName(this UiControlOption uiControlOption)
|
||||
{
|
||||
return uiControlOption.GetAttribute<GameConfigOptionAttribute>()?.Name ?? $"{uiControlOption}";
|
||||
}
|
||||
}
|
||||
40
Dalamud/Game/Config/GameConfigOptionAttribute.cs
Normal file
40
Dalamud/Game/Config/GameConfigOptionAttribute.cs
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
using System;
|
||||
|
||||
using FFXIVClientStructs.FFXIV.Common.Configuration;
|
||||
|
||||
namespace Dalamud.Game.Config;
|
||||
|
||||
/// <summary>
|
||||
/// An attribute for defining GameConfig options.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Field)]
|
||||
public class GameConfigOptionAttribute : Attribute
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="GameConfigOptionAttribute"/> class.
|
||||
/// </summary>
|
||||
/// <param name="name">Name of the config option.</param>
|
||||
/// <param name="type">The type of the config option.</param>
|
||||
/// <param name="settable">False if the game does not take changes to the config option.</param>
|
||||
public GameConfigOptionAttribute(string name, ConfigType type, bool settable = true)
|
||||
{
|
||||
this.Name = name;
|
||||
this.Type = type;
|
||||
this.Settable = settable;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Name of the config option.
|
||||
/// </summary>
|
||||
public string Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the type of the config option.
|
||||
/// </summary>
|
||||
public ConfigType Type { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the config option will update immediately or not.
|
||||
/// </summary>
|
||||
public bool Settable { get; }
|
||||
}
|
||||
407
Dalamud/Game/Config/GameConfigSection.cs
Normal file
407
Dalamud/Game/Config/GameConfigSection.cs
Normal file
|
|
@ -0,0 +1,407 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
|
||||
using Dalamud.Memory;
|
||||
using FFXIVClientStructs.FFXIV.Common.Configuration;
|
||||
using Serilog;
|
||||
|
||||
namespace Dalamud.Game.Config;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a section of the game config and contains helper functions for accessing and setting values.
|
||||
/// </summary>
|
||||
public class GameConfigSection
|
||||
{
|
||||
private readonly Framework framework;
|
||||
private readonly Dictionary<string, uint> indexMap = new();
|
||||
private readonly Dictionary<uint, string> nameMap = new();
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="GameConfigSection"/> class.
|
||||
/// </summary>
|
||||
/// <param name="sectionName">Name of the section.</param>
|
||||
/// <param name="framework">The framework service.</param>
|
||||
/// <param name="configBase">Unmanaged ConfigBase instance.</param>
|
||||
internal unsafe GameConfigSection(string sectionName, Framework framework, ConfigBase* configBase)
|
||||
: this(sectionName, framework, () => configBase)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="GameConfigSection"/> class.
|
||||
/// </summary>
|
||||
/// <param name="sectionName">Name of the section.</param>
|
||||
/// <param name="framework">The framework service.</param>
|
||||
/// <param name="getConfigBase">A function that determines which ConfigBase instance should be used.</param>
|
||||
internal GameConfigSection(string sectionName, Framework framework, GetConfigBaseDelegate getConfigBase)
|
||||
{
|
||||
this.SectionName = sectionName;
|
||||
this.framework = framework;
|
||||
this.GetConfigBase = getConfigBase;
|
||||
Log.Verbose("[GameConfig] Initalizing {SectionName} with {ConfigCount} entries.", this.SectionName, this.ConfigCount);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Delegate that gets the struct the section accesses.
|
||||
/// </summary>
|
||||
/// <returns>Pointer to unmanaged ConfigBase.</returns>
|
||||
internal unsafe delegate ConfigBase* GetConfigBaseDelegate();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of config entries contained within the section.
|
||||
/// Some entries may be empty with no data.
|
||||
/// </summary>
|
||||
public unsafe uint ConfigCount => this.GetConfigBase()->ConfigCount;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the config section.
|
||||
/// </summary>
|
||||
public string SectionName { get; }
|
||||
|
||||
private GetConfigBaseDelegate GetConfigBase { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to get a boolean config option.
|
||||
/// </summary>
|
||||
/// <param name="name">Name of the config option.</param>
|
||||
/// <param name="value">The returned value of the config option.</param>
|
||||
/// <returns>A value representing the success.</returns>
|
||||
public unsafe bool TryGetBool(string name, out bool value) {
|
||||
value = false;
|
||||
if (!this.TryGetIndex(name, out var index))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!this.TryGetEntry(index, out var entry))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
value = entry->Value.UInt != 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to get a boolean config option.
|
||||
/// </summary>
|
||||
/// <param name="name">Name of the config option.</param>
|
||||
/// <param name="value">The returned value of the config option.</param>
|
||||
/// <returns>A value representing the success.</returns>
|
||||
public bool TryGet(string name, out bool value) => this.TryGetBool(name, out value);
|
||||
|
||||
/// <summary>
|
||||
/// Get a boolean config option.
|
||||
/// </summary>
|
||||
/// <param name="name">Name of the config option.</param>
|
||||
/// <returns>Value of the config option.</returns>
|
||||
/// <exception cref="ConfigOptionNotFoundException">Thrown if the config option is not found.</exception>
|
||||
public bool GetBool(string name) {
|
||||
if (!this.TryGetBool(name, out var value))
|
||||
{
|
||||
throw new ConfigOptionNotFoundException(this.SectionName, name);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set a boolean config option.
|
||||
/// Note: Not all config options will be be immediately reflected in the game.
|
||||
/// </summary>
|
||||
/// <param name="name">Name of the config option.</param>
|
||||
/// <param name="value">New value of the config option.</param>
|
||||
/// <exception cref="ConfigOptionNotFoundException">Throw if the config option is not found.</exception>
|
||||
/// <exception cref="UnreachableException">Thrown if the name of the config option is found, but the struct was not.</exception>
|
||||
public unsafe void Set(string name, bool value) {
|
||||
if (!this.TryGetIndex(name, out var index))
|
||||
{
|
||||
throw new ConfigOptionNotFoundException(this.SectionName, name);
|
||||
}
|
||||
|
||||
if (!this.TryGetEntry(index, out var entry))
|
||||
{
|
||||
throw new UnreachableException($"An unexpected error was encountered setting {name} in {this.SectionName}");
|
||||
}
|
||||
|
||||
if ((ConfigType)entry->Type != ConfigType.UInt)
|
||||
{
|
||||
throw new IncorrectConfigTypeException(this.SectionName, name, (ConfigType)entry->Type, ConfigType.UInt);
|
||||
}
|
||||
|
||||
entry->SetValue(value ? 1U : 0U);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to get an unsigned integer config value.
|
||||
/// </summary>
|
||||
/// <param name="name">Name of the config option.</param>
|
||||
/// <param name="value">The returned value of the config option.</param>
|
||||
/// <returns>A value representing the success.</returns>
|
||||
public unsafe bool TryGetUInt(string name, out uint value) {
|
||||
value = 0;
|
||||
if (!this.TryGetIndex(name, out var index))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!this.TryGetEntry(index, out var entry))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
value = entry->Value.UInt;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to get an unsigned integer config value.
|
||||
/// </summary>
|
||||
/// <param name="name">Name of the config option.</param>
|
||||
/// <param name="value">The returned value of the config option.</param>
|
||||
/// <returns>A value representing the success.</returns>
|
||||
public bool TryGet(string name, out uint value) => this.TryGetUInt(name, out value);
|
||||
|
||||
/// <summary>
|
||||
/// Get an unsigned integer config option.
|
||||
/// </summary>
|
||||
/// <param name="name">Name of the config option.</param>
|
||||
/// <returns>Value of the config option.</returns>
|
||||
/// <exception cref="ConfigOptionNotFoundException">Thrown if the config option is not found.</exception>
|
||||
public uint GetUInt(string name) {
|
||||
if (!this.TryGetUInt(name, out var value))
|
||||
{
|
||||
throw new ConfigOptionNotFoundException(this.SectionName, name);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set an unsigned integer config option.
|
||||
/// Note: Not all config options will be be immediately reflected in the game.
|
||||
/// </summary>
|
||||
/// <param name="name">Name of the config option.</param>
|
||||
/// <param name="value">New value of the config option.</param>
|
||||
/// <exception cref="ConfigOptionNotFoundException">Throw if the config option is not found.</exception>
|
||||
/// <exception cref="UnreachableException">Thrown if the name of the config option is found, but the struct was not.</exception>
|
||||
public unsafe void Set(string name, uint value) {
|
||||
this.framework.RunOnFrameworkThread(() => {
|
||||
if (!this.TryGetIndex(name, out var index))
|
||||
{
|
||||
throw new ConfigOptionNotFoundException(this.SectionName, name);
|
||||
}
|
||||
|
||||
if (!this.TryGetEntry(index, out var entry))
|
||||
{
|
||||
throw new UnreachableException($"An unexpected error was encountered setting {name} in {this.SectionName}");
|
||||
}
|
||||
|
||||
if ((ConfigType)entry->Type != ConfigType.UInt)
|
||||
{
|
||||
throw new IncorrectConfigTypeException(this.SectionName, name, (ConfigType)entry->Type, ConfigType.UInt);
|
||||
}
|
||||
|
||||
entry->SetValue(value);
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to get a float config value.
|
||||
/// </summary>
|
||||
/// <param name="name">Name of the config option.</param>
|
||||
/// <param name="value">The returned value of the config option.</param>
|
||||
/// <returns>A value representing the success.</returns>
|
||||
public unsafe bool TryGetFloat(string name, out float value) {
|
||||
value = 0;
|
||||
if (!this.TryGetIndex(name, out var index))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!this.TryGetEntry(index, out var entry))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
value = entry->Value.Float;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to get a float config value.
|
||||
/// </summary>
|
||||
/// <param name="name">Name of the config option.</param>
|
||||
/// <param name="value">The returned value of the config option.</param>
|
||||
/// <returns>A value representing the success.</returns>
|
||||
public bool TryGet(string name, out float value) => this.TryGetFloat(name, out value);
|
||||
|
||||
/// <summary>
|
||||
/// Get a float config option.
|
||||
/// </summary>
|
||||
/// <param name="name">Name of the config option.</param>
|
||||
/// <returns>Value of the config option.</returns>
|
||||
/// <exception cref="ConfigOptionNotFoundException">Thrown if the config option is not found.</exception>
|
||||
public float GetFloat(string name) {
|
||||
if (!this.TryGetFloat(name, out var value))
|
||||
{
|
||||
throw new ConfigOptionNotFoundException(this.SectionName, name);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set a float config option.
|
||||
/// Note: Not all config options will be be immediately reflected in the game.
|
||||
/// </summary>
|
||||
/// <param name="name">Name of the config option.</param>
|
||||
/// <param name="value">New value of the config option.</param>
|
||||
/// <exception cref="ConfigOptionNotFoundException">Throw if the config option is not found.</exception>
|
||||
/// <exception cref="UnreachableException">Thrown if the name of the config option is found, but the struct was not.</exception>
|
||||
public unsafe void Set(string name, float value) {
|
||||
this.framework.RunOnFrameworkThread(() => {
|
||||
if (!this.TryGetIndex(name, out var index))
|
||||
{
|
||||
throw new ConfigOptionNotFoundException(this.SectionName, name);
|
||||
}
|
||||
|
||||
if (!this.TryGetEntry(index, out var entry))
|
||||
{
|
||||
throw new UnreachableException($"An unexpected error was encountered setting {name} in {this.SectionName}");
|
||||
}
|
||||
|
||||
if ((ConfigType)entry->Type != ConfigType.Float)
|
||||
{
|
||||
throw new IncorrectConfigTypeException(this.SectionName, name, (ConfigType)entry->Type, ConfigType.Float);
|
||||
}
|
||||
|
||||
entry->SetValue(value);
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to get a string config value.
|
||||
/// </summary>
|
||||
/// <param name="name">Name of the config option.</param>
|
||||
/// <param name="value">The returned value of the config option.</param>
|
||||
/// <returns>A value representing the success.</returns>
|
||||
public unsafe bool TryGetString(string name, out string value) {
|
||||
value = string.Empty;
|
||||
if (!this.TryGetIndex(name, out var index))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!this.TryGetEntry(index, out var entry))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (entry->Type != 4)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (entry->Value.String == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
value = entry->Value.String->ToString();
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to get a string config value.
|
||||
/// </summary>
|
||||
/// <param name="name">Name of the config option.</param>
|
||||
/// <param name="value">The returned value of the config option.</param>
|
||||
/// <returns>A value representing the success.</returns>
|
||||
public bool TryGet(string name, out string value) => this.TryGetString(name, out value);
|
||||
|
||||
/// <summary>
|
||||
/// Get a string config option.
|
||||
/// </summary>
|
||||
/// <param name="name">Name of the config option.</param>
|
||||
/// <returns>Value of the config option.</returns>
|
||||
/// <exception cref="ConfigOptionNotFoundException">Thrown if the config option is not found.</exception>
|
||||
public string GetString(string name) {
|
||||
if (!this.TryGetString(name, out var value))
|
||||
{
|
||||
throw new ConfigOptionNotFoundException(this.SectionName, name);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set a string config option.
|
||||
/// Note: Not all config options will be be immediately reflected in the game.
|
||||
/// </summary>
|
||||
/// <param name="name">Name of the config option.</param>
|
||||
/// <param name="value">New value of the config option.</param>
|
||||
/// <exception cref="ConfigOptionNotFoundException">Throw if the config option is not found.</exception>
|
||||
/// <exception cref="UnreachableException">Thrown if the name of the config option is found, but the struct was not.</exception>
|
||||
public unsafe void Set(string name, string value) {
|
||||
this.framework.RunOnFrameworkThread(() => {
|
||||
if (!this.TryGetIndex(name, out var index))
|
||||
{
|
||||
throw new ConfigOptionNotFoundException(this.SectionName, name);
|
||||
}
|
||||
|
||||
if (!this.TryGetEntry(index, out var entry))
|
||||
{
|
||||
throw new UnreachableException($"An unexpected error was encountered setting {name} in {this.SectionName}");
|
||||
}
|
||||
|
||||
if ((ConfigType)entry->Type != ConfigType.String)
|
||||
{
|
||||
throw new IncorrectConfigTypeException(this.SectionName, name, (ConfigType)entry->Type, ConfigType.String);
|
||||
}
|
||||
|
||||
entry->SetValue(value);
|
||||
});
|
||||
}
|
||||
|
||||
private unsafe bool TryGetIndex(string name, out uint index) {
|
||||
if (this.indexMap.TryGetValue(name, out index))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
var configBase = this.GetConfigBase();
|
||||
var e = configBase->ConfigEntry;
|
||||
for (var i = 0U; i < configBase->ConfigCount; i++, e++) {
|
||||
if (e->Name == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var eName = MemoryHelper.ReadStringNullTerminated(new IntPtr(e->Name));
|
||||
if (eName.Equals(name)) {
|
||||
this.indexMap.TryAdd(name, i);
|
||||
this.nameMap.TryAdd(i, name);
|
||||
index = i;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
index = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
private unsafe bool TryGetEntry(uint index, out ConfigEntry* entry) {
|
||||
entry = null;
|
||||
var configBase = this.GetConfigBase();
|
||||
if (configBase->ConfigEntry == null || index >= configBase->ConfigCount)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
entry = configBase->ConfigEntry;
|
||||
entry += index;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
23
Dalamud/Game/Config/IncorrectConfigTypeException.cs
Normal file
23
Dalamud/Game/Config/IncorrectConfigTypeException.cs
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
using System;
|
||||
|
||||
using FFXIVClientStructs.FFXIV.Common.Configuration;
|
||||
|
||||
namespace Dalamud.Game.Config;
|
||||
|
||||
/// <summary>
|
||||
/// An exception thrown when attempting to assign a value to a config option with the wrong type.
|
||||
/// </summary>
|
||||
public class IncorrectConfigTypeException : Exception
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="IncorrectConfigTypeException"/> class.
|
||||
/// </summary>
|
||||
/// <param name="sectionName">Name of the section being accessed.</param>
|
||||
/// <param name="configOptionName">Name of the config option that was not found.</param>
|
||||
/// <param name="correctType">The correct type for the config option.</param>
|
||||
/// <param name="incorrectType">The type that was attempted.</param>
|
||||
public IncorrectConfigTypeException(string sectionName, string configOptionName, ConfigType correctType, ConfigType incorrectType)
|
||||
: base($"The option '{configOptionName}' in {sectionName} is of the type {correctType}. Assigning {incorrectType} is invalid.")
|
||||
{
|
||||
}
|
||||
}
|
||||
1385
Dalamud/Game/Config/SystemConfigOption.cs
Normal file
1385
Dalamud/Game/Config/SystemConfigOption.cs
Normal file
File diff suppressed because it is too large
Load diff
3317
Dalamud/Game/Config/UiConfigOption.cs
Normal file
3317
Dalamud/Game/Config/UiConfigOption.cs
Normal file
File diff suppressed because it is too large
Load diff
1280
Dalamud/Game/Config/UiControlOption.cs
Normal file
1280
Dalamud/Game/Config/UiControlOption.cs
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,107 @@
|
|||
using Dalamud.Game.Config;
|
||||
using ImGuiNET;
|
||||
|
||||
namespace Dalamud.Interface.Internal.Windows.SelfTest.AgingSteps;
|
||||
|
||||
/// <summary>
|
||||
/// Test of GameConfig.
|
||||
/// </summary>
|
||||
internal class GameConfigAgingStep : IAgingStep
|
||||
{
|
||||
private bool started;
|
||||
private bool isStartedLegacy;
|
||||
private bool isSwitchedLegacy;
|
||||
private bool isSwitchedStandard;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string Name => "Test GameConfig";
|
||||
|
||||
/// <inheritdoc/>
|
||||
public SelfTestStepResult RunStep()
|
||||
{
|
||||
var gameConfig = Service<GameConfig>.Get();
|
||||
|
||||
if (!gameConfig.UiControl.TryGetBool("MoveMode", out var isLegacy))
|
||||
{
|
||||
return SelfTestStepResult.Fail;
|
||||
}
|
||||
|
||||
if (!this.started)
|
||||
{
|
||||
this.started = true;
|
||||
this.isStartedLegacy = isLegacy;
|
||||
return SelfTestStepResult.Waiting;
|
||||
}
|
||||
|
||||
if (this.isStartedLegacy)
|
||||
{
|
||||
if (!this.isSwitchedStandard)
|
||||
{
|
||||
if (!isLegacy)
|
||||
{
|
||||
this.isSwitchedStandard = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui.Text("Switch Movement Type to Standard");
|
||||
}
|
||||
|
||||
return SelfTestStepResult.Waiting;
|
||||
}
|
||||
|
||||
if (!this.isSwitchedLegacy)
|
||||
{
|
||||
if (isLegacy)
|
||||
{
|
||||
this.isSwitchedLegacy = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui.Text("Switch Movement Type to Legacy");
|
||||
}
|
||||
|
||||
return SelfTestStepResult.Waiting;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!this.isSwitchedLegacy)
|
||||
{
|
||||
if (isLegacy)
|
||||
{
|
||||
this.isSwitchedLegacy = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui.Text("Switch Movement Type to Legacy");
|
||||
}
|
||||
|
||||
return SelfTestStepResult.Waiting;
|
||||
}
|
||||
|
||||
if (!this.isSwitchedStandard)
|
||||
{
|
||||
if (!isLegacy)
|
||||
{
|
||||
this.isSwitchedStandard = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGui.Text("Switch Movement Type to Standard");
|
||||
}
|
||||
|
||||
return SelfTestStepResult.Waiting;
|
||||
}
|
||||
}
|
||||
|
||||
return SelfTestStepResult.Pass;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void CleanUp()
|
||||
{
|
||||
this.isSwitchedLegacy = false;
|
||||
this.isSwitchedStandard = false;
|
||||
this.started = false;
|
||||
}
|
||||
}
|
||||
|
|
@ -42,6 +42,7 @@ internal class SelfTestWindow : Window
|
|||
new PartyFinderAgingStep(),
|
||||
new HandledExceptionAgingStep(),
|
||||
new DutyStateAgingStep(),
|
||||
new GameConfigAgingStep(),
|
||||
new LogoutEventAgingStep(),
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue