diff --git a/ND_ATMs/fxmanifest.lua b/ND_ATMs/fxmanifest.lua index a825141..f1af2dd 100644 --- a/ND_ATMs/fxmanifest.lua +++ b/ND_ATMs/fxmanifest.lua @@ -2,7 +2,7 @@ author "Andyyy#7666" description "ND Framework ATMs" -version "1.1" +version "2.0.0" fx_version "cerulean" game "gta5" @@ -12,11 +12,9 @@ ui_page "source/ui/index.html" files { "source/ui/index.html", - "source/ui/js/jquery-3.6.0.min.js", - "source/ui/js/listener.js", - "source/ui/img/mazebank.png", - "source/ui/style.css", + "source/ui/script.js", + "source/ui/style.css" } server_script "source/server.lua" -client_script "source/client.lua" +client_script "source/client.lua" \ No newline at end of file diff --git a/ND_ATMs/source/client.lua b/ND_ATMs/source/client.lua index 530f44d..a415072 100644 --- a/ND_ATMs/source/client.lua +++ b/ND_ATMs/source/client.lua @@ -1,12 +1,7 @@ ------------------------------------------------------------------------- ------------------------------------------------------------------------- --- DO NOT EDIT IF YOU DON'T KNOW WHAT YOU'RE DOING -- --- -- --- For support join my discord: https://discord.gg/Z9Mxu72zZ6 -- ------------------------------------------------------------------------- ------------------------------------------------------------------------- +-- For support join my discord: https://discord.gg/Z9Mxu72zZ6 + local display = false -local balance = nil +local nearModel = false local atmModels = { "-870868698", -- older atms @@ -38,68 +33,109 @@ function getTime() return hours .. ":" .. minutes end --- Alert on top left of screen -function alert(msg) - BeginTextCommandDisplayHelp("STRING") - AddTextComponentSubstringPlayerName(msg) - EndTextCommandDisplayHelp(0, 0, 1, -1) -end - --- Check if player is near an atm -function IsNearATM() - local playerCoords = GetEntityCoords(PlayerPedId(), 0) - for k, v in pairs(atmModels) do - ATM = GetCoordsAndRotationOfClosestObjectOfType(playerCoords.x, playerCoords.y, playerCoords.z, 0.7, tonumber(v), 0) - if ATM == 1 then - return true - end - end -end - -- Hide/Show ui function SetDisplay(bool) + local playerInfo = exports["ND_Core"]:getCharacterInfo() display = bool SetNuiFocus(bool, bool) SendNUIMessage({ status = bool, - playerName = exports["ND_Core"]:getCharacterInfo(1) .. " " .. exports["ND_Core"]:getCharacterInfo(2), - balance = "Account Balance: $" .. exports["ND_Core"]:getCharacterInfo(8) .. ".00", + playerName = playerInfo.firstName .. " " .. playerInfo.lastName, + balance = "Account Balance: $" .. playerInfo.bank .. ".00", date = days[GetClockDayOfWeek() + 1], time = getTime() }) end +function drawText3D(coords, text) + local onScreen, _x, _y = World3dToScreen2d(coords.x, coords.y, coords.z + 1) + local pX, pY, pZ = table.unpack(GetGameplayCamCoords()) + SetTextScale(0.4, 0.4) + SetTextFont(4) + SetTextProportional(1) + SetTextEntry("STRING") + SetTextCentre(true) + SetTextColour(255, 255, 255, 255) + SetTextOutline() + AddTextComponentString(text) + DrawText(_x, _y) +end + +-- check if ped is close to an atm object. +function inRange(ped) + playerCoords = GetEntityCoords(ped) + for _, atm in pairs(atmModels) do + object, outPosition, outRotation = GetCoordsAndRotationOfClosestObjectOfType(playerCoords.x, playerCoords.y, playerCoords.z, 0.7, tonumber(atm), 0) + if object == 1 then + return true + end + end +end + +Citizen.CreateThread(function() + while true do + Citizen.Wait(500) + ped = PlayerPedId() + nearModel = inRange(ped) + end +end) + +Citizen.CreateThread(function() + while true do + Citizen.Wait(0) + if not display and nearModel then + drawText3D(outPosition, "~w~Press ~r~E ~w~to use the ATM") + if IsControlJustPressed(0, 51) then + SetDisplay(true) + TriggerScreenblurFadeIn(1000) + end + end + end +end) + +-- close the ui. RegisterNUICallback("close", function(data) PlaySoundFrontend(-1, "PIN_BUTTON", "ATM_SOUNDS", 1) SetDisplay(false) + TriggerScreenblurFadeOut(1000) end) +-- makes a button sount for when the ui is clicked. RegisterNUICallback("sound", function(data) PlaySoundFrontend(-1, "PIN_BUTTON", "ATM_SOUNDS", 1) end) -RegisterNUICallback("withdraw", function(data) - TriggerServerEvent("ND:withdraw", data.amount) +-- deposit/withdraw +RegisterNUICallback("useATM", function(data) + local action = string.gsub(data.action, " ", "") + if action == "WITHDRAW" then + if data.amount == "" then + Citizen.Wait(1000) + SendNUIMessage({ + success = false + }) + return + end + TriggerServerEvent("ND_ATM:withdraw", data.amount) + elseif action == "DEPOSIT" then + if data.amount == "" then + Citizen.Wait(1000) + SendNUIMessage({ + success = false + }) + return + end + TriggerServerEvent("ND_ATM:deposit", data.amount) + end end) -RegisterNUICallback("deposit", function(data) - TriggerServerEvent("ND:deposit", data.amount) -end) - --- Alert thread -Citizen.CreateThread(function() - while true do - Citizen.Wait(0) - if not display and IsNearATM() then - alert("Press ~INPUT_CONTEXT~ to use the ATM") - if IsControlJustPressed(0, 51) then - SetDisplay(true) - end - if display then - TriggerScreenblurFadeIn(1000) - else - TriggerScreenblurFadeOut(1000) - end - end - end -end) +-- update the balance on the ui and confirm if the deposit/withdraw was successful. +RegisterNetEvent("ND_ATM:update") +AddEventHandler("ND_ATM:update", function(status) + Citizen.Wait(1000) + local playerInfo = exports["ND_Core"]:getCharacterInfo() + SendNUIMessage({ + balance = "Account Balance: $" .. playerInfo.bank .. ".00", + success = status + }) +end) \ No newline at end of file diff --git a/ND_ATMs/source/server.lua b/ND_ATMs/source/server.lua index 4f5debc..d950829 100644 --- a/ND_ATMs/source/server.lua +++ b/ND_ATMs/source/server.lua @@ -1,75 +1,13 @@ --- For support join my discord: https://discord.gg/Z9Mxu72zZ6 - -expectedName = "ND_ATMs" -- This is the resource and is not suggested to be changed. -resource = GetCurrentResourceName() - --- check if resource is renamed -if resource ~= expectedName then - print("^1[^4" .. expectedName .. "^1] WARNING^0") - print("Change the resource name to ^4" .. expectedName .. " ^0or else it won't work!") -end - --- check if resource version is up to date -PerformHttpRequest("https://raw.githubusercontent.com/Andyyy7666/ND_Framework/main/ND_ATMs/fxmanifest.lua", function(error, res, head) - i, j = string.find(tostring(res), "version") - res = string.sub(tostring(res), i, j + 6) - res = string.gsub(res, "version ", "") - res = string.gsub(res, '"', "") - resp = tonumber(res) - verFile = GetResourceMetadata(expectedName, "version", 0) - - if verFile then - if tonumber(verFile) < resp then - print("^1[^4" .. expectedName .. "^1] WARNING^0") - print("^4" .. expectedName .. " ^0is outdated. Please update it from ^5https://github.com/Andyyy7666/ND_Framework ^0| Current Version: ^1" .. verFile .. " ^0| New Version: ^2" .. resp .. " ^0|") - elseif tonumber(verFile) > tonumber(resp) then - print("^1[^4" .. expectedName .. "^1] WARNING^0") - print("^4" .. expectedName .. "s ^0version number is higher than we expected. | Current Version: ^3" .. verFile .. " ^0| Expected Version: ^2" .. resp .. " ^0|") - else - print("^4" .. expectedName .. " ^0is up to date | Current Version: ^2" .. verFile .. " ^0|") - end - else - print("^1[^4" .. expectedName .. "^1] WARNING^0") - print("You may not have the latest version of ^4" .. expectedName .. "^0. A newer, improved version may be present at ^5https://github.com/Andyyy7666/ND_Framework^0") - end +RegisterNetEvent("ND_ATM:withdraw") +AddEventHandler("ND_ATM:withdraw", function(amount) + local player = source + local update = exports["ND_Core"]:withdrawMoney(amount, player) + TriggerClientEvent("ND_ATM:update", player, update) end) -function GetPlayerIdentifierFromType(type, source) -- Credits: xander1998, Post: https://forum.cfx.re/t/solved-is-there-a-better-way-to-get-lic-steam-and-ip-than-getplayeridentifiers/236243/2?u=andyyy7666 - local identifiers = {} - local identifierCount = GetNumPlayerIdentifiers(source) - - for a = 0, identifierCount do - table.insert(identifiers, GetPlayerIdentifier(source, a)) - end - - for b = 1, #identifiers do - if string.find(identifiers[b], type, 1) then - return identifiers[b] - end - end - return nil -end - -RegisterNetEvent("ND:withdraw") -AddEventHandler("ND:withdraw", function(amount) +RegisterNetEvent("ND_ATM:deposit") +AddEventHandler("ND_ATM:deposit", function(amount) local player = source - local characterId = exports["ND_Core"]:getCharacterTable()[player].characterId - exports.oxmysql:query("UPDATE characters SET bank = bank - ? WHERE license = ? AND character_id = ?", {amount, GetPlayerIdentifierFromType("license", player), characterId}, function(result) - if result then - exports.oxmysql:query("UPDATE characters SET cash = cash + ? WHERE license = ? AND character_id = ?", {amount, GetPlayerIdentifierFromType("license", player), characterId}) - TriggerClientEvent("updateMoney", player) - end - end) -end) - -RegisterNetEvent("ND:deposit") -AddEventHandler("ND:deposit", function(amount) - local player = source - local characterId = exports["ND_Core"]:getCharacterTable()[player].characterId - exports.oxmysql:query("UPDATE characters SET cash = cash - ? WHERE license = ? AND character_id = ?", {amount, GetPlayerIdentifierFromType("license", player), characterId}, function(result) - if result then - exports.oxmysql:query("UPDATE characters SET bank = bank + ? WHERE license = ? AND character_id = ?", {amount, GetPlayerIdentifierFromType("license", player), characterId}) - TriggerClientEvent("updateMoney", player) - end - end) + local update = exports["ND_Core"]:depositMoney(amount, player) + TriggerClientEvent("ND_ATM:update", player, update) end) \ No newline at end of file diff --git a/ND_ATMs/source/ui/index.html b/ND_ATMs/source/ui/index.html new file mode 100644 index 0000000..dccafe0 --- /dev/null +++ b/ND_ATMs/source/ui/index.html @@ -0,0 +1,44 @@ + + + + + + + + + + +
+
+ +

+

+
+
+

Welcome back

+

+
+
+

+ + + +
+
+
+

Are you sure you'd like to perform this action

+ + +
+
+

Success!

+ +
+
+

Failed!

+ +
+ +
+ + \ No newline at end of file diff --git a/ND_ATMs/source/ui/script.js b/ND_ATMs/source/ui/script.js new file mode 100644 index 0000000..e153bb0 --- /dev/null +++ b/ND_ATMs/source/ui/script.js @@ -0,0 +1,132 @@ +$(function() { + function display(bool) { + if (bool) { + $("#overlay").show(); + } else { + $("#overlay").hide(); + } + } + function atmDisplay(bool) { + if (bool) { + $("#atm").show(); + $("#loader, #confirmationScreen, #successScreen, #failedScreen").hide(); + return; + } + $("#atm").hide(); + } + function loader(bool) { + if (bool) { + $("#loader").show(); + $("#atm, #confirmationScreen, #successScreen, #failedScreen").hide(); + return; + } + $("#loader").hide(); + } + function confirmationScreen(bool) { + if (bool) { + $("#confirmationScreen").show(); + $("#atm, #loader, #successScreen, #failedScreen").hide(); + return; + } + $("#confirmationScreen").hide(); + } + function successScreen(bool) { + if (bool) { + $("#successScreen").show() + $("#confirmationScreen, #atm, #loader, #failedScreen").hide(); + return; + } + $("#successScreen").hide(); + } + function failedScreen(bool) { + if (bool) { + $("#failedScreen").show() + $("#confirmationScreen, #atm, #loader, #successScreen").hide(); + return; + } + $("#failedScreen").hide(); + } + display(false); + atmDisplay(true); + loader(false); + confirmationScreen(false); + successScreen(false); + + const today = new Date(); + let action; + + window.addEventListener("message", function(event) { + const item = event.data; + $("#balance").text(item.balance); + if (item.status) { + display(true); + $("#playername").text(item.playerName); + $("#date").text(`${item.date}, ${today.toLocaleDateString("en-US", {year: "numeric", month: "long", day: "numeric"})}`); + $("#time").text(item.time); + } else if (item.status === false) { + display(false); + } + if (item.success) { + loader(false); + successScreen(true); + } else if (item.success === false) { + loader(false); + failedScreen(true); + } + }) + + $("button[type=submit]").click(function () { + action = $(this).text(); + }); + + $("#confirmButton").click(function() { + $.post(`https://${GetParentResourceName()}/sound`); + confirmationScreen(false); + loader(true); + $.post(`https://${GetParentResourceName()}/useATM`, JSON.stringify({ + action: action, + amount: $("#enteredAmount").val() + })); + $("#enteredAmount").val(""); + return false; + }) + + $("#cancelButton").click(function() { + $.post(`https://${GetParentResourceName()}/sound`); + confirmationScreen(false); + loader(true); + setTimeout(() => { + loader(false); + atmDisplay(true); + }, 300); + return false; + }) + + $("#atm").submit(function() { + $.post(`https://${GetParentResourceName()}/sound`); + atmDisplay(false); + loader(true); + setTimeout(() => { + loader(false); + confirmationScreen(true); + }, 300); + return false; + }) + + $(".mainMenuButton").click(function() { + $.post(`https://${GetParentResourceName()}/sound`); + successScreen(false); + failedScreen(false); + loader(true); + setTimeout(() => { + loader(false); + atmDisplay(true); + }, 300); + return false; + }) + + $("#closeButton").click(function() { + $.post(`https://${GetParentResourceName()}/close`); + return; + }) +}); \ No newline at end of file diff --git a/ND_ATMs/source/ui/style.css b/ND_ATMs/source/ui/style.css new file mode 100644 index 0000000..44b7bfc --- /dev/null +++ b/ND_ATMs/source/ui/style.css @@ -0,0 +1,212 @@ +body { + font-family: Arial, Helvetica, sans-serif; +} + +#overlay { + display: none; + position: absolute; + height: 60vh; + width: 50vw; + top: 0; + left: 0; + right: 0; + bottom: 0; + margin: auto; + border-radius: 10px; + background-image: linear-gradient(rgb(255, 255, 255), rgb(199, 199, 199)); + background-color: white; +} + +#logo { + position: absolute; + width: 300px; + top: 2vh; + left: 6vw; + margin: auto; +} + +#date { + position: absolute; + top: 3.5vh; + right: 6vw; + color: black; + font-size: 18px; +} + +#time { + position: absolute; + font-weight: 500; + top: -0.7vh; + right: 6vw; + color: black; + font-size: 30px; +} + +#balance { + position: absolute; + top: 23vh; + font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;; + font-weight: 500; + left: 0; + right: 0; + margin: auto; + color: black; + font-size: 20px; + text-align: center; +} + +#confirmText { + position: absolute; + top: 26vh; + font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;; + font-weight: 500; + left: 0; + right: 0; + margin: auto; + color: black; + font-size: 20px; + text-align: center; +} + +#redline { + position: absolute; + height: 1vh; + width: 80%; + top: 9vh; + left: 0; + right: 0; + margin: auto; + background-color: red; + border-radius: 5px; + border: none; +} + +#redbox { + position: absolute; + height: 5vh; + width: 80%; + top: 11vh; + left: 0; + right: 0; + margin: auto; + background-color: red; + background-image: linear-gradient(rgb(204, 2, 2), rgb(255, 0, 0)); + border-radius: 5px; + border: none; +} + +#playername { + position: absolute; + top: 13vh; + left: 0; + right: 0; + margin: auto; + color: white; + text-align: center; +} + +#welcome { + position: absolute; + top: 11.5vh; + left: 0; + right: 0; + margin: auto; + color: white; + text-align: center; +} + +.input { + height: 4vh; + width: 7.3vw; + background-color: rgb(255, 0, 0); + font-weight: 1000; + color: white; + border: none; + border-radius: 5px; + margin: auto; + font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;; + transition: 50ms; +} + +.input:hover { + transition: 50ms; + background-color: rgb(214, 2, 2); +} + +#enteredAmount { + position: absolute; + width: 15.8vw; + top: 28vh; + left: 0; + right: 0; + color: black; + background-color: white; + text-align: center; +} + +#withdrawButton { + position: absolute; + top: 36.5vh; + left: 17vw; +} + +#depositButton { + position: absolute; + top: 36.5vh; + right: 17vw; +} + +.mainMenuButton { + position: absolute; + width: 10vw; + top: 34vh; + right: 0; + left: 0; + margin: auto; +} + +#closeButton { + position: absolute; + height: 4.8vh; + width: 80%; + top: 50vh; + left: 0; + right: 0; +} + +#confirmButton{ + position: absolute; + top: 33vh; + left: 17vw; +} + +#cancelButton { + position: absolute; + top: 33vh; + right: 17vw; +} + +#confirmationScreen { + display: none; +} + +#loader { + display: none; + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + margin: auto; + border: 16px solid #d1d1d1; + border-radius: 50%; + border-top: 16px solid red; + width: 120px; + height: 120px; + animation: spin 1s linear infinite; +} + +@keyframes spin { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } +} \ No newline at end of file