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 AutoRechargeHelper v1.0.0
plugins/AutoRechargeHelper.dll
Decompiled a week agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: IgnoresAccessChecksTo("")] [assembly: AssemblyCompany("Kai")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+affca2df2734f3c3721110c096a78cef5520d739")] [assembly: AssemblyProduct("AutoRechargeHelper")] [assembly: AssemblyTitle("AutoRechargeHelper")] [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 AutoRechargeHelper { [BepInPlugin("Kai.AutoRechargeHelper", "AutoRechargeHelper", "1.0.0")] public sealed class AutoRechargeHelper : BaseUnityPlugin { public static ConfigEntry<bool> EnableMod; public static ConfigEntry<bool> FirstTimeOnly; public static ConfigEntry<string> BlacklistItems; public static ConfigEntry<bool> EnableLogging; public static ConfigEntry<bool> RunIsMainLevel; public static ConfigEntry<bool> ChargeInTruck; internal static AutoRechargeHelper Instance { get; private set; } internal static ManualLogSource Log => ((BaseUnityPlugin)Instance).Logger; internal Harmony? Harmony { get; private set; } private void Awake() { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown Instance = this; LoadConfig(); AutoRechargeRuntime.ReloadBlacklist(); Harmony = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID); Harmony.PatchAll(); Log.LogInfo((object)$"{((BaseUnityPlugin)this).Info.Metadata.GUID} v{((BaseUnityPlugin)this).Info.Metadata.Version} loaded."); } private void OnDestroy() { Harmony? harmony = Harmony; if (harmony != null) { harmony.UnpatchSelf(); } } private void LoadConfig() { EnableMod = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "EnableMod", true, "Mod全体の有効化 / Enable or disable this mod."); FirstTimeOnly = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "FirstTimeOnly", true, "初回のみマークし、満充電後は再充電しない / Mark batteries only once; disable recharging after fully charged."); BlacklistItems = ((BaseUnityPlugin)this).Config.Bind<string>("General", "Blacklist", "Rubber Duck", "自動充電対象から除外するアイテム名(部分一致、カンマ区切り) / Exclude specific items from auto-recharge (partial match, comma-separated)."); EnableLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "EnableLogging", false, "ログ出力を有効化 / Enable detailed log output."); RunIsMainLevel = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "RunIsMainLevel", true, "通常ステージでも自動充電対象の管理を有効化する / Enable auto recharge in main levels."); ChargeInTruck = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ChargeInTruck", true, "アイテムがTruck内にある時だけ自動充電する / Only auto charge items while they are inside the truck."); BlacklistItems.SettingChanged += delegate { AutoRechargeRuntime.ReloadBlacklist(); }; } internal static void LogInfo(string message) { if (EnableLogging.Value) { Log.LogInfo((object)message); } } internal static void LogWarning(string message) { if (EnableLogging.Value) { Log.LogWarning((object)message); } } } internal static class AutoRechargeRuntime { private static readonly HashSet<ItemBattery> Marked = new HashSet<ItemBattery>(); private static readonly HashSet<ItemBattery> Finished = new HashSet<ItemBattery>(); private static HashSet<string> _blacklistSet = new HashSet<string>(); private static float scanIntervalSeconds = 10f; private static float _nextScanTime; internal static void ReloadBlacklist() { _blacklistSet = (from x in AutoRechargeHelper.BlacklistItems.Value.Split(',') select x.Trim().ToLowerInvariant() into x where !string.IsNullOrWhiteSpace(x) select x).ToHashSet(); } internal static bool CanRunInCurrentScene() { if (SemiFunc.RunIsLobby()) { return true; } if (AutoRechargeHelper.RunIsMainLevel.Value && SemiFunc.RunIsLevel()) { return true; } return false; } internal static bool IsBatteryInTruck(ItemBattery battery) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)battery == (Object)null) { return false; } if (SemiFunc.RunIsLobby()) { return true; } RoomVolume val = default(RoomVolume); Vector3 val2 = default(Vector3); if (SemiFunc.GetRoomVolumeAtPosition(((Component)battery).transform.position, ref val, ref val2) && (Object)(object)val != (Object)null && val.Truck) { return true; } if (TryGetBatteryOwnerAvatar(battery, out PlayerAvatar ownerAvatar)) { if ((Object)(object)ownerAvatar != (Object)null && (Object)(object)ownerAvatar.RoomVolumeCheck != (Object)null) { return ownerAvatar.RoomVolumeCheck.inTruck; } return false; } return false; } internal static bool TryGetBatteryOwnerAvatar(ItemBattery battery, out PlayerAvatar ownerAvatar) { ownerAvatar = null; if ((Object)(object)battery == (Object)null || (Object)(object)StatsManager.instance == (Object)null || (Object)(object)GameDirector.instance == (Object)null) { return false; } ItemAttributes component = ((Component)battery).GetComponent<ItemAttributes>(); if ((Object)(object)component == (Object)null || string.IsNullOrEmpty(component.instanceName)) { return false; } int hashCode = component.instanceName.GetHashCode(); foreach (PlayerAvatar player in GameDirector.instance.PlayerList) { if (!((Object)(object)player == (Object)null) && !string.IsNullOrEmpty(player.steamID)) { string steamID = player.steamID; if (StatsManager.instance.playerInventorySpot1Taken.TryGetValue(steamID, out var value) && value == 1 && StatsManager.instance.playerInventorySpot1.TryGetValue(steamID, out var value2) && value2 == hashCode) { ownerAvatar = player; return true; } if (StatsManager.instance.playerInventorySpot2Taken.TryGetValue(steamID, out var value3) && value3 == 1 && StatsManager.instance.playerInventorySpot2.TryGetValue(steamID, out var value4) && value4 == hashCode) { ownerAvatar = player; return true; } if (StatsManager.instance.playerInventorySpot3Taken.TryGetValue(steamID, out var value5) && value5 == 1 && StatsManager.instance.playerInventorySpot3.TryGetValue(steamID, out var value6) && value6 == hashCode) { ownerAvatar = player; return true; } } } return false; } internal static bool IsBlacklisted(string itemName) { if (string.IsNullOrWhiteSpace(itemName)) { return false; } string normalized = itemName.Replace("(Clone)", string.Empty).Trim().ToLowerInvariant(); return _blacklistSet.Any((string bad) => normalized.Contains(bad)); } internal static bool IsMarked(ItemBattery battery) { if ((Object)(object)battery != (Object)null) { return Marked.Contains(battery); } return false; } internal static bool IsFinished(ItemBattery battery) { if ((Object)(object)battery != (Object)null) { return Finished.Contains(battery); } return false; } internal static void ClearMarks() { Marked.Clear(); Finished.Clear(); AutoRechargeHelper.LogInfo("[ARH] Cleared all battery marks."); } internal static void CleanupInvalidEntries() { Marked.RemoveWhere((ItemBattery b) => (Object)(object)b == (Object)null); Finished.RemoveWhere((ItemBattery b) => (Object)(object)b == (Object)null); } internal static void ScanAndMarkAll() { if (!SemiFunc.IsMasterClientOrSingleplayer()) { return; } CleanupInvalidEntries(); ItemBattery[] array = Object.FindObjectsByType<ItemBattery>((FindObjectsSortMode)0); int num = 0; ItemBattery[] array2 = array; foreach (ItemBattery battery in array2) { if (CanMark(battery) && MarkBattery(battery)) { num++; } } AutoRechargeHelper.LogInfo($"[ARH] Scan complete. Marked batteries: {num}"); } internal static bool MarkBattery(ItemBattery battery) { if (!CanMark(battery)) { return false; } if (Marked.Add(battery)) { AutoRechargeHelper.LogInfo("[ARH] Marked: " + ((Object)battery).name); return true; } return false; } internal static void UnmarkBattery(ItemBattery battery) { if (!((Object)(object)battery == (Object)null) && Marked.Remove(battery)) { if (AutoRechargeHelper.FirstTimeOnly.Value) { Finished.Add(battery); } AutoRechargeHelper.LogInfo("[ARH] Unmarked: " + ((Object)battery).name); } } public static float SetNextScanTime() { return _nextScanTime = Time.time + scanIntervalSeconds; } internal static void Tick() { if (!AutoRechargeHelper.EnableMod.Value) { return; } CleanupInvalidEntries(); if (Time.time >= _nextScanTime) { _nextScanTime = SetNextScanTime(); ScanAndMarkAll(); } if (!AutoRechargeHelper.FirstTimeOnly.Value) { return; } foreach (ItemBattery item in Marked.ToList()) { if (!((Object)(object)item == (Object)null) && item.batteryLifeInt >= item.batteryBars) { UnmarkBattery(item); } } } internal static void AddMarkedBatteriesToStation(ChargingStation station) { if ((Object)(object)station == (Object)null) { return; } foreach (ItemBattery item in Marked) { if (!((Object)(object)item == (Object)null) && (!IsFinished(item) || !AutoRechargeHelper.FirstTimeOnly.Value) && item.batteryLifeInt < item.batteryBars && (!AutoRechargeHelper.ChargeInTruck.Value || IsBatteryInTruck(item)) && !station.itemsCharging.Contains(item)) { station.itemsCharging.Add(item); } } } private static bool CanMark(ItemBattery battery) { if (!AutoRechargeHelper.EnableMod.Value) { return false; } if ((Object)(object)battery == (Object)null) { return false; } if (IsBlacklisted(((Object)battery).name)) { return false; } if (AutoRechargeHelper.FirstTimeOnly.Value && Finished.Contains(battery)) { return false; } if (AutoRechargeHelper.FirstTimeOnly.Value && battery.batteryLifeInt >= battery.batteryBars) { return false; } return true; } } } namespace AutoRechargeHelper.Patches { [HarmonyPatch(typeof(ChargingStation))] internal static class ChargingStationPatch { [HarmonyPatch("ChargeAreaCheck")] [HarmonyPostfix] private static void ChargeAreaCheckPostfix(ChargingStation __instance) { if (AutoRechargeHelper.EnableMod.Value && SemiFunc.IsMasterClientOrSingleplayer() && AutoRechargeRuntime.CanRunInCurrentScene() && !((Object)(object)__instance == (Object)null) && !(__instance.chargeFloat <= 0f)) { AutoRechargeRuntime.AddMarkedBatteriesToStation(__instance); } } [HarmonyPatch("Update")] [HarmonyPostfix] private static void UpdatePostfix(ChargingStation __instance) { if (AutoRechargeHelper.EnableMod.Value && SemiFunc.IsMasterClientOrSingleplayer() && AutoRechargeRuntime.CanRunInCurrentScene() && !((Object)(object)__instance == (Object)null)) { AutoRechargeRuntime.Tick(); } } } [HarmonyPatch(typeof(SemiFunc), "OnLevelGenDone")] internal static class SemiFuncPatch { [CompilerGenerated] private sealed class <DelayedScan>d__1 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <DelayedScan>d__1(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds(1f); <>1__state = 1; return true; case 1: <>1__state = -1; if (!AutoRechargeHelper.EnableMod.Value) { return false; } if (!SemiFunc.IsMasterClientOrSingleplayer()) { return false; } AutoRechargeRuntime.ClearMarks(); AutoRechargeRuntime.ScanAndMarkAll(); AutoRechargeRuntime.SetNextScanTime(); 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(); } } [HarmonyPostfix] private static void Postfix() { if (AutoRechargeHelper.EnableMod.Value && SemiFunc.IsMasterClientOrSingleplayer() && AutoRechargeRuntime.CanRunInCurrentScene()) { ((MonoBehaviour)AutoRechargeHelper.Instance).StartCoroutine(DelayedScan()); } } [IteratorStateMachine(typeof(<DelayedScan>d__1))] private static IEnumerator DelayedScan() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <DelayedScan>d__1(0); } } }