├── fxmanifest.lua ├── README.md ├── LICENSE ├── server.lua ├── config.lua └── client.lua /fxmanifest.lua: -------------------------------------------------------------------------------- 1 | fx_version "cerulean" 2 | game "gta5" 3 | 4 | description 'Baspel' 5 | version '1.0.0' 6 | 7 | lua54 'yes' 8 | 9 | client_scripts { 10 | 'client.lua' 11 | } 12 | 13 | server_scripts { 14 | 'server.lua' 15 | } 16 | 17 | shared_scripts { 18 | '@es_extended/imports.lua', 19 | '@ox_lib/init.lua', 20 | 'config.lua' 21 | } 22 | 23 | dependencies { 24 | 'es_extended', 25 | 'ox_lib', 26 | 'xsound' 27 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DJ Script Overview 2 | - Its a DJ Script using ox_lib for menu (changeable) and xSound for sync music. You can easly copy YouTube URL and paste into menu. The music can be pausable and resumable, you can easly change volume too from 0.01 to 1. 3 | 4 | ![dj_baspel_menu](https://user-images.githubusercontent.com/77331512/182036590-0ff55a84-d5c8-403d-a149-f420a738a63a.png) 5 | # Dependency 6 | - xSound: https://github.com/Xogy/xsound 7 | - ox_lib: https://github.com/overextended/ox_lib 8 | # Optional 9 | - ox_target: https://github.com/overextended/ox_target 10 | # Usage 11 | - Simply copy coords from your game and past'em into config.lua 12 | # Features 13 | - You can add as many spots as you want 14 | - You can change radius 15 | - Music Server synced through xsound 16 | - Currently supporting ESX 17 | - Everything is easily configurable 18 | - Can be modified 19 | - Supports ox_target (optional) 20 | - You can set each location for job only (optional) 21 | - You can make your own playlist from static URL links in config 22 | # Preview 23 | - https://youtu.be/2jjH-G78fJw 24 | - For more work: https://discord.gg/PpAHBCMW97 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Baspel 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /server.lua: -------------------------------------------------------------------------------- 1 | local xSound = exports.xsound 2 | 3 | RegisterNetEvent('dj_baspel:playMusic', function (YoutubeURL) 4 | for k, v in pairs(Config.Locations) do 5 | local defaultVolume = Config.DefaultVolume 6 | local src = source 7 | local ped = GetPlayerPed(src) 8 | local coords = GetEntityCoords(ped) 9 | local dist = #(coords - v.coords) 10 | if dist < 3 then 11 | xSound:PlayUrlPos(-1, v.name, YoutubeURL, defaultVolume, coords) 12 | xSound:Distance(-1, v.name, v.radius) 13 | v.isPlaying = true 14 | if Config.Debug then 15 | print('DEBUG dj_baspel | The music started playing at the coordinates: '..coords..' in radius: '..v.radius) 16 | end 17 | end 18 | end 19 | end) 20 | 21 | RegisterNetEvent('dj_baspel:stopMusic', function() 22 | for k, v in pairs(Config.Locations) do 23 | local src = source 24 | local ped = GetPlayerPed(src) 25 | local coords = GetEntityCoords(ped) 26 | local dist = #(coords - v.coords) 27 | if dist < 3 then 28 | if v.isPlaying then 29 | v.isPlaying = false 30 | xSound:Destroy(-1, v.name) 31 | if Config.Debug then 32 | print('DEBUG dj_baspel | Music turned off at coordinates: '..coords) 33 | end 34 | end 35 | end 36 | end 37 | end) 38 | 39 | RegisterNetEvent('dj_baspel:pauseMusic', function() 40 | for k, v in pairs(Config.Locations) do 41 | local src = source 42 | local ped = GetPlayerPed(src) 43 | local coords = GetEntityCoords(ped) 44 | local dist = #(coords - v.coords) 45 | if dist < 3 then 46 | if v.isPlaying then 47 | v.isPlaying = false 48 | xSound:Pause(-1, v.name) 49 | if Config.Debug then 50 | print('DEBUG dj_baspel | The music paused at the coordinates: '..coords) 51 | end 52 | end 53 | end 54 | end 55 | end) 56 | 57 | RegisterNetEvent('dj_baspel:resumeMusic', function() 58 | for k, v in pairs(Config.Locations) do 59 | local src = source 60 | local ped = GetPlayerPed(src) 61 | local coords = GetEntityCoords(ped) 62 | local dist = #(coords - v.coords) 63 | if dist < 3 then 64 | if not v.isPlaying then 65 | v.isPlaying = true 66 | xSound:Resume(-1, v.name) 67 | if Config.Debug then 68 | print('DEBUG dj_baspel | Music resumed at coordinates: '..coords) 69 | end 70 | end 71 | end 72 | end 73 | end) 74 | 75 | RegisterNetEvent('dj_baspel:changeVolume', function(volume) 76 | for k, v in pairs(Config.Locations) do 77 | local src = source 78 | local ped = GetPlayerPed(src) 79 | local coords = GetEntityCoords(ped) 80 | local dist = #(coords - v.coords) 81 | if dist < 3 then 82 | if not tonumber(volume) then return end 83 | if v.isPlaying then 84 | xSound:setVolume(-1, v.name, volume) 85 | if Config.Debug then 86 | print('DEBUG dj_baspel | Music volume changed to: '..volume) 87 | end 88 | end 89 | end 90 | end 91 | end) 92 | -------------------------------------------------------------------------------- /config.lua: -------------------------------------------------------------------------------- 1 | Config = {} 2 | 3 | --- Common settings --- 4 | Config.Debug = true -- If you want debug in console 5 | Config.DefaultVolume = 0.1 -- Accepted values are 0.01 - 1 6 | Config.Distance = 5.0 -- Dont touch this 7 | 8 | --- Target system --- 9 | Config.ox_target = false -- If you want to use qtarget you need also polyzone script 10 | 11 | --- Locations --- 12 | Config.Locations = { 13 | { 14 | onlyJob = true, -- If false then everyone can access the location 15 | job = 'vanilla', -- if onJob true, you have to write the name of that job here like 'vanilla' 16 | name = 'Vanilla', -- Name of zone 17 | coords = vec3(120.5638, -1280.9021, 29.4805), -- Coordinates where menu will appear if you are nearby 18 | radius = 30, -- Playing music distance (radius) 19 | distance = 2.5, -- Menu appear distance 20 | isPlaying = false -- Dont touch this!!!! 21 | }, 22 | { 23 | onlyJob = false, 24 | job = 'nil', 25 | name = 'Bahama', 26 | coords = vec3(-1382.05, -614.72, 31.5), 27 | radius = 30, 28 | distance = 2.5, 29 | isPlaying = false 30 | }, 31 | { 32 | onlyJob = false, 33 | job = 'nil', 34 | name = 'Galaxy', 35 | coords = vec3(376.19, 275.45, 92.39), 36 | radius = 30, 37 | distance = 2.5, 38 | isPlaying = false 39 | }, 40 | { 41 | onlyJob = false, 42 | job = 'nil', 43 | name = 'Tequila', 44 | coords = vec3(-562.11, 281.66, 85.6764), 45 | radius = 30, 46 | distance = 2.5, 47 | isPlaying = false 48 | } 49 | } 50 | 51 | Config.Language = { 52 | ['openMenu'] = '[E] - Open a DJ Menu', 53 | ['titleMenu'] = '💿 | DJ Pult', 54 | ['playSong'] = '🎶 | Play a song', 55 | ['playSongDesc'] = 'Enter a youtube URL', 56 | ['pauseMusic'] = '⏸️ | Pause Music', 57 | ['pauseMusicDesc'] = 'Pause a currently playing music', 58 | ['resumeMusic'] = '▶️ | Resume Music', 59 | ['resumeMusicDesc'] = 'Resume playing paused music', 60 | ['changeVolume'] = '🔈 | Change Volume', 61 | ['changeVolumeDesc'] = 'Change volume of song', 62 | ['stopMusic'] = '❌ | Turn off music', 63 | ['stopMusicDesc'] = 'Stop the music & choose a new song', 64 | ['songSel'] = 'Song Selection', 65 | ['url'] = 'Youtube URL', 66 | ['musicVolume'] = 'Music Volume', 67 | ['musicVolumeNm'] = 'Min: 0.01 - Max: 1', -- Pls dont change numbers (0.01 - 1) 68 | 69 | --- Playlist --- 70 | ['playlistMenu'] = '🎶 | DJ Pult Playlist', 71 | ['playlistDesc'] = 'Play a song from playlist', 72 | ['playlistMenuTitle'] = '🎶 | Play a song' 73 | } 74 | 75 | Config.Playlist = { 76 | --- First Song 77 | ['first'] = '💿 | Mess', -- Name of first song 78 | ['desc_first'] = 'Description of the song', -- Description of the song 79 | ['music_first_id'] = 'https://www.youtube.com/watch?v=-Kjrf-pxQc4', -- Url from YT 80 | 81 | --- Second Song --- 82 | ['second'] = '💿 | Shiver', -- Name of second song 83 | ['desc_second'] = 'Description of the song', 84 | ['music_second_id'] = 'https://www.youtube.com/watch?v=NdUNtHqY5r8', 85 | 86 | --- Third Song --- 87 | ['third'] = '💿 | Good With It', -- Name of third song 88 | ['desc_third'] = 'Description of the song', 89 | ['music_third_id'] = 'https://www.youtube.com/watch?v=RInypZYiiDM', 90 | 91 | --- Fourth Song --- 92 | ['fourth'] = '💿 | Back To You', 93 | ['desc_fourth'] = 'Description of the song', 94 | ['music_fourth_id'] = 'https://www.youtube.com/watch?v=rrzHAoA-oRI', 95 | 96 | --- Fifth Song --- 97 | ['fifth'] = '💿 | Curse', 98 | ['desc_fifth'] = 'Description of the song', 99 | ['music_fifth_id'] = 'https://www.youtube.com/watch?v=XsmuiDRKbDk' 100 | } 101 | -------------------------------------------------------------------------------- /client.lua: -------------------------------------------------------------------------------- 1 | ----------------------------------------------------------------------------------- 2 | local LastZone, CurrentAction, hasAlreadyEnteredMarker, job = nil, nil, false, nil 3 | local xSound = exports.xsound 4 | local ox_target = exports.ox_target 5 | ----------------------------------------------------------------------------------- 6 | 7 | RegisterNetEvent('dj_baspel:createMusicMenu', function() 8 | lib.registerContext({ 9 | id = 'music_menu', 10 | title = Config.Language['titleMenu'], 11 | options = { 12 | { 13 | title = Config.Language['playSong'], 14 | description = Config.Language['playSongDesc'], 15 | arrow = false, 16 | event = 'dj_baspel:playMusicMenu', 17 | }, 18 | { 19 | title = Config.Language['playlistMenu'], 20 | description = Config.Language['playlistDesc'], 21 | arrow = true, 22 | menu = 'playlist_menu', 23 | }, 24 | { 25 | title = Config.Language['pauseMusic'], 26 | description = Config.Language['pauseMusicDesc'], 27 | arrow = false, 28 | serverEvent = 'dj_baspel:pauseMusic', 29 | }, 30 | { 31 | title = Config.Language['resumeMusic'], 32 | description = Config.Language['resumeMusicDesc'], 33 | arrow = false, 34 | serverEvent = 'dj_baspel:resumeMusic', 35 | }, 36 | { 37 | title = Config.Language['changeVolume'], 38 | description = Config.Language['changeVolumeDesc'], 39 | arrow = false, 40 | event = 'dj_baspel:changeVolumeMenu', 41 | }, 42 | { 43 | title = Config.Language['stopMusic'], 44 | description = Config.Language['stopMusicDesc'], 45 | arrow = false, 46 | serverEvent = 'dj_baspel:stopMusic', 47 | }, 48 | }, 49 | { 50 | id = 'playlist_menu', 51 | title = Config.Language['playlistMenuTitle'], 52 | options = { 53 | { 54 | title = Config.Playlist['first'], 55 | description = Config.Playlist['desc_first'], 56 | args = {music = Config.Playlist['music_first_id']}, 57 | event = 'dj_baspel:playMusicFromPlaylist' 58 | }, 59 | { 60 | title = Config.Playlist['second'], 61 | description = Config.Playlist['desc_second'], 62 | args = {music = Config.Playlist['music_second_id']}, 63 | event = 'dj_baspel:playMusicFromPlaylist' 64 | }, 65 | { 66 | title = Config.Playlist['third'], 67 | description = Config.Playlist['desc_third'], 68 | args = {music = Config.Playlist['music_third_id']}, 69 | event = 'dj_baspel:playMusicFromPlaylist' 70 | }, 71 | { 72 | title = Config.Playlist['fourth'], 73 | description = Config.Playlist['desc_fourth'], 74 | args = {music = Config.Playlist['music_fourth_id']}, 75 | event = 'dj_baspel:playMusicFromPlaylist' 76 | }, 77 | { 78 | title = Config.Playlist['fifth'], 79 | description = Config.Playlist['desc_fifth'], 80 | args = {music = Config.Playlist['music_fifth_id']}, 81 | event = 'dj_baspel:playMusicFromPlaylist' 82 | } 83 | } 84 | } 85 | }) 86 | lib.showContext('music_menu') 87 | end) 88 | 89 | RegisterNetEvent('dj_baspel:playMusicFromPlaylist', function (data) 90 | local input = data.music 91 | if input then 92 | TriggerServerEvent('dj_baspel:playMusic', input) 93 | end 94 | end) 95 | 96 | RegisterNetEvent('dj_baspel:playMusicMenu', function (YoutubeURL) 97 | local input = lib.inputDialog(Config.Language['songSel'], {Config.Language['url']}) 98 | if input then 99 | local YoutubeURL = input[1] 100 | TriggerServerEvent('dj_baspel:playMusic', YoutubeURL) 101 | end 102 | end) 103 | 104 | RegisterNetEvent('dj_baspel:changeVolumeMenu', function () 105 | local input = lib.inputDialog(Config.Language['musicVolume'], {Config.Language['musicVolumeNm']}) 106 | if input then 107 | local volume = input[1] 108 | TriggerServerEvent('dj_baspel:changeVolume', volume) 109 | end 110 | end) 111 | 112 | CreateThread(function() 113 | if not Config.ox_target then 114 | while true do 115 | local sleep = 1500 116 | local playerCoords, inLocation, currentZone = GetEntityCoords(PlayerPedId()), false, false 117 | 118 | for i=1, #Config.Locations do 119 | local dist = #(playerCoords - Config.Locations[i].coords) 120 | if dist <= Config.Distance then 121 | sleep = 0 122 | if dist <= Config.Locations[i].distance and Config.Locations[i].onlyJob then 123 | inLocation, currentZone, job = true, i, Config.Locations[i].job 124 | elseif dist <= Config.Locations[i].distance and not Config.Locations[i].onlyJob then 125 | inLocation, currentZone, job = true, i, nil 126 | end 127 | end 128 | end 129 | 130 | if (inLocation and not hasAlreadyEnteredMarker and ESX.PlayerData.job.name == job) or (inLocation and LastZone ~= currentZone and ESX.PlayerData.job.name == job) then 131 | hasAlreadyEnteredMarker, LastZone = true, currentZone 132 | CurrentAction = 'musicMenu' 133 | lib.showTextUI(Config.Language['openMenu']) 134 | elseif (inLocation and not hasAlreadyEnteredMarker and job == nil) or (inLocation and LastZone ~= currentZone and job == nil) then 135 | hasAlreadyEnteredMarker, LastZone = true, currentZone 136 | CurrentAction = 'musicMenu' 137 | lib.showTextUI(Config.Language['openMenu']) 138 | end 139 | 140 | if not inLocation and hasAlreadyEnteredMarker then 141 | hasAlreadyEnteredMarker = false 142 | sleep = 1000 143 | CurrentAction = nil 144 | lib.hideTextUI() 145 | end 146 | Wait(sleep) 147 | end 148 | else 149 | for k, v in pairs(Config.Locations) do 150 | if v.onlyJob then 151 | ox_target:addSphereZone({ 152 | coords = v.coords, 153 | radius = 1, 154 | debug = drawZones, 155 | options = { 156 | { 157 | name = 'sphere:dj', 158 | event = 'dj_baspel:createMusicMenu', 159 | icon = 'fa fa-music', 160 | label = 'DJ Pult', 161 | canInteract = function(entity, distance, coords, name) 162 | if v.onlyJob and ESX.PlayerData.job.name == v.job then 163 | return true 164 | end 165 | end 166 | } 167 | } 168 | }) 169 | elseif not v.onlyJob then 170 | ox_target:addSphereZone({ 171 | coords = v.coords, 172 | radius = 1, 173 | debug = drawZones, 174 | options = { 175 | { 176 | name = 'sphere:dj', 177 | event = 'dj_baspel:createMusicMenu', 178 | icon = 'fa fa-music', 179 | label = 'DJ Pult', 180 | canInteract = function(entity, distance, coords, name) 181 | return true 182 | end 183 | } 184 | } 185 | }) 186 | end 187 | end 188 | end 189 | end) 190 | 191 | if not Config.ox_target then 192 | CreateThread(function () 193 | while true do 194 | local sleep = 1500 195 | if CurrentAction ~= nil then 196 | sleep = 0 197 | if IsControlPressed(1, 38) then 198 | Wait(500) 199 | if CurrentAction == 'musicMenu' then 200 | TriggerEvent('dj_baspel:createMusicMenu') 201 | end 202 | end 203 | end 204 | Wait(sleep) 205 | end 206 | end) 207 | end 208 | --------------------------------------------------------------------------------