1
0
Fork 0
forked from Simnation/Main
This commit is contained in:
Nordi98 2025-06-26 02:53:14 +02:00
parent b863bc9763
commit f653901eb9
33 changed files with 665 additions and 478 deletions

View file

@ -1,20 +0,0 @@
# Moon Better Printers
Replace the Folder Completely and dont change name of the resource it should be "moon-printers" only
Welcome to Moon Better Printers
This script makes your qbcore server more and more happening and gives the whitelisted job rp players to extend there roleplay
To add printers all you have to do is check config.lua i have told in detail how can you add more printers
Dont Forget to Do this Before your Start the resource
* ATTENTION: To have this working correctly you MUST change shared.lua as follows: `Search for "printerdocument" and make ["unique"] = true` otherwise documents WILL STACK and You'll be able to see only latest.
* To change DEFAULT printerdocument's image navigate to qb-inventory/server/main.lua:1549 and change `info.url = "https://media.discordapp.net/attachments/1108856433048551515/1109068096104308838/image.png"` default URL there.
![image](https://github.com/OmiJod/Omi-printers/assets/69292814/e0099297-0544-4058-9540-a070c997b7a5)
![image](https://github.com/OmiJod/Omi-printers/assets/69292814/a94b1e7b-0fc5-4ddd-8f34-c1a810fdf5c4)
![image](https://github.com/OmiJod/Omi-printers/assets/69292814/c8bcdde9-4a73-4e86-ba07-98756732a3d7)

View file

@ -1,71 +0,0 @@
local QBCore = exports["qb-core"]:GetCoreObject()
local Props = {}
local Targets = {}
function despawnprintersandtargets()
for i = 1, #Props do unloadModel(GetEntityModel(Props[i])) DeleteObject(Props[i]) end
for k in pairs(Targets) do exports['qb-target']:RemoveZone(k) end
end
CreateThread(function()
for k,v in pairs(Config.Printers) do
Props[#Props+1] = makeProp({coords = v.coords, prop = v.prop}, 1, false)
local name = 'Printers'..k
-- Vereinfachte Target-Option ohne Abhängigkeit von QBCore.Shared.Jobs
Targets[name] = exports['qb-target']:AddBoxZone(name, v.coords, 2.0, 2.0, {
heading = v.coords.w,
debugPoly = Config.Debug,
minZ = v.coords.z - 1,
maxZ = v.coords.z + 0.5,
}, {
options = {
{
event = 'moon-printers:client:useprinterbox',
icon = "fas fa-print",
label = 'Print Document',
job = k,
},
},
distance = 3.0
})
end
end)
-- Events
RegisterNetEvent('moon-printers:client:UsePaperDocument', function(ItemData)
local DocumentUrl = ItemData.info.url ~= nil and ItemData.info.url or false
SendNUIMessage({
action = "openprinternui",
url = DocumentUrl
})
SetNuiFocus(true, false)
end)
-- PRINTER AND DOCUMRNTS NUI
RegisterNetEvent('moon-printers:client:useprinterbox', function()
local ped = PlayerPedId()
local pos = GetEntityCoords(ped)
if PrinterObject ~= 0 then
SendNUIMessage({
action = "startprinternui"
})
SetNuiFocus(true, true)
end
end)
RegisterNUICallback('SaveDocument', function(data)
if data.url then
TriggerServerEvent('moon-printers:server:SavePaperDocument', data.url)
end
end)
RegisterNUICallback('CloseDocument', function()
SetNuiFocus(false, false)
end)
AddEventHandler('onResourceStop', function(resource) if resource == GetCurrentResourceName() then despawnprintersandtargets() end end)

View file

@ -1,16 +0,0 @@
Config = {}
Config.Debug = false
Config.Amount = 0
Config.Printers = {
kayas = {--- Job Name
prop = `v_res_printer`, --- Prop that should Pe Spawned
coords = vector4(1534.3607, 3782.4038, 35.6940, 29.5995)
},
police = {
prop = `prop_copier_01`,
coords = vector4(208.79, -829.61, 30.75, 117.04)
},
}

View file

@ -1,45 +0,0 @@
fx_version 'cerulean'
game 'gta5'
lua54 'yes'
version '2.0.0'
author 'Nullvalue#6848'
description 'moon-printers'
files {
'*.lua',
'html/*.html',
'html/*.js',
'html/*.css',
'html/*.png',
}
shared_script {
'shared/*.lua',
}
client_scripts {
'config.lua',
'client/*.lua',
}
server_scripts {
'config.lua',
'@oxmysql/lib/MySQL.lua',
'server/server.lua',
}
-- dependencies {
-- 'ps-ui',
-- 'qb-target',
-- }
escrow_ignore {
"config.lua"
}
ui_page 'html/index.html'

View file

@ -1,65 +0,0 @@
PrinterBox = {}
$(document).ready(function() {
window.addEventListener('message', function(event) {
var action = event.data.action;
switch (action) {
case "openprinternui":
PrinterBox.Open(event.data);
break;
case "startprinternui":
PrinterBox.Start(event.data);
break;
case "close":
PrinterBox.Close(event.data);
break;
}
});
});
$(document).ready(function() {
$('.printerbox-accept').click(function() {
PrinterBox.Save();
PrinterBox.Close();
});
$('.printerbox-decline').click(function() {
PrinterBox.Close();
});
});
$(document).on('keydown', function() {
switch (event.keyCode) {
case 27: // ESC
PrinterBox.Close();
break;
case 9: // ESC
PrinterBox.Close();
break;
}
});
PrinterBox.Open = function(data) {
if (data.url) {
$(".paper-container").fadeIn(150);
$(".document-image").attr('src', data.url);
} else {
console.log('No document is linked to it!!!!!')
}
}
PrinterBox.Start = function(data) {
$(".printerbox-container").fadeIn(150);
}
PrinterBox.Save = function(data) {
$.post('https://moon-printers/SaveDocument', JSON.stringify({
url: $('.printerboxurl-input').val()
}));
}
PrinterBox.Close = function(data) {
$(".printerbox-container").fadeOut(150);
$(".paper-container").fadeOut(150);
$.post('https://moon-printers/CloseDocument');
}

View file

@ -1,34 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Printer For QB CORE Made by Omi</title>
<link rel="stylesheet" href="./style.css">
<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.7.2/animate.min.css">
</head>
<body>
<div class="container">
<div class="paper-container">
<img class="document-image" src="">
</div>
<div class="printerbox-container">
<input type="text" class="printerboxurl-input" placeholder="Document Image URL" required>
<!-- <input type="text" class="printerbox-header" placeholder="Printer" readonly required> -->
<div class="printerbox-accept">
<span class="button-text">Print 📄</span>
</div>
<div class="printerbox-decline">
<span class="button-text">Cancel ✖</span>
</div>
</div>
</div>
<script src="./app.js"></script>
</body>
</html>

View file

@ -1,149 +0,0 @@
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@100&display=swap');
body {
margin: 0;
padding: 0;
}
.container {
height: 100vh;
font-family: 'Poppins', sans-serif;
}
.paper-container {
display: none;
position: absolute;
width: 55vh;
height: 85vh;
margin: 0 auto;
left: 0;
right: 0;
top: 50%;
transform: translateY(-50%);
}
.paper-container>img {
position: absolute;
max-width: 200%;
max-height: 200%;
border: 8px dashed rgb(0, 0, 0);
top: 0;
left: 0;
}
.printerbox-container {
display: none;
position: absolute;
top: 50%;
transform: translateY(-50%);
width: 60vh;
height: 25vh;
background-color: rgba(0, 0, 0, 0.774);
border-style: inset;
border-radius: 2vh;
border: 1.5px solid rgb(240, 240, 240);
margin: 0 auto;
left: 50%;
right: 0;
overflow: hidden;
}
/* .printerbox-header {
position: absolute;
top: 0;
left: 0;
cursor:not-allowed;
display: inline-block;
text-align: center;
width: 100%;
height: 10%;
background-color: rgb(45, 108, 190);
} */
/* .header-icon {
position: absolute;
top: 0;
left: 0;
width: 3.5vh;
margin: .75vh;
} */
.printerboxurl-input {
position: absolute;
margin: 0 auto;
left: 0;
right: 0;
top: 35%;
/* border-style: inset; */
transform: translateY(-50%);
width: 40vh;
height: 4.5vh;
color: rgb(255, 255, 255);
font-weight: bolder;
border: 3px solid rgb(255, 255, 255);
border-radius: 2vh;
background-color: rgb(0, 0, 0);
outline: none;
text-align: center;
font-family: 'Poppins', sans-serif;
transition: .2s ease-in-out;
}
.printerboxurl-input:focus {
border: .4vh solid rgb(55, 126, 192);
}
.printerboxurl-input:valid {
/* border-radius: 1.5vh 1.5vh 0 0; */
border: .4vh solid rgb(9, 150, 143);
}
.printerbox-accept {
position: absolute;
bottom: 0;
left: 0;
width: 15vh;
height: 5vh;
background-color: rgba(34, 221, 118, 0.842);
font-size: 0.5cm;
font-weight: 400;
cursor: pointer;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
border: 2px solid rgb(202, 202, 202);
border-radius: 2vh;
margin: 5vh;
left: 10%;
color: rgb(0, 0, 0);
text-align: center;
line-height: 5vh;
}
.printerbox-decline {
position: absolute;
bottom: 0;
right: 0;
width: 15vh;
height: 5vh;
font-size: 0.5cm;
cursor: pointer;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
/* font-size: 1cm; */
background-color: rgb(255, 0, 0, 0.575);
border: 2px solid rgb(202, 202, 202);
border-radius: 2vh;
font-weight: bolder;
margin: 5vh;
right: 10%;
color: rgb(0, 0, 0);
text-align: center;
line-height: 5vh;
}
.button-text {
display: inline-block;
}
::placeholder {
color: rgb(255, 255, 255);
font-size: larger;
font-weight: bolder;
}

View file

@ -1,42 +0,0 @@
local QBCore = exports['qb-core']:GetCoreObject()
local ValidExtensions = {
[".png"] = true,
[".gif"] = true,
[".jpg"] = true,
["jpeg"] = true
}
local ValidExtensionsText = '.png, .gif, .jpg, .jpeg'
QBCore.Functions.CreateUseableItem("printerdocument", function(source, item)
TriggerClientEvent('moon-printers:client:UsePaperDocument', source, item)
end)
RegisterNetEvent('moon-printers:server:SavePaperDocument', function(url)
local src = source
local Player = QBCore.Functions.GetPlayer(src)
local info = {}
local extension = string.sub(url, -4)
local cash = Player.PlayerData.money['cash']
local validexts = ValidExtensions
if url ~= nil then
if validexts[extension] then
info.url = url
if cash >= Config.Amount then
if Player.Functions.RemoveItem('paper', 1) then
Player.Functions.AddItem('printerdocument', 1, nil, info)
TriggerClientEvent('inventory:client:ItemBox', src, QBCore.Shared.Items['printerdocument'], "add")
TriggerClientEvent('inventory:client:ItemBox', src, QBCore.Shared.Items['tosti'], "remove")
Player.Functions.RemoveMoney('cash', Config.Amount, 'Document-printed')
else
TriggerClientEvent('QBCore:Notify', source, 'You Dont Have A5 Paper', 'error', 2500)
end
else
TriggerClientEvent('QBCore:Notify', source, 'Paisa Nai Hai Gandu Tere pass '..Config.Amount..' Lagega', 'error', 2500)
end
else
TriggerClientEvent('QBCore:Notify', src, 'Thats not a valid extension, only '..ValidExtensionsText..' extension links are allowed.', "error")
end
end
end)

View file

@ -1,36 +0,0 @@
local QBCore = exports["qb-core"]:GetCoreObject()
RegisterNetEvent('QBCore:Client:UpdateObject', function() QBCore = exports['qb-core']:GetCoreObject() end)
local time = 1000
function loadModel(model)
if not HasModelLoaded(model) then
if Config.Debug then print("^5Debug^7: ^2Loading Model^7: '^6"..model.."^7'") end
while not HasModelLoaded(model) do
if time > 0 then time = time - 1 RequestModel(model)
else time = 1000 print("^5Debug^7: ^3LoadModel^7: ^2Timed out loading model ^7'^6"..model.."^7'") break
end
Citizen.Wait(1000)
end
end
end
function unloadModel(model) if Config.Debug then print("^5Debug^7: ^2Removing Model^7: '^6"..model.."^7'") end SetModelAsNoLongerNeeded(model) end
function destroyProp(entity)
if Config.Debug then print("^5Debug^7: ^2Destroying Prop^7: '^6"..entity.."^7'") end
SetEntityAsMissionEntity(entity)
Citizen.Wait(1000)
DetachEntity(entity, true, true)
Citizen.Wait(1000)
DeleteObject(entity)
end
function makeProp(data, freeze, synced)
loadModel(data.prop)
local prop = CreateObject(data.prop, data.coords.x, data.coords.y, data.coords.z-1.03, synced or false, synced or false, 0)
SetEntityHeading(prop, data.coords.w+180.0)
FreezeEntityPosition(prop, freeze or 0)
if Config.Debug then print("^5Debug^7: ^6Prop ^2Created ^7: '^6"..prop.."^7'") end
return prop
end

View file

@ -0,0 +1,6 @@
github: #
patreon: #
open_collective: #
ko_fi: #
buy_me_a_coffee: pulsepk
custom: ["https://pulsescripts.tebex.io/"]

View file

@ -0,0 +1,37 @@
name: Release
on:
push:
tags:
- 'v*'
permissions:
contents: write
jobs:
create-release:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Zip repository with folder
run: |
mkdir temp
repo_name=$(basename $GITHUB_REPOSITORY)
mkdir temp/$repo_name
shopt -s extglob
cp -r !(temp|.git) temp/$repo_name/
cd temp
zip -r ../$repo_name.zip $repo_name
cd ..
- name: Create GitHub release
uses: softprops/action-gh-release@v1
with:
name: Release ${{ github.ref_name }}
tag_name: ${{ github.ref_name }}
files: ${{ github.event.repository.name }}.zip
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View file

@ -0,0 +1,35 @@
# Pulse Printer | ESX, QBCore, QBox
##
![Image](https://i.imgur.com/r9ErEkc.png)
##
![Video Preview] (https://youtu.be/4yrAf1gWQps)
Check the below documentation link for installation
## Documentation
https://docs.pulsescripts.dev/
##
## Features
######
- Support ESX, QBCore, QBox Frameworks
- Print Any Document You Want
- Spawns Printer at any location
- qb-target, qtarget, ox_target
- Deduct Money For Prints
######
##
Only Fivemanage Links will work cause others are blocked by FiveM
##
## Support, Scripts & More
- [Script Store](https://pulsescripts.tebex.io/)
- [Join the Discord For Support](https://discord.gg/c6gXmtEf3H)
######
## Dependencies
- [ox_lib](https://github.com/overextended/ox_lib/releases)
- [qtarget](https://github.com/overextended/qtarget.git), [ox_target](https://github.com/overextended/ox_target/releases), [qb-target](https://github.com/qbcore-framework/qb-target)
##

View file

@ -0,0 +1,12 @@
local ESX = GetResourceState('es_extended'):find('start') and exports['es_extended']:getSharedObject() or nil
if not ESX then return end
function Notification(msg)
ESX.ShowNotification(msg)
end
RegisterNetEvent('esx:playerLoaded')
AddEventHandler('esx:playerLoaded', function()
onPlayerLoaded()
end)

View file

@ -0,0 +1,11 @@
local QBCore = GetResourceState('qb-core'):find('start') and exports['qb-core']:GetCoreObject() or nil
if not QBCore then return end
function Notification(message, type)
QBCore.Functions.Notify(message, type)
end
RegisterNetEvent('QBCore:Client:OnPlayerLoaded', function()
onPlayerLoaded()
end)

View file

@ -0,0 +1,158 @@
local spawnedObjects = {}
local imageDisplayed = false
RegisterNetEvent('pl_printer:notification')
AddEventHandler('pl_printer:notification', function(message, type)
if Config.Notify == 'ox' then
TriggerEvent('ox_lib:notify', {description = message, type = type or "success"})
elseif Config.Notify == 'esx' then
Notification(message)
elseif Config.Notify == 'okok' then
TriggerEvent('okokNotify:Alert', message, 6000, type)
elseif Config.Notify == 'qb' then
Notification(message, type)
elseif Config.Notify == 'wasabi' then
exports.wasabi_notify:notify('Printer', message, 6000, type, false, 'fas fa-ghost')
elseif Config.Notify == 'custom' then
-- Add your custom notifications here
end
end)
function disableControls()
SetEntityInvincible(PlayerPedId(), true)
FreezeEntityPosition(PlayerPedId(), true)
end
function enableControls()
SetEntityInvincible(PlayerPedId(), false)
FreezeEntityPosition(PlayerPedId(), false)
end
RegisterNetEvent("pl_printer:showImageQB")
AddEventHandler("pl_printer:showImageQB", function(imageName)
TriggerServerEvent('pl_printer:fetchImageLink',imageName)
end)
RegisterNetEvent("pl_printer:showImage")
AddEventHandler("pl_printer:showImage", function(imageName)
if not imageDisplayed then
imageDisplayed = true
SetNuiFocus(true, true)
SendNUIMessage({
action = "show",
imageUrl = imageName
})
disableControls()
end
end)
RegisterNUICallback('hideFrame', function(data, cb)
imageDisplayed = false
SetNuiFocus(false, false)
enableControls()
end)
RegisterNetEvent("pl_printer:openprinter")
AddEventHandler("pl_printer:openprinter", function()
local input = lib.inputDialog('Print Menu', {
{type = 'input', label = Locale("image_link"), description = Locale("image_url"), required = true},
{type = 'number', label = Locale("copies"), description = Locale("image_url"),required = true,placeholder='1', icon = 'hashtag'},
})
if input then
if input[1] and input[2] then
TriggerServerEvent('pl_printer:insertImageData', input[1], input[2])
else
_debug('[DEBUG] '..'Invalid Input'..'')
end
end
end)
for _, model in ipairs(Config.PrinterModel) do
if GetResourceState('qb-target') == 'started' then
exports['qb-target']:AddTargetModel(model, {
options = {
{
icon = 'fa-solid fa-print',
label = Locale("prints"),
action = function(data)
TriggerEvent('pl_printer:openprinter')
end,
},
},
distance = 2
})
elseif GetResourceState('qtarget') == 'started' or GetResourceState('ox_target') == 'started'then
exports.ox_target:addModel(model, {
{
name = 'printer_interaction',
label = Locale("prints"),
icon = 'fa-solid fa-print',
onSelect = function(data)
TriggerEvent('pl_printer:openprinter')
end,
distance = 2,
}
})
end
end
local function spawnObject(object, coords, heading)
lib.requestModel(object)
if not HasModelLoaded(object) then
_debug('[DEBUG] '..object..' failed to load.'..'')
return
end
local entity = CreateObject(object, coords.x, coords.y, coords.z, true, true, true)
if DoesEntityExist(entity) then
SetEntityHeading(entity, heading)
FreezeEntityPosition(entity, true)
table.insert(spawnedObjects, entity)
else
_debug('[DEBUG] '..' Failed to spawn object: '..object..'')
end
end
local function deleteSpawnedObjects()
for _, obj in ipairs(spawnedObjects) do
if DoesEntityExist(obj) then
DeleteObject(obj)
end
end
spawnedObjects = {}
end
AddEventHandler('onResourceStart', function(resourceName)
if GetCurrentResourceName() ~= resourceName then return end
for _, location in ipairs(Config.Locations) do
spawnObject(location.object, location.coords, location.heading)
end
end)
AddEventHandler('onResourceStop', function(resourceName)
if GetCurrentResourceName() ~= resourceName then return end
deleteSpawnedObjects()
end)
function onPlayerLoaded()
Wait(3000)
for _, location in ipairs(Config.Locations) do
spawnObject(location.object, location.coords, location.heading)
end
end
function _debug(...)
if Config.Debug then
print(...)
end
end

View file

@ -0,0 +1,28 @@
Config = {}
Config.Locale = 'de' -- 'en', 'fr', 'de', 'es', 'it', 'pt', 'tr' -- Language
Config.Debug = true
Config.Notify = 'okok' --ox, esx, okok,qb,wasabi,custom
Config.CheckItem = false --If you want player to have item before opening
Config.PrinterModel = {`prop_printer_02`,`prop_printer_01`,`v_res_printer`}
Config.ItemName = 'paper'
Config.Print = {
Price = 0, --Price
Account = 'bank' --This is the account your money will be deducted
}
Config.EnableLocation = false
Config.Locations = {
{coords = vector3(451.53, -923.32, 28.44), heading = 190.0, object = "prop_printer_02"},
-- Add more locations with coords and heading
}

View file

@ -0,0 +1,34 @@
fx_version 'cerulean'
games { 'gta5' }
lua54 'yes'
name 'Printer Script'
author 'PulseScripts'
version '1.0.4'
ui_page 'web/index.html'
shared_scripts {
'@ox_lib/init.lua',
'config.lua',
'locales/locale.lua'
}
client_scripts {
'client/main.lua',
'client/bridge/*'
}
server_scripts {
'@oxmysql/lib/MySQL.lua',
'server/main.lua',
'server/bridge/*'
}
dependencies {
'ox_lib',
}
files {
'web/index.html',
'locales/*.json'
}

View file

@ -0,0 +1,6 @@
CREATE TABLE printer (
id INT AUTO_INCREMENT PRIMARY KEY,
image_name VARCHAR(255) NOT NULL,
image_link VARCHAR(255) NOT NULL
);

View file

@ -0,0 +1,12 @@
["paper"] = {
label = "Paper",
weight = 1,
stack = false,
close = true,
consume = 0,
server = {
export = 'pl_printer.paper'
}
},

View file

@ -0,0 +1 @@
['paper'] = {['name'] = 'paper', ['label'] = 'Paper', ['weight'] = 10, ['type'] = 'item', ['image'] = 'paper.png', ['unique'] = true, ['useable'] = true, ['shouldClose'] = true, ['combinable'] = nil, ['description'] = 'A Photo Copy Print'},

Binary file not shown.

After

Width:  |  Height:  |  Size: 5 KiB

View file

@ -0,0 +1,9 @@
{
"image_link": "Bildlink",
"copies": "Kopien",
"image_url": "Bild-URL eingeben",
"enter_copies": "Anzahl der Kopien eingeben",
"prints": "Drucken",
"Money_Removed": "Geld vom Bankkonto entfernt: $",
"not_enough": "Nicht genug Geld"
}

View file

@ -0,0 +1,10 @@
{
"image_link": "Image Link",
"copies": "Copies",
"image_url": "Enter the Image URL",
"enter_copies": "Enter the number of copies",
"prints": "Prints",
"Money_Removed": "Money removed from bank: $",
"not_enough": "Not enough money"
}

View file

@ -0,0 +1,9 @@
{
"image_link": "Enlace de imagen",
"copies": "Copias",
"image_url": "Introduce la URL de la imagen",
"enter_copies": "Introduce el número de copias",
"prints": "Impresiones",
"Money_Removed": "Dinero retirado del banco: $",
"not_enough": "No hay suficiente dinero"
}

View file

@ -0,0 +1,9 @@
{
"image_link": "Lien de l'image",
"copies": "Copies",
"image_url": "Entrez l'URL de l'image",
"enter_copies": "Entrez le nombre de copies",
"prints": "Impressions",
"Money_Removed": "Argent retiré de la banque : $",
"not_enough": "Pas assez d'argent"
}

View file

@ -0,0 +1,9 @@
{
"image_link": "Link immagine",
"copies": "Copie",
"image_url": "Inserisci l'URL dell'immagine",
"enter_copies": "Inserisci il numero di copie",
"prints": "Stampe",
"Money_Removed": "Denaro rimosso dalla banca: $",
"not_enough": "Non abbastanza denaro"
}

View file

@ -0,0 +1,18 @@
Locales = {}
LocalLang = {}
function LoadLocale(lang)
local file = LoadResourceFile(GetCurrentResourceName(), 'locales/' .. lang .. '.json')
if file then
LocalLang = json.decode(file)
else
print('[Locale] Translation file not found for language: ' .. lang)
end
end
function Locale(key)
return LocalLang[key] or key
end
-- Load language
LoadLocale(Config.Locale)

View file

@ -0,0 +1,9 @@
{
"image_link": "Link da imagem",
"copies": "Cópias",
"image_url": "Digite a URL da imagem",
"enter_copies": "Digite o número de cópias",
"prints": "Impressões",
"Money_Removed": "Dinheiro removido do banco: $",
"not_enough": "Dinheiro insuficiente"
}

View file

@ -0,0 +1,9 @@
{
"image_link": "Görsel Bağlantısı",
"copies": "Kopya",
"image_url": "Görsel URL'sini girin",
"enter_copies": "Kopya sayısını girin",
"prints": "Baskılar",
"Money_Removed": "Bankadan para çekildi: $",
"not_enough": "Yetersiz bakiye"
}

View file

@ -0,0 +1,50 @@
local ESX = GetResourceState('es_extended'):find('start') and exports['es_extended']:getSharedObject() or nil
if not ESX then return end
function getPlayer(target)
local xPlayer = ESX.GetPlayerFromId(target)
return xPlayer
end
function RemovePlayerMoney(Player,account,TotalBill)
if account == 'bank' then
Player.removeAccountMoney('bank', TotalBill)
elseif account == 'money' then
Player.removeAccountMoney('money', TotalBill)
end
end
function GetPlayerAccountMoney(Player,account,TotalBill)
if account == 'bank' then
if Player.getAccount('bank').money >= TotalBill then
return true
else
return false
end
elseif account == 'money' then
if Player.getAccount('money').money >= TotalBill then
return true
else
return false
end
end
return false
end
function HasItem(playerSource)
if Config.CheckItem then
local xPlayer = ESX.GetPlayerFromId(playerSource)
if not xPlayer then return false end
local item = xPlayer.getInventoryItem(Config.ItemName)
if item and item.count >= 1 then
return true
else
return false
end
else
return true
end
end

View file

@ -0,0 +1,47 @@
local QBCore = GetResourceState('qb-core'):find('start') and exports['qb-core']:GetCoreObject() or nil
if not QBCore then return end
function getPlayer(target)
local Player = QBCore.Functions.GetPlayer(target)
return Player
end
function RemovePlayerMoney(Player,account,TotalBill)
if account == 'money' then
Player.Functions.RemoveMoney('cash', TotalBill)
elseif account == 'bank' then
Player.Functions.RemoveMoney('bank', TotalBill)
end
end
function GetPlayerAccountMoney(Player,account,TotalBill)
if account == 'bank' then
if Player.PlayerData.money.bank >= TotalBill then
return true
else
return false
end
elseif account == 'money' then
if Player.PlayerData.money.cash >= TotalBill then
return true
else
return false
end
end
return false
end
function HasItem(playerSource)
if Config.CheckItem then
return exports['qb-inventory']:HasItem(playerSource,Config.ItemName,1)
else
return true
end
end
QBCore.Functions.CreateUseableItem(Config.ItemName, function(source)
local Player = QBCore.Functions.GetPlayer(source)
local item = Player.Functions.GetItemByName(Config.ItemName)
TriggerEvent('pl_printer:fetchImageLink',item.info.id,Player.PlayerData.source)
end)

View file

@ -0,0 +1,98 @@
if GetResourceState('qb-core') == 'started' then
QBCore = exports['qb-core']:GetCoreObject()
elseif GetResourceState('es_extended') == 'started' then
ESX = exports['es_extended']:getSharedObject()
end
local resourceName = 'pl_printer'
lib.versionCheck('pulsepk/pl_printer')
RegisterServerEvent('pl_printer:insertImageData')
AddEventHandler('pl_printer:insertImageData', function(imageUrl, amount)
local Player = getPlayer(source)
local account = Config.Print.Account
local TotalBill = Config.Print.Price*amount
if GetPlayerAccountMoney(Player,account,TotalBill) then
local imageName = imageUrl:match(".*/(.*)$")
AddItem(source,amount, imageName)
if imageUrl and amount then
MySQL.Async.execute('INSERT INTO printer (image_name, image_link) VALUES (@image_name, @image_link)', {
['@image_name'] = tostring(imageName),
['@image_link'] = imageUrl
}, function(rowsChanged)
end)
RemovePlayerMoney(Player,account,TotalBill)
TriggerClientEvent('pl_printer:notification',source,Locale("Money_Removed") .. TotalBill,'success')
else
_debug('[DEBUG] '..' Invalid data received for image. '..'')
end
else
TriggerClientEvent('pl_printer:notification',source,Locale("not_enough"),'error')
end
end)
RegisterServerEvent('pl_printer:fetchImageLink')
AddEventHandler('pl_printer:fetchImageLink', function(imageName,playerSource)
local hasItem = HasItem(playerSource)
if not hasItem then return end
MySQL.Async.fetchScalar('SELECT image_link FROM printer WHERE image_name = @imageName', {
['@imageName'] = imageName
}, function(imageLink)
if imageLink then
TriggerClientEvent('pl_printer:showImage',playerSource,imageLink)
else
_debug('[DEBUG] '..' No Image Link Found for '..imageName..'')
end
end)
end)
function AddItem(source, amount, imageName)
local src = source
local info = {
id = imageName
}
if GetResourceState('qb-inventory') == 'started' then
if lib.checkDependency('qb-inventory', '2.0.0') then
exports['qb-inventory']:AddItem(src,Config.ItemName,amount,false,info)
TriggerClientEvent('qb-inventory:client:ItemBox', src, QBCore.Shared.Items[Config.ItemName], 'add', amount)
else
local Player = getPlayer(src)
Player.Functions.AddItem(Config.ItemName, amount,false, info)
TriggerClientEvent('inventory:client:ItemBox', src, QBCore.Shared.Items[Config.ItemName], "add")
end
elseif GetResourceState('ox_inventory') == 'started' then
exports.ox_inventory:AddItem(src,Config.ItemName,amount,imageName,false)
elseif GetResourceState('qs-inventory') == 'started' then
local itemMetadata ={ id = imageName }
exports['qs-inventory']:AddItem(src,Config.ItemName,amount,false,itemMetadata)
end
end
AddEventHandler('onServerResourceStart', function()
if GetResourceState('ox_inventory') == 'started' then
exports(Config.ItemName,function (event,item,inventory,slot,data)
if event == 'usingItem' then
local item_metadata = exports.ox_inventory:GetSlot(inventory.id, slot)
TriggerEvent('pl_printer:fetchImageLink', item_metadata.metadata.type, inventory.id)
end
end)
end
end)
local WaterMark = function()
SetTimeout(1500, function()
print('^1['..resourceName..'] ^2Thank you for Downloading the Script^0')
print('^1['..resourceName..'] ^2If you encounter any issues please Join the discord https://discord.gg/c6gXmtEf3H to get support..^0')
print('^1['..resourceName..'] ^2Enjoy a secret 20% OFF any script of your choice on https://pulsescripts.tebex.io/freescript^0')
print('^1['..resourceName..'] ^2Using the coupon code: SPECIAL20 (one-time use coupon, choose wisely)^0')
end)
end
WaterMark()

View file

@ -0,0 +1,48 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<title></title>
<style>
body {
margin: 0;
padding: 0;
overflow: hidden;
}
#image {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
max-width: 90%;
max-height: 90%;
}
</style>
</head>
<body>
<img id="image" src="" alt="Image" style="display:none;">
<script>
window.addEventListener('message', function(event) {
if (event.data.action === 'show') {
document.getElementById('image').src = event.data.imageUrl;
document.getElementById('image').style.display = 'block';
} else if (event.data.action === 'hide') {
document.getElementById('image').style.display = 'none';
}
});
document.addEventListener("keydown", function(event) {
if (event.key === "Escape") {
document.getElementById('image').style.display = 'none';
axios.post(`https://${GetParentResourceName()}/hideFrame`, {})
.then(function (response) {
})
.catch(function (error) {
});
}
});
</script>
</body>
</html>