using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using CSVFile;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Pigeon.Movement;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyMetadata("AI_Assisted_Creation", "This assembly was partially or fully created with the assistance of Generative AI.")]
[assembly: AssemblyMetadata("AI_Model_Vendor", "Anthropic")]
[assembly: AssemblyCompany("NoBlasphemy")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+f8a12f66cd84cb9bb5142512e181af7111bc681e")]
[assembly: AssemblyProduct("NoBlasphemy")]
[assembly: AssemblyTitle("NoBlasphemy")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace NoBlasphemy
{
internal static class Filter
{
private static readonly string[] Reverent = new string[2] { "exch_faith_5", "vl_building_2" };
private static readonly HashSet<TextBlock> blocked = new HashSet<TextBlock>();
private static readonly HashSet<string> mutedNames = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
private static readonly Dictionary<string, float> durations = new Dictionary<string, float>(StringComparer.OrdinalIgnoreCase);
private static Dictionary<uint, string> mutedIds;
public static readonly List<(string group, int index, string variant, string id)> Testable = new List<(string, int, string, string)>();
private static readonly Dictionary<TextBlock, TextBlock> alternatives = new Dictionary<TextBlock, TextBlock>();
public static bool IsMuted(TextBlock block)
{
if (Plugin.MuteVoice.Value && block != null)
{
return blocked.Contains(block);
}
return false;
}
public static bool IsMuted(string eventName)
{
if (Plugin.MuteVoice.Value && eventName != null)
{
return mutedNames.Contains(eventName);
}
return false;
}
public static bool IsMuted(uint eventId, out string name)
{
name = null;
if (!Plugin.MuteVoice.Value || mutedNames.Count == 0)
{
return false;
}
if (mutedIds == null)
{
mutedIds = new Dictionary<uint, string>();
foreach (string mutedName in mutedNames)
{
mutedIds[AkUnitySoundEngine.GetIDFromString(mutedName)] = mutedName;
}
}
return mutedIds.TryGetValue(eventId, out name);
}
public static float Duration(string name)
{
if (name == null || !durations.TryGetValue(name, out var value))
{
return 3f;
}
return value;
}
public static void Apply()
{
blocked.Clear();
mutedNames.Clear();
durations.Clear();
mutedIds = null;
HashSet<string> keep = Ids(Plugin.KeepLines.Value);
HashSet<string> extra = Ids(Plugin.ExtraLines.Value);
keep.UnionWith(Reverent);
Dictionary<string, string> english = ReadEnglish();
int language = TextBlocks.LanguageIndex;
bool cleanText = Plugin.CleanSubtitles.Value;
Dictionary<string, bool> everyLineBlocked = new Dictionary<string, bool>(StringComparer.OrdinalIgnoreCase);
int cleaned = 0;
List<(string group, int index, string variant, string id)> found = new List<(string, int, string, string)>();
alternatives.Clear();
foreach (KeyValuePair<string, TextBlockGroup> @string in TextBlocks.strings)
{
TextBlockGroup value = @string.Value;
HashSet<TextBlock[]> hashSet = new HashSet<TextBlock[]>();
if (value.variations != null)
{
foreach (KeyValuePair<string, TextBlock[]> variation in value.variations)
{
hashSet.Add(variation.Value);
for (int i = 0; i < variation.Value.Length; i++)
{
if (variation.Value[i] != null)
{
Consider(variation.Value[i], variation.Key, @string.Key, i);
}
}
Alternatives(variation.Value);
}
}
if (value.blocks == null || hashSet.Contains(value.blocks))
{
continue;
}
for (int j = 0; j < value.blocks.Length; j++)
{
if (value.blocks[j] != null)
{
Consider(value.blocks[j], null, @string.Key, j);
}
}
Alternatives(value.blocks);
}
foreach (KeyValuePair<string, bool> item in everyLineBlocked)
{
if (item.Value)
{
mutedNames.Add(item.Key);
}
}
Testable.Clear();
Testable.AddRange(from f in found
where mutedNames.Contains(f.id)
orderby f.id
select f);
Plugin.Log.LogInfo((object)(string.Format("{0} {1}: {2} lines found, {3} subtitles cleaned, ", "Quad's No Blasphemy", "1.0.0", blocked.Count, cleaned) + $"{(Plugin.SwapLines.Value ? alternatives.Count : 0)} swapped for another line when picked at random, " + (Plugin.MuteVoice.Value ? "otherwise silenced" : "voice left on (MuteVoice = false)")));
static void Alternatives(TextBlock[] lines)
{
List<TextBlock> list = lines.Where((TextBlock b) => b != null && !blocked.Contains(b)).ToList();
if (list.Count != 0)
{
for (int num = 0; num < lines.Length; num++)
{
if (lines[num] != null && blocked.Contains(lines[num]))
{
alternatives[lines[num]] = list[num % list.Count];
}
}
}
}
void Consider(TextBlock block, string variant, string groupKey, int index)
{
string uniqueID = block.uniqueID;
if (!english.TryGetValue(Key(uniqueID, variant), out var value2) && !english.TryGetValue(Key(uniqueID, null), out value2))
{
value2 = ((language == 0) ? block.text : null);
}
bool flag = keep.Contains(uniqueID);
bool flag2 = extra.Contains(uniqueID) || (!flag && Words.IsBlasphemous(value2));
bool num = flag2 || (!flag && language != 0 && Words.IsBlasphemous(block.text, language));
everyLineBlocked[uniqueID] = (!everyLineBlocked.TryGetValue(uniqueID, out var value3) || value3) && flag2;
if (flag2)
{
blocked.Add(block);
found.Add((groupKey, index, variant, uniqueID));
durations[uniqueID] = Mathf.Clamp(1f + (float)(value2 ?? block.text).Length * 0.055f, 2f, 12f);
}
if (num)
{
if (cleanText)
{
string text = block.text;
block.text = Words.Clean(block.text, language);
block.variations = null;
if (block.text != text)
{
cleaned++;
}
}
if (Plugin.LogLines.Value)
{
Plugin.Log.LogInfo((object)(" " + uniqueID + ((variant != null) ? (" [" + variant + "]") : "") + (flag2 ? "" : " (text only)") + ": " + block.text));
}
}
}
}
public static TextBlock Swap(TextBlock block)
{
if (block == null || !Plugin.SwapLines.Value || !alternatives.TryGetValue(block, out var value))
{
return block;
}
if (Plugin.LogLines.Value)
{
Plugin.Log.LogInfo((object)("No Blasphemy: said another line instead of " + block.uniqueID));
}
return value;
}
private static Dictionary<string, string> ReadEnglish()
{
Dictionary<string, string> dictionary = new Dictionary<string, string>();
TextAsset val = Resources.Load<TextAsset>("TextBlocks");
if ((Object)(object)val == (Object)null)
{
Plugin.Log.LogWarning((object)"No Blasphemy: the game's text table wasn't found; only the shown language's text is checked");
return dictionary;
}
try
{
CSVReader val2 = CSVReader.FromString(val.text, (CSVSettings)null);
try
{
foreach (string[] item in val2.Lines())
{
if (item.Length >= 3 && !string.IsNullOrEmpty(item[0]))
{
string text = item[0].Trim();
string variant = null;
int num = text.LastIndexOf('[');
if (text.EndsWith("]") && num > 0)
{
variant = text.Substring(num + 1, text.Length - num - 2);
text = text.Substring(0, num).TrimEnd();
}
dictionary[Key(text, variant)] = item[2];
}
}
return dictionary;
}
finally
{
((IDisposable)val2)?.Dispose();
}
}
finally
{
Resources.UnloadAsset((Object)(object)val);
}
}
private static string Key(string id, string variant)
{
return id + "\n" + variant;
}
private static HashSet<string> Ids(string list)
{
return new HashSet<string>(from s in (list ?? "").Split(',')
select s.Trim() into s
where s.Length > 0
select s, StringComparer.OrdinalIgnoreCase);
}
}
[HarmonyPatch(typeof(TextBlocks), "Initialize")]
internal static class TextLoaded
{
private static void Postfix()
{
Filter.Apply();
}
}
[HarmonyPatch(typeof(TextBlockGroup), "Get", new Type[] { })]
internal static class PickAny
{
private static void Postfix(ref TextBlock __result)
{
__result = Filter.Swap(__result);
}
}
[HarmonyPatch(/*Could not decode attribute arguments.*/)]
internal static class PickSeeded
{
private static void Postfix(ref TextBlock __result)
{
__result = Filter.Swap(__result);
}
}
[HarmonyPatch(/*Could not decode attribute arguments.*/)]
internal static class PickCharacterLine
{
private static void Postfix(string parameter, ref TextBlock block, ref string __result)
{
TextBlock val = Filter.Swap(block);
if (val != block)
{
block = val;
__result = val.GetText(parameter, true);
}
}
}
[HarmonyPatch(typeof(Highlighter), "PlayVoicelineSound", new Type[]
{
typeof(TextBlock),
typeof(GameObject),
typeof(string),
typeof(EventCallback),
typeof(object)
})]
internal static class PlayerLine
{
private static bool Prefix(TextBlock block, ref bool __result)
{
if (!Filter.IsMuted(block))
{
return true;
}
if (Plugin.LogLines.Value)
{
Plugin.Log.LogInfo((object)("No Blasphemy: silenced " + block.uniqueID));
}
__result = false;
return false;
}
}
[HarmonyPatch(typeof(AkUnitySoundEngine), "PostEvent", new Type[]
{
typeof(uint),
typeof(GameObject)
})]
internal static class EventById
{
private static bool Prefix(uint in_eventID, ref uint __result)
{
return Sounds.Allow(in_eventID, 0u, null, null, ref __result);
}
}
[HarmonyPatch(typeof(AkUnitySoundEngine), "PostEvent", new Type[]
{
typeof(uint),
typeof(GameObject),
typeof(uint),
typeof(EventCallback),
typeof(object)
})]
internal static class EventByIdWithCallback
{
private static bool Prefix(uint in_eventID, uint in_uFlags, EventCallback in_pfnCallback, object in_pCookie, ref uint __result)
{
return Sounds.Allow(in_eventID, in_uFlags, in_pfnCallback, in_pCookie, ref __result);
}
}
[HarmonyPatch(typeof(AkUnitySoundEngine), "PostEvent", new Type[]
{
typeof(string),
typeof(GameObject)
})]
internal static class EventByName
{
private static bool Prefix(string in_pszEventName, ref uint __result)
{
return Sounds.Allow(in_pszEventName, 0u, null, null, ref __result);
}
}
[HarmonyPatch(typeof(AkUnitySoundEngine), "PostEvent", new Type[]
{
typeof(string),
typeof(GameObject),
typeof(uint),
typeof(EventCallback),
typeof(object)
})]
internal static class EventByNameWithCallback
{
private static bool Prefix(string in_pszEventName, uint in_uFlags, EventCallback in_pfnCallback, object in_pCookie, ref uint __result)
{
return Sounds.Allow(in_pszEventName, in_uFlags, in_pfnCallback, in_pCookie, ref __result);
}
}
internal static class Sounds
{
public static bool Allow(uint id, uint flags, EventCallback callback, object cookie, ref uint result)
{
if (Filter.IsMuted(id, out var name))
{
return Silence(name, flags, callback, cookie, ref result);
}
return true;
}
public static bool Allow(string name, uint flags, EventCallback callback, object cookie, ref uint result)
{
if (Filter.IsMuted(name))
{
return Silence(name, flags, callback, cookie, ref result);
}
return true;
}
private static bool Silence(string name, uint flags, EventCallback callback, object cookie, ref uint result)
{
if (Plugin.LogLines.Value)
{
Plugin.Log.LogInfo((object)("No Blasphemy: silenced " + name));
}
if ((flags & 1) != 0)
{
Later.Call(Filter.Duration(name), callback, cookie);
}
result = 0u;
return false;
}
}
[BepInPlugin("quadslab.mycopunk.noblasphemy", "Quad's No Blasphemy", "1.0.0")]
[BepInProcess("Mycopunk.exe")]
public class Plugin : BaseUnityPlugin
{
public const string Guid = "quadslab.mycopunk.noblasphemy";
public const string Title = "Quad's No Blasphemy";
public const string Version = "1.0.0";
internal static ManualLogSource Log;
internal static ConfigEntry<bool> MuteVoice;
internal static ConfigEntry<bool> CleanSubtitles;
internal static ConfigEntry<bool> SwapLines;
internal static ConfigEntry<string> KeepLines;
internal static ConfigEntry<string> ExtraLines;
internal static ConfigEntry<bool> LogLines;
internal static ConfigEntry<bool> TestKey;
private GameObject runner;
private Harmony harmony;
private void Awake()
{
//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
//IL_0103: Expected O, but got Unknown
//IL_012d: Unknown result type (might be due to invalid IL or missing references)
//IL_0137: Expected O, but got Unknown
Log = ((BaseUnityPlugin)this).Logger;
MuteVoice = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "MuteVoice", true, "Silence the spoken lines that use God's name in vain. A recording can't lose just one word, so the whole line is quiet; its subtitle still shows, cleaned.");
CleanSubtitles = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "CleanSubtitles", true, "Take God's name out of the subtitles, in every language the game has. Takes effect at the next start.");
SwapLines = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "SwapLines", true, "When a character has other lines for the same moment (a call for help), say one of those instead of going quiet.");
KeepLines = ((BaseUnityPlugin)this).Config.Bind<string>("Lines", "Keep", "", "More line IDs to leave alone, comma-separated (the lines that speak of God sincerely are always kept). Takes effect at the next start.");
ExtraLines = ((BaseUnityPlugin)this).Config.Bind<string>("Lines", "Extra", "", "More line IDs to clean and silence, comma-separated, for any line the word list misses. Takes effect at the next start.");
LogLines = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "LogLines", false, "Write every line changed (at start) and every line silenced (as it plays) to the BepInEx log, with its ID.");
TestKey = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "TestKey", false, "F8 in a game plays the next line this mod changes, as mission control would say it: you see its cleaned subtitle and hear nothing. (A file BepInEx\\noblasphemy-test.txt does the same, for automated tests.)");
runner = new GameObject("NoBlasphemy");
Object.DontDestroyOnLoad((Object)(object)runner);
((Object)runner).hideFlags = (HideFlags)61;
runner.AddComponent<Later>();
harmony = new Harmony("quadslab.mycopunk.noblasphemy");
harmony.PatchAll(typeof(Plugin).Assembly);
if (TextBlocks.strings.Count > 0)
{
Filter.Apply();
}
}
private void OnDestroy()
{
Harmony obj = harmony;
if (obj != null)
{
obj.UnpatchSelf();
}
if ((Object)(object)runner != (Object)null)
{
Object.Destroy((Object)(object)runner);
}
}
}
internal sealed class Later : MonoBehaviour
{
private static readonly List<(float at, EventCallback callback, object cookie)> pending = new List<(float, EventCallback, object)>();
private int nextTest;
private float nextFileCheck;
public static void Call(float delay, EventCallback callback, object cookie)
{
if (callback != null)
{
pending.Add((Time.unscaledTime + delay, callback, cookie));
}
}
private void Update()
{
if (Plugin.TestKey.Value && Keyboard.current != null && ((ButtonControl)Keyboard.current.f8Key).wasPressedThisFrame)
{
PlayTest();
}
if (Plugin.TestKey.Value && Time.unscaledTime >= nextFileCheck)
{
nextFileCheck = Time.unscaledTime + 0.5f;
string path = Path.Combine(Paths.BepInExRootPath, "noblasphemy-test.txt");
if (File.Exists(path))
{
try
{
File.Delete(path);
}
catch (Exception)
{
}
PlayTest();
}
}
for (int num = pending.Count - 1; num >= 0; num--)
{
if (!(Time.unscaledTime < pending[num].at))
{
(float at, EventCallback callback, object cookie) tuple = pending[num];
EventCallback item = tuple.callback;
object item2 = tuple.cookie;
pending.RemoveAt(num);
try
{
item.Invoke(item2, (AkCallbackType)1, (AkCallbackInfo)null);
}
catch (Exception ex2)
{
Plugin.Log.LogWarning((object)("No Blasphemy: a line's finish callback failed: " + ex2.Message));
}
}
}
}
private void PlayTest()
{
//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
if (Filter.Testable.Count == 0 || (Object)(object)PlayerLook.Instance == (Object)null || (Object)(object)Highlighter.Instance == (Object)null)
{
Plugin.Log.LogInfo((object)"No Blasphemy: the test key works once you're in the game");
return;
}
var (text, num, text2, arg) = Filter.Testable[nextTest++ % Filter.Testable.Count];
Plugin.Log.LogInfo((object)$"No Blasphemy: test {nextTest}/{Filter.Testable.Count}: {arg}");
try
{
Highlighter.Instance.PlayMissionControlVoiceline(new Voiceline(text, 1000), (string)null, 0, text2, (Predicate)null, (Action)null, 0f, num, (Action<DialogueBox>)null, false, (EventCallback)null, (object)null, (Sprite)null, (GameObject)null);
}
catch (Exception ex)
{
Plugin.Log.LogWarning((object)("No Blasphemy: the test line didn't play: " + ex.Message));
}
}
}
public static class Words
{
private const RegexOptions Opts = RegexOptions.IgnoreCase | RegexOptions.CultureInvariant;
private static readonly (Regex pattern, MatchEvaluator replace)[][] Rules = new(Regex, MatchEvaluator)[10][]
{
new(Regex, MatchEvaluator)[10]
{
(new Regex("\\bgod[\\s-]*dam(?:n|m)?(it|ed)?\\b", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant), (Match m) => Cased(m.Value, (m.Groups[1].Value.ToLowerInvariant() == "it") ? "dang it" : "dang")),
R("(?<=\\bmy\\s+)(god|lord|gawd)\\b", "gosh"),
R("(?<=\\bthank\\s+)(god|gawd|the\\s+lord)\\b", "goodness"),
R("\\bfor\\s+god'?s\\s+sake\\b", "for goodness' sake"),
R("(?<=\\bgood\\s+)lord\\b", "grief"),
R("(?<=\\b(?:oh|dear|sweet)\\s+)lord\\b", "gosh"),
R("\\blord\\s+almighty\\b", "goodness gracious"),
R("\\bomg\\b", "oh my gosh"),
R("\\bgod\\s+help\\s+us\\b", "heaven help us"),
R("\\b(god|gawd|jesus|christ|lordy)\\b", "gosh")
},
new(Regex, MatchEvaluator)[6]
{
R("\\bnom\\s+de\\s+dieu\\b", "nom d'une pipe"),
R("\\bbonté\\s+divine\\b", "bon sang"),
R("\\b(?:oh\\s+)?mon\\s+dieu\\b", "oh là là"),
R("\\bseigneur(?=\\s*[!,.…])", "bon sang"),
R("\\bdieu(?=\\s*[!…])", "bon sang"),
R("\\bj[ée]sus\\b", "purée")
},
new(Regex, MatchEvaluator)[8]
{
R("\\bgottverdammt", "verflixt"),
R("\\bum\\s+gottes\\s+willen\\b", "um Himmels willen"),
R("\\bgott\\s+sei\\s+dank\\b", "zum Glück"),
R("\\bmein\\s+gott\\b", "meine Güte"),
R("\\boh\\s+gott\\b", "oh Mann"),
R("\\bgrundgütiger\\b", "meine Güte"),
R("\\bherrgott\\w*", "Mensch"),
R("\\b(jessas|jesus)\\b", "Mannomann")
},
new(Regex, MatchEvaluator)[7]
{
R("\\bdios\\s+m[ií]o\\b", "madre mía"),
R("\\bgracias\\s+a\\s+dios\\b", "menos mal"),
R("\\bpor\\s+dios\\b", "por favor"),
R("\\bque\\s+dios\\s+nos\\s+\\w+", "que haya suerte"),
R("\\bdios(?=\\s*[,!…])", "madre mía"),
R("\\bhostias?\\b", "ostras"),
R("\\bjes[uú]s\\b", "caramba")
},
new(Regex, MatchEvaluator)[4]
{
R("\\bне\\s+слава\\s+богу\\b", "не так"),
R("\\bслава\\s+богу\\b", "к счастью"),
R("\\b(?:о\\s+)?боже(?:\\s+мой)?\\b", "ох"),
R("\\b(?:о\\s+)?господи\\b", "ох")
},
new(Regex, MatchEvaluator)[7]
{
R("\\bmeu\\s+deus(?:\\s+do\\s+c[ée]u)?\\b", "minha nossa"),
R("\\bgraças\\s+a\\s+deus(?=\\s+\\p{L})", "ainda bem que"),
R("\\bgraças\\s+a\\s+deus\\b", "ainda bem"),
R("\\bpelo\\s+amor\\s+de\\s+deus\\b", "por favor"),
R("\\bdeus\\s+do\\s+c[ée]u\\b", "caramba"),
R("^senhor(?=\\s*[,!])", "caramba"),
R("\\bjesus\\b", "caramba")
},
new(Regex, MatchEvaluator)[4]
{
R("愿上帝保佑我们", "但愿我们走运"),
R("我的上帝", "我的天"),
R("上帝", "老天"),
R("耶稣", "天哪")
},
new(Regex, MatchEvaluator)[5]
{
R("願主保佑我們", "但願我們走運"),
R("我的上帝", "我的天"),
R("上帝", "老天"),
R("主啊", "天啊"),
R("耶穌", "天哪")
},
new(Regex, MatchEvaluator)[3]
{
R("オーマイゴッド", "なんてこった"),
R("ジーザス", "なんてこった"),
R("神よ", "なんてこった")
},
new(Regex, MatchEvaluator)[4]
{
R("하느님|하나님", "세상에"),
R("오\\s*마이\\s*갓", "세상에"),
R("지저스", "세상에"),
R("주여", "세상에")
}
};
private static (Regex, MatchEvaluator) R(string pattern, string replacement)
{
return (new Regex(pattern, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant), (Match m) => Cased(m.Value, replacement));
}
private static (Regex pattern, MatchEvaluator replace)[] For(int language)
{
if (language < 0 || language >= Rules.Length)
{
return Rules[0];
}
return Rules[language];
}
public static bool IsBlasphemous(string text, int language = 0)
{
if (!string.IsNullOrEmpty(text))
{
return For(language).Any(((Regex pattern, MatchEvaluator replace) r) => r.pattern.IsMatch(text));
}
return false;
}
public static string Clean(string text, int language = 0)
{
if (string.IsNullOrEmpty(text))
{
return text;
}
(Regex, MatchEvaluator)[] array = For(language);
for (int i = 0; i < array.Length; i++)
{
(Regex, MatchEvaluator) tuple = array[i];
Regex item = tuple.Item1;
MatchEvaluator item2 = tuple.Item2;
text = item.Replace(text, item2);
}
return text;
}
private static string Cased(string original, string replacement)
{
string text = original.Split(' ', '-', '\t', '\n')[^1];
if (IsShouted(original) || (text.Length > 1 && IsShouted(text)))
{
return replacement.ToUpperInvariant();
}
if (char.IsUpper(original[0]))
{
return char.ToUpperInvariant(replacement[0]) + replacement.Substring(1);
}
return replacement;
}
private static bool IsShouted(string s)
{
bool flag = false;
foreach (char c in s)
{
if (char.IsLower(c))
{
return false;
}
if (char.IsLetter(c))
{
flag = true;
}
}
if (flag)
{
return s.Length > 1;
}
return false;
}
}
}
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
internal sealed class IgnoresAccessChecksToAttribute : Attribute
{
public IgnoresAccessChecksToAttribute(string assemblyName)
{
}
}
}