Преглед на файлове

translations, one check for file exists when loading images, profanity filter for names

mbunch_kascope преди 2 години
родител
ревизия
f75c45c9af

+ 48 - 45
Assets/Scripts/DeckData.cs

@@ -13,12 +13,12 @@ public class DeckData
 
     public static int CardKindCellLength = (int)Math.Ceiling(Mathf.Log(maxCardKind, m));
 
-    #region  コンストラクタ
+    #region  constructor
     public DeckData(string DeckCode)
     {
         List<int> _DeckCardIDs = new List<int>();
         List<int> _DigitamaDeckCardIDs = new List<int>();
-        //コンマで区切り
+        //separated by commas
         string[] parseByComma = DeckCode.Split(',');
 
         List<int> DistinctDeckCardIDs = new List<int>();
@@ -29,16 +29,16 @@ public class DeckData
 
         for (int i = 0; i < parseByComma.Length; i++)
         {
-            //デッキ名
+            //deck name
             if (i == 0)
             {
                 DeckName = parseByComma[i];
             }
 
-            //デッキのカード(重複なし)
+            //Cards in the deck(no duplicates)
             else if (i == 1)
             {
-                //2文字ごとに区切り
+                //Separate every 2 characters
                 string[] SplitText = SplitClass.Split(parseByComma[i], CardKindCellLength);
 
                 for (int j = 0; j < SplitText.Length; j++)
@@ -47,32 +47,32 @@ public class DeckData
                 }
             }
 
-            //カード各種の枚数
+            //Number of each type of card
             else if (i == 2)
             {
-                //m進数の文字列
+                //m-ary string
                 string x_m = parseByComma[i];
 
                 if (!string.IsNullOrEmpty(x_m))
                 {
-                    //m進数をn進数に変換
+                    //Convert m-ary number to n-ary number
                     string x_n = ConvertBinaryNumber.NKStringToNString(x_m, n, log_n_m);
 
-                    //n進数の文字列を1文字ずつ区切り
+                    //Separate n-ary string by character
                     string[] Split_x_n = SplitClass.Split(x_n, 1);
 
                     for (int j = 0; j < Split_x_n.Length; j++)
                     {
-                        //n進数をintに変換
+                        //Convert n-ary number to int
                         DistinctDeckCardCounts.Add(ConvertBinaryNumber.NStringToInt(Split_x_n[j], n) + 1);
                     }
                 }
             }
 
-            //デジタマデッキのカード(重複なし)
+            //Digitama deck cards (no duplicates)
             else if (i == 3)
             {
-                //2文字ごとに区切り
+                //Separate every 2 characters
                 string[] SplitText = SplitClass.Split(parseByComma[i], CardKindCellLength);
 
                 for (int j = 0; j < SplitText.Length; j++)
@@ -81,29 +81,29 @@ public class DeckData
                 }
             }
 
-            //カード各種の枚数
+            //Number of each type of card
             else if (i == 4)
             {
-                //m進数の文字列
+                //m-ary string
                 string x_m = parseByComma[i];
 
                 if (!string.IsNullOrEmpty(x_m))
                 {
-                    //m進数をn進数に変換
+                    //Convert m-ary number to n-ary number
                     string x_n = ConvertBinaryNumber.NKStringToNString(x_m, n, log_n_m);
 
-                    //n進数の文字列を1文字ずつ区切り
+                    //Separate n-ary string by character
                     string[] Split_x_n = SplitClass.Split(x_n, 1);
 
                     for (int j = 0; j < Split_x_n.Length; j++)
                     {
-                        //n進数をintに変換
+                        //Convert n-ary number to int
                         DistinctDigitamaDeckCardCounts.Add(ConvertBinaryNumber.NStringToInt(Split_x_n[j], n) + 1);
                     }
                 }
             }
 
-            //キーカードID
+            //key card id
             else if (i == 5)
             {
                 if (int.TryParse(parseByComma[i], out int value))
@@ -140,7 +140,7 @@ public class DeckData
     }
     #endregion
 
-    #region デッキ名
+    #region deck name
     string _deckName = "";
     public string DeckName
     {
@@ -161,7 +161,7 @@ public class DeckData
     }
     #endregion
 
-    #region デッキに含まれるカードリスト
+    #region List of cards included in the deck
     public List<CEntity_Base> DeckCards()
     {
         List<CEntity_Base> deckCards = new List<CEntity_Base>();
@@ -183,7 +183,7 @@ public class DeckData
     }
     #endregion
 
-    #region デジタマデッキに含まれるカードリスト
+    #region List of cards included in the Digitama deck
     public List<CEntity_Base> DigitamaDeckCards()
     {
         List<CEntity_Base> deckCards = new List<CEntity_Base>();
@@ -202,7 +202,7 @@ public class DeckData
     }
     #endregion
 
-    #region デッキの全カード
+    #region all cards in the deck
     public List<CEntity_Base> AllDeckCards()
     {
         List<CEntity_Base> AllDeckCards = new List<CEntity_Base>();
@@ -221,7 +221,7 @@ public class DeckData
     }
     #endregion
 
-    #region キーカード
+    #region key card
     public int KeyCardId { get; set; } = -1;
 
     public CEntity_Base KeyCard
@@ -270,7 +270,7 @@ public class DeckData
     }
     #endregion
 
-    #region デッキに含まれるカードIDリスト
+    #region List of card IDs included in the deck
     public List<int> DeckCardIDs { get; set; } = new List<int>();
     public List<int> DigitamaDeckCardIDs { get; set; } = new List<int>();
 
@@ -372,7 +372,7 @@ public class DeckData
 
     #endregion
 
-    #region カードリストをソート
+    #region Sort card list
 
     public static List<CEntity_Base> SortedDeckCardsList(List<CEntity_Base> DeckCards)
     {
@@ -436,13 +436,13 @@ public class DeckData
     }
     #endregion
 
-    #region 256進数のデッキコードを取得
-    #region デッキ名とデッキのカードから256進数のデッキコードを取得
+    #region Get 256 hexadecimal deck code
+    #region Get the 256-decimal deck code from the deck name and deck card.
     public static string GetDeckCode(string _DeckName, List<CEntity_Base> _DeckCards, List<CEntity_Base> _DigitamaDeckCards, CEntity_Base keyCard)
     {
         string _DeckDataString = null;
 
-        //デッキ名
+        //deck name
         _DeckDataString += _DeckName + ",";
 
         SetDeckCard(_DeckCards);
@@ -458,14 +458,14 @@ public class DeckData
             _DeckDataString += $"-1,";
         }
 
-        //Debug.Log($"生デッキコード:{_DeckDataString}");
+        //Debug.Log($"raw deck cord:{_DeckDataString}");
 
         void SetDeckCard(List<CEntity_Base> cEntity_Bases)
         {
-            //カードリストを重複なしリストにする
+            //Make the card list a non-duplicate list
             List<CEntity_Base> DistinctDeckCards = cEntity_Bases.Distinct().ToList();
 
-            //重複なしのカードIDリストを登録
+            //Register a card ID list without duplicates
             foreach (CEntity_Base cardData in DistinctDeckCards)
             {
                 _DeckDataString += cardData.CardIndex_String;
@@ -473,7 +473,7 @@ public class DeckData
 
             _DeckDataString += ",";
 
-            //各カードの種類のカード枚数を保存(1減らす)
+            //Save the number of cards of each card type (reduce by 1)
             List<int> _DistinctDeckCardCounts = new List<int>();
 
             foreach (CEntity_Base cardData in DistinctDeckCards)
@@ -483,14 +483,14 @@ public class DeckData
 
             string x_n = null;
 
-            //デッキ内のカード枚数をn進数に変換
+            //Convert the number of cards in the deck to n-ary number
 
             for (int i = 0; i < _DistinctDeckCardCounts.Count; i++)
             {
                 x_n += ConvertBinaryNumber.IntToNString(_DistinctDeckCardCounts[i], n);
             }
 
-            //桁数がlog(n)m桁になるように0埋め
+            //Fill with 0s so that the number of digits is log(n)m digits
             if (x_n != null)
             {
                 while (x_n.Count() % log_n_m != 0)
@@ -499,7 +499,7 @@ public class DeckData
                 }
             }
 
-            //n進数をm進数に変換
+            //Convert n-ary number to m-ary number
             if (x_n != null)
             {
                 string x_m = ConvertBinaryNumber.NStringToNKString(x_n, n, log_n_m);
@@ -513,7 +513,7 @@ public class DeckData
     }
     #endregion
 
-    #region このデッキのデッキコードを取得
+    #region Get the deck code for this deck
     public string GetThisDeckCode()
     {
         return DeckData.GetDeckCode(DeckName, DeckCards(), DigitamaDeckCards(), KeyCard);
@@ -521,7 +521,7 @@ public class DeckData
     #endregion
     #endregion
 
-    #region その文字列がデッキコードとして適するか
+    #region Is the string suitable as a deck code?
     public static bool IsValidDeckCode(string DeckCode)
     {
         if (!DeckCode.Contains(","))
@@ -617,10 +617,10 @@ public class DeckData
     }
     #endregion
 
-    #region このデッキデータが対戦に使えるかどうか
+    #region Can this deck data be used in battle?
     public bool IsValidDeckData()
     {
-        //デッキ枚数はちょうど50枚
+        //The number of cards in the deck is exactly 50.
         if (DeckCards().Count != 50)
         {
             return false;
@@ -651,14 +651,14 @@ public class DeckData
     }
     #endregion
 
-    #region 空白のデッキコード
+    #region blank deck code
     public static DeckData EmptyDeckData()
     {
         return new DeckData("");
     }
     #endregion
 
-    #region インポートしたデッキデータを修正
+    #region Correct imported deck data
     public DeckData ModifiedDeckData()
     {
         List<CEntity_Base> deckCards = new List<CEntity_Base>();
@@ -682,7 +682,7 @@ public class DeckData
 
         List<CEntity_Base> modifiedList(List<CEntity_Base> cEntity_Bases)
         {
-            //カードリストを重複なしのリストにする
+            //Make the card list a non-duplicate list
             List<CEntity_Base> DistinctDeckCards = cEntity_Bases.Distinct().ToList();
 
             List<CEntity_Base> DistinctDeckCards1 = new List<CEntity_Base>();
@@ -702,7 +702,7 @@ public class DeckData
                 deckCards.Add(cEntity_Base);
             }
 
-            //規定枚数以上のカードを抜く
+            //Remove more than the specified number of cards
             foreach (CEntity_Base cEntity_Base in DistinctDeckCards1)
             {
                 while (cEntity_Base.SameCardIDCount(deckCards) > cEntity_Base.MaxCountInDeck)
@@ -741,7 +741,7 @@ public class DeckData
     }
     #endregion
 
-    #region デッキ名を修正
+    #region Fixed deck name
     public static string ValidateDeckName(string deckName)
     {
         if (String.IsNullOrEmpty(deckName))
@@ -762,12 +762,15 @@ public class DeckData
             deckName = deckName.Replace(error, "");
         }
 
+        var filter = new ProfanityFilter.ProfanityFilter();
+        deckName = filter.CensorString(deckName);
+
         return deckName;
     }
     #endregion
 }
 
-#region 文字列を分割
+#region split string
 public static class SplitClass
 {
     public static string[] Split(this string str, int count)

+ 8 - 0
Assets/Scripts/ProfanityFilter.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 50ed773344e1ca347848ba7c84e11a2a
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 116 - 0
Assets/Scripts/ProfanityFilter/AllowList.cs

@@ -0,0 +1,116 @@
+/*
+MIT License
+Copyright (c) 2019 
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Globalization;
+using ProfanityFilter.Interfaces;
+
+namespace ProfanityFilter
+{
+    public class AllowList : IAllowList
+    {
+        List<string> _allowList;
+
+        public AllowList()
+        {
+            _allowList = new List<string>();
+        }
+
+        /// <summary>
+        /// Return an instance of a read only collection containing allow list
+        /// </summary>
+        public ReadOnlyCollection<string> ToList
+        {
+            get
+            {
+                return new ReadOnlyCollection<string>(_allowList);
+            }
+        }
+
+        /// <summary>
+        /// Add a word to the profanity allow list. This means a word that is in the allow list
+        /// can be ignored. All words are treated as case insensitive.
+        /// </summary>
+        /// <param name="wordToAllowlist">The word that you want to allow list.</param>
+        public void Add(string wordToAllowlist)
+        {
+            if (string.IsNullOrEmpty(wordToAllowlist))
+            {
+                throw new ArgumentNullException(nameof(wordToAllowlist));
+            }
+
+            if (!_allowList.Contains(wordToAllowlist.ToLower(CultureInfo.InvariantCulture)))
+            {
+                _allowList.Add(wordToAllowlist.ToLower(CultureInfo.InvariantCulture));
+            }
+        }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="wordToCheck"></param>
+        /// <returns></returns>
+        public bool Contains(string wordToCheck)
+        {
+            if (string.IsNullOrEmpty(wordToCheck))
+            {
+                throw new ArgumentNullException(nameof(wordToCheck));
+            }
+
+            return _allowList.Contains(wordToCheck.ToLower(CultureInfo.InvariantCulture));
+        }
+
+        /// <summary>
+        /// Return the number of items in the allow list.
+        /// </summary>
+        /// <returns>The number of items in the allow list.</returns>
+        public int Count
+        {
+            get
+            {
+                return _allowList.Count;
+            }
+        }
+
+        /// <summary>
+        /// Remove all words from the allow list.
+        /// </summary>  
+        public void Clear()
+        {
+            _allowList.Clear();
+        }
+
+        /// <summary>
+        /// Remove a word from the profanity allow list. All words are treated as case insensitive.
+        /// </summary>
+        /// <param name="wordToRemove">The word that you want to use</param>
+        /// <returns>True if the word is successfuly removes, False otherwise.</returns>
+        public bool Remove(string wordToRemove)
+        {
+            if (string.IsNullOrEmpty(wordToRemove))
+            {
+                throw new ArgumentNullException(nameof(wordToRemove));
+            }
+
+            return _allowList.Remove(wordToRemove.ToLower(CultureInfo.InvariantCulture));
+        }
+    }
+}

+ 11 - 0
Assets/Scripts/ProfanityFilter/AllowList.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: cfd744cb9a5fef041b6226058dd80931
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 8 - 0
Assets/Scripts/ProfanityFilter/Interfaces.meta

@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 1cd0bd34197e5704784503f0f59a43a3
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 34 - 0
Assets/Scripts/ProfanityFilter/Interfaces/IAllowList.cs

@@ -0,0 +1,34 @@
+/*
+MIT License
+Copyright (c) 2019 
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+using System;
+using System.Collections.ObjectModel;
+
+namespace ProfanityFilter.Interfaces
+{
+    public interface IAllowList
+    {
+        void Add(string wordToAllowlist);
+        bool Contains(string wordToCheck);
+        bool Remove(string wordToRemove);
+        void Clear();
+        int Count { get; }
+        ReadOnlyCollection<string> ToList { get;  }
+    }
+}

+ 11 - 0
Assets/Scripts/ProfanityFilter/Interfaces/IAllowList.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 0bb7c21562ad744438927a04db9a4a0f
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 50 - 0
Assets/Scripts/ProfanityFilter/Interfaces/IProfanityFilter.cs

@@ -0,0 +1,50 @@
+/*
+MIT License
+Copyright (c) 2019 
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+
+namespace ProfanityFilter.Interfaces
+{
+    public interface IProfanityFilter
+    {
+        bool IsProfanity(string word);
+        ReadOnlyCollection<string> DetectAllProfanities(string sentence);
+        ReadOnlyCollection<string> DetectAllProfanities(string sentence, bool removePartialMatches);
+        bool ContainsProfanity(string term);
+        
+        IAllowList AllowList { get; }
+        string CensorString(string sentence);
+        string CensorString(string sentence, char censorCharacter);
+        string CensorString(string sentence, char censorCharacter, bool ignoreNumbers);
+        (int, int, string)? GetCompleteWord(string toCheck, string profanity);
+
+        void AddProfanity(string profanity);
+        void AddProfanity(string[] profanityList);
+        void AddProfanity(List<string> profanityList);
+
+        bool RemoveProfanity(string profanity);
+        bool RemoveProfanity(List<string> profanities);
+        bool RemoveProfanity(string [] profanities);
+
+        void Clear();
+
+        int Count { get; }
+    }
+}

+ 11 - 0
Assets/Scripts/ProfanityFilter/Interfaces/IProfanityFilter.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 9d0cae6799bed7740b6cba25267b74b0
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 193 - 0
Assets/Scripts/ProfanityFilter/ProfanityBase.cs

@@ -0,0 +1,193 @@
+/*
+MIT License
+Copyright (c) 2019 
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+
+namespace ProfanityFilter
+{
+    public partial class ProfanityBase
+    {
+        protected List<string> _profanities;
+
+        /// <summary>
+        /// Constructor that initializes the standard profanity list.
+        /// </summary>
+        public ProfanityBase()
+        {
+            _profanities = new List<string>(_wordList);
+        }
+
+        /// <summary>
+        /// Constructor that allows you to insert a custom array or profanities.
+        /// This list will replace the default list.
+        /// </summary>
+        /// <param name="profanityList">Array of words considered profanities.</param>
+        protected ProfanityBase(string[] profanityList)
+        {
+            if (profanityList == null)
+            {
+                throw new ArgumentNullException(nameof(profanityList));
+            }
+
+            _profanities = new List<string>(profanityList);
+        }
+
+        /// <summary>
+        /// Constructor that allows you to insert a custom list or profanities.
+        /// This list will replace the default list.
+        /// </summary>
+        /// <param name="profanityList">List of words considered profanities.</param>
+        protected ProfanityBase(List<string> profanityList)
+        {
+            if (profanityList == null)
+            {
+                throw new ArgumentNullException(nameof(profanityList));
+            }
+
+            _profanities = profanityList;
+        }
+
+        /// <summary>
+        /// Add a custom profanity to the list.
+        /// </summary>
+        /// <param name="profanity">The profanity to add.</param>
+        public void AddProfanity(string profanity)
+        {
+            if (string.IsNullOrEmpty(profanity))
+            {
+                throw new ArgumentNullException(nameof(profanity));
+            }
+
+            _profanities.Add(profanity);
+        }
+
+        /// <summary>
+        /// Add a custom array profanities to the defaultl list. This adds to the
+        /// default list, and does not replace it.
+        /// </summary>
+        /// <param name="profanityList">The array of profanities to add.</param>
+        public void AddProfanity(string[] profanityList)
+        {
+            if (profanityList == null)
+            {
+                throw new ArgumentNullException(nameof(profanityList));
+            }
+
+            _profanities.AddRange(profanityList);
+        }
+
+        /// <summary>
+        /// Add a custom list profanities to the defaultl list. This adds to the
+        /// default list, and does not replace it.
+        /// </summary>
+        /// <param name="profanityList">The list of profanities to add.</param>
+        public void AddProfanity(List<string> profanityList)
+        {
+            if (profanityList == null)
+            {
+                throw new ArgumentNullException(nameof(profanityList));
+            }
+
+            _profanities.AddRange(profanityList);
+        }
+
+        /// <summary>
+        /// Remove a profanity from the current loaded list of profanities.
+        /// </summary>
+        /// <param name="profanity">The profanity to remove from the list.</param>
+        /// <returns>True of the profanity was removed. False otherwise.</returns>
+        public bool RemoveProfanity(string profanity)
+        {
+            if (string.IsNullOrEmpty(profanity))
+            {
+                throw new ArgumentNullException(nameof(profanity));
+            }
+
+            return _profanities.Remove(profanity.ToLower(CultureInfo.InvariantCulture));
+        }
+
+        /// <summary>
+        /// Remove a list of profanities from the current loaded list of profanities.
+        /// </summary>
+        /// <param name="profanities">The list of profanities to remove from the list.</param>
+        /// <returns>True if the profanities were removed. False otherwise.</returns>
+        public bool RemoveProfanity(List<string> profanities)
+        {
+            if (profanities == null)
+            {
+                throw new ArgumentNullException(nameof(profanities));
+            }
+
+            foreach (string naughtyWord in profanities)
+            {
+                if (!RemoveProfanity(naughtyWord))
+                {
+                    return false;
+                }
+            }
+
+            return true;
+        }
+
+        /// <summary>
+        /// Remove an array of profanities from the current loaded list of profanities.
+        /// </summary>
+        /// <param name="profanities">The array of profanities to remove from the list.</param>
+        /// <returns>True if the profanities were removed. False otherwise.</returns>
+        public bool RemoveProfanity(string[] profanities)
+        {
+            if (profanities == null)
+            {
+                throw new ArgumentNullException(nameof(profanities));
+            }
+
+            foreach (string naughtyWord in profanities)
+            {
+                if (!RemoveProfanity(naughtyWord))
+                {
+                    return false;
+                }
+            }
+
+            return true;
+        }
+
+        /// <summary>
+        /// Remove all profanities from the current loaded list.
+        /// </summary>
+        public void Clear()
+        {
+            _profanities.Clear();
+        }
+
+        /// <summary>
+        /// Return the number of profanities in the system.
+        /// </summary>
+        public int Count
+        {
+            get
+            {
+                return _profanities.Count;
+            }
+        }
+    }
+}

+ 11 - 0
Assets/Scripts/ProfanityFilter/ProfanityBase.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: d096475999a6a6741ba12527c159d141
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 445 - 0
Assets/Scripts/ProfanityFilter/ProfanityFilter.cs

@@ -0,0 +1,445 @@
+/*
+MIT License
+Copyright (c) 2019
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Text.RegularExpressions;
+using ProfanityFilter.Interfaces;
+
+namespace ProfanityFilter
+{
+    /// <summary>
+    ///
+    /// This class will detect profanity and racial slurs contained within some text and return an indication flag.
+    /// All words are treated as case insensitive.
+    ///
+    /// </summary>
+    public class ProfanityFilter : ProfanityBase, IProfanityFilter
+    {
+
+        /// <summary>
+        /// Default constructor that loads up the default profanity list.
+        /// </summary>
+        public ProfanityFilter()
+        {
+            AllowList = new AllowList();
+        }
+
+        /// <summary>
+        /// Constructor overload that allows you to construct the filter with a customer
+        /// profanity list.
+        /// </summary>
+        /// <param name="profanityList">Array of words to add into the filter.</param>
+        public ProfanityFilter(string[] profanityList) : base (profanityList)
+        {
+            AllowList = new AllowList();
+        }
+
+        /// <summary>
+        /// Constructor overload that allows you to construct the filter with a customer
+        /// profanity list.
+        /// </summary>
+        /// <param name="profanityList">List of words to add into the filter.</param>
+        public ProfanityFilter(List<string> profanityList) : base(profanityList)
+        {
+            AllowList = new AllowList();
+        }
+
+        /// <summary>
+        /// Return the allow list;
+        /// </summary>
+        public IAllowList AllowList { get; }
+
+        /// <summary>
+        /// Check whether a specific word is in the profanity list. IsProfanity will first
+        /// check if the word exists on the allow list. If it is on the allow list, then false
+        /// will be returned.
+        /// </summary>
+        /// <param name="word">The word to check in the profanity list.</param>
+        /// <returns>True if the word is considered a profanity, False otherwise.</returns>
+        public bool IsProfanity(string word)
+        {
+            if (string.IsNullOrEmpty(word))
+            {
+                return false;
+            }
+
+            // Check if the word is in the allow list.
+            if (AllowList.Contains(word.ToLower(CultureInfo.InvariantCulture)))
+            {
+                return false;
+            }
+
+            return _profanities.Contains(word.ToLower(CultureInfo.InvariantCulture));
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="sentence"></param>
+        /// <returns></returns>
+        public ReadOnlyCollection<string> DetectAllProfanities(string sentence)
+        {
+            return DetectAllProfanities(sentence, false);
+        }
+
+        /// <summary>
+        /// For a given sentence, return a list of all the detected profanities.
+        /// </summary>
+        /// <param name="sentence">The sentence to check for profanities.</param>
+        /// <param name="removePartialMatches">Remove duplicate partial matches.</param>
+        /// <returns>A read only list of detected profanities.</returns>
+        public ReadOnlyCollection<string> DetectAllProfanities(string sentence, bool removePartialMatches)
+        {
+            if (string.IsNullOrEmpty(sentence))
+            {
+                return new ReadOnlyCollection<string>(new List<string>());
+            }
+
+            sentence = sentence.ToLower();
+            sentence = sentence.Replace(".", "");
+            sentence = sentence.Replace(",", "");
+
+            var words = sentence.Split(' ');
+            var postAllowList = FilterWordListByAllowList(words);
+            List<string> swearList = new List<string>();
+
+            // Catch whether multi-word profanities are in the allow list filtered sentence.
+            AddMultiWordProfanities(swearList, ConvertWordListToSentence(postAllowList));
+
+            // Deduplicate any partial matches, ie, if the word "twatting" is in a sentence, don't include "twat" if part of the same word.
+            if (removePartialMatches)
+            {
+                swearList.RemoveAll(x => swearList.Any(y => x != y && y.Contains(x)));
+            }
+
+            return new ReadOnlyCollection<string>(FilterSwearListForCompleteWordsOnly(sentence, swearList).Distinct().ToList());
+        }
+
+        /// <summary>
+        /// For any given string, censor any profanities from the list using the default
+        /// censoring character of an asterix.
+        /// </summary>
+        /// <param name="sentence">The string to censor.</param>
+        /// <returns></returns>
+        public string CensorString(string sentence)
+        {
+            return CensorString(sentence, '*');
+        }
+
+        /// <summary>
+        /// For any given string, censor any profanities from the list using the specified
+        /// censoring character.
+        /// </summary>
+        /// <param name="sentence">The string to censor.</param>
+        /// <param name="censorCharacter">The character to use for censoring.</param>
+        /// <returns></returns>
+        public string CensorString(string sentence, char censorCharacter)
+        {
+            return CensorString(sentence, censorCharacter, false);
+        }
+
+        /// <summary>
+        /// For any given string, censor any profanities from the list using the specified
+        /// censoring character.
+        /// </summary>
+        /// <param name="sentence">The string to censor.</param>
+        /// <param name="censorCharacter">The character to use for censoring.</param>
+        /// <param name="ignoreNumbers">Ignore any numbers that appear in a word.</param>
+        /// <returns></returns>
+        public string CensorString(string sentence, char censorCharacter, bool ignoreNumbers)
+        {
+            if (string.IsNullOrEmpty(sentence))
+            {
+                return string.Empty;
+            }
+
+            string noPunctuation = sentence.Trim();
+            noPunctuation = noPunctuation.ToLower();
+
+            noPunctuation = Regex.Replace(noPunctuation, @"[^\w\s]", "");
+
+            var words = noPunctuation.Split(' ');
+
+            var postAllowList = FilterWordListByAllowList(words);
+            var swearList = new List<string>();
+
+            // Catch whether multi-word profanities are in the allow list filtered sentence.
+            AddMultiWordProfanities(swearList, ConvertWordListToSentence(postAllowList));
+
+
+            StringBuilder censored = new StringBuilder(sentence);
+            StringBuilder tracker = new StringBuilder(sentence);
+
+            return CensorStringByProfanityList(censorCharacter, swearList, censored, tracker, ignoreNumbers).ToString();
+        }
+
+        /// <summary>
+        /// For a given sentence, look for the specified profanity. If it is found, look to see
+        /// if it is part of a containing word. If it is, then return the containing work and the start
+        /// and end positions of that word in the string.
+        ///
+        /// For example, if the string contains "scunthorpe" and the passed in profanity is "cunt",
+        /// then this method will find "cunt" and work out that it is part of an enclosed word.
+        /// </summary>
+        /// <param name="toCheck">Sentence to check.</param>
+        /// <param name="profanity">Profanity to look for.</param>
+        /// <returns>Tuple of the following format (start character, end character, found enclosed word).
+        /// If no enclosed word is found then return null.</returns>
+        public (int, int, string)? GetCompleteWord(string toCheck, string profanity)
+        {
+            if (string.IsNullOrEmpty(toCheck))
+            {
+                return null;
+            }
+
+            string profanityLowerCase = profanity.ToLower(CultureInfo.InvariantCulture);
+            string toCheckLowerCase = toCheck.ToLower(CultureInfo.InvariantCulture);
+
+            if (toCheckLowerCase.Contains(profanityLowerCase))
+            {
+                var startIndex = toCheckLowerCase.IndexOf(profanityLowerCase, StringComparison.Ordinal);
+                var endIndex = startIndex;
+
+                // Work backwards in string to get to the start of the word.
+                while (startIndex > 0)
+                {
+                    if (toCheck[startIndex - 1] == ' ' || char.IsPunctuation(toCheck[startIndex - 1]))
+                    {
+                        break;
+                    }
+
+                    startIndex -= 1;
+                }
+
+                // Work forwards to get to the end of the word.
+                while (endIndex < toCheck.Length)
+                {
+                    if (toCheck[endIndex] == ' ' || char.IsPunctuation(toCheck[endIndex]))
+                    {
+                        break;
+                    }
+
+                    endIndex += 1;
+                }
+
+                return (startIndex, endIndex, toCheckLowerCase.Substring(startIndex, endIndex - startIndex).ToLower(CultureInfo.InvariantCulture));
+            }
+
+            return null;
+        }
+
+        /// <summary>
+        /// Check whether a given term matches an entry in the profanity list. ContainsProfanity will first
+        /// check if the word exists on the allow list. If it is on the allow list, then false
+        /// will be returned.
+        /// </summary>
+        /// <param name="term">Term to check.</param>
+        /// <returns>True if the term contains a profanity, False otherwise.</returns>
+        public bool ContainsProfanity(string term)
+        {
+            if (string.IsNullOrWhiteSpace(term))
+            {
+                return false;
+            }
+
+            List<string> potentialProfanities = _profanities.Where(word => word.Length <= term.Length).ToList();
+            
+            // We might have a very short phrase coming in, resulting in no potential matches even before the regex
+            if (potentialProfanities.Count == 0)
+            {
+                return false;
+            }
+
+            Regex regex = new Regex(string.Format(@"(?:{0})", string.Join("|", potentialProfanities).Replace("$", "\\$"), RegexOptions.IgnoreCase));
+
+            foreach (Match profanity in regex.Matches(term))
+            {
+                // if any matches are found and aren't in the allowed list, we can return true here without checking further
+                if (!AllowList.Contains(profanity.Value.ToLower(CultureInfo.InvariantCulture)))
+                {
+                    return true;
+                }
+            }
+
+            return false;
+        }
+
+        private StringBuilder CensorStringByProfanityList(char censorCharacter, List<string> swearList, StringBuilder censored, StringBuilder tracker, bool ignoreNumeric)
+        {
+            foreach (string word in swearList.OrderByDescending(x => x.Length))
+            {
+                (int, int, string)? result = (0, 0, "");
+                var multiWord = word.Split(' ');
+
+                if (multiWord.Length == 1)
+                {
+                    do
+                    {
+                        result = GetCompleteWord(tracker.ToString(), word);
+
+                        if (result != null)
+                        {
+                            string filtered = result.Value.Item3;
+
+                            if (ignoreNumeric)
+                            {
+                                filtered = Regex.Replace(result.Value.Item3, @"[\d-]", string.Empty);
+                            }
+
+                            if (filtered == word)
+                            {
+                                for (int i = result.Value.Item1; i < result.Value.Item2; i++)
+                                {
+                                    censored[i] = censorCharacter;
+                                    tracker[i] = censorCharacter;
+                                }
+                            }
+                            else
+                            {
+                                for (int i = result.Value.Item1; i < result.Value.Item2; i++)
+                                {
+                                    tracker[i] = censorCharacter;
+                                }
+                            }
+                        }
+                    }
+                    while (result != null);
+                }
+                else
+                {
+                    censored = censored.Replace(word, CreateCensoredString(word, censorCharacter));
+                }
+            }
+
+            return censored;
+        }
+
+        private List<string> FilterSwearListForCompleteWordsOnly(string sentence, List<string> swearList)
+        {
+            List<string> filteredSwearList = new List<string>();
+            StringBuilder tracker = new StringBuilder(sentence);
+
+            foreach (string word in swearList.OrderByDescending(x => x.Length))
+            {
+                (int, int, string)? result = (0, 0, "");
+                var multiWord = word.Split(' ');
+
+                if (multiWord.Length == 1)
+                {
+                    do
+                    {
+                        result = GetCompleteWord(tracker.ToString(), word);
+
+                        if (result != null)
+                        {
+                            if (result.Value.Item3 == word)
+                            {
+                                filteredSwearList.Add(word);
+
+                                for (int i = result.Value.Item1; i < result.Value.Item2; i++)
+                                {
+                                    tracker[i] = '*';
+                                }
+                                break;
+                            }
+
+                            for (int i = result.Value.Item1; i < result.Value.Item2; i++)
+                            {
+                                tracker[i] = '*';
+                            }
+                        }
+                    }
+                    while (result != null);
+                }
+                else
+                {
+                    filteredSwearList.Add(word);
+                    tracker.Replace(word, " ");
+                }
+            }
+
+            return filteredSwearList;
+        }
+
+        private List<string> FilterWordListByAllowList(string[] words)
+        {
+            List<string> postAllowList = new List<string>();
+            foreach (string word in words)
+            {
+                if (!string.IsNullOrEmpty(word))
+                {
+                    if (!AllowList.Contains(word.ToLower(CultureInfo.InvariantCulture)))
+                    {
+                        postAllowList.Add(word);
+                    }
+                }
+            }
+
+            return postAllowList;
+        }
+
+        private static string ConvertWordListToSentence(List<string> postAllowList)
+        {
+            // Reconstruct sentence excluding allow listed words.
+            string postAllowListSentence = string.Empty;
+
+            foreach (string w in postAllowList)
+            {
+                postAllowListSentence = postAllowListSentence + w + " ";
+            }
+
+            return postAllowListSentence;
+        }
+
+        private void AddMultiWordProfanities(List<string> swearList, string postAllowListSentence)
+        {
+            swearList.AddRange(
+                from string profanity in _profanities
+                where postAllowListSentence.ToLower(CultureInfo.InvariantCulture).Contains(profanity)
+                select profanity);
+        }
+
+        private static string CreateCensoredString(string word, char censorCharacter)
+        {
+            string censoredWord = string.Empty;
+
+            for (int i = 0; i < word.Length; i++)
+            {
+                if (word[i] != ' ')
+                {
+                    censoredWord += censorCharacter;
+                }
+                else
+                {
+                    censoredWord += ' ';
+                }
+            }
+
+            return censoredWord;
+        }
+
+
+    }
+}

+ 11 - 0
Assets/Scripts/ProfanityFilter/ProfanityFilter.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: be0507fee96849b478d2d60a345c6a80
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 1649 - 0
Assets/Scripts/ProfanityFilter/ProfanityList.cs

@@ -0,0 +1,1649 @@
+/*
+MIT License
+Copyright (c) 2019 
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+namespace ProfanityFilter
+{
+    /// <summary>
+    /// This class contains the profanity list.
+    ///
+    /// WARNING : This file contains a lot of very offensive terminology. Do not read the content of this source code
+    /// file if you are easily offended.
+    /// </summary>
+    public partial class ProfanityBase
+    {
+        private readonly string[] _wordList =
+        {
+             "2 girls 1 cup",
+             "2 girls one cup",
+             "2g1c",
+             "4r5e",
+             "5h1t",
+             "5hit",
+             "8===D",
+             "8==D",
+             "8=D",
+             "a$$",
+             "a$$hole",
+             "a_s_s",
+             "a2m",
+             "a55",
+             "a55hole",
+             "acrotomophilia",
+             "aeolus",
+             "ahole",
+             "alabama hot pocket",
+             "alaskan pipeline",
+             "anal",
+             "anal impaler",
+             "anal leakage",
+             "analprobe",
+             "anilingus",
+             "angrydragon",
+             "angry dragon",
+             "anus",
+             "apeshit",
+             "ar5e",
+             "arian",
+             "arrse",
+             "arse",
+             "arses",
+             "arsehole",
+             "aryan",
+             "ass",
+             "ass fuck",
+             "ass hole",
+             "assbag",
+             "assbandit",
+             "assbang",
+             "assbanged",
+             "assbanger",
+             "assbangs",
+             "assbite",
+             "assclown",
+             "asscock",
+             "asscracker",
+             "asses",
+             "assface",
+             "assfaces",
+             "assfuck",
+             "assfucker",
+             "ass-fucker",
+             "assfukka",
+             "assgoblin",
+             "assh0le",
+             "asshat",
+             "ass-hat",
+             "asshead",
+             "assho1e",
+             "asshole",
+             "assholes",
+             "asshopper",
+             "ass-jabber",
+             "assjacker",
+             "asslick",
+             "asslicker",
+             "assmaster",
+             "assmonkey",
+             "assmucus",
+             "assmunch",
+             "assmuncher",
+             "assnigger",
+             "asspirate",
+             "ass-pirate",
+             "assshit",
+             "assshole",
+             "asssucker",
+             "asswad",
+             "asswhole",
+             "asswipe",
+             "asswipes",
+             "auto erotic",
+             "autoerotic",
+             "axwound",
+             "axewound",
+             "axe wound",
+             "azazel",
+             "azz",
+             "b!tch",
+             "b00bs",
+             "b17ch",
+             "b1tch",
+             "babeland",
+             "baby batter",
+             "baby juice",
+             "ball gag",
+             "ball gravy",
+             "ball kicking",
+             "ball licking",
+             "ball sack",
+             "ball sucking",
+             "ballbag",
+             "balls",
+             "ballsack",
+             "bampot",
+             "bang (one's) box",
+             "bangbros",
+             "bareback",
+             "barely legal",
+             "barenaked",
+             "barf",
+             "bastard",
+             "bastardo",
+             "bastards",
+             "bastinado",
+             "batty boy",
+             "bawdy",
+             "bbw",
+             "bdsm",
+             "beaner",
+             "beaners",
+             "beardedclam",
+             "beastial",
+             "beastiality",
+             "beatch",
+             "beaver",
+             "beaver cleaver",
+             "beaver lips",
+             "beef curtain",
+             "beef curtains",
+             "beeyotch",
+             "bellend",
+             "bender",
+             "beotch",
+             "bescumber",
+             "bestial",
+             "bestiality",
+             "bi+ch",
+             "biatch",
+             "big black",
+             "big breasts",
+             "big knockers",
+             "big tits",
+             "bigtits",
+             "bimbo",
+             "bimbos",
+             "bint",
+             "birdlock",
+             "bitch",
+             "bitch tit",
+             "bitchass",
+             "bitched",
+             "bitcher",
+             "bitchers",
+             "bitches",
+             "bitchin",
+             "bitching",
+             "bitchtits",
+             "bitchy",
+             "black cock",
+             "blonde action",
+             "blonde on blonde action",
+             "bloodclaat",
+             "bloody",
+             "bloody hell",
+             "blow job",
+             "blow me",
+             "blow mud",
+             "blow your load",
+             "blowjob",
+             "blowjobs",
+             "blue waffle",
+             "blumpkin",
+             "bod",
+             "bodily",
+             "boink",
+             "boiolas",
+             "bollock",
+             "bollocks",
+             "bollok",
+             "bollox",
+             "bondage",
+             "boned",
+             "boner",
+             "boners",
+             "bong",
+             "boob",
+             "boobies",
+             "boobs",
+             "booby",
+             "booger",
+             "bookie",
+             "boong",
+             "booobs",
+             "boooobs",
+             "booooobs",
+             "booooooobs",
+             "bootee",
+             "bootie",
+             "booty",
+             "booty call",
+             "booze",
+             "boozer",
+             "boozy",
+             "bosom",
+             "bosomy",
+             "breasts",
+             "breeder",
+             "brotherfucker",
+             "brown showers",
+             "brunette action",
+             "buceta",
+             "bugger",
+             "bukkake",
+             "bull shit",
+             "bulldyke",
+             "bullet vibe",
+             "bullshit",
+             "bullshits",
+             "bullshitted",
+             "bullturds",
+             "bum",
+             "bum boy",
+             "bumblefuck",
+             "bumclat",
+             "bummer",
+             "buncombe",
+             "bung",
+             "bung hole",
+             "bunghole",
+             "bunny fucker",
+             "bust a load",
+             "busty",
+             "butt",
+             "butt fuck",
+             "butt plug",
+             "buttcheeks",
+             "buttfuck",
+             "buttfucka",
+             "buttfucker",
+             "butthole",
+             "buttmuch",
+             "buttmunch",
+             "butt-pirate",
+             "buttplug",
+             "c.0.c.k",
+             "c.o.c.k.",
+             "c.u.n.t",
+             "c0ck",
+             "c-0-c-k",
+             "c0cksucker",
+             "caca",
+             "cacafuego",
+             "cahone",
+             "camel toe",
+             "cameltoe",
+             "camgirl",
+             "camslut",
+             "camwhore",
+             "carpet muncher",
+             "carpetmuncher",
+             "cawk",
+             "cervix",
+             "chesticle",
+             "chi-chi man",
+             "chick with a dick",
+             "child-fucker",
+             "chinc",
+             "chincs",
+             "chink",
+             "chinky",
+             "choad",
+             "choade",
+             "choc ice",
+             "chocolate rosebuds",
+             "chode",
+             "chodes",
+             "chota bags",
+             "cipa",
+             "circlejerk",
+             "cl1t",
+             "cleveland steamer",
+             "climax",
+             "clit",
+             "clit licker",
+             "clitface",
+             "clitfuck",
+             "clitoris",
+             "clits",
+             "clitty",
+             "clitty litter",
+             "clover clamps",
+             "clunge",
+             "clusterfuck",
+             "cnut",
+             "cocain",
+             "cocaine",
+             "coccydynia",
+             "cock",
+             "c-o-c-k",
+             "cock pocket",
+             "cock snot",
+             "cock sucker",
+             "cockass",
+             "cockbite",
+             "cockblock",
+             "cockburger",
+             "cockeye",
+             "cockface",
+             "cockfucker",
+             "cockhead",
+             "cockholster",
+             "cockjockey",
+             "cockknocker",
+             "cockknoker",
+             "cocklump",
+             "cockmaster",
+             "cockmongler",
+             "cockmongruel",
+             "cockmonkey",
+             "cockmunch",
+             "cockmuncher",
+             "cocknose",
+             "cocknugget",
+             "cocks",
+             "cockshit",
+             "cocksmith",
+             "cocksmoke",
+             "cocksmoker",
+             "cocksniffer",
+             "cocksuck",
+             "cocksucked",
+             "cocksucker",
+             "cock-sucker",
+             "cocksuckers",
+             "cocksucking",
+             "cocksucks",
+             "cocksuka",
+             "cocksukka",
+             "cockwaffle",
+             "coffin dodger",
+             "coital",
+             "cok",
+             "cokmuncher",
+             "coksucka",
+             "commie",
+             "condom",
+             "coochie",
+             "coochy",
+             "coon",
+             "coonnass",
+             "coons",
+             "cooter",
+             "cop some wood",
+             "coprolagnia",
+             "coprophilia",
+             "corksucker",
+             "cornhole",
+             "corp whore",
+             "corpulent",
+             "cox",
+             "crabs",
+             "crack",
+             "cracker",
+             "crackwhore",
+             "crap",
+             "crappy",
+             "creampie",
+             "cretin",
+             "crikey",
+             "cripple",
+             "crotte",
+             "cum",
+             "cum chugger",
+             "cum dumpster",
+             "cum freak",
+             "cum guzzler",
+             "cumbubble",
+             "cumdump",
+             "cumdumpster",
+             "cumguzzler",
+             "cumjockey",
+             "cummer",
+             "cummin",
+             "cumming",
+             "cums",
+             "cumshot",
+             "cumshots",
+             "cumslut",
+             "cumstain",
+             "cumtart",
+             "cunilingus",
+             "cunillingus",
+             "cunnie",
+             "cunnilingus",
+             "cunny",
+             "cunt",
+             "c-u-n-t",
+             "cunt hair",
+             "cuntass",
+             "cuntbag",
+             "cuntface",
+             "cunthole",
+             "cunthunter",
+             "cuntlick",
+             "cuntlicker",
+             "cuntrag",
+             "cunts",
+             "cuntsicle",
+             "cuntslut",
+             "cunt-struck",
+             "cus",
+             "cut rope",
+             "cyalis",
+             "cyberfuc",
+             "cyberfuck",
+             "cyberfucked",
+             "cyberfucker",
+             "cyberfucking",
+             "d0ng",
+             "d0uch3",
+             "d0uche",
+             "d1ck",
+             "d1ld0",
+             "d1ldo",
+             "dago",
+             "dagos",
+             "dammit",
+             "damn",
+             "damned",
+             "damnit",
+             "darkie",
+             "darn",
+             "date rape",
+             "daterape",
+             "dawgie-style",
+             "deep throat",
+             "deepthroat",
+             "deggo",
+             "dendrophilia",
+             "dick",
+             "dick head",
+             "dick hole",
+             "dick shy",
+             "dickbag",
+             "dickbeaters",
+             "dickdipper",
+             "dickface",
+             "dickflipper",
+             "dickfuck",
+             "dickfucker",
+             "dickhead",
+             "dickheads",
+             "dickhole",
+             "dickish",
+             "dick-ish",
+             "dickjuice",
+             "dickmilk",
+             "dickmonger",
+             "dickripper",
+             "dicks",
+             "dicksipper",
+             "dickslap",
+             "dick-sneeze",
+             "dicksucker",
+             "dicksucking",
+             "dicktickler",
+             "dickwad",
+             "dickweasel",
+             "dickweed",
+             "dickwhipper",
+             "dickwod",
+             "dickzipper",
+             "diddle",
+             "dike",
+             "dildo",
+             "dildos",
+             "diligaf",
+             "dillweed",
+             "dimwit",
+             "dingle",
+             "dingleberries",
+             "dingleberry",
+             "dink",
+             "dinks",
+             "dipship",
+             "dirsa",
+             "dirty",
+             "dirty pillows",
+             "dirty sanchez",
+             "div",
+             "dlck",
+             "dog style",
+             "dog-fucker",
+             "doggie style",
+             "doggiestyle",
+             "doggie-style",
+             "doggin",
+             "dogging",
+             "doggy style",
+             "doggystyle",
+             "doggy-style",
+             "dolcett",
+             "domination",
+             "dominatrix",
+             "dommes",
+             "dong",
+             "donkey punch",
+             "donkeypunch",
+             "donkeyribber",
+             "doochbag",
+             "doofus",
+             "dookie",
+             "doosh",
+             "dopey",
+             "double dong",
+             "double penetration",
+             "doublelift",
+             "douch3",
+             "douche",
+             "douchebag",
+             "douchebags",
+             "douche-fag",
+             "douchewaffle",
+             "douchey",
+             "dp action",
+             "drunk",
+             "dry hump",
+             "duche",
+             "dumass",
+             "dumb ass",
+             "dumbass",
+             "dumbasses",
+             "dumbcunt",
+             "dumbfuck",
+             "dumbshit",
+             "dummy",
+             "dumshit",
+             "dvda",
+             "dyke",
+             "dykes",
+             "eat a dick",
+             "eat hair pie",
+             "eat my ass",
+             "ecchi",
+             "ejaculate",
+             "ejaculated",
+             "ejaculates",
+             "ejaculating",
+             "ejaculatings",
+             "ejaculation",
+             "ejakulate",
+             "erect",
+             "erection",
+             "erotic",
+             "erotism",
+             "escort",
+             "essohbee",
+             "eunuch",
+             "extacy",
+             "extasy",
+             "f u c k",
+             "f u c k e r",
+             "f.u.c.k",
+             "f_u_c_k",
+             "f4nny",
+             "facial",
+             "fack",
+             "fag",
+             "fagbag",
+             "fagfucker",
+             "fagg",
+             "fagged",
+             "fagging",
+             "faggit",
+             "faggitt",
+             "faggot",
+             "faggotcock",
+             "faggots",
+             "faggs",
+             "fagot",
+             "fagots",
+             "fags",
+             "fagtard",
+             "faig",
+             "faigt",
+             "fanny",
+             "fannybandit",
+             "fannyflaps",
+             "fannyfucker",
+             "fanyy",
+             "fart",
+             "fartknocker",
+             "fatass",
+             "fcuk",
+             "fcuker",
+             "fcuking",
+             "fecal",
+             "feck",
+             "fecker",
+             "feist",
+             "felch",
+             "felcher",
+             "felching",
+             "fellate",
+             "fellatio",
+             "feltch",
+             "feltcher",
+             "female squirting",
+             "femdom",
+             "fenian",
+             "fice",
+             "figging",
+             "fingerbang",
+             "fingerfuck",
+             "fingerfucked",
+             "fingerfucker",
+             "fingerfuckers",
+             "fingerfucking",
+             "fingerfucks",
+             "fingering",
+             "fist fuck",
+             "fisted",
+             "fistfuck",
+             "fistfucked",
+             "fistfucker",
+             "fistfuckers",
+             "fistfuckings",
+             "fistfucks",
+             "fisting",
+             "fisty",
+             "flamer",
+             "flange",
+             "flaps",
+             "fleshflute",
+             "flog the log",
+             "floozy",
+             "foad",
+             "foah",
+             "fondle",
+             "foobar",
+             "fook",
+             "fooker",
+             "foot fetish",
+             "footjob",
+             "foreskin",
+             "freex",
+             "frenchify",
+             "frigg",
+             "frigga",
+             "frotting",
+             "fubar",
+             "fuc",
+             "fuck",
+             "f-u-c-k",
+             "fuck buttons",
+             "fuck hole",
+             "fuck off",
+             "fuck puppet",
+             "fuck trophy",
+             "fuck yo mama",
+             "fuck you",
+             "fucka",
+             "fuckass",
+             "fuck-ass",
+             "fuckbag",
+             "fuck bag",
+             "fuck-bitch",
+             "fuckboy",
+             "fuckbrain",
+             "fuckbutt",
+             "fuckbutter",
+             "fucked",
+             "fuckedup",
+             "fucked up",
+             "fucker",
+             "fuckers",
+             "fuckersucker",
+             "fuckface",
+             "fuckhead",
+             "fuckheads",
+             "fuckhole",
+             "fuckin",
+             "fucking",
+             "fuckings",
+             "fuckme",
+             "fuck me",
+             "fuckmeat",
+             "fucknugget",
+             "fucknut",
+             "fucknutt",
+             "fuckoff",
+             "fucks",
+             "fuckstick",
+             "fucktard",
+             "fuck-tard",
+             "fucktards",
+             "fucktart",
+             "fucktoy",
+             "fucktwat",
+             "fuckup",
+             "fuckwad",
+             "fuckwhit",
+             "fuckwit",
+             "fuckwitt",
+             "fudge packer",
+             "fudgepacker",
+             "fudge-packer",
+             "fuk",
+             "fuker",
+             "fukker",
+             "fukkers",
+             "fukkin",
+             "fuks",
+             "fukwhit",
+             "fukwit",
+             "fuq",
+             "futanari",
+             "fux",
+             "fux0r",
+             "fvck",
+             "fxck",
+             "gae",
+             "gai",
+             "gang bang",
+             "gangbang",
+             "gang-bang",
+             "gangbanged",
+             "gangbangs",
+             "ganja",
+             "gash",
+             "gassy ass",
+             "gay sex",
+             "gayass",
+             "gaybob",
+             "gaydo",
+             "gayfuck",
+             "gayfuckist",
+             "gaylord",
+             "gays",
+             "gaysex",
+             "gaytard",
+             "gaywad",
+             "gender bender",
+             "genitals",
+             "gey",
+             "gfy",
+             "ghay",
+             "ghey",
+             "giant cock",
+             "gigolo",
+             "ginger",
+             "gippo",
+             "girl on",
+             "girl on top",
+             "girls gone wild",
+             "glans",
+             "goatcx",
+             "goatse",
+             "god",
+             "god damn",
+             "godamn",
+             "godamnit",
+             "goddam",
+             "god-dam",
+             "goddammit",
+             "goddamn",
+             "goddamned",
+             "god-damned",
+             "goddamnit",
+             "godsdamn",
+             "gokkun",
+             "golden shower",
+             "goldenshower",
+             "golliwog",
+             "gonad",
+             "gonads",
+             "goo girl",
+             "gooch",
+             "goodpoop",
+             "gook",
+             "gooks",
+             "goregasm",
+             "gringo",
+             "grope",
+             "group sex",
+             "gspot",
+             "g-spot",
+             "gtfo",
+             "guido",
+             "guro",
+             "h0m0",
+             "h0mo",
+             "ham flap",
+             "hand job",
+             "handjob",
+             "hard core",
+             "hard on",
+             "hardcore",
+             "hardcoresex",
+             "he11",
+             "hebe",
+             "heeb",
+             "hell",
+             "hemp",
+             "hentai",
+             "heroin",
+             "herp",
+             "herpes",
+             "herpy",
+             "heshe",
+             "he-she",
+             "hircismus",
+             "hitler",
+             "hiv",
+             "hoar",
+             "hoare",
+             "hobag",
+             "hoe",
+             "hoer",
+             "holy shit",
+             "hom0",
+             "homey",
+             "homo",
+             "homodumbshit",
+             "homoerotic",
+             "homoey",
+             "honkey",
+             "honky",
+             "hooch",
+             "hookah",
+             "hooker",
+             "hoor",
+             "hootch",
+             "hooter",
+             "hooters",
+             "hore",
+             "horniest",
+             "horny",
+             "hot carl",
+             "hot chick",
+             "hotsex",
+             "how to kill",
+             "how to murdep",
+             "how to murder",
+             "huge fat",
+             "hump",
+             "humped",
+             "humping",
+             "hun",
+             "hussy",
+             "hymen",
+             "iap",
+             "iberian slap",
+             "inbred",
+             "incest",
+             "injun",
+             "intercourse",
+             "jack off",
+             "jackass",
+             "jackasses",
+             "jackhole",
+             "jackoff",
+             "jack-off",
+             "jaggi",
+             "jagoff",
+             "jail bait",
+             "jailbait",
+             "jap",
+             "japs",
+             "jelly donut",
+             "jerk",
+             "jerk off",
+             "jerk0ff",
+             "jerkass",
+             "jerked",
+             "jerkoff",
+             "jerk-off",
+             "jigaboo",
+             "jiggaboo",
+             "jiggerboo",
+             "jism",
+             "jiz",
+             "jizm",
+             "jizz",
+             "jizzed",
+             "jock",
+             "juggs",
+             "jungle bunny",
+             "junglebunny",
+             "junkie",
+             "junky",
+             "kafir",
+             "kawk",
+             "kike",
+             "kikes",
+             "kill",
+             "kinbaku",
+             "kinkster",
+             "kinky",
+             "klan",
+             "knob",
+             "knob end",
+             "knobbing",
+             "knobead",
+             "knobed",
+             "knobend",
+             "knobhead",
+             "knobjocky",
+             "knobjokey",
+             "kock",
+             "kondum",
+             "kondums",
+             "kooch",
+             "kooches",
+             "kootch",
+             "kraut",
+             "kum",
+             "kummer",
+             "kumming",
+             "kums",
+             "kunilingus",
+             "kunja",
+             "kunt",
+             "kwif",
+             "kyke",
+             "l3i+ch",
+             "l3itch",
+             "labia",
+             "lameass",
+             "lardass",
+             "leather restraint",
+             "leather straight jacket",
+             "lech",
+             "lemon party",
+             "LEN",
+             "leper",
+             "lesbian",
+             "lesbians",
+             "lesbo",
+             "lesbos",
+             "lez",
+             "lezza/lesbo",
+             "lezzie",
+             "lmao",
+             "lmfao",
+             "loin",
+             "loins",
+             "lolita",
+             "looney",
+             "lovemaking",
+             "lube",
+             "lust",
+             "lusting",
+             "lusty",
+             "m0f0",
+             "m0fo",
+             "m45terbate",
+             "ma5terb8",
+             "ma5terbate",
+             "mafugly",
+             "make me come",
+             "male squirting",
+             "mams",
+             "masochist",
+             "massa",
+             "masterb8",
+             "masterbat*",
+             "masterbat3",
+             "masterbate",
+             "master-bate",
+             "masterbating",
+             "masterbation",
+             "masterbations",
+             "masturbate",
+             "masturbating",
+             "masturbation",
+             "maxi",
+             "mcfagget",
+             "menage a trois",
+             "menses",
+             "meth",
+             "m-fucking",
+             "mick",
+             "microphallus",
+             "middle finger",
+             "midget",
+             "milf",
+             "minge",
+             "minger",
+             "missionary position",
+             "mof0",
+             "mofo",
+             "mo-fo",
+             "molest",
+             "mong",
+             "moo moo foo foo",
+             "moolie",
+             "moron",
+             "mothafuck",
+             "mothafucka",
+             "mothafuckas",
+             "mothafuckaz",
+             "mothafucked",
+             "mothafucker",
+             "mothafuckers",
+             "mothafuckin",
+             "mothafucking",
+             "mothafuckings",
+             "mothafucks",
+             "mother fucker",
+             "motherfuck",
+             "motherfucka",
+             "motherfucked",
+             "motherfucker",
+             "motherfuckers",
+             "motherfuckin",
+             "motherfucking",
+             "motherfuckings",
+             "motherfuckka",
+             "motherfucks",
+             "mound of venus",
+             "mr hands",
+             "muff",
+             "muff diver",
+             "muff puff",
+             "muffdiver",
+             "muffdiving",
+             "munging",
+             "munter",
+             "murder",
+             "mutha",
+             "muthafecker",
+             "muthafuckker",
+             "muther",
+             "mutherfucker",
+             "n1gga",
+             "n1gger",
+             "naked",
+             "nambla",
+             "napalm",
+             "nappy",
+             "nawashi",
+             "nazi",
+             "nazism",
+             "need the dick",
+             "negro",
+             "neonazi",
+             "nig nog",
+             "nigaboo",
+             "nigg3r",
+             "nigg4h",
+             "nigga",
+             "niggah",
+             "niggas",
+             "niggaz",
+             "nigger",
+             "niggers",
+             "niggle",
+             "niglet",
+             "nig-nog",
+             "nimphomania",
+             "nimrod",
+             "ninny",
+             "ninnyhammer",
+             "nipple",
+             "nipples",
+             "nob",
+             "nob jokey",
+             "nobhead",
+             "nobjocky",
+             "nobjokey",
+             "nonce",
+             "nsfw images",
+             "nude",
+             "nudity",
+             "numbnuts",
+             "nut butter",
+             "nut sack",
+             "nutsack",
+             "nutter",
+             "nympho",
+             "nymphomania",
+             "octopussy",
+             "old bag",
+             "omg",
+             "omorashi",
+             "one cup two girls",
+             "1 cup 2 girls",
+             "one cup 2 girls",
+             "1 cup two girls",
+             "one guy one jar",
+             "1 guy one jar",
+             "one guy 1 jar",
+             "opiate",
+             "opium",
+             "orally",
+             "organ",
+             "orgasim",
+             "orgasims",
+             "orgasm",
+             "orgasmic",
+             "orgasms",
+             "orgies",
+             "orgy",
+             "ovary",
+             "ovum",
+             "ovums",
+             "p.u.s.s.y.",
+             "p.u.s.s.y",
+             "p0rn",
+             "paedophile",
+             "paki",
+             "panooch",
+             "pansy",
+             "pantie",
+             "panties",
+             "panty",
+             "pawn",
+             "pcp",
+             "pecker",
+             "peckerhead",
+             "pedo",
+             "pedobear",
+             "pedophile",
+             "pedophilia",
+             "pedophiliac",
+             "pee",
+             "peepee",
+             "pegging",
+             "penetrate",
+             "penetration",
+             "penial",
+             "penile",
+             "penis",
+             "penisbanger",
+             "penisfucker",
+             "penispuffer",
+             "perversion",
+             "phallic",
+             "phone sex",
+             "phonesex",
+             "phuck",
+             "phuk",
+             "phuked",
+             "phuking",
+             "phukked",
+             "phukking",
+             "phuks",
+             "phuq",
+             "piece of shit",
+             "pigfucker",
+             "pikey",
+             "pillowbiter",
+             "pimp",
+             "pimpis",
+             "pinko",
+             "piss",
+             "piss off",
+             "piss pig",
+             "pissed",
+             "pissed off",
+             "pisser",
+             "pissers",
+             "pisses",
+             "pissflaps",
+             "piss flaps",
+             "pissin",
+             "pissing",
+             "pissoff",
+             "piss-off",
+             "pisspig",
+             "playboy",
+             "pleasure chest",
+             "polack",
+             "pole smoker",
+             "polesmoker",
+             "pollock",
+             "ponyplay",
+             "poof",
+             "poon",
+             "poonani",
+             "poonany",
+             "poontang",
+             "poop",
+             "poop chute",
+             "poopchute",
+             "Poopuncher",
+             "porch monkey",
+             "porchmonkey",
+             "porn",
+             "porno",
+             "pornography",
+             "pornos",
+             "potty",
+             "prick",
+             "pricks",
+             "prickteaser",
+             "prig",
+             "prince albert piercing",
+             "prod",
+             "pron",
+             "prone bone",
+             "pronebone",
+             "prone-bone",
+             "prostitute",
+             "prude",
+             "psycho",
+             "pthc",
+             "pube",
+             "pubes",
+             "pubic",
+             "pubis",
+             "punani",
+             "punanny",
+             "punany",
+             "punkass",
+             "punky",
+             "punta",
+             "puss",
+             "pusse",
+             "pussi",
+             "pussies",
+             "pussy",
+             "pussy fart",
+             "pussy palace",
+             "pussylicking",
+             "pussypounder",
+             "pussys",
+             "pust",
+             "puto",
+             "queaf",
+             "queef",
+             "queer",
+             "queerbait",
+             "queerhole",
+             "queero",
+             "queers",
+             "quicky",
+             "quim",
+             "racy",
+             "raghead",
+             "raging boner",
+             "rape",
+             "raped",
+             "raper",
+             "rapey",
+             "raping",
+             "rapist",
+             "raunch",
+             "rectal",
+             "rectum",
+             "rectus",
+             "reefer",
+             "reetard",
+             "reich",
+             "renob",
+             "retard",
+             "retarded",
+             "reverse cowgirl",
+             "revue",
+             "rimjaw",
+             "rimjob",
+             "rimming",
+             "ritard",
+             "rosy palm",
+             "rosy palm and her 5 sisters",
+             "rtard",
+             "r-tard",
+             "rubbish",
+             "rum",
+             "rump",
+             "rumprammer",
+             "ruski",
+             "rusty trombone",
+             "s&m",
+             "s.h.i.t.",
+             "s.o.b.",
+             "s_h_i_t",
+             "s0b",
+             "sadism",
+             "sadist",
+             "sambo",
+             "sand nigger",
+             "sandbar",
+             "Sandler",
+             "sandnigger",
+             "sanger",
+             "santorum",
+             "sausage queen",
+             "scag",
+             "scantily",
+             "scat",
+             "schizo",
+             "schlong",
+             "scissoring",
+             "screw",
+             "screwed",
+             "screwing",
+             "scroat",
+             "scrog",
+             "scrot",
+             "scrote",
+             "scrotum",
+             "scrud",
+             "scum",
+             "seaman",
+             "seduce",
+             "seks",
+             "semen",
+             "sex",
+             "sexo",
+             "sexual",
+             "sexy",
+             "sh!+",
+             "sh!t",
+             "sh1t",
+             "s-h-1-t",
+             "shag",
+             "shagger",
+             "shaggin",
+             "shagging",
+             "shamedame",
+             "shaved beaver",
+             "shaved pussy",
+             "shemale",
+             "shi+",
+             "shibari",
+             "shirt lifter",
+             "shit",
+             "s-h-i-t",
+             "shit ass",
+             "shit fucker",
+             "shitass",
+             "shitbag",
+             "shitbagger",
+             "shitblimp",
+             "shitbrains",
+             "shitbreath",
+             "shitcanned",
+             "shitcunt",
+             "shitdick",
+             "shite",
+             "shiteater",
+             "shited",
+             "shitey",
+             "shitface",
+             "shitfaced",
+             "shitfuck",
+             "shitfull",
+             "shithead",
+             "shitheads",
+             "shithole",
+             "shithouse",
+             "shiting",
+             "shitings",
+             "shits",
+             "shitspitter",
+             "shitstain",
+             "shitt",
+             "shitted",
+             "shitter",
+             "shitters",
+             "shittier",
+             "shittiest",
+             "shitting",
+             "shittings",
+             "shitty",
+             "shiz",
+             "shiznit",
+             "shota",
+             "shrimping",
+             "sissy",
+             "skag",
+             "skank",
+             "skeet",
+             "skullfuck",
+             "slag",
+             "slanteye",
+             "slave",
+             "sleaze",
+             "sleazy",
+             "slope",
+             "slut",
+             "slut bucket",
+             "slutbag",
+             "slutdumper",
+             "slutkiss",
+             "sluts",
+             "smartass",
+             "smartasses",
+             "smeg",
+             "smegma",
+             "smut",
+             "smutty",
+             "snatch",
+             "sniper",
+             "snowballing",
+             "snuff",
+             "s-o-b",
+             "sod off",
+             "sodom",
+             "sodomize",
+             "sodomy",
+             "son of a bitch",
+             "son of a motherless goat",
+             "son of a whore",
+             "son-of-a-bitch",
+             "souse",
+             "soused",
+             "spac",
+             "spade",
+             "sperm",
+             "spic",
+             "spick",
+             "spik",
+             "spiks",
+             "splooge",
+             "splooge moose",
+             "spooge",
+             "spook",
+             "spread legs",
+             "spunk",
+             "stfu",
+             "stiffy",
+             "stoned",
+             "strap on",
+             "strapon",
+             "strappado",
+             "strip",
+             "strip club",
+             "stroke",
+             "stupid",
+             "style doggy",
+             "suck",
+             "suckass",
+             "sucked",
+             "sucking",
+             "sucks",
+             "suicide girls",
+             "sultry women",
+             "sumofabiatch",
+             "swastikav",
+             "swinger",
+             "t1t",
+             "t1tt1e5",
+             "t1tties",
+             "taff",
+             "taig",
+             "tainted love",
+             "taking the piss",
+             "tampon",
+             "tard",
+             "tart",
+             "taste my",
+             "tawdry",
+             "tea bagging",
+             "teabagging",
+             "teat",
+             "teets",
+             "teez",
+             "teste",
+             "testee",
+             "testes",
+             "testical",
+             "testicle",
+             "testis",
+             "threesome",
+             "throating",
+             "thrust",
+             "thug",
+             "thundercunt",
+             "thunder cunt",
+             "tied up",
+             "tight white",
+             "tinkle",
+             "tit",
+             "tit wank",
+             "titfuck",
+             "titi",
+             "tities",
+             "tits",
+             "titt",
+             "tittie5",
+             "tittiefucker",
+             "titties",
+             "titty",
+             "tittyfuck",
+             "tittyfucker",
+             "tittywank",
+             "titwank",
+             "toke",
+             "tongue in a",
+             "toots",
+             "topless",
+             "tosser",
+             "towelhead",
+             "tramp",
+             "tranny",
+             "trashy",
+             "tribadism",
+             "trumped",
+             "tub girl",
+             "tubgirl",
+             "turd",
+             "tush",
+             "tushy",
+             "tw4t",
+             "twat",
+             "twathead",
+             "twatlips",
+             "twats",
+             "twatty",
+             "twatting",
+             "twatwaffle",
+             "twink",
+             "twinkie",
+             "two fingers",
+             "two fingers with tongue",
+             "two girls 1 cup",
+             "two girls one cup",
+             "twunt",
+             "twunter",
+             "ugly",
+             "unclefucker",
+             "undies",
+             "undressing",
+             "unwed",
+             "upskirt",
+             "urethra play",
+             "urinal",
+             "urine",
+             "urophilia",
+             "uterus",
+             "uzi",
+             "v14gra",
+             "v1gra",
+             "vag",
+             "vagina",
+             "vajayjay",
+             "va-j-j",
+             "valium",
+             "venus mound",
+             "veqtable",
+             "viagra",
+             "vibrator",
+             "violet wand",
+             "virgin",
+             "vixen",
+             "vjayjay",
+             "vodka",
+             "vomit",
+             "vorarephilia",
+             "voyeur",
+             "vulgar",
+             "vulva",
+             "w00se",
+             "wad",
+             "wang",
+             "wank",
+             "wanker",
+             "wankjob",
+             "wanky",
+             "wazoo",
+             "wedgie",
+             "weed",
+             "weenie",
+             "weewee",
+             "weiner",
+             "weirdo",
+             "wench",
+             "wet dream",
+             "wetback",
+             "wh0re",
+             "wh0reface",
+             "white power",
+             "whiz",
+             "whoar",
+             "whoralicious",
+             "whore",
+             "whorealicious",
+             "whorebag",
+             "whored",
+             "whoreface",
+             "whorehopper",
+             "whorehouse",
+             "whores",
+             "whoring",
+             "wigger",
+             "willies",
+             "willy",
+             "window licker",
+             "wiseass",
+             "wiseasses",
+             "wog",
+             "womb",
+             "wop",
+             "wrapping men",
+             "wrinkled starfish",
+             "xrated",
+             "x-rated",
+             "xx",
+             "xxx",
+             "yaoi",
+             "yeasty",
+             "yellow showers",
+             "yid",
+             "yiffy",
+             "yobbo",
+             "zibbi",
+             "zoophilia",
+             "zubb",
+        };
+    }
+}

+ 11 - 0
Assets/Scripts/ProfanityFilter/ProfanityList.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: cea19d9f8ab84864488231d33e79383c
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 6 - 62
Assets/Scripts/StreamingAssetsUtility.cs

@@ -55,67 +55,6 @@ public class StreamingAssetsUtility
         {
             return await GetSpriteImage(fileName, isLauncher);
         }
-
-        /*    if (isCard)
-        {
-            if (fileName.Contains("-token"))
-            {
-                return await GetTokenImageData(Path.Combine(GetStreamingAssetPath(isLauncher), $"Card/{fileName}.png").Replace("\\", "/"));
-            }
-            else
-            {
-                
-            }            
-        }
-        else
-        {
-            path = Path.Combine(GetStreamingAssetPath(isLauncher), $"{fileName}.jpg").Replace("\\", "/");
-
-            if (!File.Exists(path))
-                path = Path.Combine(GetStreamingAssetPath(isLauncher), $"{fileName}.png").Replace("\\", "/");
-
-            if (File.Exists(path))
-            {
-                byte[] imageBuff = await ReadFile(path);
-                Texture2D tex = BinaryToTexture(imageBuff);
-
-                Sprite sprite = Sprite.Create(tex, new Rect(0, 0, tex.width, tex.height), Vector2.zero);
-
-                return sprite;
-            }
-        }
-        
-        await Task.Yield();
-
-        if (File.Exists(path))
-        {
-            byte[] imageBuff = await ReadFile(path);
-            Texture2D tex;
-            Sprite sprite = null;
-
-            if (isCard)
-            {
-                tex = Texture2DExt.CreateTexture2DFromWebP(imageBuff, lMipmaps: true, lLinear: false, lError: out WebP.Error lError);
-
-                if (lError == WebP.Error.Success)
-                {
-                    sprite = Sprite.Create(tex, new Rect(0, 0, tex.width, tex.height), Vector2.zero);
-                }
-                else
-                {
-                    Debug.LogError("Webp Load Error : " + lError.ToString());
-                }
-            }
-            else
-            {
-                tex = BinaryToTexture(imageBuff);
-                sprite = Sprite.Create(tex, new Rect(0, 0, tex.width, tex.height), Vector2.zero);
-            }
-
-            return sprite;
-        }*/
-
-        return null;
     }
 
     public static async Task<Sprite> GetSpriteImage(string fileName, bool isLauncher = false)
@@ -165,6 +104,10 @@ public class StreamingAssetsUtility
 
                 return sprite;
             }
+            else
+            {
+                Debug.Log(lError.ToString());
+            }
         }
 
         return null;
@@ -189,7 +132,8 @@ public class StreamingAssetsUtility
             return null;
         else
         {
-            File.WriteAllBytes(filePath, webReq_CardImage.downloadHandler.data);
+            if(!File.Exists(filePath))
+                File.WriteAllBytes(filePath, webReq_CardImage.downloadHandler.data);
 
             Texture2D texture = Texture2DExt.CreateTexture2DFromWebP(webReq_CardImage.downloadHandler.data, lMipmaps: true, lLinear: false, lError: out WebP.Error lError);