Requisitos previos
Game Chat 2 requiere que su proyecto se haya configurado para el GDK. Para obtener más información sobre cómo configurarlo, consulte Introducción al Microsoft Game Development Kit. Para compilar Game Chat 2 es necesario incluir el encabezado principal GameChat2.h. Para que la vinculación sea correcta, su proyecto también debe incluir GameChat2Impl.h en al menos una unidad de compilación (se recomienda un encabezado precompilado común, ya que estas implementaciones de funciones stub son pequeñas y fáciles de generar como “inline” para el compilador). La interfaz de Game Chat 2 no requiere que un proyecto elija entre compilar con C++/CX o con C++ tradicional. Se puede usar con cualquiera de los dos. La implementación tampoco produce excepciones como medio de notificación de errores no irrecuperables. Puede consumirla fácilmente desde proyectos sin excepciones, si lo prefiere. Sin embargo, la implementación sí produce excepciones como medio de notificación de errores irrecuperables. (Para obtener más información, consulte la sección Modelo de errores más adelante en este tema).Inicialización
Empiece a interactuar con la biblioteca inicializando la instancia singleton de Game Chat 2 con parámetros que se aplican a la duración de la inicialización del singleton. La instancia singleton se inicializa llamando a chat_manager::initialize, como se muestra a continuación.Debe registrarse para los eventos de suspensión y reanudación mediante
RegisterAppStateChangeNotification. Al suspender, debe limpiar Game Chat 2 con chat_manager::cleanup(). Al reanudar, debe reinicializar Game Chat 2. Podría bloquearse si intenta usarlo a través de un ciclo de suspensión y reanudación.Configuración de usuarios
Adición de usuarios a su título del Microsoft Game Development Kit (GDK)
Antes de agregar usuarios a la instancia de Game Chat 2, asegúrese de que se hayan agregado al título del GDK. Esto se hace mediante la API XUserAddAsync. Para obtener más información sobre el uso de esta API, consulte Identidad de usuario y XUser. Después de tener elXUserHandle del usuario que desea agregar a Game Chat 2, debe obtener el identificador de usuario de XBOX (XUID) del usuario mediante la API XUserGetId.
El usuario debe estar en línea y debe contar con el consentimiento del usuario para este paso.
XUserGetId proporciona el XUID como un uint64_t. Debe convertir el XUID en un std::wstring para usarlo con Game Chat 2.
A continuación se muestra un ejemplo de código que muestra cómo agregar un usuario a Game Chat 2 después de tener un XUserHandle.
Tenga en cuenta que llamar a XUserResolveIssueWithUiAsync muestra un cuadro de diálogo del sistema.
Adición de usuarios a Game Chat 2
Una vez inicializada la instancia, debe agregar los usuarios locales a la instancia de Game Chat 2 mediante chat_manager::add_local_user. En este ejemplo, el usuario A representa un usuario local.c_communicationRelationshipSendAndReceiveAll es una constante definida en GameChat2.h para representar la comunicación bidireccional.
Establezca la relación del usuario A con el usuario B mediante chat_user_local::set_communication_relationship.
c_communicationRelationshipSendAll es una constante definida en GameChat2.h para representar esta comunicación unidireccional.
Establezca las relaciones de la manera siguiente.
chat_manager::remove_user() puede invalidar el objeto de usuario. Si usa la manipulación de audio en tiempo real, consulte Duración de los usuarios de chat para obtener más información. De lo contrario, el objeto de usuario se invalida inmediatamente cuando se llama a chat_manager::remove_user(). Una restricción sutil sobre cuándo se pueden quitar usuarios se detalla en la sección Procesamiento de cambios de estado más adelante en este tema.
Procesamiento de fotogramas de datos
Game Chat 2 no tiene su propia capa de transporte. La aplicación debe proporcionarla. Este complemento se administra mediante las llamadas regulares y frecuentes de la aplicación al par de métodos chat_manager::start_processing_data_frames() y chat_manager::finish_processing_data_frames(). Estos métodos son la forma en que Game Chat 2 proporciona datos salientes a la aplicación. Estos métodos están diseñados para funcionar con rapidez. Se pueden sondear con frecuencia en un subproceso de red dedicado. Esto proporciona un lugar conveniente para recuperar todos los datos en cola sin preocuparse por la imprevisibilidad de los tiempos de la red ni por la complejidad de las devoluciones de llamada multiproceso. Cuando se llama achat_manager::start_processing_data_frames(), todos los datos en cola se notifican en una matriz de punteros a estructuras game_chat_data_frame.
Las aplicaciones deben iterar por la matriz, inspeccionar los puntos de conexión de destino y usar la capa de red de la aplicación para entregar los datos a las instancias remotas adecuadas de la aplicación.
Una vez que se haya terminado de usar la matriz con todas las estructuras game_chat_data_frame, la matriz debe devolverse a Game Chat 2 para liberar los recursos llamando a chat_manager:finish_processing_data_frames().
Esto se muestra en el ejemplo siguiente.
Procesamiento de cambios de estado
Game Chat 2 proporciona actualizaciones a la aplicación, como los mensajes de texto recibidos, mediante las llamadas regulares y frecuentes de la aplicación al par de métodos chat_manager::start_processing_state_changes() y chat_manager::finish_processing_state_changes(). Estos métodos funcionan con rapidez, por lo que se pueden llamar en cada fotograma gráfico de su bucle de representación de la interfaz de usuario. Esto proporciona un lugar conveniente para recuperar todos los cambios en cola sin preocuparse por la imprevisibilidad de los tiempos de la red ni por la complejidad de las devoluciones de llamada multiproceso. Cuando se llama achat_manager::start_processing_state_changes(), todas las actualizaciones en cola se notifican en una matriz de punteros a estructuras game_chat_state_change.
Las aplicaciones deben iterar por la matriz, inspeccionar la estructura base para conocer su tipo más específico, convertir la estructura base al tipo más detallado correspondiente y, a continuación, controlar esa actualización según corresponda.
Una vez que se haya terminado de usar la matriz con todos los objetos game_chat_state_change disponibles actualmente, la matriz debe devolverse a Game Chat 2 para liberar los recursos llamando a chat_manager::finish_processing_state_changes().
Esto se muestra en el ejemplo siguiente.
chat_manager::remove_user() invalida inmediatamente la memoria asociada a un objeto de usuario, y los cambios de estado pueden contener punteros a objetos de usuario, no se debe llamar a chat_manager::remove_user() mientras se procesan cambios de estado.
Chat de texto
Para enviar chat de texto, use chat_user::chat_user_local::send_chat_text(). Esto se muestra en el ejemplo siguiente.Accesibilidad
La accesibilidad requiere admitir la entrada y la visualización de chat de texto. La entrada de texto es necesaria porque, incluso en plataformas o géneros de juego que históricamente no han tenido un uso generalizado del teclado físico, los usuarios pueden configurar el sistema para usar tecnologías de asistencia de texto a voz. Del mismo modo, la visualización de texto es necesaria porque los usuarios pueden configurar el sistema para usar voz a texto. Estas preferencias se pueden detectar en los usuarios locales llamando a los métodos chat_user::chat_user_local::text_to_speech_conversion_preference_enabled() y chat_user::chat_user_local::speech_to_text_conversion_preference_enabled(), respectivamente. Se recomienda habilitar el texto de forma condicional, en función de las preferencias del usuario.Texto a voz
Cuando un usuario tiene habilitado el texto a voz, chat_user::chat_user_local::text_to_speech_conversion_preference_enabled() devuelvetrue. Cuando se detecta este estado, la aplicación debe proporcionar un método de entrada de texto.
Después de obtener la entrada de texto proporcionada por un teclado real o virtual, pase la cadena al método chat_user::chat_user_local::synthesize_text_to_speech(). Game Chat 2 detecta y sintetiza datos de audio basados en la cadena y en la preferencia de voz de accesibilidad del usuario.
Esto se muestra en el ejemplo siguiente.
chat_user::chat_user_local::synthesize_text_to_speech() en un usuario que no tiene habilitado el texto a voz, Game Chat 2 no realiza ninguna acción.
Voz a texto
Cuando un usuario tiene habilitada la conversión de voz a texto, chat_user::chat_user_local::speech_to_text_conversion_preference_enabled() devuelvetrue. Cuando se detecta este estado, la aplicación debe estar preparada para proporcionar una interfaz de usuario asociada a los mensajes de chat transcritos. Game Chat 2 transcribe automáticamente el audio de cada usuario remoto y lo expone mediante una estructura game_chat_transcribed_chat_received_state_change.
Consideraciones de rendimiento de la conversión de voz a texto
Cuando la conversión de voz a texto está habilitada, la instancia de Game Chat 2 de cada dispositivo remoto inicia una conexión WebSocket con el punto de conexión de los servicios de voz. Cada cliente remoto de Game Chat 2 carga audio en el punto de conexión de los servicios de voz a través de este WebSocket. El punto de conexión de los servicios de voz devuelve ocasionalmente un mensaje de transcripción al dispositivo remoto. A continuación, el dispositivo remoto envía el mensaje de transcripción (es decir, un mensaje de texto) al dispositivo local. Game Chat 2 entrega el mensaje transcrito a la aplicación para que lo represente. Por lo tanto, el costo de rendimiento principal de la conversión de voz a texto es el uso de la red. La mayor parte del tráfico de red es la carga de audio codificado. El WebSocket carga audio que ya ha sido codificado por Game Chat 2 en la ruta “normal” del chat de voz. La aplicación tiene control sobre la velocidad de bits mediante chat_manager::set_audio_encoding_bitrate.Interfaz de usuario
Se recomienda que, en cualquier lugar donde se muestre una interfaz de usuario a los usuarios, especialmente en una lista de gamertags como un marcador, también se muestren iconos de silenciado o hablando como comentarios para el usuario. Esto se hace llamando a chat_user::chat_indicator() para recuperar una enumeración game_chat_user_chat_indicator que representa el estado actual e instantáneo del chat de ese usuario. El siguiente ejemplo muestra cómo recuperar el valor del indicador de un objeto chat_user al que apunta la variablechatUserA para determinar un valor constante de icono concreto que asignar a una variable iconToShow.
Silenciado
El método chat_user::chat_user_local::set_microphone_muted() se puede usar para cambiar el estado de silencio del micrófono de un usuario local. Cuando el micrófono está silenciado, no se captura audio de ese micrófono. Si el usuario está en un dispositivo compartido, como Kinect, el estado de silencio se aplica a todos los usuarios. El método chat_user::chat_user_local::microphone_muted() se puede usar para recuperar el estado de silencio del micrófono de un usuario local. Este método solo refleja si el micrófono del usuario local se ha silenciado por software mediante una llamada achat_user::chat_user_local::set_microphone_muted(). Este método no refleja un silencio controlado por hardware, por ejemplo, mediante un botón de los auriculares del usuario.
No existe ningún método para recuperar el estado de silencio de hardware del dispositivo de audio de un usuario a través de Game Chat 2.
El método chat_user::chat_user_local::set_remote_user_muted() se puede usar para cambiar el estado de silencio de un usuario remoto en relación con un usuario local concreto. Cuando el usuario remoto está silenciado, el usuario local no oirá ningún audio ni recibirá ningún mensaje de texto del usuario remoto.
Silencio automático por mala reputación
Normalmente, los usuarios remotos comienzan sin silenciar. Game Chat 2 inicia a los usuarios en estado silenciado cuando:- El usuario remoto no es amigo del usuario local.
- El usuario remoto tiene una marca de mala reputación.
chat_user::chat_indicator() devuelve game_chat_user_chat_indicator::reputation_restricted.
Este estado se invalida con la primera llamada a chat_user::chat_user_local::set_remote_user_muted() que incluya al usuario remoto como usuario de destino.
Privilegios y privacidad
Además de la relación de comunicación configurada por el juego, Game Chat 2 aplica restricciones de privilegios y privacidad. Game Chat 2 realiza búsquedas de restricciones de privilegios y privacidad cuando se agrega un usuario por primera vez. Elchat_user::chat_indicator() del usuario siempre devuelve game_chat_user_chat_indicator::silent hasta que se hayan completado esas operaciones.
Si la comunicación con un usuario se ve afectada por una restricción de privilegios o privacidad, el chat_user::chat_indicator() del usuario devuelve game_chat_user_chat_indicator::platform_restricted.
Las restricciones de comunicación de la plataforma se aplican tanto al chat de voz como al de texto. Nunca se dará el caso de que el chat de texto esté bloqueado por una restricción de plataforma pero el chat de voz no, ni viceversa.
chat_user::chat_user_local::get_effective_communication_relationship() se puede usar para ayudar a distinguir cuándo los usuarios no pueden comunicarse debido a operaciones de privilegios y privacidad incompletas.
Devuelve la relación de comunicación aplicada por Game Chat 2 en forma de game_chat_communication_relationship_flags y el motivo por el que la relación puede no ser igual a la relación configurada en forma de una enumeración game_chat_communication_relationship_adjuster.
Por ejemplo, si las operaciones de búsqueda siguen en curso, el game_chat_communication_relationship_adjuster será game_chat_communication_relationship_adjuster::initializing.
Este método no debe usarse para influir en la interfaz de usuario. (Para obtener más información, consulte la sección Interfaz de usuario anteriormente en este tema).
Si Game Chat 2 encuentra un problema de privilegios, se notificará en el cambio de estado communication_relationship_adjuster_changed.
Si Game Chat 2 no puede recuperar el privilegio del usuario por un motivo irrecuperable, se notificará como un ajustador game_chat_communication_relationship_adjuster::privilege_check_failure.
Si Game Chat 2 no puede recuperar el privilegio del usuario por un motivo que el usuario podría resolver, se notificará como un ajustador game_chat_communication_relationship_adjuster::resolve_user_issue.
Si al usuario le faltan privilegios que podrían resolverse con la interfaz de usuario, se notificará como un ajustador game_chat_communication_relationship_adjuster::privilege.
En estos casos, la comunicación estará restringida.
A continuación se muestra un ejemplo de cómo comprobar si un usuario tiene uno de los siguientes problemas comunes.
- Los usuarios deben dar su consentimiento a los servicios de XBOX para que Game Chat 2 compruebe los privilegios.
- La cuenta del usuario está configurada para denegar privilegios (por ejemplo, por ser una cuenta infantil y, por tanto, no poder usar el chat).
game_chat_communication_relationship_adjuster::privilege, puede llamar a XUserResolvePrivilegeWithUiAsync con XUserPrivilegeOptions::None y XUserPrivilege::Communications para intentar resolver el problema.
Para los problemas notificados con el ajustador game_chat_communication_relationship_adjuster::resolve_user_issue, puede llamar a XUserResolveIssueWithUiAsync con nullptr como dirección URL para intentar resolver el problema.
Se recomienda mostrar una interfaz de usuario que indique que hay un problema de privilegios. Permita que el usuario decida si desea intentar resolver el problema, ya sea presionando un botón o mediante una opción de menú.
Es posible que el usuario no pueda o no quiera resolver el problema.
Si el usuario resuelve el problema, se aplicará la próxima vez que se agregue el usuario a Game Chat 2.
No se debe llamar a chat_manager::remove_user() mientras se procesan cambios de estado (es decir, después de llamar a chat_manager::start_processing_state_changes() y antes de la llamada correspondiente a chat_manager::finish_processing_state_changes()). Llamar a
chat_manager::remove_user() mientras se procesan cambios de estado puede invalidar la memoria asociada al usuario quitado.
Si ve un ajustador game_chat_communication_relationship_adjuster::privilege y desea intentar resolver los privilegios del usuario, debe esperar hasta después de procesar los cambios de estado para intentarlo.XUserHandle a partir de un XUID, que es necesario para llamar a XUserResolvePrivilegeWithUiAsync, puede usar la API XUserFindUserById para obtener un nuevo XUserHandle. Como alternativa, puede conservar el que adquirió con XUserAddAsync y realizar un seguimiento de a qué XUID se asigna.
A continuación se muestra un ejemplo de cómo resolver estos problemas.
Limpieza
Cuando la aplicación ya no necesite las comunicaciones a través de Game Chat 2, debe llamar a chat_manager::cleanup(). Esto permite que Game Chat 2 recupere los recursos que se asignaron para administrar las comunicaciones.Modelo de errores
La implementación de Game Chat 2 no produce excepciones como medio de notificación de errores no irrecuperables. Puede consumirla fácilmente desde proyectos sin excepciones, si lo prefiere. Sin embargo, Game Chat 2 sí produce excepciones para informarle de errores irrecuperables. Estos errores son el resultado de un uso incorrecto de la API, como agregar un usuario a la instancia de Game Chat antes de inicializar la instancia o acceder a un objeto de usuario después de que se haya quitado de la instancia de Game Chat 2. Se espera que estos errores se detecten al principio del desarrollo y se puedan corregir modificando el patrón que se usa para interactuar con Game Chat 2. Cuando se produce un error de este tipo, se imprime en el depurador una sugerencia sobre la causa del error antes de que se genere la excepción.Cómo configurar escenarios populares
Pulsar para hablar
La funcionalidad de pulsar para hablar debe implementarse con chat_user::chat_user_local::set_microphone_muted(). Llame aset_microphone_muted(false) para permitir la voz y a set_microphone_muted(true) para restringirla.
Este método proporciona la respuesta de menor latencia de Game Chat 2.
