Various improvements to WAN and LAN connection
This commit is contained in:
parent
d586ab9011
commit
b26b784b6a
@ -280,6 +280,12 @@ void MainLoop::run()
|
|||||||
if (STKHost::existHost() &&
|
if (STKHost::existHost() &&
|
||||||
STKHost::get()->requestedShutdown())
|
STKHost::get()->requestedShutdown())
|
||||||
{
|
{
|
||||||
|
SFXManager::get()->quickSound("anvil");
|
||||||
|
core::stringw msg = _("Connection to server is lost.");
|
||||||
|
if (!STKHost::get()->getErrorMessage().empty())
|
||||||
|
{
|
||||||
|
msg = STKHost::get()->getErrorMessage();
|
||||||
|
}
|
||||||
STKHost::get()->shutdown();
|
STKHost::get()->shutdown();
|
||||||
if (World::getWorld())
|
if (World::getWorld())
|
||||||
{
|
{
|
||||||
@ -293,8 +299,7 @@ void MainLoop::run()
|
|||||||
OnlineScreen::getInstance(), NULL
|
OnlineScreen::getInstance(), NULL
|
||||||
};
|
};
|
||||||
StateManager::get()->resetAndSetStack(new_stack);
|
StateManager::get()->resetAndSetStack(new_stack);
|
||||||
MessageQueue::add(MessageQueue::MT_ERROR,
|
MessageQueue::add(MessageQueue::MT_ERROR, msg);
|
||||||
_("Connection to server is lost."));
|
|
||||||
}
|
}
|
||||||
NetworkConfig::get()->unsetNetworking();
|
NetworkConfig::get()->unsetNetworking();
|
||||||
}
|
}
|
||||||
|
@ -58,6 +58,8 @@ Network::Network(int peer_count, int channel_limit,
|
|||||||
return;
|
return;
|
||||||
if (change_port_if_bound)
|
if (change_port_if_bound)
|
||||||
{
|
{
|
||||||
|
Log::warn("Network", "%d port is in used, use another port",
|
||||||
|
address->port);
|
||||||
ENetAddress new_addr;
|
ENetAddress new_addr;
|
||||||
new_addr.host = address->host;
|
new_addr.host = address->host;
|
||||||
// Any port
|
// Any port
|
||||||
|
@ -32,12 +32,6 @@
|
|||||||
#include "utils/time.hpp"
|
#include "utils/time.hpp"
|
||||||
#include "utils/log.hpp"
|
#include "utils/log.hpp"
|
||||||
|
|
||||||
#ifdef WIN32
|
|
||||||
# include <iphlpapi.h>
|
|
||||||
#else
|
|
||||||
#include <ifaddrs.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
/** Connects to a server. This is the quick connect constructor, which
|
/** Connects to a server. This is the quick connect constructor, which
|
||||||
* will pick a server randomly.
|
* will pick a server randomly.
|
||||||
@ -84,8 +78,7 @@ void ConnectToServer::setup()
|
|||||||
// In case of LAN we already have the server's and our ip address,
|
// In case of LAN we already have the server's and our ip address,
|
||||||
// so we can immediately start requesting a connection.
|
// so we can immediately start requesting a connection.
|
||||||
m_state = NetworkConfig::get()->isLAN() ? GOT_SERVER_ADDRESS :
|
m_state = NetworkConfig::get()->isLAN() ? GOT_SERVER_ADDRESS :
|
||||||
REGISTER_SELF_ADDRESS;
|
SET_PUBLIC_ADDRESS;
|
||||||
|
|
||||||
} // setup
|
} // setup
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@ -93,10 +86,17 @@ void ConnectToServer::asynchronousUpdate()
|
|||||||
{
|
{
|
||||||
switch(m_state)
|
switch(m_state)
|
||||||
{
|
{
|
||||||
|
case SET_PUBLIC_ADDRESS:
|
||||||
|
{
|
||||||
|
STKHost::get()->setPublicAddress();
|
||||||
|
// Set to DONE will stop STKHost is not connected
|
||||||
|
m_state = STKHost::get()->getPublicAddress().isUnset() ?
|
||||||
|
DONE : REGISTER_SELF_ADDRESS;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case REGISTER_SELF_ADDRESS:
|
case REGISTER_SELF_ADDRESS:
|
||||||
{
|
{
|
||||||
registerWithSTKServer(); // Register us with STK server
|
registerWithSTKServer(); // Register us with STK server
|
||||||
|
|
||||||
if (m_quick_join)
|
if (m_quick_join)
|
||||||
{
|
{
|
||||||
handleQuickConnect();
|
handleQuickConnect();
|
||||||
@ -226,6 +226,9 @@ void ConnectToServer::asynchronousUpdate()
|
|||||||
if (STKHost::get()->getPeerCount() == 0)
|
if (STKHost::get()->getPeerCount() == 0)
|
||||||
{
|
{
|
||||||
// Shutdown STKHost (go back to online menu too)
|
// Shutdown STKHost (go back to online menu too)
|
||||||
|
STKHost::get()->setErrorMessage(
|
||||||
|
_("Cannot connect to server with address: %s.",
|
||||||
|
m_server_address.toString().c_str()));
|
||||||
STKHost::get()->requestShutdown();
|
STKHost::get()->requestShutdown();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -266,7 +269,10 @@ void ConnectToServer::registerWithSTKServer()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Log::error("ConnectToServer", "Failed to register address.");
|
irr::core::stringc error(request->getInfo().c_str());
|
||||||
|
Log::error("ConnectToServer", "Failed to register client address: %s",
|
||||||
|
error.c_str());
|
||||||
|
m_state = DONE;
|
||||||
}
|
}
|
||||||
delete request;
|
delete request;
|
||||||
|
|
||||||
@ -349,58 +355,8 @@ void ConnectToServer::waitingAloha(bool is_wan)
|
|||||||
sender.toString().c_str());
|
sender.toString().c_str());
|
||||||
if (!is_wan)
|
if (!is_wan)
|
||||||
{
|
{
|
||||||
#ifndef WIN32
|
if (sender.isPublicAddressLAN())
|
||||||
// just check if the ip is ours : if so,
|
sender.setIP(0x7f000001); // 127.0.0.1
|
||||||
// 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 (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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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
|
|
||||||
{
|
|
||||||
sender.setIP(0x7f000001); // 127.0.0.1
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
delete[] table;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
m_server_address.copy(sender);
|
m_server_address.copy(sender);
|
||||||
m_state = CONNECTING;
|
m_state = CONNECTING;
|
||||||
|
@ -40,6 +40,7 @@ private:
|
|||||||
/** State for finite state machine. */
|
/** State for finite state machine. */
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
|
SET_PUBLIC_ADDRESS,
|
||||||
REGISTER_SELF_ADDRESS,
|
REGISTER_SELF_ADDRESS,
|
||||||
GOT_SERVER_ADDRESS,
|
GOT_SERVER_ADDRESS,
|
||||||
REQUESTING_CONNECTION,
|
REQUESTING_CONNECTION,
|
||||||
|
@ -83,6 +83,8 @@
|
|||||||
ServerLobby::ServerLobby() : LobbyProtocol(NULL)
|
ServerLobby::ServerLobby() : LobbyProtocol(NULL)
|
||||||
{
|
{
|
||||||
setHandleDisconnections(true);
|
setHandleDisconnections(true);
|
||||||
|
m_state = SET_PUBLIC_ADDRESS;
|
||||||
|
|
||||||
// We use maximum 16bit unsigned limit
|
// We use maximum 16bit unsigned limit
|
||||||
auto all_k = kart_properties_manager->getAllAvailableKarts();
|
auto all_k = kart_properties_manager->getAllAvailableKarts();
|
||||||
auto all_t = track_manager->getAllTrackIdentifiers();
|
auto all_t = track_manager->getAllTrackIdentifiers();
|
||||||
@ -113,11 +115,6 @@ void ServerLobby::setup()
|
|||||||
m_game_setup = STKHost::get()->setupNewGame();
|
m_game_setup = STKHost::get()->setupNewGame();
|
||||||
m_game_setup->setNumLocalPlayers(0); // no local players on a server
|
m_game_setup->setNumLocalPlayers(0); // no local players on a server
|
||||||
m_next_player_id.setAtomic(0);
|
m_next_player_id.setAtomic(0);
|
||||||
|
|
||||||
// In case of LAN we don't need our public address or register with the
|
|
||||||
// STK server, so we can directly go to the accepting clients state.
|
|
||||||
m_state = NetworkConfig::get()->isLAN() ? ACCEPTING_CLIENTS
|
|
||||||
: INIT_WAN;
|
|
||||||
m_selection_enabled = false;
|
m_selection_enabled = false;
|
||||||
Log::info("ServerLobby", "Starting the protocol.");
|
Log::info("ServerLobby", "Starting the protocol.");
|
||||||
|
|
||||||
@ -185,7 +182,6 @@ bool ServerLobby::notifyEventAsynchronous(Event* event)
|
|||||||
case LE_VOTE_LAPS: playerLapsVote(event); break;
|
case LE_VOTE_LAPS: playerLapsVote(event); break;
|
||||||
case LE_RACE_FINISHED_ACK: playerFinishedResult(event); break;
|
case LE_RACE_FINISHED_ACK: playerFinishedResult(event); break;
|
||||||
} // switch
|
} // switch
|
||||||
|
|
||||||
} // if (event->getType() == EVENT_TYPE_MESSAGE)
|
} // if (event->getType() == EVENT_TYPE_MESSAGE)
|
||||||
else if (event->getType() == EVENT_TYPE_DISCONNECTED)
|
else if (event->getType() == EVENT_TYPE_DISCONNECTED)
|
||||||
{
|
{
|
||||||
@ -195,21 +191,34 @@ bool ServerLobby::notifyEventAsynchronous(Event* event)
|
|||||||
} // notifyEventAsynchronous
|
} // notifyEventAsynchronous
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
/** Simple finite state machine. First get the public ip address. Once this
|
/** Find out the public IP server or poll STK server asynchronously. */
|
||||||
* is known, register the server and its address with the stk server so that
|
void ServerLobby::asynchronousUpdate()
|
||||||
* client can find it.
|
|
||||||
*/
|
|
||||||
void ServerLobby::update(float dt)
|
|
||||||
{
|
{
|
||||||
switch (m_state.load())
|
switch (m_state.load())
|
||||||
{
|
{
|
||||||
case INIT_WAN:
|
case SET_PUBLIC_ADDRESS:
|
||||||
{
|
{
|
||||||
// Start the protocol to find the public ip address.
|
// In case of LAN we don't need our public address or register with the
|
||||||
m_state = GETTING_PUBLIC_ADDRESS;
|
// STK server, so we can directly go to the accepting clients state.
|
||||||
|
if (NetworkConfig::get()->isLAN())
|
||||||
|
{
|
||||||
|
m_state = ACCEPTING_CLIENTS;
|
||||||
|
STKHost::get()->startListening();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
STKHost::get()->setPublicAddress();
|
||||||
|
if (STKHost::get()->getPublicAddress().isUnset())
|
||||||
|
{
|
||||||
|
m_state = ERROR_LEAVE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
STKHost::get()->startListening();
|
||||||
|
m_state = REGISTER_SELF_ADDRESS;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case GETTING_PUBLIC_ADDRESS:
|
case REGISTER_SELF_ADDRESS:
|
||||||
{
|
{
|
||||||
// Register this server with the STK server. This will block
|
// Register this server with the STK server. This will block
|
||||||
// this thread, but there is no need for the protocol manager
|
// this thread, but there is no need for the protocol manager
|
||||||
@ -221,10 +230,39 @@ void ServerLobby::update(float dt)
|
|||||||
case ACCEPTING_CLIENTS:
|
case ACCEPTING_CLIENTS:
|
||||||
{
|
{
|
||||||
// Only poll the STK server if this is a WAN server.
|
// Only poll the STK server if this is a WAN server.
|
||||||
if(NetworkConfig::get()->isWAN())
|
if (NetworkConfig::get()->isWAN())
|
||||||
checkIncomingConnectionRequests();
|
checkIncomingConnectionRequests();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case ERROR_LEAVE:
|
||||||
|
{
|
||||||
|
requestTerminate();
|
||||||
|
m_state = EXITING;
|
||||||
|
STKHost::get()->setErrorMessage(_("Failed to setup server."));
|
||||||
|
STKHost::get()->requestShutdown();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} // asynchronousUpdate
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
/** Simple finite state machine. Once this
|
||||||
|
* is known, register the server and its address with the stk server so that
|
||||||
|
* client can find it.
|
||||||
|
*/
|
||||||
|
void ServerLobby::update(float dt)
|
||||||
|
{
|
||||||
|
switch (m_state.load())
|
||||||
|
{
|
||||||
|
case SET_PUBLIC_ADDRESS:
|
||||||
|
case REGISTER_SELF_ADDRESS:
|
||||||
|
case ACCEPTING_CLIENTS:
|
||||||
|
{
|
||||||
|
// Waiting for asynchronousUpdate
|
||||||
|
break;
|
||||||
|
}
|
||||||
case SELECTING:
|
case SELECTING:
|
||||||
// The function playerTrackVote will trigger the next state
|
// The function playerTrackVote will trigger the next state
|
||||||
// once all track votes have been received.
|
// once all track votes have been received.
|
||||||
@ -280,7 +318,8 @@ void ServerLobby::update(float dt)
|
|||||||
sendMessageToPeersChangingToken(exit_result_screen,
|
sendMessageToPeersChangingToken(exit_result_screen,
|
||||||
/*reliable*/true);
|
/*reliable*/true);
|
||||||
delete exit_result_screen;
|
delete exit_result_screen;
|
||||||
m_state = ACCEPTING_CLIENTS;
|
m_state = NetworkConfig::get()->isLAN() ?
|
||||||
|
ACCEPTING_CLIENTS : REGISTER_SELF_ADDRESS;
|
||||||
RaceResultGUI::getInstance()->backToLobby();
|
RaceResultGUI::getInstance()->backToLobby();
|
||||||
// notify the network world that it is stopped
|
// notify the network world that it is stopped
|
||||||
RaceEventManager::getInstance()->stop();
|
RaceEventManager::getInstance()->stop();
|
||||||
@ -293,10 +332,7 @@ void ServerLobby::update(float dt)
|
|||||||
setup();
|
setup();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DONE:
|
case ERROR_LEAVE:
|
||||||
m_state = EXITING;
|
|
||||||
requestTerminate();
|
|
||||||
break;
|
|
||||||
case EXITING:
|
case EXITING:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -337,14 +373,11 @@ void ServerLobby::registerServer()
|
|||||||
{
|
{
|
||||||
irr::core::stringc error(request->getInfo().c_str());
|
irr::core::stringc error(request->getInfo().c_str());
|
||||||
Log::error("ServerLobby", "%s", error.c_str());
|
Log::error("ServerLobby", "%s", error.c_str());
|
||||||
STKHost::get()->setErrorMessage(_("Failed to register server: %s",
|
m_state = ERROR_LEAVE;
|
||||||
error.c_str()));
|
|
||||||
STKHost::get()->requestShutdown();
|
|
||||||
}
|
}
|
||||||
delete request;
|
delete request;
|
||||||
} // registerServer
|
} // registerServer
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
/** Unregister this server (i.e. its public address) with the STK server,
|
/** Unregister this server (i.e. its public address) with the STK server,
|
||||||
* currently when karts enter kart selection screen it will be done.
|
* currently when karts enter kart selection screen it will be done.
|
||||||
@ -472,6 +505,12 @@ void ServerLobby::checkIncomingConnectionRequests()
|
|||||||
if (StkTime::getRealTime() < last_poll_time + POLL_INTERVAL)
|
if (StkTime::getRealTime() < last_poll_time + POLL_INTERVAL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// Keep the port open, it can be sent to anywhere as we will send to the
|
||||||
|
// correct peer later in ConnectToPeer.
|
||||||
|
BareNetworkString data;
|
||||||
|
data.addUInt8(0);
|
||||||
|
STKHost::get()->sendRawPacket(data, STKHost::get()->getStunAddress());
|
||||||
|
|
||||||
// Now poll the stk server
|
// Now poll the stk server
|
||||||
last_poll_time = StkTime::getRealTime();
|
last_poll_time = StkTime::getRealTime();
|
||||||
Online::XMLRequest* request = new Online::XMLRequest();
|
Online::XMLRequest* request = new Online::XMLRequest();
|
||||||
|
@ -14,18 +14,17 @@ public:
|
|||||||
/* The state for a small finite state machine. */
|
/* The state for a small finite state machine. */
|
||||||
enum ServerState : unsigned int
|
enum ServerState : unsigned int
|
||||||
{
|
{
|
||||||
INIT_WAN, // Start state for WAN game
|
SET_PUBLIC_ADDRESS, // Waiting to receive its public ip address
|
||||||
GETTING_PUBLIC_ADDRESS, // Waiting to receive its public ip address
|
REGISTER_SELF_ADDRESS, // Register with STK online server
|
||||||
ACCEPTING_CLIENTS, // In lobby, accepting clients
|
ACCEPTING_CLIENTS, // In lobby, accepting clients
|
||||||
SELECTING, // kart, track, ... selection started
|
SELECTING, // kart, track, ... selection started
|
||||||
LOAD_WORLD, // Server starts loading world
|
LOAD_WORLD, // Server starts loading world
|
||||||
WAIT_FOR_WORLD_LOADED, // Wait for clients and server to load world
|
WAIT_FOR_WORLD_LOADED, // Wait for clients and server to load world
|
||||||
WAIT_FOR_RACE_STARTED, // Wait for all clients to have started the race
|
WAIT_FOR_RACE_STARTED, // Wait for all clients to have started the race
|
||||||
START_RACE, // Inform clients to start race
|
|
||||||
DELAY_SERVER, // Additional server delay
|
DELAY_SERVER, // Additional server delay
|
||||||
RACING, // racing
|
RACING, // racing
|
||||||
RESULT_DISPLAY, // Show result screen
|
RESULT_DISPLAY, // Show result screen
|
||||||
DONE, // shutting down server
|
ERROR_LEAVE, // shutting down server
|
||||||
EXITING
|
EXITING
|
||||||
};
|
};
|
||||||
private:
|
private:
|
||||||
@ -92,7 +91,7 @@ public:
|
|||||||
virtual bool notifyEvent(Event* event) OVERRIDE;
|
virtual bool notifyEvent(Event* event) OVERRIDE;
|
||||||
virtual void setup() OVERRIDE;
|
virtual void setup() OVERRIDE;
|
||||||
virtual void update(float dt) OVERRIDE;
|
virtual void update(float dt) OVERRIDE;
|
||||||
virtual void asynchronousUpdate() OVERRIDE {};
|
virtual void asynchronousUpdate() OVERRIDE;
|
||||||
|
|
||||||
void signalRaceStartToClients();
|
void signalRaceStartToClients();
|
||||||
void startSelection(const Event *event=NULL);
|
void startSelection(const Event *event=NULL);
|
||||||
|
@ -261,13 +261,14 @@ STKHost::STKHost(uint32_t server_id, uint32_t host_id)
|
|||||||
// server is made.
|
// server is made.
|
||||||
m_host_id = 0;
|
m_host_id = 0;
|
||||||
init();
|
init();
|
||||||
|
|
||||||
ENetAddress ea;
|
ENetAddress ea;
|
||||||
ea.host = STKHost::HOST_ANY;
|
ea.host = STKHost::HOST_ANY;
|
||||||
ea.port = STKHost::PORT_ANY;
|
ea.port = NetworkConfig::get()->getClientPort();
|
||||||
|
|
||||||
m_network = new Network(/*peer_count*/1, /*channel_limit*/2,
|
m_network = new Network(/*peer_count*/1, /*channel_limit*/2,
|
||||||
/*max_in_bandwidth*/0, /*max_out_bandwidth*/0, &ea);
|
/*max_in_bandwidth*/0, /*max_out_bandwidth*/0,
|
||||||
|
&ea, true/*change_port_if_bound*/);
|
||||||
if (!m_network)
|
if (!m_network)
|
||||||
{
|
{
|
||||||
Log::fatal ("STKHost", "An error occurred while trying to create "
|
Log::fatal ("STKHost", "An error occurred while trying to create "
|
||||||
@ -275,15 +276,7 @@ STKHost::STKHost(uint32_t server_id, uint32_t host_id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
setPrivatePort();
|
setPrivatePort();
|
||||||
if (NetworkConfig::get()->isWAN())
|
std::make_shared<ConnectToServer>(server_id, host_id)->requestStart();
|
||||||
{
|
|
||||||
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
|
} // STKHost
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@ -300,12 +293,13 @@ STKHost::STKHost(const irr::core::stringw &server_name)
|
|||||||
|
|
||||||
ENetAddress addr;
|
ENetAddress addr;
|
||||||
addr.host = STKHost::HOST_ANY;
|
addr.host = STKHost::HOST_ANY;
|
||||||
addr.port = STKHost::PORT_ANY;
|
addr.port = NetworkConfig::get()->getServerPort();
|
||||||
|
|
||||||
m_network= new Network(NetworkConfig::get()->getMaxPlayers(),
|
m_network= new Network(NetworkConfig::get()->getMaxPlayers(),
|
||||||
/*channel_limit*/2,
|
/*channel_limit*/2,
|
||||||
/*max_in_bandwidth*/0,
|
/*max_in_bandwidth*/0,
|
||||||
/*max_out_bandwidth*/ 0, &addr);
|
/*max_out_bandwidth*/ 0, &addr,
|
||||||
|
true/*change_port_if_bound*/);
|
||||||
if (!m_network)
|
if (!m_network)
|
||||||
{
|
{
|
||||||
Log::fatal("STKHost", "An error occurred while trying to create an "
|
Log::fatal("STKHost", "An error occurred while trying to create an "
|
||||||
@ -313,16 +307,8 @@ STKHost::STKHost(const irr::core::stringw &server_name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
setPrivatePort();
|
setPrivatePort();
|
||||||
// We need the public address for server no matter what to determine
|
ProtocolManager::lock()
|
||||||
// local lan connection
|
->requestStart(LobbyProtocol::create<ServerLobby>());
|
||||||
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)
|
} // STKHost(server_name)
|
||||||
|
|
||||||
@ -335,7 +321,6 @@ void STKHost::init()
|
|||||||
m_shutdown = false;
|
m_shutdown = false;
|
||||||
m_network = NULL;
|
m_network = NULL;
|
||||||
m_game_setup = NULL;
|
m_game_setup = NULL;
|
||||||
m_error_message = "";
|
|
||||||
|
|
||||||
m_exit_flag.clear();
|
m_exit_flag.clear();
|
||||||
m_exit_flag.test_and_set();
|
m_exit_flag.test_and_set();
|
||||||
@ -435,17 +420,19 @@ void STKHost::setPublicAddress()
|
|||||||
// documentation says it points to "one or more addrinfo structures"
|
// documentation says it points to "one or more addrinfo structures"
|
||||||
assert(res != NULL);
|
assert(res != NULL);
|
||||||
struct sockaddr_in* current_interface = (struct sockaddr_in*)(res->ai_addr);
|
struct sockaddr_in* current_interface = (struct sockaddr_in*)(res->ai_addr);
|
||||||
uint32_t stun_server_ip = ntohl(current_interface->sin_addr.s_addr);
|
m_stun_address.setIP(ntohl(current_interface->sin_addr.s_addr));
|
||||||
|
m_stun_address.setPort(3478);
|
||||||
|
|
||||||
// Assemble the message for the stun server
|
// Assemble the message for the stun server
|
||||||
BareNetworkString s(20);
|
BareNetworkString s(20);
|
||||||
|
|
||||||
|
constexpr uint32_t magic_cookie = 0x2112A442;
|
||||||
// bytes 0-1: the type of the message
|
// bytes 0-1: the type of the message
|
||||||
// bytes 2-3: message length added to header (attributes)
|
// bytes 2-3: message length added to header (attributes)
|
||||||
uint16_t message_type = 0x0001; // binding request
|
uint16_t message_type = 0x0001; // binding request
|
||||||
uint16_t message_length = 0x0000;
|
uint16_t message_length = 0x0000;
|
||||||
s.addUInt16(message_type).addUInt16(message_length)
|
s.addUInt16(message_type).addUInt16(message_length)
|
||||||
.addUInt32(0x2112A442);
|
.addUInt32(magic_cookie);
|
||||||
uint8_t stun_tansaction_id[12];
|
uint8_t stun_tansaction_id[12];
|
||||||
// bytes 8-19: the transaction id
|
// bytes 8-19: the transaction id
|
||||||
for (int i = 0; i < 12; i++)
|
for (int i = 0; i < 12; i++)
|
||||||
@ -455,7 +442,7 @@ void STKHost::setPublicAddress()
|
|||||||
stun_tansaction_id[i] = random_byte;
|
stun_tansaction_id[i] = random_byte;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_network->sendRawPacket(s, TransportAddress(stun_server_ip, 3478));
|
m_network->sendRawPacket(s, m_stun_address);
|
||||||
freeaddrinfo(res);
|
freeaddrinfo(res);
|
||||||
|
|
||||||
// Recieve now
|
// Recieve now
|
||||||
@ -464,33 +451,37 @@ void STKHost::setPublicAddress()
|
|||||||
char buffer[LEN];
|
char buffer[LEN];
|
||||||
int len = m_network->receiveRawPacket(buffer, LEN, &sender, 2000);
|
int len = m_network->receiveRawPacket(buffer, LEN, &sender, 2000);
|
||||||
|
|
||||||
if (sender.getIP() != stun_server_ip)
|
if (sender.getIP() != m_stun_address.getIP())
|
||||||
{
|
{
|
||||||
TransportAddress stun(stun_server_ip, 3478);
|
|
||||||
Log::warn("STKHost",
|
Log::warn("STKHost",
|
||||||
"Received stun response from %s instead of %s.",
|
"Received stun response from %s instead of %s.",
|
||||||
sender.toString().c_str(), stun.toString().c_str());
|
sender.toString().c_str(), m_stun_address.toString().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len < 0)
|
if (len <= 0)
|
||||||
{
|
{
|
||||||
Log::error("STKHost", "STUN response contains no data at all");
|
Log::error("STKHost", "STUN response contains no data at all");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert to network string.
|
// Convert to network string.
|
||||||
BareNetworkString datas(buffer, len);
|
BareNetworkString response(buffer, len);
|
||||||
|
if (response.size() < 20)
|
||||||
// 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 "
|
Log::error("STKHost", "STUN response should be at least 20 bytes.");
|
||||||
"cookie");
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
int message_size = datas.getUInt16();
|
|
||||||
if (datas.getUInt32() != 0x2112A442)
|
if (response.getUInt16() != 0x0101)
|
||||||
|
{
|
||||||
|
Log::error("STKHost", "STUN has no binding success response.");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip message size
|
||||||
|
response.getUInt16();
|
||||||
|
|
||||||
|
if (response.getUInt32() != magic_cookie)
|
||||||
{
|
{
|
||||||
Log::error("STKHost", "STUN response doesn't contain the magic "
|
Log::error("STKHost", "STUN response doesn't contain the magic "
|
||||||
"cookie");
|
"cookie");
|
||||||
@ -499,7 +490,7 @@ void STKHost::setPublicAddress()
|
|||||||
|
|
||||||
for (int i = 0; i < 12; i++)
|
for (int i = 0; i < 12; i++)
|
||||||
{
|
{
|
||||||
if (datas.getUInt8() != stun_tansaction_id[i])
|
if (response.getUInt8() != stun_tansaction_id[i])
|
||||||
{
|
{
|
||||||
Log::error("STKHost", "STUN response doesn't contain the "
|
Log::error("STKHost", "STUN response doesn't contain the "
|
||||||
"transaction ID");
|
"transaction ID");
|
||||||
@ -511,64 +502,77 @@ void STKHost::setPublicAddress()
|
|||||||
"The STUN server responded with a valid answer");
|
"The STUN server responded with a valid answer");
|
||||||
|
|
||||||
// The stun message is valid, so we parse it now:
|
// 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
|
// Those are the port and the address to be detected
|
||||||
bool found = false;
|
bool found = false;
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
int type = datas.getUInt16();
|
if (response.size() < 4)
|
||||||
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.");
|
Log::error("STKHost", "STUN response is invalid.");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// Cannot even read the size
|
unsigned type = response.getUInt16();
|
||||||
if (message_size < 4)
|
unsigned size = response.getUInt16();
|
||||||
|
|
||||||
|
// Bit determining whether comprehension of an attribute is optional.
|
||||||
|
// Described in section 15 of RFC 5389.
|
||||||
|
constexpr uint16_t comprehension_optional = 0x1 << 15;
|
||||||
|
|
||||||
|
// Bit determining whether the bit was assigned by IETF Review.
|
||||||
|
// Described in section 18.1. of RFC 5389.
|
||||||
|
constexpr uint16_t IETF_review = 0x1 << 14;
|
||||||
|
|
||||||
|
// Defined in section 15.1 of RFC 5389
|
||||||
|
constexpr uint8_t ipv4 = 0x01;
|
||||||
|
|
||||||
|
// Defined in section 18.2 of RFC 5389
|
||||||
|
constexpr uint16_t mapped_address = 0x001;
|
||||||
|
constexpr uint16_t xor_mapped_address = 0x0020;
|
||||||
|
// The first two bits are irrelevant to the type
|
||||||
|
type &= ~(comprehension_optional | IETF_review);
|
||||||
|
if (type == mapped_address || type == xor_mapped_address)
|
||||||
{
|
{
|
||||||
Log::error("STKHost", "STUN response is invalid.");
|
if (size != 8 || response.size() < 8)
|
||||||
|
{
|
||||||
|
Log::error("STKHost", "Invalid STUN mapped address "
|
||||||
|
"length");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Ignore the first byte as mentioned in Section 15.1 of RFC
|
||||||
|
// 5389.
|
||||||
|
uint8_t ip_type = response.getUInt8();
|
||||||
|
ip_type = response.getUInt8();
|
||||||
|
if (ip_type != ipv4)
|
||||||
|
{
|
||||||
|
Log::error("STKHost", "Only IPv4 is supported");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t port = response.getUInt16();
|
||||||
|
uint32_t ip = response.getUInt32();
|
||||||
|
if (type == xor_mapped_address)
|
||||||
|
{
|
||||||
|
// Obfuscation is described in Section 15.2 of RFC 5389.
|
||||||
|
port ^= magic_cookie >> 16;
|
||||||
|
ip ^= magic_cookie;
|
||||||
|
}
|
||||||
|
m_public_address.setPort(port);
|
||||||
|
m_public_address.setIP(ip);
|
||||||
|
found = true;
|
||||||
break;
|
break;
|
||||||
|
} // type == mapped_address || type == xor_mapped_address
|
||||||
|
else
|
||||||
|
{
|
||||||
|
response.skip(size);
|
||||||
|
int padding = size % 4;
|
||||||
|
if (padding != 0)
|
||||||
|
response.skip(4 - padding);
|
||||||
}
|
}
|
||||||
} // while true
|
} // while true
|
||||||
// Found public address and port
|
// Found public address and port
|
||||||
if (found)
|
if (found)
|
||||||
untried_server.clear();
|
untried_server.clear();
|
||||||
}
|
}
|
||||||
// We shutdown next frame if no public address
|
|
||||||
if (m_public_address.isUnset())
|
|
||||||
requestShutdown();
|
|
||||||
} // setPublicAddress
|
} // setPublicAddress
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -629,18 +633,14 @@ void STKHost::abort()
|
|||||||
*/
|
*/
|
||||||
void STKHost::setErrorMessage(const irr::core::stringw &message)
|
void STKHost::setErrorMessage(const irr::core::stringw &message)
|
||||||
{
|
{
|
||||||
irr::core::stringc s(message.c_str());
|
if (!message.empty())
|
||||||
Log::error("STKHost", "%s", s.c_str());
|
{
|
||||||
|
irr::core::stringc s(message.c_str());
|
||||||
|
Log::error("STKHost", "%s", s.c_str());
|
||||||
|
}
|
||||||
m_error_message = message;
|
m_error_message = message;
|
||||||
} // setErrorMessage
|
} // setErrorMessage
|
||||||
|
|
||||||
// --------------------------------------------------------------------
|
|
||||||
/** Returns the last error (or "" if no error has happened). */
|
|
||||||
const irr::core::stringw& STKHost::getErrorMessage() const
|
|
||||||
{
|
|
||||||
return m_error_message;
|
|
||||||
} // getErrorMessage
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------
|
// --------------------------------------------------------------------
|
||||||
/** \brief Try to establish a connection to a given transport address.
|
/** \brief Try to establish a connection to a given transport address.
|
||||||
* \param peer : The transport address which you want to connect to.
|
* \param peer : The transport address which you want to connect to.
|
||||||
@ -831,7 +831,7 @@ void STKHost::handleDirectSocketRequest(Network* lan_network)
|
|||||||
{
|
{
|
||||||
// In case of a LAN connection, we only allow connections from
|
// In case of a LAN connection, we only allow connections from
|
||||||
// a LAN address (192.168*, ..., and 127.*).
|
// a LAN address (192.168*, ..., and 127.*).
|
||||||
if (!sender.isLAN() && sender.getIP() != m_public_address.getIP())
|
if (!sender.isLAN() && !sender.isPublicAddressLAN())
|
||||||
{
|
{
|
||||||
Log::error("STKHost", "Client trying to connect from '%s'",
|
Log::error("STKHost", "Client trying to connect from '%s'",
|
||||||
sender.toString().c_str());
|
sender.toString().c_str());
|
||||||
|
@ -101,6 +101,9 @@ private:
|
|||||||
/** The public address found by stun (if WAN is used). */
|
/** The public address found by stun (if WAN is used). */
|
||||||
TransportAddress m_public_address;
|
TransportAddress m_public_address;
|
||||||
|
|
||||||
|
/** The public address stun server used. */
|
||||||
|
TransportAddress m_stun_address;
|
||||||
|
|
||||||
/** The private port enet socket is bound. */
|
/** The private port enet socket is bound. */
|
||||||
uint16_t m_private_port;
|
uint16_t m_private_port;
|
||||||
|
|
||||||
@ -113,8 +116,6 @@ private:
|
|||||||
void init();
|
void init();
|
||||||
void handleDirectSocketRequest(Network* lan_network);
|
void handleDirectSocketRequest(Network* lan_network);
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
void setPublicAddress();
|
|
||||||
// ------------------------------------------------------------------------
|
|
||||||
void mainLoop();
|
void mainLoop();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -149,11 +150,16 @@ public:
|
|||||||
const TransportAddress& getPublicAddress() const
|
const TransportAddress& getPublicAddress() const
|
||||||
{ return m_public_address; }
|
{ return m_public_address; }
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
|
const TransportAddress& getStunAddress() const
|
||||||
|
{ return m_stun_address; }
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
uint16_t getPrivatePort() const
|
uint16_t getPrivatePort() const
|
||||||
{ return m_private_port; }
|
{ return m_private_port; }
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
void setPrivatePort();
|
void setPrivatePort();
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
|
void setPublicAddress();
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
virtual GameSetup* setupNewGame();
|
virtual GameSetup* setupNewGame();
|
||||||
void abort();
|
void abort();
|
||||||
void deleteAllPeers();
|
void deleteAllPeers();
|
||||||
@ -190,9 +196,11 @@ public:
|
|||||||
std::vector<NetworkPlayerProfile*> getMyPlayerProfiles();
|
std::vector<NetworkPlayerProfile*> getMyPlayerProfiles();
|
||||||
void setErrorMessage(const irr::core::stringw &message);
|
void setErrorMessage(const irr::core::stringw &message);
|
||||||
bool isAuthorisedToControl() const;
|
bool isAuthorisedToControl() const;
|
||||||
const irr::core::stringw&
|
|
||||||
getErrorMessage() const;
|
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------
|
||||||
|
/** Returns the last error (or "" if no error has happened). */
|
||||||
|
const irr::core::stringw& getErrorMessage() const
|
||||||
|
{ return m_error_message; }
|
||||||
// --------------------------------------------------------------------
|
// --------------------------------------------------------------------
|
||||||
/** Returns true if a shutdown of the network infrastructure was
|
/** Returns true if a shutdown of the network infrastructure was
|
||||||
* requested. */
|
* requested. */
|
||||||
@ -214,15 +222,6 @@ public:
|
|||||||
{
|
{
|
||||||
m_network->sendRawPacket(buffer, dst);
|
m_network->sendRawPacket(buffer, dst);
|
||||||
} // sendRawPacket
|
} // sendRawPacket
|
||||||
|
|
||||||
// --------------------------------------------------------------------
|
|
||||||
/** Returns the IP address of this host. */
|
|
||||||
uint32_t getAddress() const
|
|
||||||
{
|
|
||||||
return m_network->getENetHost()->address.host;
|
|
||||||
} // getAddress
|
|
||||||
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------
|
// --------------------------------------------------------------------
|
||||||
/** Returns a const reference to the list of peers. */
|
/** Returns a const reference to the list of peers. */
|
||||||
const std::vector<STKPeer*> &getPeers() { return m_peers; }
|
const std::vector<STKPeer*> &getPeers() { return m_peers; }
|
||||||
|
@ -18,8 +18,15 @@
|
|||||||
|
|
||||||
#include "network/transport_address.hpp"
|
#include "network/transport_address.hpp"
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
# include <iphlpapi.h>
|
||||||
|
#else
|
||||||
|
#include <ifaddrs.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
/** Returns if this IP address belongs to a LAN, i.e. is in 192.168* or
|
/** Returns if this IP address belongs to a LAN, i.e. is in 192.168* or
|
||||||
* 10*, 172.16-31.*, or is on the same host, i.e. 127*.
|
* 10*, 172.16-31.*, or is on the same host, i.e. 127* or same public address.
|
||||||
*/
|
*/
|
||||||
bool TransportAddress::isLAN() const
|
bool TransportAddress::isLAN() const
|
||||||
{
|
{
|
||||||
@ -33,6 +40,60 @@ bool TransportAddress::isLAN() const
|
|||||||
else if (ip >> 24 == 0x7f ) // 127.* localhost
|
else if (ip >> 24 == 0x7f ) // 127.* localhost
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
/** Returns this IP address is localhost (127.0.0.1).
|
||||||
|
*/
|
||||||
|
bool TransportAddress::isPublicAddressLAN() const
|
||||||
|
{
|
||||||
|
#ifndef WIN32
|
||||||
|
struct ifaddrs *ifap, *ifa;
|
||||||
|
struct sockaddr_in *sa;
|
||||||
|
getifaddrs(&ifap); // get the info
|
||||||
|
for (ifa = ifap; ifa; ifa = ifa->ifa_next)
|
||||||
|
{
|
||||||
|
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) == getIP())
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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 (getIP() == ip) // this interface is ours
|
||||||
|
{
|
||||||
|
delete[] table;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete[] table;
|
||||||
|
#endif
|
||||||
|
return false;
|
||||||
} // isLAN
|
} // isLAN
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@ -42,71 +103,71 @@ bool TransportAddress::isLAN() const
|
|||||||
void TransportAddress::unitTesting()
|
void TransportAddress::unitTesting()
|
||||||
{
|
{
|
||||||
TransportAddress t1("192.168.0.0");
|
TransportAddress t1("192.168.0.0");
|
||||||
assert(t1.getIP() == (192 << 24) + (168 << 16));
|
assert(t1.getIP() == (192u << 24) + (168u << 16));
|
||||||
assert(t1.isLAN());
|
assert(t1.isLAN());
|
||||||
|
|
||||||
TransportAddress t2("192.168.255.255");
|
TransportAddress t2("192.168.255.255");
|
||||||
assert(t2.getIP() == (192 << 24) + (168 << 16) + (255 << 8) + 255);
|
assert(t2.getIP() == (192u << 24) + (168u << 16) + (255u << 8) + 255u);
|
||||||
assert(t2.isLAN());
|
assert(t2.isLAN());
|
||||||
|
|
||||||
TransportAddress t3("193.168.0.1");
|
TransportAddress t3("193.168.0.1");
|
||||||
assert(t3.getIP() == (193 << 24) + (168 << 16) + 1);
|
assert(t3.getIP() == (193u << 24) + (168u << 16) + 1);
|
||||||
assert(!t3.isLAN());
|
assert(!t3.isLAN());
|
||||||
|
|
||||||
TransportAddress t4("192.167.255.255");
|
TransportAddress t4("192.167.255.255");
|
||||||
assert(t4.getIP() == (192 << 24) + (167 << 16) + (255 << 8) + 255);
|
assert(t4.getIP() == (192u << 24) + (167u << 16) + (255u << 8) + 255u);
|
||||||
assert(!t4.isLAN());
|
assert(!t4.isLAN());
|
||||||
|
|
||||||
TransportAddress t5("192.169.0.0");
|
TransportAddress t5("192.169.0.0");
|
||||||
assert(t5.getIP() == (192 << 24) + (169 << 16));
|
assert(t5.getIP() == (192u << 24) + (169u << 16));
|
||||||
assert(!t5.isLAN());
|
assert(!t5.isLAN());
|
||||||
|
|
||||||
TransportAddress t6("172.16.0.0");
|
TransportAddress t6("172.16.0.0");
|
||||||
assert(t6.getIP() == (172 << 24) + (16 << 16));
|
assert(t6.getIP() == (172u << 24) + (16u << 16));
|
||||||
assert(t6.isLAN());
|
assert(t6.isLAN());
|
||||||
|
|
||||||
TransportAddress t7("172.31.255.255");
|
TransportAddress t7("172.31.255.255");
|
||||||
assert(t7.getIP() == (172 << 24) + (31 << 16) + (255 << 8) + 255);
|
assert(t7.getIP() == (172u << 24) + (31u << 16) + (255u << 8) + 255u);
|
||||||
assert(t7.isLAN());
|
assert(t7.isLAN());
|
||||||
|
|
||||||
TransportAddress t8("172.15.255.255");
|
TransportAddress t8("172.15.255.255");
|
||||||
assert(t8.getIP() == (172 << 24) + (15 << 16) + (255 << 8) + 255);
|
assert(t8.getIP() == (172u << 24) + (15u << 16) + (255u << 8) + 255u);
|
||||||
assert(!t8.isLAN());
|
assert(!t8.isLAN());
|
||||||
|
|
||||||
TransportAddress t9("172.32.0.0");
|
TransportAddress t9("172.32.0.0");
|
||||||
assert(t9.getIP() == (172 << 24) + (32 << 16));
|
assert(t9.getIP() == (172u << 24) + (32u << 16));
|
||||||
assert(!t9.isLAN());
|
assert(!t9.isLAN());
|
||||||
|
|
||||||
TransportAddress t10("10.0.0.0");
|
TransportAddress t10("10.0.0.0");
|
||||||
assert(t10.getIP() == (10 << 24));
|
assert(t10.getIP() == (10u << 24));
|
||||||
assert(t10.isLAN());
|
assert(t10.isLAN());
|
||||||
|
|
||||||
TransportAddress t11("10.255.255.255");
|
TransportAddress t11("10.255.255.255");
|
||||||
assert(t11.getIP() == (10 << 24) + (255 << 16) + (255 << 8) + 255);
|
assert(t11.getIP() == (10u << 24) + (255u << 16) + (255u << 8) + 255u);
|
||||||
assert(t11.isLAN());
|
assert(t11.isLAN());
|
||||||
|
|
||||||
TransportAddress t12("9.255.255.255");
|
TransportAddress t12("9.255.255.255");
|
||||||
assert(t12.getIP() == (9 << 24) + (255 << 16) + (255 << 8) + 255);
|
assert(t12.getIP() == (9u << 24) + (255u << 16) + (255u << 8) + 255u);
|
||||||
assert(!t12.isLAN());
|
assert(!t12.isLAN());
|
||||||
|
|
||||||
TransportAddress t13("11.0.0.0");
|
TransportAddress t13("11.0.0.0");
|
||||||
assert(t13.getIP() == (11 << 24) );
|
assert(t13.getIP() == (11u << 24));
|
||||||
assert(!t13.isLAN());
|
assert(!t13.isLAN());
|
||||||
|
|
||||||
TransportAddress t14("127.0.0.0");
|
TransportAddress t14("127.0.0.0");
|
||||||
assert(t14.getIP() == (127 << 24));
|
assert(t14.getIP() == (127u << 24));
|
||||||
assert(t14.isLAN());
|
assert(t14.isLAN());
|
||||||
|
|
||||||
TransportAddress t15("127.255.255.255");
|
TransportAddress t15("127.255.255.255");
|
||||||
assert(t15.getIP() == (127 << 24) + (255 << 16) + (255 << 8) + 255);
|
assert(t15.getIP() == (127u << 24) + (255u << 16) + (255u << 8) + 255u);
|
||||||
assert(t15.isLAN());
|
assert(t15.isLAN());
|
||||||
|
|
||||||
TransportAddress t16("126.255.255.255");
|
TransportAddress t16("126.255.255.255");
|
||||||
assert(t16.getIP() == (126 << 24) + (255 << 16) + (255 << 8) + 255);
|
assert(t16.getIP() == (126u << 24) + (255u << 16) + (255u << 8) + 255u);
|
||||||
assert(!t16.isLAN());
|
assert(!t16.isLAN());
|
||||||
|
|
||||||
TransportAddress t17("128.0.0.0");
|
TransportAddress t17("128.0.0.0");
|
||||||
assert(t17.getIP() == (128 << 24));
|
assert(t17.getIP() == (128u << 24));
|
||||||
assert(!t17.isLAN());
|
assert(!t17.isLAN());
|
||||||
|
|
||||||
} // unitTesting
|
} // unitTesting
|
||||||
|
@ -88,6 +88,9 @@ private:
|
|||||||
copy(other);
|
copy(other);
|
||||||
} // TransportAddress(const TransportAddress&)
|
} // TransportAddress(const TransportAddress&)
|
||||||
public:
|
public:
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
bool isPublicAddressLAN() const;
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
bool isLAN() const;
|
bool isLAN() const;
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
bool isUnset() const { return m_ip == 0 || m_port == 0; }
|
bool isUnset() const { return m_ip == 0 || m_port == 0; }
|
||||||
|
@ -136,27 +136,6 @@ void CreateServerScreen::onUpdate(float delta)
|
|||||||
if(!STKHost::existHost())
|
if(!STKHost::existHost())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// First check if an error happened while registering the server:
|
|
||||||
// --------------------------------------------------------------
|
|
||||||
const irr::core::stringw &error = STKHost::get()->getErrorMessage();
|
|
||||||
if(error!="")
|
|
||||||
{
|
|
||||||
SFXManager::get()->quickSound("anvil");
|
|
||||||
m_info_widget->setErrorColor();
|
|
||||||
m_info_widget->setText(error, false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise wait till we get an answer from the server:
|
|
||||||
// -----------------------------------------------------
|
|
||||||
if (!LobbyProtocol::get<LobbyProtocol>())
|
|
||||||
{
|
|
||||||
m_info_widget->setDefaultColor();
|
|
||||||
m_info_widget->setText(StringUtils::loadingDots(_("Creating server")),
|
|
||||||
false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//FIXME If we really want a gui, we need to decide what else to do here
|
//FIXME If we really want a gui, we need to decide what else to do here
|
||||||
// For now start the (wrong i.e. client) lobby, to prevent to create
|
// For now start the (wrong i.e. client) lobby, to prevent to create
|
||||||
// a server more than once.
|
// a server more than once.
|
||||||
|
Loading…
Reference in New Issue
Block a user