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";
}
}