diff --git a/.gitignore b/.gitignore index fdc8383c..61d26fcf 100644 --- a/.gitignore +++ b/.gitignore @@ -267,4 +267,6 @@ external/ *.cmd.bak # VS Build Output -build/ \ No newline at end of file +build/ + +*.lscache \ No newline at end of file diff --git a/SharedClasses/ConfigManager.cs b/SharedClasses/ConfigManager.cs index c8b07fe7..5f212c2d 100644 --- a/SharedClasses/ConfigManager.cs +++ b/SharedClasses/ConfigManager.cs @@ -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, @@ -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, @@ -92,12 +95,12 @@ public static bool GetSettingsBool(Setting setting) /// /// /// - 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; } @@ -110,13 +113,13 @@ public static int GetSettingsInt(Setting setting) /// /// /// - 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; } /// diff --git a/SharedClasses/PermissionsManager.cs b/SharedClasses/PermissionsManager.cs index f3240bc6..d5826c73 100644 --- a/SharedClasses/PermissionsManager.cs +++ b/SharedClasses/PermissionsManager.cs @@ -113,6 +113,7 @@ public enum Permission #region vehicle spawner VSMenu, VSAll, + VSBypassRateLimit, VSDisableReplacePrevious, VSSpawnByName, VSAddon, @@ -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 diff --git a/SharedClasses/SupplementaryPermissionManager.cs b/SharedClasses/SupplementaryPermissionManager.cs new file mode 100644 index 00000000..8ef9944c --- /dev/null +++ b/SharedClasses/SupplementaryPermissionManager.cs @@ -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 Permission = new() + { + "VWAll", + "PWAll", + "WWAll", + }; + + public static Dictionary Permissions { get; private set; } = new Dictionary(); + public static bool ArePermissionsSetup { get; set; } = false; + + +#if SERVER + /// + /// Public function to check if a permission is allowed. + /// + /// + /// + /// + public static bool IsAllowed(string permission, Player source) => IsAllowedServer(permission, source); + + /// + /// Public function to check if a permission is allowed. + /// + /// + /// + /// + public static bool IsAllowed(string permission, string playerHandle) => IsAllowedServer(permission, playerHandle); +#endif + +#if CLIENT + /// + /// Public function to check if a permission is allowed. + /// + /// + /// if true, then the permissions will be checked even if they aren't setup yet. + /// + public static bool IsAllowed(string permission, bool checkAnyway = false) => IsAllowedClient(permission, checkAnyway); + + private static readonly Dictionary allowedPerms = new(); + /// + /// Private function that handles client side permission requests. + /// + /// + /// + 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 + /// + /// Checks if the player is allowed that specific permission. + /// + /// + /// + /// + private static bool IsAllowedServer(string permission, Player source) + { + if (source == null) + { + return false; + } + + return IsAllowedServer(permission, source.Handle); + } + + /// + /// Checks if the player is allowed that specific permission. + /// + /// + /// + /// + 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> parentPermissions = new(); + + /// + /// Gets the current permission and all parent permissions. + /// + /// + /// + public static List GetPermissionAndParentPermissions(string permission) + { + if (parentPermissions.ContainsKey(permission)) + { + return parentPermissions[permission]; + } + else + { + var list = new List() { "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 + + + /// + /// Sets the permissions for a specific player (checks server side, sends event to client side). + /// + /// + public static void SetPermissionsForPlayer([FromSource] Player player) + { + if (player == null) + { + return; + } + + var perms = new Dictionary(); + + // 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 + /// + /// Sets the permission (client side event handler). + /// + /// + public static void SetPermissions(string permissions) + { + Permissions = Newtonsoft.Json.JsonConvert.DeserializeObject>(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 + /// + /// Gets the full permission ace name for the specific enum. + /// + /// + /// + 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 + } +} diff --git a/vMenu/CommonFunctions.cs b/vMenu/CommonFunctions.cs index 3dc95ebd..cbf2e802 100644 --- a/vMenu/CommonFunctions.cs +++ b/vMenu/CommonFunctions.cs @@ -4,6 +4,7 @@ using System.Threading.Tasks; using CitizenFX.Core; +using static CitizenFX.Core.Native.API; using MenuAPI; @@ -12,9 +13,9 @@ using vMenuClient.data; using vMenuClient.menus; -using static CitizenFX.Core.Native.API; using static CitizenFX.Core.UI.Screen; using static vMenuShared.PermissionsManager; +using vMenuShared; namespace vMenuClient { @@ -23,7 +24,6 @@ public static class CommonFunctions #region Variables private static string _currentScenario = ""; private static Vehicle _previousVehicle; - internal static bool DriveToWpTaskActive = false; internal static bool DriveWanderTaskActive = false; #endregion @@ -121,7 +121,7 @@ public static async void LockOrUnlockDoors(Vehicle veh, bool lockDoors) /// /// /// - public static string GetVehDisplayNameFromModel(string name) => GetLabelText(GetDisplayNameFromVehicleModel((uint)GetHashKey(name))); + public static string GetVehDisplayNameFromModel(string name) => GetLabelText(GetDisplayNameFromVehicleModel(Game.GenerateHashASCII(name))); #endregion #region DoesModelExist @@ -130,7 +130,7 @@ public static async void LockOrUnlockDoors(Vehicle veh, bool lockDoors) /// /// The model name /// - public static bool DoesModelExist(string modelName) => DoesModelExist((uint)GetHashKey(modelName)); + public static bool DoesModelExist(string modelName) => DoesModelExist(Game.GenerateHashASCII(modelName)); /// /// Does this model exist? @@ -213,7 +213,7 @@ public static Vehicle GetVehicle(Player player, bool lastVehicle = false) /// /// Entity/vehicle. /// Returns the (uint) model hash from a (vehicle) entity. - public static uint GetVehicleModel(int vehicle) => (uint)GetHashKey(GetEntityModel(vehicle).ToString()); + public static uint GetVehicleModel(int vehicle) => Game.GenerateHashASCII(GetEntityModel(vehicle).ToString()); #endregion #region Is ped pointing @@ -873,35 +873,35 @@ public static async void CommitSuicide() if (Game.PlayerPed.Weapons.HasWeapon(WeaponHash.PistolMk2)) { - weaponHash = (uint)GetHashKey("WEAPON_PISTOL_MK2"); + weaponHash = Game.GenerateHashASCII("WEAPON_PISTOL_MK2"); } else if (Game.PlayerPed.Weapons.HasWeapon(WeaponHash.CombatPistol)) { - weaponHash = (uint)GetHashKey("WEAPON_COMBATPISTOL"); + weaponHash = Game.GenerateHashASCII("WEAPON_COMBATPISTOL"); } else if (Game.PlayerPed.Weapons.HasWeapon(WeaponHash.Pistol)) { - weaponHash = (uint)GetHashKey("WEAPON_PISTOL"); + weaponHash = Game.GenerateHashASCII("WEAPON_PISTOL"); } - else if (Game.PlayerPed.Weapons.HasWeapon((WeaponHash)(uint)GetHashKey("WEAPON_SNSPISTOL_MK2"))) + else if (Game.PlayerPed.Weapons.HasWeapon((WeaponHash)Game.GenerateHashASCII("WEAPON_SNSPISTOL_MK2"))) { - weaponHash = (uint)GetHashKey("WEAPON_SNSPISTOL_MK2"); + weaponHash = Game.GenerateHashASCII("WEAPON_SNSPISTOL_MK2"); } else if (Game.PlayerPed.Weapons.HasWeapon(WeaponHash.SNSPistol)) { - weaponHash = (uint)GetHashKey("WEAPON_SNSPISTOL"); + weaponHash = Game.GenerateHashASCII("WEAPON_SNSPISTOL"); } else if (Game.PlayerPed.Weapons.HasWeapon(WeaponHash.Pistol50)) { - weaponHash = (uint)GetHashKey("WEAPON_PISTOL50"); + weaponHash = Game.GenerateHashASCII("WEAPON_PISTOL50"); } else if (Game.PlayerPed.Weapons.HasWeapon(WeaponHash.HeavyPistol)) { - weaponHash = (uint)GetHashKey("WEAPON_HEAVYPISTOL"); + weaponHash = Game.GenerateHashASCII("WEAPON_HEAVYPISTOL"); } else if (Game.PlayerPed.Weapons.HasWeapon(WeaponHash.VintagePistol)) { - weaponHash = (uint)GetHashKey("WEAPON_VINTAGEPISTOL"); + weaponHash = Game.GenerateHashASCII("WEAPON_VINTAGEPISTOL"); } else { @@ -912,7 +912,7 @@ public static async void CommitSuicide() // If we take the pill, remove any weapons in our hands. if (takePill) { - SetCurrentPedWeapon(Game.PlayerPed.Handle, (uint)GetHashKey("weapon_unarmed"), true); + SetCurrentPedWeapon(Game.PlayerPed.Handle, Game.GenerateHashASCII("weapon_unarmed"), true); } // Otherwise, give the ped a gun. else if (weaponHash != null) @@ -922,8 +922,8 @@ public static async void CommitSuicide() } else { - GiveWeaponToPed(Game.PlayerPed.Handle, (uint)GetHashKey("weapon_pistol_mk2"), 1, false, true); - SetCurrentPedWeapon(Game.PlayerPed.Handle, (uint)GetHashKey("weapon_pistol_mk2"), true); + GiveWeaponToPed(Game.PlayerPed.Handle, Game.GenerateHashASCII("weapon_pistol_mk2"), 1, false, true); + SetCurrentPedWeapon(Game.PlayerPed.Handle, Game.GenerateHashASCII("weapon_pistol_mk2"), true); SetPedDropsWeaponsWhenDead(Game.PlayerPed.Handle, true); } @@ -935,7 +935,7 @@ public static async void CommitSuicide() while (true) { var time = GetEntityAnimCurrentTime(Game.PlayerPed.Handle, "MP_SUICIDE", takePill ? "pill" : "pistol"); - if (HasAnimEventFired(Game.PlayerPed.Handle, (uint)GetHashKey("Fire")) && !shot) // shoot the gun if the animation event is triggered. + if (HasAnimEventFired(Game.PlayerPed.Handle, Game.GenerateHashASCII("Fire")) && !shot) // shoot the gun if the animation event is triggered. { ClearEntityLastDamageEntity(Game.PlayerPed.Handle); SetPedShootsAtCoord(Game.PlayerPed.Handle, 0f, 0f, 0f, false); @@ -1209,7 +1209,7 @@ public static async Task SpawnVehicle(string vehicleName = "custom", bool s if (!string.IsNullOrEmpty(result)) { // Convert it into a model hash. - var model = (uint)GetHashKey(result); + var model = Game.GenerateHashASCII(result); return await SpawnVehicle(vehicleHash: model, spawnInside: spawnInside, replacePrevious: replacePrevious, skipLoad: false, vehicleInfo: new VehicleInfo(), saveName: null); } @@ -1220,12 +1220,14 @@ public static async Task SpawnVehicle(string vehicleName = "custom", bool s return 0; } } - return await SpawnVehicle(vehicleHash: (uint)GetHashKey(vehicleName), spawnInside: spawnInside, replacePrevious: replacePrevious, skipLoad: false, + return await SpawnVehicle(vehicleHash: Game.GenerateHashASCII(vehicleName), spawnInside: spawnInside, replacePrevious: replacePrevious, skipLoad: false, vehicleInfo: new VehicleInfo(), saveName: null); } #endregion #region Main Spawn Vehicle Function + public static int lastSpawnTime = 0; + public static int spawnTime = ConfigManager.GetSettingsInt(ConfigManager.Setting.vmenu_vehicle_spawn_delay, 5) * 1000; /// /// Spawns a vehicle. /// @@ -1252,6 +1254,27 @@ public static async Task SpawnVehicle(uint vehicleHash, bool spawnInside, b Notify.Alert("You are not allowed to spawn this vehicle, because it belongs to a category which is restricted by the server owner."); return 0; } + + if (VehicleSpawner.WhitelistVehicles.Values.Contains(vehicleHash)) + { + if (!vMenuShared.SupplementaryPermissionManager.IsAllowed("VW" + VehicleSpawner.WhitelistVehicles.FirstOrDefault(x => x.Value == vehicleHash).Key.ToLower())) + { + Notify.Alert("You are not allowed to spawn this vehicle, because it is restricted by the server owner."); + return 0; + } + } + + int gameTime = GetGameTimer(); + if (!IsAllowed(Permission.VSBypassRateLimit)) + { + if (lastSpawnTime + spawnTime > gameTime) + { + Notify.Error($"You are spawning vehicles too quickly. Please wait {Math.Ceiling((double)(lastSpawnTime + spawnTime - gameTime)/1000)} second(s) before trying again."); + return 0; + } + } + + lastSpawnTime = gameTime; if (!skipLoad) { @@ -1366,6 +1389,13 @@ public static async Task SpawnVehicle(uint vehicleHash, bool spawnInside, b { vehicle.PlaceOnGround(); } + + if (!vehicle.Model.IsTrain) // to be extra fucking safe + { + // workaround of retarded feature above: + SetVehicleForwardSpeed(vehicle.Handle, speed); + } + vehicle.CurrentRPM = rpm; } // If mod info about the vehicle was specified, check if it's not null. @@ -1376,13 +1406,6 @@ public static async Task SpawnVehicle(uint vehicleHash, bool spawnInside, b // Set the previous vehicle to the new vehicle. _previousVehicle = vehicle; - //vehicle.Speed = speed; // retarded feature that randomly breaks for no fucking reason - if (!vehicle.Model.IsTrain) // to be extra fucking safe - { - // workaround of retarded feature above: - SetVehicleForwardSpeed(vehicle.Handle, speed); - } - vehicle.CurrentRPM = rpm; int vehicleDefaultRadio = UserDefaults.VehicleDefaultRadio; @@ -2132,7 +2155,7 @@ public static void UpdateServerTime(int hours, int minutes) { realMinutes = 0; } - TriggerServerEvent("vMenu:UpdateServerTime", realHours, realMinutes); + TriggerServerEvent("vMenu:UpdateServerTime", realHours, realMinutes, EventManager.IsServerTimeFrozen); } /// @@ -2245,7 +2268,7 @@ public struct PedInfo /// Sets the player's model to the provided modelName. /// /// The model name. - public static async Task SetPlayerSkin(string modelName, PedInfo pedCustomizationOptions, bool keepWeapons = true) => await SetPlayerSkin((uint)GetHashKey(modelName), pedCustomizationOptions, keepWeapons); + public static async Task SetPlayerSkin(string modelName, PedInfo pedCustomizationOptions, bool keepWeapons = true) => await SetPlayerSkin(Game.GenerateHashASCII(modelName), pedCustomizationOptions, keepWeapons); /// /// Sets the player's model to the provided modelHash. @@ -2255,6 +2278,14 @@ public static async Task SetPlayerSkin(uint modelHash, PedInfo pedCustomizationO { if (IsModelInCdimage(modelHash)) { + if (PlayerAppearance.WhitelistedPeds.Values.Contains(modelHash)) + { + if (!vMenuShared.SupplementaryPermissionManager.IsAllowed("PW" + PlayerAppearance.WhitelistedPeds.FirstOrDefault(x => x.Value == modelHash).Key.ToLower())) + { + Notify.Alert("You are not allowed to spawn this ped, because it is restricted by the server owner."); + return; + } + } if (keepWeapons) { SaveWeaponLoadout("vmenu_temp_weapons_loadout_before_respawn"); @@ -2265,7 +2296,6 @@ public static async Task SetPlayerSkin(uint modelHash, PedInfo pedCustomizationO { await Delay(0); } - if ((uint)GetEntityModel(Game.PlayerPed.Handle) != modelHash) // only change skins if the player is not yet using the new skin. { // check if the ped is in a vehicle. @@ -2348,7 +2378,7 @@ public static async Task SetPlayerSkin(uint modelHash, PedInfo pedCustomizationO { await SpawnWeaponLoadoutAsync("vmenu_temp_weapons_loadout_before_respawn", false, true, false); } - if (modelHash == (uint)GetHashKey("mp_f_freemode_01") || modelHash == (uint)GetHashKey("mp_m_freemode_01")) + if (modelHash == Game.GenerateHashASCII("mp_f_freemode_01") || modelHash == Game.GenerateHashASCII("mp_m_freemode_01")) { //var headBlendData = Game.PlayerPed.GetHeadBlendData(); if (pedCustomizationOptions.version == -1) @@ -2376,7 +2406,7 @@ public static async void SpawnPedByName() var input = await GetUserInput(windowTitle: "Enter Ped Model Name", maxInputLength: 30); if (!string.IsNullOrEmpty(input)) { - await SetPlayerSkin((uint)GetHashKey(input), new PedInfo() { version = -1 }); + await SetPlayerSkin(Game.GenerateHashASCII(input), new PedInfo() { version = -1 }); } else { @@ -2438,7 +2468,7 @@ public static async Task SavePed(string forceName = null, bool overrideExi data.props = props; data.propTextures = propTextures; - data.isMpPed = model == (uint)GetHashKey("mp_f_freemode_01") || model == (uint)GetHashKey("mp_m_freemode_01"); + data.isMpPed = model == Game.GenerateHashASCII("mp_f_freemode_01") || model == Game.GenerateHashASCII("mp_m_freemode_01"); if (data.isMpPed) { Notify.Alert("Note, you should probably use the MP Character creator if you want more advanced features. Saving Multiplayer characters with this function does NOT save a lot of the online peds customization."); @@ -2707,7 +2737,7 @@ public static async void SpawnCustomWeapon() } } - var model = (uint)GetHashKey(inputName.ToUpper()); + var model = Game.GenerateHashASCII(inputName.ToUpper()); if (IsWeaponValid(model)) { @@ -2872,7 +2902,7 @@ public static async Task SpawnWeaponLoadoutAsync(string saveName, bool appendWea } // Set the current weapon to 'unarmed'. - SetCurrentPedWeapon(Game.PlayerPed.Handle, (uint)GetHashKey("weapon_unarmed"), true); + SetCurrentPedWeapon(Game.PlayerPed.Handle, Game.GenerateHashASCII("weapon_unarmed"), true); if (!(saveName == "vmenu_temp_weapons_loadout_before_respawn" || dontNotify)) { @@ -2990,9 +3020,9 @@ public static bool SaveWeaponLoadout(string saveName) /// public static async void SetWalkingStyle(string walkingStyle) { - if (IsPedModel(Game.PlayerPed.Handle, (uint)GetHashKey("mp_f_freemode_01")) || IsPedModel(Game.PlayerPed.Handle, (uint)GetHashKey("mp_m_freemode_01"))) + if (IsPedModel(Game.PlayerPed.Handle, Game.GenerateHashASCII("mp_f_freemode_01")) || IsPedModel(Game.PlayerPed.Handle, Game.GenerateHashASCII("mp_m_freemode_01"))) { - var isPedMale = IsPedModel(Game.PlayerPed.Handle, (uint)GetHashKey("mp_m_freemode_01")); + var isPedMale = IsPedModel(Game.PlayerPed.Handle, Game.GenerateHashASCII("mp_m_freemode_01")); ClearPedAlternateMovementAnim(Game.PlayerPed.Handle, 0, 1f); ClearPedAlternateMovementAnim(Game.PlayerPed.Handle, 1, 1f); ClearPedAlternateMovementAnim(Game.PlayerPed.Handle, 2, 1f); @@ -3444,7 +3474,7 @@ public static async void PressKeyFob(Vehicle veh) var player = Game.Player; if (player != null && !player.IsDead && !player.Character.IsInVehicle()) { - var KeyFobHashKey = (uint)GetHashKey("p_car_keys_01"); + var KeyFobHashKey = Game.GenerateHashASCII("p_car_keys_01"); RequestModel(KeyFobHashKey); while (!HasModelLoaded(KeyFobHashKey)) { @@ -3456,7 +3486,7 @@ public static async void PressKeyFob(Vehicle veh) SetModelAsNoLongerNeeded(KeyFobHashKey); // cleanup model from memory ClearPedTasks(player.Character.Handle); - SetCurrentPedWeapon(Game.PlayerPed.Handle, (uint)GetHashKey("WEAPON_UNARMED"), true); + SetCurrentPedWeapon(Game.PlayerPed.Handle, Game.GenerateHashASCII("WEAPON_UNARMED"), true); //if (player.Character.Weapons.Current.Hash != WeaponHash.Unarmed) //{ // player.Character.Weapons.Give(WeaponHash.Unarmed, 1, true, true); @@ -3599,5 +3629,81 @@ .. Enum.GetValues(typeof(VehicleData.ModType)) ]; } #endregion + + #region Delete vehicle function + + public async static void DeleteVehicle() + { + var player = Game.PlayerPed; + + if (!player.IsAlive) + return; + + if (player.IsInVehicle()) + { + var veh = GetVehicle(); + + if (veh != null && veh.Exists() && veh.Driver == player) + { + SetVehicleHasBeenOwnedByPlayer(veh.Handle, false); + SetEntityAsMissionEntity(veh.Handle, false, false); + veh.Delete(); + } + else + { + Notify.Error("This vehicle does not exist (somehow) or you need to be the driver of this vehicle to delete it!"); + } + + return; + } + + float distance = ConfigManager.GetSettingsFloat(ConfigManager.Setting.vmenu_delete_vehicle_distance, 5.0f); + int maxDeleteTries = 5; + int maxHitTries = 5; + + var forward = GetOffsetFromEntityInWorldCoords(player.Handle, 0f, distance, 0f); + var ray = StartShapeTestCapsule(player.Position.X, player.Position.Y, player.Position.Z, forward.X, forward.Y, forward.Z, 5f, 10, player.Handle, 7); + + bool hit = false; + Vector3 endCoords = Vector3.Zero; + Vector3 surfaceNormal = Vector3.Zero; + int entity = 0; + + for (int i = 0; i < maxHitTries; i++) + { + GetShapeTestResult(ray, ref hit, ref endCoords, ref surfaceNormal, ref entity); + if (hit) break; + await Task.FromResult(0); + } + + if (!hit || !DoesEntityExist(entity) || !IsEntityAVehicle(entity)) + { + Notify.Error("No vehicle found in front of you to delete!"); + return; + } + + var hitVeh = new Vehicle(entity); + + for (int i = 0; i <= maxDeleteTries && DoesEntityExist(entity); i++) + { + NetworkRequestControlOfEntity(entity); + SetVehicleHasBeenOwnedByPlayer(entity, false); + SetEntityAsMissionEntity(entity, false, false); + hitVeh.Delete(); + await Task.FromResult(0); + } + + if (DoesEntityExist(entity)) + { + Notify.Error("Failed to delete the vehicle in front of you. Try again or ask an admin for help."); + } + else + { + Notify.Success("Vehicle deleted successfully."); + } + } + + + #endregion } } diff --git a/vMenu/EntitySpawner.cs b/vMenu/EntitySpawner.cs index 0401f9b7..c3719ab8 100644 --- a/vMenu/EntitySpawner.cs +++ b/vMenu/EntitySpawner.cs @@ -47,7 +47,7 @@ public EntitySpawner() /// true spawn was succesful public static void SpawnEntity(string model, Vector3 coords) { - SpawnEntity((uint)GetHashKey(model), coords); + SpawnEntity(Game.GenerateHashASCII(model), coords); } /// diff --git a/vMenu/EventManager.cs b/vMenu/EventManager.cs index 3a57dafc..682c6825 100644 --- a/vMenu/EventManager.cs +++ b/vMenu/EventManager.cs @@ -41,6 +41,7 @@ public EventManager() EventHandlers.Add("vMenu:SetAddons", new Action(SetConfigOptions)); // DEPRECATED: Backwards-compatible event handler; use 'vMenu:SetConfigOptions' instead EventHandlers.Add("vMenu:SetConfigOptions", new Action(SetConfigOptions)); EventHandlers.Add("vMenu:SetPermissions", new Action(MainMenu.SetPermissions)); + EventHandlers.Add("vMenu:SetSupplementaryPermissions", new Action(MainMenu.SetSupplementaryPermissions)); EventHandlers.Add("vMenu:KillMe", new Action(KillMe)); EventHandlers.Add("vMenu:Notify", new Action(NotifyPlayer)); EventHandlers.Add("vMenu:SetClouds", new Action(SetClouds)); @@ -98,6 +99,7 @@ private async void SetAppearanceOnFirstSpawn() private void SetConfigOptions() { SetAddons(); + SetWhiteLists(); SetExtras(); SetTattoos(); @@ -128,7 +130,7 @@ private void SetAddons() { if (!VehicleSpawner.AddonVehicles.ContainsKey(addon)) { - VehicleSpawner.AddonVehicles.Add(addon, (uint)GetHashKey(addon)); + VehicleSpawner.AddonVehicles.Add(addon, Game.GenerateHashASCII(addon)); } else { @@ -144,7 +146,7 @@ private void SetAddons() { if (!WeaponOptions.AddonWeapons.ContainsKey(addon)) { - WeaponOptions.AddonWeapons.Add(addon, (uint)GetHashKey(addon)); + WeaponOptions.AddonWeapons.Add(addon, Game.GenerateHashASCII(addon)); } else { @@ -160,7 +162,7 @@ private void SetAddons() { if (!PlayerAppearance.AddonPeds.ContainsKey(addon)) { - PlayerAppearance.AddonPeds.Add(addon, (uint)GetHashKey(addon)); + PlayerAppearance.AddonPeds.Add(addon, Game.GenerateHashASCII(addon)); } else { @@ -190,6 +192,75 @@ private void SetAddons() } } + /// + /// Sets the addon models from the addons.json file. + /// + private void SetWhiteLists() + { + // reset addons + VehicleSpawner.WhitelistVehicles = new Dictionary(); + PlayerAppearance.WhitelistedPeds = new Dictionary(); + WeaponOptions.WeaponWhitelist = new Dictionary(); + + var jsonData = LoadResourceFile(GetCurrentResourceName(), "config/model-whitelists.json") ?? "{}"; + try + { + // load new addons. + var whitelists = JsonConvert.DeserializeObject>>(jsonData); + + // load whitelist vehicles + if (whitelists.ContainsKey("whitelistedvehicle")) + { + foreach (var whitelist in whitelists["whitelistedvehicle"]) + { + if (!VehicleSpawner.WhitelistVehicles.ContainsKey(whitelist)) + { + VehicleSpawner.WhitelistVehicles.Add(whitelist, Game.GenerateHashASCII(whitelist)); + } + else + { + Debug.WriteLine($"[vMenu] [Error] Your model-whitelists.json file contains 2 or more entries with the same vehicle name! ({whitelist}) Please remove duplicate lines!"); + } + } + } + + // load whitelisted peds. + if (whitelists.ContainsKey("whitelistedpeds")) + { + foreach (var whitelist in whitelists["whitelistedpeds"]) + { + if (!PlayerAppearance.WhitelistedPeds.ContainsKey(whitelist)) + { + PlayerAppearance.WhitelistedPeds.Add(whitelist, Game.GenerateHashASCII(whitelist)); + } + else + { + Debug.WriteLine($"[vMenu] [Error] Your model-whitelists.json file contains 2 or more entries with the same ped name! ({whitelist}) Please remove duplicate lines!"); + } + } + } + + // load whitelisted weapon. + if (whitelists.ContainsKey("whitelistedweapons")) + { + foreach (var whitelist in whitelists["whitelistedweapons"]) + { + if (!WeaponOptions.WeaponWhitelist.ContainsKey(whitelist)) + { + WeaponOptions.WeaponWhitelist.Add(whitelist, Game.GenerateHashASCII(whitelist)); + } + else + { + Debug.WriteLine($"[vMenu] [Error] Your model-whitelists.json file contains 2 or more entries with the same ped name! ({whitelist}) Please remove duplicate lines!"); + } + } + } + } + catch (JsonReaderException ex) + { + Debug.WriteLine($"\n\n^1[vMenu] [ERROR] ^7Your model-whitelists.json file contains a problem! Error details: {ex.Message}\n\n"); + } + } /// /// Sets the extras labels from the extras.json file. /// @@ -207,7 +278,7 @@ private void SetExtras() foreach (string model in extras.Keys) { - uint modelHash = (uint)GetHashKey(model); + uint modelHash = Game.GenerateHashASCII(model); if (extras[model] != null && extras[model].Count > 0) { diff --git a/vMenu/FunctionsController.cs b/vMenu/FunctionsController.cs index 12dbc85e..a584fc02 100644 --- a/vMenu/FunctionsController.cs +++ b/vMenu/FunctionsController.cs @@ -51,7 +51,7 @@ class FunctionsController : BaseScript private const string snowball_anim_dict = "anim@mp_snowball"; private const string snowball_anim_name = "pickup_snowball"; - private readonly uint snowball_hash = (uint)GetHashKey("weapon_snowball"); + private readonly uint snowball_hash = Game.GenerateHashASCII("weapon_snowball"); private bool showSnowballInfo = false; private bool stopPropsLoop = false; @@ -76,6 +76,7 @@ public void SetupTickFunctions() Tick += MiscSettings; Tick += GeneralTasks; Tick += GcTick; + Tick += ControllerTick; if (GetSettingsBool(Setting.keep_player_head_props)) { @@ -214,6 +215,36 @@ private async Task GcTick() } #endregion + #region Controller tick and functions + private async Task ControllerTick() + { + if (!Game.IsPaused && !IsPauseMenuRestarting() && IsScreenFadedIn() && !IsPlayerSwitchInProgress() && !Game.Player.IsDead && !MenuController.DisableMenuButtons) + { + if (Game.CurrentInputMode == InputMode.GamePad) + { + await HandleMenuToggleKeyForController(); + } + } + await Task.FromResult(0); + } + private async Task HandleMenuToggleKeyForController() + { + int tmpTimer = GetGameTimer(); + while ((Game.IsControlPressed(0, Control.InteractionMenu) || Game.IsDisabledControlPressed(0, Control.InteractionMenu)) && !Game.IsPaused && IsScreenFadedIn() && !Game.Player.IsDead && !IsPlayerSwitchInProgress() && !MenuController.DontOpenAnyMenu) + { + if (GetGameTimer() - tmpTimer > 400) + { + if (MainMenu.Menu != null) + { + MainMenu.Menu.OpenMenu(); + } + break; + } + await Delay(0); + } + } + #endregion + #region General Tasks /// /// All general tasks that run every 1 game ticks (and are not (sub)menu specific). @@ -590,7 +621,6 @@ private async Task VehicleOptions() var subMenus = new List() { - MainMenu.VehicleOptionsMenu.DeleteConfirmMenu, MainMenu.VehicleOptionsMenu.VehicleColorsMenu, MainMenu.VehicleOptionsMenu.VehicleComponentsMenu, MainMenu.VehicleOptionsMenu.VehicleDoorsMenu, @@ -1462,9 +1492,9 @@ private async Task WeaponOptions() if (MainMenu.WeaponOptionsMenu.UnlimitedParachutes) { - if (!HasPedGotWeapon(Game.PlayerPed.Handle, (uint)GetHashKey("gadget_parachute"), false)) + if (!HasPedGotWeapon(Game.PlayerPed.Handle, Game.GenerateHashASCII("gadget_parachute"), false)) { - GiveWeaponToPed(Game.PlayerPed.Handle, (uint)GetHashKey("gadget_parachute"), 0, false, false); + GiveWeaponToPed(Game.PlayerPed.Handle, Game.GenerateHashASCII("gadget_parachute"), 0, false, false); } if (!GetPlayerHasReserveParachute(Game.Player.Handle)) @@ -2460,38 +2490,38 @@ private async Task OnlinePlayersTasks() /* private readonly List flareVehicles = new List() { - (uint)GetHashKey("mogul"), - (uint)GetHashKey("rogue"), - (uint)GetHashKey("starling"), - (uint)GetHashKey("seabreeze"), - (uint)GetHashKey("tula"), - (uint)GetHashKey("bombushka"), - (uint)GetHashKey("hunter"), - (uint)GetHashKey("nokota"), - (uint)GetHashKey("pyro"), - (uint)GetHashKey("molotok"), - (uint)GetHashKey("havok"), - (uint)GetHashKey("alphaz1"), - (uint)GetHashKey("microlight"), - (uint)GetHashKey("howard"), - (uint)GetHashKey("avenger"), - (uint)GetHashKey("thruster"), - (uint)GetHashKey("volatol") + Game.GenerateHashASCII("mogul"), + Game.GenerateHashASCII("rogue"), + Game.GenerateHashASCII("starling"), + Game.GenerateHashASCII("seabreeze"), + Game.GenerateHashASCII("tula"), + Game.GenerateHashASCII("bombushka"), + Game.GenerateHashASCII("hunter"), + Game.GenerateHashASCII("nokota"), + Game.GenerateHashASCII("pyro"), + Game.GenerateHashASCII("molotok"), + Game.GenerateHashASCII("havok"), + Game.GenerateHashASCII("alphaz1"), + Game.GenerateHashASCII("microlight"), + Game.GenerateHashASCII("howard"), + Game.GenerateHashASCII("avenger"), + Game.GenerateHashASCII("thruster"), + Game.GenerateHashASCII("volatol") }; private readonly List bombVehicles = new List() { - (uint)GetHashKey("cuban800"), - (uint)GetHashKey("mogul"), - (uint)GetHashKey("rogue"), - (uint)GetHashKey("starling"), - (uint)GetHashKey("seabreeze"), - (uint)GetHashKey("tula"), - (uint)GetHashKey("bombushka"), - (uint)GetHashKey("hunter"), - (uint)GetHashKey("avenger"), - (uint)GetHashKey("akula"), - (uint)GetHashKey("volatol") + Game.GenerateHashASCII("cuban800"), + Game.GenerateHashASCII("mogul"), + Game.GenerateHashASCII("rogue"), + Game.GenerateHashASCII("starling"), + Game.GenerateHashASCII("seabreeze"), + Game.GenerateHashASCII("tula"), + Game.GenerateHashASCII("bombushka"), + Game.GenerateHashASCII("hunter"), + Game.GenerateHashASCII("avenger"), + Game.GenerateHashASCII("akula"), + Game.GenerateHashASCII("volatol") }; /// Returns true if the player can currently fire flares. @@ -3031,67 +3061,67 @@ private async Task SwitchHelmetOnce() { var sportBikes = new List() { - (uint)GetHashKey("AKUMA"), - (uint)GetHashKey("BATI"), - (uint)GetHashKey("BATI2"), - (uint)GetHashKey("CARBONRS"), - (uint)GetHashKey("DEFILER"), - (uint)GetHashKey("DIABLOUS2"), - (uint)GetHashKey("DOUBLE"), - (uint)GetHashKey("FCR"), - (uint)GetHashKey("FCR2"), - (uint)GetHashKey("HAKUCHOU"), - (uint)GetHashKey("HAKUCHOU2"), - (uint)GetHashKey("LECTRO"), - (uint)GetHashKey("NEMESIS"), - (uint)GetHashKey("OPPRESSOR"), - (uint)GetHashKey("OPPRESSOR2"), - (uint)GetHashKey("PCJ"), - (uint)GetHashKey("RUFFIAN"), - (uint)GetHashKey("SHOTARO"), - (uint)GetHashKey("VADER"), - (uint)GetHashKey("VORTEX"), + Game.GenerateHashASCII("AKUMA"), + Game.GenerateHashASCII("BATI"), + Game.GenerateHashASCII("BATI2"), + Game.GenerateHashASCII("CARBONRS"), + Game.GenerateHashASCII("DEFILER"), + Game.GenerateHashASCII("DIABLOUS2"), + Game.GenerateHashASCII("DOUBLE"), + Game.GenerateHashASCII("FCR"), + Game.GenerateHashASCII("FCR2"), + Game.GenerateHashASCII("HAKUCHOU"), + Game.GenerateHashASCII("HAKUCHOU2"), + Game.GenerateHashASCII("LECTRO"), + Game.GenerateHashASCII("NEMESIS"), + Game.GenerateHashASCII("OPPRESSOR"), + Game.GenerateHashASCII("OPPRESSOR2"), + Game.GenerateHashASCII("PCJ"), + Game.GenerateHashASCII("RUFFIAN"), + Game.GenerateHashASCII("SHOTARO"), + Game.GenerateHashASCII("VADER"), + Game.GenerateHashASCII("VORTEX"), }; var chopperBikes = new List() { - (uint)GetHashKey("SANCTUS"), - (uint)GetHashKey("ZOMBIEA"), - (uint)GetHashKey("ZOMBIEB"), + Game.GenerateHashASCII("SANCTUS"), + Game.GenerateHashASCII("ZOMBIEA"), + Game.GenerateHashASCII("ZOMBIEB"), }; var dirtBikes = new List() { - (uint)GetHashKey("BF400"), - (uint)GetHashKey("ENDURO"), - (uint)GetHashKey("MANCHEZ"), - (uint)GetHashKey("SANCHEZ"), - (uint)GetHashKey("SANCHEZ2"), - (uint)GetHashKey("ESSKEY"), + Game.GenerateHashASCII("BF400"), + Game.GenerateHashASCII("ENDURO"), + Game.GenerateHashASCII("MANCHEZ"), + Game.GenerateHashASCII("SANCHEZ"), + Game.GenerateHashASCII("SANCHEZ2"), + Game.GenerateHashASCII("ESSKEY"), }; var scooters = new List() { - (uint)GetHashKey("FAGGIO"), - (uint)GetHashKey("FAGGIO2"), - (uint)GetHashKey("FAGGIO3"), - (uint)GetHashKey("CLIFFHANGER"), - (uint)GetHashKey("BAGGER"), + Game.GenerateHashASCII("FAGGIO"), + Game.GenerateHashASCII("FAGGIO2"), + Game.GenerateHashASCII("FAGGIO3"), + Game.GenerateHashASCII("CLIFFHANGER"), + Game.GenerateHashASCII("BAGGER"), }; var policeb = new List() { - (uint)GetHashKey("AVARUS"), - (uint)GetHashKey("CHIMERA"), - (uint)GetHashKey("POLICEB"), - (uint)GetHashKey("SOVEREIGN"), - (uint)GetHashKey("HEXER"), - (uint)GetHashKey("INNOVATION"), - (uint)GetHashKey("NIGHTBLADE"), - (uint)GetHashKey("RATBIKE"), - (uint)GetHashKey("DAEMON"), - (uint)GetHashKey("DAEMON2"), - (uint)GetHashKey("DIABLOUS"), - (uint)GetHashKey("GARGOYLE"), - (uint)GetHashKey("THRUST"), - (uint)GetHashKey("VINDICATOR"), - (uint)GetHashKey("WOLFSBANE"), + Game.GenerateHashASCII("AVARUS"), + Game.GenerateHashASCII("CHIMERA"), + Game.GenerateHashASCII("POLICEB"), + Game.GenerateHashASCII("SOVEREIGN"), + Game.GenerateHashASCII("HEXER"), + Game.GenerateHashASCII("INNOVATION"), + Game.GenerateHashASCII("NIGHTBLADE"), + Game.GenerateHashASCII("RATBIKE"), + Game.GenerateHashASCII("DAEMON"), + Game.GenerateHashASCII("DAEMON2"), + Game.GenerateHashASCII("DIABLOUS"), + Game.GenerateHashASCII("GARGOYLE"), + Game.GenerateHashASCII("THRUST"), + Game.GenerateHashASCII("VINDICATOR"), + Game.GenerateHashASCII("WOLFSBANE"), }; if (policeb.Contains((uint)veh.Model.Hash)) @@ -3205,7 +3235,7 @@ private async Task PickupSnowballOnce() await Delay(0); if (!fired) { - if (HasAnimEventFired(Game.PlayerPed.Handle, (uint)GetHashKey("CreateObject"))) + if (HasAnimEventFired(Game.PlayerPed.Handle, Game.GenerateHashASCII("CreateObject"))) { AddAmmoToPed(Game.PlayerPed.Handle, snowball_hash, 2); GiveWeaponToPed(Game.PlayerPed.Handle, snowball_hash, 0, true, true); @@ -3215,12 +3245,12 @@ private async Task PickupSnowballOnce() } fired = true; } - else if (HasAnimEventFired(Game.PlayerPed.Handle, (uint)GetHashKey("Interrupt"))) + else if (HasAnimEventFired(Game.PlayerPed.Handle, Game.GenerateHashASCII("Interrupt"))) { break; } } - else if (HasAnimEventFired(Game.PlayerPed.Handle, (uint)GetHashKey("Interrupt"))) + else if (HasAnimEventFired(Game.PlayerPed.Handle, Game.GenerateHashASCII("Interrupt"))) { break; } diff --git a/vMenu/MainMenu.cs b/vMenu/MainMenu.cs index 550f29cc..35365efd 100644 --- a/vMenu/MainMenu.cs +++ b/vMenu/MainMenu.cs @@ -10,6 +10,8 @@ using vMenuClient.menus; +using vMenuShared; + using static CitizenFX.Core.Native.API; using static vMenuClient.CommonFunctions; using static vMenuShared.ConfigManager; @@ -23,6 +25,7 @@ public class MainMenu : BaseScript public static bool PermissionsSetupComplete => ArePermissionsSetup; public static bool ConfigOptionsSetupComplete = false; + public static bool AddonPermissionSetup = false; public static string MenuToggleKey { get; private set; } = "M"; // M by default public static string NoClipKey { get; private set; } = "F2"; // F2 by default @@ -144,6 +147,14 @@ public MainMenu() } } }), false); + + RegisterCommand("vMenu:DV", new Action, string>((source, args, rawCommand) => + { + if (IsAllowed(Permission.VODelete)) + { + DeleteVehicle(); + } + }), false); if (!(GetSettingsString(Setting.vmenu_noclip_toggle_key) == null)) { @@ -377,7 +388,19 @@ public static async Task RequestPlayerCoordinates(int serverId) return coords; } #endregion + #region Set Permissions function + /// + /// Set the permissions for this client. + /// + /// + public static void SetSupplementaryPermissions(string permissionsList) + { + vMenuShared.SupplementaryPermissionManager.SetPermissions(permissionsList); + AddonPermissionSetup = true; + SupplementaryPermissionManager.ArePermissionsSetup = true; + } + #endregion #region Set Permissions function /// /// Set the permissions for this client. @@ -414,7 +437,7 @@ public static async void SetPermissions(string permissionsList) IsAllowed(Permission.VSOpenWheel, checkAnyway: true) }; ArePermissionsSetup = true; - while (!ConfigOptionsSetupComplete) + while (!ConfigOptionsSetupComplete && !AddonPermissionSetup) { await Delay(100); } @@ -488,21 +511,21 @@ static bool canUseMenu() // Manage Stamina if (PlayerOptionsMenu != null && PlayerOptionsMenu.PlayerStamina && IsAllowed(Permission.POUnlimitedStamina)) { - StatSetInt((uint)GetHashKey("MP0_STAMINA"), 100, true); + StatSetInt(Game.GenerateHashASCII("MP0_STAMINA"), 100, true); } else { - StatSetInt((uint)GetHashKey("MP0_STAMINA"), 0, true); + StatSetInt(Game.GenerateHashASCII("MP0_STAMINA"), 0, true); } // Manage other stats, in order of appearance in the pause menu (stats) page. - StatSetInt((uint)GetHashKey("MP0_SHOOTING_ABILITY"), 100, true); // Shooting - StatSetInt((uint)GetHashKey("MP0_STRENGTH"), 100, true); // Strength - StatSetInt((uint)GetHashKey("MP0_STEALTH_ABILITY"), 100, true); // Stealth - StatSetInt((uint)GetHashKey("MP0_FLYING_ABILITY"), 100, true); // Flying - StatSetInt((uint)GetHashKey("MP0_WHEELIE_ABILITY"), 100, true); // Driving - StatSetInt((uint)GetHashKey("MP0_LUNG_CAPACITY"), 100, true); // Lung Capacity - StatSetFloat((uint)GetHashKey("MP0_PLAYER_MENTAL_STATE"), 0f, true); // Mental State + StatSetInt(Game.GenerateHashASCII("MP0_SHOOTING_ABILITY"), 100, true); // Shooting + StatSetInt(Game.GenerateHashASCII("MP0_STRENGTH"), 100, true); // Strength + StatSetInt(Game.GenerateHashASCII("MP0_STEALTH_ABILITY"), 100, true); // Stealth + StatSetInt(Game.GenerateHashASCII("MP0_FLYING_ABILITY"), 100, true); // Flying + StatSetInt(Game.GenerateHashASCII("MP0_WHEELIE_ABILITY"), 100, true); // Driving + StatSetInt(Game.GenerateHashASCII("MP0_LUNG_CAPACITY"), 100, true); // Lung Capacity + StatSetFloat(Game.GenerateHashASCII("MP0_PLAYER_MENTAL_STATE"), 0f, true); // Mental State } RegisterCommand($"vMenu:{GetKeyMappingId()}:MenuToggle", new Action, string>((dynamic source, List args, string rawCommand) => diff --git a/vMenu/data/BlipInfo.cs b/vMenu/data/BlipInfo.cs index 822f855b..e4924164 100644 --- a/vMenu/data/BlipInfo.cs +++ b/vMenu/data/BlipInfo.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using static CitizenFX.Core.Native.API; +using CitizenFX.Core; namespace vMenuClient.data { @@ -11,69 +12,69 @@ public static int GetBlipSpriteForVehicle(int vehicle) var model = (uint)GetEntityModel(vehicle); var sprites = new Dictionary() { - { (uint)GetHashKey("taxi"), 56 }, + { Game.GenerateHashASCII("taxi"), 56 }, // - { (uint)GetHashKey("nightshark"), 225 }, + { Game.GenerateHashASCII("nightshark"), 225 }, // - { (uint)GetHashKey("rhino"), 421 }, + { Game.GenerateHashASCII("rhino"), 421 }, // - { (uint)GetHashKey("lazer"), 424 }, - { (uint)GetHashKey("besra"), 424 }, - { (uint)GetHashKey("hydra"), 424 }, + { Game.GenerateHashASCII("lazer"), 424 }, + { Game.GenerateHashASCII("besra"), 424 }, + { Game.GenerateHashASCII("hydra"), 424 }, // - { (uint)GetHashKey("insurgent"), 426 }, - { (uint)GetHashKey("insurgent2"), 426 }, - { (uint)GetHashKey("insurgent3"), 426 }, + { Game.GenerateHashASCII("insurgent"), 426 }, + { Game.GenerateHashASCII("insurgent2"), 426 }, + { Game.GenerateHashASCII("insurgent3"), 426 }, // - { (uint)GetHashKey("limo2"), 460 }, + { Game.GenerateHashASCII("limo2"), 460 }, // - { (uint)GetHashKey("blazer5"), 512 }, + { Game.GenerateHashASCII("blazer5"), 512 }, // - { (uint)GetHashKey("phantom2"), 528 }, - { (uint)GetHashKey("boxville5"), 529 }, - { (uint)GetHashKey("ruiner2"), 530 }, - { (uint)GetHashKey("dune4"), 531 }, - { (uint)GetHashKey("dune5"), 531 }, - { (uint)GetHashKey("wastelander"), 532 }, - { (uint)GetHashKey("voltic2"), 533 }, - { (uint)GetHashKey("technical2"), 534 }, - { (uint)GetHashKey("technical3"), 534 }, - { (uint)GetHashKey("technical"), 534 }, + { Game.GenerateHashASCII("phantom2"), 528 }, + { Game.GenerateHashASCII("boxville5"), 529 }, + { Game.GenerateHashASCII("ruiner2"), 530 }, + { Game.GenerateHashASCII("dune4"), 531 }, + { Game.GenerateHashASCII("dune5"), 531 }, + { Game.GenerateHashASCII("wastelander"), 532 }, + { Game.GenerateHashASCII("voltic2"), 533 }, + { Game.GenerateHashASCII("technical2"), 534 }, + { Game.GenerateHashASCII("technical3"), 534 }, + { Game.GenerateHashASCII("technical"), 534 }, // - { (uint)GetHashKey("apc"), 558 }, - { (uint)GetHashKey("oppressor"), 559 }, - { (uint)GetHashKey("oppressor2"), 559 }, - { (uint)GetHashKey("halftrack"), 560 }, - { (uint)GetHashKey("dune3"), 561 }, - { (uint)GetHashKey("tampa3"), 562 }, - { (uint)GetHashKey("trailersmall2"), 563 }, + { Game.GenerateHashASCII("apc"), 558 }, + { Game.GenerateHashASCII("oppressor"), 559 }, + { Game.GenerateHashASCII("oppressor2"), 559 }, + { Game.GenerateHashASCII("halftrack"), 560 }, + { Game.GenerateHashASCII("dune3"), 561 }, + { Game.GenerateHashASCII("tampa3"), 562 }, + { Game.GenerateHashASCII("trailersmall2"), 563 }, // - { (uint)GetHashKey("alphaz1"), 572 }, - { (uint)GetHashKey("bombushka"), 573 }, - { (uint)GetHashKey("havok"), 574 }, - { (uint)GetHashKey("howard"), 575 }, - { (uint)GetHashKey("hunter"), 576 }, - { (uint)GetHashKey("microlight"), 577 }, - { (uint)GetHashKey("mogul"), 578 }, - { (uint)GetHashKey("molotok"), 579 }, - { (uint)GetHashKey("nokota"), 580 }, - { (uint)GetHashKey("pyro"), 581 }, - { (uint)GetHashKey("rogue"), 582 }, - { (uint)GetHashKey("starling"), 583 }, - { (uint)GetHashKey("seabreeze"), 584 }, - { (uint)GetHashKey("tula"), 585 }, + { Game.GenerateHashASCII("alphaz1"), 572 }, + { Game.GenerateHashASCII("bombushka"), 573 }, + { Game.GenerateHashASCII("havok"), 574 }, + { Game.GenerateHashASCII("howard"), 575 }, + { Game.GenerateHashASCII("hunter"), 576 }, + { Game.GenerateHashASCII("microlight"), 577 }, + { Game.GenerateHashASCII("mogul"), 578 }, + { Game.GenerateHashASCII("molotok"), 579 }, + { Game.GenerateHashASCII("nokota"), 580 }, + { Game.GenerateHashASCII("pyro"), 581 }, + { Game.GenerateHashASCII("rogue"), 582 }, + { Game.GenerateHashASCII("starling"), 583 }, + { Game.GenerateHashASCII("seabreeze"), 584 }, + { Game.GenerateHashASCII("tula"), 585 }, // - { (uint)GetHashKey("avenger"), 589 }, + { Game.GenerateHashASCII("avenger"), 589 }, // - { (uint)GetHashKey("stromberg"), 595 }, - { (uint)GetHashKey("deluxo"), 596 }, - { (uint)GetHashKey("thruster"), 597 }, - { (uint)GetHashKey("khanjali"), 598 }, - { (uint)GetHashKey("riot2"), 599 }, - { (uint)GetHashKey("volatol"), 600 }, - { (uint)GetHashKey("barrage"), 601 }, - { (uint)GetHashKey("akula"), 602 }, - { (uint)GetHashKey("chernobog"), 603 }, + { Game.GenerateHashASCII("stromberg"), 595 }, + { Game.GenerateHashASCII("deluxo"), 596 }, + { Game.GenerateHashASCII("thruster"), 597 }, + { Game.GenerateHashASCII("khanjali"), 598 }, + { Game.GenerateHashASCII("riot2"), 599 }, + { Game.GenerateHashASCII("volatol"), 600 }, + { Game.GenerateHashASCII("barrage"), 601 }, + { Game.GenerateHashASCII("akula"), 602 }, + { Game.GenerateHashASCII("chernobog"), 603 }, }; if (sprites.ContainsKey(model)) diff --git a/vMenu/data/PedModels.cs b/vMenu/data/PedModels.cs index 6345c16c..da264eff 100644 --- a/vMenu/data/PedModels.cs +++ b/vMenu/data/PedModels.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using static CitizenFX.Core.Native.API; +using CitizenFX.Core; namespace vMenuClient.data { @@ -8,49 +9,49 @@ public static class PedModels { public static List AnimalHashes = new() { - (uint)GetHashKey("a_c_boar"), - (uint)GetHashKey("a_c_boar_02"), // mp2023_01 - (uint)GetHashKey("a_c_cat_01"), - (uint)GetHashKey("a_c_cat_02"), // mp2025_02 - (uint)GetHashKey("a_c_chickenhawk"), - (uint)GetHashKey("a_c_chimp"), - (uint)GetHashKey("a_c_chimp_02"), // mpchristmas3 - (uint)GetHashKey("a_c_chop"), - (uint)GetHashKey("a_c_chop_02"), // mpsecurity - (uint)GetHashKey("a_c_cormorant"), - (uint)GetHashKey("a_c_cow"), - (uint)GetHashKey("a_c_coyote"), - (uint)GetHashKey("a_c_coyote_02"), // mp2023_01 - (uint)GetHashKey("a_c_crow"), - (uint)GetHashKey("a_c_deer"), - (uint)GetHashKey("a_c_deer_02"), // mp2023_01 - (uint)GetHashKey("a_c_dolphin"), - (uint)GetHashKey("a_c_fish"), - (uint)GetHashKey("a_c_hen"), - (uint)GetHashKey("a_c_humpback"), - (uint)GetHashKey("a_c_husky"), - (uint)GetHashKey("a_c_killerwhale"), - (uint)GetHashKey("a_c_mtlion"), - (uint)GetHashKey("a_c_mtlion_02"), // mp2023_01 - (uint)GetHashKey("a_c_panther"), // mpheist4 - (uint)GetHashKey("a_c_pig"), - (uint)GetHashKey("a_c_pigeon"), - (uint)GetHashKey("a_c_poodle"), - (uint)GetHashKey("a_c_pug"), - (uint)GetHashKey("a_c_pug_02"), // mp2023_01 - (uint)GetHashKey("a_c_rabbit_01"), - (uint)GetHashKey("a_c_rabbit_02"), // mpchristmas3 - (uint)GetHashKey("a_c_rat"), - (uint)GetHashKey("a_c_retriever"), - (uint)GetHashKey("a_c_rhesus"), - (uint)GetHashKey("a_c_rottweiler"), - (uint)GetHashKey("a_c_rottweiler_02"), // mp2025_01 - (uint)GetHashKey("a_c_seagull"), - (uint)GetHashKey("a_c_sharkhammer"), - (uint)GetHashKey("a_c_sharktiger"), - (uint)GetHashKey("a_c_shepherd"), - (uint)GetHashKey("a_c_stingray"), - (uint)GetHashKey("a_c_westy") + Game.GenerateHashASCII("a_c_boar"), + Game.GenerateHashASCII("a_c_boar_02"), // mp2023_01 + Game.GenerateHashASCII("a_c_cat_01"), + Game.GenerateHashASCII("a_c_cat_02"), // mp2025_02 + Game.GenerateHashASCII("a_c_chickenhawk"), + Game.GenerateHashASCII("a_c_chimp"), + Game.GenerateHashASCII("a_c_chimp_02"), // mpchristmas3 + Game.GenerateHashASCII("a_c_chop"), + Game.GenerateHashASCII("a_c_chop_02"), // mpsecurity + Game.GenerateHashASCII("a_c_cormorant"), + Game.GenerateHashASCII("a_c_cow"), + Game.GenerateHashASCII("a_c_coyote"), + Game.GenerateHashASCII("a_c_coyote_02"), // mp2023_01 + Game.GenerateHashASCII("a_c_crow"), + Game.GenerateHashASCII("a_c_deer"), + Game.GenerateHashASCII("a_c_deer_02"), // mp2023_01 + Game.GenerateHashASCII("a_c_dolphin"), + Game.GenerateHashASCII("a_c_fish"), + Game.GenerateHashASCII("a_c_hen"), + Game.GenerateHashASCII("a_c_humpback"), + Game.GenerateHashASCII("a_c_husky"), + Game.GenerateHashASCII("a_c_killerwhale"), + Game.GenerateHashASCII("a_c_mtlion"), + Game.GenerateHashASCII("a_c_mtlion_02"), // mp2023_01 + Game.GenerateHashASCII("a_c_panther"), // mpheist4 + Game.GenerateHashASCII("a_c_pig"), + Game.GenerateHashASCII("a_c_pigeon"), + Game.GenerateHashASCII("a_c_poodle"), + Game.GenerateHashASCII("a_c_pug"), + Game.GenerateHashASCII("a_c_pug_02"), // mp2023_01 + Game.GenerateHashASCII("a_c_rabbit_01"), + Game.GenerateHashASCII("a_c_rabbit_02"), // mpchristmas3 + Game.GenerateHashASCII("a_c_rat"), + Game.GenerateHashASCII("a_c_retriever"), + Game.GenerateHashASCII("a_c_rhesus"), + Game.GenerateHashASCII("a_c_rottweiler"), + Game.GenerateHashASCII("a_c_rottweiler_02"), // mp2025_01 + Game.GenerateHashASCII("a_c_seagull"), + Game.GenerateHashASCII("a_c_sharkhammer"), + Game.GenerateHashASCII("a_c_sharktiger"), + Game.GenerateHashASCII("a_c_shepherd"), + Game.GenerateHashASCII("a_c_stingray"), + Game.GenerateHashASCII("a_c_westy") }; } } diff --git a/vMenu/data/ValidAddonWeapon.cs b/vMenu/data/ValidAddonWeapon.cs index 82e497cd..842c8aa8 100644 --- a/vMenu/data/ValidAddonWeapon.cs +++ b/vMenu/data/ValidAddonWeapon.cs @@ -89,12 +89,12 @@ private static void CreateAddonWeaponsList() var realName = addonWeapon.Key; var localizedName = addonWeapon.Value; if (realName == "weapon_unarmed") continue; - var hash = (uint)GetHashKey(realName); + var hash = Game.GenerateHashASCII(realName); var componentHashes = new Dictionary(); var weaponComponents = ValidWeapons.GetWeaponComponents(); foreach (var comp in weaponComponents.Keys) { - uint componentHash = (uint)GetHashKey(comp); + uint componentHash = Game.GenerateHashASCII(comp); if (DoesWeaponTakeWeaponComponent(hash, componentHash)) { string componentName = weaponComponents[comp]; diff --git a/vMenu/data/ValidWeapon.cs b/vMenu/data/ValidWeapon.cs index f4a0b81c..a58972b4 100644 --- a/vMenu/data/ValidWeapon.cs +++ b/vMenu/data/ValidWeapon.cs @@ -108,13 +108,13 @@ private static void CreateWeaponsList() var realName = weapon.Key; var localizedName = weapon.Value; if (realName == "weapon_unarmed") continue; - var hash = (uint)GetHashKey(realName); + var hash = Game.GenerateHashASCII(realName); var componentHashes = new Dictionary(); var weaponComponents = GetWeaponComponents(); var weaponComponentKeys = weaponComponents.Keys; foreach (var comp in weaponComponentKeys) { - var componentHash = (uint)GetHashKey(comp); + var componentHash = Game.GenerateHashASCII(comp); if (DoesWeaponTakeWeaponComponent(hash, componentHash)) { var componentName = weaponComponents[comp]; diff --git a/vMenu/menus/MpPedCustomization.cs b/vMenu/menus/MpPedCustomization.cs index 610804f6..8747ab9b 100644 --- a/vMenu/menus/MpPedCustomization.cs +++ b/vMenu/menus/MpPedCustomization.cs @@ -159,7 +159,7 @@ private void MakeCreateCharacterMenu(bool male, bool editPed = false) currentCharacter.PropVariations.props = new Dictionary>(); currentCharacter.PedHeadBlendData = Game.PlayerPed.GetHeadBlendData(); currentCharacter.Version = 1; - currentCharacter.ModelHash = male ? (uint)GetHashKey("mp_m_freemode_01") : (uint)GetHashKey("mp_f_freemode_01"); + currentCharacter.ModelHash = male ? Game.GenerateHashASCII("mp_m_freemode_01") : Game.GenerateHashASCII("mp_f_freemode_01"); currentCharacter.IsMale = male; // Places the sliders in the middle by default @@ -1626,13 +1626,13 @@ void ApplySavedTattoos() foreach (var tattoo in allTattoos) { - AddPedDecorationFromHashes(Game.PlayerPed.Handle, (uint)GetHashKey(tattoo.Key), (uint)GetHashKey(tattoo.Value)); + AddPedDecorationFromHashes(Game.PlayerPed.Handle, Game.GenerateHashASCII(tattoo.Key), Game.GenerateHashASCII(tattoo.Value)); } if (!string.IsNullOrEmpty(currentCharacter.PedAppearance.HairOverlay.Key) && !string.IsNullOrEmpty(currentCharacter.PedAppearance.HairOverlay.Value)) { // reset hair value - AddPedDecorationFromHashes(Game.PlayerPed.Handle, (uint)GetHashKey(currentCharacter.PedAppearance.HairOverlay.Key), (uint)GetHashKey(currentCharacter.PedAppearance.HairOverlay.Value)); + AddPedDecorationFromHashes(Game.PlayerPed.Handle, Game.GenerateHashASCII(currentCharacter.PedAppearance.HairOverlay.Key), Game.GenerateHashASCII(currentCharacter.PedAppearance.HairOverlay.Value)); } } @@ -1653,7 +1653,7 @@ void ApplySavedTattoos() var tat = new KeyValuePair(Tattoo.collectionName, Tattoo.name); if (!currentCharacter.PedTatttoos.HairTattoos.Contains(tat)) { - AddPedDecorationFromHashes(Game.PlayerPed.Handle, (uint)GetHashKey(tat.Key), (uint)GetHashKey(tat.Value)); + AddPedDecorationFromHashes(Game.PlayerPed.Handle, Game.GenerateHashASCII(tat.Key), Game.GenerateHashASCII(tat.Value)); } } else if (menuIndex == 1) // head @@ -1662,7 +1662,7 @@ void ApplySavedTattoos() var tat = new KeyValuePair(Tattoo.collectionName, Tattoo.name); if (!currentCharacter.PedTatttoos.HeadTattoos.Contains(tat)) { - AddPedDecorationFromHashes(Game.PlayerPed.Handle, (uint)GetHashKey(tat.Key), (uint)GetHashKey(tat.Value)); + AddPedDecorationFromHashes(Game.PlayerPed.Handle, Game.GenerateHashASCII(tat.Key), Game.GenerateHashASCII(tat.Value)); } } else if (menuIndex == 2) // torso @@ -1671,7 +1671,7 @@ void ApplySavedTattoos() var tat = new KeyValuePair(Tattoo.collectionName, Tattoo.name); if (!currentCharacter.PedTatttoos.TorsoTattoos.Contains(tat)) { - AddPedDecorationFromHashes(Game.PlayerPed.Handle, (uint)GetHashKey(tat.Key), (uint)GetHashKey(tat.Value)); + AddPedDecorationFromHashes(Game.PlayerPed.Handle, Game.GenerateHashASCII(tat.Key), Game.GenerateHashASCII(tat.Value)); } } else if (menuIndex == 3) // left arm @@ -1680,7 +1680,7 @@ void ApplySavedTattoos() var tat = new KeyValuePair(Tattoo.collectionName, Tattoo.name); if (!currentCharacter.PedTatttoos.LeftArmTattoos.Contains(tat)) { - AddPedDecorationFromHashes(Game.PlayerPed.Handle, (uint)GetHashKey(tat.Key), (uint)GetHashKey(tat.Value)); + AddPedDecorationFromHashes(Game.PlayerPed.Handle, Game.GenerateHashASCII(tat.Key), Game.GenerateHashASCII(tat.Value)); } } else if (menuIndex == 4) // right arm @@ -1689,7 +1689,7 @@ void ApplySavedTattoos() var tat = new KeyValuePair(Tattoo.collectionName, Tattoo.name); if (!currentCharacter.PedTatttoos.RightArmTattoos.Contains(tat)) { - AddPedDecorationFromHashes(Game.PlayerPed.Handle, (uint)GetHashKey(tat.Key), (uint)GetHashKey(tat.Value)); + AddPedDecorationFromHashes(Game.PlayerPed.Handle, Game.GenerateHashASCII(tat.Key), Game.GenerateHashASCII(tat.Value)); } } else if (menuIndex == 5) // left leg @@ -1698,7 +1698,7 @@ void ApplySavedTattoos() var tat = new KeyValuePair(Tattoo.collectionName, Tattoo.name); if (!currentCharacter.PedTatttoos.LeftLegTattoos.Contains(tat)) { - AddPedDecorationFromHashes(Game.PlayerPed.Handle, (uint)GetHashKey(tat.Key), (uint)GetHashKey(tat.Value)); + AddPedDecorationFromHashes(Game.PlayerPed.Handle, Game.GenerateHashASCII(tat.Key), Game.GenerateHashASCII(tat.Value)); } } else if (menuIndex == 6) // right leg @@ -1707,7 +1707,7 @@ void ApplySavedTattoos() var tat = new KeyValuePair(Tattoo.collectionName, Tattoo.name); if (!currentCharacter.PedTatttoos.RightLegTattoos.Contains(tat)) { - AddPedDecorationFromHashes(Game.PlayerPed.Handle, (uint)GetHashKey(tat.Key), (uint)GetHashKey(tat.Value)); + AddPedDecorationFromHashes(Game.PlayerPed.Handle, Game.GenerateHashASCII(tat.Key), Game.GenerateHashASCII(tat.Value)); } } else if (menuIndex == 7) // badges @@ -1716,7 +1716,7 @@ void ApplySavedTattoos() var tat = new KeyValuePair(Tattoo.collectionName, Tattoo.name); if (!currentCharacter.PedTatttoos.BadgeTattoos.Contains(tat)) { - AddPedDecorationFromHashes(Game.PlayerPed.Handle, (uint)GetHashKey(tat.Key), (uint)GetHashKey(tat.Value)); + AddPedDecorationFromHashes(Game.PlayerPed.Handle, Game.GenerateHashASCII(tat.Key), Game.GenerateHashASCII(tat.Value)); } } else if (menuIndex == 8) // addon @@ -1725,7 +1725,7 @@ void ApplySavedTattoos() var tat = new KeyValuePair(Tattoo.collectionName, Tattoo.name); if (!currentCharacter.PedTatttoos.AddonTattoos.Contains(tat)) { - AddPedDecorationFromHashes(Game.PlayerPed.Handle, (uint)GetHashKey(tat.Key), (uint)GetHashKey(tat.Value)); + AddPedDecorationFromHashes(Game.PlayerPed.Handle, Game.GenerateHashASCII(tat.Key), Game.GenerateHashASCII(tat.Value)); } } }; @@ -2232,7 +2232,7 @@ void ApplySavedTattoos() { if (item == createMaleBtn) { - var model = (uint)GetHashKey("mp_m_freemode_01"); + var model = Game.GenerateHashASCII("mp_m_freemode_01"); if (!HasModelLoaded(model)) { @@ -2267,7 +2267,7 @@ void ApplySavedTattoos() } else if (item == createFemaleBtn) { - var model = (uint)GetHashKey("mp_f_freemode_01"); + var model = Game.GenerateHashASCII("mp_f_freemode_01"); if (!HasModelLoaded(model)) { @@ -3213,7 +3213,7 @@ internal void ChangePlayerHair(int newHairIndex) currentCharacter.PedAppearance.hairStyle = newHairIndex; if (hairOverlays.ContainsKey(newHairIndex)) { - SetPedFacialDecoration(Game.PlayerPed.Handle, (uint)GetHashKey(hairOverlays[newHairIndex].Key), (uint)GetHashKey(hairOverlays[newHairIndex].Value)); + SetPedFacialDecoration(Game.PlayerPed.Handle, Game.GenerateHashASCII(hairOverlays[newHairIndex].Key), Game.GenerateHashASCII(hairOverlays[newHairIndex].Value)); currentCharacter.PedAppearance.HairOverlay = new KeyValuePair(hairOverlays[newHairIndex].Key, hairOverlays[newHairIndex].Value); } } @@ -3366,7 +3366,7 @@ internal async Task AppySavedDataToPed(MultiplayerPedData character, int pedHand SetPedHairColor(pedHandle, appData.hairColor, appData.hairHighlightColor); if (!string.IsNullOrEmpty(appData.HairOverlay.Key) && !string.IsNullOrEmpty(appData.HairOverlay.Value)) { - SetPedFacialDecoration(pedHandle, (uint)GetHashKey(appData.HairOverlay.Key), (uint)GetHashKey(appData.HairOverlay.Value)); + SetPedFacialDecoration(pedHandle, Game.GenerateHashASCII(appData.HairOverlay.Key), Game.GenerateHashASCII(appData.HairOverlay.Value)); } // blemishes SetPedHeadOverlay(pedHandle, 0, appData.blemishesStyle, appData.blemishesOpacity); @@ -3470,7 +3470,7 @@ internal async Task AppySavedDataToPed(MultiplayerPedData character, int pedHand foreach (var tattoo in allTattoos) { - AddPedDecorationFromHashes(pedHandle, (uint)GetHashKey(tattoo.Key), (uint)GetHashKey(tattoo.Value)); + AddPedDecorationFromHashes(pedHandle, Game.GenerateHashASCII(tattoo.Key), Game.GenerateHashASCII(tattoo.Value)); } #endregion } diff --git a/vMenu/menus/PlayerAppearance.cs b/vMenu/menus/PlayerAppearance.cs index 2c66b116..9c799ccf 100644 --- a/vMenu/menus/PlayerAppearance.cs +++ b/vMenu/menus/PlayerAppearance.cs @@ -29,6 +29,7 @@ public class PlayerAppearance private readonly Menu otherPedsMenu = new("Other Peds", "Spawn A Ped"); public static Dictionary AddonPeds; + public static Dictionary WhitelistedPeds; public static int ClothingAnimationType { get; set; } = UserDefaults.PAClothingAnimationType; @@ -342,19 +343,24 @@ void UpdateSavedPedsMenu() var pedBtn = new MenuItem(ped.Key, "Click to spawn this model.") { Label = $"({name})" }; + checkPedWhitelist(ped.Key, pedBtn); + if (!IsModelInCdimage(ped.Value) || !IsModelAPed(ped.Value)) { pedBtn.Enabled = false; pedBtn.LeftIcon = MenuItem.Icon.LOCK; pedBtn.Description = "This ped is not (correctly) streamed. If you are the server owner, please ensure that the ped name and model are valid!"; + } + else + { + checkPedWhitelist(ped.Key, pedBtn); } - addonPedsMenu.AddMenuItem(pedBtn); } addonPedsMenu.OnItemSelect += async (sender, item, index) => { - await SetPlayerSkin((uint)GetHashKey(item.Text), new PedInfo() { version = -1 }, true); + await SetPlayerSkin(Game.GenerateHashASCII(item.Text), new PedInfo() { version = -1 }, true); }; } @@ -386,30 +392,35 @@ void UpdateSavedPedsMenu() foreach (var animal in animalModels) { var animalBtn = new MenuItem(animal.Key, "Click to spawn this animal.") { Label = $"({animal.Value})" }; + checkPedWhitelist(animal.Key, animalBtn); animalsPedsMenu.AddMenuItem(animalBtn); } foreach (var ped in mainModels) { var pedBtn = new MenuItem(ped.Key, "Click to spawn this ped.") { Label = $"({ped.Value})" }; + checkPedWhitelist(ped.Key, pedBtn); mainPedsMenu.AddMenuItem(pedBtn); } foreach (var ped in maleModels) { var pedBtn = new MenuItem(ped.Key, "Click to spawn this ped.") { Label = $"({ped.Value})" }; + checkPedWhitelist(ped.Key, pedBtn); malePedsMenu.AddMenuItem(pedBtn); } foreach (var ped in femaleModels) { var pedBtn = new MenuItem(ped.Key, "Click to spawn this ped.") { Label = $"({ped.Value})" }; + checkPedWhitelist(ped.Key, pedBtn); femalePedsMenu.AddMenuItem(pedBtn); } foreach (var ped in otherPeds) { var pedBtn = new MenuItem(ped.Key, "Click to spawn this ped.") { Label = $"({ped.Value})" }; + checkPedWhitelist(ped.Key, pedBtn); otherPedsMenu.AddMenuItem(pedBtn); } @@ -450,7 +461,7 @@ void ResetMenuFilter(Menu m) async void SpawnPed(Menu m, MenuItem item, int index) { - var model = (uint)GetHashKey(item.Text); + var model = Game.GenerateHashASCII(item.Text); if (m == animalsPedsMenu && !Game.PlayerPed.IsInWater) { switch (item.Text) @@ -761,6 +772,18 @@ void ChangeListItem(MenuListItem item, int newListIndex) }; } + public static void checkPedWhitelist(string ped, MenuItem pedBtn) + { + if (WhitelistedPeds.ContainsKey(ped.ToLower())) + { + if (!vMenuShared.SupplementaryPermissionManager.IsAllowed("PW" + ped.ToLower())) + { + pedBtn.Enabled = false; + pedBtn.LeftIcon = MenuItem.Icon.LOCK; + pedBtn.Description = "Access to this has been restricted by the server owner."; + } + } + } #endregion diff --git a/vMenu/menus/PlayerOptions.cs b/vMenu/menus/PlayerOptions.cs index 94911aa5..77660db4 100644 --- a/vMenu/menus/PlayerOptions.cs +++ b/vMenu/menus/PlayerOptions.cs @@ -372,7 +372,7 @@ private void CreateMenu() else if (item == unlimitedStaminaCheckbox) { PlayerStamina = _checked; - StatSetInt((uint)GetHashKey("MP0_STAMINA"), _checked ? 100 : 0, true); + StatSetInt(Game.GenerateHashASCII("MP0_STAMINA"), _checked ? 100 : 0, true); } // Fast run toggled. else if (item == fastRunCheckbox) diff --git a/vMenu/menus/Recording.cs b/vMenu/menus/Recording.cs index dcbdab5a..89fe9001 100644 --- a/vMenu/menus/Recording.cs +++ b/vMenu/menus/Recording.cs @@ -48,7 +48,7 @@ private void CreateMenu() } else if (item == openPmGallery) { - ActivateFrontendMenu((uint)GetHashKey("FE_MENU_VERSION_MP_PAUSE"), true, 3); + ActivateFrontendMenu(Game.GenerateHashASCII("FE_MENU_VERSION_MP_PAUSE"), true, 3); } else if (item == takePic) { diff --git a/vMenu/menus/VehicleOptions.cs b/vMenu/menus/VehicleOptions.cs index 17da329b..39490447 100644 --- a/vMenu/menus/VehicleOptions.cs +++ b/vMenu/menus/VehicleOptions.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Drawing; using System.Linq; using CitizenFX.Core; @@ -460,27 +461,8 @@ private void CreateMenu() } else { - var veh = GetVehicle(); - if (veh != null && veh.Exists() && GetVehicle().Driver == Game.PlayerPed) - { - SetVehicleHasBeenOwnedByPlayer(veh.Handle, false); - SetEntityAsMissionEntity(veh.Handle, false, false); - veh.Delete(); - } - else - { - if (!Game.PlayerPed.IsInVehicle()) - { - Notify.Alert(CommonErrors.NoVehicle); - } - else - { - Notify.Alert("You need to be in the driver's seat if you want to delete a vehicle."); - } - - } + DeleteVehicle(); DeleteConfirmMenu.GoBack(); - menu.GoBack(); } }; #endregion @@ -2152,7 +2134,7 @@ public void UpdateMods(int selectedIndex = 0) } var headlightsButton = new MenuItem("Headlights"); - var headlightsMenu = new Menu("Headlights"); + var headlightsMenu = new Menu("Headlights", "headlights"); var xenonHeadlights = new MenuCheckboxItem("Xenon Headlights", "Enable or disable ~b~xenon ~s~headlights.", IsToggleModOn(veh.Handle, 22)); headlightsMenu.AddMenuItem(xenonHeadlights); var currentHeadlightColor = GetHeadlightsColorForVehicle(veh); @@ -2214,7 +2196,7 @@ public void UpdateMods(int selectedIndex = 0) } var tireSmokeButton = new MenuItem("Tire Smoke"); - var tireSmokeMenu = new Menu("Tire Smoke"); + var tireSmokeMenu = new Menu("Tire Smoke", "Tire Smoke"); // Create a list of tire smoke options. var tireSmokes = new List() { "Red", "Orange", "Yellow", "Gold", "Light Green", "Dark Green", "Light Blue", "Dark Blue", "Purple", "Pink", "Black" }; var tireSmokeColors = new Dictionary() @@ -2541,7 +2523,7 @@ internal static int GetHeadlightsColorForVehicle(Vehicle vehicle) /// /// /// - private System.Drawing.Color GetColorFromIndex(int index) + private static System.Drawing.Color GetColorFromIndex(int index) { if (index is >= 0 and < 13) { @@ -2586,22 +2568,22 @@ public enum RGBType public static void CreateCustomColourMenu(Menu menu, RGBType type = RGBType.primaryPaint) { - var hexColour = new MenuItem("Hex Colour Code"); + var hexColour = new MenuItem("Hex Color Code"); var typeList = new MenuListItem("Paint Finish", Enum.GetNames(typeof(Colour_Types)).ToList(), 0); int r = 0, g = 0, b = 0; - var redColour = new MenuSliderItem("Red Colour", 0, 255, 128, true) + var redColour = new MenuSliderItem("Red Color", 0, 255, 128, true) { BarColor = System.Drawing.Color.FromArgb(155, 0, 0, 0), BackgroundColor = System.Drawing.Color.FromArgb(200, 79, 79, 79), }; - var greenColour = new MenuSliderItem("Green Colour", 0, 255, 128, true) + var greenColour = new MenuSliderItem("Green Color", 0, 255, 128, true) { BarColor = System.Drawing.Color.FromArgb(155, 0, 0, 0), BackgroundColor = System.Drawing.Color.FromArgb(200, 79, 79, 79), }; - var blueColour = new MenuSliderItem("Blue Colour", 0, 255, 128, true) + var blueColour = new MenuSliderItem("Blue Color", 0, 255, 128, true) { BarColor = System.Drawing.Color.FromArgb(155, 0, 0, 0), BackgroundColor = System.Drawing.Color.FromArgb(200, 79, 79, 79), @@ -2634,9 +2616,10 @@ public static void CreateCustomColourMenu(Menu menu, RGBType type = RGBType.prim { if (IsToggleModOn(vehicle.Handle, 22)) { - r = VehicleData.NeonLightColors[GetHeadlightsColorForVehicle(vehicle)][0]; - g = VehicleData.NeonLightColors[GetHeadlightsColorForVehicle(vehicle)][1]; - b = VehicleData.NeonLightColors[GetHeadlightsColorForVehicle(vehicle)][2]; + int headlight = GetHeadlightsColorForVehicle(vehicle) < 0 ? 0 : GetHeadlightsColorForVehicle(vehicle); + r = VehicleData.NeonLightColors[headlight][0]; + g = VehicleData.NeonLightColors[headlight][1]; + b = VehicleData.NeonLightColors[headlight][2]; } } @@ -2645,13 +2628,13 @@ public static void CreateCustomColourMenu(Menu menu, RGBType type = RGBType.prim GetVehicleTyreSmokeColor(vehicle.Handle, ref r, ref g, ref b); - redColour.Text = $"Red Colour ({r})"; + redColour.Text = $"Red Color ({r})"; redColour.Position = r; - greenColour.Text = $"Green Colour ({g})"; + greenColour.Text = $"Green Color ({g})"; greenColour.Position = g; - blueColour.Text = $"Blue Colour ({b})"; + blueColour.Text = $"Blue Color ({b})"; blueColour.Position = b; redColour.BarColor = System.Drawing.Color.FromArgb(255, redColour.Position, greenColour.Position, blueColour.Position); @@ -2665,7 +2648,7 @@ public static void CreateCustomColourMenu(Menu menu, RGBType type = RGBType.prim if (item == hexColour) { string hexValue = redColour.Position.ToString("X2") + greenColour.Position.ToString("X2") + blueColour.Position.ToString("X2"); - var result = await GetUserInput(windowTitle: "Enter Colour Hex", defaultText: (hexValue).Replace("#", ""), maxInputLength: 6); + var result = await GetUserInput(windowTitle: "Enter Color Hex", defaultText: (hexValue).Replace("#", ""), maxInputLength: 6); if (!string.IsNullOrEmpty(result)) { if (IsHex(result)) @@ -2690,13 +2673,13 @@ public static void CreateCustomColourMenu(Menu menu, RGBType type = RGBType.prim greenColour.BarColor = System.Drawing.Color.FromArgb(255, red, green, blue); blueColour.BarColor = System.Drawing.Color.FromArgb(255, red, green, blue); - redColour.Text = $"Red Colour ({red})"; + redColour.Text = $"Red Color ({red})"; redColour.Position = red; - greenColour.Text = $"Green Colour ({green})"; + greenColour.Text = $"Green Color ({green})"; greenColour.Position = green; - blueColour.Text = $"Blue Colour ({blue})"; + blueColour.Text = $"Blue Color ({blue})"; blueColour.Position = blue; } } @@ -2722,9 +2705,10 @@ public static void CreateCustomColourMenu(Menu menu, RGBType type = RGBType.prim { if (IsToggleModOn(vehicle.Handle, 22)) { - r = VehicleData.NeonLightColors[GetHeadlightsColorForVehicle(vehicle)][0]; - g = VehicleData.NeonLightColors[GetHeadlightsColorForVehicle(vehicle)][1]; - b = VehicleData.NeonLightColors[GetHeadlightsColorForVehicle(vehicle)][2]; + int headlight = GetHeadlightsColorForVehicle(vehicle) < 0 ? 0 : GetHeadlightsColorForVehicle(vehicle); + r = VehicleData.NeonLightColors[headlight][0]; + g = VehicleData.NeonLightColors[headlight][1]; + b = VehicleData.NeonLightColors[headlight][2]; } } @@ -2746,7 +2730,7 @@ public static void CreateCustomColourMenu(Menu menu, RGBType type = RGBType.prim else if (type == RGBType.tiresmoke) vehicle.Mods.TireSmokeColor = System.Drawing.Color.FromArgb(255, newPosition, g, b); - redColour.Text = $"Red Colour ({newPosition})"; + redColour.Text = $"Red Color ({newPosition})"; } if (sliderItem == greenColour) { @@ -2761,7 +2745,7 @@ public static void CreateCustomColourMenu(Menu menu, RGBType type = RGBType.prim else if (type == RGBType.tiresmoke) vehicle.Mods.TireSmokeColor = System.Drawing.Color.FromArgb(255, r, newPosition, b); - greenColour.Text = $"Green Colour ({newPosition})"; + greenColour.Text = $"Green Color ({newPosition})"; } if (sliderItem == blueColour) { @@ -2776,7 +2760,7 @@ public static void CreateCustomColourMenu(Menu menu, RGBType type = RGBType.prim else if (type == RGBType.tiresmoke) vehicle.Mods.TireSmokeColor = System.Drawing.Color.FromArgb(255, r, g, newPosition); - blueColour.Text = $"Blue Colour ({newPosition})"; + blueColour.Text = $"Blue Color ({newPosition})"; } redColour.BarColor = System.Drawing.Color.FromArgb(255, redColour.Position, greenColour.Position, blueColour.Position); greenColour.BarColor = System.Drawing.Color.FromArgb(255, redColour.Position, greenColour.Position, blueColour.Position); @@ -2807,42 +2791,43 @@ public static void CreateCustomColourMenu(Menu menu, RGBType type = RGBType.prim } else if (type == RGBType.underglow) { - int red = vehicle.Mods.TireSmokeColor.R; - int green = vehicle.Mods.NeonLightsColor.G; - int blue = vehicle.Mods.NeonLightsColor.B; + Color underglow = GetColorFromIndex(newIndex); + int red = underglow.R; + int green = underglow.G; + int blue = underglow.B; redColour.BarColor = System.Drawing.Color.FromArgb(255, red, green, blue); greenColour.BarColor = System.Drawing.Color.FromArgb(255, red, green, blue); blueColour.BarColor = System.Drawing.Color.FromArgb(255, red, green, blue); - redColour.Text = $"Red Colour ({red})"; + redColour.Text = $"Red Color ({red})"; redColour.Position = red; - greenColour.Text = $"Green Colour ({green})"; + greenColour.Text = $"Green Color ({green})"; greenColour.Position = green; - blueColour.Text = $"Blue Colour ({blue})"; + blueColour.Text = $"Blue Color ({blue})"; blueColour.Position = blue; } else if (type == RGBType.headlight) { - - int red = VehicleData.NeonLightColors[GetHeadlightsColorForVehicle(vehicle)][0]; - int green = VehicleData.NeonLightColors[GetHeadlightsColorForVehicle(vehicle)][1]; - int blue = VehicleData.NeonLightColors[GetHeadlightsColorForVehicle(vehicle)][2]; + int headlight = GetHeadlightsColorForVehicle(vehicle) < 0 ? 0 : GetHeadlightsColorForVehicle(vehicle); + int red = VehicleData.NeonLightColors[headlight][0]; + int green = VehicleData.NeonLightColors[headlight][1]; + int blue = VehicleData.NeonLightColors[headlight][2]; redColour.BarColor = System.Drawing.Color.FromArgb(255, red, green, blue); greenColour.BarColor = System.Drawing.Color.FromArgb(255, red, green, blue); blueColour.BarColor = System.Drawing.Color.FromArgb(255, red, green, blue); - redColour.Text = $"Red Colour ({red})"; + redColour.Text = $"Red Color ({red})"; redColour.Position = red; - greenColour.Text = $"Green Colour ({green})"; + greenColour.Text = $"Green Color ({green})"; greenColour.Position = green; - blueColour.Text = $"Blue Colour ({blue})"; + blueColour.Text = $"Blue Color ({blue})"; blueColour.Position = blue; } else if (type == RGBType.tiresmoke) @@ -2855,13 +2840,13 @@ public static void CreateCustomColourMenu(Menu menu, RGBType type = RGBType.prim greenColour.BarColor = System.Drawing.Color.FromArgb(255, red, green, blue); blueColour.BarColor = System.Drawing.Color.FromArgb(255, red, green, blue); - redColour.Text = $"Red Colour ({red})"; + redColour.Text = $"Red Color ({red})"; redColour.Position = red; - greenColour.Text = $"Green Colour ({green})"; + greenColour.Text = $"Green Color ({green})"; greenColour.Position = green; - blueColour.Text = $"Blue Colour ({blue})"; + blueColour.Text = $"Blue Color ({blue})"; blueColour.Position = blue; } diff --git a/vMenu/menus/VehicleSpawner.cs b/vMenu/menus/VehicleSpawner.cs index 6683ea56..0a6c6dee 100644 --- a/vMenu/menus/VehicleSpawner.cs +++ b/vMenu/menus/VehicleSpawner.cs @@ -7,6 +7,8 @@ using vMenuClient.data; +using vMenuShared; + using static CitizenFX.Core.Native.API; using static vMenuClient.CommonFunctions; using static vMenuShared.PermissionsManager; @@ -18,6 +20,7 @@ public class VehicleSpawner // Variables private Menu menu; public static Dictionary AddonVehicles; + public static Dictionary WhitelistVehicles; public bool SpawnInVehicle { get; private set; } = UserDefaults.VehicleSpawnerSpawnInside; public bool ReplaceVehicle { get; private set; } = UserDefaults.VehicleSpawnerReplacePrevious; @@ -91,6 +94,13 @@ private void CreateMenu() Label = $"({veh.Key})", ItemData = veh.Key // store the model name in the button data. }; + + if (!SupplementaryPermissionManager.IsAllowed("VW" + veh.Key)) + { + carBtn.Enabled = false; + carBtn.LeftIcon = MenuItem.Icon.LOCK; + carBtn.Description = "Access to this has been restricted by the server owner."; + } // This should be impossible to be false, but we check it anyway. if (IsModelInCdimage(veh.Value)) @@ -305,7 +315,7 @@ private void CreateMenu() // Get the localized vehicle name, if it's "NULL" (no label found) then use the "properCasedModelName" created above. var vehName = GetVehDisplayNameFromModel(veh) != "NULL" ? GetVehDisplayNameFromModel(veh) : properCasedModelName; var vehModelName = veh; - var model = (uint)GetHashKey(vehModelName); + var model = Game.GenerateHashASCII(vehModelName); var topSpeed = Map(GetVehicleModelEstimatedMaxSpeed(model), 0f, speedValues[vehClass], 0f, 1f); var acceleration = Map(GetVehicleModelAcceleration(model), 0f, accelerationValues[vehClass], 0f, 1f); @@ -347,6 +357,16 @@ private void CreateMenu() ItemData = new float[4] { topSpeed, acceleration, maxBraking, maxTraction } }; vehicleClassMenu.AddMenuItem(vehBtn); + + if (WhitelistVehicles.ContainsKey(veh.ToLower())) + { + if (!SupplementaryPermissionManager.IsAllowed("VW" + veh.ToLower())) + { + vehBtn.Enabled = false; + vehBtn.LeftIcon = MenuItem.Icon.LOCK; + vehBtn.Description = "Access to this has been restricted by the server owner."; + } + } } else { @@ -359,7 +379,7 @@ private void CreateMenu() vehicleClassMenu.AddMenuItem(vehBtn); vehBtn.RightIcon = MenuItem.Icon.LOCK; } - + // Mark duplicate as true and break from the loop because we already found the duplicate. duplicate = true; break; @@ -378,6 +398,16 @@ private void CreateMenu() ItemData = new float[4] { topSpeed, acceleration, maxBraking, maxTraction } }; vehicleClassMenu.AddMenuItem(vehBtn); + + if (WhitelistVehicles.ContainsKey(veh.ToLower())) + { + if (!SupplementaryPermissionManager.IsAllowed("VW" + veh.ToLower())) + { + vehBtn.Enabled = false; + vehBtn.LeftIcon = MenuItem.Icon.LOCK; + vehBtn.Description = "Access to this has been restricted by the server owner."; + } + } } else { diff --git a/vMenu/menus/WeaponOptions.cs b/vMenu/menus/WeaponOptions.cs index bcd1fc68..bf42e9aa 100644 --- a/vMenu/menus/WeaponOptions.cs +++ b/vMenu/menus/WeaponOptions.cs @@ -23,6 +23,7 @@ public class WeaponOptions public bool UnlimitedParachutes { get; private set; } = UserDefaults.WeaponsUnlimitedParachutes; public static Dictionary AddonWeapons = new(); + public static Dictionary WeaponWhitelist = new(); private Dictionary weaponInfo; private Dictionary addonWeaponInfo; @@ -113,6 +114,16 @@ private void CreateMenu() ItemData = stats }; + string spawnName = addonWeapon.SpawnName; + + if (!vMenuShared.SupplementaryPermissionManager.IsAllowed("WW" + spawnName.ToLower().Replace("weapon_", ""))) + { + addonWeaponItem.Enabled = false; + addonWeaponItem.LeftIcon = MenuItem.Icon.LOCK; + addonWeaponItem.Description = "Access to this has been restricted by the server owner."; + } + + addonWeaponInfo.Add(addonWeaponMenu, addonWeapon); var getOrRemoveWeapon = new MenuItem("Equip/Remove Weapon", "Add or remove this weapon to/form your inventory.") @@ -363,15 +374,15 @@ void EquipWeaponComponent(uint weaponHash, uint componentHash) { if (item == togglePrimary) { - if (HasPedGotWeapon(Game.PlayerPed.Handle, (uint)GetHashKey("gadget_parachute"), false)) + if (HasPedGotWeapon(Game.PlayerPed.Handle, Game.GenerateHashASCII("gadget_parachute"), false)) { Subtitle.Custom("Primary parachute removed."); - RemoveWeaponFromPed(Game.PlayerPed.Handle, (uint)GetHashKey("gadget_parachute")); + RemoveWeaponFromPed(Game.PlayerPed.Handle, Game.GenerateHashASCII("gadget_parachute")); } else { Subtitle.Custom("Primary parachute added."); - GiveWeaponToPed(Game.PlayerPed.Handle, (uint)GetHashKey("gadget_parachute"), 0, false, false); + GiveWeaponToPed(Game.PlayerPed.Handle, Game.GenerateHashASCII("gadget_parachute"), 0, false, false); } } else if (item == toggleReserve) @@ -801,7 +812,7 @@ void EquipWeaponComponent(uint weaponHash, uint componentHash) SetPedAmmo(Game.PlayerPed.Handle, avw.Hash, ammo); } - SetCurrentPedWeapon(Game.PlayerPed.Handle, (uint)GetHashKey("weapon_unarmed"), true); + SetCurrentPedWeapon(Game.PlayerPed.Handle, Game.GenerateHashASCII("weapon_unarmed"), true); } else if (item == removeAllWeapons) { diff --git a/vMenu/vMenuClient.csproj b/vMenu/vMenuClient.csproj index 939eb3ea..7c974cb9 100644 --- a/vMenu/vMenuClient.csproj +++ b/vMenu/vMenuClient.csproj @@ -11,8 +11,7 @@ false - - + @@ -51,7 +50,7 @@ - + diff --git a/vMenuServer/MainServer.cs b/vMenuServer/MainServer.cs index 28419250..c6fd8d0a 100644 --- a/vMenuServer/MainServer.cs +++ b/vMenuServer/MainServer.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Threading.Tasks; @@ -185,6 +186,7 @@ private int DynamicWeatherMinutes "XMAS", "HALLOWEEN" }; + #endregion #region Constructor @@ -224,10 +226,11 @@ public MainServer() })); // check addons file for errors + Dictionary> addonsData = new(); var addons = LoadResourceFile(GetCurrentResourceName(), "config/addons.json") ?? "{}"; try { - JsonConvert.DeserializeObject>>(addons); + addonsData = JsonConvert.DeserializeObject>>(addons); // If the above crashes, then the json is invalid and it'll throw warnings in the console. } catch (JsonReaderException ex) @@ -235,6 +238,22 @@ public MainServer() Debug.WriteLine($"\n\n^1[vMenu] [ERROR] ^7Your addons.json file contains a problem! Error details: {ex.Message}\n\n"); } + // check model-whitelists file for errors + Dictionary> whitelistData = new(); + var whitelist = LoadResourceFile(GetCurrentResourceName(), "config/model-whitelists.json") ?? "{}"; + try + { + whitelistData = JsonConvert.DeserializeObject>>(whitelist); + // If the above crashes, then the json is invalid and it'll throw warnings in the console. + } + catch (JsonReaderException ex) + { + Debug.WriteLine($"\n\n^1[vMenu] [ERROR] ^7Your model-whitelists.json file contains a problem! Error details: {ex.Message}\n\n"); + } + + // setup addon permissions + SetupAddonPerms(whitelistData, addonsData); + // check extras file for errors string extras = LoadResourceFile(GetCurrentResourceName(), "config/extras.json") ?? "{}"; try @@ -528,7 +547,7 @@ internal void ServerCommandHandler(int source, List args, string _) [EventHandler("vMenu:GetOutOfCar")] internal void GetOutOfCar([FromSource] Player source, int vehicleNetId) { - if (!PermissionsManager.IsAllowed(PermissionsManager.Permission.PVKickPassengers, source) && !PermissionsManager.IsAllowed(PermissionsManager.Permission.PVAll, source)) + if (!PermissionsManager.IsAllowed(PermissionsManager.Permission.PVKickPassengers, source)) { BanManager.BanCheater(source); return; @@ -707,7 +726,7 @@ private void RefreshWeather() [EventHandler("vMenu:UpdateServerWeather")] internal void UpdateWeather([FromSource] Player source, string newWeather, bool dynamicWeatherNew, bool enableSnow) { - if (!PermissionsManager.IsAllowed(PermissionsManager.Permission.WOSetWeather, source) && !PermissionsManager.IsAllowed(PermissionsManager.Permission.WOAll, source)) + if (!PermissionsManager.IsAllowed(PermissionsManager.Permission.WOSetWeather, source)) { BanManager.BanCheater(source); return; @@ -731,7 +750,7 @@ internal void UpdateWeather([FromSource] Player source, string newWeather, bool [EventHandler("vMenu:UpdateServerBlackout")] internal void UpdateBlackout([FromSource] Player source, bool value) { - if (!PermissionsManager.IsAllowed(PermissionsManager.Permission.WOBlackout, source) && !PermissionsManager.IsAllowed(PermissionsManager.Permission.WOAll, source)) + if (!PermissionsManager.IsAllowed(PermissionsManager.Permission.WOBlackout, source)) { BanManager.BanCheater(source); return; @@ -743,7 +762,7 @@ internal void UpdateBlackout([FromSource] Player source, bool value) [EventHandler("vMenu:UpdateServerVehicleBlackout")] internal void UpdateVehicleBlackout([FromSource] Player source, bool value) { - if (!PermissionsManager.IsAllowed(PermissionsManager.Permission.WOVehBlackout, source) && !PermissionsManager.IsAllowed(PermissionsManager.Permission.WOAll, source)) + if (!PermissionsManager.IsAllowed(PermissionsManager.Permission.WOVehBlackout, source)) { BanManager.BanCheater(source); return; @@ -759,11 +778,10 @@ internal void UpdateVehicleBlackout([FromSource] Player source, bool value) [EventHandler("vMenu:UpdateServerWeatherCloudsType")] internal void UpdateWeatherCloudsType([FromSource] Player source, bool removeClouds) { - bool allWOPermissions = PermissionsManager.IsAllowed(PermissionsManager.Permission.WOAll, source); if (removeClouds) { - if (!PermissionsManager.IsAllowed(PermissionsManager.Permission.WORemoveClouds, source) && !allWOPermissions) + if (!PermissionsManager.IsAllowed(PermissionsManager.Permission.WORemoveClouds, source)) { BanManager.BanCheater(source); return; @@ -773,7 +791,7 @@ internal void UpdateWeatherCloudsType([FromSource] Player source, bool removeClo } else { - if (!PermissionsManager.IsAllowed(PermissionsManager.Permission.WORandomizeClouds, source) && !allWOPermissions) + if (!PermissionsManager.IsAllowed(PermissionsManager.Permission.WORandomizeClouds, source)) { BanManager.BanCheater(source); return; @@ -790,15 +808,43 @@ internal void UpdateWeatherCloudsType([FromSource] Player source, bool removeClo /// /// /// + /// [EventHandler("vMenu:UpdateServerTime")] - internal void UpdateTime([FromSource] Player source, int newHours, int newMinutes) + internal async void UpdateTime([FromSource] Player source, int newHours, int newMinutes, bool newFreezeTime) { - if (!PermissionsManager.IsAllowed(PermissionsManager.Permission.TOSetTime, source) && !PermissionsManager.IsAllowed(PermissionsManager.Permission.TOAll, source)) + if (!PermissionsManager.IsAllowed(PermissionsManager.Permission.TOSetTime, source)) { BanManager.BanCheater(source); return; } + if (GetSettingsBool(Setting.vmenu_smooth_time_transitions)) + { + CurrentHours = CurrentHours; + CurrentMinutes = CurrentMinutes; + FreezeTime = true; + while (newHours != CurrentHours) + { + if ((CurrentMinutes + 1) > 59) + { + CurrentMinutes = 0; + if ((CurrentHours + 1) > 23) + { + CurrentHours = 0; + } + else + { + CurrentHours++; + } + } + else + { + CurrentMinutes = CurrentMinutes + 5; + } + await Delay(0); + } + FreezeTime = newFreezeTime; + } CurrentHours = newHours; CurrentMinutes = newMinutes; } @@ -811,7 +857,7 @@ internal void UpdateTime([FromSource] Player source, int newHours, int newMinute [EventHandler("vMenu:FreezeServerTime")] internal void FreezeServerTime([FromSource] Player source, bool freezeTime) { - if (!PermissionsManager.IsAllowed(PermissionsManager.Permission.TOFreezeTime, source) && !PermissionsManager.IsAllowed(PermissionsManager.Permission.TOAll, source)) + if (!PermissionsManager.IsAllowed(PermissionsManager.Permission.TOFreezeTime, source)) { BanManager.BanCheater(source); return; @@ -831,7 +877,7 @@ internal void FreezeServerTime([FromSource] Player source, bool freezeTime) [EventHandler("vMenu:KickPlayer")] internal void KickPlayer([FromSource] Player source, int target, string kickReason = "You have been kicked from the server.") { - if (!PermissionsManager.IsAllowed(PermissionsManager.Permission.OPKick, source) && !PermissionsManager.IsAllowed(PermissionsManager.Permission.OPAll, source)) + if (!PermissionsManager.IsAllowed(PermissionsManager.Permission.OPKick, source)) { BanManager.BanCheater(source); return; @@ -866,7 +912,7 @@ internal void KickPlayer([FromSource] Player source, int target, string kickReas [EventHandler("vMenu:KillPlayer")] internal void KillPlayer([FromSource] Player source, int target) { - if (!PermissionsManager.IsAllowed(PermissionsManager.Permission.OPKill, source) && !PermissionsManager.IsAllowed(PermissionsManager.Permission.OPAll, source)) + if (!PermissionsManager.IsAllowed(PermissionsManager.Permission.OPKill, source)) { BanManager.BanCheater(source); return; @@ -890,7 +936,7 @@ internal void KillPlayer([FromSource] Player source, int target) [EventHandler("vMenu:SummonPlayer")] internal async void SummonPlayer([FromSource] Player source, int target, int numberOfSeats) { - if (!PermissionsManager.IsAllowed(PermissionsManager.Permission.OPSummon, source) && !PermissionsManager.IsAllowed(PermissionsManager.Permission.OPAll, source)) + if (!PermissionsManager.IsAllowed(PermissionsManager.Permission.OPSummon, source)) { BanManager.BanCheater(source); return; @@ -968,7 +1014,7 @@ internal async void SummonPlayer([FromSource] Player source, int target, int num [EventHandler("vMenu:SendMessageToPlayer")] internal void SendPrivateMessage([FromSource] Player source, int target, string message) { - if (!PermissionsManager.IsAllowed(PermissionsManager.Permission.OPSendMessage, source) && !PermissionsManager.IsAllowed(PermissionsManager.Permission.OPAll, source)) + if (!PermissionsManager.IsAllowed(PermissionsManager.Permission.OPSendMessage, source)) { BanManager.BanCheater(source); return; @@ -1002,7 +1048,7 @@ internal void SendPrivateMessage([FromSource] Player source, int target, string foreach (string playerHandle in joinedPlayers) { - if (!PermissionsManager.IsAllowed(PermissionsManager.Permission.OPSeePrivateMessages, playerHandle) && !PermissionsManager.IsAllowed(PermissionsManager.Permission.OPAll, playerHandle)) + if (!PermissionsManager.IsAllowed(PermissionsManager.Permission.OPSeePrivateMessages, playerHandle)) { continue; } @@ -1044,7 +1090,7 @@ private static void KickLog(string kickLogMesage) [EventHandler("vMenu:SaveTeleportLocation")] internal void AddTeleportLocation([FromSource] Player source, string locationJson) { - if (!PermissionsManager.IsAllowed(PermissionsManager.Permission.MSTeleportSaveLocation, source) && !PermissionsManager.IsAllowed(PermissionsManager.Permission.MSAll, source)) + if (!PermissionsManager.IsAllowed(PermissionsManager.Permission.MSTeleportSaveLocation, source)) { BanManager.BanCheater(source); return; @@ -1094,7 +1140,7 @@ internal void GetPlayerCoords([FromSource] Player source, long rpcId, int player { var coords = Vector3.Zero; - if (PermissionsManager.IsAllowed(PermissionsManager.Permission.OPTeleport, source) || PermissionsManager.IsAllowed(PermissionsManager.Permission.OPAll, source)) + if (PermissionsManager.IsAllowed(PermissionsManager.Permission.OPTeleport, source)) { Player targetPlayer = GetPlayerFromServerId(playerId); @@ -1122,7 +1168,7 @@ private IEnumerable GetJoinQuitNotifPlayers() foreach (string playerHandle in joinedPlayers) { - if (!PermissionsManager.IsAllowed(PermissionsManager.Permission.MSJoinQuitNotifs, playerHandle) && !PermissionsManager.IsAllowed(PermissionsManager.Permission.MSAll, playerHandle)) + if (!PermissionsManager.IsAllowed(PermissionsManager.Permission.MSJoinQuitNotifs, playerHandle)) { continue; } @@ -1150,6 +1196,7 @@ private async Task PlayersFirstTick() joinedPlayers.Add(player.Handle); PermissionsManager.SetPermissionsForPlayer(player); + SupplementaryPermissionManager.SetPermissionsForPlayer(player); } } @@ -1159,6 +1206,7 @@ internal void OnPlayerJoining([FromSource] Player sourcePlayer) joinedPlayers.Add(sourcePlayer.Handle); PermissionsManager.SetPermissionsForPlayer(sourcePlayer); + SupplementaryPermissionManager.SetPermissionsForPlayer(sourcePlayer); string sourcePlayerName = sourcePlayer.Name; @@ -1188,6 +1236,52 @@ internal void OnPlayerDropped([FromSource] Player sourcePlayer, string reason) #endregion #region Utilities + private void SetupAddonPerms(Dictionary> whitelists, Dictionary> addons) + { + if (whitelists.ContainsKey("whitelistedweapons")) + { + foreach (var whitelist in whitelists["whitelistedweapons"]) + { + if (!SupplementaryPermissionManager.Permission.Contains("WW" + whitelist.ToLower().Replace("weapon_", ""))) + { + SupplementaryPermissionManager.Permission.Add("WW" + whitelist.ToLower().Replace("weapon_", "")); + } + } + } + if (whitelists.ContainsKey("whitelistedvehicle")) + { + foreach (var whitelist in whitelists["whitelistedvehicle"]) + { + if (!SupplementaryPermissionManager.Permission.Contains("VW" + whitelist.ToLower())) + { + SupplementaryPermissionManager.Permission.Add("VW" + whitelist.ToLower()); + } + } + } + if (whitelists.ContainsKey("whitelistedpeds")) + { + foreach (var whitelist in whitelists["whitelistedpeds"]) + { + if (!SupplementaryPermissionManager.Permission.Contains("PW" + whitelist.ToLower())) + { + SupplementaryPermissionManager.Permission.Add("PW" + whitelist.ToLower()); + } + } + } + + List supplementaryPermissions = [ + "#################################################################", + "# THIS IS A TEMPLATE FILE. #", + "# DO NOT EDIT, MAKE A COPY AND EDIT THE COPY. #", + "#################################################################", + ]; + foreach (string permission in SupplementaryPermissionManager.Permission) + { + supplementaryPermissions.Add("add_ace builtin.everyone \"" + SupplementaryPermissionManager.GetAceName(permission) + "\" allow"); + } + Directory.CreateDirectory(Path.Combine(GetResourcePath(GetCurrentResourceName()), "config", "templates")); + File.WriteAllLines(Path.Combine(GetResourcePath(GetCurrentResourceName()), "config", "templates", "SupplementaryPermissionTemplate.cfg"), supplementaryPermissions.ToArray()); + } private Player GetPlayerFromServerId(string serverId) { if (!int.TryParse(serverId, out int serverIdInt)) diff --git a/vMenuServer/config/model-whitelists.json b/vMenuServer/config/model-whitelists.json new file mode 100644 index 00000000..ca3801e9 --- /dev/null +++ b/vMenuServer/config/model-whitelists.json @@ -0,0 +1,23 @@ +{ + // Any model you list here will have a permission generated that you can use + // inside the permissions.cfg file to give people access to use that model. + // + // After entering the model names here and starting vMenu, the + // config/templates/SupplementaryPermissionTemplate.cfg file will be updated to show you which + // permissions are available, and provides an example usage. + // + // Copy those entries to your permissions.cfg to start configuring them + // for the groups that you want. + "whitelistedvehicle": [ + "whitelistedvehiclename1", + "whitelistedvehiclename2" + ], + "whitelistedpeds": [ + "whitelistedpedname1", + "whitelistedpedname2" + ], + "whitelistedweapons": [ + "whitelistedweaponname1", + "whitelistedweaponname2" + ] +} \ No newline at end of file diff --git a/vMenuServer/config/permissions.cfg b/vMenuServer/config/permissions.cfg index 6c6df4a6..aebb7ec7 100644 --- a/vMenuServer/config/permissions.cfg +++ b/vMenuServer/config/permissions.cfg @@ -114,6 +114,8 @@ setr vmenu_enable_snow false setr vmenu_enable_time_sync true # Set this to true if you want time to be frozen by default. setr vmenu_freeze_time false +# Enables smooth time transitions. +setr vmenu_smooth_time_transitions true # This setting determines how long one in-game minute lasts in real time. # By default, one GTA V minute, takes 2 seconds (2000 miliseconds). # The value here is measured in miliseconds, and must be a positive number at least greater than 100. @@ -136,6 +138,11 @@ setr vmenu_prevent_extras_when_damaged false setr vmenu_allowed_engine_damage_for_extra_change 800 # This is the amount of body damage before the extras will be blocked. Value must be between 0 and 1000 (inclusive) setr vmenu_allowed_body_damage_for_extra_change 800 +# This setting adjusts the vehicle spawning ratelimit in seconds. Value must be between 0 and infinity +setr vmenu_vehicle_spawn_rate_limit 5 +# This setting adjusts the "vMenu:DV" command delete distance. +setr vmenu_delete_vehicle_distance 5.0 + ### MP Ped options ### # Setting this to true will enable a 3D ped preview when viewing saved MP Peds. @@ -296,6 +303,7 @@ add_ace builtin.everyone "vMenu.VehicleOptions.All" allow #################################### add_ace builtin.everyone "vMenu.VehicleSpawner.Menu" allow add_ace builtin.everyone "vMenu.VehicleSpawner.All" allow +#add_ace builtin.everyone "vMenu.VehicleSpawner.BypassRateLimit" allow #add_ace builtin.everyone "vMenu.VehicleSpawner.DisableReplacePrevious" allow #add_ace builtin.everyone "vMenu.VehicleSpawner.SpawnByName" allow #add_ace builtin.everyone "vMenu.VehicleSpawner.Addon" allow # allows you to spawn an addon car from the Addon Vehicles list. diff --git a/vMenuServer/vMenuServer.csproj b/vMenuServer/vMenuServer.csproj index 5959069d..a596abcc 100644 --- a/vMenuServer/vMenuServer.csproj +++ b/vMenuServer/vMenuServer.csproj @@ -14,8 +14,7 @@ x64 - - + @@ -35,9 +34,6 @@ Always - - Always -