using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BBGreenTimer;
using BBModMenu;
using HarmonyLib;
using MelonLoader;
using UnityEngine;
using UnityEngine.UIElements;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("BBGreenTimer")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("BBGreenTimer")]
[assembly: AssemblyCopyright("Copyright © 2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: MelonInfo(typeof(global::BBGreenTimer.BBGreenTimer), "Beton Brutal Green Timer", "1.0.1", "MiaouZart", null)]
[assembly: MelonGame("", "Beton Brutal")]
[assembly: MelonAdditionalDependencies(new string[] { "BBModMenu" })]
[assembly: Guid("4dc64638-5ffa-4486-a76f-16382adf2135")]
[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")]
namespace BBGreenTimer;
public class BBGreenTimer : MelonMod
{
[HarmonyPatch(typeof(GameUI), "Awake")]
private static class PatchGameUILightAwake
{
[HarmonyPrefix]
private static void HarmonyPatchPrefixGameUi(GameUI __instance)
{
((Component)__instance).gameObject.AddComponent<BBGreenTimerComponent>();
}
}
}
internal class BBGreenTimerComponent : MonoBehaviour
{
private VisualElement _greenTimerRoot;
private bool _enable = true;
private static Color textColor = new Color(0f, 1f, 0.5f, 0.7f);
private static Color textPauseColor = new Color(0.2f, 0.2f, 0.2f, 0.7f);
private float baseFontSize = 30f;
private float baseMarginBottom = 10f;
private GameUI gameUI;
private VisualElement HuDCustomMapVisualElement;
private VisualElement HuDVisualElement;
private ModMenu _modMenu;
private Label _greenTimerLabel;
private float timer = 0f;
private VisualElement currentParent;
private PlayerStats _playerStats;
private VisualElement screenVisualElement;
private string currentMap = "";
public void Start()
{
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Expected O, but got Unknown
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
//IL_007d: Unknown result type (might be due to invalid IL or missing references)
//IL_0089: Unknown result type (might be due to invalid IL or missing references)
//IL_0093: Expected O, but got Unknown
//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
Debug.Log((object)"GreenTimer Loaded Plugin Start");
_greenTimerRoot = new VisualElement();
_greenTimerRoot.style.position = StyleEnum<Position>.op_Implicit((Position)1);
_greenTimerRoot.style.unityTextAlign = StyleEnum<TextAnchor>.op_Implicit((TextAnchor)4);
_greenTimerRoot.name = "GreenTimerRoot";
_greenTimerRoot.transform.position = new Vector3(0f, 0f, 0f);
_greenTimerLabel = new Label();
((TextElement)_greenTimerLabel).text = Extensions.TimeToString(0f, true);
((VisualElement)_greenTimerLabel).style.color = StyleColor.op_Implicit(textColor);
_greenTimerRoot.Add((VisualElement)(object)_greenTimerLabel);
gameUI = GameObject.Find("GameUI").GetComponent<GameUI>();
List<UIScreen> list = typeof(GameUI).GetField("screens", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(gameUI) as List<UIScreen>;
if (list != null)
{
UIScreen? obj = ((IEnumerable<UIScreen>)list).FirstOrDefault((Func<UIScreen, bool>)((UIScreen screen) => screen is HUDScreen));
HUDScreen obj2 = (HUDScreen)(object)((obj is HUDScreen) ? obj : null);
FieldInfo field = typeof(UIScreen).GetField("<Screen>k__BackingField", BindingFlags.Instance | BindingFlags.NonPublic);
UIScreen? obj3 = ((IEnumerable<UIScreen>)list).FirstOrDefault((Func<UIScreen, bool>)((UIScreen screen) => screen is CustomMapHUDScreen));
CustomMapHUDScreen obj4 = (CustomMapHUDScreen)(object)((obj3 is CustomMapHUDScreen) ? obj3 : null);
if (field != null)
{
object? value = field.GetValue(obj2);
VisualElement huDVisualElement = (VisualElement)((value is VisualElement) ? value : null);
HuDVisualElement = huDVisualElement;
VisualElement huDVisualElement2 = HuDVisualElement;
if (huDVisualElement2 != null)
{
huDVisualElement2.Add(_greenTimerRoot);
}
object? value2 = field.GetValue(obj4);
VisualElement huDCustomMapVisualElement = (VisualElement)((value2 is VisualElement) ? value2 : null);
HuDCustomMapVisualElement = huDCustomMapVisualElement;
}
}
_playerStats = Object.FindObjectOfType<PlayerStats>();
ref ModMenu modMenu = ref _modMenu;
UIScreen? obj5 = list?.FirstOrDefault((Func<UIScreen, bool>)((UIScreen screen) => screen is ModMenu));
modMenu = (ModMenu)(object)((obj5 is ModMenu) ? obj5 : null);
if (_modMenu == null)
{
Debug.Log((object)"ModMenu not found");
return;
}
string text = "GreenTimer";
VisualElement val = _modMenu.AddSetting(text);
Slider xSlider = _modMenu.CreateSlider(text, "XPositon", 0f, 100f, 88f, true);
Slider ySlider = _modMenu.CreateSlider(text, "YPosition", 0f, 100f, 8f, true);
Slider scaleSlider = _modMenu.CreateSlider(text, "Scale", 0.1f, 3f, 1f, false);
Action updatePosition = delegate
{
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
_greenTimerRoot.style.top = StyleLength.op_Implicit(Length.Percent(((BaseField<float>)(object)ySlider).value));
_greenTimerRoot.style.left = StyleLength.op_Implicit(Length.Percent(((BaseField<float>)(object)xSlider).value));
DisplayInSetting();
};
Action updateScale = delegate
{
//IL_002a: Unknown result type (might be due to invalid IL or missing references)
float value3 = ((BaseField<float>)(object)scaleSlider).value;
((VisualElement)_greenTimerLabel).style.fontSize = StyleLength.op_Implicit(baseFontSize * value3);
};
INotifyValueChangedExtensions.RegisterValueChangedCallback<float>((INotifyValueChanged<float>)(object)xSlider, (EventCallback<ChangeEvent<float>>)delegate
{
updatePosition();
});
INotifyValueChangedExtensions.RegisterValueChangedCallback<float>((INotifyValueChanged<float>)(object)ySlider, (EventCallback<ChangeEvent<float>>)delegate
{
updatePosition();
});
INotifyValueChangedExtensions.RegisterValueChangedCallback<float>((INotifyValueChanged<float>)(object)scaleSlider, (EventCallback<ChangeEvent<float>>)delegate
{
updateScale();
});
VisualElement val2 = _modMenu.CreateGroup("Position");
VisualElement val3 = _modMenu.CreateWrapper();
val3.Add((VisualElement)(object)_modMenu.CreateLabel("X position"));
val3.Add((VisualElement)(object)xSlider);
VisualElement val4 = _modMenu.CreateWrapper();
val4.Add((VisualElement)(object)_modMenu.CreateLabel("Y position"));
val4.Add((VisualElement)(object)ySlider);
VisualElement val5 = _modMenu.CreateWrapper();
val5.Add((VisualElement)(object)_modMenu.CreateLabel("Scale"));
val5.Add((VisualElement)(object)scaleSlider);
VisualElement val6 = _modMenu.CreateGroup("Control");
VisualElement val7 = _modMenu.CreateWrapper();
val7.Add((VisualElement)(object)_modMenu.CreateLabel("Enable"));
Toggle val8 = _modMenu.CreateToggle(text, "On", _enable);
INotifyValueChangedExtensions.RegisterValueChangedCallback<bool>((INotifyValueChanged<bool>)(object)val8, (EventCallback<ChangeEvent<bool>>)delegate(ChangeEvent<bool> b)
{
_enable = b.newValue;
_greenTimerRoot.visible = _enable;
});
val7.Add((VisualElement)(object)val8);
VisualElement val9 = _modMenu.CreateWrapper();
Button val10 = _modMenu.CreateButton("Reset");
val9.Add((VisualElement)(object)_modMenu.CreateLabel("reset"));
val10.clicked += ResetTimer;
val9.Add((VisualElement)(object)val10);
val2.Add(val3);
val2.Add(val4);
val2.Add(val5);
val6.Add(val9);
val6.Add(val7);
val.Add(val2);
val.Add(val6);
_enable = ((BaseField<bool>)(object)val8).value;
_greenTimerRoot.visible = _enable;
updatePosition();
updateScale();
}
private void DisplayInSetting()
{
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
_modMenu.getRootVisualElement().Add(_greenTimerRoot);
_greenTimerRoot.style.backgroundColor = StyleColor.op_Implicit(Color.white);
}
private void Update()
{
//IL_0153: Unknown result type (might be due to invalid IL or missing references)
//IL_014c: Unknown result type (might be due to invalid IL or missing references)
//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
//IL_0158: Unknown result type (might be due to invalid IL or missing references)
if (!_enable || gameUI.ActiveScreen == null)
{
return;
}
ref VisualElement reference = ref screenVisualElement;
object? obj = typeof(UIScreen).GetField("<Screen>k__BackingField", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(gameUI.ActiveScreen);
reference = (VisualElement)((obj is VisualElement) ? obj : null);
if (screenVisualElement != null && screenVisualElement != currentParent)
{
VisualElement greenTimerRoot = _greenTimerRoot;
if (greenTimerRoot != null)
{
greenTimerRoot.RemoveFromHierarchy();
}
screenVisualElement.Add(_greenTimerRoot);
currentParent = screenVisualElement;
if (_greenTimerRoot != null)
{
_greenTimerRoot.SendToBack();
_greenTimerRoot.style.backgroundColor = StyleColor.op_Implicit(new Color(0f, 0f, 0f, 0f));
}
}
timer += ((!gameUI.player.IsFrozen) ? Time.deltaTime : 0f);
((VisualElement)_greenTimerLabel).style.color = StyleColor.op_Implicit((!gameUI.player.IsFrozen) ? textColor : textPauseColor);
((TextElement)_greenTimerLabel).text = Extensions.TimeToString(timer, true);
string text = LoadCurrentMainStats();
if (!string.IsNullOrEmpty(text) && text != currentMap)
{
if (string.IsNullOrEmpty(currentMap))
{
currentMap = text;
}
SwitchMap();
if (!BBSettings.HasEntry("GreenTimer", currentMap))
{
BBSettings.AddEntry<float>("GreenTimer", currentMap, timer);
}
else
{
BBSettings.SetEntryValue<float>("GreenTimer", currentMap, timer);
}
}
}
private void SaveTime()
{
if (string.IsNullOrEmpty(currentMap))
{
MelonLogger.Msg("No Map");
return;
}
try
{
if (!BBSettings.HasEntry("GreenTimer", currentMap))
{
BBSettings.AddEntry<float>("GreenTimer", currentMap, timer);
}
else
{
BBSettings.SetEntryValue<float>("GreenTimer", currentMap, timer);
}
BBSettings.SavePref();
}
catch (Exception arg)
{
MelonLogger.Error($"Error saving time: {arg}");
}
}
private void SwitchMap()
{
SaveTime();
currentMap = LoadCurrentMainStats();
if (!BBSettings.HasEntry("GreenTimer", currentMap))
{
BBSettings.AddEntry<float>("GreenTimer", currentMap, 0f);
}
timer = BBSettings.GetEntryValue<float>("GreenTimer", currentMap);
}
private void OnApplicationQuit()
{
SaveTime();
}
private void ResetTimer()
{
timer = 0f;
}
public string LoadCurrentMainStats()
{
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
//IL_0034: Unknown result type (might be due to invalid IL or missing references)
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: Expected I4, but got Unknown
if (MapEditor.Instance.mapName != "Untitled")
{
return MapEditor.Instance.mapName;
}
StatsMode currentStatsMode = _playerStats.CurrentStatsMode;
StatsMode val = currentStatsMode;
return (int)val switch
{
0 => "main",
1 => "DLC1",
2 => "birthday",
_ => "",
};
}
}