using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; 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 System.Threading; using BepInEx; using BepInEx.Configuration; using GameNetcodeStuff; using Microsoft.CodeAnalysis; using UniGLTF; using UniGLTF.Extensions.VRMC_materials_mtoon; using UniVRM10; using Unity.Netcode; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; using UnityEngine.Rendering; using UnityEngine.SceneManagement; using VRMShaders; using VRMShaders.VRM10.MToon10.Runtime; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("OomJan")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyCopyright("MIT License")] [assembly: AssemblyFileVersion("1.3.0.0")] [assembly: AssemblyInformationalVersion("1.3.0+1aba838dd83a013f377625c7f52a55c18b5c8b28")] [assembly: AssemblyProduct("SoransBetterLethalVRM")] [assembly: AssemblyTitle("SoranJackal.BetterLethalVRM")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.3.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [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 OomJan { public static class MyPluginInfo { public const string PLUGIN_GUID = "SoranJackal.BetterLethalVRM"; public const string PLUGIN_NAME = "SoransBetterLethalVRM"; public const string PLUGIN_VERSION = "1.3.0"; } } namespace OomJan.BetterLethalVRM { [BepInPlugin("SoranJackal.BetterLethalVRM", "SoransBetterLethalVRM", "1.3.0")] public class BetterLethalVRMManager : BaseUnityPlugin { private const string MODEL_PATH = "VRMs"; private readonly SortedDictionary Instances = new SortedDictionary(); private readonly SortedDictionary PlayersBySteamID = new SortedDictionary(); private readonly HashSet LoadingSteamIds = new HashSet(); private Material HDRP_BaseMaterial; private GameObject PlayerPrefab; private float PlayerPrefabHeight; private PlayerControllerB[] PlayerControllers; private bool RequirePlayerUpdate; private ConfigEntry RaiseOffsetKey; private ConfigEntry LowerOffsetKey; private ConfigEntry OffsetAdjustSpeed; private bool OffsetDirty; public void Awake() { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Expected O, but got Unknown RaiseOffsetKey = ((BaseUnityPlugin)this).Config.Bind("VRM Offset", "RaiseKey", new KeyboardShortcut((KeyCode)280, Array.Empty()), "Hold to raise the local player's VRM vertically. Auto-saves to a .offset sidecar file next to the .vrm."); LowerOffsetKey = ((BaseUnityPlugin)this).Config.Bind("VRM Offset", "LowerKey", new KeyboardShortcut((KeyCode)281, Array.Empty()), "Hold to lower the local player's VRM vertically. Auto-saves to a .offset sidecar file next to the .vrm."); OffsetAdjustSpeed = ((BaseUnityPlugin)this).Config.Bind("VRM Offset", "AdjustSpeed", 0.2f, "Meters per second to adjust the VRM vertical offset while a key is held."); AssetBundle val = null; try { UriBuilder uriBuilder = new UriBuilder(Assembly.GetExecutingAssembly().CodeBase); string fileName = Uri.UnescapeDataString(uriBuilder.Path); string text = Path.Combine(new FileInfo(fileName).Directory.FullName, "bundle.asset"); if (File.Exists(text)) { val = AssetBundle.LoadFromFile(text); } } catch (Exception) { val = null; } if ((Object)(object)val == (Object)null) { ((Behaviour)this).enabled = false; Debug.LogError((object)"BetterLethalVRM failed to load it's asset bundle, this mod will not function"); return; } HDRPVrm10MToonMaterialImporter.MToonReplacementShader = (Shader)val.LoadAsset("MToonParameterShader"); if ((Object)(object)HDRPVrm10MToonMaterialImporter.MToonReplacementShader == (Object)null) { ((Behaviour)this).enabled = false; Debug.LogError((object)"BetterLethalVRM failed to load the MToon replacement shader, this mod will not function"); return; } SceneManager.sceneLoaded += delegate { SceneLoad(); }; ((Object)((Component)this).gameObject).hideFlags = (HideFlags)61; if (!Directory.Exists("VRMs")) { Directory.CreateDirectory("VRMs"); } if (!Directory.Exists("VRMs")) { ((Behaviour)this).enabled = false; Debug.LogError((object)"BetterLethalVRM failed to create directory for models, this mod will not function"); } } private void LateUpdate() { FindUpdatedIDs(); FindMaskEnemies(); HandleOffsetInput(); AnimateBonePairs(); if (RequirePlayerUpdate) { FindPlayerControllers(); RequirePlayerUpdate = false; } } private void SceneLoad() { GameNetworkManager instance = GameNetworkManager.Instance; if (instance == null || !instance.currentLobby.HasValue) { foreach (BetterLethalVRMInstance value in Instances.Values) { if ((Object)(object)value.Vrm10Instance != (Object)null && (Object)(object)((Component)value.Vrm10Instance).gameObject != (Object)null) { Object.Destroy((Object)(object)((Component)value.Vrm10Instance).gameObject); } } PlayersBySteamID.Clear(); Instances.Clear(); } FindPlayerControllers(); PreparePrefabs(); RequirePlayerUpdate = true; } private void PreparePrefabs() { //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Expected O, but got Unknown //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0151: 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_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_025e: Unknown result type (might be due to invalid IL or missing references) //IL_0264: Unknown result type (might be due to invalid IL or missing references) //IL_0269: Unknown result type (might be due to invalid IL or missing references) //IL_0273: Unknown result type (might be due to invalid IL or missing references) //IL_0290: Unknown result type (might be due to invalid IL or missing references) //IL_02a5: Unknown result type (might be due to invalid IL or missing references) //IL_02a7: Unknown result type (might be due to invalid IL or missing references) //IL_02be: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)PlayerPrefab == (Object)null) { PlayerControllerB val = ((IEnumerable)PlayerControllers).FirstOrDefault((Func)((PlayerControllerB x) => ((Object)x).name == "Player")); if ((Object)(object)val != (Object)null) { ((Component)val).gameObject.SetActive(false); PlayerPrefab = Object.Instantiate(((Component)val).gameObject); ((Object)PlayerPrefab).name = "VRM T Pose Match"; ((Object)PlayerPrefab).hideFlags = (HideFlags)61; Material material = ((Renderer)GameObject.Find("CatwalkShip").GetComponent()).material; HDRP_BaseMaterial = new Material(material); HDRP_BaseMaterial.SetFloat("_Smoothness", 0f); HDRP_BaseMaterial.SetFloat("_Metallic", 0f); HDRP_BaseMaterial.SetTextureScale("_BaseColorMap", Vector2.one); ((Component)val).gameObject.SetActive(true); ((Behaviour)PlayerPrefab.GetComponentInChildren()).enabled = false; UnityExtensions.FindDescendant(PlayerPrefab.transform, "arm.L_upper").localRotation = Quaternion.Euler(0f, 90f, -10f); UnityExtensions.FindDescendant(PlayerPrefab.transform, "arm.R_upper").localRotation = Quaternion.Euler(-10f, 0f, 0f); UnityExtensions.FindDescendant(PlayerPrefab.transform, "thigh.L").localRotation = Quaternion.Euler(20f, 180f, 180f); UnityExtensions.FindDescendant(PlayerPrefab.transform, "thigh.R").localRotation = Quaternion.Euler(20f, 180f, 180f); UnityExtensions.FindDescendant(PlayerPrefab.transform, "hand.R").localRotation = Quaternion.Euler(0f, 90f, 0f); UnityExtensions.FindDescendant(PlayerPrefab.transform, "hand.L").localRotation = Quaternion.Euler(0f, 270f, 0f); Transform val2 = UnityExtensions.FindDescendant(PlayerPrefab.transform, "foot.L"); Transform val3 = UnityExtensions.FindDescendant(PlayerPrefab.transform, "foot.R"); Transform val4 = UnityExtensions.FindDescendant(PlayerPrefab.transform, "spine.004_end"); Vector3 val5 = default(Vector3); ((Vector3)(ref val5))..ctor(0f, ((val2.position + val3.position) / 2f).y, 0f); Vector3 val6 = default(Vector3); ((Vector3)(ref val6))..ctor(0f, val4.position.y, 0f); PlayerPrefabHeight = Vector3.Distance(val5, val6); PlayerPrefab.transform.rotation = Quaternion.identity; Debug.Log((object)$"BetterLethalVRM base prefab set to {((Object)PlayerPrefab).name}, has a height of {PlayerPrefabHeight:0.###}"); } } } private void FindPlayerControllers() { PlayerControllers = Object.FindObjectsOfType(true); Debug.Log((object)$"BetterLethalVRM found {PlayerControllers.Length} player controllers"); } private void FindUpdatedIDs() { PlayerControllerB[] playerControllers = PlayerControllers; foreach (PlayerControllerB val in playerControllers) { if (val.playerSteamId == 0L) { continue; } if (PlayersBySteamID.ContainsKey(val.playerSteamId)) { if (!val.disconnectedMidGame) { NetworkObject networkObject = ((NetworkBehaviour)val).NetworkObject; if (networkObject == null || networkObject.OwnerClientId != 0 || !(((Object)val).name != "Player")) { goto IL_00b3; } } if (Instances.TryGetValue(val.playerSteamId, out BetterLethalVRMInstance value)) { Object.Destroy((Object)(object)((Component)value.Vrm10Instance).gameObject); } PlayersBySteamID.Remove(val.playerSteamId); Instances.Remove(val.playerSteamId); continue; } goto IL_00b3; IL_00b3: NetworkObject networkObject2 = ((NetworkBehaviour)val).NetworkObject; if ((networkObject2 != null && networkObject2.OwnerClientId == 0 && ((Object)val).name != "Player") || !PlayersBySteamID.TryAdd(val.playerSteamId, val)) { continue; } if (!File.Exists(string.Format("{0}/{1}_{2}.txt", "VRMs", val.playerSteamId, val.playerUsername))) { File.WriteAllText(string.Format("{0}/{1}_{2}.txt", "VRMs", val.playerSteamId, val.playerUsername), $"{val.playerSteamId} seen as {val.playerUsername}"); } if (Instances.ContainsKey(val.playerSteamId) || LoadingSteamIds.Contains(val.playerSteamId)) { continue; } string text = string.Format("{0}/{1}.vrm", "VRMs", val.playerSteamId); if (File.Exists(text)) { Debug.Log((object)("BetterLethalVRM trying to load model for path " + text)); LoadModelToPlayer(text, val); continue; } text = "VRMs/" + val.playerUsername + ".vrm"; if (File.Exists(text)) { Debug.Log((object)("BetterLethalVRM trying to load model for path " + text)); LoadModelToPlayer(text, val); continue; } text = "VRMs/fallback.vrm"; if (File.Exists(text)) { Debug.Log((object)("BetterLethalVRM trying to load fallback model for path " + text)); LoadModelToPlayer(text, val); } } } private void FindMaskEnemies() { } private async void LoadModelToPlayer(string Path, PlayerControllerB Player) { ulong steamId = Player.playerSteamId; LoadingSteamIds.Add(steamId); try { Vrm10Instance val = await Vrm10.LoadPathAsync(Path, true, (ControlRigGenerationOption)1, true, (IAwaitCaller)null, (ITextureDeserializer)null, (IMaterialDescriptorGenerator)(object)new HDRPVrm10MaterialDescriptorGenerator(), (VrmMetaInformationCallback)null, default(CancellationToken)); if ((Object)(object)val == (Object)null) { ((Behaviour)this).enabled = false; Debug.LogError((object)("BetterLethalVRM had an error loading the VRM at " + Path + ", this mod will not function")); return; } if ((Object)(object)Player == (Object)null || !PlayersBySteamID.TryGetValue(steamId, out PlayerControllerB value) || (Object)(object)value != (Object)(object)Player || Instances.ContainsKey(steamId)) { Debug.Log((object)("BetterLethalVRM discarding stale load for " + Path + " (player gone, replaced, or already loaded)")); Object.Destroy((Object)(object)((Component)val).gameObject); return; } ((Object)val).name = $"BetterLethalVRM Character Model {Player.playerUsername} {Player.playerSteamId}"; ((Component)val).transform.position = ((Component)Player).transform.position; BetterLethalVRMInstance betterLethalVRMInstance = new BetterLethalVRMInstance(); if ((Object)(object)HDRP_BaseMaterial == (Object)null) { ((Behaviour)this).enabled = false; Debug.LogError((object)"BetterLethalVRM had some error loading the Lethal Company shader material, this mod will not function"); Object.Destroy((Object)(object)((Component)val).gameObject); return; } Renderer[] componentsInChildren = ((Component)val).GetComponentsInChildren(true); foreach (Renderer val2 in componentsInChildren) { betterLethalVRMInstance.Renderers.Add(val2); val2.receiveShadows = true; val2.shadowCastingMode = (ShadowCastingMode)2; SkinnedMeshRenderer val3 = (SkinnedMeshRenderer)(object)((val2 is SkinnedMeshRenderer) ? val2 : null); if (val3 != null) { val3.updateWhenOffscreen = true; } Material[] array = (Material[])(object)new Material[val2.materials.Length]; for (int j = 0; j < val2.materials.Length; j++) { Material val4 = val2.materials[j]; Material val5 = new Material(HDRP_BaseMaterial) { name = ((Object)val4).name, mainTexture = val4.mainTexture }; if (val4.HasProperty("_M_CullMode")) { val5.SetFloat("_CullMode", val4.GetFloat("_M_CullMode")); } if (val4.HasProperty("_BumpMap")) { val5.SetTexture("_NormalMap", val4.GetTexture("_BumpMap")); } array[j] = val5; } val2.materials = array; } Animator controlRigAnimator = val.Runtime.ControlRig.ControlRigAnimator; ((Behaviour)controlRigAnimator).enabled = false; val.Runtime.VrmAnimation = null; (string, HumanBodyBones)[] array2 = new(string, HumanBodyBones)[49] { ("spine", (HumanBodyBones)0), ("spine.001", (HumanBodyBones)7), ("spine.002", (HumanBodyBones)8), ("spine.003", (HumanBodyBones)54), ("spine.004", (HumanBodyBones)9), ("shoulder.R", (HumanBodyBones)12), ("arm.R_upper", (HumanBodyBones)14), ("arm.R_lower", (HumanBodyBones)16), ("hand.R", (HumanBodyBones)18), ("shoulder.L", (HumanBodyBones)11), ("arm.L_upper", (HumanBodyBones)13), ("arm.L_lower", (HumanBodyBones)15), ("hand.L", (HumanBodyBones)17), ("thigh.R", (HumanBodyBones)2), ("shin.R", (HumanBodyBones)4), ("foot.R", (HumanBodyBones)6), ("thigh.L", (HumanBodyBones)1), ("shin.L", (HumanBodyBones)3), ("foot.L", (HumanBodyBones)5), ("finger1.L", (HumanBodyBones)24), ("finger1.L.001", (HumanBodyBones)25), ("finger1.L.001_end", (HumanBodyBones)26), ("finger2.L", (HumanBodyBones)27), ("finger2.L.001", (HumanBodyBones)28), ("finger2.L.001_end", (HumanBodyBones)29), ("finger3.L", (HumanBodyBones)30), ("finger3.L.001", (HumanBodyBones)31), ("finger3.L.001_end", (HumanBodyBones)32), ("finger4.L", (HumanBodyBones)33), ("finger4.L.001", (HumanBodyBones)34), ("finger4.L.001_end", (HumanBodyBones)35), ("finger5.L", (HumanBodyBones)36), ("finger5.L.001", (HumanBodyBones)37), ("finger5.L.001_end", (HumanBodyBones)38), ("finger1.R", (HumanBodyBones)39), ("finger1.R.001", (HumanBodyBones)40), ("finger1.R.001_end", (HumanBodyBones)41), ("finger2.R", (HumanBodyBones)42), ("finger2.R.001", (HumanBodyBones)43), ("finger2.R.001_end", (HumanBodyBones)44), ("finger3.R", (HumanBodyBones)45), ("finger3.R.001", (HumanBodyBones)46), ("finger3.R.001_end", (HumanBodyBones)47), ("finger4.R", (HumanBodyBones)48), ("finger4.R.001", (HumanBodyBones)49), ("finger4.R.001_end", (HumanBodyBones)50), ("finger5.R", (HumanBodyBones)51), ("finger5.R.001", (HumanBodyBones)52), ("finger5.R.001_end", (HumanBodyBones)53) }; if ((Object)(object)PlayerPrefab == (Object)null) { ((Behaviour)this).enabled = false; Debug.LogError((object)"BetterLethalVRM failed to find the player prefab, this mod will not function"); Object.Destroy((Object)(object)((Component)val).gameObject); return; } HashSet<(Transform, Transform, Quaternion)> hashSet = new HashSet<(Transform, Transform, Quaternion)>(); (string, HumanBodyBones)[] array3 = array2; for (int k = 0; k < array3.Length; k++) { (string, HumanBodyBones) tuple = array3[k]; Transform boneTransform = controlRigAnimator.GetBoneTransform(tuple.Item2); if ((Object)(object)boneTransform == (Object)null) { Debug.Log((object)$"BetterLethalVRM {Path} missing bone {tuple.Item2} ({tuple.Item1})"); continue; } Transform val6 = UnityExtensions.FindDescendant(((Component)Player).transform, tuple.Item1); Transform val7 = UnityExtensions.FindDescendant(PlayerPrefab.transform, tuple.Item1); Transform transform = new GameObject("VRM Rotation Bone").transform; transform.parent = val7; transform.position = val7.position; transform.rotation = boneTransform.rotation; Quaternion localRotation = transform.localRotation; transform.parent = val6; transform.position = val6.position; transform.localRotation = localRotation; hashSet.Add((boneTransform, transform, localRotation)); } Vector3 val8 = default(Vector3); ((Vector3)(ref val8))..ctor(0f, val.Humanoid.Head.position.y, 0f); Vector3 val9 = default(Vector3); ((Vector3)(ref val9))..ctor(0f, ((Component)val).transform.position.y, 0f); float num = Vector3.Distance(val8, val9); float num2 = PlayerPrefabHeight / num; ((Component)val).transform.localScale = new Vector3(num2, num2, num2); Debug.Log((object)$"BetterLethalVRM {Path} has a height of: {num:0.###}, scaling to {num2:0.###}"); float num3 = Vector3.Distance(val.Humanoid.Hips.position, (val.Humanoid.LeftFoot.position + val.Humanoid.RightFoot.position) / 2f); Transform val10 = UnityExtensions.FindDescendant(PlayerPrefab.transform, "spine"); Transform val11 = UnityExtensions.FindDescendant(PlayerPrefab.transform, "foot.L"); Transform val12 = UnityExtensions.FindDescendant(PlayerPrefab.transform, "foot.R"); float num4 = Vector3.Distance(val10.position, (val11.position + val12.position) / 2f); ((Component)UnityExtensions.FindDescendant(((Component)Player).transform, "LOD1")).gameObject.SetActive(false); ((Component)UnityExtensions.FindDescendant(((Component)Player).transform, "LOD2")).gameObject.SetActive(false); ((Component)UnityExtensions.FindDescendant(((Component)Player).transform, "LOD3")).gameObject.SetActive(false); ((Component)UnityExtensions.FindDescendant(((Component)Player).transform, "LevelSticker")).gameObject.SetActive(false); ((Component)UnityExtensions.FindDescendant(((Component)Player).transform, "BetaBadge")).gameObject.SetActive(false); foreach (Spring spring in val.SpringBone.Springs) { spring.Center = null; foreach (VRM10SpringBoneJoint joint in spring.Joints) { joint.m_stiffnessForce *= 10f; } } val.Runtime.ReconstructSpringBone(); betterLethalVRMInstance.Vrm10Instance = val; betterLethalVRMInstance.PlayerControllerB = Player; betterLethalVRMInstance.HipOffset = num3 - num4; betterLethalVRMInstance.BoneTranslation = hashSet; betterLethalVRMInstance.VrmPath = Path; betterLethalVRMInstance.VerticalOffset = ReadOffsetFile(Path); Instances.Add(betterLethalVRMInstance.PlayerControllerB.playerSteamId, betterLethalVRMInstance); Debug.Log((object)("BetterLethalVRM finished loading " + Path)); } finally { LoadingSteamIds.Remove(steamId); } } private float ReadOffsetFile(string vrmPath) { string text = Path.ChangeExtension(vrmPath, ".offset"); if (!File.Exists(text)) { return 0f; } try { string s = File.ReadAllText(text).Trim(); if (float.TryParse(s, NumberStyles.Float, CultureInfo.InvariantCulture, out var result)) { Debug.Log((object)$"BetterLethalVRM loaded vertical offset {result:0.000} from {text}"); return result; } Debug.LogWarning((object)("BetterLethalVRM offset file " + text + " could not be parsed as a number")); } catch (Exception ex) { Debug.LogError((object)("BetterLethalVRM failed to read offset file " + text + ": " + ex.Message)); } return 0f; } private void WriteOffsetFile(BetterLethalVRMInstance instance) { if (string.IsNullOrEmpty(instance.VrmPath)) { return; } string text = Path.ChangeExtension(instance.VrmPath, ".offset"); try { File.WriteAllText(text, instance.VerticalOffset.ToString("0.######", CultureInfo.InvariantCulture)); Debug.Log((object)$"BetterLethalVRM saved vertical offset {instance.VerticalOffset:0.000} to {text}"); } catch (Exception ex) { Debug.LogError((object)("BetterLethalVRM failed to write offset file " + text + ": " + ex.Message)); } } private BetterLethalVRMInstance FindLocalInstance() { foreach (BetterLethalVRMInstance value in Instances.Values) { if ((Object)(object)value.PlayerControllerB != (Object)null && ((NetworkBehaviour)value.PlayerControllerB).IsOwner) { return value; } } return null; } private unsafe static Key KeyCodeToInputSystemKey(KeyCode kc) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) string text = ((object)(*(KeyCode*)(&kc))/*cast due to .constrained prefix*/).ToString(); if (text.Length == 6 && text.StartsWith("Alpha")) { text = "Digit" + text.Substring(5); } if (!Enum.TryParse(text, out Key result)) { return (Key)0; } return result; } private static bool IsShortcutPressed(KeyboardShortcut shortcut) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) Keyboard current = Keyboard.current; if (current == null) { return false; } Key val = KeyCodeToInputSystemKey(((KeyboardShortcut)(ref shortcut)).MainKey); if ((int)val == 0 || !((ButtonControl)current[val]).isPressed) { return false; } foreach (KeyCode modifier in ((KeyboardShortcut)(ref shortcut)).Modifiers) { Key val2 = KeyCodeToInputSystemKey(modifier); if ((int)val2 == 0 || !((ButtonControl)current[val2]).isPressed) { return false; } } return true; } private void HandleOffsetInput() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) bool flag = IsShortcutPressed(RaiseOffsetKey.Value); bool flag2 = IsShortcutPressed(LowerOffsetKey.Value); if (flag || flag2) { BetterLethalVRMInstance betterLethalVRMInstance = FindLocalInstance(); if (betterLethalVRMInstance != null) { float num = OffsetAdjustSpeed.Value * Time.deltaTime; if (flag) { betterLethalVRMInstance.VerticalOffset += num; } if (flag2) { betterLethalVRMInstance.VerticalOffset -= num; } OffsetDirty = true; } } else if (OffsetDirty) { BetterLethalVRMInstance betterLethalVRMInstance2 = FindLocalInstance(); if (betterLethalVRMInstance2 != null) { WriteOffsetFile(betterLethalVRMInstance2); } OffsetDirty = false; } } private void AnimateBonePairs() { //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_02be: Unknown result type (might be due to invalid IL or missing references) //IL_02c3: Unknown result type (might be due to invalid IL or missing references) //IL_02d0: Unknown result type (might be due to invalid IL or missing references) //IL_02e3: Unknown result type (might be due to invalid IL or missing references) //IL_020a: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Unknown result type (might be due to invalid IL or missing references) //IL_02f9: Unknown result type (might be due to invalid IL or missing references) //IL_0302: Unknown result type (might be due to invalid IL or missing references) //IL_0309: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Unknown result type (might be due to invalid IL or missing references) //IL_0228: 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_0238: Unknown result type (might be due to invalid IL or missing references) //IL_0257: 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) //IL_0267: Unknown result type (might be due to invalid IL or missing references) //IL_026c: Unknown result type (might be due to invalid IL or missing references) List list = new List(); foreach (BetterLethalVRMInstance value in Instances.Values) { if ((Object)(object)value.Vrm10Instance == (Object)null || (Object)(object)value.PlayerControllerB == (Object)null) { list.Add(value); continue; } if ((Object)(object)value.DeadBodyRoot == (Object)null) { value.DeadMap = null; value.DeadBodyRoot = null; } bool flag = false; foreach (var item in value.BoneTranslation) { if ((Object)(object)item.target == (Object)null || (Object)(object)item.source == (Object)null) { list.Add(value); flag = true; break; } if (value.DeadMap != null && (Object)(object)value.DeadMap[item.source] == (Object)null) { value.DeadMap = null; value.DeadBodyRoot = null; } } if (flag) { continue; } if (!value.PlayerControllerB.isPlayerDead || (Object)(object)value.DeadBodyRoot == (Object)null) { value.DeadMap = null; value.DeadBodyRoot = null; } if (value.PlayerControllerB.isPlayerDead && (Object)(object)value.DeadBodyRoot == (Object)null && (Object)(object)value.PlayerControllerB.deadBody != (Object)null) { value.SetSkeletonMimic(((Component)value.PlayerControllerB.deadBody).transform); } foreach (var item2 in value.BoneTranslation) { item2.target.rotation = ((value.DeadMap != null) ? value.DeadMap[item2.source].rotation : item2.source.rotation); if (((Object)item2.source.parent).name == "spine") { item2.target.position = ((value.DeadMap != null) ? value.DeadMap[item2.source].position : item2.source.position); var (val, _, _) = item2; val.position += item2.target.up * value.HipOffset; if (value.VerticalOffset != 0f) { var (val2, _, _) = item2; val2.position += Vector3.up * value.VerticalOffset; } } } if ((Object)(object)value.Vrm10Instance != (Object)null && (Object)(object)((Component)value.Vrm10Instance).transform != (Object)null) { Vector3 position = ((Component)value.Vrm10Instance).transform.position; float num = ((Component)value.PlayerControllerB).transform.position.y + value.VerticalOffset; if (position.y != num) { ((Component)value.Vrm10Instance).transform.position = new Vector3(position.x, num, position.z); } } value.UpdateVisibility(); } if (!list.Any()) { return; } foreach (BetterLethalVRMInstance i in list) { if ((Object)(object)i.Vrm10Instance != (Object)null) { Object.Destroy((Object)(object)((Component)i.Vrm10Instance).gameObject); } if ((Object)(object)i.PlayerControllerB != (Object)null) { Instances.Remove(i.PlayerControllerB.playerSteamId); PlayersBySteamID.Remove(i.PlayerControllerB.playerSteamId); continue; } KeyValuePair keyValuePair = Instances.FirstOrDefault>((KeyValuePair kv) => kv.Value == i); if (!keyValuePair.Equals(default(KeyValuePair))) { Instances.Remove(keyValuePair.Key); PlayersBySteamID.Remove(keyValuePair.Key); } } } } internal class BetterLethalVRMInstance { private const int FirstPersonLayer = 23; private const int ThirdPersonLayer = 0; public readonly HashSet Renderers = new HashSet(); public HashSet<(Transform target, Transform source, Quaternion localRotation)> BoneTranslation = new HashSet<(Transform, Transform, Quaternion)>(); public Transform DeadBodyRoot; public Dictionary DeadMap; public float HipOffset; public float VerticalOffset; public string VrmPath; public PlayerControllerB PlayerControllerB; public Vrm10Instance Vrm10Instance; public void SetSkeletonMimic(Transform Root) { //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) DeadBodyRoot = Root; DeadMap = new Dictionary(); if ((Object)(object)PlayerControllerB.deadBody != (Object)null && (Object)(object)((Component)PlayerControllerB.deadBody).transform == (Object)(object)Root) { ((Object)Root).name = "spine"; } foreach (var item in BoneTranslation) { Transform val = UnityExtensions.FindDescendant(Root, ((Object)item.source.parent).name); Transform transform = new GameObject("VRM Rotation Bone").transform; transform.parent = val; transform.position = val.position; transform.localRotation = item.localRotation; DeadMap[item.source] = transform; } Renderer[] componentsInChildren = ((Component)Root).GetComponentsInChildren(); foreach (Renderer val2 in componentsInChildren) { bool flag = (Object)(object)PlayerControllerB.deadBody != (Object)null && (Object)(object)((Component)PlayerControllerB.deadBody).transform == (Object)(object)Root; bool flag2 = flag; if (!flag2) { bool flag3; switch (((Object)val2).name) { case "LOD1": case "LOD2": case "LOD3": case "LevelSticker": case "BetaBadge": flag3 = true; break; default: flag3 = false; break; } flag2 = flag3; } if (flag2) { val2.enabled = false; } } } public void UpdateVisibility() { bool enabled = !PlayerControllerB.isPlayerDead || ((Object)(object)DeadBodyRoot != (Object)null && (Object)(object)PlayerControllerB.deadBody != (Object)null); bool flag = !((Behaviour)PlayerControllerB.gameplayCamera).enabled; foreach (Renderer renderer in Renderers) { ((Component)renderer).gameObject.layer = ((!flag) ? 23 : 0); renderer.enabled = enabled; } } } public static class HDRPGltfPbrMaterialImporter { private enum BlendMode { Opaque, Cutout, Fade, Transparent } public const string ShaderName = "HDRP/Lit"; private static readonly int SrcBlend = Shader.PropertyToID("_SrcBlend"); private static readonly int DstBlend = Shader.PropertyToID("_DstBlend"); private static readonly int ZWrite = Shader.PropertyToID("_ZWrite"); private static readonly int Cutoff = Shader.PropertyToID("_Cutoff"); public static Shader Shader => Shader.Find("HDRP/Lit"); public static bool TryCreateParam(GltfData Data, int i, out MaterialDescriptor MatDesc) { //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0407: Unknown result type (might be due to invalid IL or missing references) //IL_040d: Expected O, but got Unknown //IL_02eb: Unknown result type (might be due to invalid IL or missing references) //IL_0298: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_0388: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_03ca: Unknown result type (might be due to invalid IL or missing references) if (i < 0 || i >= Data.GLTF.materials.Count) { MatDesc = null; return false; } Dictionary dictionary = new Dictionary(); Dictionary dictionary2 = new Dictionary(); Dictionary dictionary3 = new Dictionary(); Dictionary dictionary4 = new Dictionary(); List> list = new List>(); glTFMaterial tSrc = Data.GLTF.materials[i]; TextureDescriptor? val = null; if (tSrc.pbrMetallicRoughness != null || tSrc.occlusionTexture != null) { SubAssetKey val2 = default(SubAssetKey); TextureDescriptor val3 = default(TextureDescriptor); if ((tSrc.pbrMetallicRoughness.metallicRoughnessTexture != null || tSrc.occlusionTexture != null) && GltfPbrTextureImporter.TryStandardTexture(Data, tSrc, ref val2, ref val3)) { if (string.IsNullOrEmpty(val3.UnityObjectName)) { throw new ArgumentNullException(); } val = val3; } if (tSrc.pbrMetallicRoughness.baseColorFactor != null && tSrc.pbrMetallicRoughness.baseColorFactor.Length == 4) { dictionary3.Add("_BaseColor", ColorConversionExtensions.ToColor4(tSrc.pbrMetallicRoughness.baseColorFactor, (ColorSpace)1, (ColorSpace)0)); } SubAssetKey val4 = default(SubAssetKey); TextureDescriptor value = default(TextureDescriptor); if (tSrc.pbrMetallicRoughness.baseColorTexture != null && ((glTFTextureInfo)tSrc.pbrMetallicRoughness.baseColorTexture).index != -1 && GltfPbrTextureImporter.TryBaseColorTexture(Data, tSrc, ref val4, ref value)) { dictionary.Add("_BaseMap", value); } if (tSrc.pbrMetallicRoughness.metallicRoughnessTexture != null && ((glTFTextureInfo)tSrc.pbrMetallicRoughness.metallicRoughnessTexture).index != -1 && val.HasValue) { list.Add(delegate(Material material) { material.EnableKeyword("_METALLICSPECGLOSSMAP"); }); dictionary.Add("_MetallicGlossMap", val.Value); dictionary2.Add("_Metallic", 1f); dictionary2.Add("_GlossMapScale", 1f); dictionary2.Add("_Smoothness", 1f); } else { dictionary2.Add("_Metallic", tSrc.pbrMetallicRoughness.metallicFactor); dictionary2.Add("_Smoothness", 1f - tSrc.pbrMetallicRoughness.roughnessFactor); } } if (tSrc.normalTexture != null && ((glTFTextureInfo)tSrc.normalTexture).index != -1) { list.Add(delegate(Material material) { material.EnableKeyword("_NORMALMAP"); }); SubAssetKey val5 = default(SubAssetKey); TextureDescriptor value2 = default(TextureDescriptor); if (GltfPbrTextureImporter.TryNormalTexture(Data, tSrc, ref val5, ref value2)) { dictionary.Add("_BumpMap", value2); dictionary2.Add("_BumpScale", tSrc.normalTexture.scale); } } if (tSrc.occlusionTexture != null && ((glTFTextureInfo)tSrc.occlusionTexture).index != -1 && val.HasValue) { dictionary.Add("_OcclusionMap", val.Value); dictionary2.Add("_OcclusionStrength", tSrc.occlusionTexture.strength); } if (tSrc.emissiveFactor != null || (tSrc.emissiveTexture != null && ((glTFTextureInfo)tSrc.emissiveTexture).index != -1)) { list.Add(delegate(Material material) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) material.EnableKeyword("_EMISSION"); material.globalIlluminationFlags = (MaterialGlobalIlluminationFlags)(material.globalIlluminationFlags & -5); }); Color? val6 = GltfMaterialImportUtils.ImportLinearEmissiveFactor(Data, tSrc); if (val6.HasValue) { dictionary3.Add("_EmissionColor", val6.Value); } SubAssetKey val7 = default(SubAssetKey); TextureDescriptor value3 = default(TextureDescriptor); if (tSrc.emissiveTexture != null && ((glTFTextureInfo)tSrc.emissiveTexture).index != -1 && GltfPbrTextureImporter.TryEmissiveTexture(Data, tSrc, ref val7, ref value3)) { dictionary.Add("_EmissionMap", value3); } } list.Add(delegate(Material material) { BlendMode blendMode = BlendMode.Opaque; string alphaMode = tSrc.alphaMode; if (!(alphaMode == "BLEND")) { if (alphaMode == "MASK") { blendMode = BlendMode.Cutout; material.SetOverrideTag("RenderType", "TransparentCutout"); material.SetInt(SrcBlend, 1); material.SetInt(DstBlend, 0); material.SetInt(ZWrite, 1); material.SetFloat(Cutoff, tSrc.alphaCutoff); material.EnableKeyword("_ALPHATEST_ON"); material.DisableKeyword("_ALPHABLEND_ON"); material.DisableKeyword("_ALPHAPREMULTIPLY_ON"); material.renderQueue = 2450; } else { blendMode = BlendMode.Opaque; material.SetOverrideTag("RenderType", ""); material.SetInt(SrcBlend, 1); material.SetInt(DstBlend, 0); material.SetInt(ZWrite, 1); material.DisableKeyword("_ALPHATEST_ON"); material.DisableKeyword("_ALPHABLEND_ON"); material.DisableKeyword("_ALPHAPREMULTIPLY_ON"); material.renderQueue = -1; } } else { blendMode = BlendMode.Fade; material.SetOverrideTag("RenderType", "Transparent"); material.SetInt(SrcBlend, 5); material.SetInt(DstBlend, 10); material.SetInt(ZWrite, 0); material.DisableKeyword("_ALPHATEST_ON"); material.EnableKeyword("_ALPHABLEND_ON"); material.DisableKeyword("_ALPHAPREMULTIPLY_ON"); material.renderQueue = 3000; } material.SetFloat("_Mode", (float)blendMode); }); MatDesc = new MaterialDescriptor(GltfMaterialImportUtils.ImportMaterialName(i, tSrc), Shader, (int?)null, (IReadOnlyDictionary)dictionary, (IReadOnlyDictionary)dictionary2, (IReadOnlyDictionary)dictionary3, (IReadOnlyDictionary)dictionary4, (IReadOnlyList>)list); return true; } } public sealed class HDRPVrm10MaterialDescriptorGenerator : IMaterialDescriptorGenerator { public MaterialDescriptor Get(GltfData Data, int i) { //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Expected O, but got Unknown if (HDRPVrm10MToonMaterialImporter.TryCreateParam(Data, i, out MaterialDescriptor MatDesc) || HDRPVrm10MToonMaterialImporter.TryCreateParam(Data, i, out MatDesc) || HDRPVrm10MToonMaterialImporter.TryCreateParam(Data, i, out MatDesc)) { return MatDesc; } Debug.LogWarning((object)$"vrm material: {i} out of range. fallback"); Debug.LogError((object)"BetterLethalVRM fallback materials are not supported, try exporting your VRM again using the MToon shader"); return new MaterialDescriptor(GltfMaterialImportUtils.ImportMaterialName(i, (glTFMaterial)null), HDRPGltfPbrMaterialImporter.Shader, (int?)null, (IReadOnlyDictionary)new Dictionary(), (IReadOnlyDictionary)new Dictionary(), (IReadOnlyDictionary)new Dictionary(), (IReadOnlyDictionary)new Dictionary(), (IReadOnlyList>)new Action[0]); } public MaterialDescriptor GetGltfDefault() { return UrpGltfDefaultMaterialImporter.CreateParam(); } } public static class HDRPVrm10MToonMaterialImporter { public static Shader MToonReplacementShader; public static bool TryCreateParam(GltfData Data, int i, out MaterialDescriptor MatDesc) { //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Expected O, but got Unknown glTFMaterial val = Data.GLTF.materials[i]; VRMC_materials_mtoon val2 = default(VRMC_materials_mtoon); if (!GltfDeserializer.TryGet(val.extensions, ref val2)) { MatDesc = null; return false; } MatDesc = new MaterialDescriptor(val.name, MToonReplacementShader, (int?)null, (IReadOnlyDictionary)Vrm10MToonTextureImporter.EnumerateAllTextures(Data, val, val2).ToDictionary<(string, (SubAssetKey, TextureDescriptor)), string, TextureDescriptor>(((string key, (SubAssetKey, TextureDescriptor)) tuple) => tuple.key, ((string key, (SubAssetKey, TextureDescriptor)) tuple) => tuple.Item2.Item2), (IReadOnlyDictionary)BuiltInVrm10MToonMaterialImporter.TryGetAllFloats(val, val2).ToDictionary<(string, float), string, float>(((string key, float value) tuple) => tuple.key, ((string key, float value) tuple) => tuple.value), (IReadOnlyDictionary)BuiltInVrm10MToonMaterialImporter.TryGetAllColors(val, val2).ToDictionary<(string, Color), string, Color>(((string key, Color value) tuple) => tuple.key, ((string key, Color value) tuple) => tuple.value), (IReadOnlyDictionary)BuiltInVrm10MToonMaterialImporter.TryGetAllFloatArrays(val, val2).ToDictionary<(string, Vector4), string, Vector4>(((string key, Vector4 value) tuple) => tuple.key, ((string key, Vector4 value) tuple) => tuple.value), (IReadOnlyList>)new Action[1] { delegate(Material material) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) new MToonValidator(material).Validate(); } }); return true; } } }