mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-12 18:27:23 +01:00
Merge pull request #1665 from Soreepeong/revert-1659-feature/font-hash-warning
Revert "Warn if font files' hashes are unexpected"
This commit is contained in:
commit
56ff4b4c8c
2 changed files with 17 additions and 216 deletions
|
|
@ -4,7 +4,6 @@ using System.Linq;
|
|||
using System.Numerics;
|
||||
|
||||
using Dalamud.Interface.Colors;
|
||||
using Dalamud.Interface.ManagedFontAtlas;
|
||||
using Dalamud.Interface.Utility;
|
||||
using Dalamud.Utility;
|
||||
using ImGuiNET;
|
||||
|
|
@ -69,22 +68,15 @@ internal class NotificationManager : IServiceType
|
|||
/// <param name="title">The title of the notification.</param>
|
||||
/// <param name="type">The type of the notification.</param>
|
||||
/// <param name="msDelay">The time the notification should be displayed for.</param>
|
||||
/// <returns>The added notification.</returns>
|
||||
public Notification AddNotification(
|
||||
string content,
|
||||
string? title = null,
|
||||
NotificationType type = NotificationType.None,
|
||||
uint msDelay = NotifyDefaultDismiss)
|
||||
public void AddNotification(string content, string? title = null, NotificationType type = NotificationType.None, uint msDelay = NotifyDefaultDismiss)
|
||||
{
|
||||
var n = new Notification
|
||||
this.notifications.Add(new Notification
|
||||
{
|
||||
Content = content,
|
||||
Title = title,
|
||||
NotificationType = type,
|
||||
DurationMs = msDelay,
|
||||
};
|
||||
this.notifications.Add(n);
|
||||
return n;
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -105,10 +97,6 @@ internal class NotificationManager : IServiceType
|
|||
continue;
|
||||
}
|
||||
|
||||
using var pushedFont = tn.UseMonospaceFont
|
||||
? Service<InterfaceManager>.Get().MonoFontHandle?.Push()
|
||||
: null;
|
||||
|
||||
var opacity = tn.GetFadePercent();
|
||||
|
||||
var iconColor = tn.Color;
|
||||
|
|
@ -119,12 +107,8 @@ internal class NotificationManager : IServiceType
|
|||
ImGuiHelpers.ForceNextWindowMainViewport();
|
||||
ImGui.SetNextWindowBgAlpha(opacity);
|
||||
ImGui.SetNextWindowPos(ImGuiHelpers.MainViewport.Pos + new Vector2(viewportSize.X - NotifyPaddingX, viewportSize.Y - NotifyPaddingY - height), ImGuiCond.Always, Vector2.One);
|
||||
if (tn.Actions.Count == 0)
|
||||
ImGui.Begin(windowName, NotifyToastFlags);
|
||||
else
|
||||
ImGui.Begin(windowName, NotifyToastFlags & ~ImGuiWindowFlags.NoInputs);
|
||||
ImGui.Begin(windowName, NotifyToastFlags);
|
||||
|
||||
ImGui.PushID(tn.NotificationId);
|
||||
ImGui.PushTextWrapPos(viewportSize.X / 3.0f);
|
||||
|
||||
var wasTitleRendered = false;
|
||||
|
|
@ -178,22 +162,10 @@ internal class NotificationManager : IServiceType
|
|||
ImGui.TextUnformatted(tn.Content);
|
||||
}
|
||||
|
||||
foreach (var (caption, action) in tn.Actions)
|
||||
{
|
||||
if (ImGui.Button(caption))
|
||||
action.InvokeSafely();
|
||||
ImGui.SameLine();
|
||||
}
|
||||
|
||||
// break ImGui.SameLine();
|
||||
ImGui.TextUnformatted(string.Empty);
|
||||
|
||||
ImGui.PopStyleColor();
|
||||
|
||||
ImGui.PopTextWrapPos();
|
||||
|
||||
ImGui.PopID();
|
||||
|
||||
height += ImGui.GetWindowHeight() + NotifyPaddingMessageY;
|
||||
|
||||
ImGui.End();
|
||||
|
|
@ -205,8 +177,6 @@ internal class NotificationManager : IServiceType
|
|||
/// </summary>
|
||||
internal class Notification
|
||||
{
|
||||
private static int notificationIdCounter;
|
||||
|
||||
/// <summary>
|
||||
/// Possible notification phases.
|
||||
/// </summary>
|
||||
|
|
@ -233,40 +203,20 @@ internal class NotificationManager : IServiceType
|
|||
Expired,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the notification ID.
|
||||
/// </summary>
|
||||
internal int NotificationId { get; } = notificationIdCounter++;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the type of the notification.
|
||||
/// </summary>
|
||||
internal NotificationType NotificationType { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether to force the use of monospace font.
|
||||
/// Gets the title of the notification.
|
||||
/// </summary>
|
||||
internal bool UseMonospaceFont { get; set; }
|
||||
internal string? Title { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the action buttons to attach to this notification.
|
||||
/// Gets the content of the notification.
|
||||
/// </summary>
|
||||
internal List<(string Text, Action ClickCallback)> Actions { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this notification has been dismissed.
|
||||
/// </summary>
|
||||
internal bool Dismissed { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the title of the notification.
|
||||
/// </summary>
|
||||
internal string? Title { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the content of the notification.
|
||||
/// </summary>
|
||||
internal string? Content { get; set; }
|
||||
internal string Content { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the duration of the notification in milliseconds.
|
||||
|
|
@ -333,7 +283,7 @@ internal class NotificationManager : IServiceType
|
|||
{
|
||||
var elapsed = (int)this.ElapsedTime.TotalMilliseconds;
|
||||
|
||||
if (elapsed > NotifyFadeInOutTime + this.DurationMs + NotifyFadeInOutTime || this.Dismissed)
|
||||
if (elapsed > NotifyFadeInOutTime + this.DurationMs + NotifyFadeInOutTime)
|
||||
return Phase.Expired;
|
||||
else if (elapsed > NotifyFadeInOutTime + this.DurationMs)
|
||||
return Phase.FadeOut;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
using System.Buffers;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
|
@ -9,13 +8,9 @@ using System.Threading.Tasks;
|
|||
using Dalamud.Configuration.Internal;
|
||||
using Dalamud.Data;
|
||||
using Dalamud.Game;
|
||||
using Dalamud.Game.ClientState;
|
||||
using Dalamud.Game.Gui;
|
||||
using Dalamud.Interface.FontIdentifier;
|
||||
using Dalamud.Interface.GameFonts;
|
||||
using Dalamud.Interface.Internal;
|
||||
using Dalamud.Interface.Internal.Notifications;
|
||||
using Dalamud.Plugin.Services;
|
||||
using Dalamud.Storage.Assets;
|
||||
using Dalamud.Utility;
|
||||
|
||||
|
|
@ -23,11 +18,7 @@ using ImGuiNET;
|
|||
|
||||
using ImGuiScene;
|
||||
|
||||
using Lumina.Data;
|
||||
using Lumina.Data.Files;
|
||||
using Lumina.Misc;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
|
||||
using SharpDX;
|
||||
using SharpDX.Direct3D11;
|
||||
|
|
@ -42,43 +33,9 @@ namespace Dalamud.Interface.ManagedFontAtlas.Internals;
|
|||
internal sealed partial class FontAtlasFactory
|
||||
: IServiceType, GamePrebakedFontHandle.IGameFontTextureProvider, IDisposable
|
||||
{
|
||||
private static readonly Dictionary<string, uint> KnownFontFileDataHashes = new()
|
||||
{
|
||||
["common/font/AXIS_96.fdt"] = 1486212503,
|
||||
["common/font/AXIS_12.fdt"] = 1370045105,
|
||||
["common/font/AXIS_14.fdt"] = 645957730,
|
||||
["common/font/AXIS_18.fdt"] = 899094094,
|
||||
["common/font/AXIS_36.fdt"] = 2537048938,
|
||||
["common/font/Jupiter_16.fdt"] = 1642196098,
|
||||
["common/font/Jupiter_20.fdt"] = 3053628263,
|
||||
["common/font/Jupiter_23.fdt"] = 1536194944,
|
||||
["common/font/Jupiter_45.fdt"] = 3473589216,
|
||||
["common/font/Jupiter_46.fdt"] = 1370962087,
|
||||
["common/font/Jupiter_90.fdt"] = 3661420529,
|
||||
["common/font/Meidinger_16.fdt"] = 3700692128,
|
||||
["common/font/Meidinger_20.fdt"] = 441419856,
|
||||
["common/font/Meidinger_40.fdt"] = 203848091,
|
||||
["common/font/MiedingerMid_10.fdt"] = 499375313,
|
||||
["common/font/MiedingerMid_12.fdt"] = 1925552591,
|
||||
["common/font/MiedingerMid_14.fdt"] = 1919733827,
|
||||
["common/font/MiedingerMid_18.fdt"] = 1635778987,
|
||||
["common/font/MiedingerMid_36.fdt"] = 1190559864,
|
||||
["common/font/TrumpGothic_184.fdt"] = 973994576,
|
||||
["common/font/TrumpGothic_23.fdt"] = 1967289381,
|
||||
["common/font/TrumpGothic_34.fdt"] = 1777971886,
|
||||
["common/font/TrumpGothic_68.fdt"] = 1170173741,
|
||||
["common/font/font0.tex"] = 514269927,
|
||||
["common/font/font1.tex"] = 3616607606,
|
||||
["common/font/font2.tex"] = 4166651000,
|
||||
["common/font/font3.tex"] = 1264942640,
|
||||
["common/font/font4.tex"] = 3534300885,
|
||||
["common/font/font5.tex"] = 1041916216,
|
||||
["common/font/font6.tex"] = 1247097672,
|
||||
};
|
||||
|
||||
private readonly DisposeSafety.ScopedFinalizer scopedFinalizer = new();
|
||||
private readonly CancellationTokenSource cancellationTokenSource = new();
|
||||
private readonly IReadOnlyDictionary<GameFontFamilyAndSize, Task<FileResource>> fdtFiles;
|
||||
private readonly IReadOnlyDictionary<GameFontFamilyAndSize, Task<byte[]>> fdtFiles;
|
||||
private readonly IReadOnlyDictionary<string, Task<Task<TexFile>[]>> texFiles;
|
||||
private readonly IReadOnlyDictionary<string, Task<IDalamudTextureWrap?[]>> prebakedTextureWraps;
|
||||
private readonly Task<ushort[]> defaultGlyphRanges;
|
||||
|
|
@ -110,7 +67,7 @@ internal sealed partial class FontAtlasFactory
|
|||
|
||||
this.fdtFiles = gffasInfo.ToImmutableDictionary(
|
||||
x => x.Font,
|
||||
x => Task.Run(() => dataManager.GetFile(x.Attr.Path)!));
|
||||
x => Task.Run(() => dataManager.GetFile(x.Attr.Path)!.Data));
|
||||
var channelCountsTask = texPaths.ToImmutableDictionary(
|
||||
x => x,
|
||||
x => Task.WhenAll(
|
||||
|
|
@ -122,8 +79,8 @@ internal sealed partial class FontAtlasFactory
|
|||
{
|
||||
unsafe
|
||||
{
|
||||
using var pin = file.Data.AsMemory().Pin();
|
||||
var fdt = new FdtFileView(pin.Pointer, file.Data.Length);
|
||||
using var pin = file.AsMemory().Pin();
|
||||
var fdt = new FdtFileView(pin.Pointer, file.Length);
|
||||
return fdt.MaxTextureIndex;
|
||||
}
|
||||
})));
|
||||
|
|
@ -144,13 +101,11 @@ internal sealed partial class FontAtlasFactory
|
|||
{
|
||||
unsafe
|
||||
{
|
||||
using var pin = file.Result.Data.AsMemory().Pin();
|
||||
var fdt = new FdtFileView(pin.Pointer, file.Result.Data.Length);
|
||||
using var pin = file.Result.AsMemory().Pin();
|
||||
var fdt = new FdtFileView(pin.Pointer, file.Result.Length);
|
||||
return fdt.ToGlyphRanges();
|
||||
}
|
||||
});
|
||||
|
||||
Task.Run(this.CheckSanity);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -248,12 +203,12 @@ internal sealed partial class FontAtlasFactory
|
|||
/// </summary>
|
||||
/// <param name="gffas">The font family and size.</param>
|
||||
/// <returns>The <see cref="FdtReader"/>.</returns>
|
||||
public FdtReader GetFdtReader(GameFontFamilyAndSize gffas) => new(ExtractResult(this.fdtFiles[gffas]).Data);
|
||||
public FdtReader GetFdtReader(GameFontFamilyAndSize gffas) => new(ExtractResult(this.fdtFiles[gffas]));
|
||||
|
||||
/// <inheritdoc/>
|
||||
public unsafe MemoryHandle CreateFdtFileView(GameFontFamilyAndSize gffas, out FdtFileView fdtFileView)
|
||||
{
|
||||
var arr = ExtractResult(this.fdtFiles[gffas]).Data;
|
||||
var arr = ExtractResult(this.fdtFiles[gffas]);
|
||||
var handle = arr.AsMemory().Pin();
|
||||
try
|
||||
{
|
||||
|
|
@ -385,110 +340,6 @@ internal sealed partial class FontAtlasFactory
|
|||
}
|
||||
}
|
||||
|
||||
private async Task CheckSanity()
|
||||
{
|
||||
var invalidFiles = new Dictionary<string, Exception>();
|
||||
var texFileTasks = new Dictionary<string, Task<TexFile>>();
|
||||
var foundHashes = new Dictionary<string, uint>();
|
||||
foreach (var (gffas, fdtTask) in this.fdtFiles)
|
||||
{
|
||||
var fontAttr = gffas.GetAttribute<GameFontFamilyAndSizeAttribute>()!;
|
||||
try
|
||||
{
|
||||
foundHashes[fontAttr.Path] = Crc32.Get((await fdtTask).Data);
|
||||
|
||||
foreach (var (task, index) in
|
||||
(await this.texFiles[fontAttr.TexPathFormat]).Select((x, i) => (x, i)))
|
||||
texFileTasks[fontAttr.TexPathFormat.Format(index)] = task;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
invalidFiles[fontAttr.Path] = e;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var (path, texTask) in texFileTasks)
|
||||
{
|
||||
try
|
||||
{
|
||||
var hc = default(HashCode);
|
||||
hc.AddBytes((await texTask).Data);
|
||||
foundHashes[path] = Crc32.Get((await texTask).Data);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
invalidFiles[path] = e;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var (path, hashCode) in foundHashes)
|
||||
{
|
||||
if (!KnownFontFileDataHashes.TryGetValue(path, out var expectedHashCode))
|
||||
continue;
|
||||
if (expectedHashCode != hashCode)
|
||||
{
|
||||
invalidFiles[path] = new InvalidDataException(
|
||||
$"Expected 0x{expectedHashCode:X08}; got 0x{hashCode:X08}");
|
||||
}
|
||||
}
|
||||
|
||||
var dconf = await Service<DalamudConfiguration>.GetAsync();
|
||||
var nm = await Service<NotificationManager>.GetAsync();
|
||||
var intm = (await Service<InterfaceManager.InterfaceManagerWithScene>.GetAsync()).Manager;
|
||||
var ggui = await Service<GameGui>.GetAsync();
|
||||
var cstate = await Service<ClientState>.GetAsync();
|
||||
|
||||
if (invalidFiles.Any())
|
||||
{
|
||||
Log.Warning("Found {n} font related file(s) with unexpected hash code values.", invalidFiles.Count);
|
||||
foreach (var (path, ex) in invalidFiles)
|
||||
Log.Warning(ex, "\t=> {path}", path);
|
||||
Log.Verbose(JsonConvert.SerializeObject(foundHashes));
|
||||
if (this.DefaultFontSpec is not SingleFontSpec { FontId: GameFontAndFamilyId })
|
||||
return;
|
||||
|
||||
this.Framework.Update += FrameworkOnUpdate;
|
||||
|
||||
void FrameworkOnUpdate(IFramework framework)
|
||||
{
|
||||
var charaSelect = ggui.GetAddonByName("CharaSelect", 1);
|
||||
var charaMake = ggui.GetAddonByName("CharaMake", 1);
|
||||
var titleDcWorldMap = ggui.GetAddonByName("TitleDCWorldMap", 1);
|
||||
|
||||
// Show notification when TSM is visible, so that user can check whether a font looks bad
|
||||
if (cstate.IsLoggedIn
|
||||
|| charaMake != IntPtr.Zero
|
||||
|| charaSelect != IntPtr.Zero
|
||||
|| titleDcWorldMap != IntPtr.Zero)
|
||||
return;
|
||||
|
||||
this.Framework.Update -= FrameworkOnUpdate;
|
||||
|
||||
var n = nm.AddNotification(
|
||||
"Non-default game fonts detected. If things do not look right, you can use a different font. Running repairs from XIVLauncher is recommended.",
|
||||
"Modded font warning",
|
||||
NotificationType.Warning,
|
||||
10000);
|
||||
n.UseMonospaceFont = true;
|
||||
n.Actions.Add(
|
||||
(
|
||||
"Use Noto Sans",
|
||||
() =>
|
||||
{
|
||||
dconf.DefaultFontSpec =
|
||||
new SingleFontSpec
|
||||
{
|
||||
FontId = new DalamudAssetFontAndFamilyId(DalamudAsset.NotoSansJpMedium),
|
||||
SizePx = 17,
|
||||
};
|
||||
dconf.QueueSave();
|
||||
intm.RebuildFonts();
|
||||
}));
|
||||
n.Actions.Add(("Dismiss", () => n.Dismissed = true));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private IDalamudTextureWrap GetChannelTexture(string texPathFormat, int fileIndex, int channelIndex)
|
||||
{
|
||||
var texFile = ExtractResult(ExtractResult(this.texFiles[texPathFormat])[fileIndex]);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue