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 Microsoft.CodeAnalysis; using On; using UnityEngine; using UnityEngine.Localization; using UnityEngine.Localization.Settings; using UnityEngine.Localization.Tables; using UnityEngine.Networking; [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.WolfHarvest")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("LycansMod.WolfHarvest")] [assembly: AssemblyTitle("LycansMod.WolfHarvest")] [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 ActionRequests { private const string HandlersKey = "lycans.mods.actions.handlers"; private const string SendKey = "lycans.mods.actions.send"; public static void Register(string action, Action 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 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)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 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> Handlers() { if (AppDomain.CurrentDomain.GetData("lycans.mods.actions.handlers") is Dictionary> result) { return result; } Dictionary> dictionary = new Dictionary>(); 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 available = null) { List list = All(); lock (list) { list.Add(new object[4] { category, label, run, available }); } } public static List All() { if (AppDomain.CurrentDomain.GetData("lycans.mods.admin.commands") is List result) { return result; } List list = new List(); AppDomain.CurrentDomain.SetData("lycans.mods.admin.commands", list); return list; } } 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 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 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 text2; try { string text = Path.Combine(Path.GetTempPath(), "LycansModsAudio"); Directory.CreateDirectory(text); text2 = Path.Combine(text, fileName); using Stream stream = _assembly.GetManifestResourceStream(resource); using FileStream destination = File.Create(text2); 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://" + text2.Replace("\\", "/"), TypeOf(text2)); 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 text3 = (((Object)content).name = name.ToUpperInvariant()); instance.soundBank.dictionary[text3] = content; Log.Info("[AudioBank] Son « " + text3 + " » 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 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 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 list = new List(); 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 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 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 step) { HookPipeline.Register("PlayerController.IsCanMove", priority, owner, HookPhase.Before, delegate(IDictionary 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 NewData() { return new Dictionary(); } public static int Run(IDictionary 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 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 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 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 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 action) { action(player); } } public static bool IsPlaying(PlayerController player) { if ((Object)(object)player != (Object)null && AppDomain.CurrentDomain.GetData("lycans.mods.animations.playing") is Func func) { return func(player); } return false; } public static void RegisterExtraAnimator(string key, Func animator) { Animators()[key] = animator; } public static void PublishImplementation(Action play, Action stop, Func 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 Definitions() { return GetOrCreate>("lycans.mods.animations.definitions"); } public static Dictionary> Animators() { return GetOrCreate>>("lycans.mods.animations.animators"); } private static T GetOrCreate(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 enabled, Func duration, Action 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 action) { action(key, target, duration); } } public static void PublishApply(Action apply) { AppDomain.CurrentDomain.SetData("lycans.mods.effects.apply", apply); } public static SortedDictionary Definitions() { if (AppDomain.CurrentDomain.GetData("lycans.mods.effects.definitions") is SortedDictionary result) { return result; } SortedDictionary sortedDictionary = new SortedDictionary(StringComparer.Ordinal); AppDomain.CurrentDomain.SetData("lycans.mods.effects.definitions", sortedDictionary); return sortedDictionary; } } public sealed class PotionPoolContext { private readonly IDictionary _data; public List NativeEffects => (List)_data["native"]; internal PotionPoolContext(IDictionary data) { _data = data; } } public static class PotionRules { public const string Method = "GameManager.GenerateEffects"; public static void Before(int priority, string owner, Action step) { HookPipeline.Register("GameManager.GenerateEffects", priority, owner, HookPhase.Before, delegate(IDictionary data) { step(new PotionPoolContext(data)); }); } public static IDictionary NewData(List native) { return new Dictionary { ["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"; public static void Define(string key, Type itemType, Func visual, float visualScale, Func enabled) { Definitions()[key] = new object[4] { itemType, visual, visualScale, enabled }; } 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 func)) { return null; } return func(key, position, rotation); } public static string KeyOf(Item item) { if ((Object)(object)item == (Object)null) { return null; } foreach (KeyValuePair item2 in Definitions()) { if ((Type)item2.Value[0] == ((object)item).GetType()) { return item2.Key; } } return null; } public static void PublishSpawn(Func spawn) { AppDomain.CurrentDomain.SetData("lycans.mods.items.spawn", spawn); } public static SortedDictionary Definitions() { if (AppDomain.CurrentDomain.GetData("lycans.mods.items.definitions") is SortedDictionary result) { return result; } SortedDictionary sortedDictionary = new SortedDictionary(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 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 List(string key) { if (AppDomain.CurrentDomain.GetData(key) is HashSet result) { return result; } HashSet hashSet = new HashSet(); 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 func) { return func(); } return false; } } public static void PublishImplementation(Func enabled, Action infect, Action cure, Func 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 action) { action(player); } } public static void Cure(PlayerController player) { if (AppDomain.CurrentDomain.GetData("lycans.mods.disease.cure") is Action action) { action(player); } } public static int Stage(PlayerController player) { if (!(AppDomain.CurrentDomain.GetData("lycans.mods.disease.stage") is Func func)) { return 0; } return func(player); } } public enum ExtendedRole { Villager, Alchemist, Hunter, Wolf, Porcupines, Knight, Alpha, Snake, LittleGirl, Rat, None, Maire, BigWolf, Chef } public static class ExtendedRoles { 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"; 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 get, Action set, int slotCount) { AppDomain.CurrentDomain.SetData("lycans.mods.roles.get", (Func)((int index) => (int)get(index))); AppDomain.CurrentDomain.SetData("lycans.mods.roles.set", (Action)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 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 showMates = null, Func 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 showMates, out Func 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)value[3]; suffix = (Func)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 showMates; Func suffix; return TryGetDisplay(Get(player), out translationKey, out color, out wolfTeam, out showMates, out suffix) && wolfTeam; } private static Dictionary Displays() { if (AppDomain.CurrentDomain.GetData("lycans.mods.roles.display") is Dictionary result) { return result; } Dictionary dictionary = new Dictionary(); AppDomain.CurrentDomain.SetData("lycans.mods.roles.display", dictionary); return dictionary; } public static void Set(int playerIndex, ExtendedRole role) { if (AppDomain.CurrentDomain.GetData("lycans.mods.roles.set") is Action 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 _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 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 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 data) { step(new StateEnterContext(data)); }); } public static void AfterEnter(EGameState state, int priority, string owner, Action 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 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 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 { ["entered"] = entered, ["from"] = from, ["server"] = HookPipeline.Box(isServer), ["player"] = HookPipeline.Box(isPlayer), ["cancel"] = HookPipeline.False }; } } 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 ConflictMessages { get { lock (Lock) { return Conflicts().ToArray(); } } } public static void Register(string method, int priority, string owner, HookPhase phase, Action> step) { lock (Lock) { Dictionary>>>> dictionary = Steps(); if (!dictionary.TryGetValue(method, out var value)) { value = (dictionary[method] = new List>>>()); } value.RemoveAll((Tuple>> s) => s.Item1 == priority && s.Item2 == owner); Tuple>> tuple = value.Find((Tuple>> 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>> a, Tuple>> b) => a.Item1.CompareTo(b.Item1)); Cache().Clear(); } } public static bool RunBefore(string method, IDictionary data) { Tuple>>[] array = Active(method, HookPhase.Before); foreach (Tuple>> 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 data) { Tuple>>[] array = Active(method, HookPhase.After); foreach (Tuple>> 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 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 Describe(string method) { lock (Lock) { List list = new List(); if (Steps().TryGetValue(method, out var value)) { foreach (Tuple>> 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>>[] Active(string method, HookPhase phase) { lock (Lock) { Dictionary>>[][]> dictionary = Cache(); if (!dictionary.TryGetValue(method, out var value)) { value = (dictionary[method] = new Tuple>>[2][]); } if (value[(int)phase] != null) { return value[(int)phase]; } List>>> list = new List>>>(); if (Steps().TryGetValue(method, out var value2)) { foreach (Tuple>> 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>>> list, int priority) { return list.FindAll((Tuple>> s) => s.Item1 == priority).Count > 1; } private static Dictionary>>>> Steps() { return GetOrCreate>>>>>("lycans.mods.hooks.steps"); } private static List Conflicts() { return GetOrCreate>("lycans.mods.hooks.conflicts"); } private static Dictionary>>[][]> Cache() { return GetOrCreate>>[][]>>("lycans.mods.hooks.cache"); } private static T GetOrCreate(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 _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 data) { _data = data; } } public static class InteractRayRules { public const string Method = "PlayerInteract.Update"; public static void AdjustDistance(int priority, string owner, Action step) { HookPipeline.Register("PlayerInteract.Update", priority, owner, HookPhase.Before, delegate(IDictionary data) { step(new InteractRayContext(data)); }); } public static IDictionary NewData() { return new Dictionary { ["values"] = new float[1] }; } public static void Reset(IDictionary data, PlayerController player, float distance) { data["player"] = player; data["cancel"] = HookPipeline.False; ((float[])data["values"])[0] = distance; } } public sealed class InteractContext { private readonly IDictionary _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(); } } public bool Handled { get { return HookPipeline.IsCancelled(_data); } set { _data["cancel"] = HookPipeline.Box(value); } } internal InteractContext(IDictionary data) { _data = data; } } public static class InteractRules { public const string Method = "PlayerController.Interact"; public static void Before(int priority, string owner, Action step) { HookPipeline.Register("PlayerController.Interact", priority, owner, HookPhase.Before, delegate(IDictionary data) { step(new InteractContext(data)); }); } public static void After(int priority, string owner, Action step) { HookPipeline.Register("PlayerController.Interact", priority, owner, HookPhase.After, delegate(IDictionary data) { step(new InteractContext(data)); }); } public static IDictionary NewData(PlayerController player, bool isPrimary) { return new Dictionary { ["player"] = player, ["primary"] = HookPipeline.Box(isPrimary), ["target"] = player._targetObject, ["cancel"] = HookPipeline.False }; } } public sealed class ItemSpawnContext { private readonly IDictionary _data; public GameManager Game => (GameManager)_data["game"]; public List Prefabs => (List)_data["prefabs"]; public Dictionary> CustomItems => (Dictionary>)_data["custom"]; public bool BulletsAllowed { get { return (bool)_data["bullets"]; } set { _data["bullets"] = HookPipeline.Box(value); } } internal ItemSpawnContext(IDictionary data) { _data = data; } } public static class ItemSpawnRules { public const string Method = "GameManager.SpawnRandomItems"; public static void Before(int priority, string owner, Action step) { HookPipeline.Register("GameManager.SpawnRandomItems", priority, owner, HookPhase.Before, delegate(IDictionary data) { step(new ItemSpawnContext(data)); }); } public static IDictionary NewData(GameManager game) { return new Dictionary { ["game"] = game, ["prefabs"] = new List(game.spawnableItemPrefabs), ["custom"] = new Dictionary>(), ["bullets"] = HookPipeline.True, ["cancel"] = HookPipeline.False }; } } public sealed class LightingContext { private readonly IDictionary _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 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 step) { HookPipeline.Register("LightingManager.UpdateLighting", priority, owner, HookPhase.After, delegate(IDictionary data) { step(new LightingContext(data)); }); } public static void OnNightChanged(int priority, string owner, Action step) { HookPipeline.Register("LightingManager.NightChanged", priority, owner, HookPhase.After, delegate(IDictionary data) { step(new LightingContext(data)); }); } public static void ForceFlatAmbient(int priority, string owner, Func wantsFlat) { HookPipeline.Register("LightingManager.FlatAmbient", priority, owner, HookPhase.After, delegate(IDictionary data) { LightingContext lightingContext = new LightingContext(data); if (!lightingContext.FlatAmbient && wantsFlat(lightingContext)) { lightingContext.FlatAmbient = true; } }); } public static IDictionary NewData() { return new Dictionary(); } public static void Reset(IDictionary 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 _lastThrottled = new Dictionary(); 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 sealed class LootCollectContext { private readonly IDictionary _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 data) { _data = data; } } public static class LootRules { public const string Method = "Loot.Rpc_Collect"; public static void Before(int priority, string owner, Action step) { HookPipeline.Register("Loot.Rpc_Collect", priority, owner, HookPhase.Before, delegate(IDictionary data) { step(new LootCollectContext(data)); }); } public static void After(int priority, string owner, Action step) { HookPipeline.Register("Loot.Rpc_Collect", priority, owner, HookPhase.After, delegate(IDictionary data) { step(new LootCollectContext(data)); }); } public static IDictionary NewData(PlayerController player, Loot loot) { return new Dictionary { ["player"] = player, ["loot"] = loot, ["score"] = loot.ScoreValue, ["hunger"] = loot.HungerValue, ["cancel"] = HookPipeline.False }; } } public static class ModAssets { private static readonly Dictionary Bundles = new Dictionary(); private static readonly Dictionary Icons = new Dictionary(); 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() : null); if (array == null || array.Length == 0) { return null; } return array[0]; } public static T FirstAsset(Assembly assembly, string fileName) where T : Object { AssetBundle val = Bundle(assembly, fileName); T[] array = (((Object)(object)val != (Object)null) ? val.LoadAllAssets() : 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 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(); 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(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()); } } 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 sections = ModConfigRegistry.Sections; IReadOnlyList 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()); } GUI.color = color; GUILayout.Space(6f); } GUILayout.BeginHorizontal(Array.Empty()); GUILayout.BeginVertical((GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(170f) }); GUILayout.Label("Recherche", Array.Empty()); _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()); _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())) { _selectedMod = id; } else if (flag) { _selectedMod = null; } } private void DrawSelectedContent(IReadOnlyList sections) { if (_selectedMod == null) { GUILayout.Label("Choisis un mod à gauche (ou cherche son nom).", Array.Empty()); 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()); return; } bool flag = modConfigSection.GetEnabled(); GUILayout.BeginHorizontal(Array.Empty()); bool flag2 = GUILayout.Toggle(flag, "", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(20f) }); GUILayout.Label("" + modConfigSection.ModName + "", RichLabel, Array.Empty()); GUILayout.EndHorizontal(); if (flag2 != flag) { modConfigSection.SetEnabled?.Invoke(flag2); } if (!flag2) { GUILayout.Label("Mod désactivé.", Array.Empty()); 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()); 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()); 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()); 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("Conseil", RichLabel, Array.Empty()); GUILayout.Space(6f); if (!ModProposals.IsAvailable) { GUILayout.Label("Indisponible : le mod « Lycans Council » n'est pas chargé.", Array.Empty()); return; } IReadOnlyList readOnlyList = ModProposals.List(); if (readOnlyList.Count == 0) { GUILayout.Label("Aucune proposition en cours.", Array.Empty()); 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()); GUILayout.Label("" + slot.ModName + " / " + slot.FieldLabel + " — " + DescribeStatus(slot.Status), RichLabel, Array.Empty()); string[] obj = new string[6] { "Proposé par le joueur #", null, null, null, null, null }; int authorPlayerId = slot.AuthorPlayerId; obj[1] = authorPlayerId.ToString(); obj[2] = " : "; float oldValueRaw = slot.OldValueRaw; obj[3] = oldValueRaw.ToString("0.##"); obj[4] = " → "; oldValueRaw = slot.NewValueRaw; obj[5] = oldValueRaw.ToString("0.##"); GUILayout.Label(string.Concat(obj), Array.Empty()); switch (slot.Status) { case ProposalStatus.PendingHost: if (isHost) { GUILayout.BeginHorizontal(Array.Empty()); if (GUILayout.Button("Ouvrir le vote", Array.Empty())) { ModProposals.HostDecide(slot.Index, approve: true); } if (GUILayout.Button("Rejeter", Array.Empty())) { ModProposals.HostDecide(slot.Index, approve: false); } GUILayout.EndHorizontal(); } else { GUILayout.Label("En attente de l'hôte.", Array.Empty()); } break; case ProposalStatus.Voting: { string[] obj2 = new string[5] { "Votes : ", null, null, null, null }; authorPlayerId = slot.VotesFor; obj2[1] = authorPlayerId.ToString(); obj2[2] = " pour / "; authorPlayerId = slot.VotesAgainst; obj2[3] = authorPlayerId.ToString(); obj2[4] = " contre"; GUILayout.Label(string.Concat(obj2), Array.Empty()); GUILayout.BeginHorizontal(Array.Empty()); if (localPlayerId >= 0) { if (GUILayout.Button("Voter pour", Array.Empty())) { ModProposals.Vote(slot.Index, voteFor: true); } if (GUILayout.Button("Voter contre", Array.Empty())) { ModProposals.Vote(slot.Index, voteFor: false); } } if (isHost && GUILayout.Button("Clôturer le vote", Array.Empty())) { ModProposals.HostCloseVote(slot.Index); } GUILayout.EndHorizontal(); break; } case ProposalStatus.Accepted: GUILayout.Label("Acceptée — en cours d'application.", Array.Empty()); break; case ProposalStatus.Rejected: GUILayout.Label("Rejetée.", Array.Empty()); break; } GUILayout.EndVertical(); GUILayout.Space(6f); } private static string DescribeStatus(ProposalStatus status) { return status switch { ProposalStatus.PendingHost => "en attente de l'hôte", ProposalStatus.Voting => "au vote", ProposalStatus.Accepted => "acceptée", ProposalStatus.Rejected => "rejetée", _ => status.ToString(), }; } } public enum ModConfigFieldType { Bool, Int, Float, Choice } public static class ModChapters { public const string Roles = "roles"; public const string Potions = "potions"; public const string Items = "items"; public const string World = "world"; public const string Rules = "rules"; public const string Players = "players"; public const string NativeGroup = "native"; public static readonly string[] All = new string[6] { "roles", "potions", "items", "world", "rules", "players" }; } public sealed class ModConfigField { private readonly object[] _raw; public string Label => (string)_raw[0]; public ModConfigFieldType Type => (ModConfigFieldType)(int)_raw[1]; public Func Get => (Func)_raw[2]; public Action Set => (Action)_raw[3]; public float Min => (float)_raw[4]; public float Max => (float)_raw[5]; public string Description { get { if (_raw.Length <= 6) { return null; } return _raw[6] as string; } } public string[] Options { get { if (_raw.Length <= 7) { return null; } return _raw[7] as string[]; } } internal ModConfigField(object[] raw) { _raw = raw; } public float GetRaw() { object obj = Get(); switch (Type) { case ModConfigFieldType.Bool: if (!(bool)obj) { return 0f; } return 1f; case ModConfigFieldType.Int: case ModConfigFieldType.Choice: return (int)obj; default: return (float)obj; } } public void SetRaw(float raw) { switch (Type) { case ModConfigFieldType.Bool: Set(raw != 0f); break; case ModConfigFieldType.Int: case ModConfigFieldType.Choice: Set((int)Math.Round(raw)); break; default: Set(raw); break; } } public string Format(float raw) { switch (Type) { case ModConfigFieldType.Bool: if (raw == 0f) { return Translations.Text("Non", "No", "Nein", "No", "Hayır", "No"); } return Translations.Text("Oui", "Yes", "Ja", "Sí", "Evet", "Sì"); case ModConfigFieldType.Int: return ((int)Math.Round(raw)).ToString(); case ModConfigFieldType.Choice: { int num = (int)Math.Round(raw); string[] options = Options; if (options == null || num < 0 || num >= options.Length) { return num.ToString(); } return options[num]; } default: return raw.ToString("0.##"); } } } public sealed class ModConfigSection { private readonly object[] _raw; public string ModName => (string)_raw[0]; public Func GetEnabled => (Func)_raw[1]; public Action SetEnabled => (Action)_raw[2]; private List RawFields => (List)_raw[3]; public string ChapterId => (_raw[4] as string) ?? "rules"; public string Description => _raw[5] as string; public string WikiText { get { if (_raw.Length <= 6 || !(_raw[6] is string[] array)) { return null; } return Translations.Text(array[0], array[1], array[2], array[3], array[4], array[5]); } } public string Group { get { if (_raw.Length <= 7) { return null; } return _raw[7] as string; } } public string RoleKey { get { if (_raw.Length <= 8) { return null; } return _raw[8] as string; } } public bool IsInfo { get { bool flag = default(bool); int num; if (_raw.Length > 9) { object obj = _raw[9]; if (obj is bool) { flag = (bool)obj; num = 1; } else { num = 0; } } else { num = 0; } return (byte)((uint)num & (flag ? 1u : 0u)) != 0; } } public string DisplayName { get { if (!ModName.StartsWith("Lycans ", StringComparison.Ordinal)) { return ModName; } return ModName.Substring(7); } } public IReadOnlyList Fields => RawFields.Select((object[] f) => new ModConfigField(f)).ToArray(); internal ModConfigSection(object[] raw) { _raw = raw; } public ModConfigSection ForRole(string roleKey) { _raw[8] = roleKey; return this; } public ModConfigSection InGroup(string group) { _raw[7] = group; return this; } public ModConfigSection Chapter(string chapterId, string description = null) { _raw[4] = chapterId; _raw[5] = description; return this; } public ModConfigSection Wiki(string fr, string en = null, string de = null, string es = null, string tr = null, string it = null) { _raw[6] = new string[6] { fr, en, de, es, tr, it }; return this; } public ModConfigSection AddBool(string label, Func get, Action set, string description = null) { return Add(label, ModConfigFieldType.Bool, () => get(), delegate(object v) { set((bool)v); }, 0f, 1f, description, null); } public ModConfigSection AddInt(string label, Func get, Action set, int min, int max, string description = null) { return Add(label, ModConfigFieldType.Int, () => get(), delegate(object v) { set((int)v); }, min, max, description, null); } public ModConfigSection AddFloat(string label, Func get, Action set, float min, float max, string description = null) { return Add(label, ModConfigFieldType.Float, () => get(), delegate(object v) { set((float)v); }, min, max, description, null); } public ModConfigSection AddChoice(string label, string[] options, Func get, Action set, string description = null) { return Add(label, ModConfigFieldType.Choice, () => get(), delegate(object v) { set((int)v); }, 0f, options.Length - 1, description, options); } private ModConfigSection Add(string label, ModConfigFieldType type, Func get, Action set, float min, float max, string description, string[] options) { RawFields.Add(new object[8] { label, (int)type, get, set, min, max, description, options }); return this; } } public static class ModConfigRegistry { private const string SectionsKey = "lycans.mods.config.sections.v2"; private static readonly object Lock = new object(); public static IReadOnlyList Sections { get { lock (Lock) { return (from s in GetOrCreate() orderby (string)s[0] select new ModConfigSection(s)).ToArray(); } } } public static ModConfigSection RegisterMod(string modName, Func getEnabled, Action setEnabled) { lock (Lock) { List orCreate = GetOrCreate(); object[] array = orCreate.FirstOrDefault((object[] s) => (string)s[0] == modName); if (array != null) { return new ModConfigSection(array); } object[] array2 = new object[10] { modName, getEnabled, setEnabled, new List(), null, null, null, null, null, false }; orCreate.Add(array2); return new ModConfigSection(array2); } } public static ModConfigSection RegisterInfo(string name) { ModConfigSection result = RegisterMod(name, () => true, null); lock (Lock) { GetOrCreate().First((object[] s) => (string)s[0] == name)[9] = true; return result; } } private static List GetOrCreate() { if (AppDomain.CurrentDomain.GetData("lycans.mods.config.sections.v2") is List result) { return result; } List list = new List(); AppDomain.CurrentDomain.SetData("lycans.mods.config.sections.v2", list); return list; } } public static class ModFiles { private static readonly Dictionary Cache = new Dictionary(); public static string ModDirectory => Path.GetDirectoryName(typeof(ModFiles).Assembly.Location) ?? Paths.PluginPath; public static string Resolve(string relativePath) { if (Path.IsPathRooted(relativePath)) { if (!File.Exists(relativePath)) { return null; } return relativePath; } if (Cache.TryGetValue(relativePath, out var value) && File.Exists(value)) { return value; } foreach (string item in Roots()) { string path = Path.Combine(item, relativePath); if (File.Exists(path)) { return Cache[relativePath] = Path.GetFullPath(path); } } return null; } private static IEnumerable Roots() { yield return ModDirectory; yield return Paths.PluginPath; string[] array; try { array = Directory.GetDirectories(Paths.PluginPath); } catch (Exception) { array = new string[0]; } string[] array2 = array; for (int i = 0; i < array2.Length; i++) { yield return array2[i]; } yield return Paths.GameRootPath; yield return Paths.BepInExRootPath; } } public static class ModNetworkHub { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static Func <>9__9_0; public static Func <>9__9_1; public static hook_Awake <>9__12_0; public static hook_Spawned <>9__12_1; internal string b__9_0(Type t) { return t.FullName; } internal string b__9_1(string n) { return n; } internal void b__12_0(orig_Awake orig, GameManager self) { try { EnsureRegisteredInPrefabTable(); } catch (Exception ex) { Log.Error("[ModNetworkHub] Échec de l'enregistrement du préfab du carrier : " + ex); } orig.Invoke(self); } internal void b__12_1(orig_Spawned orig, GameManager self) { orig.Invoke(self); try { OnGameManagerSpawned(self); } catch (Exception ex) { Log.Error("[ModNetworkHub] Échec de la mise en place du carrier réseau : " + ex); } } } private const string RegisteredTypesKey = "lycans.mods.network.types"; private const string HookInstalledKey = "lycans.mods.network.hookinstalled"; private const string CarrierKey = "lycans.mods.network.carrier"; private const string PrefabIdKey = "lycans.mods.network.prefabid"; private const string CarrierObjectName = "LycansModNetworkCarrier"; private static readonly object Lock = new object(); private static float _nextLookup; public static IReadOnlyList RegisteredTypeNames { get { lock (Lock) { return (from t in GetOrCreate>("lycans.mods.network.types") select t.FullName).OrderBy((string n) => n, StringComparer.Ordinal).ToArray(); } } } public static NetworkObject Carrier { get { object? data = AppDomain.CurrentDomain.GetData("lycans.mods.network.carrier"); NetworkObject val = (NetworkObject)((data is NetworkObject) ? data : null); if ((Object)(object)val != (Object)null) { return val; } if (Time.unscaledTime < _nextLookup) { return null; } _nextLookup = Time.unscaledTime + 0.5f; NetworkObject[] array = Object.FindObjectsOfType(); foreach (NetworkObject val2 in array) { if ((Object)(object)val2 != (Object)null && val2.IsValid && ((Object)val2).name.StartsWith("LycansModNetworkCarrier", StringComparison.Ordinal)) { AppDomain.CurrentDomain.SetData("lycans.mods.network.carrier", val2); return val2; } } return null; } } public static void Register() where T : NetworkBehaviour { lock (Lock) { List orCreate = GetOrCreate>("lycans.mods.network.types"); if (!orCreate.Contains(typeof(T))) { orCreate.Add(typeof(T)); } InstallSpawnHookOnce(); } } private static void InstallSpawnHookOnce() { //IL_0051: 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) //IL_005c: Expected O, but got Unknown //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Expected O, but got Unknown object data = AppDomain.CurrentDomain.GetData("lycans.mods.network.hookinstalled"); 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.network.hookinstalled", true); object obj = <>c.<>9__12_0; if (obj == null) { hook_Awake val = delegate(orig_Awake orig, GameManager self) { try { EnsureRegisteredInPrefabTable(); } catch (Exception ex) { Log.Error("[ModNetworkHub] Échec de l'enregistrement du préfab du carrier : " + ex); } orig.Invoke(self); }; <>c.<>9__12_0 = val; obj = (object)val; } GameManager.Awake += (hook_Awake)obj; object obj2 = <>c.<>9__12_1; if (obj2 == null) { hook_Spawned val2 = delegate(orig_Spawned orig, GameManager self) { orig.Invoke(self); try { OnGameManagerSpawned(self); } catch (Exception ex) { Log.Error("[ModNetworkHub] Échec de la mise en place du carrier réseau : " + ex); } }; <>c.<>9__12_1 = val2; obj2 = (object)val2; } GameManager.Spawned += (hook_Spawned)obj2; } private static void OnGameManagerSpawned(GameManager self) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) if (((SimulationBehaviour)self).Runner.SessionInfo.IsOpen && ((SimulationBehaviour)self).Runner.IsServer) { EnsureRegisteredInPrefabTable(); NetworkPrefabId val = (NetworkPrefabId)AppDomain.CurrentDomain.GetData("lycans.mods.network.prefabid"); NetworkObject data = ((SimulationBehaviour)self).Runner.Spawn(val, (Vector3?)Vector3.zero, (Quaternion?)Quaternion.identity, (PlayerRef?)null, (OnBeforeSpawned)null, (NetworkObjectPredictionKey?)null, true, (NetworkObject)null); AppDomain.CurrentDomain.SetData("lycans.mods.network.carrier", data); Log.Info("[ModNetworkHub] Carrier réseau spawn côté hôte avec " + GetOrCreate>("lycans.mods.network.types").Count + " composant(s) de mod."); } } private static void EnsureRegisteredInPrefabTable() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Expected O, but got Unknown //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) if (AppDomain.CurrentDomain.GetData("lycans.mods.network.prefabid") != null) { return; } GameObject val = new GameObject("LycansModNetworkCarrier"); val.AddComponent(); foreach (Type item in GetOrCreate>("lycans.mods.network.types")) { val.AddComponent(item); } Object.DontDestroyOnLoad((Object)(object)val); NetworkObject component = val.GetComponent(); component.NetworkedBehaviours = val.GetComponents(); component.NetworkGuid = new NetworkObjectGuid(ToGuid("LycansModNetworkCarrier").ToString()); NetworkPrefabSourceStatic val2 = new NetworkPrefabSourceStatic { PrefabReference = component }; NetworkPrefabId val3 = default(NetworkPrefabId); if (!NetworkProjectConfig.Global.PrefabTable.TryAdd(component.NetworkGuid, (INetworkPrefabSource)(object)val2, ref val3)) { throw new InvalidOperationException("[ModNetworkHub] Carrier déjà présent dans la table de préfabs Fusion."); } AppDomain.CurrentDomain.SetData("lycans.mods.network.prefabid", val3); } private static Guid ToGuid(string value) { using MD5 mD = MD5.Create(); return new Guid(mD.ComputeHash(Encoding.UTF8.GetBytes(value))); } private static T GetOrCreate(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 enum ProposalStatus { Empty, PendingHost, Voting, Accepted, Rejected } public readonly struct ProposalSlot { public readonly int Index; public readonly ProposalStatus Status; public readonly string ModName; public readonly string FieldLabel; public readonly float OldValueRaw; public readonly float NewValueRaw; public readonly int AuthorPlayerId; public readonly int VotesFor; public readonly int VotesAgainst; public ProposalSlot(int index, ProposalStatus status, string modName, string fieldLabel, float oldValueRaw, float newValueRaw, int authorPlayerId, int votesFor, int votesAgainst) { Index = index; Status = status; ModName = modName; FieldLabel = fieldLabel; OldValueRaw = oldValueRaw; NewValueRaw = newValueRaw; AuthorPlayerId = authorPlayerId; VotesFor = votesFor; VotesAgainst = votesAgainst; } } public static class ModProposals { public const string EnabledField = "Activé"; private const string SubmitKey = "lycans.mods.proposals.submit"; private const string VoteKey = "lycans.mods.proposals.vote"; private const string DecideKey = "lycans.mods.proposals.decide"; private const string CloseKey = "lycans.mods.proposals.close"; private const string ListKey = "lycans.mods.proposals.list"; public static bool IsAvailable => AppDomain.CurrentDomain.GetData("lycans.mods.proposals.list") != null; public static void PublishImplementation(Action submit, Action vote, Action hostDecide, Action hostCloseVote, Func> list) { AppDomain.CurrentDomain.SetData("lycans.mods.proposals.submit", submit); AppDomain.CurrentDomain.SetData("lycans.mods.proposals.vote", vote); AppDomain.CurrentDomain.SetData("lycans.mods.proposals.decide", hostDecide); AppDomain.CurrentDomain.SetData("lycans.mods.proposals.close", hostCloseVote); AppDomain.CurrentDomain.SetData("lycans.mods.proposals.list", (Func)delegate { IReadOnlyList readOnlyList = list(); object[][] array = new object[readOnlyList.Count][]; for (int i = 0; i < readOnlyList.Count; i++) { ProposalSlot proposalSlot = readOnlyList[i]; array[i] = new object[9] { proposalSlot.Index, (int)proposalSlot.Status, proposalSlot.ModName, proposalSlot.FieldLabel, proposalSlot.OldValueRaw, proposalSlot.NewValueRaw, proposalSlot.AuthorPlayerId, proposalSlot.VotesFor, proposalSlot.VotesAgainst }; } return array; }); } public static void Submit(string modName, string fieldLabel, float oldValueRaw, float newValueRaw) { if (AppDomain.CurrentDomain.GetData("lycans.mods.proposals.submit") is Action action) { action(Hash(modName), Hash(fieldLabel), oldValueRaw, newValueRaw); } else { Log.Info("[ModProposals] Submit ignoré : mod_council non chargé."); } } public static void Vote(int slotIndex, bool voteFor) { if (AppDomain.CurrentDomain.GetData("lycans.mods.proposals.vote") is Action action) { action(slotIndex, voteFor); } } public static void HostDecide(int slotIndex, bool approve) { if (AppDomain.CurrentDomain.GetData("lycans.mods.proposals.decide") is Action action) { action(slotIndex, approve); } } public static void HostCloseVote(int slotIndex) { if (AppDomain.CurrentDomain.GetData("lycans.mods.proposals.close") is Action action) { action(slotIndex); } } public static IReadOnlyList List() { if (!(AppDomain.CurrentDomain.GetData("lycans.mods.proposals.list") is Func func)) { return Array.Empty(); } object[][] array = func(); ProposalSlot[] array2 = new ProposalSlot[array.Length]; for (int i = 0; i < array.Length; i++) { object[] array3 = array[i]; array2[i] = new ProposalSlot((int)array3[0], (ProposalStatus)(int)array3[1], (string)array3[2], (string)array3[3], (float)array3[4], (float)array3[5], (int)array3[6], (int)array3[7], (int)array3[8]); } return array2; } public static int Hash(string value) { uint num = 2166136261u; foreach (char c in value) { num ^= c; num *= 16777619; } return (int)num; } } public static class ModRegistry { private const string CapabilitiesKey = "lycans.mods.capabilities"; private const string SubscribersKey = "lycans.mods.subscribers"; private static readonly object Lock = new object(); public static void Register(string modGuid, params string[] capabilities) { lock (Lock) { HashSet orCreate = GetOrCreate>("lycans.mods.capabilities"); foreach (string item in capabilities) { orCreate.Add(item); } } } public static bool Has(string capability) { lock (Lock) { return GetOrCreate>("lycans.mods.capabilities").Contains(capability); } } public static IReadOnlyCollection AllCapabilities() { lock (Lock) { return (IReadOnlyCollection)(object)GetOrCreate>("lycans.mods.capabilities").ToArray(); } } public static void Subscribe(Action handler) { lock (Lock) { GetOrCreate>>("lycans.mods.subscribers").GetOrAdd(typeof(T)).Add(handler); } } public static void Unsubscribe(Action handler) { lock (Lock) { if (GetOrCreate>>("lycans.mods.subscribers").TryGetValue(typeof(T), out var value)) { value.Remove(handler); } } } public static void Publish(T payload) { Delegate[] array; lock (Lock) { if (!GetOrCreate>>("lycans.mods.subscribers").TryGetValue(typeof(T), out var value)) { return; } array = value.ToArray(); } Delegate[] array2 = array; foreach (Delegate obj in array2) { try { ((Action)obj)(payload); } catch (Exception ex) { Log.Error("[ModRegistry] Abonné en erreur pour " + typeof(T).Name + " : " + ex); } } } private static T GetOrCreate(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; } private static List GetOrAdd(this Dictionary> dict, Type key) { if (!dict.TryGetValue(key, out var value)) { value = (dict[key] = new List()); } return value; } } public sealed class MovementContext { private readonly IDictionary _data; private float[] Values => (float[])_data["values"]; public PlayerController Player => (PlayerController)_data["player"]; public CharacterMovementHandler Handler => (CharacterMovementHandler)_data["handler"]; public float X { get { return Values[0]; } set { Values[0] = value; } } public float Y { get { return Values[1]; } set { Values[1] = value; } } public float Speed { get { return Values[2]; } set { Values[2] = value; } } public bool Teleported => (bool)_data["teleported"]; public bool Cancel { get { return HookPipeline.IsCancelled(_data); } set { _data["cancel"] = HookPipeline.Box(value); } } internal MovementContext(IDictionary data) { _data = data; } } public static class MovementRules { public const string Method = "CharacterMovementHandler.FixedUpdateNetwork"; public static void Before(int priority, string owner, Action step) { HookPipeline.Register("CharacterMovementHandler.FixedUpdateNetwork", priority, owner, HookPhase.Before, delegate(IDictionary data) { step(new MovementContext(data)); }); } public static void After(int priority, string owner, Action step) { HookPipeline.Register("CharacterMovementHandler.FixedUpdateNetwork", priority, owner, HookPhase.After, delegate(IDictionary data) { step(new MovementContext(data)); }); } public static IDictionary NewData() { return new Dictionary { ["values"] = new float[3] }; } public static void Reset(IDictionary data, CharacterMovementHandler handler, PlayerController player, float x, float y, float speed, bool teleported) { data["handler"] = handler; data["player"] = player; data["teleported"] = HookPipeline.Box(teleported); data["cancel"] = HookPipeline.False; float[] obj = (float[])data["values"]; obj[0] = x; obj[1] = y; obj[2] = speed; } } public static class NetworkedWeaving { public unsafe static bool GetBool(int* ptr, int word) { return *CheckedPtr(ptr, word) != 0; } public unsafe static void SetBool(int* ptr, int word, bool value) { *CheckedPtr(ptr, word) = (value ? 1 : 0); } public unsafe static int GetInt(int* ptr, int word) { return *CheckedPtr(ptr, word); } public unsafe static void SetInt(int* ptr, int word, int value) { *CheckedPtr(ptr, word) = value; } public unsafe static float GetFloat(int* ptr, int word) { return *(float*)CheckedPtr(ptr, word); } public unsafe static void SetFloat(int* ptr, int word, float value) { *(float*)CheckedPtr(ptr, word) = value; } private unsafe static int* CheckedPtr(int* ptr, int word) { if (ptr == null) { throw new InvalidOperationException("Champ réseau lu avant Spawned() : les propriétés [Networked] ne sont valides qu'une fois l'objet spawn."); } return ptr + word; } } public sealed class ObjectTargetContext { private readonly IDictionary _data; public PlayerController Player => (PlayerController)_data["player"]; public GameObject Target { get { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown return (GameObject)_data["target"]; } set { _data["target"] = value; } } public float Distance => (float)_data["distance"]; public bool Offered => (bool)_data["offered"]; internal ObjectTargetContext(IDictionary data) { _data = data; } } public static class ObjectTargetRules { public const string Method = "PlayerController.UpdateRayCast"; public static void Offer(int priority, string owner, Func offer) { HookPipeline.Register("PlayerController.UpdateRayCast", priority, owner, HookPhase.Before, delegate(IDictionary data) { if (!(bool)data["offered"] && offer(new ObjectTargetContext(data))) { data["offered"] = HookPipeline.True; } }); } public static IDictionary NewData() { return new Dictionary(); } public static void Reset(IDictionary data, PlayerController player, GameObject target, float distance) { data["player"] = player; data["target"] = target; data["distance"] = distance; data["offered"] = HookPipeline.False; data["cancel"] = HookPipeline.False; } } public static class PlayerColors { private const string GetKey = "lycans.mods.colors.get"; private const string SetKey = "lycans.mods.colors.set"; private const string CountKey = "lycans.mods.colors.count"; public static bool IsAvailable => AppDomain.CurrentDomain.GetData("lycans.mods.colors.get") != null; public static int Count { get { if (!(AppDomain.CurrentDomain.GetData("lycans.mods.colors.count") is Func func)) { return 0; } return func(); } } public static void PublishImplementation(Func get, Action set, Func count) { AppDomain.CurrentDomain.SetData("lycans.mods.colors.get", get); AppDomain.CurrentDomain.SetData("lycans.mods.colors.set", set); AppDomain.CurrentDomain.SetData("lycans.mods.colors.count", count); } public static int Get(PlayerController player) { if ((Object)(object)player == (Object)null) { return 0; } if (!(AppDomain.CurrentDomain.GetData("lycans.mods.colors.get") is Func func)) { return player.Index; } return func(player.Index); } public static void Set(PlayerController player, int color) { if ((Object)(object)player != (Object)null && AppDomain.CurrentDomain.GetData("lycans.mods.colors.set") is Action action) { action(player.Index, color); } } } public static class PlayerLookup { public static bool Ready => (Object)(object)PlayerRegistry.Instance != (Object)null; public static PlayerController ByIndex(int index) { PlayerController found = null; if (!Ready) { return null; } PlayerRegistry.ForEach((Action)delegate(PlayerController p) { if ((Object)(object)found == (Object)null && (Object)(object)p != (Object)null && p.Index == index) { found = p; } }); return found; } } public static class PlayerScaleRules { public const string Method = "PlayerController.Scale"; public static void Factor(int priority, string owner, Func factor, bool instantShrink = false) { HookPipeline.Register("PlayerController.Scale", priority, owner, HookPhase.Before, delegate(IDictionary data) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown float[] array = (float[])data["values"]; float num = factor((PlayerController)data["player"]); array[0] *= num; if (instantShrink && !Mathf.Approximately(num, 1f)) { array[1] = 1f; } }); } public static IDictionary NewData() { return new Dictionary { ["values"] = new float[2] }; } public static float Run(IDictionary data, PlayerController player, out bool instant) { data["player"] = player; data["cancel"] = HookPipeline.False; float[] array = (float[])data["values"]; array[0] = 1f; array[1] = 0f; HookPipeline.RunBefore("PlayerController.Scale", data); instant = array[1] > 0.5f; return array[0]; } } public static class PlayerSkins { private const string DefinitionsKey = "lycans.mods.skins.definitions"; private const string CalibrationKey = "lycans.mods.skins.calibration"; public static void Register(string key, string label, bool werewolf, Action select, Action setVisible, Action setColor, Func animator) { Definitions()[key] = new object[6] { label, werewolf, select, setVisible, setColor, animator }; CustomAnimations.RegisterExtraAnimator("skin." + key, (PlayerController p) => (!((Object)(object)p != (Object)null)) ? null : animator(p.Index)); } public static void RegisterCalibration(string key, Func getScale, Action setScale, Func getPosition, Action setPosition, Func getCamera, Action setCamera, Action toggleOriginal, Action setCalibrationMode = null) { Calibrations()[key] = new object[8] { getScale, setScale, getPosition, setPosition, getCamera, setCamera, toggleOriginal, setCalibrationMode }; } public static SortedDictionary Calibrations() { if (AppDomain.CurrentDomain.GetData("lycans.mods.skins.calibration") is SortedDictionary result) { return result; } SortedDictionary sortedDictionary = new SortedDictionary(StringComparer.Ordinal); AppDomain.CurrentDomain.SetData("lycans.mods.skins.calibration", sortedDictionary); return sortedDictionary; } public static SortedDictionary Definitions() { if (AppDomain.CurrentDomain.GetData("lycans.mods.skins.definitions") is SortedDictionary result) { return result; } SortedDictionary sortedDictionary = new SortedDictionary(StringComparer.Ordinal); AppDomain.CurrentDomain.SetData("lycans.mods.skins.definitions", sortedDictionary); return sortedDictionary; } } public sealed class PlayerTargetContext { private readonly IDictionary _data; private float[] Values => (float[])_data["values"]; public PlayerController Player => (PlayerController)_data["player"]; public PlayerController Target => (PlayerController)_data["target"]; public float Distance => Values[0]; public float Range { get { return Values[1]; } set { Values[1] = value; } } public bool InRange => Distance < Range; public bool Offered { get { return (bool)_data["offered"]; } set { _data["offered"] = HookPipeline.Box(value); } } internal PlayerTargetContext(IDictionary data) { _data = data; } } public static class PlayerTargetRules { public const string Method = "PlayerController.CheckPlayerRayCast"; public static void AdjustRange(int priority, string owner, Action step) { HookPipeline.Register("PlayerController.CheckPlayerRayCast", priority, owner, HookPhase.Before, delegate(IDictionary data) { step(new PlayerTargetContext(data)); }); } public static void Offer(int priority, string owner, Func offer) { HookPipeline.Register("PlayerController.CheckPlayerRayCast", priority, owner, HookPhase.After, delegate(IDictionary data) { PlayerTargetContext playerTargetContext = new PlayerTargetContext(data); if (!playerTargetContext.Offered && offer(playerTargetContext)) { playerTargetContext.Offered = true; } }); } public static IDictionary NewData() { return new Dictionary { ["values"] = new float[2] }; } public static void Reset(IDictionary data, PlayerController player, PlayerController target, float distance) { data["player"] = player; data["target"] = target; data["offered"] = HookPipeline.False; data["cancel"] = HookPipeline.False; float[] obj = (float[])data["values"]; obj[0] = distance; obj[1] = 1.5f; } } public static class Replay { private const string RecordKey = "lycans.mods.replay.record"; public static void PublishImplementation(Action> record) { AppDomain.CurrentDomain.SetData("lycans.mods.replay.record", record); } public static void Record(string action, Dictionary payload = null) { if (AppDomain.CurrentDomain.GetData("lycans.mods.replay.record") is Action> action2) { action2(action, payload); } } } public static class Translations { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static Action <>9__18_0; public static hook_Spawned <>9__18_1; internal void b__18_0(Locale _) { TryPush(); } internal void b__18_1(orig_Spawned orig, GameManager self) { orig.Invoke(self); TryPush(); } } public static readonly string[] Languages = new string[6] { "fr", "en", "de", "es", "tr", "it" }; public static readonly string[] LanguageNames = new string[6] { "Français", "English", "Deutsch", "Español", "Türkçe", "Italiano" }; private const string EntriesKey = "lycans.mods.translations.entries6"; private const string InstalledKey = "lycans.mods.translations.installed6"; private const string OverrideKey = "lycans.mods.translations.language"; private const string SetterKey = "lycans.mods.translations.languagesetter"; public static string Choice => (AppDomain.CurrentDomain.GetData("lycans.mods.translations.language") as string) ?? "auto"; public static string Language { get { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Invalid comparison between Unknown and I4 //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Invalid comparison between Unknown and I4 //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Invalid comparison between Unknown and I4 //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Invalid comparison between Unknown and I4 //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Invalid comparison between Unknown and I4 string choice = Choice; if (Array.IndexOf(Languages, choice) >= 0) { return choice; } if (GameLocale().StartsWith("fr", StringComparison.OrdinalIgnoreCase)) { return "fr"; } SystemLanguage systemLanguage = Application.systemLanguage; if ((int)systemLanguage <= 21) { if ((int)systemLanguage == 15) { return "de"; } if ((int)systemLanguage == 21) { return "it"; } } else { if ((int)systemLanguage == 34) { return "es"; } if ((int)systemLanguage == 37) { return "tr"; } } return "en"; } } public static void Add(string key, string fr, string en, string de = null, string es = null, string tr = null, string it = null) { Entries()[key] = new string[6] { fr, en, de, es, tr, it }; EnsureInstalled(); TryPush(); } public static string Get(string key) { if (!Entries().TryGetValue(key, out var value)) { return key; } return Pick(value); } public static string Text(string fr, string en, string de = null, string es = null, string tr = null, string it = null) { return Pick(new string[6] { fr, en, de, es, tr, it }); } private static string Pick(string[] texts) { int num = Array.IndexOf(Languages, Language); string text = ((num >= 0 && num < texts.Length) ? texts[num] : null); if (string.IsNullOrEmpty(text)) { text = texts[1]; } if (!string.IsNullOrEmpty(text)) { return text; } return texts[0]; } public static bool IsFrench() { return Language == "fr"; } public static void SetLanguage(string choice) { AppDomain.CurrentDomain.SetData("lycans.mods.translations.language", string.IsNullOrEmpty(choice) ? "auto" : choice); (AppDomain.CurrentDomain.GetData("lycans.mods.translations.languagesetter") as Action)?.Invoke(Choice); TryPush(); } public static void PublishLanguageSetting(string initial, Action save) { AppDomain.CurrentDomain.SetData("lycans.mods.translations.languagesetter", save); AppDomain.CurrentDomain.SetData("lycans.mods.translations.language", string.IsNullOrEmpty(initial) ? "auto" : initial); TryPush(); } private static string GameLocale() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) try { Locale selectedLocale = LocalizationSettings.SelectedLocale; object obj; if (selectedLocale == null) { obj = null; } else { LocaleIdentifier identifier = selectedLocale.Identifier; obj = ((LocaleIdentifier)(ref identifier)).Code; } if (obj == null) { obj = ""; } return (string)obj; } catch { return ""; } } private static void EnsureInstalled() { //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Expected O, but got Unknown if (AppDomain.CurrentDomain.GetData("lycans.mods.translations.installed6") != null) { return; } AppDomain.CurrentDomain.SetData("lycans.mods.translations.installed6", true); LocalizationSettings.SelectedLocaleChanged += delegate { TryPush(); }; object obj = <>c.<>9__18_1; if (obj == null) { hook_Spawned val = delegate(orig_Spawned orig, GameManager self) { orig.Invoke(self); TryPush(); }; <>c.<>9__18_1 = val; obj = (object)val; } GameManager.Spawned += (hook_Spawned)obj; } private static void TryPush() { //IL_000a: Unknown result type (might be due to invalid IL or missing references) try { StringTable table = ((LocalizedDatabase)(object)LocalizationSettings.StringDatabase).GetTable(TableReference.op_Implicit("UI Text"), (Locale)null); if ((Object)(object)table == (Object)null) { return; } foreach (KeyValuePair item in Entries()) { string text = Pick(item.Value); StringTableEntry entry = ((DetailedLocalizationTable)(object)table).GetEntry(item.Key); if (entry != null) { entry.Value = text; } else { ((DetailedLocalizationTable)(object)table).AddEntry(item.Key, text); } } } catch (Exception ex) { Log.Warning("[Translations] Table « UI Text » pas encore prête : " + ex.Message); } } private static Dictionary Entries() { if (AppDomain.CurrentDomain.GetData("lycans.mods.translations.entries6") is Dictionary result) { return result; } Dictionary dictionary = new Dictionary(); AppDomain.CurrentDomain.SetData("lycans.mods.translations.entries6", dictionary); return dictionary; } } public enum VictoryDecision { NoOpinion, Continue, Village, Wolves } public sealed class VictoryContext { private readonly IDictionary _data; public bool FromScore => (bool)_data["fromScore"]; public int WolvesAlive => (int)_data["wolves"]; public int OthersAlive => (int)_data["others"]; public bool IsMeeting { get { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Invalid comparison between Unknown and I4 if ((Object)(object)GameManager.State != (Object)null) { return (int)GameManager.State.Current == 4; } return false; } } public int Score => GameManager.Instance.Score; public int MaxScore => GameManager.Instance.MaxScore; internal VictoryContext(IDictionary data) { _data = data; } } public static class VictoryRules { public const string Method = "GameManager.CheckForEndGame"; private const string DecisionKey = "decision"; private static readonly object[] Boxed = new object[4] { 0, 1, 2, 3 }; public static void Decide(int priority, string owner, Func step) { HookPipeline.Register("GameManager.CheckForEndGame", priority, owner, HookPhase.Before, delegate(IDictionary data) { VictoryDecision victoryDecision = step(new VictoryContext(data)); if (victoryDecision != VictoryDecision.NoOpinion) { data["decision"] = Boxed[(int)victoryDecision]; data["cancel"] = HookPipeline.True; } }); } public static int Run(bool fromScore, int wolvesAlive, int othersAlive) { Dictionary dictionary = new Dictionary { ["fromScore"] = fromScore, ["wolves"] = wolvesAlive, ["others"] = othersAlive, ["decision"] = Boxed[0], ["cancel"] = HookPipeline.False }; HookPipeline.RunBefore("GameManager.CheckForEndGame", dictionary); return (int)dictionary["decision"]; } } public sealed class VoteContext { private readonly IDictionary _data; private Dictionary Weights => (Dictionary)_data["weights"]; public PlayerController Eliminated { get { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown if (!_data.TryGetValue("eliminated", out var value)) { return null; } return (PlayerController)value; } } public bool Cancel { get { return HookPipeline.IsCancelled(_data); } set { _data["cancel"] = HookPipeline.Box(value); } } internal VoteContext(IDictionary data) { _data = data; } public int GetWeight(PlayerController voter) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) Dictionary weights = Weights; PlayerRef val = voter.Ref; if (!weights.TryGetValue(((PlayerRef)(ref val)).PlayerId, out var value)) { return 1; } return value; } public void SetWeight(PlayerController voter, int weight) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) Dictionary weights = Weights; PlayerRef val = voter.Ref; weights[((PlayerRef)(ref val)).PlayerId] = weight; } } public static class VoteRules { public const string Method = "GameManager.EndVote"; public static void Before(int priority, string owner, Action step) { HookPipeline.Register("GameManager.EndVote", priority, owner, HookPhase.Before, delegate(IDictionary data) { step(new VoteContext(data)); }); } public static void After(int priority, string owner, Action step) { HookPipeline.Register("GameManager.EndVote", priority, owner, HookPhase.After, delegate(IDictionary data) { step(new VoteContext(data)); }); } public static IDictionary NewData() { return new Dictionary { ["weights"] = new Dictionary(), ["cancel"] = HookPipeline.False }; } } } namespace LycansMod.WolfHarvest { [BepInPlugin("lycans.wolf-harvest", "Lycans Wolf Harvest", "1.0.2")] public class Plugin : BaseUnityPlugin { public const string Guid = "lycans.wolf-harvest"; public const string Name = "Lycans Wolf Harvest"; public const string Version = "1.0.2"; public const string Status = "stable"; private const int Priority = 10; private ConfigEntry _enabled; private void Awake() { Log.Use(((BaseUnityPlugin)this).Logger); if (!DevMode.Guard((BaseUnityPlugin)(object)this, "Lycans Wolf Harvest", "stable")) { return; } _enabled = ((BaseUnityPlugin)this).Config.Bind("Général", "Active", true, "Activé par défaut, comme dans l'ancien modpack."); ModRegistry.Register("lycans.wolf-harvest", "loot:wolf-harvest"); ModConfigRegistry.RegisterMod("Lycans Wolf Harvest", () => _enabled.Value, delegate(bool v) { _enabled.Value = v; }).Chapter("rules", "Un loup qui ramasse un butin fait perdre des points au village.").Wiki("Règle · Difficulté : difficile\nChaque butin ramassé par un loup retire des points au village au lieu d'en ajouter. Les butins comestibles le nourrissent toujours. Le score du village ne descend jamais sous 0.\nAvec la Récolte cachée, les loups ne voient pas non plus l'effet de leur sabotage."); ModConfigPanel.EnsureInstalled(); LootRules.Before(10, "Lycans Wolf Harvest", delegate(LootCollectContext ctx) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Invalid comparison between Unknown and I4 if (_enabled.Value && (int)ctx.Player.Role == 1) { ctx.Score = -ctx.Score; } }); ((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("{0} {1} chargé (actif={2}).", "Lycans Wolf Harvest", "1.0.2", _enabled.Value)); } } public static class MyPluginInfo { public const string PLUGIN_GUID = "LycansMod.WolfHarvest"; public const string PLUGIN_NAME = "LycansMod.WolfHarvest"; public const string PLUGIN_VERSION = "1.0.0"; } }