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; 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 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(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(); } 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)(object)__instance.triggerScript.onInteract).AddListener((UnityAction)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 materialInformationContainers = new List(); [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)(() => MaterialsNetworkSync.waitingPlayerCount.IsInitialized)); } LNetworkVariable 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 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 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[] 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(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(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(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(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(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(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(true); foreach (ParticleSystem val3 in componentsInChildren2) { ParticleSystemRenderer component = ((Component)val3).GetComponent(); 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(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().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().sharedMaterials = sharedMaterials3; terrainData.RefreshPrototypes(); } } } } if (materialDestination != MaterialInformationContainer.MaterialType.VFX) { continue; } VisualEffect[] componentsInChildren4 = val.GetComponentsInChildren(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 waitingPlayerCount = LNetworkVariable.Connect("waitingPlayerCount", 0, (LNetworkVariableWritePerms)2, (Action)OnWaitingPlayerCountChanged); internal static LNetworkVariable MARCPatchingLever = LNetworkVariable.Connect("MARCPatchingLever", true, (LNetworkVariableWritePerms)2, (Action)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) { } } }