Skip to content

Commit 0df96a4

Browse files
TomGrobbeRickyB505
andcommitted
Supplemental permissions pilot (#619)
* feat/fix: addon permissions/updating outdated function (#610) * feat/fix: addon permissions/updating outdated function added individual permissions to addon vehicles/weapons/peds, and added a whitelist to regular vehicles/ped. changed (uint)GetHashKey() to Game.GenerateHashASCII() for better optimization * fix: updated what was requested * fix: typo * fix: fixed what needed changing * fix: fixed controller controls and permissions for weapons (#613) * New features and fixes (#614) * vehicle spawning ratelimit * fix: move setting the vehicle speed inside where we check if they spawn inside * feat: add command "vMenu:DV" * feat: add back smooth time transitions * fix: fixes server sided permissions so it checks the parent permissions * fix: disable post build command on non windows machines * fix: Changes and fixes requested --------- Co-authored-by: Ricky Merc <65817116+RickyB505@users.noreply.github.com>
1 parent dca2473 commit 0df96a4

24 files changed

Lines changed: 962 additions & 322 deletions

SharedClasses/ConfigManager.cs

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,10 @@ public enum Setting
3434
vmenu_disable_entity_outlines_tool,
3535
vmenu_disable_player_stats_setup,
3636

37-
// Vehicle Chameleon Colours
37+
// Vehicle Settings
3838
vmenu_using_chameleon_colours,
39+
vmenu_vehicle_spawn_delay,
40+
vmenu_delete_vehicle_distance,
3941

4042
// Prevent Extras Abuse
4143
vmenu_prevent_extras_when_damaged,
@@ -61,6 +63,7 @@ public enum Setting
6163
vmenu_vehicle_blackout_enabled,
6264
vmenu_weather_change_duration,
6365
vmenu_enable_snow,
66+
vmenu_smooth_time_transitions,
6467

6568
// Time settings
6669
vmenu_enable_time_sync,
@@ -92,12 +95,12 @@ public static bool GetSettingsBool(Setting setting)
9295
/// </summary>
9396
/// <param name="setting"></param>
9497
/// <returns></returns>
95-
public static int GetSettingsInt(Setting setting)
98+
public static int GetSettingsInt(Setting setting, int defaultValue = -1)
9699
{
97-
var convarInt = GetConvarInt(setting.ToString(), -1);
98-
if (convarInt == -1)
100+
var convarInt = GetConvarInt(setting.ToString(), defaultValue);
101+
if (convarInt == defaultValue)
99102
{
100-
if (int.TryParse(GetConvar(setting.ToString(), "-1"), out var convarIntAlt))
103+
if (int.TryParse(GetConvar(setting.ToString(), defaultValue.ToString()), out var convarIntAlt))
101104
{
102105
return convarIntAlt;
103106
}
@@ -110,13 +113,13 @@ public static int GetSettingsInt(Setting setting)
110113
/// </summary>
111114
/// <param name="setting"></param>
112115
/// <returns></returns>
113-
public static float GetSettingsFloat(Setting setting)
116+
public static float GetSettingsFloat(Setting setting, float defaultValue = -1f)
114117
{
115-
if (float.TryParse(GetConvar(setting.ToString(), "-1.0"), out var result))
118+
if (float.TryParse(GetConvar(setting.ToString(), defaultValue.ToString()), out var result))
116119
{
117120
return result;
118121
}
119-
return -1f;
122+
return defaultValue;
120123
}
121124

122125
/// <summary>

SharedClasses/PermissionsManager.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ public enum Permission
113113
#region vehicle spawner
114114
VSMenu,
115115
VSAll,
116+
VSBypassRateLimit,
116117
VSDisableReplacePrevious,
117118
VSSpawnByName,
118119
VSAddon,
@@ -481,8 +482,7 @@ private static bool IsAllowedServer(Permission permission, string playerHandle)
481482
{
482483
return false;
483484
}
484-
485-
return IsPlayerAceAllowed(playerHandle, GetAceName(permission));
485+
return GetPermissionAndParentPermissions(permission).Any(p => IsPlayerAceAllowed(playerHandle, GetAceName(p)));
486486
}
487487
#endif
488488

Lines changed: 240 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,240 @@
1+
using System;
2+
3+
using System.Collections.Generic;
4+
using System.Linq;
5+
6+
using CitizenFX.Core;
7+
8+
using static CitizenFX.Core.Native.API;
9+
using CitizenFX.Core.Native;
10+
11+
namespace vMenuShared
12+
{
13+
public static class SupplementaryPermissionManager
14+
{
15+
public static List<string> Permission = new()
16+
{
17+
"VWAll",
18+
"PWAll",
19+
"WWAll",
20+
};
21+
22+
public static Dictionary<string, bool> Permissions { get; private set; } = new Dictionary<string, bool>();
23+
public static bool ArePermissionsSetup { get; set; } = false;
24+
25+
26+
#if SERVER
27+
/// <summary>
28+
/// Public function to check if a permission is allowed.
29+
/// </summary>
30+
/// <param name="permission"></param>
31+
/// <param name="source"></param>
32+
/// <returns></returns>
33+
public static bool IsAllowed(string permission, Player source) => IsAllowedServer(permission, source);
34+
35+
/// <summary>
36+
/// Public function to check if a permission is allowed.
37+
/// </summary>
38+
/// <param name="permission"></param>
39+
/// <param name="playerHandle"></param>
40+
/// <returns></returns>
41+
public static bool IsAllowed(string permission, string playerHandle) => IsAllowedServer(permission, playerHandle);
42+
#endif
43+
44+
#if CLIENT
45+
/// <summary>
46+
/// Public function to check if a permission is allowed.
47+
/// </summary>
48+
/// <param name="permission"></param>
49+
/// <param name="checkAnyway">if true, then the permissions will be checked even if they aren't setup yet.</param>
50+
/// <returns></returns>
51+
public static bool IsAllowed(string permission, bool checkAnyway = false) => IsAllowedClient(permission, checkAnyway);
52+
53+
private static readonly Dictionary<string, bool> allowedPerms = new();
54+
/// <summary>
55+
/// Private function that handles client side permission requests.
56+
/// </summary>
57+
/// <param name="permission"></param>
58+
/// <returns></returns>
59+
private static bool IsAllowedClient(string permission, bool checkAnyway)
60+
{
61+
if (ArePermissionsSetup || checkAnyway)
62+
{
63+
if (allowedPerms.ContainsKey(permission) && allowedPerms[permission])
64+
{
65+
return true;
66+
}
67+
else if (!allowedPerms.ContainsKey(permission))
68+
{
69+
allowedPerms[permission] = false;
70+
}
71+
72+
// Get a list of all permissions that are (parents) of the current permission, including the current permission.
73+
var permissionsToCheck = GetPermissionAndParentPermissions(permission);
74+
75+
// Check if any of those permissions is allowed, if so, return true.
76+
if (permissionsToCheck.Any(p => Permissions.ContainsKey(p) && Permissions[p]))
77+
{
78+
allowedPerms[permission] = true;
79+
return true;
80+
}
81+
}
82+
switch (permission.Substring(0, 2))
83+
{
84+
case "VW":
85+
allowedPerms[permission] = PermissionsManager.IsAllowed(PermissionsManager.Permission.VSAll);
86+
return PermissionsManager.IsAllowed(PermissionsManager.Permission.VSAll);
87+
case "PW":
88+
allowedPerms[permission] = PermissionsManager.IsAllowed(PermissionsManager.Permission.PAAll);
89+
return PermissionsManager.IsAllowed(PermissionsManager.Permission.PAAll);
90+
case "WW":
91+
allowedPerms[permission] = PermissionsManager.IsAllowed(PermissionsManager.Permission.WPAll);
92+
return PermissionsManager.IsAllowed(PermissionsManager.Permission.WPAll);
93+
}
94+
return false;
95+
}
96+
#endif
97+
#if SERVER
98+
/// <summary>
99+
/// Checks if the player is allowed that specific permission.
100+
/// </summary>
101+
/// <param name="permission"></param>
102+
/// <param name="source"></param>
103+
/// <returns></returns>
104+
private static bool IsAllowedServer(string permission, Player source)
105+
{
106+
if (source == null)
107+
{
108+
return false;
109+
}
110+
111+
return IsAllowedServer(permission, source.Handle);
112+
}
113+
114+
/// <summary>
115+
/// Checks if the player is allowed that specific permission.
116+
/// </summary>
117+
/// <param name="permission"></param>
118+
/// <param name="playerHandle"></param>
119+
/// <returns></returns>
120+
private static bool IsAllowedServer(string permission, string playerHandle)
121+
{
122+
if (!DoesPlayerExist(playerHandle))
123+
{
124+
return false;
125+
}
126+
127+
return GetPermissionAndParentPermissions(permission).Any(p => IsPlayerAceAllowed(playerHandle, GetAceName(p)));
128+
}
129+
#endif
130+
131+
private static readonly Dictionary<string, List<string>> parentPermissions = new();
132+
133+
/// <summary>
134+
/// Gets the current permission and all parent permissions.
135+
/// </summary>
136+
/// <param name="permission"></param>
137+
/// <returns></returns>
138+
public static List<string> GetPermissionAndParentPermissions(string permission)
139+
{
140+
if (parentPermissions.ContainsKey(permission))
141+
{
142+
return parentPermissions[permission];
143+
}
144+
else
145+
{
146+
var list = new List<string>() { "Everything", permission };
147+
148+
// if the first 2 characters are both uppercase
149+
if (permission.Substring(0, 2).ToUpper() == permission.Substring(0, 2))
150+
{
151+
if (permission.Substring(2) is not "All")
152+
{
153+
list.AddRange(Permission.Where(a => a.ToString() == permission.Substring(0, 2) + "All"));
154+
}
155+
}
156+
//else // it's one of the .Everything, .DontKickMe, DontBanMe, NoClip, Staff, etc perms that are not menu specific.
157+
//{
158+
// // do nothing
159+
//}
160+
parentPermissions[permission] = list;
161+
return list;
162+
}
163+
}
164+
165+
#if SERVER
166+
167+
168+
/// <summary>
169+
/// Sets the permissions for a specific player (checks server side, sends event to client side).
170+
/// </summary>
171+
/// <param name="player"></param>
172+
public static void SetPermissionsForPlayer([FromSource] Player player)
173+
{
174+
if (player == null)
175+
{
176+
return;
177+
}
178+
179+
var perms = new Dictionary<string, bool>();
180+
181+
// Loop through all permissions and check if they're allowed.
182+
foreach (string permission in Permission)
183+
{
184+
if (!perms.ContainsKey(permission))
185+
{
186+
perms.Add(permission, IsAllowed(permission, player)); // triggers IsAllowedServer
187+
}
188+
}
189+
// Send the permissions to the client.
190+
player.TriggerEvent("vMenu:SetSupplementaryPermissions", Newtonsoft.Json.JsonConvert.SerializeObject(perms));
191+
}
192+
#endif
193+
#if CLIENT
194+
/// <summary>
195+
/// Sets the permission (client side event handler).
196+
/// </summary>
197+
/// <param name="permissions"></param>
198+
public static void SetPermissions(string permissions)
199+
{
200+
Permissions = Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string, bool>>(permissions);
201+
202+
// if debug logging.
203+
if (GetResourceMetadata(GetCurrentResourceName(), "client_debug_mode", 0) == "true")
204+
{
205+
Debug.WriteLine("[vMenu] [Permissions] " + Newtonsoft.Json.JsonConvert.SerializeObject(Permissions, Newtonsoft.Json.Formatting.None));
206+
}
207+
}
208+
#endif
209+
#if SERVER
210+
/// <summary>
211+
/// Gets the full permission ace name for the specific <see cref="Permission"/> enum.
212+
/// </summary>
213+
/// <param name="permission"></param>
214+
/// <returns></returns>
215+
public static string GetAceName(string permission)
216+
{
217+
var name = permission.ToString();
218+
219+
var prefix = "vMenu.";
220+
221+
switch (name.Substring(0, 2))
222+
{
223+
case "VW":
224+
prefix += "VehicleSpawner.WhitelistedModels";
225+
break;
226+
case "PW":
227+
prefix += "PlayerAppearance.WhitelistedModels";
228+
break;
229+
case "WW":
230+
prefix += "WeaponOptions.WhitelistedModels";
231+
break;
232+
default:
233+
return prefix + name;
234+
}
235+
236+
return prefix + "." + name.Substring(2);
237+
}
238+
#endif
239+
}
240+
}

0 commit comments

Comments
 (0)