using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.1", FrameworkDisplayName = ".NET Framework 4.7.1")]
[assembly: AssemblyCompany("MoreLoadingQuotes")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("More loading quotes for Gamble With Your Friends")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("MoreLoadingQuotes")]
[assembly: AssemblyTitle("MoreLoadingQuotes")]
[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 MoreLoadingQuotes
{
[BepInPlugin("com.ananas1k.gwyf.moreloadingquotes", "More Loading Quotes", "1.0.0")]
public class MoreLoadingQuotesPlugin : BaseUnityPlugin
{
private sealed class QuoteParts
{
public readonly string Quote;
public readonly string Author;
public readonly string Formatted;
public QuoteParts(string quote, string author, string formatted)
{
Quote = quote;
Author = author;
Formatted = formatted;
}
}
private const string PluginGuid = "com.ananas1k.gwyf.moreloadingquotes";
private const string PluginName = "More Loading Quotes";
private const string PluginVersion = "1.0.0";
private const string PluginFolderName = "MoreLoadingQuotes";
private const string QuotesFileName = "quotes.txt";
private const string EnglishQuotesFileName = "en_quotes.txt";
private const string RussianQuotesFileName = "ru_quotes.txt";
private const string RussianTranslationPackageName = "RTLC-GWYF_Russian_Translation";
private static readonly HashSet<int> PatchedInstances = new HashSet<int>();
private static readonly Dictionary<int, string[]> VanillaQuotesByInstance = new Dictionary<int, string[]>();
private static readonly Dictionary<string, QuoteParts> QuotePartsByDisplayedText = new Dictionary<string, QuoteParts>(StringComparer.Ordinal);
private static readonly Dictionary<string, QuoteParts> QuotePartsByQuoteText = new Dictionary<string, QuoteParts>(StringComparer.Ordinal);
private static readonly object QuoteLock = new object();
private static readonly string[] EmptyQuotes = new string[0];
private static MoreLoadingQuotesPlugin Instance;
private static ConfigEntry<bool> EnableCustomQuotes;
private static ConfigEntry<bool> ReplaceVanillaQuotes;
private static ConfigEntry<bool> LiveReload;
private static ConfigEntry<string> QuoteFilePath;
private static ConfigEntry<string> QuoteAuthorFormat;
private static ConfigEntry<int> ConfigLocalizationLanguage;
private static ConfigEntry<float> ConfigLineSpacing;
private static ConfigEntry<float> ConfigTextBoxMinHeight;
private static ConfigEntry<float> ConfigAuthorVerticalOffset;
private static ConfigEntry<float> ConfigAuthorFontScale;
private static string activeQuoteFilePath;
private static string[] cachedQuotes = EmptyQuotes;
private static DateTime cachedQuoteFileWriteTimeUtc = DateTime.MinValue;
private static bool useRussianQuotes;
private static FieldInfo targetTextField;
private Harmony harmony;
private void Awake()
{
//IL_0050: Unknown result type (might be due to invalid IL or missing references)
//IL_005a: Expected O, but got Unknown
//IL_0086: Unknown result type (might be due to invalid IL or missing references)
//IL_009b: Unknown result type (might be due to invalid IL or missing references)
//IL_00a8: Expected O, but got Unknown
//IL_00a8: Expected O, but got Unknown
Instance = this;
BindConfig();
useRussianQuotes = ShouldUseRussianQuotes();
activeQuoteFilePath = ResolveQuoteFilePath();
EnsureQuoteFileExists(activeQuoteFilePath);
LoadQuotes(force: true);
targetTextField = AccessTools.Field(typeof(LoadingQuotes), "targetText");
harmony = new Harmony("com.ananas1k.gwyf.moreloadingquotes");
harmony.Patch((MethodBase)AccessTools.Method(typeof(LoadingQuotes), "ShowRandomQuote", (Type[])null, (Type[])null), new HarmonyMethod(typeof(MoreLoadingQuotesPlugin), "PatchShowRandomQuote", (Type[])null), new HarmonyMethod(typeof(MoreLoadingQuotesPlugin), "PatchShowRandomQuotePostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
((BaseUnityPlugin)this).Logger.LogInfo((object)("More Loading Quotes 1.0.0 loaded. " + (useRussianQuotes ? "Russian" : "English") + " quote file: " + activeQuoteFilePath));
}
private void OnDestroy()
{
if (harmony != null)
{
harmony.UnpatchSelf();
}
}
private void BindConfig()
{
//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
//IL_00d4: Expected O, but got Unknown
//IL_0107: Unknown result type (might be due to invalid IL or missing references)
//IL_0111: Expected O, but got Unknown
//IL_0144: Unknown result type (might be due to invalid IL or missing references)
//IL_014e: Expected O, but got Unknown
//IL_0181: Unknown result type (might be due to invalid IL or missing references)
//IL_018b: Expected O, but got Unknown
//IL_01be: Unknown result type (might be due to invalid IL or missing references)
//IL_01c8: Expected O, but got Unknown
EnableCustomQuotes = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "EnableCustomQuotes", true, "If true, loads extra loading quotes from en_quotes.txt or ru_quotes.txt.");
ReplaceVanillaQuotes = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ReplaceVanillaQuotes", false, "If true, only custom quotes from quotes.txt will be used. If false, custom quotes are added to the vanilla quote pool.");
LiveReload = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "LiveReload", true, "If true, quotes.txt is re-read when it changes, so testing new quotes does not require restarting the game.");
QuoteFilePath = ((BaseUnityPlugin)this).Config.Bind<string>("General", "QuoteFilePath", string.Empty, "Optional custom quote file path. Relative paths are resolved from the BepInEx plugins folder. Leave empty to use automatic en_quotes.txt/ru_quotes.txt selection.");
QuoteAuthorFormat = ((BaseUnityPlugin)this).Config.Bind<string>("General", "QuoteAuthorFormat", "{0}\\n- {1}", "Format used for quote lines written as: quote | author. {0}=quote, {1}=author. Use \\n for line breaks.");
ConfigLocalizationLanguage = ((BaseUnityPlugin)this).Config.Bind<int>("Localization", "Language", 0, new ConfigDescription("0=Auto, 1=English, 2=Russian. Auto uses Russian quotes when RTLC-GWYF_Russian_Translation is enabled.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 2), Array.Empty<object>()));
ConfigLineSpacing = ((BaseUnityPlugin)this).Config.Bind<float>("Layout", "LineSpacing", 35f, new ConfigDescription("Extra TextMeshPro line spacing for loading quotes. Increase if wrapped quote lines overlap.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 120f), Array.Empty<object>()));
ConfigTextBoxMinHeight = ((BaseUnityPlugin)this).Config.Bind<float>("Layout", "TextBoxMinHeight", 260f, new ConfigDescription("Minimum height for the loading quote text box. Increase if the quote author is clipped.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 600f), Array.Empty<object>()));
ConfigAuthorVerticalOffset = ((BaseUnityPlugin)this).Config.Bind<float>("Layout", "AuthorVerticalOffset", -125f, new ConfigDescription("Vertical offset for the separate quote author text. Negative values move it down.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-300f, 100f), Array.Empty<object>()));
ConfigAuthorFontScale = ((BaseUnityPlugin)this).Config.Bind<float>("Layout", "AuthorFontScale", 0.55f, new ConfigDescription("Author font size as a multiplier of the quote font size.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.2f, 1f), Array.Empty<object>()));
}
private static void PatchShowRandomQuote(LoadingQuotes __instance)
{
try
{
if ((Object)(object)__instance == (Object)null || EnableCustomQuotes == null || !EnableCustomQuotes.Value)
{
return;
}
if (LiveReload != null && LiveReload.Value && (Object)(object)Instance != (Object)null)
{
Instance.LoadQuotes(force: false);
}
string[] array = GetCachedQuotes();
if (array.Length == 0)
{
return;
}
int instanceID = ((Object)__instance).GetInstanceID();
if (!PatchedInstances.Contains(instanceID))
{
string[] source = (AccessTools.Field(typeof(LoadingQuotes), "quotes").GetValue(__instance) as string[]) ?? EmptyQuotes;
if (!VanillaQuotesByInstance.TryGetValue(instanceID, out var value))
{
value = CopyQuotes(source);
VanillaQuotesByInstance[instanceID] = value;
}
string[] value2 = ((ReplaceVanillaQuotes != null && ReplaceVanillaQuotes.Value) ? NormalizeQuotes(array) : MergeQuotes(value, array));
AccessTools.Field(typeof(LoadingQuotes), "quotes").SetValue(__instance, value2);
ApplyTextLayout(__instance);
PatchedInstances.Add(instanceID);
}
}
catch (Exception ex)
{
LogWarning("Failed to add custom loading quotes: " + ex.Message);
}
}
private static void PatchShowRandomQuotePostfix(LoadingQuotes __instance)
{
try
{
ApplyTextLayout(__instance);
}
catch (Exception ex)
{
LogWarning("Failed to adjust loading quote layout: " + ex.Message);
}
}
private static void ApplyTextLayout(LoadingQuotes loadingQuotes)
{
//IL_009d: Unknown result type (might be due to invalid IL or missing references)
//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
TextMeshProUGUI targetText = GetTargetText(loadingQuotes);
if ((Object)(object)targetText == (Object)null)
{
return;
}
((TMP_Text)targetText).richText = true;
EnableTextWrapping(targetText);
((TMP_Text)targetText).overflowMode = (TextOverflowModes)0;
((TMP_Text)targetText).lineSpacing = ((ConfigLineSpacing == null) ? 35f : ConfigLineSpacing.Value);
((TMP_Text)targetText).maxVisibleCharacters = 99999;
((TMP_Text)targetText).maxVisibleWords = 99999;
((TMP_Text)targetText).maxVisibleLines = 99999;
((TMP_Text)targetText).extraPadding = true;
float num = ((ConfigTextBoxMinHeight == null) ? 260f : ConfigTextBoxMinHeight.Value);
RectTransform rectTransform = ((TMP_Text)targetText).rectTransform;
if ((Object)(object)rectTransform != (Object)null && num > 0f)
{
Rect rect = rectTransform.rect;
if (((Rect)(ref rect)).height < num)
{
rectTransform.SetSizeWithCurrentAnchors((Axis)1, num);
}
}
ApplyAuthorText(targetText);
((TMP_Text)targetText).ForceMeshUpdate(false, false);
}
private static void ApplyAuthorText(TextMeshProUGUI targetText)
{
if (!TryGetQuoteParts(((TMP_Text)targetText).text, out var parts))
{
SetAuthorObjectActive(targetText, active: false, null);
return;
}
if (!string.Equals(((TMP_Text)targetText).text, parts.Quote, StringComparison.Ordinal))
{
((TMP_Text)targetText).text = parts.Quote;
}
SetAuthorObjectActive(targetText, active: true, parts.Author);
}
private static bool TryGetQuoteParts(string displayedText, out QuoteParts parts)
{
parts = null;
string text = NormalizeRuntimeText(displayedText);
if (string.IsNullOrEmpty(text))
{
return false;
}
if (QuotePartsByDisplayedText.TryGetValue(text, out parts))
{
return true;
}
if (QuotePartsByQuoteText.TryGetValue(text, out parts))
{
return true;
}
return TrySplitFormattedQuote(text, out parts);
}
private static void SetAuthorObjectActive(TextMeshProUGUI targetText, bool active, string author)
{
//IL_010e: Unknown result type (might be due to invalid IL or missing references)
//IL_0049: Unknown result type (might be due to invalid IL or missing references)
//IL_0055: Unknown result type (might be due to invalid IL or missing references)
//IL_0061: Unknown result type (might be due to invalid IL or missing references)
//IL_006d: Unknown result type (might be due to invalid IL or missing references)
//IL_0072: Unknown result type (might be due to invalid IL or missing references)
//IL_008f: Unknown result type (might be due to invalid IL or missing references)
//IL_0094: Unknown result type (might be due to invalid IL or missing references)
//IL_0082: Unknown result type (might be due to invalid IL or missing references)
//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
//IL_00df: Unknown result type (might be due to invalid IL or missing references)
//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
TextMeshProUGUI orCreateAuthorText = GetOrCreateAuthorText(targetText);
if ((Object)(object)orCreateAuthorText == (Object)null)
{
return;
}
((Component)orCreateAuthorText).gameObject.SetActive(active);
if (!active)
{
return;
}
RectTransform rectTransform = ((TMP_Text)targetText).rectTransform;
RectTransform rectTransform2 = ((TMP_Text)orCreateAuthorText).rectTransform;
if ((Object)(object)rectTransform != (Object)null && (Object)(object)rectTransform2 != (Object)null)
{
rectTransform2.anchorMin = rectTransform.anchorMin;
rectTransform2.anchorMax = rectTransform.anchorMax;
rectTransform2.pivot = rectTransform.pivot;
Rect rect = rectTransform.rect;
float num;
if (!(((Rect)(ref rect)).width > 0f))
{
num = rectTransform.sizeDelta.x;
}
else
{
rect = rectTransform.rect;
num = ((Rect)(ref rect)).width;
}
rectTransform2.sizeDelta = new Vector2(num, 90f);
rectTransform2.anchoredPosition = rectTransform.anchoredPosition + new Vector2(0f, (ConfigAuthorVerticalOffset == null) ? (-125f) : ConfigAuthorVerticalOffset.Value);
((Transform)rectTransform2).localScale = Vector3.one;
((Transform)rectTransform2).localRotation = Quaternion.identity;
}
((TMP_Text)orCreateAuthorText).font = ((TMP_Text)targetText).font;
((TMP_Text)orCreateAuthorText).fontSharedMaterial = ((TMP_Text)targetText).fontSharedMaterial;
((Graphic)orCreateAuthorText).color = ((Graphic)targetText).color;
((TMP_Text)orCreateAuthorText).alignment = (TextAlignmentOptions)514;
((TMP_Text)orCreateAuthorText).richText = true;
((TMP_Text)orCreateAuthorText).overflowMode = (TextOverflowModes)0;
((TMP_Text)orCreateAuthorText).enableAutoSizing = false;
((TMP_Text)orCreateAuthorText).fontSize = ((TMP_Text)targetText).fontSize * ((ConfigAuthorFontScale == null) ? 0.55f : ConfigAuthorFontScale.Value);
((TMP_Text)orCreateAuthorText).lineSpacing = ((TMP_Text)targetText).lineSpacing;
((TMP_Text)orCreateAuthorText).maxVisibleCharacters = 99999;
((TMP_Text)orCreateAuthorText).maxVisibleWords = 99999;
((TMP_Text)orCreateAuthorText).maxVisibleLines = 99999;
((TMP_Text)orCreateAuthorText).extraPadding = true;
((Graphic)orCreateAuthorText).raycastTarget = false;
((TMP_Text)orCreateAuthorText).text = "- " + author;
((TMP_Text)orCreateAuthorText).ForceMeshUpdate(false, false);
}
private static TextMeshProUGUI GetOrCreateAuthorText(TextMeshProUGUI targetText)
{
//IL_004b: Unknown result type (might be due to invalid IL or missing references)
//IL_0050: Unknown result type (might be due to invalid IL or missing references)
//IL_005d: Unknown result type (might be due to invalid IL or missing references)
Transform parent = ((TMP_Text)targetText).transform.parent;
if ((Object)(object)parent == (Object)null)
{
return null;
}
Transform val = parent.Find("MoreLoadingQuotes_Author");
if ((Object)(object)val != (Object)null)
{
return ((Component)val).GetComponent<TextMeshProUGUI>();
}
GameObject val2 = new GameObject("MoreLoadingQuotes_Author", new Type[1] { typeof(RectTransform) });
val2.transform.SetParent(parent, false);
val2.transform.SetSiblingIndex(((TMP_Text)targetText).transform.GetSiblingIndex() + 1);
return val2.AddComponent<TextMeshProUGUI>();
}
private static void EnableTextWrapping(TextMeshProUGUI targetText)
{
try
{
PropertyInfo property = typeof(TMP_Text).GetProperty("textWrappingMode", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (property != null && property.PropertyType.IsEnum)
{
object value = Enum.Parse(property.PropertyType, "Normal");
property.SetValue(targetText, value, null);
return;
}
PropertyInfo property2 = typeof(TMP_Text).GetProperty("enableWordWrapping", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (property2 != null)
{
property2.SetValue(targetText, true, null);
}
}
catch
{
}
}
private static TextMeshProUGUI GetTargetText(LoadingQuotes loadingQuotes)
{
if ((Object)(object)loadingQuotes == (Object)null || targetTextField == null)
{
return null;
}
try
{
object? value = targetTextField.GetValue(loadingQuotes);
return (TextMeshProUGUI)((value is TextMeshProUGUI) ? value : null);
}
catch
{
return null;
}
}
private static string ResolveQuoteFilePath()
{
string text = ((QuoteFilePath.Value == null) ? string.Empty : QuoteFilePath.Value.Trim());
if (!string.IsNullOrEmpty(text))
{
if (!Path.IsPathRooted(text))
{
return Path.Combine(Paths.PluginPath, text);
}
return text;
}
string text2 = (useRussianQuotes ? "ru_quotes.txt" : "en_quotes.txt");
string text3 = Path.Combine(Paths.PluginPath, "MoreLoadingQuotes", text2);
if (File.Exists(text3))
{
return text3;
}
string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
if (!string.IsNullOrEmpty(directoryName))
{
string text4 = Path.Combine(directoryName, text2);
if (File.Exists(text4))
{
return text4;
}
}
string text5 = Path.Combine(Paths.PluginPath, "MoreLoadingQuotes", "quotes.txt");
if (File.Exists(text5))
{
return text5;
}
return text3;
}
private static bool ShouldUseRussianQuotes()
{
if (ConfigLocalizationLanguage != null)
{
if (ConfigLocalizationLanguage.Value == 1)
{
return false;
}
if (ConfigLocalizationLanguage.Value == 2)
{
return true;
}
}
return IsRussianLocalizationDetected();
}
private static bool IsRussianLocalizationDetected()
{
if (TryGetManagedRussianTranslationEnabled(out var enabled))
{
return enabled;
}
if (IsManagedThunderstoreProfile())
{
return false;
}
if (HasRussianTranslationPackageFiles())
{
return true;
}
try
{
foreach (KeyValuePair<string, PluginInfo> pluginInfo in Chainloader.PluginInfos)
{
string text = pluginInfo.Key ?? string.Empty;
string text2 = ((pluginInfo.Value != null && pluginInfo.Value.Metadata != null) ? (pluginInfo.Value.Metadata.Name ?? string.Empty) : string.Empty);
string text3 = ((pluginInfo.Value != null && pluginInfo.Value.Metadata != null) ? (pluginInfo.Value.Metadata.GUID ?? string.Empty) : string.Empty);
if (IsRussianTranslationPluginText((text + " " + text2 + " " + text3).ToLowerInvariant()))
{
return true;
}
}
}
catch
{
}
return false;
}
private static bool TryGetManagedRussianTranslationEnabled(out bool enabled)
{
enabled = false;
try
{
string managedModsFilePath = GetManagedModsFilePath();
if (string.IsNullOrEmpty(managedModsFilePath) || !File.Exists(managedModsFilePath))
{
return false;
}
string[] array = File.ReadAllLines(managedModsFilePath);
bool flag = false;
for (int i = 0; i < array.Length; i++)
{
string text = array[i].Trim();
if (array[i].StartsWith("- ", StringComparison.Ordinal))
{
if (flag)
{
return true;
}
flag = false;
}
bool result;
if (text.StartsWith("name:", StringComparison.OrdinalIgnoreCase) && text.IndexOf("RTLC-GWYF_Russian_Translation", StringComparison.OrdinalIgnoreCase) >= 0)
{
flag = true;
}
else if (flag && text.StartsWith("enabled:", StringComparison.OrdinalIgnoreCase) && bool.TryParse(text.Substring("enabled:".Length).Trim(), out result))
{
enabled = result;
return true;
}
}
return flag;
}
catch
{
return false;
}
}
private static bool IsManagedThunderstoreProfile()
{
string managedModsFilePath = GetManagedModsFilePath();
if (!string.IsNullOrEmpty(managedModsFilePath))
{
return File.Exists(managedModsFilePath);
}
return false;
}
private static string GetManagedModsFilePath()
{
try
{
DirectoryInfo directoryInfo = Directory.GetParent(Paths.PluginPath)?.Parent;
return (directoryInfo == null) ? null : Path.Combine(directoryInfo.FullName, "mods.yml");
}
catch
{
return null;
}
}
private static bool HasRussianTranslationPackageFiles()
{
try
{
string text = Path.Combine(Paths.PluginPath, "RTLC-GWYF_Russian_Translation");
if (!Directory.Exists(text))
{
return false;
}
if (File.Exists(Path.Combine(text, "RTLC.GWYF", "RTLC.GWYF.Text.dll")))
{
return true;
}
return Directory.GetFiles(text, "RTLC.GWYF.Text.dll", SearchOption.AllDirectories).Length != 0;
}
catch
{
return false;
}
}
private static bool IsRussianTranslationPluginText(string text)
{
if (!text.Contains("rtlc.gwyf.text") && !text.Contains("gwyf_russian_translation") && !text.Contains("gwyf russian translation"))
{
return text.Contains("rtlc-gwyf_russian_translation");
}
return true;
}
private static void EnsureQuoteFileExists(string filePath)
{
try
{
string directoryName = Path.GetDirectoryName(filePath);
if (!string.IsNullOrEmpty(directoryName))
{
Directory.CreateDirectory(directoryName);
}
if (!File.Exists(filePath))
{
File.WriteAllText(filePath, GetQuoteFileTemplate(useRussianQuotes), Encoding.UTF8);
}
}
catch (Exception ex)
{
LogWarning("Failed to create quote file '" + filePath + "': " + ex.Message);
}
}
private static string GetQuoteFileTemplate(bool russian)
{
if (russian)
{
return "# More Loading Quotes\n# Recommended format: Quote text | Author\n# Example: Gambling is just math with dramatic lighting. | A broke statistician\n# Already formatted lines are also accepted. Use \\n for manual line breaks.\n# Empty lines and lines starting with # or // are ignored.\n# Put your Russian quotes below this line.\n";
}
return "# More Loading Quotes\n# Recommended format: Quote text | Author\n# Example: Gambling is just math with dramatic lighting. | A broke statistician\n# Already formatted lines are also accepted. Use \\n for manual line breaks.\n# Empty lines and lines starting with # or // are ignored.\n# Put your English quotes below this line.\n";
}
private void LoadQuotes(bool force)
{
lock (QuoteLock)
{
try
{
useRussianQuotes = ShouldUseRussianQuotes();
string b = ResolveQuoteFilePath();
if (!string.Equals(activeQuoteFilePath, b, StringComparison.OrdinalIgnoreCase))
{
activeQuoteFilePath = b;
cachedQuoteFileWriteTimeUtc = DateTime.MinValue;
PatchedInstances.Clear();
force = true;
}
EnsureQuoteFileExists(activeQuoteFilePath);
if (string.IsNullOrEmpty(activeQuoteFilePath) || !File.Exists(activeQuoteFilePath))
{
cachedQuotes = EmptyQuotes;
cachedQuoteFileWriteTimeUtc = DateTime.MinValue;
PatchedInstances.Clear();
return;
}
DateTime lastWriteTimeUtc = File.GetLastWriteTimeUtc(activeQuoteFilePath);
if (!force && lastWriteTimeUtc == cachedQuoteFileWriteTimeUtc)
{
return;
}
Dictionary<string, QuoteParts> dictionary = new Dictionary<string, QuoteParts>(StringComparer.Ordinal);
Dictionary<string, QuoteParts> dictionary2 = new Dictionary<string, QuoteParts>(StringComparer.Ordinal);
List<string> list = new List<string>();
string[] array = File.ReadAllLines(activeQuoteFilePath, Encoding.UTF8);
for (int i = 0; i < array.Length; i++)
{
string text = array[i].Trim();
if (!string.IsNullOrEmpty(text) && !text.StartsWith("#", StringComparison.Ordinal) && !text.StartsWith("//", StringComparison.Ordinal))
{
list.Add(ParseQuoteLine(text, dictionary, dictionary2));
}
}
cachedQuotes = NormalizeQuotes(list.ToArray());
QuotePartsByDisplayedText.Clear();
QuotePartsByQuoteText.Clear();
foreach (KeyValuePair<string, QuoteParts> item in dictionary)
{
QuotePartsByDisplayedText[item.Key] = item.Value;
}
foreach (KeyValuePair<string, QuoteParts> item2 in dictionary2)
{
QuotePartsByQuoteText[item2.Key] = item2.Value;
}
cachedQuoteFileWriteTimeUtc = lastWriteTimeUtc;
PatchedInstances.Clear();
((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("Loaded {0} custom {1} loading quote(s).", cachedQuotes.Length, useRussianQuotes ? "Russian" : "English"));
}
catch (Exception ex)
{
cachedQuotes = EmptyQuotes;
cachedQuoteFileWriteTimeUtc = DateTime.MinValue;
PatchedInstances.Clear();
((BaseUnityPlugin)this).Logger.LogWarning((object)("Failed to load custom loading quotes: " + ex.Message));
}
}
}
private static string ParseQuoteLine(string line, Dictionary<string, QuoteParts> displayedParts, Dictionary<string, QuoteParts> quoteParts)
{
string text = line.Replace("\\n", "\n").Trim();
int num = text.IndexOf('|');
if (num < 0)
{
return text;
}
string text2 = text.Substring(0, num).Trim();
string text3 = text.Substring(num + 1).Trim().TrimStart(new char[1] { '|' })
.Trim();
if (string.IsNullOrEmpty(text2) || string.IsNullOrEmpty(text3))
{
return text;
}
string text4 = FormatQuoteWithAuthor(text2, text3);
QuoteParts value = new QuoteParts(text2, text3, text4);
displayedParts[NormalizeRuntimeText(text4)] = value;
quoteParts[NormalizeRuntimeText(text2)] = value;
return text4;
}
private static bool TrySplitFormattedQuote(string text, out QuoteParts parts)
{
parts = null;
int num = text.LastIndexOf("\n- ", StringComparison.Ordinal);
if (num < 0)
{
return false;
}
string text2 = text.Substring(0, num).Trim();
string text3 = text.Substring(num + 3).Trim();
if (string.IsNullOrEmpty(text2) || string.IsNullOrEmpty(text3))
{
return false;
}
parts = new QuoteParts(text2, text3, text);
return true;
}
private static string NormalizeRuntimeText(string text)
{
if (text == null)
{
return string.Empty;
}
return text.Replace("\r\n", "\n").Replace("\r", "\n").Trim();
}
private static string FormatQuoteWithAuthor(string quote, string author)
{
string text = ((QuoteAuthorFormat == null || string.IsNullOrEmpty(QuoteAuthorFormat.Value)) ? "{0}\\n- {1}" : QuoteAuthorFormat.Value);
text = text.Replace("\\n", "\n");
try
{
return string.Format(text, quote, author);
}
catch
{
return quote + "\n- " + author;
}
}
private static string[] GetCachedQuotes()
{
lock (QuoteLock)
{
if (cachedQuotes.Length == 0)
{
return EmptyQuotes;
}
string[] array = new string[cachedQuotes.Length];
Array.Copy(cachedQuotes, array, cachedQuotes.Length);
return array;
}
}
private static string[] CopyQuotes(string[] source)
{
if (source == null || source.Length == 0)
{
return EmptyQuotes;
}
string[] array = new string[source.Length];
Array.Copy(source, array, source.Length);
return array;
}
private static string[] MergeQuotes(string[] vanillaQuotes, string[] customQuotes)
{
List<string> list = new List<string>();
AddUniqueQuotes(list, vanillaQuotes);
AddUniqueQuotes(list, customQuotes);
return list.ToArray();
}
private static string[] NormalizeQuotes(string[] quotes)
{
List<string> list = new List<string>();
AddUniqueQuotes(list, quotes);
return list.ToArray();
}
private static void AddUniqueQuotes(List<string> target, string[] source)
{
if (source == null)
{
return;
}
HashSet<string> hashSet = new HashSet<string>(target, StringComparer.Ordinal);
for (int i = 0; i < source.Length; i++)
{
string text = ((source[i] == null) ? string.Empty : source[i].Trim());
if (!string.IsNullOrEmpty(text) && !hashSet.Contains(text))
{
target.Add(text);
hashSet.Add(text);
}
}
}
private static void LogWarning(string message)
{
if ((Object)(object)Instance != (Object)null)
{
((BaseUnityPlugin)Instance).Logger.LogWarning((object)message);
}
}
}
}