diff --git a/resources/[inventory]/omi-printers/README.md b/resources/[inventory]/omi-printers/README.md
deleted file mode 100644
index 4205cbe8e..000000000
--- a/resources/[inventory]/omi-printers/README.md
+++ /dev/null
@@ -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.
-
-
-
-
-
-
-
diff --git a/resources/[inventory]/omi-printers/client/cl_main.lua b/resources/[inventory]/omi-printers/client/cl_main.lua
deleted file mode 100644
index 7fdfdf28b..000000000
--- a/resources/[inventory]/omi-printers/client/cl_main.lua
+++ /dev/null
@@ -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)
diff --git a/resources/[inventory]/omi-printers/config.lua b/resources/[inventory]/omi-printers/config.lua
deleted file mode 100644
index a21653f78..000000000
--- a/resources/[inventory]/omi-printers/config.lua
+++ /dev/null
@@ -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)
- },
-}
\ No newline at end of file
diff --git a/resources/[inventory]/omi-printers/fxmanifest.lua b/resources/[inventory]/omi-printers/fxmanifest.lua
deleted file mode 100644
index f47fe3711..000000000
--- a/resources/[inventory]/omi-printers/fxmanifest.lua
+++ /dev/null
@@ -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'
diff --git a/resources/[inventory]/omi-printers/html/app.js b/resources/[inventory]/omi-printers/html/app.js
deleted file mode 100644
index b5270ab54..000000000
--- a/resources/[inventory]/omi-printers/html/app.js
+++ /dev/null
@@ -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');
-}
\ No newline at end of file
diff --git a/resources/[inventory]/omi-printers/html/index.html b/resources/[inventory]/omi-printers/html/index.html
deleted file mode 100644
index 50bb1924f..000000000
--- a/resources/[inventory]/omi-printers/html/index.html
+++ /dev/null
@@ -1,34 +0,0 @@
-
-
-
-
-
-
- Printer For QB CORE Made by Omi
-
-
-
-
-
-
-
-
-
![]()
-
-
-
-
-
-
- Print 📄
-
-
-
- Cancel ✖
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/resources/[inventory]/omi-printers/html/style.css b/resources/[inventory]/omi-printers/html/style.css
deleted file mode 100644
index 39d47064d..000000000
--- a/resources/[inventory]/omi-printers/html/style.css
+++ /dev/null
@@ -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;
-}
\ No newline at end of file
diff --git a/resources/[inventory]/omi-printers/server/server.lua b/resources/[inventory]/omi-printers/server/server.lua
deleted file mode 100644
index a1d5831de..000000000
--- a/resources/[inventory]/omi-printers/server/server.lua
+++ /dev/null
@@ -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)
\ No newline at end of file
diff --git a/resources/[inventory]/omi-printers/shared/shared.lua b/resources/[inventory]/omi-printers/shared/shared.lua
deleted file mode 100644
index 5f20f7fab..000000000
--- a/resources/[inventory]/omi-printers/shared/shared.lua
+++ /dev/null
@@ -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
\ No newline at end of file
diff --git a/resources/[inventory]/pl_printer/.github/FUNDING.yml b/resources/[inventory]/pl_printer/.github/FUNDING.yml
new file mode 100644
index 000000000..5a84db9da
--- /dev/null
+++ b/resources/[inventory]/pl_printer/.github/FUNDING.yml
@@ -0,0 +1,6 @@
+github: #
+patreon: #
+open_collective: #
+ko_fi: #
+buy_me_a_coffee: pulsepk
+custom: ["https://pulsescripts.tebex.io/"]
\ No newline at end of file
diff --git a/resources/[inventory]/pl_printer/.github/workflows/release.yml b/resources/[inventory]/pl_printer/.github/workflows/release.yml
new file mode 100644
index 000000000..2c9a296b1
--- /dev/null
+++ b/resources/[inventory]/pl_printer/.github/workflows/release.yml
@@ -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 }}
\ No newline at end of file
diff --git a/resources/[inventory]/pl_printer/ReadMe.md b/resources/[inventory]/pl_printer/ReadMe.md
new file mode 100644
index 000000000..0c6fac608
--- /dev/null
+++ b/resources/[inventory]/pl_printer/ReadMe.md
@@ -0,0 +1,35 @@
+# Pulse Printer | ESX, QBCore, QBox
+
+##
+
+
+##
+![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)
+##
\ No newline at end of file
diff --git a/resources/[inventory]/pl_printer/client/bridge/esx.lua b/resources/[inventory]/pl_printer/client/bridge/esx.lua
new file mode 100644
index 000000000..a898d9ea9
--- /dev/null
+++ b/resources/[inventory]/pl_printer/client/bridge/esx.lua
@@ -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)
diff --git a/resources/[inventory]/pl_printer/client/bridge/qb.lua b/resources/[inventory]/pl_printer/client/bridge/qb.lua
new file mode 100644
index 000000000..5e4aab243
--- /dev/null
+++ b/resources/[inventory]/pl_printer/client/bridge/qb.lua
@@ -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)
\ No newline at end of file
diff --git a/resources/[inventory]/pl_printer/client/main.lua b/resources/[inventory]/pl_printer/client/main.lua
new file mode 100644
index 000000000..d770667c0
--- /dev/null
+++ b/resources/[inventory]/pl_printer/client/main.lua
@@ -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
\ No newline at end of file
diff --git a/resources/[inventory]/pl_printer/config.lua b/resources/[inventory]/pl_printer/config.lua
new file mode 100644
index 000000000..b008fb22f
--- /dev/null
+++ b/resources/[inventory]/pl_printer/config.lua
@@ -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
+}
+
diff --git a/resources/[inventory]/pl_printer/fxmanifest.lua b/resources/[inventory]/pl_printer/fxmanifest.lua
new file mode 100644
index 000000000..fd3c47d00
--- /dev/null
+++ b/resources/[inventory]/pl_printer/fxmanifest.lua
@@ -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'
+}
diff --git a/resources/[inventory]/pl_printer/installfolder/database.sql b/resources/[inventory]/pl_printer/installfolder/database.sql
new file mode 100644
index 000000000..e063d611c
--- /dev/null
+++ b/resources/[inventory]/pl_printer/installfolder/database.sql
@@ -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
+);
+
diff --git a/resources/[inventory]/pl_printer/installfolder/items_Oxinventory.lua b/resources/[inventory]/pl_printer/installfolder/items_Oxinventory.lua
new file mode 100644
index 000000000..d22278d19
--- /dev/null
+++ b/resources/[inventory]/pl_printer/installfolder/items_Oxinventory.lua
@@ -0,0 +1,12 @@
+
+
+["paper"] = {
+ label = "Paper",
+ weight = 1,
+ stack = false,
+ close = true,
+ consume = 0,
+ server = {
+ export = 'pl_printer.paper'
+ }
+},
\ No newline at end of file
diff --git a/resources/[inventory]/pl_printer/installfolder/items_QBCore.lua b/resources/[inventory]/pl_printer/installfolder/items_QBCore.lua
new file mode 100644
index 000000000..d865b78ba
--- /dev/null
+++ b/resources/[inventory]/pl_printer/installfolder/items_QBCore.lua
@@ -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'},
\ No newline at end of file
diff --git a/resources/[inventory]/pl_printer/installfolder/paper.png b/resources/[inventory]/pl_printer/installfolder/paper.png
new file mode 100644
index 000000000..7d19a2a25
Binary files /dev/null and b/resources/[inventory]/pl_printer/installfolder/paper.png differ
diff --git a/resources/[inventory]/pl_printer/locales/de.json b/resources/[inventory]/pl_printer/locales/de.json
new file mode 100644
index 000000000..da5316076
--- /dev/null
+++ b/resources/[inventory]/pl_printer/locales/de.json
@@ -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"
+ }
\ No newline at end of file
diff --git a/resources/[inventory]/pl_printer/locales/en.json b/resources/[inventory]/pl_printer/locales/en.json
new file mode 100644
index 000000000..bae069b2f
--- /dev/null
+++ b/resources/[inventory]/pl_printer/locales/en.json
@@ -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"
+
+}
\ No newline at end of file
diff --git a/resources/[inventory]/pl_printer/locales/es.json b/resources/[inventory]/pl_printer/locales/es.json
new file mode 100644
index 000000000..0745e1699
--- /dev/null
+++ b/resources/[inventory]/pl_printer/locales/es.json
@@ -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"
+ }
\ No newline at end of file
diff --git a/resources/[inventory]/pl_printer/locales/fr.json b/resources/[inventory]/pl_printer/locales/fr.json
new file mode 100644
index 000000000..45650742d
--- /dev/null
+++ b/resources/[inventory]/pl_printer/locales/fr.json
@@ -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"
+ }
\ No newline at end of file
diff --git a/resources/[inventory]/pl_printer/locales/it.json b/resources/[inventory]/pl_printer/locales/it.json
new file mode 100644
index 000000000..0c7aa68a4
--- /dev/null
+++ b/resources/[inventory]/pl_printer/locales/it.json
@@ -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"
+ }
\ No newline at end of file
diff --git a/resources/[inventory]/pl_printer/locales/locale.lua b/resources/[inventory]/pl_printer/locales/locale.lua
new file mode 100644
index 000000000..1d9b2daba
--- /dev/null
+++ b/resources/[inventory]/pl_printer/locales/locale.lua
@@ -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)
\ No newline at end of file
diff --git a/resources/[inventory]/pl_printer/locales/pt.json b/resources/[inventory]/pl_printer/locales/pt.json
new file mode 100644
index 000000000..137d80c7f
--- /dev/null
+++ b/resources/[inventory]/pl_printer/locales/pt.json
@@ -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"
+ }
\ No newline at end of file
diff --git a/resources/[inventory]/pl_printer/locales/tr.json b/resources/[inventory]/pl_printer/locales/tr.json
new file mode 100644
index 000000000..784545c3a
--- /dev/null
+++ b/resources/[inventory]/pl_printer/locales/tr.json
@@ -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"
+ }
\ No newline at end of file
diff --git a/resources/[inventory]/pl_printer/server/bridge/esx.lua b/resources/[inventory]/pl_printer/server/bridge/esx.lua
new file mode 100644
index 000000000..110ddb1b9
--- /dev/null
+++ b/resources/[inventory]/pl_printer/server/bridge/esx.lua
@@ -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
+
diff --git a/resources/[inventory]/pl_printer/server/bridge/qb.lua b/resources/[inventory]/pl_printer/server/bridge/qb.lua
new file mode 100644
index 000000000..df345c42c
--- /dev/null
+++ b/resources/[inventory]/pl_printer/server/bridge/qb.lua
@@ -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)
diff --git a/resources/[inventory]/pl_printer/server/main.lua b/resources/[inventory]/pl_printer/server/main.lua
new file mode 100644
index 000000000..06ba45d71
--- /dev/null
+++ b/resources/[inventory]/pl_printer/server/main.lua
@@ -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()
+
+
+
+
+
diff --git a/resources/[inventory]/pl_printer/web/index.html b/resources/[inventory]/pl_printer/web/index.html
new file mode 100644
index 000000000..ad8931e32
--- /dev/null
+++ b/resources/[inventory]/pl_printer/web/index.html
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+