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 System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using PastaClient.Patches;
using TMPro;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Networking;
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: IgnoresAccessChecksTo("0Harmony")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: IgnoresAccessChecksTo("BepInEx")]
[assembly: IgnoresAccessChecksTo("BepInEx.Harmony")]
[assembly: IgnoresAccessChecksTo("LethalConfig")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.TextMeshPro")]
[assembly: IgnoresAccessChecksTo("UnityEngine.IMGUIModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UI")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("PastaClient")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("made by Asta")]
[assembly: AssemblyFileVersion("1.2.1.0")]
[assembly: AssemblyInformationalVersion("1.2.1+8ac91082f94a2d3dda6e6ee3d9e2dde8fa02fc8c")]
[assembly: AssemblyProduct("PastaClient")]
[assembly: AssemblyTitle("PastaClient")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.2.1.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 PastaClient
{
public static class ConfigManager
{
public static ConfigEntry<bool> EnableAutoKick;
public static ConfigEntry<int> VoteKickThreshold;
public static ConfigEntry<bool> EnableShitterUIOnKick;
public static ConfigEntry<string> ServerUrl;
public static void Init(ConfigFile cfg)
{
EnableAutoKick = cfg.Bind<bool>("General", "EnableAutoKick", true, "자동킥 활성화");
VoteKickThreshold = cfg.Bind<int>("General", "VoteKickThreshold", 2, "자동킥 받을 투표 수");
EnableShitterUIOnKick = cfg.Bind<bool>("General", "EnableShitterUIOnKick", true, "킥당했을 때 UI 띄우기");
ServerUrl = cfg.Bind<string>("Server", "ServerUrl", "https://shitter.asta.rs", "서버 URL");
}
}
public class PastaNetwork : NetworkBehaviour
{
private static HashSet<ulong> _previousClients = new HashSet<ulong>();
private static HashSet<ulong> _processedConnects = new HashSet<ulong>();
private static HashSet<ulong> _processedDisconnects = new HashSet<ulong>();
public static PastaNetwork Instance { get; private set; } = null;
public static void Init()
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Expected O, but got Unknown
GameObject val = new GameObject("PastaNetwork");
Instance = val.AddComponent<PastaNetwork>();
Object.DontDestroyOnLoad((Object)(object)val);
((Object)val).hideFlags = (HideFlags)61;
SteamNameFetcher.Init((MonoBehaviour)(object)Instance);
ServerClient.Init((MonoBehaviour)(object)Instance);
}
private void Start()
{
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogInfo((object)"[PastaNetwork] Start() called");
}
((MonoBehaviour)Instance).StartCoroutine(RegisterNetworkCallbacks());
((MonoBehaviour)Instance).StartCoroutine(MonitorPlayerChanges());
}
private IEnumerator RegisterNetworkCallbacks()
{
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogInfo((object)"[PastaNetwork] Waiting for NetworkManager to initialize...");
}
float timeout = 10f;
float elapsed = 0f;
while ((Object)(object)NetworkManager.Singleton == (Object)null && elapsed < timeout)
{
yield return (object)new WaitForSeconds(0.1f);
elapsed += 0.1f;
}
if ((Object)(object)NetworkManager.Singleton == (Object)null)
{
ManualLogSource log2 = Plugin.Log;
if (log2 != null)
{
log2.LogWarning((object)"[PastaNetwork] NetworkManager not found after timeout! Will monitor manually.");
}
yield break;
}
ManualLogSource log3 = Plugin.Log;
if (log3 != null)
{
log3.LogInfo((object)"[PastaNetwork] NetworkManager found! Registering callbacks...");
}
try
{
NetworkManager.Singleton.OnClientConnectedCallback += OnClientConnected;
NetworkManager.Singleton.OnClientDisconnectCallback += OnClientDisconnected;
ManualLogSource log4 = Plugin.Log;
if (log4 != null)
{
log4.LogInfo((object)"[PastaNetwork] Callbacks registered successfully!");
}
}
catch (Exception ex)
{
ManualLogSource log5 = Plugin.Log;
if (log5 != null)
{
log5.LogError((object)$"[PastaNetwork] Failed to register callbacks: {ex}");
}
}
}
private IEnumerator MonitorPlayerChanges()
{
yield return (object)new WaitForSeconds(2f);
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogInfo((object)"[PastaNetwork] 백업 플레이어 모니터링 시작... (서버/클라이언트 모두 지원)");
}
if ((Object)(object)NetworkManager.Singleton != (Object)null && !NetworkManager.Singleton.IsServer)
{
ManualLogSource log2 = Plugin.Log;
if (log2 != null)
{
log2.LogInfo((object)"[PastaNetwork] 클라이언트 모드: 이미 있는 플레이어들 초기 수집 중...");
}
HashSet<ulong> initialPlayers = new HashSet<ulong>();
for (int attempt = 0; attempt < 5; attempt++)
{
yield return (object)new WaitForSeconds(1f);
try
{
PlayerControllerB[] allPlayers = Object.FindObjectsByType<PlayerControllerB>((FindObjectsSortMode)0);
ManualLogSource log3 = Plugin.Log;
if (log3 != null)
{
log3.LogInfo((object)$"[PastaNetwork] 초기 수집 시도 {attempt + 1}/5: PlayerControllerB {((allPlayers != null) ? allPlayers.Length : 0)}개 발견");
}
if (allPlayers != null)
{
PlayerControllerB[] array = allPlayers;
foreach (PlayerControllerB player in array)
{
if (!((Object)(object)player != (Object)null) || player.actualClientId == 0)
{
continue;
}
ulong steamId = SteamIDHelper.GetSteamID(player.actualClientId);
if (steamId != 0L && steamId != player.actualClientId)
{
initialPlayers.Add(steamId);
ManualLogSource log4 = Plugin.Log;
if (log4 != null)
{
log4.LogInfo((object)$"[PastaNetwork] 초기 발견된 플레이어: clientId={player.actualClientId}, steamId={steamId}");
}
}
else if (steamId > 76561190000000000L && steamId < 76561199999999999L)
{
initialPlayers.Add(steamId);
ManualLogSource log5 = Plugin.Log;
if (log5 != null)
{
log5.LogInfo((object)$"[PastaNetwork] 초기 발견된 플레이어 (Steam ID 형식): {steamId}");
}
}
}
}
if (attempt >= 2 && initialPlayers.Count > 0)
{
ManualLogSource log6 = Plugin.Log;
if (log6 != null)
{
log6.LogInfo((object)$"[PastaNetwork] 플레이어 수집 완료 (시도 {attempt + 1}): {initialPlayers.Count}명");
}
break;
}
continue;
}
catch (Exception ex)
{
ManualLogSource log7 = Plugin.Log;
if (log7 != null)
{
log7.LogError((object)$"[PastaNetwork] 초기 플레이어 수집 실패 (시도 {attempt + 1}): {ex.Message}");
}
continue;
}
}
if (initialPlayers.Count > 0)
{
ManualLogSource log8 = Plugin.Log;
if (log8 != null)
{
log8.LogInfo((object)$"[PastaNetwork] 총 초기 플레이어 {initialPlayers.Count}명 발견! KickTracker에 저장 중...");
}
KickTracker.SetCurrentPlayers(initialPlayers);
foreach (ulong playerId in initialPlayers)
{
if (playerId != 0)
{
((MonoBehaviour)Instance).StartCoroutine(CachePlayerNameDelayed(playerId));
}
}
}
else
{
ManualLogSource log9 = Plugin.Log;
if (log9 != null)
{
log9.LogWarning((object)"[PastaNetwork] 초기 플레이어를 찾지 못했습니다.");
}
}
}
while (true)
{
yield return (object)new WaitForSeconds(0.5f);
if ((Object)(object)NetworkManager.Singleton == (Object)null)
{
continue;
}
HashSet<ulong> currentClients = new HashSet<ulong>();
if (NetworkManager.Singleton.IsServer)
{
try
{
foreach (KeyValuePair<ulong, NetworkClient> kvp in NetworkManager.Singleton.ConnectedClients)
{
currentClients.Add(kvp.Key);
}
}
catch (Exception ex4)
{
Exception ex2 = ex4;
ManualLogSource log10 = Plugin.Log;
if (log10 != null)
{
log10.LogWarning((object)("[PastaNetwork] ConnectedClients 접근 오류: " + ex2.Message));
}
}
}
try
{
PlayerControllerB[] allPlayers2 = Object.FindObjectsByType<PlayerControllerB>((FindObjectsSortMode)0);
PlayerControllerB[] array2 = allPlayers2;
foreach (PlayerControllerB player2 in array2)
{
if ((Object)(object)player2 != (Object)null && player2.actualClientId != 0)
{
ulong steamId2 = SteamIDHelper.GetSteamID(player2.actualClientId);
if (steamId2 != 0)
{
currentClients.Add(steamId2);
}
}
}
}
catch (Exception ex3)
{
ManualLogSource log11 = Plugin.Log;
if (log11 != null)
{
log11.LogWarning((object)("[PastaNetwork] PlayerControllerB 찾기 오류: " + ex3.Message));
}
}
foreach (ulong clientId2 in _previousClients)
{
if (!currentClients.Contains(clientId2) && !_processedDisconnects.Contains(clientId2))
{
_processedDisconnects.Add(clientId2);
OnClientDisconnected(clientId2);
}
}
foreach (ulong clientId in currentClients)
{
if (_previousClients.Contains(clientId) || _processedConnects.Contains(clientId) || clientId == 0)
{
continue;
}
_processedConnects.Add(clientId);
ulong actualClientId = clientId;
if (clientId > 76561190000000000L && clientId < 76561199999999999L && (Object)(object)NetworkManager.Singleton != (Object)null && NetworkManager.Singleton.IsServer)
{
foreach (KeyValuePair<ulong, NetworkClient> connectedClient in NetworkManager.Singleton.ConnectedClients)
{
ulong connectedClientId = connectedClient.Key;
ulong connectedSteamId = SteamIDHelper.GetSteamID(connectedClientId);
if (connectedSteamId == clientId)
{
actualClientId = connectedClientId;
break;
}
}
}
OnClientConnected(actualClientId);
}
_processedDisconnects.RemoveWhere((ulong id) => !_previousClients.Contains(id));
_processedConnects.RemoveWhere((ulong id) => !currentClients.Contains(id));
_previousClients = currentClients;
}
}
private static void OnClientConnected(ulong clientId)
{
((MonoBehaviour)Instance).StartCoroutine(CachePlayerNameDelayed(clientId));
if ((Object)(object)NetworkManager.Singleton != (Object)null && NetworkManager.Singleton.IsServer && (Object)(object)Instance != (Object)null && ((NetworkBehaviour)Instance).IsSpawned)
{
((MonoBehaviour)Instance).StartCoroutine(SendPlayerListToClient(clientId));
}
if ((Object)(object)NetworkManager.Singleton != (Object)null && !NetworkManager.Singleton.IsServer && clientId == NetworkManager.Singleton.LocalClientId)
{
((MonoBehaviour)Instance).StartCoroutine(CollectExistingPlayers());
}
if (!((Object)(object)NetworkManager.Singleton == (Object)null) && NetworkManager.Singleton.IsHost)
{
((MonoBehaviour)Instance).StartCoroutine(CheckAndKickPlayerDelayed(clientId));
}
}
private static IEnumerator CollectExistingPlayers()
{
for (int attempt = 0; attempt < 5; attempt++)
{
yield return (object)new WaitForSeconds(1f);
if ((Object)(object)NetworkManager.Singleton == (Object)null || NetworkManager.Singleton.IsServer)
{
yield break;
}
List<ulong> playerIds = new List<ulong>();
try
{
PlayerControllerB[] allPlayers = Object.FindObjectsByType<PlayerControllerB>((FindObjectsSortMode)0);
PlayerControllerB[] array = (PlayerControllerB[])(((object)allPlayers) ?? ((object)new PlayerControllerB[0]));
foreach (PlayerControllerB player in array)
{
if ((Object)(object)player != (Object)null && player.actualClientId != 0)
{
ulong steamId = SteamIDHelper.GetSteamID(player.actualClientId);
if (steamId != 0)
{
playerIds.Add(steamId);
}
}
}
if (playerIds.Count <= 0)
{
continue;
}
KickTracker.SetCurrentPlayers(playerIds);
foreach (ulong playerId in playerIds)
{
if (playerId != 0)
{
((MonoBehaviour)Instance).StartCoroutine(CachePlayerNameDelayed(playerId));
}
}
yield break;
}
catch (Exception ex)
{
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogError((object)$"[PastaNetwork] 플레이어 수집 실패 (시도 {attempt + 1}): {ex.Message}");
}
}
}
ManualLogSource log2 = Plugin.Log;
if (log2 != null)
{
log2.LogWarning((object)"[PastaNetwork] 모든 시도 후에도 플레이어를 찾지 못했습니다.");
}
}
private static IEnumerator SendPlayerListToClient(ulong clientId)
{
yield return (object)new WaitForSeconds(1f);
if ((Object)(object)NetworkManager.Singleton == (Object)null || !NetworkManager.Singleton.IsServer || (Object)(object)Instance == (Object)null || !((NetworkBehaviour)Instance).IsSpawned)
{
yield break;
}
List<ulong> playerIds = new List<ulong>();
try
{
foreach (KeyValuePair<ulong, NetworkClient> connectedClient in NetworkManager.Singleton.ConnectedClients)
{
ulong connectedClientId = connectedClient.Key;
ulong steamId = SteamIDHelper.GetSteamID(connectedClientId);
if (steamId != 0)
{
playerIds.Add(steamId);
}
}
ClientRpcParams clientRpcParams = new ClientRpcParams
{
Send = new ClientRpcSendParams
{
TargetClientIds = new ulong[1] { clientId }
}
};
Instance.SendPlayerListClientRpc(playerIds.ToArray(), clientRpcParams);
}
catch (Exception ex)
{
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogError((object)("[PastaNetwork] 플레이어 목록 전송 실패: " + ex.Message));
}
}
}
private static IEnumerator CachePlayerNameDelayed(ulong clientId)
{
yield return (object)new WaitForSeconds(1f);
string playerName = GetPlayerName(clientId);
if (!string.IsNullOrEmpty(playerName) && playerName != "Unknown")
{
RecentLeaveTracker.CachePlayerName(clientId, playerName);
}
}
private static string GetPlayerName(ulong clientId)
{
if ((Object)(object)NetworkManager.Singleton == (Object)null)
{
return "Unknown";
}
if (NetworkManager.Singleton.IsServer && NetworkManager.Singleton.ConnectedClients.TryGetValue(clientId, out var value) && (Object)(object)value.PlayerObject != (Object)null)
{
string name = ((Object)value.PlayerObject).name;
if (!string.IsNullOrEmpty(name) && !IsDefaultPlayerName(name))
{
return name;
}
}
PlayerControllerB[] array = Object.FindObjectsByType<PlayerControllerB>((FindObjectsSortMode)0);
PlayerControllerB[] array2 = array;
foreach (PlayerControllerB val in array2)
{
if (!((Object)(object)val != (Object)null) || val.actualClientId != clientId)
{
continue;
}
FieldInfo field = typeof(PlayerControllerB).GetField("playerUsername", BindingFlags.Instance | BindingFlags.Public);
if (field != null)
{
string text = field.GetValue(val) as string;
if (!string.IsNullOrEmpty(text))
{
return text;
}
}
if (!string.IsNullOrEmpty(((Object)val).name) && !IsDefaultPlayerName(((Object)val).name))
{
return ((Object)val).name;
}
}
return "Unknown";
}
private static void SendChatMessage(string message)
{
if ((Object)(object)HUDManager.Instance == (Object)null)
{
return;
}
try
{
MethodInfo[] methods = typeof(HUDManager).GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
MethodInfo[] array = methods;
foreach (MethodInfo methodInfo in array)
{
string text = methodInfo.Name.ToLower();
if ((!text.Contains("chat") && !text.Contains("message")) || (!text.Contains("add") && !text.Contains("send")))
{
continue;
}
try
{
ParameterInfo[] parameters = methodInfo.GetParameters();
if (parameters.Length == 1 && parameters[0].ParameterType == typeof(string))
{
methodInfo.Invoke(HUDManager.Instance, new object[1] { message });
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogInfo((object)("[PastaNetwork] 채팅 메시지 전송 성공: " + methodInfo.Name));
}
return;
}
if (parameters.Length == 2 && parameters[0].ParameterType == typeof(string))
{
methodInfo.Invoke(HUDManager.Instance, new object[2] { message, "" });
ManualLogSource log2 = Plugin.Log;
if (log2 != null)
{
log2.LogInfo((object)("[PastaNetwork] 채팅 메시지 전송 성공: " + methodInfo.Name));
}
return;
}
}
catch
{
}
}
FieldInfo[] fields = typeof(HUDManager).GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
FieldInfo[] array2 = fields;
foreach (FieldInfo fieldInfo in array2)
{
string text2 = fieldInfo.Name.ToLower();
if (!text2.Contains("chat") || (!text2.Contains("text") && !text2.Contains("log")))
{
continue;
}
try
{
object value = fieldInfo.GetValue(HUDManager.Instance);
if (value == null)
{
continue;
}
PropertyInfo property = value.GetType().GetProperty("text");
if (property != null)
{
string text3 = (property.GetValue(value) as string) ?? "";
property.SetValue(value, text3 + "\n" + message);
ManualLogSource log3 = Plugin.Log;
if (log3 != null)
{
log3.LogInfo((object)("[PastaNetwork] 채팅 메시지 전송 성공 (필드): " + fieldInfo.Name));
}
return;
}
}
catch
{
}
}
ManualLogSource log4 = Plugin.Log;
if (log4 != null)
{
log4.LogWarning((object)"[PastaNetwork] 채팅 메시지 전송 방법을 찾지 못했습니다.");
}
}
catch (Exception arg)
{
ManualLogSource log5 = Plugin.Log;
if (log5 != null)
{
log5.LogError((object)$"[PastaNetwork] 채팅 메시지 전송 오류: {arg}");
}
}
}
private static bool IsDefaultPlayerName(string name)
{
if (string.IsNullOrEmpty(name))
{
return true;
}
string text = name.ToLower().Trim();
if (text.StartsWith("player"))
{
string text2 = text.Substring(6).Trim();
if (string.IsNullOrEmpty(text2))
{
return true;
}
text2 = text2.Replace("#", "").Replace(" ", "");
if (text2.Length > 0 && Regex.IsMatch(text2, "^\\d+$"))
{
return true;
}
}
if (text == "player")
{
return true;
}
return false;
}
private static void OnClientDisconnected(ulong clientId)
{
ulong steamID = SteamIDHelper.GetSteamID(clientId);
_processedConnects.Remove(steamID);
_processedConnects.Remove(clientId);
RecentLeaveTracker.Add(clientId);
if (!((Object)(object)NetworkManager.Singleton != (Object)null))
{
return;
}
List<ulong> list = new List<ulong>();
if (NetworkManager.Singleton.IsServer)
{
foreach (KeyValuePair<ulong, NetworkClient> connectedClient in NetworkManager.Singleton.ConnectedClients)
{
list.Add(connectedClient.Key);
}
}
else
{
PlayerControllerB[] array = Object.FindObjectsByType<PlayerControllerB>((FindObjectsSortMode)0);
PlayerControllerB[] array2 = array;
foreach (PlayerControllerB val in array2)
{
if ((Object)(object)val != (Object)null && val.actualClientId != 0)
{
ulong steamID2 = SteamIDHelper.GetSteamID(val.actualClientId);
if (steamID2 != 0)
{
list.Add(steamID2);
}
}
}
}
KickTracker.SetCurrentPlayers(list);
if (!NetworkManager.Singleton.IsServer && clientId == NetworkManager.Singleton.LocalClientId)
{
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogInfo((object)"[PastaNetwork] 킥당한 것으로 감지! UI 표시 중...");
}
((MonoBehaviour)Instance).StartCoroutine(ShowKickUIDelayed());
}
}
private static IEnumerator ShowKickUIDelayed()
{
yield return (object)new WaitForSeconds(0.5f);
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogInfo((object)"[PastaNetwork] 킥 UI 표시 중...");
}
KickUI.ShowKickedBy();
}
private static IEnumerator CheckAndKickPlayerDelayed(ulong clientId)
{
yield return (object)new WaitForSeconds(1.5f);
if ((Object)(object)NetworkManager.Singleton == (Object)null || !NetworkManager.Singleton.IsHost)
{
yield break;
}
ulong steamId = SteamIDHelper.GetSteamID(clientId);
if (steamId == clientId && clientId < 76561190000000000L)
{
yield return (object)new WaitForSeconds(1f);
steamId = SteamIDHelper.GetSteamID(clientId);
}
ServerClient.GetShitterInfo(steamId, delegate(bool success, Dictionary<string, object>? infoData)
{
if (success && infoData != null && infoData.ContainsKey("voteCount"))
{
int val = (int)infoData["voteCount"];
if (infoData.ContainsKey("fullJson"))
{
string input = infoData["fullJson"].ToString() ?? "";
string pattern = "\"votes\"\\s*:\\s*\\{([^}]+(?:\\{[^}]+\\}[^}]*)*)\\}";
Match match = Regex.Match(input, pattern);
if (match.Success)
{
string value = match.Groups[1].Value;
string pattern2 = "\"(\\d+)\"\\s*:\\s*\\{[^}]*\"reason\"\\s*:\\s*\"([^\"]+)\"";
MatchCollection matchCollection = Regex.Matches(value, pattern2);
foreach (Match item in matchCollection)
{
if (item.Groups.Count >= 3 && ulong.TryParse(item.Groups[1].Value, out var result))
{
string value2 = item.Groups[2].Value;
value2 = value2.Replace("\\\"", "\"").Replace("\\n", "\n").Replace("\\t", "\t");
ShitterDatabase.AddVote(steamId, result, value2);
}
}
}
}
int voteCount = ShitterDatabase.GetVoteCount(steamId);
int num = Math.Max(val, voteCount);
if (ConfigManager.EnableAutoKick.Value && num >= ConfigManager.VoteKickThreshold.Value)
{
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogInfo((object)$"[PastaNetwork] 자동 킥: Steam ID {steamId}, 투표 {num}개");
}
if ((Object)(object)Instance == (Object)null)
{
ManualLogSource log2 = Plugin.Log;
if (log2 != null)
{
log2.LogError((object)"[PastaNetwork] Instance is null! Cannot start kick coroutine.");
}
}
else
{
((MonoBehaviour)Instance).StartCoroutine(KickPlayerDelayed(clientId, steamId, num));
}
}
}
else if (ShitterDatabase.IsShitter(steamId))
{
int voteCount2 = ShitterDatabase.GetVoteCount(steamId);
if (ConfigManager.EnableAutoKick.Value && voteCount2 >= ConfigManager.VoteKickThreshold.Value)
{
ManualLogSource log3 = Plugin.Log;
if (log3 != null)
{
log3.LogInfo((object)$"[PastaNetwork] 자동 킥 (로컬 DB): Steam ID {steamId}, 투표 {voteCount2}개");
}
((MonoBehaviour)Instance).StartCoroutine(KickPlayerDelayed(clientId, steamId, voteCount2));
}
}
});
}
private static IEnumerator KickPlayerDelayed(ulong clientId, ulong steamId, int votes)
{
yield return (object)new WaitForSeconds(1f);
if ((Object)(object)NetworkManager.Singleton == (Object)null || !NetworkManager.Singleton.IsHost)
{
yield break;
}
ulong actualClientId = clientId;
if (clientId > 76561190000000000L && clientId < 76561199999999999L)
{
actualClientId = SteamIDHelper.GetClientID(steamId);
if (actualClientId == steamId || actualClientId == clientId)
{
foreach (KeyValuePair<ulong, NetworkClient> connectedClient in NetworkManager.Singleton.ConnectedClients)
{
ulong connectedClientId = connectedClient.Key;
ulong connectedSteamId = SteamIDHelper.GetSteamID(connectedClientId);
if (connectedSteamId == steamId)
{
actualClientId = connectedClientId;
break;
}
}
}
}
if (!NetworkManager.Singleton.ConnectedClients.ContainsKey(actualClientId))
{
yield break;
}
try
{
ShitterInfo shitterInfo = ShitterDatabase.Get(steamId);
string playerName = SteamNameFetcher.GetCachedName(steamId);
if (playerName == "Unknown")
{
playerName = GetPlayerName(actualClientId);
if (playerName == "Unknown")
{
playerName = $"플레이어 ({steamId})";
}
}
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogInfo((object)"═══════════════════════════════════════════════════════");
}
ManualLogSource log2 = Plugin.Log;
if (log2 != null)
{
log2.LogInfo((object)$"\ud83d\udeab 자동 킥 실행: {playerName} (Steam ID: {steamId})");
}
ManualLogSource log3 = Plugin.Log;
if (log3 != null)
{
log3.LogInfo((object)$"\ud83d\udcca 총 투표 수: {votes}개 (임계값: {ConfigManager.VoteKickThreshold.Value}개)");
}
if (shitterInfo != null && shitterInfo.Reasons.Count > 0)
{
ManualLogSource log4 = Plugin.Log;
if (log4 != null)
{
log4.LogInfo((object)"───────────────────────────────────────────────────────");
}
ManualLogSource log5 = Plugin.Log;
if (log5 != null)
{
log5.LogInfo((object)"\ud83d\udcdd 투표 사유:");
}
int index = 1;
foreach (KeyValuePair<ulong, string> kvp in shitterInfo.Reasons)
{
ulong voterSteamId = kvp.Key;
string reason = kvp.Value;
string voterName = SteamNameFetcher.GetCachedName(voterSteamId);
if (voterName == "Unknown")
{
voterName = $"플레이어 ({voterSteamId})";
}
ManualLogSource log6 = Plugin.Log;
if (log6 != null)
{
log6.LogInfo((object)$" {index}. [{voterName}] {reason}");
}
index++;
}
}
else
{
ManualLogSource log7 = Plugin.Log;
if (log7 != null)
{
log7.LogInfo((object)"───────────────────────────────────────────────────────");
}
ManualLogSource log8 = Plugin.Log;
if (log8 != null)
{
log8.LogInfo((object)"⚠\ufe0f 투표 사유 정보를 가져올 수 없습니다. (로컬 DB에 없음)");
}
}
ManualLogSource log9 = Plugin.Log;
if (log9 != null)
{
log9.LogInfo((object)"═══════════════════════════════════════════════════════");
}
NetworkManager.Singleton.DisconnectClient(actualClientId);
_processedConnects.Remove(steamId);
_processedConnects.Remove(actualClientId);
if ((Object)(object)HUDManager.Instance != (Object)null)
{
HUDManager.Instance.DisplayTip("Pasta Client", $"자동킥됨 (Shitter, 투표: {votes})", false, false, "LC_Tip1");
SendChatMessage($"{playerName}이(가) Shitter 투표 {votes}개로 인해 자동 킥되었습니다.");
}
}
catch (Exception ex)
{
ManualLogSource log10 = Plugin.Log;
if (log10 != null)
{
log10.LogError((object)$"[PastaNetwork] 킥 실행 중 오류: {ex}");
}
}
}
[ServerRpc(RequireOwnership = false)]
public void AddShitterServerRpc(ulong targetId, string reason, ulong senderId)
{
ShitterDatabase.AddVote(targetId, senderId, reason);
UpdateShitterClientsClientRpc(targetId);
if (!((NetworkBehaviour)this).IsHost || !((Object)(object)NetworkManager.Singleton != (Object)null))
{
return;
}
int voteCount = ShitterDatabase.GetVoteCount(targetId);
if (!ConfigManager.EnableAutoKick.Value || voteCount < ConfigManager.VoteKickThreshold.Value)
{
return;
}
ulong clientID = SteamIDHelper.GetClientID(targetId);
if (NetworkManager.Singleton.ConnectedClients.ContainsKey(clientID))
{
((MonoBehaviour)Instance).StartCoroutine(KickPlayerDelayed(clientID, targetId, voteCount));
return;
}
foreach (KeyValuePair<ulong, NetworkClient> connectedClient in NetworkManager.Singleton.ConnectedClients)
{
ulong key = connectedClient.Key;
ulong steamID = SteamIDHelper.GetSteamID(key);
if (steamID == targetId)
{
((MonoBehaviour)Instance).StartCoroutine(KickPlayerDelayed(key, targetId, voteCount));
break;
}
}
}
[ClientRpc]
public void UpdateShitterClientsClientRpc(ulong id)
{
Plugin.Log.LogDebug((object)$"[PastaNetwork] UpdateShitterClientsClientRpc: {id}");
ShitterUI.OnDatabaseUpdated(id);
}
[ClientRpc]
public void SendPlayerListClientRpc(ulong[] playerIds, ClientRpcParams rpcParams = default(ClientRpcParams))
{
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogInfo((object)$"[PastaNetwork] 방 플레이어 목록 수신: {playerIds.Length}명");
}
KickTracker.SetCurrentPlayers(playerIds);
foreach (ulong num in playerIds)
{
if (num != 0)
{
((MonoBehaviour)Instance).StartCoroutine(CachePlayerNameDelayed(num));
}
}
}
public static void RequestAddShitter(ulong targetId, string reason)
{
string reason2 = reason;
if ((Object)(object)Instance == (Object)null)
{
return;
}
ulong targetSteamId = SteamIDHelper.GetSteamID(targetId);
ulong senderSteamId = 0uL;
if ((Object)(object)NetworkManager.Singleton != (Object)null)
{
senderSteamId = SteamIDHelper.GetSteamID(NetworkManager.Singleton.LocalClientId);
}
ServerClient.SendShitterVote(targetSteamId, senderSteamId, reason2, delegate(bool success, string response)
{
if (success)
{
try
{
if (response.Contains("\"voteCount\""))
{
Match match = Regex.Match(response, "\"voteCount\"\\s*:\\s*(\\d+)");
if (match.Success && int.TryParse(match.Groups[1].Value, out var result) && (Object)(object)NetworkManager.Singleton != (Object)null && NetworkManager.Singleton.IsServer && NetworkManager.Singleton.IsHost && ConfigManager.EnableAutoKick.Value && result >= ConfigManager.VoteKickThreshold.Value)
{
ulong clientID = SteamIDHelper.GetClientID(targetSteamId);
if (NetworkManager.Singleton.ConnectedClients.ContainsKey(clientID))
{
((MonoBehaviour)Instance).StartCoroutine(KickPlayerDelayed(clientID, targetSteamId, result));
}
}
}
}
catch (Exception ex)
{
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogWarning((object)("[PastaNetwork] 서버 응답 파싱 오류: " + ex.Message));
}
}
HUDManager instance = HUDManager.Instance;
if (instance != null)
{
instance.DisplayTip("Pasta Client", "Shitter 추가 요청 전송됨", false, false, "LC_Tip1");
}
ShitterDatabase.AddVote(targetSteamId, senderSteamId, reason2);
ShitterUI.OnDatabaseUpdated(targetSteamId);
if ((Object)(object)NetworkManager.Singleton != (Object)null && NetworkManager.Singleton.IsServer && (Object)(object)Instance != (Object)null)
{
try
{
ulong localClientId = NetworkManager.Singleton.LocalClientId;
Instance.AddShitterServerRpc(targetSteamId, reason2, senderSteamId);
}
catch (Exception ex2)
{
ManualLogSource log2 = Plugin.Log;
if (log2 != null)
{
log2.LogWarning((object)("[PastaNetwork] Failed to call AddShitterServerRpc: " + ex2.Message));
}
}
}
}
else
{
ManualLogSource log3 = Plugin.Log;
if (log3 != null)
{
log3.LogError((object)("[PastaNetwork] Failed to send shitter vote to server: " + response));
}
HUDManager instance2 = HUDManager.Instance;
if (instance2 != null)
{
instance2.DisplayTip("Pasta Client", "서버 요청 실패", false, false, "LC_Tip1");
}
}
});
}
}
[BepInPlugin("dev523.pasta.client", "Pasta Client", "1.0.0")]
public class Plugin : BaseUnityPlugin
{
public static ManualLogSource Log;
private void Awake()
{
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
//IL_0033: Expected O, but got Unknown
Log = ((BaseUnityPlugin)this).Logger;
Log.LogInfo((object)"Pasta Client Loaded!");
ConfigManager.Init(((BaseUnityPlugin)this).Config);
Harmony val = new Harmony("dev523.pasta.client");
val.PatchAll();
PastaNetwork.Init();
ShitterDatabase.Init();
RecentLeaveTracker.Init((MonoBehaviour?)(object)PastaNetwork.Instance);
KickTracker.Init();
ChatCommandHandler.Init();
Object.DontDestroyOnLoad((Object)(object)this);
}
}
public static class KickTracker
{
public static List<ulong> LastPlayersInRoom = new List<ulong>();
public static void Init()
{
}
public static void SetCurrentPlayers(IEnumerable<ulong> ids)
{
LastPlayersInRoom = new List<ulong>(ids);
}
}
public class RecentPlayerInfo
{
public ulong ClientId;
public string PlayerName;
public bool IsNameLoading;
public RecentPlayerInfo(ulong clientId, string playerName, bool isNameLoading = false)
{
ClientId = clientId;
PlayerName = playerName ?? "Unknown";
IsNameLoading = isNameLoading;
}
}
public static class RecentLeaveTracker
{
private static readonly LinkedList<RecentPlayerInfo> _recent = new LinkedList<RecentPlayerInfo>();
private static readonly Dictionary<ulong, string> _playerNameCache = new Dictionary<ulong, string>();
private const int Max = 10;
private static MonoBehaviour? _coroutineRunner;
public static void Init(MonoBehaviour? coroutineRunner = null)
{
_coroutineRunner = coroutineRunner;
}
public static void Add(ulong clientId)
{
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogInfo((object)"[RecentLeaveTracker] ========================================");
}
ManualLogSource log2 = Plugin.Log;
if (log2 != null)
{
log2.LogInfo((object)"[RecentLeaveTracker] 나간 플레이어 리스트에 추가 중...");
}
ManualLogSource log3 = Plugin.Log;
if (log3 != null)
{
log3.LogInfo((object)$"[RecentLeaveTracker] Steam ID: {clientId}");
}
string value;
string text = (_playerNameCache.TryGetValue(clientId, out value) ? value : "Unknown");
ManualLogSource log4 = Plugin.Log;
if (log4 != null)
{
log4.LogInfo((object)("[RecentLeaveTracker] 캐시에서 가져온 이름: " + text));
}
if (text == "Unknown")
{
text = GetPlayerNameFromGame(clientId);
ManualLogSource log5 = Plugin.Log;
if (log5 != null)
{
log5.LogInfo((object)("[RecentLeaveTracker] 게임에서 가져온 이름: " + text));
}
if (text != "Unknown" && !string.IsNullOrEmpty(text))
{
_playerNameCache[clientId] = text;
}
}
bool flag = text == "Unknown";
ManualLogSource log6 = Plugin.Log;
if (log6 != null)
{
log6.LogInfo((object)("[RecentLeaveTracker] 현재 플레이어 이름: " + text));
}
ManualLogSource log7 = Plugin.Log;
if (log7 != null)
{
log7.LogInfo((object)$"[RecentLeaveTracker] 이름 로딩 중: {flag}");
}
RecentPlayerInfo value2 = new RecentPlayerInfo(clientId, text, flag);
_recent.AddFirst(value2);
while (_recent.Count > 10)
{
_recent.RemoveLast();
}
ManualLogSource log8 = Plugin.Log;
if (log8 != null)
{
log8.LogInfo((object)$"[RecentLeaveTracker] 리스트에 추가 완료! (총 {_recent.Count}명)");
}
if (flag && (Object)(object)_coroutineRunner != (Object)null)
{
ManualLogSource log9 = Plugin.Log;
if (log9 != null)
{
log9.LogInfo((object)"[RecentLeaveTracker] Steam API로 이름 가져오기 시작...");
}
SteamNameFetcher.FetchPlayerNameFromGameOrSteam(clientId, delegate(ulong steamId, string name)
{
ManualLogSource log15 = Plugin.Log;
if (log15 != null)
{
log15.LogInfo((object)"[RecentLeaveTracker] ========================================");
}
ManualLogSource log16 = Plugin.Log;
if (log16 != null)
{
log16.LogInfo((object)"[RecentLeaveTracker] Steam API 이름 가져오기 완료!");
}
ManualLogSource log17 = Plugin.Log;
if (log17 != null)
{
log17.LogInfo((object)$"[RecentLeaveTracker] Steam ID: {steamId}");
}
ManualLogSource log18 = Plugin.Log;
if (log18 != null)
{
log18.LogInfo((object)("[RecentLeaveTracker] 플레이어 이름: " + name));
}
ManualLogSource log19 = Plugin.Log;
if (log19 != null)
{
log19.LogInfo((object)"[RecentLeaveTracker] ========================================");
}
UpdatePlayerName(steamId, name);
});
}
else if (!flag)
{
ManualLogSource log10 = Plugin.Log;
if (log10 != null)
{
log10.LogInfo((object)"[RecentLeaveTracker] ========================================");
}
ManualLogSource log11 = Plugin.Log;
if (log11 != null)
{
log11.LogInfo((object)"[RecentLeaveTracker] 나간 플레이어 정보:");
}
ManualLogSource log12 = Plugin.Log;
if (log12 != null)
{
log12.LogInfo((object)$"[RecentLeaveTracker] Steam ID: {clientId}");
}
ManualLogSource log13 = Plugin.Log;
if (log13 != null)
{
log13.LogInfo((object)("[RecentLeaveTracker] 플레이어 이름: " + text));
}
ManualLogSource log14 = Plugin.Log;
if (log14 != null)
{
log14.LogInfo((object)"[RecentLeaveTracker] ========================================");
}
}
}
public static void CachePlayerName(ulong clientId, string playerName)
{
if (!string.IsNullOrEmpty(playerName) && playerName != "Unknown")
{
_playerNameCache[clientId] = playerName;
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogInfo((object)$"[RecentLeaveTracker] Cached player name: {clientId} = {playerName}");
}
}
if (!((Object)(object)_coroutineRunner != (Object)null))
{
return;
}
SteamNameFetcher.FetchPlayerNameFromGameOrSteam(clientId, delegate(ulong steamId, string name)
{
if (!string.IsNullOrEmpty(name) && name != "Unknown")
{
_playerNameCache[steamId] = name;
ManualLogSource log2 = Plugin.Log;
if (log2 != null)
{
log2.LogInfo((object)$"[RecentLeaveTracker] Updated cached name from Steam: {steamId} = {name}");
}
}
});
}
private static void UpdatePlayerName(ulong clientId, string playerName)
{
foreach (RecentPlayerInfo item in _recent)
{
if (item.ClientId == clientId)
{
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogInfo((object)$"[RecentLeaveTracker] 리스트에서 이름 업데이트: Steam ID {clientId}, 이전 이름: {item.PlayerName} -> 새 이름: {playerName}");
}
item.PlayerName = playerName;
item.IsNameLoading = false;
if (!string.IsNullOrEmpty(playerName) && playerName != "Unknown")
{
_playerNameCache[clientId] = playerName;
}
break;
}
}
}
private static string GetPlayerNameFromGame(ulong clientId)
{
if ((Object)(object)NetworkManager.Singleton == (Object)null)
{
return "Unknown";
}
if (NetworkManager.Singleton.IsServer && NetworkManager.Singleton.ConnectedClients.TryGetValue(clientId, out var value) && (Object)(object)value.PlayerObject != (Object)null)
{
string name = ((Object)value.PlayerObject).name;
if (!string.IsNullOrEmpty(name) && name != "Player")
{
return name;
}
}
PlayerControllerB[] array = Object.FindObjectsByType<PlayerControllerB>((FindObjectsSortMode)0);
PlayerControllerB[] array2 = array;
foreach (PlayerControllerB val in array2)
{
if (!((Object)(object)val != (Object)null) || val.actualClientId != clientId)
{
continue;
}
FieldInfo field = typeof(PlayerControllerB).GetField("playerUsername", BindingFlags.Instance | BindingFlags.Public);
if (field != null)
{
string text = field.GetValue(val) as string;
if (!string.IsNullOrEmpty(text))
{
return text;
}
}
if (!string.IsNullOrEmpty(((Object)val).name) && ((Object)val).name != "Player")
{
return ((Object)val).name;
}
}
return "Unknown";
}
public static IEnumerable<RecentPlayerInfo> GetAll()
{
return _recent;
}
public static IEnumerable<ulong> GetAllIds()
{
return _recent.Select((RecentPlayerInfo p) => p.ClientId);
}
}
public class ShitterInfo
{
public ulong SteamId;
public Dictionary<ulong, string> Reasons = new Dictionary<ulong, string>();
public ShitterInfo(ulong id)
{
SteamId = id;
}
}
public static class ShitterDatabase
{
private static readonly Dictionary<ulong, ShitterInfo> _shitters = new Dictionary<ulong, ShitterInfo>();
public static void Init()
{
}
public static void AddVote(ulong targetId, ulong voterId, string reason)
{
if (targetId != voterId)
{
if (!_shitters.TryGetValue(targetId, out ShitterInfo value))
{
value = new ShitterInfo(targetId);
_shitters[targetId] = value;
}
if (!value.Reasons.ContainsKey(voterId))
{
value.Reasons[voterId] = reason;
}
}
}
public static bool IsShitter(ulong id)
{
return _shitters.ContainsKey(id);
}
public static int GetVoteCount(ulong id)
{
ShitterInfo value;
return _shitters.TryGetValue(id, out value) ? value.Reasons.Count : 0;
}
public static IEnumerable<ShitterInfo> All()
{
return _shitters.Values;
}
public static ShitterInfo? Get(ulong id)
{
ShitterInfo value;
return _shitters.TryGetValue(id, out value) ? value : null;
}
}
public static class KickUI
{
[CompilerGenerated]
private static class <>O
{
public static Action <0>__OnGUI;
public static WindowFunction <1>__WindowFunc;
}
private static bool _open;
private static Rect _rect = new Rect(140f, 140f, 400f, 400f);
public static void ShowKickedBy()
{
if (ConfigManager.EnableShitterUIOnKick.Value)
{
_open = true;
UIHelper.Register(OnGUI);
}
}
private static void Close()
{
_open = false;
UIHelper.Unregister(OnGUI);
}
private static void OnGUI()
{
//IL_0088: Unknown result type (might be due to invalid IL or missing references)
//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
//IL_009d: Unknown result type (might be due to invalid IL or missing references)
//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
//IL_00a8: Expected O, but got Unknown
if (!_open)
{
return;
}
try
{
if (((Rect)(ref _rect)).x == 140f && ((Rect)(ref _rect)).y == 140f)
{
((Rect)(ref _rect)).x = ((float)Screen.width - ((Rect)(ref _rect)).width) / 2f;
((Rect)(ref _rect)).y = ((float)Screen.height - ((Rect)(ref _rect)).height) / 2f;
}
Rect rect = _rect;
object obj = <>O.<1>__WindowFunc;
if (obj == null)
{
WindowFunction val = WindowFunc;
<>O.<1>__WindowFunc = val;
obj = (object)val;
}
_rect = GUILayout.Window(987656, rect, (WindowFunction)obj, "킥당함 - 방 목록", UIStyle.WindowStyle, Array.Empty<GUILayoutOption>());
}
catch (Exception arg)
{
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogError((object)$"[KickUI] Error in OnGUI: {arg}");
}
}
}
private static void WindowFunc(int id)
{
//IL_007f: Unknown result type (might be due to invalid IL or missing references)
//IL_0093: Unknown result type (might be due to invalid IL or missing references)
//IL_022b: Unknown result type (might be due to invalid IL or missing references)
GUILayout.BeginVertical((GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) });
GUILayout.Label("킥 당했을 때 방에 있던 플레이어 목록입니다.", UIStyle.LabelStyle, Array.Empty<GUILayoutOption>());
GUILayout.Box("", UIStyle.BoxStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
{
GUILayout.Height(1f),
GUILayout.ExpandWidth(true)
});
GUILayout.Space(10f);
List<ulong> lastPlayersInRoom = KickTracker.LastPlayersInRoom;
if (lastPlayersInRoom != null && lastPlayersInRoom.Count > 0)
{
GUILayout.BeginScrollView(Vector2.zero, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandHeight(true) });
foreach (ulong item in lastPlayersInRoom)
{
GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
GUILayout.Label($"[{item}]", UIStyle.LabelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(150f) });
if (GUILayout.Button("Steam 프로필", UIStyle.ButtonStyle, Array.Empty<GUILayoutOption>()))
{
ulong steamID = SteamIDHelper.GetSteamID(item);
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogInfo((object)$"[KickUI] Opening Steam profile: clientId={item}, steamId={steamID}");
}
Application.OpenURL($"https://steamcommunity.com/profiles/{steamID}");
}
GUILayout.EndHorizontal();
GUILayout.Space(5f);
}
GUILayout.EndScrollView();
}
else
{
GUILayout.Label("목록이 비어있습니다.", UIStyle.LabelStyle, Array.Empty<GUILayoutOption>());
}
GUILayout.Space(10f);
GUILayout.Box("", UIStyle.BoxStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
{
GUILayout.Height(1f),
GUILayout.ExpandWidth(true)
});
GUILayout.Space(5f);
if (GUILayout.Button("닫기", UIStyle.ButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(30f) }))
{
Close();
}
GUILayout.EndVertical();
GUI.DragWindow(new Rect(0f, 0f, ((Rect)(ref _rect)).width, 20f));
}
}
public static class RecentUI
{
[CompilerGenerated]
private static class <>O
{
public static Action <0>__OnGUI;
public static WindowFunction <1>__WindowFunc;
}
private static bool _open;
private static Rect _rect = new Rect(120f, 120f, 450f, 500f);
public static void Open()
{
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogInfo((object)"[RecentUI] Open() called");
}
_open = true;
UIHelper.Register(OnGUI);
ManualLogSource log2 = Plugin.Log;
if (log2 != null)
{
log2.LogInfo((object)$"[RecentUI] UI registered, _open = {_open}");
}
}
public static void Close()
{
_open = false;
UIHelper.Unregister(OnGUI);
}
private static void OnGUI()
{
//IL_0088: Unknown result type (might be due to invalid IL or missing references)
//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
//IL_009d: Unknown result type (might be due to invalid IL or missing references)
//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
//IL_00a8: Expected O, but got Unknown
if (!_open)
{
return;
}
try
{
if (((Rect)(ref _rect)).x == 120f && ((Rect)(ref _rect)).y == 120f)
{
((Rect)(ref _rect)).x = ((float)Screen.width - ((Rect)(ref _rect)).width) / 2f;
((Rect)(ref _rect)).y = ((float)Screen.height - ((Rect)(ref _rect)).height) / 2f;
}
Rect rect = _rect;
object obj = <>O.<1>__WindowFunc;
if (obj == null)
{
WindowFunction val = WindowFunc;
<>O.<1>__WindowFunc = val;
obj = (object)val;
}
_rect = GUILayout.Window(987655, rect, (WindowFunction)obj, "최근 나간 사람들", UIStyle.WindowStyle, Array.Empty<GUILayoutOption>());
}
catch (Exception arg)
{
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogError((object)$"[RecentUI] Error in OnGUI: {arg}");
}
}
}
private static void WindowFunc(int id)
{
//IL_007e: Unknown result type (might be due to invalid IL or missing references)
//IL_0092: Unknown result type (might be due to invalid IL or missing references)
//IL_0252: Unknown result type (might be due to invalid IL or missing references)
GUILayout.BeginVertical((GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) });
GUILayout.Label("최근에 방을 나간 플레이어 목록입니다.", UIStyle.LabelStyle, Array.Empty<GUILayoutOption>());
GUILayout.Box("", UIStyle.BoxStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
{
GUILayout.Height(1f),
GUILayout.ExpandWidth(true)
});
GUILayout.Space(10f);
List<RecentPlayerInfo> list = RecentLeaveTracker.GetAll().ToList();
if (list.Count > 0)
{
GUILayout.BeginScrollView(Vector2.zero, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandHeight(true) });
foreach (RecentPlayerInfo item in list)
{
GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
string arg = (item.IsNameLoading ? "Loading..." : item.PlayerName);
GUILayout.Label($"[{item.ClientId}] {arg}", UIStyle.LabelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(250f) });
if (GUILayout.Button("Steam 프로필", UIStyle.ButtonStyle, Array.Empty<GUILayoutOption>()))
{
ulong steamID = SteamIDHelper.GetSteamID(item.ClientId);
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogInfo((object)$"[RecentUI] Opening Steam profile: clientId={item.ClientId}, steamId={steamID}");
}
Application.OpenURL($"https://steamcommunity.com/profiles/{steamID}");
}
GUILayout.EndHorizontal();
GUILayout.Space(5f);
}
GUILayout.EndScrollView();
}
else
{
GUILayout.Label("목록이 비어있습니다.", UIStyle.LabelStyle, Array.Empty<GUILayoutOption>());
}
GUILayout.Space(10f);
GUILayout.Box("", UIStyle.BoxStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
{
GUILayout.Height(1f),
GUILayout.ExpandWidth(true)
});
GUILayout.Space(5f);
if (GUILayout.Button("닫기", UIStyle.ButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(30f) }))
{
Close();
}
GUILayout.EndVertical();
GUI.DragWindow(new Rect(0f, 0f, ((Rect)(ref _rect)).width, 20f));
}
}
[Serializable]
public class ShitterVoteRequest
{
public string targetId = "";
public string senderId = "";
public string reason = "";
public long timestamp;
}
public static class ServerClient
{
private static MonoBehaviour? _coroutineRunner;
private const string DEFAULT_SERVER_URL = "https://shitter.asta.rs";
public static void Init(MonoBehaviour coroutineRunner)
{
_coroutineRunner = coroutineRunner;
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogInfo((object)"[ServerClient] Initialized");
}
}
public static void SendShitterVote(ulong targetId, ulong senderId, string reason, Action<bool, string>? onComplete = null)
{
if ((Object)(object)_coroutineRunner == (Object)null)
{
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogError((object)"[ServerClient] CoroutineRunner not initialized!");
}
onComplete?.Invoke(arg1: false, "CoroutineRunner not initialized");
return;
}
string text = ConfigManager.ServerUrl?.Value ?? "https://shitter.asta.rs";
string url = text + "/api/shitter/vote";
ManualLogSource log2 = Plugin.Log;
if (log2 != null)
{
log2.LogInfo((object)$"[ServerClient] Sending shitter vote: targetId={targetId}, senderId={senderId}, reason={reason}");
}
_coroutineRunner.StartCoroutine(SendVoteCoroutine(url, targetId, senderId, reason, onComplete));
}
private static IEnumerator SendVoteCoroutine(string url, ulong targetId, ulong senderId, string reason, Action<bool, string>? onComplete)
{
ShitterVoteRequest jsonData = new ShitterVoteRequest
{
targetId = targetId.ToString(),
senderId = senderId.ToString(),
reason = reason,
timestamp = (long)(DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds
};
string json = JsonUtility.ToJson((object)jsonData);
byte[] bodyRaw = Encoding.UTF8.GetBytes(json);
UnityWebRequest request = new UnityWebRequest(url, "POST");
try
{
request.uploadHandler = (UploadHandler)new UploadHandlerRaw(bodyRaw);
request.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer();
request.SetRequestHeader("Content-Type", "application/json");
request.SetRequestHeader("User-Agent", "PastaClient/1.0");
yield return request.SendWebRequest();
if ((int)request.result == 1)
{
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogInfo((object)("[ServerClient] Vote sent successfully: " + request.downloadHandler.text));
}
onComplete?.Invoke(arg1: true, request.downloadHandler.text);
}
else
{
ManualLogSource log2 = Plugin.Log;
if (log2 != null)
{
log2.LogError((object)("[ServerClient] Failed to send vote: " + request.error));
}
onComplete?.Invoke(arg1: false, request.error ?? "Unknown error");
}
}
finally
{
((IDisposable)request)?.Dispose();
}
}
public static void GetShitterInfo(ulong targetId, Action<bool, Dictionary<string, object>?>? onComplete = null)
{
if ((Object)(object)_coroutineRunner == (Object)null)
{
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogError((object)"[ServerClient] CoroutineRunner not initialized!");
}
onComplete?.Invoke(arg1: false, null);
return;
}
string arg = ConfigManager.ServerUrl?.Value ?? "https://shitter.asta.rs";
string url = $"{arg}/api/shitter/info/{targetId}";
ManualLogSource log2 = Plugin.Log;
if (log2 != null)
{
log2.LogInfo((object)$"[ServerClient] Getting shitter info: targetId={targetId}");
}
_coroutineRunner.StartCoroutine(GetInfoCoroutine(url, onComplete));
}
private static IEnumerator GetInfoCoroutine(string url, Action<bool, Dictionary<string, object>?>? onComplete)
{
UnityWebRequest request = UnityWebRequest.Get(url);
try
{
request.SetRequestHeader("User-Agent", "PastaClient/1.0");
yield return request.SendWebRequest();
if ((int)request.result == 1)
{
try
{
string json = request.downloadHandler.text;
Dictionary<string, object> result = new Dictionary<string, object>();
Match voteCountMatch = Regex.Match(json, "\"voteCount\"\\s*:\\s*(\\d+)");
if (voteCountMatch.Success && int.TryParse(voteCountMatch.Groups[1].Value, out var voteCount))
{
result["voteCount"] = voteCount;
}
else
{
result["voteCount"] = 0;
}
Match steamIdMatch = Regex.Match(json, "\"steamId\"\\s*:\\s*\"?(\\d+)\"?");
if (steamIdMatch.Success && ulong.TryParse(steamIdMatch.Groups[1].Value, out var steamId))
{
result["steamId"] = steamId;
}
if (json.Contains("\"votes\""))
{
result["hasVotes"] = true;
result["fullJson"] = json;
}
onComplete?.Invoke(arg1: true, result);
}
catch (Exception ex2)
{
Exception ex = ex2;
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogError((object)$"[ServerClient] Error parsing response: {ex}");
}
onComplete?.Invoke(arg1: false, null);
}
}
else
{
ManualLogSource log2 = Plugin.Log;
if (log2 != null)
{
log2.LogError((object)("[ServerClient] Failed to get info: " + request.error));
}
onComplete?.Invoke(arg1: false, null);
}
}
finally
{
((IDisposable)request)?.Dispose();
}
}
}
public static class ShitterUI
{
[CompilerGenerated]
private static class <>O
{
public static Action <0>__OnGUI;
public static WindowFunction <1>__WindowFunc;
}
private static bool _open = false;
private static Rect _windowRect = new Rect(100f, 100f, 500f, 550f);
private static Vector2 _scroll = Vector2.zero;
private static ulong _selectedId = 0uL;
private static string _reason = "";
private const string REASON_TEXTAREA_ID = "ShitterReasonTextArea";
public static void Open()
{
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogInfo((object)"[ShitterUI] Open() called");
}
_open = true;
UIHelper.Register(OnGUI);
ManualLogSource log2 = Plugin.Log;
if (log2 != null)
{
log2.LogInfo((object)$"[ShitterUI] UI registered, _open = {_open}");
}
}
public static void Close()
{
_open = false;
UIHelper.Unregister(OnGUI);
}
public static void OnDatabaseUpdated(ulong id)
{
}
private static void OnGUI()
{
//IL_0088: Unknown result type (might be due to invalid IL or missing references)
//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
//IL_009d: Unknown result type (might be due to invalid IL or missing references)
//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
//IL_00a8: Expected O, but got Unknown
if (!_open)
{
return;
}
try
{
if (((Rect)(ref _windowRect)).x == 100f && ((Rect)(ref _windowRect)).y == 100f)
{
((Rect)(ref _windowRect)).x = ((float)Screen.width - ((Rect)(ref _windowRect)).width) / 2f;
((Rect)(ref _windowRect)).y = ((float)Screen.height - ((Rect)(ref _windowRect)).height) / 2f;
}
Rect windowRect = _windowRect;
object obj = <>O.<1>__WindowFunc;
if (obj == null)
{
WindowFunction val = WindowFunc;
<>O.<1>__WindowFunc = val;
obj = (object)val;
}
_windowRect = GUILayout.Window(987654, windowRect, (WindowFunction)obj, "Shitter 추가/확인", UIStyle.WindowStyle, Array.Empty<GUILayoutOption>());
}
catch (Exception arg)
{
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogError((object)$"[ShitterUI] Error in OnGUI: {arg}");
}
}
}
private static void WindowFunc(int id)
{
//IL_0600: Unknown result type (might be due to invalid IL or missing references)
//IL_0058: Unknown result type (might be due to invalid IL or missing references)
//IL_0070: Unknown result type (might be due to invalid IL or missing references)
//IL_0075: Unknown result type (might be due to invalid IL or missing references)
GUILayout.BeginVertical((GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) });
try
{
GUILayout.Label("현재 방 플레이어:", UIStyle.LabelStyle, Array.Empty<GUILayoutOption>());
GUILayout.Box("", UIStyle.BoxStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
{
GUILayout.Height(1f),
GUILayout.ExpandWidth(true)
});
_scroll = GUILayout.BeginScrollView(_scroll, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(120f) });
try
{
Dictionary<ulong, string> dictionary = new Dictionary<ulong, string>();
PlayerControllerB[] array = Object.FindObjectsByType<PlayerControllerB>((FindObjectsSortMode)0);
if (array != null && array.Length != 0)
{
PlayerControllerB[] array2 = array;
foreach (PlayerControllerB val in array2)
{
if ((Object)(object)val != (Object)null && val.actualClientId != 0)
{
ulong actualClientId = val.actualClientId;
ulong steamIDFromPlayer = GetSteamIDFromPlayer(val, actualClientId);
string text = GetPlayerNameForUI(val, steamIDFromPlayer);
if (IsDefaultPlayerName(text))
{
text = "Unknown";
}
if (!dictionary.ContainsKey(steamIDFromPlayer))
{
dictionary[steamIDFromPlayer] = text;
}
}
}
}
foreach (ulong item in KickTracker.LastPlayersInRoom)
{
if (item != 0L && !dictionary.ContainsKey(item))
{
string text2 = SteamNameFetcher.GetCachedName(item);
if (text2 == "Unknown")
{
SteamNameFetcher.FetchPlayerNameFromGameOrSteam(item, delegate
{
});
text2 = "Loading...";
}
if (IsDefaultPlayerName(text2))
{
text2 = "Loading...";
}
dictionary[item] = text2;
}
}
if (dictionary.Count > 0)
{
foreach (KeyValuePair<ulong, string> item2 in dictionary)
{
string text3 = $"[{item2.Key}] {item2.Value}";
if (GUILayout.Button(text3, UIStyle.ButtonStyle, Array.Empty<GUILayoutOption>()))
{
_selectedId = item2.Key;
}
}
}
else
{
GUILayout.Label("플레이어 없음", UIStyle.LabelStyle, Array.Empty<GUILayoutOption>());
}
}
catch (Exception arg)
{
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogError((object)$"[ShitterUI] Error getting players: {arg}");
}
GUILayout.Label("오류 발생", UIStyle.LabelStyle, Array.Empty<GUILayoutOption>());
}
finally
{
GUILayout.EndScrollView();
}
GUILayout.Space(10f);
GUILayout.Label("최근 나간 플레이어:", UIStyle.LabelStyle, Array.Empty<GUILayoutOption>());
GUILayout.Box("", UIStyle.BoxStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
{
GUILayout.Height(1f),
GUILayout.ExpandWidth(true)
});
List<RecentPlayerInfo> list = RecentLeaveTracker.GetAll().ToList();
if (list.Count > 0)
{
foreach (RecentPlayerInfo item3 in list)
{
string text4 = $"[{item3.ClientId}] {item3.PlayerName}";
if (GUILayout.Button(text4, UIStyle.ButtonStyle, Array.Empty<GUILayoutOption>()))
{
_selectedId = item3.ClientId;
}
}
}
else
{
GUILayout.Label("없음", UIStyle.LabelStyle, Array.Empty<GUILayoutOption>());
}
GUILayout.Space(10f);
GUILayout.Box("", UIStyle.BoxStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
{
GUILayout.Height(1f),
GUILayout.ExpandWidth(true)
});
GUILayout.Space(5f);
if (_selectedId != 0)
{
GUILayout.Label($"선택된 플레이어: {_selectedId}", UIStyle.LabelStyle, Array.Empty<GUILayoutOption>());
}
else
{
GUILayout.Label("플레이어를 선택하세요", UIStyle.LabelStyle, Array.Empty<GUILayoutOption>());
}
GUILayout.Space(5f);
GUILayout.Label("이유 입력:", UIStyle.LabelStyle, Array.Empty<GUILayoutOption>());
GUI.SetNextControlName("ShitterReasonTextArea");
_reason = GUILayout.TextArea(_reason, 500, UIStyle.TextFieldStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
{
GUILayout.Height(120f),
GUILayout.ExpandWidth(true)
});
string nameOfFocusedControl = GUI.GetNameOfFocusedControl();
if (nameOfFocusedControl == "ShitterReasonTextArea")
{
UIHelper.SetTextInputActive(active: true);
}
GUILayout.Space(10f);
GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
if (GUILayout.Button("추가 요청", UIStyle.ButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(30f) }) && _selectedId != 0L && !string.IsNullOrWhiteSpace(_reason))
{
PastaNetwork.RequestAddShitter(_selectedId, _reason);
HUDManager instance = HUDManager.Instance;
if (instance != null)
{
instance.DisplayTip("Pasta Client", "Shitter 추가 요청 전송됨", false, false, "LC_Tip1");
}
_reason = "";
_selectedId = 0uL;
}
if (GUILayout.Button("닫기", UIStyle.ButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(30f) }))
{
Close();
}
GUILayout.EndHorizontal();
}
catch (Exception arg2)
{
ManualLogSource log2 = Plugin.Log;
if (log2 != null)
{
log2.LogError((object)$"[ShitterUI] Error in WindowFunc: {arg2}");
}
}
finally
{
GUILayout.EndVertical();
GUI.DragWindow(new Rect(0f, 0f, ((Rect)(ref _windowRect)).width, 20f));
}
}
private static ulong GetSteamIDFromPlayer(PlayerControllerB player, ulong fallbackClientId)
{
if ((Object)(object)player == (Object)null)
{
return fallbackClientId;
}
try
{
string[] array = new string[6] { "steamId", "playerSteamId", "ownerClientId", "steamID", "SteamID", "PlayerSteamID" };
string[] array2 = array;
foreach (string name in array2)
{
FieldInfo field = typeof(PlayerControllerB).GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (!(field != null))
{
continue;
}
object value = field.GetValue(player);
if (value != null)
{
if (value is ulong num && num != 0)
{
return num;
}
if (value is long num2 && num2 > 0)
{
return (ulong)num2;
}
}
}
NetworkObject component = ((Component)player).GetComponent<NetworkObject>();
if ((Object)(object)component != (Object)null)
{
ulong ownerClientId = component.OwnerClientId;
if (ownerClientId > 76561190000000000L && ownerClientId < 76561199999999999L)
{
return ownerClientId;
}
}
}
catch (Exception ex)
{
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogWarning((object)("[ShitterUI] Error getting Steam ID from PlayerControllerB: " + ex.Message));
}
}
if (fallbackClientId > 76561190000000000L && fallbackClientId < 76561199999999999L)
{
return fallbackClientId;
}
return fallbackClientId;
}
private static string GetPlayerNameForUI(PlayerControllerB player, ulong steamId)
{
if ((Object)(object)player == (Object)null)
{
return "Unknown";
}
string text = "Unknown";
FieldInfo field = typeof(PlayerControllerB).GetField("playerUsername", BindingFlags.Instance | BindingFlags.Public);
if (field != null)
{
string text2 = field.GetValue(player) as string;
if (!string.IsNullOrEmpty(text2))
{
text = text2;
}
}
if (text == "Unknown" && !string.IsNullOrEmpty(((Object)player).name))
{
text = ((Object)player).name;
}
if (text == "Unknown")
{
text = SteamNameFetcher.GetCachedName(steamId);
if (text == "Unknown")
{
SteamNameFetcher.FetchPlayerNameFromGameOrSteam(steamId, delegate
{
});
text = "Loading...";
}
}
return text;
}
private static bool IsDefaultPlayerName(string name)
{
if (string.IsNullOrEmpty(name) || name == "Unknown" || name == "Loading...")
{
return false;
}
string text = name.ToLower().Trim();
if (text.StartsWith("player"))
{
string text2 = text.Substring(6).Trim();
if (string.IsNullOrEmpty(text2))
{
return true;
}
text2 = text2.Replace("#", "").Replace(" ", "");
if (text2.Length > 0 && Regex.IsMatch(text2, "^\\d+$"))
{
return true;
}
}
if (text == "player")
{
return true;
}
return false;
}
}
public static class SteamIDHelper
{
public static ulong GetSteamID(ulong clientId)
{
if ((Object)(object)NetworkManager.Singleton != (Object)null && NetworkManager.Singleton.IsServer)
{
try
{
if (NetworkManager.Singleton.ConnectedClients.TryGetValue(clientId, out var value))
{
try
{
if ((Object)(object)value.PlayerObject != (Object)null)
{
PlayerControllerB component = ((Component)value.PlayerObject).GetComponent<PlayerControllerB>();
if ((Object)(object)component != (Object)null)
{
ulong steamIDFromPlayer = GetSteamIDFromPlayer(component);
if (steamIDFromPlayer != 0L && steamIDFromPlayer != clientId)
{
return steamIDFromPlayer;
}
}
}
}
catch (Exception ex)
{
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogWarning((object)("[SteamIDHelper] Error getting Steam ID from NetworkClient: " + ex.Message));
}
}
}
}
catch (Exception ex2)
{
ManualLogSource log2 = Plugin.Log;
if (log2 != null)
{
log2.LogWarning((object)("[SteamIDHelper] Error accessing ConnectedClients (may be client): " + ex2.Message));
}
}
}
try
{
PlayerControllerB[] array = Object.FindObjectsByType<PlayerControllerB>((FindObjectsSortMode)0);
PlayerControllerB[] array2 = array;
foreach (PlayerControllerB val in array2)
{
if ((Object)(object)val != (Object)null && val.actualClientId == clientId)
{
ulong steamIDFromPlayer2 = GetSteamIDFromPlayer(val);
if (steamIDFromPlayer2 != 0)
{
return steamIDFromPlayer2;
}
}
}
}
catch (Exception ex3)
{
ManualLogSource log3 = Plugin.Log;
if (log3 != null)
{
log3.LogWarning((object)("[SteamIDHelper] Error searching PlayerControllerB: " + ex3.Message));
}
}
if (clientId > 76561190000000000L && clientId < 76561199999999999L)
{
return clientId;
}
return clientId;
}
private static ulong GetSteamIDFromPlayer(PlayerControllerB player)
{
if ((Object)(object)player == (Object)null)
{
return 0uL;
}
try
{
string[] array = new string[6] { "steamId", "playerSteamId", "ownerClientId", "steamID", "SteamID", "PlayerSteamID" };
string[] array2 = array;
foreach (string name in array2)
{
FieldInfo field = typeof(PlayerControllerB).GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (!(field != null))
{
continue;
}
object value = field.GetValue(player);
if (value != null)
{
if (value is ulong num && num != 0)
{
return num;
}
if (value is long num2 && num2 > 0)
{
return (ulong)num2;
}
}
}
if ((Object)(object)((Component)player).GetComponent<NetworkObject>() != (Object)null)
{
NetworkObject component = ((Component)player).GetComponent<NetworkObject>();
if ((Object)(object)component != (Object)null)
{
ulong ownerClientId = component.OwnerClientId;
if (ownerClientId > 76561190000000000L && ownerClientId < 76561199999999999L)
{
return ownerClientId;
}
}
}
}
catch (Exception ex)
{
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogWarning((object)("[SteamIDHelper] Error getting Steam ID from PlayerControllerB: " + ex.Message));
}
}
return 0uL;
}
public static ulong GetClientID(ulong steamId)
{
if ((Object)(object)NetworkManager.Singleton != (Object)null && NetworkManager.Singleton.IsServer)
{
try
{
foreach (KeyValuePair<ulong, NetworkClient> connectedClient in NetworkManager.Singleton.ConnectedClients)
{
ulong key = connectedClient.Key;
ulong steamID = GetSteamID(key);
if (steamID == steamId)
{
return key;
}
}
}
catch (Exception ex)
{
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogWarning((object)("[SteamIDHelper] Error searching ConnectedClients: " + ex.Message));
}
}
}
try
{
PlayerControllerB[] array = Object.FindObjectsByType<PlayerControllerB>((FindObjectsSortMode)0);
PlayerControllerB[] array2 = array;
foreach (PlayerControllerB val in array2)
{
if ((Object)(object)val != (Object)null && val.actualClientId != 0)
{
ulong steamIDFromPlayer = GetSteamIDFromPlayer(val);
if (steamIDFromPlayer == steamId)
{
return val.actualClientId;
}
}
}
}
catch (Exception ex2)
{
ManualLogSource log2 = Plugin.Log;
if (log2 != null)
{
log2.LogWarning((object)("[SteamIDHelper] Error searching PlayerControllerB: " + ex2.Message));
}
}
return steamId;
}
}
public static class SteamNameFetcher
{
private static readonly Dictionary<ulong, string> _nameCache = new Dictionary<ulong, string>();
private static readonly Dictionary<ulong, bool> _fetching = new Dictionary<ulong, bool>();
private static MonoBehaviour? _coroutineRunner;
public static void Init(MonoBehaviour coroutineRunner)
{
_coroutineRunner = coroutineRunner;
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogInfo((object)"[SteamNameFetcher] Initialized");
}
}
public static void FetchPlayerName(ulong steamId, Action<ulong, string>? onComplete = null)
{
string value;
if ((Object)(object)_coroutineRunner == (Object)null)
{
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogError((object)"[SteamNameFetcher] CoroutineRunner not initialized!");
}
}
else if (_nameCache.TryGetValue(steamId, out value))
{
onComplete?.Invoke(steamId, value);
}
else if (_fetching.ContainsKey(steamId) && _fetching[steamId])
{
_coroutineRunner.StartCoroutine(WaitForFetch(steamId, onComplete));
}
else
{
_fetching[steamId] = true;
_coroutineRunner.StartCoroutine(FetchSteamNameCoroutine(steamId, onComplete));
}
}
private static IEnumerator WaitForFetch(ulong steamId, Action<ulong, string>? onComplete)
{
float timeout = 10f;
float elapsed = 0f;
while (_fetching.ContainsKey(steamId) && _fetching[steamId] && elapsed < timeout)
{
yield return (object)new WaitForSeconds(0.5f);
elapsed += 0.5f;
if (_nameCache.TryGetValue(steamId, out string name))
{
onComplete?.Invoke(steamId, name);
yield break;
}
name = null;
}
if (elapsed >= timeout)
{
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogWarning((object)$"[SteamNameFetcher] Timeout waiting for Steam ID {steamId}");
}
onComplete?.Invoke(steamId, "Unknown");
}
}
private static IEnumerator FetchSteamNameCoroutine(ulong steamId, Action<ulong, string>? onComplete)
{
string url = $"https://steamcommunity.com/profiles/{steamId}";
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogInfo((object)$"[SteamNameFetcher] Fetching name for Steam ID: {steamId}");
}
UnityWebRequest request = UnityWebRequest.Get(url);
try
{
request.SetRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36");
yield return request.SendWebRequest();
string playerName = "Unknown";
if ((int)request.result == 1)
{
try
{
string html = request.downloadHandler.text;
int nameStart = html.IndexOf("<span class=\"actual_persona_name\">");
if (nameStart >= 0)
{
nameStart = html.IndexOf(">", nameStart) + 1;
int nameEnd3 = html.IndexOf("<", nameStart);
if (nameEnd3 > nameStart)
{
playerName = html.Substring(nameStart, nameEnd3 - nameStart).Trim();
playerName = DecodeHtmlEntities(playerName);
}
}
if ((playerName == "Unknown" || string.IsNullOrEmpty(playerName)) && nameStart < 0)
{
nameStart = html.IndexOf("<div class=\"persona_name\">");
if (nameStart >= 0)
{
nameStart = html.IndexOf(">", nameStart) + 1;
int nameEnd2 = html.IndexOf("<", nameStart);
if (nameEnd2 > nameStart)
{
playerName = html.Substring(nameStart, nameEnd2 - nameStart).Trim();
playerName = DecodeHtmlEntities(playerName);
}
}
}
if ((playerName == "Unknown" || string.IsNullOrEmpty(playerName)) && nameStart < 0)
{
nameStart = html.IndexOf("profile_header_actual_link");
if (nameStart >= 0)
{
nameStart = html.IndexOf(">", nameStart) + 1;
int nameEnd = html.IndexOf("<", nameStart);
if (nameEnd > nameStart)
{
playerName = html.Substring(nameStart, nameEnd - nameStart).Trim();
playerName = DecodeHtmlEntities(playerName);
}
}
}
if (string.IsNullOrWhiteSpace(playerName))
{
playerName = "Unknown";
}
}
catch (Exception ex2)
{
Exception ex = ex2;
ManualLogSource log2 = Plugin.Log;
if (log2 != null)
{
log2.LogError((object)$"[SteamNameFetcher] Error parsing HTML: {ex}");
}
playerName = "Unknown";
}
}
else
{
ManualLogSource log3 = Plugin.Log;
if (log3 != null)
{
log3.LogWarning((object)("[SteamNameFetcher] Failed to fetch Steam profile: " + request.error));
}
}
if (!string.IsNullOrEmpty(playerName) && playerName != "Unknown")
{
_nameCache[steamId] = playerName;
ManualLogSource log4 = Plugin.Log;
if (log4 != null)
{
log4.LogInfo((object)$"[SteamNameFetcher] Cached name for {steamId}: {playerName}");
}
}
_fetching[steamId] = false;
onComplete?.Invoke(steamId, playerName);
}
finally
{
((IDisposable)request)?.Dispose();
}
}
public static void FetchPlayerNameFromGameOrSteam(ulong steamId, Action<ulong, string>? onComplete = null)
{
string playerNameFromGame = GetPlayerNameFromGame(steamId);
if (!string.IsNullOrEmpty(playerNameFromGame) && playerNameFromGame != "Unknown")
{
_nameCache[steamId] = playerNameFromGame;
onComplete?.Invoke(steamId, playerNameFromGame);
}
else
{
FetchPlayerName(steamId, onComplete);
}
}
private static string GetPlayerNameFromGame(ulong steamId)
{
if ((Object)(object)NetworkManager.Singleton == (Object)null)
{
return "Unknown";
}
if (NetworkManager.Singleton.IsServer && NetworkManager.Singleton.ConnectedClients != null)
{
foreach (KeyValuePair<ulong, NetworkClient> connectedClient in NetworkManager.Singleton.ConnectedClients)
{
ulong key = connectedClient.Key;
ulong steamID = SteamIDHelper.GetSteamID(key);
if (steamID == steamId)
{
NetworkClient value = connectedClient.Value;
if ((Object)(object)value.PlayerObject != (Object)null)
{
string name = ((Object)value.PlayerObject).name;
if (name != null && !string.IsNullOrEmpty(name) && name != "Player")
{
return name;
}
break;
}
break;
}
}
}
PlayerControllerB[] array = Object.FindObjectsByType<PlayerControllerB>((FindObjectsSortMode)0);
PlayerControllerB[] array2 = array;
foreach (PlayerControllerB val in array2)
{
if ((Object)(object)val != (Object)null && val.actualClientId == steamId)
{
FieldInfo field = typeof(PlayerControllerB).GetField("playerUsername", BindingFlags.Instance | BindingFlags.Public);
if (field != null && field.GetValue(val) is string text && !string.IsNullOrEmpty(text))
{
return text;
}
if (!string.IsNullOrEmpty(((Object)val).name) && ((Object)val).name != "Player")
{
return ((Object)val).name;
}
}
}
return "Unknown";
}
public static string GetCachedName(ulong steamId)
{
string value;
return _nameCache.TryGetValue(steamId, out value) ? value : "Unknown";
}
public static void CacheName(ulong steamId, string name)
{
if (!string.IsNullOrEmpty(name) && name != "Unknown")
{
_nameCache[steamId] = name;
}
}
public static void ClearCache()
{
_nameCache.Clear();
_fetching.Clear();
}
private static string DecodeHtmlEntities(string html)
{
if (string.IsNullOrEmpty(html))
{
return html;
}
return html.Replace("&", "&").Replace("<", "<").Replace(">", ">")
.Replace(""", "\"")
.Replace("'", "'")
.Replace("'", "'")
.Replace(" ", " ");
}
}
public static class UIHelper
{
private class UIHelperBehaviour : MonoBehaviour
{
private void Update()
{
if (IsAnyUIOpen())
{
Cursor.visible = true;
Cursor.lockState = (CursorLockMode)0;
}
}
private void OnGUI()
{
_textInputActive = false;
Action[] array = _drawers.ToArray();
if (array.Length == 0)
{
return;
}
Cursor.visible = true;
Cursor.lockState = (CursorLockMode)0;
Action[] array2 = array;
foreach (Action action in array2)
{
try
{
action();
}
catch (Exception ex)
{
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogError((object)$"[UIHelper] Error in drawer: {ex}");
}
ManualLogSource log2 = Plugin.Log;
if (log2 != null)
{
log2.LogError((object)("[UIHelper] Stack trace: " + ex.StackTrace));
}
}
}
}
}
private static readonly List<Action> _drawers = new List<Action>();
private static UIHelperBehaviour? _behaviour;
private static bool _textInputActive = false;
public static void Register(Action draw)
{
EnsureInitialized();
if (!_drawers.Contains(draw))
{
_drawers.Add(draw);
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogInfo((object)$"[UIHelper] Registered drawer, total: {_drawers.Count}");
}
UpdateCursorState();
}
}
public static void Unregister(Action draw)
{
if (_drawers.Contains(draw))
{
_drawers.Remove(draw);
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogInfo((object)$"[UIHelper] Unregistered drawer, total: {_drawers.Count}");
}
UpdateCursorState();
}
}
public static bool IsAnyUIOpen()
{
return _drawers.Count > 0;
}
public static bool IsTextInputActive()
{
return _textInputActive;
}
public static void SetTextInputActive(bool active)
{
_textInputActive = active;
}
private static void UpdateCursorState()
{
if (!((Object)(object)_behaviour == (Object)null) && IsAnyUIOpen())
{
Cursor.visible = true;
Cursor.lockState = (CursorLockMode)0;
}
}
private static void EnsureInitialized()
{
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: Expected O, but got Unknown
if (!((Object)(object)_behaviour != (Object)null))
{
GameObject val = new GameObject("PastaUIHelper");
Object.DontDestroyOnLoad((Object)(object)val);
_behaviour = val.AddComponent<UIHelperBehaviour>();
((Object)val).hideFlags = (HideFlags)61;
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogInfo((object)"[UIHelper] UIHelper initialized");
}
}
}
}
public static class UIStyle
{
private static GUIStyle? _windowStyle;
private static GUIStyle? _labelStyle;
private static GUIStyle? _buttonStyle;
private static GUIStyle? _textFieldStyle;
private static GUIStyle? _boxStyle;
private static bool _stylesInitialized = false;
private static Dictionary<string, Texture2D> _textureCache = new Dictionary<string, Texture2D>();
public static GUIStyle WindowStyle
{
get
{
InitializeStyles();
return _windowStyle;
}
}
public static GUIStyle LabelStyle
{
get
{
InitializeStyles();
return _labelStyle;
}
}
public static GUIStyle ButtonStyle
{
get
{
InitializeStyles();
return _buttonStyle;
}
}
public static GUIStyle TextFieldStyle
{
get
{
InitializeStyles();
return _textFieldStyle;
}
}
public static GUIStyle BoxStyle
{
get
{
InitializeStyles();
return _boxStyle;
}
}
public static void InitializeStyles()
{
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_0038: 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_0062: Unknown result type (might be due to invalid IL or missing references)
//IL_0072: Unknown result type (might be due to invalid IL or missing references)
//IL_0078: Unknown result type (might be due to invalid IL or missing references)
//IL_0082: Expected O, but got Unknown
//IL_0083: Unknown result type (might be due to invalid IL or missing references)
//IL_008c: Unknown result type (might be due to invalid IL or missing references)
//IL_0096: Expected O, but got Unknown
//IL_009c: Expected O, but got Unknown
//IL_00a6: 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_00b1: Unknown result type (might be due to invalid IL or missing references)
//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
//IL_00da: Unknown result type (might be due to invalid IL or missing references)
//IL_00e4: Expected O, but got Unknown
//IL_00ea: Expected O, but got Unknown
//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
//IL_0113: Unknown result type (might be due to invalid IL or missing references)
//IL_0123: Unknown result type (might be due to invalid IL or missing references)
//IL_0129: Unknown result type (might be due to invalid IL or missing references)
//IL_0134: Unknown result type (might be due to invalid IL or missing references)
//IL_014e: Unknown result type (might be due to invalid IL or missing references)
//IL_015e: Unknown result type (might be due to invalid IL or missing references)
//IL_0164: Unknown result type (might be due to invalid IL or missing references)
//IL_016f: Unknown result type (might be due to invalid IL or missing references)
//IL_0189: 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_019f: Unknown result type (might be due to invalid IL or missing references)
//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
//IL_01c4: Expected O, but got Unknown
//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
//IL_01d2: Expected O, but got Unknown
//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
//IL_01fb: 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_0211: Unknown result type (might be due to invalid IL or missing references)
//IL_021c: Unknown result type (might be due to invalid IL or missing references)
//IL_0236: Unknown result type (might be due to invalid IL or missing references)
//IL_0246: Unknown result type (might be due to invalid IL or missing references)
//IL_024c: Unknown result type (might be due to invalid IL or missing references)
//IL_0257: Unknown result type (might be due to invalid IL or missing references)
//IL_025c: Unknown result type (might be due to invalid IL or missing references)
//IL_0266: Expected O, but got Unknown
//IL_0267: Unknown result type (might be due to invalid IL or missing references)
//IL_0275: Expected O, but got Unknown
//IL_027f: Unknown result type (might be due to invalid IL or missing references)
//IL_0284: Unknown result type (might be due to invalid IL or missing references)
//IL_029e: Unknown result type (might be due to invalid IL or missing references)
//IL_02ae: Unknown result type (might be due to invalid IL or missing references)
//IL_02b3: Unknown result type (might be due to invalid IL or missing references)
//IL_02bd: Expected O, but got Unknown
//IL_02be: Unknown result type (might be due to invalid IL or missing references)
//IL_02c3: Unknown result type (might be due to invalid IL or missing references)
//IL_02cd: Expected O, but got Unknown
//IL_02d3: Expected O, but got Unknown
if (!_stylesInitialized)
{
GUIStyle val = new GUIStyle(GUI.skin.window);
val.normal.background = CreateColorTexture(new Color(0.1f, 0.1f, 0.1f, 0.95f));
val.onNormal.background = CreateColorTexture(new Color(0.1f, 0.1f, 0.1f, 0.95f));
val.border = new RectOffset(8, 8, 20, 8);
val.padding = new RectOffset(10, 10, 25, 10);
_windowStyle = val;
GUIStyle val2 = new GUIStyle(GUI.skin.label);
val2.normal.textColor = Color.white;
val2.fontSize = 14;
val2.fontStyle = (FontStyle)0;
val2.alignment = (TextAnchor)3;
val2.padding = new RectOffset(5, 5, 5, 5);
_labelStyle = val2;
GUIStyle val3 = new GUIStyle(GUI.skin.button);
val3.normal.background = CreateColorTexture(new Color(0.2f, 0.2f, 0.2f, 1f));
val3.normal.textColor = Color.white;
val3.hover.background = CreateColorTexture(new Color(0.3f, 0.3f, 0.3f, 1f));
val3.hover.textColor = Color.white;
val3.active.background = CreateColorTexture(new Color(0.15f, 0.15f, 0.15f, 1f));
val3.active.textColor = Color.white;
val3.fontSize = 13;
val3.padding = new RectOffset(10, 10, 5, 5);
val3.alignment = (TextAnchor)4;
_buttonStyle = val3;
GUIStyle val4 = new GUIStyle(GUI.skin.textField);
val4.normal.background = CreateColorTexture(new Color(0.15f, 0.15f, 0.15f, 1f));
val4.normal.textColor = Color.white;
val4.focused.background = CreateColorTexture(new Color(0.2f, 0.2f, 0.2f, 1f));
val4.focused.textColor = Color.white;
val4.padding = new RectOffset(5, 5, 5, 5);
val4.fontSize = 12;
_textFieldStyle = val4;
GUIStyle val5 = new GUIStyle(GUI.skin.box);
val5.normal.background = CreateColorTexture(new Color(0.05f, 0.05f, 0.05f, 0.8f));
val5.border = new RectOffset(1, 1, 1, 1);
val5.padding = new RectOffset(5, 5, 5, 5);
_boxStyle = val5;
_stylesInitialized = true;
}
}
private static Texture2D CreateColorTexture(Color color)
{
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_001c: 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)
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_0080: Unknown result type (might be due to invalid IL or missing references)
//IL_0086: Expected O, but got Unknown
//IL_0089: Unknown result type (might be due to invalid IL or missing references)
string key = $"{color.r}_{color.g}_{color.b}_{color.a}";
if (_textureCache.TryGetValue(key, out Texture2D value))
{
if ((Object)(object)value != (Object)null)
{
return value;
}
_textureCache.Remove(key);
}
Texture2D val = new Texture2D(1, 1, (TextureFormat)4, false);
val.SetPixel(0, 0, color);
val.Apply();
((Object)val).hideFlags = (HideFlags)52;
_textureCache[key] = val;
return val;
}
public static void ResetStyles()
{
_stylesInitialized = false;
_windowStyle = null;
_labelStyle = null;
_buttonStyle = null;
_textFieldStyle = null;
_boxStyle = null;
foreach (Texture2D value in _textureCache.Values)
{
if ((Object)(object)value != (Object)null)
{
Object.Destroy((Object)(object)value);
}
}
_textureCache.Clear();
}
}
public static class MyPluginInfo
{
public const string PLUGIN_GUID = "PastaClient";
public const string PLUGIN_NAME = "PastaClient";
public const string PLUGIN_VERSION = "1.2.1";
}
}
namespace PastaClient.Patches
{
public class ChatCommandHandler : MonoBehaviour
{
private static ChatCommandHandler instance;
private TMP_InputField? chatInputField;
private string lastInput = "";
public static void Init()
{
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: Expected O, but got Unknown
if (!((Object)(object)instance != (Object)null))
{
GameObject val = new GameObject("ChatCommandHandler");
instance = val.AddComponent<ChatCommandHandler>();
Object.DontDestroyOnLoad((Object)(object)val);
((Object)val).hideFlags = (HideFlags)61;
}
}
private void Update()
{
if (!((Object)(object)HUDManager.Instance == (Object)null) && !((Object)(object)chatInputField != (Object)null))
{
FindChatInputField();
if ((Object)(object)chatInputField != (Object)null)
{
SubscribeToChatInput();
}
}
}
private void FindChatInputField()
{
FieldInfo[] fields = typeof(HUDManager).GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
FieldInfo[] array = fields;
foreach (FieldInfo fieldInfo in array)
{
object value = fieldInfo.GetValue(HUDManager.Instance);
TMP_InputField val = (TMP_InputField)((value is TMP_InputField) ? value : null);
if (val != null)
{
chatInputField = val;
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogInfo((object)("[ChatCommandHandler] Found chat input field: " + fieldInfo.Name));
}
break;
}
InputField val2 = (InputField)((value is InputField) ? value : null);
if (val2 != null)
{
ManualLogSource log2 = Plugin.Log;
if (log2 != null)
{
log2.LogInfo((object)("[ChatCommandHandler] Found UI InputField: " + fieldInfo.Name));
}
}
}
}
private void SubscribeToChatInput()
{
if (!((Object)(object)chatInputField == (Object)null))
{
((UnityEvent<string>)(object)chatInputField.onSubmit).AddListener((UnityAction<string>)OnChatSubmit);
((UnityEvent<string>)(object)chatInputField.onEndEdit).AddListener((UnityAction<string>)OnChatSubmit);
}
}
private void OnChatSubmit(string input)
{
if (!string.IsNullOrWhiteSpace(input) && !(input == lastInput))
{
input = input.Trim();
lastInput = input;
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogInfo((object)("[ChatCommandHandler] Chat submitted: " + input));
}
if (ProcessChatCommand(input) && (Object)(object)chatInputField != (Object)null)
{
chatInputField.text = "";
lastInput = "";
}
}
}
private bool ProcessChatCommand(string input)
{
if (input.StartsWith(":st", StringComparison.OrdinalIgnoreCase))
{
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogInfo((object)"[ChatCommandHandler] :st command detected");
}
ShitterUI.Open();
return true;
}
if (input.StartsWith(":who", StringComparison.OrdinalIgnoreCase))
{
ManualLogSource log2 = Plugin.Log;
if (log2 != null)
{
log2.LogInfo((object)"[ChatCommandHandler] :who command detected");
}
RecentUI.Open();
return true;
}
return false;
}
}
[HarmonyPatch(typeof(PlayerControllerB), "Update")]
public class PlayerInputPatch
{
private static void Prefix(PlayerControllerB __instance, ref bool ___isPlayerDead, ref bool ___isTypingChat)
{
}
}
[HarmonyPatch(typeof(Input), "GetAxis", new Type[] { typeof(string) })]
public class InputPatch
{
private static bool Prefix(string axisName, ref float __result)
{
if (UIHelper.IsTextInputActive())
{
__result = 0f;
return false;
}
if (UIHelper.IsAnyUIOpen() && (axisName == "Mouse X" || axisName == "Mouse Y"))
{
__result = 0f;
return false;
}
return true;
}
}
[HarmonyPatch(typeof(Input), "GetKey", new Type[] { typeof(KeyCode) })]
public class InputGetKeyPatch
{
private static bool Prefix(KeyCode key, ref bool __result)
{
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Invalid comparison between Unknown and I4
if (UIHelper.IsTextInputActive() && (int)key != 27)
{
__result = false;
return false;
}
return true;
}
}
}
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
internal sealed class IgnoresAccessChecksToAttribute : Attribute
{
public IgnoresAccessChecksToAttribute(string assemblyName)
{
}
}
}