using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using SleepeyDev.OnTogetherPomoSound.Patches;
using SleepeyDev.OnTogetherPomoSound.Pomodoro;
using SleepeyDev.OnTogetherPomoSound.UI;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("SleepeyDev")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("OnTogetherPomoSound")]
[assembly: AssemblyTitle("OnTogetherPomoSound")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace SleepeyDev.OnTogetherPomoSound
{
public static class Conflict
{
private const string LocalPlaylistGuid = "com.sleepeydev.ontogether.localplaylist";
private static readonly Version SplitVersion = new Version(0, 6, 0);
private static bool _checked;
private static bool _standDown;
public static bool StandDown
{
get
{
if (_checked)
{
return _standDown;
}
_checked = true;
_standDown = Detect();
return _standDown;
}
}
private static bool Detect()
{
try
{
if (!Chainloader.PluginInfos.TryGetValue("com.sleepeydev.ontogether.localplaylist", out var value) || value == null || value.Metadata == null)
{
return false;
}
Version version = value.Metadata.Version;
if (version == null || version >= SplitVersion)
{
return false;
}
Plugin.Log.LogWarning((object)("On-Together Local Playlist " + version?.ToString() + " is installed and still carries the Pomodoro tick volume itself, so this mod is standing down to avoid a duplicate row and two plugins fighting over the same AudioSource."));
Plugin.Log.LogWarning((object)("Update Local Playlist to " + SplitVersion?.ToString() + " or newer and this mod takes over. Your tick volume stays where it is either way."));
return true;
}
catch (Exception ex)
{
Plugin.Log.LogWarning((object)("Could not check for an older Local Playlist: " + ex.Message));
return false;
}
}
}
public static class HarmonyBootstrap
{
private static readonly Type[] PatchClasses = new Type[1] { typeof(UiBuildPatches) };
public static void ApplyAll()
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Expected O, but got Unknown
Harmony val = new Harmony("com.sleepeydev.ontogether.pomosound");
int num = 0;
Type[] patchClasses = PatchClasses;
foreach (Type type in patchClasses)
{
try
{
val.CreateClassProcessor(type).Patch();
num++;
}
catch (Exception ex)
{
Plugin.Log.LogError((object)("Patch class " + type.Name + " failed to apply (that feature is off): " + ex.Message));
}
}
Plugin.Log.LogInfo((object)("Applied " + num + "/" + PatchClasses.Length + " patch classes."));
}
}
public static class ModConfig
{
public static ConfigEntry<bool> Enabled;
public static ConfigEntry<float> TickTockVolumeScale;
public static ConfigEntry<bool> TickRowEnabled;
public static ConfigEntry<bool> RowShrink;
public static ConfigEntry<float> RowHeight;
public static ConfigEntry<string> TickRowLabel;
public static ConfigEntry<bool> VerboseLogging;
public static ConfigEntry<bool> DumpUi;
public static ConfigEntry<KeyCode> DumpUiKey;
public static void Bind(ConfigFile cfg)
{
//IL_0044: Unknown result type (might be due to invalid IL or missing references)
//IL_004e: Expected O, but got Unknown
//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
//IL_00bc: Expected O, but got Unknown
Enabled = cfg.Bind<bool>("Pomodoro", "Enabled", true, "Master switch for the tick-tock volume fix.");
TickTockVolumeScale = cfg.Bind<float>("Pomodoro", "TickTockVolumeScale", 0f, new ConfigDescription("Loudness of the Pomodoro ticking clock, as a fraction of the phase-end bell volume.\nThe game itself forces these two to be equal (SoundManager.SetPomodoroVolume), which is why\nturning the bell down also turns the ticking down. 0 = ticking silent, bell unchanged.\n1 = vanilla behaviour. The game's own per-phase tick toggles keep working either way.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
TickRowEnabled = cfg.Bind<bool>("UI", "TickRowEnabled", true, "Add a 'Tick volume' slider to the Pomodoro sound settings, under the bell volume.");
RowShrink = cfg.Bind<bool>("UI", "RowShrink", true, "Shrink the Pomodoro sound rows so the added one fits inside the panel. The four vanilla\nrows already just overflow it, so a fifth needs the room.");
RowHeight = cfg.Bind<float>("UI", "RowHeight", 79f, new ConfigDescription("Height of each Pomodoro sound row when RowShrink is on.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(40f, 110f), Array.Empty<object>()));
TickRowLabel = cfg.Bind<string>("UI", "TickRowLabel", "Tick volume", "Caption of the added Pomodoro row.");
VerboseLogging = cfg.Bind<bool>("Diagnostics", "VerboseLogging", false, "Log what the row build did. Noisy; for bug reports.");
DumpUi = cfg.Bind<bool>("Diagnostics", "DumpUi", false, "Dump the Pomodoro sound settings tree to the log when it is built. Attach the log to a\nbug report if the row lands in the wrong place.");
DumpUiKey = cfg.Bind<KeyCode>("Diagnostics", "DumpUiKey", (KeyCode)283, "Key that dumps that tree on demand. F4-F6 and F10-F11 are taken by Day and Night,\nF7-F9 by FrameCare and BlueSage, and F3 by Local Playlist, so F1-F2 are the free ones.");
}
}
public sealed class ModRoot : MonoBehaviour
{
public static ModRoot Instance { get; private set; }
public static void Create()
{
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: Expected O, but got Unknown
if (!((Object)(object)Instance != (Object)null))
{
GameObject val = new GameObject("OTPS_ModRoot")
{
hideFlags = (HideFlags)61
};
Object.DontDestroyOnLoad((Object)val);
Instance = val.AddComponent<ModRoot>();
}
}
private void Update()
{
//IL_003c: Unknown result type (might be due to invalid IL or missing references)
try
{
TickTockVolume.Tick();
}
catch (Exception ex)
{
Plugin.Log.LogError((object)("TickTockVolume.Tick threw, disabling: " + ex));
TickTockVolume.Disable();
}
if (ModConfig.DumpUiKey != null && Input.GetKeyDown(ModConfig.DumpUiKey.Value))
{
UiBuilder.DumpNow();
}
}
}
[BepInPlugin("com.sleepeydev.ontogether.pomosound", "On-Together Pomodoro Sound", "1.0.0")]
public sealed class Plugin : BaseUnityPlugin
{
public const string Guid = "com.sleepeydev.ontogether.pomosound";
public static ManualLogSource Log { get; private set; }
private void Awake()
{
Log = ((BaseUnityPlugin)this).Logger;
try
{
ModConfig.Bind(((BaseUnityPlugin)this).Config);
}
catch (Exception ex)
{
Log.LogError((object)("Config binding failed - some features will switch themselves off: " + ex));
}
ModRoot.Create();
HarmonyBootstrap.ApplyAll();
Log.LogInfo((object)("Pomodoro Sound " + ((BaseUnityPlugin)this).Info.Metadata.Version?.ToString() + " ready."));
Refl.LogHealth();
}
}
public static class Refl
{
private static readonly List<string> Missing = new List<string>();
public static readonly FieldRef<SoundManager, AudioSource> PomodoroBell = Field<SoundManager, AudioSource>("_pomodoroBell");
public static readonly FieldRef<SoundManager, AudioSource> PomodoroTickTock = Field<SoundManager, AudioSource>("_pomodoroTickTock");
public static readonly FieldRef<PomodoroController, Slider> PomodoroBellVolume = Field<PomodoroController, Slider>("_pomodoroBellVolume");
public static bool PomodoroReady
{
get
{
if (PomodoroBell != null)
{
return PomodoroTickTock != null;
}
return false;
}
}
public static bool PomodoroUiReady
{
get
{
if (PomodoroReady)
{
return PomodoroBellVolume != null;
}
return false;
}
}
private static FieldRef<TOwner, TField> Field<TOwner, TField>(string name)
{
try
{
FieldInfo fieldInfo = AccessTools.Field(typeof(TOwner), name);
if (fieldInfo == null || !typeof(TField).IsAssignableFrom(fieldInfo.FieldType))
{
Missing.Add(typeof(TOwner).Name + "." + name);
return null;
}
return AccessTools.FieldRefAccess<TOwner, TField>(name);
}
catch (Exception)
{
Missing.Add(typeof(TOwner).Name + "." + name);
return null;
}
}
public static void LogHealth()
{
if (Missing.Count == 0)
{
Plugin.Log.LogInfo((object)"Game handles: all resolved.");
return;
}
Plugin.Log.LogWarning((object)("Game handles missing (the game was probably updated): " + string.Join(", ", Missing.ToArray())));
Plugin.Log.LogWarning((object)("Feature availability - tick volume fix: " + (PomodoroReady ? "on" : "OFF") + ", tick volume slider: " + (PomodoroUiReady ? "on" : "OFF")));
}
}
}
namespace SleepeyDev.OnTogetherPomoSound.UI
{
public sealed class DragWatcher : MonoBehaviour, IPointerDownHandler, IEventSystemHandler, IPointerUpHandler
{
public bool IsDragging { get; private set; }
public event Action Down;
public event Action Up;
public static DragWatcher Attach(GameObject go)
{
if ((Object)(object)go == (Object)null)
{
return null;
}
DragWatcher component = go.GetComponent<DragWatcher>();
if (!((Object)(object)component != (Object)null))
{
return go.AddComponent<DragWatcher>();
}
return component;
}
public void OnPointerDown(PointerEventData eventData)
{
if (!IsDragging)
{
IsDragging = true;
Fire(this.Down);
}
}
public void OnPointerUp(PointerEventData eventData)
{
Release();
}
private void Update()
{
if (IsDragging && !Input.GetMouseButton(0))
{
Release();
}
}
private void OnDisable()
{
if (IsDragging)
{
Release();
}
}
private void Release()
{
if (IsDragging)
{
IsDragging = false;
Fire(this.Up);
}
}
private void Fire(Action a)
{
if (a == null)
{
return;
}
try
{
a();
}
catch (Exception ex)
{
Plugin.Log.LogError((object)("DragWatcher handler threw: " + ex));
}
}
}
public static class GameUi
{
public const string Prefix = "OTPS_";
public static Transform Existing(Transform parent, string name)
{
if (!((Object)(object)parent == (Object)null))
{
return parent.Find(name);
}
return null;
}
public static GameObject CloneObject(GameObject donor, Transform parent, string name)
{
if ((Object)(object)donor == (Object)null || (Object)(object)parent == (Object)null)
{
return null;
}
GameObject obj = Object.Instantiate<GameObject>(donor, parent, false);
((Object)obj).name = name;
StripLocalizers(obj);
obj.SetActive(true);
return obj;
}
public static void ClearListeners<T>(UnityEvent<T> evt)
{
if (evt != null)
{
for (int num = ((UnityEventBase)evt).GetPersistentEventCount() - 1; num >= 0; num--)
{
((UnityEventBase)evt).SetPersistentListenerState(num, (UnityEventCallState)0);
}
((UnityEventBase)evt).RemoveAllListeners();
}
}
public static void ClearListeners(UnityEvent evt)
{
if (evt != null)
{
for (int num = ((UnityEventBase)evt).GetPersistentEventCount() - 1; num >= 0; num--)
{
((UnityEventBase)evt).SetPersistentListenerState(num, (UnityEventCallState)0);
}
((UnityEventBase)evt).RemoveAllListeners();
}
}
public static int StripScripts(GameObject root)
{
if ((Object)(object)root == (Object)null)
{
return 0;
}
Assembly assembly = typeof(SoundManager).Assembly;
int num = 0;
Component[] componentsInChildren = root.GetComponentsInChildren<Component>(true);
foreach (Component val in componentsInChildren)
{
if (!((Object)(object)val == (Object)null))
{
Type type = ((object)val).GetType();
bool flag = type.Name.IndexOf("Localize", StringComparison.Ordinal) >= 0;
bool flag2 = type.Assembly == assembly;
if (flag || flag2)
{
Object.Destroy((Object)(object)val);
num++;
}
}
}
return num;
}
public static int StripLocalizers(GameObject root)
{
return StripScripts(root);
}
public static void Place(RectTransform rt, Vector2 anchoredPos, Vector2 sizeDelta)
{
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_0085: Unknown result type (might be due to invalid IL or missing references)
//IL_008f: Unknown result type (might be due to invalid IL or missing references)
//IL_0095: Unknown result type (might be due to invalid IL or missing references)
//IL_0077: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)rt == (Object)null)
{
return;
}
LayoutGroup val = (((Object)(object)((Transform)rt).parent == (Object)null) ? null : ((Component)((Transform)rt).parent).GetComponent<LayoutGroup>());
if ((Object)(object)val == (Object)null)
{
rt.anchoredPosition = anchoredPos;
rt.sizeDelta = sizeDelta;
return;
}
HorizontalOrVerticalLayoutGroup val2 = (HorizontalOrVerticalLayoutGroup)(object)((val is HorizontalOrVerticalLayoutGroup) ? val : null);
if ((Object)(object)val2 != (Object)null && val2.childControlHeight)
{
LayoutElement val3 = ((Component)rt).GetComponent<LayoutElement>();
if ((Object)(object)val3 == (Object)null)
{
val3 = ((Component)rt).gameObject.AddComponent<LayoutElement>();
}
val3.preferredHeight = sizeDelta.y;
}
else
{
rt.sizeDelta = new Vector2(rt.sizeDelta.x, sizeDelta.y);
}
}
public static void DropFocus()
{
if ((Object)(object)EventSystem.current != (Object)null)
{
EventSystem.current.SetSelectedGameObject((GameObject)null);
}
}
public static void DumpHierarchy(Transform root, string title, int maxDepth = 6)
{
if ((Object)(object)root == (Object)null)
{
Plugin.Log.LogInfo((object)("[dump] " + title + ": <null>"));
return;
}
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.Append("[dump] ").Append(title).Append('\n');
Describe(root, stringBuilder, 0, maxDepth);
Plugin.Log.LogInfo((object)stringBuilder.ToString());
}
private static void Describe(Transform t, StringBuilder sb, int depth, int maxDepth)
{
//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
//IL_0105: Unknown result type (might be due to invalid IL or missing references)
//IL_011f: Unknown result type (might be due to invalid IL or missing references)
//IL_0139: Unknown result type (might be due to invalid IL or missing references)
//IL_0153: Unknown result type (might be due to invalid IL or missing references)
//IL_016d: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)t == (Object)null || depth > maxDepth)
{
return;
}
sb.Append(' ', depth * 2).Append(((Object)t).name);
sb.Append(" [").Append(((Component)t).gameObject.activeSelf ? "on" : "off").Append(", sib ")
.Append(t.GetSiblingIndex())
.Append(']');
Component[] components = ((Component)t).GetComponents<Component>();
sb.Append(" {");
for (int i = 0; i < components.Length; i++)
{
if (i > 0)
{
sb.Append(", ");
}
sb.Append(((Object)(object)components[i] == (Object)null) ? "<missing>" : ((object)components[i]).GetType().Name);
}
sb.Append('}');
RectTransform val = (RectTransform)(object)((t is RectTransform) ? t : null);
if (val != null)
{
sb.Append(" aMin").Append(V(val.anchorMin)).Append(" aMax")
.Append(V(val.anchorMax))
.Append(" piv")
.Append(V(val.pivot))
.Append(" pos")
.Append(V(val.anchoredPosition))
.Append(" size")
.Append(V(val.sizeDelta))
.Append(" scale")
.Append(V(((Transform)val).localScale));
}
LayoutGroup val2 = (((Object)(object)t.parent == (Object)null) ? null : ((Component)t.parent).GetComponent<LayoutGroup>());
if ((Object)(object)val2 != (Object)null)
{
sb.Append(" [LAYOUT-DRIVEN by ").Append(((object)val2).GetType().Name).Append(']');
}
LayoutGroup component = ((Component)t).GetComponent<LayoutGroup>();
if ((Object)(object)component != (Object)null)
{
sb.Append(" ").Append(DescribeLayout(component));
}
Selectable component2 = ((Component)t).GetComponent<Selectable>();
Slider val3 = (Slider)(object)((component2 is Slider) ? component2 : null);
if (val3 != null)
{
sb.Append(" slider(persistent=").Append(((UnityEventBase)val3.onValueChanged).GetPersistentEventCount()).Append(')');
}
else
{
Button val4 = (Button)(object)((component2 is Button) ? component2 : null);
if (val4 != null)
{
sb.Append(" button(persistent=").Append(((UnityEventBase)val4.onClick).GetPersistentEventCount()).Append(')');
}
}
TMP_Text component3 = ((Component)t).GetComponent<TMP_Text>();
if ((Object)(object)component3 != (Object)null)
{
string text = component3.text ?? "";
if (text.Length > 40)
{
text = text.Substring(0, 40) + "...";
}
sb.Append(" text=\"").Append(text).Append('"');
}
sb.Append('\n');
for (int j = 0; j < t.childCount; j++)
{
Describe(t.GetChild(j), sb, depth + 1, maxDepth);
}
}
public static string DescribeLayout(LayoutGroup g)
{
//IL_0090: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)g == (Object)null)
{
return "";
}
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.Append(((object)g).GetType().Name).Append("(pad ").Append(g.padding.left)
.Append(',')
.Append(g.padding.right)
.Append(',')
.Append(g.padding.top)
.Append(',')
.Append(g.padding.bottom)
.Append(" align=")
.Append(g.childAlignment);
HorizontalOrVerticalLayoutGroup val = (HorizontalOrVerticalLayoutGroup)(object)((g is HorizontalOrVerticalLayoutGroup) ? g : null);
if (val != null)
{
stringBuilder.Append(" spacing=").Append(val.spacing).Append(" ctrlW=")
.Append(val.childControlWidth)
.Append(" ctrlH=")
.Append(val.childControlHeight)
.Append(" expW=")
.Append(val.childForceExpandWidth)
.Append(" expH=")
.Append(val.childForceExpandHeight)
.Append(" reverse=")
.Append(val.reverseArrangement);
}
return stringBuilder.Append(')').ToString();
}
private static string V(Vector2 v)
{
return "(" + v.x.ToString("0.##") + "," + v.y.ToString("0.##") + ")";
}
private static string V(Vector3 v)
{
return "(" + v.x.ToString("0.##") + "," + v.y.ToString("0.##") + ")";
}
}
public sealed class StaticText : MonoBehaviour
{
private TMP_Text _label;
public string Text;
public static StaticText Apply(TMP_Text label, string text)
{
if ((Object)(object)label == (Object)null)
{
return null;
}
StaticText staticText = ((Component)label).gameObject.GetComponent<StaticText>();
if ((Object)(object)staticText == (Object)null)
{
staticText = ((Component)label).gameObject.AddComponent<StaticText>();
}
staticText._label = label;
staticText.Text = text;
label.text = text;
return staticText;
}
private void OnEnable()
{
if ((Object)(object)_label != (Object)null && Text != null)
{
_label.text = Text;
}
}
}
public static class TickVolumeRow
{
private const string RowName = "OTPS_TickVolumeRow";
private static bool _failed;
public static void Build(PomodoroController pc)
{
if (_failed || Conflict.StandDown || !ModConfig.TickRowEnabled.Value)
{
return;
}
if (!Refl.PomodoroUiReady)
{
Plugin.Log.LogWarning((object)"Tick volume row: game handles missing, skipping. The ticking volume still follows Pomodoro/TickTockVolumeScale.");
_failed = true;
return;
}
Slider val = Refl.PomodoroBellVolume.Invoke(pc);
if ((Object)(object)val == (Object)null)
{
Plugin.Log.LogWarning((object)"Tick volume row: no bell-volume slider on this PomodoroController.");
return;
}
Transform parent = ((Component)val).transform.parent;
Transform val2 = (((Object)(object)parent != (Object)null) ? parent.parent : null);
if ((Object)(object)val2 == (Object)null)
{
Plugin.Log.LogWarning((object)"Tick volume row: the bell slider is not two levels inside a settings group.");
}
else
{
if ((Object)(object)GameUi.Existing(val2, "OTPS_TickVolumeRow") != (Object)null)
{
return;
}
GameObject val3 = GameUi.CloneObject(((Component)parent).gameObject, val2, "OTPS_TickVolumeRow");
if ((Object)(object)val3 == (Object)null)
{
Plugin.Log.LogWarning((object)"Tick volume row: cloning the bell row failed.");
return;
}
val3.transform.SetSiblingIndex(parent.GetSiblingIndex() + 1);
Slider componentInChildren = val3.GetComponentInChildren<Slider>(true);
if ((Object)(object)componentInChildren == (Object)null)
{
Object.Destroy((Object)(object)val3);
Plugin.Log.LogWarning((object)"Tick volume row: the cloned row has no slider.");
return;
}
GameUi.ClearListeners<float>((UnityEvent<float>)(object)componentInChildren.onValueChanged);
componentInChildren.minValue = 0f;
componentInChildren.maxValue = 1f;
componentInChildren.wholeNumbers = false;
componentInChildren.SetValueWithoutNotify(TickTockVolume.Scale);
((UnityEvent<float>)(object)componentInChildren.onValueChanged).AddListener((UnityAction<float>)TickTockVolume.SetLive);
DragWatcher.Attach(((Component)componentInChildren).gameObject).Up += GameUi.DropFocus;
TMP_Text val4 = FindLabel(val3.transform, ((Component)componentInChildren).transform);
if ((Object)(object)val4 != (Object)null)
{
StaticText.Apply(val4, ModConfig.TickRowLabel.Value);
}
else
{
Plugin.Log.LogWarning((object)"Tick volume row: no label found in the clone; the row is unlabelled.");
}
ShrinkRows(val2);
Plugin.Log.LogInfo((object)("Tick volume row added at sibling " + val3.transform.GetSiblingIndex() + " under " + ((Object)val2).name + " " + GameUi.DescribeLayout(((Component)val2).GetComponent<LayoutGroup>())));
}
}
private static TMP_Text FindLabel(Transform row, Transform slider)
{
TMP_Text[] componentsInChildren = ((Component)row).GetComponentsInChildren<TMP_Text>(true);
foreach (TMP_Text val in componentsInChildren)
{
if (!((Object)(object)val == (Object)null) && !val.transform.IsChildOf(slider))
{
return val;
}
}
return null;
}
private static void ShrinkRows(Transform group)
{
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
//IL_004d: Unknown result type (might be due to invalid IL or missing references)
//IL_0058: Unknown result type (might be due to invalid IL or missing references)
if (!ModConfig.RowShrink.Value)
{
return;
}
float num = Mathf.Max(20f, ModConfig.RowHeight.Value);
int num2 = 0;
for (int i = 0; i < group.childCount; i++)
{
Transform child = group.GetChild(i);
RectTransform val = (RectTransform)(object)((child is RectTransform) ? child : null);
if (val != null && ((Component)val).gameObject.activeSelf)
{
GameUi.Place(val, val.anchoredPosition, new Vector2(val.sizeDelta.x, num));
num2++;
}
}
if (ModConfig.VerboseLogging.Value)
{
Plugin.Log.LogInfo((object)("Tick volume row: shrank " + num2 + " row(s) to " + num + " px."));
}
}
public static void Reset()
{
_failed = false;
}
}
public static class UiBuilder
{
private static PomodoroController _pomodoro;
public static void BuildPomodoroUi(PomodoroController pc)
{
if (!((Object)(object)pc == (Object)null))
{
_pomodoro = pc;
try
{
TickVolumeRow.Build(pc);
}
catch (Exception ex)
{
Plugin.Log.LogError((object)("Tick volume row build failed: " + ex));
}
if (ModConfig.DumpUi.Value)
{
Dump();
}
}
}
public static void DumpNow()
{
Dump();
}
private static void Dump()
{
try
{
if (!((Object)(object)_pomodoro == (Object)null) && Refl.PomodoroBellVolume != null)
{
Slider val = Refl.PomodoroBellVolume.Invoke(_pomodoro);
GameUi.DumpHierarchy(((Object)(object)val != (Object)null && (Object)(object)((Component)val).transform.parent != (Object)null) ? ((Component)val).transform.parent.parent : null, "pomodoro sound settings (Group_Sounds)");
}
}
catch (Exception ex)
{
Plugin.Log.LogError((object)("UI dump failed: " + ex));
}
}
}
}
namespace SleepeyDev.OnTogetherPomoSound.Pomodoro
{
public static class TickTockVolume
{
private const float CommitDelay = 0.6f;
private static bool _disabled;
private static bool _wasApplying;
private static bool _loggedOnce;
private static AudioSource _bell;
private static AudioSource _tick;
private static float _nextResolveTime;
private static bool _hasLive;
private static float _live;
private static float _commitAt;
public static float Scale => Mathf.Clamp01(_hasLive ? _live : ModConfig.TickTockVolumeScale.Value);
public static void Disable()
{
_disabled = true;
}
public static void SetLive(float scale)
{
_live = Mathf.Clamp01(scale);
_hasLive = true;
_commitAt = Time.unscaledTime + 0.6f;
}
public static void Tick()
{
if (_disabled || Conflict.StandDown || !Refl.PomodoroReady)
{
return;
}
CommitIfDue();
bool value = ModConfig.Enabled.Value;
if (!Resolve())
{
return;
}
if (!value)
{
if (_wasApplying)
{
_tick.volume = _bell.volume;
_wasApplying = false;
}
return;
}
float num = _bell.volume * Scale;
if (!Mathf.Approximately(_tick.volume, num))
{
_tick.volume = num;
}
if (!_wasApplying)
{
_wasApplying = true;
if (!_loggedOnce)
{
_loggedOnce = true;
Plugin.Log.LogInfo((object)("Pomodoro tick-tock volume decoupled from the bell (scale " + Scale.ToString("0.00") + ")."));
}
}
}
private static void CommitIfDue()
{
if (_hasLive && !(_commitAt <= 0f) && !(Time.unscaledTime < _commitAt))
{
_commitAt = 0f;
if (!Mathf.Approximately(ModConfig.TickTockVolumeScale.Value, _live))
{
ModConfig.TickTockVolumeScale.Value = _live;
Plugin.Log.LogInfo((object)("Tick volume saved: " + _live.ToString("0.00")));
}
}
}
private static bool Resolve()
{
if ((Object)(object)_bell != (Object)null && (Object)(object)_tick != (Object)null)
{
return true;
}
if (Time.unscaledTime < _nextResolveTime)
{
return false;
}
_nextResolveTime = Time.unscaledTime + 1f;
SoundManager i = MonoSingleton<SoundManager>.I;
if ((Object)(object)i == (Object)null)
{
return false;
}
_bell = Refl.PomodoroBell.Invoke(i);
_tick = Refl.PomodoroTickTock.Invoke(i);
if ((Object)(object)_bell != (Object)null)
{
return (Object)(object)_tick != (Object)null;
}
return false;
}
}
}
namespace SleepeyDev.OnTogetherPomoSound.Patches
{
[HarmonyPatch]
public static class UiBuildPatches
{
[HarmonyPatch(typeof(PomodoroController), "Start")]
[HarmonyPostfix]
private static void PomodoroController_Start_Postfix(PomodoroController __instance)
{
try
{
UiBuilder.BuildPomodoroUi(__instance);
}
catch (Exception ex)
{
Plugin.Log.LogError((object)("BuildPomodoroUi: " + ex));
}
}
}
}