mirror of
https://github.com/esx-framework/esx_core.git
synced 2026-08-29 01:08:54 +00:00
Merge branch 'dev' into patch-4
This commit is contained in:
@@ -389,6 +389,7 @@ CREATE TABLE `users` (
|
||||
`job` varchar(20) DEFAULT 'unemployed',
|
||||
`job_grade` int(11) DEFAULT 0,
|
||||
`loadout` longtext DEFAULT NULL,
|
||||
`meta` LONGTEXT NULL DEFAULT NULL,
|
||||
`position` longtext NULL DEFAULT NULL,
|
||||
`firstname` varchar(16) DEFAULT NULL,
|
||||
`lastname` varchar(16) DEFAULT NULL,
|
||||
|
||||
@@ -4,6 +4,6 @@ game 'gta5'
|
||||
author 'ESX-Framework'
|
||||
description 'cron'
|
||||
lua54 'yes'
|
||||
version '1.9.3'
|
||||
version '1.9.4'
|
||||
|
||||
server_script 'server/main.lua'
|
||||
|
||||
@@ -2,8 +2,6 @@ ESX = {}
|
||||
Core = {}
|
||||
ESX.PlayerData = {}
|
||||
ESX.PlayerLoaded = false
|
||||
Core.CurrentRequestId = 0
|
||||
Core.ServerCallbacks = {}
|
||||
Core.Input = {}
|
||||
ESX.UI = {}
|
||||
ESX.UI.Menu = {}
|
||||
@@ -187,14 +185,6 @@ ESX.RegisterInput = function(command_name, label, input_group, key, on_press, on
|
||||
RegisterKeyMapping(on_release ~= nil and "+" .. command_name or command_name, label, input_group, key)
|
||||
end
|
||||
|
||||
function ESX.TriggerServerCallback(name, cb, ...)
|
||||
local Invoke = GetInvokingResource() or "unknown"
|
||||
Core.ServerCallbacks[Core.CurrentRequestId] = cb
|
||||
|
||||
TriggerServerEvent('esx:triggerServerCallback', name, Core.CurrentRequestId,Invoke, ...)
|
||||
Core.CurrentRequestId = Core.CurrentRequestId < 65535 and Core.CurrentRequestId + 1 or 0
|
||||
end
|
||||
|
||||
function ESX.UI.Menu.RegisterType(type, open, close)
|
||||
ESX.UI.Menu.RegisteredTypes[type] = {
|
||||
open = open,
|
||||
@@ -367,7 +357,7 @@ function ESX.Game.Teleport(entity, coords, cb)
|
||||
end
|
||||
|
||||
function ESX.Game.SpawnObject(object, coords, cb, networked)
|
||||
networked = networked == nil and true or networked
|
||||
networked = networked or true
|
||||
if networked then
|
||||
ESX.TriggerServerCallback('esx:Onesync:SpawnObject', function(NetworkID)
|
||||
if cb then
|
||||
@@ -415,7 +405,16 @@ end
|
||||
function ESX.Game.SpawnVehicle(vehicle, coords, heading, cb, networked)
|
||||
local model = type(vehicle) == 'number' and vehicle or joaat(vehicle)
|
||||
local vector = type(coords) == "vector3" and coords or vec(coords.x, coords.y, coords.z)
|
||||
networked = networked == nil and true or networked
|
||||
networked = networked or true
|
||||
local playerCoords = GetEntityCoords(ESX.PlayerData.ped)
|
||||
if not vector or not playerCoords then
|
||||
return
|
||||
end
|
||||
local dist = #(playerCoords - vector)
|
||||
if dist > 424 then -- Onesync infinity Range (https://docs.fivem.net/docs/scripting-reference/onesync/)
|
||||
local executingResource = GetInvokingResource() or "Unknown"
|
||||
return print(("[^1ERROR^7] Resource ^5%s^7 Tried to spawn vehicle on the client but the position is too far away (Out of onesync range)."):format(executing_resource))
|
||||
end
|
||||
CreateThread(function()
|
||||
ESX.Streaming.RequestModel(model)
|
||||
|
||||
@@ -1304,15 +1303,6 @@ function ESX.ShowInventory()
|
||||
end)
|
||||
end
|
||||
|
||||
RegisterNetEvent('esx:serverCallback', function(requestId,invoker, ...)
|
||||
if Core.ServerCallbacks[requestId] then
|
||||
Core.ServerCallbacks[requestId](...)
|
||||
Core.ServerCallbacks[requestId] = nil
|
||||
else
|
||||
print('[^1ERROR^7] Server Callback with requestId ^5'.. requestId ..'^7 Was Called by ^5'.. invoker .. '^7 but does not exist.')
|
||||
end
|
||||
end)
|
||||
|
||||
RegisterNetEvent('esx:showNotification')
|
||||
AddEventHandler('esx:showNotification', function(msg, type, length)
|
||||
ESX.ShowNotification(msg, type, length)
|
||||
@@ -1327,4 +1317,27 @@ AddEventHandler('esx:showAdvancedNotification',
|
||||
RegisterNetEvent('esx:showHelpNotification')
|
||||
AddEventHandler('esx:showHelpNotification', function(msg, thisFrame, beep, duration)
|
||||
ESX.ShowHelpNotification(msg, thisFrame, beep, duration)
|
||||
end)
|
||||
end)
|
||||
|
||||
---@param model number|string
|
||||
---@return string
|
||||
function ESX.GetVehicleType(model)
|
||||
model = type(model) == 'string' and joaat(model) or model
|
||||
|
||||
if model == `submersible` or model == `submersible2` then
|
||||
return 'submarine'
|
||||
end
|
||||
|
||||
local vehicleType = GetVehicleClassFromName(model)
|
||||
local types = {
|
||||
[8] = "bike",
|
||||
[11] = "trailer",
|
||||
[13] = "bike",
|
||||
[14] = "boat",
|
||||
[15] = "heli",
|
||||
[16] = "plane",
|
||||
[21] = "train",
|
||||
}
|
||||
|
||||
return types[vehicleType] or "automobile"
|
||||
end
|
||||
@@ -2,7 +2,8 @@ local pickups = {}
|
||||
|
||||
CreateThread(function()
|
||||
while not Config.Multichar do
|
||||
Wait(0)
|
||||
Wait(100)
|
||||
|
||||
if NetworkIsPlayerActive(PlayerId()) then
|
||||
exports.spawnmanager:setAutoSpawn(false)
|
||||
DoScreenFadeOut(0)
|
||||
@@ -101,6 +102,74 @@ AddEventHandler('esx:playerLoaded', function(xPlayer, isNew, skin)
|
||||
end)
|
||||
end
|
||||
|
||||
-- Disable Dispatch services
|
||||
if Config.DisableDispatchServices then
|
||||
for i = 1, 15 do
|
||||
EnableDispatchService(i, false)
|
||||
end
|
||||
end
|
||||
|
||||
-- Disable Scenarios
|
||||
if Config.DisableScenarios then
|
||||
local scenarios = {
|
||||
'WORLD_VEHICLE_ATTRACTOR',
|
||||
'WORLD_VEHICLE_AMBULANCE',
|
||||
'WORLD_VEHICLE_BICYCLE_BMX',
|
||||
'WORLD_VEHICLE_BICYCLE_BMX_BALLAS',
|
||||
'WORLD_VEHICLE_BICYCLE_BMX_FAMILY',
|
||||
'WORLD_VEHICLE_BICYCLE_BMX_HARMONY',
|
||||
'WORLD_VEHICLE_BICYCLE_BMX_VAGOS',
|
||||
'WORLD_VEHICLE_BICYCLE_MOUNTAIN',
|
||||
'WORLD_VEHICLE_BICYCLE_ROAD',
|
||||
'WORLD_VEHICLE_BIKE_OFF_ROAD_RACE',
|
||||
'WORLD_VEHICLE_BIKER',
|
||||
'WORLD_VEHICLE_BOAT_IDLE',
|
||||
'WORLD_VEHICLE_BOAT_IDLE_ALAMO',
|
||||
'WORLD_VEHICLE_BOAT_IDLE_MARQUIS',
|
||||
'WORLD_VEHICLE_BOAT_IDLE_MARQUIS',
|
||||
'WORLD_VEHICLE_BROKEN_DOWN',
|
||||
'WORLD_VEHICLE_BUSINESSMEN',
|
||||
'WORLD_VEHICLE_HELI_LIFEGUARD',
|
||||
'WORLD_VEHICLE_CLUCKIN_BELL_TRAILER',
|
||||
'WORLD_VEHICLE_CONSTRUCTION_SOLO',
|
||||
'WORLD_VEHICLE_CONSTRUCTION_PASSENGERS',
|
||||
'WORLD_VEHICLE_DRIVE_PASSENGERS',
|
||||
'WORLD_VEHICLE_DRIVE_PASSENGERS_LIMITED',
|
||||
'WORLD_VEHICLE_DRIVE_SOLO',
|
||||
'WORLD_VEHICLE_FIRE_TRUCK',
|
||||
'WORLD_VEHICLE_EMPTY',
|
||||
'WORLD_VEHICLE_MARIACHI',
|
||||
'WORLD_VEHICLE_MECHANIC',
|
||||
'WORLD_VEHICLE_MILITARY_PLANES_BIG',
|
||||
'WORLD_VEHICLE_MILITARY_PLANES_SMALL',
|
||||
'WORLD_VEHICLE_PARK_PARALLEL',
|
||||
'WORLD_VEHICLE_PARK_PERPENDICULAR_NOSE_IN',
|
||||
'WORLD_VEHICLE_PASSENGER_EXIT',
|
||||
'WORLD_VEHICLE_POLICE_BIKE',
|
||||
'WORLD_VEHICLE_POLICE_CAR',
|
||||
'WORLD_VEHICLE_POLICE',
|
||||
'WORLD_VEHICLE_POLICE_NEXT_TO_CAR',
|
||||
'WORLD_VEHICLE_QUARRY',
|
||||
'WORLD_VEHICLE_SALTON',
|
||||
'WORLD_VEHICLE_SALTON_DIRT_BIKE',
|
||||
'WORLD_VEHICLE_SECURITY_CAR',
|
||||
'WORLD_VEHICLE_STREETRACE',
|
||||
'WORLD_VEHICLE_TOURBUS',
|
||||
'WORLD_VEHICLE_TOURIST',
|
||||
'WORLD_VEHICLE_TANDL',
|
||||
'WORLD_VEHICLE_TRACTOR',
|
||||
'WORLD_VEHICLE_TRACTOR_BEACH',
|
||||
'WORLD_VEHICLE_TRUCK_LOGS',
|
||||
'WORLD_VEHICLE_TRUCKS_TRAILERS',
|
||||
'WORLD_VEHICLE_DISTANT_EMPTY_GROUND',
|
||||
'WORLD_HUMAN_PAPARAZZI'
|
||||
}
|
||||
|
||||
for i, v in pairs(scenarios) do
|
||||
SetScenarioTypeEnabled(v, false)
|
||||
end
|
||||
end
|
||||
|
||||
SetDefaultVehicleNumberPlateTextPattern(-1, Config.CustomAIPlates)
|
||||
StartServerSyncLoops()
|
||||
end)
|
||||
@@ -607,27 +676,8 @@ AddEventHandler("esx:freezePlayer", function(input)
|
||||
end
|
||||
end)
|
||||
|
||||
RegisterNetEvent("esx:GetVehicleType", function(Model, Request)
|
||||
if not IsModelInCdimage(Model) then
|
||||
return TriggerServerEvent("esx:ReturnVehicleType", false, Request)
|
||||
end
|
||||
|
||||
if Model == `submersible` or Model == `submersible2` then
|
||||
return TriggerServerEvent("esx:ReturnVehicleType", "submarine", Request)
|
||||
end
|
||||
|
||||
local VehicleType = GetVehicleClassFromName(Model)
|
||||
local types = {
|
||||
[8] = "bike",
|
||||
[11] = "trailer",
|
||||
[13] = "bike",
|
||||
[14] = "boat",
|
||||
[15] = "heli",
|
||||
[16] = "plane",
|
||||
[21] = "train",
|
||||
}
|
||||
|
||||
TriggerServerEvent("esx:ReturnVehicleType", types[VehicleType] or "automobile", Request)
|
||||
ESX.RegisterClientCallback("esx:GetVehicleType", function(cb, model)
|
||||
cb(ESX.GetVehicleType(model))
|
||||
end)
|
||||
|
||||
local DoNotUse = {
|
||||
@@ -646,3 +696,7 @@ for i = 1, #DoNotUse do
|
||||
print("[^1ERROR^7] YOU ARE USING A RESOURCE THAT WILL BREAK ^1ESX^7, PLEASE REMOVE ^5" .. DoNotUse[i] .. "^7")
|
||||
end
|
||||
end
|
||||
|
||||
RegisterNetEvent('esx:updatePlayerData', function(key, val)
|
||||
ESX.SetPlayerData(key, val)
|
||||
end)
|
||||
@@ -72,6 +72,12 @@ CreateThread(function()
|
||||
current.displayName, current.netId = GetData(current.vehicle)
|
||||
TriggerEvent('esx:enteredVehicle', current.vehicle, current.plate, current.seat, current.displayName, current.netId)
|
||||
TriggerServerEvent('esx:enteredVehicle', current.plate, current.seat, current.displayName, current.netId)
|
||||
if Config.DisableVehicleSeatShuff then
|
||||
if current.seat == 0 then
|
||||
SetPedIntoVehicle(playerPed, current.vehicle, 0)
|
||||
SetPedConfigFlag(playerPed, 184, true)
|
||||
end
|
||||
end
|
||||
end
|
||||
elseif isInVehicle then
|
||||
if not IsPedInAnyVehicle(playerPed, false) or IsPlayerDead(PlayerId()) then
|
||||
@@ -112,4 +118,4 @@ if Config.EnableDebug then
|
||||
print('esx:exitedVehicle', 'vehicle', vehicle, 'plate', plate, 'seat', seat, 'displayName', displayName, 'netId', netId)
|
||||
end)
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
local RequestId = 0
|
||||
local serverRequests = {}
|
||||
|
||||
local clientCallbacks = {}
|
||||
|
||||
---@param eventName string
|
||||
---@param callback function
|
||||
---@param ... any
|
||||
ESX.TriggerServerCallback = function(eventName, callback, ...)
|
||||
serverRequests[RequestId] = callback
|
||||
|
||||
TriggerServerEvent('esx:triggerServerCallback', eventName, RequestId, GetInvokingResource() or "unknown", ...)
|
||||
|
||||
RequestId = RequestId + 1
|
||||
end
|
||||
|
||||
RegisterNetEvent('esx:serverCallback', function(requestId, invoker, ...)
|
||||
if not serverRequests[requestId] then
|
||||
return print(('[^1ERROR^7] Server Callback with requestId ^5%s^7 Was Called by ^5%s^7 but does not exist.'):format(requestId, invoker))
|
||||
end
|
||||
|
||||
serverRequests[requestId](...)
|
||||
serverRequests[requestId] = nil
|
||||
end)
|
||||
|
||||
---@param eventName string
|
||||
---@param callback function
|
||||
ESX.RegisterClientCallback = function(eventName, callback)
|
||||
clientCallbacks[eventName] = callback
|
||||
end
|
||||
|
||||
RegisterNetEvent('esx:triggerClientCallback', function(eventName, requestId, invoker, ...)
|
||||
if not clientCallbacks[eventName] then
|
||||
return print(('[^1ERROR^7] Client Callback not registered, name: ^5%s^7, invoker resource: ^5%s^7'):format(eventName, invoker))
|
||||
end
|
||||
|
||||
clientCallbacks[eventName](function(...)
|
||||
TriggerServerEvent('esx:clientCallback', requestId, invoker, ...)
|
||||
end, ...)
|
||||
end)
|
||||
@@ -133,6 +133,25 @@ function ESX.Table.Join(t, sep)
|
||||
return str
|
||||
end
|
||||
|
||||
-- Credits: https://github.com/JonasDev99/qb-garages/blob/b0335d67cb72a6b9ac60f62a87fb3946f5c2f33d/server/main.lua#L5
|
||||
function ESX.Table.TableContains(tab, val)
|
||||
if type(val) == "table" then
|
||||
for _, value in pairs(tab) do
|
||||
if ESX.Table.TableContains(val, value) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
else
|
||||
for _, value in pairs(tab) do
|
||||
if value == val then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
-- Credit: https://stackoverflow.com/a/15706820
|
||||
-- Description: sort function for pairs
|
||||
function ESX.Table.Sort(t, order)
|
||||
@@ -162,4 +181,4 @@ function ESX.Table.Sort(t, order)
|
||||
return keys[i], t[keys[i]]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -29,15 +29,18 @@ Config.EnableDefaultInventory = true -- Display the default Inventory ( F2 )
|
||||
Config.EnableWantedLevel = false -- Use Normal GTA wanted Level?
|
||||
Config.EnablePVP = true -- Allow Player to player combat
|
||||
|
||||
Config.Multichar = true -- Enable support for esx_multicharacter
|
||||
Config.Multichar = GetResourceState("esx_multicharacter") ~= "missing"
|
||||
Config.Identity = true -- Select a characters identity data before they have loaded in (this happens by default with multichar)
|
||||
Config.DistanceGive = 4.0 -- Max distance when giving items, weapons etc.
|
||||
|
||||
Config.DisableHealthRegeneration = false -- Player will no longer regenerate health
|
||||
Config.DisableVehicleRewards = false -- Disables Player Recieving weapons from vehicles
|
||||
Config.DisableNPCDrops = false -- stops NPCs from dropping weapons on death
|
||||
Config.DisableDispatchServices = false -- Disable Dispatch services
|
||||
Config.DisableScenarios = false -- Disable Scenarios
|
||||
Config.DisableWeaponWheel = false -- Disables default weapon wheel
|
||||
Config.DisableAimAssist = false -- disables AIM assist (mainly on controllers)
|
||||
Config.DisableVehicleSeatShuff = false -- Disables vehicle seat shuff
|
||||
Config.RemoveHudCommonents = {
|
||||
[1] = false, --WANTED_STARS,
|
||||
[2] = false, --WEAPON_ICON
|
||||
|
||||
@@ -15,6 +15,7 @@ CREATE TABLE `users` (
|
||||
`job` VARCHAR(20) NULL DEFAULT 'unemployed',
|
||||
`job_grade` INT NULL DEFAULT 0,
|
||||
`loadout` LONGTEXT NULL DEFAULT NULL,
|
||||
`meta` LONGTEXT NULL DEFAULT NULL,
|
||||
`position` longtext NULL DEFAULT NULL,
|
||||
|
||||
PRIMARY KEY (`identifier`)
|
||||
|
||||
@@ -5,7 +5,7 @@ game 'gta5'
|
||||
description 'ES Extended'
|
||||
|
||||
lua54 'yes'
|
||||
version '1.9.3'
|
||||
version '1.9.4'
|
||||
|
||||
shared_scripts {
|
||||
'locale.lua',
|
||||
@@ -19,30 +19,39 @@ server_scripts {
|
||||
'@oxmysql/lib/MySQL.lua',
|
||||
'config.logs.lua',
|
||||
'server/common.lua',
|
||||
'server/modules/callback.lua',
|
||||
'server/classes/player.lua',
|
||||
'server/classes/overrides/*.lua',
|
||||
'server/functions.lua',
|
||||
'server/onesync.lua',
|
||||
'server/paycheck.lua',
|
||||
|
||||
'server/main.lua',
|
||||
'server/commands.lua',
|
||||
|
||||
'common/modules/*.lua',
|
||||
'common/functions.lua',
|
||||
'server/modules/*.lua'
|
||||
'server/modules/actions.lua',
|
||||
'server/modules/npwd.lua'
|
||||
}
|
||||
|
||||
client_scripts {
|
||||
'client/common.lua',
|
||||
'client/functions.lua',
|
||||
'client/wrapper.lua',
|
||||
'client/modules/callback.lua',
|
||||
|
||||
'client/main.lua',
|
||||
|
||||
'common/modules/*.lua',
|
||||
'common/functions.lua',
|
||||
|
||||
'common/functions.lua',
|
||||
'client/modules/*.lua'
|
||||
'client/modules/actions.lua',
|
||||
'client/modules/death.lua',
|
||||
'client/modules/npwd.lua',
|
||||
'client/modules/scaleform.lua',
|
||||
'client/modules/streaming.lua',
|
||||
}
|
||||
|
||||
ui_page {
|
||||
@@ -65,8 +74,7 @@ files {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
'/server:5949',
|
||||
'/onesync',
|
||||
'/native:0x6AE51D4B',
|
||||
'oxmysql',
|
||||
'spawnmanager',
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
@font-face {
|
||||
font-family: 'Pricedown';
|
||||
src: url('../fonts/pdown.ttf');
|
||||
font-family: "Pricedown";
|
||||
src: url("../fonts/pdown.ttf");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'bankgothic';
|
||||
src: url('../fonts/bankgothic.ttf');
|
||||
font-family: "bankgothic";
|
||||
src: url("../fonts/bankgothic.ttf");
|
||||
}
|
||||
|
||||
html {
|
||||
@@ -20,11 +20,12 @@ html {
|
||||
font-size: 2em;
|
||||
font-weight: bold;
|
||||
color: #fff;
|
||||
text-shadow: -1px -1px 0 #000, 1px -1px 0 #000, -1px 1px 0 #000, 1px 1px 0 #000;
|
||||
text-shadow: -1px -1px 0 #000, 1px -1px 0 #000, -1px 1px 0 #000,
|
||||
1px 1px 0 #000;
|
||||
}
|
||||
|
||||
.menu {
|
||||
font-family: 'Open Sans', sans-serif;
|
||||
font-family: "Open Sans", sans-serif;
|
||||
min-width: 400px;
|
||||
min-height: 250px;
|
||||
color: #fff;
|
||||
@@ -34,7 +35,7 @@ html {
|
||||
}
|
||||
|
||||
.menu .head {
|
||||
font-family: 'Open Sans', sans-serif;
|
||||
font-family: "Open Sans", sans-serif;
|
||||
font-size: 28px;
|
||||
padding: 10px;
|
||||
background: #1a1a1a;
|
||||
@@ -51,14 +52,14 @@ html {
|
||||
}
|
||||
|
||||
.menu .head span {
|
||||
font-family: 'Pricedown';
|
||||
font-family: "Pricedown";
|
||||
font-size: 28px;
|
||||
padding-left: 15px;
|
||||
padding-top: 6px;
|
||||
}
|
||||
|
||||
.menu .menu-items .menu-item {
|
||||
font-family: 'Open Sans', sans-serif;
|
||||
font-family: "Open Sans", sans-serif;
|
||||
font-size: 14px;
|
||||
height: 40px;
|
||||
display: block;
|
||||
|
||||
@@ -1,38 +1,40 @@
|
||||
(() => {
|
||||
ESX = {};
|
||||
ESX = {};
|
||||
|
||||
ESX.inventoryNotification = function (add, label, count) {
|
||||
let notif = '';
|
||||
ESX.inventoryNotification = function (add, label, count) {
|
||||
let notif = "";
|
||||
|
||||
if (add) {
|
||||
notif += '+';
|
||||
} else {
|
||||
notif += '-';
|
||||
}
|
||||
if (add) {
|
||||
notif += "+";
|
||||
} else {
|
||||
notif += "-";
|
||||
}
|
||||
|
||||
if (count) {
|
||||
notif += count + ' ' + label;
|
||||
} else {
|
||||
notif += ' ' + label;
|
||||
}
|
||||
if (count) {
|
||||
notif += count + " " + label;
|
||||
} else {
|
||||
notif += " " + label;
|
||||
}
|
||||
|
||||
let elem = $('<div>' + notif + '</div>');
|
||||
$('#inventory_notifications').append(elem);
|
||||
let elem = $("<div>" + notif + "</div>");
|
||||
$("#inventory_notifications").append(elem);
|
||||
|
||||
$(elem).delay(3000).fadeOut(1000, function () {
|
||||
elem.remove();
|
||||
});
|
||||
};
|
||||
$(elem)
|
||||
.delay(3000)
|
||||
.fadeOut(1000, function () {
|
||||
elem.remove();
|
||||
});
|
||||
};
|
||||
|
||||
window.onData = (data) => {
|
||||
if (data.action === 'inventoryNotification') {
|
||||
ESX.inventoryNotification(data.add, data.item, data.count);
|
||||
}
|
||||
};
|
||||
window.onData = (data) => {
|
||||
if (data.action === "inventoryNotification") {
|
||||
ESX.inventoryNotification(data.add, data.item, data.count);
|
||||
}
|
||||
};
|
||||
|
||||
window.onload = function (e) {
|
||||
window.addEventListener('message', (event) => {
|
||||
onData(event.data);
|
||||
});
|
||||
};
|
||||
window.onload = function (e) {
|
||||
window.addEventListener("message", (event) => {
|
||||
onData(event.data);
|
||||
});
|
||||
};
|
||||
})();
|
||||
|
||||
@@ -1,42 +1,35 @@
|
||||
(() => {
|
||||
let ESXWrapper = {};
|
||||
ESXWrapper.MessageSize = 1024;
|
||||
ESXWrapper.messageId = 0;
|
||||
|
||||
let ESXWrapper = {};
|
||||
ESXWrapper.MessageSize = 1024;
|
||||
ESXWrapper.messageId = 0;
|
||||
window.SendMessage = function (namespace, type, msg) {
|
||||
ESXWrapper.messageId =
|
||||
ESXWrapper.messageId < 65535 ? ESXWrapper.messageId + 1 : 0;
|
||||
const str = JSON.stringify(msg);
|
||||
|
||||
window.SendMessage = function (namespace, type, msg) {
|
||||
for (let i = 0; i < str.length; i++) {
|
||||
let count = 0;
|
||||
let chunk = "";
|
||||
|
||||
ESXWrapper.messageId = (ESXWrapper.messageId < 65535) ? ESXWrapper.messageId + 1 : 0;
|
||||
const str = JSON.stringify(msg);
|
||||
while (count < ESXWrapper.MessageSize && i < str.length) {
|
||||
chunk += str[i];
|
||||
|
||||
for (let i = 0; i < str.length; i++) {
|
||||
count++;
|
||||
i++;
|
||||
}
|
||||
|
||||
let count = 0;
|
||||
let chunk = '';
|
||||
i--;
|
||||
|
||||
while (count < ESXWrapper.MessageSize && i < str.length) {
|
||||
const data = {
|
||||
__type: type,
|
||||
id: ESXWrapper.messageId,
|
||||
chunk: chunk,
|
||||
};
|
||||
|
||||
chunk += str[i];
|
||||
if (i == str.length - 1) data.end = true;
|
||||
|
||||
count++;
|
||||
i++;
|
||||
}
|
||||
|
||||
i--;
|
||||
|
||||
const data = {
|
||||
__type: type,
|
||||
id: ESXWrapper.messageId,
|
||||
chunk: chunk
|
||||
}
|
||||
|
||||
if (i == str.length - 1)
|
||||
data.end = true;
|
||||
|
||||
$.post('http://' + namespace + '/__chunk', JSON.stringify(data));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
})()
|
||||
$.post("http://" + namespace + "/__chunk", JSON.stringify(data));
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
@@ -0,0 +1,365 @@
|
||||
Locales['it'] = {
|
||||
-- Inventory
|
||||
['inventory'] = 'Inventario ( Peso %s / %s )',
|
||||
['use'] = 'Usa',
|
||||
['give'] = 'Dai',
|
||||
['remove'] = 'Butta',
|
||||
['return'] = 'Ritorna',
|
||||
['give_to'] = 'Dai a',
|
||||
['amount'] = 'Quantità',
|
||||
['giveammo'] = 'Dai munizioni',
|
||||
['amountammo'] = 'Quantità munizioni',
|
||||
['noammo'] = 'Non abbastanza!',
|
||||
['gave_item'] = 'Dando %sx %s a %s',
|
||||
['received_item'] = 'Ricevuto %sx %s da %s',
|
||||
['gave_weapon'] = 'Dando %s a %s',
|
||||
['gave_weapon_ammo'] = 'Dando ~o~%sx %s for %s to %s',
|
||||
['gave_weapon_withammo'] = 'Dando %s con ~o~%sx %s a %s',
|
||||
['gave_weapon_hasalready'] = '%s possiede già %s',
|
||||
['gave_weapon_noweapon'] = '%s non ha quell\' arma',
|
||||
['received_weapon'] = 'Ricevuto %s da %s',
|
||||
['received_weapon_ammo'] = 'Ricevuto ~o~%sx %s per il tuo %s da %s',
|
||||
['received_weapon_withammo'] = 'Ricevuto %s con ~o~%sx %s per %s',
|
||||
['received_weapon_hasalready'] = '%s ha tentato di darti %s, ma hai già l\'arma',
|
||||
['received_weapon_noweapon'] = '%s ha tentato di darti munizioni per %s, ma non hai l\'arma',
|
||||
['gave_account_money'] = 'Dando $%s (%s) a %s',
|
||||
['received_account_money'] = 'Ricevuto $%s (%s) da %s',
|
||||
['amount_invalid'] = 'Quantità non valida',
|
||||
['players_nearby'] = 'Nessun giocatore vicino',
|
||||
['ex_inv_lim'] = 'Non puoi farlo, eccedi il peso di %s',
|
||||
['imp_invalid_quantity'] = 'Non puoi farlo, quantità non valida',
|
||||
['imp_invalid_amount'] = 'Non puoi farlo, importo non valido',
|
||||
['threw_standard'] = 'Gettando %sx %s',
|
||||
['threw_account'] = 'Gettando $%s %s',
|
||||
['threw_weapon'] = 'Gettando %s',
|
||||
['threw_weapon_ammo'] = 'Gettando %s con ~o~%sx %s',
|
||||
['threw_weapon_already'] = 'Hai gia quest\' arma',
|
||||
['threw_cannot_pickup'] = 'Inventario pieno, non puoi raccogliere!',
|
||||
['threw_pickup_prompt'] = 'Premi E per raccogliere',
|
||||
|
||||
-- Key mapping
|
||||
['keymap_showinventory'] = 'Apri inventario',
|
||||
|
||||
-- Salary related
|
||||
['received_salary'] = 'Sei stato pagato: $%s',
|
||||
['received_help'] = 'Hai ricevuto il reddito di cittadinanza: $%s',
|
||||
['company_nomoney'] = 'La tua compagnia è troppo povera per pagarti',
|
||||
['received_paycheck'] = 'Ricveuto stipendio',
|
||||
['bank'] = 'Banca',
|
||||
['account_bank'] = 'Conto',
|
||||
['account_black_money'] = 'Soldi sporchi',
|
||||
['account_money'] = 'Contanti',
|
||||
|
||||
['act_imp'] = 'Non puoi farlo',
|
||||
['in_vehicle'] = 'Non puoi farlo, il giocatore è in un veicolo',
|
||||
|
||||
-- Commands
|
||||
['command_bring'] = 'Porta il giocatore da te',
|
||||
['command_car'] = 'Spawna un veicolo',
|
||||
['command_car_car'] = 'Modello o hash veicolo',
|
||||
['command_cardel'] = 'Rimuovi i veicoli nelle prossimità',
|
||||
['command_cardel_radius'] = 'Rimuovi i veicoli nel raggio specificato',
|
||||
['command_clear'] = 'Pulisci la chat testuale',
|
||||
['command_clearall'] = 'Pulisci la chat testuale per tutti i giocatori',
|
||||
['command_clearinventory'] = 'Rimuovi tutti gli oggetti dall\' inventario del giocatore',
|
||||
['command_clearloadout'] = 'Rimuovi tutte le armi dal loadout del giocatore',
|
||||
['command_freeze'] = 'Blocca un giocatore',
|
||||
['command_unfreeze'] = 'Sblocca un giocatore',
|
||||
['command_giveaccountmoney'] = 'Dai soldi a un\' account specifico',
|
||||
['command_giveaccountmoney_account'] = 'Account a cui aggiungere',
|
||||
['command_giveaccountmoney_amount'] = 'Quantità da aggiungere',
|
||||
['command_giveaccountmoney_invalid'] = 'Nome account non valido',
|
||||
['command_giveitem'] = 'Dai un oggetto ad un giocatore',
|
||||
['command_giveitem_item'] = 'Nome oggetto',
|
||||
['command_giveitem_count'] = 'Quantità',
|
||||
['command_giveweapon'] = 'Dai un\' arma ad un giocatore',
|
||||
['command_giveweapon_weapon'] = 'Nome arma',
|
||||
['command_giveweapon_ammo'] = 'Quantità munizioni',
|
||||
['command_giveweapon_hasalready'] = 'Il giocatore ha già l\'arma',
|
||||
['command_giveweaponcomponent'] = 'Dai un componente arma ad un giocatore',
|
||||
['command_giveweaponcomponent_component'] = 'Nome componente',
|
||||
['command_giveweaponcomponent_invalid'] = 'Componente arma non valido',
|
||||
['command_giveweaponcomponent_hasalready'] = 'Il giocatore ha già questo componente arma',
|
||||
['command_giveweaponcomponent_missingweapon'] = 'Il giocatore non ha l\'arma',
|
||||
['command_goto'] = 'Teletrasportati da un giocatore',
|
||||
['command_kill'] = 'Uccidi un giocatore',
|
||||
['command_save'] = 'Salva forzatamente i dati di un giocatore',
|
||||
['command_saveall'] = 'Salva forzatamente i dati di tutti igiocatoria',
|
||||
['command_setaccountmoney'] = 'Aggiorna i soldi dentro un account specifico',
|
||||
['command_setaccountmoney_amount'] = 'Quantità',
|
||||
['command_setcoords'] = 'Teletrasportati a delle coordinate specifiche',
|
||||
['command_setcoords_x'] = 'Valore X',
|
||||
['command_setcoords_y'] = 'Valore Y',
|
||||
['command_setcoords_z'] = 'Valore Z',
|
||||
['command_setjob'] = 'Setta lavoro ad un giocatore',
|
||||
['command_setjob_job'] = 'Nome',
|
||||
['command_setjob_grade'] = 'Grado lavoro',
|
||||
['command_setjob_invalid'] = 'Il lavoro, grado o entrambi sono errati',
|
||||
['command_setgroup'] = 'Setta un gruppo di permessi ad un giocatore',
|
||||
['command_setgroup_group'] = 'Nome del gruppo',
|
||||
['commanderror_argumentmismatch'] = 'Conta argomenti non valida (passati %s, richiesti %s)',
|
||||
['commanderror_argumentmismatch_number'] = 'Argomento #%s di tipologia errata (passato testo, richiesto numero)',
|
||||
['commanderror_invaliditem'] = 'Oggetto non valido',
|
||||
['commanderror_invalidweapon'] = 'Arma non valida',
|
||||
['commanderror_console'] = 'Comando non eseguibile dalla console',
|
||||
['commanderror_invalidcommand'] = 'Comando non valido - /%s',
|
||||
['commanderror_invalidplayerid'] = 'Il giocatore specificato non è online',
|
||||
['commandgeneric_playerid'] = 'Id server del giocatore',
|
||||
['command_giveammo_noweapon_found'] = '%s non ha quell\' arma',
|
||||
['command_giveammo_weapon'] = 'Nome arma',
|
||||
['command_giveammo_ammo'] = 'Quantità munizioni',
|
||||
['tpm_nowaypoint'] = 'Nessuna meta impostata',
|
||||
['tpm_success'] = 'Teletrasportato con successo',
|
||||
|
||||
['noclip_message'] = 'Noclip %s',
|
||||
['enabled'] = '~g~abilitato~s~',
|
||||
['disabled'] = '~r~disabilitato~s~',
|
||||
|
||||
-- Locale settings
|
||||
['locale_digit_grouping_symbol'] = ',',
|
||||
['locale_currency'] = '$%s',
|
||||
|
||||
-- Weapons
|
||||
|
||||
-- Melee
|
||||
['weapon_dagger'] = 'Pugnale Antico',
|
||||
['weapon_bat'] = 'Mazza',
|
||||
['weapon_battleaxe'] = 'Ascia',
|
||||
['weapon_bottle'] = 'Bottiglia',
|
||||
['weapon_crowbar'] = 'Piede di porco',
|
||||
['weapon_flashlight'] = 'Torcia',
|
||||
['weapon_golfclub'] = 'Mazza da golf',
|
||||
['weapon_hammer'] = 'Martello',
|
||||
['weapon_hatchet'] = 'Accetta',
|
||||
['weapon_knife'] = 'Coltello',
|
||||
['weapon_knuckle'] = 'Tirapugni',
|
||||
['weapon_machete'] = 'Machete',
|
||||
['weapon_nightstick'] = 'Manganello',
|
||||
['weapon_wrench'] = 'Tubo',
|
||||
['weapon_poolcue'] = 'Stecca',
|
||||
['weapon_stone_hatchet'] = 'Accetta di pietra',
|
||||
['weapon_switchblade'] = 'Coltello a serramanico',
|
||||
|
||||
-- Handguns
|
||||
['weapon_appistol'] = 'Pistola AP',
|
||||
['weapon_ceramicpistol'] = 'Pistola di ceramica',
|
||||
['weapon_combatpistol'] = 'Pistola da combattimento',
|
||||
['weapon_doubleaction'] = 'Revolver doppia azione',
|
||||
['weapon_navyrevolver'] = 'Revolver Marina',
|
||||
['weapon_flaregun'] = 'Pistola lanciarazzi',
|
||||
['weapon_gadgetpistol'] = 'Pistola Gadget',
|
||||
['weapon_heavypistol'] = 'Pistola pesante',
|
||||
['weapon_revolver'] = 'Revolver pesante',
|
||||
['weapon_revolver_mk2'] = 'Revolver pesante MK2',
|
||||
['weapon_marksmanpistol'] = 'Pistola da tiratore',
|
||||
['weapon_pistol'] = 'Pistola',
|
||||
['weapon_pistol_mk2'] = 'Pistola MK2',
|
||||
['weapon_pistol50'] = 'Pistola .50',
|
||||
['weapon_snspistol'] = 'Pistola SNS',
|
||||
['weapon_snspistol_mk2'] = 'Pistola SNS MK2',
|
||||
['weapon_stungun'] = 'Taser',
|
||||
['weapon_raypistol'] = 'Up-N-Atomizzatore',
|
||||
['weapon_vintagepistol'] = 'Pistola Vintage',
|
||||
|
||||
-- Shotguns
|
||||
['weapon_assaultshotgun'] = 'Fucile a pompa d\'assalto',
|
||||
['weapon_autoshotgun'] = 'Fucile a pompa automatico',
|
||||
['weapon_bullpupshotgun'] = 'Fucile a pompa Bullup',
|
||||
['weapon_combatshotgun'] = 'Fucile a pompa da combattimento',
|
||||
['weapon_dbshotgun'] = 'Fucile a pompa doppia canna',
|
||||
['weapon_heavyshotgun'] = 'Fucile a pompa pesante',
|
||||
['weapon_musket'] = 'Moschetto',
|
||||
['weapon_pumpshotgun'] = 'Fucile a pompa',
|
||||
['weapon_pumpshotgun_mk2'] = 'Fucile a pompa MK2',
|
||||
['weapon_sawnoffshotgun'] = 'Fucile a canne mozza',
|
||||
|
||||
-- SMG & LMG
|
||||
['weapon_assaultsmg'] = 'SMG d\'assalto',
|
||||
['weapon_combatmg'] = 'MG da combattimento',
|
||||
['weapon_combatmg_mk2'] = 'MG da combattimento MK2',
|
||||
['weapon_combatpdw'] = 'PDW da combattimento',
|
||||
['weapon_gusenberg'] = 'Mitragliatrice Gusenberg',
|
||||
['weapon_machinepistol'] = 'Pistola mitragliatrice',
|
||||
['weapon_mg'] = 'MG',
|
||||
['weapon_microsmg'] = 'Micro SMG',
|
||||
['weapon_minismg'] = 'Mini SMG',
|
||||
['weapon_smg'] = 'SMG',
|
||||
['weapon_smg_mk2'] = 'SMG MK2',
|
||||
['weapon_raycarbine'] = 'Hellbringer infernale',
|
||||
|
||||
-- Rifles
|
||||
['weapon_advancedrifle'] = 'Fucile avanzato',
|
||||
['weapon_assaultrifle'] = 'Fucile d\'assalto',
|
||||
['weapon_assaultrifle_mk2'] = 'Fucile d\' assalto MK2',
|
||||
['weapon_bullpuprifle'] = 'Fucile Bullpup',
|
||||
['weapon_bullpuprifle_mk2'] = 'Fucile Bullpup MK2',
|
||||
['weapon_carbinerifle'] = 'Carabina',
|
||||
['weapon_carbinerifle_mk2'] = 'Carbine MK2',
|
||||
['weapon_compactrifle'] = 'Fucile compatto',
|
||||
['weapon_militaryrifle'] = 'Fucile militare',
|
||||
['weapon_specialcarbine'] = 'Carabina speciale',
|
||||
['weapon_specialcarbine_mk2'] = 'Carabina speciale MK2',
|
||||
|
||||
-- Sniper
|
||||
['weapon_heavysniper'] = 'Cecchino pesante',
|
||||
['weapon_heavysniper_mk2'] = 'Cecchino pesante MK2',
|
||||
['weapon_marksmanrifle'] = 'Fucile da tiratore',
|
||||
['weapon_marksmanrifle_mk2'] = 'Fucile da tiratore MK2',
|
||||
['weapon_sniperrifle'] = 'Cecchino',
|
||||
|
||||
-- Heavy / Launchers
|
||||
['weapon_compactlauncher'] = 'Lanciagranate compatto',
|
||||
['weapon_firework'] = 'Cannone pirotecnico',
|
||||
['weapon_grenadelauncher'] = 'Lanciagranate',
|
||||
['weapon_hominglauncher'] = 'Lanciarazzi a tracciamento',
|
||||
['weapon_minigun'] = 'Minigun',
|
||||
['weapon_railgun'] = 'Railgun',
|
||||
['weapon_rpg'] = 'Lanciarazzi',
|
||||
['weapon_rayminigun'] = 'Widowmaker',
|
||||
|
||||
-- Criminal Enterprises DLC
|
||||
['weapon_metaldetector'] = 'Metal Detector',
|
||||
['weapon_precisionrifle'] = 'Fucile di precisione',
|
||||
['weapon_tactilerifle'] = 'Carabina di servizio',
|
||||
|
||||
-- Thrown
|
||||
['weapon_ball'] = 'Palla',
|
||||
['weapon_bzgas'] = 'BZ Gas',
|
||||
['weapon_flare'] = 'Flare',
|
||||
['weapon_grenade'] = 'Granata',
|
||||
['weapon_petrolcan'] = 'Tanica',
|
||||
['weapon_hazardcan'] = 'Tanica pericolosa',
|
||||
['weapon_molotov'] = 'Molotov',
|
||||
['weapon_proxmine'] = 'Mina di prossimità',
|
||||
['weapon_pipebomb'] = 'Esplosivo plastico',
|
||||
['weapon_snowball'] = 'Palla di neve',
|
||||
['weapon_stickybomb'] = 'Bomba adesiva',
|
||||
['weapon_smokegrenade'] = 'Gas lacrimogeno',
|
||||
|
||||
-- Special
|
||||
['weapon_fireextinguisher'] = 'Estintore',
|
||||
['weapon_digiscanner'] = 'Scanner digitale',
|
||||
['weapon_garbagebag'] = 'Sacco della spazzatura',
|
||||
['weapon_handcuffs'] = 'Manette',
|
||||
['gadget_nightvision'] = 'Visore termico',
|
||||
['gadget_parachute'] = 'Paracadute',
|
||||
|
||||
-- Weapon Components
|
||||
['component_knuckle_base'] = 'Modello basa',
|
||||
['component_knuckle_pimp'] = 'il Pappone',
|
||||
['component_knuckle_ballas'] = 'i Ballas',
|
||||
['component_knuckle_dollar'] = 'il Riccone',
|
||||
['component_knuckle_diamond'] = 'la Roccia',
|
||||
['component_knuckle_hate'] = 'l\' Hater',
|
||||
['component_knuckle_love'] = 'l\' Amante',
|
||||
['component_knuckle_player'] = 'il Giocatore',
|
||||
['component_knuckle_king'] = 'il Re',
|
||||
['component_knuckle_vagos'] = 'i Vagos',
|
||||
|
||||
['component_luxary_finish'] = 'rifinitura di lusso',
|
||||
|
||||
['component_handle_default'] = 'impugnatura base',
|
||||
['component_handle_vip'] = 'impugnatura VIP',
|
||||
['component_handle_bodyguard'] = 'impugnatura guardia del corpo',
|
||||
|
||||
['component_vip_finish'] = 'rifinitura VIP',
|
||||
['component_bodyguard_finish'] = 'rifinitura Guardia del corpo',
|
||||
|
||||
['component_camo_finish'] = 'mimetica Digitale',
|
||||
['component_camo_finish2'] = 'mimetica Cespuglio',
|
||||
['component_camo_finish3'] = 'mimetica Legnosa',
|
||||
['component_camo_finish4'] = 'mimetica Teschio',
|
||||
['component_camo_finish5'] = 'mimetica Sessanta Nove',
|
||||
['component_camo_finish6'] = 'mimetica Perseo',
|
||||
['component_camo_finish7'] = 'mimetica Leopardata',
|
||||
['component_camo_finish8'] = 'mimetica Zebra',
|
||||
['component_camo_finish9'] = 'mimetica Geometrica',
|
||||
['component_camo_finish10'] = 'mimetica Boom',
|
||||
['component_camo_finish11'] = 'mimetica Patriottica',
|
||||
|
||||
['component_camo_slide_finish'] = 'mimetica Digitale Slide',
|
||||
['component_camo_slide_finish2'] = 'mimetica Cespuglio Slide',
|
||||
['component_camo_slide_finish3'] = 'mimetica Legnosa Slide',
|
||||
['component_camo_slide_finish4'] = 'mimetica Teschio Slide',
|
||||
['component_camo_slide_finish5'] = 'mimetica Sessanta Nove Slide',
|
||||
['component_camo_slide_finish6'] = 'mimetica Perseo Slide',
|
||||
['component_camo_slide_finish7'] = 'mimetica Leopardata Slide',
|
||||
['component_camo_slide_finish8'] = 'mimetica Zebra Slide',
|
||||
['component_camo_slide_finish9'] = 'mimetica Geometrica Slide',
|
||||
['component_camo_slide_finish10'] = 'mimetica Boom Slide',
|
||||
['component_camo_slide_finish11'] = 'mimetica Patriottica Slide',
|
||||
|
||||
['component_clip_default'] = 'caricatore Standard',
|
||||
['component_clip_extended'] = 'caricatore Esteso',
|
||||
['component_clip_drum'] = 'caricatore A Batteria',
|
||||
['component_clip_box'] = 'caricatore A Scatola',
|
||||
|
||||
['component_scope_holo'] = 'mirino Olografico',
|
||||
['component_scope_small'] = 'mirino Piccolo',
|
||||
['component_scope_medium'] = 'mirino Medio',
|
||||
['component_scope_large'] = 'mirino Largo',
|
||||
['component_scope'] = 'mirino Montato',
|
||||
['component_scope_advanced'] = 'mirino Avanzato',
|
||||
['component_ironsights'] = 'integrato',
|
||||
|
||||
['component_suppressor'] = 'silenziatore',
|
||||
['component_compensator'] = 'compensatore',
|
||||
|
||||
['component_muzzle_flat'] = 'freno Di Bocca Piatto',
|
||||
['component_muzzle_tactical'] = 'freno Di Bocca Tattico',
|
||||
['component_muzzle_fat'] = 'freno Di Bocca Grosso',
|
||||
['component_muzzle_precision'] = 'freno Di Bocca Di Precisione',
|
||||
['component_muzzle_heavy'] = 'freno Di Bocca Pesante',
|
||||
['component_muzzle_slanted'] = 'freno Di Bocca Inclinato',
|
||||
['component_muzzle_split'] = 'freno Di Bocca Diviso',
|
||||
['component_muzzle_squared'] = 'freno Di Bocca Quadrato',
|
||||
|
||||
['component_flashlight'] = 'torcia',
|
||||
['component_grip'] = 'impugnatura',
|
||||
|
||||
['component_barrel_default'] = 'canna Standard',
|
||||
['component_barrel_heavy'] = 'canna Pesante',
|
||||
|
||||
['component_ammo_tracer'] = 'munizioni Traccianti',
|
||||
['component_ammo_incendiary'] = 'munizioni Incendiarie',
|
||||
['component_ammo_hollowpoint'] = 'munizioni a Punta Cava',
|
||||
['component_ammo_fmj'] = 'munizioni fMj',
|
||||
['component_ammo_armor'] = 'munizioni penetranti',
|
||||
['component_ammo_explosive'] = 'munizioni penetranti incendiarie',
|
||||
|
||||
['component_shells_default'] = 'cartucce Standard',
|
||||
['component_shells_incendiary'] = 'cartucce alito di Drago',
|
||||
['component_shells_armor'] = 'cartucce a pallettoni',
|
||||
['component_shells_hollowpoint'] = 'cartucce a freccette',
|
||||
['component_shells_explosive'] = 'cartucce esplosive',
|
||||
|
||||
-- Weapon Ammo
|
||||
['ammo_rounds'] = 'colpo(i)',
|
||||
['ammo_shells'] = 'cartuccia(e)',
|
||||
['ammo_charge'] = 'carica',
|
||||
['ammo_petrol'] = 'Litri di carburante',
|
||||
['ammo_firework'] = 'fuochi d\'artificio',
|
||||
['ammo_rockets'] = 'razzo(i)',
|
||||
['ammo_grenadelauncher'] = 'granata(e)',
|
||||
['ammo_grenade'] = 'granata(e)',
|
||||
['ammo_stickybomb'] = 'bomba(e)',
|
||||
['ammo_pipebomb'] = 'bomba(e)',
|
||||
['ammo_smokebomb'] = 'bomba(e)',
|
||||
['ammo_molotov'] = 'bottiglia(e)',
|
||||
['ammo_proxmine'] = 'mina(e)',
|
||||
['ammo_bzgas'] = 'latta(e)',
|
||||
['ammo_ball'] = 'palla(e)',
|
||||
['ammo_snowball'] = 'palle di neve',
|
||||
['ammo_flare'] = 'razzo(i)',
|
||||
['ammo_flaregun'] = 'razzo(i)',
|
||||
|
||||
-- Weapon Tints
|
||||
['tint_default'] = 'Colore standard',
|
||||
['tint_green'] = 'color verde',
|
||||
['tint_gold'] = 'color oro',
|
||||
['tint_pink'] = 'color rosa',
|
||||
['tint_army'] = 'color army',
|
||||
['tint_lspd'] = 'color blu',
|
||||
['tint_orange'] = 'color arancio',
|
||||
['tint_platinum'] = 'color platino',
|
||||
}
|
||||
@@ -4,7 +4,7 @@ local DoesEntityExist = DoesEntityExist
|
||||
local GetEntityCoords = GetEntityCoords
|
||||
local GetEntityHeading = GetEntityHeading
|
||||
|
||||
function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, weight, job, loadout, name, coords)
|
||||
function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, weight, job, loadout, name, coords, meta)
|
||||
local targetOverrides = Config.PlayerFunctionOverride and Core.PlayerFunctionOverrides[Config.PlayerFunctionOverride] or {}
|
||||
|
||||
local self = {}
|
||||
@@ -22,6 +22,7 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory,
|
||||
self.variables = {}
|
||||
self.weight = weight
|
||||
self.maxWeight = Config.MaxWeight
|
||||
self.meta = meta
|
||||
if Config.Multichar then self.license = 'license'.. identifier:sub(identifier:find(':'), identifier:len()) else self.license = 'license:'..identifier end
|
||||
|
||||
ExecuteCommand(('add_principal identifier.%s group.%s'):format(self.license, self.group))
|
||||
@@ -32,6 +33,7 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory,
|
||||
stateBag:set("job", self.job, true)
|
||||
stateBag:set("group", self.group, true)
|
||||
stateBag:set("name", self.name, true)
|
||||
stateBag:set("meta", self.meta, true)
|
||||
|
||||
function self.triggerEvent(eventName, ...)
|
||||
TriggerClientEvent(eventName, self.source, ...)
|
||||
@@ -293,14 +295,18 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory,
|
||||
|
||||
if item then
|
||||
count = ESX.Math.Round(count)
|
||||
local newCount = item.count - count
|
||||
if count > 0 then
|
||||
local newCount = item.count - count
|
||||
|
||||
if newCount >= 0 then
|
||||
item.count = newCount
|
||||
self.weight = self.weight - (item.weight * count)
|
||||
if newCount >= 0 then
|
||||
item.count = newCount
|
||||
self.weight = self.weight - (item.weight * count)
|
||||
|
||||
TriggerEvent('esx:onRemoveInventoryItem', self.source, item.name, item.count)
|
||||
self.triggerEvent('esx:removeInventoryItem', item.name, item.count)
|
||||
TriggerEvent('esx:onRemoveInventoryItem', self.source, item.name, item.count)
|
||||
self.triggerEvent('esx:removeInventoryItem', item.name, item.count)
|
||||
end
|
||||
else
|
||||
print(('[^1ERROR^7] Player ID:^5%s Tried remove a Invalid count -> %s of %s'):format(self.playerId, count,name))
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -573,6 +579,109 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory,
|
||||
self.triggerEvent('esx:showHelpNotification', msg, thisFrame, beep, duration)
|
||||
end
|
||||
|
||||
function self.getMeta(index, subIndex)
|
||||
if index then
|
||||
|
||||
if type(index) ~= "string" then
|
||||
return print("[^1ERROR^7] xPlayer.getMeta ^5index^7 should be ^5string^7!")
|
||||
end
|
||||
|
||||
if self.meta[index] then
|
||||
|
||||
if subIndex and type(self.meta[index]) == "table" then
|
||||
local _type = type(subIndex)
|
||||
|
||||
if _type == "string" then
|
||||
if self.meta[index][subIndex] then
|
||||
return self.meta[index][subIndex]
|
||||
end
|
||||
|
||||
return print(("[^1ERROR^7] xPlayer.getMeta ^5%s^7 not esxist on ^5%s^7!"):format(subIndex, index))
|
||||
end
|
||||
|
||||
if _type == "table" then
|
||||
local returnValues = {}
|
||||
for i = 1, #subIndex do
|
||||
if self.meta[index][subIndex[i]] then
|
||||
returnValues[subIndex[i]] = self.meta[index][subIndex[i]]
|
||||
else
|
||||
print(("[^1ERROR^7] xPlayer.getMeta ^5%s^7 not esxist on ^5%s^7!"):format(subIndex[i], index))
|
||||
end
|
||||
end
|
||||
|
||||
return returnValues
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
return self.meta[index]
|
||||
else
|
||||
return print(("[^1ERROR^7] xPlayer.getMeta ^5%s^7 not exist!"):format(index))
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
return self.meta
|
||||
end
|
||||
|
||||
function self.setMeta(index, value, subValue)
|
||||
if not index then
|
||||
return print("[^1ERROR^7] xPlayer.setMeta ^5index^7 is Missing!")
|
||||
end
|
||||
|
||||
if type(index) ~= "string" then
|
||||
return print("[^1ERROR^7] xPlayer.setMeta ^5index^7 should be ^5string^7!")
|
||||
end
|
||||
|
||||
if not value then
|
||||
return print(("[^1ERROR^7] xPlayer.setMeta ^5%s^7 is Missing!"):format(value))
|
||||
end
|
||||
|
||||
local _type = type(value)
|
||||
|
||||
if not subValue then
|
||||
|
||||
if _type ~= "number" and _type ~= "string" and _type ~= "table" then
|
||||
return print(("[^1ERROR^7] xPlayer.setMeta ^5%s^7 should be ^5number^7 or ^5string^7 or ^5table^7!"):format(value))
|
||||
end
|
||||
|
||||
self.meta[index] = value
|
||||
else
|
||||
|
||||
if _type ~= "string" then
|
||||
return print(("[^1ERROR^7] xPlayer.setMeta ^5value^7 should be ^5string^7 as a subIndex!"):format(value))
|
||||
end
|
||||
|
||||
self.meta[index][value] = subValue
|
||||
end
|
||||
|
||||
|
||||
self.triggerEvent('esx:updatePlayerData', 'meta', self.meta)
|
||||
Player(self.source).state:set('meta', self.meta, true)
|
||||
end
|
||||
|
||||
function self.clearMeta(index)
|
||||
if not index then
|
||||
return print(("[^1ERROR^7] xPlayer.clearMeta ^5%s^7 is Missing!"):format(index))
|
||||
end
|
||||
|
||||
if type(index) == 'table' then
|
||||
for _, val in pairs(index) do
|
||||
self.clearMeta(val)
|
||||
end
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
if not self.meta[index] then
|
||||
return print(("[^1ERROR^7] xPlayer.clearMeta ^5%s^7 not exist!"):format(index))
|
||||
end
|
||||
|
||||
self.meta[index] = nil
|
||||
self.triggerEvent('esx:updatePlayerData', 'meta', self.meta)
|
||||
Player(self.source).state:set('meta', self.meta, true)
|
||||
end
|
||||
|
||||
for fnName,fn in pairs(targetOverrides) do
|
||||
self[fnName] = fn(self)
|
||||
end
|
||||
|
||||
@@ -4,16 +4,15 @@ ESX.Jobs = {}
|
||||
ESX.Items = {}
|
||||
Core = {}
|
||||
Core.UsableItemsCallbacks = {}
|
||||
Core.ServerCallbacks = {}
|
||||
Core.ClientCallbacks = {}
|
||||
Core.CurrentRequestId = 0
|
||||
Core.RegisteredCommands = {}
|
||||
Core.Pickups = {}
|
||||
Core.PickupId = 0
|
||||
Core.PlayerFunctionOverrides = {}
|
||||
|
||||
Core.DatabaseConnected = false
|
||||
Core.playersByIdentifier = {}
|
||||
|
||||
Core.vehicleTypesByModel = {}
|
||||
|
||||
AddEventHandler("esx:getSharedObject", function()
|
||||
local Invoke = GetInvokingResource()
|
||||
print(("[^1ERROR^7] Resource ^5%s^7 Used the ^5getSharedObject^7 Event, this event ^1no longer exists!^7 Visit https://documentation.esx-framework.org/tutorials/tutorials-esx/sharedevent for how to fix!"):format(Invoke))
|
||||
@@ -40,6 +39,7 @@ local function StartDBSync()
|
||||
end
|
||||
|
||||
MySQL.ready(function()
|
||||
Core.DatabaseConnected = true
|
||||
if not Config.OxInventory then
|
||||
local items = MySQL.query.await('SELECT * FROM items')
|
||||
for k, v in ipairs(items) do
|
||||
@@ -78,15 +78,6 @@ AddEventHandler('esx:clientLog', function(msg)
|
||||
end
|
||||
end)
|
||||
|
||||
RegisterServerEvent('esx:triggerServerCallback')
|
||||
AddEventHandler('esx:triggerServerCallback', function(name, requestId,Invoke, ...)
|
||||
local source = source
|
||||
|
||||
ESX.TriggerServerCallback(name, requestId, source,Invoke, function(...)
|
||||
TriggerClientEvent('esx:serverCallback', source, requestId,Invoke, ...)
|
||||
end, ...)
|
||||
end)
|
||||
|
||||
RegisterNetEvent("esx:ReturnVehicleType", function(Type, Request)
|
||||
if Core.ClientCallbacks[Request] then
|
||||
Core.ClientCallbacks[Request](Type)
|
||||
|
||||
@@ -103,7 +103,7 @@ function ESX.RegisterCommand(name, group, cb, allowConsole, suggestion)
|
||||
end
|
||||
end
|
||||
|
||||
if v.validate == false then
|
||||
if not v.validate then
|
||||
error = nil
|
||||
end
|
||||
|
||||
@@ -143,32 +143,21 @@ function ESX.RegisterCommand(name, group, cb, allowConsole, suggestion)
|
||||
end
|
||||
end
|
||||
|
||||
function ESX.RegisterServerCallback(name, cb)
|
||||
Core.ServerCallbacks[name] = cb
|
||||
end
|
||||
|
||||
function ESX.TriggerServerCallback(name, requestId, source,Invoke, cb, ...)
|
||||
if Core.ServerCallbacks[name] then
|
||||
Core.ServerCallbacks[name](source, cb, ...)
|
||||
else
|
||||
print(('[^1ERROR^7] Server callback ^5"%s"^0 does not exist. Please Check ^5%s^7 for Errors!'):format(name, Invoke))
|
||||
end
|
||||
end
|
||||
|
||||
function Core.SavePlayer(xPlayer, cb)
|
||||
local parameters <const> = {
|
||||
json.encode(xPlayer.getAccounts(true)),
|
||||
xPlayer.job.name,
|
||||
xPlayer.job.grade,
|
||||
xPlayer.job.grade,
|
||||
xPlayer.group,
|
||||
json.encode(xPlayer.getCoords()),
|
||||
json.encode(xPlayer.getInventory(true)),
|
||||
json.encode(xPlayer.getLoadout(true)),
|
||||
json.encode(xPlayer.getMeta()),
|
||||
xPlayer.identifier
|
||||
}
|
||||
|
||||
MySQL.prepare(
|
||||
'UPDATE `users` SET `accounts` = ?, `job` = ?, `job_grade` = ?, `group` = ?, `position` = ?, `inventory` = ?, `loadout` = ? WHERE `identifier` = ?',
|
||||
'UPDATE `users` SET `accounts` = ?, `job` = ?, `job_grade` = ?, `group` = ?, `position` = ?, `inventory` = ?, `loadout` = ?, `meta` = ? WHERE `identifier` = ?',
|
||||
parameters,
|
||||
function(affectedRows)
|
||||
if affectedRows == 1 then
|
||||
@@ -200,12 +189,13 @@ function Core.SavePlayers(cb)
|
||||
json.encode(xPlayer.getCoords()),
|
||||
json.encode(xPlayer.getInventory(true)),
|
||||
json.encode(xPlayer.getLoadout(true)),
|
||||
json.encode(xPlayer.getMeta()),
|
||||
xPlayer.identifier
|
||||
}
|
||||
end
|
||||
|
||||
MySQL.prepare(
|
||||
"UPDATE `users` SET `accounts` = ?, `job` = ?, `job_grade` = ?, `group` = ?, `position` = ?, `inventory` = ?, `loadout` = ? WHERE `identifier` = ?",
|
||||
"UPDATE `users` SET `accounts` = ?, `job` = ?, `job_grade` = ?, `group` = ?, `position` = ?, `inventory` = ?, `loadout` = ?, `meta` = ? WHERE `identifier` = ?",
|
||||
parameters,
|
||||
function(results)
|
||||
if not results then
|
||||
@@ -258,10 +248,21 @@ function ESX.GetIdentifier(playerId)
|
||||
end
|
||||
end
|
||||
|
||||
function ESX.GetVehicleType(Vehicle, Player, cb)
|
||||
Core.CurrentRequestId = Core.CurrentRequestId < 65535 and Core.CurrentRequestId + 1 or 0
|
||||
Core.ClientCallbacks[Core.CurrentRequestId] = cb
|
||||
TriggerClientEvent("esx:GetVehicleType", Player, Vehicle, Core.CurrentRequestId)
|
||||
---@param model string|number
|
||||
---@param player number playerId
|
||||
---@param cb function
|
||||
|
||||
function ESX.GetVehicleType(model, player, cb)
|
||||
model = type(model) == 'string' and joaat(model) or model
|
||||
|
||||
if Core.vehicleTypesByModel[model] then
|
||||
return cb(Core.vehicleTypesByModel[model])
|
||||
end
|
||||
|
||||
ESX.TriggerClientCallback(player, "esx:GetVehicleType", function(vehicleType)
|
||||
Core.vehicleTypesByModel[model] = vehicleType
|
||||
cb(vehicleType)
|
||||
end)
|
||||
end
|
||||
|
||||
function ESX.DiscordLog(name, title, color, message)
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
SetMapName('San Andreas')
|
||||
SetGameType('ESX Legacy')
|
||||
|
||||
local oneSyncState = GetConvar('onesync', 'off')
|
||||
local newPlayer = 'INSERT INTO `users` SET `accounts` = ?, `identifier` = ?, `group` = ?'
|
||||
local loadPlayer = 'SELECT `accounts`, `job`, `job_grade`, `group`, `position`, `inventory`, `skin`, `loadout`'
|
||||
local loadPlayer = 'SELECT `accounts`, `job`, `job_grade`, `group`, `position`, `inventory`, `skin`, `loadout`, `meta`'
|
||||
|
||||
if Config.Multichar then
|
||||
newPlayer = newPlayer .. ', `firstname` = ?, `lastname` = ?, `dateofbirth` = ?, `sex` = ?, `height` = ?'
|
||||
@@ -55,6 +56,7 @@ function onPlayerJoined(playerId)
|
||||
if result then
|
||||
loadESXPlayer(identifier, playerId, false)
|
||||
else
|
||||
|
||||
createESXPlayer(identifier, playerId)
|
||||
end
|
||||
end
|
||||
@@ -95,24 +97,31 @@ if not Config.Multichar then
|
||||
local playerId = source
|
||||
local identifier = ESX.GetIdentifier(playerId)
|
||||
|
||||
if oneSyncState == "off" or oneSyncState == "legacy" then
|
||||
return deferrals.done(('[ESX] ESX Requires Onesync Infinity to work. This server currently has Onesync set to: %s'):format(oneSyncState))
|
||||
end
|
||||
|
||||
if not Core.DatabaseConnected then
|
||||
return deferrals.done(('[ESX] ESX Cannot Connect to your database. Please make sure it is correctly configured in your server.cfg'):format(oneSyncState))
|
||||
end
|
||||
|
||||
if identifier then
|
||||
if ESX.GetPlayerFromIdentifier(identifier) then
|
||||
deferrals.done(
|
||||
return deferrals.done(
|
||||
('[ESX] There was an error loading your character!\nError code: identifier-active\n\nThis error is caused by a player on this server who has the same identifier as you have. Make sure you are not playing on the same account.\n\nYour identifier: %s'):format(
|
||||
identifier))
|
||||
else
|
||||
deferrals.done()
|
||||
return deferrals.done()
|
||||
end
|
||||
else
|
||||
deferrals.done(
|
||||
return deferrals.done(
|
||||
'[ESX] There was an error loading your character!\nError code: identifier-missing\n\nThe cause of this error is not known, your identifier could not be found. Please come back later or report this problem to the server administration team.')
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
function loadESXPlayer(identifier, playerId, isNew)
|
||||
local userData = {accounts = {}, inventory = {}, job = {}, loadout = {}, playerName = GetPlayerName(playerId), weight = 0}
|
||||
|
||||
local userData = {accounts = {}, inventory = {}, job = {}, loadout = {}, playerName = GetPlayerName(playerId), weight = 0, meta = {}}
|
||||
local result = MySQL.prepare.await(loadPlayer, {identifier})
|
||||
local job, grade, jobObject, gradeObject = result.job, tostring(result.job_grade)
|
||||
local foundAccounts, foundItems = {}, {}
|
||||
@@ -271,8 +280,13 @@ function loadESXPlayer(identifier, playerId, isNew)
|
||||
end
|
||||
end
|
||||
|
||||
if result.meta and result.meta ~= '' then
|
||||
local meta = json.decode(result.meta)
|
||||
userData.meta = meta
|
||||
end
|
||||
|
||||
local xPlayer = CreateExtendedPlayer(playerId, identifier, userData.group, userData.accounts, userData.inventory, userData.weight, userData.job,
|
||||
userData.loadout, userData.playerName, userData.coords)
|
||||
userData.loadout, userData.playerName, userData.coords, userData.meta)
|
||||
ESX.Players[playerId] = xPlayer
|
||||
Core.playersByIdentifier[identifier] = xPlayer
|
||||
|
||||
@@ -307,7 +321,8 @@ function loadESXPlayer(identifier, playerId, isNew)
|
||||
lastName = xPlayer.get("lastName") or "Doe",
|
||||
dateofbirth = xPlayer.get("dateofbirth") or "01/01/2000",
|
||||
height = xPlayer.get("height") or 120,
|
||||
dead = false
|
||||
dead = false,
|
||||
meta = xPlayer.getMeta()
|
||||
}, isNew,
|
||||
userData.skin)
|
||||
|
||||
@@ -579,7 +594,7 @@ ESX.RegisterServerCallback('esx:getPlayerData', function(source, cb)
|
||||
local xPlayer = ESX.GetPlayerFromId(source)
|
||||
|
||||
cb({identifier = xPlayer.identifier, accounts = xPlayer.getAccounts(), inventory = xPlayer.getInventory(), job = xPlayer.getJob(),
|
||||
loadout = xPlayer.getLoadout(), money = xPlayer.getMoney(), position = xPlayer.getCoords(true)})
|
||||
loadout = xPlayer.getLoadout(), money = xPlayer.getMoney(), position = xPlayer.getCoords(true), meta = xPlayer.getMeta()})
|
||||
end)
|
||||
|
||||
ESX.RegisterServerCallback('esx:isUserAdmin', function(source, cb)
|
||||
@@ -594,7 +609,7 @@ ESX.RegisterServerCallback('esx:getOtherPlayerData', function(source, cb, target
|
||||
local xPlayer = ESX.GetPlayerFromId(target)
|
||||
|
||||
cb({identifier = xPlayer.identifier, accounts = xPlayer.getAccounts(), inventory = xPlayer.getInventory(), job = xPlayer.getJob(),
|
||||
loadout = xPlayer.getLoadout(), money = xPlayer.getMoney(), position = xPlayer.getCoords(true)})
|
||||
loadout = xPlayer.getLoadout(), money = xPlayer.getMoney(), position = xPlayer.getCoords(true), meta = xPlayer.getMeta()})
|
||||
end)
|
||||
|
||||
ESX.RegisterServerCallback('esx:getPlayerNames', function(source, cb, players)
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
local serverCallbacks = {}
|
||||
|
||||
local clientRequests = {}
|
||||
local RequestId = 0
|
||||
|
||||
---@param eventName string
|
||||
---@param callback function
|
||||
ESX.RegisterServerCallback = function(eventName, callback)
|
||||
serverCallbacks[eventName] = callback
|
||||
end
|
||||
|
||||
RegisterNetEvent('esx:triggerServerCallback', function(eventName, requestId, invoker, ...)
|
||||
if not serverCallbacks[eventName] then
|
||||
return print(('[^1ERROR^7] Server Callback not registered, name: ^5%s^7, invoker resource: ^5%s^7'):format(eventName, invoker))
|
||||
end
|
||||
|
||||
local source = source
|
||||
|
||||
serverCallbacks[eventName](source, function(...)
|
||||
TriggerClientEvent('esx:serverCallback', source, requestId, invoker, ...)
|
||||
end, ...)
|
||||
end)
|
||||
|
||||
---@param player number playerId
|
||||
---@param eventName string
|
||||
---@param callback function
|
||||
---@param ... any
|
||||
ESX.TriggerClientCallback = function(player, eventName, callback, ...)
|
||||
clientRequests[RequestId] = callback
|
||||
|
||||
TriggerClientEvent('esx:triggerClientCallback', player, eventName, RequestId, GetInvokingResource() or "unknown", ...)
|
||||
|
||||
RequestId = RequestId + 1
|
||||
end
|
||||
|
||||
RegisterNetEvent('esx:clientCallback', function(requestId, invoker, ...)
|
||||
if not clientRequests[requestId] then
|
||||
return print(('[^1ERROR^7] Client Callback with requestId ^5%s^7 Was Called by ^5%s^7 but does not exist.'):format(requestId, invoker))
|
||||
end
|
||||
|
||||
clientRequests[requestId](...)
|
||||
clientRequests[requestId] = nil
|
||||
end)
|
||||
@@ -4,7 +4,7 @@ game 'gta5'
|
||||
author 'ESX-Framework & Brayden'
|
||||
description 'Offical ESX Legacy Context Menu'
|
||||
lua54 'yes'
|
||||
version '1.9.3'
|
||||
version '1.9.4'
|
||||
|
||||
ui_page 'index.html'
|
||||
|
||||
|
||||
+459
-440
@@ -1,443 +1,462 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<script src="nui://game/ui/jquery.js" type="text/javascript"></script>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.13.0/css/all.min.css">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/all.min.css">
|
||||
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>ESX Context HUD</title>
|
||||
|
||||
<style type="text/css">
|
||||
:root {
|
||||
--item-main: #242424;
|
||||
--item-unselectable: #161616;
|
||||
--item-hover: #404040;
|
||||
--item-disabled: #393939;
|
||||
}
|
||||
|
||||
html,
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
outline: none;
|
||||
border: none;
|
||||
}
|
||||
|
||||
body {
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
display: none;
|
||||
}
|
||||
|
||||
#container {
|
||||
position: absolute;
|
||||
width: 280px;
|
||||
max-height: 50%;
|
||||
height: auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
overflow-y: auto;
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
.center {
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
.left {
|
||||
top: 50%;
|
||||
left: 25%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
.right {
|
||||
top: 50%;
|
||||
left: 75%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
.item {
|
||||
display: grid;
|
||||
grid-template-columns: 30px calc(100% - 30px);
|
||||
padding: 15px 10px;
|
||||
border-radius: 5px;
|
||||
background: var(--item-main);
|
||||
}
|
||||
|
||||
.item:hover {
|
||||
background: var(--item-hover);
|
||||
}
|
||||
|
||||
.item>i {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.item>div {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 5px;
|
||||
}
|
||||
|
||||
.item>div>i {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.input {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 5px;
|
||||
padding: 15px 10px;
|
||||
border-radius: 5px;
|
||||
background: var(--item-main);
|
||||
}
|
||||
|
||||
.input:hover {
|
||||
background: var(--item-hover);
|
||||
}
|
||||
|
||||
input {
|
||||
position: relative;
|
||||
width: auto;
|
||||
padding: 5px;
|
||||
margin: 0;
|
||||
border: none;
|
||||
border: none;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.unselectable {
|
||||
background: var(--item-unselectable);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.disabled {
|
||||
pointer-events: none;
|
||||
background: var(--item-disabled);
|
||||
}
|
||||
|
||||
* {
|
||||
color: white;
|
||||
font-family: Arial;
|
||||
user-select: none;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: 5px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: rgb(20, 20, 20);
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background: rgb(30, 30, 30);
|
||||
}
|
||||
|
||||
.container {
|
||||
display: flex;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
flex-direction: row-reverse;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
gap: 5px;
|
||||
}
|
||||
|
||||
/* Hide the browser's default checkbox */
|
||||
.container input {
|
||||
position: relative;
|
||||
opacity: 0;
|
||||
cursor: pointer;
|
||||
height: 0;
|
||||
width: 0;
|
||||
}
|
||||
|
||||
/* Create a custom checkbox */
|
||||
.checkmark {
|
||||
position: relative;
|
||||
height: 10px;
|
||||
width: 10px;
|
||||
border-radius: 8px;
|
||||
background-color: #eee;
|
||||
}
|
||||
|
||||
/* On mouse-over, add a grey background color */
|
||||
.container:hover input~.checkmark {
|
||||
background-color: #ccc;
|
||||
}
|
||||
|
||||
/* When the checkbox is checked, add a blue background */
|
||||
.container input:checked~.checkmark {
|
||||
background-color: #2196F3;
|
||||
}
|
||||
|
||||
/* Create the checkmark/indicator (hidden when not checked) */
|
||||
.checkmark:after {
|
||||
content: "";
|
||||
position: relative;
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Show the checkmark when checked */
|
||||
.container input:checked~.checkmark:after {
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div id="container" class="right">
|
||||
<div class="item unselectable">
|
||||
<i class="fas fa-info-circle"></i>
|
||||
<div>
|
||||
<b>Unselectable Item</b>
|
||||
<i>Testing, testing a description here.</i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item disabled">
|
||||
<i class="fas fa-times"></i>
|
||||
<div>
|
||||
<b>Disabled Item</b>
|
||||
<i>Testing, testing a description here.</i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<i class="fas fa-check"></i>
|
||||
<div>
|
||||
<b>Item</b>
|
||||
<i>Testing, testing a description here. Generic words to force overflow.</i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
const container = document.getElementById("container")
|
||||
|
||||
const CreateElement = (tag = "div", className = "", parent) => {
|
||||
const e = document.createElement(tag)
|
||||
e.className = className
|
||||
|
||||
if (parent) {
|
||||
parent.append(e)
|
||||
}
|
||||
|
||||
return e
|
||||
}
|
||||
|
||||
function Open(eles, position = "right") {
|
||||
container.innerHTML = ""
|
||||
container.className = position
|
||||
|
||||
for (let i = 0; i < eles.length; i++) {
|
||||
let ele = eles[i]
|
||||
let item = CreateElement("div", "item", container)
|
||||
|
||||
let icon = CreateElement("i", ele.icon, item)
|
||||
let div = CreateElement("div", "", item)
|
||||
|
||||
let title = CreateElement("b", "", div)
|
||||
title.innerHTML = ele.title
|
||||
|
||||
if (ele.description) {
|
||||
let desc = CreateElement("i", "", div)
|
||||
desc.innerHTML = ele.description || ""
|
||||
}
|
||||
|
||||
if (ele.input) {
|
||||
if (ele.inputType == "radio") {
|
||||
for (let j = 0; j < ele.inputValues.length; j++) {
|
||||
let v = ele.inputValues[j]
|
||||
let container = CreateElement("label", "container", div)
|
||||
container.innerHTML = v.text
|
||||
|
||||
let input = CreateElement("INPUT", "", container)
|
||||
input.type = "radio"
|
||||
input.name = i + 1
|
||||
input.checked = (ele.inputValue || ele.inputPlaceholder || -1) == v.value
|
||||
|
||||
let span = CreateElement("SPAN", "checkmark", container)
|
||||
|
||||
input.onchange = function () {
|
||||
$.post(`https://${GetParentResourceName()}/changed`, JSON.stringify({
|
||||
index: i + 1,
|
||||
value: v.value
|
||||
}))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let input = CreateElement("input", "", div)
|
||||
input.type = ele.inputType
|
||||
|
||||
if (ele.inputValue) {
|
||||
input.value = ele.inputValue
|
||||
}
|
||||
|
||||
if (ele.inputPlaceholder) {
|
||||
input.placeholder = ele.inputPlaceholder
|
||||
}
|
||||
|
||||
switch (ele.inputType) {
|
||||
case "number":
|
||||
if (ele.inputMin) input.min = ele.inputMin;
|
||||
if (ele.inputMax) input.max = ele.inputMax;
|
||||
|
||||
input.onchange = function () {
|
||||
let v = Number(input.value)
|
||||
|
||||
if (ele.inputMin) {
|
||||
v = Math.max(ele.inputMin, v)
|
||||
}
|
||||
|
||||
if (ele.inputMax) {
|
||||
v = Math.min(ele.inputMax, v)
|
||||
}
|
||||
|
||||
input.value = v
|
||||
|
||||
$.post(`https://${GetParentResourceName()}/changed`, JSON.stringify({
|
||||
index: i + 1,
|
||||
value: v
|
||||
}))
|
||||
}
|
||||
break
|
||||
|
||||
case "text":
|
||||
input.onchange = function () {
|
||||
$.post(`https://${GetParentResourceName()}/changed`, JSON.stringify({
|
||||
index: i + 1,
|
||||
value: input.value
|
||||
}))
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (ele.disabled) {
|
||||
item.className += " disabled"
|
||||
} else if (ele.unselectable) {
|
||||
item.className += " unselectable"
|
||||
} else if (!ele.input) {
|
||||
item.onclick = function () {
|
||||
$.post(`https://${GetParentResourceName()}/selected`, JSON.stringify({
|
||||
index: i + 1
|
||||
}))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
document.body.style.display = "block"
|
||||
}
|
||||
|
||||
function Closed() {
|
||||
document.body.style.display = "none"
|
||||
}
|
||||
|
||||
function Close() {
|
||||
$.post(`https://${GetParentResourceName()}/closed`,(retVal)=>{
|
||||
if(retVal){
|
||||
Closed()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
window.addEventListener("message", (e) => {
|
||||
let data = e.data
|
||||
|
||||
if (!data.func || !window[data.func]) {
|
||||
return
|
||||
}
|
||||
|
||||
window[data.func](...data.args)
|
||||
})
|
||||
|
||||
window.addEventListener("keydown", (e) => {
|
||||
if (e.key == "Escape" || e.key == "Backspace") {
|
||||
if (e.target.tagName.toLowerCase() == "input") {
|
||||
return
|
||||
}
|
||||
|
||||
Close()
|
||||
}
|
||||
})
|
||||
|
||||
// Open([
|
||||
// {
|
||||
// unselectable:true,
|
||||
// icon:"fas fa-info-circle",
|
||||
// title:"Unselectable Item (Header/Label?)",
|
||||
// },
|
||||
// {
|
||||
// icon:"fas fa-check",
|
||||
// title:"Item A",
|
||||
// description:"Some description here. Add some words to make the text overflow."
|
||||
// },
|
||||
// {
|
||||
// disabled:true,
|
||||
// icon:"fas fa-times",
|
||||
// title:"Disabled Item",
|
||||
// description:"Some description here. Add some words to make the text overflow."
|
||||
// },
|
||||
// {
|
||||
// icon:"fas fa-check",
|
||||
// title:"Item B",
|
||||
// description:"Some description here. Add some words to make the text overflow."
|
||||
// },
|
||||
// {
|
||||
// input:true,
|
||||
// icon:"fas fa-times",
|
||||
// title:"Input Text",
|
||||
// inputType:"text",
|
||||
// inputPlaceholder:"Placeholder..."
|
||||
// },
|
||||
// {
|
||||
// input:true,
|
||||
// icon:"",
|
||||
// title:"Input Number",
|
||||
// inputType:"number",
|
||||
// inputPlaceholder:"Placeholder...",
|
||||
// inputValue:0,
|
||||
// inputMin:0,
|
||||
// inputMax:50
|
||||
// },
|
||||
// {
|
||||
// input:true,
|
||||
// icon:"",
|
||||
// title:"Input Radio",
|
||||
// inputType:"radio",
|
||||
// inputPlaceholder:"turbocharger",
|
||||
// inputValue:"supercharger",
|
||||
// inputValues:[
|
||||
// {
|
||||
// value:"turbocharger",
|
||||
// title:"Turbocharger"
|
||||
// },
|
||||
// {
|
||||
// value:"supercharger",
|
||||
// title:"Supercharger"
|
||||
// },
|
||||
// ]
|
||||
// }
|
||||
// ])
|
||||
</script>
|
||||
</body>
|
||||
|
||||
<head>
|
||||
<script src="nui://game/ui/jquery.js" type="text/javascript"></script>
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.13.0/css/all.min.css"
|
||||
/>
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/all.min.css"
|
||||
/>
|
||||
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>ESX Context HUD</title>
|
||||
|
||||
<style type="text/css">
|
||||
:root {
|
||||
--item-main: #242424;
|
||||
--item-unselectable: #161616;
|
||||
--item-hover: #404040;
|
||||
--item-disabled: #393939;
|
||||
}
|
||||
|
||||
html,
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
outline: none;
|
||||
border: none;
|
||||
}
|
||||
|
||||
body {
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
display: none;
|
||||
}
|
||||
|
||||
#container {
|
||||
position: absolute;
|
||||
width: 280px;
|
||||
max-height: 50%;
|
||||
height: auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
overflow-y: auto;
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
.center {
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
.left {
|
||||
top: 50%;
|
||||
left: 25%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
.right {
|
||||
top: 50%;
|
||||
left: 75%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
.item {
|
||||
display: grid;
|
||||
grid-template-columns: 30px calc(100% - 30px);
|
||||
padding: 15px 10px;
|
||||
border-radius: 5px;
|
||||
background: var(--item-main);
|
||||
}
|
||||
|
||||
.item:hover {
|
||||
background: var(--item-hover);
|
||||
}
|
||||
|
||||
.item > i {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.item > div {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 5px;
|
||||
}
|
||||
|
||||
.item > div > i {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.input {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 5px;
|
||||
padding: 15px 10px;
|
||||
border-radius: 5px;
|
||||
background: var(--item-main);
|
||||
}
|
||||
|
||||
.input:hover {
|
||||
background: var(--item-hover);
|
||||
}
|
||||
|
||||
input {
|
||||
position: relative;
|
||||
width: auto;
|
||||
padding: 5px;
|
||||
margin: 0;
|
||||
border: none;
|
||||
border: none;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.unselectable {
|
||||
background: var(--item-unselectable);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.disabled {
|
||||
pointer-events: none;
|
||||
background: var(--item-disabled);
|
||||
}
|
||||
|
||||
* {
|
||||
color: white;
|
||||
font-family: Arial;
|
||||
user-select: none;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: 5px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: rgb(20, 20, 20);
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background: rgb(30, 30, 30);
|
||||
}
|
||||
|
||||
.container {
|
||||
display: flex;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
flex-direction: row-reverse;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
gap: 5px;
|
||||
}
|
||||
|
||||
/* Hide the browser's default checkbox */
|
||||
.container input {
|
||||
position: relative;
|
||||
opacity: 0;
|
||||
cursor: pointer;
|
||||
height: 0;
|
||||
width: 0;
|
||||
}
|
||||
|
||||
/* Create a custom checkbox */
|
||||
.checkmark {
|
||||
position: relative;
|
||||
height: 10px;
|
||||
width: 10px;
|
||||
border-radius: 8px;
|
||||
background-color: #eee;
|
||||
}
|
||||
|
||||
/* On mouse-over, add a grey background color */
|
||||
.container:hover input ~ .checkmark {
|
||||
background-color: #ccc;
|
||||
}
|
||||
|
||||
/* When the checkbox is checked, add a blue background */
|
||||
.container input:checked ~ .checkmark {
|
||||
background-color: #2196f3;
|
||||
}
|
||||
|
||||
/* Create the checkmark/indicator (hidden when not checked) */
|
||||
.checkmark:after {
|
||||
content: "";
|
||||
position: relative;
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Show the checkmark when checked */
|
||||
.container input:checked ~ .checkmark:after {
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="container" class="right">
|
||||
<div class="item unselectable">
|
||||
<i class="fas fa-info-circle"></i>
|
||||
<div>
|
||||
<b>Unselectable Item</b>
|
||||
<i>Testing, testing a description here.</i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item disabled">
|
||||
<i class="fas fa-times"></i>
|
||||
<div>
|
||||
<b>Disabled Item</b>
|
||||
<i>Testing, testing a description here.</i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<i class="fas fa-check"></i>
|
||||
<div>
|
||||
<b>Item</b>
|
||||
<i
|
||||
>Testing, testing a description here. Generic words to force
|
||||
overflow.</i
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
const container = document.getElementById("container");
|
||||
|
||||
const CreateElement = (tag = "div", className = "", parent) => {
|
||||
const e = document.createElement(tag);
|
||||
e.className = className;
|
||||
|
||||
if (parent) {
|
||||
parent.append(e);
|
||||
}
|
||||
|
||||
return e;
|
||||
};
|
||||
|
||||
function Open(eles, position = "right") {
|
||||
container.innerHTML = "";
|
||||
container.className = position;
|
||||
|
||||
for (let i = 0; i < eles.length; i++) {
|
||||
let ele = eles[i];
|
||||
let item = CreateElement("div", "item", container);
|
||||
|
||||
let icon = CreateElement("i", ele.icon, item);
|
||||
let div = CreateElement("div", "", item);
|
||||
|
||||
let title = CreateElement("b", "", div);
|
||||
title.innerHTML = ele.title;
|
||||
|
||||
if (ele.description) {
|
||||
let desc = CreateElement("i", "", div);
|
||||
desc.innerHTML = ele.description || "";
|
||||
}
|
||||
|
||||
if (ele.input) {
|
||||
if (ele.inputType == "radio") {
|
||||
for (let j = 0; j < ele.inputValues.length; j++) {
|
||||
let v = ele.inputValues[j];
|
||||
let container = CreateElement("label", "container", div);
|
||||
container.innerHTML = v.text;
|
||||
|
||||
let input = CreateElement("INPUT", "", container);
|
||||
input.type = "radio";
|
||||
input.name = i + 1;
|
||||
input.checked =
|
||||
(ele.inputValue || ele.inputPlaceholder || -1) == v.value;
|
||||
|
||||
let span = CreateElement("SPAN", "checkmark", container);
|
||||
|
||||
input.onchange = function () {
|
||||
$.post(
|
||||
`https://${GetParentResourceName()}/changed`,
|
||||
JSON.stringify({
|
||||
index: i + 1,
|
||||
value: v.value,
|
||||
})
|
||||
);
|
||||
};
|
||||
}
|
||||
} else {
|
||||
let input = CreateElement("input", "", div);
|
||||
input.type = ele.inputType;
|
||||
|
||||
if (ele.inputValue) {
|
||||
input.value = ele.inputValue;
|
||||
}
|
||||
|
||||
if (ele.inputPlaceholder) {
|
||||
input.placeholder = ele.inputPlaceholder;
|
||||
}
|
||||
|
||||
switch (ele.inputType) {
|
||||
case "number":
|
||||
if (ele.inputMin) input.min = ele.inputMin;
|
||||
if (ele.inputMax) input.max = ele.inputMax;
|
||||
|
||||
input.onchange = function () {
|
||||
let v = Number(input.value);
|
||||
|
||||
if (ele.inputMin) {
|
||||
v = Math.max(ele.inputMin, v);
|
||||
}
|
||||
|
||||
if (ele.inputMax) {
|
||||
v = Math.min(ele.inputMax, v);
|
||||
}
|
||||
|
||||
input.value = v;
|
||||
|
||||
$.post(
|
||||
`https://${GetParentResourceName()}/changed`,
|
||||
JSON.stringify({
|
||||
index: i + 1,
|
||||
value: v,
|
||||
})
|
||||
);
|
||||
};
|
||||
break;
|
||||
|
||||
case "text":
|
||||
input.onchange = function () {
|
||||
$.post(
|
||||
`https://${GetParentResourceName()}/changed`,
|
||||
JSON.stringify({
|
||||
index: i + 1,
|
||||
value: input.value,
|
||||
})
|
||||
);
|
||||
};
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (ele.disabled) {
|
||||
item.className += " disabled";
|
||||
} else if (ele.unselectable) {
|
||||
item.className += " unselectable";
|
||||
} else if (!ele.input) {
|
||||
item.onclick = function () {
|
||||
$.post(
|
||||
`https://${GetParentResourceName()}/selected`,
|
||||
JSON.stringify({
|
||||
index: i + 1,
|
||||
})
|
||||
);
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
document.body.style.display = "block";
|
||||
}
|
||||
|
||||
function Closed() {
|
||||
document.body.style.display = "none";
|
||||
}
|
||||
|
||||
function Close() {
|
||||
$.post(`https://${GetParentResourceName()}/closed`, (retVal) => {
|
||||
if (retVal) {
|
||||
Closed();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
window.addEventListener("message", (e) => {
|
||||
let data = e.data;
|
||||
|
||||
if (!data.func || !window[data.func]) {
|
||||
return;
|
||||
}
|
||||
|
||||
window[data.func](...data.args);
|
||||
});
|
||||
|
||||
window.addEventListener("keydown", (e) => {
|
||||
if (e.key == "Escape" || e.key == "Backspace") {
|
||||
if (e.target.tagName.toLowerCase() == "input") {
|
||||
return;
|
||||
}
|
||||
|
||||
Close();
|
||||
}
|
||||
});
|
||||
|
||||
// Open([
|
||||
// {
|
||||
// unselectable:true,
|
||||
// icon:"fas fa-info-circle",
|
||||
// title:"Unselectable Item (Header/Label?)",
|
||||
// },
|
||||
// {
|
||||
// icon:"fas fa-check",
|
||||
// title:"Item A",
|
||||
// description:"Some description here. Add some words to make the text overflow."
|
||||
// },
|
||||
// {
|
||||
// disabled:true,
|
||||
// icon:"fas fa-times",
|
||||
// title:"Disabled Item",
|
||||
// description:"Some description here. Add some words to make the text overflow."
|
||||
// },
|
||||
// {
|
||||
// icon:"fas fa-check",
|
||||
// title:"Item B",
|
||||
// description:"Some description here. Add some words to make the text overflow."
|
||||
// },
|
||||
// {
|
||||
// input:true,
|
||||
// icon:"fas fa-times",
|
||||
// title:"Input Text",
|
||||
// inputType:"text",
|
||||
// inputPlaceholder:"Placeholder..."
|
||||
// },
|
||||
// {
|
||||
// input:true,
|
||||
// icon:"",
|
||||
// title:"Input Number",
|
||||
// inputType:"number",
|
||||
// inputPlaceholder:"Placeholder...",
|
||||
// inputValue:0,
|
||||
// inputMin:0,
|
||||
// inputMax:50
|
||||
// },
|
||||
// {
|
||||
// input:true,
|
||||
// icon:"",
|
||||
// title:"Input Radio",
|
||||
// inputType:"radio",
|
||||
// inputPlaceholder:"turbocharger",
|
||||
// inputValue:"supercharger",
|
||||
// inputValues:[
|
||||
// {
|
||||
// value:"turbocharger",
|
||||
// title:"Turbocharger"
|
||||
// },
|
||||
// {
|
||||
// value:"supercharger",
|
||||
// title:"Supercharger"
|
||||
// },
|
||||
// ]
|
||||
// }
|
||||
// ])
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -13,7 +13,7 @@ function Post(fn,...)
|
||||
end
|
||||
|
||||
function Open(position,eles,onSelect,onClose,canClose)
|
||||
local canClose = canClose == nil and true or canClose
|
||||
local canClose = canClose or true
|
||||
activeMenu = {
|
||||
position = position,
|
||||
eles = eles,
|
||||
|
||||
@@ -4,7 +4,7 @@ game 'gta5'
|
||||
|
||||
description 'ESX Identity'
|
||||
lua54 'yes'
|
||||
version '1.9.3'
|
||||
version '1.9.4'
|
||||
|
||||
shared_scripts {
|
||||
'@es_extended/imports.lua',
|
||||
|
||||
@@ -1,152 +1,152 @@
|
||||
@import url('https://fonts.googleapis.com/css2?family=Oswald&display=swap');
|
||||
@import url("https://fonts.googleapis.com/css2?family=Oswald&display=swap");
|
||||
|
||||
body {
|
||||
font-family: sans-serif;
|
||||
overflow: hidden;
|
||||
display: none;
|
||||
font-family: sans-serif;
|
||||
overflow: hidden;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.dialog {
|
||||
width: 332px;
|
||||
opacity : 0.95;
|
||||
position : absolute;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
top : 30.0%;
|
||||
padding: 20px;
|
||||
left : 50%; /* à 50%/50% du parent référent */
|
||||
transform : translate(-50%); /* décalage de 50% de sa propre taille */
|
||||
background-color: #152029;
|
||||
border-radius : 10px;
|
||||
box-shadow: 0 -5px 3px -3px #21303d, 0 5px 3px -3px #21303d;
|
||||
border:none;
|
||||
margin:5px;
|
||||
margin-bottom:20px;
|
||||
color: #ffffff;
|
||||
width: 332px;
|
||||
opacity: 0.95;
|
||||
position: absolute;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
top: 30%;
|
||||
padding: 20px;
|
||||
left: 50%; /* à 50%/50% du parent référent */
|
||||
transform: translate(-50%); /* décalage de 50% de sa propre taille */
|
||||
background-color: #152029;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 -5px 3px -3px #21303d, 0 5px 3px -3px #21303d;
|
||||
border: none;
|
||||
margin: 5px;
|
||||
margin-bottom: 20px;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-family: 'Oswald', sans-serif;
|
||||
font-size: 22px;
|
||||
text-align: center;
|
||||
padding: 5px;
|
||||
margin-bottom: 20px;
|
||||
font-family: "Oswald", sans-serif;
|
||||
font-size: 22px;
|
||||
text-align: center;
|
||||
padding: 5px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
input {
|
||||
margin-bottom: 15px;
|
||||
border: none;
|
||||
border-bottom: 2px solid #58636c;
|
||||
width: 100%;
|
||||
outline: none;
|
||||
padding: 10px;
|
||||
padding-left:0;
|
||||
font-family: 'Oswald', sans-serif;
|
||||
color: #ffffff;
|
||||
text-align:left;
|
||||
background-color: #152029;
|
||||
margin-bottom: 15px;
|
||||
border: none;
|
||||
border-bottom: 2px solid #58636c;
|
||||
width: 100%;
|
||||
outline: none;
|
||||
padding: 10px;
|
||||
padding-left: 0;
|
||||
font-family: "Oswald", sans-serif;
|
||||
color: #ffffff;
|
||||
text-align: left;
|
||||
background-color: #152029;
|
||||
}
|
||||
|
||||
::placeholder { /* Chrome, Firefox, Opera, Safari 10.1+ */
|
||||
color: rgba(84,97,105,255);
|
||||
font-family: 'Oswald', sans-serif;
|
||||
font-weight: 200;
|
||||
opacity: 1; /* Firefox */
|
||||
::placeholder {
|
||||
/* Chrome, Firefox, Opera, Safari 10.1+ */
|
||||
color: rgba(84, 97, 105, 255);
|
||||
font-family: "Oswald", sans-serif;
|
||||
font-weight: 200;
|
||||
opacity: 1; /* Firefox */
|
||||
}
|
||||
|
||||
.radio-toolbar input[type="radio"] {
|
||||
opacity: 0;
|
||||
position: absolute;
|
||||
width: 36%;
|
||||
opacity: 0;
|
||||
position: absolute;
|
||||
width: 36%;
|
||||
}
|
||||
|
||||
.radio-toolbar label {
|
||||
display: inline-block;
|
||||
margin-top: 5px;
|
||||
background-color: rgba(15,15,15,0.9);
|
||||
padding: 10px 20px;
|
||||
font-family: 'Oswald', sans-serif;
|
||||
font-weight: 500;
|
||||
font-size: 16px;
|
||||
color: #FFFFFF;
|
||||
border: none;
|
||||
border-radius: 5px;
|
||||
width: 36%;
|
||||
display: inline-block;
|
||||
margin-top: 5px;
|
||||
background-color: rgba(15, 15, 15, 0.9);
|
||||
padding: 10px 20px;
|
||||
font-family: "Oswald", sans-serif;
|
||||
font-weight: 500;
|
||||
font-size: 16px;
|
||||
color: #ffffff;
|
||||
border: none;
|
||||
border-radius: 5px;
|
||||
width: 36%;
|
||||
}
|
||||
|
||||
.radio-toolbar input[type="radio"]:checked + label {
|
||||
width: 36%;
|
||||
background-color:rgba(15,15,15,0.9);
|
||||
border: none;
|
||||
border-bottom: 1px solid #93a3b6;
|
||||
border-radius: 5px;
|
||||
color: #ffffff;
|
||||
width: 36%;
|
||||
background-color: rgba(15, 15, 15, 0.9);
|
||||
border: none;
|
||||
border-bottom: 1px solid #93a3b6;
|
||||
border-radius: 5px;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.radio-toolbar input[type="radio"]:focus + label {
|
||||
background-color:rgba(15,15,15,0.9);
|
||||
border: none;
|
||||
border-bottom: 1px solid #93a3b6;
|
||||
border-radius: 5px;
|
||||
color: #ffffff;
|
||||
background-color: rgba(15, 15, 15, 0.9);
|
||||
border: none;
|
||||
border-bottom: 1px solid #93a3b6;
|
||||
border-radius: 5px;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.radio-toolbar label:hover {
|
||||
background-color: rgba(28, 24, 24, 0.931);
|
||||
width: 36%;
|
||||
color: #ffffff;
|
||||
background-color: rgba(28, 24, 24, 0.931);
|
||||
width: 36%;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
button {
|
||||
display: block;
|
||||
margin-top: 35px;
|
||||
/*padding: 10px;*/
|
||||
background-color: #4569c6;
|
||||
outline: none;
|
||||
border: 2px double rgba(40, 40, 40, 0.9);
|
||||
color: #FFFFFF;
|
||||
height: 30px;
|
||||
width: 100%;
|
||||
display: block;
|
||||
margin-top: 35px;
|
||||
/*padding: 10px;*/
|
||||
background-color: #4569c6;
|
||||
outline: none;
|
||||
border: 2px double rgba(40, 40, 40, 0.9);
|
||||
color: #ffffff;
|
||||
height: 30px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
h1 {
|
||||
display: block;
|
||||
margin-top: 5px;
|
||||
margin-right: 5px;
|
||||
padding: 10px;
|
||||
background-color: rgba(15,15,15,0.9);
|
||||
color: #ffffff;
|
||||
width: 93%;
|
||||
text-align: center;
|
||||
display: block;
|
||||
margin-top: 5px;
|
||||
margin-right: 5px;
|
||||
padding: 10px;
|
||||
background-color: rgba(15, 15, 15, 0.9);
|
||||
color: #ffffff;
|
||||
width: 93%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.range-wrap {
|
||||
position: relative;
|
||||
margin: 0 auto 3rem;
|
||||
position: relative;
|
||||
margin: 0 auto 3rem;
|
||||
}
|
||||
|
||||
.range {
|
||||
width: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.bubble {
|
||||
background: rgba(15,15,15,0.9);
|
||||
color: #ffffff;
|
||||
padding: 4px 12px;
|
||||
position: absolute;
|
||||
border-radius: 4px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
background: rgba(15, 15, 15, 0.9);
|
||||
color: #ffffff;
|
||||
padding: 4px 12px;
|
||||
position: absolute;
|
||||
border-radius: 4px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
|
||||
|
||||
.bubble::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 2px;
|
||||
height: 2px;
|
||||
background: rgba(15,15,15,0.9);
|
||||
color: black;
|
||||
top: -1px;
|
||||
left: 50%;
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 2px;
|
||||
height: 2px;
|
||||
background: rgba(15, 15, 15, 0.9);
|
||||
color: black;
|
||||
top: -1px;
|
||||
left: 50%;
|
||||
}
|
||||
|
||||
@@ -1,45 +1,119 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<script src="nui://game/ui/jquery.js"></script>
|
||||
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
|
||||
<link href="css/style.css" rel="stylesheet">
|
||||
<head>
|
||||
<script src="nui://game/ui/jquery.js"></script>
|
||||
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
|
||||
<link href="css/style.css" rel="stylesheet" />
|
||||
|
||||
<title>ESX Identity</title>
|
||||
</head>
|
||||
<title>ESX Identity</title>
|
||||
</head>
|
||||
|
||||
<body onkeydown="TriggeredKey(this)">
|
||||
<div class="dialog">
|
||||
<div class="title"><b>IDENTITY</b></div>
|
||||
<form id="register" name="register" action="#">
|
||||
<div style="color: rgb(46, 187, 205);font-size: 12px; font-family: 'Gill Sans', sans-serif">First Name</div>
|
||||
<input id="firstname" type="text" class="" name="firstname" placeholder="First Name" minlength="3" maxlength="8" pattern="[a-zA-Z]*"><br>
|
||||
<div style="color: rgb(46, 187, 205);font-size: 12px; font-family: 'Gill Sans', sans-serif">Last Name</div>
|
||||
<input id="lastname" type="text" class="" name="lastname" placeholder="Last Name" minlength="3" maxlength="10" pattern="[a-zA-Z]*"><br>
|
||||
<div style="color: rgb(46, 187, 205);font-size: 12px; font-family: 'Gill Sans', sans-serif">Date of Birth (MM/DD/YYYY)</div>
|
||||
<input id="dateofbirth" type="date" name="dateofbirth" class="" min="1900-01-01" max="2010-01-01" onfocus="(this.type='date')"><br>
|
||||
<div style="color: rgb(46, 187, 205);font-size: 12px; font-family: 'Gill Sans', sans-serif">Height</div>
|
||||
<input id="height" type="number" class="" name="height" min="120" max="220" placeholder="Height (cm)"><br>
|
||||
<center>
|
||||
<div class="radio-toolbar">
|
||||
<input type="radio" id="radiom" name="sex" value="m" checked>
|
||||
<label for="radiom">Male</label>
|
||||
|
||||
<input type="radio" id="radiof" name="sex" value="f">
|
||||
<label for="radiof">Female</label>
|
||||
</div>
|
||||
</center>
|
||||
<button id="submit" type="submit"><font size="4px">CREATE</font></button>
|
||||
</form>
|
||||
<center><font size="1px" color="green">If the submit button doesn't work, please ensure that you've entered the fields correctly.</font></center>
|
||||
</div>
|
||||
<script>
|
||||
function TriggeredKey(e) {
|
||||
var keycode;
|
||||
if (window.event) keycode = window.event.keyCode;
|
||||
if (window.event.keyCode == 13 || window.event.keyCode == 27) return false;
|
||||
}
|
||||
</script>
|
||||
<script src="js/script.js"></script>
|
||||
</body>
|
||||
<body onkeydown="TriggeredKey(this)">
|
||||
<div class="dialog">
|
||||
<div class="title"><b>IDENTITY</b></div>
|
||||
<form id="register" name="register" action="#">
|
||||
<div
|
||||
style="
|
||||
color: rgb(46, 187, 205);
|
||||
font-size: 12px;
|
||||
font-family: 'Gill Sans', sans-serif;
|
||||
"
|
||||
>
|
||||
First Name
|
||||
</div>
|
||||
<input
|
||||
id="firstname"
|
||||
type="text"
|
||||
class=""
|
||||
name="firstname"
|
||||
placeholder="First Name"
|
||||
minlength="3"
|
||||
maxlength="8"
|
||||
pattern="[a-zA-Z]*"
|
||||
/><br />
|
||||
<div
|
||||
style="
|
||||
color: rgb(46, 187, 205);
|
||||
font-size: 12px;
|
||||
font-family: 'Gill Sans', sans-serif;
|
||||
"
|
||||
>
|
||||
Last Name
|
||||
</div>
|
||||
<input
|
||||
id="lastname"
|
||||
type="text"
|
||||
class=""
|
||||
name="lastname"
|
||||
placeholder="Last Name"
|
||||
minlength="3"
|
||||
maxlength="10"
|
||||
pattern="[a-zA-Z]*"
|
||||
/><br />
|
||||
<div
|
||||
style="
|
||||
color: rgb(46, 187, 205);
|
||||
font-size: 12px;
|
||||
font-family: 'Gill Sans', sans-serif;
|
||||
"
|
||||
>
|
||||
Date of Birth (MM/DD/YYYY)
|
||||
</div>
|
||||
<input
|
||||
id="dateofbirth"
|
||||
type="date"
|
||||
name="dateofbirth"
|
||||
class=""
|
||||
min="1900-01-01"
|
||||
max="2010-01-01"
|
||||
onfocus="(this.type='date')"
|
||||
/><br />
|
||||
<div
|
||||
style="
|
||||
color: rgb(46, 187, 205);
|
||||
font-size: 12px;
|
||||
font-family: 'Gill Sans', sans-serif;
|
||||
"
|
||||
>
|
||||
Height
|
||||
</div>
|
||||
<input
|
||||
id="height"
|
||||
type="number"
|
||||
class=""
|
||||
name="height"
|
||||
min="120"
|
||||
max="220"
|
||||
placeholder="Height (cm)"
|
||||
/><br />
|
||||
<center>
|
||||
<div class="radio-toolbar">
|
||||
<input type="radio" id="radiom" name="sex" value="m" checked />
|
||||
<label for="radiom">Male</label>
|
||||
|
||||
<input type="radio" id="radiof" name="sex" value="f" />
|
||||
<label for="radiof">Female</label>
|
||||
</div>
|
||||
</center>
|
||||
<button id="submit" type="submit">
|
||||
<font size="4px">CREATE</font>
|
||||
</button>
|
||||
</form>
|
||||
<center>
|
||||
<font size="1px" color="green"
|
||||
>If the submit button doesn't work, please ensure that you've entered
|
||||
the fields correctly.</font
|
||||
>
|
||||
</center>
|
||||
</div>
|
||||
<script>
|
||||
function TriggeredKey(e) {
|
||||
var keycode;
|
||||
if (window.event) keycode = window.event.keyCode;
|
||||
if (window.event.keyCode == 13 || window.event.keyCode == 27)
|
||||
return false;
|
||||
}
|
||||
</script>
|
||||
<script src="js/script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,37 +1,43 @@
|
||||
$(document).ready(function () {
|
||||
$.post('http://esx_identity/ready', JSON.stringify({}));
|
||||
$.post("http://esx_identity/ready", JSON.stringify({}));
|
||||
|
||||
window.addEventListener('message', function (event) {
|
||||
if (event.data.type === 'enableui') {
|
||||
window.addEventListener("message", function (event) {
|
||||
if (event.data.type === "enableui") {
|
||||
event.data.enable ? $(document.body).show() : $(document.body).hide();
|
||||
}
|
||||
});
|
||||
|
||||
$('#register').submit(function (event) {
|
||||
$("#register").submit(function (event) {
|
||||
event.preventDefault();
|
||||
|
||||
const dofVal = $('#dateofbirth').val();
|
||||
const dofVal = $("#dateofbirth").val();
|
||||
if (!dofVal) return;
|
||||
|
||||
const dateCheck = new Date(dofVal);
|
||||
|
||||
const year = new Intl.DateTimeFormat('en', { year: 'numeric' }).format(dateCheck);
|
||||
const month = new Intl.DateTimeFormat('en', { month: '2-digit' }).format(dateCheck);
|
||||
const day = new Intl.DateTimeFormat('en', { day: '2-digit' }).format(dateCheck);
|
||||
const year = new Intl.DateTimeFormat("en", { year: "numeric" }).format(
|
||||
dateCheck
|
||||
);
|
||||
const month = new Intl.DateTimeFormat("en", { month: "2-digit" }).format(
|
||||
dateCheck
|
||||
);
|
||||
const day = new Intl.DateTimeFormat("en", { day: "2-digit" }).format(
|
||||
dateCheck
|
||||
);
|
||||
|
||||
const formattedDate = `${day}/${month}/${year}`;
|
||||
|
||||
$.post(
|
||||
'http://esx_identity/register',
|
||||
"http://esx_identity/register",
|
||||
JSON.stringify({
|
||||
firstname: $('#firstname').val(),
|
||||
lastname: $('#lastname').val(),
|
||||
firstname: $("#firstname").val(),
|
||||
lastname: $("#lastname").val(),
|
||||
dateofbirth: formattedDate,
|
||||
sex: $("input[type='radio'][name='sex']:checked").val(),
|
||||
height: $('#height').val(),
|
||||
height: $("#height").val(),
|
||||
})
|
||||
);
|
||||
|
||||
$('#register').trigger('reset');
|
||||
$("#register").trigger("reset");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -8,7 +8,7 @@ Locales['nl'] = {
|
||||
['thank_you_for_registering'] = 'Succesvol geregistreerd!',
|
||||
['debug_xPlayer_get_first_name'] = 'Stuurt je Voornaam',
|
||||
['debug_xPlayer_get_last_name'] = 'Stuurt je Achternaam',
|
||||
['debug_xPlayer_get_full_name'] = 'Stuurt je volle naam',
|
||||
['debug_xPlayer_get_full_name'] = 'Stuurt je volledige naam',
|
||||
['debug_xPlayer_get_sex'] = 'Stuurt je Geslacht',
|
||||
['debug_xPlayer_get_dob'] = 'Stuurt je Geboortedatum ',
|
||||
['debug_xPlayer_get_height'] = 'Stuurt je lengte',
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
game 'common'
|
||||
version '1.9.3'
|
||||
version '1.9.4'
|
||||
fx_version 'cerulean'
|
||||
author 'ESX-Framework'
|
||||
lua54 'yes'
|
||||
|
||||
@@ -4,7 +4,7 @@ game 'gta5'
|
||||
|
||||
description 'ESX Menu Default'
|
||||
lua54 'yes'
|
||||
version '1.9.3'
|
||||
version '1.9.4'
|
||||
|
||||
client_scripts {'@es_extended/imports.lua', 'client/main.lua'}
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@500;600&display=swap');
|
||||
@import url("https://fonts.googleapis.com/css2?family=Poppins:wght@500;600&display=swap");
|
||||
|
||||
::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.menu {
|
||||
font-family: 'Poppins', sans-serif;
|
||||
font-family: "Poppins", sans-serif;
|
||||
min-width: 350px;
|
||||
color: #fff;
|
||||
position: absolute;
|
||||
|
||||
@@ -1,378 +1,378 @@
|
||||
;(function () {
|
||||
(function () {
|
||||
let MenuTpl =
|
||||
'<div id="menu_{{_namespace}}_{{_name}}" class="menu{{#align}} align-{{align}}{{/align}}">' +
|
||||
'<div class="head"><span>{{{title}}}</span></div>' +
|
||||
'<div class="menu-items">' +
|
||||
'{{#elements}}' +
|
||||
"{{#elements}}" +
|
||||
'<div class="menu-item {{#selected}}selected{{/selected}}">' +
|
||||
'{{{label}}}{{#isSlider}} : <{{{sliderLabel}}}>{{/isSlider}}' +
|
||||
'</div>' +
|
||||
'{{/elements}}' +
|
||||
'</div>' +
|
||||
'</div>' +
|
||||
'</div>'
|
||||
window.ESX_MENU = {}
|
||||
ESX_MENU.ResourceName = 'esx_menu_default'
|
||||
ESX_MENU.opened = {}
|
||||
ESX_MENU.focus = []
|
||||
ESX_MENU.pos = {}
|
||||
"{{{label}}}{{#isSlider}} : <{{{sliderLabel}}}>{{/isSlider}}" +
|
||||
"</div>" +
|
||||
"{{/elements}}" +
|
||||
"</div>" +
|
||||
"</div>" +
|
||||
"</div>";
|
||||
window.ESX_MENU = {};
|
||||
ESX_MENU.ResourceName = "esx_menu_default";
|
||||
ESX_MENU.opened = {};
|
||||
ESX_MENU.focus = [];
|
||||
ESX_MENU.pos = {};
|
||||
|
||||
ESX_MENU.open = function (namespace, name, data) {
|
||||
if (typeof ESX_MENU.opened[namespace] == 'undefined') {
|
||||
ESX_MENU.opened[namespace] = {}
|
||||
if (typeof ESX_MENU.opened[namespace] == "undefined") {
|
||||
ESX_MENU.opened[namespace] = {};
|
||||
}
|
||||
|
||||
if (typeof ESX_MENU.opened[namespace][name] != 'undefined') {
|
||||
ESX_MENU.close(namespace, name)
|
||||
if (typeof ESX_MENU.opened[namespace][name] != "undefined") {
|
||||
ESX_MENU.close(namespace, name);
|
||||
}
|
||||
|
||||
if (typeof ESX_MENU.pos[namespace] == 'undefined') {
|
||||
ESX_MENU.pos[namespace] = {}
|
||||
if (typeof ESX_MENU.pos[namespace] == "undefined") {
|
||||
ESX_MENU.pos[namespace] = {};
|
||||
}
|
||||
|
||||
for (let i = 0; i < data.elements.length; i++) {
|
||||
if (typeof data.elements[i].type == 'undefined') {
|
||||
data.elements[i].type = 'default'
|
||||
if (typeof data.elements[i].type == "undefined") {
|
||||
data.elements[i].type = "default";
|
||||
}
|
||||
}
|
||||
|
||||
data._index = ESX_MENU.focus.length
|
||||
data._namespace = namespace
|
||||
data._name = name
|
||||
data._index = ESX_MENU.focus.length;
|
||||
data._namespace = namespace;
|
||||
data._name = name;
|
||||
|
||||
for (let i = 0; i < data.elements.length; i++) {
|
||||
data.elements[i]._namespace = namespace
|
||||
data.elements[i]._name = name
|
||||
data.elements[i]._namespace = namespace;
|
||||
data.elements[i]._name = name;
|
||||
}
|
||||
|
||||
ESX_MENU.opened[namespace][name] = data
|
||||
ESX_MENU.pos[namespace][name] = 0
|
||||
ESX_MENU.opened[namespace][name] = data;
|
||||
ESX_MENU.pos[namespace][name] = 0;
|
||||
|
||||
for (let i = 0; i < data.elements.length; i++) {
|
||||
if (data.elements[i].selected) {
|
||||
ESX_MENU.pos[namespace][name] = i
|
||||
ESX_MENU.pos[namespace][name] = i;
|
||||
} else {
|
||||
data.elements[i].selected = false
|
||||
data.elements[i].selected = false;
|
||||
}
|
||||
}
|
||||
|
||||
ESX_MENU.focus.push({
|
||||
namespace: namespace,
|
||||
name: name
|
||||
})
|
||||
name: name,
|
||||
});
|
||||
|
||||
ESX_MENU.render()
|
||||
$('#menu_' + namespace + '_' + name)
|
||||
.find('.menu-item.selected')[0]
|
||||
.scrollIntoView()
|
||||
}
|
||||
ESX_MENU.render();
|
||||
$("#menu_" + namespace + "_" + name)
|
||||
.find(".menu-item.selected")[0]
|
||||
.scrollIntoView();
|
||||
};
|
||||
|
||||
ESX_MENU.close = function (namespace, name) {
|
||||
delete ESX_MENU.opened[namespace][name]
|
||||
delete ESX_MENU.opened[namespace][name];
|
||||
|
||||
for (let i = 0; i < ESX_MENU.focus.length; i++) {
|
||||
if (
|
||||
ESX_MENU.focus[i].namespace == namespace &&
|
||||
ESX_MENU.focus[i].name == name
|
||||
) {
|
||||
ESX_MENU.focus.splice(i, 1)
|
||||
break
|
||||
ESX_MENU.focus.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ESX_MENU.render()
|
||||
}
|
||||
ESX_MENU.render();
|
||||
};
|
||||
|
||||
ESX_MENU.render = function () {
|
||||
let menuContainer = document.getElementById('menus')
|
||||
let focused = ESX_MENU.getFocused()
|
||||
menuContainer.innerHTML = ''
|
||||
$(menuContainer).hide()
|
||||
let menuContainer = document.getElementById("menus");
|
||||
let focused = ESX_MENU.getFocused();
|
||||
menuContainer.innerHTML = "";
|
||||
$(menuContainer).hide();
|
||||
|
||||
for (let namespace in ESX_MENU.opened) {
|
||||
for (let name in ESX_MENU.opened[namespace]) {
|
||||
let menuData = ESX_MENU.opened[namespace][name]
|
||||
let view = JSON.parse(JSON.stringify(menuData))
|
||||
let menuData = ESX_MENU.opened[namespace][name];
|
||||
let view = JSON.parse(JSON.stringify(menuData));
|
||||
|
||||
for (let i = 0; i < menuData.elements.length; i++) {
|
||||
let element = view.elements[i]
|
||||
let element = view.elements[i];
|
||||
|
||||
switch (element.type) {
|
||||
case 'default':
|
||||
break
|
||||
case "default":
|
||||
break;
|
||||
|
||||
case 'slider': {
|
||||
element.isSlider = true
|
||||
case "slider": {
|
||||
element.isSlider = true;
|
||||
element.sliderLabel =
|
||||
typeof element.options == 'undefined'
|
||||
typeof element.options == "undefined"
|
||||
? element.value
|
||||
: element.options[element.value]
|
||||
: element.options[element.value];
|
||||
|
||||
break
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == ESX_MENU.pos[namespace][name]) {
|
||||
element.selected = true
|
||||
element.selected = true;
|
||||
}
|
||||
}
|
||||
|
||||
let menu = $(Mustache.render(MenuTpl, view))[0]
|
||||
$(menu).hide()
|
||||
menuContainer.appendChild(menu)
|
||||
let menu = $(Mustache.render(MenuTpl, view))[0];
|
||||
$(menu).hide();
|
||||
menuContainer.appendChild(menu);
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof focused != 'undefined') {
|
||||
$('#menu_' + focused.namespace + '_' + focused.name).show()
|
||||
if (typeof focused != "undefined") {
|
||||
$("#menu_" + focused.namespace + "_" + focused.name).show();
|
||||
}
|
||||
|
||||
$(menuContainer).show()
|
||||
}
|
||||
$(menuContainer).show();
|
||||
};
|
||||
|
||||
ESX_MENU.submit = function (namespace, name, data) {
|
||||
$.post(
|
||||
'http://' + ESX_MENU.ResourceName + '/menu_submit',
|
||||
"http://" + ESX_MENU.ResourceName + "/menu_submit",
|
||||
JSON.stringify({
|
||||
_namespace: namespace,
|
||||
_name: name,
|
||||
current: data,
|
||||
elements: ESX_MENU.opened[namespace][name].elements
|
||||
elements: ESX_MENU.opened[namespace][name].elements,
|
||||
})
|
||||
)
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
ESX_MENU.cancel = function (namespace, name) {
|
||||
$.post(
|
||||
'http://' + ESX_MENU.ResourceName + '/menu_cancel',
|
||||
"http://" + ESX_MENU.ResourceName + "/menu_cancel",
|
||||
JSON.stringify({
|
||||
_namespace: namespace,
|
||||
_name: name
|
||||
_name: name,
|
||||
})
|
||||
)
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
ESX_MENU.change = function (namespace, name, data) {
|
||||
$.post(
|
||||
'http://' + ESX_MENU.ResourceName + '/menu_change',
|
||||
"http://" + ESX_MENU.ResourceName + "/menu_change",
|
||||
JSON.stringify({
|
||||
_namespace: namespace,
|
||||
_name: name,
|
||||
current: data,
|
||||
elements: ESX_MENU.opened[namespace][name].elements
|
||||
elements: ESX_MENU.opened[namespace][name].elements,
|
||||
})
|
||||
)
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
ESX_MENU.getFocused = function () {
|
||||
return ESX_MENU.focus[ESX_MENU.focus.length - 1]
|
||||
}
|
||||
return ESX_MENU.focus[ESX_MENU.focus.length - 1];
|
||||
};
|
||||
|
||||
window.onData = data => {
|
||||
window.onData = (data) => {
|
||||
switch (data.action) {
|
||||
case 'openMenu': {
|
||||
ESX_MENU.open(data.namespace, data.name, data.data)
|
||||
break
|
||||
case "openMenu": {
|
||||
ESX_MENU.open(data.namespace, data.name, data.data);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'closeMenu': {
|
||||
ESX_MENU.close(data.namespace, data.name)
|
||||
break
|
||||
case "closeMenu": {
|
||||
ESX_MENU.close(data.namespace, data.name);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'controlPressed': {
|
||||
case "controlPressed": {
|
||||
switch (data.control) {
|
||||
case 'ENTER': {
|
||||
let focused = ESX_MENU.getFocused()
|
||||
case "ENTER": {
|
||||
let focused = ESX_MENU.getFocused();
|
||||
|
||||
if (typeof focused != 'undefined') {
|
||||
let menu = ESX_MENU.opened[focused.namespace][focused.name]
|
||||
let pos = ESX_MENU.pos[focused.namespace][focused.name]
|
||||
let elem = menu.elements[pos]
|
||||
if (typeof focused != "undefined") {
|
||||
let menu = ESX_MENU.opened[focused.namespace][focused.name];
|
||||
let pos = ESX_MENU.pos[focused.namespace][focused.name];
|
||||
let elem = menu.elements[pos];
|
||||
|
||||
if (menu.elements.length > 0) {
|
||||
ESX_MENU.submit(focused.namespace, focused.name, elem)
|
||||
ESX_MENU.submit(focused.namespace, focused.name, elem);
|
||||
}
|
||||
}
|
||||
|
||||
break
|
||||
break;
|
||||
}
|
||||
|
||||
case 'BACKSPACE': {
|
||||
let focused = ESX_MENU.getFocused()
|
||||
case "BACKSPACE": {
|
||||
let focused = ESX_MENU.getFocused();
|
||||
|
||||
if (typeof focused != 'undefined') {
|
||||
ESX_MENU.cancel(focused.namespace, focused.name)
|
||||
if (typeof focused != "undefined") {
|
||||
ESX_MENU.cancel(focused.namespace, focused.name);
|
||||
}
|
||||
|
||||
break
|
||||
break;
|
||||
}
|
||||
|
||||
case 'TOP': {
|
||||
let focused = ESX_MENU.getFocused()
|
||||
case "TOP": {
|
||||
let focused = ESX_MENU.getFocused();
|
||||
|
||||
if (typeof focused != 'undefined') {
|
||||
let menu = ESX_MENU.opened[focused.namespace][focused.name]
|
||||
let pos = ESX_MENU.pos[focused.namespace][focused.name]
|
||||
if (typeof focused != "undefined") {
|
||||
let menu = ESX_MENU.opened[focused.namespace][focused.name];
|
||||
let pos = ESX_MENU.pos[focused.namespace][focused.name];
|
||||
|
||||
if (pos > 0) {
|
||||
ESX_MENU.pos[focused.namespace][focused.name]--
|
||||
ESX_MENU.pos[focused.namespace][focused.name]--;
|
||||
} else {
|
||||
ESX_MENU.pos[focused.namespace][focused.name] =
|
||||
menu.elements.length - 1
|
||||
menu.elements.length - 1;
|
||||
}
|
||||
|
||||
let elem =
|
||||
menu.elements[ESX_MENU.pos[focused.namespace][focused.name]]
|
||||
menu.elements[ESX_MENU.pos[focused.namespace][focused.name]];
|
||||
|
||||
for (let i = 0; i < menu.elements.length; i++) {
|
||||
if (i == ESX_MENU.pos[focused.namespace][focused.name]) {
|
||||
menu.elements[i].selected = true
|
||||
menu.elements[i].selected = true;
|
||||
} else {
|
||||
menu.elements[i].selected = false
|
||||
menu.elements[i].selected = false;
|
||||
}
|
||||
}
|
||||
|
||||
ESX_MENU.change(focused.namespace, focused.name, elem)
|
||||
ESX_MENU.render()
|
||||
ESX_MENU.change(focused.namespace, focused.name, elem);
|
||||
ESX_MENU.render();
|
||||
|
||||
$('#menu_' + focused.namespace + '_' + focused.name)
|
||||
.find('.menu-item.selected')[0]
|
||||
.scrollIntoView()
|
||||
$("#menu_" + focused.namespace + "_" + focused.name)
|
||||
.find(".menu-item.selected")[0]
|
||||
.scrollIntoView();
|
||||
}
|
||||
|
||||
break
|
||||
break;
|
||||
}
|
||||
|
||||
case 'DOWN': {
|
||||
let focused = ESX_MENU.getFocused()
|
||||
case "DOWN": {
|
||||
let focused = ESX_MENU.getFocused();
|
||||
|
||||
if (typeof focused != 'undefined') {
|
||||
let menu = ESX_MENU.opened[focused.namespace][focused.name]
|
||||
let pos = ESX_MENU.pos[focused.namespace][focused.name]
|
||||
let length = menu.elements.length
|
||||
if (typeof focused != "undefined") {
|
||||
let menu = ESX_MENU.opened[focused.namespace][focused.name];
|
||||
let pos = ESX_MENU.pos[focused.namespace][focused.name];
|
||||
let length = menu.elements.length;
|
||||
|
||||
if (pos < length - 1) {
|
||||
ESX_MENU.pos[focused.namespace][focused.name]++
|
||||
ESX_MENU.pos[focused.namespace][focused.name]++;
|
||||
} else {
|
||||
ESX_MENU.pos[focused.namespace][focused.name] = 0
|
||||
ESX_MENU.pos[focused.namespace][focused.name] = 0;
|
||||
}
|
||||
|
||||
let elem =
|
||||
menu.elements[ESX_MENU.pos[focused.namespace][focused.name]]
|
||||
menu.elements[ESX_MENU.pos[focused.namespace][focused.name]];
|
||||
|
||||
for (let i = 0; i < menu.elements.length; i++) {
|
||||
if (i == ESX_MENU.pos[focused.namespace][focused.name]) {
|
||||
menu.elements[i].selected = true
|
||||
menu.elements[i].selected = true;
|
||||
} else {
|
||||
menu.elements[i].selected = false
|
||||
menu.elements[i].selected = false;
|
||||
}
|
||||
}
|
||||
|
||||
ESX_MENU.change(focused.namespace, focused.name, elem)
|
||||
ESX_MENU.render()
|
||||
ESX_MENU.change(focused.namespace, focused.name, elem);
|
||||
ESX_MENU.render();
|
||||
|
||||
$('#menu_' + focused.namespace + '_' + focused.name)
|
||||
.find('.menu-item.selected')[0]
|
||||
.scrollIntoView()
|
||||
$("#menu_" + focused.namespace + "_" + focused.name)
|
||||
.find(".menu-item.selected")[0]
|
||||
.scrollIntoView();
|
||||
}
|
||||
|
||||
break
|
||||
break;
|
||||
}
|
||||
|
||||
case 'LEFT': {
|
||||
let focused = ESX_MENU.getFocused()
|
||||
case "LEFT": {
|
||||
let focused = ESX_MENU.getFocused();
|
||||
|
||||
if (typeof focused != 'undefined') {
|
||||
let menu = ESX_MENU.opened[focused.namespace][focused.name]
|
||||
let pos = ESX_MENU.pos[focused.namespace][focused.name]
|
||||
let elem = menu.elements[pos]
|
||||
if (typeof focused != "undefined") {
|
||||
let menu = ESX_MENU.opened[focused.namespace][focused.name];
|
||||
let pos = ESX_MENU.pos[focused.namespace][focused.name];
|
||||
let elem = menu.elements[pos];
|
||||
|
||||
switch (elem.type) {
|
||||
case 'default':
|
||||
break
|
||||
case "default":
|
||||
break;
|
||||
|
||||
case 'slider': {
|
||||
let min = typeof elem.min == 'undefined' ? 0 : elem.min
|
||||
case "slider": {
|
||||
let min = typeof elem.min == "undefined" ? 0 : elem.min;
|
||||
|
||||
if (elem.value > min) {
|
||||
elem.value--
|
||||
ESX_MENU.change(focused.namespace, focused.name, elem)
|
||||
elem.value--;
|
||||
ESX_MENU.change(focused.namespace, focused.name, elem);
|
||||
}
|
||||
|
||||
ESX_MENU.render()
|
||||
break
|
||||
ESX_MENU.render();
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break
|
||||
break;
|
||||
}
|
||||
|
||||
$('#menu_' + focused.namespace + '_' + focused.name)
|
||||
.find('.menu-item.selected')[0]
|
||||
.scrollIntoView()
|
||||
$("#menu_" + focused.namespace + "_" + focused.name)
|
||||
.find(".menu-item.selected")[0]
|
||||
.scrollIntoView();
|
||||
}
|
||||
|
||||
break
|
||||
break;
|
||||
}
|
||||
|
||||
case 'RIGHT': {
|
||||
let focused = ESX_MENU.getFocused()
|
||||
case "RIGHT": {
|
||||
let focused = ESX_MENU.getFocused();
|
||||
|
||||
if (typeof focused != 'undefined') {
|
||||
let menu = ESX_MENU.opened[focused.namespace][focused.name]
|
||||
let pos = ESX_MENU.pos[focused.namespace][focused.name]
|
||||
let elem = menu.elements[pos]
|
||||
if (typeof focused != "undefined") {
|
||||
let menu = ESX_MENU.opened[focused.namespace][focused.name];
|
||||
let pos = ESX_MENU.pos[focused.namespace][focused.name];
|
||||
let elem = menu.elements[pos];
|
||||
|
||||
switch (elem.type) {
|
||||
case 'default':
|
||||
break
|
||||
case "default":
|
||||
break;
|
||||
|
||||
case 'slider': {
|
||||
case "slider": {
|
||||
if (
|
||||
typeof elem.options != 'undefined' &&
|
||||
typeof elem.options != "undefined" &&
|
||||
elem.value < elem.options.length - 1
|
||||
) {
|
||||
elem.value++
|
||||
ESX_MENU.change(focused.namespace, focused.name, elem)
|
||||
elem.value++;
|
||||
ESX_MENU.change(focused.namespace, focused.name, elem);
|
||||
}
|
||||
|
||||
if (typeof elem.max != 'undefined' && elem.value < elem.max) {
|
||||
elem.value++
|
||||
ESX_MENU.change(focused.namespace, focused.name, elem)
|
||||
if (typeof elem.max != "undefined" && elem.value < elem.max) {
|
||||
elem.value++;
|
||||
ESX_MENU.change(focused.namespace, focused.name, elem);
|
||||
}
|
||||
|
||||
ESX_MENU.render()
|
||||
break
|
||||
ESX_MENU.render();
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break
|
||||
break;
|
||||
}
|
||||
|
||||
$('#menu_' + focused.namespace + '_' + focused.name)
|
||||
.find('.menu-item.selected')[0]
|
||||
.scrollIntoView()
|
||||
$("#menu_" + focused.namespace + "_" + focused.name)
|
||||
.find(".menu-item.selected")[0]
|
||||
.scrollIntoView();
|
||||
}
|
||||
|
||||
break
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break
|
||||
break;
|
||||
}
|
||||
|
||||
break
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
window.onload = function (e) {
|
||||
window.addEventListener('message', event => {
|
||||
onData(event.data)
|
||||
})
|
||||
}
|
||||
})()
|
||||
window.addEventListener("message", (event) => {
|
||||
onData(event.data);
|
||||
});
|
||||
};
|
||||
})();
|
||||
|
||||
@@ -4,7 +4,7 @@ game 'gta5'
|
||||
|
||||
description 'ESX Menu Dialog'
|
||||
lua54 'yes'
|
||||
version '1.9.3'
|
||||
version '1.9.4'
|
||||
|
||||
client_scripts {
|
||||
'@es_extended/imports.lua',
|
||||
|
||||
@@ -1,89 +1,89 @@
|
||||
|
||||
@import url('https://fonts.googleapis.com/css?family=Montserrat&display=swap');
|
||||
@import url("https://fonts.googleapis.com/css?family=Montserrat&display=swap");
|
||||
|
||||
#controls {
|
||||
font-family: montserrat;
|
||||
font-size: 3em;
|
||||
color: #FFF;
|
||||
position: absolute;
|
||||
bottom: 40;
|
||||
right: 40;
|
||||
font-family: montserrat;
|
||||
font-size: 3em;
|
||||
color: #fff;
|
||||
position: absolute;
|
||||
bottom: 40;
|
||||
right: 40;
|
||||
}
|
||||
|
||||
.controls {
|
||||
display: none;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.dialog {
|
||||
font-family: montserrat;
|
||||
background: rgba(33, 33, 33, 0.8);
|
||||
font-family: montserrat;
|
||||
background: rgba(33, 33, 33, 0.8);
|
||||
color: #fff;
|
||||
position: absolute;
|
||||
border-top-left-radius: 5px;
|
||||
border-top-right-radius: 5px;
|
||||
overflow: hidden;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
width: 600px;
|
||||
height: 152px;
|
||||
transform: translate(-50%, -50%);
|
||||
position: absolute;
|
||||
border-top-left-radius: 5px;
|
||||
border-top-right-radius: 5px;
|
||||
overflow: hidden;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
width: 600px;
|
||||
height: 152px;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
.head {
|
||||
display: flex;
|
||||
flex-basis: 100%;
|
||||
align-items: center;
|
||||
color: #fff;
|
||||
display: flex;
|
||||
flex-basis: 100%;
|
||||
align-items: center;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.dialog.big {
|
||||
height: 200px;
|
||||
height: 200px;
|
||||
}
|
||||
|
||||
.dialog .head {
|
||||
background: rgba(25, 25, 25, 0.9);
|
||||
text-align: center;
|
||||
height: 40px;
|
||||
background: rgba(25, 25, 25, 0.9);
|
||||
text-align: center;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.dialog .head span::before {
|
||||
content: "";
|
||||
display: inline-block;
|
||||
height: 100%;
|
||||
vertical-align: middle;
|
||||
content: "";
|
||||
display: inline-block;
|
||||
height: 100%;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.dialog input[type="text"] {
|
||||
width: 60%;
|
||||
height: 32px;
|
||||
width: 60%;
|
||||
height: 32px;
|
||||
outline: 0;
|
||||
background: none;
|
||||
text-align: center;
|
||||
margin-top: 26px;
|
||||
margin-left: 125px;
|
||||
font-size: large;
|
||||
font-size: large;
|
||||
transition: all 0.2s ease-in-out;
|
||||
color: white;
|
||||
border: 0.5px solid #ffffff3b;
|
||||
border-radius: 0px;
|
||||
}
|
||||
|
||||
.dialog input[type="text"]:active, .dialog input[type="text"]:hover {
|
||||
.dialog input[type="text"]:active,
|
||||
.dialog input[type="text"]:hover {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.dialog textarea {
|
||||
width: 100%;
|
||||
height: 128px;
|
||||
width: 100%;
|
||||
height: 128px;
|
||||
}
|
||||
|
||||
.dialog button[name="submit"] {
|
||||
width: 17.6%;
|
||||
height: 32px;
|
||||
width: 17.6%;
|
||||
height: 32px;
|
||||
margin-left: 160px;
|
||||
font-weight: 300;
|
||||
color: rgb(37, 34, 53);
|
||||
border-radius: 10px;
|
||||
border-radius: 10px;
|
||||
text-transform: uppercase;
|
||||
background: rgb(50, 79, 208);
|
||||
outline: 0;
|
||||
@@ -93,17 +93,17 @@
|
||||
|
||||
.dialog button {
|
||||
z-index: 9999;
|
||||
transform: translate(-0%, 50%);
|
||||
transform: translate(-0%, 50%);
|
||||
}
|
||||
|
||||
.dialog button[name="cancel"] {
|
||||
width: 17.6%;
|
||||
height: 32px;
|
||||
width: 17.6%;
|
||||
height: 32px;
|
||||
margin-left: 60px;
|
||||
border: none;
|
||||
text-transform: uppercase;
|
||||
font-weight: 200;
|
||||
border-radius: 10px;
|
||||
border-radius: 10px;
|
||||
color: rgb(53, 34, 34);
|
||||
outline: 0;
|
||||
background: #c74545;
|
||||
@@ -124,9 +124,9 @@
|
||||
|
||||
.head::before,
|
||||
.head::after {
|
||||
content: "";
|
||||
flex-grow: 1;
|
||||
background: #00e1ff;
|
||||
height: 2px;
|
||||
margin: 0px 3px;
|
||||
content: "";
|
||||
flex-grow: 1;
|
||||
background: #00e1ff;
|
||||
height: 2px;
|
||||
margin: 0px 3px;
|
||||
}
|
||||
|
||||
@@ -1,170 +1,184 @@
|
||||
(function () {
|
||||
let MenuTpl =
|
||||
'<div id="menu_{{_namespace}}_{{_name}}" class="dialog {{#isBig}}big{{/isBig}}">' +
|
||||
'<div class="head"><span>{{title}}</span></div>' +
|
||||
'{{#isDefault}}<input type="text" name="value" id="inputText"/>{{/isDefault}}' +
|
||||
'{{#isBig}}<textarea name="value"/>{{/isBig}}' +
|
||||
'<button type="button" name="submit">Submit</button>' +
|
||||
'<button type="button" name="cancel">Cancel</button>' +
|
||||
'</div>' +
|
||||
'</div>'
|
||||
;
|
||||
let MenuTpl =
|
||||
'<div id="menu_{{_namespace}}_{{_name}}" class="dialog {{#isBig}}big{{/isBig}}">' +
|
||||
'<div class="head"><span>{{title}}</span></div>' +
|
||||
'{{#isDefault}}<input type="text" name="value" id="inputText"/>{{/isDefault}}' +
|
||||
'{{#isBig}}<textarea name="value"/>{{/isBig}}' +
|
||||
'<button type="button" name="submit">Submit</button>' +
|
||||
'<button type="button" name="cancel">Cancel</button>' +
|
||||
"</div>" +
|
||||
"</div>";
|
||||
window.ESX_MENU = {};
|
||||
ESX_MENU.ResourceName = "esx_menu_dialog";
|
||||
ESX_MENU.opened = {};
|
||||
ESX_MENU.focus = [];
|
||||
ESX_MENU.pos = {};
|
||||
|
||||
window.ESX_MENU = {};
|
||||
ESX_MENU.ResourceName = 'esx_menu_dialog';
|
||||
ESX_MENU.opened = {};
|
||||
ESX_MENU.focus = [];
|
||||
ESX_MENU.pos = {};
|
||||
ESX_MENU.open = function (namespace, name, data) {
|
||||
if (typeof ESX_MENU.opened[namespace] == "undefined") {
|
||||
ESX_MENU.opened[namespace] = {};
|
||||
}
|
||||
|
||||
ESX_MENU.open = function (namespace, name, data) {
|
||||
if (typeof ESX_MENU.opened[namespace] == 'undefined') {
|
||||
ESX_MENU.opened[namespace] = {};
|
||||
}
|
||||
if (typeof ESX_MENU.opened[namespace][name] != "undefined") {
|
||||
ESX_MENU.close(namespace, name);
|
||||
}
|
||||
|
||||
if (typeof ESX_MENU.opened[namespace][name] != 'undefined') {
|
||||
ESX_MENU.close(namespace, name);
|
||||
}
|
||||
if (typeof ESX_MENU.pos[namespace] == "undefined") {
|
||||
ESX_MENU.pos[namespace] = {};
|
||||
}
|
||||
|
||||
if (typeof ESX_MENU.pos[namespace] == 'undefined') {
|
||||
ESX_MENU.pos[namespace] = {};
|
||||
}
|
||||
if (typeof data.type == "undefined") {
|
||||
data.type = "default";
|
||||
}
|
||||
|
||||
if (typeof data.type == 'undefined') {
|
||||
data.type = 'default';
|
||||
}
|
||||
if (typeof data.align == "undefined") {
|
||||
data.align = "top-left";
|
||||
}
|
||||
|
||||
if (typeof data.align == 'undefined') {
|
||||
data.align = 'top-left';
|
||||
}
|
||||
data._index = ESX_MENU.focus.length;
|
||||
data._namespace = namespace;
|
||||
data._name = name;
|
||||
|
||||
data._index = ESX_MENU.focus.length;
|
||||
data._namespace = namespace;
|
||||
data._name = name;
|
||||
ESX_MENU.opened[namespace][name] = data;
|
||||
ESX_MENU.pos[namespace][name] = 0;
|
||||
|
||||
ESX_MENU.opened[namespace][name] = data;
|
||||
ESX_MENU.pos[namespace][name] = 0;
|
||||
ESX_MENU.focus.push({
|
||||
namespace: namespace,
|
||||
name: name,
|
||||
});
|
||||
|
||||
ESX_MENU.focus.push({
|
||||
namespace: namespace,
|
||||
name: name
|
||||
});
|
||||
document.onkeyup = function (key) {
|
||||
if (key.which == 27) {
|
||||
// Escape key
|
||||
SendMessage(ESX_MENU.ResourceName, "menu_cancel", data);
|
||||
} else if (key.which == 13) {
|
||||
// Enter key
|
||||
SendMessage(ESX_MENU.ResourceName, "menu_submit", data);
|
||||
}
|
||||
};
|
||||
|
||||
document.onkeyup = function (key) {
|
||||
if (key.which == 27) { // Escape key
|
||||
SendMessage(ESX_MENU.ResourceName, 'menu_cancel', data);
|
||||
} else if (key.which == 13) { // Enter key
|
||||
SendMessage(ESX_MENU.ResourceName, 'menu_submit', data);
|
||||
}
|
||||
};
|
||||
ESX_MENU.render();
|
||||
};
|
||||
|
||||
ESX_MENU.render();
|
||||
};
|
||||
ESX_MENU.close = function (namespace, name) {
|
||||
delete ESX_MENU.opened[namespace][name];
|
||||
|
||||
ESX_MENU.close = function (namespace, name) {
|
||||
delete ESX_MENU.opened[namespace][name];
|
||||
for (let i = 0; i < ESX_MENU.focus.length; i++) {
|
||||
if (
|
||||
ESX_MENU.focus[i].namespace == namespace &&
|
||||
ESX_MENU.focus[i].name == name
|
||||
) {
|
||||
ESX_MENU.focus.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (let i = 0; i < ESX_MENU.focus.length; i++) {
|
||||
if (ESX_MENU.focus[i].namespace == namespace && ESX_MENU.focus[i].name == name) {
|
||||
ESX_MENU.focus.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
ESX_MENU.render();
|
||||
};
|
||||
|
||||
ESX_MENU.render();
|
||||
};
|
||||
ESX_MENU.render = function () {
|
||||
let menuContainer = $("#menus")[0];
|
||||
$(menuContainer).find('button[name="submit"]').unbind("click");
|
||||
$(menuContainer).find('button[name="cancel"]').unbind("click");
|
||||
$(menuContainer).find('[name="value"]').unbind("input propertychange");
|
||||
menuContainer.innerHTML = "";
|
||||
$(menuContainer).hide();
|
||||
|
||||
ESX_MENU.render = function () {
|
||||
let menuContainer = $('#menus')[0];
|
||||
$(menuContainer).find('button[name="submit"]').unbind('click');
|
||||
$(menuContainer).find('button[name="cancel"]').unbind('click');
|
||||
$(menuContainer).find('[name="value"]').unbind('input propertychange');
|
||||
menuContainer.innerHTML = '';
|
||||
$(menuContainer).hide();
|
||||
for (let namespace in ESX_MENU.opened) {
|
||||
for (let name in ESX_MENU.opened[namespace]) {
|
||||
let menuData = ESX_MENU.opened[namespace][name];
|
||||
let view = JSON.parse(JSON.stringify(menuData));
|
||||
|
||||
for (let namespace in ESX_MENU.opened) {
|
||||
for (let name in ESX_MENU.opened[namespace]) {
|
||||
let menuData = ESX_MENU.opened[namespace][name];
|
||||
let view = JSON.parse(JSON.stringify(menuData));
|
||||
switch (menuData.type) {
|
||||
case "default": {
|
||||
view.isDefault = true;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (menuData.type) {
|
||||
case "big": {
|
||||
view.isBig = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case 'default': {
|
||||
view.isDefault = true;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
case 'big': {
|
||||
view.isBig = true;
|
||||
break;
|
||||
}
|
||||
let menu = $(Mustache.render(MenuTpl, view))[0];
|
||||
|
||||
default: break;
|
||||
}
|
||||
$(menu).css("z-index", 1000 + view._index);
|
||||
|
||||
let menu = $(Mustache.render(MenuTpl, view))[0];
|
||||
$(menu)
|
||||
.find('button[name="submit"]')
|
||||
.click(
|
||||
function () {
|
||||
ESX_MENU.submit(this.namespace, this.name, this.data);
|
||||
}.bind({ namespace: namespace, name: name, data: menuData })
|
||||
);
|
||||
|
||||
$(menu).css('z-index', 1000 + view._index);
|
||||
$(menu)
|
||||
.find('button[name="cancel"]')
|
||||
.click(
|
||||
function () {
|
||||
ESX_MENU.cancel(this.namespace, this.name, this.data);
|
||||
}.bind({ namespace: namespace, name: name, data: menuData })
|
||||
);
|
||||
|
||||
$(menu).find('button[name="submit"]').click(function () {
|
||||
ESX_MENU.submit(this.namespace, this.name, this.data);
|
||||
}.bind({ namespace: namespace, name: name, data: menuData }));
|
||||
$(menu)
|
||||
.find('[name="value"]')
|
||||
.bind(
|
||||
"input propertychange",
|
||||
function () {
|
||||
this.data.value = $(menu).find('[name="value"]').val();
|
||||
ESX_MENU.change(this.namespace, this.name, this.data);
|
||||
}.bind({ namespace: namespace, name: name, data: menuData })
|
||||
);
|
||||
|
||||
$(menu).find('button[name="cancel"]').click(function () {
|
||||
ESX_MENU.cancel(this.namespace, this.name, this.data);
|
||||
}.bind({ namespace: namespace, name: name, data: menuData }));
|
||||
if (typeof menuData.value != "undefined") {
|
||||
$(menu).find('[name="value"]').val(menuData.value);
|
||||
}
|
||||
|
||||
$(menu).find('[name="value"]').bind('input propertychange', function () {
|
||||
this.data.value = $(menu).find('[name="value"]').val();
|
||||
ESX_MENU.change(this.namespace, this.name, this.data);
|
||||
}.bind({ namespace: namespace, name: name, data: menuData }));
|
||||
menuContainer.appendChild(menu);
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof menuData.value != 'undefined') {
|
||||
$(menu).find('[name="value"]').val(menuData.value);
|
||||
}
|
||||
$(menuContainer).show();
|
||||
$("#inputText").focus();
|
||||
};
|
||||
|
||||
menuContainer.appendChild(menu);
|
||||
}
|
||||
}
|
||||
ESX_MENU.submit = function (namespace, name, data) {
|
||||
SendMessage(ESX_MENU.ResourceName, "menu_submit", data);
|
||||
};
|
||||
|
||||
$(menuContainer).show();
|
||||
$("#inputText").focus();
|
||||
};
|
||||
ESX_MENU.cancel = function (namespace, name, data) {
|
||||
SendMessage(ESX_MENU.ResourceName, "menu_cancel", data);
|
||||
};
|
||||
|
||||
ESX_MENU.submit = function (namespace, name, data) {
|
||||
SendMessage(ESX_MENU.ResourceName, 'menu_submit', data);
|
||||
};
|
||||
ESX_MENU.change = function (namespace, name, data) {
|
||||
SendMessage(ESX_MENU.ResourceName, "menu_change", data);
|
||||
};
|
||||
|
||||
ESX_MENU.cancel = function (namespace, name, data) {
|
||||
SendMessage(ESX_MENU.ResourceName, 'menu_cancel', data);
|
||||
};
|
||||
ESX_MENU.getFocused = function () {
|
||||
return ESX_MENU.focus[ESX_MENU.focus.length - 1];
|
||||
};
|
||||
|
||||
ESX_MENU.change = function (namespace, name, data) {
|
||||
SendMessage(ESX_MENU.ResourceName, 'menu_change', data);
|
||||
};
|
||||
window.onData = (data) => {
|
||||
switch (data.action) {
|
||||
case "openMenu": {
|
||||
ESX_MENU.open(data.namespace, data.name, data.data);
|
||||
break;
|
||||
}
|
||||
|
||||
ESX_MENU.getFocused = function () {
|
||||
return ESX_MENU.focus[ESX_MENU.focus.length - 1];
|
||||
};
|
||||
|
||||
window.onData = (data) => {
|
||||
switch (data.action) {
|
||||
|
||||
case 'openMenu': {
|
||||
ESX_MENU.open(data.namespace, data.name, data.data);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'closeMenu': {
|
||||
ESX_MENU.close(data.namespace, data.name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
window.onload = function (e) {
|
||||
window.addEventListener('message', (event) => {
|
||||
onData(event.data);
|
||||
});
|
||||
};
|
||||
case "closeMenu": {
|
||||
ESX_MENU.close(data.namespace, data.name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
window.onload = function (e) {
|
||||
window.addEventListener("message", (event) => {
|
||||
onData(event.data);
|
||||
});
|
||||
};
|
||||
})();
|
||||
|
||||
@@ -1,19 +1,26 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="stylesheet" href="nui://esx_menu_dialog/html/css/app.css" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" />
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:ital,wght@1,300&family=PT+Sans+Narrow&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
</head>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<link rel="stylesheet" href="nui://esx_menu_dialog/html/css/app.css">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com">
|
||||
<link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:ital,wght@1,300&family=PT+Sans+Narrow&display=swap" rel="stylesheet">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="menus"></div>
|
||||
|
||||
<script src="nui://game/ui/jquery.js" type="text/javascript"></script>
|
||||
<script src="nui://es_extended/html/js/wrapper.js"></script>
|
||||
<script src="nui://esx_menu_dialog/html/js/mustache.min.js" type="text/javascript"></script>
|
||||
<script src="nui://esx_menu_dialog/html/js/app.js" type="text/javascript"></script>
|
||||
</body>
|
||||
<body>
|
||||
<div id="menus"></div>
|
||||
|
||||
<script src="nui://game/ui/jquery.js" type="text/javascript"></script>
|
||||
<script src="nui://es_extended/html/js/wrapper.js"></script>
|
||||
<script
|
||||
src="nui://esx_menu_dialog/html/js/mustache.min.js"
|
||||
type="text/javascript"
|
||||
></script>
|
||||
<script
|
||||
src="nui://esx_menu_dialog/html/js/app.js"
|
||||
type="text/javascript"
|
||||
></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -29,7 +29,7 @@ CreateThread(function()
|
||||
})
|
||||
|
||||
for k,v in pairs(OpenedMenus) do
|
||||
if v == true then
|
||||
if v then
|
||||
OpenedMenuCount = OpenedMenuCount + 1
|
||||
end
|
||||
end
|
||||
|
||||
@@ -4,7 +4,7 @@ game 'gta5'
|
||||
|
||||
description 'ESX Menu List'
|
||||
lua54 'yes'
|
||||
version '1.9.3'
|
||||
version '1.9.4'
|
||||
|
||||
client_scripts {
|
||||
'@es_extended/imports.lua',
|
||||
|
||||
@@ -1,56 +1,55 @@
|
||||
@font-face {
|
||||
font-family: bankgothic;
|
||||
src: url('../fonts/bankgothic.ttf');
|
||||
font-family: bankgothic;
|
||||
src: url("../fonts/bankgothic.ttf");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: pcdown;
|
||||
src: url('../fonts/pdown.ttf');
|
||||
font-family: pcdown;
|
||||
src: url("../fonts/pdown.ttf");
|
||||
}
|
||||
|
||||
.menu {
|
||||
font-family: bankgothic;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 40%;
|
||||
transform: translate(-50%, -50%);
|
||||
overflow-y: auto;
|
||||
max-height: 90%;
|
||||
font-family: bankgothic;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 40%;
|
||||
transform: translate(-50%, -50%);
|
||||
overflow-y: auto;
|
||||
max-height: 90%;
|
||||
}
|
||||
|
||||
.menu button {
|
||||
font-family: bankgothic;
|
||||
font-family: bankgothic;
|
||||
}
|
||||
|
||||
.menu>table {
|
||||
border-collapse: separate;
|
||||
border-spacing: 0 5px;
|
||||
min-width: 400px;
|
||||
background: rgba(33, 33, 33, 0.0);
|
||||
.menu > table {
|
||||
border-collapse: separate;
|
||||
border-spacing: 0 5px;
|
||||
min-width: 400px;
|
||||
background: rgba(33, 33, 33, 0);
|
||||
}
|
||||
|
||||
.menu>table>thead {
|
||||
background: rgba(10, 10, 10, 0.9);
|
||||
text-align: center;
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
margin-bottom: 20px;
|
||||
color: #fff;
|
||||
.menu > table > thead {
|
||||
background: rgba(10, 10, 10, 0.9);
|
||||
text-align: center;
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
margin-bottom: 20px;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.menu td {
|
||||
|
||||
text-align: center;
|
||||
padding: 8px;
|
||||
margin: 20px;
|
||||
text-align: center;
|
||||
padding: 8px;
|
||||
margin: 20px;
|
||||
}
|
||||
|
||||
.menu tbody tr:nth-child(even) {
|
||||
color: #fff;
|
||||
background: rgba(40, 40, 40, 0.8);
|
||||
color: #fff;
|
||||
background: rgba(40, 40, 40, 0.8);
|
||||
}
|
||||
|
||||
.menu tbody tr:nth-child(odd) {
|
||||
color: #fff;
|
||||
background: rgba(40, 40, 40, 0.8);
|
||||
}
|
||||
color: #fff;
|
||||
background: rgba(40, 40, 40, 0.8);
|
||||
}
|
||||
|
||||
+174
-157
@@ -1,192 +1,209 @@
|
||||
(function(){
|
||||
(function () {
|
||||
let MenuTpl =
|
||||
'<div id="menu_{{_namespace}}_{{_name}}" class="menu">' +
|
||||
"<table>" +
|
||||
"<thead>" +
|
||||
"<tr>" +
|
||||
"{{#head}}<td>{{content}}</td>{{/head}}" +
|
||||
"</tr>" +
|
||||
"</thead>" +
|
||||
"<tbody>" +
|
||||
"{{#rows}}" +
|
||||
"<tr>" +
|
||||
"{{#cols}}<td>{{{content}}}</td>{{/cols}}" +
|
||||
"</tr>" +
|
||||
"{{/rows}}" +
|
||||
"</tbody>" +
|
||||
"</table>" +
|
||||
"</div>";
|
||||
window.ESX_MENU = {};
|
||||
ESX_MENU.ResourceName = "esx_menu_list";
|
||||
ESX_MENU.opened = {};
|
||||
ESX_MENU.focus = [];
|
||||
ESX_MENU.data = {};
|
||||
|
||||
let MenuTpl =
|
||||
'<div id="menu_{{_namespace}}_{{_name}}" class="menu">' +
|
||||
'<table>' +
|
||||
'<thead>' +
|
||||
'<tr>' +
|
||||
'{{#head}}<td>{{content}}</td>{{/head}}' +
|
||||
'</tr>' +
|
||||
'</thead>'+
|
||||
'<tbody>' +
|
||||
'{{#rows}}' +
|
||||
'<tr>' +
|
||||
'{{#cols}}<td>{{{content}}}</td>{{/cols}}' +
|
||||
'</tr>' +
|
||||
'{{/rows}}' +
|
||||
'</tbody>' +
|
||||
'</table>' +
|
||||
'</div>'
|
||||
;
|
||||
ESX_MENU.open = function (namespace, name, data) {
|
||||
if (typeof ESX_MENU.opened[namespace] == "undefined") {
|
||||
ESX_MENU.opened[namespace] = {};
|
||||
}
|
||||
|
||||
window.ESX_MENU = {};
|
||||
ESX_MENU.ResourceName = 'esx_menu_list';
|
||||
ESX_MENU.opened = {};
|
||||
ESX_MENU.focus = [];
|
||||
ESX_MENU.data = {};
|
||||
if (typeof ESX_MENU.opened[namespace][name] != "undefined") {
|
||||
ESX_MENU.close(namespace, name);
|
||||
}
|
||||
|
||||
ESX_MENU.open = function(namespace, name, data) {
|
||||
data._namespace = namespace;
|
||||
data._name = name;
|
||||
|
||||
if (typeof ESX_MENU.opened[namespace] == 'undefined') {
|
||||
ESX_MENU.opened[namespace] = {};
|
||||
}
|
||||
ESX_MENU.opened[namespace][name] = data;
|
||||
|
||||
if (typeof ESX_MENU.opened[namespace][name] != 'undefined') {
|
||||
ESX_MENU.close(namespace, name);
|
||||
}
|
||||
ESX_MENU.focus.push({
|
||||
namespace: namespace,
|
||||
name: name,
|
||||
});
|
||||
|
||||
data._namespace = namespace;
|
||||
data._name = name;
|
||||
ESX_MENU.render();
|
||||
};
|
||||
|
||||
ESX_MENU.opened[namespace][name] = data;
|
||||
ESX_MENU.close = function (namespace, name) {
|
||||
delete ESX_MENU.opened[namespace][name];
|
||||
|
||||
ESX_MENU.focus.push({
|
||||
namespace: namespace,
|
||||
name : name
|
||||
});
|
||||
|
||||
ESX_MENU.render();
|
||||
};
|
||||
for (let i = 0; i < ESX_MENU.focus.length; i++) {
|
||||
if (
|
||||
ESX_MENU.focus[i].namespace == namespace &&
|
||||
ESX_MENU.focus[i].name == name
|
||||
) {
|
||||
ESX_MENU.focus.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ESX_MENU.close = function(namespace, name) {
|
||||
delete ESX_MENU.opened[namespace][name];
|
||||
ESX_MENU.render();
|
||||
};
|
||||
|
||||
for (let i=0; i<ESX_MENU.focus.length; i++) {
|
||||
if (ESX_MENU.focus[i].namespace == namespace && ESX_MENU.focus[i].name == name) {
|
||||
ESX_MENU.focus.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
ESX_MENU.render = function () {
|
||||
let menuContainer = document.getElementById("menus");
|
||||
let focused = ESX_MENU.getFocused();
|
||||
menuContainer.innerHTML = "";
|
||||
|
||||
ESX_MENU.render();
|
||||
};
|
||||
$(menuContainer).hide();
|
||||
|
||||
ESX_MENU.render = function() {
|
||||
for (let namespace in ESX_MENU.opened) {
|
||||
if (typeof ESX_MENU.data[namespace] == "undefined") {
|
||||
ESX_MENU.data[namespace] = {};
|
||||
}
|
||||
|
||||
let menuContainer = document.getElementById('menus');
|
||||
let focused = ESX_MENU.getFocused();
|
||||
menuContainer.innerHTML = '';
|
||||
for (let name in ESX_MENU.opened[namespace]) {
|
||||
ESX_MENU.data[namespace][name] = [];
|
||||
|
||||
$(menuContainer).hide();
|
||||
let menuData = ESX_MENU.opened[namespace][name];
|
||||
let view = {
|
||||
_namespace: menuData._namespace,
|
||||
_name: menuData._name,
|
||||
head: [],
|
||||
rows: [],
|
||||
};
|
||||
|
||||
for (let namespace in ESX_MENU.opened) {
|
||||
|
||||
if (typeof ESX_MENU.data[namespace] == 'undefined') {
|
||||
ESX_MENU.data[namespace] = {};
|
||||
}
|
||||
for (let i = 0; i < menuData.head.length; i++) {
|
||||
let item = { content: menuData.head[i] };
|
||||
view.head.push(item);
|
||||
}
|
||||
|
||||
for (let name in ESX_MENU.opened[namespace]) {
|
||||
for (let i = 0; i < menuData.rows.length; i++) {
|
||||
let row = menuData.rows[i];
|
||||
let data = row.data;
|
||||
|
||||
ESX_MENU.data[namespace][name] = [];
|
||||
ESX_MENU.data[namespace][name].push(data);
|
||||
|
||||
let menuData = ESX_MENU.opened[namespace][name];
|
||||
let view = {
|
||||
_namespace: menuData._namespace,
|
||||
_name : menuData._name,
|
||||
head : [],
|
||||
rows : []
|
||||
};
|
||||
view.rows.push({ cols: [] });
|
||||
|
||||
for (let i=0; i<menuData.head.length; i++) {
|
||||
let item = {content: menuData.head[i]};
|
||||
view.head.push(item);
|
||||
}
|
||||
for (let j = 0; j < row.cols.length; j++) {
|
||||
let col = menuData.rows[i].cols[j];
|
||||
let regex = /\{\{(.*?)\|(.*?)\}\}/g;
|
||||
let matches = [];
|
||||
let match;
|
||||
|
||||
for (let i=0; i<menuData.rows.length; i++) {
|
||||
let row = menuData.rows[i];
|
||||
let data = row.data;
|
||||
while ((match = regex.exec(col)) != null) {
|
||||
matches.push(match);
|
||||
}
|
||||
|
||||
ESX_MENU.data[namespace][name].push(data);
|
||||
for (let k = 0; k < matches.length; k++) {
|
||||
col = col.replace(
|
||||
"{{" + matches[k][1] + "|" + matches[k][2] + "}}",
|
||||
'<button data-id="' +
|
||||
i +
|
||||
'" data-namespace="' +
|
||||
namespace +
|
||||
'" data-name="' +
|
||||
name +
|
||||
'" data-value="' +
|
||||
matches[k][2] +
|
||||
'">' +
|
||||
matches[k][1] +
|
||||
"</button>"
|
||||
);
|
||||
}
|
||||
|
||||
view.rows.push({cols: []});
|
||||
view.rows[i].cols.push({ data: data, content: col });
|
||||
}
|
||||
}
|
||||
|
||||
for (let j=0; j<row.cols.length; j++) {
|
||||
let menu = $(Mustache.render(MenuTpl, view));
|
||||
|
||||
let col = menuData.rows[i].cols[j];
|
||||
let regex = /\{\{(.*?)\|(.*?)\}\}/g;
|
||||
let matches = [];
|
||||
let match;
|
||||
menu.find("button[data-namespace][data-name]").click(function () {
|
||||
ESX_MENU.data[$(this).data("namespace")][$(this).data("name")][
|
||||
parseInt($(this).data("id"))
|
||||
].currentRow = parseInt($(this).data("id")) + 1;
|
||||
ESX_MENU.submit($(this).data("namespace"), $(this).data("name"), {
|
||||
data: ESX_MENU.data[$(this).data("namespace")][
|
||||
$(this).data("name")
|
||||
][parseInt($(this).data("id"))],
|
||||
value: $(this).data("value"),
|
||||
});
|
||||
});
|
||||
|
||||
while ((match = regex.exec(col)) != null) {
|
||||
matches.push(match);
|
||||
}
|
||||
menu.hide();
|
||||
|
||||
for (let k=0; k<matches.length; k++) {
|
||||
col = col.replace('{{' + matches[k][1] + '|' + matches[k][2] + '}}', '<button data-id="' + i + '" data-namespace="' + namespace + '" data-name="' + name + '" data-value="' + matches[k][2] +'">' + matches[k][1] + '</button>');
|
||||
}
|
||||
menuContainer.appendChild(menu[0]);
|
||||
}
|
||||
}
|
||||
|
||||
view.rows[i].cols.push({data: data, content: col});
|
||||
}
|
||||
}
|
||||
if (typeof focused != "undefined") {
|
||||
$("#menu_" + focused.namespace + "_" + focused.name).show();
|
||||
}
|
||||
|
||||
let menu = $(Mustache.render(MenuTpl, view));
|
||||
$(menuContainer).show();
|
||||
};
|
||||
|
||||
menu.find('button[data-namespace][data-name]').click(function() {
|
||||
ESX_MENU.data[$(this).data('namespace')][$(this).data('name')][parseInt($(this).data('id'))].currentRow = parseInt($(this).data('id')) + 1;
|
||||
ESX_MENU.submit($(this).data('namespace'), $(this).data('name'), {
|
||||
data : ESX_MENU.data[$(this).data('namespace')][$(this).data('name')][parseInt($(this).data('id'))],
|
||||
value: $(this).data('value')
|
||||
});
|
||||
});
|
||||
ESX_MENU.submit = function (namespace, name, data) {
|
||||
$.post(
|
||||
"http://" + ESX_MENU.ResourceName + "/menu_submit",
|
||||
JSON.stringify({
|
||||
_namespace: namespace,
|
||||
_name: name,
|
||||
data: data.data,
|
||||
value: data.value,
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
menu.hide();
|
||||
ESX_MENU.cancel = function (namespace, name) {
|
||||
$.post(
|
||||
"http://" + ESX_MENU.ResourceName + "/menu_cancel",
|
||||
JSON.stringify({
|
||||
_namespace: namespace,
|
||||
_name: name,
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
menuContainer.appendChild(menu[0]);
|
||||
}
|
||||
}
|
||||
ESX_MENU.getFocused = function () {
|
||||
return ESX_MENU.focus[ESX_MENU.focus.length - 1];
|
||||
};
|
||||
|
||||
if (typeof focused != 'undefined') {
|
||||
$('#menu_' + focused.namespace + '_' + focused.name).show();
|
||||
}
|
||||
window.onData = (data) => {
|
||||
switch (data.action) {
|
||||
case "openMenu": {
|
||||
ESX_MENU.open(data.namespace, data.name, data.data);
|
||||
break;
|
||||
}
|
||||
|
||||
$(menuContainer).show();
|
||||
};
|
||||
case "closeMenu": {
|
||||
ESX_MENU.close(data.namespace, data.name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
ESX_MENU.submit = function(namespace, name, data){
|
||||
$.post('http://' + ESX_MENU.ResourceName + '/menu_submit', JSON.stringify({
|
||||
_namespace: namespace,
|
||||
_name : name,
|
||||
data : data.data,
|
||||
value : data.value
|
||||
}));
|
||||
};
|
||||
window.onload = function (e) {
|
||||
window.addEventListener("message", (event) => {
|
||||
onData(event.data);
|
||||
});
|
||||
};
|
||||
|
||||
ESX_MENU.cancel = function(namespace, name){
|
||||
$.post('http://' + ESX_MENU.ResourceName + '/menu_cancel', JSON.stringify({
|
||||
_namespace: namespace,
|
||||
_name : name
|
||||
}));
|
||||
};
|
||||
|
||||
ESX_MENU.getFocused = function(){
|
||||
return ESX_MENU.focus[ESX_MENU.focus.length - 1];
|
||||
};
|
||||
|
||||
window.onData = (data) => {
|
||||
switch(data.action){
|
||||
case 'openMenu' : {
|
||||
ESX_MENU.open(data.namespace, data.name, data.data);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'closeMenu' : {
|
||||
ESX_MENU.close(data.namespace, data.name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
window.onload = function(e){
|
||||
window.addEventListener('message', (event) => {
|
||||
onData(event.data);
|
||||
});
|
||||
};
|
||||
|
||||
document.onkeyup = function(data) {
|
||||
if(data.which == 27) {
|
||||
let focused = ESX_MENU.getFocused();
|
||||
ESX_MENU.cancel(focused.namespace, focused.name);
|
||||
}
|
||||
};
|
||||
|
||||
})();
|
||||
document.onkeyup = function (data) {
|
||||
if (data.which == 27) {
|
||||
let focused = ESX_MENU.getFocused();
|
||||
ESX_MENU.cancel(focused.namespace, focused.name);
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
@@ -1,16 +1,14 @@
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" href="css/app.css" />
|
||||
</head>
|
||||
|
||||
<head>
|
||||
<link rel="stylesheet" href="css/app.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="menus"></div>
|
||||
|
||||
<body>
|
||||
<div id="menus"></div>
|
||||
|
||||
<script src="nui://game/ui/jquery.js"></script>
|
||||
<script src="nui://es_extended/html/js/wrapper.js"></script>
|
||||
<script src="js/mustache.min.js"></script>
|
||||
<script src="js/app.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
<script src="nui://game/ui/jquery.js"></script>
|
||||
<script src="nui://es_extended/html/js/wrapper.js"></script>
|
||||
<script src="js/mustache.min.js"></script>
|
||||
<script src="js/app.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -4,12 +4,13 @@ if ESX.GetConfig().Multichar then
|
||||
|
||||
CreateThread(function()
|
||||
while not ESX.PlayerLoaded do
|
||||
Wait(0)
|
||||
Wait(100)
|
||||
|
||||
if NetworkIsPlayerActive(PlayerId()) then
|
||||
exports.spawnmanager:setAutoSpawn(false)
|
||||
DoScreenFadeOut(0)
|
||||
while not GetResourceState('esx_context') == 'started' do
|
||||
Wait(0)
|
||||
Wait(100)
|
||||
end
|
||||
TriggerEvent("esx_multicharacter:SetupCharacters")
|
||||
break
|
||||
@@ -95,7 +96,7 @@ if ESX.GetConfig().Multichar then
|
||||
end
|
||||
|
||||
SetupCharacter = function(index)
|
||||
if spawned == false then
|
||||
if not spawned then
|
||||
exports.spawnmanager:spawnPlayer({
|
||||
x = Config.Spawn.x,
|
||||
y = Config.Spawn.y,
|
||||
@@ -188,7 +189,7 @@ if ESX.GetConfig().Multichar then
|
||||
if not v.model and v.skin then
|
||||
if v.skin.model then v.model = v.skin.model elseif v.skin.sex == 1 then v.model = mp_f_freemode_01 else v.model = mp_m_freemode_01 end
|
||||
end
|
||||
if spawned == false then SetupCharacter(Character) end
|
||||
if not spawned then SetupCharacter(Character) end
|
||||
local label = v.firstname..' '..v.lastname
|
||||
if Characters[k].disabled then
|
||||
elements[#elements+1] = {title = label,icon = "fa-regular fa-user", value = v.id}
|
||||
@@ -318,7 +319,7 @@ if ESX.GetConfig().Multichar then
|
||||
|
||||
if Config.Relog then
|
||||
RegisterCommand('relog', function(source, args, rawCommand)
|
||||
if canRelog == true then
|
||||
if canRelog then
|
||||
canRelog = false
|
||||
TriggerServerEvent('esx_multicharacter:relog')
|
||||
ESX.SetTimeout(10000, function()
|
||||
|
||||
@@ -2,7 +2,7 @@ fx_version 'cerulean'
|
||||
game 'gta5'
|
||||
author 'ESX-Framework - Linden - KASH'
|
||||
description 'Official Multicharacter System For ESX Legacy'
|
||||
version '1.9.3'
|
||||
version '1.9.4'
|
||||
lua54 'yes'
|
||||
|
||||
dependencies {'es_extended', 'esx_context', 'esx_identity', 'esx_skin'}
|
||||
|
||||
@@ -1,76 +1,76 @@
|
||||
@import url('https://fonts.googleapis.com/css2?family=Raleway:wght@300;600&display=swap');
|
||||
@import url('https://fonts.googleapis.com/css2?family=Oswald&display=swap');
|
||||
@import url("https://fonts.googleapis.com/css2?family=Raleway:wght@300;600&display=swap");
|
||||
@import url("https://fonts.googleapis.com/css2?family=Oswald&display=swap");
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
user-select: none;
|
||||
color: rgb(255, 255, 255);
|
||||
border-radius: 15px;
|
||||
font-weight: 300;
|
||||
font-size: 1.6vh;
|
||||
font-family: Calibri, "Helvetica", san-serif;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
user-select: none;
|
||||
color: rgb(255, 255, 255);
|
||||
border-radius: 15px;
|
||||
font-weight: 300;
|
||||
font-size: 1.6vh;
|
||||
font-family: Calibri, "Helvetica", san-serif;
|
||||
}
|
||||
|
||||
html {
|
||||
overflow: hidden;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0 !important;
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
body {
|
||||
background: transparent;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.main-container {
|
||||
display:none;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: 150;
|
||||
transform: translate(0, -50%);
|
||||
border-radius: 15px;
|
||||
background: rgba(15,15,15, 0.9);
|
||||
display: none;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: 150;
|
||||
transform: translate(0, -50%);
|
||||
border-radius: 15px;
|
||||
background: rgba(15, 15, 15, 0.9);
|
||||
}
|
||||
|
||||
.header {
|
||||
font-family: 'Oswald', sans-serif;
|
||||
position: absolute;
|
||||
background: rgba(10, 10, 10, 0.9);
|
||||
border-radius: 15px 15px 0px 0px;
|
||||
height: 10%;
|
||||
width: 100%;
|
||||
left: 50%;
|
||||
text-align: center;
|
||||
transform: translate(-50%);
|
||||
font-weight: 700;
|
||||
padding-bottom: 5px;
|
||||
font-size: 1.6rem;
|
||||
font-family: "Oswald", sans-serif;
|
||||
position: absolute;
|
||||
background: rgba(10, 10, 10, 0.9);
|
||||
border-radius: 15px 15px 0px 0px;
|
||||
height: 10%;
|
||||
width: 100%;
|
||||
left: 50%;
|
||||
text-align: center;
|
||||
transform: translate(-50%);
|
||||
font-weight: 700;
|
||||
padding-bottom: 5px;
|
||||
font-size: 1.6rem;
|
||||
}
|
||||
|
||||
.footer {
|
||||
position: absolute;
|
||||
font-size: 0rem;
|
||||
position: absolute;
|
||||
font-size: 0rem;
|
||||
}
|
||||
|
||||
.character-box {
|
||||
display: flex;
|
||||
right: 0;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
line-height: 1.4rem;
|
||||
height: calc(30rem);
|
||||
width: 17rem;
|
||||
border: 1px rgba(10,10,10,0.7) solid;
|
||||
box-shadow: 2px 1px 9px 3px rgba(10,10,10,0.7);
|
||||
display: flex;
|
||||
right: 0;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
line-height: 1.4rem;
|
||||
height: calc(30rem);
|
||||
width: 17rem;
|
||||
border: 1px rgba(10, 10, 10, 0.7) solid;
|
||||
box-shadow: 2px 1px 9px 3px rgba(10, 10, 10, 0.7);
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-family: 'Oswald', sans-serif;
|
||||
font-size: 22px;
|
||||
padding-top: 1.3rem;
|
||||
display: block;
|
||||
font-weight: 0;
|
||||
font-family: "Oswald", sans-serif;
|
||||
font-size: 22px;
|
||||
padding-top: 1.3rem;
|
||||
display: block;
|
||||
font-weight: 0;
|
||||
}
|
||||
|
||||
@@ -1,35 +1,68 @@
|
||||
var money = Intl.NumberFormat('en-US', {
|
||||
style: 'currency',
|
||||
currency: 'USD',
|
||||
minimumFractionDigits: 0
|
||||
var money = Intl.NumberFormat("en-US", {
|
||||
style: "currency",
|
||||
currency: "USD",
|
||||
minimumFractionDigits: 0,
|
||||
});
|
||||
|
||||
(() => {
|
||||
Kashacter = {};
|
||||
Kashacter = {};
|
||||
|
||||
Kashacter.ShowUI = function(data) {
|
||||
$('body').css({"display":"block"});
|
||||
$('.main-container').css({"display":"block"});
|
||||
$('[data-charid=1]').html('<div class="character-info"><p class="character-info-name"><h1>' + `${translate.name} ` + '</h1><span>' + data.firstname +' '+ data.lastname +'</span></p><p class="character-info-work"><h1>' + `${translate.job} ` + '</h1><span>'+ data.job +' '+ data.job_grade +'</span></p><p class="character-info-money"><h1>' + `${translate.money} ` + '</h1><span> '+ money.format(data.money) +'</span></p><p class="character-info-bank"><h1>' + `${translate.bank} ` + '</h1><span> '+ money.format(data.bank) +'</span></p> <p class="character-info-dateofbirth"><h1>' + `${translate.dob} ` + '</h1><span>'+ data.dateofbirth +'</span></p> <p class="character-info-gender"><h1>' + `${translate.gender} ` + '</h1><span>'+ data.sex +'</span></p></div>').attr("data-ischar", "true");
|
||||
};
|
||||
Kashacter.ShowUI = function (data) {
|
||||
$("body").css({ display: "block" });
|
||||
$(".main-container").css({ display: "block" });
|
||||
$("[data-charid=1]")
|
||||
.html(
|
||||
'<div class="character-info"><p class="character-info-name"><h1>' +
|
||||
`${translate.name} ` +
|
||||
"</h1><span>" +
|
||||
data.firstname +
|
||||
" " +
|
||||
data.lastname +
|
||||
'</span></p><p class="character-info-work"><h1>' +
|
||||
`${translate.job} ` +
|
||||
"</h1><span>" +
|
||||
data.job +
|
||||
" " +
|
||||
data.job_grade +
|
||||
'</span></p><p class="character-info-money"><h1>' +
|
||||
`${translate.money} ` +
|
||||
"</h1><span> " +
|
||||
money.format(data.money) +
|
||||
'</span></p><p class="character-info-bank"><h1>' +
|
||||
`${translate.bank} ` +
|
||||
"</h1><span> " +
|
||||
money.format(data.bank) +
|
||||
'</span></p> <p class="character-info-dateofbirth"><h1>' +
|
||||
`${translate.dob} ` +
|
||||
"</h1><span>" +
|
||||
data.dateofbirth +
|
||||
'</span></p> <p class="character-info-gender"><h1>' +
|
||||
`${translate.gender} ` +
|
||||
"</h1><span>" +
|
||||
data.sex +
|
||||
"</span></p></div>"
|
||||
)
|
||||
.attr("data-ischar", "true");
|
||||
};
|
||||
|
||||
Kashacter.CloseUI = function() {
|
||||
$('body').css({"display":"none"});
|
||||
$('.main-container').css({"display":"none"});
|
||||
$('[data-charid=1]').html('<h3 class="character-fullname"></h3><div class="character-info"><p class="character-info-new"></p></div>');
|
||||
};
|
||||
|
||||
window.onload = function(e) {
|
||||
window.addEventListener('message', function(event) {
|
||||
switch(event.data.action) {
|
||||
case 'openui':
|
||||
Kashacter.ShowUI(event.data.character);
|
||||
break;
|
||||
case 'closeui':
|
||||
Kashacter.CloseUI();
|
||||
break;
|
||||
}
|
||||
})
|
||||
}
|
||||
Kashacter.CloseUI = function () {
|
||||
$("body").css({ display: "none" });
|
||||
$(".main-container").css({ display: "none" });
|
||||
$("[data-charid=1]").html(
|
||||
'<h3 class="character-fullname"></h3><div class="character-info"><p class="character-info-new"></p></div>'
|
||||
);
|
||||
};
|
||||
|
||||
window.onload = function (e) {
|
||||
window.addEventListener("message", function (event) {
|
||||
switch (event.data.action) {
|
||||
case "openui":
|
||||
Kashacter.ShowUI(event.data.character);
|
||||
break;
|
||||
case "closeui":
|
||||
Kashacter.CloseUI();
|
||||
break;
|
||||
}
|
||||
});
|
||||
};
|
||||
})();
|
||||
|
||||
@@ -1,24 +1,29 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<!-- Custom CSS -->
|
||||
<link rel="stylesheet" type="text/css" href="css/main.css" />
|
||||
<!-- Locales -->
|
||||
<script src="locales/en.js"></script>
|
||||
</head>
|
||||
<body style="display: none;">
|
||||
<div class="main-container">
|
||||
<div class='header'>Character Info</div>
|
||||
<div class="character-box" data-charid="1">
|
||||
<h3 class="character-fullname"></h3>
|
||||
<div class="character-info"></div>
|
||||
</div>
|
||||
<div class='footer'>Multicharacter</div>
|
||||
</div>
|
||||
</div>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta
|
||||
name="viewport"
|
||||
content="width=device-width, initial-scale=1, shrink-to-fit=no"
|
||||
/>
|
||||
<!-- Custom CSS -->
|
||||
<link rel="stylesheet" type="text/css" href="css/main.css" />
|
||||
<!-- Locales -->
|
||||
<script src="locales/en.js"></script>
|
||||
</head>
|
||||
<body style="display: none">
|
||||
<div class="main-container">
|
||||
<div class="header">Character Info</div>
|
||||
<div class="character-box" data-charid="1">
|
||||
<h3 class="character-fullname"></h3>
|
||||
<div class="character-info"></div>
|
||||
</div>
|
||||
<div class="footer">Multicharacter</div>
|
||||
</div>
|
||||
<script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
|
||||
<script
|
||||
src="https://code.jquery.com/jquery-3.3.1.min.js"
|
||||
integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
|
||||
crossorigin="anonymous"
|
||||
></script>
|
||||
<script src="js/app.js" type="text/javascript"></script>
|
||||
</body>
|
||||
</html>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,23 +1,26 @@
|
||||
if not ESX then
|
||||
error('\n^1Unable to start Multicharacter - you must be using ESX Legacy^0')
|
||||
elseif ESX.GetConfig().Multichar == true then
|
||||
local DATABASE do
|
||||
local connectionString = GetConvar('mysql_connection_string', '');
|
||||
if connectionString == '' then
|
||||
error(connectionString..'\n^1Unable to start Multicharacter - unable to determine database from mysql_connection_string^0', 0)
|
||||
elseif connectionString:find('mysql://') then
|
||||
connectionString = connectionString:sub(9, -1)
|
||||
DATABASE = connectionString:sub(connectionString:find('/')+1, -1):gsub('[%?]+[%w%p]*$', '')
|
||||
else
|
||||
connectionString = {string.strsplit(';', connectionString)}
|
||||
for i = 1, #connectionString do
|
||||
local v = connectionString[i]
|
||||
if v:match('database') then
|
||||
DATABASE = v:sub(10, #v)
|
||||
end
|
||||
local databaseConnected = false
|
||||
local databaseFound = false
|
||||
local oneSyncState = GetConvar('onesync', 'off')
|
||||
|
||||
local DATABASE do
|
||||
local connectionString = GetConvar('mysql_connection_string', '');
|
||||
if connectionString == '' then
|
||||
error(connectionString..'\n^1Unable to start Multicharacter - unable to determine database from mysql_connection_string^0', 0)
|
||||
elseif connectionString:find('mysql://') then
|
||||
connectionString = connectionString:sub(9, -1)
|
||||
DATABASE = connectionString:sub(connectionString:find('/')+1, -1):gsub('[%?]+[%w%p]*$', '')
|
||||
databaseFound = true
|
||||
else
|
||||
connectionString = {string.strsplit(';', connectionString)}
|
||||
for i = 1, #connectionString do
|
||||
local v = connectionString[i]
|
||||
if v:match('database') then
|
||||
DATABASE = v:sub(10, #v)
|
||||
end
|
||||
end
|
||||
databaseFound = true
|
||||
end
|
||||
end
|
||||
|
||||
local DB_TABLES = {users = 'identifier'}
|
||||
local FETCH = nil
|
||||
@@ -92,11 +95,23 @@ elseif ESX.GetConfig().Multichar == true then
|
||||
AddEventHandler('playerConnecting', function(playerName, setKickReason, deferrals)
|
||||
deferrals.defer()
|
||||
local identifier = GetIdentifier(source)
|
||||
if oneSyncState == "off" or oneSyncState == "legacy" then
|
||||
return deferrals.done(('[ESX] ESX Requires Onesync Infinity to work. This server currently has Onesync set to: %s'):format(oneSyncState))
|
||||
end
|
||||
|
||||
if not databaseFound then
|
||||
deferrals.done(('[ESX Multicharacter] Cannot Find the servers mysql_connection_string. Please make sure it is correctly configured in your server.cfg'):format(oneSyncState))
|
||||
end
|
||||
|
||||
if not databaseConnected then
|
||||
deferrals.done(('[ESX Multicharacter] ESX Cannot Connect to your database. Please make sure it is correctly configured in your server.cfg'):format(oneSyncState))
|
||||
end
|
||||
|
||||
if identifier then
|
||||
|
||||
if not ESX.GetConfig().EnableDebug then
|
||||
if ESX.Players[identifier] then
|
||||
deferrals.done(('A player is already connected to the server with this identifier.\nYour identifier: %s:%s'):format(PRIMARY_IDENTIFIER, identifier))
|
||||
deferrals.done(('[ESX Multicharacter] A player is already connected to the server with this identifier.\nYour identifier: %s:%s'):format(PRIMARY_IDENTIFIER, identifier))
|
||||
else
|
||||
deferrals.done()
|
||||
end
|
||||
@@ -141,11 +156,12 @@ elseif ESX.GetConfig().Multichar == true then
|
||||
local count = 0
|
||||
|
||||
for i = 1, #DB_COLUMNS do
|
||||
local v = DB_COLUMNS[i]
|
||||
local column = DB_COLUMNS[i]
|
||||
DB_TABLES[column.TABLE_NAME] = column.COLUMN_NAME
|
||||
|
||||
if v?.CHARACTER_MAXIMUM_LENGTH ~= length then
|
||||
if column?.CHARACTER_MAXIMUM_LENGTH ~= length then
|
||||
count += 1
|
||||
columns[v.TABLE_NAME] = v.COLUMN_NAME
|
||||
columns[column.TABLE_NAME] = column.COLUMN_NAME
|
||||
end
|
||||
end
|
||||
|
||||
@@ -179,6 +195,7 @@ elseif ESX.GetConfig().Multichar == true then
|
||||
until next(ESX.Jobs)
|
||||
|
||||
FETCH = 'SELECT identifier, accounts, job, job_grade, firstname, lastname, dateofbirth, sex, skin, disabled FROM users WHERE identifier LIKE ? LIMIT ?'
|
||||
databaseConnected = true
|
||||
end
|
||||
end)
|
||||
|
||||
@@ -219,8 +236,4 @@ elseif ESX.GetConfig().Multichar == true then
|
||||
RegisterNetEvent('esx_multicharacter:relog', function()
|
||||
local source = source
|
||||
TriggerEvent('esx:playerLogout', source)
|
||||
end)
|
||||
|
||||
else
|
||||
assert(nil, '^3WARNING: Multicharacter is disabled - please check your ESX configuration^0')
|
||||
end
|
||||
end)
|
||||
@@ -1,7 +1,7 @@
|
||||
fx_version 'adamant'
|
||||
lua54 'yes'
|
||||
game 'gta5'
|
||||
version '1.9.3'
|
||||
version '1.9.4'
|
||||
author 'ESX-Framework'
|
||||
description 'Official NUI Notification system for ESX'
|
||||
|
||||
@@ -15,5 +15,4 @@ files {
|
||||
'nui/index.html',
|
||||
'nui/js/*.js',
|
||||
'nui/css/*.css',
|
||||
'nui/img/*.png',
|
||||
}
|
||||
|
||||
@@ -1,88 +1,84 @@
|
||||
@import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@100&family=Poppins:wght@300;400;500;600;800&display=swap');
|
||||
@import url("https://fonts.googleapis.com/css2?family=Montserrat:wght@100&family=Poppins:wght@300;400;500;600;800&display=swap");
|
||||
|
||||
:root {
|
||||
--color: #919191;
|
||||
--color: #919191;
|
||||
}
|
||||
|
||||
* {
|
||||
border: 0;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
border: 0;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
color: var(--color);
|
||||
font-weight: 100;
|
||||
font-family: 'Poppins', sans-serif;
|
||||
overflow: hidden;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
color: var(--color);
|
||||
font-weight: 100;
|
||||
font-family: "Poppins", sans-serif;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#root {
|
||||
display: grid;
|
||||
justify-content: center;
|
||||
display: grid;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
#root .notify {
|
||||
display: flex;
|
||||
position: relative;
|
||||
flex: auto;
|
||||
min-width: 20rem;
|
||||
width: fit-content;
|
||||
height: 3.5rem;
|
||||
background: rgba(5,5, 5, 0.9);
|
||||
border-radius: .5rem;
|
||||
margin-top: .5rem;
|
||||
animation: anim 300ms ease-in-out;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
position: relative;
|
||||
flex: auto;
|
||||
min-width: 20rem;
|
||||
width: fit-content;
|
||||
height: 3.5rem;
|
||||
background: rgba(5, 5, 5, 0.9);
|
||||
border-radius: 0.5rem;
|
||||
margin-top: 0.5rem;
|
||||
animation: anim 300ms ease-in-out;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
#root .innerText {
|
||||
padding-left: .4rem;
|
||||
padding-right: .4rem;
|
||||
width: 100%;
|
||||
padding-left: 0.4rem;
|
||||
padding-right: 0.4rem;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#root .icon {
|
||||
float: left;
|
||||
color: #fff;
|
||||
float: left;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
#root .text {
|
||||
display: inline-block;
|
||||
margin-left: .5rem;
|
||||
display: inline-block;
|
||||
margin-left: 0.5rem;
|
||||
}
|
||||
|
||||
#root .error {
|
||||
border-bottom: 3px solid #c0392b;
|
||||
border-bottom: 3px solid #c0392b;
|
||||
}
|
||||
|
||||
#root .success {
|
||||
border-bottom: 3px solid #2ecc71;
|
||||
border-bottom: 3px solid #2ecc71;
|
||||
}
|
||||
|
||||
#root .info {
|
||||
border-bottom: 3px solid #2980b9;
|
||||
border-bottom: 3px solid #2980b9;
|
||||
}
|
||||
|
||||
.material-symbols-outlined {
|
||||
font-variation-settings:
|
||||
'FILL' 0,
|
||||
'wght' 400,
|
||||
'GRAD' 0,
|
||||
'opsz' 48
|
||||
font-variation-settings: "FILL" 0, "wght" 400, "GRAD" 0, "opsz" 48;
|
||||
}
|
||||
|
||||
@keyframes anim {
|
||||
0% {
|
||||
transform: scaleY(0);
|
||||
}
|
||||
80% {
|
||||
transform: scaleY(1.1)
|
||||
}
|
||||
100% {
|
||||
transform: scaleY(1)
|
||||
}
|
||||
0% {
|
||||
transform: scaleY(0);
|
||||
}
|
||||
80% {
|
||||
transform: scaleY(1.1);
|
||||
}
|
||||
100% {
|
||||
transform: scaleY(1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,18 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<head>
|
||||
<script src="nui://game/ui/jquery.js" type="text/javascript"></script>
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" />
|
||||
<link rel="stylesheet" href="css/style.css">
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200"
|
||||
/>
|
||||
<link rel="stylesheet" href="css/style.css" />
|
||||
<script src="js/script.js"></script>
|
||||
<title>ESX Notify</title>
|
||||
</head>
|
||||
<body>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root">
|
||||
<!-- this is just a template! No touchy touchy -->
|
||||
<!-- this is just a template! No touchy touchy -->
|
||||
</div>
|
||||
</body>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,74 +1,76 @@
|
||||
const w = window
|
||||
const w = window;
|
||||
|
||||
// Gets the current icon it needs to use.
|
||||
const types = {
|
||||
["success"]: {
|
||||
["icon"]: "check_circle",
|
||||
},
|
||||
["error"]: {
|
||||
["icon"]: "error",
|
||||
},
|
||||
["info"]: {
|
||||
["icon"]: "info",
|
||||
}
|
||||
}
|
||||
["success"]: {
|
||||
["icon"]: "check_circle",
|
||||
},
|
||||
["error"]: {
|
||||
["icon"]: "error",
|
||||
},
|
||||
["info"]: {
|
||||
["icon"]: "info",
|
||||
},
|
||||
};
|
||||
|
||||
// the color codes example `i ~r~love~s~ donuts`
|
||||
const codes = {
|
||||
"~r~": "red",
|
||||
"~b~": "#378cbf",
|
||||
"~g~": "green",
|
||||
"~y~": "yellow",
|
||||
"~p~": "purple",
|
||||
"~c~": "grey",
|
||||
"~m~": "#212121",
|
||||
"~u~": "black",
|
||||
"~o~": "orange"
|
||||
}
|
||||
"~r~": "red",
|
||||
"~b~": "#378cbf",
|
||||
"~g~": "green",
|
||||
"~y~": "yellow",
|
||||
"~p~": "purple",
|
||||
"~c~": "grey",
|
||||
"~m~": "#212121",
|
||||
"~u~": "black",
|
||||
"~o~": "orange",
|
||||
};
|
||||
|
||||
w.addEventListener("message", (event) => {
|
||||
notification({
|
||||
type: event.data.type,
|
||||
message: event.data.message,
|
||||
length: event.data.length,
|
||||
});
|
||||
notification({
|
||||
type: event.data.type,
|
||||
message: event.data.message,
|
||||
length: event.data.length,
|
||||
});
|
||||
});
|
||||
|
||||
const replaceColors = (str, obj) => {
|
||||
let strToReplace = str;
|
||||
let strToReplace = str;
|
||||
|
||||
for (let id in obj) {
|
||||
strToReplace = strToReplace.replace(new RegExp(id, "g"), obj[id]);
|
||||
}
|
||||
for (let id in obj) {
|
||||
strToReplace = strToReplace.replace(new RegExp(id, "g"), obj[id]);
|
||||
}
|
||||
|
||||
return strToReplace
|
||||
}
|
||||
return strToReplace;
|
||||
};
|
||||
|
||||
notification = (data) => {
|
||||
for (color in codes) {
|
||||
if (data["message"].includes(color)) {
|
||||
let objArr = {};
|
||||
objArr[color] = `<span style="color: ${codes[color]}">`;
|
||||
objArr["~s~"] = "</span>";
|
||||
for (color in codes) {
|
||||
if (data["message"].includes(color)) {
|
||||
let objArr = {};
|
||||
objArr[color] = `<span style="color: ${codes[color]}">`;
|
||||
objArr["~s~"] = "</span>";
|
||||
|
||||
let newStr = replaceColors(data["message"], objArr);
|
||||
let newStr = replaceColors(data["message"], objArr);
|
||||
|
||||
data["message"] = newStr
|
||||
}
|
||||
data["message"] = newStr;
|
||||
}
|
||||
}
|
||||
|
||||
const notification = $(`
|
||||
const notification = $(`
|
||||
<div class="notify ${data.type}">
|
||||
<div class="innerText">
|
||||
<span class="material-symbols-outlined icon">${types[data.type]["icon"]}</span>
|
||||
<span class="material-symbols-outlined icon">${
|
||||
types[data.type]["icon"]
|
||||
}</span>
|
||||
<p class="text">${data["message"]}</p>
|
||||
</div>
|
||||
</div>
|
||||
`).appendTo(`#root`);
|
||||
|
||||
setTimeout(() => {
|
||||
notification.fadeOut(700);
|
||||
}, data.length);
|
||||
setTimeout(() => {
|
||||
notification.fadeOut(700);
|
||||
}, data.length);
|
||||
|
||||
return notification;
|
||||
}
|
||||
return notification;
|
||||
};
|
||||
|
||||
@@ -2,7 +2,7 @@ fx_version 'adamant'
|
||||
game 'gta5'
|
||||
author 'ESX-Framework'
|
||||
lua54 'yes'
|
||||
version '1.9.3'
|
||||
version '1.9.4'
|
||||
description 'ESX Progressbar'
|
||||
|
||||
client_scripts { 'Progress.lua' }
|
||||
@@ -13,5 +13,4 @@ files {
|
||||
'nui/index.html',
|
||||
'nui/js/*.js',
|
||||
'nui/css/*.css',
|
||||
'nui/img/*.png',
|
||||
}
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
:root {
|
||||
--color: white;
|
||||
--bgColor: #212121;
|
||||
--color: white;
|
||||
--bgColor: #212121;
|
||||
}
|
||||
|
||||
* {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
body {
|
||||
color: var(--color);
|
||||
font-family: sans-serif;
|
||||
}
|
||||
color: var(--color);
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
@@ -1,88 +1,90 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<head>
|
||||
<script src="https://kit.fontawesome.com/a81368914c.js"></script>
|
||||
<link rel="stylesheet" href="css/style.css">
|
||||
</head>
|
||||
<body>
|
||||
<link rel="stylesheet" href="css/style.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="notifyInfo" class="notify">
|
||||
<div class="innerText">
|
||||
<i class="fas fa-info-circle icon info"></i>
|
||||
<p class="text" id="infoMessage"></p>
|
||||
</div>
|
||||
<div id="progline" class="progline">
|
||||
</div>
|
||||
<div class="innerText">
|
||||
<i class="fas fa-info-circle icon info"></i>
|
||||
<p class="text" id="infoMessage"></p>
|
||||
</div>
|
||||
<div id="progline" class="progline"></div>
|
||||
</div>
|
||||
</body>
|
||||
<script src="js/script.js"></script>
|
||||
</body>
|
||||
<script src="js/script.js"></script>
|
||||
</html>
|
||||
|
||||
<style>
|
||||
.notify {
|
||||
flex: auto;
|
||||
display: none;
|
||||
position: absolute;
|
||||
margin: 0 auto;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 100px;
|
||||
min-width: 15%;
|
||||
width: fit-content;
|
||||
height: 45px;
|
||||
background-color: rgba(5, 5, 5, 0.8);
|
||||
border-radius: 5px;
|
||||
animation: growDown 300ms ease-in-out;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
.progline {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 2px;
|
||||
width: 100%;
|
||||
border-radius: 20px;
|
||||
background: linear-gradient(
|
||||
to right,
|
||||
#0052d4,
|
||||
#4364f7,
|
||||
#6fb1fc
|
||||
); /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */
|
||||
}
|
||||
|
||||
.notify {
|
||||
flex: auto;
|
||||
display: none;
|
||||
position:absolute;
|
||||
margin: 0 auto;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 100px;
|
||||
min-width:15%;
|
||||
width:fit-content;
|
||||
height:45px;
|
||||
background-color:rgba(5, 5, 5, 0.800);
|
||||
border-radius: 5px;
|
||||
animation: growDown 300ms ease-in-out;
|
||||
padding-right: 10px;
|
||||
}
|
||||
.icon {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.progline {
|
||||
position:absolute;
|
||||
bottom:0;
|
||||
left:0;
|
||||
right:0;
|
||||
height:2px;
|
||||
width:100%;
|
||||
border-radius: 20px;
|
||||
background: linear-gradient(to right, #0052d4, #4364f7, #6fb1fc); /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */
|
||||
}
|
||||
.innerText {
|
||||
flex: auto;
|
||||
margin-top: 15px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.icon {
|
||||
border: 0;
|
||||
}
|
||||
.innerText {
|
||||
margin-left: 10px;
|
||||
}
|
||||
p {
|
||||
flex: auto;
|
||||
word-wrap: break-word;
|
||||
margin-left: 30px;
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
.innerText {
|
||||
flex: auto;
|
||||
margin-top: 15px;
|
||||
width:100%;
|
||||
}
|
||||
.innerText .icon {
|
||||
float: left;
|
||||
margin-left: 5px;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.innerText{
|
||||
margin-left: 10px;
|
||||
@keyframes growDown {
|
||||
0% {
|
||||
transform: scaleY(0);
|
||||
}
|
||||
p {
|
||||
flex: auto;
|
||||
word-wrap: break-word;
|
||||
margin-left: 30px;
|
||||
margin-top: 15px;
|
||||
80% {
|
||||
transform: scaleY(1.1);
|
||||
}
|
||||
|
||||
.innerText .icon {
|
||||
float: left;
|
||||
margin-left: 5px;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
@keyframes growDown {
|
||||
0% {
|
||||
transform: scaleY(0);
|
||||
}
|
||||
80% {
|
||||
transform: scaleY(1.1)
|
||||
}
|
||||
100% {
|
||||
transform: scaleY(1)
|
||||
}
|
||||
100% {
|
||||
transform: scaleY(1);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,69 +1,69 @@
|
||||
const codes = {
|
||||
"~r~": "red",
|
||||
"~b~": "#378cbf",
|
||||
"~g~": "green",
|
||||
"~y~": "yellow",
|
||||
"~p~": "purple",
|
||||
"~c~": "grey",
|
||||
"~m~": "#212121",
|
||||
"~u~": "black",
|
||||
"~o~": "orange"
|
||||
}
|
||||
"~r~": "red",
|
||||
"~b~": "#378cbf",
|
||||
"~g~": "green",
|
||||
"~y~": "yellow",
|
||||
"~p~": "purple",
|
||||
"~c~": "grey",
|
||||
"~m~": "#212121",
|
||||
"~u~": "black",
|
||||
"~o~": "orange",
|
||||
};
|
||||
|
||||
const elems = {
|
||||
infoMessage: document.getElementById('infoMessage'),
|
||||
notifyInfo: document.getElementById("notifyInfo"),
|
||||
progline: document.getElementById('progline')
|
||||
}
|
||||
infoMessage: document.getElementById("infoMessage"),
|
||||
notifyInfo: document.getElementById("notifyInfo"),
|
||||
progline: document.getElementById("progline"),
|
||||
};
|
||||
|
||||
const replaceColors = (str, obj) => {
|
||||
let strToReplace = str;
|
||||
let strToReplace = str;
|
||||
|
||||
for (let id in obj) {
|
||||
strToReplace = strToReplace.replace(new RegExp(id, "g"), obj[id]);
|
||||
for (let id in obj) {
|
||||
strToReplace = strToReplace.replace(new RegExp(id, "g"), obj[id]);
|
||||
}
|
||||
|
||||
return strToReplace;
|
||||
};
|
||||
|
||||
window.addEventListener("message", function ({ data }) {
|
||||
if (data.type === "Progressbar") {
|
||||
let { message } = data;
|
||||
|
||||
for (color in codes) {
|
||||
if (message.includes(color)) {
|
||||
let objArr = {};
|
||||
objArr[color] = `<span style="color: ${codes[color]}">`;
|
||||
objArr["~s~"] = "</span>";
|
||||
|
||||
let newStr = replaceColors(message, objArr);
|
||||
|
||||
message = newStr;
|
||||
}
|
||||
}
|
||||
|
||||
return strToReplace
|
||||
}
|
||||
elems.infoMessage.innerHTML = message;
|
||||
elems.notifyInfo.style.display = "block";
|
||||
|
||||
window.addEventListener('message', function({data}) {
|
||||
if (data.type === "Progressbar") {
|
||||
let { message } = data
|
||||
const start = new Date();
|
||||
const maxTime = data.length;
|
||||
const timeoutValue = Math.floor(maxTime / 100);
|
||||
animUpdate();
|
||||
|
||||
for (color in codes) {
|
||||
if (message.includes(color)) {
|
||||
let objArr = {};
|
||||
objArr[color] = `<span style="color: ${codes[color]}">`;
|
||||
objArr["~s~"] = "</span>";
|
||||
|
||||
let newStr = replaceColors(message, objArr);
|
||||
|
||||
message = newStr
|
||||
}
|
||||
}
|
||||
|
||||
elems.infoMessage.innerHTML = message
|
||||
elems.notifyInfo.style.display = "block";
|
||||
|
||||
const start = new Date();
|
||||
const maxTime = data.length;
|
||||
const timeoutValue = Math.floor(maxTime / 100);
|
||||
animUpdate();
|
||||
|
||||
function animUpdate() {
|
||||
const now = new Date();
|
||||
const timeoutDiff = now.getTime() - start.getTime();
|
||||
const prc = Math.round((timeoutDiff/maxTime)*100);
|
||||
if (prc <= 100) {
|
||||
elems.progline.style.width = prc + "%"
|
||||
this.timeoutID = setTimeout(animUpdate, timeoutValue);
|
||||
} else {
|
||||
elems.notifyInfo.style.display = "none";
|
||||
}
|
||||
}
|
||||
} else {
|
||||
elems.notifyInfo.style.display = 'none'
|
||||
clearTimeout(this.timeoutID);
|
||||
timeoutValue = 0;
|
||||
function animUpdate() {
|
||||
const now = new Date();
|
||||
const timeoutDiff = now.getTime() - start.getTime();
|
||||
const prc = Math.round((timeoutDiff / maxTime) * 100);
|
||||
if (prc <= 100) {
|
||||
elems.progline.style.width = prc + "%";
|
||||
this.timeoutID = setTimeout(animUpdate, timeoutValue);
|
||||
} else {
|
||||
elems.notifyInfo.style.display = "none";
|
||||
}
|
||||
}
|
||||
})
|
||||
} else {
|
||||
elems.notifyInfo.style.display = "none";
|
||||
clearTimeout(this.timeoutID);
|
||||
timeoutValue = 0;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -4,7 +4,7 @@ game 'gta5'
|
||||
|
||||
description 'ESX Skin'
|
||||
|
||||
version '1.9.3'
|
||||
version '1.9.4'
|
||||
lua54 'yes'
|
||||
shared_script '@es_extended/imports.lua'
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
fx_version 'adamant'
|
||||
game 'gta5'
|
||||
author 'ESX-Framework'
|
||||
version '1.9.3'
|
||||
version '1.9.4'
|
||||
description 'ESX TextUI'
|
||||
lua54 'yes'
|
||||
client_scripts { 'TextUI.lua' }
|
||||
|
||||
@@ -1,82 +1,77 @@
|
||||
:root {
|
||||
--color: white;
|
||||
--bgColor: #212121;
|
||||
--color: white;
|
||||
--bgColor: #212121;
|
||||
}
|
||||
|
||||
* {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
border: 0;
|
||||
box-sizing: border-box;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
border: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
color: var(--color);
|
||||
font-family: sans-serif;
|
||||
color: var(--color);
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
.notify {
|
||||
display: none;
|
||||
position: absolute;
|
||||
right: 2%;
|
||||
bottom: 50%;
|
||||
flex: auto;
|
||||
min-width: 15%;
|
||||
width: fit-content;
|
||||
height: 50px;
|
||||
background: rgba(5,5,5,.9);
|
||||
border-radius: .5rem;
|
||||
animation: growDown 300ms ease-in-out;
|
||||
align-items: center;
|
||||
display: none;
|
||||
position: absolute;
|
||||
right: 2%;
|
||||
bottom: 50%;
|
||||
flex: auto;
|
||||
min-width: 15%;
|
||||
width: fit-content;
|
||||
height: 50px;
|
||||
background: rgba(5, 5, 5, 0.9);
|
||||
border-radius: 0.5rem;
|
||||
animation: growDown 300ms ease-in-out;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.error {
|
||||
border-left: 5px solid #c0392b;
|
||||
border-left: 5px solid #c0392b;
|
||||
}
|
||||
|
||||
.success {
|
||||
border-left: 5px solid #2ecc71;
|
||||
border-left: 5px solid #2ecc71;
|
||||
}
|
||||
|
||||
.info {
|
||||
border-left: 5px solid #2980b9;
|
||||
border-left: 5px solid #2980b9;
|
||||
}
|
||||
|
||||
.innerText {
|
||||
padding-left: .4rem;
|
||||
padding-right: .4rem;
|
||||
padding-top: 12.5px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding-left: 0.4rem;
|
||||
padding-right: 0.4rem;
|
||||
padding-top: 12.5px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.innerText .icon {
|
||||
float: left;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.innerText .text {
|
||||
display: inline-block;
|
||||
margin-left: .5rem;
|
||||
margin-top: 4px;
|
||||
display: inline-block;
|
||||
margin-left: 0.5rem;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
|
||||
@keyframes growDown {
|
||||
0% {
|
||||
transform: scaleY(0);
|
||||
}
|
||||
80% {
|
||||
transform: scaleY(1.1)
|
||||
}
|
||||
100% {
|
||||
transform: scaleY(1)
|
||||
}
|
||||
0% {
|
||||
transform: scaleY(0);
|
||||
}
|
||||
80% {
|
||||
transform: scaleY(1.1);
|
||||
}
|
||||
100% {
|
||||
transform: scaleY(1);
|
||||
}
|
||||
}
|
||||
|
||||
.material-symbols-outlined {
|
||||
font-variation-settings:
|
||||
'FILL' 0,
|
||||
'wght' 400,
|
||||
'GRAD' 0,
|
||||
'opsz' 48
|
||||
font-variation-settings: "FILL" 0, "wght" 400, "GRAD" 0, "opsz" 48;
|
||||
}
|
||||
|
||||
@@ -1,30 +1,32 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" />
|
||||
<script src="https://kit.fontawesome.com/a81368914c.js"></script>
|
||||
<link rel="stylesheet" href="css/style.css">
|
||||
<script src="js/script.js"></script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div id="notifyInfo" class="notify info">
|
||||
<div class="innerText">
|
||||
<span class="material-symbols-outlined icon">info</span>
|
||||
<p class="text" id="infoMessage"></p>
|
||||
</div>
|
||||
</div>
|
||||
<div id="notifySuccess" class="notify success">
|
||||
<div class="innerText">
|
||||
<span class="material-symbols-outlined icon">check_circle</span>
|
||||
<p class="text" id="successMessage"></p>
|
||||
</div>
|
||||
</div>
|
||||
<div id="notifyError" class="notify error">
|
||||
<div class="innerText">
|
||||
<span class="material-symbols-outlined icon">error</span>
|
||||
<p class="text" id="errorMessage"></p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
<head>
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200"
|
||||
/>
|
||||
<script src="https://kit.fontawesome.com/a81368914c.js"></script>
|
||||
<link rel="stylesheet" href="css/style.css" />
|
||||
<script src="js/script.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="notifyInfo" class="notify info">
|
||||
<div class="innerText">
|
||||
<span class="material-symbols-outlined icon">info</span>
|
||||
<p class="text" id="infoMessage"></p>
|
||||
</div>
|
||||
</div>
|
||||
<div id="notifySuccess" class="notify success">
|
||||
<div class="innerText">
|
||||
<span class="material-symbols-outlined icon">check_circle</span>
|
||||
<p class="text" id="successMessage"></p>
|
||||
</div>
|
||||
</div>
|
||||
<div id="notifyError" class="notify error">
|
||||
<div class="innerText">
|
||||
<span class="material-symbols-outlined icon">error</span>
|
||||
<p class="text" id="errorMessage"></p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -4,82 +4,80 @@ let lastType = "";
|
||||
|
||||
// Gets the current icon it needs to use.
|
||||
const types = {
|
||||
["success"]: {
|
||||
["message"]: "successMessage",
|
||||
["id"]: "notifySuccess",
|
||||
},
|
||||
["error"]: {
|
||||
["message"]: "errorMessage",
|
||||
["id"]: "notifyError",
|
||||
},
|
||||
["info"]: {
|
||||
["message"]: "infoMessage",
|
||||
["id"]: "notifyInfo",
|
||||
}
|
||||
}
|
||||
["success"]: {
|
||||
["message"]: "successMessage",
|
||||
["id"]: "notifySuccess",
|
||||
},
|
||||
["error"]: {
|
||||
["message"]: "errorMessage",
|
||||
["id"]: "notifyError",
|
||||
},
|
||||
["info"]: {
|
||||
["message"]: "infoMessage",
|
||||
["id"]: "notifyInfo",
|
||||
},
|
||||
};
|
||||
|
||||
// the color codes example `i ~r~love~s~ donuts`
|
||||
const codes = {
|
||||
"~r~": "red",
|
||||
"~b~": "#378cbf",
|
||||
"~g~": "green",
|
||||
"~y~": "yellow",
|
||||
"~p~": "purple",
|
||||
"~c~": "grey",
|
||||
"~m~": "#212121",
|
||||
"~u~": "black",
|
||||
"~o~": "orange"
|
||||
}
|
||||
"~r~": "red",
|
||||
"~b~": "#378cbf",
|
||||
"~g~": "green",
|
||||
"~y~": "yellow",
|
||||
"~p~": "purple",
|
||||
"~c~": "grey",
|
||||
"~m~": "#212121",
|
||||
"~u~": "black",
|
||||
"~o~": "orange",
|
||||
};
|
||||
|
||||
w.addEventListener('message', (event) => {
|
||||
if (event.data.action === "show") {
|
||||
if (lastType) {
|
||||
doc.getElementById(lastType).style.display = "none";
|
||||
notification({
|
||||
type: event.data.type,
|
||||
message: event.data.message
|
||||
});
|
||||
} else {
|
||||
notification({
|
||||
type: event.data.type,
|
||||
message: event.data.message
|
||||
});
|
||||
}
|
||||
} else
|
||||
if (event.data.action === "hide") {
|
||||
if (lastType !== "") {
|
||||
doc.getElementById(lastType).style.display = "none"
|
||||
} else {
|
||||
console.log("There isn't a textUI displaying!?")
|
||||
}
|
||||
w.addEventListener("message", (event) => {
|
||||
if (event.data.action === "show") {
|
||||
if (lastType) {
|
||||
doc.getElementById(lastType).style.display = "none";
|
||||
notification({
|
||||
type: event.data.type,
|
||||
message: event.data.message,
|
||||
});
|
||||
} else {
|
||||
notification({
|
||||
type: event.data.type,
|
||||
message: event.data.message,
|
||||
});
|
||||
}
|
||||
} else if (event.data.action === "hide") {
|
||||
if (lastType !== "") {
|
||||
doc.getElementById(lastType).style.display = "none";
|
||||
} else {
|
||||
console.log("There isn't a textUI displaying!?");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const replaceColors = (str, obj) => {
|
||||
let strToReplace = str
|
||||
let strToReplace = str;
|
||||
|
||||
for (let id in obj) {
|
||||
strToReplace = strToReplace.replace(new RegExp(id, 'g'), obj[id])
|
||||
}
|
||||
for (let id in obj) {
|
||||
strToReplace = strToReplace.replace(new RegExp(id, "g"), obj[id]);
|
||||
}
|
||||
|
||||
return strToReplace
|
||||
}
|
||||
return strToReplace;
|
||||
};
|
||||
|
||||
notification = (data) => {
|
||||
for (color in codes) {
|
||||
if (data["message"].includes(color)) {
|
||||
let objArr = {};
|
||||
objArr[color] = `<span style="color: ${codes[color]}">`;
|
||||
objArr["~s~"] = "</span>";
|
||||
for (color in codes) {
|
||||
if (data["message"].includes(color)) {
|
||||
let objArr = {};
|
||||
objArr[color] = `<span style="color: ${codes[color]}">`;
|
||||
objArr["~s~"] = "</span>";
|
||||
|
||||
let newStr = replaceColors(data["message"], objArr);
|
||||
let newStr = replaceColors(data["message"], objArr);
|
||||
|
||||
data["message"] = newStr;
|
||||
}
|
||||
data["message"] = newStr;
|
||||
}
|
||||
}
|
||||
|
||||
doc.getElementById(types[data.type]["id"]).style.display = "block";
|
||||
lastType = types[data.type]["id"]
|
||||
doc.getElementById(types[data.type]["message"]).innerHTML = data["message"]
|
||||
|
||||
}
|
||||
doc.getElementById(types[data.type]["id"]).style.display = "block";
|
||||
lastType = types[data.type]["id"];
|
||||
doc.getElementById(types[data.type]["message"]).innerHTML = data["message"];
|
||||
};
|
||||
|
||||
@@ -6,7 +6,7 @@ lua54 'yes'
|
||||
|
||||
description 'Official ESX-Legacy resource for handling the Player`s Skin'
|
||||
|
||||
version '1.9.3'
|
||||
version '1.9.4'
|
||||
|
||||
client_scripts {
|
||||
'@es_extended/locale.lua',
|
||||
|
||||
Reference in New Issue
Block a user