Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions src/CSSUniversalMenuAPI/IMenuAPI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
using System.Threading;

using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Core.Capabilities;

namespace CSSUniversalMenuAPI;

Expand Down Expand Up @@ -38,9 +37,4 @@ public interface IMenuAPI
/// <param name="player">The player of which to query.</param>
/// <returns>Whether the player has an active menu on their screen.</returns>
bool IsMenuOpen(CCSPlayerController player);

/// <summary>
/// Standard helper to get get or provide this implementation
/// </summary>
static readonly PluginCapability<IMenuAPI> PluginCapability = new("universalmenuapi");
}
82 changes: 82 additions & 0 deletions src/CSSUniversalMenuAPI/UniversalMenu.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Text.Json;
using System.Threading;

using CounterStrikeSharp.API.Core;

namespace CSSUniversalMenuAPI;

/// <summary>
/// Because menus may want access to other drivers, and PluginCapability&lt;&gt; is not expressive enough,
/// this helper class is included with the interface to aid in constructing and
/// </summary>
public static class UniversalMenu
{
private static string? DefaultDriverDesired { get; }
private static string? DefaultDriverName { get; set; }
public static IMenuAPI? DefaultDriver { get; private set; }

private static Dictionary<string, IMenuAPI> RegisteredDrivers { get; } = new();
public static IReadOnlyDictionary<string, IMenuAPI> Drivers => RegisteredDrivers;
public static event EventHandler? DriversChanged;

static UniversalMenu()
{
var configDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) ?? Environment.CurrentDirectory;
var configPath = Path.Join(configDir, "config.json");

if (!File.Exists(configPath))
{
Console.WriteLine("UniversalMenu: No default driver configured, will use first registered driver");
return;
}

var contents = File.ReadAllText(configPath);
var doc = JsonDocument.Parse(contents);
DefaultDriverDesired = doc.RootElement.GetProperty("driver").GetString();

Console.WriteLine($"UniversalMenu: Desired default driver: {DefaultDriverDesired}");
}

public static void RegisterDriver(string name, IMenuAPI driver)
{
if (!RegisteredDrivers.TryAdd(name, driver))
throw new InvalidOperationException($"RegisterDriver(): Conflicting named drivers configured: {name}");

if (DefaultDriverDesired is null || name == DefaultDriverDesired)
{
if (DefaultDriver is not null)
throw new InvalidOperationException($"RegisterDriver(): Conflicting default drivers configured: {name} and {DefaultDriverName}");
DefaultDriver = driver;
DefaultDriverName = name;
}
DriversChanged?.Invoke(null, EventArgs.Empty);
}

public static void UnregisterDriver(string name)
{
if (RegisteredDrivers.Remove(name, out var driver) && driver == DefaultDriver)
{
DefaultDriver = null;
DefaultDriverName = null;
}
DriversChanged?.Invoke(null, EventArgs.Empty);
}

public static IMenu CreateMenu(CCSPlayerController player, CancellationToken ct = default)
{
if (DefaultDriver is null)
throw new InvalidOperationException("No default driver has been registered. Do you have a driver installed and/or configured?");
return DefaultDriver.CreateMenu(player, ct);
}

public static IMenu CreateMenu(IMenu parent, CancellationToken ct = default)
{
if (DefaultDriver is null)
throw new InvalidOperationException("No default driver has been registered. Do you have a driver installed and/or configured?");
return DefaultDriver.CreateMenu(parent, ct);
}
}
2 changes: 1 addition & 1 deletion src/UniversalMenu.Compat.CSSharp/CSSharpCompatPlugin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ public static bool BaseMenu_Open(BasePlugin? plugin, CCSPlayerController player,
activeMenu.Close();
}

var api = IMenuAPI.PluginCapability.Get();
var api = CSSUniversalMenuAPI.UniversalMenu.DefaultDriver;

if (api is null) // fall back to builtin menu
return true;
Expand Down
4 changes: 1 addition & 3 deletions src/UniversalMenu.Compat.MenuManagerApi/MenuManagerCompat.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,7 @@ public override void Load(bool hotReload)
if (Instance is not null)
return Instance;

var universalAPI = IMenuAPI.PluginCapability.Get()
?? throw new Exception("Unable to find CSSUniversalAPI supporting menu or adapter");
Instance = new MenuManagerTranslator(this, universalAPI);
Instance = new MenuManagerTranslator(this);

return Instance;
});
Expand Down
10 changes: 3 additions & 7 deletions src/UniversalMenu.Compat.MenuManagerApi/MenuManagerTranslator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Modules.Menu;

using CSSUniversalMenuAPI;
using CSSUniversalMenuAPI.Extensions;

using ICssMenu = CounterStrikeSharp.API.Modules.Menu.IMenu;
Expand All @@ -22,11 +21,9 @@ namespace UniversalMenu.Compat.MenuManagerApi;
public sealed class MenuManagerTranslator : IMenuManagerAPI
{
public MenuManagerCompat Plugin { get; }
public IMenuAPI UniversalAPI { get; }
public MenuManagerTranslator(MenuManagerCompat plugin, IMenuAPI universalAPI)
public MenuManagerTranslator(MenuManagerCompat plugin)
{
Plugin = plugin;
UniversalAPI = universalAPI;
}

internal class PlayerState
Expand Down Expand Up @@ -69,7 +66,7 @@ MenuManagerMenuType IMenuManagerAPI.GetMenuType(CCSPlayerController player)

bool IMenuManagerAPI.HasOpenedMenu(CCSPlayerController player)
{
return UniversalAPI.IsMenuOpen(player);
return CSSUniversalMenuAPI.UniversalMenu.DefaultDriver?.IsMenuOpen(player) ?? false;
}

ICssMenu IMenuManagerAPI.NewMenu(string title, Action<CCSPlayerController> back_action)
Expand All @@ -87,7 +84,6 @@ internal sealed class MenuInstanceTranslator : ICssMenu
{
public string Title { get; set; }
public MenuManagerTranslator Translator { get; }
public IMenuAPI UniversalAPI => Translator.UniversalAPI;
public bool ExitButton { get; set; }

public List<ChatMenuOption> MenuOptions { get; } = new();
Expand Down Expand Up @@ -130,7 +126,7 @@ public void Open(CCSPlayerController player)
return;
}

menu = PlayerMenus[player.SteamID] = UniversalAPI.CreateMenu(player);
menu = PlayerMenus[player.SteamID] = CSSUniversalMenuAPI.UniversalMenu.CreateMenu(player);
menu.Title = Title;
menu.PlayerCanClose = true;// ExitButton;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ namespace UniversalMenu.ScreenMenuAPIAdapter;
[MinimumApiVersion(314)]
public class ScreenMenuAPIDriverPlugin : BasePlugin
{
public override string ModuleName => "UniversalMenu.Driver.ScreenMenuAPI";
public override string ModuleName => "UniversalMenu.DefaultDriver.ScreenMenuAPI";
public override string ModuleDescription => "Implement CSSUniversalMenuAPI via ScreenMenuAPI";
public override string ModuleVersion => Verlite.Version.Full;

Expand All @@ -24,16 +24,14 @@ public override void Load(bool hotReload)
{
Cts = new CancellationTokenSource();

Capabilities.RegisterPluginCapability(IMenuAPI.PluginCapability, () =>
{
DriverInstance ??= new ScreenMenuApiDriver(this);
return DriverInstance;
});
DriverInstance = new ScreenMenuApiDriver(this);
CSSUniversalMenuAPI.UniversalMenu.RegisterDriver("ScreenMenuAPI", DriverInstance);
}

public override void Unload(bool hotReload)
{
Cts.Cancel();
CSSUniversalMenuAPI.UniversalMenu.UnregisterDriver("ScreenMenuAPI");
}

[ConsoleCommand("css_0"), ConsoleCommand("css_1"), ConsoleCommand("css_2"), ConsoleCommand("css_3"), ConsoleCommand("css_4")]
Expand Down