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