mirror of
https://github.com/solemnwarning/directplay-lite
synced 2024-12-30 16:45:37 +01:00
Copy values for DPN_APPLICATION_DESC between peers.
This commit is contained in:
parent
d4d0c2f64a
commit
f5c660f22a
@ -819,21 +819,31 @@ HRESULT DirectPlay8Peer::Host(CONST DPN_APPLICATION_DESC* CONST pdnAppDesc, IDir
|
|||||||
|
|
||||||
HRESULT DirectPlay8Peer::GetApplicationDesc(DPN_APPLICATION_DESC* CONST pAppDescBuffer, DWORD* CONST pcbDataSize, CONST DWORD dwFlags)
|
HRESULT DirectPlay8Peer::GetApplicationDesc(DPN_APPLICATION_DESC* CONST pAppDescBuffer, DWORD* CONST pcbDataSize, CONST DWORD dwFlags)
|
||||||
{
|
{
|
||||||
if(state != STATE_HOSTING && state != STATE_CONNECTED)
|
std::unique_lock<std::mutex> l(lock);
|
||||||
|
|
||||||
|
switch(state)
|
||||||
{
|
{
|
||||||
return DPNERR_NOCONNECTION;
|
case STATE_NEW: return DPNERR_UNINITIALIZED;
|
||||||
|
case STATE_HOSTING: break;
|
||||||
|
case STATE_CONNECTED: break;
|
||||||
|
case STATE_CONNECTING: return DPNERR_CONNECTING;
|
||||||
|
default: return DPNERR_NOCONNECTION;
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD required_size = sizeof(DPN_APPLICATION_DESC)
|
DWORD required_size = sizeof(DPN_APPLICATION_DESC)
|
||||||
+ (password.length() + !password.empty()) * sizeof(wchar_t)
|
+ (password.length() + !password.empty()) * sizeof(wchar_t)
|
||||||
+ application_data.size();
|
+ application_data.size();
|
||||||
|
|
||||||
if(pAppDescBuffer != NULL && *pcbDataSize >= required_size)
|
if(*pcbDataSize >= sizeof(DPN_APPLICATION_DESC) && pAppDescBuffer->dwSize != sizeof(DPN_APPLICATION_DESC))
|
||||||
{
|
{
|
||||||
unsigned char *extra_at = (unsigned char*)(pAppDescBuffer);
|
return DPNERR_INVALIDPARAM;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(*pcbDataSize >= required_size)
|
||||||
|
{
|
||||||
|
unsigned char *extra_at = (unsigned char*)(pAppDescBuffer + 1);
|
||||||
|
|
||||||
pAppDescBuffer->dwSize = sizeof(*pAppDescBuffer);
|
pAppDescBuffer->dwFlags = 0;
|
||||||
pAppDescBuffer->dwFlags = 0;
|
|
||||||
pAppDescBuffer->guidInstance = instance_guid;
|
pAppDescBuffer->guidInstance = instance_guid;
|
||||||
pAppDescBuffer->guidApplication = application_guid;
|
pAppDescBuffer->guidApplication = application_guid;
|
||||||
pAppDescBuffer->dwMaxPlayers = max_players;
|
pAppDescBuffer->dwMaxPlayers = max_players;
|
||||||
@ -879,41 +889,64 @@ HRESULT DirectPlay8Peer::GetApplicationDesc(DPN_APPLICATION_DESC* CONST pAppDesc
|
|||||||
|
|
||||||
HRESULT DirectPlay8Peer::SetApplicationDesc(CONST DPN_APPLICATION_DESC* CONST pad, CONST DWORD dwFlags)
|
HRESULT DirectPlay8Peer::SetApplicationDesc(CONST DPN_APPLICATION_DESC* CONST pad, CONST DWORD dwFlags)
|
||||||
{
|
{
|
||||||
if(state == STATE_HOSTING)
|
std::unique_lock<std::mutex> l(lock);
|
||||||
|
|
||||||
|
switch(state)
|
||||||
{
|
{
|
||||||
if(pad->dwMaxPlayers > 0 && pad->dwMaxPlayers <= player_to_peer_id.size())
|
case STATE_NEW: return DPNERR_UNINITIALIZED;
|
||||||
{
|
case STATE_HOSTING: break;
|
||||||
/* Can't set dwMaxPlayers below current player count. */
|
default: return DPNERR_NOTHOST;
|
||||||
return DPNERR_INVALIDPARAM;
|
}
|
||||||
}
|
|
||||||
|
if(pad->dwMaxPlayers > 0 && pad->dwMaxPlayers <= player_to_peer_id.size())
|
||||||
max_players = pad->dwMaxPlayers;
|
{
|
||||||
session_name = pad->pwszSessionName;
|
/* Can't set dwMaxPlayers below current player count. */
|
||||||
|
return DPNERR_INVALIDPARAM;
|
||||||
if(pad->dwFlags & DPNSESSION_REQUIREPASSWORD)
|
}
|
||||||
{
|
|
||||||
password = pad->pwszPassword;
|
max_players = pad->dwMaxPlayers;
|
||||||
}
|
session_name = pad->pwszSessionName;
|
||||||
else{
|
|
||||||
password.clear();
|
if(pad->dwFlags & DPNSESSION_REQUIREPASSWORD)
|
||||||
}
|
{
|
||||||
|
password = pad->pwszPassword;
|
||||||
application_data.clear();
|
|
||||||
|
|
||||||
if(pad->pvApplicationReservedData != NULL && pad->dwApplicationReservedDataSize > 0)
|
|
||||||
{
|
|
||||||
application_data.insert(application_data.begin(),
|
|
||||||
(unsigned char*)(pad->pvApplicationReservedData),
|
|
||||||
(unsigned char*)(pad->pvApplicationReservedData) + pad->dwApplicationReservedDataSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* TODO: Notify peers */
|
|
||||||
|
|
||||||
return S_OK;
|
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
return DPNERR_NOTHOST;
|
password.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
application_data.clear();
|
||||||
|
|
||||||
|
if(pad->pvApplicationReservedData != NULL && pad->dwApplicationReservedDataSize > 0)
|
||||||
|
{
|
||||||
|
application_data.insert(application_data.begin(),
|
||||||
|
(unsigned char*)(pad->pvApplicationReservedData),
|
||||||
|
(unsigned char*)(pad->pvApplicationReservedData) + pad->dwApplicationReservedDataSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Notify all peers of the new application description. We don't wait for confirmation
|
||||||
|
* from the other peers, they'll get it when they get it.
|
||||||
|
*/
|
||||||
|
|
||||||
|
PacketSerialiser appdesc(DPLITE_MSGID_APPDESC);
|
||||||
|
|
||||||
|
appdesc.append_dword(max_players);
|
||||||
|
appdesc.append_wstring(session_name);
|
||||||
|
appdesc.append_wstring(password);
|
||||||
|
appdesc.append_data(application_data.data(), application_data.size());
|
||||||
|
|
||||||
|
for(auto pi = peers.begin(); pi != peers.end(); ++pi)
|
||||||
|
{
|
||||||
|
if(pi->second->state != Peer::PS_CONNECTED)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
pi->second->sq.send(SendQueue::SEND_PRI_MEDIUM, appdesc, NULL,
|
||||||
|
[](std::unique_lock<std::mutex> &l, HRESULT result) {});
|
||||||
|
}
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT DirectPlay8Peer::CreateGroup(CONST DPN_GROUP_INFO* CONST pdpnGroupInfo, void* CONST pvGroupContext, void* CONST pvAsyncContext, DPNHANDLE* CONST phAsyncHandle, CONST DWORD dwFlags)
|
HRESULT DirectPlay8Peer::CreateGroup(CONST DPN_GROUP_INFO* CONST pdpnGroupInfo, void* CONST pvGroupContext, void* CONST pvAsyncContext, DPNHANDLE* CONST phAsyncHandle, CONST DWORD dwFlags)
|
||||||
@ -1966,6 +1999,12 @@ void DirectPlay8Peer::io_peer_recv(std::unique_lock<std::mutex> &l, unsigned int
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case DPLITE_MSGID_APPDESC:
|
||||||
|
{
|
||||||
|
handle_appdesc(l, peer_id, *pd);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
/* TODO: Log "unrecognised packet type" */
|
/* TODO: Log "unrecognised packet type" */
|
||||||
break;
|
break;
|
||||||
@ -2423,6 +2462,11 @@ void DirectPlay8Peer::handle_host_connect_request(std::unique_lock<std::mutex> &
|
|||||||
connect_host_ok.append_wstring(local_player_name);
|
connect_host_ok.append_wstring(local_player_name);
|
||||||
connect_host_ok.append_data(local_player_data.data(), local_player_data.size());
|
connect_host_ok.append_data(local_player_data.data(), local_player_data.size());
|
||||||
|
|
||||||
|
connect_host_ok.append_dword(max_players);
|
||||||
|
connect_host_ok.append_wstring(session_name);
|
||||||
|
connect_host_ok.append_wstring(password);
|
||||||
|
connect_host_ok.append_data(application_data.data(), application_data.size());
|
||||||
|
|
||||||
peer->sq.send(SendQueue::SEND_PRI_MEDIUM,
|
peer->sq.send(SendQueue::SEND_PRI_MEDIUM,
|
||||||
connect_host_ok,
|
connect_host_ok,
|
||||||
NULL,
|
NULL,
|
||||||
@ -2526,6 +2570,17 @@ void DirectPlay8Peer::handle_host_connect_ok(std::unique_lock<std::mutex> &l, un
|
|||||||
(const unsigned char*)(player_data.first),
|
(const unsigned char*)(player_data.first),
|
||||||
(const unsigned char*)(player_data.first) + player_data.second);
|
(const unsigned char*)(player_data.first) + player_data.second);
|
||||||
|
|
||||||
|
max_players = pd.get_dword(after_peers_base + 3);
|
||||||
|
session_name = pd.get_wstring(after_peers_base + 4);
|
||||||
|
password = pd.get_wstring(after_peers_base + 5);
|
||||||
|
|
||||||
|
std::pair<const void*, size_t> application_data = pd.get_data(after_peers_base + 6);
|
||||||
|
|
||||||
|
this->application_data.clear();
|
||||||
|
this->application_data.insert(this->application_data.end(),
|
||||||
|
(const unsigned char*)(application_data.first),
|
||||||
|
(const unsigned char*)(application_data.first) + application_data.second);
|
||||||
|
|
||||||
peer->state = Peer::PS_CONNECTED;
|
peer->state = Peer::PS_CONNECTED;
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -2726,6 +2781,53 @@ void DirectPlay8Peer::handle_ack(std::unique_lock<std::mutex> &l, unsigned int p
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DirectPlay8Peer::handle_appdesc(std::unique_lock<std::mutex> &l, unsigned int peer_id, const PacketDeserialiser &pd)
|
||||||
|
{
|
||||||
|
Peer *peer = get_peer_by_peer_id(peer_id);
|
||||||
|
assert(peer != NULL);
|
||||||
|
|
||||||
|
try {
|
||||||
|
DWORD max_players = pd.get_dword(0);
|
||||||
|
std::wstring session_name = pd.get_wstring(1);
|
||||||
|
std::wstring password = pd.get_wstring(2);
|
||||||
|
std::pair<const void*, size_t> application_data = pd.get_data(3);
|
||||||
|
|
||||||
|
if(peer->state != Peer::PS_CONNECTED)
|
||||||
|
{
|
||||||
|
/* TODO: LOG ME */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(peer->player_id != host_player_id)
|
||||||
|
{
|
||||||
|
/* TODO: LOG ME */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->max_players = max_players;
|
||||||
|
this->session_name = session_name;
|
||||||
|
this->password = password;
|
||||||
|
|
||||||
|
this->application_data.clear();
|
||||||
|
this->application_data.insert(this->application_data.end(),
|
||||||
|
(const unsigned char*)(application_data.first),
|
||||||
|
(const unsigned char*)(application_data.first) + application_data.second);
|
||||||
|
|
||||||
|
/* DPN_MSGID_APPLICATION_DESC has no accompanying structure.
|
||||||
|
* The application must call GetApplicationDesc() to obtain the
|
||||||
|
* new data.
|
||||||
|
*/
|
||||||
|
|
||||||
|
l.unlock();
|
||||||
|
message_handler(message_handler_ctx, DPN_MSGID_APPLICATION_DESC, NULL);
|
||||||
|
l.lock();
|
||||||
|
}
|
||||||
|
catch(const PacketDeserialiser::Error &e)
|
||||||
|
{
|
||||||
|
/* TODO: LOG ME */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Check if we have finished connecting and should enter STATE_CONNECTED.
|
/* Check if we have finished connecting and should enter STATE_CONNECTED.
|
||||||
*
|
*
|
||||||
* This is called after processing either of:
|
* This is called after processing either of:
|
||||||
|
@ -192,6 +192,7 @@ class DirectPlay8Peer: public IDirectPlay8Peer
|
|||||||
void handle_message(std::unique_lock<std::mutex> &l, const PacketDeserialiser &pd);
|
void handle_message(std::unique_lock<std::mutex> &l, const PacketDeserialiser &pd);
|
||||||
void handle_playerinfo(std::unique_lock<std::mutex> &l, unsigned int peer_id, const PacketDeserialiser &pd);
|
void handle_playerinfo(std::unique_lock<std::mutex> &l, unsigned int peer_id, const PacketDeserialiser &pd);
|
||||||
void handle_ack(std::unique_lock<std::mutex> &l, unsigned int peer_id, const PacketDeserialiser &pd);
|
void handle_ack(std::unique_lock<std::mutex> &l, unsigned int peer_id, const PacketDeserialiser &pd);
|
||||||
|
void handle_appdesc(std::unique_lock<std::mutex> &l, unsigned int peer_id, const PacketDeserialiser &pd);
|
||||||
|
|
||||||
void connect_check(std::unique_lock<std::mutex> &l);
|
void connect_check(std::unique_lock<std::mutex> &l);
|
||||||
void connect_fail(std::unique_lock<std::mutex> &l, HRESULT hResultCode, const void *pvApplicationReplyData, DWORD dwApplicationReplyDataSize);
|
void connect_fail(std::unique_lock<std::mutex> &l, HRESULT hResultCode, const void *pvApplicationReplyData, DWORD dwApplicationReplyDataSize);
|
||||||
|
@ -55,6 +55,10 @@
|
|||||||
* DATA | NULL - Response data
|
* DATA | NULL - Response data
|
||||||
* WSTRING - Host player name (empty = none)
|
* WSTRING - Host player name (empty = none)
|
||||||
* DATA - Host player data (empty = none)
|
* DATA - Host player data (empty = none)
|
||||||
|
* DWORD - DPN_APPLICATION_DESC.dwMaxPlayers
|
||||||
|
* WSTRING - DPN_APPLICATION_DESC.pwszSessionName
|
||||||
|
* WSTRING - DPN_APPLICATION_DESC.pwszPassword
|
||||||
|
* DATA - DPN_APPLICATION_DESC.pvApplicationReservedData
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define DPLITE_MSGID_CONNECT_HOST_FAIL 5
|
#define DPLITE_MSGID_CONNECT_HOST_FAIL 5
|
||||||
@ -93,4 +97,14 @@
|
|||||||
* DWORD - Result code (normally S_OK)
|
* DWORD - Result code (normally S_OK)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define DPLITE_MSGID_APPDESC 9
|
||||||
|
|
||||||
|
/* The host has modified the session's application description using SetApplicationDesc()
|
||||||
|
*
|
||||||
|
* DWORD - DPN_APPLICATION_DESC.dwMaxPlayers
|
||||||
|
* WSTRING - DPN_APPLICATION_DESC.pwszSessionName
|
||||||
|
* WSTRING - DPN_APPLICATION_DESC.pwszPassword
|
||||||
|
* DATA - DPN_APPLICATION_DESC.pvApplicationReservedData
|
||||||
|
*/
|
||||||
|
|
||||||
#endif /* !DPLITE_MESSAGES_HPP */
|
#endif /* !DPLITE_MESSAGES_HPP */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user