using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using DG.Tweening;
using HarmonyLib;
using TMPro;
using Unity.Services.Vivox;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.Localization;
using UnityEngine.Localization.Settings;
using UnityEngine.Localization.Tables;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("PlayerVoiceVolume")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("PlayerVoiceVolume")]
[assembly: AssemblyTitle("PlayerVoiceVolume")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace PlayerVoiceVolume;
internal static class GameAccess
{
private const float LookupInterval = 1f;
private static PlayerPanelController _players;
private static TextChannelManager _chat;
private static UIManager _ui;
private static float _nextPlayersLookup;
private static float _nextChatLookup;
private static float _nextUiLookup;
public static PlayerPanelController PlayerPanel
{
get
{
if ((Object)(object)_players == (Object)null && Time.unscaledTime >= _nextPlayersLookup)
{
_nextPlayersLookup = Time.unscaledTime + 1f;
_players = NetworkSingleton<PlayerPanelController>.I;
}
return _players;
}
set
{
_players = value;
}
}
public static TextChannelManager Chat
{
get
{
if ((Object)(object)_chat == (Object)null && Time.unscaledTime >= _nextChatLookup)
{
_nextChatLookup = Time.unscaledTime + 1f;
_chat = NetworkSingleton<TextChannelManager>.I;
}
return _chat;
}
}
public static UIManager UI
{
get
{
if ((Object)(object)_ui == (Object)null && Time.unscaledTime >= _nextUiLookup)
{
_nextUiLookup = Time.unscaledTime + 1f;
_ui = MonoSingleton<UIManager>.I;
}
return _ui;
}
}
public static bool IsLocalPlayer(PlayerPanelController players, int index)
{
TextChannelManager chat = Chat;
if ((Object)(object)chat == (Object)null || (Object)(object)chat.MainNetTransform == (Object)null)
{
return false;
}
if (index < players.PlayerTransforms.Count)
{
return (Object)(object)players.PlayerTransforms[index] == (Object)(object)chat.MainNetTransform;
}
return false;
}
public static string RawPlayerName(PlayerPanelController players, int index)
{
PlayerController val = ((index < players.PlayerControllers.Count) ? players.PlayerControllers[index] : null);
TMP_Text val2 = (TMP_Text)(object)(((Object)(object)val != (Object)null) ? val.PlayerNameText : null);
if (!((Object)(object)val2 != (Object)null))
{
return null;
}
return val2.text;
}
public static string FilterName(string name)
{
if (string.IsNullOrEmpty(name))
{
return name;
}
try
{
BadWordFilterManager i = MonoSingleton<BadWordFilterManager>.I;
return ((Object)(object)i != (Object)null) ? i.FilterString(name) : name;
}
catch (Exception)
{
return name;
}
}
public static VoiceStatus VoiceStatusOf(PlayerPanelController players, string steamId)
{
int num = players.PlayerSteamIDs.IndexOf(steamId);
if (num >= 0)
{
DataManager i = MonoSingleton<DataManager>.I;
List<string> list = (((Object)(object)i != (Object)null && i.BanData != null) ? i.BanData.VoiceMutedPlayers : null);
if (list != null && list.Contains(steamId))
{
return (VoiceStatus)2;
}
if (num < players.IsVoiceChatActive.Count && players.IsVoiceChatActive[num])
{
PlayerController val = ((num < players.PlayerControllers.Count) ? players.PlayerControllers[num] : null);
PlayerVoiceController val2 = (((Object)(object)val != (Object)null) ? val.PlayerVoice : null);
if ((Object)(object)val2 != (Object)null && val2.IsSpeaking)
{
return (VoiceStatus)1;
}
return (VoiceStatus)0;
}
return (VoiceStatus)3;
}
return (VoiceStatus)3;
}
public static void PlayUIChange()
{
try
{
UIManager uI = UI;
if ((Object)(object)uI != (Object)null)
{
uI.PlayUIChange();
}
}
catch (Exception)
{
}
}
public static void PlayUIClick()
{
try
{
UIManager uI = UI;
if ((Object)(object)uI != (Object)null)
{
uI.PlayUIClick();
}
}
catch (Exception)
{
}
}
}
internal static class GameRefs
{
public static readonly FieldRef<PlayerPanelController, GameObject> ServerList = Field<PlayerPanelController, GameObject>("_serverPanel");
public static readonly FieldRef<PlayerPanelController, GameObject> BannedList = Field<PlayerPanelController, GameObject>("_bannedPanel");
public static readonly FieldRef<PlayerPanelController, RectTransform> ServerButton = Field<PlayerPanelController, RectTransform>("_serverButtonTransform");
public static readonly FieldRef<PlayerPanelController, RectTransform> BannedButton = Field<PlayerPanelController, RectTransform>("_bannedButtonTransform");
public static readonly FieldRef<PlayerPanelController, Color> SelectedColor = Field<PlayerPanelController, Color>("_selectedColor");
public static readonly FieldRef<PlayerPanelController, Color> ServerColor = Field<PlayerPanelController, Color>("_serverColor");
public static readonly FieldRef<PlayerPanelController, Color> BannedColor = Field<PlayerPanelController, Color>("_bannedColor");
public static readonly FieldRef<PlayerPanelController, Color> GreenColor = Field<PlayerPanelController, Color>("_greenColor");
public static readonly FieldRef<PlayerPanelController, Color> OrangeColor = Field<PlayerPanelController, Color>("_orangeColor");
public static readonly FieldRef<PlayerPanelController, PlayerPanelType> PanelType = Field<PlayerPanelController, PlayerPanelType>("_playerPanelType");
public static readonly FieldRef<PlayerPanelController, GameObject> ItemPrefab = Field<PlayerPanelController, GameObject>("_playerItemPrefab");
public static readonly FieldRef<PlayerPanelController, List<PlayerItemController>> Items = Field<PlayerPanelController, List<PlayerItemController>>("_playerItemControllers");
public static readonly FieldRef<PlayerPanelController, RectTransform> InfoPanel = Field<PlayerPanelController, RectTransform>("_buttonInfoPanelTransfrom");
public static readonly FieldRef<PlayerPanelController, CanvasGroup> InfoGroup = Field<PlayerPanelController, CanvasGroup>("_buttonInfoPanelCanvasGroup");
public static readonly FieldRef<PlayerPanelController, Image> InfoHeaderBg = Field<PlayerPanelController, Image>("_buttonInfoHeaderBgImage");
public static readonly FieldRef<PlayerPanelController, TextMeshProUGUI> InfoHeader = Field<PlayerPanelController, TextMeshProUGUI>("_buttonInfoHeaderText");
public static readonly FieldRef<PlayerPanelController, TextMeshProUGUI> InfoText = Field<PlayerPanelController, TextMeshProUGUI>("_buttonInfoText");
public static readonly FieldRef<PlayerItemController, string> ItemSteamId = Field<PlayerItemController, string>("_playerSteamId");
public static readonly FieldRef<PlayerItemController, TextMeshProUGUI> ItemName = Field<PlayerItemController, TextMeshProUGUI>("_playerNameText");
public static readonly FieldRef<PlayerItemController, Button> ItemReport = Field<PlayerItemController, Button>("_reportButton");
public static readonly FieldRef<PlayerItemController, Button> ItemBan = Field<PlayerItemController, Button>("_banButton");
public static readonly FieldRef<PlayerItemController, Button> ItemSteam = Field<PlayerItemController, Button>("_steamButton");
public static readonly FieldRef<PlayerItemController, Button> ItemMute = Field<PlayerItemController, Button>("_muteButton");
public static readonly FieldRef<PlayerItemController, Button> ItemIgnore = Field<PlayerItemController, Button>("_ignoreButton");
public static readonly FieldRef<PlayerItemController, Button> ItemVoiceMute = Field<PlayerItemController, Button>("_voiceMuteButton");
public static readonly FieldRef<PlayerItemController, GameObject> ItemSync = Field<PlayerItemController, GameObject>("_syncButtonObject");
public static readonly FieldRef<PlayerItemController, GameObject> ItemSyncedWithMe = Field<PlayerItemController, GameObject>("_syncWithMeObject");
public static readonly FieldRef<PlayerItemController, Image> ItemVoiceIcon = Field<PlayerItemController, Image>("_voiceMuteImage");
public static readonly FieldRef<PlayerItemController, Image> ItemVoiceBg = Field<PlayerItemController, Image>("_voiceMuteBgImage");
public static readonly FieldRef<PlayerItemController, Sprite> ItemMicOpen = Field<PlayerItemController, Sprite>("_voiceChatOpen");
public static readonly FieldRef<PlayerItemController, Sprite> ItemMicMuted = Field<PlayerItemController, Sprite>("_voiceChatMute");
public static readonly FieldRef<SettingsController, Slider> SettingsVoiceSlider = Field<SettingsController, Slider>("_voiceVolumeSlider");
public static TField Get<TObject, TField>(FieldRef<TObject, TField> field, TObject instance) where TObject : class
{
if (field == null || instance == null)
{
return default(TField);
}
return field.Invoke(instance);
}
private static FieldRef<TObject, TField> Field<TObject, TField>(string name)
{
try
{
return AccessTools.FieldRefAccess<TObject, TField>(name);
}
catch (Exception ex)
{
Plugin.Log.LogWarning((object)("Game field " + typeof(TObject).Name + "." + name + " not found (" + ex.Message + "); some UI may be missing."));
return null;
}
}
}
internal static class Icons
{
private static Sprite _reset;
public static Sprite Reset
{
get
{
if ((Object)(object)_reset == (Object)null)
{
_reset = CreateResetIcon(64);
}
return _reset;
}
}
private static Sprite CreateResetIcon(int size)
{
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
//IL_003e: Unknown result type (might be due to invalid IL or missing references)
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
//IL_0045: Unknown result type (might be due to invalid IL or missing references)
//IL_004a: Unknown result type (might be due to invalid IL or missing references)
//IL_004f: Unknown result type (might be due to invalid IL or missing references)
//IL_0050: Unknown result type (might be due to invalid IL or missing references)
//IL_0056: Unknown result type (might be due to invalid IL or missing references)
//IL_005b: Unknown result type (might be due to invalid IL or missing references)
//IL_0060: 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_0063: Unknown result type (might be due to invalid IL or missing references)
//IL_0069: Unknown result type (might be due to invalid IL or missing references)
//IL_006e: Unknown result type (might be due to invalid IL or missing references)
//IL_0073: 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_007e: Unknown result type (might be due to invalid IL or missing references)
//IL_0083: Unknown result type (might be due to invalid IL or missing references)
//IL_0085: Unknown result type (might be due to invalid IL or missing references)
//IL_008b: Unknown result type (might be due to invalid IL or missing references)
//IL_0090: Unknown result type (might be due to invalid IL or missing references)
//IL_0095: 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_00a0: Unknown result type (might be due to invalid IL or missing references)
//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
//IL_01f2: Unknown result type (might be due to invalid IL or missing references)
//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
//IL_0204: 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_0215: Expected O, but got Unknown
//IL_0237: 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_01c3: Unknown result type (might be due to invalid IL or missing references)
//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
//IL_0133: Unknown result type (might be due to invalid IL or missing references)
//IL_0135: Unknown result type (might be due to invalid IL or missing references)
//IL_0151: Unknown result type (might be due to invalid IL or missing references)
//IL_0153: Unknown result type (might be due to invalid IL or missing references)
//IL_0155: Unknown result type (might be due to invalid IL or missing references)
//IL_015a: Unknown result type (might be due to invalid IL or missing references)
//IL_016a: Unknown result type (might be due to invalid IL or missing references)
//IL_016c: Unknown result type (might be due to invalid IL or missing references)
//IL_016e: Unknown result type (might be due to invalid IL or missing references)
//IL_0170: Unknown result type (might be due to invalid IL or missing references)
Vector2 val = default(Vector2);
((Vector2)(ref val))..ctor(0.5f, 0.5f);
float num = 0.6981317f;
Vector2 val2 = default(Vector2);
((Vector2)(ref val2))..ctor(Mathf.Cos(num), Mathf.Sin(num));
Vector2 val3 = default(Vector2);
((Vector2)(ref val3))..ctor(val2.y, 0f - val2.x);
Vector2 val4 = val + val2 * 0.31f;
Vector2 a = val4 + val3 * 0.17f;
Vector2 b = val4 + val2 * 0.16f - val3 * 0.03f;
Vector2 c = val4 - val2 * 0.16f - val3 * 0.03f;
float num2 = 5.5850534f;
Vector2 val5 = val + new Vector2(Mathf.Cos(num2), Mathf.Sin(num2)) * 0.31f;
Color32[] array = (Color32[])(object)new Color32[size * size];
Vector2 val6 = default(Vector2);
for (int i = 0; i < size; i++)
{
for (int j = 0; j < size; j++)
{
int num3 = 0;
for (int k = 0; k < 4; k++)
{
for (int l = 0; l < 4; l++)
{
((Vector2)(ref val6))..ctor(((float)j + ((float)l + 0.5f) / 4f) / (float)size, ((float)i + ((float)k + 0.5f) / 4f) / (float)size);
if (!OnArc(val6, val, 0.31f, 0.11f, 40f, 320f))
{
Vector2 val7 = val6 - val5;
if (!(((Vector2)(ref val7)).sqrMagnitude <= 0.003025f) && !InTriangle(val6, a, b, c))
{
continue;
}
}
num3++;
}
}
byte b2 = (byte)(255 * num3 / 16);
array[i * size + j] = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, b2);
}
}
Texture2D val8 = new Texture2D(size, size, (TextureFormat)4, false)
{
name = "PlayerVoiceVolume_Reset",
filterMode = (FilterMode)1,
wrapMode = (TextureWrapMode)1,
hideFlags = (HideFlags)61
};
val8.SetPixels32(array);
val8.Apply(false, true);
Sprite obj = Sprite.Create(val8, new Rect(0f, 0f, (float)size, (float)size), new Vector2(0.5f, 0.5f), (float)size);
((Object)obj).name = ((Object)val8).name;
((Object)obj).hideFlags = (HideFlags)61;
return obj;
}
private static bool OnArc(Vector2 p, Vector2 center, float radius, float stroke, float startDeg, float endDeg)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//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_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
Vector2 val = p - center;
if (Mathf.Abs(((Vector2)(ref val)).magnitude - radius) > stroke * 0.5f)
{
return false;
}
float num = Mathf.Atan2(val.y, val.x) * 57.29578f;
if (num < 0f)
{
num += 360f;
}
if (num >= startDeg)
{
return num <= endDeg;
}
return false;
}
private static bool InTriangle(Vector2 p, Vector2 a, Vector2 b, Vector2 c)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_0009: Unknown result type (might be due to invalid IL or missing references)
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
float num = Cross(p, a, b);
float num2 = Cross(p, b, c);
float num3 = Cross(p, c, a);
bool flag = num < 0f || num2 < 0f || num3 < 0f;
bool flag2 = num > 0f || num2 > 0f || num3 > 0f;
return !(flag && flag2);
}
private static float Cross(Vector2 p, Vector2 a, Vector2 b)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
return (p.x - b.x) * (a.y - b.y) - (a.x - b.x) * (p.y - b.y);
}
}
internal static class Patches
{
public static void Apply(Harmony harmony)
{
Postfix(harmony, "Start", "PlayerListStarted");
Postfix(harmony, "ButtonServer", "ServerTabSelected");
Postfix(harmony, "ButtonBanned", "BannedTabSelected");
Postfix(harmony, "ButtonClosePanel", "PlayerListClosed");
Postfix(harmony, "UpdateServerPanelOnChange", "PlayersChanged");
}
private static void Postfix(Harmony harmony, string method, string patch)
{
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
//IL_0054: Expected O, but got Unknown
try
{
MethodInfo methodInfo = AccessTools.Method(typeof(PlayerPanelController), method, (Type[])null, (Type[])null);
if (methodInfo == null)
{
Plugin.Log.LogWarning((object)("PlayerPanelController." + method + " not found; the Voice tab may not work."));
}
else
{
harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(Patches), patch, (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
}
}
catch (Exception arg)
{
Plugin.Log.LogError((object)$"Could not patch PlayerPanelController.{method}: {arg}");
}
}
private static void PlayerListStarted(PlayerPanelController __instance)
{
Run(delegate
{
GameAccess.PlayerPanel = __instance;
VoiceTab.EnsureInjected(__instance);
});
}
private static void ServerTabSelected(PlayerPanelController __instance)
{
Run(delegate
{
GameTabSelected(__instance, GameRefs.Get<PlayerPanelController, RectTransform>(GameRefs.ServerButton, __instance));
});
}
private static void BannedTabSelected(PlayerPanelController __instance)
{
Run(delegate
{
GameTabSelected(__instance, GameRefs.Get<PlayerPanelController, RectTransform>(GameRefs.BannedButton, __instance));
});
}
private static void GameTabSelected(PlayerPanelController players, RectTransform button)
{
VoiceTab.EnsureInjected(players);
VoiceTab current = VoiceTab.Current;
if ((Object)(object)current != (Object)null && (Object)(object)current.Panel == (Object)(object)players)
{
current.OnGameTabSelected(button);
}
}
private static void PlayerListClosed()
{
Run(delegate
{
Plugin.Instance.Store.Save();
});
}
private static void PlayersChanged()
{
Run(delegate
{
VoiceTab current = VoiceTab.Current;
if ((Object)(object)current != (Object)null)
{
current.MarkPlayersChanged();
}
});
}
private static void Run(Action action)
{
try
{
action();
}
catch (Exception ex)
{
Plugin.Log.LogError((object)("Player list hook failed: " + ex));
}
}
}
[BepInPlugin("ontogether.playervoicevolume", "PlayerVoiceVolume", "1.0.0")]
[BepInProcess("OnTogether.exe")]
public sealed class Plugin : BaseUnityPlugin
{
public const string PluginGuid = "ontogether.playervoicevolume";
public const string PluginName = "PlayerVoiceVolume";
public const string PluginVersion = "1.0.0";
internal ConfigEntry<int> MaxVolume;
internal ConfigEntry<int> DefaultVolume;
private VoiceApplier _applier;
private Harmony _harmony;
internal static Plugin Instance { get; private set; }
internal static ManualLogSource Log { get; private set; }
internal VolumeStore Store { get; private set; }
private void Awake()
{
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: Expected O, but got Unknown
//IL_0074: Unknown result type (might be due to invalid IL or missing references)
//IL_007e: Expected O, but got Unknown
//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
//IL_00c3: Expected O, but got Unknown
Instance = this;
Log = ((BaseUnityPlugin)this).Logger;
MaxVolume = ((BaseUnityPlugin)this).Config.Bind<int>("General", "MaxVolumePercent", 200, new ConfigDescription("Right end of the per-player volume slider, in percent. 100% leaves a player unchanged; every doubling is +10 dB, so 200% sounds about twice as loud. Values above 200% can distort loud voices.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(100, 400), Array.Empty<object>()));
DefaultVolume = ((BaseUnityPlugin)this).Config.Bind<int>("General", "DefaultVolumePercent", 100, new ConfigDescription("Volume of players you have not adjusted, in percent. The reset button on a player returns them to this value.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 400), Array.Empty<object>()));
Store = new VolumeStore(Path.Combine(Paths.ConfigPath, "ontogether.playervoicevolume.volumes.json"));
Store.Load();
_applier = new VoiceApplier();
_harmony = new Harmony("ontogether.playervoicevolume");
Patches.Apply(_harmony);
((BaseUnityPlugin)this).Config.SettingChanged += OnSettingChanged;
Log.LogInfo((object)string.Format("{0} {1} loaded; {2} saved player volume(s).", "PlayerVoiceVolume", "1.0.0", Store.Count));
}
private void Update()
{
_applier.Tick();
Store.SaveIfDue();
}
internal int VolumeFor(string steamId)
{
int percent;
return Mathf.Clamp(Store.TryGet(steamId, out percent) ? percent : DefaultVolume.Value, 0, MaxVolume.Value);
}
internal bool HasSavedVolume(string steamId)
{
int percent;
return Store.TryGet(steamId, out percent);
}
internal void SetVolume(string steamId, string playerName, int percent)
{
Store.Set(steamId, playerName, percent);
_applier.ApplySoon();
}
internal void ResetVolume(string steamId)
{
Store.Remove(steamId);
_applier.ApplySoon();
}
private void OnSettingChanged(object sender, SettingChangedEventArgs e)
{
_applier.ApplySoon();
VoiceTab current = VoiceTab.Current;
if ((Object)(object)current != (Object)null)
{
current.RefreshVolumes();
}
}
private void OnApplicationQuit()
{
Store.Save();
}
private void OnDestroy()
{
((BaseUnityPlugin)this).Config.SettingChanged -= OnSettingChanged;
Store.Save();
if (_harmony != null)
{
_harmony.UnpatchSelf();
}
}
}
internal static class Strings
{
private static string _language = "en";
public static string Tab => Pick("Voice", "Голос", "Voix", "Voz", "Voz", "ボイス", "语音");
public static string Hint => Pick("only for you", "только для вас", "pour vous seulement", "solo para ti", "só para você", "自分にだけ反映", "仅对你生效");
public static string NoPlayers => Pick("No other players here yet.", "Других игроков пока нет.", "Aucun autre joueur ici pour l'instant.", "Todavía no hay otros jugadores aquí.", "Ainda não há outros jogadores aqui.", "まだ他のプレイヤーはいません。", "这里还没有其他玩家。");
public static string ResetTitle => Pick("Reset Volume", "Сбросить громкость", "Réinitialiser le volume", "Restablecer volumen", "Redefinir volume", "音量をリセット", "重置音量");
public static string ResetInfo => Pick("Set this player's volume back to {0}.", "Вернуть громкость этого игрока к {0}.", "Remettre le volume de ce joueur à {0}.", "Devuelve el volumen de este jugador a {0}.", "Volta o volume deste jogador para {0}.", "このプレイヤーの音量を{0}に戻します。", "将该玩家的音量恢复为{0}。");
public static string Header => GameString("VoiceVolume") ?? Pick("Voice Volume", "Громкость голоса", "Volume de la voix", "Volumen de voz", "Volume da voz", "ボイス音量", "语音音量");
public static void Refresh()
{
try
{
_language = CurrentLanguage() ?? "en";
}
catch (Exception)
{
_language = "en";
}
}
private static string CurrentLanguage()
{
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
Locale selectedLocale = LocalizationSettings.SelectedLocale;
object obj;
if (!((Object)(object)selectedLocale != (Object)null))
{
obj = null;
}
else
{
LocaleIdentifier identifier = selectedLocale.Identifier;
obj = ((LocaleIdentifier)(ref identifier)).Code;
}
string text = (string)obj;
if (string.IsNullOrEmpty(text))
{
return null;
}
int num = text.IndexOfAny(new char[2] { '-', '_' });
return ((num > 0) ? text.Substring(0, num) : text).ToLowerInvariant();
}
private static string GameString(string key)
{
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
try
{
string localizedString = LocalizationSettings.StringDatabase.GetLocalizedString(TableReference.op_Implicit("General"), TableEntryReference.op_Implicit(key), (Locale)null, (FallbackBehavior)0, Array.Empty<object>());
if (string.IsNullOrEmpty(localizedString) || localizedString.StartsWith("No translation", StringComparison.OrdinalIgnoreCase))
{
return null;
}
return localizedString;
}
catch (Exception)
{
return null;
}
}
private static string Pick(string en, string ru, string fr, string es, string pt, string ja, string zh)
{
return _language switch
{
"ru" => ru,
"fr" => fr,
"es" => es,
"pt" => pt,
"ja" => ja,
"zh" => zh,
_ => en,
};
}
}
internal static class UiUtil
{
public static void RemoveLocalization(GameObject root)
{
MonoBehaviour[] componentsInChildren = root.GetComponentsInChildren<MonoBehaviour>(true);
foreach (MonoBehaviour val in componentsInChildren)
{
if ((Object)(object)val != (Object)null && ((object)val).GetType().Name == "LocalizeStringEvent")
{
Object.DestroyImmediate((Object)(object)val);
}
}
}
public static void SetOnClick(Button button, Action action)
{
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Expected O, but got Unknown
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
//IL_002f: Expected O, but got Unknown
button.onClick = new ButtonClickedEvent();
((UnityEvent)button.onClick).AddListener((UnityAction)delegate
{
try
{
action();
}
catch (Exception ex)
{
Plugin.Log.LogError((object)("UI action failed: " + ex));
}
});
}
public static void DisableNavigation(Selectable selectable)
{
//IL_0003: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
Navigation navigation = default(Navigation);
((Navigation)(ref navigation)).mode = (Mode)0;
selectable.navigation = navigation;
}
public static void Place(RectTransform rect, Vector2 anchor, Vector2 pivot, Vector2 position, Vector2 size)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
rect.anchorMin = anchor;
rect.anchorMax = anchor;
rect.pivot = pivot;
rect.anchoredPosition = position;
rect.sizeDelta = size;
}
public static void AddHover(GameObject target, Action enter, Action exit)
{
HoverRelay hoverRelay = target.GetComponent<HoverRelay>();
if ((Object)(object)hoverRelay == (Object)null)
{
hoverRelay = target.AddComponent<HoverRelay>();
}
hoverRelay.Enter = enter;
hoverRelay.Exit = exit;
}
public static Image NewImage(string name, Transform parent, Sprite sprite, Color color, float pixelsPerUnit)
{
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
//IL_0044: 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)
GameObject val = new GameObject(name, new Type[3]
{
typeof(RectTransform),
typeof(CanvasRenderer),
typeof(Image)
})
{
layer = ((Component)parent).gameObject.layer
};
val.transform.SetParent(parent, false);
Image component = val.GetComponent<Image>();
component.sprite = sprite;
component.type = (Type)(((Object)(object)sprite != (Object)null) ? 1 : 0);
component.pixelsPerUnitMultiplier = pixelsPerUnit;
((Graphic)component).color = color;
return component;
}
public static RectTransform NewRect(string name, Transform parent)
{
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: 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_003c: Unknown result type (might be due to invalid IL or missing references)
//IL_0042: Expected O, but got Unknown
GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) })
{
layer = ((Component)parent).gameObject.layer
};
val.transform.SetParent(parent, false);
return (RectTransform)val.transform;
}
public static void Stretch(RectTransform rect, Vector2 anchorMin, Vector2 anchorMax, Vector2 sizeDelta, Vector2 position)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
rect.anchorMin = anchorMin;
rect.anchorMax = anchorMax;
rect.pivot = new Vector2(0.5f, 0.5f);
rect.sizeDelta = sizeDelta;
rect.anchoredPosition = position;
}
}
internal sealed class HoverRelay : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerExitHandler
{
internal Action Enter;
internal Action Exit;
private bool _hovered;
public void OnPointerEnter(PointerEventData eventData)
{
_hovered = true;
Invoke(Enter);
}
public void OnPointerExit(PointerEventData eventData)
{
_hovered = false;
Invoke(Exit);
}
private void OnDisable()
{
if (_hovered)
{
_hovered = false;
Invoke(Exit);
}
}
private static void Invoke(Action action)
{
if (action == null)
{
return;
}
try
{
action();
}
catch (Exception ex)
{
Plugin.Log.LogWarning((object)("Hover action failed: " + ex.Message));
}
}
}
internal sealed class VoiceApplier
{
private struct Request
{
public VivoxParticipant Participant;
public int Value;
public float Time;
}
private const float Interval = 0.5f;
private const float SoonDelay = 0.1f;
private const float RetryAfter = 3f;
private readonly Dictionary<string, Request> _requests = new Dictionary<string, Request>(StringComparer.Ordinal);
private float _nextRun;
private string _lastError;
public void ApplySoon()
{
_nextRun = Mathf.Min(_nextRun, Time.unscaledTime + 0.1f);
}
public void Tick()
{
float unscaledTime = Time.unscaledTime;
if (unscaledTime < _nextRun)
{
return;
}
_nextRun = unscaledTime + 0.5f;
try
{
ApplyAll(unscaledTime);
}
catch (Exception e)
{
Report(e);
}
}
private void Report(Exception e)
{
string text = e.GetType().Name + ": " + e.Message;
if (!(text == _lastError))
{
_lastError = text;
Plugin.Log.LogWarning((object)("Could not apply player volumes: " + e));
}
}
private void ApplyAll(float now)
{
IVivoxService instance = VivoxService.Instance;
if (instance == null)
{
return;
}
ReadOnlyDictionary<string, ReadOnlyCollection<VivoxParticipant>> activeChannels = instance.ActiveChannels;
if (activeChannels == null || activeChannels.Count == 0)
{
return;
}
PlayerPanelController playerPanel = GameAccess.PlayerPanel;
if ((Object)(object)playerPanel == (Object)null)
{
return;
}
foreach (KeyValuePair<string, ReadOnlyCollection<VivoxParticipant>> item in activeChannels)
{
if (item.Value == null)
{
continue;
}
foreach (VivoxParticipant item2 in item.Value)
{
try
{
ApplyTo(item2, playerPanel, now);
}
catch (Exception e)
{
Report(e);
}
}
}
if (_requests.Count > 64)
{
_requests.Clear();
}
}
private void ApplyTo(VivoxParticipant participant, PlayerPanelController players, float now)
{
if (participant == null || participant.IsSelf)
{
return;
}
string playerId = participant.PlayerId;
int num = ((players.VivoxIDs != null) ? players.VivoxIDs.IndexOf(playerId) : (-1));
if (num >= 0 && players.PlayerSteamIDs != null && num < players.PlayerSteamIDs.Count)
{
int num2 = VolumeMath.ToVivox(Plugin.Instance.VolumeFor(players.PlayerSteamIDs[num]));
Request value;
if (participant.LocalVolume == num2)
{
_requests.Remove(playerId);
}
else if (!_requests.TryGetValue(playerId, out value) || value.Participant != participant || value.Value != num2 || !(now - value.Time < 3f))
{
participant.SetLocalVolume(num2);
_requests[playerId] = new Request
{
Participant = participant,
Value = num2,
Time = now
};
}
}
}
}
internal sealed class VoiceRow : MonoBehaviour
{
private const float GapAfterName = 18f;
private const float SliderX = 474f;
private const float SliderWidth = 360f;
private const float SliderHeight = 30f;
private const float ValueX = 850f;
private const float ValueWidth = 140f;
private const float ResetButtonCenterFromRight = 42.5f;
private const float ResetIconSize = 40f;
private VoiceTab _tab;
private TMP_Text _name;
private Slider _slider;
private CanvasGroup _sliderGroup;
private TMP_Text _value;
private RectTransform _voiceButton;
private Image _voiceBackground;
private Image _voiceIcon;
private Sprite _micOpen;
private Sprite _micMuted;
private RectTransform _resetButton;
private string _rawName;
private bool _binding;
private VoiceStatus? _shownStatus;
internal string SteamId { get; private set; }
internal string DisplayName { get; private set; }
internal VoiceStatus Status { get; private set; } = (VoiceStatus)3;
internal static VoiceRow Create(VoiceTab tab, GameObject prefab, Transform parent, Slider sliderTemplate, Sprite panelSprite)
{
GameObject val = Object.Instantiate<GameObject>(prefab, parent, false);
((Object)val).name = "Item_PlayerVoiceVolume";
VoiceRow voiceRow = val.AddComponent<VoiceRow>();
voiceRow._tab = tab;
try
{
voiceRow.Build(val.GetComponent<PlayerItemController>(), sliderTemplate, panelSprite);
return voiceRow;
}
catch
{
Object.Destroy((Object)(object)val);
throw;
}
}
private void Build(PlayerItemController item, Slider sliderTemplate, Sprite panelSprite)
{
//IL_0057: Unknown result type (might be due to invalid IL or missing references)
//IL_0061: Expected O, but got Unknown
//IL_021f: Unknown result type (might be due to invalid IL or missing references)
//IL_0239: Unknown result type (might be due to invalid IL or missing references)
//IL_024b: Unknown result type (might be due to invalid IL or missing references)
//IL_0255: Unknown result type (might be due to invalid IL or missing references)
//IL_02ab: Unknown result type (might be due to invalid IL or missing references)
//IL_02b5: Expected O, but got Unknown
//IL_02f3: Unknown result type (might be due to invalid IL or missing references)
//IL_0302: Unknown result type (might be due to invalid IL or missing references)
//IL_0311: Unknown result type (might be due to invalid IL or missing references)
//IL_0320: Unknown result type (might be due to invalid IL or missing references)
//IL_032f: Unknown result type (might be due to invalid IL or missing references)
//IL_0339: Expected O, but got Unknown
//IL_03ce: Unknown result type (might be due to invalid IL or missing references)
//IL_03dd: Unknown result type (might be due to invalid IL or missing references)
//IL_03e9: Unknown result type (might be due to invalid IL or missing references)
//IL_03f3: Unknown result type (might be due to invalid IL or missing references)
//IL_03ff: Unknown result type (might be due to invalid IL or missing references)
//IL_0409: Unknown result type (might be due to invalid IL or missing references)
//IL_0441: Unknown result type (might be due to invalid IL or missing references)
//IL_044b: Expected O, but got Unknown
//IL_0451: Unknown result type (might be due to invalid IL or missing references)
//IL_0456: Unknown result type (might be due to invalid IL or missing references)
//IL_045a: Unknown result type (might be due to invalid IL or missing references)
//IL_0482: Unknown result type (might be due to invalid IL or missing references)
//IL_0487: Unknown result type (might be due to invalid IL or missing references)
//IL_048b: Unknown result type (might be due to invalid IL or missing references)
//IL_0475: Unknown result type (might be due to invalid IL or missing references)
//IL_0490: Unknown result type (might be due to invalid IL or missing references)
//IL_04b4: Unknown result type (might be due to invalid IL or missing references)
//IL_04c3: Unknown result type (might be due to invalid IL or missing references)
//IL_04d2: Unknown result type (might be due to invalid IL or missing references)
//IL_04d7: Unknown result type (might be due to invalid IL or missing references)
//IL_050c: Unknown result type (might be due to invalid IL or missing references)
//IL_0527: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)item == (Object)null)
{
throw new InvalidOperationException("the player row prefab has no PlayerItemController");
}
TextMeshProUGUI val = GameRefs.Get<PlayerItemController, TextMeshProUGUI>(GameRefs.ItemName, item);
Button val2 = GameRefs.Get<PlayerItemController, Button>(GameRefs.ItemVoiceMute, item);
if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null)
{
throw new InvalidOperationException("the player row layout has changed");
}
_name = (TMP_Text)(object)val;
_voiceButton = (RectTransform)((Component)val2).transform;
_voiceBackground = GameRefs.Get<PlayerItemController, Image>(GameRefs.ItemVoiceBg, item);
_voiceIcon = GameRefs.Get<PlayerItemController, Image>(GameRefs.ItemVoiceIcon, item);
_micOpen = GameRefs.Get<PlayerItemController, Sprite>(GameRefs.ItemMicOpen, item);
_micMuted = GameRefs.Get<PlayerItemController, Sprite>(GameRefs.ItemMicMuted, item);
Button val3 = GameRefs.Get<PlayerItemController, Button>(GameRefs.ItemMute, item);
Transform val4 = (((Object)(object)val3 != (Object)null) ? ((Component)val3).transform.parent : null);
List<GameObject> list = new List<GameObject>();
Button[] array = (Button[])(object)new Button[4]
{
GameRefs.Get<PlayerItemController, Button>(GameRefs.ItemReport, item),
GameRefs.Get<PlayerItemController, Button>(GameRefs.ItemBan, item),
GameRefs.Get<PlayerItemController, Button>(GameRefs.ItemSteam, item),
GameRefs.Get<PlayerItemController, Button>(GameRefs.ItemIgnore, item)
};
foreach (Button val5 in array)
{
if ((Object)(object)val5 != (Object)null)
{
list.Add(((Component)val5).gameObject);
}
}
list.Add(GameRefs.Get<PlayerItemController, GameObject>(GameRefs.ItemSync, item));
list.Add(GameRefs.Get<PlayerItemController, GameObject>(GameRefs.ItemSyncedWithMe, item));
foreach (GameObject item2 in list)
{
if ((Object)(object)item2 != (Object)null)
{
Object.DestroyImmediate((Object)(object)item2);
}
}
PlayerPanelButtonController[] componentsInChildren = ((Component)this).GetComponentsInChildren<PlayerPanelButtonController>(true);
for (int i = 0; i < componentsInChildren.Length; i++)
{
Object.DestroyImmediate((Object)(object)componentsInChildren[i]);
}
Object.DestroyImmediate((Object)(object)item);
UiUtil.SetOnClick(val2, OnVoiceButton);
UiUtil.AddHover(((Component)val2).gameObject, ShowVoiceInfo, HideInfo);
UiUtil.DisableNavigation((Selectable)(object)val2);
RectTransform rectTransform = _name.rectTransform;
float num = 456f - rectTransform.anchoredPosition.x;
if (num > 50f && num < rectTransform.sizeDelta.x)
{
rectTransform.sizeDelta = new Vector2(num, rectTransform.sizeDelta.y);
}
_name.overflowMode = (TextOverflowModes)1;
_slider = (((Object)(object)sliderTemplate != (Object)null) ? Object.Instantiate<Slider>(sliderTemplate, ((Component)this).transform, false) : BuildSlider(((Component)this).transform, panelSprite));
((Object)_slider).name = "Slider_Volume";
_slider.onValueChanged = new SliderEvent();
UiUtil.DisableNavigation((Selectable)(object)_slider);
_slider.direction = (Direction)0;
_slider.minValue = 0f;
_slider.wholeNumbers = true;
UiUtil.Place((RectTransform)((Component)_slider).transform, new Vector2(0f, 0.5f), new Vector2(0f, 0.5f), new Vector2(474f, 0f), new Vector2(360f, 30f));
_sliderGroup = ((Component)_slider).gameObject.AddComponent<CanvasGroup>();
((UnityEvent<float>)(object)_slider.onValueChanged).AddListener((UnityAction<float>)OnSliderChanged);
_value = Object.Instantiate<GameObject>(((Component)_name).gameObject, ((Component)this).transform, false).GetComponent<TMP_Text>();
((Object)_value).name = "Text_Volume";
_value.alignment = (TextAlignmentOptions)514;
_value.overflowMode = (TextOverflowModes)0;
UiUtil.Place(_value.rectTransform, new Vector2(0f, 0.5f), new Vector2(0f, 0.5f), new Vector2(850f, rectTransform.anchoredPosition.y), new Vector2(140f, rectTransform.sizeDelta.y));
Button val6 = (((Object)(object)val3 != (Object)null) ? val3 : BuildButton(((Component)this).transform, panelSprite));
((Object)val6).name = "Button_ResetVolume";
_resetButton = (RectTransform)((Component)val6).transform;
Rect rect = _resetButton.rect;
? val7;
if (!(((Rect)(ref rect)).size.x > 1f))
{
val7 = new Vector2(65f, 65f);
}
else
{
rect = _resetButton.rect;
val7 = ((Rect)(ref rect)).size;
}
Vector2 size = (Vector2)val7;
((Transform)_resetButton).SetParent(((Component)this).transform, false);
UiUtil.Place(_resetButton, new Vector2(1f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(-42.5f, 0f), size);
Image val8 = FindIcon(val6);
if ((Object)(object)val8 != (Object)null)
{
val8.sprite = Icons.Reset;
val8.preserveAspect = true;
((Graphic)val8).rectTransform.anchoredPosition = Vector2.zero;
((Graphic)val8).rectTransform.sizeDelta = new Vector2(40f, 40f);
}
UiUtil.SetOnClick(val6, OnResetButton);
UiUtil.AddHover(((Component)val6).gameObject, ShowResetInfo, HideInfo);
UiUtil.DisableNavigation((Selectable)(object)val6);
if ((Object)(object)val4 != (Object)null && (Object)(object)val4 != (Object)(object)((Component)this).transform && val4.childCount == 0)
{
Object.DestroyImmediate((Object)(object)((Component)val4).gameObject);
}
}
internal void Bind(string steamId, string rawName, bool force)
{
bool num = steamId != SteamId;
SteamId = steamId;
if (num || rawName != _rawName)
{
_rawName = rawName;
DisplayName = GameAccess.FilterName(rawName) ?? string.Empty;
_name.text = DisplayName;
Plugin.Instance.Store.RememberName(steamId, DisplayName);
}
if (num || force)
{
ShowVolume(Plugin.Instance.VolumeFor(steamId));
_shownStatus = null;
}
}
private void ShowVolume(int percent)
{
_binding = true;
try
{
_slider.maxValue = Plugin.Instance.MaxVolume.Value;
_slider.SetValueWithoutNotify((float)percent);
}
finally
{
_binding = false;
}
_value.text = VolumeMath.Format(percent);
}
private void OnSliderChanged(float value)
{
if (!_binding && !string.IsNullOrEmpty(SteamId))
{
int percent = Mathf.RoundToInt(value);
Plugin.Instance.SetVolume(SteamId, DisplayName, percent);
_value.text = VolumeMath.Format(percent);
}
}
private void OnResetButton()
{
if (!string.IsNullOrEmpty(SteamId))
{
Plugin.Instance.ResetVolume(SteamId);
ShowVolume(Plugin.Instance.VolumeFor(SteamId));
GameAccess.PlayUIClick();
}
}
private void OnVoiceButton()
{
PlayerPanelController panel = _tab.Panel;
PlayerItemController val = FindGameRow(panel);
if ((Object)(object)val == (Object)null)
{
panel.UpdateServerPanel();
val = FindGameRow(panel);
}
if ((Object)(object)val == (Object)null)
{
Plugin.Log.LogWarning((object)("No player list entry for " + DisplayName + "; cannot toggle the voice mute."));
return;
}
val.ButtonVoiceMutePlayer();
RefreshStatus();
ShowVoiceInfo();
}
private PlayerItemController FindGameRow(PlayerPanelController players)
{
List<PlayerItemController> list = GameRefs.Get<PlayerPanelController, List<PlayerItemController>>(GameRefs.Items, players);
if (list == null)
{
return null;
}
foreach (PlayerItemController item in list)
{
if ((Object)(object)item != (Object)null && ((Component)item).gameObject.activeSelf && GameRefs.Get<PlayerItemController, string>(GameRefs.ItemSteamId, item) == SteamId)
{
return item;
}
}
return null;
}
internal void RefreshStatus()
{
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
//IL_0042: Unknown result type (might be due to invalid IL or missing references)
//IL_0045: Unknown result type (might be due to invalid IL or missing references)
//IL_004a: Unknown result type (might be due to invalid IL or missing references)
//IL_005a: Unknown result type (might be due to invalid IL or missing references)
//IL_006a: Unknown result type (might be due to invalid IL or missing references)
//IL_0070: Invalid comparison between Unknown and I4
//IL_00af: Unknown result type (might be due to invalid IL or missing references)
//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
//IL_00b7: Invalid comparison between Unknown and I4
//IL_0093: Unknown result type (might be due to invalid IL or missing references)
//IL_008b: Unknown result type (might be due to invalid IL or missing references)
//IL_00c6: 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_00bb: Invalid comparison between Unknown and I4
//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
//IL_00fd: Invalid comparison between Unknown and I4
//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
//IL_0100: Unknown result type (might be due to invalid IL or missing references)
//IL_0106: Invalid comparison between Unknown and I4
//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
PlayerPanelController panel = _tab.Panel;
if ((Object)(object)panel == (Object)null || string.IsNullOrEmpty(SteamId))
{
return;
}
Status = GameAccess.VoiceStatusOf(panel, SteamId);
if (_shownStatus == (VoiceStatus?)Status)
{
return;
}
_shownStatus = Status;
bool flag = (int)Status == 2;
if ((Object)(object)_voiceBackground != (Object)null)
{
((Graphic)_voiceBackground).color = (flag ? panel.RedColor : panel.IconDeactiveColor);
}
if ((Object)(object)_voiceIcon != (Object)null)
{
VoiceStatus status = Status;
if ((int)status != 1)
{
if ((int)status == 2)
{
((Graphic)_voiceIcon).color = panel.IconColor;
}
else
{
((Graphic)_voiceIcon).color = panel.MicIconInactiveColor;
}
}
else
{
((Graphic)_voiceIcon).color = panel.IconActiveColor;
}
Sprite val = (((int)Status == 2 || (int)Status == 3) ? _micMuted : _micOpen);
if ((Object)(object)val != (Object)null)
{
_voiceIcon.sprite = val;
}
}
_sliderGroup.alpha = (flag ? 0.45f : 1f);
}
private void ShowVoiceInfo()
{
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
PlayerPanelController panel = _tab.Panel;
if ((Object)(object)panel != (Object)null)
{
panel.OpenButtonInfoPopup((PlayerPanelButtonType)6, _voiceButton, Status, (PomoSyncStatus)0);
}
}
private void ShowResetInfo()
{
int percent = Mathf.Clamp(Plugin.Instance.DefaultVolume.Value, 0, Plugin.Instance.MaxVolume.Value);
_tab.ShowInfo(_resetButton, Strings.ResetTitle, string.Format(Strings.ResetInfo, VolumeMath.Format(percent)));
}
private void HideInfo()
{
PlayerPanelController val = (((Object)(object)_tab != (Object)null) ? _tab.Panel : null);
if ((Object)(object)val != (Object)null)
{
val.CloseButtonInfoPopup();
}
}
private static Image FindIcon(Button button)
{
Image[] componentsInChildren = ((Component)button).GetComponentsInChildren<Image>(true);
foreach (Image val in componentsInChildren)
{
if ((Object)(object)((Component)val).gameObject != (Object)(object)((Component)button).gameObject)
{
return val;
}
}
return null;
}
private static Slider BuildSlider(Transform parent, Sprite sprite)
{
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
//IL_004f: Unknown result type (might be due to invalid IL or missing references)
//IL_0054: Unknown result type (might be due to invalid IL or missing references)
//IL_0059: Unknown result type (might be due to invalid IL or missing references)
//IL_007a: Unknown result type (might be due to invalid IL or missing references)
//IL_0089: Unknown result type (might be due to invalid IL or missing references)
//IL_0098: Unknown result type (might be due to invalid IL or missing references)
//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
//IL_0100: Unknown result type (might be due to invalid IL or missing references)
//IL_0117: Unknown result type (might be due to invalid IL or missing references)
//IL_011c: Unknown result type (might be due to invalid IL or missing references)
//IL_012b: Unknown result type (might be due to invalid IL or missing references)
//IL_0130: Unknown result type (might be due to invalid IL or missing references)
//IL_0150: Unknown result type (might be due to invalid IL or missing references)
//IL_0168: Unknown result type (might be due to invalid IL or missing references)
//IL_0177: Unknown result type (might be due to invalid IL or missing references)
//IL_0186: Unknown result type (might be due to invalid IL or missing references)
//IL_018b: Unknown result type (might be due to invalid IL or missing references)
//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
RectTransform val = UiUtil.NewRect("Slider", parent);
UiUtil.Stretch(((Graphic)UiUtil.NewImage("Background", (Transform)(object)val, sprite, new Color(0.773f, 0.714f, 0.682f), 10f)).rectTransform, new Vector2(0f, 0.25f), new Vector2(1f, 0.75f), Vector2.zero, Vector2.zero);
RectTransform val2 = UiUtil.NewRect("Fill Area", (Transform)(object)val);
UiUtil.Stretch(val2, new Vector2(0f, 0.25f), new Vector2(1f, 0.75f), new Vector2(-20f, 0f), new Vector2(-5f, 0f));
Image val3 = UiUtil.NewImage("Fill", (Transform)(object)val2, sprite, new Color(0.416f, 0.302f, 0.322f), 10f);
UiUtil.Stretch(((Graphic)val3).rectTransform, Vector2.zero, new Vector2(0f, 1f), new Vector2(10f, 0f), Vector2.zero);
RectTransform val4 = UiUtil.NewRect("Handle Slide Area", (Transform)(object)val);
UiUtil.Stretch(val4, Vector2.zero, Vector2.one, new Vector2(-20f, 0f), Vector2.zero);
Image val5 = UiUtil.NewImage("Handle", (Transform)(object)val4, sprite, new Color(0.961f, 0.929f, 0.882f), 6f);
UiUtil.Stretch(((Graphic)val5).rectTransform, Vector2.zero, new Vector2(0f, 1f), new Vector2(22f, 12f), Vector2.zero);
((Shadow)((Component)val5).gameObject.AddComponent<Outline>()).effectColor = new Color(0.416f, 0.302f, 0.322f);
Slider obj = ((Component)val).gameObject.AddComponent<Slider>();
obj.fillRect = ((Graphic)val3).rectTransform;
obj.handleRect = ((Graphic)val5).rectTransform;
((Selectable)obj).targetGraphic = (Graphic)(object)val5;
return obj;
}
private static Button BuildButton(Transform parent, Sprite sprite)
{
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_0053: 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)
Image val = UiUtil.NewImage("Button", parent, sprite, new Color(0.906f, 0.663f, 0.4f), 7.2f);
Button obj = ((Component)val).gameObject.AddComponent<Button>();
((Selectable)obj).targetGraphic = (Graphic)(object)val;
((Graphic)UiUtil.NewImage("Image_Icon", ((Component)val).transform, null, new Color(0.961f, 0.929f, 0.882f), 1f)).raycastTarget = false;
((Graphic)val).rectTransform.sizeDelta = new Vector2(65f, 65f);
return obj;
}
}
internal sealed class VoiceTab : MonoBehaviour
{
private const float SelectedHeight = 107.2f;
private const float UnselectedHeight = 97.2f;
private const float TweenTime = 0.2f;
private const float ListSyncInterval = 0.5f;
private static readonly Color FallbackSelected = new Color(0.961f, 0.929f, 0.882f);
private static readonly Color FallbackServer = new Color(0.906f, 0.663f, 0.4f);
private static readonly Color FallbackBanned = new Color(0.906f, 0.502f, 0.427f);
private static readonly Color FallbackGreen = new Color(0.702f, 0.82f, 0.498f);
private static PlayerPanelController _failedFor;
private PlayerPanelController _players;
private RectTransform _tabButton;
private TMP_Text _tabLabel;
private Transform _background;
private ScrollRect _scroll;
private TMP_Text _header;
private TMP_Text _empty;
private GameObject _rowPrefab;
private Slider _sliderTemplate;
private Sprite _panelSprite;
private readonly List<VoiceRow> _rows = new List<VoiceRow>();
private bool _selected;
private bool _rowsFailed;
private float _nextSync;
private string _lastError;
internal static VoiceTab Current { get; private set; }
internal PlayerPanelController Panel => _players;
internal static void EnsureInjected(PlayerPanelController players)
{
if ((Object)(object)players == (Object)null || (Object)(object)players == (Object)(object)_failedFor || ((Object)(object)Current != (Object)null && (Object)(object)Current._players == (Object)(object)players))
{
return;
}
try
{
Inject(players);
}
catch (Exception ex)
{
_failedFor = players;
Plugin.Log.LogError((object)("Could not add the Voice tab to the player list (volumes still apply): " + ex));
}
}
private static void Inject(PlayerPanelController players)
{
//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
//IL_00cb: Expected O, but got Unknown
//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
//IL_00d4: 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_00df: Unknown result type (might be due to invalid IL or missing references)
//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
//IL_022e: Unknown result type (might be due to invalid IL or missing references)
//IL_0235: Expected O, but got Unknown
//IL_02da: Unknown result type (might be due to invalid IL or missing references)
GameObject obj = GameRefs.Get<PlayerPanelController, GameObject>(GameRefs.ServerList, players);
RectTransform val = GameRefs.Get<PlayerPanelController, RectTransform>(GameRefs.ServerButton, players);
RectTransform val2 = GameRefs.Get<PlayerPanelController, RectTransform>(GameRefs.BannedButton, players);
GameObject val3 = GameRefs.Get<PlayerPanelController, GameObject>(GameRefs.ItemPrefab, players);
if ((Object)(object)obj == (Object)null || (Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null || (Object)(object)val3 == (Object)null)
{
throw new InvalidOperationException("the player list layout has changed");
}
Transform parent = obj.transform.parent;
if ((Object)(object)parent == (Object)null || (Object)(object)parent.parent != (Object)(object)((Transform)val2).parent)
{
throw new InvalidOperationException("the player list layout has changed");
}
Strings.Refresh();
GameObject val4 = Object.Instantiate<GameObject>(((Component)val2).gameObject, ((Transform)val2).parent, false);
((Object)val4).name = "Button_Voice";
UiUtil.RemoveLocalization(val4);
RectTransform val5 = (RectTransform)val4.transform;
val5.anchoredPosition = val2.anchoredPosition + (val2.anchoredPosition - val.anchoredPosition);
((Transform)val5).SetSiblingIndex(parent.GetSiblingIndex());
GameObject val6 = Object.Instantiate<GameObject>(obj, parent, false);
((Object)val6).name = "Scrollview_Voice";
val6.SetActive(false);
UiUtil.RemoveLocalization(val6);
ScrollRect component = val6.GetComponent<ScrollRect>();
if ((Object)(object)component == (Object)null || (Object)(object)component.content == (Object)null)
{
Object.Destroy((Object)(object)val4);
Object.Destroy((Object)(object)val6);
throw new InvalidOperationException("the Server list has no scroll view");
}
RectTransform content = component.content;
for (int num = ((Transform)content).childCount - 1; num >= 0; num--)
{
GameObject gameObject = ((Component)((Transform)content).GetChild(num)).gameObject;
if ((Object)(object)gameObject.GetComponent<PlayerItemController>() != (Object)null)
{
Object.DestroyImmediate((Object)(object)gameObject);
}
}
VoiceTab voiceTab = val6.AddComponent<VoiceTab>();
voiceTab._players = players;
voiceTab._tabButton = val5;
voiceTab._tabLabel = val4.GetComponentInChildren<TMP_Text>(true);
voiceTab._background = parent;
voiceTab._scroll = component;
voiceTab._rowPrefab = val3;
voiceTab._sliderTemplate = GameRefs.Get<SettingsController, Slider>(GameRefs.SettingsVoiceSlider, MonoSingleton<SettingsController>.I);
Image component2 = ((Component)parent).GetComponent<Image>();
voiceTab._panelSprite = (((Object)(object)component2 != (Object)null) ? component2.sprite : null);
foreach (Transform item in (Transform)content)
{
Transform val7 = item;
voiceTab._header = ((Component)val7).GetComponent<TMP_Text>();
if ((Object)(object)voiceTab._header != (Object)null)
{
break;
}
}
if ((Object)(object)voiceTab._header != (Object)null)
{
voiceTab._empty = Object.Instantiate<GameObject>(((Component)voiceTab._header).gameObject, (Transform)(object)content, false).GetComponent<TMP_Text>();
((Object)voiceTab._empty).name = "Text_NoPlayers";
voiceTab._empty.fontSize = voiceTab._header.fontSize * 0.85f;
((Graphic)voiceTab._empty).color = players.IconActiveColor;
((Component)voiceTab._empty).gameObject.SetActive(false);
}
Button component3 = val4.GetComponent<Button>();
UiUtil.SetOnClick(component3, voiceTab.OnTabClicked);
UiUtil.DisableNavigation((Selectable)(object)component3);
voiceTab.RefreshTexts();
voiceTab.ShowTabAsSelected(selected: false, animate: false);
Current = voiceTab;
_failedFor = null;
Plugin.Log.LogInfo((object)"Added the Voice tab to the player list.");
}
private void OnDestroy()
{
if ((Object)(object)Current == (Object)(object)this)
{
Current = null;
}
if ((Object)(object)_tabButton != (Object)null)
{
Object.Destroy((Object)(object)((Component)_tabButton).gameObject);
}
if ((Object)(object)Plugin.Instance != (Object)null)
{
Plugin.Instance.Store.Save();
}
}
private void OnTabClicked()
{
if (!_selected)
{
GameAccess.PlayUIChange();
Select();
}
}
private void Select()
{
//IL_008b: Unknown result type (might be due to invalid IL or missing references)
//IL_0090: Unknown result type (might be due to invalid IL or missing references)
//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
_selected = true;
if (GameRefs.PanelType != null)
{
GameRefs.PanelType.Invoke(_players) = (PlayerPanelType)0;
}
GameObject val = GameRefs.Get<PlayerPanelController, GameObject>(GameRefs.ServerList, _players);
GameObject val2 = GameRefs.Get<PlayerPanelController, GameObject>(GameRefs.BannedList, _players);
if ((Object)(object)val != (Object)null)
{
val.SetActive(false);
}
if ((Object)(object)val2 != (Object)null)
{
val2.SetActive(false);
}
RectTransform val3 = GameRefs.Get<PlayerPanelController, RectTransform>(GameRefs.ServerButton, _players);
RectTransform val4 = GameRefs.Get<PlayerPanelController, RectTransform>(GameRefs.BannedButton, _players);
Animate(val3, ColorOf(GameRefs.ServerColor, FallbackServer), 97.2f, animate: true);
Animate(val4, ColorOf(GameRefs.BannedColor, FallbackBanned), 97.2f, animate: true);
ShowTabAsSelected(selected: true, animate: true);
PutInFront(_tabButton, val3, val4);
((Component)this).gameObject.SetActive(true);
RefreshTexts();
SyncRows(force: true);
LayoutRebuilder.ForceRebuildLayoutImmediate(_scroll.content);
_scroll.verticalNormalizedPosition = 1f;
}
internal void OnGameTabSelected(RectTransform selectedButton)
{
bool selected = _selected;
_selected = false;
((Component)this).gameObject.SetActive(false);
ShowTabAsSelected(selected: false, selected);
RectTransform val = GameRefs.Get<PlayerPanelController, RectTransform>(GameRefs.ServerButton, _players);
RectTransform val2 = GameRefs.Get<PlayerPanelController, RectTransform>(GameRefs.BannedButton, _players);
RectTransform val3 = (((Object)(object)selectedButton == (Object)(object)val) ? val2 : val);
PutInFront(selectedButton, val3, _tabButton);
if (!selected)
{
RefreshTexts();
}
}
private void ShowTabAsSelected(bool selected, bool animate)
{
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_0009: Unknown result type (might be due to invalid IL or missing references)
//IL_000e: 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_002c: Unknown result type (might be due to invalid IL or missing references)
Color color = (selected ? ColorOf(GameRefs.SelectedColor, FallbackSelected) : ColorOf(GameRefs.GreenColor, FallbackGreen));
Animate(_tabButton, color, selected ? 107.2f : 97.2f, animate);
}
private Color ColorOf(FieldRef<PlayerPanelController, Color> field, Color fallback)
{
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: 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_0034: Unknown result type (might be due to invalid IL or missing references)
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
if (field == null || (Object)(object)_players == (Object)null)
{
return fallback;
}
Color val = field.Invoke(_players);
if (!(val.a > 0f))
{
return fallback;
}
return val;
}
private static void Animate(RectTransform button, Color color, float height, bool animate)
{
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
//IL_006f: 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_0051: Unknown result type (might be due to invalid IL or missing references)
//IL_004a: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)button == (Object)null)
{
return;
}
Image component = ((Component)button).GetComponent<Image>();
Vector2 val = default(Vector2);
((Vector2)(ref val))..ctor(button.sizeDelta.x, height);
ShortcutExtensions.DOKill((Component)(object)button, false);
if ((Object)(object)component != (Object)null)
{
ShortcutExtensions.DOKill((Component)(object)component, false);
}
if (!animate)
{
if ((Object)(object)component != (Object)null)
{
((Graphic)component).color = color;
}
button.sizeDelta = val;
}
else
{
if ((Object)(object)component != (Object)null)
{
DOTweenModuleUI.DOColor(component, color, 0.2f);
}
DOTweenModuleUI.DOSizeDelta(button, val, 0.2f, false);
}
}
private void PutInFront(RectTransform selected, params RectTransform[] others)
{
if ((Object)(object)_background == (Object)null)
{
return;
}
foreach (RectTransform val in others)
{
if ((Object)(object)val != (Object)null && (Object)(object)((Transform)val).parent == (Object)(object)_background.parent && ((Transform)val).GetSiblingIndex() > _background.GetSiblingIndex())
{
((Transform)val).SetSiblingIndex(_background.GetSiblingIndex());
}
}
if ((Object)(object)selected != (Object)null && (Object)(object)((Transform)selected).parent == (Object)(object)_background.parent && ((Transform)selected).GetSiblingIndex() < _background.GetSiblingIndex())
{
((Transform)selected).SetSiblingIndex(_background.GetSiblingIndex());
}
}
private void RefreshTexts()
{
//IL_0055: Unknown result type (might be due to invalid IL or missing references)
Strings.Refresh();
if ((Object)(object)_tabLabel != (Object)null)
{
_tabLabel.text = Strings.Tab;
}
if ((Object)(object)_header != (Object)null)
{
_header.text = Strings.Header + " <size=70%><color=#" + ColorUtility.ToHtmlStringRGB(_players.IconActiveColor) + ">· " + Strings.Hint + "</color></size>";
}
if ((Object)(object)_empty != (Object)null)
{
_empty.text = Strings.NoPlayers;
}
}
internal void RefreshVolumes()
{
if (_selected)
{
SyncRows(force: true);
}
}
internal void MarkPlayersChanged()
{
_nextSync = 0f;
}
private void Update()
{
try
{
if (Time.unscaledTime >= _nextSync)
{
SyncRows(force: false);
}
for (int i = 0; i < _rows.Count; i++)
{
VoiceRow voiceRow = _rows[i];
if ((Object)(object)voiceRow != (Object)null && ((Component)voiceRow).gameObject.activeSelf)
{
voiceRow.RefreshStatus();
}
}
}
catch (Exception ex)
{
string text = ex.GetType().Name + ": " + ex.Message;
if (text != _lastError)
{
_lastError = text;
Plugin.Log.LogError((object)("Voice tab update failed: " + ex));
}
}
}
private void SyncRows(bool force)
{
_nextSync = Time.unscaledTime + 0.5f;
PlayerPanelController players = _players;
if ((Object)(object)players == (Object)null || players.PlayerSteamIDs == null)
{
return;
}
int num = 0;
for (int i = 0; i < players.PlayerSteamIDs.Count; i++)
{
string text = players.PlayerSteamIDs[i];
if (!string.IsNullOrEmpty(text) && !GameAccess.IsLocalPlayer(players, i))
{
VoiceRow voiceRow = ((num < _rows.Count) ? _rows[num] : AddRow());
if ((Object)(object)voiceRow == (Object)null)
{
break;
}
if (!((Component)voiceRow).gameObject.activeSelf)
{
((Component)voiceRow).gameObject.SetActive(true);
}
voiceRow.Bind(text, GameAccess.RawPlayerName(players, i), force);
num++;
}
}
for (int j = num; j < _rows.Count; j++)
{
if ((Object)(object)_rows[j] != (Object)null && ((Component)_rows[j]).gameObject.activeSelf)
{
((Component)_rows[j]).gameObject.SetActive(false);
}
}
if ((Object)(object)_empty != (Object)null && ((Component)_empty).gameObject.activeSelf != (num == 0))
{
((Component)_empty).gameObject.SetActive(num == 0);
}
}
private VoiceRow AddRow()
{
if (_rowsFailed)
{
return null;
}
try
{
VoiceRow voiceRow = VoiceRow.Create(this, _rowPrefab, (Transform)(object)_scroll.content, _sliderTemplate, _panelSprite);
_rows.Add(voiceRow);
return voiceRow;
}
catch (Exception ex)
{
_rowsFailed = true;
Plugin.Log.LogError((object)("Could not create a player row in the Voice tab: " + ex));
return null;
}
}
internal void ShowInfo(RectTransform anchor, string title, string text)
{
//IL_0082: Unknown result type (might be due to invalid IL or missing references)
//IL_0087: Unknown result type (might be due to invalid IL or missing references)
//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
RectTransform val = GameRefs.Get<PlayerPanelController, RectTransform>(GameRefs.InfoPanel, _players);
CanvasGroup val2 = GameRefs.Get<PlayerPanelController, CanvasGroup>(GameRefs.InfoGroup, _players);
if (!((Object)(object)val == (Object)null) && !((Object)(object)val2 == (Object)null) && !((Object)(object)anchor == (Object)null))
{
Image val3 = GameRefs.Get<PlayerPanelController, Image>(GameRefs.InfoHeaderBg, _players);
TextMeshProUGUI val4 = GameRefs.Get<PlayerPanelController, TextMeshProUGUI>(GameRefs.InfoHeader, _players);
TextMeshProUGUI val5 = GameRefs.Get<PlayerPanelController, TextMeshProUGUI>(GameRefs.InfoText, _players);
if ((Object)(object)val3 != (Object)null)
{
((Graphic)val3).color = ColorOf(GameRefs.OrangeColor, FallbackServer);
}
if ((Object)(object)val4 != (Object)null)
{
((TMP_Text)val4).text = title;
}
if ((Object)(object)val5 != (Object)null)
{
((TMP_Text)val5).text = text;
}
((Transform)val).position = ((Transform)anchor).position;
DOTweenModuleUI.DOFade(val2, 1f, 0.15f);
}
}
}
internal static class VolumeMath
{
public const int VivoxMute = -50;
public const int VivoxMax = 50;
public static int ToVivox(int percent)
{
if (percent <= 0)
{
return -50;
}
return Mathf.Clamp((int)Math.Round(10.0 * Math.Log((double)percent / 100.0, 2.0)), -49, 50);
}
public static string Format(int percent)
{
return "%" + percent;
}
}
[Serializable]
internal sealed class SavedVolume
{
public string steamId;
public string name;
public int volume;
}
[Serializable]
internal sealed class SavedVolumes
{
public int version = 1;
public List<SavedVolume> players = new List<SavedVolume>();
}
internal sealed class VolumeStore
{
private const float SaveDelay = 2f;
private const int MaxPercent = 400;
private readonly string _path;
private readonly Dictionary<string, SavedVolume> _byId = new Dictionary<string, SavedVolume>(StringComparer.Ordinal);
private bool _dirty;
private float _saveAt;
public int Count => _byId.Count;
public VolumeStore(string path)
{
_path = path;
}
public bool TryGet(string steamId, out int percent)
{
if (!string.IsNullOrEmpty(steamId) && _byId.TryGetValue(steamId, out var value))
{
percent = value.volume;
return true;
}
percent = 0;
return false;
}
public void Set(string steamId, string name, int percent)
{
if (!string.IsNullOrEmpty(steamId))
{
percent = Mathf.Clamp(percent, 0, 400);
if (!_byId.TryGetValue(steamId, out var value))
{
value = new SavedVolume
{
steamId = steamId,
volume = percent
};
_byId[steamId] = value;
MarkDirty();
}
else if (value.volume != percent)
{
value.volume = percent;
MarkDirty();
}
if (!string.IsNullOrEmpty(name) && value.name != name)
{
value.name = name;
MarkDirty();
}
}
}
public void Remove(string steamId)
{
if (!string.IsNullOrEmpty(steamId) && _byId.Remove(steamId))
{
MarkDirty();
}
}
public void RememberName(string steamId, string name)
{
if (!string.IsNullOrEmpty(steamId) && !string.IsNullOrEmpty(name) && _byId.TryGetValue(steamId, out var value) && value.name != name)
{
value.name = name;
MarkDirty();
}
}
private void MarkDirty()
{
_dirty = true;
_saveAt = Time.unscaledTime + 2f;
}
public void SaveIfDue()
{
if (_dirty && Time.unscaledTime >= _saveAt)
{
Save();
}
}
public void Load()
{
_byId.Clear();
if (!File.Exists(_path))
{
return;
}
try
{
SavedVolumes savedVolumes = JsonUtility.FromJson<SavedVolumes>(File.ReadAllText(_path, Encoding.UTF8));
if (savedVolumes == null || savedVolumes.players == null)
{
return;
}
foreach (SavedVolume player in savedVolumes.players)
{
if (player != null && !string.IsNullOrEmpty(player.steamId))
{
player.volume = Mathf.Clamp(player.volume, 0, 400);
_byId[player.steamId] = player;
}
}
}
catch (Exception ex)
{
string text = _path + ".bad";
Plugin.Log.LogError((object)("Could not read " + _path + ": " + ex.Message + ". A copy was kept as " + text + "."));
try
{
File.Copy(_path, text, overwrite: true);
}
catch (Exception ex2)
{
Plugin.Log.LogWarning((object)("Could not back up the file: " + ex2.Message));
}
}
}
public void Save()
{
if (!_dirty)
{
return;
}
_dirty = false;
try
{
SavedVolumes savedVolumes = new SavedVolumes
{
players = _byId.Values.OrderBy<SavedVolume, string>((SavedVolume e) => e.name ?? e.steamId, StringComparer.OrdinalIgnoreCase).ToList()
};
string text = _path + ".tmp";
File.WriteAllText(text, JsonUtility.ToJson((object)savedVolumes, true), new UTF8Encoding(encoderShouldEmitUTF8Identifier: false));
File.Copy(text, _path, overwrite: true);
File.Delete(text);
}
catch (Exception ex)
{
Plugin.Log.LogError((object)("Could not save player volumes to " + _path + ": " + ex.Message));
}
}
}