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 SharingIsCaring v1.1.0
SharingIsCaring.dll
Decompiled 12 months agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using Photon.Realtime; using SharingIsCaring.Config; using SharingIsCaring.Logic; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("SharingIsCaring")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("FluxTeam")] [assembly: AssemblyProduct("SharingIsCaring")] [assembly: AssemblyCopyright("Copyright © FluxTeam 2025")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("b791a899-85ee-448a-9051-42da58bf930d")] [assembly: AssemblyFileVersion("1.1.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("1.1.0.0")] [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 SharingIsCaring { [BepInPlugin("FluxTeam.SharingIsCaring", "Sharing is Caring", "1.1.0")] public class SharingIsCaringPlugin : BaseUnityPlugin { public const string PluginGUID = "FluxTeam.SharingIsCaring"; public const string PluginName = "Sharing is Caring"; public const string PluginVersion = "1.1.0"; internal static ManualLogSource Log; private void Awake() { //IL_007e: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; ((BaseUnityPlugin)this).Logger.LogInfo((object)"Sharing is Caring v1.1.0 loading..."); ModConfig.Init(((BaseUnityPlugin)this).Config); ((BaseUnityPlugin)this).Logger.LogInfo((object)$"Upgrade sync interval: {ModConfig.UpgradeSyncInterval.Value} second(s)"); ((BaseUnityPlugin)this).Config.ConfigReloaded += delegate { Log.LogInfo((object)"Configuration reloaded."); UpgradeSync.ResetTracking(); }; UpgradeSync.Initialize(); new Harmony("FluxTeam.SharingIsCaring").PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Sharing is Caring loaded successfully."); } } public static class MyPluginInfo { public const string PLUGIN_GUID = "SharingIsCaring"; public const string PLUGIN_NAME = ""; public const string PLUGIN_VERSION = "1.0.0.0"; } } namespace SharingIsCaring.Patches { [HarmonyPatch(typeof(ItemHealthPack), "UsedRPC")] internal static class Patch_ItemHealthPack_UsedRPC { private static void Postfix(ItemHealthPack __instance) { HealthSync.OnHealthPackUsed(__instance); } } [HarmonyPatch(typeof(RunManager), "ChangeLevel")] internal static class Patch_RunManager_ChangeLevel { private static void Prefix() { if (SemiFunc.MenuLevel() || SemiFunc.RunIsLobbyMenu() || SemiFunc.RunIsShop() || SemiFunc.RunIsArena()) { if (ModConfig.DebugLogging.Value) { SharingIsCaringPlugin.Log.LogDebug((object)"Skipped upgrade sync on level change (arena/shop/menu)."); } } else { UpgradeSync.ForceSync(); } } } [HarmonyPatch(typeof(StatsManager), "ResetAllStats")] internal static class Patch_StatsManager_ResetAllStats { private static void Postfix() { UpgradeSync.ResetTracking(); } } } namespace SharingIsCaring.Logic { public static class HealthSync { public static void OnHealthPackUsed(ItemHealthPack pack) { if (!PhotonNetwork.IsMasterClient || !ModConfig.EnableHealthSync.Value) { return; } FieldInfo fieldInfo = AccessTools.Field(typeof(ItemHealthPack), "itemToggle"); FieldInfo fieldInfo2 = AccessTools.Field(typeof(ItemToggle), "playerTogglePhotonID"); object value = fieldInfo.GetValue(pack); int userViewId = (int)fieldInfo2.GetValue(value); int num = 0; foreach (PlayerAvatar item in SemiFunc.PlayerGetAll()) { if (!((Object)(object)item == (Object)null)) { PhotonView photonView = item.photonView; if (!((Object)(object)photonView == (Object)null) && photonView.ViewID != userViewId) { item.playerHealth.HealOther(pack.healAmount, true); num++; } } } SharingIsCaringPlugin.Log.LogInfo((object)$"Shared health pack used (host-side) → healed {num} player(s) for {pack.healAmount} HP."); if (!ModConfig.DebugLogging.Value) { return; } string text = string.Join(", ", SemiFunc.PlayerGetAll().FindAll(delegate(PlayerAvatar p) { if (p == null) { return true; } PhotonView photonView3 = p.photonView; return ((photonView3 != null) ? new int?(photonView3.ViewID) : null) != userViewId; }).ConvertAll(delegate(PlayerAvatar p) { object obj; if (p == null) { obj = null; } else { PhotonView photonView2 = p.photonView; if (photonView2 == null) { obj = null; } else { Player owner = photonView2.Owner; obj = ((owner != null) ? owner.NickName : null); } } if (obj == null) { obj = "Unknown"; } return (string)obj; })); SharingIsCaringPlugin.Log.LogDebug((object)("Healed players: " + text)); } } public static class UpgradeSync { private class UpgradeSyncRunner : MonoBehaviour { private void Update() { if (PhotonNetwork.IsMasterClient && ModConfig.EnableUpgradeSync.Value) { float num = Mathf.Clamp(ModConfig.UpgradeSyncInterval.Value, 1f, 60f); if (Time.time - lastSyncTime > num) { SyncUpgrades(); lastSyncTime = Time.time; } } } } private static Dictionary<string, int> previousMaxValues = new Dictionary<string, int>(); private static float lastSyncTime = 0f; public static void Initialize() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) previousMaxValues.Clear(); lastSyncTime = 0f; new GameObject("UpgradeSyncRunner").AddComponent<UpgradeSyncRunner>(); } public static void ForceSync() { SyncUpgrades(forced: true); } public static void ResetTracking() { previousMaxValues.Clear(); } private static void SyncUpgrades(bool forced = false) { if (!PhotonNetwork.IsMasterClient || !ModConfig.EnableUpgradeSync.Value || !LevelGenerator.Instance.Generated || SemiFunc.MenuLevel()) { return; } if (SemiFunc.RunIsShop() || SemiFunc.RunIsArena()) { if (ModConfig.DebugLogging.Value) { SharingIsCaringPlugin.Log.LogDebug((object)"Skipping upgrade sync: currently in Shop or Arena."); } return; } StatsManager instance = StatsManager.instance; Dictionary<string, Dictionary<string, int>> dictionaryOfDictionaries = instance.dictionaryOfDictionaries; List<string> list = dictionaryOfDictionaries.Keys.Where((string key) => key.StartsWith("playerUpgrade") && ShouldSyncKey(key)).ToList(); Dictionary<string, int> dictionary = new Dictionary<string, int>(); foreach (string item in list) { if (dictionaryOfDictionaries.TryGetValue(item, out var value) && value.Count > 0) { dictionary[item] = value.Values.Max(); } } if (!forced && !dictionary.Any((KeyValuePair<string, int> kv) => !previousMaxValues.TryGetValue(kv.Key, out var value2) || value2 != kv.Value)) { return; } if (ModConfig.DebugLogging.Value) { SharingIsCaringPlugin.Log.LogDebug((object)"Upgrades changed or forced — syncing..."); } foreach (KeyValuePair<string, int> item2 in dictionary) { instance.DictionaryFill(item2.Key, item2.Value); if (ModConfig.DebugLogging.Value) { SharingIsCaringPlugin.Log.LogDebug((object)$"→ Synced {item2.Key} = {item2.Value}"); } } previousMaxValues = new Dictionary<string, int>(dictionary); SemiFunc.StatSyncAll(); SharingIsCaringPlugin.Log.LogInfo((object)"Upgrades synced for all players."); } private static bool ShouldSyncKey(string key) { string text = key.Replace("playerUpgrade", "").ToLowerInvariant(); if (text.Contains("health") || text.Contains("stamina")) { return ModConfig.SyncHealthUpgrades.Value; } if (text.Contains("jump") || text.Contains("launch") || text.Contains("speed")) { return ModConfig.SyncMobilityUpgrades.Value; } if (text.Contains("strength") || text.Contains("range") || text.Contains("throw")) { return ModConfig.SyncGrabUpgrades.Value; } return ModConfig.SyncModdedUpgrades.Value; } } } namespace SharingIsCaring.Config { public static class ModConfig { public static ConfigEntry<bool> EnableUpgradeSync; public static ConfigEntry<bool> EnableHealthSync; public static ConfigEntry<bool> DebugLogging; public static ConfigEntry<bool> SyncHealthUpgrades; public static ConfigEntry<bool> SyncMobilityUpgrades; public static ConfigEntry<bool> SyncGrabUpgrades; public static ConfigEntry<bool> SyncModdedUpgrades; public static ConfigEntry<float> UpgradeSyncInterval; private const float MinSyncInterval = 1f; private const float MaxSyncInterval = 60f; public static void Init(ConfigFile config) { EnableUpgradeSync = config.Bind<bool>("General", "EnableUpgradeSync", true, "Enable syncing of upgrades across all players."); EnableHealthSync = config.Bind<bool>("General", "EnableHealthSync", true, "Enable team healing when using health packs."); DebugLogging = config.Bind<bool>("General", "DebugLogging", false, "If true, enables detailed logging for troubleshooting."); SyncHealthUpgrades = config.Bind<bool>("Upgrade Sync", "SyncHealth", true, "Sync health-related upgrades."); SyncMobilityUpgrades = config.Bind<bool>("Upgrade Sync", "SyncMobility", true, "Sync movement-related upgrades."); SyncGrabUpgrades = config.Bind<bool>("Upgrade Sync", "SyncGrab", true, "Sync grabbing-related upgrades."); SyncModdedUpgrades = config.Bind<bool>("Upgrade Sync", "SyncModded", true, "Sync unrecognized or modded upgrades."); UpgradeSyncInterval = config.Bind<float>("Upgrade Sync", "SyncInterval", 5f, $"Time in seconds between automatic upgrade sync checks. Allowed range: {1f}-{60f} seconds."); UpgradeSyncInterval.SettingChanged += delegate { ClampSyncInterval("runtime"); }; ClampSyncInterval("startup"); } private static void ClampSyncInterval(string context) { if (UpgradeSyncInterval.Value < 1f) { SharingIsCaringPlugin.Log.LogWarning((object)$"SyncInterval was below {1f}s ({UpgradeSyncInterval.Value}) during {context} — clamping to {1f}s."); UpgradeSyncInterval.Value = 1f; } else if (UpgradeSyncInterval.Value > 60f) { SharingIsCaringPlugin.Log.LogWarning((object)$"SyncInterval exceeded {60f}s ({UpgradeSyncInterval.Value}) during {context} — clamping to {60f}s."); UpgradeSyncInterval.Value = 60f; } } } }