Fix wan connection, move get public address from stun to stk host
This commit is contained in:
parent
8daebe06e1
commit
1458f3ef8e
@ -1027,6 +1027,7 @@ int handleCmdLine()
|
||||
while (true)
|
||||
{
|
||||
Online::RequestManager::get()->update(0.0f);
|
||||
StkTime::sleep(1);
|
||||
if (PlayerManager::getCurrentOnlineState() == PlayerProfile::OS_SIGNED_IN)
|
||||
{
|
||||
break;
|
||||
@ -1074,9 +1075,6 @@ int handleCmdLine()
|
||||
if(CommandLine::has("--password", &s))
|
||||
password = s.c_str();
|
||||
|
||||
if (CommandLine::has("--my-address", &s))
|
||||
GetPublicAddress::setMyIPAddress(s);
|
||||
|
||||
/** Disable detection of LAN connection when connecting via WAN. This is
|
||||
* mostly a debugging feature to force using WAN connection. */
|
||||
if (CommandLine::has("--disable-lan"))
|
||||
|
@ -302,31 +302,32 @@ void MainLoop::run()
|
||||
->addNextTimeStep(World::getWorld()->getTime(), dt);
|
||||
}
|
||||
|
||||
if (!m_abort && !ProfileWorld::isNoGraphics())
|
||||
if (!m_abort)
|
||||
{
|
||||
float frame_duration = num_steps * dt;
|
||||
if (!ProfileWorld::isNoGraphics())
|
||||
{
|
||||
// Render the previous frame, and also handle all user input.
|
||||
PROFILER_PUSH_CPU_MARKER("IrrDriver update", 0x00, 0x00, 0x7F);
|
||||
irr_driver->update(frame_duration);
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
|
||||
// Render the previous frame, and also handle all user input.
|
||||
PROFILER_PUSH_CPU_MARKER("IrrDriver update", 0x00, 0x00, 0x7F);
|
||||
irr_driver->update(frame_duration);
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
|
||||
PROFILER_PUSH_CPU_MARKER("Input/GUI", 0x7F, 0x00, 0x00);
|
||||
#ifdef ENABLE_WIIUSE
|
||||
wiimote_manager->update();
|
||||
#endif
|
||||
input_manager->update(frame_duration);
|
||||
GUIEngine::update(frame_duration);
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
|
||||
PROFILER_PUSH_CPU_MARKER("Music", 0x7F, 0x00, 0x00);
|
||||
SFXManager::get()->update();
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
PROFILER_PUSH_CPU_MARKER("Input/GUI", 0x7F, 0x00, 0x00);
|
||||
#ifdef ENABLE_WIIUSE
|
||||
wiimote_manager->update();
|
||||
#endif
|
||||
input_manager->update(frame_duration);
|
||||
GUIEngine::update(frame_duration);
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
|
||||
PROFILER_PUSH_CPU_MARKER("Music", 0x7F, 0x00, 0x00);
|
||||
SFXManager::get()->update();
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
}
|
||||
// Some protocols in network will use RequestManager
|
||||
PROFILER_PUSH_CPU_MARKER("Database polling update", 0x00, 0x7F, 0x7F);
|
||||
Online::RequestManager::get()->update(frame_duration);
|
||||
PROFILER_POP_CPU_MARKER();
|
||||
|
||||
}
|
||||
|
||||
for(int i=0; i<num_steps; i++)
|
||||
|
@ -42,6 +42,7 @@ ConnectToPeer::ConnectToPeer(uint32_t peer_id) : Protocol(PROTOCOL_CONNECTION)
|
||||
m_state = NONE;
|
||||
m_is_lan = false;
|
||||
setHandleConnections(true);
|
||||
resetTimer();
|
||||
} // ConnectToPeer(peer_id)
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -54,7 +55,8 @@ ConnectToPeer::ConnectToPeer(const TransportAddress &address)
|
||||
m_peer_address.copy(address);
|
||||
// We don't need to find the peer address, so we can start
|
||||
// with the state when we found the peer address.
|
||||
m_state = RECEIVED_PEER_ADDRESS;
|
||||
m_state = WAIT_FOR_CONNECTION;
|
||||
resetTimer();
|
||||
m_is_lan = true;
|
||||
setHandleConnections(true);
|
||||
} // ConnectToPeers(TransportAddress)
|
||||
@ -66,14 +68,6 @@ ConnectToPeer::~ConnectToPeer()
|
||||
} // ~ConnectToPeer
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void ConnectToPeer::setup()
|
||||
{
|
||||
m_broadcast_count = 0;
|
||||
m_time_last_broadcast = 0;
|
||||
} // setup
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
bool ConnectToPeer::notifyEventAsynchronous(Event* event)
|
||||
{
|
||||
if (event->getType() == EVENT_TYPE_CONNECTED)
|
||||
@ -97,93 +91,81 @@ void ConnectToPeer::asynchronousUpdate()
|
||||
{
|
||||
case NONE:
|
||||
{
|
||||
m_current_protocol = std::make_shared<GetPeerAddress>(m_peer_id, this);
|
||||
m_current_protocol = std::make_shared<GetPeerAddress>(m_peer_id);
|
||||
m_current_protocol->requestStart();
|
||||
|
||||
// Pause this protocol till we receive an answer
|
||||
// The GetPeerAddress protocol will change the state and
|
||||
// unpause this protocol
|
||||
requestPause();
|
||||
m_state = RECEIVED_PEER_ADDRESS;
|
||||
break;
|
||||
}
|
||||
case RECEIVED_PEER_ADDRESS:
|
||||
{
|
||||
if (m_peer_address.getIP() == 0 || m_peer_address.getPort() == 0)
|
||||
// Wait until we have peer address
|
||||
auto get_peer_address =
|
||||
std::dynamic_pointer_cast<GetPeerAddress>(m_current_protocol);
|
||||
assert(get_peer_address);
|
||||
if (get_peer_address->getAddress().isUnset())
|
||||
return;
|
||||
m_peer_address.copy(get_peer_address->getAddress());
|
||||
m_current_protocol = nullptr;
|
||||
if (m_peer_address.isUnset())
|
||||
{
|
||||
Log::error("ConnectToPeer",
|
||||
"The peer you want to connect to has hidden his address.");
|
||||
m_state = DONE;
|
||||
break;
|
||||
}
|
||||
m_current_protocol = nullptr;
|
||||
|
||||
// Now we know the peer address. If it's a non-local host, start
|
||||
// the Ping protocol to keep the port available. We can't rely on
|
||||
// STKHost::isLAN(), since we might get a LAN connection even if
|
||||
// the server itself accepts connections from anywhere.
|
||||
if ( (!m_is_lan &&
|
||||
m_peer_address.getIP() !=
|
||||
NetworkConfig::get()->getMyAddress().getIP() ) ||
|
||||
NetworkConfig::m_disable_lan )
|
||||
{
|
||||
m_current_protocol = std::make_shared<PingProtocol>(m_peer_address,
|
||||
/*time-between-ping*/2.0);
|
||||
ProtocolManager::lock()->requestStart(m_current_protocol);
|
||||
m_state = CONNECTING;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_broadcast_count = 0;
|
||||
// Make sure we trigger the broadcast operation next
|
||||
m_time_last_broadcast = float(StkTime::getRealTime()-100.0f);
|
||||
m_state = WAIT_FOR_LAN;
|
||||
}
|
||||
m_state = WAIT_FOR_CONNECTION;
|
||||
resetTimer();
|
||||
break;
|
||||
}
|
||||
case WAIT_FOR_LAN:
|
||||
case WAIT_FOR_CONNECTION:
|
||||
{
|
||||
// Broadcast once per second
|
||||
if (StkTime::getRealTime() < m_time_last_broadcast + 1.0f)
|
||||
// Each 2 second for a ping or broadcast
|
||||
if (m_timer > m_timer + std::chrono::seconds(2))
|
||||
{
|
||||
break;
|
||||
}
|
||||
m_time_last_broadcast = float(StkTime::getRealTime());
|
||||
m_broadcast_count++;
|
||||
if (m_broadcast_count > 100)
|
||||
{
|
||||
// Not much we can do about if we don't receive the client
|
||||
// connection - it could have stopped, lost network, ...
|
||||
// Terminate this protocol.
|
||||
Log::error("ConnectToPeer", "Time out trying to connect to %s",
|
||||
m_peer_address.toString().c_str());
|
||||
requestTerminate();
|
||||
}
|
||||
resetTimer();
|
||||
// Now we know the peer address. If it's a non-local host, start
|
||||
// the Ping protocol to keep the port available. We can't rely
|
||||
// on STKHost::isLAN(), since we might get a LAN connection even
|
||||
// if the server itself accepts connections from anywhere.
|
||||
if ((!m_is_lan &&
|
||||
m_peer_address.getIP() !=
|
||||
STKHost::get()->getPublicAddress().getIP()) ||
|
||||
NetworkConfig::m_disable_lan)
|
||||
{
|
||||
BareNetworkString data;
|
||||
data.addUInt8(0);
|
||||
STKHost::get()->sendRawPacket(data, m_peer_address);
|
||||
}
|
||||
|
||||
// Otherwise we are in the same LAN (same public ip address).
|
||||
// Just send a broadcast packet with the string aloha_stk inside,
|
||||
// the client will know our ip address and will connect
|
||||
TransportAddress broadcast_address;
|
||||
if(NetworkConfig::get()->isWAN())
|
||||
{
|
||||
broadcast_address.setIP(-1); // 255.255.255.255
|
||||
broadcast_address.setPort(m_peer_address.getPort());
|
||||
}
|
||||
else
|
||||
// Send a broadcast packet with the string aloha_stk inside,
|
||||
// the client will know our ip address and will connect
|
||||
// The wan remote should already start its ping message to us now
|
||||
// so we can send packet directly to it.
|
||||
TransportAddress broadcast_address;
|
||||
broadcast_address.copy(m_peer_address);
|
||||
|
||||
BareNetworkString aloha(std::string("aloha_stk"));
|
||||
STKHost::get()->sendRawPacket(aloha, broadcast_address);
|
||||
Log::info("ConnectToPeer", "Broadcast aloha sent.");
|
||||
StkTime::sleep(1);
|
||||
|
||||
broadcast_address.copy(m_peer_address);
|
||||
broadcast_address.setIP(0x7f000001); // 127.0.0.1 (localhost)
|
||||
broadcast_address.setPort(m_peer_address.getPort());
|
||||
STKHost::get()->sendRawPacket(aloha, broadcast_address);
|
||||
Log::info("ConnectToPeer", "Broadcast aloha to self.");
|
||||
|
||||
BareNetworkString aloha(std::string("aloha_stk"));
|
||||
STKHost::get()->sendRawPacket(aloha, broadcast_address);
|
||||
Log::info("ConnectToPeer", "Broadcast aloha sent.");
|
||||
StkTime::sleep(1);
|
||||
|
||||
broadcast_address.setIP(0x7f000001); // 127.0.0.1 (localhost)
|
||||
broadcast_address.setPort(m_peer_address.getPort());
|
||||
STKHost::get()->sendRawPacket(aloha, broadcast_address);
|
||||
Log::info("ConnectToPeer", "Broadcast aloha to self.");
|
||||
// 30 seconds timeout
|
||||
if (m_tried_connection++ > 15)
|
||||
{
|
||||
// Not much we can do about if we don't receive the client
|
||||
// connection - it could have stopped, lost network, ...
|
||||
// Terminate this protocol.
|
||||
Log::error("ConnectToPeer", "Time out trying to connect to %s",
|
||||
m_peer_address.toString().c_str());
|
||||
requestTerminate();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CONNECTING: // waiting for the peer to connect
|
||||
@ -193,14 +175,6 @@ void ConnectToPeer::asynchronousUpdate()
|
||||
break;
|
||||
case CONNECTED:
|
||||
{
|
||||
// If the ping protocol is there for NAT traversal terminate it.
|
||||
// Ping is not running when connecting to a LAN peer.
|
||||
if (m_current_protocol)
|
||||
{
|
||||
// Kill the ping protocol because we're connected
|
||||
m_current_protocol->requestTerminate();
|
||||
m_current_protocol = nullptr;
|
||||
}
|
||||
m_state = DONE;
|
||||
break;
|
||||
}
|
||||
@ -212,16 +186,3 @@ void ConnectToPeer::asynchronousUpdate()
|
||||
break;
|
||||
}
|
||||
} // asynchronousUpdate
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Callback from the GetPeerAddress protocol. It copies the received peer
|
||||
* address so that it can be used in the next states of the connection
|
||||
* protocol.
|
||||
*/
|
||||
void ConnectToPeer::callback(Protocol *protocol)
|
||||
{
|
||||
assert(m_state==RECEIVED_PEER_ADDRESS);
|
||||
m_peer_address.copy( ((GetPeerAddress*)protocol)->getAddress() );
|
||||
// Reactivate this protocol
|
||||
requestUnpause();
|
||||
} // callback
|
||||
|
@ -23,49 +23,54 @@
|
||||
#include "network/transport_address.hpp"
|
||||
#include "utils/cpp2011.hpp"
|
||||
|
||||
#include <chrono>
|
||||
|
||||
/** One instance of this is started for every peer who tries to
|
||||
* connect to this server.
|
||||
*/
|
||||
class ConnectToPeer : public Protocol, public CallbackObject
|
||||
class ConnectToPeer : public Protocol
|
||||
{
|
||||
protected:
|
||||
|
||||
TransportAddress m_peer_address;
|
||||
uint32_t m_peer_id;
|
||||
|
||||
/** Pointer to the protocol which is monitored for state changes. */
|
||||
/** Pointer to the protocol which is monitored for state changes, this
|
||||
* need to be shared_ptr because we need to get the result from
|
||||
* \ref GetPeerAddress, otherwise when it terminated the result will be
|
||||
* gone. */
|
||||
std::shared_ptr<Protocol> m_current_protocol;
|
||||
|
||||
/** True if this is a LAN connection. */
|
||||
bool m_is_lan;
|
||||
|
||||
/** We might need to broadcast several times (in case the client is not
|
||||
* ready in time). This keep track of broadcastst. */
|
||||
float m_time_last_broadcast;
|
||||
/** Timer use for tracking broadcast. */
|
||||
std::chrono::system_clock::time_point m_timer;
|
||||
|
||||
int m_broadcast_count;
|
||||
unsigned m_tried_connection = 0;
|
||||
|
||||
enum STATE
|
||||
{
|
||||
NONE,
|
||||
RECEIVED_PEER_ADDRESS,
|
||||
WAIT_FOR_LAN,
|
||||
WAIT_FOR_CONNECTION,
|
||||
CONNECTING,
|
||||
CONNECTED,
|
||||
DONE,
|
||||
EXITING
|
||||
} m_state;
|
||||
|
||||
void resetTimer() { m_timer = std::chrono::system_clock::now(); }
|
||||
|
||||
public:
|
||||
ConnectToPeer(uint32_t peer_id);
|
||||
ConnectToPeer(const TransportAddress &address);
|
||||
virtual ~ConnectToPeer();
|
||||
|
||||
virtual bool notifyEventAsynchronous(Event* event) OVERRIDE;
|
||||
virtual void setup() OVERRIDE;
|
||||
virtual void setup() OVERRIDE {}
|
||||
virtual void update(float dt) OVERRIDE {}
|
||||
virtual void asynchronousUpdate() OVERRIDE;
|
||||
virtual void callback(Protocol *protocol) OVERRIDE;
|
||||
}; // class ConnectToPeer
|
||||
|
||||
#endif // CONNECT_TO_SERVER_HPP
|
||||
|
@ -21,11 +21,9 @@
|
||||
#include "config/player_manager.hpp"
|
||||
#include "network/event.hpp"
|
||||
#include "network/network_config.hpp"
|
||||
#include "network/protocols/get_public_address.hpp"
|
||||
#include "network/protocols/get_peer_address.hpp"
|
||||
#include "network/protocols/hide_public_address.hpp"
|
||||
#include "network/protocols/request_connection.hpp"
|
||||
#include "network/protocols/ping_protocol.hpp"
|
||||
#include "network/protocols/client_lobby.hpp"
|
||||
#include "network/protocol_manager.hpp"
|
||||
#include "network/servers_manager.hpp"
|
||||
@ -82,45 +80,21 @@ ConnectToServer::~ConnectToServer()
|
||||
void ConnectToServer::setup()
|
||||
{
|
||||
Log::info("ConnectToServer", "SETUP");
|
||||
m_current_protocol = nullptr;
|
||||
m_current_protocol.reset();
|
||||
// In case of LAN we already have the server's and our ip address,
|
||||
// so we can immediately start requesting a connection.
|
||||
m_state = NetworkConfig::get()->isLAN() ? GOT_SERVER_ADDRESS : NONE;
|
||||
m_state = NetworkConfig::get()->isLAN() ? GOT_SERVER_ADDRESS :
|
||||
REGISTER_SELF_ADDRESS;
|
||||
|
||||
} // setup
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Sets the server transport address. This is used in case of LAN networking,
|
||||
* when we do not query the stk server and instead have the address from the
|
||||
* LAN server directly.
|
||||
* \param address Address of server to connect to.
|
||||
*/
|
||||
void ConnectToServer::setServerAddress(const TransportAddress &address)
|
||||
{
|
||||
} // setServerAddress
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void ConnectToServer::asynchronousUpdate()
|
||||
{
|
||||
switch(m_state)
|
||||
{
|
||||
case NONE:
|
||||
case REGISTER_SELF_ADDRESS:
|
||||
{
|
||||
Log::info("ConnectToServer", "Protocol starting");
|
||||
// This protocol will write the public address of this
|
||||
// instance to STKHost.
|
||||
m_current_protocol = std::make_shared<GetPublicAddress>(this);
|
||||
m_current_protocol->requestStart();
|
||||
// This protocol will be unpaused in the callback from
|
||||
// GetPublicAddress
|
||||
requestPause();
|
||||
m_state = GETTING_SELF_ADDRESS;
|
||||
break;
|
||||
}
|
||||
case GETTING_SELF_ADDRESS:
|
||||
{
|
||||
// drop GetPublicAddress
|
||||
m_current_protocol = nullptr;
|
||||
|
||||
registerWithSTKServer(); // Register us with STK server
|
||||
|
||||
if (m_quick_join)
|
||||
@ -139,135 +113,125 @@ void ConnectToServer::asynchronousUpdate()
|
||||
case GOT_SERVER_ADDRESS:
|
||||
{
|
||||
assert(!m_quick_join);
|
||||
m_current_protocol = nullptr;
|
||||
Log::info("ConnectToServer", "Server's address known");
|
||||
|
||||
// we're in the same lan (same public ip address) !!
|
||||
if (m_server_address.getIP() ==
|
||||
NetworkConfig::get()->getMyAddress().getIP())
|
||||
{
|
||||
Log::info("ConnectToServer",
|
||||
"Server appears to be in the same LAN.");
|
||||
}
|
||||
m_state = REQUESTING_CONNECTION;
|
||||
m_current_protocol = std::make_shared<RequestConnection>(m_server_id);
|
||||
m_current_protocol->requestStart();
|
||||
auto request_connection =
|
||||
std::make_shared<RequestConnection>(m_server_id);
|
||||
request_connection->requestStart();
|
||||
m_current_protocol = request_connection;
|
||||
// Reset timer for next usage
|
||||
resetTimer();
|
||||
break;
|
||||
}
|
||||
case REQUESTING_CONNECTION:
|
||||
// In case of a LAN server, m_crrent_protocol is NULL
|
||||
if (!m_current_protocol ||
|
||||
m_current_protocol->getState() == PROTOCOL_STATE_TERMINATED)
|
||||
if (!m_current_protocol.expired())
|
||||
{
|
||||
m_current_protocol = nullptr;
|
||||
// Server knows we want to connect
|
||||
Log::info("ConnectToServer", "Connection request made");
|
||||
if (m_server_address.getIP() == 0 ||
|
||||
m_server_address.getPort() == 0 )
|
||||
{
|
||||
// server data not correct, hide address and stop
|
||||
m_state = HIDING_ADDRESS;
|
||||
Log::error("ConnectToServer", "Server address is %s",
|
||||
m_server_address.toString().c_str());
|
||||
m_current_protocol = std::make_shared<HidePublicAddress>();
|
||||
m_current_protocol->requestStart();
|
||||
return;
|
||||
}
|
||||
if( ( !NetworkConfig::m_disable_lan &&
|
||||
m_server_address.getIP()
|
||||
== NetworkConfig::get()->getMyAddress().getIP() ) ||
|
||||
NetworkConfig::get()->isLAN() )
|
||||
return;
|
||||
}
|
||||
|
||||
// Server knows we want to connect
|
||||
Log::info("ConnectToServer", "Connection request made");
|
||||
if (m_server_address.isUnset())
|
||||
{
|
||||
// server data not correct, hide address and stop
|
||||
m_state = HIDING_ADDRESS;
|
||||
Log::error("ConnectToServer", "Server address is %s",
|
||||
m_server_address.toString().c_str());
|
||||
auto hide_address = std::make_shared<HidePublicAddress>();
|
||||
hide_address->requestStart();
|
||||
m_current_protocol = hide_address;
|
||||
return;
|
||||
}
|
||||
if (m_tried_connection++ > 5)
|
||||
{
|
||||
Log::error("ConnectToServer", "Timeout waiting for aloha");
|
||||
m_state = NetworkConfig::get()->isWAN() ?
|
||||
HIDING_ADDRESS : DONE;
|
||||
}
|
||||
if ((!NetworkConfig::m_disable_lan &&
|
||||
m_server_address.getIP() ==
|
||||
STKHost::get()->getPublicAddress().getIP()) ||
|
||||
NetworkConfig::get()->isLAN())
|
||||
{
|
||||
// We're in the same lan (same public ip address).
|
||||
// The state will change to CONNECTING
|
||||
waitingAloha(false/*is_wan*/);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Send a 1-byte datagram, the remote host can simply ignore
|
||||
// this datagram, to keep the port open (2 second each)
|
||||
if (m_timer > m_timer + std::chrono::seconds(2))
|
||||
{
|
||||
// We're in the same lan (same public ip address).
|
||||
// The state will change to CONNECTING
|
||||
handleSameLAN();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_state = CONNECTING;
|
||||
m_current_protocol = std::make_shared<PingProtocol>(m_server_address, 2.0);
|
||||
m_current_protocol->requestStart();
|
||||
resetTimer();
|
||||
BareNetworkString data;
|
||||
data.addUInt8(0);
|
||||
STKHost::get()->sendRawPacket(data, m_server_address);
|
||||
}
|
||||
waitingAloha(true/*is_wan*/);
|
||||
}
|
||||
break;
|
||||
case CONNECTING: // waiting the server to answer our connection
|
||||
{
|
||||
if (m_timer > m_timer + std::chrono::seconds(5)) // every 5 seconds
|
||||
{
|
||||
static double timer = 0;
|
||||
if (StkTime::getRealTime() > timer+5.0) // every 5 seconds
|
||||
STKHost::get()->connect(m_server_address);
|
||||
resetTimer();
|
||||
Log::info("ConnectToServer", "Trying to connect to %s",
|
||||
m_server_address.toString().c_str());
|
||||
if (m_tried_connection++ > 3)
|
||||
{
|
||||
STKHost::get()->connect(m_server_address);
|
||||
timer = StkTime::getRealTime();
|
||||
Log::info("ConnectToServer", "Trying to connect to %s",
|
||||
m_server_address.toString().c_str());
|
||||
Log::error("ConnectToServer", "Timeout connect to %s",
|
||||
m_server_address.toString().c_str());
|
||||
m_state = NetworkConfig::get()->isWAN() ?
|
||||
HIDING_ADDRESS : DONE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CONNECTED:
|
||||
{
|
||||
Log::info("ConnectToServer", "Connected");
|
||||
if(m_current_protocol)
|
||||
{
|
||||
// Kill the ping protocol because we're connected
|
||||
m_current_protocol->requestTerminate();
|
||||
}
|
||||
m_current_protocol = nullptr;
|
||||
// LAN networking does not use the stk server tables.
|
||||
if(NetworkConfig::get()->isWAN())
|
||||
if (NetworkConfig::get()->isWAN())
|
||||
{
|
||||
m_current_protocol = std::make_shared<HidePublicAddress>();
|
||||
m_current_protocol->requestStart();
|
||||
auto hide_address = std::make_shared<HidePublicAddress>();
|
||||
hide_address->requestStart();
|
||||
m_current_protocol = hide_address;
|
||||
}
|
||||
m_state = HIDING_ADDRESS;
|
||||
break;
|
||||
}
|
||||
case HIDING_ADDRESS:
|
||||
// Wait till we have hidden our address
|
||||
if (!m_current_protocol ||
|
||||
m_current_protocol->getState() == PROTOCOL_STATE_TERMINATED)
|
||||
if (!m_current_protocol.expired())
|
||||
{
|
||||
if(m_current_protocol)
|
||||
{
|
||||
m_current_protocol = nullptr;
|
||||
Log::info("ConnectToServer", "Address hidden");
|
||||
}
|
||||
m_state = DONE;
|
||||
// lobby room protocol if we're connected only
|
||||
if(STKHost::get()->getPeers()[0]->isConnected())
|
||||
{
|
||||
auto cl = LobbyProtocol::create<ClientLobby>();
|
||||
cl->setAddress(m_server_address);
|
||||
cl->requestStart();
|
||||
}
|
||||
return;
|
||||
}
|
||||
m_state = DONE;
|
||||
// lobby room protocol if we're connected only
|
||||
if (STKHost::get()->getPeers()[0]->isConnected() &&
|
||||
!m_server_address.isUnset())
|
||||
{
|
||||
auto cl = LobbyProtocol::create<ClientLobby>();
|
||||
cl->setAddress(m_server_address);
|
||||
cl->requestStart();
|
||||
}
|
||||
break;
|
||||
case DONE:
|
||||
requestTerminate();
|
||||
m_state = EXITING;
|
||||
if (STKHost::get()->getPeerCount() == 0)
|
||||
{
|
||||
// Shutdown STKHost (go back to online menu too)
|
||||
STKHost::get()->requestShutdown();
|
||||
}
|
||||
break;
|
||||
case EXITING:
|
||||
break;
|
||||
}
|
||||
} // asynchronousUpdate
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Called when the GetPeerAddress protocol terminates.
|
||||
*/
|
||||
void ConnectToServer::callback(Protocol *protocol)
|
||||
{
|
||||
switch(m_state)
|
||||
{
|
||||
case GETTING_SELF_ADDRESS:
|
||||
// The GetPublicAddress protocol stores our address in
|
||||
// STKHost, so we only need to unpause this protocol
|
||||
requestUnpause();
|
||||
break;
|
||||
default:
|
||||
Log::error("ConnectToServer",
|
||||
"Received unexpected callback while in state %d.",
|
||||
m_state);
|
||||
} // case m_state
|
||||
} // callback
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Register this client with the STK server.
|
||||
*/
|
||||
@ -275,14 +239,13 @@ void ConnectToServer::registerWithSTKServer()
|
||||
{
|
||||
// Our public address is now known, register details with
|
||||
// STK server.
|
||||
const TransportAddress& addr = NetworkConfig::get()->getMyAddress();
|
||||
const TransportAddress& addr = STKHost::get()->getPublicAddress();
|
||||
Online::XMLRequest *request = new Online::XMLRequest();
|
||||
PlayerManager::setUserDetails(request, "set",
|
||||
Online::API::SERVER_PATH);
|
||||
request->addParameter("address", addr.getIP());
|
||||
request->addParameter("port", addr.getPort());
|
||||
request->addParameter("private_port",
|
||||
NetworkConfig::get()->getClientPort());
|
||||
request->addParameter("private_port", STKHost::get()->getPrivatePort());
|
||||
|
||||
Log::info("ConnectToServer", "Registering addr %s",
|
||||
addr.toString().c_str());
|
||||
@ -318,7 +281,6 @@ void ConnectToServer::handleQuickConnect()
|
||||
request->executeNow();
|
||||
|
||||
const XMLNode * result = request->getXMLData();
|
||||
delete request;
|
||||
std::string success;
|
||||
|
||||
if(result->get("success", &success) && success=="yes")
|
||||
@ -330,7 +292,7 @@ void ConnectToServer::handleQuickConnect()
|
||||
uint16_t port;
|
||||
// If we are using a LAN connection, we need the private (local) port
|
||||
if (m_server_address.getIP() ==
|
||||
NetworkConfig::get()->getMyAddress().getIP())
|
||||
STKHost::get()->getPublicAddress().getIP())
|
||||
{
|
||||
result->get("private_port", &port);
|
||||
}
|
||||
@ -345,13 +307,15 @@ void ConnectToServer::handleQuickConnect()
|
||||
{
|
||||
Log::error("GetPeerAddress", "Failed to get address.");
|
||||
}
|
||||
delete request;
|
||||
} // handleQuickConnect
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** Called when the server is on the same LAN. It uses broadcast to
|
||||
* find and conntect to the server.
|
||||
* find and conntect to the server. For WAN game, it makes sure server recieve
|
||||
* request from stk addons first before continuing.
|
||||
*/
|
||||
void ConnectToServer::handleSameLAN()
|
||||
void ConnectToServer::waitingAloha(bool is_wan)
|
||||
{
|
||||
// just send a broadcast packet, the client will know our
|
||||
// ip address and will connect
|
||||
@ -379,65 +343,70 @@ void ConnectToServer::handleSameLAN()
|
||||
std::string aloha("aloha_stk");
|
||||
if (received==aloha)
|
||||
{
|
||||
Log::info("ConnectToServer", "LAN Server found : %s",
|
||||
Log::info("ConnectToServer", "Server found : %s",
|
||||
sender.toString().c_str());
|
||||
#ifndef WIN32
|
||||
// just check if the ip is ours : if so,
|
||||
// then just use localhost (127.0.0.1)
|
||||
struct ifaddrs *ifap, *ifa;
|
||||
struct sockaddr_in *sa;
|
||||
getifaddrs(&ifap); // get the info
|
||||
for (ifa = ifap; ifa; ifa = ifa->ifa_next)
|
||||
if (!is_wan)
|
||||
{
|
||||
if (ifa->ifa_addr->sa_family == AF_INET)
|
||||
// just check if the ip is ours : if so,
|
||||
// then just use localhost (127.0.0.1)
|
||||
struct ifaddrs *ifap, *ifa;
|
||||
struct sockaddr_in *sa;
|
||||
getifaddrs(&ifap); // get the info
|
||||
for (ifa = ifap; ifa; ifa = ifa->ifa_next)
|
||||
{
|
||||
sa = (struct sockaddr_in *) ifa->ifa_addr;
|
||||
if (ifa->ifa_addr->sa_family == AF_INET)
|
||||
{
|
||||
sa = (struct sockaddr_in *) ifa->ifa_addr;
|
||||
|
||||
// This interface is ours
|
||||
if (ntohl(sa->sin_addr.s_addr) == sender.getIP())
|
||||
sender.setIP(0x7f000001); // 127.0.0.1
|
||||
// This interface is ours
|
||||
if (ntohl(sa->sin_addr.s_addr) == sender.getIP())
|
||||
sender.setIP(0x7f000001); // 127.0.0.1
|
||||
}
|
||||
}
|
||||
}
|
||||
freeifaddrs(ifap);
|
||||
freeifaddrs(ifap);
|
||||
#else
|
||||
// Query the list of all IP addresses on the local host
|
||||
// First call to GetIpAddrTable with 0 bytes buffer
|
||||
// will return insufficient buffer error, and size
|
||||
// will contain the number of bytes needed for all
|
||||
// data. Repeat the process of querying the size
|
||||
// using GetIpAddrTable in a while loop since it
|
||||
// can happen that an interface comes online between
|
||||
// the previous call to GetIpAddrTable and the next
|
||||
// call.
|
||||
MIB_IPADDRTABLE *table = NULL;
|
||||
unsigned long size = 0;
|
||||
int error = GetIpAddrTable(table, &size, 0);
|
||||
// Also add a count to limit the while loop - in
|
||||
// case that something strange is going on.
|
||||
int count = 0;
|
||||
while (error == ERROR_INSUFFICIENT_BUFFER && count < 10)
|
||||
{
|
||||
delete[] table; // deleting NULL is legal
|
||||
table = (MIB_IPADDRTABLE*)new char[size];
|
||||
error = GetIpAddrTable(table, &size, 0);
|
||||
count++;
|
||||
} // while insufficient buffer
|
||||
for (unsigned int i = 0; i < table->dwNumEntries; i++)
|
||||
{
|
||||
unsigned int ip = ntohl(table->table[i].dwAddr);
|
||||
if (sender.getIP() == ip) // this interface is ours
|
||||
// Query the list of all IP addresses on the local host
|
||||
// First call to GetIpAddrTable with 0 bytes buffer
|
||||
// will return insufficient buffer error, and size
|
||||
// will contain the number of bytes needed for all
|
||||
// data. Repeat the process of querying the size
|
||||
// using GetIpAddrTable in a while loop since it
|
||||
// can happen that an interface comes online between
|
||||
// the previous call to GetIpAddrTable and the next
|
||||
// call.
|
||||
MIB_IPADDRTABLE *table = NULL;
|
||||
unsigned long size = 0;
|
||||
int error = GetIpAddrTable(table, &size, 0);
|
||||
// Also add a count to limit the while loop - in
|
||||
// case that something strange is going on.
|
||||
int count = 0;
|
||||
while (error == ERROR_INSUFFICIENT_BUFFER && count < 10)
|
||||
{
|
||||
sender.setIP(0x7f000001); // 127.0.0.1
|
||||
break;
|
||||
delete[] table; // deleting NULL is legal
|
||||
table = (MIB_IPADDRTABLE*)new char[size];
|
||||
error = GetIpAddrTable(table, &size, 0);
|
||||
count++;
|
||||
} // while insufficient buffer
|
||||
for (unsigned int i = 0; i < table->dwNumEntries; i++)
|
||||
{
|
||||
unsigned int ip = ntohl(table->table[i].dwAddr);
|
||||
if (sender.getIP() == ip) // this interface is ours
|
||||
{
|
||||
sender.setIP(0x7f000001); // 127.0.0.1
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
delete[] table;
|
||||
|
||||
delete[] table;
|
||||
#endif
|
||||
m_server_address.copy(sender);
|
||||
m_server_address.copy(sender);
|
||||
}
|
||||
m_state = CONNECTING;
|
||||
// Reset timer for next usage
|
||||
resetTimer();
|
||||
m_tried_connection = 0;
|
||||
}
|
||||
} // handleSameLAN
|
||||
} // waitingAloha
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
@ -448,7 +417,6 @@ bool ConnectToServer::notifyEventAsynchronous(Event* event)
|
||||
Log::info("ConnectToServer", "The Connect To Server protocol has "
|
||||
"received an event notifying that he's connected to the peer.");
|
||||
m_state = CONNECTED; // we received a message, we are connected
|
||||
Server *server = ServersManager::get()->getJoinedServer();
|
||||
}
|
||||
return true;
|
||||
} // notifyEventAsynchronous
|
||||
|
@ -22,27 +22,28 @@
|
||||
#include "network/protocol.hpp"
|
||||
#include "network/transport_address.hpp"
|
||||
#include "utils/cpp2011.hpp"
|
||||
#include <chrono>
|
||||
#include <string>
|
||||
|
||||
class ConnectToServer : public Protocol, public CallbackObject
|
||||
class ConnectToServer : public Protocol
|
||||
{
|
||||
private:
|
||||
std::chrono::system_clock::time_point m_timer;
|
||||
TransportAddress m_server_address;
|
||||
uint32_t m_server_id;
|
||||
uint32_t m_host_id;
|
||||
unsigned m_tried_connection = 0;
|
||||
|
||||
/** Protocol currently being monitored. */
|
||||
std::shared_ptr<Protocol> m_current_protocol;
|
||||
std::weak_ptr<Protocol> m_current_protocol;
|
||||
bool m_quick_join;
|
||||
|
||||
/** State for finite state machine. */
|
||||
enum
|
||||
{
|
||||
NONE,
|
||||
GETTING_SELF_ADDRESS,
|
||||
REGISTER_SELF_ADDRESS,
|
||||
GOT_SERVER_ADDRESS,
|
||||
REQUESTING_CONNECTION,
|
||||
QUICK_JOIN,
|
||||
CONNECTING,
|
||||
CONNECTED,
|
||||
HIDING_ADDRESS,
|
||||
@ -52,7 +53,8 @@ private:
|
||||
|
||||
void registerWithSTKServer();
|
||||
void handleQuickConnect();
|
||||
void handleSameLAN();
|
||||
void waitingAloha(bool is_wan);
|
||||
void resetTimer() { m_timer = std::chrono::system_clock::now(); }
|
||||
|
||||
public:
|
||||
ConnectToServer();
|
||||
@ -62,9 +64,7 @@ public:
|
||||
virtual bool notifyEventAsynchronous(Event* event) OVERRIDE;
|
||||
virtual void setup() OVERRIDE;
|
||||
virtual void asynchronousUpdate() OVERRIDE;
|
||||
virtual void callback(Protocol *protocol) OVERRIDE;
|
||||
virtual void update(float dt) OVERRIDE {}
|
||||
void setServerAddress(const TransportAddress &address);
|
||||
}; // class ConnectToServer
|
||||
|
||||
#endif // CONNECT_TO_SERVER_HPP
|
||||
|
@ -21,13 +21,12 @@
|
||||
#include "config/player_manager.hpp"
|
||||
#include "config/user_config.hpp"
|
||||
#include "network/network_config.hpp"
|
||||
#include "network/protocol_manager.hpp"
|
||||
#include "network/stk_host.hpp"
|
||||
#include "online/request_manager.hpp"
|
||||
#include "utils/log.hpp"
|
||||
|
||||
GetPeerAddress::GetPeerAddress(uint32_t peer_id,
|
||||
CallbackObject* callback_object)
|
||||
: Protocol(PROTOCOL_SILENT, callback_object)
|
||||
GetPeerAddress::GetPeerAddress(uint32_t peer_id)
|
||||
: Protocol(PROTOCOL_SILENT, NULL)
|
||||
{
|
||||
m_peer_id = peer_id;
|
||||
} // GetPeerAddress
|
||||
@ -41,7 +40,6 @@ GetPeerAddress::~GetPeerAddress()
|
||||
void GetPeerAddress::setup()
|
||||
{
|
||||
m_address.clear();
|
||||
|
||||
m_request = new Online::XMLRequest();
|
||||
PlayerManager::setUserDetails(m_request, "get",
|
||||
Online::API::SERVER_PATH);
|
||||
@ -65,7 +63,7 @@ void GetPeerAddress::asynchronousUpdate()
|
||||
m_address.setIP(ip);
|
||||
|
||||
uint16_t port;
|
||||
uint32_t my_ip = NetworkConfig::get()->getMyAddress().getIP();
|
||||
uint32_t my_ip = STKHost::get()->getPublicAddress().getIP();
|
||||
if (m_address.getIP() == my_ip && !NetworkConfig::m_disable_lan)
|
||||
result->get("private_port", &port);
|
||||
else
|
||||
@ -84,9 +82,3 @@ void GetPeerAddress::asynchronousUpdate()
|
||||
m_request = NULL;
|
||||
}
|
||||
} // asynchronousUpdate
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void GetPeerAddress::setPeerID(uint32_t peer_id)
|
||||
{
|
||||
m_peer_id = peer_id;
|
||||
} // setPeerID
|
||||
|
@ -35,13 +35,12 @@ private:
|
||||
* to get the result. */
|
||||
TransportAddress m_address;
|
||||
public:
|
||||
GetPeerAddress(uint32_t peer_id, CallbackObject* callback_object);
|
||||
GetPeerAddress(uint32_t peer_id);
|
||||
virtual ~GetPeerAddress();
|
||||
|
||||
virtual void setup() OVERRIDE;
|
||||
virtual void asynchronousUpdate() OVERRIDE;
|
||||
void setPeerID(uint32_t m_peer_id);
|
||||
|
||||
void setPeerID(uint32_t peer_id) { m_peer_id = peer_id; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the address found. */
|
||||
const TransportAddress &getAddress() const { return m_address; }
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "network/protocols/get_public_address.hpp"
|
||||
|
||||
#include "config/user_config.hpp"
|
||||
#include "guiengine/message_queue.hpp"
|
||||
#include "network/network.hpp"
|
||||
#include "network/network_config.hpp"
|
||||
#include "network/network_string.hpp"
|
||||
@ -28,6 +29,8 @@
|
||||
#include "utils/string_utils.hpp"
|
||||
|
||||
#include <assert.h>
|
||||
#include <algorithm>
|
||||
#include <random>
|
||||
#include <string>
|
||||
|
||||
#ifdef __MINGW32__
|
||||
@ -48,36 +51,16 @@
|
||||
const uint32_t GetPublicAddress::m_stun_magic_cookie = 0x2112A442;
|
||||
TransportAddress GetPublicAddress::m_my_address(0, 0);
|
||||
|
||||
void GetPublicAddress::setMyIPAddress(const std::string &s)
|
||||
{
|
||||
std::vector<std::string> l = StringUtils::split(s, ':');
|
||||
if (l.size() != 2)
|
||||
{
|
||||
Log::fatal("Invalid IP address '%s'.", s.c_str());
|
||||
}
|
||||
std::vector<std::string> ip = StringUtils::split(l[0], '.');
|
||||
if (ip.size() != 4)
|
||||
{
|
||||
Log::fatal("Invalid IP address '%s'.", s.c_str());
|
||||
}
|
||||
uint32_t u = 0;
|
||||
for (unsigned int i = 0; i < 4; i++)
|
||||
{
|
||||
int k;
|
||||
StringUtils::fromString(ip[i], k);
|
||||
u = (u << 8) + k;
|
||||
}
|
||||
m_my_address.setIP(u);
|
||||
int p;
|
||||
StringUtils::fromString(l[1], p);
|
||||
m_my_address.setPort(p);
|
||||
} // setMyIPAddress
|
||||
|
||||
// ============================================================================
|
||||
GetPublicAddress::GetPublicAddress(CallbackObject *callback)
|
||||
: Protocol(PROTOCOL_SILENT, callback)
|
||||
GetPublicAddress::GetPublicAddress()
|
||||
: Protocol(PROTOCOL_SILENT, NULL)
|
||||
{
|
||||
m_state = NOTHING_DONE;
|
||||
m_untried_server = UserConfigParams::m_stun_servers;
|
||||
// Generate random list of stun servers
|
||||
std::random_device rd;
|
||||
std::mt19937 g(rd());
|
||||
std::shuffle(m_untried_server.begin(), m_untried_server.end(), g);
|
||||
} // GetPublicAddress
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -85,15 +68,22 @@ GetPublicAddress::GetPublicAddress(CallbackObject *callback)
|
||||
* the list stored in the config file. See
|
||||
* https://tools.ietf.org/html/rfc5389#section-6
|
||||
* for details on the message structure.
|
||||
* The request is send through m_transaction_host, from which the answer
|
||||
* The request is send through transaction_host, from which the answer
|
||||
* will be retrieved by parseStunResponse()
|
||||
*/
|
||||
void GetPublicAddress::createStunRequest()
|
||||
Network* GetPublicAddress::createStunRequest()
|
||||
{
|
||||
// Pick a random stun server
|
||||
std::vector<std::string> stun_servers = UserConfigParams::m_stun_servers;
|
||||
if (m_untried_server.empty())
|
||||
{
|
||||
// Notice: MessageQueue is thread safe to add
|
||||
MessageQueue::add(MessageQueue::MT_ERROR,
|
||||
_("Failed to get public address from stun server."));
|
||||
requestTerminate();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char* server_name = stun_servers[rand() % stun_servers.size()].c_str();
|
||||
// Pick last element in untried servers
|
||||
const char* server_name = m_untried_server.back().c_str();
|
||||
Log::debug("GetPublicAddress", "Using STUN server %s", server_name);
|
||||
|
||||
struct addrinfo hints, *res;
|
||||
@ -106,10 +96,12 @@ void GetPublicAddress::createStunRequest()
|
||||
int status = getaddrinfo(server_name, NULL, &hints, &res);
|
||||
if (status != 0)
|
||||
{
|
||||
Log::error("GetPublicAddress", "Error in getaddrinfo: %s",
|
||||
gai_strerror(status));
|
||||
return;
|
||||
Log::error("GetPublicAddress", "Error in getaddrinfo for stun server"
|
||||
" %s: %s", server_name, gai_strerror(status));
|
||||
m_untried_server.pop_back();
|
||||
return NULL;
|
||||
}
|
||||
m_untried_server.pop_back();
|
||||
// documentation says it points to "one or more addrinfo structures"
|
||||
assert(res != NULL);
|
||||
struct sockaddr_in* current_interface = (struct sockaddr_in*)(res->ai_addr);
|
||||
@ -119,7 +111,7 @@ void GetPublicAddress::createStunRequest()
|
||||
ENetAddress addr;
|
||||
addr.host = STKHost::HOST_ANY;
|
||||
addr.port = STKHost::PORT_ANY;
|
||||
m_transaction_host = new Network(1, 1, 0, 0, &addr);
|
||||
Network* transaction_host = new Network(1, 1, 0, 0, &addr);
|
||||
|
||||
// Assemble the message for the stun server
|
||||
BareNetworkString s(20);
|
||||
@ -138,11 +130,11 @@ void GetPublicAddress::createStunRequest()
|
||||
m_stun_tansaction_id[i] = random_byte;
|
||||
}
|
||||
|
||||
m_transaction_host->sendRawPacket(s,
|
||||
transaction_host->sendRawPacket(s,
|
||||
TransportAddress(m_stun_server_ip,
|
||||
m_stun_server_port) );
|
||||
freeaddrinfo(res);
|
||||
m_state = STUN_REQUEST_SENT;
|
||||
return transaction_host;
|
||||
} // createStunRequest
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -151,12 +143,13 @@ void GetPublicAddress::createStunRequest()
|
||||
* then parses the answer into address and port
|
||||
* \return "" if the address could be parsed or an error message
|
||||
*/
|
||||
std::string GetPublicAddress::parseStunResponse()
|
||||
std::string GetPublicAddress::parseStunResponse(Network* transaction_host)
|
||||
{
|
||||
TransportAddress sender;
|
||||
const int LEN = 2048;
|
||||
char buffer[LEN];
|
||||
int len = m_transaction_host->receiveRawPacket(buffer, LEN, &sender, 2000);
|
||||
int len = transaction_host->receiveRawPacket(buffer, LEN, &sender, 2000);
|
||||
delete transaction_host;
|
||||
|
||||
if(sender.getIP()!=m_stun_server_ip)
|
||||
{
|
||||
@ -199,7 +192,6 @@ std::string GetPublicAddress::parseStunResponse()
|
||||
|
||||
// Those are the port and the address to be detected
|
||||
|
||||
int pos = 20;
|
||||
while (true)
|
||||
{
|
||||
int type = datas.getUInt16();
|
||||
@ -239,35 +231,27 @@ void GetPublicAddress::asynchronousUpdate()
|
||||
if (m_my_address.getIP() != 0 && m_my_address.getPort() != 0)
|
||||
{
|
||||
NetworkConfig::get()->setMyAddress(m_my_address);
|
||||
m_state = EXITING;
|
||||
requestTerminate();
|
||||
}
|
||||
//#define LAN_TEST
|
||||
#ifdef LAN_TEST
|
||||
TransportAddress address(0x7f000001, 4);
|
||||
NetworkConfig::get()->setMyAddress(address);
|
||||
m_state = EXITING;
|
||||
requestTerminate();
|
||||
return;
|
||||
#endif
|
||||
|
||||
if (m_state == NOTHING_DONE)
|
||||
Network* transaction_host = createStunRequest();
|
||||
if (transaction_host)
|
||||
{
|
||||
createStunRequest();
|
||||
}
|
||||
if (m_state == STUN_REQUEST_SENT)
|
||||
{
|
||||
std::string message = parseStunResponse();
|
||||
delete m_transaction_host;
|
||||
std::string message = parseStunResponse(transaction_host);
|
||||
if (message != "")
|
||||
{
|
||||
Log::warn("GetPublicAddress", "%s", message.c_str());
|
||||
m_state = NOTHING_DONE; // try again
|
||||
}
|
||||
else
|
||||
{
|
||||
// The address and the port are known, so the connection can be closed
|
||||
m_state = EXITING;
|
||||
requestTerminate();
|
||||
}
|
||||
}
|
||||
|
@ -30,8 +30,10 @@ class Network;
|
||||
class GetPublicAddress : public Protocol
|
||||
{
|
||||
private:
|
||||
void createStunRequest();
|
||||
std::string parseStunResponse();
|
||||
Network* createStunRequest();
|
||||
std::string parseStunResponse(Network* transaction_host);
|
||||
|
||||
std::vector<std::string> m_untried_server;
|
||||
|
||||
// Constants
|
||||
static const uint32_t m_stun_magic_cookie;
|
||||
@ -41,20 +43,13 @@ private:
|
||||
* unnecessary (though that means that the user has to take care of
|
||||
* opening the firewall). */
|
||||
static TransportAddress m_my_address;
|
||||
enum State
|
||||
{
|
||||
NOTHING_DONE,
|
||||
STUN_REQUEST_SENT,
|
||||
EXITING
|
||||
} m_state;
|
||||
|
||||
uint8_t m_stun_tansaction_id[12];
|
||||
uint32_t m_stun_server_ip;
|
||||
Network* m_transaction_host;
|
||||
|
||||
public:
|
||||
static void setMyIPAddress(const std::string &s);
|
||||
GetPublicAddress(CallbackObject *callback = NULL);
|
||||
GetPublicAddress();
|
||||
virtual ~GetPublicAddress() {}
|
||||
|
||||
virtual void asynchronousUpdate() OVERRIDE;
|
||||
@ -65,7 +60,7 @@ public:
|
||||
// ------------------------------------------------------------------------
|
||||
virtual bool notifyEventAsynchronous(Event* event) OVERRIDE { return true; }
|
||||
// ------------------------------------------------------------------------
|
||||
virtual void setup() { m_state = NOTHING_DONE; }
|
||||
virtual void setup() { }
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
}; // class GetPublicAddress
|
||||
|
@ -56,7 +56,7 @@ void HidePublicAddress::asynchronousUpdate()
|
||||
{
|
||||
if(rec_success == "yes")
|
||||
{
|
||||
Log::debug("HidePublicAddress", "Address hidden successfully.");
|
||||
Log::info("HidePublicAddress", "Address hidden successfully.");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -26,11 +26,12 @@
|
||||
* \param delay_between_pings: How often to ping.
|
||||
*/
|
||||
PingProtocol::PingProtocol(const TransportAddress& ping_dst,
|
||||
double delay_between_pings)
|
||||
double delay_between_pings, double timeout)
|
||||
: Protocol(PROTOCOL_SILENT)
|
||||
{
|
||||
m_ping_dst.copy(ping_dst);
|
||||
m_delay_between_pings = delay_between_pings;
|
||||
m_timeout = timeout;
|
||||
} // PingProtocol
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -41,7 +42,7 @@ PingProtocol::~PingProtocol()
|
||||
// ----------------------------------------------------------------------------
|
||||
void PingProtocol::setup()
|
||||
{
|
||||
m_last_ping_time = 0;
|
||||
m_last_ping_time = 0.0;
|
||||
} // setup
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -49,6 +50,10 @@ void PingProtocol::asynchronousUpdate()
|
||||
{
|
||||
if (StkTime::getRealTime() > m_last_ping_time+m_delay_between_pings)
|
||||
{
|
||||
if (m_last_ping_time == 0.0)
|
||||
m_timeout = StkTime::getRealTime() + m_timeout;
|
||||
else if (StkTime::getRealTime() > m_timeout)
|
||||
requestTerminate();
|
||||
m_last_ping_time = StkTime::getRealTime();
|
||||
BareNetworkString data;
|
||||
data.addUInt8(0);
|
||||
|
@ -16,9 +16,12 @@ private:
|
||||
|
||||
/** Time of last ping. */
|
||||
double m_last_ping_time;
|
||||
|
||||
/** If longer than this, terminate this protocol. */
|
||||
double m_timeout;
|
||||
public:
|
||||
PingProtocol(const TransportAddress& ping_dst,
|
||||
double delay_between_pings);
|
||||
double delay_between_pings, double timeout = 60.0);
|
||||
virtual ~PingProtocol();
|
||||
|
||||
virtual void asynchronousUpdate() OVERRIDE;
|
||||
|
@ -115,7 +115,6 @@ void ServerLobby::setup()
|
||||
m_state = NetworkConfig::get()->isLAN() ? ACCEPTING_CLIENTS
|
||||
: INIT_WAN;
|
||||
m_selection_enabled = false;
|
||||
m_current_protocol = nullptr;
|
||||
Log::info("ServerLobby", "Starting the protocol.");
|
||||
|
||||
// Initialise the data structures to detect if all clients and
|
||||
@ -201,27 +200,20 @@ void ServerLobby::update(float dt)
|
||||
switch (m_state.load())
|
||||
{
|
||||
case INIT_WAN:
|
||||
{
|
||||
// Start the protocol to find the public ip address.
|
||||
m_current_protocol = std::make_shared<GetPublicAddress>(this);
|
||||
m_current_protocol->requestStart();
|
||||
m_state = GETTING_PUBLIC_ADDRESS;
|
||||
// The callback from GetPublicAddress will wake this protocol up
|
||||
requestPause();
|
||||
break;
|
||||
}
|
||||
case GETTING_PUBLIC_ADDRESS:
|
||||
{
|
||||
Log::debug("ServerLobby", "Public address known.");
|
||||
// Free GetPublicAddress protocol
|
||||
m_current_protocol = nullptr;
|
||||
|
||||
// Register this server with the STK server. This will block
|
||||
// this thread, but there is no need for the protocol manager
|
||||
// to react to any requests before the server is registered.
|
||||
registerServer();
|
||||
Log::info("ServerLobby", "Server registered.");
|
||||
m_state = ACCEPTING_CLIENTS;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case ACCEPTING_CLIENTS:
|
||||
{
|
||||
// Only poll the STK server if this is a WAN server.
|
||||
@ -306,15 +298,6 @@ void ServerLobby::update(float dt)
|
||||
}
|
||||
} // update
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Callback when the GetPublicAddress terminates. It will unpause this
|
||||
* protocol, which triggers the next state of the finite state machine.
|
||||
*/
|
||||
void ServerLobby::callback(Protocol *protocol)
|
||||
{
|
||||
requestUnpause();
|
||||
} // callback
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Register this server (i.e. its public address) with the STK server
|
||||
* so that clients can find it. It blocks till a response from the
|
||||
@ -325,12 +308,12 @@ void ServerLobby::callback(Protocol *protocol)
|
||||
void ServerLobby::registerServer()
|
||||
{
|
||||
Online::XMLRequest *request = new Online::XMLRequest();
|
||||
const TransportAddress& addr = NetworkConfig::get()->getMyAddress();
|
||||
const TransportAddress& addr = STKHost::get()->getPublicAddress();
|
||||
PlayerManager::setUserDetails(request, "create", Online::API::SERVER_PATH);
|
||||
request->addParameter("address", addr.getIP() );
|
||||
request->addParameter("port", addr.getPort() );
|
||||
request->addParameter("private_port",
|
||||
NetworkConfig::get()->getServerPort() );
|
||||
STKHost::get()->getPrivatePort() );
|
||||
request->addParameter("name", NetworkConfig::get()->getServerName() );
|
||||
request->addParameter("max_players",
|
||||
UserConfigParams::m_server_max_players );
|
||||
@ -350,9 +333,11 @@ void ServerLobby::registerServer()
|
||||
{
|
||||
irr::core::stringc error(request->getInfo().c_str());
|
||||
Log::error("RegisterServer", "%s", error.c_str());
|
||||
STKHost::get()->setErrorMessage(_("Failed to register server: %s", error.c_str()));
|
||||
STKHost::get()->setErrorMessage(_("Failed to register server: %s",
|
||||
error.c_str()));
|
||||
STKHost::get()->requestShutdown();
|
||||
}
|
||||
|
||||
delete request;
|
||||
} // registerServer
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -444,7 +429,7 @@ void ServerLobby::checkIncomingConnectionRequests()
|
||||
PlayerManager::setUserDetails(request, "poll-connection-requests",
|
||||
Online::API::SERVER_PATH);
|
||||
|
||||
const TransportAddress &addr = NetworkConfig::get()->getMyAddress();
|
||||
const TransportAddress &addr = STKHost::get()->getPublicAddress();
|
||||
request->addParameter("address", addr.getIP() );
|
||||
request->addParameter("port", addr.getPort());
|
||||
|
||||
@ -469,7 +454,7 @@ void ServerLobby::checkIncomingConnectionRequests()
|
||||
Log::debug("ServerLobby",
|
||||
"User with id %d wants to connect.", id);
|
||||
std::make_shared<ConnectToPeer>(id)->requestStart();
|
||||
}
|
||||
}
|
||||
delete request;
|
||||
} // checkIncomingConnectionRequests
|
||||
|
||||
|
@ -9,7 +9,6 @@
|
||||
#include <set>
|
||||
|
||||
class ServerLobby : public LobbyProtocol
|
||||
, public CallbackObject
|
||||
{
|
||||
public:
|
||||
/* The state for a small finite state machine. */
|
||||
@ -57,7 +56,6 @@ private:
|
||||
* seconds), which is the real time at which the server should start. */
|
||||
double m_server_delay;
|
||||
|
||||
std::shared_ptr<Protocol> m_current_protocol;
|
||||
bool m_selection_enabled;
|
||||
|
||||
/** Counts how many players are ready to go on. */
|
||||
@ -98,7 +96,6 @@ public:
|
||||
void checkRaceFinished();
|
||||
void finishedLoadingWorld();
|
||||
ServerState getCurrentState() const { return m_state.load(); }
|
||||
virtual void callback(Protocol *protocol) OVERRIDE;
|
||||
|
||||
}; // class ServerLobby
|
||||
|
||||
|
@ -43,7 +43,24 @@
|
||||
# include <errno.h>
|
||||
# include <sys/socket.h>
|
||||
#endif
|
||||
|
||||
#ifdef __MINGW32__
|
||||
# undef _WIN32_WINNT
|
||||
# define _WIN32_WINNT 0x501
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
# include <winsock2.h>
|
||||
# include <ws2tcpip.h>
|
||||
#else
|
||||
# include <netdb.h>
|
||||
#endif
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <random>
|
||||
#include <string>
|
||||
|
||||
STKHost *STKHost::m_stk_host = NULL;
|
||||
bool STKHost::m_enable_console = false;
|
||||
@ -244,10 +261,10 @@ STKHost::STKHost(uint32_t server_id, uint32_t host_id)
|
||||
// server is made.
|
||||
m_host_id = 0;
|
||||
init();
|
||||
TransportAddress a;
|
||||
a.setIP(0);
|
||||
a.setPort(NetworkConfig::get()->getClientPort());
|
||||
ENetAddress ea = a.toEnetAddress();
|
||||
|
||||
ENetAddress ea;
|
||||
ea.host = STKHost::HOST_ANY;
|
||||
ea.port = STKHost::PORT_ANY;
|
||||
|
||||
m_network = new Network(/*peer_count*/1, /*channel_limit*/2,
|
||||
/*max_in_bandwidth*/0, /*max_out_bandwidth*/0, &ea);
|
||||
@ -257,7 +274,16 @@ STKHost::STKHost(uint32_t server_id, uint32_t host_id)
|
||||
"an ENet client host.");
|
||||
}
|
||||
|
||||
std::make_shared<ConnectToServer>(server_id, host_id)->requestStart();
|
||||
setPrivatePort();
|
||||
if (NetworkConfig::get()->isWAN())
|
||||
{
|
||||
setPublicAddress();
|
||||
}
|
||||
// Don't connect to server if no public address in WAN game
|
||||
if (!m_public_address.isUnset() || NetworkConfig::get()->isLAN())
|
||||
{
|
||||
std::make_shared<ConnectToServer>(server_id, host_id)->requestStart();
|
||||
}
|
||||
} // STKHost
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -274,7 +300,7 @@ STKHost::STKHost(const irr::core::stringw &server_name)
|
||||
|
||||
ENetAddress addr;
|
||||
addr.host = STKHost::HOST_ANY;
|
||||
addr.port = NetworkConfig::get()->getServerPort();
|
||||
addr.port = STKHost::PORT_ANY;
|
||||
|
||||
m_network= new Network(NetworkConfig::get()->getMaxPlayers(),
|
||||
/*channel_limit*/2,
|
||||
@ -286,8 +312,18 @@ STKHost::STKHost(const irr::core::stringw &server_name)
|
||||
"ENet server host.");
|
||||
}
|
||||
|
||||
startListening();
|
||||
ProtocolManager::lock()->requestStart(LobbyProtocol::create<ServerLobby>());
|
||||
setPrivatePort();
|
||||
if (NetworkConfig::get()->isWAN())
|
||||
{
|
||||
setPublicAddress();
|
||||
}
|
||||
// Don't construct server if no public address in WAN game
|
||||
if (!m_public_address.isUnset() || NetworkConfig::get()->isLAN())
|
||||
{
|
||||
startListening();
|
||||
ProtocolManager::lock()
|
||||
->requestStart(LobbyProtocol::create<ServerLobby>());
|
||||
}
|
||||
|
||||
} // STKHost(server_name)
|
||||
|
||||
@ -364,6 +400,192 @@ void STKHost::shutdown()
|
||||
destroy();
|
||||
} // shutdown
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Set the public address using stun protocol.
|
||||
*/
|
||||
void STKHost::setPublicAddress()
|
||||
{
|
||||
std::vector<std::string> untried_server = UserConfigParams::m_stun_servers;
|
||||
// Generate random list of stun servers
|
||||
std::random_device rd;
|
||||
std::mt19937 g(rd());
|
||||
std::shuffle(untried_server.begin(), untried_server.end(), g);
|
||||
while (!untried_server.empty())
|
||||
{
|
||||
// Pick last element in untried servers
|
||||
const char* server_name = untried_server.back().c_str();
|
||||
Log::debug("STKHost", "Using STUN server %s", server_name);
|
||||
|
||||
struct addrinfo hints, *res;
|
||||
|
||||
memset(&hints, 0, sizeof hints);
|
||||
hints.ai_family = AF_UNSPEC; // AF_INET or AF_INET6 to force version
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
|
||||
// Resolve the stun server name so we can send it a STUN request
|
||||
int status = getaddrinfo(server_name, NULL, &hints, &res);
|
||||
if (status != 0)
|
||||
{
|
||||
Log::error("STKHost", "Error in getaddrinfo for stun server"
|
||||
" %s: %s", server_name, gai_strerror(status));
|
||||
untried_server.pop_back();
|
||||
continue;
|
||||
}
|
||||
untried_server.pop_back();
|
||||
// documentation says it points to "one or more addrinfo structures"
|
||||
assert(res != NULL);
|
||||
struct sockaddr_in* current_interface = (struct sockaddr_in*)(res->ai_addr);
|
||||
uint32_t stun_server_ip = ntohl(current_interface->sin_addr.s_addr);
|
||||
|
||||
// Assemble the message for the stun server
|
||||
BareNetworkString s(20);
|
||||
|
||||
// bytes 0-1: the type of the message
|
||||
// bytes 2-3: message length added to header (attributes)
|
||||
uint16_t message_type = 0x0001; // binding request
|
||||
uint16_t message_length = 0x0000;
|
||||
s.addUInt16(message_type).addUInt16(message_length)
|
||||
.addUInt32(0x2112A442);
|
||||
uint8_t stun_tansaction_id[12];
|
||||
// bytes 8-19: the transaction id
|
||||
for (int i = 0; i < 12; i++)
|
||||
{
|
||||
uint8_t random_byte = rand() % 256;
|
||||
s.addUInt8(random_byte);
|
||||
stun_tansaction_id[i] = random_byte;
|
||||
}
|
||||
|
||||
m_network->sendRawPacket(s, TransportAddress(stun_server_ip, 3478));
|
||||
freeaddrinfo(res);
|
||||
|
||||
// Recieve now
|
||||
TransportAddress sender;
|
||||
const int LEN = 2048;
|
||||
char buffer[LEN];
|
||||
int len = m_network->receiveRawPacket(buffer, LEN, &sender, 2000);
|
||||
|
||||
if (sender.getIP() != stun_server_ip)
|
||||
{
|
||||
TransportAddress stun(stun_server_ip, 3478);
|
||||
Log::warn("STKHost",
|
||||
"Received stun response from %s instead of %s.",
|
||||
sender.toString().c_str(), stun.toString().c_str());
|
||||
}
|
||||
|
||||
if (len < 0)
|
||||
{
|
||||
Log::error("STKHost", "STUN response contains no data at all");
|
||||
continue;
|
||||
}
|
||||
|
||||
// Convert to network string.
|
||||
BareNetworkString datas(buffer, len);
|
||||
|
||||
// check that the stun response is a response, contains the magic cookie
|
||||
// and the transaction ID
|
||||
if (datas.getUInt16() != 0x0101)
|
||||
{
|
||||
Log::error("STKHost", "STUN response doesn't contain the magic "
|
||||
"cookie");
|
||||
continue;
|
||||
}
|
||||
int message_size = datas.getUInt16();
|
||||
if (datas.getUInt32() != 0x2112A442)
|
||||
{
|
||||
Log::error("STKHost", "STUN response doesn't contain the magic "
|
||||
"cookie");
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 12; i++)
|
||||
{
|
||||
if (datas.getUInt8() != stun_tansaction_id[i])
|
||||
{
|
||||
Log::error("STKHost", "STUN response doesn't contain the "
|
||||
"transaction ID");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
Log::debug("GetPublicAddress",
|
||||
"The STUN server responded with a valid answer");
|
||||
|
||||
// The stun message is valid, so we parse it now:
|
||||
if (message_size == 0)
|
||||
{
|
||||
Log::error("STKHost", "STUN response does not contain any "
|
||||
"information.");
|
||||
continue;
|
||||
}
|
||||
// Cannot even read the size
|
||||
if (message_size < 4)
|
||||
{
|
||||
Log::error("STKHost", "STUN response is too short.");
|
||||
continue;
|
||||
}
|
||||
// Those are the port and the address to be detected
|
||||
bool found = false;
|
||||
while (true)
|
||||
{
|
||||
int type = datas.getUInt16();
|
||||
int size = datas.getUInt16();
|
||||
if (type == 0 || type == 1)
|
||||
{
|
||||
assert(size == 8);
|
||||
datas.getUInt8(); // skip 1 byte
|
||||
#ifdef DEBUG
|
||||
uint8_t skip = datas.getUInt8();
|
||||
// Family IPv4 only
|
||||
assert(skip == 0x01);
|
||||
#else
|
||||
datas.getUInt8();
|
||||
#endif
|
||||
m_public_address.setPort(datas.getUInt16());
|
||||
m_public_address.setIP(datas.getUInt32());
|
||||
// finished parsing, we know our public transport address
|
||||
Log::debug("STKHost", "The public address has been found: %s",
|
||||
m_public_address.toString().c_str());
|
||||
found = true;
|
||||
break;
|
||||
} // type = 0 or 1
|
||||
datas.skip(4 + size);
|
||||
message_size -= 4 + size;
|
||||
if (message_size == 0)
|
||||
{
|
||||
Log::error("STKHost", "STUN response is invalid.");
|
||||
break;
|
||||
}
|
||||
// Cannot even read the size
|
||||
if (message_size < 4)
|
||||
{
|
||||
Log::error("STKHost", "STUN response is invalid.");
|
||||
break;
|
||||
}
|
||||
} // while true
|
||||
// Found public address and port
|
||||
if (found)
|
||||
untried_server.clear();
|
||||
}
|
||||
// We shutdown next frame if no public address
|
||||
if (m_public_address.isUnset())
|
||||
requestShutdown();
|
||||
} // setPublicAddress
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void STKHost::setPrivatePort()
|
||||
{
|
||||
struct sockaddr_in sin;
|
||||
socklen_t len = sizeof(sin);
|
||||
ENetHost *host = m_network->getENetHost();
|
||||
if (getsockname(host->socket, (struct sockaddr *)&sin, &len) == -1)
|
||||
{
|
||||
Log::error("STKHost", "Error while using getsockname().");
|
||||
m_private_port = 0;
|
||||
}
|
||||
else
|
||||
m_private_port = ntohs(sin.sin_port);
|
||||
} // setPrivatePort
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** A previous GameSetup is deletea and a new one is created.
|
||||
* \return Newly create GameSetup object.
|
||||
@ -495,9 +717,7 @@ void STKHost::mainLoop()
|
||||
|
||||
// A separate network connection (socket) to handle LAN requests.
|
||||
Network* lan_network = NULL;
|
||||
|
||||
if (NetworkConfig::get()->isServer() &&
|
||||
(NetworkConfig::get()->isLAN() || NetworkConfig::get()->isPublicServer()) )
|
||||
if (NetworkConfig::get()->isLAN())
|
||||
{
|
||||
TransportAddress address(0, NetworkConfig::get()->getServerDiscoveryPort());
|
||||
ENetAddress eaddr = address.toEnetAddress();
|
||||
@ -610,6 +830,13 @@ void STKHost::handleDirectSocketRequest(Network* lan_network)
|
||||
{
|
||||
// In case of a LAN connection, we only allow connections from
|
||||
// a LAN address (192.168*, ..., and 127.*).
|
||||
if (!sender.isLAN())
|
||||
{
|
||||
Log::error("STKHost", "Client trying to connect from '%s'",
|
||||
sender.toString().c_str());
|
||||
Log::error("STKHost", "which is outside of LAN - rejected.");
|
||||
return;
|
||||
}
|
||||
std::make_shared<ConnectToPeer>(sender)->requestStart();
|
||||
}
|
||||
else
|
||||
@ -742,20 +969,6 @@ void STKHost::removePeer(const STKPeer* peer)
|
||||
m_peers.size());
|
||||
} // removePeer
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
uint16_t STKHost::getPort() const
|
||||
{
|
||||
struct sockaddr_in sin;
|
||||
socklen_t len = sizeof(sin);
|
||||
ENetHost *host = m_network->getENetHost();
|
||||
if (getsockname(host->socket, (struct sockaddr *)&sin, &len) == -1)
|
||||
Log::error("STKHost", "Error while using getsockname().");
|
||||
else
|
||||
return ntohs(sin.sin_port);
|
||||
return 0;
|
||||
} // getPort
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Sends data to all peers except the specified one.
|
||||
* \param peer Peer which will not receive the message.
|
||||
|
@ -103,12 +103,22 @@ private:
|
||||
* in the GUI. */
|
||||
irr::core::stringw m_error_message;
|
||||
|
||||
/** The public address found by stun (if WAN is used). */
|
||||
TransportAddress m_public_address;
|
||||
|
||||
/** The private port enet socket is bound. */
|
||||
uint16_t m_private_port;
|
||||
|
||||
/** An error message, which is set by a protocol to be displayed
|
||||
* in the GUI. */
|
||||
|
||||
STKHost(uint32_t server_id, uint32_t host_id);
|
||||
STKHost(const irr::core::stringw &server_name);
|
||||
virtual ~STKHost();
|
||||
void init();
|
||||
void handleDirectSocketRequest(Network* lan_network);
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
void setPublicAddress();
|
||||
// ------------------------------------------------------------------------
|
||||
void mainLoop();
|
||||
|
||||
@ -140,7 +150,15 @@ public:
|
||||
// ------------------------------------------------------------------------
|
||||
/** Checks if the STKHost has been created. */
|
||||
static bool existHost() { return m_stk_host != NULL; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
const TransportAddress& getPublicAddress() const
|
||||
{ return m_public_address; }
|
||||
// ------------------------------------------------------------------------
|
||||
uint16_t getPrivatePort() const
|
||||
{ return m_private_port; }
|
||||
// ------------------------------------------------------------------------
|
||||
void setPrivatePort();
|
||||
// ------------------------------------------------------------------------
|
||||
virtual GameSetup* setupNewGame();
|
||||
void abort();
|
||||
void deleteAllPeers();
|
||||
@ -175,7 +193,6 @@ public:
|
||||
STKPeer *getPeer(ENetPeer *enet_peer);
|
||||
STKPeer *getServerPeerForClient() const;
|
||||
std::vector<NetworkPlayerProfile*> getMyPlayerProfiles();
|
||||
uint16_t getPort() const;
|
||||
void setErrorMessage(const irr::core::stringw &message);
|
||||
bool isAuthorisedToControl() const;
|
||||
const irr::core::stringw&
|
||||
|
@ -90,6 +90,8 @@ private:
|
||||
public:
|
||||
bool isLAN() const;
|
||||
// ------------------------------------------------------------------------
|
||||
bool isUnset() const { return m_ip == 0 || m_port == 0; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** A copy function (to replace the copy constructor which is disabled
|
||||
* using NoCopy): it copies the data from the argument into this object.*/
|
||||
void copy(const TransportAddress &other)
|
||||
|
Loading…
Reference in New Issue
Block a user