mirror of
https://github.com/goatcorp/Dalamud.git
synced 2026-02-19 06:17:43 +01:00
Merge remote-tracking branch 'origin/master' into v9-rollup
This commit is contained in:
commit
b384216d9d
8 changed files with 725 additions and 72 deletions
|
|
@ -1,3 +1,5 @@
|
|||
using System;
|
||||
|
||||
namespace Dalamud.Configuration.Internal;
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -14,4 +16,9 @@ internal sealed class DevPluginSettings
|
|||
/// Gets or sets a value indicating whether this plugin should automatically reload on file change.
|
||||
/// </summary>
|
||||
public bool AutomaticReloading { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets an ID uniquely identifying this specific instance of a devPlugin.
|
||||
/// </summary>
|
||||
public Guid WorkingPluginId { get; set; } = Guid.Empty;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
<AssemblyVersion>$(DalamudVersion)</AssemblyVersion>
|
||||
<Version>$(DalamudVersion)</Version>
|
||||
<FileVersion>$(DalamudVersion)</FileVersion>
|
||||
<PackageLicenseExpression>AGPL-3.0-or-later</PackageLicenseExpression>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Label="Output">
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ internal unsafe class AddonLifecycle : IDisposable, IServiceType
|
|||
|
||||
private delegate void AddonOnRequestedUpdateDelegate(AtkUnitBase* addon, NumberArrayData** numberArrayData, StringArrayData** stringArrayData);
|
||||
|
||||
private delegate void AddonOnRefreshDelegate(AtkUnitManager* unitManager, AtkUnitBase* addon, uint valueCount, AtkValue* values);
|
||||
private delegate byte AddonOnRefreshDelegate(AtkUnitManager* unitManager, AtkUnitBase* addon, uint valueCount, AtkValue* values);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Dispose()
|
||||
|
|
@ -221,7 +221,7 @@ internal unsafe class AddonLifecycle : IDisposable, IServiceType
|
|||
}
|
||||
}
|
||||
|
||||
private void OnAddonRefresh(AtkUnitManager* atkUnitManager, AtkUnitBase* addon, uint valueCount, AtkValue* values)
|
||||
private byte OnAddonRefresh(AtkUnitManager* atkUnitManager, AtkUnitBase* addon, uint valueCount, AtkValue* values)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
|
@ -232,7 +232,7 @@ internal unsafe class AddonLifecycle : IDisposable, IServiceType
|
|||
Log.Error(e, "Exception in OnAddonRefresh pre-refresh invoke.");
|
||||
}
|
||||
|
||||
this.onAddonRefreshHook.Original(atkUnitManager, addon, valueCount, values);
|
||||
var result = this.onAddonRefreshHook.Original(atkUnitManager, addon, valueCount, values);
|
||||
|
||||
try
|
||||
{
|
||||
|
|
@ -242,6 +242,8 @@ internal unsafe class AddonLifecycle : IDisposable, IServiceType
|
|||
{
|
||||
Log.Error(e, "Exception in OnAddonRefresh post-refresh invoke.");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private void OnRequestedUpdate(AtkUnitBase* addon, NumberArrayData** numberArrayData, StringArrayData** stringArrayData)
|
||||
|
|
|
|||
|
|
@ -172,6 +172,42 @@ internal class GameFontManager : IServiceType
|
|||
fontPtr.BuildLookupTable();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a glyph range for use with ImGui AddFont.
|
||||
/// </summary>
|
||||
/// <param name="family">Font family and size.</param>
|
||||
/// <param name="mergeDistance">Merge two ranges into one if distance is below the value specified in this parameter.</param>
|
||||
/// <returns>Glyph ranges.</returns>
|
||||
public GCHandle ToGlyphRanges(GameFontFamilyAndSize family, int mergeDistance = 8)
|
||||
{
|
||||
var fdt = this.fdts[(int)family]!;
|
||||
var ranges = new List<ushort>(fdt.Glyphs.Count)
|
||||
{
|
||||
checked((ushort)fdt.Glyphs[0].CharInt),
|
||||
checked((ushort)fdt.Glyphs[0].CharInt),
|
||||
};
|
||||
|
||||
foreach (var glyph in fdt.Glyphs.Skip(1))
|
||||
{
|
||||
var c32 = glyph.CharInt;
|
||||
if (c32 >= 0x10000)
|
||||
break;
|
||||
|
||||
var c16 = unchecked((ushort)c32);
|
||||
if (ranges[^1] + mergeDistance >= c16 && c16 > ranges[^1])
|
||||
{
|
||||
ranges[^1] = c16;
|
||||
}
|
||||
else if (ranges[^1] + 1 < c16)
|
||||
{
|
||||
ranges.Add(c16);
|
||||
ranges.Add(c16);
|
||||
}
|
||||
}
|
||||
|
||||
return GCHandle.Alloc(ranges.ToArray(), GCHandleType.Pinned);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new GameFontHandle, and increases internal font reference counter, and if it's first time use, then the font will be loaded on next font building process.
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -791,10 +791,10 @@ internal class InterfaceManager : IDisposable, IServiceType
|
|||
}
|
||||
else
|
||||
{
|
||||
var japaneseRangeHandle = GCHandle.Alloc(GlyphRangesJapanese.GlyphRanges, GCHandleType.Pinned);
|
||||
garbageList.Add(japaneseRangeHandle);
|
||||
var rangeHandle = gameFontManager.ToGlyphRanges(GameFontFamilyAndSize.Axis12);
|
||||
garbageList.Add(rangeHandle);
|
||||
|
||||
fontConfig.GlyphRanges = japaneseRangeHandle.AddrOfPinnedObject();
|
||||
fontConfig.GlyphRanges = rangeHandle.AddrOfPinnedObject();
|
||||
fontConfig.PixelSnapH = true;
|
||||
DefaultFont = ioFonts.AddFontFromFileTTF(fontPathJp, fontConfig.SizePixels, fontConfig);
|
||||
this.loadedFontInfo[DefaultFont] = fontInfo;
|
||||
|
|
@ -851,22 +851,19 @@ internal class InterfaceManager : IDisposable, IServiceType
|
|||
|
||||
foreach (var (fontSize, requests) in extraFontRequests)
|
||||
{
|
||||
List<Tuple<ushort, ushort>> codepointRanges = new();
|
||||
codepointRanges.Add(Tuple.Create(Fallback1Codepoint, Fallback1Codepoint));
|
||||
codepointRanges.Add(Tuple.Create(Fallback2Codepoint, Fallback2Codepoint));
|
||||
|
||||
// ImGui default ellipsis characters
|
||||
codepointRanges.Add(Tuple.Create<ushort, ushort>(0x2026, 0x2026));
|
||||
codepointRanges.Add(Tuple.Create<ushort, ushort>(0x0085, 0x0085));
|
||||
List<(ushort, ushort)> codepointRanges = new(4 + requests.Sum(x => x.CodepointRanges.Count))
|
||||
{
|
||||
new(Fallback1Codepoint, Fallback1Codepoint),
|
||||
new(Fallback2Codepoint, Fallback2Codepoint),
|
||||
// ImGui default ellipsis characters
|
||||
new(0x2026, 0x2026),
|
||||
new(0x0085, 0x0085),
|
||||
};
|
||||
|
||||
foreach (var request in requests)
|
||||
{
|
||||
foreach (var range in request.CodepointRanges)
|
||||
codepointRanges.Add(range);
|
||||
}
|
||||
|
||||
codepointRanges.Sort((x, y) => (x.Item1 == y.Item1 ? (x.Item2 < y.Item2 ? -1 : (x.Item2 == y.Item2 ? 0 : 1)) : (x.Item1 < y.Item1 ? -1 : 1)));
|
||||
codepointRanges.AddRange(request.CodepointRanges.Select(x => (From: x.Item1, To: x.Item2)));
|
||||
|
||||
codepointRanges.Sort();
|
||||
List<ushort> flattenedRanges = new();
|
||||
foreach (var range in codepointRanges)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
|
@ -40,6 +41,22 @@ internal class LocalDevPlugin : LocalPlugin, IDisposable
|
|||
configuration.DevPluginSettings[dllFile.FullName] = this.devSettings = new DevPluginSettings();
|
||||
configuration.QueueSave();
|
||||
}
|
||||
|
||||
// Legacy dev plugins might not have this!
|
||||
if (this.devSettings.WorkingPluginId == Guid.Empty)
|
||||
{
|
||||
this.devSettings.WorkingPluginId = Guid.NewGuid();
|
||||
Log.Verbose("{InternalName} was assigned new devPlugin GUID {Guid}", this.InternalName, this.devSettings.WorkingPluginId);
|
||||
configuration.QueueSave();
|
||||
}
|
||||
|
||||
// If the ID in the manifest is wrong, force the good one
|
||||
if (this.DevImposedWorkingPluginId != this.manifest.WorkingPluginId)
|
||||
{
|
||||
Debug.Assert(this.DevImposedWorkingPluginId != Guid.Empty, "Empty guid for devPlugin");
|
||||
this.manifest.WorkingPluginId = this.DevImposedWorkingPluginId;
|
||||
this.SaveManifest("dev imposed working plugin id");
|
||||
}
|
||||
|
||||
if (this.AutomaticReload)
|
||||
{
|
||||
|
|
@ -76,6 +93,11 @@ internal class LocalDevPlugin : LocalPlugin, IDisposable
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets an ID uniquely identifying this specific instance of a devPlugin.
|
||||
/// </summary>
|
||||
public Guid DevImposedWorkingPluginId => this.devSettings.WorkingPluginId;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public new void Dispose()
|
||||
|
|
|
|||
|
|
@ -26,6 +26,13 @@ namespace Dalamud.Plugin.Internal.Types;
|
|||
/// </summary>
|
||||
internal class LocalPlugin : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// The underlying manifest for this plugin.
|
||||
/// </summary>
|
||||
#pragma warning disable SA1401
|
||||
protected LocalPluginManifest manifest;
|
||||
#pragma warning restore SA1401
|
||||
|
||||
private static readonly ModuleLog Log = new("LOCALPLUGIN");
|
||||
|
||||
private readonly FileInfo manifestFile;
|
||||
|
|
@ -39,8 +46,6 @@ internal class LocalPlugin : IDisposable
|
|||
private Type? pluginType;
|
||||
private IDalamudPlugin? instance;
|
||||
|
||||
private LocalPluginManifest manifest;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="LocalPlugin"/> class.
|
||||
/// </summary>
|
||||
|
|
@ -659,9 +664,11 @@ internal class LocalPlugin : IDisposable
|
|||
var manifestPath = LocalPluginManifest.GetManifestFile(this.DllFile);
|
||||
if (manifestPath.Exists)
|
||||
{
|
||||
// var isDisabled = this.IsDisabled; // saving the internal state because it could have been deleted
|
||||
// Save some state that we do actually want to carry over
|
||||
var guid = this.manifest.WorkingPluginId;
|
||||
|
||||
this.manifest = LocalPluginManifest.Load(manifestPath) ?? throw new Exception("Could not reload manifest.");
|
||||
// this.manifest.Disabled = isDisabled;
|
||||
this.manifest.WorkingPluginId = guid;
|
||||
|
||||
this.SaveManifest("dev reload");
|
||||
}
|
||||
|
|
@ -686,6 +693,12 @@ internal class LocalPlugin : IDisposable
|
|||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Save this plugin manifest.
|
||||
/// </summary>
|
||||
/// <param name="reason">Why it should be saved.</param>
|
||||
protected void SaveManifest(string reason) => this.manifest.Save(this.manifestFile, reason);
|
||||
|
||||
private static void SetupLoaderConfig(LoaderConfig config)
|
||||
{
|
||||
config.IsUnloadable = true;
|
||||
|
|
@ -694,6 +707,4 @@ internal class LocalPlugin : IDisposable
|
|||
config.SharedAssemblies.Add(typeof(Lumina.GameData).Assembly.GetName());
|
||||
config.SharedAssemblies.Add(typeof(Lumina.Excel.ExcelSheetImpl).Assembly.GetName());
|
||||
}
|
||||
|
||||
private void SaveManifest(string reason) => this.manifest.Save(this.manifestFile, reason);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue