RP Upload Server

CDN in dein Handy.
Schritt für Schritt.

Kamera, Galerie, Voice-Memos und Screenshots landen auf https://cdn.rp-upload.de. Der API-Token bleibt auf dem Gameserver — Spieler bekommen nur kurzlebige Upload-Links.

Du suchst nur den Einstieg? LB Phone Bilder hochladen – Anleitung für Spieler und Server-Owner

LB Phone & Tablet

Custom + Presign, ab v1.5.0

Andere Handys

okok, qs, 17mov, YSeries, NPWD

Setup-Paket

ZIP aus der Konsole, Token drin

Loslegen

  1. 01

    Workspace anlegen

    In der Konsole ein Workspace erzeugen. Lab reicht zum Testen, ohne Karte.

  2. 02

    API-Token kopieren

    Unter „Token erzeugen“. Er beginnt mit rpu_ und wird nur einmal angezeigt. Nie in Client-Dateien legen.

  3. 03

    Script konfigurieren

    Unten die Anleitung für LB Phone, NPWD oder die REST-API. Danach Resource neu starten.

Setup-Paket

In der Konsole Handy wählen, ZIP laden — Token und Lua-Dateien sind schon ausgefüllt. Nach einem Script-Update das Paket erneut holen.

Spieler ohne eigenen Server?

Bild in der Garage hochladen, URL kopieren, ins Handy einfügen. Die Anleitungen hier sind für Server-Owner: Kamera und Apps laden dann automatisch auf euer CDN.

Eigene CDN-Domain

City oder Network · 19,90 € einmalige Freischaltung

Im Workspace unter „Eigene CDN-Domain“ freischalten und die gewünschte Adresse eintragen, zum Beispiel cdn.dein-server.de. Der Assistent prüft DNS und richtet danach automatisch das SSL-Zertifikat ein.

  1. 1. Freischalten: Einmalzahlung im Stripe-Checkout abschließen. Die Freischaltung bleibt am Workspace gespeichert.
  2. 2. CNAME setzen: cdn.dein-server.de → cdn.rp-upload.de
  3. 3. DNS prüfen: Der Assistent erkennt den Eintrag; SSL und CDN-Weiterleitung folgen gewöhnlich innerhalb von zwei Minuten.

LB Phone

Ab Version 1.5.0 · Custom-Upload mit One-Time-Link

Der Token liegt nur in server/apiKeys.lua. Der Client holt über GetPresignedUrl einen kurzlebigen Link und lädt das Foto selbst hoch. Nach einem LB-Phone-Update diese vier Stellen erneut setzen.

1

Upload-Methode und Whitelist

In lb-phone/config/config.lua (ältere Builds: lb-phone/config.lua). Vorhandene Hosts in den Whitelists behalten, unsere beiden ergänzen.

lb-phone/config/config.lua

Config.UploadMethod.Video = "Custom"
Config.UploadMethod.Image = "Custom"
Config.UploadMethod.Audio = "Custom"

-- Bestehende Einträge behalten, diese Hosts ergänzen:
Config.UploadWhitelistedDomains = {
    "fivemanage.com",
    "fmfile.com",
    "cfx.re",
    "rp-upload.de",
    "cdn.rp-upload.de",
}

Config.ExternalWhitelistedDomains = {
    "fivemanage.com",
    "fmfile.com",
    "cfx.re",
    "rp-upload.de",
    "cdn.rp-upload.de",
}
2

Token nur auf dem Server

Denselben Token dreimal eintragen. Datei liegt serverseitig und darf nicht ins Git-Repo der Spieler.

lb-phone/server/apiKeys.lua

API_KEYS = {
    Video = "rpu_DEIN_TOKEN",
    Image = "rpu_DEIN_TOKEN",
    Audio = "rpu_DEIN_TOKEN",
}
3

Custom-Methode auf Presign stellen

Nur den Block Custom in UploadMethods ersetzen. success.path muss url sein — sonst speichert das Handy die Ticket-URL statt des CDN-Links.

lb-phone/shared/upload.lua

Custom = {
    Default = {
        url = "PRESIGNED_URL",
        field = "file",
        success = {
            path = "url"
        },
        sendPlayer = "metadata"
    },
},
4

GetPresignedUrl ersetzen

In lb-phone/server/custom/functions/functions.lua die Funktion komplett ersetzen. Danach ensure lb-phone bzw. Server restart.

lb-phone/server/custom/functions/functions.lua

---@param source number
---@param uploadType "Audio" | "Image" | "Video"
---@return string?
function GetPresignedUrl(source, uploadType)
    local apiKey = API_KEYS[uploadType]
    if type(apiKey) ~= "string" or apiKey == "" then
        infoprint("error", "RP Upload: API-Key für " .. tostring(uploadType) .. " fehlt in server/apiKeys.lua")
        return
    end

    local mime, name = "application/octet-stream", "upload.bin"
    if uploadType == "Image" then
        mime, name = "image/webp", "phone.webp"
    elseif uploadType == "Video" then
        mime, name = "video/webm", "phone.webm"
    elseif uploadType == "Audio" then
        mime, name = "audio/ogg", "voice.ogg"
    end

    local p = promise.new()
    PerformHttpRequest("https://rp-upload.de/api/server/v1/presign", function(status, body)
        if status < 200 or status >= 300 then
            infoprint("error", "RP Upload Presign " .. tostring(status) .. ": " .. tostring(body):sub(1, 180))
            p:resolve()
            return
        end

        local ok, data = pcall(json.decode, body)
        if not ok or type(data) ~= "table" or type(data.url) ~= "string" then
            infoprint("error", "RP Upload Presign: ungültige Antwort")
            p:resolve()
            return
        end

        p:resolve(data.url)
    end, "POST", json.encode({
        name = name,
        mime = mime,
    }), {
        ["Authorization"] = "Bearer " .. apiKey,
        ["Content-Type"] = "application/json",
        ["Accept"] = "application/json",
    })

    return Citizen.Await(p)
end
  • CustomGetUploadMethod in client/custom/functions/functions.lua nicht anfassen, nur prüfen dass sie existiert.
  • Limits: Bilder 15.0 MB, Video 100.0 MB, Audio 20.0 MB.
  • Öffentliche Datei danach: https://cdn.rp-upload.de/dein-slug/abc123.webp

LB Tablet

Dieselben vier Schritte wie LB Phone, andere Pfade. Upload-Config liegt unter lb-tablet/config/upload.lua, nicht in shared/.

  1. lb-tablet/config/config.lua — Custom + Whitelist
  2. lb-tablet/server/apiKeys.lua — Token
  3. lb-tablet/config/upload.lua — Custom-Block wie oben
  4. lb-tablet/server/custom/functions/functions.lua — dieselbe GetPresignedUrl

Im Setup-Paket „LB Tablet“ sind die Dateien schon so benannt.

okokPhone

Token in config/api.json, Methode in der Config. Viele Builds rufen noch Fivemerr/FiveManage fest auf — dann den Host in unverschlüsselten Dateien auf https://rp-upload.de legen. Unser Endpunkt spricht dasselbe JSON wie FiveManage (data.url).

okokPhone/config/config.lua

Config.UploadMethod = "custom"
-- ältere Builds:
-- Config.UploadMethod = "fivemerr"

okokPhone/config/api.json

{
  "FiveManage": "rpu_DEIN_TOKEN",
  "Fivemerr": "rpu_DEIN_TOKEN",
  "apiKey": "rpu_DEIN_TOKEN"
}

Upload-URL

https://rp-upload.de/api/v3/file

qs-smartphone

Quasar speichert Keys in qs-smartphone/server/webhooks.lua. Den Token nicht in web/build/custom-upload.js legen — das landet bei Spielern. Wenn der Build noch api.fivemanage.com hart kodiert, Host ersetzen durch https://rp-upload.de.

qs-smartphone/server/webhooks.lua

_G.fivemanage = {
    token = 'rpu_DEIN_TOKEN'
}

_G.rpupload = {
    url = 'https://rp-upload.de/api/v3/file',
    token = 'rpu_DEIN_TOKEN'
}

17mov Phone

Offiziell nur API.FiveManage in configs/ApiKeys.lua. Wenn es ein URL-Feld gibt, auf unseren v3-Endpunkt zeigen. Sonst in unverschlüsselten Configs api.fivemanage.com durch rp-upload.de ersetzen.

17mov_Phone/configs/ApiKeys.lua

API.FiveManage = "rpu_DEIN_TOKEN"
API.UploadUrl = "https://rp-upload.de/api/v3/file"

YSeries / YPhone / YFlip

Custom-Multipart läuft vom Gameserver, der Token bleibt in Convars / server/apiKeys.lua. Nicht mit setr setzen. Builds ohne Config.Upload.Methods.Custom (z. B. 3.0.1) sprechen fest FiveManage an — dann Host tauschen oder auf ein Update warten.

config/config.upload.lua

Config.Upload.Method.Image = "Custom"
Config.Upload.Method.Video = "Custom"
Config.Upload.Method.Audio = "Custom"

Config.Upload.Methods.Custom.Image = {
    mode = "multipart",
    url = "https://rp-upload.de/api/server/v1/media",
    field = "file",
    successPath = "url"
}

server.cfg

set yseriesApiKeyImage "rpu_DEIN_TOKEN"
set yseriesApiKeyVideo "rpu_DEIN_TOKEN"
set yseriesApiKeyAudio "rpu_DEIN_TOKEN"

NPWD

NPWD lädt vom Gameserver, der Token bleibt in der server.cfg. safeImageUrls wird ersetzt, nicht gemerged — vorhandene Hosts mitkopieren.

server.cfg

set SCREENSHOT_BASIC_TOKEN "rpu_DEIN_TOKEN"

npwd/config.json

"images": {
  "url": "https://rp-upload.de/api/server/v1/media",
  "type": "image",
  "imageEncoding": "webp",
  "contentType": "multipart/form-data",
  "useContentType": false,
  "authorizationHeader": "Authorization",
  "authorizationPrefix": "",
  "useAuthorization": true,
  "returnedDataIndexes": ["url"]
},
"imageSafety": {
  "safeImageUrls": [
    "cdn.rp-upload.de",
    "rp-upload.de"
  ]
}

qb-phone

Über den Fivemerr-Modus: Upload läuft serverseitig gegen unsere Media-API. Token in qb-phone/server.lua, nicht in die Config für Clients.

qb-phone/config.lua

Config.Fivemerr = true

qb-phone/server.lua

local WebHook = 'https://rp-upload.de/api/server/v1/media'
local FivemerrApiToken = 'rpu_DEIN_TOKEN'

RoadPhone Pro

Nur RoadPhone Pro hat Custom-Upload. Classic RoadPhone spricht fest Fivemanage an. Domain cdn.rp-upload.de analog in der Image-Whitelist ergänzen.

roadphone/config.lua

Config.uploadMethod = 'custom'

roadphone/uploader/upload-server.lua

local APIKey = 'rpu_DEIN_TOKEN'
local url = "https://rp-upload.de/api/server/v1/presign"

FiveM-Resource

Resource rpupload aus dem Ordner fivem/rpupload auf den Gameserver legen. Screenshots laufen über screenshot-basic und denselben Presign-Weg.

server.cfg

set rpupload_api "https://rp-upload.de"
set rpupload_token "rpu_DEIN_TOKEN"
set rpupload_auto_events 0
ensure screenshot-basic
ensure rpupload

eigenes Script

exports.rpupload:LogMessage("warn", "Spieler hat ein Fahrzeug gespawnt.", {
  playerSource = playerId,
  vehicle = vehicleModel,
  action = "spawn",
})

-- Screenshot über screenshot-basic (Token bleibt auf dem Server)
TriggerEvent("rpupload:take")

REST-API

Header Authorization: Bearer rpu_…. Presign ist der sichere Weg für Clients. Direct-Media nur vom Gameserver.

MethodePfadZweck
POST/GET/api/server/v1/presignEinmal-Upload-URL (5 Min.)
PUT/POST/api/server/v1/upload/:idDatei an das Ticket
POST/api/server/v1/mediaDirekt-Upload mit Token
POST/api/v3/fileFiveManage-/Fivemerr-kompatibel
POST/api/server/v1/logsLog-Ingest

Presign

curl -X POST https://rp-upload.de/api/server/v1/presign \
  -H "Authorization: Bearer rpu_DEIN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name":"phone.webp","mime":"image/webp"}'

Media (nur Gameserver)

curl -X POST https://rp-upload.de/api/server/v1/media \
  -H "Authorization: Bearer rpu_DEIN_TOKEN" \
  -F "file=@foto.webp"

Logs

Felder: level, message, event, playerId, discordId, metadata. Retention je nach Plan.

Logs

curl -X POST https://rp-upload.de/api/server/v1/logs \
  -H "Authorization: Bearer rpu_DEIN_TOKEN" \
  -H "Content-Type: application/json" \
  -d "{\"level\":\"info\",\"message\":\"Spieler verbunden\",\"event\":\"playerConnecting\",\"playerId\":\"12\"}"

Antwort nach erfolgreichem Upload enthält url und data.url — beides die öffentliche CDN-Adresse.

Fehlerbehebung

Foto wird gemacht, im Handy ist es schwarz oder weg
cdn.rp-upload.de und rp-upload.de in UploadWhitelistedDomains und ExternalWhitelistedDomains ergänzen. Vorhandene Hosts nicht löschen.
Bild-Link ist eine Ticket-URL und stirbt nach Minuten
In shared/upload.lua steht success.path falsch. Es muss url sein, nicht ein anderer Pfad.
F8: Presign 401
Token in apiKeys.lua prüfen, beginnt mit rpu_, kein Leerzeichen, Resource nach dem Einfügen neu gestartet.
400 — Nur JPEG, PNG, WebP…
Wir sniffen Magic-Bytes. Ungültige oder leere Dateien lehnen wir ab. Voice-Memos als OGG/MP3/WAV, Video als MP4/WebM.
Nach einem lb-phone Update ist alles wieder Fivemanage
Updates überschreiben config, upload.lua und functions.lua. Die vier Schritte erneut anwenden.

Token-Regel

Niemals in client/, html/ oder shared/upload.lua als Klartext. Nur server/apiKeys.lua oder server.cfg.

Pläne