Simplify STUN and LAN connection

Using enet intercept directly
This commit is contained in:
Benau 2018-09-07 01:40:32 +08:00
parent 3cdc1b6ddd
commit 88e1733d50
13 changed files with 206 additions and 482 deletions

View File

@ -1,5 +1,5 @@
# Modify this file to change the last-modified date when you add/remove a file.
# This will then trigger a new cmake run automatically.
# This will then trigger a new cmake run automatically.
file(GLOB_RECURSE STK_HEADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/*.hpp")
file(GLOB_RECURSE STK_SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/*.cpp")
file(GLOB_RECURSE STK_SHADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "data/shaders/*")

View File

@ -608,7 +608,6 @@ void cmdLineHelp()
" --init-user Save the above login and password (if set) in config.\n"
" --disable-polling Don't poll for logged in user.\n"
" --port=n Port number to use.\n"
" --disable-lan Disable LAN detection (connect using WAN).\n"
" --auto-connect Automatically connect to fist server and start race\n"
" --max-players=n Maximum number of clients (server only).\n"
" --min-players=n Minimum number of clients (server only).\n"
@ -1204,7 +1203,7 @@ int handleCmdLine()
cts->setup();
Log::info("main", "Trying to connect to server '%s'.",
server_addr.toString().c_str());
if (!cts->handleDirectConnect(10000))
if (!cts->tryConnect(2000, 15))
{
Log::error("main", "Timeout trying to connect to server '%s'.",
server_addr.toString().c_str());
@ -1356,11 +1355,6 @@ int handleCmdLine()
if (server_lobby)
server_lobby->requestStart();
/** 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"))
NetworkConfig::m_disable_lan = true;
// Race parameters
if(CommandLine::has("--kartsize-debug"))
{

View File

@ -28,7 +28,6 @@
#include "states_screens/online_screen.hpp"
NetworkConfig *NetworkConfig::m_network_config = NULL;
bool NetworkConfig::m_disable_lan = false;
const uint32_t NetworkConfig::m_server_version = 1;
/** \class NetworkConfig

View File

@ -124,10 +124,6 @@ private:
uint32_t m_joined_server_version;
public:
/** Stores the command line flag to disable lan detection (i.e. force
* WAN code to be used when connection client and server). */
static bool m_disable_lan;
/** Server version, will be advanced if there are protocol changes. */
static const uint32_t m_server_version;

View File

@ -59,13 +59,15 @@ void ConnectToPeer::asynchronousUpdate()
{
m_timer = StkTime::getRealTimeMs();
// 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.
// the client will use enet intercept to discover if server
// address or port is different from stk addons database.
// (Happens if there is firewall in between)
TransportAddress broadcast_address;
broadcast_address = m_peer_address;
BareNetworkString aloha(std::string("aloha_stk"));
// Enet packet will not have 0xFFFF for first 2 bytes
BareNetworkString aloha("aloha-stk");
aloha.getBuffer().insert(aloha.getBuffer().begin(), 2, 0xFF);
STKHost::get()->sendRawPacket(aloha, broadcast_address);
Log::verbose("ConnectToPeer", "Broadcast aloha sent.");
StkTime::sleep(1);

View File

@ -23,13 +23,13 @@
#include "network/event.hpp"
#include "network/network.hpp"
#include "network/network_config.hpp"
#include "network/protocols/request_connection.hpp"
#include "network/protocols/client_lobby.hpp"
#include "network/protocol_manager.hpp"
#include "network/servers_manager.hpp"
#include "network/server.hpp"
#include "network/stk_host.hpp"
#include "network/stk_peer.hpp"
#include "online/xml_request.hpp"
#include "states_screens/networking_lobby.hpp"
#include "utils/time.hpp"
#include "utils/log.hpp"
@ -37,6 +37,9 @@
#include <algorithm>
// ============================================================================
std::weak_ptr<bool> ConnectToServer::m_previous_unjoin;
TransportAddress ConnectToServer::m_server_address;
int ConnectToServer::m_retry_count = 0;
bool ConnectToServer::m_done_intecept = false;
// ----------------------------------------------------------------------------
/** Specify server to connect to.
* \param server Server to connect to (if nullptr than we use quick play).
@ -49,7 +52,6 @@ ConnectToServer::ConnectToServer(std::shared_ptr<Server> server)
m_server = server;
m_server_address = m_server->getAddress();
}
setHandleConnections(true);
} // ConnectToServer(server, host)
// ----------------------------------------------------------------------------
@ -75,78 +77,77 @@ ConnectToServer::~ConnectToServer()
void ConnectToServer::setup()
{
Log::info("ConnectToServer", "SETUP");
m_current_protocol.reset();
// In case of LAN or client-server 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 : SET_PUBLIC_ADDRESS;
} // setup
// ----------------------------------------------------------------------------
void ConnectToServer::getClientServerInfo()
{
assert(m_server);
// Allow up to 10 seconds for the separate process to fully start-up
bool started = false;
uint64_t timeout = StkTime::getRealTimeMs() + 10000;
const std::string& sid = NetworkConfig::get()->getServerIdFile();
assert(!sid.empty());
const std::string dir = StringUtils::getPath(sid);
const std::string server_id_file = StringUtils::getBasename(sid);
uint16_t port = 0;
unsigned server_id = 0;
while (StkTime::getRealTimeMs() < timeout)
{
std::set<std::string> files;
file_manager->listFiles(files, dir);
for (auto& f : files)
{
if (f.find(server_id_file) != std::string::npos)
{
auto split = StringUtils::split(f, '_');
if (split.size() != 3)
continue;
if (!StringUtils::fromString(split[1], server_id))
continue;
if (!StringUtils::fromString(split[2], port))
continue;
file_manager->removeFile(dir + "/" + f);
started = true;
break;
}
}
if (started)
break;
StkTime::sleep(10);
}
NetworkConfig::get()->setServerIdFile("");
if (!started)
{
Log::error("ConnectToServer",
"Separate server process failed to started");
m_state = DONE;
return;
}
else
{
assert(port != 0);
m_server_address.setPort(port);
m_server->setPrivatePort(port);
if (server_id != 0)
{
m_server->setSupportsEncryption(true);
m_server->setServerId(server_id);
}
}
} // getClientServerInfo
// ----------------------------------------------------------------------------
void ConnectToServer::asynchronousUpdate()
{
if (STKHost::get()->isClientServer() &&
!NetworkConfig::get()->getServerIdFile().empty())
{
assert(m_server);
// Allow up to 10 seconds for the separate process to fully start-up
bool started = false;
uint64_t timeout = StkTime::getRealTimeMs() + 10000;
const std::string& sid = NetworkConfig::get()->getServerIdFile();
assert(!sid.empty());
const std::string dir = StringUtils::getPath(sid);
const std::string server_id_file = StringUtils::getBasename(sid);
uint16_t port = 0;
unsigned server_id = 0;
while (StkTime::getRealTimeMs() < timeout)
{
std::set<std::string> files;
file_manager->listFiles(files, dir);
for (auto& f : files)
{
if (f.find(server_id_file) != std::string::npos)
{
auto split = StringUtils::split(f, '_');
if (split.size() != 3)
continue;
if (!StringUtils::fromString(split[1], server_id))
continue;
if (!StringUtils::fromString(split[2], port))
continue;
file_manager->removeFile(dir + "/" + f);
started = true;
break;
}
}
if (started)
break;
StkTime::sleep(10);
}
NetworkConfig::get()->setServerIdFile("");
if (!started)
{
Log::error("ConnectToServer",
"Separate server process failed to started");
m_state = DONE;
return;
}
else
{
assert(port != 0);
m_server_address.setPort(port);
m_server->setPrivatePort(port);
if (server_id != 0)
{
m_server->setSupportsEncryption(true);
m_server->setServerId(server_id);
}
if (NetworkConfig::get()->isLAN() &&
handleDirectConnect(5000))
{
m_state = DONE;
return;
}
}
getClientServerInfo();
}
switch(m_state.load())
@ -204,110 +205,42 @@ void ConnectToServer::asynchronousUpdate()
STKHost::get()->setPublicAddress();
registerWithSTKServer();
}
// Assume official server is firewall-less so give it more time
// to directly connect
if (handleDirectConnect((m_server->isOfficial() ||
STKHost::get()->isClientServer()) ? 5000 : 2000))
return;
// Set to DONE will stop STKHost is not connected
m_state = STKHost::get()->getPublicAddress().isUnset() ?
DONE : GOT_SERVER_ADDRESS;
break;
}
break;
case GOT_SERVER_ADDRESS:
{
assert(m_server);
Log::info("ConnectToServer", "Server's address known");
m_state = REQUESTING_CONNECTION;
auto request_connection =
std::make_shared<RequestConnection>(m_server);
request_connection->requestStart();
m_current_protocol = request_connection;
// Reset timer for next usage
m_timer = 0;
break;
}
case REQUESTING_CONNECTION:
{
if (!m_current_protocol.expired())
{
return;
}
// Server knows we want to connect
Log::info("ConnectToServer", "Connection request made");
if (m_server_address.isUnset())
{
// server data not correct, stop
m_state = DONE;
Log::error("ConnectToServer", "Server address is %s",
m_server_address.toString().c_str());
return;
}
if (m_tried_connection++ > 7)
{
if (NetworkConfig::get()->isWAN())
{
Log::warn("ConnectToServer", "Timeout waiting for"
" aloha, trying to connect anyway.");
m_state = CONNECTING;
// Reset timer for next usage
m_timer = 0;
m_tried_connection = 0;
}
else
m_state = DONE;
return;
}
if ((!NetworkConfig::m_disable_lan &&
if (!STKHost::get()->isClientServer() &&
m_server_address.getIP() ==
STKHost::get()->getPublicAddress().getIP()) ||
(NetworkConfig::get()->isLAN() ||
STKHost::get()->isClientServer()))
STKHost::get()->getPublicAddress().getIP())
{
// 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 (StkTime::getRealTimeMs() > m_timer + 2000)
Log::info("ConnectToServer", "Server is in the same lan");
std::string str_msg("connection-request");
BareNetworkString message(str_msg +
StringUtils::toString(m_server->getPrivatePort()));
// If use lan connection for wan server, send to all broadcast
// addresses
for (auto& addr :
ServersManager::get()->getBroadcastAddresses())
{
m_timer = StkTime::getRealTimeMs();
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
{
// Every 5 seconds
if (StkTime::getRealTimeMs() > m_timer + 5000)
{
m_timer = StkTime::getRealTimeMs();
STKHost::get()->stopListening();
STKHost::get()->connect(m_server_address);
STKHost::get()->startListening();
Log::info("ConnectToServer", "Trying to connect to %s",
m_server_address.toString().c_str());
if (m_tried_connection++ > 1)
{
Log::error("ConnectToServer", "Timeout connect to %s",
m_server_address.toString().c_str());
m_state = DONE;
for (int i = 0; i < 5; i++)
{
STKHost::get()->sendRawPacket(message, addr);
StkTime::sleep(1);
}
}
}
break;
}
case CONNECTED:
{
Log::info("ConnectToServer", "Connected");
m_state = DONE;
// 30 seconds connecting timeout total, use another port to try
// direct connection to server first, if failed than use the one
// that has stun mapped, the first 8 seconds allow the server to
// start the connect to peer protocol first before the port is
// remapped
if (tryConnect(2000, 4, true/*another_port*/))
break;
if (!tryConnect(2000, 11))
m_state = DONE;
break;
}
case DONE:
@ -321,8 +254,7 @@ void ConnectToServer::update(int ticks)
{
switch(m_state.load())
{
case REQUESTING_CONNECTION:
case CONNECTING:
case GOT_SERVER_ADDRESS:
{
// Make sure lobby display the quick play server name
assert(m_server);
@ -359,65 +291,103 @@ void ConnectToServer::update(int ticks)
} // update
// ----------------------------------------------------------------------------
bool ConnectToServer::handleDirectConnect(int timeout)
/** Intercept callback in enet to allow change server address and port if
* needed (Happens when there is firewall in between)
*/
int ConnectToServer::interceptCallback(ENetHost* host, ENetEvent* event)
{
// Direct connection to server should only possbile if public and private
// ports of server are the same
if ((NetworkConfig::get()->isWAN() &&
m_server->getPrivatePort() == m_server->getAddress().getPort()) ||
STKHost::get()->isClientServer())
if (m_done_intecept)
return 0;
// The first two bytes of a valid ENet protocol packet will never be 0xFFFF
// and then try decode the string "aloha-stk"
if (host->receivedDataLength == 12 &&
host->receivedData[0] == 0xFF && host->receivedData[1] == 0xFF &&
host->receivedData[2] == 0x09 && host->receivedData[3] == 'a' &&
host->receivedData[4] == 'l' && host->receivedData[5] == 'o' &&
host->receivedData[6] == 'h' && host->receivedData[7] == 'a' &&
host->receivedData[8] == '-' && host->receivedData[9] == 's' &&
host->receivedData[10] == 't' && host->receivedData[11] == 'k')
{
ENetEvent event;
ENetAddress ea;
ea.host = STKHost::HOST_ANY;
ea.port = STKHost::PORT_ANY;
Network* dc = new Network(/*peer_count*/1,
/*channel_limit*/EVENT_CHANNEL_COUNT,
/*max_in_bandwidth*/0, /*max_out_bandwidth*/0, &ea,
true/*change_port_if_bound*/);
assert(dc);
if (m_server_address.getPort() == 0)
TransportAddress server_addr = host->receivedAddress;
if (server_addr != m_server_address)
{
// Get the server port of server from (common) server discovery port
Log::info("ConnectToServer", "Detect port for server address.");
BareNetworkString s(std::string("stk-server-port"));
TransportAddress address(m_server_address.getIP(),
NetworkConfig::get()->getServerDiscoveryPort());
dc->sendRawPacket(s, address);
TransportAddress sender;
const int LEN = 2048;
char buffer[LEN];
int len = dc->receiveRawPacket(buffer, LEN, &sender, 2000);
if (len != 2)
{
Log::error("ConnectToServer", "Invalid port number");
delete dc;
return false;
}
BareNetworkString server_port(buffer, len);
uint16_t port = server_port.getUInt16();
m_server_address.setPort(port);
Log::info("ConnectToServer", "Using new server address %s",
server_addr.toString().c_str());
m_retry_count = 15;
m_server_address = server_addr;
m_done_intecept = true;
return 1;
}
ENetPeer* p = dc->connectTo(m_server_address);
if (p)
{
while (enet_host_service(dc->getENetHost(), &event, timeout) != 0)
{
if (event.type == ENET_EVENT_TYPE_CONNECT)
{
Log::info("ConnectToServer",
"Direct connection to %s succeed",
m_server_address.toString().c_str());
STKHost::get()->replaceNetwork(event, dc);
m_state = DONE;
return true;
}
}
}
delete dc;
}
// 0 means let enet handle this packet
return 0;
} // interceptCallback
// ----------------------------------------------------------------------------
bool ConnectToServer::tryConnect(int timeout, int retry, bool another_port)
{
m_retry_count = retry;
ENetEvent event;
ENetAddress ea;
ea.host = STKHost::HOST_ANY;
ea.port = STKHost::PORT_ANY;
Network* nw = another_port ? new Network(/*peer_count*/1,
/*channel_limit*/EVENT_CHANNEL_COUNT,
/*max_in_bandwidth*/0, /*max_out_bandwidth*/0, &ea,
true/*change_port_if_bound*/) : STKHost::get()->getNetwork();
assert(nw);
if (m_server_address.getPort() == 0)
{
// Get the server port of server from (common) server discovery port
Log::info("ConnectToServer", "Detect port for server address.");
BareNetworkString s(std::string("stk-server-port"));
TransportAddress address(m_server_address.getIP(),
NetworkConfig::get()->getServerDiscoveryPort());
nw->sendRawPacket(s, address);
TransportAddress sender;
const int LEN = 2048;
char buffer[LEN];
int len = nw->receiveRawPacket(buffer, LEN, &sender, 2000);
if (len != 2)
{
Log::error("ConnectToServer", "Invalid port number");
return false;
}
BareNetworkString server_port(buffer, len);
uint16_t port = server_port.getUInt16();
m_server_address.setPort(port);
}
m_done_intecept = false;
nw->getENetHost()->intercept = ConnectToServer::interceptCallback;
while (--m_retry_count >= 0 && !ProtocolManager::lock()->isExiting())
{
ENetPeer* p = nw->connectTo(m_server_address);
if (!p)
break;
Log::info("ConnectToServer", "Trying connecting to %s from port %d, "
"retry remain: %d", m_server_address.toString().c_str(),
nw->getENetHost()->address.port, m_retry_count);
while (enet_host_service(nw->getENetHost(), &event, timeout) != 0)
{
if (event.type == ENET_EVENT_TYPE_CONNECT)
{
Log::info("ConnectToServer", "Connected to %s",
m_server_address.toString().c_str());
nw->getENetHost()->intercept = NULL;
STKHost::get()->initClientNetwork(event, nw);
m_state = DONE;
return true;
}
}
// Reset old peer in case server address differs due to intercept
enet_peer_reset(p);
}
if (another_port)
delete nw;
return false;
} // handleDirectConnect
} // tryConnect
// ----------------------------------------------------------------------------
/** Register this client with the STK server.
@ -452,7 +422,7 @@ void ConnectToServer::registerWithSTKServer()
// network requests
request->executeNow();
const XMLNode * result = request->getXMLData();
const XMLNode* result = request->getXMLData();
std::string success;
if(result->get("success", &success) && success == "yes")
@ -469,64 +439,3 @@ void ConnectToServer::registerWithSTKServer()
delete request;
} // registerWithSTKServer
// ----------------------------------------------------------------------------
/** Called when the server is on the same LAN. It uses broadcast to
* find and conntect to the server. For WAN game, it makes sure server recieve
* request from stk addons first before continuing.
*/
void ConnectToServer::waitingAloha(bool is_wan)
{
// just send a broadcast packet, the client will know our
// ip address and will connect
STKHost::get()->stopListening(); // stop the listening
Log::info("ConnectToServer", "Waiting broadcast message.");
TransportAddress sender;
// get the sender
const int LEN=256;
char buffer[LEN];
int len = STKHost::get()->receiveRawPacket(buffer, LEN, &sender, 2000);
if(len<0)
{
Log::warn("ConnectToServer",
"Received invalid server information message.");
return;
}
BareNetworkString message(buffer, len);
std::string received;
message.decodeString(&received);
std::string aloha("aloha_stk");
if (received==aloha)
{
Log::info("ConnectToServer", "Server found : %s",
sender.toString().c_str());
if (!is_wan)
{
if (sender.isPublicAddressLocalhost())
sender.setIP(0x7f000001); // 127.0.0.1
}
m_server_address = sender;
m_state = CONNECTING;
// Reset timer for next usage
m_timer = 0;
m_tried_connection = 0;
}
} // waitingAloha
// ----------------------------------------------------------------------------
bool ConnectToServer::notifyEventAsynchronous(Event* event)
{
if (event->getType() == EVENT_TYPE_CONNECTED)
{
Log::info("ConnectToServer", "The Connect To Server protocol has "
"received an event notifying that he's connected to the peer.");
// We received a message and connected, no need to check for address
// as only 1 peer possible in client
m_state = CONNECTED;
}
return true;
} // notifyEventAsynchronous

View File

@ -31,39 +31,32 @@ class Server;
class ConnectToServer : public Protocol
{
private:
uint64_t m_timer = 0;
TransportAddress m_server_address;
std::shared_ptr<Server> m_server;
unsigned m_tried_connection = 0;
/** Protocol currently being monitored. */
std::weak_ptr<Protocol> m_current_protocol;
/** State for finite state machine. */
enum ConnectState : unsigned int
{
SET_PUBLIC_ADDRESS,
GOT_SERVER_ADDRESS,
REQUESTING_CONNECTION,
CONNECTING,
CONNECTED,
DONE,
EXITING
};
std::atomic<ConnectState> m_state;
void getClientServerInfo();
void registerWithSTKServer();
void waitingAloha(bool is_wan);
static TransportAddress m_server_address;
static int interceptCallback(ENetHost* host, ENetEvent* event);
static int m_retry_count;
static bool m_done_intecept;
public:
static std::weak_ptr<bool> m_previous_unjoin;
ConnectToServer(std::shared_ptr<Server> server);
virtual ~ConnectToServer();
virtual bool notifyEventAsynchronous(Event* event) OVERRIDE;
virtual void setup() OVERRIDE;
virtual void asynchronousUpdate() OVERRIDE;
virtual void update(int ticks) OVERRIDE;
bool handleDirectConnect(int timeout);
bool tryConnect(int timeout, int retry, bool another_port = false);
}; // class ConnectToServer

View File

@ -1,124 +0,0 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2013-2015 SuperTuxKart-Team
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "network/protocols/request_connection.hpp"
#include "config/user_config.hpp"
#include "network/network.hpp"
#include "network/network_config.hpp"
#include "network/protocol_manager.hpp"
#include "network/server.hpp"
#include "network/servers_manager.hpp"
#include "network/stk_host.hpp"
#include "online/xml_request.hpp"
#include "utils/string_utils.hpp"
using namespace Online;
/** Constructor. Stores the server id.
* \param server Server to be joined.
*/
RequestConnection::RequestConnection(std::shared_ptr<Server> server)
: Protocol(PROTOCOL_SILENT)
{
m_server = server;
} // RequestConnection
// ----------------------------------------------------------------------------
RequestConnection::~RequestConnection()
{
} // ~RequestConnection
// ----------------------------------------------------------------------------
/** Setup of this request, sets state to none.
*/
void RequestConnection::setup()
{
m_state = NONE;
} // setup
// ----------------------------------------------------------------------------
/** This implements a finite state machine to monitor the server join
* request asynchronously.
*/
void RequestConnection::asynchronousUpdate()
{
switch (m_state)
{
case NONE:
{
if ((!NetworkConfig::m_disable_lan &&
m_server->getAddress().getIP() ==
STKHost::get()->getPublicAddress().getIP()) ||
(NetworkConfig::get()->isLAN() ||
STKHost::get()->isClientServer()))
{
if (NetworkConfig::get()->isWAN())
{
Log::info("RequestConnection",
"LAN connection to WAN server will be used.");
}
std::string str_msg("connection-request");
BareNetworkString message(str_msg +
StringUtils::toString(m_server->getPrivatePort()));
if (!NetworkConfig::m_disable_lan &&
m_server->getAddress().getIP() ==
STKHost::get()->getPublicAddress().getIP() &&
!STKHost::get()->isClientServer())
{
// If use lan connection in wan server, send to all
// broadcast address
for (auto& addr :
ServersManager::get()->getBroadcastAddresses())
{
for (int i = 0; i < 5; i++)
{
STKHost::get()->sendRawPacket(message, addr);
StkTime::sleep(1);
}
}
}
else
{
TransportAddress server_addr;
server_addr.setIP(m_server->getAddress().getIP());
// Direct socket always listens on server discovery port
server_addr.setPort(NetworkConfig::get()
->getServerDiscoveryPort());
// Avoid possible packet loss, the connect to peer done by
// server will auto terminate if same peer from same port
// has connected already
for (int i = 0; i < 5; i++)
{
STKHost::get()->sendRawPacket(message, server_addr);
StkTime::sleep(1);
}
}
}
m_state = EXITING;
requestTerminate();
break;
}
case EXITING:
break;
}
} // asynchronousUpdate

View File

@ -1,40 +0,0 @@
#ifndef HEADER_REQUEST_CONNECTION_HPP
#define HEADER_REQUEST_CONNECTION_HPP
#include "network/protocol.hpp"
#include "online/xml_request.hpp"
#include <memory>
class Server;
class RequestConnection : public Protocol
{
protected:
/** Id of the server to join. */
std::shared_ptr<Server> m_server;
enum STATE
{
NONE,
EXITING
};
/** State of this connection. */
STATE m_state;
public:
// ------------------------------------------------------------------------
RequestConnection(std::shared_ptr<Server> server);
virtual ~RequestConnection();
virtual void setup() OVERRIDE;
virtual void asynchronousUpdate() OVERRIDE;
// ------------------------------------------------------------------------
virtual bool notifyEvent(Event* event) OVERRIDE { return true; }
// ------------------------------------------------------------------------
virtual bool notifyEventAsynchronous(Event* event) OVERRIDE { return true; }
// ------------------------------------------------------------------------
virtual void update(int ticks) OVERRIDE {}
}; // RequestConnection
#endif // REQUEST_CONNECTION_HPP

View File

@ -1217,13 +1217,16 @@ std::shared_ptr<STKPeer> STKHost::findPeerByHostId(uint32_t id) const
} // findPeerByHostId
//-----------------------------------------------------------------------------
void STKHost::replaceNetwork(ENetEvent& event, Network* network)
void STKHost::initClientNetwork(ENetEvent& event, Network* new_network)
{
assert(NetworkConfig::get()->isClient());
assert(!m_listening_thread.joinable());
assert(network->getENetHost()->peerCount == 1);
delete m_network;
m_network = network;
assert(new_network->getENetHost()->peerCount == 1);
if (m_network != new_network)
{
delete m_network;
m_network = new_network;
}
auto stk_peer = std::make_shared<STKPeer>(event.peer, this,
m_next_unique_host_id++);
stk_peer->setValidated();

View File

@ -280,6 +280,8 @@ public:
m_network->sendRawPacket(buffer, dst);
} // sendRawPacket
// ------------------------------------------------------------------------
Network* getNetwork() const { return m_network; }
// ------------------------------------------------------------------------
/** Returns a copied list of peers. */
std::vector<std::shared_ptr<STKPeer> > getPeers() const
{
@ -318,7 +320,7 @@ public:
* creation screen. */
bool isClientServer() const { return m_separate_process != NULL; }
// ------------------------------------------------------------------------
void replaceNetwork(ENetEvent& event, Network* network);
void initClientNetwork(ENetEvent& event, Network* new_network);
// ------------------------------------------------------------------------
std::map<uint32_t, uint32_t> getPeerPings()
{ return m_peer_pings.getAtomic(); }

View File

@ -17,20 +17,10 @@
#include "states_screens/online_profile_servers.hpp"
#include "audio/sfx_manager.hpp"
#include "config/player_manager.hpp"
#include "guiengine/engine.hpp"
#include "guiengine/scalable_font.hpp"
#include "guiengine/screen.hpp"
#include "guiengine/widget.hpp"
#include "network/network_config.hpp"
#include "network/protocol_manager.hpp"
#include "network/protocols/connect_to_server.hpp"
#include "network/protocols/request_connection.hpp"
#include "network/servers_manager.hpp"
#include "states_screens/state_manager.hpp"
#include "states_screens/create_server_screen.hpp"
#include "states_screens/networking_lobby.hpp"
#include "states_screens/online_lan.hpp"
#include "states_screens/server_selection.hpp"
#include "utils/translation.hpp"

View File

@ -267,7 +267,7 @@ void OnlineScreen::eventCallback(Widget* widget, const std::string& name,
cts->setup();
Log::info("OnlineScreen", "Trying to connect to server '%s'.",
server_addr.toString().c_str());
if (!cts->handleDirectConnect(10000))
if (!cts->tryConnect(2000, 15))
{
core::stringw err = _("Cannot connect to server %s.",
server_addr.toString().c_str());