Decompiled source of PeakVersionBypass v1.2.0

plugins/PeakVersionBypass.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using UnityEngine;
using UnityEngine.Networking;

[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: CompilationRelaxations(8)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace PeakVersionBypass;

[BepInPlugin("com.black.peakversionbypass", "PEAK Version Bypass", "1.2.0")]
public class Plugin : BaseUnityPlugin
{
	internal const string ApiUrl = "https://peaklogin3.azurewebsites.net/api/VersionCheck?version=";

	internal const float FetchTimeoutSeconds = 2.5f;

	private Harmony _harmony;

	public static ConfigEntry<string> DevMessage;

	public static ConfigEntry<string> CachedMessage;

	public static Plugin Instance { get; private set; }

	private void Awake()
	{
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Expected O, but got Unknown
		//IL_0096: Unknown result type (might be due to invalid IL or missing references)
		//IL_009c: Expected O, but got Unknown
		//IL_012e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0135: Expected O, but got Unknown
		Instance = this;
		_harmony = new Harmony("com.black.peakversionbypass");
		DevMessage = ((BaseUnityPlugin)this).Config.Bind<string>("General", "DevMessage", "we updated the frogs again", "Fallback text shown in the menu's Dev Message slot when the real server message cannot be fetched.");
		CachedMessage = ((BaseUnityPlugin)this).Config.Bind<string>("General", "CachedMessage", "", "Last known real dev message, auto-updated while online. Leave empty to fall back to DevMessage.");
		int num = 0;
		MethodInfo methodInfo = AccessTools.Method("CloudAPI:CheckVersion", (Type[])null, (Type[])null);
		if (methodInfo != null)
		{
			HarmonyMethod val = new HarmonyMethod(typeof(Patches).GetMethod("CheckVersionPrefix", BindingFlags.Static | BindingFlags.NonPublic));
			_harmony.Patch((MethodBase)methodInfo, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			num++;
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Patched CloudAPI.CheckVersion");
		}
		else
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)"CloudAPI.CheckVersion not found - version check NOT bypassed");
		}
		MethodInfo methodInfo2 = null;
		Type type = AccessTools.TypeByName("MainMenuPageHandler");
		if (type != null)
		{
			methodInfo2 = AccessTools.PropertyGetter(type, "CanSkipVersionCheck");
		}
		if (methodInfo2 != null)
		{
			HarmonyMethod val2 = new HarmonyMethod(typeof(Patches).GetMethod("CanSkipPostfix", BindingFlags.Static | BindingFlags.NonPublic));
			_harmony.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, val2, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			num++;
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Patched MainMenuPageHandler.get_CanSkipVersionCheck -> true");
		}
		else
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)"MainMenuPageHandler.CanSkipVersionCheck not found");
		}
		((BaseUnityPlugin)this).Logger.LogInfo((object)("PEAK Version Bypass ready (" + num + " patches applied)"));
	}
}
internal static class Patches
{
	[Serializable]
	private class VersionCheckDto
	{
		public string Message;
	}

	private static bool CheckVersionPrefix(object __0)
	{
		object obj = BuildResponse();
		if (obj != null && __0 != null)
		{
			if ((Object)(object)Plugin.Instance != (Object)null)
			{
				((MonoBehaviour)Plugin.Instance).StartCoroutine(FetchAndRespond(__0, obj));
			}
			else
			{
				InvokeCallback(__0, obj);
			}
		}
		return false;
	}

	private static void CanSkipPostfix(ref bool __result)
	{
		__result = true;
	}

	private static IEnumerator FetchAndRespond(object callback, object response)
	{
		string fresh = null;
		float deadline = Time.realtimeSinceStartup + 2.5f;
		UnityWebRequest req = UnityWebRequest.Get("https://peaklogin3.azurewebsites.net/api/VersionCheck?version=" + Application.version);
		try
		{
			req.timeout = 2;
			UnityWebRequestAsyncOperation op = req.SendWebRequest();
			while (!((AsyncOperation)op).isDone && Time.realtimeSinceStartup < deadline)
			{
				yield return null;
			}
			if ((int)req.result == 1)
			{
				fresh = ExtractMessage(req.downloadHandler.text);
			}
		}
		finally
		{
			((IDisposable)req)?.Dispose();
		}
		if (!string.IsNullOrEmpty(fresh))
		{
			SetField(response, "Message", fresh);
			if (Plugin.CachedMessage != null)
			{
				Plugin.CachedMessage.Value = fresh;
			}
		}
		InvokeCallback(callback, response);
	}

	private static string ExtractMessage(string json)
	{
		try
		{
			return JsonUtility.FromJson<VersionCheckDto>(json)?.Message;
		}
		catch (Exception)
		{
			return null;
		}
	}

	private static void InvokeCallback(object callback, object response)
	{
		try
		{
			MethodInfo method = callback.GetType().GetMethod("Invoke");
			method.Invoke(callback, new object[1] { response });
		}
		catch (Exception)
		{
		}
	}

	private static object BuildResponse()
	{
		try
		{
			Type type = AccessTools.TypeByName("LoginResponse");
			if (type == null)
			{
				return null;
			}
			object obj = Activator.CreateInstance(type);
			DateTime dateTime = new DateTime(2025, 6, 14, 17, 0, 0, DateTimeKind.Utc);
			int num = (int)Math.Floor((DateTime.UtcNow - dateTime).TotalHours);
			int num2 = (int)Math.Floor((double)num / 24.0);
			DateTime dateTime2 = dateTime.AddHours(num2 * 24 + 24);
			TimeSpan timeSpan = dateTime2 - DateTime.UtcNow;
			SetField(obj, "VersionOkay", true);
			SetField(obj, "HoursUntilLevel", (int)Math.Floor(timeSpan.TotalHours));
			SetField(obj, "MinutesUntilLevel", timeSpan.Minutes);
			SetField(obj, "SecondsUntilLevel", timeSpan.Seconds);
			SetField(obj, "LevelIndex", num2);
			SetField(obj, "Message", ChooseMessage());
			return obj;
		}
		catch (Exception)
		{
			return null;
		}
	}

	private static string ChooseMessage()
	{
		if (Plugin.CachedMessage != null && !string.IsNullOrEmpty(Plugin.CachedMessage.Value))
		{
			return Plugin.CachedMessage.Value;
		}
		if (Plugin.DevMessage != null && !string.IsNullOrEmpty(Plugin.DevMessage.Value))
		{
			return Plugin.DevMessage.Value;
		}
		return "we updated the frogs again";
	}

	private static void SetField(object obj, string name, object value)
	{
		FieldInfo fieldInfo = AccessTools.Field(obj.GetType(), name);
		if (fieldInfo != null)
		{
			fieldInfo.SetValue(obj, value);
		}
	}
}