Decompiled source of LycansSoundTrapItem v1.0.1
plugins/LycansMod.SoundTrapItem.dll
Decompiled 6 hours ago
The result has been truncated due to the large size, download it to view full contents!
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.Versioning; using System.Security; using System.Security.Cryptography; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using Fusion; using LycansMods.Shared; using Managers; using Microsoft.CodeAnalysis; using On; using TMPro; using UnityEngine; using UnityEngine.Localization; using UnityEngine.Localization.Settings; using UnityEngine.Localization.Tables; using UnityEngine.Networking; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")] [assembly: AssemblyCompany("LycansMod.SoundTrapItem")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+c3415ca56729154cb9015863ca402746bcdef0b3")] [assembly: AssemblyProduct("LycansMod.SoundTrapItem")] [assembly: AssemblyTitle("LycansMod.SoundTrapItem")] [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] internal sealed class IsReadOnlyAttribute : Attribute { } [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 LycansMods.Shared { public static class AbilityHud { public enum Placement { BelowAction, StaminaRight, ScreenCenter } private sealed class Watcher : MonoBehaviour { private void LateUpdate() { if ((Object)(object)_root != (Object)null && ((Component)_root).gameObject.activeSelf && Time.unscaledTime - _shownAt > 0.25f) { ((Component)_root).gameObject.SetActive(false); } } } private static RectTransform _root; private static Image _ring; private static TextMeshProUGUI _icon; private static TextMeshProUGUI _title; private static TextMeshProUGUI _detail; private static TextMeshProUGUI _badge; private static GameObject _badgeGo; private static float _shownAt; private static Sprite _circle; public static void Show(string icon, string title, string detail, Color color, float fill, string badge = null, Placement placement = Placement.StaminaRight) { //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_0129: 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) if (Build()) { _shownAt = Time.unscaledTime; ((Component)_root).gameObject.SetActive(true); ((Transform)_root).SetAsLastSibling(); Place(placement); bool flag = !string.IsNullOrEmpty(icon) && ((Object)(object)((TMP_Text)_icon).font == (Object)null || ((TMP_Text)_icon).font.HasCharacter(icon[0], true, false)); ((TMP_Text)_icon).text = (flag ? icon : (string.IsNullOrEmpty(title) ? "?" : title.Substring(0, 1).ToUpperInvariant())); ((TMP_Text)_title).text = title; ((Graphic)_title).color = color; ((TMP_Text)_detail).text = detail; ((Graphic)_ring).color = new Color(color.r, color.g, color.b, (fill >= 0.999f) ? 1f : 0.85f); _ring.fillAmount = Mathf.Clamp01(fill); ((Graphic)_icon).color = (Color)((fill >= 0.999f) ? Color.white : new Color(1f, 1f, 1f, 0.55f)); _badgeGo.SetActive(!string.IsNullOrEmpty(badge)); if (_badgeGo.activeSelf) { ((TMP_Text)_badge).text = badge; } } } private static bool Build() { //IL_00d6: 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_0135: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Unknown result type (might be due to invalid IL or missing references) //IL_0211: Unknown result type (might be due to invalid IL or missing references) //IL_024b: Unknown result type (might be due to invalid IL or missing references) //IL_0273: Unknown result type (might be due to invalid IL or missing references) //IL_0287: Unknown result type (might be due to invalid IL or missing references) //IL_02cc: Unknown result type (might be due to invalid IL or missing references) //IL_0317: Unknown result type (might be due to invalid IL or missing references) //IL_031e: Unknown result type (might be due to invalid IL or missing references) //IL_0339: Unknown result type (might be due to invalid IL or missing references) //IL_0357: Unknown result type (might be due to invalid IL or missing references) //IL_0375: Unknown result type (might be due to invalid IL or missing references) //IL_03b4: Unknown result type (might be due to invalid IL or missing references) //IL_03e3: Unknown result type (might be due to invalid IL or missing references) //IL_03ea: Unknown result type (might be due to invalid IL or missing references) //IL_0405: Unknown result type (might be due to invalid IL or missing references) //IL_0423: Unknown result type (might be due to invalid IL or missing references) //IL_0441: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_root != (Object)null) { return true; } GameUI val = (((Object)(object)GameManager.Instance != (Object)null) ? GameManager.Instance.gameUI : null); RectTransform val2 = ActionAnchor(val) ?? Anchor(val); Canvas val3 = (((Object)(object)val2 != (Object)null) ? ((Component)val2).GetComponentInParent<Canvas>() : null); RectTransform val4 = (((Object)(object)val3 != (Object)null && (Object)(object)val3.rootCanvas != (Object)null) ? ((Component)val3.rootCanvas).GetComponent<RectTransform>() : null); if ((Object)(object)val2 == (Object)null || (Object)(object)val4 == (Object)null) { return false; } TMP_FontAsset font = (((Object)(object)val.actionShortcut != (Object)null && (Object)(object)((Component)val.actionShortcut).GetComponent<TextMeshProUGUI>() != (Object)null) ? ((TMP_Text)((Component)val.actionShortcut).GetComponent<TextMeshProUGUI>()).font : null); _root = new GameObject("LycansAbilityHud", new Type[1] { typeof(RectTransform) }).GetComponent<RectTransform>(); ((Transform)_root).SetParent((Transform)(object)val4, false); ((Component)_root).gameObject.AddComponent<Watcher>(); _root.sizeDelta = new Vector2(330f, 64f); RectTransform root = _root; RectTransform root2 = _root; Vector2 val5 = default(Vector2); ((Vector2)(ref val5))..ctor(0.5f, 0.5f); root2.anchorMax = val5; root.anchorMin = val5; _root.pivot = new Vector2(0f, 0.5f); Image obj = Circle(_root, "Back", new Color(0f, 0f, 0f, 0.55f), 60f, new Vector2(30f, 0f)); _ring = Circle(((Graphic)obj).rectTransform, "Ring", Color.white, 60f, Vector2.zero); _ring.type = (Type)3; _ring.fillMethod = (FillMethod)4; _ring.fillOrigin = 2; _ring.fillClockwise = true; _icon = Label(((Graphic)Circle(((Graphic)obj).rectTransform, "Core", new Color(0.08f, 0.06f, 0.05f, 0.92f), 48f, Vector2.zero)).rectTransform, font, 24f, (TextAlignmentOptions)514, (FontStyles)1); ((TMP_Text)_icon).rectTransform.sizeDelta = new Vector2(48f, 48f); Image obj2 = Circle(((Graphic)obj).rectTransform, "Badge", new Color(0.12f, 0.09f, 0.07f, 0.95f), 24f, new Vector2(22f, 22f)); _badgeGo = ((Component)obj2).gameObject; _badge = Label(((Graphic)obj2).rectTransform, font, 13f, (TextAlignmentOptions)514, (FontStyles)1); ((TMP_Text)_badge).rectTransform.sizeDelta = new Vector2(24f, 24f); _title = Label(_root, font, 18f, (TextAlignmentOptions)1025, (FontStyles)1); RectTransform rectTransform = ((TMP_Text)_title).rectTransform; RectTransform rectTransform2 = ((TMP_Text)_title).rectTransform; ((Vector2)(ref val5))..ctor(0f, 0.5f); rectTransform2.anchorMax = val5; rectTransform.anchorMin = val5; ((TMP_Text)_title).rectTransform.pivot = new Vector2(0f, 0f); ((TMP_Text)_title).rectTransform.anchoredPosition = new Vector2(70f, 2f); ((TMP_Text)_title).rectTransform.sizeDelta = new Vector2(260f, 24f); _detail = Label(_root, font, 15f, (TextAlignmentOptions)257, (FontStyles)0); ((Graphic)_detail).color = new Color(1f, 1f, 1f, 0.88f); RectTransform rectTransform3 = ((TMP_Text)_detail).rectTransform; RectTransform rectTransform4 = ((TMP_Text)_detail).rectTransform; ((Vector2)(ref val5))..ctor(0f, 0.5f); rectTransform4.anchorMax = val5; rectTransform3.anchorMin = val5; ((TMP_Text)_detail).rectTransform.pivot = new Vector2(0f, 1f); ((TMP_Text)_detail).rectTransform.anchoredPosition = new Vector2(70f, -2f); ((TMP_Text)_detail).rectTransform.sizeDelta = new Vector2(260f, 24f); ((Component)_root).gameObject.SetActive(false); return true; } private static RectTransform ActionAnchor(GameUI ui) { if (!((Object)(object)ui != (Object)null) || !((Object)(object)ui.actionShortcut != (Object)null)) { return null; } return ((Component)ui.actionShortcut).GetComponent<RectTransform>(); } private static RectTransform Anchor(GameUI ui) { if ((Object)(object)ui == (Object)null) { return null; } if ((Object)(object)ui.hungerProgressMask != (Object)null) { return ((Graphic)ui.hungerProgressMask).rectTransform; } if (!((Object)(object)ui.actionShortcut != (Object)null)) { return null; } return ((Component)ui.actionShortcut).GetComponent<RectTransform>(); } private static void Place(Placement placement) { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) RectTransform val = Anchor(((Object)(object)GameManager.Instance != (Object)null) ? GameManager.Instance.gameUI : null); RectTransform val2 = ((placement == Placement.StaminaRight) ? val : null); Transform parent = ((Transform)_root).parent; RectTransform val3 = (RectTransform)(object)((parent is RectTransform) ? parent : null); if (!((Object)(object)val3 == (Object)null)) { Canvas componentInParent = ((Component)val3).GetComponentInParent<Canvas>(); Camera val4 = (((Object)(object)componentInParent != (Object)null && (int)componentInParent.renderMode != 0) ? componentInParent.worldCamera : null); float num = (((Object)(object)componentInParent != (Object)null) ? componentInParent.scaleFactor : 1f); Vector2 val5 = default(Vector2); Vector2 pivot = default(Vector2); if (placement == Placement.BelowAction) { ((Vector2)(ref val5))..ctor((float)Screen.width * 0.5f, (float)Screen.height * 0.43f); ((Vector2)(ref pivot))..ctor(0.5f, 0.5f); } else if (placement == Placement.ScreenCenter || (Object)(object)val2 == (Object)null) { ((Vector2)(ref val5))..ctor((float)Screen.width / 2f, (float)Screen.height * 0.58f); ((Vector2)(ref pivot))..ctor(0.5f, 0.5f); } else { Vector3[] array = (Vector3[])(object)new Vector3[4]; val2.GetWorldCorners(array); val5 = RectTransformUtility.WorldToScreenPoint(val4, new Vector3(array[2].x, (array[0].y + array[2].y) / 2f, array[0].z)) + new Vector2(16f * num, 0f); ((Vector2)(ref pivot))..ctor(0f, 0.5f); } Vector2 val6 = default(Vector2); if (RectTransformUtility.ScreenPointToLocalPointInRectangle(val3, val5, val4, ref val6)) { _root.pivot = pivot; ((Transform)_root).localPosition = new Vector3(val6.x, val6.y, 0f); } } } private static Image Circle(RectTransform parent, string name, Color color, float size, Vector2 position) { //IL_0014: 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_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0067: 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) RectTransform component = new GameObject(name, new Type[1] { typeof(RectTransform) }).GetComponent<RectTransform>(); ((Transform)component).SetParent((Transform)(object)parent, false); Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(((Object)(object)parent == (Object)(object)_root) ? 0f : 0.5f, 0.5f); component.anchorMax = val; component.anchorMin = val; component.sizeDelta = new Vector2(size, size); component.anchoredPosition = position; Image obj = ((Component)component).gameObject.AddComponent<Image>(); obj.sprite = CircleSprite(); ((Graphic)obj).color = color; ((Graphic)obj).raycastTarget = false; return obj; } private static TextMeshProUGUI Label(RectTransform parent, TMP_FontAsset font, float size, TextAlignmentOptions align, FontStyles style) { //IL_0018: 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_0054: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) RectTransform component = new GameObject("Text", new Type[1] { typeof(RectTransform) }).GetComponent<RectTransform>(); ((Transform)component).SetParent((Transform)(object)parent, false); TextMeshProUGUI val = ((Component)component).gameObject.AddComponent<TextMeshProUGUI>(); if ((Object)(object)font != (Object)null) { ((TMP_Text)val).font = font; } ((TMP_Text)val).fontSize = size; ((TMP_Text)val).alignment = align; ((TMP_Text)val).fontStyle = style; ((TMP_Text)val).enableWordWrapping = false; ((Graphic)val).raycastTarget = false; ((Graphic)val).color = Color.white; return val; } private static Sprite CircleSprite() { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: 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_0033: Expected O, but got Unknown //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_circle != (Object)null) { return _circle; } Texture2D val = new Texture2D(128, 128, (TextureFormat)4, false) { wrapMode = (TextureWrapMode)1, filterMode = (FilterMode)1 }; Color32[] array = (Color32[])(object)new Color32[16384]; float num = 63f; for (int i = 0; i < 128; i++) { for (int j = 0; j < 128; j++) { float num2 = Mathf.Sqrt(((float)j + 0.5f - 64f) * ((float)j + 0.5f - 64f) + ((float)i + 0.5f - 64f) * ((float)i + 0.5f - 64f)); array[i * 128 + j] = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, (byte)(Mathf.Clamp01(num - num2 + 0.5f) * 255f)); } } val.SetPixels32(array); val.Apply(); _circle = Sprite.Create(val, new Rect(0f, 0f, 128f, 128f), new Vector2(0.5f, 0.5f), 100f); return _circle; } } public static class Achievements { private const string ApplyKey = "lycans.achievements.apply"; private const string PendingKey = "lycans.achievements.pending"; public const string ReportAction = "achievements.report"; private const string SoloKey = "lycans.victory.solo"; public static int[] SoloWinners => AppDomain.CurrentDomain.GetData("lycans.victory.solo") as int[]; public static void Increment(string key, long n = 1L) { Apply("inc", key, null, n); } public static void SetMax(string key, long value) { Apply("max", key, null, value); } public static void AddToSet(string key, string value) { Apply("set", key, value, 1L); } public static void AddProgress(string achievementId, long n = 1L) { Apply("progress", achievementId, null, n); } public static void Unlock(string achievementId) { Apply("unlock", achievementId, null, 1L); } public static void ReportTo(PlayerController player, string op, string key, long n = 1L) { //IL_005e: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)player == (Object)null) && !string.IsNullOrEmpty(key)) { if ((Object)(object)player == (Object)(object)PlayerController.Local) { Apply(op, key, null, n); } else if (AppDomain.CurrentDomain.GetData("lycans.achievements.apply") != null) { ActionRequests.Broadcast("achievements.report", player, ModProposals.Hash(op + "|" + key), new Vector3((float)n, 0f, 0f)); } } } private static void Apply(string op, string key, string value, long n) { if (string.IsNullOrEmpty(key)) { return; } if (AppDomain.CurrentDomain.GetData("lycans.achievements.apply") is Action<string, string, string, long> action) { action(op, key, value, n); return; } ArrayList arrayList = AppDomain.CurrentDomain.GetData("lycans.achievements.pending") as ArrayList; if (arrayList == null) { arrayList = new ArrayList(); AppDomain.CurrentDomain.SetData("lycans.achievements.pending", arrayList); } if (arrayList.Count < 2000) { arrayList.Add(new object[4] { op, key, value, n }); } } public static void SetSoloWinners(int[] playerIndices) { AppDomain.CurrentDomain.SetData("lycans.victory.solo", playerIndices); } public static void Publish(Action<string, string, string, long> apply) { AppDomain.CurrentDomain.SetData("lycans.achievements.apply", apply); if (AppDomain.CurrentDomain.GetData("lycans.achievements.pending") is ArrayList arrayList) { object[] array = arrayList.ToArray(); for (int i = 0; i < array.Length; i++) { object[] array2 = (object[])array[i]; apply((string)array2[0], (string)array2[1], (string)array2[2], (long)array2[3]); } arrayList.Clear(); } } } public static class ActionRequests { private const string HandlersKey = "lycans.mods.actions.handlers"; private const string SendKey = "lycans.mods.actions.send"; public static void Register(string action, Action<PlayerController, int, Vector3> handler) { Handlers()[ModProposals.Hash(action)] = handler; } public static bool Request(string action, PlayerController actor, int value, Vector3 position = default(Vector3)) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) return Send(broadcast: false, action, actor, value, position); } public static bool Broadcast(string action, PlayerController actor, int value, Vector3 position = default(Vector3)) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) return Send(broadcast: true, action, actor, value, position); } public static bool ShouldSendFrom(PlayerController actor) { if ((Object)(object)actor != (Object)null && ((SimulationBehaviour)actor).HasInputAuthority && (Object)(object)((SimulationBehaviour)actor).Runner != (Object)null) { return ((SimulationBehaviour)actor).Runner.IsForward; } return false; } public static void PublishSender(Action<bool, int, int, int, Vector3> send) { AppDomain.CurrentDomain.SetData("lycans.mods.actions.send", send); } public static void Dispatch(int hash, int actorIndex, int value, Vector3 position) { //IL_0058: Unknown result type (might be due to invalid IL or missing references) if (!Handlers().TryGetValue(hash, out var value2)) { Log.Warning("[ActionRequests] Action inconnue (" + hash + ") : mod absent chez ce joueur ?"); return; } PlayerController actor = null; PlayerRegistry.ForEach((Action<PlayerController>)delegate(PlayerController p) { if ((Object)(object)actor == (Object)null && (Object)(object)p != (Object)null && p.Index == actorIndex) { actor = p; } }); try { value2(actor, value, position); } catch (Exception ex) { Log.Error("[ActionRequests] Action en erreur : " + ex); } } private static bool Send(bool broadcast, string action, PlayerController actor, int value, Vector3 position) { //IL_004a: Unknown result type (might be due to invalid IL or missing references) if (!(AppDomain.CurrentDomain.GetData("lycans.mods.actions.send") is Action<bool, int, int, int, Vector3> action2)) { Log.Warning("[ActionRequests] « " + action + " » ignorée : mod_core absent."); return false; } action2(broadcast, ModProposals.Hash(action), ((Object)(object)actor != (Object)null) ? actor.Index : (-1), value, position); return true; } private static Dictionary<int, Action<PlayerController, int, Vector3>> Handlers() { if (AppDomain.CurrentDomain.GetData("lycans.mods.actions.handlers") is Dictionary<int, Action<PlayerController, int, Vector3>> result) { return result; } Dictionary<int, Action<PlayerController, int, Vector3>> dictionary = new Dictionary<int, Action<PlayerController, int, Vector3>>(); AppDomain.CurrentDomain.SetData("lycans.mods.actions.handlers", dictionary); return dictionary; } } public static class AdminCommands { private const string Key = "lycans.mods.admin.commands"; public static void Register(string category, string label, Action run, Func<bool> available = null) { List<object[]> list = All(); lock (list) { list.Add(new object[4] { category, label, run, available }); } } public static List<object[]> All() { if (AppDomain.CurrentDomain.GetData("lycans.mods.admin.commands") is List<object[]> result) { return result; } List<object[]> list = new List<object[]>(); AppDomain.CurrentDomain.SetData("lycans.mods.admin.commands", list); return list; } } public static class AppearanceHooks { private const string CurrentKey = "lycans.appearance.skin.current"; private const string ChooseKey = "lycans.appearance.skin.choose"; private const string ColorKey = "lycans.appearance.color.request"; private const string PreviewKey = "lycans.appearance.preview.wolf"; public static bool SkinsAvailable => AppDomain.CurrentDomain.GetData("lycans.appearance.skin.choose") is Action<bool, string>; public static bool ColorsAvailable => AppDomain.CurrentDomain.GetData("lycans.appearance.color.request") is Action<int>; public static bool PreviewWolf { get { if (AppDomain.CurrentDomain.GetData("lycans.appearance.preview.wolf") is bool[] array) { return array[0]; } return false; } set { bool[] array = AppDomain.CurrentDomain.GetData("lycans.appearance.preview.wolf") as bool[]; if (array == null) { AppDomain.CurrentDomain.SetData("lycans.appearance.preview.wolf", array = new bool[1]); } array[0] = value; } } public static string CurrentSkin(bool werewolf) { if (!(AppDomain.CurrentDomain.GetData("lycans.appearance.skin.current") is Func<bool, string> func)) { return null; } return func(werewolf); } public static void ChooseSkin(bool werewolf, string key) { if (AppDomain.CurrentDomain.GetData("lycans.appearance.skin.choose") is Action<bool, string> action) { action(werewolf, key); } } public static void RequestColor(int color) { if (AppDomain.CurrentDomain.GetData("lycans.appearance.color.request") is Action<int> action) { action(color); } } public static void PublishSkins(Func<bool, string> current, Action<bool, string> choose) { AppDomain.CurrentDomain.SetData("lycans.appearance.skin.current", current); AppDomain.CurrentDomain.SetData("lycans.appearance.skin.choose", choose); } public static void PublishColorRequest(Action<int> request) { AppDomain.CurrentDomain.SetData("lycans.appearance.color.request", request); } } public static class AudioBank { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static hook_Spawned <>9__3_0; internal void <LoadEmbedded>b__3_0(orig_Spawned orig, GameManager self) { orig.Invoke(self); if (_loaded) { return; } _loaded = true; string[] manifestResourceNames = _assembly.GetManifestResourceNames(); foreach (string text in manifestResourceNames) { if (text.StartsWith("LycansAudio.", StringComparison.Ordinal)) { ((MonoBehaviour)self).StartCoroutine(Load(text)); } } } } public const string ResourcePrefix = "LycansAudio."; private static Assembly _assembly; private static bool _loaded; public static string TempDir => Path.Combine(Path.GetTempPath(), "LycansModsAudio", Process.GetCurrentProcess().Id.ToString()); public static void LoadEmbedded(Assembly assembly) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown if (_assembly != null) { return; } _assembly = assembly; object obj = <>c.<>9__3_0; if (obj == null) { hook_Spawned val = delegate(orig_Spawned orig, GameManager self) { orig.Invoke(self); if (!_loaded) { _loaded = true; string[] manifestResourceNames = _assembly.GetManifestResourceNames(); foreach (string text in manifestResourceNames) { if (text.StartsWith("LycansAudio.", StringComparison.Ordinal)) { ((MonoBehaviour)self).StartCoroutine(Load(text)); } } } }; <>c.<>9__3_0 = val; obj = (object)val; } GameManager.Spawned += (hook_Spawned)obj; } private static IEnumerator Load(string resource) { string fileName = resource.Substring("LycansAudio.".Length); string text; try { string tempDir = TempDir; Directory.CreateDirectory(tempDir); text = Path.Combine(tempDir, fileName); using Stream stream = _assembly.GetManifestResourceStream(resource); using FileStream destination = File.Create(text); stream.CopyTo(destination); } catch (Exception ex) { Log.Error("[AudioBank] Extraction impossible de " + fileName + " : " + ex.Message); yield break; } string name = Path.GetFileNameWithoutExtension(fileName); bool split = name.EndsWith("__split", StringComparison.OrdinalIgnoreCase); UnityWebRequest request = UnityWebRequestMultimedia.GetAudioClip("file://" + text.Replace("\\", "/"), TypeOf(text)); try { if (split) { DownloadHandler downloadHandler = request.downloadHandler; DownloadHandlerAudioClip val = (DownloadHandlerAudioClip)(object)((downloadHandler is DownloadHandlerAudioClip) ? downloadHandler : null); if (val != null) { val.streamAudio = false; } } yield return request.SendWebRequest(); if ((int)request.result != 1) { Log.Error("[AudioBank] Lecture impossible de " + fileName + " : " + request.error); yield break; } AudioClip content = DownloadHandlerAudioClip.GetContent(request); AudioManager instance = AudioManager.Instance; if ((Object)(object)content == (Object)null || instance?.soundBank?.dictionary == null) { Log.Error("[AudioBank] " + fileName + " : son ou banque de sons du jeu indisponible."); yield break; } if (split) { AddSplit(instance, content, name.Substring(0, name.Length - "__split".Length).ToUpperInvariant()); yield break; } string text2 = (((Object)content).name = name.ToUpperInvariant()); instance.soundBank.dictionary[text2] = content; Log.Info("[AudioBank] Son « " + text2 + " » ajouté."); } finally { ((IDisposable)request)?.Dispose(); } } private static void AddSplit(AudioManager audio, AudioClip clip, string baseKey) { int num = Math.Max(1, clip.channels); float[] array = new float[clip.samples * num]; clip.GetData(array, 0); List<int[]> list = DetectSegments(array, num, clip.frequency); if (list.Count == 0) { ((Object)clip).name = baseKey; audio.soundBank.dictionary[baseKey] = clip; Log.Warning("[AudioBank] « " + baseKey + " » : aucun segment, son entier ajouté."); return; } for (int i = 0; i < list.Count; i++) { int num2 = list[i][0]; int num3 = list[i][1] - list[i][0]; float[] array2 = new float[num3 * num]; Array.Copy(array, num2 * num, array2, 0, num3 * num); string text = baseKey + "_" + (i + 1); AudioClip val = AudioClip.Create(text, num3, num, clip.frequency, false); val.SetData(array2, 0); audio.soundBank.dictionary[text] = val; } Log.Info("[AudioBank] « " + baseKey + " » découpé en " + list.Count + " son(s)."); } private static List<int[]> DetectSegments(float[] data, int channels, int frequency) { int num = data.Length / channels; float num2 = 0f; foreach (float num3 in data) { num2 = Mathf.Max(num2, Mathf.Abs(num3)); } float num4 = Mathf.Max(0.02f, num2 * 0.08f); int num5 = Mathf.Max(1, (int)((float)frequency * 0.12f)); int minSegment = Mathf.Max(1, (int)((float)frequency * 0.05f)); int pad = (int)((float)frequency * 0.02f); List<int[]> list = new List<int[]>(); bool flag = false; int start = 0; int num6 = 0; for (int j = 0; j < num; j++) { float num7 = 0f; for (int k = 0; k < channels; k++) { num7 = Mathf.Max(num7, Mathf.Abs(data[j * channels + k])); } if (num7 >= num4) { if (!flag) { flag = true; start = j; } num6 = 0; } else if (flag && ++num6 >= num5) { AddSegment(list, start, j - num6 + 1, num, minSegment, pad); flag = false; } } if (flag) { AddSegment(list, start, num, num, minSegment, pad); } return list; } private static void AddSegment(List<int[]> segments, int start, int end, int frames, int minSegment, int pad) { start = Math.Max(0, start - pad); end = Math.Min(frames, end + pad); if (end - start >= minSegment) { segments.Add(new int[2] { start, end }); } } private static AudioType TypeOf(string path) { return (AudioType)(Path.GetExtension(path).ToLowerInvariant() switch { ".mp3" => 13, ".ogg" => 14, ".wav" => 20, _ => 0, }); } } public static class CandleHooks { private const string InLightKey = "lycans.candles.inLight"; private const string NearestKey = "lycans.candles.nearest"; public static bool InLight(Vector3 point) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) if (AppDomain.CurrentDomain.GetData("lycans.candles.inLight") is Func<Vector3, bool> func) { return func(point); } return false; } public static Vector3? Nearest(Vector3 point) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) if (!(AppDomain.CurrentDomain.GetData("lycans.candles.nearest") is Func<Vector3, Vector3?> func)) { return null; } return func(point); } public static void Publish(Func<Vector3, bool> inLight, Func<Vector3, Vector3?> nearest) { AppDomain.CurrentDomain.SetData("lycans.candles.inLight", inLight); AppDomain.CurrentDomain.SetData("lycans.candles.nearest", nearest); } } public enum CanMoveDecision { NoOpinion, Allow, Deny } public static class CanMoveRules { public const string Method = "PlayerController.IsCanMove"; private const string DecisionKey = "decision"; private static readonly object[] Boxed = new object[3] { 0, 1, 2 }; public static void Decide(int priority, string owner, Func<PlayerController, CanMoveDecision> step) { HookPipeline.Register("PlayerController.IsCanMove", priority, owner, HookPhase.Before, delegate(IDictionary<string, object> data) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown CanMoveDecision canMoveDecision = step((PlayerController)data["player"]); if (canMoveDecision != CanMoveDecision.NoOpinion) { data["decision"] = Boxed[(int)canMoveDecision]; data["cancel"] = HookPipeline.True; } }); } public static IDictionary<string, object> NewData() { return new Dictionary<string, object>(); } public static int Run(IDictionary<string, object> data, PlayerController player) { data["player"] = player; data["decision"] = Boxed[0]; data["cancel"] = HookPipeline.False; HookPipeline.RunBefore("PlayerController.IsCanMove", data); return (int)data["decision"]; } } public static class ChestHooks { private const string ApiKey = "lycans.chests.api"; private const string RefillKey = "lycans.chests.onRefill"; private const string OpenKey = "lycans.chests.beforeOpen"; private static Hashtable Api => AppDomain.CurrentDomain.GetData("lycans.chests.api") as Hashtable; public static int Count { get { if (!(Api?["count"] is Func<int> func)) { return 0; } return func(); } } public static Vector3 Position(int chest) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) if (!(Api?["position"] is Func<int, Vector3> func)) { return Vector3.zero; } return func(chest); } public static Transform Root(int chest) { if (!(Api?["root"] is Func<int, Transform> func)) { return null; } return func(chest); } public static Transform Lid(int chest) { if (!(Api?["lid"] is Func<int, Transform> func)) { return null; } return func(chest); } public static bool IsOpen(int chest) { if (Api?["isOpen"] is Func<int, bool> func) { return func(chest); } return false; } public static bool PutRareLoot(int chest, int slot) { if (Api?["putRare"] is Func<int, int, bool> func) { return func(chest, slot); } return false; } public static void OnRefill(Action<bool> step) { List("lycans.chests.onRefill").Add(step); } public static void BeforeOpen(Func<PlayerController, int, bool> step) { List("lycans.chests.beforeOpen").Add(step); } public static void Publish(Hashtable api) { AppDomain.CurrentDomain.SetData("lycans.chests.api", api); } public static void RaiseRefill(bool night) { object[] array = List("lycans.chests.onRefill").ToArray(); foreach (object obj in array) { try { (obj as Action<bool>)?.Invoke(night); } catch (Exception ex) { Log.Error("[ChestHooks] Abonné au remplissage en erreur : " + ex); } } } public static bool RaiseBeforeOpen(PlayerController player, int chest) { object[] array = List("lycans.chests.beforeOpen").ToArray(); foreach (object obj in array) { try { if (obj is Func<PlayerController, int, bool> func && func(player, chest)) { return true; } } catch (Exception ex) { Log.Error("[ChestHooks] Abonné à l'ouverture en erreur : " + ex); } } return false; } private static ArrayList List(string key) { ArrayList arrayList = AppDomain.CurrentDomain.GetData(key) as ArrayList; if (arrayList == null) { arrayList = new ArrayList(); AppDomain.CurrentDomain.SetData(key, arrayList); } return arrayList; } } public static class CursorControl { private const string CountKey = "lycans.mods.cursor.count"; private const string PreviousKey = "lycans.mods.cursor.previous"; private static readonly object Lock = new object(); private static int Count { get { object data = AppDomain.CurrentDomain.GetData("lycans.mods.cursor.count"); if (data is int) { return (int)data; } return 0; } } public static bool AnyPanelOpen => Count > 0; public static void Request() { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Invalid comparison between Unknown and I4 lock (Lock) { int count = Count; if (count == 0) { AppDomain.CurrentDomain.SetData("lycans.mods.cursor.previous", new bool[2] { Cursor.visible, (int)Cursor.lockState == 1 }); Cursor.lockState = (CursorLockMode)0; Cursor.visible = true; Log.Info("[CursorControl] Curseur libéré (premier panneau ouvert)."); } AppDomain.CurrentDomain.SetData("lycans.mods.cursor.count", count + 1); } } public static void Release() { lock (Lock) { int num = Math.Max(0, Count - 1); AppDomain.CurrentDomain.SetData("lycans.mods.cursor.count", num); if (num == 0) { if (AppDomain.CurrentDomain.GetData("lycans.mods.cursor.previous") is bool[] array && array.Length == 2) { Cursor.visible = array[0]; Cursor.lockState = (CursorLockMode)(array[1] ? 1 : 0); } Log.Info("[CursorControl] Curseur restauré (dernier panneau fermé)."); } } } } public static class CustomAnimations { private const string DefinitionsKey = "lycans.mods.animations.definitions"; private const string AnimatorsKey = "lycans.mods.animations.animators"; private const string PlayKey = "lycans.mods.animations.play"; private const string StopKey = "lycans.mods.animations.stop"; private const string PlayingKey = "lycans.mods.animations.playing"; public static IEnumerable<string> Ids => Definitions().Keys; public static void Define(string id, AnimationClip[] clips, int holdIndex = -1) { if (string.IsNullOrEmpty(id) || clips == null || clips.Length == 0 || Array.IndexOf(clips, null) >= 0) { Log.Warning("[CustomAnimations] « " + id + " » ignorée : clip manquant."); return; } Definitions()[id] = new object[2] { clips, holdIndex }; } public static void Play(PlayerController player, string id) { if ((Object)(object)player != (Object)null && AppDomain.CurrentDomain.GetData("lycans.mods.animations.play") is Action<PlayerController, string> action) { action(player, id); } } public static void Stop(PlayerController player) { if ((Object)(object)player != (Object)null && AppDomain.CurrentDomain.GetData("lycans.mods.animations.stop") is Action<PlayerController> action) { action(player); } } public static bool IsPlaying(PlayerController player) { if ((Object)(object)player != (Object)null && AppDomain.CurrentDomain.GetData("lycans.mods.animations.playing") is Func<PlayerController, bool> func) { return func(player); } return false; } public static void RegisterExtraAnimator(string key, Func<PlayerController, Animator> animator) { Animators()[key] = animator; } public static void PublishImplementation(Action<PlayerController, string> play, Action<PlayerController> stop, Func<PlayerController, bool> playing) { AppDomain.CurrentDomain.SetData("lycans.mods.animations.play", play); AppDomain.CurrentDomain.SetData("lycans.mods.animations.stop", stop); AppDomain.CurrentDomain.SetData("lycans.mods.animations.playing", playing); } public static SortedDictionary<string, object[]> Definitions() { return GetOrCreate<SortedDictionary<string, object[]>>("lycans.mods.animations.definitions"); } public static Dictionary<string, Func<PlayerController, Animator>> Animators() { return GetOrCreate<Dictionary<string, Func<PlayerController, Animator>>>("lycans.mods.animations.animators"); } private static T GetOrCreate<T>(string key) where T : class, new() { if (AppDomain.CurrentDomain.GetData(key) is T result) { return result; } T val = new T(); AppDomain.CurrentDomain.SetData(key, val); return val; } } public static class CustomEffects { private const string DefinitionsKey = "lycans.mods.effects.definitions"; private const string ApplyKey = "lycans.mods.effects.apply"; public static void Define(string key, Type effectType, Func<bool> enabled, Func<float> duration, Action<PlayerController, bool> onDrink = null) { Definitions()[key] = new object[4] { effectType, enabled, duration, onDrink }; } public static void Apply(string key, PlayerController target, float duration) { if ((Object)(object)target != (Object)null && AppDomain.CurrentDomain.GetData("lycans.mods.effects.apply") is Action<string, PlayerController, float> action) { action(key, target, duration); } } public static void PublishApply(Action<string, PlayerController, float> apply) { AppDomain.CurrentDomain.SetData("lycans.mods.effects.apply", apply); } public static SortedDictionary<string, object[]> Definitions() { if (AppDomain.CurrentDomain.GetData("lycans.mods.effects.definitions") is SortedDictionary<string, object[]> result) { return result; } SortedDictionary<string, object[]> sortedDictionary = new SortedDictionary<string, object[]>(StringComparer.Ordinal); AppDomain.CurrentDomain.SetData("lycans.mods.effects.definitions", sortedDictionary); return sortedDictionary; } } public sealed class PotionPoolContext { private readonly IDictionary<string, object> _data; public List<Effect> NativeEffects => (List<Effect>)_data["native"]; internal PotionPoolContext(IDictionary<string, object> data) { _data = data; } } public static class PotionRules { public const string Method = "GameManager.GenerateEffects"; public static void Before(int priority, string owner, Action<PotionPoolContext> step) { HookPipeline.Register("GameManager.GenerateEffects", priority, owner, HookPhase.Before, delegate(IDictionary<string, object> data) { step(new PotionPoolContext(data)); }); } public static IDictionary<string, object> NewData(List<Effect> native) { return new Dictionary<string, object> { ["native"] = native, ["cancel"] = HookPipeline.False }; } } public static class CustomItems { private const string DefinitionsKey = "lycans.mods.items.definitions"; private const string SpawnKey = "lycans.mods.items.spawn"; private const string IconsKey = "lycans.mods.items.icons"; public static void Define(string key, Type itemType, Func<GameObject> visual, float visualScale, Func<bool> enabled) { Definitions()[key] = new object[4] { itemType, visual, visualScale, enabled }; } public static void DefineInfo(string key, Func<Sprite> icon, string nameFr, string nameEn) { Infos()[key] = new object[3] { icon, nameFr, nameEn }; } public static Sprite IconOf(string key) { if (key == null || !Infos().TryGetValue(key, out var value) || !(value[0] is Func<Sprite> func)) { return null; } return func(); } public static string NameOf(string key) { if (key == null || !Infos().TryGetValue(key, out var value)) { return key; } return Translations.Text((string)value[1], (string)value[2]); } private static Dictionary<string, object[]> Infos() { if (AppDomain.CurrentDomain.GetData("lycans.mods.items.icons") is Dictionary<string, object[]> result) { return result; } Dictionary<string, object[]> dictionary = new Dictionary<string, object[]>(); AppDomain.CurrentDomain.SetData("lycans.mods.items.icons", dictionary); return dictionary; } public static Item Spawn(string key, Vector3 position, Quaternion rotation) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) if (!(AppDomain.CurrentDomain.GetData("lycans.mods.items.spawn") is Func<string, Vector3, Quaternion, Item> func)) { return null; } return func(key, position, rotation); } public static string KeyOf(Item item) { if ((Object)(object)item == (Object)null) { return null; } foreach (KeyValuePair<string, object[]> item2 in Definitions()) { if ((Type)item2.Value[0] == ((object)item).GetType()) { return item2.Key; } } return null; } public static void PublishSpawn(Func<string, Vector3, Quaternion, Item> spawn) { AppDomain.CurrentDomain.SetData("lycans.mods.items.spawn", spawn); } public static SortedDictionary<string, object[]> Definitions() { if (AppDomain.CurrentDomain.GetData("lycans.mods.items.definitions") is SortedDictionary<string, object[]> result) { return result; } SortedDictionary<string, object[]> sortedDictionary = new SortedDictionary<string, object[]>(StringComparer.Ordinal); AppDomain.CurrentDomain.SetData("lycans.mods.items.definitions", sortedDictionary); return sortedDictionary; } } public static class DevMode { private const string LoadedDevKey = "lycans.mods.devmode.loaded"; private const string SkippedKey = "lycans.mods.devmode.skipped"; private static bool? _enabled; public static bool Enabled { get { if (_enabled.HasValue) { return _enabled.Value; } _enabled = false; try { string path = Path.Combine(Paths.ConfigPath, "lycans.core.cfg"); if (File.Exists(path)) { string[] array = File.ReadAllLines(path); for (int i = 0; i < array.Length; i++) { string[] array2 = array[i].Split(new char[1] { '=' }); if (array2.Length == 2 && array2[0].Trim() == "ModeDev") { _enabled = array2[1].Trim().Equals("true", StringComparison.OrdinalIgnoreCase); } } } } catch (Exception ex) { Log.Warning("[DevMode] Lecture de lycans.core.cfg impossible : " + ex.Message); } return _enabled.Value; } } public static IReadOnlyCollection<string> Skipped => List("lycans.mods.devmode.skipped"); public static bool IsDevOnly(string status) { if (!(status == "dev")) { return status == "private"; } return true; } public static bool Guard(BaseUnityPlugin plugin, string modName, string status) { KeepAlive(plugin); if (!IsDevOnly(status)) { return true; } if (!Enabled) { List("lycans.mods.devmode.skipped").Add(modName); ((Behaviour)plugin).enabled = false; Log.Info("[DevMode] « " + modName + " » (" + status + ") non chargé : mode DEV désactivé (ModeDev dans lycans.core.cfg)."); return false; } List("lycans.mods.devmode.loaded").Add(modName); return true; } private static void KeepAlive(BaseUnityPlugin plugin) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Invalid comparison between Unknown and I4 if (!((Object)(object)plugin == (Object)null)) { GameObject gameObject = ((Component)plugin).gameObject; if ((int)((Object)gameObject).hideFlags != 61) { ((Object)gameObject).hideFlags = (HideFlags)61; Object.DontDestroyOnLoad((Object)(object)gameObject); } } } public static bool IsLoadedDevMod(string modName) { return List("lycans.mods.devmode.loaded").Contains(modName); } private static HashSet<string> List(string key) { if (AppDomain.CurrentDomain.GetData(key) is HashSet<string> result) { return result; } HashSet<string> hashSet = new HashSet<string>(); AppDomain.CurrentDomain.SetData(key, hashSet); return hashSet; } } public static class Disease { private const string EnabledKey = "lycans.mods.disease.enabled"; private const string InfectKey = "lycans.mods.disease.infect"; private const string CureKey = "lycans.mods.disease.cure"; private const string StageKey = "lycans.mods.disease.stage"; public static bool IsEnabled { get { if (AppDomain.CurrentDomain.GetData("lycans.mods.disease.enabled") is Func<bool> func) { return func(); } return false; } } public static void PublishImplementation(Func<bool> enabled, Action<PlayerController> infect, Action<PlayerController> cure, Func<PlayerController, int> stage) { AppDomain.CurrentDomain.SetData("lycans.mods.disease.enabled", enabled); AppDomain.CurrentDomain.SetData("lycans.mods.disease.infect", infect); AppDomain.CurrentDomain.SetData("lycans.mods.disease.cure", cure); AppDomain.CurrentDomain.SetData("lycans.mods.disease.stage", stage); } public static void Infect(PlayerController player) { if (AppDomain.CurrentDomain.GetData("lycans.mods.disease.infect") is Action<PlayerController> action) { action(player); } } public static void Cure(PlayerController player) { if (AppDomain.CurrentDomain.GetData("lycans.mods.disease.cure") is Action<PlayerController> action) { action(player); } } public static int Stage(PlayerController player) { if (!(AppDomain.CurrentDomain.GetData("lycans.mods.disease.stage") is Func<PlayerController, int> func)) { return 0; } return func(player); } } public static class EventLock { private const string Key = "lycans.events.active"; private const string CycleKey = "lycans.events.cycle"; private const string HookKey = "lycans.events.cyclehook"; private const int ResetPriority = 2; public const string Necromancer = "necromancer"; public const string DemonCar = "demon-car"; public const string WildHunt = "wild-hunt"; public static void Publish(string name, Func<bool> active) { Table()[name] = active; InstallCycleReset(); } public static void MarkStarted(string name) { Cycle()[0] = name; } public static string UsedThisCycle(string self) { string text = Cycle()[0]; if (text == null || !(text != self)) { return null; } return Label(text); } private static string[] Cycle() { string[] array = AppDomain.CurrentDomain.GetData("lycans.events.cycle") as string[]; if (array == null) { array = new string[1]; AppDomain.CurrentDomain.SetData("lycans.events.cycle", array); } return array; } private static void InstallCycleReset() { object data = AppDomain.CurrentDomain.GetData("lycans.events.cyclehook"); bool flag = default(bool); int num; if (data is bool) { flag = (bool)data; num = 1; } else { num = 0; } if (((uint)num & (flag ? 1u : 0u)) != 0) { return; } AppDomain.CurrentDomain.SetData("lycans.events.cyclehook", true); EGameState[] array = new EGameState[3]; RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/); EGameState[] array2 = (EGameState[])(object)array; for (int i = 0; i < array2.Length; i++) { GameStateRules.AfterEnter(array2[i], 2, "EventLock (un événement par cycle)", delegate(StateEnterContext ctx) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Invalid comparison between Unknown and I4 if ((int)ctx.Entered != 2 || (int)ctx.From == 1) { Cycle()[0] = null; } }); } } public static string OtherActive(string self) { foreach (DictionaryEntry item in Table()) { if (!((string)item.Key == self) && item.Value is Func<bool> func) { bool flag; try { flag = func(); } catch { flag = false; } if (flag) { return Label((string)item.Key); } } } return null; } public static string Label(string name) { return name switch { "wild-hunt" => Translations.Text("la Chasse sauvage", "the Wild Hunt"), "demon-car" => Translations.Text("la Ka Maudite", "the Cursed Ka"), "necromancer" => Translations.Text("la Bête", "the Beast"), _ => name, }; } private static Hashtable Table() { Hashtable hashtable = AppDomain.CurrentDomain.GetData("lycans.events.active") as Hashtable; if (hashtable == null) { hashtable = Hashtable.Synchronized(new Hashtable()); AppDomain.CurrentDomain.SetData("lycans.events.active", hashtable); } return hashtable; } } public enum ExtendedRole { Villager, Alchemist, Hunter, Wolf, Porcupines, Knight, Alpha, Snake, LittleGirl, Rat, None, Maire, BigWolf, Chef, Judge, Hermit, Saboteur, Carpenter, Merchant, Necromancer, Beast } public static class ExtendedRoles { public enum SecondaryCamp { Village, Wolves, All } private const string GetKey = "lycans.mods.roles.get"; private const string SetKey = "lycans.mods.roles.set"; private const string SlotCountKey = "lycans.mods.roles.slotcount"; private const string DisplayKey = "lycans.mods.roles.display"; private const string SecondaryGetKey = "lycans.mods.roles.secondary.get"; private const string SecondarySetKey = "lycans.mods.roles.secondary.set"; private const string SecondaryDefsKey = "lycans.mods.roles.secondary.defs"; public static bool IsAvailable => AppDomain.CurrentDomain.GetData("lycans.mods.roles.get") != null; public static int SlotCount { get { object data = AppDomain.CurrentDomain.GetData("lycans.mods.roles.slotcount"); if (data is int) { return (int)data; } return 0; } } public static void PublishImplementation(Func<int, ExtendedRole> get, Action<int, ExtendedRole> set, int slotCount) { AppDomain.CurrentDomain.SetData("lycans.mods.roles.get", (Func<int, int>)((int index) => (int)get(index))); AppDomain.CurrentDomain.SetData("lycans.mods.roles.set", (Action<int, int>)delegate(int index, int role) { set(index, (ExtendedRole)role); }); AppDomain.CurrentDomain.SetData("lycans.mods.roles.slotcount", slotCount); } public static ExtendedRole Get(int playerIndex) { if (AppDomain.CurrentDomain.GetData("lycans.mods.roles.get") is Func<int, int> func) { return (ExtendedRole)func(playerIndex); } return ExtendedRole.None; } public static ExtendedRole Get(PlayerController player) { if (!((Object)(object)player != (Object)null)) { return ExtendedRole.None; } return Get((int)player.Index); } public static void RegisterDisplay(ExtendedRole role, string translationKey, Color color, bool wolfTeam, Func<bool> showMates = null, Func<string> suffix = null) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) Displays()[(int)role] = new object[5] { translationKey, color, wolfTeam, showMates, suffix }; } public static bool TryGetDisplay(ExtendedRole role, out string translationKey, out Color color, out bool wolfTeam, out Func<bool> showMates, out Func<string> suffix) { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_001d: 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) if (Displays().TryGetValue((int)role, out var value)) { translationKey = (string)value[0]; color = (Color)value[1]; wolfTeam = (bool)value[2]; showMates = (Func<bool>)value[3]; suffix = (Func<string>)value[4]; return true; } translationKey = null; color = Color.white; wolfTeam = false; showMates = null; suffix = null; return false; } public static bool IsWolfTeam(PlayerController player) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Invalid comparison between Unknown and I4 if ((Object)(object)player == (Object)null) { return false; } if ((int)player.Role == 1) { return true; } string translationKey; Color color; bool wolfTeam; Func<bool> showMates; Func<string> suffix; return TryGetDisplay(Get(player), out translationKey, out color, out wolfTeam, out showMates, out suffix) && wolfTeam; } private static Dictionary<int, object[]> Displays() { if (AppDomain.CurrentDomain.GetData("lycans.mods.roles.display") is Dictionary<int, object[]> result) { return result; } Dictionary<int, object[]> dictionary = new Dictionary<int, object[]>(); AppDomain.CurrentDomain.SetData("lycans.mods.roles.display", dictionary); return dictionary; } public static void RegisterSecondary(ExtendedRole role, SecondaryCamp camp, Func<bool> enabled) { SecondaryDefinitions()[(int)role] = new object[2] { (int)camp, enabled }; } public static Dictionary<int, object[]> SecondaryDefinitions() { if (AppDomain.CurrentDomain.GetData("lycans.mods.roles.secondary.defs") is Dictionary<int, object[]> result) { return result; } Dictionary<int, object[]> dictionary = new Dictionary<int, object[]>(); AppDomain.CurrentDomain.SetData("lycans.mods.roles.secondary.defs", dictionary); return dictionary; } public static void PublishSecondary(Func<int, int> get, Action<int, int> set) { AppDomain.CurrentDomain.SetData("lycans.mods.roles.secondary.get", get); AppDomain.CurrentDomain.SetData("lycans.mods.roles.secondary.set", set); } public static ExtendedRole GetSecondary(PlayerController player) { if (!((Object)(object)player != (Object)null) || !(AppDomain.CurrentDomain.GetData("lycans.mods.roles.secondary.get") is Func<int, int> func)) { return ExtendedRole.Villager; } return (ExtendedRole)func(player.Index); } public static bool Has(PlayerController player, ExtendedRole role) { if ((Object)(object)player != (Object)null) { if (Get(player) != role) { return GetSecondary(player) == role; } return true; } return false; } public static void SetSecondary(int playerIndex, ExtendedRole role) { if (AppDomain.CurrentDomain.GetData("lycans.mods.roles.secondary.set") is Action<int, int> action) { action(playerIndex, (int)role); } } public static void Set(int playerIndex, ExtendedRole role) { if (AppDomain.CurrentDomain.GetData("lycans.mods.roles.set") is Action<int, int> action) { action(playerIndex, (int)role); } else { Log.Warning("[ExtendedRoles] Set ignoré : mod_roles non chargé."); } } } public static class GamePhases { private static NetworkRunner Runner => ((SimulationBehaviour)(GameManager.Instance?)).Runner; private static bool InPlay { get { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Invalid comparison between Unknown and I4 //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Runner != (Object)null && Runner.IsServer && (Object)(object)GameManager.State != (Object)null && (int)GameManager.State.Current == 2 && (Object)(object)GameManager.LightingManager != (Object)null && !NetworkBool.op_Implicit(GameManager.LightingManager.IsTransition)) { return !NetworkBool.op_Implicit(GameManager.Instance.IsFinished); } return false; } } public static bool CanStartNight { get { //IL_000c: Unknown result type (might be due to invalid IL or missing references) if (InPlay) { return !NetworkBool.op_Implicit(GameManager.LightingManager.IsNight); } return false; } } public static bool CanStartDawn { get { //IL_000c: Unknown result type (might be due to invalid IL or missing references) if (InPlay) { return NetworkBool.op_Implicit(GameManager.LightingManager.IsNight); } return false; } } public static bool CanEndVote { get { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Invalid comparison between Unknown and I4 if ((Object)(object)Runner != (Object)null && Runner.IsServer && (Object)(object)GameManager.State != (Object)null) { return (int)GameManager.State.Current == 4; } return false; } } public static void Transition() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) if (InPlay) { GameManager.Rpc_Transition(Runner); GameManager.LightingManager.IsTransition = NetworkBool.op_Implicit(true); Log.Info("[GamePhases] Transition forcée (" + (NetworkBool.op_Implicit(GameManager.LightingManager.IsNight) ? "aube" : "tombée de la nuit") + ")."); } } public static void StartNight() { if (CanStartNight) { Transition(); } } public static void EndVote() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) if (CanEndVote) { GameManager.Instance.VoteTimer = TickTimer.CreateFromSeconds(Runner, 0.1f); Log.Info("[GamePhases] Fin du vote forcée."); } } } public sealed class StateEnterContext { private readonly IDictionary<string, object> _data; public EGameState Entered => (EGameState)_data["entered"]; public EGameState From => (EGameState)_data["from"]; public bool IsServer => (bool)_data["server"]; public bool IsPlayer => (bool)_data["player"]; public bool Cancel { get { return HookPipeline.IsCancelled(_data); } set { _data["cancel"] = HookPipeline.Box(value); } } internal StateEnterContext(IDictionary<string, object> data) { _data = data; } } public static class GameStateRules { public unsafe static string Method(EGameState state) { return "GameState.Enter." + ((object)(*(EGameState*)(&state))/*cast due to .constrained prefix*/).ToString(); } public static void BeforeEnter(EGameState state, int priority, string owner, Action<StateEnterContext> step) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) HookPipeline.Register(Method(state), priority, owner, HookPhase.Before, delegate(IDictionary<string, object> data) { step(new StateEnterContext(data)); }); } public static void AfterEnter(EGameState state, int priority, string owner, Action<StateEnterContext> step) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) HookPipeline.Register(Method(state), priority, owner, HookPhase.After, delegate(IDictionary<string, object> data) { step(new StateEnterContext(data)); }); } public static void OnRoundStartServer(int priority, string owner, Action step) { AfterEnter((EGameState)2, priority, owner, delegate(StateEnterContext ctx) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Invalid comparison between Unknown and I4 if (ctx.IsServer && (int)ctx.From == 1) { step(); } }); } public static IDictionary<string, object> NewData(EGameState entered, EGameState from, bool isServer, bool isPlayer) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) return new Dictionary<string, object> { ["entered"] = entered, ["from"] = from, ["server"] = HookPipeline.Box(isServer), ["player"] = HookPipeline.Box(isPlayer), ["cancel"] = HookPipeline.False }; } } public static class GhostHooks { private const string RevenantKey = "lycans.ghosts.revenant"; private const string DriverKey = "lycans.ghosts.driver"; public static bool IsRevenant(int playerIndex) { if (AppDomain.CurrentDomain.GetData("lycans.ghosts.revenant") is Func<int, bool> func) { return func(playerIndex); } return false; } public static bool IsDriving(int playerIndex) { if (AppDomain.CurrentDomain.GetData("lycans.ghosts.driver") is Func<int, bool> func) { return func(playerIndex); } return false; } public static void PublishRevenants(Func<int, bool> isRevenant) { AppDomain.CurrentDomain.SetData("lycans.ghosts.revenant", isRevenant); } public static void PublishDriver(Func<int, bool> isDriving) { AppDomain.CurrentDomain.SetData("lycans.ghosts.driver", isDriving); } } public enum HookPhase { Before, After } public static class HookPipeline { public const string CancelKey = "cancel"; public static readonly object True = true; public static readonly object False = false; private const string StepsKey = "lycans.mods.hooks.steps"; private const string ConflictsKey = "lycans.mods.hooks.conflicts"; private const string CacheKey = "lycans.mods.hooks.cache"; private static readonly object Lock = new object(); public static IReadOnlyList<string> ConflictMessages { get { lock (Lock) { return Conflicts().ToArray(); } } } public static void Register(string method, int priority, string owner, HookPhase phase, Action<IDictionary<string, object>> step) { lock (Lock) { Dictionary<string, List<Tuple<int, string, int, Action<IDictionary<string, object>>>>> dictionary = Steps(); if (!dictionary.TryGetValue(method, out var value)) { value = (dictionary[method] = new List<Tuple<int, string, int, Action<IDictionary<string, object>>>>()); } value.RemoveAll((Tuple<int, string, int, Action<IDictionary<string, object>>> s) => s.Item1 == priority && s.Item2 == owner); Tuple<int, string, int, Action<IDictionary<string, object>>> tuple = value.Find((Tuple<int, string, int, Action<IDictionary<string, object>>> s) => s.Item1 == priority); if (tuple != null) { string text = method + " : priorité " + priority + " demandée par « " + owner + " » mais déjà prise par « " + tuple.Item2 + " ». Les deux étapes sont désactivées — change la priorité de l'un des deux mods."; Conflicts().Add(text); Log.Error("[HookPipeline] " + text); } value.Add(Tuple.Create(priority, owner, (int)phase, step)); value.Sort((Tuple<int, string, int, Action<IDictionary<string, object>>> a, Tuple<int, string, int, Action<IDictionary<string, object>>> b) => a.Item1.CompareTo(b.Item1)); Cache().Clear(); } } public static bool RunBefore(string method, IDictionary<string, object> data) { Tuple<int, string, int, Action<IDictionary<string, object>>>[] array = Active(method, HookPhase.Before); foreach (Tuple<int, string, int, Action<IDictionary<string, object>>> tuple in array) { try { tuple.Item4(data); } catch (Exception ex) { Log.Error("[HookPipeline] " + method + " / « " + tuple.Item2 + " » (priorité " + tuple.Item1 + ") en erreur : " + ex); } if (IsCancelled(data)) { return true; } } return false; } public static void RunAfter(string method, IDictionary<string, object> data) { Tuple<int, string, int, Action<IDictionary<string, object>>>[] array = Active(method, HookPhase.After); foreach (Tuple<int, string, int, Action<IDictionary<string, object>>> tuple in array) { try { tuple.Item4(data); } catch (Exception ex) { Log.Error("[HookPipeline] " + method + " / « " + tuple.Item2 + " » (priorité " + tuple.Item1 + ") en erreur : " + ex); } } } public static bool IsCancelled(IDictionary<string, object> data) { bool flag = default(bool); int num; if (data.TryGetValue("cancel", out var value)) { if (value is bool) { flag = (bool)value; num = 1; } else { num = 0; } } else { num = 0; } return (byte)((uint)num & (flag ? 1u : 0u)) != 0; } public static object Box(bool value) { if (!value) { return False; } return True; } public static IReadOnlyList<string> Describe(string method) { lock (Lock) { List<string> list = new List<string>(); if (Steps().TryGetValue(method, out var value)) { foreach (Tuple<int, string, int, Action<IDictionary<string, object>>> item in value) { list.Add(item.Item1 + " · " + item.Item2 + " · " + ((HookPhase)item.Item3/*cast due to .constrained prefix*/).ToString() + (IsDuplicate(value, item.Item1) ? " · CONFLIT (désactivée)" : "")); } } return list; } } private static Tuple<int, string, int, Action<IDictionary<string, object>>>[] Active(string method, HookPhase phase) { lock (Lock) { Dictionary<string, Tuple<int, string, int, Action<IDictionary<string, object>>>[][]> dictionary = Cache(); if (!dictionary.TryGetValue(method, out var value)) { value = (dictionary[method] = new Tuple<int, string, int, Action<IDictionary<string, object>>>[2][]); } if (value[(int)phase] != null) { return value[(int)phase]; } List<Tuple<int, string, int, Action<IDictionary<string, object>>>> list = new List<Tuple<int, string, int, Action<IDictionary<string, object>>>>(); if (Steps().TryGetValue(method, out var value2)) { foreach (Tuple<int, string, int, Action<IDictionary<string, object>>> item in value2) { if (item.Item3 == (int)phase && !IsDuplicate(value2, item.Item1)) { list.Add(item); } } } value[(int)phase] = list.ToArray(); return value[(int)phase]; } } private static bool IsDuplicate(List<Tuple<int, string, int, Action<IDictionary<string, object>>>> list, int priority) { return list.FindAll((Tuple<int, string, int, Action<IDictionary<string, object>>> s) => s.Item1 == priority).Count > 1; } private static Dictionary<string, List<Tuple<int, string, int, Action<IDictionary<string, object>>>>> Steps() { return GetOrCreate<Dictionary<string, List<Tuple<int, string, int, Action<IDictionary<string, object>>>>>>("lycans.mods.hooks.steps"); } private static List<string> Conflicts() { return GetOrCreate<List<string>>("lycans.mods.hooks.conflicts"); } private static Dictionary<string, Tuple<int, string, int, Action<IDictionary<string, object>>>[][]> Cache() { return GetOrCreate<Dictionary<string, Tuple<int, string, int, Action<IDictionary<string, object>>>[][]>>("lycans.mods.hooks.cache"); } private static T GetOrCreate<T>(string key) where T : class, new() { if (AppDomain.CurrentDomain.GetData(key) is T result) { return result; } T val = new T(); AppDomain.CurrentDomain.SetData(key, val); return val; } } public sealed class InteractRayContext { private readonly IDictionary<string, object> _data; public PlayerController Player => (PlayerController)_data["player"]; public float Distance { get { return ((float[])_data["values"])[0]; } set { ((float[])_data["values"])[0] = value; } } public bool IsMeeting => (int)GameManager.LocalGameState == 4; internal InteractRayContext(IDictionary<string, object> data) { _data = data; } } public static class InteractRayRules { public const string Method = "PlayerInteract.Update"; public static void AdjustDistance(int priority, string owner, Action<InteractRayContext> step) { HookPipeline.Register("PlayerInteract.Update", priority, owner, HookPhase.Before, delegate(IDictionary<string, object> data) { step(new InteractRayContext(data)); }); } public static IDictionary<string, object> NewData() { return new Dictionary<string, object> { ["values"] = new float[1] }; } public static void Reset(IDictionary<string, object> data, PlayerController player, float distance) { data["player"] = player; data["cancel"] = HookPipeline.False; ((float[])data["values"])[0] = distance; } } public sealed class InteractContext { private readonly IDictionary<string, object> _data; public PlayerController Player => (PlayerController)_data["player"]; public bool IsPrimary => (bool)_data["primary"]; public GameObject Target => (GameObject)_data["target"]; public PlayerController TargetPlayer { get { if (!((Object)(object)Target != (Object)null)) { return null; } return Target.GetComponentInParent<PlayerController>(); } } public bool Handled { get { return HookPipeline.IsCancelled(_data); } set { _data["cancel"] = HookPipeline.Box(value); } } internal InteractContext(IDictionary<string, object> data) { _data = data; } } public static class InteractRules { public const string Method = "PlayerController.Interact"; public static void Before(int priority, string owner, Action<InteractContext> step) { HookPipeline.Register("PlayerController.Interact", priority, owner, HookPhase.Before, delegate(IDictionary<string, object> data) { step(new InteractContext(data)); }); } public static void After(int priority, string owner, Action<InteractContext> step) { HookPipeline.Register("PlayerController.Interact", priority, owner, HookPhase.After, delegate(IDictionary<string, object> data) { step(new InteractContext(data)); }); } public static IDictionary<string, object> NewData(PlayerController player, bool isPrimary) { return new Dictionary<string, object> { ["player"] = player, ["primary"] = HookPipeline.Box(isPrimary), ["target"] = player._targetObject, ["cancel"] = HookPipeline.False }; } } public sealed class ItemSpawnContext { private readonly IDictionary<string, object> _data; public GameManager Game => (GameManager)_data["game"]; public List<Item> Prefabs => (List<Item>)_data["prefabs"]; public Dictionary<string, Action<Vector3, Quaternion>> CustomItems => (Dictionary<string, Action<Vector3, Quaternion>>)_data["custom"]; public bool BulletsAllowed { get { return (bool)_data["bullets"]; } set { _data["bullets"] = HookPipeline.Box(value); } } internal ItemSpawnContext(IDictionary<string, object> data) { _data = data; } } public static class ItemSpawnRules { public const string Method = "GameManager.SpawnRandomItems"; public static void Before(int priority, string owner, Action<ItemSpawnContext> step) { HookPipeline.Register("GameManager.SpawnRandomItems", priority, owner, HookPhase.Before, delegate(IDictionary<string, object> data) { step(new ItemSpawnContext(data)); }); } public static IDictionary<string, object> NewData(GameManager game) { return new Dictionary<string, object> { ["game"] = game, ["prefabs"] = new List<Item>(game.spawnableItemPrefabs), ["custom"] = new Dictionary<string, Action<Vector3, Quaternion>>(), ["bullets"] = HookPipeline.True, ["cancel"] = HookPipeline.False }; } } public sealed class LightingContext { private readonly IDictionary<string, object> _data; public LightingManager Manager => (LightingManager)_data["manager"]; public float TimeOfDay => Manager._localTimeOfDay; public bool IsNightTime { get { if (!(TimeOfDay >= 18f)) { return TimeOfDay < 6f; } return true; } } public bool IsServer { get { if ((Object)(object)((SimulationBehaviour)Manager).Runner != (Object)null) { return ((SimulationBehaviour)Manager).Runner.IsServer; } return false; } } public bool FlatAmbient { get { return (bool)_data["flat"]; } set { _data["flat"] = HookPipeline.Box(value); } } internal LightingContext(IDictionary<string, object> data) { _data = data; } } public static class LightingRules { public const string UpdateMethod = "LightingManager.UpdateLighting"; public const string NightMethod = "LightingManager.NightChanged"; public const string AmbientMethod = "LightingManager.FlatAmbient"; public static void OnUpdate(int priority, string owner, Action<LightingContext> step) { HookPipeline.Register("LightingManager.UpdateLighting", priority, owner, HookPhase.After, delegate(IDictionary<string, object> data) { step(new LightingContext(data)); }); } public static void OnNightChanged(int priority, string owner, Action<LightingContext> step) { HookPipeline.Register("LightingManager.NightChanged", priority, owner, HookPhase.After, delegate(IDictionary<string, object> data) { step(new LightingContext(data)); }); } public static void ForceFlatAmbient(int priority, string owner, Func<LightingContext, bool> wantsFlat) { HookPipeline.Register("LightingManager.FlatAmbient", priority, owner, HookPhase.After, delegate(IDictionary<string, object> data) { LightingContext lightingContext = new LightingContext(data); if (!lightingContext.FlatAmbient && wantsFlat(lightingContext)) { lightingContext.FlatAmbient = true; } }); } public static IDictionary<string, object> NewData() { return new Dictionary<string, object>(); } public static void Reset(IDictionary<string, object> data, LightingManager manager) { data["manager"] = manager; data["flat"] = HookPipeline.False; data["cancel"] = HookPipeline.False; } } public static class Log { private static ManualLogSource _source; private static readonly Dictionary<string, float> _lastThrottled = new Dictionary<string, float>(); public static void Use(ManualLogSource source) { _source = source; } public static void Info(string message) { if (_source != null) { _source.LogInfo((object)message); } else { Console.WriteLine("[Info] " + message); } } public static void Warning(string message) { if (_source != null) { _source.LogWarning((object)message); } else { Console.WriteLine("[Warning] " + message); } } public static void Error(string message) { if (_source != null) { _source.LogError((object)message); } else { Console.WriteLine("[Error] " + message); } } public static void Throttled(string key, float intervalSeconds, string message) { float unscaledTime = Time.unscaledTime; if (!_lastThrottled.TryGetValue(key, out var value) || !(unscaledTime - value < intervalSeconds)) { _lastThrottled[key] = unscaledTime; Info(message); } } } public static class LootHooks { private const string RefillKey = "lycans.loot.chestsRefill"; public static int RefillChestsNear(Vector3 center, float radius, int chancePercent) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) if (!(AppDomain.CurrentDomain.GetData("lycans.loot.chestsRefill") is Func<Vector3, float, int, int> func)) { return 0; } return func(center, radius, chancePercent); } public static void PublishChests(Func<Vector3, float, int, int> refillNear) { AppDomain.CurrentDomain.SetData("lycans.loot.chestsRefill", refillNear); } } public sealed class LootCollectContext { private readonly IDictionary<string, object> _data; public PlayerController Player => (PlayerController)_data["player"]; public Loot Loot => (Loot)_data["loot"]; public int Score { get { return (int)_data["score"]; } set { _data["score"] = value; } } public int Hunger { get { return (int)_data["hunger"]; } set { _data["hunger"] = value; } } public bool Cancel { get { return HookPipeline.IsCancelled(_data); } set { _data["cancel"] = HookPipeline.Box(value); } } internal LootCollectContext(IDictionary<string, object> data) { _data = data; } } public static class LootRules { public const string Method = "Loot.Rpc_Collect"; public static void Before(int priority, string owner, Action<LootCollectContext> step) { HookPipeline.Register("Loot.Rpc_Collect", priority, owner, HookPhase.Before, delegate(IDictionary<string, object> data) { step(new LootCollectContext(data)); }); } public static void After(int priority, string owner, Action<LootCollectContext> step) { HookPipeline.Register("Loot.Rpc_Collect", priority, owner, HookPhase.After, delegate(IDictionary<string, object> data) { step(new LootCollectContext(data)); }); } public static IDictionary<string, object> NewData(PlayerController player, Loot loot) { return new Dictionary<string, object> { ["player"] = player, ["loot"] = loot, ["score"] = loot.ScoreValue, ["hunger"] = loot.HungerValue, ["cancel"] = HookPipeline.False }; } } public static class ModAssets { private static readonly Dictionary<string, AssetBundle> Bundles = new Dictionary<string, AssetBundle>(); private static readonly Dictionary<string, Sprite> Icons = new Dictionary<string, Sprite>(); public static AssetBundle Bundle(Assembly assembly, string fileName) { if (Bundles.TryGetValue(fileName, out var value) && (Object)(object)value != (Object)null) { return value; } byte[] array = Read(assembly, "LycansBundle." + fileName); if (array == null) { return null; } AssetBundle val = AssetBundle.LoadFromMemory(array); if ((Object)(object)val == (Object)null) { foreach (AssetBundle allLoadedAssetBundle in AssetBundle.GetAllLoadedAssetBundles()) { if ((Object)(object)allLoadedAssetBundle != (Object)null && string.Equals(((Object)allLoadedAssetBundle).name, Path.GetFileNameWithoutExtension(fileName), StringComparison.OrdinalIgnoreCase)) { val = allLoadedAssetBundle; } } } if ((Object)(object)val == (Object)null) { Log.Warning("[ModAssets] Bundle illisible : " + fileName); } Bundles[fileName] = val; return val; } public static GameObject FirstPrefab(Assembly assembly, string fileName) { AssetBundle val = Bundle(assembly, fileName); GameObject[] array = (((Object)(object)val != (Object)null) ? val.LoadAllAssets<GameObject>() : null); if (array == null || array.Length == 0) { return null; } return array[0]; } public static T FirstAsset<T>(Assembly assembly, string fileName) where T : Object { AssetBundle val = Bundle(assembly, fileName); T[] array = (((Object)(object)val != (Object)null) ? val.LoadAllAssets<T>() : null); if (array == null || array.Length == 0) { Log.Warning("[ModAssets] Aucun " + typeof(T).Name + " dans " + fileName); return default(T); } return array[0]; } public static Sprite Icon(Assembly assembly, string fileName) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown //IL_006f: 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) if (Icons.TryGetValue(fileName, out var value) && (Object)(object)value != (Object)null) { return value; } byte[] array = Read(assembly, "LycansIcon." + fileName); if (array == null) { return null; } Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false); if (!ImageConversion.LoadImage(val, array)) { Log.Warning("[ModAssets] Icône illisible : " + fileName); return null; } Sprite val2 = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f)); Icons[fileName] = val2; return val2; } private static byte[] Read(Assembly assembly, string resource) { using Stream stream = assembly.GetManifestResourceStream(resource); if (stream == null) { Log.Warning("[ModAssets] Ressource absente de la DLL : " + resource); return null; } MemoryStream memoryStream = new MemoryStream(); stream.CopyTo(memoryStream); return memoryStream.ToArray(); } } public static class ModConfigPanel { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static hook_Spawned <>9__7_0; internal void <EnsureInstalled>b__7_0(orig_Spawned orig, GameManager self) { orig.Invoke(self); CreateCarrierIfNeeded(); } } private const string HookInstalledKey = "lycans.mods.config.panelhookinstalled"; private const string ReplacedKey = "lycans.mods.config.panelreplaced"; private static readonly object Lock = new object(); private static GameObject _carrier; public static bool Replaced { get { object data = AppDomain.CurrentDomain.GetData("lycans.mods.config.panelreplaced"); bool flag = default(bool); int num; if (data is bool) { flag = (bool)data; num = 1; } else { num = 0; } return (byte)((uint)num & (flag ? 1u : 0u)) != 0; } set { AppDomain.CurrentDomain.SetData("lycans.mods.config.panelreplaced", value); } } public static void EnsureInstalled() { //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Expected O, but got Unknown lock (Lock) { object data = AppDomain.CurrentDomain.GetData("lycans.mods.config.panelhookinstalled"); bool flag = default(bool); int num; if (data is bool) { flag = (bool)data; num = 1; } else { num = 0; } if (((uint)num & (flag ? 1u : 0u)) != 0) { return; } AppDomain.CurrentDomain.SetData("lycans.mods.config.panelhookinstalled", true); object obj = <>c.<>9__7_0; if (obj == null) { hook_Spawned val = delegate(orig_Spawned orig, GameManager self) { orig.Invoke(self); CreateCarrierIfNeeded(); }; <>c.<>9__7_0 = val; obj = (object)val; } GameManager.Spawned += (hook_Spawned)obj; Log.Info("[ModConfigPanel] Hook GameManager.Spawned installé, carrier créé au premier démarrage de partie."); } } private static void CreateCarrierIfNeeded() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown if (!((Object)(object)_carrier != (Object)null)) { _carrier = new GameObject("LycansModConfigPanel"); Object.DontDestroyOnLoad((Object)(object)_carrier); _carrier.AddComponent<ModConfigPanelBehaviour>(); Log.Info("[ModConfigPanel] Carrier créé (" + ((Object)_carrier).name + ")."); } } } internal sealed class ModConfigPanelBehaviour : MonoBehaviour { private const KeyCode ToggleKey = (KeyCode)290; private const string CouncilTabId = "\0council"; private bool _open; private bool _loggedFirstOnGui; private Rect _rect = new Rect(20f, 20f, 560f, 440f); private Vector2 _tabScroll; private Vector2 _contentScroll; private string _search = ""; private string _selectedMod; private static GUIStyle _richLabel; private static GUIStyle RichLabel { get { //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_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown object obj = _richLabel; if (obj == null) { GUIStyle val = new GUIStyle(GUI.skin.label) { richText = true, wordWrap = true }; _richLabel = val; obj = (object)val; } return (GUIStyle)obj; } } private void Awake() { //IL_000a: Unknown result type (might be due to invalid IL or missing references) Log.Info("[ModConfigPanel] Awake : composant créé, en attente de " + ((object)(KeyCode)290/*cast due to .constrained prefix*/).ToString() + "."); } private void OnEnable() { Log.Info("[ModConfigPanel] OnEnable."); } private void OnDisable() { Log.Info("[ModConfigPanel] OnDisable (le composant vient d'être désactivé !)."); } private void OnDestroy() { Log.Info("[ModConfigPanel] OnDestroy (le composant vient d'être détruit !)."); if (_open) { CursorControl.Release(); } } private void Update() { //IL_0078: Unknown result type (might be due to invalid IL or missing references) string reason; bool flag = CanConfigure(out reason); Log.Throttled("modconfigpanel.state", 3f, "[ModConfigPanel] CanConfigure=" + flag + " (" + reason + ")"); if (ModConfigPanel.Replaced) { SetOpen(value: false); return; } if (Input.GetKeyDown((KeyCode)290)) { Log.Info("[ModConfigPanel] " + ((object)(KeyCode)290/*cast due to .constrained prefix*/).ToString() + " détecté (appui). CanConfigure=" + flag + " (" + reason + ")"); if (flag) { SetOpen(!_open); } else { Log.Info("[ModConfigPanel] Touche ignorée : condition non remplie (" + reason + ")."); } } if (!flag) { SetOpen(value: false); } } private void SetOpen(bool value) { if (_open != value) { _open = value; if (value) { CursorControl.Request(); } else { CursorControl.Release(); } } } private static bool CanConfigure(out string reason) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Invalid comparison between Unknown and I4 GameManager instance = GameManager.Instance; if ((Object)(object)instance == (Object)null) { reason = "GameManager.Instance == null (pas en partie ?)"; return false; } if ((Object)(object)((SimulationBehaviour)instance).Runner == (Object)null) { reason = "Runner == null"; return false; } if (!((SimulationBehaviour)instance).Runner.IsRunning) { reason = "Runner.IsRunning == false"; return false; } if ((int)GameManager.LocalGameState != 1) { reason = "état de partie = " + ((object)Unsafe.As<EGameState, EGameState>(ref GameManager.LocalGameState)/*cast due to .constrained prefix*/).ToString() + " (attendu Pregame)"; return false; } reason = "ok"; return true; } private static bool IsHost() { GameManager instance = GameManager.Instance; if (instance == null) { return false; } NetworkRunner runner = ((SimulationBehaviour)instance).Runner; return ((runner != null) ? new bool?(runner.IsServer) : ((bool?)null)) == true; } private void OnGUI() { //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_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Expected O, but got Unknown //IL_0090: 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) if (!_loggedFirstOnGui) { _loggedFirstOnGui = true; Log.Info("[ModConfigPanel] OnGUI appelé pour la première fois (Unity invoque bien ce composant)."); } if (_open) { string text = (IsHost() ? "hôte" : "joueur — tes changements deviennent des propositions"); _rect = GUILayout.Window(113755157, _rect, new WindowFunction(DrawWindow), "Configuration des mods · " + text + " (" + ((object)(KeyCode)290/*cast due to .constrained prefix*/).ToString() + " pour fermer)", Array.Empty<GUILayoutOption>()); } } private void DrawWindow(int id) { //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_0208: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) IReadOnlyList<ModConfigSection> sections = ModConfigRegistry.Sections; IReadOnlyList<string> conflictMessages = HookPipeline.ConflictMessages; if (conflictMessages.Count > 0) { Color color = GUI.color; GUI.color = new Color(1f, 0.35f, 0.35f); foreach (string item in conflictMessages) { GUILayout.Label("ERREUR — " + item, Array.Empty<GUILayoutOption>()); } GUI.color = color; GUILayout.Space(6f); } GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.BeginVertical((GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(170f) }); GUILayout.Label("Recherche", Array.Empty<GUILayoutOption>()); _search = GUILayout.TextField(_search, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(160f) }); GUILayout.Space(6f); _tabScroll = GUILayout.BeginScrollView(_tabScroll, (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width(170f), GUILayout.Height(330f) }); string text = _search.Trim().ToLowerInvariant(); foreach (ModConfigSection item2 in sections) { if (text.Length <= 0 || item2.ModName.ToLowerInvariant().IndexOf(text, StringComparison.Ordinal) >= 0) { DrawTabButton(item2.ModName, item2.ModName); } } GUILayout.EndScrollView(); GUILayout.Space(6f); DrawTabButton("\0council", "Conseil"); GUILayout.EndVertical(); GUILayout.Space(10f); GUILayout.BeginVertical(Array.Empty<GUILayoutOption>()); _contentScroll = GUILayout.BeginScrollView(_contentScroll, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(380f) }); DrawSelectedContent(sections); GUILayout.EndScrollView(); GUILayout.EndVertical(); GUILayout.EndHorizontal(); GUI.DragWindow(new Rect(0f, 0f, 10000f, 20f)); } private void DrawTabButton(string id, string label) { bool flag = _selectedMod == id; if (GUILayout.Toggle(flag, label, GUIStyle.op_Implicit("Button"), Array.Empty<GUILayoutOption>())) { _selectedMod = id; } else if (flag) { _selectedMod = null; } } private void DrawSelectedContent(IReadOnlyList<ModConfigSection> sections) { if (_selectedMod == null) { GUILayout.Label("Choisis un mod à gauche (ou cherche son nom).", Array.Empty<GUILayoutOption>()); return; } if (_selectedMod == "\0council") { DrawCouncil(); return; } ModConfigSection modConfigSection = null; foreach (ModConfigSection section in sections) { if (section.ModName == _selectedMod) { modConfigSection = section; break; } } if (modConfigSection == null) { GUILayout.Label("Ce mod n'est plus chargé.", Array.Empty<GUILayoutOption>()); return; } bool flag = modConfigSection.GetEnabled(); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); bool flag2 = GUILayout.Toggle(flag, "", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(20f) }); GUILayout.Label("<b>" + modConfigSection.ModName + "</b>", RichLabel, Array.Empty<GUILayoutOption>()); GUILayout.EndHorizontal(); if (flag2 != flag) { modConfigSection.SetEnabled?.Invoke(flag2); } if (!flag2) { GUILayout.Label("Mod désactivé.", Array.Empty<GUILayoutOption>()); return; } if (!IsHost()) { GUILayout.Label("Tu n'es pas l'hôte : tes changements ci-dessous deviennent des propositions envoyées au Conseil (onglet à gauche).", RichLabel, Array.Empty<GUILayoutOption>()); GUILayout.Space(6f); } GUILayout.Space(8f); foreach (ModConfigField field in modConfigSection.Fields) { DrawField(modConfigSection.ModName, field); } } private static void DrawField(string modName, ModConfigField field) { GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.Space(20f); GUILayout.Label(field.Label, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(150f) }); object obj = field.Get(); float oldValueRaw = ToRaw(field.Type, obj); object obj2 = obj; switch (field.Type) { case ModConfigFieldType.Bool: obj2 = GUILayout.Toggle((bool)obj, "", Array.Empty<GUILayoutOption>()); break; case ModConfigFieldType.Int: { float num3 = GUILayout.HorizontalSlider((float)(int)obj, field.Min, field.Max, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(120f) }); GUILayout.Label(((int)num3).ToString(), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(32f) }); obj2 = (int)num3; break; } case ModConfigFieldType.Float: { float num2 = GUILayout.HorizontalSlider((float)obj, field.Min, field.Max, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(120f) }); GUILayout.Label(num2.ToString("0.0"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(40f) }); obj2 = num2; break; } case ModConfigFieldType.Choice: { string[] options = field.Options; int num = ((options == null) ? 1 : options.Length); if (GUILayout.Button(field.Format((int)obj), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(160f) })) { obj2 = ((int)obj + 1) % num; } break; } } GUILayout.EndHorizontal(); if (!object.Equals(obj2, obj)) { if (IsHost()) { field.Set(obj2); return; } float newValueRaw = ToRaw(field.Type, obj2); ModProposals.Submit(modName, field.Label, oldValueRaw, newValueRaw); Log.Info("[ModConfigPanel] Proposition envoyée : " + modName + " / " + field.Label); } } private static float ToRaw(ModConfigFieldType type, object value) { return type switch { ModConfigFieldType.Bool => ((bool)value) ? 1f : 0f, ModConfigFieldType.Int => (int)value, ModConfigFieldType.Choice => (int)value, ModConfigFieldType.Float => (float)value, _ => 0f, }; } private void DrawCouncil() { //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) GUILayout.Label("<b>Conseil</b>", RichLabel, Array.Empty<GUILayoutOption>()); GUILayout.Space(6f); if (!ModProposals.IsAvailable) { GUILayout.Label("Indisponible : le mod « Lycans Council » n'est pas chargé.", Array.Empty<GUILayoutOption>()); return; } IReadOnlyList<ProposalSlot> readOnlyList = ModProposals.List(); if (readOnlyList.Count == 0) { GUILayout.Label("Aucune proposition en cours.", Array.Empty<GUILayoutOption>()); return; } bool isHost = IsHost(); int num; if (!((Object)(object)PlayerController.Local != (Object)null)) { num = -1; } else { PlayerRef val = PlayerController.Local.Ref; num = ((PlayerRef)(ref val)).PlayerId; } int localPlayerId = num; foreach (ProposalSlot item in readOnlyList) { DrawProposal(item, isHost, localPlayerId); } } private static void DrawProposal(ProposalSlot slot, bool isHost, int localPlayerId) { GUILayout.BeginVertical(GUIStyle.op_Implicit("Box"), Array.Empty<GUILayoutOption>()); GUILayout.Label("<b>" + slot.ModName + " / " + sl