Decompiled source of CWOffline v1.0.2

BepInEx/plugins/CWOffline.dll

Decompiled 3 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Photon.Pun;
using TMPro;
using UnityEngine;
using UnityEngine.Localization.PropertyVariants;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("CWOffline")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Allows you to play Content Warning Offline.")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("CWOffline")]
[assembly: AssemblyTitle("CWOffline")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace CWOffline;

[BepInPlugin("CWOffline", "CWOffline", "1.0.0")]
[ContentWarningPlugin("CWOffline", "1.0.0", true)]
public class Plugin : BaseUnityPlugin
{
	internal static Harmony patch;

	internal static ManualLogSource Logger;

	internal static ConfigEntry<bool> showLoadingScreen;

	internal static ConfigEntry<bool> forceOffline;

	internal static bool m_Hosting;

	private static int connectionCache;

	internal static bool CheckInternet()
	{
		if (connectionCache != 0)
		{
			return connectionCache == 2;
		}
		try
		{
			new HttpClient();
			HttpWebRequest obj = (HttpWebRequest)WebRequest.Create("https://www.gstatic.com/generate_204");
			obj.KeepAlive = false;
			obj.Timeout = 2000;
			using ((HttpWebResponse)obj.GetResponse())
			{
				connectionCache = 2;
				return true;
			}
		}
		catch
		{
			connectionCache = 1;
			return false;
		}
	}

	private void Awake()
	{
		//IL_006e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0078: Expected O, but got Unknown
		m_Hosting = false;
		showLoadingScreen = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShowLoadingScreen", false, "Show Loading Screen when hosting while offline.");
		forceOffline = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ForceOffline", false, "Force Offline Mode.");
		connectionCache = 0;
		if (forceOffline.Value)
		{
			connectionCache = 1;
		}
		Logger = ((BaseUnityPlugin)this).Logger;
		patch = new Harmony("com.redbigz.CWOfflinePatch");
		patch.PatchAll();
		Logger.LogInfo((object)"Checking if offline...");
		if (!CheckInternet())
		{
			Logger.LogError((object)"Game is offline.");
		}
		else
		{
			Logger.LogInfo((object)"Game is online.");
		}
	}

	internal static void SetupMenu()
	{
		if (!CWOfflineAPI.IsGameOnline() && !((Object)(object)GameObject.Find("OfflineNotice") != (Object)null) && !((Object)(object)GameObject.Find("Canvas/MainPage/Buttons/Host") == (Object)null))
		{
			GameObject val = GameObject.Find("MainPage");
			GameObject val2 = GameObject.Find("Buttons");
			Logger.LogInfo((object)val2.GetComponentsInChildren<Transform>().Length.ToString());
			GameObject gameObject = ((Component)val2.transform.Find("Host")).gameObject;
			GameObject gameObject2 = ((Component)val2.transform.Find("Join")).gameObject;
			GameObject gameObject3 = ((Component)val.transform.Find("HIGH SERVER LOAD")).gameObject;
			gameObject2.SetActive(false);
			Object.Destroy((Object)(object)gameObject.GetComponentInChildren<GameObjectLocalizer>());
			((TMP_Text)gameObject.GetComponentInChildren<TextMeshProUGUI>()).text = "PLAY OFFLINE";
			GameObject obj = Object.Instantiate<GameObject>(gameObject3, val2.transform);
			Object.Destroy((Object)(object)obj.GetComponentInChildren<GameObjectLocalizer>());
			((TMP_Text)obj.GetComponentInChildren<TextMeshProUGUI>()).text = "YOU ARE CURRENTLY OFFLINE.";
			((Object)obj).name = "OfflineNotice";
			obj.transform.SetAsFirstSibling();
			obj.SetActive(true);
		}
	}
}
[HarmonyPatch(typeof(MainMenuMainPage), "OnPageEnter")]
internal static class SetupMenuPatch
{
	[HarmonyPostfix]
	private static void Postfix()
	{
		Plugin.m_Hosting = false;
		Plugin.SetupMenu();
	}
}
[HarmonyPatch(typeof(MainMenuHandler), "ConnectToPhoton")]
internal static class ConnectPatch
{
	[HarmonyPrefix]
	private static bool Prefix()
	{
		if (CWOfflineAPI.IsGameOffline())
		{
			Plugin.Logger.LogInfo((object)"Disconnecting Photon...");
			PhotonNetwork.OfflineMode = true;
			return false;
		}
		return true;
	}

	[HarmonyPostfix]
	private static void Postfix()
	{
	}
}
[HarmonyPatch(typeof(MainMenuHandler), "Host")]
internal static class HostPatch
{
	[HarmonyTranspiler]
	private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
	{
		if (!CWOfflineAPI.IsGameOffline() || !Plugin.showLoadingScreen.Value)
		{
			return instructions;
		}
		List<CodeInstruction> list = new List<CodeInstruction>(instructions);
		int num = 0;
		for (int i = 0; i < list.Count; i++)
		{
			CodeInstruction val = list[i];
			if (val.opcode == OpCodes.Callvirt && val.operand is MethodInfo methodInfo && methodInfo.Name == "HostMatch")
			{
				num = i;
			}
		}
		list.RemoveRange(num - 5, 6);
		return list.AsEnumerable();
	}

	[HarmonyPrefix]
	private static bool Prefix(int saveIndex, MainMenuHandler __instance)
	{
		if (CWOfflineAPI.IsGameOffline())
		{
			if (Plugin.m_Hosting)
			{
				return false;
			}
			if (Plugin.showLoadingScreen.Value)
			{
				return false;
			}
			SaveSystem.SelectCurrentSave(saveIndex);
			SaveSystem.UsingSave(true);
			Plugin.m_Hosting = true;
			return false;
		}
		return true;
	}

	[HarmonyPostfix]
	private static void Postfix(MainMenuHandler __instance)
	{
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		if (!CWOfflineAPI.IsGameOnline())
		{
			new Traverse((object)MainMenuHandler.SteamLobbyHandler).Field("m_isHostingPrivate").SetValue((object)true);
			AccessTools.Method(typeof(MainMenuHandler), "OnSteamHosted", (Type[])null, (Type[])null).Invoke(__instance, new object[1] { 1uL });
		}
	}
}
public static class CWOfflineAPI
{
	public static bool IsGameOffline()
	{
		return !Plugin.CheckInternet();
	}

	public static bool IsGameOnline()
	{
		return Plugin.CheckInternet();
	}
}
[HarmonyPatch]
internal class AddPlayerPatch
{
	[HarmonyTargetMethod]
	private static MethodInfo TargetMethod()
	{
		return AccessTools.Method(typeof(Player), "Start", (Type[])null, (Type[])null);
	}

	[HarmonyPostfix]
	private static IEnumerator Postfix(IEnumerator result, Player __instance)
	{
		if (CWOfflineAPI.IsGameOffline())
		{
			Scene activeScene = SceneManager.GetActiveScene();
			if (((Scene)(ref activeScene)).name == "SurfaceScene")
			{
				GameObject.Find("Tools/Teleporter").SetActive(false);
			}
		}
		while (result.MoveNext())
		{
			yield return result.Current;
		}
	}
}
[HarmonyPatch(typeof(StartGameDoorInteractable), "Interact")]
internal static class StartGameDoorInteractablePatch
{
	[HarmonyPrefix]
	private static bool Prefix(StartGameDoorInteractable __instance)
	{
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		if (CWOfflineAPI.IsGameOffline())
		{
			object value = new Traverse((object)__instance).Field("m_NetworkHandler").GetValue();
			((SurfaceNetworkHandler)((value is SurfaceNetworkHandler) ? value : null)).RequestStartGame();
			return false;
		}
		return true;
	}
}
internal static class Util
{
	public static GameObject FindObject(this GameObject parent, string name)
	{
		Transform[] componentsInChildren = parent.GetComponentsInChildren<Transform>(true);
		foreach (Transform val in componentsInChildren)
		{
			if (((Object)val).name.StartsWith(name))
			{
				return ((Component)val).gameObject;
			}
		}
		return null;
	}
}
public static class MyPluginInfo
{
	public const string PLUGIN_GUID = "CWOffline";

	public const string PLUGIN_NAME = "CWOffline";

	public const string PLUGIN_VERSION = "1.0.0";
}