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";
}