Decompiled source of FriendlyFirelessCompany v0.2.1

BepInEx/plugins/FriendlyFirelessCompany.dll

Decompiled a year ago
using 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";
	}
}