using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Security; using System.Security.Permissions; using System.Text.RegularExpressions; using System.Threading; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using Distance.CustomCar.Data.Car; using Distance.CustomCar.Data.Errors; using Distance.CustomCar.Data.Materials; using Events; using Events.Car; using Events.MainMenu; using HarmonyLib; using JsonFx.Json; using JsonFx.Model; using JsonFx.Serialization; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("Distance.ModTemplate")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Distance.ModTemplate")] [assembly: AssemblyCopyright("Copyright © 2021")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("7bcb2908-b003-45d9-be68-50cba5217603")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] public static class DictionaryExtensions { public static bool ContainsKey(this Dictionary obj, string key) { try { obj.GetItem(key); return true; } catch { return false; } } public static T GetItem(this Dictionary obj, string key) { if (!obj.ContainsKey(key)) { throw new KeyNotFoundException("The key requested doesn't exist in store: '" + key + "'."); } try { return (T)Convert.ChangeType(obj[key], typeof(T)); } catch (Exception innerException) { throw new Exception("Failed type conversion exception has been thrown.", innerException); } } public static T GetOrCreate(this Dictionary obj, string key) where T : new() { if (!obj.ContainsKey(key)) { obj[key] = new T(); } return obj.GetItem(key); } public static T GetOrCreate(this Dictionary obj, string key, T defaultValue) { if (!obj.ContainsKey(key)) { obj[key] = defaultValue; } return obj.GetItem(key); } public static T GetOrCreate(this Dictionary obj, string key, Func factory) where T : class { if (!obj.ContainsKey(key)) { return (T)(obj[key] = factory()); } return (T)obj[key]; } } public static class GameObjectExtensions { public static string FullName(this GameObject obj) { if (!Object.op_Implicit((Object)(object)obj.transform.parent)) { return ((Object)obj).name; } return ((Component)obj.transform.parent).gameObject.FullName() + "/" + ((Object)obj).name; } } namespace Distance.CustomCar { public class Assets { private string _filePath = null; private string RootDirectory { get; } private string FileName { get; set; } private string FilePath => _filePath ?? Path.Combine(Path.Combine(RootDirectory, "Assets"), FileName); public object Bundle { get; private set; } private Assets() { } public Assets(string fileName) { RootDirectory = Path.GetDirectoryName(Assembly.GetCallingAssembly().Location); FileName = fileName; if (!File.Exists(FilePath)) { Mod.Log.LogError((object)("Couldn't find requested asset bundle at " + FilePath)); } else { Bundle = Load(); } } public static Assets FromUnsafePath(string filePath) { if (!File.Exists(filePath)) { Mod.Log.LogError((object)("Could not find requested asset bundle at " + filePath)); return null; } Assets assets = new Assets { _filePath = filePath, FileName = Path.GetFileName(filePath) }; assets.Bundle = assets.Load(); if (assets.Bundle == null) { return null; } return assets; } private object Load() { try { return AssetBundleBridge.LoadFrom(FilePath); } catch (Exception ex) { Mod.Log.LogInfo((object)ex); return null; } } } internal static class AssetBundleBridge { private static Type _assetBundleType; private static MethodInfo _loadFromFile; public static Type AssetBundleType => _assetBundleType; private static MethodInfo LoadFromFile => _loadFromFile; static AssetBundleBridge() { _assetBundleType = Kernel.FindTypeByFullName("UnityEngine.AssetBundle", "UnityEngine"); _loadFromFile = _assetBundleType.GetMethod("LoadFromFile", new Type[1] { typeof(string) }); } public static object LoadFrom(string path) { MethodInfo loadFromFile = LoadFromFile; object[] parameters = new string[1] { path }; return loadFromFile.Invoke(null, parameters); } } internal static class Kernel { internal static Type FindTypeByFullName(string fullName, string assemblyFilter) { IEnumerable enumerable = from a in AppDomain.CurrentDomain.GetAssemblies() where a.GetName().Name.Contains(assemblyFilter) select a; foreach (Assembly item in enumerable) { Type type = item.GetTypes().FirstOrDefault((Type t) => t.FullName == fullName); if ((object)type == null) { continue; } return type; } Mod.Log.LogError((object)("Type " + fullName + " wasn't found in the main AppDomain at this moment.")); throw new Exception("Type " + fullName + " wasn't found in the main AppDomain at this moment."); } } public class FileSystem { public string RootDirectory { get; } public string VirtualFileSystemRoot => Path.Combine(RootDirectory, "Data"); public FileSystem() { RootDirectory = Path.GetDirectoryName(Assembly.GetCallingAssembly().Location); if (!Directory.Exists(VirtualFileSystemRoot)) { Directory.CreateDirectory(VirtualFileSystemRoot); } } public bool FileExists(string path) { string path2 = Path.Combine(VirtualFileSystemRoot, path); return File.Exists(path2); } public bool DirectoryExists(string path) { string path2 = Path.Combine(VirtualFileSystemRoot, path); return Directory.Exists(path2); } public bool PathExists(string path) { return FileExists(path) || DirectoryExists(path); } public byte[] ReadAllBytes(string filePath) { string text = Path.Combine(VirtualFileSystemRoot, filePath); if (!File.Exists(text)) { Mod.Log.LogInfo((object)("Couldn't read a file for path '" + text + "'. File does not exist.")); return null; } return File.ReadAllBytes(text); } public FileStream CreateFile(string filePath, bool overwrite = false) { string text = Path.Combine(VirtualFileSystemRoot, filePath); if (File.Exists(text)) { if (!overwrite) { Mod.Log.LogInfo((object)("Couldn't create a mod VFS file for path '" + text + "'. The file already exists.")); return null; } Mod.Log.LogInfo((object)("Couldn't delete a mod VFS file for path '" + text + "'. File does not exist.")); RemoveFile(filePath); } try { return File.Create(text); } catch (Exception ex) { Mod.Log.LogInfo((object)("Couldn't create a mod VFS file for path '" + text + "'.")); Mod.Log.LogInfo((object)ex); return null; } } public void RemoveFile(string filePath) { string text = Path.Combine(VirtualFileSystemRoot, filePath); if (!File.Exists(text)) { Mod.Log.LogInfo((object)("Couldn't delete a mod VFS file for path '" + text + "'. File does not exist.")); return; } try { File.Delete(text); } catch (Exception ex) { Mod.Log.LogInfo((object)("Couldn't delete a mod VFS file for path '" + text + "'.")); Mod.Log.LogInfo((object)ex); } } public void IterateOver(string directoryPath, Action action, bool sort = true) { string text = Path.Combine(VirtualFileSystemRoot, directoryPath); if (!Directory.Exists(text)) { Mod.Log.LogInfo((object)("Cannot iterate over directory at '" + text + "'. It doesn't exist.")); return; } List list = Directory.GetFiles(text).ToList(); list.AddRange(Directory.GetDirectories(text)); if (sort) { list = list.OrderBy((string x) => x).ToList(); } foreach (string item in list) { try { bool arg = Directory.Exists(item); action(item, arg); } catch (Exception ex) { Mod.Log.LogInfo((object)("Action for the element at path '" + item + "' failed. See file system exception log for details.")); Mod.Log.LogInfo((object)ex); break; } } } public List GetDirectories(string directoryPath, string searchPattern) { string text = Path.Combine(VirtualFileSystemRoot, directoryPath); if (!Directory.Exists(text)) { Mod.Log.LogInfo((object)("Cannot get directories in directory at '" + text + "'. It doesn't exist.")); return null; } return Directory.GetDirectories(text, searchPattern).ToList(); } public List GetDirectories(string directoryPath) { return GetDirectories(directoryPath, "*"); } public List GetFiles(string directoryPath, string searchPattern) { string text = Path.Combine(VirtualFileSystemRoot, directoryPath); if (!Directory.Exists(text)) { Mod.Log.LogInfo((object)("Cannot get files in directory at '" + text + "'. It doesn't exist.")); return null; } return Directory.GetFiles(text, searchPattern).ToList(); } public List GetFiles(string directoryPath) { return GetFiles(directoryPath, "*"); } public FileStream OpenFile(string filePath, FileMode fileMode, FileAccess fileAccess, FileShare fileShare) { string text = Path.Combine(VirtualFileSystemRoot, filePath); if (!File.Exists(text)) { Mod.Log.LogInfo((object)("Couldn't open a VFS file. The requested file: '" + text + "' does not exist.")); return null; } try { return File.Open(text, fileMode, fileAccess, fileShare); } catch (Exception ex) { Mod.Log.LogInfo((object)("Couldn't open a VFS file for path '" + text + "'.")); Mod.Log.LogInfo((object)ex); return null; } } public FileStream OpenFile(string filePath) { return OpenFile(filePath, FileMode.Open, FileAccess.ReadWrite, FileShare.Read); } public string CreateDirectory(string directoryName) { string text = Path.Combine(VirtualFileSystemRoot, directoryName); try { Directory.CreateDirectory(text); return text; } catch (Exception ex) { Mod.Log.LogInfo((object)("Couldn't create a VFS directory for path '" + text + "'.")); Mod.Log.LogInfo((object)ex); return string.Empty; } } public void RemoveDirectory(string directoryPath) { string text = Path.Combine(VirtualFileSystemRoot, directoryPath); if (!Directory.Exists(text)) { Mod.Log.LogInfo((object)("Couldn't remove a VFS directory for path '" + text + "'. Directory does not exist.")); return; } try { Directory.Delete(text, recursive: true); } catch (Exception ex) { Mod.Log.LogInfo((object)("Couldn't remove a VFS directory for path '" + text + "'.")); Mod.Log.LogInfo((object)ex); } } public static string GetValidFileName(string dirtyFileName, string replaceInvalidCharsWith = "_") { return Regex.Replace(dirtyFileName, "[^\\w\\s\\.]", replaceInvalidCharsWith, RegexOptions.None); } public static string GetValidFileNameToLower(string dirtyFileName, string replaceInvalidCharsWith = "_") { return GetValidFileName(dirtyFileName, replaceInvalidCharsWith).ToLower(); } } public sealed class MessageBox { private readonly string Message = ""; private readonly string Title = ""; private float Time = 0f; private ButtonType Buttons = (ButtonType)0; private Action Confirm; private Action Cancel; private MessageBox(string message, string title) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) Message = message; Title = title; Confirm = EmptyAction; Cancel = EmptyAction; } public static MessageBox Create(string content, string title = "") { return new MessageBox(content, title); } public MessageBox SetButtons(MessageButtons buttons) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) Buttons = (ButtonType)buttons; return this; } public MessageBox SetTimeout(float delay) { Time = delay; return this; } public MessageBox OnConfirm(Action action) { Confirm = action; return this; } public MessageBox OnCancel(Action action) { Cancel = action; return this; } public void Show() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_002a: 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_0042: Expected O, but got Unknown //IL_0042: Expected O, but got Unknown G.Sys.MenuPanelManager_.ShowMessage(Message, Title, (OnButtonClicked)delegate { Confirm(); }, (OnButtonClicked)delegate { Cancel(); }, Buttons, false, (Pivot)4, Time); } private void EmptyAction() { } } [Flags] public enum MessageButtons { Ok = 0, OkCancel = 1, YesNo = 2 } [BepInPlugin("Distance.CustomCar", "Custom Car", "1.1.4")] public sealed class Mod : BaseUnityPlugin { private const string modGUID = "Distance.CustomCar"; private const string modName = "Custom Car"; private const string modVersion = "1.1.4"; public static string UseTrumpetKey = "Use Trumpet Horn"; private static readonly Harmony harmony = new Harmony("Distance.CustomCar"); public static ManualLogSource Log = new ManualLogSource("Custom Car"); public static Mod Instance; private bool displayErrors_ = true; public static ConfigEntry UseTrumpetHorn { get; set; } public static int DefaultCarCount { get; private set; } public static int ModdedCarCount => TotalCarCount - DefaultCarCount; public static int TotalCarCount { get; private set; } public ErrorList Errors { get; set; } public ProfileCarColors CarColors { get; set; } private void Awake() { //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Expected O, but got Unknown if ((Object)(object)Instance == (Object)null) { Instance = this; } Log = Logger.CreateLogSource("Distance.CustomCar"); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Thanks for using Custom Cars!"); Errors = new ErrorList(((BaseUnityPlugin)this).Logger); CarColors = ((Component)this).gameObject.AddComponent(); UseTrumpetHorn = ((BaseUnityPlugin)this).Config.Bind("General", UseTrumpetKey, false, new ConfigDescription("Custom car models will use the encryptor horn (the \"doot!\" trumpet).", (AcceptableValueBase)null, new object[0])); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Loading..."); harmony.PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Loaded!"); } public void Start() { ProfileManager profileManager_ = G.Sys.ProfileManager_; DefaultCarCount = profileManager_.CarInfos_.Length; CarInfos carInfos = new CarInfos(); carInfos.CollectInfos(); CarBuilder carBuilder = new CarBuilder(); carBuilder.CreateCars(carInfos); TotalCarCount = profileManager_.CarInfos_.Length; CarColors.LoadAll(); Errors.Show(); } private void OnEnable() { StaticEvent.Subscribe((Delegate)OnMainMenuLoaded); } private void OnDisable() { StaticEvent.Unsubscribe((Delegate)OnMainMenuLoaded); } private void OnMainMenuLoaded(Data _) { if (displayErrors_) { Errors.Show(); displayErrors_ = false; } } private void OnConfigChanged(object sender, EventArgs e) { SettingChangedEventArgs e2 = (SettingChangedEventArgs)(object)((e is SettingChangedEventArgs) ? e : null); if (e2 != null) { } } } public class ProfileCarColors : MonoBehaviour { internal Settings Config; public event Action OnChanged; protected void Load() { Config = new Settings("CustomCars"); } protected void Awake() { Load(); Save(); } protected Dictionary Profile(string profileName) { return Config.GetOrCreate(profileName, () => new Dictionary()); } protected Dictionary Vehicle(string profileName, string vehicleName) { return Profile(profileName).GetOrCreate(vehicleName, () => new Dictionary()); } protected CarColors GetCarColors(string profileName, string vehicleName) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: 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_0077: 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_007f: 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) Dictionary vehicle = Vehicle(profileName, vehicleName); CarColors val = new CarColors { primary_ = GetColor(vehicle, "primary", Colors.whiteSmoke), secondary_ = GetColor(vehicle, "secondary", Colors.darkGray), glow_ = GetColor(vehicle, "glow", Colors.cyan), sparkle_ = GetColor(vehicle, "sparkle", Colors.lightSlateGray) }; SetCarColors(profileName, vehicleName, val); return val; } protected Color GetColor(Dictionary vehicle, string category, Color defaultColor) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0040: 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_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0076: 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_007f: Unknown result type (might be due to invalid IL or missing references) Dictionary orCreate = vehicle.GetOrCreate(category, () => new Dictionary()); float orCreate2 = orCreate.GetOrCreate("r", defaultColor.r); float orCreate3 = orCreate.GetOrCreate("g", defaultColor.g); float orCreate4 = orCreate.GetOrCreate("b", defaultColor.b); float orCreate5 = orCreate.GetOrCreate("a", defaultColor.a); return new Color(orCreate2, orCreate3, orCreate4, orCreate5); } protected void SetCarColors(string profileName, string vehicleName, CarColors colors) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) Dictionary dictionary = Vehicle(profileName, vehicleName); dictionary["primary"] = ToSection(colors.primary_); dictionary["secondary"] = ToSection(colors.secondary_); dictionary["glow"] = ToSection(colors.glow_); dictionary["sparkle"] = ToSection(colors.sparkle_); Dictionary dictionary2 = Profile(profileName); dictionary2[vehicleName] = dictionary; Config[profileName] = dictionary2; } protected Section ToSection(Color color) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) return new Section { ["r"] = color.r, ["g"] = color.g, ["b"] = color.b, ["a"] = color.a }; } protected void Save() { Config.Save(); this.OnChanged?.Invoke(this); } public void LoadAll() { //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //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) ProfileManager profileManager_ = G.Sys.ProfileManager_; List profiles_ = profileManager_.profiles_; foreach (Profile item in profiles_) { CarColors[] array = (CarColors[])(object)new CarColors[Mod.TotalCarCount]; for (int i = 0; i < profileManager_.CarInfos_.Length; i++) { if (i < Mod.DefaultCarCount) { array[i] = item.carColorsList_[i]; continue; } CarInfo val = profileManager_.CarInfos_[i]; Mod.Log.LogInfo((object)("Getting car color in " + item.FileName_ + "'s profile for the " + val.name_ + " car")); CarColors carColors = GetCarColors(item.FileName_, val.name_); array[i] = carColors; } item.carColorsList_ = array; } } public void SaveAll() { //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) ProfileManager profileManager_ = G.Sys.ProfileManager_; List profiles_ = profileManager_.profiles_; foreach (Profile item in profiles_) { for (int i = 0; i < profileManager_.CarInfos_.Length; i++) { if (i >= Mod.DefaultCarCount) { CarInfo val = profileManager_.CarInfos_[i]; CarColors colors = item.carColorsList_[i]; SetCarColors(item.FileName_, val.name_, colors); } } } Save(); } } public class Section : Dictionary { public new object this[string key] { get { if (!ContainsKey(key)) { return null; } return base[key]; } set { if (!ContainsKey(key)) { Add(key, value); this.ValueChanged?.Invoke(this, new SettingsChangedEventArgs(key, null, base[key])); } else { object oldValue = base[key]; base[key] = value; this.ValueChanged?.Invoke(this, new SettingsChangedEventArgs(key, oldValue, base[key])); } } } public event EventHandler ValueChanged; public T GetItem(string key) { if (!ContainsKey(key)) { Mod.Log.LogError((object)("The key requested doesn't exist in store: '" + key + "'.")); throw new KeyNotFoundException("The key requested doesn't exist in store: '" + key + "'."); } try { return (T)Convert.ChangeType(this[key], typeof(T)); } catch (Exception ex) { Mod.Log.LogWarning((object)$"Failed type conversion exception has been thrown. String: {key} \n{ex}"); throw new SettingsException("Failed type conversion exception has been thrown.", key, isJsonFailure: false, ex); } } public T GetOrCreate(string key) where T : new() { if (!ContainsKey(key)) { this[key] = new T(); this.ValueChanged?.Invoke(this, new SettingsChangedEventArgs(key, null, this[key])); } return GetItem(key); } public T GetOrCreate(string key, T defaultValue) { if (!ContainsKey(key)) { this[key] = defaultValue; this.ValueChanged?.Invoke(this, new SettingsChangedEventArgs(key, null, this[key])); } return GetItem(key); } public T GetOrCreate(string key, Func factory) where T : class { if (!ContainsKey(key)) { T result = (T)(this[key] = factory()); this.ValueChanged?.Invoke(this, new SettingsChangedEventArgs(key, null, this[key])); return result; } return (T)this[key]; } public bool ContainsKey(string key) { try { GetItem(key); return true; } catch { return false; } } } public class Settings : Section { private string FileName { get; } private string RootDirectory { get; } private string SettingsDirectory => Path.Combine(RootDirectory, "Settings"); private string FilePath => Path.Combine(SettingsDirectory, FileName); public Settings(string fileName) { //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Expected O, but got Unknown RootDirectory = Path.GetDirectoryName(Assembly.GetCallingAssembly().Location); FileName = fileName + ".json"; Mod.Log.LogInfo((object)("Settings instance for '" + FilePath + "' initializing...")); if (!File.Exists(FilePath)) { return; } bool flag = false; using (StreamReader streamReader = new StreamReader(FilePath)) { string text = streamReader.ReadToEnd(); JsonReader val = new JsonReader(); Section section = null; try { section = ((DataReader)(object)val).Read
(text); } catch (Exception ex) { Mod.Log.LogWarning((object)ex); flag = true; } if (section != null) { foreach (string key in section.Keys) { Add(key, section[key]); } } } if (flag) { Save(); } } public void Save(bool formatJson = true) { //IL_001f: 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_002d: Expected O, but got Unknown //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected O, but got Unknown if (!Directory.Exists(SettingsDirectory)) { Directory.CreateDirectory(SettingsDirectory); } DataWriterSettings val = new DataWriterSettings { PrettyPrint = formatJson }; JsonWriter val2 = new JsonWriter(val); try { using StreamWriter streamWriter = new StreamWriter(FilePath, append: false); streamWriter.WriteLine(((DataWriter)(object)val2).Write((object)this)); } catch (Exception ex) { Mod.Log.LogWarning((object)ex); } } } public class SettingsChangedEventArgs : EventArgs { public string Key { get; } public object OldValue { get; } public object NewValue { get; } public SettingsChangedEventArgs(string key, object oldValue = null, object newValue = null) { Key = key; OldValue = oldValue; NewValue = newValue; } } public class SettingsException : Exception { public string Key { get; } public bool IsJsonFailure { get; } public SettingsException(string message, string key, bool isJsonFailure, Exception innerException) : base(message, innerException) { Key = key; IsJsonFailure = isJsonFailure; } public SettingsException(string message, string key, bool isJsonFailure) : this(message, key, isJsonFailure, null) { } } } namespace Distance.CustomCar.Patches { [HarmonyPatch(typeof(CarAudio), "OnCarHornEvent")] internal static class OnCarHornEvent { [HarmonyPrefix] internal static bool Prefix(CarAudio __instance, Data data) { //IL_004b: Unknown result type (might be due to invalid IL or missing references) int num = G.Sys.ProfileManager_.knownCars_[__instance.carLogic_.PlayerData_.CarName_]; if (num >= Mod.DefaultCarCount && Mod.UseTrumpetHorn.Value) { __instance.phantom_.SetRTPCValue("Horn_volume", Mathf.Clamp01(data.hornPercent_ + 0.5f)); __instance.phantom_.Play("SpookyHorn", 0f, true); return false; } return true; } } [HarmonyPatch(typeof(GadgetWithAnimation), "SetAnimationStateValues")] internal static class GadgetWithAnimation__SetAnimationStateValues { [HarmonyPrefix] internal static bool Prefix(GadgetWithAnimation __instance) { Animation componentInChildren = ((Component)__instance).GetComponentInChildren(true); if (Object.op_Implicit((Object)(object)componentInChildren)) { return PatchAnimations(componentInChildren, __instance.animationName_); } return false; } private static bool PatchAnimations(Animation animation, string name) { if (Object.op_Implicit((Object)(object)animation)) { if (!ChangeBlendModeToBlend(((Component)animation).transform, name)) { return true; } AnimationState val = animation[name]; if (TrackedReference.op_Implicit((TrackedReference)(object)val)) { val.layer = 3; val.blendMode = (AnimationBlendMode)0; val.wrapMode = (WrapMode)8; val.enabled = true; val.weight = 1f; val.speed = 0f; } } return false; } private static bool ChangeBlendModeToBlend(Transform obj, string animationName) { for (int i = 0; i < obj.childCount; i++) { string text = ((Object)((Component)obj.GetChild(i)).gameObject).name.ToLower(); if (!text.StartsWith("#")) { continue; } text = text.Remove(0, 1); string[] array = text.Split(new char[1] { ';' }); if (array.Length == 1) { if (array[0] == "additive") { return false; } if (array[0] == "blend") { return true; } } if (array[1] == animationName.ToLower()) { if (array[0] == "additive") { return false; } if (array[0] == "blend") { return true; } } } return false; } } [HarmonyPatch(typeof(Profile), "Awake")] internal static class Profile__Awake { [HarmonyPostfix] internal static void Postfix(Profile __instance) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) CarColors[] array = (CarColors[])(object)new CarColors[G.Sys.ProfileManager_.carInfos_.Length]; for (int i = 0; i < array.Length; i++) { array[i] = G.Sys.ProfileManager_.carInfos_[i].colors_; } __instance.carColorsList_ = array; } } [HarmonyPatch(typeof(Profile), "Save")] internal static class Profile__Save { [HarmonyPostfix] internal static void Postfix() { Mod.Instance.CarColors.SaveAll(); } } [HarmonyPatch(typeof(Profile), "SetColorsForAllCars", new Type[] { typeof(CarColors) })] internal static class Profile__SetColorsForAllCars { [HarmonyPrefix] internal static bool Prefix(Profile __instance, CarColors cc) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) CarColors[] array = (CarColors[])(object)new CarColors[G.Sys.ProfileManager_.carInfos_.Length]; for (int i = 0; i < array.Length; i++) { array[i] = cc; } __instance.carColorsList_ = array; __instance.dataModified_ = true; return false; } } } namespace Distance.CustomCar.Data.Materials { public class MaterialInfos { public Material material; public int diffuseIndex = -1; public int normalIndex = -1; public int emitIndex = -1; public void ReplaceMaterialInRenderer(Renderer renderer, int materialIndex) { if (!((Object)(object)material == (Object)null) && !((Object)(object)renderer == (Object)null) && materialIndex < renderer.materials.Length) { ref Material reference = ref renderer.materials[materialIndex]; Material val = Object.Instantiate(material); if (diffuseIndex >= 0) { val.SetTexture(diffuseIndex, reference.GetTexture("_MainTex")); } if (emitIndex >= 0) { val.SetTexture(emitIndex, reference.GetTexture("_EmissionMap")); } if (normalIndex >= 0) { val.SetTexture(normalIndex, reference.GetTexture("_BumpMap")); } renderer.materials[materialIndex] = val; } } } public class MaterialPropertyExport { public string fromName; public string toName; public int fromID = -1; public int toID = -1; public PropertyType type; } public class MaterialPropertyInfo { public string shaderName; public string name; public int diffuseIndex = -1; public int normalIndex = -1; public int emitIndex = -1; public MaterialPropertyInfo(string _shaderName, string _name, int _diffuseIndex, int _normalIndex, int _emitIndex) { shaderName = _shaderName; name = _name; diffuseIndex = _diffuseIndex; normalIndex = _normalIndex; emitIndex = _emitIndex; } } public enum PropertyType { Color, ColorArray, Float, FloatArray, Int, Matrix, MatrixArray, Texture, Vector, VectorArray } } namespace Distance.CustomCar.Data.Errors { public class ErrorList : List { private readonly ManualLogSource logger_; public ErrorList(ManualLogSource logger) { logger_ = logger; } public new void Add(string value) { base.Add(value); logger_.LogInfo((object)value); } public void Add(Exception value) { base.Add(value.ToString()); logger_.LogInfo((object)value); } public void Show() { if (this.Any()) { string arg = ((base.Count < 15) ? string.Join(Environment.NewLine, ToArray()) : "There were too many errors when loading custom cars to be displayed here, please check the logs in your mod installation directory."); MessageBox.Create($"Can't load the cars correctly: {base.Count} error(s)\n{arg}", "CUSTOM CARS - ERRORS").SetButtons(MessageButtons.Ok).Show(); } } } } namespace Distance.CustomCar.Data.Car { public class CarBuilder { private struct BundleLoadResult { public string FilePath; public AssetBundle Bundle; public Exception Error; } private CarInfos infos_; public void CreateCars(CarInfos infos) { infos_ = infos; Dictionary dictionary = LoadAssetsBundles(); List list = new List(); foreach (KeyValuePair item in dictionary) { try { Mod.Log.LogInfo((object)("Creating car prefab for " + item.Key + " ...")); CreateCarReturnInfos createCarReturnInfos = CreateCar(item.Value); string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(item.Key.Substring(0, item.Key.LastIndexOf('(') - 1)); ((Object)createCarReturnInfos.car).name = fileNameWithoutExtension; list.Add(createCarReturnInfos); } catch (Exception value) { Mod.Log.LogError((object)("Could not load car prefab: " + item.Key)); Mod.Instance.Errors.Add("Could not load car prefab: " + item.Key); Mod.Instance.Errors.Add(value); } } RegisterCars(list); } private void RegisterCars(List carsInfos) { //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0091: 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_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Expected O, but got Unknown //IL_023b: Unknown result type (might be due to invalid IL or missing references) //IL_0240: Unknown result type (might be due to invalid IL or missing references) //IL_0281: Unknown result type (might be due to invalid IL or missing references) //IL_0286: Unknown result type (might be due to invalid IL or missing references) Mod.Log.LogInfo((object)$"Registering {carsInfos.Count} car(s)..."); ProfileManager profileManager_ = G.Sys.ProfileManager_; CarInfo[] array = ICollectionEx.ToArray((ICollection)profileManager_.carInfos_); profileManager_.carInfos_ = (CarInfo[])(object)new CarInfo[array.Length + carsInfos.Count]; ref Dictionary unlockedCars_ = ref profileManager_.unlockedCars_; ref Dictionary knownCars_ = ref profileManager_.knownCars_; for (int i = 0; i < profileManager_.carInfos_.Length; i++) { if (i < array.Length) { profileManager_.carInfos_[i] = array[i]; continue; } int index = i - array.Length; CarInfo val = new CarInfo { name_ = ((Object)carsInfos[index].car).name, prefabs_ = new CarPrefabs { carPrefab_ = carsInfos[index].car }, colors_ = carsInfos[index].colors }; if (!knownCars_.ContainsKey(val.name_) && !unlockedCars_.ContainsKey(val.name_)) { unlockedCars_.Add(val.name_, i); knownCars_.Add(val.name_, i); } else { Mod.Instance.Errors.Add("A car with the name " + val.name_ + " is already registered, rename the car file if they're the same."); Mod.Log.LogInfo((object)("Generating unique name for car " + val.name_)); string text = $"#{Guid.NewGuid():B}"; Mod.Log.LogInfo((object)("Using GUID: " + text)); val.name_ = "[FFFF00]![-] " + val.name_ + " " + text; unlockedCars_.Add(val.name_, i); knownCars_.Add(val.name_, i); } profileManager_.carInfos_[i] = val; } CarColors[] array2 = (CarColors[])(object)new CarColors[array.Length + carsInfos.Count]; for (int j = 0; j < array2.Length; j++) { array2[j] = G.Sys.ProfileManager_.carInfos_[j].colors_; } for (int k = 0; k < profileManager_.ProfileCount_; k++) { Profile profile = profileManager_.GetProfile(k); CarColors[] carColorsList_ = profile.carColorsList_; for (int l = 0; l < carColorsList_.Length && l < array2.Length; l++) { array2[l] = carColorsList_[l]; } profile.carColorsList_ = array2; } } private Dictionary LoadAssetsBundles() { Dictionary dictionary = new Dictionary(); DirectoryInfo directoryInfo = new DirectoryInfo(Path.Combine(Resource.personalDistanceDirPath_, "CustomCars")); if (!directoryInfo.Exists) { try { directoryInfo.Create(); } catch (Exception ex) { Mod.Instance.Errors.Add("Could not create the following folder: " + directoryInfo.FullName); Mod.Log.LogError((object)("Could not create the following folder: " + directoryInfo.FullName)); Mod.Instance.Errors.Add(ex); Mod.Log.LogError((object)ex); } } PrefabIndex prefabIndex = new PrefabIndex(); prefabIndex.Load(); DirectoryInfo directoryInfo2 = new DirectoryInfo(Directory.GetParent(Path.GetDirectoryName(Assembly.GetCallingAssembly().Location)).ToString()); List list = new List(); foreach (FileInfo item in from x in ArrayEx.Concat(directoryInfo2.GetFiles("*", SearchOption.AllDirectories), directoryInfo.GetFiles("*", SearchOption.AllDirectories)) orderby x.Name select x) { if (item.Extension == "" && HasValidBundleSignature(item.FullName)) { list.Add(item); } } List list2 = list; HashSet hashSet = new HashSet(); int num = Math.Max(4, Environment.ProcessorCount); int num2 = (list2.Count + num - 1) / num; for (int num3 = 0; num3 < list2.Count; num3 += num) { int num4 = Math.Min(num3 + num, list2.Count); Mod.Log.LogInfo((object)$"Batch {num3 / num + 1}/{num2} ({num4 - num3} files)"); BundleLoadResult[] batchResults = new BundleLoadResult[num4 - num3]; int batchCount = batchResults.Length; int loaded = 0; ManualResetEvent batchDone = new ManualResetEvent(initialState: false); try { for (int num5 = 0; num5 < batchCount; num5++) { int index = num5; FileInfo file = list2[num3 + num5]; ThreadPool.QueueUserWorkItem(delegate { batchResults[index] = LoadBundle(file); if (Interlocked.Increment(ref loaded) == batchCount) { batchDone.Set(); } }); } if (!batchDone.WaitOne(30000)) { Mod.Log.LogWarning((object)$"Bundle batch {num3 / num + 1} timed out after 30s — incomplete results will be skipped."); for (int num6 = 0; num6 < batchCount; num6++) { if (batchResults[num6].FilePath == null) { batchResults[num6] = new BundleLoadResult { FilePath = list2[num3 + num6].FullName, Error = new TimeoutException("Bundle loading timed out after 30 seconds — the file may be corrupted") }; } } } } finally { if (batchDone != null) { ((IDisposable)batchDone).Dispose(); } } BundleLoadResult[] array = batchResults; for (int num7 = 0; num7 < array.Length; num7++) { BundleLoadResult bundleLoadResult = array[num7]; string filePath = bundleLoadResult.FilePath; hashSet.Add(filePath); if ((Object)(object)bundleLoadResult.Bundle == (Object)null) { Mod.Instance.Errors.Add("Could not load assets file: " + filePath); Mod.Log.LogError((object)("Could not load assets file: " + filePath)); if (bundleLoadResult.Error != null) { Mod.Instance.Errors.Add(bundleLoadResult.Error); Mod.Log.LogError((object)bundleLoadResult.Error); } continue; } AssetBundle bundle = bundleLoadResult.Bundle; string[] array2; if (prefabIndex.IsUpToDate(filePath)) { array2 = prefabIndex.GetPrefabNames(filePath); if (array2 == null || array2.Length == 0) { array2 = ScanBundleForPrefabs(bundle); } } else { array2 = ScanBundleForPrefabs(bundle); if (array2.Length != 0) { Mod.Log.LogInfo((object)$"Scanned: {Path.GetFileName(filePath)} ({array2.Length} prefab(s))"); } } prefabIndex.SetPrefabNames(filePath, array2); int num8 = 0; string[] array3 = array2; foreach (string text in array3) { GameObject value = bundle.LoadAsset(text); string key = filePath + " (" + text + ")"; if (!dictionary.ContainsKey(key)) { dictionary.Add(key, value); num8++; } } if (num8 == 0) { Mod.Instance.Errors.Add("Can't find a prefab in the asset bundle: " + filePath); Mod.Log.LogError((object)("Can't find a prefab in the asset bundle: " + filePath)); } bundle.Unload(false); } } Mod.Log.LogInfo((object)$"{dictionary.Count} prefab(s) loaded from {hashSet.Count} file(s)"); prefabIndex.RemoveStaleEntries(hashSet); prefabIndex.Save(); return dictionary; } private static bool HasValidBundleSignature(string filePath) { try { using FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read); if (fileStream.Length < 8) { return false; } byte[] array = new byte[8]; if (fileStream.Read(array, 0, 8) != 8) { return false; } if (array[0] == 85 && array[1] == 110 && array[2] == 105 && array[3] == 116 && array[4] == 121 && array[5] == 70 && array[6] == 83) { return true; } if (array[0] == 85 && array[1] == 110 && array[2] == 105 && array[3] == 116 && array[4] == 121 && array[5] == 82 && array[6] == 97 && array[7] == 119) { return true; } if (array[0] == 85 && array[1] == 110 && array[2] == 105 && array[3] == 116 && array[4] == 121 && array[5] == 87 && array[6] == 101 && array[7] == 98) { return true; } return false; } catch { return false; } } private static BundleLoadResult LoadBundle(FileInfo file) { try { if (!HasValidBundleSignature(file.FullName)) { return new BundleLoadResult { FilePath = file.FullName, Error = new InvalidDataException("File is not a valid Unity AssetBundle (missing UnityFS/UnityRaw/UnityWeb header)") }; } Assets assets = Assets.FromUnsafePath(file.FullName); if (assets == null) { return new BundleLoadResult { FilePath = file.FullName }; } return new BundleLoadResult { FilePath = file.FullName, Bundle = (AssetBundle)/*isinst with value type is only supported in some contexts*/ }; } catch (Exception error) { return new BundleLoadResult { FilePath = file.FullName, Error = error }; } } private static string[] ScanBundleForPrefabs(AssetBundle bundle) { List list = new List(); string[] allAssetNames = bundle.GetAllAssetNames(); foreach (string text in allAssetNames) { if (text.EndsWith(".prefab", StringComparison.InvariantCultureIgnoreCase)) { list.Add(text); } } return list.ToArray(); } private CreateCarReturnInfos CreateCar(GameObject car) { //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) CreateCarReturnInfos createCarReturnInfos = new CreateCarReturnInfos(); GameObject val = Object.Instantiate(infos_.baseCar); ((Object)val).name = ((Object)car).name; Object.DontDestroyOnLoad((Object)(object)val); val.SetActive(false); RemoveOldCar(val); GameObject car2 = AddNewCarOnPrefab(val, car); SetCarDatas(val, car2); createCarReturnInfos.car = val; createCarReturnInfos.colors = LoadDefaultColors(car2); return createCarReturnInfos; } private void RemoveOldCar(GameObject obj) { List list = new List(); for (int i = 0; i < obj.transform.childCount; i++) { GameObject gameObject = ((Component)obj.transform.GetChild(i)).gameObject; if (((Object)gameObject).name.IndexOf("wheel", StringComparison.InvariantCultureIgnoreCase) >= 0) { list.Add(gameObject); } } if (list.Count != 4) { Mod.Instance.Errors.Add($"Found {list.Count} wheels on base prefabs, expected 4"); Mod.Log.LogError((object)$"Found {list.Count} wheels on base prefabs, expected 4"); } Transform val = obj.transform.Find("Refractor"); if ((Object)(object)val == (Object)null) { Mod.Instance.Errors.Add("Can't find the Refractor object on the base car prefab"); Mod.Log.LogError((object)"Can't find the Refractor object on the base car prefab"); return; } Object.Destroy((Object)(object)((Component)val).gameObject); foreach (GameObject item in list) { Object.Destroy((Object)(object)item); } } private GameObject AddNewCarOnPrefab(GameObject obj, GameObject car) { return Object.Instantiate(car, obj.transform); } private void SetCarDatas(GameObject obj, GameObject car) { SetColorChanger(obj.GetComponent(), car); SetCarVisuals(obj.GetComponent(), car); } private void SetColorChanger(ColorChanger colorChanger, GameObject car) { if ((Object)(object)colorChanger == (Object)null) { Mod.Instance.Errors.Add("Can't find the ColorChanger component on the base car"); Mod.Log.LogError((object)"Can't find the ColorChanger component on the base car"); return; } colorChanger.rendererChangers_ = (RendererChanger[])(object)new RendererChanger[0]; Renderer[] componentsInChildren = car.GetComponentsInChildren(); foreach (Renderer val in componentsInChildren) { ReplaceMaterials(val); if ((Object)(object)colorChanger != (Object)null) { AddMaterialColorChanger(colorChanger, ((Component)val).transform); } } } private void ReplaceMaterials(Renderer renderer) { string[] array = new string[renderer.materials.Length]; for (int i = 0; i < array.Length; i++) { array[i] = "wheel"; } List[] array2 = new List[renderer.materials.Length]; for (int j = 0; j < array2.Length; j++) { array2[j] = new List(); } FillMaterialInfos(renderer, array, array2); Material[] materials = renderer.materials; Material[] array3 = (Material[])(object)new Material[materials.Length]; Array.Copy(materials, array3, materials.Length); for (int k = 0; k < materials.Length; k++) { if (!infos_.materials.TryGetValue(array[k], out var value)) { Mod.Instance.Errors.Add("Can't find the material " + array[k] + " on " + ((Component)renderer).gameObject.FullName()); Mod.Log.LogError((object)("Can't find the material " + array[k] + " on " + ((Component)renderer).gameObject.FullName())); } else { if (value == null || (Object)(object)value.material == (Object)null) { continue; } Material val = Object.Instantiate(value.material); if (value.diffuseIndex >= 0) { val.SetTexture(value.diffuseIndex, materials[k].GetTexture("_MainTex")); } if (value.normalIndex >= 0) { val.SetTexture(value.normalIndex, materials[k].GetTexture("_BumpMap")); } if (value.emitIndex >= 0) { val.SetTexture(value.emitIndex, materials[k].GetTexture("_EmissionMap")); } foreach (MaterialPropertyExport item in array2[k]) { CopyMaterialProperty(materials[k], val, item); } array3[k] = val; } } renderer.materials = array3; } private void FillMaterialInfos(Renderer renderer, string[] matNames, List[] materialProperties) { int childCount = ((Component)renderer).transform.childCount; for (int i = 0; i < childCount; i++) { string text = ((Object)((Component)renderer).transform.GetChild(i)).name.ToLower(); if (!text.StartsWith("#")) { continue; } text = text.Remove(0, 1); string[] array = text.Split(new char[1] { ';' }); if (array.Length == 0) { continue; } if (array[0].Contains("mat")) { int result; if (array.Length != 3) { Mod.Instance.Errors.Add(array[0] + " property on " + ((Component)renderer).gameObject.FullName() + " must have 2 arguments"); Mod.Log.LogError((object)(array[0] + " property on " + ((Component)renderer).gameObject.FullName() + " must have 2 arguments")); } else if (!int.TryParse(array[1], out result)) { Mod.Instance.Errors.Add("First argument of " + array[0] + " on " + ((Component)renderer).gameObject.FullName() + " property must be a number"); Mod.Log.LogError((object)("First argument of " + array[0] + " on " + ((Component)renderer).gameObject.FullName() + " property must be a number")); } else if (result < matNames.Length) { matNames[result] = array[2]; } } else { if (!array[0].Contains("export")) { continue; } int result2; if (array.Length != 5) { Mod.Instance.Errors.Add(array[0] + " property on " + ((Component)renderer).gameObject.FullName() + " must have 4 arguments"); Mod.Log.LogError((object)(array[0] + " property on " + ((Component)renderer).gameObject.FullName() + " must have 4 arguments")); } else if (!int.TryParse(array[1], out result2)) { Mod.Instance.Errors.Add("First argument of " + array[0] + " on " + ((Component)renderer).gameObject.FullName() + " property must be a number"); Mod.Log.LogError((object)("First argument of " + array[0] + " on " + ((Component)renderer).gameObject.FullName() + " property must be a number")); } else { if (result2 >= matNames.Length) { continue; } MaterialPropertyExport materialPropertyExport = new MaterialPropertyExport(); bool flag = false; foreach (PropertyType value in Enum.GetValues(typeof(PropertyType))) { if (array[2] == value.ToString().ToLower()) { flag = true; materialPropertyExport.type = value; break; } } if (!flag) { Mod.Instance.Errors.Add("The property " + array[2] + " on " + ((Component)renderer).gameObject.FullName() + " is not valid"); Mod.Log.LogError((object)("The property " + array[2] + " on " + ((Component)renderer).gameObject.FullName() + " is not valid")); } else { if (!int.TryParse(array[3], out materialPropertyExport.fromID)) { materialPropertyExport.fromName = array[3]; } if (!int.TryParse(array[4], out materialPropertyExport.toID)) { materialPropertyExport.toName = array[4]; } materialProperties[result2].Add(materialPropertyExport); } } } } } private void CopyMaterialProperty(Material from, Material to, MaterialPropertyExport property) { //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) int num = property.fromID; if (num == -1) { num = Shader.PropertyToID(property.fromName); } int num2 = property.toID; if (num2 == -1) { num2 = Shader.PropertyToID(property.toName); } switch (property.type) { case PropertyType.Color: to.SetColor(num2, from.GetColor(num)); break; case PropertyType.ColorArray: to.SetColorArray(num2, from.GetColorArray(num)); break; case PropertyType.Float: to.SetFloat(num2, from.GetFloat(num)); break; case PropertyType.FloatArray: to.SetFloatArray(num2, from.GetFloatArray(num)); break; case PropertyType.Int: to.SetInt(num2, from.GetInt(num)); break; case PropertyType.Matrix: to.SetMatrix(num2, from.GetMatrix(num)); break; case PropertyType.MatrixArray: to.SetMatrixArray(num2, from.GetMatrixArray(num)); break; case PropertyType.Texture: to.SetTexture(num2, from.GetTexture(num)); break; case PropertyType.Vector: to.SetVector(num2, from.GetVector(num)); break; case PropertyType.VectorArray: to.SetVectorArray(num2, from.GetVectorArray(num)); break; } } private void AddMaterialColorChanger(ColorChanger colorChanger, Transform transform) { //IL_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: 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_01d1: Expected O, but got Unknown //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Expected O, but got Unknown //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) Renderer component = ((Component)transform).GetComponent(); if ((Object)(object)component == (Object)null) { return; } List list = new List(); for (int i = 0; i < transform.childCount; i++) { GameObject gameObject = ((Component)transform.GetChild(i)).gameObject; string text = ((Object)gameObject).name.ToLower(); if (!text.StartsWith("#")) { continue; } text = text.Remove(0, 1); string[] array = text.Split(new char[1] { ';' }); if (array.Length != 0 && array[0].Contains("color")) { if (array.Length != 6) { Mod.Instance.Errors.Add(array[0] + " property on " + ((Component)transform).gameObject.FullName() + " must have 5 arguments"); Mod.Log.LogError((object)(array[0] + " property on " + ((Component)transform).gameObject.FullName() + " must have 5 arguments")); continue; } UniformChanger val = new UniformChanger(); int.TryParse(array[1], out var result); val.materialIndex_ = result; val.colorType_ = ColorType(array[2]); val.name_ = UniformName(array[3]); float.TryParse(array[4], out var result2); val.mul_ = result2; val.alpha_ = string.Equals(array[5], "true", StringComparison.InvariantCultureIgnoreCase); list.Add(val); } } if (list.Count != 0) { RendererChanger item = new RendererChanger { renderer_ = component, uniformChangers_ = list.ToArray() }; List list2 = colorChanger.rendererChangers_.ToList(); list2.Add(item); colorChanger.rendererChangers_ = list2.ToArray(); } } private ColorType ColorType(string name) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) name = name.ToLower(); return (ColorType)(name switch { "primary" => 0, "secondary" => 1, "glow" => 2, "sparkle" => 3, _ => 0, }); } private SupportedUniform UniformName(string name) { //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005d: 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_0065: Unknown result type (might be due to invalid IL or missing references) name = name.ToLower(); return (SupportedUniform)(name switch { "color" => 0, "color2" => 1, "emitcolor" => 2, "reflectcolor" => 4, "speccolor" => 5, _ => 0, }); } private void SetCarVisuals(CarVisuals visuals, GameObject car) { if ((Object)(object)visuals == (Object)null) { Mod.Instance.Errors.Add("Can't find the CarVisuals component on the base car"); Mod.Log.LogInfo((object)"Can't find the CarVisuals component on the base car"); return; } SkinnedMeshRenderer componentInChildren = car.GetComponentInChildren(); MakeMeshSkinned(componentInChildren); visuals.carBodyRenderer_ = componentInChildren; List list = new List(); List list2 = new List(); List list3 = new List(); PlaceJets(car, list, list2, list3); visuals.boostJetFlames_ = list.ToArray(); visuals.wingJetFlames_ = list2.ToArray(); visuals.rotationJetFlames_ = list3.ToArray(); visuals.driverPosition_ = FindCarDriver(car.transform); PlaceCarWheelsVisuals(visuals, car); } private void MakeMeshSkinned(SkinnedMeshRenderer renderer) { //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) Mesh sharedMesh = renderer.sharedMesh; if ((Object)(object)sharedMesh == (Object)null) { Mod.Instance.Errors.Add("The mesh on " + ((Component)renderer).gameObject.FullName() + " is null"); Mod.Log.LogError((object)("The mesh on " + ((Component)renderer).gameObject.FullName() + " is null")); } else if (!sharedMesh.isReadable) { Mod.Instance.Errors.Add("Can't read the car mesh " + ((Object)sharedMesh).name + " on " + ((Component)renderer).gameObject.FullName() + "You must allow reading on it's unity inspector !"); Mod.Log.LogError((object)("Can't read the car mesh " + ((Object)sharedMesh).name + " on " + ((Component)renderer).gameObject.FullName() + "You must allow reading on it's unity inspector !")); } else if (sharedMesh.vertices.Length != sharedMesh.boneWeights.Length) { BoneWeight[] array = (BoneWeight[])(object)new BoneWeight[sharedMesh.vertices.Length]; for (int i = 0; i < array.Length; i++) { ((BoneWeight)(ref array[i])).weight0 = 1f; } sharedMesh.boneWeights = array; Transform transform = ((Component)renderer).transform; sharedMesh.bindposes = (Matrix4x4[])(object)new Matrix4x4[1] { transform.worldToLocalMatrix * ((Component)renderer).transform.localToWorldMatrix }; renderer.bones = (Transform[])(object)new Transform[1] { transform }; } } private void PlaceJets(GameObject obj, List boostJets, List wingJets, List rotationJets) { //IL_0075: 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_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_020a: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Unknown result type (might be due to invalid IL or missing references) int childCount = obj.transform.childCount; for (int i = 0; i < childCount; i++) { GameObject gameObject = GameObjectEx.GetChild(obj, i).gameObject; string text = ((Object)gameObject).name.ToLower(); if ((Object)(object)infos_.boostJet != (Object)null && text.Contains("boostjet")) { GameObject val = Object.Instantiate(infos_.boostJet, gameObject.transform); val.transform.localPosition = Vector3.zero; val.transform.localRotation = Quaternion.identity; boostJets.Add(val.GetComponentInChildren()); } else if ((Object)(object)infos_.wingJet != (Object)null && text.Contains("wingjet")) { GameObject val2 = Object.Instantiate(infos_.wingJet, gameObject.transform); val2.transform.localPosition = Vector3.zero; val2.transform.localRotation = Quaternion.identity; wingJets.Add(val2.GetComponentInChildren()); ListEx.Last(wingJets).rotationAxis_ = JetDirection(gameObject.transform); } else if ((Object)(object)infos_.rotationJet != (Object)null && text.Contains("rotationjet")) { GameObject val3 = Object.Instantiate(infos_.rotationJet, gameObject.transform); val3.transform.localPosition = Vector3.zero; val3.transform.localRotation = Quaternion.identity; rotationJets.Add(val3.GetComponentInChildren()); ListEx.Last(rotationJets).rotationAxis_ = JetDirection(gameObject.transform); } else if ((Object)(object)infos_.wingTrail != (Object)null && text.Contains("wingtrail")) { GameObject val4 = Object.Instantiate(infos_.wingTrail, gameObject.transform); val4.transform.localPosition = Vector3.zero; val4.transform.localRotation = Quaternion.identity; } else { PlaceJets(gameObject, boostJets, wingJets, rotationJets); } } } private Vector3 JetDirection(Transform transform) { //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01d5: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) int childCount = transform.childCount; for (int i = 0; i < childCount; i++) { string text = ((Object)((Component)transform.GetChild(i)).gameObject).name.ToLower(); if (!text.StartsWith("#")) { continue; } text = text.Remove(0, 1); string[] array = text.Split(new char[1] { ';' }); if (array.Length != 0 && array[0].Contains("dir") && array.Length >= 2) { if (array[1] == "front") { return new Vector3(-1f, 0f, 0f); } if (array[1] == "back") { return new Vector3(1f, 0f, 0f); } if (array[1] == "left") { return new Vector3(0f, 1f, -1f); } if (array[1] == "right") { return new Vector3(0f, -1f, 1f); } if (array.Length == 4 && array[0].Contains("dir")) { Vector3 zero = Vector3.zero; float.TryParse(array[1], out zero.x); float.TryParse(array[2], out zero.y); float.TryParse(array[3], out zero.z); return zero; } } } return Vector3.zero; } private Transform FindCarDriver(Transform parent) { for (int i = 0; i < parent.childCount; i++) { Transform child = parent.GetChild(i); Transform val = ((((Object)((Component)child).gameObject).name.IndexOf("driverposition", StringComparison.InvariantCultureIgnoreCase) >= 0) ? child : FindCarDriver(child)); if ((Object)(object)val != (Object)null) { return val; } } return null; } private void PlaceCarWheelsVisuals(CarVisuals visual, GameObject car) { for (int i = 0; i < car.transform.childCount; i++) { GameObject gameObject = ((Component)car.transform.GetChild(i)).gameObject; string text = ((Object)gameObject).name.ToLower(); if (!text.Contains("wheel")) { continue; } CarWheelVisuals val = gameObject.AddComponent(); MeshRenderer[] componentsInChildren = gameObject.GetComponentsInChildren(); foreach (MeshRenderer val2 in componentsInChildren) { if (((Object)((Component)val2).gameObject).name.IndexOf("tire", StringComparison.InvariantCultureIgnoreCase) >= 0) { val.tire_ = val2; break; } } if (text.Contains("front")) { if (text.Contains("left")) { visual.wheelFL_ = val; } else if (text.Contains("right")) { visual.wheelFR_ = val; } } else if (text.Contains("back")) { if (text.Contains("left")) { visual.wheelBL_ = val; } else if (text.Contains("right")) { visual.wheelBR_ = val; } } } } private CarColors LoadDefaultColors(GameObject car) { //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) CarColors val2 = default(CarColors); for (int i = 0; i < car.transform.childCount; i++) { GameObject gameObject = ((Component)car.transform.GetChild(i)).gameObject; string text = ((Object)gameObject).name.ToLower(); if (!text.Contains("defaultcolor")) { continue; } for (int j = 0; j < gameObject.transform.childCount; j++) { GameObject gameObject2 = ((Component)gameObject.transform.GetChild(j)).gameObject; string text2 = ((Object)gameObject2).name.ToLower(); if (!text2.StartsWith("#")) { continue; } text2 = text2.Remove(0, 1); string[] array = text2.Split(new char[1] { ';' }); if (array.Length == 2) { Color val = ColorEx.HexToColor(array[1], byte.MaxValue); val.a = 1f; if (array[0] == "primary") { val2.primary_ = val; } else if (array[0] == "secondary") { val2.secondary_ = val; } else if (array[0] == "glow") { val2.glow_ = val; } else if (array[0] == "sparkle") { val2.sparkle_ = val; } } } } return infos_.defaultColors; } } public class CarInfos { public Dictionary materials = new Dictionary(); public GameObject boostJet = null; public GameObject wingJet = null; public GameObject rotationJet = null; public GameObject wingTrail = null; public GameObject baseCar = null; public CarColors defaultColors; public void CollectInfos() { GetBaseCar(); GetJetsAndTrail(); GetMaterials(); } private void GetBaseCar() { //IL_0059: 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) GameObject carPrefab_ = G.Sys.ProfileManager_.carInfos_[0].prefabs_.carPrefab_; if ((Object)(object)carPrefab_ == (Object)null) { Mod.Instance.Errors.Add("Can't find the refractor base car prefab"); return; } baseCar = carPrefab_; defaultColors = G.Sys.ProfileManager_.carInfos_[0].colors_; } private void GetJetsAndTrail() { if ((Object)(object)baseCar == (Object)null) { return; } JetFlame[] componentsInChildren = baseCar.GetComponentsInChildren(); foreach (JetFlame val in componentsInChildren) { switch (((Object)((Component)val).gameObject).name) { case "BoostJetFlameCenter": boostJet = ((Component)val).gameObject; break; case "JetFlameBackLeft": rotationJet = ((Component)val).gameObject; break; case "WingJetFlameLeft1": wingJet = ((Component)val).gameObject; break; } } wingTrail = ((Component)baseCar.GetComponentInChildren()).gameObject; if ((Object)(object)boostJet == (Object)null) { Mod.Instance.Errors.Add("No valid BoostJet found on Refractor"); } if ((Object)(object)rotationJet == (Object)null) { Mod.Instance.Errors.Add("No valid RotationJet found on Refractor"); } if ((Object)(object)wingJet == (Object)null) { Mod.Instance.Errors.Add("No valid WingJet found on Refractor"); } if ((Object)(object)wingTrail == (Object)null) { Mod.Instance.Errors.Add("No valid WingTrail found on Refractor"); } } private void GetMaterials() { List list = new List { new MaterialPropertyInfo("Custom/LaserCut/CarPaint", "carpaint", 5, -1, -1), new MaterialPropertyInfo("Custom/LaserCut/CarWindow", "carwindow", -1, 218, 219), new MaterialPropertyInfo("Custom/Reflective/Bump Glow LaserCut", "wheel", 5, 218, 255), new MaterialPropertyInfo("Custom/LaserCut/CarPaintBump", "carpaintbump", 5, 218, -1), new MaterialPropertyInfo("Custom/Reflective/Bump Glow Interceptor Special", "interceptor", 5, 218, 255), new MaterialPropertyInfo("Custom/LaserCut/CarWindowTrans2Sided", "transparentglow", -1, 218, 219) }; CarInfo[] carInfos_ = G.Sys.ProfileManager_.carInfos_; foreach (CarInfo val in carInfos_) { GameObject carPrefab_ = val.prefabs_.carPrefab_; Renderer[] componentsInChildren = carPrefab_.GetComponentsInChildren(); foreach (Renderer val2 in componentsInChildren) { Material[] array = val2.materials; foreach (Material val3 in array) { foreach (MaterialPropertyInfo item in list) { if (!materials.ContainsKey(item.name) && ((Object)val3.shader).name == item.shaderName) { MaterialInfos value = new MaterialInfos { material = val3, diffuseIndex = item.diffuseIndex, normalIndex = item.normalIndex, emitIndex = item.emitIndex }; materials.Add(item.name, value); } } } } } foreach (MaterialPropertyInfo item2 in list) { if (!materials.ContainsKey(item2.name)) { Mod.Instance.Errors.Add("Can't find the material: " + item2.name + " - shader: " + item2.shaderName); } } materials.Add("donotreplace", new MaterialInfos()); } } public class PrefabIndex { private static readonly string IndexPath; public Dictionary Files { get; set; } = new Dictionary(); static PrefabIndex() { string directoryName = Path.GetDirectoryName(typeof(PrefabIndex).Assembly.Location); IndexPath = Path.Combine(directoryName, Path.Combine("Settings", "prefab_index.json")); } public string[] GetPrefabNames(string filePath) { if (Files.TryGetValue(filePath, out var value) && value.PrefabNames != null) { return value.PrefabNames; } return null; } public void SetPrefabNames(string filePath, string[] prefabNames) { Files[filePath] = new PrefabIndexEntry { LastWriteTime = GetLastWriteSafe(filePath), PrefabNames = (prefabNames ?? new string[0]) }; } public bool IsUpToDate(string filePath) { if (!Files.TryGetValue(filePath, out var value)) { return false; } return value.LastWriteTime == GetLastWriteSafe(filePath); } public void RemoveStaleEntries(HashSet validPaths) { List list = new List(); foreach (string key in Files.Keys) { if (!validPaths.Contains(key)) { list.Add(key); } } foreach (string item in list) { Files.Remove(item); } } private static long GetLastWriteSafe(string path) { try { return File.GetLastWriteTimeUtc(path).Ticks; } catch { return 0L; } } public void Load() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown try { if (!File.Exists(IndexPath)) { return; } string text = File.ReadAllText(IndexPath); JsonReader val = new JsonReader(); Dictionary dictionary = ((DataReader)(object)val).Read>(text); if (dictionary == null) { return; } Files.Clear(); foreach (KeyValuePair item in dictionary) { if (!(item.Value is Dictionary dictionary2)) { continue; } PrefabIndexEntry prefabIndexEntry = new PrefabIndexEntry(); if (dictionary2.TryGetValue("LastWriteTime", out var value)) { prefabIndexEntry.LastWriteTime = Convert.ToInt64(value); } if (dictionary2.TryGetValue("PrefabNames", out var value2) && value2 is List list) { prefabIndexEntry.PrefabNames = list.ConvertAll((object x) => x?.ToString() ?? string.Empty).ToArray(); } Files[item.Key] = prefabIndexEntry; } } catch (Exception ex) { Mod.Log.LogWarning((object)("Failed to load prefab index: " + ex.Message)); Files.Clear(); } } public void Save() { //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Expected O, but got Unknown //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Expected O, but got Unknown try { Dictionary dictionary = new Dictionary(); foreach (KeyValuePair file in Files) { Dictionary dictionary2 = new Dictionary(); dictionary2["LastWriteTime"] = file.Value.LastWriteTime; dictionary2["PrefabNames"] = new List(file.Value.PrefabNames ?? new string[0]); Dictionary value = dictionary2; dictionary[file.Key] = value; } string directoryName = Path.GetDirectoryName(IndexPath); if (!Directory.Exists(directoryName)) { Directory.CreateDirectory(directoryName); } JsonWriter val = new JsonWriter(new DataWriterSettings { PrettyPrint = true }); File.WriteAllText(IndexPath, ((DataWriter)(object)val).Write((object)dictionary)); } catch (Exception ex) { Mod.Log.LogWarning((object)("Failed to save prefab index: " + ex.Message)); } } } public class PrefabIndexEntry { public long LastWriteTime { get; set; } public string[] PrefabNames { get; set; } = new string[0]; } public class CreateCarReturnInfos { public GameObject car; public CarColors colors; } }