Add files via upload

This commit is contained in:
Andyyy7666
2022-07-08 23:19:05 +02:00
committed by GitHub
parent f9c2940e15
commit 9f14ba65cb
6 changed files with 488 additions and 128 deletions

View File

@@ -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"

View File

@@ -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)

View File

@@ -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)

View File

@@ -0,0 +1,44 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="style.css">
<script src="https://use.fontawesome.com/releases/v5.15.4/js/all.js" data-auto-a11y="true"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="script.js" type="text/javascript"></script>
</head>
<body>
<section id="overlay">
<div id="info">
<img src="https://i.imgur.com/NCgZtVe.png" id="logo">
<p id="date"></p>
<p id="time"></p>
<hr id="redline">
<hr id="redbox">
<p id="welcome">Welcome back</p>
<h1 id="playername"></h1>
</div>
<form id="atm">
<p id="balance"></p>
<input id="enteredAmount" class="input" type="number" placeholder="AMOUNT" min="20" max="2500">
<button id="withdrawButton" class="input" type="submit" form="atm"><i class="fas fa-coins"></i> WITHDRAW</button>
<button id="depositButton" class="input" type="submit" form="atm"><i class="fas fa-credit-card"></i> DEPOSIT</button>
</form>
<div id="loader"></div>
<div id="confirmationScreen">
<p id="confirmText">Are you sure you'd like to perform this action</p>
<button id="confirmButton" class="input"><i class="fas fa-check-circle"></i> CONFIRM</button>
<button id="cancelButton" type="reset" form="atm" class="input"><i class="fas fa-times-circle"></i> CANCEL</button>
</div>
<div id="successScreen">
<p id="confirmText">Success!</p>
<button type="reset" form="atm" class="input mainMenuButton"><i class="fas fa-chevron-circle-left"></i> BACK TO MAIN MENU</button>
</div>
<div id="failedScreen">
<p id="confirmText">Failed!</p>
<button type="reset" form="atm" class="input mainMenuButton"><i class="fas fa-chevron-circle-left"></i> BACK TO MAIN MENU</button>
</div>
<button id="closeButton" type="reset" form="atm" class="input"><i class="fas fa-sign-out-alt"></i> EXIT</button>
</section>
</body>
</html>

132
ND_ATMs/source/ui/script.js Normal file
View File

@@ -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;
})
});

212
ND_ATMs/source/ui/style.css Normal file
View File

@@ -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); }
}