Get private port and server id from file

This commit is contained in:
Benau 2018-09-06 08:33:11 +08:00
parent a60a84b05a
commit a5c9bbd3ef
8 changed files with 106 additions and 56 deletions

View File

@ -198,7 +198,8 @@ public:
void redirectOutput();
bool fileIsNewer(const std::string& f1, const std::string& f2) const;
// ------------------------------------------------------------------------
const std::string& getUserConfigDir() const { return m_user_config_dir; }
// ------------------------------------------------------------------------
/** Returns the irrlicht file system. */
irr::io::IFileSystem* getFileSystem() { return m_file_system; }

View File

@ -78,14 +78,77 @@ void 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() ||
STKHost::get()->isClientServer()) ?
m_state = NetworkConfig::get()->isLAN() ?
GOT_SERVER_ADDRESS : SET_PUBLIC_ADDRESS;
} // setup
// ----------------------------------------------------------------------------
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;
}
}
}
switch(m_state.load())
{
case SET_PUBLIC_ADDRESS:
@ -143,7 +206,8 @@ void ConnectToServer::asynchronousUpdate()
}
// Assume official server is firewall-less so give it more time
// to directly connect
if (handleDirectConnect(m_server->isOfficial() ? 5000 : 2000))
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() ?
@ -299,9 +363,9 @@ bool ConnectToServer::handleDirectConnect(int timeout)
{
// 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 ((NetworkConfig::get()->isWAN() &&
m_server->getPrivatePort() == m_server->getAddress().getPort()) ||
STKHost::get()->isClientServer())
{
ENetEvent event;
ENetAddress ea;

View File

@ -73,29 +73,10 @@ void RequestConnection::asynchronousUpdate()
Log::info("RequestConnection",
"LAN connection to WAN server will be used.");
}
if (STKHost::get()->isClientServer())
{
// Allow up to 10 seconds for the separate process to
// fully start-up
uint64_t timeout = StkTime::getRealTimeMs() + 10000;
while (StkTime::getRealTimeMs() < timeout)
{
const std::string& sid = NetworkConfig::get()
->getServerIdFile();
assert(!sid.empty());
if (file_manager->fileExists(sid))
{
file_manager->removeFile(sid);
break;
}
StkTime::sleep(10);
}
NetworkConfig::get()->setServerIdFile("");
}
std::string str_msg("connection-request");
BareNetworkString message(str_msg +
(STKHost::get()->isClientServer() ? "-localhost" :
StringUtils::toString(m_server->getPrivatePort())));
StringUtils::toString(m_server->getPrivatePort()));
if (!NetworkConfig::m_disable_lan &&
m_server->getAddress().getIP() ==

View File

@ -106,6 +106,7 @@ ServerLobby::ServerLobby() : LobbyProtocol(NULL)
m_result_ns = getNetworkString();
m_result_ns->setSynchronous(true);
m_waiting_for_reset = false;
m_server_id_online = 0;
} // ServerLobby
//-----------------------------------------------------------------------------
@ -338,10 +339,12 @@ bool ServerLobby::notifyEventAsynchronous(Event* event)
/** Create the server id file to let the graphics server client connect. */
void ServerLobby::createServerIdFile()
{
const std::string& sid = NetworkConfig::get()->getServerIdFile();
std::string sid = NetworkConfig::get()->getServerIdFile();
if (!sid.empty() && !m_has_created_server_id_file)
{
std::fstream fs;
sid += StringUtils::toString(m_server_id_online) + "_" +
StringUtils::toString(STKHost::get()->getPrivatePort());
fs.open(sid, std::ios::out);
fs.close();
m_has_created_server_id_file = true;
@ -703,7 +706,14 @@ bool ServerLobby::registerServer()
if (result->get("success", &rec_success) && rec_success == "yes")
{
Log::info("ServerLobby", "Server is now online.");
const XMLNode* server = result->getNode("server");
assert(server);
const XMLNode* server_info = server->getNode("server-info");
assert(server_info);
server_info->get("id", &m_server_id_online);
assert(m_server_id_online != 0);
Log::info("ServerLobby",
"Server %d is now online.", m_server_id_online);
delete request;
return true;
}

View File

@ -143,6 +143,8 @@ private:
std::atomic<uint32_t> m_waiting_players_counts;
unsigned m_server_id_online;
bool m_registered_for_once_only;
// connection management

View File

@ -149,6 +149,12 @@ public:
std::tuple<int, core::stringw, double, float> > >& getPlayers() const
{ return m_players; }
// ------------------------------------------------------------------------
void setServerId(unsigned id) { m_server_id = id; }
// ------------------------------------------------------------------------
void setPrivatePort(uint16_t port) { m_private_port = port; }
// ------------------------------------------------------------------------
void setSupportsEncryption(bool val) { m_supports_encrytion = val; }
// ------------------------------------------------------------------------
bool searchByName(const std::string& lower_case_word)
{
auto list = StringUtils::split(lower_case_word, ' ', false);

View File

@ -347,16 +347,6 @@ STKHost::~STKHost()
delete m_network;
enet_deinitialize();
delete m_separate_process;
// Always clean up server id file in case client failed to connect
const std::string& sid = NetworkConfig::get()->getServerIdFile();
if (!sid.empty())
{
if (file_manager->fileExists(sid))
{
file_manager->removeFile(sid);
}
NetworkConfig::get()->setServerIdFile("");
}
} // ~STKHost
//-----------------------------------------------------------------------------
@ -1017,7 +1007,6 @@ void STKHost::handleDirectSocketRequest(Network* direct_socket,
message.decodeString(&command);
const std::string connection_cmd = std::string("connection-request") +
StringUtils::toString(m_private_port);
const std::string connection_cmd_localhost("connection-request-localhost");
if (command == "stk-server")
{
@ -1059,19 +1048,6 @@ void STKHost::handleDirectSocketRequest(Network* direct_socket,
}
std::make_shared<ConnectToPeer>(sender)->requestStart();
}
else if (command == connection_cmd_localhost)
{
if (sender.getIP() == 0x7f000001)
{
std::make_shared<ConnectToPeer>(sender)->requestStart();
}
else
{
Log::error("STKHost", "Client trying to connect from '%s'",
sender.toString().c_str());
Log::error("STKHost", "which is not localhost - rejected.");
}
}
else if (command == "stk-server-port")
{
BareNetworkString s;

View File

@ -316,8 +316,18 @@ void CreateServerScreen::createServer()
server_cfg << "--lan-server=" << server_name;
}
std::string server_id_file = "server_id_file_";
server_id_file += StringUtils::toString(StkTime::getTimeSinceEpoch());
// Clear previous stk-server-id-file_*
std::set<std::string> files;
const std::string server_id_file = "stk-server-id-file_";
file_manager->listFiles(files, file_manager->getUserConfigDir());
for (auto& f : files)
{
if (f.find(server_id_file) != std::string::npos)
{
file_manager->removeFile(file_manager->getUserConfigDir() + "/" +
f);
}
}
NetworkConfig::get()->setServerIdFile(
file_manager->getUserConfigFile(server_id_file));