Skip to content

Commit 8f33aa6

Browse files
committed
fix(natives): fix broken natives and document things, this also fixed vehicle spawner needing an external resource temporarily.
1 parent 734e6cb commit 8f33aa6

10 files changed

Lines changed: 111 additions & 15 deletions

File tree

docs/src/content/docs/getting-started.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,30 @@ vMenu Enhanced is in early alpha. Installation and configuration steps are not f
1111

1212
- A FiveM **Enhanced** server.
1313

14+
## Installation
15+
16+
### Filesystem permissions
17+
18+
vMenu Enhanced writes files into its own resource folder (saved vehicles, outfits, and other
19+
persistent data). FiveM Enhanced blocks resources from writing to disk unless you explicitly
20+
grant permission, so add the following line to your `server.cfg` **before** the line that starts
21+
vMenu Enhanced:
22+
23+
```cfg
24+
add_filesystem_permission vMenu.Enhanced write vMenu.Enhanced
25+
ensure vMenu.Enhanced
26+
```
27+
28+
Both names in that command are resource names: the first is the resource being granted access
29+
(vMenu Enhanced), the second is the resource whose folder it may write to (its own). If you renamed
30+
the resource folder, use your own folder name in both places.
31+
32+
:::danger[Order matters]
33+
The permission must be set before the resource starts. If `ensure vMenu.Enhanced` comes first,
34+
vMenu Enhanced will not be able to save anything and you will see filesystem errors in the server
35+
console.
36+
:::
37+
1438
## Where things stand
1539

1640
Setup instructions, configuration, and permissions documentation will land here as vMenu Enhanced becomes usable.
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
using CitizenFX.Base;
2+
using CitizenFX.FiveM.Client;
3+
4+
namespace vMenu.Enhanced.BrokenNatives;
5+
6+
/// <summary>
7+
/// Natives that are broken in the API get fixed here.
8+
/// </summary>
9+
public static class NativeFixer
10+
{
11+
internal static NativeApi nativeApi = BaseEntrypoint.NativeApi;
12+
13+
/// <summary>
14+
/// Replacement call for <see cref="Native.GetAllVehicleModels" /> because that return type is <pre>byte[]</pre>
15+
/// </summary>
16+
/// <returns></returns>
17+
public static string[] GetAllVehicleModels()
18+
{
19+
nativeApi.ResetContext();
20+
nativeApi.Invoke(3612546629uL, "GetAllVehicleModels");
21+
return nativeApi.GetResObject(0).DeserializeTo<string[]>();
22+
}
23+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<ItemGroup>
3+
<PackageReference Include="CitizenFX.FiveM.Client" />
4+
</ItemGroup>
5+
</Project>

src/Client/vMenu.Enhanced.Menus/VehicleSpawnerMenu.cs

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
using System.Text;
2-
31
using CitizenFX.Base;
42
using CitizenFX.FiveM.Client;
53
using CitizenFX.FiveM.Client.Extensions;
@@ -14,7 +12,7 @@ namespace vMenu.Enhanced.Menus;
1412
/// </summary>
1513
public sealed class VehicleSpawnerMenu
1614
{
17-
15+
internal static NativeApi nativeApi = BaseEntrypoint.NativeApi;
1816

1917

2018
public async Task<Menu> GetMenu()
@@ -26,18 +24,12 @@ public async Task<Menu> GetMenu()
2624
MenuController.MainMenu.AddMenuItem(linkBtn);
2725
MenuController.BindMenuItem(MenuController.MainMenu, menu, linkBtn);
2826

29-
API.Log.Info("Calling something.GetVehicleList now");
30-
var data = API.Exports["something"].Call<string>("GetVehicleList");
27+
var vehicles = BrokenNatives.NativeFixer.GetAllVehicleModels();
3128

32-
// This is broken due to crash: https://github.com/citizenfx/rfc/discussions/328
33-
//var vehicles = System.Text.Json.JsonSerializer.Deserialize<string[]>(data);
3429

35-
API.Log.Info("Got vehicle list data: " + data);
36-
var vehicles = data.Replace("[", "").Replace("]", "").Replace("\"", "").Split(',');
3730

3831
if (vehicles is null)
3932
{
40-
API.Log.Warn("Vehicle list is null");
4133
return menu;
4234
}
4335

@@ -47,10 +39,6 @@ public async Task<Menu> GetMenu()
4739
.OrderBy(vehicle => vehicle)
4840
.GroupBy(vehicle => Native.GetVehicleClassFromName(API.Hash(vehicle)));
4941

50-
API.Log.Info("Vehicle list categorized and cleaned up");
51-
52-
53-
5442
foreach (var cat in vehicleSperCategory)
5543
{
5644
var submenu = new Menu("Class: " + cat.Key.ToString(), "Vehicle Spawner Menu");
@@ -61,8 +49,10 @@ public async Task<Menu> GetMenu()
6149

6250
submenu.OnItemSelect += Submenu_OnItemSelect;
6351
MenuController.AddSubmenu(menu, submenu);
52+
6453
var btn = new MenuItem("Veh Class: " + cat.Key.ToString());
6554
menu.AddMenuItem(btn);
55+
6656
MenuController.BindMenuItem(menu, submenu, btn);
6757
API.Log.Info("Added submenu for vehicle class: {0}", cat.Key.ToString());
6858
}
@@ -73,7 +63,23 @@ public async Task<Menu> GetMenu()
7363

7464
private async void Submenu_OnItemSelect(Menu menu, MenuItem menuItem, int itemIndex)
7565
{
76-
var veh = await API.Vehicles.RequestAndCreate(API.Hash(menuItem.Text), API.Players.Local.Ped!.Position, (int)API.Players.Local.Ped.Heading, true, true, true);
66+
var hash = API.Hash(menuItem.Text);
67+
68+
// Manually checking and requesting model because API.Vehicles.RequestAndCreate uses datetime which is currently broken and crashes the game.
69+
// https://github.com/citizenfx/rfc/discussions/328
70+
if (!Native.IsModelValid(hash))
71+
{
72+
return;
73+
}
74+
75+
Native.RequestModel(hash);
76+
77+
while (!Native.HasModelLoaded(hash))
78+
{
79+
await API.Delay(0);
80+
}
81+
82+
var veh = await API.Vehicles.RequestAndCreate(hash, API.Players.Local.Ped!.Position, (int)API.Players.Local.Ped.Heading, true, true, true);
7783
if (veh is not null)
7884
{
7985
API.Players.Local.Ped.SetPedIntoVehicle(veh!.Handle, -1);

src/Client/vMenu.Enhanced.Menus/vMenu.Enhanced.Menus.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,7 @@
22
<ItemGroup>
33
<PackageReference Include="MenuAPI.FiveM.Enhanced" />
44
</ItemGroup>
5+
<ItemGroup>
6+
<ProjectReference Include="..\vMenu.Enhanced.BrokenNatives\vMenu.Enhanced.BrokenNatives.csproj" />
7+
</ItemGroup>
58
</Project>
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
using CitizenFX.Base;
2+
3+
namespace vMenu.Enhanced.BrokenNatives.Server;
4+
5+
/// <summary>
6+
/// Natives that are broken in the API get fixed here.
7+
/// </summary>
8+
public static class NativeFixer
9+
{
10+
internal static NativeApi nativeApi = BaseEntrypoint.NativeApi;
11+
12+
public static bool SaveResourceFile(string resource, string file, string buffer)
13+
{
14+
nativeApi.ResetContext();
15+
nativeApi.PushArg(resource);
16+
nativeApi.PushArg(file);
17+
nativeApi.PushArg(buffer);
18+
nativeApi.PushArg(-1);
19+
nativeApi.Invoke(2694741627uL, "SaveResourceFile");
20+
return nativeApi.GetResBool(0);
21+
}
22+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<ItemGroup>
3+
<PackageReference Include="CitizenFX.FiveM.Server" />
4+
</ItemGroup>
5+
</Project>

src/Server/vMenu.Enhanced.Core.Server/Placeholder.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,8 @@ public void Initialize()
1313
{
1414
API.Log.Info("Resource Loaded");
1515
//Native.SaveResourceFile()
16+
Native.SetConvar("add_filesystem_permission", "vMenu.Enhanced write vMenu.Enhanced");
17+
18+
BrokenNatives.Server.NativeFixer.SaveResourceFile("vMenu.Enhanced", "test.txt", "Hello world");
1619
}
1720
}

src/Server/vMenu.Enhanced.Core.Server/vMenu.Enhanced.Core.Server.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,7 @@
22
<ItemGroup>
33
<PackageReference Include="CitizenFX.FiveM.Server" />
44
</ItemGroup>
5+
<ItemGroup>
6+
<ProjectReference Include="..\vMenu.Enhanced.BrokenNatives.Server\vMenu.Enhanced.BrokenNatives.Server.csproj" />
7+
</ItemGroup>
58
</Project>

vMenu.Enhanced.slnx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
</Folder>
1414
<Folder Name="/src/Client/">
1515
<File Path="src/Client/Directory.Build.props" />
16+
<Project Path="src/Client/vMenu.Enhanced.BrokenNatives/vMenu.Enhanced.BrokenNatives.csproj" />
1617
<Project Path="src/Client/vMenu.Enhanced.Configuration/vMenu.Enhanced.Configuration.csproj" />
1718
<Project Path="src/Client/vMenu.Enhanced.NoClip/vMenu.Enhanced.NoClip.csproj" />
1819
<Project Path="src/Client/vMenu.Enhanced.Core/vMenu.Enhanced.Core.csproj" />
@@ -21,6 +22,7 @@
2122
</Folder>
2223
<Folder Name="/src/Server/">
2324
<File Path="src/Server/Directory.Build.props" />
25+
<Project Path="src/Server/vMenu.Enhanced.BrokenNatives.Server/vMenu.Enhanced.BrokenNatives.Server.csproj" />
2426
<Project Path="src/Server/vMenu.Enhanced.Configuration.Server/vMenu.Enhanced.Configuration.Server.csproj" />
2527
<Project Path="src/Server/vMenu.Enhanced.Core.Server/vMenu.Enhanced.Core.Server.csproj" />
2628
<Project Path="src/Server/vMenu.Enhanced.Permissions.Server/vMenu.Enhanced.Permissions.Server.csproj" />

0 commit comments

Comments
 (0)