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 EnergyCrystalAutoRefill v4.0.0
EnergyCrystalAutoRefill.dll
Decompiled a week 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 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; } } } }