Add auto start with timeout and player threshold for owner less server

This commit is contained in:
Benau 2018-06-06 01:06:44 +08:00
parent 7093cc2196
commit 5da5a1972f
10 changed files with 150 additions and 20 deletions

View File

@ -14,13 +14,17 @@
</box>
</div>
</div>
<spacer height="10"/>
<spacer height="20"/>
<div width="100%" proportion="1" layout="horizontal-row">
<spacer width="20" height="20"/>
<box proportion="2" height="100%" layout="vertical-row">
<textbox id="chat" width="100%" height="30%"/>
<spacer height="20"/>
<button id="send" height="30%" width="fit" I18N="In the network lobby" text="Send" />
<spacer height="10"/>
<div width="100%" height="30%" proportion="1" layout="horizontal-row">
<button id="send" width="10%" height="fit" I18N="In the network lobby" text="Send" />
<spacer width="10"/>
<label id="timeout-message" width="80%" height="fit"/>
</div>
</box>
<spacer width="40"/>
<buttonbar id="actions" proportion="1" width="75%" height="75%">

View File

@ -727,6 +727,16 @@ namespace UserConfigParams
PARAM_DEFAULT(BoolUserConfigParam(true, "firewalled-server",
&m_network_group, "Disable it to turn off all stun related code "
"in server, for official server hosting use only."));
PARAM_PREFIX FloatUserConfigParam m_start_game_counter
PARAM_DEFAULT(FloatUserConfigParam(30.0f, "start-game-counter",
&m_network_group, "Time to wait before entering kart selection screen "
"if satisfied start-game-threshold below for owner less or ranked "
"server."));
PARAM_PREFIX FloatUserConfigParam m_start_game_threshold
PARAM_DEFAULT(FloatUserConfigParam(0.7f, "start-game-threshold",
&m_network_group, "Only auto start kart selection when number of "
"connected player is larger than max player * this value, for "
"owner less or ranked server, after start-game-counter."));
PARAM_PREFIX StringToUIntUserConfigParam m_server_ban_list
PARAM_DEFAULT(StringToUIntUserConfigParam("server_ban_list",

View File

@ -602,6 +602,7 @@ void cmdLineHelp()
" --no-validation Allow non validated and unencrypted connection in wan.\n"
" --ranked Server will submit ranking to stk addons server.\n"
" You require permission for that.\n"
" --owner-less Race will auto start and no one can kick players in server.\n"
" --no-console-log Does not write messages in the console but to\n"
" stdout.log.\n"
" -h, --help Show this help.\n"
@ -1071,6 +1072,11 @@ int handleCmdLine()
{
NetworkConfig::get()->setValidatedPlayers(true);
NetworkConfig::get()->setRankedServer(true);
NetworkConfig::get()->setOwnerLess(true);
}
if (CommandLine::has("--owner-less"))
{
NetworkConfig::get()->setOwnerLess(true);
}
if (CommandLine::has("--server-id-file", &s))
{

View File

@ -134,6 +134,15 @@ void GameSetup::addServerInfo(NetworkString* ns)
// No extra server info
ns->addUInt8((uint8_t)0);
}
if (NetworkConfig::get()->isOwnerLess())
{
ns->addFloat(UserConfigParams::m_start_game_threshold)
.addFloat(UserConfigParams::m_start_game_counter);
}
else
ns->addFloat(0.0f).addFloat(0.0f);
ns->addUInt8(NetworkConfig::get()->getMaxPlayers());
ns->encodeString(NetworkConfig::get()->getMOTD());
} // addServerInfo

View File

@ -51,6 +51,7 @@ NetworkConfig::NetworkConfig()
m_is_public_server = false;
m_is_ranked_server = false;
m_validated_players = false;
m_owner_less = false;
m_done_adding_network_players = false;
m_max_players = 4;
m_cur_user_id = 0;

View File

@ -93,6 +93,8 @@ private:
/** True if only validated players are allowed to join. */
bool m_validated_players;
bool m_owner_less;
bool m_done_adding_network_players;
/** If this is a server, the server name. */
@ -311,6 +313,10 @@ public:
void setValidatedPlayers(bool val) { m_validated_players = val; }
// ------------------------------------------------------------------------
bool onlyValidatedPlayers() const { return m_validated_players; }
// ------------------------------------------------------------------------
void setOwnerLess(bool val) { m_owner_less = val; }
// ------------------------------------------------------------------------
bool isOwnerLess() const { return m_owner_less; }
}; // class NetworkConfig

View File

@ -494,6 +494,7 @@ void ClientLobby::handleServerInfo(Event* event)
NetworkingLobby::getInstance()->addMoreServerInfo(each_line);
uint8_t extra_server_info = data.getUInt8();
bool grand_prix_started = false;
switch (extra_server_info)
{
case 0:
@ -513,6 +514,7 @@ void ClientLobby::handleServerInfo(Event* event)
case 2:
{
unsigned cur_gp_track = data.getUInt8();
grand_prix_started = cur_gp_track != 0;
unsigned total_gp_track = data.getUInt8();
m_game_setup->setGrandPrixTrack(total_gp_track);
each_line = _("Grand prix progress: %d / %d", cur_gp_track,
@ -521,6 +523,12 @@ void ClientLobby::handleServerInfo(Event* event)
break;
}
}
// Auto start info
float start_threshold = data.getFloat();
float start_timeout = data.getFloat();
unsigned max_player = data.getUInt8();
NetworkingLobby::getInstance()->initAutoStartTimer(grand_prix_started,
start_threshold, start_timeout, max_player);
// MOTD
data.decodeStringW(&str);

View File

@ -142,6 +142,7 @@ void ServerLobby::setup()
resetPeersReady();
m_peers_votes.clear();
m_server_delay = 0.0;
m_timeout.store(std::numeric_limits<float>::max());
Log::info("ServerLobby", "Reset server to initial state.");
} // setup
@ -297,6 +298,31 @@ void ServerLobby::asynchronousUpdate()
}
case ACCEPTING_CLIENTS:
{
if (NetworkConfig::get()->isOwnerLess())
{
auto players = m_game_setup->getPlayers();
if (((float)players.size() >
(float)NetworkConfig::get()->getMaxPlayers() *
UserConfigParams::m_start_game_threshold ||
m_game_setup->isGrandPrixStarted()) &&
m_timeout.load() == std::numeric_limits<float>::max())
{
m_timeout.store((float)StkTime::getRealTime() +
UserConfigParams::m_start_game_counter);
}
else if ((float)players.size() <
(float)NetworkConfig::get()->getMaxPlayers() *
UserConfigParams::m_start_game_threshold &&
!m_game_setup->isGrandPrixStarted())
{
m_timeout.store(std::numeric_limits<float>::max());
}
if (m_timeout.load() < (float)StkTime::getRealTime())
{
startSelection();
return;
}
}
clearDisconnectedRankedPlayer();
// Only poll the STK server if this is a WAN server.
if (NetworkConfig::get()->isWAN())
@ -573,24 +599,27 @@ void ServerLobby::signalRaceStartToClients()
} // startGame
//-----------------------------------------------------------------------------
/** Instructs all clients to start the kart selection. If event is not NULL,
* the command comes from a client (which needs to be authorised).
/** Instructs all clients to start the kart selection. If event is NULL,
* the command comes from the owner less server.
*/
void ServerLobby::startSelection(const Event *event)
{
if (m_state != ACCEPTING_CLIENTS)
if (event != NULL)
{
Log::warn("ServerLobby",
"Received startSelection while being in state %d",
m_state.load());
return;
}
if (event->getPeerSP() != m_server_owner.lock())
{
Log::warn("ServerLobby",
"Client %lx is not authorised to start selection.",
event->getPeer());
return;
if (m_state != ACCEPTING_CLIENTS)
{
Log::warn("ServerLobby",
"Received startSelection while being in state %d",
m_state.load());
return;
}
if (event->getPeerSP() != m_server_owner.lock())
{
Log::warn("ServerLobby",
"Client %d is not authorised to start selection.",
event->getPeer()->getHostId());
return;
}
}
ProtocolManager::lock()->findAndTerminate(PROTOCOL_CONNECTION);
@ -1347,7 +1376,8 @@ void ServerLobby::updatePlayerList(bool force_update)
void ServerLobby::updateServerOwner()
{
if (m_state.load() < ACCEPTING_CLIENTS ||
m_state.load() > RESULT_DISPLAY)
m_state.load() > RESULT_DISPLAY ||
NetworkConfig::get()->isOwnerLess())
return;
if (!m_server_owner.expired())
return;
@ -1694,8 +1724,8 @@ void ServerLobby::handlePendingConnection()
if (key != m_keys.end() && key->second.m_tried == false)
{
if (decryptConnectionRequest(peer, it->second.second,
key->second.m_aes_key, key->second.m_aes_iv,
online_id, key->second.m_name))
key->second.m_aes_key, key->second.m_aes_iv, online_id,
key->second.m_name))
{
it = m_pending_connection.erase(it);
m_keys.erase(online_id);

View File

@ -67,6 +67,7 @@ NetworkingLobby::NetworkingLobby() : Screen("online/networking_lobby.stkgui")
m_back_widget = NULL;
m_header = NULL;
m_text_bubble = NULL;
m_timeout_message = NULL;
m_exit_widget = NULL;
m_start_button = NULL;
m_player_list = NULL;
@ -91,6 +92,9 @@ void NetworkingLobby::loadedFromFile()
m_text_bubble = getWidget<LabelWidget>("text");
assert(m_text_bubble != NULL);
m_timeout_message = getWidget<LabelWidget>("timeout-message");
assert(m_timeout_message != NULL);
m_chat_box = getWidget<TextBoxWidget>("chat");
assert(m_chat_box != NULL);
@ -131,6 +135,10 @@ void NetworkingLobby::init()
{
Screen::init();
m_cur_starting_timer = m_start_threshold = m_start_timeout =
m_server_max_player = std::numeric_limits<float>::max();
m_timeout_message->setVisible(false);
//I18N: In the networking lobby
m_header->setText(_("Lobby"), false);
m_server_info_height = GUIEngine::getFont()->getDimension(L"X").Height;
@ -199,6 +207,33 @@ void NetworkingLobby::onUpdate(float delta)
{
if (NetworkConfig::get()->isServer())
return;
if (m_timeout_message->isVisible() && m_player_list)
{
float cur_player = (float)(m_player_list->getItemCount());
if (cur_player > m_server_max_player * m_start_threshold &&
m_cur_starting_timer == std::numeric_limits<float>::max())
{
m_cur_starting_timer = m_start_timeout;
}
else if (cur_player < m_server_max_player * m_start_threshold)
{
m_cur_starting_timer = std::numeric_limits<float>::max();
m_timeout_message->setText(L"", true);
}
if (m_cur_starting_timer != std::numeric_limits<float>::max())
{
m_cur_starting_timer -= delta;
if (m_cur_starting_timer < 0.0f)
m_cur_starting_timer = 0.0f;
//I18N: In the networking lobby, display the starting timeout
//for owner-less server
core::stringw msg = _("Game will start after %d second",
(int)m_cur_starting_timer);
m_timeout_message->setText(msg, true);
}
}
if (m_state == LS_ADD_PLAYERS)
{
m_text_bubble->setText(_("Everyone:\nPress the 'Select' button to "
@ -419,3 +454,18 @@ void NetworkingLobby::cleanAddedPlayers()
return;
m_player_list->clear();
} // cleanAddedPlayers
// ----------------------------------------------------------------------------
void NetworkingLobby::initAutoStartTimer(bool grand_prix_started,
float start_threshold,
float start_timeout,
unsigned server_max_player)
{
if (start_threshold == 0.0f || start_timeout == 0.0f)
return;
m_timeout_message->setVisible(true);
m_start_threshold = grand_prix_started ? 0.0f : start_threshold;
m_start_timeout = start_timeout;
m_server_max_player = (float)server_max_player;
} // initAutoStartTimer

View File

@ -67,9 +67,13 @@ private:
std::vector<core::stringw> m_server_info;
int m_server_info_height;
float m_cur_starting_timer, m_start_threshold, m_start_timeout,
m_server_max_player;
GUIEngine::IconButtonWidget* m_back_widget;
GUIEngine::LabelWidget* m_header;
GUIEngine::LabelWidget* m_text_bubble;
GUIEngine::LabelWidget* m_timeout_message;
GUIEngine::IconButtonWidget* m_exit_widget;
GUIEngine::IconButtonWidget* m_start_button;
GUIEngine::ListWidget* m_player_list;
@ -126,6 +130,8 @@ public:
void addSplitscreenPlayer(irr::core::stringw name);
void cleanAddedPlayers();
uint32_t getServerPing() const;
void initAutoStartTimer(bool grand_prix_started, float start_threshold,
float start_timeout, unsigned server_max_player);
}; // class NetworkingLobby
#endif