using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security.Cryptography;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using Bounce.Singletons;
using Newtonsoft.Json;
using TMPro;
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: AssemblyTitle("ObjImporterPlugin")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ObjImporterPlugin")]
[assembly: AssemblyCopyright("Copyright © 2023")]
[assembly: AssemblyTrademark("ObjImporterPlugin")]
[assembly: ComVisible(false)]
[assembly: Guid("c303405d-e66c-4316-9cdb-4e3ca15c6360")]
[assembly: AssemblyFileVersion("1.1.2.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.1.2.0")]
namespace LordAshes;
[BepInPlugin("org.lordashes.plugins.objimporter", "Obj Importer Plugin", "1.1.2.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class ObjImporterPlugin : BaseUnityPlugin
{
public static class Utility
{
public static bool isBoardLoaded()
{
return SimpleSingletonBehaviour<CameraController>.HasInstance && SingletonStateMBehaviour<BoardSessionManager, State<BoardSessionManager>>.HasInstance && !BoardSessionManager.IsLoading;
}
public static Guid GuidFromString(string input)
{
using MD5 mD = MD5.Create();
byte[] b = mD.ComputeHash(Encoding.Default.GetBytes(input));
return new Guid(b);
}
public static GameObject GetBaseLoader(CreatureGuid cid)
{
//IL_0004: Unknown result type (might be due to invalid IL or missing references)
try
{
CreatureBoardAsset val = null;
CreaturePresenter.TryGetAsset(cid, ref val);
if ((Object)(object)val != (Object)null)
{
Transform match = null;
Traverse(((Component)val).transform, "BaseLoader", 0, 10, ref match);
if ((Object)(object)match != (Object)null)
{
Debug.Log((object)("Obj Importer Plugin: Base Loader '" + ((Object)match.GetChild(0)).name + "' Found"));
return ((Component)match.GetChild(0)).gameObject;
}
Debug.LogWarning((object)"Obj Importer Plugin: Could Not Find Base Loader");
return null;
}
return null;
}
catch
{
return null;
}
}
public static GameObject GetAssetLoader(CreatureGuid cid)
{
//IL_0004: Unknown result type (might be due to invalid IL or missing references)
try
{
CreatureBoardAsset val = null;
CreaturePresenter.TryGetAsset(cid, ref val);
if ((Object)(object)val != (Object)null)
{
Transform match = null;
Traverse(((Component)val).transform, "AssetLoader", 0, 10, ref match);
if ((Object)(object)match != (Object)null)
{
Debug.Log((object)("Obj Importer Plugin: Asset Loader '" + ((Object)match.GetChild(0)).name + "' Found"));
return ((Component)match.GetChild(0)).gameObject;
}
Debug.LogWarning((object)"Obj Importer Plugin: Could Not Find Asset Loader");
return null;
}
return null;
}
catch
{
return null;
}
}
public static void Traverse(Transform root, string seek, int depth, int depthMax, ref Transform match)
{
try
{
if ((Object)(object)match != (Object)null)
{
return;
}
if (((Object)root).name == seek)
{
match = root;
return;
}
foreach (Transform item in ExtensionMethods.Children(root))
{
if (depth < depthMax)
{
Traverse(item, seek, depth + 1, depthMax, ref match);
}
}
}
catch
{
}
}
public static float ParseFloat(string value)
{
return float.Parse(value, CultureInfo.InvariantCulture);
}
public static int ParseInt(string value)
{
return int.Parse(value, CultureInfo.InvariantCulture);
}
public static string GetCreatureName(string nameBlock)
{
if (nameBlock == null)
{
return "(Unknown)";
}
if (!nameBlock.Contains("<size=0>"))
{
return nameBlock;
}
return nameBlock.Substring(0, nameBlock.IndexOf("<size=0>")).Trim();
}
public static void PostOnMainPage(MemberInfo plugin)
{
SceneManager.sceneLoaded += delegate(Scene scene, LoadSceneMode mode)
{
//IL_0072: Unknown result type (might be due to invalid IL or missing references)
//IL_0079: Expected O, but got Unknown
try
{
if (((Scene)(ref scene)).name == "UI")
{
TextMeshProUGUI uITextByName = GetUITextByName("BETA");
if (Object.op_Implicit((Object)(object)uITextByName))
{
((TMP_Text)uITextByName).text = "INJECTED BUILD - unstable mods";
}
}
else
{
TextMeshProUGUI uITextByName2 = GetUITextByName("TextMeshPro Text");
if (Object.op_Implicit((Object)(object)uITextByName2))
{
BepInPlugin val = (BepInPlugin)Attribute.GetCustomAttribute(plugin, typeof(BepInPlugin));
if (((TMP_Text)uITextByName2).text.EndsWith("</size>"))
{
((TMP_Text)uITextByName2).text = ((TMP_Text)uITextByName2).text + "\n\nMods Currently Installed:\n";
}
TextMeshProUGUI val2 = uITextByName2;
((TMP_Text)val2).text = ((TMP_Text)val2).text + "\nLord Ashes' " + val.Name + " - " + val.Version;
}
}
}
catch (Exception ex)
{
Debug.Log((object)ex);
}
};
}
private static TextMeshProUGUI GetUITextByName(string name)
{
TextMeshProUGUI[] array = Object.FindObjectsOfType<TextMeshProUGUI>();
for (int i = 0; i < array.Length; i++)
{
if (((Object)array[i]).name == name)
{
return array[i];
}
}
return null;
}
}
public enum DiagnosticLevel
{
none,
error,
warning,
info,
debug,
ultra
}
public class P2
{
public float x { get; set; }
public float y { get; set; }
public P2(float x, float y)
{
this.x = x;
this.y = y;
}
}
public class P3
{
public float x { get; set; }
public float y { get; set; }
public float z { get; set; }
public P3(float x, float y, float z)
{
this.x = x;
this.y = y;
this.z = z;
}
}
public class MeshData
{
public List<P3> v = new List<P3>();
public List<P2> vt = new List<P2>();
public List<P3> vn = new List<P3>();
public List<int> f = new List<int>();
public Vector3[] GetV()
{
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
List<Vector3> list = new List<Vector3>();
foreach (P3 item in v)
{
list.Add(new Vector3(item.x, item.y, item.z));
}
return list.ToArray();
}
public Vector2[] GetVT()
{
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
List<Vector2> list = new List<Vector2>();
foreach (P2 item in vt)
{
list.Add(new Vector2(item.x, item.y));
}
return list.ToArray();
}
public Vector3[] GetVN()
{
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
List<Vector3> list = new List<Vector3>();
foreach (P3 item in vn)
{
list.Add(new Vector3(item.x, item.y, item.z));
}
return list.ToArray();
}
}
public const string Name = "Obj Importer Plugin";
public const string Guid = "org.lordashes.plugins.objimporter";
public const string Version = "1.1.2.0";
public const string Author = "Lord Ashes";
public static float magicNumber = 0.0025f;
private ConfigEntry<KeyboardShortcut> triggerKey { get; set; }
private ConfigEntry<DiagnosticLevel> diagnostics { get; set; }
private ConfigEntry<int> warningThreshold { get; set; }
private void Awake()
{
//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
diagnostics = ((BaseUnityPlugin)this).Config.Bind<DiagnosticLevel>("Settings", "Diagnostic Level", DiagnosticLevel.info, (ConfigDescription)null);
Debug.Log((object)("Obj Importer Plugin: " + ((object)this).GetType().AssemblyQualifiedName + " Is Active. (Version = 1.1.2.0, Pack Version = " + Plugin.Manifest()["version_number"]?.ToString() + ", Diagnostic Mode = " + diagnostics.Value.ToString() + ")"));
triggerKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Hotkeys", "Open OBJ Import Dialog", new KeyboardShortcut((KeyCode)305, (KeyCode[])(object)new KeyCode[1] { (KeyCode)111 }), (ConfigDescription)null);
warningThreshold = ((BaseUnityPlugin)this).Config.Bind<int>("Setting", "Face Count Warning Threshold", 12, (ConfigDescription)null);
AssetDataPlugin.Subscribe("org.lordashes.plugins.objimporter".ToString(), (Action<DatumChange>)RequestHander, (Func<DatumChange, bool>)Checker.CheckSourceAsCreature);
Utility.PostOnMainPage(((object)this).GetType());
}
private void Update()
{
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_0053: Unknown result type (might be due to invalid IL or missing references)
if (!Utility.isBoardLoaded())
{
return;
}
KeyboardShortcut value = triggerKey.Value;
if (!((KeyboardShortcut)(ref value)).IsUp())
{
return;
}
if (diagnostics.Value >= DiagnosticLevel.info)
{
Debug.Log((object)"Obj Importer Plugin: Building Asset");
}
CreatureBoardAsset asset = default(CreatureBoardAsset);
CreaturePresenter.TryGetAsset(LocalClient.SelectedCreatureId, ref asset);
if ((Object)(object)asset != (Object)null)
{
SystemMessage.AskForTextInput("Build Custom Asset", "Name Of OBJ File:", 0, "Build", (Action<string>)delegate(string s)
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
CreatureGuid creatureId = asset.CreatureId;
AssetDataPlugin.SetInfo(((object)(CreatureGuid)(ref creatureId)).ToString(), "org.lordashes.plugins.objimporter", s, false);
}, (Action)null, "Cancel", (Action)null, "Test");
}
else
{
SystemMessage.DisplayInfoText("OBJ Importer Plugin\r\nRequires A Selected Mini", 2.5f, 0f);
}
}
private void RequestHander(DatumChange change)
{
//IL_0049: Unknown result type (might be due to invalid IL or missing references)
//IL_008a: Unknown result type (might be due to invalid IL or missing references)
//IL_0263: Unknown result type (might be due to invalid IL or missing references)
//IL_0283: Unknown result type (might be due to invalid IL or missing references)
//IL_02b8: Unknown result type (might be due to invalid IL or missing references)
if (diagnostics.Value >= DiagnosticLevel.info)
{
Debug.Log((object)("Obj Importer Plugin: Transformation Request = " + change.source.ToString() + " -> " + change.value.ToString()));
}
CreatureBoardAsset val = default(CreatureBoardAsset);
CreaturePresenter.TryGetAsset(new CreatureGuid(change.source), ref val);
if (!((Object)(object)val != (Object)null))
{
return;
}
if (diagnostics.Value >= DiagnosticLevel.ultra)
{
Debug.Log((object)"Obj Importer Plugin: Obtained Reference To Transformation Asset");
}
GameObject assetLoader = Utility.GetAssetLoader(val.CreatureId);
if (diagnostics.Value >= DiagnosticLevel.ultra)
{
Debug.Log((object)"Obj Importer Plugin: Removing Existing Mesh(es)");
}
MeshFilter[] componentsInChildren = assetLoader.GetComponentsInChildren<MeshFilter>();
foreach (MeshFilter val2 in componentsInChildren)
{
val2.mesh.triangles = new int[0];
}
SkinnedMeshRenderer[] componentsInChildren2 = assetLoader.GetComponentsInChildren<SkinnedMeshRenderer>();
foreach (SkinnedMeshRenderer val3 in componentsInChildren2)
{
val3.sharedMesh.triangles = new int[0];
}
if (assetLoader.GetComponentsInChildren<MeshFilter>().Length != 0 && assetLoader.GetComponentsInChildren<MeshRenderer>().Length != 0)
{
if (diagnostics.Value >= DiagnosticLevel.ultra)
{
Debug.Log((object)"Obj Importer Plugin: Using MeshFilter And MeshRenderer");
}
MeshFilter componentInChildren = assetLoader.GetComponentInChildren<MeshFilter>();
MeshRenderer componentInChildren2 = assetLoader.GetComponentInChildren<MeshRenderer>();
(Mesh, Material) tuple = BuildObj(change.value.ToString(), componentInChildren.mesh, ((Renderer)componentInChildren2).material);
componentInChildren.mesh = tuple.Item1;
((Renderer)componentInChildren2).material = tuple.Item2;
}
else if (assetLoader.GetComponentsInChildren<SkinnedMeshRenderer>().Length != 0)
{
if (diagnostics.Value >= DiagnosticLevel.ultra)
{
Debug.Log((object)"Obj Importer Plugin: Using SkinnedMeshRenderer");
}
SkinnedMeshRenderer componentInChildren3 = assetLoader.GetComponentInChildren<SkinnedMeshRenderer>();
(Mesh, Material) tuple2 = BuildObj(change.value.ToString(), componentInChildren3.sharedMesh, ((Renderer)componentInChildren3).material);
componentInChildren3.sharedMesh = tuple2.Item1;
((Renderer)componentInChildren3).material = tuple2.Item2;
}
if (diagnostics.Value >= DiagnosticLevel.ultra)
{
Debug.Log((object)"Obj Importer Plugin: Scaling New Mesh And Aligning With Base");
}
assetLoader.transform.localPosition = Vector3.zero;
assetLoader.transform.localRotation = Quaternion.Euler(90f, 0f, 0f);
assetLoader.transform.localScale = new Vector3(((MovableBoardAsset)val).Scale * magicNumber, ((MovableBoardAsset)val).Scale * magicNumber, ((MovableBoardAsset)val).Scale * magicNumber);
}
private (Mesh, Material) BuildObj(string meshFile, Mesh mesh, Material material)
{
//IL_0049: Unknown result type (might be due to invalid IL or missing references)
//IL_0050: Expected O, but got Unknown
string text = "";
try
{
MeshData meshData = new MeshData();
MeshData meshData2 = new MeshData();
mesh.Clear();
if (diagnostics.Value >= DiagnosticLevel.ultra)
{
Debug.Log((object)"Obj Importer Plugin: Using Standard Shader");
}
material = new Material(Shader.Find("Standard"));
string[] array = File.Find(meshFile + ".uobj", (CacheType)0);
if (diagnostics.Value >= DiagnosticLevel.ultra)
{
Debug.Log((object)("Obj Importer Plugin: Found " + array.Length + " Matches For UOBJ File"));
}
if (array.Length == 0)
{
if (diagnostics.Value >= DiagnosticLevel.ultra)
{
Debug.Log((object)"Obj Importer Plugin: Building From OBJ File");
}
string[] array2 = File.ReadAllLines(meshFile + ".obj", (CacheType)999);
int num = 0;
string[] array3 = array2;
foreach (string text2 in array3)
{
num++;
text = text2;
if (diagnostics.Value >= DiagnosticLevel.ultra)
{
Debug.Log((object)("Obj Importer Plugin: Parsing " + text2));
}
string[] array4 = text2.Split(new char[1] { ' ' });
switch (array4[0].ToUpper())
{
case "V":
meshData.v.Add(new P3(Utility.ParseFloat(array4[1]), Utility.ParseFloat(array4[2]), Utility.ParseFloat(array4[3])));
break;
case "VT":
meshData.vt.Add(new P2(Utility.ParseFloat(array4[1]), Utility.ParseFloat(array4[2])));
break;
case "VN":
meshData.vn.Add(new P3(Utility.ParseFloat(array4[1]), Utility.ParseFloat(array4[2]), Utility.ParseFloat(array4[3])));
break;
case "F":
{
if (array4.Length > 4)
{
SystemMessage.DisplayInfoText("Mesh Import Error:\r\nPlugin Requires A Triangulated Mesh", 2.5f, 0f);
return (null, null);
}
for (int j = 1; j <= 3; j++)
{
string[] array5 = array4[j].Split(new char[1] { '/' });
if (array5[0].Trim() == "" || array5[1].Trim() == "" || array5[2].Trim() == "")
{
SystemMessage.DisplayInfoText("Mesh Import Error:\r\nOBJ File Requires V, VN, VT and F Components", 30f, 0f);
return (null, null);
}
meshData2.v.Add(meshData.v[Utility.ParseInt(array5[0]) - 1]);
meshData2.vt.Add(meshData.vt[Utility.ParseInt(array5[1]) - 1]);
meshData2.vn.Add(meshData.vn[Utility.ParseInt(array5[2]) - 1]);
meshData2.f.Add(meshData2.f.Count);
if (meshData2.f.Count > 65535)
{
SystemMessage.DisplayInfoText("Mesh Import Error:\r\nMesh Exceeds 64K Faces Which Is Not Supported", 30f, 0f);
return (null, null);
}
}
break;
}
}
}
if (meshData2.f.Count > warningThreshold.Value * 1024)
{
SystemMessage.DisplayInfoText("Mesh Import Warning:\r\nMesh Exceeds " + warningThreshold.Value + "K Faces.", 15f, 0f);
}
text = "Writing UOBJ File";
if (diagnostics.Value >= DiagnosticLevel.ultra)
{
Debug.Log((object)"Obj Importer Plugin: Writing UOBJ File");
}
string text3 = File.Find(meshFile + ".obj", (CacheType)999)[0];
text3 = text3.Substring(0, text3.LastIndexOf(".")) + ".uobj";
File.WriteAllText(text3, JsonConvert.SerializeObject((object)meshData2, (Formatting)1), (CacheType)999);
}
else
{
if (diagnostics.Value >= DiagnosticLevel.ultra)
{
Debug.Log((object)"Obj Importer Plugin: Loading From UOBJ File");
}
text = "Reading UOBJ File";
meshData2 = JsonConvert.DeserializeObject<MeshData>(File.ReadAllText(meshFile + ".uobj", (CacheType)999));
}
if (diagnostics.Value >= DiagnosticLevel.ultra)
{
Debug.Log((object)("Obj Importer Plugin: Applying " + meshData2.GetV().Length + " Mesh Vertices"));
}
text = "Applying Vertices";
mesh.vertices = meshData2.GetV();
if (diagnostics.Value >= DiagnosticLevel.ultra)
{
Debug.Log((object)("Obj Importer Plugin: Applying " + meshData2.GetVT().Length + " Mesh UV"));
}
text = "Applying UV";
mesh.uv = meshData2.GetVT();
if (diagnostics.Value >= DiagnosticLevel.ultra)
{
Debug.Log((object)("Obj Importer Plugin: Applying " + meshData2.GetVN().Length + " Mesh Normals"));
}
text = "Applying Normals";
mesh.normals = meshData2.GetVN();
if (diagnostics.Value >= DiagnosticLevel.ultra)
{
Debug.Log((object)("Obj Importer Plugin: Applying " + meshData2.f.Count + " Mesh Faces"));
}
text = "Applying Triangles";
mesh.triangles = meshData2.f.ToArray();
if (diagnostics.Value >= DiagnosticLevel.ultra)
{
Debug.Log((object)"Obj Importer Plugin: Mesh Applied");
}
if (File.Exists(meshFile + ".png"))
{
text = "Applying PNG Texture";
material.mainTexture = (Texture)(object)Image.LoadTexture(meshFile + ".png", (CacheType)999);
}
else if (File.Exists(meshFile + ".bmp"))
{
text = "Applying BMP Texture";
material.mainTexture = (Texture)(object)Image.LoadTexture(meshFile + ".bmp", (CacheType)999);
}
else if (File.Exists(meshFile + ".jpg"))
{
text = "Applying JPG Texture";
material.mainTexture = (Texture)(object)Image.LoadTexture(meshFile + ".jpg", (CacheType)999);
}
return (mesh, material);
}
catch (Exception)
{
return (null, null);
}
}
}