diff --git a/README.md b/README.md
index cec80b0c..2d466b10 100644
--- a/README.md
+++ b/README.md
@@ -34,6 +34,12 @@ start esx_identity
- If you are using esx_policejob or esx_society, you need to enable the following in the scripts' `config.lua`:
```Config.EnableESXIdentity = true```
+### Commands
+```
+/char
+/chardel
+```
+
# Legal
### License
esx_identity - rp characters
diff --git a/client/main.lua b/client/main.lua
new file mode 100644
index 00000000..238a485e
--- /dev/null
+++ b/client/main.lua
@@ -0,0 +1,95 @@
+ESX = nil
+local loadingScreenFinished = false
+
+Citizen.CreateThread(function()
+ while ESX == nil do
+ TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end)
+ Citizen.Wait(0)
+ end
+end)
+
+RegisterNetEvent('esx_identity:alreadyRegistered')
+AddEventHandler('esx_identity:alreadyRegistered', function()
+ while not loadingScreenFinished do
+ Citizen.Wait(100)
+ end
+
+ TriggerEvent('esx_skin:playerRegistered')
+end)
+
+AddEventHandler('esx:loadingScreenOff', function()
+ loadingScreenFinished = true
+end)
+
+if not Config.UseDeferrals then
+ local guiEnabled, isDead = false, false
+
+ AddEventHandler('esx:onPlayerDeath', function(data)
+ isDead = true
+ end)
+
+ AddEventHandler('esx:onPlayerSpawn', function(spawn)
+ isDead = false
+ end)
+
+ function EnableGui(state)
+ SetNuiFocus(state, state)
+ guiEnabled = state
+
+ SendNUIMessage({
+ type = "enableui",
+ enable = state
+ })
+ end
+
+ RegisterNetEvent('esx_identity:showRegisterIdentity')
+ AddEventHandler('esx_identity:showRegisterIdentity', function()
+ TriggerEvent('esx_skin:resetFirstSpawn')
+
+ if not isDead then
+ EnableGui(true)
+ end
+ end)
+
+ RegisterNUICallback('register', function(data, cb)
+ ESX.TriggerServerCallback('esx_identity:registerIdentity', function(callback)
+ if callback then
+ ESX.ShowNotification(_U('thank_you_for_registering'))
+ EnableGui(false)
+ TriggerEvent('esx_skin:playerRegistered')
+ else
+ ESX.ShowNotification(_U('registration_error'))
+ end
+ end, data)
+ end)
+
+ Citizen.CreateThread(function()
+ while true do
+ Citizen.Wait(0)
+
+ if guiEnabled then
+ DisableControlAction(0, 1, true) -- LookLeftRight
+ DisableControlAction(0, 2, true) -- LookUpDown
+ DisableControlAction(0, 106, true) -- VehicleMouseControlOverride
+ DisableControlAction(0, 142, true) -- MeleeAttackAlternate
+ DisableControlAction(0, 30, true) -- MoveLeftRight
+ DisableControlAction(0, 31, true) -- MoveUpDown
+ DisableControlAction(0, 21, true) -- disable sprint
+ DisableControlAction(0, 24, true) -- disable attack
+ DisableControlAction(0, 25, true) -- disable aim
+ DisableControlAction(0, 47, true) -- disable weapon
+ DisableControlAction(0, 58, true) -- disable weapon
+ DisableControlAction(0, 263, true) -- disable melee
+ DisableControlAction(0, 264, true) -- disable melee
+ DisableControlAction(0, 257, true) -- disable melee
+ DisableControlAction(0, 140, true) -- disable melee
+ DisableControlAction(0, 141, true) -- disable melee
+ DisableControlAction(0, 143, true) -- disable melee
+ DisableControlAction(0, 75, true) -- disable exit vehicle
+ DisableControlAction(27, 75, true) -- disable exit vehicle
+ else
+ Citizen.Wait(500)
+ end
+ end
+ end)
+end
diff --git a/config.lua b/config.lua
index 96b0472d..3d37568a 100644
--- a/config.lua
+++ b/config.lua
@@ -1,7 +1,12 @@
Config = {}
Config.Locale = 'en'
-Config.MinHeight = 24 -- Minimum Height
-Config.MaxHeight = 96 -- Maximum Height
-Config.HighestYear = 2020 -- The highest year that can be used in date of birth
-Config.LowestYear = 1900 -- The lowest year that can be used in date of birth
-Config.MaxNameLength = 15 -- You must also change the SQL structure for 'firstname' and 'lastname' in the `users` table
\ No newline at end of file
+Config.EnableCommands = true
+Config.UseSteamID = false
+Config.UseDeferrals = true
+Config.MaxNameLength = 16
+Config.MinHeight = 48
+Config.MaxHeight = 96
+Config.LowestYear = 1900
+Config.HighestYear = 2020
+
+Config.EnableDebugging = false
\ No newline at end of file
diff --git a/esx_identity.sql b/esx_identity.sql
index 56b88ae4..c9e411d5 100644
--- a/esx_identity.sql
+++ b/esx_identity.sql
@@ -1,9 +1,9 @@
USE `es_extended`;
ALTER TABLE `users`
- ADD COLUMN `firstname` VARCHAR(15) NULL DEFAULT NULL,
- ADD COLUMN `lastname` VARCHAR(15) NULL DEFAULT NULL,
+ ADD COLUMN `firstname` VARCHAR(16) NULL DEFAULT NULL,
+ ADD COLUMN `lastname` VARCHAR(16) NULL DEFAULT NULL,
ADD COLUMN `dateofbirth` VARCHAR(10) NULL DEFAULT NULL,
ADD COLUMN `sex` VARCHAR(1) NULL DEFAULT NULL,
- ADD COLUMN `height` VARCHAR(3) NULL DEFAULT NULL
+ ADD COLUMN `height` INT(2) NULL DEFAULT NULL
;
\ No newline at end of file
diff --git a/fxmanifest.lua b/fxmanifest.lua
index 4917c8cb..09853b6a 100644
--- a/fxmanifest.lua
+++ b/fxmanifest.lua
@@ -4,7 +4,7 @@ game 'gta5'
description 'ESX Identity'
-version '1.3.0'
+version '1.4.0'
server_scripts {
'@es_extended/locale.lua',
@@ -15,4 +15,21 @@ server_scripts {
'server/main.lua'
}
+client_scripts {
+ '@es_extended/locale.lua',
+ 'locales/en.lua',
+ 'locales/cs.lua',
+ 'config.lua',
+ 'client/main.lua'
+}
+
+ui_page 'html/index.html'
+
+files {
+ 'html/index.html',
+ 'html/js/script.js',
+ 'html/css/style.css',
+ 'html/img/esx_identity.png'
+}
+
dependency 'es_extended'
diff --git a/html/css/style.css b/html/css/style.css
new file mode 100644
index 00000000..eaa2535e
--- /dev/null
+++ b/html/css/style.css
@@ -0,0 +1,127 @@
+body {
+ font-family: sans-serif;
+ overflow: hidden;
+ display: none;
+ color: #000000;
+}
+
+.dialog {
+ width: 332px;
+ opacity : 0.95;
+ position : absolute;
+ margin-left: auto;
+ margin-right: auto;
+ top : 30.0%;
+ padding: 10px;
+ left : 50%; /* à 50%/50% du parent référent */
+ transform : translate(-50%); /* décalage de 50% de sa propre taille */
+ background-color: #B7B7B7;
+ border-radius : 4px;
+ box-shadow: 0px 0px 50px 0px #000;
+ border-left:5px solid #000;
+ border:1px inset;
+ margin:5px;
+ margin-bottom:20px;
+ color: #000000;
+}
+
+input {
+ width: 100%;
+ padding: 10px;
+ text-align:left;
+ color: #000000;
+}
+
+::placeholder { /* Chrome, Firefox, Opera, Safari 10.1+ */
+ color: black;
+ opacity: 1; /* Firefox */
+}
+
+.radio-toolbar input[type="radio"] {
+ opacity: 0;
+ position: absolute;
+ width: 36%;
+}
+
+.radio-toolbar label {
+ display: inline-block;
+ margin-top: 5px;
+ background-color: #ddd;
+ padding: 10px 20px;
+ font-family: sans-serif, Arial;
+ font-size: 16px;
+ color: #000000;
+ border: 2px solid #444;
+ border-radius: 4px;
+ width: 36%;
+}
+
+.radio-toolbar input[type="radio"]:checked + label {
+ width: 36%;
+ background-color:#3399FF;
+ border-color: #0033FF;
+ color: #000000;
+}
+
+.radio-toolbar input[type="radio"]:focus + label {
+ border: 2px solid #444;
+ width: 36%;
+ color: #000000;
+}
+
+.radio-toolbar label:hover {
+ background-color: #dfd;
+ width: 36%;
+ color: #000000;
+}
+
+button {
+ display: block;
+ margin-top: 5px;
+ padding: 10px;
+ background-color: #373737;
+ border: 2px solid #444;
+ color: #FFFFFF;
+ width: 100%;
+}
+
+h1 {
+ display: block;
+ margin-top: 5px;
+ margin-right: 5px;
+ padding: 10px;
+ background-color: #506be6;
+ color: #000000;
+ width: 93%;
+ text-align: center;
+}
+
+.range-wrap {
+ position: relative;
+ margin: 0 auto 3rem;
+}
+
+.range {
+ width: 100%;
+}
+
+.bubble {
+ background: #3399FF;
+ color: black;
+ padding: 4px 12px;
+ position: absolute;
+ border-radius: 4px;
+ left: 50%;
+ transform: translateX(-50%);
+}
+
+.bubble::after {
+ content: "";
+ position: absolute;
+ width: 2px;
+ height: 2px;
+ background: #3399FF;
+ color: black;
+ top: -1px;
+ left: 50%;
+}
\ No newline at end of file
diff --git a/html/img/esx_identity.png b/html/img/esx_identity.png
new file mode 100644
index 00000000..dcfc17c4
Binary files /dev/null and b/html/img/esx_identity.png differ
diff --git a/html/index.html b/html/index.html
new file mode 100644
index 00000000..182d344a
--- /dev/null
+++ b/html/index.html
@@ -0,0 +1,163 @@
+
+
+
+
+
+
+
+
+
+
+

+
+
If the submit button doesn't work, please ensure that you've entered the fields correctly.
+
+
+
+
+
diff --git a/html/index_heightslider.html b/html/index_heightslider.html
new file mode 100644
index 00000000..182d344a
--- /dev/null
+++ b/html/index_heightslider.html
@@ -0,0 +1,163 @@
+
+
+
+
+
+
+
+
+
+
+

+
+
If the submit button doesn't work, please ensure that you've entered the fields correctly.
+
+
+
+
+
diff --git a/html/index_heighttext.html b/html/index_heighttext.html
new file mode 100644
index 00000000..13896e58
--- /dev/null
+++ b/html/index_heighttext.html
@@ -0,0 +1,150 @@
+
+
+
+
+
+
+
+
+
+
+

+
+
If the submit button doesn't work, please ensure that you've entered the fields correctly.
+
+
+
+
+
diff --git a/html/index_options/index_heightslider.html b/html/index_options/index_heightslider.html
new file mode 100644
index 00000000..182d344a
--- /dev/null
+++ b/html/index_options/index_heightslider.html
@@ -0,0 +1,163 @@
+
+
+
+
+
+
+
+
+
+
+

+
+
If the submit button doesn't work, please ensure that you've entered the fields correctly.
+
+
+
+
+
diff --git a/html/index_options/index_heighttext.html b/html/index_options/index_heighttext.html
new file mode 100644
index 00000000..13896e58
--- /dev/null
+++ b/html/index_options/index_heighttext.html
@@ -0,0 +1,150 @@
+
+
+
+
+
+
+
+
+
+
+

+
+
If the submit button doesn't work, please ensure that you've entered the fields correctly.
+
+
+
+
+
diff --git a/html/js/script.js b/html/js/script.js
new file mode 100644
index 00000000..a6a5afce
--- /dev/null
+++ b/html/js/script.js
@@ -0,0 +1,34 @@
+$(function() {
+ window.addEventListener('message', function(event) {
+ if (event.data.type == "enableui") {
+ document.body.style.display = event.data.enable ? "block" : "none";
+ }
+ });
+
+ $("#register").submit(function(event) {
+ event.preventDefault(); // Prevent form from submitting
+
+ // Verify date
+ var date = $("#dateofbirth").val();
+ var dateCheck = new Date($("#dateofbirth").val());
+
+ if (dateCheck == "Invalid Date") {
+ date == "invalid";
+ }
+ else {
+ const ye = new Intl.DateTimeFormat('en', { year: 'numeric' }).format(dateCheck)
+ const mo = new Intl.DateTimeFormat('en', { month: '2-digit' }).format(dateCheck)
+ const da = new Intl.DateTimeFormat('en', { day: '2-digit' }).format(dateCheck)
+
+ var formattedDate = `${mo}/${da}/${ye}`;
+
+ $.post('http://esx_identity/register', JSON.stringify({
+ firstname: $("#firstname").val(),
+ lastname: $("#lastname").val(),
+ dateofbirth: formattedDate,
+ sex: $("input[type='radio'][name='sex']:checked").val(),
+ height: $("#height").val()
+ }));
+ }
+ });
+});
diff --git a/html/localization/cs_index(outofdate).html b/html/localization/cs_index(outofdate).html
new file mode 100644
index 00000000..1dd357a9
--- /dev/null
+++ b/html/localization/cs_index(outofdate).html
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/html/localization/fi_index(outofdate).html b/html/localization/fi_index(outofdate).html
new file mode 100644
index 00000000..87ca250a
--- /dev/null
+++ b/html/localization/fi_index(outofdate).html
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/html/localization/ko_index(outofdate).html b/html/localization/ko_index(outofdate).html
new file mode 100644
index 00000000..c04fe9b7
--- /dev/null
+++ b/html/localization/ko_index(outofdate).html
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/html/localization/sv_index(outofdate).html b/html/localization/sv_index(outofdate).html
new file mode 100644
index 00000000..7706c17b
--- /dev/null
+++ b/html/localization/sv_index(outofdate).html
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/locales/cs.lua b/locales/cs.lua
index 98172461..80c6a267 100644
--- a/locales/cs.lua
+++ b/locales/cs.lua
@@ -1,6 +1,11 @@
Locales['cs'] = {
- ['data_incorrect'] = 'data byla zadána nesprávně. Prosím zkuste to znovu.',
- ['invalid_format'] = 'data byla nesprávně naformátována. Prosím zkuste to znovu.',
- ['no_identifier'] = '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.',
- ['missing_identity'] = 'there was an error loading your character!\nError code: identity-missing\n\nIt seems like your identity is missing, try connecting again.',
+ ['show_registration'] = 'zobrazit registracni menu',
+ ['show_active_character'] = 'zobrazit aktivni postavy',
+ ['delete_character'] = 'smazat svou stavajici postavu a vytvorit novou',
+ ['deleted_character'] = 'vase postava byla smazana.',
+ ['not_registered'] = 'nemas zaregistrovanou postavu.',
+ ['active_character'] = '~b~aktivni postava:~s~ %s %s',
+ ['already_registered'] = 'jiz mas zaregistrovanou postavu.',
+ ['failed_identity'] = 'nastaveni vasi postavy selhalo, zkus to prosim znovu pozdeji nebo kontaktuj majitele serveru!',
+ ['create_a_character'] = 'aby jsi mohl/a hrat, tak se musis registrovat.'
}
diff --git a/locales/en.lua b/locales/en.lua
index a8e381e4..165ee7ae 100644
--- a/locales/en.lua
+++ b/locales/en.lua
@@ -1,6 +1,33 @@
Locales['en'] = {
- ['data_incorrect'] = 'data entered incorrectly. Please try again.',
- ['invalid_format'] = 'data formatted incorrectly. Please try again.',
- ['no_identifier'] = '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.',
- ['missing_identity'] = 'there was an error loading your character!\nError code: identity-missing\n\nIt seems like your identity is missing, try connecting again.',
+ ['show_active_character'] = 'Show Active Character',
+ ['active_character'] = 'Active Character: ~b~%s~s~',
+ ['error_active_character'] = "There was an error retrieving your name. Please contact an admin.",
+ ['delete_character'] = 'Delete Your Character And Create A New One',
+ ['deleted_character'] = 'Your character has been deleted.',
+ ['error_delete_character'] = "There was an error deleting your character. Please contact an admin.",
+ ['thank_you_for_registering'] = "Thank you for registering. Have fun.",
+ ['registration_error'] = "There was an error during registration. Please contact an admin.",
+ ['debug_xPlayer_get_first_name'] = "Return Your First Name",
+ ['debug_xPlayer_get_last_name'] = "Return Your Last Name",
+ ['debug_xPlayer_get_full_name'] = "Return Your Full Name",
+ ['debug_xPlayer_get_sex'] = "Return Your Sex",
+ ['debug_xPlayer_get_dob'] = "Return Your DOB",
+ ['debug_xPlayer_get_height'] = "Return Your Height",
+ ['error_debug_xPlayer_get_first_name'] = "There was an error retrieving your first name.",
+ ['error_debug_xPlayer_get_last_name'] = "There was an error retrieving your last name.",
+ ['error_debug_xPlayer_get_full_name'] = "There was an error retrieving your full name.",
+ ['error_debug_xPlayer_get_sex'] = "There was an error retrieving your sex.",
+ ['error_debug_xPlayer_get_dob'] = "There was an error retrieving your date of birth.",
+ ['error_debug_xPlayer_get_height'] = "There was an error retrieving your height.",
+ ['return_debug_xPlayer_get_first_name'] = "First Name: ~b~%s",
+ ['return_debug_xPlayer_get_last_name'] = "Last Name: ~b~%s",
+ ['return_debug_xPlayer_get_full_name'] = "Full Name: ~b~%s",
+ ['return_debug_xPlayer_get_sex'] = "Sex: ~b~%s",
+ ['return_debug_xPlayer_get_dob'] = "DOB: ~b~%s",
+ ['return_debug_xPlayer_get_height'] = "Height: ~b~%s Inches",
+ ['data_incorrect'] = 'Data entered incorrectly. Please try again.',
+ ['invalid_format'] = 'Data formatted incorrectly. Please try again.',
+ ['no_identifier'] = '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.',
+ ['missing_identity'] = 'There was an error loading your character!\nError code: identity-missing\n\nIt seems like your identity is missing, try connecting again.',
+ ['deleted_identity'] = 'Your character has been deleted. Please login again in order to create a new character.'
}
diff --git a/server/main.lua b/server/main.lua
index 3fbc4962..ede6b5bd 100644
--- a/server/main.lua
+++ b/server/main.lua
@@ -1,95 +1,455 @@
ESX = nil
local playerIdentity = {}
-
+local alreadyRegistered = {}
TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end)
-AddEventHandler('playerConnecting', function(playerName, setKickReason, deferrals)
- deferrals.defer()
- local playerId, identifier = source
- Citizen.Wait(100)
-
- for k,v in ipairs(GetPlayerIdentifiers(playerId)) do
- if string.match(v, 'license:') then
- identifier = string.sub(v, 9)
- break
+if Config.UseDeferrals then
+ AddEventHandler('playerConnecting', function(playerName, setKickReason, deferrals)
+ deferrals.defer()
+ local playerId, identifier = source
+ Citizen.Wait(100)
+
+ if Config.UseSteamID then
+ for k,v in ipairs(GetPlayerIdentifiers(playerId)) do
+ if string.match(v, 'steam:') then
+ identifier = v
+ break
+ end
+ end
+ else
+ for k,v in ipairs(GetPlayerIdentifiers(playerId)) do
+ if string.match(v, 'license:') then
+ identifier = string.sub(v, 9)
+ break
+ end
+ end
end
- end
+
+ if identifier then
+ MySQL.Async.fetchAll('SELECT firstname, lastname, dateofbirth, sex, height FROM users WHERE identifier = @identifier', {
+ ['@identifier'] = identifier
+ }, function(result)
+ if result[1] then
+ if result[1].firstname then
+ playerIdentity[identifier] = {
+ firstName = result[1].firstname,
+ lastName = result[1].lastname,
+ dateOfBirth = result[1].dateofbirth,
+ sex = result[1].sex,
+ height = result[1].height
+ }
+
+ deferrals.done()
+ else
+ deferrals.presentCard([==[{"type": "AdaptiveCard","body":[{"type":"Container","items":[{"type":"ColumnSet","columns":[{"type":"Column","items":[{"type":"Input.Text","placeholder":"First Name","id":"firstname","maxLength":15},{"type":"Input.Text","placeholder":"Date of Birth (MM/DD/YYYY)","id":"dateofbirth","maxLength":10}],"width":"stretch"},{"type":"Column","width":"stretch","items":[{"type":"Input.Text","placeholder":"Last Name","id":"lastname","maxLength":15},{"type":"Input.Text","placeholder":"Height (48-96 inches)","id":"height","maxLength":2}]}]},{"type":"Input.ChoiceSet","placeholder":"Sex","choices":[{"title":"Male","value":"m"},{"title":"Female","value":"f"}],"style":"expanded","id":"sex"}]},{"type": "ActionSet","actions": [{"type":"Action.Submit","title":"Submit"}]}],"$schema": "http://adaptivecards.io/schemas/adaptive-card.json","version":"1.0"}]==], function(data, rawData)
+ if data.firstname == '' or data.lastname == '' or data.dateofbirth == '' or data.sex == '' or data.height == '' then
+ deferrals.done(_U('data_incorrect'))
+ else
+ if checkNameFormat(data.firstname) and checkNameFormat(data.lastname) and checkDOBFormat(data.dateofbirth) and checkSexFormat(data.sex) and checkHeightFormat(data.height) then
+ playerIdentity[identifier] = {
+ firstName = formatName(data.firstname),
+ lastName = formatName(data.lastname),
+ dateOfBirth = data.dateofbirth,
+ sex = data.sex,
+ height = tonumber(data.height),
+ saveToDatabase = true
+ }
+
+ deferrals.done()
+ else
+ deferrals.done(_U('invalid_format'))
+ end
+ end
+ end)
+ end
+ else
+ deferrals.presentCard([==[{"type": "AdaptiveCard","body":[{"type":"Container","items":[{"type":"ColumnSet","columns":[{"type":"Column","items":[{"type":"Input.Text","placeholder":"First Name","id":"firstname","maxLength":15},{"type":"Input.Text","placeholder":"Date of Birth (MM/DD/YYYY)","id":"dateofbirth","maxLength":10}],"width":"stretch"},{"type":"Column","width":"stretch","items":[{"type":"Input.Text","placeholder":"Last Name","id":"lastname","maxLength":15},{"type":"Input.Text","placeholder":"Height (48-96 inches)","id":"height","maxLength":2}]}]},{"type":"Input.ChoiceSet","placeholder":"Sex","choices":[{"title":"Male","value":"m"},{"title":"Female","value":"f"}],"style":"expanded","id":"sex"}]},{"type": "ActionSet","actions": [{"type":"Action.Submit","title":"Submit"}]}],"$schema": "http://adaptivecards.io/schemas/adaptive-card.json","version":"1.0"}]==], function(data, rawData)
+ if data.firstname == '' or data.lastname == '' or data.dateofbirth == '' or data.sex == '' or data.height == '' then
+ deferrals.done(_U('data_incorrect'))
+ else
+ if checkNameFormat(data.firstname) and checkNameFormat(data.lastname) and checkDOBFormat(data.dateofbirth) and checkSexFormat(data.sex) and checkHeightFormat(data.height) then
+ playerIdentity[identifier] = {
+ firstName = formatName(data.firstname),
+ lastName = formatName(data.lastname),
+ dateOfBirth = data.dateofbirth,
+ sex = data.sex,
+ height = tonumber(data.height),
+ saveToDatabase = true
+ }
+
+ deferrals.done()
+ else
+ deferrals.done(_U('invalid_format'))
+ end
+ end
+ end)
+ end
+ end)
+ else
+ deferrals.done(_U('no_identifier'))
+ end
+ end)
+
+ RegisterNetEvent('esx:playerLoaded')
+ AddEventHandler('esx:playerLoaded', function(playerId, xPlayer)
+ if playerIdentity[xPlayer.identifier] then
+ local currentIdentity = playerIdentity[xPlayer.identifier]
+
+ xPlayer.setName(('%s %s'):format(currentIdentity.firstName, currentIdentity.lastName))
+ xPlayer.set('firstName', currentIdentity.firstName)
+ xPlayer.set('lastName', currentIdentity.lastName)
+ xPlayer.set('dateofbirth', currentIdentity.dateOfBirth)
+ xPlayer.set('sex', currentIdentity.sex)
+ xPlayer.set('height', currentIdentity.height)
+
+ if currentIdentity.saveToDatabase then
+ saveIdentityToDatabase(xPlayer.identifier, currentIdentity)
+ end
- if identifier then
+ Citizen.Wait(1000)
+ alreadyRegistered[xPlayer.identifier] = true
+ TriggerClientEvent('esx_identity:alreadyRegistered', xPlayer.source)
+
+ playerIdentity[xPlayer.identifier] = nil
+ else
+ xPlayer.kick(_('missing_identity'))
+ end
+ end)
+elseif not Config.UseDeferrals then
+ AddEventHandler('playerConnecting', function(playerName, setKickReason, deferrals)
+ deferrals.defer()
+ local playerId, identifier = source
+ Citizen.Wait(100)
+
+ if Config.UseSteamID then
+ for k,v in ipairs(GetPlayerIdentifiers(playerId)) do
+ if string.match(v, 'steam:') then
+ identifier = v
+ break
+ end
+ end
+ else
+ for k,v in ipairs(GetPlayerIdentifiers(playerId)) do
+ if string.match(v, 'license:') then
+ identifier = string.sub(v, 9)
+ break
+ end
+ end
+ end
+
+ if identifier then
+ MySQL.Async.fetchAll('SELECT firstname, lastname, dateofbirth, sex, height FROM users WHERE identifier = @identifier', {
+ ['@identifier'] = identifier
+ }, function(result)
+ if result[1] then
+ if result[1].firstname then
+ playerIdentity[identifier] = {
+ firstName = result[1].firstname,
+ lastName = result[1].lastname,
+ dateOfBirth = result[1].dateofbirth,
+ sex = result[1].sex,
+ height = result[1].height
+ }
+
+ alreadyRegistered[identifier] = true
+
+ deferrals.done()
+ else
+ playerIdentity[identifier] = nil
+ alreadyRegistered[identifier] = false
+ deferrals.done()
+ end
+ else
+ playerIdentity[identifier] = nil
+ alreadyRegistered[identifier] = false
+ deferrals.done()
+ end
+ end)
+ else
+ deferrals.done(_U('no_identifier'))
+ end
+ end)
+
+ AddEventHandler('onResourceStart', function(resource)
+ if resource == GetCurrentResourceName() then
+ Citizen.Wait(1000)
+
+ while not ESX do
+ Citizen.Wait(10)
+ end
+
+ local xPlayers = ESX.GetPlayers()
+
+ for i=1, #xPlayers, 1 do
+ local xPlayer = ESX.GetPlayerFromId(xPlayers[i])
+
+ if xPlayer then
+ checkIdentity(xPlayer)
+ end
+ end
+ end
+ end)
+
+ RegisterNetEvent('esx:playerLoaded')
+ AddEventHandler('esx:playerLoaded', function(playerId, xPlayer)
+ if alreadyRegistered[xPlayer.identifier] == true then
+ local currentIdentity = playerIdentity[xPlayer.identifier]
+
+ xPlayer.setName(('%s %s'):format(currentIdentity.firstName, currentIdentity.lastName))
+ xPlayer.set('firstName', currentIdentity.firstName)
+ xPlayer.set('lastName', currentIdentity.lastName)
+ xPlayer.set('dateofbirth', currentIdentity.dateOfBirth)
+ xPlayer.set('sex', currentIdentity.sex)
+ xPlayer.set('height', currentIdentity.height)
+
+ if currentIdentity.saveToDatabase then
+ saveIdentityToDatabase(xPlayer.identifier, currentIdentity)
+ end
+
+ Citizen.Wait(1000)
+ TriggerClientEvent('esx_identity:alreadyRegistered', xPlayer.source)
+
+ playerIdentity[xPlayer.identifier] = nil
+ else
+ TriggerClientEvent('esx_identity:showRegisterIdentity', xPlayer.source)
+ end
+ end)
+
+ ESX.RegisterServerCallback('esx_identity:registerIdentity', function(source, cb, data)
+ local xPlayer = ESX.GetPlayerFromId(source)
+
+ if xPlayer then
+ if not alreadyRegistered[xPlayer.identifier] then
+ if checkNameFormat(data.firstname) and checkNameFormat(data.lastname) and checkSexFormat(data.sex) and checkDOBFormat(data.dateofbirth) and checkHeightFormat(data.height) then
+ playerIdentity[xPlayer.identifier] = {
+ firstName = formatName(data.firstname),
+ lastName = formatName(data.lastname),
+ dateOfBirth = data.dateofbirth,
+ sex = data.sex,
+ height = data.height
+ }
+
+ local currentIdentity = playerIdentity[xPlayer.identifier]
+
+ xPlayer.setName(('%s %s'):format(currentIdentity.firstName, currentIdentity.lastName))
+ xPlayer.set('firstName', currentIdentity.firstName)
+ xPlayer.set('lastName', currentIdentity.lastName)
+ xPlayer.set('dateofbirth', currentIdentity.dateOfBirth)
+ xPlayer.set('sex', currentIdentity.sex)
+ xPlayer.set('height', currentIdentity.height)
+
+ saveIdentityToDatabase(xPlayer.identifier, currentIdentity)
+ alreadyRegistered[xPlayer.identifier] = true
+
+ playerIdentity[xPlayer.identifier] = nil
+ cb(true)
+ else
+ cb(false)
+ end
+ else
+ cb(false)
+ end
+ end
+ end)
+
+ function checkIdentity(xPlayer)
MySQL.Async.fetchAll('SELECT firstname, lastname, dateofbirth, sex, height FROM users WHERE identifier = @identifier', {
- ['@identifier'] = identifier
+ ['@identifier'] = xPlayer.identifier
}, function(result)
if result[1] then
- playerIdentity[identifier] = {
- firstName = result[1].firstname,
- lastName = result[1].lastname,
- dateOfBirth = result[1].dateofbirth,
- sex = result[1].sex,
- height = result[1].height
- }
+ if result[1].firstname then
+ playerIdentity[xPlayer.identifier] = {
+ firstName = result[1].firstname,
+ lastName = result[1].lastname,
+ dateOfBirth = result[1].dateofbirth,
+ sex = result[1].sex,
+ height = result[1].height
+ }
- deferrals.done()
+ alreadyRegistered[xPlayer.identifier] = true
+
+ setIdentity(xPlayer)
+ else
+ playerIdentity[xPlayer.identifier] = nil
+ alreadyRegistered[xPlayer.identifier] = false
+ TriggerClientEvent('esx_identity:showRegisterIdentity', xPlayer.source)
+ end
else
- deferrals.presentCard([==[{"type":"AdaptiveCard","body":[{"type":"Container","items":[{"type":"TextBlock","text":"Identity Registration","horizontalAlignment":"Center","size":"Large","weight":"Bolder"},{"type":"ColumnSet","columns":[{"type":"Column","items":[{"type":"Input.Text","placeholder":"First Name","id":"firstname","maxLength":15}],"width":"stretch"},{"type":"Column","width":"stretch","items":[{"type":"Input.Text","placeholder":"Last Name","id":"lastname","maxLength":15}]}]},{"type":"ColumnSet","columns":[{"type":"Column","width":"stretch","items":[{"type":"Input.Text","placeholder":"Date of Birth (YYYY-MM-DD)","id":"dateofbirth","maxLength":10}],"style":"default"},{"type":"Column","width":"stretch","items":[{"type":"Input.Text","placeholder":"Height (24-96 inches)","id":"height","maxLength":2}]}]},{"type":"Input.ChoiceSet","placeholder":"Sex","choices":[{"title":"Male","value":"m"},{"title":"Female","value":"f"}],"style":"expanded","id":"sex"}],"style":"default","backgroundImage":"https://nischat.se/wp-content/uploads/Light-grey-background-1024x683.jpg"}],"actions":[{"type":"Action.Submit","title":"Submit"}],"$schema":"http://adaptivecards.io/schemas/adaptive-card.json","version":"1.0"}]==], function(data, rawData)
- if
- data.firstname == '' or
- data.lastname == '' or
- data.dateofbirth == '' or
- data.sex == '' or
- data.height == ''
- then
- deferrals.done(_U('data_incorrect'))
- else
- if
- checkNameFormat(data.firstname) and
- checkNameFormat(data.lastname) and
- checkDOBFormat(data.dateofbirth) and
- checkSexFormat(data.sex) and
- checkHeightFormat(data.height)
- then
- playerIdentity[identifier] = {
- firstName = formatName(data.firstname),
- lastName = formatName(data.lastname),
- dateOfBirth = data.dateofbirth,
- sex = data.sex,
- height = tonumber(data.height),
- saveToDatabase = true
- }
-
- deferrals.done()
- else
- deferrals.done(_U('invalid_format'))
- end
- end
- end)
+ TriggerClientEvent('esx_identity:showRegisterIdentity', xPlayer.source)
end
end)
- else
- deferrals.done(_U('no_identifier'))
end
-end)
-RegisterNetEvent('esx:playerLoaded')
-AddEventHandler('esx:playerLoaded', function(playerId, xPlayer)
- if playerIdentity[xPlayer.identifier] then
- local currentIdentity = playerIdentity[xPlayer.identifier]
+ function setIdentity(xPlayer)
+ if alreadyRegistered[xPlayer.identifier] then
+ local currentIdentity = playerIdentity[xPlayer.identifier]
- xPlayer.setName(('%s %s'):format(currentIdentity.firstName, currentIdentity.lastName))
- xPlayer.set('firstName', currentIdentity.firstName)
- xPlayer.set('lastName', currentIdentity.lastName)
- xPlayer.set('dateofbirth', currentIdentity.dateOfBirth)
- xPlayer.set('sex', currentIdentity.sex)
- xPlayer.set('height', currentIdentity.height)
+ xPlayer.setName(('%s %s'):format(currentIdentity.firstName, currentIdentity.lastName))
+ xPlayer.set('firstName', currentIdentity.firstName)
+ xPlayer.set('lastName', currentIdentity.lastName)
+ xPlayer.set('dateofbirth', currentIdentity.dateOfBirth)
+ xPlayer.set('sex', currentIdentity.sex)
+ xPlayer.set('height', currentIdentity.height)
- if currentIdentity.saveToDatabase then
- SaveIdentityToDatabase(xPlayer.identifier, currentIdentity)
+ if currentIdentity.saveToDatabase then
+ saveIdentityToDatabase(xPlayer.identifier, currentIdentity)
+ end
+
+ playerIdentity[xPlayer.identifier] = nil
end
-
- playerIdentity[xPlayer.identifier] = nil
- else
- xPlayer.kick(_('missing_identity'))
end
-end)
+end
+
+if Config.EnableCommands then
+ ESX.RegisterCommand('char', 'user', function(xPlayer, args, showError)
+ if xPlayer and xPlayer.getName() then
+ xPlayer.showNotification(_U('active_character', xPlayer.getName()))
+ else
+ xPlayer.showNotification(_U('error_active_character'))
+ end
+ end, false, {help = _U('show_active_character')})
+
+ ESX.RegisterCommand('chardel', 'user', function(xPlayer, args, showError)
+ if xPlayer and xPlayer.getName() then
+ if Config.UseDeferrals then
+ deleteIdentity(xPlayer)
+ xPlayer.showNotification(_U('deleted_character'))
+ playerIdentity[xPlayer.identifier] = nil
+ alreadyRegistered[xPlayer.identifier] = false
+ Citizen.Wait(2500)
+ xPlayer.kick(_('deleted_identity'))
+ else
+ deleteIdentity(xPlayer)
+ xPlayer.showNotification(_U('deleted_character'))
+ playerIdentity[xPlayer.identifier] = nil
+ alreadyRegistered[xPlayer.identifier] = false
+ TriggerClientEvent('esx_identity:showRegisterIdentity', xPlayer.source)
+ end
+ else
+ xPlayer.showNotification(_U('error_delete_character'))
+ end
+ end, false, {help = _U('delete_character')})
+end
+
+if Config.EnableDebugging then
+ ESX.RegisterCommand('xPlayerGetFirstName', 'user', function(xPlayer, args, showError)
+ if xPlayer and xPlayer.get('firstName') then
+ xPlayer.showNotification(_U('return_debug_xPlayer_get_first_name', xPlayer.get('firstName')))
+ else
+ xPlayer.showNotification(_U('error_debug_xPlayer_get_first_name'))
+ end
+ end, false, {help = _U('debug_xPlayer_get_first_name')})
+
+ ESX.RegisterCommand('xPlayerGetLastName', 'user', function(xPlayer, args, showError)
+ if xPlayer and xPlayer.get('lastName') then
+ xPlayer.showNotification(_U('return_debug_xPlayer_get_last_name', xPlayer.get('lastName')))
+ else
+ xPlayer.showNotification(_U('error_debug_xPlayer_get_last_name'))
+ end
+ end, false, {help = _U('debug_xPlayer_get_last_name')})
+
+ ESX.RegisterCommand('xPlayerGetFullName', 'user', function(xPlayer, args, showError)
+ if xPlayer and xPlayer.getName() then
+ xPlayer.showNotification(_U('return_debug_xPlayer_get_full_name', xPlayer.getName()))
+ else
+ xPlayer.showNotification(_U('error_debug_xPlayer_get_full_name'))
+ end
+ end, false, {help = _U('debug_xPlayer_get_full_name')})
+
+ ESX.RegisterCommand('xPlayerGetSex', 'user', function(xPlayer, args, showError)
+ if xPlayer and xPlayer.get('sex') then
+ xPlayer.showNotification(_U('return_debug_xPlayer_get_sex', xPlayer.get('sex')))
+ else
+ xPlayer.showNotification(_U('error_debug_xPlayer_get_sex'))
+ end
+ end, false, {help = _U('debug_xPlayer_get_sex')})
+
+ ESX.RegisterCommand('xPlayerGetDOB', 'user', function(xPlayer, args, showError)
+ if xPlayer and xPlayer.get('dateofbirth') then
+ xPlayer.showNotification(_U('return_debug_xPlayer_get_dob', xPlayer.get('dateofbirth')))
+ else
+ xPlayer.showNotification(_U('error_debug_xPlayer_get_dob'))
+ end
+ end, false, {help = _U('debug_xPlayer_get_dob')})
+
+ ESX.RegisterCommand('xPlayerGetHeight', 'user', function(xPlayer, args, showError)
+ if xPlayer and xPlayer.get('height') then
+ xPlayer.showNotification(_U('return_debug_xPlayer_get_height', xPlayer.get('height')))
+ else
+ xPlayer.showNotification(_U('error_debug_xPlayer_get_height'))
+ end
+ end, false, {help = _U('debug_xPlayer_get_height')})
+end
+
+function deleteIdentity(xPlayer)
+ if alreadyRegistered[xPlayer.identifier] then
+ xPlayer.setName(('%s %s'):format(nil, nil))
+ xPlayer.set('firstName', nil)
+ xPlayer.set('lastName', nil)
+ xPlayer.set('dateofbirth', nil)
+ xPlayer.set('sex', nil)
+ xPlayer.set('height', nil)
+
+ deleteIdentityFromDatabase(xPlayer)
+ end
+end
+
+function saveIdentityToDatabase(identifier, identity)
+ MySQL.Sync.execute('UPDATE users SET firstname = @firstname, lastname = @lastname, dateofbirth = @dateofbirth, sex = @sex, height = @height WHERE identifier = @identifier', {
+ ['@identifier'] = identifier,
+ ['@firstname'] = identity.firstName,
+ ['@lastname'] = identity.lastName,
+ ['@dateofbirth'] = identity.dateOfBirth,
+ ['@sex'] = identity.sex,
+ ['@height'] = identity.height
+ })
+end
+
+function deleteIdentityFromDatabase(xPlayer)
+ MySQL.Sync.execute('UPDATE users SET firstname = @firstname, lastname = @lastname, dateofbirth = @dateofbirth, sex = @sex, height = @height , skin = @skin WHERE identifier = @identifier', {
+ ['@identifier'] = xPlayer.identifier,
+ ['@firstname'] = NULL,
+ ['@lastname'] = NULL,
+ ['@dateofbirth'] = NULL,
+ ['@sex'] = NULL,
+ ['@height'] = NULL,
+ ['@skin'] = NULL
+ })
+
+ MySQL.Sync.execute('UPDATE addon_account_data SET money = 0 WHERE account_name = @account_name AND owner = @owner', {
+ ['@account_name'] = 'bank_savings',
+ ['@owner'] = xPlayer.identifier
+ })
+
+ MySQL.Sync.execute('UPDATE addon_account_data SET money = 0 WHERE account_name = @account_name AND owner = @owner', {
+ ['@account_name'] = 'caution',
+ ['@owner'] = xPlayer.identifier
+ })
+
+ MySQL.Sync.execute('UPDATE datastore_data SET data = @data WHERE name = @name AND owner = @owner', {
+ ['@data'] = '\'{}\'',
+ ['@name'] = 'user_ears',
+ ['@owner'] = xPlayer.identifier
+ })
+
+ MySQL.Sync.execute('UPDATE datastore_data SET data = @data WHERE name = @name AND owner = @owner', {
+ ['@data'] = '\'{}\'',
+ ['@name'] = 'user_glasses',
+ ['@owner'] = xPlayer.identifier
+ })
+
+ MySQL.Sync.execute('UPDATE datastore_data SET data = @data WHERE name = @name AND owner = @owner', {
+ ['@data'] = '\'{}\'',
+ ['@name'] = 'user_helmet',
+ ['@owner'] = xPlayer.identifier
+ })
+
+ MySQL.Sync.execute('UPDATE datastore_data SET data = @data WHERE name = @name AND owner = @owner', {
+ ['@data'] = '\'{}\'',
+ ['@name'] = 'user_mask',
+ ['@owner'] = xPlayer.identifier
+ })
+end
function checkNameFormat(name)
if not checkAlphanumeric(name) then
@@ -157,11 +517,11 @@ function checkForNumbers(str)
end
function checkDate(str)
- if string.match(str, '(%d%d%d%d)-(%d%d)-(%d%d)') ~= nil then
- local y, m, d = string.match(str, '(%d+)-(%d+)-(%d+)')
- y = tonumber(y)
+ if string.match(str, '(%d%d)/(%d%d)/(%d%d%d%d)') ~= nil then
+ local m, d, y = string.match(str, '(%d+)/(%d+)/(%d+)')
m = tonumber(m)
d = tonumber(d)
+ y = tonumber(y)
if ((d <= 0) or (d > 31)) or ((m <= 0) or (m > 12)) or ((y <= Config.LowestYear) or (y > Config.HighestYear)) then
return false
elseif m == 4 or m == 6 or m == 9 or m == 11 then
@@ -195,14 +555,3 @@ function checkDate(str)
return false
end
end
-
-function SaveIdentityToDatabase(identifier, identity)
- MySQL.Sync.execute('UPDATE users SET firstname = @firstname, lastname = @lastname, dateofbirth = @dateofbirth, sex = @sex, height = @height WHERE identifier = @identifier', {
- ['@identifier'] = identifier,
- ['@firstname'] = identity.firstName,
- ['@lastname'] = identity.lastName,
- ['@dateofbirth'] = identity.dateOfBirth,
- ['@sex'] = identity.sex,
- ['@height'] = identity.height
- })
-end