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
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -267,4 +267,6 @@ external/
*.cmd.bak

# VS Build Output
build/
build/

*.lscache
19 changes: 11 additions & 8 deletions SharedClasses/ConfigManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,10 @@ public enum Setting
vmenu_disable_entity_outlines_tool,
vmenu_disable_player_stats_setup,

// Vehicle Chameleon Colours
// Vehicle Settings
vmenu_using_chameleon_colours,
vmenu_vehicle_spawn_delay,
vmenu_delete_vehicle_distance,

// Prevent Extras Abuse
vmenu_prevent_extras_when_damaged,
Expand All @@ -61,6 +63,7 @@ public enum Setting
vmenu_vehicle_blackout_enabled,
vmenu_weather_change_duration,
vmenu_enable_snow,
vmenu_smooth_time_transitions,

// Time settings
vmenu_enable_time_sync,
Expand Down Expand Up @@ -92,12 +95,12 @@ public static bool GetSettingsBool(Setting setting)
/// </summary>
/// <param name="setting"></param>
/// <returns></returns>
public static int GetSettingsInt(Setting setting)
public static int GetSettingsInt(Setting setting, int defaultValue = -1)
{
var convarInt = GetConvarInt(setting.ToString(), -1);
if (convarInt == -1)
var convarInt = GetConvarInt(setting.ToString(), defaultValue);
if (convarInt == defaultValue)
{
if (int.TryParse(GetConvar(setting.ToString(), "-1"), out var convarIntAlt))
if (int.TryParse(GetConvar(setting.ToString(), defaultValue.ToString()), out var convarIntAlt))
{
return convarIntAlt;
}
Expand All @@ -110,13 +113,13 @@ public static int GetSettingsInt(Setting setting)
/// </summary>
/// <param name="setting"></param>
/// <returns></returns>
public static float GetSettingsFloat(Setting setting)
public static float GetSettingsFloat(Setting setting, float defaultValue = -1f)
{
if (float.TryParse(GetConvar(setting.ToString(), "-1.0"), out var result))
if (float.TryParse(GetConvar(setting.ToString(), defaultValue.ToString()), out var result))
{
return result;
}
return -1f;
return defaultValue;
}

/// <summary>
Expand Down
4 changes: 2 additions & 2 deletions SharedClasses/PermissionsManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ public enum Permission
#region vehicle spawner
VSMenu,
VSAll,
VSBypassRateLimit,
VSDisableReplacePrevious,
VSSpawnByName,
VSAddon,
Expand Down Expand Up @@ -481,8 +482,7 @@ private static bool IsAllowedServer(Permission permission, string playerHandle)
{
return false;
}

return IsPlayerAceAllowed(playerHandle, GetAceName(permission));
return GetPermissionAndParentPermissions(permission).Any(p => IsPlayerAceAllowed(playerHandle, GetAceName(p)));
}
#endif

Expand Down
240 changes: 240 additions & 0 deletions SharedClasses/SupplementaryPermissionManager.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,240 @@
using System;

using System.Collections.Generic;
using System.Linq;

using CitizenFX.Core;

using static CitizenFX.Core.Native.API;
using CitizenFX.Core.Native;

namespace vMenuShared
{
public static class SupplementaryPermissionManager
{
public static List<string> Permission = new()
{
"VWAll",
"PWAll",
"WWAll",
};

public static Dictionary<string, bool> Permissions { get; private set; } = new Dictionary<string, bool>();
public static bool ArePermissionsSetup { get; set; } = false;


#if SERVER
/// <summary>
/// Public function to check if a permission is allowed.
/// </summary>
/// <param name="permission"></param>
/// <param name="source"></param>
/// <returns></returns>
public static bool IsAllowed(string permission, Player source) => IsAllowedServer(permission, source);

/// <summary>
/// Public function to check if a permission is allowed.
/// </summary>
/// <param name="permission"></param>
/// <param name="playerHandle"></param>
/// <returns></returns>
public static bool IsAllowed(string permission, string playerHandle) => IsAllowedServer(permission, playerHandle);
#endif

#if CLIENT
/// <summary>
/// Public function to check if a permission is allowed.
/// </summary>
/// <param name="permission"></param>
/// <param name="checkAnyway">if true, then the permissions will be checked even if they aren't setup yet.</param>
/// <returns></returns>
public static bool IsAllowed(string permission, bool checkAnyway = false) => IsAllowedClient(permission, checkAnyway);

private static readonly Dictionary<string, bool> allowedPerms = new();
/// <summary>
/// Private function that handles client side permission requests.
/// </summary>
/// <param name="permission"></param>
/// <returns></returns>
private static bool IsAllowedClient(string permission, bool checkAnyway)
{
if (ArePermissionsSetup || checkAnyway)
{
if (allowedPerms.ContainsKey(permission) && allowedPerms[permission])
{
return true;
}
else if (!allowedPerms.ContainsKey(permission))
{
allowedPerms[permission] = false;
}

// Get a list of all permissions that are (parents) of the current permission, including the current permission.
var permissionsToCheck = GetPermissionAndParentPermissions(permission);

// Check if any of those permissions is allowed, if so, return true.
if (permissionsToCheck.Any(p => Permissions.ContainsKey(p) && Permissions[p]))
{
allowedPerms[permission] = true;
return true;
}
}
switch (permission.Substring(0, 2))
{
case "VW":
allowedPerms[permission] = PermissionsManager.IsAllowed(PermissionsManager.Permission.VSAll);
return PermissionsManager.IsAllowed(PermissionsManager.Permission.VSAll);
case "PW":
allowedPerms[permission] = PermissionsManager.IsAllowed(PermissionsManager.Permission.PAAll);
return PermissionsManager.IsAllowed(PermissionsManager.Permission.PAAll);
case "WW":
allowedPerms[permission] = PermissionsManager.IsAllowed(PermissionsManager.Permission.WPAll);
return PermissionsManager.IsAllowed(PermissionsManager.Permission.WPAll);
}
return false;
}
#endif
#if SERVER
/// <summary>
/// Checks if the player is allowed that specific permission.
/// </summary>
/// <param name="permission"></param>
/// <param name="source"></param>
/// <returns></returns>
private static bool IsAllowedServer(string permission, Player source)
{
if (source == null)
{
return false;
}

return IsAllowedServer(permission, source.Handle);
}

/// <summary>
/// Checks if the player is allowed that specific permission.
/// </summary>
/// <param name="permission"></param>
/// <param name="playerHandle"></param>
/// <returns></returns>
private static bool IsAllowedServer(string permission, string playerHandle)
{
if (!DoesPlayerExist(playerHandle))
{
return false;
}

return GetPermissionAndParentPermissions(permission).Any(p => IsPlayerAceAllowed(playerHandle, GetAceName(p)));
}
#endif

private static readonly Dictionary<string, List<string>> parentPermissions = new();

/// <summary>
/// Gets the current permission and all parent permissions.
/// </summary>
/// <param name="permission"></param>
/// <returns></returns>
public static List<string> GetPermissionAndParentPermissions(string permission)
{
if (parentPermissions.ContainsKey(permission))
{
return parentPermissions[permission];
}
else
{
var list = new List<string>() { "Everything", permission };

// if the first 2 characters are both uppercase
if (permission.Substring(0, 2).ToUpper() == permission.Substring(0, 2))
{
if (permission.Substring(2) is not "All")
{
list.AddRange(Permission.Where(a => a.ToString() == permission.Substring(0, 2) + "All"));
}
}
//else // it's one of the .Everything, .DontKickMe, DontBanMe, NoClip, Staff, etc perms that are not menu specific.
//{
// // do nothing
//}
parentPermissions[permission] = list;
return list;
}
}

#if SERVER


/// <summary>
/// Sets the permissions for a specific player (checks server side, sends event to client side).
/// </summary>
/// <param name="player"></param>
public static void SetPermissionsForPlayer([FromSource] Player player)
{
if (player == null)
{
return;
}

var perms = new Dictionary<string, bool>();

// Loop through all permissions and check if they're allowed.
foreach (string permission in Permission)
{
if (!perms.ContainsKey(permission))
{
perms.Add(permission, IsAllowed(permission, player)); // triggers IsAllowedServer
}
}
// Send the permissions to the client.
player.TriggerEvent("vMenu:SetSupplementaryPermissions", Newtonsoft.Json.JsonConvert.SerializeObject(perms));
}
#endif
#if CLIENT
/// <summary>
/// Sets the permission (client side event handler).
/// </summary>
/// <param name="permissions"></param>
public static void SetPermissions(string permissions)
{
Permissions = Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string, bool>>(permissions);

// if debug logging.
if (GetResourceMetadata(GetCurrentResourceName(), "client_debug_mode", 0) == "true")
{
Debug.WriteLine("[vMenu] [Permissions] " + Newtonsoft.Json.JsonConvert.SerializeObject(Permissions, Newtonsoft.Json.Formatting.None));
}
}
#endif
#if SERVER
/// <summary>
/// Gets the full permission ace name for the specific <see cref="Permission"/> enum.
/// </summary>
/// <param name="permission"></param>
/// <returns></returns>
public static string GetAceName(string permission)
{
var name = permission.ToString();

var prefix = "vMenu.";

switch (name.Substring(0, 2))
{
case "VW":
prefix += "VehicleSpawner.WhitelistedModels";
break;
case "PW":
prefix += "PlayerAppearance.WhitelistedModels";
break;
case "WW":
prefix += "WeaponOptions.WhitelistedModels";
break;
default:
return prefix + name;
}

return prefix + "." + name.Substring(2);
}
#endif
}
}
Loading
Loading