Skip to content

Commit

Permalink
send the players mask with the JoinAccept packet and connect the play…
Browse files Browse the repository at this point in the history
…ers explicitly when using tcp
  • Loading branch information
pionere committed Nov 18, 2023
1 parent 4c1b708 commit 0fd8e8f
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 24 deletions.
16 changes: 11 additions & 5 deletions Source/dvlnet/base_client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,10 @@ void base_client::disconnect_net(plr_t pnum)

void base_client::recv_connect(packet& pkt)
{
// connected_table[pkt.pktConnectPlr()] = CON_CONNECTED; // this can probably be removed
plr_t pkt_src = pkt.pktSrc();

if (pkt_src < MAX_PLRS)
connected_table[pkt_src] = CON_CONNECTED;
}

void base_client::recv_accept(packet& pkt)
Expand All @@ -63,7 +66,13 @@ void base_client::recv_accept(packet& pkt)
plr_self = PLR_BROADCAST;
return;
}
connected_table[plr_self] = CON_CONNECTED;
plr_t pmask = pkt.pktJoinAccMsk();
// assert(pmask & (1 << plr_self));
for (int i = 0; i < MAX_PLRS; i++) {
if (pmask & (1 << i)) {
connected_table[i] = CON_CONNECTED;
}
}
#ifdef ZEROTIER
// we joined and did not create
game_init_info = buffer_t((BYTE*)&pkt_info, (BYTE*)&pkt_info + sizeof(SNetGameData));
Expand Down Expand Up @@ -120,9 +129,6 @@ void base_client::recv_local(packet& pkt)
// FIXME: the server could still impersonate a player...
plr_t pkt_plr = pkt.pktSrc();

if (pkt_plr < MAX_PLRS) {
connected_table[pkt_plr] |= CON_CONNECTED;
}
switch (pkt.pktType()) {
case PT_MESSAGE:
net_assert(pkt_plr < MAX_PLRS || pkt_plr == SNPLAYER_MASTER);
Expand Down
38 changes: 27 additions & 11 deletions Source/dvlnet/base_protocol.h
Original file line number Diff line number Diff line change
Expand Up @@ -209,27 +209,43 @@ void base_protocol<P>::poll()
template <class P>
void base_protocol<P>::handle_join_request(packet& pkt, endpoint sender)
{
plr_t i;
for (i = 0; i < MAX_PLRS; i++) {
if (i != plr_self && !peers[i]) {
peers[i] = sender;
plr_t i, pnum, pmask;
packet* reply;

for (pnum = 0; pnum < MAX_PLRS; pnum++) {
if (pnum != plr_self && !peers[pnum]) {
peers[pnum] = sender;
break;
}
}
if (i >= MAX_PLRS) {
if (pnum >= MAX_PLRS) {
//already full
return;
}
for (plr_t j = 0; j < MAX_PLRS; j++) {
if ((j != plr_self) && (j != i) && peers[j]) {
packet* infopkt = pktfty.make_out_packet<PT_CONNECT>(PLR_MASTER, PLR_BROADCAST, j, buffer_t(peers[j].addr.begin(), peers[j].addr.end()));
proto.send(sender, infopkt->encrypted_data());
delete infopkt;
// reply to the new player
pmask = 0;
for (i = 0; i < MAX_PLRS; i++) {
if (peers[i]) {
static_assert(sizeof(pmask) * 8 >= MAX_PLRS, "handle_join_request can not send the active connections to the client.");
pmask |= 1 << i;
}
}
packet* reply = pktfty.make_out_packet<PT_JOIN_ACCEPT>(plr_self, PLR_BROADCAST, pkt.pktJoinReqCookie(), i, game_init_info);
reply = pktfty.make_out_packet<PT_JOIN_ACCEPT>(plr_self, PLR_BROADCAST, pkt.pktJoinReqCookie(), pnum, game_init_info, pmask);
proto.send(sender, reply->encrypted_data());
delete reply;
// notify the old players
reply = pktfty.make_out_packet<PT_CONNECT>(pnum, PLR_BROADCAST, PLR_MASTER, buffer_t());
send_packet(*reply);
delete reply;
// send the addresses of the old players to the new player TODO: send with PT_JOIN_ACCEPT?
pmask &= ~((1 << pnum) | (1 << plr_self));
for (plr_t i = 0; i < MAX_PLRS; i++) {
if (pmask & (1 << i)) {
reply = pktfty.make_out_packet<PT_CONNECT>(PLR_MASTER, PLR_BROADCAST, i, buffer_t(peers[i].addr.begin(), peers[i].addr.end()));
proto.send(sender, reply->encrypted_data());
delete reply;
}
}
}

template <class P>
Expand Down
10 changes: 8 additions & 2 deletions Source/dvlnet/packet.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ enum packet_type : uint8_t {
PT_TURN,
PT_JOIN_REQUEST,
PT_JOIN_ACCEPT,
PT_CONNECT, // tcpd, zt-only
PT_CONNECT, // tcp, zt-only
PT_DISCONNECT,
PT_INFO_REQUEST, // zt-only
PT_INFO_REPLY, // zt-only
Expand Down Expand Up @@ -67,6 +67,7 @@ typedef struct NetPktJoinAccept {
cookie_t m_cookie;
plr_t m_newplr;
SNetGameData m_info;
plr_t m_plrmask;
} NetPktJoinAccept;

typedef struct NetPktConnect {
Expand Down Expand Up @@ -154,6 +155,10 @@ class packet {
{
return reinterpret_cast<NetPktJoinAccept*>(decrypted_buffer.data())->m_info;
}
plr_t pktJoinAccMsk() const
{
return reinterpret_cast<const NetPktJoinAccept*>(decrypted_buffer.data())->m_plrmask;
}
// PT_INFO_REPLY
buffer_t::const_iterator pktInfoReplyNameBegin() const
{
Expand Down Expand Up @@ -259,7 +264,7 @@ inline void packet_out::create<PT_JOIN_REQUEST>(plr_t s, plr_t d, cookie_t c)

template <>
inline void packet_out::create<PT_JOIN_ACCEPT>(plr_t s, plr_t d, cookie_t c,
plr_t n, buffer_t i)
plr_t n, buffer_t i, plr_t p)
{
decrypted_buffer.resize(sizeof(NetPktJoinAccept));
NetPktJoinAccept* data = (NetPktJoinAccept*)decrypted_buffer.data();
Expand All @@ -268,6 +273,7 @@ inline void packet_out::create<PT_JOIN_ACCEPT>(plr_t s, plr_t d, cookie_t c,
data->npHdr.m_dest = d;
data->m_cookie = c;
data->m_newplr = n;
data->m_plrmask = p;
memcpy(&data->m_info, i.data(), sizeof(SNetGameData));
}

Expand Down
27 changes: 21 additions & 6 deletions Source/dvlnet/tcp_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,8 @@ void tcp_server::handle_recv(const scc& con, const asio::error_code& ec, size_t

bool tcp_server::handle_recv_newplr(const scc& con, packet& pkt)
{
plr_t i, pnum;
plr_t i, pnum, pmask;
packet* reply;

if (pkt.pktType() != PT_JOIN_REQUEST) {
// DoLog("Invalid join packet.");
Expand All @@ -162,18 +163,32 @@ bool tcp_server::handle_recv_newplr(const scc& con, packet& pkt)
pending_connections[i] = NULL;
active_connections[pnum] = con;
con->pnum = pnum;
packet* reply = pktfty.make_out_packet<PT_JOIN_ACCEPT>(PLR_MASTER, PLR_BROADCAST, pkt.pktJoinReqCookie(), pnum, game_init_info);
// reply to the new player
pmask = 0;
for (i = 0; i < MAX_PLRS; i++) {
if (active_connections[i] != NULL) {
static_assert(sizeof(pmask) * 8 >= MAX_PLRS, "handle_recv_newplr can not send the active connections to the client.");
pmask |= 1 << i;
}
}
reply = pktfty.make_out_packet<PT_JOIN_ACCEPT>(PLR_MASTER, PLR_BROADCAST, pkt.pktJoinReqCookie(), pnum, game_init_info, pmask);
start_send(con, *reply);
delete reply;
// notify the old players
reply = pktfty.make_out_packet<PT_CONNECT>(pnum, PLR_BROADCAST, PLR_MASTER, buffer_t());
send_packet(*reply);
delete reply;
//send_connect(con);
// send the addresses of the old players to the new player TODO: send with PT_JOIN_ACCEPT?
if (serverType == SRV_DIRECT) {
pmask &= ~(1 << pnum);
std::string addr;
for (i = 0; i < MAX_PLRS; i++) {
if (active_connections[i] != NULL && active_connections[i] != con) {
if (pmask & (1 << i)) {
endpoint_to_string(active_connections[i], addr);
packet* oldConPkt = pktfty.make_out_packet<PT_CONNECT>(PLR_MASTER, PLR_BROADCAST, i, buffer_t(addr.begin(), addr.end()));
start_send(con, *oldConPkt);
delete oldConPkt;
reply = pktfty.make_out_packet<PT_CONNECT>(PLR_MASTER, PLR_BROADCAST, i, buffer_t(addr.begin(), addr.end()));
start_send(con, *reply);
delete reply;
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions Source/dvlnet/tcpd_client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,8 @@ plr_t tcpd_client::next_free_queue()

void tcpd_client::recv_connect(packet& pkt)
{
base_client::recv_connect(pkt);

plr_t pnum = pkt.pktConnectPlr();
if (pnum == plr_self || pnum >= MAX_PLRS || active_connections[pnum] != NULL)
return;
Expand Down

0 comments on commit 0fd8e8f

Please sign in to comment.