fix(core): Optimizes strings / .NET 5 compatibility changes (#354)

- [X] Removes some string allocations (e.g. split)
- [X] Optimizes some collections
- [X] Converts insensitive to extension methods of built-ins.
- [X] Adds ordinal (case sensitive) string helpers
- [X] Fixes conditionals for in-game commands so they use Ordinal comparisons.
- [X] Replaces ToLower.Contains with InsensitiveContains
- [X] Adds ValueStringBuilder
- [X] Implements ValueStringBuilder in a few places where it makes sense
- [X] Removes the redundant Wrap function and replaces it with an optimized version
- [X] Fixes list conversions in Utility

Closes #351

Bumps release version
This commit is contained in:
Kamron Batman 2020-12-20 23:21:55 -08:00 • committed by GitHub
parent 92aae8d482
commit 77ce2e1980
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
117 changed files with 2000 additions and 1226 deletions

View file

@ -168,7 +168,7 @@ namespace Server.Misc
{
var info = new DirectoryInfo(paths[i]);
if (info.Name.StartsWith(match, StringComparison.Ordinal))
if (info.Name.StartsWithOrdinal(match))
{
return info;
}
@ -182,7 +182,7 @@ namespace Server.Misc
private static string FindTimeStamp(string input)
{
var start = input.IndexOf('(', StringComparison.Ordinal);
var start = input.IndexOfOrdinal('(');
if (start >= 0)
{

View file

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Text;
using Server.Buffers;
namespace Server.Misc
{
@ -316,9 +317,10 @@ namespace Server.Misc
return string.Concat(syllables);
}
public string ConstructSentance(int wordCount)
// TODO: Should be changed a preset table that is built
public string ConstructSentence(int wordCount)
{
var sentance = new StringBuilder();
using var sentence = new ValueStringBuilder(stackalloc char[256]);
var needUpperCase = true;
@ -330,56 +332,33 @@ namespace Server.Misc
if (random < 11)
{
sentance.Append(' ');
sentence.Append(' ');
}
else
{
needUpperCase = true;
if (random > 13)
{
sentance.Append("! ");
}
else
{
sentance.Append(". ");
}
sentence.Append(random > 13 ? "! " : ". ");
}
}
int syllableCount;
if (Utility.Random(100) < 30)
{
syllableCount = Utility.Random(1, 5);
}
else
{
syllableCount = Utility.Random(1, 3);
}
var syllableCount = Utility.Random(1, Utility.Random(100) < 30 ? 5 : 3);
var word = ConstructWord(syllableCount);
sentance.Append(word);
sentence.Append(word);
if (needUpperCase)
{
sentance.Replace(word[0], char.ToUpper(word[0]), sentance.Length - word.Length, 1);
sentence.Replace(word[0], char.ToUpper(word[0]), sentence.Length - word.Length, 1);
}
needUpperCase = false;
}
if (Utility.RandomMinMax(1, 5) == 1)
{
sentance.Append('!');
}
else
{
sentance.Append('.');
}
sentence.Append(Utility.RandomMinMax(1, 5) == 1 ? '!' : '.');
return sentance.ToString();
return sentence.ToString();
}
public void SayRandomTranslate(Mobile mob, params string[] sentancesInEnglish)
@ -435,44 +414,43 @@ namespace Server.Misc
if (keywordsFound.Count > 0)
{
string responseWord;
if (Utility.RandomBool())
{
responseWord = GetRandomResponseWord(keywordsFound);
}
else
{
responseWord = keywordsFound.RandomElement();
}
var responseWord = Utility.RandomBool() ?
GetRandomResponseWord(keywordsFound) : keywordsFound.RandomElement();
var secondResponseWord = GetRandomResponseWord(keywordsFound);
var response = new StringBuilder();
using var response = new ValueStringBuilder(stackalloc char[256]);
switch (Utility.Random(6))
{
default:
case 0:
{
response.Append("Me ").Append(responseWord).Append('?');
response.Append("Me ");
response.Append(responseWord);
response.Append('?');
break;
}
case 1:
{
response.Append(responseWord).Append(" thee!");
response.Append(responseWord);
response.Append(" thee!");
response.Replace(responseWord[0], char.ToUpper(responseWord[0]), 0, 1);
break;
}
case 2:
{
response.Append(responseWord).Append('?');
response.Append(responseWord);
response.Append('?');
response.Replace(responseWord[0], char.ToUpper(responseWord[0]), 0, 1);
break;
}
case 3:
{
response.Append(responseWord).Append("! ").Append(secondResponseWord).Append('.');
response.Append(responseWord);
response.Append("! ");
response.Append(secondResponseWord);
response.Append('.');
response.Replace(responseWord[0], char.ToUpper(responseWord[0]), 0, 1);
response.Replace(
secondResponseWord[0],
@ -484,13 +462,17 @@ namespace Server.Misc
}
case 4:
{
response.Append(responseWord).Append('.');
response.Append(responseWord);
response.Append('.');
response.Replace(responseWord[0], char.ToUpper(responseWord[0]), 0, 1);
break;
}
case 5:
{
response.Append(responseWord).Append("? ").Append(secondResponseWord).Append('.');
response.Append(responseWord);
response.Append("? ");
response.Append(secondResponseWord);
response.Append('.');
response.Replace(responseWord[0], char.ToUpper(responseWord[0]), 0, 1);
response.Replace(
secondResponseWord[0],
@ -502,16 +484,7 @@ namespace Server.Misc
}
}
var maxWords = split.Length / 2 + 1;
if (maxWords < 2)
{
maxWords = 2;
}
else if (maxWords > 6)
{
maxWords = 6;
}
var maxWords = Math.Clamp(split.Length / 2 + 1, 2, 6);
SaySentance(mob, Utility.RandomMinMax(2, maxWords));
mob.Say(response.ToString());
@ -617,7 +590,7 @@ namespace Server.Misc
public void SaySentance(Mobile mob, int wordCount)
{
mob.Say(ConstructSentance(wordCount));
mob.Say(ConstructSentence(wordCount));
mob.PlaySound(Sound);
}
}

View file

@ -201,7 +201,7 @@ namespace Server.Misc
for (var i = 0; i < disallowed.Length; ++i)
{
var indexOf = name.IndexOf(disallowed[i], StringComparison.Ordinal);
var indexOf = name.IndexOfOrdinal(disallowed[i]);
if (indexOf == -1)
{
@ -235,7 +235,7 @@ namespace Server.Misc
for (var i = 0; i < startDisallowed.Length; ++i)
{
if (name.StartsWith(startDisallowed[i], StringComparison.Ordinal))
if (name.StartsWithOrdinal(startDisallowed[i]))
{
return false;
}

View file

@ -34,7 +34,7 @@ namespace Server.Misc
for (var i = 0; i < disallowed.Length; i++)
{
if (name.IndexOf(disallowed[i], StringComparison.Ordinal) != -1)
if (name.IndexOfOrdinal(disallowed[i]) != -1)
{
from.SendLocalizedMessage(1072622); // That name isn't very polite.
return;

View file

@ -870,22 +870,22 @@ namespace Server.Items
/// </summary>
public static CraftResource GetFromOreInfo(OreInfo info)
{
if (info.Name.Contains("Spined", StringComparison.Ordinal))
if (info.Name.ContainsOrdinal("Spined"))
{
return CraftResource.SpinedLeather;
}
if (info.Name.Contains("Horned", StringComparison.Ordinal))
if (info.Name.ContainsOrdinal("Horned"))
{
return CraftResource.HornedLeather;
}
if (info.Name.Contains("Barbed", StringComparison.Ordinal))
if (info.Name.ContainsOrdinal("Barbed"))
{
return CraftResource.BarbedLeather;
}
if (info.Name.Contains("Leather", StringComparison.Ordinal))
if (info.Name.ContainsOrdinal("Leather"))
{
return CraftResource.RegularLeather;
}

View file

@ -393,7 +393,7 @@ namespace Server.Misc
do
{
++count;
index = title.IndexOf("<br>", index + 1, StringComparison.Ordinal);
index = title.IndexOfOrdinal("<br>", index + 1);
} while (index >= 0);
return count;

View file

@ -56,7 +56,7 @@ namespace Server
{
line = line.Trim();
if (line.Length == 0 || line.StartsWith("#", StringComparison.Ordinal))
if (line.Length == 0 || line.StartsWithOrdinal("#"))
{
continue;
}

View file

@ -143,14 +143,12 @@ namespace Server.Misc
offset = Math.Min(offset - m.Fame / 100, 0);
}
if (m.Fame + offset > MaxFame)
offset = (m.Fame + offset) switch
{
offset = MaxFame - m.Fame;
}
else if (m.Fame + offset < MinFame)
{
offset = MinFame - m.Fame;
}
> MaxFame => MaxFame - m.Fame,
< MinFame => MinFame - m.Fame,
_ => offset
};
m.Fame += offset;
@ -219,14 +217,12 @@ namespace Server.Misc
offset = Math.Min(offset - m.Karma / 100, 0);
}
if (m.Karma + offset > MaxKarma)
offset = (m.Karma + offset) switch
{
offset = MaxKarma - m.Karma;
}
else if (m.Karma + offset < MinKarma)
{
offset = MinKarma - m.Karma;
}
> MaxKarma => MaxKarma - m.Karma,
< MinKarma => MinKarma - m.Karma,
_ => offset
};
var wasPositiveKarma = m.Karma >= 0;
@ -288,11 +284,6 @@ namespace Server.Misc
var showSkillTitle = beheld.ShowFameTitle && (beholder == beheld || fame >= 5000);
/*if (beheld.Kills >= 5)
{
title.AppendFormat( beheld.Fame >= 10000 ? "The Murderer {1} {0}" : "The Murderer {0}", beheld.Name, beheld.Female ? "Lady" : "Lord" );
}
else*/
if (beheld.ShowFameTitle || beholder == beheld)
{
for (var i = 0; i < m_FameEntries.Length; ++i)
@ -345,15 +336,12 @@ namespace Server.Misc
}
}
var offset = 0;
if (highestValue > 800)
var offset = highestValue switch
{
offset = 3;
}
else if (highestValue > 300)
{
offset = highestValue / 300;
}
> 800 => 3,
> 300 => highestValue / 300,
_ => 0
};
if (offset > 0)
{
@ -369,7 +357,7 @@ namespace Server.Misc
var customTitle = beheld.Title;
if (customTitle != null && (customTitle = customTitle.Trim()).Length > 0)
if ((customTitle = customTitle?.Trim())?.Length > 0)
{
title.AppendFormat(" {0}", customTitle);
}
@ -395,7 +383,7 @@ namespace Server.Misc
var skillLevel = GetSkillLevel(highest);
var skillTitle = highest.Info.Title;
if (mob.Female && skillTitle.EndsWith("man", StringComparison.Ordinal))
if (mob.Female && skillTitle.EndsWithOrdinal("man"))
{
skillTitle = $"{skillTitle.Substring(0, skillTitle.Length - 3)}woman";
}