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 Warband v1.3.0
plugins/Warband/Warband.dll
Decompiled 2 days ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Splatform; using TMPro; using UnityEngine; using UnityEngine.Rendering; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: AssemblyVersion("0.0.0.0")] namespace Warband; internal static class Compass { private class Marker { public GameObject Go; public RectTransform Root; public Image Icon; public TextMeshProUGUI Text; public float Size; } private static bool _looked; private static FieldInfo _instanceField; private static FieldInfo _stripField; private static MethodInfo _getFont; private static readonly Dictionary<long, Marker> Markers = new Dictionary<long, Marker>(); private static readonly MethodInfo GetSprite = AccessTools.Method(typeof(Minimap), "GetSprite", (Type[])null, (Type[])null); private static void Look() { if (!_looked) { _looked = true; Type type = AccessTools.TypeByName("NavCompass.NavCompassPlugin"); if (type == null) { Plugin.Debug("[compass] Nav Compass not installed"); return; } _instanceField = AccessTools.Field(type, "_instance"); _stripField = AccessTools.Field(type, "_stripRect"); _getFont = AccessTools.Method(type, "GetFont", (Type[])null, (Type[])null); Plugin.Debug("[compass] Nav Compass found (" + (_instanceField != null) + "/" + (_stripField != null) + "/" + (_getFont != null) + ")"); } } private static RectTransform Strip(out object compass) { compass = null; Look(); if (_instanceField == null || _stripField == null) { return null; } compass = _instanceField.GetValue(null); if (compass == null) { return null; } object? value = _stripField.GetValue(compass); return (RectTransform)((value is RectTransform) ? value : null); } internal static void LateUpdate() { //IL_0053: 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_007d: 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_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: Unknown result type (might be due to invalid IL or missing references) //IL_0212: Unknown result type (might be due to invalid IL or missing references) object compass; RectTransform val = ((Plugin.CompassEnabled.Value && Party.InParty) ? Strip(out compass) : null); compass = null; if ((Object)(object)val == (Object)null || (Object)(object)Player.m_localPlayer == (Object)null || (Object)(object)GameCamera.instance == (Object)null) { HideAll(); return; } Vector3 forward = ((Component)GameCamera.instance).transform.forward; float num = Mathf.Atan2(forward.x, forward.z) * 57.29578f; Vector3 position = ((Component)Player.m_localPlayer).transform.position; float value = Plugin.CompassMaxDistance.Value; long me = Party.Me; List<long> list = new List<long>(); foreach (Member member in Party.Members) { if (member.Peer == me || !Ui.AllyPosition(member, out var pos)) { continue; } float num2 = Vector3.Distance(position, pos); if (value > 0f && num2 > value) { continue; } if (!Markers.TryGetValue(member.Peer, out var value2) || (Object)(object)value2.Go == (Object)null || (Object)(object)((Transform)value2.Root).parent != (Object)(object)val) { if (value2 != null && (Object)(object)value2.Go != (Object)null) { Object.Destroy((Object)(object)value2.Go); } value2 = Create(val, member.Name); Markers[member.Peer] = value2; } list.Add(member.Peer); float num3 = Mathf.Atan2(pos.x - position.x, pos.z - position.z) * 57.29578f; float num4 = Mathf.DeltaAngle(num, num3); bool flag = Mathf.Abs(num4) <= 90f; if (value2.Go.activeSelf != flag) { value2.Go.SetActive(flag); } if (flag) { value2.Root.anchoredPosition = new Vector2(num4 / 90f * 240f, 0f); ((Graphic)value2.Icon).color = Looks.ColorOf(member); string text = Looks.Initial(member.Name); if (((TMP_Text)value2.Text).text != text) { ((TMP_Text)value2.Text).text = text; } float value3 = Plugin.CompassIconSize.Value; if (value2.Size != value3) { Resize(value2, value3); } } } List<long> list2 = null; foreach (KeyValuePair<long, Marker> marker2 in Markers) { if (!list.Contains(marker2.Key)) { if (list2 == null) { list2 = new List<long>(); } list2.Add(marker2.Key); } } if (list2 == null) { return; } foreach (long item in list2) { Marker marker = Markers[item]; if ((Object)(object)marker.Go != (Object)null) { Object.Destroy((Object)(object)marker.Go); } Markers.Remove(item); } } private static Sprite PlayerSprite() { if ((Object)(object)Minimap.instance == (Object)null || GetSprite == null) { return null; } try { object? obj = GetSprite.Invoke(Minimap.instance, new object[1] { (object)(PinType)10 }); return (Sprite)((obj is Sprite) ? obj : null); } catch (Exception) { return null; } } private static void HideAll() { if (Markers.Count == 0) { return; } foreach (Marker value in Markers.Values) { if ((Object)(object)value.Go != (Object)null) { Object.Destroy((Object)(object)value.Go); } } Markers.Clear(); } private static Marker Create(RectTransform strip, string name) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected O, but got Unknown //IL_0073: 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) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0080: 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_0083: 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_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Expected O, but got Unknown //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Expected O, but got Unknown //IL_0229: Unknown result type (might be due to invalid IL or missing references) //IL_023d: Unknown result type (might be due to invalid IL or missing references) //IL_0249: Unknown result type (might be due to invalid IL or missing references) //IL_0257: Unknown result type (might be due to invalid IL or missing references) //IL_025c: Unknown result type (might be due to invalid IL or missing references) //IL_025d: Unknown result type (might be due to invalid IL or missing references) //IL_0264: Unknown result type (might be due to invalid IL or missing references) Marker marker = new Marker(); marker.Go = new GameObject("WarbandAlly_" + name, new Type[1] { typeof(RectTransform) }); marker.Go.transform.SetParent((Transform)(object)strip, false); marker.Root = marker.Go.GetComponent<RectTransform>(); RectTransform root = marker.Root; RectTransform root2 = marker.Root; Vector2 val = (marker.Root.pivot = new Vector2(0.5f, 0.5f)); Vector2 anchorMin = (root2.anchorMax = val); root.anchorMin = anchorMin; GameObject val4 = new GameObject("Icon", new Type[1] { typeof(RectTransform) }); val4.transform.SetParent(marker.Go.transform, false); marker.Icon = val4.AddComponent<Image>(); marker.Icon.sprite = Looks.CircleSprite; marker.Icon.preserveAspect = true; ((Graphic)marker.Icon).raycastTarget = false; RectTransform component = val4.GetComponent<RectTransform>(); component.anchorMin = Vector2.zero; component.anchorMax = Vector2.one; Vector2 offsetMin = (component.offsetMax = Vector2.zero); component.offsetMin = offsetMin; GameObject val5 = new GameObject("Initial", new Type[1] { typeof(RectTransform) }); val5.transform.SetParent(marker.Go.transform, false); marker.Text = val5.AddComponent<TextMeshProUGUI>(); Strip(out var compass); TMP_FontAsset val6 = null; try { if (_getFont != null && compass != null) { object? obj = _getFont.Invoke(compass, null); val6 = (TMP_FontAsset)((obj is TMP_FontAsset) ? obj : null); } } catch (Exception ex) { Plugin.Debug("[compass] font: " + ex.Message); } if ((Object)(object)val6 != (Object)null) { ((TMP_Text)marker.Text).font = val6; } ((TMP_Text)marker.Text).fontStyle = (FontStyles)1; ((TMP_Text)marker.Text).alignment = (TextAlignmentOptions)514; ((TMP_Text)marker.Text).textWrappingMode = (TextWrappingModes)0; ((Graphic)marker.Text).raycastTarget = false; ((Graphic)marker.Text).color = new Color(0.1f, 0.07f, 0.04f, 1f); RectTransform component2 = val5.GetComponent<RectTransform>(); component2.anchorMin = Vector2.zero; component2.anchorMax = Vector2.one; Vector2 offsetMin2 = (component2.offsetMax = Vector2.zero); component2.offsetMin = offsetMin2; Resize(marker, Plugin.CompassIconSize.Value); Plugin.Debug("[compass] marker made for " + name); return marker; } private static void Resize(Marker mk, float size) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) mk.Size = size; mk.Root.sizeDelta = new Vector2(size, size); ((TMP_Text)mk.Text).fontSize = size * 0.62f; } } internal class Friend { public string Id = ""; public string Name = ""; } internal static class Friends { internal static readonly List<Friend> List = new List<Friend>(); private static string FilePath => Path.Combine(Path.Combine(Paths.ConfigPath, "Warband"), "friends.txt"); internal static void Load() { List.Clear(); try { if (!File.Exists(FilePath)) { return; } string[] array = File.ReadAllLines(FilePath); foreach (string text in array) { if (text.Trim().Length != 0 && !text.StartsWith("#")) { string[] array2 = text.Split('\t'); Friend friend = new Friend(); if (array2.Length >= 2) { friend.Id = array2[0].Trim(); friend.Name = array2[1].Trim(); } else { friend.Name = array2[0].Trim(); } if (friend.Name.Length > 0 || friend.Id.Length > 0) { List.Add(friend); } } } } catch (Exception ex) { Plugin.Log.LogWarning((object)("Could not read the friends list: " + ex.Message)); } } internal static void Save() { try { Directory.CreateDirectory(Path.GetDirectoryName(FilePath)); List<string> list = new List<string>(); list.Add("# Warband friends: one per line, platform id <TAB> name. The id can be empty."); foreach (Friend item in List) { list.Add(item.Id + "\t" + item.Name); } File.WriteAllLines(FilePath, list.ToArray()); } catch (Exception ex) { Plugin.Log.LogWarning((object)("Could not save the friends list: " + ex.Message)); } } internal static Friend Find(string id, string name) { foreach (Friend item in List) { if (id.Length > 0 && item.Id == id) { return item; } } foreach (Friend item2 in List) { if (string.Equals(item2.Name, name, StringComparison.OrdinalIgnoreCase)) { return item2; } } return null; } internal static bool IsFriend(string id, string name) { return Find(id, name) != null; } internal static void Add(string id, string name) { Friend friend = Find(id, name); if (friend != null) { if (friend.Id.Length == 0 && id.Length > 0) { friend.Id = id; Save(); } } else { friend = new Friend(); friend.Id = id; friend.Name = name; List.Add(friend); Save(); Plugin.Message(name + " added to your friends"); } } internal static void Remove(Friend f) { List.Remove(f); Save(); Plugin.Message(f.Name + " removed from your friends"); } internal static void Refresh(List<Party.Online> online) { bool flag = false; foreach (Party.Online item in online) { Friend friend = Find(item.UserId, item.Name); if (friend != null) { if (friend.Id.Length == 0 && item.UserId.Length > 0) { friend.Id = item.UserId; flag = true; } if (friend.Name != item.Name && item.Name.Length > 0) { friend.Name = item.Name; flag = true; } } } if (flag) { Save(); } } } internal static class Gift { private class Outgoing { public int Id; public long To; public string ToName = ""; public ItemData Item; public string Prefab = ""; public int Stack; public int Quality; public int Variant; public float Durability; public float At; public bool Sent; public ZPackage Backup; } private class Incoming { public int Id; public long From; public string FromName = ""; public string Prefab = ""; public string Label = ""; public int Stack; public int Quality; public float At; } internal const string Rpc = "Warband_Gift"; private const int Offer = 0; private const int Accept = 1; private const int Decline = 2; private const int Deliver = 3; private const int Got = 4; private const int WhyDeclined = 0; private const int WhyFull = 1; private const int WhyBusy = 2; private const int WhyFar = 3; private const int WhyTimeout = 4; private const int WhyGone = 5; private const float OfferTimeout = 30f; private const float DeliverTimeout = 20f; private static readonly List<Outgoing> Out = new List<Outgoing>(); private static Incoming _offer; private static ItemData _picking; private static Rect _pickRect; private static int _nextId = Random.Range(1, 1000000); internal static bool HasOffer => _offer != null; internal static void Update() { //IL_015a: 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_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01d5: Unknown result type (might be due to invalid IL or missing references) float time = Time.time; for (int num = Out.Count - 1; num >= 0; num--) { Outgoing outgoing = Out[num]; if (!outgoing.Sent && time - outgoing.At > 35f) { Out.RemoveAt(num); Plugin.Message(outgoing.ToName + " didn't answer: the " + Name(outgoing.Prefab) + " stays with you"); } else if (outgoing.Sent && time - outgoing.At > 20f && Party.FindOnline(outgoing.To) == null) { Out.RemoveAt(num); GiveBack(outgoing, outgoing.ToName + " left before getting it"); } else if (outgoing.Sent && time - outgoing.At > 120f) { Out.RemoveAt(num); } } if (_offer != null && time - _offer.At > 30f) { Answer(_offer, 2, 4); Plugin.Message("You let the offer from " + _offer.FromName + " pass"); _offer = null; } if ((Object)(object)Player.m_localPlayer == (Object)null || Plugin.Typing()) { _picking = null; return; } if (!InventoryGui.IsVisible()) { _picking = null; } else { KeyboardShortcut value = Plugin.SendKey.Value; if (((KeyboardShortcut)(ref value)).IsDown()) { ItemData val = Hovered(); if (val == null) { Plugin.Message("Hover an item in your bag to send it"); } else { StartPicking(val); } } } if (_picking != null && Input.GetKeyDown((KeyCode)27)) { _picking = null; } if (_offer == null || Party.HasPendingInvite || Ui.PanelOpen) { return; } KeyboardShortcut value2 = Plugin.AcceptKey.Value; if (((KeyboardShortcut)(ref value2)).IsDown()) { TakeOffer(); return; } KeyboardShortcut value3 = Plugin.DeclineKey.Value; if (((KeyboardShortcut)(ref value3)).IsDown()) { Answer(_offer, 2, 0); Plugin.Message("You declined the " + _offer.Label); _offer = null; } } private static ItemData Hovered() { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) InventoryGui instance = InventoryGui.instance; if ((Object)(object)instance == (Object)null || (Object)(object)instance.m_playerGrid == (Object)null) { return null; } Vector3 mousePosition = Input.mousePosition; return instance.m_playerGrid.GetItem(new Vector2i((int)mousePosition.x, (int)mousePosition.y)); } private static void StartPicking(ItemData item) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) if (!Party.InParty) { Plugin.Message("You are not in a party"); return; } Player localPlayer = Player.m_localPlayer; if (((Humanoid)localPlayer).IsItemEquiped(item)) { Plugin.Message("Unequip the " + Label(item) + " first"); return; } _picking = item; Vector3 mousePosition = Input.mousePosition; _pickRect = new Rect(Mathf.Clamp(mousePosition.x + 24f, 10f, (float)Screen.width - 290f), Mathf.Clamp((float)Screen.height - mousePosition.y - 20f, 10f, (float)Screen.height - 300f), 280f, 0f); } private static void SendOffer(ItemData item, Member to) { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || item == null || !((Humanoid)localPlayer).GetInventory().ContainsItem(item)) { return; } if ((Object)(object)item.m_dropPrefab == (Object)null) { Plugin.Message("This item can't be sent"); return; } float num = Ui.Distance(to); if (num < 0f || num > Plugin.SendRange.Value) { Plugin.Message(to.Name + " is too far (they must be within " + Plugin.SendRange.Value.ToString("0") + " m)"); return; } foreach (Outgoing item2 in Out) { if (item2.Item == item) { Plugin.Message("You already offered that to " + item2.ToName); return; } } Outgoing outgoing = new Outgoing(); outgoing.Id = _nextId++; outgoing.To = to.Peer; outgoing.ToName = to.Name; outgoing.Item = item; outgoing.Prefab = ((Object)item.m_dropPrefab).name; outgoing.Stack = item.m_stack; outgoing.Quality = item.m_quality; outgoing.Variant = item.m_variant; outgoing.Durability = item.m_durability; outgoing.At = Time.time; Outgoing outgoing2 = outgoing; Out.Add(outgoing2); ZPackage val = Head(0, outgoing2.Id); val.Write(Party.MyName()); val.Write(outgoing2.Prefab); val.Write(Label(item)); val.Write(outgoing2.Stack); val.Write(outgoing2.Quality); Send(outgoing2.To, val); Plugin.Message("You offer " + Label(item) + " to " + to.Name); Plugin.Debug("[gift] offer #" + outgoing2.Id + " " + outgoing2.Stack + "x " + outgoing2.Prefab + " q" + outgoing2.Quality + " to " + to.Name); } private static void OnAccept(long from, int id) { //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Expected O, but got Unknown Outgoing outgoing = Find(id, from); if (outgoing == null || outgoing.Sent) { return; } Player localPlayer = Player.m_localPlayer; Inventory val = (((Object)(object)localPlayer != (Object)null) ? ((Humanoid)localPlayer).GetInventory() : null); ItemData item = outgoing.Item; string text = null; if (val == null || !val.ContainsItem(item)) { text = "it's no longer in your bag"; } else if (item.m_stack != outgoing.Stack || item.m_quality != outgoing.Quality || item.m_variant != outgoing.Variant) { text = "it changed since you offered it"; } else if (((Humanoid)localPlayer).IsItemEquiped(item)) { text = "you are using it"; } else { Member member = Party.Get(from); float num = ((member != null) ? Ui.Distance(member) : (-1f)); if (num < 0f || num > Plugin.SendRange.Value + 5f) { text = outgoing.ToName + " walked too far away"; } } if (text != null) { Out.Remove(outgoing); Answer(from, id, 2, 0); Plugin.Message("Not sent: " + text); return; } ZPackage val2 = Pack(item); val.RemoveItem(item); outgoing.Sent = true; outgoing.At = Time.time; outgoing.Backup = new ZPackage(val2.GetArray()); ZPackage val3 = Head(3, id); val3.Write(val2); Send(from, val3); Plugin.Message(outgoing.ToName + " took the " + Name(outgoing.Prefab)); Plugin.Debug("[gift] #" + id + " sent to " + outgoing.ToName); } private static void OnGot(long from, int id) { Outgoing outgoing = Find(id, from); if (outgoing != null) { Out.Remove(outgoing); } Plugin.Debug("[gift] #" + id + " arrived"); } private static void OnDeclined(long from, int id, int why) { Outgoing outgoing = Find(id, from); if (outgoing == null) { return; } Out.Remove(outgoing); if (outgoing.Sent) { GiveBack(outgoing, outgoing.ToName + " couldn't take it"); return; } string text = Name(outgoing.Prefab); switch (why) { case 1: Plugin.Message(outgoing.ToName + "'s bag is full: the " + text + " stays with you"); break; case 2: Plugin.Message(outgoing.ToName + " is answering another offer, try again in a moment"); break; case 3: Plugin.Message(outgoing.ToName + " is too far away"); break; case 4: Plugin.Message(outgoing.ToName + " didn't answer: the " + text + " stays with you"); break; default: Plugin.Message(outgoing.ToName + " declined the " + text); break; } } private static void GiveBack(Outgoing o, string why) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown //IL_004d: 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_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) if (o.Backup == null) { return; } ItemData val = Unpack(new ZPackage(o.Backup.GetArray())); Player localPlayer = Player.m_localPlayer; if (val != null && !((Object)(object)localPlayer == (Object)null)) { if (!((Humanoid)localPlayer).GetInventory().AddItem(val)) { ItemDrop.DropItem(val, val.m_stack, ((Component)localPlayer).transform.position + ((Component)localPlayer).transform.forward + Vector3.up, Quaternion.identity); } Plugin.Message(why + ": the " + Name(o.Prefab) + " is back with you"); Plugin.Debug("[gift] #" + o.Id + " given back"); } } private static void OnOffer(long from, ZPackage pkg, int id) { Incoming incoming = new Incoming(); incoming.Id = id; incoming.From = from; incoming.At = Time.time; Incoming incoming2 = incoming; incoming2.FromName = pkg.ReadString(); incoming2.Prefab = pkg.ReadString(); incoming2.Label = pkg.ReadString(); incoming2.Stack = pkg.ReadInt(); incoming2.Quality = pkg.ReadInt(); if (!Party.IsAlly(from)) { Answer(incoming2, 2, 0); return; } if (_offer != null) { Answer(incoming2, 2, 2); return; } Member member = Party.Get(from); float num = ((member != null) ? Ui.Distance(member) : (-1f)); if (num < 0f || num > Plugin.SendRange.Value + 5f) { Answer(incoming2, 2, 3); return; } if (!Room(incoming2.Prefab, incoming2.Stack, incoming2.Quality)) { Answer(incoming2, 2, 1); Plugin.Message(incoming2.FromName + " tried to send you " + incoming2.Label + ", but your bag is full"); return; } _offer = incoming2; Plugin.Debug("[gift] offer #" + id + " from " + incoming2.FromName + ": " + incoming2.Label); } private static void TakeOffer() { Incoming offer = _offer; _offer = null; if (!Room(offer.Prefab, offer.Stack, offer.Quality)) { Answer(offer, 2, 1); Plugin.Message("Your bag is full: the offer from " + offer.FromName + " was declined"); } else { Answer(offer, 1, 0); } } private static void OnDeliver(long from, ZPackage pkg, int id) { //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0091: 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_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) ItemData val = Unpack(pkg.ReadPackage()); Player localPlayer = Player.m_localPlayer; if (val == null || (Object)(object)localPlayer == (Object)null) { Answer(from, id, 2, 0); return; } Answer(from, id, 4, 0); string text = ((Party.Get(from) != null) ? Party.Get(from).Name : "A shieldmate"); string text2 = Label(val); if (((Humanoid)localPlayer).GetInventory().AddItem(val)) { Plugin.Message(text + " gave you " + text2); } else { ItemDrop.DropItem(val, val.m_stack, ((Component)localPlayer).transform.position + ((Component)localPlayer).transform.forward + Vector3.up, Quaternion.identity); Plugin.Message(text + " gave you " + text2 + " (your bag was full: it's at your feet)"); } Plugin.Debug("[gift] #" + id + " received: " + text2); } private static bool Room(string prefab, int stack, int quality) { Player localPlayer = Player.m_localPlayer; GameObject val = (((Object)(object)ObjectDB.instance != (Object)null) ? ObjectDB.instance.GetItemPrefab(prefab) : null); if ((Object)(object)localPlayer == (Object)null || (Object)(object)val == (Object)null) { return false; } ItemData val2 = val.GetComponent<ItemDrop>().m_itemData.Clone(); val2.m_dropPrefab = val; val2.m_quality = quality; val2.m_stack = stack; return ((Humanoid)localPlayer).GetInventory().CanAddItem(val2, stack); } private static ZPackage Pack(ItemData it) { //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(((Object)it.m_dropPrefab).name); val.Write(it.m_stack); val.Write(it.m_durability); val.Write(it.m_quality); val.Write(it.m_variant); val.Write(it.m_crafterID); val.Write(it.m_crafterName ?? ""); val.Write(it.m_worldLevel); Dictionary<string, string> dictionary = it.m_customData ?? new Dictionary<string, string>(); val.Write(dictionary.Count); foreach (KeyValuePair<string, string> item in dictionary) { val.Write(item.Key); val.Write(item.Value ?? ""); } return val; } private static ItemData Unpack(ZPackage p) { p.SetPos(0); if (p.ReadInt() != 1) { return null; } string text = p.ReadString(); GameObject val = (((Object)(object)ObjectDB.instance != (Object)null) ? ObjectDB.instance.GetItemPrefab(text) : null); if ((Object)(object)val == (Object)null || (Object)(object)val.GetComponent<ItemDrop>() == (Object)null) { Plugin.Log.LogWarning((object)("Gift: unknown item " + text)); return null; } ItemData val2 = val.GetComponent<ItemDrop>().m_itemData.Clone(); val2.m_dropPrefab = val; val2.m_stack = p.ReadInt(); val2.m_durability = p.ReadSingle(); val2.m_quality = p.ReadInt(); val2.m_variant = p.ReadInt(); val2.m_crafterID = p.ReadLong(); val2.m_crafterName = p.ReadString(); val2.m_worldLevel = p.ReadInt(); int num = p.ReadInt(); val2.m_customData = new Dictionary<string, string>(); for (int i = 0; i < num; i++) { string key = p.ReadString(); val2.m_customData[key] = p.ReadString(); } val2.m_pickedUp = true; val2.m_equipped = false; return val2; } private static ZPackage Head(int kind, int id) { //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(kind); val.Write(id); return val; } private static void Send(long peer, ZPackage pkg) { if (ZRoutedRpc.instance != null && peer != 0) { ZRoutedRpc.instance.InvokeRoutedRPC(peer, "Warband_Gift", new object[1] { pkg }); } } private static void Answer(Incoming x, int kind, int why) { Answer(x.From, x.Id, kind, why); } private static void Answer(long peer, int id, int kind, int why) { ZPackage val = Head(kind, id); val.Write(why); Send(peer, val); } internal static void OnMessage(long from, ZPackage pkg) { try { int num = pkg.ReadInt(); int id = pkg.ReadInt(); switch (num) { case 0: OnOffer(from, pkg, id); break; case 1: pkg.ReadInt(); OnAccept(from, id); break; case 2: OnDeclined(from, id, pkg.ReadInt()); break; case 3: OnDeliver(from, pkg, id); break; case 4: OnGot(from, id); break; } } catch (Exception ex) { Plugin.Log.LogWarning((object)("Gift message failed: " + ex.Message)); } } private static Outgoing Find(int id, long peer) { foreach (Outgoing item in Out) { if (item.Id == id && item.To == peer) { return item; } } return null; } private static string Name(string prefab) { GameObject val = (((Object)(object)ObjectDB.instance != (Object)null) ? ObjectDB.instance.GetItemPrefab(prefab) : null); ItemDrop val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<ItemDrop>() : null); if (!((Object)(object)val2 != (Object)null)) { return prefab; } return Localization.instance.Localize(val2.m_itemData.m_shared.m_name); } private static string Label(ItemData it) { string text = Localization.instance.Localize(it.m_shared.m_name); if (it.m_quality > 1) { object obj = text; text = string.Concat(obj, " (level ", it.m_quality, ")"); } if (it.m_stack <= 1) { return text; } return it.m_stack + "x " + text; } internal static void OnGUI(GUIStyle prompt, Font font, Action<Rect, Color> box, Action<Rect, string, GUIStyle, Color> text) { //IL_006a: 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_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) if (_picking != null && InventoryGui.IsVisible()) { DrawPicker(font); } if (_offer != null && !Party.HasPendingInvite && !Ui.PanelOpen) { string arg = string.Concat(_offer.FromName, " wants to give you ", _offer.Label, "\n[", Plugin.AcceptKey.Value, "] accept [", Plugin.DeclineKey.Value, "] decline"); Rect arg2 = default(Rect); ((Rect)(ref arg2))..ctor((float)(Screen.width - 500) / 2f, (float)Screen.height * 0.26f, 500f, 56f); box(arg2, new Color(0f, 0f, 0f, 0.55f)); text(arg2, arg, prompt, new Color(0.75f, 1f, 0.7f)); } } private static void DrawPicker(Font font) { //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Expected O, but got Unknown //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) List<Member> allies = new List<Member>(); foreach (Member member in Party.Members) { if (member.Peer != Party.Me) { allies.Add(member); } } GUISkin skin = GUI.skin; GUI.skin = Skin.Get(font); ((Rect)(ref _pickRect)).height = 0f; _pickRect = GUILayout.Window(5917501, _pickRect, (WindowFunction)delegate { ItemData picking = _picking; if (picking != null) { GUILayout.Label("Send " + Label(picking) + " to:", (GUILayoutOption[])(object)new GUILayoutOption[0]); if (allies.Count == 0) { GUILayout.Label("No one else is in your party.", (GUILayoutOption[])(object)new GUILayoutOption[0]); } foreach (Member item in allies) { float num = Ui.Distance(item); bool enabled = num >= 0f && num <= Plugin.SendRange.Value; string text = ((num < 0f) ? "far away" : (num.ToString("0") + " m")); GUI.enabled = enabled; if (GUILayout.Button(item.Name + " (" + text + ")", (GUILayoutOption[])(object)new GUILayoutOption[0])) { _picking = null; SendOffer(picking, item); } GUI.enabled = true; } GUILayout.Label("Within " + Plugin.SendRange.Value.ToString("0") + " m. Esc closes.", (GUILayoutOption[])(object)new GUILayoutOption[0]); if (GUILayout.Button("Cancel", (GUILayoutOption[])(object)new GUILayoutOption[0])) { _picking = null; } GUI.DragWindow(); } }, "", GUI.skin.window, (GUILayoutOption[])(object)new GUILayoutOption[0]); GUI.skin = skin; } } internal static class Looks { internal class Layer { public Sprite Sprite; public Color Color; public Vector2 OffsetMin; public Vector2 OffsetMax; } private static readonly Color[] Palette = (Color[])(object)new Color[10] { new Color(1f, 0.8f, 0.2f), new Color(0.3f, 0.85f, 1f), new Color(0.95f, 0.35f, 0.85f), new Color(0.45f, 0.95f, 0.35f), new Color(1f, 0.5f, 0.15f), new Color(0.65f, 0.5f, 1f), new Color(1f, 0.3f, 0.3f), new Color(0.25f, 0.95f, 0.75f), new Color(0.95f, 0.95f, 0.95f), new Color(0.7f, 0.55f, 0.35f) }; private static Texture2D _circle; private static Sprite _circleSprite; private static List<Layer> _layers; private static float _nextTry; internal static Texture2D Circle { get { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown //IL_00b1: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_circle != (Object)null) { return _circle; } _circle = new Texture2D(64, 64, (TextureFormat)4, false); ((Texture)_circle).wrapMode = (TextureWrapMode)1; float num = 31.5f; float num2 = 31f; float num3 = num2 - 5f; for (int i = 0; i < 64; i++) { for (int j = 0; j < 64; j++) { float num4 = Mathf.Sqrt(((float)j - num) * ((float)j - num) + ((float)i - num) * ((float)i - num)); float num5 = Mathf.Clamp01(num2 - num4 + 0.5f); float num6 = ((num4 > num3) ? Mathf.Lerp(1f, 0.15f, Mathf.Clamp01(num4 - num3)) : 1f); _circle.SetPixel(j, i, new Color(num6, num6, num6, num5)); } } _circle.Apply(); return _circle; } } internal static Sprite CircleSprite { get { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_circleSprite == (Object)null) { _circleSprite = Sprite.Create(Circle, new Rect(0f, 0f, (float)((Texture)Circle).width, (float)((Texture)Circle).height), new Vector2(0.5f, 0.5f), 100f); } return _circleSprite; } } private static uint Hash(string s) { uint num = 2166136261u; string text = s.ToLowerInvariant(); foreach (char c in text) { num ^= c; num *= 16777619; } return num; } internal static Color ColorOf(Member who) { //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_007d: 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_00c1: Unknown result type (might be due to invalid IL or missing references) List<int> list = new List<int>(); foreach (Member member in Party.Members) { if (member.Peer != Party.Me || member == who) { int num = (int)(Hash(member.Name) % (uint)Palette.Length); while (list.Contains(num) && list.Count < Palette.Length) { num = (num + 1) % Palette.Length; } list.Add(num); if (member == who) { return Palette[num]; } } } return Palette[Hash(who.Name) % (uint)Palette.Length]; } internal static string Initial(string name) { foreach (char c in name) { if (char.IsLetterOrDigit(c)) { return char.ToUpperInvariant(c).ToString(); } } return "?"; } internal static List<Layer> Background() { //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) if (_layers != null || Time.time < _nextTry) { return _layers; } _nextTry = Time.time + 2f; RectTransform val = (((Object)(object)InventoryGui.instance != (Object)null) ? InventoryGui.instance.m_player : null); if ((Object)(object)val == (Object)null) { return null; } List<Layer> list = new List<Layer>(); Image component = ((Component)val).GetComponent<Image>(); if ((Object)(object)component != (Object)null && (Object)(object)component.sprite != (Object)null) { list.Add(Make(component, Vector2.zero, Vector2.zero)); } for (int i = 0; i < ((Transform)val).childCount; i++) { Transform child = ((Transform)val).GetChild(i); RectTransform val2 = (RectTransform)(object)((child is RectTransform) ? child : null); if (!((Object)(object)val2 == (Object)null)) { Image component2 = ((Component)val2).GetComponent<Image>(); if (!((Object)(object)component2 == (Object)null) && !((Object)(object)component2.sprite == (Object)null) && val2.anchorMin.x <= 0.01f && val2.anchorMin.y <= 0.01f && val2.anchorMax.x >= 0.99f && val2.anchorMax.y >= 0.99f) { list.Add(Make(component2, val2.offsetMin, val2.offsetMax)); } } } _layers = list; string text = ""; foreach (Layer item in list) { text = text + ((text.Length > 0) ? " + " : "") + ((Object)item.Sprite).name; } Plugin.Debug("[hud] background from the inventory window: " + ((text.Length > 0) ? text : "none, plain dark box")); return _layers; } private static Layer Make(Image im, Vector2 min, Vector2 max) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_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_0026: 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) Layer layer = new Layer(); layer.Sprite = im.sprite; layer.Color = ((Graphic)im).color; layer.OffsetMin = min; layer.OffsetMax = max; return layer; } internal static void NineSlice(Rect r, Sprite s, Color tint, float borderScale) { //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_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_028e: Unknown result type (might be due to invalid IL or missing references) //IL_0268: Unknown result type (might be due to invalid IL or missing references) //IL_026b: Unknown result type (might be due to invalid IL or missing references) Texture2D texture = s.texture; if ((Object)(object)texture == (Object)null) { return; } Rect textureRect = s.textureRect; Vector4 border = s.border; float num = ((Texture)texture).width; float num2 = ((Texture)texture).height; float num3 = border.x * borderScale; float num4 = border.y * borderScale; float num5 = border.z * borderScale; float num6 = border.w * borderScale; float num7 = Mathf.Min(1f, ((Rect)(ref r)).width / Mathf.Max(1f, num3 + num5)); float num8 = Mathf.Min(1f, ((Rect)(ref r)).height / Mathf.Max(1f, num6 + num4)); num3 *= num7; num5 *= num7; num6 *= num8; num4 *= num8; float[] array = new float[4] { ((Rect)(ref r)).xMin, ((Rect)(ref r)).xMin + num3, ((Rect)(ref r)).xMax - num5, ((Rect)(ref r)).xMax }; float[] array2 = new float[4] { ((Rect)(ref r)).yMin, ((Rect)(ref r)).yMin + num6, ((Rect)(ref r)).yMax - num4, ((Rect)(ref r)).yMax }; float[] array3 = new float[4] { ((Rect)(ref textureRect)).xMin, ((Rect)(ref textureRect)).xMin + border.x, ((Rect)(ref textureRect)).xMax - border.z, ((Rect)(ref textureRect)).xMax }; float[] array4 = new float[4] { ((Rect)(ref textureRect)).yMax, ((Rect)(ref textureRect)).yMax - border.w, ((Rect)(ref textureRect)).yMin + border.y, ((Rect)(ref textureRect)).yMin }; Color color = GUI.color; GUI.color = tint; Rect val = default(Rect); Rect val2 = default(Rect); for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { ((Rect)(ref val))..ctor(array[i], array2[j], array[i + 1] - array[i], array2[j + 1] - array2[j]); if (!(((Rect)(ref val)).width <= 0f) && !(((Rect)(ref val)).height <= 0f)) { float num9 = array4[j + 1]; float num10 = array4[j]; ((Rect)(ref val2))..ctor(array3[i] / num, num9 / num2, (array3[i + 1] - array3[i]) / num, (num10 - num9) / num2); GUI.DrawTextureWithTexCoords(val, (Texture)(object)texture, val2); } } } GUI.color = color; } } internal static class Order { private static List<string> Names() { List<string> list = new List<string>(); string[] array = Plugin.HudOrder.Value.Split('|'); foreach (string text in array) { if (text.Trim().Length > 0) { list.Add(text.Trim()); } } return list; } internal static void Sort(List<Member> members) { List<string> names = Names(); if (names.Count != 0) { List<Member> copy = new List<Member>(members); members.Sort(delegate(Member a, Member b) { int num = Index(names, a.Name); int num2 = Index(names, b.Name); return (num != num2) ? num.CompareTo(num2) : copy.IndexOf(a).CompareTo(copy.IndexOf(b)); }); } } private static int Index(List<string> names, string name) { for (int i = 0; i < names.Count; i++) { if (string.Equals(names[i], name, StringComparison.OrdinalIgnoreCase)) { return i; } } return 10000; } internal static void Save(List<Member> shown) { List<string> list = new List<string>(); foreach (Member item in shown) { list.Add(item.Name); } foreach (string item2 in Names()) { bool flag = false; foreach (string item3 in list) { if (string.Equals(item3, item2, StringComparison.OrdinalIgnoreCase)) { flag = true; } } if (!flag) { list.Add(item2); } } Plugin.HudOrder.Value = string.Join("|", list.ToArray()); } } [HarmonyPatch] internal static class MapFind { private const float WorldWidth = 24576f; private static readonly FieldInfo Offset = AccessTools.Field(typeof(Minimap), "m_mapOffset"); private static readonly FieldInfo Inertia = AccessTools.Field(typeof(Minimap), "m_zoomInertia"); private static readonly FieldInfo Drag = AccessTools.Field(typeof(Minimap), "m_dragView"); private static long _target; private static string _targetName = ""; private static float _start = -1f; private static Vector3 _fromOffset; private static float _fromZoom; private static float _outZoom; private static float _inZoom; private static float _arrived = -100f; private static Rect _area; private static Font _font; private static GUIStyle _label; private static Texture2D _ring; private static float OutTime => 0.45f * Plugin.MapFindSpeed.Value; private static float MoveTime => 0.8f * Plugin.MapFindSpeed.Value; private static float InTime => 0.55f * Plugin.MapFindSpeed.Value; private static bool Flying => _start >= 0f; private static bool LargeMap() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Invalid comparison between Unknown and I4 if ((Object)(object)Minimap.instance != (Object)null && (int)Minimap.instance.m_mode == 2) { return (Object)(object)Player.m_localPlayer != (Object)null; } return false; } private static List<KeyValuePair<Member, bool>> Allies() { List<KeyValuePair<Member, bool>> list = new List<KeyValuePair<Member, bool>>(); if (!Party.InParty) { return list; } foreach (Member member in Party.Members) { if (member.Peer != Party.Me) { list.Add(new KeyValuePair<Member, bool>(member, Ui.AllyPosition(member, out var _))); } } return list; } internal static void OnGUI() { //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009c: 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_011b: 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_022e: Unknown result type (might be due to invalid IL or missing references) //IL_01d5: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Unknown result type (might be due to invalid IL or missing references) if (!Plugin.MapFindButton.Value || !LargeMap() || !Party.InParty) { if (!LargeMap()) { _start = -1f; } return; } if ((Object)(object)_font == (Object)null) { Font[] array = Resources.FindObjectsOfTypeAll<Font>(); foreach (Font val in array) { if (((Object)val).name == "AveriaSerifLibre-Bold") { _font = val; break; } } } List<KeyValuePair<Member, bool>> list = Allies(); if (list.Count == 0) { _area = default(Rect); DrawMarker(); return; } Vector2 value = Plugin.MapFindPosition.Value; float num = (float)list.Count * 30f + (float)(list.Count - 1) * 4f; float num2 = ((value.x < 0f) ? ((float)Screen.width + value.x - 160f) : value.x); float num3 = ((value.y < 0f) ? ((float)Screen.height + value.y - num) : value.y); _area = new Rect(num2, num3, 160f, num); GUISkin skin = GUI.skin; GUI.skin = Skin.Get(_font); Rect val2 = default(Rect); for (int j = 0; j < list.Count; j++) { Member key = list[j].Key; bool value2 = list[j].Value; ((Rect)(ref val2))..ctor(num2, num3 + (float)j * 34f, 160f, 30f); bool flag = (Flying || Time.unscaledTime - _arrived < 3f) && key.Peer == _target; GUI.enabled = value2; GUI.color = (Color)(flag ? new Color(1f, 0.92f, 0.6f) : Color.white); string text = (value2 ? Short(key.Name) : (Short(key.Name) + " (?)")); if (GUI.Button(val2, text)) { Go(key); } } GUI.color = Color.white; GUI.enabled = true; GUI.skin = skin; DrawMarker(); } private static string Short(string name) { if (name.Length <= 12) { return name; } return name.Substring(0, 11) + "…"; } private static void Go(Member m) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_004e: 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_0059: Unknown result type (might be due to invalid IL or missing references) if (Ui.AllyPosition(m, out var pos) && !(Offset == null)) { Minimap instance = Minimap.instance; Vector3 position = ((Component)Player.m_localPlayer).transform.position; _fromOffset = (Vector3)Offset.GetValue(instance); _fromZoom = instance.LargeZoom; float num = Vector3.Distance(position + _fromOffset, pos); _outZoom = Mathf.Clamp(Mathf.Max(_fromZoom, num * 2.2f / 24576f), instance.m_minZoom, instance.m_maxZoom); _inZoom = Mathf.Clamp(Plugin.MapFindZoom.Value, instance.m_minZoom, instance.m_maxZoom); _target = m.Peer; _targetName = m.Name; _start = Time.unscaledTime; Plugin.Debug("[map] finding " + m.Name + " at " + ((Vector3)(ref pos)).ToString("0") + " (" + num.ToString("0") + " m from the view), zoom " + _fromZoom.ToString("0.000") + " > " + _outZoom.ToString("0.000") + " > " + _inZoom.ToString("0.000")); } } [HarmonyPatch(typeof(Minimap), "UpdateMap")] [HarmonyPrefix] private static void Fly(Minimap __instance, Player player) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Invalid comparison between Unknown and I4 //IL_0049: 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_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0099: 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_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011a: 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) if (!Flying || (Object)(object)player == (Object)null || Offset == null) { return; } if ((int)__instance.m_mode != 2) { _start = -1f; return; } if ((Input.GetMouseButtonDown(0) && !Over()) || Input.GetMouseButtonDown(1) || Mathf.Abs(Input.mouseScrollDelta.y) > 0.01f) { _start = -1f; return; } Member member = Party.Get(_target); if (member == null || !Ui.AllyPosition(member, out var pos)) { _start = -1f; return; } Vector3 val = pos - ((Component)player).transform.position; val.y = 0f; float num = Time.unscaledTime - _start; float largeZoom; Vector3 val2; if (num < OutTime) { largeZoom = Mathf.Lerp(_fromZoom, _outZoom, Ease(num / OutTime)); val2 = _fromOffset; } else if (num < OutTime + MoveTime) { largeZoom = _outZoom; val2 = Vector3.Lerp(_fromOffset, val, Ease((num - OutTime) / MoveTime)); } else { float num2 = Mathf.Clamp01((num - OutTime - MoveTime) / InTime); largeZoom = Mathf.Lerp(_outZoom, _inZoom, Ease(num2)); val2 = val; if (num2 >= 1f) { _start = -1f; _arrived = Time.unscaledTime; } } Offset.SetValue(__instance, val2); __instance.LargeZoom = largeZoom; if (Inertia != null) { Inertia.SetValue(__instance, 0f); } if (Drag != null) { Drag.SetValue(__instance, false); } } private static float Ease(float x) { x = Mathf.Clamp01(x); return x * x * (3f - 2f * x); } private static void DrawMarker() { //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_022a: Unknown result type (might be due to invalid IL or missing references) //IL_024f: Unknown result type (might be due to invalid IL or missing references) //IL_0259: Unknown result type (might be due to invalid IL or missing references) //IL_026a: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Expected O, but got Unknown float num = Time.unscaledTime - _arrived; bool flag = Flying && Time.unscaledTime - _start > OutTime + MoveTime * 0.6f; if (!flag && num > 3f) { return; } Minimap instance = Minimap.instance; if ((Object)(object)instance.m_mapImageLarge == (Object)null) { return; } Vector3[] array = (Vector3[])(object)new Vector3[4]; ((Graphic)instance.m_mapImageLarge).rectTransform.GetWorldCorners(array); Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor((array[0].x + array[2].x) / 2f, (float)Screen.height - (array[0].y + array[2].y) / 2f); float num2 = (flag ? 1f : Mathf.Clamp01(3f - num)); float num3 = 1f + 0.15f * Mathf.Sin(Time.unscaledTime * 6f); float num4 = 26f * num3; Color value = Plugin.SilhouetteColor.Value; GUI.color = new Color(value.r, value.g, value.b, num2); GUI.DrawTexture(new Rect(val.x - num4, val.y - num4, num4 * 2f, num4 * 2f), (Texture)(object)Ring()); if (_label == null) { _label = new GUIStyle(GUI.skin.label); _label.fontSize = 16; _label.fontStyle = (FontStyle)1; _label.alignment = (TextAnchor)4; if ((Object)(object)_font != (Object)null) { _label.font = _font; } } Rect val2 = default(Rect); ((Rect)(ref val2))..ctor(val.x - 120f, val.y + num4 + 2f, 240f, 24f); GUI.color = new Color(0f, 0f, 0f, num2 * 0.8f); GUI.Label(new Rect(((Rect)(ref val2)).x + 1f, ((Rect)(ref val2)).y + 1f, ((Rect)(ref val2)).width, ((Rect)(ref val2)).height), _targetName, _label); GUI.color = new Color(1f, 0.92f, 0.7f, num2); GUI.Label(val2, _targetName, _label); GUI.color = Color.white; } private static Texture2D Ring() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_ring != (Object)null) { return _ring; } _ring = new Texture2D(64, 64, (TextureFormat)4, false); ((Object)_ring).hideFlags = (HideFlags)61; for (int i = 0; i < 64; i++) { for (int j = 0; j < 64; j++) { float num = Vector2.Distance(new Vector2((float)j + 0.5f, (float)i + 0.5f), new Vector2(32f, 32f)); float num2 = Mathf.Clamp01(1f - Mathf.Abs(num - 27f) / 3f) + Mathf.Clamp01(1f - Mathf.Abs(num - 16f) / 2f) * 0.7f; _ring.SetPixel(j, i, new Color(1f, 1f, 1f, Mathf.Clamp01(num2))); } } _ring.Apply(); return _ring; } private static bool Over() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: 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) if (!Plugin.MapFindButton.Value || !LargeMap() || !Party.InParty) { return false; } Vector3 mousePosition = Input.mousePosition; return ((Rect)(ref _area)).Contains(new Vector2(mousePosition.x, (float)Screen.height - mousePosition.y)); } [HarmonyPrefix] [HarmonyPatch(typeof(Minimap), "OnMapLeftDown")] private static bool LeftDown() { return !Over(); } [HarmonyPrefix] [HarmonyPatch(typeof(Minimap), "OnMapLeftUp")] private static bool LeftUp() { return !Over(); } [HarmonyPatch(typeof(Minimap), "OnMapLeftClick")] [HarmonyPrefix] private static bool LeftClick() { return !Over(); } [HarmonyPatch(typeof(Minimap), "OnMapDblClick")] [HarmonyPrefix] private static bool DblClick() { return !Over(); } } internal class Buff { public int Hash; public float Remaining; } internal class Member { public long Peer; public string Name = ""; public string UserId = ""; public float Hp; public float MaxHp = 1f; public float Stam; public float MaxStam = 1f; public float Eitr; public float MaxEitr; public string Weapon = ""; public Vector3 Pos; public bool HasPos; public readonly List<Buff> Buffs = new List<Buff>(); public float VitalsAt = -100f; public float MissingSince = -1f; public float DeadSince = -1f; public string ChatText = ""; public float ChatAt = -100f; } internal static class Party { internal class Online { public long Peer; public string Name = ""; public string UserId = ""; } private class Invite { public long From; public string FromName = ""; public long Leader; public float At; } private class Sent { public string Name = ""; public float At; } private const string RpcInvite = "Warband_Invite"; private const string RpcReply = "Warband_Reply"; private const string RpcJoin = "Warband_Join"; private const string RpcRoster = "Warband_Roster"; private const string RpcLeave = "Warband_Leave"; private const string RpcVitals = "Warband_Vitals"; private const int ReplyDeclined = 0; private const int ReplyBusy = 1; private const int ReplyFull = 2; private const int ReplyStale = 3; private const float InviteTimeout = 30f; private const float VitalsInterval = 0.5f; private const float GoneAfter = 10f; internal static readonly List<Member> Members = new List<Member>(); internal static readonly List<Online> OnlinePlayers = new List<Online>(); internal static long Leader; private static Invite _pending; private static long _joiningLeader; private static float _joiningAt; private static readonly Dictionary<long, Sent> SentInvites = new Dictionary<long, Sent>(); private static ZRoutedRpc _registeredOn; private static float _nextVitals; private static float _nextCheck; private static readonly FieldInfo RightField = AccessTools.Field(typeof(Humanoid), "m_rightItem"); private static readonly FieldInfo LeftField = AccessTools.Field(typeof(Humanoid), "m_leftItem"); internal static long Me => ZNet.GetUID(); internal static bool InParty => Members.Count >= 2; internal static bool IsLeader { get { if (InParty) { return Leader == Me; } return false; } } internal static string PendingFrom { get { if (_pending == null) { return null; } return _pending.FromName; } } internal static bool HasPendingInvite => _pending != null; internal static string MyName() { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null) { return localPlayer.GetPlayerName(); } if ((Object)(object)Game.instance != (Object)null && Game.instance.GetPlayerProfile() != null) { return Game.instance.GetPlayerProfile().GetName(); } return "?"; } internal static Member Get(long peer) { foreach (Member member in Members) { if (member.Peer == peer) { return member; } } return null; } internal static bool IsAlly(long peer) { if (InParty && peer != 0 && peer != Me) { return Get(peer) != null; } return false; } internal static Online FindOnline(long peer) { foreach (Online onlinePlayer in OnlinePlayers) { if (onlinePlayer.Peer == peer) { return onlinePlayer; } } return null; } internal static Online FindOnlineByFriend(Friend f) { foreach (Online onlinePlayer in OnlinePlayers) { if ((f.Id.Length > 0 && onlinePlayer.UserId == f.Id) || string.Equals(onlinePlayer.Name, f.Name, StringComparison.OrdinalIgnoreCase)) { return onlinePlayer; } } return null; } internal static Player FindPlayer(long peer) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) foreach (Player allPlayer in Player.GetAllPlayers()) { if ((Object)(object)allPlayer != (Object)null) { ZDOID zDOID = ((Character)allPlayer).GetZDOID(); if (((ZDOID)(ref zDOID)).UserID == peer) { return allPlayer; } } } return null; } internal static Member Self() { return Get(Me); } internal static void Update() { ZRoutedRpc instance = ZRoutedRpc.instance; if (instance == null || (Object)(object)ZNet.instance == (Object)null) { if (Members.Count > 0 || _pending != null) { Reset("left the world"); } _registeredOn = null; return; } if (instance != _registeredOn) { Register(instance); } float time = Time.time; if (time >= _nextCheck) { _nextCheck = time + 1f; RefreshOnline(); Timeouts(time); CheckGone(time); } if (InParty && time >= _nextVitals) { _nextVitals = time + 0.5f; SendVitals(); } } private static void Register(ZRoutedRpc rpc) { Reset("new connection"); rpc.Register<ZPackage>("Warband_Invite", (Action<long, ZPackage>)OnInvite); rpc.Register<ZPackage>("Warband_Reply", (Action<long, ZPackage>)OnReply); rpc.Register<ZPackage>("Warband_Join", (Action<long, ZPackage>)OnJoin); rpc.Register<ZPackage>("Warband_Roster", (Action<long, ZPackage>)OnRoster); rpc.Register<ZPackage>("Warband_Leave", (Action<long, ZPackage>)OnLeave); rpc.Register<ZPackage>("Warband_Vitals", (Action<long, ZPackage>)OnVitals); rpc.Register<ZPackage>("Warband_Chat", (Action<long, ZPackage>)PartyChat.OnMessage); rpc.Register<ZPackage>("Warband_Gift", (Action<long, ZPackage>)Gift.OnMessage); _registeredOn = rpc; Plugin.Debug("[net] messages registered, my id " + Me); } private static void Reset(string why) { if (Members.Count > 0) { Plugin.Debug("[party] cleared (" + why + ")"); } Members.Clear(); Leader = 0L; _pending = null; _joiningLeader = 0L; SentInvites.Clear(); OnlinePlayers.Clear(); } private unsafe static void RefreshOnline() { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) OnlinePlayers.Clear(); long me = Me; string text = MyName(); foreach (PlayerInfo player in ZNet.instance.GetPlayerList()) { ZDOID characterID = player.m_characterID; long userID = ((ZDOID)(ref characterID)).UserID; if (userID != me && (userID != 0 || !(player.m_name == text))) { Online online = new Online(); online.Peer = userID; online.Name = player.m_name ?? ""; PlatformUserID id = player.m_userInfo.m_id; online.UserId = ((object)(*(PlatformUserID*)(&id))/*cast due to .constrained prefix*/).ToString() ?? ""; OnlinePlayers.Add(online); } } Friends.Refresh(OnlinePlayers); foreach (Member member in Members) { Online online2 = FindOnline(member.Peer); if (online2 != null && online2.UserId.Length > 0) { member.UserId = online2.UserId; } } } private static void Timeouts(float now) { if (_pending != null && now - _pending.At > 30f) { Plugin.Message("The party invite from " + _pending.FromName + " expired"); _pending = null; } if (_joiningLeader != 0 && now - _joiningAt > 15f) { Plugin.Message("The party leader didn't answer"); _joiningLeader = 0L; } List<long> list = null; foreach (KeyValuePair<long, Sent> sentInvite in SentInvites) { if (now - sentInvite.Value.At > 30f) { if (list == null) { list = new List<long>(); } list.Add(sentInvite.Key); } } if (list == null) { return; } foreach (long item in list) { Plugin.Message(SentInvites[item].Name + " didn't answer your invite (do they have Warband?)"); SentInvites.Remove(item); } if (Members.Count == 1 && SentInvites.Count == 0) { Members.Clear(); } } private static void CheckGone(float now) { if (!InParty) { return; } long me = Me; List<Member> list = new List<Member>(); foreach (Member member3 in Members) { if (member3.Peer != me) { if (FindOnline(member3.Peer) != null || now - member3.VitalsAt < 6f) { member3.MissingSince = -1f; } else if (member3.MissingSince < 0f) { member3.MissingSince = now; } else if (now - member3.MissingSince > 10f) { list.Add(member3); } } } if (list.Count == 0) { return; } Member member = Get(Leader); if (member != null && list.Contains(member)) { Member member2 = null; foreach (Member member4 in Members) { if (!list.Contains(member4)) { member2 = member4; break; } } if (member2 == null || member2.Peer != me) { return; } Leader = me; Plugin.Message(member.Name + " is gone, you lead the party now"); } else if (Leader != me) { return; } List<long> extra = new List<long>(); foreach (Member item in list) { Members.Remove(item); if (item != member) { Plugin.Message(item.Name + " left the party (disconnected)"); } } SendRoster(extra); } internal static void InviteTo(long peer, string name) { //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Expected O, but got Unknown if (peer == 0 || peer == Me) { Plugin.Message(name + " can't be invited right now"); return; } if (Get(peer) != null && InParty) { Plugin.Message(name + " is already in your party"); return; } if (Members.Count >= Plugin.MaxMembers.Value) { Plugin.Message("Your party is full"); return; } if (Members.Count == 0) { Member member = new Member(); member.Peer = Me; member.Name = MyName(); Members.Add(member); Leader = Me; } ZPackage val = new ZPackage(); val.Write(Leader); val.Write(MyName()); Send(peer, "Warband_Invite", val); Sent sent = new Sent(); sent.Name = name; sent.At = Time.time; SentInvites[peer] = sent; Plugin.Message("Party invite sent to " + name); } internal static void Accept() { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Expected O, but got Unknown if (_pending != null) { if (InParty) { Plugin.Message("Leave your party first"); return; } Members.Clear(); Leader = 0L; SentInvites.Clear(); _joiningLeader = _pending.Leader; _joiningAt = Time.time; ZPackage val = new ZPackage(); val.Write(MyName()); Send(_pending.Leader, "Warband_Join", val); Plugin.Message("Joining " + _pending.FromName + "'s party..."); _pending = null; } } internal static void Decline() { if (_pending != null) { Reply(_pending.From, 0); Plugin.Message("You declined the invite from " + _pending.FromName); _pending = null; } } internal static void Leave() { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Expected O, but got Unknown if (!InParty) { Members.Clear(); Leader = 0L; return; } if (Leader == Me) { Member item = Self(); Members.Remove(item); Leader = Members[0].Peer; SendRoster(null); } else { Send(Leader, "Warband_Leave", new ZPackage()); } Members.Clear(); Leader = 0L; Plugin.Message("You left the party"); } internal static void Kick(long peer) { if (IsLeader && peer != Me) { Member member = Get(peer); if (member != null) { Members.Remove(member); List<long> list = new List<long>(); list.Add(peer); SendRoster(list); Plugin.Message(member.Name + " was removed from the party"); } } } internal static void MakeLeader(long peer) { if (IsLeader && peer != Me && Get(peer) != null) { Leader = peer; SendRoster(null); Plugin.Message(Get(peer).Name + " leads the party now"); } } private static void Send(long peer, string method, ZPackage pkg) { if (ZRoutedRpc.instance != null && peer != 0) { ZRoutedRpc.instance.InvokeRoutedRPC(peer, method, new object[1] { pkg }); } } private static void Reply(long peer, int code) { //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(code); val.Write(MyName()); Send(peer, "Warband_Reply", val); } private static void SendRoster(List<long> extra) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Expected O, but got Unknown ZPackage val = new ZPackage(); val.Write(Leader); val.Write(Members.Count); foreach (Member member in Members) { val.Write(member.Peer); val.Write(member.Name); } byte[] array = val.GetArray(); long me = Me; List<long> list = new List<long>(); foreach (Member member2 in Members) { if (member2.Peer != me) { list.Add(member2.Peer); } } if (extra != null) { foreach (long item in extra) { if (!list.Contains(item) && item != me) { list.Add(item); } } } foreach (long item2 in list) { Send(item2, "Warband_Roster", new ZPackage(array)); } Plugin.Debug("[party] roster sent to " + list.Count + " (leader " + Leader + ", " + Members.Count + " members)"); } private static void OnInvite(long sender, ZPackage pkg) { //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) long num = pkg.ReadLong(); string text = pkg.ReadString(); Plugin.Debug("[net] invite from " + text + " (" + sender + "), leader " + num); if (InParty) { if (Get(sender) == null) { Reply(sender, 1); } return; } _pending = new Invite(); _pending.From = sender; _pending.FromName = text; _pending.Leader = num; _pending.At = Time.time; Online online = FindOnline(sender); if (Plugin.AutoAcceptFriends.Value && Friends.IsFriend((online != null) ? online.UserId : "", text)) { Accept(); return; } Plugin.Center(string.Concat(text, " invited you to their party\n[", Plugin.AcceptKey.Value, "] accept [", Plugin.DeclineKey.Value, "] decline")); } private static void OnReply(long sender, ZPackage pkg) { int num = pkg.ReadInt(); string text = pkg.ReadString(); SentInvites.Remove(sender); switch (num) { case 0: Plugin.Message(text + " declined your party invite"); break; case 1: Plugin.Message(text + " is already in a party"); break; case 2: Plugin.Message("That party is full"); _joiningLeader = 0L; break; case 3: Plugin.Message("That invite is no longer valid"); _joiningLeader = 0L; break; } if (Members.Count == 1 && SentInvites.Count == 0) { Members.Clear(); } } private static void OnJoin(long sender, ZPackage pkg) { string text = pkg.ReadString(); Plugin.Debug("[net] join request from " + text + " (" + sender + ")"); if (Members.Count == 0 || Leader != Me) { Reply(sender, 3); return; } if (Get(sender) == null) { if (Members.Count >= Plugin.MaxMembers.Value) { Reply(sender, 2); return; } Member member = new Member(); member.Peer = sender; member.Name = text; Online online = FindOnline(sender); if (online != null) { member.UserId = online.UserId; } Members.Add(member); Plugin.Message(text + " joined the party"); } SentInvites.Remove(sender); SendRoster(null); } private static void OnRoster(long sender, ZPackage pkg) { long num = pkg.ReadLong(); int num2 = pkg.ReadInt(); List<Member> list = new List<Member>(); for (int i = 0; i < num2; i++) { long peer = pkg.ReadLong(); string name = pkg.ReadString(); Member member = Get(peer); if (member == null) { member = new Member(); member.Peer = peer; } member.Name = name; list.Add(member); } bool flag = InParty && sender == Leader; bool flag2 = sender == _joiningLeader && Time.time - _joiningAt < 30f; bool flag3 = InParty && num == sender && Get(sender) != null; if (!flag && !flag2 && !flag3) { Plugin.Debug("[net] ignored a member list from " + sender); return; } long me = Me; bool inParty = InParty; bool flag4 = false; foreach (Member item in list) { if (item.Peer == me) { flag4 = true; } } if (!flag4) { if (inParty) { Plugin.Message("You are no longer in the party"); } Members.Clear(); Leader = 0L; _joiningLeader = 0L; return; } if (inParty) { foreach (Member member3 in Members) { bool flag5 = false; foreach (Member item2 in list) { if (item2.Peer == member3.Peer) { flag5 = true; } } if (!flag5 && member3.Peer != me) { Plugin.Message(member3.Name + " left the party"); } } foreach (Member item3 in list) { if (item3.Peer != me && Get(item3.Peer) == null && item3.Peer != sender) { Plugin.Message(item3.Name + " joined the party"); } } } long leader = Leader; Members.Clear(); Members.AddRange(list); Leader = num; _joiningLeader = 0L; Member member2 = Get(num); string text = ((member2 != null) ? member2.Name : "?"); if (!inParty && InParty) { Plugin.Message("You joined " + text + "'s party"); } else if (inParty && leader != num && InParty) { Plugin.Message((num == me) ? "You lead the party now" : (text + " leads the party now")); } if (!InParty) { Plugin.Message("The party broke up"); Members.Clear(); Leader = 0L; } Plugin.Debug("[party] roster: " + Members.Count + " members, leader " + text); } private static void OnLeave(long sender, ZPackage pkg) { if (Leader != Me) { return; } Member member = Get(sender); if (member != null) { Members.Remove(member); Plugin.Message(member.Name + " left the party"); SendRoster(null); if (Members.Count < 2) { Members.Clear(); Leader = 0L; } } } private static ItemData RightItem(Humanoid h) { if (!(RightField != null)) { return null; } object? value = RightField.GetValue(h); return (ItemData)((value is ItemData) ? value : null); } private static ItemData LeftItem(Humanoid h) { if (!(LeftField != null)) { return null; } object? value = LeftField.GetValue(h); return (ItemData)((value is ItemData) ? value : null); } private static void SendVitals() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown //IL_01f9: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_0249: Unknown result type (might be due to invalid IL or missing references) //IL_0253: Expected O, but got Unknown Player localPlayer = Player.m_localPlayer; Member member = Self(); ZPackage val = new ZPackage(); if ((Object)(object)localPlayer != (Object)null) { val.Write(((Character)localPlayer).GetHealth()); val.Write(((Character)localPlayer).GetMaxHealth()); val.Write(localPlayer.GetStamina()); val.Write(((Character)localPlayer).GetMaxStamina()); val.Write(localPlayer.GetEitr()); val.Write(((Character)localPlayer).GetMaxEitr()); ItemData val2 = RightItem((Humanoid)(object)localPlayer); if (val2 == null) { val2 = LeftItem((Humanoid)(object)localPlayer); } val.Write((val2 != null && (Object)(object)val2.m_dropPrefab != (Object)null) ? ((Object)val2.m_dropPrefab).name : ""); val.Write(true); val.Write(((Component)localPlayer).transform.position); List<StatusEffect> statusEffects = ((Character)localPlayer).GetSEMan().GetStatusEffects(); List<StatusEffect> list = new List<StatusEffect>(); foreach (StatusEffect item in statusEffects) { if ((Object)(object)item != (Object)null && (Object)(object)item.m_icon != (Object)null && list.Count < 16) { list.Add(item); } } val.Write(list.Count); foreach (StatusEffect item2 in list) { val.Write(item2.NameHash()); val.Write((item2.m_ttl > 0f) ? Mathf.Max(0f, item2.GetRemaningTime()) : (-1f)); } } else { val.Write(0f); val.Write(member?.MaxHp ?? 1f); val.Write(0f); val.Write(1f); val.Write(0f); val.Write(0f); val.Write(""); val.Write(false); val.Write(Vector3.zero); val.Write(0); } byte[] array = val.GetArray(); long me = Me; foreach (Member member2 in Members) { if (member2.Peer != me) { Send(member2.Peer, "Warband_Vitals", new ZPackage(array)); } } } private static void OnVitals(long sender, ZPackage pkg) { //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) Member member = Get(sender); if (member == null || !InParty) { return; } member.Hp = pkg.ReadSingle(); member.MaxHp = pkg.ReadSingle(); member.Stam = pkg.ReadSingle(); member.MaxStam = pkg.ReadSingle(); member.Eitr = pkg.ReadSingle(); member.MaxEitr = pkg.ReadSingle(); member.Weapon = pkg.ReadString(); member.HasPos = pkg.ReadBool(); member.Pos = pkg.ReadVector3(); int num = pkg.ReadInt(); member.Buffs.Clear(); for (int i = 0; i < num; i++) { Buff buff = new Buff(); buff.Hash = pkg.ReadInt(); buff.Remaining = pkg.ReadSingle(); member.Buffs.Add(buff); } if (member.Hp <= 0f) { if (member.DeadSince < 0f) { member.DeadSince = Time.time; } } else { member.DeadSince = -1f; } member.VitalsAt = Time.time; } } internal static class PartyChat { internal const string Rpc = "Warband_Chat"; private const int MaxLength = 200; private static readonly FieldInfo HideTimer = AccessTools.Field(typeof(Chat), "m_hideTimer"); internal static string Parse(string text) { if (string.IsNullOrEmpty(text)) { return null; } string text2 = text.TrimStart(); string text3 = text2.ToLowerInvariant(); if (text3 == "/p" || text3 == "/party") { return ""; } if (text3.StartsWith("/p ")) { return text2.Substring(3).Trim(); } if (text3.StartsWith("/party ")) { return text2.Substring(7).Trim(); } return null; } internal static void Send(string text) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Expected O, but got Unknown //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Expected O, but got Unknown if (text.Length == 0) { Line("<color=#ffcc66>Party chat: type /p and your message.</color>"); return; } if (!Party.InParty) { Line("<color=#ffcc66>You are not in a party.</color>"); return; } if (text.Length > 200) { text = text.Substring(0, 200); } ZPackage val = new ZPackage(); val.Write(Party.MyName()); val.Write(text); byte[] array = val.GetArray(); long me = Party.Me; int num = 0; foreach (Member member in Party.Members) { if (member.Peer != me && ZRoutedRpc.instance != null) { ZRoutedRpc.instance.InvokeRoutedRPC(member.Peer, "Warband_Chat", new object[1] { (object)new ZPackage(array) }); num++; } } Show(Party.Self(), Party.MyName(), text); Plugin.Debug("[chat] sent to " + num); } internal static void OnMessage(long sender, ZPackage pkg) { string text = pkg.ReadString(); string text2 = pkg.ReadString(); Member member = Party.Get(sender); if (member != null && Party.InParty) { if (text2.Length > 200) { text2 = text2.Substring(0, 200); } Show(member, (member.Name.Length > 0) ? member.Name : text, text2); } } private static void Show(Member m, string name, string text) { //IL_0020: 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_0025: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: 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) if (m != null) { m.ChatText = text; m.ChatAt = Time.time; } Color val = ((m != null) ? Looks.ColorOf(m) : Color.white); Line("<color=#" + ColorUtility.ToHtmlStringRGB(Plugin.ChatColor.Value) + ">[Party]</color> <color=#" + ColorUtility.ToHtmlStringRGB(val) + ">" + Clean(name) + "</color>: <color=#" + ColorUtility.ToHtmlStringRGB(Plugin.ChatColor.Value) + "><noparse>" + text.Replace("</noparse>", "") + "</noparse></color>"); } private static string Clean(string s) { return s.Replace("<", "").Replace(">", ""); } private static void Line(string rich) { Chat instance = Chat.instance; if (!((Object)(object)instance == (Object)null)) { ((Terminal)instance).AddString(rich); if (HideTimer != null) { HideTimer.SetValue(instance, 0f); } } } } [HarmonyPatch(typeof(Chat), "InputText")] internal static class ChatInputPatch { private static bool Prefix(Chat __instance) { if ((Object)(object)((Terminal)__instance).m_input == (Object)null) { return true; } string text = PartyChat.Parse(((TMP_InputField)((Terminal)__instance).m_input).text); if (text == null) { return true; } try { PartyChat.Send(text); } catch (Exception ex) { Plugin.Log.LogWarning((object)("Party chat failed: " + ex.Message)); } return false; } } public enum SilhouetteStyle { Fill, Outline, AlwaysOnTop } [BepInPlugin("felih.Warband", "Warband", "1.3.0")] public class Plugin : BaseUnityPlugin { public const string GUID = "felih.Warband"; public const string NAME = "Warband"; public const string VERSION = "1.3.0"; internal static ManualLogSource Log; internal static ConfigEntry<KeyboardShortcut> PanelKey; internal static ConfigEntry<KeyboardShortcut> InviteKey; internal static ConfigEntry<KeyboardShortcut> AcceptKey; internal static ConfigEntry<KeyboardShortcut> DeclineKey; internal static ConfigEntry<KeyboardShortcut> SendKey; internal static ConfigEntry<float> SendRange; internal static ConfigEntry<KeyboardShortcut> EditHudKey; internal static ConfigEntry<bool> AutoAcceptFriends; internal static ConfigEntry<int> MaxMembers; internal static ConfigEntry<bool> ShowHud; internal static ConfigEntry<Vector2> HudPosition; internal static ConfigEntry<float> HudScale; internal static ConfigEntry<bool> ShowStamina; internal static ConfigEntry<bool> ShowEitr; internal static ConfigEntry<bool> ShowBuffs; internal static ConfigEntry<int> MaxBuffs; internal static ConfigEntry<bool> ShowWeapon; internal static ConfigEntry<bool> ShowDistance; internal static ConfigEntry<float> HudBackgroundOpacity; internal static ConfigEntry<string> HudOrder; internal static ConfigEntry<bool> SilhouetteEnabled; internal static ConfigEntry<Color> SilhouetteColor; internal static ConfigEntry<float> SilhouetteMaxDistance; internal static ConfigEntry<SilhouetteStyle> SilhouetteMode; internal static ConfigEntry<int> SilhouetteOutlineWidth; internal static ConfigEntry<bool> SilhouetteOnSelf; internal static ConfigEntry<float> SilhouetteMargin; internal static ConfigEntry<float> SilhouetteOpacity; internal static ConfigEntry<Color> ChatColor; internal static ConfigEntry<bool> ChatInHud; internal static ConfigEntry<float> ChatHudSeconds; internal static ConfigEntry<bool> CompassEnabled; internal static ConfigEntry<float> CompassMaxDistance; internal static ConfigEntry<float> CompassIconSize; internal static ConfigEntry<bool> MapFindButton; internal static ConfigEntry<Vector2> MapFindPosition; internal static ConfigEntry<float> MapFindZoom; internal static ConfigEntry<float> MapFindSpeed; internal static ConfigEntry<bool> DetailedLog; private void Awake() { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: 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_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Expected O, but got Unknown //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Expected O, but got Unknown //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_022f: Unknown result type (might be due to invalid IL or missing references) //IL_0239: Expected O, but got Unknown //IL_02c2: Unknown result type (might be due to invalid IL or missing references) //IL_02cc: Expected O, but got Unknown //IL_0340: Unknown result type (might be due to invalid IL or missing references) //IL_034a: Expected O, but got Unknown //IL_03b7: Unknown result type (might be due to invalid IL or missing references) //IL_03fa: Unknown result type (might be due to invalid IL or missing references) //IL_0404: Expected O, but got Unknown //IL_0438: Unknown result type (might be due to invalid IL or missing references) //IL_0442: Expected O, but got Unknown //IL_048b: Unknown result type (might be due to invalid IL or missing references) //IL_0495: Expected O, but got Unknown //IL_04c9: Unknown result type (might be due to invalid IL or missing references) //IL_04d3: Expected O, but got Unknown //IL_0547: Unknown result type (might be due to invalid IL or missing references) //IL_0551: Expected O, but got Unknown //IL_0585: Unknown result type (might be due to invalid IL or missing references) //IL_058f: Expected O, but got Unknown //IL_05b8: Unknown result type (might be due to invalid IL or missing references) //IL_061b: Unknown result type (might be due to invalid IL or missing references) //IL_0625: Expected O, but got Unknown //IL_0664: Unknown result type (might be due to invalid IL or missing references) //IL_06a7: Unknown result type (might be due to invalid IL or missing references) //IL_06b1: Expected O, but got Unknown //IL_06e5: Unknown result type (might be due to invalid IL or missing references) //IL_06ef: Expected O, but got Unknown //IL_071e: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; PanelKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("1 - Keys", "PanelKey", new KeyboardShortcut((KeyCode)112, (KeyCode[])(object)new KeyCode[1] { (KeyCode)304 }), "Opens the party panel: everyone on the server, your friends and your party."); InviteKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("1 - Keys", "InviteKey", new KeyboardShortcut((KeyCode)106, (KeyCode[])(object)new KeyCode[0]), "Invites the player you are looking at to your party."); AcceptKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("1 - Keys", "AcceptKey", new KeyboardShortcut((KeyCode)121, (KeyCode[])(object)new KeyCode[0]), "Accepts a party invite."); DeclineKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("1 - Keys", "DeclineKey", new KeyboardShortcut((KeyCode)110, (KeyCode[])(object)new KeyCode[0]), "Declines a party invite."); SendKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("1 - Keys", "SendItemKey", new KeyboardShortcut((KeyCode)112, (KeyCode[])(object)new KeyCode[0]), "With your bag open, hover an item and press this to send it to a party member nearby."); EditHudKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("1 - Keys", "EditHudKey", new KeyboardShortcut((KeyCode)289, (KeyCode[])(object)new KeyCode[0]), "Edit mode for the party HUD: drag it with the mouse, scroll to resize, press again to finish."); SendRange = ((BaseUnityPlugin)this).Config.Bind<float>("2 - Party", "SendItemRange", 30f, new ConfigDescription("How close a party member must be to send them an item (metres).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(2f, 100f), new object[0])); AutoAcceptFriends = ((BaseUnityPlugin)this).Config.Bind<bool>("2 - Party", "AutoAcceptFriends", false, "Invites from players on your friends list are accepted on their own."); MaxMembers = ((BaseUnityPlugin)this).Config.Bind<int>("2 - Party", "MaxMembers", 10, new ConfigDescription("Most players in one party (counting you).", (AcceptableValueBase)(object)new AcceptableValueRange<int>(2, 10), new object[0])); ShowHud = ((BaseUnityPlugin)this).Config.Bind<bool>("3 - HUD", "Enabled", true, "Shows your allies' health, stamina, eitr, buffs and weapon."); HudPosition = ((BaseUnityPlugin)this).Config.Bind<Vector2>("3 - HUD", "Position", new Vector2(20f, 330f), "Top left corner of the party HUD, in pixels from the top left of the screen. Easier to set with the edit key."); HudScale = ((BaseUnityPlugin)this).Config.Bind<float>("3 - HUD", "Scale", 1f, new ConfigDescription("Size of the party HUD.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 2.5f), new object[0])); ShowStamina = ((BaseUnityPlugin)this).Config.Bind<bool>("3 - HUD", "ShowStamina", true, "Stamina bar."); ShowEitr = ((BaseUnityPlugin)this).Config.Bind<bool>("3 - HUD", "ShowEitr", true, "Eitr bar (only for allies who have eitr)."); ShowBuffs = ((BaseUnityPlugin)this).Config.Bind<bool>("3 - HUD", "ShowBuffs", true, "Active effects (rested, wet, mead, set bonus...)."); MaxBuffs = ((BaseUnityPlugin)this).Config.Bind<int>("3 - HUD", "MaxBuffs", 8, new ConfigDescription("Most effect icons per ally.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 16), new object[0])); ShowWeapon = ((BaseUnityPlugin)this).Config.Bind<bool>("3 - HUD", "ShowWeapon", true, "Icon of the weapon in the ally's hand."); ShowDistance = ((BaseUnityPlugin)this).Config.Bind<bool>("3 - HUD", "ShowDistance", true, "How far each ally is."); HudBackgroundOpacity = ((BaseUnityPlugin)this).Config.Bind<float>("3 - HUD", "BackgroundOpacity", 0.85f, new ConfigDescription("How opaque the HUD background is (0 = no background, 1 = solid).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), new object[0])); HudOrder = ((BaseUnityPlugin)this).Config.Bind<string>("3 - HUD", "Order", "", "Order of your allies in the HUD (names separated by |). Easier to set by dragging them in edit mode."); SilhouetteEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("4 - Silhouette", "Enabled", true, "When an ally is behind a wall, tree or hill, the hidden part of them shows as a coloured silhouette. Parts you can see directly are left as they are."); SilhouetteColor = ((BaseUnityPlugin)this).Config.Bind<Color>("4 - Silhouette", "Color", new Color(1f, 0.85f, 0.3f, 1f), "Colour of the silhouette."); SilhouetteOpacity = ((BaseUnityPlugin)this).Config.Bind<float>("4 - Silhouette", "Opacity", 0.5f, new ConfigDescription("How opaque the silhouette is.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.05f, 1f), new object[0])); SilhouetteMaxDistance = ((BaseUnityPlugin)this).Config.Bind<float>("4 - Silhouette", "MaxDistance", 80f, new ConfigDescription("Allies farther than this (metres) get no silhouette.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 300f), new object[0])); SilhouetteMode = ((BaseUnityPlugin)this).Config.Bind<SilhouetteStyle>("4 - Silhouette", "Style", SilhouetteStyle.Fill, "Fill = the hidden part of the ally is filled with the colour. Outline = only the outer edge of the hidden part. AlwaysOnTop = the whole ally, always (for testing)."); SilhouetteOutlineWidth = ((BaseUnityPlugin)this).Config.Bind<int>("4 - Silhouette", "OutlineWidth", 3, new ConfigDescription("Thickness of the outline, in pixels.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 10), new object[0])); SilhouetteMargin = ((BaseUnityPlugin)this).Config.Bind<float>("4 - Silhouette", "VisibleMargin", 15f, new ConfigDescription("Centimetres of tolerance when deciding that a part of the ally is seen directly. Raise it if feet or parts touching the ground get coloured; lower it if parts just behind a wall don't show.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 50f), new object[0])); SilhouetteOnSelf = ((BaseUnityPlugin)this).Config.Bind<bool>("4 - Silhouette", "TestOnYourself", false, "Draws the silhouette on your own character too, so you can try it alone (stand behind a tree in third person)."); CompassEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("5 - Compass", "Enabled", true, "Shows each ally on the Nav Compass bar as a coloured circle with their initial (needs the NavCompass mod)."); CompassMaxDistance = ((BaseUnityPlugin)this).Config.Bind<float>("5 - Compass", "MaxDistance", 0f, new ConfigDescription("Allies farther than this (metres) are not shown on the compass. 0 = always shown.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 10000f), new object[0])); CompassIconSize = ((BaseUnityPlugin)this).Config.Bind<float>("5 - Compass", "IconSize", 20f, new ConfigDescription("Size of the ally icon on the compass.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(10f, 40f), new object[0])); ChatColor = ((BaseUnityPlugin)this).Config.Bind<Color>("6 - Chat", "Color", new Color(0.55f, 0.85f, 1f, 1f), "Colour of party chat messages. Type /p and your message in the chat to talk to your party only."); ChatInHud = ((BaseUnityPlugin)this).Config.Bind<bool>("6 - Chat", "ShowInHud", true, "Also shows each ally's last message under their part of the party HUD for a few seconds."); ChatHudSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("6 - Chat", "HudSeconds", 10f, new ConfigDescription("How long a message stays in the party HUD.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(2f, 60f), new object[0])); MapFindButton = ((BaseUnityPlugin)this).Config.Bind<bool>("7 - Map", "FindPartyButton", true, "A button for each ally on the large map: click a name and the map zooms out, glides to that ally and zooms back in."); MapFindPosition = ((BaseUnityPlugin)this).Config.Bind<Vector2>("7 - Map", "ButtonPosition", new Vector2(-30f, 80f), "Where the column of ally buttons sits on the screen, in pixels from the top-left corner. Negative numbers count from the right or bottom edge."); MapFindZoom = ((BaseUnityPlugin)this).Config.Bind<float>("7 - Map", "ZoomOnAlly", 0.035f, new ConfigDescription("How close the map zooms in on the ally (smaller = closer).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.01f, 0.5f), new object[0])); MapFindSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("7 - Map", "FlightTime", 1f, new ConfigDescription("How long the trip across the map takes (1 = about 1.8 seconds).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.2f, 4f), new object[0])); DetailedLog = ((BaseUnityPlugin)this).Config.Bind<bool>("9 - Debug", "DetailedLog", false, "Writes details to the BepInEx log."); Friends.Load(); new Harmony("felih.Warband").PatchAll(typeof(Plugin).Assembly); Log.LogInfo((object)"Warband 1.3.0 loaded"); } private void Update() { Party.Update(); Ui.Update(); Gift.Update(); } private void LateUpdate() { Silhouette.LateUpdate(); Compass.LateUpdate(); } private void OnGUI() { Ui.OnGUI(); MapFind.OnGUI(); } internal static void Debug(string msg) { if (DetailedLog.Value) { Log.LogInfo((object)msg); } } internal static void Message(string text) { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null) { ((Character)localPlayer).Message((MessageType)1, text, 0, (Sprite)null, false); } Debug("[msg] " + text); } internal static void Center(string text) { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null) { ((Character)localPlayer).Message((MessageType)2, text, 0, (Sprite)null, false); } Debug("[msg] " + text); } internal static bool Typing() { if ((Object)(object)Chat.instance != (Object)null && Chat.instance.HasFocus()) { return true; } if (Console.IsVisible() || TextInput.IsVisible() || Minimap.InTextInput()) { return true; } if (Menu.IsVisible()) { return true; } return false; } } internal static class Silhouette { private class Cached { public Renderer[] Renderers; public int[] SubMeshes; public float At; } private const int AllyBit = 1; private const int SeenBit = 2; private const int NearBit = 4; private const int NearSeenBit = 8; private const int AllBits = 15; private static Camera _cam; private static CameraEvent _event; private static CommandBuffer _cb; private static Material _clear; private static Material _markAlly; private static Material _markSeen; private static Material _markNear; private static Material _markNearSeen; private static Material _paintFill; private static Material _paintRing; private static Material _paintAll; private static Mesh _quad; private static bool _made; private static bool _hooked; private static readonly Dictionary<Player, Cached> Cache = new Dictionary<Player, Cached>(); private static readonly List<Player> Targets = new List<Player>(); private static float _nextPrune; private static float _nextLog; private static string _lastUsed = ""; internal static void LateUpdate() { //IL_0018: 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_0027: 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_0060: 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_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Expected O, but got Unknown //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Expected O, but got Unknown //IL_009a: 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_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Expected O, but got Unknown Camera val = (((Object)(object)GameCamera.instance != (Object)null) ? Utils.GetMainCamera() : null); CameraEvent val2 = (CameraEvent)24; if ((Object)(object)val != (Object)(object)_cam || val2 != _event) { if ((Object)(object)_cam != (Object)null && _cb != null) { _cam.RemoveCommandBuffer(_event, _cb); } _cam = val; _event = val2; if ((Object)(object)_cam != (Object)null) { if (_cb == null) { _cb = new CommandBuffer(); _cb.name = "Warband silhouettes"; } _cam.AddCommandBuffer(_event, _cb); Plugin.Debug(string.Concat("[silhouette] attached to camera ", ((Object)_cam).name, " after ", _event, " (", _cam.actualRenderingPath, ", reversed depth ", SystemInfo.usesReversedZBuffer, ", hdr ", _cam.allowHDR, ")"));