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 index 2c94e769..8ef9944c 100644 --- a/SharedClasses/SupplementaryPermissionManager.cs +++ b/SharedClasses/SupplementaryPermissionManager.cs @@ -124,7 +124,7 @@ private static bool IsAllowedServer(string permission, string playerHandle) return false; } - return IsPlayerAceAllowed(playerHandle, GetAceName(permission)); + return GetPermissionAndParentPermissions(permission).Any(p => IsPlayerAceAllowed(playerHandle, GetAceName(p))); } #endif diff --git a/vMenu/CommonFunctions.cs b/vMenu/CommonFunctions.cs index 78b40f4e..4234228f 100644 --- a/vMenu/CommonFunctions.cs +++ b/vMenu/CommonFunctions.cs @@ -15,6 +15,7 @@ using static CitizenFX.Core.UI.Screen; using static vMenuShared.PermissionsManager; +using vMenuShared; namespace vMenuClient { @@ -1225,6 +1226,8 @@ public static async Task SpawnVehicle(string vehicleName = "custom", bool s #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; // make convar /// /// Spawns a vehicle. /// @@ -1260,8 +1263,19 @@ public static async Task SpawnVehicle(uint vehicleHash, bool spawnInside, b 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) { var successFull = await LoadModel(vehicleHash); @@ -1375,6 +1389,12 @@ 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); + } } // If mod info about the vehicle was specified, check if it's not null. @@ -1386,11 +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; @@ -2141,7 +2156,7 @@ public static void UpdateServerTime(int hours, int minutes) { realMinutes = 0; } - TriggerServerEvent("vMenu:UpdateServerTime", realHours, realMinutes); + TriggerServerEvent("vMenu:UpdateServerTime", realHours, realMinutes, EventManager.IsServerTimeFrozen); } /// diff --git a/vMenu/MainMenu.cs b/vMenu/MainMenu.cs index 7087f4d7..bad66d2b 100644 --- a/vMenu/MainMenu.cs +++ b/vMenu/MainMenu.cs @@ -147,6 +147,80 @@ public MainMenu() } } }), false); + + RegisterCommand("vMenu:DV", new Action, string>(async (source, args, rawCommand) => + { + if (IsAllowed(Permission.VODelete)) + { + 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 = GetSettingsFloat(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."); + } + } + }), false); if (!(GetSettingsString(Setting.vmenu_noclip_toggle_key) == null)) { diff --git a/vMenu/vMenuClient.csproj b/vMenu/vMenuClient.csproj index 10eb93a6..7c974cb9 100644 --- a/vMenu/vMenuClient.csproj +++ b/vMenu/vMenuClient.csproj @@ -50,7 +50,7 @@ - + diff --git a/vMenuServer/MainServer.cs b/vMenuServer/MainServer.cs index 8b351ba1..c6fd8d0a 100644 --- a/vMenuServer/MainServer.cs +++ b/vMenuServer/MainServer.cs @@ -547,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; @@ -726,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; @@ -750,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; @@ -762,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; @@ -778,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; @@ -792,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; @@ -809,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; } @@ -830,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; @@ -850,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; @@ -885,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; @@ -909,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; @@ -987,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; @@ -1021,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; } @@ -1063,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; @@ -1113,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); @@ -1141,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; } 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.