Zum Inhalt springen

Installation

Zehn Minuten, und die meiste Zeit davon wartet man darauf, dass der Server startet. Es gibt keine SQL-Datei zu importieren und kein zweites Programm auszuführen — die Tabellen erstellen sich beim ersten Start der Ressource von selbst.

Jeder Schritt unten endet damit, woran du erkennst, dass es geklappt hat, damit du nie mit offenen Fragen zum nächsten Schritt übergehst.


Was du brauchstWarum
oxmysql, aktivAlles, was sich das Telefon merkt, liegt in deiner Datenbank
ESX, QBCore, QBox oder fmLibWird automatisch erkannt; du musst nicht angeben, welches
Ein FiveM-Server der letzten zwei JahreDer Web-Teil des Telefons nutzt das integrierte Node des Servers

Sonst nichts. Kein npm, kein Build-Schritt, kein Webserver.


Platziere mic_phone in deinem resources-Ordner — in einem Ordner mit eckigen Klammern ist es am ordentlichsten:

resources/[mic]/mic_phone/

Behalte den Ordnernamen mic_phone bei. Es geht zwar nichts kaputt, wenn du ihn umbenennst, aber die Webadresse des Telefons wird aus dem Ordnernamen zusammengesetzt; alles, was dazu notiert wurde, würde sich dann ebenfalls ändern.


In der server.cfg, unter oxmysql und unter deinem Framework:

ensure oxmysql
ensure es_extended # or qb-core / qbx_core
ensure mic_phone

Es hat geklappt, wenn die Konsole beim Start Folgendes anzeigt:

[mic_phone] web: door B listening on http://0.0.0.0:30125 · door A at /mic_phone/web/ on the game port

Wenn du stattdessen eine rote Fehlermeldung zu einem Framework siehst, starte mic_phone nach deinem Framework — das ist fast immer die Ursache.


Der erste Start liest sql/schema.sql ein und erstellt alles Fehlende. Du wirst eine Reihe von Zeilen wie CREATE TABLE IF NOT EXISTS mic_phone_… durchlaufen sehen. Das war’s schon.

Es hat geklappt, wenn diese Zeilen einmalig und bei späteren Starts nie wieder erscheinen.


Standardmäßig benötigt das Telefon ein Inventar-Item namens phone:

-- shared/config.lua
Config.Open = {
RequireItem = true,
Item = 'phone',
...
}

Die meisten ESX- und QB-Installationen haben dieses Item bereits. Anwender von ox_inventory: Füge es deiner Items-Liste hinzu, falls es dort noch fehlt. Möchtest du es erst einmal nur ausprobieren? Setze RequireItem = false und überspringe diesen Schritt komplett.

Es hat geklappt, wenn du beitrittst, das Item im Inventar hast und F1 das Telefon öffnet. /phone bewirkt dasselbe, und mit T entfaltet es sich zum Tablet, während es geöffnet ist.


Kopiere die Beispieldatei und trage deine gewünschten Werte ein:

shared/server_config.example.lua → shared/server_config.lua

Diese Datei wird ausschließlich als Server-Skript geladen, sodass niemals Inhalte davon an einen Client gelangen. Zwei Dinge befinden sich dort:

Fotos, Videos und Sprachnachrichten. Trage ein Fivemanage-Medien-Token in ServerConfig.Media.Token (oder die Convar FIVEMANAGE_MEDIA_API_KEY) ein, und das Telefon lädt Dateien selbstständig hoch und speichert lediglich den resultierenden Link. Ein Discord-Webhook dient als Fallback.

Wenn keines von beiden gesetzt ist, speichert FallbackToDataUrl die Datei direkt in deiner Datenbank. Für einen schnellen Test ist das in Ordnung, im Livebetrieb jedoch sehr schwerfällig — wenige Sekunden Sprachaufnahme belegen Dutzende Kilobytes in jeder betroffenen Zeile. Setze ein Token oder deaktiviere diese Option, damit Uploads klar erkennbar fehlschlagen.

Discord-Webhooks. Eine URL pro Ereignis-Typ oder Default, um alles abzufangen. Der Webhook, den du unbedingt setzen solltest (selbst wenn du den Rest auslässt), ist Server: Er ist der einzige, der dich über den Server statt über einen Spieler informiert — etwa wenn sich die Adresse geändert hat oder ein Zertifikat nicht erneuert werden konnte.


Das Telefon funktioniert. Alles Weitere ist optional.


Spieler können das Telefon ihres Charakters auf ihrem eigenen Smartphone bedienen. Das ist bereits aktiv: Einstellungen › Verknüpfte Geräte auf dem Telefon im Spiel zeigt einen QR-Code an. Sie scannen diesen und tippen den angezeigten sechsstelligen Code im Spiel ein. Das Gerät agiert ab diesem Moment als dieser Charakter.

Über einfaches HTTP erhalten sie dadurch bereits Nachrichten, E-Mails, Kontakte, die Garage, Immobilien und den Rest. Was ein Browser einer unverschlüsselten Seite jedoch verweigert, ist das Beste:

Einfaches HTTPHTTPS
Nachrichten, E-Mails, Garage, alles anderejaja
Benachrichtigungen bei geschlossener Appneinja
Anrufeneinja
Mikrofon, für Sprachnachrichtenneinja
Als App mit eigenem Icon installierenneinja

Diese Ressource kann ihr eigenes Zertifikat anfordern und erneuern. Leite eine Domain auf deinen Server, öffne zwei Ports und fülle drei Zeilen aus:

-- shared/server_config.lua (server-only: this file is never sent to a client)
ServerConfig.Web = {
Url = 'https://phone.yourserver.com/',
Https = {
Enabled = true,
Names = { 'phone.yourserver.com' },
Contact = '[email protected]',
},
}
  1. Eine Domain. Auf einem VPS ist das ein A-Record, der auf die IP-Adresse zeigt. Keine Domain? Bei duckdns.org erhältst du in einer Minute kostenlos eine.
  2. Port 80 und Port 443 in der Firewall freigeben. Port 80 wird nur geöffnet, während ein Zertifikat angefordert wird, und schließt sich sofort wieder, sobald die Challenge beantwortet wurde.

Es hat geklappt, wenn die Konsole Folgendes meldet:

https: asking for phone.yourserver.com
https: port 80 open for the challenge
https: challenge port closed
https: certificate in hand, good until 2027-01-31
https: listening on https://phone.yourserver.com/

Falls Port 443 belegt ist — manche Router belegen ihn für ihre eigene Administrationsseite — nutze stattdessen einen anderen Port: Port = 8443, leite 8443 weiter und setze Url = 'https://phone.yourserver.com:8443/'. Nur die Challenge muss zwingend über Port 80 laufen; ein Zertifikat gehört zu einem Domainnamen, nicht zu einem Port, und alles funktioniert weiterhin.

docs/HTTPS.md beschreibt die weiteren Szenarien: hinter dem Cfx.re-Proxy, hinter einem bereits laufenden Reverse-Proxy oder bei einem Hostanbieter, der keine Ports vergibt.


phonehttps check — fragt den Testserver der Zertifizierungsstelle, ob er mit deiner Maschine kommunizieren kann. Führe dies zuerst aus, wenn kein Zertifikat ankommt: Es trennt deine Firewall von dieser Ressource.

phonehttps — aktueller Status des Zertifikats und Zeitpunkt der Erneuerung.

phoneduck — Status der Domain, falls dieser Server seine eigene DuckDNS-Adresse aktuell hält, und wann dies zuletzt gemeldet wurde. phoneduck now sendet die aktuelle Adresse und gibt die Antwort von DuckDNS aus. So lässt sich feststellen, ob ein Token falsch ist, ohne darauf warten zu müssen, dass sich die IP-Adresse ändert.

Was du siehstWas es bedeutet
Das Telefon öffnet sich nichtKein phone-Item vorhanden, oder RequireItem ist an und der Spieler trägt keines bei sich
Der QR-Code führt zu einem unerreichbaren ZielSetze ServerConfig.Web.Url manuell; die automatische Erkennung sieht nicht über einen Router hinweg, der den Port verschoben hat
Kein Zertifikat, Log macht die Challenge dafür verantwortlichPort 80 erreicht diese Maschine nicht. Überprüfe Portweiterleitung und Firewall, in dieser Reihenfolge
Fotos sind riesig / die Datenbank wächst schnellKein Medien-Token hinterlegt, und FallbackToDataUrl speichert Dateien in der Datenbank
Anrufe zwischen zwei Spielern sind stummVoice steht auf auto und hat keine Voice-Ressource gefunden; trage deine in Config.Bridge.voice ein

  • shared/server_config.lua gehört dir. Teile sie niemals und committe sie an keinen öffentlichen Ort; sie enthält dein Medien-Token und deine Webhook-URLs.
  • Leite den Server-Webhook an einen Ort, den du liest. Er meldet, wenn die Eingangstür des Telefons ausgefallen ist, und ist die einzige Warnung, die du erhältst, bevor es dir ein Spieler mitteilt.
  • Schalte Config.Debug aus, falls du es eingeschaltet hattest: Es gibt jede Bridge-Entscheidung in der Konsole aus.
  • Sicherheit ist zehn Minuten wert, wenn du eine öffentliche Stadt betreibst: Welche Annahmen diese Ressource über verbundene Clients trifft und welche Regeln sie durchsetzt, damit ein modifizierter Client niemals über den eigenen Charakter hinausgreifen kann.