Decompiled source of Forever Build 2 v2.1.4

plugins\ForeverBuild2.dll

Decompiled 3 hours ago
using System;
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 ConditionalConfigSync;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("assembly_valheim")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("Allifreyr")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("2.1.4.0")]
[assembly: AssemblyInformationalVersion("2.1.4")]
[assembly: AssemblyProduct("Forever Build 2")]
[assembly: AssemblyTitle("ForeverBuild2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.1.4.0")]
[module: UnverifiableCode]
[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 ForeverBuild
{
	internal static class Stability
	{
		internal static bool ShouldModify(WearNTear wear)
		{
			if (!PluginConfig.IsActive || (Object)(object)wear == (Object)null)
			{
				return false;
			}
			if ((Object)(object)((Component)wear).GetComponent<Ship>() != (Object)null || (Object)(object)((Component)wear).GetComponent<Vagon>() != (Object)null)
			{
				return false;
			}
			Piece val = (((Object)(object)wear.m_piece != (Object)null) ? wear.m_piece : ((Component)wear).GetComponent<Piece>());
			if ((Object)(object)val != (Object)null)
			{
				return val.IsPlacedByPlayer();
			}
			return false;
		}

		internal static void ApplyVanilla(MaterialType material, out float maxSupport, out float minSupport, out float horizontalLoss, out float verticalLoss)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected I4, but got Unknown
			switch ((int)material)
			{
			case 0:
				maxSupport = 100f;
				minSupport = 10f;
				verticalLoss = 0.125f;
				horizontalLoss = 0.2f;
				break;
			case 3:
				maxSupport = 140f;
				minSupport = 10f;
				verticalLoss = 0.1f;
				horizontalLoss = 1f / 6f;
				break;
			case 1:
				maxSupport = 1000f;
				minSupport = 100f;
				verticalLoss = 0.125f;
				horizontalLoss = 1f;
				break;
			case 2:
				maxSupport = 1500f;
				minSupport = 20f;
				verticalLoss = 1f / 13f;
				horizontalLoss = 1f / 13f;
				break;
			case 4:
				maxSupport = 1500f;
				minSupport = 100f;
				verticalLoss = 0.125f;
				horizontalLoss = 0.5f;
				break;
			case 5:
				maxSupport = 2000f;
				minSupport = 100f;
				verticalLoss = 0.1f;
				horizontalLoss = 1f / 3f;
				break;
			case 6:
				maxSupport = 5000f;
				minSupport = 100f;
				verticalLoss = 1f / 15f;
				horizontalLoss = 0.25f;
				break;
			case 7:
				maxSupport = 1000f;
				minSupport = 100f;
				verticalLoss = 0.125f;
				horizontalLoss = 1f / 3f;
				break;
			case 8:
				maxSupport = 200f;
				minSupport = 10f;
				verticalLoss = 1f / 13f;
				horizontalLoss = 0.2f;
				break;
			default:
				maxSupport = 0f;
				minSupport = 0f;
				verticalLoss = 0f;
				horizontalLoss = 0f;
				break;
			}
		}
	}
	[HarmonyPatch(typeof(WearNTear), "GetMaterialProperties")]
	internal static class WearNTearGetMaterialPropertiesPatch
	{
		private static int _lastLoggedId;

		private static float _lastLoggedTime;

		private static bool Prefix(WearNTear __instance, ref float maxSupport, ref float minSupport, ref float horizontalLoss, ref float verticalLoss)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			if (!Stability.ShouldModify(__instance))
			{
				return true;
			}
			Stability.ApplyVanilla(__instance.m_materialType, out maxSupport, out minSupport, out horizontalLoss, out verticalLoss);
			if (PluginConfig.IsInfinite)
			{
				horizontalLoss = 0f;
				verticalLoss = 0f;
				LogOnce(__instance, "infinite (loss 0)");
				return false;
			}
			float effectiveMultiplier = PluginConfig.EffectiveMultiplier;
			horizontalLoss /= effectiveMultiplier;
			verticalLoss /= effectiveMultiplier;
			LogOnce(__instance, "x" + effectiveMultiplier + " loss");
			return false;
		}

		private static void LogOnce(WearNTear wear, string how)
		{
			if (!PluginConfig.ExtraLogging.Value)
			{
				return;
			}
			int instanceID = ((Object)wear).GetInstanceID();
			if (instanceID != _lastLoggedId || !(Time.time - _lastLoggedTime < 2f))
			{
				_lastLoggedId = instanceID;
				_lastLoggedTime = Time.time;
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogInfo((object)("Adjusted support on " + ((Object)wear).name + " (" + how + ")"));
				}
			}
		}
	}
	[HarmonyPatch(typeof(WearNTear), "HaveSupport")]
	internal static class WearNTearHaveSupportPatch
	{
		private static void Postfix(WearNTear __instance, ref bool __result)
		{
			if (PluginConfig.IsInfinite && Stability.ShouldModify(__instance))
			{
				__result = true;
			}
		}
	}
	[BepInPlugin("Allifreyr.ForeverBuild2", "Forever Build 2", "2.1.4")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInIncompatibility("lime.plugins.foreverbuild")]
	[BepInIncompatibility("Allifreyr.ForeverBuild")]
	public class Plugin : BaseUnityPlugin
	{
		public const string PluginGuid = "Allifreyr.ForeverBuild2";

		public const string PluginName = "Forever Build 2";

		public const string PluginVersion = "2.1.4";

		internal static Plugin Instance { get; private set; }

		internal static ManualLogSource Log { get; private set; }

		internal static Harmony Harmony { get; private set; }

		private void Awake()
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			Game.isModded = true;
			PluginConfig.Bind(((BaseUnityPlugin)this).Config);
			Harmony = new Harmony("Allifreyr.ForeverBuild2");
			Harmony.PatchAll(Assembly.GetExecutingAssembly());
			Log.LogInfo((object)string.Format("{0} {1} loaded. Mode={2}, multiplier={3}", "Forever Build 2", "2.1.4", PluginConfig.Mode.Value, PluginConfig.SupportMultiplier.Value));
		}

		private void OnDestroy()
		{
			Harmony harmony = Harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
			Instance = null;
		}
	}
	public enum StabilityMode
	{
		Vanilla,
		Multiplier,
		Infinite
	}
	internal static class PluginConfig
	{
		internal static readonly ConfigSync ConfigSync = new ConfigSync("Allifreyr.ForeverBuild2")
		{
			DisplayName = "Forever Build 2",
			CurrentVersion = "2.1.4",
			MinimumRequiredVersion = "2.1.4",
			ModRequired = true
		};

		internal static ConfigEntry<bool> LockConfiguration { get; private set; }

		internal static ConfigEntry<bool> ModEnabled { get; private set; }

		internal static ConfigEntry<StabilityMode> Mode { get; private set; }

		internal static ConfigEntry<float> SupportMultiplier { get; private set; }

		internal static ConfigEntry<bool> ExtraLogging { get; private set; }

		internal static bool IsActive
		{
			get
			{
				if (ModEnabled.Value)
				{
					return Mode.Value != StabilityMode.Vanilla;
				}
				return false;
			}
		}

		internal static bool IsInfinite
		{
			get
			{
				if (ModEnabled.Value)
				{
					return Mode.Value == StabilityMode.Infinite;
				}
				return false;
			}
		}

		internal static float EffectiveMultiplier
		{
			get
			{
				float value = SupportMultiplier.Value;
				if (!(value < 1f))
				{
					return value;
				}
				return 1f;
			}
		}

		internal static void Bind(ConfigFile config)
		{
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Expected O, but got Unknown
			LockConfiguration = config.Bind<bool>("1 - General", "Lock Configuration", true, "If on, only the server/host (and server admins) can change synced settings. [Synced with Server]");
			((ConditionalConfigSync)ConfigSync).AddLockingConfigEntry<bool>(LockConfiguration);
			ModEnabled = BindServer(config, "1 - General", "Enable", defaultValue: true, "Master switch. Off leaves vanilla stability untouched. [Synced with Server]");
			Mode = BindServer(config, "2 - Stability", "Mode", StabilityMode.Infinite, "Vanilla: unchanged game math. Multiplier: support loss is divided by Support Multiplier (still needs a path to ground). Infinite: no support loss and pieces never collapse from stability, including mid-air. [Synced with Server]");
			SupportMultiplier = BindServer(config, "2 - Stability", "Support Multiplier", 2f, new ConfigDescription("Used when Mode is Multiplier. 2 is about twice vanilla reach, 3 about three times, and so on. Minimum 1 (vanilla-equivalent). Does not allow floating pieces. [Synced with Server]", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 100f), Array.Empty<object>()));
			ExtraLogging = BindClient(config, "3 - Debug", "Extra Logging", defaultValue: false, "Local only. Writes a line when Forever Build 2 changes a piece's support math.");
		}

		private static ConfigEntry<T> BindServer<T>(ConfigFile config, string section, string key, T defaultValue, string description)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			return BindServer(config, section, key, defaultValue, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>()));
		}

		private static ConfigEntry<T> BindServer<T>(ConfigFile config, string section, string key, T defaultValue, ConfigDescription description)
		{
			ConfigEntry<T> val = config.Bind<T>(section, key, defaultValue, description);
			((ConditionalConfigSync)ConfigSync).AddConfigEntry<T>(val, (ConfigSyncMode)0);
			return val;
		}

		private static ConfigEntry<T> BindClient<T>(ConfigFile config, string section, string key, T defaultValue, string description)
		{
			ConfigEntry<T> val = config.Bind<T>(section, key, defaultValue, description);
			((ConditionalConfigSync)ConfigSync).AddConfigEntry<T>(val, (ConfigSyncMode)2);
			return val;
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}