Decompiled source of NameBending v1.0.4

Mods/NameBending.dll

Decompiled 2 days 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.Versioning;
using System.Security;
using System.Text.RegularExpressions;
using Il2CppExitGames.Client.Photon;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppPhoton.Pun;
using Il2CppPhoton.Realtime;
using Il2CppRUMBLE.Economy;
using Il2CppRUMBLE.Players;
using Il2CppRUMBLE.Utilities;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using Il2CppTMPro;
using MelonLoader;
using Microsoft.CodeAnalysis;
using NameBending;
using Newtonsoft.Json;
using RumbleModUI;
using RumbleModdingAPI;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyDescription("Change your name and title to anything you like")]
[assembly: AssemblyCopyright("Created by TacoSlayer36")]
[assembly: AssemblyTrademark(null)]
[assembly: MelonInfo(typeof(NBClass), "NameBending", "1.0.3", "TacoSlayer36", null)]
[assembly: MelonColor]
[assembly: MelonGame(null, null)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("NameBending")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("NameBending")]
[assembly: AssemblyTitle("NameBending")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
public static class StringExt
{
	public static string Truncate(this string value, int maxLength)
	{
		if (maxLength > 0)
		{
			if (string.IsNullOrEmpty(value))
			{
				return value;
			}
			return (value.Length <= maxLength) ? value : value.Substring(0, maxLength);
		}
		if (maxLength == 0)
		{
			return "";
		}
		return value;
	}

	public static string RemoveInPlaceCharArray(string input)
	{
		int length = input.Length;
		char[] array = input.ToCharArray();
		int length2 = 0;
		for (int i = 0; i < length; i++)
		{
			char c = array[i];
			switch (c)
			{
			case '\t':
			case '\n':
			case '\v':
			case '\f':
			case '\r':
			case ' ':
			case '\u0085':
			case '\u00a0':
			case '\u1680':
			case '\u2000':
			case '\u2001':
			case '\u2002':
			case '\u2003':
			case '\u2004':
			case '\u2005':
			case '\u2006':
			case '\u2007':
			case '\u2008':
			case '\u2009':
			case '\u200a':
			case '\u2028':
			case '\u2029':
			case '\u202f':
			case '\u205f':
			case '\u3000':
				continue;
			}
			array[length2++] = c;
		}
		return new string(array, 0, length2);
	}

	public static int LevenshteinDistance(string source, string target)
	{
		if (string.IsNullOrEmpty(source))
		{
			return (!string.IsNullOrEmpty(target)) ? target.Length : 0;
		}
		if (string.IsNullOrEmpty(target))
		{
			return source.Length;
		}
		int length = source.Length;
		int length2 = target.Length;
		int[,] array = new int[length + 1, length2 + 1];
		int num = 0;
		while (num <= length)
		{
			array[num, 0] = num++;
		}
		int num2 = 0;
		while (num2 <= length2)
		{
			array[0, num2] = num2++;
		}
		for (int i = 1; i <= length; i++)
		{
			for (int j = 1; j <= length2; j++)
			{
				int num3 = ((target[j - 1] != source[i - 1]) ? 1 : 0);
				array[i, j] = Math.Min(Math.Min(array[i - 1, j] + 1, array[i, j - 1] + 1), array[i - 1, j - 1] + num3);
			}
		}
		return array[length, length2];
	}

	public static string MarkCounterfeit(this string value)
	{
		string text = value;
		CatalogHandler component = ((Component)Singleton<CatalogHandler>.Instance).GetComponent<CatalogHandler>();
		Il2CppReferenceArray<CatalogItem> catalogItemsWithTags = component.GetCatalogItemsWithTags((ItemTag)4096);
		foreach (CatalogItem item in (Il2CppArrayBase<CatalogItem>)(object)catalogItemsWithTags)
		{
			string source = ("Item.Part.Title." + RemoveInPlaceCharArray(value) + ".Name").ToLower();
			string target = item.Title.ToLower();
			if (LevenshteinDistance(source, target) <= 2)
			{
				text += "<pos=0><#F00>COUNTERFEIT";
				break;
			}
		}
		return text;
	}
}
namespace NameBending
{
	public static class BuildInfo
	{
		public const string ModName = "NameBending";

		public const string ModVersion = "1.0.3";

		public const string Description = "Change your name and title to anything you like";

		public const string Author = "TacoSlayer36";

		public const string Company = "";
	}
	public class Variation
	{
		[JsonProperty("altText")]
		public string AltText;

		[JsonProperty("frameDuration")]
		public int FrameDuration;

		[JsonProperty("frames")]
		public Dictionary<int, string> Frames;
	}
	public class Root
	{
		[JsonProperty("doRandomVariations")]
		public bool DoRandomVariations { get; set; }

		[JsonProperty("variations")]
		public List<Variation> Variations { get; set; }
	}
	public class NBClass : MelonMod
	{
		private Mod Mod = new Mod();

		private bool showOtherNames = true;

		private bool showMyName = true;

		private bool showMyAlt = true;

		private bool showOtherTitles = true;

		private bool showMyTitle = true;

		private bool showAnimations = true;

		private int truncationLength = -1;

		private int playerCount = 1;

		private string sceneName = "Loader";

		private int currentNameVariationIndex = 0;

		private int currentTitleVariationIndex = 0;

		private float timer = 0f;

		private const byte nameEventNumber = 30;

		private const byte titleEventNumber = 31;

		private bool eventInit = false;

		private List<Player> playerList;

		private List<Player> lastPlayerList;

		private List<string> AllNameJsons = new List<string>();

		private List<string> AllTitleJsons = new List<string>();

		private static RaiseEventOptions eventOptions = new RaiseEventOptions
		{
			Receivers = (ReceiverGroup)0
		};

		private float updateNameCooldown = 0f;

		private CatalogHandler handler;

		public override void OnLateInitializeMelon()
		{
			((MelonBase)this).OnLateInitializeMelon();
			UI.instance.UI_Initialized += OnUIInit;
		}

		public void OnUIInit()
		{
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected O, but got Unknown
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Expected O, but got Unknown
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Expected O, but got Unknown
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Expected O, but got Unknown
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Expected O, but got Unknown
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Expected O, but got Unknown
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Expected O, but got Unknown
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Expected O, but got Unknown
			Mod.ModName = "NameBending";
			Mod.ModVersion = "1.0.3";
			Mod.SetFolder("NameBending");
			Mod.AddDescription("Description", "", "Change your name and title to anything you like", new Tags
			{
				IsSummary = true
			});
			Mod.AddToList("Others' Custom Names", true, 0, "See others' custom bent names", new Tags());
			Mod.AddToList("My Custom Name", true, 0, "See your custom bent name", new Tags());
			Mod.AddToList("My Alt Name", true, 0, "Others will see the name specified under \"altText\" in the settings file when they don't have the mod", new Tags());
			Mod.AddToList("Others' Custom Titles", true, 0, "See others' custom bent titles", new Tags());
			Mod.AddToList("My Custom Title", true, 0, "Others will see your custom bent title", new Tags());
			Mod.AddToList("Animations", true, 0, "Name and title animations will be visible", new Tags());
			Mod.AddToList("Truncation Length", -1, "Max number of characters to show on names and titles (set to -1 to disable)", new Tags());
			Mod.GetFromFile();
			Mod.ModSaved += Save;
			UI.instance.AddMod(Mod);
			MelonLogger.Msg("Added Mod: NameBending");
		}

		public void Save()
		{
			showOtherNames = (bool)Mod.Settings[1].SavedValue;
			showMyName = (bool)Mod.Settings[2].SavedValue;
			showMyAlt = (bool)Mod.Settings[3].SavedValue;
			showOtherTitles = (bool)Mod.Settings[4].SavedValue;
			showMyTitle = (bool)Mod.Settings[5].SavedValue;
			showAnimations = (bool)Mod.Settings[6].SavedValue;
			truncationLength = (int)Mod.Settings[7].SavedValue;
		}

		public override void OnUpdate()
		{
			if (updateNameCooldown > 0f)
			{
				updateNameCooldown -= Time.deltaTime;
			}
			if (Input.GetKeyDown((KeyCode)109))
			{
				foreach (string allTitleJson in AllTitleJsons)
				{
					MelonLogger.Msg(allTitleJson);
				}
			}
			if (Input.GetKeyDown((KeyCode)110) && sceneName != "Loader")
			{
				if (updateNameCooldown <= 0f)
				{
					purgeNonexistentPlayerJsons(AllNameJsons, Managers.GetPlayerManager().LocalPlayer);
					purgeNonexistentPlayerJsons(AllTitleJsons, Managers.GetPlayerManager().LocalPlayer);
					updateNameCooldown = 3f;
					DetermineSituation();
				}
				else
				{
					MelonLogger.Error("Please wait to update name again");
				}
			}
		}

		public override void OnFixedUpdate()
		{
			if (showAnimations)
			{
				timer += Time.deltaTime;
			}
			if (eventInit)
			{
				if (sceneName != "Gym" && sceneName != "Loader")
				{
					if (Managers.GetPlayerManager().AllPlayers.Count > playerCount)
					{
						playerList = Managers.GetPlayerManager().AllPlayers;
						AnalyzeAndRaise("Name");
						AnalyzeAndRaise("Title");
						timer = 0f;
					}
					if (Managers.GetPlayerManager().AllPlayers.Count < playerCount)
					{
						playerList = Managers.GetPlayerManager().AllPlayers;
						List<Player> val = new List<Player>();
						if (lastPlayerList != null)
						{
							Enumerator<Player> enumerator = lastPlayerList.GetEnumerator();
							while (enumerator.MoveNext())
							{
								Player current = enumerator.Current;
								if (!playerList.Contains(current))
								{
									val.Add(current);
								}
							}
						}
						Enumerator<Player> enumerator2 = val.GetEnumerator();
						while (enumerator2.MoveNext())
						{
							Player current2 = enumerator2.Current;
							purgeNonexistentPlayerJsons(AllNameJsons, current2);
							purgeNonexistentPlayerJsons(AllTitleJsons, current2);
						}
					}
					lastPlayerList = new List<Player>();
					if (playerList != null)
					{
						Enumerator<Player> enumerator3 = playerList.GetEnumerator();
						while (enumerator3.MoveNext())
						{
							Player current3 = enumerator3.Current;
							lastPlayerList.Add(current3);
						}
					}
				}
				playerCount = Managers.GetPlayerManager().AllPlayers.Count;
			}
			if (showOtherNames && AllNameJsons != null && AllNameJsons.Any())
			{
				finalize("Name");
			}
			if (showOtherTitles && AllTitleJsons != null && AllTitleJsons.Any())
			{
				finalize("Title");
			}
		}

		public void finalize(string tagType)
		{
			List<string> list = new List<string>();
			List<string> list2 = new List<string>();
			if (!(sceneName != "Loader"))
			{
				return;
			}
			if (tagType == "Name")
			{
				list2 = AllNameJsons;
			}
			if (tagType == "Title")
			{
				list2 = AllTitleJsons;
			}
			foreach (string item in list2)
			{
				Variation variation = null;
				string text = null;
				try
				{
					string pattern = "}.+\\Z";
					Match match = Regex.Match(item, pattern);
					text = match.Value;
					text = text.Substring(1);
					string text2 = item.Replace(text, string.Empty);
					variation = JsonConvert.DeserializeObject<Variation>(text2);
				}
				catch
				{
					MelonLogger.Error("Received invalid Json. Removing from pool");
					list.Add(item);
					break;
				}
				if (variation != null && text != null)
				{
					changeTagText(variation, text, tagType);
				}
			}
			foreach (string item2 in list)
			{
				list2.Remove(item2);
			}
		}

		public void purgeNonexistentPlayerJsons(List<string> purgeInJsons, Player player)
		{
			List<string> list = new List<string>();
			foreach (string purgeInJson in purgeInJsons)
			{
				string text = string.Empty;
				try
				{
					string pattern = "}.+\\Z";
					Match match = Regex.Match(purgeInJson, pattern);
					text = match.Value.Substring(1);
				}
				catch
				{
					MelonLogger.Error("Noticed invalid Json on player leave. Removing from pool");
					list.Add(purgeInJson);
				}
				if (text == player.Data.GeneralData.PlayFabMasterId)
				{
					list.Add(purgeInJson);
				}
			}
			foreach (string item in list)
			{
				purgeInJsons.Remove(item);
			}
		}

		public override void OnSceneWasLoaded(int buildIndex, string name)
		{
			sceneName = name;
			AllNameJsons.Clear();
			AllTitleJsons.Clear();
			DetermineSituation();
		}

		public void DetermineSituation()
		{
			if (sceneName == "Gym" && !eventInit)
			{
				MelonCoroutines.Start(WaitThenAddEvent());
				eventInit = true;
			}
			if (sceneName != "Loader")
			{
				AnalyzeAndRaise("Name");
				AnalyzeAndRaise("Title");
			}
		}

		public void AnalyzeAndRaise(string tagType)
		{
			if ((tagType == "Name" && !showMyName) || (tagType == "Title" && !showMyTitle))
			{
				return;
			}
			string empty = string.Empty;
			try
			{
				empty = File.ReadAllText("UserData/NameBending/customBent" + tagType + ".json");
			}
			catch
			{
				MelonLogger.Error("Could not find custom name file at \"UserData/NameBending/customBent" + tagType + ".json\"");
				return;
			}
			string playFabMasterId = Managers.GetPlayerManager().LocalPlayer.Data.GeneralData.PlayFabMasterId;
			Root root = new Root();
			try
			{
				root = JsonConvert.DeserializeObject<Root>(empty);
			}
			catch
			{
				MelonLogger.Error("Failed to deserialize JSON. Make sure it is formatted correctly");
				return;
			}
			string text = "";
			int index = 0;
			if (root.DoRandomVariations)
			{
				index = Random.Range(0, root.Variations.Count);
			}
			else if (tagType == "Name")
			{
				index = currentNameVariationIndex;
				currentNameVariationIndex = (currentNameVariationIndex + 1) % root.Variations.Count;
			}
			else if (tagType == "Title")
			{
				index = currentTitleVariationIndex;
				currentTitleVariationIndex = (currentTitleVariationIndex + 1) % root.Variations.Count;
			}
			if (tagType == "Name" && showMyAlt && root.Variations[index].AltText.Length > 0 && root.Variations[index].AltText.Length <= 31)
			{
				Managers.GetPlayerManager().LocalPlayer.Data.GeneralData.PublicUsername = root.Variations[index].AltText;
			}
			if (tagType == "Title")
			{
				foreach (int item2 in root.Variations[index].Frames.Keys.ToList())
				{
					root.Variations[index].Frames[item2] = root.Variations[index].Frames[item2].MarkCounterfeit();
				}
			}
			text = JsonConvert.SerializeObject((object)root.Variations[index], (Formatting)1);
			if (sceneName == "Gym")
			{
				string item = text + playFabMasterId;
				if (tagType == "Name" && !AllNameJsons.Contains(item))
				{
					AllNameJsons.Add(item);
				}
				if (tagType == "Title")
				{
					AllTitleJsons.Add(item);
				}
			}
			else
			{
				MelonCoroutines.Start(WaitThenRaise(text, playFabMasterId, tagType));
			}
		}

		private IEnumerator WaitThenRaise(string justVariationJson, string myInternalID, string tagType)
		{
			yield return (object)new WaitForSeconds(2f);
			if (tagType == "Name")
			{
				PhotonNetwork.RaiseEvent((byte)30, Object.op_Implicit(justVariationJson + myInternalID), eventOptions, SendOptions.SendReliable);
			}
			if (tagType == "Title")
			{
				PhotonNetwork.RaiseEvent((byte)31, Object.op_Implicit(justVariationJson + myInternalID), eventOptions, SendOptions.SendReliable);
			}
		}

		private IEnumerator WaitThenAddEvent()
		{
			yield return (object)new WaitForSeconds(2f);
			LoadBalancingClient networkingClient = PhotonNetwork.NetworkingClient;
			networkingClient.EventReceived += Action<EventData>.op_Implicit((Action<EventData>)OnEvent);
		}

		public void OnEvent(EventData photonEvent)
		{
			if (photonEvent.Code == 30)
			{
				string item = photonEvent.CustomData.ToString();
				if (!AllNameJsons.Contains(item))
				{
					AllNameJsons.Add(item);
				}
			}
			if (photonEvent.Code != 31)
			{
				return;
			}
			string text = photonEvent.CustomData.ToString();
			string pattern = "}.+\\Z";
			Match match = Regex.Match(text, pattern);
			string text2 = match.Value.Substring(1);
			string text3 = text.Replace(text2, string.Empty);
			Variation variation = JsonConvert.DeserializeObject<Variation>(text3);
			if (variation.Frames != null)
			{
				foreach (int item2 in variation.Frames.Keys.ToList())
				{
					if (variation.Frames[item2].Length <= 80)
					{
						variation.Frames[item2] = variation.Frames[item2].MarkCounterfeit();
					}
				}
			}
			text = JsonConvert.SerializeObject((object)variation, (Formatting)1) + text2;
			if (!AllTitleJsons.Contains(text))
			{
				AllTitleJsons.Add(text);
			}
		}

		private int FindLastFrame(Dictionary<int, string> frames)
		{
			int num = 0;
			foreach (KeyValuePair<int, string> frame in frames)
			{
				if (frame.Key > num)
				{
					num = frame.Key;
				}
			}
			if (num > 0)
			{
				return num;
			}
			return 1;
		}

		private void changeTagText(Variation currentVariation, string id, string tagType)
		{
			try
			{
				Enumerator<Player> enumerator = Managers.GetPlayerManager().AllPlayers.GetEnumerator();
				while (enumerator.MoveNext())
				{
					Player current = enumerator.Current;
					float num = (float)currentVariation.FrameDuration / 1000f;
					int key = (int)(timer / num) % (FindLastFrame(currentVariation.Frames) + 1);
					if (!currentVariation.Frames.TryGetValue(key, out string value))
					{
						continue;
					}
					if (current != null && (Object)(object)current.Controller != (Object)null && (Object)(object)((Component)current.Controller).gameObject != (Object)(object)((Component)Managers.GetPlayerManager().localPlayer.Controller).gameObject && current.Data.GeneralData.PlayFabMasterId == id && sceneName != "Gym")
					{
						TextMeshPro val = null;
						try
						{
							if (tagType == "Name")
							{
								val = ((Component)((Component)current.Controller).gameObject.transform.Find("NameTag").Find("PlayerNameText")).GetComponent<TextMeshPro>();
							}
							if (tagType == "Title")
							{
								val = ((Component)((Component)current.Controller).gameObject.transform.Find("NameTag").Find("Player Title Text")).GetComponent<TextMeshPro>();
							}
						}
						catch
						{
						}
						if ((Object)(object)val != (Object)null && ((TMP_Text)val).text != value.Truncate(truncationLength))
						{
							((TMP_Text)val).text = value.Truncate(truncationLength);
						}
					}
					if (sceneName == "Gym")
					{
						TextMeshPro val2 = null;
						if (tagType == "Name")
						{
							val2 = GameObject.Find("--------------SCENE--------------/Gym_Production/Dressing Room/Preview Player Controller/NameTag/PlayerNameText").GetComponent<TextMeshPro>();
						}
						if (tagType == "Title")
						{
							val2 = GameObject.Find("--------------SCENE--------------/Gym_Production/Dressing Room/Preview Player Controller/NameTag/Player Title Text").GetComponent<TextMeshPro>();
						}
						if ((Object)(object)val2 != (Object)null && ((TMP_Text)val2).text != value.Truncate(truncationLength))
						{
							((TMP_Text)val2).text = value.Truncate(truncationLength);
						}
					}
				}
			}
			catch
			{
			}
		}
	}
}