Decompiled source of DynamicFurniture v1.0.0

DynamicFurniture.dll

Decompiled 4 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using Jotunn;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")]
[assembly: AssemblyCompany("DynamicFurniture")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Valheim mod that dynamically loads furniture from OBJ and PNG files at runtime.")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("DynamicFurniture")]
[assembly: AssemblyTitle("DynamicFurniture")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace DynamicFurniture
{
	[BepInPlugin("com.woltreks.dynamicfurniture", "DynamicFurniture", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class DynamicFurniture : BaseUnityPlugin
	{
		public const string PluginGUID = "com.woltreks.dynamicfurniture";

		public const string PluginName = "DynamicFurniture";

		public const string PluginVersion = "1.0.0";

		private void Awake()
		{
			PrefabManager.OnVanillaPrefabsAvailable += LoadCustomFurniture;
			Logger.LogInfo((object)"DynamicFurniture mod initialized!");
		}

		private void LoadCustomFurniture()
		{
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Expected O, but got Unknown
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Expected O, but got Unknown
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0205: Expected O, but got Unknown
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Expected O, but got Unknown
			//IL_021f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0227: Unknown result type (might be due to invalid IL or missing references)
			//IL_0231: Unknown result type (might be due to invalid IL or missing references)
			//IL_0239: Unknown result type (might be due to invalid IL or missing references)
			//IL_023e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0248: Unknown result type (might be due to invalid IL or missing references)
			//IL_0250: Unknown result type (might be due to invalid IL or missing references)
			//IL_030e: Unknown result type (might be due to invalid IL or missing references)
			//IL_027b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0282: Expected O, but got Unknown
			//IL_029f: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0325: Unknown result type (might be due to invalid IL or missing references)
			//IL_0327: Unknown result type (might be due to invalid IL or missing references)
			//IL_033d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0344: Expected O, but got Unknown
			//IL_0321: Unknown result type (might be due to invalid IL or missing references)
			//IL_0323: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f9: Expected O, but got Unknown
			//IL_03fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0405: Expected O, but got Unknown
			//IL_03c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cc: Expected O, but got Unknown
			PrefabManager.OnVanillaPrefabsAvailable -= LoadCustomFurniture;
			string directoryName = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
			Logger.LogInfo((object)("Scanning for custom furniture in: " + directoryName));
			if (!Directory.Exists(directoryName))
			{
				return;
			}
			GameObject prefab = PrefabManager.Instance.GetPrefab("piece_chair");
			Material val = null;
			if ((Object)(object)prefab != (Object)null)
			{
				Renderer componentInChildren = prefab.GetComponentInChildren<Renderer>();
				if ((Object)(object)componentInChildren != (Object)null)
				{
					val = componentInChildren.sharedMaterial;
				}
			}
			string[] directories = Directory.GetDirectories(directoryName);
			foreach (string text in directories)
			{
				string text2 = Path.Combine(text, "model.obj");
				string path = Path.Combine(text, "texture.png");
				string path2 = Path.Combine(text, "piece.json");
				if (!File.Exists(text2))
				{
					continue;
				}
				string fileName = Path.GetFileName(text);
				Logger.LogInfo((object)("Found model folder: " + fileName));
				try
				{
					PieceJson pieceJson = new PieceJson();
					if (File.Exists(path2))
					{
						pieceJson = PieceJson.Parse(File.ReadAllText(path2));
					}
					else
					{
						pieceJson.name = fileName.Replace("_", " ");
					}
					Texture2D val2 = null;
					if (File.Exists(path))
					{
						byte[] array = File.ReadAllBytes(path);
						val2 = new Texture2D(2, 2);
						if (!ImageConversion.LoadImage(val2, array))
						{
							Logger.LogWarning((object)("Failed to load image texture for " + fileName));
							val2 = null;
						}
					}
					Mesh val3 = ObjLoader.LoadOBJ(text2);
					if ((Object)(object)val3 == (Object)null)
					{
						Logger.LogError((object)("Failed to load OBJ mesh for " + fileName));
						continue;
					}
					GameObject val4 = new GameObject(fileName);
					val4.SetActive(false);
					GameObject val5 = new GameObject("model");
					val5.transform.SetParent(val4.transform, false);
					val5.AddComponent<MeshFilter>().sharedMesh = val3;
					MeshRenderer obj = val5.AddComponent<MeshRenderer>();
					Material val6;
					if ((Object)(object)val != (Object)null)
					{
						val6 = new Material(val);
						if ((Object)(object)val2 != (Object)null)
						{
							val6.mainTexture = (Texture)(object)val2;
							if (val6.HasProperty("_BumpMap"))
							{
								val6.SetTexture("_BumpMap", (Texture)null);
							}
						}
					}
					else
					{
						val6 = new Material(Shader.Find("Standard"));
						if ((Object)(object)val2 != (Object)null)
						{
							val6.mainTexture = (Texture)(object)val2;
						}
					}
					((Renderer)obj).sharedMaterial = val6;
					val5.transform.localPosition = pieceJson.offset;
					val5.transform.localRotation = Quaternion.Euler(pieceJson.rotation);
					val5.transform.localScale = pieceJson.scale;
					MeshCollider obj2 = val5.AddComponent<MeshCollider>();
					obj2.sharedMesh = val3;
					obj2.convex = false;
					if (pieceJson.sittingEnabled)
					{
						GameObject val7 = new GameObject("AttachPoint");
						val7.transform.SetParent(val4.transform, false);
						val7.transform.localPosition = pieceJson.sittingPosition;
						val7.transform.localRotation = Quaternion.Euler(pieceJson.sittingRotation);
						Chair obj3 = val4.AddComponent<Chair>();
						obj3.m_attachPoint = val7.transform;
						obj3.m_name = "$piece_sit";
					}
					Piece obj4 = val4.AddComponent<Piece>();
					obj4.m_name = pieceJson.name;
					obj4.m_description = pieceJson.description;
					obj4.m_comfort = pieceJson.comfort;
					PieceCategory category = (PieceCategory)4;
					if (Enum.TryParse<PieceCategory>(pieceJson.category, ignoreCase: true, out PieceCategory result))
					{
						category = result;
					}
					obj4.m_category = category;
					val4.AddComponent<WearNTear>().m_health = 50f;
					PieceConfig val8 = new PieceConfig();
					val8.Name = pieceJson.name;
					val8.Description = pieceJson.description;
					val8.PieceTable = PieceTables.Hammer;
					val8.Category = pieceJson.category;
					val8.CraftingStation = pieceJson.craftingStation;
					if (pieceJson.cost.Count > 0)
					{
						foreach (KeyValuePair<string, int> item in pieceJson.cost)
						{
							val8.AddRequirement(new RequirementConfig(item.Key, item.Value, 0, false));
						}
					}
					else
					{
						val8.AddRequirement(new RequirementConfig("Wood", 5, 0, false));
					}
					CustomPiece val9 = new CustomPiece(val4, false, val8);
					PieceManager.Instance.AddPiece(val9);
					Logger.LogInfo((object)("Successfully registered custom piece: " + pieceJson.name));
				}
				catch (Exception arg)
				{
					Logger.LogError((object)$"Error loading custom furniture from folder {fileName}: {arg}");
				}
			}
		}
	}
	public class PieceJson
	{
		public string name = "Custom Furniture";

		public string description = "Custom building piece.";

		public string category = "Furniture";

		public string craftingStation = "piece_workbench";

		public Dictionary<string, int> cost = new Dictionary<string, int>();

		public Vector3 scale = Vector3.one;

		public Vector3 rotation = Vector3.zero;

		public Vector3 offset = Vector3.zero;

		public int comfort;

		public bool sittingEnabled;

		public Vector3 sittingPosition = new Vector3(0f, 0.5f, 0f);

		public Vector3 sittingRotation = Vector3.zero;

		public static PieceJson Parse(string jsonText)
		{
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: 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_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_0226: Unknown result type (might be due to invalid IL or missing references)
			//IL_022b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0243: Unknown result type (might be due to invalid IL or missing references)
			//IL_0248: 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)
			PieceJson pieceJson = new PieceJson();
			string[] array = jsonText.Split(new char[2] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries);
			bool flag = false;
			bool flag2 = false;
			string[] array2 = array;
			for (int i = 0; i < array2.Length; i++)
			{
				string text = array2[i].Trim();
				if (text.Contains("\"cost\":"))
				{
					flag = true;
					continue;
				}
				if (text.Contains("\"sitting\":"))
				{
					flag2 = true;
					continue;
				}
				if (text == "}," || text == "}")
				{
					flag = false;
					flag2 = false;
					continue;
				}
				int num = text.IndexOf(':');
				if (num < 0)
				{
					continue;
				}
				string text2 = text.Substring(0, num).Replace("\"", "").Trim();
				string text3 = text.Substring(num + 1).Replace("\"", "").Trim();
				if (text3.EndsWith(","))
				{
					text3 = text3.Substring(0, text3.Length - 1);
				}
				if (flag)
				{
					if (int.TryParse(text3, out var result))
					{
						pieceJson.cost[text2] = result;
					}
					continue;
				}
				if (flag2)
				{
					switch (text2)
					{
					case "enabled":
						pieceJson.sittingEnabled = text3.ToLower() == "true";
						break;
					case "position":
						pieceJson.sittingPosition = ParseVector3(text);
						break;
					case "rotation":
						pieceJson.sittingRotation = ParseVector3(text);
						break;
					}
					continue;
				}
				switch (text2)
				{
				case "name":
					pieceJson.name = text3;
					break;
				case "description":
					pieceJson.description = text3;
					break;
				case "category":
					pieceJson.category = text3;
					break;
				case "crafting_station":
					pieceJson.craftingStation = text3;
					break;
				case "comfort":
					int.TryParse(text3, out pieceJson.comfort);
					break;
				case "scale":
					pieceJson.scale = ParseVector3(text);
					break;
				case "rotation":
					pieceJson.rotation = ParseVector3(text);
					break;
				case "offset":
					pieceJson.offset = ParseVector3(text);
					break;
				}
			}
			return pieceJson;
		}

		private static Vector3 ParseVector3(string line)
		{
			//IL_0090: 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)
			int num = line.IndexOf('[');
			int num2 = line.IndexOf(']');
			if (num >= 0 && num2 > num)
			{
				string[] array = line.Substring(num + 1, num2 - num - 1).Split(',');
				if (array.Length >= 3)
				{
					float.TryParse(array[0].Trim(), NumberStyles.Float, CultureInfo.InvariantCulture, out var result);
					float.TryParse(array[1].Trim(), NumberStyles.Float, CultureInfo.InvariantCulture, out var result2);
					float.TryParse(array[2].Trim(), NumberStyles.Float, CultureInfo.InvariantCulture, out var result3);
					return new Vector3(result, result2, result3);
				}
			}
			return Vector3.one;
		}
	}
	public static class ObjLoader
	{
		public static Mesh LoadOBJ(string filePath)
		{
			//IL_033b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0342: Expected O, but got Unknown
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0244: Unknown result type (might be due to invalid IL or missing references)
			//IL_0249: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02af: 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)
			//IL_023d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0242: Unknown result type (might be due to invalid IL or missing references)
			//IL_028e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0293: Unknown result type (might be due to invalid IL or missing references)
			if (!File.Exists(filePath))
			{
				return null;
			}
			List<Vector3> list = new List<Vector3>();
			List<Vector2> list2 = new List<Vector2>();
			List<Vector3> list3 = new List<Vector3>();
			List<int> list4 = new List<int>();
			Dictionary<string, int> dictionary = new Dictionary<string, int>();
			List<Vector3> list5 = new List<Vector3>();
			List<Vector2> list6 = new List<Vector2>();
			List<Vector3> list7 = new List<Vector3>();
			string[] array = File.ReadAllLines(filePath);
			for (int i = 0; i < array.Length; i++)
			{
				string text = array[i].Trim();
				if (text.StartsWith("#") || string.IsNullOrEmpty(text))
				{
					continue;
				}
				string[] array2 = text.Split(new char[1] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
				if (array2.Length == 0)
				{
					continue;
				}
				switch (array2[0])
				{
				case "v":
				{
					float num9 = float.Parse(array2[1], CultureInfo.InvariantCulture);
					float num10 = float.Parse(array2[2], CultureInfo.InvariantCulture);
					float num11 = float.Parse(array2[3], CultureInfo.InvariantCulture);
					list.Add(new Vector3(0f - num9, num10, num11));
					break;
				}
				case "vt":
				{
					float num7 = float.Parse(array2[1], CultureInfo.InvariantCulture);
					float num8 = float.Parse(array2[2], CultureInfo.InvariantCulture);
					list2.Add(new Vector2(num7, num8));
					break;
				}
				case "vn":
				{
					float num4 = float.Parse(array2[1], CultureInfo.InvariantCulture);
					float num5 = float.Parse(array2[2], CultureInfo.InvariantCulture);
					float num6 = float.Parse(array2[3], CultureInfo.InvariantCulture);
					list3.Add(new Vector3(0f - num4, num5, num6));
					break;
				}
				case "f":
				{
					List<int> list8 = new List<int>();
					for (int j = 1; j < array2.Length; j++)
					{
						string text2 = array2[j];
						if (dictionary.TryGetValue(text2, out var value))
						{
							list8.Add(value);
							continue;
						}
						string[] array3 = text2.Split('/');
						int num = int.Parse(array3[0]) - 1;
						if (num < 0)
						{
							num = list.Count + num + 1;
						}
						Vector2 item = Vector2.zero;
						if (array3.Length > 1 && !string.IsNullOrEmpty(array3[1]))
						{
							int num2 = int.Parse(array3[1]) - 1;
							if (num2 < 0)
							{
								num2 = list2.Count + num2 + 1;
							}
							if (num2 >= 0 && num2 < list2.Count)
							{
								item = list2[num2];
							}
						}
						Vector3 item2 = Vector3.zero;
						if (array3.Length > 2 && !string.IsNullOrEmpty(array3[2]))
						{
							int num3 = int.Parse(array3[2]) - 1;
							if (num3 < 0)
							{
								num3 = list3.Count + num3 + 1;
							}
							if (num3 >= 0 && num3 < list3.Count)
							{
								item2 = list3[num3];
							}
						}
						int count = list5.Count;
						list5.Add(list[num]);
						list6.Add(item);
						list7.Add(item2);
						dictionary[text2] = count;
						list8.Add(count);
					}
					for (int k = 1; k < list8.Count - 1; k++)
					{
						list4.Add(list8[0]);
						list4.Add(list8[k + 1]);
						list4.Add(list8[k]);
					}
					break;
				}
				}
			}
			Mesh val = new Mesh();
			val.vertices = list5.ToArray();
			val.uv = list6.ToArray();
			if (list7.Count > 0)
			{
				val.normals = list7.ToArray();
			}
			else
			{
				val.RecalculateNormals();
			}
			val.triangles = list4.ToArray();
			val.RecalculateBounds();
			val.RecalculateTangents();
			return val;
		}
	}
}