From bf5bfd1ff80e1262970f2c73e028744eac2a7975 Mon Sep 17 00:00:00 2001 From: Achim <39227403+Achim-Sommer@users.noreply.github.com> Date: Sun, 9 Jul 2023 19:48:05 +0200 Subject: [PATCH] Neue Spielmechanik - Carplay /carplay im Auto --- [extras]/nass_carplay/README.md | 24 ++ [extras]/nass_carplay/client/client.lua | 337 +++++++++++++++ [extras]/nass_carplay/fxmanifest.lua | 21 + .../nass_carplay/html/SFUIText-Regular.otf | Bin 0 -> 141316 bytes .../html/applecarplaytemplate.png | Bin 0 -> 61484 bytes [extras]/nass_carplay/html/index.html | 77 ++++ [extras]/nass_carplay/html/script.js | 349 ++++++++++++++++ [extras]/nass_carplay/html/style.css | 389 ++++++++++++++++++ [extras]/nass_carplay/server/server.lua | 13 + [extras]/s1lent_keybinds/config.lua | 3 +- .../.github/ISSUE_TEMPLATE/bug_report.md | 27 ++ .../.github/ISSUE_TEMPLATE/feature_request.md | 20 + .../xsound/addon/crewphone/client/client.lua | 186 +++++++++ .../xsound/addon/crewphone/server/server.lua | 26 ++ [extras]/xsound/addon/readme.md | 14 + [extras]/xsound/client/commands.lua | 16 + [extras]/xsound/client/effects/main.lua | 69 ++++ .../client/emulator/interact_sound/client.lua | 22 + [extras]/xsound/client/events.lua | 150 +++++++ [extras]/xsound/client/exports/events.lua | 33 ++ [extras]/xsound/client/exports/info.lua | 94 +++++ .../xsound/client/exports/manipulation.lua | 165 ++++++++ [extras]/xsound/client/exports/play.lua | 143 +++++++ [extras]/xsound/client/main.lua | 150 +++++++ [extras]/xsound/config.lua | 27 ++ [extras]/xsound/fxmanifest.lua | 44 ++ [extras]/xsound/html/index.html | 15 + [extras]/xsound/html/scripts/SoundPlayer.js | 329 +++++++++++++++ [extras]/xsound/html/scripts/functions.js | 160 +++++++ [extras]/xsound/html/scripts/listener.js | 269 ++++++++++++ [extras]/xsound/html/sounds/.gitkeep | 0 [extras]/xsound/license.txt | 21 + [extras]/xsound/readme.md | 197 +++++++++ .../server/emulator/interact_sound/server.lua | 19 + .../xsound/server/exports/manipulation.lua | 68 +++ [extras]/xsound/server/exports/play.lua | 47 +++ credits.md | 4 +- 37 files changed, 3526 insertions(+), 2 deletions(-) create mode 100644 [extras]/nass_carplay/README.md create mode 100644 [extras]/nass_carplay/client/client.lua create mode 100644 [extras]/nass_carplay/fxmanifest.lua create mode 100644 [extras]/nass_carplay/html/SFUIText-Regular.otf create mode 100644 [extras]/nass_carplay/html/applecarplaytemplate.png create mode 100644 [extras]/nass_carplay/html/index.html create mode 100644 [extras]/nass_carplay/html/script.js create mode 100644 [extras]/nass_carplay/html/style.css create mode 100644 [extras]/nass_carplay/server/server.lua create mode 100644 [extras]/xsound/.github/ISSUE_TEMPLATE/bug_report.md create mode 100644 [extras]/xsound/.github/ISSUE_TEMPLATE/feature_request.md create mode 100644 [extras]/xsound/addon/crewphone/client/client.lua create mode 100644 [extras]/xsound/addon/crewphone/server/server.lua create mode 100644 [extras]/xsound/addon/readme.md create mode 100644 [extras]/xsound/client/commands.lua create mode 100644 [extras]/xsound/client/effects/main.lua create mode 100644 [extras]/xsound/client/emulator/interact_sound/client.lua create mode 100644 [extras]/xsound/client/events.lua create mode 100644 [extras]/xsound/client/exports/events.lua create mode 100644 [extras]/xsound/client/exports/info.lua create mode 100644 [extras]/xsound/client/exports/manipulation.lua create mode 100644 [extras]/xsound/client/exports/play.lua create mode 100644 [extras]/xsound/client/main.lua create mode 100644 [extras]/xsound/config.lua create mode 100644 [extras]/xsound/fxmanifest.lua create mode 100644 [extras]/xsound/html/index.html create mode 100644 [extras]/xsound/html/scripts/SoundPlayer.js create mode 100644 [extras]/xsound/html/scripts/functions.js create mode 100644 [extras]/xsound/html/scripts/listener.js create mode 100644 [extras]/xsound/html/sounds/.gitkeep create mode 100644 [extras]/xsound/license.txt create mode 100644 [extras]/xsound/readme.md create mode 100644 [extras]/xsound/server/emulator/interact_sound/server.lua create mode 100644 [extras]/xsound/server/exports/manipulation.lua create mode 100644 [extras]/xsound/server/exports/play.lua diff --git a/[extras]/nass_carplay/README.md b/[extras]/nass_carplay/README.md new file mode 100644 index 0000000..6a731b1 --- /dev/null +++ b/[extras]/nass_carplay/README.md @@ -0,0 +1,24 @@ +# nass_carplay + +## Features + +- Carplay style UI +- Saves data via state bags to the vehicle +- Synced to all players in the car +- Music queue system +- Highly optimized (0.00-0.02) +- Automatically works with my [notification system](https://forum.cfx.re/t/paid-standalone-nass-notification-system/5077964) + +## Dependency + +- Onesync (uses state bags) +- [xsound](https://github.com/Xogy/xsound) + + +## Extra Information + + + Please leave any issues you may have here on github + +# Support +Join our discord HERE for additional scripts and support! diff --git a/[extras]/nass_carplay/client/client.lua b/[extras]/nass_carplay/client/client.lua new file mode 100644 index 0000000..373804c --- /dev/null +++ b/[extras]/nass_carplay/client/client.lua @@ -0,0 +1,337 @@ +-----------------For support, scripts, and more---------------- +--------------- https://discord.gg/fz655NHeDq ------------- +--------------------------------------------------------------- +local spawnedSounds = {} + +RegisterCommand('carplay', function() + local vehicle = GetVehiclePedIsIn(PlayerPedId(), false) + if vehicle ~= 0 then + SendNUIMessage({ + event = "openCarPlay", + veh = VehToNet(vehicle), + vehIdStr = tostring(VehToNet(vehicle)), + queue = Entity(vehicle).state.queue + }) + SetNuiFocus(true, true) + else + ESX.ShowNotification("Must be in a vehicle") + end +end) + +RegisterNUICallback('closeCarPlay', function(cd) + SetNuiFocus(false, false) +end) + +function vehicleEntered(veh) + if Entity(veh).state then + local currQueue = Entity(veh).state.queue + if currQueue ~= nil then + local data = currQueue[Entity(veh).state.queuePos] + local currTime = Entity(veh).state.currTime + if data ~= nil then + + if exports.xsound:soundExists("nass_carplay_"..data.vehStr) then + exports.xsound:Destroy("nass_carplay_"..data.vehStr) + end + local volume = 1.0 + local SavedVol = Entity(NetToVeh(data.veh)).state.volume + if SavedVol ~= nil then + volume = SavedVol + end + exports.xsound:PlayUrl("nass_carplay_"..data.vehStr, data.link, volume, false, { + onPlayStart = function(event) + table.insert(spawnedSounds, NetToVeh(data.veh)) + SendNUIMessage({ + event = "playbackStarted", + link = data.link, + vol = exports.xsound:getVolume("nass_carplay_"..data.vehStr) + }) + + exports.xsound:setTimeStamp("nass_carplay_"..data.vehStr, math.floor(currTime)) + if Entity(veh).state.isPaused then + exports.xsound:Pause("nass_carplay_"..data.vehStr) + SendNUIMessage({ + event = "setPicPaused", + }) + end + local totalDurr = exports.xsound:getMaxDuration("nass_carplay_"..data.vehStr) + CreateThread(function() + while true do + Wait(999) + + if totalDurr == 0 then + totalDurr = exports.xsound:getMaxDuration("nass_carplay_"..data.vehStr) + end + + if not exports.xsound:soundExists("nass_carplay_"..data.vehStr) then + break + end + + local currTime = exports.xsound:getTimeStamp("nass_carplay_"..data.vehStr) + Entity(NetToVeh(data.veh)).state:set('currTime', currTime, true) + + if currTime+1 == totalDurr then + TriggerEvent("nass_carplay:playsound", {event = "nextSong", veh =data.veh, vehStr = data.vehStr}) + shouldBreak = true + end + + SendNUIMessage({ + event = "updateTime", + time = {currentTime = currTime, totalDuration = totalDurr} + }) + + if GetVehiclePedIsIn(PlayerPedId(), false) == 0 then + SendNUIMessage({event = "resetPlayback"}) + exports.xsound:Destroy("nass_carplay_"..data.vehStr) + shouldBreak = true + end + + if shouldBreak then + SendNUIMessage({ + event = "updateTime", + time = {currentTime = 0, totalDuration = 0} + }) + shouldBreak = false + break + end + Wait(1) + end + end) + end + }) + + print("data found") + + end + end + end +end + +RegisterNetEvent('nass_carplay:playsound') +AddEventHandler("nass_carplay:playsound", function(data) + if data.event == "url" then + if data.shouldForce then + shouldBreak = true + Wait(10) + shouldBreak = false + end + + if not data.shouldForce and exports.xsound:soundExists("nass_carplay_"..data.vehStr) then + local currQueue = Entity(NetToVeh(data.veh)).state.queue + if currQueue == nil then + currQueue = {} + end + data.queuePos = #currQueue+1 + table.insert(currQueue, data) + Entity(NetToVeh(data.veh)).state:set('queue', currQueue, true) + else + + if data.queuePos then + Entity(NetToVeh(data.veh)).state:set('queuePos', data.queuePos, true) + end + + local currQueue = Entity(NetToVeh(data.veh)).state.queue + if currQueue == nil then + local queue = {} + if data.queuePos == nil then + data.queuePos = 1 + end + table.insert(queue, data) + Entity(NetToVeh(data.veh)).state:set('queue', queue, true) + end + + if exports.xsound:soundExists("nass_carplay_"..data.vehStr) then + exports.xsound:Destroy("nass_carplay_"..data.vehStr) + end + local volume = 1.0 + local SavedVol = Entity(NetToVeh(data.veh)).state.volume + if SavedVol ~= nil then + volume = SavedVol + end + exports.xsound:PlayUrl("nass_carplay_"..data.vehStr, data.link, volume, false, { + onPlayStart = function(event) + table.insert(spawnedSounds, NetToVeh(data.veh)) + SendNUIMessage({ + event = "playbackStarted", + link = data.link, + vol = exports.xsound:getVolume("nass_carplay_"..data.vehStr) + }) + + local totalDurr = exports.xsound:getMaxDuration("nass_carplay_"..data.vehStr) + + CreateThread(function() + while true do + Wait(999) + if totalDurr == 0 then + totalDurr = exports.xsound:getMaxDuration("nass_carplay_"..data.vehStr) + end + + if not exports.xsound:soundExists("nass_carplay_"..data.vehStr) then + break + end + + local currTime = exports.xsound:getTimeStamp("nass_carplay_"..data.vehStr) + Entity(NetToVeh(data.veh)).state:set('currTime', currTime, true) + + if currTime+1 == totalDurr then + TriggerEvent("nass_carplay:playsound", {event = "nextSong", veh = data.veh, vehStr = data.vehStr}) + shouldBreak = true + end + + SendNUIMessage({ + event = "updateTime", + time = {currentTime = currTime, totalDuration = totalDurr} + }) + + if GetVehiclePedIsIn(PlayerPedId(), false) == 0 then + SendNUIMessage({event = "resetPlayback"}) + exports.xsound:Destroy("nass_carplay_"..data.vehStr) + shouldBreak = true + end + + if shouldBreak then + SendNUIMessage({ + event = "updateTime", + time = {currentTime = 0, totalDuration = 0} + }) + shouldBreak = false + break + end + Wait(1) + end + end) + end, + onPlayEnd = function(event) + shouldBreak = true + end, + }) + end + elseif data.event == "resume" then + if not exports.xsound:soundExists("nass_carplay_"..data.vehStr) then return end + + exports.xsound:Resume("nass_carplay_"..data.vehStr) + Entity(NetToVeh(data.veh)).state:set('isPaused', false, true) + elseif data.event == "pause" then + if not exports.xsound:soundExists("nass_carplay_"..data.vehStr) then return end + + exports.xsound:Pause("nass_carplay_"..data.vehStr) + Entity(NetToVeh(data.veh)).state:set('isPaused', true, true) + elseif data.event == "resetPlayback" then + exports.xsound:Destroy("nass_carplay_"..data.vehStr) + elseif data.event == "setVolume" then + if not exports.xsound:soundExists("nass_carplay_"..data.vehStr) then return end + + local newVol = math.floor(data.vol)/100 + exports.xsound:setVolume("nass_carplay_"..data.vehStr, newVol) + Entity(NetToVeh(data.veh)).state:set('volume', newVol, true) + elseif data.event == "breakLoop" then + shouldBreak = true + elseif data.event == "selectTime" then + if not exports.xsound:soundExists("nass_carplay_"..data.vehStr) then return end + + exports.xsound:setTimeStamp("nass_carplay_"..data.vehStr, math.floor(data.newTime)) + Wait(50) + elseif data.event == "restartSong" then + if not exports.xsound:soundExists("nass_carplay_"..data.vehStr) then return end + + exports.xsound:setTimeStamp("nass_carplay_"..data.vehStr, math.floor(0)) + elseif data.event == "nextSong" then + if not exports.xsound:soundExists("nass_carplay_"..data.vehStr) then return end + local currQueue = Entity(NetToVeh(data.veh)).state.queue + local currQueuePos = Entity(NetToVeh(data.veh)).state.queuePos + if currQueuePos == nil then + if exports.xsound:soundExists("nass_carplay_"..data.vehStr) then + exports.xsound:Destroy("nass_carplay_"..data.vehStr) + end + SendNUIMessage({ + event = "updateTime", + time = {currentTime = 0, totalDuration = 0} + }) + SendNUIMessage({event = "resetPlayback"}) + shouldBreak = true + return + end + local dat = currQueue[currQueuePos+1] + if dat ~= nil then + dat.shouldForce = true + Wait(1) + if exports.xsound:soundExists("nass_carplay_"..data.vehStr) then + exports.xsound:Destroy("nass_carplay_"..data.vehStr) + end + Wait(1) + + local peds = getPeds(NetToVeh(data.veh)) + TriggerServerEvent("nass_carplay:syncmusic", peds, data.veh, dat) + else + SendNUIMessage({ + event = "updateTime", + time = {currentTime = 0, totalDuration = 0} + }) + SendNUIMessage({event = "resetPlayback"}) + end + end +end) + +RegisterNUICallback('callback', function(data) + if data.veh ~= nil then + if data.event == "url" or data.event == "forceurl" then + if data.event == "forceurl" then + data.event = "url" + data.shouldForce = true + end + Entity(NetToVeh(data.veh)).state:set('data', data, true) + end + local peds = getPeds(NetToVeh(data.veh)) + TriggerServerEvent("nass_carplay:syncmusic", peds, data.veh, data) + end +end) + +function getPeds(veh) + local peds = {} + for i = -1, (GetVehicleMaxNumberOfPassengers(veh)-1), 1 do + local ped = GetPedInVehicleSeat(veh, i) + if ped ~= 0 then + table.insert(peds, GetPlayerServerId(NetworkGetPlayerIndexFromPed(ped))) + end + end + return peds +end + +AddEventHandler('onResourceStop', function(resourceName) + if (GetCurrentResourceName() ~= resourceName) then + return + end + + for k,v in pairs(spawnedSounds) do + Entity(v).state:set('data', nil, true) + Entity(v).state:set('currTime', nil, true) + Entity(v).state:set('queue', nil, true) + Entity(v).state:set('queuePos', 1, true) + Entity(v).state:set('isPaused', 1, false) + if exports.xsound:soundExists("nass_carplay_"..v) then + exports.xsound:Destroy("nass_carplay_"..v) + print("Destorying") + end + + end +end) + +Citizen.CreateThread(function() + local doAction = false + while true do + Wait(300) + local ped = PlayerPedId() + + if IsPedInAnyVehicle(ped, false) then + local veh = GetVehiclePedIsIn(ped, false) + if not doAction then + doAction = true + vehicleEntered(veh) + end + else + if doAction then + doAction = false + end + end + end +end) diff --git a/[extras]/nass_carplay/fxmanifest.lua b/[extras]/nass_carplay/fxmanifest.lua new file mode 100644 index 0000000..9d904b0 --- /dev/null +++ b/[extras]/nass_carplay/fxmanifest.lua @@ -0,0 +1,21 @@ +fx_version 'cerulean' +use_experimental_fxv2_oal 'yes' +game 'gta5' +lua54 'yes' + +description 'nass_carplay' +author 'Nass#1411' +version '1.1.0' + +server_scripts { 'server/*.lua' } + +client_scripts { 'client/*.lua' } + +ui_page 'html/index.html' +files { + "html/*", +} + +dependencies { + 'xsound', +} diff --git a/[extras]/nass_carplay/html/SFUIText-Regular.otf b/[extras]/nass_carplay/html/SFUIText-Regular.otf new file mode 100644 index 0000000000000000000000000000000000000000..b2aa38852778862c5aa2f6f490f85938bddc6967 GIT binary patch literal 141316 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

cN8G8* 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 literal 0 HcmV?d00001 diff --git a/[extras]/nass_carplay/html/applecarplaytemplate.png b/[extras]/nass_carplay/html/applecarplaytemplate.png new file mode 100644 index 0000000000000000000000000000000000000000..570feb909fc0cf7d3141ddbbcdfc2f3cb5531b4b GIT binary patch literal 61484 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 D+`ec* literal 0 HcmV?d00001 diff --git a/[extras]/nass_carplay/html/index.html b/[extras]/nass_carplay/html/index.html new file mode 100644 index 0000000..22d4552 --- /dev/null +++ b/[extras]/nass_carplay/html/index.html @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + +

+ + + \ No newline at end of file diff --git a/[extras]/nass_carplay/html/script.js b/[extras]/nass_carplay/html/script.js new file mode 100644 index 0000000..815c3c1 --- /dev/null +++ b/[extras]/nass_carplay/html/script.js @@ -0,0 +1,349 @@ +var vehId = null; +var vehIdStr = null; +var songTotal = 0; +document.addEventListener('DOMContentLoaded', () => { + window.addEventListener('message', function(event) { + var item = event.data; + if (item.event == "openCarPlay") { + vehId = item.veh; + vehIdStr = item.vehIdStr; + + if(item.queue != null){ + var songList = document.querySelector(".nextcontainer .song-list"); + item.queue.forEach(function(item) { + var songListItem = document.createElement("li"); + songListItem.textContent = item.songName + songList.appendChild(songListItem); + + + songListItem.addEventListener("click", function() { + $.post(`https://${GetParentResourceName()}/callback`, JSON.stringify({ + event: 'forceurl', + veh: vehId, + vehStr: vehIdStr, + link: item.link, + queuePos: Array.from(songList.children).indexOf(songListItem)+1, + songName: item.songName + })); + }); + }); + } + + + const mainContainer = document.getElementById('maincontainer'); + mainContainer.style.display = 'block'; + mainContainer.style.opacity = '0'; + mainContainer.style.transform = 'scale(0.8)'; + mainContainer.style.transition = 'none'; + setTimeout(() => { + mainContainer.style.transition = 'all 0.5s ease-in-out'; + mainContainer.style.opacity = '1'; + mainContainer.style.transform = 'scale(1)'; + }, 100); + }else if(item.event == "playbackStarted"){ + $.getJSON('https://noembed.com/embed?url=', {format: 'json', url: item.link}, function (data) { + var songNameElement = document.getElementById("songname"); + songNameElement.textContent = data.title; + + var authorElement = document.getElementById("author"); + authorElement.textContent = "by " + data.author_name; + + document.getElementById('musicthumbanil').src = data.thumbnail_url; + + }); + + document.querySelector('.volume-pill').style.height = `${(item.vol*100)}%`; + + }else if(item.event == "updateTime"){ + if(songTotal != item.time.totalDuration){ + songTotal = item.time.totalDuration; + } + updateMusicProg(item.time.currentTime, item.time.totalDuration) + }else if(item.event == "resetPlayback"){ + resetPlayback(); + }else if(item.event == "nextSong") { + nextSong(); + }else if(item.event == "setPicPaused"){ + $('.btn3').addClass('btn').removeClass('btn3').html(''); + } + }); +}); + +$(document).keyup(function(event) { + if (event.which == 27) { + closeMenu() + return + } +}); + +document.addEventListener('DOMContentLoaded', () => { + //Back Button + const backButton = document.querySelector('.backcont button'); + backButton.addEventListener('click', () => { + closeMenu(); + }); + + //Music Selector + const form = document.querySelector('.song-form'); + form.addEventListener('submit', (event) => { + event.preventDefault(); + + const songInput = document.querySelector('.song-input'); + const songLink = songInput.value; + + $.getJSON('https://noembed.com/embed', {format: 'json', url: songLink}, function (data) { + var songListItem = document.createElement("li"); + songListItem.textContent = data.title + " by " + data.author_name; + + var songList = document.querySelector(".nextcontainer .song-list"); + songList.appendChild(songListItem); + var isSwitching = false; + var switchingTime = 1000; + + + songListItem.addEventListener("click", function() { + if (isSwitching) return; + isSwitching = true; + $.post(`https://${GetParentResourceName()}/callback`, JSON.stringify({ + event: 'breakLoop', + vehStr: vehIdStr, + veh: vehId, + })); + setTimeout(function() { + isSwitching = false; + }, switchingTime); + $.post(`https://${GetParentResourceName()}/callback`, JSON.stringify({ + event: 'forceurl', + veh: vehId, + vehStr: vehIdStr, + queuePos: Array.from(songList.children).indexOf(songListItem)+1, + link: songLink, + songName: data.title + " by " + data.author_name, + + })); + }); + $.post(`https://${GetParentResourceName()}/callback`, JSON.stringify({ + event: 'url', + veh: vehId, + vehStr: vehIdStr, + link: songLink, + queuePos: Array.from(songList.children).indexOf(songListItem)+1, + songName: data.title + " by " + data.author_name, + })); + + }); + songInput.value = ''; + }); + + //Volume + const volumePill = document.querySelector('.volume-pill'); + const volumePillBar = document.querySelector('.volume-pill-bar'); + + function setVolume(event) { + const boundingRect = volumePillBar.getBoundingClientRect(); + const mouseY = boundingRect.bottom - event.clientY; + const volume = (mouseY / boundingRect.height) * 100; + volumePill.style.height = `${volume}%`; + volumePill.style.bottom = `0%`; + + $.post(`https://${GetParentResourceName()}/callback`, JSON.stringify({ + event: 'setVolume', + veh: vehId, + vehStr: vehIdStr, + vol: volume, + })); + } + + volumePillBar.addEventListener('click', setVolume); + + const volumenbtn = document.querySelector('.volumenbtn'); + const volumebtnmute = document.querySelector('.volumebtnmute'); + const volumeIcon = document.querySelector('.volumebtns i'); + const volumeBtns = document.querySelector('.volumebtns'); + + volumenbtn.addEventListener('click', function() { + if (this.classList.contains('volumenbtn')) { + this.classList.remove('volumenbtn'); + this.classList.add('volumebtnmute'); + volumeIcon.classList.remove('fa-volume-up'); + volumeIcon.classList.add('fa-volume-off'); + + volumePill.style.height = `${0}%`; + $.post(`https://${GetParentResourceName()}/callback`, JSON.stringify({ + event: 'setVolume', + veh: vehId, + vehStr: vehIdStr, + vol: 0, + })); + + } else if (this.classList.contains('volumebtnmute')) { + this.classList.remove('volumebtnmute'); + this.classList.add('volumenbtn'); + volumeIcon.classList.remove('fa-volume-off'); + volumeIcon.classList.add('fa-volume-up'); + volumePill.style.height = `${50}%`; + + $.post(`https://${GetParentResourceName()}/callback`, JSON.stringify({ + event: 'setVolume', + veh: vehId, + vehStr: vehIdStr, + vol: 50, + })); + } + }); + + //Progress Bar + + const progressBar = document.querySelector('.song-progress'); + const progressFill = document.querySelector('.song-progress-fill'); + const currentTime = document.querySelector('.current-time'); + + progressBar.addEventListener('click', function(event) { + const progressBarRect = progressBar.getBoundingClientRect(); + const clickX = event.clientX - progressBarRect.left; + const fillWidth = progressBarRect.width; + const newProgress = (clickX / fillWidth) * 100; + + progressBar.style.width = `${newProgress}%`; + progressFill.style.width = `${newProgress}%`; + progressFill.style.backgroundImage = `linear-gradient(to right, #ffffff ${newProgress}%, #ffffff ${newProgress}%)`; + + const newTime = (newProgress / 100) * songTotal; + const minutes = Math.floor(newTime / 60); + const seconds = Math.floor(newTime % 60); + currentTime.textContent = `${minutes}:${seconds.toString().padStart(2, '0')}`; + + $.post(`https://${GetParentResourceName()}/callback`, JSON.stringify({ + event: 'selectTime', + veh: vehId, + vehStr: vehIdStr, + newTime: newTime, + })); + }); +}); + +function closeMenu() { + var songList = document.querySelector(".nextcontainer .song-list"); + + + while (songList.hasChildNodes()) { + songList.removeChild(songList.firstChild); + } + + $.post(`https://${GetParentResourceName()}/closeCarPlay`); + const mainContainer = document.getElementById('maincontainer'); + mainContainer.style.transition = 'all 0.5s ease-out'; + mainContainer.style.opacity = '0'; + mainContainer.style.transform = 'scale(0.8)'; + + setTimeout(() => { + mainContainer.style.display = 'none'; + }, 500); +} + +$(document).ready(function() { + $('.btn').click(function() { + if ($(this).hasClass('btn')) { + $(this).addClass('btn3').removeClass('btn').html(''); + $.post(`https://${GetParentResourceName()}/callback`, JSON.stringify({ + event: 'resume', + vehStr: vehIdStr, + veh: vehId, + })); + } else if ($(this).hasClass('btn3')) { + $(this).addClass('btn').removeClass('btn3').html(''); + $.post(`https://${GetParentResourceName()}/callback`, JSON.stringify({ + event: 'pause', + vehStr: vehIdStr, + veh: vehId, + })); + } + }); + + window.addEventListener('message', function(event) { + var item = event.data; + if (item.event == "playbackStarted") { + $('.btn').addClass('btn3').removeClass('btn').html(''); + } else if (item.event == "pause") { + $('.btn3').addClass('btn').removeClass('btn3').html(''); + } + }); +}); + +let buttonClicked = false; + +function nextSong(){ + $.post(`https://${GetParentResourceName()}/callback`, JSON.stringify({ + event: 'breakLoop', + vehStr: vehIdStr, + veh: vehId, + })); + $.post(`https://${GetParentResourceName()}/callback`, JSON.stringify({ + event: 'nextSong', + vehStr: vehIdStr, + veh: vehId + })); +} + + +function backSong(){ + $.post(`https://${GetParentResourceName()}/callback`, JSON.stringify({ + event: 'restartSong', + vehStr: vehIdStr, + veh: vehId, + })); +} + +function resetPlayback(){ + var songNameElement = document.getElementById("songname"); + songNameElement.textContent = "No media present"; + + var authorElement = document.getElementById("author"); + authorElement.textContent = ""; + + document.getElementById('musicthumbanil').src = "https://i.imgur.com/M5Lnw3o.png"; + + $.post(`https://${GetParentResourceName()}/callback`, JSON.stringify({ + event: 'resetPlayback', + vehStr: vehIdStr, + veh: vehId, + })); + + updateMusicProg(0, 0) +} + +function updateMusicProg(curr, total) { + const progressBar = document.querySelector('.song-progress'); + const progressFill = document.querySelector('.song-progress-fill'); + const currentTime = document.querySelector('.current-time'); + const songLength = document.querySelector('.song-length'); + + const progress = (curr / total) * 100; + + progressBar.style.width = `${progress}%`; + + progressFill.style.width = `${progress}%`; + progressFill.style.backgroundImage = `linear-gradient(to right, #ffffff ${progress}%, #ffffff ${progress}%)`; + + const minutes = Math.floor(curr / 60); + const seconds = Math.floor(curr % 60); + currentTime.textContent = `${minutes}:${seconds.toString().padStart(2, '0')}`; + + const lengthMinutes = Math.floor(total / 60); + const lengthSeconds = Math.floor(total % 60); + songLength.textContent = `${lengthMinutes}:${lengthSeconds.toString().padStart(2, '0')}`; +} + + + + + + + + + + + + + + diff --git a/[extras]/nass_carplay/html/style.css b/[extras]/nass_carplay/html/style.css new file mode 100644 index 0000000..b062b5c --- /dev/null +++ b/[extras]/nass_carplay/html/style.css @@ -0,0 +1,389 @@ +@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@300&display=swap'); + +.maincontainer { + height: 580px; + width: 1230px; +} + +.carimage { + height: 580px; + width: 1230px; +} + +.carimage img { + object-fit: contain; + height: 580px; + width: 1230px; +} + +.buttons { + position: absolute; + border: 0px solid #ffffff; + height: 60px; + width: 500px; + top: 280px; + left: 220px; +} + +.buttons .btn { + border-radius: 3px; + background: transparent; + display: absolute; + font-size: 36px; + margin-left: 240px; + color: #ffffff; + text-decoration: none; +} + +.buttons .btn2 { + border-radius: 3px; + position: absolute; + background: transparent; + display: absolute; + font-size: 30px; + margin-left: 60px; + margin-top: 5px; + color: #b0b0b0; + text-decoration: none; +} + +.buttons .btn4 { + border-radius: 3px; + position: absolute; + background: transparent; + display: absolute; + font-size: 30px; + margin-top: 5px; + margin-left: 150px; + color: #b0b0b0; + text-decoration: none; +} + +.buttons .btn3 { + border-radius: 3px; + background: transparent; + display: absolute; + font-size: 36px; + margin-left: 240px; + color: #ffffff; + text-decoration: none; +} + +.buttons .btn:active { + color: rgba(102, 102, 102, 0.5); + animation: colorchange 3s linear infinite; +} + +.buttons .btn2:active { + color: rgba(102, 102, 102, 0.5); + animation: colorchange 3s linear infinite; +} + +.buttons .btn3:active { + color: rgba(102, 102, 102, 0.5); + animation: colorchange 3s linear infinite; +} + +.buttons .btn4:active { + color: rgba(102, 102, 102, 0.5); + animation: colorchange 3s linear infinite; +} + + + +@keyframes colorchange { + to { + filter: hue-rotate(360deg); + } +} + +.carimage .volume-pill-bar { + top: 380px; + left: 165px; + width: 45px; + height: 160px; + background-color: #9c9c9c; + border-radius: 20.5px; + overflow: hidden; + cursor: pointer; + position: absolute; +} + +.carimage .volume-pill { + width: 100%; + height: 0%; + background-color: white; + border-radius: 2.5px; + transition: height 0.2s ease-in-out; + position: absolute; + bottom: 0; + left: 0; +} + +.carimage .volumebtns { + position: absolute; + display: absolute; + top: 410px; + left: 165px; +} + +.carimage .volumebtns .volumenbtn { + position: absolute; + background: transparent; + display: absolute; + color: #4B4D4D; + font-size: 20px; + margin-left: 11px; + margin-top: 90px; + z-index: 1; + text-decoration: none; +} + +.carimage .volumebtns .volumebtnmute { + position: absolute; + background: transparent; + display: absolute; + color: #4B4D4D; + font-size: 20px; + margin-left: 11px; + margin-top: 90px; + z-index: 1; + text-decoration: none; +} + +.carimage .volumenbtn:active { + color: rgba(102, 102, 102, 0.5); + animation: colorchange 3s linear infinite; +} + +.carimage .nextup { + position: absolute; + width: 500px; + height: 160px; + border-radius: 15px; + background-color: #9c9c9c; + opacity: 30%; + top: 380px; + left: 225px; +} + + +.carimage .nextcontainer { + position: absolute; + width: 470px; + height: 140px; + z-index: 1; + top: 388px; + left: 238px; + overflow-y: scroll; + scrollbar-width: none; + -ms-overflow-style: none; +} + +.carimage .nextcontainer::-webkit-scrollbar { + width: 6px; /* set the width of the scrollbar */ +} + +.carimage .nextcontainer::-webkit-scrollbar-track { +} + +.carimage .nextcontainer::-webkit-scrollbar-thumb { + background: white; /* set the color of the thumb */ + border-radius: 10px; /* make the thumb pill-shaped */ +} + +.carimage .nextcontainer::-webkit-scrollbar-thumb:hover { + background: #a1a1a1; /* set the color of the thumb on hover */ +} + + +.song-list { + margin: 0; + padding: 0; + list-style: none; +} + +.song-list li { + font-family: 'Roboto', sans-serif; + color: white; + border-radius: 5px; + padding: 10px 20px; + word-wrap: break-word; + transition: background-color 0.2s ease-in-out; + border: none; + color: white; + margin-bottom: 5px; + cursor: pointer; +} + +.nextcontainer .song-list li:hover { + background-color: #1f1e1e; + color: #ffffff; +} + +.nextcontainer .song-list li:active { + background-color: #ffffff; + color: #000000; + transform: scale(0.95); +} + +.carimage .musicthumb { + object-fit: contain; + position: absolute; + display: absolute; + width: 256px; + height: 256px; + left: 320px; + top: -75px; +} + +.carimage .musicthumb img { + object-fit: cover; + position: absolute; + display: absolute; + width: 256px; + height: 256px; + border-radius: 10px; + left: 500px; + top: 180px; +} + +.carimage .songinput { + position: absolute; + width: 350px; + height: 140px; + border-radius: 15px; + background: rgba(156, 156, 156, 0.3); + top: 400px; + left: 773px; + font-family: 'Roboto', sans-serif; + color: white; + font-size: 20px; +} + +.song-form { + display: flex; + flex-direction: column; + align-items: center; + margin-top: 10px; +} + +.song-input, .song-submit { + margin-top: 10px; + width: 200px; + border-radius: 6px; + border: 1px solid #ffffff; +} + +.song-submit { + background-color: transparent; + color: white; + font-family: 'Roboto', sans-serif; + padding: 8px 16px; + text-align: center; + text-decoration: none; + display: inline-block; + font-size: 16px; + margin-top: 10px; + cursor: pointer; + border-radius: 5px; + transition: background-color 0.3s ease; +} + +.song-submit:hover { + background-color: #7a7a7a; +} + +.song-submit:active { + background-color: #ffffff; + box-shadow: 0 5px #666; + transform: translateY(4px); +} + +.carimage .song-progress { + top: 350px; + left: 275px; + min-width: 400px; + max-width: 400px; + height: 4px; + border-radius: 20px; + background-color: #9c9c9c; + position: absolute; +} + +.song-progress-fill { + position: absolute; + top: 0; + left: 0; + height: 100%; + border-radius: 20px; + width: 0; + background-color: #ffffff; + background-image: linear-gradient(to right, #ffffff 0%, #ffffff 0%); +} + +.carimage .song-time { + display: flex; + justify-content: space-between; + margin-top: 5px; + font-family: 'Roboto', sans-serif; + font-size: 12px; + color: white; +} + +.carimage .current-time { + margin-right: 5px; +} + +.carimage .song-length { + margin-left: 5px; +} + +.carimage .songtext { + position: absolute; + top: 110px; + width: 390px; + left: 275px; + max-height: 160px; + text-align: center; + color: white; + font-family: 'Roboto', sans-serif; +} + + +.carimage .songtext h3 { + font-size: 25px; +} + +.carimage .songtext h4 { + position: relative; + color: #dedede; + font-size: 15px; + top: -20px; +} + +.carimage .backcont { + position: absolute; + top: 45px; + left: 175px; + height: 30px; + width: 90px; +} + +.carimage .backcont button{ + background: transparent; + font-size:0; + height: 50px; + width: 100px; + border: none !important; +} + +#maincontainer.fade-out { + opacity: 0; + transition: opacity 0.5s ease-out; /* adjust the duration and timing function as needed */ +} + +#myButton[disabled] { + opacity: 0.5; + cursor: not-allowed; +} \ No newline at end of file diff --git a/[extras]/nass_carplay/server/server.lua b/[extras]/nass_carplay/server/server.lua new file mode 100644 index 0000000..60999ac --- /dev/null +++ b/[extras]/nass_carplay/server/server.lua @@ -0,0 +1,13 @@ +-----------------For support, scripts, and more---------------- +--------------- https://discord.gg/fz655NHeDq ------------- +--------------------------------------------------------------- + +RegisterNetEvent('nass_carplay:syncmusic') +AddEventHandler('nass_carplay:syncmusic', function(peds, vehNet, data) + local veh = NetworkGetEntityFromNetworkId(vehNet) + if veh ~= 0 then + for k, v in pairs(peds) do + TriggerClientEvent("nass_carplay:playsound", v, data) + end + end +end) diff --git a/[extras]/s1lent_keybinds/config.lua b/[extras]/s1lent_keybinds/config.lua index bd756a1..4f2b733 100644 --- a/[extras]/s1lent_keybinds/config.lua +++ b/[extras]/s1lent_keybinds/config.lua @@ -36,10 +36,11 @@ Config.categories = { {description='Menster hoch', key='Pfeiltaste nach oben'}, {description='Waffe wählen', key='Ü'}, - {description='MKennzeichensuche (Polizei)', key='X'}, + {description='Kennzeichensuche (Polizei)', key='X'}, }, commands={ {description='Anschnallen/Abschnallen', command='/seatbelt', arguments=''}, + {description='Öffnet die Car Pay Oberfläche', command='/carplay', arguments=''}, }, }, { diff --git a/[extras]/xsound/.github/ISSUE_TEMPLATE/bug_report.md b/[extras]/xsound/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..891c617 --- /dev/null +++ b/[extras]/xsound/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,27 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: '' +assignees: '' + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Additional context** +Add any other context about the problem here. diff --git a/[extras]/xsound/.github/ISSUE_TEMPLATE/feature_request.md b/[extras]/xsound/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..bbcbbe7 --- /dev/null +++ b/[extras]/xsound/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,20 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '' +labels: '' +assignees: '' + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. diff --git a/[extras]/xsound/addon/crewphone/client/client.lua b/[extras]/xsound/addon/crewphone/client/client.lua new file mode 100644 index 0000000..c9dd169 --- /dev/null +++ b/[extras]/xsound/addon/crewphone/client/client.lua @@ -0,0 +1,186 @@ +if config.AddonList.crewPhone then + local calanMuzikler = {} + local musicOn = false + + local ESX = nil + + CreateThread(function() + xpcall(function() + ESX = exports['es_extended']['getSharedObject']() + end, function(error) + while ESX == nil do + Wait(50) + TriggerEvent('esx:getSharedObject', function(obj) + ESX = obj + end) + end + end) + end) + + + -- Müzik çalma + exports('Cal', function(link, mp3) + local ped = PlayerPedId() + local pos = GetEntityCoords(ped) + local serverId = GetPlayerServerId(PlayerId()) + local muzikAdi = tostring(serverId) + + if musicOn then + TriggerServerEvent("muzik-durdur", muzikAdi) + musicOn = false + end + + if #calanMuzikler <= 99 then + if mp3 then + TriggerServerEvent("muzik-cal", pos, muzikAdi, "phone-ring/" .. link, serverId, true) + else + TriggerServerEvent("muzik-cal", pos, muzikAdi, "https://www.youtube.com/watch?v=" .. link, serverId, false) + end + musicOn = true + else + ESX.ShowNotification("Fazla kişi youtube uygulamasını kullandığı için açtığınız videonun sesini yakındaki kişiler duyamıyor", "error") + end + end) + + RegisterNetEvent('client-muzik-cal') + AddEventHandler('client-muzik-cal', function(pos, muzikAdi, link, serverId, mp3) + if tostring(GetPlayerServerId(PlayerId())) ~= muzikAdi then + calanMuzikler[muzikAdi] = {} + calanMuzikler[muzikAdi]["duraklat"] = false + calanMuzikler[muzikAdi]["serverId"] = serverId + calanMuzikler[muzikAdi]["mp3"] = mp3 + + if mp3 then + PlayUrlPos(muzikAdi, link, 0.1, pos) + setVolumeMax(muzikAdi, 0.1) + Distance(muzikAdi, 10) + else + PlayUrlPos(muzikAdi, link, 0.15, pos) + setVolumeMax(muzikAdi, 0.15) + Distance(muzikAdi, 15) + end + end + end) + + -- Müzik durdurma + exports('Durdur', function(link) + if musicOn then + musicOn = false + TriggerServerEvent("muzik-durdur", tostring(GetPlayerServerId(PlayerId()))) + end + end) + + RegisterNetEvent('client-muzik-durdur') + AddEventHandler('client-muzik-durdur', function(muzikAdi) + if GetPlayerServerId(PlayerId()) ~= muzikAdi then + calanMuzikler[muzikAdi] = nil + Destroy(muzikAdi) + end + end) + + -- Müzik duraklatma + exports('Duraklat', function(link) + local myId = tostring(GetPlayerServerId(PlayerId())) + TriggerServerEvent("muzik-duraklat", myId) + end) + + RegisterNetEvent('client-muzik-duraklat') + AddEventHandler('client-muzik-duraklat', function(muzikAdi) + if tostring(GetPlayerServerId(PlayerId())) ~= muzikAdi then + if calanMuzikler[muzikAdi]["duraklat"] == false then + calanMuzikler[muzikAdi]["duraklat"] = true + Pause(muzikAdi) + end + end + end) + + -- Müzik duraklatma + exports('Devamet', function(link) + local myId = tostring(GetPlayerServerId(PlayerId())) + TriggerServerEvent("muzik-devamet", myId) + end) + + RegisterNetEvent('client-muzik-devamet') + AddEventHandler('client-muzik-devamet', function(muzikAdi) + if tostring(GetPlayerServerId(PlayerId())) ~= muzikAdi then + if calanMuzikler[muzikAdi]["duraklat"] == true then + calanMuzikler[muzikAdi]["duraklat"] = false + Resume(muzikAdi) + end + end + end) + + -- Müzik Konum güncelleme + local time = 100 + Citizen.CreateThread(function() + while true do + Citizen.Wait(time) + + for x, y in pairs(calanMuzikler) do + local player = GetPlayerFromServerId(calanMuzikler[x]["serverId"]) + if player ~= -1 then + local ped = GetPlayerPed(player) + local kordinat = GetEntityCoords(ped) + local benimKordinat = GetEntityCoords(PlayerPedId()) + + local mesafe = #(benimKordinat - kordinat) + if mesafe < 200 then + time = 100 + Position(x, kordinat) + if calanMuzikler[x]["mp3"] then + if IsPedInAnyVehicle(ped, true) == 1 then + local vehicle = GetVehiclePedIsIn(ped, false) + if GetEntitySpeed(vehicle) * 3.6 > 200.0 then + Distance(x, 140) + elseif GetEntitySpeed(vehicle) * 3.6 > 150.0 then + Distance(x, 125) + elseif GetEntitySpeed(vehicle) * 3.6 > 110.0 then + Distance(x, 100) + elseif GetEntitySpeed(vehicle) * 3.6 > 90.0 then + Distance(x, 80) + elseif GetEntitySpeed(vehicle) * 3.6 > 60.0 then + Distance(x, 65) + elseif GetEntitySpeed(vehicle) * 3.6 > 30.0 then + Distance(x, 40) + else + Distance(x, 25) + end + else + Distance(x, 10) + end + else + if IsPedInAnyVehicle(ped, true) == 1 then + local vehicle = GetVehiclePedIsIn(ped, false) + if GetEntitySpeed(vehicle) * 3.6 > 200.0 then + Distance(x, 140) + elseif GetEntitySpeed(vehicle) * 3.6 > 150.0 then + Distance(x, 125) + elseif GetEntitySpeed(vehicle) * 3.6 > 110.0 then + Distance(x, 100) + elseif GetEntitySpeed(vehicle) * 3.6 > 90.0 then + Distance(x, 80) + elseif GetEntitySpeed(vehicle) * 3.6 > 60.0 then + Distance(x, 65) + elseif GetEntitySpeed(vehicle) * 3.6 > 30.0 then + Distance(x, 40) + else + Distance(x, 25) + end + else + Distance(x, 15) + end + end + + else + time = 2000 + Position(x, kordinat) + end + else + local muzikAdi = tostring(calanMuzikler[x]["serverId"]) + calanMuzikler[muzikAdi] = nil + Destroy(muzikAdi) + end + end + end + end) +end \ No newline at end of file diff --git a/[extras]/xsound/addon/crewphone/server/server.lua b/[extras]/xsound/addon/crewphone/server/server.lua new file mode 100644 index 0000000..ec73d4b --- /dev/null +++ b/[extras]/xsound/addon/crewphone/server/server.lua @@ -0,0 +1,26 @@ +if config.AddonList.crewPhone then + RegisterServerEvent('muzik-cal') + AddEventHandler('muzik-cal', function(pos, muzikAdi, link, serverId, mp3) + TriggerClientEvent("client-muzik-cal", -1, pos, muzikAdi, link, serverId, mp3) + end) + + RegisterServerEvent('muzik-durdur') + AddEventHandler('muzik-durdur', function(muzikAdi) + TriggerClientEvent("client-muzik-durdur", -1, muzikAdi) + end) + + RegisterServerEvent('muzik-duraklat') + AddEventHandler('muzik-duraklat', function(muzikAdi) + TriggerClientEvent("client-muzik-duraklat", -1, muzikAdi) + end) + + RegisterServerEvent('muzik-devamet') + AddEventHandler('muzik-devamet', function(muzikAdi) + TriggerClientEvent("client-muzik-devamet", -1, muzikAdi) + end) + + AddEventHandler('playerDropped', function(source) + local _source = source + TriggerClientEvent("client-muzik-durdur", -1, tostring(_source)) + end) +end \ No newline at end of file diff --git a/[extras]/xsound/addon/readme.md b/[extras]/xsound/addon/readme.md new file mode 100644 index 0000000..79e828d --- /dev/null +++ b/[extras]/xsound/addon/readme.md @@ -0,0 +1,14 @@ +Hey, if you're reading this that means you want to add some addon to this api.. + +so the rules are simple, you can create a folder whatever name and you dont need +to write anything to fxmanifest.lua only what rule you need to follow is to create +two folder "client","server" so in final form it will look like this + +"addon/YOUR NAME/client/whatevername.lua"
+"addon/YOUR NAME/server/whatevername.lua" + +Please do not change anything inside of the API like the crewPhone did..
+it just isnt really nice way to handle API and not even planning to update it to
+newest version so it wont bug to the other... Yes people complaning to me that
+xsound is bugged when they're using like half year old version.. :)
+Thats why i created this addon folder so you can add your own "needed" things into it.
\ No newline at end of file diff --git a/[extras]/xsound/client/commands.lua b/[extras]/xsound/client/commands.lua new file mode 100644 index 0000000..570181e --- /dev/null +++ b/[extras]/xsound/client/commands.lua @@ -0,0 +1,16 @@ +-- i recommend to NOT change the command name. it will make easier for people to use this command +-- when ever is this library.. so please keep this command name on "streamermode" command +RegisterCommand("streamermode", function(source, args, rawCommand) + disableMusic = not disableMusic + TriggerEvent("xsound:streamerMode", disableMusic) + if disableMusic then + TriggerEvent('chat:addMessage', { args = { "^1[xSound]", config.Messages["streamer_on"] } }) + + for k, v in pairs(soundInfo) do + Destroy(v.id) + end + + else + TriggerEvent('chat:addMessage', { args = { "^1[xSound]", config.Messages["streamer_off"] } }) + end +end, false) diff --git a/[extras]/xsound/client/effects/main.lua b/[extras]/xsound/client/effects/main.lua new file mode 100644 index 0000000..23502ac --- /dev/null +++ b/[extras]/xsound/client/effects/main.lua @@ -0,0 +1,69 @@ +function fadeIn(name, time, volume_) + if soundExists(name) then + volumeType(name, 0) + + local addVolume = (volume_ / time) * 100 + local called = 0 + local volume = volume_ + + while true do + volume = volume - addVolume + if volume < 0 then volume = 0 end + if volume == 0 then break end + called = called + 1 + end + + volume = getVolume(name) + while true do + Citizen.Wait(time / called) + volume = volume + addVolume + if volume > volume_ then + volume = volume_ + volumeType(name, volume) + break + end + volumeType(name, volume) + end + end +end + +exports('fadeIn', fadeIn) + +function fadeOut(name, time) + if soundExists(name) then + local volume = getVolume(name) + + local addVolume = (volume / time) * 100 + local called = 0 + + while true do + volume = volume - addVolume + if volume < 0 then volume = 0 end + if volume == 0 then break end + called = called + 1 + end + + volume = getVolume(name) + while true do + Citizen.Wait(time / called) + volume = volume - addVolume + if volume < 0 then + volume = 0 + volumeType(name, volume) + break + end + volumeType(name, volume) + end + end +end + +exports('fadeOut', fadeOut) + +function volumeType(name, volume) + if isDynamic(name) then + setVolumeMax(name,volume) + setVolume(name,volume) + else + setVolume(name,volume) + end +end \ No newline at end of file diff --git a/[extras]/xsound/client/emulator/interact_sound/client.lua b/[extras]/xsound/client/emulator/interact_sound/client.lua new file mode 100644 index 0000000..aab93fc --- /dev/null +++ b/[extras]/xsound/client/emulator/interact_sound/client.lua @@ -0,0 +1,22 @@ +if config.interact_sound_enable then + + RegisterNetEvent('InteractSound_CL:PlayOnOne') + AddEventHandler('InteractSound_CL:PlayOnOne', function(soundFile, soundVolume) + PlayUrl("./sounds/" .. soundFile, "./sounds/" .. soundFile .. "." .. config.interact_sound_file, soundVolume) + end) + + RegisterNetEvent('InteractSound_CL:PlayOnAll') + AddEventHandler('InteractSound_CL:PlayOnAll', function(soundFile, soundVolume) + PlayUrl("./sounds/" .. soundFile, "./sounds/" .. soundFile .. "." .. config.interact_sound_file, soundVolume) + end) + + RegisterNetEvent('InteractSound_CL:PlayWithinDistance') + AddEventHandler('InteractSound_CL:PlayWithinDistance', function(playerNetId, maxDistance, soundFile, soundVolume) + if GetPlayerFromServerId(playerNetId) ~= -1 then + local eCoords = GetEntityCoords(GetPlayerPed(GetPlayerFromServerId(playerNetId))) + PlayUrlPos("./sounds/" .. soundFile, "./sounds/" .. soundFile .. "." .. config.interact_sound_file, soundVolume, eCoords) + Distance("./sounds/" .. soundFile, maxDistance) + end + end) + +end diff --git a/[extras]/xsound/client/events.lua b/[extras]/xsound/client/events.lua new file mode 100644 index 0000000..d2c8f86 --- /dev/null +++ b/[extras]/xsound/client/events.lua @@ -0,0 +1,150 @@ +RegisterNUICallback("init", function(data, cb) + SendNUIMessage({ + status = "init", + time = config.RefreshTime, + }) + + if cb then cb('ok') end +end) + +RegisterNUICallback("data_status", function(data, cb) + if soundInfo[data.id] ~= nil then + if data.type == "finished" then + if not soundInfo[data.id].loop then + soundInfo[data.id].playing = false + end + TriggerEvent("xSound:songStopPlaying", data.id) + end + if data.type == "maxDuration" then + if not soundInfo[data.id].SkipTimeStamp then + soundInfo[data.id].timeStamp = 0 + end + soundInfo[data.id].maxDuration = data.time + + soundInfo[data.id].SkipTimeStamp = nil + end + end + + if cb then cb('ok') end +end) + +RegisterNUICallback("events", function(data, cb) + local id = data.id + local type = data.type + if type == "resetTimeStamp" then + if soundInfo[id] then + soundInfo[id].timeStamp = 0 + soundInfo[id].maxDuration = data.time + soundInfo[id].playing = true + end + end + if type == "onPlay" then + if globalOptionsCache[id] then + if globalOptionsCache[id].onPlayStartSilent then + globalOptionsCache[id].onPlayStartSilent(getInfo(id)) + end + + if globalOptionsCache[id].onPlayStart and not soundInfo[id].SkipEvents then + globalOptionsCache[id].onPlayStart(getInfo(id)) + end + + soundInfo[id].SkipEvents = nil + end + end + if type == "onEnd" then + if globalOptionsCache[id] then + if globalOptionsCache[id].onPlayEnd then + globalOptionsCache[id].onPlayEnd(getInfo(id)) + end + end + if soundInfo[id] then + if soundInfo[id].loop then + soundInfo[id].timeStamp = 0 + end + if soundInfo[id].destroyOnFinish and not soundInfo[id].loop then + Destroy(id) + end + end + end + if type == "onLoading" then + if globalOptionsCache[id] then + if globalOptionsCache[id].onLoading then + globalOptionsCache[id].onLoading(getInfo(id)) + end + end + end + + if cb then cb('ok') end +end) + +RegisterNetEvent("xsound:stateSound", function(state, data) + local soundId = data.soundId + + if state == "destroyOnFinish" then + if soundExists(soundId) then + destroyOnFinish(soundId, data.value) + end + end + + if state == "timestamp" then + if soundExists(soundId) then + setTimeStamp(soundId, data.time) + end + end + + if state == "texttospeech" then + TextToSpeech(soundId, data.lang, data.url, data.volume, data.loop or false) + end + + if state == "texttospeechpos" then + TextToSpeechPos(soundId, data.lang, data.url, data.volume, data.position, data.loop or false) + end + + if state == "play" then + PlayUrl(soundId, data.url, data.volume, data.loop or false) + end + + if state == "playpos" then + PlayUrlPos(soundId, data.url, data.volume, data.position, data.loop or false) + end + + if state == "position" then + if soundExists(soundId) then + Position(soundId, data.position) + end + end + + if state == "distance" then + if soundExists(soundId) then + Distance(soundId, data.distance) + end + end + + if state == "destroy" then + if soundExists(soundId) then + Destroy(soundId) + end + end + + if state == "pause" then + if soundExists(soundId) then + Pause(soundId) + end + end + + if state == "resume" then + if soundExists(soundId) then + Resume(soundId) + end + end + + if state == "volume" then + if soundExists(soundId) then + if isDynamic(soundId) then + setVolumeMax(soundId, data.volume) + else + setVolume(soundId, data.volume) + end + end + end +end) diff --git a/[extras]/xsound/client/exports/events.lua b/[extras]/xsound/client/exports/events.lua new file mode 100644 index 0000000..905a256 --- /dev/null +++ b/[extras]/xsound/client/exports/events.lua @@ -0,0 +1,33 @@ +function onPlayStart(name, delegate) + globalOptionsCache[name].onPlayStart = delegate +end + +exports('onPlayStart', onPlayStart) + +function onPlayEnd(name, delegate) + globalOptionsCache[name].onPlayEnd = delegate +end + +exports('onPlayEnd', onPlayEnd) + +function onLoading(name, delegate) + globalOptionsCache[name].onLoading = delegate +end + +exports('onLoading', onLoading) + +function onPlayPause(name, delegate) + globalOptionsCache[name].onPlayPause = delegate +end + +exports('onPlayPause', onPlayPause) + +function onPlayResume(name, delegate) + globalOptionsCache[name].onPlayResume = delegate +end + +exports('onPlayResume', onPlayResume) + +function onPlayStartSilent(name, delegate) + globalOptionsCache[name].onPlayStartSilent = delegate +end \ No newline at end of file diff --git a/[extras]/xsound/client/exports/info.lua b/[extras]/xsound/client/exports/info.lua new file mode 100644 index 0000000..b039b9d --- /dev/null +++ b/[extras]/xsound/client/exports/info.lua @@ -0,0 +1,94 @@ +soundInfo = {} + +function getLink(name_) + return soundInfo[name_].url +end + +exports('getLink', getLink) + +function getPosition(name_) + return soundInfo[name_].position +end + +exports('getPosition', getPosition) + +function isLooped(name_) + return soundInfo[name_].loop +end + +exports('isLooped', isLooped) + +function getInfo(name_) + return soundInfo[name_] +end + +exports('getInfo', getInfo) + +function soundExists(name_) + if soundInfo[name_] == nil then + return false + end + return true +end + +exports('soundExists', soundExists) + +function isPlaying(name_) + return soundInfo[name_].playing +end + +exports('isPlaying', isPlaying) + +function isPaused(name_) + return soundInfo[name_].paused +end + +exports('isPaused', isPaused) + +function getDistance(name_) + return soundInfo[name_].distance +end + +exports('getDistance', getDistance) + +function getVolume(name_) + return soundInfo[name_].volume +end + +exports('getVolume', getVolume) + +function isDynamic(name_) + return soundInfo[name_].isDynamic +end + +exports('isDynamic', isDynamic) + +function getTimeStamp(name_) + return soundInfo[name_].timeStamp or -1 +end + +exports('getTimeStamp', getTimeStamp) + +function getMaxDuration(name_) + return soundInfo[name_].maxDuration or -1 +end + +exports('getMaxDuration', getMaxDuration) + +function isPlayerInStreamerMode() + return disableMusic +end + +exports('isPlayerInStreamerMode', isPlayerInStreamerMode) + +function getAllAudioInfo() + return soundInfo +end + +exports('getAllAudioInfo', getAllAudioInfo) + +function isPlayerCloseToAnySound() + return isPlayerCloseToMusic +end + +exports('isPlayerCloseToAnySound', isPlayerCloseToAnySound) \ No newline at end of file diff --git a/[extras]/xsound/client/exports/manipulation.lua b/[extras]/xsound/client/exports/manipulation.lua new file mode 100644 index 0000000..824363c --- /dev/null +++ b/[extras]/xsound/client/exports/manipulation.lua @@ -0,0 +1,165 @@ +function Distance(name_, distance_) + SendNUIMessage({ + status = "distance", + name = name_, + distance = distance_, + }) + soundInfo[name_].distance = distance_ +end + +exports('Distance', Distance) + +function Position(name_, pos) + SendNUIMessage({ + status = "soundPosition", + name = name_, + x = pos.x, + y = pos.y, + z = pos.z, + }) + soundInfo[name_].position = pos + soundInfo[name_].id = name_ +end + +exports('Position', Position) + +function Destroy(name_) + SendNUIMessage({ + status = "delete", + name = name_ + }) + soundInfo[name_] = nil + + if globalOptionsCache[name_] ~= nil and globalOptionsCache[name_].onPlayEnd ~= nil then + globalOptionsCache[name_].onPlayEnd(getInfo(name_)) + end + + globalOptionsCache[name_] = nil +end + +function DestroySilent(name) + SendNUIMessage({ + status = "delete", + name = name + }) +end + + +exports('Destroy', Destroy) + +function Resume(name_) + SendNUIMessage({ + status = "resume", + name = name_ + }) + soundInfo[name_].playing = true + soundInfo[name_].paused = false + + if globalOptionsCache[name_] ~= nil and globalOptionsCache[name_].onPlayResume ~= nil then + globalOptionsCache[name_].onPlayResume(getInfo(name_)) + end +end + +exports('Resume', Resume) + +function Pause(name_) + SendNUIMessage({ + status = "pause", + name = name_ + }) + soundInfo[name_].playing = false + soundInfo[name_].paused = true + + if globalOptionsCache[name_] ~= nil and globalOptionsCache[name_].onPlayPause ~= nil then + globalOptionsCache[name_].onPlayPause(getInfo(name_)) + end +end + +exports('Pause', Pause) + +function setVolume(name_, vol) + SendNUIMessage({ + status = "volume", + volume = vol, + name = name_, + }) + soundInfo[name_].volume = vol +end + +exports('setVolume', setVolume) + +function setVolumeMax(name_, vol) + SendNUIMessage({ + status = "max_volume", + volume = vol, + name = name_, + }) + soundInfo[name_].volume = vol +end + +exports('setVolumeMax', setVolumeMax) + +function setTimeStamp(name_, timestamp) + getInfo(name_).timeStamp = timestamp + SendNUIMessage({ + name = name_, + status = "timestamp", + timestamp = timestamp, + }) +end + +exports('setTimeStamp', setTimeStamp) + +function destroyOnFinish(id, bool) + soundInfo[id].destroyOnFinish = bool +end + +exports('destroyOnFinish', destroyOnFinish) + +function setSoundLoop(name, value) + SendNUIMessage({ + status = "loop", + name = name, + loop = value, + }) + soundInfo[name].loop = value +end + +exports('setSoundLoop', setSoundLoop) + +function repeatSound(name) + if soundExists(name) then + SendNUIMessage({ + status = "repeat", + name = name, + }) + end +end + +exports('repeatSound', repeatSound) + +function setSoundDynamic(name, bool) + if soundExists(name) then + soundInfo[name].isDynamic = bool + SendNUIMessage({ + status = "changedynamic", + name = name, + bool = bool, + }) + end +end + +exports('setSoundDynamic', setSoundDynamic) + +function setSoundURL(name, url) + if soundExists(name) then + soundInfo[name].url = url + SendNUIMessage({ + status = "changeurl", + name = name, + url = url, + }) + end +end + +exports('setSoundURL', setSoundURL) \ No newline at end of file diff --git a/[extras]/xsound/client/exports/play.lua b/[extras]/xsound/client/exports/play.lua new file mode 100644 index 0000000..1fca4f0 --- /dev/null +++ b/[extras]/xsound/client/exports/play.lua @@ -0,0 +1,143 @@ +function PlayUrl(name_, url_, volume_, loop_, options) + if disableMusic then return end + SendNUIMessage({ + status = "url", + name = name_, + url = url_, + x = 0, + y = 0, + z = 0, + dynamic = false, + volume = volume_, + loop = loop_ or false, + }) + + if soundInfo[name_] == nil then soundInfo[name_] = getDefaultInfo() end + + soundInfo[name_].volume = volume_ + soundInfo[name_].url = url_ + soundInfo[name_].id = name_ + soundInfo[name_].playing = true + soundInfo[name_].loop = loop_ or false + soundInfo[name_].isDynamic = false + + globalOptionsCache[name_] = options or { } + + if loop_ then + soundInfo[name_].destroyOnFinish = false + else + soundInfo[name_].destroyOnFinish = true + end +end + +exports('PlayUrl', PlayUrl) + +function PlayUrlPos(name_, url_, volume_, pos, loop_, options) + if disableMusic then return end + SendNUIMessage({ + status = "url", + name = name_, + url = url_, + x = pos.x, + y = pos.y, + z = pos.z, + dynamic = true, + volume = volume_, + loop = loop_ or false, + }) + if soundInfo[name_] == nil then soundInfo[name_] = getDefaultInfo() end + + soundInfo[name_].volume = volume_ + soundInfo[name_].url = url_ + soundInfo[name_].position = pos + soundInfo[name_].id = name_ + soundInfo[name_].playing = true + soundInfo[name_].loop = loop_ or false + soundInfo[name_].isDynamic = true + + globalOptionsCache[name_] = options or { } + + if loop_ then + soundInfo[name_].destroyOnFinish = false + else + soundInfo[name_].destroyOnFinish = true + end +end + +exports('PlayUrlPos', PlayUrlPos) + +function PlayUrlPosSilent(name_, url_, volume_, pos, loop_) + if disableMusic then return end + SendNUIMessage({ + status = "url", + name = name_, + url = url_, + x = pos.x, + y = pos.y, + z = pos.z, + dynamic = true, + volume = volume_, + loop = loop_ or false, + }) +end + +--function TextToSpeech(name_, lang, text, volume_) +-- if disableMusic then return end +-- SendNUIMessage({ +-- status = "textSpeech", +-- name = name_, +-- text = text, +-- lang = lang, +-- x = 0, +-- y = 0, +-- z = 0, +-- dynamic = false, +-- volume = volume_, +-- }) +-- +-- if soundInfo[name_] == nil then soundInfo[name_] = getDefaultInfo() end +-- +-- soundInfo[name_].volume = volume_ +-- soundInfo[name_].url = "is text to speech" +-- soundInfo[name_].id = name_ +-- soundInfo[name_].playing = true +-- soundInfo[name_].loop = false +-- soundInfo[name_].isDynamic = false +-- soundInfo[name_].destroyOnFinish = true +-- +-- +-- globalOptionsCache[name_] = options or { } +--end +-- +--exports('TextToSpeech', TextToSpeech) + +--function TextToSpeechPos(name_, lang, text, volume_, pos) +-- if disableMusic then return end +-- SendNUIMessage({ +-- status = "textSpeech", +-- name = name_, +-- text = text, +-- lang = lang, +-- x = pos.x, +-- y = pos.y, +-- z = pos.z, +-- dynamic = true, +-- volume = volume_, +-- }) +-- +-- if soundInfo[name_] == nil then soundInfo[name_] = getDefaultInfo() end +-- +-- soundInfo[name_].volume = volume_ +-- soundInfo[name_].url = "is text to speech" +-- soundInfo[name_].position = pos +-- soundInfo[name_].id = name_ +-- soundInfo[name_].playing = true +-- soundInfo[name_].loop = false +-- soundInfo[name_].isDynamic = true +-- soundInfo[name_].destroyOnFinish = true +-- +-- +-- globalOptionsCache[name_] = options or { } +--end +-- +--exports('TextToSpeechPos', TextToSpeechPos) \ No newline at end of file diff --git a/[extras]/xsound/client/main.lua b/[extras]/xsound/client/main.lua new file mode 100644 index 0000000..1cb5605 --- /dev/null +++ b/[extras]/xsound/client/main.lua @@ -0,0 +1,150 @@ +globalOptionsCache = {} +isPlayerCloseToMusic = false +disableMusic = false + +function getDefaultInfo() + return { + volume = 1.0, + url = "", + id = "", + position = nil, + distance = 10, + playing = false, + paused = false, + loop = false, + isDynamic = false, + timeStamp = 0, + maxDuration = 0, + destroyOnFinish = true, + } +end + +function UpdatePlayerPositionInNUI() + local ped = PlayerPedId() + local pos = GetEntityCoords(ped) + + SendNUIMessage({ + status = "position", + x = pos.x, + y = pos.y, + z = pos.z + }) +end + +-- updating position on html side so we can count how much volume the sound needs. +CreateThread(function() + local refresh = config.RefreshTime + local ped = PlayerPedId() + local pos = GetEntityCoords(ped) + local lastPos = pos + local changedPosition = false + while true do + Wait(refresh) + if not disableMusic and isPlayerCloseToMusic then + ped = PlayerPedId() + pos = GetEntityCoords(ped) + + -- we will update position only when player have moved + if #(lastPos - pos) >= 0.1 then + lastPos = pos + UpdatePlayerPositionInNUI() + end + + if changedPosition then + UpdatePlayerPositionInNUI() + SendNUIMessage({ status = "unmuteAll" }) + end + changedPosition = false + else + if not changedPosition then + changedPosition = true + SendNUIMessage({ status = "position", x = -900000, y = -900000, z = -900000 }) + SendNUIMessage({ status = "muteAll" }) + end + Wait(1000) + end + end +end) + +-- checking if player is close to sound so we can switch bool value to true. +CreateThread(function() + local ped = PlayerPedId() + local playerPos = GetEntityCoords(ped) + while true do + Wait(500) + ped = PlayerPedId() + playerPos = GetEntityCoords(ped) + isPlayerCloseToMusic = false + for k, v in pairs(soundInfo) do + if v.position ~= nil and v.isDynamic then + if #(v.position - playerPos) < v.distance + config.distanceBeforeUpdatingPos then + isPlayerCloseToMusic = true + break + end + end + end + end +end) + +-- updating timeStamp +CreateThread(function() + Wait(1100) + + while true do + Wait(1000) + for k, v in pairs(soundInfo) do + if v.playing or v.wasSilented then + if getInfo(v.id).timeStamp ~= nil and getInfo(v.id).maxDuration ~= nil then + if getInfo(v.id).timeStamp < getInfo(v.id).maxDuration then + getInfo(v.id).timeStamp = getInfo(v.id).timeStamp + 1 + end + end + end + end + end +end) + +function PlayMusicFromCache(data) + local musicCache = soundInfo[data.id] + if musicCache then + musicCache.SkipEvents = true + musicCache.SkipTimeStamp = true + + PlayUrlPosSilent(data.id, data.url, data.volume, data.position, data.loop) + onPlayStartSilent(data.id, function() + if getInfo(data.id).maxDuration then + setTimeStamp(data.id, data.timeStamp or 0) + end + Distance(data.id, data.distance) + end) + end +end + +-- If player is far away from music we will just delete it. +CreateThread(function() + local ped = PlayerPedId() + local playerPos = GetEntityCoords(ped) + local destroyedMusicList = {} + while true do + Wait(500) + ped = PlayerPedId() + playerPos = GetEntityCoords(ped) + for k, v in pairs(soundInfo) do + if v.position ~= nil and v.isDynamic then + if #(v.position - playerPos) < (v.distance + config.distanceBeforeUpdatingPos) then + if destroyedMusicList[v.id] then + destroyedMusicList[v.id] = nil + v.wasSilented = true + PlayMusicFromCache(v) + end + else + if not destroyedMusicList[v.id] then + destroyedMusicList[v.id] = true + v.wasSilented = false + DestroySilent(v.id) + end + end + end + end + end +end) \ No newline at end of file diff --git a/[extras]/xsound/config.lua b/[extras]/xsound/config.lua new file mode 100644 index 0000000..b727b16 --- /dev/null +++ b/[extras]/xsound/config.lua @@ -0,0 +1,27 @@ +config = {} + +-- How much ofter the player position is updated ? +config.RefreshTime = 300 + +-- default sound format for interact +config.interact_sound_file = "ogg" + +-- is emulator enabled ? +config.interact_sound_enable = false + +-- how much close player has to be to the sound before starting updating position ? +config.distanceBeforeUpdatingPos = 40 + +-- Message list +config.Messages = { + ["streamer_on"] = "Streamer mode is on. From now you will not hear any music/sound.", + ["streamer_off"] = "Streamer mode is off. From now you will be able to listen to music that players might play.", + + ["no_permission"] = "You cant use this command, you dont have permissions for it!", +} + +-- Addon list +-- True/False enabled/disabled +config.AddonList = { + crewPhone = false, +} \ No newline at end of file diff --git a/[extras]/xsound/fxmanifest.lua b/[extras]/xsound/fxmanifest.lua new file mode 100644 index 0000000..3d6c245 --- /dev/null +++ b/[extras]/xsound/fxmanifest.lua @@ -0,0 +1,44 @@ +fx_version 'cerulean' +games { 'gta5', 'rdr3' } + +rdr3_warning 'I acknowledge that this is a prerelease build of RedM, and I am aware my resources *will* become incompatible once RedM ships.' + +client_scripts { + "config.lua", + "client/main.lua", + "client/events.lua", + "client/commands.lua", + + "client/exports/info.lua", + "client/exports/play.lua", + "client/exports/manipulation.lua", + "client/exports/events.lua", + "client/effects/main.lua", + + "client/emulator/interact_sound/client.lua", + + "addon/**/client/*.lua", +} + +server_scripts { + "config.lua", + "server/exports/play.lua", + "server/exports/manipulation.lua", + + "server/emulator/interact_sound/server.lua", + + "addon/**/server/*.lua", +} + +ui_page "html/index.html" + +files { + "html/index.html", + + "html/scripts/listener.js", + "html/scripts/SoundPlayer.js", + "html/scripts/functions.js", + + "html/sounds/*.ogg", + "html/sounds/*.mp3", +} diff --git a/[extras]/xsound/html/index.html b/[extras]/xsound/html/index.html new file mode 100644 index 0000000..a3c1fab --- /dev/null +++ b/[extras]/xsound/html/index.html @@ -0,0 +1,15 @@ + + + xSound + + + + + + + + + + + + diff --git a/[extras]/xsound/html/scripts/SoundPlayer.js b/[extras]/xsound/html/scripts/SoundPlayer.js new file mode 100644 index 0000000..c5f5880 --- /dev/null +++ b/[extras]/xsound/html/scripts/SoundPlayer.js @@ -0,0 +1,329 @@ +class SoundPlayer +{ + static yPlayer = null; + youtubeIsReady = false; + + constructor() + { + this.url = "test"; + this.name = ""; + this.dynamic = false; + this.distance = 10; + this.volume = 1.0; + this.pos = [0.0,0.0,0.0]; + this.max_volume = -1.0; + this.div_id = "myAudio_" + Math.floor(Math.random() * 9999999); + this.loop = false; + this.isYoutube = false; + this.load = false; + this.isMuted_ = false; + this.audioPlayer = null; + + //this.textToSpeech = false; + //this.speechSynthMessage = new SpeechSynthesisUtterance(); + //this.textToRead = "hello you know"; + //this.textToReadLang = "en-US"; + } + + /* + setTextToSpeechLang(lang){ + this.textToReadLang = lang; + } + + setTextToSpeech(text){ + this.textToRead = text; + } + + IsTextToSpeech(result){ + if(typeof result !== "undefined"){ + this.textToSpeech = result + } + return this.textToSpeech + } + */ + + isYoutubeReady(result){ + this.youtubeIsReady = result; + } + + getDistance() { return this.distance;} + getLocation() { return this.pos; } + getVolume() { return this.volume; } + getMaxVolume(){ return this.max_volume; } + getUrlSound() { return this.url; } + isDynamic() { return this.dynamic; } + getDivId() { return this.div_id; } + isLoop() { return this.loop; } + getName() { return this.name; } + loaded() { return this.load; } + + getAudioPlayer() { return this.audioPlayer; } + getYoutubePlayer() { return this.yPlayer; } + + setLoaded(result) { this.load = result; } + setName(result) { this.name = result; } + setDistance(result) { this.distance = result; } + setDynamic(result) { this.dynamic = result; } + setLocation(x_,y_,z_){ this.pos = [x_,y_,z_]; } + + + setSoundUrl(result) { + this.url = result.replace(/<[^>]*>?/gm, ''); + } + + setLoop(result) { + if(!this.isYoutube) + { + if(this.audioPlayer != null){ + this.audioPlayer.loop(result); + } + } + this.loop = result; + } + + + setMaxVolume(result) { this.max_volume = result; } + setVolume(result) + { + this.volume = result; + if(this.max_volume == -1) this.max_volume = result; + if(this.max_volume > (this.volume - 0.01)) this.volume = this.max_volume; + + /* + if(this.IsTextToSpeech()){ + this.speechSynthMessage.volume = result; + return; + } + */ + + if(this.dynamic && (this.isMuted_ || isMutedAll)){ + if(!this.isYoutube) + { + if(this.audioPlayer != null) { + this.audioPlayer.volume(0); + } + } + else + { + if(this.yPlayer && this.youtubeIsReady){ + this.yPlayer.setVolume(0); + } + } + } + else + { + if(!this.isYoutube) + { + if(this.audioPlayer != null){ + this.audioPlayer.volume(result); + } + } + else + { + if(this.yPlayer && this.youtubeIsReady){ + this.yPlayer.setVolume(result * 100); + } + } + } + } + + create() + { + $.post('https://xsound/events', JSON.stringify( + { + type: "onLoading", + id: this.getName(), + })); + var link = getYoutubeUrlId(this.getUrlSound()); + if(link === "") + { + this.isYoutube = false; + + this.audioPlayer = new Howl({ + src: [this.getUrlSound()], + loop: false, + html5: true, + autoplay: false, + volume: 0.00, + format: ['mp3'], + onend: function(event){ + ended(null); + }, + onplay: function(){ + isReady("nothing", true); + }, + }); + $("#" + this.div_id).remove(); + $("body").append("") + } + else + { + this.isYoutube = true; + this.isYoutubeReady(false); + $("#" + this.div_id).remove(); + $("body").append("
"); + this.yPlayer = new YT.Player(this.div_id, { + + startSeconds:Number, + + videoId: link, + origin: window.location.href, + enablejsapi: 1, + width: "0", + height: "0", + playerVars: { + controls: 0, + }, + events: { + 'onReady': function(event){ + event.target.unMute(); + event.target.setVolume(0); + event.target.playVideo(); + isReady(event.target.getIframe().id); + }, + 'onStateChange': function(event){ + if (event.data == YT.PlayerState.ENDED) { + isLooped(event.target.getIframe().id); + ended(event.target.getIframe().id); + } + } + } + }); + } + } + + destroyYoutubeApi() + { + if (this.yPlayer) { + if (typeof this.yPlayer.stopVideo === "function" && typeof this.yPlayer.destroy === "function") { + this.yPlayer.stopVideo(); + this.yPlayer.destroy(); + this.youtubeIsReady = false; + this.yPlayer = null; + } + } + } + + delete() + { + if(this.audioPlayer != null){ + this.audioPlayer.pause(); + this.audioPlayer.stop(); + this.audioPlayer.unload(); + } + this.audioPlayer = null; + $("#" + this.div_id).remove(); + } + + updateVolume(dd,maxd) + { + var d_max = maxd; + var d_now = dd; + + var vol = 0; + + var distance = (d_now / d_max); + + if (distance < 1) + { + distance = distance * 100; + var far_away = 100 - distance; + vol = (this.max_volume / 100) * far_away;; + this.setVolume(vol); + this.isMuted_ = false; + } + else + { + this.setVolume(0); + this.isMuted_ = true; + } + } + + play() + { + /* + if(this.IsTextToSpeech()){ + this.speechSynthMessage.lang = this.textToReadLang; + this.speechSynthMessage.text = this.textToRead; + window.speechSynthesis.speak(this.speechSynthMessage); + return; + } + */ + + if(!this.isYoutube) + { + if(this.audioPlayer != null){ + this.audioPlayer.play(); + } + } + else + { + if(this.youtubeIsReady){ + this.yPlayer.playVideo(); + } + } + } + pause() + { + if(!this.isYoutube) + { + if(this.audioPlayer != null) this.audioPlayer.pause(); + } + else + { + if(this.youtubeIsReady) this.yPlayer.pauseVideo(); + } + } + + resume() + { + if(!this.isYoutube) + { + if(this.audioPlayer != null) this.audioPlayer.play(); + } + else + { + if(this.youtubeIsReady) this.yPlayer.playVideo(); + } + } + + isMuted() + { + return this.isMuted_; + } + + mute() + { + this.isMuted_ = true; + this.setVolume(0) + } + + unmute() + { + this.isMuted_ = false; + this.setVolume(this.getVolume()) + } + + unmuteSilent() + { + this.isMuted_ = false; + } + + setTimeStamp(time) + { + if(!this.isYoutube) + { + this.audioPlayer.seek(time); + } + else + { + this.yPlayer.seekTo(time); + } + } + + isPlaying() + { + if(this.isYoutube) return this.youtubeIsReady && this.yPlayer.getPlayerState() == 1; + else return this.audioPlayer != null && this.audioPlayer.playing(); + } +} diff --git a/[extras]/xsound/html/scripts/functions.js b/[extras]/xsound/html/scripts/functions.js new file mode 100644 index 0000000..8da3be7 --- /dev/null +++ b/[extras]/xsound/html/scripts/functions.js @@ -0,0 +1,160 @@ +function getYoutubeUrlId(url) +{ + var videoId = ""; + if( url.indexOf("youtube") !== -1 ){ + var urlParts = url.split("?v="); + videoId = urlParts[1].substring(0,11); + } + + if( url.indexOf("youtu.be") !== -1 ){ + var urlParts = url.replace("//", "").split("/"); + videoId = urlParts[1].substring(0,11); + } + return videoId; +} + +function isReady(divId, howler){ + if(howler){ + for (var soundName in soundList) + { + var sound = soundList[soundName]; + if(sound.loaded() == false){ + + sound.setLoaded(true); + + var time = 0; + if(sound.getAudioPlayer() != null){time = sound.getAudioPlayer()._duration;} + if(sound.isDynamic()) sound.setVolume(0); + if(!sound.isDynamic()) sound.setVolume(sound.getVolume()); + + $.post('https://xsound/data_status', JSON.stringify( + { + time: time, + type: "maxDuration", + id: sound.getName(), + })); + + $.post('https://xsound/events', JSON.stringify( + { + type: "onPlay", + id: sound.getName(), + })); + + addToCache(); + updateVolumeSounds(); + break; + } + } + return; + } + for (var soundName in soundList) + { + var sound = soundList[soundName]; + if(sound.getDivId() === divId){ + var time = 0; + if(sound.getYoutubePlayer() != null){time = sound.getYoutubePlayer().getDuration();} + if(sound.isDynamic()) sound.setVolume(0); + sound.setLoaded(true); + + $.post('https://xsound/data_status', JSON.stringify( + { + time: time, + type: "maxDuration", + id: sound.getName(), + })); + + $.post('https://xsound/events', JSON.stringify( + { + type: "onPlay", + id: sound.getName(), + })); + + sound.isYoutubeReady(true); + + addToCache(); + updateVolumeSounds(); + + if(!sound.isDynamic()) sound.setVolume(sound.getVolume()); + break; + } + } +} + +function isLooped(divId){ + for (var soundName in soundList) + { + var sound = soundList[soundName]; + if(sound.getDivId() === divId && sound.isLoop()){ + sound.setTimeStamp(0); + sound.play(); + + $.post('https://xsound/data_status', JSON.stringify({ type: "finished",id: soundName })); + $.post('https://xsound/events', JSON.stringify( + { + type: "onEnd", + id: sound.getName(), + })); + + var time = 0; + if(sound.getAudioPlayer() != null){time = sound.getAudioPlayer()._duration;} + if(sound.getYoutubePlayer() != null){time = sound.getYoutubePlayer().getDuration();} + $.post('https://xsound/events', JSON.stringify( + { + type: "resetTimeStamp", + id: sound.getName(), + time: time, + })); + break; + } + } +} + +function ended(divId){ + if(divId == null) + { + for (var soundName in soundList) + { + var sound = soundList[soundName]; + if(!sound.isPlaying()) + { + $.post('https://xsound/data_status', JSON.stringify({ type: "finished",id: soundName })); + $.post('https://xsound/events', JSON.stringify( + { + type: "onEnd", + id: sound.getName(), + })); + if(sound.isLoop()){ + var time = 0; + if(sound.getAudioPlayer() != null){time = sound.getAudioPlayer()._duration;} + if(sound.getYoutubePlayer() != null){time = sound.getYoutubePlayer().getDuration();} + $.post('https://xsound/events', JSON.stringify( + { + type: "resetTimeStamp", + id: sound.getName(), + time: time, + })); + + sound.setTimeStamp(0); + sound.play(); + } + break; + } + } + } + else + { + for (var soundName in soundList) + { + var sound = soundList[soundName]; + if(sound.getDivId() === divId && !sound.isLoop()){ + $.post('https://xsound/data_status', JSON.stringify({ type: "finished",id: soundName })); + $.post('https://xsound/events', JSON.stringify( + { + type: "onEnd", + id: sound.getName(), + })); + break; + } + } + } +} diff --git a/[extras]/xsound/html/scripts/listener.js b/[extras]/xsound/html/scripts/listener.js new file mode 100644 index 0000000..566d286 --- /dev/null +++ b/[extras]/xsound/html/scripts/listener.js @@ -0,0 +1,269 @@ +var soundList = []; +var closeToPlayer = []; +var isMutedAll = false; + +var playerPos = [-90000,-90000,-90000]; +$(function(){ + + $.post('https://xsound/init'); + + window.addEventListener('message', function(event) { + var item = event.data; + switch(item.status) + { + case "init": + setInterval(updateVolumeSounds, item.time); + break; + case "position": + playerPos = [item.x,item.y,item.z]; + break; + + case "volume": + var sound = soundList[item.name]; + if(sound != null) + { + sound.setVolume(item.volume); + sound.setMaxVolume(item.volume); + } + break; + + case "timestamp": + var sound = soundList[item.name]; + if(sound != null) + { + sound.setTimeStamp(item.timestamp); + } + break; + + case "max_volume": + var sound = soundList[item.name]; + if(sound != null) + { + sound.setMaxVolume(item.volume); + } + break; + /* + case "textSpeech": + var sound = soundList[item.name]; + + if(sound != null) + { + sound.destroyYoutubeApi(); + sound.delete(); + sound = null; + } + + var sd = new SoundPlayer(); + sd.IsTextToSpeech(true) + sd.setName(item.name); + sd.setTextToSpeech(item.text) + sd.setTextToSpeechLang(item.lang) + sd.setDynamic(item.dynamic); + sd.setLocation(item.x,item.y,item.z); + sd.create(); + + sd.setVolume(item.volume); + sd.play(); + soundList[item.name] = sd; + break; + */ + case "url": + var sound = soundList[item.name]; + + if(sound != null) + { + sound.destroyYoutubeApi(); + sound.delete(); + sound = null; + } + + var sd = new SoundPlayer(); + sd.setName(item.name); + sd.setSoundUrl(item.url); + sd.setDynamic(item.dynamic); + sd.setLocation(item.x,item.y,item.z); + sd.setLoop(item.loop) + sd.create(); + sd.setVolume(item.volume); + sd.play(); + soundList[item.name] = sd; + break; + + case "distance": + var sound = soundList[item.name]; + if(sound != null) + { + sound.setDistance(item.distance); + } + break; + + case "play": + var sound = soundList[item.name]; + if(sound != null) + { + sound.delete(); + sound.create(); + sound.setVolume(item.volume); + sound.setDynamic(item.dynamic); + sound.setLocation(item.x,item.y,item.z); + sound.play(); + } + break; + + case "soundPosition": + var sound = soundList[item.name]; + if(sound != null) + { + sound.setLocation(item.x,item.y,item.z); + } + break; + + case "resume": + var sound = soundList[item.name]; + if(sound != null) + { + sound.resume(); + } + break; + + case"pause": + var sound = soundList[item.name]; + if(sound != null) + { + sound.pause(); + } + break; + + case "delete": + var sound = soundList[item.name]; + if(sound != null) + { + sound.destroyYoutubeApi(); + sound.delete(); + delete soundList[item.name]; + } + break; + case "repeat": + var sound = soundList[item.name]; + if(sound != null) + { + sound.setTimeStamp(0); + sound.play(); + } + break; + case "changedynamic": + var sound = soundList[item.name]; + if(sound != null) + { + sound.unmute() + sound.setDynamic(item.bool); + sound.setVolume(sound.getMaxVolume()); + } + break; + case "changeurl": + var sound = soundList[item.name]; + if(sound != null) + { + sound.destroyYoutubeApi(); + sound.delete(); + sound.setSoundUrl(item.url); + sound.setLoaded(false); + sound.create(); + + sound.play(); + } + break; + case "loop": + var sound = soundList[item.name]; + if(sound != null) + { + sound.setLoop(item.loop); + } + break; + case "unmuteAll": + isMutedAll = false; + for (var soundName in soundList) + { + sound = soundList[soundName]; + if(sound.isDynamic()){ + sound.unmuteSilent(); + } + } + updateVolumeSounds(); + break; + case "muteAll": + isMutedAll = true; + for (var soundName in soundList) + { + sound = soundList[soundName]; + if(sound.isDynamic()){ + sound.mute(); + } + } + break; + } + }) +}); + +function Between(loc1,loc2) +{ + var deltaX = loc1[0] - loc2[0]; + var deltaY = loc1[1] - loc2[1]; + var deltaZ = loc1[2] - loc2[2]; + + var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ); + return distance; +} + +function addToCache() +{ + closeToPlayer = []; + if(!isMutedAll){ + var sound = null; + for (var soundName in soundList) + { + sound = soundList[soundName]; + if(sound.isDynamic()) + { + var distance = Between(playerPos,sound.getLocation()); + var distance_max = sound.getDistance(); + if(distance < distance_max + 40) + { + closeToPlayer[soundName] = soundName; + } + else + { + if(sound.loaded()) { + sound.mute(); + } + } + } + } + } +} + +setInterval(addToCache, 1000); + +function updateVolumeSounds() +{ + if(!isMutedAll){ + var sound = null; + for (var name in closeToPlayer) + { + sound = soundList[name]; + if(sound != null){ + if(sound.isDynamic()) + { + var distance = Between(playerPos,sound.getLocation()); + var distance_max = sound.getDistance(); + if(distance < distance_max) + { + sound.updateVolume(distance,distance_max); + continue; + } + sound.mute(); + } + } + } + } +} \ No newline at end of file diff --git a/[extras]/xsound/html/sounds/.gitkeep b/[extras]/xsound/html/sounds/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/[extras]/xsound/license.txt b/[extras]/xsound/license.txt new file mode 100644 index 0000000..9300e70 --- /dev/null +++ b/[extras]/xsound/license.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 Xogy + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/[extras]/xsound/readme.md b/[extras]/xsound/readme.md new file mode 100644 index 0000000..5279346 --- /dev/null +++ b/[extras]/xsound/readme.md @@ -0,0 +1,197 @@ +😍 Checkout our store for more amazing resources https://store.rcore.cz/
+🎵 Resources using this API https://store.rcore.cz/category/music + +# Improved audio library for FiveM + +Can work with API interact sound
+Just make sure you take all sounds from interact
+sound and move them to xsound/html/sounds + +Thanks to
+https://github.com/plunkettscott
+for awesome api
+https://github.com/plunkettscott/interact-sound
+ +### SoundSystem functions + +**1. Functions (client side)** + +------------ + +### Playing sound + +------------ + + - `PlayUrl(name, URL, volume, loop, options)`
Will play sound from URL (can be heard everywhere)
argument loop and options are optional, doesn't have to be used. + + - `PlayUrlPos(name, url, volume, Vector3 vec, loop, options)`
Will play sound from url at x,y,z location
argument loop and options are optional, doesn't have to be used. + + options list + - onPlayStart + - onPlayEnd + - onLoading + - onPlayPause + - onPlayResume + +------------ + +### Manipulation with sound + +------------ + + - `Position(name, Vector3 vec)`
Will update location of sound + + - `Distance(name, newDistance)`
Will set new playing distance from location + + - `Destroy(name)`
Will destroy sound + + - `Pause(name)`
Will pause sound + + - `Resume(name)`
Will resume sound + + - `setVolume(name,volume)` volume is from 0.0 to 1.0
Will set a new value to volume. Should be used for non 3D sound + + - `setVolumeMax(name,volume)` volume is from 0.0 to 1.0
will set new value to max volume. Should be used only for 3D sound + + - `setTimeStamp(name, time)` will set a new timestamp. + + - `setSoundURL(name, url)` will set new URL to sound (will play whenever changed) + + - `repeatSound(name)` will play again the saved sound + + - `destroyOnFinish(name, bool)` true = destroy on end / false = do not destroy on end + + - `setSoundLoop(name, bool)` will set a new value to loop + + - `setSoundDynamic(name, bool)` will set if the sound is 3D / 3D = true + +------------ + +### Effects on sound + +------------ + + - `fadeOut(name, time)` + - `fadeIn(name, time, volume)` + +------------ + +### Events (client side only) + +------------ + + - `onPlayStart(name, function)` +
This event will trigger after the sound +
is loaded and start playing in game. + + - `onPlayEnd(name, function)` +
This event will be triggered after sound end. + + - `onLoading(name, function)` +
This event will be triggered when the sound start loading. + - `onPlayPause(name, function)` +
This event will be triggered whenever you pause sound. + - `onPlayResume(name, function)` +
This event will be triggered whenever you resume sound. + +------------ + +### Getting info about sound + +------------ + - `soundExists(name)`
Will return true/false if sound exists + + - `isPaused(name)`
Will return true/false if song is paused + + - `isPlaying(name)`
Will return true/false if song is playing + + - `isLooped(name)`
Will return true/false if sound is looped + + - `getDistance(name)`
Will return distance in Integer + + - `getVolume(name)`
Will return current volume of music. + + - `getPosition(name)`
Will return vector3 + + - `isDynamic(name)`
Will return if sound is 3D or 2D (3D = true, 2D = false) + + - `getTimeStamp(name)`
returns current timestamp + + - `getMaxDuration(name)`
returns max duration of sound + + - `getLink(name)`
Will return url link + + - `isPlayerInStreamerMode()`
will return if player got streamer mode enabled. + + - `getAllAudioInfo()`
Will return array of all sound + + - `isPlayerCloseToAnySound()`
will return true if player is close to any sound. + + - `getInfo(name)`
Will return an array with info of the sound... +```LUA +{ + volume, -- value from 0.0 to 1.0 + url , -- sound url + id, -- id + position, -- will be nil if position isnt set. + distance, -- distance in integer + playing, -- true/false + paused, -- true/false + loop, -- true/false + isDynamic, -- true/false + timeStamp, -- returns current timestamp + maxDuration, -- returns max duration of sound + destroyOnFinish, -- default value is true means after its finish it will destroy it self +} +``` +------------ + +**1. Functions (Server side)** + +------------ + +### Playing sound + +------------ + - `PlayUrl(source, name, URL, volume, loop)`
Will play sound from URL (can be heard everywhere) + + - `PlayUrlPos(source, name, url, volume, Vector3 vec, loop)`
Will play sound from url at x,y,z location + +------------ + +### Manipulation with sound + +------------ + - -1 for source work as well + + - `Position(source, name, Vector3 vec)`
Will update location of sound + + - `Distance(source, name, newDistance)`
Will set new playing distance from location + + - `Destroy(source, name)`
Will destroy sound + + - `Pause(source, name)`
Will pause sound + + - `Resume(source, name)`
Will resume sound + + - `setVolume(source, name,volume)` volume is from 0.0 to 1.0
Will set a new value to volume. Should be used for non 3D sound + + - `setVolumeMax(source, name,volume)` volume is from 0.0 to 1.0
will set new value to max volume. Should be used only for 3D sound + + - `setTimeStamp(source ,name, time)` will set a new timestamp. +
TIMESTAMP is in a seconds only ! +------------ + +Showcase how it can stream sound at game + +https://www.youtube.com/watch?v=zyZmF5bRSA4 + +https://www.youtube.com/watch?v=19Q2GVYElSE + +Showcase what I did with my API + +#These are just a showcase! I will not share them.... + +https://www.youtube.com/watch?v=OOf6PZFpfkI + +https://www.youtube.com/watch?v=JRTVga_FwGw diff --git a/[extras]/xsound/server/emulator/interact_sound/server.lua b/[extras]/xsound/server/emulator/interact_sound/server.lua new file mode 100644 index 0000000..e3cb44e --- /dev/null +++ b/[extras]/xsound/server/emulator/interact_sound/server.lua @@ -0,0 +1,19 @@ +RegisterServerEvent('InteractSound_SV:PlayOnOne') +AddEventHandler('InteractSound_SV:PlayOnOne', function(clientNetId, soundFile, soundVolume) + TriggerClientEvent('InteractSound_CL:PlayOnOne', clientNetId, soundFile, soundVolume) +end) + +RegisterServerEvent('InteractSound_SV:PlayOnSource') +AddEventHandler('InteractSound_SV:PlayOnSource', function(soundFile, soundVolume) + TriggerClientEvent('InteractSound_CL:PlayOnOne', source, soundFile, soundVolume) +end) + +RegisterServerEvent('InteractSound_SV:PlayOnAll') +AddEventHandler('InteractSound_SV:PlayOnAll', function(soundFile, soundVolume) + TriggerClientEvent('InteractSound_CL:PlayOnAll', -1, soundFile, soundVolume) +end) + +RegisterServerEvent('InteractSound_SV:PlayWithinDistance') +AddEventHandler('InteractSound_SV:PlayWithinDistance', function(maxDistance, soundFile, soundVolume) + TriggerClientEvent('InteractSound_CL:PlayWithinDistance', -1, source, maxDistance, soundFile, soundVolume) +end) \ No newline at end of file diff --git a/[extras]/xsound/server/exports/manipulation.lua b/[extras]/xsound/server/exports/manipulation.lua new file mode 100644 index 0000000..0288e05 --- /dev/null +++ b/[extras]/xsound/server/exports/manipulation.lua @@ -0,0 +1,68 @@ +function Position(source, name_, pos) + TriggerClientEvent("xsound:stateSound", source, "position", { + soundId = name_, + position = pos, + }) +end + +exports('Position', Position) + +function Distance(source, name_, distance_) + TriggerClientEvent("xsound:stateSound", source, "distance", { + soundId = name_, + distance = distance_, + }) +end + +exports('Distance', Distance) + +function Destroy(source, name_) + TriggerClientEvent("xsound:stateSound", source, "destroy", { + soundId = name_, + }) +end + +exports('Destroy', Destroy) + +function Pause(source, name_) + TriggerClientEvent("xsound:stateSound", source, "pause", { + soundId = name_, + }) +end + +exports('Pause', Pause) + +function Resume(source, name_) + TriggerClientEvent("xsound:stateSound", source, "resume", { + soundId = name_, + }) +end + +exports('Resume', Resume) + +function setVolume(source, name_, vol) + TriggerClientEvent("xsound:stateSound", source, "volume", { + soundId = name_, + volume = vol, + }) +end + +exports('setVolume', setVolume) + +function setTimeStamp(source, name_, time_) + TriggerClientEvent("xsound:stateSound", source, "timestamp", { + soundId = name_, + time = time_ + }) +end + +exports('setTimeStamp', setTimeStamp) + +function destroyOnFinish(id, bool) + TriggerClientEvent("xsound:stateSound", source, "destroyOnFinish", { + soundId = id, + value = bool + }) +end + +exports('destroyOnFinish', destroyOnFinish) \ No newline at end of file diff --git a/[extras]/xsound/server/exports/play.lua b/[extras]/xsound/server/exports/play.lua new file mode 100644 index 0000000..9437468 --- /dev/null +++ b/[extras]/xsound/server/exports/play.lua @@ -0,0 +1,47 @@ +function PlayUrl(source, name_, url_, volume_, loop_) + TriggerClientEvent("xsound:stateSound", source, "play", { + soundId = name_, + url = url_, + volume = volume_, + loop = loop_ + }) +end + +exports('PlayUrl', PlayUrl) + +function PlayUrlPos(source, name_, url_, volume_, pos, loop_) + TriggerClientEvent("xsound:stateSound", source, "playpos", { + soundId = name_, + position = pos, + url = url_, + volume = volume_, + loop = loop_ + }) +end + +exports('PlayUrlPos', PlayUrlPos) + +--function TextToSpeech(source, name_, lang, text, volume_, loop_) +-- TriggerClientEvent("xsound:stateSound", source, "texttospeech", { +-- soundId = name_, +-- url = text, +-- lang = lang, +-- volume = volume_, +-- loop = loop_ +-- }) +--end +-- +--exports('TextToSpeech', TextToSpeech) +-- +--function TextToSpeechPos(source, name_, lang, text, volume_, pos, loop_) +-- TriggerClientEvent("xsound:stateSound", source, "texttospeechpos", { +-- soundId = name_, +-- lang = lang, +-- position = pos, +-- url = text, +-- volume = volume_, +-- loop = loop_ +-- }) +--end +-- +--exports('TextToSpeechPos', TextToSpeechPos) \ No newline at end of file diff --git a/credits.md b/credits.md index 9b8aeb3..ed8739e 100644 --- a/credits.md +++ b/credits.md @@ -82,4 +82,6 @@ Einige Ressourcen wurden verändert, um besser mit dem Template Server zu arbeit - https://github.com/utkuali/datacrack - https://forum.cfx.re/t/free-esx-pilot-job/4916778 - https://forum.cfx.re/t/release-nc-loadingscreen-v1-0/4882120 -- https://github.com/MIAgimir/Ox_Inventory-ItemsTemplate/releases \ No newline at end of file +- https://github.com/MIAgimir/Ox_Inventory-ItemsTemplate/releases +- https://github.com/Xogy/xsound +- https://forum.cfx.re/t/standalone-free-nass-carplay/5124976 \ No newline at end of file