Decompiled source of Moonfall v1.0.0

plugin/Moonfall.dll

Decompiled 15 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using System.Text.Json;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using Microsoft.CodeAnalysis;
using Mirror;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.Rendering;
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(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("Moonfall")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("Moonfall")]
[assembly: AssemblyTitle("Moonfall")]
[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.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Moonfall
{
	internal class GlbResult
	{
		public Mesh[] Meshes;

		public float[] MinAngles;

		public byte[] ImageBytes;

		public string ImageExt = ".png";

		public byte[] NormalBytes;

		public string NormalExt = ".png";

		public float NormalScale = 1f;

		public Color Tint = Color.white;
	}
	internal static class GlbLoader
	{
		public static GlbResult Load(string path)
		{
			byte[] array = File.ReadAllBytes(path);
			if (array.Length < 20 || BitConverter.ToUInt32(array, 0) != 1179937895)
			{
				throw new Exception("Not a .glb file: " + path);
			}
			string text = null;
			byte[] array2 = null;
			int num = 12;
			while (num + 8 <= array.Length)
			{
				int num2 = BitConverter.ToInt32(array, num);
				uint num3 = BitConverter.ToUInt32(array, num + 4);
				int num4 = num + 8;
				switch (num3)
				{
				case 1313821514u:
					text = Encoding.UTF8.GetString(array, num4, num2);
					break;
				case 5130562u:
					if (array2 == null)
					{
						array2 = new byte[num2];
						Buffer.BlockCopy(array, num4, array2, 0, num2);
					}
					break;
				}
				num = num4 + num2;
			}
			if (text == null)
			{
				throw new Exception("GLB has no JSON chunk");
			}
			if (array2 == null)
			{
				array2 = new byte[0];
			}
			using JsonDocument jsonDocument = JsonDocument.Parse(text);
			return Build(jsonDocument.RootElement, array2, Path.GetDirectoryName(path));
		}

		private static GlbResult Build(JsonElement root, byte[] bin, string dir)
		{
			//IL_0324: Unknown result type (might be due to invalid IL or missing references)
			//IL_0329: Unknown result type (might be due to invalid IL or missing references)
			//IL_032d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0332: Unknown result type (might be due to invalid IL or missing references)
			//IL_033a: Unknown result type (might be due to invalid IL or missing references)
			//IL_033f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0344: Unknown result type (might be due to invalid IL or missing references)
			//IL_0349: Unknown result type (might be due to invalid IL or missing references)
			//IL_034b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0350: Unknown result type (might be due to invalid IL or missing references)
			//IL_0355: Unknown result type (might be due to invalid IL or missing references)
			//IL_035a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0373: Unknown result type (might be due to invalid IL or missing references)
			//IL_0375: Unknown result type (might be due to invalid IL or missing references)
			//IL_0377: Unknown result type (might be due to invalid IL or missing references)
			//IL_0381: Unknown result type (might be due to invalid IL or missing references)
			//IL_0386: Unknown result type (might be due to invalid IL or missing references)
			//IL_0388: Unknown result type (might be due to invalid IL or missing references)
			//IL_038a: Unknown result type (might be due to invalid IL or missing references)
			//IL_038c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0396: Unknown result type (might be due to invalid IL or missing references)
			//IL_039b: Unknown result type (might be due to invalid IL or missing references)
			//IL_039d: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
			List<Vector3> list = new List<Vector3>();
			List<Vector3> list2 = new List<Vector3>();
			List<Vector2> list3 = new List<Vector2>();
			List<int> list4 = new List<int>();
			bool hasNormals = true;
			int num = -1;
			foreach (JsonElement item in root.GetProperty("meshes").EnumerateArray())
			{
				foreach (JsonElement item2 in item.GetProperty("primitives").EnumerateArray())
				{
					JsonElement value;
					int num2 = (item2.TryGetProperty("mode", out value) ? value.GetInt32() : 4);
					if (num2 != 4)
					{
						continue;
					}
					JsonElement property = item2.GetProperty("attributes");
					float[] array = ReadVec(root, bin, property.GetProperty("POSITION").GetInt32(), 3);
					int num3 = array.Length / 3;
					int count = list.Count;
					float[] array2 = null;
					if (property.TryGetProperty("NORMAL", out var value2))
					{
						array2 = ReadVec(root, bin, value2.GetInt32(), 3);
					}
					else
					{
						hasNormals = false;
					}
					float[] array3 = null;
					if (property.TryGetProperty("TEXCOORD_0", out var value3))
					{
						array3 = ReadVec(root, bin, value3.GetInt32(), 2);
					}
					for (int i = 0; i < num3; i++)
					{
						list.Add(new Vector3(0f - array[i * 3], array[i * 3 + 1], array[i * 3 + 2]));
						if (array2 != null)
						{
							list2.Add(new Vector3(0f - array2[i * 3], array2[i * 3 + 1], array2[i * 3 + 2]));
						}
						else
						{
							list2.Add(Vector3.up);
						}
						if (array3 != null)
						{
							list3.Add(new Vector2(array3[i * 2], 1f - array3[i * 2 + 1]));
						}
						else
						{
							list3.Add(Vector2.zero);
						}
					}
					int[] array4;
					if (item2.TryGetProperty("indices", out var value4))
					{
						array4 = ReadIndices(root, bin, value4.GetInt32());
					}
					else
					{
						array4 = new int[num3];
						for (int j = 0; j < num3; j++)
						{
							array4[j] = j;
						}
					}
					for (int k = 0; k + 2 < array4.Length; k += 3)
					{
						list4.Add(count + array4[k]);
						list4.Add(count + array4[k + 2]);
						list4.Add(count + array4[k + 1]);
					}
					if (num < 0 && item2.TryGetProperty("material", out var value5))
					{
						num = value5.GetInt32();
					}
				}
			}
			if (list.Count == 0 || list4.Count == 0)
			{
				throw new Exception("GLB contained no triangle mesh");
			}
			Vector3 val = list[0];
			Vector3 val2 = list[0];
			for (int l = 1; l < list.Count; l++)
			{
				val = Vector3.Min(val, list[l]);
				val2 = Vector3.Max(val2, list[l]);
			}
			Vector3 val3 = (val + val2) * 0.5f;
			Vector3 val4 = (val2 - val) * 0.5f;
			float num4 = Mathf.Max(val4.x, Mathf.Max(val4.y, val4.z));
			if (num4 < 1E-06f)
			{
				num4 = 1f;
			}
			float num5 = 1f / num4;
			for (int m = 0; m < list.Count; m++)
			{
				list[m] = (list[m] - val3) * num5;
			}
			List<Mesh> list5 = new List<Mesh>();
			List<float> list6 = new List<float>();
			int num6 = list4.Count / 3;
			list5.Add(MakeMesh(list, list2, list3, list4, hasNormals, "Moonfall_LOD0"));
			list6.Add(22f);
			if (num6 > 3000)
			{
				Mesh val5 = Decimate(list, list2, list3, list4, hasNormals, 48, "Moonfall_LOD1", num6);
				if ((Object)(object)val5 != (Object)null)
				{
					list5.Add(val5);
					list6.Add(6f);
				}
				Mesh val6 = Decimate(list, list2, list3, list4, hasNormals, 20, "Moonfall_LOD2", num6);
				if ((Object)(object)val6 != (Object)null)
				{
					list5.Add(val6);
					list6.Add(0f);
				}
			}
			list6[list6.Count - 1] = 0f;
			GlbResult glbResult = new GlbResult
			{
				Meshes = list5.ToArray(),
				MinAngles = list6.ToArray()
			};
			try
			{
				LoadImages(root, bin, dir, num, glbResult);
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Moon textures failed, using plain color: " + ex.Message));
			}
			Plugin.Log.LogInfo((object)("Moon mesh: " + list.Count + " verts, " + num6 + " tris, " + list5.Count + " LOD(s)."));
			return glbResult;
		}

		private static Mesh MakeMesh(List<Vector3> v, List<Vector3> n, List<Vector2> uv, List<int> t, bool hasNormals, string name)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			Mesh val = new Mesh();
			((Object)val).name = name;
			val.indexFormat = (IndexFormat)(v.Count > 65535);
			val.vertices = Il2CppStructArray<Vector3>.op_Implicit(v.ToArray());
			val.uv = Il2CppStructArray<Vector2>.op_Implicit(uv.ToArray());
			val.triangles = Il2CppStructArray<int>.op_Implicit(t.ToArray());
			if (hasNormals)
			{
				val.normals = Il2CppStructArray<Vector3>.op_Implicit(n.ToArray());
			}
			else
			{
				val.RecalculateNormals();
			}
			val.RecalculateTangents();
			val.RecalculateBounds();
			((Object)val).hideFlags = (HideFlags)61;
			return val;
		}

		private static Mesh Decimate(List<Vector3> v, List<Vector3> n, List<Vector2> uv, List<int> t, bool hasNormals, int grid, string name, int origTris)
		{
			//IL_0044: 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)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: 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_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			float num = 2f / (float)grid;
			Dictionary<long, int> dictionary = new Dictionary<long, int>();
			int[] array = new int[v.Count];
			List<Vector3> list = new List<Vector3>();
			List<Vector3> list2 = new List<Vector3>();
			List<Vector2> list3 = new List<Vector2>();
			List<int> list4 = new List<int>();
			for (int i = 0; i < v.Count; i++)
			{
				Vector3 val = v[i];
				long num2 = Mathf.FloorToInt((val.x + 1f) / num);
				long num3 = Mathf.FloorToInt((val.y + 1f) / num);
				long num4 = Mathf.FloorToInt((val.z + 1f) / num);
				long key = (num2 << 40) | (num3 << 20) | num4;
				if (!dictionary.TryGetValue(key, out var value))
				{
					value = (dictionary[key] = list.Count);
					list.Add(val);
					list2.Add(n[i]);
					list3.Add(uv[i]);
					list4.Add(1);
				}
				else
				{
					List<Vector3> list5 = list;
					int index = value;
					list5[index] += val;
					list5 = list2;
					index = value;
					list5[index] += n[i];
					list4[value]++;
				}
				array[i] = value;
			}
			for (int j = 0; j < list.Count; j++)
			{
				List<Vector3> list5 = list;
				int index2 = j;
				list5[index2] /= (float)list4[j];
				int index3 = j;
				Vector3 val2 = list2[j];
				list2[index3] = ((Vector3)(ref val2)).normalized;
			}
			List<int> list6 = new List<int>(t.Count / 2);
			for (int k = 0; k + 2 < t.Count; k += 3)
			{
				int num5 = array[t[k]];
				int num6 = array[t[k + 1]];
				int num7 = array[t[k + 2]];
				if (num5 != num6 && num6 != num7 && num5 != num7)
				{
					list6.Add(num5);
					list6.Add(num6);
					list6.Add(num7);
				}
			}
			int num8 = list6.Count / 3;
			if (num8 < 8 || (float)num8 > (float)origTris * 0.6f)
			{
				return null;
			}
			return MakeMesh(list, list2, list3, list6, hasNormals, name);
		}

		private static void LoadImages(JsonElement root, byte[] bin, string dir, int matIndex, GlbResult res)
		{
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			if (matIndex < 0 || !root.TryGetProperty("materials", out var value))
			{
				return;
			}
			JsonElement jsonElement = value[matIndex];
			if (jsonElement.TryGetProperty("pbrMetallicRoughness", out var value2))
			{
				if (value2.TryGetProperty("baseColorFactor", out var value3) && value3.GetArrayLength() >= 4)
				{
					res.Tint = new Color(value3[0].GetSingle(), value3[1].GetSingle(), value3[2].GetSingle(), value3[3].GetSingle());
				}
				if (value2.TryGetProperty("baseColorTexture", out var value4))
				{
					res.ImageBytes = ReadImage(root, bin, dir, value4.GetProperty("index").GetInt32(), out res.ImageExt);
				}
			}
			if (jsonElement.TryGetProperty("normalTexture", out var value5))
			{
				res.NormalBytes = ReadImage(root, bin, dir, value5.GetProperty("index").GetInt32(), out res.NormalExt);
				if (value5.TryGetProperty("scale", out var value6))
				{
					res.NormalScale = value6.GetSingle();
				}
			}
		}

		private static byte[] ReadImage(JsonElement root, byte[] bin, string dir, int texIdx, out string ext)
		{
			ext = ".png";
			int @int = root.GetProperty("textures")[texIdx].GetProperty("source").GetInt32();
			JsonElement jsonElement = root.GetProperty("images")[@int];
			if (jsonElement.TryGetProperty("mimeType", out var value) && value.GetString().IndexOf("jpeg", StringComparison.OrdinalIgnoreCase) >= 0)
			{
				ext = ".jpg";
			}
			if (jsonElement.TryGetProperty("bufferView", out var value2))
			{
				JsonElement jsonElement2 = root.GetProperty("bufferViews")[value2.GetInt32()];
				JsonElement value3;
				int srcOffset = (jsonElement2.TryGetProperty("byteOffset", out value3) ? value3.GetInt32() : 0);
				int int2 = jsonElement2.GetProperty("byteLength").GetInt32();
				byte[] array = new byte[int2];
				Buffer.BlockCopy(bin, srcOffset, array, 0, int2);
				return array;
			}
			if (jsonElement.TryGetProperty("uri", out var value4))
			{
				string text = value4.GetString();
				if (text.StartsWith("data:", StringComparison.OrdinalIgnoreCase))
				{
					return Convert.FromBase64String(text.Substring(text.IndexOf(',') + 1));
				}
				string path = Path.Combine(dir, Uri.UnescapeDataString(text));
				if (File.Exists(path))
				{
					return File.ReadAllBytes(path);
				}
			}
			return null;
		}

		private static float[] ReadVec(JsonElement root, byte[] bin, int accIndex, int comps)
		{
			JsonElement jsonElement = root.GetProperty("accessors")[accIndex];
			int @int = jsonElement.GetProperty("count").GetInt32();
			int int2 = jsonElement.GetProperty("componentType").GetInt32();
			JsonElement value;
			bool norm = jsonElement.TryGetProperty("normalized", out value) && value.GetBoolean();
			JsonElement value2;
			int num = (jsonElement.TryGetProperty("byteOffset", out value2) ? value2.GetInt32() : 0);
			float[] array = new float[@int * comps];
			if (!jsonElement.TryGetProperty("bufferView", out var value3))
			{
				return array;
			}
			JsonElement jsonElement2 = root.GetProperty("bufferViews")[value3.GetInt32()];
			JsonElement value4;
			int num2 = (jsonElement2.TryGetProperty("byteOffset", out value4) ? value4.GetInt32() : 0);
			int num3 = CompSize(int2);
			int num4 = num3 * comps;
			if (jsonElement2.TryGetProperty("byteStride", out var value5) && value5.GetInt32() > 0)
			{
				num4 = value5.GetInt32();
			}
			for (int i = 0; i < @int; i++)
			{
				for (int j = 0; j < comps; j++)
				{
					array[i * comps + j] = ReadComp(bin, num2 + num + i * num4 + j * num3, int2, norm);
				}
			}
			return array;
		}

		private static int[] ReadIndices(JsonElement root, byte[] bin, int accIndex)
		{
			JsonElement jsonElement = root.GetProperty("accessors")[accIndex];
			int @int = jsonElement.GetProperty("count").GetInt32();
			int int2 = jsonElement.GetProperty("componentType").GetInt32();
			JsonElement value;
			int num = (jsonElement.TryGetProperty("byteOffset", out value) ? value.GetInt32() : 0);
			JsonElement value2;
			int num2 = (root.GetProperty("bufferViews")[jsonElement.GetProperty("bufferView").GetInt32()].TryGetProperty("byteOffset", out value2) ? value2.GetInt32() : 0);
			int num3 = CompSize(int2);
			int[] array = new int[@int];
			for (int i = 0; i < @int; i++)
			{
				int num4 = num2 + num + i * num3;
				switch (int2)
				{
				case 5121:
					array[i] = bin[num4];
					break;
				case 5123:
					array[i] = BitConverter.ToUInt16(bin, num4);
					break;
				default:
					array[i] = (int)BitConverter.ToUInt32(bin, num4);
					break;
				}
			}
			return array;
		}

		private static int CompSize(int ctype)
		{
			switch (ctype)
			{
			case 5120:
			case 5121:
				return 1;
			case 5122:
			case 5123:
				return 2;
			default:
				return 4;
			}
		}

		private static float ReadComp(byte[] b, int o, int ctype, bool norm)
		{
			switch (ctype)
			{
			case 5126:
				return BitConverter.ToSingle(b, o);
			case 5120:
			{
				sbyte b2 = (sbyte)b[o];
				return norm ? Mathf.Max((float)b2 / 127f, -1f) : ((float)b2);
			}
			case 5121:
				return norm ? ((float)(int)b[o] / 255f) : ((float)(int)b[o]);
			case 5122:
			{
				short num2 = BitConverter.ToInt16(b, o);
				return norm ? Mathf.Max((float)num2 / 32767f, -1f) : ((float)num2);
			}
			case 5123:
			{
				ushort num = BitConverter.ToUInt16(b, o);
				return norm ? ((float)(int)num / 65535f) : ((float)(int)num);
			}
			default:
				return BitConverter.ToUInt32(b, o);
			}
		}
	}
	public class MoonManager : MonoBehaviour
	{
		private sealed class PendingReq
		{
			public UnityWebRequest Req;

			public Action<UnityWebRequest> Done;

			public string What;
		}

		private sealed class Warn
		{
			public string Name;

			public double Sec;

			public AudioClip Clip;

			public bool Fired;
		}

		private sealed class ImageJob
		{
			public Task<DecodedImage> Work;

			public Action<Texture2D> Done;

			public string What;
		}

		private GameObject _moon;

		private Transform _moonT;

		private MeshFilter _mf;

		private Material _moonMat;

		private Mesh[] _lods;

		private float[] _lodMin;

		private int _lodIdx = -1;

		private int[] _tintIds = new int[0];

		private int[] _emisIds = new int[0];

		private Color _baseTint = Color.white;

		private Texture2D _gameOver;

		private Texture2D _vignette;

		private bool _assetsTried;

		private bool _inputError;

		private readonly List<PendingReq> _pending = new List<PendingReq>();

		private GameObject _lightGo;

		private MoonVfx _vfx;

		private Light _light;

		private GameObject _audioGo;

		private AudioSource _src;

		private AudioClip _crashClip;

		private AudioClip _diedClip;

		private readonly List<Warn> _warns = new List<Warn>();

		private double _prevRem = double.NaN;

		private bool _crashPlayed;

		private bool _diedPlayed;

		private MoonNet _net;

		private bool _netHave;

		private bool _usingNet;

		private bool _netRestart;

		private bool _netErr;

		private DateTime _netStart;

		private string _lastStartStr = "__init__";

		private bool _hasStart;

		private DateTime _start;

		private float _p;

		private float _sinceEnd = -1f;

		private double _remainingReal;

		private double _remainingScaled;

		private double _total = 21600.0;

		private double _scale = 1.0;

		private float _danger;

		private float _panic;

		private const float ExitAtSinceEnd = 19.5f;

		private bool _exiting;

		private bool _knockedDown;

		private int _exitStage;

		private float _exitT;

		private string _sceneAtExit;

		private float _doom;

		private bool _haveCam;

		private readonly MoonSession _session = new MoonSession();

		private float _crashHour;

		private bool _timeSet;

		private bool _timeForced;

		private float _nextTimeTick;

		private Camera _shakeCam;

		private Quaternion _shakeApplied = Quaternion.identity;

		private Quaternion _shakeAfter = Quaternion.identity;

		private GUIStyle _style;

		private GUIStyle _bigStyle;

		private static readonly string[] ColorProps = new string[3] { "_BaseColor", "_Color", "_UnlitColor" };

		private static readonly string[] EmisProps = new string[2] { "_EmissionColor", "_EmissiveColor" };

		private static readonly string[] TexProps = new string[4] { "_BaseMap", "_MainTex", "_UnlitColorMap", "_BaseColorMap" };

		private static readonly string[] NormalProps = new string[2] { "_BumpMap", "_NormalMap" };

		private static readonly Regex WarnRx = new Regex("^\\s*(\\d+(?:\\.\\d+)?)\\s*[-_ ]?\\s*(hours?|hrs?|h|minutes?|mins?|m|seconds?|secs?|s)\\b.*warning", RegexOptions.IgnoreCase);

		private readonly List<ImageJob> _imgJobs = new List<ImageJob>();

		public MoonManager(IntPtr ptr)
			: base(ptr)
		{
		}//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_008f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0094: Unknown result type (might be due to invalid IL or missing references)
		//IL_009a: Unknown result type (might be due to invalid IL or missing references)
		//IL_009f: Unknown result type (might be due to invalid IL or missing references)


		private void Update()
		{
			try
			{
				if (_session.Update())
				{
					OnLeftLobby();
				}
				HandleKeys();
				UpdateClock();
				CheckExit();
				UpdateTime();
				NetStep();
				if (_hasStart)
				{
					EnsureAssets();
				}
				PollRequests();
				PollImageJobs();
				UpdateAudio();
				UpdateImpact();
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)ex);
			}
		}

		private void LateUpdate()
		{
			try
			{
				if (!_hasStart)
				{
					UndoShake();
					MoonSky.Set(null, 0f, 0f, _light);
					if ((Object)(object)_moon != (Object)null && _moon.activeSelf)
					{
						_moon.SetActive(false);
					}
					if ((Object)(object)_light != (Object)null)
					{
						((Behaviour)_light).enabled = false;
					}
					if (_vfx != null)
					{
						_vfx.Hide();
					}
					_danger = 0f;
					_panic = 0f;
					_doom = 0f;
					return;
				}
				_danger = Mathf.SmoothStep(0f, 1f, Mathf.Clamp01((_p - 0.5f) * 2f));
				float num = Mathf.Max(1f, Plugin.DoomMinutes.Value * 60f);
				float num2 = Mathf.Max(1f, Plugin.DoomRampSeconds.Value);
				float num3 = (float)_remainingReal;
				_doom = Mathf.SmoothStep(0f, 1f, Mathf.Clamp01((num - num3) / num2));
				_panic = Mathf.SmoothStep(0f, 1f, Mathf.Clamp01((60f - num3) / 60f));
				if (_sinceEnd >= 0f)
				{
					_danger = 1f;
					_doom = 1f;
					_panic = 1f;
				}
				Camera cam = GetCam();
				_haveCam = (Object)(object)cam != (Object)null;
				if ((Object)(object)cam == (Object)null)
				{
					MoonSky.Set(null, 0f, 0f, _light);
					UndoShake();
					if ((Object)(object)_moon != (Object)null && _moon.activeSelf)
					{
						_moon.SetActive(false);
					}
					if ((Object)(object)_light != (Object)null)
					{
						((Behaviour)_light).enabled = false;
					}
					if (_vfx != null)
					{
						_vfx.Hide();
					}
				}
				else
				{
					UpdateMoon(cam);
					MoonSky.Set(cam, Plugin.DoomRedSky.Value ? _doom : 0f, _panic, _light);
					if (Plugin.CameraShake.Value)
					{
						ApplyShake(cam);
					}
					else
					{
						UndoShake();
					}
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)ex);
			}
		}

		private void HandleKeys()
		{
			try
			{
				if (!Input.GetKey((KeyCode)304) && !Input.GetKey((KeyCode)303))
				{
					return;
				}
				if (_netHave && Plugin.NetEnabled.Value && IsRemoteClient())
				{
					if (Input.GetKeyDown((KeyCode)291) || Input.GetKeyDown((KeyCode)292))
					{
						Plugin.Log.LogInfo((object)"Only the host can start or reset the moon while you're joined to a game.");
					}
					return;
				}
				if (Input.GetKeyDown((KeyCode)291))
				{
					string text = DateTime.UtcNow.ToString("o", CultureInfo.InvariantCulture);
					Plugin.StartUtc.Value = text;
					GUIUtility.systemCopyBuffer = text;
					Plugin.Log.LogInfo((object)("Moon countdown started. Give every player this StartUtc: " + text));
				}
				if (Input.GetKeyDown((KeyCode)292))
				{
					Plugin.StartUtc.Value = "";
					Plugin.Log.LogInfo((object)"Moon reset.");
				}
			}
			catch (Exception ex)
			{
				if (!_inputError)
				{
					_inputError = true;
					Plugin.Log.LogWarning((object)("Hotkeys unavailable (" + ex.Message + "). Set StartUtc in the config file instead."));
				}
			}
		}

		private void BeginSession()
		{
			_exiting = false;
			_exitStage = 0;
			_knockedDown = false;
			_timeSet = false;
			_prevRem = double.NaN;
			_crashPlayed = false;
			_diedPlayed = false;
			for (int i = 0; i < _warns.Count; i++)
			{
				_warns[i].Fired = false;
			}
		}

		private static bool IsRemoteClient()
		{
			try
			{
				return NetworkClient.active && !NetworkServer.active;
			}
			catch
			{
				return false;
			}
		}

		private void UpdateClock()
		{
			if (!IsRemoteClient())
			{
				_netHave = false;
			}
			if (_netHave && Plugin.NetEnabled.Value)
			{
				if (!_usingNet)
				{
					_usingNet = true;
					BeginSession();
				}
				if (_netRestart)
				{
					_netRestart = false;
					BeginSession();
				}
				_start = _netStart;
				_hasStart = true;
			}
			else
			{
				if (_usingNet)
				{
					_usingNet = false;
					_hasStart = false;
					_lastStartStr = "__init__";
				}
				string value = Plugin.StartUtc.Value;
				if (value != _lastStartStr)
				{
					_lastStartStr = value;
					_total = Math.Max(10.0, (double)Plugin.Hours.Value * 3600.0);
					_scale = Math.Max(0.01, Plugin.TimeScale.Value);
					_crashHour = Plugin.CrashHour.Value;
					BeginSession();
					_hasStart = DateTime.TryParse(value, CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal | DateTimeStyles.AssumeUniversal, out _start);
				}
			}
			if (!_hasStart)
			{
				_p = 0f;
				_sinceEnd = -1f;
				return;
			}
			double scale = _scale;
			double total = _total;
			double num = Math.Max(0.0, (DateTime.UtcNow - _start).TotalSeconds) * scale;
			_p = Mathf.Clamp01((float)(num / total));
			_remainingScaled = total - num;
			_remainingReal = _remainingScaled / scale;
			_sinceEnd = ((num >= total) ? ((float)((num - total) / scale)) : (-1f));
		}

		private void OnLeftLobby()
		{
			bool flag = _hasStart || _netHave || _timeForced || _doom > 0f;
			_netHave = false;
			if (!string.IsNullOrEmpty(Plugin.StartUtc.Value))
			{
				Plugin.StartUtc.Value = "";
			}
			if (flag)
			{
				Plugin.Log.LogInfo((object)"Moonfall: left the lobby, countdown cleared.");
			}
		}

		private void UpdateTime()
		{
			if (!Plugin.TimeSteer.Value || !_hasStart)
			{
				if (_timeForced && MoonTime.Release())
				{
					_timeForced = false;
				}
			}
			else
			{
				if (_timeSet || _doom <= 0f)
				{
					return;
				}
				float unscaledTime = Time.unscaledTime;
				if (!(unscaledTime < _nextTimeTick))
				{
					_nextTimeTick = unscaledTime + 0.5f;
					if (MoonTime.Force(_crashHour))
					{
						_timeSet = true;
						_timeForced = true;
						Plugin.Log.LogInfo((object)("Moonfall: clock set to " + _crashHour.ToString("0.0") + "h for the final phase."));
					}
				}
			}
		}

		private void NetStep()
		{
			try
			{
				if (Plugin.NetEnabled.Value)
				{
					if (_net == null)
					{
						_net = new MoonNet();
						_net.OnState += ApplyNetState;
					}
					_net.Tick();
					if (NetworkServer.active)
					{
						_net.HostSync(_hasStart, (DateTime.UtcNow - _start).TotalSeconds, (float)(_total / 3600.0), (float)_scale, _crashHour);
					}
					else if (NetworkClient.active)
					{
						_net.ClientHello();
					}
					else
					{
						_net.Idle();
					}
				}
			}
			catch (Exception ex)
			{
				if (!_netErr)
				{
					_netErr = true;
					Plugin.Log.LogError((object)("Moonfall network sync failed (timer stays local): " + ex));
				}
			}
		}

		private void ApplyNetState(MoonNet.State st)
		{
			if (!Plugin.NetEnabled.Value || !IsRemoteClient())
			{
				return;
			}
			if (!st.Running)
			{
				if (_netHave)
				{
					Plugin.Log.LogInfo((object)"Moonfall: host reset the countdown.");
				}
				_netHave = false;
				return;
			}
			DateTime dateTime = DateTime.UtcNow - TimeSpan.FromSeconds(st.ElapsedReal);
			double num = (_netHave ? Math.Abs((dateTime - _netStart).TotalSeconds) : 0.0);
			if (!_netHave || num > 2.0)
			{
				_netStart = dateTime;
				_total = Math.Max(10.0, (double)st.Hours * 3600.0);
				_scale = Math.Max(0.01, st.TimeScale);
				_crashHour = st.CrashHour;
				_netHave = true;
				_netRestart = true;
				Plugin.Log.LogInfo((object)"Moonfall: synced to the host's timer.");
			}
			else if (num > 0.5)
			{
				_netStart = dateTime;
			}
		}

		private void CheckExit()
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			if (!_hasStart)
			{
				return;
			}
			Scene activeScene;
			if (!_exiting)
			{
				if (!(_sinceEnd < 19.5f))
				{
					_exiting = true;
					_exitStage = 1;
					_exitT = Time.unscaledTime;
					activeScene = SceneManager.GetActiveScene();
					_sceneAtExit = ((Scene)(ref activeScene)).name;
					Plugin.Log.LogInfo((object)"Moonfall: game over finished, leaving to main menu.");
					LeaveSession();
				}
				return;
			}
			float num = Time.unscaledTime - _exitT;
			if (_exitStage == 1 && num > 4f)
			{
				_exitStage = 2;
				activeScene = SceneManager.GetActiveScene();
				if (((Scene)(ref activeScene)).name == _sceneAtExit)
				{
					Plugin.Log.LogInfo((object)"Moonfall: scene unchanged, loading scene 0.");
					SceneManager.LoadScene(0);
				}
			}
			else if (_exitStage == 2 && num > 6f)
			{
				_exitStage = 3;
				Plugin.StartUtc.Value = "";
				Plugin.Log.LogInfo((object)"Moonfall: reset, StartUtc cleared.");
			}
		}

		private static void LeaveSession()
		{
			try
			{
				NetworkManager singleton = NetworkManager.singleton;
				if (!((Object)(object)singleton == (Object)null))
				{
					if (NetworkServer.active && NetworkClient.isConnected)
					{
						singleton.StopHost();
					}
					else if (NetworkClient.isConnected || NetworkClient.active)
					{
						singleton.StopClient();
					}
					else if (NetworkServer.active)
					{
						singleton.StopServer();
					}
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("LeaveSession failed: " + ex));
			}
		}

		private Camera GetCam()
		{
			Camera main = Camera.main;
			if ((Object)(object)main != (Object)null && ((Behaviour)main).enabled)
			{
				return main;
			}
			foreach (Camera item in (Il2CppArrayBase<Camera>)(object)Camera.allCameras)
			{
				if ((Object)(object)item != (Object)null && ((Behaviour)item).enabled && (Object)(object)item.targetTexture == (Object)null)
				{
					return item;
				}
			}
			return null;
		}

		private void UpdateMoon(Camera cam)
		{
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: 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_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_031d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0336: Unknown result type (might be due to invalid IL or missing references)
			//IL_0341: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0303: Unknown result type (might be due to invalid IL or missing references)
			//IL_0308: Unknown result type (might be due to invalid IL or missing references)
			//IL_030a: Unknown result type (might be due to invalid IL or missing references)
			//IL_030f: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_moon == (Object)null)
			{
				return;
			}
			if (!_moon.activeSelf)
			{
				_moon.SetActive(true);
			}
			float num = Mathf.Pow(_p, Mathf.Max(0.1f, Plugin.GrowthCurve.Value));
			float num2 = Mathf.Lerp(Plugin.MinAngle.Value, Plugin.MaxAngle.Value, num);
			float num3 = Mathf.Min(Plugin.MoonDistance.Value, cam.farClipPlane * 0.85f);
			float num4 = num3 * Mathf.Tan(num2 * 0.5f * ((float)Math.PI / 180f));
			float num5 = Mathf.Lerp(Plugin.ElevStart.Value, Plugin.ElevEnd.Value, num);
			Vector3 val = Quaternion.Euler(0f - num5, Plugin.Azimuth.Value, 0f) * Vector3.forward;
			_moonT.position = ((Component)cam).transform.position + val * num3;
			_moonT.rotation = Quaternion.LookRotation(-val, Vector3.up) * Quaternion.Euler(Plugin.ModelPitch.Value, Plugin.ModelYaw.Value, Plugin.ModelRoll.Value);
			_moonT.localScale = Vector3.one * num4;
			if (_vfx != null)
			{
				_vfx.Tick(_moonT.position, val, num4, _p, _sinceEnd >= 0f, _doom, cam);
			}
			int num6 = _lods.Length - 1;
			for (int i = 0; i < _lods.Length; i++)
			{
				if (num2 >= _lodMin[i])
				{
					num6 = i;
					break;
				}
			}
			if (num6 != _lodIdx)
			{
				_lodIdx = num6;
				_mf.sharedMesh = _lods[num6];
			}
			if ((Object)(object)_light != (Object)null)
			{
				((Behaviour)_light).enabled = true;
				float num7 = Mathf.SmoothStep(0f, 1f, Mathf.Clamp01((num2 - 4f) / 30f));
				_light.intensity = Plugin.MoonLightIntensity.Value * num7 * ((_vfx != null) ? _vfx.Flicker : 1f);
				_light.color = Color.Lerp(new Color(0.85f, 0.9f, 1f, 1f), new Color(1f, 0.35f, 0.2f, 1f), _danger);
				_lightGo.transform.rotation = Quaternion.LookRotation(Quaternion.Euler(15f, Plugin.MoonLightAngle.Value, 0f) * val);
			}
			SetTint(Color.Lerp(_baseTint, new Color(1f, 0.45f, 0.3f, 1f), _danger));
		}

		private void SetTint(Color c)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_moonMat == (Object)null)
			{
				return;
			}
			for (int i = 0; i < _tintIds.Length; i++)
			{
				_moonMat.SetColor(_tintIds[i], c);
			}
			if (_emisIds.Length != 0)
			{
				Color val = Color.Lerp(Color.white, new Color(1f, 0.4f, 0.25f, 1f), _danger) * Plugin.MoonGlow.Value;
				for (int j = 0; j < _emisIds.Length; j++)
				{
					_moonMat.SetColor(_emisIds[j], val);
				}
			}
		}

		private void ApplyShake(Camera cam)
		{
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: 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_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			UndoShake();
			if (_sinceEnd > 3.2f)
			{
				return;
			}
			float num;
			if (_sinceEnd >= 0f)
			{
				num = 4f + _sinceEnd * 2f;
			}
			else
			{
				if (_doom <= 0f)
				{
					return;
				}
				double num2 = Mathf.Lerp(20f, 12f, _doom);
				double num3 = 4.0;
				double num4 = (DateTime.UtcNow - _start).TotalSeconds % num2;
				float num5 = ((num4 < num3) ? ((1f - (float)(num4 / num3)) * (0.5f + 1.8f * _doom)) : 0f);
				num = _doom * _doom * 0.3f + num5 + _panic * _panic * 1.5f;
			}
			if (!(num < 0.01f))
			{
				float num6 = Time.time * 18f;
				Quaternion val = Quaternion.Euler((Mathf.PerlinNoise(num6, 0.1f) - 0.5f) * 2f * num, (Mathf.PerlinNoise(num6, 7.3f) - 0.5f) * 2f * num, (Mathf.PerlinNoise(num6, 13.7f) - 0.5f) * num);
				Transform transform = ((Component)cam).transform;
				transform.rotation *= val;
				_shakeCam = cam;
				_shakeApplied = val;
				_shakeAfter = transform.rotation;
			}
		}

		private void UndoShake()
		{
			//IL_0020: 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_003d: 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_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_shakeCam == (Object)null))
			{
				Transform transform = ((Component)_shakeCam).transform;
				if (Quaternion.Angle(transform.rotation, _shakeAfter) < 5E-05f)
				{
					transform.rotation *= Quaternion.Inverse(_shakeApplied);
				}
				_shakeCam = null;
			}
		}

		private void UpdateAudio()
		{
			if (!_hasStart)
			{
				return;
			}
			if (!double.IsNaN(_prevRem))
			{
				for (int i = 0; i < _warns.Count; i++)
				{
					Warn warn = _warns[i];
					if (!warn.Fired && _prevRem > warn.Sec && _remainingScaled <= warn.Sec)
					{
						warn.Fired = true;
						Play(warn.Clip);
					}
				}
			}
			_prevRem = _remainingScaled;
			if (!_crashPlayed && _sinceEnd >= 0f && _sinceEnd < 5f)
			{
				_crashPlayed = true;
				Play(_crashClip);
			}
			if (!_diedPlayed && _sinceEnd >= 4.5f && _sinceEnd < 10f)
			{
				_diedPlayed = true;
				Play(_diedClip);
			}
		}

		private void UpdateImpact()
		{
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			float value = Plugin.KnockdownLead.Value;
			if (_hasStart && !_knockedDown && !(_remainingReal > (double)value))
			{
				_knockedDown = true;
				if (Plugin.ImpactKnockdown.Value && !((double)value - _remainingReal > 6.0))
				{
					Vector3 awayHorizontal = -(Quaternion.Euler(0f, Plugin.Azimuth.Value, 0f) * Vector3.forward);
					MoonPlayer.Knockdown(awayHorizontal, Plugin.KnockdownForce.Value);
				}
			}
		}

		private void Play(AudioClip c)
		{
			if ((Object)(object)c == (Object)null || (Object)(object)_src == (Object)null)
			{
				return;
			}
			try
			{
				_src.PlayOneShot(c, Plugin.AudioVolume.Value);
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("Audio play failed: " + ex.Message));
			}
		}

		private void LoadAudioFolder(string moonDir)
		{
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Unknown result type (might be due to invalid IL or missing references)
			string text = null;
			try
			{
				if (moonDir != null && Directory.Exists(Path.Combine(moonDir, "audio")))
				{
					text = Path.Combine(moonDir, "audio");
				}
				else
				{
					string[] directories = Directory.GetDirectories(Paths.PluginPath, "audio", SearchOption.AllDirectories);
					if (directories.Length != 0)
					{
						text = directories[0];
					}
				}
			}
			catch
			{
			}
			if (text == null)
			{
				Plugin.Log.LogInfo((object)"No 'audio' folder found (create one next to moon.glb).");
				return;
			}
			string[] files = Directory.GetFiles(text);
			foreach (string path in files)
			{
				AudioType type;
				switch (Path.GetExtension(path).ToLowerInvariant())
				{
				case ".mp3":
					type = (AudioType)13;
					break;
				case ".ogg":
					type = (AudioType)14;
					break;
				case ".wav":
					type = (AudioType)20;
					break;
				default:
					continue;
				}
				string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(path);
				string text2 = fileNameWithoutExtension.ToLowerInvariant().Replace(" ", "").Replace("_", "")
					.Replace("-", "");
				if (TryParseWarning(fileNameWithoutExtension, out var sec))
				{
					string n = fileNameWithoutExtension;
					double s = sec;
					RequestAudio(path, type, delegate(AudioClip c)
					{
						_warns.Add(new Warn
						{
							Name = n,
							Sec = s,
							Clip = c
						});
					});
					Plugin.Log.LogInfo((object)("Audio: '" + fileNameWithoutExtension + "' plays at " + sec + "s remaining."));
				}
				else if (text2.Contains("crash"))
				{
					RequestAudio(path, type, delegate(AudioClip c)
					{
						_crashClip = c;
					});
					Plugin.Log.LogInfo((object)("Audio: '" + fileNameWithoutExtension + "' plays at impact."));
				}
				else if (text2.Contains("youdied") || text2 == "died")
				{
					RequestAudio(path, type, delegate(AudioClip c)
					{
						_diedClip = c;
					});
					Plugin.Log.LogInfo((object)("Audio: '" + fileNameWithoutExtension + "' plays with the YOU DIED screen."));
				}
				else
				{
					Plugin.Log.LogInfo((object)("Audio: ignored '" + fileNameWithoutExtension + "' (name not recognized)."));
				}
			}
		}

		private static bool TryParseWarning(string name, out double sec)
		{
			sec = 0.0;
			Match match = WarnRx.Match(name);
			if (!match.Success)
			{
				return false;
			}
			double num = double.Parse(match.Groups[1].Value, CultureInfo.InvariantCulture);
			sec = char.ToLowerInvariant(match.Groups[2].Value[0]) switch
			{
				'm' => num * 60.0, 
				'h' => num * 3600.0, 
				_ => num, 
			};
			return true;
		}

		private void EnsureAssets()
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Expected O, but got Unknown
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Expected O, but got Unknown
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Expected O, but got Unknown
			if (_assetsTried)
			{
				return;
			}
			_assetsTried = true;
			try
			{
				_vignette = MakeVignette();
				_audioGo = new GameObject("Moonfall_Audio");
				((Object)_audioGo).hideFlags = (HideFlags)61;
				Object.DontDestroyOnLoad((Object)(object)_audioGo);
				_src = _audioGo.AddComponent<AudioSource>();
				_src.playOnAwake = false;
				_src.spatialBlend = 0f;
				string text = FindFile("moon.glb");
				if (text == null)
				{
					Plugin.Log.LogError((object)"moon.glb not found anywhere under BepInEx/plugins");
				}
				else
				{
					GlbResult glbResult = GlbLoader.Load(text);
					_baseTint = glbResult.Tint;
					_lods = glbResult.Meshes;
					_lodMin = glbResult.MinAngles;
					_moonMat = BuildMaterial();
					_moon = new GameObject("Moonfall_Moon");
					((Object)_moon).hideFlags = (HideFlags)61;
					Object.DontDestroyOnLoad((Object)(object)_moon);
					_moonT = _moon.transform;
					_mf = _moon.AddComponent<MeshFilter>();
					_mf.sharedMesh = _lods[_lods.Length - 1];
					MeshRenderer val = _moon.AddComponent<MeshRenderer>();
					((Renderer)val).sharedMaterial = _moonMat;
					((Renderer)val).shadowCastingMode = (ShadowCastingMode)0;
					((Renderer)val).receiveShadows = false;
					_lightGo = new GameObject("Moonfall_Light");
					((Object)_lightGo).hideFlags = (HideFlags)61;
					Object.DontDestroyOnLoad((Object)(object)_lightGo);
					_light = _lightGo.AddComponent<Light>();
					_light.type = (LightType)1;
					_light.shadows = (LightShadows)0;
					_light.intensity = 0f;
					if (Plugin.VfxEnabled.Value)
					{
						_vfx = new MoonVfx();
						_vfx.Create();
					}
					if (glbResult.ImageBytes != null)
					{
						byte[] ib = glbResult.ImageBytes;
						LoadTexture(() => ib, "moon texture", SetMoonTexture);
					}
					if (glbResult.NormalBytes != null)
					{
						byte[] nb = glbResult.NormalBytes;
						float sc = glbResult.NormalScale;
						LoadTexture(() => nb, "moon normal map", delegate(Texture2D t)
						{
							SetMoonNormal(t, sc);
						});
					}
				}
				string png = FindFile("youdiedgameover.png");
				if (png == null)
				{
					Plugin.Log.LogError((object)"youdiedgameover.png not found anywhere under BepInEx/plugins");
				}
				else
				{
					LoadTexture(() => File.ReadAllBytes(png), "youdiedgameover.png", delegate(Texture2D t)
					{
						_gameOver = t;
					});
				}
				LoadAudioFolder((text != null) ? Path.GetDirectoryName(text) : null);
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)ex);
			}
		}

		private void Request(UnityWebRequest req, string what, Action<UnityWebRequest> done)
		{
			req.SendWebRequest();
			_pending.Add(new PendingReq
			{
				Req = req,
				Done = done,
				What = what
			});
		}

		private void LoadTexture(Func<byte[]> getBytes, string what, Action<Texture2D> done)
		{
			try
			{
				int max = Math.Max(64, Plugin.MaxTextureSize.Value);
				Task<DecodedImage> work = Task.Run(() => PngDecoder.Decode(getBytes(), max));
				_imgJobs.Add(new ImageJob
				{
					Work = work,
					Done = done,
					What = what
				});
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("Texture job failed for " + what + ": " + ex));
			}
		}

		private void PollImageJobs()
		{
			for (int num = _imgJobs.Count - 1; num >= 0; num--)
			{
				ImageJob imageJob = _imgJobs[num];
				if (imageJob.Work.IsCompleted)
				{
					_imgJobs.RemoveAt(num);
					try
					{
						if (imageJob.Work.IsFaulted)
						{
							Plugin.Log.LogError((object)("Decode failed for " + imageJob.What + ": " + imageJob.Work.Exception.GetBaseException().Message));
						}
						else
						{
							Texture2D val = UploadRgba(imageJob.Work.Result, imageJob.What);
							if (!((Object)(object)val == (Object)null))
							{
								((Object)val).hideFlags = (HideFlags)61;
								((Texture)val).filterMode = (FilterMode)2;
								((Texture)val).anisoLevel = 8;
								imageJob.Done(val);
							}
						}
					}
					catch (Exception ex)
					{
						Plugin.Log.LogError((object)ex);
					}
				}
			}
		}

		private static Texture2D UploadRgba(DecodedImage img, string what)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Expected O, but got Unknown
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Expected O, but got Unknown
			//IL_021b: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(img.W, img.H, (TextureFormat)4, true);
			Il2CppStructArray<byte> arg = Il2CppStructArray<byte>.op_Implicit(img.Chain);
			if (InvokeOn(val, "LoadRawTextureData", arg))
			{
				val.Apply();
				Plugin.Log.LogInfo((object)("Texture '" + what + "' uploaded (" + img.W + "x" + img.H + ")."));
				return val;
			}
			int num = img.W * img.H;
			byte[] rgba = img.Rgba;
			Il2CppStructArray<Color> val2 = new Il2CppStructArray<Color>((long)num);
			for (int i = 0; i < num; i++)
			{
				((Il2CppArrayBase<Color>)(object)val2)[i] = new Color((float)(int)rgba[i * 4] / 255f, (float)(int)rgba[i * 4 + 1] / 255f, (float)(int)rgba[i * 4 + 2] / 255f, (float)(int)rgba[i * 4 + 3] / 255f);
			}
			if (InvokeOn(val, "SetPixels", val2))
			{
				val.Apply();
				Plugin.Log.LogInfo((object)("Texture '" + what + "' uploaded via SetPixels (" + img.W + "x" + img.H + ")."));
				return val;
			}
			Object.Destroy((Object)(object)val);
			DecodedImage decodedImage = PngDecoder.Shrink(img, 512);
			Texture2D val3 = new Texture2D(decodedImage.W, decodedImage.H, (TextureFormat)4, true);
			byte[] rgba2 = decodedImage.Rgba;
			for (int j = 0; j < decodedImage.H; j++)
			{
				for (int k = 0; k < decodedImage.W; k++)
				{
					int num2 = (j * decodedImage.W + k) * 4;
					val3.SetPixel(k, j, new Color((float)(int)rgba2[num2] / 255f, (float)(int)rgba2[num2 + 1] / 255f, (float)(int)rgba2[num2 + 2] / 255f, (float)(int)rgba2[num2 + 3] / 255f));
				}
			}
			val3.Apply();
			Plugin.Log.LogWarning((object)("Texture '" + what + "' uploaded per-pixel at " + decodedImage.W + "x" + decodedImage.H + " (fast paths unavailable)."));
			return val3;
		}

		private static bool InvokeOn(object target, string name, object arg)
		{
			try
			{
				MethodInfo[] methods = target.GetType().GetMethods();
				foreach (MethodInfo methodInfo in methods)
				{
					if (!(methodInfo.Name != name))
					{
						ParameterInfo[] parameters = methodInfo.GetParameters();
						if (parameters.Length == 1 && parameters[0].ParameterType.IsInstanceOfType(arg))
						{
							methodInfo.Invoke(target, new object[1] { arg });
							return true;
						}
					}
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)(name + " failed: " + (ex.InnerException ?? ex).Message));
			}
			return false;
		}

		private void RequestAudio(string path, AudioType type, Action<AudioClip> done)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				UnityWebRequest audioClip = UnityWebRequestMultimedia.GetAudioClip(new Uri(path).AbsoluteUri, type);
				Request(audioClip, path, delegate(UnityWebRequest r)
				{
					AudioClip content = DownloadHandlerAudioClip.GetContent(r);
					if (!((Object)(object)content == (Object)null))
					{
						((Object)content).hideFlags = (HideFlags)61;
						done(content);
					}
				});
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("Audio request failed for " + path + ": " + ex));
			}
		}

		private void PollRequests()
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Invalid comparison between Unknown and I4
			for (int num = _pending.Count - 1; num >= 0; num--)
			{
				PendingReq pendingReq = _pending[num];
				try
				{
					if (pendingReq.Req.isDone)
					{
						_pending.RemoveAt(num);
						if ((int)pendingReq.Req.result == 1)
						{
							pendingReq.Done(pendingReq.Req);
						}
						else
						{
							Plugin.Log.LogError((object)("Load failed for " + pendingReq.What + ": " + pendingReq.Req.error));
						}
						pendingReq.Req.Dispose();
					}
				}
				catch (Exception ex)
				{
					_pending.Remove(pendingReq);
					Plugin.Log.LogError((object)ex);
				}
			}
		}

		private void SetMoonTexture(Texture2D tex)
		{
			if ((Object)(object)_moonMat == (Object)null)
			{
				return;
			}
			string[] texProps = TexProps;
			foreach (string text in texProps)
			{
				if (_moonMat.HasProperty(text))
				{
					_moonMat.SetTexture(text, (Texture)(object)tex);
				}
			}
			if (_moonMat.HasProperty("_EmissionMap"))
			{
				_moonMat.SetTexture("_EmissionMap", (Texture)(object)tex);
			}
			Plugin.Log.LogInfo((object)"Moon texture applied.");
		}

		private void SetMoonNormal(Texture2D tex, float scale)
		{
			if ((Object)(object)_moonMat == (Object)null)
			{
				return;
			}
			string[] normalProps = NormalProps;
			foreach (string text in normalProps)
			{
				if (_moonMat.HasProperty(text))
				{
					_moonMat.SetTexture(text, (Texture)(object)tex);
				}
			}
			_moonMat.EnableKeyword("_NORMALMAP");
			if (_moonMat.HasProperty("_BumpScale"))
			{
				_moonMat.SetFloat("_BumpScale", scale);
			}
			Plugin.Log.LogInfo((object)"Moon normal map applied.");
		}

		private static string FindFile(string name)
		{
			try
			{
				string[] files = Directory.GetFiles(Paths.PluginPath, name, SearchOption.AllDirectories);
				if (files.Length != 0)
				{
					return files[0];
				}
			}
			catch
			{
			}
			return null;
		}

		private Material BuildMaterial()
		{
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Expected O, but got Unknown
			string[] array = new string[7] { "Universal Render Pipeline/Lit", "HDRP/Lit", "Standard", "Universal Render Pipeline/Unlit", "HDRP/Unlit", "Unlit/Texture", "Sprites/Default" };
			Shader val = null;
			string[] array2 = array;
			foreach (string text in array2)
			{
				val = Shader.Find(text);
				if ((Object)(object)val != (Object)null)
				{
					Plugin.Log.LogInfo((object)("Moon shader: " + text));
					break;
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				throw new Exception("No usable shader found for the moon");
			}
			Material val2 = new Material(val);
			((Object)val2).hideFlags = (HideFlags)61;
			List<int> list = new List<int>();
			string[] colorProps = ColorProps;
			foreach (string text2 in colorProps)
			{
				if (val2.HasProperty(text2))
				{
					list.Add(Shader.PropertyToID(text2));
				}
			}
			_tintIds = list.ToArray();
			List<int> list2 = new List<int>();
			string[] emisProps = EmisProps;
			foreach (string text3 in emisProps)
			{
				if (val2.HasProperty(text3))
				{
					list2.Add(Shader.PropertyToID(text3));
				}
			}
			_emisIds = list2.ToArray();
			if (val2.HasProperty("_Smoothness"))
			{
				val2.SetFloat("_Smoothness", 0f);
			}
			if (val2.HasProperty("_Glossiness"))
			{
				val2.SetFloat("_Glossiness", 0f);
			}
			if (val2.HasProperty("_Metallic"))
			{
				val2.SetFloat("_Metallic", 0f);
			}
			if (_emisIds.Length != 0)
			{
				val2.EnableKeyword("_EMISSION");
				val2.globalIlluminationFlags = (MaterialGlobalIlluminationFlags)1;
			}
			return val2;
		}

		private static Texture2D MakeVignette()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(64, 64, (TextureFormat)4, false);
			for (int i = 0; i < 64; i++)
			{
				for (int j = 0; j < 64; j++)
				{
					float num = ((float)j + 0.5f) / 64f * 2f - 1f;
					float num2 = ((float)i + 0.5f) / 64f * 2f - 1f;
					float num3 = Mathf.Sqrt(num * num + num2 * num2);
					float num4 = Mathf.Clamp01((num3 - 0.45f) / 0.75f);
					val.SetPixel(j, i, new Color(0.55f, 0f, 0f, num4 * num4));
				}
			}
			val.Apply();
			((Texture)val).wrapMode = (TextureWrapMode)1;
			((Object)val).hideFlags = (HideFlags)61;
			return val;
		}

		private void OnGUI()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Invalid comparison between Unknown and I4
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Expected O, but got Unknown
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Expected O, but got Unknown
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_022a: 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_021c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0275: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if ((int)Event.current.type != 7)
				{
					return;
				}
				float num = Screen.width;
				float num2 = Screen.height;
				Rect val = default(Rect);
				((Rect)(ref val))..ctor(0f, 0f, num, num2);
				if (_style == null)
				{
					_style = new GUIStyle(GUI.skin.label);
					_style.fontSize = 22;
					_style.fontStyle = (FontStyle)1;
					_style.alignment = (TextAnchor)1;
					_bigStyle = new GUIStyle(GUI.skin.label);
					_bigStyle.fontSize = 96;
					_bigStyle.fontStyle = (FontStyle)1;
					_bigStyle.alignment = (TextAnchor)4;
				}
				if (!_hasStart)
				{
					if (Plugin.ShowClock.Value && Time.realtimeSinceStartup < 30f)
					{
						GUI.color = Color.white;
						GUI.Label(new Rect(0f, 10f, num, 30f), "Moonfall idle - Shift+F10 starts the countdown", _style);
					}
					return;
				}
				float unscaledTime = Time.unscaledTime;
				if (_doom > 0f && _haveCam)
				{
					float num3 = 0.5f + 0.5f * Mathf.Sin(unscaledTime * (1.2f + 1.2f * _doom + 4f * _panic));
					GUI.color = new Color(0.5f, 0f, 0f, _doom * 0.18f + _panic * 0.12f * num3);
					GUI.DrawTexture(val, (Texture)(object)Texture2D.whiteTexture);
					if ((Object)(object)_vignette != (Object)null)
					{
						GUI.color = new Color(1f, 1f, 1f, Mathf.Clamp01(_doom * 0.85f + _panic * 0.3f * num3));
						GUI.DrawTexture(val, (Texture)(object)_vignette);
					}
					GUI.color = Color.white;
				}
				if (_sinceEnd < 0f && Plugin.ShowClock.Value)
				{
					DrawClock(num);
				}
				if (_sinceEnd >= 2.5f)
				{
					DrawEnding(val);
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)ex);
			}
		}

		private void DrawClock(float W)
		{
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			TimeSpan timeSpan = TimeSpan.FromSeconds(Math.Max(0.0, _remainingReal));
			string text = $"MOON IMPACT  {(int)timeSpan.TotalHours:00}:{timeSpan.Minutes:00}:{timeSpan.Seconds:00}";
			Rect val = default(Rect);
			((Rect)(ref val))..ctor(0f, 18f, W, 40f);
			GUI.color = new Color(0f, 0f, 0f, 0.8f);
			GUI.Label(new Rect(((Rect)(ref val)).x + 2f, ((Rect)(ref val)).y + 2f, ((Rect)(ref val)).width, ((Rect)(ref val)).height), text, _style);
			GUI.color = Color.Lerp(Color.white, new Color(1f, 0.2f, 0.1f, 1f), _danger);
			GUI.Label(val, text, _style);
			GUI.color = Color.white;
		}

		private void DrawEnding(Rect full)
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			float sinceEnd = _sinceEnd;
			if (sinceEnd < 3.2f)
			{
				GUI.color = new Color(1f, 1f, 1f, Mathf.Clamp01((sinceEnd - 2.5f) / 0.7f));
				GUI.DrawTexture(full, (Texture)(object)Texture2D.whiteTexture);
			}
			else
			{
				GUI.color = Color.black;
				GUI.DrawTexture(full, (Texture)(object)Texture2D.whiteTexture);
				float num = 1f - Mathf.Clamp01((sinceEnd - 3.2f) / 1f);
				if (num > 0f)
				{
					GUI.color = new Color(1f, 1f, 1f, num);
					GUI.DrawTexture(full, (Texture)(object)Texture2D.whiteTexture);
				}
				if (sinceEnd >= 4.5f)
				{
					float num2 = Mathf.Clamp01((sinceEnd - 4.5f) / 1.5f);
					if ((Object)(object)_gameOver != (Object)null)
					{
						GUI.color = new Color(1f, 1f, 1f, num2);
						GUI.DrawTexture(full, (Texture)(object)_gameOver, (ScaleMode)2, true);
					}
					else if (_pending.Count == 0 && _imgJobs.Count == 0)
					{
						GUI.color = new Color(0.8f, 0f, 0f, num2);
						GUI.Label(full, "YOU DIED", _bigStyle);
					}
				}
			}
			GUI.color = Color.white;
		}
	}
	internal sealed class MoonNet
	{
		public struct State
		{
			public bool Running;

			public double ElapsedReal;

			public float Hours;

			public float TimeScale;

			public float CrashHour;
		}

		private const ushort MsgId = 45479;

		private const ushort Protocol = 3;

		private const byte TypeHello = 1;

		private const byte TypeState = 2;

		private const byte TypeHelloAck = 3;

		private const int MaxPacket = 1024;

		private const float SendInterval = 5f;

		private readonly HashSet<int> _modded = new HashSet<int>();

		private readonly List<int> _pendingHello = new List<int>();

		private readonly HashSet<int> _alive = new HashSet<int>();

		private bool _lastRunning;

		private bool _helloSent;

		private bool _collisionWarned;

		private float _nextSend;

		private readonly Action<NetworkConnection, NetworkReader, int> _cbClient;

		private readonly Action<NetworkConnection, NetworkReader, int> _cbServer;

		private NetworkMessageDelegate _clientHandler;

		private NetworkMessageDelegate _serverHandler;

		public bool HostAcked { get; private set; }

		public event Action<State> OnState;

		public MoonNet()
		{
			_cbClient = OnClientMessage;
			_cbServer = OnServerMessage;
		}

		public void Tick()
		{
			if (NetworkClient.active)
			{
				EnsureHandler(NetworkClient.handlers, ref _clientHandler, _cbClient, "client");
			}
			if (NetworkServer.active)
			{
				EnsureHandler(NetworkServer.handlers, ref _serverHandler, _cbServer, "server");
			}
		}

		private void EnsureHandler(Dictionary<ushort, NetworkMessageDelegate> handlers, ref NetworkMessageDelegate mine, Action<NetworkConnection, NetworkReader, int> callback, string side)
		{
			if (handlers == null)
			{
				return;
			}
			if (handlers.ContainsKey((ushort)45479))
			{
				if ((Delegate)(object)mine == (Delegate)null && !_collisionWarned)
				{
					_collisionWarned = true;
					Plugin.Log.LogError((object)("MoonNet: Mirror message id " + ((ushort)45479).ToString("X4") + " is already used (" + side + "); network sync disabled."));
				}
			}
			else
			{
				if ((Delegate)(object)mine == (Delegate)null)
				{
					mine = DelegateSupport.ConvertDelegate<NetworkMessageDelegate>((Delegate)callback);
				}
				handlers.Add((ushort)45479, mine);
			}
		}

		public void HostSync(bool running, double elapsedReal, float hours, float scale, float crashHour)
		{
			if (!_collisionWarned)
			{
				float unscaledTime = Time.unscaledTime;
				bool flag = running != _lastRunning;
				_lastRunning = running;
				if (running && (flag || unscaledTime >= _nextSend))
				{
					SendToModded(MakeState(running: true, elapsedReal, hours, scale, crashHour), null);
					_nextSend = unscaledTime + 5f;
					_pendingHello.Clear();
				}
				else if (!running && flag)
				{
					SendToModded(MakeState(running: false, 0.0, hours, scale, crashHour), null);
					_pendingHello.Clear();
				}
				else if (running && _pendingHello.Count > 0)
				{
					SendToModded(MakeState(running: true, elapsedReal, hours, scale, crashHour), _pendingHello);
					_pendingHello.Clear();
				}
				else if (!running)
				{
					_pendingHello.Clear();
				}
			}
		}

		public void ClientHello()
		{
			if (!_collisionWarned && Plugin.NetAnnounce.Value)
			{
				if (!NetworkClient.active || !NetworkClient.isConnected || NetworkClient.connection == null)
				{
					_helloSent = false;
					HostAcked = false;
				}
				else if (!_helloSent)
				{
					_helloSent = true;
					byte[] array = new byte[3] { 1, 0, 0 };
					Buffer.BlockCopy(BitConverter.GetBytes((ushort)3), 0, array, 1, 2);
					NetworkWriter val = Frame(array);
					NetworkClient.connection.Send(val.ToArraySegment(), Channels.Reliable);
					Plugin.Log.LogInfo((object)"MoonNet: announced to host.");
				}
			}
		}

		public void Idle()
		{
			_helloSent = false;
			HostAcked = false;
			_lastRunning = false;
			_modded.Clear();
			_pendingHello.Clear();
		}

		private static byte[] MakeState(bool running, double elapsedReal, float hours, float scale, float crashHour)
		{
			byte[] array = new byte[22]
			{
				2,
				(byte)(running ? 1u : 0u),
				0,
				0,
				0,
				0,
				0,
				0,
				0,
				0,
				0,
				0,
				0,
				0,
				0,
				0,
				0,
				0,
				0,
				0,
				0,
				0
			};
			Buffer.BlockCopy(BitConverter.GetBytes(elapsedReal), 0, array, 2, 8);
			Buffer.BlockCopy(BitConverter.GetBytes(hours), 0, array, 10, 4);
			Buffer.BlockCopy(BitConverter.GetBytes(scale), 0, array, 14, 4);
			Buffer.BlockCopy(BitConverter.GetBytes(crashHour), 0, array, 18, 4);
			return array;
		}

		private static byte[] MakeAck()
		{
			byte[] array = new byte[3] { 3, 0, 0 };
			Buffer.BlockCopy(BitConverter.GetBytes((ushort)3), 0, array, 1, 2);
			return array;
		}

		private static NetworkWriter Frame(byte[] payload)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			NetworkWriter val = new NetworkWriter();
			NetworkWriterExtensions.WriteUShort(val, (ushort)45479);
			NetworkWriterExtensions.WriteInt(val, payload.Length);
			val.WriteBytes(Il2CppStructArray<byte>.op_Implicit(payload), 0, payload.Length);
			return val;
		}

		private static byte[] ReadPayload(NetworkReader r)
		{
			int num = NetworkReaderExtensions.ReadInt(r);
			if (num <= 0 || num > 1024 || num > r.Remaining)
			{
				return null;
			}
			Il2CppStructArray<byte> val = new Il2CppStructArray<byte>((long)num);
			r.ReadBytes(val, num);
			return Il2CppArrayBase<byte>.op_Implicit((Il2CppArrayBase<byte>)(object)val);
		}

		private void SendToModded(byte[] payload, List<int> only)
		{
			NetworkWriter val = Frame(payload);
			ArraySegment<byte> val2 = val.ToArraySegment();
			_alive.Clear();
			Enumerator<int, NetworkConnectionToClient> enumerator = NetworkServer.connections.GetEnumerator();
			while (enumerator.MoveNext())
			{
				KeyValuePair<int, NetworkConnectionToClient> current = enumerator.Current;
				NetworkConnectionToClient value = current.Value;
				if (value != null)
				{
					int connectionId = ((NetworkConnection)value).connectionId;
					_alive.Add(connectionId);
					if (connectionId != 0 && _modded.Contains(connectionId) && (only == null || only.Contains(connectionId)))
					{
						((NetworkConnection)value).Send(val2, Channels.Reliable);
					}
				}
			}
			_modded.IntersectWith(_alive);
		}

		private void OnClientMessage(NetworkConnection conn, NetworkReader reader, int channelId)
		{
			try
			{
				byte[] array = ReadPayload(reader);
				if (array == null || array.Length < 1)
				{
					return;
				}
				if (array[0] == 3)
				{
					if (array.Length >= 3 && BitConverter.ToUInt16(array, 1) == 3)
					{
						if (!HostAcked)
						{
							Plugin.Log.LogInfo((object)"MoonNet: host has Moonfall; the timer follows the host.");
						}
						HostAcked = true;
					}
					else
					{
						Plugin.Log.LogWarning((object)"MoonNet: host runs a different Moonfall protocol; ignoring it. Update the mod.");
					}
				}
				else if (array[0] == 2 && array.Length >= 22 && HostAcked)
				{
					State obj = new State
					{
						Running = (array[1] != 0),
						ElapsedReal = BitConverter.ToDouble(array, 2),
						Hours = BitConverter.ToSingle(array, 10),
						TimeScale = BitConverter.ToSingle(array, 14),
						CrashHour = BitConverter.ToSingle(array, 18)
					};
					this.OnState?.Invoke(obj);
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("MoonNet client message: " + ex.Message));
			}
		}

		private void OnServerMessage(NetworkConnection conn, NetworkReader reader, int channelId)
		{
			try
			{
				byte[] array = ReadPayload(reader);
				if (array == null || array.Length < 3 || array[0] != 1)
				{
					return;
				}
				int connectionId = conn.connectionId;
				ushort num = BitConverter.ToUInt16(array, 1);
				if (num != 3)
				{
					Plugin.Log.LogWarning((object)("MoonNet: connection " + connectionId + " runs Moonfall protocol " + num + ", we run " + (ushort)3 + "; ignoring them."));
				}
				else
				{
					if (_modded.Add(connectionId))
					{
						Plugin.Log.LogInfo((object)("MoonNet: connection " + connectionId + " has the mod."));
					}
					NetworkWriter val = Frame(MakeAck());
					conn.Send(val.ToArraySegment(), Channels.Reliable);
					_pendingHello.Add(connectionId);
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("MoonNet server message: " + ex.Message));
			}
		}
	}
	internal static class MoonPlayer
	{
		private static PlayerCharacter _local;

		private static PlayerCharacter Local()
		{
			if ((Object)(object)_local != (Object)null)
			{
				return _local;
			}
			foreach (PlayerCharacter item in Object.FindObjectsByType<PlayerCharacter>((FindObjectsSortMode)0))
			{
				if ((Object)(object)item == (Object)null || !((NetworkBehaviour)item).isLocalPlayer)
				{
					continue;
				}
				_local = item;
				return item;
			}
			return null;
		}

		public static bool Knockdown(Vector3 awayHorizontal, float force)
		{
			//IL_0056: 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)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				PlayerCharacter val = Local();
				if ((Object)(object)val == (Object)null)
				{
					Plugin.Log.LogWarning((object)"Moonfall: no local player found, can't knock anyone down.");
					return false;
				}
				Rigidbody rb = val.rb;
				if ((Object)(object)rb != (Object)null && !rb.isKinematic && force > 0f)
				{
					Vector3 val2 = new Vector3(awayHorizontal.x, 0f, awayHorizontal.z);
					Vector3 normalized = ((Vector3)(ref val2)).normalized;
					rb.linearVelocity += (normalized + Vector3.up) * force;
				}
				PlayerFaller faller = val.faller;
				if (faller == null)
				{
					Plugin.Log.LogWarning((object)"Moonfall: no PlayerFaller on the local player, can't knock them down.");
					return false;
				}
				faller.TriggerFall();
				Plugin.Log.LogInfo((object)"Moonfall: impact knockdown.");
				return true;
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Moonfall: knockdown failed: " + ex.Message));
				_local = null;
				return false;
			}
		}
	}
	internal sealed class MoonSession
	{
		private const float LeaveDelay = 1.5f;

		private bool _was;

		private float _offSince = -1f;

		public bool Update()
		{
			bool flag;
			try
			{
				flag = NetworkServer.active || NetworkClient.active;
			}
			catch
			{
				flag = false;
			}
			if (flag)
			{
				_was = true;
				_offSince = -1f;
				return false;
			}
			if (!_was)
			{
				return false;
			}
			float unscaledTime = Time.unscaledTime;
			if (_offSince < 0f)
			{
				_offSince = unscaledTime;
			}
			if (unscaledTime - _offSince < 1.5f)
			{
				return false;
			}
			_was = false;
			_offSince = -1f;
			return true;
		}
	}
	internal static class MoonSky
	{
		private sealed class F
		{
			public bool Has;

			public float Last;

			public float Base;

			public float Baseline(float cur)
			{
				if (!Has || Mathf.Abs(cur - Last) > 0.0001f)
				{
					Base = cur;
				}
				Has = true;
				return Base;
			}

			public void Reset()
			{
				Has = false;
			}
		}

		private sealed class C
		{
			public bool Has;

			public Color Last;

			public Color Base;

			public Color Baseline(Color cur)
			{
				//IL_0009: Unknown result type (might be due to invalid IL or missing references)
				//IL_0027: Unknown result type (might be due to invalid IL or missing references)
				//IL_0097: Unknown result type (might be due to invalid IL or missing references)
				//IL_009c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0089: Unknown result type (might be due to invalid IL or missing references)
				//IL_008a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0045: Unknown result type (might be due to invalid IL or missing references)
				//IL_009f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0063: Unknown result type (might be due to invalid IL or missing references)
				if (!Has || Mathf.Abs(cur.r - Last.r) > 0.0001f || Mathf.Abs(cur.g - Last.g) > 0.0001f || Mathf.Abs(cur.b - Last.b) > 0.0001f || Mathf.Abs(cur.a - Last.a) > 0.0001f)
				{
					Base = cur;
				}
				Has = true;
				return Base;
			}

			public void Reset()
			{
				Has = false;
			}
		}

		private static bool _hooked;

		private static bool _active;

		private static bool _domeFailed;

		private static Camera _cam;

		private static float _doom;

		private static float _panic;

		private static Light _ignore;

		private static GameObject _domeGo;

		private static Transform _domeT;

		private static Material _domeMat;

		private static int[] _domeColorIds = new int[0];

		private static Light _sun;

		private static float _nextSun;

		private static readonly F _sunInt = new F();

		private static readonly F _ambInt = new F();

		private static readonly C _sunCol = new C();

		private static readonly C _ambLight = new C();

		private static readonly C _ambSky = new C();

		private static readonly C _ambEq = new C();

		private static readonly C _ambGround = new C();

		public static void Set(Camera cam, float doom, float panic, Light ignore)
		{
			_ignore = ignore;
			if ((Object)(object)cam == (Object)null || doom <= 0.001f)
			{
				if (_active)
				{
					Restore();
				}
				_doom = 0f;
				_cam = null;
			}
			else
			{
				Hook();
				_cam = cam;
				_doom = doom;
				_panic = panic;
			}
		}

		private static void Hook()
		{
			if (!_hooked)
			{
				_hooked = true;
				RenderPipelineManager.beginCameraRendering += Action<ScriptableRenderContext, Camera>.op_Implicit((Action<ScriptableRenderContext, Camera>)OnBeginCamera);
				Plugin.Log.LogInfo((object)"MoonSky render hook installed.");
			}
		}

		private static void OnBeginCamera(ScriptableRenderContext ctx, Camera cam)
		{
			try
			{
				if ((Object)(object)_cam != (Object)null && (Object)(object)cam != (Object)null && (Object)(object)cam == (Object)(object)_cam && _doom > 0.001f)
				{
					Apply(cam);
				}
			}
			catch
			{
			}
		}

		private static void Apply(Camera cam)
		{
			_active = true;
			ApplyDome(cam);
			ApplyLights(_doom);
		}

		private static void ApplyDome(Camera cam)
		{
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			if (!_domeFailed && (!((Object)(object)_domeGo == (Object)null) || BuildDome()))
			{
				if (!_domeGo.activeSelf)
				{
					_domeGo.SetActive(true);
				}
				_domeT.position = ((Component)cam).transform.position;
				_domeT.localScale = Vector3.one * (cam.farClipPlane * 0.97f);
				float num = 0.5f + 0.5f * Mathf.Sin(Time.unscaledTime * (1.2f + 1.2f * _doom + 4f * _panic));
				float num2 = Mathf.Clamp01(_doom * (0.55f + 0.2f * num + 0.25f * _panic * num));
				Color val = default(Color);
				((Color)(ref val))..ctor(1f, 0.16f, 0.06f, num2);
				for (int i = 0; i < _domeColorIds.Length; i++)
				{
					_domeMat.SetColor(_domeColorIds[i], val);
				}
			}
		}

		private static bool BuildDome()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Expected O, but got Unknown
			try
			{
				Texture2D val = new Texture2D(4, 64, (TextureFormat)4, false);
				for (int i = 0; i < 64; i++)
				{
					float num = ((float)i + 0.5f) / 64f;
					float num2 = Mathf.Abs(num * 2f - 1f);
					float num3 = 0.18f + 0.72f * Mathf.Pow(1f - num2, 1.8f);
					for (int j = 0; j < 4; j++)
					{
						val.SetPixel(j, i, new Color(1f, 1f, 1f, num3));
					}
				}
				val.Apply();
				((Texture)val).wrapMode = (TextureWrapMode)1;
				((Object)val).hideFlags = (HideFlags)61;
				_domeMat = MoonVfx.MakeMaterial(val);
				if ((Object)(object)_domeMat == (Object)null)
				{
					_domeFailed = true;
					Plugin.Log.LogWarning((object)"MoonSky: no usable particle shader, the red sky glow is disabled. Try VFX/ShaderOverride in the config.");
					return false;
				}
				List<int> list = new List<int>();
				string[] array = new string[3] { "_BaseColor", "_TintColor", "_Color" };
				foreach (string text in array)
				{
					if (_domeMat.HasProperty(text))
					{
						list.Add(Shader.PropertyToID(text));
					}
				}
				_domeColorIds = list.ToArray();
				_domeGo = new GameObject("Moonfall_SkyGlow");
				((Object)_domeGo).hideFlags = (HideFlags)61;
				Object.DontDestroyOnLoad((Object)(object)_domeGo);
				_domeT = _domeGo.transform;
				_domeGo.AddComponent<MeshFilter>().sharedMesh = MakeDomeMesh();
				MeshRenderer val2 = _domeGo.AddComponent<MeshRenderer>();
				((Renderer)val2).sharedMaterial = _domeMat;
				((Renderer)val2).shadowCastingMode = (ShadowCastingMode)0;
				((Renderer)val2).receiveShadows = false;
				Plugin.Log.LogInfo((object)"MoonSky glow dome ready.");
				return true;
			}
			catch (Exception ex)
			{
				_domeFailed = true;
				Plugin.Log.LogError((object)("MoonSky dome failed: " + ex));
				return false;
			}
		}

		private static Mesh MakeDomeMesh()
		{
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Expected O, but got Unknown
			int num = 561;
			Il2CppStructArray<Vector3> val = new Il2CppStructArray<Vector3>((long)num);
			Il2CppStructArray<Vector2> val2 = new Il2CppStructArray<Vector2>((long)num);
			int num2 = 0;
			for (int i = 0; i <= 16; i++)
			{
				float num3 = (float)i / 16f;
				float num4 = (num3 - 0.5f) * (float)Math.PI;
				float num5 = Mathf.Cos(num4);
				float num6 = Mathf.Sin(num4);
				for (int j = 0; j <= 32; j++)
				{
					float num7 = (float)j / 32f * 2f * (float)Math.PI;
					((Il2CppArrayBase<Vector3>)(object)val)[num2] = new Vector3(Mathf.Cos(num7) * num5, num6, Mathf.Sin(num7) * num5);
					((Il2CppArrayBase<Vector2>)(object)val2)[num2] = new Vector2((float)j / 32f, num3);
					num2++;
				}
			}
			Il2CppStructArray<int> val3 = new Il2CppStructArray<int>(3072L);
			int num8 = 0;
			for (int k = 0; k < 16; k++)
			{
				for (int l = 0; l < 32; l++)
				{
					int num9 = k * 33 + l;
					int num10 = num9 + 1;
					int num11 = num9 + 32 + 1;
					int num12 = num11 + 1;
					((Il2CppArrayBase<int>)(object)val3)[num8++] = num9;
					((Il2CppArrayBase<int>)(object)val3)[num8++] = num11;
					((Il2CppArrayBase<int>)(object)val3)[num8++] = num10;
					((Il2CppArrayBase<int>)(object)val3)[num8++] = num10;
					((Il2CppArrayBase<int>)(object)val3)[num8++] = num11;
					((Il2CppArrayBase<int>)(object)val3)[num8++] = num12;
				}
			}
			Mesh val4 = new Mesh();
			((Object)val4).name = "Moonfall_SkyDome";
			((Object)val4).hideFlags = (HideFlags)61;
			val4.vertices = val;
			val4.uv = val2;
			val4.triangles = val3;
			val4.RecalculateBounds();
			return val4;
		}

		private static void ApplyLights(float d)
		{
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Invalid comparison between Unknown and I4
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Invalid comparison between Unknown and I4
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			float unscaledTime = Time.unscaledTime;
			if ((Object)(object)_sun == (Object)null && unscaledTime >= _nextSun)
			{
				_nextSun = unscaledTime + 2f;
				_sun = FindSun();
				_sunInt.Reset();
				_sunCol.Reset();
			}
			if ((Object)(object)_sun != (Object)null)
			{
				float num = _sunInt.Baseline(_sun.intensity);
				float num2 = Mathf.Lerp(num, num * 0.3f, d);
				_sun.intensity = num2;
				_sunInt.Last = num2;
				Color val = _sunCol.Baseline(_sun.color);
				Color val2 = Color.Lerp(val, new Color(1f, 0.28f, 0.15f, 1f), d * 0.85f);
				_sun.color = val2;
				_sunCol.Last = val2;
			}
			AmbientMode ambientMode = RenderSettings.ambientMode;
			if ((int)ambientMode == 3)
			{
				RenderSettings.ambientLight = Dim(_ambLight, RenderSettings.ambientLight, d);
			}
			else if ((int)ambientMode == 1)
			{
				RenderSettings.ambientSkyColor = Dim(_ambSky, RenderSettings.ambientSkyColor, d);
				RenderSettings.ambientEquatorColor = Dim(_ambEq, RenderSettings.ambientEquatorColor, d);
				RenderSettings.ambientGroundColor = Dim(_ambGround, RenderSettings.ambientGroundColor, d);
			}
			else
			{
				float num3 = _ambInt.Baseline(RenderSettings.ambientIntensity);
				float last = (RenderSettings.ambientIntensity = Mathf.Lerp(num3, num3 * 0.35f, d));
				_ambInt.Last = last;
			}
		}

		private static Color Dim(C o, Color cur, float d)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			Color val = o.Baseline(cur);
			return o.Last = Color.Lerp(val, new Color(val.r * 0.55f, val.g * 0.2f, val.b * 0.18f, val.a), d);
		}

		private static Light FindSun()
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Invalid comparison between Unknown and I4
			Light sun = RenderSettings.sun;
			if ((Object)(object)sun != (Object)null && (Object)(object)sun != (Object)(object)_ignore)
			{
				return sun;
			}
			Light val = null;
			foreach (Light item in Object.FindObjectsOfType<Light>())
			{
				if (!((Object)(object)item == (Object)null) && !((Object)(object)item == (Object)(object)_ignore) && (int)item.type == 1 && ((Behaviour)item).enabled && ((Object)(object)val == (Object)null || item.intensity > val.intensity))
				{
					val = item;
				}
			}
			return val;
		}

		private static void Restore()
		{
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			_active = false;
			if ((Object)(object)_domeGo != (Object)null)
			{
				_domeGo.SetActive(false);
			}
			if ((Object)(object)_sun != (Object)null)
			{
				if (_sunInt.Has)
				{
					_sun.intensity = _sunInt.Base;
				}
				if (_sunCol.Has)
				{
					_sun.color = _sunCol.Base;
				}
			}
			if (_ambInt.Has)
			{
				RenderSettings.ambientIntensity = _ambInt.Base;
			}
			if (_ambLight.Has)
			{
				RenderSettings.ambientLight = _ambLight.Base;
			}
			if (_ambSky.Has)
			{
				RenderSettings.ambientSkyColor = _ambSky.Base;
			}
			if (_ambEq.Has)
			{
				RenderSettings.ambientEquatorColor = _ambEq.Base;
			}
			if (_ambGround.Has)
			{
				RenderSettings.ambientGroundColor = _ambGround.Base;
			}
			_sunInt.Reset();
			_sunCol.Reset();
			_ambInt.Reset();
			_ambLight.Reset();
			_ambSky.Reset();
			_ambEq.Reset();
			_ambGround.Reset();
			_sun = null;
		}
	}
	internal static class MoonTime
	{
		private static bool _forced;

		private static bool _warned;

		private static float _origHour = -1f;

		private static bool Ready()
		{
			try
			{
				return SkyManager.initalized;
			}
			catch
			{
				return false;
			}
		}

		public static bool Force(float hour)
		{
			if (!Ready())
			{
				return false;
			}
			try
			{
				if (!_forced)
				{
					_origHour = SkyManager.GetCurrentTime();
				}
				SkyManager.SetFixedTime(hour);
				_forced = true;
				return true;
			}
			catch (Exception ex)
			{
				if (!_warned)
				{
					_warned = true;
					Plugin.Log.LogWarning((object)("SkyManager.SetFixedTime failed: " + ex.Message));
				}
				return false;
			}
		}

		public static bool Release()
		{
			if (!_forced)
			{
				return true;
			}
			if (!Ready())
			{
				return false;
			}
			_forced = false;
			try
			{
				if (_origHour >= 0f)
				{
					SkyManager.SetFixedTime(_origHour);
				}
				SkyManager.ClearFixedTime();
				Plugin.Log.LogInfo((object)("Moonfall: time of day released (restored " + _origHour.ToString("0.0") + "h)."));
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("SkyManager release failed: " + ex.Message));
			}
			return true;
		}
	}
	internal sealed class MoonVfx
	{
		private sealed class Emitter
		{
			private struct P
			{
				public Vector3 Pos;

				public Vector3 Vel;

				public float Age;

				public float Life;

				public float Size;

				public float Seed;
			}

			private readonly P[] _p;

			private readonly int _max;

			private readonly int _tiles;

			private readonly bool _rear;

			private readonly bool _stretch;

			private readonly bool _grow;

			private readonly float _lifeMin;

			private readonly float _lifeMax;

			private readonly float _spdMin;

			private readonly float _spdMax;

			private readonly float _sizeMin;

			private readonly float _sizeMax;

			private readonly float _velZ;

			private readonly float _turb;

			private readonly float _stretchK;

			private readonly Random _rng;

			private readonly Mesh _mesh;

			private readonly Il2CppStructArray<Vector3> _v;

			private readonly Il2CppStructArray<Vector2> _uv;

			private int _n;

			private int _prevN;

			private float _accum;

			public Emitter(string name, Transform parent, Material mat, int max, int tiles, bool rear, bool stretch, bool grow, float lifeMin, float lifeMax, float spdMin, float spdMax, float sizeMin, float sizeMax, float velZ, float turb, float stretchK, int seed)
			{
				//IL_0155: Unknown result type (might be due to invalid IL or missing references)
				//IL_0178: Unknown result type (might be due to invalid IL or missing references)
				//IL_019b: Unknown result type (might be due to invalid IL or missing references)
				//IL_01be: Unknown result type (might be due to invalid IL or missing references)
				//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
				//IL_01d4: Expected O, but got Unknown
				//IL_022d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0233: Expected O, but got Unknown
				_max = max;
				_tiles = tiles;
				_rear = rear;
				_stretch = stretch;
				_grow = grow;
				_lifeMin = lifeMin;
				_lifeMax = lifeMax;
				_spdMin = spdMin;
				_spdMax = spdMax;
				_sizeMin = sizeMin;
				_sizeMax = sizeMax;
				_velZ = velZ;
				_turb = turb;
				_stretchK = stretchK;
				_p = new P[max];
				_rng = new Random(seed);
				_v = new Il2CppStructArray<Vector3>((long)((max + 1) * 4));
				_uv = new Il2CppStructArray<Vector2>((long)((max + 1) * 4));
				Il2CppStructArray<int> val = new Il2CppStructArray<int>((long)(max * 6));
				for (int i = 0; i < max; i++)
				{
					int num = i * 4;
					int num2 = i * 6;
					((Il2CppArrayBase<int>)(object)val)[num2] = num;
					((Il2CppArrayBase<int>)(object)val)[num2 + 1] = num + 2;
					((Il2CppArrayBase<int>)(object)val)[num2 + 2] = num + 1;
					((Il2CppArrayBase<int>)(object)val)[num2 + 3] = num;
					((Il2CppArrayBase<int>)(object)val)[num2 + 4] = num + 3;
					((Il2CppArrayBase<int>)(object)val)[num2 + 5] = num + 2;
				}
				int num3 = max * 4;
				((Il2CppArrayBase<Vector3>)(object)_v)[num3] = new Vector3(-6f, -6f, -6f);
				((Il2CppArrayBase<Vector3>)(object)_v)[num3 + 1] = new Vector3(6f, 6f, 6f);
				((Il2CppArrayBase<Vector3>)(object)_v)[num3 + 2] = new Vector3(-6f, 6f, -6f);
				((Il2CppArrayBase<Vector3>)(object)_v)[num3 + 3] = new Vector3(6f, -6f, 6f);
				_mesh = new Mesh();
				((Object)_mesh).name = name;
				((Object)_mesh).hideFlags = (HideFlags)61;
				_mesh.vertices = _v;
				_mesh.uv = _uv;
				_mesh.triangles = val;
				_mesh.RecalculateBounds();
				GameObject val2 = new GameObject(name);
				val2.transform.SetParent(parent, false);
				val2.AddComponent<MeshFilter>().sharedMesh = _mesh;
				MeshRenderer val3 = val2.AddComponent<MeshRenderer>();
				((Renderer)val3).sharedMaterial = mat;
				((Renderer)val3).shadowCastingMode = (ShadowCastingMode)0;
				((Renderer)val3).receiveShadows = false;
			}

			private float R()
			{
				return (float)_rng.NextDouble();
			}

			private void Spawn()
			{
				//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
				//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
				float num = (_rear ? (0f - R()) : (R() * 2f - 1f));
				float num2 = R() * 6.2832f;
				float num3 = Mathf.Sqrt(Mathf.Max(0f, 1f - num * num));
				Vector3 val = default(Vector3);
				((Vector3)(ref val))..ctor(num3 * Mathf.Cos(num2), num3 * Mathf.Sin(num2), num);
				float num4 = Mathf.Lerp(_spdMin, _spdMax, R());
				float num5 = 0.7f + 0.6f * R();
				_p[_n++] = new P
				{
					Pos = val,
					Vel = new Vector3(val.x * num4, val.y * num4, val.z * num4 + _velZ * num5),
					Age = 0f,
					Life = Mathf.Lerp(_lifeMin, _lifeMax, R()),
					Size = Mathf.Lerp(_sizeMin, _sizeMax, R()),
					Seed = R()
				};
			}

			public void Clear()
			{
				if (_n > _prevN)
				{
					_prevN = _n;
				}
				_n = 0;
				_accum = 0f;
			}

			public void Step(float dt, float rate, float time, Vector3 right, Vector3 up, Vector3 toCam)
			{
				//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
				//IL_0151: 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_015c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0166: Unknown result type (might be due to invalid IL or missing references)
				//IL_0172: Unknown result type (might be due to invalid IL or missing references)
				//IL_017c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0188: Unknown result type (might be due to invalid IL or missing references)
				//IL_0192: Unknown result type (might be due to invalid IL or missing references)
				//IL_019c: Unknown result type (might be due to invalid IL or missing references)
				//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
				//IL_0117: Unknown result type (might be due to invalid IL or missing references)
				//IL_0142: Unknown result type (might be due to invalid IL or missing references)
				//IL_03df: Unknown result type (might be due to invalid IL or missing references)
				//IL_03f4: Unknown result type (might be due to invalid IL or missing references)
				//IL_0409: Unknown result type (might be due to invalid IL or missing references)
				//IL_041e: Unknown result type (might be due to invalid IL or missing references)
				//IL_025e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0262: Unknown result type (might be due to invalid IL or missing references)
				//IL_0267: Unknown result type (might be due to invalid IL or missing references)
				//IL_0269: Unknown result type (might be due to invalid IL or missing references)
				//IL_026d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0272: Unknown result type (might be due to invalid IL or missing references)
				//IL_027c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0281: Unknown result type (might be due to invalid IL or missing references)
				//IL_028b: Unknown result type (might be due to invalid IL or missing references)
				//IL_028d: Unknown result type (might be due to invalid IL or missing references)
				//IL_028f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0294: Unknown result type (might be due to invalid IL or missing references)
				//IL_0296: 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_02ad: Unknown result type (might be due to invalid IL or missing references)
				//IL_02af: Unknown result type (might be due to invalid IL or missing references)
				//IL_02b4: Unknown result type (might be due to invalid IL or missing references)
				//IL_02b6: Unknown result type (might be due to invalid IL or missing references)
				//IL_02cb: Unknown result type (might be due to invalid IL or missing references)
				//IL_02cd: Unknown result type (might be due to invalid IL or missing references)
				//IL_02cf: Unknown result type (might be due to invalid IL or missing references)