using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using Assimp; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using UnityEngine; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyVersion("0.0.0.0")] public class OBJLoader { private struct OBJFace { public string materialName; public string meshName; public int[] indexes; } public static bool splitByMaterial = false; public static string[] searchPaths = new string[2] { "", "%FileName%_Textures" + Path.DirectorySeparatorChar }; public static Vector3 ParseVectorFromCMPS(string[] cmps) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) float num = float.Parse(cmps[1]); float num2 = float.Parse(cmps[2]); if (cmps.Length == 4) { float num3 = float.Parse(cmps[3]); return new Vector3(num, num2, num3); } return Vector2.op_Implicit(new Vector2(num, num2)); } public static Color ParseColorFromCMPS(string[] cmps, float scalar = 1f) { //IL_0025: 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_002d: Unknown result type (might be due to invalid IL or missing references) float num = float.Parse(cmps[1]) * scalar; float num2 = float.Parse(cmps[2]) * scalar; float num3 = float.Parse(cmps[3]) * scalar; return new Color(num, num2, num3); } public static string OBJGetFilePath(string path, string basePath, string fileName) { string[] array = searchPaths; foreach (string text in array) { string text2 = text.Replace("%FileName%", fileName); if (File.Exists(basePath + text2 + path)) { return basePath + text2 + path; } if (File.Exists(path)) { return path; } } return null; } public static Material[] LoadMTLFile(string fn) { //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Expected O, but got Unknown //IL_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Unknown result type (might be due to invalid IL or missing references) //IL_0246: Unknown result type (might be due to invalid IL or missing references) //IL_024b: Unknown result type (might be due to invalid IL or missing references) //IL_025c: Unknown result type (might be due to invalid IL or missing references) Material val = null; List list = new List(); FileInfo fileInfo = new FileInfo(fn); string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fn); string basePath = fileInfo.Directory.FullName + Path.DirectorySeparatorChar; string[] array = File.ReadAllLines(fn); foreach (string text in array) { string text2 = text.Trim().Replace(" ", " "); string[] array2 = text2.Split(' '); string text3 = text2.Remove(0, text2.IndexOf(' ') + 1); if (array2[0] == "newmtl") { if ((Object)(object)val != (Object)null) { list.Add(val); } val = new Material(Shader.Find("Standard (Specular setup)")); ((Object)val).name = text3; } else if (array2[0] == "Kd") { val.SetColor("_Color", ParseColorFromCMPS(array2)); } else if (array2[0] == "map_Kd") { string text4 = OBJGetFilePath(text3, basePath, fileNameWithoutExtension); if (text4 != null) { val.SetTexture("_MainTex", (Texture)(object)TextureLoader.LoadTexture(text4)); } } else if (array2[0] == "map_Bump") { string text5 = OBJGetFilePath(text3, basePath, fileNameWithoutExtension); if (text5 != null) { val.SetTexture("_BumpMap", (Texture)(object)TextureLoader.LoadTexture(text5, normalMap: true)); val.EnableKeyword("_NORMALMAP"); } } else if (array2[0] == "Ks") { val.SetColor("_SpecColor", ParseColorFromCMPS(array2)); } else if (array2[0] == "Ka") { val.SetColor("_EmissionColor", ParseColorFromCMPS(array2, 0.05f)); val.EnableKeyword("_EMISSION"); } else if (array2[0] == "d") { float num = float.Parse(array2[1]); if (num < 1f) { Color color = val.color; color.a = num; val.SetColor("_Color", color); val.SetFloat("_Mode", 3f); val.SetInt("_SrcBlend", 5); val.SetInt("_DstBlend", 10); val.SetInt("_ZWrite", 0); val.DisableKeyword("_ALPHATEST_ON"); val.EnableKeyword("_ALPHABLEND_ON"); val.DisableKeyword("_ALPHAPREMULTIPLY_ON"); val.renderQueue = 3000; } } else if (array2[0] == "Ns") { float num2 = float.Parse(array2[1]); num2 /= 1000f; val.SetFloat("_Glossiness", num2); } } if ((Object)(object)val != (Object)null) { list.Add(val); } return list.ToArray(); } public static GameObject LoadOBJFile(string fn) { //IL_05cf: Unknown result type (might be due to invalid IL or missing references) //IL_05d6: Expected O, but got Unknown //IL_0609: Unknown result type (might be due to invalid IL or missing references) //IL_0610: Expected O, but got Unknown //IL_063a: Unknown result type (might be due to invalid IL or missing references) //IL_0645: Unknown result type (might be due to invalid IL or missing references) //IL_064c: Expected O, but got Unknown //IL_020d: Unknown result type (might be due to invalid IL or missing references) //IL_0236: Unknown result type (might be due to invalid IL or missing references) //IL_0260: Unknown result type (might be due to invalid IL or missing references) //IL_0265: Unknown result type (might be due to invalid IL or missing references) //IL_07d5: Unknown result type (might be due to invalid IL or missing references) //IL_07e6: Unknown result type (might be due to invalid IL or missing references) //IL_07f7: Unknown result type (might be due to invalid IL or missing references) //IL_0946: Unknown result type (might be due to invalid IL or missing references) //IL_094c: Expected O, but got Unknown //IL_0989: Unknown result type (might be due to invalid IL or missing references) //IL_098f: Expected O, but got Unknown //IL_042b: Unknown result type (might be due to invalid IL or missing references) //IL_0469: Unknown result type (might be due to invalid IL or missing references) //IL_0453: Unknown result type (might be due to invalid IL or missing references) //IL_04a8: Unknown result type (might be due to invalid IL or missing references) //IL_0493: Unknown result type (might be due to invalid IL or missing references) string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fn); bool flag = false; List list = new List(); List list2 = new List(); List list3 = new List(); List list4 = new List(); List list5 = new List(); List list6 = new List(); List list7 = new List(); List list8 = new List(); Dictionary dictionary = new Dictionary(); List list9 = new List(); string text = ""; string text2 = "default"; Material[] array = null; FileInfo fileInfo = new FileInfo(fn); string[] array2 = File.ReadAllLines(fn); foreach (string text3 in array2) { if (text3.Length <= 0 || text3[0] == '#') { continue; } string text4 = text3.Trim().Replace(" ", " "); string[] array3 = text4.Split(' '); string text5 = text4.Remove(0, text4.IndexOf(' ') + 1); if (array3[0] == "mtllib") { string text6 = OBJGetFilePath(text5, fileInfo.Directory.FullName + Path.DirectorySeparatorChar, fileNameWithoutExtension); if (text6 != null) { array = LoadMTLFile(text6); } } else if ((array3[0] == "g" || array3[0] == "o") && !splitByMaterial) { text2 = text5; if (!list8.Contains(text2)) { list8.Add(text2); } } else if (array3[0] == "usemtl") { text = text5; if (!list7.Contains(text)) { list7.Add(text); } if (splitByMaterial && !list8.Contains(text)) { list8.Add(text); } } else if (array3[0] == "v") { list.Add(ParseVectorFromCMPS(array3)); } else if (array3[0] == "vn") { list2.Add(ParseVectorFromCMPS(array3)); } else if (array3[0] == "vt") { list3.Add(Vector2.op_Implicit(ParseVectorFromCMPS(array3))); } else { if (!(array3[0] == "f")) { continue; } int[] array4 = new int[array3.Length - 1]; for (int j = 1; j < array3.Length; j++) { string text7 = array3[j]; int num = -1; int num2 = -1; int num3 = -1; if (text7.Contains("//")) { string[] array5 = text7.Split('/'); num = int.Parse(array5[0]) - 1; num2 = int.Parse(array5[2]) - 1; } else if (text7.Count((char x) => x == '/') == 2) { string[] array6 = text7.Split('/'); num = int.Parse(array6[0]) - 1; num3 = int.Parse(array6[1]) - 1; num2 = int.Parse(array6[2]) - 1; } else if (!text7.Contains("/")) { num = int.Parse(text7) - 1; } else { string[] array7 = text7.Split('/'); num = int.Parse(array7[0]) - 1; num3 = int.Parse(array7[1]) - 1; } string key = num + "|" + num2 + "|" + num3; if (dictionary.ContainsKey(key)) { array4[j - 1] = dictionary[key]; continue; } array4[j - 1] = dictionary.Count; dictionary[key] = dictionary.Count; list4.Add(list[num]); if (num2 < 0 || num2 > list2.Count - 1) { list5.Add(Vector3.zero); } else { flag = true; list5.Add(list2[num2]); } if (num3 < 0 || num3 > list3.Count - 1) { list6.Add(Vector2.zero); } else { list6.Add(list3[num3]); } } if (array4.Length < 5 && array4.Length >= 3) { list9.Add(new OBJFace { materialName = text, indexes = new int[3] { array4[0], array4[1], array4[2] }, meshName = (splitByMaterial ? text : text2) }); if (array4.Length > 3) { list9.Add(new OBJFace { materialName = text, meshName = (splitByMaterial ? text : text2), indexes = new int[3] { array4[2], array4[3], array4[0] } }); } } } } if (list8.Count == 0) { list8.Add("default"); } GameObject val = new GameObject(fileNameWithoutExtension); foreach (string obj in list8) { GameObject val2 = new GameObject(obj); val2.transform.SetParent(val.transform); val2.transform.localScale = new Vector3(-1f, 1f, 1f); Mesh val3 = new Mesh(); ((Object)val3).name = obj; List list10 = new List(); List list11 = new List(); List list12 = new List(); List list13 = new List(); Dictionary dictionary2 = new Dictionary(); List meshMaterialNames = new List(); OBJFace[] source = list9.Where((OBJFace x) => x.meshName == obj).ToArray(); foreach (string mn in list7) { OBJFace[] array8 = source.Where((OBJFace x) => x.materialName == mn).ToArray(); if (array8.Length == 0) { continue; } int[] array9 = new int[0]; OBJFace[] array10 = array8; for (int num4 = 0; num4 < array10.Length; num4++) { OBJFace oBJFace = array10[num4]; int num5 = array9.Length; Array.Resize(ref array9, num5 + oBJFace.indexes.Length); Array.Copy(oBJFace.indexes, 0, array9, num5, oBJFace.indexes.Length); } meshMaterialNames.Add(mn); if (val3.subMeshCount != meshMaterialNames.Count) { val3.subMeshCount = meshMaterialNames.Count; } for (int num6 = 0; num6 < array9.Length; num6++) { int num7 = array9[num6]; if (dictionary2.ContainsKey(num7)) { array9[num6] = dictionary2[num7]; continue; } list10.Add(list4[num7]); list11.Add(list5[num7]); list12.Add(list6[num7]); dictionary2[num7] = list10.Count - 1; array9[num6] = dictionary2[num7]; } list13.Add(array9); } val3.vertices = list10.ToArray(); val3.normals = list11.ToArray(); val3.uv = list12.ToArray(); for (int num8 = 0; num8 < list13.Count; num8++) { val3.SetTriangles(list13[num8], num8); } if (!flag) { val3.RecalculateNormals(); } val3.RecalculateBounds(); MeshFilter val4 = val2.AddComponent(); MeshRenderer val5 = val2.AddComponent(); Material[] array11 = (Material[])(object)new Material[meshMaterialNames.Count]; int i2; for (i2 = 0; i2 < meshMaterialNames.Count; i2++) { if (array == null) { array11[i2] = new Material(Shader.Find("Standard (Specular setup)")); } else { Material val6 = Array.Find(array, (Material x) => ((Object)x).name == meshMaterialNames[i2]); if ((Object)(object)val6 == (Object)null) { array11[i2] = new Material(Shader.Find("Standard (Specular setup)")); } else { array11[i2] = val6; } } ((Object)array11[i2]).name = meshMaterialNames[i2]; } ((Renderer)val5).materials = array11; val4.mesh = val3; } return val; } } public class TextureLoader : MonoBehaviour { public static Texture2D LoadTGA(string fileName) { using FileStream tGAStream = File.OpenRead(fileName); return LoadTGA(tGAStream); } public static Texture2D LoadDDSManual(string ddsPath) { //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Expected O, but got Unknown //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Expected O, but got Unknown //IL_0071: Unknown result type (might be due to invalid IL or missing references) try { byte[] array = File.ReadAllBytes(ddsPath); byte b = array[4]; if (b != 124) { throw new Exception("Invalid DDS DXTn texture. Unable to read"); } int num = array[13] * 256 + array[12]; int num2 = array[17] * 256 + array[16]; byte b2 = array[87]; TextureFormat val = (TextureFormat)12; if (b2 == 49) { val = (TextureFormat)10; } if (b2 == 53) { val = (TextureFormat)12; } int num3 = 128; byte[] array2 = new byte[array.Length - num3]; Buffer.BlockCopy(array, num3, array2, 0, array.Length - num3); FileInfo fileInfo = new FileInfo(ddsPath); Texture2D val2 = new Texture2D(num2, num, val, false); val2.LoadRawTextureData(array2); val2.Apply(); ((Object)val2).name = fileInfo.Name; return val2; } catch (Exception) { Debug.LogError((object)"Error: Could not load DDS"); return new Texture2D(8, 8); } } public static void SetNormalMap(ref Texture2D tex) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) Color[] pixels = tex.GetPixels(); for (int i = 0; i < pixels.Length; i++) { Color val = pixels[i]; val.r = pixels[i].g; val.a = pixels[i].r; pixels[i] = val; } tex.SetPixels(pixels); } public static Texture2D LoadTexture(string fn, bool normalMap = false) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected O, but got Unknown if (!File.Exists(fn)) { return null; } string text = Path.GetExtension(fn).ToLower(); if (text == ".png" || text == ".jpg") { Texture2D tex = new Texture2D(1, 1); ImageConversion.LoadImage(tex, File.ReadAllBytes(fn)); if (normalMap) { SetNormalMap(ref tex); } return tex; } if (text == ".dds") { Texture2D tex2 = LoadDDSManual(fn); if (normalMap) { SetNormalMap(ref tex2); } return tex2; } if (text == ".tga") { Texture2D tex3 = LoadTGA(fn); if (normalMap) { SetNormalMap(ref tex3); } return tex3; } Debug.Log((object)("texture not supported : " + fn)); return null; } public static Texture2D LoadTGA(Stream TGAStream) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Expected O, but got Unknown //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) using BinaryReader binaryReader = new BinaryReader(TGAStream); binaryReader.BaseStream.Seek(12L, SeekOrigin.Begin); short num = binaryReader.ReadInt16(); short num2 = binaryReader.ReadInt16(); int num3 = binaryReader.ReadByte(); binaryReader.BaseStream.Seek(1L, SeekOrigin.Current); Texture2D val = new Texture2D((int)num, (int)num2); Color32[] array = (Color32[])(object)new Color32[num * num2]; switch (num3) { case 32: { for (int j = 0; j < num * num2; j++) { byte b4 = binaryReader.ReadByte(); byte b5 = binaryReader.ReadByte(); byte b6 = binaryReader.ReadByte(); byte b7 = binaryReader.ReadByte(); array[j] = new Color32(b6, b5, b4, b7); } break; } case 24: { for (int i = 0; i < num * num2; i++) { byte b = binaryReader.ReadByte(); byte b2 = binaryReader.ReadByte(); byte b3 = binaryReader.ReadByte(); array[i] = new Color32(b3, b2, b, (byte)1); } break; } default: throw new Exception("TGA texture had non 32/24 bit depth."); } val.SetPixels32(array); val.Apply(); return val; } } namespace CustomMeshes; [BepInPlugin("cjayride.CustomMeshes", "Custom Meshes", "0.5.0")] public class BepInExPlugin : BaseUnityPlugin { [HarmonyPatch(typeof(ZNetScene), "Awake")] private static class ZNetScene_Awake_Patch { private static void Postfix() { } } [HarmonyPatch(typeof(ItemDrop), "Awake")] private static class ItemDrop_Patch { private static void Postfix(ItemDrop __instance) { ItemData itemData = __instance.m_itemData; object obj; if (itemData == null) { obj = null; } else { GameObject dropPrefab = itemData.m_dropPrefab; obj = ((dropPrefab != null) ? ((Object)dropPrefab).name : null); } string text = (string)obj; if (text == null || !customMeshes.ContainsKey(text)) { return; } MeshFilter[] componentsInChildren = __instance.m_itemData.m_dropPrefab.GetComponentsInChildren(true); MeshFilter[] array = componentsInChildren; foreach (MeshFilter val in array) { string name = ((Object)((Component)((Component)val).transform.parent).gameObject).name; Dbgl("got mesh filter, item name: " + text + ", obj: " + name + ", mf: " + ((Object)val).name); if (text == GetPrefabName(name) && customMeshes[text].ContainsKey(((Object)val).name) && customMeshes[text][((Object)val).name].ContainsKey(((Object)val).name)) { Dbgl("replacing item mesh " + ((Object)val).name); val.mesh = customMeshes[text][((Object)val).name][((Object)val).name].mesh; } else if (customMeshes[text].ContainsKey(name) && customMeshes[text][name].ContainsKey(((Object)val).name)) { Dbgl("replacing attached mesh " + ((Object)val).name); val.mesh = customMeshes[text][name][((Object)val).name].mesh; } } SkinnedMeshRenderer[] componentsInChildren2 = __instance.m_itemData.m_dropPrefab.GetComponentsInChildren(true); SkinnedMeshRenderer[] array2 = componentsInChildren2; foreach (SkinnedMeshRenderer val2 in array2) { string name2 = ((Object)((Component)((Component)val2).transform.parent).gameObject).name; Dbgl("got skinned mesh renderer, item name: " + text + ", obj: " + name2 + ", smr: " + ((Object)val2).name); if (text == GetPrefabName(name2) && customMeshes[text].ContainsKey(((Object)val2).name) && customMeshes[text][((Object)val2).name].ContainsKey(((Object)val2).name)) { Dbgl("replacing item mesh " + ((Object)val2).name); val2.sharedMesh = customMeshes[text][((Object)val2).name][((Object)val2).name].mesh; } else if (customMeshes[text].ContainsKey(name2) && customMeshes[text][name2].ContainsKey(((Object)val2).name)) { Dbgl("replacing attached mesh " + ((Object)val2).name); val2.sharedMesh = customMeshes[text][name2][((Object)val2).name].mesh; } } } } [HarmonyPatch(typeof(Piece), "Awake")] private static class Piece_Patch { private static void Postfix(Piece __instance) { string prefabName = GetPrefabName(((Object)((Component)__instance).gameObject).name); MeshFilter[] componentsInChildren = ((Component)__instance).gameObject.GetComponentsInChildren(true); if (!customMeshes.ContainsKey(prefabName)) { return; } MeshFilter[] array = componentsInChildren; foreach (MeshFilter val in array) { string name = ((Object)((Component)((Component)val).transform.parent).gameObject).name; if (customMeshes[prefabName].ContainsKey(name) && customMeshes[prefabName][name].ContainsKey(((Object)val).name)) { val.mesh = customMeshes[prefabName][name][((Object)val).name].mesh; } } } } [HarmonyPatch(typeof(VisEquipment), "Awake")] private static class Awake_Patch { private static void Postfix(VisEquipment __instance) { Dbgl("Vis Awake ."); if (!__instance.m_isPlayer || __instance.m_models == null || __instance.m_models.Length == 0) { return; } Dbgl("Checking for custom player models."); if (!customMeshes.ContainsKey("player")) { return; } Dbgl("Has player."); if (!customMeshes["player"].ContainsKey("model")) { return; } Dbgl("Has player model."); SkinnedMeshRenderer val = null; if (customMeshes["player"]["model"].ContainsKey("0")) { Dbgl("Replacing player model 0 with imported mesh."); CustomMeshData customMeshData = customMeshes["player"]["model"]["0"]; __instance.m_models[0].m_mesh = customMeshData.mesh; val = customMeshData.renderer; } if (customMeshes["player"]["model"].ContainsKey("1")) { Dbgl("Replacing player model 1 with imported mesh."); CustomMeshData customMeshData2 = customMeshes["player"]["model"]["1"]; __instance.m_models[1].m_mesh = customMeshData2.mesh; val = customMeshData2.renderer; } if (!((Object)(object)val != (Object)null)) { return; } Transform parent = __instance.m_bodyModel.rootBone.parent; Dbgl("Setting up new bones array"); Transform[] array = (Transform[])(object)new Transform[val.bones.Length]; for (int i = 0; i < array.Length; i++) { array[i] = RecursiveFind(parent, ((Object)val.bones[i]).name); if ((Object)(object)array[i] == (Object)null) { Dbgl("Could not find existing bone " + ((Object)val.bones[i]).name); } } __instance.m_bodyModel.bones = array; } } [HarmonyPatch(typeof(InventoryGui), "SetupDragItem")] private static class SetupDragItem_Patch { private static void Postfix(ItemData item) { if (item != null && !((Object)(object)item.m_dropPrefab == (Object)null)) { string name = ((Object)item.m_dropPrefab).name; MeshFilter[] componentsInChildren = item.m_dropPrefab.GetComponentsInChildren(); MeshFilter[] array = componentsInChildren; foreach (MeshFilter val in array) { Dbgl("dragging item name: " + name + ", mf: " + ((Object)val).name); } } } } [HarmonyPatch(typeof(Player), "Awake")] private static class Player_Awake_Patch { private static void Postfix(Player __instance) { } } [HarmonyPatch(typeof(Terminal), "InputText")] private static class InputText_Patch { private static bool Prefix(Terminal __instance) { if (!modEnabled.Value) { return true; } return true; } } private static Dictionary>> customMeshes = new Dictionary>>(); private static Dictionary customAssetBundles = new Dictionary(); private static Dictionary>> customGameObjects = new Dictionary>>(); private static BepInExPlugin context; public static ConfigEntry modEnabled; public static ConfigEntry isDebug; public static Mesh customMesh { get; set; } public static void Dbgl(string str = "", bool pref = true) { if (isDebug.Value) { Debug.Log((object)((pref ? (typeof(BepInExPlugin).Namespace + " ") : "") + str)); } } private void Awake() { context = this; modEnabled = ((BaseUnityPlugin)this).Config.Bind("General", "Enabled", true, "Enable this mod"); isDebug = ((BaseUnityPlugin)this).Config.Bind("General", "IsDebug", false, "Enable debug"); if (modEnabled.Value) { SceneManager.sceneLoaded += SceneManager_sceneLoaded; Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), (string)null); } } private void Update() { if (!Input.GetKeyDown((KeyCode)117)) { } } private void SceneManager_sceneLoaded(Scene arg0, LoadSceneMode arg1) { PreloadMeshes(); } private static void PreloadMeshes() { foreach (AssetBundle value in customAssetBundles.Values) { value.Unload(true); } customMeshes.Clear(); customGameObjects.Clear(); customAssetBundles.Clear(); Dbgl("Importing meshes"); string path = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "CustomMeshes"); if (!Directory.Exists(path)) { Directory.CreateDirectory(path); return; } string[] directories = Directory.GetDirectories(path); foreach (string path2 in directories) { string fileName = Path.GetFileName(path2); Dbgl("Importing meshes: " + fileName); customMeshes[fileName] = new Dictionary>(); customGameObjects[fileName] = new Dictionary>(); string[] directories2 = Directory.GetDirectories(path2); foreach (string path3 in directories2) { string fileName2 = Path.GetFileName(path3); Dbgl("Importing meshes: " + fileName + "\\" + fileName2); customMeshes[fileName][fileName2] = new Dictionary(); customGameObjects[fileName][fileName2] = new Dictionary(); string[] files = Directory.GetFiles(path3); foreach (string text in files) { try { SkinnedMeshRenderer val = null; Mesh val2 = null; Dbgl("Importing " + text + " " + Path.GetFileNameWithoutExtension(text) + " " + Path.GetFileName(text) + " " + Path.GetExtension(text).ToLower()); string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(text); if (fileNameWithoutExtension == Path.GetFileName(text)) { AssetBundle val3 = AssetBundle.LoadFromFile(text); customAssetBundles.Add(fileNameWithoutExtension, val3); GameObject val4 = val3.LoadAsset("Player"); if ((Object)(object)val4 != (Object)null) { val = val4.GetComponentInChildren(); if ((Object)(object)val != (Object)null) { val2 = val.sharedMesh; Dbgl("Importing " + text + " asset bundle as player"); } else { Dbgl($"No SkinnedMeshRenderer on {val4}"); } if ((Object)(object)val2 == (Object)null) { val2 = val3.LoadAsset("body"); } } else { val2 = val3.LoadAsset("body"); if ((Object)(object)val2 != (Object)null) { Dbgl("Importing " + text + " asset bundle as mesh"); } else { Dbgl("Failed to find body"); } } } else if (Path.GetExtension(text).ToLower() == ".fbx") { GameObject val5 = MeshImporter.Load(text); object obj; if (val5 == null) { obj = null; } else { Transform obj2 = val5.transform.Find("Player"); if (obj2 == null) { obj = null; } else { Transform obj3 = obj2.Find("Visual"); obj = ((obj3 != null) ? ((Component)obj3).gameObject : null); } } GameObject val6 = (GameObject)obj; val2 = val5.GetComponentInChildren().mesh; if ((Object)(object)val6 != (Object)null) { val = val6.GetComponentInChildren(); } if ((Object)(object)val2 != (Object)null) { if ((Object)(object)val != (Object)null) { Dbgl("Importing " + text + " fbx as player"); } else { Dbgl("Importing " + text + " fbx as mesh"); } } } else if (Path.GetExtension(text).ToLower() == ".obj") { val2 = new ObjImporter().ImportFile(text); if ((Object)(object)val2 != (Object)null) { Dbgl("Imported " + text + " obj as mesh"); } } if ((Object)(object)val2 != (Object)null) { customMeshes[fileName][fileName2].Add(fileNameWithoutExtension, new CustomMeshData(fileName, fileNameWithoutExtension, val2, val)); Dbgl("Added mesh data to customMeshes[" + fileName + "][" + fileName2 + "][" + fileNameWithoutExtension + "]"); } } catch { } } } } } private static string GetPrefabName(string name) { char[] anyOf = new char[2] { '(', ' ' }; int num = name.IndexOfAny(anyOf); if (num >= 0) { return name.Substring(0, num); } return name; } private static Transform RecursiveFind(Transform parent, string childName) { Transform val = null; for (int i = 0; i < parent.childCount; i++) { val = parent.GetChild(i); if (((Object)val).name == childName) { break; } val = RecursiveFind(val, childName); if ((Object)(object)val != (Object)null) { break; } } return val; } } internal class CustomMeshData { public string objName; public string meshName; public Mesh mesh; public SkinnedMeshRenderer renderer; public CustomMeshData(string dirName, string name, Mesh mesh, SkinnedMeshRenderer renderer = null) { objName = dirName; meshName = name; this.mesh = mesh; this.renderer = renderer; } } internal class MeshMaterialBinding { private string meshName; private Mesh mesh; private Material material; public Mesh Mesh => mesh; public Material Material => material; public string MeshName => meshName; private MeshMaterialBinding() { } public MeshMaterialBinding(string meshName, Mesh mesh, Material material) { this.meshName = meshName; this.mesh = mesh; this.material = material; } } public class MeshImporter { public static GameObject Load(string meshPath, float scaleX = 1f, float scaleY = 1f, float scaleZ = 1f) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Expected O, but got Unknown //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: 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_00d7: 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_0103: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_03fe: Unknown result type (might be due to invalid IL or missing references) //IL_0405: Expected O, but got Unknown //IL_021a: Unknown result type (might be due to invalid IL or missing references) //IL_021f: Unknown result type (might be due to invalid IL or missing references) //IL_0224: Unknown result type (might be due to invalid IL or missing references) //IL_022c: Unknown result type (might be due to invalid IL or missing references) //IL_0233: Unknown result type (might be due to invalid IL or missing references) //IL_023a: Unknown result type (might be due to invalid IL or missing references) //IL_0282: Unknown result type (might be due to invalid IL or missing references) //IL_0287: Unknown result type (might be due to invalid IL or missing references) //IL_028c: Unknown result type (might be due to invalid IL or missing references) //IL_0294: Unknown result type (might be due to invalid IL or missing references) //IL_029b: Unknown result type (might be due to invalid IL or missing references) //IL_02a2: Unknown result type (might be due to invalid IL or missing references) //IL_03bf: Unknown result type (might be due to invalid IL or missing references) //IL_03c4: Unknown result type (might be due to invalid IL or missing references) //IL_03c9: Unknown result type (might be due to invalid IL or missing references) //IL_03d0: Unknown result type (might be due to invalid IL or missing references) //IL_03d7: Unknown result type (might be due to invalid IL or missing references) if (!File.Exists(meshPath)) { return null; } AssimpContext val = new AssimpContext(); Scene val2 = val.ImportFile(meshPath); if (val2 == null) { return null; } string fullName = Directory.GetParent(meshPath).FullName; List list = new List(); if (val2.HasMaterials) { Color color = default(Color); Color val4 = default(Color); foreach (Material material in val2.Materials) { Material val3 = new Material(Shader.Find("Standard")); if (material.HasColorDiffuse) { ((Color)(ref color))..ctor(material.ColorDiffuse.R, material.ColorDiffuse.G, material.ColorDiffuse.B, material.ColorDiffuse.A); val3.color = color; } if (material.HasColorEmissive) { ((Color)(ref val4))..ctor(material.ColorEmissive.R, material.ColorEmissive.G, material.ColorEmissive.B, material.ColorEmissive.A); val3.SetColor("_EmissionColor", val4); val3.EnableKeyword("_EMISSION"); } if (material.HasReflectivity) { val3.SetFloat("_Glossiness", material.Reflectivity); } bool flag = false; list.Add(val3); } } List uMeshAndMats = new List(); if (val2.HasMeshes) { foreach (Mesh mesh in val2.Meshes) { List list2 = new List(); List list3 = new List(); List list4 = new List(); List list5 = new List(); if (mesh.HasVertices) { foreach (Vector3D vertex in mesh.Vertices) { list2.Add(new Vector3(0f - vertex.X, vertex.Y, vertex.Z)); } } if (mesh.HasNormals) { foreach (Vector3D normal in mesh.Normals) { list3.Add(new Vector3(0f - normal.X, normal.Y, normal.Z)); } } if (mesh.HasFaces) { foreach (Face face in mesh.Faces) { if (face.IndexCount != 1 && face.IndexCount != 2) { for (int i = 0; i < face.IndexCount - 2; i++) { list5.Add(face.Indices[i + 2]); list5.Add(face.Indices[i + 1]); list5.Add(face.Indices[0]); } } } } if (mesh.HasTextureCoords(0)) { foreach (Vector3D item in mesh.TextureCoordinateChannels[0]) { list4.Add(new Vector2(item.X, item.Y)); } } Mesh val5 = new Mesh(); val5.vertices = list2.ToArray(); val5.normals = list3.ToArray(); val5.triangles = list5.ToArray(); val5.uv = list4.ToArray(); uMeshAndMats.Add(new MeshMaterialBinding(mesh.Name, val5, list[mesh.MaterialIndex])); } } return NodeToGameObject(val2.RootNode); GameObject NodeToGameObject(Node node) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0124: 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_0130: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_014a: 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_0156: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: 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_0057: Expected O, but got Unknown //IL_00c4: Unknown result type (might be due to invalid IL or missing references) GameObject val6 = new GameObject(node.Name); if (node.HasMeshes) { foreach (int meshIndex in node.MeshIndices) { MeshMaterialBinding meshMaterialBinding = uMeshAndMats[meshIndex]; GameObject val7 = new GameObject(meshMaterialBinding.MeshName); val7.AddComponent(); val7.AddComponent(); val7.AddComponent(); val7.GetComponent().mesh = meshMaterialBinding.Mesh; ((Renderer)val7.GetComponent()).material = meshMaterialBinding.Material; val7.transform.SetParent(val6.transform, true); val7.transform.localScale = new Vector3(scaleX, scaleY, scaleZ); } } Vector3D val8 = default(Vector3D); Quaternion val9 = default(Quaternion); Vector3D val10 = default(Vector3D); Matrix4x4 transform = node.Transform; ((Matrix4x4)(ref transform)).Decompose(ref val8, ref val9, ref val10); Quaternion val11 = default(Quaternion); ((Quaternion)(ref val11))..ctor(val9.X, val9.Y, val9.Z, val9.W); Vector3 eulerAngles = ((Quaternion)(ref val11)).eulerAngles; val6.transform.localScale = new Vector3(val8.X, val8.Y, val8.Z); val6.transform.localPosition = new Vector3(val10.X, val10.Y, val10.Z); val6.transform.localRotation = Quaternion.Euler(eulerAngles.x, 0f - eulerAngles.y, eulerAngles.z); if (node.HasChildren) { foreach (Node child in node.Children) { GameObject val12 = NodeToGameObject(child); val12.transform.SetParent(val6.transform, false); } } return val6; } } } public class ObjImporter { private struct meshStruct { public Vector3[] vertices; public Vector3[] normals; public Vector2[] uv; public Vector2[] uv1; public Vector2[] uv2; public int[] triangles; public int[] faceVerts; public int[] faceUVs; public Vector3[] faceData; public string name; public string fileName; } public Mesh ImportFile(string filePath) { //IL_0052: 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_0063: 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_0077: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Expected O, but got Unknown //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: 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_00d5: 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) meshStruct mesh = createMeshStruct(filePath); populateMeshStruct(ref mesh); Vector3[] array = (Vector3[])(object)new Vector3[mesh.faceData.Length]; Vector2[] array2 = (Vector2[])(object)new Vector2[mesh.faceData.Length]; Vector3[] array3 = (Vector3[])(object)new Vector3[mesh.faceData.Length]; int num = 0; Vector3[] faceData = mesh.faceData; foreach (Vector3 val in faceData) { array[num] = mesh.vertices[(int)val.x - 1]; if (val.y >= 1f) { array2[num] = mesh.uv[(int)val.y - 1]; } if (val.z >= 1f) { array3[num] = mesh.normals[(int)val.z - 1]; } num++; } Mesh val2 = new Mesh(); val2.vertices = array; val2.uv = array2; val2.normals = array3; val2.triangles = mesh.triangles; val2.RecalculateBounds(); val2.Optimize(); return val2; } private static meshStruct createMeshStruct(string filename) { int num = 0; int num2 = 0; int num3 = 0; int num4 = 0; int num5 = 0; meshStruct result = new meshStruct { fileName = filename }; StreamReader streamReader = File.OpenText(filename); string s = streamReader.ReadToEnd(); streamReader.Close(); using (StringReader stringReader = new StringReader(s)) { string text = stringReader.ReadLine(); char[] separator = new char[1] { ' ' }; while (text != null) { if (!text.StartsWith("f ") && !text.StartsWith("v ") && !text.StartsWith("vt ") && !text.StartsWith("vn ")) { text = stringReader.ReadLine(); if (text != null) { text = text.Replace(" ", " "); } continue; } text = text.Trim(); string[] array = text.Split(separator, 50); switch (array[0]) { case "v": num2++; break; case "vt": num3++; break; case "vn": num4++; break; case "f": num5 = num5 + array.Length - 1; num += 3 * (array.Length - 2); break; } text = stringReader.ReadLine(); if (text != null) { text = text.Replace(" ", " "); } } } result.triangles = new int[num]; result.vertices = (Vector3[])(object)new Vector3[num2]; result.uv = (Vector2[])(object)new Vector2[num3]; result.normals = (Vector3[])(object)new Vector3[num4]; result.faceData = (Vector3[])(object)new Vector3[num5]; return result; } private static void populateMeshStruct(ref meshStruct mesh) { //IL_03b8: Unknown result type (might be due to invalid IL or missing references) //IL_03bd: Unknown result type (might be due to invalid IL or missing references) //IL_0389: Unknown result type (might be due to invalid IL or missing references) //IL_038e: Unknown result type (might be due to invalid IL or missing references) //IL_03f0: Unknown result type (might be due to invalid IL or missing references) //IL_03f5: Unknown result type (might be due to invalid IL or missing references) //IL_032b: Unknown result type (might be due to invalid IL or missing references) //IL_0330: Unknown result type (might be due to invalid IL or missing references) //IL_035a: Unknown result type (might be due to invalid IL or missing references) //IL_035f: Unknown result type (might be due to invalid IL or missing references) //IL_041c: Unknown result type (might be due to invalid IL or missing references) //IL_0497: Unknown result type (might be due to invalid IL or missing references) //IL_0499: Unknown result type (might be due to invalid IL or missing references) StreamReader streamReader = File.OpenText(mesh.fileName); string s = streamReader.ReadToEnd(); streamReader.Close(); using StringReader stringReader = new StringReader(s); string text = stringReader.ReadLine(); char[] separator = new char[1] { ' ' }; char[] separator2 = new char[1] { '/' }; int num = 0; int num2 = 0; int num3 = 0; int num4 = 0; int num5 = 0; int num6 = 0; int num7 = 0; while (text != null) { if (!text.StartsWith("f ") && !text.StartsWith("v ") && !text.StartsWith("vt ") && !text.StartsWith("vn ") && !text.StartsWith("g ") && !text.StartsWith("usemtl ") && !text.StartsWith("mtllib ") && !text.StartsWith("vt1 ") && !text.StartsWith("vt2 ") && !text.StartsWith("vc ") && !text.StartsWith("usemap ")) { text = stringReader.ReadLine(); if (text != null) { text = text.Replace(" ", " "); } continue; } text = text.Trim(); string[] array = text.Split(separator, 50); switch (array[0]) { case "v": mesh.vertices[num3] = new Vector3(Convert.ToSingle(array[1]), Convert.ToSingle(array[2]), Convert.ToSingle(array[3])); num3++; break; case "vt": mesh.uv[num5] = new Vector2(Convert.ToSingle(array[1]), Convert.ToSingle(array[2])); num5++; break; case "vt1": mesh.uv[num6] = new Vector2(Convert.ToSingle(array[1]), Convert.ToSingle(array[2])); num6++; break; case "vt2": mesh.uv[num7] = new Vector2(Convert.ToSingle(array[1]), Convert.ToSingle(array[2])); num7++; break; case "vn": mesh.normals[num4] = new Vector3(Convert.ToSingle(array[1]), Convert.ToSingle(array[2]), Convert.ToSingle(array[3])); num4++; break; case "f": { int num8 = 1; List list = new List(); while (num8 < array.Length && (array[num8] ?? "").Length > 0) { Vector3 val = default(Vector3); string[] array2 = array[num8].Split(separator2, 3); val.x = Convert.ToInt32(array2[0]); if (array2.Length > 1) { if (array2[1] != "") { val.y = Convert.ToInt32(array2[1]); } val.z = Convert.ToInt32(array2[2]); } num8++; mesh.faceData[num2] = val; list.Add(num2); num2++; } for (num8 = 1; num8 + 2 < array.Length; num8++) { mesh.triangles[num] = list[0]; num++; mesh.triangles[num] = list[num8]; num++; mesh.triangles[num] = list[num8 + 1]; num++; } break; } } text = stringReader.ReadLine(); if (text != null) { text = text.Replace(" ", " "); } } } }