Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

635 lines
24 KiB

/*==========================================================================
*
* Copyright (C) 1999 Microsoft Corporation. All Rights Reserved.
*
* File: dvprotocol.h
* Content: Defines structures / types for DirectXVoice protocol
*
* History:
* Date By Reason
* ==== == ======
* 07/02/99 rodtoll Created It
* 07/21/99 rodtoll Added settings confirm message to protocol
* 08/18/99 rodtoll Changed the message type to a BYTE
* 08/25/99 rodtoll General Cleanup/Modifications to support new
* compression sub-system.
* 09/07/99 rodtoll Moved definition of settarget message to dvoice.h
* 09/30/99 rodtoll Updated to include more comments
* 12/16/99 rodtoll Updated to include new messages used by host migration
* and update protocol number
* 01/14/2000 rodtoll Updated with new speech packets which optimize peer
* to peer and allow multiple targets in multicast/mixing
* and updated protocol number.
* 04/07/2000 rodtoll Code cleanup, proper structure defs
* 01/04/2001 rodtoll WinBug #94200 - Remove stray comments
* 01/22/2001 rodtoll WINBUG #288437 - IA64 Pointer misalignment due to wire packets
*
***************************************************************************/
#ifndef __DVPROTOCOL_H
#define __DVPROTOCOL_H
#pragma pack(push,1)
// DVPROTOCOL_VERSION_XXXXXX
//
// These are the values developers should use to send in the ucVersionMajor
// ucVersionMinor and dwVersionBuild (respectively) members of the ConnectRequest
// and connect accept messages.
#define DVPROTOCOL_VERSION_MAJOR 1
#define DVPROTOCOL_VERSION_MINOR 0
#define DVPROTOCOL_VERSION_BUILD 3
//
// PROTOCOL DESCRIPTION
//
// Connection Process
// ------------------
//
// Clients connect to the voice session by sending a DVPROTOCOLMSG_CONNECTREQUEST.
// The host then determines if the client is allowed to join the session. If
// the client's request is rejected, the client receives a DVPROTOCOLMSG_CONNECTREFUSE.
// If the client's request is accepted, the client receives a
// DVPROTOCOLMSG_CONNECTACCEPT. This packet contains all the information the client
// requires to determine if they are compatible.
//
// The client will then attempt to initialize themselves using the compression
// type transmitted by the server. If the client fails to initialize it takes
// no further action. If the client initializes succesfully it transmits a
// DVPROTOCOLMSG_SETTINGSCONFIRM message and is added to the session. All players
// in the session will then receive a DVPROTOCOLMSG_PLAYERJOIN.
//
// Until a DVPROTOCOLMSG_SETTINGSCONFIRM message is received by the host, the client is
// not considered to be part of the session. As such it will not transmit
// speech. (However, it may receive speech).
//
// The server then sends DVPROTOCOLMSG_PLAYERLIST message(s) to give the client the
// current player table. (Peer to peer only).
//
// Disconnection Process
// ---------------------
//
// If a client wishes to disconnect from the voice session, it sends a
// DVPROTOCOLMSG_DISCONNECT message to the host. The host will then transmit
// to all players a DVPROTOCOLMSG_PLAYERQUIT message and will send a
// DVPROTOCOLMSG_DISCONNECT message back to the player to confirm.
//
// If the client disconnects unexpectedly the voice host will detect this and
// will automatically send DVPROTOCOLMSG_PLAYERQUIT messages to all the other clients
// in the session.
//
// Speech Messages
// ---------------
//
// Speech messages are described in detail in the description for DVPROTOCOLMSG_SPEECH.
//
// Messages sent from the host are sent with the DVMSGID_SPEECHBOUNCE instead
// of DVMSGID_SPEECH so that whena host and client share a single dplay id
// the client can ignore it's own speech packets.
//
// Host Migration
// --------------
//
// NEW HOST MIGRATION
//
// Pros/Cons:
//
// First, the advantages to the new system:
// - The new host migration mechanism allows DirectPlay Voice to have a host
// - seperate from the directplay host.
// - Shutting down the host without stopping the dplay interface causes voice host
// to migrate.
// - Minimizes changes to directplay.
// - Removes requirement that all clients had to run voice clients.
// - You can prevent the host from migrating when you call stopsession by
// specifying the new DVFLAGS_NOHOSTMIGRATE which causes the session to be
// stopped.
//
// Disadvantages of the new system:
// - If there are no voice clients in the session when the host is lost, then the
// voice session will be lost.
//
// Host Election
//
// In order to elect a new host, each client is given a "Host Order ID" when
// they have completed their connection. All clients are informed of an
// individual's "Host Order ID" when they find out about the player. These
// identifiers start at 0, are a DWORD in size, and are incremented with each
// new user. Therefore the first player in the session will have ID 0, the
// second will have ID 1, etc.
//
// By using this method we ensure that the client elected to be the host will be
// the oldest client in the session. This has the advantage (because of the way
// the name table is distributed) if any client has any clients at all, they
// will have the oldest clients. Therefore everyone in the session will either
// have just themselves, or at the very least the client who will become the new
// host. If a client doesn't have anyone in the session, it means they either
// are the only ones in the session (in which case they become the new host) or
// they haven't received the name table yet. If they haven't received the name
// table they will not yet have a "Host Order ID" and will therefore be
// inelligable to become the new host.
//
// When the host migrates to a new host, the new host offsets a constant (in
// this case defined in dvcleng.cpp as DVMIGRATE_ORDERID_OFFSET) from it's own
// Host Order ID and uses it as the next Host Order ID to hand out. (So
// duplicate host order IDs are not handed out).
//
// Unless.. you get DVMIGRATE_ORDERID_OFFSET connects between when the new host
// joined and a new player joins before a player with a higher ID joins. (If a
// player informs the server that it's Host Order ID is > then the seed the host
// bumps the seed to be DVMIGRATE_ORDERID_OFFSET from the user's value). In
// this case you may end up with > 1 host. (But this case is extremely unlikely).
//
// How It's Implemented
//
// Each client in the session knows the DPID of the host. Therefore, to detect
// the situation where the host will migrate the client looks at if the session
// supports host migration and for one of two things:
//
// - A DVPROTOCOLMSG_HOSTMIGRATELEAVE message - This is sent by the host when StopSession (
// without the DVFLAGS_NOHOSTMIGRATE flag) or Release is called.
// - DirectPlay informs DirectPlay Voice that the player ID belonging to the
// session host has left the session.
//
// Once one of the above occurs, each clients runs the new host election
// algorithm. Their action will depend on the situation:
//
// - If no clients are found that are elligible to become the new host. Then the
// client will disconnect.
// - If clients are found that are elligible to become the new host but it is not
// the local client, the local client takes no action.
// - If the local client is to be the new host then it starts up a new host locally.
//
// Once the new host starts up, it will send a DVPROTOCOLMSG_HOSTMIGRATE message to all
// the users in the session. Each client in the session responds with their
// current settings using a DVPROTOCOLMSG_SETTINGSCONFIRM message (which includes the
// client's current "Host Order ID". Using these messages the new host rebuilds
// the player list. Also, in response to the DVPROTOCOLMSG_SETTINGSCONFIRM message each
// client receives a copy of the latest name table. For players who respond to
// the host migration after you, DVPROTOCOLMSG_CREATEVOICEPLAYER messages will be sent.
// This player ensures that every client ends up with a proper and up to date
// name table.
//
// Each client in the session ignores duplicate CREATEVOICEPLAYER messages.
//
// The client object that creates the new host holds a reference to the new host
// and will destroy it when the client is destroyed. (Possibly causing the host
// to migrate again).
//
// Session Losses
//
// Using this new scheme it is possible to lose the voice session if there are
// no voice clients elligeble to become the new voice host. (Meaning there are
// no clients properly connected). All clients which are not yet completed
// their connection will detect this situation and will disconnect from the
// session.
//
// In addition, when the host goes to stop, it checks to see if there are any
// clients elligeble to become the host. If there are none it transmits a
// DVPROTOCOLMSG_SESSIONLOST message to all players in the session.
//
// Notes:
//
// One thing to watch for is since the DirectPlayVoice host may migrate to a
// different client then the DirectPlay host does, just because you know who the
// DirectPlay Host is doesn't mean you know who the voice host is.
//
// In order to implement this new mechanism the following related changes were
// made:
//
// - Clients with differing major/minor/build protocol version numbers are
// rejected by the host now. The result is that new clients may be able to
// connect to old hosts but may crash, and old clients are now rejected by new
// hosts. (Handling of these cases on old clients was not good -- just don't do
// it).
// - DirectPlay host migration messages are ignored.
// - Connection requests are sent to everyone in the session. The client
// determines who the host is by seeing who responded to their message.
// - Handling of rejection messages now results in the connection failing. (There
// was a bug).
// - The rejection message now contains the major/minor/build protocol version of
// the host.
// - Instead of sending individual messages for each user in the current session
// to a client when it first joins the host now sends a DVPROTOCOLMSG_PLAYERLIST which
// is a list of players in the session. This reduces bandwidth and makes the
// connection process shorter.
/////////////////////////////////////////////////////////////////////////////////
//
// PROTOCOL SPECIFIC DEFINES
//
/////////////////////////////////////////////////////////////////////////////////
// The maximum size in bytes that a single playerlist packet can be.
//
// (Holds about 120 entries / packet).
//
#define DVPROTOCOL_PLAYERLIST_MAXSIZE 1000
#define DVPROTOCOL_HOSTORDER_INVALID 0xFFFFFFFF
// DVMIGRATE_ORDERID_OFFSET
//
// This is the number to add to this client's Host Order ID to be the
// next value handed out by the host which the client is creating in
// response to host migration.
//
#define DVMIGRATE_ORDERID_OFFSET 256
/////////////////////////////////////////////////////////////////////////////////
//
// MESSAGE IDENTIFIERS
//
/////////////////////////////////////////////////////////////////////////////////
#define DVMSGID_INTERNALBASE 0x0050
#define DVMSGID_CONNECTREQUEST DVMSGID_INTERNALBASE+0x0001
#define DVMSGID_CONNECTREFUSE DVMSGID_INTERNALBASE+0x0003
#define DVMSGID_DISCONNECT DVMSGID_INTERNALBASE+0x0004
#define DVMSGID_SPEECH DVMSGID_INTERNALBASE+0x0005
#define DVMSGID_CONNECTACCEPT DVMSGID_INTERNALBASE+0x0006
#define DVMSGID_SETTINGSCONFIRM DVMSGID_INTERNALBASE+0x0008
#define DVMSGID_SETTINGSREJECT DVMSGID_INTERNALBASE+0x0009
#define DVMSGID_DISCONNECTCONFIRM DVMSGID_INTERNALBASE+0x000A
#define DVMSGID_SPEECHBOUNCE DVMSGID_INTERNALBASE+0x0010
#define DVMSGID_PLAYERLIST DVMSGID_INTERNALBASE+0x0011
#define DVMSGID_HOSTMIGRATELEAVE DVMSGID_INTERNALBASE+0x0012
#define DVMSGID_SPEECHWITHTARGET DVMSGID_INTERNALBASE+0x0013
#define DVMSGID_SPEECHWITHFROM DVMSGID_INTERNALBASE+0x0014
/////////////////////////////////////////////////////////////////////////////////
//
// CONNECT MESSAGES
//
/////////////////////////////////////////////////////////////////////////////////
//
// DVPROTOCOLMSG_CONNECTREQUEST
//
// Session Types: ALL
// Message Flow : Voice Client -> Voice Host
//
// Requests a connection to the existing DirectXVoice session.
//
typedef UNALIGNED struct _DVPROTOCOLMSG_CONNECTREQUEST
{
BYTE dwType; // = DVMID_CONNECTREQUEST
BYTE ucVersionMajor; // Client's protocol version (major)
BYTE ucVersionMinor; // Client's protocol version (minor)
DWORD dwVersionBuild; // Client's protocol version (build)
} DVPROTOCOLMSG_CONNECTREQUEST, *PDVPROTOCOLMSG_CONNECTREQUEST;
//
// DVPROTOCOLMSG_CONNECTREFUSE
//
// Session Types: ALL
// Message Flow : Voice Host -> Voice Clients
//
// Server responds with this if no voice session available or needs
// to refuse the connection. E.g. out of memory or incompatible
// version.
//
typedef UNALIGNED struct _DVPROTOCOLMSG_CONNECTREFUSE
{
BYTE dwType; // = DVMSGID_CONNECTREFUSE
HRESULT hresResult; // Reason for refusal (DVERR_XXXXXX)
BYTE ucVersionMajor; // Server's protocol version (major)
BYTE ucVersionMinor; // Server's protocol version (minor)
DWORD dwVersionBuild; // Server's protocol version (build)
} DVPROTOCOLMSG_CONNECTREFUSE, *PDVPROTOCOLMSG_CONNECTREFUSE;
//
// DVPROTOCOLMSG_CONNECTACCEPT
//
// Session Types: ALL
// Message Flow : Voice Host -> Voice Clients
//
// Indicates to the client that their connect request was accepted.
// This message contains information about the voice session that
// the client needs to initialize.
//
typedef UNALIGNED struct _DVPROTOCOLMSG_CONNECTACCEPT
{
BYTE dwType; // = DVMSGID_CONNECTACCEPT
DWORD dwSessionType; // Type of session = DVSESSIONTYPE_XXXXXX
BYTE ucVersionMajor; // Server's protocol version (major)
BYTE ucVersionMinor; // Server's protocol version (minor)
DWORD dwVersionBuild; // Server's protocol version (build)
DWORD dwSessionFlags; // Flags for the session (Combination of DVSESSION_XXXXXX values)
GUID guidCT; // Compression Type (= DPVCTGUID_XXXXXX)
} DVPROTOCOLMSG_CONNECTACCEPT, *PDVPROTOCOLMSG_CONNECTACCEPT;
//
// DVPROTOCOLMSG_SETTINGSCONFIRM
//
// Session Types: ALL
// Message Flow : Voice Client -> Voice Host
//
// Sent by client to confirm they can handle current compression
// settings. This message is sent once the client has determined that
// they can support the specified compression type and the sound
// system has succesfully initialized.
//
// This message is also sent from voice clients to the new voice host
// when a migration has taken place.
//
typedef UNALIGNED struct _DVPROTOCOLMSG_SETTINGSCONFIRM
{
BYTE dwType; // Message Type = DVMSGID_SETTINGSCONFIRM
DWORD dwFlags; // Client Flags (Only valid one is half duplex)
DWORD dwHostOrderID; // Host Order ID (=INVALID to assign new one)
} DVPROTOCOLMSG_SETTINGSCONFIRM, *PDVPROTOCOLMSG_SETTINGSCONFIRM;
//
// DVPROTOCOLMSG_PLAYERLIST
//
// Session Types: Peer to Peer
// Message Flow : Voice Host -> Voice Clients
//
// Builds a list of players in the session to be sent to the
// client once they have confirmed they are connected.
//
// May be spread over multiple packets.
//
// These messages will be the following header followed by a
// list of DVPROTOCOLMSG_PLAYERLIST_ENTRY structures (the # will be
// specified in dwNumEntries).
//
typedef UNALIGNED struct _DVPROTOCOLMSG_PLAYERLIST
{
BYTE dwType; // = DVMSGID_PLAYERLIST
DWORD dwHostOrderID; // Host migration sequence number (for client)
DWORD dwNumEntries; // Number of DVPROTOCOLMSG_PLAYERLIST_ENTRY structures
// following this header in this packet
} DVPROTOCOLMSG_PLAYERLIST, *PDVPROTOCOLMSG_PLAYERLIST;
//
// DVPROTOCOLMSG_PLAYERLIST_ENTRY
//
// Sent as part of a DVPROTOCOLMSG_PLAYERLIST message.
//
// Peer to Peer Only
//
// Each of these structures represents a player in the session.
// They are sent as part of the DVPROTOCOLMSG_PLAYERLIST structure.
//
typedef UNALIGNED struct _DVPROTOCOLMSG_PLAYERLIST_ENTRY
{
DVID dvidID; // Player's DVID
DWORD dwPlayerFlags; // Player's player flags (DVPLAYERCAPS_XXXXX)
DWORD dwHostOrderID; // Host migration sequence number
} DVPROTOCOLMSG_PLAYERLIST_ENTRY, *PDVPROTOCOLMSG_PLAYERLIST_ENTRY;
/////////////////////////////////////////////////////////////////////////////////////
//
// IN-SESSION MESSAGES - SPEECH
//
/////////////////////////////////////////////////////////////////////////////////////
//
// DVPROTOCOLMSG_SPEECHHEADER
//
// This message is used for transporting speech. Speech packets contain
// one of these headers followed by the audio data. After this header
// the audio data will be the remaining part of the packet.
//
// ----
//
// Session Types: Peer to Peer
// Message Flow : Voice Clients <-> Voice Clients
//
// Session Types: Mixing
// Message Flow : Voice Mixing Server --> Voice Clients
//
// Session Types: Echo
// Message Flow : Voice Host <-> Voice Clients
//
typedef UNALIGNED struct _DVPROTOCOLMSG_SPEECHHEADER
{
BYTE dwType; // = DVMSGID_SPEECH
BYTE bMsgNum; // Message # for message
BYTE bSeqNum; // Sequence # for message
} DVPROTOCOLMSG_SPEECHHEADER, *PDVPROTOCOLMSG_SPEECHHEADER;
//
// DVPROTOCOLMSG_SPEECHWITHTARGET
//
// This message is used for transporting speech. The message consists
// of this header followed by a single DVID for each target the packet
// is targetted at. After the target list the audio data will be the
// remaining part of the packet.
//
// ----
// Sesssion Types: Mixing / Forwarding
// Message Flow : Voice Clients --> Voice Host / Voice Mixing Server
//
typedef UNALIGNED struct _DVPROTOCOLMSG_SPEECHWITHTARGET
{
DVPROTOCOLMSG_SPEECHHEADER dvHeader;
// dwType = DVMSGID_SPEECHWITHTARGET
DWORD dwNumTargets; // # of targets following this header
} DVPROTOCOLMSG_SPEECHWITHTARGET, *PDVPROTOCOLMSG_SPEECHWITHTARGET;
//
// DVPROTOCOLMSG_SPEECHWITHFROM
//
// This message is used by forwarding servers when a speech packet is
// bounced. The packet contains this header followed by the audio
// data. The audio data will be the remaining part of the packet.
//
// ---
// Session Types: Forwarding
// Message Flow : Forwarding Server --> Voice Clients
//
typedef UNALIGNED struct _DVPROTOCOLMSG_SPEECHWITHFROM
{
DVPROTOCOLMSG_SPEECHHEADER dvHeader;
// dwType = DVMSGID_SPEECHWITHFROM
DVID dvidFrom; // DVID of the client that this packet originated.
} DVPROTOCOLMSG_SPEECHWITHFROM, *PDVPROTOCOLMSG_SPEECHWITHFROM;
/////////////////////////////////////////////////////////////////////////////////////
//
// IN-SESSION MESSAGES - TARGET MANAGEMENT
//
/////////////////////////////////////////////////////////////////////////////////////
//
// DVPROTOCOLMSG_SETTARGET
//
// Tells client to switch it's target to the specified value. Used when
// the server calls SetTransmitTarget for a particular player. This message
// contains this header followed by dwNumTargets DWORDs containing the
// players / groups that the client is targetting.
//
// ---
// Session Types: Sessions with Server Controlled Targetting Enabled
// Message Flow : Voice Host --> Voice Clients
//
typedef UNALIGNED struct _DVPROTOCOLMSG_SETTARGET
{
BYTE dwType; // = DVMSGID_SETTARGETS
DWORD dwNumTargets; // # of targets (Can be 0 for no targets).
} DVPROTOCOLMSG_SETTARGET, *PDVPROTOCOLMSG_SETTARGET;
/////////////////////////////////////////////////////////////////////////////////////
//
// IN-SESSION MESSAGES - NAMETABLE MANAGEMENT
//
/////////////////////////////////////////////////////////////////////////////////////
//
// DVPROTOCOLMSG_PLAYERJOIN
//
// This message is used to inform clients when a new client has connected
// to the session.
//
// ---
// Session Types: Peer to Peer
// Message Flow : Voice Host --> Voice Clients
//
typedef UNALIGNED struct _DVPROTOCOLMSG_PLAYERJOIN
{
BYTE dwType; // = DVMSGID_CREATEVOICEPLAYER
DVID dvidID; // ID of the player
DWORD dwFlags; // Player's player flags (DVPLAYERCAPS_XXXXX)
DWORD dwHostOrderID; // Host Order ID
} DVPROTOCOLMSG_PLAYERJOIN, *PDVPROTOCOLMSG_PLAYERJOIN;
//
// DVPROTOCOLMSG_PLAYERQUIT
//
// This message is used to inform clients when a client has left the voice
// session.
//
// ---
// Session Types: Peer to Peer
// Message Flow : Voice Host --> Voice Clients
//
typedef UNALIGNED struct _DVPROTOCOLMSG_PLAYERQUIT
{
BYTE dwType; // = DVMSGID_DELETEVOICEPLAYER
DVID dvidID; // ID of the player
} DVPROTOCOLMSG_PLAYERQUIT, *PDVPROTOCOLMSG_PLAYERQUIT;
//
// DVPROTOCOLMSG_GENERIC
//
// Used to determine the type of a DirectPlayVoice message. Used in message
// cracking.
//
typedef UNALIGNED struct _DVPROTOCOLMSG_GENERIC
{
BYTE dwType;
} DVPROTOCOLMSG_GENERIC, *PDVPROTOCOLMSG_GENERIC;
/////////////////////////////////////////////////////////////////////////////////////
//
// IN-SESSION MESSAGES - HOST MIGRATION MESSAGES
//
/////////////////////////////////////////////////////////////////////////////////////
//
// DVPROTOCOLMSG_HOSTMIGRATED
//
// This message is sent by the new host when a host migration has taken place.
// The message is sent by the new host once they have finished initialization.
// All clients should respond to this message with a DVPROTOCOLMSG_SETTINGSCONFIRM.
//
// ---
// Session Types: Peer to Peer (With host migration enabled).
// Message Flow : Voice Host (New) --> Voice Clients
//
typedef UNALIGNED struct _DVPROTOCOLMSG_HOSTMIGRATED
{
BYTE dwType; // = DVMSGID_HOSTMIGRATED
} DVPROTOCOLMSG_HOSTMIGRATED, *PDVPROTOCOLMSG_HOSTMIGRATED;
//
// DVPROTOCOLMSG_HOSTMIGRATELEAVE
//
// This message is sent by a voice host if they are shutting down their interface
// and host migration is enabled. It informs clients that they have to run their
// election algorithm.
//
// ---
// Session Types: Peer To Peer (With Host Migration Enabled)
// Message Flow : Voice Host (Old) --> Voice Clients
//
typedef UNALIGNED struct _DVPROTOCOLMSG_HOSTMIGRATELEAVE
{
BYTE dwType; // = DVMSGID_HOSTMIGRATELEAVE
} DVPROTOCOLMSG_HOSTMIGRATELEAVE, *PDVPROTOCOLMSG_HOSTMIGRATELEAVE;
/////////////////////////////////////////////////////////////////////////////////////
//
// IN-SESSION MESSAGES - SESSION TERMINATION
//
/////////////////////////////////////////////////////////////////////////////////////
//
// DVPROTOCOLMSG_SESSIONLOST
//
// This message is sent by the voice host when they are shutting down and
// host migration is not enabled or available.
//
// This message can also be sent if a host migration takes place and a
// client encounters a fatal error when starting the new host.
//
// ---
// Session Type: ALL
// Message Flow: Voice Host (New) --> Voice Clients
// Voice Host --> Voice Clients
//
typedef UNALIGNED struct _DVPROTOCOLMSG_SESSIONLOST
{
BYTE dwType; // = DVMSGID_SESSIONLOST
HRESULT hresReason; // DVERR_XXXXXX or DV_OK
} DVPROTOCOLMSG_SESSIONLOST, *PDVPROTOCOLMSG_SESSIONLOST;
//
// DVPROTOCOLMSG_DISCONNECT
//
// This message is sent by voice clients when they wish to disconnect
// gracefully. The host responds with the same message to confirm
// it received the request. Once the client receives the response
// then it is free to disconnect.
//
// ---
// Session Type: ALL
// Message Flow: Voice Host --> Voice Client (dwType = DVPROTOCOLMSG_DISCONNECTCONFIRM)
// Voice Client --> Voice Host (dwType = DVPROTOCOLMSG_DISCONNECT)
//
typedef UNALIGNED struct _DVPROTOCOLMSG_DISCONNECT
{
BYTE dwType; // = DVPROTOCOLMSG_DISCONNECTCONFIRM OR
// DVPROTOCOLMSG_DISCONNECT
HRESULT hresDisconnect; // HRESULT that caused the disconnect
// DV_OK or DVERR_XXXXXX
} DVPROTOCOLMSG_DISCONNECT, *PDVPROTOCOLMSG_DISCONNECT;
typedef union _DVPROTOCOLMSG_FULLMESSAGE
{
DVPROTOCOLMSG_GENERIC dvGeneric;
DVPROTOCOLMSG_SESSIONLOST dvSessionLost;
DVPROTOCOLMSG_PLAYERJOIN dvPlayerJoin;
DVPROTOCOLMSG_PLAYERQUIT dvPlayerQuit;
DVPROTOCOLMSG_CONNECTACCEPT dvConnectAccept;
DVPROTOCOLMSG_CONNECTREFUSE dvConnectRefuse;
DVPROTOCOLMSG_CONNECTREQUEST dvConnectRequest;
DVPROTOCOLMSG_SPEECHHEADER dvSpeech;
DVPROTOCOLMSG_DISCONNECT dvDisconnect;
DVPROTOCOLMSG_SETTARGET dvSetTarget;
DVPROTOCOLMSG_SETTINGSCONFIRM dvSettingsConfirm;
DVPROTOCOLMSG_PLAYERLIST dvPlayerList;
DVPROTOCOLMSG_HOSTMIGRATED dvHostMigrated;
DVPROTOCOLMSG_HOSTMIGRATELEAVE dvHostMigrateLeave;
DVPROTOCOLMSG_SPEECHWITHTARGET dvSpeechWithTarget;
DVPROTOCOLMSG_SPEECHWITHFROM dvSpeechWithFrom;
} DVPROTOCOLMSG_FULLMESSAGE, *PDVPROTOCOLMSG_FULLMESSAGE;
#pragma pack(pop)
#endif