Decompiled source of TagConnectedPortals v0.1.2

TagConnectedPortals.dll

Decompiled 4 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("RenameConnectedPortals")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("RenameConnectedPortals")]
[assembly: AssemblyCopyright("Copyright ©  2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("9f8a1b6e-6d0e-4dab-bbd8-9ed433836544")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
internal sealed class ConfigurationManagerAttributes
{
	public delegate void CustomHotkeyDrawerFunc(ConfigEntryBase setting, ref bool isCurrentlyAcceptingInput);

	public bool? ShowRangeAsPercent;

	public Action<ConfigEntryBase> CustomDrawer;

	public CustomHotkeyDrawerFunc CustomHotkeyDrawer;

	public bool? Browsable;

	public string Category;

	public object DefaultValue;

	public bool? HideDefaultButton;

	public bool? HideSettingName;

	public string Description;

	public string DispName;

	public int? Order;

	public bool? ReadOnly;

	public bool? IsAdvanced;

	public Func<object, string> ObjToStr;

	public Func<string, object> StrToObj;
}
namespace neobotics.ValheimMods;

public class DelegatedConfigEntry<T> : DelegatedConfigEntryBase
{
	private ConfigEntry<T> _entry;

	private EventHandler rootHandler;

	private Action<object, EventArgs> clientDelegate;

	private Logging Log;

	public ConfigEntry<T> ConfigEntry
	{
		get
		{
			return _entry;
		}
		set
		{
			_entry = value;
			if (_entry != null && rootHandler != null)
			{
				_entry.SettingChanged += rootHandler;
			}
			Name = ((ConfigEntryBase)_entry).Definition.Key;
			Section = ((ConfigEntryBase)_entry).Definition.Section;
			ServerValue = ((ConfigEntryBase)_entry).GetSerializedValue();
			Log.Trace("Set " + Section + " " + Name + " to serialized value " + ServerValue);
		}
	}

	public T Value
	{
		get
		{
			return _entry.Value;
		}
		set
		{
			_entry.Value = value;
		}
	}

	public DelegatedConfigEntry(bool useServerDelegate = false)
		: this((Action<object, EventArgs>)null, useServerDelegate)
	{
	}

	public DelegatedConfigEntry(Action<object, EventArgs> delegateHandler, bool useServerDelegate = false)
	{
		Log = Logging.GetLogger();
		Log.Trace("DelegatedConfigEntry");
		if (delegateHandler != null)
		{
			clientDelegate = delegateHandler;
		}
		if (useServerDelegate)
		{
			Log.Trace("Configuring server delegate");
			rootHandler = delegate(object s, EventArgs e)
			{
				ServerDelegate(s, e);
			};
			ServerConfiguration.ServerDelegatedEntries.Add(this);
		}
		else if (clientDelegate != null)
		{
			rootHandler = delegate(object s, EventArgs e)
			{
				clientDelegate(s, e);
			};
		}
	}

	private void ServerDelegate(object sender, EventArgs args)
	{
		//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ea: Expected O, but got Unknown
		Logging.GetLogger().Trace("ServerDelegate");
		_entry.SettingChanged -= rootHandler;
		ZNet instance = ZNet.instance;
		bool? flag = ((instance != null) ? new bool?(instance.IsServer()) : null);
		if (flag.HasValue)
		{
			if (flag == false && ServerConfiguration.Instance.ReceivedServerValues)
			{
				if (ServerValue != null)
				{
					((ConfigEntryBase)_entry).SetSerializedValue(ServerValue);
					Log.Debug("Setting " + Name + " to server value " + ServerValue);
				}
			}
			else if (flag == true)
			{
				ServerValue = ((ConfigEntryBase)_entry).GetSerializedValue();
				ServerConfiguration.Instance.SendConfigToAllClients(sender, (SettingChangedEventArgs)args);
			}
		}
		if (clientDelegate != null)
		{
			clientDelegate(sender, args);
		}
		_entry.SettingChanged += rootHandler;
	}

	public void EnableHandler(bool setActive)
	{
		if (setActive)
		{
			_entry.SettingChanged += rootHandler;
		}
		else
		{
			_entry.SettingChanged -= rootHandler;
		}
	}

	public bool IsKeyPressed()
	{
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_003a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0060: Unknown result type (might be due to invalid IL or missing references)
		if (ConfigEntry is ConfigEntry<KeyboardShortcut> val)
		{
			KeyboardShortcut value = val.Value;
			foreach (KeyCode modifier in ((KeyboardShortcut)(ref value)).Modifiers)
			{
				if (!Input.GetKey(modifier))
				{
					return false;
				}
			}
			if (!Input.GetKeyDown(((KeyboardShortcut)(ref value)).MainKey))
			{
				return false;
			}
			return true;
		}
		Log.Error("Keyboard read attempted on non-KeyboardShortcut config.");
		return false;
	}

	public bool IsKeyDown()
	{
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_003a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0060: Unknown result type (might be due to invalid IL or missing references)
		if (ConfigEntry is ConfigEntry<KeyboardShortcut> val)
		{
			KeyboardShortcut value = val.Value;
			foreach (KeyCode modifier in ((KeyboardShortcut)(ref value)).Modifiers)
			{
				if (!Input.GetKey(modifier))
				{
					return false;
				}
			}
			if (!Input.GetKey(((KeyboardShortcut)(ref value)).MainKey))
			{
				return false;
			}
			return true;
		}
		Log.Error("Keyboard read attempted on non-KeyboardShortcut config.");
		return false;
	}

	public bool IsKeyReleased()
	{
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_003a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0060: Unknown result type (might be due to invalid IL or missing references)
		if (ConfigEntry is ConfigEntry<KeyboardShortcut> val)
		{
			KeyboardShortcut value = val.Value;
			foreach (KeyCode modifier in ((KeyboardShortcut)(ref value)).Modifiers)
			{
				if (!Input.GetKeyUp(modifier))
				{
					return false;
				}
			}
			if (!Input.GetKeyUp(((KeyboardShortcut)(ref value)).MainKey))
			{
				return false;
			}
			return true;
		}
		Log.Error("Keyboard read attempted on non-KeyboardShortcut config.");
		return false;
	}
}
public class DelegatedConfigEntryBase
{
	public string Name;

	public string Section;

	public string ServerValue;
}
public class ImageHelper
{
	private string resources;

	private bool isEmbedded;

	private Logging logger;

	public ImageHelper(string resourceLocation, bool embedded)
	{
		resources = resourceLocation;
		logger = Logging.GetLogger();
		isEmbedded = embedded;
	}

	public Sprite LoadSprite(string name, int width, int height, bool linear = false, float pixelsPerUnit = 100f)
	{
		logger.Debug("Reading image and creating sprite " + name);
		if (TryLoadImage(name, width, height, linear, out var image))
		{
			return LoadSprite(image, pixelsPerUnit);
		}
		return null;
	}

	public Sprite LoadSprite(Texture2D texture, float pixelsPerUnit = 100f)
	{
		return LoadSprite(texture, ((Object)texture).name, ((Texture)texture).width, ((Texture)texture).height, pixelsPerUnit);
	}

	public Sprite LoadSprite(Texture2D texture, string name, float width, float height, float pixelsPerUnit = 100f)
	{
		//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)
		if ((Object)(object)texture == (Object)null)
		{
			return null;
		}
		if (Utility.IsNullOrWhiteSpace(name))
		{
			name = ((Object)texture).name;
		}
		logger.Debug("Creating sprite " + name + " from existing texture");
		Sprite obj = Sprite.Create(texture, new Rect(0f, 0f, width, height), Vector2.zero, pixelsPerUnit);
		if ((Object)(object)obj == (Object)null)
		{
			throw new ApplicationException("Can't create sprite " + name);
		}
		((Object)obj).name = name;
		return obj;
	}

	public bool TryLoadImage(string name, int width, int height, bool linear, out Texture2D image)
	{
		//IL_015e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0164: Expected O, but got Unknown
		image = null;
		logger.Debug("Loading " + name + " from " + resources);
		Stream stream = null;
		if (isEmbedded)
		{
			stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resources + "." + name);
		}
		else
		{
			char directorySeparatorChar = Path.DirectorySeparatorChar;
			string text = (Utility.IsNullOrWhiteSpace(resources) ? "/" : resources);
			if (!text.EndsWith("/"))
			{
				text += directorySeparatorChar;
			}
			string text2 = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + text + name;
			text2 = text2.Replace('\\', directorySeparatorChar).Replace('/', directorySeparatorChar);
			try
			{
				logger.Debug("Reading file " + text2);
				stream = new FileStream(text2, FileMode.Open, FileAccess.Read);
			}
			catch (Exception ex)
			{
				logger.Warning("Error loading external resource. Using embedded resource: " + ex.Message);
				stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resources + "." + name);
			}
		}
		if (stream == null)
		{
			throw new FileNotFoundException("Can't find " + name + " in " + resources);
		}
		byte[] array = new byte[stream.Length];
		stream.Read(array, 0, (int)stream.Length);
		Texture2D val = new Texture2D(width, height, (TextureFormat)4, true, linear);
		logger.Debug("Loading image " + name);
		if (ImageConversion.LoadImage(val, array, false))
		{
			image = val;
			return true;
		}
		throw new FileLoadException("Can't load " + name);
	}
}
public class IterativeStopwatch : Stopwatch
{
	private double startMillis;

	private Logging Log = Logging.GetLogger();

	public long Iterations { get; private set; }

	public double IterationMicroseconds { get; private set; }

	public double TotalElapsedMicroseconds { get; private set; }

	public double IterationMilliseconds { get; private set; }

	public double TotalElapsedMilliseconds { get; private set; }

	public double AverageMicroseconds { get; private set; }

	public double AverageMilliseconds { get; private set; }

	public IterativeStopwatch()
	{
		Iterations = 0L;
	}

	public new void Start()
	{
		startMillis = base.Elapsed.TotalMilliseconds;
		base.Start();
	}

	public new void Stop()
	{
		if (base.IsRunning)
		{
			base.Stop();
			Iterations++;
			IterationMilliseconds = base.Elapsed.TotalMilliseconds - startMillis;
			IterationMicroseconds = IterationMilliseconds * 1000.0;
			TotalElapsedMilliseconds = base.Elapsed.TotalMilliseconds;
			TotalElapsedMicroseconds = base.Elapsed.TotalMilliseconds * 1000.0;
			AverageMilliseconds = TotalElapsedMilliseconds / (double)Iterations;
			AverageMicroseconds = TotalElapsedMicroseconds / (double)Iterations;
		}
	}

	public new void Reset()
	{
		startMillis = 0.0;
		Iterations = 0L;
		base.Reset();
	}

	public new void Restart()
	{
		startMillis = 0.0;
		Iterations = 0L;
		base.Restart();
	}
}
public class Logging
{
	public enum LogLevels
	{
		Critical,
		Error,
		Warning,
		Info,
		Debug,
		Trace
	}

	private static Logging _logger;

	public LogLevels LogLevel { get; set; }

	public string ModName { get; set; }

	private Logging(LogLevels level, string name)
	{
		LogLevel = level;
		ModName = name;
	}

	public static Logging GetLogger(LogLevels level, string name)
	{
		if (_logger == null)
		{
			_logger = new Logging(level, name);
		}
		return _logger;
	}

	public static Logging GetLogger()
	{
		if (_logger == null)
		{
			throw new NullReferenceException("Logger not initialized");
		}
		return _logger;
	}

	public void Trace(string msg)
	{
		if (LogLevel >= LogLevels.Trace)
		{
			Debug.Log((object)Message(msg));
		}
	}

	public void Debug(string msg)
	{
		if (LogLevel >= LogLevels.Debug)
		{
			Debug.Log((object)Message(msg));
		}
	}

	public void Info(string msg)
	{
		if (LogLevel >= LogLevels.Info)
		{
			Debug.Log((object)Message(msg));
		}
	}

	public void Warning(string msg)
	{
		if (LogLevel >= LogLevels.Warning)
		{
			Debug.LogWarning((object)Message(msg));
		}
	}

	public void Error(string msg)
	{
		if (LogLevel >= LogLevels.Error)
		{
			Debug.LogWarning((object)Message(msg));
		}
	}

	public void Error(Exception e)
	{
		Error(e, stackTrace: false);
	}

	public void Error(Exception e, bool stackTrace)
	{
		if (LogLevel >= LogLevels.Error)
		{
			Warning(Message(e.Message));
			if (stackTrace)
			{
				Warning(e.StackTrace);
			}
		}
	}

	public void Critical(Exception e)
	{
		if (LogLevel >= LogLevels.Critical)
		{
			Debug(Message(e.Message));
			Error(e.StackTrace);
		}
	}

	private string Message(string msg)
	{
		return ModName + ": " + msg;
	}

	public static void ChangeLogging(object s, EventArgs e)
	{
		SettingChangedEventArgs val = (SettingChangedEventArgs)(object)((e is SettingChangedEventArgs) ? e : null);
		GetLogger().Debug($"ChangeLog {val.ChangedSetting.Definition.Key} to {val.ChangedSetting.BoxedValue}");
		GetLogger().LogLevel = Cfg.debugLevel.Value;
	}
}
public class ServerConfiguration
{
	[HarmonyPatch(typeof(ZNet), "StopAll")]
	private static class ZNet_Shutdown_Patch
	{
		[HarmonyPrefix]
		private static void ZNet_StopAll_Prefix(ZNet __instance)
		{
			Log.Debug("ZNet_StopAll_Patch_Prefix");
			Instance.ReceivedServerValues = false;
		}
	}

	[HarmonyPatch(typeof(ZNet), "OnNewConnection")]
	private static class ZNet_OnNewConnection_Patch
	{
		private static void Postfix(ZNet __instance, ZNetPeer peer)
		{
			Log.Debug("ZNet OnNewConnection postfix");
			if (!__instance.IsServer())
			{
				try
				{
					peer.m_rpc.Register<ZPackage>("ClientConfigReceiver." + GetPluginGuid(), (Action<ZRpc, ZPackage>)Instance.RPC_ClientConfigReceiver);
					Log.Debug("Player registered RPC_ClientConfigReceiver");
					return;
				}
				catch (Exception)
				{
					Log.Warning("Failed to register RPC");
					return;
				}
			}
			try
			{
				Instance.SendConfigToClient(peer);
			}
			catch (Exception)
			{
				Log.Warning("Error sending server configuration to client");
			}
		}
	}

	public static List<DelegatedConfigEntryBase> ServerDelegatedEntries = new List<DelegatedConfigEntryBase>();

	private static ConfigFile LocalConfig;

	private static BaseUnityPlugin Mod;

	private static string ConfigFileName;

	private static ServerConfiguration _instance;

	private static Logging Log;

	public bool IsSetup;

	public bool ReceivedServerValues;

	public FileSystemWatcher ConfigWatcher;

	private const string NOT_CONFIGURED = "ServerConfiguration not initialized. Setup first.";

	public static ServerConfiguration Instance
	{
		get
		{
			if (_instance == null)
			{
				_instance = new ServerConfiguration();
			}
			return _instance;
		}
	}

	private ServerConfiguration()
	{
	}

	public void Setup(ConfigFile config, BaseUnityPlugin modInstance)
	{
		LocalConfig = config;
		Log = Logging.GetLogger();
		Log.Trace("ServerConfiguration Setup");
		Mod = modInstance;
		ConfigFileName = Path.GetFileName(LocalConfig.ConfigFilePath);
		IsSetup = true;
	}

	public void CreateConfigWatcher()
	{
		ConfigWatcher = Utils.CreateFileWatcher(LocalConfig.ConfigFilePath, LoadConfig);
	}

	private void LoadConfig(object sender, FileSystemEventArgs e)
	{
		if (!File.Exists(LocalConfig.ConfigFilePath))
		{
			return;
		}
		try
		{
			Log.Debug($"Loading configuration {e.ChangeType}");
			LocalConfig.Reload();
		}
		catch
		{
			Log.Error("Error loading configuration file " + ConfigFileName);
		}
	}

	public static string GetPluginGuid()
	{
		return Mod.Info.Metadata.GUID;
	}

	public void RPC_ClientConfigReceiver(ZRpc zrpc, ZPackage package)
	{
		if (!Instance.IsSetup)
		{
			Log.Error("ServerConfiguration not initialized. Setup first.");
			return;
		}
		Log.Debug("ClientConfigReceiver");
		string section;
		string name;
		while (package.GetPos() < package.Size())
		{
			section = package.ReadString();
			name = package.ReadString();
			string text = package.ReadString();
			Log.Trace("Reading " + section + " " + name + " value " + text + " from ZPackage");
			DelegatedConfigEntryBase delegatedConfigEntryBase = ServerDelegatedEntries.Find((DelegatedConfigEntryBase e) => e.Name == name && e.Section == section);
			if (delegatedConfigEntryBase != null)
			{
				Log.Trace("Found DCEB on client and setting to server value " + text);
				delegatedConfigEntryBase.ServerValue = text;
			}
			ConfigEntryBase val = LocalConfig[section, name];
			if (val != null)
			{
				Log.Trace("Found local CEB and setting underlying config value " + text);
				val.SetSerializedValue(text);
			}
		}
		ReceivedServerValues = true;
	}

	internal void WriteConfigEntries(ZPackage zpkg)
	{
		foreach (DelegatedConfigEntryBase serverDelegatedEntry in ServerDelegatedEntries)
		{
			Log.Trace("Writing " + serverDelegatedEntry.Section + " " + serverDelegatedEntry.Name + " value " + serverDelegatedEntry.ServerValue + " to ZPackage");
			zpkg.Write(serverDelegatedEntry.Section);
			zpkg.Write(serverDelegatedEntry.Name);
			zpkg.Write(serverDelegatedEntry.ServerValue);
		}
	}

	internal void SendConfigToClient(ZNetPeer peer)
	{
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0031: Expected O, but got Unknown
		if (!Instance.IsSetup)
		{
			Log.Error("ServerConfiguration not initialized. Setup first.");
			return;
		}
		Log.Debug("SendConfigToClient");
		ZPackage val = new ZPackage();
		WriteConfigEntries(val);
		peer.m_rpc.Invoke("ClientConfigReceiver." + GetPluginGuid(), new object[1] { val });
		Log.Trace("Invoked ClientConfigReceiver on peer");
	}

	public void SendConfigToAllClients(object o, SettingChangedEventArgs e)
	{
		//IL_004d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0053: Expected O, but got Unknown
		if (!IsSetup)
		{
			Log.Error("ServerConfiguration not initialized. Setup first.");
		}
		else if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer() && ZNet.instance.GetPeerConnections() > 0)
		{
			Log.Debug("SendConfigToAllClients");
			ZPackage zpkg = new ZPackage();
			WriteConfigEntries(zpkg);
			((MonoBehaviour)Mod).StartCoroutine(_instance.Co_BroadcastConfig(zpkg));
		}
	}

	private IEnumerator Co_BroadcastConfig(ZPackage zpkg)
	{
		Log.Debug("Co_BroadcastConfig");
		List<ZNetPeer> connectedPeers = ZNet.instance.GetConnectedPeers();
		foreach (ZNetPeer item in connectedPeers)
		{
			if (item != ZNet.instance.GetServerPeer())
			{
				item.m_rpc.Invoke("ClientConfigReceiver." + GetPluginGuid(), new object[1] { zpkg });
				Log.Trace("Invoked ClientConfigReceiver on peer");
			}
			yield return null;
		}
	}
}
internal class Utils
{
	public static TEnum Guardrails<TEnum>(string value, TEnum enumDefault) where TEnum : struct
	{
		if (Enum.TryParse<TEnum>(value, ignoreCase: true, out var result))
		{
			return result;
		}
		return enumDefault;
	}

	public static int Guardrails(int value, int lbound, int ubound)
	{
		if (value < lbound)
		{
			return lbound;
		}
		if (value > ubound)
		{
			return ubound;
		}
		return value;
	}

	public static string truncate(string value, int maxChars)
	{
		if (value == null)
		{
			return null;
		}
		if (value.Length <= maxChars)
		{
			return value;
		}
		return value.Substring(0, maxChars);
	}

	public static void GetCharactersInRangeXZ(Vector3 point, float radius, List<Character> characters)
	{
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		float num = radius * radius;
		foreach (Character s_character in Character.s_characters)
		{
			if (DistanceSqrXZ(((Component)s_character).transform.position, point) < num)
			{
				characters.Add(s_character);
			}
		}
	}

	public static float DistanceSqr(Vector3 v0, Vector3 v1)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: 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_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		float num = v1.x - v0.x;
		float num2 = v1.y - v0.y;
		float num3 = v1.z - v0.z;
		return num * num + num2 * num2 + num3 * num3;
	}

	public static float DistanceSqrXZ(Vector3 v0, Vector3 v1)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: 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)
		float num = v1.x - v0.x;
		float num2 = v1.z - v0.z;
		return num * num + num2 * num2;
	}

	public static float DistanceXZ(Vector3 v0, Vector3 v1)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: 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)
		float num = v1.x - v0.x;
		float num2 = v1.z - v0.z;
		return Mathf.Sqrt(num * num + num2 * num2);
	}

	public static float Guardrails(float value, float lbound, float ubound)
	{
		if (value < lbound)
		{
			return lbound;
		}
		if (value > ubound)
		{
			return ubound;
		}
		return value;
	}

	public static string UnClonifiedName(string name)
	{
		if (name == null)
		{
			return null;
		}
		int num = name.IndexOf("(Clone)");
		if (num < 1)
		{
			return name;
		}
		return name.Substring(0, num);
	}

	public static void SetTranslator(int id, string idText)
	{
		typeof(Localization).GetMethod("AddWord", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(Localization.instance, new object[2]
		{
			"skill_" + id,
			idText
		});
	}

	public static string GetTranslated(int id)
	{
		Logging.GetLogger().Debug(string.Format("Got translation for id {0} to {1}", id, Localization.instance.Localize("skill_" + id)));
		return Localization.instance.Localize("$skill_" + id);
	}

	public static string GetAssemblyPathedFile(string fileName)
	{
		return new FileInfo(Assembly.GetExecutingAssembly().Location).DirectoryName.Replace('\\', '/') + "/" + fileName;
	}

	public static Sprite GetPrefabIcon(string prefabName)
	{
		Sprite result = null;
		GameObject prefab = GetPrefab(prefabName);
		ItemDrop val = default(ItemDrop);
		if ((Object)(object)prefab != (Object)null && prefab.TryGetComponent<ItemDrop>(ref val))
		{
			result = val.m_itemData.GetIcon();
		}
		return result;
	}

	public static Player GetPlayerByZDOID(ZDOID zid)
	{
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		foreach (Player allPlayer in Player.GetAllPlayers())
		{
			ZDOID zDOID = ((Character)allPlayer).GetZDOID();
			if (((ZDOID)(ref zDOID)).Equals(zid))
			{
				return allPlayer;
			}
		}
		return null;
	}

	public static Character GetCharacterByZDOID(string cid)
	{
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		foreach (Character allCharacter in Character.GetAllCharacters())
		{
			ZDOID zDOID = allCharacter.GetZDOID();
			if (((object)(ZDOID)(ref zDOID)).ToString().Equals(cid))
			{
				return allCharacter;
			}
		}
		return null;
	}

	public static Character GetCharacterByZDOID(ZDOID cid)
	{
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		foreach (Character allCharacter in Character.GetAllCharacters())
		{
			ZDOID zDOID = allCharacter.GetZDOID();
			if (((ZDOID)(ref zDOID)).Equals(cid))
			{
				return allCharacter;
			}
		}
		return null;
	}

	public static ZNetPeer GetPeerByRPC(ZRpc rpc)
	{
		foreach (ZNetPeer peer in ZNet.instance.GetPeers())
		{
			if (peer.m_rpc == rpc)
			{
				return peer;
			}
		}
		return null;
	}

	public static List<GameObject> GetGameObjectsOfType(Type t)
	{
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		List<GameObject> list = new List<GameObject>();
		Object[] array = Object.FindObjectsOfType(t);
		foreach (Object val in array)
		{
			list.Add(((Component)val).gameObject);
		}
		return list;
	}

	public static GameObject GetClosestGameObjectOfType(Type t, Vector3 point, float radius)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		return GetGameObjectsOfTypeInRangeByDistance(t, point, radius)?[0];
	}

	public static List<GameObject> GetGameObjectsOfTypeInRangeByDistance(Type t, Vector3 point, float radius)
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_0034: 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)
		List<KeyValuePair<GameObject, float>> list = new List<KeyValuePair<GameObject, float>>();
		List<GameObject> gameObjectsOfTypeInRange = GetGameObjectsOfTypeInRange(t, point, radius);
		if (gameObjectsOfTypeInRange.Count > 0)
		{
			foreach (GameObject item in gameObjectsOfTypeInRange)
			{
				list.Add(new KeyValuePair<GameObject, float>(item, Vector3.Distance(item.transform.position, point)));
			}
			list.Sort((KeyValuePair<GameObject, float> pair1, KeyValuePair<GameObject, float> pair2) => pair1.Value.CompareTo(pair2.Value));
			return list.ConvertAll((KeyValuePair<GameObject, float> x) => x.Key);
		}
		return null;
	}

	public static List<GameObject> GetGameObjectsOfTypeInRange(Type t, Vector3 point, float radius)
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		return (from x in GetGameObjectsOfType(t)
			where Vector3.Distance(x.transform.position, point) < radius
			select x).ToList();
	}

	public static float GetPointDepth(Vector3 p)
	{
		//IL_000a: Unknown result type (might be due to invalid IL or missing references)
		return ZoneSystem.instance.m_waterLevel - GetSolidHeight(p);
	}

	public static List<string> GetDelimitedStringAsList(string delimitedString, char delimiter)
	{
		List<string> list = new List<string>();
		string[] array = delimitedString.Split(new char[1] { delimiter }, StringSplitOptions.RemoveEmptyEntries);
		foreach (string text in array)
		{
			list.Add(text.Trim());
		}
		return list;
	}

	public static float GetSolidHeight(Vector3 p)
	{
		//IL_0021: 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_004b: Unknown result type (might be due to invalid IL or missing references)
		int solidRayMask = ZoneSystem.instance.m_solidRayMask;
		float result = 0f;
		p.y += 1000f;
		RaycastHit val = default(RaycastHit);
		if (Physics.Raycast(p, Vector3.down, ref val, 2000f, solidRayMask) && !Object.op_Implicit((Object)(object)((RaycastHit)(ref val)).collider.attachedRigidbody))
		{
			result = ((RaycastHit)(ref val)).point.y;
		}
		return result;
	}

	public static Transform FindChild(Transform aParent, string aName)
	{
		//IL_000f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0015: Expected O, but got Unknown
		foreach (Transform item in aParent)
		{
			Transform val = item;
			if (((Object)val).name == aName)
			{
				return val;
			}
			Transform val2 = FindChild(val, aName);
			if ((Object)(object)val2 != (Object)null)
			{
				return val2;
			}
		}
		return null;
	}

	public static Transform FindParent(Transform go)
	{
		while ((Object)(object)go.parent != (Object)null)
		{
			go = go.parent;
		}
		return go;
	}

	public static GameObject GetPrefab(int prefabHash)
	{
		return GetPrefabByHash(prefabHash);
	}

	public static GameObject GetPrefabByHash(int prefabHash)
	{
		GameObject val = ObjectDB.instance.GetItemPrefab(prefabHash);
		Logging logger = Logging.GetLogger();
		if ((Object)(object)val != (Object)null)
		{
			logger.Debug("Found prefab in ObjectDB");
		}
		else
		{
			ZNetScene instance = ZNetScene.instance;
			val = ((instance != null) ? instance.GetPrefab(prefabHash) : null);
			if ((Object)(object)val != (Object)null)
			{
				logger.Debug("Found prefab in Scene");
			}
		}
		return val;
	}

	public static GameObject GetPrefab(string prefabName)
	{
		GameObject val = ObjectDB.instance.GetItemPrefab(prefabName);
		Logging logger = Logging.GetLogger();
		if ((Object)(object)val != (Object)null)
		{
			logger.Debug("Found " + prefabName + " in ObjectDB");
		}
		else
		{
			ZNetScene instance = ZNetScene.instance;
			val = ((instance != null) ? instance.GetPrefab(prefabName) : null);
			if ((Object)(object)val != (Object)null)
			{
				logger.Debug("Found " + prefabName + " in Scene");
			}
		}
		return val;
	}

	public static string SerializeFromDictionary<K, V>(string delimp, string delimc, IDictionary<K, V> dict)
	{
		if (dict == null)
		{
			return null;
		}
		IEnumerable<string> values = dict.Select(delegate(KeyValuePair<K, V> kvp)
		{
			KeyValuePair<K, V> keyValuePair = kvp;
			string? obj = keyValuePair.Key?.ToString();
			string text = delimc;
			keyValuePair = kvp;
			return obj + text + keyValuePair.Value;
		});
		return string.Join(delimp, values);
	}

	public static void DeserializeToDictionary<K, V>(string serializedString, string delimp, string delimc, ref IDictionary<K, V> dict)
	{
		if (dict == null)
		{
			return;
		}
		dict.Clear();
		string[] separator = new string[1] { delimp };
		string[] separator2 = new string[1] { delimc };
		string[] array = serializedString.Split(separator, StringSplitOptions.RemoveEmptyEntries);
		for (int i = 0; i < array.Length; i++)
		{
			string[] array2 = array[i].Split(separator2, StringSplitOptions.RemoveEmptyEntries);
			if (array2.Length == 2)
			{
				dict.Add(TypedValue<K>(array2[0]), TypedValue<V>(array2[1]));
			}
		}
	}

	public static FileSystemWatcher CreateFileWatcher(string fullPath, FileSystemEventHandler handler)
	{
		string fileName = Path.GetFileName(fullPath);
		FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(fullPath.Substring(0, fullPath.Length - fileName.Length), fileName);
		fileSystemWatcher.NotifyFilter = NotifyFilters.Attributes | NotifyFilters.Size | NotifyFilters.LastWrite | NotifyFilters.CreationTime;
		fileSystemWatcher.Changed += handler;
		fileSystemWatcher.Created += handler;
		fileSystemWatcher.IncludeSubdirectories = false;
		fileSystemWatcher.SynchronizingObject = ThreadingHelper.SynchronizingObject;
		fileSystemWatcher.EnableRaisingEvents = true;
		return fileSystemWatcher;
	}

	public static T TypedValue<T>(object a)
	{
		return (T)Convert.ChangeType(a, typeof(T));
	}

	public static float TimeAdjustedRamp(float maxValue, float duration, float elapsedTime, float pctFromStartRise, float pctFromEndFall)
	{
		float num = elapsedTime / duration;
		if (num <= pctFromStartRise)
		{
			return maxValue * (num / pctFromStartRise);
		}
		if (num >= 1f - pctFromEndFall)
		{
			return maxValue * ((1f - num) / pctFromEndFall);
		}
		return maxValue;
	}

	public static bool CopyComponentToGameObject(Component original, ref GameObject destination)
	{
		//IL_0073: Unknown result type (might be due to invalid IL or missing references)
		//IL_0079: Expected O, but got Unknown
		Logging logger = Logging.GetLogger();
		Type type = ((object)original).GetType();
		logger.Debug($"Original Type is {type}");
		GameObject obj = destination;
		logger.Debug("Destination GameObject " + ((obj != null) ? ((Object)obj).name : null));
		Component val = destination.GetComponent(type);
		if ((Object)(object)val == (Object)null)
		{
			val = destination.AddComponent(type);
		}
		if ((Object)(object)val == (Object)null)
		{
			logger.Debug("Destination component is null");
			return false;
		}
		Component val2 = (Component)Activator.CreateInstance(type);
		if ((Object)(object)val2 == (Object)null)
		{
			logger.Debug("Destination component is null");
			return false;
		}
		if ((Object)(object)val2 == (Object)null)
		{
			logger.Debug("Boxed component is null");
			return false;
		}
		FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
		foreach (FieldInfo fieldInfo in fields)
		{
			fieldInfo.SetValue(val2, fieldInfo.GetValue(original));
		}
		val = val2;
		return true;
	}

	public static bool CopyObject(object original, object target)
	{
		Logging logger = Logging.GetLogger();
		Type type = original.GetType();
		Type type2 = target.GetType();
		if (type == null)
		{
			logger.Warning("Copy Object: Source object is null");
			Activator.CreateInstance(type);
			return false;
		}
		if (type2 == null)
		{
			logger.Warning("Copy Object: Destination object is null");
			return false;
		}
		if (type2 != type)
		{
			logger.Warning("Copy Object: Source and destination components are different types");
			return false;
		}
		FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
		foreach (FieldInfo fieldInfo in fields)
		{
			fieldInfo.SetValue(target, fieldInfo.GetValue(original));
		}
		return true;
	}
}
internal class Cfg
{
	public static DelegatedConfigEntry<Logging.LogLevels> debugLevel = null;

	public static DelegatedConfigEntry<string> tagTranslation = null;

	public static DelegatedConfigEntry<int> maxChars = null;

	public static ConfigEntry<KeyboardShortcut> useModifier = null;

	private static KeyboardShortcut useModifierDefault = new KeyboardShortcut((KeyCode)304, Array.Empty<KeyCode>());

	public static void BepInExConfig(BaseUnityPlugin _instance)
	{
		//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e0: Expected O, but got Unknown
		//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
		ServerConfiguration.Instance.Setup(_instance.Config, _instance);
		debugLevel = new DelegatedConfigEntry<Logging.LogLevels>(Logging.ChangeLogging);
		debugLevel.ConfigEntry = _instance.Config.Bind<Logging.LogLevels>("Utility", "LogLevel", Logging.LogLevels.Info, "Controls the level of information contained in the log");
		TagConnectedPortals.Log.LogLevel = debugLevel.Value;
		tagTranslation = new DelegatedConfigEntry<string>(TagConnectedPortals.ChangeTranslation);
		tagTranslation.ConfigEntry = _instance.Config.Bind<string>("Utility", "Tag Connected Translation", "Tag connected", "Sets the translation text for the 'Tag' interaction prompt and portal dialog when tagging connected portals. Max 30 characters.");
		maxChars = new DelegatedConfigEntry<int>(useServerDelegate: true);
		maxChars.ConfigEntry = _instance.Config.Bind<int>("General", "Portal Name Limit", 10, new ConfigDescription("", (AcceptableValueBase)(object)new AcceptableValueRange<int>(10, 100), Array.Empty<object>()));
		useModifier = _instance.Config.Bind<KeyboardShortcut>("General", "Use Key Modifier", useModifierDefault, "Key when pressed along with your 'Use' key will open the Tag Connected dialog.");
		ServerConfiguration.Instance.CreateConfigWatcher();
	}
}
[BepInPlugin("neobotics.valheim_mod.tagconnectedportals", "TagConnectedPortals", "0.1.2")]
[BepInProcess("valheim.exe")]
[BepInProcess("valheim_server.exe")]
public class TagConnectedPortals : BaseUnityPlugin
{
	[HarmonyPatch(typeof(TeleportWorld), "GetHoverText")]
	private static class TeleportWorld_GetHoverText_Patch
	{
		[HarmonyPostfix]
		private static void TeleportWorld_GetHoverText_Postfix(TeleportWorld __instance, ref string __result)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: 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)
			if (__instance.HaveTarget())
			{
				string obj = __result;
				Localization instance = Localization.instance;
				KeyboardShortcut value = Cfg.useModifier.Value;
				__result = obj + instance.Localize($"\n[<color=yellow><b>{((KeyboardShortcut)(ref value)).MainKey} + $KEY_Use</b></color>] {tagTranslated}");
			}
		}
	}

	[HarmonyPatch(typeof(TeleportWorld), "Interact")]
	private static class TeleportWorld_Interact_Patch
	{
		[HarmonyPrefix]
		private static bool TeleportWorld_Interact_Prefix(TeleportWorld __instance, Humanoid human, bool hold, bool alt, out bool __result)
		{
			//IL_0014: 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)
			//IL_001c: 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_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			Log.Debug("TeleportWorld_Interact_Patch_Prefix");
			KeyboardShortcut value = Cfg.useModifier.Value;
			bool key = Input.GetKey(((KeyboardShortcut)(ref value)).MainKey);
			__result = false;
			if (!key || hold)
			{
				return true;
			}
			if (!PrivateArea.CheckAccess(((Component)__instance).transform.position, 0f, true, false))
			{
				((Character)human).Message((MessageType)2, "$piece_noaccess", 0, (Sprite)null);
				__result = true;
				return false;
			}
			Log.Debug("Modifier pressed. Retagging target.");
			TextInput.instance.RequestText((TextReceiver)(object)__instance, tagTranslated, Cfg.maxChars.Value);
			retagTarget = __instance.m_nview.m_zdo.GetConnectionZDOID((ConnectionType)1);
			__result = true;
			return false;
		}
	}

	[HarmonyPatch(typeof(TeleportWorld), "SetText")]
	private static class TeleportWorld_SetText_Patch
	{
		[HarmonyPostfix]
		private static void TeleportWorld_SetText_Postfix(TeleportWorld __instance, string text)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			Log.Debug("TeleportWorld_SetText_Patch_Postfix");
			if (TagConnectedPortals.retagTarget != ZDOID.None)
			{
				ZDOID retagTarget = TagConnectedPortals.retagTarget;
				TagConnectedPortals.retagTarget = ZDOID.None;
				ZDO zDO = ZDOMan.instance.GetZDO(retagTarget);
				if (zDO != null && zDO.IsValid())
				{
					Log.Debug("Setting connected tag and updating connnection");
					zDO.Set(ZDOVars.s_tag, text);
					zDO.UpdateConnection((ConnectionType)1, ZDOID.None);
				}
				else
				{
					Log.Warning("Valid connected portal not found.");
				}
			}
		}
	}

	private static TagConnectedPortals _modInstance;

	private static string Mod = "TagConnectedPortals";

	private static string LcMod = Mod.ToLower();

	public static Logging Log;

	private static Harmony harmony = null;

	private const string TAG_DIALOG_KEY = "piece_portal_tag";

	private static string tagTranslated = string.Empty;

	private static ZDOID retagTarget = ZDOID.None;

	public static TagConnectedPortals GetInstance()
	{
		return _modInstance;
	}

	private void Awake()
	{
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_0020: Expected O, but got Unknown
		_modInstance = this;
		harmony = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID);
		harmony.PatchAll(Assembly.GetExecutingAssembly());
		ConfigureMod();
		Log.Info("Awake");
	}

	private void ConfigureMod()
	{
		Log = Logging.GetLogger(Logging.LogLevels.Info, Mod);
		Cfg.BepInExConfig((BaseUnityPlugin)(object)_modInstance);
		tagTranslated = Utils.truncate(Cfg.tagTranslation.Value, 30);
	}

	private void OnDestroy()
	{
		harmony.UnpatchSelf();
	}

	internal static void ChangeTranslation(object s, EventArgs e)
	{
		tagTranslated = Utils.truncate(Cfg.tagTranslation.Value, 30);
	}
}