using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using A2.CleanLargeWoodGate.Prefabs; using A2.CleanLargeWoodGate.Prefabs.Code; using A2.CleanLargeWoodGate.Unity; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using Jotunn; using Jotunn.Managers; using Jotunn.Utils; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("Clean Large Wood Gate")] [assembly: AssemblyDescription("Removes blood from MountainKit_wood_gate.")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Clean Large Wood Gate")] [assembly: AssemblyCopyright("")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("fefa9141-3b96-5497-7c58-660a9652a5e4")] [assembly: AssemblyFileVersion("1.2.2.0")] [assembly: AssemblyVersion("1.2.2.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.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; } } } internal static class PluginInfo { public const string PluginGUID = "A2.CleanLargeWoodGate"; public const string PluginName = "Clean Large Wood Gate"; public const string PluginDescription = "Removes blood from MountainKit_wood_gate."; public const string PluginSemanticVersion = "1.2.2"; public const string PluginFullVersion = "1.2.2.0"; } namespace A2.CleanLargeWoodGate { [BepInPlugin("A2.CleanLargeWoodGate", "Clean Large Wood Gate", "1.2.2")] [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] internal class Plugin : BaseUnityPlugin { private static readonly Harmony _harmony = new Harmony("A2.CleanLargeWoodGate"); private static bool _isInitialized = false; public void Awake() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Invalid comparison between Unknown and I4 if ((int)SystemInfo.graphicsDeviceType != 4 && !_isInitialized) { _isInitialized = true; _harmony.PatchAll(); PluginConfig.Bind(((BaseUnityPlugin)this).Config); PrefabManager.OnVanillaPrefabsAvailable += OnVanillaPrefabsAvailable; } } public void OnDestroy() { if (_isInitialized) { _isInitialized = false; PrefabManager.OnVanillaPrefabsAvailable -= OnVanillaPrefabsAvailable; _harmony.UnpatchSelf(); } } private static void OnVanillaPrefabsAvailable() { Controller.Update(); } } internal class PluginConfig { public static ConfigFile? File; public static ConfigEntry? DisableBloodOnMountainKitWoodGate; public static void Bind(ConfigFile config) { if (File == null) { File = config; DisableBloodOnMountainKitWoodGate = WithChangedHandler(config.Bind("Disable blood decals", "Mountain kit wood gate", true, "Mountain kit wood gate")); } } private static ConfigEntry? WithChangedHandler(ConfigEntry? configEntry) { if (configEntry != null) { configEntry.SettingChanged += OnSettingsChanged; } return configEntry; } private static void OnSettingsChanged(object sender, EventArgs e) { Controller.Update(); } } } namespace A2.CleanLargeWoodGate.Unity { internal static class GameObjectExtensions { public static bool SetChildrenInactive(this GameObject prefab, params string[] names) { if (prefab == null) { return false; } int num = 0; Transform[] componentsInChildren = prefab.GetComponentsInChildren(false); foreach (Transform val in componentsInChildren) { if (val != null && names.Contains(((Object)val).name, StringComparer.InvariantCultureIgnoreCase)) { GameObject gameObject = ((Component)val).gameObject; if (gameObject != null) { gameObject.SetActive(false); num++; } } } return num > 0; } public static bool SetSubChildrenInactive(this GameObject prefab, string subParent, params string[] names) { string subParent2 = subParent; if (prefab == null) { return false; } Transform val = prefab.GetComponentsInChildren(true)?.FirstOrDefault((Func)((Transform x) => string.Compare(((Object)x).name, subParent2, StringComparison.InvariantCultureIgnoreCase) == 0)); if (val == null) { return false; } int num = 0; Transform[] componentsInChildren = ((Component)val).GetComponentsInChildren(false); foreach (Transform val2 in componentsInChildren) { if (val2 != null && names.Contains(((Object)val2).name, StringComparer.InvariantCultureIgnoreCase)) { GameObject gameObject = ((Component)val2).gameObject; if (gameObject != null) { gameObject.SetActive(false); num++; } } } return num > 0; } public static bool SetChildrenActive(this GameObject prefab, params string[] names) { if (prefab == null) { return false; } int num = 0; Transform[] componentsInChildren = prefab.GetComponentsInChildren(true); foreach (Transform val in componentsInChildren) { if (val != null && names.Contains(((Object)val).name, StringComparer.InvariantCultureIgnoreCase)) { GameObject gameObject = ((Component)val).gameObject; if (gameObject != null) { gameObject.SetActive(true); num++; } } } return num > 0; } public static bool SetSubChildrenActive(this GameObject prefab, string subParent, params string[] names) { string subParent2 = subParent; if (prefab == null) { return false; } Transform val = prefab.GetComponentsInChildren(true)?.FirstOrDefault((Func)((Transform x) => string.Compare(((Object)x).name, subParent2, StringComparison.InvariantCultureIgnoreCase) == 0)); if (val == null) { return false; } int num = 0; Transform[] componentsInChildren = ((Component)val).GetComponentsInChildren(true); foreach (Transform val2 in componentsInChildren) { if (val2 != null && names.Contains(((Object)val2).name, StringComparer.InvariantCultureIgnoreCase)) { GameObject gameObject = ((Component)val2).gameObject; if (gameObject != null) { gameObject.SetActive(true); num++; } } } return num > 0; } public static bool DisableShaderKeyword(this GameObject prefab, string rendererName, string keyword) { string rendererName2 = rendererName; if (prefab == null) { return false; } Renderer val = ((prefab == null) ? null : prefab.GetComponentsInChildren()?.FirstOrDefault((Func)((Renderer x) => StringComparer.InvariantCultureIgnoreCase.Compare(((Object)x).name, rendererName2) == 0))); if (val == null) { return false; } Material sharedMaterial = val.sharedMaterial; if (sharedMaterial == null) { return false; } sharedMaterial.DisableKeyword(keyword); return true; } public static bool EnableShaderKeyword(this GameObject prefab, string rendererName, string keyword) { string rendererName2 = rendererName; if (prefab == null) { return false; } Renderer val = ((prefab == null) ? null : prefab.GetComponentsInChildren()?.FirstOrDefault((Func)((Renderer x) => StringComparer.InvariantCultureIgnoreCase.Compare(((Object)x).name, rendererName2) == 0))); if (val == null) { return false; } Material sharedMaterial = val.sharedMaterial; if (sharedMaterial == null) { return false; } sharedMaterial.EnableKeyword(keyword); return true; } } } namespace A2.CleanLargeWoodGate.Prefabs { internal static class Controller { private static readonly HashSet Names = new HashSet { "MountainKit_wood_gate" }; private static Dictionary Find() { Dictionary dictionary = new Dictionary(); foreach (string name2 in Names) { GameObject prefab = PrefabManager.Instance.GetPrefab(name2); if (prefab != null && !string.IsNullOrEmpty(((Object)prefab).name)) { string name = ((Object)prefab).name; dictionary.Add(name, prefab); } } return dictionary; } private static Dictionary FindClones() { return (from go in (from t in Object.FindObjectsByType((FindObjectsInactive)1, (FindObjectsSortMode)0) select ((Component)t).gameObject).Where(delegate(GameObject go) { string item = (((Object)go).name.EndsWith("(Clone)") ? ((Object)go).name.Substring(0, ((Object)go).name.Length - 7) : ((Object)go).name); return Names.Contains(item); }) group go by (!((Object)go).name.EndsWith("(Clone)")) ? ((Object)go).name : ((Object)go).name.Substring(0, ((Object)go).name.Length - 7)).ToDictionary((IGrouping g) => g.Key, (IGrouping g) => g.ToArray()); } private static bool Modify(Dictionary prefabs, Dictionary clones) { bool flag = true; return MountainKitWoodGate.Modify(prefabs, clones) && flag; } private static bool Restore(Dictionary prefabs, Dictionary clones) { bool flag = true; return MountainKitWoodGate.Restore(prefabs, clones) && flag; } public static bool Update() { if (!Flags.Evaluate()) { return false; } Dictionary dictionary = Find(); if (dictionary.Count == 0) { return false; } Dictionary clones = FindClones(); bool flag = false; flag = Restore(dictionary, clones) || flag; return Modify(dictionary, clones) || flag; } } internal static class Flags { public static PrefabState MountainKitWoodGate; public static bool Evaluate() { bool flag = false; return (PluginConfig.DisableBloodOnMountainKitWoodGate != null && Evaluate(ref MountainKitWoodGate, PluginConfig.DisableBloodOnMountainKitWoodGate.Value)) || flag; } private static bool Evaluate(ref PrefabState state, bool config) { if (config) { state = PrefabState.ToModify; return true; } if (state == PrefabState.ToRestore) { return true; } if (state == PrefabState.Modified) { state = PrefabState.ToRestore; return true; } if (state == PrefabState.ToModify) { state = PrefabState.Restored; return false; } state = PrefabState.Unknown; return false; } } internal enum PrefabState { Unknown, ToModify, Modified, ToRestore, Restored } internal static class PrefabTools { public static bool TryModify(IReadOnlyDictionary prefabs, IReadOnlyDictionary clones, string prefabName, ref PrefabState state, Func modifyFunc, string callerClassName, string callerMethodName) { try { if (state != PrefabState.ToModify) { return false; } if (!prefabs.TryGetValue(prefabName, out GameObject value)) { Logger.LogInfo((object)(callerClassName + "." + callerMethodName + ": Prefab " + prefabName + " not found.")); return false; } bool flag = true; if (clones.TryGetValue(prefabName, out GameObject[] value2)) { GameObject[] array = value2; foreach (GameObject arg in array) { flag = modifyFunc(arg) || flag; } } flag = modifyFunc(value) && flag; if (flag) { state = PrefabState.Modified; } return flag; } catch (Exception arg2) { Logger.LogError((object)$"{callerClassName}.{callerMethodName}: Exception occurred:\n{arg2}"); return false; } } public static bool TryRestore(IReadOnlyDictionary prefabs, IReadOnlyDictionary clones, string prefabName, ref PrefabState state, Func restoreFunc, string callerClassName, string callerMethodName) { try { if (state != PrefabState.ToRestore) { return false; } if (!prefabs.TryGetValue(prefabName, out GameObject value)) { Logger.LogInfo((object)(callerClassName + "." + callerMethodName + ": Prefab " + prefabName + " not found.")); return false; } bool flag = true; if (clones.TryGetValue(prefabName, out GameObject[] value2)) { GameObject[] array = value2; foreach (GameObject arg in array) { flag = restoreFunc(arg) || flag; } } flag = restoreFunc(value) && flag; if (flag) { state = PrefabState.Restored; } return flag; } catch (Exception arg2) { Logger.LogError((object)$"{callerClassName}.{callerMethodName}: Exception occurred:\n{arg2}"); return false; } } } } namespace A2.CleanLargeWoodGate.Prefabs.Code { internal static class MountainKitWoodGate { public const string Name = "Mountain kit wood gate"; public const string PrefabName = "MountainKit_wood_gate"; public static bool Modify(IReadOnlyDictionary prefabs, IReadOnlyDictionary clones) { return PrefabTools.TryModify(prefabs, clones, "MountainKit_wood_gate", ref Flags.MountainKitWoodGate, Modify, "MountainKitWoodGate", "Modify"); } public static bool Restore(IReadOnlyDictionary prefabs, IReadOnlyDictionary clones) { return PrefabTools.TryRestore(prefabs, clones, "MountainKit_wood_gate", ref Flags.MountainKitWoodGate, Restore, "MountainKitWoodGate", "Restore"); } private static bool Modify(GameObject prefab) { bool flag = true; return prefab.SetChildrenInactive("CastleKit_decal_fenrir_blood", "CastleKit_decal_fenrir_blood (1)", "CastleKit_decal_fenrir_blood (2)", "CastleKit_decal_fenrir_blood (3)") && flag; } private static bool Restore(GameObject prefab) { bool flag = true; return prefab.SetChildrenActive("CastleKit_decal_fenrir_blood", "CastleKit_decal_fenrir_blood (1)", "CastleKit_decal_fenrir_blood (2)", "CastleKit_decal_fenrir_blood (3)") && flag; } } }