From 09e651b3abea0d0a7857fcab2dfc807b9e7c1983 Mon Sep 17 00:00:00 2001
From: kalilistic <35899782+kalilistic@users.noreply.github.com>
Date: Sun, 4 Apr 2021 08:21:01 -0400
Subject: [PATCH 1/4] refactor: change client language to internal
---
Dalamud/Data/DataManager.cs | 37 ++++++++++++++++++++-----------------
1 file changed, 20 insertions(+), 17 deletions(-)
diff --git a/Dalamud/Data/DataManager.cs b/Dalamud/Data/DataManager.cs
index 6ea358135..c8dced858 100644
--- a/Dalamud/Data/DataManager.cs
+++ b/Dalamud/Data/DataManager.cs
@@ -19,6 +19,11 @@ namespace Dalamud.Data
///
public class DataManager : IDisposable
{
+ ///
+ /// The current game client language.
+ ///
+ internal ClientLanguage Language;
+
private const string IconFileFormat = "ui/icon/{0:D3}000/{1}{2:D6}.tex";
///
@@ -26,8 +31,6 @@ namespace Dalamud.Data
///
private Lumina.GameData gameData;
- private ClientLanguage language;
-
private Thread luminaResourceThread;
///
@@ -39,7 +42,7 @@ namespace Dalamud.Data
// Set up default values so plugins do not null-reference when data is being loaded.
this.ServerOpCodes = new ReadOnlyDictionary(new Dictionary());
- this.language = language;
+ this.Language = language;
}
///
@@ -94,14 +97,14 @@ namespace Dalamud.Data
PanicOnSheetChecksumMismatch = false,
#endif
- DefaultExcelLanguage = this.language switch {
- ClientLanguage.Japanese => Language.Japanese,
- ClientLanguage.English => Language.English,
- ClientLanguage.German => Language.German,
- ClientLanguage.French => Language.French,
+ DefaultExcelLanguage = this.Language switch {
+ ClientLanguage.Japanese => Lumina.Data.Language.Japanese,
+ ClientLanguage.English => Lumina.Data.Language.English,
+ ClientLanguage.German => Lumina.Data.Language.German,
+ ClientLanguage.French => Lumina.Data.Language.French,
_ => throw new ArgumentOutOfRangeException(
- nameof(this.language),
- "Unknown Language: " + this.language),
+ nameof(this.Language),
+ "Unknown Language: " + this.Language),
},
};
@@ -156,11 +159,11 @@ namespace Dalamud.Data
public ExcelSheet GetExcelSheet(ClientLanguage language) where T : ExcelRow
{
var lang = language switch {
- ClientLanguage.Japanese => Language.Japanese,
- ClientLanguage.English => Language.English,
- ClientLanguage.German => Language.German,
- ClientLanguage.French => Language.French,
- _ => throw new ArgumentOutOfRangeException(nameof(this.language), "Unknown Language: " + this.language)
+ ClientLanguage.Japanese => Lumina.Data.Language.Japanese,
+ ClientLanguage.English => Lumina.Data.Language.English,
+ ClientLanguage.German => Lumina.Data.Language.German,
+ ClientLanguage.French => Lumina.Data.Language.French,
+ _ => throw new ArgumentOutOfRangeException(nameof(this.Language), "Unknown Language: " + this.Language)
};
return this.Excel.GetSheet(lang);
}
@@ -207,7 +210,7 @@ namespace Dalamud.Data
/// The containing the icon.
public TexFile GetIcon(int iconId)
{
- return this.GetIcon(this.language, iconId);
+ return this.GetIcon(this.Language, iconId);
}
///
@@ -223,7 +226,7 @@ namespace Dalamud.Data
ClientLanguage.English => "en/",
ClientLanguage.German => "de/",
ClientLanguage.French => "fr/",
- _ => throw new ArgumentOutOfRangeException(nameof(this.language), "Unknown Language: " + this.language)
+ _ => throw new ArgumentOutOfRangeException(nameof(this.Language), "Unknown Language: " + this.Language)
};
return this.GetIcon(type, iconId);
From 4504bb049fd837e81a3c2f7f47bb9f986592b6ea Mon Sep 17 00:00:00 2001
From: kalilistic <35899782+kalilistic@users.noreply.github.com>
Date: Sun, 4 Apr 2021 09:20:07 -0400
Subject: [PATCH 2/4] feat: add sanitizer
---
Dalamud.Test/Dalamud.Test.csproj | 1 +
.../Plugin/Sanitizer/SanitizerTests.cs | 67 +++++++++++
Dalamud.sln.DotSettings | 3 +-
Dalamud/Plugin/DalamudPluginInterface.cs | 7 ++
Dalamud/Plugin/Sanitizer/ISanitizer.cs | 40 +++++++
Dalamud/Plugin/Sanitizer/Sanitizer.cs | 113 ++++++++++++++++++
6 files changed, 230 insertions(+), 1 deletion(-)
create mode 100644 Dalamud.Test/Plugin/Sanitizer/SanitizerTests.cs
create mode 100644 Dalamud/Plugin/Sanitizer/ISanitizer.cs
create mode 100644 Dalamud/Plugin/Sanitizer/Sanitizer.cs
diff --git a/Dalamud.Test/Dalamud.Test.csproj b/Dalamud.Test/Dalamud.Test.csproj
index 7091ebe26..1ae18862f 100644
--- a/Dalamud.Test/Dalamud.Test.csproj
+++ b/Dalamud.Test/Dalamud.Test.csproj
@@ -43,6 +43,7 @@
+
diff --git a/Dalamud.Test/Plugin/Sanitizer/SanitizerTests.cs b/Dalamud.Test/Plugin/Sanitizer/SanitizerTests.cs
new file mode 100644
index 000000000..b0ead50a2
--- /dev/null
+++ b/Dalamud.Test/Plugin/Sanitizer/SanitizerTests.cs
@@ -0,0 +1,67 @@
+// ReSharper disable StringLiteralTypo
+
+using System.Linq;
+using NUnit.Framework;
+
+namespace Dalamud.Test.Plugin.Sanitizer {
+ [TestFixture]
+ public class SanitizerTests {
+ global::Dalamud.Plugin.Sanitizer.Sanitizer sanitizer;
+
+ [Test]
+ public void Sanitize_NormalString_NoChange() {
+ sanitizer = new global::Dalamud.Plugin.Sanitizer.Sanitizer(ClientLanguage.English);
+ const string str = "Pixie Cotton Hood of Healing";
+ var sanitizedString = sanitizer.Sanitize(str);
+ Assert.AreEqual(str, sanitizedString);
+ }
+
+ [Test]
+ public void Sanitize_DESpecialCharacters_Sanitized() {
+ sanitizer = new global::Dalamud.Plugin.Sanitizer.Sanitizer(ClientLanguage.German);
+ const string str = @"Anemos-Panzerhandschuhe des Drachenbluts";
+ var sanitizedString = sanitizer.Sanitize(str);
+ Assert.AreEqual(@"Anemos-Panzerhandschuhe des Drachenbluts", sanitizedString);
+ }
+
+ [Test]
+ public void Sanitize_FRSpecialCharacters_Sanitized() {
+ sanitizer = new global::Dalamud.Plugin.Sanitizer.Sanitizer(ClientLanguage.French);
+ const string str = @"Le Diademe: terrains de chasse|Le Diademe: terrains de chasse";
+ var sanitizedString = sanitizer.Sanitize(str);
+ Assert.AreEqual(@"Le Diademe: terrains de chasse|Le Diademe: terrains de chasse", sanitizedString);
+ }
+
+ [Test]
+ public void Sanitize_SpecifyLanguage_Sanitized() {
+ sanitizer = new global::Dalamud.Plugin.Sanitizer.Sanitizer(ClientLanguage.French);
+ const string str = @"Le Diademe: terrains de chasse|Le Diademe: terrains de chasse";
+ var sanitizedString = sanitizer.Sanitize(str, ClientLanguage.French);
+ Assert.AreEqual(@"Le Diademe: terrains de chasse|Le Diademe: terrains de chasse", sanitizedString);
+ }
+
+ [Test]
+ public void Sanitize_List_Sanitized() {
+ sanitizer = new global::Dalamud.Plugin.Sanitizer.Sanitizer(ClientLanguage.German);
+ const string str = @"Anemos-Panzerhandschuhe des Drachenbluts";
+ var sanitizedStrings = sanitizer.Sanitize(new[] {str});
+ Assert.AreEqual(@"Anemos-Panzerhandschuhe des Drachenbluts", sanitizedStrings.First());
+ }
+
+ [Test]
+ public void Sanitize_SpecifyLanguageList_Sanitized() {
+ sanitizer = new global::Dalamud.Plugin.Sanitizer.Sanitizer(ClientLanguage.German);
+ const string str = @"Anemos-Panzerhandschuhe des Drachenbluts";
+ var sanitizedStrings = sanitizer.Sanitize(new[] {str}, ClientLanguage.German);
+ Assert.AreEqual(@"Anemos-Panzerhandschuhe des Drachenbluts", sanitizedStrings.First());
+ }
+
+ [Test]
+ public void Sanitize_UseAlternateLanguage_Sanitized() {
+ sanitizer = new global::Dalamud.Plugin.Sanitizer.Sanitizer(ClientLanguage.English);
+ const string str = @"Anemos-Panzerhandschuhe des Drachenbluts";
+ var sanitizedStrings = sanitizer.Sanitize(new[] {str}, ClientLanguage.German);
+ Assert.AreEqual(@"Anemos-Panzerhandschuhe des Drachenbluts", sanitizedStrings.First());
+ }
+ }
+}
diff --git a/Dalamud.sln.DotSettings b/Dalamud.sln.DotSettings
index 8b8890e01..af8f4d833 100644
--- a/Dalamud.sln.DotSettings
+++ b/Dalamud.sln.DotSettings
@@ -47,4 +47,5 @@
True
True
True
- True
\ No newline at end of file
+ True
+ True
\ No newline at end of file
diff --git a/Dalamud/Plugin/DalamudPluginInterface.cs b/Dalamud/Plugin/DalamudPluginInterface.cs
index c0d9f12e3..dab5995e7 100644
--- a/Dalamud/Plugin/DalamudPluginInterface.cs
+++ b/Dalamud/Plugin/DalamudPluginInterface.cs
@@ -13,6 +13,7 @@ using Dalamud.Game.ClientState;
using Dalamud.Game.Command;
using Dalamud.Game.Internal;
using Dalamud.Interface;
+using Dalamud.Plugin.Sanitizer;
namespace Dalamud.Plugin
{
@@ -48,6 +49,7 @@ namespace Dalamud.Plugin
this.pluginName = pluginName;
this.configs = configs;
+ this.Sanitizer = new Sanitizer.Sanitizer(this.Data.Language);
this.UiLanguage = this.dalamud.Configuration.LanguageOverride;
dalamud.LocalizationManager.OnLocalizationChanged += this.OnLocalizationChanged;
}
@@ -132,6 +134,11 @@ namespace Dalamud.Plugin
///
public string UiLanguage { get; private set; }
+ ///
+ /// Gets serializer class with functions to remove special characters from strings.
+ ///
+ public ISanitizer Sanitizer { get; }
+
///
/// Gets the action that should be executed when any plugin sends a message.
///
diff --git a/Dalamud/Plugin/Sanitizer/ISanitizer.cs b/Dalamud/Plugin/Sanitizer/ISanitizer.cs
new file mode 100644
index 000000000..21fe8ab77
--- /dev/null
+++ b/Dalamud/Plugin/Sanitizer/ISanitizer.cs
@@ -0,0 +1,40 @@
+using System.Collections.Generic;
+
+namespace Dalamud.Plugin.Sanitizer
+{
+ ///
+ /// Sanitize strings to remove soft hyphens and other special characters.
+ ///
+ public interface ISanitizer
+ {
+ ///
+ /// Creates a sanitized string using current clientLanguage.
+ ///
+ /// An unsanitized string to sanitize.
+ /// A sanitized string.
+ string Sanitize(string unsanitizedString);
+
+ ///
+ /// Creates a sanitized string using request clientLanguage.
+ ///
+ /// An unsanitized string to sanitize.
+ /// Target language for sanitized strings.
+ /// A sanitized string.
+ string Sanitize(string unsanitizedString, ClientLanguage clientLanguage);
+
+ ///
+ /// Creates a list of sanitized strings using current clientLanguage.
+ ///
+ /// List of unsanitized string to sanitize.
+ /// A list of sanitized strings.
+ IEnumerable Sanitize(IEnumerable unsanitizedStrings);
+
+ ///
+ /// Creates a list of sanitized strings using requested clientLanguage.
+ ///
+ /// List of unsanitized string to sanitize.
+ /// Target language for sanitized strings.
+ /// A list of sanitized strings.
+ IEnumerable Sanitize(IEnumerable unsanitizedStrings, ClientLanguage clientLanguage);
+ }
+}
diff --git a/Dalamud/Plugin/Sanitizer/Sanitizer.cs b/Dalamud/Plugin/Sanitizer/Sanitizer.cs
new file mode 100644
index 000000000..66b2c413f
--- /dev/null
+++ b/Dalamud/Plugin/Sanitizer/Sanitizer.cs
@@ -0,0 +1,113 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Dalamud.Plugin.Sanitizer
+{
+ ///
+ /// Sanitize strings to remove soft hyphens and other special characters.
+ ///
+ public class Sanitizer : ISanitizer
+ {
+ private readonly KeyValuePair softHyphen = new KeyValuePair("\u0002\u0016\u0001\u0003", string.Empty);
+ private readonly KeyValuePair emphasisOpen = new KeyValuePair("\u0002\u001A\u0003", string.Empty);
+ private readonly KeyValuePair emphasisClose = new KeyValuePair("\u0002\u001A\u0001\u0003", string.Empty);
+ private readonly KeyValuePair indent = new KeyValuePair("\u0002\u001D\u0001\u0003", string.Empty);
+ private readonly KeyValuePair dagger = new KeyValuePair("\u0020\u2020", string.Empty);
+ private readonly KeyValuePair ligatureOE = new KeyValuePair("\u0153", "\u006F\u0065");
+ private readonly List> defaultSanitizationList;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// Default clientLanguage for sanitizing strings.
+ public Sanitizer(ClientLanguage clientLanguage)
+ {
+ this.defaultSanitizationList = this.BuildSanitizationList(clientLanguage);
+ }
+
+ ///
+ /// Creates a sanitized string using current clientLanguage.
+ ///
+ /// An unsanitized string to sanitize.
+ /// A sanitized string.
+ public string Sanitize(string unsanitizedString)
+ {
+ return this.defaultSanitizationList == null ? unsanitizedString : ApplySanitizationList(unsanitizedString, this.defaultSanitizationList);
+ }
+
+ ///
+ /// Creates a sanitized string using request clientLanguage.
+ ///
+ /// An unsanitized string to sanitize.
+ /// Target language for sanitized strings.
+ /// A sanitized string.
+ public string Sanitize(string unsanitizedString, ClientLanguage clientLanguage)
+ {
+ var newSanitizationList = this.BuildSanitizationList(clientLanguage);
+ return newSanitizationList == null ? unsanitizedString : ApplySanitizationList(unsanitizedString, newSanitizationList);
+ }
+
+ ///
+ /// Creates a list of sanitized strings using current clientLanguage.
+ ///
+ /// List of unsanitized string to sanitize.
+ /// A list of sanitized strings.
+ public IEnumerable Sanitize(IEnumerable unsanitizedStrings)
+ {
+ return this.defaultSanitizationList == null ? unsanitizedStrings.Select(unsanitizedString => unsanitizedString) :
+ unsanitizedStrings.Select(unsanitizedString => ApplySanitizationList(unsanitizedString, this.defaultSanitizationList));
+ }
+
+ ///
+ /// Creates a list of sanitized strings using requested clientLanguage.
+ ///
+ /// List of unsanitized string to sanitize.
+ /// Target language for sanitized strings.
+ /// A list of sanitized strings.
+ public IEnumerable Sanitize(IEnumerable unsanitizedStrings, ClientLanguage clientLanguage)
+ {
+ var newSanitizationList = this.BuildSanitizationList(clientLanguage);
+ return newSanitizationList == null ? unsanitizedStrings.Select(unsanitizedString => unsanitizedString) :
+ unsanitizedStrings.Select(unsanitizedString => ApplySanitizationList(unsanitizedString, newSanitizationList));
+ }
+
+ private static string ApplySanitizationList(string unsanitizedString, IEnumerable> sanitizationList)
+ {
+ var sanitizedValue = new StringBuilder(unsanitizedString);
+ foreach (var item in sanitizationList) sanitizedValue.Replace(item.Key, item.Value);
+ return sanitizedValue.ToString();
+ }
+
+ private List> BuildSanitizationList(ClientLanguage clientLanguage)
+ {
+ switch (clientLanguage)
+ {
+ case ClientLanguage.Japanese:
+ break;
+ case ClientLanguage.English:
+ break;
+ case ClientLanguage.German:
+ return new List>
+ {
+ this.softHyphen,
+ this.emphasisOpen,
+ this.emphasisClose,
+ this.dagger,
+ };
+ case ClientLanguage.French:
+ return new List>
+ {
+ this.softHyphen,
+ this.indent,
+ this.ligatureOE,
+ };
+ default:
+ throw new ArgumentOutOfRangeException();
+ }
+
+ return null;
+ }
+ }
+}
From e5524539a3618772d8d73a43e09a337e80aa5dfb Mon Sep 17 00:00:00 2001
From: kalilistic <35899782+kalilistic@users.noreply.github.com>
Date: Sun, 4 Apr 2021 10:59:25 -0400
Subject: [PATCH 3/4] refactor: convert tests to xunit
---
.../Plugin/Sanitizer/SanitizerTests.cs | 32 +++++++++----------
1 file changed, 16 insertions(+), 16 deletions(-)
diff --git a/Dalamud.Test/Plugin/Sanitizer/SanitizerTests.cs b/Dalamud.Test/Plugin/Sanitizer/SanitizerTests.cs
index b0ead50a2..888c0b0a5 100644
--- a/Dalamud.Test/Plugin/Sanitizer/SanitizerTests.cs
+++ b/Dalamud.Test/Plugin/Sanitizer/SanitizerTests.cs
@@ -1,67 +1,67 @@
// ReSharper disable StringLiteralTypo
using System.Linq;
-using NUnit.Framework;
+using Xunit;
namespace Dalamud.Test.Plugin.Sanitizer {
- [TestFixture]
+
public class SanitizerTests {
global::Dalamud.Plugin.Sanitizer.Sanitizer sanitizer;
- [Test]
+ [Fact]
public void Sanitize_NormalString_NoChange() {
sanitizer = new global::Dalamud.Plugin.Sanitizer.Sanitizer(ClientLanguage.English);
const string str = "Pixie Cotton Hood of Healing";
var sanitizedString = sanitizer.Sanitize(str);
- Assert.AreEqual(str, sanitizedString);
+ Assert.Equal(str, sanitizedString);
}
- [Test]
+ [Fact]
public void Sanitize_DESpecialCharacters_Sanitized() {
sanitizer = new global::Dalamud.Plugin.Sanitizer.Sanitizer(ClientLanguage.German);
const string str = @"Anemos-Panzerhandschuhe des Drachenbluts";
var sanitizedString = sanitizer.Sanitize(str);
- Assert.AreEqual(@"Anemos-Panzerhandschuhe des Drachenbluts", sanitizedString);
+ Assert.Equal(@"Anemos-Panzerhandschuhe des Drachenbluts", sanitizedString);
}
- [Test]
+ [Fact]
public void Sanitize_FRSpecialCharacters_Sanitized() {
sanitizer = new global::Dalamud.Plugin.Sanitizer.Sanitizer(ClientLanguage.French);
const string str = @"Le Diademe: terrains de chasse|Le Diademe: terrains de chasse";
var sanitizedString = sanitizer.Sanitize(str);
- Assert.AreEqual(@"Le Diademe: terrains de chasse|Le Diademe: terrains de chasse", sanitizedString);
+ Assert.Equal(@"Le Diademe: terrains de chasse|Le Diademe: terrains de chasse", sanitizedString);
}
- [Test]
+ [Fact]
public void Sanitize_SpecifyLanguage_Sanitized() {
sanitizer = new global::Dalamud.Plugin.Sanitizer.Sanitizer(ClientLanguage.French);
const string str = @"Le Diademe: terrains de chasse|Le Diademe: terrains de chasse";
var sanitizedString = sanitizer.Sanitize(str, ClientLanguage.French);
- Assert.AreEqual(@"Le Diademe: terrains de chasse|Le Diademe: terrains de chasse", sanitizedString);
+ Assert.Equal(@"Le Diademe: terrains de chasse|Le Diademe: terrains de chasse", sanitizedString);
}
- [Test]
+ [Fact]
public void Sanitize_List_Sanitized() {
sanitizer = new global::Dalamud.Plugin.Sanitizer.Sanitizer(ClientLanguage.German);
const string str = @"Anemos-Panzerhandschuhe des Drachenbluts";
var sanitizedStrings = sanitizer.Sanitize(new[] {str});
- Assert.AreEqual(@"Anemos-Panzerhandschuhe des Drachenbluts", sanitizedStrings.First());
+ Assert.Equal(@"Anemos-Panzerhandschuhe des Drachenbluts", sanitizedStrings.First());
}
- [Test]
+ [Fact]
public void Sanitize_SpecifyLanguageList_Sanitized() {
sanitizer = new global::Dalamud.Plugin.Sanitizer.Sanitizer(ClientLanguage.German);
const string str = @"Anemos-Panzerhandschuhe des Drachenbluts";
var sanitizedStrings = sanitizer.Sanitize(new[] {str}, ClientLanguage.German);
- Assert.AreEqual(@"Anemos-Panzerhandschuhe des Drachenbluts", sanitizedStrings.First());
+ Assert.Equal(@"Anemos-Panzerhandschuhe des Drachenbluts", sanitizedStrings.First());
}
- [Test]
+ [Fact]
public void Sanitize_UseAlternateLanguage_Sanitized() {
sanitizer = new global::Dalamud.Plugin.Sanitizer.Sanitizer(ClientLanguage.English);
const string str = @"Anemos-Panzerhandschuhe des Drachenbluts";
var sanitizedStrings = sanitizer.Sanitize(new[] {str}, ClientLanguage.German);
- Assert.AreEqual(@"Anemos-Panzerhandschuhe des Drachenbluts", sanitizedStrings.First());
+ Assert.Equal(@"Anemos-Panzerhandschuhe des Drachenbluts", sanitizedStrings.First());
}
}
}
From 20dfe5cbc950b7060aafa9921a21f7a3606c051e Mon Sep 17 00:00:00 2001
From: kalilistic <35899782+kalilistic@users.noreply.github.com>
Date: Sun, 4 Apr 2021 13:09:54 -0400
Subject: [PATCH 4/4] refactor: improve sanitizer
---
.../Plugin/Sanitizer/SanitizerTests.cs | 73 ++++--------
Dalamud/Plugin/Sanitizer/Sanitizer.cs | 106 ++++++++++--------
2 files changed, 81 insertions(+), 98 deletions(-)
diff --git a/Dalamud.Test/Plugin/Sanitizer/SanitizerTests.cs b/Dalamud.Test/Plugin/Sanitizer/SanitizerTests.cs
index 888c0b0a5..25aefd183 100644
--- a/Dalamud.Test/Plugin/Sanitizer/SanitizerTests.cs
+++ b/Dalamud.Test/Plugin/Sanitizer/SanitizerTests.cs
@@ -1,67 +1,32 @@
// ReSharper disable StringLiteralTypo
+using System.Collections.Generic;
using System.Linq;
using Xunit;
namespace Dalamud.Test.Plugin.Sanitizer {
public class SanitizerTests {
- global::Dalamud.Plugin.Sanitizer.Sanitizer sanitizer;
+ private global::Dalamud.Plugin.Sanitizer.Sanitizer sanitizer;
- [Fact]
- public void Sanitize_NormalString_NoChange() {
+ [Theory]
+ [InlineData( ClientLanguage.English, "Pixie Cotton Hood of Healing", "Pixie Cotton Hood of Healing" )]
+ [InlineData( ClientLanguage.Japanese, "アラガントームストーン:真理", "アラガントームストーン:真理" )]
+ [InlineData( ClientLanguage.German, "Anemos-Pan\x02\x16\x01\x03zer\x02\x16\x01\x03hand\x02\x16\x01\x03schu\x02\x16\x01\x03he des Drachenbluts", "Anemos-Panzerhandschuhe des Drachenbluts" )]
+ [InlineData( ClientLanguage.German, "Bienen-Spatha †", "Bienen-Spatha" )]
+ [InlineData( ClientLanguage.French, "Le Diademe\x02\x1D\x01\x03: terrains de chasse|Le Diademe\x02\x1D\x01\x03: terrains de chasse", "Le Diademe: terrains de chasse|Le Diademe: terrains de chasse" )]
+ [InlineData( ClientLanguage.French, "Cuir de bœuf", "Cuir de boeuf" )]
+ public void StringsAreSanitizedCorrectly(
+ ClientLanguage clientLanguage, string unsanitizedString, string sanitizedString)
+ {
+ var sanitizedStrings = new List {unsanitizedString};
+ sanitizer = new global::Dalamud.Plugin.Sanitizer.Sanitizer(clientLanguage);
+ Assert.Equal(sanitizedString, sanitizer.Sanitize(unsanitizedString));
+ Assert.Equal(sanitizedString, sanitizer.Sanitize(sanitizedStrings).First());
+
sanitizer = new global::Dalamud.Plugin.Sanitizer.Sanitizer(ClientLanguage.English);
- const string str = "Pixie Cotton Hood of Healing";
- var sanitizedString = sanitizer.Sanitize(str);
- Assert.Equal(str, sanitizedString);
- }
-
- [Fact]
- public void Sanitize_DESpecialCharacters_Sanitized() {
- sanitizer = new global::Dalamud.Plugin.Sanitizer.Sanitizer(ClientLanguage.German);
- const string str = @"Anemos-Panzerhandschuhe des Drachenbluts";
- var sanitizedString = sanitizer.Sanitize(str);
- Assert.Equal(@"Anemos-Panzerhandschuhe des Drachenbluts", sanitizedString);
- }
-
- [Fact]
- public void Sanitize_FRSpecialCharacters_Sanitized() {
- sanitizer = new global::Dalamud.Plugin.Sanitizer.Sanitizer(ClientLanguage.French);
- const string str = @"Le Diademe: terrains de chasse|Le Diademe: terrains de chasse";
- var sanitizedString = sanitizer.Sanitize(str);
- Assert.Equal(@"Le Diademe: terrains de chasse|Le Diademe: terrains de chasse", sanitizedString);
- }
-
- [Fact]
- public void Sanitize_SpecifyLanguage_Sanitized() {
- sanitizer = new global::Dalamud.Plugin.Sanitizer.Sanitizer(ClientLanguage.French);
- const string str = @"Le Diademe: terrains de chasse|Le Diademe: terrains de chasse";
- var sanitizedString = sanitizer.Sanitize(str, ClientLanguage.French);
- Assert.Equal(@"Le Diademe: terrains de chasse|Le Diademe: terrains de chasse", sanitizedString);
- }
-
- [Fact]
- public void Sanitize_List_Sanitized() {
- sanitizer = new global::Dalamud.Plugin.Sanitizer.Sanitizer(ClientLanguage.German);
- const string str = @"Anemos-Panzerhandschuhe des Drachenbluts";
- var sanitizedStrings = sanitizer.Sanitize(new[] {str});
- Assert.Equal(@"Anemos-Panzerhandschuhe des Drachenbluts", sanitizedStrings.First());
- }
-
- [Fact]
- public void Sanitize_SpecifyLanguageList_Sanitized() {
- sanitizer = new global::Dalamud.Plugin.Sanitizer.Sanitizer(ClientLanguage.German);
- const string str = @"Anemos-Panzerhandschuhe des Drachenbluts";
- var sanitizedStrings = sanitizer.Sanitize(new[] {str}, ClientLanguage.German);
- Assert.Equal(@"Anemos-Panzerhandschuhe des Drachenbluts", sanitizedStrings.First());
- }
-
- [Fact]
- public void Sanitize_UseAlternateLanguage_Sanitized() {
- sanitizer = new global::Dalamud.Plugin.Sanitizer.Sanitizer(ClientLanguage.English);
- const string str = @"Anemos-Panzerhandschuhe des Drachenbluts";
- var sanitizedStrings = sanitizer.Sanitize(new[] {str}, ClientLanguage.German);
- Assert.Equal(@"Anemos-Panzerhandschuhe des Drachenbluts", sanitizedStrings.First());
+ Assert.Equal(sanitizedString, sanitizer.Sanitize(unsanitizedString, clientLanguage));
+ Assert.Equal(sanitizedString, sanitizer.Sanitize(sanitizedStrings, clientLanguage).First());
}
}
}
diff --git a/Dalamud/Plugin/Sanitizer/Sanitizer.cs b/Dalamud/Plugin/Sanitizer/Sanitizer.cs
index 66b2c413f..58f6fde47 100644
--- a/Dalamud/Plugin/Sanitizer/Sanitizer.cs
+++ b/Dalamud/Plugin/Sanitizer/Sanitizer.cs
@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
-using System.Text;
namespace Dalamud.Plugin.Sanitizer
{
@@ -10,21 +9,25 @@ namespace Dalamud.Plugin.Sanitizer
///
public class Sanitizer : ISanitizer
{
- private readonly KeyValuePair softHyphen = new KeyValuePair("\u0002\u0016\u0001\u0003", string.Empty);
- private readonly KeyValuePair emphasisOpen = new KeyValuePair("\u0002\u001A\u0003", string.Empty);
- private readonly KeyValuePair emphasisClose = new KeyValuePair("\u0002\u001A\u0001\u0003", string.Empty);
- private readonly KeyValuePair indent = new KeyValuePair("\u0002\u001D\u0001\u0003", string.Empty);
- private readonly KeyValuePair dagger = new KeyValuePair("\u0020\u2020", string.Empty);
- private readonly KeyValuePair ligatureOE = new KeyValuePair("\u0153", "\u006F\u0065");
- private readonly List> defaultSanitizationList;
+ private static readonly Dictionary DESanitizationDict = new Dictionary
+ {
+ { "\u0020\u2020", string.Empty }, // dagger
+ };
+
+ private static readonly Dictionary FRSanitizationDict = new Dictionary
+ {
+ { "\u0153", "\u006F\u0065" }, // ligature oe
+ };
+
+ private readonly ClientLanguage defaultClientLanguage;
///
/// Initializes a new instance of the class.
///
- /// Default clientLanguage for sanitizing strings.
- public Sanitizer(ClientLanguage clientLanguage)
+ /// Default clientLanguage for sanitizing strings.
+ public Sanitizer(ClientLanguage defaultClientLanguage)
{
- this.defaultSanitizationList = this.BuildSanitizationList(clientLanguage);
+ this.defaultClientLanguage = defaultClientLanguage;
}
///
@@ -34,7 +37,7 @@ namespace Dalamud.Plugin.Sanitizer
/// A sanitized string.
public string Sanitize(string unsanitizedString)
{
- return this.defaultSanitizationList == null ? unsanitizedString : ApplySanitizationList(unsanitizedString, this.defaultSanitizationList);
+ return SanitizeByLanguage(unsanitizedString, this.defaultClientLanguage);
}
///
@@ -45,8 +48,7 @@ namespace Dalamud.Plugin.Sanitizer
/// A sanitized string.
public string Sanitize(string unsanitizedString, ClientLanguage clientLanguage)
{
- var newSanitizationList = this.BuildSanitizationList(clientLanguage);
- return newSanitizationList == null ? unsanitizedString : ApplySanitizationList(unsanitizedString, newSanitizationList);
+ return SanitizeByLanguage(unsanitizedString, clientLanguage);
}
///
@@ -56,8 +58,7 @@ namespace Dalamud.Plugin.Sanitizer
/// A list of sanitized strings.
public IEnumerable Sanitize(IEnumerable unsanitizedStrings)
{
- return this.defaultSanitizationList == null ? unsanitizedStrings.Select(unsanitizedString => unsanitizedString) :
- unsanitizedStrings.Select(unsanitizedString => ApplySanitizationList(unsanitizedString, this.defaultSanitizationList));
+ return SanitizeByLanguage(unsanitizedStrings, this.defaultClientLanguage);
}
///
@@ -68,46 +69,63 @@ namespace Dalamud.Plugin.Sanitizer
/// A list of sanitized strings.
public IEnumerable Sanitize(IEnumerable unsanitizedStrings, ClientLanguage clientLanguage)
{
- var newSanitizationList = this.BuildSanitizationList(clientLanguage);
- return newSanitizationList == null ? unsanitizedStrings.Select(unsanitizedString => unsanitizedString) :
- unsanitizedStrings.Select(unsanitizedString => ApplySanitizationList(unsanitizedString, newSanitizationList));
+ return SanitizeByLanguage(unsanitizedStrings, clientLanguage);
}
- private static string ApplySanitizationList(string unsanitizedString, IEnumerable> sanitizationList)
- {
- var sanitizedValue = new StringBuilder(unsanitizedString);
- foreach (var item in sanitizationList) sanitizedValue.Replace(item.Key, item.Value);
- return sanitizedValue.ToString();
- }
-
- private List> BuildSanitizationList(ClientLanguage clientLanguage)
+ private static string SanitizeByLanguage(string unsanitizedString, ClientLanguage clientLanguage)
{
+ var sanitizedString = FilterUnprintableCharacters(unsanitizedString);
switch (clientLanguage)
{
case ClientLanguage.Japanese:
- break;
case ClientLanguage.English:
- break;
+ return sanitizedString;
case ClientLanguage.German:
- return new List>
- {
- this.softHyphen,
- this.emphasisOpen,
- this.emphasisClose,
- this.dagger,
- };
+ return FilterByDict(sanitizedString, DESanitizationDict);
case ClientLanguage.French:
- return new List>
- {
- this.softHyphen,
- this.indent,
- this.ligatureOE,
- };
+ return FilterByDict(sanitizedString, FRSanitizationDict);
default:
- throw new ArgumentOutOfRangeException();
+ throw new ArgumentOutOfRangeException(nameof(clientLanguage), clientLanguage, null);
}
+ }
- return null;
+ private static IEnumerable SanitizeByLanguage(
+ IEnumerable unsanitizedStrings, ClientLanguage clientLanguage)
+ {
+ var sanitizedStrings = new List();
+ switch (clientLanguage)
+ {
+ case ClientLanguage.Japanese:
+ case ClientLanguage.English:
+ sanitizedStrings.AddRange(unsanitizedStrings.Select(FilterUnprintableCharacters));
+ return sanitizedStrings;
+ case ClientLanguage.German:
+ sanitizedStrings.AddRange(
+ unsanitizedStrings.Select(
+ unsanitizedString =>
+ FilterByDict(FilterUnprintableCharacters(unsanitizedString), DESanitizationDict)));
+ return sanitizedStrings;
+ case ClientLanguage.French:
+ sanitizedStrings.AddRange(
+ unsanitizedStrings.Select(
+ unsanitizedString =>
+ FilterByDict(FilterUnprintableCharacters(unsanitizedString), FRSanitizationDict)));
+ return sanitizedStrings;
+ default:
+ throw new ArgumentOutOfRangeException(nameof(clientLanguage), clientLanguage, null);
+ }
+ }
+
+ private static string FilterUnprintableCharacters(string str)
+ {
+ return new string(str?.Where(ch => ch >= 0x20).ToArray());
+ }
+
+ private static string FilterByDict(string str, Dictionary dict)
+ {
+ return dict.Aggregate(
+ str, (current, kvp) =>
+ current.Replace(kvp.Key, kvp.Value));
}
}
}