Instalación
Diez minutos, y la mayor parte es esperar a que arranque el servidor. No hay archivo SQL que importar ni un segundo programa que ejecutar: las tablas se crean solas la primera vez que arranca el recurso.
Cada paso de abajo termina con cómo saber que ha funcionado, para que nunca pases al siguiente con dudas.
Antes de empezar
Sección titulada «Antes de empezar»| Necesitas | Por qué |
|---|---|
| oxmysql, en marcha | Todo lo que recuerda el móvil vive en tu base de datos |
| ESX, QBCore, QBox o fmLib | Se detecta solo; no tienes que decir cuál |
| Un servidor FiveM de los últimos dos años | La parte web del móvil usa el Node integrado del servidor |
Nada más. Sin npm, sin paso de compilación, sin servidor web.
1. Coloca la carpeta
Sección titulada «1. Coloca la carpeta»Suelta mic_phone en tus resources; dentro de una carpeta entre corchetes queda más ordenado:
resources/[mic]/mic_phone/Mantén el nombre de carpeta mic_phone. No se rompe nada si la renombras, pero la dirección web del móvil se construye a partir del nombre de la carpeta, así que cualquier cosa que hayas apuntado sobre ella cambiaría también.
2. Arráncalo después de aquello en lo que se apoya
Sección titulada «2. Arráncalo después de aquello en lo que se apoya»En server.cfg, debajo de oxmysql y debajo de tu framework:
ensure oxmysqlensure es_extended # or qb-core / qbx_coreensure mic_phoneHa funcionado si la consola dice, al arrancar:
[mic_phone] web: door B listening on http://0.0.0.0:30125 · door A at /mic_phone/web/ on the game portSi en su lugar ves una línea roja sobre un framework, arranca mic_phone después de tu framework: casi siempre es eso.
3. La base de datos: no hay nada que hacer
Sección titulada «3. La base de datos: no hay nada que hacer»El primer arranque lee sql/schema.sql y crea lo que falte. Verás pasar una serie de líneas CREATE TABLE IF NOT EXISTS mic_phone_…. Eso es todo.
Ha funcionado si esas líneas aparecen una vez y nunca más en los arranques siguientes.
4. Dale a los jugadores algo que abrir
Sección titulada «4. Dale a los jugadores algo que abrir»De serie, el móvil necesita un ítem de inventario llamado phone:
-- shared/config.luaConfig.Open = { RequireItem = true, Item = 'phone', ...}La mayoría de instalaciones de ESX y QB ya tienen ese ítem. Usuarios de ox_inventory: añadidlo a vuestra lista de ítems si no está. ¿Solo quieres probarlo? Pon RequireItem = false y sáltate esto por completo.
Ha funcionado si entras, llevas el ítem y F1 abre el móvil. /phone hace lo mismo, y T lo despliega en la tablet mientras está abierto.
5. Ajustes solo del servidor
Sección titulada «5. Ajustes solo del servidor»Copia el ejemplo y rellena lo que quieras:
shared/server_config.example.lua → shared/server_config.luaEste archivo se carga solo como script de servidor, así que nada de lo que contiene llega nunca a un jugador. Ahí viven dos cosas:
Fotos, vídeos y notas de voz. Pon un token de medios de Fivemanage en ServerConfig.Media.Token (o la convar FIVEMANAGE_MEDIA_API_KEY) y el móvil sube los archivos por sí mismo, guardando solo el enlace resultante. Un webhook de Discord sirve como alternativa.
Si no configuras ninguno de los dos,
FallbackToDataUrlguarda el archivo dentro de tu base de datos. Eso está bien para una prueba y pesa mucho en producción: unos segundos de voz son decenas de kilobytes en cada fila que toca. Pon un token, o desactiva esa opción y deja que las subidas fallen de forma visible.
Webhooks de Discord. Una URL por tipo de evento, o Default para recogerlo todo. El que vale la pena configurar aunque te saltes el resto es Server: es el único que te informa sobre el servidor y no sobre un jugador: la dirección ha cambiado, un certificado no se ha renovado.
Ya está
Sección titulada «Ya está»El móvil funciona. Todo lo que sigue es opcional.
Opcional: el móvil en un móvil real
Sección titulada «Opcional: el móvil en un móvil real»Los jugadores pueden llevar el móvil de su personaje en su propio teléfono. Ya está activado: Ajustes › Dispositivos enlazados en el móvil del juego muestra un QR, lo escanean y escriben en el juego los seis dígitos que les muestra. A partir de ahí, ese dispositivo actúa como ese personaje.
Por HTTP normal eso ya les da mensajes, correo, contactos, el garaje, propiedades y el resto. Lo que un navegador no le da a una página insegura es lo mejor:
| HTTP normal | HTTPS | |
|---|---|---|
| Mensajes, correo, garaje, todo lo demás | sí | sí |
| Notificaciones con la app cerrada | no | sí |
| Llamadas | no | sí |
| El micrófono, para notas de voz | no | sí |
| Instalarlo como app, con su propio icono | no | sí |
Conseguir HTTPS sin instalar nada
Sección titulada «Conseguir HTTPS sin instalar nada»Este recurso puede obtener y renovar su propio certificado. Apunta un nombre a tu servidor, abre dos puertos y rellena tres líneas:
-- 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' }, },}- Un nombre. En un VPS es un registro A que apunta a su dirección. ¿No tienes dominio?
duckdns.orgte da uno gratis en un minuto. - Puerto 80 y puerto 443 abiertos en el firewall. El 80 solo se abre mientras se pide un certificado, y se vuelve a cerrar en cuanto llega la respuesta.
Ha funcionado si la consola dice:
https: asking for phone.yourserver.comhttps: port 80 open for the challengehttps: challenge port closedhttps: certificate in hand, good until 2027-01-31https: listening on https://phone.yourserver.com/Si el 443 está ocupado (algunos routers lo reservan para su propia página de administración), sirve en otro puerto: Port = 8443, redirige el 8443 y escribe Url = 'https://phone.yourserver.com:8443/'. Solo el desafío tiene que ir por el 80; un certificado pertenece a un nombre, no a un puerto, y todo sigue funcionando.
docs/HTTPS.md cubre las demás situaciones: detrás del proxy de Cfx.re, detrás de un proxy inverso que ya tengas, en un host que no te da puertos.
Cuando algo no va bien
Sección titulada «Cuando algo no va bien»phonehttps check: pregunta al servidor de pruebas de la autoridad de certificación si hablará con tu máquina. Ejecútalo primero cuando no llegue ningún certificado: separa tu firewall de este recurso.
phonehttps: en qué estado está el certificado y cuándo se renueva.
phoneduck: en qué estado está el nombre, si este servidor mantiene su propio nombre de DuckDNS apuntando a sí mismo, y cuándo lo comunicó por última vez. phoneduck now envía la dirección que tiene en ese momento e imprime lo que ha respondido DuckDNS, que es la forma de descubrir que un token está mal sin esperar a que cambie la dirección.
| Lo que ves | Qué es |
|---|---|
| El móvil no se abre | No hay ítem phone, o RequireItem está activado y no llevan uno |
| El QR apunta a un sitio inalcanzable | Configura ServerConfig.Web.Url a mano; la detección automática no ve más allá de un router que ha cambiado el puerto |
| No hay certificado, y el log culpa al desafío | El puerto 80 no llega a esta máquina. Revisa la redirección y el firewall, en ese orden |
| Las fotos son enormes / la base de datos crece rápido | No hay token de medios, y FallbackToDataUrl está guardando los archivos en la base de datos |
| Las llamadas entre dos jugadores no tienen sonido | La voz está en auto y no ha encontrado ningún recurso de voz; indica el tuyo en Config.Bridge.voice |
Antes de abrir tu ciudad
Sección titulada «Antes de abrir tu ciudad»shared/server_config.luaes tuyo. No lo compartas nunca ni lo subas a ningún sitio público; contiene tu token de medios y las URL de tus webhooks.- Apunta el webhook
Servera un sitio que leas. Es el que avisa de que la puerta de entrada del móvil ha dejado de funcionar, y es el único aviso que tendrás antes de que te lo diga un jugador. - Desactiva
Config.Debugsi lo activaste: imprime en la consola cada decisión del bridge. - Vale la pena dedicar diez minutos a Seguridad si llevas una ciudad pública: qué supone este recurso sobre las personas que se conectan a él, y las reglas que mantiene para que un cliente modificado no pueda ir más allá de su propio personaje.