using System;
using System.Collections;
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.RegularExpressions;
using BepInEx;
using HarmonyLib;
using JigglePhysics;
using Newtonsoft.Json;
using TMPro;
using UltraClean;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using UnityEngine.Video;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: UnverifiableCode]
public class TextCleaner : MonoBehaviour
{
[CompilerGenerated]
private sealed class <MenuMessage>d__12 : IEnumerator<object>, IEnumerator, IDisposable
{
private int <>1__state;
private object <>2__current;
private GameObject <target1>5__2;
private GameObject <target2>5__3;
private int <i>5__4;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <MenuMessage>d__12(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<target1>5__2 = null;
<target2>5__3 = null;
<>1__state = -2;
}
private bool MoveNext()
{
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
//IL_0076: Expected O, but got Unknown
//IL_0225: Unknown result type (might be due to invalid IL or missing references)
//IL_022f: Expected O, but got Unknown
//IL_02ff: Unknown result type (might be due to invalid IL or missing references)
//IL_015b: Unknown result type (might be due to invalid IL or missing references)
Transform parent;
GameObject val;
RectTransform component;
TextMeshProUGUI[] componentsInChildren;
string text;
TextMeshProUGUI[] array;
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
Debug.Log((object)"[UltraClean] MenuMessage START");
<target1>5__2 = null;
<i>5__4 = 0;
goto IL_0098;
case 1:
<>1__state = -1;
<i>5__4++;
goto IL_0098;
case 2:
{
<>1__state = -1;
<i>5__4++;
break;
}
IL_0098:
if (<i>5__4 < 10)
{
<target1>5__2 = GameObject.Find("Canvas/Main Menu (1)/LeftSide/Panel/Text (2)");
if (!((Object)(object)<target1>5__2 != (Object)null))
{
<>2__current = (object)new WaitForSeconds(0.5f);
<>1__state = 1;
return true;
}
Debug.Log((object)"[UltraClean] Target FOUND");
}
if ((Object)(object)<target1>5__2 == (Object)null)
{
Debug.LogError((object)"[UltraClean] Target NOT FOUND after 10 attempts");
return false;
}
parent = <target1>5__2.transform.parent;
if ((Object)(object)parent == (Object)null)
{
Debug.LogError((object)"[UltraClean] Target parent is NULL");
return false;
}
try
{
val = Object.Instantiate<GameObject>(<target1>5__2, parent);
}
catch (Exception ex)
{
Debug.LogError((object)("[UltraClean] Instantiate failed: " + ex));
return false;
}
if ((Object)(object)val == (Object)null)
{
Debug.LogError((object)"[UltraClean] Clone is NULL after Instantiate");
return false;
}
((Object)val).name = "ultraclean_message";
component = val.GetComponent<RectTransform>();
if ((Object)(object)component != (Object)null)
{
((Transform)component).position = new Vector3(130f, 62.1059f, 0f);
}
componentsInChildren = val.GetComponentsInChildren<TextMeshProUGUI>(true);
if (componentsInChildren == null)
{
return false;
}
text = "0.8.6";
array = componentsInChildren;
foreach (TextMeshProUGUI val2 in array)
{
if (!((Object)(object)val2 == (Object)null))
{
string text2 = ((TMP_Text)val2).text;
text2 = text2.Replace("INIT SOCIALS...OK", "ULTRACLEAN_V." + text + " READY");
((TMP_Text)val2).text = "<color=\"orange\">" + text2;
}
}
val.SetActive(true);
<target2>5__3 = null;
<i>5__4 = 0;
break;
}
if (<i>5__4 < 10)
{
<target2>5__3 = GameObject.Find("Canvas/Main Menu (1)/LeftSide/Panel/Text (2)");
if (!((Object)(object)<target2>5__3 != (Object)null))
{
<>2__current = (object)new WaitForSeconds(0.5f);
<>1__state = 2;
return true;
}
Debug.Log((object)"[UltraClean] Target2 FOUND");
}
Transform parent2 = <target2>5__3.transform.parent;
if ((Object)(object)parent2 == (Object)null)
{
Debug.LogError((object)"[UltraClean] Target2 parent2 is NULL");
return false;
}
GameObject val3;
try
{
val3 = Object.Instantiate<GameObject>(<target2>5__3, parent2);
}
catch (Exception ex2)
{
Debug.LogError((object)("[UltraClean] Instantiate target2 failed: " + ex2));
return false;
}
if ((Object)(object)val3 == (Object)null)
{
Debug.LogError((object)"[UltraClean] Clone2 is NULL after Instantiate");
}
((Object)val3).name = "ultraclean_message2";
RectTransform component2 = val3.GetComponent<RectTransform>();
if ((Object)(object)component2 != (Object)null)
{
((Transform)component2).position = new Vector3(127.5f, 95.2908f, 0f);
}
TextMeshProUGUI[] componentsInChildren2 = val3.GetComponentsInChildren<TextMeshProUGUI>(true);
if (componentsInChildren2 == null)
{
return false;
}
array = componentsInChildren2;
foreach (TextMeshProUGUI val4 in array)
{
if (!((Object)(object)val4 == (Object)null))
{
if (((Object)((Component)val4).gameObject).name == "ultraclean_message2")
{
((TMP_Text)val4).text = "<mark=#000000>INIT MODULES...OK";
}
else
{
((TMP_Text)val4).text = "INIT MODULES...OK";
}
}
}
val3.SetActive(true);
Debug.Log((object)"[UltraClean] MenuMessage END");
return false;
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
private float timer;
private float checkInterval = 0.15f;
private void Start()
{
if (UltraCleanPlugin.wordConfig != null)
{
checkInterval = Mathf.Max(0.01f, UltraCleanPlugin.wordConfig.checkInterval);
}
}
private void Update()
{
UltraCleanWordConfig wordConfig = UltraCleanPlugin.wordConfig;
if (wordConfig == null || wordConfig.rules == null || wordConfig.rules.Length == 0)
{
return;
}
timer += Time.deltaTime;
if (timer < checkInterval)
{
return;
}
timer = 0f;
TMP_Text[] array = Object.FindObjectsOfType<TMP_Text>();
foreach (TMP_Text val in array)
{
if (!((Object)(object)val == (Object)null))
{
string text = val.text;
string text2 = ApplyRules(text, wordConfig.rules);
if (text2 != text)
{
Debug.Log((object)("[UltraClean] Replaced in '" + ((Object)((Component)val).gameObject).name + "': \"" + text + "\" -> \"" + text2 + "\""));
val.text = text2;
}
}
}
MapInfoBase[] array2 = Object.FindObjectsOfType<MapInfoBase>();
foreach (MapInfoBase val2 in array2)
{
if (!((Object)(object)val2 == (Object)null))
{
string layerName = val2.layerName;
string levelName = val2.levelName;
string text3 = ApplyRules(layerName, wordConfig.rules);
string text4 = ApplyRules(levelName, wordConfig.rules);
if (text3 != layerName)
{
Debug.Log((object)("[UltraClean] Replaced in MapInfoBase.layerName: \"" + layerName + "\" -> \"" + text3 + "\""));
val2.layerName = text3;
}
if (text4 != levelName)
{
Debug.Log((object)("[UltraClean] Replaced in MapInfoBase.levelName: \"" + levelName + "\" -> \"" + text4 + "\""));
val2.levelName = text4;
}
}
}
CleanSubtitleCaptions(wordConfig.rules);
}
private void CleanSubtitleCaptions(WordRule[] rules)
{
Subtitle[] array = Object.FindObjectsOfType<Subtitle>();
foreach (Subtitle val in array)
{
if (!((Object)(object)val == (Object)null) && !((Object)(object)val.uiText == (Object)null))
{
string text = val.uiText.text;
string text2 = ApplyRules(text, rules);
if (text2 != text)
{
Debug.Log((object)("[UltraClean] Replaced in Subtitle.uiText: \"" + text + "\" -> \"" + text2 + "\""));
val.uiText.text = text2;
}
}
}
SubtitleController instance = MonoSingleton<SubtitleController>.Instance;
if (!((Object)(object)instance != (Object)null) || instance.delayedSubs == null)
{
return;
}
foreach (SubtitleData delayedSub in instance.delayedSubs)
{
if (delayedSub != null)
{
string caption = delayedSub.caption;
string text3 = ApplyRules(caption, rules);
if (text3 != caption)
{
Debug.Log((object)("[UltraClean] Replaced in SubtitleController.delayedSubs: \"" + caption + "\" -> \"" + text3 + "\""));
delayedSub.caption = text3;
}
}
}
}
private string ApplyRules(string text, WordRule[] rules)
{
if (string.IsNullOrEmpty(text) || rules == null || rules.Length == 0)
{
return text;
}
string text2 = text;
foreach (WordRule wordRule in rules)
{
if (wordRule != null && !string.IsNullOrEmpty(wordRule.find))
{
string replacement = (((wordRule.operation ?? "replace").Trim().ToLowerInvariant() == "remove") ? string.Empty : (wordRule.replace ?? string.Empty));
text2 = ApplySingleRule(text2, wordRule.find, replacement, wordRule.matchCase ?? "auto", wordRule.wholeWord);
}
}
return text2;
}
private string ApplySingleRule(string input, string search, string replacement, string matchCase, bool wholeWord)
{
if (string.IsNullOrEmpty(input) || string.IsNullOrEmpty(search))
{
return input;
}
string pattern = (wholeWord ? ("\\b" + Regex.Escape(search) + "\\b") : Regex.Escape(search));
RegexOptions options = RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.CultureInvariant;
return Regex.Replace(input, pattern, delegate(Match match)
{
string value = match.Value;
return (matchCase ?? "auto").Trim().ToLowerInvariant() switch
{
"lower" => replacement.ToLowerInvariant(),
"upper" => replacement.ToUpperInvariant(),
"preserve" => replacement,
_ => MatchCapitalization(value, replacement),
};
}, options);
}
private string MatchCapitalization(string original, string replacement)
{
if (string.IsNullOrEmpty(replacement))
{
return replacement;
}
if (IsAllUpper(original))
{
return replacement.ToUpperInvariant();
}
if (IsAllLower(original))
{
return replacement.ToLowerInvariant();
}
if (IsCapitalized(original))
{
return Capitalize(replacement);
}
return replacement;
}
private bool IsAllUpper(string s)
{
bool result = false;
foreach (char c in s)
{
if (char.IsLetter(c))
{
result = true;
if (!char.IsUpper(c))
{
return false;
}
}
}
return result;
}
private bool IsAllLower(string s)
{
bool result = false;
foreach (char c in s)
{
if (char.IsLetter(c))
{
result = true;
if (!char.IsLower(c))
{
return false;
}
}
}
return result;
}
private bool IsCapitalized(string s)
{
if (string.IsNullOrEmpty(s))
{
return false;
}
if (!char.IsUpper(s[0]))
{
return false;
}
bool flag = false;
for (int i = 1; i < s.Length; i++)
{
if (char.IsLetter(s[i]))
{
flag = true;
if (!char.IsLower(s[i]))
{
return false;
}
}
}
if (!flag)
{
return s.Length == 1;
}
return true;
}
private string Capitalize(string s)
{
if (string.IsNullOrEmpty(s))
{
return s;
}
if (s.Length == 1)
{
return char.ToUpperInvariant(s[0]).ToString();
}
return char.ToUpperInvariant(s[0]) + s.Substring(1).ToLowerInvariant();
}
[IteratorStateMachine(typeof(<MenuMessage>d__12))]
public IEnumerator MenuMessage()
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <MenuMessage>d__12(0);
}
}
namespace UltraClean
{
[Serializable]
public class UltraCleanWordConfig
{
public float checkInterval = 0.15f;
public WordRule[] rules = new WordRule[1]
{
new WordRule
{
operation = "replace",
find = "lust",
replace = "excess",
matchCase = "auto",
wholeWord = false
}
};
}
[Serializable]
public class WordRule
{
public string operation = "replace";
public string find;
public string replace = "";
public string matchCase = "auto";
public bool wholeWord;
}
[BepInPlugin("com.fuckyou.ultraclean", "UltraClean", "1.0.0")]
public class UltraCleanPlugin : BaseUnityPlugin
{
[Serializable]
public struct TextureSwapEntry
{
public string originalName;
public Texture2D replacement;
}
[Serializable]
public struct SkinnedMeshSwapEntry
{
public string originalName;
public Mesh replacementMesh;
}
public class CoroutineRunner : MonoBehaviour
{
private static CoroutineRunner _instance;
public static CoroutineRunner Instance
{
get
{
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: Expected O, but got Unknown
if ((Object)(object)_instance == (Object)null)
{
GameObject val = new GameObject("CoroutineRunner");
Object.DontDestroyOnLoad((Object)val);
_instance = val.AddComponent<CoroutineRunner>();
}
return _instance;
}
}
}
[HarmonyPatch(typeof(JiggleRigBuilder), "Awake")]
internal class lol7
{
private static void Postfix(JiggleRigBuilder __instance)
{
if (!((Object)(object)__instance == (Object)null))
{
Debug.LogWarning((object)"bye");
Object.Destroy((Object)(object)__instance);
}
}
}
[HarmonyPatch(typeof(PowerVoiceController), "Awake")]
internal class lol3
{
private static void Postfix(PowerVoiceController __instance)
{
__instance.intro = (AudioClip[])(object)new AudioClip[1];
__instance.enrage = (AudioClip[])(object)new AudioClip[1];
__instance.greatsword = (AudioClip[])(object)new AudioClip[1];
__instance.cheapShot = (AudioClip[])(object)new AudioClip[1];
__instance.rapier = (AudioClip[])(object)new AudioClip[1];
__instance.glaive = (AudioClip[])(object)new AudioClip[1];
__instance.spearThrow = (AudioClip[])(object)new AudioClip[1];
__instance.spear = (AudioClip[])(object)new AudioClip[1];
__instance.greatsword = (AudioClip[])(object)new AudioClip[1];
__instance.glaiveThrow = (AudioClip[])(object)new AudioClip[1];
}
}
[HarmonyPatch(typeof(PowerVoiceController), "Spear")]
internal class lol4
{
private static bool Prefix(ref AudioClip __result)
{
__result = null;
return false;
}
}
[HarmonyPatch(typeof(PowerVoiceController), "Intro")]
internal class lol5
{
private static bool Prefix(ref AudioClip __result)
{
__result = null;
return false;
}
}
[HarmonyPatch(typeof(PowerVoiceController), "Enrage")]
internal class lol6
{
private static bool Prefix(ref AudioClip __result)
{
__result = null;
return false;
}
}
[HarmonyPatch(typeof(PowerVoiceController), "Taunt")]
internal class lol8
{
private static bool Prefix(ref AudioClip __result)
{
__result = null;
return false;
}
}
[HarmonyPatch(typeof(PowerVoiceController), "CheapShot")]
internal class lol9
{
private static bool Prefix(ref AudioClip __result)
{
__result = null;
return false;
}
}
[HarmonyPatch(typeof(PowerVoiceController), "SpearThrow")]
internal class lol10
{
private static bool Prefix(ref AudioClip __result)
{
__result = null;
return false;
}
}
[HarmonyPatch(typeof(PowerVoiceController), "Glaive")]
internal class lol11
{
private static bool Prefix(ref AudioClip __result)
{
__result = null;
return false;
}
}
[HarmonyPatch(typeof(PowerVoiceController), "GlaiveThrow")]
internal class lol12
{
private static bool Prefix(ref AudioClip __result)
{
__result = null;
return false;
}
}
[HarmonyPatch(typeof(PowerVoiceController), "Greatsword")]
internal class lol13
{
private static bool Prefix(ref AudioClip __result)
{
__result = null;
return false;
}
}
[HarmonyPatch(typeof(PowerVoiceController), "Rapier")]
internal class lol14
{
private static bool Prefix(ref AudioClip __result)
{
__result = null;
return false;
}
}
[HarmonyPatch(typeof(PowerIntro), "Activate")]
internal class lol15
{
private static bool Prefix(PowerIntro __instance)
{
__instance.introOverride = null;
return true;
}
}
[HarmonyPatch(typeof(Mindflayer), "Awake")]
internal class lol2
{
private static void Postfix(Mindflayer __instance)
{
if ((Object)(object)__instance.smr != (Object)null && (Object)(object)__instance.ensim != (Object)null)
{
if ((Object)(object)_texNormal != (Object)null)
{
__instance.maleMaterial.SetTexture("_MainTex", (Texture)(object)_texNormal);
}
if ((Object)(object)_texEnraged != (Object)null)
{
__instance.maleMaterialEnraged.SetTexture("_MainTex", (Texture)(object)_texEnraged);
}
__instance.smr.sharedMesh = __instance.maleMesh;
((Renderer)__instance.smr).material = __instance.maleMaterial;
__instance.ensim.enragedMaterial = __instance.maleMaterialEnraged;
}
}
}
[HarmonyPatch(typeof(StockMapInfo), "Awake")]
internal class lol
{
private static void Postfix(StockMapInfo __instance)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
Scene activeScene = SceneManager.GetActiveScene();
string name = ((Scene)(ref activeScene)).name;
if (name.StartsWith("6440445"))
{
Debug.LogError((object)"UltraClean: Booted into 2-2");
string[] pathParts = new string[3] { "1 Nonstuff", "Building with Interior", "Skeleton 1" };
string[] pathParts2 = new string[3] { "1 Nonstuff", "Building with Interior", "Skeleton 1 (1)" };
GameObject val = FindInactive("1 - First District");
if ((Object)(object)val != (Object)null)
{
Transform transform = val.transform;
Transform val2 = FindDeepChildPath(transform, pathParts);
Transform val3 = FindDeepChildPath(transform, pathParts2);
if ((Object)(object)val2 != (Object)null)
{
Object.Destroy((Object)(object)((Component)val2).gameObject);
}
if ((Object)(object)val3 != (Object)null)
{
Object.Destroy((Object)(object)((Component)val3).gameObject);
}
}
else
{
Debug.LogError((object)"UltraClean: Root '1 - First District' not found!");
}
}
if (name.StartsWith("9dcce8"))
{
Debug.LogError((object)"UltraClean: im gonna skip this whole fucking level");
GameObject val4 = FindInactive("Canvas");
if ((Object)(object)val4 != (Object)null)
{
Transform val5 = FindInChildrenRecursive(val4.transform, "PowerUpVignette");
if ((Object)(object)val5 != (Object)null)
{
Object.Destroy((Object)(object)((Component)val5).gameObject);
}
SkipRunner skipRunner = val4.AddComponent<SkipRunner>();
skipRunner._intermission = _intermissionVid;
skipRunner.RunWaitAndRankless();
((Component)skipRunner).gameObject.SetActive(true);
}
else
{
Debug.LogError((object)"UltraClean: oh shit canvas not found");
}
}
if (name.StartsWith("e6c104"))
{
Debug.LogError((object)"UltraClean: Booted into 6-1");
string[] pathParts3 = new string[2] { "14", "Cube (2)" };
GameObject val6 = FindInactive("Exteriors");
if ((Object)(object)val6 != (Object)null)
{
Transform val7 = FindDeepChildPath(val6.transform, pathParts3);
if ((Object)(object)val7 != (Object)null)
{
MeshRenderer component = ((Component)val7).GetComponent<MeshRenderer>();
if ((Object)(object)component != (Object)null)
{
Material[] materialArray = ((Renderer)component).GetMaterialArray();
materialArray[1] = materialArray[0];
((Renderer)component).SetMaterialArray(materialArray);
}
}
}
else
{
Debug.LogError((object)"UltraClean: Root 'Exteriors' not found!");
}
}
FishObject[] array = Resources.FindObjectsOfTypeAll<FishObject>();
foreach (FishObject val8 in array)
{
if ((Object)(object)val8 != (Object)null && val8.fishName.Contains("Shark"))
{
val8.description = "The great white shark (Carcharodon carcharias), also known as the white shark, white pointer, or simply great white, is a species of large mackerel shark.\r\n\r\nLives in huge bodies of water and avoids land, though it may swim close to shore to feed.";
}
}
SpawnableObject[] array2 = Resources.FindObjectsOfTypeAll<SpawnableObject>();
foreach (SpawnableObject val9 in array2)
{
if ((Object)(object)val9 != (Object)null && val9.objectName == "Power")
{
val9.description = "Much like the other archangels, Gabriel had a radiance that inspired many followers, the most numerous of which were the Powers, who acted as his disciples.\n\nAshamed of their incomplete bodies, they use a part of their energy to always carry a useless gold arm with them in order to look more like the fully formed archangels they aspire to be.\n\nWhile Heaven's tastes began to trend towards ornateness and decoration, Gabriel stuck with the simpler old style of armor as a sign of discipline. Though Powers initially followed suit, in his absence in having become the Judge of Hell, their standards gradually slipped and they adopted the vanity of their peers.\n\nLike all Angels, Powers are exempt and unable to partake in standard biological processes.";
}
if ((Object)(object)val9 != (Object)null && val9.objectName == "Mindflayer")
{
val9.description = "Rare but extremely dangerous, the Mindflayer is a machine that has adapted and mastered the use of Hell Energy alongside its own technological prowess. \n\n\nDespite it being a waste of resources, Mindflayers will use everything in its power to protect the plastic body from harm, even if that means destroying itself in the process.";
}
}
}
private static GameObject FindInactive(string name)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
Scene activeScene = SceneManager.GetActiveScene();
GameObject[] rootGameObjects = ((Scene)(ref activeScene)).GetRootGameObjects();
for (int i = 0; i < rootGameObjects.Length; i++)
{
Transform val = FindInChildrenRecursive(rootGameObjects[i].transform, name);
if ((Object)(object)val != (Object)null)
{
return ((Component)val).gameObject;
}
}
return null;
}
private static Transform FindInChildrenRecursive(Transform parent, string targetName)
{
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_002a: Expected O, but got Unknown
if (((Object)parent).name == targetName)
{
return parent;
}
foreach (Transform item in parent)
{
Transform val = FindInChildrenRecursive(item, targetName);
if ((Object)(object)val != (Object)null)
{
return val;
}
}
return null;
}
private static Transform FindDeepChild(Transform parent, string[] pathParts, int index = 0)
{
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: Expected O, but got Unknown
if (index >= pathParts.Length)
{
return parent;
}
foreach (Transform item in parent)
{
Transform val = item;
if (((Object)val).name == pathParts[index])
{
Transform val2 = FindDeepChild(val, pathParts, index + 1);
if ((Object)(object)val2 != (Object)null)
{
return val2;
}
}
}
return null;
}
}
internal static List<TextureSwapEntry> swaps = new List<TextureSwapEntry>();
internal static List<SkinnedMeshSwapEntry> meshSwaps = new List<SkinnedMeshSwapEntry>();
private static AssetBundle _bundle;
private static AssetBundle _powerBundle;
internal static Texture2D _texNormal;
internal static Texture2D _texEnraged;
internal static Texture2D _texMannequin;
internal static Texture2D _texMinos;
internal static Texture2D _texSisyphus;
internal static Texture2D _texSchism;
internal static Texture2D _texAttention;
internal static Texture2D _texPower;
internal static Texture2D _texPowerEnraged;
internal static Mesh _meshPower;
internal static VideoClip _intermissionVid;
internal static GameObject _powerObject;
internal static Mesh _powerSeparateMesh;
public static string wordConfigPath;
public static UltraCleanPlugin Instance { get; private set; }
public static UltraCleanWordConfig wordConfig { get; private set; }
private static GameObject FindInactive(string name)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
Scene activeScene = SceneManager.GetActiveScene();
GameObject[] rootGameObjects = ((Scene)(ref activeScene)).GetRootGameObjects();
for (int i = 0; i < rootGameObjects.Length; i++)
{
Transform val = FindInChildrenRecursive(rootGameObjects[i].transform, name);
if ((Object)(object)val != (Object)null)
{
return ((Component)val).gameObject;
}
}
return null;
}
public static void LoadWordConfig(string path)
{
try
{
Directory.CreateDirectory(Path.GetDirectoryName(path));
if (!File.Exists(path))
{
wordConfig = new UltraCleanWordConfig();
File.WriteAllText(path, JsonConvert.SerializeObject((object)wordConfig, (Formatting)1));
UltraCleanPlugin instance = Instance;
if (instance != null)
{
((BaseUnityPlugin)instance).Logger.LogInfo((object)"UltraClean: Created default words.json");
}
return;
}
wordConfig = JsonConvert.DeserializeObject<UltraCleanWordConfig>(File.ReadAllText(path));
if (wordConfig == null)
{
wordConfig = new UltraCleanWordConfig();
UltraCleanPlugin instance2 = Instance;
if (instance2 != null)
{
((BaseUnityPlugin)instance2).Logger.LogWarning((object)"UltraClean: words.json was invalid, using defaults.");
}
}
if (wordConfig.rules == null || wordConfig.rules.Length == 0)
{
wordConfig.rules = new WordRule[1]
{
new WordRule
{
operation = "replace",
find = "lust",
replace = "excess",
matchCase = "auto",
wholeWord = false
}
};
}
UltraCleanPlugin instance3 = Instance;
if (instance3 != null)
{
((BaseUnityPlugin)instance3).Logger.LogInfo((object)$"UltraClean: Loaded {wordConfig.rules.Length} word rules.");
}
}
catch (Exception arg)
{
UltraCleanPlugin instance4 = Instance;
if (instance4 != null)
{
((BaseUnityPlugin)instance4).Logger.LogError((object)$"UltraClean: Failed to load words.json: {arg}");
}
wordConfig = new UltraCleanWordConfig();
}
}
private static Transform FindInChildrenRecursive(Transform parent, string targetName)
{
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_002a: Expected O, but got Unknown
if (((Object)parent).name == targetName)
{
return parent;
}
foreach (Transform item in parent)
{
Transform val = FindInChildrenRecursive(item, targetName);
if ((Object)(object)val != (Object)null)
{
return val;
}
}
return null;
}
private static Transform FindDeepChild(Transform parent, string name)
{
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_002a: Expected O, but got Unknown
if (((Object)parent).name == name)
{
return parent;
}
foreach (Transform item in parent)
{
Transform val = FindDeepChild(item, name);
if ((Object)(object)val != (Object)null)
{
return val;
}
}
return null;
}
public void TextPatcher()
{
MapInfoBase[] array = Resources.FindObjectsOfTypeAll<MapInfoBase>();
foreach (MapInfoBase val in array)
{
if ((Object)(object)val != (Object)null && val.layerName.Contains("LUST"))
{
val.layerName = val.layerName.Replace("LUST", "EXCESS");
}
}
}
private void ReplaceMaterials()
{
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
//IL_003d: Invalid comparison between Unknown and I4
Material[] array = Resources.FindObjectsOfTypeAll<Material>();
foreach (Material val in array)
{
if ((Object)(object)val == (Object)null)
{
continue;
}
Shader shader = val.shader;
int propertyCount = shader.GetPropertyCount();
for (int j = 0; j < propertyCount; j++)
{
if ((int)shader.GetPropertyType(j) != 4)
{
continue;
}
string propertyName = shader.GetPropertyName(j);
Texture texture = val.GetTexture(propertyName);
if ((Object)(object)texture == (Object)null)
{
continue;
}
foreach (TextureSwapEntry swap in swaps)
{
if (((Object)texture).name == swap.originalName && (Object)(object)swap.replacement != (Object)null)
{
val.SetTexture(propertyName, (Texture)(object)swap.replacement);
}
}
}
}
}
private static Transform FindDeepChildPath(Transform parent, string[] pathParts, int index = 0)
{
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: Expected O, but got Unknown
if (index >= pathParts.Length)
{
return parent;
}
foreach (Transform item in parent)
{
Transform val = item;
if (((Object)val).name == pathParts[index])
{
Transform val2 = FindDeepChildPath(val, pathParts, index + 1);
if ((Object)(object)val2 != (Object)null)
{
return val2;
}
}
}
return null;
}
private void Awake()
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
Instance = this;
new Harmony("com.fuckyou.ultraclean").PatchAll();
((BaseUnityPlugin)this).Logger.LogInfo((object)"UltraClean: Harmony patches applied.");
_bundle = AssetBundle.LoadFromFile(Path.Combine(ModPath(), "ultraclean.bundle"));
wordConfigPath = Path.Combine(ModPath(), "config", "words.json");
LoadWordConfig(wordConfigPath);
if ((Object)(object)_bundle == (Object)null)
{
((BaseUnityPlugin)this).Logger.LogError((object)"UltraClean: Failed to load ultraclean.bundle!");
}
else
{
_texNormal = _bundle.LoadAsset<Texture2D>("midflayer_m");
_texEnraged = _bundle.LoadAsset<Texture2D>("midflayer_m_enr");
_texMannequin = _bundle.LoadAsset<Texture2D>("mannegood");
_texMinos = _bundle.LoadAsset<Texture2D>("minosbutgood");
_texSisyphus = _bundle.LoadAsset<Texture2D>("sisyphusbutgood");
_texSchism = _bundle.LoadAsset<Texture2D>("schismbutgood");
_texAttention = _bundle.LoadAsset<Texture2D>("attentionbutgood");
_intermissionVid = _bundle.LoadAsset<VideoClip>("ultraclean_inter");
if ((Object)(object)_texNormal == (Object)null || (Object)(object)_texEnraged == (Object)null || (Object)(object)_texMannequin == (Object)null || (Object)(object)_texMinos == (Object)null || (Object)(object)_texSisyphus == (Object)null || (Object)(object)_texSchism == (Object)null || (Object)(object)_texAttention == (Object)null || (Object)(object)_intermissionVid == (Object)null)
{
((BaseUnityPlugin)this).Logger.LogError((object)"UltraClean: Missing expected textures in ultraclean.bundle");
}
}
_powerBundle = AssetBundle.LoadFromFile(Path.Combine(ModPath(), "ultraclean-power.bundle"));
if ((Object)(object)_powerBundle == (Object)null)
{
((BaseUnityPlugin)this).Logger.LogError((object)"UltraClean: Failed to load ultraclean-power.bundle!");
}
else
{
_texPower = _powerBundle.LoadAsset<Texture2D>("powerbutgood");
_texPowerEnraged = _powerBundle.LoadAsset<Texture2D>("powerbutgood-enr");
_powerObject = _powerBundle.LoadAsset<GameObject>("power-orig");
_powerSeparateMesh = _powerBundle.LoadAsset<Mesh>("PowerTransfer");
_meshPower = _powerSeparateMesh;
Debug.Log((object)("Loaded replacement mesh: " + (((Object)(object)_meshPower != (Object)null) ? ((Object)_meshPower).name : "NULL")));
Mesh[] array = _powerBundle.LoadAllAssets<Mesh>();
for (int i = 0; i < array.Length; i++)
{
Debug.Log((object)((Object)array[i]).name);
}
if ((Object)(object)_texPower == (Object)null || (Object)(object)_meshPower == (Object)null || (Object)(object)_texPowerEnraged == (Object)null)
{
((BaseUnityPlugin)this).Logger.LogError((object)"UltraClean: Missing expected assets in ultraclean-power.bundle");
((BaseUnityPlugin)this).Logger.LogError((object)("UltraClean: " + (((Object)(object)_texPower == (Object)null) ? "Missing bake_full texture. " : "") + (((Object)(object)_meshPower == (Object)null) ? "Missing PowerRedone mesh." : "") + (((Object)(object)_texPowerEnraged == (Object)null) ? "Missing _texPowerEnraged texture." : "")));
}
}
SceneManager.sceneLoaded += OnSceneLoaded;
swaps.Add(new TextureSwapEntry
{
originalName = "T_Mannequin 1",
replacement = _texMannequin
});
swaps.Add(new TextureSwapEntry
{
originalName = "T_Mannequin",
replacement = _texMannequin
});
swaps.Add(new TextureSwapEntry
{
originalName = "MinosPrime 1",
replacement = _texMinos
});
swaps.Add(new TextureSwapEntry
{
originalName = "T_SisyphusBody_Pattern4",
replacement = _texSisyphus
});
swaps.Add(new TextureSwapEntry
{
originalName = "T_GreyHuskPaint2png",
replacement = _texSchism
});
swaps.Add(new TextureSwapEntry
{
originalName = "WaterProcessingAttention",
replacement = _texAttention
});
swaps.Add(new TextureSwapEntry
{
originalName = "T_Power",
replacement = _texPower
});
swaps.Add(new TextureSwapEntry
{
originalName = "T_Power 1",
replacement = _texPowerEnraged
});
}
private void OnDestroy()
{
if ((Object)(object)_bundle != (Object)null)
{
_bundle.Unload(false);
_bundle = null;
}
Instance = null;
}
public static string ModPath()
{
return Assembly.GetExecutingAssembly().Location.Substring(0, Assembly.GetExecutingAssembly().Location.LastIndexOf(Path.DirectorySeparatorChar));
}
private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
TextCleaner textCleaner = new GameObject("TextCleaner").AddComponent<TextCleaner>();
ReplaceMaterials();
TextPatcher();
if (((Scene)(ref scene)).name.StartsWith("b3e7f2f"))
{
((MonoBehaviour)textCleaner).StartCoroutine(textCleaner.MenuMessage());
}
}
}
public class SkipRunner : MonoBehaviour
{
[CompilerGenerated]
private sealed class <>c__DisplayClass2_0
{
public bool finished;
internal void <PlayIntermissionThenExit>b__0(VideoPlayer source)
{
finished = true;
}
}
[CompilerGenerated]
private sealed class <PlayIntermissionThenExit>d__2 : IEnumerator<object>, IEnumerator, IDisposable
{
private int <>1__state;
private object <>2__current;
private <>c__DisplayClass2_0 <>8__1;
public SkipRunner <>4__this;
private VideoPlayer <vp>5__2;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <PlayIntermissionThenExit>d__2(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>8__1 = null;
<vp>5__2 = null;
<>1__state = -2;
}
private bool MoveNext()
{
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
//IL_003f: Expected O, but got Unknown
//IL_0063: Unknown result type (might be due to invalid IL or missing references)
//IL_0068: Unknown result type (might be due to invalid IL or missing references)
//IL_0085: Unknown result type (might be due to invalid IL or missing references)
//IL_0095: Unknown result type (might be due to invalid IL or missing references)
//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
//IL_0100: Expected O, but got Unknown
//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
//IL_01d0: Expected O, but got Unknown
int num = <>1__state;
SkipRunner skipRunner = <>4__this;
switch (num)
{
default:
return false;
case 0:
{
<>1__state = -1;
<>8__1 = new <>c__DisplayClass2_0();
GameObject val = new GameObject("IntermissionCanvas");
val.AddComponent<Canvas>().renderMode = (RenderMode)0;
val.AddComponent<CanvasScaler>().uiScaleMode = (ScaleMode)1;
val.AddComponent<GraphicRaycaster>();
GameObject val2 = new GameObject("VideoPlayerOutput");
val2.transform.SetParent(val.transform, false);
RawImage obj = val2.AddComponent<RawImage>();
((Graphic)obj).rectTransform.anchorMin = Vector2.zero;
((Graphic)obj).rectTransform.anchorMax = Vector2.one;
((Graphic)obj).rectTransform.offsetMin = Vector2.zero;
((Graphic)obj).rectTransform.offsetMax = Vector2.zero;
<vp>5__2 = val.AddComponent<VideoPlayer>();
<vp>5__2.playOnAwake = false;
<vp>5__2.renderMode = (VideoRenderMode)2;
<vp>5__2.aspectRatio = (VideoAspectRatio)5;
RenderTexture val3 = new RenderTexture(Screen.width, Screen.height, 0);
<vp>5__2.targetTexture = val3;
obj.texture = (Texture)(object)val3;
string url = Path.Combine(UltraCleanPlugin.ModPath(), "ultraclean_inter.mp4");
<vp>5__2.source = (VideoSource)1;
<vp>5__2.url = url;
<vp>5__2.isLooping = false;
<vp>5__2.audioOutputMode = (VideoAudioOutputMode)1;
AudioSource val4 = val.AddComponent<AudioSource>();
<vp>5__2.EnableAudioTrack((ushort)0, true);
<vp>5__2.SetTargetAudioSource((ushort)0, val4);
<vp>5__2.Prepare();
goto IL_019b;
}
case 1:
<>1__state = -1;
goto IL_019b;
case 2:
{
<>1__state = -1;
break;
}
IL_019b:
if (!<vp>5__2.isPrepared)
{
<>2__current = null;
<>1__state = 1;
return true;
}
<>8__1.finished = false;
<vp>5__2.loopPointReached += (EventHandler)delegate
{
<>8__1.finished = true;
};
<vp>5__2.Play();
break;
}
if (!<>8__1.finished)
{
<>2__current = null;
<>1__state = 2;
return true;
}
((MonoBehaviour)skipRunner).StartCoroutine(skipRunner.WaitAndRanklessNextLevel());
return false;
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
[CompilerGenerated]
private sealed class <WaitAndRanklessNextLevel>d__3 : IEnumerator<object>, IEnumerator, IDisposable
{
private int <>1__state;
private object <>2__current;
public SkipRunner <>4__this;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <WaitAndRanklessNextLevel>d__3(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>1__state = -2;
}
private bool MoveNext()
{
int num = <>1__state;
SkipRunner skipRunner = <>4__this;
switch (num)
{
default:
return false;
case 0:
<>1__state = -1;
MonoSingleton<StatsManager>.Instance.fr.RanklessNextLevel("Main Menu");
Object.Destroy((Object)(object)skipRunner);
<>2__current = null;
<>1__state = 1;
return true;
case 1:
<>1__state = -1;
return false;
}
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
public VideoClip _intermission;
public void RunWaitAndRankless()
{
if ((Object)(object)_intermission != (Object)null)
{
((MonoBehaviour)this).StartCoroutine(PlayIntermissionThenExit());
}
else
{
((MonoBehaviour)this).StartCoroutine(WaitAndRanklessNextLevel());
}
}
[IteratorStateMachine(typeof(<PlayIntermissionThenExit>d__2))]
private IEnumerator PlayIntermissionThenExit()
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <PlayIntermissionThenExit>d__2(0)
{
<>4__this = this
};
}
[IteratorStateMachine(typeof(<WaitAndRanklessNextLevel>d__3))]
private IEnumerator WaitAndRanklessNextLevel()
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <WaitAndRanklessNextLevel>d__3(0)
{
<>4__this = this
};
}
}
}
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
internal sealed class IgnoresAccessChecksToAttribute : Attribute
{
internal IgnoresAccessChecksToAttribute(string assemblyName)
{
}
}
}