1
0
Fork 0
forked from Simnation/Main
Main/resources/[tools]/nordi_dj/server/main.lua
2025-08-03 16:51:12 +02:00

263 lines
9.3 KiB
Lua

local QBCore = exports['qb-core']:GetCoreObject()
-- YouTube URL Converter
local function ConvertYouTubeUrl(url, callback)
if not string.match(url, "youtube%.com") and not string.match(url, "youtu%.be") then
callback(url) -- Nicht YouTube, direkt zurückgeben
return
end
-- Extrahiere Video ID
local videoId = ExtractYouTubeVideoId(url)
if not videoId then
callback(nil)
return
end
if Config.LocalYouTubeConverter.enabled then
-- Verwende lokalen Converter
PerformHttpRequest(Config.LocalYouTubeConverter.serverUrl, function(errorCode, resultData, resultHeaders)
if errorCode == 200 then
local data = json.decode(resultData)
if data and data.url then
callback(data.url)
else
callback(nil)
end
else
callback(nil)
end
end, 'POST', json.encode({videoId = videoId}), {['Content-Type'] = 'application/json'})
elseif Config.YouTubeAPI.enabled then
-- Verwende externe API
local apiUrl = Config.YouTubeAPI.apiUrl .. "?id=" .. videoId
PerformHttpRequest(apiUrl, function(errorCode, resultData, resultHeaders)
if errorCode == 200 then
local data = json.decode(resultData)
if data and data.link then
callback(data.link)
else
callback(nil)
end
else
print("YouTube API Error: " .. errorCode)
callback(nil)
end
end, 'GET', '', Config.YouTubeAPI.headers)
else
callback(nil)
end
end
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
-- 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,
created_at TIMESTAMP DEFAULT 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,
url TEXT NOT NULL,
converted_url TEXT NULL,
position INT DEFAULT 0,
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 UNIQUE,
converted_url TEXT NOT NULL,
expires_at TIMESTAMP NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
]])
end)
-- Events
RegisterNetEvent('dj:server:playMusic', function(data)
local src = source
-- Prüfe Cache zuerst
MySQL.query('SELECT converted_url FROM dj_url_cache WHERE original_url = ? AND expires_at > NOW()', {data.url}, function(cached)
if cached[1] then
-- Verwende gecachte URL
local musicData = {
title = data.title,
url = cached[1].converted_url,
volume = data.volume,
booth = data.booth,
range = data.range
}
TriggerClientEvent('dj:client:playMusic', -1, musicData)
print(('[DJ System] %s spielt Musik ab (cached): %s'):format(GetPlayerName(src), data.title))
else
-- Konvertiere URL
ConvertYouTubeUrl(data.url, function(convertedUrl)
if convertedUrl then
-- Cache die URL für 1 Stunde
MySQL.insert('INSERT INTO dj_url_cache (original_url, converted_url, expires_at) VALUES (?, ?, DATE_ADD(NOW(), INTERVAL 1 HOUR)) ON DUPLICATE KEY UPDATE converted_url = VALUES(converted_url), expires_at = VALUES(expires_at)', {
data.url,
convertedUrl
})
local musicData = {
title = data.title,
url = convertedUrl,
volume = data.volume,
booth = data.booth,
range = data.range
}
TriggerClientEvent('dj:client:playMusic', -1, musicData)
print(('[DJ System] %s spielt Musik ab (converted): %s'):format(GetPlayerName(src), data.title))
else
TriggerClientEvent('dj:client:notify', src, 'Fehler beim Konvertieren der YouTube URL!', 'error')
print(('[DJ System] Fehler beim Konvertieren der URL: %s'):format(data.url))
end
end)
end
end)
end)
RegisterNetEvent('dj:server:stopMusic', function(booth)
local src = source
TriggerClientEvent('dj:client:stopMusic', -1)
print(('[DJ System] %s hat die Musik gestoppt'):format(GetPlayerName(src)))
end)
RegisterNetEvent('dj:server:setVolume', function(data)
local src = source
TriggerClientEvent('dj:client:setVolume', -1, data.volume)
print(('[DJ System] %s hat die Lautstärke auf %d%% gesetzt'):format(GetPlayerName(src), data.volume))
end)
RegisterNetEvent('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 = ?', {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,
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)
RegisterNetEvent('dj:server:createPlaylist', function(name)
local src = source
local Player = QBCore.Functions.GetPlayer(src)
if not Player then return end
MySQL.insert('INSERT INTO dj_playlists (name, owner) VALUES (?, ?)', {
name,
Player.PlayerData.citizenid
}, function(id)
if id then
TriggerClientEvent('dj:client:notify', src, 'Playlist "' .. name .. '" wurde erstellt!', 'success')
TriggerEvent('dj:server:getPlaylists')
else
TriggerClientEvent('dj:client:notify', src, 'Fehler beim Erstellen der Playlist!', 'error')
end
end)
end)
RegisterNetEvent('dj:server:addSongToPlaylist', function(playlistId, song)
local src = source
local Player = QBCore.Functions.GetPlayer(src)
if not Player then return end
MySQL.query('SELECT * FROM dj_playlists WHERE id = ? AND owner = ?', {
playlistId,
Player.PlayerData.citizenid
}, function(result)
if result[1] then
MySQL.insert('INSERT INTO dj_playlist_songs (playlist_id, title, url) VALUES (?, ?, ?)', {
playlistId,
song.title,
song.url
}, function(id)
if id then
TriggerClientEvent('dj:client:notify', src, 'Song wurde zur Playlist hinzugefügt!', 'success')
TriggerEvent('dj:server:getPlaylists')
else
TriggerClientEvent('dj:client:notify', src, 'Fehler beim Hinzufügen des Songs!', 'error')
end
end)
else
TriggerClientEvent('dj:client:notify', src, 'Du hast keine Berechtigung für diese Playlist!', 'error')
end
end)
end)
RegisterNetEvent('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('dj:client:notify', src, 'Playlist wurde gelöscht!', 'success')
TriggerEvent('dj:server:getPlaylists')
else
TriggerClientEvent('dj:client:notify', src, 'Fehler beim Löschen der Playlist!', 'error')
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)