fix: Fixes mobile titles not displaying properly (#1149)

This commit is contained in:
mark1145 2022-08-28 06:31:22 +10:00 • committed by GitHub
parent 42f2c7f6ae
commit b8146f26f1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 55 additions and 36 deletions

View file

@ -18,6 +18,12 @@ using System;
namespace Server.Buffers; namespace Server.Buffers;
/// <summary>
/// Wrapper for STArray backed strings and char buffers that will be used in InterpolatedStringHandlers.
/// The wrapper prevents intermediate strings from being created unnecessarily.
/// Note: TryFormat can only be called once. Using the PooledArraySpanFormattable after calling TryFormat will throw.
/// To use the span multiple times, use the Chars property directly instead.
/// </summary>
public struct PooledArraySpanFormattable : ISpanFormattable, IDisposable public struct PooledArraySpanFormattable : ISpanFormattable, IDisposable
{ {
private char[] _arrayToReturnToPool; private char[] _arrayToReturnToPool;
@ -42,6 +48,7 @@ public struct PooledArraySpanFormattable : ISpanFormattable, IDisposable
STArrayPool<char>.Shared.Return(_arrayToReturnToPool); STArrayPool<char>.Shared.Return(_arrayToReturnToPool);
_arrayToReturnToPool = null; _arrayToReturnToPool = null;
// We don't dispose so we can call ToString() multiple times with idempotence.
return _value; return _value;
} }
@ -58,6 +65,9 @@ public struct PooledArraySpanFormattable : ISpanFormattable, IDisposable
_arrayToReturnToPool.AsSpan(0, _pos).CopyTo(destination); _arrayToReturnToPool.AsSpan(0, _pos).CopyTo(destination);
charsWritten = _pos; charsWritten = _pos;
// Interpolated string handlers do not dispose, but we need to return the chars to the array.
Dispose();
return true; return true;
} }

View file

@ -3228,8 +3228,6 @@ namespace Server
public virtual void AddNameProperties(IPropertyList list) public virtual void AddNameProperties(IPropertyList list)
{ {
var name = Name ?? " ";
string prefix; string prefix;
if (ShowFameTitle && (m_Player || m_Body.IsHuman) && m_Fame >= 10000) if (ShowFameTitle && (m_Player || m_Body.IsHuman) && m_Fame >= 10000)
@ -3241,22 +3239,19 @@ namespace Server
prefix = " "; prefix = " ";
} }
var title = PropertyTitle && !string.IsNullOrEmpty(Title) ? Title : "";
string suffix;
var guild = m_Guild; var guild = m_Guild;
if (guild != null && (m_Player || m_DisplayGuildTitle)) var hasTitle = PropertyTitle && !string.IsNullOrEmpty(Title);
{ var hasGuild = guild != null && (m_Player || m_DisplayGuildTitle);
suffix = title.Length > 0
? $"{title} [{Utility.FixHtml(guild.Abbreviation)}]"
: $"[{Utility.FixHtml(guild.Abbreviation)}]";
}
else
{
suffix = " ";
}
list.Add(1050045, $"{prefix}\t{name}\t{ApplyNameSuffix(suffix)}"); // ~1_PREFIX~~2_NAME~~3_SUFFIX~ string suffix = hasTitle switch
{
true when hasGuild => $" {Title} [{Utility.FixHtmlFormattable(guild.Abbreviation)}]",
true => $" {Title}",
false when hasGuild => $" [{Utility.FixHtmlFormattable(guild.Abbreviation)}]",
_ => " "
};
list.Add(1050045, $"{prefix}\t{Name ?? " "}\t{ApplyNameSuffix(suffix)}"); // ~1_PREFIX~~2_NAME~~3_SUFFIX~
if (guild != null && (m_DisplayGuildTitle || m_Player && guild.Type != GuildType.Regular)) if (guild != null && (m_DisplayGuildTitle || m_Player && guild.Type != GuildType.Regular))
{ {
@ -3268,11 +3263,11 @@ namespace Server
{ {
if (NewGuildDisplay) if (NewGuildDisplay)
{ {
list.Add($"{Utility.FixHtml(guildTitle)}, {Utility.FixHtml(guild.Name)}"); list.Add($"{Utility.FixHtmlFormattable(guildTitle)}, {Utility.FixHtmlFormattable(guild.Name)}");
} }
else else
{ {
list.Add($"{Utility.FixHtml(guildTitle)}, {Utility.FixHtml(guild.Name)} Guild{type}"); list.Add($"{Utility.FixHtmlFormattable(guildTitle)}, {Utility.FixHtmlFormattable(guild.Name)} Guild{type}");
} }
} }
else else
@ -7850,14 +7845,7 @@ namespace Server
prefix = m_Female ? "Lady" : "Lord"; prefix = m_Female ? "Lady" : "Lord";
} }
var suffix = ""; var suffix = ApplyNameSuffix(ClickTitle && !string.IsNullOrEmpty(Title) ? Title : "");
if (ClickTitle && !string.IsNullOrEmpty(Title))
{
suffix = Title;
}
suffix = ApplyNameSuffix(suffix);
string val; string val;

View file

@ -303,4 +303,12 @@ public static class StringHelpers
chars = chars[(indexOf + 1)..]; chars = chars[(indexOf + 1)..];
} }
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static char[] ToPooledArray(this string str)
{
var chars = STArrayPool<char>.Shared.Rent(str.Length);
str.CopyTo(chars);
return chars;
}
} }

View file

@ -567,12 +567,11 @@ public static class Utility
return str; return str;
} }
using var sb = new ValueStringBuilder(str, stackalloc char[Math.Min(128, str.Length)]); var chars = str.ToPooledArray();
ReadOnlySpan<char> invalid = stackalloc []{ '<', '>', '#' }; var span = chars.AsSpan(0, str.Length);
ReadOnlySpan<char> replacement = stackalloc []{ '(', ')', '-' }; FixHtml(span);
sb.ReplaceAny(invalid, replacement, 0, sb.Length);
return sb.ToString(); return span.ToString();
} }
public static void FixHtml(Span<char> chars) public static void FixHtml(Span<char> chars)
@ -588,6 +587,20 @@ public static class Utility
chars.ReplaceAny(invalid, replacement); chars.ReplaceAny(invalid, replacement);
} }
public static PooledArraySpanFormattable FixHtmlFormattable(string str)
{
var chars = str.ToPooledArray();
var span = chars.AsSpan(0, str.Length);
var formattable = new PooledArraySpanFormattable(chars, str.Length);
if (!string.IsNullOrEmpty(str))
{
FixHtml(span);
}
return formattable;
}
public static int InsensitiveCompare(string first, string second) => first.InsensitiveCompare(second); public static int InsensitiveCompare(string first, string second) => first.InsensitiveCompare(second);
public static bool InsensitiveStartsWith(string first, string second) => first.InsensitiveStartsWith(second); public static bool InsensitiveStartsWith(string first, string second) => first.InsensitiveStartsWith(second);

View file

@ -46,7 +46,7 @@ namespace Server.Engines.Help
10, 10,
280, 280,
20, 20,
$"<basefont color=#A0A0FF><center>SPEECH LOG - {playerName} (<i>{Utility.FixHtml(playerAccount)}</i>)</center></basefont>" $"<basefont color=#A0A0FF><center>SPEECH LOG - {playerName} (<i>{Utility.FixHtmlFormattable(playerAccount)}</i>)</center></basefont>"
); );
var lastPage = (log.Count - 1) / MaxEntriesPerPage; var lastPage = (log.Count - 1) / MaxEntriesPerPage;

View file

@ -114,11 +114,11 @@ public partial class Guildstone : Item, IAddon, IChoppable
} }
// list.Add( 1060802, Utility.FixHtml( name ) ); // Guild name: ~1_val~ // list.Add( 1060802, Utility.FixHtml( name ) ); // Guild name: ~1_val~
list.Add(1060802, $"{Utility.FixHtml(name)} [{Utility.FixHtml(abbr)}]"); list.Add(1060802, $"{Utility.FixHtmlFormattable(name)} [{Utility.FixHtmlFormattable(abbr)}]");
} }
else if (_guildName != null && _guildAbbrev != null) else if (_guildName != null && _guildAbbrev != null)
{ {
list.Add(1060802, $"{Utility.FixHtml(_guildName)} [{Utility.FixHtml(_guildAbbrev)}]"); list.Add(1060802, $"{Utility.FixHtmlFormattable(_guildName)} [{Utility.FixHtmlFormattable(_guildAbbrev)}]");
} }
} }
@ -254,11 +254,11 @@ public partial class GuildstoneDeed : Item
} }
// list.Add( 1060802, Utility.FixHtml( name ) ); // Guild name: ~1_val~ // list.Add( 1060802, Utility.FixHtml( name ) ); // Guild name: ~1_val~
list.Add(1060802, $"{Utility.FixHtml(name)} [{Utility.FixHtml(abbr)}]"); list.Add(1060802, $"{Utility.FixHtmlFormattable(name)} [{Utility.FixHtmlFormattable(abbr)}]");
} }
else if (_guildName != null && _guildAbbrev != null) else if (_guildName != null && _guildAbbrev != null)
{ {
list.Add(1060802, $"{Utility.FixHtml(_guildName)} [{Utility.FixHtml(_guildAbbrev)}]"); list.Add(1060802, $"{Utility.FixHtmlFormattable(_guildName)} [{Utility.FixHtmlFormattable(_guildAbbrev)}]");
} }
} }