using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text.RegularExpressions; using System.Threading.Tasks; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Logging; using HarmonyLib; using Jukebox.Components; using Microsoft.CodeAnalysis; using Notiffy.API; using NukeLib.Assets; using NukeLib.ImageUtils; using NukeLib.Reflection; using PluginConfig.API; using PluginConfig.API.Decorators; using PluginConfig.API.Fields; using PluginConfig.API.Functionals; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.SceneManagement; using VolumetricSkyboxes; using VolumetricSkyboxes.Components; using VolumetricSkyboxes.Utils; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("CybergrindSlideshow")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+83964a13f97589b0eea8a6ea16cfd2d7d5ecfb4d")] [assembly: AssemblyProduct("CybergrindSlideshow")] [assembly: AssemblyTitle("CybergrindSlideshow")] [assembly: AssemblyVersion("1.0.0.0")] [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 CybergrindSlideshow { public class ConfigManager { public enum SelectionMode { Random, DeterministicSequential } public enum SecondarySelectionMode { Independent, StrictlyMatchSkyboxName, ClosestColorToSkybox } public enum MonochromeSelectionMode { Independent } internal static readonly string ApplicationPath; internal static readonly string SkyboxesPath; internal static readonly string GridPath; internal static readonly string GlowPath; internal static readonly string MusicPath; internal static readonly string VolumetricSkyboxesPath; private static PluginConfigurator config; public static IntField ThemeChangeWaveInterval; public static BoolField ThemeChangeWhenMusicChanges; public static BoolField SkyboxEnabled; public static StringField SkyboxDir; public static BoolField SkyboxDirRecursive; public static EnumField SkyboxChangeOrder; public static BoolField SkyboxAllowVolumetric; public static BoolField ForceDisableVolumetricSkyboxGridTexture; public static BoolField LightingEnabled; public static FloatField LightingIntensity; public static BoolField LightingAdjustment; public static BoolField GridEnabled; public static StringField GridDir; public static BoolField GridDirRecursive; public static EnumField GridSelectionMode; public static BoolField GlowEnabled; public static StringField GlowDir; public static BoolField GlowDirRecursive; public static EnumField GlowSelectionMode; public static StringField LastVersion; public static void Initialize() { } static ConfigManager() { //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Expected O, but got Unknown //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Expected O, but got Unknown //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: Expected O, but got Unknown //IL_01fa: Unknown result type (might be due to invalid IL or missing references) //IL_0211: Unknown result type (might be due to invalid IL or missing references) //IL_022c: Unknown result type (might be due to invalid IL or missing references) //IL_0236: Expected O, but got Unknown //IL_024b: Unknown result type (might be due to invalid IL or missing references) //IL_0255: Expected O, but got Unknown //IL_0266: Unknown result type (might be due to invalid IL or missing references) //IL_027d: Unknown result type (might be due to invalid IL or missing references) //IL_0298: Unknown result type (might be due to invalid IL or missing references) //IL_02a2: Expected O, but got Unknown //IL_02bb: Unknown result type (might be due to invalid IL or missing references) //IL_02c5: Expected O, but got Unknown //IL_02da: Unknown result type (might be due to invalid IL or missing references) //IL_02e4: Expected O, but got Unknown //IL_0318: Unknown result type (might be due to invalid IL or missing references) //IL_0322: Expected O, but got Unknown //IL_0337: Unknown result type (might be due to invalid IL or missing references) //IL_0341: Expected O, but got Unknown //IL_0352: Unknown result type (might be due to invalid IL or missing references) //IL_0369: Unknown result type (might be due to invalid IL or missing references) //IL_0384: Unknown result type (might be due to invalid IL or missing references) //IL_038e: Expected O, but got Unknown //IL_03a7: Unknown result type (might be due to invalid IL or missing references) //IL_03b1: Expected O, but got Unknown //IL_03c6: Unknown result type (might be due to invalid IL or missing references) //IL_03d0: Expected O, but got Unknown //IL_03e1: Unknown result type (might be due to invalid IL or missing references) //IL_03f8: Unknown result type (might be due to invalid IL or missing references) //IL_0413: Unknown result type (might be due to invalid IL or missing references) //IL_041d: Expected O, but got Unknown //IL_0436: Unknown result type (might be due to invalid IL or missing references) //IL_0440: Expected O, but got Unknown //IL_0455: Unknown result type (might be due to invalid IL or missing references) //IL_045f: Expected O, but got Unknown //IL_048f: Unknown result type (might be due to invalid IL or missing references) //IL_04a6: Unknown result type (might be due to invalid IL or missing references) //IL_04c1: Unknown result type (might be due to invalid IL or missing references) //IL_04cb: Expected O, but got Unknown //IL_04e4: Unknown result type (might be due to invalid IL or missing references) //IL_04ee: Expected O, but got Unknown //IL_0503: Unknown result type (might be due to invalid IL or missing references) //IL_050d: Expected O, but got Unknown //IL_053d: Unknown result type (might be due to invalid IL or missing references) //IL_0554: Unknown result type (might be due to invalid IL or missing references) //IL_056e: Unknown result type (might be due to invalid IL or missing references) //IL_0573: Unknown result type (might be due to invalid IL or missing references) //IL_0580: Expected O, but got Unknown //IL_057b: Unknown result type (might be due to invalid IL or missing references) //IL_0581: Unknown result type (might be due to invalid IL or missing references) //IL_058e: Expected O, but got Unknown //IL_0589: Unknown result type (might be due to invalid IL or missing references) //IL_05a3: Expected O, but got Unknown //IL_059e: Unknown result type (might be due to invalid IL or missing references) //IL_05a8: Expected O, but got Unknown ApplicationPath = Path.Combine(Directory.GetParent(Application.dataPath)?.FullName); SkyboxesPath = Path.Combine(ApplicationPath, "Cybergrind", "Textures", "Skyboxes"); GridPath = Path.Combine(ApplicationPath, "Cybergrind", "Textures"); GlowPath = Path.Combine(ApplicationPath, "Cybergrind", "Textures", "Glows"); MusicPath = Path.Combine(ApplicationPath, "Cybergrind", "Music"); VolumetricSkyboxesPath = Path.Combine(ApplicationPath, "Cybergrind", "VolumetricSkyboxes"); config = PluginConfigurator.Create("Cybergrind Slideshow", "com.github.end-4.cybergrindSlideshow"); string text = Path.Combine(Plugin.workingDir, "icon.png"); if (File.Exists(text)) { config.SetIconWithURL(text); } new ConfigHeader(config.rootPanel, "", 10); new ConfigHeader(config.rootPanel, "-- USAGE NOTES --", 24); new ConfigHeader(config.rootPanel, "- Folders: The defaults follow the default organization of the base game, adjust if needed\n- Grid:\n - By default, the texture that has the closest color to the skybox will be chosen. To force a specific tile for a certain skybox, name it exactly the same except the file extension. Example: Skybox is SpAcE.png or SpAcE.cgvsb -> Matching grid is SpAcE.jpg or SpAcE.png\n - You can create grid sets by adding \"_base\", \"_top\", \"_topRow\" at the end of each texture (and make sure they're of same file extension), for example \"griddy_base.png\", \"griddy_top.png\", and \"griddy_topRow.png\" are always loaded together.\n- Glow: You can also match with skybox with precise file naming like grids, but other than that it's random\n- Volumetric skyboxes: Can be used, but they cause Slideshow to be inconsistent in dominant color detection & grid swapping, so they're disabled by default.", 13, (TextAlignmentOptions)513); new ConfigHeader(config.rootPanel, "Quick open", 18, (TextAlignmentOptions)513); ButtonArrayField val = new ButtonArrayField(config.rootPanel, "openDirButtons", 3, new float[3] { 0.33f, 0.33f, 0.33f }, new string[3] { "Skybox folder", "Grid folder", "Glow folder" }, 10f); val.OnClickEventHandler(0).onClick += (OnClick)delegate { Application.OpenURL(SkyboxDir.value); }; val.OnClickEventHandler(1).onClick += (OnClick)delegate { Application.OpenURL(GridDir.value); }; val.OnClickEventHandler(2).onClick += (OnClick)delegate { Application.OpenURL(GlowDir.value); }; new ConfigHeader(config.rootPanel, "", 10); new ConfigHeader(config.rootPanel, "-- GENERAL --", 24); ThemeChangeWaveInterval = new IntField(config.rootPanel, "Change theme every x wave, where x=", "themeChangeWaveInterval", 1); ThemeChangeWhenMusicChanges = new BoolField(config.rootPanel, "Change theme when music changes", "themeChangeWhenMusicChanges", false); new ConfigHeader(config.rootPanel, "", 10); new ConfigHeader(config.rootPanel, "-- SKYBOX --", 24); SkyboxEnabled = new BoolField(config.rootPanel, "Change skybox", "skyboxEnabled", true); SkyboxDir = new StringField(config.rootPanel, "Skybox folder", "skyboxDir", SkyboxesPath); SkyboxDirRecursive = new BoolField(config.rootPanel, "Consider subfolders", "skyboxDirRecursive", false); SkyboxChangeOrder = new EnumField(config.rootPanel, "Skybox change order", "skyboxChangeOrder", SelectionMode.Random); SkyboxAllowVolumetric = new BoolField(config.rootPanel, "Allow volumetric skyboxes", "skyboxAllowVolumetric", false); ForceDisableVolumetricSkyboxGridTexture = new BoolField(config.rootPanel, "Disallow grid change from volumetric skyboxes", "forceDisableVolumetricSkyboxGridTexture", false); new ConfigHeader(config.rootPanel, "", 10); new ConfigHeader(config.rootPanel, "-- LIGHTING --", 24); LightingEnabled = new BoolField(config.rootPanel, "Sync with skybox", "lightingEnabled", true); LightingIntensity = new FloatField(config.rootPanel, "Lighting intensity", "lightingIntensity", 5f); LightingAdjustment = new BoolField(config.rootPanel, "Adjust intensity based on lightness", "lightingAdjustment", true); new ConfigHeader(config.rootPanel, "", 10); new ConfigHeader(config.rootPanel, "-- GRID --", 24); GridEnabled = new BoolField(config.rootPanel, "Change grid", "gridEnabled", true); GridDir = new StringField(config.rootPanel, "Grid folder", "gridDir", GridPath); GridDirRecursive = new BoolField(config.rootPanel, "Consider subfolders", "gridDirRecursive", false); GridSelectionMode = new EnumField(config.rootPanel, "Grid selection mode", "gridSelectionMode", SecondarySelectionMode.ClosestColorToSkybox); new ConfigHeader(config.rootPanel, "", 10); new ConfigHeader(config.rootPanel, "-- GLOW --", 24); GlowEnabled = new BoolField(config.rootPanel, "Change glow", "glowEnabled", true); GlowDir = new StringField(config.rootPanel, "Glow folder", "growDir", GlowPath); GlowDirRecursive = new BoolField(config.rootPanel, "Consider subfolders", "glowDirRecursive", false); GlowSelectionMode = new EnumField(config.rootPanel, "Glow selection mode", "glowSelectionMode", MonochromeSelectionMode.Independent); new ConfigHeader(config.rootPanel, "", 10); new ConfigHeader(config.rootPanel, "-- DEBUG --", 24); ConfigPanel val2 = new ConfigPanel(config.rootPanel, "Developer options", "devOptions"); new ConfigHeader(val2, "", 10); new ConfigHeader(val2, "These don't do anything exciting. Don't bother.", 13); LastVersion = new StringField(val2, "Last version", "lastVersion", "0.0.0"); } } public static class JukeboxHelper { private static JukeboxMusicPlayer? _cachedCustomMusicPlayer; public static AudioClip? GetCurrentAudioClip() { if ((Object)(object)_cachedCustomMusicPlayer == (Object)null) { _cachedCustomMusicPlayer = Object.FindObjectOfType(); if ((Object)(object)_cachedCustomMusicPlayer == (Object)null) { return null; } } return _cachedCustomMusicPlayer.Source.clip; } public static void ResetCache() { _cachedCustomMusicPlayer = null; } } public static class PlaylistListener { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static PostBoolValueChangeEvent <>9__3_0; public static UnityAction <>9__3_1; internal void b__3_0(bool val) { _listening = val; } internal void b__3_1(Scene _, LoadSceneMode __) { _cachedCustomMusicPlayer = null; if (Plugin.JukeboxAvailable) { JukeboxHelper.ResetCache(); } } } private static bool _listening; private static CustomMusicPlayer? _cachedCustomMusicPlayer; private static AudioClip? _lastClip; public static void Initialize() { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown _listening = ConfigManager.ThemeChangeWhenMusicChanges.value; BoolField themeChangeWhenMusicChanges = ConfigManager.ThemeChangeWhenMusicChanges; object obj = <>c.<>9__3_0; if (obj == null) { PostBoolValueChangeEvent val = delegate(bool listening) { _listening = listening; }; <>c.<>9__3_0 = val; obj = (object)val; } themeChangeWhenMusicChanges.postValueChangeEvent += (PostBoolValueChangeEvent)obj; SceneManager.sceneLoaded += delegate { _cachedCustomMusicPlayer = null; if (Plugin.JukeboxAvailable) { JukeboxHelper.ResetCache(); } }; } private static AudioClip? GetCurrentVanillaAudioClip() { if ((Object)(object)_cachedCustomMusicPlayer == (Object)null) { _cachedCustomMusicPlayer = Object.FindObjectOfType(); if ((Object)(object)_cachedCustomMusicPlayer == (Object)null) { return null; } } return _cachedCustomMusicPlayer.source.clip; } public static void OnUpdate() { if (_listening) { AudioClip val = (Plugin.JukeboxAvailable ? JukeboxHelper.GetCurrentAudioClip() : GetCurrentVanillaAudioClip()); if ((Object)(object)val != (Object)(object)_lastClip) { ThemeChanger.ChangeTheme(); _lastClip = val; } } } } [BepInPlugin("com.github.end-4.cybergrindSlideshow", "CybergrindSlideshow", "1.2.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { [HarmonyPatch(typeof(EndlessGrid))] [HarmonyPatch("NextWave")] public class EndlessGridPatch { public static void Prefix() { try { ThemeChanger.SetupFirstWaveIfNecessary(); } catch (Exception ex) { Log.LogWarning((object)ex); } } public static void Postfix() { ThemeChanger.ChangeTheme(); } } [HarmonyPatch(typeof(EndlessGrid))] [HarmonyPatch("Start")] public class EndlessGridStart { public static void Postfix() { ThemeChanger.SetupScene(); } } internal static ManualLogSource Log; public static string workingPath = Assembly.GetExecutingAssembly().Location; public static string workingDir = Path.GetDirectoryName(workingPath); public const string PluginGUID = "com.github.end-4.cybergrindSlideshow"; public const string PluginName = "CybergrindSlideshow"; public const string PluginVersion = "1.2.0"; internal static bool VolumetricAvailable = false; internal static bool JukeboxAvailable = false; private void Awake() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; ConfigManager.Initialize(); UserHints.Initialize(); new Harmony("CybergrindSlideshow").PatchAll(); Log.LogInfo((object)"CybergrindSlideshow loaded"); } private void Start() { if (Chainloader.PluginInfos.ContainsKey("dev.flazhik.volumetric-skyboxes")) { VolumetricAvailable = true; } if (Chainloader.PluginInfos.ContainsKey("dev.flazhik.jukebox")) { JukeboxAvailable = true; } Log.LogInfo((object)$"Volumetric available: {VolumetricAvailable}"); Log.LogInfo((object)$"Jukebox available: {JukeboxAvailable}"); PlaylistListener.Initialize(); } private void Update() { if (!(SceneHelper.CurrentScene != "Endless")) { PlaylistListener.OnUpdate(); } } } public static class ThemeChanger { private record struct GridSet { public string Top; public string Base; public string TopRow; public static GridSet FromSingleFile(string filePath) { string fileExt = Path.GetExtension(filePath); string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(filePath); string baseDir = Path.GetDirectoryName(filePath) ?? ""; string baseName = Regex.Replace(fileNameWithoutExtension, "(base|topRow|toprow|top)$", ""); (string, string[])[] obj = new(string, string[])[3] { ("Top", new string[2] { "top", "TOP" }), ("Base", new string[2] { "base", "BASE" }), ("TopRow", new string[4] { "topRow", "toprow", "TOPROW", "TOP ROW" }) }; string text = (File.Exists(GetPath("")) ? GetPath("") : filePath); GridSet result = default(GridSet); (string, string[])[] array = obj; for (int i = 0; i < array.Length; i++) { (string, string[]) tuple = array[i]; string text2 = text; string[] item = tuple.Item2; for (int j = 0; j < item.Length; j++) { string text3 = GetPath(item[j]); if (File.Exists(text3)) { text2 = text3; break; } } switch (tuple.Item1) { case "Top": result.Top = text2; break; case "Base": result.Base = text2; break; case "TopRow": result.TopRow = text2; break; } } return result; string GetPath(string suffix) { return Path.Join(baseDir.AsSpan(), (baseName + suffix + fileExt).AsSpan()); } } public static GridSet FromPrefs() { PrefsManager instance = MonoSingleton.Instance; GridSet result = default(GridSet); if ((Object)(object)instance == (Object)null) { return result; } result.Top = instance.GetStringLocal("cyberGrind.customGrid_1", (string)null); result.TopRow = instance.GetStringLocal("cyberGrind.customGrid_2", (string)null); result.Base = instance.GetStringLocal("cyberGrind.customGrid_0", (string)null); return result; } } private static string LastSkyboxPath = ""; private static Color CachedSkyboxColor = Color.black; private static CustomTextures? CustomTexObj; private static GameObject LightObj; private static Light LightComp; private static Dictionary DirectoryCache = new Dictionary(); private static Dictionary DominantColorCache = new Dictionary(); private static readonly string[] ImageExtensions = new string[3] { ".jpg", ".jpeg", ".png" }; private static readonly string[] AudioExtensions = new string[3] { ".mp3", ".wav", ".ogg" }; private static readonly string[] GridFaceSuffixes = new string[12] { "", "base", "top", "topRow", "toprow", "_base", "_top", "_topRow", "_toprow", "_BASE", "_TOP", "_TOP ROW" }; private static bool FirstWaveChange = true; private static int wavesPassed = 0; private static bool IsVolumetricSkybox(string filePath) { return filePath.EndsWith(".cgvsb"); } private static Color GetDominantColorCached(string cacheKey, Texture2D? tex) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)tex == (Object)null) { return Color.black; } if (DominantColorCache.TryGetValue(cacheKey, out var value)) { return value; } Color dominantColor = ImageUtils.GetDominantColor(tex); DominantColorCache[cacheKey] = dominantColor; return dominantColor; } private static string SelectFile(string folderPath, ConfigManager.SelectionMode selectionMode, string[] allowedExtensions, bool recursive = false) { if (!Directory.Exists(folderPath)) { return ""; } string key = folderPath + "_" + recursive; if (!DirectoryCache.TryGetValue(key, out string[] value)) { SearchOption searchOption = (recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly); value = (from file in Directory.EnumerateFiles(folderPath, "*.*", searchOption) where allowedExtensions.Contains(Path.GetExtension(file), StringComparer.OrdinalIgnoreCase) select file).ToArray(); DirectoryCache[key] = value; } if (value.Length == 0) { return ""; } int num = 0; num = selectionMode switch { ConfigManager.SelectionMode.Random => Random.Range(0, value.Length), _ => MonoSingleton.Instance.currentWave % value.Length, }; if (value[num] == LastSkyboxPath) { num = (num + 1) % value.Length; } return LastSkyboxPath = value[num]; } private static string SelectSkyboxFile(string folderPath, ConfigManager.SelectionMode selectionMode) { return SelectFile(folderPath, selectionMode, (!Plugin.VolumetricAvailable || !ConfigManager.SkyboxAllowVolumetric.value) ? new string[3] { ".jpg", ".jpeg", ".png" } : new string[4] { ".jpg", ".jpeg", ".png", ".cgvsb" }, ConfigManager.SkyboxDirRecursive.value); } private static string SelectGridFile(string folderPath, ConfigManager.SelectionMode selectionMode, bool recursive) { return SelectFile(folderPath, selectionMode, new string[3] { ".jpg", ".jpeg", ".png" }, recursive); } private static string SelectMatchingFile(string searchDir, string baseFilePath, string[] suffixes, string[] extensions) { string text = Path.GetFileNameWithoutExtension(baseFilePath).Trim(); foreach (string text2 in suffixes) { foreach (string text3 in extensions) { string text4 = Path.Join(searchDir.AsSpan(), (text + text2 + text3).AsSpan()); if (File.Exists(text4)) { return text4; } } } return ""; } private static async Task ChangeSkybox(string filePath) { Plugin.Log.LogInfo((object)("Skybox -> " + filePath)); Material mat = ReflectionUtils.GetPrivate((object)(OutdoorLightMaster)Object.FindObjectsOfType(typeof(OutdoorLightMaster))[0], "skyboxMaterial"); Material mat2 = ReflectionUtils.GetPrivate((object)(OutdoorLightMaster)Object.FindObjectsOfType(typeof(OutdoorLightMaster))[0], "tempSkybox"); if (Plugin.VolumetricAvailable) { VolumetricSkyboxHelper.UnloadAllVolumetricSkyboxes(); } if (IsVolumetricSkybox(filePath)) { try { string guid = VolumetricSkyboxHelper.GuidForVolumetricSkyboxFile(filePath); if (Plugin.VolumetricAvailable) { VolumetricSkyboxHelper.LoadVolumetricSkybox(guid); } } catch (Exception ex) { Plugin.Log.LogWarning((object)ex); } } else { Texture2D mainTexture = (Texture2D)(object)(mat.mainTexture = (Texture)(object)(await FileAssetHelper.LoadTextureAsync(filePath))); mat2.mainTexture = (Texture)(object)mainTexture; } if (ConfigManager.GridSelectionMode.value == ConfigManager.SecondarySelectionMode.ClosestColorToSkybox || ConfigManager.LightingEnabled.value) { try { Texture mainTexture2 = mat.mainTexture; CachedSkyboxColor = GetDominantColorCached(filePath, (Texture2D?)(((object)((mainTexture2 is Texture2D) ? mainTexture2 : null)) ?? ((object)(/*isinst with value type is only supported in some contexts*/ ?? null)))); } catch (Exception ex2) { Plugin.Log.LogWarning((object)("Failed to get dominant color: " + ex2.Message)); } } } private static async void ChangeTechnicalGridTexture(string[] files, string textureName) { if ((Object)(object)CustomTexObj == (Object)null) { Plugin.Log.LogWarning((object)"CustomTextures not found"); return; } if ((Object)(object)((Component)CustomTexObj).gameObject != (Object)null && !((Component)CustomTexObj).gameObject.activeSelf) { ((Component)CustomTexObj).gameObject.SetActive(true); } Material[] mats = ReflectionUtils.GetPrivate((object)CustomTexObj, "gridMaterials"); if (mats == null) { Plugin.Log.LogWarning((object)"CustomTextures::gridMaterials not found"); return; } for (int i = 0; i < files.Length && i < mats.Length; i++) { string text = files[i]; if (File.Exists(text)) { Material val = mats[i]; val.SetTexture(textureName, (Texture)(object)(await FileAssetHelper.LoadTextureAsync(text))); } } } private static async void ChangeGridTexture(GridSet gridSet) { ChangeTechnicalGridTexture(new string[3] { gridSet.Base, gridSet.Top, gridSet.TopRow }, "_MainTex"); } private static void ChangeGlowTexture(GridSet gridSet) { ChangeTechnicalGridTexture(new string[3] { gridSet.Base, gridSet.Top, gridSet.TopRow }, "_EmissiveTex"); } private static async void ChangeGrid(string skyboxFilePath) { GridSet gridSet = default(GridSet); string text = SelectMatchingFile(ConfigManager.GridDir.value, skyboxFilePath, GridFaceSuffixes, ImageExtensions); if (text != "") { gridSet = GridSet.FromSingleFile(text); } else { switch (ConfigManager.GridSelectionMode.value) { case ConfigManager.SecondarySelectionMode.Independent: text = SelectGridFile(ConfigManager.GridDir.value, ConfigManager.SkyboxChangeOrder.value, ConfigManager.GridDirRecursive.value); gridSet = GridSet.FromSingleFile(text); break; case ConfigManager.SecondarySelectionMode.StrictlyMatchSkyboxName: gridSet = GridSet.FromPrefs(); break; case ConfigManager.SecondarySelectionMode.ClosestColorToSkybox: { Color targetColor = CachedSkyboxColor; await Task.Yield(); gridSet = GridSet.FromSingleFile(ImageUtils.FindClosestColorImage(targetColor, ConfigManager.GridDir.value)); break; } } } Plugin.Log.LogInfo((object)("Grid -> " + gridSet.Base + "\n + " + gridSet.Top + "\n + " + gridSet.TopRow)); ChangeGridTexture(gridSet); } private static void ChangeLighting(string skyboxFilePath) { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) OutdoorLightMaster instance = MonoSingleton.Instance; if ((Object)(object)instance == (Object)null) { return; } foreach (Light item in (from light in ((Component)instance).gameObject.GetComponentsInChildren() where (int)light.type == 1 select light).ToList()) { item.color = CachedSkyboxColor; float num = (ConfigManager.LightingAdjustment.value ? (1f + 0.39999998f * ColorUtils.PerceivedLightness(CachedSkyboxColor)) : 1f); item.intensity = ConfigManager.LightingIntensity.value * num; } } private static async void ChangeGlow(string skyboxFilePath) { string text = SelectMatchingFile(ConfigManager.GlowDir.value, skyboxFilePath, GridFaceSuffixes, ImageExtensions); if (text == "" && ConfigManager.GlowSelectionMode.value == ConfigManager.MonochromeSelectionMode.Independent) { text = SelectGridFile(ConfigManager.GlowDir.value, ConfigManager.SkyboxChangeOrder.value, ConfigManager.GlowDirRecursive.value); } ChangeGlowTexture(GridSet.FromSingleFile(text)); } public static async Task ChangeTheme() { if (FirstWaveChange) { FirstWaveChange = false; return; } wavesPassed++; if (wavesPassed < ConfigManager.ThemeChangeWaveInterval.value) { return; } wavesPassed = 0; string filePath = SelectSkyboxFile(ConfigManager.SkyboxDir.value, ConfigManager.SkyboxChangeOrder.value); if (!(filePath == "")) { Plugin.Log.LogInfo((object)"---- New wave ----"); await Task.Yield(); if (ConfigManager.SkyboxEnabled.value) { await ChangeSkybox(filePath); } if (ConfigManager.LightingEnabled.value) { ChangeLighting(filePath); } if (ConfigManager.GridEnabled.value) { ChangeGrid(filePath); } if (ConfigManager.GlowEnabled.value) { ChangeGlow(filePath); } } } public static void SetupScene() { FirstWaveChange = true; DirectoryCache.Clear(); DominantColorCache.Clear(); } public static void SetupFirstWaveIfNecessary() { if ((Object)(object)CustomTexObj == (Object)null) { CustomTexObj = Object.Instantiate(((Component)Object.FindObjectOfType()).gameObject).GetComponent(); Plugin.Log.LogInfo((object)"Duped CustomTextures"); } } } internal static class UserHints { private static readonly Dictionary VolumetricCopyActions; private static uint notificationId; private static void Hook() { NotificationSystem.ActionInvoked += OnActionInvoked; NotificationSystem.NotificationDeleted += OnNotificationDeleted; } private static void Unhook() { NotificationSystem.ActionInvoked -= OnActionInvoked; NotificationSystem.NotificationDeleted -= OnNotificationDeleted; } private static void OnActionInvoked(uint id, string actionIdentifier) { if (id == notificationId) { switch (actionIdentifier) { case "yes": CopyAndEnableCopyVolumetricSkyboxes(); break; case "remind": ConfigManager.LastVersion.value = "0.0.0"; break; } Unhook(); } } private static void OnNotificationDeleted(uint id) { if (id == notificationId) { Unhook(); } } private static void IssueFirstRunNoticeIfNecessary() { Version value = new Version(ConfigManager.LastVersion.value); if (new Version("1.1.0").CompareTo(value) == 1) { ConfigManager.LastVersion.value = "1.2.0"; if (Plugin.VolumetricAvailable) { notificationId = NotificationSystem.NotifySend("Cybergrind Slideshow", "1. Default settings should work, but configuration and usage notes are in Options > Plugin Config > Cybergrind Slideshow\n2. Would you like to enable Volumetric skyboxes support (might be inconsistent) and copy them to the slideshow folder?", (Sprite)null, Path.Combine(Plugin.workingDir, "icon.png"), (Urgency)1, "CybergrindSlideshow", 0u, VolumetricCopyActions, 20000); Hook(); } else { NotificationSystem.NotifySend("Cybergrind Slideshow", "Default settings should work, but configuration and usage notes are in Options > Plugin Config > Cybergrind Slideshow", (Sprite)null, Path.Combine(Plugin.workingDir, "icon.png"), (Urgency)1, "CybergrindSlideshow", 0u, (Dictionary)null, 10000); } } } private static void OnSceneLoaded(Scene s, LoadSceneMode m) { if (SceneHelper.CurrentScene == "Endless") { IssueFirstRunNoticeIfNecessary(); } } private static void CopyAndEnableCopyVolumetricSkyboxes() { ConfigManager.SkyboxAllowVolumetric.value = true; string volumetricSkyboxesPath = ConfigManager.VolumetricSkyboxesPath; string value = ConfigManager.SkyboxDir.value; string[] files = Directory.GetFiles(volumetricSkyboxesPath); foreach (string obj in files) { string fileName = Path.GetFileName(obj); string destFileName = Path.Combine(value, fileName); File.Copy(obj, destFileName, overwrite: true); Plugin.Log.LogInfo((object)("Copied: " + fileName)); } } public static void Initialize() { } static UserHints() { VolumetricCopyActions = new Dictionary { { "yes", "Yes" }, { "no", "No" }, { "remind", "Remind me later" } }; SceneManager.sceneLoaded += OnSceneLoaded; } } public static class VolumetricSkyboxHelper { public static void UnloadAllVolumetricSkyboxes() { VolumetricSkyboxesManager instance = MonoSingleton.Instance; if ((Object)(object)instance == (Object)null) { return; } Dictionary dictionary = ReflectionUtils.GetPrivate>((object)instance, "_skyboxes"); if (dictionary == null) { return; } Dictionary.KeyCollection keyCollection = dictionary?.Keys; if (keyCollection == null) { return; } foreach (string item in new List(keyCollection)) { if ((Object)(object)instance == (Object)null) { break; } instance.RemoveSkybox(item); } } public static void LoadVolumetricSkybox(string guid) { int num; if (!ConfigManager.ForceDisableVolumetricSkyboxGridTexture.value) { num = 0; } else { num = (MonoSingleton.Instance.GetBoolLocal("cyberGrind.volumetricSkyboxes.useSkyboxesGridTextures", true) ? 1 : 0); if (num != 0) { MonoSingleton.Instance.SetBoolLocal("cyberGrind.volumetricSkyboxes.useSkyboxesGridTextures", false); } } VolumetricSkyboxesManager instance = MonoSingleton.Instance; if ((Object)(object)instance != (Object)null) { instance.AddSkybox(guid); } if (num != 0) { MonoSingleton.Instance.SetBoolLocal("cyberGrind.volumetricSkyboxes.useSkyboxesGridTextures", true); } } public static VolumetricSkyboxBundleData UnpackFile(string filePath) { return SkyboxFileUtility.UnpackSkybox(filePath, false); } public static string GuidForVolumetricSkyboxFile(string filePath) { return UnpackFile(filePath).guid; } } }