using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using LC_API.ServerAPI;
using TMPro;
using Unity.Netcode;
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(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("ChangeName")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Change in-game name")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+9ad07e918fa6011a98cef2e1281a0a7577b70a07")]
[assembly: AssemblyProduct("ChangeName")]
[assembly: AssemblyTitle("ChangeName")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace ChangeName
{
[BepInPlugin("me.wallen.changename", "Change Player Names", "1.0.0")]
public class ChangeNamePlugin : BaseUnityPlugin
{
private const string GUID = "me.wallen.changename";
private const string NAME = "Change Player Names";
private const string VERSION = "1.0.0";
private static ChangeNamePlugin Instance;
private void Awake()
{
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: Expected O, but got Unknown
Instance = this;
LogInfo("Loading...");
Harmony val = new Harmony("me.wallen.changename");
val.PatchAll();
Networking.GetString = (Action<string, string>)Delegate.Combine(Networking.GetString, new Action<string, string>(NameDatabase.NDNetGetString));
LogInfo("Loading Complete!");
}
internal static void LogDebug(string message)
{
Instance.Log(message, (LogLevel)32);
}
internal static void LogInfo(string message)
{
Instance.Log(message, (LogLevel)16);
}
internal static void LogWarning(string message)
{
Instance.Log(message, (LogLevel)4);
}
internal static void LogError(string message)
{
Instance.Log(message, (LogLevel)2);
}
internal static void LogError(Exception ex)
{
Instance.Log(ex.Message + "\n" + ex.StackTrace, (LogLevel)2);
}
private void Log(string message, LogLevel logLevel)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
((BaseUnityPlugin)this).Logger.Log(logLevel, (object)message);
}
}
internal static class NameDatabase
{
internal static bool shouldUpdateNames = false;
internal static bool shouldSendNames = false;
public const string SIG_BEGIN_UPDATE_NAMES = "CHANGE_NAME_BEGIN_UPDATE_NAMES";
public const string SIG_UPDATE_NAME = "CHANGE_NAME_UPDATE_NAME";
public const string SIG_END_UPDATE_NAMES = "CHANGE_NAME_END_UPDATE_NAMES";
public const string SIG_PLAYER_JOIN = "CHANGE_NAME_PLAYER_JOIN";
public const string SIG_NEW_LEVEL = "CHANGE_NAME_NEW_LEVEL";
private const string SIG_NEW_ROUND = "CHANGE_NAME_NEW_ROUND";
private static Dictionary<ulong, string> names = new Dictionary<ulong, string>();
internal static string GetName(ulong id)
{
if (!names.ContainsKey(id))
{
ChangeNamePlugin.LogWarning("[NameDatabase.GetName] Failed to get name");
return "";
}
return names[id];
}
internal static void SetName(ulong id, string name)
{
if (!names.ContainsKey(id))
{
names.Add(id, name);
}
else
{
names[id] = name;
}
}
internal static bool HasName(string name)
{
return names.ContainsValue(name);
}
internal static bool HasId(ulong id)
{
return names.ContainsKey(id);
}
internal static ulong GetUsableIdFromPlayer(PlayerControllerB player)
{
if (!GameNetworkManager.Instance.disableSteam)
{
return player.playerSteamId;
}
return player.playerClientId;
}
internal static void UpdateName(string oldName, string newName)
{
if (!names.ContainsValue(oldName))
{
ChangeNamePlugin.LogWarning("[NameDatabase.UpdateName] Tried to update name " + oldName + " but it does not exist");
ChangeNamePlugin.LogWarning(names.ToString());
}
else
{
ulong key = names.FirstOrDefault((KeyValuePair<ulong, string> x) => x.Value == oldName).Key;
names[key] = newName;
}
shouldUpdateNames = true;
}
internal static int NumberOfNames()
{
return names.Count;
}
internal static void NDNetGetString(string data, string signature)
{
switch (signature)
{
case "CHANGE_NAME_PLAYER_JOIN":
case "CHANGE_NAME_NEW_ROUND":
if (((NetworkBehaviour)StartOfRound.Instance).IsHost)
{
shouldSendNames = true;
}
break;
case "CHANGE_NAME_BEGIN_UPDATE_NAMES":
ChangeNamePlugin.LogInfo("[NameDatabase] Beginning name update process.");
break;
case "CHANGE_NAME_UPDATE_NAME":
{
KeyValuePair<ulong, string>? keyValuePair = DecodeName(data);
if (keyValuePair.HasValue)
{
KeyValuePair<ulong, string> value = keyValuePair.Value;
ChangeNamePlugin.LogInfo("[NameDatabase] New name received: " + value.Key + " : " + value.Value);
names[value.Key] = value.Value;
}
break;
}
case "CHANGE_NAME_END_UPDATE_NAMES":
ChangeNamePlugin.LogInfo("[NameDatabase] End of name update process.");
shouldUpdateNames = true;
break;
}
}
internal static void NDNetSendNames()
{
Networking.Broadcast(string.Empty, "CHANGE_NAME_BEGIN_UPDATE_NAMES");
foreach (KeyValuePair<ulong, string> name in names)
{
string text = EncodeName(name);
Networking.Broadcast(text, "CHANGE_NAME_UPDATE_NAME");
}
Networking.Broadcast(string.Empty, "CHANGE_NAME_END_UPDATE_NAMES");
}
private static string EncodeName(KeyValuePair<ulong, string> namePair)
{
return $"{namePair.Key}:{namePair.Value}";
}
private static KeyValuePair<ulong, string>? DecodeName(string encoded)
{
string[] array = encoded.Split(':');
if (array.Length == 2 && ulong.TryParse(array[0], out var result))
{
return new KeyValuePair<ulong, string>(result, array[1]);
}
return null;
}
private static string EncodeNames(Dictionary<ulong, string> names)
{
StringBuilder stringBuilder = new StringBuilder();
foreach (KeyValuePair<ulong, string> name in names)
{
stringBuilder.Append($"{name.Key}:{name.Value};");
}
return stringBuilder.ToString();
}
private static Dictionary<ulong, string> DecodeNames(string encoded)
{
string[] array = encoded.Split(new char[1] { ';' }, StringSplitOptions.RemoveEmptyEntries);
Dictionary<ulong, string> dictionary = new Dictionary<ulong, string>();
string[] array2 = array;
foreach (string text in array2)
{
string[] array3 = text.Split(':');
dictionary[ulong.Parse(array3[0])] = array3[1];
}
return dictionary;
}
private static string DictionaryToString(Dictionary<ulong, string> dictionary)
{
StringBuilder stringBuilder = new StringBuilder();
foreach (KeyValuePair<ulong, string> item in dictionary)
{
stringBuilder.AppendLine($"Key: {item.Key}, Value: {item.Value}");
}
return stringBuilder.ToString();
}
}
}
namespace ChangeName.Patches
{
[HarmonyPatch(typeof(HUDManager), "AddChatMessage")]
internal class HUDManager_AddChatMessage
{
private static string lastChatMessage = "";
private static void Postfix(HUDManager __instance, string chatMessage, string nameOfUserWhoTyped)
{
if (lastChatMessage == chatMessage)
{
return;
}
lastChatMessage = chatMessage;
ChangeNamePlugin.LogDebug(chatMessage);
if (chatMessage.Contains("!name"))
{
string text = chatMessage.Substring(chatMessage.IndexOf("!name") + "!name".Length).Trim();
if (NameDatabase.HasName(text))
{
__instance.AddTextToChatOnServer("Duplicate names are not allowed!", -1);
}
else if (((NetworkBehaviour)__instance.playersManager).IsHost)
{
NameDatabase.UpdateName(nameOfUserWhoTyped, text);
NameDatabase.shouldSendNames = true;
NameDatabase.shouldUpdateNames = true;
}
}
}
}
[HarmonyPatch(typeof(PlayerControllerB), "ConnectClientToPlayerObject")]
internal class PlayerControllerB_ConnectClientToPlayerObject
{
private static void Postfix(PlayerControllerB __instance)
{
ChangeNamePlugin.LogDebug("Steam Disabled: " + GameNetworkManager.Instance.disableSteam);
ChangeNamePlugin.LogDebug("Is Host: " + ((NetworkBehaviour)__instance).IsHost);
ChangeNamePlugin.LogDebug("Player steam ID: " + __instance.playerSteamId);
ChangeNamePlugin.LogDebug("Player client ID: " + __instance.playerClientId);
ChangeNamePlugin.LogDebug("Actual client ID: " + __instance.actualClientId);
ChangeNamePlugin.LogDebug("Player Username: " + __instance.playerUsername);
Networking.Broadcast("", "CHANGE_NAME_PLAYER_JOIN");
}
}
[HarmonyPatch(typeof(PlayerControllerB), "Update")]
internal class PlayerControllerB_Update
{
private static float lastUpdateTime;
private static void Postfix(PlayerControllerB __instance)
{
if (!(lastUpdateTime + 2f < Time.time))
{
return;
}
if (((NetworkBehaviour)__instance).IsHost)
{
PlayerControllerB[] allPlayerScripts = __instance.playersManager.allPlayerScripts;
foreach (PlayerControllerB val in allPlayerScripts)
{
if (!NameDatabase.HasId(NameDatabase.GetUsableIdFromPlayer(val)))
{
NameDatabase.SetName(NameDatabase.GetUsableIdFromPlayer(val), val.playerUsername);
}
}
if (NameDatabase.shouldSendNames)
{
NameDatabase.NDNetSendNames();
NameDatabase.shouldSendNames = false;
}
}
if (NameDatabase.shouldUpdateNames)
{
PlayerControllerB[] allPlayerScripts2 = __instance.playersManager.allPlayerScripts;
foreach (PlayerControllerB val2 in allPlayerScripts2)
{
string name = NameDatabase.GetName(NameDatabase.GetUsableIdFromPlayer(val2));
foreach (TransformAndName radarTarget in StartOfRound.Instance.mapScreen.radarTargets)
{
Transform transform = radarTarget.transform;
if (radarTarget.name == val2.playerUsername)
{
StartOfRound.Instance.mapScreen.ChangeNameOfTargetTransform(transform, name);
}
}
val2.playerUsername = name;
((TMP_Text)val2.usernameBillboardText).text = name;
}
NameDatabase.shouldUpdateNames = false;
}
lastUpdateTime = Time.time;
}
}
[HarmonyPatch(typeof(StartOfRound), "ArriveAtLevel")]
internal class StartOfRound_ArriveAtLevel
{
private static void Postfix(StartOfRound __instance)
{
}
}
}