using System; using System.Collections.Generic; 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 API; using Agents; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using BepInEx.Unity.IL2CPP; using EWC.API; using EWC.CustomWeapon; using EWC.CustomWeapon.Enums; using EWC.CustomWeapon.Properties; using EWC.CustomWeapon.Properties.Effects; using EWC.CustomWeapon.Properties.Traits.CustomProjectile.Components; using EWC.CustomWeapon.Structs; using EWC.Utils; using Enemies; using GameData; using Gear; using HarmonyLib; using Il2CppInterop.Runtime.InteropTypes; using LevelGeneration; using Microsoft.CodeAnalysis; using Player; using ReplayRecorder.API; using ReplayRecorder.API.Attributes; using ReplayRecorder.Core; using ReplayRecorder.EWC.BepInEx; using SNetwork; using UnityEngine; using UnityEngine.Analytics; using Vanilla; using Vanilla.Events; using Vanilla.StatTracker; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("ReplayRecorder.ExtraWeaponCustomization")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+4de1880dffb95b2402ed998583447b60ab6fd15a")] [assembly: AssemblyProduct("ReplayRecorder.ExtraWeaponCustomization")] [assembly: AssemblyTitle("ReplayRecorder.ExtraWeaponCustomization")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } } namespace API { [HarmonyPatch(typeof(GameDataInit))] internal class GameDataInit_Patches { [HarmonyPatch("Initialize")] [HarmonyWrapSafe] [HarmonyPostfix] public static void Initialize_Postfix() { Analytics.enabled = false; } } internal static class APILogger { private static readonly ManualLogSource logger; static APILogger() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Expected O, but got Unknown logger = new ManualLogSource("Rand-API"); Logger.Sources.Add((ILogSource)(object)logger); } private static string Format(string module, object msg) { return $"[{module}]: {msg}"; } public static void Info(string module, object data) { logger.LogMessage((object)Format(module, data)); } public static void Verbose(string module, object data) { } public static void Log(object data) { logger.LogDebug((object)Format("ReplayRecorder.EWC", data)); } public static void Debug(object data) { if (ConfigManager.Debug) { Log(data); } } public static void Warn(object data) { logger.LogWarning((object)Format("ReplayRecorder.EWC", data)); } public static void Error(object data) { logger.LogError((object)Format("ReplayRecorder.EWC", data)); } } } namespace ReplayRecorder.EWC { [ReplayData("EWC.Damage", "0.0.2")] internal class rEWCDamage : ReplayEvent { internal static class Hooks { public static void Shrapnel(float damage, EnemyAgent enemy, Dam_EnemyDamageLimb limb, PlayerAgent? source, pCWC cwc) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)source == (Object)null)) { Sync.Trigger(new rEWCDamage(Type.Shrapnel, damage, (Agent)(object)source, (Agent)(object)enemy, ((Enum)cwc.ownerType).HasFlag((Enum)(object)(OwnerType)8))); } } public static void Explosive(float damage, EnemyAgent enemy, Dam_EnemyDamageLimb limb, PlayerAgent? source, pCWC cwc) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)source == (Object)null)) { Sync.Trigger(new rEWCDamage(Type.Explosive, damage, (Agent)(object)source, (Agent)(object)enemy, ((Enum)cwc.ownerType).HasFlag((Enum)(object)(OwnerType)8))); } } public static void DoT(float damage, EnemyAgent enemy, Dam_EnemyDamageLimb limb, PlayerAgent? source, pCWC cwc) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)source == (Object)null)) { Sync.Trigger(new rEWCDamage(Type.DoT, damage, (Agent)(object)source, (Agent)(object)enemy, ((Enum)cwc.ownerType).HasFlag((Enum)(object)(OwnerType)8))); } } } public enum Type { Explosive, DoT, Shrapnel } private static class Sync { private const string eventName = "EWC.Damage"; private static ByteBuffer packet = new ByteBuffer(); [ReplayPluginLoad] private static void Load() { RNet.Register("EWC.Damage", (Action>)OnReceive); } public static void Trigger(rEWCDamage damage) { Replay.Trigger((ReplayEvent)(object)damage); ByteBuffer val = packet; val.Clear(); BitHelper.WriteBytes((byte)damage.type, val); BitHelper.WriteBytes(damage.source, val); BitHelper.WriteBytes(damage.target, val); BitHelper.WriteHalf(damage.damage, val); BitHelper.WriteBytes(damage.isSentry, val); RNet.Trigger("EWC.Damage", val); } private static void OnReceive(ulong sender, ArraySegment packet) { int num = 0; byte type = BitHelper.ReadByte(packet, ref num); ushort source = BitHelper.ReadUShort(packet, ref num); ushort target = BitHelper.ReadUShort(packet, ref num); float damage = BitHelper.ReadHalf(packet, ref num); bool isSentry = BitHelper.ReadBool(packet, ref num); Replay.Trigger((ReplayEvent)(object)new rEWCDamage((Type)type, damage, source, target, isSentry)); } } private Type type; private float damage; private ushort source; private ushort target; private bool isSentry; public rEWCDamage(Type type, float damage, ushort source, ushort target, bool isSentry) { this.type = type; this.damage = damage; this.source = source; this.target = target; this.isSentry = isSentry; } public rEWCDamage(Type type, float damage, Agent source, Agent target, bool isSentry) { this.type = type; this.damage = damage; this.source = source.GlobalID; this.target = target.GlobalID; this.isSentry = isSentry; } public override void Write(ByteBuffer buffer) { BitHelper.WriteBytes((byte)type, buffer); BitHelper.WriteBytes(source, buffer); BitHelper.WriteBytes(target, buffer); BitHelper.WriteHalf(damage, buffer); BitHelper.WriteBytes(isSentry, buffer); } } [ReplayData("EWC.Explosion", "0.0.1")] internal class rEWCExplosion : ReplayEvent { internal static class Hooks { public static void Trigger(Vector3 position, Explosive explosion) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) Replay.Trigger((ReplayEvent)(object)new rEWCExplosion(position, explosion)); } } private Vector3 position; private Explosive explosion; public rEWCExplosion(Vector3 position, Explosive explosion) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) this.position = position; this.explosion = explosion; } public override void Write(ByteBuffer buffer) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) BitHelper.WriteBytes(position, buffer); BitHelper.WriteHalf(explosion.InnerRadius, buffer); BitHelper.WriteHalf(explosion.Radius, buffer); } } internal class rEWCGunShot { internal static class Hooks { public static void Trigger(HitData hit, Vector3 start, Vector3 end, WeaponType weaponType) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown Replay.Trigger((ReplayEvent)new rGunshot(hit.owner, hit.damage, start, end, ((Enum)weaponType).HasFlag((Enum)(object)(WeaponType)16), false, true)); } } } [HarmonyPatch] internal static class EWCAccuracy { private class BulletInfo { public int hits; public int crits; } private static Dictionary projectiles = new Dictionary(); private static Identifier currentWeapon = Identifier.unknown; private static PlayerAgent? currentPlayer = null; private static BulletInfo currentBullet = new BulletInfo(); [ReplayInit] private static void Init() { projectiles.Clear(); } public static void OnProjectileDespawn(EWCProjectileComponentBase projectile) { //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Expected O, but got Unknown if (projectile.IsManaged && !((Object)(object)((WeaponPropertyBase)projectile.Settings).CWC.Owner.Player == (Object)null)) { if (!projectiles.ContainsKey(projectile.SyncID)) { projectiles.Add(projectile.SyncID, new BulletInfo()); } BulletInfo bulletInfo = projectiles[projectile.SyncID]; if (bulletInfo.hits > 255 || bulletInfo.crits > 255) { APILogger.Warn($"Number of enemies hit / crit for this bullet exceeded maximum value of {255}."); } Sync.Trigger(new rGunshotInfo(((WeaponPropertyBase)projectile.Settings).CWC.Owner.Player, Identifier.From(((WeaponPropertyBase)projectile.Settings).CWC.Weapon.Component), (byte)bulletInfo.hits, (byte)bulletInfo.crits)); projectiles.Remove(projectile.SyncID); } } public static void OnProjectileHit(EWCProjectileComponentBase projectile, IDamageable? damageable) { //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Invalid comparison between Unknown and I4 if (!projectile.IsManaged || damageable == null) { return; } if (!projectiles.ContainsKey(projectile.SyncID)) { projectiles.Add(projectile.SyncID, new BulletInfo()); } BulletInfo bulletInfo = projectiles[projectile.SyncID]; Dam_EnemyDamageLimb val = ((Il2CppObjectBase)damageable).TryCast(); if ((Object)(object)val != (Object)null) { bulletInfo.hits++; if ((int)val.m_type == 1) { bulletInfo.crits++; } return; } if ((Object)(object)((Il2CppObjectBase)damageable).TryCast() != (Object)null) { bulletInfo.hits++; return; } LG_WeakLockDamage val2 = ((Il2CppObjectBase)damageable).TryCast(); if ((Object)(object)val2 != (Object)null) { if (!(val2.Health <= 0f)) { bulletInfo.hits++; } } else if ((Object)(object)((Il2CppObjectBase)damageable).TryCast() != (Object)null) { bulletInfo.hits++; } } public static void PreShotFired(HitData hit, Ray ray, WeaponType weaponType) { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: 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) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)hit.owner == (Object)null || (!SNet.IsMaster && hit.owner.Owner.IsBot) || (!hit.owner.Owner.IsBot && !((Agent)hit.owner).IsLocallyOwned)) { return; } currentPlayer = hit.owner; currentWeapon = Identifier.unknown; (SentryGunInstance, CustomGunComponent) tuple = default((SentryGunInstance, CustomGunComponent)); if (((Enum)weaponType).HasFlag((Enum)(object)(WeaponType)16) && CustomWeaponManager.TryGetSentry(currentPlayer, ref tuple)) { currentWeapon = Identifier.From((ItemEquippable)(object)tuple.Item1); return; } ItemEquippable wieldedItem = currentPlayer.Inventory.m_wieldedItem; if (wieldedItem.IsWeapon && (Object)(object)((Il2CppObjectBase)wieldedItem).TryCast() != (Object)null) { currentWeapon = Identifier.From(wieldedItem); } } public static void OnShotFired(HitData hit, Vector3 start, Vector3 end, WeaponType weaponType) { //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Expected O, but got Unknown if (!((Object)(object)currentPlayer == (Object)null)) { if (currentBullet.hits > 255 || currentBullet.crits > 255) { APILogger.Warn($"Number of enemies hit / crit for this bullet exceeded maximum value of {255}."); } Sync.Trigger(new rGunshotInfo(currentPlayer, currentWeapon, (byte)currentBullet.hits, (byte)currentBullet.crits)); currentPlayer = null; currentBullet.crits = 0; currentBullet.hits = 0; } } public static void OnExplosiveDamage(float damage, EnemyAgent enemy, Dam_EnemyDamageLimb limb, PlayerAgent? source, pCWC cwc) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Invalid comparison between Unknown and I4 //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Invalid comparison between Unknown and I4 if (!((Agent)enemy).Alive) { return; } if ((Object)(object)currentPlayer != (Object)null) { currentBullet.hits++; if ((int)limb.m_type == 1) { currentBullet.crits++; } } if ((Object)(object)Patches.currentPlayer != (Object)null) { Patches.currentBullet.hits++; if ((int)limb.m_type == 1) { Patches.currentBullet.crits++; } } } public static void OnShrapnelDamage(float damage, EnemyAgent enemy, Dam_EnemyDamageLimb limb, PlayerAgent? source, pCWC cwc) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) OnExplosiveDamage(damage, enemy, limb, source, cwc); } [HarmonyPatch(typeof(Dam_EnemyDamageLimb), "BulletDamage")] [HarmonyPrefix] public static void Prefix_EnemyLimbBulletDamage(Dam_EnemyDamageLimb __instance, Agent sourceAgent) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Invalid comparison between Unknown and I4 if (((Agent)__instance.m_base.Owner).Alive && !((Object)(object)currentPlayer == (Object)null)) { currentBullet.hits++; if ((int)__instance.m_type == 1) { currentBullet.crits++; } } } [HarmonyPatch(typeof(Dam_PlayerDamageLimb), "BulletDamage")] [HarmonyPrefix] public static void Prefix_PlayerLimbBulletDamage(Dam_PlayerDamageLimb __instance, Agent sourceAgent) { if (((Agent)__instance.m_base.Owner).Alive && !((Object)(object)currentPlayer == (Object)null)) { currentBullet.hits++; } } [HarmonyPatch(typeof(GenericDamageComponent), "BulletDamage")] [HarmonyPrefix] public static void Prefix_GenericBulletDamage(GenericDamageComponent __instance, Agent sourceAgent) { if (!((Object)(object)currentPlayer == (Object)null)) { currentBullet.hits++; } } [HarmonyPatch(typeof(LG_WeakLockDamage), "BulletDamage")] [HarmonyPrefix] public static void Prefix_LockBulletDamage(LG_WeakLockDamage __instance, Agent sourceAgent) { if (!(__instance.Health <= 0f) && !((Object)(object)currentPlayer == (Object)null)) { currentBullet.hits++; } } } internal struct ProjectileTransform : IReplayTransform { private EWCProjectileComponentBase projectile; private byte dimension; public byte dimensionIndex => dimension; public bool active => (Object)(object)projectile != (Object)null; public Vector3 position => ((Component)projectile).transform.position; public Quaternion rotation => ((Component)projectile).transform.rotation; public ProjectileTransform(EWCProjectileComponentBase projectile) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) this.projectile = projectile; dimension = (byte)Dimension.GetDimensionFromPos(((Component)projectile).transform.position).DimensionIndex; } } [ReplayData("EWC.Projectile", "0.0.1")] internal class rEWCProjectile : DynamicTransform { internal static class Hooks { public static void OnSpawn(EWCProjectileComponentBase projectile) { try { Replay.Spawn((ReplayDynamic)(object)new rEWCProjectile(projectile), true); } catch (Exception value) { APILogger.Error($"Failed to spawn EWC projectile: {value}"); } } public static void OnDespawn(EWCProjectileComponentBase projectile) { Replay.TryDespawn(GetUniqueId(projectile)); } } private EWCProjectileComponentBase projectile; [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int GetUniqueId(EWCProjectileComponentBase projectile) { return projectile.SyncID + (projectile.PlayerIndex << 16); } public rEWCProjectile(EWCProjectileComponentBase projectile) : base(GetUniqueId(projectile), (IReplayTransform)(object)new ProjectileTransform(projectile)) { this.projectile = projectile; } public override void Spawn(ByteBuffer buffer) { ((DynamicTransform)this).Spawn(buffer); BitHelper.WriteBytes((byte)projectile.PlayerIndex, buffer); BitHelper.WriteHalf(projectile.Settings.ModelScale, buffer); } } } namespace ReplayRecorder.EWC.BepInEx { public static class Module { public const string GUID = "randomuserhi.ReplayRecorder.EWC"; public const string Name = "ReplayRecorder.EWC"; public const string Version = "0.0.1"; } public static class ConfigManager { public static ConfigFile configFile; private static ConfigEntry debug; public static bool Debug { get { return debug.Value; } set { debug.Value = value; } } static ConfigManager() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Expected O, but got Unknown configFile = new ConfigFile(Path.Combine(Paths.ConfigPath, "ReplayRecorder.EWC.cfg"), true); debug = configFile.Bind("Debug", "enable", false, "Enables debug messages when true."); } } [BepInPlugin("randomuserhi.ReplayRecorder.EWC", "ReplayRecorder.EWC", "0.0.1")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BasePlugin { private static Harmony? harmony; public override void Load() { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Expected O, but got Unknown //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Expected O, but got Unknown //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Expected O, but got Unknown //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Expected O, but got Unknown //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Expected O, but got Unknown //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Expected O, but got Unknown //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Expected O, but got Unknown //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Expected O, but got Unknown //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Expected O, but got Unknown //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Expected O, but got Unknown //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Expected O, but got Unknown //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Expected O, but got Unknown //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Expected O, but got Unknown APILogger.Log("Plugin is loaded!"); harmony = new Harmony("randomuserhi.ReplayRecorder.EWC"); harmony.PatchAll(); APILogger.Log("Debug is " + (ConfigManager.Debug ? "Enabled" : "Disabled")); Replay.RegisterAll(); ProjectileAPI.OnProjectileSpawned += new ProjectileCallback(rEWCProjectile.Hooks.OnSpawn); ProjectileAPI.OnProjectileDestroyed += new ProjectileCallback(rEWCProjectile.Hooks.OnDespawn); ExplosionAPI.OnExplosionSpawned += new ExplosionSpawnedCallback(rEWCExplosion.Hooks.Trigger); DamageAPI.PreExplosiveDamage += new DamageCallback(rEWCDamage.Hooks.Explosive); DamageAPI.PreShrapnelDamage += new DamageCallback(rEWCDamage.Hooks.Shrapnel); DamageAPI.PreDOTDamage += new DamageCallback(rEWCDamage.Hooks.DoT); FireShotAPI.OnShotFired += new ShotFiredCallback(rEWCGunShot.Hooks.Trigger); ProjectileAPI.OnProjectileDestroyed += new ProjectileCallback(EWCAccuracy.OnProjectileDespawn); ProjectileAPI.OnProjectileHit += new ProjectileHitCallback(EWCAccuracy.OnProjectileHit); FireShotAPI.OnShotFired += new ShotFiredCallback(EWCAccuracy.OnShotFired); FireShotAPI.PreShotFired += new PreShotFiredCallback(EWCAccuracy.PreShotFired); DamageAPI.PreExplosiveDamage += new DamageCallback(EWCAccuracy.OnExplosiveDamage); DamageAPI.PreShrapnelDamage += new DamageCallback(EWCAccuracy.OnShrapnelDamage); rGunshot.RegisterCancelSyncedShot((Func)CancelSyncedShot); } private static bool CancelSyncedShot(BulletWeapon weapon) { return (Object)(object)((Component)weapon).GetComponent() != (Object)null; } } }