Decompiled source of Emuheim v0.2.2

BepInEx/plugins/AutoFeed.dll

Decompiled 8 months ago
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using TMPro;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("AutoFeed")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("AutoFeed")]
[assembly: AssemblyCopyright("Copyright ©  2021")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("4a4941b7-3227-4d66-ae89-d9ffd36996c4")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyVersion("1.0.0.0")]
public class AedenthornUtils
{
	public static bool IgnoreKeyPresses(bool extra = false)
	{
		if (!extra)
		{
			int result;
			if (!((Object)(object)ZNetScene.instance == (Object)null) && !((Object)(object)Player.m_localPlayer == (Object)null) && !Minimap.IsOpen() && !Console.IsVisible() && !TextInput.IsVisible() && !ZNet.instance.InPasswordDialog())
			{
				Chat instance = Chat.instance;
				result = ((instance != null && instance.HasFocus()) ? 1 : 0);
			}
			else
			{
				result = 1;
			}
			return (byte)result != 0;
		}
		int result2;
		if (!((Object)(object)ZNetScene.instance == (Object)null) && !((Object)(object)Player.m_localPlayer == (Object)null) && !Minimap.IsOpen() && !Console.IsVisible() && !TextInput.IsVisible() && !ZNet.instance.InPasswordDialog())
		{
			Chat instance2 = Chat.instance;
			if ((instance2 == null || !instance2.HasFocus()) && !StoreGui.IsVisible() && !InventoryGui.IsVisible() && !Menu.IsVisible())
			{
				TextViewer instance3 = TextViewer.instance;
				result2 = ((instance3 != null && instance3.IsVisible()) ? 1 : 0);
				goto IL_00d2;
			}
		}
		result2 = 1;
		goto IL_00d2;
		IL_00d2:
		return (byte)result2 != 0;
	}

	public static bool CheckKeyDown(string value)
	{
		try
		{
			return Input.GetKeyDown(value.ToLower());
		}
		catch
		{
			return false;
		}
	}

	public static bool CheckKeyHeld(string value, bool req = true)
	{
		try
		{
			return Input.GetKey(value.ToLower());
		}
		catch
		{
			return !req;
		}
	}
}
namespace AutoFeed;

[BepInPlugin("aedenthorn.AutoFeed", "Auto Feed", "0.8.0")]
public class BepInExPlugin : BaseUnityPlugin
{
	[HarmonyPatch(typeof(MonsterAI), "UpdateConsumeItem")]
	private static class UpdateConsumeItem_Patch
	{
		private static void Postfix(MonsterAI __instance, ZNetView ___m_nview, Character ___m_character, Tameable ___m_tamable, List<ItemDrop> ___m_consumeItems, float dt, bool __result)
		{
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			if (!modEnabled.Value || !isOn.Value || __result || !Object.op_Implicit((Object)(object)___m_character) || !Object.op_Implicit((Object)(object)___m_nview) || !___m_nview.IsOwner() || (Object)(object)___m_tamable == (Object)null || !___m_tamable.IsHungry() || ___m_consumeItems == null || ___m_consumeItems.Count == 0)
			{
				return;
			}
			string prefabName = GetPrefabName(((Object)((Component)__instance).gameObject).name);
			if (animalDisallowTypes.Value.Split(new char[1] { ',' }).Contains(prefabName))
			{
				return;
			}
			List<Container> nearbyContainers = GetNearbyContainers(((Component)___m_character).gameObject.transform.position, containerRange.Value, __instance);
			using List<ItemDrop>.Enumerator enumerator = __instance.m_consumeItems.GetEnumerator();
			while (enumerator.MoveNext())
			{
				foreach (Container item2 in nearbyContainers)
				{
					if (Utils.DistanceXZ(((Component)item2).transform.position, ((Component)__instance).transform.position) < moveProximity.Value && Mathf.Abs(((Component)item2).transform.position.y - ((Component)__instance).transform.position.y) > moveProximity.Value)
					{
						continue;
					}
					ItemData item = item2.GetInventory().GetItem(enumerator.Current.m_itemData.m_shared.m_name, -1, false);
					if (item == null || feedDisallowTypes.Value.Split(new char[1] { ',' }).Contains(((Object)item.m_dropPrefab).name))
					{
						continue;
					}
					if ((double)(Time.time - lastFeed) < 0.1)
					{
						feedCount++;
						FeedAnimal(__instance, ___m_tamable, ___m_character, item2, item, feedCount * 33);
					}
					else
					{
						feedCount = 0;
						lastFeed = Time.time;
						FeedAnimal(__instance, ___m_tamable, ___m_character, item2, item, 0);
					}
					return;
				}
			}
		}
	}

	[HarmonyPatch(typeof(Terminal), "InputText")]
	private static class InputText_Patch
	{
		private static bool Prefix(Terminal __instance)
		{
			if (!modEnabled.Value)
			{
				return true;
			}
			string text = ((TMP_InputField)__instance.m_input).text;
			if (text.ToLower().Equals(typeof(BepInExPlugin).Namespace.ToLower() + " reset"))
			{
				((BaseUnityPlugin)context).Config.Reload();
				((BaseUnityPlugin)context).Config.Save();
				__instance.AddString(text);
				__instance.AddString(((BaseUnityPlugin)context).Info.Metadata.Name + " config reloaded");
				return false;
			}
			return true;
		}
	}

	public static ConfigEntry<bool> isDebug;

	public static ConfigEntry<float> containerRange;

	public static ConfigEntry<float> moveProximity;

	public static ConfigEntry<string> feedDisallowTypes;

	public static ConfigEntry<string> animalDisallowTypes;

	public static ConfigEntry<string> toggleKey;

	public static ConfigEntry<string> toggleString;

	public static ConfigEntry<bool> isOn;

	public static ConfigEntry<bool> requireMove;

	public static ConfigEntry<bool> requireOnlyFood;

	public static ConfigEntry<bool> modEnabled;

	public static ConfigEntry<int> nexusID;

	private static BepInExPlugin context;

	private static float lastFeed;

	private static int feedCount;

	public static void Dbgl(string str = "", bool pref = true)
	{
		if (isDebug.Value)
		{
			Debug.Log((object)((pref ? (typeof(BepInExPlugin).Namespace + " ") : "") + str));
		}
	}

	private void Awake()
	{
		context = this;
		containerRange = ((BaseUnityPlugin)this).Config.Bind<float>("Config", "ContainerRange", 10f, "Container range in metres.");
		feedDisallowTypes = ((BaseUnityPlugin)this).Config.Bind<string>("Config", "FeedDisallowTypes", "", "Types of item to disallow as feed, comma-separated.");
		animalDisallowTypes = ((BaseUnityPlugin)this).Config.Bind<string>("Config", "AnimalDisallowTypes", "", "Types of creature to disallow to feed, comma-separated.");
		requireMove = ((BaseUnityPlugin)this).Config.Bind<bool>("Config", "RequireMove", true, "Require animals to move to container to feed.");
		requireOnlyFood = ((BaseUnityPlugin)this).Config.Bind<bool>("Config", "RequireOnlyFood", false, "Don't allow feeding from containers that have items that the animal will not eat as well.");
		moveProximity = ((BaseUnityPlugin)this).Config.Bind<float>("Config", "MoveProximity", 2f, "How close to move towards the container if RequireMove is true.");
		toggleKey = ((BaseUnityPlugin)this).Config.Bind<string>("General", "ToggleKey", "", "Key to toggle behaviour. Leave blank to disable the toggle key. Use https://docs.unity3d.com/Manual/ConventionalGameInput.html");
		toggleString = ((BaseUnityPlugin)this).Config.Bind<string>("General", "ToggleString", "Auto Feed: {0}", "Text to show on toggle. {0} is replaced with true/false");
		modEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Enable this mod");
		isDebug = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "IsDebug", true, "Show debug logs");
		nexusID = ((BaseUnityPlugin)this).Config.Bind<int>("General", "NexusID", 985, "Nexus mod ID for updates");
		isOn = ((BaseUnityPlugin)this).Config.Bind<bool>("ZAuto", "IsOn", true, "Behaviour is currently on or not");
		if (modEnabled.Value)
		{
			Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), (string)null);
		}
	}

	private void Update()
	{
		if (AedenthornUtils.CheckKeyDown(toggleKey.Value) && !AedenthornUtils.IgnoreKeyPresses(extra: true))
		{
			isOn.Value = !isOn.Value;
			((BaseUnityPlugin)this).Config.Save();
			((Character)Player.m_localPlayer).Message((MessageType)2, string.Format(toggleString.Value, isOn.Value), 0, (Sprite)null);
		}
	}

	private static string GetPrefabName(string name)
	{
		char[] anyOf = new char[2] { '(', ' ' };
		int num = name.IndexOfAny(anyOf);
		if (num >= 0)
		{
			return name.Substring(0, num);
		}
		return name;
	}

	public static List<Container> GetNearbyContainers(Vector3 center, float range, MonsterAI monsterAI)
	{
		//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)
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			List<Container> list = new List<Container>();
			Collider[] array = Physics.OverlapSphere(center, Mathf.Max(range, 0f), LayerMask.GetMask(new string[1] { "piece" }));
			foreach (Collider val in array)
			{
				Transform parent = ((Component)val).transform.parent;
				object obj;
				if (parent == null)
				{
					obj = null;
				}
				else
				{
					Transform parent2 = parent.parent;
					if (parent2 == null)
					{
						obj = null;
					}
					else
					{
						GameObject gameObject = ((Component)parent2).gameObject;
						obj = ((gameObject != null) ? gameObject.GetComponent<Container>() : null);
					}
				}
				Container val2 = (Container)obj;
				if (val2 == null)
				{
					continue;
				}
				ZNetView component = ((Component)val2).GetComponent<ZNetView>();
				if (((component != null) ? new bool?(component.IsValid()) : null) != true || (!((Object)val2).name.StartsWith("piece_chest") && !((Object)val2).name.StartsWith("Container")) || val2.GetInventory() == null)
				{
					continue;
				}
				if (requireOnlyFood.Value)
				{
					foreach (ItemData item in val2.GetInventory().GetAllItems())
					{
						if (monsterAI.m_consumeItems.Exists((ItemDrop i) => i.m_itemData.m_shared.m_name == item.m_shared.m_name))
						{
						}
					}
				}
				list.Add(val2);
			}
			list.OrderBy((Container c) => Vector3.Distance(((Component)c).transform.position, center));
			return list;
		}
		catch
		{
			return new List<Container>();
		}
	}

	public static async void FeedAnimal(MonsterAI monsterAI, Tameable tamable, Character character, Container c, ItemData item, int delay)
	{
		await Task.Delay(delay);
		if ((Object)(object)tamable == (Object)null || !tamable.IsHungry())
		{
			return;
		}
		if (requireOnlyFood.Value)
		{
			foreach (ItemData temp in c.GetInventory().GetAllItems())
			{
				if (!monsterAI.m_consumeItems.Exists((ItemDrop i) => i.m_itemData.m_shared.m_name == temp.m_shared.m_name))
				{
					return;
				}
			}
		}
		if (requireMove.Value)
		{
			float ground = default(float);
			ZoneSystem.instance.GetGroundHeight(((Component)c).transform.position, ref ground);
			Vector3 groundTarget = new Vector3(((Component)c).transform.position.x, ground, ((Component)c).transform.position.z);
			Traverse traverseAI = Traverse.Create((object)monsterAI);
			traverseAI.Field("m_lastFindPathTime").SetValue((object)0);
			if (!traverseAI.Method("MoveTo", new object[4] { 0.05f, groundTarget, moveProximity.Value, false }).GetValue<bool>() || Mathf.Abs(((Component)c).transform.position.y - ((Component)monsterAI).transform.position.y) > moveProximity.Value)
			{
				return;
			}
			traverseAI.Method("LookAt", new object[1] { ((Component)c).transform.position }).GetValue();
			if (!traverseAI.Method("IsLookingAt", new object[2]
			{
				((Component)c).transform.position,
				90f
			}).GetValue<bool>())
			{
				return;
			}
			traverseAI.Field("m_aiStatus").SetValue((object)"Consume item");
		}
		Dbgl($"{((Object)((Component)monsterAI).gameObject).name} {((Component)monsterAI).transform.position} consuming {((Object)item.m_dropPrefab).name} at {((Component)c).transform.position}, distance {Utils.DistanceXZ(((Component)monsterAI).transform.position, ((Component)c).transform.position)}");
		ConsumeItem(item, monsterAI, character);
		c.GetInventory().RemoveItem(item.m_shared.m_name, 1, -1, true);
		typeof(Inventory).GetMethod("Changed", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(c.GetInventory(), new object[0]);
		typeof(Container).GetMethod("Save", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(c, new object[0]);
	}

	private static void ConsumeItem(ItemData item, MonsterAI monsterAI, Character character)
	{
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_002a: Unknown result type (might be due to invalid IL or missing references)
		monsterAI.m_onConsumedItem?.Invoke(null);
		((Humanoid)((character is Humanoid) ? character : null)).m_consumeItemEffects.Create(((Component)character).transform.position, Quaternion.identity, (Transform)null, 1f, -1);
		Traverse.Create((object)monsterAI).Field("m_animator").GetValue<ZSyncAnimation>()
			.SetTrigger("consume");
	}
}

BepInEx/plugins/BuildRestrictionTweaks.dll

Decompiled 8 months ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace BuildRestrictionTweaks;

[BepInPlugin("aedenthorn.BuildRestrictionTweaks", "Build Restriction Tweaks", "0.5.0")]
public class BepInExPlugin : BaseUnityPlugin
{
	private enum PlacementStatus
	{
		Valid,
		Invalid,
		BlockedbyPlayer,
		NoBuildZone,
		PrivateZone,
		MoreSpace,
		NoTeleportArea,
		ExtensionMissingStation,
		WrongBiome,
		NeedCultivated,
		NeedDirt,
		NotInDungeon
	}

	[HarmonyPatch(typeof(Location), "IsInsideNoBuildLocation")]
	private static class Location_IsInsideNoBuildLocation_Patch
	{
		private static void Postfix(ref bool __result)
		{
			if (modEnabled.Value && (ignoreBuildZone.Value || alwaysValid.Value))
			{
				__result = false;
			}
		}
	}

	[HarmonyPatch(typeof(CraftingStation), "HaveBuildStationInRange")]
	private static class CraftingStation_HaveBuildStationInRange_Patch
	{
		private static void Postfix(ref CraftingStation __result, string name)
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Expected O, but got Unknown
			if (modEnabled.Value && (ignoreMissingStation.Value || alwaysValid.Value) && !((Object)(object)__result != (Object)null))
			{
				if (Object.op_Implicit((Object)(object)craftingStationObject))
				{
					__result = craftingStationObject.GetComponent<CraftingStation>();
					return;
				}
				craftingStationObject = new GameObject();
				Object.DontDestroyOnLoad((Object)(object)craftingStationObject);
				__result = craftingStationObject.AddComponent<CraftingStation>();
			}
		}
	}

	[HarmonyPatch(typeof(Player), "UpdatePlacementGhost")]
	private static class Player_UpdatePlacementGhost_Patch
	{
		private static void Postfix(Player __instance, GameObject ___m_placementGhost)
		{
			if (modEnabled.Value && !((Object)(object)___m_placementGhost == (Object)null))
			{
				PlacementStatus placementStatus = (PlacementStatus)(int)AccessTools.Field(typeof(Player), "m_placementStatus").GetValue(__instance);
				if ((placementStatus != 0 && placementStatus != PlacementStatus.PrivateZone && alwaysValid.Value) || (placementStatus == PlacementStatus.Invalid && ignoreInvalid.Value) || (placementStatus == PlacementStatus.BlockedbyPlayer && ignoreBlockedbyPlayer.Value) || (placementStatus == PlacementStatus.NoBuildZone && ignoreBuildZone.Value) || (placementStatus == PlacementStatus.MoreSpace && ignoreSpaceRestrictions.Value) || (placementStatus == PlacementStatus.NoTeleportArea && ignoreTeleportAreaRestrictions.Value) || (placementStatus == PlacementStatus.ExtensionMissingStation && ignoreMissingStationExtension.Value) || (placementStatus == PlacementStatus.WrongBiome && ignoreBiomeRestrictions.Value) || (placementStatus == PlacementStatus.NeedCultivated && ignoreCultivationRestrictions.Value) || (placementStatus == PlacementStatus.NeedDirt && ignoreDirtRestrictions.Value) || (placementStatus == PlacementStatus.NotInDungeon && ignoreDungeonRestrictions.Value))
				{
					AccessTools.Field(typeof(Player), "m_placementStatus").SetValue(__instance, 0);
					AccessTools.Method(typeof(Player), "SetPlacementGhostValid", (Type[])null, (Type[])null).Invoke(__instance, new object[1] { true });
				}
			}
		}
	}

	private static readonly bool isDebug = true;

	public static ConfigEntry<string> modKey;

	public static ConfigEntry<bool> modEnabled;

	public static ConfigEntry<int> nexusID;

	public static ConfigEntry<bool> alwaysValid;

	public static ConfigEntry<bool> ignoreInvalid;

	public static ConfigEntry<bool> ignoreBlockedbyPlayer;

	public static ConfigEntry<bool> ignoreBuildZone;

	public static ConfigEntry<bool> ignoreSpaceRestrictions;

	public static ConfigEntry<bool> ignoreTeleportAreaRestrictions;

	public static ConfigEntry<bool> ignoreMissingStation;

	public static ConfigEntry<bool> ignoreMissingStationExtension;

	public static ConfigEntry<bool> ignoreBiomeRestrictions;

	public static ConfigEntry<bool> ignoreCultivationRestrictions;

	public static ConfigEntry<bool> ignoreDirtRestrictions;

	public static ConfigEntry<bool> ignoreDungeonRestrictions;

	private static BepInExPlugin context;

	public static GameObject craftingStationObject;

	public static void Dbgl(string str = "", bool pref = true)
	{
		if (isDebug)
		{
			Debug.Log((object)((pref ? (typeof(BepInExPlugin).Namespace + " ") : "") + str));
		}
	}

	private void Awake()
	{
		context = this;
		modEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Enable this mod");
		nexusID = ((BaseUnityPlugin)this).Config.Bind<int>("General", "NexusID", 1606, "Nexus mod ID for updates");
		alwaysValid = ((BaseUnityPlugin)this).Config.Bind<bool>("Options", "AlwaysValid", false, "Remove all build restrictions.");
		ignoreBlockedbyPlayer = ((BaseUnityPlugin)this).Config.Bind<bool>("Options", "ignoreBlockedbyPlayer", false, "Ignore player blocking build.");
		ignoreInvalid = ((BaseUnityPlugin)this).Config.Bind<bool>("Options", "IgnoreInvalid", false, "Prevent misc build restrictions.");
		ignoreBuildZone = ((BaseUnityPlugin)this).Config.Bind<bool>("Options", "ignoreBuildZone", false, "Ignore zone restrictions.");
		ignoreSpaceRestrictions = ((BaseUnityPlugin)this).Config.Bind<bool>("Options", "ignoreSpaceRestrictions", false, "Ignore space restrictions.");
		ignoreTeleportAreaRestrictions = ((BaseUnityPlugin)this).Config.Bind<bool>("Options", "ignoreTeleportAreaRestrictions", false, "Ignore teleport area restrictions.");
		ignoreMissingStationExtension = ((BaseUnityPlugin)this).Config.Bind<bool>("Options", "ignoreMissingStationExtension", false, "Ignore missing station extension.");
		ignoreMissingStation = ((BaseUnityPlugin)this).Config.Bind<bool>("Options", "ignoreMissingStation", false, "Ignore missing station.");
		ignoreBiomeRestrictions = ((BaseUnityPlugin)this).Config.Bind<bool>("Options", "ignoreBiomeRestrictions", false, "Ignore biome restrictions.");
		ignoreCultivationRestrictions = ((BaseUnityPlugin)this).Config.Bind<bool>("Options", "ignoreCultivationRestrictions", false, "Ignore need for cultivated ground.");
		ignoreDirtRestrictions = ((BaseUnityPlugin)this).Config.Bind<bool>("Options", "ignoreDirtRestrictions", false, "Ignore need for dirt.");
		ignoreDungeonRestrictions = ((BaseUnityPlugin)this).Config.Bind<bool>("Options", "ignoreDungeonRestrictions", false, "Ignore indoor restrictions.");
		nexusID.Value = 1606;
		if (modEnabled.Value)
		{
			Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), MetadataHelper.GetMetadata((object)this).GUID);
		}
	}
}

BepInEx/plugins/CharacterEdit.dll

Decompiled 8 months ago
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace CharacterEdit;

[BepInPlugin("aedenthorn.CharacterEdit", "Character Edit", "0.7.0")]
public class BepInExPlugin : BaseUnityPlugin
{
	[HarmonyPatch(typeof(FejdStartup), "Awake")]
	private static class FejdStartup_Awake_Patch
	{
		private static void Postfix(FejdStartup __instance)
		{
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Expected O, but got Unknown
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Expected O, but got Unknown
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			if (modEnabled.Value)
			{
				Transform val = FejdStartup.instance.m_selectCharacterPanel.transform.Find("BottomWindow");
				Transform val2 = Object.Instantiate<Transform>(val.Find("New"));
				((Object)val2).name = "Edit";
				((Component)val2).transform.SetParent(val);
				((Component)val2).GetComponent<RectTransform>().anchoredPosition = Vector2.op_Implicit(new Vector3(-100f, 50f, 0f));
				((Component)((Component)val2).transform.Find("Text")).GetComponent<Text>().text = buttonText.Value;
				((UnityEventBase)((Component)val2).GetComponent<Button>().onClick).RemoveAllListeners();
				((Component)val2).GetComponent<Button>().onClick = new ButtonClickedEvent();
				((UnityEvent)((Component)val2).GetComponent<Button>().onClick).AddListener(new UnityAction(StartCharacterEdit));
				((Component)val2).GetComponent<UIGamePad>().m_zinputKey = gamePadButton.Value;
				((TMP_Text)((Component)((Component)val2).transform.Find("gamepad_hint").Find("Text")).GetComponent<TextMeshProUGUI>()).text = gamePadButtonHint.Value;
				title = Object.Instantiate<Transform>(FejdStartup.instance.m_newCharacterPanel.transform.Find("Topic"));
				((Object)title).name = "EditTitle";
				title.SetParent(FejdStartup.instance.m_newCharacterPanel.transform);
				((Component)title).GetComponent<Text>().text = titleText.Value;
				((Component)title).GetComponent<RectTransform>().anchoredPosition = ((Component)FejdStartup.instance.m_newCharacterPanel.transform.Find("Topic")).GetComponent<RectTransform>().anchoredPosition;
				((Component)title).gameObject.SetActive(false);
			}
		}
	}

	[HarmonyPatch(typeof(FejdStartup), "OnNewCharacterDone")]
	private static class FejdStartup_OnNewCharacterDone_Patch
	{
		private static bool Prefix(FejdStartup __instance, ref List<PlayerProfile> ___m_profiles)
		{
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			Dbgl($"New character done, editing {editingCharacter}");
			if (!editingCharacter)
			{
				return true;
			}
			((Component)title).gameObject.SetActive(false);
			((Component)FejdStartup.instance.m_newCharacterPanel.transform.Find("Topic")).gameObject.SetActive(true);
			editingCharacter = false;
			string text = __instance.m_csNewCharacterName.text;
			string text2 = text.ToLower();
			PlayerProfile val = Traverse.Create((object)FejdStartup.instance).Field("m_profiles").GetValue<List<PlayerProfile>>()[Traverse.Create((object)FejdStartup.instance).Field("m_profileIndex").GetValue<int>()];
			Player component = Traverse.Create((object)FejdStartup.instance).Field("m_playerInstance").GetValue<GameObject>()
				.GetComponent<Player>();
			val.SavePlayerData(component);
			val.SetName(text);
			Traverse val2 = Traverse.Create((object)val).Field("m_filename");
			string value = val2.GetValue<string>();
			if (value != text2)
			{
				string path = Path.Combine(Utils.GetSaveDataPath(Game.instance.GetPlayerProfile().m_fileSource), "characters");
				if (File.Exists(Path.Combine(path, value + ".fch")))
				{
					File.Move(Path.Combine(path, value + ".fch"), Path.Combine(path, text2 + ".fch"));
				}
				if (File.Exists(Path.Combine(path, value + ".fch.old")))
				{
					File.Move(Path.Combine(path, value + ".fch.old"), Path.Combine(path, text2 + ".fch.old"));
				}
				if (File.Exists(Path.Combine(path, value + ".fch.new")))
				{
					File.Move(Path.Combine(path, value + ".fch.new"), Path.Combine(path, text2 + ".fch.new"));
				}
				val2.SetValue((object)text2);
			}
			val.Save();
			__instance.m_selectCharacterPanel.SetActive(true);
			__instance.m_newCharacterPanel.SetActive(false);
			___m_profiles = null;
			Traverse.Create((object)__instance).Method("SetSelectedProfile", new object[1] { text2 }).GetValue();
			return false;
		}
	}

	[HarmonyPatch(typeof(FejdStartup), "OnNewCharacterCancel")]
	private static class FejdStartup_OnNewCharacterCancel_Patch
	{
		private static void Postfix(FejdStartup __instance)
		{
			Dbgl($"New character cancel, editing {editingCharacter}");
			((Component)title).gameObject.SetActive(false);
			((Component)FejdStartup.instance.m_newCharacterPanel.transform.Find("Topic")).gameObject.SetActive(true);
			editingCharacter = false;
		}
	}

	[HarmonyPatch(typeof(PlayerCustomizaton), "OnEnable")]
	private static class PlayerCustomizaton_OnEnable_Patch
	{
		private static void Postfix(PlayerCustomizaton __instance)
		{
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			Dbgl("Player customization enabled");
			if (editingCharacter)
			{
				Dbgl("is editing");
				Player previewPlayer = ((Component)__instance).GetComponentInParent<FejdStartup>().GetPreviewPlayer();
				if (previewPlayer.GetPlayerModel() == 1)
				{
					__instance.m_maleToggle.isOn = false;
					__instance.m_femaleToggle.isOn = true;
				}
				VisEquipment value = Traverse.Create((object)previewPlayer).Field("m_visEquipment").GetValue<VisEquipment>();
				Vector3 value2 = Traverse.Create((object)value).Field("m_skinColor").GetValue<Vector3>();
				float value3 = Vector3.Distance(value2, Utils.ColorToVec3(__instance.m_skinColor0)) / Vector3.Distance(Utils.ColorToVec3(__instance.m_skinColor1), Utils.ColorToVec3(__instance.m_skinColor0)) * (__instance.m_skinHue.maxValue - __instance.m_skinHue.minValue) + __instance.m_skinHue.minValue;
				__instance.m_skinHue.value = value3;
			}
		}
	}

	[HarmonyPatch(typeof(Terminal), "InputText")]
	private static class InputText_Patch
	{
		private static bool Prefix(Terminal __instance)
		{
			if (!modEnabled.Value)
			{
				return true;
			}
			string text = ((TMP_InputField)__instance.m_input).text;
			if (text.ToLower().Equals(typeof(BepInExPlugin).Namespace.ToLower() + " reset"))
			{
				((BaseUnityPlugin)context).Config.Reload();
				((BaseUnityPlugin)context).Config.Save();
				__instance.AddString(text);
				__instance.AddString(((BaseUnityPlugin)context).Info.Metadata.Name + " config reloaded");
				return false;
			}
			return true;
		}
	}

	private static readonly bool isDebug = true;

	private static bool editingCharacter = false;

	private static BepInExPlugin context;

	private Harmony harmony;

	public static ConfigEntry<bool> modEnabled;

	public static ConfigEntry<string> titleText;

	public static ConfigEntry<string> buttonText;

	public static ConfigEntry<string> gamePadButton;

	public static ConfigEntry<string> gamePadButtonHint;

	public static ConfigEntry<int> nexusID;

	private static Transform title;

	public static void Dbgl(string str = "", bool pref = true)
	{
		if (isDebug)
		{
			Debug.Log((object)((pref ? (typeof(BepInExPlugin).Namespace + " ") : "") + str));
		}
	}

	private void Awake()
	{
		//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
		//IL_0109: Expected O, but got Unknown
		context = this;
		modEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Enable this mod");
		buttonText = ((BaseUnityPlugin)this).Config.Bind<string>("General", "ButtonText", "Edit", "Button text");
		titleText = ((BaseUnityPlugin)this).Config.Bind<string>("General", "TitleText", "Edit Character", "Title text");
		gamePadButton = ((BaseUnityPlugin)this).Config.Bind<string>("General", "GamePadButton", "JoyLTrigger", "Gamepad button used to press button. Possible values: JoyHide, JoyGPower, JoyRun, JoyCrouch, JoyMap, JoyMenu, JoyBlock, JoyAttack, JoySecondAttack, JoyAltPlace, JoyRotate, JoyPlace, JoyRemove, JoyTabLeft, JoyTabRight, JoyLStickLeft, JoyLStickRight, JoyLStickUp, JoyLStickDown, JoyDPadLeft, JoyDPadRight, JoyDPadUp, JoyDPadDown, JoyLTrigger, JoyRTrigger, JoyLStick, JoyRStick");
		gamePadButtonHint = ((BaseUnityPlugin)this).Config.Bind<string>("General", "GamePadButtonHint", "LT", "Hint to show for gamepad button");
		nexusID = ((BaseUnityPlugin)this).Config.Bind<int>("General", "NexusID", 650, "Nexus mod ID for updates");
		if (modEnabled.Value)
		{
			harmony = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID);
			harmony.PatchAll();
		}
	}

	private static void StartCharacterEdit()
	{
		Dbgl("Start editing character");
		editingCharacter = true;
		((Component)title).gameObject.SetActive(true);
		((Component)FejdStartup.instance.m_newCharacterPanel.transform.Find("Topic")).gameObject.SetActive(false);
		PlayerProfile val = Traverse.Create((object)FejdStartup.instance).Field("m_profiles").GetValue<List<PlayerProfile>>()[Traverse.Create((object)FejdStartup.instance).Field("m_profileIndex").GetValue<int>()];
		FejdStartup.instance.m_newCharacterPanel.SetActive(true);
		FejdStartup.instance.m_selectCharacterPanel.SetActive(false);
		FejdStartup.instance.m_csNewCharacterName.text = val.GetName();
		FejdStartup.instance.m_newCharacterError.SetActive(false);
		Traverse.Create((object)FejdStartup.instance).Method("SetupCharacterPreview", new object[1] { val }).GetValue();
		Gogan.LogEvent("Screen", "Enter", "CreateCharacter", 0L);
	}
}

BepInEx/plugins/QuickConnect.dll

Decompiled 8 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("QuickConnect")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("QuickConnect")]
[assembly: AssemblyCopyright("Copyright ©  2021")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("1c6b0fc4-ad65-4bb6-a9db-7ca3b47eadf6")]
[assembly: AssemblyFileVersion("1.5.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.5.0.0")]
namespace QuickConnect;

[HarmonyPatch(typeof(ZNet), "RPC_ClientHandshake")]
internal class PatchPasswordPrompt
{
	private static bool Prefix(ZNet __instance, ZRpc rpc, bool needPassword, string serverPasswordSalt)
	{
		string text = QuickConnectUI.instance.CurrentPass();
		if (text != null)
		{
			if (needPassword)
			{
				Mod.Log.LogInfo((object)"Authenticating with saved password...");
				((Component)__instance.m_connectingDialog).gameObject.SetActive(false);
				FieldInfo field = typeof(ZNet).GetField("m_serverPasswordSalt", BindingFlags.Static | BindingFlags.NonPublic);
				field.SetValue(null, serverPasswordSalt);
				MethodInfo method = typeof(ZNet).GetMethod("SendPeerInfo", BindingFlags.Instance | BindingFlags.NonPublic);
				method.Invoke(__instance, new object[2] { rpc, text });
				return false;
			}
			Mod.Log.LogInfo((object)"Server didn't want password?");
		}
		return true;
	}
}
[HarmonyPatch(typeof(ZSteamMatchmaking), "OnJoinServerFailed")]
internal class PatchConnectFailed
{
	private static void Postfix()
	{
		if (Object.op_Implicit((Object)(object)QuickConnectUI.instance))
		{
			QuickConnectUI.instance.JoinServerFailed();
		}
	}
}
[HarmonyPatch(typeof(FejdStartup), "OnSelelectCharacterBack")]
internal class PatchCharacterBack
{
	private static void Postfix()
	{
		if (Object.op_Implicit((Object)(object)QuickConnectUI.instance))
		{
			QuickConnectUI.instance.AbortConnect();
		}
	}
}
[HarmonyPatch(typeof(FejdStartup), "SetupGui")]
internal class PatchUiInit
{
	private static void Postfix()
	{
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Expected O, but got Unknown
		if (!Object.op_Implicit((Object)(object)QuickConnectUI.instance))
		{
			Servers.Init();
			GameObject val = new GameObject("QuickConnect");
			QuickConnectUI.instance = val.AddComponent<QuickConnectUI>();
		}
	}
}
[BepInPlugin("net.bdew.valheim.QuickConnect", "QuickConnect", "1.6.0")]
internal class Mod : BaseUnityPlugin
{
	public static ManualLogSource Log;

	public static ConfigEntry<float> windowPosX;

	public static ConfigEntry<float> windowPosY;

	public static ConfigEntry<int> buttonFontSize;

	public static ConfigEntry<int> labelFontSize;

	public static ConfigEntry<int> windowWidth;

	public static ConfigEntry<int> windowHeight;

	private void Awake()
	{
		//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d0: Expected O, but got Unknown
		Log = Logger.CreateLogSource("QuickConnect");
		windowPosX = ((BaseUnityPlugin)this).Config.Bind<float>("UI", "WindowPosX", 20f, (ConfigDescription)null);
		windowPosY = ((BaseUnityPlugin)this).Config.Bind<float>("UI", "WindowPosY", 20f, (ConfigDescription)null);
		buttonFontSize = ((BaseUnityPlugin)this).Config.Bind<int>("UI", "ButtonFontSize", 0, (ConfigDescription)null);
		labelFontSize = ((BaseUnityPlugin)this).Config.Bind<int>("UI", "LabelFontSize", 0, (ConfigDescription)null);
		windowWidth = ((BaseUnityPlugin)this).Config.Bind<int>("UI", "WindowWidth", 250, (ConfigDescription)null);
		windowHeight = ((BaseUnityPlugin)this).Config.Bind<int>("UI", "WindowHeight", 50, (ConfigDescription)null);
		Harmony val = new Harmony("net.bdew.valheim.QuickConnect");
		val.PatchAll();
	}
}
internal class QuickConnectUI : MonoBehaviour
{
	public static QuickConnectUI instance;

	private Rect windowRect;

	private Rect lastRect;

	private Rect errorWinRect;

	private Rect dragRect = new Rect(0f, 0f, 10000f, 20f);

	private int buttonFontSize;

	private int labelFontSize;

	private GUIStyle buttonStyle;

	private GUIStyle labelStyle;

	private Task<IPHostEntry> resolveTask;

	private Servers.Entry connecting;

	private string errorMsg;

	private void Update()
	{
		if (resolveTask == null)
		{
			return;
		}
		if (resolveTask.IsFaulted)
		{
			Mod.Log.LogError((object)$"Error resolving IP: {resolveTask.Exception}");
			if (resolveTask.Exception != null)
			{
				ShowError(resolveTask.Exception.InnerException.Message);
			}
			else
			{
				ShowError(resolveTask.Exception.Message);
			}
			resolveTask = null;
			connecting = null;
		}
		else if (resolveTask.IsCanceled)
		{
			resolveTask = null;
			connecting = null;
		}
		else
		{
			if (!resolveTask.IsCompleted)
			{
				return;
			}
			IPAddress[] addressList = resolveTask.Result.AddressList;
			foreach (IPAddress iPAddress in addressList)
			{
				if (iPAddress.AddressFamily == AddressFamily.InterNetwork)
				{
					Mod.Log.LogInfo((object)$"Resolved: {iPAddress}");
					resolveTask = null;
					ZSteamMatchmaking.instance.QueueServerJoin($"{iPAddress}:{connecting.port}");
					return;
				}
			}
			resolveTask = null;
			connecting = null;
			ShowError("Server DNS resolved to no valid addresses");
		}
	}

	private void Awake()
	{
		//IL_007d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0082: Unknown result type (might be due to invalid IL or missing references)
		((Rect)(ref windowRect)).x = Mod.windowPosX.Value;
		((Rect)(ref windowRect)).y = Mod.windowPosY.Value;
		buttonFontSize = Mod.buttonFontSize.Value;
		labelFontSize = Mod.labelFontSize.Value;
		((Rect)(ref windowRect)).width = Mod.windowWidth.Value;
		((Rect)(ref windowRect)).height = Mod.windowHeight.Value;
		lastRect = windowRect;
	}

	private void OnGUI()
	{
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Expected O, but got Unknown
		//IL_0041: Unknown result type (might be due to invalid IL or missing references)
		//IL_004b: Expected O, but got Unknown
		//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c6: Expected O, but got Unknown
		//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
		//IL_0073: Unknown result type (might be due to invalid IL or missing references)
		//IL_007f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0093: Expected O, but got Unknown
		//IL_008e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0093: Unknown result type (might be due to invalid IL or missing references)
		//IL_0112: Unknown result type (might be due to invalid IL or missing references)
		//IL_0117: Unknown result type (might be due to invalid IL or missing references)
		if (buttonStyle == null)
		{
			buttonStyle = new GUIStyle(GUI.skin.button);
			buttonStyle.fontSize = buttonFontSize;
			labelStyle = new GUIStyle(GUI.skin.label);
			labelStyle.fontSize = labelFontSize;
		}
		if (errorMsg != null)
		{
			errorWinRect = GUILayout.Window(1586464, errorWinRect, new WindowFunction(DrawErrorWindow), "Error", Array.Empty<GUILayoutOption>());
			return;
		}
		windowRect = GUILayout.Window(1586463, windowRect, new WindowFunction(DrawConnectWindow), "Quick Connect", Array.Empty<GUILayoutOption>());
		if (!((Rect)(ref lastRect)).Equals(windowRect))
		{
			Mod.windowPosX.Value = ((Rect)(ref windowRect)).x;
			Mod.windowPosY.Value = ((Rect)(ref windowRect)).y;
			lastRect = windowRect;
		}
	}

	private void DrawConnectWindow(int windowID)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		GUI.DragWindow(dragRect);
		if (connecting != null)
		{
			GUILayout.Label("Connecting to " + connecting.name, labelStyle, Array.Empty<GUILayoutOption>());
			if (GUILayout.Button("Cancel", buttonStyle, Array.Empty<GUILayoutOption>()))
			{
				AbortConnect();
			}
			return;
		}
		if (Servers.entries.Count > 0)
		{
			GUILayout.Label("Choose A Server:", labelStyle, Array.Empty<GUILayoutOption>());
			{
				foreach (Servers.Entry entry in Servers.entries)
				{
					if (GUILayout.Button(entry.name, buttonStyle, Array.Empty<GUILayoutOption>()))
					{
						DoConnect(entry);
					}
				}
				return;
			}
		}
		GUILayout.Label("No servers defined", labelStyle, Array.Empty<GUILayoutOption>());
		GUILayout.Label("Add quick_connect_servers.cfg", labelStyle, Array.Empty<GUILayoutOption>());
	}

	private void DrawErrorWindow(int windowID)
	{
		GUILayout.Label(errorMsg, labelStyle, Array.Empty<GUILayoutOption>());
		if (GUILayout.Button("Close", buttonStyle, Array.Empty<GUILayoutOption>()))
		{
			errorMsg = null;
		}
	}

	private void DoConnect(Servers.Entry server)
	{
		connecting = server;
		try
		{
			IPAddress.Parse(server.ip);
			ZSteamMatchmaking.instance.QueueServerJoin($"{server.ip}:{server.port}");
		}
		catch (FormatException)
		{
			Mod.Log.LogInfo((object)("Resolving: " + server.ip));
			resolveTask = Dns.GetHostEntryAsync(server.ip);
		}
	}

	public string CurrentPass()
	{
		if (connecting != null)
		{
			return connecting.pass;
		}
		return null;
	}

	public void JoinServerFailed()
	{
		ShowError("Server connection failed");
		connecting = null;
	}

	public void ShowError(string msg)
	{
		//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)
		errorMsg = msg;
		errorWinRect = new Rect((float)(Screen.width / 2 - 125), (float)(Screen.height / 2), 250f, 30f);
	}

	public void AbortConnect()
	{
		connecting = null;
		resolveTask = null;
	}
}
internal class Servers
{
	public class Entry
	{
		public string name;

		public string ip;

		public int port;

		public string pass;

		public override string ToString()
		{
			return string.Format("Server(name={0},ip={1},port={2}}", name, ip, port);
		}
	}

	public static string ConfigPath;

	public static List<Entry> entries;

	public static void Init()
	{
		entries.Clear();
		try
		{
			if (!File.Exists(ConfigPath))
			{
				return;
			}
			using StreamReader streamReader = new StreamReader(ConfigPath);
			string text;
			while ((text = streamReader.ReadLine()) != null)
			{
				text = text.Trim();
				if (text.Length == 0 || text.StartsWith("#"))
				{
					continue;
				}
				string[] array = text.Split(new char[1] { ':' });
				if (array.Length >= 3)
				{
					string name = array[0];
					string ip = array[1];
					int port = int.Parse(array[2]);
					string pass = null;
					if (array.Length >= 4)
					{
						pass = array[3];
					}
					entries.Add(new Entry
					{
						name = name,
						ip = ip,
						port = port,
						pass = pass
					});
				}
				else
				{
					Mod.Log.LogWarning((object)("Invalid config line: " + text));
				}
			}
			Mod.Log.LogInfo((object)$"Loaded {entries.Count} server entries");
		}
		catch (Exception arg)
		{
			Mod.Log.LogError((object)$"Error loading config {arg}");
		}
	}

	static Servers()
	{
		string? directoryName = Path.GetDirectoryName(Paths.BepInExConfigPath);
		char directorySeparatorChar = Path.DirectorySeparatorChar;
		ConfigPath = directoryName + directorySeparatorChar + "quick_connect_servers.cfg";
		entries = new List<Entry>();
	}
}