Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Snow Menu v1.1.2
Snow.dll
Decompiled 4 months agousing System; 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 BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.SceneManagement; [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: AssemblyCompany("Omniscye")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("Snow")] [assembly: AssemblyTitle("Snow")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace Omniscye.SnowEverywhere { [BepInPlugin("Omniscye.SnowEverywhere", "SnowEverywhere", "1.4.1")] public class SnowEverywhere : BaseUnityPlugin { private sealed class SnowController : MonoBehaviour { internal struct Settings { public bool Enabled; public float FlakesPerSecond; public float FallSpeed; public float FlakeSize; public float WindX; public float WindZ; public float SpawnBoxHalfExtent; public int MaxParticles; public bool StickToCamera; public bool UseUnscaledTime; } private ParticleSystem _ps = null; private EmissionModule _emission; private MainModule _main; private ShapeModule _shape; private VelocityOverLifetimeModule _vel; private ParticleSystemRenderer _rend = null; private Camera? _cam; private Settings _settings; private float _targetLifetime; private bool _manualSimulateFallback = false; public void Initialize(Settings s, Texture2D? customTexture) { _settings = s; BuildParticleSystem(customTexture); RefreshForScene(); if (s.Enabled) { Enable(); } else { Disable(); } } public void RefreshForScene() { //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) _cam = Camera.main; if ((Object)(object)_cam == (Object)null) { Camera[] array = Object.FindObjectsOfType<Camera>(); Camera[] array2 = array; foreach (Camera val in array2) { if ((Object)(object)val != (Object)null && ((Behaviour)val).enabled) { _cam = val; break; } } } if (_settings.StickToCamera && (Object)(object)_cam != (Object)null) { Vector3 position = ((Component)_cam).transform.position; position.y += 15f; ((Component)this).transform.position = position; } } private void LateUpdate() { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) if (_settings.StickToCamera && (Object)(object)_cam != (Object)null) { Vector3 position = ((Component)_cam).transform.position; position.y += 15f; ((Component)this).transform.position = position; } if (!_settings.Enabled || (Object)(object)_ps == (Object)null) { return; } if (_manualSimulateFallback) { float num = (_settings.UseUnscaledTime ? Time.unscaledDeltaTime : Time.deltaTime); if (_ps.isPlaying) { _ps.Pause(false); } _ps.Simulate(num, false, false, false); } else if (_ps.isStopped || _ps.isPaused) { _ps.Play(); } } private void BuildParticleSystem(Texture2D? customTexture) { //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Expected O, but got Unknown //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_01fd: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_0225: Unknown result type (might be due to invalid IL or missing references) //IL_0237: Unknown result type (might be due to invalid IL or missing references) //IL_023c: Unknown result type (might be due to invalid IL or missing references) //IL_0288: Unknown result type (might be due to invalid IL or missing references) //IL_0299: Unknown result type (might be due to invalid IL or missing references) //IL_02ab: Unknown result type (might be due to invalid IL or missing references) //IL_02b0: Unknown result type (might be due to invalid IL or missing references) //IL_02e0: Unknown result type (might be due to invalid IL or missing references) //IL_02fd: Unknown result type (might be due to invalid IL or missing references) //IL_0319: Unknown result type (might be due to invalid IL or missing references) _ps = ((Component)this).gameObject.AddComponent<ParticleSystem>(); _rend = ((Component)_ps).GetComponent<ParticleSystemRenderer>(); _rend.alignment = (ParticleSystemRenderSpace)0; _rend.renderMode = (ParticleSystemRenderMode)0; Shader val = Shader.Find("Particles/Standard Unlit"); if ((Object)(object)val == (Object)null) { val = Shader.Find("Legacy Shaders/Particles/Alpha Blended"); } Material val2 = new Material(val); ((Object)val2).name = "Snow_Menu_Material"; val2.color = Color.white; if ((Object)(object)customTexture != (Object)null) { val2.mainTexture = (Texture)(object)customTexture; } val2.SetFloat("_Mode", 2f); val2.EnableKeyword("_ALPHABLEND_ON"); val2.DisableKeyword("_ALPHATEST_ON"); val2.DisableKeyword("_ALPHAPREMULTIPLY_ON"); val2.SetInt("_ZWrite", 0); val2.SetInt("_SrcBlend", 5); val2.SetInt("_DstBlend", 10); val2.renderQueue = 3000; ((Renderer)_rend).material = val2; ((Renderer)_rend).sortingOrder = 32767; TrySetAlwaysSimulate(_ps, _rend); _main = _ps.main; ((MainModule)(ref _main)).loop = true; ((MainModule)(ref _main)).startColor = MinMaxGradient.op_Implicit(Color.white); ((MainModule)(ref _main)).startSize = MinMaxCurve.op_Implicit(_settings.FlakeSize); _targetLifetime = Mathf.Max(6f, 25f / Mathf.Max(0.05f, _settings.FallSpeed)); ((MainModule)(ref _main)).startLifetime = MinMaxCurve.op_Implicit(_targetLifetime); ((MainModule)(ref _main)).startSpeed = MinMaxCurve.op_Implicit(0f); ((MainModule)(ref _main)).maxParticles = _settings.MaxParticles; ((MainModule)(ref _main)).simulationSpace = (ParticleSystemSimulationSpace)1; _emission = _ps.emission; ((EmissionModule)(ref _emission)).enabled = true; ((EmissionModule)(ref _emission)).rateOverTime = MinMaxCurve.op_Implicit(_settings.FlakesPerSecond); _shape = _ps.shape; ((ShapeModule)(ref _shape)).enabled = true; ((ShapeModule)(ref _shape)).shapeType = (ParticleSystemShapeType)5; ((ShapeModule)(ref _shape)).scale = new Vector3(_settings.SpawnBoxHalfExtent * 2f, 2f, _settings.SpawnBoxHalfExtent * 2f); ((ShapeModule)(ref _shape)).position = Vector3.zero; _vel = _ps.velocityOverLifetime; ((VelocityOverLifetimeModule)(ref _vel)).enabled = true; ((VelocityOverLifetimeModule)(ref _vel)).space = (ParticleSystemSimulationSpace)1; ((VelocityOverLifetimeModule)(ref _vel)).x = MinMaxCurve.op_Implicit(_settings.WindX); ((VelocityOverLifetimeModule)(ref _vel)).y = MinMaxCurve.op_Implicit(0f - _settings.FallSpeed); ((VelocityOverLifetimeModule)(ref _vel)).z = MinMaxCurve.op_Implicit(_settings.WindZ); _ps.Play(); } private void TrySetAlwaysSimulate(ParticleSystem ps, ParticleSystemRenderer rend) { if ((Object)(object)rend != (Object)null) { ((Renderer)rend).allowOcclusionWhenDynamic = false; } PropertyInfo property = typeof(ParticleSystem).GetProperty("cullingMode", BindingFlags.Instance | BindingFlags.Public); if (property != null) { Type propertyType = property.PropertyType; object value; try { value = Enum.Parse(propertyType, "AlwaysSimulate"); } catch { value = Enum.ToObject(propertyType, 2); } try { property.SetValue(ps, value, null); _manualSimulateFallback = false; return; } catch { } } _manualSimulateFallback = true; } public void Enable() { _settings.Enabled = true; if ((Object)(object)_ps == (Object)null) { return; } if (_manualSimulateFallback) { if (_ps.isPlaying) { _ps.Pause(false); } } else { _ps.Play(); } } public void Disable() { _settings.Enabled = false; if (!((Object)(object)_ps == (Object)null)) { _ps.Pause(); } } public void SetEmissionRate(float r) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) _settings.FlakesPerSecond = Mathf.Max(0f, r); ((EmissionModule)(ref _emission)).rateOverTime = MinMaxCurve.op_Implicit(_settings.FlakesPerSecond); RecalculateRecommendedMaxParticles(); } public void SetFallSpeed(float s) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) _settings.FallSpeed = Mathf.Max(0.01f, s); ((VelocityOverLifetimeModule)(ref _vel)).y = MinMaxCurve.op_Implicit(0f - _settings.FallSpeed); _targetLifetime = Mathf.Max(6f, 25f / _settings.FallSpeed); ((MainModule)(ref _main)).startLifetime = MinMaxCurve.op_Implicit(_targetLifetime); RecalculateRecommendedMaxParticles(); } public void SetFlakeSize(float s) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) _settings.FlakeSize = Mathf.Clamp(s, 0.005f, 0.25f); ((MainModule)(ref _main)).startSize = MinMaxCurve.op_Implicit(_settings.FlakeSize); } public void SetWind(float x, float z) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) _settings.WindX = x; _settings.WindZ = z; ((VelocityOverLifetimeModule)(ref _vel)).x = MinMaxCurve.op_Implicit(x); ((VelocityOverLifetimeModule)(ref _vel)).z = MinMaxCurve.op_Implicit(z); } public void SetSpawnBox(float halfExtent) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) _settings.SpawnBoxHalfExtent = Mathf.Clamp(halfExtent, 5f, 200f); ((ShapeModule)(ref _shape)).scale = new Vector3(_settings.SpawnBoxHalfExtent * 2f, 2f, _settings.SpawnBoxHalfExtent * 2f); } public void SetMaxParticles(int max) { _settings.MaxParticles = Mathf.Clamp(max, 200, 50000); ((MainModule)(ref _main)).maxParticles = _settings.MaxParticles; } public void SetStickToCamera(bool stick) { _settings.StickToCamera = stick; } public void SetUseUnscaledTime(bool useUnscaled) { _settings.UseUnscaledTime = useUnscaled; } private void RecalculateRecommendedMaxParticles() { int num = Mathf.CeilToInt(_settings.FlakesPerSecond * _targetLifetime * 1.2f); if (num > _settings.MaxParticles) { _settings.MaxParticles = num; ((MainModule)(ref _main)).maxParticles = _settings.MaxParticles; } } } public const string PluginGuid = "Omniscye.SnowEverywhere"; public const string PluginName = "SnowEverywhere"; public const string PluginVersion = "1.4.1"; private ConfigEntry<bool> _enabled = null; private ConfigEntry<float> _flakesPerSecond = null; private ConfigEntry<float> _fallSpeed = null; private ConfigEntry<float> _flakeSize = null; private ConfigEntry<float> _windX = null; private ConfigEntry<float> _windZ = null; private ConfigEntry<float> _spawnBoxHalfExtent = null; private ConfigEntry<int> _maxParticles = null; private ConfigEntry<bool> _stickToCamera = null; private ConfigEntry<bool> _useUnscaledTime = null; private ConfigEntry<bool> _onlyInMenuLobby = null; private ConfigEntry<bool> _useCustomTexture = null; private ConfigEntry<string> _customTextureName = null; private SnowController? _controller; private float _filterPollTimer; private bool _lastAllowed; private bool _loggedSemiFuncNotReady; private Texture2D? _snowTex; internal static SnowEverywhere Instance { get; private set; } internal static ManualLogSource Logger => Instance._logger; private ManualLogSource _logger => ((BaseUnityPlugin)this).Logger; internal Harmony? Harmony { get; set; } private void Awake() { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Expected O, but got Unknown //IL_004a: Expected O, but got Unknown Instance = this; ((Component)this).transform.parent = null; ((Object)this).hideFlags = (HideFlags)61; BindConfig(); if (Harmony == null) { Harmony val = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID); Harmony val2 = val; Harmony = val; } Harmony.PatchAll(); TryLoadSnowTexture(); EnsureController(); SceneManager.sceneLoaded += OnSceneLoaded; ApplyMenuFilter(initial: true); Logger.LogInfo((object)$"{((BaseUnityPlugin)this).Info.Metadata.GUID} v{((BaseUnityPlugin)this).Info.Metadata.Version} loaded — menu/lobby-gated snowfall with custom texture support."); } private void OnDestroy() { SceneManager.sceneLoaded -= OnSceneLoaded; Harmony? harmony = Harmony; if (harmony != null) { harmony.UnpatchSelf(); } } private void Update() { _filterPollTimer -= (_useUnscaledTime.Value ? Time.unscaledDeltaTime : Time.deltaTime); if (_filterPollTimer <= 0f) { _filterPollTimer = 0.5f; ApplyMenuFilter(initial: false); } } private void OnSceneLoaded(Scene scene, LoadSceneMode mode) { if ((Object)(object)_controller == (Object)null) { EnsureController(); } _controller.RefreshForScene(); ApplyMenuFilter(initial: true); Logger.LogDebug((object)("Snow refreshed for scene '" + ((Scene)(ref scene)).name + "'.")); } private void BindConfig() { _enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Master toggle for snowfall."); _flakesPerSecond = ((BaseUnityPlugin)this).Config.Bind<float>("Snow", "FlakesPerSecond", 150f, "Emission rate (flakes/second)."); _fallSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Snow", "FallSpeed", 0.8f, "Downward speed in m/s. Lower = slower."); _flakeSize = ((BaseUnityPlugin)this).Config.Bind<float>("Snow", "FlakeSize", 0.06f, "Base particle size in meters."); _windX = ((BaseUnityPlugin)this).Config.Bind<float>("Snow", "WindX", 0.15f, "Horizontal drift X."); _windZ = ((BaseUnityPlugin)this).Config.Bind<float>("Snow", "WindZ", -0.05f, "Horizontal drift Z."); _spawnBoxHalfExtent = ((BaseUnityPlugin)this).Config.Bind<float>("Snow", "SpawnBoxHalfExtent", 25f, "Half-extent of spawn box (XZ)."); _maxParticles = ((BaseUnityPlugin)this).Config.Bind<int>("Performance", "MaxParticles", 8000, "Max live particles (raise if rate×lifetime is high)."); _stickToCamera = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "StickToCamera", true, "Anchor emitter to active camera."); _useUnscaledTime = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "UseUnscaledTime", true, "Use unscaled time so menus/slowmo don’t freeze snow."); _onlyInMenuLobby = ((BaseUnityPlugin)this).Config.Bind<bool>("Scenes", "OnlyInMenuLobby", true, "If true, snow runs only when SemiFunc.MenuLevel() is true."); _useCustomTexture = ((BaseUnityPlugin)this).Config.Bind<bool>("Visual", "UseCustomTexture", true, "If true, tries to load a PNG beside the DLL and use it for flake texture."); _customTextureName = ((BaseUnityPlugin)this).Config.Bind<string>("Visual", "CustomTextureName", "snow.png", "File name of the texture next to the plugin DLL."); } private void EnsureController() { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown if (!((Object)(object)_controller != (Object)null)) { GameObject val = new GameObject("SnowEverywhere_Controller"); Object.DontDestroyOnLoad((Object)(object)val); ((Object)val).hideFlags = (HideFlags)61; _controller = val.AddComponent<SnowController>(); _controller.Initialize(new SnowController.Settings { Enabled = _enabled.Value, FlakesPerSecond = _flakesPerSecond.Value, FallSpeed = _fallSpeed.Value, FlakeSize = _flakeSize.Value, WindX = _windX.Value, WindZ = _windZ.Value, SpawnBoxHalfExtent = _spawnBoxHalfExtent.Value, MaxParticles = _maxParticles.Value, StickToCamera = _stickToCamera.Value, UseUnscaledTime = _useUnscaledTime.Value }, _snowTex); _enabled.SettingChanged += delegate { ApplyMenuFilter(initial: false); }; _flakesPerSecond.SettingChanged += delegate { _controller.SetEmissionRate(_flakesPerSecond.Value); }; _fallSpeed.SettingChanged += delegate { _controller.SetFallSpeed(_fallSpeed.Value); }; _flakeSize.SettingChanged += delegate { _controller.SetFlakeSize(_flakeSize.Value); }; _windX.SettingChanged += delegate { _controller.SetWind(_windX.Value, _windZ.Value); }; _windZ.SettingChanged += delegate { _controller.SetWind(_windX.Value, _windZ.Value); }; _spawnBoxHalfExtent.SettingChanged += delegate { _controller.SetSpawnBox(_spawnBoxHalfExtent.Value); }; _maxParticles.SettingChanged += delegate { _controller.SetMaxParticles(_maxParticles.Value); }; _stickToCamera.SettingChanged += delegate { _controller.SetStickToCamera(_stickToCamera.Value); }; _useUnscaledTime.SettingChanged += delegate { _controller.SetUseUnscaledTime(_useUnscaledTime.Value); }; } } private void ApplyMenuFilter(bool initial) { if ((Object)(object)_controller == (Object)null) { return; } if (!_enabled.Value) { _controller.Disable(); return; } bool flag = true; if (_onlyInMenuLobby.Value) { flag = IsMenuOrLobbyActiveSafe(); } if (initial || flag != _lastAllowed) { _lastAllowed = flag; if (flag) { _controller.Enable(); Logger.LogDebug((object)"Snow: ENABLE (menu level detected)."); } else { _controller.Disable(); Logger.LogDebug((object)"Snow: DISABLE (not a menu level)."); } } } private bool IsMenuOrLobbyActiveSafe() { try { return SemiFunc.MenuLevel(); } catch (Exception ex) { if (!_loggedSemiFuncNotReady) { _loggedSemiFuncNotReady = true; Logger.LogDebug((object)("Snow: SemiFunc.MenuLevel() not ready yet (" + ex.GetType().Name + "). Will retry.")); } return false; } } private void TryLoadSnowTexture() { //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Expected O, but got Unknown _snowTex = null; if (!_useCustomTexture.Value) { return; } try { string path = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location) ?? ""; string text = Path.Combine(path, _customTextureName.Value); if (!File.Exists(text)) { Logger.LogDebug((object)("Snow: custom texture not found at '" + text + "'. Using default white material.")); return; } byte[] array = File.ReadAllBytes(text); Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false, false); if (!ImageConversion.LoadImage(val, array, false)) { Logger.LogWarning((object)"Snow: failed to load snow texture (LoadImage returned false)."); Object.Destroy((Object)(object)val); return; } ((Object)val).name = "Snow_Menu_Texture"; ((Texture)val).wrapMode = (TextureWrapMode)1; ((Texture)val).filterMode = (FilterMode)1; _snowTex = val; Logger.LogInfo((object)$"Snow: loaded custom flake texture '{_customTextureName.Value}' ({((Texture)val).width}x{((Texture)val).height})."); } catch (Exception ex) { Logger.LogWarning((object)("Snow: error loading custom texture: " + ex.GetType().Name + ": " + ex.Message)); _snowTex = null; } } } }