using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text.RegularExpressions; using HornetCloakColor.Client; using HornetCloakColor.Server; using HornetCloakColor.Shared; using Microsoft.CodeAnalysis; using SSMP.Api.Client; using SSMP.Api.Client.Networking; using SSMP.Api.Server; using SSMP.Api.Server.Networking; using SSMP.Game; using SSMP.Networking.Packet; using SSMP.Networking.Packet.Data; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("HornetCloakColor.SSMP")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+0eba9b2e5df530332fab65160f0c51fed55f93df")] [assembly: AssemblyProduct("HornetCloakColor.SSMP")] [assembly: AssemblyTitle("HornetCloakColor.SSMP")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] 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; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace HornetCloakColor.SSMPIntegration { public static class SatelliteEntry { public static void Register() { ClientAddon clientAddon = new ClientAddon(); ServerAddon serverAddon = new ServerAddon(); ClientAddon.RegisterAddon((ClientAddon)(object)clientAddon); ServerAddon.RegisterAddon((ServerAddon)(object)serverAddon); } public static void NotifyLocalCloakAppearanceChanged(CloakNetAppearance appearance) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) ClientAddon.Instance?.SetLocalCloakAppearance(appearance); } public static CloakColor GetRemoteMapColorOrDefault(ushort playerId) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) return ClientAddon.Instance?.GetRemoteMapColorOrDefault(playerId) ?? CloakColor.Default; } public static void NotifyLocalUsernameColorChanged(CloakColor color) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) ClientAddon.Instance?.SetLocalUsernameTint(hasCustomUsernameTint: true, color); } public static void ClearLocalUsernameColorOnNetwork() { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) ClientAddon.Instance?.SetLocalUsernameTint(hasCustomUsernameTint: false, default(CloakColor)); } public static void ResendStoredLocalColorsToServer() { ClientAddon.Instance?.ForceResendLocalColorsToServer(); } } } namespace HornetCloakColor.Shared { internal enum PacketId { CloakColorUpdate, UsernameColorUpdate, ServerUsernameColorRules } internal class CloakColorPacket : IPacketData { public ushort PlayerId; public CloakColor Color; public byte TextureSaturationCenti = 100; public bool IsReliable => true; public bool DropReliableDataIfNewerExists => true; public void WriteData(IPacket packet) { packet.Write(PlayerId); packet.Write(((CloakColor)(ref Color)).R); packet.Write(((CloakColor)(ref Color)).G); packet.Write(((CloakColor)(ref Color)).B); packet.Write(TextureSaturationCenti); } public void ReadData(IPacket packet) { //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) PlayerId = packet.ReadUShort(); byte b = packet.ReadByte(); byte b2 = packet.ReadByte(); byte b3 = packet.ReadByte(); Color = new CloakColor(b, b2, b3); TextureSaturationCenti = packet.ReadByte(); } } internal class UsernameColorPacket : IPacketData { public ushort PlayerId; public CloakColor Color; public bool HasCustomUsernameTint; public bool IsReliable => true; public bool DropReliableDataIfNewerExists => true; public void WriteData(IPacket packet) { packet.Write(PlayerId); packet.Write(((CloakColor)(ref Color)).R); packet.Write(((CloakColor)(ref Color)).G); packet.Write(((CloakColor)(ref Color)).B); packet.Write(HasCustomUsernameTint); } public void ReadData(IPacket packet) { //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) PlayerId = packet.ReadUShort(); byte b = packet.ReadByte(); byte b2 = packet.ReadByte(); byte b3 = packet.ReadByte(); Color = new CloakColor(b, b2, b3); HasCustomUsernameTint = packet.ReadBool(); } } internal class ServerUsernameColorRulesPacket : IPacketData { public bool CustomUsernameColorsOverrideTeamColors; public bool IsReliable => true; public bool DropReliableDataIfNewerExists => true; public void WriteData(IPacket packet) { packet.Write(CustomUsernameColorsOverrideTeamColors); } public void ReadData(IPacket packet) { CustomUsernameColorsOverrideTeamColors = packet.ReadBool(); } } internal static class ServerAddonReceivePacketFactory { public static IPacketData Instantiate(PacketId id) { return (IPacketData)(id switch { PacketId.CloakColorUpdate => new CloakColorPacket(), PacketId.UsernameColorUpdate => new UsernameColorPacket(), PacketId.ServerUsernameColorRules => new ServerUsernameColorRulesPacket(), _ => new CloakColorPacket(), }); } } internal static class ClientAddonReceivePacketFactory { public static IPacketData Instantiate(PacketId id) { return (IPacketData)(id switch { PacketId.CloakColorUpdate => new PacketDataCollection(), PacketId.UsernameColorUpdate => new PacketDataCollection(), PacketId.ServerUsernameColorRules => new ServerUsernameColorRulesPacket(), _ => new PacketDataCollection(), }); } } } namespace HornetCloakColor.Server { internal sealed class PlayerCosmeticsTracker { private readonly Dictionary _cloaks = new Dictionary(); private readonly Dictionary _usernameTints = new Dictionary(); internal IReadOnlyDictionary Cloaks => _cloaks; internal IReadOnlyDictionary UsernameTints => _usernameTints; internal void SetCloak(ushort playerId, CloakNetAppearance appearance) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) _cloaks[playerId] = appearance; } internal void SetUsernameTint(ushort playerId, bool hasCustomTint, CloakColor color) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) if (!hasCustomTint) { _usernameTints.Remove(playerId); } else { _usernameTints[playerId] = color; } } internal void RemovePlayer(ushort playerId) { _cloaks.Remove(playerId); _usernameTints.Remove(playerId); } } internal class ServerAddon : ServerAddon { private readonly PlayerCosmeticsTracker _tracker = new PlayerCosmeticsTracker(); private readonly bool _customUsernameColorsOverrideTeamColors = ServerUsernameRulesStore.LoadCustomUsernameColorsOverrideTeamColors(); private readonly HashSet _sceneCatchUpSent = new HashSet(); private IServerApi? _api; protected override string Name => "HornetCloakColor"; protected override string Version => "1.15.0"; public override uint ApiVersion => 1u; public override bool NeedsNetwork => true; public override void Initialize(IServerApi serverApi) { _api = serverApi; ServerCosmeticsPacketSender.Init(serverApi.NetServer.GetNetworkSender((ServerAddon)(object)this)); IServerAddonNetworkReceiver networkReceiver = serverApi.NetServer.GetNetworkReceiver((ServerAddon)(object)this, (Func)ServerAddonReceivePacketFactory.Instantiate); networkReceiver.RegisterPacketHandler(PacketId.CloakColorUpdate, (GenericServerPacketHandler)OnCloakColorUpdate); networkReceiver.RegisterPacketHandler(PacketId.UsernameColorUpdate, (GenericServerPacketHandler)OnUsernameColorUpdate); serverApi.ServerManager.PlayerConnectEvent += OnPlayerConnect; serverApi.ServerManager.PlayerEnterSceneEvent += OnPlayerEnterSceneFirstCatchUp; serverApi.ServerManager.PlayerDisconnectEvent += OnPlayerDisconnect; Log.Info(_customUsernameColorsOverrideTeamColors ? "Server addon initialized (custom username colors may override team colors)." : "Server addon initialized (team colors take precedence over custom username colors when teams are used)."); } private void OnPlayerConnect(IServerPlayer player) { PushJoinSnapshotTo(player, "PlayerConnect"); } private void OnPlayerEnterSceneFirstCatchUp(IServerPlayer player) { if (_sceneCatchUpSent.Add(player.Id)) { PushJoinSnapshotTo(player, "first scene catch-up"); } } private void PushJoinSnapshotTo(IServerPlayer player, string reason) { ServerCosmeticsPacketSender.SendUsernameRulesTo(player.Id, _customUsernameColorsOverrideTeamColors); ServerCosmeticsPacketSender.SendAllOtherPlayersCloaksTo(player.Id, _tracker); ServerCosmeticsPacketSender.SendAllOtherPlayersUsernameTintsTo(player.Id, _tracker); Log.Info($"Cosmetics snapshot ({reason}) → player {player.Id} (rules + others' cloak/username)."); } private void OnPlayerDisconnect(IServerPlayer player) { _tracker.RemovePlayer(player.Id); _sceneCatchUpSent.Remove(player.Id); } private void OnCloakColorUpdate(ushort senderId, CloakColorPacket data) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_001a: 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) CloakNetAppearance appearance = default(CloakNetAppearance); ((CloakNetAppearance)(ref appearance))..ctor(data.Color, data.TextureSaturationCenti); _tracker.SetCloak(senderId, appearance); if (_api != null) { ServerCosmeticsPacketSender.BroadcastCloakToOthers(senderId, appearance, _api.ServerManager.Players); } } private void OnUsernameColorUpdate(ushort senderId, UsernameColorPacket data) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) _tracker.SetUsernameTint(senderId, data.HasCustomUsernameTint, data.Color); if (_api != null) { ServerCosmeticsPacketSender.BroadcastUsernameTintToOthers(senderId, data.Color, data.HasCustomUsernameTint, _api.ServerManager.Players); } } } internal static class ServerCosmeticsPacketSender { private static IServerAddonNetworkSender? _sender; internal static void Init(IServerAddonNetworkSender sender) { _sender = sender; } internal static void SendUsernameRulesTo(ushort recipientId, bool customUsernameColorsOverrideTeamColors) { if (_sender != null) { _sender.SendSingleData(PacketId.ServerUsernameColorRules, (IPacketData)(object)new ServerUsernameColorRulesPacket { CustomUsernameColorsOverrideTeamColors = customUsernameColorsOverrideTeamColors }, recipientId); } } internal static void SendAllOtherPlayersCloaksTo(ushort recipientId, PlayerCosmeticsTracker tracker) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) if (_sender == null) { return; } foreach (KeyValuePair cloak in tracker.Cloaks) { if (cloak.Key != recipientId) { IServerAddonNetworkSender? sender = _sender; CloakColorPacket obj = new CloakColorPacket { PlayerId = cloak.Key }; CloakNetAppearance value = cloak.Value; obj.Color = ((CloakNetAppearance)(ref value)).Color; value = cloak.Value; obj.TextureSaturationCenti = ((CloakNetAppearance)(ref value)).TextureSaturationCenti; sender.SendCollectionData(PacketId.CloakColorUpdate, obj, recipientId); } } } internal static void SendAllOtherPlayersUsernameTintsTo(ushort recipientId, PlayerCosmeticsTracker tracker) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) if (_sender == null) { return; } foreach (KeyValuePair usernameTint in tracker.UsernameTints) { if (usernameTint.Key != recipientId) { _sender.SendCollectionData(PacketId.UsernameColorUpdate, new UsernameColorPacket { PlayerId = usernameTint.Key, Color = usernameTint.Value, HasCustomUsernameTint = true }, recipientId); } } } internal static void BroadcastCloakToOthers(ushort senderId, CloakNetAppearance appearance, IReadOnlyCollection players) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) if (_sender == null) { return; } foreach (IServerPlayer player in players) { if (player.Id != senderId) { _sender.SendCollectionData(PacketId.CloakColorUpdate, new CloakColorPacket { PlayerId = senderId, Color = ((CloakNetAppearance)(ref appearance)).Color, TextureSaturationCenti = ((CloakNetAppearance)(ref appearance)).TextureSaturationCenti }, player.Id); } } } internal static void BroadcastUsernameTintToOthers(ushort senderId, CloakColor color, bool hasCustomUsernameTint, IReadOnlyCollection players) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) if (_sender == null) { return; } foreach (IServerPlayer player in players) { if (player.Id != senderId) { _sender.SendCollectionData(PacketId.UsernameColorUpdate, new UsernameColorPacket { PlayerId = senderId, Color = color, HasCustomUsernameTint = hasCustomUsernameTint }, player.Id); } } } } internal static class ServerUsernameRulesStore { private const string FileName = "HornetCloakColor.server.json"; internal static bool LoadCustomUsernameColorsOverrideTeamColors() { try { string directoryName = Path.GetDirectoryName(typeof(ServerAddon).Assembly.Location); if (string.IsNullOrEmpty(directoryName)) { return false; } string path = Path.Combine(directoryName, "HornetCloakColor.server.json"); if (!File.Exists(path)) { return false; } Match match = Regex.Match(File.ReadAllText(path), "\"customUsernameColorsOverrideTeamColors\"\\s*:\\s*(true|false)", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant); return match.Success && string.Equals(match.Groups[1].Value, "true", StringComparison.OrdinalIgnoreCase); } catch { return false; } } } } namespace HornetCloakColor.Client { internal class ClientAddon : ClientAddon { private const string UsernameObjectName = "Username"; private readonly Dictionary _playerCloakAppearances = new Dictionary(); private readonly Dictionary _playerUsernameColors = new Dictionary(); private IClientApi? _api; private CloakNetAppearance _localCloakAppearance = CloakNetAppearance.Default; private CloakColor _localUsernameColor = CloakColor.Default; private bool _localUsernameHasCustomTint; private bool _serverCustomUsernameOverridesTeam; protected override string Name => "HornetCloakColor"; protected override string Version => "1.15.0"; public override uint ApiVersion => 1u; public override bool NeedsNetwork => true; internal static ClientAddon? Instance { get; private set; } public override void Initialize(IClientApi clientApi) { Instance = this; _api = clientApi; IClientAddonNetworkSender networkSender = clientApi.NetClient.GetNetworkSender((ClientAddon)(object)this); ClientCosmeticsPacketSender.Init(clientApi, networkSender); IClientAddonNetworkReceiver networkReceiver = clientApi.NetClient.GetNetworkReceiver((ClientAddon)(object)this, (Func)ClientAddonReceivePacketFactory.Instantiate); networkReceiver.RegisterPacketHandler(PacketId.CloakColorUpdate, (GenericClientPacketHandler)OnCloakColorUpdate); networkReceiver.RegisterPacketHandler(PacketId.UsernameColorUpdate, (GenericClientPacketHandler)OnUsernameColorUpdate); networkReceiver.RegisterPacketHandler(PacketId.ServerUsernameColorRules, (GenericClientPacketHandler)OnServerUsernameColorRules); clientApi.ClientManager.ConnectEvent += OnConnected; clientApi.ClientManager.DisconnectEvent += OnDisconnected; clientApi.ClientManager.PlayerEnterSceneEvent += OnPlayerEnterScene; clientApi.ClientManager.PlayerDisconnectEvent += OnPlayerDisconnect; PushUsernameDelegates(); Log.Info("Client addon initialized."); } private void PushUsernameDelegates() { UsernameNetworkDelegates.TryResolveUsernameTransform = TryResolveUsernameTransform; UsernameNetworkDelegates.GetRemoteUsernameTintOrNull = GetRemoteUsernameTintOrNull; UsernameNetworkDelegates.GetTeamsEnabled = () => _api.ClientManager.ServerSettings.TeamsEnabled; UsernameNetworkDelegates.GetServerCustomUsernameOverridesTeam = () => _serverCustomUsernameOverridesTeam; UsernameNetworkDelegates.GetLocalPlayerTeamOrdinal = () => (int)_api.ClientManager.PlayerManager.LocalPlayerTeam; } public void SetLocalCloakAppearance(CloakNetAppearance appearance) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: 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) _localCloakAppearance = appearance; ClientCosmeticsPacketSender.TrySendCloakUpdate(_localCloakAppearance); } public void SetLocalUsernameTint(bool hasCustomUsernameTint, CloakColor color) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) _localUsernameHasCustomTint = hasCustomUsernameTint; _localUsernameColor = color; ClientCosmeticsPacketSender.TrySendUsernameUpdate(_localUsernameHasCustomTint, _localUsernameColor); } internal CloakColor GetRemoteMapColorOrDefault(ushort playerId) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) if (!_playerCloakAppearances.TryGetValue(playerId, out var value)) { return CloakColor.Default; } return ((CloakNetAppearance)(ref value)).Color; } internal CloakColor? GetRemoteUsernameTintOrNull(ushort playerId) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) if (!_playerUsernameColors.TryGetValue(playerId, out var value)) { return null; } return value; } private UsernameResolveResult TryResolveUsernameTransform(Transform t) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: 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) if ((Object)(object)t == (Object)null) { return default(UsernameResolveResult); } if ((Object)(object)HeroController.instance != (Object)null && t.IsChildOf(HeroController.instance.transform)) { if (TryGetLocalNetworkPlayerId(out var id)) { return new UsernameResolveResult(true, true, id); } return new UsernameResolveResult(true, true, (ushort)0); } if (TryResolveRemoteByPlayerContainerAncestor(t, out var playerId)) { return new UsernameResolveResult(true, false, playerId); } if (_api == null) { return default(UsernameResolveResult); } foreach (IClientPlayer player in _api.ClientManager.Players) { if (!((Object)(object)player.PlayerContainer == (Object)null) && t.IsChildOf(player.PlayerContainer.transform)) { return new UsernameResolveResult(true, false, player.Id); } } return default(UsernameResolveResult); } private static bool TryResolveRemoteByPlayerContainerAncestor(Transform t, out ushort playerId) { playerId = 0; Transform val = t; while ((Object)(object)val != (Object)null) { string name = ((Object)val).name; if (name.StartsWith("Player Container ", StringComparison.Ordinal)) { return ushort.TryParse(name.Substring("Player Container ".Length), NumberStyles.Integer, CultureInfo.InvariantCulture, out playerId); } val = val.parent; } return false; } private bool TryGetLocalNetworkPlayerId(out ushort id) { id = 0; if (_api == null || (Object)(object)HeroController.instance == (Object)null) { return false; } foreach (IClientPlayer player in _api.ClientManager.Players) { if ((Object)(object)player.PlayerObject != (Object)null && player.PlayerObject == ((Component)HeroController.instance).gameObject) { id = player.Id; return true; } } return false; } internal void ForceResendLocalColorsToServer() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) ClientCosmeticsPacketSender.TrySendStoredLocal(_localCloakAppearance, _localUsernameHasCustomTint, _localUsernameColor); } private void OnConnected() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) PushUsernameDelegates(); ClientCosmeticsPacketSender.TrySendStoredLocal(_localCloakAppearance, _localUsernameHasCustomTint, _localUsernameColor); SSMPBridge.SchedulePostConnectColorResend(); } private void OnDisconnected() { UsernameNetworkDelegates.Clear(); _playerUsernameColors.Clear(); _serverCustomUsernameOverridesTeam = false; } private void OnPlayerEnterScene(IClientPlayer player) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) if (_playerCloakAppearances.TryGetValue(player.Id, out var value) && (Object)(object)player.PlayerObject != (Object)null) { CloakColorApplier.Apply(player.PlayerObject, ((CloakNetAppearance)(ref value)).Color, (float?)((CloakNetAppearance)(ref value)).TextureSaturationMultiplier); if (!IsLocalHeroPlayer(player)) { MpRemoteCloakReapply.Schedule(player.PlayerObject, value); } } if (!IsLocalHeroPlayer(player)) { RefreshRemoteUsernameVisual(player.Id); } } private static bool IsLocalHeroPlayer(IClientPlayer player) { HeroController instance = HeroController.instance; if ((Object)(object)instance != (Object)null && (Object)(object)player.PlayerObject != (Object)null) { return player.PlayerObject == ((Component)instance).gameObject; } return false; } private void OnPlayerDisconnect(IClientPlayer player) { _playerCloakAppearances.Remove(player.Id); _playerUsernameColors.Remove(player.Id); } private void OnCloakColorUpdate(CloakColorPacket data) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) CloakNetAppearance val = default(CloakNetAppearance); ((CloakNetAppearance)(ref val))..ctor(data.Color, data.TextureSaturationCenti); _playerCloakAppearances[data.PlayerId] = val; PlayerMapMaskTintRegistry.SetColor(data.PlayerId, ((CloakNetAppearance)(ref val)).Color); IClientApi? api = _api; IClientPlayer val2 = ((api != null) ? api.ClientManager.GetPlayer(data.PlayerId) : null); if ((Object)(object)((val2 != null) ? val2.PlayerObject : null) != (Object)null) { CloakColorApplier.Apply(val2.PlayerObject, ((CloakNetAppearance)(ref val)).Color, (float?)((CloakNetAppearance)(ref val)).TextureSaturationMultiplier); MpRemoteCloakReapply.Schedule(val2.PlayerObject, val); } } private void OnServerUsernameColorRules(ServerUsernameColorRulesPacket data) { _serverCustomUsernameOverridesTeam = data.CustomUsernameColorsOverrideTeamColors; } private void OnUsernameColorUpdate(UsernameColorPacket data) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) if (!data.HasCustomUsernameTint) { _playerUsernameColors.Remove(data.PlayerId); } else { _playerUsernameColors[data.PlayerId] = data.Color; } RefreshRemoteUsernameVisual(data.PlayerId); } private void RefreshRemoteUsernameVisual(ushort playerId) { //IL_005c: 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) //IL_0081: Expected I4, but got Unknown IClientPlayer val = default(IClientPlayer); if (_api == null || !_api.ClientManager.TryGetPlayer(playerId, ref val) || val == null) { return; } GameObject playerContainer = val.PlayerContainer; if ((Object)(object)playerContainer == (Object)null) { return; } GameObject val2 = FindDeepChildByName(playerContainer, "Username"); if ((Object)(object)val2 == (Object)null) { return; } Component val3 = UsernameTmpCompat.FindOnGameObject(val2); if (!((Object)(object)val3 == (Object)null)) { SsmpUsernameVanillaColors.ApplyTeamColor(val3, val.Team); if (_playerUsernameColors.ContainsKey(playerId)) { UsernameTintCoordinator.ApplyRemoteUsernameAfterSync(val3, playerId, (int)val.Team); } } } private static GameObject? FindDeepChildByName(GameObject root, string name) { Transform[] componentsInChildren = root.GetComponentsInChildren(true); foreach (Transform val in componentsInChildren) { if (((Object)val).name == name) { return ((Component)val).gameObject; } } return null; } } internal static class ClientCosmeticsPacketSender { private static IClientApi? _api; private static IClientAddonNetworkSender? _sender; internal static void Init(IClientApi api, IClientAddonNetworkSender sender) { _api = api; _sender = sender; } internal static void TrySendCloakUpdate(CloakNetAppearance appearance) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) if (_api == null || _sender == null || !_api.NetClient.IsConnected) { return; } try { _sender.SendSingleData(PacketId.CloakColorUpdate, (IPacketData)(object)new CloakColorPacket { PlayerId = 0, Color = ((CloakNetAppearance)(ref appearance)).Color, TextureSaturationCenti = ((CloakNetAppearance)(ref appearance)).TextureSaturationCenti }); } catch (Exception ex) { Log.Warn("HornetCloakColor: failed to send cloak color to server (" + ex.GetType().Name + ": " + ex.Message + ")."); } } internal static void TrySendUsernameUpdate(bool hasCustomUsernameTint, CloakColor color) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) if (_api == null || _sender == null || !_api.NetClient.IsConnected) { return; } try { _sender.SendSingleData(PacketId.UsernameColorUpdate, (IPacketData)(object)new UsernameColorPacket { PlayerId = 0, Color = color, HasCustomUsernameTint = hasCustomUsernameTint }); } catch (Exception ex) { Log.Warn("HornetCloakColor: failed to send username tint to server (" + ex.GetType().Name + ": " + ex.Message + ")."); } } internal static void TrySendStoredLocal(CloakNetAppearance cloak, bool hasCustomUsernameTint, CloakColor usernameColor) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) TrySendCloakUpdate(cloak); TrySendUsernameUpdate(hasCustomUsernameTint, usernameColor); } } internal static class SsmpUsernameVanillaColors { internal static void ApplyTeamColor(Component? textMeshObject, Team team) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected I4, but got Unknown //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_007a: 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) Color white = default(Color); switch (team - 1) { case 0: ((Color)(ref white))..ctor(0f, 0.5882353f, 0f); break; case 1: ((Color)(ref white))..ctor(40f / 51f, 0.5882353f, 0f); break; case 2: ((Color)(ref white))..ctor(50f / 51f, 10f / 51f, 10f / 51f); break; case 3: ((Color)(ref white))..ctor(10f / 51f, 0.5882353f, 40f / 51f); break; default: white = Color.white; break; } UsernameTmpCompat.SetColor(textMeshObject, white); } } }