Projektdateien hinzufügen.

This commit is contained in:
2022-11-04 17:57:03 +01:00
parent d1f29939f6
commit 4741d8c437
38 changed files with 1776 additions and 0 deletions

View File

@@ -0,0 +1,24 @@
using Dalamud.Game.Text.SeStringHandling;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Pilz.Dalamud.Tools.Strings
{
public class StringChange
{
/// <summary>
/// The payloads to use for inserting/replacing.
/// </summary>
public List<Payload> Payloads { get; init; } = new();
/// <summary>
/// Defines if only one anchor payload should be used, if using anchor payloads.
/// With this true the single anchor payload will be used in StringUpdateFactory instead of the anchor payload list.
/// Not needed to be true for the most cases.
/// </summary>
public bool ForceUsingSingleAnchorPayload { get; set; } = false;
}
}

View File

@@ -0,0 +1,40 @@
using Dalamud.Game.Text.SeStringHandling;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Pilz.Dalamud.Tools.Strings
{
public class StringChanges
{
private readonly Dictionary<StringPosition, StringChange> changes = new();
public StringChanges()
{
changes.Add(StringPosition.Before, new StringChange());
changes.Add(StringPosition.After, new StringChange());
changes.Add(StringPosition.Replace, new StringChange());
}
/// <summary>
/// Gets a change of the position of your choice where you can add your payloads.
/// </summary>
/// <param name="position">The position of your choice.</param>
/// <returns></returns>
public StringChange GetChange(StringPosition position)
{
return changes[position];
}
/// <summary>
/// Checks if there is any string change listed.
/// </summary>
/// <returns></returns>
public bool Any()
{
return changes.Sum(n => n.Value.Payloads.Count) != 0;
}
}
}

View File

@@ -0,0 +1,31 @@
using Dalamud.Game.ClientState.Objects.Types;
using Dalamud.Game.Text.SeStringHandling;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Pilz.Dalamud.Tools.Strings
{
public class StringChangesProps
{
/// <summary>
/// The string where the changes should be applied.
/// </summary>
public SeString Destination { get; set; }
/// <summary>
/// The changes that should be applied to the destination.
/// </summary>
public StringChanges StringChanges { get; set; }
/// <summary>
/// Payloads to use as anchor where the changes should be applied to.
/// </summary>
public List<Payload> AnchorPayloads { get; set; }
/// <summary>
/// A single payload to use as anchor where the changes should be applied to.
/// This property will only be used if StringChange.ForceSingleAnchorPayload is true.
/// </summary>
public Payload AnchorPayload { get; set; }
}
}

View File

@@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Pilz.Dalamud.Tools.Strings
{
public enum StringPosition
{
Before,
After,
Replace
}
}

View File

@@ -0,0 +1,132 @@
using Dalamud.Game.Text.SeStringHandling;
using Dalamud.Game.Text.SeStringHandling.Payloads;
using Lumina.Text;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Pilz.Dalamud.Tools.Strings
{
public static class StringUpdateFactory
{
public static void ApplyStringChanges(StringChangesProps props)
{
if (props.StringChanges.Any())
{
var seString = props.Destination;
List<StringPosition> stringPositionsOrdered = GetOrderedStringPositions(props);
foreach (var stringPosition in stringPositionsOrdered)
{
var stringChange = props.StringChanges.GetChange(stringPosition);
if (stringChange != null && stringChange.Payloads.Any())
{
AddSpacesBetweenTextPayloads(stringChange.Payloads, stringPosition);
if (stringPosition == StringPosition.Before)
{
Payload anchorFirst = stringChange.ForceUsingSingleAnchorPayload ? props.AnchorPayload : props.AnchorPayloads?.FirstOrDefault();
if (anchorFirst != null)
{
var anchorPayloadIndex = seString.Payloads.IndexOf(anchorFirst);
seString.Payloads.InsertRange(anchorPayloadIndex, stringChange.Payloads);
}
else
seString.Payloads.InsertRange(0, stringChange.Payloads);
}
else if (stringPosition == StringPosition.After)
{
Payload anchorLast = stringChange.ForceUsingSingleAnchorPayload ? props.AnchorPayload : props.AnchorPayloads?.LastOrDefault();
if (anchorLast != null)
{
var anchorPayloadIndex = seString.Payloads.IndexOf(anchorLast);
seString.Payloads.InsertRange(anchorPayloadIndex + 1, stringChange.Payloads);
}
else
seString.Payloads.AddRange(stringChange.Payloads);
}
else if (stringPosition == StringPosition.Replace)
{
Payload anchorReplace = props.AnchorPayload;
if (anchorReplace != null)
{
var anchorPayloadIndex = seString.Payloads.IndexOf(anchorReplace);
seString.Payloads.InsertRange(anchorPayloadIndex, stringChange.Payloads);
seString.Remove(anchorReplace);
}
else
{
seString.Payloads.Clear();
seString.Payloads.AddRange(stringChange.Payloads);
}
}
}
}
}
}
private static void AddSpacesBetweenTextPayloads(List<Payload> payloads, StringPosition tagPosition)
{
if (payloads != null && payloads.Any())
{
var indicesToInsertSpacesAt = new List<int>();
var lastTextPayloadIndex = -1;
static TextPayload getNewTextPayload() => new(" ");
foreach (var payload in payloads.Reverse<Payload>())
{
if (payload is IconPayload iconPayload)
lastTextPayloadIndex = -1;
else if (payload is TextPayload textPayload)
{
if (lastTextPayloadIndex != -1)
indicesToInsertSpacesAt.Add(payloads.IndexOf(textPayload) + 1);
lastTextPayloadIndex = payloads.IndexOf(textPayload);
}
}
foreach (var indexToInsertSpaceAt in indicesToInsertSpacesAt)
payloads.Insert(indexToInsertSpaceAt, getNewTextPayload());
// Decide whether to add a space to the end
if (tagPosition == StringPosition.Before)
{
var significantPayloads = payloads.Where(payload => payload is TextPayload || payload is IconPayload);
if (significantPayloads.Last() is TextPayload)
payloads.Add(getNewTextPayload());
}
// Decide whether to add a space to the beginning
else if (tagPosition == StringPosition.After)
{
var significantPayloads = payloads.Where(payload => payload is TextPayload || payload is IconPayload);
if (significantPayloads.First() is TextPayload)
payloads.Insert(0, getNewTextPayload());
}
}
}
private static List<StringPosition> GetOrderedStringPositions(StringChangesProps props)
{
var tagPositionsOrdered = new List<StringPosition>();
// If there's no anchor payload, do replaces first so that befores and afters are based on the replaced data
if (props.AnchorPayloads == null || !props.AnchorPayloads.Any())
tagPositionsOrdered.Add(StringPosition.Replace);
tagPositionsOrdered.Add(StringPosition.Before);
tagPositionsOrdered.Add(StringPosition.After);
// If there is an anchor payload, do replaces last so that we still know which payload needs to be removed
if (props.AnchorPayloads != null && props.AnchorPayloads.Any())
tagPositionsOrdered.Add(StringPosition.Replace);
return tagPositionsOrdered;
}
}
}