Merge branch 'dev' into patch-4

This commit is contained in:
TheFantomas
2023-03-12 12:24:13 +01:00
committed by GitHub
60 changed files with 2728 additions and 1881 deletions
+1
View File
@@ -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,
+1 -1
View File
@@ -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'
+35 -22
View File
@@ -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
+76 -22
View File
@@ -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)
+20 -1
View File
@@ -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
+4 -1
View File
@@ -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
+1
View File
@@ -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`)
+13 -5
View File
@@ -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',
}
+10 -9
View File
@@ -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;
+31 -29
View File
@@ -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);
});
};
})();
+26 -33
View File
@@ -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));
}
};
})();
+365
View File
@@ -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',
}
+116 -7
View File
@@ -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 -13
View File
@@ -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)
+21 -20
View File
@@ -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)
+25 -10
View File
@@ -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)
+1 -1
View File
@@ -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
View File
@@ -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>
+1 -1
View File
@@ -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,
+1 -1
View File
@@ -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',
+105 -105
View File
@@ -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%;
}
+114 -40
View File
@@ -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>
+19 -13
View File
@@ -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");
});
});
+1 -1
View File
@@ -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 -1
View File
@@ -1,5 +1,5 @@
game 'common'
version '1.9.3'
version '1.9.4'
fx_version 'cerulean'
author 'ESX-Framework'
lua54 'yes'
+1 -1
View File
@@ -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'}
+2 -2
View File
@@ -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;
+182 -182
View File
@@ -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}} : &lt;{{{sliderLabel}}}&gt;{{/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}} : &lt;{{{sliderLabel}}}&gt;{{/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);
});
};
})();
+1 -1
View File
@@ -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',
+50 -50
View File
@@ -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;
}
+149 -135
View File
@@ -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);
});
};
})();
+22 -15
View File
@@ -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>
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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',
+32 -33
View File
@@ -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
View File
@@ -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);
}
};
})();
+11 -13
View File
@@ -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>
+6 -5
View File
@@ -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()
+1 -1
View File
@@ -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'}
+50 -50
View File
@@ -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;
}
+61 -28
View File
@@ -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;
}
});
};
})();
+26 -21
View File
@@ -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>
+39 -26
View File
@@ -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 -2
View File
@@ -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',
}
+45 -49
View File
@@ -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);
}
}
+10 -7
View File
@@ -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>
+49 -47
View File
@@ -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;
};
+1 -2
View File
@@ -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',
}
+7 -7
View File
@@ -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;
}
+72 -70
View File
@@ -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>
+58 -58
View File
@@ -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;
}
});
+1 -1
View File
@@ -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 -1
View File
@@ -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' }
+42 -47
View File
@@ -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;
}
+29 -27
View File
@@ -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>
+61 -63
View File
@@ -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"];
};
+1 -1
View File
@@ -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',