Decompiled source of Erenshor Custom SimPlayer Names v1.1.0

BepInEx\plugins\CustomSimPlayerNames\Erenshor-CustomSimPlayerNames.dll

Decompiled 3 days ago
using System;
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.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("Erenshor-CustomSimPlayerNames")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Erenshor-CustomSimPlayerNames")]
[assembly: AssemblyCopyright("Copyright ©  2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("6c1f6b4f-ac83-4639-ab86-e03790207e0f")]
[assembly: AssemblyFileVersion("1.1.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.1.0.0")]
namespace Erenshor_CustomSimPlayerNames;

[BepInPlugin("Brad522.CustomSimPlayerNames", "Custom SimPlayer Names", "1.1.0")]
public class CustomSimPlayerNames : BaseUnityPlugin
{
	[HarmonyPatch(typeof(SimPlayerMngr))]
	[HarmonyPatch("CreateGenericSimPlayers")]
	public class SimPlayerMngr_CreateGenericSimPlayers_Patch
	{
		[HarmonyPrefix]
		public static void Prefix()
		{
			LoadNamesFromFile("NameDatabaseMale.txt");
			LoadNamesFromFile("NameDatabaseFemale.txt", female: true);
		}
	}

	public static CustomSimPlayerNames Instance;

	internal const string ModName = "CustomSimPlayerNames";

	internal const string ModVersion = "1.1.0";

	internal const string ModDescription = "Custom SimPlayer Names";

	internal const string Author = "Brad522";

	private const string ModGUID = "Brad522.CustomSimPlayerNames";

	private readonly Harmony harmony = new Harmony("Brad522.CustomSimPlayerNames");

	internal static ManualLogSource Log;

	internal static Random RandomGen;

	public static ConfigEntry<bool> RandomizeNames;

	private static readonly HashSet<string> randomizedFiles = new HashSet<string>();

	private static readonly HashSet<string> ReservedWindowsNames = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
	{
		"CON", "PRN", "AUX", "NUL", "COM1", "COM2", "COM3", "COM4", "COM5", "COM6",
		"COM7", "COM8", "COM9", "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7",
		"LPT8", "LPT9"
	};

	public void Awake()
	{
		Instance = this;
		RandomizeNames = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "RandomizeNames", false, "If true, SimPlayer names will be assigned randomly instead of in order.");
		Log = ((BaseUnityPlugin)this).Logger;
		RandomGen = new Random();
		harmony.PatchAll();
	}

	private static void LoadNamesFromFile(string fileName = "CustomSimPlayerNames.txt", bool female = false)
	{
		string directoryName = Path.GetDirectoryName(Path.GetFullPath(Assembly.GetExecutingAssembly().Location));
		string text = Path.Combine(directoryName, fileName);
		if (!File.Exists(text))
		{
			Log.LogError((object)("[CustomSimPlayerNames] Name file not found: " + text));
			return;
		}
		try
		{
			string[] array = File.ReadAllLines(text);
			List<string> list = new List<string>();
			string[] array2 = array;
			for (int i = 0; i < array2.Length; i++)
			{
				string text2 = array2[i].Trim();
				if (!string.IsNullOrEmpty(text2))
				{
					string text3 = text2.Normalize(NormalizationForm.FormC);
					if (!IsValidName(text3))
					{
						Log.LogWarning((object)("[CustomSimPlayerNames] Invalid name skipped: " + text2));
					}
					else if (list.Contains(text3))
					{
						Log.LogWarning((object)("[CustomSimPlayerNames] Duplicate name skipped: " + text3));
					}
					else
					{
						list.Add(text3);
					}
				}
			}
			ref List<string> reference = ref female ? ref GameData.SimMngr.NameDatabaseFemale : ref GameData.SimMngr.NameDatabaseMale;
			if (list.Count < 60 && reference != null)
			{
				int num = 0;
				foreach (string item in reference)
				{
					if (!list.Contains(item))
					{
						list.Add(item);
						num++;
						if (list.Count >= 60)
						{
							break;
						}
					}
				}
				Log.LogDebug((object)$"[CustomSimPlayerNames] Added {num} names from existing database to {fileName}");
			}
			if (RandomizeNames.Value)
			{
				string text4 = Path.Combine(directoryName, Path.GetFileNameWithoutExtension(fileName) + "_original.txt");
				if (!File.Exists(text4))
				{
					File.Copy(text, text4);
					Log.LogDebug((object)("[CustomSimPlayerNames] Created backup of original names file at " + text4));
				}
				else
				{
					Log.LogWarning((object)("[CustomSimPlayerNames] Backup file already exists: " + text4));
				}
				ShuffleNames(list);
				File.WriteAllLines(text, list);
				Log.LogDebug((object)("[CustomSimPlayerNames] Shuffled names and saved to " + text));
				MarkRandomizationCompleteIfNeeded(fileName);
			}
			Log.LogDebug((object)$"[CustomSimPlayerNames] Loaded {list.Count} names from {text}");
			reference = list;
		}
		catch (IOException ex)
		{
			Log.LogError((object)("[CustomSimPlayerNames] Error reading name file: " + ex.Message));
		}
	}

	private static bool IsValidName(string name)
	{
		if (string.IsNullOrWhiteSpace(name))
		{
			return false;
		}
		if (name.IndexOfAny(Path.GetInvalidFileNameChars()) >= 0)
		{
			return false;
		}
		if (name.EndsWith(" ") || name.EndsWith("."))
		{
			return false;
		}
		if (ReservedWindowsNames.Contains(name))
		{
			return false;
		}
		if (name.Length > 30)
		{
			return false;
		}
		if (name.Any((char c) => char.IsControl(c)))
		{
			return false;
		}
		return true;
	}

	private static void ShuffleNames(List<string> names)
	{
		int num = names.Count;
		while (num > 1)
		{
			num--;
			int num2 = RandomGen.Next(num + 1);
			int index = num;
			int index2 = num2;
			string value = names[num2];
			string value2 = names[num];
			names[index] = value;
			names[index2] = value2;
		}
		Log.LogDebug((object)"[CustomSimPlayerNames] Names shuffled.");
	}

	private static void MarkRandomizationCompleteIfNeeded(string justRandomized)
	{
		randomizedFiles.Add(justRandomized);
		if (randomizedFiles.Contains("NameDatabaseMale.txt") && randomizedFiles.Contains("NameDatabaseFemale.txt"))
		{
			Log.LogInfo((object)"[CustomSimPlayerNames] All name databases have been randomized.");
			RandomizeNames.Value = false;
			((BaseUnityPlugin)Instance).Config.Save();
			randomizedFiles.Clear();
		}
	}
}