forked from Simnation/Main
575 lines
21 KiB
Lua
575 lines
21 KiB
Lua
local QBCore = exports['qb-core']:GetCoreObject()
|
|
|
|
-- Aktive DJ-Booths
|
|
local activeDJBooths = {}
|
|
|
|
-- Database Setup
|
|
CreateThread(function()
|
|
MySQL.query([[
|
|
CREATE TABLE IF NOT EXISTS dj_playlists (
|
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
|
name VARCHAR(255) NOT NULL,
|
|
owner VARCHAR(50) NOT NULL,
|
|
description TEXT DEFAULT NULL,
|
|
is_public TINYINT(1) DEFAULT 0,
|
|
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
|
|
)
|
|
]])
|
|
|
|
MySQL.query([[
|
|
CREATE TABLE IF NOT EXISTS dj_playlist_songs (
|
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
|
playlist_id INT NOT NULL,
|
|
title VARCHAR(255) NOT NULL,
|
|
artist VARCHAR(255) DEFAULT NULL,
|
|
url TEXT NOT NULL,
|
|
converted_url TEXT DEFAULT NULL,
|
|
duration INT DEFAULT NULL,
|
|
position INT DEFAULT 0,
|
|
song_type VARCHAR(20) DEFAULT 'direct',
|
|
thumbnail TEXT DEFAULT NULL,
|
|
added_by VARCHAR(50) DEFAULT NULL,
|
|
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
FOREIGN KEY (playlist_id) REFERENCES dj_playlists(id) ON DELETE CASCADE
|
|
)
|
|
]])
|
|
|
|
MySQL.query([[
|
|
CREATE TABLE IF NOT EXISTS dj_url_cache (
|
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
|
original_url VARCHAR(500) NOT NULL,
|
|
converted_url TEXT NOT NULL,
|
|
video_id VARCHAR(50) DEFAULT NULL,
|
|
title VARCHAR(255) DEFAULT NULL,
|
|
duration INT DEFAULT NULL,
|
|
thumbnail TEXT DEFAULT NULL,
|
|
expires_at TIMESTAMP NOT NULL,
|
|
hit_count INT DEFAULT 1,
|
|
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
last_accessed TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
UNIQUE KEY (original_url(255))
|
|
)
|
|
]])
|
|
|
|
MySQL.query([[
|
|
CREATE TABLE IF NOT EXISTS dj_session_history (
|
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
|
dj_citizenid VARCHAR(50) NOT NULL,
|
|
dj_name VARCHAR(100) NOT NULL,
|
|
booth_name VARCHAR(100) NOT NULL,
|
|
song_title VARCHAR(255) NOT NULL,
|
|
song_url TEXT NOT NULL,
|
|
song_type VARCHAR(20) DEFAULT 'direct',
|
|
volume INT DEFAULT 50,
|
|
duration_played INT DEFAULT NULL,
|
|
session_start TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
session_end TIMESTAMP NULL DEFAULT NULL,
|
|
listeners_count INT DEFAULT 0
|
|
)
|
|
]])
|
|
end)
|
|
|
|
-- YouTube URL Funktionen
|
|
local function extractYouTubeVideoId(url)
|
|
-- YouTube URL Patterns
|
|
local patterns = {
|
|
"youtube%.com/watch%?v=([%w%-_]+)",
|
|
"youtube%.com/watch%?.*&v=([%w%-_]+)",
|
|
"youtu%.be/([%w%-_]+)",
|
|
"youtube%.com/embed/([%w%-_]+)"
|
|
}
|
|
|
|
for _, pattern in ipairs(patterns) do
|
|
local videoId = string.match(url, pattern)
|
|
if videoId then
|
|
return videoId
|
|
end
|
|
end
|
|
|
|
return nil
|
|
end
|
|
|
|
local function cleanYouTubeUrl(url)
|
|
local videoId = extractYouTubeVideoId(url)
|
|
if not videoId then
|
|
return nil
|
|
end
|
|
|
|
-- Erstelle saubere YouTube URL ohne Playlist-Parameter
|
|
return "https://www.youtube.com/watch?v=" .. videoId
|
|
end
|
|
|
|
-- Events
|
|
RegisterServerEvent('dj:server:playMusic')
|
|
AddEventHandler('dj:server:playMusic', function(data)
|
|
local src = source
|
|
local Player = QBCore.Functions.GetPlayer(src)
|
|
if not Player then return end
|
|
|
|
-- Speichere den aktuellen DJ-Status
|
|
activeDJBooths[data.booth.name] = {
|
|
url = data.url,
|
|
title = data.title,
|
|
volume = data.volume,
|
|
range = data.range,
|
|
dj = {
|
|
id = Player.PlayerData.citizenid,
|
|
name = Player.PlayerData.charinfo.firstname .. ' ' .. Player.PlayerData.charinfo.lastname
|
|
},
|
|
coords = data.booth.coords
|
|
}
|
|
|
|
-- Sende an alle Spieler
|
|
TriggerClientEvent('dj:client:playMusic', -1, data)
|
|
|
|
-- Log für Admin
|
|
print(('[DJ System] %s spielt Musik ab: %s | Booth: %s'):format(
|
|
GetPlayerName(src),
|
|
data.title,
|
|
data.booth.name
|
|
))
|
|
|
|
-- Speichere in Datenbank
|
|
MySQL.insert('INSERT INTO dj_session_history (dj_citizenid, dj_name, booth_name, song_title, song_url, song_type, volume, session_start) VALUES (?, ?, ?, ?, ?, ?, ?, NOW())', {
|
|
Player.PlayerData.citizenid,
|
|
Player.PlayerData.charinfo.firstname .. ' ' .. Player.PlayerData.charinfo.lastname,
|
|
data.booth.name,
|
|
data.title,
|
|
data.url,
|
|
string.match(data.url, "youtube") and 'youtube' or 'direct',
|
|
data.volume
|
|
})
|
|
end)
|
|
|
|
RegisterServerEvent('dj:server:stopMusic')
|
|
AddEventHandler('dj:server:stopMusic', function(boothName)
|
|
local src = source
|
|
|
|
-- Entferne DJ-Status
|
|
if activeDJBooths[boothName] then
|
|
-- Aktualisiere Session-Ende in der Datenbank
|
|
local djData = activeDJBooths[boothName]
|
|
if djData and djData.dj then
|
|
MySQL.update('UPDATE dj_session_history SET session_end = NOW() WHERE dj_citizenid = ? AND booth_name = ? AND session_end IS NULL', {
|
|
djData.dj.id,
|
|
boothName
|
|
})
|
|
end
|
|
|
|
activeDJBooths[boothName] = nil
|
|
end
|
|
|
|
-- Sende an alle Spieler
|
|
TriggerClientEvent('dj:client:stopMusic', -1, boothName)
|
|
|
|
print(('[DJ System] %s hat die Musik gestoppt in: %s'):format(GetPlayerName(src), boothName))
|
|
end)
|
|
|
|
RegisterServerEvent('dj:server:setVolume')
|
|
AddEventHandler('dj:server:setVolume', function(data)
|
|
local src = source
|
|
|
|
-- Aktualisiere DJ-Status
|
|
if activeDJBooths[data.booth.name] then
|
|
activeDJBooths[data.booth.name].volume = data.volume
|
|
activeDJBooths[data.booth.name].range = data.range
|
|
end
|
|
|
|
-- Sende an alle Spieler
|
|
TriggerClientEvent('dj:client:setVolume', -1, data)
|
|
|
|
print(('[DJ System] %s hat die Lautstärke auf %d%% gesetzt in: %s'):format(
|
|
GetPlayerName(src),
|
|
data.volume,
|
|
data.booth.name
|
|
))
|
|
end)
|
|
|
|
-- Playlist Management
|
|
RegisterServerEvent('dj:server:getPlaylists')
|
|
AddEventHandler('dj:server:getPlaylists', function()
|
|
local src = source
|
|
local Player = QBCore.Functions.GetPlayer(src)
|
|
if not Player then return end
|
|
|
|
MySQL.query('SELECT * FROM dj_playlists WHERE owner = ? OR is_public = 1', {Player.PlayerData.citizenid}, function(playlists)
|
|
local playlistData = {}
|
|
|
|
for _, playlist in pairs(playlists) do
|
|
MySQL.query('SELECT * FROM dj_playlist_songs WHERE playlist_id = ? ORDER BY position', {playlist.id}, function(songs)
|
|
table.insert(playlistData, {
|
|
id = playlist.id,
|
|
name = playlist.name,
|
|
description = playlist.description,
|
|
isPublic = playlist.is_public == 1,
|
|
isOwner = playlist.owner == Player.PlayerData.citizenid,
|
|
songs = songs
|
|
})
|
|
|
|
if #playlistData == #playlists then
|
|
TriggerClientEvent('dj:client:updatePlaylists', src, playlistData)
|
|
end
|
|
end)
|
|
end
|
|
|
|
if #playlists == 0 then
|
|
TriggerClientEvent('dj:client:updatePlaylists', src, {})
|
|
end
|
|
end)
|
|
end)
|
|
|
|
RegisterServerEvent('dj:server:createPlaylist')
|
|
AddEventHandler('dj:server:createPlaylist', function(name, description, isPublic)
|
|
local src = source
|
|
local Player = QBCore.Functions.GetPlayer(src)
|
|
if not Player then return end
|
|
|
|
MySQL.insert('INSERT INTO dj_playlists (name, owner, description, is_public) VALUES (?, ?, ?, ?)', {
|
|
name,
|
|
Player.PlayerData.citizenid,
|
|
description or '',
|
|
isPublic and 1 or 0
|
|
}, function(id)
|
|
if id then
|
|
TriggerClientEvent('QBCore:Notify', src, 'Playlist "' .. name .. '" wurde erstellt!', 'success')
|
|
TriggerEvent('dj:server:getPlaylists', src)
|
|
else
|
|
TriggerClientEvent('QBCore:Notify', src, 'Fehler beim Erstellen der Playlist!', 'error')
|
|
end
|
|
end)
|
|
end)
|
|
|
|
RegisterServerEvent('dj:server:addSongToPlaylist')
|
|
AddEventHandler('dj:server:addSongToPlaylist', function(playlistId, song)
|
|
local src = source
|
|
local Player = QBCore.Functions.GetPlayer(src)
|
|
if not Player then return end
|
|
|
|
-- Prüfe ob Playlist dem Spieler gehört
|
|
MySQL.query('SELECT * FROM dj_playlists WHERE id = ? AND (owner = ? OR is_public = 1)', {
|
|
playlistId,
|
|
Player.PlayerData.citizenid
|
|
}, function(result)
|
|
if result[1] then
|
|
-- Bereinige YouTube URL
|
|
local songUrl = song.url
|
|
if string.match(songUrl, "youtube") then
|
|
local cleanUrl = cleanYouTubeUrl(songUrl)
|
|
if cleanUrl then
|
|
songUrl = cleanUrl
|
|
end
|
|
end
|
|
|
|
-- Hole höchste Position
|
|
MySQL.query('SELECT MAX(position) as max_pos FROM dj_playlist_songs WHERE playlist_id = ?', {playlistId}, function(posResult)
|
|
local position = 1
|
|
if posResult[1] and posResult[1].max_pos then
|
|
position = posResult[1].max_pos + 1
|
|
end
|
|
|
|
-- Füge Song hinzu
|
|
MySQL.insert('INSERT INTO dj_playlist_songs (playlist_id, title, artist, url, song_type, position, added_by) VALUES (?, ?, ?, ?, ?, ?, ?)', {
|
|
playlistId,
|
|
song.title,
|
|
song.artist or '',
|
|
songUrl,
|
|
string.match(songUrl, "youtube") and 'youtube' or 'direct',
|
|
position,
|
|
Player.PlayerData.citizenid
|
|
}, function(id)
|
|
if id then
|
|
TriggerClientEvent('QBCore:Notify', src, 'Song wurde zur Playlist hinzugefügt!', 'success')
|
|
TriggerEvent('dj:server:getPlaylists', src)
|
|
else
|
|
TriggerClientEvent('QBCore:Notify', src, 'Fehler beim Hinzufügen des Songs!', 'error')
|
|
end
|
|
end)
|
|
end)
|
|
else
|
|
TriggerClientEvent('QBCore:Notify', src, 'Du hast keine Berechtigung für diese Playlist!', 'error')
|
|
end
|
|
end)
|
|
end)
|
|
|
|
RegisterServerEvent('dj:server:removeSongFromPlaylist')
|
|
AddEventHandler('dj:server:removeSongFromPlaylist', function(playlistId, songId)
|
|
local src = source
|
|
local Player = QBCore.Functions.GetPlayer(src)
|
|
if not Player then return end
|
|
|
|
-- Prüfe ob Playlist dem Spieler gehört
|
|
MySQL.query('SELECT * FROM dj_playlists WHERE id = ? AND owner = ?', {
|
|
playlistId,
|
|
Player.PlayerData.citizenid
|
|
}, function(result)
|
|
if result[1] then
|
|
MySQL.query('DELETE FROM dj_playlist_songs WHERE id = ? AND playlist_id = ?', {
|
|
songId,
|
|
playlistId
|
|
}, function(affectedRows)
|
|
if affectedRows > 0 then
|
|
TriggerClientEvent('QBCore:Notify', src, 'Song wurde aus der Playlist entfernt!', 'success')
|
|
TriggerEvent('dj:server:getPlaylists', src)
|
|
else
|
|
TriggerClientEvent('QBCore:Notify', src, 'Fehler beim Entfernen des Songs!', 'error')
|
|
end
|
|
end)
|
|
else
|
|
TriggerClientEvent('QBCore:Notify', src, 'Du hast keine Berechtigung für diese Playlist!', 'error')
|
|
end
|
|
end)
|
|
end)
|
|
|
|
RegisterServerEvent('dj:server:deletePlaylist')
|
|
AddEventHandler('dj:server:deletePlaylist', function(playlistId)
|
|
local src = source
|
|
local Player = QBCore.Functions.GetPlayer(src)
|
|
if not Player then return end
|
|
|
|
MySQL.query('DELETE FROM dj_playlists WHERE id = ? AND owner = ?', {
|
|
playlistId,
|
|
Player.PlayerData.citizenid
|
|
}, function(affectedRows)
|
|
if affectedRows > 0 then
|
|
TriggerClientEvent('QBCore:Notify', src, 'Playlist wurde gelöscht!', 'success')
|
|
TriggerEvent('dj:server:getPlaylists', src)
|
|
else
|
|
TriggerClientEvent('QBCore:Notify', src, 'Fehler beim Löschen der Playlist!', 'error')
|
|
end
|
|
end)
|
|
end)
|
|
|
|
RegisterServerEvent('dj:server:updatePlaylist')
|
|
AddEventHandler('dj:server:updatePlaylist', function(playlistId, name, description, isPublic)
|
|
local src = source
|
|
local Player = QBCore.Functions.GetPlayer(src)
|
|
if not Player then return end
|
|
|
|
MySQL.update('UPDATE dj_playlists SET name = ?, description = ?, is_public = ? WHERE id = ? AND owner = ?', {
|
|
name,
|
|
description or '',
|
|
isPublic and 1 or 0,
|
|
playlistId,
|
|
Player.PlayerData.citizenid
|
|
}, function(affectedRows)
|
|
if affectedRows > 0 then
|
|
TriggerClientEvent('QBCore:Notify', src, 'Playlist wurde aktualisiert!', 'success')
|
|
TriggerEvent('dj:server:getPlaylists', src)
|
|
else
|
|
TriggerClientEvent('QBCore:Notify', src, 'Fehler beim Aktualisieren der Playlist!', 'error')
|
|
end
|
|
end)
|
|
end)
|
|
|
|
-- Synchronisation
|
|
RegisterServerEvent('dj:server:requestActiveDJs')
|
|
AddEventHandler('dj:server:requestActiveDJs', function()
|
|
local src = source
|
|
TriggerClientEvent('dj:client:receiveActiveDJs', src, activeDJBooths)
|
|
end)
|
|
|
|
-- Wenn ein Spieler das Spiel verlässt und DJ war, stoppe die Musik
|
|
AddEventHandler('playerDropped', function(reason)
|
|
local src = source
|
|
local Player = QBCore.Functions.GetPlayer(src)
|
|
if not Player then return end
|
|
|
|
-- Prüfe ob Spieler DJ war
|
|
for boothName, boothData in pairs(activeDJBooths) do
|
|
if boothData.dj and boothData.dj.id == Player.PlayerData.citizenid then
|
|
-- Spieler war DJ, stoppe Musik
|
|
|
|
-- Aktualisiere Session-Ende in der Datenbank
|
|
MySQL.update('UPDATE dj_session_history SET session_end = NOW() WHERE dj_citizenid = ? AND booth_name = ? AND session_end IS NULL', {
|
|
boothData.dj.id,
|
|
boothName
|
|
})
|
|
|
|
activeDJBooths[boothName] = nil
|
|
TriggerClientEvent('dj:client:stopMusic', -1, boothName)
|
|
|
|
print(('[DJ System] DJ %s hat das Spiel verlassen, Musik in %s gestoppt'):format(
|
|
GetPlayerName(src),
|
|
boothName
|
|
))
|
|
end
|
|
end
|
|
end)
|
|
|
|
-- Cache Cleanup (läuft alle 30 Minuten)
|
|
CreateThread(function()
|
|
while true do
|
|
Wait(1800000) -- 30 Minuten
|
|
MySQL.query('DELETE FROM dj_url_cache WHERE expires_at < NOW()')
|
|
print('[DJ System] Cache bereinigt')
|
|
end
|
|
end)
|
|
|
|
-- Initialisiere Standard-Playlists
|
|
CreateThread(function()
|
|
Wait(5000) -- Warte bis Datenbank bereit ist
|
|
|
|
-- Prüfe ob Standard-Playlists existieren
|
|
MySQL.query('SELECT * FROM dj_playlists WHERE owner = ?', {'system'}, function(result)
|
|
if #result == 0 then
|
|
print('[DJ System] Erstelle Standard-Playlists')
|
|
|
|
-- Erstelle Standard-Playlists
|
|
for _, playlist in pairs(Config.DefaultPlaylists) do
|
|
MySQL.insert('INSERT INTO dj_playlists (name, owner, description, is_public) VALUES (?, ?, ?, ?)', {
|
|
playlist.name,
|
|
'system',
|
|
'Standard-Playlist',
|
|
1
|
|
}, function(playlistId)
|
|
if playlistId then
|
|
-- Füge Songs hinzu
|
|
for position, song in ipairs(playlist.songs) do
|
|
MySQL.insert('INSERT INTO dj_playlist_songs (playlist_id, title, url, song_type, position, added_by) VALUES (?, ?, ?, ?, ?, ?)', {
|
|
playlistId,
|
|
song.title,
|
|
song.url,
|
|
string.match(song.url, "youtube") and 'youtube' or 'direct',
|
|
position,
|
|
'system'
|
|
})
|
|
end
|
|
|
|
print('[DJ System] Standard-Playlist erstellt: ' .. playlist.name)
|
|
end
|
|
end)
|
|
end
|
|
end
|
|
end)
|
|
end)
|
|
|
|
-- QBCore Callbacks
|
|
QBCore.Functions.CreateCallback('dj:server:getActiveDJs', function(source, cb)
|
|
cb(activeDJBooths)
|
|
end)
|
|
|
|
QBCore.Functions.CreateCallback('dj:server:getPlaylists', function(source, cb)
|
|
local Player = QBCore.Functions.GetPlayer(source)
|
|
if not Player then return cb({}) end
|
|
|
|
MySQL.query('SELECT * FROM dj_playlists WHERE owner = ? OR is_public = 1', {Player.PlayerData.citizenid}, function(playlists)
|
|
local playlistData = {}
|
|
local remaining = #playlists
|
|
|
|
if remaining == 0 then
|
|
return cb({})
|
|
end
|
|
|
|
for _, playlist in pairs(playlists) do
|
|
MySQL.query('SELECT * FROM dj_playlist_songs WHERE playlist_id = ? ORDER BY position', {playlist.id}, function(songs)
|
|
table.insert(playlistData, {
|
|
id = playlist.id,
|
|
name = playlist.name,
|
|
description = playlist.description,
|
|
isPublic = playlist.is_public == 1,
|
|
isOwner = playlist.owner == Player.PlayerData.citizenid,
|
|
songs = songs
|
|
})
|
|
|
|
remaining = remaining - 1
|
|
if remaining == 0 then
|
|
cb(playlistData)
|
|
end
|
|
end)
|
|
end
|
|
end)
|
|
end)
|
|
|
|
QBCore.Functions.CreateCallback('dj:server:getSessionHistory', function(source, cb, limit)
|
|
local Player = QBCore.Functions.GetPlayer(source)
|
|
if not Player then return cb({}) end
|
|
|
|
limit = limit or 50
|
|
|
|
MySQL.query('SELECT * FROM dj_session_history WHERE dj_citizenid = ? ORDER BY session_start DESC LIMIT ?', {
|
|
Player.PlayerData.citizenid,
|
|
limit
|
|
}, function(history)
|
|
cb(history)
|
|
end)
|
|
end)
|
|
|
|
-- Admin Commands
|
|
QBCore.Commands.Add('djstop', 'Stoppe alle DJ-Booths (Admin)', {}, false, function(source, args)
|
|
local Player = QBCore.Functions.GetPlayer(source)
|
|
if Player.PlayerData.job.name ~= 'admin' and Player.PlayerData.job.name ~= 'police' then
|
|
TriggerClientEvent('QBCore:Notify', source, 'Du hast keine Berechtigung für diesen Befehl!', 'error')
|
|
return
|
|
end
|
|
|
|
for boothName, _ in pairs(activeDJBooths) do
|
|
-- Aktualisiere Session-Ende in der Datenbank
|
|
local djData = activeDJBooths[boothName]
|
|
if djData and djData.dj then
|
|
MySQL.update('UPDATE dj_session_history SET session_end = NOW() WHERE dj_citizenid = ? AND booth_name = ? AND session_end IS NULL', {
|
|
djData.dj.id,
|
|
boothName
|
|
})
|
|
end
|
|
|
|
activeDJBooths[boothName] = nil
|
|
TriggerClientEvent('dj:client:stopMusic', -1, boothName)
|
|
end
|
|
|
|
TriggerClientEvent('QBCore:Notify', source, 'Alle DJ-Booths wurden gestoppt!', 'success')
|
|
print('[DJ System] Admin ' .. GetPlayerName(source) .. ' hat alle DJ-Booths gestoppt')
|
|
end)
|
|
|
|
QBCore.Commands.Add('djstatus', 'Zeige Status aller DJ-Booths (Admin)', {}, false, function(source, args)
|
|
local Player = QBCore.Functions.GetPlayer(source)
|
|
if Player.PlayerData.job.name ~= 'admin' and Player.PlayerData.job.name ~= 'police' then
|
|
TriggerClientEvent('QBCore:Notify', source, 'Du hast keine Berechtigung für diesen Befehl!', 'error')
|
|
return
|
|
end
|
|
|
|
local status = {}
|
|
for boothName, boothData in pairs(activeDJBooths) do
|
|
table.insert(status, {
|
|
booth = boothName,
|
|
song = boothData.title,
|
|
dj = boothData.dj.name,
|
|
volume = boothData.volume
|
|
})
|
|
end
|
|
|
|
if #status == 0 then
|
|
TriggerClientEvent('QBCore:Notify', source, 'Keine aktiven DJ-Booths!', 'info')
|
|
else
|
|
for _, booth in ipairs(status) do
|
|
TriggerClientEvent('QBCore:Notify', source, booth.booth .. ': ' .. booth.song .. ' (DJ: ' .. booth.dj .. ', Vol: ' .. booth.volume .. '%)', 'info')
|
|
end
|
|
end
|
|
end)
|
|
|
|
-- Exports
|
|
exports('GetActiveDJs', function()
|
|
return activeDJBooths
|
|
end)
|
|
|
|
exports('StopBooth', function(boothName)
|
|
if activeDJBooths[boothName] then
|
|
-- Aktualisiere Session-Ende in der Datenbank
|
|
local djData = activeDJBooths[boothName]
|
|
if djData and djData.dj then
|
|
MySQL.update('UPDATE dj_session_history SET session_end = NOW() WHERE dj_citizenid = ? AND booth_name = ? AND session_end IS NULL', {
|
|
djData.dj.id,
|
|
boothName
|
|
})
|
|
end
|
|
|
|
activeDJBooths[boothName] = nil
|
|
TriggerClientEvent('dj:client:stopMusic', -1, boothName)
|
|
return true
|
|
end
|
|
return false
|
|
end)
|
|
|
|
-- Initialisierung
|
|
print('[DJ System] Server gestartet')
|
|
|