using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Threading; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using JetBrains.Annotations; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("ServeYouRight")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("sighsorry")] [assembly: AssemblyProduct("ServeYouRight")] [assembly: AssemblyCopyright("Copyright © 2021")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("4358610B-F3F4-4843-B7AF-98B7BC60DCDE")] [assembly: AssemblyFileVersion("1.0.2")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.2.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; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class ExtensionMarkerAttribute : Attribute { private readonly string k__BackingField; public string Name => k__BackingField; public ExtensionMarkerAttribute(string name) { k__BackingField = name; } } } namespace ServerSyncModTemplate { [BepInPlugin("sighsorry.ServeYouRight", "ServeYouRight", "1.0.2")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class ServerSyncModTemplatePlugin : BaseUnityPlugin { public enum Toggle { On = 1, Off = 0 } private class ConfigurationManagerAttributes { [UsedImplicitly] public int? Order = null; [UsedImplicitly] public bool? Browsable = null; [UsedImplicitly] public string? Category = null; [UsedImplicitly] public Action? CustomDrawer = null; } private class AcceptableShortcuts : AcceptableValueBase { public AcceptableShortcuts() : base(typeof(KeyboardShortcut)) { } public override object Clamp(object value) { return value; } public override bool IsValid(object value) { return true; } public override string ToDescriptionString() { return "# Acceptable values: " + string.Join(", ", UnityInput.Current.SupportedKeyCodes); } } internal const string ModName = "ServeYouRight"; internal const string ModVersion = "1.0.2"; internal const string Author = "sighsorry"; private const string ModGUID = "sighsorry.ServeYouRight"; private static string ConfigFileName = "sighsorry.ServeYouRight.cfg"; private static string ConfigFileFullPath; private static ServerSyncModTemplatePlugin? _instance; private readonly Harmony _harmony = new Harmony("sighsorry.ServeYouRight"); public static readonly ManualLogSource ServerSyncModTemplateLogger; private FileSystemWatcher? _watcher; private readonly object _reloadLock = new object(); private static readonly object DynamicConfigLock; private int _skipWatcherEvents; private DateTime _lastConfigReloadTime; private const long RELOAD_DELAY = 10000000L; private static readonly Dictionary PerModConfigs; private static bool _pendingDynamicConfigSave; public void Awake() { _instance = this; bool saveOnConfigSet = ((BaseUnityPlugin)this).Config.SaveOnConfigSet; ((BaseUnityPlugin)this).Config.SaveOnConfigSet = false; JotunnBridge.InitializeAndEnableModQuery(); Localization.OnLanguageChange = (Action)Delegate.Combine(Localization.OnLanguageChange, new Action(OnLanguageChange)); Assembly executingAssembly = Assembly.GetExecutingAssembly(); _harmony.PatchAll(executingAssembly); SetupWatcher(); ((BaseUnityPlugin)this).Config.Save(); if (saveOnConfigSet) { ((BaseUnityPlugin)this).Config.SaveOnConfigSet = saveOnConfigSet; } } private void OnDestroy() { Localization.OnLanguageChange = (Action)Delegate.Remove(Localization.OnLanguageChange, new Action(OnLanguageChange)); SaveWithRespectToConfigSet(); _watcher?.Dispose(); } private void OnLanguageChange() { FeasterFoodInjector.OnLanguageChanged(ObjectDB.instance); } private void SetupWatcher() { _watcher = new FileSystemWatcher(Paths.ConfigPath, ConfigFileName); _watcher.Changed += ReadConfigValues; _watcher.Created += ReadConfigValues; _watcher.Renamed += ReadConfigValues; _watcher.IncludeSubdirectories = true; _watcher.SynchronizingObject = ThreadingHelper.SynchronizingObject; _watcher.EnableRaisingEvents = true; } private void ReadConfigValues(object sender, FileSystemEventArgs e) { if (Interlocked.CompareExchange(ref _skipWatcherEvents, 0, 0) > 0) { Interlocked.Decrement(ref _skipWatcherEvents); return; } DateTime now = DateTime.Now; long num = now.Ticks - _lastConfigReloadTime.Ticks; if (num < 10000000) { return; } lock (_reloadLock) { if (!File.Exists(ConfigFileFullPath)) { ServerSyncModTemplateLogger.LogWarning((object)"Config file does not exist. Skipping reload."); return; } try { ServerSyncModTemplateLogger.LogDebug((object)"Reloading configuration..."); SaveWithRespectToConfigSet(reload: true); ServerSyncModTemplateLogger.LogInfo((object)"Configuration reload complete."); } catch (Exception ex) { ServerSyncModTemplateLogger.LogError((object)("Error reloading configuration: " + ex.Message)); } } _lastConfigReloadTime = now; } private void SaveWithRespectToConfigSet(bool reload = false) { bool saveOnConfigSet = ((BaseUnityPlugin)this).Config.SaveOnConfigSet; ((BaseUnityPlugin)this).Config.SaveOnConfigSet = false; if (reload) { ((BaseUnityPlugin)this).Config.Reload(); FeasterFoodInjector.OnConfigReload(ObjectDB.instance); } SuppressWatcherEvents(); ((BaseUnityPlugin)this).Config.Save(); if (saveOnConfigSet) { ((BaseUnityPlugin)this).Config.SaveOnConfigSet = saveOnConfigSet; } } internal static bool UseModSpecificTab(FoodSourceMod mod, PieceCategory category) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected I4, but got Unknown PerModCategoryConfig orCreatePerModConfig = GetOrCreatePerModConfig(mod); if (1 == 0) { } bool result = (category - 5) switch { 1 => orCreatePerModConfig.Food.Value.IsOn(), 2 => orCreatePerModConfig.Meads.Value.IsOn(), 0 => orCreatePerModConfig.Feasts.Value.IsOn(), _ => false, }; if (1 == 0) { } return result; } private static PerModCategoryConfig GetOrCreatePerModConfig(FoodSourceMod mod) { lock (DynamicConfigLock) { if (PerModConfigs.TryGetValue(mod.Id, out PerModCategoryConfig value)) { return value; } if ((Object)(object)_instance == (Object)null) { throw new InvalidOperationException("Plugin instance is not initialized."); } string group = "ServingTray - " + SanitizeConfigText(mod.DisplayName) + " (" + SanitizeConfigText(mod.Id) + ")"; PerModCategoryConfig perModCategoryConfig = new PerModCategoryConfig(mod, _instance.config(group, "Food", Toggle.On, "If on, '" + mod.DisplayName + "' Food items go to 'Food - " + mod.DisplayName + "'. If off, they merge into vanilla Food.", 300), _instance.config(group, "Meads", Toggle.On, "If on, '" + mod.DisplayName + "' Mead items go to 'Meads - " + mod.DisplayName + "'. If off, they merge into vanilla Meads.", 200), _instance.config(group, "Feasts", Toggle.On, "If on, '" + mod.DisplayName + "' Feast items go to 'Feasts - " + mod.DisplayName + "'. If off, they merge into vanilla Feasts.", 100)); PerModConfigs[mod.Id] = perModCategoryConfig; _pendingDynamicConfigSave = true; return perModCategoryConfig; } } internal static void FlushPendingDynamicConfigSave() { ServerSyncModTemplatePlugin instance = _instance; if (!((Object)(object)instance == (Object)null)) { bool pendingDynamicConfigSave; lock (DynamicConfigLock) { pendingDynamicConfigSave = _pendingDynamicConfigSave; _pendingDynamicConfigSave = false; } if (pendingDynamicConfigSave) { bool saveOnConfigSet = ((BaseUnityPlugin)instance).Config.SaveOnConfigSet; ((BaseUnityPlugin)instance).Config.SaveOnConfigSet = false; instance.SuppressWatcherEvents(); ((BaseUnityPlugin)instance).Config.Save(); ((BaseUnityPlugin)instance).Config.SaveOnConfigSet = saveOnConfigSet; } } } private void SuppressWatcherEvents(int eventCount = 6) { if (eventCount > 0) { Interlocked.Add(ref _skipWatcherEvents, eventCount); } } private static string SanitizeConfigText(string text) { if (string.IsNullOrWhiteSpace(text)) { return "Unknown"; } char[] array = text.ToCharArray(); for (int i = 0; i < array.Length; i++) { if (array[i] == '\r' || "=\n\t\\\"'[]".IndexOf(array[i]) >= 0 || char.IsControl(array[i])) { array[i] = '_'; } } string text2 = new string(array).Trim(); return string.IsNullOrWhiteSpace(text2) ? "Unknown" : text2; } private ConfigEntry config(string group, string name, T value, ConfigDescription description) { return ((BaseUnityPlugin)this).Config.Bind(group, name, value, description); } private ConfigEntry config(string group, string name, T value, string description) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown return config(group, name, value, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty())); } private ConfigEntry config(string group, string name, T value, string description, int order) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected O, but got Unknown ConfigDescription description2 = new ConfigDescription(description, (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = order } }); return config(group, name, value, description2); } static ServerSyncModTemplatePlugin() { string configPath = Paths.ConfigPath; char directorySeparatorChar = Path.DirectorySeparatorChar; ConfigFileFullPath = configPath + directorySeparatorChar + ConfigFileName; ServerSyncModTemplateLogger = Logger.CreateLogSource("ServeYouRight"); DynamicConfigLock = new object(); PerModConfigs = new Dictionary(StringComparer.OrdinalIgnoreCase); } } [HarmonyPatch(typeof(ObjectDB), "Awake")] public static class ObjectDbAwakePatch { private static void Postfix(ObjectDB __instance) { FeasterFoodInjector.Inject(__instance); } } [HarmonyPatch(typeof(ObjectDB), "CopyOtherDB")] public static class ObjectDbCopyOtherDbPatch { private static void Postfix(ObjectDB __instance) { FeasterFoodInjector.Inject(__instance); } } [HarmonyPatch(typeof(Player), "SetPlaceMode")] public static class PlayerSetPlaceModePatch { private static void Postfix(Player __instance, PieceTable buildPieces) { if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && !((Object)(object)buildPieces == (Object)null) && buildPieces.m_canRemoveFeasts) { FeasterFoodInjector.Inject(ObjectDB.instance); __instance.UpdateKnownRecipesList(); __instance.UpdateAvailablePiecesList(); FeasterFoodInjector.ApplyCustomCategoryLabels(buildPieces); } } } [HarmonyPatch(typeof(PieceTable), "UpdateAvailable")] public static class PieceTableUpdateAvailablePatch { private static void Postfix(PieceTable __instance) { if (!((Object)(object)__instance == (Object)null) && __instance.m_canRemoveFeasts) { FeasterFoodInjector.ApplyCustomCategoryLabels(__instance); } } } [HarmonyPatch(typeof(ItemDrop), "MakePiece")] public static class ItemDropMakePiecePatch { private static void Postfix(ItemDrop __instance) { //IL_0038: 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_0049: 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) if ((Object)(object)((Component)__instance).GetComponent() == (Object)null) { return; } ParticleSystem[] componentsInChildren = ((Component)__instance).GetComponentsInChildren(true); foreach (ParticleSystem val in componentsInChildren) { val.Stop(true, (ParticleSystemStopBehavior)0); val.Clear(true); EmissionModule emission = val.emission; ((EmissionModule)(ref emission)).enabled = false; MainModule main = val.main; ((MainModule)(ref main)).playOnAwake = false; ParticleSystemRenderer component = ((Component)val).GetComponent(); if ((Object)(object)component != (Object)null) { ((Renderer)component).enabled = false; } } } } internal static class FeasterFoodInjector { [CompilerGenerated] private sealed class d__10 : IEnumerable, IEnumerable, IEnumerator, IDisposable, IEnumerator { private int <>1__state; private PieceTable <>2__current; private int <>l__initialThreadId; private ObjectDB objectDb; public ObjectDB <>3__objectDb; private HashSet 5__1; private List.Enumerator <>s__2; private GameObject 5__3; private ItemDrop 5__4; private PieceTable 5__5; private bool 5__6; PieceTable IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__10(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || num == 1) { try { } finally { <>m__Finally1(); } } 5__1 = null; <>s__2 = default(List.Enumerator); 5__3 = null; 5__4 = null; 5__5 = null; <>1__state = -2; } private bool MoveNext() { try { int num = <>1__state; if (num != 0) { if (num != 1) { return false; } <>1__state = -3; goto IL_017a; } <>1__state = -1; 5__1 = new HashSet(); <>s__2 = objectDb.m_items.GetEnumerator(); <>1__state = -3; goto IL_0190; IL_017a: 5__4 = null; 5__5 = null; 5__3 = null; goto IL_0190; IL_0190: while (true) { if (<>s__2.MoveNext()) { 5__3 = <>s__2.Current; if ((Object)(object)5__3 == (Object)null) { continue; } 5__4 = 5__3.GetComponent(); 5__5 = 5__4?.m_itemData?.m_shared?.m_buildPieces; if (!((Object)(object)5__5 == (Object)null) && 5__5.m_canRemoveFeasts) { 5__6 = 5__5.m_categories.Contains((PieceCategory)6) || 5__5.m_categories.Contains((PieceCategory)7) || 5__5.m_categories.Contains((PieceCategory)5); if (5__6) { break; } } continue; } <>m__Finally1(); <>s__2 = default(List.Enumerator); return false; } if (5__1.Add(5__5)) { <>2__current = 5__5; <>1__state = 1; return true; } goto IL_017a; } catch { //try-fault ((IDisposable)this).Dispose(); throw; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; ((IDisposable)<>s__2).Dispose(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { d__10 d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; d__ = this; } else { d__ = new d__10(0); } d__.objectDb = <>3__objectDb; return d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)this).GetEnumerator(); } } private static bool _isInjecting; private static readonly Dictionary ModCategoryCache = new Dictionary(StringComparer.OrdinalIgnoreCase); private static readonly Dictionary SourceModHitCache = new Dictionary(StringComparer.OrdinalIgnoreCase); private static readonly object ModCategoryLock = new object(); public static void OnConfigReload(ObjectDB? objectDb) { Inject(objectDb); if ((Object)(object)Player.m_localPlayer != (Object)null) { Player.m_localPlayer.UpdateKnownRecipesList(); Player.m_localPlayer.UpdateAvailablePiecesList(); ApplyCustomCategoryLabels(Player.m_localPlayer.m_buildPieces); } } public static void OnLanguageChanged(ObjectDB? objectDb) { Inject(objectDb); if ((Object)(object)Player.m_localPlayer != (Object)null) { Player.m_localPlayer.UpdateKnownRecipesList(); Player.m_localPlayer.UpdateAvailablePiecesList(); ApplyCustomCategoryLabels(Player.m_localPlayer.m_buildPieces); } } public static void Inject(ObjectDB? objectDb) { if (_isInjecting || (Object)(object)objectDb == (Object)null) { return; } _isInjecting = true; try { List candidateFoods = GetCandidateFoods(objectDb); if (candidateFoods.Count == 0) { return; } foreach (PieceTable feasterPieceTable in GetFeasterPieceTables(objectDb)) { int num = InjectIntoTable(feasterPieceTable, candidateFoods); if (num > 0) { ServerSyncModTemplatePlugin.ServerSyncModTemplateLogger.LogInfo((object)$"Added {num} mod food pieces to feaster table '{((Object)feasterPieceTable).name}'."); } ApplyCustomCategoryLabels(feasterPieceTable); } } catch (Exception arg) { ServerSyncModTemplatePlugin.ServerSyncModTemplateLogger.LogError((object)$"Failed to inject feaster foods: {arg}"); } finally { _isInjecting = false; ServerSyncModTemplatePlugin.FlushPendingDynamicConfigSave(); } } private static List GetCandidateFoods(ObjectDB objectDb) { //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Invalid comparison between Unknown and I4 //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) List list = new List(); FeastRoutingData feastRoutingData = BuildFeastRoutingData(objectDb); foreach (GameObject item in objectDb.m_items) { if ((Object)(object)item == (Object)null) { continue; } ItemDrop component = item.GetComponent(); SharedData val = component?.m_itemData?.m_shared; if (!((Object)(object)component == (Object)null) && val != null) { string prefabName = Utils.GetPrefabName(((Object)item).name); if (feastRoutingData.MaterialToResultPrefab.TryGetValue(prefabName, out GameObject value)) { list.Add(new CandidateFood(component, value, (PieceCategory)5)); } else if (!feastRoutingData.ResultPrefabNames.Contains(prefabName) && !((Object)(object)((Component)component).GetComponent() != (Object)null) && (int)val.m_itemType == 2 && (val.m_isDrink || val.m_food > 0f || val.m_foodStamina > 0f || val.m_foodEitr > 0f)) { PieceCategory category = (PieceCategory)(val.m_isDrink ? 7 : 6); list.Add(new CandidateFood(component, ((Component)component).gameObject, category)); } } } return list; } private static FeastRoutingData BuildFeastRoutingData(ObjectDB objectDb) { //IL_0298: Unknown result type (might be due to invalid IL or missing references) //IL_029e: Invalid comparison between Unknown and I4 //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Invalid comparison between Unknown and I4 //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Invalid comparison between Unknown and I4 //IL_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_01fb: Invalid comparison between Unknown and I4 Dictionary dictionary = new Dictionary(StringComparer.OrdinalIgnoreCase); foreach (GameObject item in objectDb.m_items) { if ((Object)(object)item == (Object)null) { continue; } ItemDrop component = item.GetComponent(); if (!((Object)(object)component == (Object)null)) { string prefabName = Utils.GetPrefabName(((Object)item).name); if (!dictionary.ContainsKey(prefabName)) { dictionary[prefabName] = component; } } } Dictionary dictionary2 = new Dictionary(StringComparer.OrdinalIgnoreCase); HashSet hashSet = new HashSet(StringComparer.OrdinalIgnoreCase); foreach (KeyValuePair item2 in dictionary) { string key = item2.Key; ItemDrop value = item2.Value; SharedData val = value.m_itemData?.m_shared; Feast component2 = ((Component)value).GetComponent(); if ((Object)(object)component2 == (Object)null || val == null) { continue; } ItemDrop foodItem = component2.m_foodItem; string text = (((Object)(object)foodItem != (Object)null) ? Utils.GetPrefabName(((Object)((Component)foodItem).gameObject).name) : string.Empty); bool flag = !string.IsNullOrWhiteSpace(text) && !string.Equals(text, key, StringComparison.OrdinalIgnoreCase); SharedData val2 = foodItem?.m_itemData?.m_shared; bool flag2 = (Object)(object)foodItem != (Object)null && ((Object)(object)((Component)foodItem).GetComponent() != (Object)null || (val2 != null && ((int)val2.m_itemType == 2 || LooksLikeConsumableFood(val2)))); if ((int)val.m_itemType == 1) { if (flag && flag2) { dictionary2[key] = ((Component)foodItem).gameObject; hashSet.Add(text); } } else if (flag && flag2 && (int)val.m_itemType != 2 && !LooksLikeConsumableFood(val)) { dictionary2[key] = ((Component)foodItem).gameObject; hashSet.Add(text); } else { hashSet.Add(key); } } foreach (KeyValuePair item3 in dictionary) { string key2 = item3.Key; ItemDrop value2 = item3.Value; SharedData val3 = value2.m_itemData?.m_shared; if (val3 == null || (int)val3.m_itemType != 1) { continue; } ItemDrop appendToolTip = val3.m_appendToolTip; if (!((Object)(object)appendToolTip == (Object)null)) { string prefabName2 = Utils.GetPrefabName(((Object)((Component)appendToolTip).gameObject).name); if (!string.Equals(prefabName2, key2, StringComparison.OrdinalIgnoreCase) && (hashSet.Contains(prefabName2) || (Object)(object)((Component)appendToolTip).GetComponent() != (Object)null)) { dictionary2[key2] = ((Component)appendToolTip).gameObject; hashSet.Add(prefabName2); } } } return new FeastRoutingData(dictionary2, hashSet); } private static bool LooksLikeConsumableFood(SharedData shared) { return shared.m_food > 0f || shared.m_foodStamina > 0f || shared.m_foodEitr > 0f || shared.m_isDrink; } [IteratorStateMachine(typeof(d__10))] private static IEnumerable GetFeasterPieceTables(ObjectDB objectDb) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__10(-2) { <>3__objectDb = objectDb }; } private static int InjectIntoTable(PieceTable table, List candidates) { //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0085: 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) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) EnsureBaseCategories(table); HashSet hashSet = BuildExistingFoodHashSet(table); int num = 0; foreach (CandidateFood candidate in candidates) { ItemDrop itemDrop = candidate.ItemDrop; GameObject placePrefab = candidate.PlacePrefab; int prefabNameHash = GetPrefabNameHash(((Component)itemDrop).gameObject); bool flag = hashSet.Contains(prefabNameHash); bool flag2 = IsInjectedByServeYouRight(placePrefab); if (!flag || flag2) { PieceCategory category = candidate.Category; PieceCategory category2 = ResolveTargetCategory(table, ((Component)itemDrop).gameObject, category); if (TryGetTemplate(table, category2, out Piece templatePiece, out WearNTear templateWearNTear) && PrepareFoodPrefab(placePrefab, itemDrop, category2, templatePiece, templateWearNTear) && !table.m_pieces.Contains(placePrefab)) { table.m_pieces.Add(placePrefab); hashSet.Add(prefabNameHash); num++; } } } return num; } private static void EnsureBaseCategories(PieceTable table) { EnsureBaseCategoryExists(table, (PieceCategory)6, GetBaseCategoryLabel(table, (PieceCategory)6)); EnsureBaseCategoryExists(table, (PieceCategory)7, GetBaseCategoryLabel(table, (PieceCategory)7)); EnsureBaseCategoryExists(table, (PieceCategory)5, GetBaseCategoryLabel(table, (PieceCategory)5)); } public static void ApplyCustomCategoryLabels(PieceTable? table) { //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)table == (Object)null) { return; } List list; lock (ModCategoryLock) { list = ModCategoryCache.Values.ToList(); } foreach (ModCategoryInfo item in list) { int num = table.m_categories.IndexOf(item.Category); if (num >= 0) { while (table.m_categoryLabels.Count <= num) { table.m_categoryLabels.Add(string.Empty); } string baseCategoryLabel = GetBaseCategoryLabel(table, item.BaseCategory); string baseLabel = ResolveCategoryDisplayLabel(item.BaseCategory, baseCategoryLabel); table.m_categoryLabels[num] = BuildDisplayCategoryName(baseLabel, item.SourceMod); } } } private static bool TryGetTemplate(PieceTable table, PieceCategory category, out Piece templatePiece, out WearNTear? templateWearNTear) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) templatePiece = null; templateWearNTear = null; foreach (GameObject piece in table.m_pieces) { if ((Object)(object)piece == (Object)null) { continue; } Piece component = piece.GetComponent(); if (!((Object)(object)component == (Object)null) && component.m_category == category && !component.m_repairPiece && !component.m_removePiece) { templatePiece = component; templateWearNTear = piece.GetComponent(); if ((Object)(object)templateWearNTear != (Object)null) { return true; } } } foreach (GameObject piece2 in table.m_pieces) { if ((Object)(object)piece2 == (Object)null) { continue; } Piece component2 = piece2.GetComponent(); if (!((Object)(object)component2 == (Object)null) && !component2.m_repairPiece && !component2.m_removePiece) { templatePiece = component2; templateWearNTear = piece2.GetComponent(); if ((Object)(object)templateWearNTear != (Object)null) { return true; } } } ServerSyncModTemplatePlugin.ServerSyncModTemplateLogger.LogWarning((object)("No feaster template piece found for table '" + ((Object)table).name + "'.")); return false; } private static bool PrepareFoodPrefab(GameObject foodPrefab, ItemDrop sourceItemDrop, PieceCategory category, Piece templatePiece, WearNTear? templateWearNTear) { //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Expected O, but got Unknown if ((Object)(object)foodPrefab.GetComponent() == (Object)null) { ServerSyncModTemplatePlugin.ServerSyncModTemplateLogger.LogWarning((object)("Skipping '" + ((Object)foodPrefab).name + "' because it has no ZNetView.")); return false; } Piece val = foodPrefab.GetComponent(); if ((Object)(object)val == (Object)null) { val = foodPrefab.AddComponent(); CopyFields(templatePiece, val); } WearNTear component = foodPrefab.GetComponent(); if ((Object)(object)component == (Object)null) { component = foodPrefab.AddComponent(); if ((Object)(object)templateWearNTear != (Object)null) { CopyFields(templateWearNTear, component); } } SharedData shared = sourceItemDrop.m_itemData.m_shared; val.m_name = shared.m_name; val.m_description = shared.m_description; val.m_enabled = true; val.m_category = category; val.m_repairPiece = false; val.m_removePiece = false; val.m_resources = (Requirement[])(object)new Requirement[1] { new Requirement { m_resItem = sourceItemDrop, m_amount = 1, m_amountPerLevel = 1, m_recover = true } }; Sprite[] icons = shared.m_icons; if (icons != null && icons.Length > 0) { val.m_icon = sourceItemDrop.m_itemData.GetIcon(); } if ((Object)(object)foodPrefab.GetComponent() == (Object)null) { foodPrefab.AddComponent(); } return true; } private static HashSet BuildExistingFoodHashSet(PieceTable table) { HashSet hashSet = new HashSet(); foreach (GameObject piece in table.m_pieces) { if ((Object)(object)piece == (Object)null) { continue; } Piece component = piece.GetComponent(); if ((Object)(object)component == (Object)null) { continue; } Requirement[] array = component.m_resources ?? Array.Empty(); foreach (Requirement val in array) { if ((Object)(object)val?.m_resItem != (Object)null) { hashSet.Add(GetPrefabNameHash(((Component)val.m_resItem).gameObject)); } } ItemDrop component2 = piece.GetComponent(); if ((Object)(object)component2 != (Object)null) { hashSet.Add(GetPrefabNameHash(((Component)component2).gameObject)); } } return hashSet; } private static PieceCategory ResolveTargetCategory(PieceTable table, GameObject foodPrefab, PieceCategory baseCategory) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000a: 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_0022: 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) //IL_003b: 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_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0037: 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) //IL_0045: Unknown result type (might be due to invalid IL or missing references) string baseCategoryLabel = GetBaseCategoryLabel(table, baseCategory); EnsureBaseCategoryExists(table, baseCategory, baseCategoryLabel); if (!TryResolveFoodSourceMod(foodPrefab, out var sourceMod)) { return baseCategory; } if (!ServerSyncModTemplatePlugin.UseModSpecificTab(sourceMod, baseCategory)) { return baseCategory; } return ResolveOrCreateModCategory(baseCategory, sourceMod); } private static string GetBaseCategoryLabel(PieceTable table, PieceCategory category) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Expected I4, but got Unknown int num = table.m_categories.IndexOf(category); if (num >= 0 && num < table.m_categoryLabels.Count) { string text = table.m_categoryLabels[num]; if (!string.IsNullOrWhiteSpace(text)) { return text; } } if (1 == 0) { } string result = (category - 5) switch { 1 => "Food", 2 => "Meads", 0 => "Feasts", _ => ((object)(PieceCategory)(ref category)).ToString(), }; if (1 == 0) { } return result; } private static PieceCategory ResolveOrCreateModCategory(PieceCategory baseCategory, FoodSourceMod sourceMod) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Expected I4, but got Unknown //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) string key = $"{sourceMod.Id}:{(int)baseCategory}"; lock (ModCategoryLock) { if (ModCategoryCache.TryGetValue(key, out ModCategoryInfo value)) { return value.Category; } string text = BuildStableCategoryKey(baseCategory, sourceMod.Id); if (!JotunnBridge.TryAddPieceCategory(text, out var category)) { ServerSyncModTemplatePlugin.ServerSyncModTemplateLogger.LogWarning((object)$"Could not create Jotunn category '{text}'. Falling back to vanilla category '{baseCategory}'."); return baseCategory; } ModCategoryCache[key] = new ModCategoryInfo(category, baseCategory, sourceMod); return category; } } private static string ResolveCategoryDisplayLabel(PieceCategory category, string baseLabel) { //IL_00aa: 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) if (!string.IsNullOrWhiteSpace(baseLabel)) { string text = baseLabel.Trim(); string text2 = text; if (LooksLikeLocalizationTokenKey(text) && !text.StartsWith("$", StringComparison.Ordinal)) { text2 = "$" + text; } if (Localization.instance != null) { string text3 = Localization.instance.Localize(text2); if (!string.IsNullOrWhiteSpace(text3) && !string.Equals(text3, text2, StringComparison.Ordinal)) { return text3.Trim(); } } if (LooksLikeLocalizationTokenKey(text)) { return GetFallbackCategoryLabel(category); } return text; } return GetFallbackCategoryLabel(category); } private static bool LooksLikeLocalizationTokenKey(string value) { if (string.IsNullOrWhiteSpace(value)) { return false; } if (value.StartsWith("$", StringComparison.Ordinal)) { return true; } if (value.IndexOfAny(new char[4] { ' ', '\t', '\r', '\n' }) >= 0) { return false; } if (!value.Contains("_")) { return false; } foreach (char c in value) { if (!char.IsLetterOrDigit(c) && c != '_' && c != '.' && c != '-') { return false; } } return true; } private static string BuildDisplayCategoryName(string baseLabel, FoodSourceMod sourceMod) { return baseLabel + " - " + sourceMod.DisplayName; } private static string BuildStableCategoryKey(PieceCategory baseCategory, string modId) { //IL_0005: 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_0019: Expected I4, but got Unknown //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected I4, but got Unknown if (1 == 0) { } string text = (baseCategory - 5) switch { 1 => "food", 2 => "meads", 0 => "feasts", _ => $"cat{(int)baseCategory}", }; if (1 == 0) { } string arg = text; int num = StringExtensionMethods.GetStableHashCode(modId ?? string.Empty); if (num == int.MinValue) { num = int.MaxValue; } num = Math.Abs(num); return $"syr_{arg}_{num}"; } private static string GetFallbackCategoryLabel(PieceCategory category) { //IL_0005: 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_0019: Expected I4, but got Unknown if (1 == 0) { } string result = (category - 5) switch { 1 => "Food", 2 => "Meads", 0 => "Feasts", _ => ((object)(PieceCategory)(ref category)).ToString(), }; if (1 == 0) { } return result; } private static bool TryResolveFoodSourceMod(GameObject foodPrefab, out FoodSourceMod sourceMod) { string prefabName = Utils.GetPrefabName(((Object)foodPrefab).name); if (SourceModHitCache.TryGetValue(prefabName, out var value)) { sourceMod = value; return true; } if (KnownCloneSourceBridge.TryResolveSourceMod(prefabName, out var sourceMod2)) { sourceMod = sourceMod2; SourceModHitCache[prefabName] = sourceMod; return true; } if (JotunnBridge.TryGetPrefabSourceMod(prefabName, out var sourceMod3)) { sourceMod = sourceMod3; SourceModHitCache[prefabName] = sourceMod; return true; } sourceMod = default(FoodSourceMod); return false; } private static bool IsInjectedByServeYouRight(GameObject foodPrefab) { return (Object)(object)foodPrefab.GetComponent() != (Object)null; } private static void EnsureBaseCategoryExists(PieceTable table, PieceCategory category, string label) { //IL_0007: 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) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) int num = table.m_categories.IndexOf(category); if (num < 0) { table.m_categories.Add(category); while (table.m_categoryLabels.Count < table.m_categories.Count - 1) { List categoryLabels = table.m_categoryLabels; PieceCategory val = table.m_categories[table.m_categoryLabels.Count]; categoryLabels.Add(((object)(PieceCategory)(ref val)).ToString()); } table.m_categoryLabels.Add(label); } } private static int GetPrefabNameHash(GameObject prefab) { string prefabName = Utils.GetPrefabName(((Object)prefab).name); return StringExtensionMethods.GetStableHashCode(prefabName); } private static void CopyFields(T source, T destination) where T : class { FieldInfo[] fields = typeof(T).GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo in fields) { if (!fieldInfo.IsStatic && !fieldInfo.IsInitOnly && !fieldInfo.IsLiteral) { fieldInfo.SetValue(destination, fieldInfo.GetValue(source)); } } } } internal readonly struct FoodSourceMod { public string Id { get; } public string DisplayName { get; } public FoodSourceMod(string id, string displayName) { Id = id; DisplayName = displayName; } } internal readonly struct CandidateFood { public ItemDrop ItemDrop { get; } public GameObject PlacePrefab { get; } public PieceCategory Category { get; } public CandidateFood(ItemDrop itemDrop, GameObject placePrefab, PieceCategory category) { //IL_0010: 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) ItemDrop = itemDrop; PlacePrefab = placePrefab; Category = category; } } internal sealed class FeastRoutingData { public Dictionary MaterialToResultPrefab { get; } public HashSet ResultPrefabNames { get; } public FeastRoutingData(Dictionary materialToResultPrefab, HashSet resultPrefabNames) { MaterialToResultPrefab = materialToResultPrefab; ResultPrefabNames = resultPrefabNames; } } internal sealed class ModCategoryInfo { public PieceCategory Category { get; } public PieceCategory BaseCategory { get; } public FoodSourceMod SourceMod { get; } public ModCategoryInfo(PieceCategory category, PieceCategory baseCategory, FoodSourceMod sourceMod) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000a: 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_0011: Unknown result type (might be due to invalid IL or missing references) Category = category; BaseCategory = baseCategory; SourceMod = sourceMod; } } internal sealed class PerModCategoryConfig { public FoodSourceMod Mod { get; } public ConfigEntry Food { get; } public ConfigEntry Meads { get; } public ConfigEntry Feasts { get; } public PerModCategoryConfig(FoodSourceMod mod, ConfigEntry food, ConfigEntry meads, ConfigEntry feasts) { Mod = mod; Food = food; Meads = meads; Feasts = feasts; } } internal static class KnownCloneSourceBridge { private const string WackyGuid = "WackyMole.WackysDatabase"; private const string DefaultWackyName = "WackysDatabase"; private static bool _initialized; private static MethodInfo? _wackyGetClonedMap; private static string _wackyDisplayName = "WackysDatabase"; private static readonly HashSet WackyCloneHitCache = new HashSet(StringComparer.OrdinalIgnoreCase); private static readonly HashSet WackyCloneMissCache = new HashSet(StringComparer.OrdinalIgnoreCase); public static bool TryResolveSourceMod(string prefabName, out FoodSourceMod sourceMod) { sourceMod = default(FoodSourceMod); EnsureInitialized(); if (_wackyGetClonedMap == null) { return false; } if (WackyCloneHitCache.Contains(prefabName)) { sourceMod = new FoodSourceMod("WackyMole.WackysDatabase", _wackyDisplayName); return true; } if (WackyCloneMissCache.Contains(prefabName)) { return false; } try { object obj = _wackyGetClonedMap.Invoke(null, new object[1] { prefabName }); string value = obj as string; if (string.IsNullOrWhiteSpace(value)) { WackyCloneMissCache.Add(prefabName); return false; } WackyCloneHitCache.Add(prefabName); sourceMod = new FoodSourceMod("WackyMole.WackysDatabase", _wackyDisplayName); return true; } catch (Exception ex) { ServerSyncModTemplatePlugin.ServerSyncModTemplateLogger.LogDebug((object)("Known clone source resolution failed for '" + prefabName + "': " + ex.Message)); return false; } } private static void EnsureInitialized() { if (_initialized) { return; } _initialized = true; try { _wackyGetClonedMap = Type.GetType("API.WackyAPI, WackysDatabase")?.GetMethod("GetClonedMap", BindingFlags.Static | BindingFlags.Public, null, new Type[1] { typeof(string) }, null); if (Chainloader.PluginInfos.TryGetValue("WackyMole.WackysDatabase", out var value)) { object obj; if (value == null) { obj = null; } else { BepInPlugin metadata = value.Metadata; obj = ((metadata != null) ? metadata.Name : null); } if (obj == null) { obj = string.Empty; } string text = (string)obj; if (!string.IsNullOrWhiteSpace(text)) { _wackyDisplayName = text; } } } catch (Exception ex) { _wackyGetClonedMap = null; ServerSyncModTemplatePlugin.ServerSyncModTemplateLogger.LogDebug((object)("Known clone source bridge init failed: " + ex.Message)); } } } internal static class JotunnBridge { private static bool _initialized; private static bool _available; private static MethodInfo? _modQueryEnable; private static MethodInfo? _modQueryGetPrefab; private static PropertyInfo? _pieceManagerInstance; private static MethodInfo? _pieceManagerAddPieceCategory; public static void InitializeAndEnableModQuery() { if (_initialized) { EnableModQuery(); return; } _initialized = true; try { Type type = Type.GetType("Jotunn.Utils.ModQuery, Jotunn"); Type type2 = Type.GetType("Jotunn.Managers.PieceManager, Jotunn"); _modQueryEnable = type?.GetMethod("Enable", BindingFlags.Static | BindingFlags.Public); _modQueryGetPrefab = type?.GetMethod("GetPrefab", BindingFlags.Static | BindingFlags.Public, null, new Type[1] { typeof(string) }, null); _pieceManagerInstance = type2?.GetProperty("Instance", BindingFlags.Static | BindingFlags.Public); _pieceManagerAddPieceCategory = type2?.GetMethod("AddPieceCategory", BindingFlags.Instance | BindingFlags.Public, null, new Type[1] { typeof(string) }, null); _available = _modQueryEnable != null && _modQueryGetPrefab != null && _pieceManagerInstance != null && _pieceManagerAddPieceCategory != null; } catch (Exception ex) { _available = false; ServerSyncModTemplatePlugin.ServerSyncModTemplateLogger.LogWarning((object)("Failed to initialize Jotunn bridge: " + ex.Message)); } if (!_available) { ServerSyncModTemplatePlugin.ServerSyncModTemplateLogger.LogWarning((object)"Jotunn bridge is unavailable. Mod-specific tabs will fall back to vanilla categories."); } else { EnableModQuery(); } } public static bool TryGetPrefabSourceMod(string prefabName, out FoodSourceMod sourceMod) { sourceMod = default(FoodSourceMod); if (!_available || _modQueryGetPrefab == null) { return false; } try { object obj = _modQueryGetPrefab.Invoke(null, new object[1] { prefabName }); if (obj == null) { return false; } object obj2 = obj.GetType().GetProperty("SourceMod", BindingFlags.Instance | BindingFlags.Public)?.GetValue(obj); if (obj2 == null) { return false; } BepInPlugin val = (BepInPlugin)((obj2 is BepInPlugin) ? obj2 : null); if (val != null) { string displayName = (string.IsNullOrWhiteSpace(val.Name) ? val.GUID : val.Name); sourceMod = new FoodSourceMod(val.GUID, displayName); return true; } string text = obj2.GetType().GetProperty("GUID", BindingFlags.Instance | BindingFlags.Public)?.GetValue(obj2) as string; string text2 = obj2.GetType().GetProperty("Name", BindingFlags.Instance | BindingFlags.Public)?.GetValue(obj2) as string; string text3 = text ?? string.Empty; if (string.IsNullOrWhiteSpace(text3)) { return false; } string displayName2 = (string.IsNullOrWhiteSpace(text2) ? text3 : text2); sourceMod = new FoodSourceMod(text3, displayName2); return true; } catch (Exception ex) { ServerSyncModTemplatePlugin.ServerSyncModTemplateLogger.LogDebug((object)("ModQuery.GetPrefab failed for '" + prefabName + "': " + ex.Message)); return false; } } public static bool TryAddPieceCategory(string categoryName, out PieceCategory category) { //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: 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_0087: Expected I4, but got Unknown category = (PieceCategory)6; if (!_available || _pieceManagerInstance == null || _pieceManagerAddPieceCategory == null) { return false; } try { object value = _pieceManagerInstance.GetValue(null); if (value == null) { return false; } object obj = _pieceManagerAddPieceCategory.Invoke(value, new object[1] { categoryName }); if (obj is PieceCategory val) { category = (PieceCategory)(int)val; return true; } if (obj is int num) { category = (PieceCategory)num; return true; } return false; } catch (Exception ex) { ServerSyncModTemplatePlugin.ServerSyncModTemplateLogger.LogWarning((object)("Failed to add Jotunn piece category '" + categoryName + "': " + ex.Message)); return false; } } private static void EnableModQuery() { if (!_available || _modQueryEnable == null) { return; } try { _modQueryEnable.Invoke(null, null); } catch (Exception ex) { ServerSyncModTemplatePlugin.ServerSyncModTemplateLogger.LogWarning((object)("Failed to enable Jotunn ModQuery: " + ex.Message)); } } } internal sealed class ServeYouRightInjectedPieceMarker : MonoBehaviour { } public static class KeyboardExtensions { [SpecialName] public sealed class $8D1D3E80A18AA9715780B6CB7003B2F1 { [SpecialName] public static class $895AB635D4D087636CF1C26BA650BA11 { } [ExtensionMarker("$895AB635D4D087636CF1C26BA650BA11")] public bool IsKeyDown() { throw new NotSupportedException(); } [ExtensionMarker("$895AB635D4D087636CF1C26BA650BA11")] public bool IsKeyHeld() { throw new NotSupportedException(); } } public static bool IsKeyDown(this KeyboardShortcut shortcut) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) return (int)((KeyboardShortcut)(ref shortcut)).MainKey != 0 && Input.GetKeyDown(((KeyboardShortcut)(ref shortcut)).MainKey) && ((KeyboardShortcut)(ref shortcut)).Modifiers.All((Func)Input.GetKey); } public static bool IsKeyHeld(this KeyboardShortcut shortcut) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) return (int)((KeyboardShortcut)(ref shortcut)).MainKey != 0 && Input.GetKey(((KeyboardShortcut)(ref shortcut)).MainKey) && ((KeyboardShortcut)(ref shortcut)).Modifiers.All((Func)Input.GetKey); } } public static class ToggleExtentions { [SpecialName] public sealed class $57ABA57BD1CE54EF9BE00DAABFE926BC { [SpecialName] public static class $C02B13F2B6FFC3465B74B38D50860BED { } [ExtensionMarker("$C02B13F2B6FFC3465B74B38D50860BED")] public bool IsOn() { throw new NotSupportedException(); } [ExtensionMarker("$C02B13F2B6FFC3465B74B38D50860BED")] public bool IsOff() { throw new NotSupportedException(); } } public static bool IsOn(this ServerSyncModTemplatePlugin.Toggle value) { return value == ServerSyncModTemplatePlugin.Toggle.On; } public static bool IsOff(this ServerSyncModTemplatePlugin.Toggle value) { return value == ServerSyncModTemplatePlugin.Toggle.Off; } } }