├── .gitattributes ├── .github ├── ISSUE_TEMPLATE │ └── bug_report.md └── dependabot.yml ├── LICENSE ├── README.md ├── client ├── chat.lua ├── data.lua ├── inventory.lua ├── main.lua ├── misc.lua ├── noclip.lua ├── players.lua ├── spectate.lua ├── teleport.lua ├── toggle_laser.lua ├── troll.lua ├── utils.lua ├── vehicles.lua └── world.lua ├── data ├── object.lua └── ped.lua ├── fxmanifest.lua ├── html ├── index.css ├── index.html └── index.js ├── locales ├── de.json ├── en.json ├── es.json ├── fr.json ├── id.json ├── it.json ├── nl.json ├── no.json ├── pt-br.json └── tr.json ├── server ├── chat.lua ├── inventory.lua ├── main.lua ├── misc.lua ├── players.lua ├── regcommands.lua ├── resources.lua ├── spectate.lua ├── teleport.lua ├── trolls.lua ├── utils.lua └── vehicle.lua ├── shared └── config.lua └── ui ├── .gitignore ├── .prettierrc ├── README.md ├── index.html ├── package-lock.json ├── package.json ├── pnpm-lock.yaml ├── postcss.config.js ├── src ├── App.svelte ├── components │ ├── Autofill.svelte │ ├── DropdownComponent.svelte │ ├── EntityInformation.svelte │ ├── Header.svelte │ ├── Modal.svelte │ ├── Spinner.svelte │ ├── ToggleCoords.svelte │ └── VehicleDev.svelte ├── layout │ ├── Main.svelte │ └── Sidebar │ │ ├── Components │ │ └── Button.svelte │ │ └── Sidebar.svelte ├── main.ts ├── pages │ ├── Actions │ │ └── components │ │ │ ├── Button.svelte │ │ │ ├── Dropdown.svelte │ │ │ ├── Favorite.svelte │ │ │ ├── Input.svelte │ │ │ └── Tabs.svelte │ ├── Chat │ │ ├── Chat.svelte │ │ └── components │ │ │ ├── RecieveInput.svelte │ │ │ └── SendInput.svelte │ ├── Commands │ │ ├── Commands.svelte │ │ └── components │ │ │ └── CommandsCard.svelte │ ├── Players │ │ └── components │ │ │ └── Button.svelte │ ├── Server │ │ └── components │ │ │ ├── ButtonState.svelte │ │ │ └── ResourceCard.svelte │ ├── actions │ │ └── Actions.svelte │ ├── players │ │ └── Players.svelte │ └── server │ │ └── Server.svelte ├── providers │ ├── AlwaysListener.svelte │ ├── BackdropFix.svelte │ ├── DebugBrowser.svelte │ └── VisibilityProvider.svelte ├── store │ ├── actions.ts │ ├── data.ts │ ├── entityInfo.ts │ ├── players.ts │ ├── reports.ts │ ├── server.ts │ ├── staffchat.ts │ ├── stores.ts │ ├── togglecoords.ts │ └── vehicle_dev.ts ├── styles.css ├── typings │ └── type.ts ├── utils │ ├── ReceiveNUI.ts │ ├── SendNUI.ts │ ├── debugData.ts │ ├── misc.ts │ └── timeAgo.ts └── vite-env.d.ts ├── svelte.config.js ├── tailwind.config.cjs ├── tsconfig.json └── vite.config.js /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | 21 | **Screenshots** 22 | If applicable, add screenshots to help explain your problem. 23 | 24 | 25 | **Additional context** 26 | Add any other context about the problem here. 27 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: 'npm' 4 | directory: '/ui/' 5 | schedule: 6 | interval: 'monthly' 7 | groups: 8 | all-dependencies: 9 | patterns: 10 | - "*" 11 | versioning-strategy: 'increase-if-necessary' 12 | open-pull-requests-limit: 3 13 | ignore: 14 | - dependency-name: '*' 15 | update-types: 16 | ['version-update:semver-major', 'version-update:semver-patch'] -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ps-adminmenu 2 | The Admin Menu crafted by [OK1ez](https://github.com/OK1ez) and our dedicated team is user-friendly and intuitive. We invite you to contribute by submitting new features through PRs. We're always eager to review and consider new features. Make sure you use our template when opening Issues or they will be auto closed. 3 | 4 | ## Unofficial ESX Version 5 | Made by Avilchiis for the community, you can download it [here](https://github.com/avilchiis/ps-adminmenu). **WE DO NOT PROVIDE SUPPORT FOR ESX VERSION, DO NOT ASK YOU'LL BE IGNORED.** 6 | 7 | # Preview 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | # Change Language. 17 | - Place this `setr ox:locale en` inside your `server.cfg` 18 | - Change the `en` to your desired language! 19 | 20 | **Supported Languages:** 21 | | **Alias** | **Language Names** | 22 | | --------- | -------------------- | 23 | | en | English | 24 | | fr | French | 25 | | id | Indonesia | 26 | | pt-br | Brazilian Portuguese | 27 | | tr | Turkish | 28 | | es | Spanish | 29 | | nl | Dutch | 30 | | no | Norwegian | 31 | | de | German | 32 | 33 | # Features 34 | * Admin Car 35 | * Ban Player 36 | * Bring Player 37 | * Change Plate 38 | * Checking number plates before ```Change Plate``` 39 | * Change Time 40 | * Change Weather 41 | * Check Permissions 42 | * Clear Inventory 43 | * Clear Inventory Offline 44 | * Clothing Menu 45 | * Copy Coordinates 46 | * Delete Vehicle 47 | * Delete Laser 48 | * Explode Player 49 | * Fix Vehicle 50 | * Freeze Player 51 | * Give Clothing Menu 52 | * Give Item 53 | * Give Item to All 54 | * Give Money 55 | * Give Money to All 56 | * Give Vehicle to Player 57 | * Give NUI Focus 58 | * God Mode 59 | * Invisible 60 | * Infinite Ammo 61 | * Kick Player 62 | * Kill Player 63 | * Make Player Drunk 64 | * Message Player 65 | * Mute Player 66 | * Max Vehicle Mods 67 | * No Clip 68 | * Open Inventory 69 | * Open Stash 70 | * Open Trunk 71 | * Play Sound 72 | * Refuel Vehicle 73 | * Remove Money 74 | * Remove Stress 75 | * Revive All 76 | * Revive Player 77 | * Revive Radius 78 | * Set Bucket 79 | * Server Announcement 80 | * Set Ammo 81 | * Set Vehicle State in Garage (In & Out) 82 | * Set Gang 83 | * Set Job 84 | * Set on Fire 85 | * Set Permissions 86 | * Set Player Ped 87 | * Sit in Vehicle 88 | * Spawn Vehicle 89 | * Spectate Player 90 | * Teleport Back 91 | * Teleport to Coordinates 92 | * Teleport to Marker 93 | * Teleport to player 94 | * Toggle Blackout 95 | * Toggle Blips 96 | * Toggle Coords 97 | * Toggle Cuffs 98 | * Toggle Delete Laser 99 | * Toggle Duty 100 | * Toggle Names 101 | * Vehicle Dev Menu 102 | * Warn player 103 | 104 | # Depedency 105 | 1. [qb-core](https://github.com/qbcore-framework/qb-core) 106 | 2. [ox_lib](https://github.com/overextended/ox_lib) 107 | 108 | # Installation 109 | 1. Download the latest release. 110 | 2. Add the files to your server resources. 111 | 3. Ensure `ps-adminmenu` in your server cfg. Make sure ox_lib starts before ps-adminmenu. 112 | 4. Set the config in `shared/config.lua` to your needs. 113 | 114 | A community video has been made for setup instructions and showcase, you can find it [here](https://www.youtube.com/watch?v=aez5RIi8db8&ab_channel=Kamaryn) 115 | 116 | ## Permissions 117 | Make sure you've correctly configured player permissions in your server.cfg by using ACE permissions with the appropriate identifier. Otherwise, you'll be unable to access or launch the admin menu. Here's a sample configuration where the player, MonkeyWhisper, is assigned god, admin, and mod roles, you should not have all 3 permissions for a single person. For a deeper understanding of how QBCore manages permissions, refer to [this documentation.](https://docs.qbcore.org/qbcore-documentation/guides/setting-permissions) 118 | 119 | ### Player Permission 120 | ``` 121 | add_principal identifier.fivem:565139 qbcore.god # MonkeyWhisper 122 | add_principal identifier.fivem:565139 qbcore.admin # MonkeyWhisper 123 | add_principal identifier.fivem:565139 qbcore.mod # MonkeyWhisper 124 | ``` 125 | 126 | 127 | ## Setting Up Logs 128 | 1. Set up a Discord Webhook for the channel you want the logs to be. 129 | 2. Add this to `qb-smallresource/server/logs.lua` - 130 | `['ps-adminmenu'] = 'discord webhook'` 131 | 3. Replace the place holder with your webhook link. 132 | 133 | # To Do 134 | * Rework the blips/names 135 | 136 | # Credits 137 | * [OK1ez](https://github.com/OK1ez) 138 | * [Lenzh](https://github.com/Lenzh) 139 | * [LeSiiN](https://github.com/LeSiiN) 140 | * Project Sloth Team 141 | -------------------------------------------------------------------------------- /client/chat.lua: -------------------------------------------------------------------------------- 1 | local function getMessagesCallBack() 2 | return lib.callback.await('ps-adminmenu:callback:GetMessages', false) 3 | end 4 | 5 | RegisterNUICallback("GetMessages", function(_, cb) 6 | local data = getMessagesCallBack() 7 | if next(data) then 8 | SendNUIMessage({ 9 | action = "setMessages", 10 | data = data 11 | }) 12 | end 13 | cb(1) 14 | end) 15 | 16 | RegisterNUICallback("SendMessage", function(msgData, cb) 17 | local message = msgData.message 18 | print(message, PlayerData.citizenid, PlayerData.charinfo.firstname .. " " .. PlayerData.charinfo.lastname ) 19 | 20 | TriggerServerEvent("ps-adminmenu:server:sendMessageServer", message, PlayerData.citizenid, PlayerData.charinfo.firstname .. " " .. PlayerData.charinfo.lastname) 21 | 22 | local data = getMessagesCallBack() 23 | SendNUIMessage({ 24 | action = "setMessages", 25 | data = data 26 | }) 27 | cb(1) 28 | end) -------------------------------------------------------------------------------- /client/data.lua: -------------------------------------------------------------------------------- 1 | local PedList = require "data.ped" 2 | 3 | -- Returns a list of vehicles from QBCore.Shared.Vehicles 4 | local function GetVehicles() 5 | local vehicles = {} 6 | 7 | for _, v in pairs(QBCore.Shared.Vehicles) do 8 | vehicles[#vehicles + 1] = { label = v.name, value = v.model } 9 | end 10 | 11 | return vehicles 12 | end 13 | 14 | -- Returns a list of items from QBCore.Shared.Items 15 | local function GetItems() 16 | local items = {} 17 | local ItemsData = QBCore.Shared.Items 18 | 19 | if Config.Inventory == "ox_inventory" then 20 | ItemsData = exports.ox_inventory:Items() 21 | end 22 | 23 | for name, v in pairs(ItemsData) do 24 | items[#items + 1] = { label = v.label, value = name } 25 | end 26 | 27 | return items 28 | end 29 | 30 | -- Returns a list of jobs from QBCore.Shared.Jobs 31 | local function GetJobs() 32 | local jobs = {} 33 | 34 | for name, v in pairs(QBCore.Shared.Jobs) do 35 | local gradeDataList = {} 36 | 37 | for grade, gradeData in pairs(v.grades) do 38 | gradeDataList[#gradeDataList + 1] = { name = gradeData.name, grade = grade, isboss = gradeData.isboss } 39 | end 40 | 41 | jobs[#jobs + 1] = { label = v.label, value = name, grades = gradeDataList } 42 | end 43 | 44 | return jobs 45 | end 46 | 47 | -- Returns a list of gangs from QBCore.Shared.Gangs 48 | local function GetGangs() 49 | local gangs = {} 50 | 51 | for name, v in pairs(QBCore.Shared.Gangs) do 52 | local gradeDataList = {} 53 | 54 | for grade, gradeData in pairs(v.grades) do 55 | gradeDataList[#gradeDataList + 1] = { name = gradeData.name, grade = grade, isboss = gradeData.isboss } 56 | end 57 | 58 | gangs[#gangs + 1] = { label = v.label, value = name, grades = gradeDataList } 59 | end 60 | 61 | return gangs 62 | end 63 | 64 | -- Returns a list of locations from QBCore.Shared.Loactions 65 | local function GetLocations() 66 | local locations = {} 67 | 68 | for name, v in pairs(QBCore.Shared.Locations) do 69 | locations[#locations + 1] = { label = name, value = v } 70 | end 71 | 72 | return locations 73 | end 74 | 75 | -- Sends data to the UI on resource start 76 | function GetData() 77 | SendNUIMessage({ 78 | action = "data", 79 | data = { 80 | vehicles = GetVehicles(), 81 | items = GetItems(), 82 | jobs = GetJobs(), 83 | gangs = GetGangs(), 84 | locations = GetLocations(), 85 | pedlist = PedList 86 | }, 87 | }) 88 | end 89 | -------------------------------------------------------------------------------- /client/inventory.lua: -------------------------------------------------------------------------------- 1 | -- Open Inventory 2 | RegisterNetEvent('ps-adminmenu:client:openInventory', function(data, selectedData) 3 | local data = CheckDataFromKey(data) 4 | if not data or not CheckPerms(data.perms) then return end 5 | local player = selectedData["Player"].value 6 | 7 | if Config.Inventory == 'ox_inventory' then 8 | TriggerServerEvent("ps-adminmenu:server:OpenInv", player) 9 | else 10 | TriggerServerEvent("inventory:server:OpenInventory", "otherplayer", player) 11 | end 12 | end) 13 | 14 | -- Open Stash 15 | RegisterNetEvent('ps-adminmenu:client:openStash', function(data, selectedData) 16 | local data = CheckDataFromKey(data) 17 | if not data or not CheckPerms(data.perms) then return end 18 | local stash = selectedData["Stash"].value 19 | 20 | if Config.Inventory == 'ox_inventory' then 21 | TriggerServerEvent("ps-adminmenu:server:OpenStash", stash) 22 | else 23 | TriggerServerEvent("inventory:server:OpenInventory", "stash", tostring(stash)) 24 | TriggerEvent("inventory:client:SetCurrentStash", tostring(stash)) 25 | end 26 | end) 27 | 28 | -- Open Trunk 29 | RegisterNetEvent('ps-adminmenu:client:openTrunk', function(data, selectedData) 30 | local data = CheckDataFromKey(data) 31 | if not data or not CheckPerms(data.perms) then return end 32 | local vehiclePlate = selectedData["Plate"].value 33 | 34 | if Config.Inventory == 'ox_inventory' then 35 | TriggerServerEvent("ps-adminmenu:server:OpenTrunk", vehiclePlate) 36 | else 37 | TriggerServerEvent("inventory:server:OpenInventory", "trunk", tostring(vehiclePlate)) 38 | TriggerEvent("inventory:client:SetCurrentStash", tostring(vehiclePlate)) 39 | end 40 | end) 41 | -------------------------------------------------------------------------------- /client/main.lua: -------------------------------------------------------------------------------- 1 | QBCore = exports['qb-core']:GetCoreObject() 2 | PlayerData = {} 3 | 4 | -- Functions 5 | local function setupMenu() 6 | Wait(500) 7 | PlayerData = QBCore.Functions.GetPlayerData() 8 | local resources = lib.callback.await('ps-adminmenu:callback:GetResources', false) 9 | local commands = lib.callback.await('ps-adminmenu:callback:GetCommands', false) 10 | GetData() 11 | SendNUIMessage({ 12 | action = "setupUI", 13 | data = { 14 | actions = Config.Actions, 15 | resources = resources, 16 | playerData = PlayerData, 17 | commands = commands 18 | } 19 | }) 20 | end 21 | 22 | -- Event Handlers 23 | AddEventHandler("QBCore:Client:OnPlayerLoaded", function() 24 | setupMenu() 25 | end) 26 | 27 | AddEventHandler("onResourceStart", function(resourceName) 28 | if (GetCurrentResourceName() == resourceName) then 29 | setupMenu() 30 | end 31 | end) 32 | 33 | -- NUICallbacks 34 | RegisterNUICallback("hideUI", function() 35 | ToggleUI(false) 36 | end) 37 | 38 | RegisterNUICallback("clickButton", function(data) 39 | local selectedData = data.selectedData 40 | local key = data.data 41 | local data = CheckDataFromKey(key) 42 | if not data or not CheckPerms(data.perms) then return end 43 | 44 | if data.type == "client" then 45 | TriggerEvent(data.event, key, selectedData) 46 | elseif data.type == "server" then 47 | TriggerServerEvent(data.event, key, selectedData) 48 | elseif data.type == "command" then 49 | ExecuteCommand(data.event) 50 | end 51 | 52 | Log("Action Used: " .. key, 53 | PlayerData.name .. 54 | " (" .. 55 | PlayerData.citizenid .. 56 | ") - Used: " .. key .. (selectedData and (" with args: " .. json.encode(selectedData)) or "")) 57 | end) 58 | 59 | -- Open UI Event 60 | RegisterNetEvent('ps-adminmenu:client:OpenUI', function() 61 | ToggleUI(true) 62 | end) 63 | 64 | -- Close UI Event 65 | RegisterNetEvent('ps-adminmenu:client:CloseUI', function() 66 | ToggleUI(false) 67 | end) 68 | 69 | -- Change resource state 70 | RegisterNUICallback("setResourceState", function(data, cb) 71 | local resources = lib.callback.await('ps-adminmenu:callback:ChangeResourceState', false, data) 72 | cb(resources) 73 | end) 74 | 75 | -- Get players 76 | RegisterNUICallback("getPlayers", function(data, cb) 77 | local players = lib.callback.await('ps-adminmenu:callback:GetPlayers', false) 78 | cb(players) 79 | end) 80 | -------------------------------------------------------------------------------- /client/misc.lua: -------------------------------------------------------------------------------- 1 | -- Toggles Invincibility 2 | local visible = true 3 | RegisterNetEvent('ps-adminmenu:client:ToggleInvisible', function(data) 4 | local data = CheckDataFromKey(data) 5 | if not data or not CheckPerms(data.perms) then return end 6 | visible = not visible 7 | 8 | SetEntityVisible(cache.ped, visible, 0) 9 | end) 10 | 11 | -- God Mode 12 | local godmode = false 13 | RegisterNetEvent('ps-adminmenu:client:ToggleGodmode', function(data) 14 | local data = CheckDataFromKey(data) 15 | if not data or not CheckPerms(data.perms) then return end 16 | godmode = not godmode 17 | 18 | if godmode then 19 | QBCore.Functions.Notify(locale("godmode", "enabled"), 'primary') 20 | while godmode do 21 | Wait(0) 22 | SetPlayerInvincible(cache.playerId, true) 23 | end 24 | SetPlayerInvincible(cache.playerId, false) 25 | QBCore.Functions.Notify(locale("godmode", "disabled"), 'primary') 26 | end 27 | end) 28 | 29 | -- Cuff/Uncuff 30 | RegisterNetEvent('ps-adminmenu:client:ToggleCuffs', function(player) 31 | local target = GetPlayerServerId(player) 32 | TriggerEvent("police:client:GetCuffed", target) 33 | end) 34 | 35 | -- Copy Coordinates 36 | local function CopyCoords(data) 37 | local coords = GetEntityCoords(cache.ped) 38 | local heading = GetEntityHeading(cache.ped) 39 | local formats = { vector2 = "%.2f, %.2f", vector3 = "%.2f, %.2f, %.2f", vector4 = "%.2f, %.2f, %.2f, %.2f", heading = 40 | "%.2f" } 41 | local format = formats[data] 42 | 43 | local clipboardText = "" 44 | if data == "vector2" then 45 | clipboardText = string.format(format, coords.x, coords.y) 46 | elseif data == "vector3" then 47 | clipboardText = string.format(format, coords.x, coords.y, coords.z) 48 | elseif data == "vector4" then 49 | clipboardText = string.format(format, coords.x, coords.y, coords.z, heading) 50 | elseif data == "heading" then 51 | clipboardText = string.format(format, heading) 52 | end 53 | 54 | lib.setClipboard(clipboardText) 55 | end 56 | 57 | RegisterCommand("vector2", function() 58 | if not CheckPerms('mod') then return end 59 | CopyCoords("vector2") 60 | end, false) 61 | 62 | RegisterCommand("vector3", function() 63 | if not CheckPerms('mod') then return end 64 | CopyCoords("vector3") 65 | end, false) 66 | 67 | RegisterCommand("vector4", function() 68 | if not CheckPerms('mod') then return end 69 | CopyCoords("vector4") 70 | end, false) 71 | 72 | RegisterCommand("heading", function() 73 | if not CheckPerms('mod') then return end 74 | CopyCoords("heading") 75 | end, false) 76 | 77 | -- Infinite Ammo 78 | local InfiniteAmmo = false 79 | RegisterNetEvent('ps-adminmenu:client:setInfiniteAmmo', function(data) 80 | local data = CheckDataFromKey(data) 81 | if not data or not CheckPerms(data.perms) then return end 82 | InfiniteAmmo = not InfiniteAmmo 83 | 84 | if GetAmmoInPedWeapon(cache.ped, cache.weapon) < 6 then 85 | SetAmmoInClip(cache.ped, cache.weapon, 10) 86 | Wait(50) 87 | end 88 | 89 | while InfiniteAmmo do 90 | SetPedInfiniteAmmo(cache.ped, true, cache.weapon) 91 | RefillAmmoInstantly(cache.ped) 92 | Wait(250) 93 | end 94 | 95 | SetPedInfiniteAmmo(cache.ped, false, cache.weapon) 96 | end) 97 | 98 | -- Toggle coords 99 | local showCoords = false 100 | local function showCoordsMenu() 101 | while showCoords do 102 | Wait(50) 103 | local coords = GetEntityCoords(PlayerPedId()) 104 | local heading = GetEntityHeading(PlayerPedId()) 105 | SendNUIMessage({ 106 | action = "showCoordsMenu", 107 | data = { 108 | show = showCoords, 109 | x = QBCore.Shared.Round(coords.x, 2), 110 | y = QBCore.Shared.Round(coords.y, 2), 111 | z = QBCore.Shared.Round(coords.z, 2), 112 | heading = QBCore.Shared.Round(heading, 2) 113 | } 114 | }) 115 | end 116 | end 117 | 118 | RegisterNetEvent('ps-adminmenu:client:ToggleCoords', function(data) 119 | local data = CheckDataFromKey(data) 120 | if not data or not CheckPerms(data.perms) then return end 121 | 122 | showCoords = not showCoords 123 | 124 | if showCoords then 125 | CreateThread(showCoordsMenu) 126 | end 127 | end) 128 | 129 | -- Set Ammo 130 | RegisterNetEvent('ps-adminmenu:client:SetAmmo', function(data, selectedData) 131 | local data = CheckDataFromKey(data) 132 | if not data or not CheckPerms(data.perms) then return end 133 | 134 | local ammo = selectedData["Ammo Amount"].value 135 | local weapon = GetSelectedPedWeapon(cache.ped) 136 | 137 | if weapon ~= nil then 138 | SetPedAmmo(cache.ped, weapon, ammo) 139 | QBCore.Functions.Notify(locale("set_wepaon_ammo", tostring(ammo)), 'success') 140 | else 141 | QBCore.Functions.Notify(locale("no_weapon"), 'error') 142 | end 143 | end) 144 | 145 | RegisterCommand("setammo", function(source) 146 | if not CheckPerms('mod') then return end 147 | local weapon = GetSelectedPedWeapon(cache.ped) 148 | local ammo = 999 149 | if weapon ~= nil then 150 | SetPedAmmo(cache.ped, weapon, ammo) 151 | QBCore.Functions.Notify(locale("set_wepaon_ammo", tostring(ammo)), 'success') 152 | else 153 | QBCore.Functions.Notify(locale("no_weapon"), 'error') 154 | end 155 | end, false) 156 | 157 | --Toggle Dev 158 | local ToggleDev = false 159 | 160 | RegisterNetEvent('ps-adminmenu:client:ToggleDev', function(dataKey) 161 | local data = CheckDataFromKey(dataKey) 162 | if not data or not CheckPerms(data.perms) then return end 163 | 164 | ToggleDev = not ToggleDev 165 | 166 | TriggerEvent("qb-admin:client:ToggleDevmode") -- toggle dev mode (ps-hud/qb-hud) 167 | TriggerEvent('ps-adminmenu:client:ToggleCoords', dataKey) -- toggle Coords 168 | TriggerEvent('ps-adminmenu:client:ToggleGodmode', dataKey) -- Godmode 169 | 170 | QBCore.Functions.Notify(locale("toggle_dev"), 'success') 171 | end) 172 | 173 | -- Key Bindings 174 | local toogleAdmin = lib.addKeybind({ 175 | name = 'toogleAdmin', 176 | description = locale("command_admin_desc"), 177 | defaultKey = Config.AdminKey, 178 | onPressed = function(self) 179 | ExecuteCommand('admin') 180 | end 181 | }) 182 | 183 | --noclip 184 | RegisterCommand('nc', function() 185 | TriggerEvent(Config.Actions["noclip"].event) 186 | end, false) 187 | 188 | local toogleNoclip = lib.addKeybind({ 189 | name = 'toogleNoclip', 190 | description = locale("command_noclip_desc"), 191 | defaultKey = Config.NoclipKey, 192 | onPressed = function(self) 193 | ExecuteCommand('nc') 194 | end 195 | }) 196 | 197 | if Config.Keybindings then 198 | toogleAdmin:disable(false) 199 | toogleNoclip:disable(false) 200 | else 201 | toogleAdmin:disable(true) 202 | toogleNoclip:disable(true) 203 | end 204 | 205 | -- Set Ped 206 | RegisterNetEvent("ps-adminmenu:client:setPed", function(pedModels) 207 | lib.requestModel(pedModels, 1500) 208 | SetPlayerModel(cache.playerId, pedModels) 209 | SetPedDefaultComponentVariation(cache.ped) 210 | SetModelAsNoLongerNeeded(pedModels) 211 | end) 212 | -------------------------------------------------------------------------------- /client/noclip.lua: -------------------------------------------------------------------------------- 1 | local noclip = false 2 | local cam = 0 3 | local ped 4 | local speed = 1 5 | local maxSpeed = 16 6 | 7 | 8 | -- Disable the controls 9 | local function DisabledControls() 10 | HudWeaponWheelIgnoreSelection() 11 | DisableAllControlActions(0) 12 | DisableAllControlActions(1) 13 | DisableAllControlActions(2) 14 | EnableControlAction(0, 220, true) 15 | EnableControlAction(0, 221, true) 16 | EnableControlAction(0, 245, true) 17 | end 18 | 19 | -- Setup the camera 20 | local function SetupCam() 21 | local rotation = GetEntityRotation(ped) 22 | local coords = GetEntityCoords(ped) 23 | 24 | cam = CreateCameraWithParams("DEFAULT_SCRIPTED_CAMERA", coords, vector3(0.0, 0.0, rotation.z), 75.0) 25 | SetCamActive(cam, true) 26 | RenderScriptCams(true, true, 1000, false, false) 27 | AttachCamToEntity(cam, ped, 0.0, 0.0, 1.0, true) 28 | end 29 | 30 | -- Destroys the camera 31 | local function DestoryCam() 32 | Wait(100) 33 | SetGameplayCamRelativeHeading(0) 34 | RenderScriptCams(false, true, 1000, true, true) 35 | DetachEntity(ped, true, true) 36 | SetCamActive(cam, false) 37 | DestroyCam(cam, true) 38 | end 39 | 40 | -- Checks if a control is always pressed 41 | local IsControlAlwaysPressed = function(inputGroup, control) 42 | return IsControlPressed(inputGroup, control) or IsDisabledControlPressed(inputGroup, control) 43 | end 44 | 45 | -- Updates the camera rotation 46 | local function UpdateCameraRotation() 47 | local rightAxisX = GetControlNormal(0, 220) 48 | local rightAxisY = GetControlNormal(0, 221) 49 | local rotation = GetCamRot(cam, 2) 50 | local yValue = rightAxisY * -5 51 | local newX 52 | local newZ = rotation.z + (rightAxisX * -10) 53 | 54 | if (rotation.x + yValue > -89.0) and (rotation.x + yValue < 89.0) then 55 | newX = rotation.x + yValue 56 | end 57 | 58 | if newX ~= nil and newZ ~= nil then 59 | SetCamRot(cam, vector3(newX, rotation.y, newZ), 2) 60 | end 61 | 62 | SetEntityHeading(ped, math.max(0, (rotation.z % 360))) 63 | end 64 | 65 | -- Gets the ground coords 66 | local function TeleportToGround() 67 | local coords = GetEntityCoords(ped) 68 | local rayCast = StartShapeTestRay(coords.x, coords.y, coords.z, coords.x, coords.y, -10000.0, 1, 0) 69 | local _, hit, hitCoords = GetShapeTestResult(rayCast) 70 | 71 | if hit == 1 then 72 | SetEntityCoords(ped, hitCoords.x, hitCoords.y, hitCoords.z) 73 | else 74 | SetEntityCoords(ped, coords.x, coords.y, coords.z) 75 | end 76 | end 77 | 78 | -- Toggles the behavior of visiblty, collision, etc 79 | local function ToggleBehavior(bool) 80 | local coords = GetEntityCoords(ped) 81 | 82 | RequestCollisionAtCoord(coords.x, coords.y, coords.z) 83 | FreezeEntityPosition(ped, bool) 84 | SetEntityCollision(ped, not bool, not bool) 85 | SetEntityVisible(ped, not bool, not bool) 86 | SetEntityInvincible(ped, bool) 87 | SetEntityAlpha(ped, bool and noclipAlpha or 255, false) 88 | SetLocalPlayerVisibleLocally(true) 89 | SetEveryoneIgnorePlayer(ped, bool) 90 | SetPoliceIgnorePlayer(ped, bool) 91 | 92 | local vehicle = GetVehiclePedIsIn(ped, false) 93 | if vehicle ~= 0 then 94 | SetEntityAlpha(vehicle, bool and noclipAlpha or 255, false) 95 | end 96 | end 97 | 98 | 99 | -- Stops the noclip 100 | local function StopNoclip() 101 | DestoryCam() 102 | TeleportToGround() 103 | ToggleBehavior(false) 104 | end 105 | 106 | -- Handels the speed 107 | local function UpdateSpeed() 108 | if IsControlAlwaysPressed(2, 14) then 109 | speed = speed - 0.5 110 | if speed < 0.5 then 111 | speed = 0.5 112 | end 113 | elseif IsControlAlwaysPressed(2, 15) then 114 | speed = speed + 0.5 115 | if speed > maxSpeed then 116 | speed = maxSpeed 117 | end 118 | elseif IsDisabledControlJustReleased(0, 348) then 119 | speed = 1 120 | end 121 | end 122 | 123 | -- Handels the movement 124 | local function UpdateMovement() 125 | local multi = 1.0 126 | if IsControlAlwaysPressed(0, 21) then 127 | multi = 2 128 | elseif IsControlAlwaysPressed(0, 19) then 129 | multi = 4 130 | elseif IsControlAlwaysPressed(0, 36) then 131 | multi = 0.25 132 | end 133 | 134 | if IsControlAlwaysPressed(0, 32) then 135 | local pitch = GetCamRot(cam, 0) 136 | 137 | if pitch.x >= 0 then 138 | SetEntityCoordsNoOffset(ped, 139 | GetOffsetFromEntityInWorldCoords(ped, 0.0, 0.5 * (speed * multi), 140 | (pitch.x * ((speed / 2) * multi)) / 89)) 141 | else 142 | SetEntityCoordsNoOffset(ped, 143 | GetOffsetFromEntityInWorldCoords(ped, 0.0, 0.5 * (speed * multi), 144 | -1 * ((math.abs(pitch.x) * ((speed / 2) * multi)) / 89))) 145 | end 146 | elseif IsControlAlwaysPressed(0, 33) then 147 | local pitch = GetCamRot(cam, 2) 148 | 149 | if pitch.x >= 0 then 150 | SetEntityCoordsNoOffset(ped, 151 | GetOffsetFromEntityInWorldCoords(ped, 0.0, -0.5 * (speed * multi), 152 | -1 * (pitch.x * ((speed / 2) * multi)) / 89)) 153 | else 154 | SetEntityCoordsNoOffset(ped, 155 | GetOffsetFromEntityInWorldCoords(ped, 0.0, -0.5 * (speed * multi), 156 | ((math.abs(pitch.x) * ((speed / 2) * multi)) / 89))) 157 | end 158 | end 159 | 160 | if IsControlAlwaysPressed(0, 34) then 161 | SetEntityCoordsNoOffset(ped, 162 | GetOffsetFromEntityInWorldCoords(ped, -0.5 * (speed * multi), 0.0, 0.0)) 163 | elseif IsControlAlwaysPressed(0, 35) then 164 | SetEntityCoordsNoOffset(ped, 165 | GetOffsetFromEntityInWorldCoords(ped, 0.5 * (speed * multi), 0.0, 0.0)) 166 | end 167 | 168 | if IsControlAlwaysPressed(0, 44) then 169 | SetEntityCoordsNoOffset(ped, 170 | GetOffsetFromEntityInWorldCoords(ped, 0.0, 0.0, 0.5 * (speed * multi))) 171 | elseif IsControlAlwaysPressed(0, 46) then 172 | SetEntityCoordsNoOffset(ped, 173 | GetOffsetFromEntityInWorldCoords(ped, 0.0, 0.0, -0.5 * (speed * multi))) 174 | end 175 | end 176 | 177 | -- Toggles the noclip 178 | local function ToggleNoclip() 179 | noclip = not noclip 180 | 181 | if cache.vehicle then 182 | ped = cache.vehicle 183 | else 184 | ped = cache.ped 185 | end 186 | 187 | if noclip then 188 | SetupCam() 189 | ToggleBehavior(true) 190 | while noclip do 191 | Wait(0) 192 | UpdateCameraRotation() 193 | DisabledControls() 194 | UpdateSpeed() 195 | UpdateMovement() 196 | end 197 | else 198 | StopNoclip() 199 | end 200 | end 201 | 202 | RegisterNetEvent('ps-adminmenu:client:ToggleNoClip', function() 203 | if not CheckPerms(Config.Actions["noclip"].perms) then return end 204 | ToggleNoclip() 205 | end) 206 | 207 | -------------------------------------------------------------------------------- /client/players.lua: -------------------------------------------------------------------------------- 1 | local ShowBlips = false 2 | local ShowNames = false 3 | local NetCheck1 = false 4 | local NetCheck2 = false 5 | local Blip = nil 6 | local Tag = nil 7 | local currentPlayers = {} 8 | 9 | -- Function to remove all names and Blips 10 | local function removeNameAndBlips() 11 | if DoesBlipExist(Blip) then 12 | RemoveBlip(Blip) 13 | end 14 | if Tag then 15 | SetMpGamerTagVisibility(Tag, 0, false) 16 | SetMpGamerTagVisibility(Tag, 2, false) 17 | SetMpGamerTagVisibility(Tag, 4, false) 18 | SetMpGamerTagVisibility(Tag, 6, false) 19 | RemoveMpGamerTag(Tag) 20 | end 21 | end 22 | 23 | -- Function to Toggle Blips and Names 24 | local function ToggleBlipsAndNames(isBlips) 25 | if isBlips then 26 | ShowBlips = not ShowBlips 27 | NetCheck1 = ShowBlips 28 | local message = ShowBlips and "blips_activated" or "blips_deactivated" 29 | QBCore.Functions.Notify(locale(message), ShowBlips and "success" or "error") 30 | else 31 | ShowNames = not ShowNames 32 | NetCheck2 = ShowNames 33 | local message = ShowNames and "names_activated" or "names_deactivated" 34 | QBCore.Functions.Notify(locale(message), ShowNames and "success" or "error") 35 | end 36 | if not ShowNames or not ShowBlips then 37 | removeNameAndBlips() 38 | end 39 | end 40 | 41 | -- Main Function to Update Blips and Names 42 | local function UpdateBlipsAndNames(players) 43 | local playerPed = PlayerPedId() 44 | local playerCoords = GetEntityCoords(playerPed, true) 45 | local blipSprites = { -- Sprite Per Vehicle Class 46 | [1] = 1, 47 | [8] = 226, 48 | [9] = 757, 49 | [10] = 477, 50 | [11] = 477, 51 | [12] = 67, 52 | [13] = 226, 53 | [14] = 427, 54 | [15] = 422, 55 | [16] = 423, 56 | [17] = 198, 57 | [18] = 56, 58 | [19] = 421, 59 | [20] = 477, 60 | } 61 | 62 | for _, player in pairs(players) do 63 | local playerId = GetPlayerFromServerId(player.id) 64 | local ped = GetPlayerPed(playerId) 65 | local name = 'ID: ' .. player.id .. ' | ' .. player.name 66 | Blip = GetBlipFromEntity(ped) 67 | 68 | Tag = CreateFakeMpGamerTag(ped, name, false, false, "", false) 69 | SetMpGamerTagAlpha(Tag, 0, 255) 70 | SetMpGamerTagAlpha(Tag, 2, 255) 71 | SetMpGamerTagAlpha(Tag, 4, 255) 72 | SetMpGamerTagAlpha(Tag, 6, 255) 73 | SetMpGamerTagHealthBarColour(Tag, 25) 74 | 75 | local isPlayerTalking = NetworkIsPlayerTalking(playerId) 76 | local isPlayerInvincible = GetPlayerInvincible(playerId) 77 | if ShowNames then 78 | SetMpGamerTagVisibility(Tag, 0, true) 79 | SetMpGamerTagVisibility(Tag, 2, true) 80 | SetMpGamerTagVisibility(Tag, 4, isPlayerTalking) 81 | SetMpGamerTagVisibility(Tag, 6, isPlayerInvincible) 82 | else 83 | SetMpGamerTagVisibility(Tag, 0, false) 84 | SetMpGamerTagVisibility(Tag, 2, false) 85 | SetMpGamerTagVisibility(Tag, 4, false) 86 | SetMpGamerTagVisibility(Tag, 6, false) 87 | RemoveMpGamerTag(Tag) 88 | end 89 | 90 | if ShowBlips then 91 | if not DoesBlipExist(Blip) then 92 | Blip = AddBlipForEntity(ped) 93 | ShowHeadingIndicatorOnBlip(Blip, true) 94 | SetBlipCategory(Blip, 7) 95 | else 96 | local veh = GetVehiclePedIsIn(ped, false) 97 | local classveh = GetVehicleClass(veh) 98 | local modelveh = GetEntityModel(veh) 99 | if veh ~= 0 then 100 | local blipSprite = blipSprites[classveh] or 225 101 | if modelveh == 'besra' or modelveh == 'hydra' or modelveh == 'lazer' then 102 | blipSprite = 424 103 | end 104 | 105 | SetBlipSprite(Blip, blipSprite) 106 | ShowHeadingIndicatorOnBlip(Blip, false) 107 | 108 | local passengers = GetVehicleNumberOfPassengers(veh) 109 | if passengers then 110 | if not IsVehicleSeatFree(veh, -1) then 111 | passengers = passengers + 1 112 | end 113 | ShowNumberOnBlip(Blip, passengers) 114 | else 115 | HideNumberOnBlip(Blip) 116 | end 117 | 118 | SetBlipRotation(Blip, math.ceil(GetEntityHeading(veh))) 119 | SetBlipNameToPlayerName(Blip, playerId) 120 | SetBlipScale(Blip, 0.85) 121 | 122 | local distance = math.floor(Vdist(playerCoords.x, playerCoords.y, playerCoords.z, 123 | GetEntityCoords(ped, true).x, GetEntityCoords(ped, true).y, GetEntityCoords(ped, true).z) / 124 | -1) + 125 | 900 126 | distance = math.max(0, math.min(255, distance)) 127 | SetBlipAlpha(Blip, distance) 128 | else 129 | HideNumberOnBlip(Blip) 130 | SetBlipSprite(Blip, 1) 131 | SetBlipNameToPlayerName(Blip, playerId) 132 | ShowHeadingIndicatorOnBlip(Blip, true) 133 | end 134 | end 135 | end 136 | end 137 | end 138 | 139 | local function preparePlayers() 140 | currentPlayers = {} 141 | Wait(100) 142 | currentPlayers = lib.callback.await('ps-adminmenu:callback:GetPlayers') 143 | end 144 | 145 | -- Toggle Blips and Names events 146 | RegisterNetEvent('ps-adminmenu:client:toggleBlips', function(data) 147 | local data = CheckDataFromKey(data) 148 | if not data or not CheckPerms(data.perms) then return end 149 | if not ShowBlips then preparePlayers() end 150 | ToggleBlipsAndNames(true) 151 | end) 152 | 153 | RegisterNetEvent('ps-adminmenu:client:toggleNames', function(data) 154 | local data = CheckDataFromKey(data) 155 | if not data or not CheckPerms(data.perms) then return end 156 | if not ShowNames then preparePlayers() end 157 | ToggleBlipsAndNames(false) 158 | end) 159 | 160 | -- Mute Player 161 | RegisterNetEvent("ps-adminmenu:client:MutePlayer", function(data, selectedData) 162 | local data = CheckDataFromKey(data) 163 | if not data or not CheckPerms(data.perms) then return end 164 | local playerId = selectedData["Player"].value 165 | if not playerId then return end 166 | exports["pma-voice"]:toggleMutePlayer(playerId) 167 | end) 168 | 169 | -- Main loop to check for updates 170 | CreateThread(function() 171 | while true do 172 | Wait(1000) 173 | if NetCheck1 or NetCheck2 then 174 | UpdateBlipsAndNames(currentPlayers) 175 | end 176 | end 177 | end) 178 | 179 | -- Remove Stress 180 | RegisterNetEvent('ps-adminmenu:client:removeStress', function(data) 181 | TriggerServerEvent('hud:server:RelieveStress', 100) 182 | end) 183 | -------------------------------------------------------------------------------- /client/spectate.lua: -------------------------------------------------------------------------------- 1 | local oldPos = nil 2 | local spectateInfo = { 3 | toggled = false, 4 | target = 0, 5 | targetPed = 0 6 | } 7 | 8 | RegisterNetEvent('ps-adminmenu:requestSpectate', function(targetPed, target, name) 9 | oldPos = GetEntityCoords(cache.ped) 10 | spectateInfo = { 11 | toggled = true, 12 | target = target, 13 | targetPed = targetPed 14 | } 15 | end) 16 | 17 | RegisterNetEvent('ps-adminmenu:cancelSpectate', function() 18 | if NetworkIsInSpectatorMode() then 19 | NetworkSetInSpectatorMode(false, spectateInfo['targetPed']) 20 | end 21 | SetEntityVisible(cache.ped, true, 0) 22 | spectateInfo = { toggled = false, target = 0, targetPed = 0 } 23 | RequestCollisionAtCoord(oldPos) 24 | SetEntityCoords(cache.ped, oldPos) 25 | oldPos = nil; 26 | end) 27 | 28 | CreateThread(function() 29 | while true do 30 | Wait(0) 31 | if spectateInfo['toggled'] then 32 | local targetPed = NetworkGetEntityFromNetworkId(spectateInfo.targetPed) 33 | if DoesEntityExist(targetPed) then 34 | SetEntityVisible(cache.ped, false, 0) 35 | if not NetworkIsInSpectatorMode() then 36 | RequestCollisionAtCoord(GetEntityCoords(targetPed)) 37 | NetworkSetInSpectatorMode(true, targetPed) 38 | end 39 | else 40 | TriggerServerEvent('ps-adminmenu:spectate:teleport', spectateInfo['target']) 41 | while not DoesEntityExist(NetworkGetEntityFromNetworkId(spectateInfo.targetPed)) do Wait(100) end 42 | end 43 | else 44 | Wait(500) 45 | end 46 | end 47 | end) 48 | -------------------------------------------------------------------------------- /client/teleport.lua: -------------------------------------------------------------------------------- 1 | local lastCoords 2 | 3 | local function teleport(x, y, z) 4 | if cache.vehicle then 5 | return SetPedCoordsKeepVehicle(cache.ped, x, y, z) 6 | end 7 | 8 | SetEntityCoords(cache.ped, x, y, z, false, false, false, false) 9 | end 10 | 11 | -- Teleport to player 12 | RegisterNetEvent('ps-adminmenu:client:TeleportToPlayer', function(coords) 13 | lastCoords = GetEntityCoords(cache.ped) 14 | SetPedCoordsKeepVehicle(cache.ped, coords.x, coords.y, coords.z) 15 | end) 16 | 17 | -- Teleport to coords 18 | RegisterNetEvent('ps-adminmenu:client:TeleportToCoords', function(data, selectedData) 19 | local data = CheckDataFromKey(data) 20 | if not data or not CheckPerms(data.perms) then return end 21 | 22 | local coordsStr = selectedData["Coords"].value 23 | local x, y, z, heading 24 | 25 | x, y, z, heading = coordsStr:match("(-?%d+%.?%d*),%s*(-?%d+%.?%d*),?%s*(-?%d*%.?%d*),?%s*(-?%d*%.?%d*)") 26 | 27 | if not x or not y then 28 | x, y, z, heading = coordsStr:match("(-?%d+%.?%d*)%s+(-?%d+%.?%d*)%s*(-?%d*%.?%d*)%s*(-?%d*%.?%d*)") 29 | end 30 | 31 | x = tonumber(x) 32 | y = tonumber(y) 33 | z = tonumber(z or 0) 34 | heading = tonumber(heading or 0) 35 | 36 | if x and y then 37 | lastCoords = GetEntityCoords(cache.ped) 38 | if heading and heading ~= 0 then 39 | SetEntityHeading(cache.ped, heading) 40 | end 41 | SetPedCoordsKeepVehicle(cache.ped, x, y, z) 42 | end 43 | end) 44 | 45 | -- Teleport to Locaton 46 | RegisterNetEvent('ps-adminmenu:client:TeleportToLocation', function(data, selectedData) 47 | local data = CheckDataFromKey(data) 48 | if not data or not CheckPerms(data.perms) then return end 49 | local coords = selectedData["Location"].value 50 | 51 | lastCoords = GetEntityCoords(cache.ped) 52 | SetPedCoordsKeepVehicle(cache.ped, coords.x, coords.y, coords.z) 53 | end) 54 | 55 | -- Teleport back 56 | RegisterNetEvent('ps-adminmenu:client:TeleportBack', function(data) 57 | local data = CheckDataFromKey(data) 58 | if not data or not CheckPerms(data.perms) then return end 59 | 60 | if lastCoords then 61 | local coords = GetEntityCoords(cache.ped) 62 | teleport(lastCoords.x, lastCoords.y, lastCoords.z) 63 | lastCoords = coords 64 | end 65 | end) 66 | -------------------------------------------------------------------------------- /client/toggle_laser.lua: -------------------------------------------------------------------------------- 1 | local ObjectList = require "data.object" 2 | 3 | local function DrawEntityBoundingBox(entity, color) 4 | local model = GetEntityModel(entity) 5 | local min, max = GetModelDimensions(model) 6 | local rightVector, forwardVector, upVector, position = GetEntityMatrix(entity) 7 | 8 | -- Calculate size 9 | local dim = 10 | { 11 | x = 0.5 * (max.x - min.x), 12 | y = 0.5 * (max.y - min.y), 13 | z = 0.5 * (max.z - min.z) 14 | } 15 | 16 | -- Calculate the eight bounding box edges 17 | local edges = {} 18 | edges[1] = position - dim.y * rightVector - dim.x * forwardVector - dim.z * upVector 19 | edges[2] = edges[1] + 2 * dim.y * rightVector 20 | edges[3] = edges[2] + 2 * dim.z * upVector 21 | edges[4] = edges[1] + 2 * dim.z * upVector 22 | edges[5] = position + dim.y * rightVector + dim.x * forwardVector + dim.z * upVector 23 | edges[6] = edges[5] - 2 * dim.y * rightVector 24 | edges[7] = edges[6] - 2 * dim.z * upVector 25 | edges[8] = edges[5] - 2 * dim.z * upVector 26 | 27 | -- Draw lines to connect the edges and create the bounding box 28 | for i = 1, 4 do 29 | local j = i % 4 + 1 30 | DrawLine(edges[i].x, edges[i].y, edges[i].z, edges[j].x, edges[j].y, edges[j].z, color.r, color.g, color.b, color.a) 31 | DrawLine(edges[i + 4].x, edges[i + 4].y, edges[i + 4].z, edges[j + 4].x, edges[j + 4].y, edges[j + 4].z, color.r, color.g, color.b, color.a) 32 | DrawLine(edges[i].x, edges[i].y, edges[i].z, edges[i + 4].x, edges[i + 4].y, edges[i + 4].z, color.r, color.g, color.b, color.a) 33 | end 34 | end 35 | 36 | local function RotationToDirection(rotation) 37 | local adjustedRotation = 38 | { 39 | x = (math.pi / 180) * rotation.x, 40 | y = (math.pi / 180) * rotation.y, 41 | z = (math.pi / 180) * rotation.z 42 | } 43 | local direction = 44 | { 45 | x = -math.sin(adjustedRotation.z) * math.abs(math.cos(adjustedRotation.x)), 46 | y = math.cos(adjustedRotation.z) * math.abs(math.cos(adjustedRotation.x)), 47 | z = math.sin(adjustedRotation.x) 48 | } 49 | return direction 50 | end 51 | 52 | local function RayCastGamePlayCamera(distance) 53 | local cameraRotation = GetGameplayCamRot() 54 | local cameraCoord = GetGameplayCamCoord() 55 | local direction = RotationToDirection(cameraRotation) 56 | local destination = 57 | { 58 | x = cameraCoord.x + direction.x * distance, 59 | y = cameraCoord.y + direction.y * distance, 60 | z = cameraCoord.z + direction.z * distance 61 | } 62 | local a, b, c, d, e = GetShapeTestResult(StartShapeTestRay(cameraCoord.x, cameraCoord.y, cameraCoord.z, destination.x, destination.y, destination.z, -1, PlayerPedId(), 0)) 63 | return b, c, e 64 | end 65 | 66 | -- Toggle Delete Laser 67 | local activeLaser = false 68 | RegisterNetEvent('ps-adminmenu:client:ToggleLaser', function() 69 | local x = 0.4 70 | local y = 0.025 71 | activeLaser = not activeLaser 72 | CreateThread(function() 73 | while true do 74 | local wait = 7 75 | if activeLaser then 76 | local color = {r = 255, g = 255, b = 255, a = 200} 77 | local position = GetEntityCoords(PlayerPedId()) 78 | local hit, coords, entity = RayCastGamePlayCamera(1000.0) 79 | local objectData = {} 80 | 81 | DisableControlAction(0, 200) 82 | DisableControlAction(0, 26) 83 | 84 | if hit and (IsEntityAVehicle(entity) or IsEntityAPed(entity) or IsEntityAnObject(entity)) then 85 | local entityCoord = GetEntityCoords(entity) 86 | local heading = GetEntityHeading(entity) 87 | local model = GetEntityModel(entity) 88 | local minimum, maximum = GetModelDimensions(model) 89 | DrawEntityBoundingBox(entity, color) 90 | DrawLine(position.x, position.y, position.z, coords.x, coords.y, coords.z, color.r, color.g, color.b, color.a) 91 | 92 | objectData.hash = model 93 | objectData.name = ObjectList[model] 94 | objectData.coords = ("vec4(%s, %s, %s, %s)"):format(entityCoord.x, entityCoord.y, entityCoord.z, heading) 95 | 96 | if IsControlJustReleased(0, 38) then 97 | SetEntityAsMissionEntity(entity, true, true) 98 | DeleteEntity(entity) 99 | end 100 | 101 | if IsDisabledControlJustReleased(0, 26) then 102 | lib.setClipboard(json.encode(objectData, {indent = true})) 103 | end 104 | 105 | elseif coords.x ~= 0.0 and coords.y ~= 0.0 then 106 | DrawLine(position.x, position.y, position.z, coords.x, coords.y, coords.z, color.r, color.g, color.b, color.a) 107 | DrawMarker(28, coords.x, coords.y, coords.z, 0.0, 0.0, 0.0, 0.0, 180.0, 0.0, 0.1, 0.1, 0.1, color.r, color.g, color.b, color.a, false, true, 2, nil, nil, false) 108 | end 109 | 110 | if IsDisabledControlJustReleased(0, 200) then 111 | activeLaser = not activeLaser 112 | end 113 | 114 | SendNUIMessage({ 115 | action = "showEntityInfo", 116 | data = { 117 | show = true, 118 | hash = objectData.hash or "", 119 | name = objectData.name or "", 120 | } 121 | }) 122 | else 123 | local wait = 500 124 | SendNUIMessage({ 125 | action = "showEntityInfo", 126 | data = { 127 | show = false, 128 | } 129 | }) 130 | end 131 | Wait(wait) 132 | end 133 | end) 134 | end) -------------------------------------------------------------------------------- /client/troll.lua: -------------------------------------------------------------------------------- 1 | -- Set on fire 2 | RegisterNetEvent('ps-adminmenu:client:SetOnFire', function(time) 3 | if not time then time = 10 end 4 | local timer = time * 1000 5 | StartEntityFire(cache.serverId) 6 | Wait(timer) 7 | StopEntityFire(cache.serverId) 8 | end) 9 | 10 | -- Explode player 11 | RegisterNetEvent('ps-adminmenu:client:ExplodePlayer', function(damage) 12 | local coords = GetEntityCoords(cache.serverId) 13 | if damage == nil then damage = "nodamage" end 14 | if damage == "nodamage" then 15 | AddExplosion(coords.x, coords.y, coords.z, 'EXPLOSION_TANKER', 2.0, true, false, 2.0) 16 | else 17 | AddExplosion(coords.x, coords.y, coords.z, 2, 0.9, 1, 0, 1065353216, 0) 18 | end 19 | end) 20 | 21 | -- Play Sound 22 | RegisterNetEvent('ps-adminmenu:client:PlaySound', function(data, selectedData) 23 | local data = CheckDataFromKey(data) 24 | if not data or not CheckPerms(data.perms) then return end 25 | local player = selectedData["Player"].value 26 | local sound = selectedData["Sound"].value 27 | 28 | TriggerServerEvent("InteractSound_SV:PlayOnOne", player, sound, 0.30) 29 | end) 30 | 31 | -- Drunk Player 32 | RegisterNetEvent('ps-adminmenu:client:InitiateDrunkEffect', function() 33 | local playerPed = cache.ped 34 | lib.requestAnimSet("MOVE_M@DRUNK@VERYDRUNK") 35 | Wait(650) 36 | SetPedMotionBlur(playerPed, true) 37 | SetPedMovementClipset(playerPed, "MOVE_M@DRUNK@VERYDRUNK", true) 38 | SetPedIsDrunk(playerPed, true) 39 | ShakeGameplayCam("DRUNK_SHAKE", 2.0) 40 | Wait(30000) -- Time To Be Drunk 41 | SetPedMoveRateOverride(playerPed, 1.0) 42 | SetRunSprintMultiplierForPlayer(playerPed, 1.0) 43 | SetPedIsDrunk(playerPed, false) 44 | SetPedMotionBlur(playerPed, false) 45 | ResetPedMovementClipset(playerPed) 46 | ShakeGameplayCam("DRUNK_SHAKE", 0.0) 47 | SetTimecycleModifierStrength(0.0) 48 | end) 49 | -------------------------------------------------------------------------------- /client/utils.lua: -------------------------------------------------------------------------------- 1 | --- @param bool boolean 2 | function ToggleUI(bool) 3 | SetNuiFocus(bool, bool) 4 | SendNUIMessage({ 5 | action = "setVisible", 6 | data = bool 7 | }) 8 | end 9 | 10 | --- @param perms table 11 | function CheckPerms(perms) 12 | return lib.callback.await('ps-adminmenu:callback:CheckPerms', false, perms) 13 | end 14 | 15 | function CheckDataFromKey(key) 16 | local actions = Config.Actions[key] 17 | if actions then 18 | local data = nil 19 | 20 | if actions.event then 21 | data = actions 22 | end 23 | 24 | if actions.dropdown then 25 | for _, v in pairs(actions.dropdown) do 26 | if v.event then 27 | local new = v 28 | new.perms = actions.perms 29 | data = new 30 | break 31 | end 32 | end 33 | end 34 | 35 | return data 36 | end 37 | 38 | local playerActions = Config.PlayerActions[key] 39 | if playerActions then 40 | return playerActions 41 | end 42 | 43 | local otherActions = Config.OtherActions[key] 44 | if otherActions then 45 | return otherActions 46 | end 47 | end 48 | 49 | --- @param title string 50 | --- @param message string 51 | function Log(title, message) 52 | TriggerServerEvent("qb-log:server:CreateLog", "ps-adminmenu", title, "red", message) 53 | end 54 | -------------------------------------------------------------------------------- /client/vehicles.lua: -------------------------------------------------------------------------------- 1 | local function GetVehicleName(hash) 2 | for _, v in pairs(QBCore.Shared.Vehicles) do 3 | if hash == v.hash then 4 | return v.model 5 | end 6 | end 7 | end 8 | 9 | -- Own Vehicle 10 | RegisterNetEvent('ps-adminmenu:client:Admincar', function(data) 11 | local data = CheckDataFromKey(data) 12 | if not data or not CheckPerms(data.perms) then return end 13 | 14 | if not cache.vehicle then return end 15 | 16 | local props = lib.getVehicleProperties(cache.vehicle) 17 | local name = GetVehicleName(props.model) 18 | local sharedVehicles = QBCore.Shared.Vehicles[name] 19 | local hash = GetHashKey(cache.vehicle) 20 | 21 | if sharedVehicles then 22 | TriggerServerEvent('ps-adminmenu:server:SaveCar', props, sharedVehicles, hash, props.plate) 23 | else 24 | QBCore.Functions.Notify(locale("cannot_store_veh"), 'error') 25 | end 26 | end) 27 | 28 | -- Spawn Vehicle 29 | RegisterNetEvent('ps-adminmenu:client:SpawnVehicle', function(data, selectedData) 30 | local data = CheckDataFromKey(data) 31 | if not data or not CheckPerms(data.perms) then return end 32 | 33 | local selectedVehicle = selectedData["Vehicle"].value 34 | local hash = GetHashKey(selectedVehicle) 35 | 36 | if not IsModelValid(hash) then return end 37 | 38 | lib.requestModel(hash) 39 | 40 | if cache.vehicle then 41 | DeleteVehicle(cache.vehicle) 42 | end 43 | 44 | local vehicle = CreateVehicle(hash, GetEntityCoords(cache.ped), GetEntityHeading(cache.ped), true, false) 45 | TaskWarpPedIntoVehicle(cache.ped, vehicle, -1) 46 | 47 | Wait(100) 48 | 49 | if Config.Fuel == "ox_fuel" then 50 | Entity(vehicle).state.fuel = 100.0 51 | else 52 | exports[Config.Fuel]:SetFuel(vehicle, 100.0) 53 | end 54 | 55 | TriggerEvent("vehiclekeys:client:SetOwner", QBCore.Functions.GetPlate(vehicle)) 56 | end) 57 | 58 | -- Refuel Vehicle 59 | RegisterNetEvent('ps-adminmenu:client:RefuelVehicle', function(data) 60 | local data = CheckDataFromKey(data) 61 | if not data or not CheckPerms(data.perms) then return end 62 | 63 | if cache.vehicle then 64 | if Config.Fuel == "ox_fuel" then 65 | Entity(cache.vehicle).state.fuel = 100.0 66 | else 67 | exports[Config.Fuel]:SetFuel(cache.vehicle, 100.0) 68 | end 69 | QBCore.Functions.Notify(locale("refueled_vehicle"), 'success') 70 | else 71 | QBCore.Functions.Notify(locale("not_in_vehicle"), 'error') 72 | end 73 | end) 74 | 75 | -- Change plate 76 | RegisterNetEvent('ps-adminmenu:client:ChangePlate', function(data, selectedData) 77 | local data = CheckDataFromKey(data) 78 | if not data or not CheckPerms(data.perms) then return end 79 | local plate = selectedData["Plate"].value 80 | 81 | if string.len(plate) > 8 then 82 | return QBCore.Functions.Notify(locale("plate_max"), "error", 5000) 83 | end 84 | 85 | if cache.vehicle then 86 | local AlreadyPlate = lib.callback.await("ps-adminmenu:callback:CheckAlreadyPlate", false, plate) 87 | 88 | if AlreadyPlate then 89 | QBCore.Functions.Notify(locale("already_plate"), "error", 5000) 90 | return 91 | end 92 | 93 | local currentPlate = GetVehicleNumberPlateText(cache.vehicle) 94 | TriggerServerEvent('ps-adminmenu:server:ChangePlate', plate, currentPlate) 95 | Wait(100) 96 | SetVehicleNumberPlateText(cache.vehicle, plate) 97 | Wait(100) 98 | TriggerServerEvent('qb-vehiclekeys:server:AcquireVehicleKeys', QBCore.Functions.GetPlate(cache.vehicle)) 99 | else 100 | QBCore.Functions.Notify(locale("not_in_vehicle"), 'error') 101 | end 102 | end) 103 | 104 | 105 | -- Toggle Vehicle Dev mode 106 | local VEHICLE_DEV_MODE = false 107 | local function UpdateVehicleMenu() 108 | while VEHICLE_DEV_MODE do 109 | Wait(1000) 110 | 111 | local vehicle = lib.getVehicleProperties(cache.vehicle) 112 | local name = GetVehicleName(vehicle.model) 113 | local netID = VehToNet(cache.vehicle) 114 | 115 | SendNUIMessage({ 116 | action = "showVehicleMenu", 117 | data = { 118 | show = VEHICLE_DEV_MODE, 119 | name = name, 120 | model = vehicle.model, 121 | netID = netID, 122 | engine_health = vehicle.engineHealth, 123 | body_health = vehicle.bodyHealth, 124 | plate = vehicle.plate, 125 | fuel = vehicle.fuelLevel, 126 | } 127 | }) 128 | end 129 | end 130 | 131 | RegisterNetEvent('ps-adminmenu:client:ToggleVehDevMenu', function(data) 132 | local data = CheckDataFromKey(data) 133 | if not data or not CheckPerms(data.perms) then return end 134 | if not cache.vehicle then return end 135 | 136 | VEHICLE_DEV_MODE = not VEHICLE_DEV_MODE 137 | 138 | if VEHICLE_DEV_MODE then 139 | CreateThread(UpdateVehicleMenu) 140 | end 141 | end) 142 | 143 | -- Max Mods 144 | local PERFORMANCE_MOD_INDICES = { 11, 12, 13, 15, 16 } 145 | local function UpgradePerformance(vehicle) 146 | SetVehicleModKit(vehicle, 0) 147 | ToggleVehicleMod(vehicle, 18, true) 148 | SetVehicleFixed(vehicle) 149 | 150 | for _, modType in ipairs(PERFORMANCE_MOD_INDICES) do 151 | local maxMod = GetNumVehicleMods(vehicle, modType) - 1 152 | SetVehicleMod(vehicle, modType, maxMod, customWheels) 153 | end 154 | 155 | QBCore.Functions.Notify(locale("vehicle_max_modded"), 'success', 7500) 156 | end 157 | 158 | 159 | RegisterNetEvent('ps-adminmenu:client:maxmodVehicle', function(data) 160 | local data = CheckDataFromKey(data) 161 | if not data or not CheckPerms(data.perms) then return end 162 | 163 | if cache.vehicle then 164 | UpgradePerformance(cache.vehicle) 165 | else 166 | QBCore.Functions.Notify(locale("vehicle_not_driver"), 'error', 7500) 167 | end 168 | end) 169 | 170 | -- Spawn Personal vehicles 171 | 172 | RegisterNetEvent("ps-adminmenu:client:SpawnPersonalVehicle", function(data, selectedData) 173 | local data = CheckDataFromKey(data) 174 | if not data or not CheckPerms(data.perms) then return end 175 | 176 | local plate = selectedData['VehiclePlate'].value 177 | local ped = PlayerPedId() 178 | local coords = QBCore.Functions.GetCoords(ped) 179 | local cid = QBCore.Functions.GetPlayerData().citizenid 180 | 181 | lib.callback('ps-adminmenu:server:GetVehicleByPlate', false, function(vehModel) 182 | vehicle = vehModel 183 | end, plate) 184 | 185 | Wait(100) 186 | QBCore.Functions.TriggerCallback('QBCore:Server:SpawnVehicle', function(vehicle) 187 | local veh = NetToVeh(vehicle) 188 | local props = QBCore.Functions.GetVehicleProperties(veh) 189 | SetEntityHeading(veh, coords.w) 190 | TaskWarpPedIntoVehicle(ped, veh, -1) 191 | SetVehicleModKit(veh, 0) 192 | Wait(100) 193 | QBCore.Functions.SetVehicleProperties(veh, props) 194 | SetVehicleNumberPlateText(veh, plate) 195 | 196 | if Config.Fuel == "ox_fuel" then 197 | Entity(veh).state.fuel = 100.0 198 | else 199 | exports[Config.Fuel]:SetFuel(veh, 100.0) 200 | end 201 | 202 | TriggerEvent("vehiclekeys:client:SetOwner", plate) 203 | TriggerEvent('iens:repaira', ped) 204 | TriggerEvent('vehiclemod:client:fixEverything', ped) 205 | end, vehicle, coords, true) 206 | end) 207 | 208 | 209 | -- Get Vehicle Data 210 | lib.callback.register("ps-adminmenu:client:getvehData", function(vehicle) 211 | lib.requestModel(vehicle) 212 | 213 | local coords = vec(GetOffsetFromEntityInWorldCoords(cache.ped, 0.0, 2.0, 0.5), GetEntityHeading(cache.ped) + 90) 214 | local veh = CreateVehicle(vehicle, coords, false, false) 215 | 216 | local prop = {} 217 | if DoesEntityExist(veh) then 218 | SetEntityCollision(veh, false, false) 219 | FreezeEntityPosition(veh, true) 220 | prop = QBCore.Functions.GetVehicleProperties(veh) 221 | Wait(500) 222 | DeleteVehicle(veh) 223 | end 224 | 225 | return prop 226 | end) 227 | -------------------------------------------------------------------------------- /client/world.lua: -------------------------------------------------------------------------------- 1 | -- Changes the time 2 | RegisterNetEvent('ps-adminmenu:client:ChangeTime', function(data, selectedData) 3 | local data = CheckDataFromKey(data) 4 | if not data or not CheckPerms(data.perms) then return end 5 | local time = selectedData["Time Events"].value 6 | 7 | if not time then return end 8 | 9 | TriggerServerEvent('qb-weathersync:server:setTime', time, 00) 10 | end) 11 | 12 | -- Changes the weather 13 | RegisterNetEvent('ps-adminmenu:client:ChangeWeather', function(data, selectedData) 14 | local data = CheckDataFromKey(data) 15 | if not data or not CheckPerms(data.perms) then return end 16 | local weather = selectedData["Weather"].value 17 | 18 | TriggerServerEvent('qb-weathersync:server:setWeather', weather) 19 | end) 20 | 21 | RegisterNetEvent('ps-adminmenu:client:copyToClipboard', function(data, selectedData) 22 | local data = CheckDataFromKey(data) 23 | if not data or not CheckPerms(data.perms) then return end 24 | 25 | local dropdown = selectedData["Copy Coords"].value 26 | local ped = PlayerPedId() 27 | local string = nil 28 | if dropdown == 'vector2' then 29 | local coords = GetEntityCoords(ped) 30 | local x = QBCore.Shared.Round(coords.x, 2) 31 | local y = QBCore.Shared.Round(coords.y, 2) 32 | string = "vector2(".. x ..", ".. y ..")" 33 | QBCore.Functions.Notify(locale("copy_vector2"), 'success') 34 | elseif dropdown == 'vector3' then 35 | local coords = GetEntityCoords(ped) 36 | local x = QBCore.Shared.Round(coords.x, 2) 37 | local y = QBCore.Shared.Round(coords.y, 2) 38 | local z = QBCore.Shared.Round(coords.z, 2) 39 | string = "vector3(".. x ..", ".. y ..", ".. z ..")" 40 | QBCore.Functions.Notify(locale("copy_vector3"), 'success') 41 | elseif dropdown == 'vector4' then 42 | local coords = GetEntityCoords(ped) 43 | local x = QBCore.Shared.Round(coords.x, 2) 44 | local y = QBCore.Shared.Round(coords.y, 2) 45 | local z = QBCore.Shared.Round(coords.z, 2) 46 | local heading = GetEntityHeading(ped) 47 | local h = QBCore.Shared.Round(heading, 2) 48 | string = "vector4(".. x ..", ".. y ..", ".. z ..", ".. h ..")" 49 | QBCore.Functions.Notify(locale("copy_vector4"), 'success') 50 | elseif dropdown == 'heading' then 51 | local heading = GetEntityHeading(ped) 52 | local h = QBCore.Shared.Round(heading, 2) 53 | string = h 54 | QBCore.Functions.Notify(locale("copy_heading"), 'success') 55 | elseif string == nil then 56 | QBCore.Functions.Notify(locale("empty_input"), 'error') 57 | end 58 | 59 | lib.setClipboard(string) 60 | 61 | end) -------------------------------------------------------------------------------- /fxmanifest.lua: -------------------------------------------------------------------------------- 1 | fx_version 'cerulean' 2 | 3 | game "gta5" 4 | 5 | author "Project Sloth & OK1ez" 6 | version '1.1.6' 7 | description 'Admin Menu' 8 | repository 'https://github.com/Project-Sloth/ps-adminmenu' 9 | 10 | lua54 'yes' 11 | 12 | ui_page 'html/index.html' 13 | -- ui_page 'http://localhost:5173/' --for dev 14 | 15 | client_script { 16 | 'client/**', 17 | } 18 | 19 | server_script { 20 | "server/**", 21 | "@oxmysql/lib/MySQL.lua", 22 | } 23 | 24 | shared_script { 25 | '@ox_lib/init.lua', 26 | "shared/**", 27 | } 28 | 29 | files { 30 | 'html/**', 31 | 'data/ped.lua', 32 | 'data/object.lua', 33 | 'locales/*.json', 34 | } 35 | 36 | ox_lib 'locale' -- v3.8.0 or above 37 | -------------------------------------------------------------------------------- /html/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | ps-adminmenu 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /locales/de.json: -------------------------------------------------------------------------------- 1 | { 2 | "already_plate": "Dies Kennzeichen wurde bereits bei einem anderen Fahrzeug verwendet", 3 | "amount_max": "Der maximale Wert ist $999,999", 4 | "ban_expires": "Ban läuft aus: ", 5 | "ban_perm": "Du wurdest permanent gebannt!", 6 | "banreason": "Grund: %s, bis %s", 7 | "banned": "Du wurdest gebannt!", 8 | "blackout": "Blackout ist %s", 9 | "blips_activated": "Blips aktiviert", 10 | "blips_deactivated": "Blips deaktiviert", 11 | "body_health": "Karosserieschaden: ", 12 | "bucket_get": "Spieler %s ist in bucket: %s", 13 | "bucket_set": "Routing gesetzt auf bucket: %s", 14 | "bucket_set_for_target": "Routing gesetzt für: %s in bucket: %s", 15 | "cannot_store_veh": "Du kannst diese Fahrzeug nicht in die Garage stellen", 16 | "cant_spectate_yourself": "Du kannst dich nicht selbst spectaten", 17 | "command_admin_desc": "Admin Menü öffnen", 18 | "command_noclip_desc": "NoClip benutzen", 19 | "copy_heading": "Heading kopiert", 20 | "copy_vector2": "vector2 kopiert", 21 | "copy_vector3": "vector3 kopiert", 22 | "copy_vector4": "vector4 kopiert", 23 | "deFrozen": "Du hast %s erfolgreich entfroren", 24 | "empty_input": "Leere Eingabe", 25 | "eng_health": "Motor Schaden: ", 26 | "entered_vehicle": "Du bist in ein Fahrzeug eingestiegen", 27 | "ent_id": "Entity ID: ", 28 | "explode_player": "Person wurde in die Luft gejagt :P", 29 | "Frozen": "%s wurde eingefroren", 30 | "gangset": "Du hast %s die Gang: %s mit dem Rang %s gegeben", 31 | "give_item": "Du gibst %s an %s", 32 | "give_item_all": "Du gibst %s an jeden Spieler", 33 | "give_money": "Du gibst %s %s", 34 | "give_money_all": "Du gibst %s an jeden Spieler", 35 | "give_money_all_crypto": "Du gibst %s Crypto/s an jeden Spieler", 36 | "give_money_crypto": "Du gibst %s Crypto/s an %s", 37 | "givecar.plates_alreadyused": "Fahrzeug wurde nicht weitergegeben. Das Kennzeichen %s wurde bereits in einem anderen Fahrzeug verwendet.", 38 | "givecar.success.source": "Erfolgreich das Fahrzeug %s an %s gegeben.", 39 | "givecar.success.target": "Du hast ein Fahrzeug mit dem Kennzeichen %s erhalten. Du findest es in %s.", 40 | "godmode": "Godmode: %s", 41 | "hash": "Hash: ", 42 | "inf_ammo_toggled": "Unendlich Munition aktiviert/deaktiviert", 43 | "invisible": "Unsichtbar: %s", 44 | "invcleared": "%s's Inventar wurde geleert", 45 | "jobset": "Du hast %s den Job: %s mit dem Rang %s gegeben", 46 | "kicked": "Du wurdest gekickt!", 47 | "model": "Modell: ", 48 | "names_activated": "Namen aktiviert", 49 | "names_deactivated": "Namen deaktiviert", 50 | "net_id": "Net ID: ", 51 | "net_id_not_registered": "Nicht registriert", 52 | "new_staffchat": "Neue Admin Nachricht", 53 | "no_free_seats": "Das Fahrzeug hat keine freien Sitze!", 54 | "no_perms": "Du hast keine Berechtigung dies zu tun", 55 | "no_waypoint": "Kein Wegpunkt gesetzt.", 56 | "no_weapon": "Er hat keine Waffe.", 57 | "noclip_disabled": "No-clip deaktiviert", 58 | "noclip_enabled": "No-clip aktiviert", 59 | "not_enough_money": "Der Spieler hat nicht genug Geld um es zu entfernen", 60 | "not_in_veh": "Du bist in keinem Fahrzeug..", 61 | "not_in_vehicle": "Du bist in keinem Fahrzeug", 62 | "not_online": "Spieler nicht online", 63 | "ped_coords": "Ped Koordinaten:", 64 | "plate_max": "Die Maximale Anzahl an Zeichen ist 8", 65 | "plate_invalid": "Das Kennzeichen ist ungültig", 66 | "player_not_found": "Spieler nicht gefunden.", 67 | "player_not_in_veh": "Du bist in keinem Fahrzeug..", 68 | "player_perms": "%s hat die Berechtigungen [ %s ] bekommen.", 69 | "playerbanned": "Du hast %s für %s mit dem Grund: %s gebannt", 70 | "playerdrunk": "Spieler betrunken gemacht ", 71 | "reason": "Grund: ", 72 | "refueled_vehicle": "Fahrzeug aufgefüllt", 73 | "restarted_resource": "Resource neugestartet", 74 | "removed_stress_player": "Stress von Spieler entfernt", 75 | "set_on_fire": "Person angezündet :P", 76 | "set_wepaon_ammo": "%s Munition gegeben!", 77 | "started_resource": "Resource gestartet", 78 | "status_title": "CFX Status", 79 | "stopped_resource": "Resource gestoppt", 80 | "state_changed": "Du hast den Status für das Fahrzeug gesetzt.", 81 | "take_money": "Du hast %s %s entfernt", 82 | "take_money_crypto": "Du hast %s Crypto/s von %s entfernt", 83 | "target_same_bucket": "Du hast versucht %s den gleichen bucket zu setzen %s in the same bucket", 84 | "teleported_waypoint": "Zu Wegpunkt teleportiert.", 85 | "toggled_cuffs": "Handschellen aktiviert/deaktiviert", 86 | "toggle_dev": "Dev Modus aktiviert/deaktiviert", 87 | "tp_error": "Fehler beim teleportieren.", 88 | "u_veh_owner": "Dieses Fahrzeug gehört bereits dir..", 89 | "veh_fixed": "Fahrzeug für %s repariert", 90 | "veh_owner": "Das Fahrzeug gehört nun dir!", 91 | "vehicle_dev_data": "Fahrzeug Informationen", 92 | "vehicle_max_modded": "Das Fahrzeug wurde maximal getuned", 93 | "vehicle_not_driver": "Nicht im Fahrersitz", 94 | "warned": "Du wurdest verwarnt ", 95 | "warngiven": "Verwarnt: ", 96 | "weatherType": "Wetter gewechselt zu: %s" 97 | } -------------------------------------------------------------------------------- /locales/en.json: -------------------------------------------------------------------------------- 1 | { 2 | "already_plate": "This number plate has been used on another vehicle", 3 | "amount_max": "Max Input is $999,999", 4 | "ban_expires": "Ban expires: ", 5 | "ban_perm": "You have been permanently banned!", 6 | "banreason": "Reason: %s, until %s", 7 | "banned": "You have been banned!", 8 | "blackout": "Blackout is %s", 9 | "blips_activated": "Blips activated", 10 | "blips_deactivated": "Blips deactivated", 11 | "body_health": "Body Health: ", 12 | "bucket_get": "Player %s is in bucket: %s", 13 | "bucket_set": "Routing set to bucket: %s", 14 | "bucket_set_for_target": "Routing bucket set for: %s to bucket: %s", 15 | "cannot_store_veh": "Cannot store this car in your garage", 16 | "cant_spectate_yourself": "You cant spectate yourself", 17 | "command_admin_desc": "Toggle Admin Menu", 18 | "command_noclip_desc": "Toggle NoClip", 19 | "copy_heading": "Copied heading", 20 | "copy_vector2": "Copied vector2", 21 | "copy_vector3": "Copied vector3", 22 | "copy_vector4": "Copied vector4", 23 | "deFrozen": "You've set %s free", 24 | "empty_input": "Input was empty.", 25 | "eng_health": "Engine Health: ", 26 | "entered_vehicle": "Entered vehicle", 27 | "ent_id": "Entity ID: ", 28 | "explode_player": "Person was exploded :P", 29 | "Frozen": "%s's successfully frozen", 30 | "gangset": "You have given %s the gang: %s with grade %s", 31 | "give_item": "Gave %s to %s", 32 | "give_item_all": "Gave %s to every Player", 33 | "give_money": "Gave %s %s", 34 | "give_money_all": "Added %s to every Players", 35 | "give_money_all_crypto": "Gave %s Crypto/s to every Player", 36 | "give_money_crypto": "Gave %s Crypto/s to %s", 37 | "givecar.plates_alreadyused": "Unable to gave vehicle. Number plate %s is already in use on another vehicle", 38 | "givecar.success.source": "Successfully gave the vehicle %s to %s.", 39 | "givecar.success.target": "You have received a new vehicle with license plate %s. You can check it at %s.", 40 | "godmode": "Godmode is %s", 41 | "hash": "Hash: ", 42 | "inf_ammo_toggled": "Infinite Ammo Toggled", 43 | "invisible": "Invisible: %s", 44 | "invcleared": "%s's inventory is cleared", 45 | "jobset": "You have given %s the job: %s with grade %s", 46 | "kicked": "You have been kicked!", 47 | "model": "Model: ", 48 | "names_activated": "Names activated", 49 | "names_deactivated": "Names deactivated", 50 | "net_id": "Net ID: ", 51 | "net_id_not_registered": "Not registered", 52 | "new_staffchat": "New Staff Message", 53 | "no_free_seats": "The vehicle has no free seats!", 54 | "no_perms": "You do not have permission to do this", 55 | "no_waypoint": "No Waypoint Set.", 56 | "no_weapon": "He doesn't have a gun.", 57 | "noclip_disabled": "No-clip disabled", 58 | "noclip_enabled": "No-clip enabled", 59 | "not_enough_money": "Insufficient funds to remove money from the player", 60 | "not_in_veh": "You are not in a vehicle..", 61 | "not_in_vehicle": "Your not in a Vehicle", 62 | "not_online": "Player not online", 63 | "ped_coords": "Ped Coordinates:", 64 | "plate_max": "Max Digits for a Plate is 8", 65 | "plate_invalid": "Invalid Plate", 66 | "player_not_found": "Player not found.", 67 | "player_not_in_veh": "You are not in a vehicle..", 68 | "player_perms": "%s got [ %s ] Permissions.", 69 | "playerbanned": "You have banned %s for %s with reason: %s", 70 | "playerdrunk": "Made Player Drunk: ", 71 | "reason": "Reason: ", 72 | "refueled_vehicle": "Refueled Vehicle", 73 | "restarted_resource": "Restarted Resource", 74 | "removed_stress_player": "Removed stress from Player", 75 | "set_on_fire": "Person set on Fire :P", 76 | "set_wepaon_ammo": "%s ammunition given!", 77 | "started_resource": "Started Resource", 78 | "status_title": "CFX Status", 79 | "stopped_resource": "Stopped Resource", 80 | "state_changed": "You have set the state for the vehicle.", 81 | "take_money": "Removed %s from %s", 82 | "take_money_crypto": "Removed %s Crypto/s from %s", 83 | "target_same_bucket": "Tried to place %s in the same bucket", 84 | "teleported_waypoint": "Teleported To Waypoint.", 85 | "toggled_cuffs": "Toggled Cuffs", 86 | "toggle_dev": "Toggled Dev Mode", 87 | "tp_error": "Error While Teleporting.", 88 | "u_veh_owner": "This vehicle is already yours..", 89 | "veh_fixed": "Vehicle fixed for %s", 90 | "veh_owner": "The vehicle is now yours!", 91 | "vehicle_dev_data": "Vehicle Information", 92 | "vehicle_max_modded": "Vehicle has been max modded", 93 | "vehicle_not_driver": "Not in the drivers seat", 94 | "warned": "You have been warned ", 95 | "warngiven": "Warned: ", 96 | "weatherType": "Weather is changed to: %s" 97 | } 98 | -------------------------------------------------------------------------------- /locales/es.json: -------------------------------------------------------------------------------- 1 | { 2 | "already_plate": "Esta matrícula ya ha sido usada en otro vehículo", 3 | "amount_max": "La cantidad máxima es de $999,999", 4 | "ban_expires": "El baneo expira: ", 5 | "ban_perm": "¡Has sido baneado permanentemente!", 6 | "banreason": "Motivo: %s, hasta %s", 7 | "banned": "¡Has sido baneado!", 8 | "blackout": "El apagón ha sido %s", 9 | "blips_activated": "Marcadores activados", 10 | "blips_deactivated": "Marcadores desactivados", 11 | "body_health": "Salud: ", 12 | "bucket_get": "El jugador %s está en dimensión: %s", 13 | "bucket_set": "La dimensión ha sido actualizada a la: %s", 14 | "bucket_set_for_target": "La dimensión ha sido actualizada para: %s a la dimensión: %s", 15 | "cannot_store_veh": "No puedes guardar este coche en tu garaje", 16 | "cant_spectate_yourself": "No puedes observarte a ti mismo", 17 | "command_admin_desc": "Alternar menú de administración", 18 | "command_noclip_desc": "Alternar NoClip", 19 | "copy_heading": "Heading copiado", 20 | "copy_vector2": "Vector2 copiado", 21 | "copy_vector3": "Vector3 copiado", 22 | "copy_vector4": "Vector4 copiado", 23 | "deFrozen": "Has liberado a %s", 24 | "empty_input": "El texto esta vacío", 25 | "eng_health": "Salud: ", 26 | "entered_vehicle": "Entró en el vehículo", 27 | "ent_id": "ID de entidad: ", 28 | "explode_player": "¡Has explotado a la persona! :P", 29 | "Frozen": "%s ha sido congelado", 30 | "gangset": "Has dado a %s la banda: %s con grado %s", 31 | "give_item": "Diste %s a %s", 32 | "give_item_all": "Diste %s a todos los jugadores", 33 | "give_money": "Diste %s a %s", 34 | "give_money_all": "Diste %s a todos los jugadores %s", 35 | "give_money_all_crypto": "Diste %s criptomoneda/s a todos los jugadores", 36 | "give_money_crypto": "Diste %s criptomoneda/s a %s", 37 | "givecar.plates_alreadyused": "No se puede dar el vehículo, la matrícula %s ya está en uso en otro vehículo", 38 | "givecar.success.source": "Has dado con éxito el vehículo %s a %s", 39 | "givecar.success.target": "Has recibido un nuevo vehículo con matrícula %s, puedes comprobarlo en %s.", 40 | "godmode": "Has %s la inmortalidad", 41 | "hash": "Hash: ", 42 | "inf_ammo_toggled": "Alternada munición infinita", 43 | "invisible": "Invisible: %s", 44 | "invcleared": "El inventario de %s ha sido eliminado", 45 | "jobset": "Has dado a %s el trabajo: %s con grado %s", 46 | "kicked": "¡Has sido expulsado!", 47 | "model": "Modelo: ", 48 | "names_activated": "Nombres activados", 49 | "names_deactivated": "Nombres desactivados", 50 | "net_id": "ID de red: ", 51 | "net_id_not_registered": "No registrado", 52 | "new_staffchat": "Nuevo mensaje del personal", 53 | "no_free_seats": "¡El vehículo no tiene asientos libres!", 54 | "no_perms": "No tienes permiso para hacer esto", 55 | "no_waypoint": "No se ha establecido ningún punto de referencia.", 56 | "no_weapon": "No tiene un arma.", 57 | "noclip_disabled": "No-clip desactivado", 58 | "noclip_enabled": "No-clip activado", 59 | "not_enough_money": "Fondos insuficientes para quitar dinero al jugador", 60 | "not_in_veh": "No estás en un vehículo.", 61 | "not_in_vehicle": "No estás en un vehículo", 62 | "not_online": "El jugador no está en línea", 63 | "ped_coords": "Coordenadas del PED:", 64 | "plate_max": "La máxima cantidad de dígitos para una matrícula es 8", 65 | "plate_invalid": "Placa no válida", 66 | "player_not_found": "Jugador no encontrado", 67 | "player_not_in_veh": "No estás en un vehículo", 68 | "player_perms": "%s tiene permisos [ %s ]", 69 | "playerbanned": "Has baneado a %s por %s con motivo: %s", 70 | "playerdrunk": "Hecho jugador borracho: ", 71 | "reason": "Motivo: ", 72 | "refueled_vehicle": "Vehículo repostado", 73 | "restarted_resource": "Recurso reiniciado", 74 | "removed_stress_player": "Se eliminó el estrés del jugador", 75 | "set_on_fire": "¡Persona prendida fuego! :P", 76 | "set_wepaon_ammo": "¡Se ha dado munición a %s!", 77 | "started_resource": "Recurso iniciado", 78 | "status_title": "Estado de CFX", 79 | "state_changed": "Ha configurado el estado del vehículo.", 80 | "stopped_resource": "Recurso detenido", 81 | "take_money": "Se ha quitado %s de %s", 82 | "take_money_crypto": "Se ha quitado %s criptomoneda/s de %s", 83 | "target_same_bucket": "Intentaste colocar %s en la misma dimensión", 84 | "teleported_waypoint": "Teletransportado al marcador del mapa", 85 | "toggled_cuffs": "Esposas alternadas", 86 | "toggle_dev": "Alternado modo de desarrollo", 87 | "tp_error": "Error al teleportar", 88 | "u_veh_owner": "Este vehículo ya es tuyo", 89 | "veh_fixed": "Vehículo reparado a %s", 90 | "veh_owner": "¡El vehículo ahora es tuyo!", 91 | "vehicle_dev_data": "Información del vehículo", 92 | "vehicle_max_modded": "El vehículo ha sido modificado al máximo", 93 | "vehicle_not_driver": "No estás en el asiento del conductor", 94 | "warned": "Has sido advertido", 95 | "warngiven": "Advertencia: ", 96 | "weatherType": "El clima ha cambiado a: %s" 97 | } 98 | -------------------------------------------------------------------------------- /locales/fr.json: -------------------------------------------------------------------------------- 1 | { 2 | "already_plate": "Cette plaque est déjà utilisé sur un autre véhicule", 3 | "amount_max": "Le nombre maximum est de $999,999", 4 | "ban_expires": "Le bannissement expire : ", 5 | "ban_perm": "Vous avez été banni de manière permanente!", 6 | "banreason": "Raison: %s, jusqu'à %s", 7 | "banned": "Vous avez été banni !", 8 | "blackout": "Le black-out est %s", 9 | "blips_activated": "Blips activé", 10 | "blips_deactivated": "Blips désactivé", 11 | "body_health": "Santé de la carrosserie: ", 12 | "bucket_get": "Joueur %s est dans le 'routing-bucket': %s", 13 | "bucket_set": "'routing-bucker' mis à %s", 14 | "bucket_set_for_target": "Changement du 'routing-bucket' de %s vers: %s", 15 | "cannot_store_veh": "Impossible de stocker ce véhicule dans le garage..", 16 | "cant_spectate_yourself": "Vous ne pouvez pas vous regarder vous même", 17 | "command_admin_desc": "Basculer le Menu Admin", 18 | "command_noclip_desc": "Basculer le No-Clip", 19 | "copy_heading": "Copié direction (heading)", 20 | "copy_vector2": "Copié vector2", 21 | "copy_vector3": "Copié vector3", 22 | "copy_vector4": "Copié vector4", 23 | "deFrozen": "Vous avez dé-gelé %s", 24 | "empty_input": "Champ vide.", 25 | "eng_health": "Santé du moteur: ", 26 | "ent_id": "ID de l'entité : ", 27 | "entered_vehicle": "Entrée dans le véhicule", 28 | "explode_player": "Joueur explosé :P", 29 | "Frozen": "%s à été gelé", 30 | "gangset": "Vous avez donné à %s le gang: %s avec le grade %s", 31 | "give_item": "Donné %s à %s", 32 | "give_item_all": "Donné %s à tous les joueurs", 33 | "give_money": "Donné %s %s", 34 | "give_money_all": "Donné %s à tous les joueurs %s", 35 | "give_money_all_crypto": "Donné %s Crypto/s à tous les joueurs", 36 | "give_money_crypto": "Donné %s Crypto/s à %s", 37 | "givecar.plates_alreadyused": "Impossible de donner le véhicule. La plaque d'immatriculation %s est déjà utilisée sur un autre véhicule", 38 | "givecar.success.source": "Véhicule %s donné avec succès à %s.", 39 | "givecar.success.target": "Vous avez reçu un nouveau véhicule avec la plaque d'immatriculation %s. Vous pouvez le vérifier à %s.", 40 | "godmode": "Mode dieux est %s", 41 | "hash": "Hash: ", 42 | "inf_ammo_toggled": "Munitions illimité basculé", 43 | "invisible": "Invisible %s", 44 | "invcleared": "Inventaire de %s vidé", 45 | "jobset": "Vous avez donné à %s le travail: %s avec le grade %s", 46 | "kicked": "Vous avez été expulsé !", 47 | "missing_args": "Vous n'avez pas entré tous les arguments (x, y, z)", 48 | "model": "Modèle: ", 49 | "names_activated": "Noms activé", 50 | "names_deactivated": "Noms désactivé", 51 | "net_id": "ID réseau : ", 52 | "net_id_not_registered": "Non enregistré", 53 | "new_staffchat": "Nouveau message du chat staff", 54 | "no_free_seats": "Le véhicule n'as pas de place!", 55 | "no_perms": "Vous n'avez pas les permissions nécessaires.", 56 | "no_weapon": "Ce joueur n'as pas d'arme.", 57 | "no_waypoint": "Vous n'avez pas de marqueur.", 58 | "noclip_disabled": "No-Clip Désactivé", 59 | "noclip_enabled": "No-Clip Activé", 60 | "not_enough_money": "Fonds insuffisants pour retirer de l'argent du joueur", 61 | "not_in_veh": "Vous n'êtes pas dans un véhicule..", 62 | "not_in_vehicle": "Vous n'êtes pas dans un véhicule", 63 | "not_online": "Joueur Hors-Ligne", 64 | "ped_coords": "Coordonnées du ped:", 65 | "plate_max": "Le nombre de charactère maximum pour une plaque est de 8", 66 | "plate_invalid": "Plaque invalide", 67 | "player_not_found": "Joueur non trouvé.", 68 | "player_not_in_veh": "Vous n'êtes pas dans un véhicule..", 69 | "player_perms": "%s à eu [ %s ] Persmissions.", 70 | "playerbanned": "Vous avez banni %s pour %s avec la raison : %s", 71 | "playerdrunk": "A rendu le joueur ivre: ", 72 | "reason": "Raison : ", 73 | "refueled_vehicle": "Véhicule remplis d'essence", 74 | "restarted_resource": "Ressource redémarré", 75 | "removed_stress_player": "Suppression du stress du joueur", 76 | "set_on_fire": "Joueur mise en feu :P", 77 | "set_wepaon_ammo": "%s munitions donné!", 78 | "started_resource": "Ressource démarrée", 79 | "status_title": "Status CFX", 80 | "stopped_resource": "Ressource arrêté", 81 | "state_changed": "Vous avez défini l'état du véhicule.", 82 | "take_money": "Retiré %s à %s", 83 | "take_money_crypto": "Retiré %s Crypto/s à %s", 84 | "target_same_bucket": "Vous avez essayé de mettre %s dans le même 'routing-bucket'", 85 | "teleported_waypoint": "Téléporter au Marqueur.", 86 | "tp_error": "Erreur lors de la téléportation.", 87 | "toggled_cuffs": "Menottes Basculé", 88 | "toggle_dev": "Mode Dev Basculé", 89 | "u_veh_owner": "Ce véhicule est déjà le votre..", 90 | "vehicle_dev_data": "Informations sur le véhicule", 91 | "vehicle_max_modded": "Véhicule modifié au maximum", 92 | "vehicle_not_driver": "Vous n'êtes pas dans le siège conducteur.", 93 | "veh_fixed": "Véhicule réparé %s", 94 | "veh_owner": "Vous êtes maintenant le propriétaire de ce véhicule!", 95 | "warngiven": "Avertissement: ", 96 | "warned": "Vous avez été avertis ", 97 | "weatherType": "Température mise à: %s" 98 | } -------------------------------------------------------------------------------- /locales/id.json: -------------------------------------------------------------------------------- 1 | { 2 | "already_plate": "Nomor plat ini telah digunakan pada kendaraan lain.", 3 | "amount_max": "Maksimum input adalah $999,999.", 4 | "ban_expires": "Ban berakhir: ", 5 | "ban_perm": "Kamu telah dibanned secara permanen!", 6 | "banned": "Kamu telah dibanned!", 7 | "banreason": "Alasan: %s, hingga %s.", 8 | "blackout": "Padamkan Listrik: %s.", 9 | "blips_activated": "Blips diaktifkan.", 10 | "blips_deactivated": "Blips dinonaktifkan.", 11 | "body_health": "Kesehatan Bodi: ", 12 | "bucket_get": "Pemain %s berada di dalam bucket: %s.", 13 | "bucket_set": "Routing di atur ke bucket: %s", 14 | "bucket_set_for_target": "Routing Bucket diatur untuk: %s ke Bucket: %s.", 15 | "cant_spectate_yourself": "Kamu tidak bisa menyaksikan dirimu sendiri.", 16 | "cannot_store_veh": "Tidak dapat menyimpan kendaraan ini di garasimu.", 17 | "command_admin_desc": "Aktifkan/Nonaktifkan Menu Admin.", 18 | "command_noclip_desc": "Aktifkan/Nonaktifkan NoClip.", 19 | "copy_heading": "Menyalin arah.", 20 | "copy_vector2": "Menyalin vector2.", 21 | "copy_vector3": "Menyalin vector3.", 22 | "copy_vector4": "Menyalin vector4.", 23 | "deFrozen": "%s telah di unfreeze", 24 | "empty_input": "Input kosong.", 25 | "eng_health": "Kesehatan Mesin: ", 26 | "entered_vehicle": "Masuk ke dalam kendaraan.", 27 | "ent_id": "ID Entitas: ", 28 | "explode_player": "Seseorang di ledakkan :P.", 29 | "Frozen": "%s berhasil di freeze.", 30 | "gangset": "Kamu telah memberikan %s geng: %s dengan pangkat %s.", 31 | "give_item": "Memberikan %s kepada %s.", 32 | "give_item_all": "Memberikan %s kepada setiap pemain.", 33 | "give_money": "Memberikan %s %s.", 34 | "give_money_all": "Menambahkan %s ke setiap pemain %s.", 35 | "give_money_all_crypto": "Memberikan %s Crypto/s kepada setiap pemain.", 36 | "give_money_crypto": "Memberikan %s Crypto/s kepada %s.", 37 | "givecar.error.plates_alreadyused": "Tidak bisa memberi kendaraan. Pelat nomor %s sudah di gunakan pada kendaraan lain", 38 | "givecar.success.source": "Berhasil memberi kendaraan %s kepada %s", 39 | "givecar.success.target": "Anda menerima kendaraan baru dengan pelat nomor %s. Anda bisa mengecek nya di %s", 40 | "godmode": "Godmode %s.", 41 | "hash": "Hash: ", 42 | "inf_ammo_toggled": "Ammunisi tak terbatas diaktifkan.", 43 | "invcleared": "Inventory %s telah dibersihkan.", 44 | "invisible": "Tidak terlihat: %s.", 45 | "jobset": "Kamu telah memberikan %s pekerjaan: %s dengan pangkat %s.", 46 | "kicked": "Kamu telah ditendang!", 47 | "missing_args": "Tidak semua argumen telah dimasukkan (x, y, z).", 48 | "model": "Model: ", 49 | "names_activated": "Nama diaktifkan.", 50 | "names_deactivated": "Nama dinonaktifkan.", 51 | "net_id": "ID Jaringan: ", 52 | "net_id_not_registered": "Tidak terdaftar.", 53 | "new_staffchat": "Pesan Staff Baru.", 54 | "no_free_seats": "Kendaraan ini tidak memiliki kursi kosong!", 55 | "no_perms": "Kamu tidak memiliki izin untuk melakukannya.", 56 | "no_weapon": "Dia tidak memiliki senjata.", 57 | "no_waypoint": "Tidak ada Waypoint yang ditetapkan.", 58 | "noclip_disabled": "No-clip dinonaktifkan.", 59 | "noclip_enabled": "No-clip diaktifkan.", 60 | "not_enough_money": "Dana tidak mencukupi untuk mengurangi uang pemain.", 61 | "not_in_veh": "Kamu tidak berada di dalam kendaraan.", 62 | "not_in_vehicle": "Kamu tidak berada di dalam kendaraan.", 63 | "not_online": "Pemain tidak online.", 64 | "ped_coords": "Koordinat Ped:", 65 | "plate_max": "Maksimum digit untuk plat adalah 8.", 66 | "plate_invalid": "Pelat Tidak Valid", 67 | "player_not_found": "Pemain tidak ditemukan.", 68 | "player_not_in_veh": "Kamu tidak berada di dalam kendaraan.", 69 | "player_perms": "%s mendapatkan [ %s ] Izin.", 70 | "playerbanned": "Kamu telah membanned %s selama %s dengan alasan: %s.", 71 | "playerdrunk": "Membuat Pemain Mabuk: ", 72 | "reason": "Alasan: ", 73 | "refueled_vehicle": "Mengisi bahan bakar kendaraan.", 74 | "restarted_resource": "Resource di-restart.", 75 | "removed_stress_player": "Menghilangkan stres dari Pemain", 76 | "set_on_fire": "Seseorang dibakar :P.", 77 | "set_wepaon_ammo": "Amunisi %s diberikan!", 78 | "started_resource": "Resource dimulai.", 79 | "status_title": "Status CFX.", 80 | "stopped_resource": "Resource dihentikan.", 81 | "state_changed": "Anda telah mengatur status kendaraan.", 82 | "take_money": "Menghapus %s dari %s.", 83 | "take_money_crypto": "Menghapus %s Crypto/s dari %s.", 84 | "target_same_bucket": "Mencoba menempatkan %s dalam bucket yang sama.", 85 | "teleported_waypoint": "Berpindah ke Waypoint.", 86 | "toggled_cuffs": "Toggle Cuffs.", 87 | "toggle_dev": "Toggle Mode Pengembang.", 88 | "tp_error": "Kesalahan saat melakukan teleport.", 89 | "u_veh_owner": "Kendaraan ini sudah menjadi milikmu.", 90 | "veh_fixed": "Kendaraan %s berhasil di perbaiki.", 91 | "veh_owner": "Kendaraan ini sekarang menjadi milikmu!", 92 | "vehicle_dev_data": "Informasi Kendaraan.", 93 | "vehicle_max_modded": "Kendaraan telah dimodifikasi secara maksimum.", 94 | "vehicle_not_driver": "Tidak berada di kursi pengemudi.", 95 | "warngiven": "Diingatkan: ", 96 | "warned": "Kamu telah diingatkan.", 97 | "weatherType": "Cuaca diubah menjadi: %s." 98 | } -------------------------------------------------------------------------------- /locales/it.json: -------------------------------------------------------------------------------- 1 | { 2 | "already_plate": "Questa targa appartiene già ad un altro veicolo", 3 | "amount_max": "Importo massimo $999,999", 4 | "ban_expires": "Il ban scade: ", 5 | "ban_perm": "Sei stato bannato permanentemente!", 6 | "banreason": "Motivo: %s, Fino a: %s", 7 | "banned": "Sei stato bannato!", 8 | "blackout": "Blackout %s", 9 | "blips_activated": "Blip attivati", 10 | "blips_deactivated": "Blip disattivati", 11 | "body_health": "Stato Carrozzeria: ", 12 | "bucket_get": "Il giocatore %s è nel bucket: %s", 13 | "bucket_set": "Routing bucket impostato: %s", 14 | "bucket_set_for_target": "Routing bucket impostato a: %s in: %s", 15 | "cannot_store_veh": "Non puoi depositare questo veicolo nel garage", 16 | "cant_spectate_yourself": "Non puoi spectare te stesso", 17 | "command_admin_desc": "Admin Menu", 18 | "command_noclip_desc": "NoClip", 19 | "copy_heading": "Heading copiato", 20 | "copy_vector2": "Vector2 copiato", 21 | "copy_vector3": "Vector3 copiato", 22 | "copy_vector4": "Vector4 copiato", 23 | "deFrozen": "Hai sbloccato %s", 24 | "empty_input": "Input non valido o vuoto", 25 | "eng_health": "Stato Motore: ", 26 | "entered_vehicle": "Entrato nel veicolo", 27 | "ent_id": "ID Entità: ", 28 | "explode_player": "Il giocatore è esploso :P", 29 | "Frozen": "%s è stato bloccato", 30 | "gangset": "Hai impostato a: %s , la fazione: %s con il grado %s", 31 | "give_item": "Hai dato %s a %s", 32 | "give_item_all": "Hai dato %s a tutti i giocatori", 33 | "give_money": "Hai dato %s %s", 34 | "give_money_all": "Hai dato %s a tutti i giocatori", 35 | "give_money_all_crypto": "Hai dato %s Crypto a tutti i giocatori", 36 | "give_money_crypto": "Hai dato %s Crypto a %s", 37 | "givecar.plates_alreadyused": "La targa %s è già in uso su un altro veicolo", 38 | "givecar.success.source": "Hai dato il veicolo %s a %s.", 39 | "givecar.success.target": "Hai ricevuto un veicolo con la targa: %s. Puoi prenderlo al %s.", 40 | "godmode": "Godmode %s", 41 | "hash": "Hash: ", 42 | "inf_ammo_toggled": "Munizioni Infinite", 43 | "invisible": "Invisiblità: %s", 44 | "invcleared": "%s inventario svuotato", 45 | "jobset": "Hai impostato a: %s il lavoro: %s con il grado %s", 46 | "kicked": "Sei stato espulso dal server!", 47 | "model": "Modello: ", 48 | "names_activated": "Nomi Attivati", 49 | "names_deactivated": "Nomi Disattivati", 50 | "net_id": "Netword ID: ", 51 | "net_id_not_registered": "Non registrato", 52 | "new_staffchat": "Nuovo Messaggio Staff", 53 | "no_free_seats": "Il veicolo non ha posti liberi", 54 | "no_perms": "Non hai i permessi necessari", 55 | "no_waypoint": "Nessun waypoint impostato", 56 | "no_weapon": "Non ha un arma.", 57 | "noclip_disabled": "No-clip disabilitato", 58 | "noclip_enabled": "No-clip abilitato", 59 | "not_enough_money": "Il giocatore non ha tutti questi soldi", 60 | "not_in_veh": "Non sei in un veicolo..", 61 | "not_in_vehicle": "Non sei in un veicolo..", 62 | "not_online": "Giocatore offline", 63 | "ped_coords": "Coordinate Giocatore:", 64 | "plate_max": "Puoi inserire al massimo 8 caratteri", 65 | "plate_invalid": "Targa non valida", 66 | "player_not_found": "Giocaotore non trovato", 67 | "player_not_in_veh": "Il giocatore non è in un veicolo..", 68 | "player_perms": "%s ha ricevuto [ %s ] come permessi.", 69 | "playerbanned": "Sei bannato dal server %s per %s. Motivo: %s", 70 | "playerdrunk": "Rendi ubriaco il giocatore: ", 71 | "reason": "Motivo: ", 72 | "refueled_vehicle": "Veicolo rifornito", 73 | "restarted_resource": "Restarta Risorsa", 74 | "removed_stress_player": "Rimuovi stress dal giocatore", 75 | "set_on_fire": "Il giocatore sta prendendo fuoco :P", 76 | "set_wepaon_ammo": "%s munizioni date!", 77 | "started_resource": "Risorse Avviate", 78 | "status_title": "CFX Status", 79 | "stopped_resource": "Risorse Stoppate", 80 | "state_changed": "Hai impostato lo stato per il veicolo.", 81 | "take_money": "Hai preso %s da %s", 82 | "take_money_crypto": "Hai preso %s Crypto da %s", 83 | "target_same_bucket": "Il giocatore è già in questo bucket %s", 84 | "teleported_waypoint": "TP al waypoint.", 85 | "toggled_cuffs": "Togli/Metti Manette", 86 | "toggle_dev": "Attiva/Disattiva Dev Mode", 87 | "tp_error": "Errore nel TP.", 88 | "u_veh_owner": "Questo veicolo è già tuo..", 89 | "veh_fixed": "Veicolo riparato a %s", 90 | "veh_owner": "Auguri per il tuo nuovo veicolo!", 91 | "vehicle_dev_data": "Informazioni veicolo", 92 | "vehicle_max_modded": "Il veicolo è ora con il fullkit", 93 | "vehicle_not_driver": "Non sei al posto di guida", 94 | "warned": "Hai ricevuto un warn ", 95 | "warngiven": "Warn: ", 96 | "weatherType": "Meteo impostato: %s" 97 | } 98 | -------------------------------------------------------------------------------- /locales/nl.json: -------------------------------------------------------------------------------- 1 | { 2 | "already_plate": "Dit kenteken is al in gebruik", 3 | "amount_max": "Maximum bedrag is $999,999", 4 | "ban_expires": "Ban verloopt op: ", 5 | "ban_perm": "Je bent permanent verbannen!", 6 | "banreason": "Reden: %s, Verbanning tot %s", 7 | "banned": "Je bent gebanned!", 8 | "blackout": "Blackout is %s", 9 | "blips_activated": "Blips geactiveerd", 10 | "blips_deactivated": "Blips gedeactiveerd", 11 | "body_health": "karroserie: ", 12 | "bucket_get": "Speler %s is in routing bucket: %s", 13 | "bucket_set": "Routing is nu routing bucket: %s", 14 | "bucket_set_for_target": "Routing bucket voor: %s is gezet naar bucket: %s", 15 | "cannot_store_veh": "Je kan dit voertuig niet opslaan in je garage", 16 | "cant_spectate_yourself": "Je kan jezelf niet spectate", 17 | "command_admin_desc": "Toggle Admin Menu", 18 | "command_noclip_desc": "Toggle NoClip", 19 | "copy_heading": "Heading gekopieerd", 20 | "copy_vector2": "Vector2 gekopieerd", 21 | "copy_vector3": "Vector3 gekopieerd", 22 | "copy_vector4": "Vector4 gekopieerd", 23 | "deFrozen": "Je hebt %s geunfreezed", 24 | "empty_input": "Input is leeg.", 25 | "eng_health": "Motor HP: ", 26 | "entered_vehicle": "In voertuig gestapt", 27 | "ent_id": "Entity ID: ", 28 | "explode_player": "Persoon is geexplodeerd :P", 29 | "Frozen": "%s is gefreezed", 30 | "gangset": "Je hebt %s de gang: %s gegeven met grade %s", 31 | "give_item": "%s aan %s gegeven", 32 | "give_item_all": "%s aan elke speler gegeven", 33 | "give_money": "%s gegeven aan %s", 34 | "give_money_all": "%s Aan elke speler gegeven %s", 35 | "give_money_all_crypto": "%s Crypto aan elke speler gegeven", 36 | "give_money_crypto": "%s Crypto aan %s gegeven", 37 | "givecar.plates_alreadyused": "Fout bij voertuig geven. Kenteken %s is al in gebruik", 38 | "givecar.success.source": "Succesvol vehicle %s aan %s gegeven.", 39 | "givecar.success.target": "Je hebt een nieuw voertuig gekregen %s. Je kunt hem bekijken bij %s.", 40 | "godmode": "Godmode is %s", 41 | "hash": "Hash: ", 42 | "inf_ammo_toggled": "Infinite Ammo getoggled", 43 | "invisible": "Ontzichtbaarheid: %s", 44 | "invcleared": "%s's hun inventory is gecleared", 45 | "jobset": "Je hebt %s de baan gegeven: %s met grade %s", 46 | "kicked": "Je bent gekicked!", 47 | "model": "Model: ", 48 | "names_activated": "Namen aangezet", 49 | "names_deactivated": "Namen uitgezet", 50 | "net_id": "Net ID: ", 51 | "net_id_not_registered": "Niet geregistreerd", 52 | "new_staffchat": "Nieuw staff bericht", 53 | "no_free_seats": "Dit voertuig heeft geen stoelen meer vrij!", 54 | "no_perms": "Onvoldoende rechten", 55 | "no_waypoint": "Geen waypoint ingesteld.", 56 | "no_weapon": "Dit persoon heeft geen wapen.", 57 | "noclip_disabled": "No-clip uitgezet", 58 | "noclip_enabled": "No-clip aangezet", 59 | "not_enough_money": "Speler heeft niet genoeg geld", 60 | "not_in_veh": "Je zit niet in een voertuig..", 61 | "not_in_vehicle": "Je zit niet in een voertuig..", 62 | "not_online": "Speler is offline", 63 | "ped_coords": "Ped coordinaten:", 64 | "plate_max": "Een kenteken kan maar 8 tekens hebben", 65 | "plate_invalid": "Ongeldig kenteken", 66 | "player_not_found": "Speler niet gevonden.", 67 | "player_not_in_veh": "Je zit niet in een voertuig..", 68 | "player_perms": "%s heeft [ %s ] Permissions.", 69 | "playerbanned": "Je hebt %s gebanned voor %s met de reden: %s", 70 | "playerdrunk": "Speler dronken gemaakt: ", 71 | "reason": "Reden: ", 72 | "refueled_vehicle": "Voertuig getanked", 73 | "restarted_resource": "Script gerestart", 74 | "removed_stress_player": "Stress verwijderd van speler", 75 | "set_on_fire": "Speler in de fik gezet :P", 76 | "set_wepaon_ammo": "%s kogels gegeven!", 77 | "started_resource": "Script gestart", 78 | "status_title": "CFX Status", 79 | "stopped_resource": "Script gestopt", 80 | "state_changed": "Je hebt voertuig status ingesteld.", 81 | "take_money": "%s van speler %s afgenomen", 82 | "take_money_crypto": "%s Crypto van speler %s afgenomen", 83 | "target_same_bucket": "Je hebt geprobeerd %s in dezelfde bucket te zetten", 84 | "teleported_waypoint": "Geteleporteerd naar waypoint.", 85 | "toggled_cuffs": "Cuffs getoggled", 86 | "toggle_dev": "Dev mode getoggled", 87 | "tp_error": "Error bij teleporteren.", 88 | "u_veh_owner": "Dit voertuig is al van jou..", 89 | "veh_fixed": "Voertuig gefixed voor %s", 90 | "veh_owner": "Dit voertuig is nu van jou!", 91 | "vehicle_dev_data": "Voertuig informatie", 92 | "vehicle_max_modded": "Voertuig is nu max modded", 93 | "vehicle_not_driver": "Je bent niet de bestuurder van dit voertuig", 94 | "warned": "Je bent gewaarschuwed ", 95 | "warngiven": "Speler gewaarschuwed: ", 96 | "weatherType": "Weer ingesteld op: %s" 97 | } -------------------------------------------------------------------------------- /locales/no.json: -------------------------------------------------------------------------------- 1 | { 2 | "already_plate": "Dette skilt-nummer er brukt på et annet kjøretøy", 3 | "amount_max": "Maks er 999,999", 4 | "ban_expires": "Ban utløper: ", 5 | "ban_perm": "Du har blitt permanent utestengt!", 6 | "banreason": "Grunnlag: %s, until %s", 7 | "banned": "Du har blitt utestengt!", 8 | "blackout": "Blackout is %s", 9 | "blips_activated": "Blips aktivert", 10 | "blips_deactivated": "Blips deaktivert", 11 | "body_health": "Liv spiller: ", 12 | "bucket_get": "Spiller %s er i bucket: %s", 13 | "bucket_set": "Markering satt til bucket: %s", 14 | "bucket_set_for_target": "Ruting bucket satt for: %s til bucket: %s", 15 | "cannot_store_veh": "Du kan ikke sette denne bilen i garasje", 16 | "cant_spectate_yourself": "Du kan ikke spectate deg selv", 17 | "command_admin_desc": "Åpne Staff Meny", 18 | "command_noclip_desc": "Aktiver NoClip", 19 | "copy_heading": "Kopiert heading", 20 | "copy_vector2": "Kopiert vector2", 21 | "copy_vector3": "Kopiert vector3", 22 | "copy_vector4": "Kopiert vector4", 23 | "deFrozen": "Du har satt %s løs", 24 | "empty_input": "Inndata var tomt.", 25 | "eng_health": "Motorhelse: ", 26 | "entered_vehicle": "I kjøretøy", 27 | "ent_id": "Entity ID: ", 28 | "explode_player": "Personen ble eksplodert :P", 29 | "Frozen": "%s's er blitt frosset", 30 | "gangset": "Du har gitt %s gjeng: %s med grad %s", 31 | "give_item": "Ga %s til %s", 32 | "give_item_all": "Ga %s til alle spillere", 33 | "give_money": "Ga %s %s", 34 | "give_money_all": "Ga %s kroner til alle spillere %s", 35 | "give_money_all_crypto": "Ga %s krypto/s til alle spillere", 36 | "give_money_crypto": "Ga %s krypto/s til %s", 37 | "givecar.plates_alreadyused": "Nummerskiltet %s er allerede i bruk på et annet kjøretøy", 38 | "givecar.success.source": "Ga kjøretøy %s to %s.", 39 | "givecar.success.target": "Du har mottatt et nytt kjøretøy med nummerskilt %s. Du kan finne det på %s.", 40 | "godmode": "Gudmodus er %s", 41 | "hash": "Hash: ", 42 | "inf_ammo_toggled": "Uendelig ammunisjon Toggled", 43 | "invisible": "Usynlig: %s", 44 | "invcleared": "%s sitt inventory er tømt", 45 | "jobset": "Du har gitt %s jobb: %s med stilling %s", 46 | "kicked": "Du har blitt kicket!", 47 | "model": "Model: ", 48 | "names_activated": "Nametags aktivert", 49 | "names_deactivated": "Nametags deaktivert", 50 | "net_id": "Net ID: ", 51 | "net_id_not_registered": "Ikke registrert", 52 | "new_staffchat": "Ny melding i staff-chat", 53 | "no_free_seats": "kjøretøyet har ingen ledige seter!", 54 | "no_perms": "Du har ikke tillatelse til å gjøre dette", 55 | "no_waypoint": "Ingen Waypoint er satt.", 56 | "no_weapon": "Han har ikke en pistol.", 57 | "noclip_disabled": "No-clip deaktivert", 58 | "noclip_enabled": "No-clip aktivert", 59 | "not_enough_money": "Ikke nok midler til å fjerne penger fra spilleren", 60 | "not_in_veh": "Du er ikke i et kjøretøy..", 61 | "not_in_vehicle": "Du er ikke i et kjøretøy", 62 | "not_online": "Spiller er ikke online", 63 | "ped_coords": "Ped Koordinater:", 64 | "plate_max": "Maks sifre for en tallerken er 8", 65 | "player_not_found": "Spiller ikke funnet.", 66 | "player_not_in_veh": "Du er ikke i et kjøretøy..", 67 | "player_perms": "%s Har nå fått [ %s ] Rettigheter", 68 | "playerbanned": "Du har utestengt %s for %s med grunn: %s", 69 | "reason": "Grunn: ", 70 | "refueled_vehicle": "Tanket kjøretøy", 71 | "restarted_resource": "Restartet Resource", 72 | "set_on_fire": "Person satt i brann :P", 73 | "set_wepaon_ammo": "%s ammunisjon gitt!", 74 | "started_resource": "Startet Resource", 75 | "status_title": "CFX Status", 76 | "stopped_resource": "Stoppet Resource", 77 | "take_money": "Fjernet %s fra %s", 78 | "take_money_crypto": "Fjernet %s Crypto/s fra %s", 79 | "target_same_bucket": "Prøvde å plassere %s i samme bucket", 80 | "teleported_waypoint": "Teleportert til markør.", 81 | "toggled_cuffs": "Satt på håndjærn", 82 | "toggle_dev": "Aktivert Dev Modus", 83 | "tp_error": "Feil under teleportering.", 84 | "u_veh_owner": "Dette kjøretøyet er allerede ditt..", 85 | "veh_fixed": "Utført reparasjon på kjøretøy for %s", 86 | "veh_owner": "Kjøretøyet er nå ditt!", 87 | "vehicle_dev_data": "Kjøretøyinformasjon", 88 | "vehicle_max_modded": "Kjøretøyet har blitt maks oppgradert", 89 | "vehicle_not_driver": "Ikke i førersetet", 90 | "warned": "Du har fått en advarsel ", 91 | "warngiven": "Advart: ", 92 | "weatherType": "Været endret til: %s" 93 | } -------------------------------------------------------------------------------- /locales/pt-br.json: -------------------------------------------------------------------------------- 1 | { 2 | "already_plate": "Esta placa de matrícula foi usada em outro veículo", 3 | "amount_max": "A entrada máxima é $999,999", 4 | "ban_expires": "Ban expira: ", 5 | "ban_perm": "Você foi banido permanentemente!", 6 | "banreason": "Razão: %s, até %s", 7 | "banned": "Você foi banido!", 8 | "blackout": "Blackout is %s", 9 | "blips_activated": "Blips ativada", 10 | "blips_deactivated": "Blips desativada", 11 | "body_health": "Saúde do carroceria: ", 12 | "bucket_get": "Jogador %s está no balde: %s", 13 | "bucket_set": "Roteamento definido para o balde: %s", 14 | "bucket_set_for_target": "Routing bucket set for: %s to bucket: %s", 15 | "cant_spectate_yourself": "Você não pode se assistir", 16 | "cannot_store_veh": "Não posso armazenar este carro em sua garagem", 17 | "copy_heading": "Copiada heading", 18 | "copy_vector2": "Copiada vector2", 19 | "copy_vector3": "Copiada vector3", 20 | "copy_vector4": "Copiada vector4", 21 | "deFrozen": "Você definiu %s livre", 22 | "empty_input": "A entrada esta vazia.", 23 | "eng_health": "Saúde do motor: ", 24 | "entered_vehicle": "Veículo entrou", 25 | "ent_id": "Entity ID: ", 26 | "explode_player": "Pessoa foi explodida :P", 27 | "Frozen": "%s's congelado com sucesso", 28 | "gangset": "Você deu %s A gangue: %s com cargo %s", 29 | "give_item": "Deu %s para %s", 30 | "give_item_all": "Deu %s para cada jogador", 31 | "give_money": "Deu %s %s", 32 | "give_money_all": "Adicionada %s para todos os jogadores %s", 33 | "give_money_all_crypto": "Deu %s Crypto/s para cada jogador", 34 | "give_money_crypto": "Deu %s Crypto/s para %s", 35 | "godmode": "Godmode esta %s", 36 | "hash": "Hash: ", 37 | "inf_ammo_toggled": "Munição infinita alternada", 38 | "invisible": "Invisible: %s", 39 | "invcleared": "%s's Inventário foi limpo", 40 | "jobset": "Você deu %s o emprego: %s com cargo %s", 41 | "kicked": "Você foi chutado!", 42 | "model": "Modelo: ", 43 | "names_activated": "Nomes ativada", 44 | "names_deactivated": "Nomes desativados", 45 | "net_id": "Net ID: ", 46 | "net_id_not_registered": "Não registrado", 47 | "new_staffchat": "Nova mensagem da equipe", 48 | "no_free_seats": "O veículo não tem assentos livres!", 49 | "no_perms": "Você não tem permissão para fazer isso", 50 | "no_waypoint": "Sem waypoint definido.", 51 | "noclip_disabled": "No-clip desabilitada", 52 | "noclip_enabled": "No-clip habilitada", 53 | "not_enough_money": "Fundos insuficientes para remover o dinheiro do jogador", 54 | "not_in_veh": "Você não está em um veículo ..", 55 | "not_in_vehicle": "Você não está em um veículo", 56 | "not_online": "Jogador não online", 57 | "ped_coords": "Ped coordenadas:", 58 | "plate_max": "Dígitos máximos para um placa é 8", 59 | "plate_invalid": "Placa Inválida", 60 | "player_not_found": "Jogador não encontrado.", 61 | "player_not_in_veh": "Você não está em um veículo ..", 62 | "player_perms": "%s pegou [ %s ] Permissões.", 63 | "playerbanned": "Você baniu %s para %s com razão: %s", 64 | "playerdrunk": "deixou o jogador bêbado: ", 65 | "reason": "Razão: ", 66 | "refueled_vehicle": "Veículo reabastecido", 67 | "restarted_resource": "Recurso reiniciado", 68 | "removed_stress_player": "Removido o estresse do Player", 69 | "set_on_fire": "Pessoa incendiada :P", 70 | "started_resource": "Recurso iniciado", 71 | "status_title": "CFX Status", 72 | "stopped_resource": "Recurso parado", 73 | "state_changed": "Você definiu o estado do veículo.", 74 | "take_money": "Removida %s de %s", 75 | "take_money_crypto": "Removida %s Crypto/s de %s", 76 | "target_same_bucket": "Tentou colocar %s na mesma dimensão", 77 | "teleported_waypoint": "Teletransportado para o waypoint.", 78 | "tp_error": "Erro ao se teletransportar.", 79 | "toggled_cuffs": "Punhos alternados", 80 | "u_veh_owner": "Este veículo já é seu ..", 81 | "veh_fixed": "Veículo arrumado para %s", 82 | "veh_owner": "O veículo agora é seu!", 83 | "vehicle_dev_data": "Informações sobre o veículo", 84 | "vehicle_max_modded": "O veículo foi modificado no máximo", 85 | "vehicle_not_driver": "Não esta no assento do motorista", 86 | "warned": "Você foi avisado ", 87 | "warngiven": "Avisado: ", 88 | "weatherType": "O tempo mudou para: %s" 89 | } -------------------------------------------------------------------------------- /locales/tr.json: -------------------------------------------------------------------------------- 1 | { 2 | "already_plate": "Bu plaka başka bir araçta kullanılıyor", 3 | "amount_max": "Maksimum $999,999 giriş yapabilirsiniz", 4 | "ban_expires": "Yasaklanmanın bitiş süresi: ", 5 | "ban_perm": "Kalıcı olarak yasaklandınız!", 6 | "banreason": "Sebep: %s, %s", 7 | "banned": "Yasaklandınız!", 8 | "blackout": "Blackout şu şekilde ayarlı: %s", 9 | "blips_activated": "İşaretler açıldı", 10 | "blips_deactivated": "İşaretler kapatıldı", 11 | "body_health": "Gövde Sağlığı: ", 12 | "bucket_get": "Oyuncu %s kovada: %s", 13 | "bucket_set": "Yönlendirme kovaya ayarlandı: %s", 14 | "bucket_set_for_target": "Yönlendirme kovası %s, %s için ayarlandı", 15 | "cannot_store_veh": "Bu aracı garajınızda saklayamazsınız", 16 | "cant_spectate_yourself": "Kendinizi izleyemezsiniz", 17 | "command_admin_desc": "Admin Menüsünü Aç", 18 | "command_noclip_desc": "NoClip'i Aç/Kapat", 19 | "copy_heading": "Bakış yönü kopyalandı", 20 | "copy_vector2": "vector2 kordinatı kopyalandı", 21 | "copy_vector3": "vector3 kordinatı kopyalandı", 22 | "copy_vector4": "vector4 kordinatı kopyalandı", 23 | "deFrozen": "%s oyuncusunun dondurulması kaldırıldı", 24 | "empty_input": "Giriş boş.", 25 | "eng_health": "Motor Sağlığı: ", 26 | "entered_vehicle": "Araca binildi", 27 | "ent_id": "Varlık ID'si: ", 28 | "explode_player": "Kişi patlatıldı :P", 29 | "Frozen": "%s donduruldu", 30 | "gangset": "%s oyuncusu çete olarak atandı: %s rütbe %s", 31 | "give_item": "%s oyuncusuna %s verildi", 32 | "give_item_all": "Tüm oyunculara %s verildi", 33 | "give_money": "%s verildi %s", 34 | "give_money_all": "Tüm oyunculara %s eklendi", 35 | "give_money_all_crypto": "Tüm oyunculara %s kripto verildi", 36 | "give_money_crypto": "%s kripto %s oyuncusuna verildi", 37 | "givecar.plates_alreadyused": "Araç verilemedi. %s Plakası başka bir araçta zaten kullanılıyor", 38 | "givecar.success.source": "%s Oyuncusuna %s aracı verildi", 39 | "givecar.success.target": "You have received a new vehicle with license plate %s. You can check it at %s.", 40 | "godmode": "Ölümsüzlük modu %s", 41 | "hash": "Hash: ", 42 | "inf_ammo_toggled": "Sınırsız Mermi Açıldı", 43 | "invisible": "Görünmezlik: %s", 44 | "invcleared": "%s oyuncusunun envanteri temizlendi", 45 | "jobset": "%s oyuncusuna meslek verildi: %s rütbe %s", 46 | "kicked": "Atıldınız!", 47 | "model": "Model: ", 48 | "names_activated": "İsimler açıldı", 49 | "names_deactivated": "İsimler kapatıldı", 50 | "net_id": "Net ID: ", 51 | "net_id_not_registered": "Kayıt edilmemiş", 52 | "new_staffchat": "Yeni Yetkili Mesajı", 53 | "no_free_seats": "Aracın boş koltuğu yok!", 54 | "no_perms": "Bunu yapabilmek için yeterli yetkiye sahip değilsin", 55 | "no_waypoint": "İşaret Yok.", 56 | "no_weapon": "Silahı yok.", 57 | "noclip_disabled": "No-clip kapatıldı", 58 | "noclip_enabled": "No-clip açıldı", 59 | "not_enough_money": "Oyuncudan para çekmek için yeterli parası yok", 60 | "not_in_veh": "Araç içerisinde değilsiniz...", 61 | "not_in_vehicle": "Araç içerisinde değilsiniz", 62 | "not_online": "Oyuncu aktif değil", 63 | "ped_coords": "Ped Kordinatları:", 64 | "plate_max": "Maksimum Plaka Hanesi 8 Olmalı", 65 | "plate_invalid": "Geçersiz Plaka", 66 | "player_not_found": "Oyuncu bulunamadı.", 67 | "player_not_in_veh": "Araç içerisinde değilsiniz...", 68 | "player_perms": "%s, [ %s ] yetkileri aldı.", 69 | "playerbanned": "%s oyuncusunu %s için %s sebebiyle yasakladınız", 70 | "playerdrunk": "Oyuncu Sarhoş Oldu: ", 71 | "reason": "Sebep: ", 72 | "refueled_vehicle": "Yakıt Dolduruldu", 73 | "restarted_resource": "Kaynak Yeniden Başlatıldı", 74 | "removed_stress_player": "Oyuncudan stress kaldırıldı", 75 | "set_on_fire": "Kişi yanıyor :P", 76 | "set_wepaon_ammo": "%s cephane verildi", 77 | "started_resource": "Kaynak Başlatıldı", 78 | "status_title": "CFX Durumu", 79 | "stopped_resource": "Kaynak Durduruldu", 80 | "state_changed": "Aracın durumunu ayarladınız.", 81 | "take_money": "%s, %s oyuncusundan alındı", 82 | "take_money_crypto": "%s kripto %s oyuncusundan alındı", 83 | "target_same_bucket": "%s aynı pakete yerleştirilmeye çalışıldı", 84 | "teleported_waypoint": "İşarete Işınlanıldı.", 85 | "toggled_cuffs": "Kelepçelendi", 86 | "toggle_dev": "Geliştirici Modu Açıldı", 87 | "tp_error": "Işınlanılırken Bir Sorun Oluştu.", 88 | "u_veh_owner": "Bu araç zaten sizin...", 89 | "veh_fixed": "Araç %s için tamir edildi", 90 | "veh_owner": "Bu araç zaten sizin!", 91 | "vehicle_dev_data": "Araç Bilgileri", 92 | "vehicle_max_modded": "Araç maksimum duruma getirildi", 93 | "vehicle_not_driver": "Sürücü koltuğunda değilsiniz", 94 | "warned": "Başarıyla uyardınız ", 95 | "warngiven": "Uyarıldı: ", 96 | "weatherType": "Hava durumu %s olarak güncellendi" 97 | } 98 | -------------------------------------------------------------------------------- /server/chat.lua: -------------------------------------------------------------------------------- 1 | local messages = {} 2 | 3 | -- Staff Chat 4 | RegisterNetEvent('ps-adminmenu:server:sendMessageServer', function(message, citizenid, fullname) 5 | if not CheckPerms(source, 'mod') then return end 6 | 7 | local time = os.time() * 1000 8 | local players = QBCore.Functions.GetPlayers() 9 | 10 | for i = 1, #players, 1 do 11 | local player = players[i] 12 | if QBCore.Functions.IsOptin(player) then 13 | QBCore.Functions.Notify(player, locale("new_staffchat", 'inform', 7500)) 14 | end 15 | end 16 | 17 | messages[#messages + 1] = { message = message, citizenid = citizenid, fullname = fullname, time = time } 18 | end) 19 | 20 | 21 | lib.callback.register('ps-adminmenu:callback:GetMessages', function() 22 | if not CheckPerms(source, 'mod') then return {} end 23 | return messages 24 | end) 25 | -------------------------------------------------------------------------------- /server/inventory.lua: -------------------------------------------------------------------------------- 1 | -- Clear Inventory 2 | RegisterNetEvent('ps-adminmenu:server:ClearInventory', function(data, selectedData) 3 | local data = CheckDataFromKey(data) 4 | if not data or not CheckPerms(data.perms) then return end 5 | 6 | local src = source 7 | local player = selectedData["Player"].value 8 | local Player = QBCore.Functions.GetPlayer(player) 9 | 10 | if not Player then 11 | return QBCore.Functions.Notify(source, locale("not_online"), 'error', 7500) 12 | end 13 | 14 | if Config.Inventory == 'ox_inventory' then 15 | exports.ox_inventory:ClearInventory(player) 16 | else 17 | exports[Config.Inventory]:ClearInventory(player, nil) 18 | end 19 | 20 | QBCore.Functions.Notify(src, 21 | locale("invcleared", Player.PlayerData.charinfo.firstname .. ' ' .. Player.PlayerData.charinfo.lastname), 22 | 'success', 7500) 23 | end) 24 | 25 | -- Clear Inventory Offline 26 | RegisterNetEvent('ps-adminmenu:server:ClearInventoryOffline', function(data, selectedData) 27 | local data = CheckDataFromKey(data) 28 | if not data or not CheckPerms(source, data.perms) then return end 29 | 30 | local src = source 31 | local citizenId = selectedData["Citizen ID"].value 32 | local Player = QBCore.Functions.GetPlayerByCitizenId(citizenId) 33 | 34 | if Player then 35 | if Config.Inventory == 'ox_inventory' then 36 | exports.ox_inventory:ClearInventory(Player.PlayerData.source) 37 | else 38 | exports[Config.Inventory]:ClearInventory(Player.PlayerData.source, nil) 39 | end 40 | QBCore.Functions.Notify(src, 41 | locale("invcleared", Player.PlayerData.charinfo.firstname .. ' ' .. Player.PlayerData.charinfo.lastname), 42 | 'success', 7500) 43 | else 44 | MySQL.Async.fetchAll("SELECT * FROM players WHERE citizenid = @citizenid", { ['@citizenid'] = citizenId }, 45 | function(result) 46 | if result and result[1] then 47 | MySQL.Async.execute("UPDATE players SET inventory = '{}' WHERE citizenid = @citizenid", 48 | { ['@citizenid'] = citizenId }) 49 | QBCore.Functions.Notify(src, "Player's inventory cleared", 'success', 7500) 50 | else 51 | QBCore.Functions.Notify(src, locale("player_not_found"), 'error', 7500) 52 | end 53 | end) 54 | end 55 | end) 56 | 57 | -- Open Inv [ox side] 58 | RegisterNetEvent('ps-adminmenu:server:OpenInv', function(data) 59 | exports.ox_inventory:forceOpenInventory(source, 'player', data) 60 | end) 61 | 62 | -- Open Stash [ox side] 63 | RegisterNetEvent('ps-adminmenu:server:OpenStash', function(data) 64 | exports.ox_inventory:forceOpenInventory(source, 'stash', data) 65 | end) 66 | 67 | -- Open Trunk [ox side] 68 | RegisterNetEvent('ps-adminmenu:server:OpenTrunk', function(data) 69 | exports.ox_inventory:forceOpenInventory(source, 'trunk', data) 70 | end) 71 | 72 | -- Give Item 73 | RegisterNetEvent('ps-adminmenu:server:GiveItem', function(data, selectedData) 74 | local data = CheckDataFromKey(data) 75 | if not data or not CheckPerms(source, data.perms) then return end 76 | 77 | local target = selectedData["Player"].value 78 | local item = selectedData["Item"].value 79 | local amount = selectedData["Amount"].value 80 | local Player = QBCore.Functions.GetPlayer(target) 81 | 82 | if not item or not amount then return end 83 | if not Player then 84 | return QBCore.Functions.Notify(source, locale("not_online"), 'error', 7500) 85 | end 86 | 87 | Player.Functions.AddItem(item, amount) 88 | QBCore.Functions.Notify(source, 89 | locale("give_item", tonumber(amount) .. " " .. item, 90 | Player.PlayerData.charinfo.firstname .. " " .. Player.PlayerData.charinfo.lastname), "success", 7500) 91 | end) 92 | 93 | -- Give Item to All 94 | RegisterNetEvent('ps-adminmenu:server:GiveItemAll', function(data, selectedData) 95 | local data = CheckDataFromKey(data) 96 | if not data or not CheckPerms(source, data.perms) then return end 97 | 98 | local item = selectedData["Item"].value 99 | local amount = selectedData["Amount"].value 100 | local players = QBCore.Functions.GetPlayers() 101 | 102 | if not item or not amount then return end 103 | 104 | for _, id in pairs(players) do 105 | local Player = QBCore.Functions.GetPlayer(id) 106 | Player.Functions.AddItem(item, amount) 107 | QBCore.Functions.Notify(source, locale("give_item_all", amount .. " " .. item), "success", 7500) 108 | end 109 | end) 110 | -------------------------------------------------------------------------------- /server/main.lua: -------------------------------------------------------------------------------- 1 | QBCore = exports['qb-core']:GetCoreObject() 2 | 3 | lib.addCommand('admin', { 4 | help = 'Open the admin menu', 5 | restricted = 'qbcore.mod' 6 | }, function(source) 7 | if not QBCore.Functions.IsOptin(source) then TriggerClientEvent('QBCore:Notify', source, 'You are not on admin duty', 'error'); return end 8 | TriggerClientEvent('ps-adminmenu:client:OpenUI', source) 9 | end) 10 | -- Callbacks 11 | -------------------------------------------------------------------------------- /server/misc.lua: -------------------------------------------------------------------------------- 1 | -- Ban Player 2 | RegisterNetEvent('ps-adminmenu:server:BanPlayer', function(data, selectedData) 3 | local data = CheckDataFromKey(data) 4 | if not data or not CheckPerms(source, data.perms) then return end 5 | 6 | local player = selectedData["Player"].value 7 | local reason = selectedData["Reason"].value or "" 8 | local time = selectedData["Duration"].value 9 | 10 | local banTime = tonumber(os.time() + time) 11 | local timeTable = os.date('*t', banTime) 12 | 13 | MySQL.insert('INSERT INTO bans (name, license, discord, ip, reason, expire, bannedby) VALUES (?, ?, ?, ?, ?, ?, ?)', 14 | { GetPlayerName(player), QBCore.Functions.GetIdentifier(player, 'license'), QBCore.Functions.GetIdentifier( 15 | player, 'discord'), QBCore.Functions.GetIdentifier(player, 'ip'), reason, banTime, GetPlayerName(source) }) 16 | 17 | if time == 2147483647 then 18 | DropPlayer(player, locale("banned") .. '\n' .. locale("reason") .. reason .. locale("ban_perm")) 19 | else 20 | DropPlayer(player, 21 | locale("banned") .. 22 | '\n' .. 23 | locale("reason") .. 24 | reason .. 25 | '\n' .. 26 | locale("ban_expires") .. 27 | timeTable['day'] .. 28 | '/' .. timeTable['month'] .. '/' .. timeTable['year'] .. ' ' .. timeTable['hour'] .. ':' .. timeTable['min']) 29 | end 30 | 31 | QBCore.Functions.Notify(source, locale("playerbanned", player, banTime, reason), 'success', 7500) 32 | end) 33 | 34 | -- Warn Player 35 | RegisterNetEvent('ps-adminmenu:server:WarnPlayer', function(data, selectedData) 36 | local data = CheckDataFromKey(data) 37 | if not data or not CheckPerms(source, data.perms) then return end 38 | local targetId = selectedData["Player"].value 39 | local target = QBCore.Functions.GetPlayer(targetId) 40 | local reason = selectedData["Reason"].value 41 | local sender = QBCore.Functions.GetPlayer(source) 42 | local warnId = 'WARN-' .. math.random(1111, 9999) 43 | if target ~= nil then 44 | QBCore.Functions.Notify(target.PlayerData.source, 45 | locale("warned") .. ", for: " .. locale("reason") .. ": " .. reason, 'inform', 10000) 46 | QBCore.Functions.Notify(source, 47 | locale("warngiven") .. GetPlayerName(target.PlayerData.source) .. ", for: " .. reason) 48 | MySQL.insert('INSERT INTO player_warns (senderIdentifier, targetIdentifier, reason, warnId) VALUES (?, ?, ?, ?)', 49 | { 50 | sender.PlayerData.license, 51 | target.PlayerData.license, 52 | reason, 53 | warnId 54 | }) 55 | else 56 | TriggerClientEvent('QBCore:Notify', source, locale("not_online"), 'error') 57 | end 58 | end) 59 | 60 | RegisterNetEvent('ps-adminmenu:server:KickPlayer', function(data, selectedData) 61 | local data = CheckDataFromKey(data) 62 | if not data or not CheckPerms(source, data.perms) then return end 63 | local src = source 64 | local target = QBCore.Functions.GetPlayer(selectedData["Player"].value) 65 | local reason = selectedData["Reason"].value 66 | 67 | if not target then 68 | QBCore.Functions.Notify(src, locale("not_online"), 'error', 7500) 69 | return 70 | end 71 | 72 | DropPlayer(target.PlayerData.source, locale("kicked") .. '\n' .. locale("reason") .. reason) 73 | end) 74 | 75 | -- Revive Player 76 | RegisterNetEvent('ps-adminmenu:server:Revive', function(data, selectedData) 77 | local data = CheckDataFromKey(data) 78 | if not data or not CheckPerms(source, data.perms) then return end 79 | local player = selectedData["Player"].value 80 | 81 | TriggerClientEvent('hospital:client:Revive', player) 82 | end) 83 | 84 | -- Revive All 85 | RegisterNetEvent('ps-adminmenu:server:ReviveAll', function(data) 86 | local data = CheckDataFromKey(data) 87 | if not data or not CheckPerms(source, data.perms) then return end 88 | 89 | TriggerClientEvent('hospital:client:Revive', -1) 90 | end) 91 | 92 | -- Revive Radius 93 | RegisterNetEvent('ps-adminmenu:server:ReviveRadius', function(data) 94 | local data = CheckDataFromKey(data) 95 | if not data or not CheckPerms(source, data.perms) then return end 96 | 97 | local src = source 98 | local ped = GetPlayerPed(src) 99 | local pos = GetEntityCoords(ped) 100 | local players = QBCore.Functions.GetPlayers() 101 | 102 | for k, v in pairs(players) do 103 | local target = GetPlayerPed(v) 104 | local targetPos = GetEntityCoords(target) 105 | local dist = #(pos - targetPos) 106 | 107 | if dist < 15.0 then 108 | TriggerClientEvent("hospital:client:Revive", v) 109 | end 110 | end 111 | end) 112 | 113 | -- Set RoutingBucket 114 | RegisterNetEvent('ps-adminmenu:server:SetBucket', function(data, selectedData) 115 | local data = CheckDataFromKey(data) 116 | if not data or not CheckPerms(source, data.perms) then return end 117 | 118 | local src = source 119 | local player = selectedData["Player"].value 120 | local bucket = selectedData["Bucket"].value 121 | local currentBucket = GetPlayerRoutingBucket(player) 122 | 123 | if bucket == currentBucket then 124 | return QBCore.Functions.Notify(src, locale("target_same_bucket", player), 'error', 7500) 125 | end 126 | 127 | SetPlayerRoutingBucket(player, bucket) 128 | QBCore.Functions.Notify(src, locale("bucket_set_for_target", player, bucket), 'success', 7500) 129 | end) 130 | 131 | -- Get RoutingBucket 132 | RegisterNetEvent('ps-adminmenu:server:GetBucket', function(data, selectedData) 133 | local data = CheckDataFromKey(data) 134 | if not data or not CheckPerms(source, data.perms) then return end 135 | 136 | local src = source 137 | local player = selectedData["Player"].value 138 | local currentBucket = GetPlayerRoutingBucket(player) 139 | 140 | QBCore.Functions.Notify(src, locale("bucket_get", player, currentBucket), 'success', 7500) 141 | end) 142 | 143 | -- Give Money 144 | RegisterNetEvent('ps-adminmenu:server:GiveMoney', function(data, selectedData) 145 | local data = CheckDataFromKey(data) 146 | if not data or not CheckPerms(source, data.perms) then return end 147 | 148 | local src = source 149 | local target, amount, moneyType = selectedData["Player"].value, selectedData["Amount"].value, 150 | selectedData["Type"].value 151 | local Player = QBCore.Functions.GetPlayer(tonumber(target)) 152 | 153 | if Player == nil then 154 | return QBCore.Functions.Notify(src, locale("not_online"), 'error', 7500) 155 | end 156 | 157 | Player.Functions.AddMoney(tostring(moneyType), tonumber(amount)) 158 | QBCore.Functions.Notify(src, 159 | locale((moneyType == "crypto" and "give_money_crypto" or "give_money"), tonumber(amount), 160 | Player.PlayerData.charinfo.firstname .. " " .. Player.PlayerData.charinfo.lastname), "success") 161 | end) 162 | 163 | -- Give Money to all 164 | RegisterNetEvent('ps-adminmenu:server:GiveMoneyAll', function(data, selectedData) 165 | local data = CheckDataFromKey(data) 166 | if not data or not CheckPerms(source, data.perms) then return end 167 | 168 | local src = source 169 | local amount, moneyType = selectedData["Amount"].value, selectedData["Type"].value 170 | local players = QBCore.Functions.GetPlayers() 171 | 172 | for _, v in pairs(players) do 173 | local Player = QBCore.Functions.GetPlayer(tonumber(v)) 174 | Player.Functions.AddMoney(tostring(moneyType), tonumber(amount)) 175 | QBCore.Functions.Notify(src, 176 | locale((moneyType == "crypto" and "give_money_all_crypto" or "give_money_all"), tonumber(amount)), "success") 177 | end 178 | end) 179 | 180 | -- Take Money 181 | RegisterNetEvent('ps-adminmenu:server:TakeMoney', function(data, selectedData) 182 | local data = CheckDataFromKey(data) 183 | if not data or not CheckPerms(source, data.perms) then return end 184 | 185 | local src = source 186 | local target, amount, moneyType = selectedData["Player"].value, selectedData["Amount"].value, 187 | selectedData["Type"].value 188 | local Player = QBCore.Functions.GetPlayer(tonumber(target)) 189 | 190 | if Player == nil then 191 | return QBCore.Functions.Notify(src, locale("not_online"), 'error', 7500) 192 | end 193 | 194 | if Player.PlayerData.money[moneyType] >= tonumber(amount) then 195 | Player.Functions.RemoveMoney(moneyType, tonumber(amount), "state-fees") 196 | else 197 | QBCore.Functions.Notify(src, locale("not_enough_money"), "primary") 198 | end 199 | 200 | QBCore.Functions.Notify(src, 201 | locale((moneyType == "crypto" and "take_money_crypto" or "take_money"), tonumber(amount) .. "$", 202 | Player.PlayerData.charinfo.firstname .. " " .. Player.PlayerData.charinfo.lastname), "success") 203 | end) 204 | 205 | -- Blackout 206 | local Blackout = false 207 | RegisterNetEvent('ps-adminmenu:server:ToggleBlackout', function(data) 208 | local data = CheckDataFromKey(data) 209 | if not data or not CheckPerms(source, data.perms) then return end 210 | Blackout = not Blackout 211 | 212 | local src = source 213 | 214 | if Blackout then 215 | TriggerClientEvent('QBCore:Notify', src, locale("blackout", "enabled"), 'primary') 216 | while Blackout do 217 | Wait(0) 218 | exports["qb-weathersync"]:setBlackout(true) 219 | end 220 | exports["qb-weathersync"]:setBlackout(false) 221 | TriggerClientEvent('QBCore:Notify', src, locale("blackout", "disabled"), 'primary') 222 | end 223 | end) 224 | 225 | -- Toggle Cuffs 226 | RegisterNetEvent('ps-adminmenu:server:CuffPlayer', function(data, selectedData) 227 | local data = CheckDataFromKey(data) 228 | if not data or not CheckPerms(source, data.perms) then return end 229 | 230 | local target = selectedData["Player"].value 231 | 232 | TriggerClientEvent('ps-adminmenu:client:ToggleCuffs', target) 233 | QBCore.Functions.Notify(source, locale("toggled_cuffs"), 'success') 234 | end) 235 | 236 | -- Give Clothing Menu 237 | RegisterNetEvent('ps-adminmenu:server:ClothingMenu', function(data, selectedData) 238 | local data = CheckDataFromKey(data) 239 | if not data or not CheckPerms(source, data.perms) then return end 240 | 241 | local src = source 242 | local target = tonumber(selectedData["Player"].value) 243 | 244 | if target == nil then 245 | return QBCore.Functions.Notify(src, locale("not_online"), 'error', 7500) 246 | end 247 | 248 | if target == src then 249 | TriggerClientEvent("ps-adminmenu:client:CloseUI", src) 250 | end 251 | 252 | TriggerClientEvent('qb-clothing:client:openMenu', target) 253 | end) 254 | 255 | -- Set Ped 256 | RegisterNetEvent("ps-adminmenu:server:setPed", function(data, selectedData) 257 | local src = source 258 | local data = CheckDataFromKey(data) 259 | if not data or not CheckPerms(source, data.perms) then 260 | QBCore.Functions.Notify(src, locale("no_perms"), "error", 5000) 261 | return 262 | end 263 | 264 | local ped = selectedData["Ped Models"].label 265 | local tsrc = selectedData["Player"].value 266 | local Player = QBCore.Functions.GetPlayer(tsrc) 267 | 268 | if not Player then 269 | QBCore.Functions.Notify(locale("not_online"), "error", 5000) 270 | return 271 | end 272 | 273 | TriggerClientEvent("ps-adminmenu:client:setPed", Player.PlayerData.source, ped) 274 | end) 275 | -------------------------------------------------------------------------------- /server/players.lua: -------------------------------------------------------------------------------- 1 | local function getVehicles(cid) 2 | local result = MySQL.query.await( 3 | 'SELECT vehicle, plate, fuel, engine, body FROM player_vehicles WHERE citizenid = ?', { cid }) 4 | local vehicles = {} 5 | 6 | for k, v in pairs(result) do 7 | local vehicleData = QBCore.Shared.Vehicles[v.vehicle] 8 | 9 | if vehicleData then 10 | vehicles[#vehicles + 1] = { 11 | id = k, 12 | cid = cid, 13 | label = vehicleData.name, 14 | brand = vehicleData.brand, 15 | model = vehicleData.model, 16 | plate = v.plate, 17 | fuel = v.fuel, 18 | engine = v.engine, 19 | body = v.body 20 | } 21 | end 22 | end 23 | 24 | return vehicles 25 | end 26 | 27 | local function getPlayers() 28 | local players = {} 29 | local GetPlayers = QBCore.Functions.GetQBPlayers() 30 | 31 | for k, v in pairs(GetPlayers) do 32 | local playerData = v.PlayerData 33 | local vehicles = getVehicles(playerData.citizenid) 34 | 35 | players[#players + 1] = { 36 | id = k, 37 | name = playerData.charinfo.firstname .. ' ' .. playerData.charinfo.lastname, 38 | cid = playerData.citizenid, 39 | license = QBCore.Functions.GetIdentifier(k, 'license'), 40 | discord = QBCore.Functions.GetIdentifier(k, 'discord'), 41 | steam = QBCore.Functions.GetIdentifier(k, 'steam'), 42 | job = playerData.job.label, 43 | grade = playerData.job.grade.level, 44 | dob = playerData.charinfo.birthdate, 45 | cash = playerData.money.cash, 46 | bank = playerData.money.bank, 47 | phone = playerData.charinfo.phone, 48 | vehicles = vehicles 49 | } 50 | end 51 | 52 | table.sort(players, function(a, b) return a.id < b.id end) 53 | 54 | return players 55 | end 56 | 57 | lib.callback.register('ps-adminmenu:callback:GetPlayers', function(source) 58 | return getPlayers() 59 | end) 60 | 61 | -- Set Job 62 | RegisterNetEvent('ps-adminmenu:server:SetJob', function(data, selectedData) 63 | local data = CheckDataFromKey(data) 64 | if not data or not CheckPerms(source, data.perms) then return end 65 | local src = source 66 | local playerId, Job, Grade = selectedData["Player"].value, selectedData["Job"].value, selectedData["Grade"].value 67 | local Player = QBCore.Functions.GetPlayer(playerId) 68 | local name = Player.PlayerData.charinfo.firstname .. ' ' .. Player.PlayerData.charinfo.lastname 69 | local jobInfo = QBCore.Shared.Jobs[Job] 70 | local grade = jobInfo["grades"][selectedData["Grade"].value] 71 | 72 | if not jobInfo then 73 | TriggerClientEvent('QBCore:Notify', source, "Not a valid job", 'error') 74 | return 75 | end 76 | 77 | if not grade then 78 | TriggerClientEvent('QBCore:Notify', source, "Not a valid grade", 'error') 79 | return 80 | end 81 | 82 | Player.Functions.SetJob(tostring(Job), tonumber(Grade)) 83 | if Config.RenewedPhone then 84 | exports['qb-phone']:hireUser(tostring(Job), Player.PlayerData.citizenid, tonumber(Grade)) 85 | end 86 | 87 | QBCore.Functions.Notify(src, locale("jobset", name, Job, Grade), 'success', 5000) 88 | end) 89 | 90 | -- Set Gang 91 | RegisterNetEvent('ps-adminmenu:server:SetGang', function(data, selectedData) 92 | local data = CheckDataFromKey(data) 93 | if not data or not CheckPerms(source, data.perms) then return end 94 | local src = source 95 | local playerId, Gang, Grade = selectedData["Player"].value, selectedData["Gang"].value, selectedData["Grade"].value 96 | local Player = QBCore.Functions.GetPlayer(playerId) 97 | local name = Player.PlayerData.charinfo.firstname .. ' ' .. Player.PlayerData.charinfo.lastname 98 | local GangInfo = QBCore.Shared.Gangs[Gang] 99 | local grade = GangInfo["grades"][selectedData["Grade"].value] 100 | 101 | if not GangInfo then 102 | TriggerClientEvent('QBCore:Notify', source, "Not a valid Gang", 'error') 103 | return 104 | end 105 | 106 | if not grade then 107 | TriggerClientEvent('QBCore:Notify', source, "Not a valid grade", 'error') 108 | return 109 | end 110 | 111 | Player.Functions.SetGang(tostring(Gang), tonumber(Grade)) 112 | QBCore.Functions.Notify(src, locale("gangset", name, Gang, Grade), 'success', 5000) 113 | end) 114 | 115 | -- Set Perms 116 | RegisterNetEvent("ps-adminmenu:server:SetPerms", function(data, selectedData) 117 | local data = CheckDataFromKey(data) 118 | if not data or not CheckPerms(source, data.perms) then return end 119 | local src = source 120 | local rank = selectedData["Permissions"].value 121 | local targetId = selectedData["Player"].value 122 | local tPlayer = QBCore.Functions.GetPlayer(tonumber(targetId)) 123 | 124 | if not tPlayer then 125 | QBCore.Functions.Notify(src, locale("not_online"), "error", 5000) 126 | return 127 | end 128 | 129 | local name = tPlayer.PlayerData.charinfo.firstname .. ' ' .. tPlayer.PlayerData.charinfo.lastname 130 | 131 | QBCore.Functions.AddPermission(tPlayer.PlayerData.source, tostring(rank)) 132 | QBCore.Functions.Notify(tPlayer.PlayerData.source, locale("player_perms", name, rank), 'success', 5000) 133 | end) 134 | 135 | -- Remove Stress 136 | RegisterNetEvent("ps-adminmenu:server:RemoveStress", function(data, selectedData) 137 | local data = CheckDataFromKey(data) 138 | if not data or not CheckPerms(source, data.perms) then return end 139 | local src = source 140 | local targetId = selectedData['Player (Optional)'] and tonumber(selectedData['Player (Optional)'].value) or src 141 | local tPlayer = QBCore.Functions.GetPlayer(tonumber(targetId)) 142 | 143 | if not tPlayer then 144 | QBCore.Functions.Notify(src, locale("not_online"), "error", 5000) 145 | return 146 | end 147 | 148 | TriggerClientEvent('ps-adminmenu:client:removeStress', targetId) 149 | 150 | QBCore.Functions.Notify(tPlayer.PlayerData.source, locale("removed_stress_player"), 'success', 5000) 151 | end) 152 | -------------------------------------------------------------------------------- /server/regcommands.lua: -------------------------------------------------------------------------------- 1 | local commandsTable, addedCommands = {}, {} 2 | local blacklistCommands = { 3 | "sv_", "adhesive_", "citizen_", "con_", "endpoint_", "fileserver", "load_server", 4 | "mysql_connection", "net_tcp", "netPort", "netlib", "onesync", "onesync_", 5 | "rateLimiter_", "svgui", "web_base", "temp_", "txAdmin", "txa", 6 | } 7 | 8 | local function isCommandBlacklisted(commandName) 9 | for _, bcommand in pairs(blacklistCommands) do 10 | if string.match(commandName, '^' .. bcommand) then 11 | return true 12 | end 13 | end 14 | return false 15 | end 16 | 17 | lib.callback.register('ps-adminmenu:callback:GetCommands', function() 18 | if not CheckPerms(source, Config.ShowCommandsPerms) then return {} end 19 | 20 | local allCommands = GetRegisteredCommands() 21 | 22 | for _, command in ipairs(allCommands) do 23 | if not isCommandBlacklisted(command.name) and not addedCommands[command.name] then 24 | commandsTable[#commandsTable + 1] = { 25 | name = '/' .. command.name 26 | } 27 | addedCommands[command.name] = true -- prevent duplicates 28 | end 29 | end 30 | 31 | return commandsTable 32 | end) 33 | -------------------------------------------------------------------------------- /server/resources.lua: -------------------------------------------------------------------------------- 1 | local resources = {} 2 | 3 | lib.callback.register('ps-adminmenu:callback:GetResources', function(source) 4 | local totalResources = GetNumResources() 5 | 6 | resources = {} 7 | 8 | for i = 0, totalResources - 1 do 9 | local resourceName = GetResourceByFindIndex(i) 10 | local author = GetResourceMetadata(resourceName, "author") 11 | local version = GetResourceMetadata(resourceName, "version") 12 | local description = GetResourceMetadata(resourceName, "description") 13 | local resourceState = GetResourceState(resourceName) 14 | 15 | resources[#resources + 1] = { 16 | name = resourceName, 17 | author = author, 18 | version = version, 19 | description = description, 20 | resourceState = resourceState, 21 | } 22 | end 23 | 24 | return resources 25 | end) 26 | 27 | 28 | lib.callback.register('ps-adminmenu:callback:ChangeResourceState', function(source, data, perms) 29 | print(json.encode(data)) 30 | if not CheckPerms(source, Config.ResourcePerms) then return end 31 | 32 | if data.state == "start" then 33 | StartResource(data.name) 34 | print("Started " .. data.name) 35 | elseif data.state == "stop" then 36 | StopResource(data.name) 37 | print("Stopped " .. data.name) 38 | elseif data.state == "restart" then 39 | StopResource(data.name) 40 | Wait(200) 41 | StartResource(data.name) 42 | print("Restarted " .. data.name) 43 | end 44 | 45 | return resources 46 | end) 47 | -------------------------------------------------------------------------------- /server/spectate.lua: -------------------------------------------------------------------------------- 1 | local spectating = {} 2 | 3 | RegisterNetEvent('ps-adminmenu:server:SpectateTarget', function(data, selectedData) 4 | local data = CheckDataFromKey(data) 5 | if not data or not CheckPerms(source, data.perms) then return end 6 | local player = selectedData["Player"].value 7 | 8 | local type = "1" 9 | if player == source then return QBCore.Functions.Notify(source, locale("cant_spectate_yourself"), 'error', 7500) end 10 | if spectating[source] then type = "0" end 11 | TriggerEvent('ps-adminmenu:spectate', player, type == "1", source, data.perms) 12 | CheckRoutingbucket(source, player) 13 | end) 14 | 15 | AddEventHandler('ps-adminmenu:spectate', function(target, on, source, perms) 16 | local tPed = GetPlayerPed(target) 17 | local data = {} 18 | data.perms = perms 19 | if DoesEntityExist(tPed) then 20 | if not on then 21 | TriggerClientEvent('ps-adminmenu:cancelSpectate', source) 22 | spectating[source] = false 23 | FreezeEntityPosition(GetPlayerPed(source), false) 24 | TriggerClientEvent('ps-adminmenu:client:toggleNames', source, data) 25 | elseif on then 26 | TriggerClientEvent('ps-adminmenu:requestSpectate', source, NetworkGetNetworkIdFromEntity(tPed), target, 27 | GetPlayerName(target)) 28 | spectating[source] = true 29 | TriggerClientEvent('ps-adminmenu:client:toggleNames', source, data) 30 | end 31 | end 32 | end) 33 | 34 | RegisterNetEvent('ps-adminmenu:spectate:teleport', function(target) 35 | local source = source 36 | local ped = GetPlayerPed(target) 37 | if DoesEntityExist(ped) then 38 | local targetCoords = GetEntityCoords(ped) 39 | SetEntityCoords(GetPlayerPed(source), targetCoords.x, targetCoords.y, targetCoords.z - 10) 40 | FreezeEntityPosition(GetPlayerPed(source), true) 41 | end 42 | end) 43 | -------------------------------------------------------------------------------- /server/teleport.lua: -------------------------------------------------------------------------------- 1 | -- Teleport To Player 2 | RegisterNetEvent('ps-adminmenu:server:TeleportToPlayer', function(data, selectedData) 3 | local data = CheckDataFromKey(data) 4 | if not data or not CheckPerms(source, data.perms) then return end 5 | 6 | local src = source 7 | local player = selectedData["Player"].value 8 | local targetPed = GetPlayerPed(player) 9 | local coords = GetEntityCoords(targetPed) 10 | 11 | CheckRoutingbucket(src, player) 12 | TriggerClientEvent('ps-adminmenu:client:TeleportToPlayer', src, coords) 13 | end) 14 | 15 | -- Bring Player 16 | RegisterNetEvent('ps-adminmenu:server:BringPlayer', function(data, selectedData) 17 | local data = CheckDataFromKey(data) 18 | if not data or not CheckPerms(source, data.perms) then return end 19 | 20 | local src = source 21 | local targetPed = selectedData["Player"].value 22 | local admin = GetPlayerPed(src) 23 | local coords = GetEntityCoords(admin) 24 | local target = GetPlayerPed(targetPed) 25 | 26 | CheckRoutingbucket(targetPed, src) 27 | SetEntityCoords(target, coords) 28 | end) 29 | -------------------------------------------------------------------------------- /server/trolls.lua: -------------------------------------------------------------------------------- 1 | -- Freeze Player 2 | local frozen = false 3 | RegisterNetEvent('ps-adminmenu:server:FreezePlayer', function(data, selectedData) 4 | local data = CheckDataFromKey(data) 5 | if not data or not CheckPerms(source, data.perms) then return end 6 | local src = source 7 | 8 | local target = selectedData["Player"].value 9 | 10 | local ped = GetPlayerPed(target) 11 | local Player = QBCore.Functions.GetPlayer(target) 12 | 13 | if not frozen then 14 | frozen = true 15 | FreezeEntityPosition(ped, true) 16 | QBCore.Functions.Notify(src, 17 | locale("Frozen", 18 | Player.PlayerData.charinfo.firstname .. 19 | " " .. Player.PlayerData.charinfo.lastname .. " | " .. Player.PlayerData.citizenid), 'Success', 7500) 20 | else 21 | frozen = false 22 | FreezeEntityPosition(ped, false) 23 | QBCore.Functions.Notify(src, 24 | locale("deFrozen", 25 | Player.PlayerData.charinfo.firstname .. 26 | " " .. Player.PlayerData.charinfo.lastname .. " | " .. Player.PlayerData.citizenid), 'Success', 7500) 27 | end 28 | if Player == nil then return QBCore.Functions.Notify(src, locale("not_online"), 'error', 7500) end 29 | end) 30 | 31 | -- Drunk Player 32 | RegisterNetEvent('ps-adminmenu:server:DrunkPlayer', function(data, selectedData) 33 | local data = CheckDataFromKey(data) 34 | if not data or not CheckPerms(source, data.perms) then return end 35 | 36 | local src = source 37 | local target = selectedData["Player"].value 38 | local targetPed = GetPlayerPed(target) 39 | local Player = QBCore.Functions.GetPlayer(target) 40 | 41 | if not Player then 42 | return QBCore.Functions.Notify(src, locale("not_online"), 'error', 7500) 43 | end 44 | 45 | TriggerClientEvent('ps-adminmenu:client:InitiateDrunkEffect', target) 46 | QBCore.Functions.Notify(src, 47 | locale("playerdrunk", 48 | Player.PlayerData.charinfo.firstname .. 49 | " " .. Player.PlayerData.charinfo.lastname .. " | " .. Player.PlayerData.citizenid), 'Success', 7500) 50 | end) 51 | -------------------------------------------------------------------------------- /server/utils.lua: -------------------------------------------------------------------------------- 1 | local function noPerms(source) 2 | QBCore.Functions.Notify(source, "You are not Admin or God.", 'error') 3 | end 4 | 5 | --- @param perms string 6 | function CheckPerms(source, perms) 7 | local hasPerms = QBCore.Functions.HasPermission(source, perms) 8 | if not hasPerms then 9 | return noPerms(source) 10 | end 11 | 12 | return hasPerms 13 | end 14 | 15 | function CheckDataFromKey(key) 16 | local actions = Config.Actions[key] 17 | if actions then 18 | local data = nil 19 | 20 | if actions.event then 21 | data = actions 22 | end 23 | 24 | if actions.dropdown then 25 | for _, v in pairs(actions.dropdown) do 26 | if v.event then 27 | local new = v 28 | new.perms = actions.perms 29 | data = new 30 | break 31 | end 32 | end 33 | end 34 | 35 | return data 36 | end 37 | 38 | local playerActions = Config.PlayerActions[key] 39 | if playerActions then 40 | return playerActions 41 | end 42 | 43 | local otherActions = Config.OtherActions[key] 44 | if otherActions then 45 | return otherActions 46 | end 47 | end 48 | 49 | ---@param plate string 50 | ---@return boolean 51 | function CheckAlreadyPlate(plate) 52 | local vPlate = QBCore.Shared.Trim(plate) 53 | local result = MySQL.single.await("SELECT plate FROM player_vehicles WHERE plate = ?", { vPlate }) 54 | if result and result.plate then return true end 55 | return false 56 | end 57 | 58 | lib.callback.register('ps-adminmenu:callback:CheckPerms', function(source, perms) 59 | return CheckPerms(source, perms) 60 | end) 61 | 62 | lib.callback.register('ps-adminmenu:callback:CheckAlreadyPlate', function(_, vPlate) 63 | return CheckAlreadyPlate(vPlate) 64 | end) 65 | 66 | --- @param source number 67 | --- @param target number 68 | function CheckRoutingbucket(source, target) 69 | local sourceBucket = GetPlayerRoutingBucket(source) 70 | local targetBucket = GetPlayerRoutingBucket(target) 71 | 72 | if sourceBucket == targetBucket then return end 73 | 74 | SetPlayerRoutingBucket(source, targetBucket) 75 | QBCore.Functions.Notify(source, locale("bucket_set", targetBucket), 'error', 7500) 76 | end 77 | -------------------------------------------------------------------------------- /server/vehicle.lua: -------------------------------------------------------------------------------- 1 | -- Admin Car 2 | RegisterNetEvent('ps-adminmenu:server:SaveCar', function(mods, vehicle, _, plate) 3 | local src = source 4 | local Player = QBCore.Functions.GetPlayer(src) 5 | local result = MySQL.query.await('SELECT plate FROM player_vehicles WHERE plate = ?', { plate }) 6 | 7 | if result[1] == nil then 8 | MySQL.insert( 9 | 'INSERT INTO player_vehicles (license, citizenid, vehicle, hash, mods, plate, state) VALUES (?, ?, ?, ?, ?, ?, ?)', 10 | { 11 | Player.PlayerData.license, 12 | Player.PlayerData.citizenid, 13 | vehicle.model, 14 | vehicle.hash, 15 | json.encode(mods), 16 | plate, 17 | 0 18 | }) 19 | TriggerClientEvent('QBCore:Notify', src, locale("veh_owner"), 'success', 5000) 20 | else 21 | TriggerClientEvent('QBCore:Notify', src, locale("u_veh_owner"), 'error', 3000) 22 | end 23 | end) 24 | 25 | -- Give Car 26 | RegisterNetEvent("ps-adminmenu:server:givecar", function(data, selectedData) 27 | local src = source 28 | 29 | local data = CheckDataFromKey(data) 30 | if not data or not CheckPerms(source, data.perms) then 31 | QBCore.Functions.Notify(src, locale("no_perms"), "error", 5000) 32 | return 33 | end 34 | 35 | local vehmodel = selectedData['Vehicle'].value 36 | local vehicleData = lib.callback.await("ps-adminmenu:client:getvehData", src, vehmodel) 37 | 38 | if not next(vehicleData) then 39 | return 40 | end 41 | 42 | local tsrc = selectedData['Player'].value 43 | local plate = selectedData['Plate (Optional)'] and selectedData['Plate (Optional)'].value or vehicleData.plate 44 | local garage = selectedData['Garage (Optional)'] and selectedData['Garage (Optional)'].value or Config.DefaultGarage 45 | local Player = QBCore.Functions.GetPlayer(tsrc) 46 | 47 | if plate and #plate < 1 then 48 | plate = vehicleData.plate 49 | end 50 | 51 | if garage and #garage < 1 then 52 | garage = Config.DefaultGarage 53 | end 54 | 55 | if plate:len() > 8 then 56 | QBCore.Functions.Notify(src, locale("plate_max"), "error", 5000) 57 | return 58 | end 59 | 60 | if not Player then 61 | QBCore.Functions.Notify(src, locale("not_online"), "error", 5000) 62 | return 63 | end 64 | 65 | if CheckAlreadyPlate(plate) then 66 | QBCore.Functions.Notify(src, locale("givecar.error.plates_alreadyused", plate:upper()), "error", 5000) 67 | return 68 | end 69 | 70 | MySQL.insert( 71 | 'INSERT INTO player_vehicles (license, citizenid, vehicle, hash, mods, plate, garage, state) VALUES (?, ?, ?, ?, ?, ?, ?, ?)', 72 | { 73 | Player.PlayerData.license, 74 | Player.PlayerData.citizenid, 75 | vehmodel, 76 | joaat(vehmodel), 77 | json.encode(vehicleData), 78 | plate, 79 | garage, 80 | 1 81 | }) 82 | 83 | QBCore.Functions.Notify(src, 84 | locale("givecar.success.source", QBCore.Shared.Vehicles[vehmodel].name, 85 | ("%s %s"):format(Player.PlayerData.charinfo.firstname, Player.PlayerData.charinfo.lastname)), "success", 5000) 86 | QBCore.Functions.Notify(Player.PlayerData.source, locale("givecar.success.target", plate:upper(), garage), "success", 87 | 5000) 88 | end) 89 | 90 | -- Give Car 91 | RegisterNetEvent("ps-adminmenu:server:SetVehicleState", function(data, selectedData) 92 | local src = source 93 | 94 | local data = CheckDataFromKey(data) 95 | if not data or not CheckPerms(source, data.perms) then 96 | QBCore.Functions.Notify(src, locale("no_perms"), "error", 5000) 97 | return 98 | end 99 | 100 | local plate = string.upper(selectedData['Plate'].value) 101 | local state = tonumber(selectedData['State'].value) 102 | 103 | if plate:len() > 8 then 104 | QBCore.Functions.Notify(src, locale("plate_max"), "error", 5000) 105 | return 106 | end 107 | 108 | if not CheckAlreadyPlate(plate) then 109 | QBCore.Functions.Notify(src, locale("plate_doesnt_exist"), "error", 5000) 110 | return 111 | end 112 | 113 | MySQL.update('UPDATE player_vehicles SET state = ?, depotprice = ? WHERE plate = ?', { state, 0, plate }) 114 | 115 | QBCore.Functions.Notify(src, locale("state_changed"), "success", 5000) 116 | end) 117 | 118 | -- Change Plate 119 | RegisterNetEvent('ps-adminmenu:server:ChangePlate', function(newPlate, currentPlate) 120 | local newPlate = newPlate:upper() 121 | 122 | if Config.Inventory == 'ox_inventory' then 123 | exports.ox_inventory:UpdateVehicle(currentPlate, newPlate) 124 | end 125 | 126 | MySQL.Sync.execute('UPDATE player_vehicles SET plate = ? WHERE plate = ?', { newPlate, currentPlate }) 127 | MySQL.Sync.execute('UPDATE trunkitems SET plate = ? WHERE plate = ?', { newPlate, currentPlate }) 128 | MySQL.Sync.execute('UPDATE gloveboxitems SET plate = ? WHERE plate = ?', { newPlate, currentPlate }) 129 | end) 130 | 131 | lib.callback.register('ps-adminmenu:server:GetVehicleByPlate', function(source, plate) 132 | local result = MySQL.query.await('SELECT vehicle FROM player_vehicles WHERE plate = ?', { plate }) 133 | local veh = result[1] and result[1].vehicle or {} 134 | return veh 135 | end) 136 | 137 | -- Fix Vehicle for player 138 | RegisterNetEvent('ps-adminmenu:server:FixVehFor', function(data, selectedData) 139 | local data = CheckDataFromKey(data) 140 | if not data or not CheckPerms(source, data.perms) then return end 141 | local src = source 142 | local playerId = selectedData['Player'].value 143 | local Player = QBCore.Functions.GetPlayer(tonumber(playerId)) 144 | if Player then 145 | local name = Player.PlayerData.charinfo.firstname .. " " .. Player.PlayerData.charinfo.lastname 146 | TriggerClientEvent('iens:repaira', Player.PlayerData.source) 147 | TriggerClientEvent('vehiclemod:client:fixEverything', Player.PlayerData.source) 148 | QBCore.Functions.Notify(src, locale("veh_fixed", name), 'success', 7500) 149 | else 150 | TriggerClientEvent('QBCore:Notify', src, locale("not_online"), "error") 151 | end 152 | end) 153 | -------------------------------------------------------------------------------- /ui/.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules/ 2 | 3 | 4 | .DS_Store 5 | -------------------------------------------------------------------------------- /ui/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "tabWidth": 4, 3 | "useTabs": true, 4 | "semi": false, 5 | "singleQuote": true 6 | } 7 | -------------------------------------------------------------------------------- /ui/README.md: -------------------------------------------------------------------------------- 1 | # Svelte + TS + Vite 2 | 3 | This template should help get you started developing with Svelte and TypeScript in Vite. 4 | 5 | ## Recommended IDE Setup 6 | 7 | [VSCode](https://code.visualstudio.com/) + [Svelte](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode). 8 | 9 | ## Need an official Svelte framework? 10 | 11 | Check out [SvelteKit](https://github.com/sveltejs/kit#readme), which is also powered by Vite. Deploy anywhere with its serverless-first approach and adapt to various platforms, with out of the box support for TypeScript, SCSS, and Less, and easily-added support for mdsvex, GraphQL, PostCSS, Tailwind CSS, and more. 12 | 13 | ## Technical considerations 14 | 15 | **Why use this over SvelteKit?** 16 | 17 | - It brings its own routing solution which might not be preferable for some users. 18 | - It is first and foremost a framework that just happens to use Vite under the hood, not a Vite app. 19 | `vite dev` and `vite build` wouldn't work in a SvelteKit environment, for example. 20 | 21 | This template contains as little as possible to get started with Vite + TypeScript + Svelte, while taking into account the developer experience with regards to HMR and intellisense. It demonstrates capabilities on par with the other `create-vite` templates and is a good starting point for beginners dipping their toes into a Vite + Svelte project. 22 | 23 | Should you later need the extended capabilities and extensibility provided by SvelteKit, the template has been structured similarly to SvelteKit so that it is easy to migrate. 24 | 25 | **Why `global.d.ts` instead of `compilerOptions.types` inside `jsconfig.json` or `tsconfig.json`?** 26 | 27 | Setting `compilerOptions.types` shuts out all other types not explicitly listed in the configuration. Using triple-slash references keeps the default TypeScript setting of accepting type information from the entire workspace, while also adding `svelte` and `vite/client` type information. 28 | 29 | **Why enable `allowJs` in the TS template?** 30 | 31 | While `allowJs: false` would indeed prevent the use of `.js` files in the project, it does not prevent the use of JavaScript syntax in `.svelte` files. In addition, it would force `checkJs: false`, bringing the worst of both worlds: not being able to guarantee the entire codebase is TypeScript, and also having worse typechecking for the existing JavaScript. In addition, there are valid use cases in which a mixed codebase may be relevant. 32 | 33 | **Why is HMR not preserving my local component state?** 34 | 35 | HMR state preservation comes with a number of gotchas! It has been disabled by default in both `svelte-hmr` and `@sveltejs/vite-plugin-svelte` due to its often surprising behavior. You can read the details [here](https://github.com/rixo/svelte-hmr#svelte-hmr). 36 | 37 | If you have state that's important to retain within a component, consider creating an external store which would not be replaced by HMR. 38 | 39 | ```ts 40 | // store.ts 41 | // An extremely simple external store 42 | import { writable } from 'svelte/store' 43 | export default writable(0) 44 | ``` 45 | -------------------------------------------------------------------------------- /ui/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | ps-adminmenu 19 | 20 | 21 |
22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /ui/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "would_you_rather", 3 | "version": "0.0.0", 4 | "type": "module", 5 | "scripts": { 6 | "dev": "vite", 7 | "build": "vite build", 8 | "preview": "vite preview", 9 | "check": "svelte-check --tsconfig ./tsconfig.json" 10 | }, 11 | "devDependencies": { 12 | "@sveltejs/vite-plugin-svelte": "^2.4.3", 13 | "@tsconfig/svelte": "^5.0.0", 14 | "autoprefixer": "^10.4.14", 15 | "postcss": "^8.4.27", 16 | "svelte": "^4.1.2", 17 | "svelte-check": "^3.4.6", 18 | "svelte-preprocess": "^5.0.4", 19 | "tailwindcss": "^3.3.3", 20 | "tslib": "^2.6.1", 21 | "typescript": "^5.1.6", 22 | "vite": "^4.4.9" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /ui/postcss.config.js: -------------------------------------------------------------------------------- 1 | import tailwind from 'tailwindcss'; 2 | import autoprefixer from 'autoprefixer'; 3 | import tailwindConfig from './tailwind.config.cjs'; 4 | 5 | export default { 6 | plugins: [tailwind(tailwindConfig), autoprefixer], 7 | } 8 | -------------------------------------------------------------------------------- /ui/src/App.svelte: -------------------------------------------------------------------------------- 1 | 17 | 18 | 19 |
20 | 21 | 22 | {#if $VEHICLE_DEV?.show} 23 | 24 | {/if} 25 | 26 | {#if $TOGGLE_COORDS?.show} 27 | 28 | {/if} 29 | 30 | {#if $ENTITY_INFO?.show} 31 | 32 | {/if} 33 | 34 | 35 | {#if $BROWSER_MODE} 36 | 37 |
38 | {/if} 39 | -------------------------------------------------------------------------------- /ui/src/components/Autofill.svelte: -------------------------------------------------------------------------------- 1 | 53 | 54 |
55 |
56 | 64 | 65 |
66 | 67 | {#if DataDropdownActive} 68 | 85 | {/each} 86 | {:else if data === "vehicles"} 87 | {#each $VEHICLE_DATA.filter(i => i.label.toLowerCase().includes(search.toLowerCase()) || i.value.toLowerCase().includes(search.toLowerCase())) as i} 88 | 95 | {/each} 96 | {:else if data === "items"} 97 | {#each $ITEM_DATA.filter(i => i.label.toLowerCase().includes(search.toLowerCase()) || i.value.toLowerCase().includes(search.toLowerCase())) as i} 98 | 105 | {/each} 106 | {:else if data === "jobs"} 107 | {#each $JOB_DATA.filter(i => i.label.toLowerCase().includes(search.toLowerCase()) || i.value.toLowerCase().includes(search.toLowerCase())) as i} 108 | 115 | {/each} 116 | {:else if data === "gangs"} 117 | {#each $GANG_DATA.filter(i => i.label.toLowerCase().includes(search.toLowerCase()) || i.value.toLowerCase().includes(search.toLowerCase())) as i} 118 | 125 | {/each} 126 | {:else if data === "locations"} 127 | {#each $LOCATION_DATA.filter(i => i.label.toLowerCase().includes(search.toLowerCase()) || i.value.toLowerCase().includes(search.toLowerCase())) as i} 128 | 135 | {/each} 136 | {:else if data === "pedlist"} 137 | {#each $PED_LIST.filter(i => i.label.toLowerCase().includes(search.toLowerCase()) || i.value.toLowerCase().includes(search.toLowerCase())) as i} 138 | 145 | {/each} 146 | {:else} 147 | {#each data.filter(i => i.label.toLowerCase().includes(search.toLowerCase()) || i.value.toLowerCase().includes(search.toLowerCase())) as i} 148 | 155 | {/each} 156 | {/if} 157 | 158 | {/if} 159 |
160 | 161 | -------------------------------------------------------------------------------- /ui/src/components/DropdownComponent.svelte: -------------------------------------------------------------------------------- 1 | 29 | 30 | 70 | 71 | -------------------------------------------------------------------------------- /ui/src/components/EntityInformation.svelte: -------------------------------------------------------------------------------- 1 | 5 | 6 |
7 |
8 |
9 | 10 |

Entity Information

11 |
12 |
13 |

Model: {$ENTITY_INFO?.name}

14 |

Hash: {$ENTITY_INFO?.hash}

15 |
16 |

C - Copy Information

17 |

E - Delete Entity

18 |

ESC - Close

19 |
20 |
21 |
-------------------------------------------------------------------------------- /ui/src/components/Header.svelte: -------------------------------------------------------------------------------- 1 | 10 | 11 |

{title}

12 | 13 | {#if hasSearch} 14 |
17 | 18 | 25 |
26 | {/if} 27 | -------------------------------------------------------------------------------- /ui/src/components/Modal.svelte: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 |
5 |
-------------------------------------------------------------------------------- /ui/src/components/Spinner.svelte: -------------------------------------------------------------------------------- 1 |
2 |
5 |
6 |
7 | -------------------------------------------------------------------------------- /ui/src/components/ToggleCoords.svelte: -------------------------------------------------------------------------------- 1 | 5 | 6 |
7 |
8 |
9 | 10 |

Coords Information

11 |
12 |
13 |

X: {$TOGGLE_COORDS?.x}

14 |

Y: {$TOGGLE_COORDS?.y}

15 |

Z: {$TOGGLE_COORDS?.z}

16 |

Heading: {$TOGGLE_COORDS?.heading}

17 |
18 |
19 |
-------------------------------------------------------------------------------- /ui/src/components/VehicleDev.svelte: -------------------------------------------------------------------------------- 1 | 5 | 6 |
7 |
8 |
9 | 10 |

Vehicle Information

11 |
12 |
13 |

Model: {$VEHICLE_DEV?.name}

14 |

Hash: {$VEHICLE_DEV?.model}

15 |

NetID: {$VEHICLE_DEV?.netID}

16 |

Plate: {$VEHICLE_DEV?.plate}

17 |

Fuel: {$VEHICLE_DEV?.fuel}

18 |

Engine: {$VEHICLE_DEV?.engine_health}

19 |

Body: {$VEHICLE_DEV?.body_health}

20 |
21 |
22 |
-------------------------------------------------------------------------------- /ui/src/layout/Main.svelte: -------------------------------------------------------------------------------- 1 | 12 | 13 |
16 | 17 |
18 | {#if $ACTIVE_PAGE == 'Actions'} 19 | 20 | {:else if $ACTIVE_PAGE == 'Server'} 21 | 22 | {:else if $ACTIVE_PAGE == 'Staffchat'} 23 | 24 | {:else if $ACTIVE_PAGE == 'Players'} 25 | 26 | {:else if $ACTIVE_PAGE == 'Commands'} 27 | 28 | {/if} 29 |
30 |
31 | -------------------------------------------------------------------------------- /ui/src/layout/Sidebar/Components/Button.svelte: -------------------------------------------------------------------------------- 1 | 8 | 9 | -------------------------------------------------------------------------------- /ui/src/layout/Sidebar/Sidebar.svelte: -------------------------------------------------------------------------------- 1 | 14 | 15 |
18 |
19 | 29 |
30 | 31 | {#each navigation as nav} 32 | 74 |
75 | -------------------------------------------------------------------------------- /ui/src/main.ts: -------------------------------------------------------------------------------- 1 | import App from './App.svelte' 2 | import './styles.css' 3 | 4 | const app = new App({ 5 | target: document.getElementById('app') 6 | }) 7 | 8 | export default app 9 | -------------------------------------------------------------------------------- /ui/src/pages/Actions/components/Button.svelte: -------------------------------------------------------------------------------- 1 | 13 | 14 | 28 | -------------------------------------------------------------------------------- /ui/src/pages/Actions/components/Dropdown.svelte: -------------------------------------------------------------------------------- 1 | 36 | 37 |
42 | 52 | 53 | {#if dropdownActive} 54 |
58 | {#if data.dropdown} 59 | {#each data.dropdown as i} 60 | {#if i.option === 'text'} 61 | 62 | {:else if i.option === 'dropdown'} 63 | 69 | {:else if i.option === 'button'} 70 | 78 | {/if} 79 | {/each} 80 | {/if} 81 |
82 | {/if} 83 |
84 | -------------------------------------------------------------------------------- /ui/src/pages/Actions/components/Favorite.svelte: -------------------------------------------------------------------------------- 1 | 19 | 20 | 25 | -------------------------------------------------------------------------------- /ui/src/pages/Actions/components/Input.svelte: -------------------------------------------------------------------------------- 1 | 16 | 17 | 18 |
19 |
20 | input = e.target.value} 25 | on:blur={() => selectData(data.label, input)} 26 | on:click={() => selectData(data.label, input)} 27 | class="h-full w-[90%] bg-transparent" 28 | /> 29 |
30 |
-------------------------------------------------------------------------------- /ui/src/pages/Actions/components/Tabs.svelte: -------------------------------------------------------------------------------- 1 | 4 | 5 |
6 | 15 | 24 |
25 | -------------------------------------------------------------------------------- /ui/src/pages/Chat/Chat.svelte: -------------------------------------------------------------------------------- 1 | 8 | 9 |
10 |
11 |
12 | 13 |
14 | 15 |
-------------------------------------------------------------------------------- /ui/src/pages/Chat/components/RecieveInput.svelte: -------------------------------------------------------------------------------- 1 | 21 | 22 |
23 | 24 |
25 | {#if $Message && $Messages} 26 | {#each $Message as message} 27 |
28 |
29 |

{message.fullname}

30 |
31 |
32 |

{message.message}

33 |
34 |

{timeAgo(Number(message.time))}

35 |
36 | {/each} 37 | {/if} 38 |
39 | 40 |
-------------------------------------------------------------------------------- /ui/src/pages/Chat/components/SendInput.svelte: -------------------------------------------------------------------------------- 1 | 26 | 27 |
30 | { 34 | if (e.key === "Enter") { 35 | sendMessage(); 36 | } 37 | }} 38 | bind:value={message} 39 | class="h-full px-[1vh] bg-transparent text-[1.7vh] {$MENU_WIDE ? 'w-[94%]' : 'w-[80%]'}" 40 | /> 41 | 47 |
-------------------------------------------------------------------------------- /ui/src/pages/Commands/Commands.svelte: -------------------------------------------------------------------------------- 1 | 12 | 13 |
14 |
(search = event.target.value)} 18 | /> 19 |
20 | {#if $COMMANDS} 21 | {#if $COMMANDS && $COMMANDS.filter((commands) => commands.name.toLowerCase().includes(search.toLowerCase())).length === 0} 22 |
No Commands Found.
23 | {:else} 24 | Total Commands: {SortedCommands.length} 25 | {#each SortedCommands.filter((commands) => commands.name.toLowerCase().includes(search.toLowerCase())) as commands} 26 | 27 | {/each} 28 | {/if} 29 | {/if} 30 |
31 |
32 | 33 | {#if $MENU_WIDE} 34 |
35 |
36 |
37 | {/if} 38 | -------------------------------------------------------------------------------- /ui/src/pages/Commands/components/CommandsCard.svelte: -------------------------------------------------------------------------------- 1 | 4 | 5 | 11 | -------------------------------------------------------------------------------- /ui/src/pages/Players/components/Button.svelte: -------------------------------------------------------------------------------- 1 | 13 | 14 | 25 | -------------------------------------------------------------------------------- /ui/src/pages/Server/components/ButtonState.svelte: -------------------------------------------------------------------------------- 1 | 15 | 16 | 22 | -------------------------------------------------------------------------------- /ui/src/pages/Server/components/ResourceCard.svelte: -------------------------------------------------------------------------------- 1 | 14 | 15 | 39 | -------------------------------------------------------------------------------- /ui/src/pages/actions/Actions.svelte: -------------------------------------------------------------------------------- 1 | 12 | 13 |
14 |
$searchActions = event.target.value} 19 | search={$searchActions} 20 | /> 21 | 22 |
23 | {#if $ACTION} 24 | {#each Object.entries($ACTION) 25 | .filter(([actionKey, actionValue]) => { 26 | if ($ALL_ACTIONS) { 27 | return actionValue.label.toLowerCase().includes($searchActions.toLowerCase()); 28 | } else { 29 | return localStorage.getItem(`favorite-${actionKey}`) === 'true'; 30 | } 31 | }) 32 | .sort(([aKey, aValue], [bKey, bValue]) => 33 | aValue.label.localeCompare(bValue.label) 34 | ) as [actionKey, actionValue]} 35 | {#if actionValue.dropdown} 36 | 37 | {:else} 38 |
43 |
44 | -------------------------------------------------------------------------------- /ui/src/pages/server/Server.svelte: -------------------------------------------------------------------------------- 1 | 12 | 13 |
14 |
(search = event.target.value)} 18 | /> 19 |
20 | {#if $RESOURCE} 21 | {#if $RESOURCE && $RESOURCE.filter((resource) => resource.name.toLowerCase().includes(search.toLowerCase())).length === 0} 22 |
No Resource Found.
23 | {:else} 24 | {#each SortedResources.filter((resource) => resource.name.toLowerCase().includes(search.toLowerCase())) as resource} 25 | 32 | {/each} 33 | {/if} 34 | {/if} 35 |
36 |
37 | 38 | {#if $MENU_WIDE} 39 |
40 |
41 |
42 | {/if} 43 | -------------------------------------------------------------------------------- /ui/src/providers/AlwaysListener.svelte: -------------------------------------------------------------------------------- 1 | 69 | -------------------------------------------------------------------------------- /ui/src/providers/BackdropFix.svelte: -------------------------------------------------------------------------------- 1 | 177 | 178 |
179 | 184 |
185 | 186 | -------------------------------------------------------------------------------- /ui/src/providers/VisibilityProvider.svelte: -------------------------------------------------------------------------------- 1 | 48 | 49 | {#if isVisible} 50 |
51 | 52 |
53 | 54 | {/if} 55 | 56 | 70 | -------------------------------------------------------------------------------- /ui/src/store/actions.ts: -------------------------------------------------------------------------------- 1 | import { writable } from "svelte/store"; 2 | 3 | export const ALL_ACTIONS = writable(true); 4 | 5 | export const ACTION = writable(null); 6 | 7 | interface DROPDOWN_DATA { 8 | label: string; 9 | type: string; 10 | option?: string; 11 | data?: any[]; 12 | event?: string; 13 | } 14 | 15 | interface ACITONS_DATA { 16 | id: string; 17 | label: string; 18 | type?: string; 19 | event?: string; 20 | perms: string[]; 21 | dropdown?: DROPDOWN_DATA[]; 22 | } -------------------------------------------------------------------------------- /ui/src/store/data.ts: -------------------------------------------------------------------------------- 1 | import { writable } from "svelte/store"; 2 | 3 | export const VEHICLE_DATA = writable(null); 4 | export const ITEM_DATA = writable(null); 5 | export const JOB_DATA = writable(null); 6 | export const GANG_DATA = writable(null); 7 | export const LOCATION_DATA = writable(null); 8 | export const PED_LIST = writable(null); -------------------------------------------------------------------------------- /ui/src/store/entityInfo.ts: -------------------------------------------------------------------------------- 1 | import { writable } from "svelte/store"; 2 | 3 | export const ENTITY_INFO = writable(null); 4 | 5 | interface ENTITY_INFO { 6 | show: boolean; 7 | name: string; 8 | hash: string; 9 | } -------------------------------------------------------------------------------- /ui/src/store/players.ts: -------------------------------------------------------------------------------- 1 | import { writable } from "svelte/store"; 2 | 3 | export const PLAYER_DATA = writable(null); 4 | 5 | export const SELECTED_PLAYER = writable(null); 6 | 7 | export const PLAYER = writable(null); 8 | 9 | export const PLAYER_VEHICLES = writable(null); 10 | 11 | interface PLAYER_DATA { 12 | id?: string; 13 | name?: string; 14 | cid?: string; 15 | license?: string; 16 | discord?: string; 17 | steam?: string; 18 | fivem?: string; 19 | vehicles?: PLAYER_VEHICLES[]; 20 | } 21 | 22 | interface PLAYER_VEHICLES { 23 | id?: string; 24 | cid?: string; 25 | label?: string; 26 | brand?: string; 27 | model?: string; 28 | plate?: string; 29 | fuel?: string; 30 | engine?: string; 31 | body?: string; 32 | } 33 | -------------------------------------------------------------------------------- /ui/src/store/reports.ts: -------------------------------------------------------------------------------- 1 | import { writable } from "svelte/store"; 2 | 3 | export const REPORT = writable(null); 4 | export const REPORTS = writable(null); 5 | 6 | interface REPORT_DATA { 7 | message: string, 8 | citizenid: string, 9 | fullname: string, 10 | time: number, 11 | } -------------------------------------------------------------------------------- /ui/src/store/server.ts: -------------------------------------------------------------------------------- 1 | import { writable } from "svelte/store"; 2 | 3 | export const RESOURCE = writable(null); 4 | export const RESOURCES = writable(null); 5 | export const COMMANDS = writable(null); 6 | 7 | export const SERVER = writable(null); 8 | 9 | interface RESOURCE_DATA { 10 | name?: string; 11 | author?: string; 12 | version?: string; 13 | description?: string; 14 | resourceState?: string; 15 | } 16 | 17 | interface SERVER_DATA { 18 | TotalCash?: string; 19 | TotalBank?: string; 20 | TotalItems?: string; 21 | CharacterCount?: string; 22 | VehicleCount?: string; 23 | BansCount?: string; 24 | UniquePlayers?: string; 25 | } 26 | 27 | interface COMMANDS_DATA { 28 | name?: string; 29 | } 30 | -------------------------------------------------------------------------------- /ui/src/store/staffchat.ts: -------------------------------------------------------------------------------- 1 | import { writable } from 'svelte/store' 2 | 3 | interface ChatData { 4 | message: string 5 | citizenid: string 6 | fullname: string 7 | time: number 8 | } 9 | 10 | export const Message = writable(null) 11 | export const Messages = writable(null) 12 | -------------------------------------------------------------------------------- /ui/src/store/stores.ts: -------------------------------------------------------------------------------- 1 | import { writable } from "svelte/store"; 2 | 3 | export const VISIBILITY = writable(false); 4 | export const BROWSER_MODE = writable(false); 5 | export const RESOURCE_NAME = writable(""); 6 | 7 | export const DEV_MODE = writable(false); 8 | 9 | export const MENU_WIDE = writable(false); 10 | export const ACTIVE_PAGE = writable("Actions"); 11 | 12 | export const searchActions = writable(''); -------------------------------------------------------------------------------- /ui/src/store/togglecoords.ts: -------------------------------------------------------------------------------- 1 | import { writable } from "svelte/store"; 2 | 3 | export const TOGGLE_COORDS = writable(null); 4 | 5 | interface COORDS_DATA { 6 | show: boolean; 7 | x: string; 8 | y: string; 9 | z: string; 10 | heading?: string; 11 | } -------------------------------------------------------------------------------- /ui/src/store/vehicle_dev.ts: -------------------------------------------------------------------------------- 1 | import { writable } from "svelte/store"; 2 | 3 | export const VEHICLE_DEV = writable(null); 4 | 5 | interface VEHICLE_DATA { 6 | show: boolean; 7 | name: string; 8 | model: string; 9 | netID: string; 10 | engine_health?: string; 11 | body_health?: string; 12 | plate?: string; 13 | fuel?: string; 14 | speed?: string; 15 | } -------------------------------------------------------------------------------- /ui/src/styles.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | * { 6 | margin: 0; 7 | padding: 0; 8 | font-smooth: auto; 9 | } 10 | 11 | *:focus { 12 | outline: none; 13 | } 14 | 15 | :root { 16 | font-size: 62.5%; 17 | font-smooth: auto; 18 | color: #c2c2c2; 19 | font-synthesis: none; 20 | text-rendering: optimizeLegibility; 21 | -webkit-font-smoothing: antialiased; 22 | -moz-osx-font-smoothing: grayscale; 23 | -webkit-text-size-adjust: 100%; 24 | } 25 | 26 | html, 27 | body { 28 | height: 100vh; 29 | width: 100vw; 30 | font-size: 1.6rem; 31 | overflow: hidden; 32 | } 33 | 34 | ::-webkit-scrollbar { 35 | height: 0px; 36 | width: 0vh; 37 | background-color: #24272b; 38 | } 39 | 40 | .scroll-visble ::-webkit-scrollbar { 41 | width: 0.5vh; 42 | background-color: #141517; 43 | } 44 | 45 | ::-webkit-scrollbar-thumb { 46 | background-color: #24272b; 47 | border-radius: 50px; 48 | } 49 | -------------------------------------------------------------------------------- /ui/src/typings/type.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Project-Sloth/ps-adminmenu/00d18577021879eade34e2bcd435eb64be819237/ui/src/typings/type.ts -------------------------------------------------------------------------------- /ui/src/utils/ReceiveNUI.ts: -------------------------------------------------------------------------------- 1 | import { onMount, onDestroy } from "svelte"; 2 | 3 | interface NuiMessage { 4 | action: string; 5 | data: T; 6 | } 7 | 8 | /** 9 | * A function that manage events listeners for receiving data from the client scripts 10 | * @param action The specific `action` that should be listened for. 11 | * @param handler The callback function that will handle data relayed by this function 12 | * 13 | * @example 14 | * useNuiEvent<{VISIBILITY: true, wasVisible: 'something'}>('setVisible', (data) => { 15 | * // whatever logic you want 16 | * }) 17 | * 18 | **/ 19 | 20 | export function ReceiveNUI( 21 | action: string, 22 | handler: (data: T) => void 23 | ) { 24 | const eventListener = (event: MessageEvent>) => { 25 | const { action: eventAction, data } = event.data; 26 | 27 | eventAction === action && handler(data); 28 | }; 29 | onMount(() => window.addEventListener("message", eventListener)); 30 | onDestroy(() => window.removeEventListener("message", eventListener)); 31 | } 32 | 33 | -------------------------------------------------------------------------------- /ui/src/utils/SendNUI.ts: -------------------------------------------------------------------------------- 1 | import { BROWSER_MODE, RESOURCE_NAME } from '@store/stores' 2 | 3 | let isBrowserMode: boolean = false; 4 | BROWSER_MODE.subscribe((value: boolean) => { 5 | isBrowserMode = value; 6 | }); 7 | 8 | let debugResName: string = ""; 9 | RESOURCE_NAME.subscribe((value: string) => { 10 | debugResName = value; 11 | }); 12 | 13 | /** 14 | * @param eventName - The endpoint eventname to target 15 | * @param data - Data you wish to send in the NUI Callback 16 | * 17 | * @return returnData - A promise for the data sent back by the NuiCallbacks CB argument 18 | */ 19 | 20 | export async function SendNUI( 21 | eventName: string, 22 | data: unknown = {}, 23 | debugReturn?: T 24 | ): Promise { 25 | if ((isBrowserMode == true && debugReturn) || (isBrowserMode == true)) { 26 | return Promise.resolve(debugReturn || {} as T) 27 | } 28 | const options = { 29 | method: "post", 30 | headers: { 31 | "Content-Type": "application/json; charset=UTF-8", 32 | }, 33 | body: JSON.stringify(data), 34 | }; 35 | 36 | const resourceName = (window as any).GetParentResourceName 37 | ? (window as any).GetParentResourceName() 38 | : debugResName; 39 | 40 | 41 | const resp: Response = await fetch(`https://${resourceName}/${eventName}`, options); 42 | return await resp.json() 43 | } 44 | -------------------------------------------------------------------------------- /ui/src/utils/debugData.ts: -------------------------------------------------------------------------------- 1 | import {isEnvBrowser} from "./misc"; 2 | 3 | interface DebugEvent { 4 | action: string; 5 | data: T; 6 | } 7 | 8 | /* 9 | * Emulates dispatching an event using SendNuiMessage in the lua scripts. 10 | * This is used when developing in browser 11 | * 12 | * @param events - The event you want to cover 13 | * @param timer - How long until it should trigger (ms) 14 | */ 15 | export const debugData =

(events: DebugEvent

[], timer = 0): void => { 16 | if (isEnvBrowser()) { 17 | for (const event of events) { 18 | setTimeout(() => { 19 | window.dispatchEvent( 20 | new MessageEvent("message", { 21 | data: { 22 | action: event.action, 23 | data: event.data, 24 | }, 25 | }) 26 | ); 27 | }, timer); 28 | } 29 | } 30 | }; -------------------------------------------------------------------------------- /ui/src/utils/misc.ts: -------------------------------------------------------------------------------- 1 | export const isEnvBrowser = (): boolean => !(window as any).invokeNative; -------------------------------------------------------------------------------- /ui/src/utils/timeAgo.ts: -------------------------------------------------------------------------------- 1 | const MONTH_NAMES = [ 2 | 'January', 3 | 'February', 4 | 'March', 5 | 'April', 6 | 'May', 7 | 'June', 8 | 'July', 9 | 'August', 10 | 'September', 11 | 'October', 12 | 'November', 13 | 'December', 14 | ] 15 | 16 | function getFormattedDate(date, prefomattedDate = false, hideYear = false) { 17 | const day = date.getDate() 18 | const month = MONTH_NAMES[date.getMonth()] 19 | const year = date.getFullYear() 20 | const hours = date.getHours() 21 | let minutes = date.getMinutes() 22 | 23 | if (minutes < 10) { 24 | minutes = `0${minutes}` 25 | } 26 | 27 | if (prefomattedDate) { 28 | return `${prefomattedDate} at ${hours}:${minutes}` 29 | } 30 | 31 | if (hideYear) { 32 | return `${day}. ${month} at ${hours}:${minutes}` 33 | } 34 | 35 | return `${day}. ${month} ${year}. at ${hours}:${minutes}` 36 | } 37 | 38 | export function timeAgo(dateParam) { 39 | if (!dateParam) { 40 | return 'Unknown' 41 | } 42 | 43 | let date 44 | try { 45 | date = typeof dateParam === 'object' ? dateParam : new Date(dateParam) 46 | } catch (e) { 47 | return 'Invalid date' 48 | } 49 | 50 | if (isNaN(date)) { 51 | return 'Invalid date' 52 | } 53 | const DAY_IN_MS = 86400000 54 | const today = new Date() 55 | const yesterday = new Date(today - DAY_IN_MS) 56 | const seconds = Math.round((today - date) / 1000) 57 | const minutes = Math.round(seconds / 60) 58 | const isToday = today.toDateString() === date.toDateString() 59 | const isYesterday = yesterday.toDateString() === date.toDateString() 60 | const isThisYear = today.getFullYear() === date.getFullYear() 61 | 62 | if (seconds < 5) { 63 | return 'Just Now' 64 | } else if (seconds < 60) { 65 | return `${seconds} Seconds ago` 66 | } else if (seconds < 90) { 67 | return 'A minute ago' 68 | } else if (minutes < 60) { 69 | return `${minutes} Minutes ago` 70 | } else if (isToday) { 71 | return getFormattedDate(date, 'Today') 72 | } else if (isYesterday) { 73 | return getFormattedDate(date, 'Yesterday') 74 | } else if (isThisYear) { 75 | return getFormattedDate(date, false, true) 76 | } 77 | 78 | return getFormattedDate(date) 79 | } -------------------------------------------------------------------------------- /ui/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | -------------------------------------------------------------------------------- /ui/svelte.config.js: -------------------------------------------------------------------------------- 1 | import sveltePreprocess from 'svelte-preprocess' 2 | 3 | export default { 4 | // Consult https://github.com/sveltejs/svelte-preprocess 5 | // for more information about preprocessors 6 | preprocess: sveltePreprocess() 7 | } 8 | -------------------------------------------------------------------------------- /ui/tailwind.config.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | darkmode: true, 3 | content: [ 4 | "./index.html", 5 | "./src/**/*.{svelte,js,ts,jsx,tsx}", 6 | ], 7 | theme: { 8 | extend: { 9 | colors: { 10 | primary: '#141517', 11 | secondary: '#1a1b1e', 12 | tertiary: '#24272b', 13 | accent: '#2284d9', 14 | border_primary: '#373a40', 15 | hover_secondary: '#2c2e33', 16 | } 17 | }, 18 | }, 19 | plugins: [], 20 | } 21 | -------------------------------------------------------------------------------- /ui/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@tsconfig/svelte/tsconfig.json", 3 | "compilerOptions": { 4 | "target": "esnext", 5 | "useDefineForClassFields": true, 6 | "module": "esnext", 7 | "resolveJsonModule": true, 8 | "baseUrl": ".", 9 | "paths": { 10 | "@assets/*": ["src/assets/*"], 11 | "@components/*": ["src/components/*"], 12 | "@providers/*": ["src/providers/*"], 13 | "@store/*": ["src/store/*"], 14 | "@utils/*": ["src/utils/*"], 15 | "@typings/*": ["src/typings/*"], 16 | "@layout/*": ["src/layout/*"], 17 | "@pages/*": ["src/pages/*"], 18 | }, 19 | /** 20 | * Typecheck JS in `.svelte` and `.js` files by default. 21 | * Disable checkJs if you'd like to use dynamic types in JS. 22 | * Note that setting allowJs false does not prevent the use 23 | * of JS in `.svelte` files. 24 | */ 25 | "allowJs": true, 26 | "checkJs": true 27 | }, 28 | "include": ["src/**/*.d.ts", "src/**/*.ts", "src/**/*.js", "src/**/*.svelte"] 29 | } 30 | -------------------------------------------------------------------------------- /ui/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import { svelte } from '@sveltejs/vite-plugin-svelte' 3 | import postcss from './postcss.config.js'; 4 | import { resolve } from "path"; 5 | 6 | // https://vitejs.dev/config/ 7 | export default defineConfig({ 8 | css: { 9 | postcss, 10 | }, 11 | plugins: [svelte({ 12 | /* plugin options */ 13 | })], 14 | base: './', // fivem nui needs to have local dir reference 15 | resolve: { 16 | alias: { 17 | "@assets": resolve("./src/assets"), 18 | "@components": resolve("./src/components"), 19 | "@providers": resolve("./src/providers"), 20 | "@store": resolve("./src/store"), 21 | "@utils": resolve("./src/utils"), 22 | "@typings": resolve("./src/typings"), 23 | "@layout": resolve("./src/layout"), 24 | "@pages": resolve("./src/pages"), 25 | }, 26 | }, 27 | build: { 28 | emptyOutDir: true, 29 | outDir: '../html', 30 | assetsDir: './', 31 | rollupOptions: { 32 | output: { 33 | // By not having hashes in the name, you don't have to update the manifest, yay! 34 | entryFileNames: `[name].js`, 35 | chunkFileNames: `[name].js`, 36 | assetFileNames: `[name].[ext]` 37 | } 38 | } 39 | } 40 | 41 | }) 42 | --------------------------------------------------------------------------------