diff --git a/README.md b/README.md index c2edec3f..cec80b0c 100644 --- a/README.md +++ b/README.md @@ -34,14 +34,6 @@ 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 -``` -/register -/charlist -/charselect -/chardel -``` - # Legal ### License esx_identity - rp characters diff --git a/client/main.lua b/client/main.lua deleted file mode 100644 index 45d474e8..00000000 --- a/client/main.lua +++ /dev/null @@ -1,167 +0,0 @@ -local guiEnabled, hasIdentity, isDead = false, false, false -local myIdentity, myIdentifiers = {}, {} - -ESX = nil - -Citizen.CreateThread(function() - while ESX == nil do - TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) - Citizen.Wait(0) - 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) - end -end) - -RegisterNetEvent('esx_identity:identityCheck') -AddEventHandler('esx_identity:identityCheck', function(identityCheck) - hasIdentity = identityCheck -end) - -RegisterNetEvent('esx_identity:saveID') -AddEventHandler('esx_identity:saveID', function(data) - myIdentifiers = data -end) - -RegisterNUICallback('escape', function(data, cb) - if hasIdentity then - EnableGui(false) - else - ESX.ShowNotification(_U('create_a_character')) - 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 - else - reason = "Unacceptable player height!" - break - 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 diff --git a/config.lua b/config.lua index aaec53d7..4266ca75 100644 --- a/config.lua +++ b/config.lua @@ -1,3 +1,8 @@ -Config = {} - -Config.Locale = 'en' \ No newline at end of file +Config = {} +Config.Locale = 'en' +Config.StartingAccountMoney = {bank = 50000} +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 diff --git a/esx_identity.sql b/esx_identity.sql index e6a39cc3..b8eeb2ee 100644 --- a/esx_identity.sql +++ b/esx_identity.sql @@ -1,9 +1,9 @@ USE `essentialmode`; 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(15) NULL DEFAULT NULL, + ADD COLUMN `lastname` VARCHAR(15) 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 ; \ No newline at end of file diff --git a/fxmanifest.lua b/fxmanifest.lua index 256ab072..4917c8cb 100644 --- a/fxmanifest.lua +++ b/fxmanifest.lua @@ -4,7 +4,7 @@ game 'gta5' description 'ESX Identity' -version '1.2.0' +version '1.3.0' server_scripts { '@es_extended/locale.lua', @@ -15,20 +15,4 @@ 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/script.js', - 'html/style.css' -} - dependency 'es_extended' diff --git a/html/cs_index.html b/html/cs_index.html deleted file mode 100644 index 1dd357a9..00000000 --- a/html/cs_index.html +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - -
-
-

Register

-
-
-
-
- Male - Female
- -
-
- - - diff --git a/html/fi_index.html b/html/fi_index.html deleted file mode 100644 index 87ca250a..00000000 --- a/html/fi_index.html +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - -
-
-

Rekistöröinti

-
-
-
-
- Mies - Nainen
- -
-
- - - diff --git a/html/index.html b/html/index.html deleted file mode 100644 index 6fc5dfc7..00000000 --- a/html/index.html +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - -
-
-

Register

-
-
-
-
- Male - Female
- -
-
- - - diff --git a/html/ko_index.html b/html/ko_index.html deleted file mode 100644 index c04fe9b7..00000000 --- a/html/ko_index.html +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - -
-
-

등록

-
-
-
-
- 남자 - 여자
- -
-
- - - \ No newline at end of file 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/html/sv_index.html b/html/sv_index.html deleted file mode 100644 index 7706c17b..00000000 --- a/html/sv_index.html +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - -
-
-

Registrera

-
-
-
-
- Man - Kvinna
- -
-
- - - diff --git a/locales/cs.lua b/locales/cs.lua index 80c6a267..f32a8888 100644 --- a/locales/cs.lua +++ b/locales/cs.lua @@ -1,11 +1,5 @@ Locales['cs'] = { - ['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.' + ['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_identifiers'] = '[Chyba] Nelze najít identifikátory.' } diff --git a/locales/en.lua b/locales/en.lua index 53fac161..8ab2f5b2 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -1,11 +1,5 @@ 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.' + ['data_incorrect'] = 'Data entered incorrectly. Please try again.', + ['invalid_format'] = 'Data formatted incorrectly. Please try again.', + ['no_identifiers'] = '[Error] Could not find identifiers.' } diff --git a/server/main.lua b/server/main.lua index f96f4495..01215420 100644 --- a/server/main.lua +++ b/server/main.lua @@ -1,189 +1,226 @@ ESX = nil +local registered = false +local data = { + firstName, + lastName, + dateOfBirth, + sex, + height +} TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) -function getIdentity(source, callback) - local xPlayer = ESX.GetPlayerFromId(source) +AddEventHandler("playerConnecting", function(name, setKickReason, deferrals) + local player = source + local identifiers = GetPlayerIdentifiers(player) + local identifier + deferrals.defer() - 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 - } + Citizen.Wait(0) - callback(data) - else - local data = { - identifier = '', - firstname = '', - lastname = '', - dateofbirth = '', - sex = '', - height = '' - } + for k, v in pairs(identifiers) do + if string.match(v, 'license:') then + identifier = string.sub(v, 9) + break + end + end - callback(data) - end - end) -end + Citizen.Wait(0) + + 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 ~= nil then + data = { + firstName = result[1].firstname, + lastName = result[1].lastname, + dateOfBirth = result[1.].dateofbirth, + sex = result[1].sex, + height = result[1].height + } + end + end + 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) - end - end) -end - -function updateIdentity(playerId, data, callback) - local xPlayer = ESX.GetPlayerFromId(playerId) - - 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) - end - end) -end - -function deleteIdentity(source) - local xPlayer = ESX.GetPlayerFromId(source) - - 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'] = '', - }) -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) - else - xPlayer.showNotification(_U('failed_identity')) - end - end) + Citizen.Wait(500) + if data.firstName ~= nil then + registered = true + deferrals.done() + else + deferrals.presentCard([==[{"type": "AdaptiveCard", "body": [{ "type": "ColumnSet", "columns": [{ "type": "Column", "items": [ + { "type": "Input.Text", "placeholder": "First Name (Max 15 Characters)", "id": "firstname" }], "width": "stretch" }]}, + { "type": "Input.Text", "placeholder": "Last Name (Max 15 Characters)", "id": "lastname" }, + { "type": "Input.Text", "placeholder": "Height (24-96 Inches)", "id": "height" }, + { "type": "Input.Date", "id": "dateofbirth" }, + { "type": "Input.ChoiceSet", "placeholder": "Sex", "choices": [{ "title": "Male", "value": "m" }, { "title": "Female", "value": "f" }], "style": "expanded", "value": "m", "id": "sex" }], + "actions": [{ "type": "Action.Submit", "title": "Submit" }], + "$schema": "http://adaptivecards.io/schemas/adaptive-card.json", + "version": "1.0" + }]==], function(submittedData, rawData) + if submittedData.firstname == "" or submittedData.lastname == "" or submittedData.dateofbirth == "" or submittedData.sex == "" or submittedData.height == "" then + deferrals.done(_U('data_incorrect')) + else + if checkNameFormat(submittedData.firstname) and checkNameFormat(submittedData.lastname) and checkDOBFormat(submittedData.dateofbirth) and checkSexFormat(submittedData.sex) and checkHeightFormat(submittedData.height) then + local formattedFirstName = formatName(submittedData.firstname) + local formattedLastName = formatName(submittedData.lastname) + local formattedHeight = tonumber(submittedData.height) + data = { + firstName = formattedFirstName, + lastName = formattedLastName, + dateOfBirth = submittedData.dateofbirth, + sex = submittedData.sex, + height = formattedHeight + } + Citizen.Wait(500) + deferrals.done() + else + deferrals.done(_U('invalid_format')) + end + end + end) + end + else + deferrals.done(_U('no_identifiers')) + end end) -AddEventHandler('esx:playerLoaded', function(playerId, xPlayer) - local myID = { - steamid = xPlayer.identifier, - playerid = playerId - } +RegisterServerEvent('esx:onPlayerSpawn') +AddEventHandler('esx:onPlayerSpawn', function() + local playerId = source + local xPlayer = ESX.GetPlayerFromId(playerId) - TriggerClientEvent('esx_identity:saveID', playerId, myID) + Citizen.Wait(4000) + + 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) + end - 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) + if not registered then + registered = true + SetIdentity(xPlayer.identifier, data.firstName, data.lastName, data.dateOfBirth, data.sex, data.height) + 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) - end -end) +function checkNameFormat(name) + if checkAlphanumeric(name) == nil then + if checkForNumbers(name) == nil then + local stringLength = string.len(name) + if stringLength > 0 and stringLength < Config.MaxNameLength then + return true + else + return false + end + else + return false + end + else + return false + 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) == true 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) - end - end - 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 -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')}) +function formatName(name) + local loweredName = convertToLowerCase(name) + local formattedName = convertFirstLetterToUpper(loweredName) + return formattedName +end -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')}) +function convertToLowerCase(str) + return string.lower(str) +end -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 +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 y, m, d = string.match(str, '(%d+)-(%d+)-(%d+)') + y = tonumber(y) + m = tonumber(m) + d = tonumber(d) + 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 + +function SetIdentity(identifier, firstName, lastName, dateOfBirth, sex, height) + MySQL.Async.execute('UPDATE `users` SET `firstname` = @firstname, `lastname` = @lastname, `dateofbirth` = @dateofbirth, `sex` = @sex, `height` = @height WHERE identifier = @identifier', { + ['@identifier'] = identifier, + ['@firstname'] = firstName, + ['@lastname'] = lastName, + ['@dateofbirth'] = dateOfBirth, + ['@sex'] = sex, + ['@height'] = height + }) +end \ No newline at end of file