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
148 lines
4.2 KiB
Dart
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,
|
|
});
|
|
}
|
|
}
|