Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Wink v1.0.1
Wink.dll
Decompiled 4 days agousing 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.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: AssemblyCompany("Vippy")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.1.0")] [assembly: AssemblyInformationalVersion("1.0.1+f87475f264960c77a77b1f34d93f988a339b4b75")] [assembly: AssemblyProduct("Wink")] [assembly: AssemblyTitle("Wink")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.1.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.1"; } internal static class WinkState { internal static EyeSettings? Closed; internal static void EnsureClosed(List<ExpressionSettings> 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 bool WaitUp; public float LeadIn; public float Timer; public float Dur; public float Hold; public WinkStyle Style; public float Amount; } private const float PreviewUpThreshold = 0.95f; private static readonly Dictionary<PlayerExpression, Anim> _anims = new Dictionary<PlayerExpression, Anim>(); private static readonly List<PlayerExpression> _dead = new List<PlayerExpression>(); public static void Start(PlayerExpression pe, WinkStyle style, float leadIn = 0f, float hold = 0f, bool waitForPreviewUp = false) { 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 { WaitUp = waitForPreviewUp, LeadIn = Mathf.Max(0f, leadIn), Timer = num, Dur = num, Hold = Mathf.Max(0f, hold), Style = style }; } public static void Tick(PlayerExpression pe) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) if (!_anims.TryGetValue(pe, out Anim value)) { return; } if (value.WaitUp) { PlayerExpressionsUI instance = PlayerExpressionsUI.instance; if ((Object)(object)instance != (Object)null && (Object)(object)instance.rectShrink != (Object)null && ((Transform)instance.rectShrink).localScale.x < 0.95f) { value.Amount = 0f; return; } value.WaitUp = false; } if (value.LeadIn > 0f) { value.LeadIn -= Time.deltaTime; value.Amount = 0f; return; } if (value.Timer > 0f) { value.Timer -= Time.deltaTime; if (value.Timer > 0f) { value.Amount = Mathf.Sin(MathF.PI * (1f - value.Timer / value.Dur)); return; } value.Amount = 0f; } if (value.Hold > 0f) { value.Hold -= Time.deltaTime; value.Amount = 0f; } else { _anims.Remove(pe); } } 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_0038: Unknown result type (might be due to invalid IL or missing references) List<ExpressionSettings> 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_0085: Unknown result type (might be due to invalid IL or missing references) List<ExpressionSettings> expressions = __instance.expressions; if (expressions == null || expressions.Count == 0) { return; } PlayerAvatarVisuals playerVisuals = __instance.playerVisuals; bool flag = __instance.isLocal && (Object)(object)playerVisuals != (Object)null && !playerVisuals.isMenuAvatar && (Object)(object)__instance.playerAvatar != (Object)null && (Object)(object)__instance == (Object)(object)__instance.playerAvatar.playerExpression; if (flag && (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, WinkConfig.PreviewLeadIn.Value, WinkConfig.PreviewHold.Value, waitForPreviewUp: true); } } if (!__instance.onlyVisualRepresentation) { WinkNet.Send(__instance.playerAvatar, style); } } WinkAnim.Tick(__instance); float amount; WinkStyle style2; bool flag2 = WinkAnim.TryGet(__instance, out amount, out style2); bool flag3 = false; PlayerExpressionsUI instance2 = PlayerExpressionsUI.instance; if ((Object)(object)instance2 != (Object)null && (Object)(object)instance2.playerExpression != (Object)null && WinkAnim.TryGet(instance2.playerExpression, out var _, out var _)) { if ((Object)(object)instance2.playerExpression == (Object)(object)__instance || flag) { instance2.ShrinkReset(); } flag3 = flag; } if (!flag2 && !flag3) { 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 (flag2 && (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<ExpressionSettings> 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 num5 = isLeft == WinkConfig.WinkLeftEye.Value; bool flag = style == WinkStyle.Seductive; float num6 = (num5 ? amount : (flag ? (amount * WinkConfig.SultryLid.Value) : 0f)); float num7 = (num5 ? amount : 0f); __result.upperLidClosedPercent = Mathf.Lerp(__result.upperLidClosedPercent, closed.upperLidClosedPercent, num6); __result.lowerLidClosedPercent = Mathf.Lerp(__result.lowerLidClosedPercent, closed.lowerLidClosedPercent, num6); __result.upperLidAngle = Mathf.Lerp(__result.upperLidAngle, closed.upperLidAngle, num7); __result.lowerLidAngle = Mathf.Lerp(__result.lowerLidAngle, closed.lowerLidAngle, num7); __result.pupilSize = Mathf.Lerp(__result.pupilSize, closed.pupilSize, num7); } } [HarmonyPatch(typeof(PunManager), "Awake")] internal static class PunManagerWinkPatch { [HarmonyPostfix] public static void Postfix(PunManager __instance) { if ((Object)(object)((Component)__instance).GetComponent<WinkNet>() == (Object)null) { ((Component)__instance).gameObject.AddComponent<WinkNet>(); } } } [BepInPlugin("Vippy.Wink", "Wink", "1.0.1")] public class WinkPlugin : BaseUnityPlugin { internal static ManualLogSource Log { get; private set; } private void Awake() { //IL_0039: 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.1 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_001f: 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) 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<KeyCode> WinkKey; public static ConfigEntry<string> Style; public static ConfigEntry<bool> BlinkForOthers; public static ConfigEntry<bool> WinkLeftEye; public static ConfigEntry<float> NormalDuration; public static ConfigEntry<float> SeductiveDuration; public static ConfigEntry<float> EyelidSpeed; public static ConfigEntry<float> SultryLid; public static ConfigEntry<float> HeadTilt; public static ConfigEntry<float> PreviewLeadIn; public static ConfigEntry<float> PreviewHold; public static void Init(ConfigFile config) { //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Expected O, but got Unknown //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Expected O, but got Unknown //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Expected O, but got Unknown //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Expected O, but got Unknown //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Expected O, but got Unknown //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Expected O, but got Unknown //IL_01d7: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Expected O, but got Unknown //IL_020f: Unknown result type (might be due to invalid IL or missing references) //IL_0219: Expected O, but got Unknown WinkKey = config.Bind<KeyCode>("Wink", "Wink key", (KeyCode)52, "Key that plays the wink. This is a NEW expression on its own key, nothing the game ships with is changed: the inventory keys (1-3) and the six vanilla expression keys (5-0) stay exactly as they are. Default is Alpha4, which is Unity's name for the 4 key on the number row (not the numpad). Pick which wink it plays with the 'Wink style' setting."); Style = config.Bind<string>("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<string>(new string[2] { "Normal", "Seductive" }), Array.Empty<object>())); BlinkForOthers = config.Bind<bool>("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<bool>("Wink", "Wink the left eye", false, "Close the LEFT eye instead of the right."); NormalDuration = config.Bind<float>("Wink", "Normal wink duration", 0.35f, new ConfigDescription("Seconds for the normal wink's close-and-reopen.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.15f, 1f), Array.Empty<object>())); SeductiveDuration = config.Bind<float>("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<float>(0.2f, 2f), Array.Empty<object>())); EyelidSpeed = config.Bind<float>("Wink", "Eyelid speed", 18f, new ConfigDescription("Eyelid spring smoothing (vanilla 20). Lower is softer.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(8f, 60f), Array.Empty<object>())); SultryLid = config.Bind<float>("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<float>(0f, 0.85f), Array.Empty<object>())); HeadTilt = config.Bind<float>("Wink", "Head tilt", 10f, new ConfigDescription("Seductive wink only: head tilt in degrees (sign flips direction). 0 = none.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-25f, 25f), Array.Empty<object>())); PreviewLeadIn = config.Bind<float>("Wink", "Preview lead-in", 0.5f, new ConfigDescription("Seconds the bottom preview holds your face open AFTER it has fully risen, before the wink plays. The wink already waits for the preview to finish rising; this is the extra beat on top of that. Preview only - the wink others see in-world stays instant.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 3f), Array.Empty<object>())); PreviewHold = config.Bind<float>("Wink", "Preview hold", 0.9f, new ConfigDescription("Seconds the bottom preview lingers after the wink finishes, before it settles back. Preview only - your in-world wink is unaffected.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 3f), Array.Empty<object>())); } } }