forked from Simnation/Main
265 lines
8.8 KiB
Lua
265 lines
8.8 KiB
Lua
local QBCore = exports['qb-core']:GetCoreObject()
|
|
local currentArtifact = GetConvar('version', 'unknown')
|
|
local updateInProgress = false
|
|
|
|
-- Hilfsfunktionen
|
|
local function hasPermission(source)
|
|
local Player = QBCore.Functions.GetPlayer(source)
|
|
if not Player then return false end
|
|
|
|
for _, group in pairs(Config.AllowedGroups) do
|
|
if QBCore.Functions.HasPermission(source, group) then
|
|
return true
|
|
end
|
|
end
|
|
return false
|
|
end
|
|
|
|
local function sendDiscordLog(message)
|
|
if not Config.DiscordWebhook.enabled then return end
|
|
|
|
PerformHttpRequest(Config.DiscordWebhook.url, function(err, text, headers) end, 'POST', json.encode({
|
|
username = Config.DiscordWebhook.botName,
|
|
content = message
|
|
}), { ['Content-Type'] = 'application/json' })
|
|
end
|
|
|
|
local function notifyAdmins(message)
|
|
local players = QBCore.Functions.GetPlayers()
|
|
for _, playerId in pairs(players) do
|
|
if hasPermission(playerId) then
|
|
TriggerClientEvent('QBCore:Notify', playerId, message, 'primary', 10000)
|
|
end
|
|
end
|
|
end
|
|
|
|
local function getCurrentArtifact()
|
|
-- Versuche aktuelle Version aus verschiedenen Quellen zu ermitteln
|
|
local version = GetConvar('version', '')
|
|
if version and version ~= '' then
|
|
local artifact = string.match(version, 'v1%.0%.0%.(%d+)')
|
|
if artifact then
|
|
return tonumber(artifact)
|
|
end
|
|
end
|
|
return nil
|
|
end
|
|
|
|
local function checkForUpdates()
|
|
if updateInProgress then return end
|
|
|
|
print('[FX-Updater] Prüfe auf Updates...')
|
|
|
|
PerformHttpRequest('https://runtime.fivem.net/artifacts/fivem/build_proot_linux/master/', function(errorCode, resultData, resultHeaders)
|
|
if errorCode == 200 then
|
|
-- Parse die neueste Artifact-Nummer aus der HTML-Antwort
|
|
local latestArtifact = nil
|
|
for artifact in string.gmatch(resultData, '(%d+)%-[a-f0-9]+/') do
|
|
local num = tonumber(artifact)
|
|
if not latestArtifact or num > latestArtifact then
|
|
latestArtifact = num
|
|
end
|
|
end
|
|
|
|
if latestArtifact and latestArtifact >= Config.RequiredArtifact then
|
|
local currentArt = getCurrentArtifact()
|
|
if not currentArt or latestArtifact > currentArt then
|
|
local message = string.format(Config.Notifications.updateAvailable, latestArtifact)
|
|
print('[FX-Updater] ' .. message)
|
|
notifyAdmins(message)
|
|
sendDiscordLog('🔄 ' .. message)
|
|
|
|
if Config.AutoUpdate then
|
|
Citizen.SetTimeout(5000, function()
|
|
performUpdate(latestArtifact)
|
|
end)
|
|
end
|
|
end
|
|
end
|
|
else
|
|
print('[FX-Updater] Fehler beim Prüfen auf Updates: ' .. errorCode)
|
|
end
|
|
end, 'GET', '', {})
|
|
end
|
|
|
|
local function createBackup()
|
|
if not Config.BackupEnabled then return true end
|
|
|
|
local timestamp = os.date('%Y%m%d_%H%M%S')
|
|
local backupDir = Config.BackupPath .. 'backup_' .. timestamp
|
|
|
|
-- Erstelle Backup-Verzeichnis
|
|
os.execute('mkdir -p "' .. backupDir .. '"')
|
|
|
|
-- Sichere wichtige Dateien
|
|
os.execute('cp server.cfg "' .. backupDir .. '/"')
|
|
os.execute('cp -r resources "' .. backupDir .. '/"')
|
|
os.execute('cp -r server-data "' .. backupDir .. '/" 2>/dev/null || true')
|
|
|
|
print('[FX-Updater] Backup erstellt: ' .. backupDir)
|
|
return true
|
|
end
|
|
|
|
function performUpdate(targetArtifact)
|
|
if updateInProgress then return end
|
|
updateInProgress = true
|
|
|
|
print('[FX-Updater] Starte Update auf Artifact ' .. targetArtifact)
|
|
notifyAdmins(Config.Notifications.updateStarted)
|
|
sendDiscordLog('🔄 Update gestartet auf Artifact ' .. targetArtifact)
|
|
|
|
-- Warnung an alle Spieler
|
|
TriggerClientEvent('chatMessage', -1, '[SERVER]', {255, 165, 0}, 'Server wird in 30 Sekunden für ein Update neu gestartet!')
|
|
|
|
Citizen.SetTimeout(30000, function()
|
|
-- Backup erstellen
|
|
if not createBackup() then
|
|
print('[FX-Updater] Backup fehlgeschlagen!')
|
|
updateInProgress = false
|
|
return
|
|
end
|
|
|
|
-- Download-URL erstellen
|
|
local downloadUrl = string.format(
|
|
'https://runtime.fivem.net/artifacts/fivem/build_proot_linux/master/%d-*/fx.tar.xz',
|
|
targetArtifact
|
|
)
|
|
|
|
-- Update-Script erstellen und ausführen
|
|
local updateScript = [[
|
|
#!/bin/bash
|
|
echo "FXServer Update gestartet..."
|
|
|
|
# Download neue Version
|
|
wget -O fx-new.tar.xz "]] .. downloadUrl .. [["
|
|
|
|
if [ $? -eq 0 ]; then
|
|
# Entpacken
|
|
mkdir -p temp-update
|
|
cd temp-update
|
|
tar -xf ../fx-new.tar.xz
|
|
cd ..
|
|
|
|
# Installation
|
|
cp temp-update/run.sh ./
|
|
cp -r temp-update/alpine ./
|
|
chmod +x run.sh
|
|
chmod +x alpine/opt/cfx-server/FXServer
|
|
|
|
# Aufräumen
|
|
rm -rf temp-update fx-new.tar.xz
|
|
|
|
echo "Update abgeschlossen, starte Server..."
|
|
# Server neu starten
|
|
./run.sh +exec server.cfg &
|
|
else
|
|
echo "Download fehlgeschlagen!"
|
|
exit 1
|
|
fi
|
|
]]
|
|
|
|
-- Script in Datei schreiben
|
|
local file = io.open('update_fx.sh', 'w')
|
|
if file then
|
|
file:write(updateScript)
|
|
file:close()
|
|
|
|
-- Script ausführbar machen und ausführen
|
|
os.execute('chmod +x update_fx.sh')
|
|
|
|
-- Server beenden und Update starten
|
|
print('[FX-Updater] Server wird beendet für Update...')
|
|
notifyAdmins(Config.Notifications.updateCompleted)
|
|
sendDiscordLog('✅ Update wird durchgeführt, Server startet neu...')
|
|
|
|
Citizen.SetTimeout(2000, function()
|
|
os.execute('./update_fx.sh')
|
|
os.exit() -- Server beenden
|
|
end)
|
|
else
|
|
print('[FX-Updater] Konnte Update-Script nicht erstellen!')
|
|
updateInProgress = false
|
|
end
|
|
end)
|
|
end
|
|
|
|
-- Events
|
|
RegisterNetEvent('fx-updater:checkUpdate', function()
|
|
local src = source
|
|
if not hasPermission(src) then
|
|
TriggerClientEvent('QBCore:Notify', src, Config.Notifications.noPermission, 'error')
|
|
return
|
|
end
|
|
|
|
checkForUpdates()
|
|
end)
|
|
|
|
RegisterNetEvent('fx-updater:forceUpdate', function(targetArtifact)
|
|
local src = source
|
|
if not hasPermission(src) then
|
|
TriggerClientEvent('QBCore:Notify', src, Config.Notifications.noPermission, 'error')
|
|
return
|
|
end
|
|
|
|
targetArtifact = targetArtifact or Config.RequiredArtifact
|
|
performUpdate(targetArtifact)
|
|
end)
|
|
|
|
RegisterNetEvent('fx-updater:getVersion', function()
|
|
local src = source
|
|
if not hasPermission(src) then
|
|
TriggerClientEvent('QBCore:Notify', src, Config.Notifications.noPermission, 'error')
|
|
return
|
|
end
|
|
|
|
local current = getCurrentArtifact() or 'Unbekannt'
|
|
local message = string.format(Config.Notifications.currentVersion, current)
|
|
TriggerClientEvent('QBCore:Notify', src, message, 'primary')
|
|
end)
|
|
|
|
-- Commands
|
|
QBCore.Commands.Add('fxupdate', 'Prüfe auf FXServer Updates', {}, false, function(source, args)
|
|
if not hasPermission(source) then
|
|
TriggerClientEvent('QBCore:Notify', source, Config.Notifications.noPermission, 'error')
|
|
return
|
|
end
|
|
|
|
TriggerEvent('fx-updater:checkUpdate')
|
|
end, Config.AllowedGroups)
|
|
|
|
QBCore.Commands.Add('fxforceupdate', 'Erzwinge FXServer Update', {{name = 'artifact', help = 'Artifact Nummer (optional)'}}, false, function(source, args)
|
|
if not hasPermission(source) then
|
|
TriggerClientEvent('QBCore:Notify', source, Config.Notifications.noPermission, 'error')
|
|
return
|
|
end
|
|
|
|
local targetArtifact = args[1] and tonumber(args[1]) or Config.RequiredArtifact
|
|
TriggerEvent('fx-updater:forceUpdate', targetArtifact)
|
|
end, Config.AllowedGroups)
|
|
|
|
QBCore.Commands.Add('fxversion', 'Zeige aktuelle FXServer Version', {}, false, function(source, args)
|
|
if not hasPermission(source) then
|
|
TriggerClientEvent('QBCore:Notify', source, Config.Notifications.noPermission, 'error')
|
|
return
|
|
end
|
|
|
|
TriggerEvent('fx-updater:getVersion')
|
|
end, Config.AllowedGroups)
|
|
|
|
-- Auto-Check Timer
|
|
if Config.CheckInterval > 0 then
|
|
Citizen.CreateThread(function()
|
|
while true do
|
|
Citizen.Wait(Config.CheckInterval)
|
|
checkForUpdates()
|
|
end
|
|
end)
|
|
end
|
|
|
|
-- Beim Server-Start prüfen
|
|
Citizen.CreateThread(function()
|
|
Citizen.Wait(10000) -- Warte 10 Sekunden nach Server-Start
|
|
checkForUpdates()
|
|
end)
|
|
|
|
print('[FX-Updater] Resource gestartet!')
|