using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using ExitGames.Client.Photon;
using HarmonyLib;
using PeakVoiceFix.Patches;
using Photon.Pun;
using Photon.Realtime;
using Photon.Voice.PUN;
using Photon.Voice.Unity;
using Steamworks;
using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("BetterVoiceFix")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("0.3.0.0")]
[assembly: AssemblyInformationalVersion("0.3.0+bb251e0d88dcb3522b334cc324b38508656edd8a")]
[assembly: AssemblyProduct("BetterVoiceFix")]
[assembly: AssemblyTitle("BetterVoiceFix")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.3.0.0")]
[module: UnverifiableCode]
namespace PeakVoiceFix
{
public class CacheEntry
{
public string IP;
public float LastSeenTime;
public string PlayerName;
public byte RemoteState;
public string ModVersion;
}
public class SOSData
{
public int ActorNumber;
public string PlayerName;
public string TargetIP;
public string OriginIP;
public float ReceiveTime;
}
public static class NetworkManager
{
public static Dictionary<int, CacheEntry> PlayerCache = new Dictionary<int, CacheEntry>();
public static List<SOSData> ActiveSOSList = new List<SOSData>();
public static List<string> HostHistory = new List<string>();
private static string LastKnownHostIP = "";
private static string LastDecisionLog = "";
private static ClientState lastClientState = (ClientState)14;
public static PunVoiceClient punVoice;
private static float nextRetryTime = 0f;
private static float lastPingPublishTime = 0f;
private static float lastSOSTime = 0f;
private static float nextSummaryLogTime = 0f;
private const float SCAN_INTERVAL = 30f;
private const float CACHE_TTL = 180f;
private const float PING_PUBLISH_INTERVAL = 89f;
private const string PROP_IP = "PVF_IP";
private const string PROP_PING = "PVF_Ping";
private const byte TYPE_SOS = 0;
private const byte TYPE_LOG = 1;
private const byte TYPE_STATE = 2;
public static string TargetGameServer { get; private set; }
public static bool ConnectedUsingHost { get; private set; } = true;
public static bool IsBlindConnect { get; private set; } = false;
public static int WrongIPCount { get; private set; } = 0;
public static int ConnectionFailCount { get; private set; } = 0;
public static int TotalRetryCount { get; private set; } = 0;
public static string LastErrorMessage { get; private set; } = "";
public static float LastScanTime { get; private set; } = 0f;
public static float LastHostUpdateTime { get; private set; } = 0f;
public static string GetPlayerName(int actorNumber)
{
//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
string text = "Unknown";
Player val = null;
if (PhotonNetwork.CurrentRoom != null)
{
val = PhotonNetwork.CurrentRoom.GetPlayer(actorNumber, false);
}
if (val != null && !string.IsNullOrEmpty(val.NickName))
{
text = val.NickName;
UpdatePlayerCache(actorNumber, text);
return text;
}
if (PlayerCache.ContainsKey(actorNumber))
{
string playerName = PlayerCache[actorNumber].PlayerName;
if (!string.IsNullOrEmpty(playerName) && playerName != "Unknown" && !playerName.StartsWith("Player "))
{
return playerName;
}
}
if ((text == "Unknown" || string.IsNullOrEmpty(text)) && val != null && !string.IsNullOrEmpty(val.UserId))
{
try
{
if (ulong.TryParse(val.UserId, out var result))
{
string friendPersonaName = SteamFriends.GetFriendPersonaName(new CSteamID(result));
if (!string.IsNullOrEmpty(friendPersonaName) && friendPersonaName != "[unknown]")
{
text = friendPersonaName;
UpdatePlayerCache(actorNumber, text);
return text;
}
}
}
catch (Exception)
{
}
}
if (text == "Unknown" || string.IsNullOrEmpty(text))
{
string text2 = ScavengeNameFromScene(actorNumber);
if (!string.IsNullOrEmpty(text2))
{
UpdatePlayerCache(actorNumber, text2);
return text2;
}
}
if (text == "Unknown")
{
return $"Player {actorNumber}";
}
return text;
}
public static string ScavengeNameFromScene(int actorNumber)
{
try
{
PhotonView[] array = Object.FindObjectsOfType<PhotonView>();
PhotonView[] array2 = array;
foreach (PhotonView val in array2)
{
if (!((Object)(object)val == (Object)null) && val.OwnerActorNr == actorNumber)
{
if (val.Owner != null && !string.IsNullOrEmpty(val.Owner.NickName))
{
return val.Owner.NickName;
}
TextMeshProUGUI componentInChildren = ((Component)val).GetComponentInChildren<TextMeshProUGUI>(true);
if ((Object)(object)componentInChildren != (Object)null && !string.IsNullOrEmpty(((TMP_Text)componentInChildren).text))
{
return ((TMP_Text)componentInChildren).text;
}
TextMeshPro componentInChildren2 = ((Component)val).GetComponentInChildren<TextMeshPro>(true);
if ((Object)(object)componentInChildren2 != (Object)null && !string.IsNullOrEmpty(((TMP_Text)componentInChildren2).text))
{
return ((TMP_Text)componentInChildren2).text;
}
Text componentInChildren3 = ((Component)val).GetComponentInChildren<Text>(true);
if ((Object)(object)componentInChildren3 != (Object)null && !string.IsNullOrEmpty(componentInChildren3.text))
{
return componentInChildren3.text;
}
}
}
}
catch (Exception)
{
}
return null;
}
public static void UpdatePlayerCache(int actorNumber, string name, string ip = null, string version = null)
{
if (!PlayerCache.ContainsKey(actorNumber))
{
PlayerCache[actorNumber] = new CacheEntry();
}
if (!string.IsNullOrEmpty(name) && name != "Unknown")
{
PlayerCache[actorNumber].PlayerName = name;
}
if (!string.IsNullOrEmpty(ip))
{
PlayerCache[actorNumber].IP = ip;
}
if (!string.IsNullOrEmpty(version))
{
PlayerCache[actorNumber].ModVersion = version;
}
PlayerCache[actorNumber].LastSeenTime = Time.unscaledTime;
}
public static bool IsGhost(int actorNumber)
{
if (PhotonNetwork.CurrentRoom == null)
{
return true;
}
return PhotonNetwork.CurrentRoom.GetPlayer(actorNumber, false) == null;
}
public static int GetGhostCount()
{
if ((Object)(object)punVoice == (Object)null || ((VoiceConnection)punVoice).Client == null || ((LoadBalancingClient)((VoiceConnection)punVoice).Client).CurrentRoom == null)
{
return 0;
}
int num = 0;
foreach (int key in ((LoadBalancingClient)((VoiceConnection)punVoice).Client).CurrentRoom.Players.Keys)
{
if (IsGhost(key))
{
num++;
}
}
return num;
}
public static void SystemUpdate()
{
//IL_0072: 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_0079: Unknown result type (might be due to invalid IL or missing references)
//IL_007b: Unknown result type (might be due to invalid IL or missing references)
//IL_0091: Unknown result type (might be due to invalid IL or missing references)
//IL_009b: 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_00b9: Unknown result type (might be due to invalid IL or missing references)
//IL_00bd: Invalid comparison between Unknown and I4
//IL_00d3: 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)
if ((Object)(object)punVoice == (Object)null)
{
GameObject val = GameObject.Find("VoiceClient");
if ((Object)(object)val != (Object)null)
{
punVoice = val.GetComponent<PunVoiceClient>();
}
}
if (!PhotonNetwork.InRoom)
{
return;
}
if ((Object)(object)punVoice != (Object)null && ((VoiceConnection)punVoice).Client != null)
{
ClientState state = ((LoadBalancingClient)((VoiceConnection)punVoice).Client).State;
if (state != lastClientState)
{
string message = $"状态变更: {lastClientState} -> {state}";
BroadcastLog(message);
SendStateSync(state);
if ((int)state == 9)
{
ConnectionFailCount = 0;
}
UpdateDataLayer(force: true);
lastClientState = state;
}
}
UpdateDataLayer();
HandleInputAndState();
ManageSOSList();
if ((Object)(object)punVoice != (Object)null && ((VoiceConnection)punVoice).Client != null && Time.unscaledTime >= nextRetryTime)
{
if (PhotonNetwork.IsMasterClient)
{
HandleHostLogic();
}
else
{
HandleClientLogic();
}
}
}
public static void SendStateSync(ClientState state)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//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)
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_0032: Expected O, but got Unknown
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
byte b = (byte)state;
object[] array = new object[3]
{
(byte)2,
b,
"v0.3.4"
};
RaiseEventOptions val = new RaiseEventOptions
{
Receivers = (ReceiverGroup)0
};
PhotonNetwork.RaiseEvent((byte)186, (object)array, val, SendOptions.SendUnreliable);
}
public static void BroadcastLog(string message)
{
//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)
//IL_0077: Unknown result type (might be due to invalid IL or missing references)
//IL_007d: Expected O, but got Unknown
//IL_0080: Unknown result type (might be due to invalid IL or missing references)
if (VoiceFix.EnableDebugLogs != null && VoiceFix.EnableDebugLogs.Value)
{
VoiceFix.logger.LogInfo((object)message);
}
string playerName = GetPlayerName(PhotonNetwork.LocalPlayer.ActorNumber);
if ((Object)(object)VoiceUIManager.Instance != (Object)null)
{
VoiceUIManager.Instance.AddLog(playerName, message, isLocal: true);
}
byte b = 186;
object[] array = new object[2]
{
(byte)1,
message
};
RaiseEventOptions val = new RaiseEventOptions
{
Receivers = (ReceiverGroup)0
};
PhotonNetwork.RaiseEvent(b, (object)array, val, SendOptions.SendReliable);
}
private static void UpdateDataLayer(bool force = false)
{
//IL_0048: Unknown result type (might be due to invalid IL or missing references)
//IL_004e: Expected O, but got Unknown
//IL_006e: Unknown result type (might be due to invalid IL or missing references)
//IL_0075: Invalid comparison between Unknown and I4
bool flag = Time.unscaledTime - lastPingPublishTime > 89f;
if ((force || flag) && (Object)(object)punVoice != (Object)null && ((VoiceConnection)punVoice).Client != null)
{
lastPingPublishTime = Time.unscaledTime;
Hashtable val = new Hashtable();
val[(object)"PVF_Ping"] = PhotonNetwork.GetPing();
string ip = (string)(val[(object)"PVF_IP"] = (((int)((LoadBalancingClient)((VoiceConnection)punVoice).Client).State == 9) ? ((LoadBalancingClient)((VoiceConnection)punVoice).Client).GameServerAddress : ""));
PhotonNetwork.LocalPlayer.SetCustomProperties(val, (Hashtable)null, (WebFlags)null);
UpdatePlayerCache(PhotonNetwork.LocalPlayer.ActorNumber, PhotonNetwork.LocalPlayer.NickName, ip, "v0.3.4");
}
if (!force)
{
if (Time.unscaledTime - LastScanTime > 30f)
{
LastScanTime = Time.unscaledTime;
ScanPlayers();
}
if (Time.unscaledTime > nextSummaryLogTime)
{
PrintSummaryLog();
nextSummaryLogTime = Time.unscaledTime + 60f;
}
}
}
private static void PrintSummaryLog()
{
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.AppendLine($"[缓存快照] 记录数:{PlayerCache.Count}");
foreach (KeyValuePair<int, CacheEntry> item in PlayerCache)
{
string arg = (string.IsNullOrEmpty(item.Value.IP) ? "N/A" : item.Value.IP);
stringBuilder.AppendLine($" - {item.Value.PlayerName}: {arg} (St:{item.Value.RemoteState})");
}
if ((Object)(object)VoiceUIManager.Instance != (Object)null)
{
VoiceUIManager.Instance.AddLog("System", stringBuilder.ToString(), isLocal: true);
}
}
private static void ScanPlayers()
{
Player[] playerListOthers = PhotonNetwork.PlayerListOthers;
foreach (Player val in playerListOthers)
{
object value = null;
if (!((Dictionary<object, object>)(object)val.CustomProperties).TryGetValue((object)"PVF_IP", out value) || !(value is string text))
{
continue;
}
string playerName = GetPlayerName(val.ActorNumber);
UpdatePlayerCache(val.ActorNumber, playerName, text);
if (!val.IsMasterClient)
{
continue;
}
if (!string.IsNullOrEmpty(text))
{
LastHostUpdateTime = Time.unscaledTime;
}
if (!string.IsNullOrEmpty(LastKnownHostIP) && LastKnownHostIP != text && !string.IsNullOrEmpty(text))
{
string message = "房主IP变动: " + LastKnownHostIP + " -> " + text;
BroadcastLog(message);
if (HostHistory.Count > 5)
{
HostHistory.RemoveAt(0);
}
HostHistory.Add($"[{DateTime.Now:HH:mm:ss}] {text}");
}
LastKnownHostIP = text;
}
List<int> list = (from x in PlayerCache
where Time.unscaledTime - x.Value.LastSeenTime > 180f
select x.Key).ToList();
foreach (int item in list)
{
PlayerCache.Remove(item);
}
}
private static void ManageSOSList()
{
for (int num = ActiveSOSList.Count - 1; num >= 0; num--)
{
SOSData sOSData = ActiveSOSList[num];
if (Time.unscaledTime - sOSData.ReceiveTime > 60f)
{
ActiveSOSList.RemoveAt(num);
}
else if (GetPlayerName(sOSData.ActorNumber) == "Unknown")
{
ActiveSOSList.RemoveAt(num);
}
else
{
Player player = PhotonNetwork.CurrentRoom.GetPlayer(sOSData.ActorNumber, false);
object value = null;
if (player != null && ((Dictionary<object, object>)(object)player.CustomProperties).TryGetValue((object)"PVF_IP", out value) && value is string value2 && !string.IsNullOrEmpty(value2))
{
ActiveSOSList.RemoveAt(num);
}
}
}
}
private static void HandleHostLogic()
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: Invalid comparison between Unknown and I4
if ((int)((LoadBalancingClient)((VoiceConnection)punVoice).Client).State == 14)
{
BroadcastLog("[Host] 房主意外断开,正在自动恢复...");
((VoiceConnection)punVoice).ConnectUsingSettings(PhotonNetwork.PhotonServerSettings.AppSettings);
nextRetryTime = Time.unscaledTime + 5f;
}
}
private static void HandleClientLogic()
{
//IL_00d0: 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_00d6: Unknown result type (might be due to invalid IL or missing references)
//IL_00d9: Invalid comparison between Unknown and I4
//IL_0087: Unknown result type (might be due to invalid IL or missing references)
//IL_008e: Invalid comparison between Unknown and I4
//IL_018e: Unknown result type (might be due to invalid IL or missing references)
//IL_0191: Invalid comparison between Unknown and I4
string mode;
string text = DecideTargetIP(out mode);
if (!string.IsNullOrEmpty(text) && ConnectionFailCount > 0 && ConnectionFailCount % 6 >= 3)
{
BroadcastLog($"[循环] 已失败{ConnectionFailCount}次,暂时切换为盲连...");
text = null;
mode += "->BlindLoop";
}
if (string.IsNullOrEmpty(text))
{
IsBlindConnect = true;
TargetGameServer = null;
if ((int)((LoadBalancingClient)((VoiceConnection)punVoice).Client).State == 14)
{
PerformReconnect("Blind");
}
return;
}
IsBlindConnect = false;
TargetGameServer = text;
string gameServerAddress = ((LoadBalancingClient)((VoiceConnection)punVoice).Client).GameServerAddress;
ClientState state = ((LoadBalancingClient)((VoiceConnection)punVoice).Client).State;
if ((int)state == 9)
{
if (gameServerAddress == TargetGameServer)
{
WrongIPCount = 0;
ConnectionFailCount = 0;
TotalRetryCount = 0;
return;
}
WrongIPCount++;
if (WrongIPCount <= 2)
{
BroadcastLog($"[异频] 当前:{gameServerAddress} 目标:{TargetGameServer} | 纠正({WrongIPCount}/2)");
((LoadBalancingClient)((VoiceConnection)punVoice).Client).Disconnect();
PerformReconnect(mode);
}
else if (WrongIPCount == 3)
{
BroadcastLog("[妥协] 纠正失败,驻留当前IP: " + gameServerAddress);
}
}
else if ((int)state == 14)
{
ConnectionFailCount++;
PerformReconnect(mode);
}
}
private static void SetGameServerAddress(LoadBalancingClient client, string ip)
{
try
{
BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
PropertyInfo property = ((object)client).GetType().GetProperty("GameServerAddress", bindingAttr);
if (property != null && property.CanWrite)
{
property.SetValue(client, ip);
return;
}
Type type = ((object)client).GetType();
while (type != null)
{
FieldInfo field = type.GetField("GameServerAddress", bindingAttr);
if (field == null)
{
field = type.GetField("<GameServerAddress>k__BackingField", bindingAttr);
}
if (field != null)
{
field.SetValue(client, ip);
return;
}
type = type.BaseType;
}
if (VoiceFix.logger != null)
{
VoiceFix.logger.LogError((object)"无法反射设置 IP");
}
}
catch (Exception arg)
{
if (VoiceFix.logger != null)
{
VoiceFix.logger.LogError((object)$"反射失败: {arg}");
}
}
}
private static string DecideTargetIP(out string mode)
{
int maxCount;
string majorityIP = GetMajorityIP(out maxCount);
if (!string.IsNullOrEmpty(majorityIP) && maxCount >= 2)
{
mode = $"多数派({maxCount}人)";
ConnectedUsingHost = false;
LogDecision(mode, majorityIP);
return majorityIP;
}
if (!string.IsNullOrEmpty(LastKnownHostIP))
{
mode = "房主";
ConnectedUsingHost = true;
LogDecision(mode, LastKnownHostIP);
return LastKnownHostIP;
}
mode = "自动(盲连)";
ConnectedUsingHost = false;
LogDecision(mode, "Auto");
return null;
}
private static void LogDecision(string mode, string target)
{
string text = mode + "->" + target;
if (text != LastDecisionLog)
{
BroadcastLog("[决策] 目标变更: " + text);
LastDecisionLog = text;
}
}
public static string GetMajorityIP(out int maxCount)
{
maxCount = 0;
if (PlayerCache.Count == 0)
{
return null;
}
Dictionary<string, int> dictionary = new Dictionary<string, int>();
foreach (KeyValuePair<int, CacheEntry> item in PlayerCache)
{
if (!string.IsNullOrEmpty(item.Value.IP))
{
if (!dictionary.ContainsKey(item.Value.IP))
{
dictionary[item.Value.IP] = 0;
}
dictionary[item.Value.IP]++;
}
}
string result = null;
foreach (KeyValuePair<string, int> item2 in dictionary)
{
if (item2.Value > maxCount)
{
maxCount = item2.Value;
result = item2.Key;
}
}
return result;
}
private static void PerformReconnect(string mode)
{
//IL_0075: Unknown result type (might be due to invalid IL or missing references)
//IL_007c: Invalid comparison between Unknown and I4
TotalRetryCount++;
nextRetryTime = Time.unscaledTime + VoiceFix.RetryInterval.Value;
if (Time.unscaledTime - lastSOSTime > 20f && PhotonNetwork.IsConnectedAndReady)
{
lastSOSTime = Time.unscaledTime;
SendSOS(string.IsNullOrEmpty(TargetGameServer) ? "Unknown" : TargetGameServer);
}
if ((int)((LoadBalancingClient)((VoiceConnection)punVoice).Client).State != 14)
{
((LoadBalancingClient)((VoiceConnection)punVoice).Client).Disconnect();
}
SetGameServerAddress((LoadBalancingClient)(object)((VoiceConnection)punVoice).Client, TargetGameServer);
((VoiceConnection)punVoice).ConnectUsingSettings(PhotonNetwork.PhotonServerSettings.AppSettings);
}
private static void SendSOS(string targetInfo)
{
//IL_0079: Unknown result type (might be due to invalid IL or missing references)
//IL_007e: 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_008d: Unknown result type (might be due to invalid IL or missing references)
string text = "Unknown";
if ((Object)(object)punVoice != (Object)null && ((VoiceConnection)punVoice).Client != null)
{
text = ((LoadBalancingClient)((VoiceConnection)punVoice).Client).GameServerAddress;
}
if (string.IsNullOrEmpty(text))
{
text = "Disconnected";
}
BroadcastLog("[SOS] 发送求救 -> 目标:" + targetInfo + " | 本机:" + text);
object[] array = new object[3]
{
(byte)0,
targetInfo,
text
};
RaiseEventOptions val = new RaiseEventOptions
{
Receivers = (ReceiverGroup)0
};
PhotonNetwork.RaiseEvent((byte)186, (object)array, val, SendOptions.SendReliable);
}
public static void OnEvent(EventData photonEvent)
{
if (photonEvent.Code != 186)
{
return;
}
int senderActor = photonEvent.Sender;
string playerName = GetPlayerName(senderActor);
if (!(photonEvent.CustomData is object[] array) || array.Length < 2)
{
return;
}
byte b = 0;
if (array[0] is byte b2)
{
b = b2;
}
else if (array[0] is int num)
{
b = (byte)num;
}
switch (b)
{
case 1:
{
string msg = array[1] as string;
if ((Object)(object)VoiceUIManager.Instance != (Object)null)
{
VoiceUIManager.Instance.AddLog(playerName, msg, isLocal: false);
}
break;
}
case 0:
{
string text3 = array[1] as string;
string originIP = "未知(旧版)";
if (array.Length >= 3 && array[2] is string text4)
{
originIP = text4;
}
else if (PlayerCache.ContainsKey(senderActor))
{
originIP = PlayerCache[senderActor].IP;
}
ActiveSOSList.RemoveAll((SOSData x) => x.ActorNumber == senderActor);
ActiveSOSList.Add(new SOSData
{
ActorNumber = senderActor,
PlayerName = playerName,
TargetIP = text3,
OriginIP = originIP,
ReceiveTime = Time.unscaledTime
});
if ((Object)(object)VoiceUIManager.Instance != (Object)null)
{
VoiceUIManager.Instance.AddLog("System", "收到 " + playerName + " SOS (目标:" + text3 + ")", isLocal: true);
VoiceUIManager.Instance.TriggerNotification(playerName);
}
break;
}
case 2:
{
byte remoteState = 0;
if (array[1] is byte b3)
{
remoteState = b3;
}
else if (array[1] is int num2)
{
remoteState = (byte)num2;
}
string text = "";
if (array.Length >= 3 && array[2] is string text2)
{
text = text2;
}
if (PlayerCache.ContainsKey(senderActor))
{
PlayerCache[senderActor].RemoteState = remoteState;
if (!string.IsNullOrEmpty(text))
{
PlayerCache[senderActor].ModVersion = text;
}
PlayerCache[senderActor].LastSeenTime = Time.unscaledTime;
}
else
{
CacheEntry value = new CacheEntry
{
PlayerName = playerName,
LastSeenTime = Time.unscaledTime,
RemoteState = remoteState,
ModVersion = text
};
PlayerCache[senderActor] = value;
}
break;
}
}
}
private static void HandleInputAndState()
{
//IL_0048: Unknown result type (might be due to invalid IL or missing references)
//IL_004f: Invalid comparison between Unknown and I4
//IL_005b: Unknown result type (might be due to invalid IL or missing references)
//IL_0061: Invalid comparison between Unknown and I4
//IL_006d: Unknown result type (might be due to invalid IL or missing references)
//IL_0073: Invalid comparison between Unknown and I4
if (VoiceFix.EnableManualReconnect == null || !VoiceFix.EnableManualReconnect.Value || (!Input.GetKey((KeyCode)308) && !Input.GetKey((KeyCode)307)) || !Input.GetKeyDown((KeyCode)107))
{
return;
}
if ((int)((LoadBalancingClient)((VoiceConnection)punVoice).Client).State == 9 || (int)((LoadBalancingClient)((VoiceConnection)punVoice).Client).State == 6 || (int)((LoadBalancingClient)((VoiceConnection)punVoice).Client).State == 1)
{
BroadcastLog("[系统] Alt+K 手动断开");
if (PhotonNetwork.IsConnectedAndReady)
{
SendSOS("手动断开 (Manual)");
}
((LoadBalancingClient)((VoiceConnection)punVoice).Client).Disconnect();
if ((Object)(object)VoiceUIManager.Instance != (Object)null)
{
VoiceUIManager.Instance.ShowStatsTemporary();
}
}
else
{
BroadcastLog("[系统] Alt+K 强制重连");
if (PhotonNetwork.IsMasterClient)
{
int maxCount;
string majorityIP = GetMajorityIP(out maxCount);
string ip = ((!string.IsNullOrEmpty(majorityIP) && maxCount >= 2) ? majorityIP : null);
SetGameServerAddress((LoadBalancingClient)(object)((VoiceConnection)punVoice).Client, ip);
}
string targetGameServer = TargetGameServer;
if (string.IsNullOrEmpty(targetGameServer))
{
targetGameServer = "Auto/Blind";
}
nextRetryTime = Time.unscaledTime;
ConnectionFailCount = 0;
((VoiceConnection)punVoice).ConnectUsingSettings(PhotonNetwork.PhotonServerSettings.AppSettings);
}
WrongIPCount = 0;
TotalRetryCount = 0;
}
}
[HarmonyPatch]
public static class PhotonRPCFix
{
[HarmonyPatch(typeof(PhotonNetwork), "RPC", new Type[]
{
typeof(PhotonView),
typeof(string),
typeof(RpcTarget),
typeof(Player),
typeof(bool),
typeof(object[])
})]
[HarmonyPrefix]
public static void PrePhotonNetworkRPC(PhotonView view, string methodName, ref RpcTarget target)
{
if (VoiceFix.EnableDebugLogs != null && VoiceFix.EnableDebugLogs.Value && !methodName.Contains("Transform") && !methodName.Contains("Movement") && !methodName.Contains("Time") && !methodName.Contains("Speak") && VoiceFix.logger != null)
{
VoiceFix.logger.LogWarning((object)$"[RPC捕捉] Name: {methodName} | Target: {target}");
}
}
}
[BepInPlugin("chuxiaaaa.Aiae.BetterVoiceFix", "BetterVoiceFix", "0.3.4")]
public class VoiceFix : BaseUnityPlugin
{
public static VoiceFix Instance;
public static ManualLogSource logger;
public static ManualLogSource debugLogger;
public static ConfigEntry<string> UIPositionSide;
public static ConfigEntry<KeyCode> ToggleUIKey;
public static ConfigEntry<bool> ShowProfessionalInfo;
public static ConfigEntry<float> OffsetX_Right;
public static ConfigEntry<float> OffsetY_Right;
public static ConfigEntry<float> OffsetX_Left;
public static ConfigEntry<float> OffsetY_Left;
public static ConfigEntry<float> FontSize;
public static ConfigEntry<string> HostSymbol;
public static ConfigEntry<float> ConnectTimeout;
public static ConfigEntry<float> RetryInterval;
public static ConfigEntry<bool> EnableManualReconnect;
public static ConfigEntry<bool> EnableGhostFix;
public static ConfigEntry<int> MaxTotalLength;
public static ConfigEntry<float> LatencyOffset;
public static ConfigEntry<bool> AutoHideNormal;
public static ConfigEntry<bool> ShowPingInNormal;
public static ConfigEntry<bool> HideOnMenu;
public static ConfigEntry<bool> EnableDebugLogs;
public static ConfigEntry<bool> EnableVirtualTestPlayer;
public static ConfigEntry<string> TestPlayerName;
public const string MOD_VERSION = "v0.3.4";
private void Awake()
{
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_0021: Expected O, but got Unknown
//IL_006d: Unknown result type (might be due to invalid IL or missing references)
//IL_0077: Expected O, but got Unknown
//IL_021a: Unknown result type (might be due to invalid IL or missing references)
//IL_0224: Expected O, but got Unknown
Instance = this;
logger = ((BaseUnityPlugin)this).Logger;
debugLogger = new ManualLogSource("VoiceFixDebug");
Logger.Sources.Add((ILogSource)(object)debugLogger);
string text = "UI设置";
UIPositionSide = ((BaseUnityPlugin)this).Config.Bind<string>(text, "UI位置", "右侧", new ConfigDescription("选择UI面板显示在屏幕的哪一侧。", (AcceptableValueBase)(object)new AcceptableValueList<string>(new string[2] { "左侧", "右侧" }), Array.Empty<object>()));
ToggleUIKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>(text, "开关快捷键", (KeyCode)106, "切换语音面板显示的按键。");
ShowProfessionalInfo = ((BaseUnityPlugin)this).Config.Bind<bool>(text, "显示详细IP信息", true, "是否在面板中显示具体的IP地址和调试信息。");
OffsetX_Right = ((BaseUnityPlugin)this).Config.Bind<float>(text, "右侧边距", 20f, "距离屏幕右边缘的水平距离。");
OffsetY_Right = ((BaseUnityPlugin)this).Config.Bind<float>(text, "顶部边距(右)", 20f, "距离屏幕上边缘的垂直距离。");
OffsetX_Left = ((BaseUnityPlugin)this).Config.Bind<float>(text, "左侧边距", 20f, "距离屏幕左边缘的水平距离。");
OffsetY_Left = ((BaseUnityPlugin)this).Config.Bind<float>(text, "顶部边距(左)", 20f, "距离屏幕上边缘的垂直距离。");
FontSize = ((BaseUnityPlugin)this).Config.Bind<float>(text, "字体大小", 21f, "面板文字的基础大小。");
HostSymbol = ((BaseUnityPlugin)this).Config.Bind<string>(text, "房主标记符号", "★", "显示在房主名字前的特殊符号。");
string text2 = "网络设置";
ConnectTimeout = ((BaseUnityPlugin)this).Config.Bind<float>(text2, "重连超时时间 (s)", 25f, "如果连接卡住,超过多少秒判定为断开。");
RetryInterval = ((BaseUnityPlugin)this).Config.Bind<float>(text2, "重试间隔 (s)", 8f, "每次自动重连之间的冷却时间。");
EnableManualReconnect = ((BaseUnityPlugin)this).Config.Bind<bool>(text2, "启用手动重置 (Alt+K)", true, "允许按 Alt+K 强制断开或重连语音。");
EnableGhostFix = ((BaseUnityPlugin)this).Config.Bind<bool>(text2, "启用ID漂移修复", true, "尝试从场景中搜寻名字以修复 Unknown 问题。");
string text3 = "高级与调试";
MaxTotalLength = ((BaseUnityPlugin)this).Config.Bind<int>(text3, "最大名字长度", 26, new ConfigDescription("显示名字的最大字符数。", (AcceptableValueBase)(object)new AcceptableValueRange<int>(10, 60), Array.Empty<object>()));
LatencyOffset = ((BaseUnityPlugin)this).Config.Bind<float>(text3, "延迟对齐偏移量", 350f, "Ping值显示的水平像素偏移。");
AutoHideNormal = ((BaseUnityPlugin)this).Config.Bind<bool>(text3, "自动隐藏简易UI", true, "当所有人连接正常时,自动隐藏简易模式的UI。");
ShowPingInNormal = ((BaseUnityPlugin)this).Config.Bind<bool>(text3, "简易模式显示Ping", true, "在简易模式下方显示本机延迟。");
HideOnMenu = ((BaseUnityPlugin)this).Config.Bind<bool>(text3, "菜单时隐藏", true, "打开ESC菜单时隐藏UI。");
EnableDebugLogs = ((BaseUnityPlugin)this).Config.Bind<bool>(text3, "启用调试日志", false, "在控制台输出详细的网络日志。");
EnableVirtualTestPlayer = ((BaseUnityPlugin)this).Config.Bind<bool>(text3, "启用虚拟玩家", false, "添加一个假玩家用于测试UI布局。");
TestPlayerName = ((BaseUnityPlugin)this).Config.Bind<string>(text3, "虚拟玩家名字", "1234567891012141618202224262830323436", "假玩家的名字。");
Harmony.CreateAndPatchAll(typeof(LoadBalancingClientPatch), (string)null);
Harmony.CreateAndPatchAll(typeof(PhotonRPCFix), (string)null);
VoiceUIManager.CreateGlobalInstance();
logger.LogInfo((object)"Better Voice Fix (v0.3.4) 已加载。");
}
private void Update()
{
NetworkManager.SystemUpdate();
}
}
public class VoiceUIManager : MonoBehaviour
{
private struct LogEntry
{
public string Time;
public string Player;
public string Msg;
public bool IsLocal;
}
private class PlayerRenderData
{
public string Name;
public string IP;
public int Ping;
public bool IsLocal;
public bool IsHost;
public bool IsAlive;
public bool HasModData;
public bool IsInVoiceRoom;
public int ActorNumber;
public byte RemoteState;
}
public static VoiceUIManager Instance;
public TextMeshProUGUI statsText;
private Canvas myCanvas;
private bool showDebugConsole = false;
private Rect debugWindowRect = new Rect(20f, 20f, 600f, 400f);
private Vector2 debugScrollPosition;
private Vector2 filterScrollPosition;
private List<LogEntry> debugLogs = new List<LogEntry>();
private int logFilterMode = 0;
private int targetActorNumber = -1;
private bool isResizing = false;
private Rect resizeHandleRect;
private Dictionary<int, float> joinTimes = new Dictionary<int, float>();
private const string C_GREEN = "#90EE90";
private const string C_PALE_GREEN = "#98FB98";
private const string C_YELLOW = "#F0E68C";
private const string C_RED = "#FF6961";
private const string C_LOW_SAT_RED = "#CD5C5C";
private const string C_TEXT = "#dfdac2";
private const string C_GREY = "#808080";
private const string C_GOLD = "#ffd700";
private const string C_GHOST_GREEN = "#b2d3b2";
private float nextUiUpdateTime = 0f;
private bool isDetailMode = false;
private float detailModeExpiry = 0f;
private float lastFontRetryTime;
private string notificationMsg = "";
private float notificationExpiry = 0f;
private bool wasSinglePlayer = false;
private float singlePlayerEnterTime = 0f;
public static void CreateGlobalInstance()
{
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: Expected O, but got Unknown
//IL_0059: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)Instance != (Object)null))
{
GameObject val = new GameObject("BetterVoiceFix_UI");
Object.DontDestroyOnLoad((Object)(object)val);
Canvas val2 = val.AddComponent<Canvas>();
val2.renderMode = (RenderMode)0;
val2.sortingOrder = 9999;
CanvasScaler val3 = val.AddComponent<CanvasScaler>();
val3.uiScaleMode = (ScaleMode)1;
val3.referenceResolution = new Vector2(1920f, 1080f);
Instance = val.AddComponent<VoiceUIManager>();
Instance.myCanvas = val2;
Instance.InitText();
}
}
private void InitText()
{
//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("StatusText");
val.transform.SetParent(((Component)this).transform, false);
ContentSizeFitter val2 = val.AddComponent<ContentSizeFitter>();
val2.horizontalFit = (FitMode)2;
val2.verticalFit = (FitMode)2;
statsText = val.AddComponent<TextMeshProUGUI>();
((TMP_Text)statsText).richText = true;
((Graphic)statsText).raycastTarget = false;
((TMP_Text)statsText).overflowMode = (TextOverflowModes)0;
((TMP_Text)statsText).textWrappingMode = (TextWrappingModes)0;
UpdateLayout();
TrySyncFontFromGame();
}
public void AddLog(string player, string msg, bool isLocal)
{
if (debugLogs.Count > 300)
{
debugLogs.RemoveAt(0);
}
debugLogs.Add(new LogEntry
{
Time = DateTime.Now.ToString("HH:mm:ss"),
Player = player,
Msg = msg,
IsLocal = isLocal
});
debugScrollPosition.y = float.MaxValue;
}
private void OnGUI()
{
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
//IL_004c: 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_0067: Expected O, but got Unknown
//IL_0062: Unknown result type (might be due to invalid IL or missing references)
//IL_0067: Unknown result type (might be due to invalid IL or missing references)
if (showDebugConsole)
{
GUI.skin.window.normal.background = Texture2D.blackTexture;
GUI.backgroundColor = new Color(0f, 0f, 0f, 0.85f);
debugWindowRect = GUI.Window(999, debugWindowRect, new WindowFunction(DrawDebugWindow), "语音修复调试控制台 (Alt+J) | EvCode:186");
}
}
private void DrawDebugWindow(int windowID)
{
//IL_0085: 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_020d: Unknown result type (might be due to invalid IL or missing references)
//IL_0217: 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_0373: Unknown result type (might be due to invalid IL or missing references)
//IL_03ab: Unknown result type (might be due to invalid IL or missing references)
//IL_03b0: Unknown result type (might be due to invalid IL or missing references)
//IL_03b6: Unknown result type (might be due to invalid IL or missing references)
//IL_03cd: Unknown result type (might be due to invalid IL or missing references)
//IL_03db: Unknown result type (might be due to invalid IL or missing references)
//IL_03fb: Unknown result type (might be due to invalid IL or missing references)
//IL_0401: Invalid comparison between Unknown and I4
//IL_0416: Unknown result type (might be due to invalid IL or missing references)
//IL_041c: Invalid comparison between Unknown and I4
//IL_0323: Unknown result type (might be due to invalid IL or missing references)
//IL_0328: Unknown result type (might be due to invalid IL or missing references)
//IL_033a: Expected O, but got Unknown
//IL_043e: Unknown result type (might be due to invalid IL or missing references)
//IL_045c: Unknown result type (might be due to invalid IL or missing references)
GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
if (GUILayout.Button("复制全部", Array.Empty<GUILayoutOption>()))
{
ExportLogs(toFile: false);
}
if (GUILayout.Button("导出文件", Array.Empty<GUILayoutOption>()))
{
ExportLogs(toFile: true);
}
if (GUILayout.Button("清空", Array.Empty<GUILayoutOption>()))
{
debugLogs.Clear();
}
if (GUILayout.Button("打印语音底层名单", Array.Empty<GUILayoutOption>()))
{
DumpVoicePlayers();
}
GUILayout.EndHorizontal();
filterScrollPosition = GUILayout.BeginScrollView(filterScrollPosition, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(40f) });
GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
if (GUILayout.Button((logFilterMode == 0) ? "[★全部]" : "全部", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(60f) }))
{
logFilterMode = 0;
}
if (GUILayout.Button((logFilterMode == 1) ? "[★本机]" : "本机", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(60f) }))
{
logFilterMode = 1;
}
if (PhotonNetwork.InRoom)
{
Player[] playerList = PhotonNetwork.PlayerList;
foreach (Player val in playerList)
{
if (!val.IsLocal)
{
string playerName = NetworkManager.GetPlayerName(val.ActorNumber);
string text = ((playerName.Length > 9) ? playerName.Substring(0, 9) : playerName);
string text2 = ((logFilterMode == -1 && targetActorNumber == val.ActorNumber) ? ("[★" + text + "]") : text);
if (GUILayout.Button(text2, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(80f) }))
{
logFilterMode = -1;
targetActorNumber = val.ActorNumber;
}
}
}
}
GUILayout.EndHorizontal();
GUILayout.EndScrollView();
debugScrollPosition = GUILayout.BeginScrollView(debugScrollPosition, Array.Empty<GUILayoutOption>());
foreach (LogEntry debugLog in debugLogs)
{
if (logFilterMode == 1 && !debugLog.IsLocal)
{
continue;
}
if (logFilterMode == -1)
{
string playerName2 = NetworkManager.GetPlayerName(targetActorNumber);
if (debugLog.Player != playerName2)
{
continue;
}
}
string text3 = (debugLog.IsLocal ? "cyan" : "yellow");
if (debugLog.Player == "System")
{
text3 = "white";
}
GUILayout.Label("<color=" + text3 + ">[" + debugLog.Time + "] " + debugLog.Player + ":</color> " + debugLog.Msg, new GUIStyle(GUI.skin.label)
{
richText = true
}, Array.Empty<GUILayoutOption>());
}
GUILayout.EndScrollView();
GUI.DragWindow(new Rect(0f, 0f, 10000f, 20f));
resizeHandleRect = new Rect(((Rect)(ref debugWindowRect)).width - 20f, ((Rect)(ref debugWindowRect)).height - 20f, 20f, 20f);
GUI.Label(resizeHandleRect, "◢");
Event current2 = Event.current;
if ((int)current2.type == 0 && ((Rect)(ref resizeHandleRect)).Contains(current2.mousePosition))
{
isResizing = true;
}
else if ((int)current2.type == 1)
{
isResizing = false;
}
else if ((int)current2.type == 3 && isResizing)
{
ref Rect reference = ref debugWindowRect;
((Rect)(ref reference)).width = ((Rect)(ref reference)).width + current2.delta.x;
ref Rect reference2 = ref debugWindowRect;
((Rect)(ref reference2)).height = ((Rect)(ref reference2)).height + current2.delta.y;
if (((Rect)(ref debugWindowRect)).width < 300f)
{
((Rect)(ref debugWindowRect)).width = 300f;
}
if (((Rect)(ref debugWindowRect)).height < 200f)
{
((Rect)(ref debugWindowRect)).height = 200f;
}
}
}
private void DumpVoicePlayers()
{
if ((Object)(object)NetworkManager.punVoice == (Object)null || ((VoiceConnection)NetworkManager.punVoice).Client == null || ((LoadBalancingClient)((VoiceConnection)NetworkManager.punVoice).Client).CurrentRoom == null)
{
AddLog("System", "客户端未连接", isLocal: true);
return;
}
StringBuilder stringBuilder = new StringBuilder();
Dictionary<int, Player> players = ((LoadBalancingClient)((VoiceConnection)NetworkManager.punVoice).Client).CurrentRoom.Players;
stringBuilder.AppendLine($"=== 语音底层名单 (Count: {players.Count}) ===");
foreach (KeyValuePair<int, Player> item in players)
{
int key = item.Key;
string playerName = NetworkManager.GetPlayerName(key);
bool flag = NetworkManager.IsGhost(key);
string text = "N/A";
string text2 = "";
if (NetworkManager.PlayerCache.ContainsKey(key))
{
text = NetworkManager.PlayerCache[key].IP;
text2 = NetworkManager.PlayerCache[key].ModVersion;
}
string text3 = (flag ? " [幽灵]" : "");
string text4 = (string.IsNullOrEmpty(text2) ? "" : (" | Ver: " + text2));
stringBuilder.AppendLine($" - ID: {key} | Name: {playerName} | IP: {text}{text4}{text3}");
}
AddLog("System", stringBuilder.ToString(), isLocal: true);
}
private void ExportLogs(bool toFile)
{
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.AppendLine($"=== Log Export ({DateTime.Now}) ===");
foreach (LogEntry debugLog in debugLogs)
{
stringBuilder.AppendLine("[" + debugLog.Time + "] " + debugLog.Player + ": " + debugLog.Msg);
}
if (toFile)
{
string text = Path.Combine(Paths.BepInExRootPath, "Log", "BetterVoiceFix_Dump.txt");
try
{
File.WriteAllText(text, stringBuilder.ToString());
AddLog("System", "已导出: " + text, isLocal: true);
return;
}
catch (Exception ex)
{
AddLog("System", "失败: " + ex.Message, isLocal: true);
return;
}
}
GUIUtility.systemCopyBuffer = stringBuilder.ToString();
AddLog("System", "已复制", isLocal: true);
}
private void Update()
{
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
if (VoiceFix.ToggleUIKey == null)
{
return;
}
if (Input.GetKeyDown(VoiceFix.ToggleUIKey.Value))
{
if (isDetailMode)
{
isDetailMode = false;
detailModeExpiry = 0f;
}
else
{
isDetailMode = true;
detailModeExpiry = Time.unscaledTime + 10f;
}
}
if ((Input.GetKey((KeyCode)308) || Input.GetKey((KeyCode)307)) && Input.GetKeyDown((KeyCode)106))
{
showDebugConsole = !showDebugConsole;
}
if (isDetailMode && Time.unscaledTime > detailModeExpiry)
{
isDetailMode = false;
}
Scene activeScene = SceneManager.GetActiveScene();
string name = ((Scene)(ref activeScene)).name;
bool flag = name == "Airport";
bool inRoom = PhotonNetwork.InRoom;
bool flag2 = VoiceFix.HideOnMenu != null && VoiceFix.HideOnMenu.Value && Cursor.visible;
bool flag3 = false;
if (inRoom && !flag2)
{
if (isDetailMode)
{
flag3 = true;
}
else
{
bool flag4 = Time.unscaledTime < notificationExpiry;
if (flag || flag4)
{
flag3 = true;
}
}
}
if (((Behaviour)myCanvas).enabled != flag3)
{
((Behaviour)myCanvas).enabled = flag3;
}
if (!flag3)
{
return;
}
if ((Object)(object)((TMP_Text)statsText).font == (Object)null || ((Object)((TMP_Text)statsText).font).name.Contains("Liberation") || Time.unscaledTime - lastFontRetryTime > 2f)
{
lastFontRetryTime = Time.unscaledTime;
TrySyncFontFromGame();
}
if (Time.unscaledTime > nextUiUpdateTime)
{
if (isDetailMode)
{
UpdateContent_Detail();
}
else
{
UpdateContent_Normal();
}
UpdateLayout();
nextUiUpdateTime = Time.unscaledTime + 0.2f;
}
}
public bool IsDetailModeActive()
{
return isDetailMode;
}
private void UpdateLayout()
{
//IL_0108: Unknown result type (might be due to invalid IL or missing references)
//IL_011e: 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_0143: Unknown result type (might be due to invalid IL or missing references)
//IL_00a1: 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_00cd: 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)
if (!((Object)(object)statsText == (Object)null) && VoiceFix.UIPositionSide != null)
{
bool flag = VoiceFix.UIPositionSide.Value == "右侧";
float num = (flag ? Mathf.Abs(VoiceFix.OffsetX_Right.Value) : Mathf.Abs(VoiceFix.OffsetX_Left.Value));
float num2 = (flag ? Mathf.Abs(VoiceFix.OffsetY_Right.Value) : Mathf.Abs(VoiceFix.OffsetY_Left.Value));
RectTransform rectTransform = ((TMP_Text)statsText).rectTransform;
if (flag)
{
rectTransform.anchorMin = new Vector2(1f, 1f);
rectTransform.anchorMax = new Vector2(1f, 1f);
rectTransform.pivot = new Vector2(1f, 1f);
rectTransform.anchoredPosition = new Vector2(0f - num, 0f - num2);
((TMP_Text)statsText).alignment = (TextAlignmentOptions)257;
}
else
{
rectTransform.anchorMin = new Vector2(0f, 1f);
rectTransform.anchorMax = new Vector2(0f, 1f);
rectTransform.pivot = new Vector2(0f, 1f);
rectTransform.anchoredPosition = new Vector2(num, 0f - num2);
((TMP_Text)statsText).alignment = (TextAlignmentOptions)257;
}
((TMP_Text)statsText).fontSize = VoiceFix.FontSize.Value;
}
}
public void TriggerNotification(string playerName)
{
notificationMsg = "<color=#dfdac2>" + playerName + ":</color> " + FormatStatusTag("连接断开", "#F0E68C");
notificationExpiry = Time.unscaledTime + 5f;
}
public void ShowStatsTemporary()
{
notificationMsg = "<color=#F0E68C>[系统] 手动操作...</color>";
notificationExpiry = Time.unscaledTime + 5f;
}
private string GetLocalizedState(ClientState state)
{
//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_0003: Unknown result type (might be due to invalid IL or missing references)
//IL_0004: Unknown result type (might be due to invalid IL or missing references)
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_0008: Invalid comparison between Unknown and I4
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Invalid comparison between Unknown and I4
ClientState val = state;
ClientState val2 = val;
if ((int)val2 != 9)
{
if ((int)val2 == 14)
{
return "已断开";
}
return ((object)(ClientState)(ref state)).ToString();
}
return "已连接";
}
private string GetMyStateRaw(out string color)
{
int joined = 0;
int total = 0;
GetVoiceCounts(out joined, out total);
if (IsVoiceConnected())
{
if (joined > 1)
{
color = "#90EE90";
return "同步";
}
if (joined == 1 && PhotonNetwork.CurrentRoom.PlayerCount > 1)
{
color = "#F0E68C";
return "孤立";
}
color = "#90EE90";
return "同步";
}
if (IsConnectingLocal())
{
color = "#F0E68C";
return "连接中";
}
color = "#FF6961";
return "断开";
}
private void AppendCommonStats(StringBuilder sb, bool forceShow)
{
//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
bool flag = PhotonNetwork.OfflineMode || (PhotonNetwork.CurrentRoom != null && PhotonNetwork.CurrentRoom.MaxPlayers == 1);
if (flag)
{
if (!wasSinglePlayer)
{
singlePlayerEnterTime = Time.unscaledTime;
wasSinglePlayer = true;
}
}
else
{
wasSinglePlayer = false;
}
if (!(!forceShow && flag) || !(Time.unscaledTime > singlePlayerEnterTime + 10f))
{
if (flag)
{
sb.Append("<color=#dfdac2>本机语音: 单人游戏</color>\n");
}
else
{
string color;
string myStateRaw = GetMyStateRaw(out color);
string text = myStateRaw;
if ((Object)(object)NetworkManager.punVoice != (Object)null && ((VoiceConnection)NetworkManager.punVoice).Client != null && myStateRaw != "同步" && myStateRaw != "孤立")
{
text = GetLocalizedState(((LoadBalancingClient)((VoiceConnection)NetworkManager.punVoice).Client).State);
}
sb.Append("<color=#dfdac2>本机语音: </color>");
if (IsVoiceConnected())
{
if (PhotonNetwork.IsMasterClient)
{
sb.Append("<color=#dfdac2>已连接</color>");
}
else
{
sb.Append("<color=#dfdac2>已连接</color> " + FormatStatusTag(myStateRaw, color));
}
}
else
{
sb.Append("<color=" + color + ">" + text + "</color>");
}
sb.Append("\n");
GetVoiceCounts(out var _, out var total);
int ghostCount = NetworkManager.GetGhostCount();
int count = ((LoadBalancingClient)((VoiceConnection)NetworkManager.punVoice).Client).CurrentRoom.Players.Count;
int num = total;
sb.Append("<color=#dfdac2>语音连接人数:</color>");
string arg = "#F0E68C";
if (count == 1 && num >= 3)
{
arg = "#FF6961";
}
else if (ghostCount > 0)
{
arg = "#b2d3b2";
}
else if (count == num)
{
arg = "#90EE90";
}
sb.Append($"<color={arg}>{count}</color>");
sb.Append(string.Format("<color={0}>/</color><color={1}>{2}</color>", "#dfdac2", "#dfdac2", num));
if (ghostCount > 0)
{
sb.Append(string.Format(" <color={0}>(</color><color={1}>{2}</color><color={3}> 人ID错位)</color>", "#dfdac2", "#b2d3b2", ghostCount, "#dfdac2"));
}
sb.Append("\n");
}
if (VoiceFix.ShowPingInNormal != null && VoiceFix.ShowPingInNormal.Value)
{
int ping = PhotonNetwork.GetPing();
string arg2 = ((ping < 100) ? "#90EE90" : ((ping < 200) ? "#F0E68C" : "#FF6961"));
sb.Append(string.Format("<color={0}>本机延迟: </color><color={1}>{2}ms</color>\n", "#dfdac2", arg2, ping));
}
}
if (Time.unscaledTime < notificationExpiry)
{
sb.Append(notificationMsg + "\n");
}
}
private void UpdateContent_Normal()
{
StringBuilder stringBuilder = new StringBuilder();
AppendCommonStats(stringBuilder, forceShow: false);
((TMP_Text)statsText).text = stringBuilder.ToString();
}
private void UpdateContent_Detail()
{
StringBuilder stringBuilder = new StringBuilder();
bool value = VoiceFix.ShowProfessionalInfo.Value;
float value2 = VoiceFix.LatencyOffset.Value;
stringBuilder.Append("<align=\"center\"><size=120%><color=#dfdac2>语音详细状态 (v0.3.4)</color></size></align>\n");
stringBuilder.Append("<align=\"center\"><color=#dfdac2>------------------</color></align>\n");
string currentIP = GetCurrentIP();
string color;
string myStateRaw = GetMyStateRaw(out color);
stringBuilder.Append("<size=75%><color=#dfdac2>本机IP:</color> ");
if (!PhotonNetwork.IsMasterClient || !IsVoiceConnected())
{
string text = FormatStatusTag(myStateRaw, color);
stringBuilder.Append(text + " ");
}
if (value)
{
stringBuilder.Append(" <color=#dfdac2>" + currentIP + "</color>");
}
stringBuilder.Append("\n");
stringBuilder.Append("<color=#dfdac2>房主IP:</color> ");
if (PhotonNetwork.IsMasterClient)
{
GetVoiceCounts(out var joined, out var total);
int num = total - joined;
if (num < 0)
{
num = 0;
}
stringBuilder.Append("<color=#dfdac2>[</color><color=#dfdac2>本机</color><color=#dfdac2>]</color> ");
string text2 = ((joined >= total) ? "#90EE90" : "#F0E68C");
stringBuilder.Append(string.Format("<color={0}>[</color><color={1}>同步:</color><color={2}>{3}/{4}</color><color={5}>]</color> ", "#dfdac2", "#dfdac2", text2, joined, total, "#dfdac2"));
string text3 = ((num > 0) ? "#CD5C5C" : "#dfdac2");
stringBuilder.Append(string.Format("<color={0}>[</color><color={1}>异常:</color><color={2}>{3}</color><color={4}>]</color>", "#dfdac2", "#dfdac2", text3, num, "#dfdac2"));
}
else
{
Player masterClient = PhotonNetwork.MasterClient;
string s = ((masterClient != null) ? NetworkManager.GetPlayerName(masterClient.ActorNumber) : "未知");
string text4 = "";
if (masterClient != null && NetworkManager.PlayerCache.TryGetValue(masterClient.ActorNumber, out var value3))
{
text4 = value3.IP;
}
stringBuilder.Append("<color=#dfdac2>[" + Truncate(s, 0, isHost: false) + "]</color>");
if (!string.IsNullOrEmpty(text4))
{
stringBuilder.Append("<color=#dfdac2>: " + text4 + "</color>");
}
}
stringBuilder.Append("</size>\n");
if (PhotonNetwork.IsMasterClient)
{
int c;
string majorityIP = GetMajorityIP(out c);
if (c > 2 && !string.IsNullOrEmpty(majorityIP) && majorityIP != currentIP)
{
stringBuilder.Append(string.Format("<color={0}><size=85%>⚠ [警告] 多数玩家({1}人)在另一频道!</size></color>\n", "#F0E68C", c));
}
}
int ghostCount = NetworkManager.GetGhostCount();
List<PlayerRenderData> list = new List<PlayerRenderData>();
if (VoiceFix.EnableVirtualTestPlayer != null && VoiceFix.EnableVirtualTestPlayer.Value)
{
string name = ((VoiceFix.TestPlayerName != null) ? VoiceFix.TestPlayerName.Value : "Test");
list.Add(new PlayerRenderData
{
Name = "虚拟玩家1",
IP = "",
Ping = 0,
IsLocal = false,
IsHost = false,
IsAlive = true,
HasModData = false,
IsInVoiceRoom = false
});
list.Add(new PlayerRenderData
{
Name = name,
IP = currentIP,
Ping = 50,
IsLocal = false,
IsHost = false,
IsAlive = true,
HasModData = true,
IsInVoiceRoom = true
});
}
HashSet<int> hashSet = new HashSet<int>();
if (PhotonNetwork.PlayerList != null)
{
Player[] playerList = PhotonNetwork.PlayerList;
foreach (Player val in playerList)
{
int actorNumber = val.ActorNumber;
hashSet.Add(actorNumber);
string text5 = "";
int ping = 0;
bool hasModData = false;
bool isLocal = val.IsLocal;
bool isMasterClient = val.IsMasterClient;
bool isInVoiceRoom = false;
if ((Object)(object)NetworkManager.punVoice != (Object)null && ((VoiceConnection)NetworkManager.punVoice).Client != null && ((LoadBalancingClient)((VoiceConnection)NetworkManager.punVoice).Client).CurrentRoom != null)
{
isInVoiceRoom = ((LoadBalancingClient)((VoiceConnection)NetworkManager.punVoice).Client).CurrentRoom.Players.ContainsKey(actorNumber);
}
if (isLocal)
{
text5 = GetCurrentIP();
ping = PhotonNetwork.GetPing();
hasModData = true;
isInVoiceRoom = IsVoiceConnected();
}
else
{
if (((Dictionary<object, object>)(object)val.CustomProperties).TryGetValue((object)"PVF_IP", out object value4))
{
text5 = (string)value4;
}
if (((Dictionary<object, object>)(object)val.CustomProperties).TryGetValue((object)"PVF_Ping", out object value5))
{
ping = (int)value5;
}
if (!string.IsNullOrEmpty(text5))
{
hasModData = true;
}
}
string playerName = NetworkManager.GetPlayerName(actorNumber);
byte remoteState = 0;
if (NetworkManager.PlayerCache.ContainsKey(actorNumber))
{
remoteState = NetworkManager.PlayerCache[actorNumber].RemoteState;
}
list.Add(new PlayerRenderData
{
Name = playerName,
IP = text5,
Ping = ping,
IsLocal = isLocal,
IsHost = isMasterClient,
IsAlive = true,
HasModData = hasModData,
IsInVoiceRoom = isInVoiceRoom,
ActorNumber = actorNumber,
RemoteState = remoteState
});
}
}
foreach (KeyValuePair<int, CacheEntry> item in NetworkManager.PlayerCache)
{
int key = item.Key;
if (!hashSet.Contains(key) && !(Time.unscaledTime - item.Value.LastSeenTime > 5f))
{
list.Add(new PlayerRenderData
{
Name = item.Value.PlayerName,
IP = item.Value.IP,
Ping = 0,
IsLocal = false,
IsHost = false,
IsAlive = false,
HasModData = true,
IsInVoiceRoom = false,
ActorNumber = key,
RemoteState = item.Value.RemoteState
});
}
}
list.Sort((PlayerRenderData a, PlayerRenderData b) => b.IsLocal.CompareTo(a.IsLocal));
stringBuilder.Append("<line-height=105%>");
foreach (PlayerRenderData item2 in list)
{
BuildPlayerEntry(stringBuilder, item2.Name, item2.IP, item2.Ping, item2.IsLocal, item2.IsHost, value, value2, item2.IsAlive, item2.HasModData, item2.IsInVoiceRoom, ghostCount > 0, item2.ActorNumber, item2.RemoteState);
}
stringBuilder.Append("</line-height>");
stringBuilder.Append("<align=\"center\"><color=#dfdac2>------------------</color></align>\n");
AppendCommonStats(stringBuilder, forceShow: true);
if (NetworkManager.ActiveSOSList.Count > 0)
{
stringBuilder.Append("<align=\"center\"><color=#dfdac2>------------------</color></align>\n");
stringBuilder.Append("<color=#F0E68C>[SOS快照]</color>\n");
int c2;
string majorityIP2 = GetMajorityIP(out c2);
string text6 = ((PhotonNetwork.IsMasterClient || IsIPMatch(majorityIP2)) ? "同步" : majorityIP2);
stringBuilder.Append(string.Format("<size=80%><color={0}>多数派: {1} ({2}人)</color></size>\n", "#dfdac2", majorityIP2, c2));
foreach (SOSData activeSOS in NetworkManager.ActiveSOSList)
{
stringBuilder.Append("<size=80%><color=#FF6961>检测到 " + activeSOS.PlayerName + " 掉线</color></size>\n");
string text7 = (string.IsNullOrEmpty(activeSOS.OriginIP) ? "未知" : activeSOS.OriginIP);
stringBuilder.Append(" <size=80%><color=#dfdac2>目标: (" + activeSOS.TargetIP + ") | 上次: " + text7 + "</color></size>\n");
}
}
if (value)
{
stringBuilder.Append("<align=\"center\"><color=#dfdac2>------------------</color></align>\n");
int c3;
string majorityIP3 = GetMajorityIP(out c3);
float num2 = Time.unscaledTime - NetworkManager.LastScanTime;
stringBuilder.Append(string.Format("<size=80%><color={0}>[缓存快照] ({1:F0}秒前)</color>\n", "#dfdac2", num2));
stringBuilder.Append(string.Format("<color={0}>多数派:</color> <color={1}>{2}</color> <color={3}>({4}人)</color>\n", "#dfdac2", "#dfdac2", majorityIP3, "#dfdac2", c3));
IEnumerable<IGrouping<string, KeyValuePair<int, CacheEntry>>> enumerable = from x in NetworkManager.PlayerCache
group x by x.Value.IP;
foreach (IGrouping<string, KeyValuePair<int, CacheEntry>> item3 in enumerable)
{
if (!(item3.Key == majorityIP3))
{
string text8 = (string.IsNullOrEmpty(item3.Key) ? "未连接" : item3.Key);
IEnumerable<string> values = item3.Select((KeyValuePair<int, CacheEntry> x) => x.Value.PlayerName).Take(3);
string text9 = string.Join(",", values);
stringBuilder.Append("<color=#dfdac2> - " + text8 + ": " + text9 + "</color>\n");
}
}
if (NetworkManager.HostHistory.Count > 0)
{
stringBuilder.Append("<color=#dfdac2>[历史]</color> " + NetworkManager.HostHistory[NetworkManager.HostHistory.Count - 1] + "\n");
}
stringBuilder.Append("</size>");
}
((TMP_Text)statsText).text = stringBuilder.ToString();
}
private string GetClientStateLocalized(ClientState state)
{
//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_0003: Unknown result type (might be due to invalid IL or missing references)
//IL_0004: Unknown result type (might be due to invalid IL or missing references)
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_004f: Expected I4, but got Unknown
ClientState val = state;
ClientState val2 = val;
return (int)val2 switch
{
0 => "初始化中...",
1 => "验证中...",
2 => "已验证",
8 => "加入中...",
9 => "已连接",
13 => "断开中...",
14 => "断开",
6 => "连接到游戏服务器中...",
12 => "连接到主服务器中...",
16 => "连接到名称服务器中...",
_ => ((object)(ClientState)(ref state)).ToString(),
};
}
private void BuildPlayerEntry(StringBuilder sb, string name, string ip, int ping, bool isLocal, bool isHost, bool pro, float alignX, bool isAlive, bool hasModData, bool isInVoiceRoom, bool hasGhosts, int actorNumber = -1, byte remoteState = 0)
{
//IL_007e: 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_0084: Invalid comparison between Unknown and I4
//IL_0086: Unknown result type (might be due to invalid IL or missing references)
//IL_008a: Invalid comparison between Unknown and I4
//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
//IL_00ab: Invalid comparison between Unknown and I4
//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
//IL_0546: Unknown result type (might be due to invalid IL or missing references)
int num = 0;
if (!hasModData)
{
string text = (isHost ? ("<color=#ffd700>" + VoiceFix.HostSymbol.Value + " </color>") : "");
string text2 = "未知";
string colorHex = "#dfdac2";
bool flag = false;
string text3 = "";
if (isInVoiceRoom)
{
text2 = "已连接";
colorHex = "#98FB98";
}
else if (remoteState != 0)
{
ClientState val = (ClientState)remoteState;
if ((int)val == 14 || (int)val == 13)
{
text2 = "断开";
colorHex = "#FF6961";
}
else if ((int)val == 9)
{
text2 = "已连接";
colorHex = "#98FB98";
}
else
{
text2 = "连接中";
colorHex = "#F0E68C";
flag = true;
text3 = GetClientStateLocalized(val);
if (actorNumber != -1)
{
joinTimes[actorNumber] = Time.unscaledTime;
}
}
}
else if (actorNumber != -1)
{
if (!joinTimes.ContainsKey(actorNumber))
{
joinTimes[actorNumber] = Time.unscaledTime;
}
if (Time.unscaledTime - joinTimes[actorNumber] < 25f)
{
text2 = "连接中";
colorHex = "#F0E68C";
}
else if (hasGhosts)
{
text2 = "错位";
colorHex = "#b2d3b2";
}
else
{
text2 = "断开";
colorHex = "#FF6961";
}
}
num = 8;
string text4 = Truncate(name, num, isHost);
sb.Append(FormatStatusTag(text2, colorHex) + " " + text + "<size=100%><color=#90EE90>" + text4 + "</color></size>\n");
if (flag && pro)
{
sb.Append("<voffset=0.17em><size=80%><color=#dfdac2> » " + text3 + "</color></size></voffset>\n");
}
return;
}
bool flag2 = !string.IsNullOrEmpty(ip);
string text5 = "";
string text6 = "#90EE90";
bool flag3 = false;
if (!flag2)
{
if (isAlive && ping > 0)
{
text5 = "连接中";
text6 = "#F0E68C";
flag3 = true;
num = 8;
}
else
{
text5 = "断开";
text6 = "#FF6961";
num = 6;
}
}
else if (IsIPMatch(ip))
{
text5 = "同步";
text6 = "#90EE90";
num = 6;
}
else
{
text5 = "异常";
text6 = "#CD5C5C";
num = 6;
}
if (isLocal)
{
num = 6;
if (IsConnectingLocal())
{
flag3 = true;
}
}
if (!isAlive && !isLocal)
{
text5 = "已退";
text6 = "#808080";
num = 6;
}
string text7 = FormatStatusTag(text5, text6);
string text8 = (isHost ? ("<color=#ffd700>" + VoiceFix.HostSymbol.Value + " </color>") : "");
if (isLocal)
{
text7 = "<color=#dfdac2>[</color><color=#dfdac2>本机</color><color=#dfdac2>]</color>";
}
string text9 = Truncate(name, num, isHost);
string text10 = ((!isAlive && !isLocal) ? "#808080" : "#90EE90");
string text11 = "";
string text12 = ((ping < 100) ? "#90EE90" : ((ping < 200) ? "#F0E68C" : "#FF6961"));
if (ping > 0 || (isAlive && string.IsNullOrEmpty(ip)))
{
text11 = string.Format("<pos={0}><color={1}>| 延迟:</color><color={2}>{3}ms</color>", alignX, "#dfdac2", text12, ping);
}
sb.Append(text7 + " " + text8 + "<size=100%><color=" + text10 + ">" + text9 + "</color></size>" + text11 + "\n");
if (pro && !isLocal)
{
string text13 = ip;
string text14 = "已连接";
if (remoteState != 0 && remoteState != 9 && remoteState != 14)
{
text13 = GetClientStateLocalized((ClientState)remoteState);
text14 = "状态";
sb.Append("<voffset=0.17em><size=80%><color=#dfdac2> » " + text13 + "</color></size></voffset>\n");
return;
}
string text15 = (flag3 ? "(等待数据...)" : (string.IsNullOrEmpty(ip) ? "N/A" : ip));
if (flag3 && string.IsNullOrEmpty(ip))
{
text15 = "<color=grey>获取中...</color>";
}
string text16 = (flag3 ? "正在连接" : "已连接");
sb.Append("<voffset=0.17em><size=80%><color=#dfdac2> » " + text16 + ": " + text15 + "</color></size></voffset>\n");
}
else if (pro && isLocal && flag3)
{
string text17 = "连接中...";
if ((Object)(object)NetworkManager.punVoice != (Object)null && ((VoiceConnection)NetworkManager.punVoice).Client != null)
{
text17 = GetClientStateLocalized(((LoadBalancingClient)((VoiceConnection)NetworkManager.punVoice).Client).State);
}
sb.Append("<voffset=0.17em><size=80%><color=#dfdac2> » " + text17 + "</color></size></voffset>\n");
}
}
private void GetVoiceCounts(out int joined, out int total)
{
joined = 0;
total = 0;
if (PhotonNetwork.PlayerList == null)
{
return;
}
total = PhotonNetwork.PlayerList.Length;
if ((Object)(object)NetworkManager.punVoice != (Object)null && ((VoiceConnection)NetworkManager.punVoice).Client != null && ((LoadBalancingClient)((VoiceConnection)NetworkManager.punVoice).Client).CurrentRoom != null)
{
foreach (int key in ((LoadBalancingClient)((VoiceConnection)NetworkManager.punVoice).Client).CurrentRoom.Players.Keys)
{
if (!NetworkManager.IsGhost(key))
{
joined++;
}
}
return;
}
Player[] playerList = PhotonNetwork.PlayerList;
foreach (Player val in playerList)
{
CacheEntry value;
if (val.IsLocal)
{
if (IsVoiceConnected())
{
joined++;
}
}
else if (NetworkManager.PlayerCache.TryGetValue(val.ActorNumber, out value) && !string.IsNullOrEmpty(value.IP))
{
joined++;
}
}
}
private string FormatStatusTag(string text, string colorHex)
{
return "<color=#dfdac2>[</color><color=" + colorHex + ">" + text + "</color><color=#dfdac2>]</color>";
}
private LoadBalancingClient GetVoiceClient()
{
if ((Object)(object)NetworkManager.punVoice != (Object)null)
{
return (LoadBalancingClient)(object)((VoiceConnection)NetworkManager.punVoice).Client;
}
GameObject val = GameObject.Find("VoiceClient");
if ((Object)(object)val != (Object)null)
{
PunVoiceClient component = val.GetComponent<PunVoiceClient>();
if ((Object)(object)component != (Object)null)
{
return (LoadBalancingClient)(object)((VoiceConnection)component).Client;
}
}
return null;
}
private string GetCurrentIP()
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0013: Invalid comparison between Unknown and I4
LoadBalancingClient voiceClient = GetVoiceClient();
return (voiceClient != null && (int)voiceClient.State == 9) ? voiceClient.GameServerAddress : "";
}
private bool IsVoiceConnected()
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0013: Invalid comparison between Unknown and I4
LoadBalancingClient voiceClient = GetVoiceClient();
return voiceClient != null && (int)voiceClient.State == 9;
}
private bool IsConnectingLocal()
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: Invalid comparison between Unknown and I4
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Invalid comparison between Unknown and I4
LoadBalancingClient voiceClient = GetVoiceClient();
return voiceClient != null && ((int)voiceClient.State == 6 || (int)voiceClient.State == 1);
}
private bool IsMismatch()
{
if (NetworkManager.WrongIPCount > 2)
{
return true;
}
string targetGameServer = NetworkManager.TargetGameServer;
string currentIP = GetCurrentIP();
return !string.IsNullOrEmpty(targetGameServer) && !string.IsNullOrEmpty(currentIP) && targetGameServer != currentIP;
}
private bool IsIPMatch(string otherIP)
{
return otherIP == GetCurrentIP();
}
private string GetMajorityIP(out int c)
{
return NetworkManager.GetMajorityIP(out c);
}
private bool IsAllGood()
{
return IsVoiceConnected() && !IsMismatch() && NetworkManager.TotalRetryCount == 0;
}
private string Truncate(string s, int prefixWeight, bool isHost)
{
if (string.IsNullOrEmpty(s))
{
return "";
}
int num = 26;
if (VoiceFix.MaxTotalLength != null)
{
num = VoiceFix.MaxTotalLength.Value;
}
int num2 = num - prefixWeight;
if (num2 < 6)
{
num2 = 6;
}
if (isHost)
{
num2 -= 2;
}
int num3 = 0;
for (int i = 0; i < s.Length; i++)
{
int num4 = ((s[i] <= 'ÿ') ? 1 : 2);
if (num3 + num4 > num2)
{
return s.Substring(0, i) + "...";
}
num3 += num4;
}
return s;
}
private void TrySyncFontFromGame()
{
if (!((Object)(object)statsText == (Object)null))
{
PlayerConnectionLog val = Object.FindFirstObjectByType<PlayerConnectionLog>();
if ((Object)(object)val != (Object)null && (Object)(object)val.text != (Object)null)
{
((TMP_Text)statsText).font = ((TMP_Text)val.text).font;
((TMP_Text)statsText).fontSharedMaterial = ((TMP_Text)val.text).fontSharedMaterial;
}
}
}
}
}
namespace PeakVoiceFix.Patches
{
[HarmonyPatch(typeof(LoadBalancingClient))]
public class LoadBalancingClientPatch
{
[HarmonyPatch("OnEvent")]
[HarmonyPrefix]
public static void OnEventPrefix(EventData photonEvent)
{
if (photonEvent.Code == 186)
{
NetworkManager.OnEvent(photonEvent);
}
}
}
}
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
internal sealed class IgnoresAccessChecksToAttribute : Attribute
{
public IgnoresAccessChecksToAttribute(string assemblyName)
{
}
}
}