mirror of
https://github.com/solemnwarning/directplay-lite
synced 2024-12-30 16:45:37 +01:00
Handle IDirectPlay8Peer::Close() being called by the host.
This commit is contained in:
parent
e7f5d0f68d
commit
1b16624577
@ -1372,16 +1372,18 @@ HRESULT DirectPlay8Peer::Close(CONST DWORD dwFlags)
|
||||
std::unique_lock<std::mutex> l(lock);
|
||||
|
||||
bool was_connected = false;
|
||||
bool was_hosting = false;
|
||||
|
||||
switch(state)
|
||||
{
|
||||
case STATE_NEW: return DPNERR_UNINITIALIZED;
|
||||
case STATE_INITIALISED: break;
|
||||
case STATE_HOSTING: was_connected = true; break;
|
||||
case STATE_HOSTING: was_hosting = true; break;
|
||||
case STATE_CONNECTING: break;
|
||||
case STATE_CONNECT_FAILED: break;
|
||||
case STATE_CONNECTED: was_connected = true; break;
|
||||
case STATE_CLOSING: return DPNERR_ALREADYCLOSING;
|
||||
case STATE_TERMINATED: break;
|
||||
}
|
||||
|
||||
/* Signal all EnumHosts() calls to complete. */
|
||||
@ -1410,6 +1412,29 @@ HRESULT DirectPlay8Peer::Close(CONST DWORD dwFlags)
|
||||
|
||||
state = STATE_CLOSING;
|
||||
|
||||
/* When Close() is called as a host, the DPNMSG_DESTROY_PLAYER for the local player comes
|
||||
* before the ones for the peers, when called as a non-host, it comes after.
|
||||
*
|
||||
* Do not question the ways of DirectX.
|
||||
*/
|
||||
|
||||
if(was_hosting)
|
||||
{
|
||||
/* Raise a DPNMSG_DESTROY_PLAYER for ourself. */
|
||||
|
||||
DPNMSG_DESTROY_PLAYER dp;
|
||||
memset(&dp, 0, sizeof(dp));
|
||||
|
||||
dp.dwSize = sizeof(DPNMSG_DESTROY_PLAYER);
|
||||
dp.dpnidPlayer = local_player_id;
|
||||
dp.pvPlayerContext = local_player_ctx;
|
||||
dp.dwReason = DPNDESTROYPLAYERREASON_NORMAL;
|
||||
|
||||
l.unlock();
|
||||
message_handler(message_handler_ctx, DPN_MSGID_DESTROY_PLAYER, &dp);
|
||||
l.lock();
|
||||
}
|
||||
|
||||
if(dwFlags & DPNCLOSE_IMMEDIATE)
|
||||
{
|
||||
while(!peers.empty())
|
||||
@ -2500,6 +2525,8 @@ void DirectPlay8Peer::peer_destroy(std::unique_lock<std::mutex> &l, unsigned int
|
||||
|
||||
if(peer->state == Peer::PS_CONNECTED)
|
||||
{
|
||||
DPNID killed_player_id = peer->player_id;
|
||||
|
||||
DPNMSG_DESTROY_PLAYER dp;
|
||||
memset(&dp, 0, sizeof(dp));
|
||||
|
||||
@ -2519,9 +2546,52 @@ void DirectPlay8Peer::peer_destroy(std::unique_lock<std::mutex> &l, unsigned int
|
||||
message_handler(message_handler_ctx, DPN_MSGID_DESTROY_PLAYER, &dp);
|
||||
l.lock();
|
||||
|
||||
RENEW_PEER_OR_RETURN();
|
||||
player_to_peer_id.erase(killed_player_id);
|
||||
|
||||
player_to_peer_id.erase(peer->player_id);
|
||||
if(state == STATE_CONNECTED && killed_player_id == host_player_id)
|
||||
{
|
||||
/* The connection to the host has been lost. We need to raise a
|
||||
* DPNMSG_TERMINATE_SESSION and dump all the other peers. We don't return
|
||||
* to STATE_INITIALISED because the application is still expected to call
|
||||
* IDirectPlay8Peer::Close() after receiving DPNMSG_TERMINATE_SESSION.
|
||||
*
|
||||
* TODO: Implement host migration here.
|
||||
*/
|
||||
|
||||
DPNMSG_TERMINATE_SESSION ts;
|
||||
memset(&ts, 0, sizeof(ts));
|
||||
|
||||
ts.dwSize = sizeof(DPNMSG_TERMINATE_SESSION);
|
||||
ts.hResultCode = outstanding_op_result;
|
||||
ts.pvTerminateData = (void*)(NULL);
|
||||
ts.dwTerminateDataSize = 0;
|
||||
|
||||
state = STATE_TERMINATED;
|
||||
|
||||
l.unlock();
|
||||
message_handler(message_handler_ctx, DPN_MSGID_TERMINATE_SESSION, &ts);
|
||||
l.lock();
|
||||
|
||||
DPNMSG_DESTROY_PLAYER dp;
|
||||
memset(&dp, 0, sizeof(dp));
|
||||
|
||||
dp.dwSize = sizeof(DPNMSG_DESTROY_PLAYER);
|
||||
dp.dpnidPlayer = local_player_id;
|
||||
dp.pvPlayerContext = local_player_ctx;
|
||||
dp.dwReason = DPNDESTROYPLAYERREASON_NORMAL;
|
||||
|
||||
l.unlock();
|
||||
message_handler(message_handler_ctx, DPN_MSGID_DESTROY_PLAYER, &dp);
|
||||
l.lock();
|
||||
|
||||
while(!peers.empty())
|
||||
{
|
||||
auto peer_id = peers.begin()->first;
|
||||
peer_destroy(l, peer_id, outstanding_op_result, destroy_player_reason);
|
||||
}
|
||||
}
|
||||
|
||||
RENEW_PEER_OR_RETURN();
|
||||
}
|
||||
else if(state == STATE_CONNECTING && (peer->state == Peer::PS_CONNECTING_HOST || peer->state == Peer::PS_REQUESTING_HOST))
|
||||
{
|
||||
|
@ -35,6 +35,7 @@ class DirectPlay8Peer: public IDirectPlay8Peer
|
||||
STATE_CONNECT_FAILED,
|
||||
STATE_CONNECTED,
|
||||
STATE_CLOSING,
|
||||
STATE_TERMINATED,
|
||||
} state;
|
||||
|
||||
AsyncHandleAllocator handle_alloc;
|
||||
|
@ -337,10 +337,14 @@ class TestPeer
|
||||
expecting = true;
|
||||
}
|
||||
|
||||
void expect_push(const std::function<HRESULT(DWORD,PVOID)> &callback)
|
||||
void expect_push(const std::function<HRESULT(DWORD,PVOID)> &callback, int count = 1)
|
||||
{
|
||||
std::unique_lock<std::mutex> l(lock);
|
||||
callbacks.push_back(callback);
|
||||
|
||||
for(int i = 0; i < count; ++i)
|
||||
{
|
||||
callbacks.push_back(callback);
|
||||
}
|
||||
}
|
||||
|
||||
void expect_end()
|
||||
@ -348,7 +352,10 @@ class TestPeer
|
||||
std::unique_lock<std::mutex> l(lock);
|
||||
expecting = false;
|
||||
|
||||
EXPECT_TRUE(callbacks.empty());
|
||||
if(!callbacks.empty())
|
||||
{
|
||||
ADD_FAILURE() << "[" << ident << "] " << callbacks.size() << " missed messages";
|
||||
}
|
||||
|
||||
callbacks.clear();
|
||||
}
|
||||
@ -2437,6 +2444,492 @@ TEST(DirectPlay8Peer, ConnectTwoPeersToHost)
|
||||
EXPECT_EQ(p2_cp2_dpnidPlayer, p1_player_id);
|
||||
}
|
||||
|
||||
TEST(DirectPlay8Peer, HostPeerSoftClose)
|
||||
{
|
||||
DPN_APPLICATION_DESC app_desc;
|
||||
memset(&app_desc, 0, sizeof(app_desc));
|
||||
|
||||
app_desc.dwSize = sizeof(app_desc);
|
||||
app_desc.guidApplication = APP_GUID_1;
|
||||
app_desc.pwszSessionName = L"Session 1";
|
||||
|
||||
IDP8AddressInstance host_addr(CLSID_DP8SP_TCPIP, PORT);
|
||||
|
||||
TestPeer host("host");
|
||||
ASSERT_EQ(host->Host(&app_desc, &(host_addr.instance), 1, NULL, NULL, 0, 0), S_OK);
|
||||
|
||||
IDP8AddressInstance connect_addr(CLSID_DP8SP_TCPIP, L"127.0.0.1", PORT);
|
||||
|
||||
TestPeer peer1("peer1");
|
||||
ASSERT_EQ(peer1->Connect(
|
||||
&app_desc, /* pdnAppDesc */
|
||||
connect_addr, /* pHostAddr */
|
||||
NULL, /* pDeviceInfo */
|
||||
NULL, /* pdnSecurity */
|
||||
NULL, /* pdnCredentials */
|
||||
NULL, /* pvUserConnectData */
|
||||
0, /* dwUserConnectDataSize */
|
||||
0, /* pvPlayerContext */
|
||||
NULL, /* pvAsyncContext */
|
||||
NULL, /* phAsyncHandle */
|
||||
DPNCONNECT_SYNC /* dwFlags */
|
||||
), S_OK);
|
||||
|
||||
TestPeer peer2("peer2");
|
||||
ASSERT_EQ(peer2->Connect(
|
||||
&app_desc, /* pdnAppDesc */
|
||||
connect_addr, /* pHostAddr */
|
||||
NULL, /* pDeviceInfo */
|
||||
NULL, /* pdnSecurity */
|
||||
NULL, /* pdnCredentials */
|
||||
NULL, /* pvUserConnectData */
|
||||
0, /* dwUserConnectDataSize */
|
||||
0, /* pvPlayerContext */
|
||||
NULL, /* pvAsyncContext */
|
||||
NULL, /* phAsyncHandle */
|
||||
DPNCONNECT_SYNC /* dwFlags */
|
||||
), S_OK);
|
||||
|
||||
Sleep(100);
|
||||
|
||||
DPNID host_dp1_dpnidPlayer;
|
||||
DPNID host_dp2_dpnidPlayer;
|
||||
|
||||
host.expect_begin();
|
||||
host.expect_push([&host, &peer1, &peer2](DWORD dwMessageType, PVOID pMessage)
|
||||
{
|
||||
EXPECT_EQ(dwMessageType, DPN_MSGID_DESTROY_PLAYER);
|
||||
|
||||
if(dwMessageType == DPN_MSGID_DESTROY_PLAYER)
|
||||
{
|
||||
DPNMSG_DESTROY_PLAYER *dp = (DPNMSG_DESTROY_PLAYER*)(pMessage);
|
||||
|
||||
EXPECT_EQ(dp->dwSize, sizeof(DPNMSG_DESTROY_PLAYER));
|
||||
|
||||
EXPECT_TRUE((dp->dpnidPlayer == host.first_cp_dpnidPlayer))
|
||||
<< "(dpnidPlayer = " << dp->dpnidPlayer
|
||||
<< ", host = " << host.first_cp_dpnidPlayer
|
||||
<< ", peer1 = " << peer1.first_cc_dpnidLocal
|
||||
<< ", peer2 = " << peer2.first_cc_dpnidLocal << ")";
|
||||
|
||||
EXPECT_EQ(dp->pvPlayerContext, (void*)~(uintptr_t)(dp->dpnidPlayer));
|
||||
EXPECT_EQ(dp->dwReason, DPNDESTROYPLAYERREASON_NORMAL);
|
||||
}
|
||||
|
||||
return DPN_OK;
|
||||
});
|
||||
host.expect_push([&host, &peer1, &peer2, &host_dp1_dpnidPlayer](DWORD dwMessageType, PVOID pMessage)
|
||||
{
|
||||
EXPECT_EQ(dwMessageType, DPN_MSGID_DESTROY_PLAYER);
|
||||
|
||||
if(dwMessageType == DPN_MSGID_DESTROY_PLAYER)
|
||||
{
|
||||
DPNMSG_DESTROY_PLAYER *dp = (DPNMSG_DESTROY_PLAYER*)(pMessage);
|
||||
|
||||
EXPECT_EQ(dp->dwSize, sizeof(DPNMSG_DESTROY_PLAYER));
|
||||
|
||||
EXPECT_TRUE((dp->dpnidPlayer == peer1.first_cc_dpnidLocal || dp->dpnidPlayer == peer2.first_cc_dpnidLocal))
|
||||
<< "(dpnidPlayer = " << dp->dpnidPlayer
|
||||
<< ", host = " << host.first_cp_dpnidPlayer
|
||||
<< ", peer1 = " << peer1.first_cc_dpnidLocal
|
||||
<< ", peer2 = " << peer2.first_cc_dpnidLocal << ")";
|
||||
|
||||
EXPECT_EQ(dp->pvPlayerContext, (void*)~(uintptr_t)(dp->dpnidPlayer));
|
||||
EXPECT_EQ(dp->dwReason, DPNDESTROYPLAYERREASON_NORMAL);
|
||||
|
||||
host_dp1_dpnidPlayer = dp->dpnidPlayer;
|
||||
}
|
||||
|
||||
return DPN_OK;
|
||||
});
|
||||
host.expect_push([&host, &peer1, &peer2, &host_dp2_dpnidPlayer](DWORD dwMessageType, PVOID pMessage)
|
||||
{
|
||||
EXPECT_EQ(dwMessageType, DPN_MSGID_DESTROY_PLAYER);
|
||||
|
||||
if(dwMessageType == DPN_MSGID_DESTROY_PLAYER)
|
||||
{
|
||||
DPNMSG_DESTROY_PLAYER *dp = (DPNMSG_DESTROY_PLAYER*)(pMessage);
|
||||
|
||||
EXPECT_EQ(dp->dwSize, sizeof(DPNMSG_DESTROY_PLAYER));
|
||||
|
||||
EXPECT_TRUE((dp->dpnidPlayer == peer1.first_cc_dpnidLocal || dp->dpnidPlayer == peer2.first_cc_dpnidLocal))
|
||||
<< "(dpnidPlayer = " << dp->dpnidPlayer
|
||||
<< ", host = " << host.first_cp_dpnidPlayer
|
||||
<< ", peer1 = " << peer1.first_cc_dpnidLocal
|
||||
<< ", peer2 = " << peer2.first_cc_dpnidLocal << ")";
|
||||
|
||||
EXPECT_EQ(dp->pvPlayerContext, (void*)~(uintptr_t)(dp->dpnidPlayer));
|
||||
EXPECT_EQ(dp->dwReason, DPNDESTROYPLAYERREASON_NORMAL);
|
||||
|
||||
host_dp2_dpnidPlayer = dp->dpnidPlayer;
|
||||
}
|
||||
|
||||
return DPN_OK;
|
||||
});
|
||||
|
||||
std::set<DPNID> p1_dp_dpnidPlayer;
|
||||
bool p1_ts = false;
|
||||
|
||||
peer1.expect_begin();
|
||||
peer1.expect_push([&host, &peer1, &peer2, &p1_dp_dpnidPlayer, &p1_ts](DWORD dwMessageType, PVOID pMessage)
|
||||
{
|
||||
if(dwMessageType == DPN_MSGID_DESTROY_PLAYER)
|
||||
{
|
||||
DPNMSG_DESTROY_PLAYER *dp = (DPNMSG_DESTROY_PLAYER*)(pMessage);
|
||||
|
||||
EXPECT_EQ(dp->dwSize, sizeof(DPNMSG_DESTROY_PLAYER));
|
||||
|
||||
EXPECT_TRUE((dp->dpnidPlayer == host.first_cp_dpnidPlayer || dp->dpnidPlayer == peer1.first_cc_dpnidLocal || dp->dpnidPlayer == peer2.first_cc_dpnidLocal))
|
||||
<< "(dpnidPlayer = " << dp->dpnidPlayer
|
||||
<< ", host = " << host.first_cp_dpnidPlayer
|
||||
<< ", peer1 = " << peer1.first_cc_dpnidLocal
|
||||
<< ", peer2 = " << peer2.first_cc_dpnidLocal << ")";
|
||||
|
||||
EXPECT_EQ(dp->pvPlayerContext, (void*)~(uintptr_t)(dp->dpnidPlayer));
|
||||
|
||||
if(dp->dpnidPlayer == host.first_cp_dpnidPlayer)
|
||||
{
|
||||
EXPECT_EQ(dp->dwReason, DPNDESTROYPLAYERREASON_NORMAL);
|
||||
}
|
||||
else{
|
||||
EXPECT_TRUE((dp->dwReason == DPNDESTROYPLAYERREASON_NORMAL || dp->dwReason == DPNDESTROYPLAYERREASON_CONNECTIONLOST))
|
||||
<< "dwReason = " << dp->dwReason;
|
||||
}
|
||||
|
||||
p1_dp_dpnidPlayer.insert(dp->dpnidPlayer);
|
||||
}
|
||||
else if(dwMessageType == DPN_MSGID_TERMINATE_SESSION)
|
||||
{
|
||||
DPNMSG_TERMINATE_SESSION *ts = (DPNMSG_TERMINATE_SESSION*)(pMessage);
|
||||
|
||||
EXPECT_EQ(ts->dwSize, sizeof(DPNMSG_TERMINATE_SESSION));
|
||||
EXPECT_EQ(ts->hResultCode, DPNERR_CONNECTIONLOST);
|
||||
EXPECT_EQ(ts->pvTerminateData, (void*)(NULL));
|
||||
EXPECT_EQ(ts->dwTerminateDataSize, 0);
|
||||
|
||||
p1_ts = true;
|
||||
}
|
||||
else{
|
||||
ADD_FAILURE() << "Unexpected message type: " << dwMessageType;
|
||||
}
|
||||
|
||||
return DPN_OK;
|
||||
}, 4);
|
||||
|
||||
std::set<DPNID> p2_dp_dpnidPlayer;
|
||||
bool p2_ts = false;
|
||||
|
||||
peer2.expect_begin();
|
||||
peer2.expect_push([&host, &peer1, &peer2, &p2_dp_dpnidPlayer, &p2_ts](DWORD dwMessageType, PVOID pMessage)
|
||||
{
|
||||
if(dwMessageType == DPN_MSGID_DESTROY_PLAYER)
|
||||
{
|
||||
DPNMSG_DESTROY_PLAYER *dp = (DPNMSG_DESTROY_PLAYER*)(pMessage);
|
||||
|
||||
EXPECT_EQ(dp->dwSize, sizeof(DPNMSG_DESTROY_PLAYER));
|
||||
|
||||
EXPECT_TRUE((dp->dpnidPlayer == host.first_cp_dpnidPlayer || dp->dpnidPlayer == peer1.first_cc_dpnidLocal || dp->dpnidPlayer == peer2.first_cc_dpnidLocal))
|
||||
<< "(dpnidPlayer = " << dp->dpnidPlayer
|
||||
<< ", host = " << host.first_cp_dpnidPlayer
|
||||
<< ", peer1 = " << peer1.first_cc_dpnidLocal
|
||||
<< ", peer2 = " << peer2.first_cc_dpnidLocal << ")";
|
||||
|
||||
EXPECT_EQ(dp->pvPlayerContext, (void*)~(uintptr_t)(dp->dpnidPlayer));
|
||||
|
||||
if(dp->dpnidPlayer == host.first_cp_dpnidPlayer)
|
||||
{
|
||||
EXPECT_EQ(dp->dwReason, DPNDESTROYPLAYERREASON_NORMAL);
|
||||
}
|
||||
else{
|
||||
EXPECT_TRUE((dp->dwReason == DPNDESTROYPLAYERREASON_NORMAL || dp->dwReason == DPNDESTROYPLAYERREASON_CONNECTIONLOST))
|
||||
<< "dwReason = " << dp->dwReason;
|
||||
}
|
||||
|
||||
p2_dp_dpnidPlayer.insert(dp->dpnidPlayer);
|
||||
}
|
||||
else if(dwMessageType == DPN_MSGID_TERMINATE_SESSION)
|
||||
{
|
||||
DPNMSG_TERMINATE_SESSION *ts = (DPNMSG_TERMINATE_SESSION*)(pMessage);
|
||||
|
||||
EXPECT_EQ(ts->dwSize, sizeof(DPNMSG_TERMINATE_SESSION));
|
||||
EXPECT_EQ(ts->hResultCode, DPNERR_CONNECTIONLOST);
|
||||
EXPECT_EQ(ts->pvTerminateData, (void*)(NULL));
|
||||
EXPECT_EQ(ts->dwTerminateDataSize, 0);
|
||||
|
||||
p2_ts = true;
|
||||
}
|
||||
else{
|
||||
ADD_FAILURE() << "Unexpected message type: " << dwMessageType;
|
||||
}
|
||||
|
||||
return DPN_OK;
|
||||
}, 4);
|
||||
|
||||
host->Close(0);
|
||||
|
||||
Sleep(100);
|
||||
|
||||
peer2.expect_end();
|
||||
peer1.expect_end();
|
||||
host.expect_end();
|
||||
|
||||
EXPECT_NE(host_dp1_dpnidPlayer, host_dp2_dpnidPlayer);
|
||||
|
||||
std::set<DPNID> all_players;
|
||||
all_players.insert(host.first_cp_dpnidPlayer);
|
||||
all_players.insert(peer1.first_cc_dpnidLocal);
|
||||
all_players.insert(peer2.first_cc_dpnidLocal);
|
||||
|
||||
EXPECT_EQ(p1_dp_dpnidPlayer, all_players);
|
||||
EXPECT_TRUE(p1_ts);
|
||||
|
||||
EXPECT_EQ(p2_dp_dpnidPlayer, all_players);
|
||||
EXPECT_TRUE(p2_ts);
|
||||
}
|
||||
|
||||
TEST(DirectPlay8Peer, HostPeerHardClose)
|
||||
{
|
||||
DPN_APPLICATION_DESC app_desc;
|
||||
memset(&app_desc, 0, sizeof(app_desc));
|
||||
|
||||
app_desc.dwSize = sizeof(app_desc);
|
||||
app_desc.guidApplication = APP_GUID_1;
|
||||
app_desc.pwszSessionName = L"Session 1";
|
||||
|
||||
IDP8AddressInstance host_addr(CLSID_DP8SP_TCPIP, PORT);
|
||||
|
||||
TestPeer host("host");
|
||||
ASSERT_EQ(host->Host(&app_desc, &(host_addr.instance), 1, NULL, NULL, 0, 0), S_OK);
|
||||
|
||||
IDP8AddressInstance connect_addr(CLSID_DP8SP_TCPIP, L"127.0.0.1", PORT);
|
||||
|
||||
TestPeer peer1("peer1");
|
||||
ASSERT_EQ(peer1->Connect(
|
||||
&app_desc, /* pdnAppDesc */
|
||||
connect_addr, /* pHostAddr */
|
||||
NULL, /* pDeviceInfo */
|
||||
NULL, /* pdnSecurity */
|
||||
NULL, /* pdnCredentials */
|
||||
NULL, /* pvUserConnectData */
|
||||
0, /* dwUserConnectDataSize */
|
||||
0, /* pvPlayerContext */
|
||||
NULL, /* pvAsyncContext */
|
||||
NULL, /* phAsyncHandle */
|
||||
DPNCONNECT_SYNC /* dwFlags */
|
||||
), S_OK);
|
||||
|
||||
TestPeer peer2("peer2");
|
||||
ASSERT_EQ(peer2->Connect(
|
||||
&app_desc, /* pdnAppDesc */
|
||||
connect_addr, /* pHostAddr */
|
||||
NULL, /* pDeviceInfo */
|
||||
NULL, /* pdnSecurity */
|
||||
NULL, /* pdnCredentials */
|
||||
NULL, /* pvUserConnectData */
|
||||
0, /* dwUserConnectDataSize */
|
||||
0, /* pvPlayerContext */
|
||||
NULL, /* pvAsyncContext */
|
||||
NULL, /* phAsyncHandle */
|
||||
DPNCONNECT_SYNC /* dwFlags */
|
||||
), S_OK);
|
||||
|
||||
Sleep(100);
|
||||
|
||||
DPNID host_dp1_dpnidPlayer;
|
||||
DPNID host_dp2_dpnidPlayer;
|
||||
|
||||
host.expect_begin();
|
||||
host.expect_push([&host, &peer1, &peer2](DWORD dwMessageType, PVOID pMessage)
|
||||
{
|
||||
EXPECT_EQ(dwMessageType, DPN_MSGID_DESTROY_PLAYER);
|
||||
|
||||
if(dwMessageType == DPN_MSGID_DESTROY_PLAYER)
|
||||
{
|
||||
DPNMSG_DESTROY_PLAYER *dp = (DPNMSG_DESTROY_PLAYER*)(pMessage);
|
||||
|
||||
EXPECT_EQ(dp->dwSize, sizeof(DPNMSG_DESTROY_PLAYER));
|
||||
|
||||
EXPECT_TRUE((dp->dpnidPlayer == host.first_cp_dpnidPlayer))
|
||||
<< "(dpnidPlayer = " << dp->dpnidPlayer
|
||||
<< ", host = " << host.first_cp_dpnidPlayer
|
||||
<< ", peer1 = " << peer1.first_cc_dpnidLocal
|
||||
<< ", peer2 = " << peer2.first_cc_dpnidLocal << ")";
|
||||
|
||||
EXPECT_EQ(dp->pvPlayerContext, (void*)~(uintptr_t)(dp->dpnidPlayer));
|
||||
EXPECT_EQ(dp->dwReason, DPNDESTROYPLAYERREASON_NORMAL);
|
||||
}
|
||||
|
||||
return DPN_OK;
|
||||
});
|
||||
host.expect_push([&host, &peer1, &peer2, &host_dp1_dpnidPlayer](DWORD dwMessageType, PVOID pMessage)
|
||||
{
|
||||
EXPECT_EQ(dwMessageType, DPN_MSGID_DESTROY_PLAYER);
|
||||
|
||||
if(dwMessageType == DPN_MSGID_DESTROY_PLAYER)
|
||||
{
|
||||
DPNMSG_DESTROY_PLAYER *dp = (DPNMSG_DESTROY_PLAYER*)(pMessage);
|
||||
|
||||
EXPECT_EQ(dp->dwSize, sizeof(DPNMSG_DESTROY_PLAYER));
|
||||
|
||||
EXPECT_TRUE((dp->dpnidPlayer == peer1.first_cc_dpnidLocal || dp->dpnidPlayer == peer2.first_cc_dpnidLocal))
|
||||
<< "(dpnidPlayer = " << dp->dpnidPlayer
|
||||
<< ", host = " << host.first_cp_dpnidPlayer
|
||||
<< ", peer1 = " << peer1.first_cc_dpnidLocal
|
||||
<< ", peer2 = " << peer2.first_cc_dpnidLocal << ")";
|
||||
|
||||
EXPECT_EQ(dp->pvPlayerContext, (void*)~(uintptr_t)(dp->dpnidPlayer));
|
||||
EXPECT_EQ(dp->dwReason, DPNDESTROYPLAYERREASON_NORMAL);
|
||||
|
||||
host_dp1_dpnidPlayer = dp->dpnidPlayer;
|
||||
}
|
||||
|
||||
return DPN_OK;
|
||||
});
|
||||
host.expect_push([&host, &peer1, &peer2, &host_dp2_dpnidPlayer](DWORD dwMessageType, PVOID pMessage)
|
||||
{
|
||||
EXPECT_EQ(dwMessageType, DPN_MSGID_DESTROY_PLAYER);
|
||||
|
||||
if(dwMessageType == DPN_MSGID_DESTROY_PLAYER)
|
||||
{
|
||||
DPNMSG_DESTROY_PLAYER *dp = (DPNMSG_DESTROY_PLAYER*)(pMessage);
|
||||
|
||||
EXPECT_EQ(dp->dwSize, sizeof(DPNMSG_DESTROY_PLAYER));
|
||||
|
||||
EXPECT_TRUE((dp->dpnidPlayer == peer1.first_cc_dpnidLocal || dp->dpnidPlayer == peer2.first_cc_dpnidLocal))
|
||||
<< "(dpnidPlayer = " << dp->dpnidPlayer
|
||||
<< ", host = " << host.first_cp_dpnidPlayer
|
||||
<< ", peer1 = " << peer1.first_cc_dpnidLocal
|
||||
<< ", peer2 = " << peer2.first_cc_dpnidLocal << ")";
|
||||
|
||||
EXPECT_EQ(dp->pvPlayerContext, (void*)~(uintptr_t)(dp->dpnidPlayer));
|
||||
EXPECT_EQ(dp->dwReason, DPNDESTROYPLAYERREASON_NORMAL);
|
||||
|
||||
host_dp2_dpnidPlayer = dp->dpnidPlayer;
|
||||
}
|
||||
|
||||
return DPN_OK;
|
||||
});
|
||||
|
||||
std::set<DPNID> p1_dp_dpnidPlayer;
|
||||
bool p1_ts = false;
|
||||
|
||||
peer1.expect_begin();
|
||||
peer1.expect_push([&host, &peer1, &peer2, &p1_dp_dpnidPlayer, &p1_ts](DWORD dwMessageType, PVOID pMessage)
|
||||
{
|
||||
if(dwMessageType == DPN_MSGID_DESTROY_PLAYER)
|
||||
{
|
||||
DPNMSG_DESTROY_PLAYER *dp = (DPNMSG_DESTROY_PLAYER*)(pMessage);
|
||||
|
||||
EXPECT_EQ(dp->dwSize, sizeof(DPNMSG_DESTROY_PLAYER));
|
||||
|
||||
EXPECT_TRUE((dp->dpnidPlayer == host.first_cp_dpnidPlayer || dp->dpnidPlayer == peer1.first_cc_dpnidLocal || dp->dpnidPlayer == peer2.first_cc_dpnidLocal))
|
||||
<< "(dpnidPlayer = " << dp->dpnidPlayer
|
||||
<< ", host = " << host.first_cp_dpnidPlayer
|
||||
<< ", peer1 = " << peer1.first_cc_dpnidLocal
|
||||
<< ", peer2 = " << peer2.first_cc_dpnidLocal << ")";
|
||||
|
||||
EXPECT_EQ(dp->pvPlayerContext, (void*)~(uintptr_t)(dp->dpnidPlayer));
|
||||
|
||||
if(dp->dpnidPlayer == host.first_cp_dpnidPlayer)
|
||||
{
|
||||
EXPECT_EQ(dp->dwReason, DPNDESTROYPLAYERREASON_CONNECTIONLOST);
|
||||
}
|
||||
else{
|
||||
EXPECT_TRUE((dp->dwReason == DPNDESTROYPLAYERREASON_NORMAL || dp->dwReason == DPNDESTROYPLAYERREASON_CONNECTIONLOST))
|
||||
<< "dwReason = " << dp->dwReason;
|
||||
}
|
||||
|
||||
p1_dp_dpnidPlayer.insert(dp->dpnidPlayer);
|
||||
}
|
||||
else if(dwMessageType == DPN_MSGID_TERMINATE_SESSION)
|
||||
{
|
||||
DPNMSG_TERMINATE_SESSION *ts = (DPNMSG_TERMINATE_SESSION*)(pMessage);
|
||||
|
||||
EXPECT_EQ(ts->dwSize, sizeof(DPNMSG_TERMINATE_SESSION));
|
||||
EXPECT_EQ(ts->hResultCode, DPNERR_CONNECTIONLOST);
|
||||
EXPECT_EQ(ts->pvTerminateData, (void*)(NULL));
|
||||
EXPECT_EQ(ts->dwTerminateDataSize, 0);
|
||||
|
||||
p1_ts = true;
|
||||
}
|
||||
else{
|
||||
ADD_FAILURE() << "Unexpected message type: " << dwMessageType;
|
||||
}
|
||||
|
||||
return DPN_OK;
|
||||
}, 4);
|
||||
|
||||
std::set<DPNID> p2_dp_dpnidPlayer;
|
||||
bool p2_ts = false;
|
||||
|
||||
peer2.expect_begin();
|
||||
peer2.expect_push([&host, &peer1, &peer2, &p2_dp_dpnidPlayer, &p2_ts](DWORD dwMessageType, PVOID pMessage)
|
||||
{
|
||||
if(dwMessageType == DPN_MSGID_DESTROY_PLAYER)
|
||||
{
|
||||
DPNMSG_DESTROY_PLAYER *dp = (DPNMSG_DESTROY_PLAYER*)(pMessage);
|
||||
|
||||
EXPECT_EQ(dp->dwSize, sizeof(DPNMSG_DESTROY_PLAYER));
|
||||
|
||||
EXPECT_TRUE((dp->dpnidPlayer == host.first_cp_dpnidPlayer || dp->dpnidPlayer == peer1.first_cc_dpnidLocal || dp->dpnidPlayer == peer2.first_cc_dpnidLocal))
|
||||
<< "(dpnidPlayer = " << dp->dpnidPlayer
|
||||
<< ", host = " << host.first_cp_dpnidPlayer
|
||||
<< ", peer1 = " << peer1.first_cc_dpnidLocal
|
||||
<< ", peer2 = " << peer2.first_cc_dpnidLocal << ")";
|
||||
|
||||
EXPECT_EQ(dp->pvPlayerContext, (void*)~(uintptr_t)(dp->dpnidPlayer));
|
||||
|
||||
if(dp->dpnidPlayer == host.first_cp_dpnidPlayer)
|
||||
{
|
||||
EXPECT_EQ(dp->dwReason, DPNDESTROYPLAYERREASON_CONNECTIONLOST);
|
||||
}
|
||||
else{
|
||||
EXPECT_TRUE((dp->dwReason == DPNDESTROYPLAYERREASON_NORMAL || dp->dwReason == DPNDESTROYPLAYERREASON_CONNECTIONLOST))
|
||||
<< "dwReason = " << dp->dwReason;
|
||||
}
|
||||
|
||||
p2_dp_dpnidPlayer.insert(dp->dpnidPlayer);
|
||||
}
|
||||
else if(dwMessageType == DPN_MSGID_TERMINATE_SESSION)
|
||||
{
|
||||
DPNMSG_TERMINATE_SESSION *ts = (DPNMSG_TERMINATE_SESSION*)(pMessage);
|
||||
|
||||
EXPECT_EQ(ts->dwSize, sizeof(DPNMSG_TERMINATE_SESSION));
|
||||
EXPECT_EQ(ts->hResultCode, DPNERR_CONNECTIONLOST);
|
||||
EXPECT_EQ(ts->pvTerminateData, (void*)(NULL));
|
||||
EXPECT_EQ(ts->dwTerminateDataSize, 0);
|
||||
|
||||
p2_ts = true;
|
||||
}
|
||||
else{
|
||||
ADD_FAILURE() << "Unexpected message type: " << dwMessageType;
|
||||
}
|
||||
|
||||
return DPN_OK;
|
||||
}, 4);
|
||||
|
||||
host->Close(DPNCLOSE_IMMEDIATE);
|
||||
|
||||
Sleep(100);
|
||||
|
||||
peer2.expect_end();
|
||||
peer1.expect_end();
|
||||
host.expect_end();
|
||||
|
||||
EXPECT_NE(host_dp1_dpnidPlayer, host_dp2_dpnidPlayer);
|
||||
|
||||
std::set<DPNID> all_players;
|
||||
all_players.insert(host.first_cp_dpnidPlayer);
|
||||
all_players.insert(peer1.first_cc_dpnidLocal);
|
||||
all_players.insert(peer2.first_cc_dpnidLocal);
|
||||
|
||||
EXPECT_EQ(p1_dp_dpnidPlayer, all_players);
|
||||
EXPECT_TRUE(p1_ts);
|
||||
|
||||
EXPECT_EQ(p2_dp_dpnidPlayer, all_players);
|
||||
EXPECT_TRUE(p2_ts);
|
||||
}
|
||||
|
||||
TEST(DirectPlay8Peer, NonHostPeerSoftClose)
|
||||
{
|
||||
DPN_APPLICATION_DESC app_desc;
|
||||
@ -2521,11 +3014,11 @@ TEST(DirectPlay8Peer, NonHostPeerSoftClose)
|
||||
return DPN_OK;
|
||||
});
|
||||
|
||||
DPNID p2_dp_dpnidPlayer1;
|
||||
DPNID p2_dp_dpnidPlayer2;
|
||||
DPNID p2_dp1_dpnidPlayer;
|
||||
DPNID p2_dp2_dpnidPlayer;
|
||||
|
||||
peer2.expect_begin();
|
||||
peer2.expect_push([&host, &peer1, &peer2, &p2_dp_dpnidPlayer1](DWORD dwMessageType, PVOID pMessage)
|
||||
peer2.expect_push([&host, &peer1, &peer2, &p2_dp1_dpnidPlayer](DWORD dwMessageType, PVOID pMessage)
|
||||
{
|
||||
EXPECT_EQ(dwMessageType, DPN_MSGID_DESTROY_PLAYER);
|
||||
|
||||
@ -2544,12 +3037,12 @@ TEST(DirectPlay8Peer, NonHostPeerSoftClose)
|
||||
EXPECT_EQ(dp->pvPlayerContext, (void*)~(uintptr_t)(dp->dpnidPlayer));
|
||||
EXPECT_EQ(dp->dwReason, DPNDESTROYPLAYERREASON_NORMAL);
|
||||
|
||||
p2_dp_dpnidPlayer1 = dp->dpnidPlayer;
|
||||
p2_dp1_dpnidPlayer = dp->dpnidPlayer;
|
||||
}
|
||||
|
||||
return DPN_OK;
|
||||
});
|
||||
peer2.expect_push([&host, &peer1, &peer2, &p2_dp_dpnidPlayer2](DWORD dwMessageType, PVOID pMessage)
|
||||
peer2.expect_push([&host, &peer1, &peer2, &p2_dp2_dpnidPlayer](DWORD dwMessageType, PVOID pMessage)
|
||||
{
|
||||
EXPECT_EQ(dwMessageType, DPN_MSGID_DESTROY_PLAYER);
|
||||
|
||||
@ -2568,7 +3061,7 @@ TEST(DirectPlay8Peer, NonHostPeerSoftClose)
|
||||
EXPECT_EQ(dp->pvPlayerContext, (void*)~(uintptr_t)(dp->dpnidPlayer));
|
||||
EXPECT_EQ(dp->dwReason, DPNDESTROYPLAYERREASON_NORMAL);
|
||||
|
||||
p2_dp_dpnidPlayer2 = dp->dpnidPlayer;
|
||||
p2_dp2_dpnidPlayer = dp->dpnidPlayer;
|
||||
}
|
||||
|
||||
return DPN_OK;
|
||||
@ -2604,7 +3097,7 @@ TEST(DirectPlay8Peer, NonHostPeerSoftClose)
|
||||
peer1.expect_end();
|
||||
host.expect_end();
|
||||
|
||||
EXPECT_NE(p2_dp_dpnidPlayer1, p2_dp_dpnidPlayer2);
|
||||
EXPECT_NE(p2_dp1_dpnidPlayer, p2_dp2_dpnidPlayer);
|
||||
}
|
||||
|
||||
TEST(DirectPlay8Peer, NonHostPeerHardClose)
|
||||
@ -2691,11 +3184,11 @@ TEST(DirectPlay8Peer, NonHostPeerHardClose)
|
||||
return DPN_OK;
|
||||
});
|
||||
|
||||
DPNID p2_dp_dpnidPlayer1;
|
||||
DPNID p2_dp_dpnidPlayer2;
|
||||
DPNID p2_dp1_dpnidPlayer;
|
||||
DPNID p2_dp2_dpnidPlayer;
|
||||
|
||||
peer2.expect_begin();
|
||||
peer2.expect_push([&host, &peer1, &peer2, &p2_dp_dpnidPlayer1](DWORD dwMessageType, PVOID pMessage)
|
||||
peer2.expect_push([&host, &peer1, &peer2, &p2_dp1_dpnidPlayer](DWORD dwMessageType, PVOID pMessage)
|
||||
{
|
||||
EXPECT_EQ(dwMessageType, DPN_MSGID_DESTROY_PLAYER);
|
||||
|
||||
@ -2714,12 +3207,12 @@ TEST(DirectPlay8Peer, NonHostPeerHardClose)
|
||||
EXPECT_EQ(dp->pvPlayerContext, (void*)~(uintptr_t)(dp->dpnidPlayer));
|
||||
EXPECT_EQ(dp->dwReason, DPNDESTROYPLAYERREASON_NORMAL);
|
||||
|
||||
p2_dp_dpnidPlayer1 = dp->dpnidPlayer;
|
||||
p2_dp1_dpnidPlayer = dp->dpnidPlayer;
|
||||
}
|
||||
|
||||
return DPN_OK;
|
||||
});
|
||||
peer2.expect_push([&host, &peer1, &peer2, &p2_dp_dpnidPlayer2](DWORD dwMessageType, PVOID pMessage)
|
||||
peer2.expect_push([&host, &peer1, &peer2, &p2_dp2_dpnidPlayer](DWORD dwMessageType, PVOID pMessage)
|
||||
{
|
||||
EXPECT_EQ(dwMessageType, DPN_MSGID_DESTROY_PLAYER);
|
||||
|
||||
@ -2738,7 +3231,7 @@ TEST(DirectPlay8Peer, NonHostPeerHardClose)
|
||||
EXPECT_EQ(dp->pvPlayerContext, (void*)~(uintptr_t)(dp->dpnidPlayer));
|
||||
EXPECT_EQ(dp->dwReason, DPNDESTROYPLAYERREASON_NORMAL);
|
||||
|
||||
p2_dp_dpnidPlayer2 = dp->dpnidPlayer;
|
||||
p2_dp2_dpnidPlayer = dp->dpnidPlayer;
|
||||
}
|
||||
|
||||
return DPN_OK;
|
||||
@ -2774,7 +3267,7 @@ TEST(DirectPlay8Peer, NonHostPeerHardClose)
|
||||
peer1.expect_end();
|
||||
host.expect_end();
|
||||
|
||||
EXPECT_NE(p2_dp_dpnidPlayer1, p2_dp_dpnidPlayer2);
|
||||
EXPECT_NE(p2_dp1_dpnidPlayer, p2_dp2_dpnidPlayer);
|
||||
}
|
||||
|
||||
TEST(DirectPlay8Peer, GetApplicationDesc)
|
||||
|
Loading…
x
Reference in New Issue
Block a user