Please disclose if any significant portion of your mod was created 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 Bullet Control v1.0.0
BulletControl.dll
Decompiled 7 months agousing System; using System.Collections; 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 BepInEx.Logging; using ExitGames.Client.Photon; using HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using Photon.Realtime; using UnityEngine; using UnityEngine.Events; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: IgnoresAccessChecksTo("")] [assembly: AssemblyCompany("Omniscye")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("BulletControl")] [assembly: AssemblyTitle("BulletControl")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.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.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] [Microsoft.CodeAnalysis.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; } } [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 Empress.RepoMods.GuidedBulletCam { [BepInPlugin("empress.repogame.guidedbulletcam", "Guided Bullet Camera", "2.1.0")] public class GuidedBulletCamPlugin : BaseUnityPlugin { private sealed class TimeGuard : MonoBehaviour { private float _deadline = -1f; private Action _quitHandler; private UnityAction<Scene, Scene> _sceneChangedHandler; private void OnEnable() { _quitHandler = OnAppQuitting; _sceneChangedHandler = OnSceneChanged; Application.quitting += _quitHandler; SceneManager.activeSceneChanged += _sceneChangedHandler; } private void OnDisable() { if (_quitHandler != null) { Application.quitting -= _quitHandler; } if (_sceneChangedHandler != null) { SceneManager.activeSceneChanged -= _sceneChangedHandler; } } public static void Arm(float seconds) { TimeGuard timeGuard = Object.FindObjectOfType<TimeGuard>(); if (Object.op_Implicit((Object)(object)timeGuard)) { timeGuard._deadline = Time.realtimeSinceStartup + Mathf.Max(0.25f, seconds); } } public static void Disarm() { TimeGuard timeGuard = Object.FindObjectOfType<TimeGuard>(); if (Object.op_Implicit((Object)(object)timeGuard)) { timeGuard._deadline = -1f; } } private void Update() { if (_deadline >= 0f && Time.realtimeSinceStartup >= _deadline) { ForceRestore(); } } private void OnAppQuitting() { ForceRestore(); } private void OnSceneChanged(Scene a, Scene b) { ForceRestore(); } private void ForceRestore() { try { IsGuiding = false; Time.timeScale = BaselineTimeScale; Time.fixedDeltaTime = BaselineFixedDelta; } catch { } _deadline = -1f; } } public class GuidedCamHandshakeRouter : MonoBehaviourPunCallbacks, IOnEventCallback { [CompilerGenerated] private sealed class <WaitForLevelThenHandshake>d__18 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public GuidedCamHandshakeRouter <>4__this; private float <t>5__1; private float <elapsed>5__2; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <WaitForLevelThenHandshake>d__18(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <t>5__1 = 0f; goto IL_0066; case 1: <>1__state = -1; goto IL_0066; case 2: { <>1__state = -1; goto IL_0155; } IL_0066: if (((Object)(object)LevelGenerator.Instance == (Object)null || !LevelGenerator.Instance.Generated) && <t>5__1 < 20f) { <t>5__1 += Time.deltaTime; <>2__current = null; <>1__state = 1; return true; } _levelReady = true; if (!PhotonNetwork.InRoom || !PhotonNetwork.IsConnectedAndReady) { _handshakeComplete = true; _hostHasMod = true; return false; } if (PhotonNetwork.IsMasterClient) { _handshakeComplete = true; _hostHasMod = true; return false; } if (_requestSent) { break; } _requestSent = true; PhotonNetwork.RaiseEvent((byte)73, (object)new object[2] { "empress.repogame.guidedbulletcam", "2.1.0" }, new RaiseEventOptions { Receivers = (ReceiverGroup)2 }, SendOptions.SendReliable); <elapsed>5__2 = 0f; goto IL_0155; IL_0155: if (!_handshakeComplete && <elapsed>5__2 < 4f) { <elapsed>5__2 += Time.deltaTime; <>2__current = null; <>1__state = 2; return true; } if (!_handshakeComplete) { _hostHasMod = false; _handshakeComplete = true; } break; } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private const byte EVENT_HANDSHAKE_REQUEST = 73; private const byte EVENT_HANDSHAKE_RESPONSE = 74; private static bool _levelReady; private static bool _handshakeComplete; private static bool _hostHasMod; private static bool _requestSent; private static string _loadedSceneName; private bool _callbackHooked; public static bool CanUseModNow() { if (!CfgEnabled.Value) { return false; } if (!PhotonNetwork.InRoom) { return _levelReady; } if (PhotonNetwork.IsMasterClient) { return _levelReady; } return _levelReady && _handshakeComplete && _hostHasMod; } private void OnEnable() { SceneManager.sceneLoaded += OnSceneLoaded; } private void OnDisable() { SceneManager.sceneLoaded -= OnSceneLoaded; if (_callbackHooked) { PhotonNetwork.RemoveCallbackTarget((object)this); } _callbackHooked = false; } public override void OnJoinedRoom() { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) EnsureCallbackHooked(); ResetStatesOnRoomChange(); Scene activeScene = SceneManager.GetActiveScene(); if (IsRealLevel(((Scene)(ref activeScene)).name)) { ((MonoBehaviour)this).StartCoroutine(WaitForLevelThenHandshake()); } } public override void OnLeftRoom() { if (_callbackHooked) { PhotonNetwork.RemoveCallbackTarget((object)this); _callbackHooked = false; } _levelReady = false; _handshakeComplete = false; _hostHasMod = false; _requestSent = false; } private void EnsureCallbackHooked() { if (!_callbackHooked) { PhotonNetwork.AddCallbackTarget((object)this); _callbackHooked = true; } } private void OnSceneLoaded(Scene s, LoadSceneMode m) { _loadedSceneName = ((Scene)(ref s)).name ?? string.Empty; ResetStatesOnSceneChange(); EnsureCallbackHooked(); if (IsRealLevel(_loadedSceneName)) { ((MonoBehaviour)this).StartCoroutine(WaitForLevelThenHandshake()); } } private static void ResetStatesOnSceneChange() { _levelReady = false; _handshakeComplete = false; _hostHasMod = false; _requestSent = false; } private static void ResetStatesOnRoomChange() { _levelReady = false; _handshakeComplete = false; _hostHasMod = false; _requestSent = false; } private bool IsRealLevel(string sceneName) { if (string.IsNullOrEmpty(sceneName)) { return false; } if (sceneName.IndexOf("Lobby", StringComparison.OrdinalIgnoreCase) >= 0) { return false; } return true; } [IteratorStateMachine(typeof(<WaitForLevelThenHandshake>d__18))] private IEnumerator WaitForLevelThenHandshake() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <WaitForLevelThenHandshake>d__18(0) { <>4__this = this }; } public void OnEvent(EventData photonEvent) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Expected O, but got Unknown //IL_005f: Unknown result type (might be due to invalid IL or missing references) try { if (photonEvent.Code == 73) { if (PhotonNetwork.IsMasterClient) { int sender = photonEvent.Sender; object[] array = new object[3] { "empress.repogame.guidedbulletcam", "2.1.0", true }; RaiseEventOptions val = new RaiseEventOptions(); val.TargetActors = new int[1] { sender }; PhotonNetwork.RaiseEvent((byte)74, (object)array, val, SendOptions.SendReliable); } } else if (photonEvent.Code == 74 && photonEvent.CustomData is object[] array2 && array2.Length >= 3) { string text = array2[0] as string; object obj = array2[2]; bool flag = default(bool); int num; if (obj is bool) { flag = (bool)obj; num = 1; } else { num = 0; } bool flag2 = (byte)((uint)num & (flag ? 1u : 0u)) != 0; if (!string.IsNullOrEmpty(text) && text == "empress.repogame.guidedbulletcam" && flag2) { _hostHasMod = true; } else { _hostHasMod = false; } _handshakeComplete = true; } } catch { } } } [HarmonyPatch] private static class ItemGunStartInjector { private static MethodBase TargetMethod() { Type type = AccessTools.TypeByName("ItemGun"); return (type != null) ? AccessTools.Method(type, "Start", (Type[])null, (Type[])null) : null; } private static void Postfix(MonoBehaviour __instance) { GameObject gameObject = ((Component)__instance).gameObject; if (!Object.op_Implicit((Object)(object)gameObject.GetComponent<EmpressGunProxy>())) { gameObject.AddComponent<EmpressGunProxy>(); } } } [HarmonyPatch] private static class ItemToggleHooks { private static MethodBase TargetMethod() { return AccessTools.Method(AccessTools.TypeByName("ItemToggle"), "ToggleItem", new Type[2] { typeof(bool), typeof(int) }, (Type[])null); } private static bool Prefix(MonoBehaviour __instance, bool toggle, int player) { //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0400: Unknown result type (might be due to invalid IL or missing references) //IL_0414: Unknown result type (might be due to invalid IL or missing references) //IL_0293: Unknown result type (might be due to invalid IL or missing references) //IL_0298: Unknown result type (might be due to invalid IL or missing references) //IL_02a2: Unknown result type (might be due to invalid IL or missing references) //IL_02a9: Unknown result type (might be due to invalid IL or missing references) //IL_04d7: Unknown result type (might be due to invalid IL or missing references) //IL_04dc: Unknown result type (might be due to invalid IL or missing references) //IL_04e6: Unknown result type (might be due to invalid IL or missing references) //IL_04ed: Unknown result type (might be due to invalid IL or missing references) if (!CfgEnabled.Value) { return true; } if (!IsLevelReady()) { return true; } Type type = AccessTools.TypeByName("SemiFunc"); MethodInfo methodInfo = AccessTools.Method(type, "PhotonViewIDPlayerAvatarLocal", (Type[])null, (Type[])null); int num = -1; try { num = (int)(methodInfo?.Invoke(null, null) ?? ((object)(-1))); } catch { } if (player != num) { return true; } Type type2 = AccessTools.TypeByName("ItemGun"); Component component = ((Component)__instance).GetComponent(type2); if (!Object.op_Implicit((Object)(object)component) || !toggle) { return true; } if (!HasAmmo(component)) { object obj2 = AccessTools.Field(((object)component).GetType(), "soundNoAmmoClick")?.GetValue(component); Vector3 position = ((Component)__instance).transform.position; if (obj2 != null) { MethodInfo methodInfo2 = AccessTools.Method(obj2.GetType(), "Play", new Type[5] { typeof(Vector3), typeof(float), typeof(float), typeof(float), typeof(float) }, (Type[])null); if (methodInfo2 != null) { methodInfo2.Invoke(obj2, new object[5] { position, 1f, 1f, 1f, 1f }); } } SafeCall(component, "StartTriggerAnimation"); object field = GetField(component, "gunMuzzle"); Transform val = (Transform)((field is Transform) ? field : null); if (Object.op_Implicit((Object)(object)val)) { AccessTools.Method(type, "CameraShakeImpact", new Type[2] { typeof(float), typeof(float) }, (Type[])null)?.Invoke(null, new object[2] { 1f, 0.1f }); object? obj3 = AccessTools.Field(((object)component).GetType(), "physGrabObject")?.GetValue(component); Component val2 = (Component)((obj3 is Component) ? obj3 : null); Rigidbody val3 = (Object.op_Implicit((Object)(object)val2) ? val2.GetComponent<Rigidbody>() : null); if (val3 != null) { val3.AddForceAtPosition(-val.forward * 1f, val.position, (ForceMode)1); } } return false; } PhotonView val4 = ResolvePV((Component)(object)__instance); if (!Object.op_Implicit((Object)(object)val4)) { return true; } object field2 = GetField(component, "gunMuzzle"); Transform val5 = (Transform)((field2 is Transform) ? field2 : null); if (!Object.op_Implicit((Object)(object)val5)) { return true; } float num2 = (float)(GetField(component, "batteryDrain") ?? ((object)0f)); bool flag = (bool)(GetField(component, "batteryDrainFullBar") ?? ((object)false)); int num3 = (int)(GetField(component, "batteryDrainFullBars") ?? ((object)1)); if (PhotonNetwork.IsConnected && val4.ViewID != 0) { val4.RPC("Empress_StartGuide", (RpcTarget)2, new object[4] { num, flag, num3, num2 }); val4.RPC("ToggleItemRPC", (RpcTarget)1, new object[2] { toggle, player }); } else { EmpressGunProxy.SetPendingLocal(val4, component, flag, num3, num2, val5); } SafeInvokeSound(component, "soundShoot", val5.position); SafeInvokeSound(component, "soundShootGlobal", val5.position); SafeCall(component, "MuzzleFlash"); SafeCall(component, "StartTriggerAnimation"); AccessTools.Method(type, "CameraShakeImpact", new Type[2] { typeof(float), typeof(float) }, (Type[])null)?.Invoke(null, new object[2] { 1f, 0.1f }); object? obj4 = AccessTools.Field(((object)component).GetType(), "physGrabObject")?.GetValue(component); Component val6 = (Component)((obj4 is Component) ? obj4 : null); Rigidbody val7 = (Object.op_Implicit((Object)(object)val6) ? val6.GetComponent<Rigidbody>() : null); if (val7 != null) { val7.AddForceAtPosition(-val5.forward * 1f, val5.position, (ForceMode)1); } StartLocalOverlay(component, val4, val5); return false; } private static void StartLocalOverlay(object gun, PhotonView pv, Transform muzzle) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) try { GameObject val = new GameObject("Empress_GuidedBulletHost"); Object.DontDestroyOnLoad((Object)(object)val); GuidedBulletController guidedBulletController = val.AddComponent<GuidedBulletController>(); guidedBulletController.Init(gun, pv, muzzle.position, muzzle.forward, Mathf.Max(0.1f, CfgBulletSpeed.Value), Mathf.Clamp(CfgTurnRateDeg.Value, 10f, 1440f), Mathf.Clamp(CfgFov.Value, 20f, 110f), CfgCancelKey.Value, Mathf.Clamp(CfgTimeScale.Value, 0.02f, 0.5f), Mathf.Clamp(CfgMaxGuideSeconds.Value, 0.25f, 30f), Mathf.Clamp(CfgHitRadius.Value, 0f, 0.5f), Mathf.Clamp(CfgMaxDistance.Value, 5f, 5000f)); } catch (Exception arg) { ManualLogSource logS = LogS; if (logS != null) { logS.LogError((object)$"StartLocalOverlay failed: {arg}"); } } } } [HarmonyPatch] private static class ShootRpcMasterSkipper { private static MethodBase TargetMethod() { Type type = AccessTools.TypeByName("ItemGun"); return (type != null) ? AccessTools.Method(type, "ShootRPC", new Type[1] { typeof(PhotonMessageInfo) }, (Type[])null) : null; } private static bool Prefix(MonoBehaviour __instance) { if (!CfgEnabled.Value) { return true; } if (!PhotonNetwork.IsConnected || !PhotonNetwork.IsMasterClient) { return true; } PhotonView val = ResolvePV((Component)(object)__instance); if (Object.op_Implicit((Object)(object)val) && IsPendingGuided(val)) { return false; } return true; } } private sealed class EmpressGunProxy : MonoBehaviour { [PunRPC] public void Empress_StartGuide(int shooterViewID, bool fullBar, int bars, float drain, PhotonMessageInfo info) { //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) if (!PhotonNetwork.IsMasterClient) { return; } PhotonView val = ResolvePV((Component)(object)this); if (!Object.op_Implicit((Object)(object)val)) { return; } Type type = AccessTools.TypeByName("ItemGun"); Component val2 = ((type != null) ? ((Component)this).GetComponent(type) : null); if ((Object)(object)val2 == (Object)null) { return; } if (!HasAmmo(val2)) { val.RPC("Empress_CancelGuideClient", info.Sender, Array.Empty<object>()); return; } MarkPendingGuided(val); object field = GetField(val2, "itemBattery"); ApplyBatteryDrain(field, fullBar, bars, drain); object field2 = GetField(val2, "gunMuzzle"); Transform val3 = (Transform)((field2 is Transform) ? field2 : null); if (Object.op_Implicit((Object)(object)val3)) { SafeInvokeSound(val2, "soundShoot", val3.position); SafeInvokeSound(val2, "soundShootGlobal", val3.position); SafeCall(val2, "MuzzleFlash"); SafeCall(val2, "StartTriggerAnimation"); } } [PunRPC] public void Empress_BulletResult(Vector3 endPos, bool hit, PhotonMessageInfo info) { //IL_0099: Unknown result type (might be due to invalid IL or missing references) if (!PhotonNetwork.IsMasterClient) { return; } PhotonView val = ResolvePV((Component)(object)this); if (Object.op_Implicit((Object)(object)val)) { ClearPending(val); } Type type = AccessTools.TypeByName("ItemGun"); Component val2 = ((type != null) ? ((Component)this).GetComponent(type) : null); if ((Object)(object)val2 == (Object)null) { return; } MethodInfo methodInfo = AccessTools.Method(type, "ShootBullet", new Type[2] { typeof(Vector3), typeof(bool) }, (Type[])null); try { methodInfo?.Invoke(val2, new object[2] { endPos, hit }); } catch (Exception arg) { ManualLogSource logS = LogS; if (logS != null) { logS.LogError((object)$"ShootBullet invoke failed: {arg}"); } } } [PunRPC] public void Empress_CancelGuideClient(PhotonMessageInfo _) { GuidedBulletController[] array = Object.FindObjectsOfType<GuidedBulletController>(); foreach (GuidedBulletController guidedBulletController in array) { guidedBulletController.CancelFromMaster(); } } public static void SetPendingLocal(PhotonView pv, object gun, bool fullBar, int bars, float drain, Transform muzzle) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)pv) && gun != null) { MarkPendingGuided(pv); object field = GetField(gun, "itemBattery"); ApplyBatteryDrain(field, fullBar, bars, drain); if (Object.op_Implicit((Object)(object)muzzle)) { SafeInvokeSound(gun, "soundShoot", muzzle.position); SafeInvokeSound(gun, "soundShootGlobal", muzzle.position); SafeCall(gun, "MuzzleFlash"); SafeCall(gun, "StartTriggerAnimation"); } } } } private sealed class GuidedBulletController : MonoBehaviour { private object _gun; private PhotonView _gunPV; private GameObject _projGo; private Vector3 _startPos; private float _speed; private float _turnDegPerSec; private float _hitRadius; private float _maxDistance; private int _hitMask = -5; private Camera _mainCam; private Camera _guidedCam; private RenderTexture _rt; private GameObject _uiCanvasGo; private RawImage _uiImage; private float _deadlineRealtime; private KeyCode _cancelKey; private bool _active; private bool _suppressSend; public void Init(object ownerGun, PhotonView ownerPV, Vector3 startPos, Vector3 startDir, float speed, float turnDegPerSec, float fov, KeyCode cancelKey, float timeScaleTarget, float maxGuideSeconds, float hitSphereRadius, float maxDistanceUnits) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0011: 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_0039: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Expected O, but got Unknown //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) _gun = ownerGun; _gunPV = ownerPV; _startPos = startPos; _speed = speed; _turnDegPerSec = turnDegPerSec; _hitRadius = hitSphereRadius; _maxDistance = maxDistanceUnits; _cancelKey = cancelKey; _mainCam = ResolveMainCam(); if ((Object)(object)_mainCam == (Object)null) { ManualLogSource logS = LogS; if (logS != null) { logS.LogError((object)"[GuidedBulletCam] No main camera; abort."); } Object.Destroy((Object)(object)((Component)this).gameObject); return; } Type type = AccessTools.TypeByName("SemiFunc"); if (type != null) { MethodInfo methodInfo = AccessTools.Method(type, "LayerMaskGetVisionObstruct", (Type[])null, (Type[])null); if (methodInfo != null && methodInfo.GetParameters().Length == 0) { try { _hitMask = (int)methodInfo.Invoke(null, null); } catch { } } } try { _hitMask |= LayerMask.GetMask(new string[1] { "Enemy" }); } catch { } _projGo = new GameObject("Empress_GuidedProjectile"); _projGo.transform.SetPositionAndRotation(startPos, Quaternion.LookRotation(startDir, Vector3.up)); Rigidbody val = _projGo.AddComponent<Rigidbody>(); val.isKinematic = true; CapsuleCollider val2 = _projGo.AddComponent<CapsuleCollider>(); ((Collider)val2).isTrigger = true; val2.radius = Mathf.Max(0.01f, hitSphereRadius); val2.height = val2.radius * 2f; val2.direction = 2; TrailRenderer val3 = _projGo.AddComponent<TrailRenderer>(); val3.time = 0.25f; val3.minVertexDistance = 0.01f; val3.startWidth = 0.02f; val3.endWidth = 0f; SetupOverlayCameraAndUI(fov); Time.timeScale = timeScaleTarget; Time.fixedDeltaTime = BaselineFixedDelta * Time.timeScale; _deadlineRealtime = Time.realtimeSinceStartup + maxGuideSeconds; SceneManager.activeSceneChanged += OnSceneChanged; TimeGuard.Arm(maxGuideSeconds + 0.5f); IsGuiding = true; _active = true; } private Camera ResolveMainCam() { if (Object.op_Implicit((Object)(object)Camera.main)) { return Camera.main; } Type type = AccessTools.TypeByName("CameraUtils"); if (type != null) { object obj = AccessTools.Field(type, "Instance")?.GetValue(null); if (obj != null) { object? obj2 = AccessTools.Field(type, "MainCamera")?.GetValue(obj); Camera val = (Camera)((obj2 is Camera) ? obj2 : null); if (Object.op_Implicit((Object)(object)val)) { return val; } } } Camera[] array = Object.FindObjectsOfType<Camera>(); foreach (Camera val2 in array) { if (((Behaviour)val2).enabled) { return val2; } } return null; } private void SetupOverlayCameraAndUI(float fov) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Expected O, but got Unknown //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Expected O, but got Unknown //IL_01d4: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_01fe: Expected O, but got Unknown //IL_0252: Unknown result type (might be due to invalid IL or missing references) //IL_025f: Unknown result type (might be due to invalid IL or missing references) //IL_026c: Unknown result type (might be due to invalid IL or missing references) //IL_0279: Unknown result type (might be due to invalid IL or missing references) int num = Mathf.Max(16, Screen.width); int num2 = Mathf.Max(16, Screen.height); _rt = new RenderTexture(num, num2, 24, (RenderTextureFormat)7) { useMipMap = false, autoGenerateMips = false }; _rt.Create(); GameObject val = new GameObject("Empress_GuidedCam"); _guidedCam = val.AddComponent<Camera>(); Object.DontDestroyOnLoad((Object)(object)val); _guidedCam.CopyFrom(_mainCam); _guidedCam.fieldOfView = fov; ((Component)_guidedCam).transform.position = _projGo.transform.position - _projGo.transform.forward * 0.25f + Vector3.up * 0.02f; ((Component)_guidedCam).transform.rotation = Quaternion.LookRotation(_projGo.transform.forward, Vector3.up); AudioListener component = val.GetComponent<AudioListener>(); if (Object.op_Implicit((Object)(object)component)) { Object.Destroy((Object)(object)component); } _guidedCam.targetTexture = _rt; _guidedCam.depth = _mainCam.depth + 1000f; _uiCanvasGo = new GameObject("Empress_GuidedCanvas", new Type[3] { typeof(Canvas), typeof(CanvasScaler), typeof(GraphicRaycaster) }); Object.DontDestroyOnLoad((Object)(object)_uiCanvasGo); Canvas component2 = _uiCanvasGo.GetComponent<Canvas>(); component2.renderMode = (RenderMode)0; component2.sortingOrder = 32767; CanvasScaler component3 = _uiCanvasGo.GetComponent<CanvasScaler>(); component3.uiScaleMode = (ScaleMode)1; component3.referenceResolution = new Vector2((float)num, (float)num2); GameObject val2 = new GameObject("Empress_GuidedImage", new Type[1] { typeof(RawImage) }); val2.transform.SetParent(_uiCanvasGo.transform, false); _uiImage = val2.GetComponent<RawImage>(); _uiImage.texture = (Texture)(object)_rt; ((Graphic)_uiImage).raycastTarget = false; RectTransform rectTransform = ((Graphic)_uiImage).rectTransform; rectTransform.anchorMin = Vector2.zero; rectTransform.anchorMax = Vector2.one; rectTransform.offsetMin = Vector2.zero; rectTransform.offsetMax = Vector2.zero; } private void LateUpdate() { //IL_004a: 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) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_0203: Unknown result type (might be due to invalid IL or missing references) //IL_0208: Unknown result type (might be due to invalid IL or missing references) //IL_020a: Unknown result type (might be due to invalid IL or missing references) //IL_0220: Unknown result type (might be due to invalid IL or missing references) //IL_0226: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_024f: Unknown result type (might be due to invalid IL or missing references) //IL_027f: Unknown result type (might be due to invalid IL or missing references) //IL_0284: Unknown result type (might be due to invalid IL or missing references) //IL_028b: Unknown result type (might be due to invalid IL or missing references) //IL_0290: Unknown result type (might be due to invalid IL or missing references) //IL_0295: Unknown result type (might be due to invalid IL or missing references) //IL_029f: Unknown result type (might be due to invalid IL or missing references) //IL_02a4: Unknown result type (might be due to invalid IL or missing references) //IL_02a9: Unknown result type (might be due to invalid IL or missing references) //IL_02c1: Unknown result type (might be due to invalid IL or missing references) //IL_02c6: Unknown result type (might be due to invalid IL or missing references) //IL_02cd: Unknown result type (might be due to invalid IL or missing references) //IL_02ee: Unknown result type (might be due to invalid IL or missing references) //IL_02f3: Unknown result type (might be due to invalid IL or missing references) //IL_02f5: Unknown result type (might be due to invalid IL or missing references) //IL_02fa: Unknown result type (might be due to invalid IL or missing references) //IL_0304: Unknown result type (might be due to invalid IL or missing references) if (!_active) { return; } if (Time.realtimeSinceStartup >= _deadlineRealtime) { FinishAndSend(hit: false, _projGo.transform.position); return; } if (Input.GetKeyDown(_cancelKey)) { FinishAndSend(hit: false, _projGo.transform.position); return; } float axisRaw = Input.GetAxisRaw("Mouse X"); float axisRaw2 = Input.GetAxisRaw("Mouse Y"); float num = axisRaw + (Input.GetKey((KeyCode)100) ? 0.5f : 0f) - (Input.GetKey((KeyCode)97) ? 0.5f : 0f); float num2 = 0f - axisRaw2 + (Input.GetKey((KeyCode)119) ? 0.5f : 0f) - (Input.GetKey((KeyCode)115) ? 0.5f : 0f); float num3 = _turnDegPerSec * Time.unscaledDeltaTime; Quaternion val = Quaternion.AngleAxis(num * num3, Vector3.up) * Quaternion.AngleAxis(num2 * num3, Vector3.right); _projGo.transform.rotation = val * _projGo.transform.rotation; Vector3 forward = _projGo.transform.forward; Vector3 val2 = forward * _speed * Time.deltaTime; float num4 = Mathf.Max(0.001f, ((Vector3)(ref val2)).magnitude + 0.05f); RaycastHit val3 = default(RaycastHit); if (Physics.SphereCast(_projGo.transform.position, (_hitRadius > 0.001f) ? _hitRadius : 0.01f, forward, ref val3, num4, _hitMask, (QueryTriggerInteraction)1)) { _projGo.transform.position = ((RaycastHit)(ref val3)).point; FinishAndSend(hit: true, ((RaycastHit)(ref val3)).point); return; } Transform transform = _projGo.transform; transform.position += val2; if (Vector3.Distance(_projGo.transform.position, _startPos) >= _maxDistance) { FinishAndSend(hit: false, _projGo.transform.position); } else if (Object.op_Implicit((Object)(object)_guidedCam)) { Vector3 val4 = _projGo.transform.position - forward * 0.25f + Vector3.up * 0.02f; ((Component)_guidedCam).transform.position = Vector3.Lerp(((Component)_guidedCam).transform.position, val4, 0.6f); ((Component)_guidedCam).transform.rotation = Quaternion.Slerp(((Component)_guidedCam).transform.rotation, Quaternion.LookRotation(forward, Vector3.up), 0.6f); } } public void CancelFromMaster() { _suppressSend = true; try { Time.timeScale = BaselineTimeScale; Time.fixedDeltaTime = BaselineFixedDelta; } catch { } Cleanup(); } private void FinishAndSend(bool hit, Vector3 finalPos) { //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) try { Time.timeScale = BaselineTimeScale; Time.fixedDeltaTime = BaselineFixedDelta; } catch { } try { if (!_suppressSend) { if ((Object)(object)_gunPV != (Object)null && _gunPV.ViewID != 0 && PhotonNetwork.IsConnected) { _gunPV.RPC("Empress_BulletResult", (RpcTarget)2, new object[2] { finalPos, hit }); } else { Type type = _gun.GetType(); AccessTools.Method(type, "ShootBullet", new Type[2] { typeof(Vector3), typeof(bool) }, (Type[])null)?.Invoke(_gun, new object[2] { finalPos, hit }); } } } catch (Exception arg) { ManualLogSource logS = LogS; if (logS != null) { logS.LogError((object)$"Finish send failed: {arg}"); } } Cleanup(); } private void OnSceneChanged(Scene a, Scene b) { Cleanup(); } private void OnDisable() { Cleanup(); } private void OnDestroy() { Cleanup(); } private void Cleanup() { if (!_active) { return; } _active = false; SceneManager.activeSceneChanged -= OnSceneChanged; TimeGuard.Disarm(); IsGuiding = false; try { if (Object.op_Implicit((Object)(object)_guidedCam)) { _guidedCam.targetTexture = null; Object.Destroy((Object)(object)((Component)_guidedCam).gameObject); } } catch { } try { if (Object.op_Implicit((Object)(object)_uiImage)) { _uiImage.texture = null; } if (Object.op_Implicit((Object)(object)_uiCanvasGo)) { Object.Destroy((Object)(object)_uiCanvasGo); } } catch { } try { if (Object.op_Implicit((Object)(object)_rt)) { _rt.Release(); Object.Destroy((Object)(object)_rt); } } catch { } if (Object.op_Implicit((Object)(object)_projGo)) { Object.Destroy((Object)(object)_projGo); } Object.Destroy((Object)(object)((Component)this).gameObject); } } public const string PluginGuid = "empress.repogame.guidedbulletcam"; public const string PluginName = "Guided Bullet Camera"; public const string PluginVersion = "2.1.0"; internal static ManualLogSource LogS; internal static ConfigEntry<bool> CfgEnabled; internal static ConfigEntry<KeyCode> CfgCancelKey; internal static ConfigEntry<float> CfgTimeScale; internal static ConfigEntry<float> CfgFov; internal static ConfigEntry<float> CfgBulletSpeed; internal static ConfigEntry<float> CfgTurnRateDeg; internal static ConfigEntry<float> CfgHitRadius; internal static ConfigEntry<float> CfgMaxGuideSeconds; internal static ConfigEntry<float> CfgMaxDistance; internal static float BaselineTimeScale = 1f; internal static float BaselineFixedDelta = 0.02f; internal static volatile bool IsGuiding; private static readonly HashSet<int> PendingGuided = new HashSet<int>(); private Harmony _harmony; private void Awake() { //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Expected O, but got Unknown //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: Expected O, but got Unknown //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Expected O, but got Unknown LogS = ((BaseUnityPlugin)this).Logger; BaselineTimeScale = Time.timeScale; BaselineFixedDelta = Time.fixedDeltaTime; CfgEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Master toggle."); CfgCancelKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Controls", "CancelKey", (KeyCode)27, "Abort guiding."); CfgTimeScale = ((BaseUnityPlugin)this).Config.Bind<float>("Camera", "TimeScaleDuringGuide", 0.08f, "Local Time.timeScale during guide."); CfgFov = ((BaseUnityPlugin)this).Config.Bind<float>("Camera", "CameraFOV", 45f, "Overlay camera FOV."); CfgBulletSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Projectile", "SpeedUnitsPerSec", 70f, "Projectile speed (u/s)."); CfgTurnRateDeg = ((BaseUnityPlugin)this).Config.Bind<float>("Projectile", "TurnRateDegPerSec", 240f, "Turn rate (deg/s)."); CfgHitRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Projectile", "HitSphereRadius", 0.05f, "Spherecast radius."); CfgMaxGuideSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Safety", "MaxGuideSeconds", 3f, "Realtime hard cap for a guided shot."); CfgMaxDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Safety", "MaxDistanceUnits", 500f, "Auto-restore after projectile travels this far."); _harmony = new Harmony("empress.repogame.guidedbulletcam"); _harmony.PatchAll(typeof(ItemGunStartInjector)); _harmony.PatchAll(typeof(ItemToggleHooks)); _harmony.PatchAll(typeof(ShootRpcMasterSkipper)); GameObject val = new GameObject("Empress_TimeGuard"); Object.DontDestroyOnLoad((Object)(object)val); val.AddComponent<TimeGuard>(); GameObject val2 = new GameObject("Empress_GuidedCam_Handshake"); Object.DontDestroyOnLoad((Object)(object)val2); ((Object)val2).hideFlags = (HideFlags)52; val2.AddComponent<GuidedCamHandshakeRouter>(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Guided Bullet Camera v2.1.0 loaded."); } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } internal static bool IsLevelReady() { return GuidedCamHandshakeRouter.CanUseModNow(); } private static PhotonView ResolvePV(Component c) { if (!Object.op_Implicit((Object)(object)c)) { return null; } PhotonView component = c.GetComponent<PhotonView>(); if (Object.op_Implicit((Object)(object)component)) { return component; } component = c.GetComponentInParent<PhotonView>(); if (Object.op_Implicit((Object)(object)component)) { return component; } return c.GetComponentInChildren<PhotonView>(); } private static bool IsPendingGuided(PhotonView pv) { return Object.op_Implicit((Object)(object)pv) && PendingGuided.Contains(pv.ViewID); } private static void MarkPendingGuided(PhotonView pv) { if (Object.op_Implicit((Object)(object)pv)) { PendingGuided.Add(pv.ViewID); } } private static void ClearPending(PhotonView pv) { if (Object.op_Implicit((Object)(object)pv)) { PendingGuided.Remove(pv.ViewID); } } private static object GetField(object obj, string name) { if (obj == null) { return null; } return AccessTools.Field(obj.GetType(), name)?.GetValue(obj); } private static void SafeInvokeSound(object gun, string fieldName, Vector3 pos) { //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) try { object obj = AccessTools.Field(gun.GetType(), fieldName)?.GetValue(gun); if (obj == null) { return; } MethodInfo methodInfo = AccessTools.Method(obj.GetType(), "Play", new Type[5] { typeof(Vector3), typeof(float), typeof(float), typeof(float), typeof(float) }, (Type[])null); if (methodInfo != null) { methodInfo.Invoke(obj, new object[5] { pos, 1f, 1f, 1f, 1f }); return; } foreach (MethodInfo declaredMethod in AccessTools.GetDeclaredMethods(obj.GetType())) { if (declaredMethod.Name != "Play") { continue; } ParameterInfo[] parameters = declaredMethod.GetParameters(); if (parameters.Length < 1 || !(parameters[0].ParameterType == typeof(Vector3))) { continue; } object[] array = new object[parameters.Length]; array[0] = pos; for (int i = 1; i < parameters.Length; i++) { array[i] = ((parameters[i].ParameterType == typeof(float)) ? ((object)1f) : Type.Missing); } declaredMethod.Invoke(obj, array); break; } } catch { } } private static void SafeCall(object obj, string method) { MethodInfo methodInfo = AccessTools.Method(obj.GetType(), method, (Type[])null, (Type[])null); try { methodInfo?.Invoke(obj, null); } catch { } } private static bool HasAmmo(object gun) { object field = GetField(gun, "itemBattery"); if (field == null) { return false; } FieldInfo fieldInfo = AccessTools.Field(field.GetType(), "batteryLifeInt"); if (fieldInfo == null) { return false; } int num = (int)fieldInfo.GetValue(field); return num > 0; } internal static void ApplyBatteryDrain(object itemBattery, bool fullBar, int bars, float drain) { if (itemBattery == null) { return; } try { if (!fullBar) { FieldInfo fieldInfo = AccessTools.Field(itemBattery.GetType(), "batteryLife"); if (fieldInfo != null) { float num = (float)fieldInfo.GetValue(itemBattery); fieldInfo.SetValue(itemBattery, Mathf.Max(0f, num - drain)); FieldInfo fieldInfo2 = AccessTools.Field(itemBattery.GetType(), "batteryLifeInt"); if (fieldInfo2 != null) { FieldInfo fieldInfo3 = AccessTools.Field(itemBattery.GetType(), "batteryBars"); int num2 = ((fieldInfo3 != null) ? ((int)fieldInfo3.GetValue(itemBattery)) : 6); int num3 = Mathf.Clamp(Mathf.RoundToInt((float)fieldInfo.GetValue(itemBattery) / (100f / (float)Mathf.Max(1, num2))), 0, num2); fieldInfo2.SetValue(itemBattery, num3); } MethodInfo methodInfo = AccessTools.Method(itemBattery.GetType(), "BatteryFullPercentChange", new Type[2] { typeof(int), typeof(bool) }, (Type[])null); FieldInfo fieldInfo4 = AccessTools.Field(itemBattery.GetType(), "batteryLifeInt"); if (methodInfo != null && fieldInfo4 != null) { methodInfo.Invoke(itemBattery, new object[2] { (int)fieldInfo4.GetValue(itemBattery), false }); } } } else { AccessTools.Method(itemBattery.GetType(), "RemoveFullBar", new Type[1] { typeof(int) }, (Type[])null)?.Invoke(itemBattery, new object[1] { bars }); } } catch (Exception arg) { ManualLogSource logS = LogS; if (logS != null) { logS.LogWarning((object)$"Battery drain apply failed: {arg}"); } } } } } namespace BulletControl { [BepInPlugin("Omniscye.BulletControl", "BulletControl", "1.0")] public class BulletControl : BaseUnityPlugin { internal static BulletControl Instance { get; private set; } internal static ManualLogSource Logger => Instance._logger; private ManualLogSource _logger => ((BaseUnityPlugin)this).Logger; internal Harmony? Harmony { get; set; } private void Awake() { Instance = this; ((Component)this).gameObject.transform.parent = null; ((Object)((Component)this).gameObject).hideFlags = (HideFlags)61; Patch(); Logger.LogInfo((object)$"{((BaseUnityPlugin)this).Info.Metadata.GUID} v{((BaseUnityPlugin)this).Info.Metadata.Version} has loaded!"); } internal void Patch() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown //IL_0026: Expected O, but got Unknown if (Harmony == null) { Harmony val = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID); Harmony val2 = val; Harmony = val; } Harmony.PatchAll(); } internal void Unpatch() { Harmony? harmony = Harmony; if (harmony != null) { harmony.UnpatchSelf(); } } private void Update() { } } }