using System; using System.Collections; 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: AssemblyCompany("FeedingFrenzy")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+792ec908dc89689b0fce079d4b9e41033c968a90")] [assembly: AssemblyProduct("FeedingFrenzy")] [assembly: AssemblyTitle("FeedingFrenzy")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.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 FeedingFrenzy { [HarmonyPatch(typeof(Character), "AddExtraStamina")] internal static class AddExtraStamina_Multiplier_Patch { private static Dictionary feedTimes = new Dictionary(); private const float FED_WINDOW = 3f; public static void MarkAsFed(int characterID) { feedTimes[characterID] = Time.time; if (FeedingFrenzyPlugin.debugMode.Value) { FeedingFrenzyPlugin.Log.LogInfo((object)$"[FeedingFrenzy] Marked character {characterID} as fed"); } } [HarmonyPrefix] private static void Prefix(Character __instance, ref float add) { if (!(add <= 0f)) { int ownerActorNr = ((MonoBehaviourPun)__instance).photonView.OwnerActorNr; if (feedTimes.TryGetValue(ownerActorNr, out var value) && Time.time - value <= 3f) { float num = add; add = num * FeedingFrenzyPlugin.extraStaminaMultiplier.Value; FeedingFrenzyPlugin.Log.LogInfo((object)("[FeedingFrenzy] " + __instance.characterName + " fed! " + $"Extra stamina multiplier: {num:F2} → {add:F2}")); feedTimes.Remove(ownerActorNr); } } } } [BepInPlugin("jill920.FeedingFrenzy", "Feeding Frenzy", "1.1.0")] public class FeedingFrenzyPlugin : BaseUnityPlugin { public const string MOD_GUID = "jill920.FeedingFrenzy"; public const string MOD_NAME = "Feeding Frenzy"; public const string MOD_VERSION = "1.1.0"; public static ConfigEntry extraStaminaMultiplier; public static ConfigEntry flatExtraStaminaBonus; public static ConfigEntry debugMode; public static FeedingFrenzyPlugin Instance { get; private set; } public static ManualLogSource Log { get; private set; } private void Awake() { Instance = this; Log = ((BaseUnityPlugin)this).Logger; extraStaminaMultiplier = ((BaseUnityPlugin)this).Config.Bind("Multiplier", "ExtraStaminaMultiplier", 1.5f, "Multiplier applied to extra stamina from items when feeding another player.\nExample: 1.5 = 50% more stamina, 2.0 = 100% more stamina"); flatExtraStaminaBonus = ((BaseUnityPlugin)this).Config.Bind("FlatBonus", "FlatExtraStaminaBonus", 0.05f, "Flat bonus stamina given to the receiver when fed by another player.\nThis is applied AFTER the feeding animation completes.\nSet to 0 to disable."); debugMode = ((BaseUnityPlugin)this).Config.Bind("Debug", "EnableDebugLogs", false, "Enable debug logging"); Harmony val = Harmony.CreateAndPatchAll(typeof(GameUtils_StartFeed_Patch), "jill920.FeedingFrenzy"); val.PatchAll(typeof(AddExtraStamina_Multiplier_Patch)); val.PatchAll(typeof(Item_SendFeedDataRPC_Patch)); Log.LogInfo((object)"[Feeding Frenzy 1.1.0] Loaded successfully!"); Log.LogInfo((object)$" Multiplier: {extraStaminaMultiplier.Value}x"); Log.LogInfo((object)$" Flat Bonus: +{flatExtraStaminaBonus.Value} stamina"); } } [HarmonyPatch(typeof(GameUtils), "StartFeed")] internal static class GameUtils_StartFeed_Patch { [HarmonyPrefix] private static void Prefix(int giverID, int receiverID, ushort itemID, float totalItemTime) { Character val = default(Character); Character val2 = default(Character); if (Character.GetCharacterWithPhotonID(giverID, ref val) && Character.GetCharacterWithPhotonID(receiverID, ref val2)) { AddExtraStamina_Multiplier_Patch.MarkAsFed(((MonoBehaviourPun)val2).photonView.OwnerActorNr); FeedingFrenzyPlugin.Log.LogInfo((object)$"[FeedingFrenzy] Native feed detected: {val.characterName} -> {val2.characterName} (Item ID: {itemID})"); } } } [HarmonyPatch(typeof(Item), "SendFeedDataRPC")] internal static class Item_SendFeedDataRPC_Patch { [CompilerGenerated] private sealed class d__1 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public Character receiver; public float delay; public int itemID; private float 5__1; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__1(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds(delay); <>1__state = 1; return true; case 1: <>1__state = -1; <>2__current = null; <>1__state = 2; return true; case 2: <>1__state = -1; 5__1 = FeedingFrenzyPlugin.flatExtraStaminaBonus.Value; if (5__1 > 0f) { receiver.AddExtraStamina(5__1); if (FeedingFrenzyPlugin.debugMode.Value) { FeedingFrenzyPlugin.Log.LogInfo((object)("[FeedingFrenzy] Flat bonus applied to " + receiver.characterName + " " + $"(Item ID: {itemID}) after {delay:F2}s: +{5__1:F2} stamina")); } } return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [HarmonyPostfix] private static void Postfix(Item __instance, int giverID, int recieverID, int itemID, float totalUsingTime) { Character val = default(Character); if (Character.GetCharacterWithPhotonID(recieverID, ref val) && val.IsLocal) { ((MonoBehaviour)FeedingFrenzyPlugin.Instance).StartCoroutine(ApplyFlatBonusAfterDelay(val, totalUsingTime, itemID)); } } [IteratorStateMachine(typeof(d__1))] private static IEnumerator ApplyFlatBonusAfterDelay(Character receiver, float delay, int itemID) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__1(0) { receiver = receiver, delay = delay, itemID = itemID }; } } }