diff --git a/README.md b/README.md
index c2edec3f..2d466b10 100644
--- a/README.md
+++ b/README.md
@@ -36,9 +36,7 @@ start esx_identity
### Commands
```
-/register
-/charlist
-/charselect
+/char
/chardel
```
diff --git a/client/main.lua b/client/main.lua
index 45d474e8..238a485e 100644
--- a/client/main.lua
+++ b/client/main.lua
@@ -1,7 +1,5 @@
-local guiEnabled, hasIdentity, isDead = false, false, false
-local myIdentity, myIdentifiers = {}, {}
-
ESX = nil
+local loadingScreenFinished = false
Citizen.CreateThread(function()
while ESX == nil do
@@ -10,158 +8,88 @@ Citizen.CreateThread(function()
end
end)
-AddEventHandler('esx:onPlayerDeath', function(data)
- isDead = true
-end)
-
-AddEventHandler('playerSpawned', 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()
- if not isDead then
- EnableGui(true)
+RegisterNetEvent('esx_identity:alreadyRegistered')
+AddEventHandler('esx_identity:alreadyRegistered', function()
+ while not loadingScreenFinished do
+ Citizen.Wait(100)
end
+
+ TriggerEvent('esx_skin:playerRegistered')
end)
-RegisterNetEvent('esx_identity:identityCheck')
-AddEventHandler('esx_identity:identityCheck', function(identityCheck)
- hasIdentity = identityCheck
+AddEventHandler('esx:loadingScreenOff', function()
+ loadingScreenFinished = true
end)
-RegisterNetEvent('esx_identity:saveID')
-AddEventHandler('esx_identity:saveID', function(data)
- myIdentifiers = data
-end)
+if not Config.UseDeferrals then
+ local guiEnabled, isDead = false, false
-RegisterNUICallback('escape', function(data, cb)
- if hasIdentity then
- EnableGui(false)
- else
- ESX.ShowNotification(_U('create_a_character'))
+ 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
-end)
-RegisterNUICallback('register', function(data, cb)
- local reason = ""
- myIdentity = data
- for theData, value in pairs(myIdentity) do
- if theData == "firstname" or theData == "lastname" then
- reason = verifyName(value)
-
- if reason ~= "" then
- break
- end
- elseif theData == "dateofbirth" then
- if value == "invalid" then
- reason = "Invalid date of birth!"
- break
- end
- elseif theData == "height" then
- local height = tonumber(value)
- if height then
- if height > 200 or height < 140 then
- reason = "Unacceptable player height!"
- break
- 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
- reason = "Unacceptable player height!"
- break
+ 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
-
- if reason == "" then
- TriggerServerEvent('esx_identity:setIdentity', data, myIdentifiers)
- EnableGui(false)
- Citizen.Wait(500)
- TriggerEvent('esx_skin:openSaveableMenu', myIdentifiers.id)
- else
- ESX.ShowNotification(reason)
- end
-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)
-
-function verifyName(name)
- -- Don't allow short user names
- local nameLength = string.len(name)
- if nameLength > 25 or nameLength < 2 then
- return 'Your player name is either too short or too long.'
- end
-
- -- Don't allow special characters (doesn't always work)
- local count = 0
- for i in name:gmatch('[abcdefghijklmnopqrstuvwxyzåäöABCDEFGHIJKLMNOPQRSTUVWXYZÅÄÖ0123456789 -]') do
- count = count + 1
- end
- if count ~= nameLength then
- return 'Your player name contains special characters that are not allowed on this server.'
- end
-
- -- Does the player carry a first and last name?
- --
- -- Example:
- -- Allowed: 'Bob Joe'
- -- Not allowed: 'Bob'
- -- Not allowed: 'Bob joe'
- local spacesInName = 0
- local spacesWithUpper = 0
- for word in string.gmatch(name, '%S+') do
-
- if string.match(word, '%u') then
- spacesWithUpper = spacesWithUpper + 1
- end
-
- spacesInName = spacesInName + 1
- end
-
- if spacesInName > 2 then
- return 'Your name contains more than two spaces'
- end
-
- if spacesWithUpper ~= spacesInName then
- return 'your name must start with a capital letter.'
- end
-
- return ''
+ end)
end
diff --git a/config.lua b/config.lua
index aaec53d7..3d37568a 100644
--- a/config.lua
+++ b/config.lua
@@ -1,3 +1,12 @@
-Config = {}
+Config = {}
+Config.Locale = 'en'
+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.Locale = 'en'
\ No newline at end of file
+Config.EnableDebugging = false
\ No newline at end of file
diff --git a/esx_identity.sql b/esx_identity.sql
index e6a39cc3..c9e411d5 100644
--- a/esx_identity.sql
+++ b/esx_identity.sql
@@ -1,9 +1,9 @@
-USE `essentialmode`;
+USE `es_extended`;
ALTER TABLE `users`
- ADD COLUMN `firstname` VARCHAR(50) NULL DEFAULT '',
- ADD COLUMN `lastname` VARCHAR(50) NULL DEFAULT '',
- ADD COLUMN `dateofbirth` VARCHAR(25) NULL DEFAULT '',
- ADD COLUMN `sex` VARCHAR(10) NULL DEFAULT '',
- ADD COLUMN `height` VARCHAR(5) NULL DEFAULT ''
+ 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` INT(2) NULL DEFAULT NULL
;
\ No newline at end of file
diff --git a/fxmanifest.lua b/fxmanifest.lua
index 256ab072..09853b6a 100644
--- a/fxmanifest.lua
+++ b/fxmanifest.lua
@@ -4,7 +4,7 @@ game 'gta5'
description 'ESX Identity'
-version '1.2.0'
+version '1.4.0'
server_scripts {
'@es_extended/locale.lua',
@@ -27,8 +27,9 @@ ui_page 'html/index.html'
files {
'html/index.html',
- 'html/script.js',
- 'html/style.css'
+ '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
index 6fc5dfc7..182d344a 100644
--- a/html/index.html
+++ b/html/index.html
@@ -1,22 +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/cs_index.html b/html/localization/cs_index(outofdate).html
similarity index 100%
rename from html/cs_index.html
rename to html/localization/cs_index(outofdate).html
diff --git a/html/fi_index.html b/html/localization/fi_index(outofdate).html
similarity index 100%
rename from html/fi_index.html
rename to html/localization/fi_index(outofdate).html
diff --git a/html/ko_index.html b/html/localization/ko_index(outofdate).html
similarity index 100%
rename from html/ko_index.html
rename to html/localization/ko_index(outofdate).html
diff --git a/html/sv_index.html b/html/localization/sv_index(outofdate).html
similarity index 100%
rename from html/sv_index.html
rename to html/localization/sv_index(outofdate).html
diff --git a/html/script.js b/html/script.js
deleted file mode 100644
index b4d4d5b4..00000000
--- a/html/script.js
+++ /dev/null
@@ -1,33 +0,0 @@
-$(function() {
- window.addEventListener('message', function(event) {
- if (event.data.type == "enableui") {
- document.body.style.display = event.data.enable ? "block" : "none";
- }
- });
-
- document.onkeyup = function (data) {
- if (data.which == 27) { // Escape key
- $.post('http://esx_identity/escape', JSON.stringify({}));
- }
- };
-
- $("#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";
- }
-
- $.post('http://esx_identity/register', JSON.stringify({
- firstname: $("#firstname").val(),
- lastname: $("#lastname").val(),
- dateofbirth: date,
- sex: $("input[type='radio'][name='sex']:checked").val(),
- height: $("#height").val()
- }));
- });
-});
diff --git a/html/style.css b/html/style.css
deleted file mode 100644
index 79a6b347..00000000
--- a/html/style.css
+++ /dev/null
@@ -1,46 +0,0 @@
-body {
- font-family: sans-serif;
- overflow: hidden;
- display: none;
-}
-
-.dialog {
- width: 300px;
- position: absolute;
- margin-left: auto;
- margin-right: auto;
- left: 0;
- right: 0;
- padding: 10px;
- box-shadow: 0px 0px 50px 0px #000;
- background-color: #f1f1f1;
- overflow: hidden;
- opacity: 0.9;
-}
-
-input[type=text] {
- width: 100%;
- padding: 7px;
- text-align: center;
-}
-
-button {
- display: block;
- margin-top: 5px;
- padding: 10px;
- background-color: #506be6;
- border: 0;
- color: #fff;
- width: 100%;
-}
-
-h1 {
- display: block;
- margin-top: 5px;
- margin-right: 5px;
- padding: 10px;
- background-color: #506be6;
- color: #fff;
- width: 93%;
- text-align: center;
-}
\ No newline at end of file
diff --git a/locales/en.lua b/locales/en.lua
index 53fac161..165ee7ae 100644
--- a/locales/en.lua
+++ b/locales/en.lua
@@ -1,11 +1,33 @@
Locales['en'] = {
- ['show_registration'] = 'show Registration Menu',
- ['show_active_character'] = 'show Active Character',
- ['delete_character'] = 'delete Your Character And Create A New One',
- ['deleted_character'] = 'your character has been deleted.',
- ['not_registered'] = 'you do not have a character reistered.',
- ['active_character'] = '~b~active Character:~s~ %s %s',
- ['already_registered'] = 'you already have a character registered.',
- ['failed_identity'] = 'failed to set your character, try again later or contact the server admin!',
- ['create_a_character'] = 'you have to create a character in order to play.'
+ ['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 f96f4495..ede6b5bd 100644
--- a/server/main.lua
+++ b/server/main.lua
@@ -1,189 +1,557 @@
ESX = nil
-
+local playerIdentity = {}
+local alreadyRegistered = {}
TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end)
-function getIdentity(source, callback)
- local xPlayer = ESX.GetPlayerFromId(source)
-
- MySQL.Async.fetchAll('SELECT identifier, firstname, lastname, dateofbirth, sex, height FROM `users` WHERE `identifier` = @identifier', {
- ['@identifier'] = xPlayer.identifier
- }, function(result)
- if result[1].firstname ~= nil then
- local data = {
- identifier = result[1].identifier,
- firstname = result[1].firstname,
- lastname = result[1].lastname,
- dateofbirth = result[1].dateofbirth,
- sex = result[1].sex,
- height = result[1].height
- }
-
- callback(data)
+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
- local data = {
- identifier = '',
- firstname = '',
- lastname = '',
- dateofbirth = '',
- sex = '',
- height = ''
- }
-
- callback(data)
+ 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
+ }
+
+ 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)
-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
-function setIdentity(identifier, data, callback)
- MySQL.Async.execute('UPDATE `users` SET `firstname` = @firstname, `lastname` = @lastname, `dateofbirth` = @dateofbirth, `sex` = @sex, `height` = @height WHERE identifier = @identifier', {
- ['@identifier'] = identifier,
- ['@firstname'] = data.firstname,
- ['@lastname'] = data.lastname,
- ['@dateofbirth'] = data.dateofbirth,
- ['@sex'] = data.sex,
- ['@height'] = data.height
- }, function(rowsChanged)
- if callback then
- callback(true)
+ Citizen.Wait(1000)
+ alreadyRegistered[xPlayer.identifier] = true
+ TriggerClientEvent('esx_identity:alreadyRegistered', xPlayer.source)
+
+ playerIdentity[xPlayer.identifier] = nil
+ else
+ xPlayer.kick(_('missing_identity'))
end
end)
-end
+elseif not Config.UseDeferrals then
+ AddEventHandler('playerConnecting', function(playerName, setKickReason, deferrals)
+ deferrals.defer()
+ local playerId, identifier = source
+ Citizen.Wait(100)
-function updateIdentity(playerId, data, callback)
- local xPlayer = ESX.GetPlayerFromId(playerId)
+ 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
- MySQL.Async.execute('UPDATE `users` SET `firstname` = @firstname, `lastname` = @lastname, `dateofbirth` = @dateofbirth, `sex` = @sex, `height` = @height WHERE identifier = @identifier', {
- ['@identifier'] = xPlayer.identifier,
- ['@firstname'] = data.firstname,
- ['@lastname'] = data.lastname,
- ['@dateofbirth'] = data.dateofbirth,
- ['@sex'] = data.sex,
- ['@height'] = data.height
- }, function(rowsChanged)
- if callback then
- TriggerEvent('esx_identity:characterUpdated', playerId, data)
- callback(true)
+ 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'] = xPlayer.identifier
+ }, function(result)
+ if result[1] then
+ 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
+ }
+
+ alreadyRegistered[xPlayer.identifier] = true
+
+ setIdentity(xPlayer)
+ else
+ playerIdentity[xPlayer.identifier] = nil
+ alreadyRegistered[xPlayer.identifier] = false
+ TriggerClientEvent('esx_identity:showRegisterIdentity', xPlayer.source)
+ end
+ else
+ TriggerClientEvent('esx_identity:showRegisterIdentity', xPlayer.source)
+ end
+ end)
+ end
+
+ 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)
+
+ if currentIdentity.saveToDatabase then
+ saveIdentityToDatabase(xPlayer.identifier, currentIdentity)
+ end
+
+ playerIdentity[xPlayer.identifier] = nil
+ end
+ end
end
-function deleteIdentity(source)
- local xPlayer = ESX.GetPlayerFromId(source)
+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')})
- MySQL.Async.execute('UPDATE `users` SET `firstname` = @firstname, `lastname` = @lastname, `dateofbirth` = @dateofbirth, `sex` = @sex, `height` = @height WHERE identifier = @identifier', {
- ['@identifier'] = xPlayer.identifier,
- ['@firstname'] = '',
- ['@lastname'] = '',
- ['@dateofbirth'] = '',
- ['@sex'] = '',
- ['@height'] = '',
+ 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
-RegisterServerEvent('esx_identity:setIdentity')
-AddEventHandler('esx_identity:setIdentity', function(data, myIdentifiers)
- local xPlayer = ESX.GetPlayerFromId(source)
- setIdentity(myIdentifiers.steamid, data, function(callback)
- if callback then
- TriggerClientEvent('esx_identity:identityCheck', myIdentifiers.playerid, true)
- TriggerEvent('esx_identity:characterUpdated', myIdentifiers.playerid, data)
+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
+ if not checkForNumbers(name) then
+ local stringLength = string.len(name)
+ if stringLength > 0 and stringLength < Config.MaxNameLength then
+ return true
+ else
+ return false
+ end
else
- xPlayer.showNotification(_U('failed_identity'))
+ return false
end
- end)
-end)
-
-AddEventHandler('esx:playerLoaded', function(playerId, xPlayer)
- local myID = {
- steamid = xPlayer.identifier,
- playerid = playerId
- }
-
- TriggerClientEvent('esx_identity:saveID', playerId, myID)
-
- getIdentity(playerId, function(data)
- if data.firstname == '' then
- TriggerClientEvent('esx_identity:identityCheck', playerId, false)
- TriggerClientEvent('esx_identity:showRegisterIdentity', playerId)
- else
- TriggerClientEvent('esx_identity:identityCheck', playerId, true)
- TriggerEvent('esx_identity:characterUpdated', playerId, data)
- end
- end)
-end)
-
-AddEventHandler('esx_identity:characterUpdated', function(playerId, data)
- local xPlayer = ESX.GetPlayerFromId(playerId)
-
- if xPlayer then
- xPlayer.setName(('%s %s'):format(data.firstname, data.lastname))
- xPlayer.set('firstName', data.firstname)
- xPlayer.set('lastName', data.lastname)
- xPlayer.set('dateofbirth', data.dateofbirth)
- xPlayer.set('sex', data.sex)
- xPlayer.set('height', data.height)
+ else
+ return false
end
-end)
+end
--- Set all the client side variables for connected users one new time
-AddEventHandler('onResourceStart', function(resource)
- if resource == GetCurrentResourceName() then
- Citizen.Wait(3000)
- local xPlayers = ESX.GetPlayers()
+function checkDOBFormat(dob)
+ local date = tostring(dob)
+ if checkDate(date) then
+ return true
+ else
+ return false
+ end
+end
- for i=1, #xPlayers, 1 do
- local xPlayer = ESX.GetPlayerFromId(xPlayers[i])
+function checkSexFormat(sex)
+ if sex == "m" or sex == "M" or sex == "f" or sex == "F" then
+ return true
+ else
+ return false
+ end
+end
- if xPlayer then
- local myID = {
- steamid = xPlayer.identifier,
- playerid = xPlayer.source
- }
-
- TriggerClientEvent('esx_identity:saveID', xPlayer.source, myID)
-
- getIdentity(xPlayer.source, function(data)
- if data.firstname == '' then
- TriggerClientEvent('esx_identity:identityCheck', xPlayer.source, false)
- TriggerClientEvent('esx_identity:showRegisterIdentity', xPlayer.source)
- else
- TriggerClientEvent('esx_identity:identityCheck', xPlayer.source, true)
- TriggerEvent('esx_identity:characterUpdated', xPlayer.source, data)
- end
- end)
+function checkHeightFormat(height)
+ local numHeight = tonumber(height)
+ if numHeight < Config.MinHeight and numHeight > Config.MaxHeight then
+ return false
+ else
+ return true
+ end
+end
+
+function formatName(name)
+ local loweredName = convertToLowerCase(name)
+ local formattedName = convertFirstLetterToUpper(loweredName)
+ return formattedName
+end
+
+function convertToLowerCase(str)
+ return string.lower(str)
+end
+
+function convertFirstLetterToUpper(str)
+ return str:gsub("^%l", string.upper)
+end
+
+function checkAlphanumeric(str)
+ return (string.match(str, "%W"))
+end
+
+function checkForNumbers(str)
+ return (string.match(str,"%d"))
+end
+
+function checkDate(str)
+ 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
+ if d > 30 then
+ return false
+ else
+ return true
+ end
+ elseif m == 2 then
+ if y%400 == 0 or (y%100 ~= 0 and y%4 == 0) then
+ if d > 29 then
+ return false
+ else
+ return true
+ end
+ else
+ if d > 28 then
+ return false
+ else
+ return true
+ end
+ end
+ else
+ if d > 31 then
+ return false
+ else
+ return true
end
end
+ else
+ return false
end
-end)
-
-ESX.RegisterCommand('register', 'user', function(xPlayer, args, showError)
- getIdentity(xPlayer.source, function(data)
- if data.firstname ~= '' then
- xPlayer.showNotification(_U('already_registered'))
- else
- TriggerClientEvent('esx_identity:showRegisterIdentity', xPlayer.source)
- end
- end)
-end, false, {help = _U('show_registration')})
-
-ESX.RegisterCommand('char', 'user', function(xPlayer, args, showError)
- getIdentity(xPlayer.source, function(data)
- if data.firstname == '' then
- xPlayer.showNotification(_U('not_registered'))
- else
- xPlayer.showNotification(_U('active_character', data.firstname, data.lastname))
- end
- end)
-end, false, {help = _U('show_active_character')})
-
-ESX.RegisterCommand('chardel', 'user', function(xPlayer, args, showError)
- getIdentity(xPlayer.source, function(data)
- if data.firstname == '' then
- xPlayer.showNotification(_U('not_registered'))
- else
- deleteIdentity(xPlayer.source)
- xPlayer.showNotification(_U('deleted_character'))
- TriggerClientEvent('esx_identity:showRegisterIdentity', xPlayer.source)
- end
- end)
-end, false, {help = _U('delete_character')})
\ No newline at end of file
+end