Skip to content

Commit c5f87e0

Browse files
Merge pull request #3 from CSGALS/default-menu-compat
Added more compatibility plugins
2 parents e7bef18 + a8faddc commit c5f87e0

7 files changed

Lines changed: 278 additions & 0 deletions

File tree

CSSUniversalMenuAPI.sln

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProofOfConcepts", "tests\Pr
2525
EndProject
2626
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UniversalMenu.Compat.MenuManagerApi", "src\UniversalMenu.Compat.MenuManagerApi\UniversalMenu.Compat.MenuManagerApi.csproj", "{44AAF649-62D6-1CD8-3F16-028F4D262BE6}"
2727
EndProject
28+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UniversalMenu.Compat.ScreenMenuAPI", "src\UniversalMenu.Compat.ScreenMenuAPI\UniversalMenu.Compat.ScreenMenuAPI.csproj", "{B5AB3AB6-5BB6-0154-27DF-61D9EE587806}"
29+
EndProject
2830
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UniversalMenu.Driver.ScreenMenuAPI", "src\UniversalMenu.Driver.ScreenMenuAPI\UniversalMenu.Driver.ScreenMenuAPI.csproj", "{E2FD83DD-D7EA-97CA-B6F4-DE2F92E5A00F}"
2931
EndProject
3032
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "GitHub Actions", "GitHub Actions", "{02EA681E-C7D8-13C7-8484-4AC65E1B71E8}"
@@ -37,6 +39,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "GitHub Actions", "GitHub Ac
3739
.github\shared.yml = .github\shared.yml
3840
EndProjectSection
3941
EndProject
42+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UniversalMenu.Compat.CSSharp", "src\UniversalMenu.Compat.CSSharp\UniversalMenu.Compat.CSSharp.csproj", "{EF2866D7-C411-42ED-B5E0-DCE79CCFCA09}"
43+
EndProject
44+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UniversalMenu.Compat.CSSharp.Shared", "src\UniversalMenu.Compat.CSSharp.Shared\UniversalMenu.Compat.CSSharp.Shared.csproj", "{6ADB7AC3-E7F1-4BAB-A323-633932EBB322}"
45+
EndProject
4046
Global
4147
GlobalSection(SolutionConfigurationPlatforms) = preSolution
4248
Debug|Any CPU = Debug|Any CPU
@@ -59,10 +65,22 @@ Global
5965
{44AAF649-62D6-1CD8-3F16-028F4D262BE6}.Debug|Any CPU.Build.0 = Debug|Any CPU
6066
{44AAF649-62D6-1CD8-3F16-028F4D262BE6}.Release|Any CPU.ActiveCfg = Release|Any CPU
6167
{44AAF649-62D6-1CD8-3F16-028F4D262BE6}.Release|Any CPU.Build.0 = Release|Any CPU
68+
{B5AB3AB6-5BB6-0154-27DF-61D9EE587806}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
69+
{B5AB3AB6-5BB6-0154-27DF-61D9EE587806}.Debug|Any CPU.Build.0 = Debug|Any CPU
70+
{B5AB3AB6-5BB6-0154-27DF-61D9EE587806}.Release|Any CPU.ActiveCfg = Release|Any CPU
71+
{B5AB3AB6-5BB6-0154-27DF-61D9EE587806}.Release|Any CPU.Build.0 = Release|Any CPU
6272
{E2FD83DD-D7EA-97CA-B6F4-DE2F92E5A00F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
6373
{E2FD83DD-D7EA-97CA-B6F4-DE2F92E5A00F}.Debug|Any CPU.Build.0 = Debug|Any CPU
6474
{E2FD83DD-D7EA-97CA-B6F4-DE2F92E5A00F}.Release|Any CPU.ActiveCfg = Release|Any CPU
6575
{E2FD83DD-D7EA-97CA-B6F4-DE2F92E5A00F}.Release|Any CPU.Build.0 = Release|Any CPU
76+
{EF2866D7-C411-42ED-B5E0-DCE79CCFCA09}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
77+
{EF2866D7-C411-42ED-B5E0-DCE79CCFCA09}.Debug|Any CPU.Build.0 = Debug|Any CPU
78+
{EF2866D7-C411-42ED-B5E0-DCE79CCFCA09}.Release|Any CPU.ActiveCfg = Release|Any CPU
79+
{EF2866D7-C411-42ED-B5E0-DCE79CCFCA09}.Release|Any CPU.Build.0 = Release|Any CPU
80+
{6ADB7AC3-E7F1-4BAB-A323-633932EBB322}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
81+
{6ADB7AC3-E7F1-4BAB-A323-633932EBB322}.Debug|Any CPU.Build.0 = Debug|Any CPU
82+
{6ADB7AC3-E7F1-4BAB-A323-633932EBB322}.Release|Any CPU.ActiveCfg = Release|Any CPU
83+
{6ADB7AC3-E7F1-4BAB-A323-633932EBB322}.Release|Any CPU.Build.0 = Release|Any CPU
6684
EndGlobalSection
6785
GlobalSection(SolutionProperties) = preSolution
6886
HideSolutionNode = FALSE

package.sh

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,20 @@ mkdir -p "$dst_plugins/UniversalMenu.Compat.MenuManagerApi"
1616
src="./src/UniversalMenu.Compat.MenuManagerApi/bin/Release/net8.0/publish"
1717
cp -r "$src/." "$dst_plugins/UniversalMenu.Compat.MenuManagerApi/"
1818

19+
# package UniversalMenu.Compat.CSSharp
20+
mkdir -p "$dst_plugins/UniversalMenu.Compat.CSSharp"
21+
src="./src/UniversalMenu.Compat.CSSharp/bin/Release/net8.0/publish"
22+
cp -r "$src/." "$dst_plugins/UniversalMenu.Compat.CSSharp/"
23+
# shared part: allows modified methods to load the 0Harmony.dll dependency
24+
mkdir -p "$dst_shared/UniversalMenu.Compat.CSSharp.Shared"
25+
src="./src/UniversalMenu.Compat.CSSharp.Shared/bin/Release/net8.0/publish"
26+
cp -r "$src/." "$dst_shared/UniversalMenu.Compat.CSSharp.Shared/"
27+
28+
# package UniversalMenu.Compat.ScreenMenuAPI # this isn't implemented yet
29+
#mkdir -p "$dst_plugins/UniversalMenu.Compat.ScreenMenuAPI"
30+
#src="./src/UniversalMenu.Compat.ScreenMenuAPI/bin/Release/net8.0/publish"
31+
#cp -r "$src/." "$dst_shared/UniversalMenu.Compat.ScreenMenuAPI/"
32+
1933
# zip CSSUniversalMenuAPI.zip
2034
pushd "$dst"
2135
7z a ../CSSUniversalMenuAPI.zip ./
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
5+
using AngleSharp.Dom;
6+
using AngleSharp.Html.Parser;
7+
8+
using CounterStrikeSharp.API.Core;
9+
using CounterStrikeSharp.API.Modules.Menu;
10+
11+
using CS2ScreenMenuAPI;
12+
13+
using CSSUniversalMenuAPI;
14+
using CSSUniversalMenuAPI.Extensions;
15+
16+
using HarmonyLib;
17+
18+
using IUniversalMenu = CSSUniversalMenuAPI.IMenu;
19+
20+
namespace UniversalMenu.Compat.CSSharp;
21+
22+
public static class CSSharpCompatPluginShared
23+
{
24+
private static Harmony? Harmony { get; set; }
25+
private static Dictionary<nint, IUniversalMenu> ActiveMenus { get; } = new();
26+
27+
public static void Patch()
28+
{
29+
Harmony = new Harmony("com.universalmenu.compat.cssharp");
30+
31+
{
32+
var original = AccessTools.Method(typeof(MenuManager), nameof(MenuManager.OpenCenterHtmlMenu));
33+
var pre = SymbolExtensions.GetMethodInfo(() => MenuManager_OpenCenterHtmlMenu(null!, null!, null!));
34+
Harmony.Patch(original, prefix: new HarmonyMethod(pre));
35+
}
36+
37+
{
38+
var original = AccessTools.Method(typeof(MenuManager), nameof(MenuManager.OpenChatMenu));
39+
var pre = SymbolExtensions.GetMethodInfo(() => MenuManager_OpenChatMenu(null!, null!));
40+
Harmony.Patch(original, prefix: new HarmonyMethod(pre));
41+
}
42+
43+
{
44+
var original = AccessTools.Method(typeof(MenuManager), nameof(MenuManager.OpenConsoleMenu));
45+
var pre = SymbolExtensions.GetMethodInfo(() => MenuManager_OpenConsoleMenu(null!, null!));
46+
Harmony.Patch(original, prefix: new HarmonyMethod(pre));
47+
}
48+
49+
{
50+
var original = AccessTools.Method(typeof(MenuManager), nameof(MenuManager.CloseActiveMenu));
51+
var pre = SymbolExtensions.GetMethodInfo(() => MenuManager_CloseActiveMenu(null!));
52+
Harmony.Patch(original, prefix: new HarmonyMethod(pre));
53+
}
54+
}
55+
56+
public static void Unpatch()
57+
{
58+
Harmony?.UnpatchAll();
59+
}
60+
61+
public static void PlayerDisconnected(CCSPlayerController player)
62+
{
63+
ActiveMenus.Remove(player.Handle);
64+
}
65+
66+
public static bool BaseMenu_Open(BasePlugin? plugin, CCSPlayerController player, BaseMenu menu)
67+
{
68+
// this API assumes there may only be 1 menu at a time, so tell the implementation
69+
// that this menu is expected to be closed
70+
if (ActiveMenus.TryGetValue(player.Handle, out var activeMenu))
71+
{
72+
ActiveMenus.Remove(player.Handle);
73+
activeMenu.Close();
74+
}
75+
76+
var api = IMenuAPI.PluginCapability.Get();
77+
78+
if (api is null) // fall back to builtin menu
79+
return true;
80+
81+
var newMenu = api.CreateMenu(player);
82+
newMenu.PlayerCanClose = menu.ExitButton;
83+
84+
var useHtml = false;
85+
if (newMenu is IHtmlSupportMenuExtension htmlMenu)
86+
htmlMenu.UseHtml = useHtml = true;
87+
88+
if (useHtml)
89+
newMenu.Title = menu.Title;
90+
else
91+
newMenu.Title = StripHtml(menu.Title);
92+
93+
foreach (var item in menu.MenuOptions)
94+
{
95+
var newItem = newMenu.CreateItem();
96+
newItem.Enabled = !item.Disabled;
97+
98+
if (useHtml)
99+
newItem.Title = item.Text;
100+
else
101+
newItem.Title = StripHtml(item.Text);
102+
103+
if (item.OnSelect is not null)
104+
newItem.Selected += (selectedItem) =>
105+
{
106+
item.OnSelect(player, item);
107+
if (menu.PostSelectAction == PostSelectAction.Close)
108+
{
109+
if (ActiveMenus.TryGetValue(player.Handle, out var activeMenu) && activeMenu == newMenu)
110+
ActiveMenus.Remove(player.Handle);
111+
newMenu.Close();
112+
}
113+
};
114+
}
115+
116+
ActiveMenus[player.Handle] = newMenu;
117+
newMenu.Display();
118+
return false;
119+
}
120+
121+
public static bool MenuManager_CloseActiveMenu(CCSPlayerController player)
122+
{
123+
Console.WriteLine($"Close active menu 1");
124+
if (ActiveMenus.TryGetValue(player.Handle, out var activeMenu))
125+
{
126+
Console.WriteLine($"Close active menu 2");
127+
ActiveMenus.Remove(player.Handle);
128+
activeMenu.Close();
129+
}
130+
return true;
131+
}
132+
133+
public static bool MenuManager_OpenCenterHtmlMenu(BasePlugin plugin, CCSPlayerController player, CenterHtmlMenu menu)
134+
{
135+
return BaseMenu_Open(plugin, player, menu);
136+
}
137+
138+
public static bool MenuManager_OpenChatMenu(CCSPlayerController player, ChatMenu menu)
139+
{
140+
return BaseMenu_Open(null, player, menu);
141+
}
142+
143+
public static bool MenuManager_OpenConsoleMenu(CCSPlayerController player, ConsoleMenu menu)
144+
{
145+
return BaseMenu_Open(null, player, menu);
146+
}
147+
148+
private static readonly HtmlParser HtmlParser = new(new HtmlParserOptions() { IsStrictMode = false });
149+
private static string StripHtml(string input)
150+
{
151+
var doc = HtmlParser.ParseFragment(input, null!);
152+
return string.Join(string.Empty, doc.Select(x => x.Text()));
153+
}
154+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<RootNamespace>UniversalMenu.Compat.CSSharp</RootNamespace>
5+
<OutputType>Library</OutputType>
6+
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
7+
</PropertyGroup>
8+
9+
<ItemGroup>
10+
<ProjectReference Include="..\CSSUniversalMenuAPI\CSSUniversalMenuAPI.csproj">
11+
<Private>False</Private>
12+
<CopyLocalSatelliteAssemblies>False</CopyLocalSatelliteAssemblies>
13+
</ProjectReference>
14+
<PackageReference Include="AngleSharp" Version="1.2.0" />
15+
16+
<PackageReference Include="CS2ScreenMenuAPI" Version="3.0.4" ExcludeAssets="runtime" />
17+
<PackageReference Include="Lib.Harmony" Version="2.3.6" />
18+
</ItemGroup>
19+
20+
</Project>
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
using CounterStrikeSharp.API.Core;
2+
using CounterStrikeSharp.API.Core.Attributes.Registration;
3+
4+
namespace UniversalMenu.Compat.CSSharp;
5+
6+
public class CSSharpCompatPlugin : BasePlugin
7+
{
8+
public override string ModuleName => "UniversalMenu.Compat.CSSharp";
9+
public override string ModuleVersion => Verlite.Version.Full;
10+
11+
public override void Load(bool hotReload)
12+
{
13+
CSSharpCompatPluginShared.Patch();
14+
}
15+
16+
public override void Unload(bool hotReload)
17+
{
18+
CSSharpCompatPluginShared.Unpatch();
19+
}
20+
21+
[GameEventHandler(HookMode.Pre)]
22+
public HookResult OnPlayerDisconnect(EventPlayerDisconnect e, GameEventInfo info)
23+
{
24+
if (e.Userid is null)
25+
return HookResult.Continue;
26+
27+
CSSharpCompatPluginShared.PlayerDisconnected(e.Userid);
28+
return HookResult.Continue;
29+
}
30+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<RootNamespace>UniversalMenu.Compat.CSSharp</RootNamespace>
5+
<OutputType>Library</OutputType>
6+
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
7+
</PropertyGroup>
8+
9+
<ItemGroup>
10+
<ProjectReference Include="..\CSSUniversalMenuAPI\CSSUniversalMenuAPI.csproj">
11+
<Private>False</Private>
12+
<CopyLocalSatelliteAssemblies>False</CopyLocalSatelliteAssemblies>
13+
</ProjectReference>
14+
15+
<ProjectReference Include="..\UniversalMenu.Compat.CSSharp.Shared\UniversalMenu.Compat.CSSharp.Shared.csproj">
16+
<Private>False</Private>
17+
<CopyLocalSatelliteAssemblies>False</CopyLocalSatelliteAssemblies>
18+
<ExcludeAssets>runtime</ExcludeAssets>
19+
</ProjectReference>
20+
21+
<PackageReference Include="CS2ScreenMenuAPI" Version="3.0.4" ExcludeAssets="runtime" />
22+
</ItemGroup>
23+
24+
</Project>
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<RootNamespace>UniversalMenu.Compat.ScreenMenuAPI</RootNamespace>
5+
<OutputType>Library</OutputType>
6+
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
7+
</PropertyGroup>
8+
9+
<ItemGroup>
10+
<ProjectReference Include="..\CSSUniversalMenuAPI\CSSUniversalMenuAPI.csproj">
11+
<Private>False</Private>
12+
<CopyLocalSatelliteAssemblies>False</CopyLocalSatelliteAssemblies>
13+
</ProjectReference>
14+
15+
<PackageReference Include="CS2ScreenMenuAPI" Version="3.0.4" ExcludeAssets="runtime" />
16+
</ItemGroup>
17+
18+
</Project>

0 commit comments

Comments
 (0)