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 BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using ExitGames.Client.Photon;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using Photon.Realtime;
using RepoMods.PropHunt;
using TMPro;
using UnityEngine;
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: IgnoresAccessChecksTo("")]
[assembly: AssemblyCompany("REPOJP")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("zabuMod")]
[assembly: AssemblyTitle("zabuMod")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace REPOJP.PropHuntFix
{
[BepInPlugin("REPOJP.PropHunt_Fix", "PropHunt_Fix", "1.0.0")]
public class PropHuntFixPlugin : BaseUnityPlugin
{
internal static PropHuntFixPlugin Instance;
internal static ManualLogSource Log;
internal static Harmony Harmony;
internal const int RecentHunterWeight0 = 100;
internal const int RecentHunterWeight1 = 50;
internal const int RecentHunterWeight2 = 20;
internal const int RecentHunterWeight3 = 5;
internal const float LowestCountBonusMultiplier = 1.75f;
internal static ConfigEntry<int> CfgHunterCount;
internal static ConfigEntry<int> CfgRoundRoomCount;
internal static ConfigEntry<bool> CfgGiveMapPlayerCountUpgrade;
internal static ConfigEntry<bool> CfgRefillHuntersWhenHunterLeaves;
internal static ConfigEntry<bool> CfgEnableHunterAllyNameHighlight;
internal static ConfigEntry<bool> CfgWriteHunterSelectionLog;
internal static ConfigEntry<float> CfgEyeRefreshInterval;
internal static ConfigEntry<int> CfgDeathSoundVolumePercent;
internal static ConfigEntry<int> CfgWinSoundVolumePercent;
internal static ConfigEntry<int> CfgCountdownSoundVolumePercent;
internal static ConfigEntry<int> CfgMainMenuMusicVolumePercent;
internal static ConfigEntry<FixLanguage> CfgLanguage;
private GameObject runtimeRoot;
private void Awake()
{
//IL_0041: Unknown result type (might be due to invalid IL or missing references)
//IL_004b: Expected O, but got Unknown
//IL_0073: Unknown result type (might be due to invalid IL or missing references)
//IL_007d: Expected O, but got Unknown
//IL_012a: Unknown result type (might be due to invalid IL or missing references)
//IL_0134: Expected O, but got Unknown
//IL_015d: Unknown result type (might be due to invalid IL or missing references)
//IL_0167: Expected O, but got Unknown
//IL_0190: Unknown result type (might be due to invalid IL or missing references)
//IL_019a: Expected O, but got Unknown
//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
//IL_01cd: Expected O, but got Unknown
//IL_0217: Unknown result type (might be due to invalid IL or missing references)
//IL_0221: Expected O, but got Unknown
Instance = this;
Log = ((BaseUnityPlugin)this).Logger;
PropHuntAudioUtil.EnsureReady();
MainMenuMusicVolumeService.EnsureStarted();
CfgHunterCount = ((BaseUnityPlugin)this).Config.Bind<int>("Gameplay", "HunterCount", 1, new ConfigDescription("Hunter count per round. ラウンドごとの鬼人数", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 10), Array.Empty<object>()));
CfgRoundRoomCount = ((BaseUnityPlugin)this).Config.Bind<int>("MapGeneration", "RoundRoomCount", 2, new ConfigDescription("Generated room count for PropHunt rounds. PropHuntラウンドの生成部屋数", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 20), Array.Empty<object>()));
CfgGiveMapPlayerCountUpgrade = ((BaseUnityPlugin)this).Config.Bind<bool>("Gameplay", "GiveMapPlayerCountUpgrade", true, "Give the map player count upgrade to all players in PropHunt. PropHunt中に全員へマッププレイヤーカウントアップグレードを配布");
CfgRefillHuntersWhenHunterLeaves = ((BaseUnityPlugin)this).Config.Bind<bool>("Gameplay", "RefillHuntersWhenHunterLeaves", true, "Refill hunter slots if a hunter leaves mid-round. 鬼離脱時の補充");
CfgEnableHunterAllyNameHighlight = ((BaseUnityPlugin)this).Config.Bind<bool>("Visual", "EnableHunterAllyNameHighlight", true, "Show allied hunter name tags in red for hunters. 鬼同士の赤ネームタグ表示");
CfgEyeRefreshInterval = ((BaseUnityPlugin)this).Config.Bind<float>("Visual", "EyeRefreshInterval", 0.75f, "Eye color refresh interval in seconds. 目色再適用間隔(秒)");
CfgDeathSoundVolumePercent = ((BaseUnityPlugin)this).Config.Bind<int>("Audio", "DeathSoundVolumePercent", 50, new ConfigDescription("Death sound volume percent. 死亡音の音量(%)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
CfgWinSoundVolumePercent = ((BaseUnityPlugin)this).Config.Bind<int>("Audio", "WinSoundVolumePercent", 50, new ConfigDescription("Win result sound volume percent. 勝利結果音の音量(%)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
CfgCountdownSoundVolumePercent = ((BaseUnityPlugin)this).Config.Bind<int>("Audio", "CountdownSoundVolumePercent", 50, new ConfigDescription("Hunter unlock countdown beep volume percent. 鬼ロック解除カウントダウン音の音量(%)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
CfgMainMenuMusicVolumePercent = ((BaseUnityPlugin)this).Config.Bind<int>("Audio", "MainMenuMusicVolumePercent", 50, new ConfigDescription("Main menu custom music volume percent. メインメニュー独自BGM音量(%)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
CfgLanguage = ((BaseUnityPlugin)this).Config.Bind<FixLanguage>("Localization", "Language", FixLanguage.English, "Display language. AutoTranslatorConfig.ini Language is used automatically when supported. 表示言語。対応言語の場合はAutoTranslatorConfig.iniのLanguageを自動使用");
CfgWriteHunterSelectionLog = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "WriteHunterSelectionLog", true, "Write hunter selection logs. 抽選ログ出力");
Harmony = new Harmony("REPOJP.PropHunt_Fix");
Harmony.PatchAll();
Log.LogInfo((object)"[PropHunt_Fix] Loaded v1.0.0");
}
internal static void EnsureRuntimeRoot()
{
//IL_0036: Unknown result type (might be due to invalid IL or missing references)
//IL_003c: Expected O, but got Unknown
try
{
if (!((Object)(object)Instance == (Object)null) && !((Object)(object)Instance.runtimeRoot != (Object)null))
{
GameObject val = new GameObject("PropHunt_Fix_Runtime");
val.transform.parent = null;
((Object)val).hideFlags = (HideFlags)61;
Object.DontDestroyOnLoad((Object)(object)val);
val.AddComponent<HostConfigSyncService>();
val.AddComponent<ClientConfigApplyService>();
val.AddComponent<EyeColorRefreshService>();
val.AddComponent<ReadySyncService>();
val.AddComponent<NameTagOriginalPatchDisabler>();
val.AddComponent<LocalHunterUnlockAudioService>();
val.AddComponent<PropHuntFixHudService>();
val.AddComponent<MapPlayerCountUpgradeService>();
val.AddComponent<DisguiseFlashlightSuppressService>();
val.AddComponent<LockPhaseRevealAndStaminaService>();
val.AddComponent<PostMatchVoiceAllHearService>();
Instance.runtimeRoot = val;
Log.LogInfo((object)"[PropHunt_Fix] Runtime initialized.");
}
}
catch (Exception ex)
{
Log.LogWarning((object)("[PropHunt_Fix] Runtime init failed: " + ex.Message));
}
}
}
public enum NonHunterEyeColorMode
{
Green,
Black,
Pink,
Yellow,
None
}
public enum FixLanguage
{
English,
Japanese,
Chinese,
Korean,
Russian,
French,
Spanish,
German,
Portuguese
}
internal static class FixLocalization
{
private static bool autoLoaded;
private static bool hasAutoLanguage;
private static FixLanguage autoLanguage;
public static FixLanguage Current
{
get
{
LoadAutoLanguageOnce();
if (hasAutoLanguage)
{
return autoLanguage;
}
try
{
if (PropHuntFixPlugin.CfgLanguage != null)
{
return PropHuntFixPlugin.CfgLanguage.Value;
}
}
catch
{
}
return FixLanguage.English;
}
}
private static void LoadAutoLanguageOnce()
{
if (autoLoaded)
{
return;
}
autoLoaded = true;
try
{
string path = Path.Combine(Paths.ConfigPath, "AutoTranslatorConfig.ini");
if (!File.Exists(path))
{
return;
}
string[] array = File.ReadAllLines(path);
for (int i = 0; i < array.Length; i++)
{
string text = array[i];
if (string.IsNullOrEmpty(text))
{
continue;
}
text = text.Trim();
if (text.StartsWith("Language=", StringComparison.OrdinalIgnoreCase))
{
if (TryParseLanguageCode(text.Substring("Language=".Length).Trim(), out var language))
{
autoLanguage = language;
hasAutoLanguage = true;
}
break;
}
}
}
catch
{
}
}
private static bool TryParseLanguageCode(string code, out FixLanguage language)
{
language = FixLanguage.English;
if (string.IsNullOrEmpty(code))
{
return false;
}
code = code.Trim().ToLowerInvariant();
int num = code.IndexOf('-');
if (num >= 0)
{
code = code.Substring(0, num);
}
if (code == "en")
{
language = FixLanguage.English;
return true;
}
if (code == "ja" || code == "jp")
{
language = FixLanguage.Japanese;
return true;
}
if (code == "zh" || code == "cn")
{
language = FixLanguage.Chinese;
return true;
}
if (code == "ko" || code == "kr")
{
language = FixLanguage.Korean;
return true;
}
switch (code)
{
case "ru":
language = FixLanguage.Russian;
return true;
case "fr":
language = FixLanguage.French;
return true;
case "es":
language = FixLanguage.Spanish;
return true;
case "de":
language = FixLanguage.German;
return true;
case "pt":
language = FixLanguage.Portuguese;
return true;
default:
return false;
}
}
public static string Text(string key)
{
FixLanguage current = Current;
return key switch
{
"Hunters" => Pick(current, "Hunters", "鬼", "猎人", "술래", "Охотники", "Chasseurs", "Cazadores", "Jäger", "Caçadores"),
"Hunter" => Pick(current, "HUNTER", "鬼", "猎人", "술래", "ОХОТНИК", "CHASSEUR", "CAZADOR", "JÄGER", "CAÇADOR"),
"Hider" => Pick(current, "HIDER", "逃げ側", "躲藏者", "도망자", "ПРЯЧУЩИЙСЯ", "CACHEUR", "OCULTO", "VERSTECKER", "ESCONDIDO"),
"PropHunt" => Pick(current, "PROP HUNT", "プロップハント", "躲猫猫", "프롭 헌트", "ОХОТА НА ПРЕДМЕТЫ", "PROP HUNT", "PROP HUNT", "PROP HUNT", "PROP HUNT"),
"ScanHelp" => Pick(current, "RMB: Scan | Miss penalty", "右クリック: スキャン | ミスでHP減少", "右键: 扫描 | 失误扣血", "우클릭: 스캔 | 실패 시 체력 감소", "ПКМ: Скан | Промах снимает HP", "Clic droit: scan | Échec: PV-", "Clic derecho: escanear | Fallo: PV-", "Rechtsklick: Scan | Fehlschuss: HP-", "Botão direito: escanear | Erro: HP-"),
"HiderHelp" => Pick(current, "Toggle disguise / View / Lock", "変身 / 視点 / 固定", "切换伪装 / 视角 / 锁定", "변장 / 시점 / 고정", "Маскировка / Вид / Фиксация", "Déguisement / Vue / Verrou", "Disfraz / Vista / Bloqueo", "Tarnung / Ansicht / Sperre", "Disfarce / Visão / Travar"),
"HideTime" => Pick(current, "Hide time", "隠れる時間", "躲藏时间", "숨는 시간", "Время прятаться", "Temps de cache", "Tiempo para esconderse", "Versteckzeit", "Tempo para esconder"),
"TimeLeft" => Pick(current, "Time left", "残り時間", "剩余时间", "남은 시간", "Осталось", "Temps restant", "Tiempo restante", "Verbleibende Zeit", "Tempo restante"),
"HunterLock" => Pick(current, "Hunter lock", "鬼ロック", "猎人锁定", "술래 잠금", "Блокировка охотника", "Blocage chasseur", "Bloqueo cazador", "Jägersperre", "Bloqueio do caçador"),
"Disguise" => Pick(current, "Disguise", "変身", "伪装", "변장", "Маскировка", "Déguisement", "Disfraz", "Tarnung", "Disfarce"),
"TargetLocked" => Pick(current, "Target locked", "対象固定済み", "目标已锁定", "대상 고정됨", "Цель выбрана", "Cible verrouillée", "Objetivo fijado", "Ziel fixiert", "Alvo travado"),
"LookValuable" => Pick(current, "Look at a Valuable to lock target", "貴重品を見て対象を固定", "看向贵重品来锁定目标", "귀중품을 봐서 대상 고정", "Посмотрите на ценность", "Regardez un objet de valeur", "Mira un valioso", "Wertgegenstand ansehen", "Olhe para um valioso"),
"Locked" => Pick(current, "LOCKED", "固定中", "已锁定", "고정됨", "ЗАФИКСИРОВАНО", "VERROUILLÉ", "BLOQUEADO", "GESPERRT", "TRAVADO"),
"Start" => Pick(current, "START", "スタート", "开始", "시작", "СТАРТ", "DÉPART", "INICIO", "START", "INICIAR"),
"NotReady" => Pick(current, "NOT READY", "未導入", "未就绪", "준비 안 됨", "НЕ ГОТОВ", "PAS PRÊT", "NO LISTO", "NICHT BEREIT", "NÃO PRONTO"),
"Sec" => Pick(current, "sec", "秒", "秒", "초", "сек", "s", "seg", "Sek", "s"),
"Min" => Pick(current, "min", "分", "分钟", "분", "мин", "min", "min", "Min", "min"),
"HidersWin" => Pick(current, "HIDERS WIN!", "逃げ側の勝利!", "躲藏者胜利!", "도망자 승리!", "ПРЯЧУЩИЕСЯ ПОБЕДИЛИ!", "CACHEURS GAGNENT!", "¡GANAN LOS OCULTOS!", "VERSTECKER GEWINNEN!", "ESCONDIDOS VENCEM!"),
"HunterWins" => Pick(current, "HUNTER WINS!", "鬼の勝利!", "猎人胜利!", "술래 승리!", "ОХОТНИК ПОБЕДИЛ!", "CHASSEUR GAGNE!", "¡GANA EL CAZADOR!", "JÄGER GEWINNT!", "CAÇADOR VENCE!"),
"Draw" => Pick(current, "DRAW", "引き分け", "平局", "무승부", "НИЧЬЯ", "ÉGALITÉ", "EMPATE", "UNENTSCHIEDEN", "EMPATE"),
"TimeExpired" => Pick(current, "Time expired", "時間切れ", "时间到", "시간 초과", "Время вышло", "Temps écoulé", "Tiempo agotado", "Zeit abgelaufen", "Tempo esgotado"),
"HunterEliminated" => Pick(current, "Hunter eliminated", "鬼が全滅", "猎人被消灭", "술래 제거됨", "Охотник устранён", "Chasseur éliminé", "Cazador eliminado", "Jäger eliminiert", "Caçador eliminado"),
"AllHidersEliminated" => Pick(current, "All hiders eliminated", "逃げ側が全滅", "躲藏者全灭", "도망자 전멸", "Все прячущиеся устранены", "Tous les cacheurs éliminés", "Todos los ocultos eliminados", "Alle Verstecker eliminiert", "Todos escondidos eliminados"),
_ => key,
};
}
public static string TranslateMessage(string message)
{
if (string.IsNullOrEmpty(message))
{
return message;
}
string text = message;
text = text.Replace("HIDERS WIN!", Text("HidersWin"));
text = text.Replace("HUNTER WINS!", Text("HunterWins"));
text = text.Replace("DRAW", Text("Draw"));
text = text.Replace("Time expired", Text("TimeExpired"));
text = text.Replace("Hunter eliminated", Text("HunterEliminated"));
text = text.Replace("All hiders eliminated", Text("AllHidersEliminated"));
text = text.Replace("View: third-person", Pick(Current, "View: third-person", "視点: 三人称", "视角: 第三人称", "시점: 3인칭", "Вид: от третьего лица", "Vue: troisième personne", "Vista: tercera persona", "Ansicht: dritte Person", "Visão: terceira pessoa"));
text = text.Replace("View: first-person", Pick(Current, "View: first-person", "視点: 一人称", "视角: 第一人称", "시점: 1인칭", "Вид: от первого лица", "Vue: première personne", "Vista: primera persona", "Ansicht: erste Person", "Visão: primeira pessoa"));
text = text.Replace("Position LOCKED", Pick(Current, "Position LOCKED", "位置固定", "位置已锁定", "위치 고정", "Позиция зафиксирована", "Position verrouillée", "Posición bloqueada", "Position gesperrt", "Posição travada"));
text = text.Replace("Position UNLOCKED", Pick(Current, "Position UNLOCKED", "位置固定解除", "位置解锁", "위치 해제", "Позиция разблокирована", "Position déverrouillée", "Posición desbloqueada", "Position entsperrt", "Posição destravada"));
text = text.Replace("Disguise cleared.", Pick(Current, "Disguise cleared.", "変身解除", "伪装已解除", "변장 해제", "Маскировка снята", "Déguisement retiré", "Disfraz eliminado", "Tarnung aufgehoben", "Disfarce removido"));
text = text.Replace("No disguise target. Look at a Valuable.", Pick(Current, "No disguise target. Look at a Valuable.", "変身対象なし。貴重品を見てください", "没有伪装目标。看向贵重品", "변장 대상 없음. 귀중품을 보세요", "Нет цели маскировки. Посмотрите на ценность", "Aucune cible. Regardez un objet de valeur", "Sin objetivo. Mira un valioso", "Kein Ziel. Wertgegenstand ansehen", "Sem alvo. Olhe para um valioso"));
return text.Replace("Disguised.", Pick(Current, "Disguised.", "変身しました", "已伪装", "변장 완료", "Замаскировано", "Déguisé", "Disfrazado", "Getarnt", "Disfarçado"));
}
public static string PickForInternal(string en, string ja, string zh, string ko, string ru, string fr, string es, string de, string pt)
{
return Pick(Current, en, ja, zh, ko, ru, fr, es, de, pt);
}
private static string Pick(FixLanguage language, string en, string ja, string zh, string ko, string ru, string fr, string es, string de, string pt)
{
return language switch
{
FixLanguage.Japanese => ja,
FixLanguage.Chinese => zh,
FixLanguage.Korean => ko,
FixLanguage.Russian => ru,
FixLanguage.French => fr,
FixLanguage.Spanish => es,
FixLanguage.German => de,
FixLanguage.Portuguese => pt,
_ => en,
};
}
}
internal static class OriginalPropHuntConfigBridge
{
private const float DefaultPreHideSeconds = 30f;
private const float DefaultHunterLockSeconds = 30f;
private const float DefaultRoundSeconds = 300f;
private const int DefaultMissPenaltyHP = 5;
private const float DefaultGunRangeMeters = 60f;
private const float DefaultGunCooldownSeconds = 0.18f;
private static ConfigEntryBase GetConfigEntry(string fieldName)
{
try
{
FieldInfo fieldInfo = AccessTools.Field(typeof(PropHuntPlugin), fieldName);
if (fieldInfo == null)
{
return null;
}
object value = fieldInfo.GetValue(null);
return (ConfigEntryBase)((value is ConfigEntryBase) ? value : null);
}
catch
{
return null;
}
}
private static float GetFloat(string fieldName, float defaultValue)
{
try
{
ConfigEntryBase configEntry = GetConfigEntry(fieldName);
if (configEntry != null && configEntry.BoxedValue != null)
{
object boxedValue = configEntry.BoxedValue;
if (boxedValue is float result)
{
return result;
}
if (boxedValue is int)
{
return (int)boxedValue;
}
if (boxedValue is double)
{
return (float)(double)boxedValue;
}
if (boxedValue is long)
{
return (long)boxedValue;
}
if (boxedValue is string s && float.TryParse(s, out var result2))
{
return result2;
}
}
}
catch
{
}
return defaultValue;
}
private static int GetInt(string fieldName, int defaultValue)
{
try
{
ConfigEntryBase configEntry = GetConfigEntry(fieldName);
if (configEntry != null && configEntry.BoxedValue != null)
{
object boxedValue = configEntry.BoxedValue;
if (boxedValue is int result)
{
return result;
}
if (boxedValue is int result2)
{
return result2;
}
if (boxedValue is int result3)
{
return result3;
}
if (boxedValue is long)
{
return (int)(long)boxedValue;
}
if (boxedValue is float)
{
return Mathf.RoundToInt((float)boxedValue);
}
if (boxedValue is string s && int.TryParse(s, out var result4))
{
return result4;
}
}
}
catch
{
}
return defaultValue;
}
public static float GetPreHideSeconds()
{
return Mathf.Max(1f, GetFloat("CfgPreHideSeconds", 30f));
}
public static float GetHunterLockSeconds()
{
return Mathf.Max(0f, GetFloat("CfgHunterLockSeconds", 30f));
}
public static float GetRoundSeconds()
{
return Mathf.Max(5f, GetFloat("CfgRoundSeconds", 300f));
}
public static int GetMissPenaltyHP()
{
return Mathf.Max(0, GetInt("CfgMissPenaltyHP", 5));
}
public static float GetGunRangeMeters()
{
return Mathf.Max(1f, GetFloat("CfgGunRangeMeters", 60f));
}
public static float GetGunCooldownSeconds()
{
return Mathf.Max(0f, GetFloat("CfgGunCooldownSeconds", 0.18f));
}
public static void SubscribeToOriginalConfigChanges(EventHandler handler)
{
SubscribeField("CfgPreHideSeconds", handler);
SubscribeField("CfgHunterLockSeconds", handler);
SubscribeField("CfgRoundSeconds", handler);
SubscribeField("CfgMissPenaltyHP", handler);
SubscribeField("CfgGunRangeMeters", handler);
SubscribeField("CfgGunCooldownSeconds", handler);
}
private static void SubscribeField(string fieldName, EventHandler handler)
{
try
{
ConfigEntryBase configEntry = GetConfigEntry(fieldName);
if (configEntry != null)
{
EventInfo @event = ((object)configEntry).GetType().GetEvent("SettingChanged", BindingFlags.Instance | BindingFlags.Public);
if (@event != null)
{
@event.AddEventHandler(configEntry, handler);
}
}
}
catch
{
}
}
}
internal class FixConfigSnapshot
{
public float PreHideSeconds;
public float HunterLockSeconds;
public float RoundSeconds;
public int MissPenaltyHP;
public float GunRangeMeters;
public float GunCooldownSeconds;
public int HunterCount;
public bool RefillHuntersWhenHunterLeaves;
public int RecentHunterWeight0;
public int RecentHunterWeight1;
public int RecentHunterWeight2;
public int RecentHunterWeight3;
public float LowestCountBonusMultiplier;
public NonHunterEyeColorMode NonHunterEyeColor;
public bool EnableHunterAllyNameHighlight;
public static FixConfigSnapshot FromLocalConfig()
{
FixConfigSnapshot fixConfigSnapshot = new FixConfigSnapshot();
fixConfigSnapshot.PreHideSeconds = OriginalPropHuntConfigBridge.GetPreHideSeconds();
fixConfigSnapshot.HunterLockSeconds = OriginalPropHuntConfigBridge.GetHunterLockSeconds();
fixConfigSnapshot.RoundSeconds = OriginalPropHuntConfigBridge.GetRoundSeconds();
fixConfigSnapshot.MissPenaltyHP = OriginalPropHuntConfigBridge.GetMissPenaltyHP();
fixConfigSnapshot.GunRangeMeters = OriginalPropHuntConfigBridge.GetGunRangeMeters();
fixConfigSnapshot.GunCooldownSeconds = OriginalPropHuntConfigBridge.GetGunCooldownSeconds();
fixConfigSnapshot.HunterCount = Mathf.Max(1, PropHuntFixPlugin.CfgHunterCount.Value);
fixConfigSnapshot.RefillHuntersWhenHunterLeaves = PropHuntFixPlugin.CfgRefillHuntersWhenHunterLeaves.Value;
fixConfigSnapshot.RecentHunterWeight0 = 100;
fixConfigSnapshot.RecentHunterWeight1 = 50;
fixConfigSnapshot.RecentHunterWeight2 = 20;
fixConfigSnapshot.RecentHunterWeight3 = 5;
fixConfigSnapshot.LowestCountBonusMultiplier = 1.75f;
fixConfigSnapshot.NonHunterEyeColor = NonHunterEyeColorMode.None;
fixConfigSnapshot.EnableHunterAllyNameHighlight = PropHuntFixPlugin.CfgEnableHunterAllyNameHighlight.Value;
return fixConfigSnapshot;
}
public bool EqualsTo(FixConfigSnapshot other)
{
if (other == null)
{
return false;
}
return PreHideSeconds == other.PreHideSeconds && HunterLockSeconds == other.HunterLockSeconds && RoundSeconds == other.RoundSeconds && MissPenaltyHP == other.MissPenaltyHP && GunRangeMeters == other.GunRangeMeters && GunCooldownSeconds == other.GunCooldownSeconds && HunterCount == other.HunterCount && RefillHuntersWhenHunterLeaves == other.RefillHuntersWhenHunterLeaves && RecentHunterWeight0 == other.RecentHunterWeight0 && RecentHunterWeight1 == other.RecentHunterWeight1 && RecentHunterWeight2 == other.RecentHunterWeight2 && RecentHunterWeight3 == other.RecentHunterWeight3 && Mathf.Approximately(LowestCountBonusMultiplier, other.LowestCountBonusMultiplier) && NonHunterEyeColor == other.NonHunterEyeColor && EnableHunterAllyNameHighlight == other.EnableHunterAllyNameHighlight;
}
public Hashtable ToHashtable()
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Expected O, but got Unknown
Hashtable val = new Hashtable();
val[(object)"PHFIX_CFG_PreHideSeconds"] = PreHideSeconds;
val[(object)"PHFIX_CFG_HunterLockSeconds"] = HunterLockSeconds;
val[(object)"PHFIX_CFG_RoundSeconds"] = RoundSeconds;
val[(object)"PHFIX_CFG_MissPenaltyHP"] = MissPenaltyHP;
val[(object)"PHFIX_CFG_GunRangeMeters"] = GunRangeMeters;
val[(object)"PHFIX_CFG_GunCooldownSeconds"] = GunCooldownSeconds;
val[(object)"PHFIX_CFG_HunterCount"] = HunterCount;
val[(object)"PHFIX_CFG_RefillHuntersWhenHunterLeaves"] = RefillHuntersWhenHunterLeaves;
val[(object)"PHFIX_CFG_RecentHunterWeight0"] = RecentHunterWeight0;
val[(object)"PHFIX_CFG_RecentHunterWeight1"] = RecentHunterWeight1;
val[(object)"PHFIX_CFG_RecentHunterWeight2"] = RecentHunterWeight2;
val[(object)"PHFIX_CFG_RecentHunterWeight3"] = RecentHunterWeight3;
val[(object)"PHFIX_CFG_LowestCountBonusMultiplier"] = LowestCountBonusMultiplier;
val[(object)"PHFIX_CFG_NonHunterEyeColor"] = (int)NonHunterEyeColor;
val[(object)"PHFIX_CFG_EnableHunterAllyNameHighlight"] = EnableHunterAllyNameHighlight;
return val;
}
public static FixConfigSnapshot FromRoomProperties(Hashtable props)
{
if (props == null)
{
return null;
}
FixConfigSnapshot fixConfigSnapshot = new FixConfigSnapshot();
if (!RoomPropUtil.TryGetFloat(props, "PHFIX_CFG_PreHideSeconds", out fixConfigSnapshot.PreHideSeconds))
{
return null;
}
if (!RoomPropUtil.TryGetFloat(props, "PHFIX_CFG_HunterLockSeconds", out fixConfigSnapshot.HunterLockSeconds))
{
return null;
}
if (!RoomPropUtil.TryGetFloat(props, "PHFIX_CFG_RoundSeconds", out fixConfigSnapshot.RoundSeconds))
{
return null;
}
if (!RoomPropUtil.TryGetInt(props, "PHFIX_CFG_MissPenaltyHP", out fixConfigSnapshot.MissPenaltyHP))
{
return null;
}
if (!RoomPropUtil.TryGetFloat(props, "PHFIX_CFG_GunRangeMeters", out fixConfigSnapshot.GunRangeMeters))
{
return null;
}
if (!RoomPropUtil.TryGetFloat(props, "PHFIX_CFG_GunCooldownSeconds", out fixConfigSnapshot.GunCooldownSeconds))
{
return null;
}
if (!RoomPropUtil.TryGetInt(props, "PHFIX_CFG_HunterCount", out fixConfigSnapshot.HunterCount))
{
return null;
}
if (!RoomPropUtil.TryGetBool(props, "PHFIX_CFG_RefillHuntersWhenHunterLeaves", out fixConfigSnapshot.RefillHuntersWhenHunterLeaves))
{
return null;
}
if (!RoomPropUtil.TryGetInt(props, "PHFIX_CFG_RecentHunterWeight0", out fixConfigSnapshot.RecentHunterWeight0))
{
return null;
}
if (!RoomPropUtil.TryGetInt(props, "PHFIX_CFG_RecentHunterWeight1", out fixConfigSnapshot.RecentHunterWeight1))
{
return null;
}
if (!RoomPropUtil.TryGetInt(props, "PHFIX_CFG_RecentHunterWeight2", out fixConfigSnapshot.RecentHunterWeight2))
{
return null;
}
if (!RoomPropUtil.TryGetInt(props, "PHFIX_CFG_RecentHunterWeight3", out fixConfigSnapshot.RecentHunterWeight3))
{
return null;
}
if (!RoomPropUtil.TryGetFloat(props, "PHFIX_CFG_LowestCountBonusMultiplier", out fixConfigSnapshot.LowestCountBonusMultiplier))
{
return null;
}
if (!RoomPropUtil.TryGetInt(props, "PHFIX_CFG_NonHunterEyeColor", out var value))
{
return null;
}
fixConfigSnapshot.NonHunterEyeColor = (NonHunterEyeColorMode)value;
if (!RoomPropUtil.TryGetBool(props, "PHFIX_CFG_EnableHunterAllyNameHighlight", out fixConfigSnapshot.EnableHunterAllyNameHighlight))
{
return null;
}
return fixConfigSnapshot;
}
}
internal static class RoomKeys
{
public const string Active = "PH_Active";
public const string Hunter = "PH_Hunter";
public const string Hunters = "PH_Hunters";
public const string UnlockAt = "PHFIX_UnlockAt";
public const string UnlockSerial = "PHFIX_UnlockSerial";
public const string CfgPreHideSeconds = "PHFIX_CFG_PreHideSeconds";
public const string CfgHunterLockSeconds = "PHFIX_CFG_HunterLockSeconds";
public const string CfgRoundSeconds = "PHFIX_CFG_RoundSeconds";
public const string CfgMissPenaltyHP = "PHFIX_CFG_MissPenaltyHP";
public const string CfgGunRangeMeters = "PHFIX_CFG_GunRangeMeters";
public const string CfgGunCooldownSeconds = "PHFIX_CFG_GunCooldownSeconds";
public const string CfgHunterCount = "PHFIX_CFG_HunterCount";
public const string CfgRefillHuntersWhenHunterLeaves = "PHFIX_CFG_RefillHuntersWhenHunterLeaves";
public const string CfgRecentHunterWeight0 = "PHFIX_CFG_RecentHunterWeight0";
public const string CfgRecentHunterWeight1 = "PHFIX_CFG_RecentHunterWeight1";
public const string CfgRecentHunterWeight2 = "PHFIX_CFG_RecentHunterWeight2";
public const string CfgRecentHunterWeight3 = "PHFIX_CFG_RecentHunterWeight3";
public const string CfgLowestCountBonusMultiplier = "PHFIX_CFG_LowestCountBonusMultiplier";
public const string CfgNonHunterEyeColor = "PHFIX_CFG_NonHunterEyeColor";
public const string CfgEnableHunterAllyNameHighlight = "PHFIX_CFG_EnableHunterAllyNameHighlight";
}
internal static class PlayerKeys
{
public const string Ready = "PHFIX_Ready";
public const string HasPropHunt = "PHFIX_HasPropHunt";
public const string HasFix = "PHFIX_HasFix";
public const string FixVersion = "PHFIX_Version";
}
internal static class RoomPropUtil
{
public static bool TryGetInt(Hashtable props, string key, out int value)
{
value = 0;
if (props == null || !((Dictionary<object, object>)(object)props).ContainsKey(key))
{
return false;
}
object obj = props[(object)key];
try
{
if (obj is int)
{
value = (int)obj;
return true;
}
if (obj is byte)
{
value = (byte)obj;
return true;
}
if (obj is short)
{
value = (short)obj;
return true;
}
if (obj is long)
{
value = (int)(long)obj;
return true;
}
if (obj is float)
{
value = Mathf.RoundToInt((float)obj);
return true;
}
if (obj is double)
{
value = (int)(double)obj;
return true;
}
if (obj is string && int.TryParse((string)obj, out value))
{
return true;
}
}
catch
{
}
return false;
}
public static bool TryGetFloat(Hashtable props, string key, out float value)
{
value = 0f;
if (props == null || !((Dictionary<object, object>)(object)props).ContainsKey(key))
{
return false;
}
object obj = props[(object)key];
try
{
if (obj is float)
{
value = (float)obj;
return true;
}
if (obj is int)
{
value = (int)obj;
return true;
}
if (obj is double)
{
value = (float)(double)obj;
return true;
}
if (obj is long)
{
value = (long)obj;
return true;
}
if (obj is string && float.TryParse((string)obj, out value))
{
return true;
}
}
catch
{
}
return false;
}
public static bool TryGetBool(Hashtable props, string key, out bool value)
{
value = false;
if (props == null || !((Dictionary<object, object>)(object)props).ContainsKey(key))
{
return false;
}
object obj = props[(object)key];
try
{
if (obj is bool)
{
value = (bool)obj;
return true;
}
if (obj is int)
{
value = (int)obj != 0;
return true;
}
if (obj is byte)
{
value = (byte)obj != 0;
return true;
}
if (obj is string && bool.TryParse((string)obj, out value))
{
return true;
}
}
catch
{
}
return false;
}
}
internal static class PropHuntFixState
{
private static readonly Random Rng = new Random();
public static readonly HashSet<int> CurrentHunters = new HashSet<int>();
public static readonly Dictionary<string, int> TotalHunterCountsByUserKey = new Dictionary<string, int>();
public static readonly Queue<List<string>> RecentHunterHistory = new Queue<List<string>>();
public static FixConfigSnapshot AppliedSnapshot;
public static FixConfigSnapshot PendingSnapshot;
public static bool PendingGameplayApply;
public static void ResetRoomState()
{
CurrentHunters.Clear();
RecentHunterHistory.Clear();
TotalHunterCountsByUserKey.Clear();
PendingSnapshot = null;
AppliedSnapshot = null;
PendingGameplayApply = false;
}
public static string GetIdentityKey(Player player)
{
if (player == null)
{
return "unknown";
}
try
{
if (!string.IsNullOrEmpty(player.UserId))
{
return "uid:" + player.UserId;
}
}
catch
{
}
try
{
object obj2 = ((AccessTools.Property(typeof(Player), "UserId") != null) ? player.UserId : null);
if (obj2 != null)
{
return "sid:" + obj2.ToString();
}
}
catch
{
}
return "actor:" + player.ActorNumber;
}
public static int GetRecentHunterCount(string userKey)
{
int num = 0;
foreach (List<string> item in RecentHunterHistory)
{
if (item.Contains(userKey))
{
num++;
}
}
return num;
}
public static int GetTotalHunterCount(string userKey)
{
if (TotalHunterCountsByUserKey.TryGetValue(userKey, out var value))
{
return value;
}
return 0;
}
public static void CommitSelectedHunters(List<Player> selectedPlayers)
{
if (selectedPlayers == null || selectedPlayers.Count == 0)
{
return;
}
List<string> list = new List<string>();
for (int i = 0; i < selectedPlayers.Count; i++)
{
Player player = selectedPlayers[i];
string identityKey = GetIdentityKey(player);
list.Add(identityKey);
if (!TotalHunterCountsByUserKey.ContainsKey(identityKey))
{
TotalHunterCountsByUserKey[identityKey] = 0;
}
TotalHunterCountsByUserKey[identityKey]++;
}
RecentHunterHistory.Enqueue(list);
while (RecentHunterHistory.Count > 3)
{
RecentHunterHistory.Dequeue();
}
}
public static float BuildWeight(Player player, FixConfigSnapshot snapshot, List<Player> allCandidates)
{
string identityKey = GetIdentityKey(player);
int recentHunterCount = GetRecentHunterCount(identityKey);
int totalHunterCount = GetTotalHunterCount(identityKey);
int num = int.MaxValue;
bool flag = true;
int num2 = int.MinValue;
for (int i = 0; i < allCandidates.Count; i++)
{
int totalHunterCount2 = GetTotalHunterCount(GetIdentityKey(allCandidates[i]));
if (i == 0)
{
num2 = totalHunterCount2;
}
else if (num2 != totalHunterCount2)
{
flag = false;
}
if (totalHunterCount2 < num)
{
num = totalHunterCount2;
}
}
float num3 = Mathf.Clamp(recentHunterCount, 0, 3) switch
{
0 => snapshot.RecentHunterWeight0,
1 => snapshot.RecentHunterWeight1,
2 => snapshot.RecentHunterWeight2,
_ => snapshot.RecentHunterWeight3,
};
if (!flag && totalHunterCount == num)
{
num3 *= snapshot.LowestCountBonusMultiplier;
}
return Mathf.Max(0.01f, num3);
}
public static List<Player> SelectHunters(List<Player> activePlayers, FixConfigSnapshot snapshot, ICollection<int> excludeActorNumbers)
{
List<Player> list = new List<Player>();
for (int i = 0; i < activePlayers.Count; i++)
{
Player val = activePlayers[i];
if (val != null && !val.IsInactive && (excludeActorNumbers == null || !excludeActorNumbers.Contains(val.ActorNumber)))
{
list.Add(val);
}
}
list = list.OrderBy((Player p) => p.ActorNumber).ToList();
int num = Mathf.Clamp(snapshot.HunterCount, 1, Mathf.Max(1, list.Count));
if (activePlayers.Count > 0)
{
num = Mathf.Min(num, Mathf.Max(1, activePlayers.Count - 1));
}
List<Player> list2 = new List<Player>();
while (list2.Count < num && list.Count > 0)
{
float num2 = 0f;
for (int j = 0; j < list.Count; j++)
{
num2 += BuildWeight(list[j], snapshot, list);
}
double num3 = Rng.NextDouble() * (double)num2;
double num4 = 0.0;
int index = list.Count - 1;
for (int k = 0; k < list.Count; k++)
{
num4 += (double)BuildWeight(list[k], snapshot, list);
if (num3 <= num4)
{
index = k;
break;
}
}
list2.Add(list[index]);
list.RemoveAt(index);
}
if (PropHuntFixPlugin.CfgWriteHunterSelectionLog.Value)
{
LogSelection(activePlayers, list2, snapshot);
}
return list2;
}
private static void LogSelection(List<Player> activePlayers, List<Player> selected, FixConfigSnapshot snapshot)
{
try
{
List<string> list = new List<string>();
for (int i = 0; i < activePlayers.Count; i++)
{
Player val = activePlayers[i];
string identityKey = GetIdentityKey(val);
list.Add(val.ActorNumber + "=" + GetTotalHunterCount(identityKey));
}
List<string> list2 = new List<string>();
for (int j = 0; j < selected.Count; j++)
{
list2.Add(selected[j].ActorNumber.ToString());
}
PropHuntFixPlugin.Log.LogInfo((object)("[PropHunt_Fix] Active players: " + activePlayers.Count));
PropHuntFixPlugin.Log.LogInfo((object)("[PropHunt_Fix] Config hunter count: " + snapshot.HunterCount));
PropHuntFixPlugin.Log.LogInfo((object)("[PropHunt_Fix] Total hunter counts: " + string.Join(", ", list.ToArray())));
PropHuntFixPlugin.Log.LogInfo((object)("[PropHunt_Fix] Selected hunters: " + string.Join(", ", list2.ToArray())));
}
catch (Exception ex)
{
PropHuntFixPlugin.Log.LogWarning((object)("[PropHunt_Fix] Selection log failed: " + ex.Message));
}
}
public static void SyncHuntersFromRoomProperties(Hashtable props)
{
CurrentHunters.Clear();
if (props == null)
{
return;
}
if (((Dictionary<object, object>)(object)props).ContainsKey("PH_Hunters"))
{
object obj = props[(object)"PH_Hunters"];
if (obj is int[])
{
int[] array = (int[])obj;
for (int i = 0; i < array.Length; i++)
{
CurrentHunters.Add(array[i]);
}
return;
}
if (obj is object[])
{
object[] array2 = (object[])obj;
for (int j = 0; j < array2.Length; j++)
{
if (TryToInt(array2[j], out var val))
{
CurrentHunters.Add(val);
}
}
return;
}
}
if (RoomPropUtil.TryGetInt(props, "PH_Hunter", out var value))
{
CurrentHunters.Add(value);
}
}
public static bool TryToInt(object o, out int val)
{
try
{
if (o is int)
{
val = (int)o;
return true;
}
if (o is byte)
{
val = (byte)o;
return true;
}
if (o is short)
{
val = (short)o;
return true;
}
if (o is long)
{
val = (int)(long)o;
return true;
}
if (o is float)
{
val = (int)(float)o;
return true;
}
if (o is double)
{
val = (int)(double)o;
return true;
}
if (o is string && int.TryParse((string)o, out val))
{
return true;
}
}
catch
{
}
val = -1;
return false;
}
}
public class ReadySyncService : MonoBehaviourPunCallbacks
{
public static bool IsLocalReadySent;
private void Start()
{
TrySendReady();
}
public override void OnJoinedRoom()
{
TrySendReady();
}
private void Update()
{
if (!IsLocalReadySent && PhotonNetwork.InRoom)
{
TrySendReady();
}
}
private void TrySendReady()
{
//IL_004e: Unknown result type (might be due to invalid IL or missing references)
//IL_0054: Expected O, but got Unknown
try
{
if (PhotonNetwork.InRoom && PhotonNetwork.LocalPlayer != null)
{
bool flag = AccessTools.TypeByName("RepoMods.PropHunt.PropHuntPlugin") != null;
bool flag2 = (Object)(object)PropHuntFixPlugin.Instance != (Object)null;
if (flag && flag2)
{
Hashtable val = new Hashtable();
val[(object)"PHFIX_Ready"] = true;
val[(object)"PHFIX_HasPropHunt"] = flag;
val[(object)"PHFIX_HasFix"] = flag2;
val[(object)"PHFIX_Version"] = "1.0.0";
PhotonNetwork.LocalPlayer.SetCustomProperties(val, (Hashtable)null, (WebFlags)null);
IsLocalReadySent = true;
}
}
}
catch
{
}
}
}
public class HunterLockAudioWatcher : MonoBehaviour
{
}
public class HostConfigSyncService : MonoBehaviourPunCallbacks
{
private static HostConfigSyncService Instance;
private FixConfigSnapshot lastWrittenSnapshot;
private void Awake()
{
Instance = this;
SubscribeConfigChanges();
}
public override void OnJoinedRoom()
{
TryWriteSnapshot();
}
public override void OnLeftRoom()
{
lastWrittenSnapshot = null;
}
public static void RequestWriteSnapshot()
{
try
{
if ((Object)(object)Instance != (Object)null)
{
Instance.TryWriteSnapshot();
return;
}
HostConfigSyncService hostConfigSyncService = Object.FindObjectOfType<HostConfigSyncService>();
if ((Object)(object)hostConfigSyncService != (Object)null)
{
hostConfigSyncService.TryWriteSnapshot();
}
}
catch
{
}
}
private void SubscribeConfigChanges()
{
OriginalPropHuntConfigBridge.SubscribeToOriginalConfigChanges(OnConfigChanged);
SubscribeConfigEntry((ConfigEntryBase)(object)PropHuntFixPlugin.CfgHunterCount, OnConfigChanged);
SubscribeConfigEntry((ConfigEntryBase)(object)PropHuntFixPlugin.CfgRefillHuntersWhenHunterLeaves, OnConfigChanged);
SubscribeConfigEntry((ConfigEntryBase)(object)PropHuntFixPlugin.CfgEnableHunterAllyNameHighlight, OnConfigChanged);
}
private void SubscribeConfigEntry(ConfigEntryBase entry, EventHandler handler)
{
try
{
if (entry != null)
{
EventInfo @event = ((object)entry).GetType().GetEvent("SettingChanged", BindingFlags.Instance | BindingFlags.Public);
if (@event != null)
{
@event.AddEventHandler(entry, handler);
}
}
}
catch
{
}
}
private void OnConfigChanged(object sender, EventArgs e)
{
TryWriteSnapshot();
}
public void TryWriteSnapshot()
{
if (!PhotonNetwork.InRoom || !PhotonNetwork.IsMasterClient || PhotonNetwork.CurrentRoom == null)
{
return;
}
FixConfigSnapshot fixConfigSnapshot = FixConfigSnapshot.FromLocalConfig();
if (lastWrittenSnapshot != null && fixConfigSnapshot.EqualsTo(lastWrittenSnapshot))
{
return;
}
try
{
PhotonNetwork.CurrentRoom.SetCustomProperties(fixConfigSnapshot.ToHashtable(), (Hashtable)null, (WebFlags)null);
lastWrittenSnapshot = fixConfigSnapshot;
if (PropHuntFixPlugin.CfgWriteHunterSelectionLog == null || PropHuntFixPlugin.CfgWriteHunterSelectionLog.Value)
{
PropHuntFixPlugin.Log.LogInfo((object)("[PropHunt_Fix] Host config snapshot synchronized. PreHide=" + fixConfigSnapshot.PreHideSeconds.ToString("0.00") + ", HunterLock=" + fixConfigSnapshot.HunterLockSeconds.ToString("0.00") + ", Round=" + fixConfigSnapshot.RoundSeconds.ToString("0.00") + ", MissPenalty=" + fixConfigSnapshot.MissPenaltyHP + ", Range=" + fixConfigSnapshot.GunRangeMeters.ToString("0.00") + ", Cooldown=" + fixConfigSnapshot.GunCooldownSeconds.ToString("0.00") + ", HunterCount=" + fixConfigSnapshot.HunterCount));
}
}
catch (Exception ex)
{
PropHuntFixPlugin.Log.LogWarning((object)("[PropHunt_Fix] Host config sync failed: " + ex.Message));
}
}
}
public class ClientConfigApplyService : MonoBehaviourPunCallbacks
{
public static ClientConfigApplyService Instance;
private void Awake()
{
Instance = this;
}
public override void OnJoinedRoom()
{
QueueSnapshotFromCurrentRoom();
ApplyPendingVisuals();
PropHuntFixPlugin.EnsureRuntimeRoot();
}
public override void OnLeftRoom()
{
PropHuntFixState.ResetRoomState();
}
public override void OnRoomPropertiesUpdate(Hashtable propertiesThatChanged)
{
QueueSnapshotFromCurrentRoom();
ApplyPendingVisuals();
}
public void QueueSnapshotFromCurrentRoom()
{
if (PhotonNetwork.InRoom && PhotonNetwork.CurrentRoom != null)
{
FixConfigSnapshot fixConfigSnapshot = FixConfigSnapshot.FromRoomProperties(((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties);
if (fixConfigSnapshot != null)
{
PropHuntFixState.PendingSnapshot = fixConfigSnapshot;
}
}
}
public void ApplyPendingVisuals()
{
if (PropHuntFixState.PendingSnapshot != null)
{
EyeColorRefreshService.ApplyAllVisiblePlayerEyes();
NameTagPatch.RefreshAllNameTags();
}
}
public void RequestGameplayApplyForNextRound()
{
PropHuntFixState.PendingGameplayApply = true;
}
public void ApplyPendingGameplayIfRequested()
{
if (PropHuntFixState.PendingGameplayApply && PropHuntFixState.PendingSnapshot != null)
{
PropHuntManager instance = PropHuntManager.Instance;
if (!((Object)(object)instance == (Object)null))
{
FixConfigSnapshot pendingSnapshot = PropHuntFixState.PendingSnapshot;
instance.PreHideSeconds = pendingSnapshot.PreHideSeconds;
instance.HunterLockSeconds = pendingSnapshot.HunterLockSeconds;
instance.RoundSeconds = pendingSnapshot.RoundSeconds;
instance.MissPenaltyHP = pendingSnapshot.MissPenaltyHP;
instance.GunRangeMeters = pendingSnapshot.GunRangeMeters;
instance.GunCooldownSeconds = pendingSnapshot.GunCooldownSeconds;
PropHuntFixState.AppliedSnapshot = pendingSnapshot;
PropHuntFixState.PendingGameplayApply = false;
EyeColorRefreshService.ApplyAllVisiblePlayerEyes();
NameTagPatch.RefreshAllNameTags();
PropHuntFixPlugin.Log.LogInfo((object)"[PropHunt_Fix] Pending gameplay config applied.");
}
}
}
}
public class EyeColorRefreshService : MonoBehaviourPunCallbacks
{
private void Update()
{
ApplyAllVisiblePlayerEyes();
}
private void LateUpdate()
{
ApplyAllVisiblePlayerEyes();
}
public override void OnJoinedRoom()
{
ApplyAllVisiblePlayerEyes();
}
public override void OnPlayerEnteredRoom(Player newPlayer)
{
ApplyAllVisiblePlayerEyes();
}
public override void OnRoomPropertiesUpdate(Hashtable propertiesThatChanged)
{
ApplyAllVisiblePlayerEyes();
}
public static void ApplyAllVisiblePlayerEyes()
{
try
{
if (!((Object)(object)GameDirector.instance == (Object)null) && GameDirector.instance.PlayerList != null)
{
for (int i = 0; i < GameDirector.instance.PlayerList.Count; i++)
{
ApplyEyeColorForAvatar(GameDirector.instance.PlayerList[i]);
}
}
}
catch
{
}
}
public static void ApplyEyeColorForAvatar(PlayerAvatar avatar)
{
//IL_0069: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)avatar == (Object)null || (Object)(object)avatar.photonView == (Object)null || (Object)(object)avatar.playerHealth == (Object)null || avatar.photonView.Owner == null || !TryGetEyeState(avatar.photonView.Owner.ActorNumber, out var state))
{
return;
}
try
{
avatar.playerHealth.EyeMaterialOverride(state, 0.25f, 999999);
}
catch
{
}
}
private static bool TryGetEyeState(int actorNumber, out EyeOverrideState state)
{
if (PropHuntFixState.CurrentHunters.Contains(actorNumber))
{
state = (EyeOverrideState)1;
return true;
}
state = (EyeOverrideState)2;
return false;
}
}
[HarmonyPatch(typeof(PropHuntManager), "Start")]
public static class Patch_PropHuntManager_Start
{
private static void Prefix()
{
if (!PhotonNetwork.IsMasterClient || !PhotonNetwork.InRoom || PhotonNetwork.CurrentRoom == null)
{
return;
}
Hashtable customProperties = ((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties;
if (!((Dictionary<object, object>)(object)customProperties).ContainsKey("PH_Active"))
{
FixConfigSnapshot snapshot = PropHuntFixState.PendingSnapshot ?? FixConfigSnapshot.FromLocalConfig();
List<Player> list = PhotonNetwork.PlayerList.Where((Player p) => p != null && !p.IsInactive).ToList();
if (list.Count > 1)
{
List<Player> list2 = PropHuntFixState.SelectHunters(list, snapshot, null);
PropHuntFixState.CommitSelectedHunters(list2);
SetHunterRoomProperties(list2);
HunterUnlockCountdownController.PublishHostUnlockTimeForNewRound(snapshot);
}
}
}
private static void Postfix(PropHuntManager __instance)
{
PropHuntFixRuntime.ApplyRoomHuntersToManager(__instance);
if ((Object)(object)ClientConfigApplyService.Instance != (Object)null)
{
PropHuntFixPlugin.EnsureRuntimeRoot();
if ((Object)(object)ClientConfigApplyService.Instance != (Object)null)
{
ClientConfigApplyService.Instance.QueueSnapshotFromCurrentRoom();
}
PropHuntFixPlugin.EnsureRuntimeRoot();
if ((Object)(object)ClientConfigApplyService.Instance != (Object)null)
{
ClientConfigApplyService.Instance.ApplyPendingGameplayIfRequested();
}
}
EyeColorRefreshService.ApplyAllVisiblePlayerEyes();
}
internal static void SetHunterRoomProperties(List<Player> selected)
{
//IL_0052: Unknown result type (might be due to invalid IL or missing references)
//IL_0058: Expected O, but got Unknown
if (PhotonNetwork.CurrentRoom != null && selected != null && selected.Count != 0)
{
int[] array = new int[selected.Count];
for (int i = 0; i < selected.Count; i++)
{
array[i] = selected[i].ActorNumber;
}
Hashtable val = new Hashtable();
val[(object)"PH_Active"] = 1;
val[(object)"PH_Hunter"] = array[0];
val[(object)"PH_Hunters"] = array;
PhotonNetwork.CurrentRoom.SetCustomProperties(val, (Hashtable)null, (WebFlags)null);
}
}
}
[HarmonyPatch(typeof(PropHuntManager), "RepickHunterForNextRound")]
public static class Patch_PropHuntManager_RepickHunterForNextRound
{
private static bool Prefix(PropHuntManager __instance)
{
if (!PhotonNetwork.IsMasterClient || !PhotonNetwork.InRoom || PhotonNetwork.CurrentRoom == null)
{
return false;
}
FixConfigSnapshot snapshot = PropHuntFixState.PendingSnapshot ?? PropHuntFixState.AppliedSnapshot ?? FixConfigSnapshot.FromLocalConfig();
List<Player> list = PhotonNetwork.PlayerList.Where((Player p) => p != null && !p.IsInactive).ToList();
if (list.Count <= 1)
{
return false;
}
HashSet<int> excludeActorNumbers = new HashSet<int>(PropHuntFixState.CurrentHunters);
List<Player> list2 = PropHuntFixState.SelectHunters(list, snapshot, null);
if (list2.Count == 0)
{
list2 = PropHuntFixState.SelectHunters(list, snapshot, excludeActorNumbers);
}
PropHuntFixState.CommitSelectedHunters(list2);
Patch_PropHuntManager_Start.SetHunterRoomProperties(list2);
return false;
}
}
[HarmonyPatch(typeof(PropHuntManager), "OnPlayerLeftRoom")]
public static class Patch_PropHuntManager_OnPlayerLeftRoom
{
private static bool Prefix(PropHuntManager __instance, Player otherPlayer)
{
if (!PhotonNetwork.IsMasterClient || !PhotonNetwork.InRoom || otherPlayer == null)
{
return false;
}
if (!PropHuntFixState.CurrentHunters.Contains(otherPlayer.ActorNumber))
{
return false;
}
PropHuntFixState.CurrentHunters.Remove(otherPlayer.ActorNumber);
FixConfigSnapshot fixConfigSnapshot = PropHuntFixState.PendingSnapshot ?? PropHuntFixState.AppliedSnapshot ?? FixConfigSnapshot.FromLocalConfig();
if (!fixConfigSnapshot.RefillHuntersWhenHunterLeaves)
{
Patch_PropHuntManager_Start.SetHunterRoomProperties(PhotonNetwork.PlayerList.Where((Player p) => p != null && PropHuntFixState.CurrentHunters.Contains(p.ActorNumber)).ToList());
return false;
}
List<Player> list = PhotonNetwork.PlayerList.Where((Player p) => p != null && !p.IsInactive && !PropHuntFixState.CurrentHunters.Contains(p.ActorNumber)).ToList();
if (list.Count > 0)
{
List<Player> list2 = PropHuntFixState.SelectHunters(list, fixConfigSnapshot, null);
if (list2.Count > 1)
{
list2 = list2.Take(1).ToList();
}
if (list2.Count > 0)
{
PropHuntFixState.CurrentHunters.Add(list2[0].ActorNumber);
PropHuntFixState.CommitSelectedHunters(list2);
}
}
List<Player> list3 = PhotonNetwork.PlayerList.Where((Player p) => p != null && PropHuntFixState.CurrentHunters.Contains(p.ActorNumber)).ToList();
if (list3.Count > 0)
{
Patch_PropHuntManager_Start.SetHunterRoomProperties(list3);
}
return false;
}
}
[HarmonyPatch(typeof(PropHuntManager), "ApplyRoomState")]
public static class Patch_PropHuntManager_ApplyRoomState
{
private static void Postfix(PropHuntManager __instance, Hashtable props)
{
PropHuntFixRuntime.ApplyRoomHuntersToManager(__instance, props);
EyeColorRefreshService.ApplyAllVisiblePlayerEyes();
NameTagPatch.RefreshAllNameTags();
}
}
[HarmonyPatch(typeof(PropHuntManager), "OnRoomPropertiesUpdate")]
public static class Patch_PropHuntManager_OnRoomPropertiesUpdate
{
private static void Postfix(PropHuntManager __instance)
{
PropHuntFixRuntime.ApplyRoomHuntersToManager(__instance);
if ((Object)(object)ClientConfigApplyService.Instance != (Object)null)
{
PropHuntFixPlugin.EnsureRuntimeRoot();
if ((Object)(object)ClientConfigApplyService.Instance != (Object)null)
{
ClientConfigApplyService.Instance.QueueSnapshotFromCurrentRoom();
}
ClientConfigApplyService.Instance.ApplyPendingVisuals();
}
}
}
[HarmonyPatch(typeof(PropHuntManager), "OnJoinedRoom")]
public static class Patch_PropHuntManager_OnJoinedRoom
{
private static void Postfix(PropHuntManager __instance)
{
PropHuntFixRuntime.ApplyRoomHuntersToManager(__instance);
if ((Object)(object)ClientConfigApplyService.Instance != (Object)null)
{
PropHuntFixPlugin.EnsureRuntimeRoot();
if ((Object)(object)ClientConfigApplyService.Instance != (Object)null)
{
ClientConfigApplyService.Instance.QueueSnapshotFromCurrentRoom();
}
ClientConfigApplyService.Instance.ApplyPendingVisuals();
}
EyeColorRefreshService.ApplyAllVisiblePlayerEyes();
}
}
[HarmonyPatch(typeof(PropHuntManager), "OnPlayerPropertiesUpdate")]
public static class Patch_PropHuntManager_OnPlayerPropertiesUpdate
{
private static void Postfix()
{
NameTagPatch.RefreshAllNameTags();
}
}
[HarmonyPatch(typeof(PropHuntManager), "OnEvent")]
public static class Patch_PropHuntManager_OnEvent
{
private static bool Prefix(PropHuntManager __instance, EventData e)
{
if (e.Code == 119)
{
return HandleFixSoundEvent(e);
}
if (e.Code == 101)
{
return HandleKillEvent(__instance, e);
}
if (e.Code == 102)
{
return HandlePlayerDownEvent(__instance, e);
}
return true;
}
private static bool HandleFixSoundEvent(EventData e)
{
try
{
if (!(e.CustomData is object[] array) || array.Length < 2)
{
return false;
}
string text = array[0] as string;
string text2 = array[1] as string;
if (text == "PHFIX_SOUND" && !string.IsNullOrEmpty(text2))
{
PropHuntAudioUtil.PlayLocalSound(text2);
}
}
catch
{
}
return false;
}
private static bool HandleKillEvent(PropHuntManager manager, EventData e)
{
if (!(e.CustomData is object[] array) || array.Length < 3)
{
return false;
}
string text = array[0] as string;
if (text != "PH1")
{
return false;
}
if (!PropHuntFixState.TryToInt(array[1], out var val) || !PropHuntFixState.TryToInt(array[2], out var val2))
{
return false;
}
if (val2 <= 0 || !PropHuntFixState.CurrentHunters.Contains(val))
{
return false;
}
if (PhotonNetwork.LocalPlayer != null && PhotonNetwork.LocalPlayer.ActorNumber == val2)
{
MethodInfo methodInfo = AccessTools.Method(typeof(PropHuntManager), "KillLocalPlayerClean", (Type[])null, (Type[])null);
if (methodInfo != null)
{
methodInfo.Invoke(manager, null);
}
}
return false;
}
private static bool HandlePlayerDownEvent(PropHuntManager manager, EventData e)
{
if (!(e.CustomData is object[] array) || array.Length < 2)
{
return false;
}
string text = array[0] as string;
if (text != "PH1")
{
return false;
}
if (!PropHuntFixState.TryToInt(array[1], out var val))
{
return false;
}
PropHuntAudioUtil.PlayLocalSound("player death01");
if (PhotonNetwork.LocalPlayer != null && val == PhotonNetwork.LocalPlayer.ActorNumber)
{
PlayerAvatar val2 = PropHuntFixRuntime.FindLocalAvatar();
if ((Object)(object)val2 != (Object)null)
{
PropDisguiseController component = ((Component)val2).GetComponent<PropDisguiseController>();
if ((Object)(object)component != (Object)null)
{
component.ApplyClearLocal();
}
}
}
if (PhotonNetwork.IsMasterClient)
{
HashSet<int> value = Traverse.Create((object)manager).Field("_deadActors").GetValue<HashSet<int>>();
value?.Add(val);
bool flag = PropHuntFixRuntime.AreAllHuntersDead(value);
bool flag2 = PropHuntFixRuntime.AreAllHidersDead(value);
if (flag)
{
Traverse.Create((object)manager).Field("_roundArmed").SetValue((object)false);
PropHuntFixRuntime.BroadcastMatchEnd(manager, (PHWinner)2, "All hunters eliminated");
}
else if (flag2)
{
Traverse.Create((object)manager).Field("_roundArmed").SetValue((object)false);
PropHuntFixRuntime.BroadcastMatchEnd(manager, (PHWinner)1, "All hiders eliminated");
}
}
return false;
}
}
[HarmonyPatch(typeof(PropHuntManager), "AllHidersDead")]
public static class Patch_PropHuntManager_AllHidersDead
{
private static bool Prefix(ref bool __result)
{
HashSet<int> deadActors = PropHuntFixRuntime.GetDeadActors(PropHuntManager.Instance);
__result = PropHuntFixRuntime.AreAllHidersDead(deadActors);
return false;
}
}
[HarmonyPatch(typeof(PropHuntManager), "OnGUI")]
public static class Patch_PropHuntManager_OnGUI_Localized
{
private static readonly FieldInfo FieldEnding = AccessTools.Field(typeof(PropHuntManager), "_ending");
private static readonly FieldInfo FieldEndUntil = AccessTools.Field(typeof(PropHuntManager), "_endUntil");
private static readonly FieldInfo FieldWhoWon = AccessTools.Field(typeof(PropHuntManager), "_whoWon");
private static readonly FieldInfo FieldFlashMsg = AccessTools.Field(typeof(PropHuntManager), "_flashMsg");
private static readonly FieldInfo FieldFlashMsgUntil = AccessTools.Field(typeof(PropHuntManager), "_flashMsgUntil");
private static readonly FieldInfo FieldCachedPropPhotonViewId = AccessTools.Field(typeof(PropHuntManager), "_cachedPropPhotonViewId");
private static GUIStyle boxStyle;
private static GUIStyle labelStyle;
private static GUIStyle centerStyle;
private static GUIStyle subCenterStyle;
private static bool Prefix(PropHuntManager __instance)
{
//IL_0041: Unknown result type (might be due to invalid IL or missing references)
//IL_0046: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
//IL_0049: Invalid comparison between Unknown and I4
//IL_007b: Unknown result type (might be due to invalid IL or missing references)
try
{
if ((Object)(object)__instance == (Object)null || SemiFunc.MenuLevel() || (Object)(object)LevelGenerator.Instance == (Object)null || (Object)(object)GameDirector.instance == (Object)null || !PhotonNetwork.InRoom)
{
return true;
}
PHRole localRole = GetLocalRole(__instance);
if ((int)localRole == 0)
{
return true;
}
EnsureStyles();
GUI.depth = 0;
bool @bool = GetBool(FieldEnding, __instance);
if (!@bool)
{
DrawStatusBox(__instance, localRole);
}
DrawFlash(__instance);
if (@bool)
{
DrawEndBanner(__instance);
}
return false;
}
catch
{
return true;
}
}
private static void DrawStatusBox(PropHuntManager manager, PHRole role)
{
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
//IL_002d: Invalid comparison between Unknown and I4
//IL_004b: Unknown result type (might be due to invalid IL or missing references)
//IL_004d: Invalid comparison between Unknown and I4
//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
//IL_0121: Unknown result type (might be due to invalid IL or missing references)
//IL_0123: Invalid comparison between Unknown and I4
//IL_016c: Unknown result type (might be due to invalid IL or missing references)
//IL_021a: Unknown result type (might be due to invalid IL or missing references)
//IL_021c: Invalid comparison between Unknown and I4
//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
//IL_02a8: Unknown result type (might be due to invalid IL or missing references)
//IL_02aa: Invalid comparison between Unknown and I4
//IL_026a: Unknown result type (might be due to invalid IL or missing references)
//IL_036a: Unknown result type (might be due to invalid IL or missing references)
Rect val = default(Rect);
((Rect)(ref val))..ctor(20f, 20f, 720f, 180f);
string text = FixLocalization.Text("PropHunt") + " — " + (((int)role == 1) ? FixLocalization.Text("Hunter") : FixLocalization.Text("Hider"));
string text2 = (((int)role == 1) ? (FixLocalization.Text("ScanHelp") + ": -" + manager.MissPenaltyHP + " HP") : (((object)(KeyCode)(ref manager.KeyHiderToggle)).ToString() + ": " + FixLocalization.Text("Disguise") + " | " + ((object)(KeyCode)(ref manager.KeyDisguiseViewToggle)).ToString() + ": View | " + ((object)(KeyCode)(ref manager.KeyLockToggle)).ToString() + ": " + FixLocalization.Text("Locked")));
GUI.Box(val, text + "\n" + text2, boxStyle);
float num = ((Rect)(ref val)).yMax + 6f;
if ((int)role == 2 && manager.PreHidePhaseActive)
{
float seconds = Mathf.Max(0f, GetPrivateFloat(manager, "_preHideUntil") - Time.time);
GUI.Label(new Rect(((Rect)(ref val)).x + 8f, num, ((Rect)(ref val)).width, 24f), FixLocalization.Text("HideTime") + ": " + FormatClock(seconds), labelStyle);
num += 22f;
}
if (manager.RoundIsLive)
{
float seconds2 = Mathf.Max(0f, (float)(GetPrivateDouble(manager, "_roundEndRealtime") - (double)Time.time));
GUI.Label(new Rect(((Rect)(ref val)).x + 8f, num, ((Rect)(ref val)).width, 24f), FixLocalization.Text("TimeLeft") + ": " + FormatClock(seconds2), labelStyle);
num += 22f;
}
if ((int)role == 1 && manager.IsHunterLocked)
{
int num2 = Mathf.CeilToInt(Mathf.Max(0f, GetPrivateFloat(manager, "_hunterLockUntil") - Time.time));
GUI.Label(new Rect(((Rect)(ref val)).x + 8f, num, ((Rect)(ref val)).width, 24f), FixLocalization.Text("HunterLock") + ": " + num2 + FixLocalization.Text("Sec"), labelStyle);
num += 22f;
}
if ((int)role != 2)
{
return;
}
string text3 = FixLocalization.Text("LookValuable");
int privateInt = GetPrivateInt(manager, "_cachedPropPhotonViewId");
if (privateInt != 0 && (Object)(object)PhotonView.Find(privateInt) != (Object)null)
{
text3 = FixLocalization.Text("TargetLocked");
}
PlayerAvatar val2 = PropHuntFixRuntime.FindLocalAvatar();
if ((Object)(object)val2 != (Object)null)
{
PropDisguiseController component = ((Component)val2).GetComponent<PropDisguiseController>();
if ((Object)(object)component != (Object)null && component.IsLocked)
{
text3 = text3 + " [" + FixLocalization.Text("Locked") + "]";
}
}
GUI.Label(new Rect(((Rect)(ref val)).x + 8f, num, ((Rect)(ref val)).width, 24f), FixLocalization.Text("Disguise") + ": " + text3, labelStyle);
}
private static void DrawFlash(PropHuntManager manager)
{
//IL_004d: Unknown result type (might be due to invalid IL or missing references)
float privateFloat = GetPrivateFloat(manager, "_flashMsgUntil");
if (!(Time.time >= privateFloat))
{
string privateString = GetPrivateString(manager, "_flashMsg");
if (!string.IsNullOrEmpty(privateString))
{
GUI.Label(new Rect(30f, 228f, 720f, 28f), FixLocalization.TranslateMessage(privateString), labelStyle);
}
}
}
private static void DrawEndBanner(PropHuntManager manager)
{
//IL_0032: 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_0049: Unknown result type (might be due to invalid IL or missing references)
//IL_0055: 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_005b: Unknown result type (might be due to invalid IL or missing references)
//IL_005d: Invalid comparison between Unknown and I4
//IL_005f: Unknown result type (might be due to invalid IL or missing references)
//IL_0061: Invalid comparison between Unknown and I4
//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
//IL_0110: Unknown result type (might be due to invalid IL or missing references)
Rect val = default(Rect);
((Rect)(ref val))..ctor(0f, 0f, (float)Screen.width, (float)Screen.height);
GUI.color = new Color(0f, 0f, 0f, 0.55f);
GUI.DrawTexture(val, (Texture)(object)Texture2D.whiteTexture);
GUI.color = Color.white;
PHWinner winner = GetWinner(manager);
string text = (((int)winner == 2) ? FixLocalization.Text("HidersWin") : (((int)winner == 1) ? FixLocalization.Text("HunterWins") : FixLocalization.Text("Draw")));
float privateFloat = GetPrivateFloat(manager, "_endUntil");
string text2 = (PhotonNetwork.IsMasterClient ? Mathf.CeilToInt(Mathf.Max(0f, privateFloat - Time.time)).ToString() : "…");
GUI.Label(new Rect(0f, (float)Screen.height * 0.35f, (float)Screen.width, 80f), text, centerStyle);
GUI.Label(new Rect(0f, (float)Screen.height * 0.35f + 68f, (float)Screen.width, 60f), FixLocalization.PickForInternal("Next round starting in", "次のラウンド開始まで", "下一回合开始倒计时", "다음 라운드 시작까지", "До следующего раунда", "Prochain round dans", "Siguiente ronda en", "Nächste Runde in", "Próxima rodada em") + " " + text2, subCenterStyle);
}
private static void EnsureStyles()
{
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_0022: Expected O, but got Unknown
//IL_0051: Unknown result type (might be due to invalid IL or missing references)
//IL_0074: Unknown result type (might be due to invalid IL or missing references)
//IL_007e: Expected O, but got Unknown
//IL_0095: Unknown result type (might be due to invalid IL or missing references)
//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
//IL_00c2: Expected O, but got Unknown
//IL_010f: Unknown result type (might be due to invalid IL or missing references)
//IL_0132: Unknown result type (might be due to invalid IL or missing references)
//IL_013c: Expected O, but got Unknown
//IL_0191: Unknown result type (might be due to invalid IL or missing references)
if (boxStyle == null)
{
boxStyle = new GUIStyle(GUI.skin.box);
boxStyle.alignment = (TextAnchor)0;
boxStyle.fontSize = 16;
boxStyle.wordWrap = true;
boxStyle.normal.textColor = Color.white;
}
if (labelStyle == null)
{
labelStyle = new GUIStyle(GUI.skin.label);
labelStyle.fontSize = 16;
labelStyle.normal.textColor = Color.white;
}
if (centerStyle == null)
{
centerStyle = new GUIStyle(GUI.skin.label);
centerStyle.alignment = (TextAnchor)4;
centerStyle.fontStyle = (FontStyle)1;
centerStyle.fontSize = Mathf.RoundToInt(Mathf.Clamp((float)Screen.width * 0.06f, 32f, 72f));
centerStyle.normal.textColor = Color.white;
}
if (subCenterStyle == null)
{
subCenterStyle = new GUIStyle(GUI.skin.label);
subCenterStyle.alignment = (TextAnchor)4;
subCenterStyle.fontSize = Mathf.RoundToInt(Mathf.Clamp((float)Screen.width * 0.03f, 18f, 36f));
subCenterStyle.normal.textColor = new Color(1f, 1f, 1f, 0.9f);
}
}
private static PHRole GetLocalRole(PropHuntManager manager)
{
//IL_0038: 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)
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
try
{
object value = Traverse.Create((object)manager).Field("_localRole").GetValue();
if (value is PHRole)
{
return (PHRole)value;
}
}
catch
{
}
return (PHRole)0;
}
private static PHWinner GetWinner(PropHuntManager manager)
{
//IL_0038: 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)
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
try
{
object value = Traverse.Create((object)manager).Field("_whoWon").GetValue();
if (value is PHWinner)
{
return (PHWinner)value;
}
}
catch
{
}
return (PHWinner)0;
}
private static string FormatClock(float seconds)
{
int num = Mathf.CeilToInt(Mathf.Max(0f, seconds));
return (num / 60).ToString("00") + ":" + (num % 60).ToString("00");
}
private static bool GetBool(FieldInfo field, object instance)
{
try
{
object obj = ((field != null) ? field.GetValue(instance) : null);
return obj is bool && (bool)obj;
}
catch
{
return false;
}
}
private static float GetPrivateFloat(PropHuntManager manager, string fieldName)
{
try
{
object value = Traverse.Create((object)manager).Field(fieldName).GetValue();
if (value is float result)
{
return result;
}
if (value is double)
{
return (float)(double)value;
}
}
catch
{
}
return 0f;
}
private static double GetPrivateDouble(PropHuntManager manager, string fieldName)
{
try
{
object value = Traverse.Create((object)manager).Field(fieldName).GetValue();
if (value is double result)
{
return result;
}
if (value is float)
{
return (float)value;
}
}
catch
{
}
return 0.0;
}
private static int GetPrivateInt(PropHuntManager manager, string fieldName)
{
try
{
object value = Traverse.Create((object)manager).Field(fieldName).GetValue();
if (value is int)
{
return (int)value;
}
}
catch
{
}
return 0;
}
private static string GetPrivateString(PropHuntManager manager, string fieldName)
{
try
{
object value = Traverse.Create((object)manager).Field(fieldName).GetValue();
return value as string;
}
catch
{
}
return string.Empty;
}
}
[HarmonyPatch(typeof(PropHuntManager), "Flash")]
public static class Patch_PropHuntManager_Flash_Localized
{
private static void Prefix(ref string msg)
{
msg = FixLocalization.TranslateMessage(msg);
}
}
[HarmonyPatch(typeof(PropHuntManager), "Update")]
public static class Patch_PropHuntManager_Update_LockAudio
{
private static void Postfix(PropHuntManager __instance)
{
HunterUnlockCountdownController.Tick(__instance);
}
}
[HarmonyPatch(typeof(FlashlightController), "Update")]
public static class Patch_FlashlightController_Update_DisguiseSuppress
{
private static void Postfix(FlashlightController __instance)
{
DisguiseFlashlightSuppressService.SuppressControllerAfterOriginal(__instance);
}
}
[HarmonyPatch(typeof(PropHuntManager), "StartEndBannerLocal")]
public static class Patch_PropHuntManager_StartEndBannerLocal
{
private static void Postfix(PropHuntManager __instance)
{
//IL_0075: Unknown result type (might be due to invalid IL or missing references)
//IL_007c: Expected O, but got Unknown
try
{
FieldInfo fieldInfo = AccessTools.Field(typeof(PropHuntManager), "_endMsg");
if (fieldInfo != null && (Object)(object)__instance != (Object)null)
{
string message = fieldInfo.GetValue(__instance) as string;
fieldInfo.SetValue(__instance, FixLocalization.TranslateMessage(message));
}
}
catch
{
}
PropHuntAudioUtil.PlayLocalSound("extraction point success");
if (PhotonNetwork.IsMasterClient && PhotonNetwork.CurrentRoom != null)
{
Hashtable val = new Hashtable();
val[(object)"PHFIX_UnlockAt"] = 0.0;
val[(object)"PHFIX_UnlockSerial"] = 0;
PhotonNetwork.CurrentRoom.SetCustomProperties(val, (Hashtable)null, (WebFlags)null);
}
HostConfigSyncService.RequestWriteSnapshot();
if ((Object)(object)ClientConfigApplyService.Instance != (Object)null)
{
PropHuntFixPlugin.EnsureRuntimeRoot();
if ((Object)(object)ClientConfigApplyService.Instance != (Object)null)
{
ClientConfigApplyService.Instance.RequestGameplayApplyForNextRound();
}
}
}
}
[HarmonyPatch(typeof(PropHuntManager), "SafeAdvanceScene")]
public static class Patch_PropHuntManager_SafeAdvanceScene
{
private static void Prefix()
{
HostConfigSyncService.RequestWriteSnapshot();
if ((Object)(object)ClientConfigApplyService.Instance != (Object)null)
{
PropHuntFixPlugin.EnsureRuntimeRoot();
if ((Object)(object)ClientConfigApplyService.Instance != (Object)null)
{
ClientConfigApplyService.Instance.ApplyPendingGameplayIfRequested();
}
}
}
}
public class NameTagOriginalPatchDisabler : MonoBehaviour
{
private float nextTry;
private bool done;
private void Update()
{
if (!done && !(Time.unscaledTime < nextTry))
{
nextTry = Time.unscaledTime + 1f;
done = NameTagPatch.TryDisableOriginalHidePatch();
}
}
}
[HarmonyPatch(typeof(WorldSpaceUIPlayerName), "Update")]
public static class NameTagPatch
{
private static readonly FieldInfo FieldPlayerAvatar = AccessTools.Field(typeof(WorldSpaceUIPlayerName), "playerAvatar");
private static bool triedImmediateUnpatch;
public static bool TryDisableOriginalHidePatch()
{
try
{
MethodInfo methodInfo = AccessTools.Method(typeof(WorldSpaceUIPlayerName), "Update", (Type[])null, (Type[])null);
if (methodInfo == null || PropHuntFixPlugin.Harmony == null)
{
return false;
}
Patches patchInfo = Harmony.GetPatchInfo((MethodBase)methodInfo);
if (patchInfo != null && patchInfo.Prefixes != null)
{
for (int i = 0; i < patchInfo.Prefixes.Count; i++)
{
Patch val = patchInfo.Prefixes[i];
if (val != null && !string.IsNullOrEmpty(val.owner) && !(val.owner == "REPOJP.PropHunt_Fix"))
{
string text = ((val.PatchMethod != null && val.PatchMethod.DeclaringType != null) ? val.PatchMethod.DeclaringType.Name : string.Empty);
if (val.owner == "omni.repo.prophunt" || text.Contains("Patch_HidePlayerNames"))
{
PropHuntFixPlugin.Harmony.Unpatch((MethodBase)methodInfo, (HarmonyPatchType)1, val.owner);
}
}
}
}
return true;
}
catch
{
return false;
}
}
[HarmonyPriority(800)]
private static bool Prefix()
{
if (!triedImmediateUnpatch)
{
triedImmediateUnpatch = true;
TryDisableOriginalHidePatch();
}
return true;
}
private static void Postfix(WorldSpaceUIPlayerName __instance)
{
try
{
if (PhotonNetwork.InRoom)
{
PropHuntFixPlugin.EnsureRuntimeRoot();
}
if (!((Object)(object)__instance == (Object)null) && !((Object)(object)__instance.text == (Object)null))
{
PlayerAvatar targetAvatar = GetTargetAvatar(__instance);
if (!((Object)(object)targetAvatar == (Object)null))
{
ApplyNameTagVisual(__instance, targetAvatar);
}
}
}
catch
{
}
}
public static void RefreshAllNameTags()
{
}
private static PlayerAvatar GetTargetAvatar(WorldSpaceUIPlayerName instance)
{
try
{
if (FieldPlayerAvatar != null)
{
object? value = FieldPlayerAvatar.GetValue(instance);
PlayerAvatar val = (PlayerAvatar)((value is PlayerAvatar) ? value : null);
if ((Object)(object)val != (Object)null)
{
return val;
}
}
if ((Object)(object)instance != (Object)null)
{
PlayerAvatar componentInParent = ((Component)instance).GetComponentInParent<PlayerAvatar>();
if ((Object)(object)componentInParent != (Object)null)
{
return componentInParent;
}
}
}
catch
{
}
return null;
}
private static void ApplyNameTagVisual(WorldSpaceUIPlayerName instance, PlayerAvatar targetAvatar)
{
//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
//IL_01a9: 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)
//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
//IL_018d: Unknown result type (might be due to invalid IL or missing references)
//IL_0160: Unknown result type (might be due to invalid IL or missing references)
//IL_013a: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)instance == (Object)null || (Object)(object)instance.text == (Object)null || (Object)(object)targetAvatar == (Object)null || (Object)(object)targetAvatar.photonView == (Object)null || targetAvatar.photonView.Owner == null)
{
return;
}
Player localPlayer = PhotonNetwork.LocalPlayer;
if (localPlayer == null)
{
return;
}
bool flag = PropHuntFixState.CurrentHunters.Contains(localPlayer.ActorNumber);
bool flag2 = PropHuntFixState.CurrentHunters.Contains(targetAvatar.photonView.Owner.ActorNumber);
bool flag3 = SemiFunc.MenuLevel();
bool isMasterClient = PhotonNetwork.IsMasterClient;
bool targetReady = IsTargetReady(targetAvatar.photonView.Owner);
Color color = ((Graphic)instance.text).color;
float a = color.a;
if (flag3)
{
ApplyReadyUnderline(instance, targetAvatar, isMasterClient, localPlayer, targetReady);
return;
}
RemoveReadyUnderline(instance);
if (!IsRoundNameTagPatchEnabled() || a <= 0.01f)
{
return;
}
if (!flag)
{
if (flag2)
{
((Graphic)instance.text).color = new Color(1f, 0.15f, 0.15f, a);
}
else
{
((Graphic)instance.text).color = new Color(1f, 1f, 1f, a);
}
}
else if (flag2)
{
((Graphic)instance.text).color = new Color(1f, 0.15f, 0.15f, a);
}
else
{
((Graphic)instance.text).color = new Color(color.r, color.g, color.b, 0f);
}
}
private static bool IsRoundNameTagPatchEnabled()
{
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_0032: Invalid comparison between Unknown and I4
try
{
if (!PhotonNetwork.InRoom || SemiFunc.MenuLevel())
{
return false;
}
if ((Object)(object)GameDirector.instance == (Object)null || (int)GameDirector.instance.currentState != 2)
{
return false;
}
return (Object)(object)PropHuntManager.Instance != (Object)null;
}
catch
{
return false;
}
}
private static bool IsTargetReady(Player player)
{
try
{
if (player == null || player.CustomProperties == null)
{
return false;
}
Hashtable customProperties = player.CustomProperties;
bool flag = ReadBoolProperty(customProperties, "PHFIX_Ready");
bool flag2 = ReadBoolProperty(customProperties, "PHFIX_HasPropHunt");
bool flag3 = ReadBoolProperty(customProperties, "PHFIX_HasFix");
return flag && flag2 && flag3;
}
catch
{
}
return false;
}
private static bool ReadBoolProperty(Hashtable props, string key)
{
try
{
if (props == null || !((Dictionary<object, object>)(object)props).ContainsKey(key))
{
return false;
}
object obj = props[(object)key];
if (obj is bool result)
{
return result;
}
if (obj is int)
{
return (int)obj != 0;
}
if (obj is string)
{
return string.Equals((string)obj, "true", StringComparison.OrdinalIgnoreCase);
}
}
catch
{
}
return false;
}
private static void ApplyReadyUnderline(WorldSpaceUIPlayerName instance, PlayerAvatar targetAvatar, bool isHostView, Player localPlayer, bool targetReady)
{
try
{
string text = ((TMP_Text)instance.text).text;
if (string.IsNullOrEmpty(text))
{
text = targetAvatar.photonView.Owner.NickName;
}
if (string.IsNullOrEmpty(text))
{
text = targetAvatar.photonView.Owner.ActorNumber.ToString();
}
text = StripReadyLine(text);
if (isHostView && targetAvatar.photonView.Owner.ActorNumber != localPlayer.ActorNumber && !targetReady)
{
text = text + "\n<color=#ff0000><u>" + FixLocalization.Text("NotReady") + "</u></color>";
}
((TMP_Text)instance.text).text = text;
}
catch
{
}
}
private static void RemoveReadyUnderline(WorldSpaceUIPlayerName instance)
{
try
{
((TMP_Text)instance.text).text = StripReadyLine(((TMP_Text)instance.text).text);
}
catch
{
}
}
private static string StripReadyLine(string text)
{
if (string.IsNullOrEmpty(text))
{
return text;
}
string value = "<color=#ff0000><u>";
int num = text.IndexOf(value, StringComparison.OrdinalIgnoreCase);
if (num < 0)
{
return text;
}
int num2 = num;
if (num2 > 0 && text[num2 - 1] == '\n')
{
num2--;
}
int num3 = text.IndexOf("</u></color>", num, StringComparison.OrdinalIgnoreCase);
if (num3 < 0)
{
return text.Substring(0, num2);
}
num3 += "</u></color>".Length;
return text.Remove(num2, num3 - num2);
}
}
internal static class PropHuntFixRuntime
{
public static void ApplyRoomHuntersToManager(PropHuntManager manager)
{
Hashtable props = ((PhotonNetwork.CurrentRoom != null) ? ((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties : null);
ApplyRoomHuntersToManager(manager, props);
}
public static void ApplyRoomHuntersToManager(PropHuntManager manager, Hashtable props)
{
//IL_0090: Unknown result type (might be due to invalid IL or missing references)
//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)manager == (Object)null)
{
return;
}
PropHuntFixState.SyncHuntersFromRoomProperties((props != null) ? props : ((PhotonNetwork.CurrentRoom != null) ? ((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties : null));
int num = ((PropHuntFixState.CurrentHunters.Count > 0) ? PropHuntFixState.CurrentHunters.First() : (-1));
Traverse.Create((object)manager).Field("_hunterActor").SetValue((object)num);
if (PhotonNetwork.LocalPlayer != null)
{
PHRole val = (PHRole)(PropHuntFixState.CurrentHunters.Contains(PhotonNetwork.LocalPlayer.ActorNumber) ? 1 : 2);
if (props != null && (!((Dictionary<object, object>)(object)props).ContainsKey("PH_Active") || Convert.ToInt32(props[(object)"PH_Active"]) != 1))
{
val = (PHRole)0;
}
Traverse.Create((object)manager).Field("_localRole").SetValue((object)val);
}
}
public static HashSet<int> GetDeadActors(PropHuntManager manager)
{
try
{
if ((Object)(object)manager == (Object)null)
{
return new HashSet<int>();
}
HashSet<int> value = Traverse.Create((object)manager).Field("_deadActors").GetValue<HashSet<int>>();
return value ?? new HashSet<int>();
}
catch
{
return new HashSet<int>();
}
}
public static PlayerAvatar FindLocalAvatar()
{
if ((Object)(object)GameDirector.instance == (Object)null || GameDirector.instance.PlayerList == null)
{
return null;
}
for (int i = 0; i < GameDirector.instance.PlayerList.Count; i++)
{
PlayerAvatar val = GameDirector.instance.PlayerList[i];
if ((Object)(object)val != (Object)null && (Object)(object)val.photonView != (Object)null && val.photonView.IsMine)
{
return val;
}
}
return null;
}
public static bool AreAllHidersDead(HashSet<int> deadActors)
{
Player[] playerList = PhotonNetwork.PlayerList;
foreach (Player val in playerList)
{
if (val != null && !val.IsInactive && !PropHuntFixState.CurrentHunters.Contains(val.ActorNumber) && (deadActors == null || !deadActors.Contains(val.ActorNumber)))
{
return false;
}
}
return true;
}
public static bool AreAllHuntersDead(HashSet<int> deadActors)
{
if (PropHuntFixState.CurrentHunters.Count == 0)
{
return false;
}
foreach (int currentHunter in PropHuntFixState.CurrentHunters)
{
if (deadActors == null || !deadActors.Contains(currentHunter))
{
return false;
}
}
return true;
}
public static void BroadcastMatchEnd(PropHuntManager manager, PHWinner winner, string reason)
{
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Expected I4, but got Unknown
//IL_0029: 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)
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_003f: Expected O, but got Unknown
//IL_006d: Unknown result type (might be due to invalid IL or missing references)
object[] array = new object[3]
{
"PH1",
(int)winner,
reason ?? string.Empty
};
PhotonNetwork.RaiseEvent((byte)103, (object)array, new RaiseEventOptions
{
Receivers = (ReceiverGroup)1
}, SendOptions.SendReliable);
MethodInfo methodInfo = AccessTools.Method(typeof(PropHuntManager), "StartEndBannerLocal", (Type[])null, (Type[])null);
if (methodInfo != null)
{
methodInfo.Invoke(manager, new object[2] { winner, reason });
}
}
}
public class MainMenuMusicVolumeService : MonoBehaviour
{
private static GameObject serviceObject;
private float nextApply;
public static void EnsureStarted()
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: Expected O, but got Unknown
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Expected O, but got Unknown
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
//IL_0044: Expected O, but got Unknown
try
{
if (!((Object)serviceObject != (Object)null))
{
serviceObject = new GameObject("REPOJP_PropHuntFix_MainMenuMusicVolume");
((Object)serviceObject).hideFlags = (HideFlags)61;
Object.DontDestroyOnLoad((Object)serviceObject);
serviceObject.AddComponent<MainMenuMusicVolumeService>();
}
}
catch
{
serviceObject = null;
}
}
private void Update()
{
if (!(Time.unscaledTime < nextApply))
{
nextApply = Time.unscaledTime + 0.25f;
ApplyMainMenuMusicVolume();
}
}
private static void ApplyMainMenuMusicVolume()
{
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Expected O, but got Unknown
try
{
float volume = GetVolume();
AudioSource[] array = Object.FindObjectsOfType<AudioSource>(true);
foreach (AudioSource val in array)
{
if (!((Object)val == (Object)null) && IsMainMenuSwapSource(val))
{
val.volume = volume;
}
}
}
catch
{
}
}
private static bool IsMainMenuSwapSource(AudioSource source)
{
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Expected O, but got Unknown
try
{
string text = ((Object)((Component)source).gameObject).name ?? string.Empty;
string text2 = (((Object)source.clip != (Object)null) ? ((Object)source.clip).name : string.Empty);
if (text.Equals("MainMenuMusic_Swap", StringComparison.OrdinalIgnoreCase))
{
return true;
}
if (text2.Equals("Constant Music - Main Menu", StringComparison.OrdinalIgnoreCase))
{
return true;
}
return false;
}
catch
{
return false;
}
}
private static float GetVolume()
{
try
{
if (PropHuntFixPlugin.CfgMainMenuMusicVolumePercent == null)
{
return 0.5f;
}
return (float)Mathf.Clamp(PropHuntFixPlugin.CfgMainMenuMusicVolumePercent.Value, 0, 100) / 100f;
}
catch
{
return 0.5f;
}
}
}
internal static class PropHuntAudioUtil
{
private static readonly Dictionary<string, AudioClip> ClipCache = new Dictionary<string, AudioClip>(StringComparer.OrdinalIgnoreCase);
private static GameObject audioObject;
private static AudioSource audioSource;
public static void EnsureReady()
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: Expected O, but got Unknown
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: Expected O, but got Unknown
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: Expected O, but got Unknown
try
{
if (!((Object)audioSource != (Object)null))
{
audioObject = new GameObject("REPOJP_PropHuntFix_AudioSource");
((Object)audioObject).hideFlags = (HideFlags)61;
Object.DontDestroyOnLoad((Object)audioObject);
audioSource = audioObject.AddComponent<AudioSource>();
audioSource.playOnAwake = false;
audioSource.loop = false;
audioSource.mute = false;
audioSource.volume = 1f;
audioSource.pitch = 1f;
audioSource.spatialBlend = 0f;
audioSource.priority = 0;
audioSource.dopplerLevel = 0f;
audioSource.rolloffMode = (AudioRolloffMode)1;
}
}
catch
{
audioObject = null;
audioSource = null;
}
}
public static void PlayLocalSound(string officialClipName)
{
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_0022: Expected O, but got Unknown
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
//IL_0039: Expected O, but got Unknown
//IL_004a: Unknown result type (might be due to invalid IL or missing references)
//IL_0055: Expected O, but got Unknown
try
{
if (string.IsNullOrEmpty(officialClipName))
{
return;
}
AudioClip val = FindOfficialClip(officialClipName);
if (!((Object)val == (Object)null))
{
if ((Object)audioSource == (Object)null)
{
EnsureReady();
}
if (!((Object)audioSource == (Object)null))
{
audioSource.PlayOneShot(val, GetVolume(officialClipName));
}
}
}
catch
{
}
}
private static float GetVolume(string officialClipName)
{
try
{
if (string.Equals(officialClipName, "player death01", StringComparison.OrdinalIgnoreCase))
{
return (float)Mathf.Clamp(PropHuntFixPlugin.CfgDeathSoundVolumePercent.Value, 0, 100) / 100f;
}
if (string.Equals(officialClipName, "extraction point success", StringComparison.OrdinalIgnoreCase))
{
return (float)Mathf.Clamp(PropHuntFixPlugin.CfgWinSoundVolumePercent.Value, 0, 100) / 100f;
}
}
catch
{
}
return 0.5f;
}
private static AudioClip FindOfficialClip(string officialClipName)
{
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_001c: Expected O, but got Unknown
//IL_003e: Unknown result type (might be due to invalid IL or missing references)
//IL_0049: Expected O, but got Unknown
if (ClipCache.TryGetValue(officialClipName, out var value) && (Object)value != (Object)null)
{
return value;
}
try
{
AudioClip[] array = Resources.FindObjectsOfTypeAll<AudioClip>();
foreach (AudioClip val in array)
{
if ((Object)val != (Object)null && ((Object)val).name == officialClipName)
{
ClipCache[officialClipName] = val;
return val;
}
}
}
catch
{
}
return null;
}
}
internal static class PropHuntCountdownBeepUtil
{
private static GameObject audioObject;
private static AudioSource audioSource;
private static AudioClip shortBeepClip;
private static AudioClip longBeepClip;
private static void EnsureReady()
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: Expected O, but got Unknown
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: Expected O, but got Unknown
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: Expected O, but got Unknown
try
{
if (!((Object)audioSource != (Object)null))
{
audioObject = new GameObject("REPOJP_PropHuntFix_CountdownAudioSource");
((Object)audioObject).hideFlags = (HideFlags)61;
Object.DontDestroyOnLoad((Object)audioObject);
audioSource = audioObject.AddComponent<AudioSource>();
audioSource.playOnAwake = false;
audioSource.loop = false;
audioSource.mute = false;
audioSource.volume = 1f;
audioSource.pitch = 1f;
audioSource.spatialBlend = 0f;
audioSource.priority = 0;
audioSource.dopplerLevel = 0f;
audioSource.rolloffMode = (AudioRolloffMode)1;
}
}
catch
{
audioObject = null;
audioSource = null;
}
}
public static void PlayShortBeep()
{
PlayGeneratedBeep(GetShortBeepClip());
}
public static void PlayLongBeep()
{
PlayGeneratedBeep(GetLongBeepClip());
}
private static void PlayGeneratedBeep(AudioClip clip)
{
//IL_0003: Unknown result type (might be due to invalid IL or missing references)
//IL_000e: Expected O, but got Unknown
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: Expected O, but got Unknown
try
{
if (!((Object)clip == (Object)null))
{
EnsureReady();
if (!((Object)audioSource == (Object)null))
{
audioSource.PlayOneShot(clip, GetVolume());
}
}
}
catch
{
}
}
private static float GetVolume()
{
try
{
if (PropHuntFixPlugin.CfgCountdownSoundVolumePercent == null)
{
return 0.5f;
}
return (float)Mathf.Clamp(PropHuntFixPlugin.CfgCountdownSoundVolumePercent.Value, 0, 100) / 100f;
}
catch
{
return 0.5f;
}
}
private static AudioClip GetShortBeepClip()
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Expected O, but got Unknown
if ((Object)shortBeepClip == (Object)null)
{
shortBeepClip = CreateToneClip("REPOJP_PropHuntFix_Countdown_Put", 520f, 0.12f, 44100);
}
return shortBeepClip;
}
private static AudioClip GetLongBeepClip()
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Expected O, but got Unknown
if ((Object)longBeepClip == (Object)null)
{
longBeepClip = CreateToneClip("REPOJP_PropHuntFix_Countdown_Pee", 780f, 0.55f, 44100);
}
return longBeepClip;
}
private static AudioClip CreateToneClip(string name, float frequency, float duration, int sampleRate)
{
int num = Mathf.Max(1, Mathf.CeilToInt((float)sampleRate * duration));
float[] array = new float[num];
for (int i = 0; i < num; i++)
{
float num2 = (float)i / (float)sampleRate;
float num3 = 1f;
if (num2 < 0.01f)
{
num3 = num2 / 0.01f;
}
else if (num2 > duration - 0.03f)
{
num3 = Mathf.Clamp01((duration - num2) / 0.03f);
}
array[i] = Mathf.Sin(MathF.PI * 2f * frequency * num2) * 0.55f * num3;
}
AudioClip val = AudioClip.Create(name, num, 1, sampleRate, false);
val.SetData(array, 0);
return val;
}
}
internal static class HunterUnlockCountdownController
{
private class CountdownState
{
public double UnlockAtPhoton;
public bool Beep3Played;
public bool Beep2Played;
public bool Beep1Played;
public bool GoPlayed;
}
private static readonly Dictionary<int, CountdownState> States = new Dictionary<int, CountdownState>();
private static double lastPublishedUnlockAt;
private static readonly FieldInfo FieldHunterLockUntil = AccessTools.Field(typeof(PropHuntManager), "_hunterLockUntil");
public static void Tick(PropHuntManager manager)
{
//IL_0082: Unknown result type (might be due to invalid IL or missing references)
try
{
if ((Object)(object)manager == (Object)null || !PhotonNetwork.InRoom)
{
return;
}
PublishHostUnlockTime(manager);
double sharedUnlockPhotonTime = GetSharedUnlockPhotonTime();
if (sharedUnlockPhotonTime <= 0.0)
{
return;
}
double num = sharedUnlockPhotonTime - PhotonNetwork.Time;
if (!(num < -1.5) && !(num > 10.0))
{
SyncLocalHunterLock(manager, num);
int instanceID = ((Object)manager).GetInstanceID();
if (!States.TryGetValue(instanceID, out var value))
{
value = new CountdownState();
States[instanceID] = value;
}
if (Math.Abs(value.UnlockAtPhoton - sharedUnlockPhotonTime) > 0.05)
{
value.UnlockAtPhoton = sharedUnlockPhotonTime;
value.Beep3Played = num < 2.8;
value.Beep2Played = num < 1.8;
value.Beep1Played = num < 0.8;
value.GoPlayed = num < -0.1;
}
if (!value.Beep3Played && num <= 3.0 && num > 2.0)
{
value.Beep3Played = true;
PropHuntCountdownBeepUtil.PlayShortBeep();
}
if (!value.Beep2Played && num <= 2.0 && num > 1.0)
{
value.Beep2Played = true;
PropHuntCountdownBeepUtil.PlayShortBeep();
}
if (!value.Beep1Played && num <= 1.0 && num > 0.0)
{
value.Beep1Played = true;
PropHuntCountdownBeepUtil.PlayShortBeep();
}
if (!value.GoPlayed && num <= 0.0)
{
value.GoPlayed = true;
PropHuntCountdownBeepUtil.PlayLongBeep();
SyncLocalHunterLock(manager, 0.0);
}
}
}
catch
{
}
}
public static double GetSharedRemainingSeconds()
{
try
{
if (!PhotonNetwork.InRoom)
{
return double.NaN;
}
double sharedUnlockPhotonTime = GetSharedUnlockPhotonTime();
if (sharedUnlockPhotonTime <= 0.0)
{
return double.NaN;
}
return sharedUnlockPhotonTime - PhotonNetwork.Time;
}
catch
{
return double.NaN;
}
}
public static void PublishHostUnlockTimeForNewRound(FixConfigSnapshot snapshot)
{
try
{
if (PhotonNetwork.IsMasterClient && PhotonNetwork.CurrentRoom != null && snapshot != null)
{
float num = Mathf.Max(0f, snapshot.HunterLockSeconds);
if (!(num <= 0f))
{
double photonUnlockAt = PhotonNetwork.Time + (double)num;
WriteSharedUnlockTime(photonUnlockAt, num, "new-round");
}
}
}
catch
{
}
}
private static void PublishHostUnlockTime(PropHuntManager manager)
{
try
{
if (!PhotonNetwork.IsMasterClient || PhotonNetwork.CurrentRoom == null || (Object)(object)manager == (Object)null)
{
return;
}
double sharedUnlockPhotonTime = GetSharedUnlockPhotonTime();
if (!(sharedUnlockPhotonTime > PhotonNetwork.Time - 0.25) || !(sharedUnlockPhotonTime < PhotonNetwork.Time + 120.0))
{
float hunterUnlockTimeLocal = GetHunterUnlockTimeLocal(manager);
float num = 0f;
if (hunterUnlockTimeLocal > Time.time)
{
num = hunterUnlockTimeLocal - Time.time;
}
else if (manager.PreHidePhaseActive && !manager.RoundIsLive)
{
num = Mathf.Clamp(Mathf.Max(0f, manager.Hunter