Dokumentation
Prox einrichten und erweitern.
Alles, was du für Prox brauchst: von der ersten Zeile in der server.cfg bis zu Team-Sperren, Funk-Rechten und eigenen Scripts.
Nichts gefunden. Versuch ein anderes Wort.
Überblick
Prox ist ein Voice-Chat für FiveM, der ohne TeamSpeak auskommt. Spieler öffnen einmal einen Browser-Tab auf proxvoice.net, koppeln ihn mit einem Code und reden danach mit allen in der Nähe, über Funk oder Telefon.
- 3D-Ton mit Entfernung, Richtung, gedämpftem Klang in geschlossenen Fahrzeugen und Hall in Innenräumen.
- Funk mit zwei Kanälen, echter Funk-Klangqualität, Dauerfunk, Mitgliederlisten und Job-Rechten.
- Telefon inklusive Lautsprecher, den Umstehende hören.
- Kompatibel mit den Exports und Events von SaltyChat und pma-voice. Bestehende Handys, Funkgeräte und HUDs laufen meist ohne Änderung weiter.
- Gehostet: Die Voice-Server betreiben wir. Du trägst nur deinen Schlüssel ein.
Gesprochen wird über drei Teile: die FiveM-Ressource prox auf deinem Server, unsere Voice-Server und den Browser-Tab der Spieler. Positionen und Rechte kommen immer von deinem Server, nie vom Spieler. Deshalb kann niemand seine Position fälschen oder sich in fremde Funkkanäle hören.
Installation
- Server anlegen. Melde dich im Panel mit Discord an und lege einen Server an. Bis 50 Spieler ist das kostenlos. Unter „Einrichtung“ steht dein Schlüssel.
- Ressource einfügen. Lade die Ressource herunter und lege den Ordner
proxin deinenresources-Ordner. Der Name mussproxbleiben. - server.cfg ergänzen. Andere Voice-Ressourcen (SaltyChat, pma-voice) vorher entfernen.
ensure prox set prox_key "dein-schlüssel-aus-dem-panel"
- Server starten. In der Konsole erscheint
[prox] verbunden als "Dein Server". Fertig.
Startreihenfolge
Starte prox nach deinem Framework (es_extended oder qb-core) und vor Ressourcen, die SaltyChat- oder pma-voice-Exports nutzen, zum Beispiel Handy oder Funkgerät.
ensure oxmysql ensure es_extended ensure prox ensure mein_handy ensure mein_funk
Für Spieler
Beim ersten Joinen öffnet sich ingame ein Fenster mit einem Link und einem 6-stelligen Code. Spieler öffnen den Link im Browser, erlauben das Mikrofon und sind verbunden. Ab dann reicht es, den Tab offen zu lassen. Beim nächsten Mal verbindet er sich von selbst.
| Taste | Funktion |
|---|---|
| N | Sprechen (gedrückt halten) |
| Feststell | Funk, primärer Kanal (gedrückt halten) |
| J | Dauerfunk an/aus. Alles, was du sagst, geht über den Funk. |
| Y | Sprachreichweite wechseln |
| F9 | Mikrofon stumm |
| F7 | Voice-Fenster öffnen (Link und Code) |
Alle Tasten lassen sich in GTA unter Einstellungen → Tastenbelegung → FiveM ändern. Die Standardtasten legst du in der Config fest.
Im Browser-Tab
- Sprachaktivierung statt Push-to-Talk, Lautstärke pro Spieler, Spieler stumm schalten (bleibt gespeichert)
- Soundboard, Stimmenverzerrer, Dauerfunk-Knopf (Taste R im Tab)
- Verbindungsanzeige mit Ping und Verlust. Bei schlechter Leitung senkt Prox die Qualität automatisch, statt abzubrechen.
proxvoice.net eintragen.Config
Alle Einstellungen stehen in config.lua. Diese Datei ist offen und bleibt bei Updates deine.
| Option | Standard | Bedeutung |
|---|---|---|
Framework | 'auto' | 'esx', 'qb' oder 'custom'. Wird für Job-Rechte und das Verbinden-Fenster genutzt. |
Ranges | {3, 8, 15, 32} | Sprachreichweiten in Metern |
DefaultRange | 2 | Startreichweite (Index in Ranges) |
MaxClientRange | 32.0 | Größte Reichweite, die ein Client selbst setzen darf |
Keys | siehe Datei | Standardtasten: talk, radio1, radio2, radioLatch, range, mute, deaf, connect |
AllowVoiceActivation | true | Sprachaktivierung im Browser erlauben |
AllowSoundboard | true | Soundboard im Browser erlauben |
RangeCircle | an | Kreis am Boden beim Wechseln der Reichweite: marker, color, alpha, duration, animate, onForced |
Overlay | true | Kleine Statusleiste ingame |
Prompt.enabled | true | Verbinden-Fenster automatisch zeigen |
Prompt.event | 'auto' | Erst nach diesem Client-Event zeigen. 'auto' nimmt esx:playerLoaded bzw. QBCore:Client:OnPlayerLoaded, '' sofort. |
Prompt.delay | 4000 | Verzögerung danach in ms |
RadioAnimation | Funkgerät am Ohr | enabled, dict, name, duration (-1 = solange gefunkt wird), inVehicle, skip (Funktion, die true liefert, um die Animation zu überspringen) |
BlockShootingWhileRadio | false | Beim Funken nicht schießen |
Sounds | true | true = Prox-Sounds, 'gta' = GTA-Funksounds, false = aus |
SoundVolume | 1.0 | Lautstärke der Prox-Sounds |
Radio | Siehe Funk und Jobs | |
Death | an | Bewusstlose können nicht sprechen. stateKeys sind Statebag-Werte, die als tot gelten. |
LimitWarning | an, alle 10 min | Konsolenwarnung ab 90 % der Plätze |
ClientCalls | true | Telefonate über Client-Exports (pma-voice) erlauben |
NotifyEvent | '' | Eigenes Notify-Event, z. B. 'esx:showNotification'. Leer = GTA-Benachrichtigung. |
Text | Alle Texte, die Spieler sehen |
Convars
| Convar | Bedeutung |
|---|---|
prox_key | Dein Lizenzschlüssel (Pflicht) |
prox_debug | 1 = ausführliche Logs in der Konsole |
prox_check_ms | Wie oft Positionen und Tod geprüft werden (Standard 1000, verteilt über alle Spieler) |
Funk und Jobs
Frequenzen sind frei wählbare Texte oder Zahlen. Wer in welche Frequenz darf, prüft immer dein Server.
Config.Radio = {
public = true,
ranges = {
{ from = 1, to = 10, jobs = { 'police', 'sheriff', 'fib' } },
{ from = 11, to = 15, jobs = { 'ambulance' } }
},
check = function(source, frequency, job)
return nil
end
}
- ranges sperren Zahlenbereiche für Jobs. Kommazahlen gehen auch,
1.5liegt im Bereich 1 bis 10. - public regelt alle Frequenzen ohne Regel. Mit
falseist alles gesperrt, was du nicht freigibst. - check ist deine eigene Prüfung.
trueerlaubt,falseverbietet,nillässt die normalen Regeln entscheiden.
Wechselt ein Spieler den Job (esx:setJob bzw. QBCore:Server:OnJobUpdate), prüft Prox seine Funkkanäle neu und wirft ihn aus Frequenzen, für die er keine Rechte mehr hat. Bei eigenem Framework löst du das selbst aus:
TriggerEvent('prox:recheckRadio', source)
Eigenes Framework
Config.Framework = 'custom'
Config.GetJob = function(source)
return exports['mein_core']:GetJob(source)
end
Regeln aus Scripts
Einzelne Frequenzen kannst du zur Laufzeit festlegen. Das hat Vorrang vor der Config.
exports['prox']:SetRadioPermission('swat', function(source, frequency)
return IsPlayerAceAllowed(source, 'swat.radio')
end)
exports['prox']:SetRadioPermission('event', { 12, 48, 77 })
exports['prox']:SetRadioPermission('geschlossen', false)
exports['prox']:SetRadioPermission('swat', nil)
Ingame-UI anpassen
Die Statusleiste und das Verbinden-Fenster liegen offen in nui/index.html. Farben, Schriften und Position kannst du dort frei ändern. Die Sounds liegen in nui/sounds und lassen sich durch eigene .wav-Dateien mit gleichem Namen ersetzen.
Server-Exports
Alle Exports gibt es unter exports['prox']. src ist immer die Server-ID des Spielers. Sprechmodi: 0 still, 1 in der Nähe, 2 Funk primär, 3 Funk sekundär.
Status
| Export | Rückgabe |
|---|---|
IsVoiceConnected(src) | true, wenn der Browser-Tab verbunden ist |
GetConnection(src) | { connected, level, quality, ping, loss } |
IsTalking(src) / GetTalkMode(src) | Spricht gerade / Sprechmodus |
GetActiveTalkers() | Liste { src, mode, radio } aller, die gerade sprechen |
IsSelfMuted(src) / IsDeafened(src) | Selbst stumm / Ton aus |
GetVoiceStats() | { players, waiting, max, connected } |
Funk
| Export | Beschreibung |
|---|---|
SetRadio(src, freq, primary) | Kanal setzen, '' zum Verlassen. primary = false für den zweiten Kanal. Prüft keine Rechte. |
GetRadio(src) | { primär, sekundär } |
CanUseRadio(src, freq) | Darf der Spieler in die Frequenz? |
GetRadioMembers(freq) | Liste { src, name, primary, talking, connected } |
GetRadioMemberCount(freq) | Anzahl ohne Liste |
GetRadioFrequencies() | { [freq] = anzahl } aller belegten Frequenzen |
SetRadioPermission(freq, regel) | Siehe Regeln aus Scripts |
SetRadioLatch(src, on) / IsRadioLatched(src) | Dauerfunk setzen / abfragen |
Sprache und Telefon
| Export | Beschreibung |
|---|---|
ForceRange(src, meter) | Reichweite festlegen, der Spieler kann sie nicht ändern. nil gibt sie frei. |
SetMegaphone(src, on) | Megafon (60 m, mit Effekt) |
SetCall(src, name) | In ein Telefonat. Alle mit gleichem name hören sich. nil beendet. |
MutePlayerFor(target, src, on) | target hört src nicht mehr (z. B. Blockieren) |
ClearMutesFor(target) | Alle Sperren von target aufheben |
SetRoutingBucket(src, bucket) | Nur nötig, wenn du Buckets ohne SetPlayerRoutingBucket verwaltest. Sonst erkennt Prox sie selbst. |
RegisterNetEvent('mein_handy:anrufen', function(target)
local src = source
if not Handy.KannAnrufen(src, target) then return end
local name = ('call:%d:%d'):format(math.min(src, target), math.max(src, target))
exports['prox']:SetCall(src, name)
exports['prox']:SetCall(target, name)
end)
Team-Sperren
Sperren gelten pro Spieler (Rockstar-Lizenz) und bleiben über Reconnects und Server-Neustarts erhalten. Im Browser-Tab sieht der Spieler „vom Team gesperrt“ samt Ablaufzeit.
| Export | Beschreibung |
|---|---|
AdminMute(src, sekunden, grund, von) | Mikrofon sperren. 0 oder nil = dauerhaft. |
AdminUnmute(src) | Freigeben |
AdminDeafen(src, sekunden, grund, von) | Ton sperren, der Spieler hört niemanden |
AdminUndeafen(src) | Freigeben |
GetAdminState(src) | { muted, mutedUntil, deafened, deafUntil, reason, by }. -1 = dauerhaft. |
GetAdminList() | Alle aktiven Sperren, auch von Spielern, die offline sind |
AdminClear(src | license) | Alle Sperren eines Spielers löschen, auch offline per Lizenz |
RegisterCommand('vmute', function(source, args)
if not IstTeam(source) then return end
local target = tonumber(args[1])
local minuten = tonumber(args[2]) or 10
exports['prox']:AdminMute(target, minuten * 60, table.concat(args, ' ', 3), GetPlayerName(source))
end, false)
Nur Funk
Für Gangkriege, Events oder Einsätze: Spieler sprechen und/oder hören nur noch über Funk. Nähe und Telefon sind dann aus.
exports['prox']:SetRadioOnly(source, true, false) exports['prox']:SetBucketRadioOnly(42, true, true) exports['prox']:SetBucketRadioOnly(42, false, false) local mode = exports['prox']:GetRadioOnly(source)
Bucket-Regeln gelten automatisch für jeden, der den Bucket betritt, und enden beim Verlassen. Spieler-Regeln und Bucket-Regeln addieren sich.
Client-Exports
| Export | Rückgabe |
|---|---|
IsConnected() | Browser-Tab verbunden |
GetConnection() | { connected, level, ping, loss } |
IsTalking() / GetTalkMode() | Spricht gerade / Modus |
GetRange() | Aktuelle Reichweite in Metern |
GetRadio() | primär, sekundär |
GetRadioMembers(freq) | Liste { src, name } deines Kanals, ohne Server-Abfrage |
IsRadioLatched() / SetRadioLatch(on) | Dauerfunk |
IsAdminMuted() / IsAdminDeafened() | Vom Team gesperrt |
GetRadioOnly() | talk, hear |
AddEventHandler('prox:radioMembers', function(frequency, members)
for src, name in pairs(members) do
print(frequency, src, name)
end
end)
Events
Server (AddEventHandler)
| Event | Argumente |
|---|---|
prox:talk | src, mode |
prox:talkersChanged | keine, danach GetActiveTalkers() |
prox:clientState | src, connected |
prox:radioChanged | src, freq, primary |
prox:radioMembersChanged | freq, src, joined |
prox:latchChanged | src, on |
prox:selfMute | src, muted, deafened |
prox:adminChanged | src, 'mute' | 'deafen', on |
prox:aliveChanged | src, alive |
prox:quality | src, level, ping, loss. Level 0 gut bis 3 kritisch |
prox:full | src, der Spieler hat wegen des Limits keinen Voice |
prox:violation | src, meter, gemeldete Position weicht ab |
prox:lockdown | on, Schutzmodus gegen Angriffe |
Client (AddEventHandler)
| Event | Argumente |
|---|---|
prox:talkState | mode |
prox:rangeChanged | meter, index |
prox:clientState | connected |
prox:radioTraffic | src, freq, on, jemand funkt in deinem Kanal |
prox:radioMembers | freq, { [src] = name } |
prox:latchChanged | on |
prox:selfMute | muted, deafened |
prox:adminState | muted, deafened |
prox:radioOnlyChanged | talk, hear |
prox:connectionQuality | level, ping, loss |
Zusätzlich feuert Prox die bekannten SaltyChat-Events (SaltyChat_TalkStateChanged, SaltyChat_VoiceRangeChanged, SaltyChat_RadioTrafficStateChanged usw.) und pma-voice:radioActive.
Status-API
Für Discord-Bots, Webseiten oder Statusseiten. Lege im Panel unter deinem Server einen API-Schlüssel an. Optional kannst du ihn auf feste IPs und ein Ablaufdatum beschränken.
curl -H "Authorization: Bearer prx_dein_schluessel" https://panel.proxvoice.net/v1/status
{
"name": "Mein Server",
"status": "active",
"players": 412,
"max_players": 500,
"peak": 468,
"connected": true,
"voice": { "online": true, "city": "Frankfurt am Main", "country": "DE" },
"expires": null
}
Höchstens 120 Anfragen pro Minute und IP. status ist active, grace, expired oder suspended.
Umstieg von SaltyChat
saltychataus der server.cfg entfernen und den Ordner löschen. Die TeamSpeak-Convars (VoiceEnabled,ServerUniqueIdentifierusw.) brauchst du nicht mehr.- Prox installieren wie unter Installation.
- Fertig. Prox stellt sich als
saltychatbereit.exports['saltychat']:SetPlayerRadioChannel(...)und die SaltyChat-Events funktionieren weiter.
| SaltyChat | Status |
|---|---|
| Funk, Telefon, Reichweite, Megafon, Tod | Voll unterstützt |
SetPlayerRadioSpeaker, SetRadioVolume | Werden angenommen, ändern den Klang aber noch nicht |
SetRadioTowers | Wird ignoriert. Funk reicht bei Prox über die ganze Karte, mit zunehmender Entfernung etwas rauer. |
| TeamSpeak-Plugin | Nicht mehr nötig |
Umstieg von pma-voice / Mumble
pma-voiceaus der server.cfg entfernen.- Alle
voice_*-Zeilen von pma-voice aus der server.cfg entfernen. Ohne pma-voice bleibt der eingebaute Mumble-Voice aus, Spieler hören sich also nicht doppelt. - Prox installieren. Prox stellt sich als
pma-voicebereit,setPlayerRadio,setPlayerCall,overrideProximityRangeund der Statebagproximityfunktionieren weiter.
setRadioChannel(5) landet in Frequenz 5. Deine Job-Bereiche in Config.Radio.ranges greifen dabei.Pakete und Limits
- Plätze: Jedes Paket hat eine Anzahl gleichzeitiger Voice-Spieler. Ab 90 % erscheint in deiner Serverkonsole eine rote Warnung (abschaltbar mit
Config.LimitWarning). - Limit erreicht: Wer schon spricht, behält Voice. Neue Spieler sehen „Voice ist gerade nicht verfügbar“ und rücken automatisch nach, sobald ein Platz frei wird. Den Text änderst du in
Config.Text.full. - Abgelaufen: Voice läuft noch 3 Tage weiter, die Konsole erinnert alle 30 Minuten. Danach ist Voice aus, bis du verlängerst.
- Team: Im Panel kannst du anderen per Discord-ID Zugriff geben, mit einzelnen Rechten für Schlüssel, API und Team.
Befehle
| Befehl | Wo | Funktion |
|---|---|---|
/prox | Spieler | Neuen Code anfordern, z. B. für ein zweites Gerät |
/proxnet | Spieler | Verbindungsqualität anzeigen |
/proxstatus | Spieler (F8) | Technischer Status für die Fehlersuche |
prox_lockdown auto|on|off | Serverkonsole | Schutzmodus: nur noch bekannte Spieler-IPs dürfen verbinden |
Fehlersuche
„Der Lizenzschlüssel (prox_key) ist ungültig.“
Schlüssel im Panel kopieren und ohne Leerzeichen in die server.cfg setzen. Wurde er im Panel neu erzeugt, gilt der alte nicht mehr.
„Dieser Server ist im Prox-Panel gesperrt“ oder „abgelaufen“
Im Panel den Status prüfen oder das Paket verlängern. Prox versucht es alle 5 Minuten neu und verbindet sich danach von selbst.
Spieler hören nichts
- Ist der Browser-Tab offen und steht oben „Verbunden“?
- Im Tab unter „Verbindung“ steht, ob UDP oder TCP genutzt wird. Blockiert eine Firewall UDP, wechselt Prox automatisch auf TCP.
- Chrome im Hintergrund: siehe Chrome-Tipp.
- Ist der Spieler tot, gesperrt oder im Modus „Nur Funk“?
/proxstatuszeigt es.
Handy oder Funk reagieren nicht
Die Ressource muss nach prox starten. Wurde prox neu gestartet, auch Handy und Funk einmal neu starten, damit sie die Exports neu laden.
Das Verbinden-Fenster kommt im Ladebildschirm
Config.Prompt.event auf das Event setzen, das dein Charakter-Menü nach dem Spawn auslöst, und delay erhöhen.