Decompiled source of LethalPhonesCustomNumbers v0.0.1

LethalPhonesCustomNumbers.dll

Decompiled 7 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using Scoops;
using Scoops.customization;
using Scoops.service;
using TMPro;
using Unity.Netcode;
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(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("LethalPhonesCustomNumbers")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("LethalPhonesCustomNumbers")]
[assembly: AssemblyTitle("LethalPhonesCustomNumbers")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace LethalPhonesCustomNumbers;

[HarmonyPatch(typeof(PhoneNetworkHandler))]
public class ClientPhonePatch
{
	[HarmonyPatch("CreateNewPhone")]
	[HarmonyPrefix]
	public static void CreateNewPhonePrefix(ref string skinId)
	{
		string text = ConfigManager.ClientRequestedNumber.Value;
		if (!string.IsNullOrEmpty(text) && text.Length > 0)
		{
			if (text.Length < 4)
			{
				text = text.PadLeft(4, '0');
			}
			skinId = skinId + "|" + text;
			Plugin.Logger.LogInfo((object)("Client appended requested number to skinId: " + skinId));
		}
	}
}
public static class ConfigManager
{
	public static ConfigEntry<string> SteamIdMappingConfig;

	public static Dictionary<ulong, short> SteamIdToNumber = new Dictionary<ulong, short>();

	public static ConfigFile Config { get; private set; }

	public static ConfigEntry<string> ClientRequestedNumber { get; private set; }

	public static void Init(ConfigFile config)
	{
		Config = config;
		ClientRequestedNumber = Config.Bind<string>("Client", "RequestedNumber", "", "Your requested 4-digit phone number. Leave empty for a random number.");
		SteamIdMappingConfig = config.Bind<string>("General", "SteamIdMapping", "76561198000000000:1234,76561198000000001:5678", "Comma-separated list of SteamID:Number mappings.");
		ParseMapping();
	}

	public static void ParseMapping()
	{
		SteamIdToNumber.Clear();
		string value = SteamIdMappingConfig.Value;
		if (string.IsNullOrWhiteSpace(value))
		{
			return;
		}
		string[] array = value.Split(',');
		string[] array2 = array;
		foreach (string text in array2)
		{
			string[] array3 = text.Split(':');
			if (array3.Length == 2 && ulong.TryParse(array3[0].Trim(), out var result) && short.TryParse(array3[1].Trim(), out var result2))
			{
				SteamIdToNumber[result] = result2;
				Plugin.Logger.LogInfo((object)$"Loaded CustomNumbers map: {result} -> {result2}");
			}
		}
	}
}
[HarmonyPatch(typeof(CustomizationManager))]
public class CustomizationUIPatch
{
	private static TMP_InputField numberInputField;

	private static readonly string[] TAB_NAMES = new string[3] { "SkinButton", "CharmButton", "RingtoneButton" };

	[HarmonyPatch("SpawnCustomizationGUI")]
	[HarmonyPostfix]
	public static void SpawnCustomizationGUIPostfix()
	{
		object? obj = AccessTools.Field(typeof(CustomizationManager), "customizationPanel")?.GetValue(null);
		Transform val = (Transform)((obj is Transform) ? obj : null);
		if ((Object)(object)val == (Object)null)
		{
			Plugin.Logger.LogError((object)"CustomNumbers: customizationPanel not found!");
			return;
		}
		Transform val2 = val.Find("Panel");
		if ((Object)(object)val2 == (Object)null)
		{
			Plugin.Logger.LogError((object)"CustomNumbers: 'Panel' not found!");
			return;
		}
		Plugin.Logger.LogInfo((object)"=== CustomNumbers: Panel Hierarchy Dump ===");
		DumpHierarchy(val2, "  ");
		Plugin.Logger.LogInfo((object)"=== CustomNumbers: End Dump ===");
		List<Button> list = FindTabButtons(val2);
		if (list.Count > 0)
		{
			Plugin.Logger.LogInfo((object)$"CustomNumbers: Found {list.Count} tab button(s)");
			CreatePhoneNumberTab(val2, list);
		}
		else
		{
			Plugin.Logger.LogError((object)"CustomNumbers: No tab buttons found — cannot create UI!");
		}
	}

	private static List<Button> FindTabButtons(Transform panel)
	{
		return (from b in ((Component)panel).GetComponentsInChildren<Button>(true)
			where TAB_NAMES.Contains(((Object)((Component)b).gameObject).name)
			orderby ((Component)b).GetComponent<RectTransform>().anchoredPosition.y descending
			select b).ToList();
	}

	private static void CreatePhoneNumberTab(Transform panel, List<Button> tabButtons)
	{
		//IL_00be: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
		//IL_0105: 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_014b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0155: Expected O, but got Unknown
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_005a: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0201: Unknown result type (might be due to invalid IL or missing references)
		//IL_027d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0287: Expected O, but got Unknown
		//IL_02bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c3: Expected O, but got Unknown
		//IL_02c8: Expected O, but got Unknown
		//IL_02f7: Unknown result type (might be due to invalid IL or missing references)
		Button val = tabButtons.First();
		Button val2 = tabButtons.Last();
		RectTransform component = ((Component)val).GetComponent<RectTransform>();
		float num = 31f;
		if (tabButtons.Count >= 2)
		{
			float y = ((Component)tabButtons[0]).GetComponent<RectTransform>().anchoredPosition.y;
			float y2 = ((Component)tabButtons[1]).GetComponent<RectTransform>().anchoredPosition.y;
			num = Mathf.Abs(y - y2);
			Plugin.Logger.LogInfo((object)$"CustomNumbers: Tab spacing = {num}");
		}
		GameObject val3 = Object.Instantiate<GameObject>(((Component)val2).gameObject, ((Component)val2).transform.parent);
		((Object)val3).name = "PhoneNumberTab";
		RectTransform component2 = val3.GetComponent<RectTransform>();
		float num2 = component.anchoredPosition.x - component.sizeDelta.x * component.pivot.x;
		float num3 = num2 + component2.sizeDelta.x * component2.pivot.x;
		component2.anchoredPosition = new Vector2(num3, component.anchoredPosition.y + num);
		Plugin.Logger.LogInfo((object)$"CustomNumbers: Skin left edge={num2}, our X={num3}");
		Button component3 = val3.GetComponent<Button>();
		component3.onClick = new ButtonClickedEvent();
		((Selectable)component3).interactable = true;
		TextMeshProUGUI componentInChildren = val3.GetComponentInChildren<TextMeshProUGUI>();
		if ((Object)(object)componentInChildren == (Object)null)
		{
			Plugin.Logger.LogError((object)"CustomNumbers: Cloned tab has no TextMeshProUGUI!");
			return;
		}
		((TMP_Text)componentInChildren).text = "[ Phone # ]";
		TMP_FontAsset font = ((TMP_Text)componentInChildren).font;
		float fontSize = ((TMP_Text)componentInChildren).fontSize;
		Color color = ((Graphic)componentInChildren).color;
		Material fontSharedMaterial = ((TMP_Text)componentInChildren).fontSharedMaterial;
		FontStyles fontStyle = ((TMP_Text)componentInChildren).fontStyle;
		Plugin.Logger.LogInfo((object)$"CustomNumbers: Tab style — font={((font != null) ? ((Object)font).name : null)} size={fontSize} color={color}");
		GameObject phoneDisplay = CreatePhoneNumberDisplay(panel, font, fontSize, color, fontSharedMaterial, fontStyle);
		phoneDisplay.SetActive(false);
		Transform phoneModel = panel.Find("PhoneDisplayModel");
		Transform charmDisplay = panel.Find("CharmDisplay");
		Transform audioDisplay = panel.Find("AudioDisplay");
		Transform nextBtn = panel.Find("NextButton");
		Transform prevBtn = panel.Find("PrevButton");
		((UnityEvent)component3.onClick).AddListener((UnityAction)delegate
		{
			if ((Object)(object)phoneModel != (Object)null)
			{
				((Component)phoneModel).gameObject.SetActive(false);
			}
			if ((Object)(object)charmDisplay != (Object)null)
			{
				((Component)charmDisplay).gameObject.SetActive(false);
			}
			if ((Object)(object)audioDisplay != (Object)null)
			{
				((Component)audioDisplay).gameObject.SetActive(false);
			}
			if ((Object)(object)nextBtn != (Object)null)
			{
				((Component)nextBtn).gameObject.SetActive(false);
			}
			if ((Object)(object)prevBtn != (Object)null)
			{
				((Component)prevBtn).gameObject.SetActive(false);
			}
			phoneDisplay.SetActive(true);
		});
		UnityAction val4 = default(UnityAction);
		foreach (Button tabButton in tabButtons)
		{
			ButtonClickedEvent onClick = ((Component)tabButton).GetComponent<Button>().onClick;
			UnityAction obj = val4;
			if (obj == null)
			{
				UnityAction val5 = delegate
				{
					phoneDisplay.SetActive(false);
					if ((Object)(object)nextBtn != (Object)null)
					{
						((Component)nextBtn).gameObject.SetActive(true);
					}
					if ((Object)(object)prevBtn != (Object)null)
					{
						((Component)prevBtn).gameObject.SetActive(true);
					}
				};
				UnityAction val6 = val5;
				val4 = val5;
				obj = val6;
			}
			((UnityEvent)onClick).AddListener(obj);
		}
		Plugin.Logger.LogInfo((object)$"CustomNumbers: [ Phone # ] tab created at y={component2.anchoredPosition.y}");
	}

	private static GameObject CreatePhoneNumberDisplay(Transform panel, TMP_FontAsset font, float fontSize, Color color, Material fontMat, FontStyles fontStyle)
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Expected O, but got Unknown
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_005a: Unknown result type (might be due to invalid IL or missing references)
		//IL_006a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0070: Expected O, but got Unknown
		//IL_0095: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
		//IL_010b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0152: Unknown result type (might be due to invalid IL or missing references)
		//IL_0159: Expected O, but got Unknown
		//IL_0182: Unknown result type (might be due to invalid IL or missing references)
		//IL_0199: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01de: Expected O, but got Unknown
		//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
		//IL_020b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0218: Unknown result type (might be due to invalid IL or missing references)
		//IL_0225: Unknown result type (might be due to invalid IL or missing references)
		//IL_023d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0244: Expected O, but got Unknown
		//IL_0264: Unknown result type (might be due to invalid IL or missing references)
		//IL_0271: Unknown result type (might be due to invalid IL or missing references)
		//IL_027e: Unknown result type (might be due to invalid IL or missing references)
		//IL_028b: Unknown result type (might be due to invalid IL or missing references)
		//IL_02bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_032a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0331: Expected O, but got Unknown
		//IL_0351: Unknown result type (might be due to invalid IL or missing references)
		//IL_035e: Unknown result type (might be due to invalid IL or missing references)
		//IL_036b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0378: Unknown result type (might be due to invalid IL or missing references)
		//IL_03ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_03dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_0458: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = new GameObject("PhoneNumberDisplay");
		val.transform.SetParent(panel, false);
		RectTransform val2 = val.AddComponent<RectTransform>();
		val2.anchorMin = Vector2.zero;
		val2.anchorMax = Vector2.one;
		val2.offsetMin = new Vector2(150f, 60f);
		val2.offsetMax = new Vector2(-150f, -60f);
		GameObject val3 = new GameObject("Title");
		val3.transform.SetParent(val.transform, false);
		RectTransform val4 = val3.AddComponent<RectTransform>();
		val4.anchorMin = new Vector2(0.5f, 0.5f);
		val4.anchorMax = new Vector2(0.5f, 0.5f);
		val4.anchoredPosition = new Vector2(0f, 50f);
		val4.sizeDelta = new Vector2(400f, 50f);
		val3.AddComponent<CanvasRenderer>();
		TextMeshProUGUI val5 = val3.AddComponent<TextMeshProUGUI>();
		((TMP_Text)val5).font = font;
		((TMP_Text)val5).fontSize = fontSize * 1.5f;
		((Graphic)val5).color = color;
		if ((Object)(object)fontMat != (Object)null)
		{
			((TMP_Text)val5).fontSharedMaterial = fontMat;
		}
		((TMP_Text)val5).alignment = (TextAlignmentOptions)514;
		((TMP_Text)val5).enableWordWrapping = false;
		((TMP_Text)val5).text = "Phone Number";
		GameObject val6 = new GameObject("PhoneNumberInput");
		val6.transform.SetParent(val.transform, false);
		RectTransform val7 = val6.AddComponent<RectTransform>();
		val7.anchorMin = new Vector2(0.5f, 0.5f);
		val7.anchorMax = new Vector2(0.5f, 0.5f);
		val7.anchoredPosition = new Vector2(0f, -20f);
		val7.sizeDelta = new Vector2(400f, 70f);
		GameObject val8 = new GameObject("Text Area");
		val8.transform.SetParent(val6.transform, false);
		RectTransform val9 = val8.AddComponent<RectTransform>();
		val9.anchorMin = Vector2.zero;
		val9.anchorMax = Vector2.one;
		val9.offsetMin = Vector2.zero;
		val9.offsetMax = Vector2.zero;
		val8.AddComponent<RectMask2D>();
		GameObject val10 = new GameObject("Placeholder");
		val10.transform.SetParent(val8.transform, false);
		RectTransform val11 = val10.AddComponent<RectTransform>();
		val11.anchorMin = Vector2.zero;
		val11.anchorMax = Vector2.one;
		val11.offsetMin = Vector2.zero;
		val11.offsetMax = Vector2.zero;
		val10.AddComponent<CanvasRenderer>();
		TextMeshProUGUI val12 = val10.AddComponent<TextMeshProUGUI>();
		((TMP_Text)val12).font = font;
		((TMP_Text)val12).fontSize = fontSize * 2.5f;
		Color color2 = color;
		color2.a = 0.4f;
		((Graphic)val12).color = color2;
		if ((Object)(object)fontMat != (Object)null)
		{
			((TMP_Text)val12).fontSharedMaterial = fontMat;
		}
		((TMP_Text)val12).alignment = (TextAlignmentOptions)514;
		((TMP_Text)val12).fontStyle = (FontStyles)2;
		((TMP_Text)val12).enableWordWrapping = false;
		((TMP_Text)val12).overflowMode = (TextOverflowModes)0;
		((TMP_Text)val12).text = "[ 0000 ]";
		GameObject val13 = new GameObject("Text");
		val13.transform.SetParent(val8.transform, false);
		RectTransform val14 = val13.AddComponent<RectTransform>();
		val14.anchorMin = Vector2.zero;
		val14.anchorMax = Vector2.one;
		val14.offsetMin = Vector2.zero;
		val14.offsetMax = Vector2.zero;
		val13.AddComponent<CanvasRenderer>();
		TextMeshProUGUI val15 = val13.AddComponent<TextMeshProUGUI>();
		((TMP_Text)val15).font = font;
		((TMP_Text)val15).fontSize = fontSize * 2.5f;
		((Graphic)val15).color = color;
		if ((Object)(object)fontMat != (Object)null)
		{
			((TMP_Text)val15).fontSharedMaterial = fontMat;
		}
		((TMP_Text)val15).alignment = (TextAlignmentOptions)514;
		((TMP_Text)val15).fontStyle = fontStyle;
		((TMP_Text)val15).enableWordWrapping = false;
		((TMP_Text)val15).overflowMode = (TextOverflowModes)0;
		numberInputField = val6.AddComponent<TMP_InputField>();
		numberInputField.textViewport = val9;
		numberInputField.textComponent = (TMP_Text)(object)val15;
		numberInputField.placeholder = (Graphic)(object)val12;
		numberInputField.characterLimit = 4;
		numberInputField.contentType = (ContentType)2;
		numberInputField.pointSize = fontSize * 2.5f;
		numberInputField.caretColor = color;
		numberInputField.customCaretColor = true;
		string value = ConfigManager.ClientRequestedNumber.Value;
		if (!string.IsNullOrEmpty(value))
		{
			numberInputField.text = value;
		}
		Plugin.Logger.LogInfo((object)"CustomNumbers: Phone number display created");
		return val;
	}

	private static void DumpHierarchy(Transform t, string indent)
	{
		//IL_00c4: 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_00e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
		string text = "";
		Component[] components = ((Component)t).GetComponents<Component>();
		foreach (Component val in components)
		{
			if ((Object)(object)val != (Object)null && !(val is Transform) && !(val is RectTransform))
			{
				text = text + " [" + ((object)val).GetType().Name + "]";
			}
		}
		TextMeshProUGUI component = ((Component)t).GetComponent<TextMeshProUGUI>();
		string text2 = (((Object)(object)component != (Object)null) ? (" text='" + ((TMP_Text)component).text + "'") : "");
		RectTransform component2 = ((Component)t).GetComponent<RectTransform>();
		string text3 = (((Object)(object)component2 != (Object)null) ? $" pos={component2.anchoredPosition} size={component2.sizeDelta} anchors=({component2.anchorMin},{component2.anchorMax})" : "");
		Plugin.Logger.LogInfo((object)(indent + ((Object)t).name + text + text2 + text3));
		for (int j = 0; j < t.childCount; j++)
		{
			DumpHierarchy(t.GetChild(j), indent + "  ");
		}
	}

	[HarmonyPatch("SaveCustomization")]
	[HarmonyPostfix]
	public static void SaveCustomizationPostfix()
	{
		if ((Object)(object)numberInputField != (Object)null)
		{
			string text = numberInputField.text;
			if (text.Length > 0 && text.Length < 4)
			{
				text = text.PadLeft(4, '0');
			}
			ConfigManager.ClientRequestedNumber.Value = text;
			ConfigManager.Config.Save();
			Plugin.Logger.LogInfo((object)("CustomNumbers: Saved phone number: " + text));
		}
	}
}
[HarmonyPatch(typeof(MenuManager))]
public class ForceUIPatch
{
	[HarmonyPatch("Start")]
	[HarmonyPostfix]
	public static void StartPostfix(MenuManager __instance)
	{
		if (!__instance.isInitScene)
		{
			((MonoBehaviour)__instance).StartCoroutine(DelayedMainMenuInjection());
		}
	}

	private static IEnumerator DelayedMainMenuInjection()
	{
		yield return (object)new WaitForSeconds(0f);
		GameObject menuContainer = GameObject.Find("MenuContainer");
		if (!Object.op_Implicit((Object)(object)menuContainer))
		{
			yield break;
		}
		Transform mainButtonsTransform = menuContainer.transform.Find("MainButtons");
		if (!Object.op_Implicit((Object)(object)mainButtonsTransform))
		{
			yield break;
		}
		TextMeshProUGUI existingButton = ((IEnumerable<TextMeshProUGUI>)((Component)mainButtonsTransform).GetComponentsInChildren<TextMeshProUGUI>()).FirstOrDefault((Func<TextMeshProUGUI, bool>)((TextMeshProUGUI t) => ((TMP_Text)t).text == "> Personalize Phone"));
		if ((Object)(object)existingButton != (Object)null)
		{
			yield break;
		}
		Transform quitButton = mainButtonsTransform.Find("QuitButton");
		if (!Object.op_Implicit((Object)(object)quitButton))
		{
			yield break;
		}
		Plugin.Logger.LogInfo((object)"LethalPhonesCustomNumbers: Forcing Customization GUI to spawn because LethalPhones skipped it...");
		MethodInfo method = typeof(CustomizationManager).Assembly.GetType("Scoops.customization.CustomizationMenuUtils")?.GetMethod("InjectMenu", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
		if (method != null)
		{
			method.Invoke(null, new object[2]
			{
				mainButtonsTransform,
				((Component)quitButton).gameObject
			});
			object? obj = AccessTools.Field(typeof(CustomizationManager), "customizationPanel")?.GetValue(null);
			Transform customizationPanel = (Transform)((obj is Transform) ? obj : null);
			if ((Object)(object)customizationPanel != (Object)null)
			{
				Plugin.Logger.LogInfo((object)"Dumping CustomizationPanel hierarchy:");
				DumpTransform(customizationPanel, "");
			}
		}
		else
		{
			Plugin.Logger.LogError((object)"LethalPhonesCustomNumbers: Failed to find CustomizationMenuUtils.InjectMenu via reflection!");
		}
	}

	private static void DumpTransform(Transform t, string indent)
	{
		Plugin.Logger.LogInfo((object)(indent + ((Object)t).name + " (" + ((object)t).GetType().Name + ")"));
		Component[] components = ((Component)t).GetComponents<Component>();
		foreach (Component val in components)
		{
			if ((Object)(object)val != (Object)null && ((object)val).GetType() != typeof(Transform))
			{
				Plugin.Logger.LogInfo((object)(indent + " - " + ((object)val).GetType().Name));
			}
		}
		for (int j = 0; j < t.childCount; j++)
		{
			DumpTransform(t.GetChild(j), indent + "  ");
		}
	}
}
[HarmonyPatch(typeof(PhoneNetworkHandler))]
public class PhoneNetworkHandlerPatch
{
	private static FieldInfo _phoneNumberDictField = AccessTools.Field(typeof(PhoneNetworkHandler), "phoneNumberDict");

	private static FieldInfo _phoneObjectDictField = AccessTools.Field(typeof(PhoneNetworkHandler), "phoneObjectDict");

	private static MethodInfo _requestClientUpdatesMethod = AccessTools.Method(typeof(PhoneNetworkHandler), "RequestClientUpdates", (Type[])null, (Type[])null);

	[HarmonyPatch("CreateNewPhoneNumberServerRpc")]
	[HarmonyPrefix]
	public static bool CreateNewPhoneNumberServerRpcPrefix(ulong phoneId, ref string skinId, string charmId, string ringtoneId, ref PhoneNetworkHandler __instance, ServerRpcParams serverRpcParams)
	{
		//IL_0075: Unknown result type (might be due to invalid IL or missing references)
		//IL_0077: Unknown result type (might be due to invalid IL or missing references)
		Plugin.Logger.LogInfo((object)$"Intercepted CreateNewPhoneNumberServerRpc for PhoneId: {phoneId}");
		string text = null;
		if (skinId != null && skinId.Contains("|"))
		{
			string[] array = skinId.Split('|');
			skinId = array[0];
			if (array.Length > 1)
			{
				text = array[1];
				Plugin.Logger.LogInfo((object)("Server received requested custom number: " + text));
			}
		}
		ulong senderClientId = serverRpcParams.Receive.SenderClientId;
		ulong num = 0uL;
		if ((Object)(object)StartOfRound.Instance != (Object)null && StartOfRound.Instance.allPlayerScripts != null)
		{
			PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
			foreach (PlayerControllerB val in allPlayerScripts)
			{
				if (val.actualClientId == senderClientId)
				{
					num = val.playerSteamId;
					break;
				}
			}
		}
		IDictionary dictionary = (IDictionary)_phoneNumberDictField.GetValue(__instance);
		IDictionary dictionary2 = (IDictionary)_phoneObjectDictField.GetValue(__instance);
		int value = Config.maxPhoneNumber.Value;
		if (dictionary.Count >= value)
		{
			Plugin.Logger.LogError((object)"Cannot create a new unique phone number. Not enough numbers remaining. Please increase the maxPhoneNumber config.");
			return false;
		}
		short num2 = -1;
		bool flag = false;
		if (!string.IsNullOrEmpty(text) && text.Length == 4 && short.TryParse(text, out var result))
		{
			if (!dictionary.Contains(result) && result.ToString("D4") != Config.switchboardNumber.Value)
			{
				num2 = result;
				flag = true;
				Plugin.Logger.LogInfo((object)$"Custom number {result:D4} is available and assigned to SteamId {num}");
			}
			else
			{
				Plugin.Logger.LogInfo((object)$"Custom number {result:D4} is already taken or invalid! Falling back to deterministic generation.");
			}
		}
		if (!flag && num != 0L && ConfigManager.SteamIdToNumber.TryGetValue(num, out var value2))
		{
			if (value2 < value && !dictionary.Contains(value2) && value2.ToString("D4") != Config.switchboardNumber.Value)
			{
				num2 = value2;
				flag = true;
				Plugin.Logger.LogInfo((object)$"Assigned config mapped number {num2:D4} for Steam ID {num}");
			}
			else
			{
				Plugin.Logger.LogWarning((object)$"Mapped number {value2:D4} for Steam ID {num} is invalid (in use or out of bounds). Falling back.");
			}
		}
		if (!flag && num != 0)
		{
			num2 = (short)(num % (ulong)value);
			string text2 = num2.ToString("D4");
			int num3 = 0;
			while ((dictionary.Contains(num2) || text2 == Config.switchboardNumber.Value) && num3 < value)
			{
				num2 = (short)((num2 + 1) % value);
				text2 = num2.ToString("D4");
				num3++;
			}
			if (num3 < value)
			{
				flag = true;
				Plugin.Logger.LogInfo((object)$"Assigned hashed number {num2:D4} for Steam ID {num}");
			}
		}
		if (!flag)
		{
			num2 = (short)Random.Range(0, value);
			string text3 = num2.ToString("D4");
			while (dictionary.Contains(num2) || text3 == Config.switchboardNumber.Value)
			{
				num2 = (short)Random.Range(0, value);
				text3 = num2.ToString("D4");
			}
			Plugin.Logger.LogInfo((object)$"Assigned random number {num2:D4} (no steam id or hash collision)");
		}
		NetworkManager.Singleton.SpawnManager.SpawnedObjects.TryGetValue(phoneId, out var value3);
		if ((Object)(object)value3 == (Object)null)
		{
			Plugin.Logger.LogError((object)$"NetworkObject with ID {phoneId} not found.");
			return false;
		}
		Component component = ((Component)value3).GetComponent(AccessTools.TypeByName("Scoops.gameobjects.PhoneBehavior") ?? AccessTools.TypeByName("Scoops.misc.PhoneBehavior") ?? AccessTools.TypeByName("Scoops.PhoneBehavior"));
		Plugin.Logger.LogInfo((object)$"New phone for object: {phoneId}");
		value3.ChangeOwnership(senderClientId);
		dictionary.Add(num2, value3.NetworkObjectId);
		dictionary2.Add(num2, component);
		AccessTools.Field(((object)component).GetType(), "phoneSkinId").SetValue(component, skinId);
		AccessTools.Field(((object)component).GetType(), "phoneCharmId").SetValue(component, charmId);
		AccessTools.Field(((object)component).GetType(), "phoneRingtoneId").SetValue(component, ringtoneId);
		AccessTools.Method(((object)component).GetType(), "SetNewPhoneNumberClientRpc", (Type[])null, (Type[])null).Invoke(component, new object[1] { num2 });
		_requestClientUpdatesMethod.Invoke(__instance, null);
		return false;
	}
}
[BepInPlugin("com.ashby.lethalphonescustomnumbers", "LethalPhonesCustomNumbers", "1.0.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class Plugin : BaseUnityPlugin
{
	private Harmony _harmony;

	public static Plugin Instance { get; private set; }

	public static ManualLogSource Logger { get; private set; }

	public Dictionary<ulong, short> CustomNumbersMap { get; private set; } = new Dictionary<ulong, short>();

	private void Awake()
	{
		//IL_003a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Expected O, but got Unknown
		Instance = this;
		Logger = Logger.CreateLogSource("LethalPhonesCustomNumbers");
		Logger.LogInfo((object)"Plugin LethalPhonesCustomNumbers is loaded!");
		ConfigManager.Init(((BaseUnityPlugin)this).Config);
		_harmony = new Harmony("com.ashby.lethalphonescustomnumbers");
		_harmony.PatchAll();
		Logger.LogInfo((object)"Patches applied successfully.");
	}
}
public static class PluginInfo
{
	public const string PLUGIN_GUID = "LethalPhonesCustomNumbers";

	public const string PLUGIN_NAME = "LethalPhonesCustomNumbers";

	public const string PLUGIN_VERSION = "1.0.0";
}