using System;
using System.Diagnostics;
using System.IO;
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 CSync.Extensions;
using CSync.Lib;
using CessilCellsCeaChells.CeaChore;
using IL;
using Microsoft.CodeAnalysis;
using Mono.Cecil.Cil;
using MonoMod.Cil;
using MonoMod.RuntimeDetour;
using On;
using PredictableEggs.NetcodePatcher;
using Unity.Netcode;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: RequiresMethod(typeof(StunGrenadeItem), "Awake", typeof(void), new Type[] { })]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("PredictableEggs")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("A mod for Lethal Company")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+1e6e75db2673090a5f440c6cb2b31a57f0051f4f")]
[assembly: AssemblyProduct("PredictableEggs")]
[assembly: AssemblyTitle("PredictableEggs")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
[module: NetcodePatchedAssembly]
internal class <Module>
{
static <Module>()
{
}
}
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 PredictableEggs
{
public static class Assets
{
public static AudioClip EggReadyToExplode { get; private set; }
public static void Load()
{
string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
AssetBundle val = AssetBundle.LoadFromFile(Path.Combine(directoryName, "predictableeggs.bundle"));
EggReadyToExplode = val.LoadAsset<AudioClip>("EggReadyToExplode");
}
}
public class Config : SyncedConfig2<Config>
{
[SyncedEntryField]
public SyncedEntry<float> EggExplodeChance;
[SyncedEntryField]
public SyncedEntry<bool> WarningSound;
[SyncedEntryField]
public SyncedEntry<bool> DontExplodeOnDrop;
[SyncedEntryField]
public SyncedEntry<bool> DetermineOnPickUp;
[SyncedEntryField]
public SyncedEntry<int> EnemyDamage;
public Config(ConfigFile cfg)
: base("moe.sylvi.PredictableEggs")
{
EggExplodeChance = SyncedBindingExtensions.BindSyncedEntry<float>(cfg, "General", "EggExplodeChance", 16f, "Percentage chance for the egg to explode, determined when the egg is selected in the inventory. (Vanilla value is 16%)");
WarningSound = SyncedBindingExtensions.BindSyncedEntry<bool>(cfg, "General", "WarningSound", true, "Plays a unique sound (fizzling) if the egg will explode on its next throw.");
DontExplodeOnDrop = SyncedBindingExtensions.BindSyncedEntry<bool>(cfg, "General", "DontExplodeOnDrop", false, "Prevents eggs from exploding when dropped, as opposed to being thrown.");
DetermineOnPickUp = SyncedBindingExtensions.BindSyncedEntry<bool>(cfg, "General", "DetermineOnPickUp", false, "Decides whether eggs will explode only on pickup, as opposed to any time it's selected.");
EnemyDamage = SyncedBindingExtensions.BindSyncedEntry<int>(cfg, "General", "EnemyDamage", 6, "The amount of damage egg explosions should deal to enemies. (Vanilla value is 6)");
ConfigManager.Register<Config>((SyncedConfig2<Config>)this);
}
}
public static class Patches
{
private delegate void StunGrenadeItem_orig_Awake(StunGrenadeItem self);
[CompilerGenerated]
private static class <>O
{
public static hook_EquipItem <0>__StunGrenadeItem_EquipItem;
public static hook_DiscardItem <1>__StunGrenadeItem_DiscardItem;
public static hook_ItemActivate <2>__StunGrenadeItem_ItemActivate;
public static hook_OnHitGround <3>__StunGrenadeItem_OnHitGround;
public static hook_ExplodeStunGrenade <4>__StunGrenadeItem_ExplodeStunGrenade;
public static Manipulator <5>__Landmine_SpawnExplosion;
public static Func<int, int> <6>__ApplyOverrideLandmineEnemyDamage;
}
public static bool OverrideLandmineEnemyDamage;
public static void Initialize()
{
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_001c: Expected O, but got Unknown
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
//IL_003d: Expected O, but got Unknown
//IL_0053: Unknown result type (might be due to invalid IL or missing references)
//IL_0058: Unknown result type (might be due to invalid IL or missing references)
//IL_005e: Expected O, but got Unknown
//IL_0074: Unknown result type (might be due to invalid IL or missing references)
//IL_0079: Unknown result type (might be due to invalid IL or missing references)
//IL_007f: Expected O, but got Unknown
//IL_0095: Unknown result type (might be due to invalid IL or missing references)
//IL_009a: Unknown result type (might be due to invalid IL or missing references)
//IL_00a0: Expected O, but got Unknown
//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
//IL_00c1: Expected O, but got Unknown
object obj = <>O.<0>__StunGrenadeItem_EquipItem;
if (obj == null)
{
hook_EquipItem val = StunGrenadeItem_EquipItem;
<>O.<0>__StunGrenadeItem_EquipItem = val;
obj = (object)val;
}
StunGrenadeItem.EquipItem += (hook_EquipItem)obj;
object obj2 = <>O.<1>__StunGrenadeItem_DiscardItem;
if (obj2 == null)
{
hook_DiscardItem val2 = StunGrenadeItem_DiscardItem;
<>O.<1>__StunGrenadeItem_DiscardItem = val2;
obj2 = (object)val2;
}
StunGrenadeItem.DiscardItem += (hook_DiscardItem)obj2;
object obj3 = <>O.<2>__StunGrenadeItem_ItemActivate;
if (obj3 == null)
{
hook_ItemActivate val3 = StunGrenadeItem_ItemActivate;
<>O.<2>__StunGrenadeItem_ItemActivate = val3;
obj3 = (object)val3;
}
StunGrenadeItem.ItemActivate += (hook_ItemActivate)obj3;
object obj4 = <>O.<3>__StunGrenadeItem_OnHitGround;
if (obj4 == null)
{
hook_OnHitGround val4 = StunGrenadeItem_OnHitGround;
<>O.<3>__StunGrenadeItem_OnHitGround = val4;
obj4 = (object)val4;
}
StunGrenadeItem.OnHitGround += (hook_OnHitGround)obj4;
object obj5 = <>O.<4>__StunGrenadeItem_ExplodeStunGrenade;
if (obj5 == null)
{
hook_ExplodeStunGrenade val5 = StunGrenadeItem_ExplodeStunGrenade;
<>O.<4>__StunGrenadeItem_ExplodeStunGrenade = val5;
obj5 = (object)val5;
}
StunGrenadeItem.ExplodeStunGrenade += (hook_ExplodeStunGrenade)obj5;
object obj6 = <>O.<5>__Landmine_SpawnExplosion;
if (obj6 == null)
{
Manipulator val6 = Landmine_SpawnExplosion;
<>O.<5>__Landmine_SpawnExplosion = val6;
obj6 = (object)val6;
}
Landmine.SpawnExplosion += (Manipulator)obj6;
new Hook((MethodBase)typeof(StunGrenadeItem).GetMethod("Awake", BindingFlags.Instance | BindingFlags.Public), typeof(Patches).GetMethod("StunGrenadeItem_Awake", BindingFlags.Static | BindingFlags.NonPublic)).Apply();
}
private static void Landmine_SpawnExplosion(ILContext il)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_0008: Expected O, but got Unknown
ILCursor val = new ILCursor(il);
if (!val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1]
{
(Instruction instr) => ILPatternMatchingExt.MatchLdcI4(instr, 6)
}))
{
Plugin.Logger.LogError((object)"Failed IL hook for Landmine.SpawnExplosion @ HitEnemyOnLocalClient for 6 damage");
}
else
{
val.EmitDelegate<Func<int, int>>((Func<int, int>)ApplyOverrideLandmineEnemyDamage);
}
}
private static int ApplyOverrideLandmineEnemyDamage(int orig)
{
return OverrideLandmineEnemyDamage ? Plugin.Config.EnemyDamage.Value : orig;
}
private static void StunGrenadeItem_ExplodeStunGrenade(orig_ExplodeStunGrenade orig, StunGrenadeItem self, bool destroy)
{
if (self.chanceToExplode >= 100f)
{
orig.Invoke(self, destroy);
return;
}
OverrideLandmineEnemyDamage = true;
orig.Invoke(self, destroy);
OverrideLandmineEnemyDamage = false;
}
private static void StunGrenadeItem_OnHitGround(orig_OnHitGround orig, StunGrenadeItem self)
{
Plugin.Logger.LogInfo((object)$"Hit ground! Will explode: {self.explodeOnThrow}");
orig.Invoke(self);
}
private static void StunGrenadeItem_ItemActivate(orig_ItemActivate orig, StunGrenadeItem self, bool used, bool buttonDown)
{
if (!self.inPullingPinAnimation && self.pinPulled && ((NetworkBehaviour)self).IsOwner)
{
PredictableEggComponent component = ((Component)self).gameObject.GetComponent<PredictableEggComponent>();
component.WasThrown = true;
}
orig.Invoke(self, used, buttonDown);
}
private static void StunGrenadeItem_EquipItem(orig_EquipItem orig, StunGrenadeItem self)
{
if (self.chanceToExplode >= 100f)
{
orig.Invoke(self);
return;
}
bool isPocketed = ((GrabbableObject)self).isPocketed;
float chanceToExplode = self.chanceToExplode;
self.chanceToExplode = 100f;
orig.Invoke(self);
self.chanceToExplode = chanceToExplode;
PredictableEggComponent component = ((Component)self).gameObject.GetComponent<PredictableEggComponent>();
component.SetExplosiveOnEquip(isPocketed);
component.WasThrown = false;
self.gotExplodeOnThrowRPC = true;
}
private static void StunGrenadeItem_DiscardItem(orig_DiscardItem orig, StunGrenadeItem self)
{
if (SyncedEntry<bool>.op_Implicit(Plugin.Config.DontExplodeOnDrop) && (((NetworkBehaviour)self).IsOwner || ((GrabbableObject)self).wasOwnerLastFrame) && (Object)(object)((GrabbableObject)self).playerHeldBy != (Object)null && !((GrabbableObject)self).playerHeldBy.isPlayerDead && self.chanceToExplode < 100f)
{
PredictableEggComponent component = ((Component)self).gameObject.GetComponent<PredictableEggComponent>();
if (!component.WasThrown)
{
Plugin.Logger.LogInfo((object)"Dropping safely!");
self.explodeOnThrow = false;
component.SetExplodeOnThrowDirectServerRpc(explode: false);
}
}
orig.Invoke(self);
}
private static void StunGrenadeItem_Awake(StunGrenadeItem_orig_Awake orig, StunGrenadeItem self)
{
orig(self);
if (!Object.op_Implicit((Object)(object)((Component)self).gameObject.GetComponent<PredictableEggComponent>()))
{
((Component)self).gameObject.AddComponent<PredictableEggComponent>();
}
}
}
[BepInPlugin("moe.sylvi.PredictableEggs", "PredictableEggs", "1.1.0")]
[BepInDependency("com.sigurd.csync", "5.0.1")]
public class Plugin : BaseUnityPlugin
{
public static Config Config { get; private set; }
public static ManualLogSource Logger { get; private set; }
private void Awake()
{
Config = new Config(((BaseUnityPlugin)this).Config);
Logger = ((BaseUnityPlugin)this).Logger;
Assets.Load();
Patches.Initialize();
InitNetcodePatcher();
Logger.LogInfo((object)"Plugin moe.sylvi.PredictableEggs is loaded!");
}
private void InitNetcodePatcher()
{
Type[] types = Assembly.GetExecutingAssembly().GetTypes();
Type[] array = types;
foreach (Type type in array)
{
MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
MethodInfo[] array2 = methods;
foreach (MethodInfo methodInfo in array2)
{
object[] customAttributes = methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false);
if (customAttributes.Length != 0)
{
methodInfo.Invoke(null, null);
}
}
}
}
}
public static class PluginInfo
{
public const string PLUGIN_GUID = "moe.sylvi.PredictableEggs";
public const string PLUGIN_NAME = "PredictableEggs";
public const string PLUGIN_VERSION = "1.1.0";
}
public class PredictableEggComponent : NetworkBehaviour
{
public bool WasThrown = false;
private StunGrenadeItem eggItem;
private void Awake()
{
eggItem = ((Component)this).gameObject.GetComponent<StunGrenadeItem>();
}
public void SetExplosiveOnEquip(bool wasPocketed)
{
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
if (((NetworkBehaviour)this).IsOwner)
{
Random random = new Random(StartOfRound.Instance.randomMapSeed + 10 + (int)((Component)this).transform.position.x + (int)((Component)this).transform.position.z);
bool flag = random.NextDouble() * 100.0 < (double)Plugin.Config.EggExplodeChance.Value;
if (wasPocketed && Plugin.Config.DetermineOnPickUp.Value)
{
flag = eggItem.explodeOnThrow;
}
if (flag && Plugin.Config.WarningSound.Value)
{
((Component)this).gameObject.GetComponent<AudioSource>().PlayOneShot(Assets.EggReadyToExplode, 1f);
}
Plugin.Logger.LogInfo((object)$"Egg explosion prediction: {flag}");
eggItem.explodeOnThrow = flag;
SetExplodeOnThrowDirectServerRpc(flag);
}
}
[ServerRpc(RequireOwnership = false)]
public void SetExplodeOnThrowDirectServerRpc(bool explode)
{
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Invalid comparison between Unknown and I4
//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
//IL_00b1: Invalid comparison between Unknown and I4
//IL_005f: Unknown result type (might be due to invalid IL or missing references)
//IL_0068: Unknown result type (might be due to invalid IL or missing references)
//IL_006d: Unknown result type (might be due to invalid IL or missing references)
//IL_007d: Unknown result type (might be due to invalid IL or missing references)
//IL_0083: Unknown result type (might be due to invalid IL or missing references)
//IL_0097: Unknown result type (might be due to invalid IL or missing references)
NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
if (networkManager != null && networkManager.IsListening)
{
if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
{
ServerRpcParams val = default(ServerRpcParams);
FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(1866835474u, val, (RpcDelivery)0);
((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref explode, default(ForPrimitives));
((NetworkBehaviour)this).__endSendServerRpc(ref val2, 1866835474u, val, (RpcDelivery)0);
}
if ((int)base.__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
{
SetExplodeOnThrowDirectClientRpc(explode);
}
}
}
[ClientRpc]
public void SetExplodeOnThrowDirectClientRpc(bool explode)
{
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Invalid comparison between Unknown and I4
//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
//IL_00b1: Invalid comparison between Unknown and I4
//IL_005f: Unknown result type (might be due to invalid IL or missing references)
//IL_0068: Unknown result type (might be due to invalid IL or missing references)
//IL_006d: Unknown result type (might be due to invalid IL or missing references)
//IL_007d: Unknown result type (might be due to invalid IL or missing references)
//IL_0083: Unknown result type (might be due to invalid IL or missing references)
//IL_0097: Unknown result type (might be due to invalid IL or missing references)
NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
if (networkManager != null && networkManager.IsListening)
{
if ((int)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
{
ClientRpcParams val = default(ClientRpcParams);
FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(1435201353u, val, (RpcDelivery)0);
((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref explode, default(ForPrimitives));
((NetworkBehaviour)this).__endSendClientRpc(ref val2, 1435201353u, val, (RpcDelivery)0);
}
if ((int)base.__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost) && !((NetworkBehaviour)this).IsOwner)
{
Plugin.Logger.LogInfo((object)$"Egg explosion prediction: {explode}");
eggItem.gotExplodeOnThrowRPC = true;
eggItem.explodeOnThrow = explode;
}
}
}
protected override void __initializeVariables()
{
((NetworkBehaviour)this).__initializeVariables();
}
[RuntimeInitializeOnLoadMethod]
internal static void InitializeRPCS_PredictableEggComponent()
{
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Expected O, but got Unknown
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_0036: Expected O, but got Unknown
NetworkManager.__rpc_func_table.Add(1866835474u, new RpcReceiveHandler(__rpc_handler_1866835474));
NetworkManager.__rpc_func_table.Add(1435201353u, new RpcReceiveHandler(__rpc_handler_1435201353));
}
private static void __rpc_handler_1866835474(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
{
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_0044: Unknown result type (might be due to invalid IL or missing references)
//IL_005e: Unknown result type (might be due to invalid IL or missing references)
NetworkManager networkManager = target.NetworkManager;
if (networkManager != null && networkManager.IsListening)
{
bool explodeOnThrowDirectServerRpc = default(bool);
((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref explodeOnThrowDirectServerRpc, default(ForPrimitives));
target.__rpc_exec_stage = (__RpcExecStage)1;
((PredictableEggComponent)(object)target).SetExplodeOnThrowDirectServerRpc(explodeOnThrowDirectServerRpc);
target.__rpc_exec_stage = (__RpcExecStage)0;
}
}
private static void __rpc_handler_1435201353(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
{
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_0044: Unknown result type (might be due to invalid IL or missing references)
//IL_005e: Unknown result type (might be due to invalid IL or missing references)
NetworkManager networkManager = target.NetworkManager;
if (networkManager != null && networkManager.IsListening)
{
bool explodeOnThrowDirectClientRpc = default(bool);
((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref explodeOnThrowDirectClientRpc, default(ForPrimitives));
target.__rpc_exec_stage = (__RpcExecStage)2;
((PredictableEggComponent)(object)target).SetExplodeOnThrowDirectClientRpc(explodeOnThrowDirectClientRpc);
target.__rpc_exec_stage = (__RpcExecStage)0;
}
}
[MethodImpl(MethodImplOptions.NoInlining)]
protected internal override string __getTypeName()
{
return "PredictableEggComponent";
}
}
}
namespace PredictableEggs.NetcodePatcher
{
[AttributeUsage(AttributeTargets.Module)]
internal class NetcodePatchedAssemblyAttribute : Attribute
{
}
}