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 AdvancedHeightMap v0.1.0
AdvancedHeightMap.dll
Decompiled a day agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using AdvancedHeightMap.Helpers; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using Configs; using HarmonyLib; using Jotunn.Extensions; using Jotunn.Utils; using Logging; using Microsoft.CodeAnalysis; using SoftReferenceableAssets; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("AdvancedHeightMap")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("AdvancedHeightMap")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("08a6f7d7-cf93-4931-aecd-abf2ce6ed34c")] [assembly: AssemblyFileVersion("0.1.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.1.0.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 Logging { internal static class Log { internal enum InfoLevel { Low, Medium, High } private static ManualLogSource logSource; internal static ConfigEntry<InfoLevel> Verbosity { get; set; } internal static InfoLevel VerbosityLevel => Verbosity.Value; internal static bool IsVerbosityLow => Verbosity.Value >= InfoLevel.Low; internal static bool IsVerbosityMedium => Verbosity.Value >= InfoLevel.Medium; internal static bool IsVerbosityHigh => Verbosity.Value >= InfoLevel.High; internal static void Init(ManualLogSource logSource) { Log.logSource = logSource; } internal static void LogDebug(object data) { logSource.LogDebug(data); } internal static void LogError(object data) { logSource.LogError(data); } internal static void LogFatal(object data) { logSource.LogFatal(data); } internal static void LogMessage(object data) { logSource.LogMessage(data); } internal static void LogWarning(object data) { logSource.LogWarning(data); } internal static void LogInfo(object data, InfoLevel level = InfoLevel.Low) { if (Verbosity == null || VerbosityLevel >= level) { logSource.LogInfo(data); } } internal static void LogGameObject(GameObject prefab, bool includeChildren = false) { //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Expected O, but got Unknown LogInfo("***** " + ((Object)prefab).name + " *****"); Component[] components = prefab.GetComponents<Component>(); for (int i = 0; i < components.Length; i++) { LogComponent(components[i]); } if (!includeChildren) { return; } LogInfo("***** " + ((Object)prefab).name + " (children) *****"); foreach (Transform item in prefab.transform) { Transform val = item; if (Object.op_Implicit((Object)(object)val)) { LogInfo(" - " + ((Object)val).name); components = ((Component)val).GetComponents<Component>(); for (int i = 0; i < components.Length; i++) { LogComponent(components[i]); } } } } internal static void LogComponent(Component compo) { if (!Object.op_Implicit((Object)(object)compo)) { return; } try { LogInfo("--- " + ((object)compo).GetType().Name + ": " + ((Object)compo).name + " ---"); } catch (Exception ex) { LogError(ex.ToString()); LogWarning("Could not get type name for component!"); return; } try { foreach (PropertyInfo declaredProperty in AccessTools.GetDeclaredProperties(((object)compo).GetType())) { try { LogInfo($" - {declaredProperty.Name} = {declaredProperty.GetValue(compo)}"); } catch (Exception ex2) { LogError(ex2.ToString()); LogWarning("Could not get property: " + declaredProperty.Name + " for component!"); } } } catch (Exception ex3) { LogError(ex3.ToString()); LogWarning("Could not get properties for component!"); } try { foreach (FieldInfo declaredField in AccessTools.GetDeclaredFields(((object)compo).GetType())) { try { LogInfo($" - {declaredField.Name} = {declaredField.GetValue(compo)}"); } catch (Exception ex4) { LogError(ex4.ToString()); LogWarning("Could not get field: " + declaredField.Name + " for component!"); } } } catch (Exception ex5) { LogError(ex5.ToString()); LogWarning("Could not get fields for component!"); } } } } namespace Configs { public static class ConfigFileExtensions { public static bool DisableSaveOnConfigSet(this ConfigFile configFile) { bool saveOnConfigSet = configFile.SaveOnConfigSet; configFile.SaveOnConfigSet = false; return saveOnConfigSet; } } internal static class SafeInvokeEvent { internal static void SafeInvoke(this Action events) { if (events == null) { return; } Delegate[] invocationList = events.GetInvocationList(); for (int i = 0; i < invocationList.Length; i++) { Action action = (Action)invocationList[i]; try { action(); } catch (Exception arg) { Log.LogWarning("Exception thrown at event " + new StackFrame(1).GetMethod().Name + $" in {action.Method.DeclaringType.Name}.{action.Method.Name}:\n{arg}"); } } } } } namespace AdvancedHeightMap { [BepInPlugin("Searica.Valheim.AdvancedHeightMap", "AdvancedHeightMap", "0.1.0")] [BepInDependency("com.jotunn.jotunn", "2.30.2")] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] [SynchronizationMode(/*Could not decode attribute arguments.*/)] internal sealed class AdvancedHeightMap : BaseUnityPlugin { public const string PluginName = "AdvancedHeightMap"; internal const string Author = "Searica"; public const string PluginGUID = "Searica.Valheim.AdvancedHeightMap"; public const string PluginVersion = "0.1.0"; internal static AdvancedHeightMap Instance; internal static ConfigFile ConfigFile; internal static ConfigFileWatcher ConfigFileWatcher; internal const string MainConfigSection = "AdvancedHeightMap"; internal static ConfigEntry<float> MaxHeightChange; internal static ConfigEntry<float> MinHeightChange; internal static bool BoundConfigs; internal static float GetMaxHeightChange() { return MaxHeightChange.Value; } internal static float GetMinHeightChange() { return MinHeightChange.Value; } public void Awake() { //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Expected O, but got Unknown Instance = this; ConfigFile = ((BaseUnityPlugin)this).Config; Log.Init(((BaseUnityPlugin)this).Logger); ((BaseUnityPlugin)this).Config.DisableSaveOnConfigSet(); SetUpConfigEntries(); ((BaseUnityPlugin)this).Config.Save(); ((BaseUnityPlugin)this).Config.SaveOnConfigSet = true; Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "Searica.Valheim.AdvancedHeightMap"); Game.isModded = true; ConfigFileWatcher = new ConfigFileWatcher(((BaseUnityPlugin)this).Config, 1000L); } internal void SetUpConfigEntries() { Log.Verbosity = ConfigFileExtensions.BindConfigInOrder<Log.InfoLevel>(((BaseUnityPlugin)this).Config, "AdvancedHeightMap", "Verbosity", Log.InfoLevel.Low, "Low will log basic information about the mod. Medium will log information that is useful for troubleshooting. High will log a lot of information, do not set it to this without good reason as it will slow Down your game.", false, false, true, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); MaxHeightChange = ConfigFileExtensions.BindConfigInOrder<float>(((BaseUnityPlugin)this).Config, "AdvancedHeightMap", "MaxHeightChange", 200f, "How high you can raise terrain up relative to the heightmap's original position. Vanilla default is 8", true, false, true, (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 200f), (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); MinHeightChange = ConfigFileExtensions.BindConfigInOrder<float>(((BaseUnityPlugin)this).Config, "AdvancedHeightMap", "MinHeightChange", -200f, "How far you can dig down relative to the heightmap's original position. Vanilla default is -8", true, false, true, (AcceptableValueBase)(object)new AcceptableValueRange<float>(-200f, -1f), (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null); BoundConfigs = true; } public void OnDestroy() { ((BaseUnityPlugin)this).Config.Save(); } } public static class AdvancedHeightMapAPI { public static float GetMaxHeightChange() { if (AdvancedHeightMap.BoundConfigs) { return AdvancedHeightMap.MaxHeightChange.Value; } return 8f; } public static float GetMinHeightChange() { if (AdvancedHeightMap.BoundConfigs) { return AdvancedHeightMap.MinHeightChange.Value; } return 8f; } } [HarmonyPatch] internal static class HeightMapPatches { private static readonly MethodInfo ClampMethod = AccessTools.Method(typeof(Mathf), "Clamp", new Type[3] { typeof(float), typeof(float), typeof(float) }, (Type[])null); private static readonly CodeMatch[] TargetMatches = (CodeMatch[])(object)new CodeMatch[3] { new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction instruction) => CodeInstructionExtensions.LoadsConstant(instruction, -8.0)), (string)null), new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction instruction) => CodeInstructionExtensions.LoadsConstant(instruction, 8.0)), (string)null), new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction instruction) => CodeInstructionExtensions.Calls(instruction, ClampMethod)), (string)null) }; [HarmonyTranspiler] [HarmonyPatch(typeof(TerrainComp), "RaiseTerrain")] private static IEnumerable<CodeInstruction> ChangeRaiseTerrainLimits(IEnumerable<CodeInstruction> instructions) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown CodeMatcher val = new CodeMatcher((IEnumerable<CodeInstruction>)PatchHelper.Copy(instructions), (ILGenerator)null); if (val.TryMatchStartForward("RaiseTerrain Transpiler", TargetMatches)) { val.SetInstructionAndAdvance(Transpilers.EmitDelegate<Func<float>>((Func<float>)AdvancedHeightMap.GetMinHeightChange)); val.SetInstructionAndAdvance(Transpilers.EmitDelegate<Func<float>>((Func<float>)AdvancedHeightMap.GetMaxHeightChange)); return val.InstructionEnumeration(); } return instructions; } [HarmonyTranspiler] [HarmonyPatch(typeof(TerrainComp), "LevelTerrain")] private static IEnumerable<CodeInstruction> ChangeLevelTerrainLimits(IEnumerable<CodeInstruction> instructions) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown CodeMatcher val = new CodeMatcher((IEnumerable<CodeInstruction>)PatchHelper.Copy(instructions), (ILGenerator)null); if (val.TryMatchStartForward("LevelTerrain Transpiler", TargetMatches)) { val.SetInstructionAndAdvance(Transpilers.EmitDelegate<Func<float>>((Func<float>)AdvancedHeightMap.GetMinHeightChange)); val.SetInstructionAndAdvance(Transpilers.EmitDelegate<Func<float>>((Func<float>)AdvancedHeightMap.GetMaxHeightChange)); return val.InstructionEnumeration(); } return instructions; } [HarmonyTranspiler] [HarmonyPatch(typeof(TerrainComp), "ApplyToHeightmap")] private static IEnumerable<CodeInstruction> ChangeApplyToHeightmapLimits(IEnumerable<CodeInstruction> instructions) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Expected O, but got Unknown //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Expected O, but got Unknown //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Expected O, but got Unknown //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Expected O, but got Unknown CodeMatcher val = new CodeMatcher((IEnumerable<CodeInstruction>)PatchHelper.Copy(instructions), (ILGenerator)null); CodeMatch[] matches = (CodeMatch[])(object)new CodeMatch[2] { new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction instruction) => CodeInstructionExtensions.LoadsConstant(instruction, 8.0)), (string)null), new CodeMatch((OpCode?)OpCodes.Sub, (object)null, (string)null) }; CodeMatch[] matches2 = (CodeMatch[])(object)new CodeMatch[2] { new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction instruction) => CodeInstructionExtensions.LoadsConstant(instruction, 8.0)), (string)null), new CodeMatch((OpCode?)OpCodes.Add, (object)null, (string)null) }; if (val.TryMatchStartForward("ApplyToHeightMap Change Min Depth Transpiler", matches)) { val.SetInstructionAndAdvance(Transpilers.EmitDelegate<Func<float>>((Func<float>)AdvancedHeightMap.GetMinHeightChange)); val.SetInstructionAndAdvance(new CodeInstruction(OpCodes.Add, (object)null)); } if (val.TryMatchStartForward("ApplyToHeightMap Change Max Height Transpiler", matches2)) { val.SetInstructionAndAdvance(Transpilers.EmitDelegate<Func<float>>((Func<float>)AdvancedHeightMap.GetMaxHeightChange)); } if (val.IsValid) { return val.InstructionEnumeration(); } return instructions; } } } namespace AdvancedHeightMap.Helpers { internal static class PatchHelper { internal const int AnyCount = -1; internal static List<CodeInstruction> Copy(IEnumerable<CodeInstruction> instructions) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown List<CodeInstruction> list = ((instructions is ICollection<CodeInstruction> collection) ? new List<CodeInstruction>(collection.Count) : new List<CodeInstruction>()); foreach (CodeInstruction instruction in instructions) { list.Add(new CodeInstruction(instruction)); } return list; } internal static IEnumerable<CodeInstruction> ReplaceCalls(IEnumerable<CodeInstruction> instructions, MethodInfo original, MethodInfo replacement, string site, int expected = -1) { if (original == null || replacement == null) { Log.LogWarning(site + ": a method this fix needs could not be resolved, so it is inactive here."); return instructions; } List<CodeInstruction> list = Copy(instructions); int num = 0; for (int i = 0; i < list.Count; i++) { if (CodeInstructionExtensions.Calls(list[i], original)) { list[i].opcode = OpCodes.Call; list[i].operand = replacement; num++; } } if ((expected == -1) ? (num > 0) : (num == expected)) { return list; } string text = ((expected == -1) ? "at least 1" : expected.ToString()); Log.LogWarning(site + ": expected " + text + " call(s) to " + original.DeclaringType?.Name + "." + original.Name + ", " + $"found {num}, so this fix is inactive here. Another mod has most likely already " + "rewritten the method - if so, nothing is wrong."); return instructions; } internal static IEnumerable<CodeInstruction> ReplaceAllMatches(IEnumerable<CodeInstruction> instructions, CodeMatch[] pattern, CodeInstruction[] replacement, string site, int expected = -1) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null); int num = 0; while (val.MatchStartForward(pattern).IsValid) { for (int i = 1; i < pattern.Length; i++) { CodeInstruction val2 = val.InstructionAt(i); if (val2.labels.Count != 0 || val2.blocks.Count != 0) { Log.LogWarning(site + ": a jump or exception block lands inside the code this fix rewrites, so it is inactive here. Another mod has most likely already rewritten the method - if so, nothing is wrong."); return instructions; } } CodeInstruction[] array = (CodeInstruction[])(object)new CodeInstruction[replacement.Length]; for (int j = 0; j < array.Length; j++) { array[j] = replacement[j].Clone(); } CodeInstructionExtensions.MoveBlocksFrom(CodeInstructionExtensions.MoveLabelsFrom(array[0], val.Instruction), val.Instruction); val.RemoveInstructions(pattern.Length).InsertAndAdvance(array); num++; } if ((expected == -1) ? (num > 0) : (num == expected)) { return val.InstructionEnumeration(); } string arg = ((expected == -1) ? "at least 1" : expected.ToString()); Log.LogWarning($"{site}: expected {arg} match(es) of the code this fix rewrites, found {num}, " + "so this fix is inactive here. Another mod has most likely already rewritten the method - if so, nothing is wrong."); return instructions; } public static bool TryMatchStartForward(this CodeMatcher matcher, string failureMessage, params CodeMatch[] matches) { matcher.MatchStartForward(matches); if (matcher.IsInvalid) { Log.LogWarning(failureMessage + " Anchor instruction not found, it was likely consumed by another mod. Skipping this patch."); return false; } return true; } public static bool TryMatchStartForward(this CodeMatcher matcher, params CodeMatch[] matches) { matcher.MatchStartForward(matches); if (matcher.IsInvalid) { return false; } return true; } public static bool TryMatchStartBackwards(this CodeMatcher matcher, string failureMessage, params CodeMatch[] matches) { matcher.MatchStartBackwards(matches); if (matcher.IsInvalid) { Log.LogWarning(failureMessage + " Anchor instruction not found, it was likely consumed by another mod. Skipping this patch."); return false; } return true; } public static bool TryMatchStartBackwards(this CodeMatcher matcher, params CodeMatch[] matches) { matcher.MatchStartBackwards(matches); if (matcher.IsInvalid) { return false; } return true; } public static bool TryMatchEndForward(this CodeMatcher matcher, string failureMessage, params CodeMatch[] matches) { matcher.MatchEndForward(matches); if (matcher.IsInvalid) { Log.LogWarning(failureMessage + " Anchor instruction not found, it was likely consumed by another mod. Skipping this patch."); return false; } return true; } public static bool TryMatchEndForward(this CodeMatcher matcher, params CodeMatch[] matches) { matcher.MatchEndForward(matches); if (matcher.IsInvalid) { return false; } return true; } } } namespace AdvancedHeightMap.Extensions { internal static class AssetBundleLoaderExtensions { private static readonly Dictionary<BundleLoader, HashSet<AssetID>> _bundleLoaderToAssetIDsMap = new Dictionary<BundleLoader, HashSet<AssetID>>(); private static Dictionary<BundleLoader, HashSet<AssetID>> GetBundleLoaderToAssetIDDependeciesMap() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0039: 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_005a: 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) if (_bundleLoaderToAssetIDsMap.Count == 0) { AssetLoader[] assetLoaders = AssetBundleLoader.Instance.m_assetLoaders; foreach (AssetLoader val in assetLoaders) { BundleLoader bundleLoaderFromAssetID = AssetBundleLoader.Instance.GetBundleLoaderFromAssetID(val.m_assetID); if (!_bundleLoaderToAssetIDsMap.TryGetValue(bundleLoaderFromAssetID, out var value)) { value = new HashSet<AssetID>(); _bundleLoaderToAssetIDsMap[bundleLoaderFromAssetID] = value; } value.Add(val.m_assetID); } } return _bundleLoaderToAssetIDsMap; } internal static BundleLoader GetBundleLoaderFromAssetID(this AssetBundleLoader assetBundleLoader, AssetID assetID) { //IL_0001: 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_000c: 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_0019: Unknown result type (might be due to invalid IL or missing references) AssetLoader loader = assetBundleLoader.GetLoader(assetID); return assetBundleLoader.m_bundleLoaders[loader.m_bundleLoaderIndex]; } internal static HashSet<AssetID> GetDependenciesFromAssetID(this AssetBundleLoader assetBundleLoader, AssetID assetID) { //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_002b: Unknown result type (might be due to invalid IL or missing references) BundleLoader bundleLoaderFromAssetID = assetBundleLoader.GetBundleLoaderFromAssetID(assetID); List<AssetID> list = new List<AssetID>(); Dictionary<BundleLoader, HashSet<AssetID>> bundleLoaderToAssetIDDependeciesMap = GetBundleLoaderToAssetIDDependeciesMap(); int[] bundleLoaderIndicesOfThisAndDependencies = bundleLoaderFromAssetID.m_bundleLoaderIndicesOfThisAndDependencies; foreach (int num in bundleLoaderIndicesOfThisAndDependencies) { if (bundleLoaderToAssetIDDependeciesMap.TryGetValue(assetBundleLoader.m_bundleLoaders[num], out var value)) { list.AddRange(value); } } return list.ToHashSet(); } } internal static class GameObjectExtensions { public static bool IsRootPrefab(this GameObject go) { return !Object.op_Implicit((Object)(object)go.transform.parent); } } } namespace AdvancedHeightMap.API { public static class AdvanedHeightMapInfo { public const string PluginGUID = "Searica.Valheim.AdvancedHeightMap"; } public static class AdvancedHeightMapAPI { private const string ReceiverTypeName = "AdvancedHeightMap.API.APIReceiver"; private const string ReceiverAssemblyName = "AdvancedHeightMap"; private static readonly Type APIReceiver; private static readonly List<string> Unbound; private static readonly Func<int> getApiVersion; private static readonly Func<float> getMaxHeightChange; private static readonly Func<float> getMinHeightChange; public static bool IsAvailable => APIReceiver != null; public static int ReceiverApiVersion { get { if (getApiVersion == null) { return 0; } return getApiVersion(); } } static AdvancedHeightMapAPI() { Unbound = new List<string>(); APIReceiver = FindReceiver(); if (!(APIReceiver == null)) { getApiVersion = Bind<Func<int>>("GetApiVersion"); getMaxHeightChange = Bind<Func<float>>("GetMaxHeightChange"); getMinHeightChange = Bind<Func<float>>("GetMinHeightChange"); } } private static Type FindReceiver() { Type type = null; try { type = Type.GetType("AdvancedHeightMap.API.APIReceiver, AdvancedHeightMap", throwOnError: false); } catch (Exception) { } if (type != null) { return type; } Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { if (!(assembly.GetName().Name != "AdvancedHeightMap")) { type = assembly.GetType("AdvancedHeightMap.API.APIReceiver", throwOnError: false); if (type != null) { return type; } } } return null; } private static T Bind<T>(string name) where T : class { MethodInfo method = typeof(T).GetMethod("Invoke"); ParameterInfo[] parameters = method.GetParameters(); Type[] array = new Type[parameters.Length]; for (int i = 0; i < parameters.Length; i++) { array[i] = parameters[i].ParameterType; } MethodInfo method2 = APIReceiver.GetMethod(name, BindingFlags.Static | BindingFlags.Public, null, array, null); T obj = ((method2 != null && method2.ReturnType == method.ReturnType) ? (Delegate.CreateDelegate(typeof(T), method2, throwOnBindFailure: false) as T) : null); if (obj == null) { Unbound.Add(name); } return obj; } public static float GetMaxHeightChange() { if (getMaxHeightChange == null) { return 8f; } return getMaxHeightChange(); } public static float GetMinHeightChange() { if (getMinHeightChange == null) { return -8f; } return getMinHeightChange(); } } public static class APIReceiver { internal const int ApiVersion = 1; public static int GetApiVersion() { return 1; } public static float GetMaxHeightChange() { if (AdvancedHeightMap.BoundConfigs) { return AdvancedHeightMap.MaxHeightChange.Value; } return 8f; } public static float GetMinHeightChange() { if (AdvancedHeightMap.BoundConfigs) { return AdvancedHeightMap.MinHeightChange.Value; } return 8f; } } }