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.0
Wink.dll
Decompiled 9 hours 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.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<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 float Timer; public float Dur; public WinkStyle Style; public float Amount; } 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) { 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<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_0094: 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; 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<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 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<WinkNet>() == (Object)null) { ((Component)__instance).gameObject.AddComponent<WinkNet>(); } } } [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<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 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<KeyCode>("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<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>())); } } }