using System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using UnityEngine; using Zorro.Core; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("GhostHats")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.1.0.0")] [assembly: AssemblyInformationalVersion("0.1.0+58a883f81ab0a4fcb6daeb34c041f97c31e23c98")] [assembly: AssemblyProduct("GhostHats")] [assembly: AssemblyTitle("GhostHats")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.1.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.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace GhostHats { internal class GhostHat : MonoBehaviour { internal static void Attach(PlayerGhost ghost) { if (!((Object)(object)ghost == (Object)null) && !((Object)(object)ghost.m_owner == (Object)null) && !((Object)(object)((Component)ghost).GetComponent() != (Object)null)) { Character owner = ghost.m_owner; PhotonView photonView = ((MonoBehaviourPun)owner).photonView; if (!((Object)(object)photonView != (Object)null) || !photonView.IsMine) { ((Component)ghost).gameObject.AddComponent().Build(ghost, owner); } } } private void Build(PlayerGhost ghost, Character owner) { //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: 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_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: Unknown result type (might be due to invalid IL or missing references) Renderer val = ResolveHatRenderer(owner); if ((Object)(object)val == (Object)null) { Object.Destroy((Object)(object)this); return; } CustomizationRefs refs = owner.refs.customization.refs; if (!TryFaceFrame(refs.EyeRenderers, refs.mouthRenderer, out var center, out var rotation, out var span) || !TryFaceFrame(ghost.EyeRenderers, ghost.mouthRenderer, out var center2, out var rotation2, out var span2)) { Plugin.Log.LogWarning((object)"Could not measure a face (two eyes + a mouth) on the character or the ghost, so there is nothing to line the hat up with. Did the game update?"); Object.Destroy((Object)(object)this); return; } GameObject val2 = Object.Instantiate(((Component)val).gameObject); ((Object)val2).name = "GhostHat"; val2.SetActive(true); Collider[] componentsInChildren = val2.GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren.Length; i++) { Object.Destroy((Object)(object)componentsInChildren[i]); } SetLayerRecursively(val2.transform, GhostLayer(ghost)); Quaternion val3 = rotation2 * Quaternion.Inverse(rotation); float num = span2 / span; Transform transform = ((Component)val).transform; Vector3 val4 = center2 + val3 * (transform.position - center) * num; Quaternion val5 = val3 * transform.rotation; Vector3 val6 = transform.lossyScale * num; Transform transform2 = ((Component)ghost).transform; Vector3 lossyScale = transform2.lossyScale; Transform transform3 = val2.transform; transform3.SetParent(transform2, false); transform3.localPosition = transform2.InverseTransformPoint(val4); transform3.localRotation = Quaternion.Inverse(transform2.rotation) * val5; transform3.localScale = new Vector3(val6.x / NonZero(lossyScale.x), val6.y / NonZero(lossyScale.y), val6.z / NonZero(lossyScale.z)); Log($"Hat '{((Object)val).name}' on {owner.characterName}'s ghost: scale ratio {num:F3}, " + $"local pos {transform3.localPosition}."); } private static Renderer ResolveHatRenderer(Character owner) { CharacterCustomization val = ((owner.refs != null) ? owner.refs.customization : null); if ((Object)(object)val == (Object)null || (Object)(object)val.refs == (Object)null || val.refs.playerHats == null) { Log(owner.characterName + " has no customization refs, so no hat."); return null; } Renderer[] playerHats = val.refs.playerHats; PersistentPlayerData playerData = GameHandler.GetService().GetPlayerData(((MonoBehaviourPun)owner).photonView.Owner); if (playerData == null) { return null; } int num = playerData.customizationData.currentHat; Customization instance = Singleton.Instance; if ((Object)(object)instance != (Object)null) { CustomizationOption val2 = instance.fits[CharacterCustomization.GetFitIndex(playerData)]; if ((Object)(object)val2 != (Object)null && val2.overrideHat) { num = val2.overrideHatIndex; } if (num >= 0 && num < instance.hats.Length && (Object)(object)instance.hats[num] != (Object)null && instance.hats[num].isBlank) { Log(owner.characterName + " is not wearing a hat."); return null; } } if (num < 0 || num >= playerHats.Length) { Log($"Hat index {num} is out of range (0..{playerHats.Length - 1}), so no hat."); return null; } Renderer val3 = playerHats[num]; if ((Object)(object)val3 == (Object)null || !HasVisibleMesh(val3)) { Log($"Hat index {num} has no mesh, so no hat."); return null; } return val3; } private static bool TryFaceFrame(Renderer[] eyes, Renderer mouth, out Vector3 center, out Quaternion rotation, out float span) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: 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) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: 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_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0112: 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_011a: Unknown result type (might be due to invalid IL or missing references) //IL_011f: 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_0128: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0159: 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_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) center = Vector3.zero; rotation = Quaternion.identity; span = 0f; if (eyes == null || eyes.Length < 2 || (Object)(object)mouth == (Object)null) { return false; } Vector3 val = Vector3.zero; Vector3 val2 = Vector3.zero; Bounds bounds; for (int i = 0; i < eyes.Length; i++) { if ((Object)(object)eyes[i] == (Object)null) { continue; } for (int j = i + 1; j < eyes.Length; j++) { if (!((Object)(object)eyes[j] == (Object)null)) { bounds = eyes[i].bounds; Vector3 center2 = ((Bounds)(ref bounds)).center; bounds = eyes[j].bounds; float num = Vector3.Distance(center2, ((Bounds)(ref bounds)).center); if (!(num <= span)) { span = num; bounds = eyes[i].bounds; val = ((Bounds)(ref bounds)).center; bounds = eyes[j].bounds; val2 = ((Bounds)(ref bounds)).center; } } } } if (span < 0.0001f) { return false; } center = (val + val2) * 0.5f; Vector3 val3 = (val2 - val) / span; Vector3 val4 = center; bounds = mouth.bounds; Vector3 val5 = Vector3.ProjectOnPlane(val4 - ((Bounds)(ref bounds)).center, val3); if (((Vector3)(ref val5)).sqrMagnitude < 1E-08f) { return false; } ((Vector3)(ref val5)).Normalize(); rotation = Quaternion.LookRotation(Vector3.Cross(val3, val5), val5); return true; } private static int GhostLayer(PlayerGhost ghost) { Renderer[] playerRenderers = ghost.PlayerRenderers; if (playerRenderers != null) { for (int i = 0; i < playerRenderers.Length; i++) { if ((Object)(object)playerRenderers[i] != (Object)null) { return ((Component)playerRenderers[i]).gameObject.layer; } } } return ((Component)ghost).gameObject.layer; } private static void SetLayerRecursively(Transform t, int layer) { ((Component)t).gameObject.layer = layer; for (int i = 0; i < t.childCount; i++) { SetLayerRecursively(t.GetChild(i), layer); } } private static bool HasVisibleMesh(Renderer renderer) { MeshFilter component = ((Component)renderer).GetComponent(); if ((Object)(object)component != (Object)null && (Object)(object)component.sharedMesh != (Object)null) { return true; } SkinnedMeshRenderer val = (SkinnedMeshRenderer)(object)((renderer is SkinnedMeshRenderer) ? renderer : null); if ((Object)(object)val != (Object)null && (Object)(object)val.sharedMesh != (Object)null) { return true; } if ((Object)(object)component == (Object)null) { return (Object)(object)val == (Object)null; } return false; } private static float NonZero(float v) { if (!(Mathf.Abs(v) < 1E-05f)) { return v; } return 1f; } private static void Log(string message) { Plugin.Log.LogDebug((object)message); } } [HarmonyPatch(typeof(PlayerGhost), "RPCA_InitGhost")] internal static class PlayerGhostInitPatch { private static void Postfix(PlayerGhost __instance) { try { GhostHat.Attach(__instance); } catch (Exception arg) { Plugin.Log.LogError((object)$"Failed to put a hat on a ghost: {arg}"); } } } [BepInPlugin("com.exoflex.ghosthats", "GhostHats", "0.1.0")] public class Plugin : BaseUnityPlugin { public const string PluginGuid = "com.exoflex.ghosthats"; public const string PluginName = "GhostHats"; public const string PluginVersion = "0.1.0"; private Harmony harmony; internal static ManualLogSource Log { get; private set; } private void Awake() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; harmony = new Harmony("com.exoflex.ghosthats"); harmony.PatchAll(typeof(Plugin).Assembly); Log.LogInfo((object)"GhostHats 0.1.0 loaded. Death is no excuse for bad fashion."); } private void OnDestroy() { Harmony obj = harmony; if (obj != null) { obj.UnpatchSelf(); } } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }