using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using BepInEx; using DefaultNamespace; using ExitGames.Client.Photon; using HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using Photon.Realtime; using Steamworks; using TMPro; using UnityEngine; using UnityEngine.UI; using Virality.Core; using Virality.Helpers; using Virality.State; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: IgnoresAccessChecksTo("0Harmony")] [assembly: IgnoresAccessChecksTo("Accessibility")] [assembly: IgnoresAccessChecksTo("Ashley.MeshSplitter")] [assembly: IgnoresAccessChecksTo("Assembly-CSharp-firstpass")] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: IgnoresAccessChecksTo("com.rlabrecque.steamworks.net")] [assembly: IgnoresAccessChecksTo("Discord")] [assembly: IgnoresAccessChecksTo("HBAO.Demo.Universal.Runtime")] [assembly: IgnoresAccessChecksTo("HBAO.Runtime")] [assembly: IgnoresAccessChecksTo("HBAO.Universal.Runtime")] [assembly: IgnoresAccessChecksTo("LocalizationAssembly")] [assembly: IgnoresAccessChecksTo("Managers")] [assembly: IgnoresAccessChecksTo("MeshSplit")] [assembly: IgnoresAccessChecksTo("ModalAssembly")] [assembly: IgnoresAccessChecksTo("Mono.Cecil")] [assembly: IgnoresAccessChecksTo("Mono.Cecil.Mdb")] [assembly: IgnoresAccessChecksTo("Mono.Cecil.Pdb")] [assembly: IgnoresAccessChecksTo("Mono.Cecil.Rocks")] [assembly: IgnoresAccessChecksTo("Mono.Posix")] [assembly: IgnoresAccessChecksTo("Mono.Security")] [assembly: IgnoresAccessChecksTo("Mono.WebBrowser")] [assembly: IgnoresAccessChecksTo("MonoMod.RuntimeDetour")] [assembly: IgnoresAccessChecksTo("MonoMod.Utils")] [assembly: IgnoresAccessChecksTo("mscorlib")] [assembly: IgnoresAccessChecksTo("netstandard")] [assembly: IgnoresAccessChecksTo("Newtonsoft.Json")] [assembly: IgnoresAccessChecksTo("Photon")] [assembly: IgnoresAccessChecksTo("Photon3Unity3D")] [assembly: IgnoresAccessChecksTo("PhotonChat")] [assembly: IgnoresAccessChecksTo("PhotonRealtime")] [assembly: IgnoresAccessChecksTo("PhotonUnityNetworking")] [assembly: IgnoresAccessChecksTo("PhotonUnityNetworking.Utilities")] [assembly: IgnoresAccessChecksTo("PhotonVoice.API")] [assembly: IgnoresAccessChecksTo("PhotonVoice")] [assembly: IgnoresAccessChecksTo("PhotonVoice.PUN")] [assembly: IgnoresAccessChecksTo("Platforms")] [assembly: IgnoresAccessChecksTo("PlayEveryWare.VideoEncoding")] [assembly: IgnoresAccessChecksTo("pworld")] [assembly: IgnoresAccessChecksTo("sc.posteffects.runtime")] [assembly: IgnoresAccessChecksTo("Sirenix.OdinInspector.Attributes")] [assembly: IgnoresAccessChecksTo("Sirenix.OdinInspector.Modules.Unity.Addressables")] [assembly: IgnoresAccessChecksTo("Sirenix.OdinInspector.Modules.UnityLocalization")] [assembly: IgnoresAccessChecksTo("Sirenix.Serialization.Config")] [assembly: IgnoresAccessChecksTo("Sirenix.Serialization")] [assembly: IgnoresAccessChecksTo("Sirenix.Utilities")] [assembly: IgnoresAccessChecksTo("SteamCommon")] [assembly: IgnoresAccessChecksTo("SteamManagerAssembly")] [assembly: IgnoresAccessChecksTo("System.ComponentModel.Composition")] [assembly: IgnoresAccessChecksTo("System.Configuration")] [assembly: IgnoresAccessChecksTo("System.Configuration.Install")] [assembly: IgnoresAccessChecksTo("System.Core")] [assembly: IgnoresAccessChecksTo("System.Data.DataSetExtensions")] [assembly: IgnoresAccessChecksTo("System.Data")] [assembly: IgnoresAccessChecksTo("System")] [assembly: IgnoresAccessChecksTo("System.Drawing")] [assembly: IgnoresAccessChecksTo("System.EnterpriseServices")] [assembly: IgnoresAccessChecksTo("System.IO.Compression")] [assembly: IgnoresAccessChecksTo("System.IO.Compression.FileSystem")] [assembly: IgnoresAccessChecksTo("System.IO.Hashing")] [assembly: IgnoresAccessChecksTo("System.Memory")] [assembly: IgnoresAccessChecksTo("System.Net.Http")] [assembly: IgnoresAccessChecksTo("System.Numerics")] [assembly: IgnoresAccessChecksTo("System.Runtime.CompilerServices.Unsafe")] [assembly: IgnoresAccessChecksTo("System.Runtime")] [assembly: IgnoresAccessChecksTo("System.Runtime.Serialization")] [assembly: IgnoresAccessChecksTo("System.Runtime.Serialization.Formatters.Soap")] [assembly: IgnoresAccessChecksTo("System.Security")] [assembly: IgnoresAccessChecksTo("System.ServiceModel.Internals")] [assembly: IgnoresAccessChecksTo("System.ServiceProcess")] [assembly: IgnoresAccessChecksTo("System.Transactions")] [assembly: IgnoresAccessChecksTo("System.Windows.Forms")] [assembly: IgnoresAccessChecksTo("System.Xml")] [assembly: IgnoresAccessChecksTo("System.Xml.Linq")] [assembly: IgnoresAccessChecksTo("Tayx.Graphy")] [assembly: IgnoresAccessChecksTo("Unity.Addressables")] [assembly: IgnoresAccessChecksTo("Unity.AI.Navigation")] [assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging")] [assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging.DocCodeExamples")] [assembly: IgnoresAccessChecksTo("Unity.Burst")] [assembly: IgnoresAccessChecksTo("Unity.Burst.Unsafe")] [assembly: IgnoresAccessChecksTo("Unity.Collections")] [assembly: IgnoresAccessChecksTo("Unity.Collections.LowLevel.ILSupport")] [assembly: IgnoresAccessChecksTo("Unity.InputSystem")] [assembly: IgnoresAccessChecksTo("Unity.InputSystem.ForUI")] [assembly: IgnoresAccessChecksTo("Unity.InternalAPIEngineBridge.003")] [assembly: IgnoresAccessChecksTo("Unity.InternalAPIEngineBridge.013")] [assembly: IgnoresAccessChecksTo("Unity.Localization")] [assembly: IgnoresAccessChecksTo("Unity.Mathematics")] [assembly: IgnoresAccessChecksTo("Unity.Microsoft.GDK")] [assembly: IgnoresAccessChecksTo("Unity.Microsoft.GDK.Tools")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Center.Common")] [assembly: IgnoresAccessChecksTo("Unity.PlayableGraphVisualizer")] [assembly: IgnoresAccessChecksTo("Unity.Postprocessing.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.Profiling.Core")] [assembly: IgnoresAccessChecksTo("Unity.Rendering.LightTransport.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipeline.Universal.ShaderLibrary")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.Runtime.Shared")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.ShaderLibrary")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.GPUDriven.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Universal.2D.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Universal.Config.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Universal.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Universal.Shaders")] [assembly: IgnoresAccessChecksTo("Unity.ResourceManager")] [assembly: IgnoresAccessChecksTo("Unity.ScriptableBuildPipeline")] [assembly: IgnoresAccessChecksTo("Unity.Splines")] [assembly: IgnoresAccessChecksTo("Unity.TextMeshPro")] [assembly: IgnoresAccessChecksTo("Unity.Timeline")] [assembly: IgnoresAccessChecksTo("Unity.VectorGraphics")] [assembly: IgnoresAccessChecksTo("UnityEngine.AccessibilityModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.AIModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.AMDModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.AndroidJNIModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.AnimationModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.ARModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.AssetBundleModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.AudioModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.ClothModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.ClusterInputModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.ClusterRendererModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.ContentLoadModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.CoreModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.CrashReportingModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.DirectorModule")] [assembly: IgnoresAccessChecksTo("UnityEngine")] [assembly: IgnoresAccessChecksTo("UnityEngine.DSPGraphModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.GameCenterModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.GIModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.GraphicsStateCollectionSerializerModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.GridModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.HierarchyCoreModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.HotReloadModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.ImageConversionModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.IMGUIModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.InputForUIModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.InputLegacyModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.InputModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.JSONSerializeModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.LocalizationModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.MarshallingModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.MultiplayerModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.NVIDIAModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.ParticleSystemModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.PerformanceReportingModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.Physics2DModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.PhysicsModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.PropertiesModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.RuntimeInitializeOnLoadManagerInitializerModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.ScreenCaptureModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.ShaderVariantAnalyticsModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.SharedInternalsModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.SpriteMaskModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.SpriteShapeModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.StreamingModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.SubstanceModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.SubsystemsModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.TerrainModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.TerrainPhysicsModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.TextCoreFontEngineModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.TextCoreTextEngineModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.TextRenderingModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.TilemapModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.TLSModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.UI")] [assembly: IgnoresAccessChecksTo("UnityEngine.UIElementsModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.UIModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.UmbraModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.UnityAnalyticsCommonModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.UnityAnalyticsModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.UnityConnectModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.UnityCurlModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.UnityTestProtocolModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.UnityWebRequestAssetBundleModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.UnityWebRequestAudioModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.UnityWebRequestModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.UnityWebRequestTextureModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.UnityWebRequestWWWModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.VehiclesModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.VFXModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.VideoModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.VirtualTexturingModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.VRModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.WindModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.XRModule")] [assembly: IgnoresAccessChecksTo("Utilities")] [assembly: IgnoresAccessChecksTo("VerboseAssembly")] [assembly: IgnoresAccessChecksTo("websocket-sharp")] [assembly: IgnoresAccessChecksTo("Whinarn.UnityMeshSimplifier.Runtime")] [assembly: IgnoresAccessChecksTo("XblPCSandbox")] [assembly: IgnoresAccessChecksTo("Zorro.AutoLOD")] [assembly: IgnoresAccessChecksTo("Zorro.ControllerSupport")] [assembly: IgnoresAccessChecksTo("Zorro.Core.Runtime")] [assembly: IgnoresAccessChecksTo("Zorro.Localization")] [assembly: IgnoresAccessChecksTo("Zorro.PhotonUtility")] [assembly: IgnoresAccessChecksTo("Zorro.Recorder")] [assembly: IgnoresAccessChecksTo("Zorro.Settings.Runtime")] [assembly: IgnoresAccessChecksTo("Zorro.UI.Runtime")] [assembly: AssemblyCompany("MaxWasUnavailable;Day;Ethans FatAhh")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Automatic expanded multiplayer fork for Content Warning with late joining and Steam rich presence fixes.")] [assembly: AssemblyFileVersion("0.0.0.0")] [assembly: AssemblyInformationalVersion("0.0.0-dev")] [assembly: AssemblyProduct("ViralityDeprecatedSoIFixedIt")] [assembly: AssemblyTitle("ViralityDeprecatedSoIFixedIt")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace Virality { [BepInPlugin("EthansFatAhh.ViralityDeprecatedSoIFixedIt", "ViralityDeprecatedSoIFixedIt", "1.0.0")] public sealed class BepInExEntry : BaseUnityPlugin { private void Awake() { Virality.Logger?.LogInfo("BepInEx entry loaded. Applying multiplayer patches."); Virality.Instance.PatchAll(); } private void OnDestroy() { Virality.Instance.UnpatchAll(); } } public static class PluginInfo { public const string PluginGuid = "EthansFatAhh.ViralityDeprecatedSoIFixedIt"; public const string PluginName = "ViralityDeprecatedSoIFixedIt"; public const string PluginVersion = "1.0.0"; } [ContentWarningPlugin("EthansFatAhh.ViralityDeprecatedSoIFixedIt", "1.0.0", false)] public class Virality { private bool _isPatched; internal const int AutomaticSteamSlots = 250; internal const int UnlimitedPhotonSlots = 0; private Harmony? Harmony { get; set; } internal static Logger? Logger { get; } internal static int MaxPlayers => 250; internal static bool AllowLateJoin => true; internal static bool EnableVoiceFix => false; public static Virality Instance { get; } static Virality() { Logger = new Logger(); Instance = new Virality(); } public Virality() { Logger?.LogInfo("Plugin EthansFatAhh.ViralityDeprecatedSoIFixedIt is loaded!"); } public void PatchAll() { //IL_0040: 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_0047: Expected O, but got Unknown //IL_004c: Expected O, but got Unknown if (_isPatched) { Logger?.LogWarning("Already patched!"); return; } Logger?.LogDebug("Patching..."); if (Harmony == null) { Harmony val = new Harmony("EthansFatAhh.ViralityDeprecatedSoIFixedIt"); Harmony val2 = val; Harmony = val; } try { Harmony.PatchAll(); _isPatched = true; Logger?.LogDebug("Patched!"); } catch (Exception arg) { Logger?.LogError($"Failed to patch: {arg}"); } } public void UnpatchAll() { if (!_isPatched) { Logger?.LogWarning("Already unpatched!"); return; } Logger?.LogDebug("Unpatching..."); try { Harmony? harmony = Harmony; if (harmony != null) { harmony.UnpatchSelf(); } _isPatched = false; Logger?.LogDebug("Unpatched!"); } catch (Exception arg) { Logger?.LogError($"Failed to unpatch: {arg}"); } } } } namespace Virality.State { public static class CurrentObjectiveTracker { public static Objective? CurrentObjective { get; internal set; } } public static class DoorOpenTracker { public static bool IsDoorOpen { get; internal set; } } public static class PhotonLobbyLimitTracker { public static int? PlayerLimit { get; set; } } } namespace Virality.Patches { [HarmonyPatch(typeof(BedBoss))] [HarmonyPriority(800)] internal static class BedBossPatches { private const int VanillaBedCount = 4; [HarmonyPrefix] [HarmonyPatch("OnPlayerJoined")] private static bool OnPlayerJoinedPrefix(BedBoss __instance) { if (!PhotonNetwork.IsMasterClient || (Object)(object)PlayerHandler.instance == (Object)null) { return false; } int num = 0; int num2 = Math.Min(4, __instance.beds.Count); for (int i = 0; i < PlayerHandler.instance.players.Count; i++) { if (num >= num2) { break; } Player val = PlayerHandler.instance.players[i]; __instance.view_g.RPC("AssignBed", (RpcTarget)0, new object[2] { val.refs.view.ViewID, num }); num++; } return false; } } [HarmonyPatch(typeof(EscapeMenuMainPage))] [HarmonyPriority(800)] internal static class EscapeMenuMainPagePatches { [HarmonyPrefix] [HarmonyPatch("Update")] private static bool UpdatePrefix(EscapeMenuMainPage __instance) { bool active = LateJoinHelper.IsLateJoinAllowed || VanillaCheck(); ((Component)__instance.inviteButton).gameObject.SetActive(active); return false; } private static bool VanillaCheck() { if (MainMenuHandler.SteamLobbyHandler != null && (Object)(object)SurfaceNetworkHandler.Instance != (Object)null) { return !SurfaceNetworkHandler.HasStarted; } return false; } } [HarmonyPatch(typeof(InviteFriendsTerminal))] [HarmonyPriority(800)] internal static class InviteFriendsTerminalPatches { [HarmonyPrefix] [HarmonyPatch(/*Could not decode attribute arguments.*/)] private static bool IsGameFullPrefix(ref bool __result) { if (SteamLobbyHelper.LobbyHandler == null) { return true; } __result = PlayerHandler.instance.players.Count >= SteamLobbyHelper.LobbyHandler.m_MaxPlayers; return false; } [HarmonyPrefix] [HarmonyPatch(/*Could not decode attribute arguments.*/)] private static bool IsGameStartedPrefix(ref bool __result) { if (!Virality.AllowLateJoin) { return true; } __result = false; return false; } } [HarmonyPatch(typeof(Modal))] [HarmonyPriority(800)] internal static class ModalPatches { private const string PhotonRoomErrorTitle = "failed to create photon room"; private const string PhotonLobbyLimitBodyPartial = "max players peer room value is too big"; private static readonly Regex LastNumberRegex = new Regex("(\\d+)(?!.*\\d)", RegexOptions.Compiled); private static bool IsPhotonLobbyLimitError(string title, string body) { if (title.Equals("failed to create photon room", StringComparison.OrdinalIgnoreCase)) { return body.IndexOf("max players peer room value is too big", StringComparison.OrdinalIgnoreCase) >= 0; } return false; } [HarmonyPrefix] [HarmonyPatch("ShowError")] private static void ShowErrorPrefix(string title, ref string body) { if (IsPhotonLobbyLimitError(title, body)) { Match match = LastNumberRegex.Match(body); if (match.Success && int.TryParse(match.Value, out var result)) { Virality.Logger?.LogWarning($"Photon lobby limit error detected. Automatically using {result} players for this session."); PhotonLobbyLimitTracker.PlayerLimit = result; body += $"\n\nViralityDeprecatedSoIFixedIt detected the Photon limit and will use {result} players automatically for this session."; } } } } [HarmonyPatch(typeof(PhotonGameLobbyHandler))] [HarmonyPriority(800)] internal static class PhotonGameLobbyHandlerPatches { [HarmonyPrefix] [HarmonyPatch("Start")] private static void OnSteamHostedPrefix() { if (Virality.EnableVoiceFix) { OverrideVoiceServerAppId(); } } private static void OverrideVoiceServerAppId() { PhotonNetwork.PhotonServerSettings.AppSettings.AppIdVoice = PhotonNetwork.PhotonServerSettings.AppSettings.AppIdRealtime; Virality.Logger?.LogDebug("Voice server app id set to realtime server app id (" + PhotonNetwork.PhotonServerSettings.AppSettings.AppIdVoice + ")"); } [HarmonyPostfix] [HarmonyPatch("Start")] private static void StartPostfixHide() { if (PhotonLobbyHelper.IsMasterClient() && Virality.AllowLateJoin && !PhotonLobbyHelper.IsOnSurface()) { LateJoinHelper.DisableLateJoin(); } } [HarmonyPrefix] [HarmonyPatch("SetCurrentObjective")] private static bool SetCurrentObjectivePostfix(ref Objective objective) { if (!PhotonLobbyHelper.IsMasterClient()) { return true; } bool flag = objective is LeaveHouseObjective; if (flag) { Objective currentObjective = CurrentObjectiveTracker.CurrentObjective; bool flag2 = ((currentObjective is InviteFriendsObjective || currentObjective is LeaveHouseObjective) ? true : false); flag = !flag2; } if (flag) { return false; } Virality.Logger?.LogDebug($"Setting current objective to {objective}."); CurrentObjectiveTracker.CurrentObjective = objective; return true; } } [HarmonyPatch(typeof(PhotonNetwork))] [HarmonyPriority(800)] internal static class PhotonNetworkPatches { [HarmonyPrefix] [HarmonyPatch("CreateRoom", new Type[] { typeof(string), typeof(RoomOptions), typeof(TypedLobby), typeof(string[]) })] private static void CreateRoomPrefix(ref RoomOptions roomOptions) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown if (roomOptions == null) { roomOptions = new RoomOptions(); } roomOptions.MaxPlayers = LobbyHelper.GetPhotonRoomSlots(); string text = ((roomOptions.MaxPlayers <= 0) ? "unlimited" : roomOptions.MaxPlayers.ToString()); Virality.Logger?.LogInfo("Setting Photon room max players to " + text + "."); } [HarmonyPrefix] [HarmonyPatch("JoinRandomRoom", new Type[] { typeof(Hashtable), typeof(byte) })] private static void JoinRandomRoomPrefix(ref byte expectedMaxPlayers) { if (expectedMaxPlayers <= 4) { expectedMaxPlayers = (byte)LobbyHelper.GetPhotonRoomSlots(); } } } [HarmonyPatch(typeof(PlayerHandler))] [HarmonyPriority(800)] internal static class PlayerHandlerPatches { private const int RequiredSleepers = 1; [HarmonyPostfix] [HarmonyPatch("AddPlayer")] private static void AddPlayerPostfixOpenDoor(Player player) { if (PhotonLobbyHelper.IsMasterClient() && !player.IsLocal && Virality.AllowLateJoin && DoorOpenTracker.IsDoorOpen && PhotonLobbyHelper.IsOnSurface()) { SendDoorOpenRPC(player); } } [HarmonyPostfix] [HarmonyPatch("AddPlayer")] private static void AddPlayerPostfixSyncObjective(Player player) { if (PhotonLobbyHelper.IsMasterClient() && Virality.AllowLateJoin) { SyncObjectiveRPC(player); } } private static void SendDoorOpenRPC(Player player) { SurfaceNetworkHandler.Instance.m_View.RPC("RPCA_OpenDoor", player.refs.view.Controller, Array.Empty()); } private static void SyncObjectiveRPC(Player player) { Objective currentObjective = CurrentObjectiveTracker.CurrentObjective; if (currentObjective != null) { ((MonoBehaviourPun)PhotonGameLobbyHandler.Instance).photonView.RPC("RPC_SetCurrentObjective", player.refs.view.Controller, new object[1] { ObjectiveDatabase.GetIndex(currentObjective) }); } } [HarmonyPostfix] [HarmonyPatch("AllPlayersInBed")] private static void AllPlayersInBedPostfix(PlayerHandler __instance, ref bool __result) { int num = 0; for (int i = 0; i < __instance.playersAlive.Count; i++) { if ((Object)(object)__instance.playersAlive[i].data.currentBed != (Object)null) { num++; } } __result = __instance.playersAlive.Count > 0 && num >= 1; } [HarmonyPostfix] [HarmonyPatch("AllPlayersAsleep")] private static void AllPlayersAsleepPostfix(PlayerHandler __instance, ref bool __result) { int num = 0; for (int i = 0; i < __instance.playersAlive.Count; i++) { if (__instance.playersAlive[i].data.sleepAmount >= 0.9f) { num++; } } __result = __instance.playersAlive.Count > 0 && num >= 1; } } [HarmonyPatch(typeof(RichPresenceHandler))] [HarmonyPriority(800)] internal static class RichPresenceHandlerPatches { [HarmonyPrefix] [HarmonyPatch("SetGroupSize")] private static void SetGroupSizePrefix(ref int maxSize) { if (maxSize <= 4) { maxSize = LobbyHelper.GetLobbyMaxConfig(); } } } [HarmonyPatch(typeof(SpawnHandler))] [HarmonyPriority(800)] internal static class SpawnHandlerPatches { [HarmonyPostfix] [HarmonyPatch("Start")] private static void StartPostfix(SpawnHandler __instance) { CreditToastHelper.ShowLobbyJoinToast(); } [HarmonyPostfix] [HarmonyPatch("FindLocalSpawnIndex")] private static void FindLocalSpawnIndexPostfix(ref SpawnHandler __instance) { if (__instance.m_LocalSpawnIndex != 0) { int num = Math.Min(Math.Min(__instance.m_HospitalSpawns.Length, __instance.m_HouseSpawns.Length), __instance.m_DiveBellSpawns.Length) - 1; SpawnHandler obj = __instance; obj.m_LocalSpawnIndex %= num; SpawnHandler obj2 = __instance; obj2.m_LocalSpawnIndex++; } } } [HarmonyPatch(typeof(SteamLobbyHandler))] [HarmonyPriority(800)] internal static class SteamLobbyHandlerPatches { [HarmonyPrefix] [HarmonyPatch("HostMatch")] private static void HostMatchPrefix() { SteamLobbyHelper.SetLobbyMaxToConfig(); } } [HarmonyPatch(typeof(SurfaceNetworkHandler))] [HarmonyPriority(800)] internal static class SurfaceNetworkHandlerPatches { [HarmonyPostfix] [HarmonyPatch("RPCM_StartGame")] private static void RPCM_StartGamePostfix() { if (PhotonLobbyHelper.IsMasterClient() && Virality.AllowLateJoin && PhotonLobbyHelper.IsOnSurface()) { DoorOpenTracker.IsDoorOpen = true; LateJoinHelper.EnableLateJoin(); } } [HarmonyPostfix] [HarmonyPatch("OnSlept")] private static void OnSleptPostfix() { if (PhotonLobbyHelper.IsMasterClient() && Virality.AllowLateJoin) { LateJoinHelper.EnableLateJoin(); } } } } namespace Virality.Helpers { internal static class CreditToastHelper { private const string RuntimeObjectName = "ViralityDeprecatedSoIFixedIt_CreditToast"; private static bool _shownThisProcess; public static void ShowLobbyJoinToast() { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Expected O, but got Unknown if (!_shownThisProcess) { _shownThisProcess = true; GameObject val = GameObject.Find("ViralityDeprecatedSoIFixedIt_CreditToast"); if ((Object)(object)val == (Object)null) { val = new GameObject("ViralityDeprecatedSoIFixedIt_CreditToast"); Object.DontDestroyOnLoad((Object)(object)val); val.AddComponent(); } val.GetComponent()?.Show(); } } } internal sealed class CreditToastRuntime : MonoBehaviour { [CompilerGenerated] private sealed class d__8 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public CreditToastRuntime <>4__this; private float 5__2; object? IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object? IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__8(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { int num = <>1__state; CreditToastRuntime creditToastRuntime = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; 5__2 = 0f; goto IL_0080; case 1: <>1__state = -1; goto IL_0080; case 2: <>1__state = -1; goto IL_00da; case 3: { <>1__state = -1; break; } IL_0080: if (5__2 < 0.3f) { 5__2 += Time.unscaledDeltaTime; creditToastRuntime.SetToast(Mathf.Clamp01(5__2 / 0.3f), 5__2); <>2__current = null; <>1__state = 1; return true; } 5__2 = 0f; goto IL_00da; IL_00da: if (5__2 < 2.4f) { 5__2 += Time.unscaledDeltaTime; creditToastRuntime.SetToast(1f, 5__2 + 0.3f); <>2__current = null; <>1__state = 2; return true; } 5__2 = 0f; break; } if (5__2 < 0.75f) { 5__2 += Time.unscaledDeltaTime; creditToastRuntime.SetToast(1f - Mathf.Clamp01(5__2 / 0.75f), 5__2 + 0.3f + 2.4f); <>2__current = null; <>1__state = 3; return true; } creditToastRuntime.SetToast(0f, 0f); creditToastRuntime._toastRoutine = null; return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private CanvasGroup? _group; private RawImage? _background; private TextMeshProUGUI? _title; private TextMeshProUGUI? _sub; private Coroutine? _toastRoutine; private Texture2D? _loadedBackground; private void Awake() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_0053: 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_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_0112: 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_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Canvas"); val.transform.SetParent(((Component)this).transform, false); Canvas obj = val.AddComponent(); obj.renderMode = (RenderMode)0; obj.sortingOrder = 26000; val.AddComponent(); CanvasScaler obj2 = val.AddComponent(); obj2.uiScaleMode = (ScaleMode)1; obj2.referenceResolution = new Vector2(1920f, 1080f); obj2.matchWidthOrHeight = 0.5f; _group = val.AddComponent(); _group.alpha = 0f; _group.blocksRaycasts = false; _group.interactable = false; _background = CreateBackground(val.transform); _title = CreateText(val.transform, new Vector2(0.5f, 0.78f), new Vector2(0f, 0f), new Vector2(980f, 115f), 54f, (FontStyles)1, (TextAlignmentOptions)514); ((TMP_Text)_title).textWrappingMode = (TextWrappingModes)0; _sub = CreateText(val.transform, new Vector2(0.5f, 0.7f), new Vector2(0f, 0f), new Vector2(760f, 42f), 23f, (FontStyles)1, (TextAlignmentOptions)514); ((Graphic)_sub).color = new Color(0.85f, 0.95f, 1f, 1f); ((TMP_Text)_sub).text = "EthansFatAhh fixed it"; } public void Show() { RefreshBackgroundImage(); if (_toastRoutine != null) { ((MonoBehaviour)this).StopCoroutine(_toastRoutine); } _toastRoutine = ((MonoBehaviour)this).StartCoroutine(ShowRoutine()); } [IteratorStateMachine(typeof(d__8))] private IEnumerator ShowRoutine() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__8(0) { <>4__this = this }; } private void SetToast(float alpha, float time) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_group != (Object)null) { _group.alpha = alpha; } if ((Object)(object)_background != (Object)null) { ((Graphic)_background).color = new Color(1f, 1f, 1f, Mathf.Clamp01(alpha * 0.7f)); } if ((Object)(object)_title != (Object)null) { ((TMP_Text)_title).text = RainbowText("VIRALITY FIXED", time * 0.85f); float num = 1f + Mathf.Sin(time * 9f) * 0.018f; ((Transform)((TMP_Text)_title).rectTransform).localScale = Vector3.one * num; } if ((Object)(object)_sub != (Object)null) { ((Graphic)_sub).color = Color.HSVToRGB(Mathf.Repeat(time * 0.28f + 0.55f, 1f), 0.38f, 1f); } } private void RefreshBackgroundImage() { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Expected O, but got Unknown string backgroundPath = GetBackgroundPath(); if (!File.Exists(backgroundPath)) { if ((Object)(object)_background != (Object)null) { _background.texture = null; ((Component)_background).gameObject.SetActive(false); } return; } try { byte[] array = File.ReadAllBytes(backgroundPath); Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false); if (!ImageConversion.LoadImage(val, array)) { Object.Destroy((Object)(object)val); return; } if ((Object)(object)_loadedBackground != (Object)null) { Object.Destroy((Object)(object)_loadedBackground); } _loadedBackground = val; if ((Object)(object)_background != (Object)null) { _background.texture = (Texture)(object)val; ((Component)_background).gameObject.SetActive(true); } } catch (Exception ex) { Virality.Logger?.LogWarning("Failed to load custom toast background: " + ex.Message); } } private static string GetBackgroundPath() { string text = Path.Combine(AppContext.BaseDirectory, "Plugins", "ViralityDeprecatedSoIFixedIt", "CustomAssets"); string directoryName = Path.GetDirectoryName(typeof(CreditToastRuntime).Assembly.Location); string[] array = ((!string.IsNullOrEmpty(directoryName)) ? new string[2] { Path.Combine(directoryName, "CustomAssets"), text } : new string[1] { text }); string[] array2 = array; foreach (string path in array2) { string text2 = Path.Combine(path, "credit_background.jpg"); if (File.Exists(text2)) { return text2; } string text3 = Path.Combine(path, "credit_background.jpeg"); if (File.Exists(text3)) { return text3; } string text4 = Path.Combine(path, "credit_background.png"); if (File.Exists(text4)) { return text4; } } return Path.Combine(array[0], "credit_background.jpg"); } private static RawImage CreateBackground(Transform parent) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_001f: 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_0035: 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_0064: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("CreditBackground"); val.transform.SetParent(parent, false); RectTransform obj = val.AddComponent(); obj.anchorMin = Vector2.zero; obj.anchorMax = Vector2.one; obj.offsetMin = Vector2.zero; obj.offsetMax = Vector2.zero; RawImage obj2 = val.AddComponent(); ((Graphic)obj2).color = new Color(1f, 1f, 1f, 0f); ((Graphic)obj2).raycastTarget = false; val.SetActive(false); return obj2; } private static string RainbowText(string value, float offset) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) StringBuilder stringBuilder = new StringBuilder(value.Length * 24); for (int i = 0; i < value.Length; i++) { Color val = Color.HSVToRGB(Mathf.Repeat(offset + (float)i / (float)value.Length, 1f), 0.92f, 1f); stringBuilder.Append("'); stringBuilder.Append(value[i]); stringBuilder.Append(""); } return stringBuilder.ToString(); } private static TextMeshProUGUI CreateText(Transform parent, Vector2 anchor, Vector2 position, Vector2 size, float fontSize, FontStyles style, TextAlignmentOptions alignment) { //IL_0005: 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_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0041: 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_005b: 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_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Text"); val.transform.SetParent(parent, false); RectTransform obj = val.AddComponent(); obj.anchorMin = anchor; obj.anchorMax = anchor; obj.pivot = new Vector2(0.5f, 0.5f); obj.anchoredPosition = position; obj.sizeDelta = size; TextMeshProUGUI obj2 = val.AddComponent(); ((TMP_Text)obj2).fontSize = fontSize; ((TMP_Text)obj2).fontStyle = style; ((TMP_Text)obj2).alignment = alignment; ((Graphic)obj2).raycastTarget = false; ((TMP_Text)obj2).outlineWidth = 0.18f; ((TMP_Text)obj2).outlineColor = Color32.op_Implicit(new Color(0f, 0f, 0f, 0.8f)); return obj2; } } public static class LateJoinHelper { public static bool IsLateJoinAllowed { get; private set; } public static void EnableLateJoin() { Virality.Logger?.LogDebug("Enabling late join."); SteamLobbyHandler? lobbyHandler = SteamLobbyHelper.LobbyHandler; if (lobbyHandler != null) { lobbyHandler.OpenLobby(); } if (PhotonNetwork.CurrentRoom != null) { PhotonNetwork.CurrentRoom.IsOpen = true; PhotonNetwork.CurrentRoom.IsVisible = true; } IsLateJoinAllowed = true; } public static void DisableLateJoin() { Virality.Logger?.LogDebug("Disabling late join."); SteamLobbyHandler? lobbyHandler = SteamLobbyHelper.LobbyHandler; if (lobbyHandler != null) { lobbyHandler.HideLobby(); } if (PhotonNetwork.CurrentRoom != null) { PhotonNetwork.CurrentRoom.IsOpen = false; PhotonNetwork.CurrentRoom.IsVisible = false; } IsLateJoinAllowed = false; } } public static class LobbyHelper { private const int MinSteamSlots = 1; private const int MaxSteamSlots = 250; public static int GetLobbyMaxConfig() { int num = PhotonLobbyLimitTracker.PlayerLimit ?? Virality.MaxPlayers; if (num < 1) { return 1; } if (num <= 250) { return num; } return 250; } public static int GetPhotonRoomSlots() { return PhotonLobbyLimitTracker.PlayerLimit.GetValueOrDefault(); } } public static class PhotonLobbyHelper { public static bool IsOnSurface() { return PhotonGameLobbyHandler.IsSurface; } public static void SetLobbyMaxPlayers(int maxPlayers) { PhotonNetwork.CurrentRoom.MaxPlayers = maxPlayers; } public static void SetLobbyMaxToConfig() { SetLobbyMaxPlayers(LobbyHelper.GetPhotonRoomSlots()); } public static bool IsMasterClient() { return PhotonNetwork.IsMasterClient; } } public static class SteamLobbyHelper { public static SteamLobbyHandler? LobbyHandler => MainMenuHandler.SteamLobbyHandler; public static AppId_t GetAppId() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return SteamUtils.GetAppID(); } public static CSteamID GetUserId() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return SteamUser.GetSteamID(); } public static CSteamID GetLobbyId() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) return LobbyHandler.m_CurrentLobby; } public static void SetLobbyMaxPlayers(int maxPlayers) { Virality.Logger?.LogInfo($"Setting lobby max players to {maxPlayers}."); LobbyHandler.m_MaxPlayers = maxPlayers; } public static void SetLobbyMaxToConfig() { SetLobbyMaxPlayers(LobbyHelper.GetLobbyMaxConfig()); } } } namespace Virality.Core { public class Logger { private string MessageFormat(string message) { return "[EthansFatAhh.ViralityDeprecatedSoIFixedIt:1.0.0] " + message; } public void LogDebug(string message) { Debug.Log((object)MessageFormat(message)); } public void LogInfo(string message) { Debug.Log((object)MessageFormat(message)); } public void LogWarning(string message) { Debug.LogWarning((object)MessageFormat(message)); } public void LogError(string message) { Debug.LogError((object)MessageFormat(message)); } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }