mirror of
https://github.com/solemnwarning/directplay-lite
synced 2024-12-30 16:45:37 +01:00
Connect non-host peers in sessions together.
This commit is contained in:
parent
a91ded1268
commit
818adcbba1
@ -415,6 +415,12 @@ HRESULT DirectPlay8Peer::Connect(CONST DPN_APPLICATION_DESC* CONST pdnAppDesc, I
|
||||
return DPNERR_GENERIC;
|
||||
}
|
||||
|
||||
if(WSAEventSelect(udp_socket, udp_socket_event, FD_READ | FD_WRITE) != 0
|
||||
|| WSAEventSelect(listener_socket, other_socket_event, FD_ACCEPT) != 0)
|
||||
{
|
||||
return DPNERR_GENERIC;
|
||||
}
|
||||
|
||||
if(dwFlags & DPNCONNECT_SYNC)
|
||||
{
|
||||
connect_cv.wait(l, [this]() { return (state != STATE_CONNECTING && state != STATE_CONNECT_FAILED); });
|
||||
@ -1937,7 +1943,22 @@ void DirectPlay8Peer::io_peer_connected(std::unique_lock<std::mutex> &l, unsigne
|
||||
}
|
||||
else if(peer->state == Peer::PS_CONNECTING_PEER)
|
||||
{
|
||||
/* TODO: Send DPLITE_MSGID_CONNECT_PEER message. */
|
||||
PacketSerialiser connect_peer(DPLITE_MSGID_CONNECT_PEER);
|
||||
|
||||
connect_peer.append_guid(instance_guid);
|
||||
connect_peer.append_guid(application_guid);
|
||||
connect_peer.append_wstring(password);
|
||||
|
||||
connect_peer.append_dword(local_player_id);
|
||||
connect_peer.append_wstring(local_player_name);
|
||||
connect_peer.append_data(local_player_data.data(), local_player_data.size());
|
||||
|
||||
peer->sq.send(SendQueue::SEND_PRI_HIGH,
|
||||
connect_peer,
|
||||
NULL,
|
||||
[](std::unique_lock<std::mutex> &l, HRESULT result){});
|
||||
|
||||
peer->state = Peer::PS_REQUESTING_PEER;
|
||||
}
|
||||
}
|
||||
else{
|
||||
@ -2122,6 +2143,24 @@ void DirectPlay8Peer::io_peer_recv(std::unique_lock<std::mutex> &l, unsigned int
|
||||
break;
|
||||
}
|
||||
|
||||
case DPLITE_MSGID_CONNECT_PEER:
|
||||
{
|
||||
handle_connect_peer(l, peer_id, *pd);
|
||||
break;
|
||||
}
|
||||
|
||||
case DPLITE_MSGID_CONNECT_PEER_OK:
|
||||
{
|
||||
handle_connect_peer_ok(l, peer_id, *pd);
|
||||
break;
|
||||
}
|
||||
|
||||
case DPLITE_MSGID_CONNECT_PEER_FAIL:
|
||||
{
|
||||
handle_connect_peer_fail(l, peer_id, *pd);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
log_printf(
|
||||
"Unexpected message type %u received from peer %u",
|
||||
@ -2204,7 +2243,7 @@ void DirectPlay8Peer::peer_accept(std::unique_lock<std::mutex> &l)
|
||||
worker_pool.add_handle(peer->event, [this, peer_id]() { io_peer_triggered(peer_id); });
|
||||
}
|
||||
|
||||
bool DirectPlay8Peer::peer_connect(Peer::PeerState initial_state, uint32_t remote_ip, uint16_t remote_port)
|
||||
bool DirectPlay8Peer::peer_connect(Peer::PeerState initial_state, uint32_t remote_ip, uint16_t remote_port, DPNID player_id)
|
||||
{
|
||||
int p_sock = create_client_socket(local_ip, local_port);
|
||||
if(p_sock == -1)
|
||||
@ -2215,6 +2254,8 @@ bool DirectPlay8Peer::peer_connect(Peer::PeerState initial_state, uint32_t remot
|
||||
unsigned int peer_id = next_peer_id++;
|
||||
Peer *peer = new Peer(initial_state, p_sock, remote_ip, remote_port);
|
||||
|
||||
peer->player_id = player_id;
|
||||
|
||||
if(WSAEventSelect(peer->sock, peer->event, FD_CONNECT | FD_READ | FD_WRITE | FD_CLOSE) != 0)
|
||||
{
|
||||
closesocket(peer->sock);
|
||||
@ -2589,7 +2630,19 @@ void DirectPlay8Peer::handle_host_connect_request(std::unique_lock<std::mutex> &
|
||||
connect_host_ok.append_dword(host_player_id);
|
||||
connect_host_ok.append_dword(peer->player_id);
|
||||
|
||||
connect_host_ok.append_dword(0); /* TODO: Other peers */
|
||||
connect_host_ok.append_dword(player_to_peer_id.size() - 1);
|
||||
|
||||
for(auto pi = peers.begin(); pi != peers.end(); ++pi)
|
||||
{
|
||||
Peer *pip = pi->second;
|
||||
|
||||
if(pip != peer && pip->state == Peer::PS_CONNECTED)
|
||||
{
|
||||
connect_host_ok.append_dword(pip->player_id);
|
||||
connect_host_ok.append_dword(pip->ip);
|
||||
connect_host_ok.append_dword(pip->port);
|
||||
}
|
||||
}
|
||||
|
||||
if(ic.dwReplyDataSize > 0)
|
||||
{
|
||||
@ -2674,12 +2727,10 @@ void DirectPlay8Peer::handle_host_connect_ok(std::unique_lock<std::mutex> &l, un
|
||||
|
||||
for(DWORD n = 0; n < n_other_peers; ++n)
|
||||
{
|
||||
DPNID player_id = pd.get_dword(4 + (n * 3));
|
||||
uint32_t player_ipaddr = pd.get_dword(5 + (n * 3));
|
||||
uint16_t player_port = pd.get_dword(6 + (n * 3));
|
||||
|
||||
/* TODO: Setup connections to other peers. */
|
||||
abort();
|
||||
/* Spinning through the loop so we blow up early if malformed. */
|
||||
pd.get_dword(4 + (n * 3));
|
||||
pd.get_dword(5 + (n * 3));
|
||||
pd.get_dword(6 + (n * 3));
|
||||
}
|
||||
|
||||
int after_peers_base = 4 + (n_other_peers * 3);
|
||||
@ -2755,6 +2806,19 @@ void DirectPlay8Peer::handle_host_connect_ok(std::unique_lock<std::mutex> &l, un
|
||||
peer->player_ctx = cp.pvPlayerContext;
|
||||
}
|
||||
|
||||
for(DWORD n = 0; n < n_other_peers; ++n)
|
||||
{
|
||||
DPNID player_id = pd.get_dword(4 + (n * 3));
|
||||
uint32_t player_ipaddr = pd.get_dword(5 + (n * 3));
|
||||
uint16_t player_port = pd.get_dword(6 + (n * 3));
|
||||
|
||||
if(!peer_connect(Peer::PS_CONNECTING_PEER, player_ipaddr, player_port, player_id))
|
||||
{
|
||||
connect_fail(l, DPNERR_PLAYERNOTREACHABLE, NULL, 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
connect_check(l);
|
||||
}
|
||||
|
||||
@ -2799,6 +2863,179 @@ void DirectPlay8Peer::handle_host_connect_fail(std::unique_lock<std::mutex> &l,
|
||||
connect_fail(l, hResultCode, pvApplicationReplyData, dwApplicationReplyDataSize);
|
||||
}
|
||||
|
||||
void DirectPlay8Peer::handle_connect_peer(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);
|
||||
|
||||
if(peer->state != Peer::PS_ACCEPTED)
|
||||
{
|
||||
log_printf("Received unexpected DPLITE_MSGID_CONNECT_PEER from peer %u, in state %u",
|
||||
peer_id, (unsigned)(peer->state));
|
||||
return;
|
||||
}
|
||||
|
||||
auto send_fail = [&peer](DWORD error)
|
||||
{
|
||||
PacketSerialiser connect_peer_fail(DPLITE_MSGID_CONNECT_PEER_FAIL);
|
||||
connect_peer_fail.append_dword(error);
|
||||
|
||||
peer->sq.send(SendQueue::SEND_PRI_HIGH,
|
||||
connect_peer_fail,
|
||||
NULL,
|
||||
[](std::unique_lock<std::mutex> &l, HRESULT result) {});
|
||||
};
|
||||
|
||||
if(state != STATE_CONNECTED)
|
||||
{
|
||||
send_fail(DPNERR_GENERIC);
|
||||
return;
|
||||
}
|
||||
|
||||
if(pd.get_guid(0) != instance_guid)
|
||||
{
|
||||
send_fail(DPNERR_INVALIDINSTANCE);
|
||||
return;
|
||||
}
|
||||
|
||||
if(pd.get_guid(1) != application_guid)
|
||||
{
|
||||
send_fail(DPNERR_INVALIDAPPLICATION);
|
||||
return;
|
||||
}
|
||||
|
||||
if(pd.get_wstring(2) != password)
|
||||
{
|
||||
send_fail(DPNERR_INVALIDPASSWORD);
|
||||
return;
|
||||
}
|
||||
|
||||
peer->player_id = pd.get_dword(3);
|
||||
peer->player_name = pd.get_wstring(4);
|
||||
|
||||
peer->player_data.clear();
|
||||
|
||||
std::pair<const void*, size_t> player_data = pd.get_data(5);
|
||||
|
||||
peer->player_data.reserve(player_data.second);
|
||||
peer->player_data.insert(peer->player_data.end(),
|
||||
(const unsigned char*)(player_data.first),
|
||||
(const unsigned char*)(player_data.first) + player_data.second);
|
||||
|
||||
if(player_to_peer_id.find(peer->player_id) != player_to_peer_id.end())
|
||||
{
|
||||
log_printf("Rejected DPLITE_MSGID_CONNECT_PEER with already-known Player ID %u", (unsigned)(peer->player_id));
|
||||
|
||||
send_fail(DPNERR_ALREADYCONNECTED);
|
||||
return;
|
||||
}
|
||||
|
||||
player_to_peer_id[peer->player_id] = peer_id;
|
||||
|
||||
peer->state = Peer::PS_CONNECTED;
|
||||
|
||||
PacketSerialiser connect_peer_ok(DPLITE_MSGID_CONNECT_PEER_OK);
|
||||
connect_peer_ok.append_wstring(local_player_name);
|
||||
connect_peer_ok.append_data(local_player_data.data(), local_player_data.size());
|
||||
|
||||
peer->sq.send(SendQueue::SEND_PRI_HIGH,
|
||||
connect_peer_ok,
|
||||
NULL,
|
||||
[](std::unique_lock<std::mutex> &l, HRESULT result) {});
|
||||
|
||||
DPNMSG_CREATE_PLAYER cp;
|
||||
memset(&cp, 0, sizeof(cp));
|
||||
|
||||
cp.dwSize = sizeof(cp);
|
||||
cp.dpnidPlayer = peer->player_id;
|
||||
cp.pvPlayerContext = NULL;
|
||||
|
||||
l.unlock();
|
||||
message_handler(message_handler_ctx, DPN_MSGID_CREATE_PLAYER, &cp);
|
||||
l.lock();
|
||||
|
||||
RENEW_PEER_OR_RETURN();
|
||||
|
||||
peer->player_ctx = cp.pvPlayerContext;
|
||||
}
|
||||
|
||||
void DirectPlay8Peer::handle_connect_peer_ok(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);
|
||||
|
||||
if(peer->state != Peer::PS_REQUESTING_PEER)
|
||||
{
|
||||
/* TODO: LOG ME */
|
||||
return;
|
||||
}
|
||||
|
||||
assert(state == STATE_CONNECTING);
|
||||
|
||||
peer->player_name = pd.get_wstring(0);
|
||||
|
||||
peer->player_data.clear();
|
||||
|
||||
std::pair<const void*, size_t> player_data = pd.get_data(1);
|
||||
|
||||
peer->player_data.reserve(player_data.second);
|
||||
peer->player_data.insert(peer->player_data.end(),
|
||||
(const unsigned char*)(player_data.first),
|
||||
(const unsigned char*)(player_data.first) + player_data.second);
|
||||
|
||||
peer->state = Peer::PS_CONNECTED;
|
||||
|
||||
/* player_id initialised in handling of DPLITE_MSGID_CONNECT_HOST_OK. */
|
||||
player_to_peer_id[peer->player_id] = peer_id;
|
||||
|
||||
{
|
||||
DPNMSG_CREATE_PLAYER cp;
|
||||
memset(&cp, 0, sizeof(cp));
|
||||
|
||||
cp.dwSize = sizeof(cp);
|
||||
cp.dpnidPlayer = peer->player_id;
|
||||
cp.pvPlayerContext = NULL;
|
||||
|
||||
l.unlock();
|
||||
message_handler(message_handler_ctx, DPN_MSGID_CREATE_PLAYER, &cp);
|
||||
l.lock();
|
||||
|
||||
RENEW_PEER_OR_RETURN();
|
||||
|
||||
peer->player_ctx = cp.pvPlayerContext;
|
||||
}
|
||||
|
||||
connect_check(l);
|
||||
}
|
||||
|
||||
void DirectPlay8Peer::handle_connect_peer_fail(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);
|
||||
|
||||
if(peer->state != Peer::PS_REQUESTING_PEER)
|
||||
{
|
||||
log_printf("Received unexpected DPLITE_MSGID_CONNECT_PEER_FAIL from peer %u, in state %u",
|
||||
peer_id, (unsigned)(peer->state));
|
||||
return;
|
||||
}
|
||||
|
||||
assert(state == STATE_CONNECTING);
|
||||
|
||||
DWORD hResultCode = DPNERR_GENERIC;
|
||||
|
||||
try {
|
||||
hResultCode = pd.get_dword(0);
|
||||
}
|
||||
catch(const PacketDeserialiser::Error &e)
|
||||
{
|
||||
log_printf("Received invalid DPLITE_MSGID_CONNECT_PEER_FAIL from peer %u: %s",
|
||||
peer_id, e.what());
|
||||
}
|
||||
|
||||
connect_fail(l, DPNERR_PLAYERNOTREACHABLE, NULL, 0);
|
||||
}
|
||||
|
||||
void DirectPlay8Peer::handle_message(std::unique_lock<std::mutex> &l, const PacketDeserialiser &pd)
|
||||
{
|
||||
try {
|
||||
|
@ -182,7 +182,7 @@ class DirectPlay8Peer: public IDirectPlay8Peer
|
||||
void io_peer_recv(std::unique_lock<std::mutex> &l, unsigned int peer_id);
|
||||
|
||||
void peer_accept(std::unique_lock<std::mutex> &l);
|
||||
bool peer_connect(Peer::PeerState initial_state, uint32_t remote_ip, uint16_t remote_port);
|
||||
bool peer_connect(Peer::PeerState initial_state, uint32_t remote_ip, uint16_t remote_port, DPNID player_id = 0);
|
||||
void peer_destroy(std::unique_lock<std::mutex> &l, unsigned int peer_id, HRESULT outstanding_op_result);
|
||||
|
||||
void close_everything_now(std::unique_lock<std::mutex> &l);
|
||||
@ -191,6 +191,9 @@ class DirectPlay8Peer: public IDirectPlay8Peer
|
||||
void handle_host_connect_request(std::unique_lock<std::mutex> &l, unsigned int peer_id, const PacketDeserialiser &pd);
|
||||
void handle_host_connect_ok(std::unique_lock<std::mutex> &l, unsigned int peer_id, const PacketDeserialiser &pd);
|
||||
void handle_host_connect_fail(std::unique_lock<std::mutex> &l, unsigned int peer_id, const PacketDeserialiser &pd);
|
||||
void handle_connect_peer(std::unique_lock<std::mutex> &l, unsigned int peer_id, const PacketDeserialiser &pd);
|
||||
void handle_connect_peer_ok(std::unique_lock<std::mutex> &l, unsigned int peer_id, const PacketDeserialiser &pd);
|
||||
void handle_connect_peer_fail(std::unique_lock<std::mutex> &l, unsigned int peer_id, 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_ack(std::unique_lock<std::mutex> &l, unsigned int peer_id, const PacketDeserialiser &pd);
|
||||
|
@ -107,4 +107,32 @@
|
||||
* DATA - DPN_APPLICATION_DESC.pvApplicationReservedData
|
||||
*/
|
||||
|
||||
#define DPLITE_MSGID_CONNECT_PEER 10
|
||||
|
||||
/* Initial connect request to a follow non-host peer.
|
||||
*
|
||||
* GUID - Instance GUID
|
||||
* GUID - Application GUID
|
||||
* WSTRING - Password
|
||||
* DWORD - Player ID
|
||||
* WSTRING - Player name (empty = none)
|
||||
* DATA - Player data (empty = none)
|
||||
*/
|
||||
|
||||
#define DPLITE_MSGID_CONNECT_PEER_OK 11
|
||||
|
||||
/* Successful response to DPLITE_MSGID_CONNECT_PEER.
|
||||
*
|
||||
* WSTRING - Player name (empty = none)
|
||||
* DATA - Player data (empty = none)
|
||||
*/
|
||||
|
||||
#define DPLITE_MSGID_CONNECT_PEER_FAIL 12
|
||||
|
||||
/* Negative response to DPLITE_MSGID_CONNECT_PEER.
|
||||
* Peer will close the connection after sending this.
|
||||
*
|
||||
* DWORD - Error code (DPNERR_HOSTREJECTEDCONNECTION, DPNERR_INVALIDAPPLICATION, etc)
|
||||
*/
|
||||
|
||||
#endif /* !DPLITE_MESSAGES_HPP */
|
||||
|
@ -1,6 +1,8 @@
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "network.hpp"
|
||||
|
||||
|
@ -1929,6 +1929,377 @@ TEST(DirectPlay8Peer, ConnectToIPX)
|
||||
EXPECT_EQ(p1_cc_dpnidLocal, p1_player_id);
|
||||
}
|
||||
|
||||
TEST(DirectPlay8Peer, ConnectTwoPeersToHost)
|
||||
{
|
||||
std::atomic<bool> testing(true);
|
||||
|
||||
std::atomic<int> host_seq(0), p1_seq(0), p2_seq(0);
|
||||
DPNID host_player_id = -1, p1_player_id = -1, p2_player_id = -1;
|
||||
|
||||
SessionHost host(APP_GUID_1, L"Session 1", PORT,
|
||||
[&testing, &host_seq, &host_player_id, &p1_player_id, &p2_player_id]
|
||||
(DWORD dwMessageType, PVOID pMessage)
|
||||
{
|
||||
if(!testing)
|
||||
{
|
||||
return DPN_OK;
|
||||
}
|
||||
|
||||
int seq = ++host_seq;
|
||||
|
||||
switch(seq)
|
||||
{
|
||||
case 1:
|
||||
EXPECT_EQ(dwMessageType, DPN_MSGID_CREATE_PLAYER);
|
||||
|
||||
if(dwMessageType == DPN_MSGID_CREATE_PLAYER)
|
||||
{
|
||||
DPNMSG_CREATE_PLAYER *cp = (DPNMSG_CREATE_PLAYER*)(pMessage);
|
||||
host_player_id = cp->dpnidPlayer;
|
||||
|
||||
EXPECT_EQ(cp->dwSize, sizeof(DPNMSG_CREATE_PLAYER));
|
||||
EXPECT_EQ(cp->pvPlayerContext, (void*)(0xB00));
|
||||
|
||||
cp->pvPlayerContext = (void*)(0xB00B00);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 2:
|
||||
EXPECT_EQ(dwMessageType, DPN_MSGID_INDICATE_CONNECT);
|
||||
|
||||
if(dwMessageType == DPN_MSGID_INDICATE_CONNECT)
|
||||
{
|
||||
DPNMSG_INDICATE_CONNECT *ic = (DPNMSG_INDICATE_CONNECT*)(pMessage);
|
||||
|
||||
EXPECT_EQ(ic->dwSize, sizeof(DPNMSG_INDICATE_CONNECT));
|
||||
|
||||
EXPECT_EQ(ic->pvUserConnectData, (void*)(NULL));
|
||||
EXPECT_EQ(ic->dwUserConnectDataSize, 0);
|
||||
|
||||
EXPECT_EQ(ic->pvReplyData, (void*)(NULL));
|
||||
EXPECT_EQ(ic->dwReplyDataSize, 0);
|
||||
|
||||
EXPECT_EQ(ic->pvReplyContext, (void*)(NULL));
|
||||
EXPECT_EQ(ic->pvPlayerContext, (void*)(NULL));
|
||||
|
||||
/* TODO: Check pAddressPlayer, pAddressDevice */
|
||||
|
||||
ic->pvPlayerContext = (void*)(0xB441);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 3:
|
||||
EXPECT_EQ(dwMessageType, DPN_MSGID_CREATE_PLAYER);
|
||||
|
||||
if(dwMessageType == DPN_MSGID_CREATE_PLAYER)
|
||||
{
|
||||
DPNMSG_CREATE_PLAYER *cp = (DPNMSG_CREATE_PLAYER*)(pMessage);
|
||||
p1_player_id = cp->dpnidPlayer;
|
||||
|
||||
EXPECT_EQ(cp->dwSize, sizeof(DPNMSG_CREATE_PLAYER));
|
||||
EXPECT_EQ(cp->pvPlayerContext, (void*)(0xB441));
|
||||
|
||||
cp->pvPlayerContext = (void*)(0xFEED);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 4:
|
||||
EXPECT_EQ(dwMessageType, DPN_MSGID_INDICATE_CONNECT);
|
||||
|
||||
if(dwMessageType == DPN_MSGID_INDICATE_CONNECT)
|
||||
{
|
||||
DPNMSG_INDICATE_CONNECT *ic = (DPNMSG_INDICATE_CONNECT*)(pMessage);
|
||||
|
||||
EXPECT_EQ(ic->dwSize, sizeof(DPNMSG_INDICATE_CONNECT));
|
||||
|
||||
EXPECT_EQ(ic->pvUserConnectData, (void*)(NULL));
|
||||
EXPECT_EQ(ic->dwUserConnectDataSize, 0);
|
||||
|
||||
EXPECT_EQ(ic->pvReplyData, (void*)(NULL));
|
||||
EXPECT_EQ(ic->dwReplyDataSize, 0);
|
||||
|
||||
EXPECT_EQ(ic->pvReplyContext, (void*)(NULL));
|
||||
EXPECT_EQ(ic->pvPlayerContext, (void*)(NULL));
|
||||
|
||||
/* TODO: Check pAddressPlayer, pAddressDevice */
|
||||
|
||||
ic->pvPlayerContext = (void*)(0xB442);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 5:
|
||||
EXPECT_EQ(dwMessageType, DPN_MSGID_CREATE_PLAYER);
|
||||
|
||||
if(dwMessageType == DPN_MSGID_CREATE_PLAYER)
|
||||
{
|
||||
DPNMSG_CREATE_PLAYER *cp = (DPNMSG_CREATE_PLAYER*)(pMessage);
|
||||
p2_player_id = cp->dpnidPlayer;
|
||||
|
||||
EXPECT_EQ(cp->dwSize, sizeof(DPNMSG_CREATE_PLAYER));
|
||||
EXPECT_EQ(cp->pvPlayerContext, (void*)(0xB442));
|
||||
|
||||
cp->pvPlayerContext = (void*)(0xFEEE);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
ADD_FAILURE() << "Unexpected message of type " << dwMessageType <<", sequence " << seq;
|
||||
break;
|
||||
}
|
||||
|
||||
return DPN_OK;
|
||||
});
|
||||
|
||||
Sleep(1000);
|
||||
|
||||
DPNID p1_cp1_dpnidPlayer = -1, p1_cc_dpnidLocal = -1, p1_cp2_dpnidPlayer = -1;
|
||||
|
||||
std::function<HRESULT(DWORD,PVOID)> p1_cb =
|
||||
[&testing, &p1_seq, &host_player_id, &p1_player_id, &p1_cp1_dpnidPlayer, &p1_cc_dpnidLocal, &p1_cp2_dpnidPlayer]
|
||||
(DWORD dwMessageType, PVOID pMessage)
|
||||
{
|
||||
if(!testing)
|
||||
{
|
||||
return DPN_OK;
|
||||
}
|
||||
|
||||
int seq = ++p1_seq;
|
||||
|
||||
switch(seq)
|
||||
{
|
||||
case 1:
|
||||
EXPECT_EQ(dwMessageType, DPN_MSGID_CREATE_PLAYER);
|
||||
|
||||
if(dwMessageType == DPN_MSGID_CREATE_PLAYER)
|
||||
{
|
||||
DPNMSG_CREATE_PLAYER *cp = (DPNMSG_CREATE_PLAYER*)(pMessage);
|
||||
p1_cp1_dpnidPlayer = cp->dpnidPlayer;
|
||||
|
||||
EXPECT_EQ(cp->dwSize, sizeof(DPNMSG_CREATE_PLAYER));
|
||||
EXPECT_EQ(cp->pvPlayerContext, (void*)(0xBCDE));
|
||||
|
||||
cp->pvPlayerContext = (void*)(0xCDEF);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 2:
|
||||
EXPECT_EQ(dwMessageType, DPN_MSGID_CREATE_PLAYER);
|
||||
|
||||
if(dwMessageType == DPN_MSGID_CREATE_PLAYER)
|
||||
{
|
||||
DPNMSG_CREATE_PLAYER *cp = (DPNMSG_CREATE_PLAYER*)(pMessage);
|
||||
|
||||
EXPECT_EQ(cp->dwSize, sizeof(DPNMSG_CREATE_PLAYER));
|
||||
EXPECT_EQ(cp->dpnidPlayer, host_player_id);
|
||||
EXPECT_EQ(cp->pvPlayerContext, (void*)(0));
|
||||
|
||||
cp->pvPlayerContext = (void*)(0xBAA);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 3:
|
||||
EXPECT_EQ(dwMessageType, DPN_MSGID_CONNECT_COMPLETE);
|
||||
|
||||
if(dwMessageType == DPN_MSGID_CONNECT_COMPLETE)
|
||||
{
|
||||
DPNMSG_CONNECT_COMPLETE *cc = (DPNMSG_CONNECT_COMPLETE*)(pMessage);
|
||||
|
||||
EXPECT_EQ(cc->dwSize, sizeof(DPNMSG_CONNECT_COMPLETE));
|
||||
EXPECT_EQ(cc->hAsyncOp, 0);
|
||||
EXPECT_EQ(cc->hResultCode, S_OK);
|
||||
|
||||
EXPECT_EQ(cc->pvApplicationReplyData, (PVOID)(NULL));
|
||||
EXPECT_EQ(cc->dwApplicationReplyDataSize, 0);
|
||||
|
||||
p1_cc_dpnidLocal = cc->dpnidLocal;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 4:
|
||||
EXPECT_EQ(dwMessageType, DPN_MSGID_CREATE_PLAYER);
|
||||
|
||||
if(dwMessageType == DPN_MSGID_CREATE_PLAYER)
|
||||
{
|
||||
DPNMSG_CREATE_PLAYER *cp = (DPNMSG_CREATE_PLAYER*)(pMessage);
|
||||
p1_cp2_dpnidPlayer = cp->dpnidPlayer;
|
||||
|
||||
EXPECT_EQ(cp->dwSize, sizeof(DPNMSG_CREATE_PLAYER));
|
||||
EXPECT_EQ(cp->pvPlayerContext, (void*)(0));
|
||||
|
||||
cp->pvPlayerContext = (void*)(0xBAB);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
ADD_FAILURE() << "Unexpected message of type " << dwMessageType <<", sequence " << seq;
|
||||
break;
|
||||
}
|
||||
|
||||
return DPN_OK;
|
||||
};
|
||||
|
||||
IDP8PeerInstance p1;
|
||||
|
||||
ASSERT_EQ(p1->Initialize(&p1_cb, &callback_shim, 0), S_OK);
|
||||
|
||||
DPN_APPLICATION_DESC connect_to_app;
|
||||
memset(&connect_to_app, 0, sizeof(connect_to_app));
|
||||
|
||||
connect_to_app.dwSize = sizeof(connect_to_app);
|
||||
connect_to_app.guidApplication = APP_GUID_1;
|
||||
|
||||
IDP8AddressInstance connect_to_addr(L"127.0.0.1", PORT);
|
||||
|
||||
EXPECT_EQ(p1->Connect(
|
||||
&connect_to_app, /* pdnAppDesc */
|
||||
connect_to_addr, /* pHostAddr */
|
||||
NULL, /* pDeviceInfo */
|
||||
NULL, /* pdnSecurity */
|
||||
NULL, /* pdnCredentials */
|
||||
NULL, /* pvUserConnectData */
|
||||
0, /* dwUserConnectDataSize */
|
||||
(void*)(0xBCDE), /* pvPlayerContext */
|
||||
NULL, /* pvAsyncContext */
|
||||
NULL, /* phAsyncHandle */
|
||||
DPNCONNECT_SYNC /* dwFlags */
|
||||
), S_OK);
|
||||
|
||||
Sleep(1000);
|
||||
|
||||
DPNID p2_cp1_dpnidPlayer = -1, p2_cc_dpnidLocal = -1, p2_cp2_dpnidPlayer = -1;
|
||||
|
||||
std::function<HRESULT(DWORD,PVOID)> p2_cb =
|
||||
[&testing, &p2_seq, &host_player_id, &p2_cp1_dpnidPlayer, &p2_cc_dpnidLocal, &p2_cp2_dpnidPlayer]
|
||||
(DWORD dwMessageType, PVOID pMessage)
|
||||
{
|
||||
if(!testing)
|
||||
{
|
||||
return DPN_OK;
|
||||
}
|
||||
|
||||
int seq = ++p2_seq;
|
||||
|
||||
switch(seq)
|
||||
{
|
||||
case 1:
|
||||
EXPECT_EQ(dwMessageType, DPN_MSGID_CREATE_PLAYER);
|
||||
|
||||
if(dwMessageType == DPN_MSGID_CREATE_PLAYER)
|
||||
{
|
||||
DPNMSG_CREATE_PLAYER *cp = (DPNMSG_CREATE_PLAYER*)(pMessage);
|
||||
p2_cp1_dpnidPlayer = cp->dpnidPlayer;
|
||||
|
||||
EXPECT_EQ(cp->dwSize, sizeof(DPNMSG_CREATE_PLAYER));
|
||||
EXPECT_EQ(cp->pvPlayerContext, (void*)(0xCDEF));
|
||||
|
||||
cp->pvPlayerContext = (void*)(0xCDEF);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 2:
|
||||
EXPECT_EQ(dwMessageType, DPN_MSGID_CREATE_PLAYER);
|
||||
|
||||
if(dwMessageType == DPN_MSGID_CREATE_PLAYER)
|
||||
{
|
||||
DPNMSG_CREATE_PLAYER *cp = (DPNMSG_CREATE_PLAYER*)(pMessage);
|
||||
|
||||
EXPECT_EQ(cp->dwSize, sizeof(DPNMSG_CREATE_PLAYER));
|
||||
EXPECT_EQ(cp->dpnidPlayer, host_player_id);
|
||||
EXPECT_EQ(cp->pvPlayerContext, (void*)(0));
|
||||
|
||||
cp->pvPlayerContext = (void*)(0xBAA);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 3:
|
||||
EXPECT_EQ(dwMessageType, DPN_MSGID_CREATE_PLAYER);
|
||||
|
||||
if(dwMessageType == DPN_MSGID_CREATE_PLAYER)
|
||||
{
|
||||
DPNMSG_CREATE_PLAYER *cp = (DPNMSG_CREATE_PLAYER*)(pMessage);
|
||||
p2_cp2_dpnidPlayer = cp->dpnidPlayer;
|
||||
|
||||
EXPECT_EQ(cp->dwSize, sizeof(DPNMSG_CREATE_PLAYER));
|
||||
EXPECT_EQ(cp->pvPlayerContext, (void*)(0));
|
||||
|
||||
cp->pvPlayerContext = (void*)(0xBAB);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 4:
|
||||
EXPECT_EQ(dwMessageType, DPN_MSGID_CONNECT_COMPLETE);
|
||||
|
||||
if(dwMessageType == DPN_MSGID_CONNECT_COMPLETE)
|
||||
{
|
||||
DPNMSG_CONNECT_COMPLETE *cc = (DPNMSG_CONNECT_COMPLETE*)(pMessage);
|
||||
|
||||
EXPECT_EQ(cc->dwSize, sizeof(DPNMSG_CONNECT_COMPLETE));
|
||||
EXPECT_EQ(cc->hAsyncOp, 0);
|
||||
EXPECT_EQ(cc->hResultCode, S_OK);
|
||||
|
||||
EXPECT_EQ(cc->pvApplicationReplyData, (PVOID)(NULL));
|
||||
EXPECT_EQ(cc->dwApplicationReplyDataSize, 0);
|
||||
|
||||
p2_cc_dpnidLocal = cc->dpnidLocal;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
ADD_FAILURE() << "Unexpected message of type " << dwMessageType <<", sequence " << seq;
|
||||
break;
|
||||
}
|
||||
|
||||
return DPN_OK;
|
||||
};
|
||||
|
||||
IDP8PeerInstance p2;
|
||||
|
||||
ASSERT_EQ(p2->Initialize(&p2_cb, &callback_shim, 0), S_OK);
|
||||
|
||||
EXPECT_EQ(p2->Connect(
|
||||
&connect_to_app, /* pdnAppDesc */
|
||||
connect_to_addr, /* pHostAddr */
|
||||
NULL, /* pDeviceInfo */
|
||||
NULL, /* pdnSecurity */
|
||||
NULL, /* pdnCredentials */
|
||||
NULL, /* pvUserConnectData */
|
||||
0, /* dwUserConnectDataSize */
|
||||
(void*)(0xCDEF), /* pvPlayerContext */
|
||||
NULL, /* pvAsyncContext */
|
||||
NULL, /* phAsyncHandle */
|
||||
DPNCONNECT_SYNC /* dwFlags */
|
||||
), S_OK);
|
||||
|
||||
Sleep(1000);
|
||||
|
||||
testing = false;
|
||||
|
||||
EXPECT_EQ(host_seq, 5);
|
||||
EXPECT_EQ(p1_seq, 4);
|
||||
EXPECT_EQ(p2_seq, 4);
|
||||
|
||||
EXPECT_EQ(p1_cp1_dpnidPlayer, p1_player_id);
|
||||
EXPECT_EQ(p1_cc_dpnidLocal, p1_player_id);
|
||||
EXPECT_EQ(p1_cp2_dpnidPlayer, p2_player_id);
|
||||
|
||||
EXPECT_EQ(p2_cp1_dpnidPlayer, p2_player_id);
|
||||
EXPECT_EQ(p2_cc_dpnidLocal, p2_player_id);
|
||||
EXPECT_EQ(p2_cp2_dpnidPlayer, p1_player_id);
|
||||
}
|
||||
|
||||
TEST(DirectPlay8Peer, GetApplicationDesc)
|
||||
{
|
||||
const unsigned char APP_DATA[] = { 0x00, 0x01, 0x02, 0x03, 0x04 };
|
||||
|
Loading…
x
Reference in New Issue
Block a user