Decompiled source of CoconutMall v1.0.0
BepInEx/patchers/SlipSkid.StripFix.dll
Decompiled 6 hours agousing System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx.Core.Logging.Interpolation; using BepInEx.Logging; using BepInEx.Preloader.Core.Patching; using Microsoft.CodeAnalysis; using Mono.Cecil; using Mono.Cecil.Cil; using Mono.Collections.Generic; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("SlipSkid.StripFix")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("SlipSkid.StripFix")] [assembly: AssemblyTitle("SlipSkid.StripFix")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace SlipSkid.StripFix { [PatcherPluginInfo("slipskid.stripfix", "Slip & Skid - Strip Fix", "1.0.0")] public class StripFixPatcher : BasePatcher { private const string UnityVersion = "2022.3.62f2"; [TargetAssembly("UnityEngine.CoreModule.dll")] public void PatchCoreModule(AssemblyDefinition assembly) { TypeDefinition type = assembly.MainModule.GetType("UnityEngine.Application"); if (type == null) { ((BasePatcher)this).Log.LogWarning((object)"UnityEngine.Application not found; skipping strip fix."); return; } RestoreUnityVersion(assembly, type); RestoreLogMessageReceived(assembly, type); } private void RestoreUnityVersion(AssemblyDefinition assembly, TypeDefinition application) { //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Expected O, but got Unknown //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: 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_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Expected O, but got Unknown //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Expected O, but got Unknown if (application.Methods.Any((MethodDefinition m) => ((MemberReference)m).Name == "get_unityVersion")) { ((BasePatcher)this).Log.LogInfo((object)"Application.get_unityVersion already present."); return; } TypeReference val = assembly.MainModule.TypeSystem.String; MethodDefinition val2 = new MethodDefinition("get_unityVersion", (MethodAttributes)2198, val); ILProcessor iLProcessor = val2.Body.GetILProcessor(); iLProcessor.Append(iLProcessor.Create(OpCodes.Ldstr, "2022.3.62f2")); iLProcessor.Append(iLProcessor.Create(OpCodes.Ret)); application.Methods.Add(val2); application.Properties.Add(new PropertyDefinition("unityVersion", (PropertyAttributes)0, val) { GetMethod = val2 }); ManualLogSource log = ((BasePatcher)this).Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(40, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("Restored Application.unityVersion => \""); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>("2022.3.62f2"); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("\"."); } log.LogInfo(val3); } private void RestoreLogMessageReceived(AssemblyDefinition assembly, TypeDefinition application) { //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0175: 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_018a: Expected O, but got Unknown if (application.Events.Any((EventDefinition e) => ((MemberReference)e).Name == "logMessageReceived")) { ((BasePatcher)this).Log.LogInfo((object)"Application.logMessageReceived already present."); return; } FieldDefinition val = application.Fields.FirstOrDefault((FieldDefinition f) => ((MemberReference)f).Name == "s_LogCallbackHandler"); TypeDefinition val2 = application.NestedTypes.FirstOrDefault((TypeDefinition t) => ((MemberReference)t).Name == "LogCallback"); if (val == null || val2 == null) { ((BasePatcher)this).Log.LogWarning((object)"s_LogCallbackHandler or LogCallback missing — cannot restore logMessageReceived. Game log forwarding will stay disabled."); return; } ModuleDefinition mainModule = assembly.MainModule; MethodReference combineOrRemove = mainModule.ImportReference((MethodBase)typeof(Delegate).GetMethod("Combine", new Type[2] { typeof(Delegate), typeof(Delegate) })); MethodReference combineOrRemove2 = mainModule.ImportReference((MethodBase)typeof(Delegate).GetMethod("Remove", new Type[2] { typeof(Delegate), typeof(Delegate) })); MethodDefinition val3 = BuildAccessor("add_logMessageReceived", (TypeReference)(object)val2, val, combineOrRemove, mainModule); MethodDefinition val4 = BuildAccessor("remove_logMessageReceived", (TypeReference)(object)val2, val, combineOrRemove2, mainModule); application.Methods.Add(val3); application.Methods.Add(val4); application.Events.Add(new EventDefinition("logMessageReceived", (EventAttributes)0, (TypeReference)(object)val2) { AddMethod = val3, RemoveMethod = val4 }); ((BasePatcher)this).Log.LogInfo((object)"Restored Application.logMessageReceived — game Debug.Log will reach BepInEx."); } private static MethodDefinition BuildAccessor(string name, TypeReference callbackType, FieldDefinition handlerField, MethodReference combineOrRemove, ModuleDefinition module) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_003b: 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) //IL_005e: 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_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Expected O, but got Unknown MethodDefinition val = new MethodDefinition(name, (MethodAttributes)2198, module.TypeSystem.Void); ((MethodReference)val).Parameters.Add(new ParameterDefinition("value", (ParameterAttributes)0, callbackType)); ILProcessor iLProcessor = val.Body.GetILProcessor(); iLProcessor.Append(iLProcessor.Create(OpCodes.Ldsfld, (FieldReference)(object)handlerField)); iLProcessor.Append(iLProcessor.Create(OpCodes.Ldarg_0)); iLProcessor.Append(iLProcessor.Create(OpCodes.Call, combineOrRemove)); iLProcessor.Append(iLProcessor.Create(OpCodes.Castclass, callbackType)); iLProcessor.Append(iLProcessor.Create(OpCodes.Stsfld, (FieldReference)(object)handlerField)); iLProcessor.Append(iLProcessor.Create(OpCodes.Ret)); return val; } } internal static class CecilExtensions { public static bool Any<T>(this Collection<T> collection, Func<T, bool> predicate) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) Enumerator<T> enumerator = collection.GetEnumerator(); try { while (enumerator.MoveNext()) { T current = enumerator.Current; if (predicate(current)) { return true; } } } finally { ((IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose(); } return false; } public static T FirstOrDefault<T>(this Collection<T> collection, Func<T, bool> predicate) where T : class { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) Enumerator<T> enumerator = collection.GetEnumerator(); try { while (enumerator.MoveNext()) { T current = enumerator.Current; if (predicate(current)) { return current; } } } finally { ((IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose(); } return null; } } }
BepInEx/plugins/SlipSkid.MapLoader/SlipSkid.MapLoader.dll
Decompiled 6 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Cryptography; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Core.Logging.Interpolation; using BepInEx.Logging; using BepInEx.Unity.Mono; using CameraUtils; using Game; using Game.Levels; using HarmonyLib; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using Obstacles; using Player; using SlipSkid.MapSDK; using Sounds; using Sounds.SplitScreenAudio; using UnityEngine; using UnityEngine.Audio; using UnityEngine.Rendering; using UnityEngine.SceneManagement; using Utils; using Utils.Networking; using World; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("SlipSkid.MapLoader")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("SlipSkid.MapLoader")] [assembly: AssemblyTitle("SlipSkid.MapLoader")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace SlipSkid.MapLoader { internal class BoostPadZone : MonoBehaviour { public float boostSpeed = 15f; private const float Cooldown = 0.5f; private float _lastBoostTime = -999f; private void OnTriggerEnter(Collider other) { //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) if (Time.time - _lastBoostTime < 0.5f) { return; } Rigidbody attachedRigidbody = other.attachedRigidbody; if (!((Object)(object)attachedRigidbody == (Object)null)) { SphereCarController componentInParent = ((Component)attachedRigidbody).GetComponentInParent<SphereCarController>(); if (!((Object)(object)componentInParent == (Object)null)) { Vector3 val = (((Object)(object)componentInParent.car != (Object)null) ? componentInParent.car.forward : ((Component)attachedRigidbody).transform.forward); attachedRigidbody.AddForce(val * boostSpeed, (ForceMode)2); _lastBoostTime = Time.time; } } } } public class CustomMap { public MapManifest Manifest { get; } public string Directory { get; } public AssetBundle Bundle { get; internal set; } public Level Level { get; internal set; } public string ScenePath { get; internal set; } public bool Loaded { get { if ((Object)(object)Bundle != (Object)null) { return (Object)(object)Level != (Object)null; } return false; } } public CustomMap(MapManifest manifest, string directory) { Manifest = manifest; Directory = directory; } public string ResolvePath(string relative) { if (!string.IsNullOrEmpty(relative)) { return Path.Combine(Directory, relative); } return null; } public override string ToString() { return Manifest.DisplayName + " (" + Manifest.Id + ")"; } } public static class CustomMapLoader { private static readonly List<CustomMap> Maps = new List<CustomMap>(); private static bool _discovered; public static IReadOnlyList<CustomMap> All => Maps; public static bool BundlesReady { get; private set; } public static string MapsDirectory => Path.GetFullPath(Path.Combine(Paths.BepInExRootPath, "CustomMaps")); public static bool IsCustomMap(string levelName) { if (string.IsNullOrEmpty(levelName)) { return false; } foreach (CustomMap map in Maps) { if ((Object)(object)map.Level != (Object)null && string.Equals(map.Level.name, levelName, StringComparison.OrdinalIgnoreCase)) { return true; } if (string.Equals(map.Manifest.SceneName, levelName, StringComparison.OrdinalIgnoreCase) || string.Equals(map.Manifest.DisplayName, levelName, StringComparison.OrdinalIgnoreCase)) { return true; } } return false; } private static List<string> FindMapFolders(string root) { List<string> found = new List<string>(); HashSet<string> seen = new HashSet<string>(StringComparer.OrdinalIgnoreCase); Collect(root, 2); Collect(Paths.PluginPath, 4); found.Sort(StringComparer.OrdinalIgnoreCase); return found; void Collect(string directory, int depth) { if (depth >= 0 && Directory.Exists(directory)) { string[] directories = Directory.GetDirectories(directory); foreach (string text in directories) { if (File.Exists(Path.Combine(text, "map.json"))) { string fileName = Path.GetFileName(text); if (seen.Add(fileName)) { found.Add(text); } } else { Collect(text, depth - 1); } } } } } public static void Discover() { //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Expected O, but got Unknown //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Expected O, but got Unknown //IL_0216: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Expected O, but got Unknown //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Expected O, but got Unknown //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Expected O, but got Unknown //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Expected O, but got Unknown if (_discovered) { return; } _discovered = true; string mapsDirectory = MapsDirectory; if (!Directory.Exists(mapsDirectory)) { Directory.CreateDirectory(mapsDirectory); } List<string> list = FindMapFolders(mapsDirectory); bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val; if (list.Count == 0) { ManualLogSource log = Plugin.Log; val = new BepInExInfoLogInterpolatedStringHandler(41, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("No custom maps found. Put map folders in "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(mapsDirectory); } log.LogInfo(val); return; } foreach (string item in list) { string path = Path.Combine(item, "map.json"); MapManifest mapManifest; try { mapManifest = JsonConvert.DeserializeObject<MapManifest>(File.ReadAllText(path)); } catch (Exception ex) { ManualLogSource log2 = Plugin.Log; BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(33, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Skipping '"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(Path.GetFileName(item)); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("': malformed map.json: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.Message); } log2.LogError(val2); continue; } if (mapManifest == null) { ManualLogSource log3 = Plugin.Log; BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(39, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Skipping '"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(Path.GetFileName(item)); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("': map.json parsed to nothing"); } log3.LogError(val2); continue; } if (!mapManifest.Validate(out var error)) { ManualLogSource log4 = Plugin.Log; BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(13, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Skipping '"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(Path.GetFileName(item)); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("': "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(error); } log4.LogError(val2); continue; } Maps.Add(new CustomMap(mapManifest, item)); ManualLogSource log5 = Plugin.Log; val = new BepInExInfoLogInterpolatedStringHandler(19, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Discovered map: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(mapManifest.DisplayName); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" ["); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(mapManifest.Id); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("]"); } log5.LogInfo(val); } ManualLogSource log6 = Plugin.Log; val = new BepInExInfoLogInterpolatedStringHandler(29, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(Maps.Count); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" custom map(s) discovered in "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(mapsDirectory); } log6.LogInfo(val); } public static IEnumerator LoadBundlesRoutine() { Discover(); if (Maps.Count == 0) { BundlesReady = true; yield break; } bool flag = default(bool); foreach (CustomMap map in Maps) { if ((Object)(object)map.Bundle != (Object)null) { continue; } string bundlePath = ResolveBundlePath(map); if (bundlePath == null) { ManualLogSource log = Plugin.Log; BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(29, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<CustomMap>(map); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("': no .bundle file found in "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(map.Directory); } log.LogError(val); continue; } AssetBundleCreateRequest request = AssetBundle.LoadFromFileAsync(bundlePath); yield return request; if ((Object)(object)request.assetBundle == (Object)null) { ManualLogSource log2 = Plugin.Log; BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(148, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<CustomMap>(map); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("': AssetBundle failed to load. Most likely built with a Unity version other than "); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("2022.3.62f2, or for a different platform than StandaloneWindows64."); } log2.LogError(val); continue; } map.Bundle = request.assetBundle; ManualLogSource log3 = Plugin.Log; BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(23, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Bundle loaded for '"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<CustomMap>(map); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("' ("); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(Path.GetFileName(bundlePath)); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(")"); } log3.LogInfo(val2); } BundlesReady = true; } public static void BuildLevels(LevelManager levelManager) { //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Expected O, but got Unknown //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Expected O, but got Unknown if (Maps.Count == 0) { return; } Level val = PickTemplate(levelManager, null); if ((Object)(object)val == (Object)null) { Plugin.Log.LogError((object)"No shipped level to use as a template; cannot register custom maps."); return; } bool flag = default(bool); foreach (CustomMap map in Maps) { if ((Object)(object)map.Level != (Object)null || (Object)(object)map.Bundle == (Object)null) { continue; } try { Level template = PickTemplate(levelManager, map.Manifest.TemplateLevel) ?? val; map.Level = BuildLevel(map, template); ManualLogSource log = Plugin.Log; BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(25, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Registered '"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<CustomMap>(map); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("' -> scene '"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(map.Manifest.SceneName); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("'"); } log.LogInfo(val2); } catch (Exception ex) { ManualLogSource log2 = Plugin.Log; BepInExErrorLogInterpolatedStringHandler val3 = new BepInExErrorLogInterpolatedStringHandler(30, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("Failed to build level for '"); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<CustomMap>(map); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("': "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<Exception>(ex); } log2.LogError(val3); } } } private static Level BuildLevel(CustomMap map, Level template) { //IL_005a: 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_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) Level val = Object.Instantiate<Level>(template); ((Object)val).hideFlags = (HideFlags)61; val.name = map.Manifest.DisplayName; ((Object)val).name = map.Manifest.DisplayName; val.sceneName = map.Manifest.SceneName; val.difficulty = Mathf.Max(1, map.Manifest.Difficulty); LevelInGameStats inGameStats = val.inGameStats; inGameStats.isReversible = map.Manifest.IsReversible; val.inGameStats = inGameStats; val.ghostUnlockableContent = default(GhostUnlockableContent); Texture2D val2 = LoadTexture(map.ResolvePath(map.Manifest.Thumbnail)); if ((Object)(object)val2 != (Object)null) { val.thumbnailImage = val2; } Texture2D val3 = LoadTexture(map.ResolvePath(map.Manifest.Preview)); if ((Object)(object)val3 != (Object)null) { val.previewImage = val3; } return val; } private static string ResolveBundlePath(CustomMap map) { if (!string.IsNullOrEmpty(map.Manifest.Bundle)) { string text = map.ResolvePath(map.Manifest.Bundle); if (!File.Exists(text)) { return null; } return text; } string[] files = Directory.GetFiles(map.Directory, "*.bundle"); if (files.Length == 0) { return null; } return files[0]; } private static Level PickTemplate(LevelManager levelManager, string preferredName) { Level[] array = levelManager?.levels; if (array == null || array.Length == 0) { return null; } Level[] array2; if (!string.IsNullOrEmpty(preferredName)) { array2 = array; foreach (Level val in array2) { if ((Object)(object)val != (Object)null && val.name == preferredName) { return val; } } } array2 = array; foreach (Level val2 in array2) { if ((Object)(object)val2 != (Object)null) { return val2; } } return null; } private static Texture2D LoadTexture(string path) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected O, but got Unknown if (string.IsNullOrEmpty(path) || !File.Exists(path)) { return null; } Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false); if (ImageConversion.LoadImage(val, File.ReadAllBytes(path))) { ((Object)val).hideFlags = (HideFlags)61; return val; } Object.Destroy((Object)(object)val); ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(24, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Could not decode image: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(path); } log.LogWarning(val2); return null; } } [HarmonyPatch] internal static class GameLogForwarder { private static ManualLogSource _log; internal static void Install(Harmony harmony) { _log = Logger.CreateLogSource("Game"); harmony.PatchAll(typeof(GameLogForwarder)); _log.LogInfo((object)"Game log forwarding active."); } private static void Write(LogLevel level, object message) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) try { ManualLogSource log = _log; if (log != null) { log.Log(level, message ?? "null"); } } catch { } } [HarmonyPatch(typeof(Debug), "Log", new Type[] { typeof(object) })] [HarmonyPostfix] private static void OnLog(object message) { Write((LogLevel)16, message); } [HarmonyPatch(typeof(Debug), "Log", new Type[] { typeof(object), typeof(Object) })] [HarmonyPostfix] private static void OnLogContext(object message) { Write((LogLevel)16, message); } [HarmonyPatch(typeof(Debug), "LogWarning", new Type[] { typeof(object) })] [HarmonyPostfix] private static void OnWarning(object message) { Write((LogLevel)4, message); } [HarmonyPatch(typeof(Debug), "LogWarning", new Type[] { typeof(object), typeof(Object) })] [HarmonyPostfix] private static void OnWarningContext(object message) { Write((LogLevel)4, message); } [HarmonyPatch(typeof(Debug), "LogError", new Type[] { typeof(object) })] [HarmonyPostfix] private static void OnError(object message) { Write((LogLevel)2, message); } [HarmonyPatch(typeof(Debug), "LogError", new Type[] { typeof(object), typeof(Object) })] [HarmonyPostfix] private static void OnErrorContext(object message) { Write((LogLevel)2, message); } [HarmonyPatch(typeof(Debug), "LogException", new Type[] { typeof(Exception) })] [HarmonyPostfix] private static void OnException(Exception exception) { Write((LogLevel)2, exception); } } internal static class LevelRigHarvester { private static GameObject _cachedRig; private static GameObject _cachedStartLine; private static GameObject _cachedFinishLine; private static GameObject _cachedEndGamePlatform; private static GameObject _cachedCheckpoint; public static bool HasRig => (Object)(object)_cachedRig != (Object)null; public static GameObject StartLinePrefab => _cachedStartLine; public static GameObject FinishLinePrefab => _cachedFinishLine; public static GameObject EndGamePlatformPrefab => _cachedEndGamePlatform; public static GameObject CheckpointPrefab => _cachedCheckpoint; public static int RoadTileLayer { get; private set; } = -1; public static List<LevelEnvironmentBiome> StockBiomes { get; private set; } public static LevelEnvironmentBiome StockRushBiome { get; private set; } public static Material StockFogMaterial { get; private set; } public static Material[] StockRoadMaterials { get; private set; } public static GameObject RoadPiecePrefab { get; private set; } public static List<GameObject> RoadPiecePrefabs { get; private set; } public static bool HasRoadPieces { get { if (RoadPiecePrefabs != null) { return RoadPiecePrefabs.Count > 0; } return false; } } public static Vector3 RoadPieceSize { get; private set; } public static Mesh RoadPieceMesh { get; private set; } public static Material BorderMaterial { get; private set; } public static bool HasEnvironment { get { if (StockBiomes != null) { return StockBiomes.Count > 0; } return false; } } public static float StockGravity { get; private set; } = 40f; private static void HarvestRoadPieces(Scene scene, LevelTileObject sample) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Expected O, but got Unknown //IL_01d9: 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_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_01f6: Unknown result type (might be due to invalid IL or missing references) //IL_01fd: Expected O, but got Unknown //IL_020f: Unknown result type (might be due to invalid IL or missing references) //IL_0233: Unknown result type (might be due to invalid IL or missing references) //IL_0255: Unknown result type (might be due to invalid IL or missing references) //IL_0290: Unknown result type (might be due to invalid IL or missing references) //IL_0297: Expected O, but got Unknown //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0102: 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_02d3: Unknown result type (might be due to invalid IL or missing references) //IL_02d8: Unknown result type (might be due to invalid IL or missing references) //IL_02e4: Unknown result type (might be due to invalid IL or missing references) //IL_02eb: Expected O, but got Unknown //IL_03c0: Unknown result type (might be due to invalid IL or missing references) //IL_03c5: Unknown result type (might be due to invalid IL or missing references) //IL_03d1: Unknown result type (might be due to invalid IL or missing references) //IL_03d8: Expected O, but got Unknown //IL_0452: Unknown result type (might be due to invalid IL or missing references) //IL_046c: Unknown result type (might be due to invalid IL or missing references) //IL_0491: Unknown result type (might be due to invalid IL or missing references) //IL_0356: Unknown result type (might be due to invalid IL or missing references) //IL_05b1: Unknown result type (might be due to invalid IL or missing references) //IL_05b8: Expected O, but got Unknown //IL_05e4: Unknown result type (might be due to invalid IL or missing references) Transform transform = ((Component)sample).transform; ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(36, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("--- Stock road tile '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(((Object)transform).name); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' structure ---"); } log.LogInfo(val); DumpHierarchy(transform, 0); RoadPiecePrefab = CloneInactive(((Component)transform).gameObject, "SlipSkid_CachedRoadPiece"); RoadPiecePrefabs = new List<GameObject>(); HashSet<string> hashSet = new HashSet<string>(); GameObject[] rootGameObjects = ((Scene)(ref scene)).GetRootGameObjects(); Bounds bounds; for (int i = 0; i < rootGameObjects.Length; i++) { LevelTileObject[] componentsInChildren = rootGameObjects[i].GetComponentsInChildren<LevelTileObject>(true); foreach (LevelTileObject val2 in componentsInChildren) { if (RoadPiecePrefabs.Count >= 24) { break; } MeshFilter component = ((Component)val2).GetComponent<MeshFilter>(); MeshRenderer component2 = ((Component)val2).GetComponent<MeshRenderer>(); if ((Object)(object)component == (Object)null || (Object)(object)component.sharedMesh == (Object)null || (Object)(object)component2 == (Object)null) { continue; } string name = ((Object)component.sharedMesh).name; bounds = ((Renderer)component2).bounds; string item = $"{name}|{((Bounds)(ref bounds)).size}"; if (hashSet.Add(item)) { GameObject val3 = CloneInactive(((Component)val2).gameObject, $"SlipSkid_RoadPiece_{RoadPiecePrefabs.Count:00}"); if (!((Object)(object)val3 == (Object)null)) { RoadPiecePrefabs.Add(val3); } } } } ManualLogSource log2 = Plugin.Log; val = new BepInExInfoLogInterpolatedStringHandler(44, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Cached "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(RoadPiecePrefabs.Count); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" real road piece prefab(s) for reuse."); } log2.LogInfo(val); MeshRenderer component3 = ((Component)sample).GetComponent<MeshRenderer>(); if ((Object)(object)component3 != (Object)null) { bounds = ((Renderer)component3).bounds; RoadPieceSize = ((Bounds)(ref bounds)).size; ManualLogSource log3 = Plugin.Log; val = new BepInExInfoLogInterpolatedStringHandler(73, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("REAL ROAD PIECE SIZE (world): "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Vector3>(RoadPieceSize); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" "); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("-> generate path segments "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(RoadPieceSize.z, "F1"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" long and "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(RoadPieceSize.x, "F1"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" wide."); } log3.LogInfo(val); } foreach (Transform item2 in transform) { Transform val4 = item2; if (((Object)val4).name.IndexOf("Border", StringComparison.OrdinalIgnoreCase) < 0) { continue; } MeshRenderer component4 = ((Component)val4).GetComponent<MeshRenderer>(); if (!((Object)(object)component4 == (Object)null)) { BorderMaterial = ((Renderer)component4).sharedMaterial; Bounds bounds2 = ((Renderer)component4).bounds; ManualLogSource log4 = Plugin.Log; val = new BepInExInfoLogInterpolatedStringHandler(39, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Border piece '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(((Object)val4).name); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("': material='"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(((Object)(object)BorderMaterial != (Object)null) ? ((Object)BorderMaterial).name : "none"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' "); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("worldSize="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Vector3>(((Bounds)(ref bounds2)).size); } log4.LogInfo(val); break; } } MeshFilter component5 = ((Component)sample).GetComponent<MeshFilter>(); if ((Object)(object)component5 != (Object)null && (Object)(object)component5.sharedMesh != (Object)null) { RoadPieceMesh = component5.sharedMesh; Bounds bounds3 = RoadPieceMesh.bounds; ManualLogSource log5 = Plugin.Log; val = new BepInExInfoLogInterpolatedStringHandler(63, 6, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Road piece mesh '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(((Object)RoadPieceMesh).name); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("': verts="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(RoadPieceMesh.vertexCount); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" "); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("subMeshes="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(RoadPieceMesh.subMeshCount); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" size="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Vector3>(((Bounds)(ref bounds3)).size); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" center="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Vector3>(((Bounds)(ref bounds3)).center); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" "); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("lossyScale="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Vector3>(transform.lossyScale); } log5.LogInfo(val); } Dictionary<string, int> dictionary = new Dictionary<string, int>(); rootGameObjects = ((Scene)(ref scene)).GetRootGameObjects(); for (int i = 0; i < rootGameObjects.Length; i++) { LevelTileObject[] componentsInChildren = rootGameObjects[i].GetComponentsInChildren<LevelTileObject>(true); for (int j = 0; j < componentsInChildren.Length; j++) { MeshFilter component6 = ((Component)componentsInChildren[j]).GetComponent<MeshFilter>(); string key = (((Object)(object)component6 != (Object)null && (Object)(object)component6.sharedMesh != (Object)null) ? ((Object)component6.sharedMesh).name : "(no mesh)"); dictionary[key] = ((!dictionary.TryGetValue(key, out var value)) ? 1 : (value + 1)); } } List<string> list = new List<string>(); int num = 0; foreach (KeyValuePair<string, int> item3 in dictionary) { if (num++ >= 12) { break; } list.Add($"{item3.Key} x{item3.Value}"); } ManualLogSource log6 = Plugin.Log; val = new BepInExInfoLogInterpolatedStringHandler(58, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Stock level uses "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(dictionary.Count); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" distinct road mesh(es) across "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(CountTiles(scene)); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" tiles: ["); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(string.Join(", ", list)); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("]"); } log6.LogInfo(val); } private static int CountTiles(Scene scene) { int num = 0; GameObject[] rootGameObjects = ((Scene)(ref scene)).GetRootGameObjects(); foreach (GameObject val in rootGameObjects) { num += val.GetComponentsInChildren<LevelTileObject>(true).Length; } return num; } private static void DumpHierarchy(Transform t, int depth) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Expected O, but got Unknown //IL_0123: Unknown result type (might be due to invalid IL or missing references) if (depth > 3) { return; } string text = new string(' ', depth * 2); MeshFilter component = ((Component)t).GetComponent<MeshFilter>(); MeshRenderer component2 = ((Component)t).GetComponent<MeshRenderer>(); Collider component3 = ((Component)t).GetComponent<Collider>(); ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(38, 6, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(((Object)t).name); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" "); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("mesh="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(((Object)(object)component != (Object)null && (Object)(object)component.sharedMesh != (Object)null) ? ((Object)component.sharedMesh).name : "-"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" "); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("renderer="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(((Object)(object)component2 != (Object)null) ? "yes" : "-"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" "); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("collider="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(((Object)(object)component3 != (Object)null) ? ((object)component3).GetType().Name : "-"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" "); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("localScale="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Vector3>(t.localScale); } log.LogInfo(val); foreach (Transform item in t) { DumpHierarchy(item, depth + 1); } } private static void HarvestEnvironment(Scene scene) { //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Expected O, but got Unknown LevelDefinition val = null; GameObject[] rootGameObjects = ((Scene)(ref scene)).GetRootGameObjects(); for (int i = 0; i < rootGameObjects.Length; i++) { val = rootGameObjects[i].GetComponentInChildren<LevelDefinition>(true); if ((Object)(object)val != (Object)null) { break; } } if ((Object)(object)val == (Object)null) { Plugin.Log.LogWarning((object)"No LevelDefinition in the stock level; custom maps will have no scenery."); return; } if (val.environmentBiomes != null && val.environmentBiomes.Count > 0) { StockBiomes = new List<LevelEnvironmentBiome>(); foreach (LevelEnvironmentBiome environmentBiome in val.environmentBiomes) { if ((Object)(object)environmentBiome != (Object)null) { StockBiomes.Add(environmentBiome); } } } StockRushBiome = val.rushModeEnvironmentBiome; if ((Object)(object)val.fogPlane != (Object)null) { StockFogMaterial = ((Renderer)val.fogPlane).sharedMaterial; } List<string> list = new List<string>(); if (StockBiomes != null) { foreach (LevelEnvironmentBiome stockBiome in StockBiomes) { list.Add(((Object)stockBiome).name + "->" + (((Object)(object)stockBiome.prefabToInstantiate != (Object)null) ? ((Object)stockBiome.prefabToInstantiate).name : "NO PREFAB")); } } ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(56, 4, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Harvested "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>((StockBiomes != null) ? StockBiomes.Count : 0); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" environment biome(s): "); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("["); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(string.Join(", ", list)); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("]; rush="); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(((Object)(object)StockRushBiome != (Object)null) ? ((Object)StockRushBiome).name : "none"); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("; "); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("fogMaterial="); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(((Object)(object)StockFogMaterial != (Object)null) ? ((Object)StockFogMaterial).name : "none"); } log.LogInfo(val2); } private static void StripLevelComponents(GameObject rig) { //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Expected O, but got Unknown int num = 0; num += DestroyAll<RandomPositionPlayerSpawner>(rig); num += DestroyAll<LevelDefinition>(rig); num += DestroyAll<ObstacleLevelDefinition>(rig); num += DestroyAll<StartLine>(rig); num += DestroyAll<FinishLine>(rig); num += DestroyAll<EndGamePlatform>(rig); num += DestroyAll<CheckPoint>(rig); num += DestroyAll<LevelTileObject>(rig); if (num > 0) { ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(52, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Stripped "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(num); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" level component(s) from the harvested rig."); } log.LogInfo(val); } } private static int DestroyAll<T>(GameObject root) where T : Component { T[] componentsInChildren = root.GetComponentsInChildren<T>(true); T[] array = componentsInChildren; for (int i = 0; i < array.Length; i++) { Object.DestroyImmediate((Object)(object)array[i]); } return componentsInChildren.Length; } private static GameObject CloneInactive(GameObject source, string name) { if ((Object)(object)source == (Object)null) { return null; } bool activeSelf = source.activeSelf; source.SetActive(false); GameObject obj = Object.Instantiate<GameObject>(source); ((Object)obj).name = name; Object.DontDestroyOnLoad((Object)(object)obj); source.SetActive(activeSelf); return obj; } public static IEnumerator HarvestRoutine() { if ((Object)(object)_cachedRig != (Object)null) { yield break; } while ((Object)(object)LevelManager.instance == (Object)null) { yield return null; } Level[] levels = LevelManager.instance.levels; if (levels == null || levels.Length == 0) { Plugin.Log.LogWarning((object)"No shipped levels to harvest a camera rig from."); yield break; } string sceneName = null; Level[] array = levels; foreach (Level val in array) { if ((Object)(object)val != (Object)null && !string.IsNullOrEmpty(val.sceneName)) { sceneName = val.sceneName; break; } } if (sceneName == null) { yield break; } ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(44, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Harvesting camera rig from stock level '"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(sceneName); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("'..."); } log.LogInfo(val2); AsyncOperation load; try { load = SceneManager.LoadSceneAsync(sceneName, (LoadSceneMode)1); } catch (Exception ex) { ManualLogSource log2 = Plugin.Log; BepInExErrorLogInterpolatedStringHandler val3 = new BepInExErrorLogInterpolatedStringHandler(30, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("Could not additively load '"); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(sceneName); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("': "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(ex.Message); } log2.LogError(val3); yield break; } if (load == null) { yield break; } while (!load.isDone) { yield return null; } Scene sceneByName = SceneManager.GetSceneByName(sceneName); CameraManager val4 = null; if (((Scene)(ref sceneByName)).IsValid()) { GameObject[] rootGameObjects = ((Scene)(ref sceneByName)).GetRootGameObjects(); for (int i = 0; i < rootGameObjects.Length; i++) { val4 = rootGameObjects[i].GetComponentInChildren<CameraManager>(true); if ((Object)(object)val4 != (Object)null) { break; } } } if ((Object)(object)val4 != (Object)null) { _cachedRig = CloneInactive(((Component)((Component)val4).transform.root).gameObject, "SlipSkid_CachedCameraRig"); StripLevelComponents(_cachedRig); ManualLogSource log3 = Plugin.Log; val2 = new BepInExInfoLogInterpolatedStringHandler(26, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Camera rig cached from '"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(sceneName); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("'."); } log3.LogInfo(val2); } else { ManualLogSource log4 = Plugin.Log; BepInExWarningLogInterpolatedStringHandler val5 = new BepInExWarningLogInterpolatedStringHandler(29, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("No CameraManager found in '"); ((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<string>(sceneName); ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("'."); } log4.LogWarning(val5); } if (((Scene)(ref sceneByName)).IsValid()) { StartLine val6 = null; FinishLine val7 = null; EndGamePlatform val8 = null; GravityShapeInfinitePlane val9 = null; CheckPoint val10 = null; GameObject[] rootGameObjects = ((Scene)(ref sceneByName)).GetRootGameObjects(); foreach (GameObject val11 in rootGameObjects) { if ((Object)(object)val6 == (Object)null) { val6 = val11.GetComponentInChildren<StartLine>(true); } if ((Object)(object)val7 == (Object)null) { val7 = val11.GetComponentInChildren<FinishLine>(true); } if ((Object)(object)val8 == (Object)null) { val8 = val11.GetComponentInChildren<EndGamePlatform>(true); } if ((Object)(object)val10 == (Object)null) { val10 = val11.GetComponentInChildren<CheckPoint>(true); } if ((Object)(object)val9 == (Object)null) { val9 = val11.GetComponentInChildren<GravityShapeInfinitePlane>(true); } } if ((Object)(object)val9 != (Object)null) { StockGravity = val9.gravity; ManualLogSource log5 = Plugin.Log; val2 = new BepInExInfoLogInterpolatedStringHandler(24, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Stock gravity sampled: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<float>(StockGravity); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("."); } log5.LogInfo(val2); } rootGameObjects = ((Scene)(ref sceneByName)).GetRootGameObjects(); for (int i = 0; i < rootGameObjects.Length; i++) { LevelTileObject componentInChildren = rootGameObjects[i].GetComponentInChildren<LevelTileObject>(true); if ((Object)(object)componentInChildren == (Object)null) { continue; } Collider componentInChildren2 = ((Component)componentInChildren).GetComponentInChildren<Collider>(true); int layer = ((Component)componentInChildren).gameObject.layer; RoadTileLayer = (((Object)(object)componentInChildren2 != (Object)null) ? ((Component)componentInChildren2).gameObject.layer : layer); MeshRenderer component = ((Component)componentInChildren).GetComponent<MeshRenderer>(); if ((Object)(object)component != (Object)null) { StockRoadMaterials = ((Renderer)component).sharedMaterials; List<string> list = new List<string>(); Material[] stockRoadMaterials = StockRoadMaterials; foreach (Material val12 in stockRoadMaterials) { list.Add(((Object)(object)val12 != (Object)null) ? ((Object)val12).name : "null"); } ManualLogSource log6 = Plugin.Log; val2 = new BepInExInfoLogInterpolatedStringHandler(27, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Stock tile materials ("); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(StockRoadMaterials.Length); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("): ["); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(string.Join(", ", list)); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("]"); } log6.LogInfo(val2); } HarvestRoadPieces(sceneByName, componentInChildren); ManualLogSource log7 = Plugin.Log; val2 = new BepInExInfoLogInterpolatedStringHandler(111, 5, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Stock road: LevelTileObject layer "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(layer); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" ('"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(LayerMask.LayerToName(layer)); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("'), "); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("collider layer "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(RoadTileLayer); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" ('"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(LayerMask.LayerToName(RoadTileLayer)); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("') "); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("on '"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(((Object)(object)componentInChildren2 != (Object)null) ? ((Object)componentInChildren2).name : "no collider"); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("' — custom tiles will use the collider layer."); } log7.LogInfo(val2); break; } if (RoadTileLayer < 0) { Plugin.Log.LogWarning((object)"Could not sample the stock road layer; custom tiles stay on Default and the car's floor raycast may not see them."); } HarvestEnvironment(sceneByName); if ((Object)(object)val6 != (Object)null) { _cachedStartLine = CloneInactive(((Component)val6).gameObject, "SlipSkid_CachedStartLine"); } if ((Object)(object)val7 != (Object)null) { _cachedFinishLine = CloneInactive(((Component)val7).gameObject, "SlipSkid_CachedFinishLine"); } if ((Object)(object)val8 != (Object)null) { _cachedEndGamePlatform = CloneInactive(((Component)val8).gameObject, "SlipSkid_CachedEndGamePlatform"); } if ((Object)(object)val10 != (Object)null) { _cachedCheckpoint = CloneInactive(((Component)val10).gameObject, "SlipSkid_CachedCheckpoint"); } ManualLogSource log8 = Plugin.Log; val2 = new BepInExInfoLogInterpolatedStringHandler(64, 4, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Cached level pieces — startLine:"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<bool>((Object)(object)_cachedStartLine != (Object)null); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" "); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("finishLine:"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<bool>((Object)(object)_cachedFinishLine != (Object)null); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" podium:"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<bool>((Object)(object)_cachedEndGamePlatform != (Object)null); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" "); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("checkpoint:"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<bool>((Object)(object)_cachedCheckpoint != (Object)null); } log8.LogInfo(val2); } AsyncOperation unload = SceneManager.UnloadSceneAsync(sceneByName); if (unload != null) { while (!unload.isDone) { yield return null; } } Plugin.Log.LogInfo((object)"Stock level unloaded; rig harvest complete."); } public static void EnsurePresent() { //IL_0047: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)CameraManager.instance != (Object)null)) { if ((Object)(object)_cachedRig == (Object)null) { Plugin.Log.LogError((object)"No camera rig cached and none in the scene — the level will fail to initialise (CameraManager.SetGlobalVolume null-refs)."); return; } GameObject obj = Object.Instantiate<GameObject>(_cachedRig); ((Object)obj).name = "SlipSkid_CameraRig"; obj.SetActive(true); SceneManager.MoveGameObjectToScene(obj, SceneManager.GetActiveScene()); Plugin.Log.LogInfo((object)"Camera rig instantiated into custom map."); } } } internal static class MapBuilder { private static Material _fogMaterial; internal static readonly HashSet<string> SwappableMaterialNames = new HashSet<string>(StringComparer.OrdinalIgnoreCase); private static int _shadersRebound; private static int _shadersUnresolved; private static int _surfaceSkinned; private static int _stockPiecesPlaced; private static int _loggedFlags; private static Shader _fallbackShader; private const string RoadCombinedLayerName = "RoadCombined"; private const string GeneratedCollisionName = "SlipSkid_GeneratedCollision"; private const string CheckpointLayerName = "CheckPoint"; private static Shader FallbackShader { get { if ((Object)(object)_fallbackShader != (Object)null) { return _fallbackShader; } _fallbackShader = Shader.Find("Universal Render Pipeline/Lit") ?? Shader.Find("Universal Render Pipeline/Simple Lit") ?? Shader.Find("Universal Render Pipeline/Unlit") ?? Shader.Find("Standard"); if ((Object)(object)_fallbackShader == (Object)null) { Plugin.Log.LogError((object)"No usable fallback shader found — imported models will be invisible."); } return _fallbackShader; } } internal static bool SuppressStockMusic { get; private set; } public static bool TryBuild() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Expected O, but got Unknown //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Expected O, but got Unknown MapRoot val = Object.FindObjectOfType<MapRoot>(); if ((Object)(object)val == (Object)null) { SwappableMaterialNames.Clear(); Scene activeScene = SceneManager.GetActiveScene(); GameObject[] rootGameObjects = ((Scene)(ref activeScene)).GetRootGameObjects(); for (int i = 0; i < rootGameObjects.Length; i++) { if (!((Object)(object)rootGameObjects[i].GetComponentInChildren<MeshRenderer>(true) == (Object)null)) { Plugin.Log.LogWarning((object)("Scene '" + ((Scene)(ref activeScene)).name + "' has geometry but no MapRoot. If this is a custom map, its marker scripts failed to resolve — check that SlipSkid.MapSDK.dll sits next to SlipSkid.MapLoader.dll and that the bundle was built against the same version.")); break; } } return false; } if ((Object)(object)Object.FindObjectOfType<LevelDefinition>() != (Object)null) { Plugin.Log.LogInfo((object)"Custom map already has a LevelDefinition; skipping build."); return true; } ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(42, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Building custom map '"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(val.mapName); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("' from SDK markers..."); } log.LogInfo(val2); SwappableMaterialNames.Clear(); LevelRigHarvester.EnsurePresent(); GameObject gameObject = ((Component)val).gameObject; LevelDefinition val3 = gameObject.AddComponent<LevelDefinition>(); Surface val4 = ResolveSurface(val.defaultSurfaceIndex); if ((Object)(object)val4 == (Object)null) { Plugin.Log.LogError((object)"No Surface available from SurfaceManager; cannot build map."); return false; } BuildTiles(val, val4, val3); BuildCollisionMeshes(val); BuildBoostPads(val); BuildMusic(val); BuildLighting(gameObject, val3); BuildEnvironment(gameObject, val3, val4); BuildStartFinish(val, val3); BuildEndGamePlatform(val, val3); BuildSpawner(val); BuildGravity(val); BuildCheckpoints(val, val3); val3.surfaceToIgnoreDuringCount = (Surface[])(object)new Surface[0]; val3.defaultSurfaceTileCount = val4; BuildObstacleLevelDefinition(gameObject); ManualLogSource log2 = Plugin.Log; val2 = new BepInExInfoLogInterpolatedStringHandler(39, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Custom map built: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(val3.tiles.Count); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" tiles, "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(val3.checkpoints.Count); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" checkpoints."); } log2.LogInfo(val2); ValidateMap(val3); ReportCollision(val); return true; } private static void ReportCollision(MapRoot root) { int num = LayerMask.NameToLayer("RoadCombined"); int num2 = 0; int num3 = 0; Collider[] componentsInChildren = ((Component)root).GetComponentsInChildren<Collider>(true); foreach (Collider val in componentsInChildren) { if (!val.isTrigger && val.enabled && ((Component)val).gameObject.activeInHierarchy) { if (((Component)val).gameObject.layer == num) { num2++; } else { num3++; } } } if (num2 == 0) { Plugin.Log.LogError((object)"No collider on the 'RoadCombined' layer — the car will fall through this map. Every collidable mesh needs a MapCollisionMesh child."); } if (num3 == 0) { Plugin.Log.LogWarning((object)"No colliders off the RoadCombined layer — the car's floor raycast has nothing to hit, so it will never count as grounded."); } } private static void ValidateMap(LevelDefinition def) { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_005c: 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_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) if (def.tiles.Count == 0) { Plugin.Log.LogError((object)"Map has no road tiles — add MapRoadTile components to your track."); return; } RandomPositionPlayerSpawner spawner = GameManager.Spawner; if ((Object)(object)spawner == (Object)null || spawner.SpawnCount == 0) { Plugin.Log.LogError((object)"Map has no spawn points — add a MapSpawnPoints marker."); return; } Transform spawnPoint = spawner.GetSpawnPoint(0); RaycastHit val = default(RaycastHit); if (!Physics.Raycast(spawnPoint.position + Vector3.up * 5f, Vector3.down, ref val, 200f, -1, (QueryTriggerInteraction)1)) { Plugin.Log.LogError((object)($"No track under the first spawn point ({spawnPoint.position}) — the car will fall. " + "Move the MapSpawnPoints marker onto the road.")); } } private static void BuildObstacleLevelDefinition(GameObject parent) { if (!((Object)(object)Object.FindObjectOfType<ObstacleLevelDefinition>() != (Object)null)) { ObstacleLevelDefinition component = parent.GetComponent<ObstacleLevelDefinition>(); (((Object)(object)component != (Object)null) ? component : parent.AddComponent<ObstacleLevelDefinition>()).forbiddenObstacleZones = (BoxCollider[])(object)new BoxCollider[0]; Plugin.Log.LogInfo((object)"Added ObstacleLevelDefinition (required by ObstacleManager.InitLevel)."); } } private static Surface ResolveSurface(int index) { Surface[] array = SurfaceManager.Surfaces; if (array == null || array.Length == 0) { SurfaceManager val = Object.FindObjectOfType<SurfaceManager>(); array = (((Object)(object)val != (Object)null) ? val.surfaces : null); } if (array == null || array.Length == 0) { return null; } if (index < 0 || index >= array.Length) { index = 0; } return array[index]; } private static void BuildTiles(MapRoot root, Surface defaultSurface, LevelDefinition def) { //IL_0271: Unknown result type (might be due to invalid IL or missing references) //IL_0278: Expected O, but got Unknown //IL_0235: Unknown result type (might be due to invalid IL or missing references) //IL_023c: Expected O, but got Unknown //IL_02b9: Unknown result type (might be due to invalid IL or missing references) //IL_02c0: Expected O, but got Unknown //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Expected O, but got Unknown MapRoadTile[] componentsInChildren = ((Component)root).GetComponentsInChildren<MapRoadTile>(true); def.tiles = new List<LevelTileObject>(); int num = 0; _shadersRebound = 0; _shadersUnresolved = 0; _surfaceSkinned = 0; _stockPiecesPlaced = 0; _loggedFlags = 0; MapRoadTile[] array = componentsInChildren; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val2; foreach (MapRoadTile val in array) { Surface surface = ((val.surfaceIndex >= 0) ? (ResolveSurface(val.surfaceIndex) ?? defaultSurface) : defaultSurface); if (_loggedFlags < 3) { ManualLogSource log = Plugin.Log; val2 = new BepInExInfoLogInterpolatedStringHandler(51, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Tile '"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(((Object)val).name); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("': useStockRoadPiece="); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<bool>(val.useStockRoadPiece); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" "); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("useGameSurfaceMaterial="); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<bool>(val.useGameSurfaceMaterial); } log.LogInfo(val2); _loggedFlags++; } if (val.useStockRoadPiece && LevelRigHarvester.HasRoadPieces && PlaceStockRoadPiece(val, def, surface)) { continue; } Collider[] componentsInChildren2 = ((Component)val).GetComponentsInChildren<Collider>(true); if (componentsInChildren2.Length == 0) { num++; continue; } Collider[] array2 = componentsInChildren2; foreach (Collider val3 in array2) { if (!val3.isTrigger && !((Object)(object)((Component)val3).GetComponentInParent<MapRoadBorder>() != (Object)null) && !((Object)(object)((Component)val3).GetComponent<MapCollisionMesh>() != (Object)null)) { GameObject gameObject = ((Component)val3).gameObject; if (LevelRigHarvester.RoadTileLayer >= 0) { gameObject.layer = LevelRigHarvester.RoadTileLayer; } (gameObject.GetComponent<SurfaceInfo>() ?? gameObject.AddComponent<SurfaceInfo>()).surface = surface; if (val.useGameSurfaceMaterial) { ApplySurfaceMaterial(gameObject, surface); } else { RebindShaders(gameObject); } RegisterSwappableMaterials(gameObject); LevelTileObject val4 = gameObject.GetComponent<LevelTileObject>() ?? gameObject.AddComponent<LevelTileObject>(); val4.id = MakeGuid(val, gameObject); MeshFilter component = gameObject.GetComponent<MeshFilter>(); if ((Object)(object)component != (Object)null) { val4.nonBatchedMesh = component.sharedMesh; } ForceStart((MonoBehaviour)(object)val4); def.tiles.Add(val4); } } } if (num > 0) { ManualLogSource log2 = Plugin.Log; BepInExWarningLogInterpolatedStringHandler val5 = new BepInExWarningLogInterpolatedStringHandler(80, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<int>(num); ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(" MapRoadTile(s) had no collider and were skipped — cars would fall through them."); } log2.LogWarning(val5); } SkinBorders(root); RebindAllImportedShaders(root); ManualLogSource log3 = Plugin.Log; val2 = new BepInExInfoLogInterpolatedStringHandler(58, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Surface swap: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(SwappableMaterialNames.Count); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" material name(s) registered as repaintable."); } log3.LogInfo(val2); ManualLogSource log4 = Plugin.Log; val2 = new BepInExInfoLogInterpolatedStringHandler(135, 4, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Road: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(_stockPiecesPlaced); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" real shipped piece(s) placed; "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(_surfaceSkinned); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" renderer(s) given the game's surface material; "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(_shadersRebound); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" authored material(s) shader-rebound, "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(_shadersUnresolved); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" unresolved."); } log4.LogInfo(val2); } private static void RegisterSwappableMaterials(GameObject host) { MeshRenderer component = host.GetComponent<MeshRenderer>(); if ((Object)(object)component == (Object)null) { return; } Material[] sharedMaterials = ((Renderer)component).sharedMaterials; foreach (Material val in sharedMaterials) { if (!((Object)(object)val == (Object)null) && !string.IsNullOrEmpty(((Object)val).name)) { SwappableMaterialNames.Add(((Object)val).name); } } } private static SerializableGuid MakeGuid(MapRoadTile marker, GameObject host) { //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Expected O, but got Unknown string text = (string.IsNullOrEmpty(marker.tileGuid) ? BuildPath(((Component)marker).transform) : marker.tileGuid); if ((Object)(object)host != (Object)(object)((Component)marker).gameObject) { text = text + "/" + BuildPath(host.transform); } return new SerializableGuid(DeterministicGuid(text)); } private static string BuildPath(Transform t) { string text = ((Object)t).name; while ((Object)(object)t.parent != (Object)null) { t = t.parent; text = ((Object)t).name + "/" + text; } return text; } private static void RebindAllImportedShaders(MapRoot root) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_01cb: Expected O, but got Unknown //IL_00c2: 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_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_0152: 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) int num = 0; int num2 = 0; List<MeshRenderer> list = new List<MeshRenderer>(); Scene scene = ((Component)root).gameObject.scene; GameObject[] rootGameObjects = ((Scene)(ref scene)).GetRootGameObjects(); foreach (GameObject val in rootGameObjects) { list.AddRange(val.GetComponentsInChildren<MeshRenderer>(true)); } foreach (MeshRenderer item in list) { Material[] materials = ((Renderer)item).materials; bool flag = false; foreach (Material val2 in materials) { if ((Object)(object)val2 == (Object)null || (Object)(object)val2.shader == (Object)null) { continue; } if ((Object)(object)Shader.Find(((Object)val2.shader).name) != (Object)null) { num2++; continue; } Texture val3 = FirstTexture(val2); Color val4 = FirstColor(val2); Shader fallbackShader = FallbackShader; if ((Object)(object)fallbackShader == (Object)null) { continue; } val2.shader = fallbackShader; if ((Object)(object)val3 != (Object)null) { if (val2.HasProperty("_BaseMap")) { val2.SetTexture("_BaseMap", val3); } if (val2.HasProperty("_MainTex")) { val2.SetTexture("_MainTex", val3); } } if (((Color)(ref val4)).maxColorComponent < 0.05f) { val4 = Color.white; } if (val2.HasProperty("_BaseColor")) { val2.SetColor("_BaseColor", val4); } if (val2.HasProperty("_Color")) { val2.SetColor("_Color", val4); } flag = true; num++; } if (flag) { ((Renderer)item).materials = materials; } } if (num > 0) { ManualLogSource log = Plugin.Log; bool flag2 = default(bool); BepInExInfoLogInterpolatedStringHandler val5 = new BepInExInfoLogInterpolatedStringHandler(62, 3, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("Imported shaders: "); ((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<int>(num); ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(" material(s) remapped to '"); ((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<string>(((Object)FallbackShader).name); ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("', "); ((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<int>(num2); ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(" already valid."); } log.LogInfo(val5); } } private static Texture FirstTexture(Material mat) { string[] array = new string[5] { "_BaseMap", "_MainTex", "baseColorTexture", "_BaseColorTexture", "_albedoTexture" }; foreach (string text in array) { if (mat.HasProperty(text)) { Texture texture = mat.GetTexture(text); if ((Object)(object)texture != (Object)null) { return texture; } } } return null; } private static Color FirstColor(Material mat) { //IL_004a: 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) string[] array = new string[4] { "_BaseColor", "_Color", "baseColorFactor", "_BaseColorFactor" }; foreach (string text in array) { if (mat.HasProperty(text)) { return mat.GetColor(text); } } return Color.white; } private static bool PlaceStockRoadPiece(MapRoadTile marker, LevelDefinition def, Surface surface) { //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_005c: 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_0083: 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_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //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_00ef: Unknown result type (might be due to invalid IL or missing references) GameObject val = LevelRigHarvester.RoadPiecePrefabs[0]; if ((Object)(object)val == (Object)null) { return false; } GameObject val2 = Object.Instantiate<GameObject>(val); ((Object)val2).name = "StockRoadPiece_" + ((Object)marker).name; val2.transform.SetParent(((Component)marker).transform, false); val2.transform.localPosition = Vector3.zero; val2.transform.localRotation = Quaternion.identity; MeshRenderer component = ((Component)marker).GetComponent<MeshRenderer>(); float num; Bounds bounds; if (!((Object)(object)component != (Object)null)) { num = 0f; } else { bounds = ((Renderer)component).bounds; num = ((Bounds)(ref bounds)).size.z; } float num2 = num; MeshRenderer componentInChildren = val2.GetComponentInChildren<MeshRenderer>(true); if ((Object)(object)componentInChildren != (Object)null && num2 > 0.01f) { bounds = ((Renderer)componentInChildren).bounds; float z = ((Bounds)(ref bounds)).size.z; if (z > 0.01f) { Vector3 localScale = val2.transform.localScale; localScale.z *= num2 / z; val2.transform.localScale = localScale; } } MeshRenderer[] componentsInChildren = val2.GetComponentsInChildren<MeshRenderer>(true); foreach (MeshRenderer obj in componentsInChildren) { ((Renderer)obj).shadowCastingMode = (ShadowCastingMode)1; ((Renderer)obj).receiveShadows = true; } val2.SetActive(true); componentsInChildren = ((Component)marker).GetComponents<MeshRenderer>(); for (int i = 0; i < componentsInChildren.Length; i++) { ((Renderer)componentsInChildren[i]).enabled = false; } Collider[] componentsInChildren2 = val2.GetComponentsInChildren<Collider>(true); foreach (Collider val3 in componentsInChildren2) { if (!val3.isTrigger && !((Object)(object)((Component)val3).GetComponentInParent<MapRoadBorder>() != (Object)null)) { GameObject gameObject = ((Component)val3).gameObject; if (LevelRigHarvester.RoadTileLayer >= 0) { gameObject.layer = LevelRigHarvester.RoadTileLayer; } (gameObject.GetComponent<SurfaceInfo>() ?? gameObject.AddComponent<SurfaceInfo>()).surface = surface; LevelTileObject val4 = gameObject.GetComponent<LevelTileObject>() ?? gameObject.AddComponent<LevelTileObject>(); val4.id = MakeGuid(marker, gameObject); MeshFilter component2 = gameObject.GetComponent<MeshFilter>(); if ((Object)(object)component2 != (Object)null) { val4.nonBatchedMesh = component2.sharedMesh; } ForceStart((MonoBehaviour)(object)val4); def.tiles.Add(val4); } } _stockPiecesPlaced++; return true; } private static void SkinBorders(MapRoot root) { //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Expected O, but got Unknown MapRoadBorder[] componentsInChildren = ((Component)root).GetComponentsInChildren<MapRoadBorder>(true); if (componentsInChildren.Length == 0) { return; } Material borderMaterial = LevelRigHarvester.BorderMaterial; int num = 0; MapRoadBorder[] array = componentsInChildren; for (int i = 0; i < array.Length; i++) { MeshRenderer[] componentsInChildren2 = ((Component)array[i]).GetComponentsInChildren<MeshRenderer>(true); foreach (MeshRenderer val in componentsInChildren2) { if ((Object)(object)borderMaterial != (Object)null) { Material[] materials = ((Renderer)val).materials; for (int k = 0; k < materials.Length; k++) { materials[k] = borderMaterial; } ((Renderer)val).materials = materials; } else { RebindShaders(((Component)val).gameObject); } if (LevelRigHarvester.RoadTileLayer >= 0) { ((Component)val).gameObject.layer = LevelRigHarvester.RoadTileLayer; } num++; } } ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(38, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Borders: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(num); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" renderer(s) skinned with "); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("'"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(((Object)(object)borderMaterial != (Object)null) ? ((Object)borderMaterial).name : "authored material"); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("'."); } log.LogInfo(val2); } private static void ApplySurfaceMaterial(GameObject host, Surface surface) { Material val = (((Object)(object)surface != (Object)null && surface.effects != null) ? surface.effects.material : null); if ((Object)(object)val == (Object)null) { RebindShaders(host); return; } Material[] stockRoadMaterials = LevelRigHarvester.StockRoadMaterials; MeshRenderer[] components = host.GetComponents<MeshRenderer>(); foreach (MeshRenderer val2 in components) { Material[] sharedMaterials = ((Renderer)val2).sharedMaterials; for (int j = 0; j < sharedMaterials.Length; j++) { if (j == 0 || stockRoadMaterials == null || j >= stockRoadMaterials.Length) { sharedMaterials[j] = val; } else { sharedMaterials[j] = stockRoadMaterials[j] ?? val; } } ((Renderer)val2).materials = sharedMaterials; _surfaceSkinned++; } } private static void RebindShaders(GameObject host) { //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_00fe: 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) MeshRenderer[] components = host.GetComponents<MeshRenderer>(); foreach (MeshRenderer val in components) { Material[] materials = ((Renderer)val).materials; Material[] array = materials; foreach (Material val2 in array) { if ((Object)(object)val2 == (Object)null || (Object)(object)val2.shader == (Object)null) { continue; } Shader val3 = Shader.Find(((Object)val2.shader).name); if ((Object)(object)val3 == (Object)null) { val3 = FallbackShader; if ((Object)(object)val3 == (Object)null) { _shadersUnresolved++; continue; } Texture val4 = FirstTexture(val2); Color val5 = FirstColor(val2); val2.shader = val3; if ((Object)(object)val4 != (Object)null) { if (val2.HasProperty("_BaseMap")) { val2.SetTexture("_BaseMap", val4); } if (val2.HasProperty("_MainTex")) { val2.SetTexture("_MainTex", val4); } } if (val2.HasProperty("_BaseColor")) { val2.SetColor("_BaseColor", val5); } if (val2.HasProperty("_Color")) { val2.SetColor("_Color", val5); } _shadersRebound++; } else if (!((Object)(object)val3 == (Object)(object)val2.shader)) { val2.shader = val3; _shadersRebound++; } } ((Renderer)val).materials = materials; } } private static void ForceStart(MonoBehaviour behaviour) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Expected O, but got Unknown MethodInfo method = ((object)behaviour).GetType().GetMethod("Start", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (method == null) { return; } try { method.Invoke(behaviour, null); } catch (Exception ex) { ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(28, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Forcing Start() on "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(((object)behaviour).GetType().Name); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message); } log.LogWarning(val); } } private static Guid DeterministicGuid(string seed) { using MD5 mD = MD5.Create(); return new Guid(mD.ComputeHash(Encoding.UTF8.GetBytes(seed))); } private static void BuildLighting(GameObject parent, LevelDefinition def) { //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Expected O, but got Unknown //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Invalid comparison between Unknown and I4 LevelLighting componentInChildren = parent.GetComponentInChildren<LevelLighting>(true); if ((Object)(object)componentInChildren != (Object)null) { def.levelLighting = componentInChildren; return; } Light[] array = Object.FindObjectsOfType<Light>(); List<Light> list = new List<Light>(); Light[] array2 = array; foreach (Light val in array2) { if ((Object)(object)val != (Object)null && (int)val.type == 1) { list.Add(val); } } GameObject val2 = new GameObject("LevelLighting"); val2.transform.SetParent(parent.transform, false); LevelLighting val3 = val2.AddComponent<LevelLighting>(); if (list.Count >= 3) { val3.mainLight = list[0]; val3.secondaryLight = list[1]; val3.thirdLight = list[2]; } else { Plugin.Log.LogWarning((object)($"Map authored {list.Count} directional light(s); 3 are required. " + "Falling back to generated lights — these cannot be made directional because Light.type is stripped from this build, so lighting will look wrong.")); val3.mainLight = FallbackLight(val2.transform, "MainLight", list, 0); val3.secondaryLight = FallbackLight(val2.transform, "SecondaryLight", list, 1); val3.thirdLight = FallbackLight(val2.transform, "ThirdLight", list, 2); } def.levelLighting = val3; } private static Light FallbackLight(Transform parent, string name, List<Light> authored, int index) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) if (index < authored.Count) { return authored[index]; } GameObject val = new GameObject(name); val.transform.SetParent(parent, false); return val.AddComponent<Light>(); } private static void BuildEnvironment(GameObject parent, LevelDefinition def, Surface surface) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Expected O, but got Unknown GameObject val = new GameObject("EnvironmentVisualRoot"); val.transform.SetParent(parent.transform, false); def.environmentVisualRoot = val.transform; def.fogPlane = BuildFogPlane(parent.transform); if (LevelRigHarvester.HasEnvironment) { LevelEnvironmentBiome val2 = ResolveForcedBiome(parent, surface); def.environmentBiomes = (((Object)(object)val2 != (Object)null) ? new List<LevelEnvironmentBiome> { val2 } : new List<LevelEnvironmentBiome>(LevelRigHarvester.StockBiomes)); def.rushModeEnvironmentBiome = LevelRigHarvester.StockRushBiome ?? MakeBiome(surface, rush: true); ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(48, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("Using "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<int>(def.environmentBiomes.Count); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" shipped environment biome(s) for scenery."); } log.LogInfo(val3); } else { Plugin.Log.LogWarning((object)"No shipped biomes harvested — falling back to empty scenery. The map will render against a bare background."); def.environmentBiomes = new List<LevelEnvironmentBiome> { MakeBiome(surface, rush: false) }; def.rushModeEnvironmentBiome = MakeBiome(surface, rush: true); } } private static LevelEnvironmentBiome ResolveForcedBiome(GameObject parent, Surface surface) { //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Expected O, but got Unknown MapRoot component = parent.GetComponent<MapRoot>(); string text = (((Object)(object)component != (Object)null) ? component.forceEnvironmentBiome : null); if (string.IsNullOrEmpty(text)) { return null; } LevelEnvironmentBiome val = null; foreach (LevelEnvironmentBiome stockBiome in LevelRigHarvester.StockBiomes) { if (!((Object)(object)stockBiome == (Object)null) && ((Object)stockBiome).name != null && ((Object)stockBiome).name.IndexOf(text, StringComparison.OrdinalIgnoreCase) >= 0) { val = stockBiome; break; } } if ((Object)(object)val == (Object)null) { List<string> list = new List<string>(); foreach (LevelEnvironmentBiome stockBiome2 in LevelRigHarvester.StockBiomes) { if ((Object)(object)stockBiome2 != (Object)null) { list.Add(((Object)stockBiome2).name); } } ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(100, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("forceEnvironmentBiome '"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(text); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("' matched no shipped biome. "); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Available: ["); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(string.Join(", ", list)); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("]. Falling back to automatic scenery."); } log.LogWarning(val2); return null; } LevelEnvironmentBiome val3 = Object.Instantiate<LevelEnvironmentBiome>(val); ((Object)val3).name = ((Object)val).name + " (forced)"; val3.matchingSurface = surface; Plugin.Log.LogInfo((object)("Forcing scenery to '" + ((Object)val).name + "' on surface '" + ((Object)surface).name + "' (handling unchanged).")); return val3; } private static MeshRenderer BuildFogPlane(Transform parent) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0052: 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_006c: Unknown result type (might be due to invalid IL or missing references) GameObject obj = GameObject.CreatePrimitive((PrimitiveType)5); ((Object)obj).name = "FogPlane"; obj.transform.SetParent(parent, false); obj.transform.localPosition = new Vector3(0f, -60f, 0f); obj.transform.localRotation = Quaternion.Euler(90f, 0f, 0f); obj.transform.localScale = Vector3.one * 2000f; Collider component = obj.GetComponent<Collider>(); if ((Object)(object)component != (Object)null) { Object.Destroy((Object)(object)component); } MeshRenderer component2 = obj.GetComponent<MeshRenderer>(); Material stockFogMaterial = LevelRigHarvester.StockFogMaterial; if ((Object)(object)stockFogMaterial != (Object)null) { ((Renderer)component2).sharedMaterial = stockFogMaterial; ((Renderer)component2).enabled = true; } else { ((Renderer)component2).enabled = false; } return component2; } private static LevelEnvironmentBiome MakeBiome(Surface surface, bool rush) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0028: 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_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Expected O, but got Unknown //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Expected O, but got Unknown //IL_00bb: Expected O, but got Unknown LevelEnvironmentBiome val = ScriptableObject.CreateInstance<LevelEnvironmentBiome>(); ((Object)val).hideFlags = (HideFlags)61; val.matchingSurface = surface; val.fogColor = (rush ? new Color(0.85f, 0.35f, 0.45f) : new Color(0.45f, 0.55f, 0.85f)); val.fogStartDistance = 120f; val.fogEndDistance = 700f; val.fogPlaneMaterial = GetFogMaterial(); GameObject val2 = new GameObject(rush ? "RushBiomeVisuals" : "BiomeVisuals"); val2.SetActive(false); Object.DontDestroyOnLoad((Object)(object)val2); if (rush) { RushModeEnvironmentBiome val3 = val2.AddComponent<RushModeEnvironmentBiome>(); val3.subEnvironmentBiomes = (SubEnvironmentBiomes[])(object)new SubEnvironmentBiomes[1] { new SubEnvironmentBiomes { surface = surface, gameObject = new GameObject("SubBiome") } }; val3.subEnvironmentBiomes[0].gameObject.transform.SetParent(val2.transform, false); } val.prefabToInstantiate = val2; return val; } private static Material GetFogMaterial() { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but got Unknown if ((Object)(object)_fogMaterial != (Object)null) { return _fogMaterial; } _fogMaterial = new Material(Shader.Find("Universal Render Pipeline/Unlit") ?? Shader.Find("Unlit/Color")) { hideFlags = (HideFlags)61 }; return _fogMaterial; } private static void BuildStartFinish(MapRoot root, LevelDefinition def) { MapStartLine componentInChildren = ((Component)root).GetComponentInChildren<MapStartLine>(true); MapFinishLine componentInChildren2 = ((Component)root).GetComponentInChildren<MapFinishLine>(true); def.startLine = PlaceCloned<StartLine>(LevelRigHarvester.StartLinePrefab, ((Object)(object)componentInChildren != (Object)null) ? ((Component)componentInChildren).transform : ((Component)root).transform, ((Component)root).transform, "StartLine"); def.finishLine = PlaceCloned<FinishLine>(LevelRigHarvester.FinishLinePrefab, ((Object)(object)componentInChildren2 != (Object)null) ? ((Component)componentInChildren2).transform : ((Component)root).transform, ((Component)root).transform, "FinishLine"); if ((Object)(object)def.startLine == (Object)null || (Object)(object)def.finishLine == (Object)null) { Plugin.Log.LogError((object)"Start or finish line could not be cloned from a shipped level — the level will not initialise correctly."); } } private static T PlaceCloned<T>(GameObject prefab, Transform at, Transform parent, string name) where T : Component { //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown if ((Object)(object)prefab == (Object)null) { ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(32, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("No cached prefab available for "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(name); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("."); } log.LogError(val); return default(T); } GameObject obj = Object.Instantiate<GameObject>(prefab); ((Object)obj).name = name; obj.transform.SetParent(parent, false); obj.transform.position = at.position; obj.transform.rotation = at.rotation; obj.SetActive(true); return obj.GetComponentInChildren<T>(true); } private static void BuildEndGamePlatform(MapRoot root, LevelDefinition def) { MapEndGamePlatform componentInChildren = ((Component)root).GetComponentInChildren<MapEndGamePlatform>(true); Transform at = (((Object)(object)componentInChildren != (Object)null) ? ((Component)componentInChildren).transform : ((Component)root).transform); def.endGamePlatform = PlaceCloned<EndGamePlatform>(LevelRigHarvester.EndGamePlatformPrefab, at, ((Component)root).transform, "EndGamePlatform"); if ((Object)(object)def.endGamePlatform == (Object)null) { Plugin.Log.LogWarning((object)"No end-game platform available; finishing a race may fail."); } } private static void BuildSpawner(MapRoot root) { //IL_00ac: Unknown result type (might be due to invalid IL or missing references) MapSpawnPoints componentInChildren = ((Component)root).GetComponentInChildren<MapSpawnPoints>(true); GameObject val = (((Object)(object)componentInChildren != (Object)null) ? ((Component)componentInChildren).gameObject : NewChild(((Component)root).transform, "PlayerSpawner")); RandomPositionPlayerSpawner val2 = val.GetComponent<RandomPositionPlayerSpawner>() ?? val.AddComponent<RandomPositionPlayerSpawner>(); List<Transform> list = (((Object)(object)componentInChildren != (Object)null) ? componentInChildren.Resolve() : new List<Transform>()); if (list.Count == 0) { Plugin.Log.LogWarning((object)"Map has no spawn points; generating a default row of 4."); for (int i = 0; i < 4; i++) { GameObject val3 = NewChild(val.transform, $"SpawnPoint_{i}"); val3.transform.localPosition = new Vector3(((float)i - 1.5f) * 4f, 1f, 0f); list.Add(val3.transform); } } SetPrivateList(val2, "spawnPositions", list); if ((Object)(object)componentInChildren != (Object)null && (Object)(object)componentInChildren.timeTrialSpawn != (Object)null) { val2.timeTrialSpawn = componentInChildren.timeTrialSpawn; } else if (list.Count > 0) { val2.timeTrialSpawn = list[0]; } } private static void BuildCollisionMeshes(MapRoot root) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Expected O, but got Unknown List<MapCollisionMesh> list = new List<MapCollisionMesh>(); Scene scene = ((Component)root).gameObject.scene; GameObject[] rootGameObjects = ((Scene)(ref scene)).GetRootGameObjects(); foreach (GameObject val in rootGameObjects) { list.AddRange(val.GetComponentsInChildren<MapCollisionMesh>(true)); } int num = LayerMask.NameToLayer("RoadCombined"); if (num < 0) { Plugin.Log.LogError((object)"No 'RoadCombined' layer in this build — the car will fall through this map. Collision geometry left on its authored layer."); return; } foreach (MapCollisionMesh item in list) { ((Component)item).gameObject.layer = num; } int num2 = GenerateMissingCollision(root, num); ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(76, 4, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Collision: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(list.Count); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" authored mesh(es) moved to layer "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(num); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" "); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("('"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>("RoadCombined"); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("'), "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(num2); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" generated at load time."); } log.LogInfo(val2); } private static int GenerateMissingCollision(MapRoot root, int layer) { //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0141: 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) if (layer < 0) { return 0; } List<Collider> list = new List<Collider>(); Collider[] componentsInChildren = ((Component)root).GetComponentsInChildren<Collider>(true); foreach (Collider val in componentsInChildren) { if (!val.isTrigger && val.enabled && ((Component)val).gameObject.activeInHierarchy && ((Component)val).gameObject.layer != layer && !((Object)(object)((Component)val).GetComponent<MapCollisionMesh>() != (Object)null) && !HasCollisionChild(((Component)val).transform, layer)) { list.Add(val); } } int num = 0; foreach (Collider item in list) { GameObject val2 = Object.Instantiate<GameObject>(((Component)item).gameObject, ((Component)item).transform); ((Object)val2).name = "SlipSkid_GeneratedCollision"; val2.layer = layer; for (int num2 = val2.transform.childCount - 1; num2 >= 0; num2--) { Object.Destroy((Object)(object)((Component)val2.transform.GetChild(num2)).gameObject); } Component[] components = val2.GetComponents<Component>(); foreach (Component val3 in components) { if (!(val3 is Transform) && !(val3 is Collider)) { Object.Destroy((Object)(object)val3); } } val2.transform.localPosition = Vector3.zero; val2.transform.localRotation = Quaternion.identity; val2.transform.localScale = Vector3.one; num++; } return num; } private static bool HasCollisionChild(Transform parent, int layer) { for (int i = 0; i < parent.childCount; i++) { Transform child = parent.GetChild(i); if ((Object)(object)((Component)child).GetComponent<MapCollisionMesh>() != (Object)null) { return true; } if (((Component)child).gameObject.layer == layer && (Object)(object)((Component)child).GetComponent<Collider>() != (Object)null) { return true; } } return false; } private static void BuildBoostPads(MapRoot root) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_02d6: Unknown result type (might be due to invalid IL or missing references) //IL_02dd: Expected O, but got Unknown //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Expected O, but got Unknown //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_01f6: Unknown result type (might be due to invalid IL or missing references) //IL_021a: Unknown result type (might be due to invalid IL or missing references) //IL_023e: Unknown result type (might be due to invalid IL or missing references) List<MapBoostPad> list = new List<MapBoostPad>(); Scene scene = ((Component)root).gameObject.scene; GameObject[] rootGameObjects = ((Scene)(ref scene)).GetRootGameObjects(); foreach (GameObject val in rootGameObjects) { list.AddRange(val.GetComponentsInChildren<MapBoostPad>(true)); } if (list.Count == 0) { return; } int num = LayerMask.NameToLayer("RoadCombined"); int num2 = 0; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val2; foreach (MapBoostPad item in list) { BoxCollider component = ((Component)item).GetComponent<BoxCollider>(); if ((Object)(object)component == (Object)null) { Plugin.Log.LogWarning((object)("Boost pad '" + ((Object)item).name + "' has no BoxCollider; skipping. AccelerationZone needs a box trigger to measure itself against.")); continue; } ((Collider)component).isTrigger = true; if (num >= 0) { ((Component)item).gameObject.layer = num; } if (item.capAtBoostSpeed) { AccelerationZone obj = ((Component)item).GetComponent<AccelerationZone>() ?? ((Component)item).gameObject.AddComponent<AccelerationZone>(); obj.trigger = component; obj.setVelocityOnEnter = true; obj.velocityOnEnter = item.boostSpeed; obj.acceleration = item.continuousAcceleration; obj.dynamicResize = false; } else { (((Component)item).GetComponent<BoostPadZone>() ?? ((Component)item).gameObject.AddComponent<BoostPadZone>()).boostSpeed = item.boostSpeed; } Bounds bounds = ((Collider)component).bounds; ManualLogSource log = Plugin.Log; val2 = new BepInExInfoLogInterpolatedStringHandler(44, 9, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" boost pad '"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(((Object)item).name); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("' at ("); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<float>(((Bounds)(ref bounds)).center.x, "0.0"); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<float>(((Bounds)(ref bounds)).center.y, "0.0"); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<float>(((Bounds)(ref bounds)).center.z, "0.0"); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(") "); ((BepInExLogInterpolatedStringHan
BepInEx/plugins/SlipSkid.MapLoader/SlipSkid.MapSDK.dll
Decompiled 6 hours agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("SlipSkid.MapSDK")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("SlipSkid.MapSDK")] [assembly: AssemblyTitle("SlipSkid.MapSDK")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace SlipSkid.MapSDK { [AddComponentMenu("Slip & Skid/Map Root")] public class MapRoot : MonoBehaviour { [Header("Identity")] public string mapName = "My Map"; public string author = ""; [Range(1f, 5f)] public int difficulty = 1; [Tooltip("Lets the Random level picker run this map in reverse.")] public bool isReversible; [Header("Environment")] [Tooltip("Index into the game's SurfaceManager.surfaces, used when a road tile doesn't pick its own. Surfaces are global and networked by index, so maps have to reuse the game's rather than ship their own.")] public int defaultSurfaceIndex; [Tooltip("Copy biome and lighting from this stock level. Empty = the first one.")] public string biomeFromLevel = ""; [Tooltip("Force the backdrop scenery regardless of what the track is made of. Matched loosely against the stock biome names: Asphalt, Dirt, Ice, Magma, Mud, Sand. Empty = picked from the dominant surface.\n\nThis is how you get desert scenery on an asphalt track. Choosing it through the surface instead would also change how the car handles.")] public string forceEnvironmentBiome = ""; } [AddComponentMenu("Slip & Skid/Road Tile")] public class MapRoadTile : MonoBehaviour { [Tooltip("-1 = use the map's default. Otherwise an index into SurfaceManager.surfaces.")] public int surfaceIndex = -1; [Tooltip("Stable unique id, filled in automatically. Surface swaps are networked by this GUID, so changing it between builds desyncs clients.")] public string tileGuid = ""; [Tooltip("Swap this tile's geometry for a real road piece taken from a stock level. The tile's own mesh becomes placement data only; the piece brings the game's mesh, borders and materials with it.")] public bool useStockRoadPiece = true; [Tooltip("Skin this tile with the game's own surface material. Recommended: the surface-swap mechanic matches materials by name, so a tile that keeps a custom material never changes surface with the rest of the track. Uncheck for decorative geometry.")] public bool useGameSurfaceMaterial = true; private void Reset() { if (string.IsNullOrEmpty(tileGuid)) { tileGuid = Guid.NewGuid().ToString(); } } } [AddComponentMenu("Slip & Skid/Road Border")] public class MapRoadBorder : MonoBehaviour { } [AddComponentMenu("Slip & Skid/Boost Pad")] public class MapBoostPad : MonoBehaviour { [Tooltip("Speed added along the car's forward when you drive onto the pad.")] public float boostSpeed = 15f; [Tooltip("ON: the game's own behaviour, where Boost Speed is a TARGET and nothing happens if you're already faster. Values below cruising speed do nothing.\n\nOFF (default): Boost Speed is always added, so small values give a small nudge and the pad still helps at top speed.")] public bool capAtBoostSpeed; [Tooltip("Continuous push while the car is on the pad, along the PAD's forward. Zero by default: imported meshes rarely face down the track, and a non-zero value here shoves cars sideways.")] public float continuousAcceleration; } [AddComponentMenu("Slip & Skid/Map Music")] [RequireComponent(typeof(AudioSource))] public class MapMusic : MonoBehaviour { [Tooltip("Play instead of the game's racing track while this map is loaded.")] public bool replaceStockMusic = true; [Tooltip("Route through the game's music mixer so the volume setting applies. Off = full volume regardless of settings.")] public bool useGameMusicVolume = true; [Tooltip("Fade this music out while the game plays one of its own tracks, such as the obstacle picker or the scoreboard, and fade back in for the race. Off = both play at once.")] public bool duckForGameMusic = true; [Tooltip("How long the fade takes, in seconds.")] public float fadeSeconds = 1.5f; } [AddComponentMenu("Slip & Skid/Collision Mesh")] public class MapCollisionMesh : MonoBehaviour { } [AddComponentMenu("Slip & Skid/Start Line")] public class MapStartLine : MonoBehaviour { } [AddComponentMenu("Slip & Skid/Finish Line")] public class MapFinishLine : MonoBehaviour { public float width = 14f; public float height = 8f; } [AddComponentMenu("Slip & Skid/Checkpoint")] public class MapCheckpoint : MonoBehaviour { [Tooltip("Pass order, ascending. Ties break by sibling index.")] public int order; public float width = 14f; public float height = 8f; } [AddComponentMenu("Slip & Skid/Spawn Points")] public class MapSpawnPoints : MonoBehaviour { [Tooltip("In grid order. Children are used automatically when this is empty.")] public List<Transform> points = new List<Transform>(); [Tooltip("Optional dedicated time-trial spawn. Falls back to the first point.")] public Transform timeTrialSpawn; public List<Transform> Resolve() { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but got Unknown if (points != null && points.Count > 0) { return points; } List<Transform> list = new List<Transform>(); foreach (Transform item2 in ((Component)this).transform) { Transform item = item2; list.Add(item); } return list; } } [AddComponentMenu("Slip & Skid/End Game Platform")] public class MapEndGamePlatform : MonoBehaviour { public List<Transform> finishOrderSpawns = new List<Transform>(); } [AddComponentMenu("Slip & Skid/Gravity Sphere")] public class MapGravitySphere : MonoBehaviour { public float gravity = 40f; public float innerRadius = 2.5f; public float outerRadius = 10f; public bool useObjectScale = true; } }