Please disclose if your mod was created primarily 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 FriendlyFirelessCompany v0.2.1
BepInEx/plugins/FriendlyFirelessCompany.dll
Decompiled 2 years 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 GameNetcodeStuff; using HarmonyLib; using LC_API.ServerAPI; using Microsoft.CodeAnalysis; using Unity.Netcode; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("FriendlyFirelessCompany")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("You could have alternatively not hit your allies, but here we are.")] [assembly: AssemblyFileVersion("0.1.0.0")] [assembly: AssemblyInformationalVersion("0.1.0")] [assembly: AssemblyProduct("FriendlyFirelessCompany")] [assembly: AssemblyTitle("FriendlyFirelessCompany")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.1.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 FriendlyFirelessCompany { [BepInPlugin("rogerfk.FriendlyFirelessCompany", "Friendly Fireless Company", "1.0.0")] public class Plugin : BaseUnityPlugin { public static string guid = "rogerfk.FriendlyFirelessCompany"; public static string pluginName = "Friendly Fireless Company"; public static string version = "1.0.0"; public Harmony _harmony; public ConfigEntry<float> damageScaleConfig; private bool heardItAlready; public static Plugin instance = null; public HashSet<PlayerControllerB> ignorePlayers = new HashSet<PlayerControllerB>(); private void Awake() { //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Expected O, but got Unknown //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Expected O, but got Unknown ((BaseUnityPlugin)this).Logger.LogInfo((object)("Plugin " + guid + " is loading...")); if ((Object)(object)instance != (Object)null) { if (!heardItAlready) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Unsure what is going on, seemingly " + guid + " got reloaded somehow? Someone called 'Awake()' again?" + Environment.NewLine + "--> Since RogerFK is a smartass, he's unpatching all Harmony patches, just in case. Last time his smart ass heard of unpatching, it didn't really work all that well." + Environment.NewLine + "--> But since his smartest ass of all believes Andreas Pardeike or whoever contributed to Harmony is smarter than him, he believesthey probably fixed it already, right? It's been two years." + Environment.NewLine + "--> If something breaks, tell his smart ass on Discord this shit is broken and to not unpatch previous patches. Probably doesn't even make a difference now that I'm thinking, tbh. t. RogerFK")); } heardItAlready = true; instance._harmony.UnpatchSelf(); } instance = this; _harmony = new Harmony(pluginName); Type type = AccessTools.TypeByName("LC_API.CheatDatabase"); ((BaseUnityPlugin)this).Logger.LogInfo((object)type.FullName); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Methodis: " + string.Join(", ", (IEnumerable<MethodInfo>)type.GetMethods(BindingFlags.Static | BindingFlags.NonPublic)))); _harmony.Patch((MethodBase)type.GetMethod("OtherPlayerCheatDetector", BindingFlags.Static | BindingFlags.Public), (HarmonyMethod)null, new HarmonyMethod(typeof(SyncFFCValues), "SyncWithLCAPIPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); _harmony.PatchAll(); instance = this; damageScaleConfig = ((BaseUnityPlugin)this).Config.Bind<float>("Values", "DamageScale", 0f, "Multiplies the damage by this value. 0 means no damage, 0.5 half damage, 1 full damage, 2 double damage, etc."); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Plugin " + guid + " (" + pluginName + " v" + version + ") loaded!")); ((BaseUnityPlugin)this).Logger.LogInfo((object)$"Configs: Damage Scale: {damageScaleConfig.Value}"); Networking.GetFloat = (Action<float, string>)Delegate.Combine(Networking.GetFloat, new Action<float, string>(SyncFFCValues.SyncedDelegate)); } public void LogInfo(string message) { ((BaseUnityPlugin)this).Logger.LogInfo((object)message); } } [HarmonyPatch(typeof(NetworkManager), "Shutdown")] public class SyncFFCValues { public static bool useServerFF = true; public static float serverFFValue = 1f; public static void SyncWithLCAPIPostfix() { if (useServerFF) { Plugin.instance.LogInfo("Using own config for FF from now on"); } useServerFF = false; Networking.Broadcast(Plugin.instance.damageScaleConfig.Value, "FFC_DamageScale_FromHost"); } public static void Postfix() { Plugin.instance.LogInfo("Left the server, resetting server's friendly fire for compatibility."); useServerFF = true; serverFFValue = 1f; } internal static void SyncedDelegate(float value, string signature) { if (signature == "FFC_DamageScale_FromHost") { useServerFF = true; serverFFValue = value; Plugin.instance.LogInfo($"Using received config for FF from now on: {serverFFValue}"); } } } [HarmonyPatch(typeof(PlayerControllerB), "DamagePlayerFromOtherClientServerRpc")] internal class DamageOtherPlayerPatch { private static void Prefix(PlayerControllerB __instance, ref int damageAmount, Vector3 hitDirection, int playerWhoHit) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) Plugin.instance.LogInfo($"[DamageOtherPlayer] Instance: {__instance} | damageAmount: {damageAmount} | hitDirection: {hitDirection} | playerWhoHit: {playerWhoHit}"); if (Plugin.instance.ignorePlayers.Contains(__instance)) { Plugin.instance.LogInfo($"[FriendlyFirelessCompany] Applying normal FF damage to {__instance}"); } else { damageAmount = Mathf.RoundToInt((float)damageAmount * Plugin.instance.damageScaleConfig.Value); } } } [HarmonyPatch(typeof(ShotgunItem), "ShootGunServerRpc")] internal class ShotgunServerPatch { private static void Prefix(ShotgunItem __instance, ref Vector3 shotgunPosition) { if ((Object)(object)((GrabbableObject)__instance).playerHeldBy != (Object)null) { Plugin.instance.LogInfo("[ShootGunServerRpc] Held by a player"); DamagePlayerPatch.timeToNotDamage = Time.time + 1f; DamagePlayerServerPatch.timeToNotDamage = Time.time + 1f; DamagePlayerPatch.timeToNotDamage = Time.time + 1f; } else { Plugin.instance.LogInfo("[ShootGunServerRpc] Not held by a player, damaging"); } } } [HarmonyPatch(typeof(ShotgunItem), "ShootGunClientRpc")] internal class ShotgunClientPatch { private static void Prefix(ShotgunItem __instance, ref Vector3 shotgunPosition) { if ((Object)(object)((GrabbableObject)__instance).playerHeldBy != (Object)null) { Plugin.instance.LogInfo("[ShootGunClientRpc] Held by a player"); DamagePlayerPatch.timeToNotDamage = Time.time + 1f; DamagePlayerServerPatch.timeToNotDamage = Time.time + 1f; DamagePlayerClientPatch.timeToNotDamage = Time.time + 1f; } else { Plugin.instance.LogInfo("[ShootGunClientRpc] Not held by a player, damaging"); } } } [HarmonyPatch(typeof(PlayerControllerB), "DamagePlayerServerRpc")] internal class DamagePlayerServerPatch { public static float timeToNotDamage; private static void Prefix(PlayerControllerB __instance, ref int damageNumber, ref int newHealthAmount) { Plugin.instance.LogInfo($"[DamagePlayerServer] Instance: {__instance} | damageNumber: {damageNumber} | newHealthAmount: {newHealthAmount}"); if (Plugin.instance.ignorePlayers.Contains(__instance)) { Plugin.instance.LogInfo($"[DamagePlayerServer] Applying normal FF damage to {__instance}"); return; } Plugin.instance.LogInfo($"[DamagePlayerServer] Changing damage values? {timeToNotDamage > Time.time}"); if (timeToNotDamage > Time.time) { newHealthAmount += damageNumber; damageNumber = Mathf.RoundToInt((float)damageNumber * Plugin.instance.damageScaleConfig.Value); newHealthAmount -= damageNumber; } } } [HarmonyPatch(typeof(PlayerControllerB), "DamagePlayerClientRpc")] internal class DamagePlayerClientPatch { public static float timeToNotDamage; private static void Prefix(PlayerControllerB __instance, ref int damageNumber, ref int newHealthAmount) { Plugin.instance.LogInfo($"[DamagePlayerClient] Instance: {__instance} | damageNumber: {damageNumber} | newHealthAmount: {newHealthAmount}"); if (Plugin.instance.ignorePlayers.Contains(__instance)) { Plugin.instance.LogInfo($"[DamagePlayerClient] Applying normal FF damage to {__instance}"); return; } Plugin.instance.LogInfo($"[DamagePlayerClient] Changing damage values? {timeToNotDamage > Time.time}"); if (timeToNotDamage > Time.time) { newHealthAmount += damageNumber; damageNumber = Mathf.RoundToInt((float)damageNumber * Plugin.instance.damageScaleConfig.Value); newHealthAmount -= damageNumber; } } } [HarmonyPatch(typeof(PlayerControllerB), "DamagePlayer")] internal class DamagePlayerPatch { public static float timeToNotDamage; public static bool forceAllowFF; private static void Prefix(PlayerControllerB __instance, ref int damageNumber, CauseOfDeath causeOfDeath) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Invalid comparison between Unknown and I4 if (((NetworkBehaviour)__instance).IsOwner && !__instance.isPlayerDead && __instance.AllowPlayerDeath() && !forceAllowFF && (int)causeOfDeath == 7 && timeToNotDamage > Time.time) { Plugin.instance.LogInfo($"Multiplying the damage by the value: {(SyncFFCValues.useServerFF ? SyncFFCValues.serverFFValue : Plugin.instance.damageScaleConfig.Value)}"); damageNumber = Mathf.RoundToInt((float)damageNumber * ((!SyncFFCValues.useServerFF) ? SyncFFCValues.serverFFValue : Plugin.instance.damageScaleConfig.Value)); } } } [HarmonyPatch(typeof(HauntedMaskItem), "AttachToPlayerOnLocalClient")] internal class SCP035ClientAttachPatch { private static void Prefix(HauntedMaskItem __instance) { DamagePlayerPatch.forceAllowFF = true; } } [HarmonyPatch(typeof(HauntedMaskItem), "FinishAttaching")] internal class SCP035SpawnClientPatch { private static void Prefix(HauntedMaskItem __instance) { DamagePlayerPatch.forceAllowFF = false; } } [HarmonyPatch(typeof(HauntedMaskItem), "AttachServerRpc")] internal class SCP035ServerAttachPatch { private static void Prefix(HauntedMaskItem __instance) { Plugin.instance.ignorePlayers.Add(((GrabbableObject)__instance).playerHeldBy); } } [HarmonyPatch(typeof(HauntedMaskItem), "CreateMimicServerRpc")] internal class SCP035SpawnPatch { private static void Prefix(HauntedMaskItem __instance) { Plugin.instance.ignorePlayers.Remove(((GrabbableObject)__instance).playerHeldBy); } } public static class PluginInfo { public const string PLUGIN_GUID = "FriendlyFirelessCompany"; public const string PLUGIN_NAME = "FriendlyFirelessCompany"; public const string PLUGIN_VERSION = "0.1.0"; } }