mirror of
https://github.com/solemnwarning/directplay-lite
synced 2024-12-30 16:45:37 +01:00
Handle group cleanups for session end etc
This commit is contained in:
parent
e8e35c1c45
commit
6df47cee60
@ -2478,6 +2478,8 @@ HRESULT DirectPlay8Peer::Close(CONST DWORD dwFlags)
|
|||||||
dispatch_destroy_player(l, local_player_id, local_player_ctx, DPNDESTROYPLAYERREASON_NORMAL);
|
dispatch_destroy_player(l, local_player_id, local_player_ctx, DPNDESTROYPLAYERREASON_NORMAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
group_destroy_all(l, DPNDESTROYGROUPREASON_NORMAL);
|
||||||
|
|
||||||
/* Wait for outstanding EnumHosts() calls. */
|
/* Wait for outstanding EnumHosts() calls. */
|
||||||
host_enum_completed.wait(l, [this]() { return async_host_enums.empty() && sync_host_enums.empty(); });
|
host_enum_completed.wait(l, [this]() { return async_host_enums.empty() && sync_host_enums.empty(); });
|
||||||
|
|
||||||
@ -2945,6 +2947,8 @@ HRESULT DirectPlay8Peer::TerminateSession(void* CONST pvTerminateData, CONST DWO
|
|||||||
dispatch_destroy_player(l, cp->first, cp->second, DPNDESTROYPLAYERREASON_SESSIONTERMINATED);
|
dispatch_destroy_player(l, cp->first, cp->second, DPNDESTROYPLAYERREASON_SESSIONTERMINATED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
group_destroy_all(l, DPNDESTROYGROUPREASON_NORMAL);
|
||||||
|
|
||||||
/* Destroy any peers which weren't fully connected. */
|
/* Destroy any peers which weren't fully connected. */
|
||||||
|
|
||||||
for(auto dp = destroy_peers.begin(); dp != destroy_peers.end();)
|
for(auto dp = destroy_peers.begin(); dp != destroy_peers.end();)
|
||||||
@ -3788,6 +3792,8 @@ void DirectPlay8Peer::peer_destroy(std::unique_lock<std::mutex> &l, unsigned int
|
|||||||
auto peer_id = peers.begin()->first;
|
auto peer_id = peers.begin()->first;
|
||||||
peer_destroy(l, peer_id, outstanding_op_result, destroy_player_reason);
|
peer_destroy(l, peer_id, outstanding_op_result, destroy_player_reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
group_destroy_all(l, DPNDESTROYGROUPREASON_NORMAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
RENEW_PEER_OR_RETURN();
|
RENEW_PEER_OR_RETURN();
|
||||||
@ -3882,6 +3888,23 @@ void DirectPlay8Peer::peer_shutdown_all(std::unique_lock<std::mutex> &l, HRESULT
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DirectPlay8Peer::group_destroy_all(std::unique_lock<std::mutex> &l, DWORD dwReason)
|
||||||
|
{
|
||||||
|
for(std::map<DPNID, Group>::iterator g; (g = groups.begin()) != groups.end();)
|
||||||
|
{
|
||||||
|
DPNID group_id = g->first;
|
||||||
|
Group *group = &(g->second);
|
||||||
|
|
||||||
|
if(destroyed_groups.find(group_id) == destroyed_groups.end())
|
||||||
|
{
|
||||||
|
destroyed_groups.insert(group_id);
|
||||||
|
dispatch_destroy_group(l, group_id, group->ctx, dwReason);
|
||||||
|
}
|
||||||
|
|
||||||
|
groups.erase(group_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void DirectPlay8Peer::close_main_sockets()
|
void DirectPlay8Peer::close_main_sockets()
|
||||||
{
|
{
|
||||||
if(discovery_socket != -1)
|
if(discovery_socket != -1)
|
||||||
@ -4581,6 +4604,8 @@ void DirectPlay8Peer::handle_connect_peer(std::unique_lock<std::mutex> &l, unsig
|
|||||||
|
|
||||||
/* Send DPLITE_MSGID_GROUP_CREATE for each group. */
|
/* Send DPLITE_MSGID_GROUP_CREATE for each group. */
|
||||||
|
|
||||||
|
std::set<DPNID> member_group_ids;
|
||||||
|
|
||||||
for(auto gi = groups.begin(); gi != groups.end(); ++gi)
|
for(auto gi = groups.begin(); gi != groups.end(); ++gi)
|
||||||
{
|
{
|
||||||
DPNID group_id = gi->first;
|
DPNID group_id = gi->first;
|
||||||
@ -4599,6 +4624,11 @@ void DirectPlay8Peer::handle_connect_peer(std::unique_lock<std::mutex> &l, unsig
|
|||||||
|
|
||||||
peer->sq.send(SendQueue::SEND_PRI_HIGH, group_create, NULL,
|
peer->sq.send(SendQueue::SEND_PRI_HIGH, group_create, NULL,
|
||||||
[](std::unique_lock<std::mutex> &l, HRESULT result) {});
|
[](std::unique_lock<std::mutex> &l, HRESULT result) {});
|
||||||
|
|
||||||
|
if(group->player_ids.find(local_player_id) != group->player_ids.end())
|
||||||
|
{
|
||||||
|
member_group_ids.insert(group_id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Send DPLITE_MSGID_CONNECT_PEER_OK. */
|
/* Send DPLITE_MSGID_CONNECT_PEER_OK. */
|
||||||
@ -4607,7 +4637,12 @@ void DirectPlay8Peer::handle_connect_peer(std::unique_lock<std::mutex> &l, unsig
|
|||||||
connect_peer_ok.append_wstring(local_player_name);
|
connect_peer_ok.append_wstring(local_player_name);
|
||||||
connect_peer_ok.append_data(local_player_data.data(), local_player_data.size());
|
connect_peer_ok.append_data(local_player_data.data(), local_player_data.size());
|
||||||
|
|
||||||
/* TODO: Include our group memberships. */
|
connect_peer_ok.append_dword(member_group_ids.size());
|
||||||
|
|
||||||
|
for(auto i = member_group_ids.begin(); i != member_group_ids.end(); ++i)
|
||||||
|
{
|
||||||
|
connect_peer_ok.append_dword(*i);
|
||||||
|
}
|
||||||
|
|
||||||
peer->sq.send(SendQueue::SEND_PRI_HIGH,
|
peer->sq.send(SendQueue::SEND_PRI_HIGH,
|
||||||
connect_peer_ok,
|
connect_peer_ok,
|
||||||
@ -4655,6 +4690,14 @@ void DirectPlay8Peer::handle_connect_peer_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);
|
||||||
|
|
||||||
|
DWORD peer_group_count = pd.get_dword(2);
|
||||||
|
std::set<DPNID> peer_groups;
|
||||||
|
|
||||||
|
for(DWORD i = 0; i < peer_group_count; ++i)
|
||||||
|
{
|
||||||
|
peer_groups.insert(pd.get_dword(3 + i));
|
||||||
|
}
|
||||||
|
|
||||||
peer->state = Peer::PS_CONNECTED;
|
peer->state = Peer::PS_CONNECTED;
|
||||||
|
|
||||||
/* player_id initialised in handling of DPLITE_MSGID_CONNECT_HOST_OK. */
|
/* player_id initialised in handling of DPLITE_MSGID_CONNECT_HOST_OK. */
|
||||||
@ -4677,7 +4720,46 @@ void DirectPlay8Peer::handle_connect_peer_ok(std::unique_lock<std::mutex> &l, un
|
|||||||
peer->player_ctx = cp.pvPlayerContext;
|
peer->player_ctx = cp.pvPlayerContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: Add peer to specified groups. */
|
for(auto g = peer_groups.begin(); g != peer_groups.end(); ++g)
|
||||||
|
{
|
||||||
|
DPNID group_id = *g;
|
||||||
|
|
||||||
|
if(destroyed_groups.find(group_id) != destroyed_groups.end())
|
||||||
|
{
|
||||||
|
/* Group is already in the process of being destroyed. */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Group *group = get_group_by_id(group_id);
|
||||||
|
if(group == NULL)
|
||||||
|
{
|
||||||
|
/* Unknown group ID... very rarely normal. */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(group->player_ids.find(peer->player_id) != group->player_ids.end())
|
||||||
|
{
|
||||||
|
/* Already in group... somehow?! */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
group->player_ids.insert(peer->player_id);
|
||||||
|
|
||||||
|
DPNMSG_ADD_PLAYER_TO_GROUP ap;
|
||||||
|
memset(&ap, 0, sizeof(ap));
|
||||||
|
|
||||||
|
ap.dwSize = sizeof(ap);
|
||||||
|
ap.dpnidGroup = group_id;
|
||||||
|
ap.pvGroupContext = group->ctx;
|
||||||
|
ap.dpnidPlayer = peer->player_id;
|
||||||
|
ap.pvPlayerContext = peer->player_ctx;
|
||||||
|
|
||||||
|
l.unlock();
|
||||||
|
message_handler(message_handler_ctx, DPN_MSGID_ADD_PLAYER_TO_GROUP, &ap);
|
||||||
|
l.lock();
|
||||||
|
|
||||||
|
RENEW_PEER_OR_RETURN();
|
||||||
|
}
|
||||||
|
|
||||||
connect_check(l);
|
connect_check(l);
|
||||||
}
|
}
|
||||||
@ -4966,6 +5048,8 @@ void DirectPlay8Peer::handle_destroy_peer(std::unique_lock<std::mutex> &l, unsig
|
|||||||
}
|
}
|
||||||
|
|
||||||
peer_shutdown_all(l, DPNERR_HOSTTERMINATEDSESSION, DPNDESTROYPLAYERREASON_SESSIONTERMINATED);
|
peer_shutdown_all(l, DPNERR_HOSTTERMINATEDSESSION, DPNDESTROYPLAYERREASON_SESSIONTERMINATED);
|
||||||
|
|
||||||
|
group_destroy_all(l, DPNDESTROYGROUPREASON_SESSIONTERMINATED);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
/* The host called DestroyPeer() on another peer in the session.
|
/* The host called DestroyPeer() on another peer in the session.
|
||||||
@ -5032,6 +5116,8 @@ void DirectPlay8Peer::handle_terminate_session(std::unique_lock<std::mutex> &l,
|
|||||||
dispatch_destroy_player(l, local_player_id, local_player_ctx, DPNDESTROYPLAYERREASON_SESSIONTERMINATED);
|
dispatch_destroy_player(l, local_player_id, local_player_ctx, DPNDESTROYPLAYERREASON_SESSIONTERMINATED);
|
||||||
|
|
||||||
peer_shutdown_all(l, DPNERR_HOSTTERMINATEDSESSION, DPNDESTROYPLAYERREASON_SESSIONTERMINATED);
|
peer_shutdown_all(l, DPNERR_HOSTTERMINATEDSESSION, DPNDESTROYPLAYERREASON_SESSIONTERMINATED);
|
||||||
|
|
||||||
|
group_destroy_all(l, DPNDESTROYGROUPREASON_SESSIONTERMINATED);
|
||||||
}
|
}
|
||||||
catch(const PacketDeserialiser::Error &e)
|
catch(const PacketDeserialiser::Error &e)
|
||||||
{
|
{
|
||||||
@ -5627,6 +5713,36 @@ HRESULT DirectPlay8Peer::dispatch_create_player(std::unique_lock<std::mutex> &l,
|
|||||||
|
|
||||||
HRESULT DirectPlay8Peer::dispatch_destroy_player(std::unique_lock<std::mutex> &l, DPNID dpnidPlayer, void *pvPlayerContext, DWORD dwReason)
|
HRESULT DirectPlay8Peer::dispatch_destroy_player(std::unique_lock<std::mutex> &l, DPNID dpnidPlayer, void *pvPlayerContext, DWORD dwReason)
|
||||||
{
|
{
|
||||||
|
/* HACK: Remove the player ID from any groups it is still in. */
|
||||||
|
for(auto g = groups.begin(); g != groups.end();)
|
||||||
|
{
|
||||||
|
DPNID group_id = g->first;
|
||||||
|
Group *group = &(g->second);
|
||||||
|
|
||||||
|
if(group->player_ids.find(dpnidPlayer) != group->player_ids.end())
|
||||||
|
{
|
||||||
|
group->player_ids.erase(dpnidPlayer);
|
||||||
|
|
||||||
|
DPNMSG_REMOVE_PLAYER_FROM_GROUP rp;
|
||||||
|
memset(&rp, 0, sizeof(rp));
|
||||||
|
|
||||||
|
rp.dwSize = sizeof(rp);
|
||||||
|
rp.dpnidGroup = group_id;
|
||||||
|
rp.pvGroupContext = group->ctx;
|
||||||
|
rp.dpnidPlayer = dpnidPlayer;
|
||||||
|
rp.pvPlayerContext = pvPlayerContext;
|
||||||
|
|
||||||
|
l.unlock();
|
||||||
|
message_handler(message_handler_ctx, DPN_MSGID_REMOVE_PLAYER_FROM_GROUP, &rp);
|
||||||
|
l.lock();
|
||||||
|
|
||||||
|
g = groups.begin();
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
++g;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
DPNMSG_DESTROY_PLAYER dp;
|
DPNMSG_DESTROY_PLAYER dp;
|
||||||
memset(&dp, 0, sizeof(dp));
|
memset(&dp, 0, sizeof(dp));
|
||||||
|
|
||||||
@ -5638,6 +5754,18 @@ HRESULT DirectPlay8Peer::dispatch_destroy_player(std::unique_lock<std::mutex> &l
|
|||||||
return dispatch_message(l, DPN_MSGID_DESTROY_PLAYER, &dp);
|
return dispatch_message(l, DPN_MSGID_DESTROY_PLAYER, &dp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HRESULT DirectPlay8Peer::dispatch_destroy_group(std::unique_lock<std::mutex> &l, DPNID dpnidGroup, void *pvGroupContext, DWORD dwReason)
|
||||||
|
{
|
||||||
|
DPNMSG_DESTROY_GROUP dg;
|
||||||
|
|
||||||
|
dg.dwSize = sizeof(dg);
|
||||||
|
dg.dpnidGroup = dpnidGroup;
|
||||||
|
dg.pvGroupContext = pvGroupContext;
|
||||||
|
dg.dwReason = dwReason;
|
||||||
|
|
||||||
|
return dispatch_message(l, DPN_MSGID_DESTROY_GROUP, &dg);
|
||||||
|
}
|
||||||
|
|
||||||
DirectPlay8Peer::Peer::Peer(enum PeerState state, int sock, uint32_t ip, uint16_t port):
|
DirectPlay8Peer::Peer::Peer(enum PeerState state, int sock, uint32_t ip, uint16_t port):
|
||||||
state(state), sock(sock), ip(ip), port(port), recv_busy(false), recv_buf_cur(0), events(0), sq(event), send_open(true), next_ack_id(1)
|
state(state), sock(sock), ip(ip), port(port), recv_busy(false), recv_buf_cur(0), events(0), sq(event), send_open(true), next_ack_id(1)
|
||||||
{}
|
{}
|
||||||
|
@ -218,6 +218,8 @@ class DirectPlay8Peer: public IDirectPlay8Peer
|
|||||||
void peer_shutdown(std::unique_lock<std::mutex> &l, unsigned int peer_id, HRESULT outstanding_op_result, DWORD destroy_player_reason);
|
void peer_shutdown(std::unique_lock<std::mutex> &l, unsigned int peer_id, HRESULT outstanding_op_result, DWORD destroy_player_reason);
|
||||||
void peer_shutdown_all(std::unique_lock<std::mutex> &l, HRESULT outstanding_op_result, DWORD destroy_player_reason);
|
void peer_shutdown_all(std::unique_lock<std::mutex> &l, HRESULT outstanding_op_result, DWORD destroy_player_reason);
|
||||||
|
|
||||||
|
void group_destroy_all(std::unique_lock<std::mutex> &l, DWORD dwReason);
|
||||||
|
|
||||||
void close_main_sockets();
|
void close_main_sockets();
|
||||||
|
|
||||||
void handle_host_enum_request(std::unique_lock<std::mutex> &l, const PacketDeserialiser &pd, const struct sockaddr_in *from_addr);
|
void handle_host_enum_request(std::unique_lock<std::mutex> &l, const PacketDeserialiser &pd, const struct sockaddr_in *from_addr);
|
||||||
@ -246,6 +248,7 @@ class DirectPlay8Peer: public IDirectPlay8Peer
|
|||||||
HRESULT dispatch_message(std::unique_lock<std::mutex> &l, DWORD dwMessageType, PVOID pvMessage);
|
HRESULT dispatch_message(std::unique_lock<std::mutex> &l, DWORD dwMessageType, PVOID pvMessage);
|
||||||
HRESULT dispatch_create_player(std::unique_lock<std::mutex> &l, DPNID dpnidPlayer, void **ppvPlayerContext);
|
HRESULT dispatch_create_player(std::unique_lock<std::mutex> &l, DPNID dpnidPlayer, void **ppvPlayerContext);
|
||||||
HRESULT dispatch_destroy_player(std::unique_lock<std::mutex> &l, DPNID dpnidPlayer, void *pvPlayerContext, DWORD dwReason);
|
HRESULT dispatch_destroy_player(std::unique_lock<std::mutex> &l, DPNID dpnidPlayer, void *pvPlayerContext, DWORD dwReason);
|
||||||
|
HRESULT dispatch_destroy_group(std::unique_lock<std::mutex> &l, DPNID dpnidGroup, void *pvGroupContext, DWORD dwReason);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DirectPlay8Peer(std::atomic<unsigned int> *global_refcount);
|
DirectPlay8Peer(std::atomic<unsigned int> *global_refcount);
|
||||||
|
@ -9477,6 +9477,108 @@ TEST(DirectPlay8Peer, DestroyGroupByTerminateSession)
|
|||||||
peer1.expect_end();
|
peer1.expect_end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(DirectPlay8Peer, DestroyGroupByDestroyPeer)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
|
||||||
|
Sleep(100);
|
||||||
|
|
||||||
|
DPNID p1_cg_dpnidGroup;
|
||||||
|
|
||||||
|
peer1.expect_begin();
|
||||||
|
peer1.expect_push([&host, &p1_cg_dpnidGroup](DWORD dwMessageType, PVOID pMessage)
|
||||||
|
{
|
||||||
|
EXPECT_EQ(dwMessageType, DPN_MSGID_CREATE_GROUP);
|
||||||
|
if(dwMessageType == DPN_MSGID_CREATE_GROUP)
|
||||||
|
{
|
||||||
|
DPNMSG_CREATE_GROUP *cg = (DPNMSG_CREATE_GROUP*)(pMessage);
|
||||||
|
cg->pvGroupContext = (void*)(0xBCDE);
|
||||||
|
|
||||||
|
p1_cg_dpnidGroup = cg->dpnidGroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
});
|
||||||
|
|
||||||
|
DPN_GROUP_INFO group_info;
|
||||||
|
memset(&group_info, 0, sizeof(group_info));
|
||||||
|
|
||||||
|
group_info.dwSize = sizeof(group_info);
|
||||||
|
group_info.dwInfoFlags = DPNINFO_NAME | DPNINFO_DATA;
|
||||||
|
group_info.pwszName = L"Test Group";
|
||||||
|
group_info.pvData = NULL;
|
||||||
|
group_info.dwDataSize = 0;
|
||||||
|
group_info.dwGroupFlags = 0;
|
||||||
|
|
||||||
|
ASSERT_EQ(host->CreateGroup(
|
||||||
|
&group_info, /* pdpnGroupInfo */
|
||||||
|
NULL, /* pvGroupContext */
|
||||||
|
NULL, /* pvAsyncContext */
|
||||||
|
NULL, /* phAsyncHandle */
|
||||||
|
DPNCREATEGROUP_SYNC), /* dwFlags */
|
||||||
|
S_OK);
|
||||||
|
|
||||||
|
Sleep(250);
|
||||||
|
|
||||||
|
peer1.expect_end();
|
||||||
|
|
||||||
|
peer1.expect_begin();
|
||||||
|
peer1.expect_push([](DWORD dwMessageType, PVOID pMessage)
|
||||||
|
{
|
||||||
|
EXPECT_TRUE(dwMessageType == DPN_MSGID_DESTROY_PLAYER
|
||||||
|
|| dwMessageType == DPN_MSGID_TERMINATE_SESSION);
|
||||||
|
return S_OK;
|
||||||
|
}, 3);
|
||||||
|
peer1.expect_push([&host, &p1_cg_dpnidGroup](DWORD dwMessageType, PVOID pMessage)
|
||||||
|
{
|
||||||
|
EXPECT_EQ(dwMessageType, DPN_MSGID_DESTROY_GROUP);
|
||||||
|
if(dwMessageType == DPN_MSGID_DESTROY_GROUP)
|
||||||
|
{
|
||||||
|
DPNMSG_DESTROY_GROUP *dg = (DPNMSG_DESTROY_GROUP*)(pMessage);
|
||||||
|
|
||||||
|
EXPECT_EQ(dg->dwSize, sizeof(DPNMSG_DESTROY_GROUP));
|
||||||
|
EXPECT_EQ(dg->dpnidGroup, p1_cg_dpnidGroup);
|
||||||
|
EXPECT_EQ(dg->pvGroupContext, (void*)(0xBCDE));
|
||||||
|
EXPECT_EQ(dg->dwReason, DPNDESTROYGROUPREASON_SESSIONTERMINATED);
|
||||||
|
}
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
});
|
||||||
|
|
||||||
|
ASSERT_EQ(host->DestroyPeer(peer1.first_cc_dpnidLocal, NULL, 0, 0), S_OK);
|
||||||
|
|
||||||
|
Sleep(250);
|
||||||
|
|
||||||
|
peer1.expect_end();
|
||||||
|
}
|
||||||
|
|
||||||
TEST(DirectPlay8Peer, AddPlayerToGroupSync)
|
TEST(DirectPlay8Peer, AddPlayerToGroupSync)
|
||||||
{
|
{
|
||||||
const unsigned char GROUP_DATA[] = { 0x01, 0x00, 0x02, 0x03, 0x04, 0x05, 0x06 };
|
const unsigned char GROUP_DATA[] = { 0x01, 0x00, 0x02, 0x03, 0x04, 0x05, 0x06 };
|
||||||
|
Loading…
x
Reference in New Issue
Block a user