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 Terrainer v1.0.8
plugins/Terrainer.dll
Decompiled 2 months agousing System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using ExampleCallMethodMod.Utils; using HarmonyLib; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: IgnoresAccessChecksTo("assembly_googleanalytics")] [assembly: IgnoresAccessChecksTo("assembly_guiutils")] [assembly: IgnoresAccessChecksTo("assembly_lux")] [assembly: IgnoresAccessChecksTo("assembly_postprocessing")] [assembly: IgnoresAccessChecksTo("assembly_simplemeshcombine")] [assembly: IgnoresAccessChecksTo("assembly_sunshafts")] [assembly: IgnoresAccessChecksTo("assembly_utils")] [assembly: IgnoresAccessChecksTo("assembly_valheim")] [assembly: IgnoresAccessChecksTo("gui_framework")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("Terrainer")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.8.0")] [assembly: AssemblyInformationalVersion("1.0.8+e2a8511ea022dec2d2b33283399cadecd56412f4")] [assembly: AssemblyProduct("Terrainer")] [assembly: AssemblyTitle("Terrainer")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.8.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [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 ExampleCallMethodMod { [BepInPlugin("com.github.terrainer.Terrainer", "Terrainer", "1.0.8.0")] public class Mod : BaseUnityPlugin { private static readonly Harmony harmony = new Harmony("com.github.terrainer.Terrainer"); public const string LevelPieceName = "Terrainer_LevelToHeight"; public const string LevelPieceSquareName = "Terrainer_LevelToHeightSquare"; public const string PieceNamePrefix = "Terrainer_LevelToHeight"; public static readonly Dictionary<string, GhostVisualInfo> GhostVisuals = new Dictionary<string, GhostVisualInfo>(); public const string PluginAuthor = "Terrainer"; public const string PluginGuid = "com.github.terrainer.Terrainer"; public const string PluginName = "Terrainer"; public const string PluginVersion = "1.0.8.0"; public static ConfigEntry<float> Radius { get; private set; } public static ConfigEntry<float> HeightStep { get; private set; } public static ConfigEntry<float> HeightStepLarge { get; private set; } public static ConfigEntry<float> RadiusStep { get; private set; } public static ConfigEntry<bool> ConsumeRocks { get; private set; } public static ConfigEntry<float> RocksPerCubicMeter { get; private set; } public static float TargetHeight { get; set; } public static bool HasTargetHeight { get; set; } public static float CurrentRadius { get; set; } public static ManualLogSource Log { get; private set; } private void Awake() { Radius = ((BaseUnityPlugin)this).Config.Bind<float>("Leveler", "Radius", 4f, "Начальный радиус выравнивания (меняется Shift+колесо в игре)."); HeightStep = ((BaseUnityPlugin)this).Config.Bind<float>("Leveler", "HeightStep", 0.25f, "Шаг изменения высоты (Q/E)."); HeightStepLarge = ((BaseUnityPlugin)this).Config.Bind<float>("Leveler", "HeightStepLarge", 2f, "Шаг изменения высоты при зажатом Ctrl (Q/E)."); RadiusStep = ((BaseUnityPlugin)this).Config.Bind<float>("Leveler", "RadiusStep", 0.5f, "Шаг изменения радиуса (Shift+колесо)."); ConsumeRocks = ((BaseUnityPlugin)this).Config.Bind<bool>("Leveler", "ConsumeRocks", false, "Требовать камень за подъём terrain (по объёму добавленной земли)."); RocksPerCubicMeter = ((BaseUnityPlugin)this).Config.Bind<float>("Leveler", "RocksPerCubicMeter", 0.15f, "Камня за кубический метр подъёма (при включённом ConsumeRocks)."); CurrentRadius = Radius.Value; Log = ((BaseUnityPlugin)this).Logger; try { harmony.PatchAll(); } catch (Exception arg) { Log.LogError((object)$"PatchAll упал: {arg}"); } } private void OnDestroy() { harmony.UnpatchSelf(); } private void OnGUI() { //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Expected O, but got Unknown //IL_00c5: Unknown result type (might be due to invalid IL or missing references) if (HasTargetHeight && !((Object)(object)Player.m_localPlayer == (Object)null)) { string text = (ModLoc.Russian ? $"Высота: {TargetHeight:F2} Радиус: {CurrentRadius:F1}\nQ/E — высота (Ctrl — крупно, Shift — кратно шагу) · Shift+колесо — радиус · R — сброс" : $"Height: {TargetHeight:F2} Radius: {CurrentRadius:F1}\nQ/E — height (Ctrl — large, Shift — snap) · Shift+wheel — radius · R — reset"); GUIStyle val = new GUIStyle(GUI.skin.label) { fontSize = 15 }; val.normal.textColor = Color.white; GUIStyle val2 = val; Rect val3 = default(Rect); ((Rect)(ref val3))..ctor((float)Screen.width / 2f + 24f, (float)Screen.height / 2f - 16f, 560f, 48f); GUI.Label(val3, text, val2); } } } public class GhostVisualInfo { public string VisualPath; public Vector3 BaseScale; public float BaseRadius; } public static class ModLoc { public const string RoundPieceToken = "$terainer_level_round"; public const string SquarePieceToken = "$terainer_level_square"; public const string DescToken = "$terainer_level_desc"; public static bool Russian { get; private set; } public static string RoundPieceName => Russian ? "Выровнять по высоте" : "Level to height"; public static string SquarePieceName => Russian ? "Выровнять по высоте (квадрат)" : "Level to height (square)"; private static string TrimToken(string token) { return token.TrimStart(new char[1] { '$' }); } public static string Register() { Localization instance = Localization.m_instance; if (instance == null) { return null; } Russian = instance.GetSelectedLanguage() == "Russian"; instance.AddWord(TrimToken("$terainer_level_round"), RoundPieceName); instance.AddWord(TrimToken("$terainer_level_square"), SquarePieceName); instance.AddWord(TrimToken("$terainer_level_desc"), Russian ? "Q/E выбирает высоту, ЛКМ выравнивает terrain в области до неё." : "Q/E picks the height, LMB levels the terrain in the area to it."); return instance.GetSelectedLanguage(); } } [HarmonyPatch(typeof(Localization), "SetStartupLanguage")] public static class LocalizationStartupPatch { private static void Postfix() { ModLoc.Register(); } } [HarmonyPatch(typeof(Localization), "SetLanguageFromLocale")] public static class LocalizationLocalePatch { private static void Postfix() { ModLoc.Register(); } } [HarmonyPatch(typeof(Localization), "SetLanguage")] public static class LocalizationSetLanguagePatch { private static void Postfix() { ModLoc.Register(); } } [HarmonyPatch(typeof(Player), "UpdatePlacementGhost")] public static class GhostHeightPatch { private static float lastDiagLog; private static void Postfix(Player __instance) { //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: 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_00c5: Unknown result type (might be due to invalid IL or missing references) try { GameObject placementGhost = __instance.m_placementGhost; if ((Object)(object)placementGhost != (Object)null && Time.time - lastDiagLog > 3f) { lastDiagLog = Time.time; Mod.Log.LogInfo((object)($"GH patch: active={PlayerInputPatch.IsActiveMode(__instance)} " + $"ghost={((Object)placementGhost).name} y={placementGhost.transform.position.y:F2} " + $"hasTarget={Mod.HasTargetHeight} target={Mod.TargetHeight:F2}")); } if (PlayerInputPatch.IsActiveMode(__instance)) { if (!Mod.HasTargetHeight) { Mod.TargetHeight = placementGhost.transform.position.y; Mod.HasTargetHeight = true; } placementGhost.transform.position = new Vector3(placementGhost.transform.position.x, Mod.TargetHeight, placementGhost.transform.position.z); ApplyRadius(__instance.m_placementGhost.GetComponent<TerrainOp>()); Piece selectedPiece = __instance.m_buildPieces.GetSelectedPiece(); ApplyRadius((selectedPiece != null) ? ((Component)selectedPiece).GetComponent<TerrainOp>() : null); ApplyGhostVisualScale(placementGhost); } } catch (Exception arg) { Mod.Log.LogError((object)$"GhostHeightPatch: {arg}"); } } public static void ApplyRadius(TerrainOp op) { if (!((Object)(object)op == (Object)null)) { op.m_settings.m_levelRadius = Mod.CurrentRadius; op.m_settings.m_paintRadius = Mathf.Max(op.m_settings.m_paintRadius, Mod.CurrentRadius); } } public static void ApplyGhostVisualScale(GameObject ghost) { //IL_0090: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)ghost == (Object)null) && Mod.GhostVisuals.TryGetValue(((Object)ghost).name, out var value) && value != null && !(value.BaseRadius <= 0.01f)) { Transform val = ghost.transform.Find(value.VisualPath); if (!((Object)(object)val == (Object)null)) { float num = Mod.CurrentRadius / value.BaseRadius; val.localScale = new Vector3(value.BaseScale.x * num, value.BaseScale.y, value.BaseScale.z * num); } } } } [HarmonyPatch(typeof(Player), "Update")] public static class PlayerInputPatch { private const float ScrollThreshold = 0.05f; private const float KeyRepeatInterval = 0.12f; private static float scrollAccumulator; private static float keyRepeatTimer; private static float lastDiagnostic; public static bool IsActiveMode(Player player) { if ((Object)(object)player == (Object)null || (Object)(object)player != (Object)(object)Player.m_localPlayer || !((Character)player).InPlaceMode()) { return false; } if ((Object)(object)player.m_placementGhost != (Object)null && ((Object)player.m_placementGhost).name.StartsWith("Terrainer_LevelToHeight", StringComparison.Ordinal)) { return true; } PieceTable buildPieces = player.m_buildPieces; Piece val = ((buildPieces != null) ? buildPieces.GetSelectedPiece() : null); return (Object)(object)val != (Object)null && ((Object)val).name.StartsWith("Terrainer_LevelToHeight", StringComparison.Ordinal); } private static void LogBuildState(Player player) { if (!(Time.time - lastDiagnostic < 10f)) { lastDiagnostic = Time.time; PieceTable buildPieces = player.m_buildPieces; Piece val = ((buildPieces != null) ? buildPieces.GetSelectedPiece() : null); Mod.Log.LogInfo((object)($"Build state: local={(Object)(object)player == (Object)(object)Player.m_localPlayer} owner={((Character)player).m_nview.IsOwner()} " + $"placeMode={((Character)player).InPlaceMode()} " + "ghost=" + (((Object)(object)player.m_placementGhost != (Object)null) ? ((Object)player.m_placementGhost).name : "<null>") + " " + string.Format("selected={0} active={1} ", ((Object)(object)val != (Object)null) ? ((Object)val).name : "<null>", IsActiveMode(player)) + $"hasTarget={Mod.HasTargetHeight} target={Mod.TargetHeight:F2} radius={Mod.CurrentRadius:F1}")); } } private static void Postfix(Player __instance) { //IL_034a: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer) { return; } EnsurePieceKnown(__instance); if ((Object)(object)__instance.m_placementGhost != (Object)null && ((Character)__instance).InPlaceMode()) { LogBuildState(__instance); } if (!Mod.HasTargetHeight && !IsActiveMode(__instance)) { return; } if (!IsActiveMode(__instance) || Hud.IsPieceSelectionVisible()) { scrollAccumulator = 0f; keyRepeatTimer = 0f; if (!IsActiveMode(__instance)) { if (Mod.HasTargetHeight) { PieceTable buildPieces = __instance.m_buildPieces; Piece val = ((buildPieces != null) ? buildPieces.GetSelectedPiece() : null); Mod.Log.LogInfo((object)("Reset hasTarget: ghost=" + (((Object)(object)__instance.m_placementGhost != (Object)null) ? ((Object)__instance.m_placementGhost).name : "<null>") + " selected=" + (((Object)(object)val != (Object)null) ? ((Object)val).name : "<null>") + " " + $"hud={Hud.IsPieceSelectionVisible()} owner={((Character)__instance).m_nview.IsOwner()}")); } Mod.HasTargetHeight = false; } return; } bool flag = ZInput.GetKey((KeyCode)306, true) || ZInput.GetKey((KeyCode)305, true); bool flag2 = ZInput.GetKey((KeyCode)304, true) || ZInput.GetKey((KeyCode)303, true); float num = (flag ? Mod.HeightStepLarge.Value : Mod.HeightStep.Value); keyRepeatTimer -= Time.deltaTime; bool key = ZInput.GetKey((KeyCode)113, true); bool key2 = ZInput.GetKey((KeyCode)101, true); if ((key || key2) && keyRepeatTimer <= 0f) { keyRepeatTimer = 0.12f; if (key) { Mod.TargetHeight += num; } if (key2) { Mod.TargetHeight -= num; } if (flag2) { Mod.TargetHeight = Mathf.Round(Mod.TargetHeight / num) * num; } } if (flag2) { scrollAccumulator += ZInput.GetMouseScrollWheel(); float num2 = (flag ? (Mod.RadiusStep.Value * 4f) : Mod.RadiusStep.Value); while (scrollAccumulator >= 0.05f) { scrollAccumulator -= 0.05f; Mod.CurrentRadius = Mathf.Clamp(Mod.CurrentRadius + num2, 1f, 16f); } while (scrollAccumulator <= -0.05f) { scrollAccumulator += 0.05f; Mod.CurrentRadius = Mathf.Clamp(Mod.CurrentRadius - num2, 1f, 16f); } } else { scrollAccumulator = 0f; } if (ZInput.GetButtonDown("Rotate")) { Mod.TargetHeight = ZoneSystem.instance.GetGroundHeight(((Component)Player.m_localPlayer).transform.position); } } catch (Exception arg) { Mod.Log.LogError((object)$"PlayerInputPatch: {arg}"); } } private static void EnsurePieceKnown(Player player) { if ((Object)(object)player != (Object)(object)Player.m_localPlayer || player.m_knownRecipes == null || (player.m_knownRecipes.Contains("$terainer_level_round") && player.m_knownRecipes.Contains("$terainer_level_square"))) { return; } Dictionary<string, string> dictionary = new Dictionary<string, string> { { "Terrainer_LevelToHeight", "$terainer_level_round" }, { "Terrainer_LevelToHeightSquare", "$terainer_level_square" } }; List<PieceTable> list = new List<PieceTable>(); ((Humanoid)player).m_inventory.GetAllPieceTables(list); foreach (PieceTable item in list) { foreach (GameObject piece in item.m_pieces) { if ((Object)(object)piece != (Object)null && dictionary.TryGetValue(((Object)piece).name, out var value) && !player.m_knownRecipes.Contains(value)) { player.AddKnownPiece(piece.GetComponent<Piece>()); player.UpdateAvailablePiecesList(); } } } } } [HarmonyPatch(typeof(PieceTable), "UpdateAvailable")] public static class PieceTablePatch { private static void Prefix(HashSet<string> knownRecipies) { if (knownRecipies != null) { knownRecipies.Add("$terainer_level_round"); knownRecipies.Add("$terainer_level_square"); } } } [HarmonyPatch(typeof(Player), "PlacePiece")] public static class PlaceHeightPatch { private static void Prefix(Player __instance, Piece piece, ref Vector3 pos) { try { if (Mod.HasTargetHeight && !((Object)(object)piece == (Object)null) && ((Object)piece).name.StartsWith("Terrainer_LevelToHeight", StringComparison.Ordinal)) { pos.y = Mod.TargetHeight; } } catch (Exception arg) { Mod.Log.LogError((object)$"PlaceHeightPatch: {arg}"); } } } [HarmonyPatch(typeof(Player), "TryPlacePiece")] public static class RockCostPatch { private static int pendingCost; private static bool Prefix(Player __instance, Piece piece, ref bool __result) { //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) pendingCost = 0; if ((Object)(object)piece == (Object)null || !((Object)piece).name.StartsWith("Terrainer_LevelToHeight", StringComparison.Ordinal) || !Mod.ConsumeRocks.Value || (Object)(object)__instance.m_placementGhost == (Object)null) { return true; } try { Vector3 position = __instance.m_placementGhost.transform.position; bool square = ((Object)piece).name == "Terrainer_LevelToHeightSquare"; pendingCost = ComputeStoneCost(position, square); } catch (Exception arg) { Mod.Log.LogError((object)$"RockCostPatch: {arg}"); } if (pendingCost <= 0) { return true; } int num = ((Humanoid)__instance).m_inventory.CountItems("$item_stone", -1, true); if (num < pendingCost) { string text = (ModLoc.Russian ? $"Камень: нужно {pendingCost}, есть {num}" : $"Stone: need {pendingCost}, have {num}"); ((Character)__instance).Message((MessageType)2, text, 0, (Sprite)null); __result = false; return false; } return true; } private static void Postfix(Player __instance, bool __result) { if (__result && pendingCost > 0) { ((Humanoid)__instance).m_inventory.RemoveItem("$item_stone", pendingCost, -1, true); } pendingCost = 0; } private static int ComputeStoneCost(Vector3 pos, bool square) { //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) float currentRadius = Mod.CurrentRadius; float targetHeight = Mod.TargetHeight; float num = 0f; float num2 = currentRadius * currentRadius; for (float num3 = 0f - currentRadius; num3 <= currentRadius + 0.01f; num3 += 0.5f) { for (float num4 = 0f - currentRadius; num4 <= currentRadius + 0.01f; num4 += 0.5f) { if (square || !(num3 * num3 + num4 * num4 > num2)) { float groundHeight = ZoneSystem.instance.GetGroundHeight(pos + new Vector3(num3, 0f, num4)); if (targetHeight > groundHeight) { num += (targetHeight - groundHeight) * 0.25f; } } } } return Mathf.CeilToInt(num * Mod.RocksPerCubicMeter.Value); } } [HarmonyPatch(typeof(ZNetScene), "Awake")] public static class ZNetScenePatch { private const int CylinderSegments = 32; private static Mesh cylinderMesh; private static void Postfix(ZNetScene __instance) { GameObject itemPrefab = ObjectDB.instance.GetItemPrefab("Hoe"); PieceTable val = ((itemPrefab == null) ? null : itemPrefab.GetComponent<ItemDrop>()?.m_itemData.m_shared.m_buildPieces); if ((Object)(object)val == (Object)null || (Object)(object)__instance == (Object)null) { Mod.Log.LogWarning((object)"Не найдена таблица пьесов мотыги, режимы не добавлены"); return; } int num = val.m_pieces.RemoveAll((GameObject p) => (Object)(object)p == (Object)null); if (num > 0) { Mod.Log.LogInfo((object)$"Убрано {num} уничтоженных пьесов из таблицы мотыги"); } if (val.m_pieces.Any((GameObject p) => ((Object)p).name == "Terrainer_LevelToHeight")) { return; } GameObject val2 = null; foreach (GameObject piece in val.m_pieces) { if ((Object)(object)((piece != null) ? piece.GetComponentInChildren<TerrainOp>() : null) != (Object)null) { val2 = piece; break; } } if ((Object)(object)val2 == (Object)null) { Mod.Log.LogWarning((object)"В таблице мотыги не найдено ни одного пьеса с TerrainOp, режимы не добавлены"); return; } RegisterClone(__instance, val, val2, "Terrainer_LevelToHeight", "$terainer_level_round", square: false); RegisterClone(__instance, val, val2, "Terrainer_LevelToHeightSquare", "$terainer_level_square", square: true); ModLoc.Register(); } private static void RegisterClone(ZNetScene scene, PieceTable table, GameObject source, string cloneName, string nameToken, bool square) { TerrainOp.m_forceDisableTerrainOps = true; GameObject val = Object.Instantiate<GameObject>(source, ((Component)scene).transform); TerrainOp.m_forceDisableTerrainOps = false; ((Object)val).name = cloneName; TerrainOp componentInChildren = val.GetComponentInChildren<TerrainOp>(); componentInChildren.m_settings.m_level = true; componentInChildren.m_settings.m_raise = false; componentInChildren.m_settings.m_smooth = false; componentInChildren.m_settings.m_square = square; componentInChildren.m_settings.m_levelRadius = Mod.Radius.Value; componentInChildren.m_settings.m_paintRadius = Mathf.Max(componentInChildren.m_settings.m_paintRadius, Mod.Radius.Value); Piece component = val.GetComponent<Piece>(); component.m_name = nameToken; component.m_description = "$terainer_level_desc"; component.m_canRotate = true; GhostVisualInfo ghostVisualInfo = SetupGhostVisual(val, square); if (ghostVisualInfo != null) { Mod.GhostVisuals[cloneName] = ghostVisualInfo; } if (!scene.m_prefabs.Contains(val)) { scene.m_prefabs.Add(val); } if (!table.m_pieces.Contains(val)) { table.m_pieces.Add(val); } Mod.Log.LogInfo((object)($"Режим '{nameToken}' добавлен в таблицу мотыги (на основе {((Object)source).name}, радиус {Mod.Radius.Value}" + ((ghostVisualInfo != null) ? $", визуал {ghostVisualInfo.BaseRadius:F2} м" : ", визуал не найден") + ")")); } private static GhostVisualInfo SetupGhostVisual(GameObject clone, bool square) { //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Expected O, but got Unknown //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: 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_0146: Unknown result type (might be due to invalid IL or missing references) MeshFilter componentInChildren = clone.GetComponentInChildren<MeshFilter>(true); if ((Object)(object)componentInChildren == (Object)null) { return null; } if (square) { Transform transform = ((Component)componentInChildren).transform; return new GhostVisualInfo { VisualPath = GetRelativePath(clone.transform, transform), BaseScale = transform.localScale, BaseRadius = MeasureSubtreeRadius(transform) }; } MeshRenderer component = ((Component)componentInChildren).GetComponent<MeshRenderer>(); GameObject val = new GameObject("TerrainerVisual"); val.transform.SetParent(clone.transform, false); val.transform.localPosition = new Vector3(0f, -0.5f, 0f); val.transform.localRotation = Quaternion.identity; val.transform.localScale = Vector3.one; val.AddComponent<MeshFilter>().sharedMesh = GetCylinderMesh(); MeshRenderer val2 = val.AddComponent<MeshRenderer>(); if ((Object)(object)component != (Object)null) { ((Renderer)val2).sharedMaterials = ((Renderer)component).sharedMaterials; } if ((Object)(object)((Component)componentInChildren).transform != (Object)(object)clone.transform) { ((Component)componentInChildren).gameObject.SetActive(false); } return new GhostVisualInfo { VisualPath = ((Object)val).name, BaseScale = val.transform.localScale, BaseRadius = 1f }; } private static float MeasureSubtreeRadius(Transform root) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0044: 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_0059: 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_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) float num = 0f; MeshFilter[] componentsInChildren = ((Component)root).GetComponentsInChildren<MeshFilter>(true); foreach (MeshFilter val in componentsInChildren) { Mesh sharedMesh = val.sharedMesh; if (!((Object)(object)sharedMesh == (Object)null)) { Bounds bounds = sharedMesh.bounds; Vector3 lossyScale = ((Component)val).transform.lossyScale; num = Mathf.Max(new float[3] { num, ((Bounds)(ref bounds)).extents.x * Mathf.Abs(lossyScale.x), ((Bounds)(ref bounds)).extents.z * Mathf.Abs(lossyScale.z) }); } } return num; } private static string GetRelativePath(Transform root, Transform node) { string text = ((Object)node).name; while ((Object)(object)node.parent != (Object)null && (Object)(object)node.parent != (Object)(object)root) { node = node.parent; text = ((Object)node).name + "/" + text; } return text; } private static Mesh GetCylinderMesh() { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_009f: 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_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_02d6: Unknown result type (might be due to invalid IL or missing references) //IL_02db: Unknown result type (might be due to invalid IL or missing references) //IL_02e8: Unknown result type (might be due to invalid IL or missing references) //IL_02f5: Unknown result type (might be due to invalid IL or missing references) //IL_0307: Expected O, but got Unknown if ((Object)(object)cylinderMesh != (Object)null) { return cylinderMesh; } List<Vector3> list = new List<Vector3>(); List<Vector3> list2 = new List<Vector3>(); List<int> list3 = new List<int>(); int count = list.Count; list.Add(new Vector3(0f, 0.5f, 0f)); list2.Add(Vector3.up); int count2 = list.Count; Vector3 val = default(Vector3); for (int i = 0; i <= 32; i++) { float num = (float)i * (float)Math.PI * 2f / 32f; ((Vector3)(ref val))..ctor(Mathf.Cos(num), 0f, Mathf.Sin(num)); list.Add(val + new Vector3(0f, 0.5f, 0f)); list2.Add(Vector3.up); } int count3 = list.Count; Vector3 val2 = default(Vector3); for (int j = 0; j <= 32; j++) { float num2 = (float)j * (float)Math.PI * 2f / 32f; ((Vector3)(ref val2))..ctor(Mathf.Cos(num2), 0f, Mathf.Sin(num2)); list.Add(val2 + new Vector3(0f, 0.5f, 0f)); list2.Add(val2); } int count4 = list.Count; Vector3 val3 = default(Vector3); for (int k = 0; k <= 32; k++) { float num3 = (float)k * (float)Math.PI * 2f / 32f; ((Vector3)(ref val3))..ctor(Mathf.Cos(num3), 0f, Mathf.Sin(num3)); list.Add(val3 - new Vector3(0f, 0.5f, 0f)); list2.Add(val3); } for (int l = 0; l < 32; l++) { int item = count; int item2 = count2 + l; int item3 = count2 + l + 1; list3.Add(item); list3.Add(item3); list3.Add(item2); list3.Add(item); list3.Add(item2); list3.Add(item3); int item4 = count3 + l; int item5 = count3 + l + 1; int item6 = count4 + l; int item7 = count4 + l + 1; list3.Add(item4); list3.Add(item6); list3.Add(item7); list3.Add(item4); list3.Add(item7); list3.Add(item5); list3.Add(item4); list3.Add(item7); list3.Add(item6); list3.Add(item4); list3.Add(item5); list3.Add(item7); } cylinderMesh = new Mesh { vertices = list.ToArray(), normals = list2.ToArray(), triangles = list3.ToArray() }; cylinderMesh.RecalculateBounds(); ((Object)cylinderMesh).name = "TerrainerCylinder"; return cylinderMesh; } } } namespace ExampleCallMethodMod.Utils { public static class ArrayUtils { public const string NullString = "<null>"; public static IEnumerable<object> ToArray(object obj) { if (!(obj is IEnumerable source)) { if (obj == null) { return Enumerable.Empty<object>(); } return new object[1] { obj }; } return source.Cast<object>(); } public static IEnumerable<string> ToStringArray(object obj) { return from o in ToArray(obj) select o?.ToString() ?? "<null>"; } } public static class CommandParser { public enum SegmentType { Unknown, Int, Float, String, Identifier } public class CommandSegment { public SegmentType Type { get; } public string Text { get; } public CommandSegment(SegmentType type, string text) { Type = type; Text = text ?? ""; } public override string ToString() { return Text; } } public class TakerResult { public CommandSegment Segment { get; } public int Offset { get; } public TakerResult(CommandSegment segment) { Segment = segment; Offset = segment?.Text.Length ?? 0; } public TakerResult(CommandSegment segment, int offset) : this(segment) { Segment = segment; Offset = offset; } } private static readonly Func<string, int, TakerResult>[] segmentTakers = new Func<string, int, TakerResult>[4] { TakeInt, TakeFloat, TakeString, TakeIdentifier }; public static IEnumerable<CommandSegment> Parse(string input) { if (string.IsNullOrWhiteSpace(input)) { yield break; } int index = 0; while (true) { TakerResult takerResult2; TakerResult takerResult = (takerResult2 = TakeSegment(input, index)); if (takerResult2 != null) { yield return takerResult.Segment; index = takerResult.Offset; continue; } break; } } private static TakerResult TakeSegment(string input, int offset, SegmentType type = SegmentType.Unknown) { while (true) { if (offset >= input.Length) { return null; } if (input[offset] != ' ') { break; } offset++; } int startIndex = offset; TakerResult takerResult = null; Func<string, int, TakerResult>[] array = segmentTakers; foreach (Func<string, int, TakerResult> func in array) { takerResult = func(input, offset); if (takerResult?.Segment != null) { break; } } return takerResult ?? new TakerResult(new CommandSegment(SegmentType.Unknown, input.Substring(startIndex))); } private static TakerResult TakeIdentifier(string input, int offset) { Match match = Regex.Match(input.Substring(offset), "^\\w+"); CommandSegment commandSegment = (match.Success ? new CommandSegment(SegmentType.Identifier, match.Value) : null); return new TakerResult(commandSegment, (offset + commandSegment?.Text.Length) ?? offset); } private static TakerResult TakeInt(string input, int offset) { Match match = Regex.Match(input.Substring(offset), "^\\-?\\d+"); CommandSegment commandSegment = (match.Success ? new CommandSegment(SegmentType.Int, match.Value) : null); return new TakerResult(commandSegment, (offset + commandSegment?.Text.Length) ?? offset); } private static TakerResult TakeFloat(string input, int offset) { Match match = Regex.Match(input.Substring(offset), "^\\-?\\d+(?:\\.\\d+)?"); CommandSegment commandSegment = (match.Success ? new CommandSegment(SegmentType.Float, match.Value) : null); return new TakerResult(commandSegment, (offset + commandSegment?.Text.Length) ?? offset); } private static TakerResult TakeString(string input, int offset) { if (input[offset] != '"') { return null; } StringBuilder stringBuilder = new StringBuilder(); offset++; while (offset < input.Length) { if (input[offset] == '\\' && offset + 1 < input.Length) { stringBuilder.Append(input[offset + 1]); offset += 2; continue; } if (input[offset] == '"') { offset++; break; } stringBuilder.Append(input[offset]); offset++; } return new TakerResult(new CommandSegment(SegmentType.String, stringBuilder.ToString()), offset); } } } namespace ExampleCallMethodMod.Patches { public static class ConsolePatch { [HarmonyPatch(typeof(Console), "IsConsoleEnabled")] public static class ConsoleEnabled { public static bool Prefix(ref bool __result) { __result = true; return false; } } [HarmonyPatch(typeof(Terminal), "InputText")] public static class InputText { public static bool Prefix() { Console instance = Console.instance; string text = ((TMP_InputField)((Terminal)instance).m_input).text; if (!text.StartsWith("call", ignoreCase: true, CultureInfo.InvariantCulture)) { return true; } CommandParser.CommandSegment[] parts = CommandParser.Parse(text).ToArray(); if (parts.Length < 3) { ((Terminal)instance).AddString("call command requires at least 3 arguments: call <class> <methodName> [arg1] [arg2]"); return false; } ((Terminal)instance).AddString(text); Type type = typeof(Console).Assembly.GetTypes().FirstOrDefault((Type t) => t.Name.Equals(parts[1].Text, StringComparison.InvariantCultureIgnoreCase)); if (type == null) { ((Terminal)instance).AddString($"Could not find class with name '{parts[1]}'"); return false; } MethodInfo methodInfo = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.InvokeMethod).FirstOrDefault((MethodInfo m) => m.Name.Equals(parts[2].Text, StringComparison.InvariantCultureIgnoreCase)); if (methodInfo == null) { ((Terminal)instance).AddString("Could not find method '" + parts[2].Text + "' on class '" + type.FullName + "'"); return false; } ParameterInfo[] parameters = methodInfo.GetParameters(); if (parameters.Length != parts.Length - 3) { ((Terminal)instance).AddString("Command does not match method parameters. Expected parameter types: " + string.Join(", ", parameters.Select((ParameterInfo p) => p.ParameterType.Name))); return false; } object[] array = new object[parameters.Length]; for (int num = 0; num < parameters.Length; num++) { string text2 = parts[num + 3].Text; Type parameterType = parameters[num].ParameterType; try { array[num] = TypeDescriptor.GetConverter(parameterType).ConvertFrom(text2); } catch (NotSupportedException) { ((Terminal)instance).AddString($"Cannot convert argument {num + 1} '{text2}' to type of '{parameterType.FullName}'"); return false; } } object obj = null; if (!methodInfo.IsStatic) { obj = ((type == typeof(Player)) ? Player.m_localPlayer : type.GetField("m_instance", BindingFlags.Static | BindingFlags.NonPublic)?.GetValue(null)); if (obj == null) { ((Terminal)instance).AddString("Could not call method '" + methodInfo.Name + "' because it's an instance method and no static instance field is defined on it"); return false; } } object obj2 = methodInfo.Invoke(obj, array); if (obj2 != null) { ((Terminal)instance).AddString(string.Join(", ", ArrayUtils.ToStringArray(obj2))); } return false; } } } } namespace System { [ExcludeFromCodeCoverage] internal readonly struct Index : IEquatable<Index> { private static class ThrowHelper { [DoesNotReturn] public static void ThrowValueArgumentOutOfRange_NeedNonNegNumException() { throw new ArgumentOutOfRangeException("value", "Non-negative number required."); } } private readonly int _value; public static Index Start => new Index(0); public static Index End => new Index(-1); public int Value { get { if (_value < 0) { return ~_value; } return _value; } } public bool IsFromEnd => _value < 0; [MethodImpl(MethodImplOptions.AggressiveInlining)] public Index(int value, bool fromEnd = false) { if (value < 0) { ThrowHelper.ThrowValueArgumentOutOfRange_NeedNonNegNumException(); } if (fromEnd) { _value = ~value; } else { _value = value; } } private Index(int value) { _value = value; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Index FromStart(int value) { if (value < 0) { ThrowHelper.ThrowValueArgumentOutOfRange_NeedNonNegNumException(); } return new Index(value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Index FromEnd(int value) { if (value < 0) { ThrowHelper.ThrowValueArgumentOutOfRange_NeedNonNegNumException(); } return new Index(~value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public int GetOffset(int length) { int num = _value; if (IsFromEnd) { num += length + 1; } return num; } public override bool Equals([NotNullWhen(true)] object? value) { return value is Index && _value == ((Index)value)._value; } public bool Equals(Index other) { return _value == other._value; } public override int GetHashCode() { return _value; } public static implicit operator Index(int value) { return FromStart(value); } public override string ToString() { if (IsFromEnd) { return ToStringFromEnd(); } return ((uint)Value).ToString(); } private string ToStringFromEnd() { return "^" + Value; } } [ExcludeFromCodeCoverage] internal readonly struct Range : IEquatable<Range> { private static class HashHelpers { public static int Combine(int h1, int h2) { uint num = (uint)((h1 << 5) | (h1 >>> 27)); return ((int)num + h1) ^ h2; } } private static class ThrowHelper { [DoesNotReturn] public static void ThrowArgumentOutOfRangeException() { throw new ArgumentOutOfRangeException("length"); } } public Index Start { get; } public Index End { get; } public static Range All => Index.Start..Index.End; public Range(Index start, Index end) { Start = start; End = end; } public override bool Equals([NotNullWhen(true)] object? value) { return value is Range { Start: var start } range && start.Equals(Start) && range.End.Equals(End); } public bool Equals(Range other) { return other.Start.Equals(Start) && other.End.Equals(End); } public override int GetHashCode() { return HashHelpers.Combine(Start.GetHashCode(), End.GetHashCode()); } public override string ToString() { return Start.ToString() + ".." + End; } public static Range StartAt(Index start) { return start..Index.End; } public static Range EndAt(Index end) { return Index.Start..end; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public (int Offset, int Length) GetOffsetAndLength(int length) { Index start = Start; int num = ((!start.IsFromEnd) ? start.Value : (length - start.Value)); Index end = End; int num2 = ((!end.IsFromEnd) ? end.Value : (length - end.Value)); if ((uint)num2 > (uint)length || (uint)num > (uint)num2) { ThrowHelper.ThrowArgumentOutOfRangeException(); } return (Offset: num, Length: num2 - num); } } } namespace System.Diagnostics.CodeAnalysis { [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class AllowNullAttribute : Attribute { } [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class ConstantExpectedAttribute : Attribute { public object? Min { get; set; } public object? Max { get; set; } } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class DisallowNullAttribute : Attribute { } [AttributeUsage(AttributeTargets.Method, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class DoesNotReturnAttribute : Attribute { } [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class DoesNotReturnIfAttribute : Attribute { public bool ParameterValue { get; } public DoesNotReturnIfAttribute(bool parameterValue) { ParameterValue = parameterValue; } } [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class ExperimentalAttribute : Attribute { public string DiagnosticId { get; } public string? UrlFormat { get; set; } public ExperimentalAttribute(string diagnosticId) { DiagnosticId = diagnosticId; } } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class MaybeNullAttribute : Attribute { } [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class MaybeNullWhenAttribute : Attribute { public bool ReturnValue { get; } public MaybeNullWhenAttribute(bool returnValue) { ReturnValue = returnValue; } } [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)] [ExcludeFromCodeCoverage] internal sealed class MemberNotNullAttribute : Attribute { public string[] Members { get; } public MemberNotNullAttribute(string member) { Members = new string[1] { member }; } public MemberNotNullAttribute(params string[] members) { Members = members; } } [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)] [ExcludeFromCodeCoverage] internal sealed class MemberNotNullWhenAttribute : Attribute { public bool ReturnValue { get; } public string[] Members { get; } public MemberNotNullWhenAttribute(bool returnValue, string member) { ReturnValue = returnValue; Members = new string[1] { member }; } public MemberNotNullWhenAttribute(bool returnValue, params string[] members) { ReturnValue = returnValue; Members = members; } } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class NotNullAttribute : Attribute { } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Parameter | AttributeTargets.ReturnValue, AllowMultiple = true, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class NotNullIfNotNullAttribute : Attribute { public string ParameterName { get; } public NotNullIfNotNullAttribute(string parameterName) { ParameterName = parameterName; } } [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class NotNullWhenAttribute : Attribute { public bool ReturnValue { get; } public NotNullWhenAttribute(bool returnValue) { ReturnValue = returnValue; } } [AttributeUsage(AttributeTargets.Constructor, AllowMultiple = false, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class SetsRequiredMembersAttribute : Attribute { } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class StringSyntaxAttribute : Attribute { public const string CompositeFormat = "CompositeFormat"; public const string DateOnlyFormat = "DateOnlyFormat"; public const string DateTimeFormat = "DateTimeFormat"; public const string EnumFormat = "EnumFormat"; public const string GuidFormat = "GuidFormat"; public const string Json = "Json"; public const string NumericFormat = "NumericFormat"; public const string Regex = "Regex"; public const string TimeOnlyFormat = "TimeOnlyFormat"; public const string TimeSpanFormat = "TimeSpanFormat"; public const string Uri = "Uri"; public const string Xml = "Xml"; public string Syntax { get; } public object?[] Arguments { get; } public StringSyntaxAttribute(string syntax) { Syntax = syntax; Arguments = new object[0]; } public StringSyntaxAttribute(string syntax, params object?[] arguments) { Syntax = syntax; Arguments = arguments; } } [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class UnscopedRefAttribute : Attribute { } } namespace System.Runtime.Versioning { [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class RequiresPreviewFeaturesAttribute : Attribute { public string? Message { get; } public string? Url { get; set; } public RequiresPreviewFeaturesAttribute() { } public RequiresPreviewFeaturesAttribute(string? message) { Message = message; } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false, AllowMultiple = false)] [ExcludeFromCodeCoverage] internal sealed class AsyncMethodBuilderAttribute : Attribute { public Type BuilderType { get; } public AsyncMethodBuilderAttribute(Type builderType) { BuilderType = builderType; } } [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class CallerArgumentExpressionAttribute : Attribute { public string ParameterName { get; } public CallerArgumentExpressionAttribute(string parameterName) { ParameterName = parameterName; } } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class CollectionBuilderAttribute : Attribute { public Type BuilderType { get; } public string MethodName { get; } public CollectionBuilderAttribute(Type builderType, string methodName) { BuilderType = builderType; MethodName = methodName; } } [AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class CompilerFeatureRequiredAttribute : Attribute { public const string RefStructs = "RefStructs"; public const string RequiredMembers = "RequiredMembers"; public string FeatureName { get; } public bool IsOptional { get; set; } public CompilerFeatureRequiredAttribute(string featureName) { FeatureName = featureName; } } [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class InterpolatedStringHandlerArgumentAttribute : Attribute { public string[] Arguments { get; } public InterpolatedStringHandlerArgumentAttribute(string argument) { Arguments = new string[1] { argument }; } public InterpolatedStringHandlerArgumentAttribute(params string[] arguments) { Arguments = arguments; } } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class InterpolatedStringHandlerAttribute : Attribute { } [EditorBrowsable(EditorBrowsableState.Never)] [ExcludeFromCodeCoverage] internal static class IsExternalInit { } [AttributeUsage(AttributeTargets.Method, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class ModuleInitializerAttribute : Attribute { } [AttributeUsage(AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property, AllowMultiple = false, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class OverloadResolutionPriorityAttribute : Attribute { public int Priority { get; } public OverloadResolutionPriorityAttribute(int priority) { Priority = priority; } } [AttributeUsage(AttributeTargets.Parameter, Inherited = true, AllowMultiple = false)] [ExcludeFromCodeCoverage] internal sealed class ParamCollectionAttribute : Attribute { } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class RequiredMemberAttribute : Attribute { } [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] [EditorBrowsable(EditorBrowsableState.Never)] [ExcludeFromCodeCoverage] internal sealed class RequiresLocationAttribute : Attribute { } [AttributeUsage(AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Event | AttributeTargets.Interface, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class SkipLocalsInitAttribute : Attribute { } }