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 AstvardServerMod v2.0.2
BepInEx/plugins/Astvard.Core.dll
Decompiled 2 weeks ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.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 Astvard.Core.Net; using Astvard.Core.Placement; using Astvard.Core.Ui; using BepInEx; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.Rendering; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: InternalsVisibleTo("Astvard.Dev")] [assembly: InternalsVisibleTo("Astvard.Admin")] [assembly: InternalsVisibleTo("Astvard.Server")] [assembly: InternalsVisibleTo("Astvard.Player")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("Astvard.Core")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+d8721dbc184a53c5b52947c0c2c8980b874b1ebb")] [assembly: AssemblyProduct("Astvard.Core")] [assembly: AssemblyTitle("Astvard.Core")] [assembly: AssemblyVersion("1.0.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 Astvard.Core { internal static class Access { internal static Func<bool> Admin = () => false; internal static bool AdminInstalled; internal static bool AdminPays; internal static string AdminPaysWhy = "так настроено в админке"; internal static bool IsAdmin => Admin(); } internal static class Build { private const string Prefix = "Astvard."; private static readonly Dictionary<string, string> Called = new Dictionary<string, string> { { "Core", "ядро" }, { "Player", "игрок" }, { "Admin", "админка" }, { "Dev", "отладка" }, { "Server", "сервер" } }; private static string _here; private static ZNet _toldOn; internal static string Here => _here ?? (_here = Pack()); internal static string Say(string packed) { if (string.IsNullOrEmpty(packed)) { return ""; } int num = packed.IndexOf(": ", StringComparison.Ordinal); string text = ((num > 0) ? packed.Substring(0, num) : ""); string obj = ((num > 0) ? packed.Substring(num + 2) : packed); List<string> list = new List<string>(); Dictionary<string, List<string>> dictionary = new Dictionary<string, List<string>>(); string[] array = obj.Split(new string[1] { ", " }, StringSplitOptions.RemoveEmptyEntries); foreach (string text2 in array) { int num2 = text2.LastIndexOf(' '); if (num2 > 0) { string text3 = text2.Substring(0, num2); string text4 = text2.Substring(num2 + 1); if (!dictionary.TryGetValue(text4, out var value)) { value = (dictionary[text4] = new List<string>()); list.Add(text4); } value.Add(Called.TryGetValue(text3, out var value2) ? value2 : text3); } } string text5 = ((text.Length > 0) ? (text + ", ") : ""); if (list.Count == 0) { return text; } if (list.Count == 1) { return text5 + "сборка " + list[0]; } List<string> list3 = new List<string>(); foreach (string item in list) { list3.Add(item + " (" + string.Join(", ", dictionary[item]) + ")"); } return text5 + "сборки " + string.Join(", ", list3); } internal static string VersionOf(string packed) { if (string.IsNullOrEmpty(packed)) { return ""; } int num = packed.IndexOf(": ", StringComparison.Ordinal); if (num <= 0) { return ""; } return packed.Substring(0, num); } internal static int Compare(string mine, string theirs) { string[] array = (mine ?? "").Split(new char[1] { '.' }); string[] array2 = (theirs ?? "").Split(new char[1] { '.' }); for (int i = 0; i < 3; i++) { if (i >= array.Length || i >= array2.Length) { return 0; } if (!int.TryParse(array[i], out var result) || !int.TryParse(array2[i], out var result2)) { return 0; } if (result != result2) { if (result >= result2) { return 1; } return -1; } } return 0; } internal static string Differs(string serverPacked) { string theirs = VersionOf(serverPacked); int num = Compare("2.0.2", theirs); if (num < 0) { return "На сервере мод новее — обнови: часть кнопок может работать не так"; } if (num > 0) { return "На сервере мод старше: заходить это не мешает, но нового он ещё не умеет"; } return ""; } internal static void TellIfOther(string serverPacked) { ZNet instance = ZNet.instance; string text = Differs(serverPacked); if (!((Object)(object)instance == (Object)null) && text.Length != 0 && instance != _toldOn) { _toldOn = instance; string text2 = VersionOf(serverPacked); Plugin.Log.LogInfo((object)("The server runs the mod " + text2 + ", this client 2.0.2.")); Chat instance2 = Chat.instance; if (instance2 != null) { ((Terminal)instance2).AddString("Astvard: у тебя мод 2.0.2, на сервере " + text2 + ". " + text + "."); } } } private static string Pack() { List<string> list = new List<string>(); Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { string name = assembly.GetName().Name; if (name != null && name.StartsWith("Astvard.", StringComparison.Ordinal)) { list.Add(name.Substring("Astvard.".Length) + " " + CommitOf(assembly)); } } list.Sort(delegate(string a, string b) { bool flag = a.StartsWith("Core ", StringComparison.Ordinal); bool flag2 = b.StartsWith("Core ", StringComparison.Ordinal); return (flag != flag2) ? ((!flag) ? 1 : (-1)) : string.CompareOrdinal(a, b); }); return "2.0.2: " + string.Join(", ", list); } private static string CommitOf(Assembly assembly) { string text = ((AssemblyInformationalVersionAttribute)Attribute.GetCustomAttribute(assembly, typeof(AssemblyInformationalVersionAttribute)))?.InformationalVersion ?? ""; int num = text.IndexOf('+'); if (num < 0 || num == text.Length - 1) { return "?"; } string text2 = text.Substring(num + 1); if (text2.Length <= 7) { return text2; } return text2.Substring(0, 7); } } internal static class Headless { private static bool? _yes; internal static bool Yes { get { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Invalid comparison between Unknown and I4 if (!_yes.HasValue) { _yes = (int)SystemInfo.graphicsDeviceType == 4; } return _yes.Value; } } } [BepInPlugin("astvard.core", "Astvard Core", "2.0.2")] [BepInProcess("valheim.exe")] [BepInProcess("valheim_server.exe")] public sealed class Plugin : BaseUnityPlugin { internal const string Guid = "astvard.core"; internal const string Title = "Astvard Core"; internal const string Version = "2.0.2"; internal const int Protocol = 1; private Harmony _harmony; internal static ManualLogSource Log { get; private set; } private void Awake() { //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; ((Component)this).gameObject.AddComponent<Projection.Driver>(); ((Component)this).gameObject.AddComponent<Rules.Driver>(); ((Component)this).gameObject.AddComponent<Weather.Driver>(); ((Component)this).gameObject.AddComponent<Wind.Driver>(); if (!Headless.Yes) { ((Component)this).gameObject.AddComponent<CraftTabs.Driver>(); ((Component)this).gameObject.AddComponent<Corner.Driver>(); } _harmony = new Harmony("astvard.core"); _harmony.PatchAll(); Log.LogInfo((object)("Astvard Core 2.0.2 (protocol " + 1 + ") loaded, " + (Headless.Yes ? "headless" : "with a screen") + ".")); } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } } } namespace Astvard.Core.Ui { internal static class Corner { internal sealed class Driver : MonoBehaviour { private void Update() { Tick(); } } private const float Every = 0.25f; private const int Size = 20; private const float Width = 520f; private const float Gap = 10f; private const float FurthestBelow = 170f; private const string HeadInk = "#FFC759"; private static readonly List<Func<string>> Sayers = new List<Func<string>>(); private static readonly Vector3[] Corners = (Vector3[])(object)new Vector3[4]; private static GameObject _root; private static Text _text; private static HotkeyBar _bar; private static string _shown; private static float _at; private static bool _told; private static bool _toldNoBar; private static readonly HashSet<string> Troubles = new HashSet<string>(); internal static void Add(Func<string> says) { Sayers.Add(says); } internal static string Head(string words) { return "<color=#FFC759>" + Plain(words) + "</color>"; } internal static string Plain(string words) { return (words ?? "").Replace('<', '‹').Replace('>', '›'); } private static void Tick() { if (Time.unscaledTime < _at) { return; } _at = Time.unscaledTime + 0.25f; string text = (Covered() ? null : Gather()); if (string.IsNullOrEmpty(text)) { if ((Object)(object)_root != (Object)null && _root.activeSelf) { _root.SetActive(false); } } else if (!((Object)(object)_root == (Object)null) || Build()) { if (text != _shown) { _shown = text; _text.text = text; } bool flag = Place(); if (_root.activeSelf != flag) { _root.SetActive(flag); } } } private static bool Covered() { if (!((Object)(object)Player.m_localPlayer == (Object)null) && !((Object)(object)Root.Canvas == (Object)null) && !((Object)(object)Hud.instance == (Object)null) && Hud.instance.IsVisible() && !InventoryGui.IsVisible() && !Minimap.IsOpen() && !Menu.IsVisible()) { return StoreGui.IsVisible(); } return true; } private static string Gather() { string text = null; foreach (Func<string> sayer in Sayers) { string text2; try { text2 = sayer(); } catch (Exception ex) { if (Troubles.Add(ex.GetType().Name + ": " + ex.Message)) { Plugin.Log.LogError((object)("A line of the corner could not be said: " + ex)); } continue; } if (!string.IsNullOrEmpty(text2)) { text = ((text == null) ? text2 : (text + "\n\n" + text2)); } } return text; } private static bool Build() { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown //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_0056: 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_006b: 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_008a: 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_00ec: 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_0101: Unknown result type (might be due to invalid IL or missing references) //IL_012f: 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) if ((Object)(object)Root.Canvas == (Object)null) { return false; } _root = new GameObject("corner", new Type[1] { typeof(RectTransform) }); _root.transform.SetParent(Root.Canvas, false); RectTransform val = (RectTransform)_root.transform; val.anchorMin = Vector2.zero; val.anchorMax = Vector2.zero; val.pivot = new Vector2(0f, 1f); val.sizeDelta = new Vector2(520f, 40f); _text = Widgets.Label(_root.transform, "words", "", 20, (TextAnchor)0); _text.horizontalOverflow = (HorizontalWrapMode)0; _text.verticalOverflow = (VerticalWrapMode)1; _text.supportRichText = true; RectTransform rectTransform = ((Graphic)_text).rectTransform; rectTransform.anchorMin = Vector2.zero; rectTransform.anchorMax = Vector2.one; rectTransform.offsetMin = Vector2.zero; rectTransform.offsetMax = Vector2.zero; Outline obj = ((Component)_text).gameObject.AddComponent<Outline>(); ((Shadow)obj).effectColor = new Color(0f, 0f, 0f, 0.85f); ((Shadow)obj).effectDistance = new Vector2(1.5f, -1.5f); _shown = null; return true; } private static bool Place() { //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Expected O, but got Unknown //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_bar == (Object)null) { _bar = ((Component)Hud.instance).GetComponentInChildren<HotkeyBar>(true); } if ((Object)(object)_bar == (Object)null) { if (!_toldNoBar) { Plugin.Log.LogWarning((object)"Corner: no hotkey bar in the game's interface — its words are not shown."); } _toldNoBar = true; return false; } float left = float.MaxValue; float bottom = float.MaxValue; Transform transform = ((Component)_bar).transform; Reach((RectTransform)(object)((transform is RectTransform) ? transform : null), ref left, ref bottom); foreach (Transform item in ((Component)_bar).transform) { object obj = (object)item; Reach((RectTransform)((obj is RectTransform) ? obj : null), ref left, ref bottom); } if (left == float.MaxValue) { return false; } float y = _root.transform.lossyScale.y; float num = bottom - 10f * y; float num2 = float.MaxValue; TMP_Text val = (((Object)(object)MessageHud.instance != (Object)null) ? MessageHud.instance.m_messageText : null); if ((Object)(object)val != (Object)null) { val.rectTransform.GetWorldCorners(Corners); Vector3[] corners = Corners; foreach (Vector3 val2 in corners) { num2 = Mathf.Min(num2, val2.y); } if (num2 < num && num2 > bottom - 170f * y) { num = num2 - 4f * y; } } _root.transform.position = new Vector3(left, num, 0f); bool flag = left >= 0f && left < (float)Screen.width && num > 0f && num <= (float)Screen.height; if (!_told) { _told = true; Plugin.Log.LogInfo((object)("Corner: words under the hotkey bar at (" + Px(left) + ", " + Px(num) + ") of a screen " + Screen.width + "x" + Screen.height + " — the bar's left edge " + Px(left) + " and its bottom " + Px(bottom) + " with " + ((Component)_bar).transform.childCount + " slots, the game's own words there down to " + ((num2 == float.MaxValue) ? "nothing found" : Px(num2)) + ", our canvas scaled " + y.ToString("0.###", CultureInfo.InvariantCulture) + (flag ? "." : " — off the screen, not shown."))); } return flag; } private static void Reach(RectTransform rect, ref float left, ref float bottom) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)rect == (Object)null)) { rect.GetWorldCorners(Corners); Vector3[] corners = Corners; foreach (Vector3 val in corners) { left = Mathf.Min(left, val.x); bottom = Mathf.Min(bottom, val.y); } } } private static string Px(float value) { return value.ToString("0", CultureInfo.InvariantCulture); } } internal static class CraftTabs { private sealed class Built { internal Button Button; internal MenuPage Page; } internal sealed class Driver : MonoBehaviour { private void Update() { Tick(); } } private static readonly List<Built> Tabs = new List<Built>(); private static InventoryGui _gui; private static int _open = -1; private static GameObject _gameList; private static GameObject _gameDetails; private static bool _gameHidden; internal static void Build(InventoryGui gui) { //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Expected O, but got Unknown _gui = gui; Tabs.Clear(); _gameHidden = false; if (MenuTabs.All.Count == 0) { return; } RectTransform crafting = gui.m_crafting; Transform val = (((Object)(object)crafting != (Object)null) ? PaneHolding((Transform)(object)crafting, (Transform)(object)gui.m_recipeListRoot) : null); Transform val2 = (((Object)(object)crafting != (Object)null) ? ((Transform)crafting).Find("Decription") : null); if ((Object)(object)gui.m_tabUpgrade == (Object)null || (Object)(object)gui.m_tabCraft == (Object)null || (Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null || (Object)(object)gui.m_recipeElementPrefab == (Object)null) { Plugin.Log.LogWarning((object)"The crafting window is not built the way it was on 24.09.2026 (tabs / RecipeList / Decription / recipe row) — our tabs are not added."); return; } _gameList = ((Component)val).gameObject; _gameDetails = ((Component)val2).gameObject; StringBuilder stringBuilder = new StringBuilder(); Transform transform = ((Component)gui.m_tabUpgrade).transform; for (int i = 0; i < MenuTabs.All.Count; i++) { MenuTabs.Tab tab = MenuTabs.All[i]; int index = i; MenuPage page = MenuPage.Build(gui, tab, val, val2); Button val3 = GameLook.Copy(gui.m_tabUpgrade, transform.parent, tab.Caption, (UnityAction)delegate { Select(index); }); ((Component)val3).transform.SetSiblingIndex(transform.GetSiblingIndex() + 1); transform = ((Component)val3).transform; Tabs.Add(new Built { Button = val3, Page = page }); stringBuilder.Append((i == 0) ? "" : ", ").Append('«').Append(tab.Caption) .Append('»'); } if (_open >= Tabs.Count) { _open = -1; } Paint(); Plugin.Log.LogInfo((object)("Tabs added to the crafting window: " + stringBuilder?.ToString() + ".")); } internal static void CraftingUpdated() { if (Tabs.Count != 0) { Place(); Paint(); } } internal static void GameTabChosen() { if (_open >= 0) { _open = -1; Paint(); } } internal static void Refresh() { if (_open >= 0 && _open < Tabs.Count) { Tabs[_open].Page.Refresh(); } } private static void Tick() { if (_open >= 0 && _open < Tabs.Count && InventoryGui.IsVisible()) { Tabs[_open].Page.Tick(); } } private static void Select(int index) { if (_open != index) { _open = index; Paint(); } } private static void Paint() { if (Tabs.Count == 0) { return; } for (int i = 0; i < Tabs.Count; i++) { ((Selectable)Tabs[i].Button).interactable = i != _open; if (i != _open) { Tabs[i].Page.Show(shown: false); } } HideGame(_open >= 0); if (_open >= 0) { Tabs[_open].Page.Show(shown: true); ((Selectable)_gui.m_tabCraft).interactable = true; ((Selectable)_gui.m_tabUpgrade).interactable = true; } } private static void HideGame(bool hide) { if (hide != _gameHidden && !((Object)(object)_gameList == (Object)null)) { _gameHidden = hide; _gameList.SetActive(!hide); _gameDetails.SetActive(!hide); } } private static void Place() { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Expected O, but got Unknown //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Expected O, but got Unknown //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_015e: 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_0178: Unknown result type (might be due to invalid IL or missing references) RectTransform val = (RectTransform)((Component)_gui.m_tabCraft).transform; RectTransform val2 = (RectTransform)((Component)_gui.m_tabUpgrade).transform; Transform val3 = (Transform)(object)val2; foreach (Built tab in Tabs) { ((Component)tab.Button).transform.SetSiblingIndex(val3.GetSiblingIndex() + 1); val3 = ((Component)tab.Button).transform; } if ((Object)(object)((Component)((Transform)val2).parent).GetComponent<HorizontalOrVerticalLayoutGroup>() != (Object)null || (!((Component)val2).gameObject.activeSelf && !((Component)val).gameObject.activeSelf)) { return; } float num = Left(val2) - Right(val); if (num <= 0f) { num = 4f; } RectTransform val4 = (((Component)val2).gameObject.activeSelf ? val2 : val); foreach (Built tab2 in Tabs) { RectTransform val5 = (RectTransform)((Component)tab2.Button).transform; TMP_Text componentInChildren = ((Component)tab2.Button).GetComponentInChildren<TMP_Text>(true); Rect rect = val2.rect; float num2 = ((Rect)(ref rect)).width; if ((Object)(object)componentInChildren != (Object)null) { num2 = Mathf.Max(num2, componentInChildren.preferredWidth + 24f); } val5.SetSizeWithCurrentAnchors((Axis)0, num2); float num3 = Right(val4) + num; val5.anchoredPosition = new Vector2(num3 + val5.pivot.x * num2, val4.anchoredPosition.y); val4 = val5; } } private static float Left(RectTransform r) { //IL_0001: 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_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) float x = r.anchoredPosition.x; float x2 = r.pivot.x; Rect rect = r.rect; return x - x2 * ((Rect)(ref rect)).width; } private static float Right(RectTransform r) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) float x = r.anchoredPosition.x; float num = 1f - r.pivot.x; Rect rect = r.rect; return x + num * ((Rect)(ref rect)).width; } private static Transform PaneHolding(Transform window, Transform inside) { Transform val = inside; while ((Object)(object)val != (Object)null) { if ((Object)(object)val.parent == (Object)(object)window) { return val; } val = val.parent; } return null; } } internal static class Fields { internal sealed class Look { internal TMP_FontAsset Font; internal Material Material; internal float Size = 20f; internal Color Ink = Theme.Ink; internal Sprite Backing; } private static readonly List<TMP_InputField> Live = new List<TMP_InputField>(); private static int _askedFrame = -1; private static bool _typing; private static bool _told; private const float TextScale = 0.8f; internal static bool Typing { get { if (_askedFrame == Time.frameCount) { return _typing; } _askedFrame = Time.frameCount; _typing = false; for (int num = Live.Count - 1; num >= 0; num--) { TMP_InputField val = Live[num]; if ((Object)(object)val == (Object)null) { Live.RemoveAt(num); } else if (val.isFocused) { _typing = true; } } return _typing; } } internal static Look LookOf(InventoryGui gui, Transform details) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) Look look = new Look(); TMP_Text componentInChildren = ((Component)gui.m_craftButton).GetComponentInChildren<TMP_Text>(true); if ((Object)(object)componentInChildren != (Object)null) { look.Font = componentInChildren.font; look.Material = componentInChildren.fontSharedMaterial; look.Size = componentInChildren.fontSize; look.Ink = ((Graphic)componentInChildren).color; } look.Backing = BackingOf(details); if (!_told) { _told = true; Plugin.Log.LogInfo((object)("Fields wear " + (((Object)(object)look.Font != (Object)null) ? ((Object)look.Font).name : "TextMeshPro's default font") + " at " + look.Size + " on " + (((Object)(object)look.Backing != (Object)null) ? ((Object)look.Backing).name : "a plain dark box") + ".")); } return look; } private static Sprite BackingOf(Transform details) { if ((Object)(object)details == (Object)null) { return null; } Image[] componentsInChildren = ((Component)details).GetComponentsInChildren<Image>(true); foreach (Image val in componentsInChildren) { if ((Object)(object)val.sprite != (Object)null && ((Object)val.sprite).name.Contains("background")) { return val.sprite; } } Image component = ((Component)details).GetComponent<Image>(); if (!((Object)(object)component != (Object)null)) { return null; } return component.sprite; } internal static TMP_InputField Make(Transform parent, MenuTabs.Entry entry, Look look) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0093: 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_0120: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_01f6: Expected O, but got Unknown GameObject obj = TMP_DefaultControls.CreateInputField(new Resources { inputField = look.Backing }); ((Object)obj).name = "Astvard " + (entry.Caption ?? entry.Hint) + " field"; obj.transform.SetParent(parent, false); ((Graphic)obj.GetComponent<Image>()).color = (Color)(((Object)(object)look.Backing != (Object)null) ? Color.white : new Color(0f, 0f, 0f, 0.5f)); TMP_InputField component = obj.GetComponent<TMP_InputField>(); if ((Object)(object)look.Font != (Object)null) { component.fontAsset = look.Font; } component.pointSize = look.Size * 0.8f; TMP_Text[] componentsInChildren = obj.GetComponentsInChildren<TMP_Text>(true); foreach (TMP_Text val in componentsInChildren) { if ((Object)(object)look.Material != (Object)null) { val.fontSharedMaterial = look.Material; } val.alignment = (TextAlignmentOptions)513; } ((Graphic)component.textComponent).color = look.Ink; Graphic placeholder = component.placeholder; TMP_Text val2 = (TMP_Text)(object)((placeholder is TMP_Text) ? placeholder : null); if (val2 != null) { val2.text = entry.Hint; val2.fontStyle = (FontStyles)0; ((Graphic)val2).color = new Color(look.Ink.r, look.Ink.g, look.Ink.b, 0.45f); } component.customCaretColor = true; component.caretColor = look.Ink; component.selectionColor = new Color(look.Ink.r, look.Ink.g, look.Ink.b, 0.3f); component.characterLimit = entry.Limit; if (entry.Accepts != null) { component.onValidateInput = (OnValidateInput)((string text, int index, char added) => (entry.Accepts.IndexOf(added) >= 0) ? added : '\0'); } component.SetTextWithoutNotify(entry.Text); ((UnityEvent<string>)(object)component.onValueChanged).AddListener((UnityAction<string>)delegate(string typed) { entry.Text = typed; }); Live.Add(component); ((UnityEvent<string>)(object)component.onSubmit).AddListener((UnityAction<string>)delegate(string typed) { if (!entry.IsBare) { Widgets.Announce(entry.Caption); entry.Apply(typed); } }); return component; } } internal static class GameLook { private static readonly HashSet<string> ToldOf = new HashSet<string>(); internal static Button Copy(Button source, Transform parent, string caption, UnityAction onClick) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Expected O, but got Unknown //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Expected O, but got Unknown Button obj = Object.Instantiate<Button>(source, parent); ((Object)obj).name = "Astvard " + caption; LeaveUnselected((Selectable)(object)obj, ((Object)source).name); obj.onClick = new ButtonClickedEvent(); ((UnityEvent)obj.onClick).AddListener((UnityAction)delegate { Widgets.Announce(caption); }); ((UnityEvent)obj.onClick).AddListener(onClick); ((Selectable)obj).interactable = true; ((Component)obj).gameObject.SetActive(true); Caption(obj, caption); return obj; } internal static void LeaveUnselected(Selectable selectable, string from) { //IL_004a: 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) if (ToldOf.Add(from)) { Plugin.Log.LogInfo((object)("Buttons: «" + from + "» came with " + Describe(selectable) + ".")); } Navigation navigation = default(Navigation); ((Navigation)(ref navigation)).mode = (Mode)0; selectable.navigation = navigation; } private static string Describe(Selectable selectable) { //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_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_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_0098: 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_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) ColorBlock colors = selectable.colors; Graphic targetGraphic = selectable.targetGraphic; string[] obj = new string[17] { "navigation ", null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null }; Navigation navigation = selectable.navigation; obj[1] = ((object)((Navigation)(ref navigation)).mode/*cast due to .constrained prefix*/).ToString(); obj[2] = ", transition "; obj[3] = ((object)selectable.transition/*cast due to .constrained prefix*/).ToString(); obj[4] = ", tinting "; obj[5] = (((Object)(object)targetGraphic != (Object)null) ? ("«" + ((Object)targetGraphic).name + "»") : "nothing"); obj[6] = ", normal "; obj[7] = Hex(((ColorBlock)(ref colors)).normalColor); obj[8] = ", highlighted "; obj[9] = Hex(((ColorBlock)(ref colors)).highlightedColor); obj[10] = ", pressed "; obj[11] = Hex(((ColorBlock)(ref colors)).pressedColor); obj[12] = ", selected "; obj[13] = Hex(((ColorBlock)(ref colors)).selectedColor); obj[14] = ", fade "; obj[15] = ((ColorBlock)(ref colors)).fadeDuration.ToString("0.##", CultureInfo.InvariantCulture); obj[16] = " s"; return string.Concat(obj); } private static string Hex(Color color) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) return "#" + ColorUtility.ToHtmlStringRGBA(color); } internal static TMP_Text Caption(Button button, string caption) { TMP_Text componentInChildren = ((Component)button).GetComponentInChildren<TMP_Text>(true); if ((Object)(object)componentInChildren == (Object)null) { Plugin.Log.LogWarning((object)("The copied button \"" + caption + "\" has no TextMeshPro caption.")); return null; } componentInChildren.text = caption; return componentInChildren; } } internal sealed class MenuPage { private sealed class ScrollPassOn : MonoBehaviour, IScrollHandler, IEventSystemHandler { internal ScrollRect List; public void OnScroll(PointerEventData data) { if ((Object)(object)List != (Object)null) { List.OnScroll(data); } } } private sealed class Heading { internal GameObject Root; internal TMP_Text Name; internal TMP_Text Count; } [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static UnityAction <>9__66_0; internal void <NewTile>b__66_0() { } } private static readonly string[] KeptInDetails = new string[2] { "Icon", "Name" }; private const float ButtonHeight = 44f; private const float ButtonGap = 8f; private const float WordsScale = 0.8f; private const float TitleScale = 0.7f; private const float SettingScale = 0.65f; private const float LabelScale = 0.6f; private const float HeadingHeight = 28f; private const float HeadingPad = 5f; private const float CountWidth = 44f; private const float TileHeight = 36f; private const float TileGap = 6f; private const float EdgeWidth = 4f; private const float FieldHeight = 38f; private const float FramePad = 6f; private const float FrameGap = 4f; private const float ScrollGap = 4f; private const string Back = "Назад"; private const float LiveEvery = 0.25f; private static readonly Color HeadingInk = new Color(1f, 0.78f, 0.35f); private static readonly Color StripInk = new Color(0.23f, 0.17f, 0.12f, 0.85f); private static readonly Color CountInk = new Color(0.7f, 0.6f, 0.47f); private readonly MenuTabs.Tab _tab; private readonly List<GameObject> _rows = new List<GameObject>(); private readonly List<GameObject> _groups = new List<GameObject>(); private readonly List<List<KeyValuePair<TMP_Text, Func<string>>>> _words = new List<List<KeyValuePair<TMP_Text, Func<string>>>>(); private readonly Dictionary<TMP_Text, GameObject> _blockOf = new Dictionary<TMP_Text, GameObject>(); private readonly List<List<KeyValuePair<TMP_InputField, MenuTabs.Entry>>> _filled = new List<List<KeyValuePair<TMP_InputField, MenuTabs.Entry>>>(); private readonly List<List<KeyValuePair<TMP_InputField, MenuTabs.Entry>>> _shared = new List<List<KeyValuePair<TMP_InputField, MenuTabs.Entry>>>(); private readonly List<string> _filledFor = new List<string>(); private readonly List<Button> _listTiles = new List<Button>(); private readonly List<Heading> _listHeadings = new List<Heading>(); private readonly List<Heading> _listNotes = new List<Heading>(); private readonly List<GridLayoutGroup> _listBlocks = new List<GridLayoutGroup>(); private InventoryGui _gui; private GameObject _sectionsPane; private RectTransform _rowsRoot; private float _baseHeight; private GameObject _details; private Image _icon; private TMP_Text _name; private GameObject _listView; private ScrollRect _listScroll; private RectTransform _listContent; private TMP_Text _listEmpty; private Fields.Look _look; private float _listWidth; private ScrollRect _gameScroll; private float _wideWidth; private float _narrowWidth; private int _listFor = -1; private float _liveAt; private static bool _toldTakers; private static readonly HashSet<string> MeasuredTabs = new HashSet<string>(); private static bool _toldRow; private MenuPage(MenuTabs.Tab tab) { _tab = tab; } internal static MenuPage Build(InventoryGui gui, MenuTabs.Tab tab, Transform listSource, Transform detailsSource) { //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected O, but got Unknown //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Expected O, but got Unknown //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Expected O, but got Unknown //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Expected O, but got Unknown //IL_0217: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Unknown result type (might be due to invalid IL or missing references) //IL_0235: Unknown result type (might be due to invalid IL or missing references) //IL_023a: Unknown result type (might be due to invalid IL or missing references) //IL_02d8: Unknown result type (might be due to invalid IL or missing references) //IL_0340: Unknown result type (might be due to invalid IL or missing references) //IL_0345: Unknown result type (might be due to invalid IL or missing references) MenuPage menuPage = new MenuPage(tab) { _gui = gui }; RectTransform crafting = gui.m_crafting; menuPage._sectionsPane = Object.Instantiate<GameObject>(((Component)listSource).gameObject, (Transform)(object)crafting); ((Object)menuPage._sectionsPane).name = "Astvard " + tab.Caption + " sections"; RectTransform val = (RectTransform)menuPage._sectionsPane.transform.Find(PathBetween(listSource, (Transform)(object)gui.m_recipeListRoot)); List<GameObject> list = new List<GameObject>(); foreach (Transform item in (Transform)val) { Transform val2 = item; list.Add(((Component)val2).gameObject); } foreach (GameObject item2 in list) { Object.Destroy((Object)(object)item2); } menuPage._rowsRoot = val; menuPage._details = Object.Instantiate<GameObject>(((Component)detailsSource).gameObject, (Transform)(object)crafting); ((Object)menuPage._details).name = "Astvard " + tab.Caption + " section"; foreach (Transform item3 in menuPage._details.transform) { Transform val3 = item3; ((Component)val3).gameObject.SetActive(Array.IndexOf(KeptInDetails, ((Object)val3).name) >= 0); } Transform obj = menuPage._details.transform.Find("Icon"); menuPage._icon = ((obj != null) ? ((Component)obj).GetComponent<Image>() : null); Transform obj2 = menuPage._details.transform.Find("Name"); menuPage._name = ((obj2 != null) ? ((Component)obj2).GetComponent<TMP_Text>() : null); RectTransform val4 = ActionsArea((RectTransform)menuPage._details.transform); Fields.Look look = Fields.LookOf(gui, detailsSource); menuPage._look = look; menuPage._gameScroll = menuPage._sectionsPane.GetComponentInChildren<ScrollRect>(true); menuPage._wideWidth = ButtonWidth(gui); Rect rect = val4.rect; if (((Rect)(ref rect)).width >= 1f) { float wideWidth = menuPage._wideWidth; rect = val4.rect; menuPage._wideWidth = Mathf.Min(wideWidth, ((Rect)(ref rect)).width); } menuPage._narrowWidth = menuPage._wideWidth - menuPage.BarRoom(); bool flag = false; for (int i = 0; i < tab.Sections.Count; i++) { MenuTabs.Section section = tab.Sections[i]; bool flag2 = section.Rows != null; flag = flag || flag2; menuPage._rows.Add(menuPage.Row(gui, val, section, i)); List<KeyValuePair<TMP_Text, Func<string>>> list2 = new List<KeyValuePair<TMP_Text, Func<string>>>(); List<KeyValuePair<TMP_InputField, MenuTabs.Entry>> list3 = new List<KeyValuePair<TMP_InputField, MenuTabs.Entry>>(); List<KeyValuePair<TMP_InputField, MenuTabs.Entry>> list4 = new List<KeyValuePair<TMP_InputField, MenuTabs.Entry>>(); menuPage._groups.Add(menuPage.Group(val4, section, list2, list3, list4, flag2 ? new UnityAction(menuPage.CloseRow) : ((UnityAction)null))); menuPage._words.Add(list2); menuPage._filled.Add(list3); menuPage._shared.Add(list4); menuPage._filledFor.Add(null); } if (flag) { menuPage.ListView(val4); } rect = val.rect; menuPage._baseHeight = ((Rect)(ref rect)).height; menuPage.Size(tab.Sections.Count); menuPage.TellListOnce(); menuPage.Show(shown: false); return menuPage; } internal void Show(bool shown) { _sectionsPane.SetActive(shown); _details.SetActive(shown); if (shown) { _sectionsPane.transform.SetAsLastSibling(); _details.transform.SetAsLastSibling(); Choose(_tab.Chosen); } } internal void Refresh() { if (_details.activeSelf) { Choose(_tab.Chosen); } } internal void Tick() { if (_details.activeSelf && !(Time.unscaledTime < _liveAt)) { int chosen = _tab.Chosen; if (chosen >= 0 && chosen < _tab.Sections.Count && _tab.Sections[chosen].IsLive) { _liveAt = Time.unscaledTime + 0.25f; Say(chosen); } } } private void Choose(int index) { List<MenuTabs.Section> sections = _tab.Sections; if (sections.Count == 0) { return; } index = Mathf.Clamp(index, 0, sections.Count - 1); _tab.Chosen = index; MenuTabs.Section section = sections[index]; IReadOnlyList<MenuTabs.Row> readOnlyList = null; MenuTabs.Row row = null; if (section.Rows != null) { readOnlyList = RowsOf(section); row = RowFor(readOnlyList, section.ChosenKey); section.ChosenKey = row?.Key; } else { _listFor = -1; } string text = row?.Key; if (text != _filledFor[index]) { _filledFor[index] = text; if (text != null) { FillFields(index); } } else if (section.RefillAsked && text != null) { FillFields(index); } section.RefillAsked = false; ShowShared(index); bool flag = readOnlyList != null && row == null; for (int i = 0; i < _rows.Count; i++) { Transform obj = _rows[i].transform.Find("selected"); if (obj != null) { ((Component)obj).gameObject.SetActive(i == index); } _groups[i].SetActive(i == index && !flag); Transform obj2 = _rows[i].transform.Find("icon"); Paint((obj2 != null) ? ((Component)obj2).GetComponent<Image>() : null, sections[i]); } if ((Object)(object)_listView != (Object)null) { _listView.SetActive(flag); } if (flag) { FillList(index, readOnlyList); } if ((Object)(object)_name != (Object)null) { _name.text = ((row != null) ? row.Title : section.Title); } Paint(_icon, section); Say(index); } private void OpenSection(int index) { MenuTabs.Section section = _tab.Sections[index]; if (section.Rows != null) { section.ChosenKey = null; } if (section.Opened != null) { try { section.Opened(); } catch (Exception ex) { Plugin.Log.LogError((object)("«" + section.Title + "» stumbled as it opened: " + ex)); } } Choose(index); } private void OpenRow(string key) { _tab.Sections[_tab.Chosen].ChosenKey = key; Choose(_tab.Chosen); } private void CloseRow() { _tab.Sections[_tab.Chosen].ChosenKey = null; Choose(_tab.Chosen); } private static IReadOnlyList<MenuTabs.Row> RowsOf(MenuTabs.Section section) { try { return section.Rows() ?? new List<MenuTabs.Row>(); } catch (Exception ex) { Plugin.Log.LogError((object)("The list «" + section.Title + "» could not be made: " + ex)); return new List<MenuTabs.Row>(); } } private static MenuTabs.Row RowFor(IReadOnlyList<MenuTabs.Row> rows, string key) { if (key == null) { return null; } foreach (MenuTabs.Row row in rows) { if (!row.IsHeading && row.Key == key) { return row; } } return null; } private void FillList(int index, IReadOnlyList<MenuTabs.Row> rows) { //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_0398: Unknown result type (might be due to invalid IL or missing references) bool flag = _listFor != index; _listFor = index; int num = 0; ((Component)_listEmpty).gameObject.SetActive(rows.Count == 0); if (rows.Count == 0) { _listEmpty.text = _tab.Sections[index].Empty?.Invoke() ?? "Пусто"; _listEmpty.transform.SetSiblingIndex(num++); } int num2 = 0; int num3 = 0; int num4 = 0; int num5 = 0; int num6 = 0; GridLayoutGroup val = null; foreach (MenuTabs.Row row in rows) { if (row.IsNote) { while (_listNotes.Count <= num4) { _listNotes.Add(NewNote()); } Heading heading = _listNotes[num4++]; heading.Root.SetActive(true); heading.Name.text = row.Title; heading.Count.text = row.Words; heading.Root.transform.SetSiblingIndex(num++); val = null; continue; } if (row.IsHeading) { while (_listHeadings.Count <= num3) { _listHeadings.Add(NewHeading()); } Heading heading2 = _listHeadings[num3++]; heading2.Root.SetActive(true); heading2.Name.text = row.Title; heading2.Count.text = row.Aside ?? ""; Widgets.Size(height: Mathf.Max(28f, Mathf.Ceil(heading2.Name.GetPreferredValues(row.Title, HeadingNameWidth(), 0f).y) + 10f), go: heading2.Root, width: _listWidth); heading2.Root.transform.SetSiblingIndex(num++); val = null; continue; } if ((Object)(object)val == (Object)null) { val = Pooled<GridLayoutGroup>(_listBlocks, num5++, (Func<GridLayoutGroup>)NewBlock); ((Component)val).transform.SetSiblingIndex(num++); num6 = 0; } Button val2 = Pooled<Button>(_listTiles, num2++, (Func<Button>)NewTile); Wire(val2, row); ((Component)val2).transform.SetParent(((Component)val).transform, false); ((Component)val2).transform.SetSiblingIndex(num6++); } for (int i = num3; i < _listHeadings.Count; i++) { _listHeadings[i].Root.SetActive(false); } for (int j = num4; j < _listNotes.Count; j++) { _listNotes[j].Root.SetActive(false); } for (int k = num5; k < _listBlocks.Count; k++) { ((Component)_listBlocks[k]).gameObject.SetActive(false); } for (int l = num2; l < _listTiles.Count; l++) { ((Component)_listTiles[l]).gameObject.SetActive(false); } if (flag) { _listScroll.StopMovement(); _listContent.anchoredPosition = Vector2.zero; } } private static T Pooled<T>(List<T> pool, int at, Func<T> make) where T : Component { while (pool.Count <= at) { pool.Add(make()); } T val = pool[at]; ((Component)val).gameObject.SetActive(true); return val; } private void Wire(Button button, MenuTabs.Row row) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Expected O, but got Unknown //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Expected O, but got Unknown string title = row.Title; string key = row.Key; button.onClick = new ButtonClickedEvent(); ((UnityEvent)button.onClick).AddListener((UnityAction)delegate { Widgets.Announce(title); }); if (row.Act != null) { ((UnityEvent)button.onClick).AddListener(row.Act); } else { ((UnityEvent)button.onClick).AddListener((UnityAction)delegate { OpenRow(key); }); } GameLook.Caption(button, title); } private Button NewTile() { //IL_002a: 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_0035: Expected O, but got Unknown Button craftButton = _gui.m_craftButton; RectTransform listContent = _listContent; object obj = <>c.<>9__66_0; if (obj == null) { UnityAction val = delegate { }; <>c.<>9__66_0 = val; obj = (object)val; } Button obj2 = GameLook.Copy(craftButton, (Transform)(object)listContent, "", (UnityAction)obj); ((Object)obj2).name = "Astvard list tile " + _listTiles.Count; TMP_Text componentInChildren = ((Component)obj2).GetComponentInChildren<TMP_Text>(true); if ((Object)(object)componentInChildren != (Object)null) { componentInChildren.enableAutoSizing = true; componentInChildren.fontSizeMin = 12f; componentInChildren.fontSizeMax = _look.Size * 0.65f; componentInChildren.textWrappingMode = (TextWrappingModes)1; componentInChildren.overflowMode = (TextOverflowModes)1; } PassScrollOn(((Component)obj2).gameObject, _listScroll); return obj2; } private GridLayoutGroup NewBlock() { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: 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_007e: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Astvard list block " + _listBlocks.Count, new Type[1] { typeof(RectTransform) }); val.transform.SetParent((Transform)(object)_listContent, false); GridLayoutGroup obj = val.AddComponent<GridLayoutGroup>(); obj.cellSize = new Vector2(Mathf.Floor((_listWidth - 6f) / 2f), 36f); obj.spacing = new Vector2(6f, 6f); obj.constraint = (Constraint)1; obj.constraintCount = 2; obj.startCorner = (Corner)0; obj.startAxis = (Axis)0; ((LayoutGroup)obj).childAlignment = (TextAnchor)0; return obj; } private static void PassScrollOn(GameObject copy, ScrollRect column) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) IScrollHandler[] componentsInChildren = copy.GetComponentsInChildren<IScrollHandler>(true); copy.AddComponent<ScrollPassOn>().List = column; IScrollHandler[] array = componentsInChildren; for (int i = 0; i < array.Length; i++) { GameObject gameObject = ((Component)array[i]).gameObject; if ((Object)(object)gameObject.GetComponent<ScrollPassOn>() == (Object)null) { gameObject.AddComponent<ScrollPassOn>().List = column; } } if (!_toldTakers) { _toldTakers = true; List<string> list = new List<string>(); array = componentsInChildren; foreach (IScrollHandler val in array) { list.Add(((object)val).GetType().Name + " on " + ((Object)(Component)val).name); } Plugin.Log.LogInfo((object)((list.Count == 0) ? "List buttons: nothing in the copied craft button takes the wheel." : ("List buttons: the wheel was taken by " + string.Join(", ", list) + " — handed on to the list."))); } } private Heading NewNote() { //IL_0057: 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) Transform val = Frame((Transform)(object)_listContent, "Astvard list note " + _listNotes.Count); Widgets.Width(((Component)val).gameObject, _listWidth); TMP_Text name = NewText(val, "Astvard note name", _look, _look.Size * 0.7f, HeadingInk, (TextAlignmentOptions)513, (TextWrappingModes)0, (TextOverflowModes)1); TMP_Text count = NewText(val, "Astvard note words", _look, _look.Size * 0.65f, _look.Ink, (TextAlignmentOptions)257, (TextWrappingModes)1, (TextOverflowModes)0); return new Heading { Root = ((Component)val).gameObject, Name = name, Count = count }; } private Heading NewHeading() { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_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_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: 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_010e: 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_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_0158: 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_0163: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Astvard list heading " + _listHeadings.Count, new Type[1] { typeof(RectTransform) }); val.transform.SetParent((Transform)(object)_listContent, false); Image obj = val.AddComponent<Image>(); ((Graphic)obj).color = StripInk; ((Graphic)obj).raycastTarget = false; Widgets.Size(val, _listWidth, 28f); Edge(val.transform); TMP_Text val2 = NewText(val.transform, "Astvard count", _look, _look.Size * 0.6f, CountInk, (TextAlignmentOptions)516, (TextWrappingModes)0, (TextOverflowModes)1); RectTransform val3 = (RectTransform)val2.transform; val3.anchorMin = new Vector2(1f, 0f); val3.anchorMax = Vector2.one; val3.pivot = new Vector2(1f, 0.5f); val3.sizeDelta = new Vector2(44f, 0f); val3.anchoredPosition = new Vector2(-8f, 0f); TMP_Text val4 = NewText(val.transform, "Astvard name", _look, _look.Size * 0.65f, HeadingInk, (TextAlignmentOptions)513, (TextWrappingModes)1, (TextOverflowModes)1); RectTransform val5 = (RectTransform)val4.transform; val5.anchorMin = Vector2.zero; val5.anchorMax = Vector2.one; val5.offsetMin = new Vector2(12f, 0f); val5.offsetMax = new Vector2(-56f, 0f); return new Heading { Root = val, Name = val4, Count = val2 }; } private float HeadingNameWidth() { return _listWidth - 12f - 56f; } private void ListView(RectTransform actions) { _listScroll = ScrollColumn(actions, "list", stretch: false, out _listContent); _listView = ((Component)_listScroll).gameObject; _listWidth = _narrowWidth; _listEmpty = Words((Transform)(object)_listContent, _look, _listWidth); _listView.SetActive(false); } private ScrollRect ScrollColumn(RectTransform parent, string name, bool stretch, out RectTransform content) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Expected O, but got Unknown //IL_0047: 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_0079: 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_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Expected O, but got Unknown //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Expected O, but got Unknown //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Expected O, but got Unknown //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_0101: 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_0125: 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_0167: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Expected O, but got Unknown GameObject val = new GameObject("Astvard " + name, new Type[1] { typeof(RectTransform) }); val.transform.SetParent((Transform)(object)parent, false); Stretch((RectTransform)val.transform); ((Graphic)val.AddComponent<Image>()).color = Color.clear; GameObject val2 = new GameObject("Astvard " + name + " viewport", new Type[1] { typeof(RectTransform) }); val2.transform.SetParent(val.transform, false); RectTransform val3 = (RectTransform)val2.transform; Stretch(val3); val2.AddComponent<RectMask2D>(); GameObject val4 = new GameObject("Astvard " + name + " rows", new Type[1] { typeof(RectTransform) }); val4.transform.SetParent((Transform)(object)val3, false); content = (RectTransform)val4.transform; content.anchorMin = new Vector2(0f, 1f); content.anchorMax = Vector2.one; content.pivot = new Vector2(0.5f, 1f); content.offsetMin = Vector2.zero; content.offsetMax = Vector2.zero; VerticalLayoutGroup val5 = val4.AddComponent<VerticalLayoutGroup>(); ((HorizontalOrVerticalLayoutGroup)val5).spacing = 8f; ((LayoutGroup)val5).childAlignment = (TextAnchor)1; ((HorizontalOrVerticalLayoutGroup)val5).childForceExpandWidth = stretch; ((HorizontalOrVerticalLayoutGroup)val5).childForceExpandHeight = false; if (stretch) { Rect rect = parent.rect; if (((Rect)(ref rect)).width >= 1f) { rect = parent.rect; int num = Mathf.Max(0, Mathf.FloorToInt((((Rect)(ref rect)).width - _wideWidth) / 2f)); ((LayoutGroup)val5).padding = new RectOffset(num, num, 0, 0); } } val4.AddComponent<ContentSizeFitter>().verticalFit = (FitMode)2; Scrollbar val6 = ScrollbarCopy(val.transform); ScrollRect val7 = val.AddComponent<ScrollRect>(); val7.content = content; val7.viewport = val3; val7.horizontal = false; val7.vertical = true; if ((Object)(object)_gameScroll != (Object)null) { val7.movementType = _gameScroll.movementType; val7.elasticity = _gameScroll.elasticity; val7.inertia = _gameScroll.inertia; val7.decelerationRate = _gameScroll.decelerationRate; val7.scrollSensitivity = _gameScroll.scrollSensitivity; } else { val7.movementType = (MovementType)2; val7.scrollSensitivity = 44f; } if ((Object)(object)val6 != (Object)null) { val7.verticalScrollbar = val6; val7.verticalScrollbarVisibility = (ScrollbarVisibility)2; val7.verticalScrollbarSpacing = 4f; } return val7; } private float BarRoom() { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) Scrollbar recipeListScroll = _gui.m_recipeListScroll; if ((Object)(object)recipeListScroll == (Object)null) { return 0f; } Rect rect = ((RectTransform)((Component)recipeListScroll).transform).rect; float width = ((Rect)(ref rect)).width; return ((width < 1f) ? 10f : width) + 4f; } private Scrollbar ScrollbarCopy(Transform parent) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Expected O, but got Unknown //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_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006d: 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_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) Scrollbar recipeListScroll = _gui.m_recipeListScroll; if ((Object)(object)recipeListScroll == (Object)null) { return null; } float num = BarRoom() - 4f; Scrollbar obj = Object.Instantiate<Scrollbar>(recipeListScroll, parent); ((Object)obj).name = "Astvard scrollbar"; obj.onValueChanged = new ScrollEvent(); ((Component)obj).gameObject.SetActive(true); RectTransform val = (RectTransform)((Component)obj).transform; val.anchorMin = new Vector2(1f, 0f); val.anchorMax = Vector2.one; val.pivot = new Vector2(1f, 0.5f); val.anchoredPosition = Vector2.zero; val.sizeDelta = new Vector2(num, 0f); return obj; } private static void Stretch(RectTransform rect) { //IL_0001: 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_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) rect.anchorMin = Vector2.zero; rect.anchorMax = Vector2.one; rect.offsetMin = Vector2.zero; rect.offsetMax = Vector2.zero; } private static void Edge(Transform parent) { //IL_0018: 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_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003c: 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_0042: 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_0057: 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_006c: 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_0081: 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_009b: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Astvard edge", new Type[1] { typeof(RectTransform) }); val.transform.SetParent(parent, false); val.AddComponent<LayoutElement>().ignoreLayout = true; RectTransform val2 = (RectTransform)val.transform; val2.anchorMin = Vector2.zero; val2.anchorMax = new Vector2(0f, 1f); val2.pivot = new Vector2(0f, 0.5f); val2.sizeDelta = new Vector2(4f, 0f); val2.anchoredPosition = Vector2.zero; Image obj = val.AddComponent<Image>(); ((Graphic)obj).color = HeadingInk; ((Graphic)obj).raycastTarget = false; } private void Size(int count) { _rowsRoot.SetSizeWithCurrentAnchors((Axis)1, Mathf.Max(_baseHeight, (float)count * _gui.m_recipeListSpace)); } private void Say(int index) { foreach (KeyValuePair<TMP_Text, Func<string>> item in _words[index]) { string text; try { text = item.Value(); } catch (Exception ex) { Plugin.Log.LogError((object)("A line of «" + _tab.Sections[index].Title + "» could not be said: " + ex)); text = ""; } item.Key.text = text ?? ""; if (_blockOf.TryGetValue(item.Key, out var value)) { value.SetActive(item.Key.text.Length > 0); } } } private GameObject Row(InventoryGui gui, RectTransform rows, MenuTabs.Section section, int index) { //IL_0050: 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_00ab: 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_0144: Expected O, but got Unknown //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Expected O, but got Unknown //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Expected O, but got Unknown GameObject obj = Object.Instantiate<GameObject>(gui.m_recipeElementPrefab, (Transform)(object)rows); ((Object)obj).name = "Astvard " + section.Title; obj.SetActive(true); ((RectTransform)obj.transform).anchoredPosition = new Vector2(0f, (float)(-index) * gui.m_recipeListSpace); Transform obj2 = obj.transform.Find("name"); TMP_Text val = ((obj2 != null) ? ((Component)obj2).GetComponent<TMP_Text>() : null); if ((Object)(object)val != (Object)null) { val.text = section.Title; ((Graphic)val).color = Color.white; } Transform obj3 = obj.transform.Find("Durability"); if (obj3 != null) { ((Component)obj3).gameObject.SetActive(false); } Transform obj4 = obj.transform.Find("QualityLevel"); if (obj4 != null) { ((Component)obj4).gameObject.SetActive(false); } Transform obj5 = obj.transform.Find("selected"); if (obj5 != null) { ((Component)obj5).gameObject.SetActive(false); } TellRowOnce(obj); Button component = obj.GetComponent<Button>(); if ((Object)(object)component != (Object)null) { GameLook.LeaveUnselected((Selectable)(object)component, "recipe row"); component.onClick = new ButtonClickedEvent(); ((UnityEvent)component.onClick).AddListener((UnityAction)delegate { Widgets.Announce(section.Title); }); ((UnityEvent)component.onClick).AddListener((UnityAction)delegate { OpenSection(index); }); } return obj; } private void TellListOnce() { //IL_0054: 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_0082: 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_00bf: Unknown result type (might be due to invalid IL or missing references) if (_rows.Count != 0 && MeasuredTabs.Add(_tab.Caption)) { RectTransform val = (RectTransform)((!((Object)(object)_gameScroll != (Object)null)) ? null : (((Object)(object)_gameScroll.viewport != (Object)null) ? ((object)_gameScroll.viewport) : ((object)(RectTransform)((Component)_gameScroll).transform))); Rect rect = ((RectTransform)_rows[0].transform).rect; float height = ((Rect)(ref rect)).height; float num = (float)(_rows.Count - 1) * _gui.m_recipeListSpace + height; float num2; if (!((Object)(object)val != (Object)null)) { num2 = 0f; } else { rect = val.rect; num2 = ((Rect)(ref rect)).height; } float num3 = num2; Plugin.Log.LogInfo((object)("Rows of «" + _tab.Caption + "»: " + _rows.Count + " a step of " + _gui.m_recipeListSpace.ToString("0.#", CultureInfo.InvariantCulture) + " px, a row " + height.ToString("0.#", CultureInfo.InvariantCulture) + " px tall, reaching " + num.ToString("0.#", CultureInfo.InvariantCulture) + " px down a window " + num3.ToString("0.#", CultureInfo.InvariantCulture) + " px tall" + (((Object)(object)val == (Object)null) ? " (no window found)" : ((num <= num3) ? " — all in view." : " — the last one runs past the edge.")))); } } private static void TellRowOnce(GameObject row) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown if (_toldRow) { return; } _toldRow = true; List<string> list = new List<string>(); foreach (Transform item in row.transform) { Transform val = item; Graphic component = ((Component)val).GetComponent<Graphic>(); list.Add(((Object)val).name + (((Component)val).gameObject.activeSelf ? "" : " (off)") + (((Object)(object)component == (Object)null) ? "" : (component.raycastTarget ? " [catches]" : " [drawn]"))); } Graphic component2 = row.GetComponent<Graphic>(); Plugin.Log.LogInfo((object)("Rows: the recipe row is " + (((Object)(object)component2 == (Object)null) ? "no graphic" : (component2.raycastTarget ? "a graphic that catches" : "a graphic")) + ", its children drawn in order: " + string.Join(", ", list) + ".")); } private static float ButtonWidth(InventoryGui gui) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: 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) Rect rect = ((RectTransform)((Component)gui.m_craftButton).transform).rect; float width = ((Rect)(ref rect)).width; if (!(width < 1f)) { return width; } return 300f; } private GameObject Group(RectTransform actions, MenuTabs.Section section, List<KeyValuePair<TMP_Text, Func<string>>> words, List<KeyValuePair<TMP_InputField, MenuTabs.Entry>> filled, List<KeyValuePair<TMP_InputField, MenuTabs.Entry>> shared, UnityAction back) { RectTransform content; ScrollRect val = ScrollColumn(actions, section.Title + " actions", stretch: true, out content); if (back != null) { AddButton((Transform)(object)content, "Назад", back, val); } List<MenuTabs.Entry> list = new List<MenuTabs.Entry>(); List<MenuTabs.Entry> list2 = new List<MenuTabs.Entry>(); foreach (MenuTabs.Entry entry in section.Entries) { if (entry.Kind == MenuTabs.Entry.Kinds.Mark) { continue; } if (entry.Kind == MenuTabs.Entry.Kinds.Tile) { FieldBlock((Transform)(object)content, list, val, filled, shared); list2.Add(entry); continue; } if (entry.IsField && !entry.IsHeaded) { TileRows((Transform)(object)content, list2, val, words); list.Add(entry); continue; } FieldBlock((Transform)(object)content, list, val, filled, shared); TileRows((Transform)(object)content, list2, val, words); if (entry.Kind == MenuTabs.Entry.Kinds.Heading) { ColumnHeading((Transform)(object)content, entry.Caption); } else if (entry.Kind == MenuTabs.Entry.Kinds.Strip) { StripBlock((Transform)(object)content, entry, words); } else if (entry.IsHeaded) { if (entry.IsField) { ValueBlock((Transform)(object)content, entry, val, words); } else if (entry.OnClick == null) { WordsBlock((Transform)(object)content, entry, words); } else { SettingBlock((Transform)(object)content, entry, val, words); } } else if (entry.Says != null) { words.Add(new KeyValuePair<TMP_Text, Func<string>>(Words((Transform)(object)content, _look, 0f), entry.Says)); } else if (entry.CaptionOf != null) { TMP_Text componentInChildren = ((Component)AddButton((Transform)(object)content, entry.CaptionOf(), entry.OnClick, val)).GetComponentInChildren<TMP_Text>(true); if ((Object)(object)componentInChildren != (Object)null) { words.Add(new KeyValuePair<TMP_Text, Func<string>>(componentInChildren, entry.CaptionOf)); } } else { AddButton((Transform)(object)content, entry.Caption, entry.OnClick, val); } } FieldBlock((Transform)(object)content, list, val, filled, shared); TileRows((Transform)(object)content, list2, val, words); ((Component)val).gameObject.SetActive(false); return ((Component)val).gameObject; } private void ColumnHeading(Transform column, string title) { //IL_001e: 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_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Expected O, but got Unknown //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: 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_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Astvard heading " + title, new Type[1] { typeof(RectTransform) }); val.transform.SetParent(column, false); Image obj = val.AddComponent<Image>(); ((Graphic)obj).color = StripInk; ((Graphic)obj).raycastTarget = false; Widgets.Height(val, 28f); Edge(val.transform); TMP_Text obj2 = NewText(val.transform, "Astvard name", _look, _look.Size * 0.65f, HeadingInk, (TextAlignmentOptions)513, (TextWrappingModes)0, (TextOverflowModes)1); RectTransform val2 = (RectTransform)obj2.transform; val2.anchorMin = Vector2.zero; val2.anchorMax = Vector2.one; val2.offsetMin = new Vector2(12f, 0f); val2.offsetMax = new Vector2(-8f, 0f); obj2.text = title; } private void StripBlock(Transform column, MenuTabs.Entry entry, List<KeyValuePair<TMP_Text, Func<string>>> words) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) Transform val = Frame(column, "Astvard strip"); TMP_Text key = NewText(val, "Astvard strip words", _look, _look.Size * 0.65f, HeadingInk, (TextAlignmentOptions)257, (TextWrappingModes)1, (TextOverflowModes)0); words.Add(new KeyValuePair<TMP_Text, Func<string>>(key, entry.Says)); _blockOf[key] = ((Component)val).gameObject; } private void TileRows(Transform column, List<MenuTabs.Entry> tiles, ScrollRect scroll, List<KeyValuePair<TMP_Text, Func<string>>> words) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected O, but got Unknown for (int i = 0; i < tiles.Count; i += 2) { GameObject val = new GameObject("Astvard tiles", new Type[1] { typeof(RectTransform) }); val.transform.SetParent(column, false); HorizontalLayoutGroup obj = val.AddComponent<HorizontalLayoutGroup>(); ((HorizontalOrVerticalLayoutGroup)obj).spacing = 6f; ((LayoutGroup)obj).childAlignment = (TextAnchor)3; ((HorizontalOrVerticalLayoutGroup)obj).childForceExpandWidth = true; ((HorizontalOrVerticalLayoutGroup)obj).childForceExpandHeight = false; Widgets.Height(val, 36f); for (int j = i; j < i + 2; j++) { if (j < tiles.Count) { ColumnTile(val.transform, tiles[j], scroll, words); } else { Spacer(val.transform); } } } tiles.Clear(); } private void ColumnTile(Transform row, MenuTabs.Entry entry, ScrollRect scroll, List<KeyValuePair<TMP_Text, Func<string>>> words) { string caption = ((entry.CaptionOf != null) ? entry.CaptionOf() : entry.Caption); Button obj = GameLook.Copy(_gui.m_craftButton, row, caption, entry.OnClick); Widgets.Height(((Component)obj).gameObject, 36f); LayoutElement component = ((Component)obj).GetComponent<LayoutElement>(); component.preferredWidth = 0f; component.flexibleWidth = 1f; TMP_Text componentInChildren = ((Component)obj).GetComponentInChildren<TMP_Text>(true); if ((Object)(object)componentInChildren != (Object)null) { componentInChildren.enableAutoSizing = true; componentInChildren.fontSizeMin = 12f; componentInChildren.fontSizeMax = _look.Size * 0.65f; componentInChildren.textWrappingMode = (TextWrappingModes)1; componentInChildren.overflowMode = (TextOverflowModes)1; if (entry.CaptionOf != null) { words.Add(new KeyValuePair<TMP_Text, Func<string>>(componentInChildren, entry.CaptionOf)); } } PassScrollOn(((Component)obj).gameObject, scroll); } private static void Spacer(Transform row) { //IL_0018: 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) GameObject val = new GameObject("Astvard spacer", new Type[1] { typeof(RectTransform) }); val.transform.SetParent(row, false); LayoutElement obj = val.AddComponent<LayoutElement>(); obj.preferredWidth = 0f; obj.flexibleWidth = 1f; obj.preferredHeight = 36f; } private Button AddButton(Transform column, string caption, UnityAction onClick, ScrollRect scroll) { Button obj = GameLook.Copy(_gui.m_craftButton, column, caption, onClick); Widgets.Height(((Component)obj).gameObject, 44f); PassScrollOn(((Component)obj).gameObject, scroll); return obj; } private void FieldBlock(Transform column, List<MenuTabs.Entry> run, ScrollRect scroll, List<KeyValuePair<TMP_InputField, MenuTabs.Entry>> filled, List<KeyValuePair<TMP_InputField, MenuTabs.Entry>> shared) { //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Expected O, but got Unknown //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Expected O, but got Unknown if (run.Count == 0) { return; } Transform val = Frame(column, "Astvard fields"); List<MenuTabs.Entry> list = new List<MenuTabs.Entry>(); foreach (MenuTabs.Entry item in run) { if (item.Label != null) { Label(val, item.Label); } TMP_InputField val2 = Fields.Make(val, item, _look); Widgets.Height(((Component)val2).gameObject, 38f); if (item.Fill != null) { filled.Add(new KeyValuePair<TMP_InputField, MenuTabs.Entry>(val2, item)); } if (item.Same != null) { shared.Add(new KeyValuePair<TMP_InputField, MenuTabs.Entry>(val2, item)); } if (!item.IsBare) { list.Add(item); } } if (list.Count > 0) { GameObject val3 = new GameObject("Astvard field buttons", new Type[1] { typeof(RectTransform) }); val3.transform.SetParent(val, false); HorizontalLayoutGroup obj = val3.AddComponent<HorizontalLayoutGroup>(); ((HorizontalOrVerticalLayoutGroup)obj).spacing = 4f; ((LayoutGroup)obj).childAlignment = (TextAnchor)4; ((HorizontalOrVerticalLayoutGroup)obj).childForceExpandWidth = true; ((HorizontalOrVerticalLayoutGroup)obj).childForceExpandHeight = false; Widgets.Height(val3, 38f); foreach (MenuTabs.Entry entry in list) { Button obj2 = GameLook.Copy(_gui.m_craftButton, val3.transform, entry.Caption, (UnityAction)delegate { entry.Apply(entry.Text); }); Widgets.Height(((Component)obj2).gameObject, 38f); LayoutElement component = ((Component)obj2).GetComponent<LayoutElement>(); component.preferredWidth = 0f; component.flexibleWidth = 1f; Fit(obj2); PassScrollOn(((Component)obj2).gameObject, scroll); } } run.Clear(); } private static void Fit(Button button) { TMP_Text componentInChildren = ((Component)button).GetComponentInChildren<TMP_Text>(true); if (!((Object)(object)componentInChildren == (Object)null)) { float fontSize = componentInChildren.fontSize; componentInChildren.enableAutoSizing = true; componentInChildren.fontSizeMax = fontSize; componentInChildren.fontSizeMin = 12f; componentInChildren.textWrappingMode = (TextWrappingModes)0; componentInChildren.overflowMode = (TextOverflowModes)1; } } private void SettingBlock(Transform column, MenuTabs.Entry entry, ScrollRect scroll, List<KeyValuePair<TMP_Text, Func<string>>> words) { //IL_0029: 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) Transform parent = Frame(column, "Astvard setting"); NewText(parent, "Astvard setting name", _look, _look.Size * 0.7f, HeadingInk, (TextAlignmentOptions)513, (TextWrappingModes)0, (TextOverflowModes)1).text = entry.Heading; TMP_Text key = NewText(parent, "Astvard setting words", _look, _look.Size * 0.65f, _look.Ink, (TextAlignmentOptions)257, (TextWrappingModes)1, (TextOverflowModes)0); words.Add(new KeyValuePair<TMP_Text, Func<string>>(key, entry.Says)); Button obj = GameLook.Copy(_gui.m_craftButton, parent, entry.Heading, entry.OnClick); Widgets.Height(((Component)obj).gameObject, 38f); Fit(obj); PassScrollOn(((Component)obj).gameObject, scroll); TMP_Text val = GameLook.Caption(obj, entry.CaptionOf()); if ((Object)(object)val != (Object)null) { words.Add(new KeyValuePair<TMP_Text, Func<string>>(val, entry.CaptionOf)); } } private void WordsBlock(Transform column, MenuTabs.Entry entry, List<KeyValuePair<TMP_Text, Func<string>>> words) { //IL_0029: 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) Transform val = Frame(column, "Astvard words block"); NewText(val, "Astvard block name", _look, _look.Size * 0.7f, HeadingInk, (TextAlignmentOptions)513, (TextWrappingModes)0, (TextOverflowModes)1).text = entry.Heading; TMP_Text key = NewText(val, "Astvard block words", _look, _look.Size * 0.65f, _look.Ink, (TextAlignmentOptions)257, (TextWrappingModes)1, (TextOverflowModes)0); words.Add(new KeyValuePair<TMP_Text, Func<string>>(key, entry.Says)); _blockOf[key] = ((Component)val).gameObject; } private void ValueBlock(Transform column, MenuTabs.Entry entry, ScrollRect scroll, List<KeyValuePair<TMP_Text, Func<string>>> words) { //IL_0036: 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_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Expected O, but got Unknown Transform parent = Frame(column, "Astvard value"); NewText(parent, "Astvard value name", _look, _look.Size * 0.7f, HeadingInk, (TextAlignmentOptions)513, (TextWrappingModes)0, (TextOverflowModes)1).text = entry.Heading; TMP_Text key = NewText(parent, "Astvard value words", _look, _look.Size * 0.65f, _look.Ink, (TextAlignmentOptions)257, (TextWrappingModes)1, (TextOverflowModes)0); words.Add(new KeyValuePair<TMP_Text, Func<string>>(key, entry.Says)); Widgets.Height(((Component)Fields.Make(parent, entry, _look)).gameObject, 38f); Button obj = GameLook.Copy(_gui.m_craftButton, parent, entry.Heading, (UnityAction)delegate { entry.Apply(entry.Text); }); GameLook.Caption(obj, entry.Caption); Widgets.Height(((Component)obj).gameObject, 38f); Fit(obj); PassScrollOn(((Component)obj).gameObject, scroll); } private static Transform Frame(Transform column, string name) { //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_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Expected O, but got Unknown //IL_0072: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) }); val.transform.SetParent(column, false); Image obj = val.AddComponent<Image>(); ((Graphic)obj).color = StripInk; ((Graphic)obj).raycastTarget = false; VerticalLayoutGroup obj2 = val.AddComponent<VerticalLayoutGroup>(); ((LayoutGroup)obj2).padding = new RectOffset(10, 6, 6, 6); ((HorizontalOrVerticalLayoutGroup)obj2).spacing = 4f; ((LayoutGroup)obj2).childAlignment = (TextAnchor)0; ((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandWidth = true; ((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandHeight = false; Edge(val.transform); return val.transform; } private void Label(Transform block, string text) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) NewText(block, "Astvard label", _look, _look.Size * 0.6f, HeadingInk, (TextAlignmentOptions)1025, (TextWrappingModes)0, (TextOverflowModes)1).text = text; } private void FillFields(int index) { foreach (KeyValuePair<TMP_InputField, MenuTabs.Entry> item in _filled[index]) { string textWithoutNotify; try { textWithoutNotify = item.Value.Fill() ?? ""; } catch (Exception ex) { Plugin.Log.LogError((object)("A field of «" + _tab.Sections[index].Title + "» could not be filled: " + ex)); textWithoutNotify = ""; } item.Key.SetTextWithoutNotify(textWithoutNotify); item.Value.Text = item.Key.text; } } private void ShowShared(int index) { foreach (KeyValuePair<TMP_InputField, MenuTabs.Entry> item in _shared[index]) { if ((Object)(object)item.Key != (Object)null && !item.Key.isFocused && item.Key.text != item.Value.Text) { item.Key.SetTextWithoutNotify(item.Value.Text); } } } private static TMP_Text Words(Transform parent, Fields.Look look, float width) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) TMP_Text val = NewText(parent, "Astvard words", look, look.Size * 0.8f, look.Ink, (TextAlignmentOptions)257, (TextWrappingModes)1, (TextOverflowModes)0); if (width > 0f) { Widgets.Width(((Component)val).gameObject, width); } return val; } private static TMP_Text NewText(Transform parent, string name, Fields.Look look, float size, Color ink, TextAlignmentOptions alignment, TextWrappingModes wrapping, TextOverflowModes overflow = (TextOverflowModes)1) { //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_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0070: 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_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) }); val.SetActive(false); val.transform.SetParent(parent, false); TextMeshProUGUI val2 = val.AddComponent<TextMeshProUGUI>(); if ((Object)(object)look.Font != (Object)null) { ((TMP_Text)val2).font = look.Font; } if ((Object)(object)look.Material != (Object)null) { ((TMP_Text)val2).fontSharedMaterial = look.Material; } ((TMP_Text)val2).fontSize = size; ((Graphic)val2).color = ink; ((TMP_Text)val2).alignment = alignment; ((TMP_Text)val2).textWrappingMode = wrapping; ((TMP_Text)val2).overflowMode = overflow; ((Graphic)val2).raycastTarget = false; val.SetActive(true); return (TMP_Text)(object)val2; } private static RectTransform ActionsArea(RectTransform details) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: 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_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Expected O, but got Unknown //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Astvard actions", new Type[1] { typeof(RectTransform) }); val.transform.SetParent((Transform)(object)details, false); Rect rect = details.rect; float num = ((Rect)(ref rect)).yMax - 80f; Vector3[] array = (Vector3[])(object)new Vector3[4]; string[] keptInDetails = KeptInDetails; foreach (string text in keptInDetails) { Transform obj = ((Transform)details).Find(text); RectTransform val2 = (RectTransform)(object)((obj is RectTransform) ? obj : null); if (!((Object)(object)val2 == (Object)null)) { val2.GetWorldCorners(array); num = Mathf.Min(num, ((Transform)details).InverseTransformPoint(array[0]).y); } } RectTransform val3 = (RectTransform)val.transform; val3.anchorMin = Vector2.zero; val3.anchorMax = Vector2.one; val3.offsetMin = new Vector2(10f, 10f); float num2 = num - 12f; rect = details.rect; val3.offsetMax = new Vector2(-10f, num2 - ((Rect)(ref rect)).yMax); return val3; } private static void Paint(Image image, MenuTabs.Section section) { //IL_002e: 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) if (!((Object)(object)image == (Object)null)) { Sprite val = (image.sprite = IconOf(section.IconPrefab)); ((Graphic)image).color = (((Object)(object)val != (Object)null) ? Color.white : Color.clear); } } private static Sprite IconOf(string prefab) { if (string.IsNullOrEmpty(prefab)) { return null; } GameObject val = (((Object)(object)ObjectDB.instance != (Object)null) ? ObjectDB.instance.GetItemPrefab(prefab) : null); ItemDrop val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<ItemDrop>() : null); if ((Object)(object)val2 != (Object)null) { return val2.m_itemData.GetIcon(); } GameObject val3 = (((Object)(object)ZNetScene.instance != (Object)null) ? ZNetScene.instance.GetPrefab(prefab) : null); Piece val4 = (((Object)(object)val3 != (Object)null) ? val3.GetComponent<Piece>() : null); if ((Object)(object)val4 != (Object)null) { return val4.m_icon; } StatusEffect val5 = (((Object)(object)ObjectDB.instance != (Object)null) ? ObjectDB.instance.GetStatusEffect(StringExtensionMethods.GetStableHashCode(prefab)) : null); if (!((Object)(object)val5 != (Object)null)) { return null; } return val5.m_icon; } private static string PathBetween(Transform top, Transform bottom) { List<string> list = new List<string>(); Transform val = bottom; while ((Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)top) { list.Add(((Object)val).name); val = val.parent; } list.Reverse(); return string.Join("/", list); } } internal static class MenuTabs { internal sealed class Tab { internal readonly string Caption; internal readonly List<Section> Sections = new List<Section>(); internal int Chosen; internal Tab(string caption) { Caption = caption; } internal Section Add(string title, string iconPrefab) { Section section = new Section(title, iconPrefab); Sections.Add(section); return section; } } internal sealed class Section { internal readonly string Title; internal readonly string IconPrefab; internal readonly List<Entry> Entries = new List<Entry>(); internal Func<IReadOnlyList<Row>> Rows; internal Func<string> Empty; internal string ChosenKey; internal string Id; internal bool IsLive; internal Action Opened; internal bool RefillAsked; internal Section(string title, string iconPrefab) { Title = title; IconPrefab = iconPrefab; } internal Section Action(string caption, UnityAction onClick) { Entries.Add(new Entry(caption, onClick)); return this; } internal Section Field(string label, string hint, string caption, Action<string> apply, string accepts = null, int limit = 32, Func<string> fill = null) { Entries.Add(new Entry(label, hint, caption, apply, accepts, limit, fill)); return this; } internal Section Field(string label, string hint, string caption, Action<string> apply, string accepts, int limit, out Entry field) { field = new Entry(label, hint, caption, apply, accepts, limit, null); Entries.Add(field); return this; } internal Section Input(string label, string hint, string accepts, int limit, out Entry field) { field = new Entry(label, hint, null, null, accepts, limit, null); Entries.Add(field); return this; } internal Section Input(string label, string hint, string accepts, int limit, Func<string> fill, out Entry field) { field = new Entry(label, hint, null, null, accepts, limit, fill); Entries.Add(field); return this; } internal Section Input(string label, string hint, string accepts, int limit, Shared same) { Entries.Add(new Entry(label, hint, null, null, accepts, limit, null, same)); return this; } internal Section Setting(string title, Func<string> says, Func<string> caption, UnityAction onClick) { Entries.Add(new Entry(title, says, caption, onClick)); return this; } internal Section Value(string title, Func<string> says, string hint, string caption, Action<string> apply, string accepts, int limit) { Entries.Add(new Entry(title, says, hint, caption, apply, accepts, limit)); return this; } internal Section Toggle(Func<string> caption, UnityAction onClick) { Entries.Add(Entry.TileOf(caption, onClick)); return this; } internal Section Tile(string caption, UnityAction onClick) { Entries.Add(Entry.TileOf(caption, onClick)); return this; } internal Section Button(Func<string> caption, UnityAction onClick) { Entries.Add(new Entry(caption, onClick)); return this; } internal Section Heading(string title) { Entries.Add(Entry.HeadingOf(title)); return this; } internal Section Strip(Func<string> says) { Entries.Add(Entry.StripOf(says)); return this; } internal Section Mark(string name) { Entries.Add(Entry.MarkOf(name)); return this; } internal Section Insert(string mark, params Entry[] entries) { int index = Entries.Count; for (int i = 0; i < Entries.Count; i++) { if (Entries[i].Kind == Entry.Kinds.Mark && Entries[i].Caption == mark) { index = i; break; } } Entries.InsertRange(index, entries); return this; } internal Section Text(Func<string> says) { Entries.Add(new Entry(says)); return this; } internal Section Block(string title, Func<string> says) { Entries.Add(new Entry(title, says)); return this; } internal Section Called(string id) { Id = id; return this; } internal Section Live() { IsLive = true; return this; } internal Section OnOpen(Action opened) { Opened = opened; return this; } internal void Refill() { RefillAsked = true; } internal Section List(Func<IReadOnlyList<Row>> rows, string empty) { return List(rows, () => empty); } internal Section List(Func<IReadOnlyList<Row>> rows, Func<string> empty) { Rows = rows; Empty = empty; return this; } } internal sealed class Row { internal readonly string Title; internal readonly string Key; internal readonly string Aside; internal readonly UnityAction Act; internal readonly string Words; internal bool IsNote => Words != null; internal bool IsHeading { get { if (Key == null) { return Words == null; } return false; } } internal Row(string title, string key, string aside = null) : this(title, key, aside, null, null) { } internal Row(string title, string key, UnityAction act) : this(title, key, null, act, null) { } private Row(string title, string key, string aside, UnityAction act, string words) { Title = title; Key = key; Aside = aside; Act = act; Words = words; } internal static Row Note(string title, string words) { return new Row(title, null, null, null, words ?? ""); } } internal sealed class Shared { internal string Text = ""; } internal sealed class Entry { internal enum Kinds { Plain, Heading, Strip, Tile, Mark } internal readonly Kinds Kind; internal readonly string Caption; internal readonly UnityAction OnClick; internal readonly string Hint; internal readonly string Label; internal readonly Action<string> Apply; internal readonly string Accepts; internal readonly int
BepInEx/plugins/Astvard.Player.dll
Decompiled 2 weeks ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using System.Text.RegularExpressions; using Astvard.Core; using Astvard.Core.Builds; using Astvard.Core.Net; using Astvard.Core.Placement; using Astvard.Core.Sorting; using Astvard.Core.Terrain; using Astvard.Core.Ui; using Astvard.Players.Building; using Astvard.Players.Functions; using Astvard.Players.Hunting; using Astvard.Players.Sorting; using Astvard.Players.Terrain; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using Splatform; using UnityEngine; using UnityEngine.Events; using UnityEngine.Rendering; [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("Astvard.Player")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+d8721dbc184a53c5b52947c0c2c8980b874b1ebb")] [assembly: AssemblyProduct("Astvard.Player")] [assembly: AssemblyTitle("Astvard.Player")] [assembly: AssemblyVersion("1.0.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 Astvard.Players { internal static class CharacterStats { [HarmonyPatch(typeof(Player), "GetTotalFoodValue")] private static class EitrOnTop { private static void Postfix(Player __instance, ref float eitr) { Sheet now = Now; if (now != null && now.Eitr > 0 && (Object)(object)__instance == (Object)(object)Player.m_localPlayer) { eitr += now.Eitr; } } } private const float AskEvery = 10f; private static ZRoutedRpc _listening; private static ZNet _heardOn; private static float _askedAt = float.MinValue; private static Sheet _sheet = new Sheet(); private static Player _laidOn; private static bool _toldBadPacket; private static bool Heard { get { if ((Object)(object)_heardOn != (Object)null) { return _heardOn == ZNet.instance; } return false; } } private static Sheet Now { get { if (!Heard) { return null; } return _sheet; } } private static Player Prefab { get { ZNetScene instance = ZNetScene.instance; GameObject val = (((Object)(object)instance != (Object)null) ? instance.GetPrefab("Player") : null); if (!((Object)(object)val != (Object)null)) { return null; } return val.GetComponent<Player>(); } } internal static void Tick() { ZRoutedRpc instance = ZRoutedRpc.instance; ZNet instance2 = ZNet.instance; if (instance == null || (Object)(object)instance2 == (Object)null || instance2.IsServer()) { return; } if (_listening != instance) { instance.Register<ZPackage>("Astvard_MyStats", (Action<long, ZPackage>)OnSheet); _listening = instance; _askedAt = float.MinValue; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return; } if (!Heard) { if (!(Time.time - _askedAt < 10f)) { _askedAt = Time.time; instance.InvokeRoutedRPC("Astvard_AskMyStats", Array.Empty<object>()); } } else if ((Object)(object)localPlayer != (Object)(object)_laidOn && _sheet.Any) { Lay(localPlayer); } } private static void OnSheet(long sender, ZPackage pkg) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) Sheet val = StatSheets.UnpackSheet(pkg); if (val == null) { if (!_toldBadPacket) { Plugin.Log.LogWarning((object)"The server sent the character's numbers in a format this mod does not read."); } _toldBadPacket = true; return; } bool flag = !Heard; Sheet val2 = (Sheet)((!flag) ? ((object)_sheet) : ((object)new Sheet())); _sheet = val; _heardOn = ZNet.instance; if (!val.Same(val2)) { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null) { Lay(localPlayer); } Plugin.Log.LogInfo((object)("Character stats from the server: " + StatSheets.Describe(val) + ".")); if (localPlayer != null) { ((Character)localPlayer).Message((MessageType)1, flag ? ("Твоему персонажу здесь задано: " + StatSheets.Say(val)) : (val.Any ? ("Админ задал твоему персонажу: " + StatSheets.Say(val)) : "Админ вернул твоему персонажу числа игры"), 0, (Sprite)null, false); } MenuTabs.Refresh(); } } private static void Lay(Player player) { Player prefab = Prefab; if (!((Object)(object)prefab == (Object)null)) { player.m_baseHP = ((_sheet.Hp != -1) ? ((float)_sheet.Hp) : prefab.m_baseHP); player.m_baseStamina = ((_sheet.Stamina != -1) ? ((float)_sheet.Stamina) : prefab.m_baseStamina); player.m_maxCarryWeight = ((_sheet.Carry != -1) ? ((float)_sheet.Carry) : prefab.m_maxCarryWeight); _laidOn = player; } } internal static string About() { Sheet now = Now; if (now == null || !now.Any) { return ""; } Player prefab = Prefab; StringBuilder stringBuilder = new StringBuilder("Админ задал твоему персонажу на этом сервере:"); if (now.Hp != -1) { stringBuilder.Append("\nздоровье без еды ").Append(now.Hp).Append(((Object)(object)prefab != (Object)null) ? (" (у игры " + Round(prefab.m_baseHP) + ")") : ""); } if (now.Stamina != -1) { stringBuilder.Append("\nвыносливость без еды ").Append(now.Stamina).Append(((Object)(object)prefab != (Object)null) ? (" (у игры " + Round(prefab.m_baseStamina) + ")") : ""); } if (now.Eitr != -1) { stringBuilder.Append("\nэйтр сверх еды +").Append(now.Eitr); } if (now.Carry != -1) { stringBuilder.Append("\nпереносимый вес без пояса ").Append(now.Carry).Append(((Object)(object)prefab != (Object)null) ? (" (у игры " + Round(prefab.m_maxCarryWeight) + ")") : ""); } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null) { stringBuilder.Append("\nСейчас, с едой и поясом: здоровье ").Append(Round(((Character)localPlayer).GetMaxHealth())).Append(", выносливость ") .Append(Round(((Character)localPlayer).GetMaxStamina())) .Append(", эйтр ") .Append(Round(((Character)localPlayer).GetMaxEitr())) .Append(", вес ") .Append(Round(localPlayer.GetMaxCarryWeight())); } return stringBuilder.ToString(); } private static string Round(float value) { return Mathf.RoundToInt(value).ToString(CultureInfo.InvariantCulture); } } internal sealed class Charge { private sealed class Item { internal string Key; internal int Units; internal long Estimate; } internal readonly string Label; private readonly List<Item> _items = new List<Item>(); internal int Cost { get { long num = 0L; foreach (Item item in _items) { num += item.Estimate; } return (int)Math.Min(num, 2147483647L); } } internal Charge(string label) { Label = label; } internal Charge Add(Limit price, int units) { if (units > 0) { _items.Add(new Item { Key = price.Key, Units = units, Estimate = (long)price.Value * (long)units }); } return this; } internal Charge AddServerBuild(string name, int pieces, int own) { long estimate = ((own >= 0) ? own : (Limits.PriceBuild.Value + (long)Limits.PriceBuild100.Value * (long)((pieces + 99) / 100))); _items.Add(new Item { Key = "build:" + name, Units = pieces, Estimate = estimate }); return this; } internal List<KeyValuePair<string, int>> Keys() { List<KeyValuePair<string, int>> list = new List<KeyValuePair<string, int>>(_items.Count); foreach (Item item in _items) { list.Add(new KeyValuePair<string, int>(item.Key, item.Units)); } return list; } } internal static class Charges { private const float Patience = 10f; private static int _counter; private static int _asked; private static float _askedAt; private static Charge _charge; private static Action<int> _go; private static Action<bool> _refused; private static ZRoutedRpc _listening; internal static bool Waiting { get { if (_asked != 0) { return Time.time - _askedAt < 10f; } return false; } } internal static void Pay(Charge charge, Action<int> go, Action<bool> refused = null, bool asPlayer = false) { if ((Access.IsAdmin && !asPlayer) || charge.Cost <= 0) { go(0); return; } ZRoutedRpc instance = ZRoutedRpc.instance; if (instance == null) { refused?.Invoke(obj: false); return; } if (Waiting) { Notice.Say("Жду, что скажет сервер про руны"); refused?.Invoke(obj: false); return; } if (instance != _listening) { instance.Register<int, bool, int, int>("Astvard_PayAnswer", (Method<int, bool, int, int>)OnAnswer); _listening = instance; } _asked = ++_counter; _askedAt = Time.time; _charge = charge; _go = go; _refused = refused; instance.InvokeRoutedRPC("Astvard_Pay", new object[1] { Payments.PackPay(_asked, charge.Label, (IList<KeyValuePair<string, int>>)charge.Keys()) }); ((MonoBehaviour)Plugin.Instance).StartCoroutine(GiveUp(_asked)); } internal static void Refund(int receipt, string label) { if (receipt != 0) { ZRoutedRpc instance = ZRoutedRpc.instance; if (instance != null) { instance.InvokeRoutedRPC("Astvard_Refund", new object[1] { receipt }); } Plugin.Log.LogInfo((object)("Asked the runes back for «" + label + "» (ask " + receipt + "): it did not happen.")); Player localPlayer = Player.m_localPlayer; if (localPlayer != null) { ((Character)localPlayer).Message((MessageType)1, "Руны за «" + label + "» возвращаются: не вышло", 0, (Sprite)null, false); } } } internal static string List() { List<string> list = new List<string>(); Limit[] prices = Limits.Prices; foreach (Limit val in prices) { if (val.Value > 0) { list.Add(val.Title + " — " + val.Say(val.Value)); } } if (list.Count != 0) { return string.Join("\n", list.ToArray()); } return null; } private static void OnAnswer(long sender, int ask, bool yes, int cost, int balance) { if (ask != _asked) { if (yes && cost > 0) { ZRoutedRpc instance = ZRoutedRpc.instance; if (instance != null) { instance.InvokeRoutedRPC("Astvard_Refund", new object[1] { ask }); } Plugin.Log.LogInfo((object)("The server took " + cost + " runes for ask " + ask + " after it was given up — asked them back.")); } return; } Charge charge = _charge; Action<int> go = _go; Action<bool> refused = _refused; _asked = 0; _charge = null; _go = null; _refused = null; if (yes) { if (cost > 0) { Plugin.Log.LogInfo((object)("Paid " + cost + " runes for «" + charge.Label + "», " + balance + " left.")); Player localPlayer = Player.m_localPlayer; if (localPlayer != null) { ((Character)localPlayer).Message((MessageType)1, "−" + Words.Runes(cost) + " за «" + charge.Label + "». Осталось " + balance, 0, (Sprite)null, false); } } go((cost > 0) ? ask : 0); } else { Plugin.Log.LogInfo((object)("Not enough runes for «" + charge.Label + "»: " + cost + " asked, " + balance + " held.")); Notice.Say("Не хватает рун: «" + charge.Label + "» стоит " + Words.Runes(cost) + ", а у тебя " + balance); refused?.Invoke(obj: true); } } private static IEnumerator GiveUp(int ask) { yield return (object)new WaitForSeconds(10f); if (ask == _asked) { Action<bool> refused = _refused; _asked = 0; _charge = null; _go = null; _refused = null; Notice.Say("Сервер не ответил про руны — нажми ещё раз"); refused?.Invoke(obj: false); } } } internal static class Favorites { [HarmonyPatch(typeof(FejdStartup), "Start")] private static class AtTheMenu { private static void Postfix() { try { Take(); } catch (Exception ex) { Plugin.Log.LogError((object)("Favourites: " + ex)); } } } [CompilerGenerated] private static class <>O { public static PopupButtonCallback <0>__Pop; } private const string Argument = "+astvard_favorite"; private static readonly Regex Address = new Regex("^([A-Za-z0-9.-]{1,253}):(\\d{1,5})$"); private static readonly FieldInfo WindowsList = AccessTools.Field(typeof(ServerListGui), "m_favoriteServersList"); private static bool _taken; private static string _toSay; internal static void Tick() { //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Expected O, but got Unknown //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_0083: Expected O, but got Unknown if (_toSay == null) { return; } if ((Object)(object)ZNet.instance != (Object)null) { _toSay = null; return; } FejdStartup instance = FejdStartup.instance; if (!((Object)(object)instance == (Object)null) && !((Object)(object)instance.m_mainMenu == (Object)null) && instance.m_mainMenu.activeInHierarchy && UnifiedPopup.IsAvailable() && !UnifiedPopup.IsVisible()) { string toSay = _toSay; _toSay = null; object obj = <>O.<0>__Pop; if (obj == null) { PopupButtonCallback val = UnifiedPopup.Pop; <>O.<0>__Pop = val; obj = (object)val; } UnifiedPopup.Push((PopupBase)new WarningPopup("Избранное", toSay, (PopupButtonCallback)obj, false)); } } private static void Take() { if (_taken) { return; } _taken = true; string[] commandLineArgs = Environment.GetCommandLineArgs(); List<string> list = new List<string>(); for (int i = 0; i < commandLineArgs.Length; i++) { if (commandLineArgs[i] != "+astvard_favorite") { continue; } if (i + 1 >= commandLineArgs.Length) { Plugin.Log.LogWarning((object)"Favourites: +astvard_favorite came last, with no address after it."); continue; } string text = Put(commandLineArgs[i + 1]); if (text != null) { list.Add(text); } } if (list.Count > 0) { _toSay = string.Join("\n", list); } } private unsafe static string Put(string given) { //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Expected O, but got Unknown //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) Match match = Address.Match((given ?? "").Trim().TrimEnd(new char[1] { '/' })); if (!match.Success || !int.TryParse(match.Groups[2].Value, out var result) || result < 1 || result > 65535) { Plugin.Log.LogWarning((object)("Favourites: «" + given + "» after +astvard_favorite is not a host and a port, left alone.")); return null; } string text = match.Groups[1].Value.ToLowerInvariant(); string text2 = text + ":" + result; ServerJoinDataDedicated val = default(ServerJoinDataDedicated); ((ServerJoinDataDedicated)(ref val))..ctor(text, (ushort)result); LocalServerList val2 = ListOfTheWindow(); bool flag = val2 == null; if (flag) { val2 = new LocalServerList((string)null, ServerListGui.GetServerListLocations("favorite")); } try { if (Holds(val2, val)) { Plugin.Log.LogInfo((object)("Favourites: " + text2 + " is there already.")); return "Сервер " + text2 + " уже в избранном."; } val2.Add(new ServerJoinData(val)); SaveStatusCode val3 = val2.Save(false); if ((int)val3 != 0) { Plugin.Log.LogError((object)("Favourites: " + text2 + " was not saved: " + ((object)(*(SaveStatusCode*)(&val3))/*cast due to .constrained prefix*/).ToString() + ".")); return "Не вышло добавить " + text2 + " в избранное: игра не записала список (" + ((object)(*(SaveStatusCode*)(&val3))/*cast due to .constrained prefix*/).ToString() + ")."; } Plugin.Log.LogInfo((object)("Favourites: " + text2 + " added, into " + (flag ? "the list's file" : "the server window's list") + ".")); return "Сервер " + text2 + " добавлен в избранное — он в «Присоединиться» → «Избранное»."; } finally { if (flag) { val2.Dispose(); } } } private static LocalServerList ListOfTheWindow() { ServerListGui val = Object.FindFirstObjectByType<ServerListGui>((FindObjectsInactive)1); if ((Object)(object)val == (Object)null) { return null; } if (WindowsList == null) { Plugin.Log.LogWarning((object)"Favourites: the server window keeps its favourites elsewhere in this game; the file is written, and the window, made already, shows the server from the next launch."); return null; } object? value = WindowsList.GetValue(val); return (LocalServerList)((value is LocalServerList) ? value : null); } private static bool Holds(LocalServerList list, ServerJoinDataDedicated wanted) { //IL_0006: 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_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Invalid comparison between Unknown and I4 //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //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) for (int i = 0; i < list.Count; i++) { ServerJoinData val = list[i]; if ((int)val.m_type == 3) { ServerJoinDataDedicated dedicated = ((ServerJoinData)(ref val)).Dedicated; if (dedicated.m_port == wanted.m_port && string.Equals(((ServerJoinDataDedicated)(ref dedicated)).m_host, ((ServerJoinDataDedicated)(ref wanted)).m_host, StringComparison.OrdinalIgnoreCase)) { return true; } } } return false; } } internal static class FrameTurn { private sealed class Slow { internal int Count; internal double Longest; internal float ToldAt = float.MinValue; } private const double SlowMs = 8.0; private const float TellEvery = 60f; private static readonly Dictionary<string, Slow> Slows = new Dictionary<string, Slow>(); private static int _taken = -1; internal static bool Take() { int frameCount = Time.frameCount; if (_taken == frameCount) { return false; } _taken = frameCount; return true; } internal static long Started() { return Stopwatch.GetTimestamp(); } internal static void Done(string what, long started) { double num = (double)(Stopwatch.GetTimestamp() - started) * 1000.0 / (double)Stopwatch.Frequency; if (!(num < 8.0)) { if (!Slows.TryGetValue(what, out var value)) { value = new Slow(); Slows[what] = value; } value.Count++; if (num > value.Longest) { value.Longest = num; } if (!(Time.time - value.ToldAt < 60f)) { Plugin.Log.LogInfo((object)("Slow: " + what + " took " + num.ToString("0") + " ms" + ((value.Count > 1) ? (" — " + value.Count + " passes over " + 8.0.ToString("0") + " ms since the last word, the longest " + value.Longest.ToString("0") + " ms") : "") + ".")); value.ToldAt = Time.time; value.Count = 0; value.Longest = 0.0; } } } } internal static class InfoPage { private const float OffGround = 1f; private const float Near = 5f; private const int MostNames = 10; private static readonly string[] Sides = new string[8] { "север", "северо-восток", "восток", "юго-восток", "юг", "юго-запад", "запад", "северо-запад" }; internal static string Where() { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_004b: 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_006b: 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_0076: 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_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return ""; } Vector3 position = ((Component)localPlayer).transform.position; StringBuilder stringBuilder = new StringBuilder(); StringBuilder stringBuilder2 = stringBuilder.Append("Позиция: x ").Append(Mathf.RoundToInt(position.x)).Append(", z ") .Append(Mathf.RoundToInt(position.z)) .Append(" — "); Vector2 val = new Vector2(position.x, position.z); stringBuilder2.Append(Distance(((Vector2)(ref val)).magnitude)).Append(" от центра мира\n"); stringBuilder.Append(Height(position)).Append('\n'); stringBuilder.Append("Биом: ").Append(Biome(localPlayer)).Append('\n'); stringBuilder.Append("Смотришь на ").Append(Facing(localPlayer)).Append('\n'); stringBuilder.Append(Bed(position)).Append('\n'); stringBuilder.Append(Building(position)); return stringBuilder.ToString(); } internal static string World() { StringBuilder stringBuilder = new StringBuilder(); World world = ZNet.World; if (world != null) { stringBuilder.Append("Мир «").Append(world.m_name).Append("», сид ") .Append(world.m_seedName) .Append('\n'); } int num = Limits.WorldResourceRate(); stringBuilder.Append("Ресурсы: ").Append((num == Limits.ResourceRate.Default) ? "как в игре" : (num + "% от обычного")).Append('\n'); string text = Clock(); if (text != null) { stringBuilder.Append(text).Append('\n'); } stringBuilder.Append(Players()).Append('\n'); stringBuilder.Append("Мод у тебя: ").Append(Build.Say(Build.Here)).Append('\n'); stringBuilder.Append("Мод на сервере: ").Append(ServerBuild()); string text2 = ((Rules.ServerBuild != null) ? Build.Differs(Plain(Rules.ServerBuild)) : ""); if (text2.Length > 0) { stringBuilder.Append('\n').Append(text2); } return stringBuilder.ToString(); } internal static void CopySeed() { World world = ZNet.World; if (world == null || string.IsNullOrEmpty(world.m_seedName)) { Notice.Say("Сида нет — зайди в мир"); return; } GUIUtility.systemCopyBuffer = world.m_seedName; Notice.Say("Сид скопирован: " + world.m_seedName); } internal static string Allowed() { StringBuilder stringBuilder = new StringBuilder(); if (!Rules.Heard) { stringBuilder.Append("Сервер правил не сказал, пока так:\n"); } else if (Access.IsAdmin) { stringBuilder.Append(Access.AdminPays ? ("Ты сейчас админ: эти правила тебя не держат, а постройки — за ресурсы: " + Access.AdminPaysWhy + ".\n") : "Ты сейчас админ: эти правила тебя не держат.\n"); } stringBuilder.Append("Постройки: "); if (Rules.PlayersPay) { stringBuilder.Append("платно, ").Append(Rules.PlayersChests ? ("из сумки и сундуков " + Said(Limits.Chests)) : "только из сумки"); } else { stringBuilder.Append("даром, ").Append((Limits.BuildPause.Value > 0) ? ("не чаще раза в " + Limits.BuildPause.Value + " мин") : "без паузы"); } stringBuilder.Append("\nКопирование ").Append(Said(Limits.Copy)).Append(", выравнивание ") .Append(Rules.PlayersLevel ? Said(Limits.Level) : "только админу"); stringBuilder.Append("\nДорожки ").Append(Rules.PlayersRoad ? (Said(Limits.RoadLength) + ", мощение " + Said(Limits.PavingRadius)) : "только админу"); stringBuilder.Append("\nСнос деревьев и камней: ").Append(Rules.PlayersClear ? "можно" : "только админу, игрокам — подлесок"); stringBuilder.Append("\nМосты ").Append((Limits.BridgeLength.Value > 0) ? Said(Limits.BridgeLength) : "только админу"); stringBuilder.Append("\nПочинка ").Append(Said(Limits.Repair)).Append(", топливо ") .Append(Rules.PlayersRepairPay ? "из сумки" : "даром"); stringBuilder.Append("\nОтметки на карте ").Append(Said(Limits.MarksRadius)).Append(" — у всех, и у админа"); stringBuilder.Append("\nВыкладывать постройки на сервер: ").Append(Rules.PlayersShare ? "можно" : "только админу"); string text = Charges.List(); stringBuilder.Append("\nЦены в рунах: ").Append((text == null) ? "всё без рун" : ("\n" + text)); return stringBuilder.ToString(); } private static string Height(Vector3 at) { //IL_0000: 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_0036: 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) if (Character.InInterior(at)) { return "Высота: в подземелье не считается"; } string text = "Высота: " + Levelling.AboveWater(at.y); float num = default(float); if ((Object)(object)ZoneSystem.instance != (Object)null && ZoneSystem.instance.GetGroundHeight(at, ref num) && Mathf.Abs(at.y - num) > 1f) { text = text + "\nЗемля под тобой: " + Levelling.AboveWater(num); } return text; } private static string Biome(Player player) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) BiomeSector currentBiomeData = player.GetCurrentBiomeData(); if ((int)currentBiomeData.Biome != 0) { return currentBiomeData.GetName(false); } return "ещё не ясно"; } private static string Facing(Player player) { //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_000f: 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_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) Vector3 lookDir = ((Character)player).GetLookDir(); Vector2 way = default(Vector2); ((Vector2)(ref way))..ctor(lookDir.x, lookDir.z); if (((Vector2)(ref way)).sqrMagnitude < 0.0001f) { Vector3 forward = ((Component)player).transform.forward; ((Vector2)(ref way))..ctor(forward.x, forward.z); } float num = Bearing(way); return Side(num) + " (" + Mathf.RoundToInt(num) % 360 + "°)"; } private static string Bed(Vector3 at) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0074: 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) PlayerProfile val = (((Object)(object)Game.instance != (Object)null) ? Game.instance.GetPlayerProfile() : null); if (val != null && val.HaveCustomSpawnPoint()) { return "Кровать: " + Way(at, val.GetCustomSpawnPoint()); } Vector3 to = default(Vector3); if ((Object)(object)Game.instance != (Object)null && (Object)(object)ZoneSystem.instance != (Object)null && ZoneSystem.instance.GetLocationIcon(Game.instance.m_StartLocation, ref to)) { return "Кровати нет — возродишься у жертвенных камней: " + Way(at, to); } return "Кровати нет"; } private static string Building(Vector3 at) { //IL_0000: 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_0023: Unknown result type (might be due to invalid IL or missing references) if (Location.IsInsideNoBuildLocation(at)) { return "Строить: нельзя — здесь запрет самой игры"; } if (!PrivateArea.CheckAccess(at, 0f, false, false)) { return "Строить: нельзя — чужой оберег"; } if (PrivateArea.InsideFactionArea(at, (Faction)0)) { return "Строить: можно — оберег тебя пускает"; } return "Строить: можно — оберегов нет"; } private static string Clock() { EnvMan instance = EnvMan.instance; if ((Object)(object)instance == (Object)null) { return null; } int num = Mathf.FloorToInt(instance.GetDayFraction() * 24f * 60f) % 1440; string text = "Время: день " + instance.GetDay() + ", " + (num / 60).ToString("00") + ":" + (num % 60).ToString("00"); List<string> list = new List<string>(); if (EnvMan.IsNight()) { list.Add("ночь"); } if (EnvMan.CanSleep()) { list.Add("можно спать"); } if (list.Count <= 0) { return text; } return text + " — " + string.Join(", ", list); } private static string Players() { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) List<PlayerInfo> list = (((Object)(object)ZNet.instance != (Object)null) ? ZNet.instance.GetPlayerList() : null); if (list == null || list.Count == 0) { return "В мире: сервер ещё не прислал, кто здесь"; } List<string> list2 = new List<string>(); foreach (PlayerInfo item in list) { if (list2.Count == 10) { break; } string text = Plain(item.m_name); list2.Add((text.Length > 0) ? text : "без персонажа"); } string text2 = "В мире " + list.Count + " " + Words.Plural(list.Count, "игрок", "игрока", "игроков") + ": " + string.Join(", ", list2); if (list.Count <= list2.Count) { return text2; } return text2 + " и ещё " + (list.Count - list2.Count); } private static string ServerBuild() { string serverBuild = Rules.ServerBuild; if (serverBuild != null) { return Build.Say(Plain(serverBuild)); } if (!Rules.Heard) { return "не ответил: на нём нет Astvard.Server, или это одиночная игра"; } return "не говорит — сборка старше этой"; } private static string Said(Limit limit) { return limit.Say(limit.Value); } private static string Way(Vector3 from, Vector3 to) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //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_0046: Unknown result type (might be due to invalid IL or missing references) Vector2 way = default(Vector2); ((Vector2)(ref way))..ctor(to.x - from.x, to.z - from.z); if (((Vector2)(ref way)).magnitude < 5f) { return "рядом"; } return Distance(((Vector2)(ref way)).magnitude) + " на " + Side(Bearing(way)); } private static float Bearing(Vector2 way) { //IL_0000: 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) return Mathf.Repeat(Mathf.Atan2(way.x, way.y) * 57.29578f, 360f); } private static string Side(float degrees) { return Sides[Mathf.RoundToInt(degrees / 45f) % Sides.Length]; } private static string Distance(float metres) { if (metres < 1000f) { return Mathf.RoundToInt(metres) + " м"; } return (metres / 1000f).ToString("0.#", CultureInfo.InvariantCulture).Replace('.', ',') + " км"; } private static string Plain(string text) { if (string.IsNullOrEmpty(text)) { return ""; } StringBuilder stringBuilder = new StringBuilder(text.Length); foreach (char c in text) { if (c != '<' && c != '>' && !char.IsControl(c)) { stringBuilder.Append(c); } } return stringBuilder.ToString().Trim(); } } [BepInPlugin("astvard.player", "Astvard Player", "2.0.2")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInProcess("valheim.exe")] public sealed class Plugin : BaseUnityPlugin { [CompilerGenerated] private static class <>O { public static Func<string, string, string, string, Copy> <0>__TextAround; public static Func<Vector3, float, float, bool, bool, string, bool> <1>__PaveAt; public static Func<Vector3, float, bool, bool, bool, string, bool> <2>__StartAround; public static Func<string> <3>__About; public static Func<string> <4>__About; public static Func<string> <5>__Where; public static Func<string> <6>__World; public static Func<string> <7>__Allowed; public static UnityAction <8>__CopySeed; public static Func<string> <9>__Now; public static Action<string> <10>__CopyAndHold; public static Action<string> <11>__CopyAndSave; public static UnityAction <12>__CopyForRunes; public static Func<string> <13>__Caption; public static UnityAction <14>__Next; public static Func<string> <15>__NeighboursCaption; public static UnityAction <16>__ToggleNeighbours; public static Func<string> <17>__SnapCaption; public static UnityAction <18>__ToggleSnap; public static Func<string> <19>__ClearCaption; public static UnityAction <20>__ToggleClear; public static Func<string> <21>__About; public static Func<string> <22>__About; public static Func<string> <23>__Keys; public static UnityAction <24>__Undo; public static Func<IReadOnlyList<Row>> <25>__Rows; public static Func<string> <26>__Info; public static UnityAction <27>__Place; public static UnityAction <28>__PlaceForRunes; public static Action<string> <29>__Rename; public static Func<string> <30>__ChosenName; public static Action<string> <31>__Move; public static Func<string> <32>__ChosenCategory; public static UnityAction <33>__Put; public static UnityAction <34>__Delete; public static Func<IReadOnlyList<Row>> <35>__Rows; public static Func<string> <36>__Empty; public static Func<string> <37>__Info; public static UnityAction <38>__Place; public static UnityAction <39>__PlaceForRunes; public static Func<string> <40>__KindCaption; public static UnityAction <41>__NextKind; public static Func<string> <42>__ModeCaption; public static UnityAction <43>__ToggleMode; public static Func<string> <44>__PlaceCaption; public static UnityAction <45>__Place; public static UnityAction <46>__PlaceForRunes; public static Func<string> <47>__About; public static Func<string> <48>__WalkwayCaption; public static UnityAction <49>__ToggleWalkway; public static Func<string> <50>__RoofCaption; public static UnityAction <51>__ToggleRoof; public static Func<string> <52>__LevelCaption; public static UnityAction <53>__ToggleLevel; public static UnityAction <54>__Start; public static UnityAction <55>__StartForRunes; public static Func<string> <56>__About; public static Func<string> <57>__RoofCaption; public static UnityAction <58>__ToggleRoof; public static UnityAction <59>__Start; public static UnityAction <60>__StartForRunes; public static Func<string> <61>__About; public static Func<IReadOnlyList<Row>> <62>__Rows; public static Func<string> <63>__Empty; public static Func<string> <64>__Info; public static Func<string> <65>__HighlightCaption; public static UnityAction <66>__Highlight; public static Func<string> <67>__ShapeCaption; public static UnityAction <68>__ToggleShape; public static UnityAction <69>__Move; public static Action<string> <70>__Rename; public static Func<string> <71>__ChosenName; public static Action<string> <72>__Resize; public static Func<string> <73>__ChosenRadius; public static Action<string> <74>__Invite; public static Action<string> <75>__Strike; public static Func<string> <76>__DropCaption; public static UnityAction <77>__Drop; public static Func<IReadOnlyList<Row>> <78>__Rows; public static Func<string> <79>__Empty; public static Func<string> <80>__ZoneNow; public static Action<string> <81>__SetCoal; public static Func<string> <82>__ChosenCoal; public static Func<string> <83>__Stations; public static Func<string> <84>__Coal; public static Func<string> <85>__Lacking; public static Func<string> <86>__NoRoom; public static Func<string> <87>__Hives; public static Func<string> <88>__Meads; public static Func<string> <89>__Tames; public static Func<string> <90>__Info; public static Func<IReadOnlyList<Row>> <91>__Rows; public static Func<string> <92>__Empty; public static Func<string> <93>__ZoneNow; public static Func<string> <94>__ChosenKeep; public static Func<string> <95>__ChosenSeeds; public static Action<string> <96>__SetLimits; public static Func<string> <97>__ChosenBeds; public static Func<string> <98>__About; public static Func<IReadOnlyList<Row>> <99>__Rows; public static Func<string> <100>__Empty; public static Action <101>__Opened; public static Func<string> <102>__Info; public static Action<string> <103>__SetKeep; public static Func<string> <104>__ChosenKeep; public static Func<IReadOnlyList<Row>> <105>__ShelfRows; public static Func<string> <106>__Now; public static Func<string> <107>__SupplyTile; public static UnityAction <108>__ArmSupply; public static Func<string> <109>__CollectTile; public static UnityAction <110>__ArmCollect; public static Func<string> <111>__HighlightCaption; public static UnityAction <112>__ToggleHighlight; public static Func<string> <113>__About; public static Func<string> <114>__FillMeans; public static Func<string> <115>__FillCaption; public static UnityAction <116>__ToggleFill; public static Func<string> <117>__CollectMeans; public static Func<string> <118>__CollectCaption; public static UnityAction <119>__ToggleCollect; public static Func<string> <120>__ReachSays; public static Action<string> <121>__SetReach; public static Func<string> <122>__ShapeMeans; public static Func<string> <123>__ShapeCaption; public static UnityAction <124>__ToggleShape; public static Func<string> <125>__CoalSays; public static Action<string> <126>__SetCoal; public static Func<string> <127>__AtChests; public static Func<string> <128>__Coal; public static Func<string> <129>__Lacks; public static Func<string> <130>__NoRoom; public static Func<string> <131>__Hives; public static Func<string> <132>__Barrels; public static Func<string> <133>__Tames; public static Func<string> <134>__Now; public static UnityAction <135>__Place; public static Func<string> <136>__TrapTile; public static UnityAction <137>__ArmTrap; public static Func<string> <138>__ReleaseTile; public static UnityAction <139>__ArmRelease; public static Func<string> <140>__FeedTile; public static UnityAction <141>__ToggleFeed; public static Func<string> <142>__Near; public static Func<string> <143>__Diets; public static Func<string> <144>__About; public static UnityAction <145>__Circle; public static UnityAction <146>__Square; public static Func<string> <147>__About; public static UnityAction <148>__TakeBack; public static Action<Vector3> <149>__RememberEnd; public static Action<Vector3> <150>__ForgetEnd; public static Action <151>__Redraw; public static Func<string> <152>__Now; public static UnityAction <153>__Start; public static UnityAction <154>__Continue; public static Action<string> <155>__Pave; public static Func<string> <156>__SideCaption; public static UnityAction <157>__ToggleSide; public static Func<string> <158>__About; public static UnityAction <159>__TakeBack; public static Action<string> <160>__Run; public static Func<string> <161>__About; public static Func<string> <162>__Caption; public static UnityAction <163>__Toggle; public static Func<string> <164>__About; public static Func<string> <165>__CornerSays; } internal const string Guid = "astvard.player"; internal const string Title = "Astvard Player"; private Harmony _harmony; internal static ManualLogSource Log { get; private set; } internal static Plugin Instance { get; private set; } private void Awake() { //IL_015f: 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_016a: Expected O, but got Unknown //IL_0252: Unknown result type (might be due to invalid IL or missing references) //IL_0257: Unknown result type (might be due to invalid IL or missing references) //IL_025d: Expected O, but got Unknown //IL_0297: Unknown result type (might be due to invalid IL or missing references) //IL_029c: Unknown result type (might be due to invalid IL or missing references) //IL_02a2: Expected O, but got Unknown //IL_02d2: Unknown result type (might be due to invalid IL or missing references) //IL_02d7: Unknown result type (might be due to invalid IL or missing references) //IL_02dd: Expected O, but got Unknown //IL_030d: Unknown result type (might be due to invalid IL or missing references) //IL_0312: Unknown result type (might be due to invalid IL or missing references) //IL_0318: Expected O, but got Unknown //IL_0348: Unknown result type (might be due to invalid IL or missing references) //IL_034d: Unknown result type (might be due to invalid IL or missing references) //IL_0353: Expected O, but got Unknown //IL_0400: Unknown result type (might be due to invalid IL or missing references) //IL_0405: Unknown result type (might be due to invalid IL or missing references) //IL_040b: Expected O, but got Unknown //IL_0480: Unknown result type (might be due to invalid IL or missing references) //IL_0485: Unknown result type (might be due to invalid IL or missing references) //IL_048b: Expected O, but got Unknown //IL_04a5: Unknown result type (might be due to invalid IL or missing references) //IL_04aa: Unknown result type (might be due to invalid IL or missing references) //IL_04b0: Expected O, but got Unknown //IL_0578: Unknown result type (might be due to invalid IL or missing references) //IL_057d: Unknown result type (might be due to invalid IL or missing references) //IL_0583: Expected O, but got Unknown //IL_059d: Unknown result type (might be due to invalid IL or missing references) //IL_05a2: Unknown result type (might be due to invalid IL or missing references) //IL_05a8: Expected O, but got Unknown //IL_0641: Unknown result type (might be due to invalid IL or missing references) //IL_0646: Unknown result type (might be due to invalid IL or missing references) //IL_064c: Expected O, but got Unknown //IL_0666: Unknown result type (might be due to invalid IL or missing references) //IL_066b: Unknown result type (might be due to invalid IL or missing references) //IL_0671: Expected O, but got Unknown //IL_06e5: Unknown result type (might be due to invalid IL or missing references) //IL_06ea: Unknown result type (might be due to invalid IL or missing references) //IL_06f0: Expected O, but got Unknown //IL_0720: Unknown result type (might be due to invalid IL or missing references) //IL_0725: Unknown result type (might be due to invalid IL or missing references) //IL_072b: Expected O, but got Unknown //IL_075b: Unknown result type (might be due to invalid IL or missing references) //IL_0760: Unknown result type (might be due to invalid IL or missing references) //IL_0766: Expected O, but got Unknown //IL_0780: Unknown result type (might be due to invalid IL or missing references) //IL_0785: Unknown result type (might be due to invalid IL or missing references) //IL_078b: Expected O, but got Unknown //IL_0863: Unknown result type (might be due to invalid IL or missing references) //IL_0868: Unknown result type (might be due to invalid IL or missing references) //IL_086e: Expected O, but got Unknown //IL_089e: Unknown result type (might be due to invalid IL or missing references) //IL_08a3: Unknown result type (might be due to invalid IL or missing references) //IL_08a9: Expected O, but got Unknown //IL_08d9: Unknown result type (might be due to invalid IL or missing references) //IL_08de: Unknown result type (might be due to invalid IL or missing references) //IL_08e4: Expected O, but got Unknown //IL_08fe: Unknown result type (might be due to invalid IL or missing references) //IL_0903: Unknown result type (might be due to invalid IL or missing references) //IL_0909: Expected O, but got Unknown //IL_0923: Unknown result type (might be due to invalid IL or missing references) //IL_0928: Unknown result type (might be due to invalid IL or missing references) //IL_092e: Expected O, but got Unknown //IL_096d: Unknown result type (might be due to invalid IL or missing references) //IL_0972: Unknown result type (might be due to invalid IL or missing references) //IL_0978: Expected O, but got Unknown //IL_0a3a: Unknown result type (might be due to invalid IL or missing references) //IL_0a3f: Unknown result type (might be due to invalid IL or missing references) //IL_0a45: Expected O, but got Unknown //IL_0a5f: Unknown result type (might be due to invalid IL or missing references) //IL_0a64: Unknown result type (might be due to invalid IL or missing references) //IL_0a6a: Expected O, but got Unknown //IL_0a84: Unknown result type (might be due to invalid IL or missing references) //IL_0a89: Unknown result type (might be due to invalid IL or missing references) //IL_0a8f: Expected O, but got Unknown //IL_0ace: Unknown result type (might be due to invalid IL or missing references) //IL_0ad3: Unknown result type (might be due to invalid IL or missing references) //IL_0ad9: Expected O, but got Unknown //IL_0b7f: Unknown result type (might be due to invalid IL or missing references) //IL_0b84: Unknown result type (might be due to invalid IL or missing references) //IL_0b8a: Expected O, but got Unknown //IL_0bba: Unknown result type (might be due to invalid IL or missing references) //IL_0bbf: Unknown result type (might be due to invalid IL or missing references) //IL_0bc5: Expected O, but got Unknown //IL_0bdf: Unknown result type (might be due to invalid IL or missing references) //IL_0be4: Unknown result type (might be due to invalid IL or missing references) //IL_0bea: Expected O, but got Unknown //IL_0d31: Unknown result type (might be due to invalid IL or missing references) //IL_0d36: Unknown result type (might be due to invalid IL or missing references) //IL_0d3c: Expected O, but got Unknown //IL_0dfc: Unknown result type (might be due to invalid IL or missing references) //IL_0e06: Expected O, but got Unknown //IL_1051: Unknown result type (might be due to invalid IL or missing references) //IL_105b: Expected O, but got Unknown //IL_12ea: Unknown result type (might be due to invalid IL or missing references) //IL_12ef: Unknown result type (might be due to invalid IL or missing references) //IL_12f5: Expected O, but got Unknown //IL_1325: Unknown result type (might be due to invalid IL or missing references) //IL_132a: Unknown result type (might be due to invalid IL or missing references) //IL_1330: Expected O, but got Unknown //IL_1360: Unknown result type (might be due to invalid IL or missing references) //IL_1365: Unknown result type (might be due to invalid IL or missing references) //IL_136b: Expected O, but got Unknown //IL_13ea: Unknown result type (might be due to invalid IL or missing references) //IL_13ef: Unknown result type (might be due to invalid IL or missing references) //IL_13f5: Expected O, but got Unknown //IL_1445: Unknown result type (might be due to invalid IL or missing references) //IL_144a: Unknown result type (might be due to invalid IL or missing references) //IL_1450: Expected O, but got Unknown //IL_14f0: Unknown result type (might be due to invalid IL or missing references) //IL_14f5: Unknown result type (might be due to invalid IL or missing references) //IL_14fb: Expected O, but got Unknown //IL_16bd: Unknown result type (might be due to invalid IL or missing references) //IL_16c2: Unknown result type (might be due to invalid IL or missing references) //IL_16c8: Expected O, but got Unknown //IL_16f8: Unknown result type (might be due to invalid IL or missing references) //IL_16fd: Unknown result type (might be due to invalid IL or missing references) //IL_1703: Expected O, but got Unknown //IL_173d: Unknown result type (might be due to invalid IL or missing references) //IL_1742: Unknown result type (might be due to invalid IL or missing references) //IL_1748: Expected O, but got Unknown //IL_1778: Unknown result type (might be due to invalid IL or missing references) //IL_177d: Unknown result type (might be due to invalid IL or missing references) //IL_1783: Expected O, but got Unknown //IL_1851: Unknown result type (might be due to invalid IL or missing references) //IL_1856: Unknown result type (might be due to invalid IL or missing references) //IL_185c: Expected O, but got Unknown //IL_1876: Unknown result type (might be due to invalid IL or missing references) //IL_187b: Unknown result type (might be due to invalid IL or missing references) //IL_1881: Expected O, but got Unknown //IL_18c0: Unknown result type (might be due to invalid IL or missing references) //IL_18c5: Unknown result type (might be due to invalid IL or missing references) //IL_18cb: Expected O, but got Unknown //IL_1985: Unknown result type (might be due to invalid IL or missing references) //IL_198a: Unknown result type (might be due to invalid IL or missing references) //IL_1990: Expected O, but got Unknown //IL_19aa: Unknown result type (might be due to invalid IL or missing references) //IL_19af: Unknown result type (might be due to invalid IL or missing references) //IL_19b5: Expected O, but got Unknown //IL_1a55: Unknown result type (might be due to invalid IL or missing references) //IL_1a5a: Unknown result type (might be due to invalid IL or missing references) //IL_1a60: Expected O, but got Unknown //IL_1b1b: Unknown result type (might be due to invalid IL or missing references) //IL_1b20: Unknown result type (might be due to invalid IL or missing references) //IL_1b26: Expected O, but got Unknown //IL_1b77: Unknown result type (might be due to invalid IL or missing references) //IL_1b81: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; Instance = this; Tab val = MenuTabs.Add("ПАНЕЛЬ ИГРОКА"); Copies.Around = Commands.TextAround; Paving.Circle = Roads.PaveAt; Paving.Fence = Fence.StartAround; Section obj = val.Add("Информация", "piece_cartographytable").Live().Block("Руны", (Func<string>)Runes.About) .Block("Персонаж", (Func<string>)CharacterStats.About) .Block("Где ты", (Func<string>)InfoPage.Where) .Block("Мир и сервер", (Func<string>)InfoPage.World) .Block("Правила сервера", (Func<string>)InfoPage.Allowed); object obj2 = <>O.<8>__CopySeed; if (obj2 == null) { UnityAction val2 = InfoPage.CopySeed; <>O.<8>__CopySeed = val2; obj2 = (object)val2; } obj.Action("Скопировать сид", (UnityAction)obj2); Section obj3 = val.Add("Постройки", "Hammer").Called("build-settings").Live() .Strip((Func<string>)Builder.Now) .Heading("Копия") .Field("Радиус, м", "10, если пусто", "Копировать", (Action<string>)Commands.CopyAndHold, "0123456789", 2, ref Commands.Radius) .Field("Имя постройки", "напр. Дом у реки", "Скопировать", (Action<string>)Commands.CopyAndSave, (string)null, 60, (Func<string>)null) .Input("Категория", "Разное, если пусто", (string)null, 40, ref Commands.Category); object obj4 = <>O.<12>__CopyForRunes; if (obj4 == null) { UnityAction val3 = Commands.CopyForRunes; <>O.<12>__CopyForRunes = val3; obj4 = (object)val3; } Section obj5 = obj3.Tile("Копировать за руны", (UnityAction)obj4).Heading("Как ставится"); Func<string> func = Groundwork.Caption; object obj6 = <>O.<14>__Next; if (obj6 == null) { UnityAction val4 = Groundwork.Next; <>O.<14>__Next = val4; obj6 = (object)val4; } Section obj7 = obj5.Toggle(func, (UnityAction)obj6); Func<string> func2 = BuildSettings.NeighboursCaption; object obj8 = <>O.<16>__ToggleNeighbours; if (obj8 == null) { UnityAction val5 = BuildSettings.ToggleNeighbours; <>O.<16>__ToggleNeighbours = val5; obj8 = (object)val5; } Section obj9 = obj7.Toggle(func2, (UnityAction)obj8); Func<string> func3 = BuildSettings.SnapCaption; object obj10 = <>O.<18>__ToggleSnap; if (obj10 == null) { UnityAction val6 = BuildSettings.ToggleSnap; <>O.<18>__ToggleSnap = val6; obj10 = (object)val6; } Section obj11 = obj9.Toggle(func3, (UnityAction)obj10); Func<string> func4 = BuildSettings.ClearCaption; object obj12 = <>O.<20>__ToggleClear; if (obj12 == null) { UnityAction val7 = BuildSettings.ToggleClear; <>O.<20>__ToggleClear = val7; obj12 = (object)val7; } Section obj13 = obj11.Toggle(func4, (UnityAction)obj12).Mark("admin-build-tiles").Input("Дистанция проекции, м", "11, если пусто; от 2 до 40", "0123456789.,", 4, ref BuildSettings.Distance) .Block("Что копируется", (Func<string>)Commands.About) .Block("Что это значит", (Func<string>)BuildSettings.About) .Block("Клавиши", (Func<string>)BuildSettings.Keys); object obj14 = <>O.<24>__Undo; if (obj14 == null) { UnityAction val8 = Commands.Undo; <>O.<24>__Undo = val8; obj14 = (object)val8; } obj13.Action("Отменить постройку", (UnityAction)obj14); Section obj15 = val.Add("Мои постройки", "Wood").List((Func<IReadOnlyList<Row>>)Library.Rows, "Пока пусто: «Скопировать»\nв «Постройках» сохраняет сюда").Block("Постройка", (Func<string>)Library.Info); object obj16 = <>O.<27>__Place; if (obj16 == null) { UnityAction val9 = Library.Place; <>O.<27>__Place = val9; obj16 = (object)val9; } Section obj17 = obj15.Tile("Поставить", (UnityAction)obj16); object obj18 = <>O.<28>__PlaceForRunes; if (obj18 == null) { UnityAction val10 = Library.PlaceForRunes; <>O.<28>__PlaceForRunes = val10; obj18 = (object)val10; } Section obj19 = obj17.Tile("За руны", (UnityAction)obj18).Heading("Имя и категория").Field("Имя", "новое имя", "Переназвать", (Action<string>)Library.Rename, (string)null, 60, (Func<string>)Library.ChosenName) .Field("Категория", "напр. Дома", "Перенести", (Action<string>)Library.Move, (string)null, 40, (Func<string>)Library.ChosenCategory) .Heading("Ещё"); object obj20 = <>O.<33>__Put; if (obj20 == null) { UnityAction val11 = PutOnServer.Put; <>O.<33>__Put = val11; obj20 = (object)val11; } Section obj21 = obj19.Tile("Выложить на сервер", (UnityAction)obj20); object obj22 = <>O.<34>__Delete; if (obj22 == null) { UnityAction val12 = Library.Delete; <>O.<34>__Delete = val12; obj22 = (object)val12; } Library.Section = obj21.Tile("Удалить", (UnityAction)obj22); Section obj23 = val.Add("Постройки сервера", "piece_workbench").Called("server-builds").List((Func<IReadOnlyList<Row>>)ServerLibrary.Rows, (Func<string>)ServerLibrary.Empty) .Block("Постройка", (Func<string>)ServerLibrary.Info); object obj24 = <>O.<38>__Place; if (obj24 == null) { UnityAction val13 = ServerLibrary.Place; <>O.<38>__Place = val13; obj24 = (object)val13; } Section obj25 = obj23.Tile("Поставить", (UnityAction)obj24); object obj26 = <>O.<39>__PlaceForRunes; if (obj26 == null) { UnityAction val14 = ServerLibrary.PlaceForRunes; <>O.<39>__PlaceForRunes = val14; obj26 = (object)val14; } ServerLibrary.Section = obj25.Tile("За руны", (UnityAction)obj26); Section obj27 = val.Add("Сундуки", "piece_chest_wood").Live().Strip((Func<string>)Builder.Now) .Heading("Какой и как"); Func<string> func5 = Chests.KindCaption; object obj28 = <>O.<41>__NextKind; if (obj28 == null) { UnityAction val15 = Chests.NextKind; <>O.<41>__NextKind = val15; obj28 = (object)val15; } Section obj29 = obj27.Toggle(func5, (UnityAction)obj28); Func<string> func6 = Chests.ModeCaption; object obj30 = <>O.<43>__ToggleMode; if (obj30 == null) { UnityAction val16 = Chests.ToggleMode; <>O.<43>__ToggleMode = val16; obj30 = (object)val16; } Section obj31 = obj29.Toggle(func6, (UnityAction)obj30); Func<string> func7 = Chests.PlaceCaption; object obj32 = <>O.<45>__Place; if (obj32 == null) { UnityAction val17 = Chests.Place; <>O.<45>__Place = val17; obj32 = (object)val17; } Section obj33 = obj31.Toggle(func7, (UnityAction)obj32); object obj34 = <>O.<46>__PlaceForRunes; if (obj34 == null) { UnityAction val18 = Chests.PlaceForRunes; <>O.<46>__PlaceForRunes = val18; obj34 = (object)val18; } obj33.Tile("За руны", (UnityAction)obj34).Block("Как встаёт", (Func<string>)Chests.About).Block("Клавиши", (Func<string>)BuildSettings.Keys); Section obj35 = val.Add("Забор", "stake_wall").Live().Strip((Func<string>)(() => Both(Fence.Now(), Builder.Now()))) .Heading("Кольцо") .Input("Радиус, м", "20, если пусто", "0123456789.,", 4, ref Fence.Radius); Func<string> func8 = Fence.WalkwayCaption; object obj36 = <>O.<49>__ToggleWalkway; if (obj36 == null) { UnityAction val19 = Fence.ToggleWalkway; <>O.<49>__ToggleWalkway = val19; obj36 = (object)val19; } Section obj37 = obj35.Toggle(func8, (UnityAction)obj36); Func<string> func9 = Fence.RoofCaption; object obj38 = <>O.<51>__ToggleRoof; if (obj38 == null) { UnityAction val20 = Fence.ToggleRoof; <>O.<51>__ToggleRoof = val20; obj38 = (object)val20; } Section obj39 = obj37.Toggle(func9, (UnityAction)obj38); Func<string> func10 = Fence.LevelCaption; object obj40 = <>O.<53>__ToggleLevel; if (obj40 == null) { UnityAction val21 = Fence.ToggleLevel; <>O.<53>__ToggleLevel = val21; obj40 = (object)val21; } Section obj41 = obj39.Toggle(func10, (UnityAction)obj40); object obj42 = <>O.<54>__Start; if (obj42 == null) { UnityAction val22 = Fence.Start; <>O.<54>__Start = val22; obj42 = (object)val22; } Section obj43 = obj41.Action("Обнести забором", (UnityAction)obj42); object obj44 = <>O.<55>__StartForRunes; if (obj44 == null) { UnityAction val23 = Fence.StartForRunes; <>O.<55>__StartForRunes = val23; obj44 = (object)val23; } Section obj45 = obj43.Action("Обнести забором за руны", (UnityAction)obj44).Block("Как встаёт", (Func<string>)Fence.About); object obj46 = <>O.<24>__Undo; if (obj46 == null) { UnityAction val24 = Commands.Undo; <>O.<24>__Undo = val24; obj46 = (object)val24; } obj45.Action("Отменить постройку", (UnityAction)obj46); Section obj47 = val.Add("Мост", "wood_floor").Live().Strip((Func<string>)(() => Both(Bridge.Now(), Builder.Now()))) .Heading("Размеры") .Input("Ширина, секций по 2 м", "2, если пусто; до 8", "0123456789", 1, ref Bridge.Width) .Input("Подъём настила, м", "0, если пусто", "0123456789.,", 4, ref Bridge.Lift) .Input("Отступ конца, м", "4, если пусто", "0123456789.,", 4, ref Bridge.Gap); Func<string> func11 = Bridge.RoofCaption; object obj48 = <>O.<58>__ToggleRoof; if (obj48 == null) { UnityAction val25 = Bridge.ToggleRoof; <>O.<58>__ToggleRoof = val25; obj48 = (object)val25; } Section obj49 = obj47.Toggle(func11, (UnityAction)obj48); object obj50 = <>O.<59>__Start; if (obj50 == null) { UnityAction val26 = Bridge.Start; <>O.<59>__Start = val26; obj50 = (object)val26; } Section obj51 = obj49.Action("Начать мост", (UnityAction)obj50); object obj52 = <>O.<60>__StartForRunes; if (obj52 == null) { UnityAction val27 = Bridge.StartForRunes; <>O.<60>__StartForRunes = val27; obj52 = (object)val27; } Section obj53 = obj51.Action("Начать мост за руны", (UnityAction)obj52).Block("Как класть", (Func<string>)Bridge.About); object obj54 = <>O.<24>__Undo; if (obj54 == null) { UnityAction val28 = Commands.Undo; <>O.<24>__Undo = val28; obj54 = (object)val28; } obj53.Action("Отменить постройку", (UnityAction)obj54); Section obj55 = val.Add("Зоны сортировки", "Cart").List((Func<IReadOnlyList<Row>>)SortPage.Rows, (Func<string>)SortPage.Empty).Live() .Block("Зона", (Func<string>)SortPage.Info); Func<string> func12 = SortPage.HighlightCaption; object obj56 = <>O.<66>__Highlight; if (obj56 == null) { UnityAction val29 = SortPage.Highlight; <>O.<66>__Highlight = val29; obj56 = (object)val29; } Section obj57 = obj55.Toggle(func12, (UnityAction)obj56); Func<string> func13 = SortPage.ShapeCaption; object obj58 = <>O.<68>__ToggleShape; if (obj58 == null) { UnityAction val30 = SortPage.ToggleShape; <>O.<68>__ToggleShape = val30; obj58 = (object)val30; } Section obj59 = obj57.Toggle(func13, (UnityAction)obj58); object obj60 = <>O.<69>__Move; if (obj60 == null) { UnityAction val31 = SortPage.Move; <>O.<69>__Move = val31; obj60 = (object)val31; } Section obj61 = obj59.Tile("Перенести", (UnityAction)obj60).Heading("Имя и размер").Field("Имя зоны", "напр. Склад", "Назвать", (Action<string>)SortPage.Rename, (string)null, 24, (Func<string>)SortPage.ChosenName) .Field("Радиус, м", "у квадрата — от середины до края", "Задать", (Action<string>)SortPage.Resize, "0123456789", 2, (Func<string>)SortPage.ChosenRadius) .Heading("Кто в зоне") .Field("Вписать игрока", "имя в игре", "Вписать", (Action<string>)SortPage.Invite, (string)null, 32, (Func<string>)null) .Field("Выписать игрока", "имя в игре", "Выписать", (Action<string>)SortPage.Strike, (string)null, 32, (Func<string>)null); Func<string> func14 = SortPage.DropCaption; object obj62 = <>O.<77>__Drop; if (obj62 == null) { UnityAction val32 = SortPage.Drop; <>O.<77>__Drop = val32; obj62 = (object)val32; } SortPage.Zones = obj61.Button(func14, (UnityAction)obj62); FillPage.Section = val.Add("Настройка зоны", "smelter").List((Func<IReadOnlyList<Row>>)FillPage.Rows, (Func<string>)FillPage.Empty).Live() .Strip((Func<string>)FillPage.ZoneNow) .Heading("Что наполнять"); int[] order = FillKinds.Order; foreach (int num2 in order) { int chosen = num2; FillPage.Section.Toggle((Func<string>)(() => FillPage.Caption(chosen)), (UnityAction)delegate { FillPage.Toggle(chosen); }); } FillPage.Section.Field("Угля на складе", "0 — без предела", "Задать", (Action<string>)FillPage.SetCoal, "0123456789", 6, (Func<string>)FillPage.ChosenCoal).Heading("Последний проход").Block("Станции", (Func<string>)FillPage.Stations) .Block("Уголь", (Func<string>)FillPage.Coal) .Block("Нечем наполнить", (Func<string>)FillPage.Lacking) .Block("Некуда класть", (Func<string>)FillPage.NoRoom) .Block("Ульи", (Func<string>)FillPage.Hives) .Block("Медовухи", (Func<string>)FillPage.Meads) .Block("Звери", (Func<string>)FillPage.Tames) .Block("Что это значит", (Func<string>)FillPage.Info); GardenPage.Section = val.Add("Огород", "Cultivator").List((Func<IReadOnlyList<Row>>)GardenPage.Rows, (Func<string>)GardenPage.Empty).Live() .Strip((Func<string>)GardenPage.ZoneNow) .Heading("Что делать"); order = GardenKinds.Order; foreach (int num3 in order) { int chosen2 = num3; GardenPage.Section.Toggle((Func<string>)(() => GardenPage.Caption(chosen2)), (UnityAction)delegate { GardenPage.Toggle(chosen2); }); } GardenPage.Section.Heading("Пределы").Input("Урожая на складе", "каждой культуры, 0 — без предела", "0123456789", 6, (Func<string>)GardenPage.ChosenKeep, ref GardenPage.Keep).Input("Семян на складе", "каждого вида, 0 — без предела", "0123456789", 6, (Func<string>)GardenPage.ChosenSeeds, ref GardenPage.Seeds) .Field("Количество грядок", "всего в зоне, 0 — без предела", "Задать", (Action<string>)GardenPage.SetLimits, "0123456789", 6, (Func<string>)GardenPage.ChosenBeds) .Block("Как это устроено", (Func<string>)GardenPage.About); MeadPage.Section = val.Add("Медовухи", "MeadHealthMinor").List((Func<IReadOnlyList<Row>>)MeadPage.Rows, (Func<string>)MeadPage.Empty).OnOpen((Action)MeadPage.Opened) .Live() .Block("Сейчас", (Func<string>)MeadPage.Info) .Field("Держать на складе", "бутылок, 0 — не варить", "Задать", (Action<string>)MeadPage.SetKeep, "0123456789", 4, (Func<string>)MeadPage.ChosenKeep); val.Add("Полки", "sign").List((Func<IReadOnlyList<Row>>)SortPage.ShelfRows, "Полок нет"); StationChests.Bind(((BaseUnityPlugin)this).Config); Section obj63 = val.Add("Зона станций", "piece_chest").Live().Strip((Func<string>)StationChests.Now) .Heading("Назначить сундук"); Func<string> func15 = StationPage.SupplyTile; object obj64 = <>O.<108>__ArmSupply; if (obj64 == null) { UnityAction val33 = StationPage.ArmSupply; <>O.<108>__ArmSupply = val33; obj64 = (object)val33; } Section obj65 = obj63.Toggle(func15, (UnityAction)obj64); Func<string> func16 = StationPage.CollectTile; object obj66 = <>O.<110>__ArmCollect; if (obj66 == null) { UnityAction val34 = StationPage.ArmCollect; <>O.<110>__ArmCollect = val34; obj66 = (object)val34; } Section obj67 = obj65.Toggle(func16, (UnityAction)obj66); Func<string> func17 = StationPage.HighlightCaption; object obj68 = <>O.<112>__ToggleHighlight; if (obj68 == null) { UnityAction val35 = StationPage.ToggleHighlight; <>O.<112>__ToggleHighlight = val35; obj68 = (object)val35; } Section obj69 = obj67.Toggle(func17, (UnityAction)obj68).Block("Как", (Func<string>)StationPage.About).Heading("Настройки"); Func<string> func18 = StationPage.FillMeans; Func<string> func19 = StationPage.FillCaption; object obj70 = <>O.<116>__ToggleFill; if (obj70 == null) { UnityAction val36 = StationPage.ToggleFill; <>O.<116>__ToggleFill = val36; obj70 = (object)val36; } Section obj71 = obj69.Setting("Наполнение", func18, func19, (UnityAction)obj70); Func<string> func20 = StationPage.CollectMeans; Func<string> func21 = StationPage.CollectCaption; object obj72 = <>O.<119>__ToggleCollect; if (obj72 == null) { UnityAction val37 = StationPage.ToggleCollect; <>O.<119>__ToggleCollect = val37; obj72 = (object)val37; } Section obj73 = obj71.Setting("Сбор", func20, func21, (UnityAction)obj72).Value("Зона станций", (Func<string>)StationPage.ReachSays, "от 8 до 64 м", "Задать", (Action<string>)StationPage.SetReach, "0123456789", 2); Func<string> func22 = StationPage.ShapeMeans; Func<string> func23 = StationPage.ShapeCaption; object obj74 = <>O.<124>__ToggleShape; if (obj74 == null) { UnityAction val38 = StationPage.ToggleShape; <>O.<124>__ToggleShape = val38; obj74 = (object)val38; } obj73.Setting("Форма зоны", func22, func23, (UnityAction)obj74).Value("Угля на складе", (Func<string>)StationPage.CoalSays, "0 — без предела", "Задать", (Action<string>)StationPage.SetCoal, "0123456789", 6).Heading("Последний проход") .Block("У сундуков", (Func<string>)StationChests.AtChests) .Block("Уголь", (Func<string>)StationChests.Coal) .Block("Нечем наполнить", (Func<string>)StationChests.Lacks) .Block("Некуда класть", (Func<string>)StationChests.NoRoom) .Block("Ульи", (Func<string>)StationChests.Hives) .Block("Бочки", (Func<string>)StationChests.Barrels) .Block("Звери", (Func<string>)StationChests.Tames); Traps.Bind(((BaseUnityPlugin)this).Config); Section obj75 = val.Add("Капканы", "TrophyBoar").Live().Strip((Func<string>)TrapPage.Now) .Heading("Капкан"); object obj76 = <>O.<135>__Place; if (obj76 == null) { UnityAction val39 = TrapPage.Place; <>O.<135>__Place = val39; obj76 = (object)val39; } Section obj77 = obj75.Tile("Поставить капкан", (UnityAction)obj76); Func<string> func24 = TrapPage.TrapTile; object obj78 = <>O.<137>__ArmTrap; if (obj78 == null) { UnityAction val40 = TrapPage.ArmTrap; <>O.<137>__ArmTrap = val40; obj78 = (object)val40; } Section obj79 = obj77.Toggle(func24, (UnityAction)obj78).Heading("Пойманный зверь"); Func<string> func25 = TrapPage.ReleaseTile; object obj80 = <>O.<139>__ArmRelease; if (obj80 == null) { UnityAction val41 = TrapPage.ArmRelease; <>O.<139>__ArmRelease = val41; obj80 = (object)val41; } Section obj81 = obj79.Toggle(func25, (UnityAction)obj80); Func<string> func26 = TrapPage.FeedTile; object obj82 = <>O.<141>__ToggleFeed; if (obj82 == null) { UnityAction val42 = TrapPage.ToggleFeed; <>O.<141>__ToggleFeed = val42; obj82 = (object)val42; } obj81.Toggle(func26, (UnityAction)obj82).Block("Капканы рядом", (Func<string>)TrapPage.Near).Block("Кто что ест", (Func<string>)TrapPage.Diets) .Block("Как работает", (Func<string>)TrapPage.About); Section obj83 = val.Add("Рельеф", "Hoe").Input("Радиус, м", "8, если пусто", "0123456789", 2, ref Levelling.Radius).Input("Высота над водой, м", "где стоишь, если пусто", "0123456789-.,", 6, ref Levelling.Height); object obj84 = <>O.<145>__Circle; if (obj84 == null) { UnityAction val43 = Levelling.Circle; <>O.<145>__Circle = val43; obj84 = (object)val43; } Section obj85 = obj83.Tile("Выровнять круг", (UnityAction)obj84); object obj86 = <>O.<146>__Square; if (obj86 == null) { UnityAction val44 = Levelling.Square; <>O.<146>__Square = val44; obj86 = (object)val44; } Section obj87 = obj85.Tile("Выровнять квадрат", (UnityAction)obj86).Block("Как это", (Func<string>)Levelling.About); object obj88 = <>O.<148>__TakeBack; if (obj88 == null) { UnityAction val45 = Levelling.TakeBack; <>O.<148>__TakeBack = val45; obj88 = (object)val45; } obj87.Action("Откатить", (UnityAction)obj88); LongRoads.Ended += Roads.RememberEnd; LongRoads.Undone += Roads.ForgetEnd; RoadSettings.Changed += Roads.Redraw; Section obj89 = val.Add("Дорожки", "stone_floor_2x2").Live().Strip((Func<string>)Roads.Now) .Heading("Проложить"); object obj90 = <>O.<153>__Start; if (obj90 == null) { UnityAction val46 = Roads.Start; <>O.<153>__Start = val46; obj90 = (object)val46; } Section obj91 = obj89.Tile("Начать дорожку", (UnityAction)obj90); object obj92 = <>O.<154>__Continue; if (obj92 == null) { UnityAction val47 = Roads.Continue; <>O.<154>__Continue = val47; obj92 = (object)val47; } Section obj93 = obj91.Tile("Продолжить от конца", (UnityAction)obj92).Field("Радиус мощения, м", "8, если пусто", "Замостить круг", (Action<string>)Roads.Pave, "0123456789", 2, ref Roads.PavingRadius); RoadSettings.AddTo(obj93, (Action<Section>)delegate(Section own) { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Expected O, but got Unknown Section obj98 = own.Input("Изгиб", "0 — прямо, 10 — полукругом", "0123456789,.", 4, ref Roads.Bend); Func<string> func28 = Roads.SideCaption; object obj99 = <>O.<157>__ToggleSide; if (obj99 == null) { UnityAction val50 = Roads.ToggleSide; <>O.<157>__ToggleSide = val50; obj99 = (object)val50; } obj98.Toggle(func28, (UnityAction)obj99); }, false); Section obj94 = obj93.Block("Как это", (Func<string>)Roads.About); object obj95 = <>O.<159>__TakeBack; if (obj95 == null) { UnityAction val48 = Roads.TakeBack; <>O.<159>__TakeBack = val48; obj95 = (object)val48; } obj94.Action("Откатить", (UnityAction)obj95); MapMarks.Bind(((BaseUnityPlugin)this).Config); Section obj96 = val.Add("Функции", "Torch").Heading("Починить").Field("Радиус, м", "20, если пусто", "Починить", (Action<string>)Repair.Run, "0123456789", 3, (Func<string>)null) .Block("Что делает", (Func<string>)Repair.About) .Heading("Карта"); Func<string> func27 = MapMarks.Caption; object obj97 = <>O.<163>__Toggle; if (obj97 == null) { UnityAction val49 = MapMarks.Toggle; <>O.<163>__Toggle = val49; obj97 = (object)val49; } obj96.Toggle(func27, (UnityAction)obj97).Block("Что отмечается", (Func<string>)MapMarks.About); Corner.Add((Func<string>)Builder.CornerSays); _harmony = new Harmony("astvard.player"); _harmony.PatchAll(); Log.LogInfo((object)"Player tab registered."); } private static string Both(string first, string second) { if (string.IsNullOrEmpty(first)) { return second ?? ""; } if (!string.IsNullOrEmpty(second)) { return first + "\n" + second; } return first; } private void Update() { Runes.Tick(); CharacterStats.Tick(); ZoneBook.Tick(); ShelfNews.Tick(); SortPass.Tick(); StationChests.Tick(); ChestLabels.Tick(); ZoneHighlight.Tick(); StationHighlight.Tick(); Traps.Tick(); MapMarks.Tick(); Favorites.Tick(); } private void FixedUpdate() { Traps.Hold(); } private void LateUpdate() { ChestLabels.Face(); TrapRope.Draw(); } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } } internal static class Runes { private const float AskEvery = 10f; private static ZRoutedRpc _listening; private static ZNet _heardOn; private static float _askedAt = float.MinValue; private static int _balance; private static float _nextAt; private static bool _away; private static int _played; private static float _playedAt; private static ZNet _playedOn; private static bool Heard { get { if ((Object)(object)_heardOn != (Object)null) { return _heardOn == ZNet.instance; } return false; } } private static bool PlayedHeard { get { if ((Object)(object)_playedOn != (Object)null) { return _playedOn == ZNet.instance; } return false; } } internal static void Tick() { ZRoutedRpc instance = ZRoutedRpc.instance; ZNet instance2 = ZNet.instance; if (instance != null && !((Object)(object)instance2 == (Object)null) && !instance2.IsServer()) { if (_listening != instance) { instance.Register<int, int, bool, bool>("Astvard_Runes", (Method<int, int, bool, bool>)OnRunes); instance.Register<int>("Astvard_Played", (Action<long, int>)OnPlayed); instance.Register<ZPackage>("Astvard_RunesGranted", (Action<long, ZPackage>)OnGranted); _listening = instance; _askedAt = float.MinValue; } if (!Heard && !((Object)(object)Player.m_localPlayer == (Object)null) && !(Time.time - _askedAt < 10f)) { _askedAt = Time.time; instance.InvokeRoutedRPC("Astvard_AskRunes", Array.Empty<object>()); } } } private static void OnRunes(long sender, int balance, int toNext, bool earned, bool away) { bool num = !Heard || balance != _balance || away != _away; _heardOn = ZNet.instance; _balance = Mathf.Max(0, balance); _nextAt = Time.realtimeSinceStartup + (float)Mathf.Max(0, toNext); _away = away; if (earned) { Player localPlayer = Player.m_localPlayer; if (localPlayer != null) { ((Character)localPlayer).Message((MessageType)1, "+1 руна за " + Rate(Limits.RuneMinutes.Value) + " в мире. Всего: " + _balance, 0, (Sprite)null, false); } } if (num) { MenuTabs.Refresh(); } } private static void OnGranted(long sender, ZPackage pkg) { int num = default(int); int num2 = default(int); if (RuneLedger.UnpackGranted(pkg, ref num, ref num2) && num != 0) { Player localPlayer = Player.m_localPlayer; if (localPlayer != null) { ((Character)localPlayer).Message((MessageType)1, (num > 0) ? ("Админ выдал тебе " + Words.Runes(num) + ". Всего: " + num2) : ("Админ забрал у тебя " + Words.Runes(-num) + ". Осталось: " + num2), 0, (Sprite)null, false); } } } private static void OnPlayed(long sender, int seconds) { _played = Mathf.Max(0, seconds); _playedAt = Time.realtimeSinceStartup; _playedOn = ZNet.instance; } internal static string About() { if (!Heard) { return "Сервер про руны не сказал: на нём нет Astvard.Server, или это одиночная игра."; } int value = Limits.RuneIdle.Value; int num = Mathf.CeilToInt((_nextAt - Time.realtimeSinceStartup) / 60f); string text = "У тебя " + _balance + " " + Words.Plural(_balance, "руна", "руны", "рун"); string text2 = (_away ? (text + ". Сейчас они стоят: ты " + value + " мин ничего не делал. Двинься или займись делом — счёт пойдёт снова.") : (text + ((num > 0) ? (" — следующая примерно через " + num + " мин игры.") : " — следующая вот-вот."))); return text2 + (PlayedHeard ? ("\nНаиграно здесь: " + Duration(Played()) + ".") : "") + "\nРуна — за " + Each(Limits.RuneMinutes.Value) + " в мире, остаток не пропадает." + ((value > 0) ? (" " + value + " мин без дела — рун нет, пока не займёшься делом.") : ""); } private static double Played() { return (double)_played + (_away ? 0.0 : ((double)(Time.realtimeSinceStartup - _playedAt))); } private static string Duration(double seconds) { long num = (long)(seconds / 60.0); if (num < 1) { return "меньше минуты"; } if (num < 60) { return num + " мин"; } long num2 = num % 60; return num / 60 + " ч" + ((num2 > 0) ? (" " + num2 + " мин") : ""); } private static string Rate(int minutes) { if (minutes == 60) { return "час"; } if (minutes % 60 == 0) { return minutes / 60 + " ч"; } return minutes + " мин"; } private static string Each(int minutes) { return minutes switch { 60 => "каждый час", 1 => "каждую минуту", _ => "каждые " + Rate(minutes), }; } } } namespace Astvard.Players.Terrain { internal static class GroundUndo { internal sealed class Step { internal readonly string Label; internal readonly Vector3 Centre; internal readonly float Reach; internal readonly ZNet World = ZNet.instance; internal readonly List<Vector2s> Zones = new List<Vector2s>(); internal readonly List<Before> Befores = new List<Before>(); internal readonly List<Before> Paints = new List<Before>(); internal readonly List<ZDOID> Pieces = new List<ZDOID>(); internal string PiecesPrefab; internal bool PiecesPaid; internal Receipt PiecesReceipt; internal Action Undone; internal Step(string label, Vector3 centre, float reach) { //IL_0045: 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) Label = label; Centre = centre; Reach = reach; } internal void Add(Vector2s zone, Before before) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) Add(zone, before, null); } internal void Add(Vector2s zone, Before heights, Before paint) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) Zones.Add(zone); Befores.Add((Before)(((object)heights) ?? ((object)new Before()))); Paints.Add((paint != null && paint.Count > 0) ? paint : null); } } private const int Depth = 5; private static readonly List<Step> Steps = new List<Step>(); internal static void Push(Step step) { if (step.Zones.Count != 0) { Steps.Add(step); while (Steps.Count > 5) { Steps.RemoveAt(0); } } } internal static void TakeBack() { Steps.RemoveAll((Step step2) => step2.World != ZNet.instance); if (Steps.Count == 0) { Notice.Say("Откатывать нечего"); return; } Step step = Steps[Steps.Count - 1]; Notice.Say(Restore(step, out var said) ?? ("Откат: " + step.Label + said)); } internal static string TakeBack(Step step) { Steps.RemoveAll((Step each) => each.World != ZNet.instance); if (Steps.Count == 0 || Steps[Steps.Count - 1] != step) { return "Землю после неё уже меняли — откати её в «Рельефе»"; } string said; return Restore(step, out said); } private static string Restore(Step step, out string said) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Unknown result type (might be due to invalid IL or missing references) said = ""; if (!Ground.Ready) { return "Откат не сработает с этой версией игры — подробности в логе"; } List<TerrainComp> list = new List<TerrainComp>(step.Zones.Count); foreach (Vector2s zone in step.Zones) { Vector3 zonePos = ZoneSystem.GetZonePos(zone); TerrainComp val = TerrainComp.FindTerrainCompiler(zonePos); if ((Object)(object)val == (Object)null) { return ((Object)(object)Heightmap.FindHeightmap(zonePos) == (Object)null) ? ("Подойди ближе к тому месту: " + step.Label + " — в " + Mathf.RoundToInt(Away(step)) + " м") : "Земля там ещё прогружается — нажми через пару секунд"; } list.Add(val); } for (int i = 0; i < list.Count; i++) { if (step.Befores[i].Count > 0) { Ground.Restore(list[i], step.Befores[i], step.Centre, step.Reach); } else { Ground.Claim(list[i]); Ground.Note(list[i], step.Centre, step.Reach); } if (step.Paints[i] != null) { RoadPaint.Restore(list[i], step.Paints[i]); } } foreach (TerrainComp item in list) { Ground.Save(item); } Ground.Refresh(step.Centre, step.Reach); said = TakeDown(step); Steps.Remove(step); step.Undone?.Invoke(); Plugin.Log.LogInfo((object)("Took back " + step.Label + " at " + ((object)step.Centre/*cast due to .constrained prefix*/).ToString() + " in " + list.Count + " zones" + ((step.Pieces.Count > 0) ? (", " + step.Pieces.Count + " pieces with it") : "") + "; " + Steps.Count + " steps left.")); return null; } private static string TakeDown(Step step) { //IL_0033: 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_003f: Unknown result type (might be due to invalid IL or missing references) if (step.Pieces.Count == 0 || (Object)(object)ZNetScene.instance == (Object)null) { return ""; } int num = 0; foreach (ZDOID piece in step.Pieces) { GameObject val = ZNetScene.instance.FindInstance(piece); ZNetView val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<ZNetView>() : null); if (!((Object)(object)val2 == (Object)null) && val2.IsValid()) { val2.ClaimOwnership(); ZNetScene.instance.Destroy(val); num++; } } string text = ", факелов убрано: " + num; Player localPlayer = Player.m_localPlayer; if (!step.PiecesPaid || num == 0 || (Object)(object)localPlayer == (Object)null) { return text; } Bill bill = new Bill(); bill.Add(step.PiecesPrefab, num); bill.Refund(localPlayer, step.PiecesReceipt, out var toChests, out var toFeet); return text + ((toChests && toFeet) ? ", материалы — в сундуки и под ноги" : (toChests ? ", материалы — в сундуки" : (toFeet ? ", материалы под ногами" : ""))); } private static float Away(Step step) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0021: 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_0045: 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) Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return 0f; } Vector3 position = ((Component)localPlayer).transform.position; Vector2 val = new Vector2(position.x - step.Centre.x, position.z - step.Centre.z); return ((Vector2)(ref val)).magnitude; } } internal static class Levelling { internal const string Digits = "0123456789"; internal const string HeightCharacters = "0123456789-.,"; private const float DefaultRadius = 8f; internal const float MaxRadius = 64f; private const float WardCell = 4f; internal const string Closed = "Ровнять землю игрокам нельзя — так решил админ"; internal static Entry Radius; internal static Entry Height; private static Projection _hand; private static PadMarks _marks; private static bool _square; private static float _toldLift; private static string _toldHeight; private static int _standMask; internal static bool Allowed { get { if (!Access.IsAdmin) { return Rules.PlayersLevel; } return true; } } private static float Sea { get { if (!((Object)(object)ZoneSystem.instance != (Object)null)) { return 30f; } return ZoneSystem.instance.m_waterLevel; } } internal static string About() { if (!Allowed) { return "Ровнять землю игрокам нельзя — так решил админ. «Откатить» возвращает своё и так."; } int value = Limits.PriceLevel.Value; return "Площадка встаёт в руки: земля под ней ляжет ровно на высоту поля — или на высоту, где стоишь, если оно пусто, — а вокруг сойдёт склоном.\nЛКМ — выровнять, Shift+ЛКМ — и оставить в руках, Esc — убрать, P — закрепить, стрелки — сдвинуть, Q и E — повернуть квадрат, Shift+Q и Shift+E — выше и ниже.\nИгра даёт сдвинуть землю не дальше " + 8 + " м от той, что дал мир: где не дотянется, край площадки в руках красный." + ((!Access.IsAdmin) ? ("\nРадиус игрокам — до " + Limits.Level.Value + " м") : "") + ((value > 0 && !Access.IsAdmin) ? (", цена — " + Limits.PriceLevel.Say(value)) : ""); } internal static void Circle() { Hold(square: false); } internal static void Square() { Hold(square: true); } internal static void TakeBack() { GroundUndo.TakeBack(); } private static void Hold(bool square) { if ((Object)(object)Player.m_localPlayer == (Object)null) { return; } if (!Allowed) { Notice.Say("Ровнять землю игрокам нельзя — так решил админ"); return; } if (!Ground.Ready) { Notice.Say("Выравнивание не сработает с этой версией игры — подробности в логе"); return; } _square = square; if (_hand == null || Projection.Current != _hand) { Projection val = Projection.Start(square ? "выравнивание квадратом" : "выравнивание кругом", 11f); PadMarks padMarks = PadMarks.On(val.Root); if (padMarks == null) { val.Drop(); Notice.Say("Проекцию нечем нарисовать — подробности в логе"); return; } _hand = val; _marks = padMarks; _toldLift = val.Lift; Entry height = Height; _toldHeight = ((height != null) ? height.Text : null); val.Place = Place; val.Redraw = Redraw; } _hand.NoTurning = (square ? null : "Круг вращать незачем"); _marks.Invalidate(); int value = Limits.PriceLevel.Value; Notice.Say((square ? "Выравнивание квадратом" : "Выравнивание кругом") + "\nЛКМ — выровнять, Esc — отмена, P — закрепить" + (square ? ", Q/E — поворот" : "") + "\nShift+Q/E — выше и ниже" + ((value > 0 && !Access.IsAdmin) ? ("\nЦена: " + Limits.PriceLevel.Say(value)) : "")); } private static void Redraw(Projection hand) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_003f: 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) Entry radius = Radius; float num = RadiusOf((radius != null) ? radius.Text : null); Entry height = Height; if (!TryHeight((height != null) ? height.Text : null, out var metres)) { metres = 0f; } Vector3 centre = CentreOf(hand); float num2 = TargetOf(hand, centre, metres); bool flag = _marks.Draw(centre, num2, num, Pad.BlendFor(num), _square, YawOf(hand)); if (hand.Lift == _toldLift) { Entry height2 = Height; if (!(((height2 != null) ? height2.Text : null) != _toldHeight)) { return; } } _toldLift = hand.Lift; Entry height3 = Height; _toldHeight = ((height3 != null) ? height3.Text : null); Notice.Say("Высота площадки: " + AboveWater(num2) + (flag ? "\nМестами земля дальше 8 м от неё — ровно не выйдет" : "")); } private static void Place(Projection hand, bool keep) { //IL_0080: 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_0097: Unknown result type (might be due to invalid IL or missing references) if (!Allowed) { Notice.Say("Ровнять землю игрокам нельзя — так решил админ"); return; } if (Charges.Waiting) { Notice.Say("Жду, что скажет сервер про руны"); return; } Entry height = Height; if (!TryHeight((height != null) ? height.Text : null, out var metres)) { Notice.Say("Высота — метры над водой, например 5\nПусто — где стоишь"); return; } Entry radius = Radius; float radius2 = RadiusOf((radius != null) ? radius.Text : null); Vector3 centre = CentreOf(hand); centre.y = TargetOf(hand, centre, metres); bool square = _square; float yaw = YawOf(hand); string label = (square ? "площадка квадратом" : "площадка кругом"); Charges.Pay(new Charge(label).Add(Limits.PriceLevel, 1), delegate(int receipt) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) if (Projection.Current != hand || !Level(centre, radius2, square, yaw, "выравнивание", quiet: false, out var _)) { Charges.Refund(receipt, label); } else if (keep) { _marks?.Invalidate(); } else { hand.Finish(); _hand = null; _marks = null; } }); } internal unsafe static bool Level(Vector3 target, float radius, bool square, float yaw, string label, bool quiet, out GroundUndo.Step step) { //IL_0040: 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_0071: 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_0098: Expected O, but got Unknown //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0292: 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_01a2: Unknown result type (might be due to invalid IL or missing references) step = null; if (!Ground.Ready) { Notice.Say("Выравнивание не сработает с этой версией игры — подробности в логе"); return false; } float num = Pad.BlendFor(radius); float num2 = radius + num; if (!Access.IsAdmin && !WardsAllow(target, num2, square, yaw)) { Notice.Say("Выравнивание задевает чужой оберег — уменьши радиус или отойди"); return false; } bool flag = default(bool); List<TerrainComp> list = Ground.Compilers(target, num2, square, yaw, ref flag); if (list == null) { Notice.Say(flag ? "Выравнивание выходит за прогруженную землю — уменьши радиус или подойди ближе" : "Земля там ещё прогружается — подожди пару секунд и нажми снова"); return false; } float num3 = Pad.Extent(num2, square, yaw); GroundUndo.Step step2 = new GroundUndo.Step(label, target, num3); int num4 = 0; foreach (TerrainComp item in list) { Before val = new Before(); num4 += Ground.Level(item, target, radius, num, square, yaw, val); if (val.Count > 0) { step2.Add(Ground.ZoneOf(item), val); } } foreach (TerrainComp item2 in list) { Ground.Save(item2); } Ground.Refresh(target, num3); GroundUndo.Push(step2); if (step2.Zones.Count > 0) { step = step2; } int num5 = Mathf.RoundToInt(radius); if (!quiet) { Notice.Say((square ? ("Выровнено квадратом " + num5 * 2 + "×" + num5 * 2 + " м") : ("Выровнено кругом радиусом " + num5 + " м")) + ", на " + AboveWater(target.y) + ((num4 > 0) ? "\nЗемля двигается не дальше 8 м — местами не дотянулась" : "")); } ManualLogSource log = Plugin.Log; string[] obj = new string[16] { "Levelled ", label, ", a ", square ? ("square turned " + Mathf.RoundToInt(yaw) + "°") : "circle", ": r=", radius.ToString(), ", slope ", num.ToString("0.#", CultureInfo.InvariantCulture), " m, y=", target.y.ToString("0.##", CultureInfo.InvariantCulture), ", ", step2.Zones.Count.ToString(), " zones at ", null, null, null
BepInEx/plugins/Astvard.Server.dll
Decompiled 2 weeks ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using Astvard.Core; using Astvard.Core.Builds; using Astvard.Core.Net; using Astvard.Core.Placement; using Astvard.Core.Sorting; using Astvard.Core.Terrain; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using Splatform; using Steamworks; using UnityEngine; using UnityEngine.Networking; [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("Astvard.Server")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+d8721dbc184a53c5b52947c0c2c8980b874b1ebb")] [assembly: AssemblyProduct("Astvard.Server")] [assembly: AssemblyTitle("Astvard.Server")] [assembly: AssemblyVersion("1.0.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 Astvard.Server { internal sealed class AccessLists { [Serializable] private sealed class Answer { public int format; public string[] permitted; public string[] admins; } private const int Format = 1; private static readonly UTF8Encoding NoMark = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false); private readonly ConfigEntry<string> _url; private readonly ConfigEntry<string> _token; private readonly ConfigEntry<int> _seconds; private string _etag; private string _trouble; private float Interval => Mathf.Clamp(_seconds.Value, 5, 600); private static string Folder => Utils.GetSaveDataPath((FileSource)2); internal AccessLists(ConfigEntry<string> url, ConfigEntry<string> token, ConfigEntry<int> seconds) { _url = url; _token = token; _seconds = seconds; } internal IEnumerator Run() { WaitForSecondsRealtime second = new WaitForSecondsRealtime(1f); while ((Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer()) { yield return second; } Plugin.Log.LogInfo((object)("Access lists: from " + _url.Value + " every " + Interval + " s, into " + Folder + ".")); while (true) { if ((Object)(object)ZNet.instance != (Object)null) { yield return Fetch(); } yield return (object)new WaitForSecondsRealtime(Interval); } } private IEnumerator Fetch() { string text = (_token.Value ?? "").Trim(); if (text.Length == 0) { Trouble("no token: [Сайт] Токен in astvard.server.cfg is empty, so the lists are left as they are."); yield break; } UnityWebRequest request = UnityWebRequest.Get(_url.Value); try { request.timeout = 10; request.SetRequestHeader("Authorization", "Bearer " + text); if (_etag != null) { request.SetRequestHeader("If-None-Match", _etag); } yield return request.SendWebRequest(); if ((int)request.result == 2) { Trouble("the site would not answer (" + request.error + "); the lists are left as they are."); yield break; } long responseCode = request.responseCode; switch (responseCode) { case 304L: Settled(); yield break; case 401L: Trouble("the site turned the token down (401): [Сайт] Токен is not the site's GAME_TOKEN."); yield break; case 404L: Trouble("404: the address is wrong, or the site has no GAME_TOKEN of its own and so no route."); yield break; default: Trouble("the site answered " + responseCode + "; the lists are left as they are."); yield break; case 200L: { Answer answer; try { answer = JsonUtility.FromJson<Answer>(request.downloadHandler.text); } catch (Exception ex) { Trouble("the site's answer is not JSON: " + ex.Message); yield break; } if (answer == null || answer.format != 1 || answer.permitted == null || answer.admins == null) { Trouble("the site's answer has a form this mod does not know (format " + ((answer != null) ? answer.format.ToString() : "none") + ", this mod knows " + 1 + ")."); yield break; } if (Apply(answer)) { _etag = request.GetResponseHeader("ETag"); } break; } } } finally { ((IDisposable)request)?.Dispose(); } } private bool Apply(Answer answer) { int kept; int skipped; string text = AccessText.Permitted(answer.permitted, out kept, out skipped); int kept2; int skipped2; string text2 = AccessText.Admins(answer.admins, out kept2, out skipped2); bool flag; bool flag2; try { flag = Write("permittedlist.txt", text); flag2 = Write("adminlist.txt", text2); } catch (Exception ex) { Trouble("could not write the lists into " + Folder + ": " + ex.Message); return false; } Settled(); if (skipped + skipped2 > 0) { Plugin.Log.LogWarning((object)("Access lists: " + (skipped + skipped2) + " ids from the site are not SteamID64s and were left out.")); } if (!flag && !flag2) { return true; } Plugin.Log.LogInfo((object)("Access lists: the site lets in " + ((kept == 0) ? "nobody" : kept.ToString()) + " and makes " + kept2 + " admin" + ((kept2 == 1) ? "" : "s") + " — wrote " + (flag ? "permittedlist.txt" : "") + ((flag && flag2) ? " and " : "") + (flag2 ? "adminlist.txt" : "") + "." + ((kept == 0) ? " The server is closed to everyone: a list with no ids would open it." : ""))); return true; } private static bool Write(string name, string text) { string text2 = Folder + "/" + name; if (File.Exists(text2) && File.ReadAllText(text2) == text) { return false; } string text3 = text2 + ".astvard-new"; File.WriteAllText(text3, text, NoMark); if (File.Exists(text2)) { File.Replace(text3, text2, text2 + ".bak"); } else { File.Move(text3, text2); } File.SetLastWriteTimeUtc(text2, DateTime.UtcNow); return true; } private void Trouble(string what) { if (!(what == _trouble)) { _trouble = what; Plugin.Log.LogWarning((object)("Access lists: " + what)); } } private void Settled() { if (_trouble != null) { _trouble = null; Plugin.Log.LogInfo((object)"Access lists: the site answers again."); } } } internal static class AccessText { internal const string Nobody = "76561197960265728"; private const ulong First = 76561197960265728uL; private const ulong Last = 76561202255233023uL; private const string Header = "// Этот файл пишет Astvard.Server по списку с сайта. Правка руками пропадёт,\n// как только он перепишет файл: при старте сервера или когда список на сайте изменится.\n"; internal static bool IsSteamId(string id) { if (id == null || id.Length != 17) { return false; } foreach (char c in id) { if (c < '0' || c > '9') { return false; } } if (ulong.TryParse(id, NumberStyles.None, CultureInfo.InvariantCulture, out var result) && result > 76561197960265728L) { return result <= 76561202255233023L; } return false; } internal static string Permitted(IEnumerable<string> ids, out int kept, out int skipped) { StringBuilder stringBuilder = new StringBuilder("// Этот файл пишет Astvard.Server по списку с сайта. Правка руками пропадёт,\n// как только он перепишет файл: при старте сервера или когда список на сайте изменится.\n"); kept = Lines(stringBuilder, ids, out skipped, "V_"); if (kept == 0) { stringBuilder.Append("// На сайте не пущен никто. Файл без номеров игра читает как «пускать всех»,\n"); stringBuilder.Append("// поэтому здесь номер, которого нет ни у кого: аккаунт 0.\n"); stringBuilder.Append("V_").Append("76561197960265728").Append('\n'); } return stringBuilder.ToString(); } internal static string Admins(IEnumerable<string> ids, out int kept, out int skipped) { StringBuilder stringBuilder = new StringBuilder("// Этот файл пишет Astvard.Server по списку с сайта. Правка руками пропадёт,\n// как только он перепишет файл: при старте сервера или когда список на сайте изменится.\n"); kept = Lines(stringBuilder, ids, out skipped, "V_", "Steam_"); if (kept == 0) { stringBuilder.Append("// Админов в игре на сайте нет.\n"); } return stringBuilder.ToString(); } private static int Lines(StringBuilder text, IEnumerable<string> ids, out int skipped, params string[] prefixes) { HashSet<string> hashSet = new HashSet<string>(); int num = 0; skipped = 0; if (ids == null) { return 0; } foreach (string id in ids) { if (!IsSteamId(id)) { skipped++; } else if (hashSet.Add(id)) { num++; foreach (string value in prefixes) { text.Append(value).Append(id).Append('\n'); } } } return num; } } internal sealed class BuildPause { private readonly PlayerRules _rules; private readonly Dictionary<string, float> _lastBuild = new Dictionary<string, float>(); private ZRoutedRpc _listening; internal BuildPause(PlayerRules rules) { _rules = rules; } internal void Tick() { ZRoutedRpc instance = ZRoutedRpc.instance; if (instance != null && instance != _listening) { _listening = instance; instance.Register<int>("Astvard_AskBuild", (Action<long, int>)OnAsk); } } private void OnAsk(long sender, int ask) { string who; bool flag = Senders.FromAdmin(out who); string text = Senders.SenderHost(); float num = (float)_rules.LimitOf(Limits.BuildPause) * 60f; float realtimeSinceStartup = Time.realtimeSinceStartup; int num2 = 0; if (!flag && num > 0f && !string.IsNullOrEmpty(text) && _lastBuild.TryGetValue(text, out var value)) { num2 = Mathf.Max(0, Mathf.CeilToInt(value + num - realtimeSinceStartup)); } bool flag2 = num2 == 0; if (flag2 && !flag && !string.IsNullOrEmpty(text)) { _lastBuild[text] = realtimeSinceStartup; } ZRoutedRpc.instance.InvokeRoutedRPC(sender, "Astvard_BuildAnswer", new object[3] { ask, flag2, num2 }); Plugin.Log.LogInfo((object)("Build asked by " + who + (flag ? " (admin)" : "") + ": " + (flag2 ? "yes" : ("no, " + num2 + " s of the pause left")) + ".")); } } internal static class Causeway { internal struct Stretch { internal int First; internal int Last; } private const float Least = 0.05f; internal static float[] Raise(IList<float> ground, float step, float floor) { int count = ground.Count; float[] array = new float[count]; bool flag = false; for (int i = 0; i < count; i++) { array[i] = float.MinValue; if (!(ground[i] >= floor)) { array[i] = floor; flag = true; } } if (!flag) { return null; } if (step > 0f) { float num = 0.35f * step; for (int j = 1; j < count; j++) { if (array[j - 1] > float.MinValue) { array[j] = Math.Max(array[j], array[j - 1] - num); } } for (int num2 = count - 2; num2 >= 0; num2--) { if (array[num2 + 1] > float.MinValue) { array[num2] = Math.Max(array[num2], array[num2 + 1] - num); } } } float[] array2 = new float[count]; for (int k = 0; k < count; k++) { array2[k] = Math.Max(ground[k], array[k]); } return array2; } internal static List<Stretch> Spans(IList<float> ground, IList<float> raised) { List<Stretch> list = new List<Stretch>(); int num = Math.Min(ground.Count, raised.Count); int i = 0; while (i < num) { if (raised[i] - ground[i] < 0.05f) { i++; continue; } int num2 = i; for (; i + 1 < num && raised[i + 1] - ground[i + 1] >= 0.05f; i++) { } int num3 = i; i++; num2 = Math.Max(0, num2 - 1); num3 = Math.Min(num - 1, num3 + 1); if (list.Count > 0 && num2 <= list[list.Count - 1].Last + 1) { Stretch value = list[list.Count - 1]; value.Last = num3; list[list.Count - 1] = value; } else { list.Add(new Stretch { First = num2, Last = num3 }); } } return list; } } internal sealed class Charges { private sealed class Paid { internal string Name; internal string Label; internal int Cost; internal float At; } private const float KeepFor = 600f; private readonly PlayerRules _rules; private readonly Runes _runes; private readonly Dictionary<string, Paid> _paid = new Dictionary<string, Paid>(); private ZRoutedRpc _listening; internal Charges(PlayerRules rules, Runes runes) { _rules = rules; _runes = runes; } internal void Tick() { ZRoutedRpc instance = ZRoutedRpc.instance; if (instance != null && instance != _listening) { _listening = instance; instance.Register<ZPackage>("Astvard_Pay", (Action<long, ZPackage>)OnPay); instance.Register<int>("Astvard_Refund", (Action<long, int>)OnRefund); } } private void OnPay(long sender, ZPackage pkg) { long num = Senders.SenderPeer(); string text = Senders.SenderHost(); int num2 = default(int); string text2 = default(string); List<KeyValuePair<string, int>> items = default(List<KeyValuePair<string, int>>); if (num != 0L && !string.IsNullOrEmpty(text) && Payments.UnpackPay(pkg, ref num2, ref text2, ref items)) { string text3 = Senders.SenderName(); int num3 = CostOf(items); int balance; if (num3 == 0) { ZRoutedRpc.instance.InvokeRoutedRPC(num, "Astvard_PayAnswer", new object[4] { num2, true, 0, _runes.BalanceOf(text, text3) }); } else if (!_runes.Spend(num, text, text3, num3, out balance)) { ZRoutedRpc.instance.InvokeRoutedRPC(num, "Astvard_PayAnswer", new object[4] { num2, false, num3, balance }); Plugin.Log.LogInfo((object)("Runes: «" + text3 + "» (" + text + ") has " + balance + ", «" + text2 + "» costs " + num3 + " — refused.")); } else { Forget(); _paid[KeyOf(text, num2)] = new Paid { Name = text3, Label = text2, Cost = num3, At = Time.realtimeSinceStartup }; ZRoutedRpc.instance.InvokeRoutedRPC(num, "Astvard_PayAnswer", new object[4] { num2, true, num3, balance }); Plugin.Log.LogInfo((object)("Runes: «" + text3 + "» (" + text + ") paid " + num3 + " for «" + text2 + "», now " + balance + ".")); } } } private void OnRefund(long sender, int ask) { long num = Senders.SenderPeer(); string text = Senders.SenderHost(); if (num == 0L || string.IsNullOrEmpty(text)) { return; } string key = KeyOf(text, ask); if (_paid.TryGetValue(key, out var value)) { _paid.Remove(key); if (!(Time.realtimeSinceStartup - value.At > 600f)) { _runes.Give(num, text, value.Cost); Plugin.Log.LogInfo((object)("Runes: " + value.Cost + " back to «" + value.Name + "» (" + text + ") for «" + value.Label + "»: it did not happen.")); } } } private int CostOf(List<KeyValuePair<string, int>> items) { long num = 0L; foreach (KeyValuePair<string, int> item in items) { if (item.Key.StartsWith("build:", StringComparison.Ordinal)) { num += ServerBuildCost(item.Key.Substring("build:".Length), item.Value); continue; } Limit val = Limits.PriceOf(item.Key); if (val != null) { num += (long)_rules.LimitOf(val) * (long)item.Value; } } return (int)Math.Min(num, 2147483647L); } private long ServerBuildCost(string name, int pieces) { Heading val = SharedFolder.FindByName(SharedBuilds.Folder, name); if (val != null) { int? num = SharedFolder.Price(val); if (num.HasValue) { return num.Value; } pieces = val.Pieces; } return _rules.LimitOf(Limits.PriceBuild) + (long)_rules.LimitOf(Limits.PriceBuild100) * (long)((pieces + 99) / 100); } private void Forget() { float realtimeSinceStartup = Time.realtimeSinceStartup; List<string> list = null; foreach (KeyValuePair<string, Paid> item in _paid) { if (realtimeSinceStartup - item.Value.At > 600f) { (list ?? (list = new List<string>())).Add(item.Key); } } if (list == null) { return; } foreach (string item2 in list) { _paid.Remove(item2); } } private static string KeyOf(string id, int ask) { return id + "/" + ask.ToString(CultureInfo.InvariantCulture); } } internal static class GameWords { internal static Dictionary<string, string> In(string language) { LocalizationSettings val = Resources.Load<LocalizationSettings>("LocalizationSettings"); List<TextAsset> list = (((Object)(object)val != (Object)null) ? val.Localizations : null); if (list == null || list.Count == 0) { return null; } Dictionary<string, string> dictionary = new Dictionary<string, string>(StringComparer.Ordinal); bool flag = false; foreach (TextAsset item in list) { if ((Object)(object)item != (Object)null && Read(item.text, language, dictionary)) { flag = true; } } if (!flag) { return null; } return dictionary; } internal static bool Read(string text, string language, Dictionary<string, string> words) { if (string.IsNullOrEmpty(text)) { return false; } int num = text.IndexOf('\n'); if (num < 0) { return false; } int column = -1; string[] array = text.Substring(0, num).TrimEnd(new char[1] { '\r' }).Split(new char[1] { ',' }); for (int i = 0; i < array.Length; i++) { if (Bare(array[i]) == language) { column = i; break; } } if (column < 0) { return false; } StringBuilder key = new StringBuilder(); StringBuilder english = new StringBuilder(); StringBuilder wanted = new StringBuilder(); int field = 0; bool flag = false; for (int j = num + 1; j <= text.Length; j++) { bool flag2 = j == text.Length; char c = (flag2 ? '\n' : text[j]); if (!flag2 && c == '"') { if (flag && j + 1 < text.Length && text[j + 1] == '"') { Keep('"'); j++; } else { flag = !flag; } } else if (!flag2 && c == ',' && !flag) { field++; } else if (flag2 || (c == '\n' && !flag)) { Row(); } else { Keep(c); } } return true; void Keep(char symbol) { if (field == 0) { key.Append(symbol); } else if (field == 1) { english.Append(symbol); } if (field == column) { wanted.Append(symbol); } } void Row() { string text2 = key.ToString(); if (text2.Length > 0 && !text2.StartsWith("//", StringComparison.Ordinal) && field >= column) { string text3 = wanted.ToString().Trim(); if (text3.Length == 0) { text3 = english.ToString(); } words[text2] = text3; } key.Length = 0; english.Length = 0; wanted.Length = 0; field = 0; } } private static string Bare(string name) { name = name.Trim(); if (name.Length < 2 || name[0] != '"' || name[name.Length - 1] != '"') { return name; } return name.Substring(1, name.Length - 2); } } internal static class Json { internal sealed class Writer { private readonly StringBuilder _json = new StringBuilder(); private readonly Stack<char> _open = new Stack<char>(); private bool _first = true; internal int Length => _json.Length; internal Writer Object(string name = null) { return Open(name, '{', '}'); } internal Writer Array(string name) { return Open(name, '[', ']'); } internal Writer End() { _json.Append(_open.Pop()); _first = false; return this; } internal Writer Field(string name, string value) { Item(name); Quote(_json, value); return this; } internal Writer Field(string name, int value) { Item(name); _json.Append(value.ToString(CultureInfo.InvariantCulture)); return this; } internal Writer Field(string name, long value) { Item(name); _json.Append(value.ToString(CultureInfo.InvariantCulture)); return this; } internal Writer Field(string name, bool value) { Item(name); _json.Append(value ? "true" : "false"); return this; } internal Writer Field(string name, double value) { Item(name); bool flag = !double.IsNaN(value) && !double.IsInfinity(value); _json.Append(flag ? value.ToString("0.###", CultureInfo.InvariantCulture) : "0"); return this; } internal Writer Element(string value) { return Field(null, value); } public override string ToString() { return _json.ToString(); } private Writer Open(string name, char opens, char closes) { Item(name); _json.Append(opens); _open.Push(closes); _first = true; return this; } private void Item(string name) { if (!_first) { _json.Append(','); } _first = false; if (name != null) { Quote(_json, name); _json.Append(':'); } } } private sealed class Reader { private const int Deepest = 32; private readonly string _text; private int _at; internal Reader(string text) { _text = text; } internal object Whole() { object result = Value(0); Space(); if (_at < _text.Length) { throw Wrong("nothing after the value"); } return result; } private object Value(int depth) { Space(); if (_at >= _text.Length) { throw Wrong("a value"); } return _text[_at] switch { '{' => ReadObject(depth + 1), '[' => ReadArray(depth + 1), '"' => ReadString(), 't' => Word("true", true), 'f' => Word("false", false), 'n' => Word("null", null), _ => ReadNumber(), }; } private Dictionary<string, object> ReadObject(int depth) { if (depth > 32) { throw Wrong("no more than " + 32 + " levels"); } Dictionary<string, object> dictionary = new Dictionary<string, object>(); _at++; Space(); if (Take('}')) { return dictionary; } do { Space(); if (_at >= _text.Length || _text[_at] != '"') { throw Wrong("a name in quotes"); } string key = ReadString(); Space(); if (!Take(':')) { throw Wrong("':'"); } dictionary[key] = Value(depth); Space(); } while (Take(',')); if (!Take('}')) { throw Wrong("',' or '}'"); } return dictionary; } private List<object> ReadArray(int depth) { if (depth > 32) { throw Wrong("no more than " + 32 + " levels"); } List<object> list = new List<object>(); _at++; Space(); if (Take(']')) { return list; } do { list.Add(Value(depth)); Space(); } while (Take(',')); if (!Take(']')) { throw Wrong("',' or ']'"); } return list; } private string ReadString() { _at++; StringBuilder stringBuilder = new StringBuilder(); while (true) { if (_at >= _text.Length) { throw Wrong("the end of the string"); } char c = _text[_at++]; if (c == '"') { return stringBuilder.ToString(); } if (c < ' ') { throw Wrong("no control characters in a string"); } if (c != '\\') { stringBuilder.Append(c); continue; } if (_at >= _text.Length) { break; } switch (_text[_at++]) { case '"': stringBuilder.Append('"'); break; case '\\': stringBuilder.Append('\\'); break; case '/': stringBuilder.Append('/'); break; case 'b': stringBuilder.Append('\b'); break; case 'f': stringBuilder.Append('\f'); break; case 'n': stringBuilder.Append('\n'); break; case 'r': stringBuilder.Append('\r'); break; case 't': stringBuilder.Append('\t'); break; case 'u': { if (_at + 4 > _text.Length || !int.TryParse(_text.Substring(_at, 4), NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture, out var result)) { throw Wrong("four hex digits after \\u"); } stringBuilder.Append((char)result); _at += 4; break; } default: _at--; throw Wrong("an escape JSON has"); } } throw Wrong("an escape"); } private object ReadNumber() { int at = _at; while (_at < _text.Length && "-+.0123456789eE".IndexOf(_text[_at]) >= 0) { _at++; } string text = _text.Substring(at, _at - at); if (text.Length == 0) { throw Wrong("a value"); } if (long.TryParse(text, NumberStyles.AllowLeadingSign, CultureInfo.InvariantCulture, out var result)) { return result; } if (double.TryParse(text, NumberStyles.Float, CultureInfo.InvariantCulture, out var result2)) { return result2; } _at = at; throw Wrong("a number"); } private object Word(string word, object value) { if (_at + word.Length > _text.Length || string.CompareOrdinal(_text, _at, word, 0, word.Length) != 0) { throw Wrong("a value"); } _at += word.Length; return value; } private bool Take(char c) { if (_at >= _text.Length || _text[_at] != c) { return false; } _at++; return true; } private void Space() { while (_at < _text.Length && (_text[_at] == ' ' || _text[_at] == '\t' || _text[_at] == '\n' || _text[_at] == '\r')) { _at++; } } private FormatException Wrong(string wanted) { return new FormatException("expected " + wanted + " at character " + _at); } } internal static object Read(string text) { return new Reader(text ?? "").Whole(); } internal static void Quote(StringBuilder json, string text) { json.Append('"'); string text2 = text ?? ""; foreach (char c in text2) { switch (c) { case '"': json.Append("\\\""); continue; case '\\': json.Append("\\\\"); continue; case '\n': json.Append("\\n"); continue; case '\r': json.Append("\\r"); continue; case '\t': json.Append("\\t"); continue; } if (c < ' ') { StringBuilder stringBuilder = json.Append("\\u"); int num = c; stringBuilder.Append(num.ToString("x4", CultureInfo.InvariantCulture)); } else { json.Append(c); } } json.Append('"'); } } internal sealed class NetLights<TKey> { private struct Paving { internal int Piece; internal float Ax; internal float Az; internal float Bx; internal float Bz; internal float Half; } private sealed class Lamp { internal int Piece; internal bool Road; internal float X; internal float Z; internal TKey Key; internal bool Gone; } private const float Cell = 32f; internal const float MostSlack = 1f; private readonly List<Paving> _pavings = new List<Paving>(); private readonly Dictionary<long, List<int>> _pavingCells = new Dictionary<long, List<int>>(); private readonly List<Lamp> _lamps = new List<Lamp>(); private readonly Dictionary<long, List<int>> _lampCells = new Dictionary<long, List<int>>(); internal int Standing { get; private set; } internal void AddRoad(int piece, IList<float> xs, IList<float> zs, float half) { int num = Math.Min(xs.Count, zs.Count); switch (num) { case 0: return; case 1: AddDisc(piece, xs[0], zs[0], half); return; } for (int i = 0; i + 1 < num; i++) { AddPaving(piece, xs[i], zs[i], xs[i + 1], zs[i + 1], half); } } internal void AddDisc(int piece, float x, float z, float radius) { AddPaving(piece, x, z, x, z, radius); } internal void AddLamp(int piece, bool road, float x, float z, TKey key) { int count = _lamps.Count; _lamps.Add(new Lamp { Piece = piece, Road = road, X = x, Z = z, Key = key }); Into(_lampCells, KeyOf(CellOf(x), CellOf(z)), count); Standing++; } internal bool OnPaving(int piece, float x, float z, float slack) { slack = Math.Max(0f, Math.Min(slack, 1f)); if (!_pavingCells.TryGetValue(KeyOf(CellOf(x), CellOf(z)), out var value)) { return false; } foreach (int item in value) { Paving paving = _pavings[item]; if (paving.Piece != piece) { float num = paving.Half + slack; if (SegmentSq(x, z, paving.Ax, paving.Az, paving.Bx, paving.Bz) < num * num) { return true; } } } return false; } internal bool NearLamp(int piece, float x, float z, float reach) { int num = CellOf(x - reach); int num2 = CellOf(x + reach); int num3 = CellOf(z - reach); int num4 = CellOf(z + reach); for (int i = num3; i <= num4; i++) { for (int j = num; j <= num2; j++) { if (!_lampCells.TryGetValue(KeyOf(j, i), out var value)) { continue; } foreach (int item in value) { Lamp lamp = _lamps[item]; if (!lamp.Gone && lamp.Piece != piece) { float num5 = lamp.X - x; float num6 = lamp.Z - z; if (num5 * num5 + num6 * num6 < reach * reach) { return true; } } } } } return false; } internal List<TKey> Take(int piece, IList<float> xs, IList<float> zs, float reach, bool roadsOnly) { List<TKey> list = new List<TKey>(); int num = Math.Min(xs.Count, zs.Count); for (int i = 0; i < num; i++) { float num2 = ((i + 1 < num) ? xs[i + 1] : xs[i]); float num3 = ((i + 1 < num) ? zs[i + 1] : zs[i]); if (i + 1 >= num && num > 1) { break; } int num4 = CellOf(Math.Min(xs[i], num2) - reach); int num5 = CellOf(Math.Max(xs[i], num2) + reach); int num6 = CellOf(Math.Min(zs[i], num3) - reach); int num7 = CellOf(Math.Max(zs[i], num3) + reach); for (int j = num6; j <= num7; j++) { for (int k = num4; k <= num5; k++) { if (!_lampCells.TryGetValue(KeyOf(k, j), out var value)) { continue; } foreach (int item in value) { Lamp lamp = _lamps[item]; if (!lamp.Gone && lamp.Piece != piece && (!roadsOnly || lamp.Road) && !(SegmentSq(lamp.X, lamp.Z, xs[i], zs[i], num2, num3) >= reach * reach)) { lamp.Gone = true; Standing--; list.Add(lamp.Key); } } } } } return list; } private void AddPaving(int piece, float ax, float az, float bx, float bz, float half) { int count = _pavings.Count; _pavings.Add(new Paving { Piece = piece, Ax = ax, Az = az, Bx = bx, Bz = bz, Half = half }); float num = half + 1f; int num2 = CellOf(Math.Min(ax, bx) - num); int num3 = CellOf(Math.Max(ax, bx) + num); int num4 = CellOf(Math.Min(az, bz) - num); int num5 = CellOf(Math.Max(az, bz) + num); for (int i = num4; i <= num5; i++) { for (int j = num2; j <= num3; j++) { Into(_pavingCells, KeyOf(j, i), count); } } } private static void Into(Dictionary<long, List<int>> cells, long key, int index) { if (!cells.TryGetValue(key, out var value)) { value = (cells[key] = new List<int>()); } value.Add(index); } private static int CellOf(float value) { return (int)Math.Floor(value / 32f); } private static long KeyOf(int cx, int cz) { return ((long)cx << 32) | (uint)cz; } private static float SegmentSq(float x, float z, float ax, float az, float bx, float bz) { float num = bx - ax; float num2 = bz - az; float num3 = num * num + num2 * num2; float num4 = ((num3 > 1E-08f) ? Math.Max(0f, Math.Min(1f, ((x - ax) * num + (z - az) * num2) / num3)) : 0f); float num5 = x - (ax + num * num4); float num6 = z - (az + num2 * num4); return num5 * num5 + num6 * num6; } } internal sealed class PlaceFinder { private ZRoutedRpc _listening; internal void Tick() { ZNet instance = ZNet.instance; ZRoutedRpc instance2 = ZRoutedRpc.instance; if (!((Object)(object)instance == (Object)null) && instance2 != null && instance.IsServer() && instance2 != _listening) { _listening = instance2; instance2.Register<ZPackage>("Astvard_AskPlaces", (Action<long, ZPackage>)OnAsk); } } private static void OnAsk(long sender, ZPackage package) { //IL_00d5: 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_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) long num = Senders.SenderPeer(); if (num == 0L) { return; } string text; try { text = PlaceList.UnpackAsk(package); } catch (Exception ex) { Plugin.Log.LogWarning((object)("Places: an ask from " + Senders.SenderName() + " would not read: " + ex.Message)); return; } if (text == null) { return; } if (!Senders.FromAdmin(out var who)) { Plugin.Log.LogWarning((object)("Places: " + who + " asked where every " + text + " is and is no admin — refused.")); ZRoutedRpc.instance.InvokeRoutedRPC(num, "Astvard_Places", new object[1] { PlaceList.PackAnswer((Outcome)1, text, (IList<Vector2>)null) }); return; } List<Vector2> list = new List<Vector2>(); ZoneSystem instance = ZoneSystem.instance; if ((Object)(object)instance != (Object)null) { foreach (LocationInstance value in instance.m_locationInstances.Values) { ZoneLocation location = value.m_location; if (location != null && !(((!string.IsNullOrEmpty(location.m_prefabName)) ? location.m_prefabName : location.m_name) != text)) { list.Add(new Vector2(value.m_position.x, value.m_position.z)); if (list.Count >= 4000) { break; } } } } ZRoutedRpc.instance.InvokeRoutedRPC(num, "Astvard_Places", new object[1] { PlaceList.PackAnswer((Outcome)0, text, (IList<Vector2>)list) }); Plugin.Log.LogInfo((object)("Places: " + list.Count + " " + text + " in this world, told to " + who + ".")); } } internal sealed class PlayerRules { private enum Outcome { Changed, Same, Refused } private readonly Dictionary<string, ConfigEntry<bool>> _switches = new Dictionary<string, ConfigEntry<bool>>(); private readonly Dictionary<string, ConfigEntry<int>> _limits = new Dictionary<string, ConfigEntry<int>>(); private ZRoutedRpc _listening; internal bool PlayersShare => _switches["players_share"].Value; internal event Action<string, string> ChangedInGame; internal event Action Changed; internal PlayerRules(ConfigEntry<bool> playersPay, ConfigEntry<bool> playersChests, ConfigEntry<bool> playersShare, ConfigEntry<bool> playersLevel, ConfigEntry<bool> playersRoad, ConfigEntry<bool> playersClear, ConfigEntry<bool> playersRepairPay, ConfigFile config) { _switches["players_pay"] = playersPay; _switches["players_chests"] = playersChests; _switches["players_share"] = playersShare; _switches["players_level"] = playersLevel; _switches["players_road"] = playersRoad; _switches["players_clear"] = playersClear; _switches["players_repair_pay"] = playersRepairPay; Limit[] all = Limits.All; foreach (Limit val in all) { Dictionary<string, ConfigEntry<int>> limits = _limits; string key = val.Key; string text = val.Group; string configKey = val.ConfigKey; int num = val.Default; string[] obj = new string[13] { val.Title, ", ", val.Unit, ": от ", null, null, null, null, null, null, null, null, null }; int min = val.Min; obj[4] = min.ToString(); obj[5] = " до "; min = val.Max; obj[6] = min.ToString(); obj[7] = ((val.Zero != null) ? ("; 0 — " + val.Zero) : ""); obj[8] = ". "; obj[9] = val.About; obj[10] = " Меняется и из игры: «АДМИНКА» → «"; obj[11] = val.Group; obj[12] = "», и на сайте."; limits[key] = config.Bind<int>(text, configKey, num, string.Concat(obj)); } } internal int LimitOf(Limit limit) { if (!_limits.TryGetValue(limit.Key, out var value)) { return limit.Default; } return Mathf.Clamp(value.Value, limit.Min, limit.Max); } internal void Tick() { ZRoutedRpc instance = ZRoutedRpc.instance; if (instance != null && instance != _listening) { _listening = instance; instance.Register("Astvard_AskRules", (Action<long>)OnAsk); instance.Register<string, string>("Astvard_SetRule", (Action<long, string, string>)OnSet); Plugin.Log.LogInfo((object)("Rules for players: " + Describe() + ".")); } } internal Dictionary<string, string> Values() { Dictionary<string, string> dictionary = new Dictionary<string, string>(); foreach (KeyValuePair<string, ConfigEntry<bool>> @switch in _switches) { dictionary[@switch.Key] = (@switch.Value.Value ? "1" : "0"); } Limit[] all = Limits.All; foreach (Limit val in all) { dictionary[val.Key] = LimitOf(val).ToString(CultureInfo.InvariantCulture); } return dictionary; } internal bool Apply(IEnumerable<KeyValuePair<string, string>> values, string from) { List<string> list = new List<string>(); foreach (KeyValuePair<string, string> value in values) { string said; string why; switch (Set(value.Key, value.Value, out said, out why)) { case Outcome.Changed: list.Add(value.Key + " " + value.Value); break; case Outcome.Refused: if (why != null) { Plugin.Log.LogWarning((object)("Rule from " + from + ": " + why)); } break; } } if (list.Count == 0) { return false; } Plugin.Log.LogInfo((object)("Rules for players changed by " + from + " (" + string.Join(", ", list) + "): " + Describe() + ".")); Tell(); return true; } private string Describe() { List<string> list = new List<string>(); Limit[] all = Limits.All; foreach (Limit val in all) { list.Add(val.Key + " " + LimitOf(val)); } return (_switches["players_pay"].Value ? "players pay for their builds" : "players build free") + (_switches["players_chests"].Value ? " (from the bag and the chests nearby)" : " (from the bag only)") + (_switches["players_share"].Value ? ", may put builds on the server" : ", may not put builds on the server") + (_switches["players_level"].Value ? ", may level the ground" : ", may not level the ground") + ((!_switches["players_road"].Value) ? ", may not lay roads" : (_switches["players_clear"].Value ? ", may lay roads clearing their way" : ", may lay roads")) + (_switches["players_repair_pay"].Value ? ", and pay for fuel when mending" : ", and get fuel free when mending") + "; limits: " + string.Join(", ", list); } private ZPackage Packet() { Dictionary<string, string> dictionary = Values(); dictionary["server_build"] = Build.Here; return Rules.Pack((IDictionary<string, string>)dictionary); } private void Tell() { ZRoutedRpc instance = ZRoutedRpc.instance; if (instance != null) { instance.InvokeRoutedRPC(0L, "Astvard_Rules", new object[1] { Packet() }); } this.Changed?.Invoke(); } private void OnAsk(long sender) { ZRoutedRpc.instance.InvokeRoutedRPC(sender, "Astvard_Rules", new object[1] { Packet() }); } private void OnSet(long sender, string key, string value) { if (!Senders.FromAdmin(out var who)) { Plugin.Log.LogWarning((object)("Rule " + key + " = " + value + " asked by " + who + ", who is not an admin — refused.")); return; } string said; string why; Outcome outcome = Set(key, value, out said, out why); if (outcome == Outcome.Refused) { Plugin.Log.LogWarning((object)("Rule asked by " + who + ": " + why)); return; } Plugin.Log.LogInfo((object)("Rules for players changed by " + who + ": " + Describe() + ".")); Tell(); if (outcome == Outcome.Changed) { this.ChangedInGame?.Invoke(key, said); } } private Outcome Set(string key, string value, out string said, out string why) { said = null; why = null; if (key == null) { why = "a rule with no key — refused."; return Outcome.Refused; } if (_switches.TryGetValue(key, out var value2)) { if (value != "1" && value != "0") { why = key + " = " + value + " is neither 1 nor 0 — refused."; return Outcome.Refused; } said = value; bool flag = value == "1"; if (value2.Value == flag) { return Outcome.Same; } value2.Value = flag; return Outcome.Changed; } Limit[] all = Limits.All; foreach (Limit val in all) { if (!(val.Key != key)) { int? num = Rules.ReadLimit(val, value); if (!num.HasValue) { string[] obj = new string[8] { key, " = ", value, " is not a whole number from ", null, null, null, null }; int min = val.Min; obj[4] = min.ToString(); obj[5] = " to "; min = val.Max; obj[6] = min.ToString(); obj[7] = " — refused."; why = string.Concat(obj); return Outcome.Refused; } said = num.Value.ToString(CultureInfo.InvariantCulture); if (LimitOf(val) == num.Value) { return Outcome.Same; } _limits[key].Value = num.Value; return Outcome.Changed; } } why = key + " is not a rule this server knows — refused."; return Outcome.Refused; } } internal sealed class PlayerStats { private sealed class Entry { internal string Id; internal string Name = ""; internal Sheet Sheet = new Sheet(); } private const string FileName = "astvard-stats.txt"; private const string Header = "# astvard stats 1: id, health, stamina, eitr, carry weight, name; -1 is the game's own"; private const int LongestName = 64; private static readonly CultureInfo Invariant = CultureInfo.InvariantCulture; private readonly Dictionary<string, Entry> _entries = new Dictionary<string, Entry>(); private readonly HashSet<long> _asked = new HashSet<long>(); private readonly Runes _runes; private ZRoutedRpc _listening; private bool _loaded; private string _troubleWriting; private static string FilePath => Path.Combine(Paths.ConfigPath, "astvard-stats.txt"); internal PlayerStats(Runes runes) { _runes = runes; } internal string Describe() { if (!_loaded) { Load(); } return "Player stats: " + _entries.Count + " player(s) with numbers set in astvard-stats.txt; an admin sets them in «Персонаж», and a player's own client lays them on the character."; } internal void Tick() { ZNet instance = ZNet.instance; ZRoutedRpc instance2 = ZRoutedRpc.instance; if (!((Object)(object)instance == (Object)null) && instance2 != null && instance.IsServer() && instance2 != _listening) { _listening = instance2; instance2.Register("Astvard_AskMyStats", (Action<long>)OnAskMine); instance2.Register("Astvard_AskStatsLedger", (Action<long>)OnAskLedger); instance2.Register<ZPackage>("Astvard_SetStats", (Action<long, ZPackage>)OnSet); _asked.Clear(); if (!_loaded) { Load(); } } } private void OnAskMine(long sender) { //IL_0063: Unknown result type (might be due to invalid IL or missing references) string text = Senders.SenderHost(); long num = Senders.SenderPeer(); if (string.IsNullOrEmpty(text) || num == 0L) { return; } _asked.Add(num); Entry entry = Find(text); if (entry != null) { string text2 = Clean(Senders.SenderName()); if (text2.Length > 0 && text2 != entry.Name) { entry.Name = text2; Save(); } } Tell(num, (Sheet)((entry != null) ? ((object)entry.Sheet) : ((object)new Sheet()))); } private void OnAskLedger(long sender) { long num = Senders.SenderPeer(); if (num == 0L) { return; } if (!Senders.FromAdmin(out var who)) { Plugin.Log.LogWarning((object)("Player stats: " + who + " asked for the list of players and is no admin — refused.")); ZRoutedRpc.instance.InvokeRoutedRPC(num, "Astvard_StatsLedger", new object[1] { StatSheets.PackLedger((Outcome)1, (IList<Row>)null) }); return; } List<Row> list = Ledger(num); if (list.Count > 500) { Plugin.Log.LogWarning((object)("Player stats: the list for " + who + " is one package: " + (list.Count - 500) + " players did not fit in it.")); } ZRoutedRpc.instance.InvokeRoutedRPC(num, "Astvard_StatsLedger", new object[1] { StatSheets.PackLedger((Outcome)0, (IList<Row>)list) }); } private List<Row> Ledger(long asker) { //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_019b: 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_01bf: Expected O, but got Unknown //IL_00ab: 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_00b8: 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_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Expected O, but got Unknown if (!_loaded) { Load(); } List<Row> list = new List<Row>(); HashSet<string> hashSet = new HashSet<string>(); HashSet<long> hashSet2 = new HashSet<long>(); foreach (ZNetPeer connectedPeer in ZNet.instance.GetConnectedPeers()) { if (connectedPeer != null) { hashSet2.Add(connectedPeer.m_uid); ISocket socket = connectedPeer.m_socket; string text = ((socket != null) ? socket.GetHostName() : null); if (!string.IsNullOrEmpty(text) && !((ZDOID)(ref connectedPeer.m_characterID)).IsNone() && hashSet.Add(text)) { Entry entry = Find(text); string text2 = Clean(connectedPeer.m_playerName); list.Add(new Row { Id = text, Name = ((text2.Length > 0) ? text2 : (entry?.Name ?? "")), Online = true, Modded = _asked.Contains(connectedPeer.m_uid), You = (connectedPeer.m_uid == asker), Sheet = (Sheet)((entry != null) ? ((object)entry.Sheet.Copy()) : ((object)new Sheet())) }); } } } _asked.IntersectWith(hashSet2); foreach (Entry value in _entries.Values) { if (!hashSet.Contains(value.Id)) { list.Add(new Row { Id = value.Id, Name = value.Name, Sheet = value.Sheet.Copy() }); } } list.Sort(delegate(Row a, Row b) { if (a.Online != b.Online) { if (!a.Online) { return 1; } return -1; } int num = string.Compare(a.Name, b.Name, StringComparison.OrdinalIgnoreCase); return (num == 0) ? string.CompareOrdinal(a.Id, b.Id) : num; }); return list; } private void OnSet(long sender, ZPackage pkg) { long num = Senders.SenderPeer(); string text = default(string); Sheet val = default(Sheet); if (num == 0L || !StatSheets.UnpackSet(pkg, ref text, ref val)) { return; } if (!Senders.FromAdmin(out var who)) { Plugin.Log.LogWarning((object)("Player stats: " + who + " tried to set the numbers of " + text + " and is no admin — refused.")); Answer(num, (Outcome)1, text, null, null, told: false); return; } if (string.IsNullOrEmpty(text) || text.Length > 32 || !StatSheets.Valid(val)) { Plugin.Log.LogWarning((object)("Player stats: " + who + " sent numbers out of bounds for " + text + " — refused.")); Answer(num, (Outcome)2, text, null, null, told: false); return; } if (!_loaded) { Load(); } ZNetPeer val2 = PeerOf(text); Entry entry = Find(text); string text2 = Clean(val2?.m_playerName); if (text2.Length == 0) { text2 = entry?.Name ?? _runes.NameOf(text) ?? ""; } if (val.Any) { if (entry == null) { entry = new Entry { Id = text }; _entries[text] = entry; } entry.Sheet = val.Copy(); if (text2.Length > 0) { entry.Name = text2; } } else { _entries.Remove(text); } Save(); if (val2 != null) { Tell(val2.m_uid, val); } bool flag = val2 != null && _asked.Contains(val2.m_uid); Plugin.Log.LogInfo((object)("Player stats: " + who + " set «" + text2 + "» (" + text + ") to " + StatSheets.Describe(val) + ((val2 == null) ? ", not on now." : (flag ? ", told." : ", on without the part that lays them.")))); Answer(num, (Outcome)0, text, text2, val, flag); } private static void Answer(long to, Outcome outcome, string id, string name, Sheet sheet, bool told) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) ZRoutedRpc.instance.InvokeRoutedRPC(to, "Astvard_SetStatsAnswer", new object[1] { StatSheets.PackAnswer(outcome, id, name, sheet, told) }); } private static void Tell(long peer, Sheet sheet) { ZRoutedRpc instance = ZRoutedRpc.instance; if (instance != null) { instance.InvokeRoutedRPC(peer, "Astvard_MyStats", new object[1] { StatSheets.PackSheet(sheet) }); } } private Entry Find(string id) { if (!_loaded) { Load(); } if (id == null || !_entries.TryGetValue(id, out var value)) { return null; } return value; } private static ZNetPeer PeerOf(string id) { ZNet instance = ZNet.instance; if ((Object)(object)instance == (Object)null) { return null; } foreach (ZNetPeer connectedPeer in instance.GetConnectedPeers()) { if (connectedPeer?.m_socket != null && connectedPeer.m_socket.GetHostName() == id) { return connectedPeer; } } return null; } private static string Clean(string name) { if (string.IsNullOrEmpty(name)) { return ""; } string text = name.Replace('\t', ' ').Replace('\r', ' ').Replace('\n', ' ') .Trim(); if (text.Length <= 64) { return text; } return text.Substring(0, 64); } private void Load() { //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0091: 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) //IL_00af: Unknown result type (might be due to invalid IL or missing references) _loaded = true; _entries.Clear(); try { if (!File.Exists(FilePath)) { return; } int num = 0; string[] array = File.ReadAllLines(FilePath, Encoding.UTF8); foreach (string text in array) { if (!text.StartsWith("#") && text.Trim().Length != 0) { string[] array2 = text.Split(new char[1] { '\t' }); Sheet val = ((array2.Length < 5) ? ((Sheet)null) : new Sheet { Hp = Number(array2[1]), Stamina = Number(array2[2]), Eitr = Number(array2[3]), Carry = Number(array2[4]) }); string text2 = array2[0].Trim(); if (text2.Length == 0 || val == null || !StatSheets.Valid(val) || !val.Any) { num++; continue; } _entries[text2] = new Entry { Id = text2, Name = ((array2.Length > 5) ? Clean(array2[5]) : ""), Sheet = val }; } } if (num > 0) { Plugin.Log.LogWarning((object)("Player stats: " + num + " line(s) of astvard-stats.txt are not a player's numbers — left out.")); } } catch (Exception ex) { Plugin.Log.LogError((object)("Player stats: could not read astvard-stats.txt: " + ex.Message)); } } private static int Number(string text) { if (!int.TryParse(text.Trim(), NumberStyles.Integer, Invariant, out var result)) { return int.MinValue; } return result; } private void Save() { try { List<string> list = new List<string> { "# astvard stats 1: id, health, stamina, eitr, carry weight, name; -1 is the game's own" }; foreach (Entry value in _entries.Values) { Sheet sheet = value.Sheet; list.Add(value.Id + "\t" + sheet.Hp.ToString(Invariant) + "\t" + sheet.Stamina.ToString(Invariant) + "\t" + sheet.Eitr.ToString(Invariant) + "\t" + sheet.Carry.ToString(Invariant) + "\t" + value.Name); } string text = FilePath + ".tmp"; File.WriteAllLines(text, list.ToArray(), new UTF8Encoding(encoderShouldEmitUTF8Identifier: false)); if (File.Exists(FilePath)) { File.Replace(text, FilePath, null); } else { File.Move(text, FilePath); } _troubleWriting = null; } catch (Exception ex) { if (!(_troubleWriting == ex.Message)) { _troubleWriting = ex.Message; Plugin.Log.LogError((object)("Player stats: could not write astvard-stats.txt: " + ex.Message)); } } } } [BepInPlugin("astvard.server", "Astvard Server", "2.0.2")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInProcess("valheim_server.exe")] public sealed class Plugin : BaseUnityPlugin { internal const string Guid = "astvard.server"; internal const string Title = "Astvard Server"; private Harmony _harmony; private PlayerRules _rules; private SharedBuilds _builds; private BuildPause _pause; private Runes _runes; private Charges _charges; private RuneGrants _grants; private PlayerStats _stats; private readonly PlaceFinder _places = new PlaceFinder(); private SharedWeather _weather; private SharedWind _wind; private SharedTime _time; private SortZones _zones; private SortShelves _shelves; private WorldRates _worldRates; private RoadJobs _roads; private RoadNet _roadNet; internal static ManualLogSource Log { get; private set; } private void Awake() { //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; _rules = new PlayerRules(((BaseUnityPlugin)this).Config.Bind<bool>("Постройки игроков", "Платно", true, "Игроки ставят постройки мода за ресурсы из сумки (true) или даром (false). Админ меняет это и из игры: «АДМИНКА» → «Настройки»."), ((BaseUnityPlugin)this).Config.Bind<bool>("Постройки игроков", "Из сундуков", true, "Чего нет в сумке, платная постройка игрока добирает из сундуков рядом, которые он открыл бы сам (true), или берёт только из сумки (false). Как далеко — [Пределы игроков] Сундуки рядом. Меняется и из игры: «АДМИНКА» → «Настройки», и на сайте."), ((BaseUnityPlugin)this).Config.Bind<bool>("Постройки игроков", "Выкладывать", false, "Игроки могут выкладывать свои постройки на сервер (true): они приходят скрытыми, и открывает их игрокам админ. Меняется и из игры: «АДМИНКА» → «Настройки»."), ((BaseUnityPlugin)this).Config.Bind<bool>("Рельеф игроков", "Выравнивание", true, "Игроки могут ровнять землю «Рельефом» и под своими постройками (true) или ровняет только админ (false). Как далеко — [Пределы игроков] Выравнивание. Меняется и из игры: «АДМИНКА» → «Настройки», и на сайте."), ((BaseUnityPlugin)this).Config.Bind<bool>("Рельеф игроков", "Дорожки", true, "Игроки могут класть дорожки и мостить круги в «Дорожках» (true) или кладёт только админ (false). Как далеко — [Пределы игроков] Дорожка и Мощение. Меняется и из игры: «АДМИНКА» → «Настройки», и на сайте."), ((BaseUnityPlugin)this).Config.Bind<bool>("Рельеф игроков", "Снос", false, "Дорожка игрока сносит деревья, пни, брёвна и голые камни на пути (true) или убирает только подлесок (false). Снесённое откат не вернёт. Меняется и из игры: «АДМИНКА» → «Настройки», и на сайте."), ((BaseUnityPlugin)this).Config.Bind<bool>("Функции игроков", "Починка платно", true, "«Починить» у игроков берёт топливо для факелов, костров и печей из сумки (true) или заправляет даром (false). Чинит всегда даром, как молот. Меняется и из игры: «АДМИНКА» → «Настройки»."), ((BaseUnityPlugin)this).Config); _builds = new SharedBuilds(() => _rules.PlayersShare); _pause = new BuildPause(_rules); _runes = new Runes(_rules); _charges = new Charges(_rules, _runes); _grants = new RuneGrants(_runes); _stats = new PlayerStats(_runes); _weather = new SharedWeather(); _wind = new SharedWind(); _time = new SharedTime(); _zones = new SortZones(_rules, _runes); _shelves = new SortShelves(); _worldRates = new WorldRates(_rules); WorldSeed.Bind(((BaseUnityPlugin)this).Config); SteamListing.Bind(((BaseUnityPlugin)this).Config); _roads = new RoadJobs((MonoBehaviour)(object)this); _roadNet = new RoadNet((MonoBehaviour)(object)this, _roads); _harmony = new Harmony("astvard.server"); _harmony.PatchAll(); Log.LogInfo((object)Throttle.Describe()); Log.LogInfo((object)RuneGrants.Describe()); Log.LogInfo((object)_stats.Describe()); Log.LogInfo((object)SharedWeather.Describe()); Log.LogInfo((object)SharedWind.Describe()); Log.LogInfo((object)SharedTime.Describe()); Log.LogInfo((object)_zones.Describe()); Log.LogInfo((object)_shelves.Describe()); Log.LogInfo((object)WorldRates.Describe()); Log.LogInfo((object)WorldSeed.Describe()); Log.LogInfo((object)SteamListing.Describe()); Log.LogInfo((object)RoadJobs.Describe()); Log.LogInfo((object)RoadNet.Describe()); ConfigEntry<string> val = ((BaseUnityPlugin)this).Config.Bind<string>("Сайт", "Адрес", "http://127.0.0.1:3002/api/game/access", "Где сайт отдаёт списки допуска и админов (GET, договор — в AstvardTwo/site/CLAUDE.md). Правила игроков ходят рядом: …/access, замененный на …/rules."); ConfigEntry<string> token = ((BaseUnityPlugin)this).Config.Bind<string>("Сайт", "Токен", "", "GAME_TOKEN из .env сайта. Пусто — списки и правила на сервере с сайтом не сверяются."); ConfigEntry<int> seconds = ((BaseUnityPlugin)this).Config.Bind<int>("Сайт", "Секунд", 15, "Как часто спрашивать сайт, от 5 до 600. Игра сама перечитывает списки раз в 10 секунд."); ((MonoBehaviour)this).StartCoroutine(new AccessLists(val, token, seconds).Run()); ((MonoBehaviour)this).StartCoroutine(new SiteRules(_rules, val, token, seconds).Run()); ((MonoBehaviour)this).StartCoroutine(new SiteRunes(_runes, val, token, seconds).Run()); ((MonoBehaviour)this).StartCoroutine(new SiteBuilds(val, token, seconds).Run()); ((MonoBehaviour)this).StartCoroutine(new SiteZones(_zones, val, token, seconds).Run()); ((MonoBehaviour)this).StartCoroutine(new SiteShelves(_shelves, val, token, seconds).Run()); ((MonoBehaviour)this).StartCoroutine(new SiteStatus(val, token, seconds).Run()); Log.LogInfo((object)"Astvard Server 2.0.2 loaded."); } private void Update() { _rules.Tick(); _builds.Tick(); _pause.Tick(); _runes.Tick(); _charges.Tick(); _grants.Tick(); _stats.Tick(); _places.Tick(); _weather.Tick(); _wind.Tick(); _time.Tick(); _zones.Tick(); _shelves.Tick(); _worldRates.Tick(); _roads.Tick(); _roadNet.Tick(); } private void OnApplicationQuit() { _runes?.Save(); } private void OnDestroy() { RoadJobs.Shutdown(); _runes?.Save(); Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } } internal sealed class RoadJobs { internal sealed class NetPiece { internal string Label = "Road net"; internal readonly List<float> X = new List<float>(); internal readonly List<float> Z = new List<float>(); internal bool Circle; internal float Radius; internal Order Order; internal NetLights<ZDOID> Lights; internal int Index; internal bool Over; internal string Failure; internal bool Stopped; internal float Laid; internal int Doused; internal int Spared; internal int Cleared; internal int Placed; internal int Skipped; internal int Bends; internal int Unbent; internal NetPiece FromRing; internal NetPiece ToRing; internal bool Trimmed; internal float WetMetres; internal float MostFill; internal float Raised; internal int Bridges; internal float BridgeMetres; } private sealed class Job { internal int Id; internal string Label; internal NetPiece Net; internal bool Circle; internal long Asker; internal string Who; internal Order Order; internal readonly List<float> X = new List<float>(); internal readonly List<float> Z = new List<float>(); internal float Half; internal float Blend; internal Color Paint; internal bool Stop; internal Record Record; internal readonly HashSet<Vector2s> Zones = new HashSet<Vector2s>(); internal float NextPost; internal float Laid; internal int Cleared; internal int Painted; internal int ShortOf; internal int Placed; internal int Skipped; internal int Spared; internal int Bends; internal int Unbent; internal int Incomplete; internal float Raised; internal int Bridges; internal float BridgeMetres; internal int BridgeParts; internal int Islands; internal List<Causeway.Stretch> Spanned; internal float Reach => Half + Blend; } private sealed class Record { internal int Id; internal bool Running = true; internal readonly Dictionary<ZDOID, byte[]> Before = new Dictionary<ZDOID, byte[]>(); internal readonly List<ZDOID> Torches = new List<ZDOID>(); internal Vector3 End; } private sealed class Span { internal Vector3 Start; internal Quaternion Facing; internal readonly List<Piece> Parts = new List<Piece>(); } private sealed class Crossing { internal readonly List<Span> Bridges = new List<Span>(); internal readonly List<Causeway.Stretch> Islands = new List<Causeway.Stretch>(); } private const int Piece = 100; private const float BridgeLeast = 4f; private const float BridgeMost = 64f; private const int MostSpans = 4; private const float Margin = 64f; private const float Patience = 60f; private const int Kept = 4; private const int NewZonesARound = 2; internal const float RingMost = 32f; internal const float PlaceRoom = 4f; private const float ApartShare = 0.55f; private const float PavingSlack = 0.3f; private static readonly WaitForSeconds Quarter = new WaitForSeconds(0.25f); private static readonly MethodInfo PokeMethod = AccessTools.Method(typeof(ZoneSystem), "PokeLocalZone", new Type[1] { typeof(Vector2s) }, (Type[])null); private static readonly MethodInfo CheckLoadMethod = AccessTools.Method(typeof(TerrainComp), "CheckLoad", (Type[])null, (Type[])null); private static Job _job; private static Func<Vector2s, bool> _poke; private static ZoneSystem _pokeFor; private static float _pokedAt = float.MinValue; private static readonly List<ZDO> Records = new List<ZDO>(); private static readonly HashSet<ZDO> Near = new HashSet<ZDO>(); private readonly MonoBehaviour _host; private readonly List<Record> _kept = new List<Record>(); private ZRoutedRpc _listening; internal static bool Busy => _job != null; internal RoadJobs(MonoBehaviour host) { _host = host; } internal static string Describe() { return "Long roads: an admin's road past " + 100 + " m is laid here, " + 100 + " m at a time, up to " + 10000 + " m" + ((PokeMethod != null) ? ", its ground loaded by the server." : "; ZoneSystem.PokeLocalZone is gone, so they are not laid."); } internal void Tick() { ZRoutedRpc instance = ZRoutedRpc.instance; if (instance != null && instance != _listening) { _listening = instance; instance.Register<ZPackage>("Astvard_LongRoad", (Action<long, ZPackage>)OnOrder); instance.Register<int>("Astvard_LongRoadStop", (Action<long, int>)OnStop); instance.Register<int>("Astvard_LongRoadUndo", (Action<long, int>)OnUndo); } } internal static void Shutdown() { if (_job != null) { _job.Stop = true; } } internal static void StopNet() { if (_job?.Net != null) { _job.Stop = true; } } internal bool Take(NetPiece piece) { //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) if (_job != null || piece == null || piece.Order == null || piece.X.Count == 0 || piece.X.Count != piece.Z.Count) { return false; } ZoneSystem instance = ZoneSystem.instance; if (PokeFor(instance) == null || !instance.LocationsGenerated || !Ground.Ready) { return false; } Order order = piece.Order; float num = (piece.Circle ? Mathf.Clamp(piece.Radius, 1f, 32f) : Mathf.Max(order.Width * 0.5f, 0.75f)); Job job = new Job { Id = Random.Range(1, int.MaxValue), Label = piece.Label, Net = piece, Circle = piece.Circle, Asker = 0L, Who = "the road net", Order = order, Half = num, Blend = (order.Smooth ? RoadLevel.BlendFor(num) : 0f), Paint = (order.Paved ? Heightmap.m_paintMaskPaved : Heightmap.m_paintMaskDirt), NextPost = order.Spacing * 0.5f }; job.X.AddRange(piece.X); job.Z.AddRange(piece.Z); job.Record = new Record { Id = job.Id }; _job = job; _host.StartCoroutine(Run(job)); return true; } private void OnOrder(long sender, ZPackage package) { //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_00db: 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_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: 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_0193: Unknown result type (might be due to invalid IL or missing references) //IL_020e: 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) //IL_02ed: Unknown result type (might be due to invalid IL or missing references) //IL_02f3: Unknown result type (might be due to invalid IL or missing references) //IL_0392: Unknown result type (might be due to invalid IL or missing references) //IL_038b: Unknown result type (might be due to invalid IL or missing references) //IL_0397: Unknown result type (might be due to invalid IL or missing references) //IL_04ca: Unknown result type (might be due to invalid IL or missing references) long num = Senders.SenderPeer(); Order val; try { val = Order.Read(package); } catch (Exception ex) { Plugin.Log.LogWarning((object)("Long road: an order from " + Senders.SenderName() + " would not read: " + ex.Message)); return; } if (!Senders.FromAdmin(out var who)) { Plugin.Log.LogWarning((object)("Long road asked by " + who + ", who is not an admin — refused.")); Tell(num, val?.Id ?? 0, (News)5, "Длинные дорожки сервер кладёт только админу"); return; } if (val == null) { Tell(num, 0, (News)5, "У тебя мод другой версии: сервер твою дорожку не прочтёт"); return; } if (_job != null || RoadNet.Laying) { Tell(num, val.Id, (News)5, RoadNet.Laying ? "Сервер кладёт сеть дорог — дождись её или останови в «АДМИНКЕ» → «Сеть дорог»" : "Сервер уже кладёт дорожку — дождись её или останови"); return; } ZoneSystem instance = ZoneSystem.instance; if (PokeFor(instance) == null || !instance.LocationsGenerated || !Ground.Ready) { Tell(num, val.Id, (News)5, "Сервер сейчас не может подгружать землю — см. его лог"); return; } if (!val.Finite()) { Plugin.Log.LogWarning((object)("Long road " + val.Id + " from " + who + " carried a non-number.")); Tell(num, val.Id, (News)5, "Дорожка пришла битой — отметь её заново"); return; } float num2 = Flat(val.From, val.To); if (num2 < 1f || num2 > 10000f) { Tell(num, val.Id, (News)5, "Дорожка " + Metres(num2) + " м — сервер кладёт от 1 до " + Metres(10000f) + " м"); return; } val.Bend = Mathf.Clamp(val.Bend, -10f, 10f); val.Width = Mathf.Clamp(val.Width, 1f, 8f); val.Spacing = Mathf.Clamp(val.Spacing, 4f, 50f); if (val.Torch < 0 || val.Torch >= Torches.Prefabs.Length) { val.Torch = 0; } RoadLine val2 = RoadLine.Curve(val.From.x, val.From.z, val.To.x, val.To.z, val.Bend, 1f); if (val2.Count < 2) { Tell(num, val.Id, (News)5, "Точки слишком близко"); return; } float num3 = Mathf.Max(val.Width * 0.5f, 0.75f); Job job = new Job { Id = val.Id, Label = "Long road " + val.Id, Asker = num, Who = who, Order = val, Half = num3, Blend = (val.Smooth ? RoadLevel.BlendFor(num3) : 0f), Paint = (val.Paved ? Heightmap.m_paintMaskPaved : Heightmap.m_paintMaskDirt), NextPost = val.Spacing * 0.5f }; for (int i = 0; i < val2.Count; i++) { job.X.Add(val2.XAt(i)); job.Z.Add(val2.ZAt(i)); } job.Record = new Record { Id = val.Id }; _kept.Add(job.Record); int num4 = 0; while (num4 < _kept.Count && _kept.Count > 4) { if (_kept[num4].Running) { num4++; } else { _kept.RemoveAt(num4); } } _job = job; _host.StartCoroutine(Run(job)); Tell(num, job.Id, (News)0, "Сервер взялся за дорожку " + Metres(val2.Length) + " м: кладёт по " + 100 + " м, землю подгружает сам. Можно заниматься своим", val.From, 0f, val2.Length); Plugin.Log.LogInfo((object)(job.Label + " from " + who + ": " + val2.Length.ToString("0.0", CultureInfo.InvariantCulture) + " m from " + ((Vector3)(ref val.From)).ToString("F1") + " to " + ((Vector3)(ref val.To)).ToString("F1") + ", width " + val.Width.ToString("0.#", CultureInfo.InvariantCulture) + ", bend " + val.Bend.ToString("0.#", CultureInfo.InvariantCulture) + (val.Paved ? ", stone" : ", dirt") + (val.Smooth ? ", smoothed" : "") + (val.Clear ? ", clearing" : ", undergrowth only") + (val.Round ? ", going round" : "") + ((val.Torch > 0) ? (", torches " + Torches.Prefabs[val.Torch] + " every " + Metres(val.Spacing) + " m" + (val.Forever ? ", everlasting" : "")) : "") + ", " + val2.Count + " points.")); } private static void OnStop(long sender, int id) { //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) long num = Senders.SenderPeer(); if (!Senders.FromAdmin(out var who)) { Plugin.Log.LogWarning((object)("Long road " + id + ": a stop asked by " + who + ", who is not an admin — refused.")); } else if (_job != null && _job.Id == id) { _job.Asker = num; _job.Stop = true; Plugin.Log.LogInfo((object)("Long road " + id + ": stop asked by " + who + ".")); } else { Tell(num, id, (News)3, "Эта дорожка уже не кладётся"); } } private void OnUndo(long sender, int id) { //IL_006a: 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_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: 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_00bb: 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_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_0204: Unknown result type (might be due to invalid IL or missing references) //IL_02e1: Unknown result type (might be due to invalid IL or missing references) long num = Senders.SenderPeer(); if (!Senders.FromAdmin(out var who)) { Plugin.Log.LogWarning((object)("Long road " + id + ": taking back asked by " + who + ", who is not an admin — refused.")); Tell(num, id, (News)7, "Откатывать дорожки сервера может только админ"); return; } if (_job != null) { if (_job.Id == id) { _job.Asker = num; Tell(num, id, (News)8, "Эта дорожка ещё кладётся — «Остановить укладку», потом откатывай"); } else { Tell(num, id, (News)7, "Сервер сейчас кладёт другую дорожку — откати, когда он закончит"); } return; } Record record = _kept.Find((Record r) => r.Id == id); if (record == null) { Tell(num, id, (News)6, "Сервер уже не помнит эту дорожку — откатить нечего"); return; } _kept.Remove(record); long sessionID = ZDOMan.GetSessionID(); int num2 = 0; int num3 = 0; foreach (KeyValuePair<ZDOID, byte[]> item in record.Before) { ZDO zDO = ZDOMan.instance.GetZDO(item.Key); if (zDO == null) { num3++; continue; } zDO.SetOwner(sessionID); zDO.Set(ZDOVars.s_TCData, item.Value); num2++; } int num4 = 0; foreach (ZDOID torch in record.Torches) { ZDO zDO2 = ZDOMan.instance.GetZDO(torch); if (zDO2 == null) { continue; } GameObject val = (((Object)(object)ZNetScene.instance != (Object)null) ? ZNetScene.instance.FindInstance(torch) : null); if ((Object)(object)val != (Object)null) { ZNetView component = val.GetComponent<ZNetView>(); if (component != null) { component.ClaimOwnership(); } ZNetScene.instance.Destroy(val); } else { zDO2.SetOwner(sessionID); ZDOMan.instance.DestroyZDO(zDO2); } num4++; } Tell(num, id, (News)6, "Откат: дорожка сервера — " + num2 + " зон" + ((num4 > 0) ? (", факелов убрано: " + num4) : "") + ((num3 > 0) ? (", " + num3 + " зон уже нет") : ""), record.End); Plugin.Log.LogInfo((object)("Long road " + id + " taken back by " + who + ": " + num2 + " zones written back, " + num3 + " gone, " + num4 + " torches taken down.")); } private static void Tell(long peer, int id, News news, string text, Vector3 end = default(Vector3), float laid = 0f, float total = 0f) { //IL_001f: 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) if (peer != 0L && ZRoutedRpc.instance != null) { ZRoutedRpc.instance.InvokeRoutedRPC(peer, "Astvard_LongRoadNews", new object[1] { LongRoads.Say(id, news, text, end, laid, total) }); } } private IEnumerator Run(Job job) { float began = Time.realtimeSinceStartup; string failure = null; int laidTo = 0; int pieces = 0; int lastStart = Math.Max(1, job.X.Count - 1); try { if (job.Order.Round && !job.Circle) { RoundPlaces(job); } int first = 0; while (first < lastStart && !job.Stop && !((Object)(object)ZNet.instance == (Object)null)) { int last = Math.Min(first + 100, job.X.Count - 1); int ahead = Math.Min(first + 200, job.X.Count - 1); if (job.Order.Bridge && !job.Circle) { last = PastWater(job, last, ahead); } float pieceBegan = Time.realtimeSinceStartup; SetZones(job, first, ahead); float deadline = Time.time + 60f; while (!HasGround(job) && !job.Stop && Time.time < deadline && (Object)(object)ZNet.instance != (Object)null) { yield return Quarter; } if (job.Stop || (Object)(object)ZNet.instance == (Object)null) { break; } if (!HasGround(job)) { failure = "земля не подгрузилась за минуту"; break; } deadline = Time.time + 60f; while ((Pending(job) > 0 || !Settled(job)) && !job.Stop && Time.time < deadline && (Object)(object)ZNet.instance != (Object)null) { yield return Quarter; } if (job.Stop || (Object)(object)ZNet.instance == (Object)null) { break; } bool complete = Pending(job) == 0 && Settled(job); if (!complete) { job.Incomplete++; Plugin.Log.LogWarning((object)(job.Label + ": " + Pending(job) + " objects still not built after a minute; the piece goes without clearing, going round and torches.")); } yield return null; yield return null; if (job.Stop || (Object)(object)ZNet.instance == (Object)null || ZDOMan.instance == null) { break; } if (complete && job.Order.Round && !job.Circle) { RoundAhead(job, first, ahead, last); } if (complete && job.Circle) { Grow(job); } RoadLine piece = LineOf(job, first, last); failure = Lay(job, piece, complete); if (failure != null) { break; } laidTo = last; pieces++; job.Laid += piece.Length; NetLights<ZDOID> lights = job.Net?.Lights; if (lights != null) { if (job.Circle) { lights.AddDisc(job.Net.Index, job.X[0], job.Z[0], job.Half); } else { lights.AddRoad(job.Net.Index, XsOf(piece), ZsOf(piece), job.Half); } } if (job.Order.Torch > 0) { yield return null; if ((Object)(object)ZNet.instance == (Object)null || (Object)(object)ZNetScene.instance == (Object)null) { break; } if (job.Circle) { if (lights != null) { float[] xs = new float[1] { job.X[0] }; float[] zs = new float[1] { job.Z[0] }; job.Net.Doused += Douse(lights.Take(job.Net.Index, xs, zs, job.Half + 0.6f + Apart(job), roadsOnly: true)); job.Net.Doused += Douse(lights.Take(job.Net.Index, xs, zs, job.Half + 0.3f, roadsOnly: false)); } List<Post> list = RoadLine.RingPosts(job.X[0], job.Z[0], job.Half + 0.6f, job.Order.Spacing); if (complete) { Light(job, list); } else { job.Skipped += list.Count; } } else { if (lights != null) { job.Net.Doused += Douse(lights.Take(job.Net.Index, XsOf(piece), ZsOf(piece), job.Half + 0.3f, roadsOnly: false)); } List<Post> list2 = piece.EdgePostsFrom(job.NextPost, job.Order.Spacing, job.Half + 0.6f, ref job.NextPost); if (job.Spanned != null && job.Spanned.Count > 0) { list2 = OffBridges(piece, list2, job.Spanned); } if (complete) { Light(job, list2); } else { job.Skipped += list2.Count; } } } float num = LengthOf(job); Plugin.Log.LogInfo((object)(job.Label + ": " + (job.Circle ? ("circle r=" + job.Half.ToString("0.#", CultureInfo.InvariantCulture) + " m laid, ") : (Metres(job.Laid) + " of " + Metres(num) + " m laid, ")) + job.Zones.Count + " zones, " + (Time.realtimeSinceStartup - pieceBegan).ToString("0.0", CultureInfo.InvariantCulture) + " s.")); Tell(job.Asker, job.Id, (News)1, "Сервер кладёт дорожку: " + Metres(job.Laid) + " из " + Metres(num) + " м", PointAt(job, last), job.Laid, num); if (last <= first) { break; } first = last; } } finally { job.Zones.Clear(); job.Record.Running = false; job.Record.End = PointAt(job, laidTo); if (_job == job) { _job = null; } if (job.Net != null) { Hand(job, failure, pieces, laidTo); } } float num2 = LengthOf(job); string text = ((job.Order.Smooth && job.Laid > 0f) ? ", сглажена" : "") + ((job.Raised > 0f) ? (", поднята над водой: " + Metres(job.Raised) + " м") : "") + ((job.Bridges > 0) ? (", мостов: " + job.Bridges + " (" + Metres(job.BridgeMetres) + " м)" + ((job.Islands > 0) ? (", островов между ними: " + job.Islands) : "")) : "") + ((job.Cleared > 0) ? (", снесено: " + job.Cleared) : "") + ((job.Order.Torch > 0) ? (", факелов: " + job.Placed + ((job.Skipped > 0) ? (", " + job.Skipped + " некуда поставить") : "")) : "") + ((job.Bends > 0) ? (", обойдено: " + job.Bends) : "") + ((job.Unbent > 0) ? (", обойти не вышло: " + job.Unbent) : "") + ((job.Incomplete > 0) ? (", кусков без сноса и факелов: " + job.Incomplete + " — там не догрузились объекты") : "") + ((job.ShortOf > 0) ? "\nземля двигается не дальше 8 м — местами не дотянулась" : ""); Vector3 end = PointAt(job, laidTo); bool flag = failure == null && pieces > 0 && laidTo >= job.X.Count - 1; if (failure != null) { Tell(job.Asker, job.Id, (News)4, "Дорожка встала на " + Metres(job.Laid) + " из " + Metres(num2) + " м: " + failure + text, end, job.Laid, num2); } else if (!flag) { Tell(job.Asker, job.Id, (News)3, "Укладка остановлена: " + Metres(job.Laid) + " из " + Metres(num2) + " м" + text, end, job.Laid, num2); } else { Tell(job.Asker, job.Id, (News)2, "Дорожка " + Metres(num2) + " м готова, ширина " + job.Order.Width.ToString("0.#", CultureInfo.InvariantCulture).Replace('.', ',') + " м" + text, end, job.Laid, num2); } Plugin.Log.LogInfo((object)(job.Label + " " + ((failure != null) ? ("failed: " + failure) : (flag ? "done" : "stopped")) + ": " + (job.Circle ? ("a circle of " + job.Half.ToString("0.#", CultureInfo.InvariantCulture) + " m, ") : (Metres(job.Laid) + " of " + Metres(num2) + " m in " + pieces + " pieces, ")) + (Time.realtimeSinceStartup - began).ToString("0", CultureInfo.InvariantCulture) + " s, " + job.Record.Before.Count + " zones, cleared " + job.Cleared + ", painted " + job.Painted + ((job.Order.Smooth || job.Raised > 0f) ? (", " + job.ShortOf + " held by the 8 m") : "") + ((job.Raised > 0f) ? (", raised over the water " + Metres(job.Raised) + " m") : "") + ((job.Bridges > 0) ? (", " + job.Bridges + " bridge(s) over " + Metres(job.BridgeMetres) + " m of water, " + job.BridgeParts + " parts" + ((job.Islands > 0) ? (", " + job.Islands + " island(s) between") : "")) : "") + ", torches " + job.Placed + " placed " + job.Skipped + " skipped" + ((job.Spared > 0) ? (", " + job.Spared + " spared beside the net's own") : "") + ((job.Net != null && job.Net.Doused > 0) ? (", " + job.Net.Doused + " of the net's put out") : "") + (job.Circle ? "" : (", went round " + job.Bends + ((job.Unbent > 0) ? (" (" + job.Unbent + " left standing)") : ""))) + ".")); } private static void Hand(Job job, string failure, int pieces, int laidTo) { NetPiece net = job.Net; net.Failure = failure; net.Stopped = failure == null && (pieces == 0 || laidTo < job.X.Count - 1); net.Laid = job.Laid; net.Radius = job.Half; net.Cleared = job.Cleared; net.Placed = job.Placed; net.Skipped = job.Skipped; net.Bends = job.Bends; net.Unbent = job.Unbent; net.Spared = job.Spared; net.Raised = job.Raised; net.Bridges = job.Bridges; net.BridgeMetres = job.BridgeMetres; net.Over = true; } private static void Grow(Job job) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) Location zoneLocation = Location.GetZoneLocation(new Vector3(job.X[0], 0f, job.Z[0])); if (!((Object)(object)zoneLocation == (Object)null) && zoneLocation.m_noBuild) { float num = Mathf.Min((zoneLocation.m_noBuildRadiusOverride > 0f) ? zoneLocation.m_noBuildRadiusOverride : zoneLocation.GetMaxRadius(), 32f); if (!(num <= job.Half + 0.01f)) { Plugin.Log.LogInfo((object)(job.Label + ": ring " + job.Half.ToString("0.0", CultureInfo.InvariantCulture) + " → " + num.ToString("0.0", CultureInfo.InvariantCulture) + " m, to the no-build edge of " + ((Object)zoneLocation).name + ".")); job.Half = num; job.Blend = (job.Order.Smooth ? RoadLevel.BlendFor(num) : 0f); } } } private static int Douse(List<ZDOID> lamps) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_003e: 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) ZNetScene instance = ZNetScene.instance; ZDOMan instance2 = ZDOMan.instance; if (lamps.Count == 0 || (Object)(object)instance == (Object)null || instance2 == null) { return 0; } long sessionID = ZDOMan.GetSessionID(); int num = 0; foreach (ZDOID lamp in lamps) { ZDO zDO = instance2.GetZDO(lamp); if (zDO == null) { continue; } GameObject val = instance.FindInstance(lamp); if ((Object)(object)val != (Object)null) { ZNetView component = val.GetComponent<ZNetView>(); if (component != null) { component.ClaimOwnership(); } instance.Destroy(val); } else { zDO.SetOwner(sessionID); instance2.DestroyZDO(zDO); } num++; } return num; } private static float Apart(Job job) { return job.Order.Spacing * 0.55f; } private static float[] XsOf(RoadLine line) { float[] array = new float[line.Count]; for (int i = 0; i < array.Length; i++) { array[i] = line.XAt(i); } return array; } private static float[] ZsOf(RoadLine line) { float[] array = new float[line.Count]; for (int i = 0; i < array.Length; i++) { array[i] = line.ZAt(i); } return array; } private static string Lay(Job job, RoadLine piece, bool complete) { //IL_02ca: Unknown result type (might be due to invalid IL or missing references) //IL_02cf: Unknown result type (might be due to invalid IL or missing references) //IL_02ec: Unknown result type (might be due to invalid IL or missing references) //IL_030d: Unknown result type (might be due to invalid IL or missing references) //IL_0312: 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_033f: Unknown result type (might be due to invalid IL or missing references) //IL_0366: Unknown result type (might be due to invalid IL or missing references) if (ZDOMan.instance == null || (Object)(object)ZNetScene.instance == (Object)null) { return "сервер закрывается"; } try { float[] array = null; float[] array2 = null; List<Causeway.Stretch> list = null; bool flag = job.Order.Bridge && !job.Circle; if (!job.Order.Smooth || flag) { array = GroundUnder(piece); if (array != null) { array2 = Causeway.Raise(array, StepOf(piece), Floor()); } if (array2 != null) { list = Causeway.Spans(array, array2); } } float num = ((array2 != null) ? Mathf.Max(job.Reach, job.Half + RoadLevel.BlendFor(job.Half)) : job.Reach); bool flag2 = default(bool); List<TerrainComp> list2 = Ground.CompilersAlong(piece, num, true, ref flag2); if (list2 == null) { return flag2 ? "земля под куском не подгружена" : "рельеф зоны не поднялся на сервере"; } foreach (TerrainComp item in list2) { CheckLoadMethod?.Invoke(item, null); Remember(job.Record, item); } if (complete && (!job.Circle || job.Order.Clear)) { job.Cleared += Clearing.Along(piece, job.Half, job.Order.Clear, true, "Road clearing"); } job.Spanned = ((flag && complete && list != null) ? Bridge(job, piece, array, list, list2) : null); if (job.Order.Smooth) { job.ShortOf += Level(job, piece, list2, job.Spanned); } else if (list != null) { job.ShortOf += RaiseOver(job, piece, list2, array2, list, job.Spanned); } int num2 = 0; foreach (TerrainComp item2 in list2) { RoadPaint val = RoadPaint.Of(item2); if (val == null) { num2++; continue; } foreach (Causeway.Stretch item3 in Dry(piece.Count, job.Spanned)) { job.Painted += val.Stretch(piece, item3.First, item3.Last, job.Half, job.Paint); } } if (num2 > 0) { Plugin.Log.LogWarning((object)(job.Label + ": " + num2 + " of " + list2.Count + " compilers would not say what is under them; no paint there.")); } Vector3 val2 = PointAt(job, 0); float num3 = default(float); float num4 = default(float); float num5 = default(float); float num6 = default(float); piece.Bounds(ref num3, ref num4, ref num5, ref num6); ((Vector3)(ref val2))..ctor((num3 + num5) * 0.5f, val2.y, (num4 + num6) * 0.5f); Vector2 val3 = new Vector2(num5 - num3, num6 - num4); float num7 = ((Vector2)(ref val3)).magnitude * 0.5f + num + 2f; foreach (TerrainComp item4 in list2) { Ground.Note(item4, val2, num7); Ground.Save(item4); } Ground.Refresh(val2, num7 + 16f); return null; } catch (Exception ex) { Plugin.Log.LogError((object)(job.Label + ": a piece failed: " + ex)); return "ошибка на сервере, см. его лог"; } } private static float Floor() { if (!((Object)(object)ZoneSystem.instance != (Object)null)) { return float.MinValue; } return ZoneSystem.instance.m_waterLevel + 1f; } private static int Level(Job job, RoadLine piece, List<TerrainComp> comps, List<Causeway.Stretch> spanned = null) { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Expected O, but got Unknown float[] array = GroundUnder(piece); if (array == null) { return 0; } if (spanned == null || spanned.Count == 0) { return LevelAlong(job, piece, array, comps); } int num = 0; foreach (Causeway.Stretch item in Dry(piece.Count, spanned)) { if (item.Last > item.First) { RoadLine val = new RoadLine(); float[] array2 = new float[item.Last - item.First + 1]; for (int i = item.First; i <= item.Last; i++) { val.Add(piece.XAt(i), piece.ZAt(i)); array2[i - item.First] = array[i]; } num += LevelAlong(job, val, array2, comps); } } return num; } private static int LevelAlong(Job job, RoadLine piece, float[] ground, List<TerrainComp> comps) { //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_006c: 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_0080: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) float[] array = RoadLevel.Profile((IList<float>)ground, StepOf(piece), job.Half, Floor()); int num = 0; List<int> list = new List<int>(); Heightmap val2 = default(Heightmap); foreach (TerrainComp comp in comps) { Zone val = Ground.Heights(comp, ref val2); if (val != null) { Vector3 position = ((Component)val2).transform.position; float num2 = (float)(val.Size - 1) * 0.5f * val.Scale; piece.SegmentsNear(position.x - num2, position.z - num2, position.x + num2, position.z + num2, job.Reach, list); num += RoadLevel.Along(val, position.x, position.y, position.z, piece, list, array, job.Half, job.Blend, (Before)null); } } return num; } private static float[] GroundUnder(RoadLine piece) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) float[] array = new float[piece.Count]; float num = 0f; bool flag = false; float num2 = default(float); for (int i = 0; i < piece.Count; i++) { if (Heightmap.GetHeight(new Vector3(piece.XAt(i), 0f, piece.ZAt(i)), ref num2)) { num = num2; flag = true; } array[i] = num; } if (!flag) { return null; } return array; } private static float StepOf(RoadLine piece) { if (piece.Count <= 1) { return 0f; } return piece.Length / (float)(piece.Count - 1); } private static int RaiseOver(Job job, RoadLine piece, List<TerrainComp> comps, float[] raised, List<Causeway.Stretch> wet, List<Causeway.Stretch> spanned) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Expected O, but got Unknown //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: 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_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) float num = RoadLevel.BlendFor(job.Half); int num2 = 0; List<int> list = new List<int>(); Heightmap val3 = default(Heightmap); foreach (Causeway.Stretch item in wet) { if (spanned != null && spanned.Contains(item)) { continue; } RoadLine val = new RoadLine(); float[] array = new float[item.Last - item.First + 1]; for (int i = item.First; i <= item.Last; i++) { val.Add(piece.XAt(i), piece.ZAt(i)); array[i - item.First] = raised[i]; } foreach (TerrainComp comp in comps) { Zone val2 = Ground.Heights(comp, ref val3); if (val2 != null) { Vector3 position = ((Component)val3).transform.position; float num3 = (float)(val2.Size - 1) * 0.5f * val2.Scale; val.SegmentsNear(position.x - num3, position.z - num3, position.x + num3, position.z + num3, job.Half + num, list); num2 += RoadLevel.Along(val2, position.x, position.y, position.z, val, list, array, job.Half, num, (Before)null); } } job.Raised += ((val.Count > 1) ? val.Length : (job.Half * 2f)); } return num2; } private static List<Causeway.Stretch> Dry(int count, List<Causeway.Stretch> spanned) { List<Causeway.Stretch> list = new List<Causeway.Stretch>(); int num = 0; if (spanned != null) { foreach (Causeway.Stretch item in spanned) { list.Add(new Causeway.Stretch { First = num, Last = item.First }); num = item.Last; } } list.Add(new Causeway.Stretch { First = num, Last = Math.Max(num, count - 1) }); return list; } private static int PastWater(Job job, int last, int ahead) { WorldGenerator instance = WorldGenerator.instance; if (instance == null) { return last; } float num = Floor(); while (last < ahead && instance.GetHeight(job.X[last], job.Z[last]) < num) { last++; } return last; } private static List<Causeway.Stretch> Bridge(Job job, RoadLine piece, float[] under, List<Causeway.Stretch> wet, List<TerrainComp> comps) { //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) List<Causeway.Stretch> list = new List<Causeway.Stretch>(); ZNetScene instance = ZNetScene.instance; if ((Object)(object)instance == (Object)null || under == null) { return list; } int num = Mathf.Max(1, Mathf.RoundToInt(job.Order.Width / 2f)); foreach (Causeway.Stretch item in wet) { if (item.First == 0 || item.Last == piece.Count - 1) { continue; } float num2 = Between(piece, item.First, item.Last); if (num2 < 4f) { continue; } float deck = Mathf.Max(Mathf.Max(under[item.First], under[item.Last]), Floor()); Crossing crossing = null; string why = null; for (int i = Mathf.Max(1, Mathf.CeilToInt(num2 / 64f)); i <= 4; i++) { if (crossing != null) { break; } crossing = Plan(piece, under, item, deck, num, job.Order.BridgeRoof, i, out why); } if (crossing == null) { Plugin.Log.LogInfo((object)(job.Label + ": no bridge over " + Metres(num2) + " m of water — " + why + "; the fill takes it.")); continue; } float half = Mathf.Max(job.Half, (float)num * 2f * 0.5f); foreach (Causeway.Stretch island in crossing.Islands) { job.ShortOf += Island(job, piece, comps, island, deck, half); } int num3 = 0; foreach (Span bridge in crossing.Bridges) { num3 += Put(job, instan