using System;
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.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.SceneManagement;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Sparroh")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("AutoUpCraft")]
[assembly: AssemblyTitle("AutoUpCraft")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[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 AutoUpCraft
{
internal static class AutoUpcraftService
{
private static bool _converting;
private static bool _loggedMissingWindow;
private static bool _loggedMissingCosts;
private static bool _costsReady;
private static ResourceCost[] _toRare;
private static ResourceCost[] _toEpic;
private static ResourceCost[] _toExotic;
private static readonly FieldInfo UpcraftToRareCostField = AccessTools.Field(typeof(CraftingWindow), "upcraftToRareCost");
private static readonly FieldInfo UpcraftToEpicCostField = AccessTools.Field(typeof(CraftingWindow), "upcraftToEpicCost");
private static readonly FieldInfo UpcraftToExoticCostField = AccessTools.Field(typeof(CraftingWindow), "upcraftToExoticCost");
private static readonly FieldInfo ResourcesField = AccessTools.Field(typeof(PlayerData), "resources");
private static readonly MethodInfo InvokeResourceUpdateMethod = AccessTools.Method(typeof(PlayerData), "InvokeResourceUpdate", (Type[])null, (Type[])null);
public static bool IsConverting => _converting;
public static bool WouldOvercap(PlayerResource resource, int amountBeforeAdd, int amountAdded)
{
if ((Object)(object)resource == (Object)null || amountAdded <= 0)
{
return false;
}
return amountBeforeAdd + amountAdded > resource.Max;
}
public static void TryAutoUpcraftFromOverflow(PlayerResource overflowedScrap)
{
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
//IL_0033: Invalid comparison between Unknown and I4
//IL_004a: Unknown result type (might be due to invalid IL or missing references)
//IL_0063: Unknown result type (might be due to invalid IL or missing references)
//IL_0064: Unknown result type (might be due to invalid IL or missing references)
if (_converting || (Object)(object)overflowedScrap == (Object)null || PlayerData.Instance == null || (Object)(object)Global.Instance == (Object)null || !TryGetScrapRarity(overflowedScrap, out var rarity))
{
return;
}
if ((int)rarity >= 3)
{
ClampResource(overflowedScrap);
return;
}
if (!EnsureCostsCached())
{
ClampResource(overflowedScrap);
return;
}
if (!TryGetNextTierRecipe(rarity, out var toRarity, out var cost))
{
ClampResource(overflowedScrap);
return;
}
_converting = true;
try
{
ConvertWhileCapped(rarity, toRarity, cost);
}
catch (Exception arg)
{
SparrohPlugin.Log.LogError((object)$"Auto upcraft failed: {arg}");
}
finally
{
ClampResource(overflowedScrap);
_converting = false;
}
}
private static bool TryGetNextTierRecipe(Rarity fromRarity, out Rarity toRarity, out ResourceCost[] cost)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: Expected I4, but got Unknown
switch ((int)fromRarity)
{
case 0:
toRarity = (Rarity)1;
cost = _toRare;
if (cost != null)
{
return cost.Length != 0;
}
return false;
case 1:
toRarity = (Rarity)2;
cost = _toEpic;
if (cost != null)
{
return cost.Length != 0;
}
return false;
case 2:
toRarity = (Rarity)3;
cost = _toExotic;
if (cost != null)
{
return cost.Length != 0;
}
return false;
default:
toRarity = (Rarity)(-1);
cost = null;
return false;
}
}
public static void RestoreUnclampedTotal(PlayerResource resource, int amountBeforeAdd, int amountAdded)
{
if ((Object)(object)resource == (Object)null || amountAdded <= 0 || PlayerData.Instance == null)
{
return;
}
int num = amountBeforeAdd + amountAdded;
if (num > resource.Max)
{
int resource2 = PlayerData.Instance.GetResource(resource);
if (resource2 < num)
{
SetResourceRaw(resource, num);
SparrohPlugin.Log.LogDebug((object)($"Restored overflow for {resource.ID}: clamped {resource2} → unclamped {num} " + $"(before {amountBeforeAdd} + {amountAdded})"));
}
}
}
private static bool ConvertWhileCapped(Rarity fromRarity, Rarity toRarity, ResourceCost[] cost)
{
//IL_0009: 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_0084: Unknown result type (might be due to invalid IL or missing references)
//IL_008a: Unknown result type (might be due to invalid IL or missing references)
if (cost == null || cost.Length == 0)
{
return false;
}
PlayerResource scrap = GetScrap(fromRarity);
PlayerResource scrap2 = GetScrap(toRarity);
if ((Object)(object)scrap == (Object)null || (Object)(object)scrap2 == (Object)null)
{
return false;
}
PlayerData instance = PlayerData.Instance;
bool result = false;
int num = 0;
while (num++ < 10000)
{
int resource = instance.GetResource(scrap);
if (resource < scrap.Max || instance.GetResource(scrap2) >= scrap2.Max || !instance.CanAffordCost(cost) || !instance.TryRemoveResources(cost))
{
break;
}
instance.AddResource(scrap2, 1, false);
result = true;
SparrohPlugin.Log.LogDebug((object)($"Upcrafted {fromRarity} scrap → 1 {toRarity} scrap " + $"(was {resource}/{scrap.Max})"));
}
return result;
}
private static void ClampResource(PlayerResource scrap)
{
if (!((Object)(object)scrap == (Object)null) && PlayerData.Instance != null)
{
int resource = PlayerData.Instance.GetResource(scrap);
if (resource > scrap.Max)
{
SetResourceRaw(scrap, scrap.Max);
SparrohPlugin.Log.LogDebug((object)$"Clamped {scrap.ID} from {resource} to {scrap.Max}");
}
}
}
private static void SetResourceRaw(PlayerResource resource, int amount, bool invokeUpdate = true)
{
Dictionary<string, int> resourcesDictionary = GetResourcesDictionary();
if (resourcesDictionary != null && !((Object)(object)resource == (Object)null))
{
resourcesDictionary[resource.ID] = amount;
if (invokeUpdate)
{
InvokeResourceUpdate();
}
}
}
private static Dictionary<string, int> GetResourcesDictionary()
{
if (PlayerData.Instance == null || ResourcesField == null)
{
return null;
}
return ResourcesField.GetValue(PlayerData.Instance) as Dictionary<string, int>;
}
private static void InvokeResourceUpdate()
{
try
{
InvokeResourceUpdateMethod?.Invoke(null, null);
}
catch (Exception ex)
{
SparrohPlugin.Log.LogDebug((object)("InvokeResourceUpdate failed: " + ex.Message));
}
}
private static PlayerResource GetScrap(Rarity rarity)
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_000d: Expected I4, but got Unknown
RarityData[] rarities = Global.Instance.Rarities;
int num = (int)rarity;
if (rarities == null || num < 0 || num >= rarities.Length)
{
return null;
}
return rarities[num].scrapResource;
}
private static bool TryGetScrapRarity(PlayerResource resource, out Rarity rarity)
{
rarity = (Rarity)(-1);
if ((Object)(object)resource == (Object)null || Global.Instance?.Rarities == null)
{
return false;
}
RarityData[] rarities = Global.Instance.Rarities;
int num = Math.Min(rarities.Length, 4);
for (int i = 0; i < num; i++)
{
if ((Object)(object)rarities[i].scrapResource == (Object)(object)resource)
{
rarity = (Rarity)(sbyte)i;
return true;
}
}
return false;
}
private static bool EnsureCostsCached()
{
if (_costsReady)
{
return true;
}
CraftingWindow val = FindCraftingWindow();
if ((Object)(object)val == (Object)null)
{
if (!_loggedMissingWindow)
{
_loggedMissingWindow = true;
SparrohPlugin.Log.LogWarning((object)"CraftingWindow not found yet; auto-upcraft will retry when scrap overcaps.");
}
return false;
}
_toRare = UpcraftToRareCostField?.GetValue(val) as ResourceCost[];
_toEpic = UpcraftToEpicCostField?.GetValue(val) as ResourceCost[];
_toExotic = UpcraftToExoticCostField?.GetValue(val) as ResourceCost[];
if (!IsValidCost(_toRare) || !IsValidCost(_toEpic) || !IsValidCost(_toExotic))
{
if (!_loggedMissingCosts)
{
_loggedMissingCosts = true;
SparrohPlugin.Log.LogError((object)"Failed to read vanilla upcraft costs from CraftingWindow. Auto-upcraft disabled until costs are available.");
}
return false;
}
_costsReady = true;
_loggedMissingWindow = false;
_loggedMissingCosts = false;
SparrohPlugin.Log.LogInfo((object)("Cached vanilla upcraft costs (Rare: " + FormatCost(_toRare) + ", Epic: " + FormatCost(_toEpic) + ", Exotic: " + FormatCost(_toExotic) + ")"));
return true;
}
private static bool IsValidCost(ResourceCost[] cost)
{
if (cost == null || cost.Length == 0)
{
return false;
}
for (int i = 0; i < cost.Length; i++)
{
if ((Object)(object)cost[i].resource == (Object)null || cost[i].count < 1)
{
return false;
}
}
return true;
}
private static string FormatCost(ResourceCost[] cost)
{
List<string> list = new List<string>(cost.Length);
for (int i = 0; i < cost.Length; i++)
{
string arg = (((Object)(object)cost[i].resource != (Object)null) ? cost[i].resource.ID : "?");
list.Add($"{cost[i].count}x {arg}");
}
return string.Join(" + ", list);
}
private static CraftingWindow FindCraftingWindow()
{
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
CraftingWindow[] array = Resources.FindObjectsOfTypeAll<CraftingWindow>();
if (array == null || array.Length == 0)
{
return null;
}
foreach (CraftingWindow val in array)
{
if (!((Object)(object)val == (Object)null))
{
Scene scene = ((Component)val).gameObject.scene;
if (((Scene)(ref scene)).IsValid())
{
return val;
}
}
}
return array[0];
}
public static bool IsUpgradeScrap(PlayerResource resource)
{
Rarity rarity;
return TryGetScrapRarity(resource, out rarity);
}
}
[BepInPlugin("sparroh.autoupcraft", "AutoUpCraft", "1.0.0")]
[MycoMod(/*Could not decode attribute arguments.*/)]
public class SparrohPlugin : BaseUnityPlugin
{
public const string PluginGUID = "sparroh.autoupcraft";
public const string PluginName = "AutoUpCraft";
public const string PluginVersion = "1.0.0";
internal static ManualLogSource Log;
private Harmony _harmony;
private void Awake()
{
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Expected O, but got Unknown
Log = ((BaseUnityPlugin)this).Logger;
_harmony = new Harmony("sparroh.autoupcraft");
_harmony.PatchAll();
Log.LogInfo((object)"AutoUpCraft v1.0.0 loaded");
}
}
public static class MyPluginInfo
{
public const string PLUGIN_GUID = "AutoUpCraft";
public const string PLUGIN_NAME = "AutoUpCraft";
public const string PLUGIN_VERSION = "1.0.0";
}
}
namespace AutoUpCraft.Patches
{
[HarmonyPatch(typeof(PlayerData), "AddResource")]
internal static class PlayerDataAddResourcePatch
{
[HarmonyPrefix]
private static void Prefix(PlayerResource resource, int amount, ref int __state)
{
__state = -1;
if (amount > 0 && !((Object)(object)resource == (Object)null) && !AutoUpcraftService.IsConverting && AutoUpcraftService.IsUpgradeScrap(resource) && PlayerData.Instance != null)
{
__state = PlayerData.Instance.GetResource(resource);
}
}
[HarmonyPostfix]
private static void Postfix(PlayerResource resource, int amount, int __state)
{
if (amount > 0 && !((Object)(object)resource == (Object)null) && !AutoUpcraftService.IsConverting && AutoUpcraftService.IsUpgradeScrap(resource) && __state >= 0 && AutoUpcraftService.WouldOvercap(resource, __state, amount))
{
AutoUpcraftService.RestoreUnclampedTotal(resource, __state, amount);
AutoUpcraftService.TryAutoUpcraftFromOverflow(resource);
}
}
}
}
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
internal sealed class IgnoresAccessChecksToAttribute : Attribute
{
public IgnoresAccessChecksToAttribute(string assemblyName)
{
}
}
}