using System;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Logging;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.SceneManagement;
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: CompilationRelaxations(8)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace HowToFishFlyingBoat;
[BepInPlugin("chadi7bark.howtofish.flyingboat", "Skyboat Bomber", "0.5.4")]
[BepInProcess("How to Fish.exe")]
public sealed class FlyingBoatMod : BaseUnityPlugin
{
private sealed class PendingBomb
{
public Component Explosive;
public object PlayerWhoDropped;
public float DetonateAt;
}
private const float RiseSpeed = 12f;
private const float DescendSpeed = 9f;
private const float VerticalAcceleration = 28f;
private const float HoverAcceleration = 18f;
private const float MaximumFlightSpeed = 50f;
private const float EngineAcceleration = 15f;
private const float BrakingAcceleration = 20f;
private const float VelocityAlignment = 3.5f;
private const float ThrottleIncreasePerSecond = 0.35f;
private const float ThrottleDecreasePerSecond = 0.45f;
private const float MouseFollowDegreesPerSecond = 85f;
private const float MaximumAimPitchDegrees = 65f;
private const float RollDegreesPerSecond = 115f;
private const float RollAutoLevelDegreesPerSecond = 55f;
private const float MouseSensitivity = 0.11f;
private const float ThirdPersonDistance = 11f;
private const float ThirdPersonHeight = 4f;
private const float ThirdPersonPivotHeight = 1.5f;
private const float CameraPitchDownDegrees = 8f;
private const int CarpetBombCount = 10;
private const float CarpetBombInterval = 0.14f;
private const float CarpetBombCooldown = 3f;
private const float CarpetBombFuseSeconds = 3.5f;
private const float CarpetBombDropDistance = 2.2f;
private const float CarpetBombSideSpread = 3.2f;
private const float CarpetBombDownSpeed = 8f;
private Type _boatType;
private Component _activeBoat;
private Rigidbody _physicsRig;
private bool _flightEnabled;
private bool _savedUseGravity;
private float _savedDrag;
private float _savedAngularDrag;
private RigidbodyConstraints _savedConstraints;
private float _nextTypeSearchTime;
private float _nextMissingBoatMessageTime;
private float _throttle;
private float _manualRollAngle;
private float _aimYaw;
private float _aimPitch;
private Vector3 _mouseAimDirection;
private Camera _flightCamera;
private Vector3 _savedCameraPosition;
private Quaternion _savedCameraRotation;
private bool _cameraStateSaved;
private bool _cameraPreCullHooked;
private Type _itemManagerType;
private Type _explosiveType;
private Type _serverType;
private MethodInfo _spawnNewItemMethod;
private MethodInfo _activateExplosiveMethod;
private MethodInfo _setItemHolderMethod;
private MethodInfo _handOverItemSimulationMethod;
private Component _dynamitePrefab;
private bool _bombBarrageActive;
private int _bombsRemaining;
private float _nextBombDropTime;
private float _nextBombBarrageAllowedTime;
private bool _loggedForcedSpawnThisBarrage;
private readonly List<PendingBomb> _pendingBombs = new List<PendingBomb>();
private void Awake()
{
PluginLog.Bind(((BaseUnityPlugin)this).Logger);
ResolveBoatType();
ResolveBombingSystems();
PluginLog.Msg("Flying Boat v0.5.4 loaded.");
PluginLog.Msg("F6 = flight + fixed third-person chase camera | mouse aim = point the bow | W/S = throttle | A/D = roll only | Space/Ctrl = rise/descend");
PluginLog.Msg("LEFT CLICK = drop a 10-dynamite carpet-bomb barrage while flight is active.");
PluginLog.Msg("Flight requires the local player to be the current boat driver and stops immediately when the driver seat is left.");
PluginLog.Msg("Flying and carpet bombing are authoritative in solo games and for the host. The Item Spawner force-release route is embedded; no Item Spawner dependency is used.");
LogBombingRouteStatus();
}
private void OnDestroy()
{
DisableFlight(null);
_pendingBombs.Clear();
}
private void Update()
{
try
{
if (_boatType == null && Time.unscaledTime >= _nextTypeSearchTime)
{
_nextTypeSearchTime = Time.unscaledTime + 2f;
ResolveBoatType();
}
if (Input.GetKeyDown((KeyCode)287))
{
if (_flightEnabled)
{
DisableFlight("Flight disabled. Gravity restored.");
}
else
{
TryEnableFlight();
}
}
if (_flightEnabled && !IsActiveBoatStillValid())
{
DisableFlight("Flight disabled because you left the driver seat or changed boats.");
}
if (_flightEnabled)
{
UpdateMouseAim();
if (Mouse.current != null && Mouse.current.leftButton.wasPressedThisFrame)
{
TryStartCarpetBombBarrage();
}
UpdateCarpetBombBarrage();
}
UpdatePendingBombs();
}
catch (Exception ex)
{
PluginLog.Error("Flying Boat update error: " + ex);
DisableFlight("Flight disabled after an update error.");
}
}
private void FixedUpdate()
{
if (!_flightEnabled || (Object)(object)_physicsRig == (Object)null)
{
return;
}
try
{
ApplyFlightPhysics();
}
catch (Exception ex)
{
PluginLog.Error("Flying Boat physics error: " + ex);
DisableFlight("Flight disabled after a physics error.");
}
}
private void LateUpdate()
{
if (!_flightEnabled)
{
return;
}
try
{
UpdateThirdPersonCamera();
}
catch (Exception ex)
{
PluginLog.Warning("Third-person camera update failed: " + ex.GetType().Name);
}
}
private void TryEnableFlight()
{
//IL_0100: Unknown result type (might be due to invalid IL or missing references)
//IL_0105: Unknown result type (might be due to invalid IL or missing references)
//IL_0141: Unknown result type (might be due to invalid IL or missing references)
//IL_0151: Unknown result type (might be due to invalid IL or missing references)
if (_boatType == null)
{
ResolveBoatType();
if (_boatType == null)
{
PluginLog.Warning("The game's Boat type is not loaded yet. Enter the playable world and try F6 again.");
return;
}
}
Component val = FindLocallyDrivenBoat();
if ((Object)(object)val == (Object)null)
{
if (Time.unscaledTime >= _nextMissingBoatMessageTime)
{
_nextMissingBoatMessageTime = Time.unscaledTime + 1f;
PluginLog.Warning("Flight was not enabled: you must be sitting in the driver seat, then press F6.");
}
return;
}
if (IsClientOnly(val))
{
PluginLog.Warning("Flight was not enabled: this first build requires solo play or the host. A client-only boat would be corrected by the server.");
return;
}
object obj = ReadMember(val, "HiddenPhysicsRig");
Rigidbody val2 = (Rigidbody)((obj is Rigidbody) ? obj : null);
if ((Object)(object)val2 == (Object)null)
{
object obj2 = ReadMember(val, "<HiddenPhysicsRig>k__BackingField");
val2 = (Rigidbody)((obj2 is Rigidbody) ? obj2 : null);
}
if ((Object)(object)val2 == (Object)null)
{
PluginLog.Warning("The current boat's HiddenPhysicsRig was not found.");
return;
}
_activeBoat = val;
_physicsRig = val2;
_savedUseGravity = _physicsRig.useGravity;
_savedDrag = _physicsRig.drag;
_savedAngularDrag = _physicsRig.angularDrag;
_savedConstraints = _physicsRig.constraints;
_physicsRig.useGravity = false;
_physicsRig.drag = 0.2f;
_physicsRig.angularDrag = 2.5f;
float num = Mathf.Max(0f, Vector3.Dot(_physicsRig.velocity, ((Component)_physicsRig).transform.forward));
_throttle = Mathf.Clamp01(num / 50f);
_manualRollAngle = 0f;
_flightEnabled = true;
BeginThirdPersonCamera();
PluginLog.Msg("FLIGHT ENABLED: fixed third-person chase view active. Mouse aims the bow; W/S change throttle; A/D roll only.");
}
private void DisableFlight(string message)
{
//IL_0048: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)_physicsRig != (Object)null)
{
try
{
_physicsRig.useGravity = _savedUseGravity;
_physicsRig.drag = _savedDrag;
_physicsRig.angularDrag = _savedAngularDrag;
_physicsRig.constraints = _savedConstraints;
}
catch
{
}
}
bool flightEnabled = _flightEnabled;
EndThirdPersonCamera();
_flightEnabled = false;
_activeBoat = null;
_physicsRig = null;
_throttle = 0f;
_manualRollAngle = 0f;
_bombBarrageActive = false;
_bombsRemaining = 0;
if (flightEnabled && !string.IsNullOrEmpty(message))
{
PluginLog.Msg(message);
}
}
private void ApplyFlightPhysics()
{
//IL_0111: Unknown result type (might be due to invalid IL or missing references)
//IL_0116: Unknown result type (might be due to invalid IL or missing references)
//IL_0117: Unknown result type (might be due to invalid IL or missing references)
//IL_0118: Unknown result type (might be due to invalid IL or missing references)
//IL_011d: Unknown result type (might be due to invalid IL or missing references)
//IL_0122: Unknown result type (might be due to invalid IL or missing references)
//IL_0129: Unknown result type (might be due to invalid IL or missing references)
//IL_012e: Unknown result type (might be due to invalid IL or missing references)
//IL_0133: Unknown result type (might be due to invalid IL or missing references)
//IL_0135: Unknown result type (might be due to invalid IL or missing references)
//IL_0136: Unknown result type (might be due to invalid IL or missing references)
//IL_0138: Unknown result type (might be due to invalid IL or missing references)
//IL_013d: Unknown result type (might be due to invalid IL or missing references)
//IL_0145: Unknown result type (might be due to invalid IL or missing references)
//IL_014a: Unknown result type (might be due to invalid IL or missing references)
//IL_0153: Unknown result type (might be due to invalid IL or missing references)
//IL_0158: Unknown result type (might be due to invalid IL or missing references)
//IL_0160: Unknown result type (might be due to invalid IL or missing references)
//IL_0167: Unknown result type (might be due to invalid IL or missing references)
//IL_0169: Unknown result type (might be due to invalid IL or missing references)
//IL_016e: Unknown result type (might be due to invalid IL or missing references)
//IL_0173: Unknown result type (might be due to invalid IL or missing references)
//IL_017b: Unknown result type (might be due to invalid IL or missing references)
//IL_0180: Unknown result type (might be due to invalid IL or missing references)
//IL_0182: Unknown result type (might be due to invalid IL or missing references)
//IL_0184: Unknown result type (might be due to invalid IL or missing references)
//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
//IL_01f5: 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_01fc: 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_02d3: Unknown result type (might be due to invalid IL or missing references)
//IL_02af: Unknown result type (might be due to invalid IL or missing references)
//IL_02b9: Unknown result type (might be due to invalid IL or missing references)
//IL_02be: Unknown result type (might be due to invalid IL or missing references)
float num = Mathf.Max(Time.fixedDeltaTime, 0.001f);
if (Input.GetKey((KeyCode)119) || Input.GetKey((KeyCode)273))
{
_throttle = Mathf.Clamp01(_throttle + 0.35f * num);
}
if (Input.GetKey((KeyCode)115) || Input.GetKey((KeyCode)274))
{
_throttle = Mathf.Clamp01(_throttle - 0.45f * num);
}
float num2 = 0f;
if (Input.GetKey((KeyCode)97) || Input.GetKey((KeyCode)276))
{
num2 -= 1f;
}
if (Input.GetKey((KeyCode)100) || Input.GetKey((KeyCode)275))
{
num2 += 1f;
}
if (Mathf.Abs(num2) > 0.01f)
{
_manualRollAngle -= num2 * 115f * num;
_manualRollAngle = Mathf.Repeat(_manualRollAngle + 180f, 360f) - 180f;
}
else
{
_manualRollAngle = Mathf.MoveTowardsAngle(_manualRollAngle, 0f, 55f * num);
}
Vector3 mouseAimDirection = GetMouseAimDirection();
Quaternion val = Quaternion.LookRotation(mouseAimDirection, Vector3.up);
Quaternion val2 = Quaternion.AngleAxis(_manualRollAngle, Vector3.forward);
Quaternion val3 = val * val2;
Quaternion val4 = Quaternion.RotateTowards(_physicsRig.rotation, val3, 85f * num);
_physicsRig.MoveRotation(val4);
Vector3 val5 = val4 * Vector3.forward;
Vector3 val6 = _physicsRig.velocity;
float num3 = Vector3.Dot(val6, val5);
float num4 = _throttle * 50f;
float num5 = ((num4 >= num3) ? (15f * num) : (20f * num));
float num6 = Mathf.MoveTowards(num3, num4, num5);
Vector3 val7 = val6 - val5 * num3;
val7 = Vector3.Lerp(val7, Vector3.zero, Mathf.Clamp01(3.5f * num));
val6 = val5 * num6 + val7;
float num7 = 0f;
bool key = Input.GetKey((KeyCode)32);
bool flag = Input.GetKey((KeyCode)306) || Input.GetKey((KeyCode)305);
if (key && !flag)
{
num7 = 12f;
}
else if (flag && !key)
{
num7 = -9f;
}
if (key || flag)
{
float num8 = 28f * num;
val6.y = Mathf.MoveTowards(val6.y, num7, num8);
}
else if (_throttle < 0.02f)
{
val6.y = Mathf.MoveTowards(val6.y, 0f, 18f * num);
}
if (((Vector3)(ref val6)).magnitude > 55f)
{
val6 = ((Vector3)(ref val6)).normalized * 55f;
}
_physicsRig.velocity = val6;
_physicsRig.angularVelocity = Vector3.zero;
}
private Vector3 GetMouseAimDirection()
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0049: Unknown result type (might be due to invalid IL or missing references)
//IL_004e: 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_0023: Unknown result type (might be due to invalid IL or missing references)
//IL_0104: Unknown result type (might be due to invalid IL or missing references)
//IL_0107: Unknown result type (might be due to invalid IL or missing references)
//IL_010c: 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_0117: Unknown result type (might be due to invalid IL or missing references)
//IL_011c: Unknown result type (might be due to invalid IL or missing references)
//IL_0120: Unknown result type (might be due to invalid IL or missing references)
//IL_003a: 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_00d3: Unknown result type (might be due to invalid IL or missing references)
//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
Vector3 val = _mouseAimDirection;
if (((Vector3)(ref val)).sqrMagnitude < 0.001f)
{
val = (((Object)(object)_physicsRig != (Object)null) ? ((Component)_physicsRig).transform.forward : Vector3.forward);
}
if (((Vector3)(ref val)).sqrMagnitude < 0.001f)
{
val = Vector3.forward;
}
((Vector3)(ref val)).Normalize();
float num = Mathf.Sin((float)Math.PI * 13f / 36f);
float num2 = Mathf.Clamp(val.y, 0f - num, num);
Vector3 val2 = default(Vector3);
((Vector3)(ref val2))..ctor(val.x, 0f, val.z);
if (((Vector3)(ref val2)).sqrMagnitude < 0.001f)
{
val2 = (Vector3)(((Object)(object)_physicsRig != (Object)null) ? new Vector3(((Component)_physicsRig).transform.forward.x, 0f, ((Component)_physicsRig).transform.forward.z) : Vector3.forward);
}
((Vector3)(ref val2)).Normalize();
float num3 = Mathf.Sqrt(Mathf.Max(0f, 1f - num2 * num2));
Vector3 val3 = val2 * num3 + Vector3.up * num2;
return ((Vector3)(ref val3)).normalized;
}
private void BeginThirdPersonCamera()
{
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
HookCameraPreCull();
if (!TryAcquireFlightCamera())
{
PluginLog.Warning("Flight enabled, but no active game camera was available for third-person view.");
InitializeAimFromDirection(((Component)_physicsRig).transform.forward);
}
else
{
InitializeAimFromDirection(((Component)_physicsRig).transform.forward);
UpdateThirdPersonCamera();
PluginLog.Msg("Fixed third-person chase camera enabled.");
}
}
private void EndThirdPersonCamera()
{
//IL_005c: Unknown result type (might be due to invalid IL or missing references)
//IL_0061: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
//IL_003e: Unknown result type (might be due to invalid IL or missing references)
UnhookCameraPreCull();
if ((Object)(object)_flightCamera != (Object)null && _cameraStateSaved)
{
try
{
((Component)_flightCamera).transform.position = _savedCameraPosition;
((Component)_flightCamera).transform.rotation = _savedCameraRotation;
}
catch
{
}
}
_flightCamera = null;
_cameraStateSaved = false;
_mouseAimDirection = Vector3.zero;
}
private void InitializeAimFromDirection(Vector3 direction)
{
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
if (((Vector3)(ref direction)).sqrMagnitude < 0.001f)
{
direction = Vector3.forward;
}
((Vector3)(ref direction)).Normalize();
_aimYaw = Mathf.Atan2(direction.x, direction.z) * 57.29578f;
_aimPitch = (0f - Mathf.Asin(Mathf.Clamp(direction.y, -1f, 1f))) * 57.29578f;
_aimPitch = Mathf.Clamp(_aimPitch, -65f, 65f);
RefreshAimDirection();
}
private void UpdateMouseAim()
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
Vector2 val = Vector2.zero;
try
{
if (Mouse.current != null)
{
val = ((InputControl<Vector2>)(object)((Pointer)Mouse.current).delta).ReadValue();
}
}
catch
{
}
_aimYaw += val.x * 0.11f;
_aimPitch -= val.y * 0.11f;
_aimPitch = Mathf.Clamp(_aimPitch, -65f, 65f);
_aimYaw = Mathf.Repeat(_aimYaw + 180f, 360f) - 180f;
RefreshAimDirection();
}
private void RefreshAimDirection()
{
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
//IL_0021: 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_003e: Unknown result type (might be due to invalid IL or missing references)
_mouseAimDirection = Quaternion.Euler(_aimPitch, _aimYaw, 0f) * Vector3.forward;
if (((Vector3)(ref _mouseAimDirection)).sqrMagnitude < 0.001f)
{
_mouseAimDirection = Vector3.forward;
}
((Vector3)(ref _mouseAimDirection)).Normalize();
}
private void UpdateThirdPersonCamera()
{
if ((!((Object)(object)_flightCamera == (Object)null) || TryAcquireFlightCamera()) && !((Object)(object)_physicsRig == (Object)null))
{
ForceThirdPersonCameraTransform();
}
}
private void ForceThirdPersonCameraTransform()
{
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
//IL_0090: Unknown result type (might be due to invalid IL or missing references)
//IL_0095: Unknown result type (might be due to invalid IL or missing references)
//IL_009f: Unknown result type (might be due to invalid IL or missing references)
//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
//IL_00a9: 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_00ab: Unknown result type (might be due to invalid IL or missing references)
//IL_00b1: 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_00c5: Unknown result type (might be due to invalid IL or missing references)
//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
//IL_00cf: 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_00d1: 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)
//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
//IL_0100: Unknown result type (might be due to invalid IL or missing references)
//IL_0111: 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_0082: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)_flightCamera == (Object)null) && !((Object)(object)_physicsRig == (Object)null))
{
Vector3 val = _physicsRig.rotation * Vector3.forward;
val.y = 0f;
if (((Vector3)(ref val)).sqrMagnitude < 0.001f)
{
((Vector3)(ref val))..ctor(_mouseAimDirection.x, 0f, _mouseAimDirection.z);
}
if (((Vector3)(ref val)).sqrMagnitude < 0.001f)
{
val = Vector3.forward;
}
((Vector3)(ref val)).Normalize();
Vector3 val2 = _physicsRig.worldCenterOfMass + Vector3.up * 1.5f;
Vector3 position = val2 - val * 11f + Vector3.up * 4f;
Quaternion rotation = Quaternion.LookRotation(val, Vector3.up) * Quaternion.Euler(8f, 0f, 0f);
((Component)_flightCamera).transform.position = position;
((Component)_flightCamera).transform.rotation = rotation;
}
}
private void HookCameraPreCull()
{
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_001f: Expected O, but got Unknown
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_0029: Expected O, but got Unknown
if (!_cameraPreCullHooked)
{
Camera.onPreCull = (CameraCallback)Delegate.Combine((Delegate?)(object)Camera.onPreCull, (Delegate?)new CameraCallback(OnFlightCameraPreCull));
_cameraPreCullHooked = true;
}
}
private void UnhookCameraPreCull()
{
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_001f: Expected O, but got Unknown
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_0029: Expected O, but got Unknown
if (_cameraPreCullHooked)
{
Camera.onPreCull = (CameraCallback)Delegate.Remove((Delegate?)(object)Camera.onPreCull, (Delegate?)new CameraCallback(OnFlightCameraPreCull));
_cameraPreCullHooked = false;
}
}
private void OnFlightCameraPreCull(Camera renderingCamera)
{
if (_flightEnabled && !((Object)(object)_physicsRig == (Object)null) && !((Object)(object)renderingCamera == (Object)null) && (!((Object)(object)_flightCamera == (Object)null) || TryAcquireFlightCamera()) && (Object)(object)renderingCamera == (Object)(object)_flightCamera)
{
ForceThirdPersonCameraTransform();
}
}
private void TryStartCarpetBombBarrage()
{
if (_flightEnabled && !((Object)(object)_activeBoat == (Object)null) && !((Object)(object)_physicsRig == (Object)null) && !_bombBarrageActive && !(Time.unscaledTime < _nextBombBarrageAllowedTime) && IsLocalPlayerTheDriver(_activeBoat))
{
if (!ResolveBombingSystems() || !ResolveDynamitePrefab())
{
PluginLog.Warning("Carpet bombing is unavailable: the native Dynamite spawn systems were not found.");
return;
}
_bombBarrageActive = true;
_bombsRemaining = 10;
_nextBombDropTime = Time.unscaledTime;
_nextBombBarrageAllowedTime = Time.unscaledTime + 3f;
_loggedForcedSpawnThisBarrage = false;
PluginLog.Msg("CARPET BOMBING: force-spawning 10 dynamites 2.2 metres beneath the boat.");
}
}
private void UpdateCarpetBombBarrage()
{
if (!_bombBarrageActive)
{
return;
}
if (!_flightEnabled || (Object)(object)_activeBoat == (Object)null || (Object)(object)_physicsRig == (Object)null || !IsLocalPlayerTheDriver(_activeBoat))
{
_bombBarrageActive = false;
_bombsRemaining = 0;
}
else if (!(Time.unscaledTime < _nextBombDropTime))
{
DropOneCarpetBomb();
_bombsRemaining--;
if (_bombsRemaining <= 0)
{
_bombBarrageActive = false;
PluginLog.Msg("Carpet-bomb barrage released.");
}
else
{
_nextBombDropTime = Time.unscaledTime + 0.14f;
}
}
}
private void DropOneCarpetBomb()
{
//IL_0097: Unknown result type (might be due to invalid IL or missing references)
//IL_009c: Unknown result type (might be due to invalid IL or missing references)
//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
//IL_00df: Unknown result type (might be due to invalid IL or missing references)
//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
//IL_00f9: 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_0100: Unknown result type (might be due to invalid IL or missing references)
//IL_011e: Unknown result type (might be due to invalid IL or missing references)
//IL_0129: Unknown result type (might be due to invalid IL or missing references)
//IL_0188: Unknown result type (might be due to invalid IL or missing references)
//IL_0196: Unknown result type (might be due to invalid IL or missing references)
//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
//IL_01da: Unknown result type (might be due to invalid IL or missing references)
//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
//IL_01fe: 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_020f: Unknown result type (might be due to invalid IL or missing references)
//IL_0223: Unknown result type (might be due to invalid IL or missing references)
Component val = FindLiveRuntimeComponent(_itemManagerType, "Server(Clone)");
if ((Object)(object)val == (Object)null || _spawnNewItemMethod == null || (Object)(object)_dynamitePrefab == (Object)null)
{
ResolveBombingSystems();
ResolveDynamitePrefab();
val = FindLiveRuntimeComponent(_itemManagerType, "Server(Clone)");
}
if ((Object)(object)val == (Object)null || _spawnNewItemMethod == null || (Object)(object)_dynamitePrefab == (Object)null)
{
PluginLog.Warning("A carpet bomb could not spawn because ItemManager was unavailable.");
_bombBarrageActive = false;
return;
}
Vector3 forward = ((Component)_physicsRig).transform.forward;
Vector3 right = ((Component)_physicsRig).transform.right;
float num = Random.Range(-3.2f, 3.2f);
Vector3 val2 = _physicsRig.worldCenterOfMass - Vector3.up * 2.2f + right * num - forward * 0.75f;
Quaternion rotation = Random.rotation;
object obj;
try
{
obj = _spawnNewItemMethod.Invoke(val, new object[3] { _dynamitePrefab, val2, rotation });
}
catch (Exception ex)
{
PluginLog.Warning("Native Dynamite spawn failed: " + ex.GetType().Name);
return;
}
Component val3 = (Component)((obj is Component) ? obj : null);
if ((Object)(object)val3 == (Object)null)
{
PluginLog.Warning("Native Dynamite spawn returned an object that was not an Item component.");
return;
}
ForceReleaseBombToWorld(val3);
val3.transform.position = val2;
val3.transform.rotation = rotation;
object obj2 = ReadMember(val3, "Rig");
Rigidbody val4 = (Rigidbody)((obj2 is Rigidbody) ? obj2 : null);
if ((Object)(object)val4 == (Object)null)
{
val4 = val3.GetComponent<Rigidbody>();
}
if ((Object)(object)val4 != (Object)null)
{
val4.velocity = _physicsRig.velocity + Vector3.down * 8f + right * Random.Range(-1.5f, 1.5f);
val4.angularVelocity = Random.onUnitSphere * Random.Range(3f, 8f);
}
Component val5 = null;
if (_explosiveType != null && _explosiveType.IsInstanceOfType(val3))
{
val5 = val3;
}
if ((Object)(object)val5 == (Object)null)
{
object obj3 = ReadMember(val3, "Explosive");
val5 = (Component)((obj3 is Component) ? obj3 : null);
}
if ((Object)(object)val5 == (Object)null && _explosiveType != null)
{
val5 = val3.GetComponent(_explosiveType);
}
if ((Object)(object)val5 != (Object)null)
{
PendingBomb pendingBomb = new PendingBomb();
pendingBomb.Explosive = val5;
pendingBomb.PlayerWhoDropped = ReadMember(_activeBoat, "LocalPlayerOnBoat");
pendingBomb.DetonateAt = Time.time + 3.5f;
_pendingBombs.Add(pendingBomb);
}
}
private void UpdatePendingBombs()
{
for (int num = _pendingBombs.Count - 1; num >= 0; num--)
{
PendingBomb pendingBomb = _pendingBombs[num];
if (pendingBomb == null || (Object)(object)pendingBomb.Explosive == (Object)null)
{
_pendingBombs.RemoveAt(num);
}
else if (!(Time.time < pendingBomb.DetonateAt))
{
DetonateBomb(pendingBomb.Explosive, pendingBomb.PlayerWhoDropped);
_pendingBombs.RemoveAt(num);
}
}
}
private void DetonateBomb(Component explosive, object playerWhoDropped)
{
if ((Object)(object)explosive == (Object)null)
{
return;
}
Component val = FindLiveRuntimeComponent(_serverType, "Server(Clone)");
if ((Object)(object)val == (Object)null || _activateExplosiveMethod == null)
{
ResolveBombingSystems();
val = FindLiveRuntimeComponent(_serverType, "Server(Clone)");
}
if ((Object)(object)val == (Object)null || _activateExplosiveMethod == null)
{
return;
}
uint num = ReadNetworkTick(val);
try
{
_activateExplosiveMethod.Invoke(val, new object[5] { explosive, num, true, true, playerWhoDropped });
}
catch (Exception ex)
{
PluginLog.Warning("Dynamite detonation failed: " + ex.GetType().Name);
}
}
private bool ResolveBombingSystems()
{
if (_itemManagerType == null)
{
_itemManagerType = FindRuntimeType("ItemManager");
}
if (_explosiveType == null)
{
_explosiveType = FindRuntimeType("Explosive");
}
if (_serverType == null)
{
_serverType = FindRuntimeType("Server");
}
if (_itemManagerType != null && _spawnNewItemMethod == null)
{
_spawnNewItemMethod = FindMethodRecursive(_itemManagerType, "SpawnNewItem", 3);
}
if (_serverType != null && _activateExplosiveMethod == null)
{
_activateExplosiveMethod = FindMethodRecursive(_serverType, "ActivateExplosive", 5);
}
if (_serverType != null && _setItemHolderMethod == null)
{
_setItemHolderMethod = FindMethodRecursive(_serverType, "SetItemHolder", 3);
}
if (_serverType != null && _handOverItemSimulationMethod == null)
{
_handOverItemSimulationMethod = FindMethodRecursive(_serverType, "HandOverItemSimulation", 1);
}
if (_itemManagerType != null && _explosiveType != null && _serverType != null && _spawnNewItemMethod != null && _activateExplosiveMethod != null && _setItemHolderMethod != null)
{
return _handOverItemSimulationMethod != null;
}
return false;
}
private void LogBombingRouteStatus()
{
PluginLog.Msg("FORCED-SPAWN ROUTE: SpawnNewItem=" + FoundText(_spawnNewItemMethod) + " | SetItemHolder=" + FoundText(_setItemHolderMethod) + " | HandOverItemSimulation=" + FoundText(_handOverItemSimulationMethod) + " | ActivateExplosive=" + FoundText(_activateExplosiveMethod));
}
private static string FoundText(MethodInfo method)
{
if (!(method == null))
{
return "FOUND";
}
return "NOT FOUND";
}
private void ForceReleaseBombToWorld(Component spawnedItem)
{
if ((Object)(object)spawnedItem == (Object)null)
{
return;
}
Component val = FindLiveRuntimeComponent(_serverType, "Server(Clone)");
if ((Object)(object)val == (Object)null || _setItemHolderMethod == null || _handOverItemSimulationMethod == null)
{
ResolveBombingSystems();
val = FindLiveRuntimeComponent(_serverType, "Server(Clone)");
}
if ((Object)(object)val == (Object)null || _setItemHolderMethod == null || _handOverItemSimulationMethod == null)
{
PluginLog.Warning("FORCED-SPAWN FAIL: the live Server release route was unavailable after SpawnNewItem.");
return;
}
try
{
_setItemHolderMethod.Invoke(val, new object[3] { spawnedItem, null, null });
_handOverItemSimulationMethod.Invoke(val, new object[1] { spawnedItem });
if (!_loggedForcedSpawnThisBarrage)
{
_loggedForcedSpawnThisBarrage = true;
PluginLog.Msg("FORCED-SPAWN PASS: Server.SetItemHolder(item, null, null) + Server.HandOverItemSimulation(item).");
}
}
catch (TargetInvocationException ex)
{
Exception ex2 = ex.InnerException ?? ex;
PluginLog.Warning("FORCED-SPAWN FAIL: " + ex2.GetType().Name + ": " + ex2.Message);
}
catch (Exception ex3)
{
PluginLog.Warning("FORCED-SPAWN FAIL: " + ex3.GetType().Name + ": " + ex3.Message);
}
}
private static Component FindLiveRuntimeComponent(Type type, string preferredPathText)
{
//IL_0092: 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)
if (type == null)
{
return null;
}
object obj = ReadStaticMember(type, "Instance");
Component val = (Component)((obj is Component) ? obj : null);
if ((Object)(object)val != (Object)null)
{
return val;
}
Object[] array;
try
{
array = Resources.FindObjectsOfTypeAll(type);
}
catch
{
return null;
}
Component val2 = null;
int num = int.MinValue;
foreach (Object obj3 in array)
{
Component val3 = (Component)(object)((obj3 is Component) ? obj3 : null);
if (!((Object)(object)val3 == (Object)null) && !((Object)(object)val3.gameObject == (Object)null))
{
int num2 = 0;
if (val3.gameObject.activeInHierarchy)
{
num2 += 100;
}
Scene scene = val3.gameObject.scene;
if (!string.IsNullOrEmpty(((Scene)(ref scene)).name))
{
num2 += 50;
}
string hierarchyPath = GetHierarchyPath(val3.transform);
if (!string.IsNullOrEmpty(preferredPathText) && hierarchyPath.IndexOf(preferredPathText, StringComparison.OrdinalIgnoreCase) >= 0)
{
num2 += 500;
}
if (hierarchyPath.IndexOf("Backup", StringComparison.OrdinalIgnoreCase) >= 0)
{
num2 -= 500;
}
if ((Object)(object)val2 == (Object)null || num2 > num)
{
val2 = val3;
num = num2;
}
}
}
return val2;
}
private static string GetHierarchyPath(Transform transform)
{
if ((Object)(object)transform == (Object)null)
{
return string.Empty;
}
string text = ((Object)transform).name;
Transform parent = transform.parent;
while ((Object)(object)parent != (Object)null)
{
text = ((Object)parent).name + "/" + text;
parent = parent.parent;
}
return text;
}
private bool ResolveDynamitePrefab()
{
//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)
if ((Object)(object)_dynamitePrefab != (Object)null)
{
return true;
}
if (_explosiveType == null && !ResolveBombingSystems())
{
return false;
}
Object[] array;
try
{
array = Resources.FindObjectsOfTypeAll(_explosiveType);
}
catch
{
return false;
}
Component dynamitePrefab = null;
foreach (Object obj2 in array)
{
Component val = (Component)(object)((obj2 is Component) ? obj2 : null);
if (!((Object)(object)val == (Object)null) && string.Equals(((Object)val.gameObject).name, "Dynamite", StringComparison.OrdinalIgnoreCase))
{
dynamitePrefab = val;
Scene scene = val.gameObject.scene;
if (string.IsNullOrEmpty(((Scene)(ref scene)).name))
{
_dynamitePrefab = val;
return true;
}
}
}
_dynamitePrefab = dynamitePrefab;
return (Object)(object)_dynamitePrefab != (Object)null;
}
private static uint ReadNetworkTick(Component server)
{
try
{
object target = ReadMember(server, "TimeManager");
object obj = ReadMember(target, "Tick");
if (obj != null)
{
return Convert.ToUInt32(obj);
}
}
catch
{
}
return 0u;
}
private bool IsActiveBoatStillValid()
{
if ((Object)(object)_activeBoat == (Object)null || (Object)(object)_physicsRig == (Object)null)
{
return false;
}
try
{
return _activeBoat.gameObject.activeInHierarchy && IsLocalPlayerTheDriver(_activeBoat);
}
catch
{
return false;
}
}
private Component FindLocallyDrivenBoat()
{
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_0051: Unknown result type (might be due to invalid IL or missing references)
if (_boatType == null)
{
return null;
}
Object[] array;
try
{
array = Resources.FindObjectsOfTypeAll(_boatType);
}
catch
{
return null;
}
foreach (Object obj2 in array)
{
Component val = (Component)(object)((obj2 is Component) ? obj2 : null);
if ((Object)(object)val == (Object)null)
{
continue;
}
try
{
if (val.gameObject.activeInHierarchy)
{
Scene scene = val.gameObject.scene;
if (!string.IsNullOrEmpty(((Scene)(ref scene)).name) && IsLocalPlayerTheDriver(val))
{
return val;
}
}
}
catch
{
}
}
return null;
}
private bool IsLocalPlayerTheDriver(Component boat)
{
if ((Object)(object)boat == (Object)null || _boatType == null)
{
return false;
}
if (!TryReadStaticBoolean(_boatType, "IsDrivingLocally", out var value) || !value)
{
return false;
}
object obj = ReadMember(boat, "LocalPlayerOnBoat");
if (obj == null)
{
obj = ReadMember(boat, "<LocalPlayerOnBoat>k__BackingField");
}
object obj2 = ReadMember(boat, "Driver");
if (obj == null || obj2 == null)
{
return false;
}
Object val = (Object)((obj is Object) ? obj : null);
Object val2 = (Object)((obj2 is Object) ? obj2 : null);
if (val != (Object)null && val2 != (Object)null)
{
return val == val2;
}
return object.ReferenceEquals(obj, obj2);
}
private bool TryAcquireFlightCamera()
{
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
//IL_0042: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
Camera val = FindActiveGameCamera();
if ((Object)(object)val == (Object)null)
{
return false;
}
_flightCamera = val;
if (!_cameraStateSaved)
{
_savedCameraPosition = ((Component)_flightCamera).transform.position;
_savedCameraRotation = ((Component)_flightCamera).transform.rotation;
_cameraStateSaved = true;
}
return true;
}
private static Camera FindActiveGameCamera()
{
Camera main = Camera.main;
if (IsUsableCamera(main))
{
return main;
}
Object[] array;
try
{
array = Resources.FindObjectsOfTypeAll(typeof(Camera));
}
catch
{
return null;
}
Camera val = null;
int num = int.MinValue;
foreach (Object obj2 in array)
{
Camera val2 = (Camera)(object)((obj2 is Camera) ? obj2 : null);
if (IsUsableCamera(val2))
{
int num2 = ScoreGameCamera(val2);
if ((Object)(object)val == (Object)null || num2 > num)
{
val = val2;
num = num2;
}
}
}
return val;
}
private static bool IsUsableCamera(Camera camera)
{
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)camera == (Object)null)
{
return false;
}
try
{
int result;
if (((Behaviour)camera).enabled && ((Component)camera).gameObject.activeInHierarchy)
{
Scene scene = ((Component)camera).gameObject.scene;
if (!string.IsNullOrEmpty(((Scene)(ref scene)).name))
{
result = (((Object)(object)camera.targetTexture == (Object)null) ? 1 : 0);
goto IL_0049;
}
}
result = 0;
goto IL_0049;
IL_0049:
return (byte)result != 0;
}
catch
{
return false;
}
}
private static int ScoreGameCamera(Camera camera)
{
int num = 0;
if (!camera.orthographic)
{
num += 50;
}
if ((Object)(object)((Component)camera).GetComponent<AudioListener>() != (Object)null)
{
num += 100;
}
string text = ((Object)((Component)camera).gameObject).name.ToLowerInvariant();
if (text.IndexOf("player") >= 0)
{
num += 40;
}
if (text.IndexOf("main") >= 0)
{
num += 30;
}
if (text.IndexOf("game") >= 0)
{
num += 15;
}
if (text.IndexOf("ui") >= 0)
{
num -= 100;
}
if (text.IndexOf("menu") >= 0)
{
num -= 100;
}
if (text.IndexOf("endgame") >= 0)
{
num -= 100;
}
return num;
}
private static bool IsClientOnly(Component boat)
{
bool value;
bool flag = TryReadBoolean(boat, "IsServerStarted", out value);
bool value2;
bool flag2 = TryReadBoolean(boat, "IsClientStarted", out value2);
if (flag && flag2 && value2)
{
return !value;
}
return false;
}
private static Type FindRuntimeType(string fullName)
{
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
for (int i = 0; i < assemblies.Length; i++)
{
try
{
Type type = assemblies[i].GetType(fullName, throwOnError: false);
if (type != null)
{
return type;
}
}
catch
{
}
}
return null;
}
private static MethodInfo FindMethodRecursive(Type type, string name, int parameterCount)
{
Type type2 = type;
while (type2 != null)
{
try
{
MethodInfo[] methods = type2.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
foreach (MethodInfo methodInfo in methods)
{
if (methodInfo.Name == name && methodInfo.GetParameters().Length == parameterCount)
{
return methodInfo;
}
}
}
catch
{
}
type2 = type2.BaseType;
}
return null;
}
private void ResolveBoatType()
{
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
for (int i = 0; i < assemblies.Length; i++)
{
Type type = null;
try
{
type = assemblies[i].GetType("Boat", throwOnError: false);
}
catch
{
}
if (type != null && typeof(Component).IsAssignableFrom(type))
{
_boatType = type;
PluginLog.Msg("Resolved the runtime Boat controller from " + assemblies[i].GetName().Name + ".");
break;
}
}
}
private static object ReadMember(object target, string name)
{
if (target == null)
{
return null;
}
Type type = target.GetType();
PropertyInfo propertyInfo = FindPropertyRecursive(type, name);
if (propertyInfo != null && propertyInfo.GetIndexParameters().Length == 0)
{
try
{
return propertyInfo.GetValue(target, null);
}
catch
{
}
}
FieldInfo fieldInfo = FindFieldRecursive(type, name);
if (fieldInfo != null)
{
try
{
return fieldInfo.GetValue(target);
}
catch
{
}
}
return null;
}
private static object ReadStaticMember(Type type, string name)
{
if (type == null)
{
return null;
}
PropertyInfo propertyInfo = FindPropertyRecursive(type, name);
if (propertyInfo != null && propertyInfo.GetIndexParameters().Length == 0)
{
try
{
return propertyInfo.GetValue(null, null);
}
catch
{
}
}
FieldInfo fieldInfo = FindFieldRecursive(type, name);
if (fieldInfo != null && fieldInfo.IsStatic)
{
try
{
return fieldInfo.GetValue(null);
}
catch
{
}
}
return null;
}
private static bool TryReadBoolean(object target, string name, out bool value)
{
value = false;
object obj = ReadMember(target, name);
if (obj is bool)
{
value = (bool)obj;
return true;
}
return false;
}
private static bool TryReadStaticBoolean(Type type, string name, out bool value)
{
value = false;
PropertyInfo propertyInfo = FindPropertyRecursive(type, name);
if (propertyInfo != null)
{
try
{
object value2 = propertyInfo.GetValue(null, null);
if (value2 is bool)
{
value = (bool)value2;
return true;
}
}
catch
{
}
}
FieldInfo fieldInfo = FindFieldRecursive(type, name);
if (fieldInfo != null && fieldInfo.IsStatic)
{
try
{
object value3 = fieldInfo.GetValue(null);
if (value3 is bool)
{
value = (bool)value3;
return true;
}
}
catch
{
}
}
return false;
}
private static FieldInfo FindFieldRecursive(Type type, string name)
{
Type type2 = type;
while (type2 != null)
{
try
{
FieldInfo field = type2.GetField(name, BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
if (field != null)
{
return field;
}
}
catch
{
}
type2 = type2.BaseType;
}
return null;
}
private static PropertyInfo FindPropertyRecursive(Type type, string name)
{
Type type2 = type;
while (type2 != null)
{
try
{
PropertyInfo property = type2.GetProperty(name, BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
if (property != null)
{
return property;
}
}
catch
{
}
type2 = type2.BaseType;
}
return null;
}
}
internal static class PluginLog
{
private static ManualLogSource _source;
internal static void Bind(ManualLogSource source)
{
_source = source;
}
internal static void Msg(object value)
{
if (_source != null)
{
_source.LogInfo(value);
}
}
internal static void Warning(object value)
{
if (_source != null)
{
_source.LogWarning(value);
}
}
internal static void Error(object value)
{
if (_source != null)
{
_source.LogError(value);
}
}
}