using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using DefaultNamespace;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using Steamworks;
using Unity.Mathematics;
using UnityEngine;
using Virality.Core;
using Virality.Helpers;
using Virality.State;
using Zorro.Settings;
[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("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("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.Security")]
[assembly: IgnoresAccessChecksTo("MonoMod.RuntimeDetour")]
[assembly: IgnoresAccessChecksTo("MonoMod.Utils")]
[assembly: IgnoresAccessChecksTo("mscorlib")]
[assembly: IgnoresAccessChecksTo("netstandard")]
[assembly: IgnoresAccessChecksTo("Newtonsoft.Json")]
[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("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("SteamManagerAssembly")]
[assembly: IgnoresAccessChecksTo("System.ComponentModel.Composition")]
[assembly: IgnoresAccessChecksTo("System.Configuration")]
[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.Net.Http")]
[assembly: IgnoresAccessChecksTo("System.Numerics")]
[assembly: IgnoresAccessChecksTo("System.Runtime")]
[assembly: IgnoresAccessChecksTo("System.Runtime.Serialization")]
[assembly: IgnoresAccessChecksTo("System.Security")]
[assembly: IgnoresAccessChecksTo("System.ServiceModel.Internals")]
[assembly: IgnoresAccessChecksTo("System.Transactions")]
[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.PlayableGraphVisualizer")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipeline.Universal.ShaderLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.ShaderLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary")]
[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.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.GridModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.HotReloadModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ImageConversionModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.IMGUIModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.InputLegacyModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.InputModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.JSONSerializeModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.LocalizationModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.NVIDIAModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ParticleSystemModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.PerformanceReportingModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.Physics2DModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.PhysicsModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ProfilerModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.PropertiesModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.RuntimeInitializeOnLoadManagerInitializerModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ScreenCaptureModule")]
[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("VerboseAssembly")]
[assembly: IgnoresAccessChecksTo("websocket-sharp")]
[assembly: IgnoresAccessChecksTo("Whinarn.UnityMeshSimplifier.Runtime")]
[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")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Extends the max number of players that can play in a lobby, adds late joining, and proper Steam rich presence.")]
[assembly: AssemblyFileVersion("1.5.3.0")]
[assembly: AssemblyInformationalVersion("1.5.3+3657fe5e1551e13cdefa5abe4bc15addfd975218")]
[assembly: AssemblyProduct("MaxWasUnavailable.Virality")]
[assembly: AssemblyTitle("MaxWasUnavailable.Virality")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/MaxWasUnavailable/Virality")]
[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.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
{
public static class PluginInfo
{
public const string PluginGuid = "MaxWasUnavailable.Virality";
public const string PluginVersion = "1.5.3";
}
[ContentWarningPlugin("MaxWasUnavailable.Virality", "1.5.3", false)]
public class Virality
{
[ContentWarningSetting]
public class MaxPlayersSetting : IntSetting, IExposedSetting
{
public SettingCategory GetSettingCategory()
{
return (SettingCategory)4;
}
public string GetDisplayName()
{
return "Max Players";
}
public override void ApplyValue()
{
MaxPlayers = ValidateValue(((IntSetting)this).Value);
}
public override int GetDefaultValue()
{
return 12;
}
private static int ValidateValue(int value)
{
return math.clamp(value, 1, 100);
}
public string GetDescription()
{
return "The maximum number of players allowed in your lobby.";
}
}
[ContentWarningSetting]
public class LateJoinSetting : BoolSetting, IExposedSetting
{
public SettingCategory GetSettingCategory()
{
return (SettingCategory)4;
}
public string GetDisplayName()
{
return "Allow Late Join";
}
public override void ApplyValue()
{
AllowLateJoin = ((BoolSetting)this).Value;
}
public override bool GetDefaultValue()
{
return true;
}
public string GetDescription()
{
return "Whether or not to allow players to join your lobby after the game has started.";
}
}
[ContentWarningSetting]
public class VoiceFixSetting : BoolSetting, IExposedSetting
{
public SettingCategory GetSettingCategory()
{
return (SettingCategory)4;
}
public string GetDisplayName()
{
return "Enable Voice Fix";
}
public override void ApplyValue()
{
EnableVoiceFix = ((BoolSetting)this).Value;
}
public override bool GetDefaultValue()
{
return true;
}
public string GetDescription()
{
return "Whether or not to enable the voice fix.";
}
}
private bool _isPatched;
private Harmony? Harmony { get; set; }
internal static Logger? Logger { get; }
internal static int MaxPlayers { get; private set; }
internal static bool AllowLateJoin { get; private set; }
internal static bool EnableVoiceFix { get; private set; }
public static Virality Instance { get; }
static Virality()
{
MaxPlayers = 12;
AllowLateJoin = true;
EnableVoiceFix = true;
Logger = new Logger();
Instance = new Virality();
}
public Virality()
{
Logger?.LogInfo("Plugin MaxWasUnavailable.Virality is loaded!");
}
private 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("MaxWasUnavailable.Virality");
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
{
[HarmonyPrefix]
[HarmonyPatch("OnPlayerJoined")]
private static bool OnPlayerJoinedPrefix()
{
return PlayerHandler.instance.players.Count <= 4;
}
}
[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(MainMenuHandler))]
[HarmonyPriority(800)]
internal static class MainMenuHandlerPatches
{
[HarmonyTranspiler]
[HarmonyPatch("OnSteamHosted")]
private static IEnumerable<CodeInstruction> OnSteamHostedTranspiler(IEnumerable<CodeInstruction> instructions)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_0050: Unknown result type (might be due to invalid IL or missing references)
//IL_005a: Expected O, but got Unknown
return new CodeMatcher(instructions, (ILGenerator)null).SearchForward((Func<CodeInstruction, bool>)((CodeInstruction instruction) => instruction.opcode == OpCodes.Ldc_I4_4)).ThrowIfInvalid("Could not find max players constant").SetInstructionAndAdvance(new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(LobbyHelper), "GetLobbyMaxConfig", (Type[])null, (Type[])null)))
.InstructionEnumeration();
}
}
[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 bool IsPhotonLobbyLimitError(string title, string body)
{
if (title.ToLower() == "failed to create photon room")
{
return body.ToLower().Contains("max players peer room value is too big");
}
return false;
}
[HarmonyPrefix]
[HarmonyPatch("ShowError")]
private static void ShowErrorPrefix(string title, ref string body)
{
if (IsPhotonLobbyLimitError(title, body))
{
int num = int.Parse(body.Split(':').Last());
Virality.Logger?.LogWarning($"Photon lobby limit error detected. Setting temporary max player override to {num}. You may use a mod such as \"Self Sufficient\" to increase this limit.");
PhotonLobbyLimitTracker.PlayerLimit = num;
body += $"\n\nThe lobby player limit will temporarily be set to {num} for the duration of this session.";
body += "\nYou may use a mod such as \"Self Sufficient\" to host your own Photon server with a higher player limit.";
}
}
[HarmonyPrefix]
[HarmonyPatch("Show")]
private static void ShowPostfix(string title, ref string body, ref ModalOption[] options)
{
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
//IL_0031: Expected O, but got Unknown
if (IsPhotonLobbyLimitError(title, body))
{
ModalOption element = new ModalOption("Cancel", (Action)CancelPhotonLobbyLimitOverride);
options = options.Append(element).ToArray();
}
}
private static void CancelPhotonLobbyLimitOverride()
{
PhotonLobbyLimitTracker.PlayerLimit = null;
Virality.Logger?.LogWarning("Photon lobby limit override cancelled.");
}
}
[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(PlayerHandler))]
[HarmonyPriority(800)]
internal static class PlayerHandlerPatches
{
[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<object>());
}
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.ToArray()[i].data.currentBed != (Object)null)
{
num++;
}
}
__result = num >= Math.Min(__instance.playersAlive.Count, 4);
}
[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.ToArray()[i].data.sleepAmount >= 0.9f)
{
num++;
}
}
__result = num >= Math.Min(__instance.playersAlive.Count, 4);
}
}
[HarmonyPatch(typeof(SpawnHandler))]
[HarmonyPriority(800)]
internal static class SpawnHandlerPatches
{
[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();
}
[HarmonyTranspiler]
[HarmonyPatch(/*Could not decode attribute arguments.*/)]
private static IEnumerable<CodeInstruction> ConstructorTranspiler(IEnumerable<CodeInstruction> instructions)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_0050: Unknown result type (might be due to invalid IL or missing references)
//IL_005a: Expected O, but got Unknown
return new CodeMatcher(instructions, (ILGenerator)null).SearchForward((Func<CodeInstruction, bool>)((CodeInstruction instruction) => instruction.opcode == OpCodes.Ldarg_1)).ThrowIfInvalid("Could not find max players argument").SetInstructionAndAdvance(new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(LobbyHelper), "GetLobbyMaxConfig", (Type[])null, (Type[])null)))
.InstructionEnumeration();
}
}
[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
{
public static class LateJoinHelper
{
public static bool IsLateJoinAllowed { get; private set; }
public static void EnableLateJoin()
{
Virality.Logger?.LogDebug("Enabling late join.");
SteamLobbyHelper.LobbyHandler.OpenLobby();
PhotonNetwork.CurrentRoom.IsOpen = true;
PhotonNetwork.CurrentRoom.IsVisible = true;
IsLateJoinAllowed = true;
}
public static void DisableLateJoin()
{
Virality.Logger?.LogDebug("Disabling late join.");
SteamLobbyHelper.LobbyHandler.HideLobby();
PhotonNetwork.CurrentRoom.IsOpen = false;
PhotonNetwork.CurrentRoom.IsVisible = false;
IsLateJoinAllowed = false;
}
}
public static class LobbyHelper
{
public static int GetLobbyMaxConfig()
{
return PhotonLobbyLimitTracker.PlayerLimit ?? Virality.MaxPlayers;
}
}
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.GetLobbyMaxConfig());
}
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 "[MaxWasUnavailable.Virality:1.5.3] " + 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)
{
}
}
}