mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-12 18:27:23 +01:00
Merge branch 'master' into plugin-name
This commit is contained in:
commit
97a2c103e3
30 changed files with 13220 additions and 7113 deletions
|
|
@ -174,10 +174,6 @@ namespace Dalamud.Injector
|
|||
|
||||
private static void InitLogging(bool verbose, IEnumerable<string> args)
|
||||
{
|
||||
#if DEBUG
|
||||
verbose = true;
|
||||
#endif
|
||||
|
||||
var levelSwitch = new LoggingLevelSwitch
|
||||
{
|
||||
MinimumLevel = verbose ? LogEventLevel.Verbose : LogEventLevel.Information,
|
||||
|
|
|
|||
|
|
@ -351,6 +351,26 @@ internal sealed class DalamudConfiguration : IServiceType
|
|||
/// </summary>
|
||||
public bool WindowIsImmersive { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets hitch threshold for game network up in milliseconds.
|
||||
/// </summary>
|
||||
public double GameNetworkUpHitch { get; set; } = 30;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets hitch threshold for game network down in milliseconds.
|
||||
/// </summary>
|
||||
public double GameNetworkDownHitch { get; set; } = 30;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets hitch threshold for framework update in milliseconds.
|
||||
/// </summary>
|
||||
public double FrameworkUpdateHitch { get; set; } = 50;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets hitch threshold for ui builder in milliseconds.
|
||||
/// </summary>
|
||||
public double UiBuilderHitch { get; set; } = 100;
|
||||
|
||||
/// <summary>
|
||||
/// Load a configuration from the provided path.
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -146,7 +146,7 @@
|
|||
<Target Name="GetGitHashStub" BeforeTargets="WriteGitHash" Condition="'$(BuildHash)'=='' And '$(Configuration)'=='Debug'">
|
||||
<!-- Set the BuildHash property to contain some placeholder, if it wasn't already set.-->
|
||||
<PropertyGroup>
|
||||
<LocalBuildText>Local build at $([System.DateTime]::Now.ToString(yyyyMMdd-hhmmss))</LocalBuildText>
|
||||
<LocalBuildText>Local build at $([System.DateTime]::Now.ToString(yyyy-MM-dd HH:mm:ss))</LocalBuildText>
|
||||
<BuildHash>$(LocalBuildText)</BuildHash>
|
||||
<BuildHashClientStructs>???</BuildHashClientStructs>
|
||||
</PropertyGroup>
|
||||
|
|
|
|||
3
Dalamud/Dalamud.csproj.DotSettings
Normal file
3
Dalamud/Dalamud.csproj.DotSettings
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=interface_005Cfontawesome/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
|
||||
<s:Int64 x:Key="/Default/PerformanceThreshold/AnalysisFileSizeThreshold/=CSHARP/@EntryIndexedValue">300000</s:Int64>
|
||||
|
|
@ -147,11 +147,9 @@ public sealed class EntryPoint
|
|||
var configuration = DalamudConfiguration.Load(info.ConfigurationPath!);
|
||||
|
||||
// Set the appropriate logging level from the configuration
|
||||
#if !DEBUG
|
||||
if (!configuration.LogSynchronously)
|
||||
InitLogging(info.WorkingDirectory!, info.BootShowConsole, configuration.LogSynchronously, info.LogName);
|
||||
LogLevelSwitch.MinimumLevel = configuration.LogLevel;
|
||||
#endif
|
||||
|
||||
// Log any unhandled exception.
|
||||
AppDomain.CurrentDomain.UnhandledException += OnUnhandledException;
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ public sealed partial class BuddyList : IServiceType
|
|||
/// </summary>
|
||||
internal IntPtr BuddyListAddress => this.address.BuddyList;
|
||||
|
||||
private static int BuddyMemberSize { get; } = Marshal.SizeOf<FFXIVClientStructs.FFXIV.Client.Game.UI.Buddy>();
|
||||
private static int BuddyMemberSize { get; } = Marshal.SizeOf<FFXIVClientStructs.FFXIV.Client.Game.UI.Buddy.BuddyMember>();
|
||||
|
||||
private unsafe FFXIVClientStructs.FFXIV.Client.Game.UI.Buddy* BuddyListStruct => (FFXIVClientStructs.FFXIV.Client.Game.UI.Buddy*)this.BuddyListAddress;
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ public sealed class Framework : IDisposable, IServiceType
|
|||
private static Stopwatch statsStopwatch = new();
|
||||
|
||||
private readonly Stopwatch updateStopwatch = new();
|
||||
private readonly HitchDetector hitchDetector = new("FrameworkUpdate", 50);
|
||||
private readonly HitchDetector hitchDetector;
|
||||
|
||||
private readonly Hook<OnUpdateDetour> updateHook;
|
||||
private readonly Hook<OnRealDestroyDelegate> destroyHook;
|
||||
|
|
@ -39,9 +39,14 @@ public sealed class Framework : IDisposable, IServiceType
|
|||
|
||||
private Thread? frameworkUpdateThread;
|
||||
|
||||
[ServiceManager.ServiceDependency]
|
||||
private readonly DalamudConfiguration configuration = Service<DalamudConfiguration>.Get();
|
||||
|
||||
[ServiceManager.ServiceConstructor]
|
||||
private Framework(SigScanner sigScanner)
|
||||
{
|
||||
this.hitchDetector = new HitchDetector("FrameworkUpdate", this.configuration.FrameworkUpdateHitch);
|
||||
|
||||
this.Address = new FrameworkAddressResolver();
|
||||
this.Address.Setup(sigScanner);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +1,13 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
using Dalamud.Configuration.Internal;
|
||||
using Dalamud.Hooking;
|
||||
using Dalamud.IoC;
|
||||
using Dalamud.IoC.Internal;
|
||||
using Dalamud.Utility;
|
||||
using Serilog;
|
||||
using Serilog.Core;
|
||||
|
||||
namespace Dalamud.Game.Network;
|
||||
|
||||
|
|
@ -22,14 +23,20 @@ public sealed class GameNetwork : IDisposable, IServiceType
|
|||
private readonly Hook<ProcessZonePacketDownDelegate> processZonePacketDownHook;
|
||||
private readonly Hook<ProcessZonePacketUpDelegate> processZonePacketUpHook;
|
||||
|
||||
private readonly HitchDetector hitchDetectorUp = new("GameNetworkUp", 30);
|
||||
private readonly HitchDetector hitchDetectorDown = new("GameNetworkDown", 30);
|
||||
private readonly HitchDetector hitchDetectorUp;
|
||||
private readonly HitchDetector hitchDetectorDown;
|
||||
|
||||
private IntPtr baseAddress;
|
||||
|
||||
[ServiceManager.ServiceDependency]
|
||||
private readonly DalamudConfiguration configuration = Service<DalamudConfiguration>.Get();
|
||||
|
||||
[ServiceManager.ServiceConstructor]
|
||||
private GameNetwork(SigScanner sigScanner)
|
||||
{
|
||||
this.hitchDetectorUp = new HitchDetector("GameNetworkUp", this.configuration.GameNetworkUpHitch);
|
||||
this.hitchDetectorDown = new HitchDetector("GameNetworkDown", this.configuration.GameNetworkDownHitch);
|
||||
|
||||
this.address = new GameNetworkAddressResolver();
|
||||
this.address.Setup(sigScanner);
|
||||
|
||||
|
|
|
|||
|
|
@ -192,6 +192,11 @@ internal class NetworkHandlers : IDisposable, IServiceType
|
|||
IObservable<MarketBoardCurrentOfferings> UntilBatchEnd(MarketBoardItemRequest request)
|
||||
{
|
||||
var totalPackets = Convert.ToInt32(Math.Ceiling((double)request.AmountToArrive / 10));
|
||||
if (totalPackets == 0)
|
||||
{
|
||||
return Observable.Empty<MarketBoardCurrentOfferings>();
|
||||
}
|
||||
|
||||
return offeringsObservable
|
||||
.Where(offerings => offerings.ItemListings.All(l => l.CatalogId == request.CatalogId))
|
||||
.Skip(totalPackets - 1)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
using System;
|
||||
|
||||
namespace Dalamud.Interface;
|
||||
|
||||
/// <summary>
|
||||
/// Set categories associated with a font awesome icon.
|
||||
/// </summary>
|
||||
public class FontAwesomeCategoriesAttribute : Attribute
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="FontAwesomeCategoriesAttribute"/> class.
|
||||
/// </summary>
|
||||
/// <param name="categories">categories for enum member.</param>
|
||||
public FontAwesomeCategoriesAttribute(string[] categories) => this.Categories = categories;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets categories.
|
||||
/// </summary>
|
||||
public string[] Categories { get; set; }
|
||||
}
|
||||
53
Dalamud/Interface/FontAwesome/FontAwesomeExtensions.cs
Normal file
53
Dalamud/Interface/FontAwesome/FontAwesomeExtensions.cs
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
using Dalamud.Utility;
|
||||
|
||||
namespace Dalamud.Interface;
|
||||
|
||||
/// <summary>
|
||||
/// Extension methods for <see cref="FontAwesomeIcon"/>.
|
||||
/// </summary>
|
||||
public static class FontAwesomeExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Convert the FontAwesomeIcon to a <see cref="char"/> type.
|
||||
/// </summary>
|
||||
/// <param name="icon">The icon to convert.</param>
|
||||
/// <returns>The converted icon.</returns>
|
||||
public static char ToIconChar(this FontAwesomeIcon icon)
|
||||
{
|
||||
return (char)icon;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert the FontAwesomeIcon to a <see cref="string"/> type.
|
||||
/// </summary>
|
||||
/// <param name="icon">The icon to convert.</param>
|
||||
/// <returns>The converted icon.</returns>
|
||||
public static string ToIconString(this FontAwesomeIcon icon)
|
||||
{
|
||||
return string.Empty + (char)icon;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get FontAwesome search terms.
|
||||
/// </summary>
|
||||
/// <param name="icon">The icon to pull search terms from.</param>
|
||||
/// <returns>string array of search terms or empty array if none.</returns>
|
||||
public static IEnumerable<string> GetSearchTerms(this FontAwesomeIcon icon)
|
||||
{
|
||||
var searchTermsAttribute = icon.GetAttribute<FontAwesomeSearchTermsAttribute>();
|
||||
return searchTermsAttribute == null ? new string[] { } : searchTermsAttribute.SearchTerms;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get FontAwesome categories.
|
||||
/// </summary>
|
||||
/// <param name="icon">The icon to pull categories from.</param>
|
||||
/// <returns>string array of categories or empty array if none.</returns>
|
||||
public static IEnumerable<string> GetCategories(this FontAwesomeIcon icon)
|
||||
{
|
||||
var categoriesAttribute = icon.GetAttribute<FontAwesomeCategoriesAttribute>();
|
||||
return categoriesAttribute == null ? new string[] { } : categoriesAttribute.Categories;
|
||||
}
|
||||
}
|
||||
117
Dalamud/Interface/FontAwesome/FontAwesomeHelpers.cs
Normal file
117
Dalamud/Interface/FontAwesome/FontAwesomeHelpers.cs
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
using Dalamud.Utility;
|
||||
|
||||
namespace Dalamud.Interface;
|
||||
|
||||
/// <summary>
|
||||
/// Class containing various helper methods for use with Font Awesome inside Dalamud.
|
||||
/// </summary>
|
||||
public static class FontAwesomeHelpers
|
||||
{
|
||||
/// <summary>
|
||||
/// Get all non-obsolete icons.
|
||||
/// </summary>
|
||||
/// <returns>list of font awesome icons.</returns>
|
||||
public static List<FontAwesomeIcon> GetIcons()
|
||||
{
|
||||
var icons = new List<FontAwesomeIcon>();
|
||||
foreach (var icon in Enum.GetValues(typeof(FontAwesomeIcon)).Cast<FontAwesomeIcon>().ToList())
|
||||
{
|
||||
if (icon.IsObsolete()) continue;
|
||||
icons.Add(icon);
|
||||
}
|
||||
|
||||
return icons;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get all categories available on non-obsolete icons.
|
||||
/// </summary>
|
||||
/// <returns>list of font awesome icons.</returns>
|
||||
public static string[] GetCategories()
|
||||
{
|
||||
var icons = GetIcons();
|
||||
var result = new List<string>();
|
||||
foreach (var icon in icons)
|
||||
{
|
||||
var categories = icon.GetCategories();
|
||||
foreach (var category in categories)
|
||||
{
|
||||
if (!result.Contains(category))
|
||||
{
|
||||
result.Add(category);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result.Sort();
|
||||
result.Insert(0, string.Empty);
|
||||
return result.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get icons by search term.
|
||||
/// </summary>
|
||||
/// <param name="search">search term string.</param>
|
||||
/// <param name="category">name of category to filter by.</param>
|
||||
/// <returns>list array of font awesome icons matching search term.</returns>
|
||||
public static List<FontAwesomeIcon> SearchIcons(string search, string category)
|
||||
{
|
||||
var icons = GetIcons();
|
||||
var result = new List<FontAwesomeIcon>();
|
||||
|
||||
// if no filters
|
||||
if (string.IsNullOrEmpty(search) && string.IsNullOrEmpty(category))
|
||||
{
|
||||
return icons;
|
||||
}
|
||||
|
||||
// if search with only search term
|
||||
if (!string.IsNullOrEmpty(search) && string.IsNullOrEmpty(category))
|
||||
{
|
||||
foreach (var icon in icons)
|
||||
{
|
||||
var name = Enum.GetName(icon)?.ToLower();
|
||||
var searchTerms = icon.GetSearchTerms();
|
||||
if (name!.Contains(search.ToLower()) || searchTerms.Contains(search.ToLower()))
|
||||
{
|
||||
result.Add(icon);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// if search with only category
|
||||
if (string.IsNullOrEmpty(search) && !string.IsNullOrEmpty(category))
|
||||
{
|
||||
foreach (var icon in icons)
|
||||
{
|
||||
var categories = icon.GetCategories();
|
||||
if (categories.Contains(category))
|
||||
{
|
||||
result.Add(icon);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// search by both terms and category
|
||||
foreach (var icon in icons)
|
||||
{
|
||||
var name = Enum.GetName(icon)?.ToLower();
|
||||
var searchTerms = icon.GetSearchTerms();
|
||||
var categories = icon.GetCategories();
|
||||
if ((name!.Contains(search.ToLower()) || searchTerms.Contains(search.ToLower())) && categories.Contains(category))
|
||||
{
|
||||
result.Add(icon);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
12669
Dalamud/Interface/FontAwesome/FontAwesomeIcon.cs
Normal file
12669
Dalamud/Interface/FontAwesome/FontAwesomeIcon.cs
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,20 @@
|
|||
using System;
|
||||
|
||||
namespace Dalamud.Interface;
|
||||
|
||||
/// <summary>
|
||||
/// Set search terms associated with a font awesome icon.
|
||||
/// </summary>
|
||||
public class FontAwesomeSearchTermsAttribute : Attribute
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="FontAwesomeSearchTermsAttribute"/> class.
|
||||
/// </summary>
|
||||
/// <param name="searchTerms">search terms for enum member.</param>
|
||||
public FontAwesomeSearchTermsAttribute(string[] searchTerms) => this.SearchTerms = searchTerms;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets search terms.
|
||||
/// </summary>
|
||||
public string[] SearchTerms { get; set; }
|
||||
}
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
// Font-Awesome - Version 5.0.9
|
||||
|
||||
namespace Dalamud.Interface;
|
||||
|
||||
/// <summary>
|
||||
/// Extension methods for <see cref="FontAwesomeIcon"/>.
|
||||
/// </summary>
|
||||
public static class FontAwesomeExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Convert the FontAwesomeIcon to a <see cref="char"/> type.
|
||||
/// </summary>
|
||||
/// <param name="icon">The icon to convert.</param>
|
||||
/// <returns>The converted icon.</returns>
|
||||
public static char ToIconChar(this FontAwesomeIcon icon)
|
||||
{
|
||||
return (char)icon;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Conver the FontAwesomeIcon to a <see cref="string"/> type.
|
||||
/// </summary>
|
||||
/// <param name="icon">The icon to convert.</param>
|
||||
/// <returns>The converted icon.</returns>
|
||||
public static string ToIconString(this FontAwesomeIcon icon)
|
||||
{
|
||||
return string.Empty + (char)icon;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -29,10 +29,16 @@ internal class DalamudCommands : IServiceType
|
|||
HelpMessage = Loc.Localize("DalamudUnloadHelp", "Unloads XIVLauncher in-game addon."),
|
||||
ShowInHelp = false,
|
||||
});
|
||||
|
||||
commandManager.AddHandler("/xlkill", new CommandInfo(this.OnKillCommand)
|
||||
{
|
||||
HelpMessage = "Kill the game.",
|
||||
ShowInHelp = false,
|
||||
});
|
||||
|
||||
commandManager.AddHandler("/xlhelp", new CommandInfo(this.OnHelpCommand)
|
||||
{
|
||||
HelpMessage = Loc.Localize("DalamudCmdInfoHelp", "Shows list of commands available."),
|
||||
HelpMessage = Loc.Localize("DalamudCmdInfoHelp", "Shows list of commands available. If an argument is provided, shows help for that command."),
|
||||
});
|
||||
|
||||
commandManager.AddHandler("/xlmute", new CommandInfo(this.OnBadWordsAddCommand)
|
||||
|
|
@ -141,21 +147,35 @@ internal class DalamudCommands : IServiceType
|
|||
Service<ChatGui>.Get().Print("Unloading...");
|
||||
Service<Dalamud>.Get().Unload();
|
||||
}
|
||||
|
||||
private void OnKillCommand(string command, string arguments)
|
||||
{
|
||||
Process.GetCurrentProcess().Kill();
|
||||
}
|
||||
|
||||
private void OnHelpCommand(string command, string arguments)
|
||||
{
|
||||
var chatGui = Service<ChatGui>.Get();
|
||||
var commandManager = Service<CommandManager>.Get();
|
||||
|
||||
var showDebug = arguments.Contains("debug");
|
||||
|
||||
chatGui.Print(Loc.Localize("DalamudCmdHelpAvailable", "Available commands:"));
|
||||
foreach (var cmd in commandManager.Commands)
|
||||
if (arguments.IsNullOrWhitespace())
|
||||
{
|
||||
if (!cmd.Value.ShowInHelp && !showDebug)
|
||||
continue;
|
||||
chatGui.Print(Loc.Localize("DalamudCmdHelpAvailable", "Available commands:"));
|
||||
foreach (var cmd in commandManager.Commands)
|
||||
{
|
||||
if (!cmd.Value.ShowInHelp)
|
||||
continue;
|
||||
|
||||
chatGui.Print($"{cmd.Key}: {cmd.Value.HelpMessage}");
|
||||
chatGui.Print($"{cmd.Key}: {cmd.Value.HelpMessage}");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var trimmedArguments = arguments.Trim();
|
||||
var targetCommandText = trimmedArguments[0] == '/' ? trimmedArguments : $"/{trimmedArguments}";
|
||||
chatGui.Print(commandManager.Commands.TryGetValue(targetCommandText, out var targetCommand)
|
||||
? $"{targetCommandText}: {targetCommand.HelpMessage}"
|
||||
: Loc.Localize("DalamudCmdHelpNotFound", "Command not found."));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@ internal class DalamudInterface : IDisposable, IServiceType
|
|||
private readonly TitleScreenMenuWindow titleScreenMenuWindow;
|
||||
private readonly ProfilerWindow profilerWindow;
|
||||
private readonly BranchSwitcherWindow branchSwitcherWindow;
|
||||
private readonly HitchSettingsWindow hitchSettingsWindow;
|
||||
|
||||
private readonly TextureWrap logoTexture;
|
||||
private readonly TextureWrap tsmLogoTexture;
|
||||
|
|
@ -108,6 +109,7 @@ internal class DalamudInterface : IDisposable, IServiceType
|
|||
this.titleScreenMenuWindow = new TitleScreenMenuWindow() { IsOpen = false };
|
||||
this.profilerWindow = new ProfilerWindow() { IsOpen = false };
|
||||
this.branchSwitcherWindow = new BranchSwitcherWindow() { IsOpen = false };
|
||||
this.hitchSettingsWindow = new HitchSettingsWindow() { IsOpen = false };
|
||||
|
||||
this.WindowSystem.AddWindow(this.changelogWindow);
|
||||
this.WindowSystem.AddWindow(this.colorDemoWindow);
|
||||
|
|
@ -124,6 +126,7 @@ internal class DalamudInterface : IDisposable, IServiceType
|
|||
this.WindowSystem.AddWindow(this.titleScreenMenuWindow);
|
||||
this.WindowSystem.AddWindow(this.profilerWindow);
|
||||
this.WindowSystem.AddWindow(this.branchSwitcherWindow);
|
||||
this.WindowSystem.AddWindow(this.hitchSettingsWindow);
|
||||
|
||||
ImGuiManagedAsserts.AssertsEnabled = configuration.AssertsEnabledAtStartup;
|
||||
this.isImGuiDrawDevMenu = this.isImGuiDrawDevMenu || configuration.DevBarOpenAtStartup;
|
||||
|
|
@ -263,6 +266,15 @@ internal class DalamudInterface : IDisposable, IServiceType
|
|||
this.pluginWindow.BringToFront();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Opens the <see cref="PluginInstallerWindow"/> on the plugin installed.
|
||||
/// </summary>
|
||||
public void OpenPluginInstallerPluginInstalled()
|
||||
{
|
||||
this.pluginWindow.OpenInstalledPlugins();
|
||||
this.pluginWindow.BringToFront();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Opens the <see cref="PluginInstallerWindow"/> on the plugin changelogs.
|
||||
/// </summary>
|
||||
|
|
@ -307,6 +319,15 @@ internal class DalamudInterface : IDisposable, IServiceType
|
|||
this.profilerWindow.IsOpen = true;
|
||||
this.profilerWindow.BringToFront();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Opens the <see cref="HitchSettingsWindow"/>.
|
||||
/// </summary>
|
||||
public void OpenHitchSettings()
|
||||
{
|
||||
this.hitchSettingsWindow.IsOpen = true;
|
||||
this.hitchSettingsWindow.BringToFront();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Opens the <see cref="BranchSwitcherWindow"/>.
|
||||
|
|
@ -420,6 +441,15 @@ internal class DalamudInterface : IDisposable, IServiceType
|
|||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Sets the current search text for the plugin installer.
|
||||
/// </summary>
|
||||
/// <param name="text">The search term.</param>
|
||||
public void SetPluginInstallerSearchText(string text)
|
||||
{
|
||||
this.pluginWindow.SetSearchText(text);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Toggle the screen darkening effect used for the credits.
|
||||
/// </summary>
|
||||
|
|
@ -676,6 +706,11 @@ internal class DalamudInterface : IDisposable, IServiceType
|
|||
{
|
||||
this.OpenProfiler();
|
||||
}
|
||||
|
||||
if (ImGui.MenuItem("Open Hitch Settings"))
|
||||
{
|
||||
this.OpenHitchSettings();
|
||||
}
|
||||
|
||||
ImGui.Separator();
|
||||
|
||||
|
|
|
|||
|
|
@ -733,7 +733,7 @@ internal class InterfaceManager : IDisposable, IServiceType
|
|||
// FontAwesome icon font
|
||||
Log.Verbose("[FONT] SetupFonts - FontAwesome icon font");
|
||||
{
|
||||
var fontPathIcon = Path.Combine(dalamud.AssetDirectory.FullName, "UIRes", "FontAwesome5FreeSolid.otf");
|
||||
var fontPathIcon = Path.Combine(dalamud.AssetDirectory.FullName, "UIRes", "FontAwesomeFreeSolid.otf");
|
||||
if (!File.Exists(fontPathIcon))
|
||||
ShowFontError(fontPathIcon);
|
||||
|
||||
|
|
|
|||
|
|
@ -80,6 +80,14 @@ internal class DataWindow : Window
|
|||
private Hook<MessageBoxWDelegate>? messageBoxMinHook;
|
||||
private bool hookUseMinHook = false;
|
||||
|
||||
// FontAwesome
|
||||
private List<FontAwesomeIcon>? icons;
|
||||
private List<string> iconNames;
|
||||
private string[]? iconCategories;
|
||||
private int selectedIconCategory;
|
||||
private string iconSearchInput = string.Empty;
|
||||
private bool iconSearchChanged = true;
|
||||
|
||||
// IPC
|
||||
private ICallGateProvider<string, string> ipcPub;
|
||||
private ICallGateSubscriber<string, string> ipcSub;
|
||||
|
|
@ -149,7 +157,8 @@ internal class DataWindow : Window
|
|||
Address,
|
||||
Object_Table,
|
||||
Fate_Table,
|
||||
Font_Test,
|
||||
SE_Font_Test,
|
||||
FontAwesome_Test,
|
||||
Party_List,
|
||||
Buddy_List,
|
||||
Plugin_IPC,
|
||||
|
|
@ -270,8 +279,12 @@ internal class DataWindow : Window
|
|||
this.DrawFateTable();
|
||||
break;
|
||||
|
||||
case DataKind.Font_Test:
|
||||
this.DrawFontTest();
|
||||
case DataKind.SE_Font_Test:
|
||||
this.DrawSEFontTest();
|
||||
break;
|
||||
|
||||
case DataKind.FontAwesome_Test:
|
||||
this.DrawFontAwesomeTest();
|
||||
break;
|
||||
|
||||
case DataKind.Party_List:
|
||||
|
|
@ -573,7 +586,7 @@ internal class DataWindow : Window
|
|||
}
|
||||
}
|
||||
|
||||
private void DrawFontTest()
|
||||
private void DrawSEFontTest()
|
||||
{
|
||||
var specialChars = string.Empty;
|
||||
|
||||
|
|
@ -581,15 +594,45 @@ internal class DataWindow : Window
|
|||
specialChars += $"0x{i:X} - {(SeIconChar)i} - {(char)i}\n";
|
||||
|
||||
ImGui.TextUnformatted(specialChars);
|
||||
}
|
||||
|
||||
foreach (var fontAwesomeIcon in Enum.GetValues(typeof(FontAwesomeIcon)).Cast<FontAwesomeIcon>())
|
||||
private void DrawFontAwesomeTest()
|
||||
{
|
||||
this.iconCategories ??= FontAwesomeHelpers.GetCategories();
|
||||
|
||||
if (this.iconSearchChanged)
|
||||
{
|
||||
ImGui.Text(((int)fontAwesomeIcon.ToIconChar()).ToString("X") + " - ");
|
||||
ImGui.SameLine();
|
||||
this.icons = FontAwesomeHelpers.SearchIcons(this.iconSearchInput, this.iconCategories[this.selectedIconCategory]);
|
||||
this.iconNames = this.icons.Select(icon => Enum.GetName(icon)!).ToList();
|
||||
this.iconSearchChanged = false;
|
||||
}
|
||||
|
||||
ImGui.SetNextItemWidth(160f);
|
||||
var categoryIndex = this.selectedIconCategory;
|
||||
if (ImGui.Combo("####FontAwesomeCategorySearch", ref categoryIndex, this.iconCategories, this.iconCategories.Length))
|
||||
{
|
||||
this.selectedIconCategory = categoryIndex;
|
||||
this.iconSearchChanged = true;
|
||||
}
|
||||
|
||||
ImGui.SameLine(170f);
|
||||
ImGui.SetNextItemWidth(180f);
|
||||
if (ImGui.InputTextWithHint($"###FontAwesomeInputSearch", "search icons", ref this.iconSearchInput, 50))
|
||||
{
|
||||
this.iconSearchChanged = true;
|
||||
}
|
||||
|
||||
ImGuiHelpers.ScaledDummy(10f);
|
||||
for (var i = 0; i < this.icons?.Count; i++)
|
||||
{
|
||||
ImGui.Text($"0x{(int)this.icons[i].ToIconChar():X}");
|
||||
ImGuiHelpers.ScaledRelativeSameLine(50f);
|
||||
ImGui.Text($"{this.iconNames[i]}");
|
||||
ImGuiHelpers.ScaledRelativeSameLine(280f);
|
||||
ImGui.PushFont(UiBuilder.IconFont);
|
||||
ImGui.Text(fontAwesomeIcon.ToIconString());
|
||||
ImGui.Text(this.icons[i].ToIconString());
|
||||
ImGui.PopFont();
|
||||
ImGuiHelpers.ScaledDummy(2f);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
58
Dalamud/Interface/Internal/Windows/HitchSettingsWindow.cs
Normal file
58
Dalamud/Interface/Internal/Windows/HitchSettingsWindow.cs
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
using Dalamud.Configuration.Internal;
|
||||
using Dalamud.Interface.Windowing;
|
||||
using ImGuiNET;
|
||||
|
||||
namespace Dalamud.Interface.Internal.Windows;
|
||||
|
||||
/// <summary>
|
||||
/// Window responsible for hitch settings.
|
||||
/// </summary>
|
||||
public class HitchSettingsWindow : Window
|
||||
{
|
||||
private const float MinHitch = 1;
|
||||
private const float MaxHitch = 500;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="HitchSettingsWindow"/> class.
|
||||
/// </summary>
|
||||
public HitchSettingsWindow()
|
||||
: base("Hitch Settings", ImGuiWindowFlags.AlwaysAutoResize)
|
||||
{
|
||||
this.ShowCloseButton = true;
|
||||
this.RespectCloseHotkey = true;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void Draw()
|
||||
{
|
||||
var config = Service<DalamudConfiguration>.Get();
|
||||
|
||||
var uiBuilderHitch = (float)config.UiBuilderHitch;
|
||||
if (ImGui.SliderFloat("UiBuilderHitch", ref uiBuilderHitch, MinHitch, MaxHitch))
|
||||
{
|
||||
config.UiBuilderHitch = uiBuilderHitch;
|
||||
config.QueueSave();
|
||||
}
|
||||
|
||||
var frameworkUpdateHitch = (float)config.FrameworkUpdateHitch;
|
||||
if (ImGui.SliderFloat("FrameworkUpdateHitch", ref frameworkUpdateHitch, MinHitch, MaxHitch))
|
||||
{
|
||||
config.FrameworkUpdateHitch = frameworkUpdateHitch;
|
||||
config.QueueSave();
|
||||
}
|
||||
|
||||
var gameNetworkUpHitch = (float)config.GameNetworkUpHitch;
|
||||
if (ImGui.SliderFloat("GameNetworkUpHitch", ref gameNetworkUpHitch, MinHitch, MaxHitch))
|
||||
{
|
||||
config.GameNetworkUpHitch = gameNetworkUpHitch;
|
||||
config.QueueSave();
|
||||
}
|
||||
|
||||
var gameNetworkDownHitch = (float)config.GameNetworkDownHitch;
|
||||
if (ImGui.SliderFloat("GameNetworkDownHitch", ref gameNetworkDownHitch, MinHitch, MaxHitch))
|
||||
{
|
||||
config.GameNetworkDownHitch = gameNetworkDownHitch;
|
||||
config.QueueSave();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -97,6 +97,7 @@ internal class PluginInstallerWindow : Window, IDisposable
|
|||
private bool hasDevPlugins = false;
|
||||
|
||||
private string searchText = string.Empty;
|
||||
private bool isSearchTextPrefilled = false;
|
||||
|
||||
private PluginSortKind sortKind = PluginSortKind.Alphabetical;
|
||||
private string filterText = Locs.SortBy_Alphabetical;
|
||||
|
|
@ -202,7 +203,7 @@ internal class PluginInstallerWindow : Window, IDisposable
|
|||
|
||||
_ = pluginManager.ReloadPluginMastersAsync();
|
||||
|
||||
this.searchText = string.Empty;
|
||||
if (!this.isSearchTextPrefilled) this.searchText = string.Empty;
|
||||
this.sortKind = PluginSortKind.Alphabetical;
|
||||
this.filterText = Locs.SortBy_Alphabetical;
|
||||
|
||||
|
|
@ -218,6 +219,12 @@ internal class PluginInstallerWindow : Window, IDisposable
|
|||
public override void OnClose()
|
||||
{
|
||||
Service<DalamudConfiguration>.Get().QueueSave();
|
||||
|
||||
if (this.isSearchTextPrefilled)
|
||||
{
|
||||
this.isSearchTextPrefilled = false;
|
||||
this.searchText = string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
|
|
@ -244,6 +251,18 @@ internal class PluginInstallerWindow : Window, IDisposable
|
|||
this.imageCache.ClearIconCache();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Open the window on the plugin changelogs.
|
||||
/// </summary>
|
||||
public void OpenInstalledPlugins()
|
||||
{
|
||||
// Installed group
|
||||
this.categoryManager.CurrentGroupIdx = 1;
|
||||
// All category
|
||||
this.categoryManager.CurrentCategoryIdx = 0;
|
||||
this.IsOpen = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Open the window on the plugin changelogs.
|
||||
/// </summary>
|
||||
|
|
@ -256,6 +275,16 @@ internal class PluginInstallerWindow : Window, IDisposable
|
|||
this.IsOpen = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the current search text and marks it as prefilled.
|
||||
/// </summary>
|
||||
/// <param name="text">The search term.</param>
|
||||
public void SetSearchText(string text)
|
||||
{
|
||||
this.isSearchTextPrefilled = true;
|
||||
this.searchText = text;
|
||||
}
|
||||
|
||||
private void DrawProgressOverlay()
|
||||
{
|
||||
var pluginManager = Service<PluginManager>.Get();
|
||||
|
|
|
|||
|
|
@ -34,6 +34,9 @@ public sealed class UiBuilder : IDisposable
|
|||
private bool hasErrorWindow = false;
|
||||
private bool lastFrameUiHideState = false;
|
||||
|
||||
[ServiceManager.ServiceDependency]
|
||||
private readonly DalamudConfiguration configuration = Service<DalamudConfiguration>.Get();
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="UiBuilder"/> class and registers it.
|
||||
/// You do not have to call this manually.
|
||||
|
|
@ -42,7 +45,7 @@ public sealed class UiBuilder : IDisposable
|
|||
internal UiBuilder(string namespaceName)
|
||||
{
|
||||
this.stopwatch = new Stopwatch();
|
||||
this.hitchDetector = new HitchDetector($"UiBuilder({namespaceName})", 100);
|
||||
this.hitchDetector = new HitchDetector($"UiBuilder({namespaceName})", this.configuration.UiBuilderHitch);
|
||||
this.namespaceName = namespaceName;
|
||||
|
||||
this.interfaceManager.Draw += this.OnDraw;
|
||||
|
|
@ -86,13 +89,13 @@ public sealed class UiBuilder : IDisposable
|
|||
public event Action AfterBuildFonts;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets an action that is called when plugin UI or interface modifications are supposed to be hidden.
|
||||
/// Gets or sets an action that is called when plugin UI or interface modifications are supposed to be shown.
|
||||
/// These may be fired consecutively.
|
||||
/// </summary>
|
||||
public event Action ShowUi;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets an action that is called when plugin UI or interface modifications are supposed to be shown.
|
||||
/// Gets or sets an action that is called when plugin UI or interface modifications are supposed to be hidden.
|
||||
/// These may be fired consecutively.
|
||||
/// </summary>
|
||||
public event Action HideUi;
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ using Dalamud.Game.Text.SeStringHandling;
|
|||
using Dalamud.Game.Text.SeStringHandling.Payloads;
|
||||
using Dalamud.Interface;
|
||||
using Dalamud.Interface.Internal;
|
||||
using Dalamud.Interface.Internal.Windows.PluginInstaller;
|
||||
using Dalamud.Plugin.Internal;
|
||||
using Dalamud.Plugin.Internal.Types;
|
||||
using Dalamud.Plugin.Ipc;
|
||||
|
|
@ -199,6 +200,24 @@ public sealed class DalamudPluginInterface : IDisposable
|
|||
/// </summary>
|
||||
public List<string> PluginInternalNames => Service<PluginManager>.Get().InstalledPlugins.Select(p => p.Manifest.InternalName).ToList();
|
||||
|
||||
/// <summary>
|
||||
/// Opens the <see cref="PluginInstallerWindow"/> with the plugin name set as search target.
|
||||
/// </summary>
|
||||
/// <returns>Returns false if the DalamudInterface was null.</returns>
|
||||
public bool OpenPluginInstaller()
|
||||
{
|
||||
var dalamudInterface = Service<DalamudInterface>.GetNullable(); // Can be null during boot
|
||||
if (dalamudInterface == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
dalamudInterface.OpenPluginInstallerPluginInstalled();
|
||||
dalamudInterface.SetPluginInstallerSearchText(this.pluginName);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#region IPC
|
||||
|
||||
/// <inheritdoc cref="DataShare.GetOrCreateData{T}"/>
|
||||
|
|
|
|||
|
|
@ -1273,7 +1273,7 @@ Thanks and have fun!";
|
|||
Debug.Assert(this.bannedPlugins != null, "this.bannedPlugins != null");
|
||||
|
||||
if (this.LoadBannedPlugins)
|
||||
return true;
|
||||
return false;
|
||||
|
||||
var config = Service<DalamudConfiguration>.Get();
|
||||
|
||||
|
|
|
|||
|
|
@ -27,4 +27,14 @@ public static class EnumExtensions
|
|||
.OfType<TAttribute>()
|
||||
.SingleOrDefault();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets an indicator if enum has been flagged as obsolete (deprecated).
|
||||
/// </summary>
|
||||
/// <param name="value">The enum value that has an attached attribute.</param>
|
||||
/// <returns>Indicator if enum has been flagged as obsolete.</returns>
|
||||
public static bool IsObsolete(this Enum value)
|
||||
{
|
||||
return GetAttribute<ObsoleteAttribute>(value) != null;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Numerics;
|
||||
using FFXIVClientStructs.FFXIV.Client.Graphics;
|
||||
|
||||
namespace Dalamud.Utility.Numerics;
|
||||
|
||||
|
|
@ -53,4 +54,9 @@ public static class VectorExtensions
|
|||
{
|
||||
return new Vector2(v.X, y);
|
||||
}
|
||||
|
||||
public static ByteColor ToByteColor(this Vector4 v)
|
||||
{
|
||||
return new ByteColor { A = (byte)(v.W * 255), R = (byte)(v.X * 255), G = (byte)(v.Y * 255), B = (byte)(v.Z * 255) };
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,4 +14,18 @@ public static class SeStringExtensions
|
|||
/// <param name="originalString">The original Lumina SeString.</param>
|
||||
/// <returns>The re-parsed Dalamud SeString.</returns>
|
||||
public static SeString ToDalamudString(this Lumina.Text.SeString originalString) => SeString.Parse(originalString.RawData);
|
||||
|
||||
/// <summary>
|
||||
/// Validate if character name is valid.
|
||||
/// Both forename and surname must be between 2 and 15 characters and not total more than 20 characters combined.
|
||||
/// Only letters, hyphens, and apostrophes can be used.
|
||||
/// The first character of either name must be a letter.
|
||||
/// Hyphens cannot be used in succession or placed immediately before or after apostrophes.
|
||||
/// </summary>
|
||||
/// <param name="value">character name to validate.</param>
|
||||
/// <returns>indicator if character is name is valid.</returns>
|
||||
public static bool IsValidCharacterName(this SeString value)
|
||||
{
|
||||
return value.ToString().IsValidCharacterName();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
|
||||
namespace Dalamud.Utility;
|
||||
|
||||
|
|
@ -28,4 +29,38 @@ public static class StringExtensions
|
|||
/// <param name="value">The string to test.</param>
|
||||
/// <returns>true if the value parameter is null or an empty string (""), or if value consists exclusively of white-space characters.</returns>
|
||||
public static bool IsNullOrWhitespace([NotNullWhen(false)] this string? value) => string.IsNullOrWhiteSpace(value);
|
||||
|
||||
/// <summary>
|
||||
/// Validate if character name is valid.
|
||||
/// Both forename and surname must be between 2 and 15 characters and not total more than 20 characters combined.
|
||||
/// Only letters, hyphens, and apostrophes can be used.
|
||||
/// The first character of either name must be a letter.
|
||||
/// Hyphens cannot be used in succession or placed immediately before or after apostrophes.
|
||||
/// </summary>
|
||||
/// <param name="value">character name to validate.</param>
|
||||
/// <returns>indicator if character is name is valid.</returns>
|
||||
public static bool IsValidCharacterName(this string value)
|
||||
{
|
||||
if (string.IsNullOrEmpty(value)) return false;
|
||||
if (value.Length > 21) return false; // add 1 to allow for space
|
||||
var names = value.Split(' ');
|
||||
if (names.Length != 2) return false;
|
||||
var forename = names[0];
|
||||
var surname = names[1];
|
||||
if (!IsValidName(forename)) return false;
|
||||
if (!IsValidName(surname)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool IsValidName(string name)
|
||||
{
|
||||
if (name.Length is < 2 or > 15) return false;
|
||||
if (name.Any(c => !char.IsLetter(c) && !c.Equals('\'') && !c.Equals('-'))) return false;
|
||||
if (!char.IsLetter(name[0])) return false;
|
||||
if (!char.IsUpper(name[0])) return false;
|
||||
if (name.Contains("--")) return false;
|
||||
if (name.Contains("\'-")) return false;
|
||||
if (name.Contains("-\'")) return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit 5fc5e7bc33443af4b2c2c60168f576ffbcab8d1f
|
||||
Subproject commit a7f5dfa9dd3d4256cc561a4eed8972d78070c4d0
|
||||
Loading…
Add table
Add a link
Reference in a new issue