using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.Localization;
using UnityEngine.Localization.Settings;
using UnityEngine.Localization.SmartFormat.Extensions;
using UnityEngine.Localization.SmartFormat.PersistentVariables;
using UnityEngine.Localization.Tables;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("OldMarket.PreOpenTimeStop")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("OldMarket.PreOpenTimeStop")]
[assembly: AssemblyCopyright("Copyright © 2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("9c3c58c0-6e05-49fd-806b-572a8e946389")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
[BepInPlugin("oldmarket.pausetimebeforeopen", "Old Market Pause Time Before Open", "1.1.0")]
public class PreOpenPlugin : BaseUnityPlugin
{
public const string PluginGuid = "oldmarket.pausetimebeforeopen";
public const string PluginName = "Old Market Pause Time Before Open";
public const string PluginVersion = "1.1.0";
internal static ManualLogSource Log;
internal static bool OpenedToday;
internal static bool IsTimeFrozen;
internal static ConfigEntry<bool> AdvanceTimeUntilCustomer;
internal static ConfigEntry<float> FreezeMinutesBeforeCustomerStart;
internal static ConfigEntry<bool> ShowNumericTime;
private void Awake()
{
//IL_0080: Unknown result type (might be due to invalid IL or missing references)
Log = ((BaseUnityPlugin)this).Logger;
OpenedToday = false;
IsTimeFrozen = false;
AdvanceTimeUntilCustomer = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "AdvanceTimeUntilCustomer", true, "If true, the day starts with time running as normal and will automatically pause shortly before customers can start arriving (CustomerManager.timelineStart). If false, time is paused from the beginning of each day until the first time you open the market.");
FreezeMinutesBeforeCustomerStart = ((BaseUnityPlugin)this).Config.Bind<float>("General", "FreezeMinutesBeforeCustomerStart", 1f, "How many minutes before CustomerManager.timelineStart the time should be frozen when AdvanceTimeUntilCustomer is true.");
ShowNumericTime = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "ShowNumericTime", false, "If true, append the numeric time (HH:MM) after the localized time label for debugging, e.g. 'Morning (07:00)'.");
new Harmony("oldmarket.pausetimebeforeopen").PatchAll();
}
}
[HarmonyPatch(typeof(GameManager))]
internal static class GameManager_TimeFreezePatches
{
[HarmonyPatch(typeof(UIManager))]
internal static class UIManager_TimeFreezePatches
{
private const string PauseMark = "*";
private const string ScheduledMark = "*>";
[HarmonyPrefix]
[HarmonyPatch("SetTimeText")]
private static bool SetTimeText_Prefix(string value)
{
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
//IL_0043: Unknown result type (might be due to invalid IL or missing references)
try
{
IVariable obj = LocalizationSettings.StringDatabase.SmartFormatter.GetSourceExtension<PersistentVariablesSource>()["global"]["time"];
StringVariable val = (StringVariable)(object)((obj is StringVariable) ? obj : null);
if (val == null)
{
return true;
}
string text = LocalizationSettings.StringDatabase.GetLocalizedString(TableReference.op_Implicit("Translations"), TableEntryReference.op_Implicit(value), (Locale)null, (FallbackBehavior)0, Array.Empty<object>());
string text2 = string.Empty;
if (PreOpenPlugin.IsTimeFrozen)
{
text2 = "*";
}
else if (PreOpenPlugin.AdvanceTimeUntilCustomer != null && PreOpenPlugin.AdvanceTimeUntilCustomer.Value)
{
GameManager instance = GameManager.Instance;
CustomerManager instance2 = CustomerManager.Instance;
if ((Object)(object)instance != (Object)null && (Object)(object)instance2 != (Object)null && !instance.IsMarketOpen() && instance.GetTimelineValue() < instance2.timelineStart)
{
text2 = "*>";
}
}
if (PreOpenPlugin.ShowNumericTime != null && PreOpenPlugin.ShowNumericTime.Value)
{
GameManager instance3 = GameManager.Instance;
if ((Object)(object)instance3 != (Object)null)
{
float timelineValue = instance3.GetTimelineValue();
int num = (int)Math.Floor(timelineValue);
int num2 = (int)Math.Round((timelineValue - (float)num) * 60f);
if (num2 >= 60)
{
num2 -= 60;
num = (num + 1) % 24;
}
text += $"({num:00}:{num2:00})";
}
}
if (!string.IsNullOrEmpty(text2))
{
text += text2;
}
((Variable<string>)(object)val).Value = text;
return false;
}
catch (Exception ex)
{
ManualLogSource log = PreOpenPlugin.Log;
if (log != null)
{
log.LogError((object)("[TimeFreezeBeforeOpen] UI patch error: " + ex));
}
return true;
}
}
}
[HarmonyPostfix]
[HarmonyPatch("LoadWorldServer")]
private static void LoadWorldServer_Postfix(GameManager __instance)
{
if (((NetworkBehaviour)__instance).IsServer)
{
PreOpenPlugin.OpenedToday = false;
if (PreOpenPlugin.AdvanceTimeUntilCustomer != null && PreOpenPlugin.AdvanceTimeUntilCustomer.Value)
{
PreOpenPlugin.IsTimeFrozen = false;
}
else
{
FreezeTime(__instance);
}
}
}
[HarmonyPostfix]
[HarmonyPatch("NextDayServer")]
private static void NextDayServer_Postfix(GameManager __instance)
{
if (((NetworkBehaviour)__instance).IsServer)
{
PreOpenPlugin.OpenedToday = false;
if (PreOpenPlugin.AdvanceTimeUntilCustomer != null && PreOpenPlugin.AdvanceTimeUntilCustomer.Value)
{
PreOpenPlugin.IsTimeFrozen = false;
}
else
{
FreezeTime(__instance);
}
}
}
[HarmonyPostfix]
[HarmonyPatch("OnMarketStatusChanged")]
private static void OnMarketStatusChanged_Postfix(GameManager __instance, bool previous, bool current)
{
try
{
if (((NetworkBehaviour)__instance).IsServer && !previous && current && !PreOpenPlugin.OpenedToday)
{
if (PreOpenPlugin.IsTimeFrozen)
{
ResumeTime(__instance);
}
PreOpenPlugin.OpenedToday = true;
}
}
catch (Exception ex)
{
ManualLogSource log = PreOpenPlugin.Log;
if (log != null)
{
log.LogError((object)ex);
}
}
}
[HarmonyPostfix]
[HarmonyPatch("OnTimelineChanged")]
private static void OnTimelineChanged_Postfix(GameManager __instance, float previous, float current)
{
try
{
if (!((NetworkBehaviour)__instance).IsServer || PreOpenPlugin.AdvanceTimeUntilCustomer == null || !PreOpenPlugin.AdvanceTimeUntilCustomer.Value || PreOpenPlugin.IsTimeFrozen || __instance.IsMarketOpen())
{
return;
}
CustomerManager instance = CustomerManager.Instance;
if ((Object)(object)instance == (Object)null)
{
return;
}
float timelineStart = instance.timelineStart;
if (timelineStart <= 0f || timelineStart >= 22f)
{
return;
}
float num = ((PreOpenPlugin.FreezeMinutesBeforeCustomerStart != null) ? PreOpenPlugin.FreezeMinutesBeforeCustomerStart.Value : 0f);
float num2 = ((num > 0f) ? (num / 60f) : 0f);
float num3 = timelineStart;
if (num2 > 0f)
{
num3 = Math.Max(timelineStart - num2, 0f);
}
if (!(previous < num3) || !(current >= num3))
{
return;
}
__instance.SetTimelineServer(num3);
if ((Object)(object)__instance.azureTimeController != (Object)null)
{
__instance.azureTimeController.SetNewDayLength(-1f);
}
PreOpenPlugin.IsTimeFrozen = true;
try
{
UIManager.Instance.SetTimeText(__instance.GetTimeString());
}
catch (Exception ex)
{
ManualLogSource log = PreOpenPlugin.Log;
if (log != null)
{
log.LogError((object)("[TimeFreezeBeforeOpen] UI refresh error: " + ex));
}
}
}
catch (Exception ex2)
{
ManualLogSource log2 = PreOpenPlugin.Log;
if (log2 != null)
{
log2.LogError((object)("[TimeFreezeBeforeOpen] OnTimelineChanged_Postfix error: " + ex2));
}
}
}
private static void FreezeTime(GameManager gm)
{
if (!((Object)(object)gm == (Object)null) && !((Object)(object)gm.azureTimeController == (Object)null))
{
gm.azureTimeController.SetNewDayLength(-1f);
PreOpenPlugin.IsTimeFrozen = true;
}
}
private static void ResumeTime(GameManager gm)
{
if (!((Object)(object)gm == (Object)null) && !((Object)(object)gm.azureTimeController == (Object)null))
{
gm.azureTimeController.SetNewDayLength(gm.initialDayLength);
PreOpenPlugin.IsTimeFrozen = false;
}
}
}