using System; using System.Collections.Generic; 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.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using UnityEngine; [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: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: AssemblyCompany("Vippy")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+32312975ceabdd634b835c7a8ffa6f3f51b54f2d")] [assembly: AssemblyProduct("Wink")] [assembly: AssemblyTitle("Wink")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.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 Wink { internal static class BuildInfo { public const string Version = "1.0.0"; } internal static class WinkState { internal static EyeSettings? Closed; internal static void EnsureClosed(List expressions) { if (Closed != null || expressions == null) { return; } float num = float.NegativeInfinity; EyeSettings val = null; foreach (ExpressionSettings expression in expressions) { if (expression == null) { continue; } EyeSettings[] array = (EyeSettings[])(object)new EyeSettings[2] { expression.leftEye, expression.rightEye }; foreach (EyeSettings val2 in array) { if (val2 != null && val2.upperLidClosedPercent > num) { num = val2.upperLidClosedPercent; val = val2; } } } if (val != null) { Closed = Copy(val); } } private static EyeSettings Copy(EyeSettings s) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: 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_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0035: 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_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0095: 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_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Expected O, but got Unknown return new EyeSettings { upperLidAngle = s.upperLidAngle, upperLidClosedPercent = s.upperLidClosedPercent, upperLidClosedPercentJitterAmount = s.upperLidClosedPercentJitterAmount, upperLidClosedPercentJitterSpeed = s.upperLidClosedPercentJitterSpeed, lowerLidAngle = s.lowerLidAngle, lowerLidClosedPercent = s.lowerLidClosedPercent, lowerLidClosedPercentJitterAmount = s.lowerLidClosedPercentJitterAmount, lowerLidClosedPercentJitterSpeed = s.lowerLidClosedPercentJitterSpeed, pupilSize = s.pupilSize, pupilSizeJitterAmount = s.pupilSizeJitterAmount, pupilSizeJitterSpeed = s.pupilSizeJitterSpeed, pupilPositionJitter = s.pupilPositionJitter, pupilPositionJitterAmount = s.pupilPositionJitterAmount, pupilOffsetRotationX = s.pupilOffsetRotationX, pupilOffsetRotationY = s.pupilOffsetRotationY }; } } internal enum WinkStyle { Normal, Seductive } internal static class WinkAnim { private class Anim { public float Timer; public float Dur; public WinkStyle Style; public float Amount; } private static readonly Dictionary _anims = new Dictionary(); private static readonly List _dead = new List(); public static void Start(PlayerExpression pe, WinkStyle style) { foreach (PlayerExpression key in _anims.Keys) { if ((Object)(object)key == (Object)null) { _dead.Add(key); } } foreach (PlayerExpression item in _dead) { _anims.Remove(item); } _dead.Clear(); float num = Mathf.Max(0.05f, (style == WinkStyle.Seductive) ? WinkConfig.SeductiveDuration.Value : WinkConfig.NormalDuration.Value); _anims[pe] = new Anim { Timer = num, Dur = num, Style = style }; } public static void Tick(PlayerExpression pe) { if (_anims.TryGetValue(pe, out Anim value)) { value.Timer -= Time.deltaTime; if (value.Timer <= 0f) { _anims.Remove(pe); } else { value.Amount = Mathf.Sin(MathF.PI * (1f - value.Timer / value.Dur)); } } } public static bool TryGet(PlayerExpression pe, out float amount, out WinkStyle style) { if (_anims.TryGetValue(pe, out Anim value)) { amount = value.Amount; style = value.Style; return true; } amount = 0f; style = WinkStyle.Normal; return false; } } [HarmonyPatch(typeof(PlayerExpression), "Start")] internal static class WinkSetupPatch { private static bool _logged; [HarmonyPostfix] public static void Postfix(PlayerExpression __instance) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) List expressions = __instance.expressions; if (expressions != null) { WinkState.EnsureClosed(expressions); if (!_logged) { _logged = true; WinkPlugin.Log.LogInfo((object)$"[Wink] {expressions.Count} expressions, wink on {WinkConfig.WinkKey.Value}"); } float value = WinkConfig.EyelidSpeed.Value; SetSpeed(__instance.leftUpperLidClosedAngle, value); SetSpeed(__instance.leftLowerLidClosedAngle, value); SetSpeed(__instance.rightUpperLidClosedAngle, value); SetSpeed(__instance.rightLowerLidClosedAngle, value); } } private static void SetSpeed(SpringFloat? spring, float spd) { if (spring != null) { spring.speed = spd; } } } [HarmonyPatch(typeof(PlayerExpression), "Update")] internal static class WinkUpdatePatch { private const float HeldFaceMinWeight = 5f; private const float KeepAliveTimer = 0.1f; [HarmonyPostfix] public static void Postfix(PlayerExpression __instance) { //IL_0094: Unknown result type (might be due to invalid IL or missing references) List expressions = __instance.expressions; if (expressions == null || expressions.Count == 0) { return; } PlayerAvatarVisuals playerVisuals = __instance.playerVisuals; if (__instance.isLocal && (Object)(object)playerVisuals != (Object)null && !playerVisuals.isMenuAvatar && (Object)(object)__instance.playerAvatar != (Object)null && (Object)(object)__instance == (Object)(object)__instance.playerAvatar.playerExpression && (Object)(object)MenuManager.instance != (Object)null && !Object.op_Implicit((Object)(object)MenuManager.instance.currentMenuPage) && Input.GetKeyDown(WinkConfig.WinkKey.Value)) { WinkStyle style = ((WinkConfig.Style.Value == "Seductive") ? WinkStyle.Seductive : WinkStyle.Normal); WinkAnim.Start(__instance, style); PlayerExpressionsUI instance = PlayerExpressionsUI.instance; if ((Object)(object)instance != (Object)null) { instance.ShrinkReset(); if ((Object)(object)instance.playerExpression != (Object)null) { WinkAnim.Start(instance.playerExpression, style); } } if (!__instance.onlyVisualRepresentation) { WinkNet.Send(__instance.playerAvatar, style); } } WinkAnim.Tick(__instance); if (!WinkAnim.TryGet(__instance, out var amount, out var style2)) { return; } expressions[0].timer = Mathf.Max(expressions[0].timer, 0.1f); float num = 0f; for (int i = 1; i < expressions.Count; i++) { if (i != 4) { num += expressions[i].weight; } } if (num < 5f) { expressions[0].weight = 100f; } if ((Object)(object)playerVisuals != (Object)null && style2 == WinkStyle.Seductive) { playerVisuals.HeadTiltOverride(WinkConfig.HeadTilt.Value * amount); } } } [HarmonyPatch(typeof(PlayerExpression), "BlendEyeSettings")] internal static class WinkBlendPatch { [HarmonyPostfix] public static void Postfix(PlayerExpression __instance, bool isLeft, EyeSettings __result) { if (!WinkAnim.TryGet(__instance, out var amount, out var style) || amount <= 0f) { return; } EyeSettings closed = WinkState.Closed; if (closed == null || __result == null) { return; } List expressions = __instance.expressions; int num = 4; if (expressions == null || num >= expressions.Count) { return; } float num2 = 0f; for (int i = 0; i < expressions.Count; i++) { num2 += expressions[i].weight; } float num3 = expressions[num]?.weight ?? 0f; if (num3 > 0.5f && num2 > 0.001f) { float num4 = num2 - num3; EyeSettings val = (isLeft ? expressions[num].leftEye : expressions[num].rightEye); if (num4 > 0.5f && val != null) { __result.upperLidClosedPercent = (__result.upperLidClosedPercent * num2 - val.upperLidClosedPercent * num3) / num4; __result.lowerLidClosedPercent = (__result.lowerLidClosedPercent * num2 - val.lowerLidClosedPercent * num3) / num4; __result.upperLidAngle = (__result.upperLidAngle * num2 - val.upperLidAngle * num3) / num4; __result.lowerLidAngle = (__result.lowerLidAngle * num2 - val.lowerLidAngle * num3) / num4; __result.pupilSize = (__result.pupilSize * num2 - val.pupilSize * num3) / num4; } } bool flag = isLeft == WinkConfig.WinkLeftEye.Value; bool flag2 = style == WinkStyle.Seductive; float num5 = (flag ? amount : (flag2 ? (amount * WinkConfig.SultryLid.Value) : 0f)); float num6 = (flag ? amount : 0f); __result.upperLidClosedPercent = Mathf.Lerp(__result.upperLidClosedPercent, closed.upperLidClosedPercent, num5); __result.lowerLidClosedPercent = Mathf.Lerp(__result.lowerLidClosedPercent, closed.lowerLidClosedPercent, num5); __result.upperLidAngle = Mathf.Lerp(__result.upperLidAngle, closed.upperLidAngle, num6); __result.lowerLidAngle = Mathf.Lerp(__result.lowerLidAngle, closed.lowerLidAngle, num6); __result.pupilSize = Mathf.Lerp(__result.pupilSize, closed.pupilSize, num6); } } [HarmonyPatch(typeof(PunManager), "Awake")] internal static class PunManagerWinkPatch { [HarmonyPostfix] public static void Postfix(PunManager __instance) { if ((Object)(object)((Component)__instance).GetComponent() == (Object)null) { ((Component)__instance).gameObject.AddComponent(); } } } [BepInPlugin("Vippy.Wink", "Wink", "1.0.0")] public class WinkPlugin : BaseUnityPlugin { internal static ManualLogSource Log { get; private set; } private void Awake() { //IL_003e: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; ((Component)this).gameObject.transform.parent = null; ((Object)((Component)this).gameObject).hideFlags = (HideFlags)61; WinkConfig.Init(((BaseUnityPlugin)this).Config); new Harmony("Vippy.Wink").PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Wink v1.0.0 loaded"); } } internal class WinkNet : MonoBehaviour { private const float BlinkSeconds = 0.3f; private static float _blinkStopAt; public static void Send(PlayerAvatar avatar, WinkStyle style) { if (PhotonNetwork.InRoom && PhotonNetwork.CurrentRoom.PlayerCount > 1) { PunManager.instance.photonView.RPC("WinkRPC", (RpcTarget)1, new object[2] { SemiFunc.PhotonViewIDPlayerAvatarLocal(), (int)style }); if (WinkConfig.BlinkForOthers.Value) { avatar.PlayerExpressionSet(4, 100f); _blinkStopAt = Time.time + 0.3f; } } } [PunRPC] public void WinkRPC(int _avatarViewID, int _style, PhotonMessageInfo _info = default(PhotonMessageInfo)) { //IL_0026: 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) PlayerAvatar val = SemiFunc.PlayerAvatarGetFromPhotonID(_avatarViewID); if (!((Object)(object)val == (Object)null) && !((Object)(object)val.playerExpression == (Object)null) && _info.Sender != null && !((Object)(object)val.photonView == (Object)null) && val.photonView.Owner == _info.Sender) { WinkAnim.Start(val.playerExpression, (_style == 1) ? WinkStyle.Seductive : WinkStyle.Normal); } } private void Update() { if (_blinkStopAt > 0f && Time.time >= _blinkStopAt) { _blinkStopAt = 0f; if ((Object)(object)PlayerAvatar.instance != (Object)null) { PlayerAvatar.instance.PlayerExpressionStop(4); } } } } internal static class WinkConfig { public const int BlinkSlot = 4; public const string StyleNormal = "Normal"; public const string StyleSeductive = "Seductive"; public static ConfigEntry WinkKey; public static ConfigEntry Style; public static ConfigEntry BlinkForOthers; public static ConfigEntry WinkLeftEye; public static ConfigEntry NormalDuration; public static ConfigEntry SeductiveDuration; public static ConfigEntry EyelidSpeed; public static ConfigEntry SultryLid; public static ConfigEntry HeadTilt; public static void Init(ConfigFile config) { //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Expected O, but got Unknown //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Expected O, but got Unknown //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Expected O, but got Unknown //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Expected O, but got Unknown //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Expected O, but got Unknown //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Expected O, but got Unknown WinkKey = config.Bind("Wink", "Wink key", (KeyCode)52, "Wink. Pick which wink it does with the 'Wink style' setting. The inventory keys (1-3) and the six expression keys (5-0) stay vanilla."); Style = config.Bind("Wink", "Wink style", "Normal", new ConfigDescription("Normal is a quick close-and-reopen. Seductive is slower - the other eye goes half-lidded and the head tilts.", (AcceptableValueBase)(object)new AcceptableValueList(new string[2] { "Normal", "Seductive" }), Array.Empty())); BlinkForOthers = config.Bind("Wink", "Blink for unmodded players", true, "Also flash the vanilla closed-eyes face for a split second so players WITHOUT the mod see a quick blink instead of nothing. Players with the mod always see the real one-eyed wink."); WinkLeftEye = config.Bind("Wink", "Wink the left eye", false, "Close the LEFT eye instead of the right."); NormalDuration = config.Bind("Wink", "Normal wink duration", 0.35f, new ConfigDescription("Seconds for the normal wink's close-and-reopen.", (AcceptableValueBase)(object)new AcceptableValueRange(0.15f, 1f), Array.Empty())); SeductiveDuration = config.Bind("Wink", "Seductive wink duration", 0.7f, new ConfigDescription("Seconds for the seductive wink's close-and-reopen. Higher = slower, more deliberate.", (AcceptableValueBase)(object)new AcceptableValueRange(0.2f, 2f), Array.Empty())); EyelidSpeed = config.Bind("Wink", "Eyelid speed", 18f, new ConfigDescription("Eyelid spring smoothing (vanilla 20). Lower is softer.", (AcceptableValueBase)(object)new AcceptableValueRange(8f, 60f), Array.Empty())); SultryLid = config.Bind("Wink", "Sultry lid", 0.4f, new ConfigDescription("Seductive wink only: how far the OTHER eye half-closes (bedroom eyes). 0 = wide open.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 0.85f), Array.Empty())); HeadTilt = config.Bind("Wink", "Head tilt", 10f, new ConfigDescription("Seductive wink only: head tilt in degrees (sign flips direction). 0 = none.", (AcceptableValueBase)(object)new AcceptableValueRange(-25f, 25f), Array.Empty())); } } }