Files
farolero/lib/servicios/servicio_nearby.dart
ShanaiaBot de2c8ffa18 El Impostor v0.1 — app Flutter completa
Juego de deducción social para 3-20 jugadores.
Modo un solo móvil completamente funcional.
1000 palabras en 10 categorías.
Notas privadas, votación, adivinanza, revancha.
Material 3 dark theme.
Package: es.freetimelab.elimpostor
2026-04-04 00:50:04 +02:00

148 lines
4.2 KiB
Dart

import 'dart:convert';
import 'package:flutter/foundation.dart';
/// Tipos de mensajes en el protocolo P2P
enum TipoMensaje {
salaInfo,
partidaInicio,
fase,
votacionResultado,
partidaFin,
unirse,
voto,
listo,
}
/// Mensaje del protocolo P2P entre dispositivos
class MensajeP2P {
final TipoMensaje tipo;
final Map<String, dynamic> datos;
MensajeP2P({required this.tipo, required this.datos});
String toJson() => json.encode({
'tipo': tipo.name,
'datos': datos,
});
factory MensajeP2P.fromJson(String jsonStr) {
final mapa = json.decode(jsonStr) as Map<String, dynamic>;
return MensajeP2P(
tipo: TipoMensaje.values.firstWhere((t) => t.name == mapa['tipo']),
datos: mapa['datos'] as Map<String, dynamic>,
);
}
}
/// Servicio para conexiones P2P usando Google Nearby Connections API.
///
/// Este servicio encapsula toda la lógica de Nearby Connections.
/// Requiere dispositivos Android físicos para funcionar.
/// En la versión actual, se provee la estructura para integración futura.
class ServicioNearby extends ChangeNotifier {
bool _esHost = false;
bool _conectado = false;
String? _endpointId;
final List<String> _dispositivos = [];
bool get esHost => _esHost;
bool get conectado => _conectado;
String? get endpointId => _endpointId;
List<String> get dispositivos => List.unmodifiable(_dispositivos);
/// Inicia como host (anunciando el endpoint)
Future<bool> iniciarHost(String nombreSala) async {
// Nota: nearby_connections requiere permisos de ubicación y Bluetooth
// que deben solicitarse antes de iniciar.
// Implementación con el paquete nearby_connections:
//
// try {
// await Nearby().startAdvertising(
// nombreSala,
// Strategy.P2P_STAR,
// onConnectionInitiated: _onConexionIniciada,
// onConnectionResult: _onResultadoConexion,
// onDisconnected: _onDesconexion,
// serviceId: 'es.freetimelab.elimpostor',
// );
// _esHost = true;
// _endpointId = nombreSala;
// notifyListeners();
// return true;
// } catch (e) {
// debugPrint('Error iniciando host: $e');
// return false;
// }
_esHost = true;
_endpointId = nombreSala;
notifyListeners();
return true;
}
/// Conecta a un host escaneado via QR
Future<bool> conectarAHost(String endpointId, String nombre) async {
// Implementación con el paquete nearby_connections:
//
// try {
// await Nearby().startDiscovery(
// nombre,
// Strategy.P2P_STAR,
// onEndpointFound: (id, name, serviceId) {
// Nearby().requestConnection(nombre, id,
// onConnectionInitiated: _onConexionIniciada,
// onConnectionResult: _onResultadoConexion,
// onDisconnected: _onDesconexion,
// );
// },
// onEndpointLost: (id) {},
// serviceId: 'es.freetimelab.elimpostor',
// );
// return true;
// } catch (e) {
// debugPrint('Error conectando: $e');
// return false;
// }
_conectado = true;
notifyListeners();
return true;
}
/// Envía un mensaje a un dispositivo específico
Future<void> enviarMensaje(String endpointId, MensajeP2P mensaje) async {
// Implementación:
// final bytes = Uint8List.fromList(utf8.encode(mensaje.toJson()));
// await Nearby().sendBytesPayload(endpointId, bytes);
debugPrint('Enviar a $endpointId: ${mensaje.toJson()}');
}
/// Envía un mensaje a todos los dispositivos conectados
Future<void> enviarATodos(MensajeP2P mensaje) async {
for (final id in _dispositivos) {
await enviarMensaje(id, mensaje);
}
}
/// Desconecta y limpia
Future<void> desconectar() async {
// await Nearby().stopAllEndpoints();
// await Nearby().stopAdvertising();
// await Nearby().stopDiscovery();
_esHost = false;
_conectado = false;
_endpointId = null;
_dispositivos.clear();
notifyListeners();
}
/// Genera los datos para el código QR de conexión
String generarDatosQR(String nombreSala) {
return json.encode({
'app': 'elimpostor',
'endpoint': _endpointId,
'sala': nombreSala,
});
}
}