Revert "Rebase dev"

This commit is contained in:
Fezz
2025-10-03 14:15:17 +01:00
committed by GitHub
parent 977a567d83
commit 17199568c5
12 changed files with 141 additions and 257 deletions
+14 -15
View File
@@ -235,7 +235,6 @@ INSERT INTO `items` (`name`, `label`, `weight`, `rare`, `can_remove`) VALUES
CREATE TABLE `jobs` (
`name` varchar(50) NOT NULL,
`label` varchar(50) DEFAULT NULL,
`type` varchar(50) NOT NULL DEFAULT 'civ',
`whitelisted` tinyint(1) NOT NULL DEFAULT 0
) ENGINE=InnoDB;
@@ -243,20 +242,20 @@ CREATE TABLE `jobs` (
-- Dumping data for table `jobs`
--
INSERT INTO `jobs` (`name`, `label`, `type`, `whitelisted`) VALUES
('ambulance', 'EMS', 'ems', 0),
('cardealer', 'Cardealer', 'civ', 0),
('fisherman', 'Fisherman', 'civ', 0),
('fueler', 'Fueler', 'civ', 0),
('lumberjack', 'Lumberjack', 'civ', 0),
('mechanic', 'Mechanic', 'mechanic', 0),
('miner', 'Miner', 'civ', 0),
('police', 'LSPD', 'leo', 0),
('reporter', 'Reporter', 'civ', 0),
('slaughterer', 'Butcher', 'civ', 0),
('tailor', 'Tailor', 'civ', 0),
('taxi', 'Taxi', 'civ', 0),
('unemployed', 'Unemployed', 'civ', 0);
INSERT INTO `jobs` (`name`, `label`, `whitelisted`) VALUES
('ambulance', 'EMS', 0),
('cardealer', 'Cardealer', 0),
('fisherman', 'Fisherman', 0),
('fueler', 'Fueler', 0),
('lumberjack', 'Lumberjack', 0),
('mechanic', 'Mechanic', 0),
('miner', 'Miner', 0),
('police', 'LSPD', 0),
('reporter', 'Reporter', 0),
('slaughterer', 'Butcher', 0),
('tailor', 'Tailor', 0),
('taxi', 'Taxi', 0),
('unemployed', 'Unemployed', 0);
-- --------------------------------------------------------
@@ -585,7 +585,6 @@ function CreateExtendedPlayer(playerId, identifier, ssn, group, accounts, invent
id = jobObject.id,
name = jobObject.name,
label = jobObject.label,
type = jobObject.type,
onDuty = onDuty,
grade = tonumber(grade) or 0,
+2 -21
View File
@@ -562,7 +562,7 @@ function ESX.RefreshJobs()
if not Jobs then
-- Fallback data, if no jobs exist
ESX.Jobs["unemployed"] = { name = "unemployed", label = "Unemployed", type = "civ", whitelisted = false, grades = { ["0"] = { grade = 0, name = "unemployed", label = "Unemployed", salary = 200, skin_male = {}, skin_female = {} } } }
ESX.Jobs["unemployed"] = { name = "unemployed", label = "Unemployed", whitelisted = false, grades = { ["0"] = { grade = 0, name = "unemployed", label = "Unemployed", salary = 200, skin_male = {}, skin_female = {} } } }
else
ESX.Jobs = Jobs
end
@@ -628,34 +628,15 @@ function ESX.GetItemLabel(item)
end
end
---@param jobType string|string[]?
---@return table
function ESX.GetJobs(jobType)
function ESX.GetJobs()
while not Core.JobsLoaded do
Citizen.Wait(200)
end
if not jobType then
return ESX.Jobs
end
jobType = type(jobType) == "string" and { jobType } or jobType
local jobTypeLookup = {}
for i = 1, #jobType do
jobTypeLookup[jobType[i]] = true
end
local filteredJobs = {}
for jobName, jobObject in pairs(ESX.Jobs) do
if jobTypeLookup[jobObject.type] then
filteredJobs[jobName] = jobObject
end
end
return filteredJobs
end
---@return table
function ESX.GetItems()
return ESX.Items
-1
View File
@@ -234,7 +234,6 @@ function loadESXPlayer(identifier, playerId, isNew)
id = jobObject.id,
name = jobObject.name,
label = jobObject.label,
type = jobObject.type,
grade = tonumber(grade),
grade_name = gradeObject.name,
@@ -1,35 +0,0 @@
local esxVersion = "v1.13.5"
Core.Migrations = Core.Migrations or {}
Core.Migrations[esxVersion] = Core.Migrations[esxVersion] or {}
if GetResourceKvpInt(("esx_migration:%s"):format(esxVersion)) == 1 then
return
end
---@return boolean restartRequired
Core.Migrations[esxVersion].jobTypes = function()
print("^4[esx_migration:v1.13.5:jobTypes]^7 Adding job type column to jobs table.")
local col = MySQL.scalar.await([[
SELECT COUNT(*)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'jobs'
AND COLUMN_NAME = 'type'
]])
if col == 0 then
print("^4[esx_migration:v1.13.5:jobTypes]^7 Column not found, altering jobs table.")
MySQL.update.await([[
ALTER TABLE `jobs`
ADD COLUMN `type` VARCHAR(50) NOT NULL DEFAULT 'civ' AFTER `label`
]])
else
print("^4[esx_migration:v1.13.5:jobTypes]^7 Column already exists, migration not needed.")
return false
end
print("^4[esx_migration:v1.13.5:jobTypes]^7 Migration complete.")
return true
end
@@ -19,8 +19,8 @@ local function doesJobAndGradesExist(name, grades)
return true
end
local function generateNewJobTable(name, label, grades, jobType)
local job = { name = name, label = label, type = jobType, grades = {} }
local function generateNewJobTable(name, label, grades)
local job = { name = name, label = label, grades = {} }
for _, v in pairs(grades) do
job.grades[tostring(v.grade)] = { job_name = name, grade = v.grade, name = v.name, label = v.label, salary = v.salary, skin_male = v.skin_male or '{}', skin_female = v.skin_female or '{}' }
end
@@ -42,8 +42,7 @@ end
--- @param name string
--- @param label string
--- @param grades table
--- @param jobType string
function ESX.CreateJob(name, label, grades, jobType)
function ESX.CreateJob(name, label, grades)
local currentResourceName = GetInvokingResource()
local success = false
@@ -62,10 +61,6 @@ function ESX.CreateJob(name, label, grades, jobType)
return success
end
if type(jobType) ~= "string" then
jobType = "civ"
end
local currentJobExist = doesJobAndGradesExist(name, grades)
if currentJobExist then
@@ -74,7 +69,7 @@ function ESX.CreateJob(name, label, grades, jobType)
end
local queries = {
{ query = 'INSERT INTO `jobs` (`name`, `label`, `type`) VALUES (?, ?, ?)', values = { name, label, jobType } }
{ query = 'INSERT INTO jobs (name, label) VALUES (?, ?)', values = { name, label } }
}
for _, grade in pairs(grades) do
@@ -91,7 +86,7 @@ function ESX.CreateJob(name, label, grades, jobType)
return success
end
ESX.Jobs[name] = generateNewJobTable(name, label, grades, jobType)
ESX.Jobs[name] = generateNewJobTable(name, label, grades)
notify("SUCCESS", currentResourceName, 'Job created successfully: `%s`', name)
-41
View File
@@ -1,41 +0,0 @@
return {
["inventory"] = "الحقيبة ( الوزن %s / %s )",
["use"] = "استخدام",
["give"] = "إعطاء",
["remove"] = "رمي",
["return"] = "رجوع",
["give_to"] = "إعطاء إلى",
["amount"] = "الكمية",
["giveammo"] = "إعطاء ذخيرة",
["amountammo"] = "عدد الطلقات",
["noammo"] = "لا يوجد ما يكفي!",
["gave_item"] = "تم إعطاء %sx %s إلى %s",
["received_item"] = "استلمت %sx %s من %s",
["gave_weapon"] = "تم إعطاء %s إلى %s",
["gave_weapon_ammo"] = "تم إعطاء ~o~%sx %s لسلاح %s إلى %s",
["gave_weapon_withammo"] = "تم إعطاء %s مع ~o~%sx %s إلى %s",
["gave_weapon_hasalready"] = "%s لديه بالفعل %s",
["gave_weapon_noweapon"] = "%s لا يملك هذا السلاح",
["received_weapon"] = "استلمت %s من %s",
["received_weapon_ammo"] = "استلمت ~o~%sx %s لسلاحك %s من %s",
["received_weapon_withammo"] = "استلمت %s مع ~o~%sx %s من %s",
["received_weapon_hasalready"] = "%s حاول أن يعطيك %s، لكنك تملك هذا السلاح بالفعل",
["received_weapon_noweapon"] = "%s حاول أن يعطيك ذخيرة لسلاح %s، لكنك لا تملك هذا السلاح",
["gave_account_money"] = "تم إعطاء $%s (%s) إلى %s",
["received_account_money"] = "استلمت $%s (%s) من %s",
["amount_invalid"] = "كمية غير صالحة",
["players_nearby"] = "لا يوجد لاعبين قريبين",
["ex_inv_lim"] = "لا يمكن تنفيذ العملية، الوزن تجاوز الحد %s",
["imp_invalid_quantity"] = "لا يمكن تنفيذ العملية، الكمية غير صالحة",
["imp_invalid_amount"] = "لا يمكن تنفيذ العملية، المبلغ غير صالح",
["threw_standard"] = "تم رمي %sx %s",
["threw_account"] = "تم رمي $%s %s",
["threw_weapon"] = "تم رمي %s",
["threw_weapon_ammo"] = "تم رمي %s مع ~o~%sx %s",
["threw_weapon_already"] = "لديك هذا السلاح بالفعل",
["threw_cannot_pickup"] = "الحقيبة ممتلئ، لا يمكنك الالتقاط!",
["threw_pickup_prompt"] = "اضغط E للالتقاط",
["keymap_showinventory"] = "فتح الحقيبة",
["locale_currency"] = "$%s",
["ammo_rounds"] = "طلقات"
}
+49 -49
View File
@@ -1,12 +1,12 @@
@import url("https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap");
@import url("https://fonts.googleapis.com/css?family=Montserrat&display=swap");
#controls {
font-family: "Poppins", sans-serif;
font-size: 2.77vh;
font-family: montserrat;
font-size: 3em;
color: #fff;
position: absolute;
bottom: 3.7vh;
right: 3.7vh;
bottom: 40;
right: 40;
}
.controls {
@@ -14,17 +14,17 @@
}
.dialog {
font-family: "Poppins", sans-serif;
background: #212121;
font-family: montserrat;
background: rgba(33, 33, 33, 0.8);
color: #fff;
position: absolute;
border-radius: 0.46vh;
border-top-left-radius: 5px;
border-top-right-radius: 5px;
overflow: hidden;
top: 50%;
left: 50%;
width: 55.6vh;
height: 14.1vh;
padding-bottom: 1vh;
width: 600px;
height: 152px;
transform: translate(-50%, -50%);
}
@@ -32,21 +32,17 @@
display: flex;
flex-basis: 100%;
align-items: center;
justify-content: center;
color: #fff;
font-size: 1.6vh;
font-weight: 500;
text-transform: uppercase;
}
.dialog.big {
height: 18.5vh;
height: 200px;
}
.dialog .head {
background: #161616;
background: rgba(25, 25, 25, 0.9);
text-align: center;
height: 3.7vh;
height: 40px;
}
.dialog .head span::before {
@@ -58,17 +54,17 @@
.dialog input[type="text"] {
width: 60%;
height: 2.96vh;
height: 32px;
outline: 0;
background: none;
text-align: center;
margin-top: 2.4vh;
margin-left: 11.6vh;
font-size: 1.48vh;
margin-top: 26px;
margin-left: 125px;
font-size: large;
transition: all 0.2s ease-in-out;
color: white;
border: 0.05vh solid #ffffff3b;
border-radius: 0.3vh;
border: 0.5px solid #ffffff3b;
border-radius: 0px;
}
.dialog input[type="text"]:active,
@@ -78,19 +74,18 @@
.dialog textarea {
width: 100%;
height: 11.85vh;
height: 128px;
}
.dialog button[name="submit"] {
width: 17.6%;
height: 2.96vh;
margin-left: 14.8vh;
font-weight: 500;
color: #fb9b04;
border-radius: 0.5vh;
font-size: 1.2vh;
background: #fb9c0433;
height: 32px;
margin-left: 160px;
font-weight: 300;
color: rgb(37, 34, 53);
border-radius: 10px;
text-transform: uppercase;
background: rgb(50, 79, 208);
outline: 0;
border: none;
transition: all 0.2s ease-in-out;
@@ -103,30 +98,35 @@
.dialog button[name="cancel"] {
width: 17.6%;
height: 2.96vh;
margin-left: 5.6vh;
font-weight: 500;
color: #fefefe;
border-radius: 0.5vh;
font-size: 1.2vh;
background: #94949433;
outline: 0;
height: 32px;
margin-left: 60px;
border: none;
text-transform: uppercase;
font-weight: 200;
border-radius: 10px;
color: rgb(53, 34, 34);
outline: 0;
background: #c74545;
transition: all 0.2s ease-in-out;
}
.dialog button[name="cancel"]:hover {
letter-spacing: 0.09vh;
transform: scale(1.05) translate(-0%, 50%);
letter-spacing: 1px;
color: #ffffff;
width: 17.6%;
}
.dialog button[name="submit"]:hover {
letter-spacing: 0.09vh;
transform: scale(1.05) translate(-0%, 50%);
letter-spacing: 1px;
color: white;
width: 17.6%;
}
* {
font-family: Poppins !important;
.head::before,
.head::after {
content: "";
flex-grow: 1;
background: #00e1ff;
height: 2px;
margin: 0px 3px;
}
+1
View File
@@ -3,6 +3,7 @@
<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>
@@ -5,7 +5,7 @@
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>ESX MULTICHARACTER</title>
<script type="module" crossorigin src="./assets/index-OCpTJ5nO.js"></script>
<script type="module" crossorigin src="./assets/index-DejQJnIG.js"></script>
<link rel="stylesheet" crossorigin href="./assets/index-Kwy28xkx.css">
</head>
<body>
+20 -34
View File
@@ -1,61 +1,47 @@
import CharacterSelection from "./components/CharacterSelection";
import { useState, useEffect } from "react";
import { useNuiEvent } from "./utils/useNuiEvent";
import { Character, Locale } from "./types/Character";
import { fetchNui } from "./utils/fetchNui";
import CharacterSelection from './components/CharacterSelection';
import { useState, useEffect } from 'react';
import { useNuiEvent } from './utils/useNuiEvent'
import { Character, Locale } from './types/Character';
import { fetchNui } from './utils/fetchNui';
function App() {
const [isVisible, setIsVisible] = useState<boolean>(false);
const [characters, setCharacters] = useState<Character[]>([]);
const [Candelete, setCandelete] = useState<boolean>(false);
const [MaxAllowedSlot, setMaxAllowedSlot] = useState<number>(0);
const [locale, setLocale] = useState<Locale>({
char_info_title: "",
play: "",
title: "",
});
const [locale, setLocale] = useState<Locale>({ char_info_title: '', play: '', title: '' });
useEffect(() => {
fetchNui("nuiReady");
}, []);
fetchNui('nuiReady')
}, [])
useNuiEvent("ToggleMulticharacter", (data: any) => {
useNuiEvent('ToggleMulticharacter', (data:any) => {
if (data.show) {
const validCharacters = data.Characters.filter(
(char: any) => char !== null
);
const parsedCharacters: Character[] = validCharacters.map(
(char: any, index: number) => ({
const validCharacters = data.Characters.filter((char: any) => char !== null);
const parsedCharacters: Character[] = validCharacters.map((char: any, index: number) => ({
id: char.id.toString(),
name: `${char.firstname} ${char.lastname}`,
birthDate: char.dateofbirth,
gender: char.sex,
gender: char.sex?.toUpperCase() === 'MALE' ? 'MALE' : 'FEMALE',
occupation: char.job,
disabled: char.disabled,
isActive: index === 0,
})
);
}));
setIsVisible(true);
setCharacters(parsedCharacters);
setCandelete(data.CanDelete);
setMaxAllowedSlot(data.AllowedSlot);
setLocale(data.Locale);
setMaxAllowedSlot(data.AllowedSlot)
setLocale(data.Locale)
} else {
setIsVisible(false);
setCharacters([]);
}
});
return (
isVisible && (
<CharacterSelection
initialCharacters={characters}
Candelete={Candelete}
MaxAllowedSlot={MaxAllowedSlot}
locale={locale}
/>
)
}
})
return isVisible && (
<CharacterSelection initialCharacters={characters} Candelete={Candelete} MaxAllowedSlot={MaxAllowedSlot} locale={locale} />
);
}