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 SapTweaks v1.2.1
plugins/SapTweaks.dll
Decompiled an hour agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using ModHub; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyVersion("0.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 SapTweaks { internal static class HubUi { public const float RefHeight = 1080f; public static readonly Color Panel = new Color(0.075f, 0.066f, 0.052f, 0.95f); public static readonly Color Gold = new Color(0.86f, 0.71f, 0.42f); public static readonly Color GoldDim = new Color(0.52f, 0.42f, 0.27f); public static readonly Color TitleCol = new Color(0.72f, 0.49f, 0.16f); public static readonly Color HeaderCol = new Color(0.8f, 0.55f, 0.24f); public static readonly Color TextCol = new Color(0.87f, 0.84f, 0.78f); public static readonly Color StatusCol = new Color(0.47f, 0.44f, 0.39f); public static readonly Color DimText = new Color(0.52f, 0.49f, 0.43f); public static readonly Color ValueCol = new Color(0.55f, 0.47f, 0.34f); public static readonly Color BtnFill = new Color(0.15f, 0.13f, 0.1f, 1f); public static readonly Color BtnHover = new Color(0.21f, 0.18f, 0.13f, 1f); public static readonly Color BtnBorder = new Color(0.42f, 0.35f, 0.23f); public static readonly Color TrackCol = new Color(0.33f, 0.28f, 0.19f); public static readonly Color FillCol = new Color(0.84f, 0.71f, 0.43f); private static Font _serif; private static Font _serifBold; private static bool _fontsSearched; private static float _stylesScale = -1f; private static Texture2D _knob; private static GUIStyle _sliderBg; private static GUIStyle _thumb; public static GUIStyle TitleStyle; public static GUIStyle StatusStyle; public static GUIStyle HeaderStyle; public static GUIStyle LabelStyle; public static GUIStyle ValueStyle; public static GUIStyle HintStyle; public static GUIStyle FooterStyle; public static GUIStyle ButtonText; public static GUIStyle ButtonTextDim; public static GUIStyle IconText; public static float Scale { get; private set; } = 1f; public static float VirtualWidth => (float)Screen.width / Scale; private static bool Repaint => (int)Event.current.type == 7; public static void Begin() { Scale = Mathf.Max(0.5f, (float)Screen.height / 1080f); if (!_fontsSearched) { FindFonts(); } if (!Mathf.Approximately(_stylesScale, Scale)) { BuildStyles(); } Cursor.lockState = (CursorLockMode)0; Cursor.visible = true; } public static Rect S(Rect r) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) return new Rect(((Rect)(ref r)).x * Scale, ((Rect)(ref r)).y * Scale, ((Rect)(ref r)).width * Scale, ((Rect)(ref r)).height * Scale); } public static void RoundRect(Rect v, Color fill, float radius, Color border = default(Color), float borderW = 0f) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: 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_0032: 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_0055: 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_0078: Unknown result type (might be due to invalid IL or missing references) if (Repaint) { Rect val = S(v); float num = radius * Scale; if (fill.a > 0f) { GUI.DrawTexture(val, (Texture)(object)Texture2D.whiteTexture, (ScaleMode)0, true, 0f, fill, 0f, num); } if (borderW > 0f && border.a > 0f) { GUI.DrawTexture(val, (Texture)(object)Texture2D.whiteTexture, (ScaleMode)0, true, 0f, border, Mathf.Max(1f, borderW * Scale), num); } } } public static void Window(Rect v) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: 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_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_0082: Unknown result type (might be due to invalid IL or missing references) RoundRect(v, Panel, 26f, Gold, 4.5f); RoundRect(new Rect(((Rect)(ref v)).x + 22f, ((Rect)(ref v)).y + 22f, ((Rect)(ref v)).width - 44f, ((Rect)(ref v)).height - 44f), Color.clear, 16f, new Color(Gold.r, Gold.g, Gold.b, 0.35f), 1.5f); } public static void Label(Rect v, string text, GUIStyle style) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) GUI.Label(S(v), text, style); } public static bool IconButton(Rect v, string text) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: 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_001a: 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_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0032: 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_0056: Unknown result type (might be due to invalid IL or missing references) Rect val = S(v); bool flag = ((Rect)(ref val)).Contains(Event.current.mousePosition); RoundRect(v, flag ? BtnHover : BtnFill, 12f, flag ? Gold : BtnBorder, 2.5f); GUI.Label(val, text, IconText); return GUI.Button(val, GUIContent.none, GUIStyle.none); } public static bool Button(Rect v, string text, bool active) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0024: 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_0038: 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_0066: Unknown result type (might be due to invalid IL or missing references) Rect val = S(v); bool flag = active && ((Rect)(ref val)).Contains(Event.current.mousePosition); RoundRect(v, flag ? BtnHover : BtnFill, 12f, flag ? GoldDim : BtnBorder, 2.5f); GUI.Label(val, text, active ? ButtonText : ButtonTextDim); return GUI.Button(val, GUIContent.none, GUIStyle.none) && active; } public static bool Toggle(Rect row, bool value, string label, bool enabled = true) { //IL_0056: 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_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0099: 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) Rect v = default(Rect); ((Rect)(ref v))..ctor(((Rect)(ref row)).x, ((Rect)(ref row)).y + (((Rect)(ref row)).height - 38f) / 2f, 38f, 38f); if (value) { RoundRect(v, FillCol, 8f, GoldDim, 2f); } else { RoundRect(v, BtnFill, 8f, GoldDim, 2f); } Label(new Rect(((Rect)(ref v)).xMax + 20f, ((Rect)(ref row)).y, ((Rect)(ref row)).width - 58f, ((Rect)(ref row)).height), label, LabelStyle); if (enabled && GUI.Button(S(row), GUIContent.none, GUIStyle.none)) { return !value; } return value; } public static float Slider(Rect row, string label, float value, float min, float max, string valueText, bool enabled = true) { //IL_0033: 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_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0092: 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_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_019f: 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_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) float num = ((Rect)(ref row)).width * 0.42f; float num2 = ((Rect)(ref row)).width * 0.12f; Label(new Rect(((Rect)(ref row)).x, ((Rect)(ref row)).y, num, ((Rect)(ref row)).height), label, LabelStyle); Rect v = default(Rect); ((Rect)(ref v))..ctor(((Rect)(ref row)).x + num, ((Rect)(ref row)).y + ((Rect)(ref row)).height / 2f - 5f, ((Rect)(ref row)).width - num - num2 - 24f, 10f); RoundRect(v, TrackCol, 5f); float num3 = Mathf.InverseLerp(min, max, value); if (num3 > 0.001f) { RoundRect(new Rect(((Rect)(ref v)).x, ((Rect)(ref v)).y, Mathf.Max(10f, ((Rect)(ref v)).width * num3), ((Rect)(ref v)).height), FillCol, 5f); } float num4 = 36f; Rect r = default(Rect); ((Rect)(ref r))..ctor(((Rect)(ref v)).x - num4 / 2f, ((Rect)(ref row)).y + ((Rect)(ref row)).height / 2f - num4 / 2f, ((Rect)(ref v)).width + num4, num4); bool enabled2 = GUI.enabled; GUI.enabled = enabled2 && enabled; float result = GUI.HorizontalSlider(S(r), value, min, max, _sliderBg, _thumb); GUI.enabled = enabled2; Label(new Rect(((Rect)(ref row)).xMax - num2, ((Rect)(ref row)).y, num2, ((Rect)(ref row)).height), valueText, ValueStyle); return result; } public static int Choice(Rect row, string label, string valueText) { //IL_0023: 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_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Expected O, but got Unknown //IL_0151: 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_0163: 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) Label(new Rect(((Rect)(ref row)).x, ((Rect)(ref row)).y, ((Rect)(ref row)).width * 0.42f, ((Rect)(ref row)).height), label, LabelStyle); float num = ((Rect)(ref row)).width * 0.58f; Rect val = default(Rect); ((Rect)(ref val))..ctor(((Rect)(ref row)).xMax - num, ((Rect)(ref row)).y + 2f, num, ((Rect)(ref row)).height - 4f); int num2 = 0; if (IconButton(new Rect(((Rect)(ref val)).x, ((Rect)(ref val)).y, ((Rect)(ref val)).height, ((Rect)(ref val)).height), "<")) { num2 = -1; } if (IconButton(new Rect(((Rect)(ref val)).xMax - ((Rect)(ref val)).height, ((Rect)(ref val)).y, ((Rect)(ref val)).height, ((Rect)(ref val)).height), ">")) { num2 = 1; } Rect val2 = default(Rect); ((Rect)(ref val2))..ctor(((Rect)(ref val)).x + ((Rect)(ref val)).height + 10f, ((Rect)(ref val)).y, ((Rect)(ref val)).width - ((Rect)(ref val)).height * 2f - 20f, ((Rect)(ref val)).height); RoundRect(val2, BtnFill, 12f, BtnBorder, 2f); GUIStyle val3 = new GUIStyle(LabelStyle) { alignment = (TextAnchor)4 }; GUI.Label(S(val2), valueText, val3); if (num2 == 0 && GUI.Button(S(val2), GUIContent.none, GUIStyle.none)) { num2 = 1; } return num2; } public static string Mult(float v) { return "x" + v.ToString("0.0#").Replace('.', ','); } private static void FindFonts() { _fontsSearched = true; Font[] fonts = Resources.FindObjectsOfTypeAll<Font>(); _serif = Pick(new string[2] { "AveriaSerifLibre-Regular", "AveriaSerifLibre-Bold" }); _serifBold = Pick(new string[2] { "AveriaSerifLibre-Bold", "AveriaSerifLibre-Regular" }); if ((Object)(object)_serif == (Object)null) { SapTweaksPlugin.Log.LogWarning((object)"Шрифт AveriaSerifLibre не найден, используется стандартный"); } Font Pick(params string[] names) { return names.Select((string n) => ((IEnumerable<Font>)fonts).FirstOrDefault((Func<Font, bool>)((Font f) => (Object)(object)f != (Object)null && ((Object)f).name.Equals(n, StringComparison.OrdinalIgnoreCase)))).FirstOrDefault<Font>((Func<Font, bool>)((Font f) => (Object)(object)f != (Object)null)); } } private static void BuildStyles() { //IL_0012: 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_0042: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0081: 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_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: 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_012a: 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_0146: Expected O, but got Unknown //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Expected O, but got Unknown //IL_0107: 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) _stylesScale = Scale; TitleStyle = T(_serifBold, 62, TitleCol, (TextAnchor)4, (FontStyle)3); ValueStyle = T(_serif, 22, ValueCol, (TextAnchor)5, (FontStyle)2); HintStyle = T(_serif, 20, ValueCol, (TextAnchor)3, (FontStyle)2); FooterStyle = T(_serif, 20, ValueCol, (TextAnchor)4, (FontStyle)2); IconText = T(_serifBold, 30, new Color(0.9f, 0.86f, 0.76f), (TextAnchor)4, (FontStyle)3); StatusStyle = T(null, 22, StatusCol, (TextAnchor)3, (FontStyle)0); HeaderStyle = T(null, 32, HeaderCol, (TextAnchor)3, (FontStyle)1); LabelStyle = T(null, 25, TextCol, (TextAnchor)3, (FontStyle)0); ButtonText = T(null, 28, TextCol, (TextAnchor)4, (FontStyle)1); ButtonTextDim = T(null, 28, DimText, (TextAnchor)4, (FontStyle)1); if ((Object)(object)_knob == (Object)null) { _knob = Circle(64, FillCol, new Color(0.6f, 0.49f, 0.28f)); } _sliderBg = new GUIStyle { fixedHeight = 36f * Scale }; _thumb = new GUIStyle { fixedWidth = 36f * Scale, fixedHeight = 36f * Scale }; GUIStyleState normal = _thumb.normal; GUIStyleState hover = _thumb.hover; Texture2D val = (_thumb.active.background = _knob); Texture2D background = (hover.background = val); normal.background = background; } private static GUIStyle T(Font font, int size, Color color, TextAnchor anchor, FontStyle style = (FontStyle)0) { //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_0023: 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_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) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Expected O, but got Unknown //IL_006b: 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_006d: 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) //IL_0076: 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) GUIStyle val = new GUIStyle { font = (((Object)(object)font != (Object)null) ? font : GUI.skin.font), fontSize = Mathf.RoundToInt((float)size * Scale), alignment = anchor, fontStyle = style, wordWrap = false, clipping = (TextClipping)0 }; GUIStyleState normal = val.normal; GUIStyleState hover = val.hover; Color val2 = (val.active.textColor = color); Color textColor = (hover.textColor = val2); normal.textColor = textColor; return val; } private static Texture2D Circle(int size, Color fill, Color rim) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0068: 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_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(size, size, (TextureFormat)4, false) { filterMode = (FilterMode)1, wrapMode = (TextureWrapMode)1 }; float num = (float)size / 2f - 1f; for (int i = 0; i < size; i++) { for (int j = 0; j < size; j++) { Vector2 val2 = new Vector2((float)j + 0.5f - (float)size / 2f, (float)i + 0.5f - (float)size / 2f); float magnitude = ((Vector2)(ref val2)).magnitude; Color val3 = Color.Lerp(fill, rim, Mathf.Clamp01(magnitude - (num - 4f))); val3.a = Mathf.Clamp01(num - magnitude + 0.5f); val.SetPixel(j, i, val3); } } val.Apply(); return val; } } internal static class Loc { private enum Lang { En, Ru, Uk } private static readonly Dictionary<string, string[]> Texts = new Dictionary<string, string[]> { ["status_menu"] = new string[3] { "Main menu — settings will be saved to the config.", "Главное меню — настройки сохранятся в конфиг.", "Головне меню — налаштування збережуться в конфіг." }, ["status_host"] = new string[3] { "You are the host — settings apply to all players.", "Ты хост — настройки применяются ко всем игрокам.", "Ти хост — налаштування застосовуються до всіх гравців." }, ["status_client"] = new string[3] { "Settings are set by the host — view only.", "Настройки задаёт хост — только просмотр.", "Налаштування задає хост — лише перегляд." }, ["status_wait"] = new string[3] { "Waiting for settings from the host…", "Ожидание настроек от хоста…", "Очікування налаштувань від хоста…" }, ["enabled"] = new string[3] { "Mod enabled", "Мод включён", "Мод увімкнено" }, ["roots"] = new string[3] { "Yggdrasil roots", "Корни Иггдрасиля", "Коріння Іґґдрасиля" }, ["infinite"] = new string[3] { "Infinite roots", "Бесконечные корни", "Нескінченне коріння" }, ["capacity"] = new string[3] { "Root capacity", "Запас в корне", "Запас у корені" }, ["regen"] = new string[3] { "Regeneration", "Восстановление", "Відновлення" }, ["extractor"] = new string[3] { "Sap extractor", "Экстрактор живицы", "Екстрактор живиці" }, ["speed"] = new string[3] { "Extraction speed", "Скорость добычи", "Швидкість видобутку" }, ["ext_capacity"] = new string[3] { "Capacity", "Вместимость", "Місткість" }, ["vanilla"] = new string[3] { "vanilla", "ваниль", "ваніль" }, ["vanilla_hint"] = new string[3] { "(vanilla: {0})", "(ваниль: {0})", "(ваніль: {0})" }, ["btn_vanilla"] = new string[3] { "Vanilla", "Ванилла", "Ваніла" }, ["btn_cancel"] = new string[3] { "Cancel", "Отменить", "Скасувати" }, ["btn_apply"] = new string[3] { "Apply", "Применить", "Застосувати" }, ["footer"] = new string[3] { "Esc — close", "Esc — закрыть", "Esc — закрити" }, ["language"] = new string[3] { "Language", "Язык", "Мова" }, ["lang_auto"] = new string[3] { "Auto (game)", "Авто (как в игре)", "Авто (як у грі)" }, ["hub_desc"] = new string[3] { "Sap: root capacity, infinite roots, extractor", "Живица: запас корней, бесконечные корни, экстрактор", "Живиця: запас коріння, нескінченне коріння, екстрактор" } }; public static readonly string[] Options = new string[4] { "Auto", "English", "Russian", "Ukrainian" }; private static Func<string> _getGameLang; private static bool _searched; private static Lang Current { get { string text = SapTweaksPlugin.CfgLanguage?.Value ?? "Auto"; if (text == "Auto") { text = GameLanguage(); } string text2 = text; string text3 = text2; if (!(text3 == "Russian")) { if (text3 == "Ukrainian") { return Lang.Uk; } return Lang.En; } return Lang.Ru; } } public static string OptionName(string opt) { return opt switch { "English" => "English", "Russian" => "Русский", "Ukrainian" => "Українська", _ => T("lang_auto"), }; } private static string GameLanguage() { if (!_searched) { _searched = true; try { Type type = AppDomain.CurrentDomain.GetAssemblies().Select(delegate(Assembly a) { try { return a.GetType("Localization", throwOnError: false); } catch { return (Type)null; } }).FirstOrDefault((Type t) => t != null); PropertyInfo inst = type?.GetProperty("instance", BindingFlags.Static | BindingFlags.Public); FieldInfo instField = type?.GetField("m_instance", BindingFlags.Static | BindingFlags.NonPublic); MethodInfo method = type?.GetMethod("GetSelectedLanguage", BindingFlags.Instance | BindingFlags.Public); if (method != null && (inst != null || instField != null)) { _getGameLang = delegate { object obj2 = ((inst != null) ? inst.GetValue(null) : instField.GetValue(null)); return (obj2 != null) ? (method.Invoke(obj2, null) as string) : null; }; } else { SapTweaksPlugin.Log.LogWarning((object)"Localization.GetSelectedLanguage не найден, язык берётся из PlayerPrefs"); } } catch (Exception ex) { SapTweaksPlugin.Log.LogWarning((object)("Не удалось определить язык игры: " + ex.Message)); } } string text = null; try { text = _getGameLang?.Invoke(); } catch { } if (string.IsNullOrEmpty(text)) { text = PlayerPrefs.GetString("language", "English"); } return text; } public static string T(string key) { string[] value; return Texts.TryGetValue(key, out value) ? value[(int)Current] : key; } public static string T(string key, object arg) { return string.Format(T(key), arg); } } internal static class ModHubBridge { public const string ModHubGUID = "kaefchik.modhub"; private const string HubId = "saptweaks"; private static Sprite _icon; internal static void Register() { ModHubAPI.Register("saptweaks", "Sap", (Action)SapMenu.Open, (string)null, LoadIcon(), (Color?)null, Loc.T("hub_desc"), 60, (Func<bool>)null, (Action)SapMenu.Close, (Func<bool>)(() => SapMenu.Visible)); } internal static void SetInputBlock(bool blocked) { ModHubAPI.SetInputBlock("saptweaks", blocked); } private static Sprite LoadIcon() { //IL_0060: 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_0073: Expected O, but got Unknown //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_icon != (Object)null) { return _icon; } using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("SapTweaks.icon.png")) { if (stream == null) { SapTweaksPlugin.Log.LogWarning((object)"icon.png не найден в ресурсах"); return null; } MemoryStream memoryStream = new MemoryStream(); stream.CopyTo(memoryStream); Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false) { name = "SapTweaksIcon" }; ImageConversion.LoadImage(val, memoryStream.ToArray()); _icon = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f)); } return _icon; } } [BepInPlugin("brat.saptweaks", "SapTweaks", "1.2.1")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class SapTweaksPlugin : BaseUnityPlugin { public const string GUID = "brat.saptweaks"; public const string NAME = "SapTweaks"; public const string VERSION = "1.2.1"; internal static SapTweaksPlugin Instance; internal static ManualLogSource Log; internal static ConfigEntry<string> CfgLanguage; internal static ConfigEntry<bool> CfgEnabled; internal static ConfigEntry<bool> CfgInfinite; internal static ConfigEntry<int> CfgRootCapacity; internal static ConfigEntry<float> CfgRegenMultiplier; internal static ConfigEntry<float> CfgExtractorSpeed; internal static ConfigEntry<int> CfgExtractorCapacity; private static float _pendingSyncAt = -1f; private Harmony _harmony; private void Awake() { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Expected O, but got Unknown //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Expected O, but got Unknown //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Expected O, but got Unknown //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Expected O, but got Unknown //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Expected O, but got Unknown //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; CfgLanguage = ((BaseUnityPlugin)this).Config.Bind<string>("Общее", "Язык", "Auto", new ConfigDescription("Язык окна (личная настройка, не синхронизируется).", (AcceptableValueBase)(object)new AcceptableValueList<string>(Loc.Options), Array.Empty<object>())); CfgEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Общее", "Мод включён", true, "Выключено = всё как в ванили."); CfgInfinite = ((BaseUnityPlugin)this).Config.Bind<bool>("Корни", "Бесконечные корни", false, "Корни Иггдрасиля никогда не истощаются."); CfgRootCapacity = ((BaseUnityPlugin)this).Config.Bind<int>("Корни", "Запас живицы в корне", 0, new ConfigDescription("Максимальный запас каждого корня. 0 = ванильное значение.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100000), Array.Empty<object>())); CfgRegenMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Корни", "Множитель восстановления", 1f, new ConfigDescription("Скорость восстановления запаса корня (1 = ваниль).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), Array.Empty<object>())); CfgExtractorSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Экстрактор", "Множитель скорости", 1f, new ConfigDescription("Как быстро экстрактор качает живицу (2 = в два раза быстрее).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 100f), Array.Empty<object>())); CfgExtractorCapacity = ((BaseUnityPlugin)this).Config.Bind<int>("Экстрактор", "Вместимость", 0, new ConfigDescription("Сколько живицы помещается в экстрактор. 0 = ваниль.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 1000), Array.Empty<object>())); ((BaseUnityPlugin)this).Config.SettingChanged += delegate(object _, SettingChangedEventArgs e) { if ((object)e.ChangedSetting != CfgLanguage) { _pendingSyncAt = Time.unscaledTime + 0.4f; } }; Sync.ResetToLocal(); _harmony = new Harmony("brat.saptweaks"); _harmony.PatchAll(typeof(SapTweaksPlugin).Assembly); RootPatches.Apply(_harmony); ((Component)this).gameObject.AddComponent<SapMenu>(); ModHubBridge.Register(); Log.LogInfo((object)"SapTweaks 1.2.1 загружен"); } private void Update() { if (_pendingSyncAt > 0f && Time.unscaledTime >= _pendingSyncAt) { _pendingSyncAt = -1f; Sync.OnLocalConfigChanged(); } } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } } internal static class RootPatches { internal static float? VanillaRootMax; internal static float? VanillaRegen; internal static float? VanillaSecPerUnit; internal static int? VanillaExtractorMax; private static readonly FieldInfo F_RootMax = AccessTools.Field(typeof(ResourceRoot), "m_maxLevel"); private static readonly FieldInfo F_RootRegen = AccessTools.Field(typeof(ResourceRoot), "m_regenPerSec"); private static readonly FieldInfo F_SecPerUnit = AccessTools.Field(typeof(SapCollector), "m_secPerUnit"); private static readonly FieldInfo F_ExtractorMax = AccessTools.Field(typeof(SapCollector), "m_maxLevel"); internal static void Apply(Harmony h) { //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Expected O, but got Unknown Type typeFromHandle = typeof(RootPatches); TryPatch(h, typeof(ResourceRoot), "Awake", null, typeFromHandle.GetMethod("RootAwakePostfix", BindingFlags.Static | BindingFlags.NonPublic)); TryPatch(h, typeof(SapCollector), "Awake", null, typeFromHandle.GetMethod("CollectorAwakePostfix", BindingFlags.Static | BindingFlags.NonPublic)); TryPatch(h, typeof(ResourceRoot), "CanDrain", typeFromHandle.GetMethod("CanDrainPrefix", BindingFlags.Static | BindingFlags.NonPublic)); MethodInfo methodInfo = AccessTools.Method(typeof(ResourceRoot), "Drain", (Type[])null, (Type[])null); if (methodInfo != null) { string name = ((methodInfo.ReturnType == typeof(bool)) ? "DrainPrefixBool" : "DrainPrefixVoid"); h.Patch((MethodBase)methodInfo, new HarmonyMethod(typeFromHandle.GetMethod(name, BindingFlags.Static | BindingFlags.NonPublic)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } else { SapTweaksPlugin.Log.LogWarning((object)"ResourceRoot.Drain не найден — бесконечные корни не будут работать"); } if (F_RootMax == null) { SapTweaksPlugin.Log.LogWarning((object)"ResourceRoot.m_maxLevel не найден"); } if (F_RootRegen == null) { SapTweaksPlugin.Log.LogWarning((object)"ResourceRoot.m_regenPerSec не найден"); } if (F_SecPerUnit == null) { SapTweaksPlugin.Log.LogWarning((object)"SapCollector.m_secPerUnit не найден"); } if (F_ExtractorMax == null) { SapTweaksPlugin.Log.LogWarning((object)"SapCollector.m_maxLevel не найден"); } } private static void TryPatch(Harmony h, Type type, string method, MethodInfo prefix = null, MethodInfo postfix = null) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) MethodInfo methodInfo = AccessTools.Method(type, method, (Type[])null, (Type[])null); if (methodInfo == null) { SapTweaksPlugin.Log.LogWarning((object)(type.Name + "." + method + " не найден, патч пропущен")); } else { h.Patch((MethodBase)methodInfo, (!(prefix != null)) ? ((HarmonyMethod)null) : new HarmonyMethod(prefix), (!(postfix != null)) ? ((HarmonyMethod)null) : new HarmonyMethod(postfix), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } private static void RootAwakePostfix(ResourceRoot __instance) { ApplyRoot(__instance); } private static void CollectorAwakePostfix(SapCollector __instance) { ApplyCollector(__instance); } private static bool CanDrainPrefix(ref bool __result) { if (!Sync.Effective.Infinite) { return true; } __result = true; return false; } private static bool DrainPrefixBool(ref bool __result) { if (!Sync.Effective.Infinite) { return true; } __result = true; return false; } private static bool DrainPrefixVoid() { return !Sync.Effective.Infinite; } internal static void CaptureVanillaFromPrefabs() { if ((Object)(object)ZNetScene.instance == (Object)null || (VanillaRootMax.HasValue && VanillaRegen.HasValue && VanillaSecPerUnit.HasValue && VanillaExtractorMax.HasValue)) { return; } foreach (GameObject prefab in ZNetScene.instance.m_prefabs) { if ((Object)(object)prefab == (Object)null) { continue; } ResourceRoot component = prefab.GetComponent<ResourceRoot>(); if ((Object)(object)component != (Object)null) { if (!VanillaRootMax.HasValue && F_RootMax != null) { VanillaRootMax = Convert.ToSingle(F_RootMax.GetValue(component)); } if (!VanillaRegen.HasValue && F_RootRegen != null) { VanillaRegen = Convert.ToSingle(F_RootRegen.GetValue(component)); } } SapCollector component2 = prefab.GetComponent<SapCollector>(); if ((Object)(object)component2 != (Object)null) { if (!VanillaSecPerUnit.HasValue && F_SecPerUnit != null) { VanillaSecPerUnit = Convert.ToSingle(F_SecPerUnit.GetValue(component2)); } if (!VanillaExtractorMax.HasValue && F_ExtractorMax != null) { VanillaExtractorMax = Convert.ToInt32(F_ExtractorMax.GetValue(component2)); } } } } internal static void ApplyAll() { if (!((Object)(object)ZNet.instance == (Object)null)) { CaptureVanillaFromPrefabs(); ResourceRoot[] array = Object.FindObjectsByType<ResourceRoot>((FindObjectsSortMode)0); foreach (ResourceRoot root in array) { ApplyRoot(root); } SapCollector[] array2 = Object.FindObjectsByType<SapCollector>((FindObjectsSortMode)0); foreach (SapCollector col in array2) { ApplyCollector(col); } } } private static void ApplyRoot(ResourceRoot root) { if ((Object)(object)root == (Object)null) { return; } SapSettings effective = Sync.Effective; if (F_RootMax != null) { if (!VanillaRootMax.HasValue) { VanillaRootMax = Convert.ToSingle(F_RootMax.GetValue(root)); } float num = ((effective.RootCapacity > 0) ? ((float)effective.RootCapacity) : VanillaRootMax.Value); F_RootMax.SetValue(root, Convert.ChangeType(num, F_RootMax.FieldType)); } if (F_RootRegen != null) { if (!VanillaRegen.HasValue) { VanillaRegen = Convert.ToSingle(F_RootRegen.GetValue(root)); } F_RootRegen.SetValue(root, VanillaRegen.Value * effective.RegenMultiplier); } } private static void ApplyCollector(SapCollector col) { if ((Object)(object)col == (Object)null) { return; } SapSettings effective = Sync.Effective; if (F_SecPerUnit != null) { if (!VanillaSecPerUnit.HasValue) { VanillaSecPerUnit = Convert.ToSingle(F_SecPerUnit.GetValue(col)); } F_SecPerUnit.SetValue(col, VanillaSecPerUnit.Value / Mathf.Max(0.1f, effective.ExtractorSpeed)); } if (F_ExtractorMax != null) { if (!VanillaExtractorMax.HasValue) { VanillaExtractorMax = Convert.ToInt32(F_ExtractorMax.GetValue(col)); } int num = ((effective.ExtractorCapacity > 0) ? effective.ExtractorCapacity : VanillaExtractorMax.Value); F_ExtractorMax.SetValue(col, Convert.ChangeType(num, F_ExtractorMax.FieldType)); } } } internal class SapMenu : MonoBehaviour { private static SapSettings _draft; private const float W = 860f; private float _height = 900f; internal static bool Visible { get; private set; } internal static void Open() { SetVisible(v: true); } internal static void Close() { SetVisible(v: false); } internal static void Toggle() { SetVisible(!Visible); } private static void SetVisible(bool v) { if (Visible != v) { Visible = v; if (v) { RootPatches.CaptureVanillaFromPrefabs(); _draft = CurrentSaved(); } ModHubBridge.SetInputBlock(v); } } private static SapSettings CurrentSaved() { return Sync.CanEdit ? SapSettings.FromConfig() : Sync.Active.Clone(); } private void Update() { if (Visible && Input.GetKeyDown((KeyCode)27)) { Close(); } } private void OnGUI() { //IL_0094: 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) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_0141: 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_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_0244: Unknown result type (might be due to invalid IL or missing references) //IL_028f: Unknown result type (might be due to invalid IL or missing references) //IL_02c3: 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_03de: Unknown result type (might be due to invalid IL or missing references) //IL_040f: Unknown result type (might be due to invalid IL or missing references) //IL_0484: Unknown result type (might be due to invalid IL or missing references) //IL_04b3: Unknown result type (might be due to invalid IL or missing references) //IL_055a: Unknown result type (might be due to invalid IL or missing references) //IL_05dc: Unknown result type (might be due to invalid IL or missing references) //IL_0627: Unknown result type (might be due to invalid IL or missing references) //IL_0674: Unknown result type (might be due to invalid IL or missing references) //IL_06ac: Unknown result type (might be due to invalid IL or missing references) //IL_06f1: Unknown result type (might be due to invalid IL or missing references) if (Visible) { GUI.depth = -1000; HubUi.Begin(); bool canEdit = Sync.CanEdit; if (!canEdit) { _draft = Sync.Active.Clone(); } SapSettings sapSettings = CurrentSaved(); bool active = canEdit && !_draft.SameAs(sapSettings); Rect v = default(Rect); ((Rect)(ref v))..ctor((HubUi.VirtualWidth - 860f) / 2f, (1080f - _height) / 2f, 860f, _height); HubUi.Window(v); if (HubUi.IconButton(new Rect(((Rect)(ref v)).x + 38f, ((Rect)(ref v)).y + 38f, 52f, 52f), "<")) { Close(); ModHubAPI.OpenHub(); } if (HubUi.IconButton(new Rect(((Rect)(ref v)).xMax - 90f, ((Rect)(ref v)).y + 38f, 52f, 52f), "X")) { Close(); } HubUi.Label(new Rect(((Rect)(ref v)).x, ((Rect)(ref v)).y + 34f, ((Rect)(ref v)).width, 80f), "SAP", HubUi.TitleStyle); float num = ((Rect)(ref v)).x + 82f; float num2 = ((Rect)(ref v)).width - 164f; float num3 = ((Rect)(ref v)).y + 140f; HubUi.Label(new Rect(num, num3, num2, 36f), StatusText(), HubUi.StatusStyle); num3 += 58f; string[] options = Loc.Options; int num4 = Array.IndexOf(options, SapTweaksPlugin.CfgLanguage.Value); if (num4 < 0) { num4 = 0; } int num5 = HubUi.Choice(new Rect(num, num3, num2, 50f), Loc.T("language"), Loc.OptionName(options[num4])); if (num5 != 0) { SapTweaksPlugin.CfgLanguage.Value = options[(num4 + num5 + options.Length) % options.Length]; } num3 += 70f; _draft.Enabled = HubUi.Toggle(new Rect(num, num3, num2, 50f), _draft.Enabled, Loc.T("enabled"), canEdit); num3 += 78f; bool flag = canEdit && _draft.Enabled; HubUi.Label(new Rect(num, num3, num2, 44f), Loc.T("roots"), HubUi.HeaderStyle); num3 += 62f; _draft.Infinite = HubUi.Toggle(new Rect(num, num3, num2, 50f), _draft.Infinite, Loc.T("infinite"), flag); num3 += 68f; bool flag2 = flag && !_draft.Infinite; string arg = (RootPatches.VanillaRootMax.HasValue ? RootPatches.VanillaRootMax.Value.ToString("0") : "?"); float num6 = HubUi.Slider(new Rect(num, num3, num2, 50f), Loc.T("capacity"), _draft.RootCapacity, 0f, 2000f, _draft.Infinite ? "∞" : ((_draft.RootCapacity == 0) ? Loc.T("vanilla") : _draft.RootCapacity.ToString()), flag2); if (flag2) { _draft.RootCapacity = Mathf.RoundToInt(num6 / 10f) * 10; } num3 += 50f; HubUi.Label(new Rect(num, num3, num2, 30f), Loc.T("vanilla_hint", arg), HubUi.HintStyle); num3 += 52f; float num7 = HubUi.Slider(new Rect(num, num3, num2, 50f), Loc.T("regen"), _draft.RegenMultiplier, 0f, 10f, HubUi.Mult(_draft.RegenMultiplier), flag2); if (flag2) { _draft.RegenMultiplier = Mathf.Round(num7 * 10f) / 10f; } num3 += 82f; HubUi.Label(new Rect(num, num3, num2, 44f), Loc.T("extractor"), HubUi.HeaderStyle); num3 += 62f; float num8 = HubUi.Slider(new Rect(num, num3, num2, 50f), Loc.T("speed"), _draft.ExtractorSpeed, 0.1f, 10f, HubUi.Mult(_draft.ExtractorSpeed), flag); if (flag) { _draft.ExtractorSpeed = Mathf.Max(0.1f, Mathf.Round(num8 * 10f) / 10f); } num3 += 66f; string arg2 = (RootPatches.VanillaExtractorMax.HasValue ? RootPatches.VanillaExtractorMax.Value.ToString() : "?"); float num9 = HubUi.Slider(new Rect(num, num3, num2, 50f), Loc.T("ext_capacity"), _draft.ExtractorCapacity, 0f, 200f, (_draft.ExtractorCapacity == 0) ? Loc.T("vanilla") : _draft.ExtractorCapacity.ToString(), flag); if (flag) { _draft.ExtractorCapacity = Mathf.RoundToInt(num9); } num3 += 50f; HubUi.Label(new Rect(num, num3, num2, 30f), Loc.T("vanilla_hint", arg2), HubUi.HintStyle); num3 += 70f; float num10 = 24f; float num11 = (num2 - num10 * 2f) / 3f; if (HubUi.Button(new Rect(num, num3, num11, 66f), Loc.T("btn_vanilla"), canEdit)) { SapSettings vanilla = SapSettings.Vanilla; vanilla.Enabled = _draft.Enabled; _draft = vanilla; } if (HubUi.Button(new Rect(num + num11 + num10, num3, num11, 66f), Loc.T("btn_cancel"), active)) { _draft = sapSettings; } if (HubUi.Button(new Rect(num + (num11 + num10) * 2f, num3, num11, 66f), Loc.T("btn_apply"), active)) { _draft.SaveToConfig(); } num3 += 82f; HubUi.Label(new Rect(((Rect)(ref v)).x, num3, ((Rect)(ref v)).width, 30f), Loc.T("footer"), HubUi.FooterStyle); num3 += 60f; _height = num3 - ((Rect)(ref v)).y; } } private static string StatusText() { if (!Sync.InWorld) { return Loc.T("status_menu"); } if (Sync.IsServer) { return Loc.T("status_host"); } return Sync.FromServer ? Loc.T("status_client") : Loc.T("status_wait"); } } internal class SapSettings { public bool Enabled = true; public bool Infinite; public int RootCapacity; public float RegenMultiplier = 1f; public float ExtractorSpeed = 1f; public int ExtractorCapacity; public static SapSettings Vanilla => new SapSettings(); public SapSettings Clone() { return (SapSettings)MemberwiseClone(); } public bool SameAs(SapSettings o) { return o != null && Enabled == o.Enabled && Infinite == o.Infinite && RootCapacity == o.RootCapacity && Mathf.Approximately(RegenMultiplier, o.RegenMultiplier) && Mathf.Approximately(ExtractorSpeed, o.ExtractorSpeed) && ExtractorCapacity == o.ExtractorCapacity; } public static SapSettings FromConfig() { return new SapSettings { Enabled = SapTweaksPlugin.CfgEnabled.Value, Infinite = SapTweaksPlugin.CfgInfinite.Value, RootCapacity = SapTweaksPlugin.CfgRootCapacity.Value, RegenMultiplier = SapTweaksPlugin.CfgRegenMultiplier.Value, ExtractorSpeed = SapTweaksPlugin.CfgExtractorSpeed.Value, ExtractorCapacity = SapTweaksPlugin.CfgExtractorCapacity.Value }; } public void SaveToConfig() { SapTweaksPlugin.CfgEnabled.Value = Enabled; SapTweaksPlugin.CfgInfinite.Value = Infinite; SapTweaksPlugin.CfgRootCapacity.Value = RootCapacity; SapTweaksPlugin.CfgRegenMultiplier.Value = RegenMultiplier; SapTweaksPlugin.CfgExtractorSpeed.Value = ExtractorSpeed; SapTweaksPlugin.CfgExtractorCapacity.Value = ExtractorCapacity; } public void Write(ZPackage p) { p.Write(2); p.Write(Infinite); p.Write(RootCapacity); p.Write(RegenMultiplier); p.Write(ExtractorSpeed); p.Write(ExtractorCapacity); p.Write(Enabled); } public static SapSettings Read(ZPackage p) { int num = p.ReadInt(); SapSettings sapSettings = new SapSettings { Infinite = p.ReadBool(), RootCapacity = p.ReadInt(), RegenMultiplier = p.ReadSingle(), ExtractorSpeed = p.ReadSingle(), ExtractorCapacity = p.ReadInt() }; if (num >= 2) { sapSettings.Enabled = p.ReadBool(); } return sapSettings; } } internal static class Sync { private const string RPC_SYNC = "SapTweaks_Sync"; private const string RPC_REQUEST = "SapTweaks_Request"; internal static SapSettings Active = new SapSettings(); internal static SapSettings Effective => Active.Enabled ? Active : SapSettings.Vanilla; internal static bool FromServer { get; private set; } internal static bool IsServer => (Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer(); internal static bool InWorld => (Object)(object)ZNet.instance != (Object)null; internal static bool CanEdit => !InWorld || IsServer; internal static void ResetToLocal() { Active = SapSettings.FromConfig(); FromServer = false; RootPatches.ApplyAll(); } internal static void RegisterRpcs() { ZRoutedRpc.instance.Register<ZPackage>("SapTweaks_Sync", (Action<long, ZPackage>)OnSync); ZRoutedRpc.instance.Register("SapTweaks_Request", (Action<long>)OnRequest); } internal static void OnLocalConfigChanged() { if (!InWorld || IsServer) { Active = SapSettings.FromConfig(); RootPatches.ApplyAll(); if (IsServer && ZRoutedRpc.instance != null) { Send(0L); } } } internal static void RequestFromServer() { if (!IsServer && ZRoutedRpc.instance != null) { ZRoutedRpc.instance.InvokeRoutedRPC(0L, "SapTweaks_Request", Array.Empty<object>()); } } private static void Send(long target) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown ZPackage val = new ZPackage(); Active.Write(val); ZRoutedRpc.instance.InvokeRoutedRPC(target, "SapTweaks_Sync", new object[1] { val }); } private static void OnRequest(long sender) { if (IsServer) { Send(sender); } } private static void OnSync(long sender, ZPackage pkg) { if (!IsServer) { Active = SapSettings.Read(pkg); FromServer = true; RootPatches.ApplyAll(); SapTweaksPlugin.Log.LogInfo((object)"Получены настройки живицы с сервера"); } } } [HarmonyPatch(typeof(ZNet), "Awake")] internal static class ZNetAwakePatch { private static void Postfix() { Sync.ResetToLocal(); Sync.RegisterRpcs(); } } [HarmonyPatch(typeof(ZNet), "OnDestroy")] internal static class ZNetDestroyPatch { private static void Postfix() { Sync.ResetToLocal(); } } [HarmonyPatch(typeof(Player), "OnSpawned")] internal static class PlayerSpawnPatch { private static void Postfix(Player __instance) { if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer) { Sync.RequestFromServer(); } } } }