Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Blyssheim v0.4.5
plugins/Blyssheim/Blyssheim.dll
Decompiled 43 minutes ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using Blyssheim.Dev; using Blyssheim.Pets; using Blyssheim.Warden; using Blyssheim.Watch; using HarmonyLib; using Jotunn.Entities; using Jotunn.Managers; using Jotunn.Utils; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using UnityEngine; using UnityEngine.Rendering; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("Blyssheim")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.4.5.0")] [assembly: AssemblyInformationalVersion("0.4.5+8639bc0efdf90803a1a603d3111c7ca3251e90b0")] [assembly: AssemblyProduct("Blyssheim")] [assembly: AssemblyTitle("Blyssheim")] [assembly: AssemblyVersion("0.4.5.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace Blyssheim { [BepInPlugin("overzealyss.blyssheim", "Blyssheim", "0.4.5")] [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { public const string Guid = "overzealyss.blyssheim"; public const string Name = "Blyssheim"; public const string Version = "0.4.5"; internal static ManualLogSource Log; internal static Plugin Instance; private void Awake() { //IL_0058: Unknown result type (might be due to invalid IL or missing references) Instance = this; Log = ((BaseUnityPlugin)this).Logger; Settings.Bind(((BaseUnityPlugin)this).Config); Diagnostics.Bind(((BaseUnityPlugin)this).Config); BodyExport.Bind(((BaseUnityPlugin)this).Config); WardenItems.Init(((BaseUnityPlugin)this).Config); WardenNet.Init(((BaseUnityPlugin)this).Config); PetFetch.Bind(((BaseUnityPlugin)this).Config); new Harmony("overzealyss.blyssheim").PatchAll(); Log.LogInfo((object)"Blyssheim 0.4.5 loaded."); } private void Update() { WardenNet.Tick(); WardenSearch.Tick(); } } [HarmonyPatch(typeof(Game), "Start")] internal static class Rpc { public const string Snapshot = "Blyssheim_Snapshot"; public const string Alert = "Blyssheim_Alert"; private static void Postfix() { ZRoutedRpc.instance.Register<ZPackage>("Blyssheim_Snapshot", (Action<long, ZPackage>)ServerWatch.OnSnapshot); ZRoutedRpc.instance.Register<string>("Blyssheim_Alert", (Action<long, string>)ClientWatch.OnAlert); WardenNet.Register(); if (Object.op_Implicit((Object)(object)ZNet.instance) && ZNet.instance.IsDedicated()) { ((MonoBehaviour)Plugin.Instance).StartCoroutine(ReportContrabandSoon()); } } private static IEnumerator ReportContrabandSoon() { yield return (object)new WaitForSeconds(15f); Contraband.LogSummary(); } public static long ServerPeerId() { return (long)AccessTools.Method(typeof(ZRoutedRpc), "GetServerPeerID", (Type[])null, (Type[])null).Invoke(ZRoutedRpc.instance, null); } } } namespace Blyssheim.Watch { internal static class ClientWatch { [HarmonyPatch(typeof(Player), "OnSpawned")] private static class SpawnPatch { private static void Postfix(Player __instance) { if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && _loop == null) { _loop = ((MonoBehaviour)Plugin.Instance).StartCoroutine(Loop()); } } } [HarmonyPatch(typeof(Game), "Logout")] private static class LogoutPatch { private static void Prefix() { Send("leave"); } } private static readonly PlayerStatType[] TrackedStats; private static Coroutine _loop; private static string _lastSent; private static bool OnDedicatedServer { get { if ((Object)(object)ZNet.instance != (Object)null && !ZNet.instance.IsServer()) { return (Object)(object)Player.m_localPlayer != (Object)null; } return false; } } public unsafe static Snapshot Take(string kind) { //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; Game instance = Game.instance; PlayerProfile val = ((instance != null) ? instance.GetPlayerProfile() : null); if ((Object)(object)localPlayer == (Object)null || val == null) { return null; } Snapshot snapshot = new Snapshot { Kind = kind, PlayerId = val.GetPlayerID(), Character = val.GetName(), UsedCheats = val.m_usedCheats }; PlayerStats[] array = val.m_playerStats ?? Array.Empty<PlayerStats>(); foreach (PlayerStats val2 in array) { if (val2 != null) { if (val2.m_knownWorlds != null) { snapshot.KnownWorlds.AddRange(val2.m_knownWorlds.Keys); } if (val2.m_knownCommands != null) { snapshot.KnownCommands.AddRange(val2.m_knownCommands.Keys); } } } snapshot.KnownWorlds = snapshot.KnownWorlds.Distinct().ToList(); snapshot.KnownCommands = snapshot.KnownCommands.Distinct().Where(IsCheatCommand).ToList(); PlayerStatType[] trackedStats = TrackedStats; for (int i = 0; i < trackedStats.Length; i++) { PlayerStatType val3 = trackedStats[i]; snapshot.Stats[((object)(*(PlayerStatType*)(&val3))/*cast due to .constrained prefix*/).ToString()] = val.GetStat(val3); } foreach (ItemData allItem in ((Humanoid)localPlayer).GetInventory().GetAllItems()) { snapshot.Items.Add(new ItemEntry { Name = (Object.op_Implicit((Object)(object)allItem.m_dropPrefab) ? ((Object)allItem.m_dropPrefab).name : allItem.m_shared.m_name), Stack = allItem.m_stack, Quality = allItem.m_quality, Cheated = allItem.m_cheated, Crafter = allItem.m_crafterName }); } return snapshot; } private static bool IsCheatCommand(string name) { if (string.IsNullOrEmpty(name)) { return false; } string text = name.Split(' ')[0].ToLowerInvariant(); if (text == "devcommands") { return true; } if (!(AccessTools.Field(typeof(Terminal), "commands")?.GetValue(null) is IDictionary dictionary) || !dictionary.Contains(text)) { return false; } object? obj = dictionary[text]; return ((ConsoleCommand)(((obj is ConsoleCommand) ? obj : null)?)).IsCheat ?? false; } public static void Send(string kind, bool onlyIfChanged = false) { if (!OnDedicatedServer) { return; } Snapshot snapshot = Take(kind); if (snapshot != null) { string text = string.Join(";", from kv in snapshot.Totals() orderby kv.Key select kv.Key + "=" + kv.Value); if (!onlyIfChanged || !(text == _lastSent)) { _lastSent = text; ZRoutedRpc.instance.InvokeRoutedRPC(Rpc.ServerPeerId(), "Blyssheim_Snapshot", new object[1] { snapshot.ToPackage() }); } } } private static IEnumerator Loop() { yield return (object)new WaitForSeconds(3f); _lastSent = null; Send("arrive"); while ((Object)(object)Player.m_localPlayer != (Object)null) { yield return (object)new WaitForSeconds((float)Mathf.Max(5, Settings.CheckpointSeconds.Value)); Send("checkpoint", onlyIfChanged: true); } _loop = null; } public static void OnAlert(long sender, string text) { if (Object.op_Implicit((Object)(object)MessageHud.instance)) { MessageHud.instance.ShowMessage((MessageType)2, "<color=#ff4040>CONTRABAND</color>\n" + text, 0, (Sprite)null, false, true); } if (Object.op_Implicit((Object)(object)Chat.instance)) { ((Terminal)Chat.instance).AddString("<color=#ff4040>Blyssheim</color>", text, (Type)0, true); } Plugin.Log.LogWarning((object)("Contraband alert: " + text)); Alerts.Raise(text); } static ClientWatch() { PlayerStatType[] array = new PlayerStatType[16]; RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/); TrackedStats = (PlayerStatType[])(object)array; } } public static class Alerts { public static event Action<string> OnContraband; internal static void Raise(string text) { Alerts.OnContraband?.Invoke(text); } } internal static class Contraband { public static readonly (string Key, string Boss)[] Bosses = new(string, string)[7] { ("defeated_eikthyr", "Eikthyr"), ("defeated_gdking", "The Elder"), ("defeated_bonemass", "Bonemass"), ("defeated_dragon", "Moder"), ("defeated_goblinking", "Yagluth"), ("defeated_queen", "The Queen"), ("defeated_fader", "Fader") }; private static readonly Dictionary<string, string[]> Defaults = new Dictionary<string, string[]> { ["defeated_eikthyr"] = new string[1] { "HardAntler" }, ["defeated_gdking"] = new string[4] { "Iron", "IronScrap", "IronOre", "CryptKey" }, ["defeated_bonemass"] = new string[3] { "Silver", "SilverOre", "Wishbone" }, ["defeated_dragon"] = new string[3] { "DragonTear", "BlackMetal", "LinenThread" }, ["defeated_goblinking"] = new string[4] { "YagluthDrop", "Wisp", "Eitr", "BlackCore" }, ["defeated_queen"] = new string[5] { "QueenDrop", "FlametalNew", "FlametalOreNew", "Flametal", "FlametalOre" }, ["defeated_fader"] = new string[1] { "FaderDrop" } }; private static Dictionary<string, int> _tier; private static string FilePath => Path.Combine(ServerWatch.DataDir, "contraband.json"); private static Dictionary<string, string[]> LoadTable() { if (!File.Exists(FilePath)) { File.WriteAllText(FilePath, JsonConvert.SerializeObject((object)Defaults, (Formatting)1)); } try { return JsonConvert.DeserializeObject<Dictionary<string, string[]>>(File.ReadAllText(FilePath)) ?? Defaults; } catch { return Defaults; } } private static void Build() { _tier = new Dictionary<string, int>(); Dictionary<string, string[]> dictionary = LoadTable(); for (int i = 0; i < Bosses.Length; i++) { if (dictionary.TryGetValue(Bosses[i].Key, out var value)) { string[] array = value; foreach (string key in array) { _tier[key] = i; } } } List<Recipe> list = (Object.op_Implicit((Object)(object)ObjectDB.instance) ? ObjectDB.instance.m_recipes.Where((Recipe r) => Object.op_Implicit((Object)(object)r) && Object.op_Implicit((Object)(object)r.m_item)).ToList() : new List<Recipe>()); bool flag = true; int num = 0; while (flag && num < 20) { flag = false; foreach (Recipe item in list) { int num2 = -1; Requirement[] array2 = (Requirement[])(((object)item.m_resources) ?? ((object)new Requirement[0])); foreach (Requirement val in array2) { if (Object.op_Implicit((Object)(object)val?.m_resItem) && _tier.TryGetValue(((Object)((Component)val.m_resItem).gameObject).name, out var value2) && value2 > num2) { num2 = value2; } } if (num2 >= 0) { string name = ((Object)((Component)item.m_item).gameObject).name; if (!_tier.TryGetValue(name, out var value3) || num2 > value3) { _tier[name] = num2; flag = true; } } } num++; } Plugin.Log.LogInfo((object)$"Contraband table: {_tier.Count} gated items."); } public static string BossNeeded(string item) { if (_tier == null) { Build(); } if (!_tier.TryGetValue(item, out var value)) { return null; } ZoneSystem instance = ZoneSystem.instance; if ((Object)(object)instance != (Object)null && instance.GetGlobalKey(Bosses[value].Key)) { return null; } return Bosses[value].Boss; } public static void Reset() { _tier = null; } public static void LogSummary() { if (_tier == null) { Build(); } List<IGrouping<string, (string, string)>> list = (from i in _tier.Keys select (Item: i, Boss: BossNeeded(i)) into x where x.Boss != null group x by x.Boss).ToList(); IEnumerable<string> values = from b in Bosses where Object.op_Implicit((Object)(object)ZoneSystem.instance) && ZoneSystem.instance.GetGlobalKey(b.Key) select b.Boss; Plugin.Log.LogInfo((object)("Contraband: bosses beaten: " + string.Join(", ", values) + ". " + $"{list.Sum((IGrouping<string, (string Item, string Boss)> g) => g.Count())} items are contraband right now.")); foreach (IGrouping<string, (string, string)> item in list) { Plugin.Log.LogInfo((object)string.Format(" waits on {0} ({1}): {2}{3}", item.Key, item.Count(), string.Join(", ", (from x in item select x.Item into x orderby x select x).Take(25)), (item.Count() > 25) ? ", ..." : "")); } } } public class PlayerRecord { public string Host; public string Character; public long PlayerId; public DateTime LastSeen; public bool UsedCheats; public List<string> KnownWorlds = new List<string>(); public List<string> KnownCommands = new List<string>(); public Dictionary<string, float> Stats = new Dictionary<string, float>(); public Snapshot Last; public DateTime? OnlineSince; public double SecondsOnServer; public int Sessions; public DateTime? FirstSeen; } public class Incident { public DateTime When; public string Character; public string Host; public List<string> Charges = new List<string>(); } internal static class ServerWatch { private static readonly Dictionary<long, string> OpenByPeer = new Dictionary<long, string>(); private static readonly JsonSerializerSettings Json = new JsonSerializerSettings { Formatting = (Formatting)1 }; public static string DataDir { get { string text = Path.Combine(Paths.ConfigPath, "Blyssheim"); Directory.CreateDirectory(text); return text; } } private static string PlayersDir { get { string text = Path.Combine(DataDir, "players"); Directory.CreateDirectory(text); return text; } } private static string IncidentsPath => Path.Combine(DataDir, "incidents.json"); private static string LogPath => Path.Combine(DataDir, "watch.log"); private static string SessionsPath => Path.Combine(DataDir, "sessions.csv"); public static void OnSnapshot(long sender, ZPackage pkg) { if ((Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer()) { return; } try { Snapshot snapshot = Snapshot.FromPackage(pkg); ZNetPeer peer = ZNet.instance.GetPeer(sender); if (snapshot != null && peer != null) { Handle(peer, snapshot); } } catch (Exception ex) { Plugin.Log.LogError((object)("Watch: " + ex)); } } private static string FileFor(string host, long id) { return Path.Combine(PlayersDir, string.Concat(string.Concat((host + "_" + id).Select((char c) => (!Path.GetInvalidFileNameChars().Contains(c)) ? c : '_')), ".json")); } public static IEnumerable<PlayerRecord> AllRecords() { return from r in Directory.GetFiles(PlayersDir, "*.json").Select(delegate(string f) { try { return JsonConvert.DeserializeObject<PlayerRecord>(File.ReadAllText(f)); } catch { return (PlayerRecord)null; } }) where r != null select r; } public static List<Incident> Incidents() { try { return File.Exists(IncidentsPath) ? (JsonConvert.DeserializeObject<List<Incident>>(File.ReadAllText(IncidentsPath)) ?? new List<Incident>()) : new List<Incident>(); } catch { return new List<Incident>(); } } private static void Handle(ZNetPeer peer, Snapshot snap) { string hostName = peer.m_socket.GetHostName(); string text = FileFor(hostName, snap.PlayerId); PlayerRecord playerRecord = null; if (File.Exists(text)) { try { playerRecord = JsonConvert.DeserializeObject<PlayerRecord>(File.ReadAllText(text)); } catch { } } if (snap.Kind == "arrive") { List<string> list = Judge(playerRecord, snap); Note($"{snap.Character} ({hostName}) arrived carrying {snap.Items.Sum((ItemEntry i) => i.Stack)} items" + ((list.Count > 0) ? (" - CHARGES: " + string.Join("; ", list)) : " - clean")); if (list.Count > 0) { Report(new Incident { When = DateTime.Now, Character = snap.Character, Host = hostName, Charges = list }); } } playerRecord = playerRecord ?? new PlayerRecord(); if (snap.Kind == "arrive") { if (playerRecord.OnlineSince.HasValue) { CloseSession(playerRecord, playerRecord.LastSeen, "no leave recorded"); } playerRecord.OnlineSince = DateTime.Now; playerRecord.Sessions++; playerRecord.FirstSeen = playerRecord.FirstSeen ?? DateTime.Now; OpenByPeer[peer.m_uid] = text; } else if (snap.Kind == "leave" && playerRecord.OnlineSince.HasValue) { CloseSession(playerRecord, DateTime.Now, "left"); OpenByPeer.Remove(peer.m_uid); } playerRecord.Host = hostName; playerRecord.Character = snap.Character; playerRecord.PlayerId = snap.PlayerId; playerRecord.LastSeen = DateTime.Now; playerRecord.UsedCheats = snap.UsedCheats; playerRecord.KnownWorlds = snap.KnownWorlds; playerRecord.KnownCommands = snap.KnownCommands; playerRecord.Stats = snap.Stats; playerRecord.Last = snap; File.WriteAllText(text, JsonConvert.SerializeObject((object)playerRecord, Json)); } private static void CloseSession(PlayerRecord rec, DateTime end, string how) { DateTime value = rec.OnlineSince.Value; double num = Math.Max(0.0, (end - value).TotalSeconds); rec.SecondsOnServer += num; rec.OnlineSince = null; try { if (!File.Exists(SessionsPath)) { File.WriteAllText(SessionsPath, "character,account,start,end,minutes,how" + Environment.NewLine); } File.AppendAllText(SessionsPath, $"{rec.Character},{rec.Host},{value:yyyy-MM-dd HH:mm:ss},{end:yyyy-MM-dd HH:mm:ss},{num / 60.0:0.0},{how}{Environment.NewLine}"); } catch { } } public static void OnDisconnect(ZNetPeer peer) { if (peer == null || !OpenByPeer.TryGetValue(peer.m_uid, out var value)) { return; } OpenByPeer.Remove(peer.m_uid); try { PlayerRecord playerRecord = JsonConvert.DeserializeObject<PlayerRecord>(File.ReadAllText(value)); if (playerRecord != null && playerRecord.OnlineSince.HasValue) { CloseSession(playerRecord, DateTime.Now, "disconnected"); File.WriteAllText(value, JsonConvert.SerializeObject((object)playerRecord, Json)); } } catch (Exception ex) { Plugin.Log.LogError((object)("Watch session: " + ex)); } } public static string PlaytimeReport() { List<(string, double, int, bool, float, DateTime?)> list = (from x in AllRecords().Select(delegate(PlayerRecord r) { double item = r.SecondsOnServer + (r.OnlineSince.HasValue ? (DateTime.Now - r.OnlineSince.Value).TotalSeconds : 0.0); float item2 = 0f; if (r.Stats != null) { r.Stats.TryGetValue("TimeInBase", out var value); r.Stats.TryGetValue("TimeOutOfBase", out var value2); item2 = value + value2; } return (Character: r.Character, s: item, Sessions: r.Sessions, Online: r.OnlineSince.HasValue, Life: item2, FirstSeen: r.FirstSeen); }) orderby x.s descending select x).ToList(); if (list.Count == 0) { return "No time recorded yet."; } return "Time on Blyss (since Blyssheim 0.4.3):\n" + string.Join("\n", list.Select<(string, double, int, bool, float, DateTime?), string>(((string Character, double s, int Sessions, bool Online, float Life, DateTime? FirstSeen) x) => string.Format("{0}: {1} in {2} session{3}{4}", x.Character, Span(x.s), x.Sessions, (x.Sessions == 1) ? "" : "s", x.Online ? " (online now)" : "") + ((x.Life > 0f) ? ("; character total, all worlds: " + Span(x.Life)) : ""))); static string Span(double s) { TimeSpan timeSpan = TimeSpan.FromSeconds(s); if (!(timeSpan.TotalHours >= 1.0)) { return $"{timeSpan.Minutes}m"; } return $"{(int)timeSpan.TotalHours}h {timeSpan.Minutes:00}m"; } } private static List<string> Judge(PlayerRecord rec, Snapshot now) { List<string> list = new List<string>(); bool flag = rec?.Last == null; Dictionary<string, int> before = (flag ? new Dictionary<string, int>() : rec.Last.Totals()); Dictionary<string, int> source = now.Totals(); int num = ((!flag) ? rec.Last.Items.Where((ItemEntry i) => i.Cheated).Sum((ItemEntry i) => i.Stack) : 0); List<string> list2 = (from i in now.Items where i.Cheated group i by i.Name into g select $"{g.Sum((ItemEntry i) => i.Stack)} {g.Key}").ToList(); if (list2.Count > 0 && now.Items.Where((ItemEntry i) => i.Cheated).Sum((ItemEntry i) => i.Stack) > num) { list.Add("carrying items made with cheats: " + string.Join(", ", list2)); } if (now.UsedCheats && (flag || !rec.UsedCheats)) { list.Add("this character has used cheats"); } List<string> list3 = now.KnownCommands.Except(flag ? new List<string>() : rec.KnownCommands).ToList(); if (list3.Count > 0) { list.Add("console commands used: " + string.Join(", ", list3)); } int value; List<string> list4 = (from kv in source select (Item: kv.Key, Gain: kv.Value - (before.TryGetValue(kv.Key, out value) ? value : 0), Boss: Contraband.BossNeeded(kv.Key)) into x where x.Gain > 0 && x.Boss != null select $"{x.Gain} {x.Item} (needs {x.Boss})").ToList(); if (list4.Count > 0) { list.Add("contraband: " + string.Join(", ", list4)); } if (!flag) { List<(string Item, int Gain)> list5 = (from kv in source select (Item: kv.Key, Gain: kv.Value - (before.TryGetValue(kv.Key, out value) ? value : 0)) into x where x.Gain > 0 && Contraband.BossNeeded(x.Item) == null select x).ToList(); int big = Math.Max(1, Settings.BigGainStacks.Value); List<(string, int)> list6 = list5.Where(((string Item, int Gain) x) => x.Gain >= big * MaxStack(x.Item)).ToList(); if (list6.Count > 0) { list.Add("came back with a big haul: " + string.Join(", ", list6.Select<(string, int), string>(((string Item, int Gain) x) => $"+{x.Gain} {x.Item}"))); } List<(string, int)> list7 = list5.Except<(string, int)>(list6).ToList(); if (list7.Count > 0 && (Settings.AlertOnAnyGain.Value || list.Count > 0)) { list.Add("also gained while away: " + string.Join(", ", list7.Select<(string, int), string>(((string Item, int Gain) x) => $"+{x.Gain} {x.Item}"))); } List<string> list8 = now.KnownWorlds.Except(rec.KnownWorlds).ToList(); if (list8.Count > 0 && list.Count > 0) { list.Add("visited other worlds since last time: " + string.Join(", ", list8)); } } return list; } private static int MaxStack(string item) { GameObject val = (Object.op_Implicit((Object)(object)ObjectDB.instance) ? ObjectDB.instance.GetItemPrefab(item) : null); ItemDrop val2 = (Object.op_Implicit((Object)(object)val) ? val.GetComponent<ItemDrop>() : null); if (!Object.op_Implicit((Object)(object)val2)) { return 50; } return Math.Max(1, val2.m_itemData.m_shared.m_maxStackSize); } private static void Report(Incident inc) { List<Incident> list = Incidents(); list.Add(inc); File.WriteAllText(IncidentsPath, JsonConvert.SerializeObject((object)list, Json)); string text = inc.Character + ": " + string.Join("\n", inc.Charges); foreach (ZNetPeer connectedPeer in ZNet.instance.GetConnectedPeers()) { if (ZNet.instance.IsAdmin(connectedPeer.m_socket.GetHostName())) { ZRoutedRpc.instance.InvokeRoutedRPC(connectedPeer.m_uid, "Blyssheim_Alert", new object[1] { text }); } } } public static void Log(string line) { Note(line); } private static void Note(string line) { Plugin.Log.LogInfo((object)("Watch: " + line)); try { File.AppendAllText(LogPath, $"{DateTime.Now:yyyy-MM-dd HH:mm:ss} {line}{Environment.NewLine}"); } catch { } } } [HarmonyPatch(typeof(ZNet), "Disconnect", new Type[] { typeof(ZNetPeer) })] internal static class SessionPatches { private static void Prefix(ZNetPeer peer) { if (Object.op_Implicit((Object)(object)ZNet.instance) && ZNet.instance.IsServer()) { ServerWatch.OnDisconnect(peer); } } } internal static class Settings { public static ConfigEntry<int> CheckpointSeconds; public static ConfigEntry<int> BigGainStacks; public static ConfigEntry<bool> AlertOnAnyGain; public static void Bind(ConfigFile cfg) { CheckpointSeconds = cfg.Bind<int>("Watch", "CheckpointSeconds", 20, "How often a player's game reports what they carry while playing, so a crash still leaves a recent record."); BigGainStacks = cfg.Bind<int>("Watch", "BigGainStacks", 2, "Server: coming back with this many more full stacks of one item than you left with counts as a charge."); AlertOnAnyGain = cfg.Bind<bool>("Watch", "AlertOnAnyGain", true, "Server: if true, any item gained while away is listed with the charges; if false, only gated, cheated or big gains are."); } } public class ItemEntry { public string Name; public int Stack; public int Quality; public bool Cheated; public string Crafter; } public class Snapshot { public const int Format = 1; public string Kind; public long PlayerId; public string Character; public bool UsedCheats; public List<string> KnownWorlds = new List<string>(); public List<string> KnownCommands = new List<string>(); public Dictionary<string, float> Stats = new Dictionary<string, float>(); public List<ItemEntry> Items = new List<ItemEntry>(); public Dictionary<string, int> Totals() { return (from i in Items group i by i.Name).ToDictionary((IGrouping<string, ItemEntry> g) => g.Key, (IGrouping<string, ItemEntry> g) => g.Sum((ItemEntry i) => i.Stack)); } public ZPackage ToPackage() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown ZPackage val = new ZPackage(); val.Write(1); val.Write(Kind ?? ""); val.Write(PlayerId); val.Write(Character ?? ""); val.Write(UsedCheats); WriteList(val, KnownWorlds); WriteList(val, KnownCommands); val.Write(Stats.Count); foreach (KeyValuePair<string, float> stat in Stats) { val.Write(stat.Key); val.Write(stat.Value); } val.Write(Items.Count); foreach (ItemEntry item in Items) { val.Write(item.Name ?? ""); val.Write(item.Stack); val.Write(item.Quality); val.Write(item.Cheated); val.Write(item.Crafter ?? ""); } return val; } public static Snapshot FromPackage(ZPackage p) { if (p.ReadInt() != 1) { return null; } Snapshot snapshot = new Snapshot { Kind = p.ReadString(), PlayerId = p.ReadLong(), Character = p.ReadString(), UsedCheats = p.ReadBool(), KnownWorlds = ReadList(p), KnownCommands = ReadList(p) }; int num = p.ReadInt(); for (int i = 0; i < num; i++) { snapshot.Stats[p.ReadString()] = p.ReadSingle(); } num = p.ReadInt(); for (int j = 0; j < num; j++) { snapshot.Items.Add(new ItemEntry { Name = p.ReadString(), Stack = p.ReadInt(), Quality = p.ReadInt(), Cheated = p.ReadBool(), Crafter = p.ReadString() }); } return snapshot; } private static void WriteList(ZPackage p, List<string> list) { p.Write(list.Count); foreach (string item in list) { p.Write(item ?? ""); } } private static List<string> ReadList(ZPackage p) { List<string> list = new List<string>(); int num = p.ReadInt(); for (int i = 0; i < num; i++) { list.Add(p.ReadString()); } return list; } } } namespace Blyssheim.Warden { internal static class WardenAccess { [HarmonyPatch(typeof(PrivateArea), "CheckAccess")] private static class Wards { private static void Postfix(ref bool __result) { if (!__result && Active()) { __result = true; } } } [HarmonyPatch(typeof(Container), "CheckAccess")] private static class PrivateChests { private static void Postfix(ref bool __result) { if (!__result && Active()) { __result = true; } } } [HarmonyPatch(typeof(Player), "OnSpawned")] private static class AskOnSpawn { private static void Postfix(Player __instance) { if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && Object.op_Implicit((Object)(object)ZNet.instance) && !ZNet.instance.IsServer()) { AdminConfirmed = false; WardenNet.AskServer("whoami", 0f); } } } public static bool AdminConfirmed; public static bool Active() { Player localPlayer = Player.m_localPlayer; if (AdminConfirmed && Object.op_Implicit((Object)(object)localPlayer)) { return WardenVisuals.IsWarden(((Component)localPlayer).GetComponent<VisEquipment>()); } return false; } } internal class WardenFX : MonoBehaviour { [HarmonyPatch(typeof(Player), "Awake")] private static class AttachToPlayers { private static void Postfix(Player __instance) { if (!Object.op_Implicit((Object)(object)((Component)__instance).GetComponent<WardenFX>())) { ((Component)__instance).gameObject.AddComponent<WardenFX>(); } } } public static readonly Dictionary<ZDOID, float> SirenUntil = new Dictionary<ZDOID, float>(); public static readonly Dictionary<ZDOID, (string Word, float Until)> Shamed = new Dictionary<ZDOID, (string, float)>(); private static readonly Color RuneDim = new Color(0.45f, 0.02f, 0.02f); private static readonly Color RuneBright = new Color(1f, 0.12f, 0.08f); private Player _player; private VisEquipment _vis; private GameObject _rig; private Transform _hips; private Transform _spine2; private Transform _head; private Transform _lFore; private Transform _lHand; private Transform _rFore; private Transform _rHand; private Transform _lUp; private Transform _lLeg; private Transform _lFoot; private Transform _rUp; private Transform _rLeg; private Transform _rFoot; private readonly List<(Transform T, Func<Vector3> Pos, Func<Quaternion> Rot)> _pieces = new List<(Transform, Func<Vector3>, Func<Quaternion>)>(); private readonly List<Material> _runeMats = new List<Material>(); private Light _chestLight; private Light _beaconLight; private Light _beaconSpot; private Transform _beacon; private Transform _spinner; private Material _beaconMat; private float _nextBubble; private Transform _helmModel; private List<GameObject> _clothes; private float _nextHelmLook; private static Material _unlit; private ZDOID Id { get { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)_player)) { return ZDOID.None; } return ((Character)_player).GetZDOID(); } } private void Awake() { _player = ((Component)this).GetComponent<Player>(); _vis = ((Component)this).GetComponent<VisEquipment>(); } private void LateUpdate() { //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Invalid comparison between Unknown and I4 //IL_01f4: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)_player)) { return; } bool flag = WardenVisuals.IsWarden(_vis); if (flag && !Object.op_Implicit((Object)(object)_rig)) { Build(); } if (!flag && Object.op_Implicit((Object)(object)_rig)) { Object.Destroy((Object)(object)_rig); _rig = null; _pieces.Clear(); _runeMats.Clear(); } if (!flag && Object.op_Implicit((Object)(object)_helmModel)) { Object.Destroy((Object)(object)((Component)_helmModel).gameObject); _helmModel = null; } if (!flag && _clothes != null) { foreach (GameObject clothe in _clothes) { if (Object.op_Implicit((Object)(object)clothe)) { Object.Destroy((Object)(object)clothe); } } _clothes = null; } if (flag && _clothes == null && (int)SystemInfo.graphicsDeviceType != 4) { _clothes = new List<GameObject>(); string[] array = new string[2] { "warden_coat", "warden_pants" }; foreach (string asset in array) { GameObject val = WardenSkinned.Attach(_vis, asset); if (Object.op_Implicit((Object)(object)val)) { _clothes.Add(val); } } if (Object.op_Implicit((Object)(object)_rig) && WardenSkinned.Has("warden_coat")) { Renderer[] componentsInChildren = _rig.GetComponentsInChildren<Renderer>(true); foreach (Renderer val2 in componentsInChildren) { if ((Object)(object)((Component)val2).transform != (Object)(object)_beacon) { val2.enabled = false; } } } } ZDOID id = Id; float value; bool siren = SirenUntil.TryGetValue(id, out value) && Time.time < value; if (Object.op_Implicit((Object)(object)_rig)) { Animate(siren); } Bubbles(id, siren); } private Transform Bone(string name) { Transform[] componentsInChildren = ((Component)this).GetComponentsInChildren<Transform>(true); foreach (Transform val in componentsInChildren) { if (((Object)val).name == name) { return val; } } return null; } private void Build() { //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Expected O, but got Unknown //IL_02e8: Unknown result type (might be due to invalid IL or missing references) //IL_02ed: Unknown result type (might be due to invalid IL or missing references) //IL_036d: Unknown result type (might be due to invalid IL or missing references) //IL_0372: Unknown result type (might be due to invalid IL or missing references) //IL_03cb: Unknown result type (might be due to invalid IL or missing references) //IL_03df: Unknown result type (might be due to invalid IL or missing references) //IL_0438: Unknown result type (might be due to invalid IL or missing references) //IL_047b: Unknown result type (might be due to invalid IL or missing references) //IL_0481: Expected O, but got Unknown //IL_04a8: Unknown result type (might be due to invalid IL or missing references) //IL_04d0: Unknown result type (might be due to invalid IL or missing references) _hips = Bone("Hips"); _spine2 = Bone("Spine2"); _head = Bone("Helmet_attach") ?? Bone("Head"); _lFore = Bone("LeftForeArm"); _lHand = Bone("LeftHand"); _rFore = Bone("RightForeArm"); _rHand = Bone("RightHand"); _lUp = Bone("LeftUpLeg"); _lLeg = Bone("LeftLeg"); _lFoot = Bone("LeftFoot"); _rUp = Bone("RightUpLeg"); _rLeg = Bone("RightLeg"); _rFoot = Bone("RightFoot"); if (!Object.op_Implicit((Object)(object)_hips) || !Object.op_Implicit((Object)(object)_spine2) || !Object.op_Implicit((Object)(object)_head)) { return; } _rig = new GameObject("BlyssheimWardenRig"); _rig.transform.SetParent(((Component)this).transform, false); Transform root = ((Component)this).transform; AddRune(() => Vector3.Lerp(_lFore.position, _lHand.position, 0.45f) - root.right * 0.1f, () => Quaternion.LookRotation(-root.right), 1f); AddRune(() => Vector3.Lerp(_rFore.position, _rHand.position, 0.45f) + root.right * 0.1f, () => Quaternion.LookRotation(root.right), 1f); (Transform, Transform, Transform)[] array = new(Transform, Transform, Transform)[2] { (_lUp, _lLeg, _lFoot), (_rUp, _rLeg, _rFoot) }; for (int num = 0; num < array.Length; num++) { (Transform, Transform, Transform) tuple = array[num]; Transform item = tuple.Item1; Transform item2 = tuple.Item2; Transform item3 = tuple.Item3; Transform u = item; Transform k = item2; Transform f = item3; AddRune(() => Vector3.Lerp(u.position, k.position, 0.55f) + root.forward * 0.1f, () => root.rotation, 1f); AddRune(() => Vector3.Lerp(k.position, f.position, 0.4f) + root.forward * 0.09f, () => root.rotation, 0.9f); } Transform val = Primitive((PrimitiveType)2, new Vector3(0.11f, 0.004f, 0.11f), RuneDim); _pieces.Add((val, () => _spine2.position + root.forward * 0.26f + root.up * 0.03f, () => root.rotation * Quaternion.Euler(90f, 0f, 0f))); AddRune(() => _spine2.position + root.forward * 0.27f + root.up * 0.03f, () => root.rotation, 1.3f); _chestLight = AddLight(val, (LightType)2, 1.4f, 0.6f); Transform val2 = Primitive((PrimitiveType)3, new Vector3(0.05f, 0.08f, 0.05f), RuneDim); _pieces.Add((val2, () => _hips.position + root.right * 0.25f + root.forward * 0.1f - root.up * 0.05f, () => root.rotation)); AddLight(val2, (LightType)2, 0.9f, 0.4f); _beacon = Primitive((PrimitiveType)2, new Vector3(0.09f, 0.045f, 0.09f), new Color(0.3f, 0.02f, 0.02f)); _beaconMat = ((Component)_beacon).GetComponent<Renderer>().material; _pieces.Add((_beacon, () => (!Object.op_Implicit((Object)(object)_helmModel)) ? (_head.position + root.up * 0.1f) : _helmModel.TransformPoint(0f, 1.28f, 0f), () => root.rotation)); _spinner = new GameObject("spinner").transform; _spinner.SetParent(_beacon, false); _beaconLight = AddLight(_beacon, (LightType)2, 4f, 0f); GameObject val3 = new GameObject("spot"); val3.transform.SetParent(_spinner, false); val3.transform.localRotation = Quaternion.Euler(10f, 0f, 0f); _beaconSpot = val3.AddComponent<Light>(); _beaconSpot.type = (LightType)0; _beaconSpot.color = RuneBright; _beaconSpot.range = 14f; _beaconSpot.spotAngle = 45f; _beaconSpot.intensity = 0f; } private static Material Unlit(Color c) { //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Expected O, but got Unknown //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Expected O, but got Unknown if (!Object.op_Implicit((Object)(object)_unlit)) { Shader[] array = Resources.FindObjectsOfTypeAll<Shader>(); Shader val = null; string[] array2 = new string[3] { "Standard", "Unlit/Color", "Sprites/Default" }; foreach (string want in array2) { val = Array.Find(array, (Shader s) => Object.op_Implicit((Object)(object)s) && ((Object)s).name == want) ?? Shader.Find(want); if (Object.op_Implicit((Object)(object)val)) { break; } } _unlit = new Material(val); Plugin.Log.LogInfo((object)("Warden glow shader: " + (Object.op_Implicit((Object)(object)val) ? ((Object)val).name : "none"))); } Material val2 = new Material(_unlit); if (val2.HasProperty("_EmissionColor")) { val2.EnableKeyword("_EMISSION"); } SetGlow(val2, c, 1.5f); return val2; } private static void SetGlow(Material m, Color c, float brightness) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) if (m.HasProperty("_EmissionColor")) { m.color = c * 0.35f; m.SetColor("_EmissionColor", c * brightness); } else { m.color = c; } } private Transform Primitive(PrimitiveType type, Vector3 scale, Color color) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_002e: 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) GameObject obj = GameObject.CreatePrimitive(type); Object.Destroy((Object)(object)obj.GetComponent<Collider>()); obj.transform.SetParent(_rig.transform, false); obj.transform.localScale = scale; Material val = Unlit(color); obj.GetComponent<Renderer>().material = val; obj.GetComponent<Renderer>().shadowCastingMode = (ShadowCastingMode)0; _runeMats.Add(val); return obj.transform; } private void AddRune(Func<Vector3> pos, Func<Quaternion> rot, float size) { //IL_0005: 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_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) Transform transform = new GameObject("rune").transform; transform.SetParent(_rig.transform, false); float[] array = new float[2] { 40f, -40f }; foreach (float num in array) { Transform obj = Primitive((PrimitiveType)3, new Vector3(0.011f * size, 0.07f * size, 0.004f), RuneDim); obj.SetParent(transform, false); obj.localRotation = Quaternion.Euler(0f, 0f, num); } _pieces.Add((transform, pos, rot)); } private Light AddLight(Transform at, LightType type, float range, float intensity) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("light"); val.transform.SetParent(at, false); Light obj = val.AddComponent<Light>(); obj.type = type; obj.color = RuneBright; obj.range = range; obj.intensity = intensity; obj.shadows = (LightShadows)0; return obj; } private void Animate(bool siren) { //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_01cb: Unknown result type (might be due to invalid IL or missing references) //IL_0284: Unknown result type (might be due to invalid IL or missing references) //IL_0224: Unknown result type (might be due to invalid IL or missing references) //IL_02a8: Unknown result type (might be due to invalid IL or missing references) //IL_02ad: Unknown result type (might be due to invalid IL or missing references) //IL_030f: Unknown result type (might be due to invalid IL or missing references) //IL_02e2: Unknown result type (might be due to invalid IL or missing references) //IL_0341: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)_helmModel) && Time.time > _nextHelmLook) { _nextHelmLook = Time.time + 1f; if (Object.op_Implicit((Object)(object)_head)) { _helmModel = WardenModels.PinTo(_head, "helm"); } if (Object.op_Implicit((Object)(object)_helmModel) && Object.op_Implicit((Object)(object)_beacon)) { ((Component)_beacon).GetComponent<Renderer>().enabled = false; } } foreach (var (val, func, func2) in _pieces) { if (Object.op_Implicit((Object)(object)val)) { val.position = func(); val.rotation = func2(); } } float num = (siren ? 6f : 2f); float num2 = 0.5f + 0.5f * Mathf.Sin(Time.time * num); float brightness = (siren ? (3f + 5f * num2) : (1.2f + 2.8f * num2)); foreach (Material runeMat in _runeMats) { if (Object.op_Implicit((Object)(object)runeMat) && (Object)(object)runeMat != (Object)(object)_beaconMat) { SetGlow(runeMat, RuneBright, brightness); } } if (Object.op_Implicit((Object)(object)_chestLight)) { _chestLight.intensity = 0.3f + 0.7f * num2 * (siren ? 2f : 1f); } if (Object.op_Implicit((Object)(object)_beaconMat)) { SetGlow(_beaconMat, RuneBright, siren ? (6f + 6f * num2) : 0.4f); } if (Object.op_Implicit((Object)(object)_spinner)) { _spinner.localRotation = Quaternion.Euler(0f, siren ? (Time.time * 540f % 360f) : 0f, 0f); } if (Object.op_Implicit((Object)(object)_beaconSpot)) { _beaconSpot.intensity = (siren ? 6f : 0f); } if (Object.op_Implicit((Object)(object)_beaconLight)) { _beaconLight.intensity = (siren ? (1.5f + 2.5f * num2) : 0f); } Color val2 = Color.white * (siren ? (3f + 6f * num2) : (0.8f + 1.4f * num2)); if (Object.op_Implicit((Object)(object)_helmModel) && Object.op_Implicit((Object)(object)WardenModels.Helm?.Material)) { WardenModels.Helm.Material.SetColor("_EmissionColor", val2); } if (Object.op_Implicit((Object)(object)WardenModels.Club?.Material)) { WardenModels.Club.Material.SetColor("_EmissionColor", val2); } foreach (Material value in WardenSkinned.Materials.Values) { if (Object.op_Implicit((Object)(object)value)) { value.SetColor("_EmissionColor", val2); } } } private void Bubbles(ZDOID id, bool siren) { //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_003f: 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_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)Chat.instance) || Time.time < _nextBubble) { return; } (string, float) value; if (siren) { if (Mathf.FloorToInt(Time.time * 2f) % 2 == 0) { Chat.instance.SetNpcText(((Component)this).gameObject, Vector3.up * 2.3f, 40f, 0.5f, "", "<color=#ff3030>WEE WOO</color>", true); } _nextBubble = Time.time + 0.5f; } else if (Shamed.TryGetValue(id, out value) && Time.time < value.Item2) { Chat.instance.SetNpcText(((Component)this).gameObject, Vector3.up * 2.3f, 40f, 2.2f, "", "<color=#ff3030>" + value.Item1 + "</color>", true); _nextBubble = Time.time + 2f; } } } internal static class WardenItems { public const string Regalia = "BH_WardenRegalia"; public const string Helm = "BH_WardenHelm"; public const string Legs = "BH_WardenLegs"; public const string Club = "BH_WardenClub"; public static ConfigEntry<string> Tint; private static readonly Dictionary<Material, Material> Cache = new Dictionary<Material, Material>(); public static int RegaliaHash => StringExtensionMethods.GetStableHashCode("BH_WardenRegalia"); public static int HelmHash => StringExtensionMethods.GetStableHashCode("BH_WardenHelm"); public static int LegsHash => StringExtensionMethods.GetStableHashCode("BH_WardenLegs"); public static void Init(ConfigFile cfg) { Tint = cfg.Bind<string>("Realm Warden", "Tint", "#6E4636", "Colour multiplied into the Warden's armour (hex). Darker = closer to the concept art's leather and iron."); WardenModels.Bind(cfg); PrefabManager.OnVanillaPrefabsAvailable += Add; } private static void Add() { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Expected O, but got Unknown //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) PrefabManager.OnVanillaPrefabsAvailable -= Add; Color val2 = default(Color); Color val = (Color)(ColorUtility.TryParseHtmlString(Tint.Value, ref val2) ? val2 : new Color(0.43f, 0.27f, 0.21f)); AddArmour("BH_WardenRegalia", "ArmorCarapaceChest", "Realm Warden Regalia", "The full uniform of the Realm Warden. Same laws, different shores: contraband is contraband.", val); AddArmour("BH_WardenHelm", "HelmetCarapace", "Realm Warden Beacon Hat", "Worn with the Regalia.", val); AddArmour("BH_WardenLegs", "ArmorCarapaceLegs", "Realm Warden Greaves", "Worn with the Regalia.", val); CustomItem val3 = new CustomItem("BH_WardenClub", "Club"); SharedData shared = val3.ItemDrop.m_itemData.m_shared; shared.m_name = "Warden's Billy Club"; shared.m_description = "Does no harm. Staggers the guilty and marks them OFFENDER for all to see."; shared.m_damages = default(DamageTypes); shared.m_attackForce = 120f; shared.m_useDurability = false; Recolour(val3.ItemPrefab, val * 0.8f); WardenModels.Apply(val3.ItemPrefab, "club"); SetIcon(shared, "icon_club"); ItemManager.Instance.AddItem(val3); WardenSearch.AddPrefab(); Plugin.Log.LogInfo((object)"Realm Warden items added."); } private static void AddArmour(string name, string basePrefab, string display, string description, Color tint) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Invalid comparison between Unknown and I4 //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Expected O, but got Unknown CustomItem val = new CustomItem(name, basePrefab); SharedData shared = val.ItemDrop.m_itemData.m_shared; shared.m_name = display; shared.m_description = description; shared.m_setName = ""; shared.m_setSize = 0; shared.m_equipStatusEffect = null; shared.m_useDurability = false; if (Object.op_Implicit((Object)(object)shared.m_armorMaterial)) { shared.m_armorMaterial = Tinted(shared.m_armorMaterial, tint); } if (name == "BH_WardenRegalia" && WardenSkinned.Has("warden_coat") && (int)SystemInfo.graphicsDeviceType != 4) { shared.m_armorMaterial = null; Renderer[] componentsInChildren = val.ItemPrefab.GetComponentsInChildren<Renderer>(true); foreach (Renderer val2 in componentsInChildren) { if ((Object)(object)((Component)val2).transform != (Object)(object)val.ItemPrefab.transform && (Object)(object)((Component)val2).transform.parent != (Object)(object)val.ItemPrefab.transform) { val2.enabled = false; } } foreach (Transform item in val.ItemPrefab.transform) { Transform val3 = item; if (((Object)val3).name.StartsWith("attach")) { componentsInChildren = ((Component)val3).GetComponentsInChildren<Renderer>(true); for (int i = 0; i < componentsInChildren.Length; i++) { componentsInChildren[i].enabled = false; } } } } Recolour(val.ItemPrefab, tint); if (name == "BH_WardenRegalia") { SetIcon(shared, "icon_regalia"); } ItemManager.Instance.AddItem(val); } private static void SetIcon(SharedData s, string asset) { Sprite val = WardenModels.LoadIcon(asset); if (Object.op_Implicit((Object)(object)val)) { s.m_icons = (Sprite[])(object)new Sprite[1] { val }; } } private static void Recolour(GameObject prefab, Color tint) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) Renderer[] componentsInChildren = prefab.GetComponentsInChildren<Renderer>(true); foreach (Renderer val in componentsInChildren) { if (!(val is ParticleSystemRenderer)) { val.sharedMaterials = val.sharedMaterials.Select((Material m) => (!Object.op_Implicit((Object)(object)m)) ? m : Tinted(m, tint)).ToArray(); } } } private static Material Tinted(Material m, Color tint) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) if (Cache.TryGetValue(m, out var value)) { return value; } Material val = new Material(m) { name = ((Object)m).name + "_warden" }; if (val.HasProperty("_Color")) { val.color *= tint; } Cache[m] = val; return val; } } internal class ModelPlacer : MonoBehaviour { public string Key; private void Start() { if (Key != null && WardenModels.Parts.TryGetValue(Key, out var value)) { WardenModels.Place(((Component)this).transform, value); } } } internal static class WardenModels { public class Part { public string Asset; public string ChildName; public ConfigEntry<string> Offset; public ConfigEntry<string> Rotation; public ConfigEntry<float> Size; public ConfigEntry<string> Stretch; public Material Material; public GameObject TemplateObject; } public static readonly Dictionary<string, Part> Parts = new Dictionary<string, Part>(); public static ConfigEntry<float> Brightness; public static ConfigEntry<float> Shine; public static ConfigEntry<float> Contrast; private static readonly Dictionary<Texture2D, Color32[]> Originals = new Dictionary<Texture2D, Color32[]>(); private static float _appliedContrast = 1f; private static readonly List<Material> AllMaterials = new List<Material>(); public static Part Helm { get { if (!Parts.TryGetValue("helm", out var value)) { return null; } return value; } } public static Part Club { get { if (!Parts.TryGetValue("club", out var value)) { return null; } return value; } } private static string AssetsDir => Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)Plugin.Instance).Info.Location), "assets"); public static void Bind(ConfigFile cfg) { Add(cfg, "helm", "warden_helm", "0,-0.1525,-0.002", "0,0,0", 0.3352f, "Helmet model on the head (offset x,y,z metres; y is up)", "Helmet width in metres"); Add(cfg, "club", "warden_club", "0.02,-0.04,-0.18", "90,0,0", 0.136f, "Billy club model in the hand (offset x,y,z metres)", "Club thickness in metres"); Brightness = cfg.Bind<float>("Realm Warden Model", "Brightness", 0.5f, "Multiplies the colour of the Warden models (1 = as textured; lower = darker). The wardenlook command changes it live."); Shine = cfg.Bind<float>("Realm Warden Model", "Shine", 0.3f, "How shiny the Warden models are (0 = matte, 1 = polished)."); Contrast = cfg.Bind<float>("Realm Warden Model", "Contrast", 1.5f, "Contrast of the Warden models' colours (1 = as textured; higher = punchier darks and lights; lower = flatter)."); } public static void ApplyLook() { foreach (Material allMaterial in AllMaterials) { if (Object.op_Implicit((Object)(object)allMaterial)) { Look(allMaterial); } } if (Mathf.Approximately(_appliedContrast, Contrast.Value)) { return; } foreach (Texture2D key in Originals.Keys) { Recontrast(key); } _appliedContrast = Contrast.Value; } private static void Recontrast(Texture2D tex) { //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)tex) && Originals.TryGetValue(tex, out var value)) { float value2 = Contrast.Value; byte[] array = new byte[256]; for (int i = 0; i < 256; i++) { array[i] = (byte)Mathf.Clamp(Mathf.RoundToInt(((float)i - 128f) * value2 + 128f), 0, 255); } Color32[] array2 = (Color32[])(object)new Color32[value.Length]; for (int j = 0; j < value.Length; j++) { Color32 val = value[j]; array2[j] = new Color32(array[val.r], array[val.g], array[val.b], val.a); } tex.SetPixels32(array2); tex.Apply(true); } } private static void Look(Material m) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) m.color = new Color(Brightness.Value, Brightness.Value, Brightness.Value, 1f); m.SetFloat("_Glossiness", Shine.Value); m.SetFloat("_Metallic", 0f); } private static void Add(ConfigFile cfg, string key, string asset, string offset, string rotation, float size, string what, string sizeWhat) { string text = "Realm Warden Model"; string text2 = char.ToUpper(key[0]) + key.Substring(1); Parts[key] = new Part { Asset = asset, ChildName = "Blyssheim_" + asset, Offset = cfg.Bind<string>(text, text2 + "Offset", offset, what + "."), Rotation = cfg.Bind<string>(text, text2 + "Rotation", rotation, text2 + " model rotation (degrees x,y,z)."), Size = cfg.Bind<float>(text, text2 + "Scale", size, sizeWhat + "."), Stretch = cfg.Bind<string>(text, text2 + "Stretch", "1,1,1", text2 + " model stretch: width, height, depth multipliers (1 = unchanged).") }; } public static Vector3 ParseVec(string s) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) string[] p = s.Split(','); return new Vector3(F(0), F(1), F(2)); float F(int i) { if (p.Length <= i || !float.TryParse(p[i].Trim(), NumberStyles.Float, CultureInfo.InvariantCulture, out var result)) { return 0f; } return result; } } public static void Apply(GameObject prefab, string key) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Invalid comparison between Unknown and I4 //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) if ((int)SystemInfo.graphicsDeviceType == 4) { return; } Part part = Parts[key]; Mesh val = LoadMesh(Path.Combine(AssetsDir, part.Asset + ".bhm")); if ((Object)(object)val == (Object)null) { Plugin.Log.LogWarning((object)("Model " + part.Asset + " not found; keeping the vanilla look.")); return; } Transform val2 = prefab.transform.Find("attach"); if (!Object.op_Implicit((Object)(object)val2)) { Plugin.Log.LogWarning((object)(((Object)prefab).name + " has no 'attach'; keeping the vanilla look.")); return; } Renderer[] componentsInChildren = ((Component)val2).GetComponentsInChildren<Renderer>(true); for (int i = 0; i < componentsInChildren.Length; i++) { componentsInChildren[i].enabled = false; } foreach (Transform item in val2) { ((Component)item).gameObject.SetActive(false); } part.Material = BuildMaterial(part.Asset); GameObject val3 = new GameObject(part.ChildName); val3.transform.SetParent(val2, false); val3.AddComponent<MeshFilter>().sharedMesh = val; ((Renderer)val3.AddComponent<MeshRenderer>()).sharedMaterial = part.Material; val3.AddComponent<ModelPlacer>().Key = key; Place(val3.transform, part); Plugin.Log.LogInfo((object)$"Model {part.Asset} on {((Object)prefab).name} ({val.triangles.Length / 3} triangles; attach scale {val2.lossyScale})."); } public static GameObject Template(string key) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Invalid comparison between Unknown and I4 //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Expected O, but got Unknown Part part = Parts[key]; if (Object.op_Implicit((Object)(object)part.TemplateObject)) { return part.TemplateObject; } if ((int)SystemInfo.graphicsDeviceType == 4) { return null; } Mesh val = LoadMesh(Path.Combine(AssetsDir, part.Asset + ".bhm")); if ((Object)(object)val == (Object)null) { Plugin.Log.LogWarning((object)("Model " + part.Asset + " not found.")); return null; } part.Material = (Object.op_Implicit((Object)(object)part.Material) ? part.Material : BuildMaterial(part.Asset)); GameObject val2 = new GameObject(part.ChildName); val2.SetActive(false); Object.DontDestroyOnLoad((Object)(object)val2); val2.AddComponent<MeshFilter>().sharedMesh = val; ((Renderer)val2.AddComponent<MeshRenderer>()).sharedMaterial = part.Material; val2.AddComponent<ModelPlacer>().Key = key; part.TemplateObject = val2; Plugin.Log.LogInfo((object)$"Model {part.Asset} ready to pin ({val.triangles.Length / 3} triangles)."); return val2; } public static Transform PinTo(Transform bone, string key) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown Part part = Parts[key]; foreach (Transform item in bone) { Transform val = item; if (((Object)val).name.StartsWith(part.ChildName)) { return val; } } GameObject val2 = Template(key); if (!Object.op_Implicit((Object)(object)val2)) { return null; } GameObject obj = Object.Instantiate<GameObject>(val2, bone, false); ((Object)obj).name = part.ChildName; obj.SetActive(true); Place(obj.transform, part); return obj.transform; } public static void Place(Transform t, Part part) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_000d: 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_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //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) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) Vector3 val = (Object.op_Implicit((Object)(object)t.parent) ? t.parent.lossyScale : Vector3.one); float num = (Mathf.Approximately(val.x, 0f) ? 1f : (1f / val.x)); t.localPosition = ParseVec(part.Offset.Value) * num; t.localRotation = Quaternion.Euler(ParseVec(part.Rotation.Value)); Vector3 val2 = ParseVec(part.Stretch.Value); if (val2 == Vector3.zero) { val2 = Vector3.one; } t.localScale = Vector3.Scale(val2, Vector3.one * part.Size.Value * num); } public static void PlaceAll(Part part) { Transform[] array = Resources.FindObjectsOfTypeAll<Transform>(); foreach (Transform val in array) { if (Object.op_Implicit((Object)(object)val) && ((Object)val).name.StartsWith(part.ChildName)) { Place(val, part); } } } private static Mesh LoadMesh(string path) { //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Expected O, but got Unknown if (!File.Exists(path)) { return null; } BinaryReader r = new BinaryReader(File.OpenRead(path)); try { if (new string(r.ReadChars(4)) != "BHM1") { return null; } int num = r.ReadInt32(); int num2 = r.ReadInt32(); Vector3[] vertices = V(num); Vector3[] normals = V(num); Vector2[] array = (Vector2[])(object)new Vector2[num]; for (int i = 0; i < num; i++) { array[i] = new Vector2(r.ReadSingle(), r.ReadSingle()); } int[] array2 = new int[num2]; for (int j = 0; j < num2; j++) { array2[j] = r.ReadInt32(); } Mesh val = new Mesh { name = Path.GetFileNameWithoutExtension(path) }; if (num > 65000) { val.indexFormat = (IndexFormat)1; } val.vertices = vertices; val.normals = normals; val.uv = array; val.triangles = array2; val.RecalculateBounds(); val.RecalculateTangents(); return val; } finally { if (r != null) { ((IDisposable)r).Dispose(); } } Vector3[] V(int count) { //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) Vector3[] array3 = (Vector3[])(object)new Vector3[count]; for (int k = 0; k < count; k++) { array3[k] = new Vector3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle()); } return array3; } } private static Texture2D LoadTexture(string path, bool linear) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown //IL_0022: Expected O, but got Unknown if (!File.Exists(path)) { return null; } Texture2D val = new Texture2D(2, 2, (TextureFormat)4, true, linear); ImageConversion.LoadImage(val, File.ReadAllBytes(path)); return val; } private static Texture2D ToNormalMap(Texture2D src) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: 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: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected O, but got Unknown Color32[] pixels = src.GetPixels32(); for (int i = 0; i < pixels.Length; i++) { Color32 val = pixels[i]; pixels[i] = new Color32(byte.MaxValue, val.g, val.g, val.r); } Texture2D val2 = new Texture2D(((Texture)src).width, ((Texture)src).height, (TextureFormat)4, true, true); val2.SetPixels32(pixels); val2.Apply(true); Object.Destroy((Object)(object)src); return val2; } public static Material BuildMaterialFor(string name) { return BuildMaterial(name); } public static Sprite LoadIcon(string name) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Invalid comparison between Unknown and I4 //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) if ((int)SystemInfo.graphicsDeviceType == 4) { return null; } Texture2D val = LoadTexture(Path.Combine(AssetsDir, name + ".png"), linear: false); if (!Object.op_Implicit((Object)(object)val)) { return null; } ((Texture)val).wrapMode = (TextureWrapMode)1; return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f); } private static Material BuildMaterial(string name) { //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_0044: Expected O, but got Unknown //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) Material val = new Material(Array.Find(Resources.FindObjectsOfTypeAll<Shader>(), (Shader s) => Object.op_Implicit((Object)(object)s) && ((Object)s).name == "Standard") ?? Shader.Find("Standard")) { name = name }; Texture2D val2 = LoadTexture(Path.Combine(AssetsDir, name + "_color.png"), linear: false); if (Object.op_Implicit((Object)(object)val2)) { Originals[val2] = val2.GetPixels32(); if (!Mathf.Approximately(Contrast.Value, 1f)) { Recontrast(val2); } _appliedContrast = Contrast.Value; val.SetTexture("_MainTex", (Texture)(object)val2); } Texture2D val3 = LoadTexture(Path.Combine(AssetsDir, name + "_normal.png"), linear: true); if (Object.op_Implicit((Object)(object)val3)) { val.SetTexture("_BumpMap", (Texture)(object)ToNormalMap(val3)); val.EnableKeyword("_NORMALMAP"); } Texture2D val4 = LoadTexture(Path.Combine(AssetsDir, name + "_glow.png"), linear: false); if (Object.op_Implicit((Object)(object)val4)) { val.SetTexture("_EmissionMap", (Texture)(object)val4); val.EnableKeyword("_EMISSION"); val.SetColor("_EmissionColor", Color.white * 1.5f); } Look(val); AllMaterials.Add(val); return val; } } internal static class WardenNet { [HarmonyPatch(typeof(Humanoid), "StartAttack")] private static class ClubSwing { private static void Postfix(Humanoid __instance, bool __result) { //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Expected O, but got Unknown if (__result && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer)) { ItemData currentWeapon = __instance.GetCurrentWeapon(); if (!((Object)(object)currentWeapon?.m_dropPrefab == (Object)null) && !(((Object)currentWeapon.m_dropPrefab).name != "BH_WardenClub")) { ((MonoBehaviour)Plugin.Instance).StartCoroutine(Bonk((Player)__instance)); } } } } private class WardenCommand : ConsoleCommand { public override string Name => "warden"; public override string Help => "Admins: receive the Realm Warden Regalia and billy club."; public override void Run(string[] args) { AskServer("warden", 0f); } } private class ModelCommand : ConsoleCommand { private readonly string _key; public override string Name => "warden" + _key; public override string Help => "Adjust the Warden " + _key + " model live: warden" + _key + " <x> <y> <z> [size] [rotX rotY rotZ] (no arguments shows the current values)"; public ModelCommand(string key) { _key = key; } public override void Run(string[] args) { WardenModels.Part part = WardenModels.Parts[_key]; CultureInfo invariantCulture = CultureInfo.InvariantCulture; if (args.Length >= 3) { part.Offset.Value = args[0] + "," + args[1] + "," + args[2]; } if (args.Length >= 4 && float.TryParse(args[3], NumberStyles.Float, invariantCulture, out var result)) { part.Size.Value = result; } if (args.Length >= 7) { part.Rotation.Value = args[4] + "," + args[5] + "," + args[6]; } WardenModels.PlaceAll(part); Console.instance.Print("warden" + _key + " " + part.Offset.Value.Replace(",", " ") + " " + part.Size.Value.ToString("0.###", invariantCulture) + " " + part.Rotation.Value.Replace(",", " ")); } } private class DebugCommand : ConsoleCommand { public override string Name => "wardendebug"; public override string Help => "Writes what is attached to your head (and where) to the log, for fixing the Warden helmet."; public override void Run(string[] args) { //IL_0066: 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) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if (!Object.op_Implicit((Object)(object)localPlayer)) { return; } Transform val = Array.Find(((Component)localPlayer).GetComponentsInChildren<Transform>(true), (Transform t) => ((Object)t).name == "Helmet_attach"); if (!Object.op_Implicit((Object)(object)val)) { Console.instance.Print("No Helmet_attach found."); return; } ManualLogSource log = Plugin.Log; object[] obj = new object[4] { val.position, val.lossyScale, null, null }; Quaternion rotation = val.rotation; obj[2] = ((Quaternion)(ref rotation)).eulerAngles; obj[3] = ((Component)localPlayer).transform.position; log.LogInfo((object)string.Format("wardendebug: Helmet_attach world={0} lossyScale={1} rot={2} player={3}", obj)); Transform[] componentsInChildren = ((Component)val).GetComponentsInChildren<Transform>(true); foreach (Transform val2 in componentsInChildren) { Renderer component = ((Component)val2).GetComponent<Renderer>(); MeshFilter component2 = ((Component)val2).GetComponent<MeshFilter>(); ManualLogSource log2 = Plugin.Log; string text = $" {((Object)val2).name} active={((Component)val2).gameObject.activeInHierarchy} local={val2.localPosition} scale={val2.localScale} lossy={val2.lossyScale} layer={((Component)val2).gameObject.layer}"; object obj2; if (!Object.op_Implicit((Object)(object)component)) { obj2 = ""; } else { object[] obj3 = new object[5] { ((object)component).GetType().Name, component.enabled, null, null, null }; Bounds bounds = component.bounds; obj3[2] = ((Bounds)(ref bounds)).center; bounds = component.bounds; obj3[3] = ((Bounds)(ref bounds)).size; obj3[4] = (Object.op_Implicit((Object)(object)component.sharedMaterial) ? ((Object)component.sharedMaterial.shader).name : "none"); obj2 = string.Format(" renderer={0} enabled={1} bounds={2}/{3} shader={4}", obj3); } log2.LogInfo((object)(text + (string?)obj2 + (Object.op_Implicit((Object)(object)component2) ? (" mesh=" + (Object.op_Implicit((Object)(object)component2.sharedMesh) ? (((Object)component2.sharedMesh).name + " v" + component2.sharedMesh.vertexCount) : "none")) : ""))); } Console.instance.Print("Written to the log."); } } private class StretchCommand : ConsoleCommand { public override string Name => "wardenstretch"; public override string Help => "Stretch a Warden model: wardenstretch <helm|club> <width> <height> <depth> (1 = unchanged; e.g. wardenstretch helm 1 1.15 1)"; public override void Run(string[] args) { if (args.Length < 1 || !WardenModels.Parts.TryGetValue(args[0], out var value)) { Console.instance.Print(((ConsoleCommand)this).Help); return; } if (args.Length >= 4) { value.Stretch.Value = args[1] + "," + args[2] + "," + args[3]; } WardenModels.PlaceAll(value); Console.instance.Print("wardenstretch " + args[0] + " " + value.Stretch.Value.Replace(",", " ")); } } private class LookCommand : ConsoleCommand { public override string Name => "wardenlook"; public override string Help => "Adjust how the Warden models look: wardenlook <brightness> [shine] [contrast] (1 = as textured; no arguments shows the current values)"; public override void Run(string[] args) { CultureInfo invariantCulture = CultureInfo.InvariantCulture; if (args.Length >= 1 && float.TryParse(args[0], NumberStyles.Float, invariantCulture, out var result)) { WardenModels.Brightness.Value = result; } if (args.Length >= 2 && float.TryParse(args[1], NumberStyles.Float, invariantCulture, out var result2)) { WardenModels.Shine.Value = result2; } if (args.Length >= 3 && float.TryParse(args[2], NumberStyles.Float, invariantCulture, out var result3)) { WardenModels.Contrast.Value = result3; } WardenModels.ApplyLook(); Console.instance.Print("wardenlook " + WardenModels.Brightness.Value.ToString("0.##", invariantCulture) + " " + WardenModels.Shine.Value.ToString("0.##", invariantCulture) + " " + WardenModels.Contrast.Value.ToString("0.##", invariantCulture)); } } private class PlaytimeCommand : ConsoleCommand { public override string Name => "playtime"; public override string Help => "Admins: time each character has spent on this server."; public override void Run(string[] args) { AskServer("playtime", 0f); } } private class SirenCommand : ConsoleCommand { public override string Name => "siren"; public override string Help => "Admins: set off the Realm Warden siren (test). Optional seconds."; public override void Run(string[] args) { AskServer("siren", (args.Length != 0 && float.TryParse(args[0], out var result)) ? result : SirenSeconds.Value); } } public const string SirenRpc = "Blyssheim_Siren"; public const string ShameRpc = "Blyssheim_Shame"; public static ConfigEntry<float> SirenSeconds; public static ConfigEntry<float> ShameSeconds; public static ConfigEntry<string> ShameWord; public static ConfigEntry<KeyboardShortcut> SirenKey; public const string AskRpc = "Blyssheim_AdminAsk"; public const string GrantRpc = "Blyssheim_AdminGrant"; public const string InfoRpc = "Blyssheim_Info"; public static void Init(ConfigFile cfg) { //IL_006f: Unknown result type (might be due to invalid IL or missing references) SirenSeconds = cfg.Bind<float>("Realm Warden", "SirenSeconds", 20f, "How long the siren (spinning beacon, WEE WOO) goes off after a catch."); ShameSeconds = cfg.Bind<float>("Realm Warden", "ShameSeconds", 60f, "How long OFFENDER stays over someone hit with the billy club."); ShameWord = cfg.Bind<string>("Realm Warden", "ShameWord", "OFFENDER", "The word over their head (try SHAME)."); SirenKey = cfg.Bind<KeyboardShortcut>("Realm Warden", "SirenKey", new KeyboardShortcut((KeyCode)121, Array.Empty<KeyCode>()), "While wearing the Regalia: press to switch the siren (beacon and WEE WOO) on, again to switch it off."); Alerts.OnContraband += delegate { OnCatch(); }; CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new WardenCommand()); CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new SirenCommand()); CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new ModelCommand("helm")); CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new ModelCommand("club")); CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new DebugCommand()); CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new LookCommand()); CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new StretchCommand()); CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new PlaytimeCommand()); } public static void Register() { ZRoutedRpc.instance.Register<ZDOID, float>("Blyssheim_Siren", (Action<long, ZDOID, float>)delegate(long sender, ZDOID id, float secs) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) if (secs <= 0f) { WardenFX.SirenUntil.Remove(id); } else { WardenFX.SirenUntil[id] = Time.time + secs; } }); ZRoutedRpc.instance.Register<ZDOID, string, float>("Blyssheim_Shame", (Action<long, ZDOID, string, float>)OnShame); ZRoutedRpc.instance.Register<string, float>("Blyssheim_AdminAsk", (Action<long, string, float>)OnAsk); ZRoutedRpc.instance.Register<string, float, bool>("Blyssheim_AdminGrant", (Action<long, string, float, bool>)OnGrant); WardenSearch.Register(); ZRoutedRpc.instance.Register<string>("Blyssheim_Info", (Action<long, string>)delegate(long sender, string text) { if (Object.op_Implicit((Object)(object)Console.instance)) { string[] array = text.Split('\n'); foreach (string text2 in array) { Console.instance.Print(text2); } } if (Object.op_Implicit((Object)(object)Chat.instance)) { ((Terminal)Chat.instance).AddString("<color=#ffcc66>Blyssheim</color>", text, (Type)0, true); } }); } public static void AskServer(string action, float arg) { if (Object.op_Implicit((Object)(object)ZNet.instance) && ZNet.instance.IsServer()) { OnGrant(0L, action, arg, ok: true); return; } ZRoutedRpc.instance.InvokeRoutedRPC(Rpc.ServerPeerId(), "Blyssheim_AdminAsk", new object[2] { action, arg }); } private static void OnAsk(long sender, string action, float arg) { if (Object.op_Implicit((Object)(object)ZNet.instance) && ZNet.instance.IsServer()) { ZNetPeer peer = ZNet.instance.GetPeer(sender); bool flag = peer != null && ZNet.instance.IsAdmin(peer.m_socket.GetHostName()); if (action == "playtime") { ZRoutedRpc.instance.InvokeRoutedRPC(sender, "Blyssheim_Info", new object[1] { flag ? ServerWatch.PlaytimeReport() : "Only admins can see playtime." }); return; } ZRoutedRpc.instance.InvokeRoutedRPC(sender, "Blyssheim_AdminGrant", new object[3] { action, arg, flag }); } } private static void OnGrant(long sender, string action, float arg, bool ok) { if (action == "whoami") { WardenAccess.AdminConfirmed = ok; return; } Player localPlayer = Player.m_localPlayer; if (!Object.op_Implicit((Object)(object)localPlayer)) { return; } if (!ok) { Say("Only admins can be the Realm Warden."); return; } if (!(action == "warden")) { if (action == "siren") { Siren(arg); } return; } string[] array = new string[2] { "BH_WardenRegalia", "BH_WardenClub" }; foreach (string text in array) { GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(text); if (Object.op_Implicit((Object)(object)itemPrefab)) { ((Humanoid)localPlayer).GetInventory().AddItem(itemPrefab, 1); } } Say("The Realm Warden is on duty."); static void Say(string s) { if (Object.op_Implicit((Object)(object)Console.instance)) { Console.instance.Print(s); } if (Object.op_Implicit((Object)(object)MessageHud.instance)) { MessageHud.instance.ShowMessage((MessageType)1, s, 0, (Sprite)null, false, true); } } } private static void OnCatch() { Player localPlayer = Player.m_localPlayer; if (!Object.op_Implicit((Object)(object)localPlayer)) { return; } ItemData val = ((IEnumerable<ItemData>)((Humanoid)localPlayer).GetInventory().GetAllItems()).FirstOrDefault((Func<ItemData, bool>)((ItemData i) => Object.op_Implicit((Object)(object)i.m_dropPrefab) && ((Object)i.m_dropPrefab).name == "BH_WardenRegalia")); if (val != null) { if (!((Humanoid)localPlayer).IsItemEquiped(val)) { ((Humanoid)localPlayer).EquipItem(val, true); } Siren(SirenSeconds.Value); } } public static void Siren(float seconds) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if (Object.op_Implicit((Object)(object)localPlayer)) { ZRoutedRpc.instance.InvokeRoutedRPC(0L, "Blyssheim_Siren", new object[2] { ((Character)localPlayer).GetZDOID(), seconds }); } } public static void Tick() { //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_0065: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if (Object.op_Implicit((Object)(object)localPlayer)) { KeyboardShortcut value = SirenKey.Value; if (((KeyboardShortcut)(ref value)).IsDown() && (!Object.op_Implicit((Object)(object)Chat.instance) || !Chat.instance.HasFocus()) && !Console.IsVisible() && !TextInput.IsVisible() && !Menu.IsVisible() && WardenVisuals.IsWarden(((Component)localPlayer).GetComponent<VisEquipment>())) { Siren((WardenFX.SirenUntil.TryGetValue(((Character)localPlayer).GetZDOID(), out var value2) && Time.time < value2) ? 0f : 3600f); } } } private static void OnShame(long sender, ZDOID id, string word, float seconds) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) WardenFX.Shamed[id] = (word, Time.time + seconds); Player localPlayer = Player.m_localPlayer; if (Object.op_Implicit((Object)(object)localPlayer) && ((Character)localPlayer).GetZDOID() == id && Object.op_Implicit((Object)(object)MessageHud.instance)) { MessageHud.instance.ShowMessage((MessageType)2, "<color=#ff3030>" + word + "</color>", 0, (Sprite)null, false, true); } } private static IEnumerator Bonk(Player warden) { yield return (object)new WaitForSeconds(0.35f); if (!Object.op_Implicit((Object)(object)warden)) { yield break; } Vector3 val = ((Component)warden).transform.position + Vector3.up; foreach (Player allPlayer in Player.GetAllPlayers()) { if (!Object.op_Implicit((Object)(object)allPlayer) || (Object)(object)allPlayer == (Object)(object)warden || ((Character)allPlayer).IsDead()) { continue; } Vector3 val2 = ((Component)allPlayer).transform.position + Vector3.up - val; if (!(((Vector3)(ref val2)).magnitude > 2.8f) && !(Vector3.Angle(((Component)warden).transform.forward, new Vector3(val2.x, 0f, val2.z)) > 70f)) { ((Character)allPlayer).Stagger(((Vector3)(ref val2)).normalized); ZRoutedRpc.instance.InvokeRoutedRPC(0L, "Blyssheim_Shame", new object[3] { ((Character)allPlayer).GetZDOID(), ShameWord.Value, ShameSeconds.Value }); if (WardenAccess.Active()) { WardenSearch.Request(allPlayer); break; } } } } } internal static class WardenSearch { [HarmonyPatch(typeof(ItemDrop), "DropItem")] private static class NoCopiesOnTheGround { private static void Postfix(ItemData item, ItemDrop __result) { if (Object.op_Implicit((Object)(object)__result) && MarkOf(item) != null) { ZNetScene.instance.Destroy(((Component)__result).gameObject); } } } public const string Prefab = "BH_EvidenceView"; private const string Marker = "blyssheim_evidence"; private const string SearchReq = "Blyssheim_SearchReq"; private const string Search = "Blyssheim_Search"; private const string SearchResult = "Blyssheim_SearchResult"; private const string SearchView = "Blyssheim_SearchView"; private const string SeizeReq = "Blyssheim_SeizeReq"; private const string Seize = "Blyssheim_Seize"; private static Container _view; private static long _target; private static string _targetName; private static readonly Dictionary<string, (string Name, int X, int Y, int Stack)> Mirror = new Dictionary<string, (string, int, int, int)>(); private static bool IsServer { get { if (Object.op_Implicit((Object)(object)ZNet.instance)) { return ZNet.instance.IsServer(); } return false; } } private static long Server => Rpc.ServerPeerId(); public static void AddPrefab() { GameObject val = PrefabManager.Instance.CreateClonedPrefab("BH_EvidenceView", "piece_chest_wood"); if (!Object.op_Implicit((Object)(object)val)) { Plugin.Log.LogWarning((object)"Evidence window: could not clone a chest."); return; } WearNTear[] componentsInChildren = val.GetComponentsInChildren<WearNTear>(true); for (int i = 0; i < componentsInChildren.Length; i++) { Object.DestroyImmediate((Object)(object)componentsInChildren[i]); } Renderer[] componentsInChildren2 = val.GetComponentsInChildren<Renderer>(true); for (int i = 0; i < componentsInChildren2.Length; i++) { componentsInChildren2[i].enabled = false; } Collider[] componentsInChildren3 = val.GetComponentsInChildren<Collider>(true); for (int i = 0; i < componentsInChildren3.Length; i++) { componentsInChildren3[i].enabled = false; } ZNetView component = val.GetComponent<ZNetView>(); if (Object.op_Implicit((Object)(object)component)) { component.m_persistent = false; } Container component2 = val.GetComponent<Container>(); component2.m_width = 8; component2.m_height = 5; component2.m_name = "Evidence"; PrefabManager.Instance.AddPrefab(val); } public static void Register() { ZRoutedRpc instance = ZRoutedRpc.instance; instance.Register<ZPackage>("Blyssheim_SearchReq", (Action<long, ZPackage>)OnSearchReq); instance.Register<ZPackage>("Blyssheim_Search", (Action<long, ZPackage>)OnSearch); instance.Register<ZPackage>("Blyssheim_SearchResult", (Action<long, ZPackage>)OnSearchResult); instance.Register<ZPackage>("Blyssheim_SearchView", (Action<long, ZPackage>)OnSearchView); instance.Register<ZPackage>("Blyssheim_SeizeReq", (Action<long, ZPackage>)OnSeizeReq); instance.Register<ZPackage>("Blyssheim_Seize", (Action<long, ZPackage>)OnSeize); } private static bool SenderIsAdmin(long sender) { ZNetPeer peer = ZNet.instance.GetPeer(sender); if (peer != null) { return ZNet.instance.IsAdmin(peer.m_socket.GetHostName()); } return false; } public static void Request(Player target) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)target) && !IsServer && !Object.op_Implicit((Object)(object)_view)) { ZPackage val = new ZPackage(); ZDOID zDOID = ((Character)target).GetZDOID(); val.Write(((ZDOID)(ref zDOID)).UserID); ZRoutedRpc.instance.InvokeRoutedRPC(Server, "Blyssheim_SearchReq", new object[1] { val }); } } private static void OnSearchReq(long sender, ZPackage p) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown if (IsServer && SenderIsAdmin(sender)) { long num = p.ReadLong(); ZPackage val = new ZPackage(); val.Write(sender); ZRoutedRpc.instance.InvokeRoutedRPC(num, "Blyssheim_Search", new object[1] { val }); } } private static void OnSearch(long sender, ZPackage p) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected O, but got Unknown if (!IsServer && sender == Server && Object.op_Implicit((Object)(object)Player.m_localPlayer)) { long num = p.ReadLong(); ZPackage val = new ZPackage(); ((Humanoid)Player.m_localPlayer).GetInventory().Save(val); ZPackage val2 = new ZPackage(); val2.Write(num); val2.Write(Player.m_localPlayer.GetPlayerName()); val2.Write(val); ZRoutedRpc.instance.InvokeRoutedRPC(Server, "Blyssheim_SearchResult", new object[1] { val2 }); if (Object.op_Implicit((Object)(object)MessageHud.instance)) { MessageHud.instance.ShowMessage((MessageType)2, "<color=#ff4040>The Realm Warden searched you.</color>", 0, (Sprite)null, false, true); } } } private static void OnSearchResult(long sender, ZPackage p) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown if (IsServer) { long num = p.ReadLong(); string text = p.ReadString(); ZPackage val = p.ReadPackage(); if (SenderIsAdmin(num)) { ZPackage val2 = new ZPackage(); val2.Write(sender); val2.Write(text); val2.Write(val); ZRoutedRpc.instance.InvokeRoutedRPC(num, "Blyssheim_SearchView", new object[1] { val2 }); ServerWatch.Log(text + " was searched by the Realm Warden"); } } } private static void OnSearchView(long sender, ZPackage p) { //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) if (IsServer || sender != Server || !Object.op_Implicit((Object)(object)Player.m_localPlayer) || Object.op_Implicit((Object)(object)_view)) { return; } _target = p.ReadLong(); _targetName = p.ReadString(); ZPackage val = p.ReadPackage(); Player localPlayer = Player.m_localPlayer; GameObject prefab = ZNetScene.instance.GetPrefab("BH_EvidenceView"); if (!Object.op_Implicit((Object)(object)prefab)) { return; } _view = Object.Instantiate<GameObject>(prefab, ((Component)localPlayer).transform.position, Quaternion.identity).GetComponent<Container>(); _view.m_name = "Evidence: " + _targetName; Inventory inventory = _view.GetInventory(); inventory.Load(val); Mirror.Clear(); int num = 0; foreach (ItemData allItem in inventory.GetAllItems()) { string text = "e" + num++; allItem.m_customData = allItem.m_customData ?? new Dictionary<string, string>(); allItem.m_customData["blyssheim_evidence"] = text; Mirror[text] = (Object.op_Implicit((Object)(object)allItem.m_dropPrefab) ? ((Object)allItem.m_dropPrefab).name : allItem.m_shared.m_name, allItem.m_gridPos.x, allItem.m_gridPos.y, allItem.m_stack); } inventory.m_onChanged = (Action)Delegate.Combine(inventory.m_onChanged, new Action(OnViewChanged)); InventoryGui.instance.Show(_view, 1); } private static string MarkOf(ItemData it) { if (it?.m_customData == null || !it.m_customData.TryGetValue("blyssheim_evidence", out var value)) { return null; } return value; } private static void OnViewChanged() { //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Expected O, but got Unknown //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_0194: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)_view)) { return; } Dictionary<string, int> dictionary = (from i in _view.GetInventory().GetAllItems() where MarkOf(i) != null select i).GroupBy(MarkOf).ToDictionary((IGrouping<string, ItemData> g) => g.Key, (IGrouping<string, ItemData> g) => g.Sum((ItemData i) => i.m_stack)); foreach (string item in Mirror.Keys.ToList()) { (string, int, int, int) tuple = Mirror[item]; dictionary.TryGetValue(item, out var value); if (value < tuple.Item4) { int num = tuple.Item4 - value; Mirror[item] = (tuple.Item1, tuple.Item2, tuple.Item3, value); ZPackage val = new ZPackage(); val.Write(_target); val.Write(tuple.Item1); val.Write(tuple.Item2); val.Write(tuple.Item3); val.Write(num); val.Write(((Component)Player.m_localPlayer).transform.position + ((Component)Player.m_localPlayer).transform.forward * 0.8f + Vector3.up * 0.5f); ZRoutedRpc.instance.InvokeRoutedRPC(Server, "Blyssheim_SeizeReq", new object[1] { val }); } } } public static void Tick() { //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if (!Object.op_Implicit((Object)(object)localPlayer)) { return; } Inventory inventory = ((Humanoid)localPlayer).GetInventory(); foreach (ItemData item in (from i in inventory.GetAllItems() where MarkOf(i) != null select i).ToList()) { inventory.RemoveItem(item); } if (!Object.op_Implicit((Object)(object)_view) || (Object.op_Implicit((Object)(object)InventoryGui.instance) && InventoryGui.IsVisible() && (Object)/*isinst with value type is only supported in some contexts*/ == (Object)(object)_view)) { return; } foreach (ItemData item2 in (from i in _view.GetInventory().GetAllItems() where MarkOf(i) == null select i).ToList()) { _view.GetInventory().RemoveItem(item2); if (!inventory.AddItem(item2)) { ItemDrop.DropItem(item2, item2.m_stack, ((Component)localPlayer).transform.position + Vector3.up, Quaternion.identity); } } Inventory inventory2 = _view.GetInventory(); inventory2.m_onChanged = (Action)Delegate.Remove(inventory2.m_onChanged, new Action(OnViewChanged)); ZNetScene.instance.Destroy(((Component)_view).gameObject); _view = null; Mirror.Clear(); } private static void OnSeizeReq(long sender, ZPackage p) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown resu