Use only official tracks for default vote

So network AI won't have trouble finishing some bad wip / addons tracks
This commit is contained in:
Benau 2018-12-20 15:42:10 +08:00
parent 57765c98bf
commit 7954b118a8
2 changed files with 87 additions and 29 deletions

View File

@ -141,6 +141,7 @@ ServerLobby::ServerLobby() : LobbyProtocol(NULL)
m_server_id_online.store(0); m_server_id_online.store(0);
m_difficulty.store(ServerConfig::m_server_difficulty); m_difficulty.store(ServerConfig::m_server_difficulty);
m_game_mode.store(ServerConfig::m_server_mode); m_game_mode.store(ServerConfig::m_server_mode);
m_default_vote = new PeerVote();
} // ServerLobby } // ServerLobby
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -156,9 +157,12 @@ ServerLobby::~ServerLobby()
delete m_result_ns; delete m_result_ns;
if (m_save_server_config) if (m_save_server_config)
ServerConfig::writeServerConfigToDisk(); ServerConfig::writeServerConfigToDisk();
delete m_default_vote;
} // ~ServerLobby } // ~ServerLobby
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
/** Called whenever server is reset or game mode is changed.
*/
void ServerLobby::updateTracksForMode() void ServerLobby::updateTracksForMode()
{ {
auto all_t = track_manager->getAllTrackIdentifiers(); auto all_t = track_manager->getAllTrackIdentifiers();
@ -536,7 +540,8 @@ void ServerLobby::asynchronousUpdate()
case SELECTING: case SELECTING:
{ {
PeerVote winner_vote; PeerVote winner_vote;
bool all_votes_in = handleAllVotes(&winner_vote); uint32_t winner_peer_id = std::numeric_limits<uint32_t>::max();
bool all_votes_in = handleAllVotes(&winner_vote, &winner_peer_id);
if (isVotingOver() || all_votes_in) if (isVotingOver() || all_votes_in)
{ {
m_game_setup->setRace(winner_vote); m_game_setup->setRace(winner_vote);
@ -930,25 +935,6 @@ void ServerLobby::startSelection(const Event *event)
} }
} }
if (!allowJoinedPlayersWaiting())
{
ProtocolManager::lock()->findAndTerminate(PROTOCOL_CONNECTION);
if (NetworkConfig::get()->isWAN())
{
unregisterServer(false/*now*/);
}
}
startVotingPeriod(ServerConfig::m_voting_timeout);
NetworkString *ns = getNetworkString(1);
// Start selection - must be synchronous since the receiver pushes
// a new screen, which must be done from the main thread.
ns->setSynchronous(true);
ns->addUInt8(LE_START_SELECTION)
.addFloat(ServerConfig::m_voting_timeout)
.addUInt8(m_game_setup->isGrandPrixStarted() ? 1 : 0)
.addUInt8(ServerConfig::m_auto_game_time_ratio > 0.0f ? 1 : 0);
// Remove karts / tracks from server that are not supported on all clients // Remove karts / tracks from server that are not supported on all clients
std::set<std::string> karts_erase, tracks_erase; std::set<std::string> karts_erase, tracks_erase;
auto peers = STKHost::get()->getPeers(); auto peers = STKHost::get()->getPeers();
@ -982,6 +968,77 @@ void ServerLobby::startSelection(const Event *event)
it++; it++;
} }
} }
// Default vote use only official tracks to prevent network AI cannot
// finish some bad wip / addons tracks
std::set<std::string> official_tracks = m_official_kts.second;
std::set<std::string>::iterator it = official_tracks.begin();
while (it != official_tracks.end())
{
if (m_available_kts.second.find(*it) == m_available_kts.second.end())
{
it = official_tracks.erase(it);
}
else
it++;
}
if (official_tracks.empty())
{
Log::error("ServerLobby", "No official tracks for playing!");
return;
}
RandomGenerator rg;
it = official_tracks.begin();
std::advance(it, rg.get((int)official_tracks.size()));
m_default_vote->m_track_name = *it;
switch (race_manager->getMinorMode())
{
case RaceManager::MINOR_MODE_NORMAL_RACE:
case RaceManager::MINOR_MODE_TIME_TRIAL:
case RaceManager::MINOR_MODE_FOLLOW_LEADER:
{
Track* t = track_manager->getTrack(*it);
assert(t);
m_default_vote->m_num_laps = t->getDefaultNumberOfLaps();
m_default_vote->m_reverse =
m_default_vote->m_track_name.size() % 2 == 0;
break;
}
case RaceManager::MINOR_MODE_FREE_FOR_ALL:
case RaceManager::MINOR_MODE_CAPTURE_THE_FLAG:
{
m_default_vote->m_num_laps = 0;
m_default_vote->m_reverse = 0;
break;
}
case RaceManager::MINOR_MODE_SOCCER:
{
m_default_vote->m_num_laps = 3;
m_default_vote->m_reverse = 0;
break;
}
default:
assert(false);
break;
}
if (!allowJoinedPlayersWaiting())
{
ProtocolManager::lock()->findAndTerminate(PROTOCOL_CONNECTION);
if (NetworkConfig::get()->isWAN())
{
unregisterServer(false/*now*/);
}
}
startVotingPeriod(ServerConfig::m_voting_timeout);
NetworkString *ns = getNetworkString(1);
// Start selection - must be synchronous since the receiver pushes
// a new screen, which must be done from the main thread.
ns->setSynchronous(true);
ns->addUInt8(LE_START_SELECTION)
.addFloat(ServerConfig::m_voting_timeout)
.addUInt8(m_game_setup->isGrandPrixStarted() ? 1 : 0)
.addUInt8(ServerConfig::m_auto_game_time_ratio > 0.0f ? 1 : 0);
const auto& all_k = m_available_kts.first; const auto& all_k = m_available_kts.first;
const auto& all_t = m_available_kts.second; const auto& all_t = m_available_kts.second;
@ -2028,8 +2085,10 @@ void ServerLobby::handlePlayerVote(Event* event)
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
/** Select the track to be used based on all votes being received. /** Select the track to be used based on all votes being received.
* \param winner_vote The PeerVote that was picked. * \param winner_vote The PeerVote that was picked.
* \param winner_peer_id The host id of winner (unchanged if no vote).
*/ */
bool ServerLobby::handleAllVotes(PeerVote *winner_vote) bool ServerLobby::handleAllVotes(PeerVote* winner_vote,
uint32_t* winner_peer_id)
{ {
// First remove all votes from disconnected hosts // First remove all votes from disconnected hosts
auto it = m_peers_votes.begin(); auto it = m_peers_votes.begin();
@ -2055,12 +2114,7 @@ bool ServerLobby::handleAllVotes(PeerVote *winner_vote)
if (cur_players == 0 || m_peers_votes.size() < cur_players) if (cur_players == 0 || m_peers_votes.size() < cur_players)
{ {
// Default settings if no votes at all // Default settings if no votes at all
RandomGenerator rg; *winner_vote = *m_default_vote;
std::set<std::string>::iterator it = m_available_kts.second.begin();
std::advance(it, rg.get((int)m_available_kts.second.size()));
winner_vote->m_track_name = *it;
winner_vote->m_num_laps = UserConfigParams::m_num_laps;
winner_vote->m_reverse = winner_vote->m_track_name.size() % 2 == 0;
return false; return false;
} }
@ -2070,6 +2124,7 @@ bool ServerLobby::handleAllVotes(PeerVote *winner_vote)
auto vote = m_peers_votes.begin(); auto vote = m_peers_votes.begin();
std::advance(vote, r.get(m_peers_votes.size()) ); std::advance(vote, r.get(m_peers_votes.size()) );
*winner_peer_id = vote->first;
*winner_vote = vote->second; *winner_vote = vote->second;
// For now: don't trigger start of race if all votes // For now: don't trigger start of race if all votes
@ -2077,7 +2132,7 @@ bool ServerLobby::handleAllVotes(PeerVote *winner_vote)
// return m_peers_votes.size() == cur_players; // return m_peers_votes.size() == cur_players;
// to start the race when all votes have been received. // to start the race when all votes have been received.
return false; return false;
} // handleAllVotes } // handleAllVotes
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

View File

@ -163,6 +163,9 @@ private:
bool m_save_server_config; bool m_save_server_config;
// Default game settings if no one has ever vote
PeerVote* m_default_vote;
// connection management // connection management
void clientDisconnected(Event* event); void clientDisconnected(Event* event);
void connectionRequested(Event* event); void connectionRequested(Event* event);
@ -243,7 +246,7 @@ private:
const std::string& iv, const std::string& iv,
uint32_t online_id, uint32_t online_id,
const irr::core::stringw& online_name); const irr::core::stringw& online_name);
bool handleAllVotes(PeerVote *winner); bool handleAllVotes(PeerVote* winner, uint32_t* winner_peer_id);
void getRankingForPlayer(std::shared_ptr<NetworkPlayerProfile> p); void getRankingForPlayer(std::shared_ptr<NetworkPlayerProfile> p);
void submitRankingsToAddons(); void submitRankingsToAddons();
void computeNewRankings(); void computeNewRankings();