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 ValheimCreate v0.2.15
plugins\ValheimCreate\ValheimCreate.dll
Decompiled a week agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Jotunn.Managers; using Jotunn.Utils; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("ValheimCreate")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.2.15.0")] [assembly: AssemblyInformationalVersion("0.2.15+e8576d0c75f18f1a7da71fbbd0cd61e148f5fbb5")] [assembly: AssemblyProduct("ValheimCreate")] [assembly: AssemblyTitle("ValheimCreate")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.2.15.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.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] [Microsoft.CodeAnalysis.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] [Microsoft.CodeAnalysis.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 ValheimCreate { internal static class FreePiecesConfig { internal sealed class ExtraPiece { internal string PrefabName { get; } internal string DisplayName { get; } internal ExtraPiece(string prefabName, string displayName) { PrefabName = prefabName; DisplayName = displayName; } } internal static readonly IReadOnlyList<ExtraPiece> All = new ExtraPiece[2] { new ExtraPiece("piece_groundtorch_wood", "Standing Wood Torch"), new ExtraPiece("stake_wall", "Stake Wall") }; internal static readonly Dictionary<string, ConfigEntry<bool>> Entries = new Dictionary<string, ConfigEntry<bool>>(); internal static void Bind(ConfigFile config) { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Expected O, but got Unknown foreach (ExtraPiece item in All) { Entries[item.PrefabName] = config.Bind<bool>("Extra Free Pieces", item.DisplayName, false, new ConfigDescription("Place and remove " + item.DisplayName + " for free.", (AcceptableValueBase)null, Array.Empty<object>())); } } internal static bool IsEnabled(string prefabName) { if (Entries.TryGetValue(prefabName, out ConfigEntry<bool> value)) { return value.Value; } return false; } } internal class FreePiecesUI : MonoBehaviour { private GameObject? _panel; private GameObject? _openButton; private bool _panelVisible; private void Start() { GUIManager.OnCustomGUIAvailable += CreateUI; } private void OnDestroy() { GUIManager.OnCustomGUIAvailable -= CreateUI; } private void Update() { if ((Object)(object)_openButton == (Object)null) { return; } bool flag = (Object)(object)Player.m_localPlayer != (Object)null && ((Character)Player.m_localPlayer).InPlaceMode() && (Object)(object)Hud.instance != (Object)null && (Object)(object)Hud.instance.m_pieceSelectionWindow != (Object)null && Hud.instance.m_pieceSelectionWindow.activeSelf; if (_openButton.activeSelf != flag) { _openButton.SetActive(flag); if (!flag) { SetPanelVisible(visible: false); } } } private void CreateUI() { CreateOpenButton(); CreateConfigPanel(); } private void CreateOpenButton() { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_003d: 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_0083: Expected O, but got Unknown _openButton = GUIManager.Instance.CreateButton("Free Build Piece Selection", GUIManager.CustomGUIFront.transform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, -290f), 130f, 34f); _openButton.SetActive(false); ((UnityEvent)_openButton.GetComponent<Button>().onClick).AddListener((UnityAction)delegate { SetPanelVisible(!_panelVisible); }); } private void CreateConfigPanel() { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0089: 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_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0253: Unknown result type (might be due to invalid IL or missing references) //IL_0262: Unknown result type (might be due to invalid IL or missing references) //IL_0271: Unknown result type (might be due to invalid IL or missing references) //IL_0296: Unknown result type (might be due to invalid IL or missing references) //IL_02a0: Expected O, but got Unknown //IL_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Unknown result type (might be due to invalid IL or missing references) float num = 110f + (float)FreePiecesConfig.All.Count * 44f; _panel = GUIManager.Instance.CreateWoodpanel(GUIManager.CustomGUIFront.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), Vector2.zero, 280f, num); GUIManager.Instance.CreateText("Extra Free Pieces", _panel.transform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, -28f), GUIManager.Instance.AveriaSerifBold, 18, GUIManager.Instance.ValheimOrange, true, Color.black, 240f, 36f, false); for (int i = 0; i < FreePiecesConfig.All.Count; i++) { FreePiecesConfig.ExtraPiece extraPiece = FreePiecesConfig.All[i]; ConfigEntry<bool> val2 = FreePiecesConfig.Entries[extraPiece.PrefabName]; float num2 = -72f - (float)i * 44f; GameObject obj = GUIManager.Instance.CreateToggle(_panel.transform, 36f, 36f); RectTransform component = obj.GetComponent<RectTransform>(); component.anchorMin = new Vector2(0f, 1f); component.anchorMax = new Vector2(0f, 1f); component.anchoredPosition = new Vector2(36f, num2); Toggle component2 = obj.GetComponent<Toggle>(); component2.isOn = val2.Value; Text componentInChildren = obj.GetComponentInChildren<Text>(); if ((Object)(object)componentInChildren != (Object)null) { componentInChildren.text = string.Empty; } GUIManager.Instance.CreateText(extraPiece.DisplayName, _panel.transform, new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(160f, num2), GUIManager.Instance.AveriaSerif, 16, Color.white, false, Color.black, 120f, 36f, false); ConfigEntry<bool> capturedEntry = val2; ((UnityEvent<bool>)(object)component2.onValueChanged).AddListener((UnityAction<bool>)delegate(bool val) { capturedEntry.Value = val; }); } ((UnityEvent)GUIManager.Instance.CreateButton("Close", _panel.transform, new Vector2(0.5f, 0f), new Vector2(0.5f, 0f), new Vector2(0f, 28f), 100f, 34f).GetComponent<Button>().onClick).AddListener((UnityAction)delegate { SetPanelVisible(visible: false); }); _panel.SetActive(false); } private void SetPanelVisible(bool visible) { _panelVisible = visible; GameObject? panel = _panel; if (panel != null) { panel.SetActive(visible); } GUIManager.BlockInput(visible); } } [BepInPlugin("dpshaef.ValheimCreate", "ValheimCreate", "0.2.15")] [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { public const string PluginGUID = "dpshaef.ValheimCreate"; public const string PluginName = "ValheimCreate"; public const string PluginVersion = "0.2.15"; internal static ManualLogSource Log; internal static ConfigEntry<bool> FreeBuildEnabled; private readonly Harmony _harmony = new Harmony("dpshaef.ValheimCreate"); private void Awake() { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Expected O, but got Unknown //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; FreeBuildEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Free Build", "Enabled", true, new ConfigDescription("Remove resource costs for Building and Heavy Build pieces. All other categories (Misc, Crafting, Furniture) retain normal costs.", (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes { Order = 1 } })); FreePiecesConfig.Bind(((BaseUnityPlugin)this).Config); ((Component)this).gameObject.AddComponent<FreePiecesUI>(); _harmony.PatchAll(); Log.LogInfo((object)string.Format("{0} v{1} loaded. Free build: {2}", "ValheimCreate", "0.2.15", FreeBuildEnabled.Value)); } private void OnDestroy() { _harmony.UnpatchSelf(); } } } namespace ValheimCreate.Patches { internal static class FreeBuildPatch { [HarmonyPatch(typeof(Player), "HaveRequirements", new Type[] { typeof(Piece), typeof(RequirementMode) })] private static class HaveRequirements_Patch { private static bool Prefix(Piece piece, RequirementMode mode, ref bool __result) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Invalid comparison between Unknown and I4 if (!IsFreeCategory(piece) || (int)mode == 1) { return true; } __result = true; return false; } } [HarmonyPatch(typeof(Player), "UpdatePlacement")] private static class UpdatePlacement_Patch { private static void Prefix(Player __instance) { PieceTable buildPieces = __instance.m_buildPieces; _suppressConsumption = IsFreeCategory((buildPieces != null) ? buildPieces.GetSelectedPiece() : null); } private static void Postfix() { _suppressConsumption = false; } } [HarmonyPatch(typeof(Player), "ConsumeResources")] private static class ConsumeResources_Patch { private static bool Prefix() { Plugin.Log.LogInfo((object)$"[ConsumeResources] suppress={_suppressConsumption}"); return !_suppressConsumption; } } [HarmonyPatch(typeof(Player), "PlacePiece")] private static class PlacePiece_Log_Patch { private static void Prefix(Player __instance, Piece piece, out int __state) { __state = ((Humanoid)__instance).GetInventory().CountItems("$item_wood", -1, true); Plugin.Log.LogInfo((object)string.Format("[PlacePiece] piece={0} isFree={1} suppress={2} m_noPlacementCost={3} wood_before={4}", ((piece != null) ? ((Object)piece).name : null) ?? "null", IsFreeCategory(piece), _suppressConsumption, __instance.m_noPlacementCost, __state)); } private static void Postfix(Player __instance, int __state) { int num = ((Humanoid)__instance).GetInventory().CountItems("$item_wood", -1, true); Plugin.Log.LogInfo((object)$"[PlacePiece] wood_after={num}"); if (num < __state) { Plugin.Log.LogError((object)$"[PlacePiece] WOOD DECREASED: {__state} -> {num}"); } } } private static bool _suppressConsumption; internal static bool IsFreeCategory(Piece? piece) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Invalid comparison between Unknown and I4 //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Invalid comparison between Unknown and I4 if ((Object)(object)piece == (Object)null || !Plugin.FreeBuildEnabled.Value) { return false; } if ((int)piece.m_category == 2 || (int)piece.m_category == 3) { return true; } return FreePiecesConfig.IsEnabled(Utils.GetPrefabName(((Component)piece).gameObject)); } } internal static class FreeRemovePatch { [HarmonyPatch(typeof(Piece), "SetCreator")] private static class SetCreator_Patch { private static void Postfix(Piece __instance, long uid) { if (uid != 0L && Plugin.FreeBuildEnabled.Value && FreeBuildPatch.IsFreeCategory(__instance)) { ZNetView component = ((Component)__instance).GetComponent<ZNetView>(); if ((Object)(object)component == (Object)null || !component.IsValid()) { Plugin.Log.LogWarning((object)("[SetCreator] SKIPPED tagging " + ((Object)__instance).name + " — ZNetView null or invalid")); return; } component.GetZDO().Set(ZdoKeyHash, true); Plugin.Log.LogInfo((object)("[SetCreator] Tagged " + ((Object)__instance).name + " as free-build")); } } } [HarmonyPatch(typeof(Piece), "DropResources")] private static class DropResources_Patch { private static bool Prefix(Piece __instance) { ZNetView component = ((Component)__instance).GetComponent<ZNetView>(); if ((Object)(object)component == (Object)null || !component.IsValid()) { return true; } return !component.GetZDO().GetBool(ZdoKeyHash, false); } } [HarmonyPatch(typeof(Player), "RemovePiece")] private static class RemovePiece_Patch { private static void Prefix(Player __instance, out Piece? __state) { //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) __state = null; _savedStation = null; if (!Plugin.FreeBuildEnabled.Value) { return; } Camera val = (((Object)(object)GameCamera.instance != (Object)null) ? GameCamera.instance.m_camera : Camera.main); if ((Object)(object)val == (Object)null) { Plugin.Log.LogWarning((object)"[RemovePiece] No camera found"); return; } int mask = LayerMask.GetMask(new string[2] { "piece", "piece_nonsolid" }); RaycastHit val2 = default(RaycastHit); if (!Physics.Raycast(((Component)val).transform.position, ((Component)val).transform.forward, ref val2, __instance.m_maxPlaceDistance, mask)) { return; } Piece componentInParent = ((Component)((RaycastHit)(ref val2)).collider).GetComponentInParent<Piece>(); if ((Object)(object)componentInParent == (Object)null) { Plugin.Log.LogInfo((object)"[RemovePiece] Raycast hit but no Piece component found"); return; } ManualLogSource log = Plugin.Log; string name = ((Object)componentInParent).name; object arg = componentInParent.m_category; CraftingStation craftingStation = componentInParent.m_craftingStation; log.LogInfo((object)string.Format("[RemovePiece] Aiming at {0} cat={1} station={2}", name, arg, ((craftingStation != null) ? ((Object)craftingStation).name : null) ?? "none")); if ((Object)(object)componentInParent.m_craftingStation == (Object)null) { Plugin.Log.LogInfo((object)"[RemovePiece] No crafting station required — no bypass needed"); return; } if (!FreeBuildPatch.IsFreeCategory(componentInParent)) { Plugin.Log.LogInfo((object)("[RemovePiece] " + ((Object)componentInParent).name + " is NOT a free category — skipping bypass")); return; } ZNetView component = ((Component)componentInParent).GetComponent<ZNetView>(); if ((Object)(object)component == (Object)null || !component.IsValid()) { Plugin.Log.LogWarning((object)("[RemovePiece] " + ((Object)componentInParent).name + " ZNetView null or invalid — cannot check tag")); return; } bool @bool = component.GetZDO().GetBool(ZdoKeyHash, false); Plugin.Log.LogInfo((object)$"[RemovePiece] {((Object)componentInParent).name} ZDO tag vc_freebuild={@bool}"); if (@bool) { _savedStation = componentInParent.m_craftingStation; componentInParent.m_craftingStation = null; __state = componentInParent; Plugin.Log.LogInfo((object)("[RemovePiece] Bypassing station check for " + ((Object)componentInParent).name)); } } private static void Postfix(Piece? __state) { if ((Object)(object)__state != (Object)null && (Object)(object)_savedStation != (Object)null) { __state.m_craftingStation = _savedStation; _savedStation = null; } } } private static readonly int ZdoKeyHash = StringExtensionMethods.GetStableHashCode("vc_freebuild"); private static CraftingStation? _savedStation; } }