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 LootFilter v1.0.0
plugins/LootFilter.dll
Decompiled a week agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: IgnoresAccessChecksTo("assembly_valheim")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("LootFilter")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Marks items or item groups as junk: no auto-pickup and no sparkles on the ground.")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+b842e5737e7a8006377d712939acbf222a2c8827")] [assembly: AssemblyProduct("LootFilter")] [assembly: AssemblyTitle("LootFilter")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace LootFilter { internal sealed class DropEffects : MonoBehaviour { private sealed class State { public readonly List<Behaviour> DisabledBehaviours = new List<Behaviour>(); public readonly List<ParticleSystem> StoppedParticles = new List<ParticleSystem>(); public readonly Dictionary<ParticleSystem, MinMaxGradient> RecoloredParticles = new Dictionary<ParticleSystem, MinMaxGradient>(); public readonly Dictionary<Light, (Color color, float intensity)> RecoloredLights = new Dictionary<Light, (Color, float)>(); } private const float ScanInterval = 0.25f; private readonly Dictionary<ItemDrop, State> _changed = new Dictionary<ItemDrop, State>(); private float _nextScan; private int _seenVersion = -1; private bool _wasRevealing; private bool _effectSettingsChanged; private void Awake() { Settings.FilteredSparkles.SettingChanged += OnEffectSettingChanged; Settings.SparkleColor.SettingChanged += OnEffectSettingChanged; } private void OnEffectSettingChanged(object sender, EventArgs e) { _effectSettingsChanged = true; } private void Update() { bool flag = Input.Held(Settings.Reveal); if (flag != _wasRevealing || _seenVersion != Rules.Version || _effectSettingsChanged || !(Time.time < _nextScan)) { if (_effectSettingsChanged) { RestoreAll(); _effectSettingsChanged = false; } _wasRevealing = flag; _seenVersion = Rules.Version; _nextScan = Time.time + 0.25f; Scan(flag); } } private void OnDestroy() { RestoreAll(); } private void RestoreAll() { foreach (State value in _changed.Values) { Restore(value); } _changed.Clear(); } private void Scan(bool revealing) { bool flag = Settings.FilteredSparkles.Value != SparkleMode.Unchanged; foreach (ItemDrop s_instance in ItemDrop.s_instances) { if (!Object.op_Implicit((Object)(object)s_instance)) { continue; } bool num = flag && !revealing && !Rules.Paused && Rules.IsFiltered(s_instance.m_itemData); State value; bool flag2 = _changed.TryGetValue(s_instance, out value); if (num) { if (!flag2) { value = (_changed[s_instance] = new State()); } Apply(s_instance, value); } else if (flag2) { Restore(value); _changed.Remove(s_instance); } } foreach (ItemDrop item in _changed.Keys.Where((ItemDrop d) => !Object.op_Implicit((Object)(object)d)).ToList()) { _changed.Remove(item); } } private static void Apply(ItemDrop drop, State state) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_007e: 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_008b: 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_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) bool flag = Settings.FilteredSparkles.Value == SparkleMode.Hidden; Color value = Settings.SparkleColor.Value; if (value.a <= 0f) { flag = true; } ParticleSystem[] componentsInChildren = ((Component)drop).GetComponentsInChildren<ParticleSystem>(); foreach (ParticleSystem val in componentsInChildren) { if (flag) { if (val.isPlaying) { val.Stop(true, (ParticleSystemStopBehavior)0); state.StoppedParticles.Add(val); } } else if (!state.RecoloredParticles.ContainsKey(val)) { MainModule main = val.main; state.RecoloredParticles[val] = ((MainModule)(ref main)).startColor; ((MainModule)(ref main)).startColor = new MinMaxGradient(value); val.Clear(false); } } Light[] componentsInChildren2 = ((Component)drop).GetComponentsInChildren<Light>(); foreach (Light val2 in componentsInChildren2) { if (flag) { if (((Behaviour)val2).enabled) { ((Behaviour)val2).enabled = false; state.DisabledBehaviours.Add((Behaviour)(object)val2); } } else if (!state.RecoloredLights.ContainsKey(val2)) { state.RecoloredLights[val2] = (val2.color, val2.intensity); val2.color = new Color(value.r, value.g, value.b); val2.intensity *= value.a; } } } private static void Restore(State state) { //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) foreach (Behaviour disabledBehaviour in state.DisabledBehaviours) { if (Object.op_Implicit((Object)(object)disabledBehaviour)) { disabledBehaviour.enabled = true; } } foreach (ParticleSystem stoppedParticle in state.StoppedParticles) { if (Object.op_Implicit((Object)(object)stoppedParticle)) { stoppedParticle.Play(true); } } foreach (KeyValuePair<ParticleSystem, MinMaxGradient> recoloredParticle in state.RecoloredParticles) { if (Object.op_Implicit((Object)(object)recoloredParticle.Key)) { MainModule main = recoloredParticle.Key.main; ((MainModule)(ref main)).startColor = recoloredParticle.Value; recoloredParticle.Key.Clear(false); } } foreach (KeyValuePair<Light, (Color, float)> recoloredLight in state.RecoloredLights) { if (Object.op_Implicit((Object)(object)recoloredLight.Key)) { recoloredLight.Key.color = recoloredLight.Value.Item1; recoloredLight.Key.intensity = recoloredLight.Value.Item2; } } } } internal static class Input { private static readonly KeyCode[] ModifierKeys; public static bool Pressed(ConfigEntry<KeyboardShortcut> entry) { //IL_0007: 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) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) KeyboardShortcut value = entry.Value; if ((int)((KeyboardShortcut)(ref value)).MainKey == 0 || !ZInput.GetKeyDown(((KeyboardShortcut)(ref value)).MainKey, false)) { return false; } List<KeyCode> modifiers = ((KeyboardShortcut)(ref value)).Modifiers.ToList(); if (modifiers.Any((KeyCode key) => !ZInput.GetKey(key, false))) { return false; } return !ModifierKeys.Any((KeyCode key) => !modifiers.Contains(key) && ZInput.GetKey(key, false)); } public static bool Held(ConfigEntry<KeyboardShortcut> entry) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) KeyboardShortcut value = entry.Value; if ((int)((KeyboardShortcut)(ref value)).MainKey != 0 && ZInput.GetKey(((KeyboardShortcut)(ref value)).MainKey, false)) { return ((KeyboardShortcut)(ref value)).Modifiers.All((KeyCode key) => ZInput.GetKey(key, false)); } return false; } public static bool IsTyping() { if (!Console.IsVisible() && !TextInput.IsVisible() && !Menu.IsVisible() && !Minimap.InTextInput()) { if (Object.op_Implicit((Object)(object)Chat.instance)) { return Chat.instance.HasFocus(); } return false; } return true; } static Input() { KeyCode[] array = new KeyCode[6]; RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/); ModifierKeys = (KeyCode[])(object)array; } } [Flags] public enum ItemGroups { None = 0, Materials = 1, FoodAndPotions = 2, Weapons = 4, Shields = 8, Armor = 0x10, Ammo = 0x20, Trophies = 0x40, Fish = 0x80, ToolsAndTorches = 0x100, UtilityAndTrinkets = 0x200, Misc = 0x400 } internal static class Groups { public static ItemGroups Of(ItemData item) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: 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) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Expected I4, but got Unknown ItemType itemType = item.m_shared.m_itemType; switch (itemType - 1) { case 0: return ItemGroups.Materials; case 1: return ItemGroups.FoodAndPotions; case 2: case 3: case 13: case 19: case 21: return ItemGroups.Weapons; case 4: return ItemGroups.Shields; case 5: case 6: case 10: case 11: case 16: return ItemGroups.Armor; case 8: case 22: return ItemGroups.Ammo; case 12: return ItemGroups.Trophies; case 20: return ItemGroups.Fish; case 14: case 18: return ItemGroups.ToolsAndTorches; case 17: case 23: return ItemGroups.UtilityAndTrinkets; default: return ItemGroups.Misc; } } public static string Describe(ItemGroups group) { return group switch { ItemGroups.FoodAndPotions => "Food & potions", ItemGroups.ToolsAndTorches => "Tools & torches", ItemGroups.UtilityAndTrinkets => "Utility & trinkets", _ => group.ToString(), }; } } internal sealed class Marker : MonoBehaviour { private void Update() { if (!Object.op_Implicit((Object)(object)Player.m_localPlayer) || Input.IsTyping()) { return; } if (Input.Pressed(Settings.TogglePause)) { Rules.Paused = !Rules.Paused; Message(Rules.Paused ? "Loot filter paused: filtered items will be picked up" : "Loot filter active"); } bool flag = Input.Pressed(Settings.ToggleItem); bool flag2 = Input.Pressed(Settings.ToggleGroup); if (!flag && !flag2) { return; } ItemData val = HoveredItem(); if (val != null) { if (flag) { MarkItem(val); } if (flag2) { MarkGroup(val); } } } private static void MarkItem(ItemData target) { bool flag = Rules.ToggleItem(target); Message(Localization.instance.Localize(target.m_shared.m_name) + ": " + (flag ? "filtered" : "not filtered")); } private static void MarkGroup(ItemData target) { ItemGroups itemGroups = Groups.Of(target); bool flag = Rules.ToggleGroup(itemGroups); Message("All " + Groups.Describe(itemGroups).ToLowerInvariant() + ": " + (flag ? "filtered" : "not filtered")); } private static ItemData HoveredItem() { if (InventoryGui.IsVisible()) { InventoryGui instance = InventoryGui.instance; return HoveredIn(instance.m_playerGrid) ?? HoveredIn(instance.m_containerGrid); } GameObject hoverObject = ((Humanoid)Player.m_localPlayer).GetHoverObject(); ItemDrop val = (Object.op_Implicit((Object)(object)hoverObject) ? hoverObject.GetComponentInParent<ItemDrop>() : null); if (!Object.op_Implicit((Object)(object)val)) { return null; } return val.m_itemData; } private static ItemData HoveredIn(InventoryGrid grid) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)grid) || !((Behaviour)grid).isActiveAndEnabled) { return null; } InventoryElement hoveredElement = grid.GetHoveredElement(); if ((Object)(object)hoveredElement == (Object)null) { return null; } Vector2i elementPos = grid.GetElementPos(hoveredElement); Inventory inventory = grid.GetInventory(); if (inventory == null) { return null; } return inventory.GetItemAt(elementPos.x, elementPos.y); } private static void Message(string text) { Player localPlayer = Player.m_localPlayer; if (localPlayer != null) { ((Character)localPlayer).Message((MessageType)1, text, 0, (Sprite)null, false); } } } [HarmonyPatch(typeof(Player), "AutoPickup")] internal static class AutoPickupPatch { private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) { FieldInfo autoPickup = AccessTools.Field(typeof(ItemDrop), "m_autoPickup"); MethodInfo replacement = AccessTools.Method(typeof(AutoPickupPatch), "CanAutoPickup", (Type[])null, (Type[])null); int replaced = 0; foreach (CodeInstruction instruction in instructions) { if (CodeInstructionExtensions.LoadsField(instruction, autoPickup, false)) { replaced++; yield return new CodeInstruction(OpCodes.Call, (object)replacement) { labels = instruction.labels, blocks = instruction.blocks }; } else { yield return instruction; } } if (replaced != 1) { Debug.LogWarning((object)$"[LootFilter] Expected one m_autoPickup check in Player.AutoPickup, found {replaced}; auto-pickup filtering may not work"); } } private static bool CanAutoPickup(ItemDrop drop) { if (drop.m_autoPickup) { return !Rules.BlocksAutoPickup(drop.m_itemData); } return false; } } internal static class BuildCameraPickupPatch { public const string Guid = "EndosBuildCamera"; public static void Apply(Harmony harmony, ManualLogSource log) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Expected O, but got Unknown MethodInfo methodInfo = AccessTools.Method(AccessTools.TypeByName("MyValheimBuildCamera.BuildCameraBase"), "ExecuteCameraAutoPickup", (Type[])null, (Type[])null); if (methodInfo == null) { log.LogWarning((object)"My Build Camera's camera pickup method wasn't found (different version?); its pickups aren't filtered"); } else { harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(typeof(BuildCameraPickupPatch), "Transpiler", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null); } } private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) { MethodInfo canAddItem = AccessTools.Method(typeof(Inventory), "CanAddItem", new Type[2] { typeof(ItemData), typeof(int) }, (Type[])null); MethodInfo replacement = AccessTools.Method(typeof(BuildCameraPickupPatch), "CanAddItem", (Type[])null, (Type[])null); int replaced = 0; foreach (CodeInstruction instruction in instructions) { if (CodeInstructionExtensions.Calls(instruction, canAddItem)) { replaced++; yield return new CodeInstruction(OpCodes.Call, (object)replacement) { labels = instruction.labels, blocks = instruction.blocks }; } else { yield return instruction; } } if (replaced != 1) { Debug.LogWarning((object)$"[LootFilter] Expected one CanAddItem check in My Build Camera's pickup, found {replaced}; its pickups may not be filtered"); } } private static bool CanAddItem(Inventory inventory, ItemData item, int stack) { if (inventory.CanAddItem(item, stack)) { return !Rules.BlocksAutoPickup(item); } return false; } } [HarmonyPatch(typeof(ItemData), "GetTooltip", new Type[] { typeof(ItemData), typeof(int), typeof(bool), typeof(float), typeof(int), typeof(bool) })] internal static class TooltipPatch { private static void Postfix(ItemData item, bool crafting, ref string __result) { if (!crafting && Settings.ShowInTooltip.Value) { string text = (Rules.Paused ? ", paused" : ""); switch (Rules.Explain(item)) { case FilterReason.Item: __result = __result + "\n<color=#ff9a5c>Loot filter: filtered" + (Rules.Paused ? " (paused)" : "") + "</color>"; break; case FilterReason.Group: __result = __result + "\n<color=#ff9a5c>Loot filter: filtered (group: " + Groups.Describe(Groups.Of(item)) + text + ")</color>"; break; } } } } [BepInPlugin("s992.LootFilter", "LootFilter", "1.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { private void Awake() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown Settings.Bind(((BaseUnityPlugin)this).Config); Rules.Init(); Harmony val = new Harmony("s992.LootFilter"); val.PatchAll(); if (Chainloader.PluginInfos.ContainsKey("EndosBuildCamera")) { BuildCameraPickupPatch.Apply(val, ((BaseUnityPlugin)this).Logger); } ((Component)this).gameObject.AddComponent<Marker>(); ((Component)this).gameObject.AddComponent<DropEffects>(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"LootFilter 1.0.0 loaded"); } } internal enum FilterReason { NotFiltered, Item, Group } internal static class Rules { private static HashSet<string> s_items = new HashSet<string>(StringComparer.OrdinalIgnoreCase); private static bool s_paused; public static int Version { get; private set; } public static bool Paused { get { return s_paused; } set { if (s_paused != value) { s_paused = value; Version++; } } } public static bool BlocksAutoPickup(ItemData item) { if (Settings.BlockAutoPickup.Value && !Paused) { return IsFiltered(item); } return false; } public static void Init() { ParseItems(); Settings.FilteredItems.SettingChanged += delegate { ParseItems(); Version++; }; Settings.FilteredGroups.SettingChanged += delegate { Version++; }; } private static void ParseItems() { s_items = new HashSet<string>(from s in Settings.FilteredItems.Value.Split(',') select s.Trim() into s where s.Length > 0 select s, StringComparer.OrdinalIgnoreCase); } public static string ItemName(ItemData item) { if (!Object.op_Implicit((Object)(object)item.m_dropPrefab)) { return item.m_shared.m_name; } return ((Object)item.m_dropPrefab).name; } public static bool IsFiltered(ItemData item) { return Explain(item) != FilterReason.NotFiltered; } public static FilterReason Explain(ItemData item) { if (item == null) { return FilterReason.NotFiltered; } if (s_items.Contains(ItemName(item))) { return FilterReason.Item; } if ((Settings.FilteredGroups.Value & Groups.Of(item)) != ItemGroups.None) { return FilterReason.Group; } return FilterReason.NotFiltered; } public static bool ToggleItem(ItemData item) { string item2 = ItemName(item); HashSet<string> hashSet = new HashSet<string>(s_items, StringComparer.OrdinalIgnoreCase); bool num = !hashSet.Remove(item2); if (num) { hashSet.Add(item2); } Settings.FilteredItems.Value = string.Join(", ", hashSet.OrderBy<string, string>((string s) => s, StringComparer.OrdinalIgnoreCase)); return num; } public static bool ToggleGroup(ItemGroups group) { ConfigEntry<ItemGroups> filteredGroups = Settings.FilteredGroups; filteredGroups.Value ^= group; return (Settings.FilteredGroups.Value & group) != 0; } } public enum SparkleMode { Hidden, Recolored, Unchanged } internal static class Settings { public static ConfigEntry<string> FilteredItems; public static ConfigEntry<ItemGroups> FilteredGroups; public static ConfigEntry<bool> BlockAutoPickup; public static ConfigEntry<bool> ShowInTooltip; public static ConfigEntry<SparkleMode> FilteredSparkles; public static ConfigEntry<Color> SparkleColor; public static ConfigEntry<KeyboardShortcut> ToggleItem; public static ConfigEntry<KeyboardShortcut> ToggleGroup; public static ConfigEntry<KeyboardShortcut> Reveal; public static ConfigEntry<KeyboardShortcut> TogglePause; public static void Bind(ConfigFile config) { //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) FilteredItems = config.Bind<string>("Rules", "FilteredItems", "", "Comma-separated item names to filter (internal prefab names, e.g. Resin, Stone, RoundLog). Easiest to edit with the ToggleItem key while hovering an item."); FilteredGroups = config.Bind<ItemGroups>("Rules", "FilteredGroups", ItemGroups.None, "Item groups to filter."); BlockAutoPickup = config.Bind<bool>("Behaviour", "BlockAutoPickup", true, "Don't auto-pickup filtered items. They can still be picked up manually."); ShowInTooltip = config.Bind<bool>("Behaviour", "ShowInTooltip", true, "Add a line to item tooltips saying whether (and why) the item is filtered."); FilteredSparkles = config.Bind<SparkleMode>("Effects", "FilteredSparkles", SparkleMode.Hidden, "What to do with the sparkles and glow of filtered drops: hide them, recolor them with SparkleColor, or leave them alone."); SparkleColor = config.Bind<Color>("Effects", "SparkleColor", new Color(0.55f, 0.55f, 0.55f, 0.35f), "Color of filtered drops' sparkles when FilteredSparkles is Recolored. The alpha (A) value sets how visible they are."); ToggleItem = config.Bind<KeyboardShortcut>("Keys", "ToggleItem", new KeyboardShortcut((KeyCode)127, Array.Empty<KeyCode>()), "Filter/unfilter the hovered item (inventory, chest or on the ground)."); ToggleGroup = config.Bind<KeyboardShortcut>("Keys", "ToggleGroup", new KeyboardShortcut((KeyCode)127, (KeyCode[])(object)new KeyCode[1] { (KeyCode)304 }), "Filter/unfilter the hovered item's group (Weapons, Trophies, ...)."); Reveal = config.Bind<KeyboardShortcut>("Keys", "Reveal", new KeyboardShortcut((KeyCode)308, Array.Empty<KeyCode>()), "Hold to show the original effects of filtered items."); TogglePause = config.Bind<KeyboardShortcut>("Keys", "TogglePause", new KeyboardShortcut((KeyCode)277, Array.Empty<KeyCode>()), "Pause/resume the filter: while paused, filtered items are auto-picked up and keep their effects. The filter is always active again after restarting the game."); } } public static class MyPluginInfo { public const string PLUGIN_GUID = "s992.LootFilter"; public const string PLUGIN_NAME = "LootFilter"; public const string PLUGIN_VERSION = "1.0.0"; } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }