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 Leaderboard v1.1.0
plugins/NuckflareLeaderboard/NuckflareLeaderboard.dll
Decompiled 2 days agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Jotunn.Configs; using Jotunn.Entities; using Jotunn.Managers; using Jotunn.Utils; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.Rendering; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("NuckflareLeaderboard")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.1.0.0")] [assembly: AssemblyInformationalVersion("1.1.0")] [assembly: AssemblyProduct("NuckflareLeaderboard")] [assembly: AssemblyTitle("NuckflareLeaderboard")] [assembly: AssemblyVersion("1.1.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace NuckflareLeaderboard { public class BoardTexts : MonoBehaviour { public TMP_Text Title; public TMP_Text Sub; public TMP_Text[] Columns; public Color Ink; public Color Highlight; } public class LeaderBoard : MonoBehaviour, Hoverable, Interactable { private const string SortKey = "nf_lb_sort"; private static readonly List<LeaderBoard> All = new List<LeaderBoard>(); private ZNetView _nview; private BoardTexts _texts; private Piece _piece; private Renderer[] _renderers; private float _range; private int _shownSort = -1; private int _shownVersion = -1; private int _pendingSort = -1; private float _pendingUntil; private float _resetArmedAt = -100f; private int Sort { get { if ((Object)(object)_nview == (Object)null || !_nview.IsValid()) { return 0; } int num = Mathf.Clamp(_nview.GetZDO().GetInt("nf_lb_sort", 0), 0, 4); if (_pendingSort >= 0 && (num == _pendingSort || Time.time > _pendingUntil)) { _pendingSort = -1; } if (_pendingSort < 0) { return num; } return _pendingSort; } } private static bool LocalAdmin { get { if ((Object)(object)ZNet.instance != (Object)null) { return ZNet.instance.LocalPlayerIsAdminOrHost(); } return false; } } private void Awake() { //IL_0087: Unknown result type (might be due to invalid IL or missing references) _nview = ((Component)this).GetComponent<ZNetView>(); _piece = ((Component)this).GetComponent<Piece>(); _texts = ((Component)this).GetComponentInChildren<BoardTexts>(true); if (!((Object)(object)_nview == (Object)null) && _nview.GetZDO() != null && !((Object)(object)_texts == (Object)null)) { Renderer[] componentsInChildren = (Renderer[])(object)((Component)_texts).GetComponentsInChildren<MeshRenderer>(true); _renderers = componentsInChildren; BoxCollider componentInChildren = ((Component)_texts).GetComponentInChildren<BoxCollider>(true); _range = 15f * (((Object)(object)componentInChildren != (Object)null) ? componentInChildren.size.x : 2f); _nview.Register<int>("NfLb_SetSort", (Action<long, int>)RPC_SetSort); All.Add(this); } } private void OnDestroy() { All.Remove(this); } internal static void UpdateAll() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) if (All.Count == 0) { return; } Camera mainCamera = Utils.GetMainCamera(); if ((Object)(object)mainCamera == (Object)null) { return; } Vector3 position = ((Component)mainCamera).transform.position; for (int num = All.Count - 1; num >= 0; num--) { LeaderBoard leaderBoard = All[num]; if ((Object)(object)leaderBoard == (Object)null) { All.RemoveAt(num); } else { leaderBoard.Tick(position); } } } private void Tick(Vector3 eye) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) int sort = Sort; if (sort != _shownSort || BoardData.Version != _shownVersion) { float num = Vector3.Distance(eye, ((Component)_texts).transform.position); if (!(num > _range) && (!(num > 8f) || OnScreen())) { _shownSort = sort; _shownVersion = BoardData.Version; BoardText.Apply(_texts, BoardData.Entries, sort); } } } private bool OnScreen() { Renderer[] renderers = _renderers; foreach (Renderer val in renderers) { if ((Object)(object)val != (Object)null && val.isVisible) { return true; } } return false; } public string GetHoverText() { string text = GetHoverName() + "\n[<color=yellow><b>$KEY_Use</b></color>] $nf_lb_sort: $" + BoardText.ModeToken(Sort); if (LocalAdmin) { text += "\n[<color=yellow><b>$KEY_AltPlace + $KEY_Use</b></color>] $nf_lb_reset"; } return Localization.instance.Localize(text); } public string GetHoverName() { return Localization.instance.Localize(((Object)(object)_piece != (Object)null) ? _piece.m_name : "$piece_nf_leaderboard"); } public float GetHoverOffset() { return 0f; } public bool Interact(Humanoid user, bool hold, bool alt) { if (hold || (Object)(object)_nview == (Object)null || !_nview.IsValid()) { return false; } if (alt) { if (!LocalAdmin) { Message("nf_lb_reset_denied"); } else if (Time.time - _resetArmedAt > 5f) { _resetArmedAt = Time.time; Message("nf_lb_reset_confirm"); } else { _resetArmedAt = -100f; ZRoutedRpc.instance.InvokeRoutedRPC("NfLb_Reset", Array.Empty<object>()); } return true; } int num = (_pendingSort = (Sort + 1) % 5); _pendingUntil = Time.time + 3f; _nview.InvokeRPC("NfLb_SetSort", new object[1] { num }); return true; } private static void Message(string token) { MessageHud instance = MessageHud.instance; if (instance != null) { instance.ShowMessage((MessageType)2, Texts.L(token), 0, (Sprite)null, false, true); } } public bool UseItem(Humanoid user, ItemData item) { return false; } private void RPC_SetSort(long sender, int value) { if (_nview.IsOwner()) { _nview.GetZDO().Set("nf_lb_sort", Mathf.Clamp(value, 0, 4)); } } } internal static class BoardText { internal const int Modes = 5; private static readonly string[] ModeTokens = new string[5] { "nf_lb_maxdmg", "nf_lb_total", "nf_lb_kills", "nf_lb_bosses", "nf_lb_deaths" }; private static readonly CultureInfo Inv = CultureInfo.InvariantCulture; internal static string ModeToken(int sort) { return ModeTokens[Mathf.Clamp(sort, 0, 4)]; } private static double Value(Entry e, int mode) { return mode switch { 0 => e.MaxHit, 1 => e.Damage, 2 => e.Kills, 3 => e.Bosses, _ => e.Deaths, }; } internal static void Apply(BoardTexts t, List<Entry> entries, int sort) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) string text = "#" + ColorUtility.ToHtmlStringRGB(t.Highlight); string text2 = "#" + ColorUtility.ToHtmlStringRGB(t.Ink) + "B0"; List<Entry> list = (from e in entries orderby Value(e, sort) descending, e.MaxHit descending, e.Damage descending, e.Name select e).Take(Mathf.Max(1, Plugin.MaxRows.Value)).ToList(); float num = Mathf.Clamp(t.Columns[0].rectTransform.sizeDelta.y / ((float)Mathf.Max(list.Count, 5) + 1.3f), 20f, 40f); float num2 = Mathf.Round(num * 0.66f); float size = Mathf.Round(num * 0.36f); Set(t.Title, "<cspace=0.08em><b>" + Texts.L("nf_lb_title") + "</b></cspace>"); Set(t.Sub, "<color=" + text2 + ">" + Texts.L("nf_lb_sorting") + ":</color> <color=" + text + "><b>" + Texts.L(ModeTokens[sort]) + "</b></color>"); StringBuilder[] array = new StringBuilder[t.Columns.Length]; for (int num3 = 0; num3 < array.Length; num3++) { array[num3] = new StringBuilder($"<line-height={num:0}>"); } Head(array[0], "#", text2, size); Head(array[1], Texts.L("nf_lb_player"), text2, size); for (int num4 = 0; num4 < 5; num4++) { Head(array[2 + num4], Texts.L(ModeTokens[num4]), (num4 == sort) ? text : text2, size); } for (int num5 = 0; num5 < list.Count; num5++) { Entry entry = list[num5]; string text3 = ((num5 == 0) ? "<b>" : ""); string text4 = ((num5 == 0) ? "</b>" : ""); array[0].Append($"\n<size={num2:0}><color={text2}>{num5 + 1}</color></size>"); array[1].Append($"\n<size={num2:0}>{text3}<noparse>{entry.Name}</noparse>{text4}</size>"); for (int num6 = 0; num6 < 5; num6++) { string text5 = ((num6 == 0) ? Full(Value(entry, num6)) : Compact(Value(entry, num6))); array[2 + num6].Append((num6 == sort) ? $"\n<size={num2:0}><color={text}><b>{text5}</b></color></size>" : $"\n<size={num2:0}>{text3}{text5}{text4}</size>"); } } if (list.Count == 0) { array[1].Append(string.Format("\n<size={0:0}><color={1}>{2}</color></size>", num2, text2, Texts.L("nf_lb_empty"))); } for (int num7 = 0; num7 < array.Length; num7++) { Set(t.Columns[num7], array[num7].ToString()); } } private static void Set(TMP_Text t, string text) { if (t.text != text) { t.text = text; } } private static void Head(StringBuilder sb, string text, string color, float size) { sb.Append($"<size={size:0}><color={color}><cspace=0.04em>{text.ToUpperInvariant()}</cspace></color></size>"); } private static string Full(double v) { return Math.Floor(v).ToString("#,0", Inv); } internal static string Compact(double v) { if (v < 100000.0) { return Full(v); } string[] array = new string[4] { "K", "M", "B", "T" }; double num = v / 1000.0; int num2 = 0; while (num >= 1000.0 && num2 < array.Length - 1) { num /= 1000.0; num2++; } return ((num < 100.0) ? (Math.Floor(num * 10.0) / 10.0).ToString("0.#", Inv) : Math.Floor(num).ToString("0", Inv)) + array[num2]; } } internal static class BoardPiece { private const float W = 2f; private const float H = 1.3f; private const float Frame = 0.1f; private const float FrameDepth = 0.12f; private const float PanelDepth = 0.06f; private const float Pad = 0.05f; private const float HeaderH = 0.24f; private const float DividerH = 0.04f; private const float Unit = 0.0025f; internal static readonly (string prefab, string token, float scale)[] Sizes = new(string, string, float)[5] { ("nf_leaderboard", "piece_nf_leaderboard_s", 1f), ("nf_leaderboard_m", "piece_nf_leaderboard_m", 1.5f), ("nf_leaderboard_l", "piece_nf_leaderboard_l", 2f), ("nf_leaderboard_xl", "piece_nf_leaderboard_xl", 3f), ("nf_leaderboard_xxl", "piece_nf_leaderboard_xxl", 4f) }; internal static readonly Dictionary<string, GameObject> Prefabs = new Dictionary<string, GameObject>(); internal static GameObject PanelSource; internal static GameObject BeamSource; internal static GameObject WallSource; internal static bool PanelTurn = true; internal static GameObject Prefab { get { if (!Prefabs.TryGetValue(Sizes[0].prefab, out var value)) { return null; } return value; } } internal static void Register() { PrefabManager.OnVanillaPrefabsAvailable += Create; } private static void Create() { PrefabManager.OnVanillaPrefabsAvailable -= Create; PanelSource = Parts.Find("wood_floor", "woodwall"); BeamSource = Parts.Find("darkwood_beam", "wood_beam"); WallSource = Parts.Find("woodwall"); if ((Object)(object)PanelSource == (Object)null || (Object)(object)BeamSource == (Object)null) { Plugin.Log.LogError((object)"Board pieces not created: vanilla floor / beam prefab missing"); return; } string[] array = new string[4] { "wood_floor", "woodwall", "wood_beam", "darkwood_beam" }; foreach (string text in array) { GameObject val = Parts.Find(text); if ((Object)(object)val != (Object)null) { Plugin.Log.LogInfo((object)Parts.Describe(val)); } } GameObject obj = Parts.Find("sign"); TextMeshProUGUI val2 = ((obj == null) ? null : obj.GetComponent<Sign>()?.m_textWidget); if ((Object)(object)val2 != (Object)null) { Plugin.Log.LogInfo((object)$"sign text material: {((Object)((TMP_Text)val2).fontSharedMaterial).name}[{((Object)((TMP_Text)val2).fontSharedMaterial.shader).name} q{((TMP_Text)val2).fontSharedMaterial.renderQueue}]"); } (string, string, float)[] sizes = Sizes; for (int i = 0; i < sizes.Length; i++) { (string, string, float) tuple = sizes[i]; try { Build(tuple.Item1, tuple.Item2, tuple.Item3); } catch (Exception arg) { Plugin.Log.LogError((object)$"Board piece {tuple.Item1} not created: {arg}"); } } } private static void Build(string prefabName, string token, float s) { //IL_0714: Unknown result type (might be due to invalid IL or missing references) //IL_071e: Expected O, but got Unknown //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Expected O, but got Unknown //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0143: 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_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Expected O, but got Unknown //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_021b: Unknown result type (might be due to invalid IL or missing references) //IL_022b: Unknown result type (might be due to invalid IL or missing references) //IL_0232: 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_027c: Unknown result type (might be due to invalid IL or missing references) //IL_0281: Unknown result type (might be due to invalid IL or missing references) //IL_0293: Unknown result type (might be due to invalid IL or missing references) //IL_0298: Unknown result type (might be due to invalid IL or missing references) //IL_029d: Unknown result type (might be due to invalid IL or missing references) //IL_0540: Unknown result type (might be due to invalid IL or missing references) //IL_0545: Unknown result type (might be due to invalid IL or missing references) //IL_054d: Unknown result type (might be due to invalid IL or missing references) //IL_0579: Unknown result type (might be due to invalid IL or missing references) //IL_0587: Unknown result type (might be due to invalid IL or missing references) //IL_05fb: Unknown result type (might be due to invalid IL or missing references) //IL_0600: Unknown result type (might be due to invalid IL or missing references) //IL_0611: Unknown result type (might be due to invalid IL or missing references) //IL_061c: Unknown result type (might be due to invalid IL or missing references) //IL_0627: Unknown result type (might be due to invalid IL or missing references) //IL_0632: Unknown result type (might be due to invalid IL or missing references) //IL_063f: Expected O, but got Unknown //IL_064a: Unknown result type (might be due to invalid IL or missing references) //IL_0654: Expected O, but got Unknown //IL_065b: Unknown result type (might be due to invalid IL or missing references) //IL_0660: Unknown result type (might be due to invalid IL or missing references) //IL_0665: Unknown result type (might be due to invalid IL or missing references) //IL_0671: Unknown result type (might be due to invalid IL or missing references) //IL_0676: Unknown result type (might be due to invalid IL or missing references) //IL_067b: Unknown result type (might be due to invalid IL or missing references) //IL_0680: Unknown result type (might be due to invalid IL or missing references) //IL_0685: Unknown result type (might be due to invalid IL or missing references) //IL_068a: Unknown result type (might be due to invalid IL or missing references) //IL_0693: Unknown result type (might be due to invalid IL or missing references) //IL_0698: Unknown result type (might be due to invalid IL or missing references) //IL_06a8: Unknown result type (might be due to invalid IL or missing references) //IL_06ad: Unknown result type (might be due to invalid IL or missing references) //IL_06af: Unknown result type (might be due to invalid IL or missing references) //IL_06b9: Unknown result type (might be due to invalid IL or missing references) //IL_06c4: Unknown result type (might be due to invalid IL or missing references) //IL_06d4: Expected O, but got Unknown float num = 2f * s; float num2 = 1.3f * s; float num3 = 0.1f * s; float num4 = 0.12f * s; float num5 = 0.06f * s; float num6 = 0.05f * s; float num7 = 0.24f * s; float num8 = 0.04f * s; float num9 = 0.0025f * s; GameObject val = PrefabManager.Instance.CreateClonedPrefab(prefabName, "sign"); Transform transform = val.transform; Sign component = val.GetComponent<Sign>(); TextMeshProUGUI template = component.m_textWidget; Canvas componentInParent = ((Component)template).GetComponentInParent<Canvas>(true); if ((Object)(object)componentInParent == (Object)null) { throw new Exception("sign canvas not found"); } int layer = val.layer; Collider[] componentsInChildren = ((Component)transform).GetComponentsInChildren<Collider>(true); int layer2 = ((componentsInChildren.Length != 0) ? ((Component)componentsInChildren[0]).gameObject.layer : val.layer); List<MeshRenderer> list = ((Component)transform).GetComponentsInChildren<MeshRenderer>(true).ToList(); GameObject val2 = new GameObject("NfBoard") { layer = layer }; val2.transform.SetParent(transform, false); val2.transform.rotation = ((Component)componentInParent).transform.rotation; Bounds val3 = BoundsIn(val2.transform, list); val2.transform.position = val2.transform.TransformPoint(new Vector3(((Bounds)(ref val3)).center.x, ((Bounds)(ref val3)).center.y, ((Bounds)(ref val3)).max.z)); GameObject val4 = BuildVisual(val2.transform, PanelSource, PanelTurn, BeamSource, layer, s); float num10 = num2 / 2f - num3 - num6; float num11 = (0f - num2) / 2f + num3 + num6; float num12 = num - 2f * (num3 + num6); RectTransform canvasRT = (RectTransform)((Component)componentInParent).transform; ((Transform)canvasRT).SetParent(val2.transform, false); ((Transform)canvasRT).localRotation = Quaternion.identity; ((Transform)canvasRT).localPosition = new Vector3(0f, (num10 + num11) / 2f, 0f - num5 - 0.03f - 0.006f * s); ((Transform)canvasRT).localScale = Vector3.one * num9; canvasRT.sizeDelta = new Vector2(num12 / num9, (num10 - num11) / num9); Parts.SetLayer(((Component)canvasRT).gameObject, layer); BoardTexts boardTexts = val2.AddComponent<BoardTexts>(); boardTexts.Ink = ((Graphic)template).color; boardTexts.Highlight = Color32.op_Implicit(new Color32((byte)122, (byte)30, (byte)14, byte.MaxValue)); float iw = num12 / num9; float ih = (num10 - num11) / num9; float num13 = (num10 - (num2 / 2f - num3 - num7 + num8 / 2f)) / num9; float tableTop = num13 + num8 / num9 + 10f; boardTexts.Title = MakeText((TMP_Text)(object)template, canvasRT, "Title", 0f, 0f, iw, 50f, (TextAlignmentOptions)258, 44f); boardTexts.Sub = MakeText((TMP_Text)(object)template, canvasRT, "Sub", 0f, num13 - 25f, iw, 24f, (TextAlignmentOptions)258, 19f); (string, float, float, TextAlignmentOptions)[] source = new(string, float, float, TextAlignmentOptions)[7] { ("Rank", 0f, 0.04f, (TextAlignmentOptions)260), ("Name", 0.055f, 0.32f, (TextAlignmentOptions)257), ("MaxDamage", 0.33f, 0.47f, (TextAlignmentOptions)260), ("TotalDamage", 0.48f, 0.64f, (TextAlignmentOptions)260), ("Kills", 0.65f, 0.76f, (TextAlignmentOptions)260), ("Bosses", 0.77f, 0.87f, (TextAlignmentOptions)260), ("Deaths", 0.88f, 1f, (TextAlignmentOptions)260) }; boardTexts.Columns = source.Select(((string name, float from, float to, TextAlignmentOptions align) c) => MakeText((TMP_Text)(object)template, canvasRT, c.name, c.from * iw, tableTop, (c.to - c.from) * iw, ih - tableTop, c.align, 26f)).ToArray(); boardTexts.Columns[1].overflowMode = (TextOverflowModes)1; Object.DestroyImmediate((Object)(object)((Component)template).gameObject); foreach (MeshRenderer item in list) { if (!((Object)(object)item == (Object)null)) { MeshFilter component2 = ((Component)item).GetComponent<MeshFilter>(); Object.DestroyImmediate((Object)(object)item); if ((Object)(object)component2 != (Object)null) { Object.DestroyImmediate((Object)(object)component2); } } } LODGroup[] componentsInChildren2 = ((Component)transform).GetComponentsInChildren<LODGroup>(true); for (int num14 = 0; num14 < componentsInChildren2.Length; num14++) { Object.DestroyImmediate((Object)(object)componentsInChildren2[num14]); } Collider[] array = componentsInChildren; foreach (Collider val5 in array) { if ((Object)(object)val5 != (Object)null) { Object.DestroyImmediate((Object)(object)val5); } } GameObject val6 = new GameObject("Collider") { layer = layer2 }; val6.transform.SetParent(val2.transform, false); BoxCollider obj = val6.AddComponent<BoxCollider>(); obj.center = new Vector3(0f, 0f, (0f - num4) / 2f); obj.size = new Vector3(num, num2, num4); WearNTear component3 = val.GetComponent<WearNTear>(); if ((Object)(object)component3 != (Object)null) { component3.m_new = val4; component3.m_worn = val4; component3.m_broken = val4; Parts.Null(component3, "m_wet", "m_snow", "m_snowWorn", "m_snowBroken"); } Object.DestroyImmediate((Object)(object)component); val.AddComponent<LeaderBoard>(); PieceConfig val7 = new PieceConfig { Name = "$" + token, Description = "$piece_nf_leaderboard_desc", PieceTable = PieceTables.Hammer, Category = PieceCategories.Furniture, CraftingStation = CraftingStations.Workbench }; val7.AddRequirement(new RequirementConfig("Wood", 10, 0, true)); try { Quaternion val8 = Quaternion.Inverse(Quaternion.LookRotation(val2.transform.localRotation * Vector3.back, val2.transform.localRotation * Vector3.up)); Sprite val9 = RenderManager.Instance.Render(new RenderRequest(val) { Rotation = Quaternion.Euler(8f, -20f, 0f) * val8, Width = 128, Height = 128 }); if ((Object)(object)val9 != (Object)null) { val7.Icon = val9; } } catch (Exception ex) { Plugin.Log.LogWarning((object)("Icon render: " + ex.Message)); } PieceManager.Instance.AddPiece(new CustomPiece(val, false, val7)); Prefabs[prefabName] = val; Plugin.Log.LogInfo((object)$"Board piece {prefabName} ready ({num}x{num2} m)"); } internal static GameObject BuildVisual(Transform board, GameObject panelSrc, bool turn, GameObject beamSrc, int layer, float s) { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Expected O, but got Unknown //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0078: 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_0081: 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_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01fd: Unknown result type (might be due to invalid IL or missing references) //IL_020f: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Unknown result type (might be due to invalid IL or missing references) float num = 2f * s; float num2 = 1.3f * s; float num3 = 0.1f * s; float num4 = 0.12f * s; float num5 = 0.06f * s; float num6 = 0.24f * s; float num7 = 0.04f * s; float num8 = num4 * 0.7f; GameObject val = new GameObject("Visual") { layer = layer }; val.transform.SetParent(board, false); Quaternion orient = Parts.PanelTo(panelSrc, turn); Quaternion orient2 = Parts.LongAxisTo(beamSrc, 0); Quaternion orient3 = Parts.LongAxisTo(beamSrc, 1); Parts.Fit(panelSrc, val.transform, "Panel", new Vector3(0f, 0f, (0f - num5) / 2f), new Vector3(num - num3, num2 - num3, num5), orient, layer); Parts.Fit(beamSrc, val.transform, "Top", new Vector3(0f, num2 / 2f - num3 / 2f, (0f - num4) / 2f), new Vector3(num, num3, num4), orient2, layer); Parts.Fit(beamSrc, val.transform, "Bottom", new Vector3(0f, (0f - num2) / 2f + num3 / 2f, (0f - num4) / 2f), new Vector3(num, num3, num4), orient2, layer); Parts.Fit(beamSrc, val.transform, "Left", new Vector3((0f - num) / 2f + num3 / 2f, 0f, (0f - num4) / 2f), new Vector3(num3, num2 - 2f * num3, num4), orient3, layer); Parts.Fit(beamSrc, val.transform, "Right", new Vector3(num / 2f - num3 / 2f, 0f, (0f - num4) / 2f), new Vector3(num3, num2 - 2f * num3, num4), orient3, layer); Parts.Fit(beamSrc, val.transform, "Divider", new Vector3(0f, num2 / 2f - num3 - num6, (0f - num8) / 2f), new Vector3(num - 2f * num3, num7, num8), orient2, layer); return val; } internal static float HeightOf(float scale) { return 1.3f * scale; } internal static float WidthOf(float scale) { return 2f * scale; } private static TMP_Text MakeText(TMP_Text template, RectTransform parent, string name, float x, float y, float w, float h, TextAlignmentOptions align, float size) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0049: 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_005f: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_007c: 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_00b3: Unknown result type (might be due to invalid IL or missing references) GameObject obj = Object.Instantiate<GameObject>(((Component)template).gameObject, (Transform)(object)parent, false); ((Object)obj).name = name; TMP_Text component = obj.GetComponent<TMP_Text>(); RectTransform rectTransform = component.rectTransform; Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(0f, 1f); rectTransform.anchorMax = val; rectTransform.anchorMin = val; rectTransform.pivot = new Vector2(0f, 1f); ((Transform)rectTransform).localRotation = Quaternion.identity; ((Transform)rectTransform).localScale = Vector3.one; rectTransform.anchoredPosition = new Vector2(x, 0f - y); rectTransform.sizeDelta = new Vector2(w, h); component.alignment = align; component.enableAutoSizing = false; component.fontSize = size; component.textWrappingMode = (TextWrappingModes)0; component.overflowMode = (TextOverflowModes)0; component.richText = true; component.margin = Vector4.zero; component.text = ""; return component; } private static Bounds BoundsIn(Transform frame, List<MeshRenderer> renderers) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0061: 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) //IL_0096: 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_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) Bounds result = default(Bounds); bool flag = false; foreach (MeshRenderer renderer in renderers) { MeshFilter component = ((Component)renderer).GetComponent<MeshFilter>(); if ((Object)(object)component == (Object)null || (Object)(object)component.sharedMesh == (Object)null) { continue; } Bounds bounds = component.sharedMesh.bounds; for (int i = 0; i < 8; i++) { Vector3 val = ((Bounds)(ref bounds)).center + Vector3.Scale(((Bounds)(ref bounds)).extents, new Vector3((float)(((i & 1) != 0) ? 1 : (-1)), (float)(((i & 2) != 0) ? 1 : (-1)), (float)(((i & 4) != 0) ? 1 : (-1)))); Vector3 val2 = frame.InverseTransformPoint(((Component)renderer).transform.TransformPoint(val)); if (!flag) { result = new Bounds(val2, Vector3.zero); flag = true; } else { ((Bounds)(ref result)).Encapsulate(val2); } } } return result; } } internal class Entry { public long Id; public string Name = ""; public double Damage; public float MaxHit; public int Kills; public int Bosses; public int Deaths; public int BaseKills; public int BaseBosses; public int BaseDeaths; internal void Write(ZPackage pkg) { pkg.Write(Id); pkg.Write(Name); pkg.Write(Damage); pkg.Write(MaxHit); pkg.Write(Math.Max(0, Kills - BaseKills)); pkg.Write(Math.Max(0, Bosses - BaseBosses)); pkg.Write(Math.Max(0, Deaths - BaseDeaths)); } internal static Entry Read(ZPackage pkg) { return new Entry { Id = pkg.ReadLong(), Name = pkg.ReadString(), Damage = pkg.ReadDouble(), MaxHit = pkg.ReadSingle(), Kills = pkg.ReadInt(), Bosses = pkg.ReadInt(), Deaths = pkg.ReadInt() }; } internal Entry Shown() { return new Entry { Id = Id, Name = Name, Damage = Damage, MaxHit = MaxHit, Kills = Math.Max(0, Kills - BaseKills), Bosses = Math.Max(0, Bosses - BaseBosses), Deaths = Math.Max(0, Deaths - BaseDeaths) }; } } internal static class BoardData { private static readonly Dictionary<long, Entry> ById = new Dictionary<long, Entry>(); internal static List<Entry> Entries = new List<Entry>(); internal static int Version; internal static void OnData(long sender, ZPackage pkg) { try { if (pkg.ReadInt() == 2) { bool full = pkg.ReadBool(); int num = pkg.ReadInt(); List<Entry> list = new List<Entry>(num); for (int i = 0; i < num; i++) { list.Add(Entry.Read(pkg)); } Apply(list, full); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("Board data: " + ex.Message)); } } internal static void Apply(IEnumerable<Entry> rows, bool full) { if (full) { ById.Clear(); } foreach (Entry row in rows) { ById[row.Id] = row; } Entries = new List<Entry>(ById.Values); Version++; } } internal static class Parts { private struct Piece { public MeshFilter Filter; public MeshRenderer Renderer; public Matrix4x4 ToRoot; } internal static GameObject Find(params string[] names) { foreach (string text in names) { GameObject prefab = PrefabManager.Instance.GetPrefab(text); if ((Object)(object)prefab != (Object)null) { return prefab; } } return null; } private static List<Piece> Meshes(GameObject src) { Transform transform = src.transform; WearNTear component = src.GetComponent<WearNTear>(); Transform val = (((Object)(object)component != (Object)null && (Object)(object)component.m_new != (Object)null) ? component.m_new.transform : transform); HashSet<Renderer> hashSet = null; LODGroup val2 = ((Component)val).GetComponentInChildren<LODGroup>(true) ?? src.GetComponentInChildren<LODGroup>(true); if ((Object)(object)val2 != (Object)null && val2.GetLODs().Length != 0) { hashSet = new HashSet<Renderer>(val2.GetLODs()[0].renderers.Where((Renderer r) => (Object)(object)r != (Object)null)); } List<Piece> list = Collect(val, transform, hashSet); if (list.Count == 0 && hashSet != null) { list = Collect(val, transform, null); } return list; } private static List<Piece> Collect(Transform from, Transform root, HashSet<Renderer> only) { //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) List<Piece> list = new List<Piece>(); MeshRenderer[] componentsInChildren = ((Component)from).GetComponentsInChildren<MeshRenderer>(true); foreach (MeshRenderer val in componentsInChildren) { if (only == null || only.Contains((Renderer)(object)val)) { MeshFilter component = ((Component)val).GetComponent<MeshFilter>(); if (!((Object)(object)component == (Object)null) && !((Object)(object)component.sharedMesh == (Object)null)) { list.Add(new Piece { Filter = component, Renderer = val, ToRoot = root.worldToLocalMatrix * ((Component)val).transform.localToWorldMatrix }); } } } return list; } internal static Bounds SourceBounds(GameObject src) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_005d: 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_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) Bounds result = default(Bounds); bool flag = false; foreach (Piece item in Meshes(src)) { foreach (Vector3 item2 in Corners(item.Filter.sharedMesh.bounds)) { Matrix4x4 toRoot = item.ToRoot; Vector3 val = ((Matrix4x4)(ref toRoot)).MultiplyPoint3x4(item2); if (!flag) { result = new Bounds(val, Vector3.zero); flag = true; } else { ((Bounds)(ref result)).Encapsulate(val); } } } return result; } internal static GameObject Fit(GameObject src, Transform parent, string name, Vector3 center, Vector3 size, Quaternion orient, int layer) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown //IL_002f: 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_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Expected O, but got Unknown //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //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_007d: 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_0094: 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_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00de: 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_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0118: 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_0132: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_0189: 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) List<Piece> list = Meshes(src); Bounds val = SourceBounds(src); GameObject val2 = new GameObject(name) { layer = layer }; val2.transform.SetParent(parent, false); val2.transform.localPosition = center; val2.transform.localRotation = orient; GameObject val3 = new GameObject("fit") { layer = layer }; val3.transform.SetParent(val2.transform, false); Vector3 val4 = Abs(Quaternion.Inverse(orient) * size); Vector3 val5 = default(Vector3); ((Vector3)(ref val5))..ctor(Ratio(val4.x, ((Bounds)(ref val)).size.x), Ratio(val4.y, ((Bounds)(ref val)).size.y), Ratio(val4.z, ((Bounds)(ref val)).size.z)); val3.transform.localScale = val5; val3.transform.localPosition = -Vector3.Scale(val5, ((Bounds)(ref val)).center); foreach (Piece item in list) { GameObject val6 = new GameObject(((Object)item.Filter).name) { layer = layer }; val6.transform.SetParent(val3.transform, false); Transform transform = val6.transform; Matrix4x4 toRoot = item.ToRoot; transform.localPosition = Vector4.op_Implicit(((Matrix4x4)(ref toRoot)).GetColumn(3)); Transform transform2 = val6.transform; toRoot = item.ToRoot; transform2.localRotation = ((Matrix4x4)(ref toRoot)).rotation; Transform transform3 = val6.transform; toRoot = item.ToRoot; transform3.localScale = ((Matrix4x4)(ref toRoot)).lossyScale; val6.AddComponent<MeshFilter>().sharedMesh = item.Filter.sharedMesh; MeshRenderer obj = val6.AddComponent<MeshRenderer>(); ((Renderer)obj).sharedMaterials = ((Renderer)item.Renderer).sharedMaterials; ((Renderer)obj).shadowCastingMode = ((Renderer)item.Renderer).shadowCastingMode; ((Renderer)obj).receiveShadows = ((Renderer)item.Renderer).receiveShadows; } return val2; } internal static Quaternion LongAxisTo(GameObject src, int target) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: 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) Bounds val = SourceBounds(src); Vector3 size = ((Bounds)(ref val)).size; return AxisTo((!(size.x >= size.y) || !(size.x >= size.z)) ? ((size.y >= size.z) ? 1 : 2) : 0, target); } internal static Quaternion PanelTo(GameObject src, bool turn) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: 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) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0061: 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) Bounds val = SourceBounds(src); Vector3 size = ((Bounds)(ref val)).size; Quaternion val2 = AxisTo((!(size.x <= size.y) || !(size.x <= size.z)) ? ((size.y <= size.z) ? 1 : 2) : 0, 2); if (!turn) { return val2; } return Quaternion.Euler(0f, 0f, 90f) * val2; } internal static Quaternion WallTo(GameObject src, bool horizontalPlanks) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: 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_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0053: 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) Bounds val = SourceBounds(src); Vector3 size = ((Bounds)(ref val)).size; Quaternion val2 = ((size.x < size.z) ? Quaternion.Euler(0f, 90f, 0f) : Quaternion.identity); if (!horizontalPlanks) { return val2; } return Quaternion.Euler(0f, 0f, 90f) * val2; } private static Quaternion AxisTo(int from, int to) { //IL_0004: 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_004a: Unknown result type (might be due to invalid IL or missing references) if (from == to) { return Quaternion.identity; } if ((from == 0 && to == 1) || (from == 1 && to == 0)) { return Quaternion.Euler(0f, 0f, 90f); } if ((from == 2 && to == 0) || (from == 0 && to == 2)) { return Quaternion.Euler(0f, 90f, 0f); } return Quaternion.Euler(-90f, 0f, 0f); } internal static string Describe(GameObject src) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_008b: 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_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) Bounds val = SourceBounds(src); string text = string.Join(", ", from m in Meshes(src).SelectMany((Piece p) => ((Renderer)p.Renderer).sharedMaterials) select (!((Object)(object)m == (Object)null)) ? $"{((Object)m).name}[{((Object)m.shader).name} q{m.renderQueue}]" : "null"); return $"{((Object)src).name}: {Meshes(src).Count} mesh, size {((Bounds)(ref val)).size.x:0.00}x{((Bounds)(ref val)).size.y:0.00}x{((Bounds)(ref val)).size.z:0.00}, center {((Bounds)(ref val)).center}; {text}"; } private static float Ratio(float want, float have) { if (!(want > 0f) || !(have > 0.0001f)) { return 1f; } return want / have; } private static Vector3 Abs(Vector3 v) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0016: 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) return new Vector3(Mathf.Abs(v.x), Mathf.Abs(v.y), Mathf.Abs(v.z)); } private static IEnumerable<Vector3> Corners(Bounds b) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < 8; i++) { yield return ((Bounds)(ref b)).center + Vector3.Scale(((Bounds)(ref b)).extents, new Vector3((float)(((i & 1) != 0) ? 1 : (-1)), (float)(((i & 2) != 0) ? 1 : (-1)), (float)(((i & 4) != 0) ? 1 : (-1)))); } } internal static void SetLayer(GameObject go, int layer) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) go.layer = layer; foreach (Transform item in go.transform) { SetLayer(((Component)item).gameObject, layer); } } internal static void Null(object target, params string[] fields) { foreach (string text in fields) { Traverse val = Traverse.Create(target).Field(text); if (val.FieldExists()) { val.SetValue((object)null); } } } } [BepInPlugin("nuckflare.leaderboard", "NuckflareLeaderboard", "1.1.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { public const string Guid = "nuckflare.leaderboard"; public const string Version = "1.1.0"; internal const string RpcDamage = "NfLb_Damage"; internal const string RpcStats = "NfLb_Stats"; internal const string RpcBossKill = "NfLb_BossKill"; internal const string RpcData = "NfLb_Data"; internal const string RpcReset = "NfLb_Reset"; internal static Plugin Instance; internal static ManualLogSource Log; internal static string DataDir; internal static ConfigEntry<int> MaxRows; internal static ConfigEntry<float> NearbyRadius; private void Awake() { //IL_0084: Unknown result type (might be due to invalid IL or missing references) Instance = this; Log = ((BaseUnityPlugin)this).Logger; DataDir = Path.Combine(Paths.ConfigPath, "NuckflareLeaderboard"); Directory.CreateDirectory(DataDir); MaxRows = ((BaseUnityPlugin)this).Config.Bind<int>("Board", "Max rows", 10, "Players shown on a board."); NearbyRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Server", "Boss nearby radius", 80f, "Players within this distance (m) of a boss when it dies count as present (with the players who hit it)."); Texts.Register(); BoardPiece.Register(); new Harmony("nuckflare.leaderboard").PatchAll(typeof(Plugin).Assembly); } private void Update() { Tracker.Tick(); Server.Tick(); Preview.Tick(); } private void LateUpdate() { LeaderBoard.UpdateAll(); } private void OnApplicationQuit() { Server.Save(); } } [HarmonyPatch(typeof(Game), "Start")] internal static class GameStartPatch { private static void Postfix() { ZRoutedRpc instance = ZRoutedRpc.instance; if (instance != null) { instance.Register<ZPackage>("NfLb_Damage", (Action<long, ZPackage>)Server.OnDamage); instance.Register<ZPackage>("NfLb_Stats", (Action<long, ZPackage>)Server.OnStats); instance.Register<ZPackage>("NfLb_BossKill", (Action<long, ZPackage>)Server.OnBossKill); instance.Register<ZPackage>("NfLb_Data", (Action<long, ZPackage>)BoardData.OnData); instance.Register("NfLb_Reset", (Action<long>)Server.OnReset); if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer()) { Server.Load(); } } } } [HarmonyPatch(typeof(ZNet), "Shutdown")] internal static class ShutdownPatch { private static void Prefix() { Server.Save(); } } internal static class Preview { private const int Layer = 31; private static bool _running; private static readonly List<Entry> Sample = new List<Entry> { new Entry { Id = 1L, Name = "Mrebtww", Damage = 1284120.0, MaxHit = 1102f, Kills = 1906, Bosses = 7, Deaths = 67 }, new Entry { Id = 2L, Name = "Mind", Damage = 386115.0, MaxHit = 1284f, Kills = 1744, Bosses = 7, Deaths = 44 }, new Entry { Id = 3L, Name = "İiİiİiİ", Damage = 99950.0, MaxHit = 968f, Kills = 1390, Bosses = 6, Deaths = 41 }, new Entry { Id = 4L, Name = "Alya Vural", Damage = 96730.0, MaxHit = 611f, Kills = 412, Bosses = 2, Deaths = 18 } }; private static string Request => Path.Combine(Plugin.DataDir, "onizleme.istek"); internal static void Tick() { if (!_running && !((Object)(object)BoardPiece.Prefab == (Object)null) && !((Object)(object)FejdStartup.instance == (Object)null) && File.Exists(Request)) { _running = true; ((MonoBehaviour)Plugin.Instance).StartCoroutine(Run()); } } private static IEnumerator Run() { string mode = ""; try { mode = File.ReadAllText(Request); File.Delete(Request); } catch { } Texture.streamingTextureForceLoadAll = true; yield return (object)new WaitForSeconds(4f); try { RenderAll(); } catch (Exception ex) { Plugin.Log.LogError((object)("Preview failed: " + ex)); } Texture.streamingTextureForceLoadAll = false; File.WriteAllText(Path.Combine(Plugin.DataDir, "onizleme.bitti"), DateTime.Now.ToString("s")); if (mode.Contains("kapat")) { Application.Quit(); } } private static void RenderAll() { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_073a: Unknown result type (might be due to invalid IL or missing references) //IL_0741: 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) //IL_0047: Expected O, but got Unknown //IL_005b: 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_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: 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) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0146: 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_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01be: 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_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_02df: Unknown result type (might be due to invalid IL or missing references) //IL_02e6: Expected O, but got Unknown //IL_02f2: Unknown result type (might be due to invalid IL or missing references) //IL_02f9: Expected O, but got Unknown //IL_032f: Unknown result type (might be due to invalid IL or missing references) //IL_0355: Unknown result type (might be due to invalid IL or missing references) //IL_0390: Unknown result type (might be due to invalid IL or missing references) //IL_03b8: Unknown result type (might be due to invalid IL or missing references) //IL_03c7: Unknown result type (might be due to invalid IL or missing references) //IL_03ce: Expected O, but got Unknown //IL_0404: Unknown result type (might be due to invalid IL or missing references) //IL_0449: Unknown result type (might be due to invalid IL or missing references) //IL_044e: Unknown result type (might be due to invalid IL or missing references) //IL_0450: Unknown result type (might be due to invalid IL or missing references) //IL_0455: Unknown result type (might be due to invalid IL or missing references) //IL_0273: Unknown result type (might be due to invalid IL or missing references) //IL_0281: Unknown result type (might be due to invalid IL or missing references) //IL_02a8: Unknown result type (might be due to invalid IL or missing references) //IL_0479: Unknown result type (might be due to invalid IL or missing references) //IL_04bc: Unknown result type (might be due to invalid IL or missing references) //IL_04cc: Unknown result type (might be due to invalid IL or missing references) //IL_04d1: Unknown result type (might be due to invalid IL or missing references) //IL_04d6: Unknown result type (might be due to invalid IL or missing references) //IL_04e6: Unknown result type (might be due to invalid IL or missing references) //IL_04eb: Unknown result type (might be due to invalid IL or missing references) //IL_051a: Unknown result type (might be due to invalid IL or missing references) //IL_051d: Unknown result type (might be due to invalid IL or missing references) //IL_0522: Unknown result type (might be due to invalid IL or missing references) //IL_053e: Unknown result type (might be due to invalid IL or missing references) //IL_0543: Unknown result type (might be due to invalid IL or missing references) //IL_0548: Unknown result type (might be due to invalid IL or missing references) //IL_054b: Unknown result type (might be due to invalid IL or missing references) //IL_0550: Unknown result type (might be due to invalid IL or missing references) //IL_05b5: Unknown result type (might be due to invalid IL or missing references) //IL_05b8: Unknown result type (might be due to invalid IL or missing references) //IL_05bd: Unknown result type (might be due to invalid IL or missing references) //IL_05d1: Unknown result type (might be due to invalid IL or missing references) //IL_05ed: Unknown result type (might be due to invalid IL or missing references) //IL_05f2: Unknown result type (might be due to invalid IL or missing references) //IL_05f7: Unknown result type (might be due to invalid IL or missing references) //IL_05fc: Unknown result type (might be due to invalid IL or missing references) //IL_05ff: Unknown result type (might be due to invalid IL or missing references) //IL_0604: Unknown result type (might be due to invalid IL or missing references) //IL_0674: Unknown result type (might be due to invalid IL or missing references) //IL_0677: Unknown result type (might be due to invalid IL or missing references) //IL_067c: Unknown result type (might be due to invalid IL or missing references) //IL_0690: Unknown result type (might be due to invalid IL or missing references) //IL_0695: Unknown result type (might be due to invalid IL or missing references) //IL_069a: Unknown result type (might be due to invalid IL or missing references) //IL_069d: Unknown result type (might be due to invalid IL or missing references) //IL_06a2: Unknown result type (might be due to invalid IL or missing references) //IL_06bd: Unknown result type (might be due to invalid IL or missing references) //IL_06c0: Unknown result type (might be due to invalid IL or missing references) //IL_06c5: Unknown result type (might be due to invalid IL or missing references) //IL_06d9: Unknown result type (might be due to invalid IL or missing references) //IL_06ed: Unknown result type (might be due to invalid IL or missing references) //IL_06f2: Unknown result type (might be due to invalid IL or missing references) //IL_06f7: Unknown result type (might be due to invalid IL or missing references) //IL_06fc: Unknown result type (might be due to invalid IL or missing references) //IL_0706: Unknown result type (might be due to invalid IL or missing references) //IL_070b: Unknown result type (might be due to invalid IL or missing references) //IL_0710: Unknown result type (might be due to invalid IL or missing references) //IL_0713: Unknown result type (might be due to invalid IL or missing references) //IL_0718: Unknown result type (might be due to invalid IL or missing references) Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(0f, 4000f, 0f); GameObject val2 = new GameObject("NfPreview"); val2.transform.position = val; GameObject src = BoardPiece.WallSource ?? BoardPiece.PanelSource; GameObject val3 = new GameObject("Wall"); val3.transform.SetParent(val2.transform, false); Quaternion orient = Parts.WallTo(src, horizontalPlanks: false); Bounds val4 = Parts.SourceBounds(src); Vector3 size = ((Bounds)(ref val4)).size; float num = Mathf.Min(size.x, size.z); for (int i = -10; i < 10; i++) { for (int j = 0; j < 4; j++) { Parts.Fit(src, val3.transform, $"wall{i}{j}", new Vector3((float)i * 2f + 1f, (float)j * 2f + 1f, num / 2f + 0.001f), new Vector3(2f, 2f, num), orient, 31); } } float num2 = -16.2f; GameObject val5 = Parts.Find("wood_door"); if ((Object)(object)val5 != (Object)null) { val4 = Parts.SourceBounds(val5); Vector3 size2 = ((Bounds)(ref val4)).size; Quaternion val6 = Parts.WallTo(val5, horizontalPlanks: false); Vector3 val7 = Abs(val6 * size2); Parts.Fit(val5, val2.transform, "Door", new Vector3(num2 + val7.x / 2f, val7.y / 2f, (0f - val7.z) / 2f), Vector3.zero, val6, 31); num2 += val7.x + 0.9f; } List<(GameObject, float, Vector3)> list = new List<(GameObject, float, Vector3)>(); (string, string, float)[] sizes = BoardPiece.Sizes; Vector3 val9 = default(Vector3); for (int k = 0; k < sizes.Length; k++) { (string, string, float) tuple = sizes[k]; if (BoardPiece.Prefabs.TryGetValue(tuple.Item1, out var value)) { float num3 = BoardPiece.WidthOf(tuple.Item3); float num4 = BoardPiece.HeightOf(tuple.Item3); GameObject val8 = Object.Instantiate<GameObject>(((Component)value.transform.Find("NfBoard")).gameObject, val2.transform, false); ((Vector3)(ref val9))..ctor(num2 + num3 / 2f, 0.6f + num4 / 2f, 0f); val8.transform.localPosition = val9; val8.transform.localRotation = Quaternion.identity; BoardText.Apply(val8.GetComponent<BoardTexts>(), Sample, 0); list.Add((val8, tuple.Item3, val9)); num2 += num3 + 0.9f; } } Parts.SetLayer(val2, 31); GameObject val10 = new GameObject("NfKey"); Light obj = val10.AddComponent<Light>(); GameObject val11 = new GameObject("NfFill"); Light val12 = val11.AddComponent<Light>(); obj.type = (LightType)1; obj.cullingMask = int.MinValue; obj.intensity = 1.1f; obj.color = new Color(1f, 0.93f, 0.84f); obj.shadows = (LightShadows)2; val10.transform.rotation = Quaternion.Euler(32f, 28f, 0f); val12.type = (LightType)1; val12.cullingMask = int.MinValue; val12.intensity = 0.35f; val12.color = new Color(0.85f, 0.9f, 1f); val12.shadows = (LightShadows)0; val11.transform.rotation = Quaternion.Euler(12f, -40f, 0f); GameObject val13 = new GameObject("NfCam"); Camera val14 = val13.AddComponent<Camera>(); ((Behaviour)val14).enabled = false; val14.cullingMask = int.MinValue; val14.clearFlags = (CameraClearFlags)2; val14.backgroundColor = new Color(0.08f, 0.065f, 0.05f); val14.fieldOfView = 30f; val14.nearClipPlane = 0.05f; val14.farClipPlane = 300f; val14.allowHDR = false; val14.allowMSAA = true; bool fog = RenderSettings.fog; AmbientMode ambientMode = RenderSettings.ambientMode; Color ambientLight = RenderSettings.ambientLight; float shadowDistance = QualitySettings.shadowDistance; try { RenderSettings.fog = false; RenderSettings.ambientMode = (AmbientMode)3; RenderSettings.ambientLight = new Color(0.4f, 0.37f, 0.34f); QualitySettings.shadowDistance = 80f; Canvas.ForceUpdateCanvases(); TMP_Text[] componentsInChildren = val2.GetComponentsInChildren<TMP_Text>(true); for (int k = 0; k < componentsInChildren.Length; k++) { componentsInChildren[k].ForceMeshUpdate(false, false); } Shot(val14, val + new Vector3(0f, 3.4f, -34f), val + new Vector3(0f, 3f, 0f), "boyutlar", 2400, 1000); foreach (var item2 in list) { Vector3 pos = val + item2.Item3 + new Vector3(0f, 0f, -3.4f * item2.Item2); Vector3 target = val + item2.Item3; float item = item2.Item2; Shot(val14, pos, target, "olcek-" + item.ToString("0.0"), 1600, 1000); } foreach (var item3 in list) { Vector3 pos2 = val + item3.Item3 + Quaternion.Euler(0f, 35f, 0f) * new Vector3(0f, 0f, -3.4f * item3.Item2); Vector3 target2 = val + item3.Item3; float item = item3.Item2; Shot(val14, pos2, target2, "olcek-aci-" + item.ToString("0.0"), 1600, 1000); } if (list.Count > 0) { (GameObject, float, Vector3) tuple2 = list[list.Count - 1]; Shot(val14, val + tuple2.Item3 + new Vector3(0f, -0.4f, -13f), val + tuple2.Item3, "dev-on", 1600, 1000); Shot(val14, val + tuple2.Item3 + Quaternion.Euler(0f, -35f, 0f) * new Vector3(0f, 0f, -14f) + Vector3.down * 0.8f, val + tuple2.Item3, "dev-aci", 1600, 1000); } } finally { RenderSettings.fog = fog; RenderSettings.ambientMode = ambientMode; RenderSettings.ambientLight = ambientLight; QualitySettings.shadowDistance = shadowDistance; Object.Destroy((Object)(object)val2); Object.Destroy((Object)(object)val13); Object.Destroy((Object)(object)val10); Object.Destroy((Object)(object)val11); } } private static string Bounds(Transform t) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0076: 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) if ((Object)(object)t == (Object)null) { return "none"; } Renderer[] componentsInChildren = ((Component)t).GetComponentsInChildren<Renderer>(true); if (componentsInChildren.Length == 0) { return "no renderer"; } Bounds bounds = componentsInChildren[0].bounds; Renderer[] array = componentsInChildren; foreach (Renderer val in array) { ((Bounds)(ref bounds)).Encapsulate(val.bounds); } Transform parent = t.parent.parent; return $"world z {((Bounds)(ref bounds)).min.z:0.000}..{((Bounds)(ref bounds)).max.z:0.000} (board z {parent.position.z:0.000})"; } private static Vector3 Abs(Vector3 v) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0016: 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) return new Vector3(Mathf.Abs(v.x), Mathf.Abs(v.y), Mathf.Abs(v.z)); } private static void Shot(Camera cam, Vector3 pos, Vector3 target, string name, int w, int h) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_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_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Expected O, but got Unknown //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Expected O, but got Unknown //IL_0072: Unknown result type (might be due to invalid IL or missing references) ((Component)cam).transform.position = pos; ((Component)cam).transform.rotation = Quaternion.LookRotation(target - pos, Vector3.up); RenderTexture val = new RenderTexture(w, h, 24, (RenderTextureFormat)0) { antiAliasing = 8 }; RenderTexture active = RenderTexture.active; try { cam.targetTexture = val; cam.Render(); RenderTexture.active = val; Texture2D val2 = new Texture2D(w, h, (TextureFormat)3, false); val2.ReadPixels(new Rect(0f, 0f, (float)w, (float)h), 0, 0); val2.Apply(); File.WriteAllBytes(Path.Combine(Plugin.DataDir, "onizleme-" + name + ".png"), ImageConversion.EncodeToPNG(val2)); Object.Destroy((Object)(object)val2); } finally { cam.targetTexture = null; RenderTexture.active = active; val.Release(); Object.Destroy((Object)(object)val); } } } internal static class Server { private static readonly Dictionary<long, Entry> Entries = new Dictionary<long, Entry>(); private static readonly Dictionary<long, long> Peers = new Dictionary<long, long>(); private static readonly HashSet<long> Changed = new HashSet<long>(); private static readonly HashSet<long> NeedFull = new HashSet<long>(); private static DateTime? _resetAt; private static bool _loaded; private static bool _dirty; private static bool _fullAll; private static float _nextSave; private static float _nextPrune; private static readonly MethodInfo ListContainsId = AccessTools.Method(typeof(ZNet), "ListContainsId", (Type[])null, (Type[])null); private static readonly FieldInfo AdminList = AccessTools.Field(typeof(ZNet), "m_adminList"); private static bool Active { get { if ((Object)(object)ZNet.instance != (Object)null) { return ZNet.instance.IsServer(); } return false; } } private static string FilePath => Path.Combine(Plugin.DataDir, "istatistik.tsv"); internal static void Load() { Entries.Clear(); Peers.Clear(); Changed.Clear(); NeedFull.Clear(); _resetAt = null; try { if (File.Exists(FilePath)) { string[] array = File.ReadAllLines(FilePath, Encoding.UTF8); foreach (string text in array) { if (text.StartsWith("#reset\t")) { if (DateTime.TryParse(text.Substring(7), CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind, out var result)) { _resetAt = result; } } else { if (text.Length == 0 || text[0] == '#') { continue; } string[] array2 = text.Split(new char[1] { '\t' }); if (array2.Length >= 7) { Entry entry = new Entry { Id = long.Parse(array2[0], CultureInfo.InvariantCulture), Name = array2[1], Damage = double.Parse(array2[2], CultureInfo.InvariantCulture), MaxHit = float.Parse(array2[3], CultureInfo.InvariantCulture), Kills = Int(array2[4]), Bosses = Int(array2[5]), Deaths = Int(array2[6]) }; if (array2.Length >= 10) { entry.BaseKills = Int(array2[7]); entry.BaseBosses = Int(array2[8]); entry.BaseDeaths = Int(array2[9]); } Entries[entry.Id] = entry; } } } } Plugin.Log.LogInfo((object)($"Loaded {Entries.Count} players from {FilePath}" + (_resetAt.HasValue ? $", last reset {_resetAt:u}" : ""))); } catch (Exception ex) { Plugin.Log.LogError((object)("Load failed, starting empty: " + ex.Message)); Entries.Clear(); } _loaded = true; _fullAll = true; } private static int Int(string s) { return int.Parse(s, CultureInfo.InvariantCulture); } internal static void Save() { if (!_loaded || !_dirty) { return; } try { CultureInfo invariantCulture = CultureInfo.InvariantCulture; StringBuilder stringBuilder = new StringBuilder("#nf-leaderboard v2: id name totaldamage maxdamage kills bosses deaths basekills basebosses basedeaths\n"); if (_resetAt.HasValue) { stringBuilder.Append("#reset\t").Append(_resetAt.Value.ToString("o", invariantCulture)).Append('\n'); } foreach (Entry item in Entries.Values.OrderBy((Entry x) => x.Id)) { stringBuilder.Append(string.Join("\t", item.Id.ToString(invariantCulture), item.Name.Replace('\t', ' '), item.Damage.ToString("R", invariantCulture), item.MaxHit.ToString("R", invariantCulture), item.Kills.ToString(invariantCulture), item.Bosses.ToString(invariantCulture), item.Deaths.ToString(invariantCulture), item.BaseKills.ToString(invariantCulture), item.BaseBosses.ToString(invariantCulture), item.BaseDeaths.ToString(invariantCulture))).Append('\n'); } string text = FilePath + ".tmp"; File.WriteAllText(text, stringBuilder.ToString(), new UTF8Encoding(encoderShouldEmitUTF8Identifier: false)); if (File.Exists(FilePath)) { File.Replace(text, FilePath, null); } else { File.Move(text, FilePath); } _dirty = false; } catch (Exception ex) { Plugin.Log.LogError((object)("Save failed: " + ex.Message)); } } internal static void SetStats(long id, string name, int kills, int bosses, int deaths) { if (!Active || !_loaded || id == 0L) { return; } if (!Entries.TryGetValue(id, out var value)) { Dictionary<long, Entry> entries = Entries; Entry obj = new Entry { Id = id }; value = obj; entries[id] = obj; if (_resetAt.HasValue) { value.BaseKills = kills; value.BaseBosses = bosses; value.BaseDeaths = deaths; } _dirty = true; Changed.Add(id); } if (!string.IsNullOrEmpty(name) && value.Name != name) { value.Name = name; _dirty = true; Changed.Add(id); } if (value.Kills != kills || value.Bosses != bosses || value.Deaths != deaths) { value.Kills = kills; value.Bosses = bosses; value.Deaths = deaths; _dirty = true; Changed.Add(id); } } internal static void AddDamage(long id, long uid, string name, double total, float max) { if (!Active || !_loaded || total <= 0.0) { return; } if (id == 0L && !Peers.TryGetValue(uid, out id)) { if (uid != ZNet.GetUID() || !((Object)(object)Player.m_localPlayer != (Object)null)) { return; } id = Player.m_localPlayer.GetPlayerID(); } if (Entries.TryGetValue(id, out var value)) { if (!string.IsNullOrEmpty(name)) { value.Name = name; } value.Damage += total; if (max > value.MaxHit) { value.MaxHit = max; } _dirty = true; Changed.Add(id); } } internal static void OnDamage(long sender, ZPackage pkg) { if (!Active) { return; } try { if (pkg.ReadInt() == 1) { int num = pkg.ReadInt(); for (int i = 0; i < num; i++) { AddDamage(pkg.ReadLong(), pkg.ReadLong(), pkg.ReadString(), pkg.ReadDouble(), pkg.ReadSingle()); } } } catch (Exception ex) { Plugin.Log.LogWarning((object)("Damage report: " + ex.Message)); } } internal static void OnStats(long sender, ZPackage pkg) { if (!Active) { return; } try { if (pkg.ReadInt() == 1) { long num = pkg.ReadLong(); SetStats(num, pkg.ReadString(), pkg.ReadInt(), pkg.ReadInt(), pkg.ReadInt()); if (!Peers.ContainsKey(sender)) { Peers[sender] = num; NeedFull.Add(sender); } } } catch (Exception ex) { Plugin.Log.LogWarning((object)("Stats report: " + ex.Message)); } } internal static void OnBossKill(long sender, ZPackage pkg) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) if (!Active) { return; } try { if (pkg.ReadInt() == 1) { string prefab = pkg.ReadString(); string key = pkg.ReadString(); Vector3 pos = pkg.ReadVector3(); string killer = pkg.ReadString(); int num = pkg.ReadInt(); List<string> list = new List<string>(num); for (int i = 0; i < num; i++) { list.Add(pkg.ReadString()); } BossKill(prefab, key, pos, killer, list); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("Boss kill report: " + ex.Message)); } } internal static void BossKill(string prefab, string key, Vector3 pos, string killer, List<string> hitters) { //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) HashSet<string> hashSet = new HashSet<string>(hitters.Where((string h) => !string.IsNullOrEmpty(h))); float value = Plugin.NearbyRadius.Value; foreach (ZNetPeer peer in ZNet.instance.GetPeers()) { if (!string.IsNullOrEmpty(peer.m_playerName) && Vector3.Distance(peer.m_refPos, pos) <= value) { hashSet.Add(peer.m_playerName); } } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null && Vector3.Distance(((Component)localPlayer).transform.position, pos) <= value) { hashSet.Add(localPlayer.GetPlayerName()); } hashSet.Remove(killer ?? ""); string[] array = hashSet.OrderBy<string, string>((string x) => x, StringComparer.CurrentCultureIgnoreCase).ToArray(); BossKills.Put(key, killer, array); Plugin.Log.LogInfo((object)("Boss " + prefab + " (" + key + ") last hit: " + killer + "; with: " + string.Join(", ", array))); } internal static void OnReset(long sender) { if (!Active || !_loaded) { return; } ZNetPeer peer = ZNet.instance.GetPeer(sender); bool num = sender == ZNet.GetUID() || IsAdmin(peer); object obj; if (peer == null) { Player localPlayer = Player.m_localPlayer; obj = ((localPlayer != null) ? localPlayer.GetPlayerName() : null) ?? "server"; } else { obj = peer.m_playerName; } string text = (string)obj; if (!num) { Plugin.Log.LogWarning((object)("Reset refused for " + text + " (not an admin)")); ZRoutedRpc.instance.InvokeRoutedRPC(sender, "ShowMessage", new object[2] { 2, Texts.L("nf_lb_reset_denied") }); return; } foreach (Entry value in Entries.Values) { value.Damage = 0.0; value.MaxHit = 0f; value.BaseKills = value.Kills; value.BaseBosses = value.Bosses; value.BaseDeaths = value.Deaths; } _resetAt = DateTime.UtcNow; _dirty = true; _fullAll = true; Save(); Plugin.Log.LogInfo((object)("Leaderboard reset by " + text)); ZRoutedRpc.instance.InvokeRoutedRPC(0L, "ShowMessage", new object[2] { 2, Texts.L("nf_lb_reset_done") }); } private static bool IsAdmin(ZNetPeer peer) { if (peer == null || peer.m_rpc == null || ListContainsId == null || AdminList == null) { return false; } string hostName = peer.m_rpc.GetSocket().GetHostName(); return (bool)ListContainsId.Invoke(ZNet.instance, new object[2] { AdminList.GetValue(ZNet.instance), hostName }); } internal static void Tick() { if (!_loaded || !Active) { return; } float unscaledTime = Time.unscaledTime; if (unscaledTime >= _nextPrune) { _nextPrune = unscaledTime + 5f; HashSet<long> live = new HashSet<long>(from p in ZNet.instance.GetPeers() select p.m_uid); foreach (long item in Peers.Keys.Where((long u) => !live.Contains(u)).ToList()) { Peers.Remove(item); } } if (_fullAll) { _fullAll = false; NeedFull.Clear(); Changed.Clear(); Send(Entries.Values.ToList(), full: true, Peers.Keys); } else { if (NeedFull.Count > 0) { Send(Entries.Values.ToList(), full: true, NeedFull.Where(Peers.ContainsKey).ToList()); NeedFull.Clear(); } if (Changed.Count > 0) { List<Entry> rows = (from id in Changed.Where(Entries.ContainsKey) select Entries[id]).ToList(); Changed.Clear(); Send(rows, full: false, Peers.Keys); } } if (_dirty && unscaledTime >= _nextSave) { _nextSave = unscaledTime + 10f; Save(); } } private static void Send(List<Entry> rows, bool full, IEnumerable<long> peers) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but got Unknown if (!ZNet.instance.IsDedicated()) { BoardData.Apply(rows.Select((Entry e) => e.Shown()), full); } ZPackage val = new ZPackage(); val.Write(2); val.Write(full); val.Write(rows.Count); foreach (Entry row in rows) { row.Write(val); } foreach (long item in peers.ToList()) { if (item != ZNet.GetUID()) { ZRoutedRpc.instance.InvokeRoutedRPC(item, "NfLb_Data", new object[1] { val }); } } } } public static class BossKills { private static readonly Dictionary<string, (DateTime at, string killer, string[] with)> Recent = new Dictionary<string, (DateTime, string, string[])>(); private static string Norm(string key) { return (key ?? "").Trim().Split(new char[1] { ' ' })[0].ToLowerInvariant(); } internal static void Put(string key, string killer, string[] with) { string text = Norm(key); if (text.Length != 0 && !string.IsNullOrEmpty(killer)) { Recent[text] = (DateTime.UtcNow, killer, with ?? new string[0]); } } public static bool TryTake(string defeatKey, out string killer, out string[] with) { killer = null; with = null; string text = Norm(defeatKey); if (text.Length == 0 || !Recent.TryGetValue(text, out (DateTime, string, string[]) value)) { return false; } Recent.Remove(text); if ((DateTime.UtcNow - value.Item1).TotalSeconds > 60.0) { return false; } killer = value.Item2; with = value.Item3; return true; } } internal static class Texts { internal static void Register() { CustomLocalization localization = LocalizationManager.Instance.GetLocalization(); string text = "English"; localization.AddTranslation(ref text, new Dictionary<string, string> { { "piece_nf_leaderboard", "Leaderboard" }, { "piece_nf_leaderboard_s", "Leaderboard (Small)" }, { "piece_nf_leaderboard_m", "Leaderboard (Medium)" }, { "piece_nf_leaderboard_l", "Leaderboard (Large)" }, { "piece_nf_leaderboard_xl", "Leaderboard (Huge)" }, { "piece_nf_leaderboard_xxl", "Leaderboard (Colossal)" }, { "piece_nf_leaderboard_desc", "Hang it on a wall: max damage, total damage, kills, boss kills and deaths of every player." }, { "nf_lb_title", "LEADERBOARD" }, { "nf_lb_sort", "Sort" }, { "nf_lb_sorting", "Sorted by" }, { "nf_lb_player", "Player" }, { "nf_lb_maxdmg", "Max Damage" }, { "nf_lb_total", "Total Damage" }, { "nf_lb_kills", "Kills" }, { "nf_lb_bosses", "Bosses" }, { "nf_lb_deaths", "Deaths" }, { "nf_lb_empty", "No records yet" }, { "nf_lb_reset", "Reset" }, { "nf_lb_reset_confirm", "Press again within 5 seconds to reset the leaderboard" }, { "nf_lb_reset_denied", "Only admins can reset the leaderboard" }, { "nf_lb_reset_done", "The leaderboard has been reset" } }); } internal static string L(string token) { if (Localization.instance == null) { return token; } return Localization.instance.Localize("$" + token); } } internal static class Tracker { private class Acc { public string Name; public double Total; public float Max; } private class Hit { public Character Target; public long Id; public long Uid; public string Name; public float Shown; public float Dot; public bool Applied; } private static readonly Dictionary<(long id, long uid), Acc> Pending = new Dictionary<(long, long), Acc>(); private static readonly Stack<Hit> Hits = new Stack<Hit>(); private static readonly Dictionary<ZDOID, string> LastPlayerHit = new Dictionary<ZDOID, string>(); private static readonly FieldRef<Character, HitData> LastHit = AccessTools.FieldRefAccess<Character, HitData>("m_lastHit"); private static readonly FieldRef<Character, ZNetView> NView = AccessTools.FieldRefAccess<Character, ZNetView>("m_nview"); private static float _nextStats; private static float _lastStatsSent; internal static bool StatsChanged; private static (long id, int kills, int bosses, int deaths) _lastStats; private static Hit Current { get { if (Hits.Count <= 0) { return null; } return Hits.Peek(); } } internal static void BeginHit(Character target, HitData hit) { Hit item = null; if ((Object)(object)target != (Object)null && hit != null && !target.IsPlayer() && !target.IsTamed() && Attacker(hit, out var id, out var uid, out var name)) { item = new Hit { Target = target, Id = id, Uid = uid, Name = name }; } Hits.Push(item); } internal static void EndHit() { //IL_00f4: Unknown result type (might be due to invalid IL or missing references) if (Hits.Count == 0) { return; } Hit hit = Hits.Pop(); if (hit == null) { return; } float num = (hit.Applied ? hit.Shown : 0f) + hit.Dot; if (num <= 0f) { return; } (long, long) key = (hit.Id, (hit.Id != 0L) ? 0 : hit.Uid); if (!Pending.TryGetValue(key, out var value)) { value = (Pending[key] = new Acc()); } value.Name = hit.Name; value.Total += num; value.Max = Mathf.Max(value.Max, num); ZNetView obj = NView.Invoke(hit.Target); ZDO val = ((obj != null) ? obj.GetZDO() : null); if (val != null) { if (LastPlayerHit.Count > 4096) { LastPlayerHit.Clear(); } LastPlayerHit[val.m_uid] = hit.Name; } } internal static void BeforeApply(Character target, HitData hit, out (float health, float shown) state) { state = (health: target.GetHealth(), shown: hit.GetTotalDamage()); } internal static void AfterApply(Character target, (float health, float shown) state) { Hit current = Current; if (current != null && !((Object)(object)current.Target != (Object)(object)target) && !current.Applied && target.GetHealth() < state.health) { current.Applied = true; current.Shown = state.shown; } } internal static void AddDot(StatusEffect se, float amount) { Hit current = Current; if (current != null && !((Object)(object)se == (Object)null) && !(amount <= 0f) && !((Object)(object)se.m_character != (Object)(object)current.Target)) { current.Dot += amount; } } private static bool Attacker(HitData hit, out long id, out long uid, out string name) { //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_008c: 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_0093: 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) id = 0L; uid = (((ZDOID)(ref hit.m_attacker)).IsNone() ? 0 : ((ZDOID)(ref hit.m_attacker)).UserID); name = null; Character attacker = hit.GetAttacker(); Player val = (Player)(object)((attacker is Player) ? attacker : null); if (val != null) { id = val.GetPlayerID(); name = val.GetPlayerName(); return id != 0; } if ((Object)(object)attacker != (Object)null || ((ZDOID)(ref hit.m_attacker)).IsNone() || (Object)(object)ZNet.instance == (Object)null) { return false; } foreach (PlayerInfo player in ZNet.instance.GetPlayerList()) { if (player.m_characterID == hit.m_attacker) { name = player.m_name; return true; } } return false; } internal static void OnDeath(Character c) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: 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_0156: Expected O, but got Unknown //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) ZNetView val = NView.Invoke(c); ZDO val2 = (((Object)(object)val != (Object)null && val.IsValid()) ? val.GetZDO() : null); if (val2 == null || !val.IsOwner()) { return; } LastPlayerHit.TryGetValue(val2.m_uid, out var value); LastPlayerHit.Remove(val2.m_uid); if (!c.IsBoss() || ZRoutedRpc.instance == null) { return; } HitData obj = LastHit.Invoke(c); Character obj2 = ((obj != null) ? obj.GetAttacker() : null); Player val3 = (Player)(object)((obj2 is Player) ? obj2 : null); string text = ((val3 != null) ? val3.GetPlayerName() : (value ?? "")); List<string> list = new List<string>(); foreach (PlayerInfo player in ZNet.instance.GetPlayerList()) { if (!string.IsNullOrEmpty(player.m_name)) { int s_attackers = ZDOVars.s_attackers; if (val2.GetBool(s_attackers + player.m_name, false)) { list.Add(player.m_name); } } } string prefabName = Utils.GetPrefabName(((Component)c).gameObject); if (ZNet.instance.IsServer()) { Server.BossKill(prefabName, c.m_defeatSetGlobalKey, ((Component)c).transform.position, text, list); return; } ZPackage val4 = new ZPackage(); val4.Write(1); val4.Write(prefabName); val4.Write(c.m_defeatSetGlobalKey ?? ""); val4.Write(((Component)c).transform.position); val4.Write(text); val4.Write(list.Count); foreach (string item in list) { val4.Write(item); } ZRoutedRpc.instance.InvokeRoutedRPC("NfLb_BossKill", new object[1] { val4 }); } internal static void Tick() { if ((Object)(object)ZNet.instance == (Object)null || ZRoutedRpc.instance == null) { return; } float unscaledTime = Time.unscaledTime; if (Pending.Count > 0) { try { Flush(); } catch (Exception ex) { Plugin.Log.LogWarning((object)("Damage flush: " + ex.Message)); } } if (!StatsChanged && !(unscaledTime >= _nextStats)) { return; } StatsChanged = false; _nextStats = unscaledTime + 1f; try { Stats(unscaledTime); } catch (Exception ex2) { Plugin.Log.LogWarning((object)("Stats: " + ex2.Message)); } } private static void Flush() { //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Expected O, but got Unknown if (ZNet.instance.IsServer()) { foreach (KeyValuePair<(long, long), Acc> item in Pending) { Server.AddDamage(item.Key.Item1, item.Key.Item2, item.Value.Name, item.Value.Total, item.Value.Max); } } else { ZPackage val = new ZPackage(); val.Write(1); val.Write(Pending.Count); foreach (KeyValuePair<(long, long), Acc> item2 in Pending) { val.Write(item2.Key.Item1); val.Write(item2.Key.Item2); val.Write(item2.Value.Name ?? ""); val.Write(item2.Value.Total); val.Write(item2.Value.Max); } ZRoutedRpc.instance.InvokeRoutedRPC("NfLb_Damage", new object[1] { val }); } Pending.Clear(); } private static void Stats(float t) { //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Expected O, but got Unknown Player localPlayer = Player.m_localPlayer; PlayerProfile val = (((Object)(object)Game.instance != (Object)null) ? Game.instance.GetPlayerProfile() : null); if ((Object)(object)localPlayer == (Object)null || val == null) { return; } long playerID = localPlayer.GetPlayerID(); if (playerID == 0L) { return; } PlayerStats val2 = val.m_playerStats[0]; (long, int, int, int) tuple = (playerID, (int)val2[(PlayerStatType)6], (int)val2[(PlayerStatType)85], (int)val2[(PlayerStatType)0]); (long, int, int, int) tuple2 = tuple; (long, int, int, int) lastStats = _lastStats; if (tuple2.Item1 != lastStats.Item1 || tuple2.Item2 != lastStats.Item2 || tuple2.Item3 != lastStats.Item3 || tuple2.Item4 != lastStats.Item4 || !(t - _lastStatsSent < 30f)) { _lastStats = tuple; _lastStatsSent = t; if (ZNet.instance.IsServer()) { Server.SetStats(playerID, localPlayer.GetPlayerName(), tuple.Item2, tuple.Item3, tuple.Item4); return; } ZPackage val3 = new ZPackage(); val3.Write(1); val3.Write(playerID); val3.Write(localPlayer.GetPlayerName()); val3.Write(tuple.Item2); val3.Write(tuple.Item3); val3.Write(tuple.Item4); ZRoutedRpc.instance.InvokeRoutedRPC("NfLb_Stats", new object[1] { val3 }); } } } [HarmonyPatch(typeof(Character), "RPC_Damage")] internal static class RpcDamagePatch { private static void Prefix(Character __instance, HitData hit) { try { Tracker.BeginHit(__instance, hit); } catch (Exception ex) { Plugin.Log.LogWarning((object)("Hit start: " + ex.Message)); } } private static Exception Finalizer(Exception __exception) { try { Tracker.EndHit(); } catch (Exception ex) { Plugin.Log.LogWarning((object)("Hit end: " + ex.Message)); } return __exception; } } [HarmonyPatch(typeof(Character), "ApplyDamage")] internal static class ApplyDamagePatch { private static void Prefix(Character __instance, HitData hit, out (float, float) __state) { Tracker.BeforeApply(__instance, hit, out __state); } private static void Postfix(Character __instance, (float, float) __state) { try { Tracker.AfterApply(__instance, __state); } catch (Exception ex) { Plugin.Log.LogWarning((object)("Damage hook: " + ex.Message)); } } } [HarmonyPatch(typeof(SE_Burning), "AddFireDamage")] internal static class FirePatch { private static void Postfix(SE_Burning __instance, float damage, bool __result) { if (__result) { Tracker.AddDot((StatusEffect)(object)__instance, damage); } } } [HarmonyPatch(typeof(SE_Burning), "AddSpiritDamage")] internal static class SpiritPatch { private static void Postfix(SE_Burning __instance, float damage, bool __result) { if (__result) { Tracker.AddDot((StatusEffect)(object)__instance, damage); } } } [HarmonyPatch(typeof(SE_Poison), "AddDamage")] internal static class PoisonPatch { private static void Prefix(SE_Poison __instance, float damage, float ___m_damageLeft) { if (damage >= ___m_damageLeft) { Tracker.AddDot((StatusEffect)(object)__instance, damage); } } } [HarmonyPatch(typeof(PlayerProfile), "IncrementStat")] internal static class IncrementStatPatch { private static void Postfix(PlayerStatType stat) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Invalid comparison between Unknown and I4 //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 //IL_0009: Unknown result type (might be due to invalid IL or missing references) if ((int)stat == 6 || (int)stat == 85 || (int)stat == 0) { Tracker.StatsChanged = true; } } } [HarmonyPatch(typeof(Character), "OnDeath")] internal static class OnDeathPatch { private static void Prefix(Character __instance) { try { Tracker.OnDeath(__instance); } catch (Exception ex) { Plugin.Log.LogWarning((object)("Death hook: " + ex.Message)); } } } }