1
0
Fork 0
forked from Simnation/Main
This commit is contained in:
Nordi98 2025-07-09 21:31:55 +02:00
parent 55adb0ec7f
commit 1f0a23516e
46 changed files with 2671 additions and 9 deletions

View file

@ -13,7 +13,7 @@ Config = {
Core = 'QBCORE', -- 'ESX' / 'QBCORE' | Other core setting on the 'core' folder.
VoiceSytem = 'yaca-voice', -- "pma-voice" / "mumble" / "SaltyChat"
Inventory = 'qb_inventory_new', -- 'ox_inventory' / 'qb_inventory_old'/ 'qb_inventory_new' / 'quasar_inventory' / 'chezza_inventory' / 'codem_inventory' / 'core_inventory' // Custom can be add in the cl_utils.lua!!!
Wardrobe = 'default', -- 'default' / 'ak47_clothing' / 'codem_apperance' / 'fivem_appearance' / 'illenium_appearance' / 'qb_clothing' / 'raid_clothes' / 'rcore_clothes' / 'rcore_clothing' / 'sleek_clothestore' / 'tgiann_clothing' // Custom can be add in the cl_utils.lua!!!
Wardrobe = 'illenium_appearance', -- 'default' / 'ak47_clothing' / 'codem_apperance' / 'fivem_appearance' / 'illenium_appearance' / 'qb_clothing' / 'raid_clothes' / 'rcore_clothes' / 'rcore_clothing' / 'sleek_clothestore' / 'tgiann_clothing' // Custom can be add in the cl_utils.lua!!!
TextUI = 'ox_lib', -- false / 'brutal_textui' / 'ox_lib' / 'okokTextUI' / 'ESXTextUI' / 'QBDrawText' // Custom can be add in the cl_utils.lua!!!
BrutalKeys = false, -- Buy here: https://store.brutalscripts.com
BrutalPoliceJob = false, -- Buy here: https://store.brutalscripts.com | Better connection
@ -36,14 +36,14 @@ Config = {
Blips = {
available = true,
availableHouse = {label = "Available House", size = 0.7, sprite = 40, color = 2},
availableGarage = {label = "Available Garage", size = 0.7, sprite = 357, color = 2},
availableHouse = {label = "Kaufbares Haus", size = 0.7, sprite = 40, color = 2},
availableGarage = {label = "Kaufbare Garage", size = 0.7, sprite = 357, color = 2},
owned = true,
myHouse = {label = "My House", size = 0.7, sprite = 40, color = 53},
myGarage = {label = "My Garage", size = 0.7, sprite = 357, color = 53},
hasKeyHouse = {label = "House", size = 0.7, sprite = 40, color = 53},
hasKeyGarage = {label = "House", size = 0.7, sprite = 40, color = 53},
ownedHouse = {label = "House", size = 0.7, sprite = 40, color = 1},
myHouse = {label = "Mein Haus", size = 0.7, sprite = 40, color = 53},
myGarage = {label = "Meine Garage", size = 0.7, sprite = 357, color = 53},
hasKeyHouse = {label = "Haus", size = 0.7, sprite = 40, color = 53},
hasKeyGarage = {label = "Haus", size = 0.7, sprite = 40, color = 53},
ownedHouse = {label = "Haus", size = 0.7, sprite = 40, color = 1},
ownedGarage = {label = "Garage", size = 0.7, sprite = 357, color = 1},
police = true,
burglarAlarm = {label = "Einbruch Alarm", size = 1.0, sprite = 161, color = 1},
@ -171,7 +171,7 @@ Config = {
MyProperties = {
Command = 'myproperties',
Suggestion = 'To manage your propertys',
Control = '', -- Controls list: https://docs.fivem.net/docs/game-references/input-mapper-parameter-ids/keyboard/
Control = 'F7', -- Controls list: https://docs.fivem.net/docs/game-references/input-mapper-parameter-ids/keyboard/
},
ServerDestroy = {

Binary file not shown.

View file

@ -0,0 +1 @@
Please follow the instructions: https://docs.brutalscripts.com

View file

@ -0,0 +1,85 @@
ESX = Core
QBCore = Core
-- Buy here: (4€+VAT) https://store.brutalscripts.com
function notification(title, text, time, type)
if Config.BrutalNotify then
exports['brutal_notify']:SendAlert(title, text, time, type)
else
-- Put here your own notify and set the Config.BrutalNotify to false
SetNotificationTextEntry("STRING")
AddTextComponentString(text)
DrawNotification(0,1)
-- Default ESX Notify:
--TriggerEvent('esx:showNotification', text)
-- Default QB Notify:
--TriggerEvent('QBCore:Notify', text, 'info', 5000)
-- OKOK Notify:
-- exports['okokNotify']:Alert(title, text, time, type, false)
end
end
function TextUIFunction(type, text)
if type == 'open' then
if Config.TextUI:lower() == 'ox_lib' then
lib.showTextUI(text)
elseif Config.TextUI:lower() == 'okoktextui' then
exports['okokTextUI']:Open(text, 'darkblue', 'right')
elseif Config.TextUI:lower() == 'esxtextui' then
ESX.TextUI(text)
elseif Config.TextUI:lower() == 'qbdrawtext' then
exports['qb-core']:DrawText(text,'left')
elseif Config.TextUI:lower() == 'brutal_textui' then
exports['brutal_textui']:Open(text, "blue")
end
elseif type == 'hide' then
if Config.TextUI:lower() == 'ox_lib' then
lib.hideTextUI()
elseif Config.TextUI:lower() == 'okoktextui' then
exports['okokTextUI']:Close()
elseif Config.TextUI:lower() == 'esxtextui' then
ESX.HideUI()
elseif Config.TextUI:lower() == 'qbdrawtext' then
exports['qb-core']:HideText()
elseif Config.TextUI:lower() == 'brutal_textui' then
exports['brutal_textui']:Close()
end
end
end
function PoliceAlert(coords, plate)
local x,y,z = table.unpack(coords)
local streetLabel = GetStreetNameFromHashKey(GetStreetNameAtCoord(x,y,z))
if GetResourceState("brutal_policejob") == "started" then
TriggerServerEvent('brutal_policejob:server:citizencall', 'create', "Vehicle jacking", coords, streetLabel)
end
end
function OpenMenuUtil()
InMenu = true
SetNuiFocus(true, true)
Citizen.CreateThread(function()
while InMenu do
N_0xf4f2c0d4ee209e20() -- it's disable the AFK camera zoom
Citizen.Wait(15000)
end
end)
DisplayRadar(false)
end
function DisableMinimap()
DisplayRadar(false)
-- Here you can add a trigger to hide your HUD system
end
function EnableMinimap()
DisplayRadar(true)
-- Here you can add a trigger to enable your HUD system
end

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,155 @@
----------------------------------------------------------------------------------------------
--------------------------------------| BRUTAL KEYS :) |--------------------------------------
----------------------------------------------------------------------------------------------
--[[
Hi, thank you for buying our script, We are very grateful!
For help join our Discord server: https://discord.gg/85u2u5c8q9
More informations about the script: https://docs.brutalscripts.com
--]]
Config = {
Core = 'QBCORE', -- 'ESX' / 'QBCORE' | Other core setting on the 'core' folder.
TextUI = 'ox_lib', -- false / 'brutal_textui' / 'ox_lib' / 'okokTextUI' / 'ESXTextUI' / 'QBDrawText' // Custom can be add in the cl_utils.lua!!!
BrutalNotify = true, -- Buy here: (4€+VAT) https://store.brutalscripts.com | Or set up your own notify >> cl_utils.lua
AdminGroups = {'superadmin', 'admin', 'mod', 'god'}, -- Admin groups
DataStorage = {
--[[
optimized = Saves the data when the script is restarted, the server is shut down or restarted, or during a scheduled server restart.
events: "txAdmin:events:serverShuttingDown" & "txAdmin:events:scheduledRestart" or fixed restart times.
resource_heavy = all data will be saved immediately, this is very stressful for the server so we don't recommend using this, but the choice is up to you.
]]--
Type = "optimized", -- "optimized" / "resource_heavy"
Restarts = {}, -- example: "11:59" | Save the data 1 minute before restart. Save data at 15:59 instead of 16:00
},
CopyPrice = 500, -- Key copy price
UseVehicleKeySystem = false, -- true / false | false = the full vehicle key system is switched off.
DriveWithKey = true, -- If true, players can only drive the car if they have a key, IF false, they can drive the car anytime they find it unlocked.
LockPicking = {maxTry = 1, item = "lockpick"}, -- maxTry = maximum try per vehicle | item = item or ""
Hotwiring = {maxTry = 1, successrate = 25, item = "screwdriver"}, -- maxTry = maximum try per vehicle | successrate = 10 = 10% | item = item or ""
AlertPolice = {use = true, chance = 10}, -- chance 10 = 10% | Supports Brutal Policejob basically to modity it open the cl_utils.lua file
UseKeyProp = true, -- Use the key prop in the player's hand when closing or opening a vehicle
LostVehicleKeys = {
npc = vector4(-354.5593, -128.0446, 39.4307, 65.9746), -- npc VECTOR4! coords
model = "ig_benny", -- npc type
blip = {use = true, label = "Lost Vehicle Keys", size = 1.0, sprite = 186, color = 1},
price = 2500 -- if they lost all of their keys then the price is higher
},
QuickKeys = {
['everyone'] = { -- no one needs a key to drive those vehicles
"adder", "bmx"
},
['police'] = { -- player in the job do not need a key to drive the vehicle
"police", "police2", "police3", "policeb", "pbus"
},
['ambulance'] = { -- player in the job do not need a key to drive the vehicle
"ambulance",
},
},
Commands = {
MyKeys = {
Command = 'mykeys',
Suggestion = 'To manage your keys',
Control = '', -- Controls list: https://docs.fivem.net/docs/game-references/input-mapper-parameter-ids/keyboard/
},
VehicleKey = {
Command = 'vkey',
Suggestion = 'To open the nearest vehicle',
Control = '', -- 'G' | Controls list: https://docs.fivem.net/docs/game-references/input-mapper-parameter-ids/keyboard/
},
Lockpicking = {
Command = 'lockpick',
Suggestion = 'Lockpicking the nearest vehicle',
Control = '', -- Controls list: https://docs.fivem.net/docs/game-references/input-mapper-parameter-ids/keyboard/
},
Hotwiring = {
Command = 'hotwiring',
Suggestion = 'To start the vehicle without keys',
Control = '', -- Controls list: https://docs.fivem.net/docs/game-references/input-mapper-parameter-ids/keyboard/
},
-- Admin --
StaffMode = {
Command = 'kstaff',
Suggestion = 'To switch Key System Staff mode ON/OFF',
},
AddKey = { -- /addkey [ID] [KEY-ID] [label]
Command = 'addkey',
Suggestion = 'To add key',
},
RemoveKey = { -- /removekey [ID] [KEY-ID]
Command = 'removekey',
Suggestion = 'To remove key',
},
AddVehicleKey = { -- /addvehiclekey [ID] [PLATE]
Command = 'addvehiclekey',
Suggestion = 'To add vehicle key',
},
AddVehicleTemporaryKey = { -- /addtempkey [ID] [PLATE]
Command = 'addtempkey',
Suggestion = 'To add vehicle temporary key',
},
RemoveVehicleKey = { -- /removevehiclekey [ID] [PLATE]
Command = 'removevehiclekey',
Suggestion = 'To remove vehicle key',
},
},
-----------------------------------------------------------
-----------------------| TRANSLATE |-----------------------
-----------------------------------------------------------
NUILanguage = "en", -- "en", "es", "fr", "de", "pt", "it", "pl", "nl", "ru", "tr", "hu", "ro", "cs", "sv", "ar"
MoneyForm = '$', -- Money form
Texts = {
[1] = {'[E] - Lost Key', 38, 'Open the lost key menu'},
},
-- Notify function EDITABLE >> cl_utils.lua
Notify = {
[1] = {"Keys", "Staff mode: ON", 5000, "success"},
[2] = {"Keys", "Staff mode: OFF", 5000, "error"},
[3] = {"Keys", "You got a new key!", 5000, "info"},
[4] = {"Keys", "A key has been deleted!", 5000, "success"},
[5] = {"Keys", "You gave them a key:", 5000, "info"},
[6] = {"Keys", "You copied a key!", 5000, "success"},
[7] = {"Keys", "You got a key from:", 5000, "info"},
[8] = {"Keys", "Successful lock change!", 5000, "success"},
[9] = {"Keys", "Only the vehicle owner can change!", 5000, "error"},
[10] = {"Keys", "You don't have enough money!", 5000, "error"},
[11] = {"Keys", "You have no car / you have keys to all your cars!", 5000, "error"},
[12] = {"Keys", "No vehicle near you!", 5000, "error"},
[13] = {"Keys", "The vehicle is open!", 5000, "error"},
[14] = {"Keys", "Someone is sitting in the car!", 5000, "error"},
[15] = {"Keys", "You have reached the maximum amount of keys!", 5000, "error"},
[16] = {"Keys", "This person already has a temporary key for this car!", 5000, "error"},
[17] = {"Keys", "To reduce the server load, you will have to wait a little!", 5000, "error"},
[18] = {"Keys", "Plate: 3-8 characters", 5000, "error"},
[19] = {"Keys", "Invalid Player ID!", 5000, "error"},
[20] = {"Keys", "You can't try again!", 5000, "error"},
[21] = {"Keys", "You have to sit in the driver's seat!", 5000, "error"},
[22] = {"Keys", "You did it! You've started the engine!", 5000, "success"},
[23] = {"Keys", "Unfortunately the safety lock would not let you start the engine!", 5000, "error"},
[24] = {"Keys", "You need: Lockpick", 5000, "error"},
[25] = {"Keys", "You need: Screwdriver", 5000, "error"},
},
}

View file

@ -0,0 +1,68 @@
Core = nil
if Config['Core']:upper() == 'ESX' then
local _esx_ = 'new' -- 'new' / 'old'
if _esx_ then
Core = exports['es_extended']:getSharedObject()
else
while Core == nil do
TriggerEvent('esx:getSharedObject', function(obj) Core = obj end)
Citizen.Wait(0)
end
end
LoadedEvent = 'esx:playerLoaded'
ReviveEvent = 'esx_ambulancejob:revive'
JobUpdateEvent = 'esx:setJob'
TSCB = Core.TriggerServerCallback
function GetPlayerJobDatas()
return Core.GetPlayerData().job
end
function GetPlayersFunction()
return Core.Game.GetPlayers()
end
function GetVehiclePropertiesFunction(vehicle)
return Core.Game.GetVehicleProperties(vehicle)
end
function SetVehiclePropertiesFunction(vehicle, properties)
return Core.Game.SetVehicleProperties(vehicle, properties)
end
function GetClosestVehicleFunction(coords, modelFilter)
return Core.Game.GetClosestVehicle(coords, modelFilter)
end
elseif Config['Core']:upper() == 'QBCORE' then
Core = exports['qb-core']:GetCoreObject()
LoadedEvent = 'QBCore:Client:OnPlayerLoaded'
ReviveEvent = 'hospital:client:Revive'
JobUpdateEvent = 'QBCore:Client:OnJobUpdate'
TSCB = Core.Functions.TriggerCallback
function GetPlayerJobDatas()
return Core.Functions.GetPlayerData().job
end
function GetPlayersFunction()
return Core.Functions.GetPlayers()
end
function GetVehiclePropertiesFunction(vehicle)
return Core.Functions.GetVehicleProperties(vehicle)
end
function SetVehiclePropertiesFunction(vehicle, properties)
return Core.Functions.SetVehicleProperties(vehicle, properties)
end
function GetClosestVehicleFunction(coords, modelFilter)
return Core.Functions.GetClosestVehicle(coords, modelFilter)
end
end

Binary file not shown.

View file

@ -0,0 +1,271 @@
Core = nil
if Config['Core']:upper() == 'ESX' then
local _esx_ = 'new' -- 'new' / 'old'
if _esx_ == 'new' then
Core = exports['es_extended']:getSharedObject()
else
Core = nil
TriggerEvent('esx:getSharedObject', function(obj) Core = obj end)
while Core == nil do
Citizen.Wait(0)
end
end
RESCB = Core.RegisterServerCallback
GETPFI = Core.GetPlayerFromId
RUI = Core.RegisterUsableItem
SetJobEvent = 'esx:setJob'
onPlayerDeath = 'esx:onPlayerDeath'
SQLData = {
player_vehicles = 'owned_vehicles',
}
function GetIdentifier(source)
local xPlayer = GETPFI(source)
while xPlayer == nil do
Citizen.Wait(1000)
xPlayer = GETPFI(source)
end
return xPlayer.identifier
end
function GetPlayerByIdentifier(identifier)
return Core.GetPlayerFromIdentifier(identifier)
end
function GetAccountMoney(source,account)
local xPlayer = GETPFI(source)
if account == 'bank' then
return xPlayer.getAccount(account).money
elseif account == 'money' then
return xPlayer.getMoney()
end
end
function AddMoneyFunction(source, account, amount)
local xPlayer = GETPFI(source)
if account == 'bank' then
xPlayer.addAccountMoney('bank', amount)
elseif account == 'money' then
xPlayer.addMoney(amount)
end
end
function RemoveAccountMoney(source, account, amount)
local xPlayer = GETPFI(source)
if account == 'bank' then
xPlayer.removeAccountMoney('bank', amount)
elseif account == 'money' then
xPlayer.removeMoney(amount)
end
end
function GetItemCount(source, item)
local xPlayer = GETPFI(source)
if _esx_ == 'new' then
return xPlayer.getInventoryItem(item).count
else
if string.sub(item, 0, 6):lower() == 'weapon' then
local loadoutNum, weapon = xPlayer.getWeapon(item:upper())
if weapon then
return true
else
return false
end
else
return xPlayer.getInventoryItem(item).count
end
end
end
function RemoveItem(source, item, amount)
local xPlayer = GETPFI(source)
if _esx_ == 'new' then
xPlayer.removeInventoryItem(item, amount)
else
if string.sub(item, 0, 6):lower() == 'weapon' then
xPlayer.removeWeapon(item)
else
xPlayer.removeInventoryItem(item, amount)
end
end
end
function AddItem(source, item, count, info)
local xPlayer = GETPFI(source)
if _esx_ == 'new' then
xPlayer.addInventoryItem(item, count, info)
else
if string.sub(item, 0, 6):lower() == 'weapon' then
xPlayer.addWeapon(item, 90)
else
xPlayer.addInventoryItem(item, count)
end
end
end
function GetPlayerNameFunction(source)
local name
if Config.SteamName then
name = GetPlayerName(source) or 'No Data'
else
local xPlayer = GETPFI(source)
name = xPlayer.getName() or 'No Data'
end
return name
end
function GetPlayerJob(source)
local xPlayer = GETPFI(source)
return xPlayer.job.name
end
function CreateCoreJob(name, label, grades)
Core.CreateJob(name, label, grades)
end
function SetCoreJob(source, job, grade)
local xPlayer = GETPFI(source)
xPlayer.setJob(job, grade)
end
function SetCoreJobOffline(identifier, job, grade)
MySQL.update('UPDATE users SET job = ?, job_grade = ? WHERE identifier = ?', {job, grade, identifier})
end
function GetPlayersFunction()
return Core.GetPlayers()
end
elseif Config['Core']:upper() == 'QBCORE' then
Core = exports['qb-core']:GetCoreObject()
RESCB = Core.Functions.CreateCallback
GETPFI = Core.Functions.GetPlayer
RUI = Core.Functions.CreateUseableItem
SetJobEvent = 'QBCore:Server:SetGang'
onPlayerDeath = GetResourceState("brutal_ambulancejob") == "started" and 'onPlayerDeath' or 'hospital:server:SetDeathStatus'
SQLData = {
player_vehicles = 'player_vehicles',
}
function GetIdentifier(source)
local xPlayer = GETPFI(source)
while xPlayer == nil do
Citizen.Wait(1000)
xPlayer = GETPFI(source)
end
return xPlayer.PlayerData.citizenid
end
function GetPlayerByIdentifier(identifier)
return Core.Functions.GetPlayerByCitizenId(identifier)
end
function GetAccountMoney(source, account)
local xPlayer = GETPFI(source)
if account == 'bank' then
return xPlayer.PlayerData.money.bank
elseif account == 'money' then
return xPlayer.PlayerData.money.cash
end
end
function AddMoneyFunction(source, account, amount)
local xPlayer = GETPFI(source)
if account == 'bank' then
xPlayer.Functions.AddMoney('bank', amount)
elseif account == 'money' then
xPlayer.Functions.AddMoney('cash', amount)
end
end
function RemoveAccountMoney(source, account, amount)
local xPlayer = GETPFI(source)
if account == 'bank' then
xPlayer.Functions.RemoveMoney('bank', amount)
elseif account == 'money' then
xPlayer.Functions.RemoveMoney('cash', amount)
end
end
function GetItemCount(source, item)
local xPlayer = GETPFI(source)
local items = xPlayer.Functions.GetItemByName(item)
local item_count = 0
if items ~= nil then
item_count = items.amount
else
item_count = 0
end
return item_count
end
function RemoveItem(source, item, amount)
local xPlayer = GETPFI(source)
xPlayer.Functions.RemoveItem(item, amount)
end
function AddItem(source, item, count, info)
local xPlayer = GETPFI(source)
xPlayer.Functions.AddItem(item, count, nil, info)
end
function GetPlayerNameFunction(source)
local name
if Config.SteamName then
name = GetPlayerName(source)
else
local xPlayer = GETPFI(source)
name = xPlayer.PlayerData.charinfo.firstname..' '..xPlayer.PlayerData.charinfo.lastname
end
return name
end
function GetPlayerJob(source)
local xPlayer = GETPFI(source)
return xPlayer.PlayerData.gang.name
end
function CreateCoreJob(name, label, grades)
Core.Functions.AddGang(name,
{
label = label,
grades = grades,
})
end
function UpdateCoreJob(name, label, grades)
Core.Functions.UpdateGang(name, {
label = label,
grades = grades,
})
end
function RemoveCoreJob(name)
Core.Functions.RemoveGang(name)
end
function SetCoreJob(source, job, grade)
local xPlayer = GETPFI(source)
xPlayer.Functions.SetGang(job, grade)
end
function SetCoreJobOffline(identifier, job)
local joblabel = "None"
if Gangs[job] ~= nil and Gangs[job].label ~= nil then
joblabel = Gangs[job].label
end
MySQL.update('UPDATE players SET gang = ? WHERE citizenid = ?', {json.encode({grade = {level = 0, name = "Member"}, name = job, isboss = false, label = joblabel}), identifier})
end
function GetPlayersFunction()
return Core.Functions.GetPlayers()
end
end

Binary file not shown.

View file

@ -0,0 +1,61 @@
fx_version 'cerulean'
games { 'gta5' }
lua54 'yes'
author 'Keres & Dév'
description 'Brutal Keys - store.brutalscripts.com'
version '1.0.5'
client_scripts {
'config.lua',
'core/client-core.lua',
'cl_utils.lua',
'client/*.lua'
}
server_scripts {
'@mysql-async/lib/MySQL.lua',
'config.lua',
'core/server-core.lua',
'sv_utils.lua',
'server/*.lua',
}
shared_script {
'@ox_lib/init.lua'
}
export 'addKey'
export 'removeKey'
export 'addVehicleKey'
export 'addVehicleTemporaryKey'
export 'getPlayerKey'
export 'OpenKeysMenu'
ui_page "html/index.html"
files {
"html/index.html",
"html/style.css",
"html/script.js",
"html/assets/**",
'locales/*.json',
}
dependencies {
'lockpick', -- https://github.com/baguscodestudio/lockpick
'mx_fixwiring', -- https://github.com/mxlolshop/minigameFixWiring/tree/main/Fix%20Wiring/FiveM/mx_fixwiring
'/server:5181', -- ⚠PLEASE READ⚠; Requires at least SERVER build 5181
'/gameBuild:2189', -- ⚠PLEASE READ⚠; Requires at least GAME build 2189.
}
escrow_ignore {
'config.lua',
'cl_utils.lua',
'sv_utils.lua',
'core/client-core.lua',
'core/server-core.lua',
'stream/*.ydr',
'stream/*.ytyp',
}
dependency '/assetpacks'

View file

@ -0,0 +1,3 @@
<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M79 64V79H64M1 16V1H16M16 79H1V64M64 1H79V16" stroke="white" stroke-opacity="0.3" stroke-width="2"/>
</svg>

After

Width:  |  Height:  |  Size: 213 B

View file

@ -0,0 +1,3 @@
<svg width="381" height="62" viewBox="0 0 381 62" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M380 46V61H365M1 16V1H16M16 61H1V46M365 1H380V16" stroke="white" stroke-opacity="0.67" stroke-width="2"/>
</svg>

After

Width:  |  Height:  |  Size: 220 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

View file

@ -0,0 +1,6 @@
<svg width="182" height="10" viewBox="0 0 182 10" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect x="13" width="169" height="10" fill="#79D7BE" fill-opacity="0.43"/>
<rect x="8" width="4" height="10" fill="#79D7BE"/>
<rect x="3" width="3" height="10" fill="#79D7BE"/>
<rect width="1" height="10" fill="#79D7BE"/>
</svg>

After

Width:  |  Height:  |  Size: 326 B

View file

@ -0,0 +1,5 @@
<svg width="39" height="39" viewBox="0 0 39 39" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M6 39L0 38.5V32L16 16.5L14 9L23 0L35.5 3.5L39 16L29.5 25.5L22 23.5L15.2962 30H12L12.5 33H9V36.5L6 39Z" fill="white"/>
<path d="M25 10.5C25 8.567 26.567 7 28.5 7C30.433 7 32 8.567 32 10.5C32 12.433 30.433 14 28.5 14C26.567 14 25 12.433 25 10.5Z" fill="#3E3E3E"/>
<path d="M11.5068 30.0822L11.9098 32.5H9H8.5V33V36.2658L5.83732 38.4847L0.5 38.0399V32.2118L16.3479 16.8591L16.5588 16.6548L16.4831 16.3712L14.5574 9.14971L23.1468 0.560328L35.0943 3.90565L38.4397 15.8532L29.3503 24.9426L22.1288 23.0169L21.8552 22.9439L21.6519 23.141L15.0936 29.5H12H11.4098L11.5068 30.0822ZM28.5 13.5C26.8431 13.5 25.5 12.1569 25.5 10.5C25.5 8.84315 26.8431 7.5 28.5 7.5C30.1569 7.5 31.5 8.84315 31.5 10.5C31.5 12.1569 30.1569 13.5 28.5 13.5ZM24.5 10.5C24.5 12.7091 26.2909 14.5 28.5 14.5C30.7091 14.5 32.5 12.7091 32.5 10.5C32.5 8.29086 30.7091 6.5 28.5 6.5C26.2909 6.5 24.5 8.29086 24.5 10.5Z" stroke="white"/>
</svg>

After

Width:  |  Height:  |  Size: 1,005 B

View file

@ -0,0 +1,3 @@
<svg width="27" height="27" viewBox="0 0 27 27" fill="none" xmlns="http://www.w3.org/2000/svg">
<foreignObject x="-27" y="-27" width="81.5" height="81.5"><div xmlns="http://www.w3.org/1999/xhtml" style="backdrop-filter:blur(13.75px);height:100%;width:100%"></div></foreignObject><path data-figma-bg-blur-radius="27.5" d="M2 27L2 2L27 2" stroke="white" stroke-width="3"/>
</svg>

After

Width:  |  Height:  |  Size: 378 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

View file

@ -0,0 +1,3 @@
<svg width="82" height="82" viewBox="0 0 82 82" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M80 65V80H65M2 17V2H17M17 80H2V65M65 2H80V17" stroke="white" stroke-width="4"/>
</svg>

After

Width:  |  Height:  |  Size: 192 B

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

View file

@ -0,0 +1,97 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests" />
<link rel="stylesheet" href="style.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.0/css/all.css"></link>
<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js" integrity="sha256-VazP97ZCwtekAsvgPBSUwPFKdrwD3unUfSGVYrahUqU=" crossorigin="anonymous"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-KK94CHFLLe+nY2dmCWGMq91rCGa5gtU4mk92HdvYe+M/SXH301p5ILy+dN9+nJOZ" crossorigin="anonymous">
<script src="https://unpkg.com/leaflet@1.8.0/dist/leaflet.js" integrity="sha512-BB3hKbKWOc9Ez/TAwyWxNXeoV9c1v6FIeYiBieIWkpLjauysF18NzgR1MBNBXf8/KABdlkX68nAhlwcDFLGPCQ==" crossorigin=""></script>
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.8.0/dist/leaflet.css" integrity="sha512-hoalWLoI8r4UszCkZ5kL8vayOGVae1oxXe/2A4AO6J9+580uKHDO3JdHb7NzwwzK5xr/Fs0W40kiNHxM9vyTtQ==" crossorigin=""/>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.3.0/font/bootstrap-icons.css">
<script src="https://jsuites.net/v4/jsuites.js"></script>
<script src="https://unpkg.com/@dotlottie/player-component@latest/dist/dotlottie-player.mjs" type="module"></script>
<link rel="stylesheet" href="https://jsuites.net/v4/jsuites.css" type="text/css" />
<title>Brutal Keys</title>
</head>
<body style="background: none;">
<div class="key_menu" id="key_menu">
<object id="plugin_1" type="application/x-cfx-game-view" style="position: absolute; top: 0%; left: 0%; height: 100%; width: 100%;"></object>
<div class="overflow_container">
<div class="animation_element"></div>
<div class="panel" id="key_panel">
<div class="panel_border_top"></div>
<div class="panel_border_bottom"></div>
<div class="top_line"></div>
<div class="top_box"></div>
<div class="title" data-i18n="keys"></div>
<div class="row" style="position: absolute; top: 24px; right: 25px;">
<div class="col p-0" style="position: relative;">
<button class="action_btn" id="actions_btn" onclick="CreateActionPage()" data-i18n="actions"><div class="line"></div><div class="bg"></div></button>
</div>
<div class="col" style="position: relative;">
<button class="action_btn" onclick="Close()" data-i18n="back"><div class="line"></div></button>
</div>
</div>
<div class="page_selector_container">
</div>
<div class="keys_container">
</div>
</div>
</div>
<div class="actions_section" id="actions_section">
<div class="actions_panel" id="actions_panel">
<div class="key_deleting" id="key_delete">
<div class="bg"></div>
<div class="bin"></div>
</div>
<hr>
<div class="people_container">
</div>
</div>
</div>
</div>
<div class="key_purchase_menu" id="key_purchase_menu">
<object id="plugin_2" type="application/x-cfx-game-view" style="position: absolute; top: 0%; left: 0%; height: 100%; width: 100%;"></object>
<div class="panel" id="key_purchase_panel">
<div class="panel_border_top"></div>
<div class="panel_border_bottom"></div>
<div class="top_line"></div>
<div class="top_box"></div>
<div class="title" data-i18n="buy_keys"></div>
<div class="description" data-i18n="buy_keys_des"></div>
<button class="action_btn m-4" onclick="Close()" data-i18n="back"><div class="line"></div></button>
<div class="vehicles_container">
</div>
</div>
</div>
<div class="key_notify" id="key_notify">
<div class="container">
<div class="inner">
<div class="text"></div>
<div class="line" id="line">
<div class="prog_line"></div>
</div>
</div>
</div>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-3-typeahead/4.0.2/bootstrap3-typeahead.min.js">
</script>
<script src="script.js"></script>
</html>

View file

@ -0,0 +1,637 @@
BGBlur = true
ActionsOpen = false
ChangedKeys = []
DoorNotify = false
CurrentKeyPage = 1
let translations = {};
async function loadTranslations(lang) {
try {
const response = await fetch(`../locales/${lang}.json`);
translations = await response.json();
updateText()
} catch (error) {
console.error("Error loading translation:", error);
}
}
function updateText() {
document.querySelectorAll("[data-i18n]").forEach(element => {
const key = element.getAttribute("data-i18n");
if (element.hasAttribute("placeholder")) {
element.setAttribute("placeholder", translations[key]);
} else {
element.innerHTML = translations[key];
}
});
}
function t(key) {
return translations[key] || key;
}
window.addEventListener('message', function(event) {
let data = event.data
if (data.action == "NUILanguage") {
loadTranslations(data.language);
}
else if (data.action === "OpenKeysMenu") {
MyKeys = data.mykeys
CreateKeyMenu()
BackgroundBlur("plugin_1", 'key_panel')
if (ActionsOpen){
BackgroundBlur("plugin_1", 'key_panel', true)
MakeKeysDraggable()
}
else{
BackgroundBlur("plugin_1", 'key_panel')
}
ChangedKeys = []
}
if (data.action === "OpenLostKeyMenu") {
MyVehicles = data.myvehicles
VehicleKeyPrice = data.price
Currency = data.currencyform
CreateKeyPurchaseMenu()
show('key_purchase_menu')
BackgroundBlur("plugin_2", 'key_purchase_panel')
}
if (data.action === "DoorState") {
DoorState = data.status
if (DoorState == 'unlocked'){
$(".key_notify .text").html(t('doors_unlocked'))
document.getElementById('line').classList.remove("red")
}
else{
$(".key_notify .text").html(t('doors_locked'))
document.getElementById('line').classList.add("red")
}
$('.key_notify').css('display', 'block')
$('.key_notify .container').css('animation', 'container 1s ease both')
if (DoorNotify){
clearTimeout(DoorNotify)
}
DoorNotify = setTimeout(() => {
$('.key_notify .container').css('animation', 'reverse_container 1s ease both')
setTimeout(() => {
$('.key_notify').css('display', 'none')
DoorNotify = false
}, 800);
}, 4000);
}
else if (data.action === "close") {
Close()
}
})
document.onkeydown = function(data) {
if (event.key == 'Escape') {
Close()
}
}
function Close(){
CloseKeyMenu()
hide('key_purchase_menu')
$.post('https://' + GetParentResourceName() + '/UseButton', JSON.stringify({action: "close", table:ChangedKeys}))
ChangedKeys = []
}
function CreateKeyPurchaseMenu(){
$('.vehicles_container').html('')
for (let i = 0; i < MyVehicles.length; i++) {
$('.vehicles_container').append(`
<div class="vehicle_element">
<div class="element_border"></div>
<div class="plate">${MyVehicles[i].plate}</div>
<div class="price">${VehicleKeyPrice.toLocaleString('hu-HU')+' '+Currency}</div>
<button class="action_btn" onclick="SendBuyKeyForVehicle('${MyVehicles[i].plate}')">${t('buy')}</button>
</div>
`)
}
}
function SendBuyKeyForVehicle(plate){
$.post('https://' + GetParentResourceName() + '/UseButton', JSON.stringify({action: "lostKey", plate}))
}
function CreateKeyMenu(){
$('.key_menu').css('display', 'block')
$('.key_menu .animation_element').css('animation', 'animation_element 1s ease both')
$('.key_menu .overflow_container').css('animation', 'overflow_container 1s ease both')
$('.key_menu .panel').css('animation', 'panel 1s ease both')
CreatePageSelector()
InsertDataToPanel()
}
function SendChangeLock(keyid){
$.post('https://' + GetParentResourceName() + '/UseButton', JSON.stringify({action: "changeLock", keyid, table:ChangedKeys}))
ChangedKeys = []
}
function SendCopy(keyid){
$.post('https://' + GetParentResourceName() + '/UseButton', JSON.stringify({action: "copyKey", keyid, table:ChangedKeys}))
ChangedKeys = []
}
function SendDeleteAll(keyid, plate){
$.post('https://' + GetParentResourceName() + '/UseButton', JSON.stringify({action: "deleteAll", keyid, table:ChangedKeys, plate}))
ChangedKeys = []
}
function CloseKeyMenu(){
$('.key_menu .animation_element').css('animation', 'reverse_animation_element 1s ease both')
$('.key_menu .overflow_container').css('animation', 'reverse_overflow_container 1s ease both')
$('.key_menu .panel').css('animation', 'reverse_panel 1s ease both')
if (ActionsOpen){
document.getElementById('actions_btn').classList.remove("active")
$('.key_menu .overflow_container').css('transform', 'translate(0px, -50%)')
$('.actions_section #actions_panel').css('animation', 'reverse_actions_panel 0.3s both')
MakeKeysNotDraggable()
setTimeout(() => {
ActionsOpen = false
BackgroundBlur("plugin_1", 'key_panel')
$('.actions_section').css('display', 'none')
}, 400);
}
setTimeout(() => {
$('.key_menu').css('display', 'none')
}, 700);
}
function ChooseKeyPage(element, number){
MakeKeysNotDraggable()
CurrentKeyPage = number+1
for (let i = 0; i < NumberOfPages; i++) {
document.getElementById("page_"+i).classList.remove("choosed")
}
element.classList.add("choosed")
InsertDataToPanel()
if (ActionsOpen){
MakeKeysDraggable()
}
}
function CreatePageSelector(){
BiggestSlot = 1
for (let i = 0; i < MyKeys.length; i++) {
if (MyKeys[i].slot > BiggestSlot){
BiggestSlot = MyKeys[i].slot
}
}
NumberOfPages = (BiggestSlot-(BiggestSlot%24))/24+1
$(".page_selector_container").html('')
if (NumberOfPages > 1){
for (let i = 0; i < NumberOfPages; i++) {
if (CurrentKeyPage-1 == i){
$(".page_selector_container").append(`
<div class="page_element choosed" id='page_${i}' onclick='ChooseKeyPage(this, ${i})'></div>
`)
}
else{
$(".page_selector_container").append(`
<div class="page_element" id='page_${i}' onclick='ChooseKeyPage(this, ${i})'></div>
`)
}
}
}
}
function InsertDataToPanel(){
$('.keys_container').html('')
for (let i = (CurrentKeyPage*24)-24; i < CurrentKeyPage*24; i++) {
if (MyKeys.length != 0){
for (let _i = 0; _i < MyKeys.length; _i++) {
if (MyKeys[_i] != undefined && MyKeys[_i].slot-1 == i){
let options = {year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit"};
let date = new Date(MyKeys[_i].time * 1000);
$('.keys_container').append(`
<div class="key_element">
<div class="key_border"></div>
<div class="number">${MyKeys[_i].quantity>1?MyKeys[_i].quantity:''}</div>
<div class="name">${MyKeys[_i].label}</div>
${MyKeys[_i].type == 'temporary_key'?`<div class="temporary"></div>`:''}
<div class="dropdown">
<div class="key_image ${MyKeys[_i].type == 'vehicle_key'?'vehicle':''}" type="button" data-bs-toggle="dropdown" aria-expanded="false" id="key_${i}"></div>
<ul class="dropdown-menu">
${MyKeys[_i].type != 'temporary_key'?`<li><button class="dropdown-item mb-2" onclick='SendCopy("${MyKeys[_i].id}")'>${t('copy')}</button></li>`:''}
${MyKeys[_i].type == 'vehicle_key'?`<li><button class="dropdown-item mb-2" onclick='SendChangeLock("${MyKeys[_i].id}")'>${t('change_lock')}</button></li>`:''}
<li><button class="dropdown-item" onclick='SendDeleteAll("${MyKeys[_i].id}", "${MyKeys[_i].plate}")'>${t('delete_all')}</button></li>
<div class="time">${date.toLocaleString("hu-HU", options)}</div>
</ul>
</div>
</div>
`)
break
}
else if(_i+1 == MyKeys.length){
$('.keys_container').append(`
<div class="key_element" id="empty_${i}">
<div class="key_border"></div>
</div>
`)
break
}
}
}
else{
$('.keys_container').append(`
<div class="key_element" id="empty_${i}">
<div class="key_border"></div>
</div>
`)
}
}
document.querySelectorAll(".key_image").forEach(el => {
const dropdownMenu = new bootstrap.Dropdown(el);
el.addEventListener("contextmenu", function (event) {
event.preventDefault();
document.querySelectorAll(".key_image").forEach(otherEl => {
if (otherEl !== el) {
new bootstrap.Dropdown(otherEl).hide();
}
});
dropdownMenu.show();
});
document.addEventListener("click", function () {
dropdownMenu.hide();
});
});
}
function MakeKeysDraggable(){
for (let i = (CurrentKeyPage*24)-24; i < CurrentKeyPage*24; i++) {
for (let _i = 0; _i < MyKeys.length; _i++) {
if (MyKeys[_i] != undefined && MyKeys[_i].slot-1 == i){
dragElement(document.getElementById('key_'+i), 'key_'+i, MyKeys[_i].id, _i)
}
}
}
}
function MakeKeysNotDraggable(){
for (let i = (CurrentKeyPage*24)-24; i < CurrentKeyPage*24; i++) {
for (let _i = 0; _i < MyKeys.length; _i++) {
if (MyKeys[_i] != undefined && MyKeys[_i].slot-1 == i){
document.getElementById('key_'+i).onmousedown = null
}
}
}
}
function CreateActionPage(){
if (!ActionsOpen){
ActionsOpen = true
document.getElementById('actions_btn').classList.add("active")
$('.key_menu .overflow_container').css('transform', 'translate(-100px, -50%)')
BackgroundBlur("plugin_1", 'key_panel', true)
$('#actions_panel').css('height', $('.key_menu .panel').height()+'px')
$('.actions_section #actions_panel').css('animation', 'actions_panel 0.3s ease both')
$('.actions_section').css('display', 'block')
MakeKeysDraggable()
TriggerCallback('getClosestPlayers', {}).done((cb) => {
ClosestPlayers = cb
$('.people_container').html('')
if (ClosestPlayers.length > 0){
for (let i = 0; i < ClosestPlayers.length; i++) {
$('.people_container').append(`
<div class="people_element" id='player_${i}'>
<div class="element_border"></div>
<div class="people_image"></div>
<div class="id">ID ${ClosestPlayers[i].id}</div>
</div>
`)
}
}
else{
$('.people_container').append(`
<div class="people_element">
<div class="element_border"></div>
<div class="text">x</div>
</div>
`)
}
});
}
else{
document.getElementById('actions_btn').classList.remove("active")
$('.key_menu .overflow_container').css('transform', 'translate(0px, -50%)')
$('.actions_section #actions_panel').css('animation', 'reverse_actions_panel 0.3s both')
MakeKeysNotDraggable()
setTimeout(() => {
ActionsOpen = false
BackgroundBlur("plugin_1", 'key_panel')
$('.actions_section').css('display', 'none')
}, 400);
}
}
function TriggerCallback(event, data) {
data.action = event;
return $.post('https://' + GetParentResourceName() + '/UseButton', JSON.stringify(data)).promise();
}
function BackgroundBlur(element, target, value) {
if (BGBlur){
var bodyRect = document.body.getBoundingClientRect();
let elemRect = getTotalBoundingBox(target);
if (!elemRect) return;
let offset = [];
if (value){
offset = [
(elemRect.top - bodyRect.top)-2,
((elemRect.right - bodyRect.right) * (-1))-150,
(elemRect.bottom - bodyRect.bottom)+2,
(elemRect.left - bodyRect.left)-100
];
}
else{
offset = [
(elemRect.top - bodyRect.top)-2,
((elemRect.right - bodyRect.right) * (-1))-1,
(elemRect.bottom - bodyRect.bottom)+2,
(elemRect.left - bodyRect.left)-1
];
}
$('#' + element).css('clip-path', `inset(${offset[0]}px ${offset[1]}px calc(100% - ${offset[2]}px) ${offset[3]}px)`);
}
else{
$('#' + element).css('display', 'none')
}
}
function getTotalBoundingBox(target) {
const elem = document.getElementById(target);
if (!elem) return null;
let elemRect = elem.getBoundingClientRect();
let minX = elemRect.left;
let minY = elemRect.top;
let maxX = elemRect.right;
let maxY = elemRect.bottom;
Array.from(elem.children).forEach(child => {
let childRect = child.getBoundingClientRect();
minX = Math.min(minX, childRect.left!=0?childRect.left:99999);
minY = Math.min(minY, childRect.top!=0?childRect.top:99999);
maxX = Math.max(maxX, childRect.right);
maxY = Math.max(maxY, childRect.bottom);
});
return {
width: maxX - minX,
height: maxY - minY,
left: minX,
top: minY,
right: maxX,
bottom: maxY
};
}
function show(element) {
$("#" + element).css("display", "block")
document.getElementById(element).style.animation = "showmenu 0.35s ease";
}
function hide(element) {
document.getElementById(element).style.animation = "hidemenu 0.3s ease";
setTimeout(function() {
$("#" + element).css("display", "none")
}, 300)
}
function isNumber(evt) {
evt = (evt) ? evt : window.event
var charCode = (evt.which) ? evt.which : evt.keyCode
if (charCode > 31 && (charCode < 48 || charCode > 57)) {
return false
}
return true
}
////////////////////////////////////////////// DRAGGING //////////////////////////////////////////////////
OGPos = {}
function dragElement(elmnt, item, keyid, index) {
var pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
if (OGPos[item] == null){
OGPos[item] = { x: null, y: null }
OGPos[item].x = elmnt.offsetLeft
OGPos[item].y = elmnt.offsetTop
}
elmnt.onmousedown = dragMouseDown
function dragMouseDown(e) {
e = e || window.event;
e.preventDefault();
pos3 = e.clientX;
pos4 = e.clientY;
document.onmouseup = closeDragElement;
document.onmousemove = elementDrag;
}
function elementDrag(e) {
e = e || window.event
e.preventDefault()
pos1 = pos3 - e.clientX
pos2 = pos4 - e.clientY
pos3 = e.clientX
pos4 = e.clientY
elmnt.style.opacity = "0.8"
elmnt.style.top = (elmnt.offsetTop - pos2) + "px"
elmnt.style.left = (elmnt.offsetLeft - pos1) + "px"
if (elementsOverlap(elmnt, document.getElementById("key_panel"), true) == false && elementsOverlap(elmnt, document.getElementById("actions_panel")) == false){
closeDragElement(e)
}
for (let i = (CurrentKeyPage*24)-24; i < CurrentKeyPage*24; i++) {
if (document.getElementById("empty_"+i) != undefined){
if (elementsOverlapPrecise(document.getElementById("empty_"+i), e.clientX, e.clientY) == false){
document.getElementById('empty_'+i).classList.remove("hovered")
}
else{
document.getElementById('empty_'+i).classList.add("hovered")
}
}
}
for (let i = 0; i < ClosestPlayers.length; i++) {
if (elementsOverlapPrecise(document.getElementById("player_"+i), e.clientX, e.clientY) == false){
document.getElementById('player_'+i).classList.remove("hovered")
}
else{
document.getElementById('player_'+i).classList.add("hovered")
}
}
if (elementsOverlapPrecise(document.getElementById("key_delete"), e.clientX, e.clientY) == false){
document.getElementById('key_delete').classList.remove("hovered")
}
else{
document.getElementById('key_delete').classList.add("hovered")
}
}
function closeDragElement(e) {
UseElement(elmnt, item, e.clientX, e.clientY, keyid, index)
elmnt.style.opacity = "1"
document.onmouseup = null;
document.onmousemove = null;
}
}
function UseElement(elmnt, item, X, Y, keyid, index){
let elm = elmnt
for (let i = (CurrentKeyPage*24)-24; i < CurrentKeyPage*24; i++) {
if (document.getElementById("empty_"+i) != undefined){
if (elementsOverlapPrecise(document.getElementById("empty_"+i), X, Y) == false){
document.getElementById('empty_'+i).classList.remove("hovered")
}
else{
for (const key in ChangedKeys) {
if (ChangedKeys[key].keyid == keyid){
ChangedKeys.splice(key, 1)
}
}
for (const key in MyKeys) {
if (MyKeys[key].id == keyid){
if (MyKeys[key].oldSlot == undefined || MyKeys[key].oldSlot != i+1){
ChangedKeys.push({keyid: keyid, slot:i+1, plate:MyKeys[key].plate})
break
}
}
}
MakeKeysNotDraggable()
if (MyKeys[index].oldSlot == undefined){
MyKeys[index].oldSlot = MyKeys[index].slot
}
MyKeys[index].slot = i+1
InsertDataToPanel()
MakeKeysDraggable()
return
}
}
}
for (let i = 0; i < ClosestPlayers.length; i++) {
if (elementsOverlapPrecise(document.getElementById("player_"+i), X, Y)){
$.post('https://' + GetParentResourceName() + '/UseButton', JSON.stringify({action: "giveKey", playerid:ClosestPlayers[i].id, keyid, table:ChangedKeys}))
document.getElementById('player_'+i).classList.remove("hovered")
ChangedKeys = []
return
}
}
if (elementsOverlapPrecise(document.getElementById("key_delete"), X, Y)){
$.post('https://' + GetParentResourceName() + '/UseButton', JSON.stringify({action: "deleteKey", keyid, table:ChangedKeys, plate:MyKeys[index].plate}))
document.getElementById('key_delete').classList.remove("hovered")
ChangedKeys = []
return
}
/* if (elementsOverlap(elm, document.getElementById("head_box")) && Damages.head){
ItemAnim(elm, item)
}
else if(elementsOverlap(elm, document.getElementById("head_box")) && Damages.head == false){
WrongItemAnim(elm, item)
}
else{
elm.style.top = OGPos[item].y + "px"
elm.style.left = OGPos[item].x + "px"
}*/
elm.style.top = OGPos[item].y + "px"
elm.style.left = OGPos[item].x + "px"
}
function ItemAnim(elm, item, part){
elm.style.animation = 'none';
elm.offsetHeight;
elm.style.animation = "itemuseanim 1.2s";
setTimeout(function(){
elm.style.top = OGPos[item].y + "px"
elm.style.left = OGPos[item].x + "px"
elm.style.animation = 'none';
Close()
},1200)
$.post('https://'+GetParentResourceName()+'/UseButton', JSON.stringify({action:"MedicerMenu", type:"useitem", item, you:Mediceryou, part}))
}
function WrongItemAnim(elm, item){
elm.style.animation = 'none';
elm.offsetHeight;
elm.style.animation = "itemnotuseanim 0.8s";
setTimeout(function(){
elm.style.top = OGPos[item].y + "px"
elm.style.left = OGPos[item].x + "px"
elm.style.animation = 'none';
},800)
}
function elementsOverlap(el1, el2, value) {
const domRect1 = el1.getBoundingClientRect();
const domRect2 = el2.getBoundingClientRect();
if (value){
return !(
domRect1.top+50 > domRect2.bottom ||
domRect1.right-50 < domRect2.left ||
domRect1.bottom-50 < domRect2.top ||
domRect1.left-50 > domRect2.right
);
}
else{
return !(
domRect1.top+50 > domRect2.bottom ||
domRect1.right-50 < domRect2.left ||
domRect1.bottom-50 < domRect2.top ||
domRect1.left+50 > domRect2.right
);
}
}
function elementsOverlapPrecise(el1, X, Y) {
const domRect1 = el1.getBoundingClientRect();
return !(
domRect1.top > Y ||
domRect1.right < X ||
domRect1.bottom < Y ||
domRect1.left > X
);
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,13 @@
{
"keys": "مفتاح",
"actions": "الإجراءات<div class='line'></div><div class='bg'></div>",
"back": "رجوع<div class='line'></div>",
"buy_keys": "شراء مفتاح",
"buy_keys_des": "هنا يمكنك شراء مفتاح جديد إذا فقدت جميع المفاتيح.",
"doors_unlocked": "الباب مفتوح",
"doors_locked": "الباب مغلق",
"buy": "شراء",
"copy": "نسخ",
"change_lock": "تغيير القفل",
"delete_all": "حذف الكل"
}

View file

@ -0,0 +1,13 @@
{
"keys": "KLÍČ",
"actions": "AKCE<div class='line'></div><div class='bg'></div>",
"back": "ZPĚT<div class='line'></div>",
"buy_keys": "KOUPIT KLÍČ",
"buy_keys_des": "Zde si můžeš koupit nový klíč, pokud jsi všechny ztratil.",
"doors_unlocked": "DVEŘE OTEVŘENÉ",
"doors_locked": "DVEŘE ZAVŘENÉ",
"buy": "KOUPIT",
"copy": "KOPÍROVAT",
"change_lock": "ZMĚNIT ZÁMEK",
"delete_all": "SMAZAT VŠE"
}

View file

@ -0,0 +1,13 @@
{
"keys": "SCHLUSS",
"actions": "AKTIONEN<div class='line'></div><div class='bg'></div>",
"back": "ZURUCK<div class='line'></div>",
"buy_keys": "KAUF SCHLUSS",
"buy_keys_des": "Hier kannst du einen neuen Schluss kaufen, wenn alle verloren sind.",
"doors_unlocked": "TUR OFFEN",
"doors_locked": "TUR ZU",
"buy": "KAUFEN",
"copy": "KOPIEREN",
"change_lock": "SCHLOSS WECHSEL",
"delete_all": "ALLES LOSCHEN"
}

Binary file not shown.

View file

@ -0,0 +1,13 @@
{
"keys": "KEYS",
"actions": "ACTIONS<div class='line'></div><div class='bg'></div>",
"back": "BACK<div class='line'></div>",
"buy_keys": "BUY KEYS",
"buy_keys_des": "Here you can buy keys for your vehicles if you have managed to lose all of them.",
"doors_unlocked": "DOORS UNLOCKED",
"doors_locked": "DOORS LOCKED",
"buy": "BUY",
"copy": "COPY",
"change_lock": "CHANGE LOCK",
"delete_all": "DELETE ALL"
}

View file

@ -0,0 +1,13 @@
{
"keys": "CLE",
"actions": "ACTIONS<div class='line'></div><div class='bg'></div>",
"back": "RETOUR<div class='line'></div>",
"buy_keys": "ACHAT CLE",
"buy_keys_des": "Ici, tu peux acheter une nouvelle cle si toutes sont perdues.",
"doors_unlocked": "PORTE OUVERTE",
"doors_locked": "PORTE FERME",
"buy": "ACHETER",
"copy": "COPIER",
"change_lock": "CHANGER SERRURE",
"delete_all": "SUPPRIMER TOUT"
}

View file

@ -0,0 +1,13 @@
{
"keys": "KULCS",
"actions": "MŰVELETEK<div class='line'></div><div class='bg'></div>",
"back": "VISSZA<div class='line'></div>",
"buy_keys": "VÁSÁRLÁS",
"buy_keys_des": "Itt vásárolhatsz kulcsokat a járműveidhez, ha az összeset elvesztetted.",
"doors_unlocked": "AJTÓK NYITVA",
"doors_locked": "AJTÓK ZÁRVA",
"buy": "VÁSÁRLÁS",
"copy": "MÁSOLÁS",
"change_lock": "ZÁRCSERE",
"delete_all": "ÖSSZES TÖRLÉSE"
}

View file

@ -0,0 +1,13 @@
{
"keys": "CHIAVE",
"actions": "AZIONI<div class='line'></div><div class='bg'></div>",
"back": "INDIETRO<div class='line'></div>",
"buy_keys": "COMPRA CHIAVE",
"buy_keys_des": "Qui puoi comprare una nuova chiave se le hai perse tutte.",
"doors_unlocked": "PORTA APERTA",
"doors_locked": "PORTA CHIUSA",
"buy": "COMPRA",
"copy": "COPIA",
"change_lock": "CAMBIA SERRATURA",
"delete_all": "ELIMINA TUTTO"
}

View file

@ -0,0 +1,13 @@
{
"keys": "SLEUTEL",
"actions": "ACTIES<div class='line'></div><div class='bg'></div>",
"back": "TERUG<div class='line'></div>",
"buy_keys": "KOOP SLEUTEL",
"buy_keys_des": "Hier kun je een nieuwe sleutel kopen als je alles kwijt bent.",
"doors_unlocked": "DEUR OPEN",
"doors_locked": "DEUR DICHT",
"buy": "KOPEN",
"copy": "KOPIEREN",
"change_lock": "VERVANG SLOT",
"delete_all": "VERWIJDER ALLES"
}

View file

@ -0,0 +1,13 @@
{
"keys": "KLUCZ",
"actions": "AKCJE<div class='line'></div><div class='bg'></div>",
"back": "WSTECZ<div class='line'></div>",
"buy_keys": "KUP KLUCZ",
"buy_keys_des": "Tutaj mozesz kupic nowy klucz, jesli zgubiles wszystkie.",
"doors_unlocked": "DRZWI OTWARTE",
"doors_locked": "DRZWI ZAMKNIETE",
"buy": "KUP",
"copy": "KOPIUJ",
"change_lock": "ZMIEN ZAMEK",
"delete_all": "USUN WSZYSTKO"
}

View file

@ -0,0 +1,13 @@
{
"keys": "CHAVE",
"actions": "ACOES<div class='line'></div><div class='bg'></div>",
"back": "VOLTAR<div class='line'></div>",
"buy_keys": "COMPRAR CHAVE",
"buy_keys_des": "Aqui voce pode comprar uma nova chave se perdeu todas.",
"doors_unlocked": "PORTA ABERTA",
"doors_locked": "PORTA FECHADA",
"buy": "COMPRAR",
"copy": "COPIAR",
"change_lock": "TROCAR FECHADURA",
"delete_all": "APAGAR TUDO"
}

View file

@ -0,0 +1,13 @@
{
"keys": "CHEIE",
"actions": "ACȚIUNI<div class='line'></div><div class='bg'></div>",
"back": "ÎNAPOI<div class='line'></div>",
"buy_keys": "CUMPĂRĂ CHEIE",
"buy_keys_des": "Aici poți cumpăra o nouă cheie dacă le-ai pierdut pe toate.",
"doors_unlocked": "UȘA DESCHISĂ",
"doors_locked": "UȘA ÎNCHISĂ",
"buy": "CUMPĂRĂ",
"copy": "COPIAZĂ",
"change_lock": "SCHIMBĂ LACĂTUL",
"delete_all": "ȘTERGE TOT"
}

View file

@ -0,0 +1,13 @@
{
"keys": "КЛЮЧ",
"actions": "ДЕЙСТВИЯ<div class='line'></div><div class='bg'></div>",
"back": "НАЗАД<div class='line'></div>",
"buy_keys": "КУПИТЬ КЛЮЧ",
"buy_keys_des": "Здесь можно купить новый ключ, если все потеряны.",
"doors_unlocked": "ДВЕРЬ ОТКРЫТА",
"doors_locked": "ДВЕРЬ ЗАКРЫТА",
"buy": "КУПИТЬ",
"copy": "КОПИРОВАТЬ",
"change_lock": "СМЕНИТЬ ЗАМОК",
"delete_all": "УДАЛИТЬ ВСЕ"
}

View file

@ -0,0 +1,13 @@
{
"keys": "LLAVE",
"actions": "ACCIONES<div class='line'></div><div class='bg'></div>",
"back": "ATRAS<div class='line'></div>",
"buy_keys": "COMPRAR LLAVE",
"buy_keys_des": "Aqui puedes comprar una nueva llave si perdiste todas.",
"doors_unlocked": "PUERTA ABIERTA",
"doors_locked": "PUERTA CERRADA",
"buy": "COMPRAR",
"copy": "COPIAR",
"change_lock": "CAMBIO CERRADURA",
"delete_all": "BORRAR TODO"
}

View file

@ -0,0 +1,13 @@
{
"keys": "NYCKEL",
"actions": "ÅTGÄRDER<div class='line'></div><div class='bg'></div>",
"back": "TILLBAKA<div class='line'></div>",
"buy_keys": "KÖP NYCKEL",
"buy_keys_des": "Här kan du köpa en ny nyckel om du har tappat alla.",
"doors_unlocked": "DÖRR ÖPPEN",
"doors_locked": "DÖRR LÅST",
"buy": "KÖP",
"copy": "KOPIERA",
"change_lock": "BYT LÅS",
"delete_all": "RADERA ALLT"
}

View file

@ -0,0 +1,13 @@
{
"keys": "ANAHTAR",
"actions": "EYLEMLER<div class='line'></div><div class='bg'></div>",
"back": "GERI<div class='line'></div>",
"buy_keys": "ANAHTAR AL",
"buy_keys_des": "Buradan tum anahtarlarini kaybettiysen yeni bir tane alabilirsin.",
"doors_unlocked": "KAPI ACIK",
"doors_locked": "KAPI KAPALI",
"buy": "AL",
"copy": "KOPYALA",
"change_lock": "KILIT DEGISTIR",
"delete_all": "HEPSINI SIL"
}

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,25 @@
function StaffCheck(source)
local staff = false
if Config.Core:upper() == 'ESX'then
local player = Core.GetPlayerFromId(source)
local playerGroup = player.getGroup()
for i, Group in ipairs(Config.AdminGroups) do
if playerGroup == Group then
staff = true
break
end
end
elseif Config.Core:upper() == 'QBCORE' then
for i, Group in ipairs(Config.AdminGroups) do
if Core.Functions.HasPermission(source, Group) or IsPlayerAceAllowed(source, Group) or IsPlayerAceAllowed(source, 'command') then
staff = true
break
end
end
end
return staff
end