Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of ServeYouRight v1.0.1
ServeYouRight.dll
Decompiled a month agousing 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.1")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.1.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 { public ExtensionMarkerAttribute(string name) { } } } namespace ServerSyncModTemplate { [BepInPlugin("sighsorry.ServeYouRight", "ServeYouRight", "1.0.1")] [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<ConfigEntryBase>? 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.1"; 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<string, PerModCategoryConfig> 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<T> config<T>(string group, string name, T value, ConfigDescription description) { return ((BaseUnityPlugin)this).Config.Bind<T>(group, name, value, description); } private ConfigEntry<T> config<T>(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<object>())); } private ConfigEntry<T> config<T>(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<string, PerModCategoryConfig>(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); } } } internal static class FeasterFoodInjector { [CompilerGenerated] private sealed class <GetFeasterPieceTables>d__10 : IEnumerable<PieceTable>, IEnumerable, IEnumerator<PieceTable>, IDisposable, IEnumerator { private int <>1__state; private PieceTable <>2__current; private int <>l__initialThreadId; private ObjectDB objectDb; public ObjectDB <>3__objectDb; private HashSet<PieceTable> <uniqueTables>5__1; private List<GameObject>.Enumerator <>s__2; private GameObject <itemPrefab>5__3; private ItemDrop <itemDrop>5__4; private PieceTable <pieceTable>5__5; private bool <supportsFoodTabs>5__6; PieceTable IEnumerator<PieceTable>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <GetFeasterPieceTables>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(); } } <uniqueTables>5__1 = null; <>s__2 = default(List<GameObject>.Enumerator); <itemPrefab>5__3 = null; <itemDrop>5__4 = null; <pieceTable>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; <uniqueTables>5__1 = new HashSet<PieceTable>(); <>s__2 = objectDb.m_items.GetEnumerator(); <>1__state = -3; goto IL_0190; IL_017a: <itemDrop>5__4 = null; <pieceTable>5__5 = null; <itemPrefab>5__3 = null; goto IL_0190; IL_0190: while (true) { if (<>s__2.MoveNext()) { <itemPrefab>5__3 = <>s__2.Current; if ((Object)(object)<itemPrefab>5__3 == (Object)null) { continue; } <itemDrop>5__4 = <itemPrefab>5__3.GetComponent<ItemDrop>(); <pieceTable>5__5 = <itemDrop>5__4?.m_itemData?.m_shared?.m_buildPieces; if (!((Object)(object)<pieceTable>5__5 == (Object)null) && <pieceTable>5__5.m_canRemoveFeasts) { <supportsFoodTabs>5__6 = <pieceTable>5__5.m_categories.Contains((PieceCategory)6) || <pieceTable>5__5.m_categories.Contains((PieceCategory)7) || <pieceTable>5__5.m_categories.Contains((PieceCategory)5); if (<supportsFoodTabs>5__6) { break; } } continue; } <>m__Finally1(); <>s__2 = default(List<GameObject>.Enumerator); return false; } if (<uniqueTables>5__1.Add(<pieceTable>5__5)) { <>2__current = <pieceTable>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<PieceTable> IEnumerable<PieceTable>.GetEnumerator() { <GetFeasterPieceTables>d__10 <GetFeasterPieceTables>d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; <GetFeasterPieceTables>d__ = this; } else { <GetFeasterPieceTables>d__ = new <GetFeasterPieceTables>d__10(0); } <GetFeasterPieceTables>d__.objectDb = <>3__objectDb; return <GetFeasterPieceTables>d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable<PieceTable>)this).GetEnumerator(); } } private static bool _isInjecting; private static readonly Dictionary<string, ModCategoryInfo> ModCategoryCache = new Dictionary<string, ModCategoryInfo>(StringComparer.OrdinalIgnoreCase); private static readonly Dictionary<string, FoodSourceMod> SourceModHitCache = new Dictionary<string, FoodSourceMod>(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<CandidateFood> 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<CandidateFood> 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<CandidateFood> list = new List<CandidateFood>(); FeastRoutingData feastRoutingData = BuildFeastRoutingData(objectDb); foreach (GameObject item in objectDb.m_items) { if ((Object)(object)item == (Object)null) { continue; } ItemDrop component = item.GetComponent<ItemDrop>(); 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<Feast>() != (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<string, ItemDrop> dictionary = new Dictionary<string, ItemDrop>(StringComparer.OrdinalIgnoreCase); foreach (GameObject item in objectDb.m_items) { if ((Object)(object)item == (Object)null) { continue; } ItemDrop component = item.GetComponent<ItemDrop>(); if (!((Object)(object)component == (Object)null)) { string prefabName = Utils.GetPrefabName(((Object)item).name); if (!dictionary.ContainsKey(prefabName)) { dictionary[prefabName] = component; } } } Dictionary<string, GameObject> dictionary2 = new Dictionary<string, GameObject>(StringComparer.OrdinalIgnoreCase); HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase); foreach (KeyValuePair<string, ItemDrop> item2 in dictionary) { string key = item2.Key; ItemDrop value = item2.Value; SharedData val = value.m_itemData?.m_shared; Feast component2 = ((Component)value).GetComponent<Feast>(); 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<Feast>() != (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<string, ItemDrop> 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<Feast>() != (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(<GetFeasterPieceTables>d__10))] private static IEnumerable<PieceTable> GetFeasterPieceTables(ObjectDB objectDb) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <GetFeasterPieceTables>d__10(-2) { <>3__objectDb = objectDb }; } private static int InjectIntoTable(PieceTable table, List<CandidateFood> 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<int> 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<ModCategoryInfo> 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<Piece>(); if (!((Object)(object)component == (Object)null) && component.m_category == category && !component.m_repairPiece && !component.m_removePiece) { templatePiece = component; templateWearNTear = piece.GetComponent<WearNTear>(); 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<Piece>(); if (!((Object)(object)component2 == (Object)null) && !component2.m_repairPiece && !component2.m_removePiece) { templatePiece = component2; templateWearNTear = piece2.GetComponent<WearNTear>(); 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<ZNetView>() == (Object)null) { ServerSyncModTemplatePlugin.ServerSyncModTemplateLogger.LogWarning((object)("Skipping '" + ((Object)foodPrefab).name + "' because it has no ZNetView.")); return false; } Piece val = foodPrefab.GetComponent<Piece>(); if ((Object)(object)val == (Object)null) { val = foodPrefab.AddComponent<Piece>(); CopyFields<Piece>(templatePiece, val); } WearNTear component = foodPrefab.GetComponent<WearNTear>(); if ((Object)(object)component == (Object)null) { component = foodPrefab.AddComponent<WearNTear>(); if ((Object)(object)templateWearNTear != (Object)null) { CopyFields<WearNTear>(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<ServeYouRightInjectedPieceMarker>() == (Object)null) { foodPrefab.AddComponent<ServeYouRightInjectedPieceMarker>(); } return true; } private static HashSet<int> BuildExistingFoodHashSet(PieceTable table) { HashSet<int> hashSet = new HashSet<int>(); foreach (GameObject piece in table.m_pieces) { if ((Object)(object)piece == (Object)null) { continue; } Piece component = piece.GetComponent<Piece>(); if ((Object)(object)component == (Object)null) { continue; } Requirement[] array = component.m_resources ?? Array.Empty<Requirement>(); 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<ItemDrop>(); 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<ServeYouRightInjectedPieceMarker>() != (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<string> 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>(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<string, GameObject> MaterialToResultPrefab { get; } public HashSet<string> ResultPrefabNames { get; } public FeastRoutingData(Dictionary<string, GameObject> materialToResultPrefab, HashSet<string> 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<ServerSyncModTemplatePlugin.Toggle> Food { get; } public ConfigEntry<ServerSyncModTemplatePlugin.Toggle> Meads { get; } public ConfigEntry<ServerSyncModTemplatePlugin.Toggle> Feasts { get; } public PerModCategoryConfig(FoodSourceMod mod, ConfigEntry<ServerSyncModTemplatePlugin.Toggle> food, ConfigEntry<ServerSyncModTemplatePlugin.Toggle> meads, ConfigEntry<ServerSyncModTemplatePlugin.Toggle> 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<string> WackyCloneHitCache = new HashSet<string>(StringComparer.OrdinalIgnoreCase); private static readonly HashSet<string> WackyCloneMissCache = new HashSet<string>(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 <G>$8D1D3E80A18AA9715780B6CB7003B2F1 { [SpecialName] public static class <M>$895AB635D4D087636CF1C26BA650BA11 { } [ExtensionMarker("<M>$895AB635D4D087636CF1C26BA650BA11")] public bool IsKeyDown() { throw null; } [ExtensionMarker("<M>$895AB635D4D087636CF1C26BA650BA11")] public bool IsKeyHeld() { throw null; } } 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<KeyCode, bool>)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<KeyCode, bool>)Input.GetKey); } } public static class ToggleExtentions { [SpecialName] public sealed class <G>$57ABA57BD1CE54EF9BE00DAABFE926BC { [SpecialName] public static class <M>$C02B13F2B6FFC3465B74B38D50860BED { } [ExtensionMarker("<M>$C02B13F2B6FFC3465B74B38D50860BED")] public bool IsOn() { throw null; } [ExtensionMarker("<M>$C02B13F2B6FFC3465B74B38D50860BED")] public bool IsOff() { throw null; } } 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; } } }