Decompiled source of EnergyCrystalAutoRefill v4.0.0

EnergyCrystalAutoRefill.dll

Decompiled a week ago
using 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 HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using UnityEngine;

[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("REPOJP")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("zabuMod")]
[assembly: AssemblyTitle("zabuMod")]
[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 REPOJP.EnergyCrystalAutoRefill
{
	[BepInPlugin("REPOJP.EnergyCrystalAutoRefill", "EnergyCrystalAutoRefill", "4.0.0")]
	public sealed class EnergyCrystalAutoRefillPlugin : BaseUnityPlugin
	{
		private sealed class ForcedMessageInfo
		{
			private readonly Queue<string> _messages = new Queue<string>();

			public int Count => _messages.Count;

			public void AddMessage(string message)
			{
				if (!string.IsNullOrEmpty(message))
				{
					_messages.Enqueue(message);
				}
			}

			public bool TryDequeue(out string message)
			{
				if (_messages.Count > 0)
				{
					message = _messages.Dequeue();
					return true;
				}
				message = null;
				return false;
			}
		}

		private sealed class ForcedChatEntry
		{
			public string Message;

			public Vector3 TargetPosition;
		}

		private sealed class PlayerDistanceInfo
		{
			public PlayerAvatar Player;

			public float DistanceSqr;
		}

		[HarmonyPatch(typeof(ChargingStation), "Update")]
		private static class ChargingStationUpdatePostfixPatch
		{
			private enum FlowState
			{
				Idle,
				Running,
				Cooldown
			}

			[CompilerGenerated]
			private sealed class <FlowCoroutine>d__33 : IEnumerator<object>, IEnumerator, IDisposable
			{
				private int <>1__state;

				private object <>2__current;

				public ChargingStation station;

				public Vector3 initialTargetPosition;

				private Vector3 <targetPosition>5__1;

				private int <costK>5__2;

				private ForcedMessageInfo <costInfo>5__3;

				private int <currencyBeforeWait>5__4;

				private float <endWait>5__5;

				private int <currencyBeforeSpend>5__6;

				private bool <refillOk>5__7;

				private int <savingsAfter>5__8;

				private ForcedMessageInfo <savingsInfo>5__9;

				private float <cd>5__10;

				private ForcedMessageInfo <insufficientInfo>5__11;

				private int <i>5__12;

				private ForcedMessageInfo <insufficientInfo>5__13;

				private int <curNow>5__14;

				object IEnumerator<object>.Current
				{
					[DebuggerHidden]
					get
					{
						return <>2__current;
					}
				}

				object IEnumerator.Current
				{
					[DebuggerHidden]
					get
					{
						return <>2__current;
					}
				}

				[DebuggerHidden]
				public <FlowCoroutine>d__33(int <>1__state)
				{
					this.<>1__state = <>1__state;
				}

				[DebuggerHidden]
				void IDisposable.Dispose()
				{
					<costInfo>5__3 = null;
					<savingsInfo>5__9 = null;
					<insufficientInfo>5__11 = null;
					<insufficientInfo>5__13 = null;
					<>1__state = -2;
				}

				private bool MoveNext()
				{
					//IL_05f7: Unknown result type (might be due to invalid IL or missing references)
					//IL_035d: Unknown result type (might be due to invalid IL or missing references)
					//IL_0362: Unknown result type (might be due to invalid IL or missing references)
					//IL_0367: 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_00a1: Unknown result type (might be due to invalid IL or missing references)
					//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
					//IL_011b: Unknown result type (might be due to invalid IL or missing references)
					//IL_02e4: 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_02ff: Expected O, but got Unknown
					//IL_028e: 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_020d: Unknown result type (might be due to invalid IL or missing references)
					//IL_03e2: Unknown result type (might be due to invalid IL or missing references)
					//IL_03e7: Unknown result type (might be due to invalid IL or missing references)
					//IL_03ec: Unknown result type (might be due to invalid IL or missing references)
					//IL_04da: Unknown result type (might be due to invalid IL or missing references)
					switch (<>1__state)
					{
					default:
						return false;
					case 0:
						<>1__state = -1;
						if ((Object)(object)station == (Object)null)
						{
							_sequenceRunning = false;
							_state = FlowState.Idle;
							return false;
						}
						ResetTryCache();
						UpdateTryCache(station);
						if (!IsDepleted(station) || !_tryCacheValid || !_tryCached)
						{
							_sequenceRunning = false;
							_state = FlowState.Idle;
							return false;
						}
						<targetPosition>5__1 = GetForcedChatTargetPosition(station, initialTargetPosition);
						<costK>5__2 = Mathf.Clamp(CfgCostPerRefillK.Value, 0, 100);
						<costInfo>5__3 = new ForcedMessageInfo();
						<costInfo>5__3.AddMessage("Buy cost " + <costK>5__2 + "k$.");
						BroadcastTruckMessage("Buy cost " + <costK>5__2 + "k$.");
						StartForcedMessageQueue(<costInfo>5__3, <targetPosition>5__1);
						<currencyBeforeWait>5__4 = SemiFunc.StatGetRunCurrency();
						if (<costK>5__2 > 0 && <currencyBeforeWait>5__4 < <costK>5__2)
						{
							<insufficientInfo>5__11 = new ForcedMessageInfo();
							<insufficientInfo>5__11.AddMessage("No money…");
							<insufficientInfo>5__11.AddMessage("My money is " + <currencyBeforeWait>5__4 + "k$.");
							<insufficientInfo>5__11.AddMessage("Need " + <costK>5__2 + "k$.");
							BroadcastTruckMessage("No money…");
							BroadcastTruckMessage("My money is " + <currencyBeforeWait>5__4 + "k$.");
							BroadcastTruckMessage("Need " + <costK>5__2 + "k$.");
							StartForcedMessageQueue(<insufficientInfo>5__11, <targetPosition>5__1);
							_requireReinsertAfterInsufficient = true;
							_sequenceRunning = false;
							_state = FlowState.Idle;
							return false;
						}
						<endWait>5__5 = Time.time + 5f;
						goto IL_02b5;
					case 1:
						<>1__state = -1;
						goto IL_02b5;
					case 2:
						{
							<>1__state = -1;
							ResetTryCache();
							UpdateTryCache(station);
							if (!IsDepleted(station) || !_tryCacheValid || !_tryCached)
							{
								_sequenceRunning = false;
								_state = FlowState.Idle;
								return false;
							}
							<targetPosition>5__1 = GetForcedChatTargetPosition(station, <targetPosition>5__1);
							<i>5__12--;
							break;
						}
						IL_02b5:
						if (Time.time < <endWait>5__5)
						{
							ResetTryCache();
							UpdateTryCache(station);
							if (!IsDepleted(station) || !_tryCacheValid || !_tryCached)
							{
								_sequenceRunning = false;
								_state = FlowState.Idle;
								return false;
							}
							<targetPosition>5__1 = GetForcedChatTargetPosition(station, <targetPosition>5__1);
							<>2__current = null;
							<>1__state = 1;
							return true;
						}
						<i>5__12 = 5;
						break;
					}
					if (<i>5__12 >= 1)
					{
						ForceNearestTruckPlayersChat(<i>5__12.ToString(), <targetPosition>5__1);
						<>2__current = (object)new WaitForSeconds(1f);
						<>1__state = 2;
						return true;
					}
					ResetTryCache();
					UpdateTryCache(station);
					if (!IsDepleted(station) || !_tryCacheValid || !_tryCached)
					{
						_sequenceRunning = false;
						_state = FlowState.Idle;
						return false;
					}
					<targetPosition>5__1 = GetForcedChatTargetPosition(station, <targetPosition>5__1);
					<currencyBeforeSpend>5__6 = SemiFunc.StatGetRunCurrency();
					if (<costK>5__2 > 0 && <currencyBeforeSpend>5__6 < <costK>5__2)
					{
						<insufficientInfo>5__13 = new ForcedMessageInfo();
						<insufficientInfo>5__13.AddMessage("No money…");
						<insufficientInfo>5__13.AddMessage("My money is " + <currencyBeforeSpend>5__6 + "k$.");
						<insufficientInfo>5__13.AddMessage("Need " + <costK>5__2 + "k$.");
						BroadcastTruckMessage("No money…");
						BroadcastTruckMessage("My money is " + <currencyBeforeSpend>5__6 + "k$.");
						BroadcastTruckMessage("Need " + <costK>5__2 + "k$.");
						StartForcedMessageQueue(<insufficientInfo>5__13, <targetPosition>5__1);
						_requireReinsertAfterInsufficient = true;
						_sequenceRunning = false;
						_state = FlowState.Idle;
						return false;
					}
					if (<costK>5__2 > 0)
					{
						SemiFunc.StatSetRunCurrency(<currencyBeforeSpend>5__6 - <costK>5__2);
					}
					<refillOk>5__7 = false;
					try
					{
						DoRefillAddPowerCrystalsOnly(station);
						<refillOk>5__7 = true;
					}
					catch
					{
						<refillOk>5__7 = false;
					}
					if (!<refillOk>5__7)
					{
						if (<costK>5__2 > 0)
						{
							<curNow>5__14 = SemiFunc.StatGetRunCurrency();
							SemiFunc.StatSetRunCurrency(<curNow>5__14 + <costK>5__2);
						}
						_sequenceRunning = false;
						_state = FlowState.Idle;
						return false;
					}
					<savingsAfter>5__8 = SemiFunc.StatGetRunCurrency();
					<savingsInfo>5__9 = new ForcedMessageInfo();
					<savingsInfo>5__9.AddMessage("My money is " + <savingsAfter>5__8 + "k$.");
					BroadcastTruckMessage("My money is " + <savingsAfter>5__8 + "k$.");
					StartForcedMessageQueue(<savingsInfo>5__9, <targetPosition>5__1);
					<cd>5__10 = Mathf.Clamp(CfgCooldownSeconds.Value, 1f, 300f);
					_cooldownEndTime = Time.time + <cd>5__10;
					_cooldownChatSent = false;
					_state = FlowState.Cooldown;
					_sequenceRunning = false;
					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();
				}
			}

			[CompilerGenerated]
			private sealed class <ForcedMessageQueueCoroutine>d__35 : IEnumerator<object>, IEnumerator, IDisposable
			{
				private int <>1__state;

				private object <>2__current;

				private ForcedChatEntry <entry>5__1;

				object IEnumerator<object>.Current
				{
					[DebuggerHidden]
					get
					{
						return <>2__current;
					}
				}

				object IEnumerator.Current
				{
					[DebuggerHidden]
					get
					{
						return <>2__current;
					}
				}

				[DebuggerHidden]
				public <ForcedMessageQueueCoroutine>d__35(int <>1__state)
				{
					this.<>1__state = <>1__state;
				}

				[DebuggerHidden]
				void IDisposable.Dispose()
				{
					<entry>5__1 = null;
					<>1__state = -2;
				}

				private bool MoveNext()
				{
					//IL_0079: Unknown result type (might be due to invalid IL or missing references)
					//IL_0083: Expected O, but got Unknown
					//IL_0067: Unknown result type (might be due to invalid IL or missing references)
					switch (<>1__state)
					{
					default:
						return false;
					case 0:
						<>1__state = -1;
						break;
					case 1:
						<>1__state = -1;
						<entry>5__1 = null;
						break;
					}
					if (ForcedChatQueue.Count > 0)
					{
						<entry>5__1 = ForcedChatQueue.Dequeue();
						if (<entry>5__1 != null && !string.IsNullOrEmpty(<entry>5__1.Message))
						{
							ForceNearestTruckPlayersChat(<entry>5__1.Message, <entry>5__1.TargetPosition);
						}
						<>2__current = (object)new WaitForSeconds(1.2f);
						<>1__state = 1;
						return true;
					}
					_forcedMessageQueueRunning = false;
					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 static readonly FieldInfo FiChargeFloat = AccessTools.Field(typeof(ChargingStation), "chargeFloat");

			private static readonly FieldInfo FiChargeTotal = AccessTools.Field(typeof(ChargingStation), "chargeTotal");

			private static readonly FieldInfo FiChargeInt = AccessTools.Field(typeof(ChargingStation), "chargeInt");

			private static readonly FieldInfo FiChargeSegments = AccessTools.Field(typeof(ChargingStation), "chargeSegments");

			private static readonly FieldInfo FiChargeSegmentCurrent = AccessTools.Field(typeof(ChargingStation), "chargeSegmentCurrent");

			private static readonly FieldInfo FiChargeArea = AccessTools.Field(typeof(ChargingStation), "chargeArea");

			private static readonly FieldInfo FiChargeRate = AccessTools.Field(typeof(ChargingStation), "chargeRate");

			private static readonly FieldInfo FiChargeScale = AccessTools.Field(typeof(ChargingStation), "chargeScale");

			private static readonly FieldInfo FiChargeScaleTarget = AccessTools.Field(typeof(ChargingStation), "chargeScaleTarget");

			private static readonly FieldInfo FiEnergyPerCrystal = AccessTools.Field(typeof(ChargingStation), "energyPerCrystal");

			private static readonly FieldInfo FiMaxCrystals = AccessTools.Field(typeof(ChargingStation), "maxCrystals");

			private static readonly FieldInfo FiLastSentSegment = AccessTools.Field(typeof(ChargingStation), "lastSentSegment");

			private static readonly FieldInfo FiPlayerIsDisabled = AccessTools.Field(typeof(PlayerAvatar), "isDisabled");

			private static readonly FieldInfo FiRoomVolumeInTruck = AccessTools.Field(typeof(RoomVolumeCheck), "inTruck");

			private static readonly FieldInfo FiRunManagerRestarting = AccessTools.Field(typeof(RunManager), "restarting");

			private static readonly FieldInfo FiRunManagerLevelIsShop = AccessTools.Field(typeof(RunManager), "levelIsShop");

			private static readonly FieldInfo FiItemBatteryLifeInt = AccessTools.Field(typeof(ItemBattery), "batteryLifeInt");

			private static readonly Queue<ForcedChatEntry> ForcedChatQueue = new Queue<ForcedChatEntry>();

			private static FlowState _state;

			private static bool _sequenceRunning;

			private static float _cooldownEndTime;

			private static bool _forcedMessageQueueRunning;

			private static bool _cooldownChatSent;

			private static bool _requireReinsertAfterInsufficient;

			private static float _tryScanTimer;

			private static bool _tryCached;

			private static bool _tryCacheValid;

			private static bool _tryTargetPositionValid;

			private static Vector3 _tryTargetPosition;

			private static bool _lastTrying;

			[HarmonyPostfix]
			private static void Postfix(ChargingStation __instance)
			{
				//IL_0161: Unknown result type (might be due to invalid IL or missing references)
				//IL_0166: Unknown result type (might be due to invalid IL or missing references)
				//IL_0228: Unknown result type (might be due to invalid IL or missing references)
				//IL_0221: Unknown result type (might be due to invalid IL or missing references)
				//IL_022d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0230: Unknown result type (might be due to invalid IL or missing references)
				if (CfgEnableMod == null || !CfgEnableMod.Value || (Object)(object)__instance == (Object)null || !IsSafeChargingScene() || SemiFunc.RunIsShop() || ((Object)(object)RunManager.instance != (Object)null && GetRunManagerLevelIsShop()) || !SemiFunc.IsMasterClientOrSingleplayer() || ((Object)(object)RunManager.instance != (Object)null && GetRunManagerRestarting()))
				{
					return;
				}
				UpdateTryCache(__instance);
				bool flag = _tryCacheValid && _tryCached;
				if (_state == FlowState.Cooldown)
				{
					if (!(Time.time >= _cooldownEndTime))
					{
						if (flag && IsDepleted(__instance) && !_cooldownChatSent)
						{
							ForcedMessageInfo forcedMessageInfo = new ForcedMessageInfo();
							forcedMessageInfo.AddMessage("Cooldown " + Mathf.CeilToInt(Mathf.Max(0f, _cooldownEndTime - Time.time)) + "s.");
							StartForcedMessageQueue(forcedMessageInfo, GetForcedChatTargetPosition(__instance, GetStationPosition(__instance)));
							_cooldownChatSent = true;
						}
						_lastTrying = flag;
						return;
					}
					_state = FlowState.Idle;
					_sequenceRunning = false;
					_cooldownChatSent = false;
				}
				if (!IsDepleted(__instance))
				{
					_lastTrying = false;
					if (_state == FlowState.Running)
					{
						_state = FlowState.Idle;
						_sequenceRunning = false;
					}
					return;
				}
				if (_requireReinsertAfterInsufficient)
				{
					if (!(!_lastTrying && flag))
					{
						_lastTrying = flag;
						return;
					}
					_requireReinsertAfterInsufficient = false;
				}
				if (!flag)
				{
					_lastTrying = false;
					return;
				}
				if (_state == FlowState.Idle && !_sequenceRunning)
				{
					Vector3 targetPosition = (_tryTargetPositionValid ? _tryTargetPosition : GetStationPosition(__instance));
					StartSequence(__instance, targetPosition);
				}
				_lastTrying = flag;
			}

			private static void StartSequence(ChargingStation station, Vector3 targetPosition)
			{
				//IL_002f: Unknown result type (might be due to invalid IL or missing references)
				if (!_sequenceRunning)
				{
					_sequenceRunning = true;
					_state = FlowState.Running;
					if ((Object)(object)Instance != (Object)null)
					{
						((MonoBehaviour)Instance).StartCoroutine(FlowCoroutine(station, targetPosition));
						return;
					}
					_sequenceRunning = false;
					_state = FlowState.Idle;
				}
			}

			[IteratorStateMachine(typeof(<FlowCoroutine>d__33))]
			private static IEnumerator FlowCoroutine(ChargingStation station, Vector3 initialTargetPosition)
			{
				//IL_000e: Unknown result type (might be due to invalid IL or missing references)
				//IL_000f: Unknown result type (might be due to invalid IL or missing references)
				//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
				return new <FlowCoroutine>d__33(0)
				{
					station = station,
					initialTargetPosition = initialTargetPosition
				};
			}

			private static void StartForcedMessageQueue(ForcedMessageInfo info, Vector3 targetPosition)
			{
				//IL_002f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: Unknown result type (might be due to invalid IL or missing references)
				if (info != null && !((Object)(object)Instance == (Object)null))
				{
					string message;
					while (info.TryDequeue(out message))
					{
						ForcedChatEntry forcedChatEntry = new ForcedChatEntry();
						forcedChatEntry.Message = message;
						forcedChatEntry.TargetPosition = targetPosition;
						ForcedChatQueue.Enqueue(forcedChatEntry);
					}
					if (!_forcedMessageQueueRunning)
					{
						_forcedMessageQueueRunning = true;
						((MonoBehaviour)Instance).StartCoroutine(ForcedMessageQueueCoroutine());
					}
				}
			}

			[IteratorStateMachine(typeof(<ForcedMessageQueueCoroutine>d__35))]
			private static IEnumerator ForcedMessageQueueCoroutine()
			{
				//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
				return new <ForcedMessageQueueCoroutine>d__35(0);
			}

			private static void UpdateTryCache(ChargingStation station)
			{
				//IL_008c: Unknown result type (might be due to invalid IL or missing references)
				//IL_008d: Unknown result type (might be due to invalid IL or missing references)
				if (_tryCacheValid && _tryScanTimer < 0.5f)
				{
					_tryScanTimer += Time.deltaTime;
					return;
				}
				_tryScanTimer += Time.deltaTime;
				if (!_tryCacheValid || !(_tryScanTimer < 0.5f))
				{
					_tryScanTimer = 0f;
					_tryCached = TryGetChargingTargetPosition(station, out var targetPosition);
					_tryCacheValid = true;
					_tryTargetPositionValid = _tryCached;
					if (_tryCached)
					{
						_tryTargetPosition = targetPosition;
					}
				}
			}

			private static void ResetTryCache()
			{
				//IL_001d: 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)
				_tryScanTimer = 0.5f;
				_tryCacheValid = false;
				_tryCached = false;
				_tryTargetPositionValid = false;
				_tryTargetPosition = Vector3.zero;
			}

			private static bool TryGetChargingTargetPosition(ChargingStation station, out Vector3 targetPosition)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				//IL_0041: 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)
				//IL_0051: Unknown result type (might be due to invalid IL or missing references)
				//IL_0057: Unknown result type (might be due to invalid IL or missing references)
				//IL_005c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0166: Unknown result type (might be due to invalid IL or missing references)
				//IL_016b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0106: 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_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)
				targetPosition = Vector3.zero;
				if ((Object)(object)station == (Object)null)
				{
					return false;
				}
				Transform val = SafeGetTransform(station, FiChargeArea);
				if ((Object)(object)val == (Object)null)
				{
					return false;
				}
				try
				{
					Collider[] array = Physics.OverlapBox(val.position, val.lossyScale / 2f, val.rotation, LayerMask.op_Implicit(SemiFunc.LayerMaskGetPhysGrabObject()));
					ItemBattery val2 = null;
					float num = float.MaxValue;
					List<ItemBattery> list = new List<ItemBattery>();
					for (int i = 0; i < array.Length; i++)
					{
						if ((Object)(object)array[i] == (Object)null)
						{
							continue;
						}
						ItemBattery componentInParent = ((Component)array[i]).GetComponentInParent<ItemBattery>();
						if ((Object)(object)componentInParent == (Object)null || list.Contains(componentInParent))
						{
							continue;
						}
						list.Add(componentInParent);
						if (SafeGetInt(componentInParent, FiItemBatteryLifeInt, componentInParent.batteryBars) < componentInParent.batteryBars)
						{
							Vector3 val3 = GetTransformPosition(((Component)componentInParent).transform) - val.position;
							float sqrMagnitude = ((Vector3)(ref val3)).sqrMagnitude;
							if (sqrMagnitude < num)
							{
								num = sqrMagnitude;
								val2 = componentInParent;
							}
						}
					}
					if ((Object)(object)val2 != (Object)null)
					{
						targetPosition = GetTransformPosition(((Component)val2).transform);
						return true;
					}
				}
				catch
				{
				}
				return false;
			}

			private static bool IsDepleted(ChargingStation station)
			{
				if ((Object)(object)station == (Object)null)
				{
					return false;
				}
				float num = SafeGetFloat(station, FiChargeFloat, 0f);
				int num2 = SafeGetInt(station, FiChargeTotal, 0);
				int num3 = SafeGetInt(station, FiChargeSegments, 40);
				int num4 = SafeGetInt(station, FiChargeSegmentCurrent, Mathf.RoundToInt(num * (float)num3));
				return num2 <= 0 || num <= 0f || num4 <= 0;
			}

			private static void DoRefillAddPowerCrystalsOnly(ChargingStation station)
			{
				if ((Object)(object)station == (Object)null)
				{
					return;
				}
				int num = SafeGetInt(station, FiChargeSegments, 40);
				int num2 = Mathf.Clamp(SafeGetInt(station, FiEnergyPerCrystal, 10), 1, 100);
				int num3 = Mathf.Clamp(SafeGetInt(station, FiMaxCrystals, 10), 1, 100);
				int num4 = Mathf.Clamp(CfgPowerCrystalsToAdd.Value, 1, num3);
				TryAddPowerCrystalPurchase(station, num4, num3);
				int num5 = Mathf.Clamp(SafeGetInt(station, FiChargeTotal, 0), 0, 100);
				int num6 = num2 * num4;
				int num7 = Mathf.Clamp(num5 + num6, 1, 100);
				SafeSetInt(station, FiChargeTotal, num7);
				float num8 = (float)num7 / 100f;
				SafeSetFloat(station, FiChargeFloat, num8);
				int num9 = Mathf.Clamp(Mathf.RoundToInt(num8 * (float)num), 1, num);
				float value = (float)num9 / (float)num;
				SafeSetInt(station, FiChargeSegmentCurrent, num9);
				SafeSetFloat(station, FiChargeScaleTarget, value);
				SafeSetFloat(station, FiChargeScale, value);
				SafeSetFloat(station, FiChargeRate, 1f / (float)num2 / 100f);
				SafeSetInt(station, FiLastSentSegment, num9);
				try
				{
					if ((Object)(object)PunManager.instance != (Object)null)
					{
						PunManager.instance.SetRunStatSet("chargingStationChargeTotal", num7);
						PunManager.instance.SetRunStatSet("chargingStationCharge", SafeGetInt(station, FiChargeInt, 0));
					}
					else if ((Object)(object)StatsManager.instance != (Object)null)
					{
						StatsManager.instance.runStats["chargingStationChargeTotal"] = num7;
						StatsManager.instance.runStats["chargingStationCharge"] = SafeGetInt(station, FiChargeInt, 0);
					}
				}
				catch
				{
				}
				PhotonView component = ((Component)station).GetComponent<PhotonView>();
				if (!((Object)(object)component != (Object)null) || !SemiFunc.IsMultiplayer())
				{
					return;
				}
				try
				{
					PhotonNetwork.RemoveBufferedRPCs(component.ViewID, "ChargingStationSegmentChangedRPC", (int[])null);
					component.RPC("ChargingStationSegmentChangedRPC", (RpcTarget)3, new object[1] { (byte)Mathf.Clamp(num9, 0, 255) });
				}
				catch
				{
				}
			}

			private static void TryAddPowerCrystalPurchase(ChargingStation station, int addCount, int maxCrystals)
			{
				if ((Object)(object)station == (Object)null)
				{
					return;
				}
				int num = Mathf.Clamp(addCount, 1, maxCrystals);
				int num2 = Mathf.Clamp(SafeGetInt(station, FiChargeInt, 0), 0, maxCrystals);
				int num3 = Mathf.Clamp(num2 + num, 1, maxCrystals);
				int num4 = Mathf.Max(0, num3 - num2);
				SafeSetInt(station, FiChargeInt, num3);
				try
				{
					if ((Object)(object)station.item != (Object)null && (Object)(object)StatsManager.instance != (Object)null)
					{
						StatsManager.instance.SetItemPurchase(station.item, num3);
					}
				}
				catch
				{
				}
				try
				{
					if (!((Object)(object)StatsManager.instance != (Object)null))
					{
						return;
					}
					if (StatsManager.instance.itemsPurchased != null)
					{
						StatsManager.instance.itemsPurchased["Item Power Crystal"] = num3;
						TrySyncDictionaryValue("itemsPurchased", "Item Power Crystal", num3);
					}
					if (StatsManager.instance.itemsPurchasedTotal != null && num4 > 0)
					{
						int num5 = 0;
						if (StatsManager.instance.itemsPurchasedTotal.ContainsKey("Item Power Crystal"))
						{
							num5 = StatsManager.instance.itemsPurchasedTotal["Item Power Crystal"];
						}
						int value = Mathf.Max(0, num5 + num4);
						StatsManager.instance.itemsPurchasedTotal["Item Power Crystal"] = value;
						TrySyncDictionaryValue("itemsPurchasedTotal", "Item Power Crystal", value);
					}
				}
				catch
				{
				}
			}

			private static void TrySyncDictionaryValue(string dictionaryName, string key, int value)
			{
				try
				{
					if ((Object)(object)PunManager.instance != (Object)null && SemiFunc.IsMasterClientOrSingleplayer())
					{
						PunManager.instance.UpdateStat(dictionaryName, key, value);
					}
				}
				catch
				{
				}
			}

			private static void BroadcastTruckMessage(string message)
			{
				try
				{
					if ((Object)(object)TruckScreenText.instance != (Object)null)
					{
						TruckScreenText.instance.MessageSendCustom("", message, 0);
					}
				}
				catch
				{
				}
			}

			private static void ForceNearestTruckPlayersChat(string message, Vector3 targetPosition)
			{
				//IL_0082: Unknown result type (might be due to invalid IL or missing references)
				//IL_0087: Unknown result type (might be due to invalid IL or missing references)
				//IL_009b: Unknown result type (might be due to invalid IL or missing references)
				//IL_009d: Unknown result type (might be due to invalid IL or missing references)
				//IL_009e: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
				try
				{
					if (string.IsNullOrEmpty(message))
					{
						return;
					}
					List<PlayerAvatar> list = SemiFunc.PlayerGetList();
					if (list == null || list.Count == 0)
					{
						return;
					}
					List<PlayerDistanceInfo> list2 = new List<PlayerDistanceInfo>();
					for (int i = 0; i < list.Count; i++)
					{
						PlayerAvatar val = list[i];
						if (!((Object)(object)val == (Object)null) && !IsPlayerDisabled(val) && IsPlayerInTruck(val))
						{
							Vector3 playerPosition = GetPlayerPosition(val);
							PlayerDistanceInfo playerDistanceInfo = new PlayerDistanceInfo();
							playerDistanceInfo.Player = val;
							Vector3 val2 = playerPosition - targetPosition;
							playerDistanceInfo.DistanceSqr = ((Vector3)(ref val2)).sqrMagnitude;
							list2.Add(playerDistanceInfo);
						}
					}
					if (list2.Count == 0)
					{
						return;
					}
					list2.Sort((PlayerDistanceInfo a, PlayerDistanceInfo b) => a.DistanceSqr.CompareTo(b.DistanceSqr));
					int num = Mathf.Min(3, list2.Count);
					for (int j = 0; j < num; j++)
					{
						if (list2[j] != null && (Object)(object)list2[j].Player != (Object)null)
						{
							list2[j].Player.ChatMessageSend(message);
						}
					}
				}
				catch
				{
				}
			}

			private static Vector3 GetForcedChatTargetPosition(ChargingStation station, Vector3 fallback)
			{
				//IL_000b: 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)
				//IL_0020: 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_003f: Unknown result type (might be due to invalid IL or missing references)
				//IL_003b: Unknown result type (might be due to invalid IL or missing references)
				//IL_003c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0033: Unknown result type (might be due to invalid IL or missing references)
				//IL_0038: Unknown result type (might be due to invalid IL or missing references)
				if (_tryTargetPositionValid)
				{
					return _tryTargetPosition;
				}
				if (TryGetChargingTargetPosition(station, out var targetPosition))
				{
					return targetPosition;
				}
				if ((Object)(object)station != (Object)null)
				{
					return GetStationPosition(station);
				}
				return fallback;
			}

			private static bool IsSafeChargingScene()
			{
				try
				{
					if ((Object)(object)RunManager.instance == (Object)null)
					{
						return false;
					}
					if ((Object)(object)StatsManager.instance == (Object)null)
					{
						return false;
					}
					if (SemiFunc.RunIsShop() || SemiFunc.RunIsArena())
					{
						return false;
					}
					if (SemiFunc.RunIsLevel() || SemiFunc.RunIsLobby())
					{
						return true;
					}
					return false;
				}
				catch
				{
					return false;
				}
			}

			private static Vector3 GetStationPosition(ChargingStation station)
			{
				//IL_001b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0020: 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_0012: 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)
				if ((Object)(object)station == (Object)null)
				{
					return Vector3.zero;
				}
				return GetTransformPosition(((Component)station).transform);
			}

			private static Vector3 GetPlayerPosition(PlayerAvatar player)
			{
				//IL_000d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0012: 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_003f: Unknown result type (might be due to invalid IL or missing references)
				//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)
				if ((Object)(object)player == (Object)null)
				{
					return Vector3.zero;
				}
				if ((Object)(object)player.playerTransform != (Object)null)
				{
					return player.playerTransform.position;
				}
				return GetTransformPosition(((Component)player).transform);
			}

			private static Vector3 GetTransformPosition(Transform transform)
			{
				//IL_0016: Unknown result type (might be due to invalid IL or missing references)
				//IL_001b: 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_0012: Unknown result type (might be due to invalid IL or missing references)
				//IL_001e: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)transform == (Object)null)
				{
					return Vector3.zero;
				}
				return transform.position;
			}

			private static bool IsPlayerDisabled(PlayerAvatar player)
			{
				if ((Object)(object)player == (Object)null)
				{
					return true;
				}
				return SafeGetBool(player, FiPlayerIsDisabled, fallback: false);
			}

			private static bool IsPlayerInTruck(PlayerAvatar player)
			{
				if ((Object)(object)player == (Object)null || (Object)(object)player.RoomVolumeCheck == (Object)null)
				{
					return false;
				}
				try
				{
					player.RoomVolumeCheck.CheckSet();
				}
				catch
				{
				}
				return SafeGetBool(player.RoomVolumeCheck, FiRoomVolumeInTruck, fallback: false);
			}

			private static bool GetRunManagerRestarting()
			{
				if ((Object)(object)RunManager.instance == (Object)null)
				{
					return false;
				}
				return SafeGetBool(RunManager.instance, FiRunManagerRestarting, fallback: false);
			}

			private static bool GetRunManagerLevelIsShop()
			{
				if ((Object)(object)RunManager.instance == (Object)null)
				{
					return false;
				}
				return SafeGetBool(RunManager.instance, FiRunManagerLevelIsShop, fallback: false);
			}

			private static Transform SafeGetTransform(object obj, FieldInfo fi)
			{
				if (obj == null || fi == null)
				{
					return null;
				}
				try
				{
					object? value = fi.GetValue(obj);
					return (Transform)((value is Transform) ? value : null);
				}
				catch
				{
					return null;
				}
			}

			private static int SafeGetInt(object obj, FieldInfo fi, int fallback)
			{
				if (obj == null || fi == null)
				{
					return fallback;
				}
				try
				{
					object value = fi.GetValue(obj);
					if (value is int)
					{
						return (int)value;
					}
				}
				catch
				{
				}
				return fallback;
			}

			private static float SafeGetFloat(object obj, FieldInfo fi, float fallback)
			{
				if (obj == null || fi == null)
				{
					return fallback;
				}
				try
				{
					object value = fi.GetValue(obj);
					if (value is float)
					{
						return (float)value;
					}
				}
				catch
				{
				}
				return fallback;
			}

			private static bool SafeGetBool(object obj, FieldInfo fi, bool fallback)
			{
				if (obj == null || fi == null)
				{
					return fallback;
				}
				try
				{
					object value = fi.GetValue(obj);
					if (value is bool)
					{
						return (bool)value;
					}
				}
				catch
				{
				}
				return fallback;
			}

			private static void SafeSetInt(object obj, FieldInfo fi, int value)
			{
				if (obj == null || fi == null)
				{
					return;
				}
				try
				{
					fi.SetValue(obj, value);
				}
				catch
				{
				}
			}

			private static void SafeSetFloat(object obj, FieldInfo fi, float value)
			{
				if (obj == null || fi == null)
				{
					return;
				}
				try
				{
					fi.SetValue(obj, value);
				}
				catch
				{
				}
			}
		}

		public const string PluginGuid = "REPOJP.EnergyCrystalAutoRefill";

		public const string PluginName = "EnergyCrystalAutoRefill";

		public const string PluginVersion = "4.0.0";

		private static ConfigEntry<bool> CfgEnableMod;

		private static ConfigEntry<int> CfgCostPerRefillK;

		private static ConfigEntry<int> CfgPowerCrystalsToAdd;

		private static ConfigEntry<float> CfgCooldownSeconds;

		private const float PreCountdownDelaySeconds = 5f;

		private const int CountdownSecondsFixed = 5;

		private const int ForcedChatMaxPlayers = 3;

		private const float TryScanIntervalSeconds = 0.5f;

		private Harmony _harmony;

		internal static EnergyCrystalAutoRefillPlugin Instance;

		private void Awake()
		{
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Expected O, but got Unknown
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Expected O, but got Unknown
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Expected O, but got Unknown
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Expected O, but got Unknown
			((BaseUnityPlugin)this).Logger.LogInfo((object)"\n█████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████\n ▄▄▄▄▄▄▄                                ▄▄▄▄▄▄▄                              ▄▄   ▄▄▄▄                     ▄▄▄▄▄▄▄           ▄▄     ▄▄ ▄▄\n███▀▀▀▀▀                               ███▀▀▀▀▀                    ██        ██ ▄██▀▀██▄        ██         ███▀▀███▄        ██  ▀▀  ██ ██\n███▄▄    ████▄ ▄█▀█▄ ████▄ ▄████ ██ ██ ███      ████▄ ██ ██ ▄█▀▀▀ ▀██▀▀ ▀▀█▄ ██ ███  ███ ██ ██ ▀██▀▀ ▄███▄ ███▄▄███▀ ▄█▀█▄ ▀██▀ ██  ██ ██\n███      ██ ██ ██▄█▀ ██ ▀▀ ██ ██ ██▄██ ███      ██ ▀▀ ██▄██ ▀███▄  ██  ▄█▀██ ██ ███▀▀███ ██ ██  ██   ██ ██ ███▀▀██▄  ██▄█▀  ██  ██  ██ ██\n▀███████ ██ ██ ▀█▄▄▄ ██    ▀████  ▀██▀ ▀███████ ██     ▀██▀ ▄▄▄█▀  ██  ▀█▄██ ██ ███  ███ ▀██▀█  ██   ▀███▀ ███  ▀███ ▀█▄▄▄  ██  ██▄ ██ ██\n                              ██   ██                   ██                                                                               \n                            ▀▀▀  ▀▀▀                  ▀▀▀                                                                                █████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████\n");
			try
			{
				((Component)this).transform.parent = null;
				((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
				Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
				Instance = this;
				CfgEnableMod = ((BaseUnityPlugin)this).Config.Bind<bool>("A General", "EnableMod", true, "Enable or disable this mod.このMODの有効無効");
				CfgCostPerRefillK = ((BaseUnityPlugin)this).Config.Bind<int>("A General", "CostPerRefill", 10, new ConfigDescription("Cost per refill in k$.補充1回あたりのコスト(k$)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
				CfgPowerCrystalsToAdd = ((BaseUnityPlugin)this).Config.Bind<int>("A General", "PowerCrystalsToAdd", 1, new ConfigDescription("How many power crystals worth to add per refill. One crystal keeps the vanilla one-crystal charge duration.補充するパワークリスタル数。1クリスタルでバニラ相当の1クリスタル分の充電時間を補充", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 10), Array.Empty<object>()));
				CfgCooldownSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("A General", "CooldownSeconds", 10f, new ConfigDescription("Cooldown seconds after a refill.補充後クールダウン秒", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 300f), Array.Empty<object>()));
				_harmony = new Harmony("REPOJP.EnergyCrystalAutoRefill");
				_harmony.PatchAll(typeof(ChargingStationUpdatePostfixPatch));
				((BaseUnityPlugin)this).Logger.LogInfo((object)"EnergyCrystalAutoRefill loaded.");
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("Failure: Awake\n" + ex));
				throw;
			}
		}

		private void OnDestroy()
		{
			try
			{
				if (_harmony != null)
				{
					_harmony.UnpatchSelf();
				}
			}
			catch
			{
			}
			if ((Object)(object)Instance == (Object)(object)this)
			{
				Instance = null;
			}
		}
	}
}