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<T>(this Dictionary<string, object> obj, string key)
{
try
{
obj.GetItem<T>(key);
return true;
}
catch
{
return false;
}
}
public static T GetItem<T>(this Dictionary<string, object> 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<T>(this Dictionary<string, object> obj, string key) where T : new()
{
if (!obj.ContainsKey(key))
{
obj[key] = new T();
}
return obj.GetItem<T>(key);
}
public static T GetOrCreate<T>(this Dictionary<string, object> obj, string key, T defaultValue)
{
if (!obj.ContainsKey<T>(key))
{
obj[key] = defaultValue;
}
return obj.GetItem<T>(key);
}
public static T GetOrCreate<T>(this Dictionary<string, object> obj, string key, Func<T> 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<Assembly> 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<string, bool> 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<string> 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<string> 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<string> GetDirectories(string directoryPath)
{
return GetDirectories(directoryPath, "*");
}
public List<string> 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<string> 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<bool> 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<ProfileCarColors>();
UseTrumpetHorn = ((BaseUnityPlugin)this).Config.Bind<bool>("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<Data>.Subscribe((Delegate<Data>)OnMainMenuLoaded);
}
private void OnDisable()
{
StaticEvent<Data>.Unsubscribe((Delegate<Data>)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<ProfileCarColors> OnChanged;
protected void Load()
{
Config = new Settings("CustomCars");
}
protected void Awake()
{
Load();
Save();
}
protected Dictionary<string, object> Profile(string profileName)
{
return Config.GetOrCreate(profileName, () => new Dictionary<string, object>());
}
protected Dictionary<string, object> Vehicle(string profileName, string vehicleName)
{
return Profile(profileName).GetOrCreate(vehicleName, () => new Dictionary<string, object>());
}
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<string, object> 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<string, object> 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<string, object> orCreate = vehicle.GetOrCreate(category, () => new Dictionary<string, object>());
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<string, object> 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<string, object> 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<Profile> 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<Profile> 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<string, object>
{
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<SettingsChangedEventArgs> ValueChanged;
public T GetItem<T>(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<T>(string key) where T : new()
{
if (!ContainsKey(key))
{
this[key] = new T();
this.ValueChanged?.Invoke(this, new SettingsChangedEventArgs(key, null, this[key]));
}
return GetItem<T>(key);
}
public T GetOrCreate<T>(string key, T defaultValue)
{
if (!ContainsKey<T>(key))
{
this[key] = defaultValue;
this.ValueChanged?.Invoke(this, new SettingsChangedEventArgs(key, null, this[key]));
}
return GetItem<T>(key);
}
public T GetOrCreate<T>(string key, Func<T> 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<T>(string key)
{
try
{
GetItem<T>(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<ModelTokenType>)(object)val).Read<Section>(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<ModelTokenType>)(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<Animation>(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>(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<string>
{
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<string, GameObject> dictionary = LoadAssetsBundles();
List<CreateCarReturnInfos> list = new List<CreateCarReturnInfos>();
foreach (KeyValuePair<string, GameObject> 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<CreateCarReturnInfos> 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<CarInfo>((ICollection<CarInfo>)profileManager_.carInfos_);
profileManager_.carInfos_ = (CarInfo[])(object)new CarInfo[array.Length + carsInfos.Count];
ref Dictionary<string, int> unlockedCars_ = ref profileManager_.unlockedCars_;
ref Dictionary<string, int> 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<string, GameObject> LoadAssetsBundles()
{
Dictionary<string, GameObject> dictionary = new Dictionary<string, GameObject>();
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<FileInfo> list = new List<FileInfo>();
foreach (FileInfo item in from x in ArrayEx.Concat<FileInfo>(directoryInfo2.GetFiles("*", SearchOption.AllDirectories), directoryInfo.GetFiles("*", SearchOption.AllDirectories))
orderby x.Name
select x)
{
if (item.Extension == "" && HasValidBundleSignature(item.FullName))
{
list.Add(item);
}
}
List<FileInfo> list2 = list;
HashSet<string> hashSet = new HashSet<string>();
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<GameObject>(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<string> list = new List<string>();
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<GameObject>(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<GameObject> list = new List<GameObject>();
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<GameObject>(car, obj.transform);
}
private void SetCarDatas(GameObject obj, GameObject car)
{
SetColorChanger(obj.GetComponent<ColorChanger>(), car);
SetCarVisuals(obj.GetComponent<CarVisuals>(), 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<Renderer>();
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<MaterialPropertyExport>[] array2 = new List<MaterialPropertyExport>[renderer.materials.Length];
for (int j = 0; j < array2.Length; j++)
{
array2[j] = new List<MaterialPropertyExport>();
}
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<Material>(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<MaterialPropertyExport>[] 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<Renderer>();
if ((Object)(object)component == (Object)null)
{
return;
}
List<UniformChanger> list = new List<UniformChanger>();
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<RendererChanger> 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<SkinnedMeshRenderer>();
MakeMeshSkinned(componentInChildren);
visuals.carBodyRenderer_ = componentInChildren;
List<JetFlame> list = new List<JetFlame>();
List<JetFlame> list2 = new List<JetFlame>();
List<JetFlame> list3 = new List<JetFlame>();
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<JetFlame> boostJets, List<JetFlame> wingJets, List<JetFlame> 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<GameObject>(infos_.boostJet, gameObject.transform);
val.transform.localPosition = Vector3.zero;
val.transform.localRotation = Quaternion.identity;
boostJets.Add(val.GetComponentInChildren<JetFlame>());
}
else if ((Object)(object)infos_.wingJet != (Object)null && text.Contains("wingjet"))
{
GameObject val2 = Object.Instantiate<GameObject>(infos_.wingJet, gameObject.transform);
val2.transform.localPosition = Vector3.zero;
val2.transform.localRotation = Quaternion.identity;
wingJets.Add(val2.GetComponentInChildren<JetFlame>());
ListEx.Last<JetFlame>(wingJets).rotationAxis_ = JetDirection(gameObject.transform);
}
else if ((Object)(object)infos_.rotationJet != (Object)null && text.Contains("rotationjet"))
{
GameObject val3 = Object.Instantiate<GameObject>(infos_.rotationJet, gameObject.transform);
val3.transform.localPosition = Vector3.zero;
val3.transform.localRotation = Quaternion.identity;
rotationJets.Add(val3.GetComponentInChildren<JetFlame>());
ListEx.Last<JetFlame>(rotationJets).rotationAxis_ = JetDirection(gameObject.transform);
}
else if ((Object)(object)infos_.wingTrail != (Object)null && text.Contains("wingtrail"))
{
GameObject val4 = Object.Instantiate<GameObject>(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<CarWheelVisuals>();
MeshRenderer[] componentsInChildren = gameObject.GetComponentsInChildren<MeshRenderer>();
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<string, MaterialInfos> materials = new Dictionary<string, MaterialInfos>();
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<JetFlame>();
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<WingTrail>()).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<MaterialPropertyInfo> list = new List<MaterialPropertyInfo>
{
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<Renderer>();
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<string, PrefabIndexEntry> Files { get; set; } = new Dictionary<string, PrefabIndexEntry>();
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<string> validPaths)
{
List<string> list = new List<string>();
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<string, object> dictionary = ((DataReader<ModelTokenType>)(object)val).Read<Dictionary<string, object>>(text);
if (dictionary == null)
{
return;
}
Files.Clear();
foreach (KeyValuePair<string, object> item in dictionary)
{
if (!(item.Value is Dictionary<string, object> 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<object> 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<string, object> dictionary = new Dictionary<string, object>();
foreach (KeyValuePair<string, PrefabIndexEntry> file in Files)
{
Dictionary<string, object> dictionary2 = new Dictionary<string, object>();
dictionary2["LastWriteTime"] = file.Value.LastWriteTime;
dictionary2["PrefabNames"] = new List<object>(file.Value.PrefabNames ?? new string[0]);
Dictionary<string, object> 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<ModelTokenType>)(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;
}
}