Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of MaterialAssetRestorerCore v2.0.0
Sniper1_1.MaterialAssetRestorerCore.dll
Decompiled 3 days agousing 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; using BepInEx; using BepInEx.Logging; using DunGen; using GameNetcodeStuff; using HarmonyLib; using LethalNetworkAPI; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using Unity.Netcode; using UnityEngine; using UnityEngine.Events; using UnityEngine.SceneManagement; using UnityEngine.VFX; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: IgnoresAccessChecksTo("AmazingAssets.TerrainToMesh")] [assembly: IgnoresAccessChecksTo("Assembly-CSharp-firstpass")] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: IgnoresAccessChecksTo("ClientNetworkTransform")] [assembly: IgnoresAccessChecksTo("com.olegknyazev.softmask")] [assembly: IgnoresAccessChecksTo("DissonanceVoip")] [assembly: IgnoresAccessChecksTo("DunGen")] [assembly: IgnoresAccessChecksTo("DunGen.Integration.ASPP")] [assembly: IgnoresAccessChecksTo("DunGen.Integration.UnityNav")] [assembly: IgnoresAccessChecksTo("EasyTextEffects")] [assembly: IgnoresAccessChecksTo("Facepunch Transport for Netcode for GameObjects")] [assembly: IgnoresAccessChecksTo("Facepunch.Steamworks.Win64")] [assembly: IgnoresAccessChecksTo("Unity.AI.Navigation")] [assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging")] [assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging.DocCodeExamples")] [assembly: IgnoresAccessChecksTo("Unity.Burst")] [assembly: IgnoresAccessChecksTo("Unity.Burst.Unsafe")] [assembly: IgnoresAccessChecksTo("Unity.Collections")] [assembly: IgnoresAccessChecksTo("Unity.Collections.LowLevel.ILSupport")] [assembly: IgnoresAccessChecksTo("Unity.InputSystem")] [assembly: IgnoresAccessChecksTo("Unity.InputSystem.ForUI")] [assembly: IgnoresAccessChecksTo("Unity.Jobs")] [assembly: IgnoresAccessChecksTo("Unity.Mathematics")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.Common")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.MetricTypes")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStats")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Component")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Configuration")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Implementation")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsReporting")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkProfiler.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkSolutionInterface")] [assembly: IgnoresAccessChecksTo("Unity.Netcode.Components")] [assembly: IgnoresAccessChecksTo("Unity.Netcode.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.Networking.Transport")] [assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Csg")] [assembly: IgnoresAccessChecksTo("Unity.ProBuilder")] [assembly: IgnoresAccessChecksTo("Unity.ProBuilder.KdTree")] [assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Poly2Tri")] [assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Stl")] [assembly: IgnoresAccessChecksTo("Unity.Profiling.Core")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.ShaderLibrary")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Config.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary")] [assembly: IgnoresAccessChecksTo("Unity.Services.Authentication")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Analytics")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Components")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Configuration")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Device")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments.Internal")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Internal")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Networking")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Registration")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Scheduler")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Telemetry")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Threading")] [assembly: IgnoresAccessChecksTo("Unity.Services.QoS")] [assembly: IgnoresAccessChecksTo("Unity.Services.Relay")] [assembly: IgnoresAccessChecksTo("Unity.TextMeshPro")] [assembly: IgnoresAccessChecksTo("Unity.Timeline")] [assembly: IgnoresAccessChecksTo("Unity.VisualEffectGraph.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.XR.CoreUtils")] [assembly: IgnoresAccessChecksTo("Unity.XR.Management")] [assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR")] [assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.ConformanceAutomation")] [assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.MetaQuestSupport")] [assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.MockRuntime")] [assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.OculusQuestSupport")] [assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.RuntimeDebugger")] [assembly: IgnoresAccessChecksTo("UnityEngine.ARModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.NVIDIAModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.SpatialTracking")] [assembly: IgnoresAccessChecksTo("UnityEngine.UI")] [assembly: IgnoresAccessChecksTo("UnityEngine.XR.LegacyInputHelpers")] [assembly: AssemblyCompany("Sniper1_1.MaterialAssetRestorerCore")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("2.0.0.0")] [assembly: AssemblyInformationalVersion("2.0.0+388e20f91116320c11909ea84229296db8ae0927")] [assembly: AssemblyProduct("MaterialAssetRestorerCore")] [assembly: AssemblyTitle("Sniper1_1.MaterialAssetRestorerCore")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("2.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.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] [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] [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 MaterialAssetRestorerCore { [BepInPlugin("Sniper1_1.MaterialAssetRestorerCore", "MaterialAssetRestorerCore", "2.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class MaterialAssetRestorerCore : BaseUnityPlugin { public static MaterialAssetRestorerCore Instance { get; private set; } internal static ManualLogSource Logger { get; private set; } internal static Harmony? Harmony { get; set; } private void Awake() { Logger = ((BaseUnityPlugin)this).Logger; Instance = this; MaterialsNetworkSync.InitializeNetworkVariables(); Patch(); Logger.LogInfo((object)"Sniper1_1.MaterialAssetRestorerCore v2.0.0 has loaded!"); Logger.LogInfo((object)"Oh hi, M.A.R.C."); } internal static void Patch() { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown if (Harmony == null) { Harmony = new Harmony("Sniper1_1.MaterialAssetRestorerCore"); } Logger.LogDebug((object)"Patching..."); Harmony.PatchAll(typeof(MaterialInit)); Harmony.PatchAll(typeof(MaterialSwap)); Harmony.PatchAll(typeof(MARCLeverPatchClass)); JSONManager.ReadJSONFiles(); Logger.LogDebug((object)"Finished patching!"); } internal static void Unpatch() { Logger.LogDebug((object)"Unpatching..."); Harmony? harmony = Harmony; if (harmony != null) { harmony.UnpatchSelf(); } Logger.LogDebug((object)"Finished unpatching!"); } } public class JSONManager { private class MaterialSetsWrapper { public List<MaterialInformationContainer> MaterialSets { get; set; } } public static void ReadJSONFiles() { DirectoryInfo parent = new DirectoryInfo(Assembly.GetExecutingAssembly().Location).Parent.Parent; DirectoryInfo[] directories = parent.GetDirectories("MaterialReplacements", SearchOption.AllDirectories); if (directories.Length == 0) { MaterialAssetRestorerCore.Logger.LogWarning((object)"Could not find MaterialReplacements in plugins folder."); return; } MaterialAssetRestorerCore.Logger.LogDebug((object)("Found MaterialReplacements in plugins folder with " + directories.Length + " files.")); DirectoryInfo[] array = directories; foreach (DirectoryInfo directoryInfo in array) { FileInfo[] files = directoryInfo.GetFiles("*.json", SearchOption.AllDirectories); foreach (FileInfo fileInfo in files) { MaterialAssetRestorerCore.Logger.LogDebug((object)("Reading JSON file: " + fileInfo.FullName)); try { string text = File.ReadAllText(fileInfo.FullName, Encoding.UTF8); MaterialSetsWrapper materialSetsWrapper = JsonConvert.DeserializeObject<MaterialSetsWrapper>(text); if (materialSetsWrapper == null || materialSetsWrapper.MaterialSets.Count == 0) { MaterialAssetRestorerCore.Logger.LogWarning((object)("No material sets found in JSON file '" + fileInfo.Name + "', skipping.")); continue; } foreach (MaterialInformationContainer materialSet in materialSetsWrapper.MaterialSets) { if (string.IsNullOrEmpty(materialSet.BaseMaterial)) { MaterialAssetRestorerCore.Logger.LogWarning((object)("Skipping entry in '" + fileInfo.Name + "': missing 'BaseMaterial'.")); continue; } if (string.IsNullOrEmpty(materialSet.ReplaceMaterial)) { MaterialAssetRestorerCore.Logger.LogWarning((object)("Skipping entry in '" + fileInfo.Name + "': missing 'ReplaceMaterial'.")); continue; } if (string.IsNullOrEmpty(materialSet.PrefabName) && string.IsNullOrEmpty(materialSet.SceneName)) { MaterialAssetRestorerCore.Logger.LogWarning((object)("Skipping entry in '" + fileInfo.Name + "': While both aren't needed, either a valid 'PrefabName' or 'SceneName' is required.")); continue; } if ((materialSet.MaterialSource.Value == MaterialInformationContainer.MaterialType.VFX && materialSet.MaterialDestination.Value != MaterialInformationContainer.MaterialType.VFX) || (materialSet.MaterialDestination.Value == MaterialInformationContainer.MaterialType.VFX && materialSet.MaterialSource.Value != MaterialInformationContainer.MaterialType.VFX)) { MaterialAssetRestorerCore.Logger.LogWarning((object)("Skipping entry in '" + fileInfo.Name + "': VFX must be paired with VFX")); continue; } if (materialSet.MaterialSource.Value == MaterialInformationContainer.MaterialType.TerrainDetail && string.IsNullOrEmpty(materialSet.SceneName)) { MaterialAssetRestorerCore.Logger.LogWarning((object)("Skipping entry in '" + fileInfo.Name + "': TerrainDetails as a 'MaterialSource' must have a valid 'SceneName'")); continue; } MaterialInit.materialInformationContainers.Add(materialSet); MaterialAssetRestorerCore.Logger.LogDebug((object)("Registered: '" + materialSet.BaseMaterial + "' -> '" + materialSet.ReplaceMaterial + "'" + ((materialSet.SceneName != null) ? (" in scene '" + materialSet.SceneName + "'") : "") + ((materialSet.PrefabName != null) ? (" from prefab '" + materialSet.PrefabName + "'") : "") + $" (Source: {materialSet.MaterialSource.Value}, Destination: {materialSet.MaterialDestination.Value})")); } } catch (Exception ex) { MaterialAssetRestorerCore.Logger.LogError((object)("Error reading JSON file '" + fileInfo.Name + "': " + ex.Message)); } } } } } [HarmonyPatch] internal static class MARCLeverPatchClass { private static string MARCDisabledHoverTip = "[ M.A.R.C. still caching materials! ]"; private static string PreviousDisabledHoverTip = null; private static StartOfRound startOfRoundInstance = null; [HarmonyPatch(typeof(StartMatchLever), "Update")] [HarmonyPostfix] private static void LeverPatch(StartMatchLever __instance) { if (!MaterialsNetworkSync.MARCPatchingLever.Value) { return; } if ((Object)(object)startOfRoundInstance == (Object)null) { startOfRoundInstance = Object.FindObjectOfType<StartOfRound>(); } if (__instance.triggerScript.disabledHoverTip != MARCDisabledHoverTip) { PreviousDisabledHoverTip = __instance.triggerScript.disabledHoverTip; } if (MaterialsNetworkSync.waitingPlayerCount.Value > 0) { __instance.triggerScript.disabledHoverTip = MARCDisabledHoverTip; __instance.triggerScript.interactable = false; return; } __instance.triggerScript.disabledHoverTip = PreviousDisabledHoverTip; if (((NetworkBehaviour)__instance).IsServer && startOfRoundInstance.inShipPhase && !startOfRoundInstance.travellingToNewLevel) { __instance.triggerScript.interactable = true; } } [HarmonyPatch(typeof(StartMatchLever), "Start")] [HarmonyPrefix] private static void SubscribeToLeverPull(StartMatchLever __instance) { if (MaterialsNetworkSync.MARCPatchingLever.Value) { MaterialAssetRestorerCore.Logger.LogDebug((object)"Subscribing to lever pull event"); ((UnityEvent<PlayerControllerB>)(object)__instance.triggerScript.onInteract).AddListener((UnityAction<PlayerControllerB>)OnLeverPulled); } } private static void OnLeverPulled(PlayerControllerB player) { MaterialsNetworkSync.MARCPatchingLever.Value = false; MaterialAssetRestorerCore.Logger.LogDebug((object)"Lever pulled, M.A.R.C. patching of lever disabled"); } } [HarmonyPatch(typeof(StartMatchLever))] public class MaterialInit { public static List<MaterialInformationContainer> materialInformationContainers = new List<MaterialInformationContainer>(); [HarmonyPostfix] [HarmonyPatch(typeof(StartMatchLever), "Start")] public static void InitializeMaterialsPatch() { ((MonoBehaviour)CoroutineHelper.Instance).StartCoroutine(InitializeMaterialsCoroutine()); } public static IEnumerator InitializeMaterialsCoroutine() { if (!MaterialsNetworkSync.waitingPlayerCount.IsInitialized) { yield return (object)new WaitUntil((Func<bool>)(() => MaterialsNetworkSync.waitingPlayerCount.IsInitialized)); } LNetworkVariable<int> waitingPlayerCount = MaterialsNetworkSync.waitingPlayerCount; int value = waitingPlayerCount.Value; waitingPlayerCount.Value = value + 1; SceneLoadPatches.MuteSceneStateChangeEvents(); MaterialAssetRestorerCore.Logger.LogInfo((object)"Initializing materials..."); foreach (MaterialInformationContainer container in materialInformationContainers) { yield return MaterialGet.GET_material(container.BaseMaterial, container.PrefabName, container.SceneName, container.MaterialSource, delegate(Object foundMaterial) { if (foundMaterial != (Object)null) { container.replacementMaterial = foundMaterial; } }); } SceneLoadPatches.UnmuteSceneStateChangeEvents(); MaterialAssetRestorerCore.Logger.LogInfo((object)"Finished initializing materials."); LNetworkVariable<int> waitingPlayerCount2 = MaterialsNetworkSync.waitingPlayerCount; value = waitingPlayerCount2.Value; waitingPlayerCount2.Value = value - 1; } } [HarmonyPatch(typeof(RoundManager), "FinishGeneratingNewLevelClientRpc")] public class MaterialSwap { [HarmonyPostfix] public static void SwapMaterials(RoundManager __instance) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) Scene sceneByName = SceneManager.GetSceneByName(__instance.currentLevel.sceneName); foreach (MaterialInformationContainer materialInformationContainer in MaterialInit.materialInformationContainers) { if (materialInformationContainer.replacementMaterial != (Object)null) { MaterialSet.SET_material(materialInformationContainer.ReplaceMaterial, materialInformationContainer.replacementMaterial, sceneByName, materialInformationContainer.MaterialDestination); } } } } public class MaterialInformationContainer { public enum MaterialType { Renderer, TerrainDetail, ParticleSystem, VFX } public string BaseMaterial = null; public string ReplaceMaterial = null; public string PrefabName = null; public string SceneName = null; public Object replacementMaterial = null; public MaterialType? MaterialSource = MaterialType.Renderer; public MaterialType? MaterialDestination = MaterialType.Renderer; public MaterialInformationContainer(string materialToFindName, string materialToReplaceName, string prefabToSearchName, string sceneToSearchName, Material replacementMaterial, MaterialType materialSource, MaterialType materialDestination) { BaseMaterial = materialToFindName; ReplaceMaterial = materialToReplaceName; PrefabName = prefabToSearchName; SceneName = sceneToSearchName; this.replacementMaterial = (Object)(object)replacementMaterial; MaterialSource = materialSource; MaterialDestination = materialDestination; } } [HarmonyPatch(typeof(SceneManager))] public class SceneLoadPatches { public static void MuteSceneStateChangeEvents() { Harmony? harmony = MaterialAssetRestorerCore.Harmony; if (harmony != null) { harmony.PatchAll(typeof(SceneLoadPatches)); } MaterialAssetRestorerCore.Logger.LogDebug((object)"Suppressed scene load/unload events from triggering."); } public static void UnmuteSceneStateChangeEvents() { Harmony? harmony = MaterialAssetRestorerCore.Harmony; if (harmony != null) { harmony.Unpatch((MethodBase)AccessTools.Method(typeof(SceneManager), "Internal_SceneLoaded", (Type[])null, (Type[])null), (HarmonyPatchType)0, MaterialAssetRestorerCore.Harmony.Id); } Harmony? harmony2 = MaterialAssetRestorerCore.Harmony; if (harmony2 != null) { harmony2.Unpatch((MethodBase)AccessTools.Method(typeof(SceneManager), "Internal_SceneUnloaded", (Type[])null, (Type[])null), (HarmonyPatchType)0, MaterialAssetRestorerCore.Harmony.Id); } MaterialAssetRestorerCore.Logger.LogDebug((object)"Re-enabled scene load/unload events."); } [HarmonyPrefix] [HarmonyPriority(800)] [HarmonyPatch("Internal_SceneLoaded")] public static bool MuteSceneLoadedEventTrigger() { return false; } [HarmonyPrefix] [HarmonyPriority(800)] [HarmonyPatch("Internal_SceneUnloaded")] public static bool MuteSceneUnloadedEventTrigger() { return false; } } public class MaterialGet { public static IEnumerator GET_material(string materialToFind, string prefabToSearch = null, string sceneToSearch = null, MaterialInformationContainer.MaterialType? materialSource = null, Action<Object> onComplete = null) { Object materialToReturn = null; if (string.IsNullOrEmpty(materialToFind)) { MaterialAssetRestorerCore.Logger.LogWarning((object)"Material to find is null."); onComplete?.Invoke(null); yield break; } if (!string.IsNullOrEmpty(prefabToSearch)) { GameObject[] objects = Resources.FindObjectsOfTypeAll<GameObject>(); GameObject[] array = objects; foreach (GameObject prefab in array) { if (((Object)prefab).name == prefabToSearch) { MaterialAssetRestorerCore.Logger.LogDebug((object)("Found a prefab '" + prefabToSearch + "'.")); if (!materialSource.HasValue || materialSource == MaterialInformationContainer.MaterialType.Renderer) { materialToReturn = (Object)(object)GetFromRenderers(prefab, materialToFind); } if (materialSource == MaterialInformationContainer.MaterialType.ParticleSystem) { materialToReturn = (Object)(object)GetFromParticleSystems(prefab, materialToFind); } if (materialSource == MaterialInformationContainer.MaterialType.TerrainDetail) { materialToReturn = (Object)(object)GetFromTerrainDetails(prefab, materialToFind); } if (materialSource == MaterialInformationContainer.MaterialType.VFX) { materialToReturn = (Object)(object)GetFromVFX(prefab, materialToFind); } if (materialToReturn != (Object)null) { break; } } } } else if (!string.IsNullOrEmpty(sceneToSearch)) { Scene scene = SceneManager.GetSceneByName(sceneToSearch); if (sceneToSearch != "SampleSceneRelay" && !((Scene)(ref scene)).isLoaded) { MaterialAssetRestorerCore.Logger.LogDebug((object)("Attempting to access scene '" + sceneToSearch + "'.")); yield return SceneManager.LoadSceneAsync(sceneToSearch, (LoadSceneMode)1); scene = SceneManager.GetSceneByName(sceneToSearch); MaterialAssetRestorerCore.Logger.LogDebug((object)$"Found scene '{sceneToSearch}'? {((Scene)(ref scene)).isLoaded}"); if (!((Scene)(ref scene)).IsValid()) { MaterialAssetRestorerCore.Logger.LogWarning((object)("Scene '" + sceneToSearch + "' not found.")); onComplete?.Invoke(null); yield break; } } GameObject[] gameObjects = ((Scene)(ref scene)).GetRootGameObjects(); GameObject[] array2 = gameObjects; foreach (GameObject gameObject in array2) { if (sceneToSearch != "SampleSceneRelay") { gameObject.SetActive(false); } if (!materialSource.HasValue || materialSource == MaterialInformationContainer.MaterialType.Renderer) { materialToReturn = (Object)(object)GetFromRenderers(gameObject, materialToFind); } if (materialSource == MaterialInformationContainer.MaterialType.ParticleSystem) { materialToReturn = (Object)(object)GetFromParticleSystems(gameObject, materialToFind); } if (materialSource == MaterialInformationContainer.MaterialType.TerrainDetail) { materialToReturn = (Object)(object)GetFromTerrainDetails(gameObject, materialToFind); } if (materialSource == MaterialInformationContainer.MaterialType.VFX) { materialToReturn = (Object)(object)GetFromVFX(gameObject, materialToFind); } if (materialToReturn != (Object)null) { break; } } if (sceneToSearch != "SampleSceneRelay" && ((Scene)(ref scene)).isLoaded) { yield return SceneManager.UnloadSceneAsync(scene); MaterialAssetRestorerCore.Logger.LogDebug((object)("Unloaded scene '" + sceneToSearch + "'.")); } } MaterialAssetRestorerCore.Logger.LogInfo((object)("Material '" + materialToFind + "' search completed. Found: " + ((materialToReturn != (Object)null) ? "Yes" : "No"))); onComplete?.Invoke(materialToReturn); } private static Material GetFromRenderers(GameObject objToSearch, string materialToFind) { Renderer[] componentsInChildren = objToSearch.GetComponentsInChildren<Renderer>(true); foreach (Renderer val in componentsInChildren) { if ((Object)(object)val.sharedMaterial != (Object)null && ((Object)val.sharedMaterial).name == materialToFind && ((Object)val.sharedMaterial.shader).name != "Hidden/InternalErrorShader") { MaterialAssetRestorerCore.Logger.LogDebug((object)("Found material '" + materialToFind + "' in '" + ((Object)objToSearch).name + "''s renderers.")); return val.sharedMaterial; } } return null; } private static Material GetFromParticleSystems(GameObject objToSearch, string materialToFind) { ParticleSystemRenderer[] componentsInChildren = objToSearch.GetComponentsInChildren<ParticleSystemRenderer>(true); foreach (ParticleSystemRenderer val in componentsInChildren) { if ((Object)(object)((Renderer)val).sharedMaterial != (Object)null && ((Object)((Renderer)val).sharedMaterial).name == materialToFind && ((Object)((Renderer)val).sharedMaterial.shader).name != "Hidden/InternalErrorShader") { MaterialAssetRestorerCore.Logger.LogDebug((object)("Found material '" + materialToFind + "' in '" + ((Object)objToSearch).name + "''s particle systems.")); return ((Renderer)val).sharedMaterial; } } return null; } private static Material GetFromTerrainDetails(GameObject objToSearch, string materialToFind) { Terrain[] componentsInChildren = objToSearch.GetComponentsInChildren<Terrain>(true); foreach (Terrain val in componentsInChildren) { DetailPrototype[] detailPrototypes = val.terrainData.detailPrototypes; foreach (DetailPrototype val2 in detailPrototypes) { if (!((Object)(object)val2.prototype != (Object)null)) { continue; } Renderer[] componentsInChildren2 = val2.prototype.GetComponentsInChildren<Renderer>(true); foreach (Renderer val3 in componentsInChildren2) { if ((Object)(object)val3.sharedMaterial != (Object)null && ((Object)val3.sharedMaterial).name == materialToFind && ((Object)val3.sharedMaterial.shader).name != "Hidden/InternalErrorShader") { MaterialAssetRestorerCore.Logger.LogDebug((object)("Found material '" + materialToFind + "' in '" + ((Object)objToSearch).name + "'s detail prototype.")); return val3.sharedMaterial; } } } } return null; } private static VisualEffectAsset GetFromVFX(GameObject objToSearch, string materialToFind) { VisualEffect[] componentsInChildren = objToSearch.GetComponentsInChildren<VisualEffect>(true); foreach (VisualEffect val in componentsInChildren) { if ((Object)(object)val.visualEffectAsset != (Object)null && ((Object)val.visualEffectAsset).name == materialToFind) { MaterialAssetRestorerCore.Logger.LogDebug((object)("Found vfx '" + materialToFind + "' in '" + ((Object)objToSearch).name + "''s visual effects.")); return val.visualEffectAsset; } } return null; } } public class MaterialSet { public static void SET_material(string original, Object replacement, Scene sceneToReplace, MaterialInformationContainer.MaterialType? materialDestination = null) { //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Expected O, but got Unknown //IL_0496: Unknown result type (might be due to invalid IL or missing references) //IL_04a0: Expected O, but got Unknown //IL_01db: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Expected O, but got Unknown //IL_034d: Unknown result type (might be due to invalid IL or missing references) //IL_0353: Expected O, but got Unknown GameObject[] rootGameObjects = ((Scene)(ref sceneToReplace)).GetRootGameObjects(); foreach (GameObject val in rootGameObjects) { if (!materialDestination.HasValue || materialDestination == MaterialInformationContainer.MaterialType.Renderer) { Renderer[] componentsInChildren = val.GetComponentsInChildren<Renderer>(true); foreach (Renderer val2 in componentsInChildren) { Material[] sharedMaterials = val2.sharedMaterials; bool flag = false; for (int k = 0; k < sharedMaterials.Length; k++) { if ((Object)(object)sharedMaterials[k] != (Object)null && ((Object)sharedMaterials[k]).name == original) { sharedMaterials[k] = (Material)replacement; flag = true; MaterialAssetRestorerCore.Logger.LogInfo((object)("Replaced material '" + original + "' with '" + replacement.name + "' in renderer '" + ((Object)((Component)val2).gameObject).name + "' in scene '" + ((Scene)(ref sceneToReplace)).name + "'.")); } } if (flag) { val2.sharedMaterials = sharedMaterials; } } } else if (materialDestination == MaterialInformationContainer.MaterialType.ParticleSystem) { ParticleSystem[] componentsInChildren2 = val.GetComponentsInChildren<ParticleSystem>(true); foreach (ParticleSystem val3 in componentsInChildren2) { ParticleSystemRenderer component = ((Component)val3).GetComponent<ParticleSystemRenderer>(); if (!((Object)(object)component != (Object)null)) { continue; } Material[] sharedMaterials2 = ((Renderer)component).sharedMaterials; bool flag2 = false; for (int m = 0; m < sharedMaterials2.Length; m++) { if ((Object)(object)sharedMaterials2[m] != (Object)null && ((Object)sharedMaterials2[m]).name == original) { sharedMaterials2[m] = (Material)replacement; flag2 = true; MaterialAssetRestorerCore.Logger.LogInfo((object)("Replaced material '" + original + "' with '" + replacement.name + "' in particle system '" + ((Object)((Component)val3).gameObject).name + "' in scene '" + ((Scene)(ref sceneToReplace)).name + "'.")); } } if (flag2) { ((Renderer)component).sharedMaterials = sharedMaterials2; } } } if (materialDestination == MaterialInformationContainer.MaterialType.TerrainDetail) { Terrain[] componentsInChildren3 = val.GetComponentsInChildren<Terrain>(true); foreach (Terrain val4 in componentsInChildren3) { TerrainData terrainData = val4.terrainData; if (!((Object)(object)terrainData != (Object)null)) { continue; } DetailPrototype[] detailPrototypes = terrainData.detailPrototypes; bool flag3 = false; for (int num = 0; num < detailPrototypes.Length; num++) { if (!((Object)(object)detailPrototypes[num].prototype != (Object)null)) { continue; } Material[] sharedMaterials3 = detailPrototypes[num].prototype.GetComponent<Renderer>().sharedMaterials; for (int num2 = 0; num2 < sharedMaterials3.Length; num2++) { if ((Object)(object)sharedMaterials3[num2] != (Object)null && ((Object)sharedMaterials3[num2]).name == original) { sharedMaterials3[num2] = (Material)replacement; flag3 = true; MaterialAssetRestorerCore.Logger.LogInfo((object)("Replaced material '" + original + "' with '" + replacement.name + "' in terrain detail '" + ((Object)detailPrototypes[num].prototype).name + "' in scene '" + ((Scene)(ref sceneToReplace)).name + "'.")); } } if (flag3) { detailPrototypes[num].prototype.GetComponent<Renderer>().sharedMaterials = sharedMaterials3; terrainData.RefreshPrototypes(); } } } } if (materialDestination != MaterialInformationContainer.MaterialType.VFX) { continue; } VisualEffect[] componentsInChildren4 = val.GetComponentsInChildren<VisualEffect>(true); foreach (VisualEffect val5 in componentsInChildren4) { bool flag4 = false; if ((Object)(object)val5 != (Object)null && (Object)(object)val5.visualEffectAsset != (Object)null && ((Object)val5.visualEffectAsset).name == original) { val5.visualEffectAsset = (VisualEffectAsset)replacement; val5.Reinit(); flag4 = true; MaterialAssetRestorerCore.Logger.LogInfo((object)("Replaced vfx '" + original + "' with '" + replacement.name + "' in vfx '" + ((Object)val5).name + "' in scene '" + ((Scene)(ref sceneToReplace)).name + "'.")); } } } } } internal static class MaterialsNetworkSync { internal static LNetworkVariable<int> waitingPlayerCount = LNetworkVariable<int>.Connect("waitingPlayerCount", 0, (LNetworkVariableWritePerms)2, (Action<int, int>)OnWaitingPlayerCountChanged); internal static LNetworkVariable<bool> MARCPatchingLever = LNetworkVariable<bool>.Connect("MARCPatchingLever", true, (LNetworkVariableWritePerms)2, (Action<bool, bool>)OnMARCPatchingLeverChanged); private static void OnWaitingPlayerCountChanged(int oldValue, int newValue) { MaterialAssetRestorerCore.Logger.LogWarning((object)$"M.A.R.C. Waiting player count changed from {oldValue} to {newValue}"); if (newValue <= 0) { MaterialAssetRestorerCore.Logger.LogDebug((object)"Pull the lever, Kronk!"); return; } MARCPatchingLever.Value = true; MaterialAssetRestorerCore.Logger.LogDebug((object)"Wrong lever!"); } private static void OnMARCPatchingLeverChanged(bool oldValue, bool newValue) { MaterialAssetRestorerCore.Logger.LogWarning((object)$"M.A.R.C. MARCPatchingLever changed from {oldValue} to {newValue}"); } internal static void InitializeNetworkVariables() { MaterialAssetRestorerCore.Logger.LogDebug((object)"Initialized network variables"); } } public static class MyPluginInfo { public const string PLUGIN_GUID = "Sniper1_1.MaterialAssetRestorerCore"; public const string PLUGIN_NAME = "MaterialAssetRestorerCore"; public const string PLUGIN_VERSION = "2.0.0"; } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }