Decompiled source of AvatarCreatures v0.0.6

AvatarCreatures.dll

Decompiled a year ago
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using GameNetcodeStuff;
using HarmonyLib;
using LC_API.BundleAPI;
using Microsoft.CodeAnalysis;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.Rendering.HighDefinition;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("AvatarCreatures")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Custom avatars in Lethal Company.")]
[assembly: AssemblyFileVersion("0.0.6.0")]
[assembly: AssemblyInformationalVersion("0.0.6+2db75090404c8dd6b712954e21f2bdb9fcfa09ca")]
[assembly: AssemblyProduct("AvatarCreatures")]
[assembly: AssemblyTitle("AvatarCreatures")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.6.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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 AvatarCreatures
{
	public class AvatarCreature
	{
		public class CreatureController : MonoBehaviour
		{
			private bool isLocalPlayer = false;

			private GameObject currentAvatar = null;

			private Transform spineBoneForRotation = null;

			private Transform chestBone = null;

			private Camera thirdPersonCamera = null;

			private MonoBehaviour thirdPersonComponent = null;

			private ulong LOCAL_STEAM_ID = 0uL;

			private bool oldValue = false;

			private void Start()
			{
				//IL_024d: Unknown result type (might be due to invalid IL or missing references)
				//IL_02a0: 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_0670: Unknown result type (might be due to invalid IL or missing references)
				//IL_0677: Expected O, but got Unknown
				//IL_069d: Unknown result type (might be due to invalid IL or missing references)
				//IL_06ad: Unknown result type (might be due to invalid IL or missing references)
				//IL_06b4: Expected O, but got Unknown
				//IL_06da: Unknown result type (might be due to invalid IL or missing references)
				//IL_06ea: Unknown result type (might be due to invalid IL or missing references)
				//IL_06f1: Expected O, but got Unknown
				//IL_0717: Unknown result type (might be due to invalid IL or missing references)
				//IL_0727: Unknown result type (might be due to invalid IL or missing references)
				//IL_072e: Expected O, but got Unknown
				//IL_0754: Unknown result type (might be due to invalid IL or missing references)
				//IL_049e: Unknown result type (might be due to invalid IL or missing references)
				PlayerControllerB component = ((Component)this).gameObject.GetComponent<PlayerControllerB>();
				ulong playerSteamId = component.playerSteamId;
				if (((NetworkBehaviour)component).IsLocalPlayer)
				{
					isLocalPlayer = true;
				}
				Debug.Log((object)"Checking for third person mod...");
				GameObject val = GameObject.Find("3rdPerson");
				if ((Object)(object)val != (Object)null)
				{
					thirdPersonComponent = val.GetComponents<MonoBehaviour>().ElementAt(2);
				}
				bool flag = (Object)(object)thirdPersonComponent != (Object)null;
				Debug.Log((object)("Third person mod is: " + (flag ? "Enabled" : "Not Found")));
				Debug.Log((object)$"Loading model for player '{playerSteamId}'...");
				string path = Path.Combine(Paths.GameRootPath, "Avatars");
				string text = Path.Combine(path, playerSteamId.ToString());
				string text2 = text + ".assetbundle";
				AssetBundle val2 = AssetBundle.LoadFromFile(text2);
				if ((Object)(object)val2 == (Object)null)
				{
					Debug.LogWarning((object)("Failed to load asset bundle '" + text2 + "' - does not exist, falling back to custom default"));
					text2 = Path.Combine(path, "default.assetbundle");
					val2 = AssetBundle.LoadFromFile(text2);
					if ((Object)(object)val2 == (Object)null)
					{
						Debug.LogWarning((object)("Failed to load default asset bundle '" + text2 + "' - does not exist, falling back to game default"));
						return;
					}
				}
				Transform val3 = ((Component)this).gameObject.transform.Find("ScavengerModel").Find("metarig");
				spineBoneForRotation = val3.Find("spine").Find("spine.001").Find("spine.002")
					.Find("spine.003");
				if ((Object)(object)spineBoneForRotation == (Object)null)
				{
					throw new Exception("ScavengerModel is missing a spine bone");
				}
				HideDefaultCreature();
				GameObject val4 = val2.LoadAsset<GameObject>("model.fbx");
				if ((Object)(object)val4 == (Object)null)
				{
					throw new Exception("Model fbx not found inside bundle");
				}
				RuntimeAnimatorController loadedAsset = BundleLoader.GetLoadedAsset<RuntimeAnimatorController>("assets/crittercontrol.controller");
				if ((Object)(object)loadedAsset == (Object)null)
				{
					loadedAsset = BundleLoader.GetLoadedAsset<RuntimeAnimatorController>("assets/assets/crittercontrol.controller");
					if ((Object)(object)loadedAsset == (Object)null)
					{
						throw new Exception("Could not find controller in bundle");
					}
				}
				Debug.Log((object)"Creating avatar");
				GameObject val5 = Object.Instantiate<GameObject>(val4);
				val5.transform.localScale = new Vector3(1f, 1f, 1f);
				Debug.Log((object)"Parenting avatar");
				Transform parent = val3.Find("spine").Find("spine.001");
				val5.transform.SetParent(parent);
				val5.transform.localPosition = new Vector3(0f, 0f, 0f);
				val5.transform.localEulerAngles = Vector3.zero;
				Debug.Log((object)"Updating material");
				SkinnedMeshRenderer thisPlayerModel = ((Component)this).gameObject.GetComponent<PlayerControllerB>().thisPlayerModel;
				Shader shader = ((Renderer)thisPlayerModel).material.shader;
				Renderer[] componentsInChildren = val5.GetComponentsInChildren<Renderer>();
				Renderer[] array = componentsInChildren;
				foreach (Renderer val6 in array)
				{
					string name = ((Object)((Component)val6).gameObject).name;
					Debug.Log((object)$"Updating {val6.materials.Length} materials for renderer '{name}'");
					int num = 0;
					Material[] materials = val6.materials;
					foreach (Material val7 in materials)
					{
						Debug.Log((object)$"Applying textures to material #{num} - '{((Object)val7).name}'");
						val7.shader = shader;
						val7.EnableKeyword("_EMISSION");
						val7.EnableKeyword("_SPECGLOSSMAP");
						val7.EnableKeyword("_NORMALMAP");
						string text3 = $"{name}_{num}_Albedo.png";
						Texture val8 = val2.LoadAsset<Texture>(text3);
						Texture val9 = val2.LoadAsset<Texture>($"{name}_{num}_Smoothness.png");
						Texture val10 = val2.LoadAsset<Texture>($"{name}_{num}_Emission.png");
						Texture val11 = val2.LoadAsset<Texture>($"{name}_{num}_Normal.png");
						if ((Object)(object)val8 == (Object)null)
						{
							throw new Exception("Could not find asset '" + text3 + "' in asset bundle");
						}
						val7.SetTexture("_BaseColorMap", val8);
						val7.SetTexture("_SpecularColorMap", val9);
						val7.SetFloat("_Smoothness", 0.3f);
						val7.SetTexture("_EmissiveColorMap", val10);
						val7.SetTexture("_BumpMap", val11);
						if ((Object)(object)val10 != (Object)null)
						{
							val7.SetColor("_EmissiveColor", Color.white);
						}
						HDMaterial.ValidateMaterial(val7);
						num++;
					}
				}
				Animator componentInChildren = val5.GetComponentInChildren<Animator>();
				Debug.Log((object)"Storing chest bone");
				chestBone = componentInChildren.GetBoneTransform((HumanBodyBones)8);
				if ((Object)(object)chestBone == (Object)null)
				{
					chestBone = componentInChildren.GetBoneTransform((HumanBodyBones)7);
					if ((Object)(object)chestBone == (Object)null)
					{
						throw new Exception("Avatar is missing a chest or spine bone");
					}
				}
				Debug.Log((object)"Inserting controller");
				componentInChildren.runtimeAnimatorController = loadedAsset;
				Debug.Log((object)"Setting up IK");
				IKController iKController = val5.AddComponent<IKController>();
				Transform val12 = val3.Find("spine").Find("thigh.L");
				Transform val13 = val3.Find("spine").Find("thigh.R");
				Transform val14 = val12.Find("shin.L");
				Transform val15 = val13.Find("shin.R");
				Transform val16 = val14.Find("foot.L");
				Transform val17 = val15.Find("foot.R");
				Transform val18 = val3.Find("spine").Find("spine.001").Find("spine.002")
					.Find("spine.003");
				Transform val19 = val18.Find("shoulder.L");
				Transform val20 = val18.Find("shoulder.R");
				Transform val21 = val19.Find("arm.L_upper");
				Transform val22 = val20.Find("arm.R_upper");
				Transform val23 = val21.Find("arm.L_lower");
				Transform val24 = val22.Find("arm.R_lower");
				Transform val25 = val23.Find("hand.L");
				Transform val26 = val24.Find("hand.R");
				GameObject val27 = new GameObject("IK Offset");
				val27.transform.SetParent(val16, false);
				val27.transform.localPosition = new Vector3(0f, -0.1f, 0f);
				GameObject val28 = new GameObject("IK Offset");
				val28.transform.SetParent(val17, false);
				val28.transform.localPosition = new Vector3(0f, -0.1f, 0f);
				GameObject val29 = new GameObject("IK Offset");
				val29.transform.SetParent(val25, false);
				val29.transform.localPosition = new Vector3(0.05f, 0f, 0f);
				GameObject val30 = new GameObject("IK Offset");
				val30.transform.SetParent(val26, false);
				val30.transform.localPosition = new Vector3(-0.05f, 0f, 0f);
				iKController.leftLegTarget = val27.transform;
				iKController.rightLegTarget = val28.transform;
				iKController.leftHandTarget = val29.transform;
				iKController.rightHandTarget = val30.transform;
				iKController.ikActive = true;
				Debug.Log((object)"IK set up");
				val2.Unload(false);
				Debug.Log((object)"Avatar has been loaded");
				currentAvatar = val5;
			}

			private void LateUpdate()
			{
				//IL_004b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0062: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)currentAvatar != (Object)null && (Object)(object)chestBone != (Object)null && (Object)(object)spineBoneForRotation != (Object)null)
				{
					currentAvatar.transform.localPosition = new Vector3(0f, -0.15f, 0f);
					chestBone.localEulerAngles = spineBoneForRotation.localEulerAngles;
				}
			}

			private void HideDefaultCreature()
			{
				((Component)this).gameObject.GetComponentInChildren<LODGroup>().enabled = false;
				SkinnedMeshRenderer[] componentsInChildren = ((Component)this).gameObject.GetComponentsInChildren<SkinnedMeshRenderer>();
				SkinnedMeshRenderer[] array = componentsInChildren;
				foreach (SkinnedMeshRenderer val in array)
				{
					((Renderer)val).enabled = false;
				}
			}
		}
	}
	public class IKController : MonoBehaviour
	{
		protected Animator animator;

		public bool ikActive = false;

		public Transform leftLegTarget = null;

		public Transform rightLegTarget = null;

		public Transform leftHandTarget = null;

		public Transform rightHandTarget = null;

		private void Start()
		{
			animator = ((Component)this).GetComponent<Animator>();
		}

		private void OnAnimatorIK()
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: 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_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)animator))
			{
				return;
			}
			if (ikActive)
			{
				if ((Object)(object)leftLegTarget != (Object)null)
				{
					animator.SetIKPositionWeight((AvatarIKGoal)0, 1f);
					animator.SetIKPosition((AvatarIKGoal)0, leftLegTarget.position);
					animator.SetIKRotation((AvatarIKGoal)0, leftLegTarget.rotation);
				}
				if ((Object)(object)rightLegTarget != (Object)null)
				{
					animator.SetIKPositionWeight((AvatarIKGoal)1, 1f);
					animator.SetIKPosition((AvatarIKGoal)1, rightLegTarget.position);
					animator.SetIKRotation((AvatarIKGoal)1, rightLegTarget.rotation);
				}
				if ((Object)(object)leftHandTarget != (Object)null)
				{
					animator.SetIKPositionWeight((AvatarIKGoal)2, 1f);
					animator.SetIKPosition((AvatarIKGoal)2, leftHandTarget.position);
					animator.SetIKRotation((AvatarIKGoal)2, leftHandTarget.rotation);
				}
				if ((Object)(object)rightHandTarget != (Object)null)
				{
					animator.SetIKPositionWeight((AvatarIKGoal)3, 1f);
					animator.SetIKPosition((AvatarIKGoal)3, rightHandTarget.position);
					animator.SetIKRotation((AvatarIKGoal)3, rightHandTarget.rotation);
				}
			}
			else
			{
				animator.SetIKPositionWeight((AvatarIKGoal)0, 0f);
				animator.SetIKRotationWeight((AvatarIKGoal)0, 0f);
				animator.SetIKPositionWeight((AvatarIKGoal)1, 0f);
				animator.SetIKRotationWeight((AvatarIKGoal)1, 0f);
				animator.SetIKPositionWeight((AvatarIKGoal)2, 0f);
				animator.SetIKRotationWeight((AvatarIKGoal)2, 0f);
				animator.SetIKPositionWeight((AvatarIKGoal)3, 0f);
				animator.SetIKRotationWeight((AvatarIKGoal)3, 0f);
			}
		}
	}
	[BepInPlugin("AvatarCreatures", "AvatarCreatures", "0.0.6")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		public static Harmony _harmony;

		public static ConfigEntry<bool> configAlwaysRenderLocalPlayerModel;

		private void Awake()
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected O, but got Unknown
			configAlwaysRenderLocalPlayerModel = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "AlwaysRenderLocalPlayerModel", false, "If to always render the local player model. Useful for testing with 3rd person mods.");
			_harmony = new Harmony("AvatarCreatures");
			_harmony.PatchAll();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"AvatarCreatures loaded");
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "AvatarCreatures";

		public const string PLUGIN_NAME = "AvatarCreatures";

		public const string PLUGIN_VERSION = "0.0.6";
	}
}
namespace AvatarCreatures.Patches
{
	[HarmonyPatch]
	internal class PlayerObjects
	{
		public static void InitModels()
		{
			PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController;
			PlayerControllerB[] array = Object.FindObjectsOfType<PlayerControllerB>();
			bool value = Plugin.configAlwaysRenderLocalPlayerModel.Value;
			Debug.Log((object)("Always render local player model: " + (value ? "Yes" : "No")));
			PlayerControllerB[] array2 = array;
			foreach (PlayerControllerB val in array2)
			{
				if (((Object)(object)val == (Object)(object)localPlayerController || val.playerSteamId == 0L) && !value)
				{
					Debug.Log((object)$"Ignoring local player (steam ID {val.playerSteamId})");
					continue;
				}
				AvatarCreature.CreatureController[] componentsInChildren = ((Component)val).gameObject.GetComponentsInChildren<AvatarCreature.CreatureController>();
				if (componentsInChildren.Length != 0)
				{
					Debug.Log((object)$"Steam ID {val.playerSteamId} already has creature, skipping");
					continue;
				}
				Debug.Log((object)$"Adding creature to steam ID {val.playerSteamId}...");
				((Component)val).gameObject.AddComponent<AvatarCreature.CreatureController>();
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB), "SpawnPlayerAnimation")]
		[HarmonyPostfix]
		public static void InitModel(ref PlayerControllerB __instance)
		{
			InitModels();
		}

		[HarmonyPatch(typeof(PlayerControllerB), "DisablePlayerModel")]
		[HarmonyPostfix]
		public static void DisablePlayerModel(ref PlayerControllerB __instance, GameObject playerObject)
		{
			PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController;
			if ((Object)(object)playerObject == (Object)(object)localPlayerController)
			{
				return;
			}
			playerObject.gameObject.GetComponentInChildren<LODGroup>().enabled = false;
			SkinnedMeshRenderer[] componentsInChildren = playerObject.gameObject.GetComponentsInChildren<SkinnedMeshRenderer>();
			SkinnedMeshRenderer[] array = componentsInChildren;
			foreach (SkinnedMeshRenderer val in array)
			{
				if (!(((Object)val).name == "Body"))
				{
					((Renderer)val).enabled = false;
				}
			}
		}
	}
	[HarmonyPatch(typeof(UnlockableSuit))]
	internal class UnlockableSuitPatch
	{
		[HarmonyPatch("SwitchSuitForPlayer")]
		[HarmonyPrefix]
		private static void SwitchSuitForPlayerPatch(PlayerControllerB player, int suitID, bool playAudio = true)
		{
		}
	}
}