LLib/DataManagerExtensions.cs

151 lines
5.0 KiB
C#
Raw Normal View History

2023-10-13 20:01:58 +00:00
using System;
2024-11-15 21:32:13 +00:00
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
2023-10-13 20:01:58 +00:00
using System.Linq;
using System.Text.RegularExpressions;
2024-11-15 21:32:13 +00:00
using Dalamud.Game.Text.SeStringHandling.Payloads;
2023-10-13 20:01:58 +00:00
using Dalamud.Plugin.Services;
2024-11-15 21:32:13 +00:00
using Dalamud.Utility;
2023-10-13 20:01:58 +00:00
using Lumina.Excel;
2024-11-15 21:32:13 +00:00
using Lumina.Excel.Sheets;
2023-10-13 20:01:58 +00:00
using Lumina.Text;
using Lumina.Text.Payloads;
2024-11-15 21:32:13 +00:00
using Lumina.Text.ReadOnly;
2023-10-13 20:01:58 +00:00
namespace LLib;
public static class DataManagerExtensions
{
2024-11-16 13:36:45 +00:00
public static ReadOnlySeString? GetSeString<T>(this IDataManager dataManager, string key)
where T : struct, IQuestDialogueText, IExcelRow<T>
2023-10-13 20:01:58 +00:00
{
2024-03-20 18:10:35 +00:00
ArgumentNullException.ThrowIfNull(dataManager);
2024-11-16 13:36:45 +00:00
return dataManager.GetExcelSheet<T>()
.Cast<T?>()
.SingleOrDefault(x => x!.Value.Key == key)
?.Value;
2023-10-19 18:45:14 +00:00
}
public static string? GetString<T>(this IDataManager dataManager, string key, IPluginLog? pluginLog)
2024-11-16 13:36:45 +00:00
where T : struct, IQuestDialogueText, IExcelRow<T>
2023-10-19 18:45:14 +00:00
{
string? text = GetSeString<T>(dataManager, key)?.WithCertainMacroCodeReplacements();
2023-10-19 18:45:14 +00:00
pluginLog?.Verbose($"{typeof(T).Name}.{key} => {text}");
return text;
}
public static Regex? GetRegex<T>(this IDataManager dataManager, string key, IPluginLog? pluginLog)
2024-11-16 13:36:45 +00:00
where T : struct, IQuestDialogueText, IExcelRow<T>
2023-10-19 18:45:14 +00:00
{
2024-11-16 13:36:45 +00:00
ReadOnlySeString? text = GetSeString<T>(dataManager, key);
2023-10-19 18:45:14 +00:00
if (text == null)
return null;
2024-11-16 13:36:45 +00:00
string regex = string.Join("", text.Select((ReadOnlySePayload payload) =>
2023-10-19 18:45:14 +00:00
{
2024-11-16 13:36:45 +00:00
if (payload.Type == ReadOnlySePayloadType.Text)
return Regex.Escape(payload.ToString());
2023-10-19 18:45:14 +00:00
else
2023-10-21 10:32:21 +00:00
return "(.*)";
2023-10-19 18:45:14 +00:00
}));
pluginLog?.Verbose($"{typeof(T).Name}.{key} => /{regex}/");
return new Regex(regex);
2023-10-13 20:01:58 +00:00
}
2024-11-15 21:32:13 +00:00
public static ReadOnlySeString? GetSeString<T>(this IDataManager dataManager, uint rowId, Func<T, ReadOnlySeString?> mapper)
where T : struct, IExcelRow<T>
2023-10-13 20:01:58 +00:00
{
2024-03-20 18:10:35 +00:00
ArgumentNullException.ThrowIfNull(dataManager);
ArgumentNullException.ThrowIfNull(mapper);
2024-11-15 21:32:13 +00:00
var row = dataManager.GetExcelSheet<T>().GetRowOrDefault(rowId);
2023-10-13 20:01:58 +00:00
if (row == null)
return null;
2024-11-15 21:32:13 +00:00
return mapper(row.Value);
2023-10-13 20:01:58 +00:00
}
2024-11-15 21:32:13 +00:00
public static string? GetString<T>(this IDataManager dataManager, uint rowId, Func<T, ReadOnlySeString?> mapper,
2024-03-20 18:10:35 +00:00
IPluginLog? pluginLog = null)
2024-11-15 21:32:13 +00:00
where T : struct, IExcelRow<T>
2023-10-13 20:01:58 +00:00
{
string? text = GetSeString(dataManager, rowId, mapper)?.WithCertainMacroCodeReplacements();
2023-10-13 20:01:58 +00:00
pluginLog?.Verbose($"{typeof(T).Name}.{rowId} => {text}");
return text;
}
2024-11-15 21:32:13 +00:00
public static Regex? GetRegex<T>(this IDataManager dataManager, uint rowId, Func<T, ReadOnlySeString?> mapper,
2024-03-20 18:10:35 +00:00
IPluginLog? pluginLog = null)
2024-11-15 21:32:13 +00:00
where T : struct, IExcelRow<T>
2023-10-13 20:01:58 +00:00
{
2024-11-15 21:32:13 +00:00
ReadOnlySeString? text = GetSeString(dataManager, rowId, mapper);
2023-10-13 20:01:58 +00:00
if (text == null)
return null;
2024-08-05 13:44:45 +00:00
Regex regex = text.ToRegex();
2023-10-13 20:01:58 +00:00
pluginLog?.Verbose($"{typeof(T).Name}.{rowId} => /{regex}/");
2024-08-05 13:44:45 +00:00
return regex;
2023-10-13 20:01:58 +00:00
}
2023-10-21 10:32:21 +00:00
2024-11-15 21:32:13 +00:00
public static Regex? GetRegex<T>(this T excelRow, Func<T, ReadOnlySeString?> mapper, IPluginLog? pluginLog)
where T : struct, IExcelRow<T>
2023-10-21 10:32:21 +00:00
{
2024-03-20 18:10:35 +00:00
ArgumentNullException.ThrowIfNull(excelRow);
ArgumentNullException.ThrowIfNull(mapper);
2024-11-15 21:32:13 +00:00
ReadOnlySeString? text = mapper(excelRow);
2023-10-21 10:32:21 +00:00
if (text == null)
return null;
2024-08-05 13:44:45 +00:00
Regex regex = text.ToRegex();
pluginLog?.Verbose($"{typeof(T).Name}.regex => /{regex}/");
return regex;
}
2024-11-15 21:32:13 +00:00
public static Regex ToRegex(this ReadOnlySeString? text)
2024-08-05 13:44:45 +00:00
{
ArgumentNullException.ThrowIfNull(text);
2024-11-15 21:32:13 +00:00
return new Regex(string.Join("", text.Value.Select(payload =>
2023-10-21 10:32:21 +00:00
{
2024-11-15 21:32:13 +00:00
if (payload.Type == ReadOnlySePayloadType.Text)
return Regex.Escape(payload.ToString());
2023-10-21 10:32:21 +00:00
else
return "(.*)";
2024-08-05 13:44:45 +00:00
})));
2023-10-21 10:32:21 +00:00
}
public static string WithCertainMacroCodeReplacements(this ReadOnlySeString text)
{
return string.Join("", text.Select(payload =>
{
if (payload.Type == ReadOnlySePayloadType.Text)
return Regex.Escape(payload.ToString());
else if (payload is { Type: ReadOnlySePayloadType.Macro, MacroCode: MacroCode.NewLine })
return "";
else
return payload.ToString();
}));
}
2023-10-13 20:01:58 +00:00
}
2024-11-15 21:32:13 +00:00
2024-11-16 13:36:45 +00:00
public interface IQuestDialogueText
{
public ReadOnlySeString Key { get; }
public ReadOnlySeString Value { get; }
}
2024-11-15 21:32:13 +00:00
[SuppressMessage("Performance", "CA1815")]
2024-11-17 01:12:02 +00:00
[Sheet("PleaseSpecifyTheSheetExplicitly")]
2024-11-16 13:36:45 +00:00
public readonly struct QuestDialogueText(ExcelPage page, uint offset, uint row) : IQuestDialogueText, IExcelRow<QuestDialogueText>
2024-11-15 21:32:13 +00:00
{
public uint RowId => row;
public ReadOnlySeString Key => page.ReadString(offset, offset);
public ReadOnlySeString Value => page.ReadString(offset + 4, offset);
static QuestDialogueText IExcelRow<QuestDialogueText>.Create(ExcelPage page, uint offset, uint row) =>
new(page, offset, row);
}