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<SelectionMode> 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<SecondarySelectionMode> GridSelectionMode;
public static BoolField GlowEnabled;
public static StringField GlowDir;
public static BoolField GlowDirRecursive;
public static EnumField<MonochromeSelectionMode> 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, "-- <color=#95f857>USAGE NOTES</color> --", 24);
new ConfigHeader(config.rootPanel, "- <color=#95f857><u>Folders</u></color>: The defaults follow the default organization of the base game, adjust if needed\n- <color=#95f857><u>Grid</u></color>:\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- <color=#95f857><u>Glow</u></color>: You can also match with skybox with precise file naming like grids, but other than that it's random\n- <color=#95f857><u>Volumetric skyboxes</u></color>: 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, "-- <color=#69fff7>GENERAL</color> --", 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, "-- <color=#55bcec>SKYBOX</color> --", 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<SelectionMode>(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, "-- <color=#f1c40f>LIGHTING</color> --", 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, "-- <color=#9c87f4>GRID</color> --", 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<SecondarySelectionMode>(config.rootPanel, "Grid selection mode", "gridSelectionMode", SecondarySelectionMode.ClosestColorToSkybox);
new ConfigHeader(config.rootPanel, "", 10);
new ConfigHeader(config.rootPanel, "-- <color=#f77428>GLOW</color> --", 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<MonochromeSelectionMode>(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<JukeboxMusicPlayer>();
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<Scene, LoadSceneMode> <>9__3_1;
internal void <Initialize>b__3_0(bool val)
{
_listening = val;
}
internal void <Initialize>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<CustomMusicPlayer>();
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<PrefsManager>.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<string, string[]> DirectoryCache = new Dictionary<string, string[]>();
private static Dictionary<string, Color> DominantColorCache = new Dictionary<string, Color>();
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<string>(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<EndlessGrid>.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<Material>((object)(OutdoorLightMaster)Object.FindObjectsOfType(typeof(OutdoorLightMaster))[0], "skyboxMaterial");
Material mat2 = ReflectionUtils.GetPrivate<Material>((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<Material[]>((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<OutdoorLightMaster>.Instance;
if ((Object)(object)instance == (Object)null)
{
return;
}
foreach (Light item in (from light in ((Component)instance).gameObject.GetComponentsInChildren<Light>()
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<GameObject>(((Component)Object.FindObjectOfType<CustomTextures>()).gameObject).GetComponent<CustomTextures>();
Plugin.Log.LogInfo((object)"Duped CustomTextures");
}
}
}
internal static class UserHints
{
private static readonly Dictionary<string, string> 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("<color=#9ccaed>Cybergrind Slideshow</color>", "1. Default settings should work, but configuration and usage notes are in <color=#55c7f6>Options > Plugin Config > Cybergrind Slideshow</color>\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("<color=#9ccaed>Cybergrind Slideshow</color>", "Default settings should work, but configuration and usage notes are in <color=#55c7f6>Options > Plugin Config > Cybergrind Slideshow</color>", (Sprite)null, Path.Combine(Plugin.workingDir, "icon.png"), (Urgency)1, "CybergrindSlideshow", 0u, (Dictionary<string, string>)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<string, string>
{
{ "yes", "Yes" },
{ "no", "No" },
{ "remind", "Remind me later" }
};
SceneManager.sceneLoaded += OnSceneLoaded;
}
}
public static class VolumetricSkyboxHelper
{
public static void UnloadAllVolumetricSkyboxes()
{
VolumetricSkyboxesManager instance = MonoSingleton<VolumetricSkyboxesManager>.Instance;
if ((Object)(object)instance == (Object)null)
{
return;
}
Dictionary<string, VolumetricSkyboxContainer> dictionary = ReflectionUtils.GetPrivate<Dictionary<string, VolumetricSkyboxContainer>>((object)instance, "_skyboxes");
if (dictionary == null)
{
return;
}
Dictionary<string, VolumetricSkyboxContainer>.KeyCollection keyCollection = dictionary?.Keys;
if (keyCollection == null)
{
return;
}
foreach (string item in new List<string>(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<PrefsManager>.Instance.GetBoolLocal("cyberGrind.volumetricSkyboxes.useSkyboxesGridTextures", true) ? 1 : 0);
if (num != 0)
{
MonoSingleton<PrefsManager>.Instance.SetBoolLocal("cyberGrind.volumetricSkyboxes.useSkyboxesGridTextures", false);
}
}
VolumetricSkyboxesManager instance = MonoSingleton<VolumetricSkyboxesManager>.Instance;
if ((Object)(object)instance != (Object)null)
{
instance.AddSkybox(guid);
}
if (num != 0)
{
MonoSingleton<PrefsManager>.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;
}
}
}