OpenClonk
C4Network2Discover.cpp
Go to the documentation of this file.
1 /*
2  * OpenClonk, http://www.openclonk.org
3  *
4  * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/
5  * Copyright (c) 2013-2016, The OpenClonk Team and contributors
6  *
7  * Distributed under the terms of the ISC license; see accompanying file
8  * "COPYING" for details.
9  *
10  * "Clonk" is a registered trademark of Matthes Bender, used with permission.
11  * See accompanying file "TRADEMARK" for details.
12  *
13  * To redistribute this file separately, substitute the full license texts
14  * for the above references.
15  */
16 #include "C4Include.h"
18 
19 // *** C4Network2IODiscover
20 //
21 // Quick multicast discovery guide by Luchs:
22 //
23 // All engines in network mode join a multicast group (defined by C4NetDiscoveryAddress).
24 //
25 // Engines searching for a game ("client") send a single byte c = 3 to that multicast group. This
26 // happens while on the network list on each refresh.
27 //
28 // Engines hosting a game (when going into the lobby) send a byte c = 4 plus their reference server
29 // port to the multicast group. Additionally, they listen for the c = 3 bytes and will reply with
30 // another multicast answer.
31 
33 {
34  char c;
35  uint16_t Port;
36 };
37 
38 void C4Network2IODiscover::OnPacket(const class C4NetIOPacket &rPacket, C4NetIO *pNetIO)
39 {
40  // discovery?
41  if (fEnabled && rPacket.getSize() == 1 && rPacket.getStatus() == 3)
42  Announce();
43 }
44 
45 bool C4Network2IODiscover::Init(uint16_t iPort)
46 {
47  // Reuse address
49  // Regular init (bind to port)
50  if (!C4NetIOSimpleUDP::Init(iPort))
51  return false;
52  // Set callback
54  // Build broadcast address
55  DiscoveryAddr.SetAddress(C4NetDiscoveryAddress);
56  DiscoveryAddr.SetPort(iPort);
57  // Initialize broadcast
58  if (!C4NetIOSimpleUDP::InitBroadcast(&DiscoveryAddr))
59  return false;
60  // Enable multicast loopback
62 }
63 
65 {
66  // Announce our presence
67  C4Network2IODiscoverReply Reply = { 4, iRefServerPort };
68  return Send(C4NetIOPacket(&Reply, sizeof(Reply), false, DiscoveryAddr));
69 }
70 
71 // *** C4Network2IODiscoverClient
72 
73 void C4Network2IODiscoverClient::OnPacket(const class C4NetIOPacket &rPacket, C4NetIO *pNetIO)
74 {
75  // discovery?
76  if (rPacket.getSize() == sizeof(C4Network2IODiscoverReply) && rPacket.getStatus() == 4)
77  {
78  // save discovered address
79  if (iDiscoverCount < C4NetMaxDiscover)
80  {
81  const C4Network2IODiscoverReply *pReply = reinterpret_cast<const C4Network2IODiscoverReply *>(rPacket.getData());
82  Discovers[iDiscoverCount] = rPacket.getAddr();
83  Discovers[iDiscoverCount].SetPort(pReply->Port);
84  iDiscoverCount++;
85  }
86  }
87 }
88 
90 {
91  // Reuse address
93  // Bind to port
94  if (!C4NetIOSimpleUDP::Init(iPort))
95  return false;
96  // Set callback
98  // Build broadcast address
99  DiscoveryAddr.SetAddress(C4NetDiscoveryAddress);
100  DiscoveryAddr.SetPort(iPort);
101  // Initialize broadcast
102  if (!C4NetIOSimpleUDP::InitBroadcast(&DiscoveryAddr))
103  return false;
104  // Enable multicast loopback
105  return C4NetIOSimpleUDP::SetMCLoopback(true);
106 }
107 
109 {
110  // Multicast discovery byte
111  char c = 3;
112  return Send(C4NetIOPacket(&c, sizeof(c), false, DiscoveryAddr));
113 }
114 
116 {
117  // Discovers left?
118  if (!getDiscoverCount())
119  return false;
120  // Return one
121  Discover = Discovers[--iDiscoverCount];
122  return true;
123 }
const StdStrBuf C4NetDiscoveryAddress
const int C4NetMaxDiscover
const C4NetIO::addr_t & getAddr() const
Definition: C4NetIO.h:317
uint8_t getStatus() const
Definition: C4NetIO.h:319
bool Init(uint16_t iPort=addr_t::IPPORT_NONE) override
Definition: C4NetIO.cpp:1898
bool Send(const C4NetIOPacket &rPacket) override
Definition: C4NetIO.cpp:2180
bool SetMCLoopback(int fLoopback)
Definition: C4NetIO.cpp:2290
void SetCallback(CBClass *pnCallback) override
Definition: C4NetIO.h:590
void SetReUseAddress(bool fAllow)
Definition: C4NetIO.cpp:2302
virtual bool InitBroadcast(addr_t *pBroadcastAddr)
Definition: C4NetIO.cpp:1986
void OnPacket(const class C4NetIOPacket &rPacket, C4NetIO *pNetIO) override
bool PopDiscover(C4NetIO::addr_t &Discover)
bool Init(uint16_t iPort=C4NetIO::addr_t::IPPORT_NONE) override
void OnPacket(const class C4NetIOPacket &rPacket, C4NetIO *pNetIO) override
bool Init(uint16_t iPort=C4NetIO::addr_t::IPPORT_NONE) override
size_t getSize() const
Definition: StdBuf.h:101
const void * getData() const
Definition: StdBuf.h:99
void SetAddress(const sockaddr *addr)
Definition: C4NetIO.cpp:364
void SetPort(uint16_t port)
Definition: C4NetIO.cpp:531