using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using Common;
using HarmonyLib;
using Jotunn;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("CraftedBossDrops")]
[assembly: AssemblyDescription("https://thunderstore.io/c/valheim/p/probablykory/CraftedBossDrops/")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("probablykory")]
[assembly: AssemblyCopyright("Copyright probablykory © 2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("e3243d22-4307-4008-ba36-9f326008cde5")]
[assembly: AssemblyFileVersion("1.0.9")]
[assembly: AssemblyProduct("CraftedBossDrops")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.9.0")]
[module: <2bbef6a2-ec2f-455d-af37-047412e59296>RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[<d8c74559-f18f-47c0-ad96-ff69778ec96d>Embedded]
internal sealed class <d8c74559-f18f-47c0-ad96-ff69778ec96d>EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
[<d8c74559-f18f-47c0-ad96-ff69778ec96d>Embedded]
[CompilerGenerated]
internal sealed class <2bbef6a2-ec2f-455d-af37-047412e59296>RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public <2bbef6a2-ec2f-455d-af37-047412e59296>RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace CraftedBossDrops
{
public class Entries
{
private Action<object, EventArgs> _action;
public string Name { get; set; } = string.Empty;
public ConfigEntry<string> Table { get; set; }
public ConfigEntry<int> MinTableLevel { get; set; }
public ConfigEntry<int> Amount { get; set; }
public ConfigEntry<string> Requirements { get; set; }
public static Entries GetFromProps(IPlugin instance, string name, string table, int minTableLevel, int amount, string requirements)
{
//IL_0043: Unknown result type (might be due to invalid IL or missing references)
//IL_004d: Expected O, but got Unknown
//IL_0084: Unknown result type (might be due to invalid IL or missing references)
//IL_008e: Expected O, but got Unknown
//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
//IL_00d0: Expected O, but got Unknown
//IL_010b: Unknown result type (might be due to invalid IL or missing references)
//IL_0110: Unknown result type (might be due to invalid IL or missing references)
//IL_0117: Unknown result type (might be due to invalid IL or missing references)
//IL_0124: Expected O, but got Unknown
//IL_0124: Unknown result type (might be due to invalid IL or missing references)
//IL_012e: Expected O, but got Unknown
Entries entries = new Entries();
entries.Name = name;
entries.Table = instance.Config(entries.Name, "Table", table, new ConfigDescription("Crafting station needed to craft " + entries.Name + ".", (AcceptableValueBase)(object)CraftingStations.GetAcceptableValueList(), new object[1] { ConfigHelper.GetAdminOnlyFlag() }));
entries.MinTableLevel = instance.Config(entries.Name, "Table Level", minTableLevel, new ConfigDescription("Level of crafting station required to craft " + entries.Name + ".", (AcceptableValueBase)null, new object[1] { ConfigHelper.GetAdminOnlyFlag() }));
entries.Amount = instance.Config(entries.Name, "Amount", amount, new ConfigDescription("The amount of " + entries.Name + " created.", (AcceptableValueBase)null, new object[1] { ConfigHelper.GetAdminOnlyFlag() }));
entries.Requirements = instance.Config(entries.Name, "Requirements", requirements, new ConfigDescription("The required items to craft " + entries.Name + ".", (AcceptableValueBase)(object)new AcceptableValueConfigNote("You must use valid spawn item codes."), new object[1] { (object)new ConfigurationManagerAttributes
{
IsAdminOnly = true,
CustomDrawer = SharedDrawers.DrawReqConfigTable()
} }));
return entries;
}
private void OnSettingChanged(object sender, EventArgs e)
{
if (_action != null)
{
_action(sender, e);
}
}
public void AddSettingsChangedHandler(Action<object, EventArgs> action)
{
_action = action;
Table.SettingChanged += OnSettingChanged;
MinTableLevel.SettingChanged += OnSettingChanged;
Amount.SettingChanged += OnSettingChanged;
Requirements.SettingChanged += OnSettingChanged;
}
public void RemoveSettingsChangedHandler()
{
Table.SettingChanged -= OnSettingChanged;
MinTableLevel.SettingChanged -= OnSettingChanged;
Amount.SettingChanged -= OnSettingChanged;
Requirements.SettingChanged -= OnSettingChanged;
_action = null;
}
}
[BepInDependency(/*Could not decode attribute arguments.*/)]
[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInPlugin("probablykory.CraftedBossDrops", "CraftedBossDrops", "1.0.9")]
internal class CraftedBossDrops : BaseUnityPlugin, IPlugin
{
public const string PluginAuthor = "probablykory";
public const string PluginName = "CraftedBossDrops";
public const string PluginVersion = "1.0.9";
public const string PluginGUID = "probablykory.CraftedBossDrops";
private bool settingsUpdated;
private Harmony harmony;
internal static CraftedBossDrops Instance;
private static ConfigEntry<bool> isDebugEnabled;
private CustomRecipe hardAntlerRecipe;
private CustomRecipe cryptKeyRecipe;
private CustomRecipe wishboneRecipe;
private CustomRecipe dragonTearRecipe;
private CustomRecipe yagluthDropRecipe;
private CustomRecipe queenDropRecipe;
private CustomRecipe faderDropRecipe;
public ManualLogSource Logger { get; private set; } = Logger.CreateLogSource("CraftedBossDrops");
public bool Debug
{
get
{
if (isDebugEnabled == null)
{
return true;
}
return isDebugEnabled.Value;
}
}
public Entries HardAntlerEntry { get; protected set; }
public Entries CryptKeyEntry { get; protected set; }
public Entries WishboneEntry { get; protected set; }
public Entries DragonTearEntry { get; protected set; }
public Entries YagluthDropEntry { get; protected set; }
public Entries QueenDropEntry { get; protected set; }
public Entries FaderDropEntry { get; protected set; }
private void Awake()
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: Expected O, but got Unknown
harmony = new Harmony("probablykory.CraftedBossDrops");
harmony.PatchAll();
isDebugEnabled = this.Config("1 - General", "Debugging Enabled", value: false, "If on, mod will output alot more information in the debug log level.");
Instance = this;
InitializeFeatures();
PrefabManager.OnVanillaPrefabsAvailable += OnVanillaPrefabsAvailable;
SynchronizationManager.OnConfigurationSynchronized += OnConfigurationSynchronized;
((BaseUnityPlugin)this).Config.ConfigReloaded += OnConfigReloaded;
new ConfigWatcher(this);
}
private void InitializeFeatures()
{
HardAntlerEntry = Entries.GetFromProps(Instance, "HardAntler", "Workbench", 3, 1, "TrophyDeer:10,Resin:20");
CryptKeyEntry = Entries.GetFromProps(Instance, "CryptKey", "Forge", 3, 1, "AncientSeed:6,Bronze:20");
WishboneEntry = Entries.GetFromProps(Instance, "Wishbone", "Forge", 7, 1, "WitheredBone:15,Iron:10,TrophyDraugr:3");
DragonTearEntry = Entries.GetFromProps(Instance, "DragonTear", "Workbench", 5, 2, "DragonEgg:4,Crystal:16");
YagluthDropEntry = Entries.GetFromProps(Instance, "YagluthDrop", "ArtisanTable", 1, 2, "GoblinTotem:10,TrophyGoblin:3,TrophyGoblinShaman:1,TrophyGoblinBrute:1");
QueenDropEntry = Entries.GetFromProps(Instance, "QueenDrop", "BlackForge", 2, 1, "DvergrKeyFragment:10,Mandible:5,TrophySeeker:3,TrophySeekerBrute:1");
FaderDropEntry = Entries.GetFromProps(Instance, "FaderDrop", "ArtisanTable", 2, 1, "BellFragment:10,MorgenHeart:5,TrophyCharredMelee:4,TrophyCharredMage:1");
HardAntlerEntry.AddSettingsChangedHandler(OnSettingsChanged);
CryptKeyEntry.AddSettingsChangedHandler(OnSettingsChanged);
WishboneEntry.AddSettingsChangedHandler(OnSettingsChanged);
DragonTearEntry.AddSettingsChangedHandler(OnSettingsChanged);
YagluthDropEntry.AddSettingsChangedHandler(OnSettingsChanged);
QueenDropEntry.AddSettingsChangedHandler(OnSettingsChanged);
FaderDropEntry.AddSettingsChangedHandler(OnSettingsChanged);
}
private void UpdateFeatures()
{
settingsUpdated = false;
hardAntlerRecipe.Update(getRecipeFromEntry(HardAntlerEntry));
cryptKeyRecipe.Update(getRecipeFromEntry(CryptKeyEntry));
wishboneRecipe.Update(getRecipeFromEntry(WishboneEntry));
dragonTearRecipe.Update(getRecipeFromEntry(DragonTearEntry));
yagluthDropRecipe.Update(getRecipeFromEntry(YagluthDropEntry));
queenDropRecipe.Update(getRecipeFromEntry(QueenDropEntry));
faderDropRecipe.Update(getRecipeFromEntry(FaderDropEntry));
}
private void OnVanillaPrefabsAvailable()
{
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_0022: Expected O, but got Unknown
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_0039: Expected O, but got Unknown
//IL_0046: Unknown result type (might be due to invalid IL or missing references)
//IL_0050: Expected O, but got Unknown
//IL_005d: Unknown result type (might be due to invalid IL or missing references)
//IL_0067: Expected O, but got Unknown
//IL_0074: Unknown result type (might be due to invalid IL or missing references)
//IL_007e: Expected O, but got Unknown
//IL_008b: Unknown result type (might be due to invalid IL or missing references)
//IL_0095: Expected O, but got Unknown
//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
//IL_00ac: Expected O, but got Unknown
this.LogDebugOnly("Vanilla Prefabs Available received.");
hardAntlerRecipe = new CustomRecipe(getRecipeFromEntry(HardAntlerEntry));
cryptKeyRecipe = new CustomRecipe(getRecipeFromEntry(CryptKeyEntry));
wishboneRecipe = new CustomRecipe(getRecipeFromEntry(WishboneEntry));
dragonTearRecipe = new CustomRecipe(getRecipeFromEntry(DragonTearEntry));
yagluthDropRecipe = new CustomRecipe(getRecipeFromEntry(YagluthDropEntry));
queenDropRecipe = new CustomRecipe(getRecipeFromEntry(QueenDropEntry));
faderDropRecipe = new CustomRecipe(getRecipeFromEntry(FaderDropEntry));
ItemManager.Instance.AddRecipe(hardAntlerRecipe);
ItemManager.Instance.AddRecipe(cryptKeyRecipe);
ItemManager.Instance.AddRecipe(wishboneRecipe);
ItemManager.Instance.AddRecipe(dragonTearRecipe);
ItemManager.Instance.AddRecipe(yagluthDropRecipe);
ItemManager.Instance.AddRecipe(queenDropRecipe);
ItemManager.Instance.AddRecipe(faderDropRecipe);
PrefabManager.OnVanillaPrefabsAvailable -= OnVanillaPrefabsAvailable;
}
private void OnSettingsChanged(object sender, EventArgs e)
{
settingsUpdated = true;
}
private void OnConfigReloaded(object sender, EventArgs e)
{
if (settingsUpdated)
{
UpdateFeatures();
}
}
private void OnConfigurationSynchronized(object sender, ConfigurationSynchronizationEventArgs e)
{
UpdateFeatures();
}
private RecipeConfig getRecipeFromEntry(Entries entry)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
//IL_004e: Unknown result type (might be due to invalid IL or missing references)
//IL_005f: Unknown result type (might be due to invalid IL or missing references)
//IL_0076: Expected O, but got Unknown
return new RecipeConfig
{
Item = entry.Name,
CraftingStation = CraftingStations.GetInternalName(entry.Table.Value),
RepairStation = CraftingStations.GetInternalName(entry.Table.Value),
MinStationLevel = entry.MinTableLevel.Value,
Amount = entry.Amount.Value,
Requirements = RequirementsEntry.Deserialize(entry.Requirements.Value)
};
}
ConfigFile IPlugin.get_Config()
{
return ((BaseUnityPlugin)this).Config;
}
}
public static class Extensions
{
private static HashSet<CustomRecipe> hashsetRecipes;
public static Recipe GetRecipe(this List<Recipe> list, Recipe recipe)
{
int num = ObjectDB.instance.m_recipes.IndexOf(recipe);
if (num > -1)
{
return list[num];
}
string name = ((object)recipe).ToString();
return ((IEnumerable<Recipe>)ObjectDB.instance.m_recipes).FirstOrDefault((Func<Recipe, bool>)((Recipe r) => name.Equals(((object)r).ToString())));
}
public static bool Update(this CustomRecipe recipe, RecipeConfig newRecipe)
{
//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
//IL_00e7: Expected O, but got Unknown
//IL_0208: Unknown result type (might be due to invalid IL or missing references)
//IL_0212: Expected O, but got Unknown
if (hashsetRecipes == null)
{
FieldInfo fieldInfo = ((object)ItemManager.Instance).GetType().GetMembers(BindingFlags.Instance | BindingFlags.NonPublic).FirstOrDefault((MemberInfo m) => m.Name == "Recipes") as FieldInfo;
if (fieldInfo != null && fieldInfo.GetValue(ItemManager.Instance) is HashSet<CustomRecipe> hashSet)
{
hashsetRecipes = hashSet;
}
}
Recipe recipe2 = ObjectDB.instance.m_recipes.GetRecipe(recipe.Recipe);
if ((Object)(object)recipe2 == (Object)null)
{
if (hashsetRecipes != null && hashsetRecipes.Contains(recipe))
{
IPlugin plugin = Get.Plugin;
object obj;
if (recipe == null)
{
obj = null;
}
else
{
Recipe recipe3 = recipe.Recipe;
obj = ((recipe3 != null) ? ((Object)recipe3).name : null);
}
plugin.LogDebugOnly("Removing and re-adding recipe " + (string?)obj + " in ItemManager.");
ItemManager.Instance.RemoveRecipe(recipe);
ItemManager.Instance.AddRecipe(new CustomRecipe(newRecipe));
return true;
}
object obj2;
if (recipe == null)
{
obj2 = null;
}
else
{
Recipe recipe4 = recipe.Recipe;
obj2 = ((recipe4 != null) ? ((Object)recipe4).name : null);
}
Logger.LogError((object)("Error updating recipe " + (string?)obj2 + ", did not find existing recipe in ObjectDB or ItemManager"));
return false;
}
IPlugin plugin2 = Get.Plugin;
object obj3;
if (recipe == null)
{
obj3 = null;
}
else
{
Recipe recipe5 = recipe.Recipe;
obj3 = ((recipe5 != null) ? ((Object)recipe5).name : null);
}
plugin2.LogDebugOnly("Updating recipe " + (string?)obj3 + " in place.");
recipe2.m_amount = newRecipe.Amount;
recipe2.m_minStationLevel = newRecipe.MinStationLevel;
GameObject prefab = PrefabManager.Instance.GetPrefab(newRecipe.CraftingStation);
recipe2.m_craftingStation = ((prefab != null) ? prefab.GetComponent<CraftingStation>() : null);
recipe2.m_resources = newRecipe.GetRequirements();
Requirement[] resources = recipe2.m_resources;
foreach (Requirement val in resources)
{
GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(((Object)val.m_resItem).name.Replace("JVLmock_", ""));
if ((Object)(object)itemPrefab != (Object)null)
{
val.m_resItem = itemPrefab.GetComponent<ItemDrop>();
}
}
if (hashsetRecipes != null)
{
hashsetRecipes.Remove(recipe);
hashsetRecipes.Add(new CustomRecipe(recipe2, false, false));
}
return true;
}
}
[HarmonyPatch]
public static class TraderPatch
{
private static Dictionary<string, string> GlobalKeyTokenMap = new Dictionary<string, string>
{
{ "defeated_eikthyr", "$item_hardantler" },
{ "defeated_gdking", "$item_cryptkey" },
{ "defeated_bonemass", "$item_wishbone" },
{ "defeated_dragon", "$item_dragontear" },
{ "defeated_goblinking", "$item_yagluththing" },
{ "defeated_queen", "$item_queen_drop" },
{ "defeated_fader", "$item_fader_drop" }
};
[HarmonyPatch(typeof(Trader), "GetAvailableItems")]
[HarmonyPostfix]
public static List<TradeItem> TraderGetAvailableItems(List<TradeItem> values, Trader __instance)
{
if ((Object)(object)__instance == (Object)null)
{
return values;
}
if (((__instance == null) ? null : ((Object)__instance).name?.Contains("Haldor")).Value || ((__instance == null) ? null : ((Object)__instance).name?.Contains("BogWitch")).Value)
{
List<TradeItem> list = new List<TradeItem>();
{
foreach (TradeItem item in __instance.m_items)
{
if (string.IsNullOrEmpty(item.m_requiredGlobalKey) || ZoneSystem.instance.GetGlobalKey(item.m_requiredGlobalKey) || (GlobalKeyTokenMap.ContainsKey(item.m_requiredGlobalKey) && Player.m_localPlayer.IsKnownMaterial(GlobalKeyTokenMap[item.m_requiredGlobalKey])))
{
list.Add(item);
}
}
return list;
}
}
return values;
}
[HarmonyPrefix]
[HarmonyPatch(typeof(Player), "AddKnownItem")]
public static void PlayerAddKnownItem(ItemData item, Player __instance)
{
object obj;
if (item == null)
{
obj = null;
}
else
{
GameObject dropPrefab = item.m_dropPrefab;
obj = ((dropPrefab != null) ? ((Object)dropPrefab).name : null);
}
string text = (string)obj;
if (!string.IsNullOrEmpty(text) && string.Equals(text, "HardAntler") && !__instance.m_knownMaterial.Contains(item.m_shared.m_name))
{
__instance.SetSeenTutorial("blackforest");
}
}
}
}
namespace Microsoft.CodeAnalysis
{
[Microsoft.CodeAnalysis.Embedded]
[CompilerGenerated]
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]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class NullableContextAttribute : Attribute
{
public readonly byte Flag;
public NullableContextAttribute(byte P_0)
{
Flag = P_0;
}
}
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
[Microsoft.CodeAnalysis.Embedded]
[CompilerGenerated]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace Common
{
internal class AcceptableValueConfigNote : AcceptableValueBase
{
public virtual string Note { get; }
public AcceptableValueConfigNote(string note)
: base(typeof(string))
{
if (string.IsNullOrEmpty(note))
{
throw new ArgumentException("A string with atleast 1 character is needed", "Note");
}
Note = note;
}
public override object Clamp(object value)
{
return value;
}
public override bool IsValid(object value)
{
return !string.IsNullOrEmpty(value as string);
}
public override string ToDescriptionString()
{
return "# Note: " + Note;
}
}
internal static class ConfigHelper
{
public static ConfigurationManagerAttributes GetAdminOnlyFlag()
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_000d: Expected O, but got Unknown
return new ConfigurationManagerAttributes
{
IsAdminOnly = true
};
}
public static ConfigurationManagerAttributes GetTags(Action<ConfigEntryBase> action)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_000d: Expected O, but got Unknown
return new ConfigurationManagerAttributes
{
CustomDrawer = action
};
}
public static ConfigurationManagerAttributes GetTags()
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Expected O, but got Unknown
return new ConfigurationManagerAttributes();
}
public static ConfigEntry<T> Config<T>(this IPlugin instance, string group, string name, T value, ConfigDescription description)
{
return instance.Config.Bind<T>(group, name, value, description);
}
public static ConfigEntry<T> Config<T>(this IPlugin instance, string group, string name, T value, string description)
{
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_001f: Expected O, but got Unknown
return instance.Config(group, name, value, new ConfigDescription(description, (AcceptableValueBase)null, new object[1] { GetAdminOnlyFlag() }));
}
}
internal static class RequirementsEntry
{
public static RequirementConfig[] Deserialize(string reqs)
{
return ((IEnumerable<string>)reqs.Split(new char[1] { ',' })).Select((Func<string, RequirementConfig>)delegate(string r)
{
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_0020: 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_0058: Unknown result type (might be due to invalid IL or missing references)
//IL_0060: Expected O, but got Unknown
string[] array = r.Split(new char[1] { ':' });
int result;
int result2;
return new RequirementConfig
{
Item = array[0],
Amount = ((array.Length <= 1 || !int.TryParse(array[1], out result)) ? 1 : result),
AmountPerLevel = ((array.Length > 2 && int.TryParse(array[2], out result2)) ? result2 : 0),
Recover = true
};
}).ToArray();
}
public static string Serialize(RequirementConfig[] reqs)
{
return string.Join(",", reqs.Select((RequirementConfig r) => (r.AmountPerLevel <= 0) ? $"{r.Item}:{r.Amount}" : $"{r.Item}:{r.Amount}:{r.AmountPerLevel}"));
}
}
internal static class SharedDrawers
{
private static BaseUnityPlugin configManager;
private static BaseUnityPlugin GetConfigManager()
{
if ((Object)(object)configManager == (Object)null && Chainloader.PluginInfos.TryGetValue("com.bepis.bepinex.configurationmanager", out var value) && Object.op_Implicit((Object)(object)value.Instance))
{
configManager = value.Instance;
}
return configManager;
}
public static int GetRightColumnWidth()
{
int result = 130;
BaseUnityPlugin val = GetConfigManager();
if ((Object)(object)val != (Object)null)
{
PropertyInfo propertyInfo = ((object)val)?.GetType().GetProperty("RightColumnWidth", BindingFlags.Instance | BindingFlags.NonPublic);
if (propertyInfo != null)
{
result = (int)propertyInfo.GetValue(val);
}
}
return result;
}
public static void ReloadConfigDisplay()
{
BaseUnityPlugin val = GetConfigManager();
if ((Object)(object)val != (Object)null)
{
object obj = ((object)val).GetType()?.GetProperty("DisplayingWindow")?.GetValue(val);
if (obj is bool && (bool)obj)
{
((object)val).GetType().GetMethod("BuildSettingList").Invoke(val, Array.Empty<object>());
}
}
}
public static Action<ConfigEntryBase> DrawReqConfigTable(bool hasUpgrades = false)
{
return delegate(ConfigEntryBase cfg)
{
//IL_005c: Unknown result type (might be due to invalid IL or missing references)
//IL_0061: Unknown result type (might be due to invalid IL or missing references)
//IL_008d: Expected O, but got Unknown
//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
//IL_00ee: Expected O, but got Unknown
//IL_0163: Unknown result type (might be due to invalid IL or missing references)
//IL_0168: Unknown result type (might be due to invalid IL or missing references)
//IL_017d: Expected O, but got Unknown
//IL_0125: Unknown result type (might be due to invalid IL or missing references)
//IL_012a: Unknown result type (might be due to invalid IL or missing references)
//IL_013f: Expected O, but got Unknown
//IL_0184: Unknown result type (might be due to invalid IL or missing references)
//IL_0189: Unknown result type (might be due to invalid IL or missing references)
//IL_0191: Unknown result type (might be due to invalid IL or missing references)
//IL_0199: Unknown result type (might be due to invalid IL or missing references)
//IL_01a6: Expected O, but got Unknown
//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
//IL_01cf: Expected O, but got Unknown
//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
//IL_01f0: Expected O, but got Unknown
List<RequirementConfig> list = new List<RequirementConfig>();
bool flag = false;
int rightColumnWidth = GetRightColumnWidth();
GUILayout.BeginVertical(Array.Empty<GUILayoutOption>());
foreach (RequirementConfig item in RequirementsEntry.Deserialize((string)cfg.BoxedValue).ToList())
{
GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
string text = GUILayout.TextField(item.Item, new GUIStyle(GUI.skin.textField)
{
fixedWidth = rightColumnWidth - 33 - (hasUpgrades ? 37 : 0) - 21 - 21 - 12
}, Array.Empty<GUILayoutOption>());
string text2 = (string.IsNullOrEmpty(text) ? item.Item : text);
flag = flag || text2 != item.Item;
int num = item.Amount;
if (int.TryParse(GUILayout.TextField(num.ToString(), new GUIStyle(GUI.skin.textField)
{
fixedWidth = 33f
}, Array.Empty<GUILayoutOption>()), out var result) && result != num)
{
num = result;
flag = true;
}
int num2 = item.AmountPerLevel;
if (hasUpgrades && int.TryParse(GUILayout.TextField(num2.ToString(), new GUIStyle(GUI.skin.textField)
{
fixedWidth = 33f
}, Array.Empty<GUILayoutOption>()), out var result2) && result2 != num2)
{
num2 = result2;
flag = true;
}
if (GUILayout.Button("x", new GUIStyle(GUI.skin.button)
{
fixedWidth = 21f
}, Array.Empty<GUILayoutOption>()))
{
flag = true;
}
else
{
list.Add(new RequirementConfig
{
Item = text2,
Amount = num,
AmountPerLevel = num2
});
}
if (GUILayout.Button("+", new GUIStyle(GUI.skin.button)
{
fixedWidth = 21f
}, Array.Empty<GUILayoutOption>()))
{
flag = true;
list.Add(new RequirementConfig
{
Item = "<Prefab Name>",
Amount = 1
});
}
GUILayout.EndHorizontal();
}
GUILayout.EndVertical();
if (flag)
{
cfg.BoxedValue = RequirementsEntry.Serialize(list.ToArray());
}
};
}
}
internal class ConfigWatcher
{
private BaseUnityPlugin configurationManager;
private IPlugin plugin;
public ConfigWatcher(IPlugin plugin)
{
if (plugin == null)
{
throw new ArgumentNullException("plugin");
}
this.plugin = plugin;
CheckForConfigManager();
}
private void InitializeWatcher()
{
string fileName = Path.GetFileName(plugin.Config.ConfigFilePath);
new Watcher(Path.GetDirectoryName(plugin.Config.ConfigFilePath), fileName).FileChanged += OnFileChanged;
Get.Plugin.LogDebugOnly("File system watcher initialized.");
}
private void CheckForConfigManager()
{
PluginInfo value;
if (GUIManager.IsHeadless())
{
InitializeWatcher();
}
else if (Chainloader.PluginInfos.TryGetValue("com.bepis.bepinex.configurationmanager", out value) && Object.op_Implicit((Object)(object)value.Instance))
{
configurationManager = value.Instance;
Get.Plugin.LogDebugOnly("Configuration manager found, hooking DisplayingWindowChanged");
EventInfo @event = ((object)configurationManager).GetType().GetEvent("DisplayingWindowChanged");
if (@event != null)
{
Action<object, object> action = OnConfigManagerDisplayingWindowChanged;
Delegate handler = Delegate.CreateDelegate(@event.EventHandlerType, action.Target, action.Method);
@event.AddEventHandler(configurationManager, handler);
}
}
else
{
InitializeWatcher();
}
}
private void OnFileChanged(object sender, FileSystemEventArgs e)
{
string configFilePath = plugin.Config.ConfigFilePath;
if (!File.Exists(configFilePath))
{
return;
}
try
{
plugin.Config.SaveOnConfigSet = false;
plugin.Config.Reload();
plugin.Config.SaveOnConfigSet = true;
}
catch
{
Get.Plugin.LogError("There was an issue with your " + Path.GetFileName(configFilePath) + " file.");
Get.Plugin.LogError("Please check the format and spelling.");
}
}
private void OnConfigManagerDisplayingWindowChanged(object sender, object e)
{
if (!(bool)((object)configurationManager).GetType().GetProperty("DisplayingWindow").GetValue(configurationManager, null))
{
plugin.Config.SaveOnConfigSet = false;
plugin.Config.Reload();
plugin.Config.SaveOnConfigSet = true;
}
}
}
internal class CustomSyncedValueBase
{
private class Patches
{
[HarmonyPatch(typeof(ZNet), "Shutdown")]
[HarmonyPostfix]
private static void ZNet_Shutdown()
{
if (ZNetExtension.IsClientInstance(ZNet.instance))
{
foreach (CustomSyncedValueBase syncedValue in SyncedValues)
{
syncedValue.OnResetFromServer();
}
return;
}
foreach (CustomSyncedValueBase syncedValue2 in SyncedValues)
{
syncedValue2.OnServerShutdown();
}
}
}
public readonly string Name;
public readonly Type Type;
private object? boxedValue;
public object? LocalBaseValue;
private CustomRPC customRPC;
private static readonly HashSet<CustomSyncedValueBase> SyncedValues = new HashSet<CustomSyncedValueBase>();
private static Harmony harmony = null;
public bool IsSourceOfTruth { get; private set; } = true;
public object? BoxedValue
{
get
{
return boxedValue;
}
set
{
boxedValue = value;
this.ValueChanged?.Invoke(this, value);
}
}
public event Action<object, object>? ValueChanged;
protected CustomSyncedValueBase(string name, Type type, object? initialValue)
{
//IL_0099: Unknown result type (might be due to invalid IL or missing references)
//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
//IL_00af: Expected O, but got Unknown
//IL_00af: Expected O, but got Unknown
//IL_0048: Unknown result type (might be due to invalid IL or missing references)
//IL_0052: Expected O, but got Unknown
Name = name;
Type = type;
SyncedValues.Add(this);
if (harmony == null)
{
harmony = (Harmony)AccessTools.Field(typeof(Main), "Harmony").GetValue(null);
harmony.PatchAll(typeof(Patches));
Get.Plugin.LogDebugOnly("Jotunn's harmony instance obtained, CustomSyncedValueBase+Patches applied.");
}
boxedValue = initialValue;
customRPC = NetworkManager.Instance.AddRPC(Name + "_CustomSyncedValue_RPC", new CoroutineHandler(OnServerReceive), new CoroutineHandler(OnClientReceive));
SynchronizationManager.Instance.AddInitialSynchronization(customRPC, (Func<ZPackage>)GetPackage);
}
public void SendPackage()
{
if ((Object)(object)ZNet.instance == (Object)null)
{
Get.Plugin.LogDebugOnly("SendPackage called but am not connected.");
}
if (!SynchronizationManager.Instance.PlayerIsAdmin)
{
Get.Plugin.LogDebugOnly("SendPackage called but Player is not admin.");
}
if ((Object)(object)ZNet.instance != (Object)null && SynchronizationManager.Instance.PlayerIsAdmin)
{
ZPackage package = GetPackage();
if (ZNetExtension.IsClientInstance(ZNet.instance))
{
customRPC.SendPackage(ZRoutedRpc.instance.GetServerPeerID(), package);
}
else
{
customRPC.SendPackage(ZNet.instance.m_peers, package);
}
}
}
private ZPackage GetPackage()
{
return new PackageEntry
{
key = Name,
type = Type,
value = boxedValue
}.ToPackage();
}
private IEnumerator OnServerReceive(long sender, ZPackage package)
{
Get.Plugin.LogDebugOnly($"Server received RPC: {sender} {package}");
yield return null;
ParsedEntries parsedEntries = package.ReadEntries();
if (parsedEntries.Count > 0 && parsedEntries.TryGetValue(Name, out var value))
{
BoxedValue = (LocalBaseValue = value.value);
Get.Plugin.LogDebugOnly($"Set local and boxed: {value.value}");
customRPC.SendPackage(ZNet.instance.m_peers.Where((ZNetPeer x) => x.m_uid != sender).ToList(), package);
}
else
{
OnReceiveError(parsedEntries);
}
}
private IEnumerator OnClientReceive(long sender, ZPackage package)
{
Get.Plugin.LogDebugOnly($"Client received RPC: {sender} {package}");
yield return null;
ParsedEntries parsedEntries = package.ReadEntries();
if (parsedEntries.Count > 0 && parsedEntries.TryGetValue(Name, out var value))
{
IsSourceOfTruth = false;
if (LocalBaseValue == null)
{
LocalBaseValue = BoxedValue;
}
BoxedValue = value.value;
Get.Plugin.LogDebugOnly($"Set source of truth: {IsSourceOfTruth}, {Environment.NewLine}local: {LocalBaseValue} {Environment.NewLine}boxed: {BoxedValue}");
}
else
{
OnReceiveError(parsedEntries);
}
}
private void OnReceiveError(ParsedEntries entries)
{
Get.Plugin.LogWarning(Name + "_CustomSyncedValue_RPC recieved package without expected key: " + Name);
string text = "";
foreach (KeyValuePair<string, PackageEntry> entry in entries)
{
text += $"{entry.Key} - {entry.Value.type} - {entry.Value.value?.ToString()} {Environment.NewLine}";
}
Get.Plugin.LogWarning("Result: " + Environment.NewLine + text);
}
private void OnResetFromServer()
{
BoxedValue = LocalBaseValue;
IsSourceOfTruth = true;
LocalBaseValue = null;
}
private void OnServerShutdown()
{
}
}
internal sealed class CustomSyncedValue<T> : CustomSyncedValueBase
{
public T Value
{
get
{
return (T)base.BoxedValue;
}
set
{
base.BoxedValue = value;
if (base.BoxedValue != null)
{
SendPackage();
}
}
}
public CustomSyncedValue(string name, T value = default(T))
: base(name, typeof(T), value)
{
}
public void AssignLocalValue(T value)
{
if (base.IsSourceOfTruth && SynchronizationManager.Instance.PlayerIsAdmin)
{
Value = value;
}
else
{
LocalBaseValue = value;
}
}
}
internal class ParsedEntries : Dictionary<string, PackageEntry>
{
}
internal class PackageEntry
{
public string key;
public Type type;
public object? value;
}
internal class InvalidDeserializationTypeException : Exception
{
public string expected;
public string received;
public string field = "";
}
internal static class PackageUtils
{
public static string GetPackageTypeString(Type type)
{
return type.AssemblyQualifiedName;
}
public static void AddValue(this ZPackage package, object? value)
{
Type type = value?.GetType();
if (value is Enum)
{
value = ((IConvertible)value).ToType(Enum.GetUnderlyingType(value.GetType()), CultureInfo.InvariantCulture);
}
else
{
if (value is ICollection collection)
{
package.Write(collection.Count);
{
foreach (object item in collection)
{
package.AddValue(item);
}
return;
}
}
if ((object)type != null && type.IsValueType && !type.IsPrimitive)
{
FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
package.Write(fields.Length);
FieldInfo[] array = fields;
foreach (FieldInfo fieldInfo in array)
{
package.Write(GetPackageTypeString(fieldInfo.FieldType));
package.AddValue(fieldInfo.GetValue(value));
}
return;
}
}
ZRpc.Serialize(new object[1] { value }, ref package);
}
public static void AddEntry(this ZPackage package, PackageEntry entry)
{
package.Write(entry.key);
package.Write((entry.value == null) ? "" : GetPackageTypeString(entry.type));
package.AddValue(entry.value);
}
public static ZPackage ToPackage(this PackageEntry packageEntry)
{
return new List<PackageEntry> { packageEntry }.ToPackage();
}
public static ZPackage ToPackage(this IEnumerable<PackageEntry> packageEntries)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Expected O, but got Unknown
ZPackage val = new ZPackage();
val.Write(packageEntries?.Count() ?? 0);
foreach (PackageEntry item in packageEntries ?? Array.Empty<PackageEntry>())
{
val.AddEntry(item);
}
return val;
}
public static object ReadValueWithType(this ZPackage package, Type type)
{
if ((object)type != null && type.IsValueType && !type.IsPrimitive && !type.IsEnum)
{
FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
int num = package.ReadInt();
if (num != fields.Length)
{
throw new InvalidDeserializationTypeException
{
received = $"(field count: {num})",
expected = $"(field count: {fields.Length})"
};
}
object uninitializedObject = FormatterServices.GetUninitializedObject(type);
FieldInfo[] array = fields;
foreach (FieldInfo fieldInfo in array)
{
string text = package.ReadString();
if (text != GetPackageTypeString(fieldInfo.FieldType))
{
throw new InvalidDeserializationTypeException
{
received = text,
expected = GetPackageTypeString(fieldInfo.FieldType),
field = fieldInfo.Name
};
}
fieldInfo.SetValue(uninitializedObject, package.ReadValueWithType(fieldInfo.FieldType));
}
return uninitializedObject;
}
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Dictionary<, >))
{
int num2 = package.ReadInt();
IDictionary dictionary = (IDictionary)Activator.CreateInstance(type);
Type type2 = typeof(KeyValuePair<, >).MakeGenericType(type.GenericTypeArguments);
FieldInfo field = type2.GetField("key", BindingFlags.Instance | BindingFlags.NonPublic);
FieldInfo field2 = type2.GetField("value", BindingFlags.Instance | BindingFlags.NonPublic);
for (int j = 0; j < num2; j++)
{
object obj = package.ReadValueWithType(type2);
dictionary.Add(field.GetValue(obj), field2.GetValue(obj));
}
return dictionary;
}
if (type != typeof(List<string>) && type.IsGenericType)
{
Type type3 = typeof(ICollection<>).MakeGenericType(type.GenericTypeArguments[0]);
if ((object)type3 != null && type3.IsAssignableFrom(type))
{
int num3 = package.ReadInt();
object obj2 = Activator.CreateInstance(type);
MethodInfo method = type3.GetMethod("Add");
for (int k = 0; k < num3; k++)
{
method.Invoke(obj2, new object[1] { package.ReadValueWithType(type.GenericTypeArguments[0]) });
}
return obj2;
}
}
ParameterInfo parameterInfo = (ParameterInfo)FormatterServices.GetUninitializedObject(typeof(ParameterInfo));
AccessTools.DeclaredField(typeof(ParameterInfo), "ClassImpl").SetValue(parameterInfo, type);
List<object> source = new List<object>();
ZRpc.Deserialize(new ParameterInfo[2] { null, parameterInfo }, package, ref source);
return source.FirstOrDefault();
}
public static ParsedEntries ReadEntries(this ZPackage package)
{
ParsedEntries parsedEntries = new ParsedEntries();
int num = package.ReadInt();
for (int i = 0; i < num; i++)
{
string key = package.ReadString();
string text = package.ReadString();
Type type = Type.GetType(text);
if (text == "" || type != null)
{
object obj;
try
{
obj = ((text == "") ? null : package.ReadValueWithType(type));
}
catch (InvalidDeserializationTypeException ex)
{
Get.Plugin.LogWarning("Got unexpected struct internal type " + ex.received + " for field " + ex.field + " struct " + text);
continue;
}
if (obj != null)
{
parsedEntries[key] = new PackageEntry
{
key = key,
type = type,
value = obj
};
}
continue;
}
Get.Plugin.LogWarning("Got invalid type " + text + ", abort reading of received configs");
return new ParsedEntries();
}
return parsedEntries;
}
public static void Test()
{
}
}
internal interface IPlugin
{
ConfigFile Config { get; }
bool Debug { get; }
ManualLogSource Logger { get; }
}
internal static class LoggingExtensions
{
private static readonly Dictionary<string, ManualLogSource> logSources = new Dictionary<string, ManualLogSource>();
internal static ManualLogSource GetLogger(this IPlugin mod)
{
if (mod.Debug)
{
Type declaringType = new StackFrame(2).GetMethod().DeclaringType;
if (!logSources.TryGetValue(declaringType.FullName, out var value))
{
value = Logger.CreateLogSource(declaringType.FullName);
logSources.Add(declaringType.FullName, value);
}
return value;
}
return mod.Logger;
}
public static void LogDebugOnly(this IPlugin mod, object data)
{
if (mod.Debug)
{
mod.GetLogger().LogDebug(data);
}
}
public static void LogDebug(this IPlugin mod, object data)
{
if (mod.Debug)
{
mod.GetLogger().LogDebug(data);
}
else
{
mod.Logger.LogDebug(data);
}
}
public static void LogInfo(this IPlugin mod, object data)
{
if (mod.Debug)
{
mod.GetLogger().LogInfo(data);
}
else
{
mod.Logger.LogInfo(data);
}
}
public static void LogMessage(this IPlugin mod, object data)
{
if (mod.Debug)
{
mod.GetLogger().LogMessage(data);
}
else
{
mod.Logger.LogMessage(data);
}
}
public static void LogWarning(this IPlugin mod, object data)
{
if (mod.Debug)
{
mod.GetLogger().LogWarning(data);
}
else
{
mod.Logger.LogWarning(data);
}
}
public static void LogError(this IPlugin mod, object data)
{
if (mod.Debug)
{
mod.GetLogger().LogError(data);
}
else
{
mod.Logger.LogError(data);
}
}
public static void LogFatal(this IPlugin mod, object data)
{
if (mod.Debug)
{
mod.GetLogger().LogFatal(data);
}
else
{
mod.Logger.LogFatal(data);
}
}
}
internal static class Get
{
private static IPlugin cachedModRef;
public static IPlugin Plugin
{
get
{
if (cachedModRef == null)
{
cachedModRef = AccessTools.Field((from p in new StackFrame(0).GetMethod().DeclaringType.Assembly.GetTypes()
where typeof(IPlugin).IsAssignableFrom(p)
select p).FirstOrDefault(), "Instance").GetValue(null) as IPlugin;
cachedModRef.LogDebugOnly("Caching static mod reference");
}
return cachedModRef;
}
}
}
internal class Watcher
{
private FileSystemWatcher fileSystemWatcher;
public bool EnableRaisingEvents
{
get
{
if (fileSystemWatcher != null)
{
return fileSystemWatcher.EnableRaisingEvents;
}
return false;
}
set
{
if (fileSystemWatcher != null)
{
fileSystemWatcher.EnableRaisingEvents = value;
}
}
}
public event Action<object, FileSystemEventArgs>? FileChanged;
public Watcher(string path, string filter)
{
if (path == null)
{
throw new ArgumentNullException("path");
}
if (filter == null)
{
throw new ArgumentNullException("filter");
}
Get.Plugin.LogDebugOnly("Watcher created for " + path + ", " + filter);
fileSystemWatcher = new FileSystemWatcher(path, filter);
fileSystemWatcher.Changed += OnCreatedChangedOrRenamed;
fileSystemWatcher.Created += OnCreatedChangedOrRenamed;
fileSystemWatcher.Renamed += OnCreatedChangedOrRenamed;
fileSystemWatcher.IncludeSubdirectories = true;
fileSystemWatcher.SynchronizingObject = ThreadingHelper.SynchronizingObject;
fileSystemWatcher.EnableRaisingEvents = true;
}
private void OnCreatedChangedOrRenamed(object sender, FileSystemEventArgs args)
{
Get.Plugin.LogDebugOnly($"OnCreatedChangedOrRenamed triggered {args.Name}, {args.ChangeType}");
this.FileChanged?.Invoke(sender, args);
}
}
}