Use new method to start game
This commit is contained in:
parent
9a4013843e
commit
50aa334912
@ -224,57 +224,50 @@ void GameSetup::addServerInfo(NetworkString* ns)
|
||||
} // addServerInfo
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void GameSetup::sortPlayersForGrandPrix()
|
||||
void GameSetup::sortPlayersForGrandPrix(
|
||||
std::vector<std::shared_ptr<NetworkPlayerProfile> >& players) const
|
||||
{
|
||||
if (!isGrandPrix())
|
||||
return;
|
||||
std::lock_guard<std::mutex> lock(m_players_mutex);
|
||||
|
||||
if (m_tracks.size() == 1)
|
||||
{
|
||||
std::random_device rd;
|
||||
std::mt19937 g(rd());
|
||||
std::shuffle(m_players.begin(), m_players.end(), g);
|
||||
std::shuffle(players.begin(), players.end(), g);
|
||||
return;
|
||||
}
|
||||
|
||||
std::sort(m_players.begin(), m_players.end(),
|
||||
[](const std::weak_ptr<NetworkPlayerProfile>& a,
|
||||
const std::weak_ptr<NetworkPlayerProfile>& b)
|
||||
std::sort(players.begin(), players.end(),
|
||||
[](const std::shared_ptr<NetworkPlayerProfile>& a,
|
||||
const std::shared_ptr<NetworkPlayerProfile>& b)
|
||||
{
|
||||
// They should be never expired
|
||||
auto c = a.lock();
|
||||
assert(c);
|
||||
auto d = b.lock();
|
||||
assert(d);
|
||||
return (c->getScore() < d->getScore()) ||
|
||||
(c->getScore() == d->getScore() &&
|
||||
c->getOverallTime() > d->getOverallTime());
|
||||
return (a->getScore() < b->getScore()) ||
|
||||
(a->getScore() == b->getScore() &&
|
||||
a->getOverallTime() > b->getOverallTime());
|
||||
});
|
||||
if (UserConfigParams::m_gp_most_points_first)
|
||||
{
|
||||
std::reverse(m_players.begin(), m_players.end());
|
||||
std::reverse(players.begin(), players.end());
|
||||
}
|
||||
} // sortPlayersForGrandPrix
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void GameSetup::sortPlayersForGame()
|
||||
void GameSetup::sortPlayersForGame(
|
||||
std::vector<std::shared_ptr<NetworkPlayerProfile> >& players) const
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_players_mutex);
|
||||
if (!isGrandPrix())
|
||||
{
|
||||
std::random_device rd;
|
||||
std::mt19937 g(rd());
|
||||
std::shuffle(m_players.begin(), m_players.end(), g);
|
||||
std::shuffle(players.begin(), players.end(), g);
|
||||
}
|
||||
if (!race_manager->teamEnabled() ||
|
||||
ServerConfig::m_team_choosing)
|
||||
return;
|
||||
for (unsigned i = 0; i < m_players.size(); i++)
|
||||
for (unsigned i = 0; i < players.size(); i++)
|
||||
{
|
||||
auto player = m_players[i].lock();
|
||||
assert(player);
|
||||
player->setTeam((KartTeam)(i % 2));
|
||||
players[i]->setTeam((KartTeam)(i % 2));
|
||||
}
|
||||
} // sortPlayersForGame
|
||||
|
||||
|
@ -171,9 +171,11 @@ public:
|
||||
// ------------------------------------------------------------------------
|
||||
const std::vector<std::string>& getAllTracks() const { return m_tracks; }
|
||||
// ------------------------------------------------------------------------
|
||||
void sortPlayersForGrandPrix();
|
||||
void sortPlayersForGrandPrix(
|
||||
std::vector<std::shared_ptr<NetworkPlayerProfile> >& players) const;
|
||||
// ------------------------------------------------------------------------
|
||||
void sortPlayersForGame();
|
||||
void sortPlayersForGame(
|
||||
std::vector<std::shared_ptr<NetworkPlayerProfile> >& players) const;
|
||||
// ------------------------------------------------------------------------
|
||||
void setHitCaptureTime(int hc, float time)
|
||||
{
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "karts/controller/player_controller.hpp"
|
||||
#include "karts/kart_properties.hpp"
|
||||
#include "karts/kart_properties_manager.hpp"
|
||||
#include "modes/capture_the_flag.hpp"
|
||||
#include "modes/linear_world.hpp"
|
||||
#include "network/crypto.hpp"
|
||||
#include "network/event.hpp"
|
||||
@ -245,7 +246,7 @@ void ServerLobby::updateTracksForMode()
|
||||
void ServerLobby::setup()
|
||||
{
|
||||
LobbyProtocol::setup();
|
||||
auto players = m_game_setup->getConnectedPlayers();
|
||||
auto players = STKHost::get()->getPlayersForNewGame();
|
||||
if (m_game_setup->isGrandPrix() && !m_game_setup->isGrandPrixStarted())
|
||||
{
|
||||
for (auto player : players)
|
||||
@ -490,7 +491,7 @@ void ServerLobby::asynchronousUpdate()
|
||||
if (ServerConfig::m_owner_less)
|
||||
{
|
||||
m_game_setup->update(true/*remove_disconnected_players*/);
|
||||
int player_size = m_game_setup->getPlayerCount();
|
||||
int player_size = STKHost::get()->getPlayersInGame();
|
||||
if ((player_size >= ServerConfig::m_min_start_game_players ||
|
||||
m_game_setup->isGrandPrixStarted()) &&
|
||||
m_timeout.load() == std::numeric_limits<int64_t>::max())
|
||||
@ -545,11 +546,9 @@ void ServerLobby::asynchronousUpdate()
|
||||
if (go_on_race)
|
||||
{
|
||||
m_game_setup->setRace(winner_vote);
|
||||
// Remove disconnected player (if any) one last time
|
||||
m_game_setup->update(true);
|
||||
m_game_setup->sortPlayersForGrandPrix();
|
||||
m_game_setup->sortPlayersForGame();
|
||||
auto players = m_game_setup->getConnectedPlayers();
|
||||
auto players = STKHost::get()->getPlayersForNewGame();
|
||||
m_game_setup->sortPlayersForGrandPrix(players);
|
||||
m_game_setup->sortPlayersForGame(players);
|
||||
for (auto& player : players)
|
||||
{
|
||||
std::shared_ptr<STKPeer> peer = player->getPeer();
|
||||
@ -670,7 +669,7 @@ void ServerLobby::update(int ticks)
|
||||
|
||||
if ((m_state.load() > WAITING_FOR_START_GAME ||
|
||||
m_game_setup->isGrandPrixStarted()) &&
|
||||
m_game_setup->getPlayerCount() == 0 &&
|
||||
STKHost::get()->getPlayersInGame() == 0 &&
|
||||
NetworkConfig::get()->getServerIdFile().empty())
|
||||
{
|
||||
if (RaceEventManager::getInstance() &&
|
||||
@ -687,7 +686,7 @@ void ServerLobby::update(int ticks)
|
||||
// Reset for ranked server if in kart / track selection has only 1 player
|
||||
if (ServerConfig::m_ranked &&
|
||||
m_state.load() == SELECTING &&
|
||||
m_game_setup->getPlayerCount() == 1)
|
||||
STKHost::get()->getPlayersInGame() == 1)
|
||||
{
|
||||
NetworkString* exit_result_screen = getNetworkString(1);
|
||||
exit_result_screen->setSynchronous(true);
|
||||
@ -699,12 +698,9 @@ void ServerLobby::update(int ticks)
|
||||
resetServer();
|
||||
}
|
||||
|
||||
if (m_game_setup)
|
||||
{
|
||||
// Remove disconnected players if in these two states
|
||||
m_game_setup->update(m_state.load() == WAITING_FOR_START_GAME ||
|
||||
m_state.load() == SELECTING);
|
||||
}
|
||||
STKHost::get()->updateConnectedPlayersInGame();
|
||||
handlePlayerDisconnection();
|
||||
|
||||
switch (m_state.load())
|
||||
{
|
||||
case SET_PUBLIC_ADDRESS:
|
||||
@ -925,7 +921,7 @@ void ServerLobby::startSelection(const Event *event)
|
||||
|
||||
if (ServerConfig::m_team_choosing && race_manager->teamEnabled())
|
||||
{
|
||||
auto red_blue = m_game_setup->getPlayerTeamInfo();
|
||||
auto red_blue = STKHost::get()->getAllPlayersTeamInfo();
|
||||
if ((red_blue.first == 0 || red_blue.second == 0) &&
|
||||
red_blue.first + red_blue.second != 1)
|
||||
{
|
||||
@ -967,7 +963,7 @@ void ServerLobby::startSelection(const Event *event)
|
||||
while (it != m_available_kts.second.end())
|
||||
{
|
||||
Track* t = track_manager->getTrack(*it);
|
||||
if (t->getMaxArenaPlayers() < m_game_setup->getPlayerCount())
|
||||
if (t->getMaxArenaPlayers() < STKHost::get()->getPlayersInGame())
|
||||
{
|
||||
it = m_available_kts.second.erase(it);
|
||||
}
|
||||
@ -1184,7 +1180,7 @@ void ServerLobby::checkIncomingConnectionRequests()
|
||||
request->addParameter("address", addr.getIP() );
|
||||
request->addParameter("port", addr.getPort());
|
||||
request->addParameter("current-players",
|
||||
m_game_setup->getPlayerCount() + m_waiting_players_counts.load());
|
||||
STKHost::get()->getPlayersInGame() + m_waiting_players_counts.load());
|
||||
request->addParameter("game-started",
|
||||
m_state.load() == WAITING_FOR_START_GAME ? 0 : 1);
|
||||
request->queue();
|
||||
@ -1671,7 +1667,7 @@ void ServerLobby::connectionRequested(Event* event)
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_game_setup->getPlayerCount() + player_count +
|
||||
if (STKHost::get()->getPlayersInGame() + player_count +
|
||||
m_waiting_players_counts.load() >
|
||||
(unsigned)ServerConfig::m_server_max_players)
|
||||
{
|
||||
@ -1770,6 +1766,8 @@ void ServerLobby::handleUnencryptedConnection(std::shared_ptr<STKPeer> peer,
|
||||
{
|
||||
core::stringw name;
|
||||
data.decodeStringW(&name);
|
||||
if (name.empty())
|
||||
name = L"unnamed";
|
||||
float default_kart_color = data.getFloat();
|
||||
PerPlayerDifficulty per_player_difficulty =
|
||||
(PerPlayerDifficulty)data.getUInt8();
|
||||
@ -2927,3 +2925,56 @@ void ServerLobby::changeHandicap(Event* event)
|
||||
player->setPerPlayerDifficulty(d);
|
||||
updatePlayerList();
|
||||
} // changeHandicap
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Update and see if any player disconnects, if so eliminate the kart in
|
||||
* world, so this function must be called in main thread.
|
||||
*/
|
||||
void ServerLobby::handlePlayerDisconnection() const
|
||||
{
|
||||
if (!World::getWorld() ||
|
||||
World::getWorld()->getPhase() < WorldStatus::MUSIC_PHASE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int red_count = 0;
|
||||
int blue_count = 0;
|
||||
unsigned total = 0;
|
||||
for (unsigned i = 0; i < race_manager->getNumPlayers(); i++)
|
||||
{
|
||||
const RemoteKartInfo& rki = race_manager->getKartInfo(i);
|
||||
bool disconnected = rki.disconnected();
|
||||
if (race_manager->getKartInfo(i).getKartTeam() == KART_TEAM_RED &&
|
||||
!disconnected)
|
||||
red_count++;
|
||||
else if (race_manager->getKartInfo(i).getKartTeam() ==
|
||||
KART_TEAM_BLUE && !disconnected)
|
||||
blue_count++;
|
||||
|
||||
if (!disconnected)
|
||||
{
|
||||
total++;
|
||||
continue;
|
||||
}
|
||||
AbstractKart* k = World::getWorld()->getKart(i);
|
||||
if (!k->isEliminated() && !k->hasFinishedRace())
|
||||
{
|
||||
CaptureTheFlag* ctf = dynamic_cast<CaptureTheFlag*>
|
||||
(World::getWorld());
|
||||
if (ctf)
|
||||
ctf->loseFlagForKart(k->getWorldKartId());
|
||||
|
||||
World::getWorld()->eliminateKart(i,
|
||||
false/*notify_of_elimination*/);
|
||||
k->setPosition(
|
||||
World::getWorld()->getCurrentNumKarts() + 1);
|
||||
k->finishedRace(World::getWorld()->getTime(), true/*from_server*/);
|
||||
}
|
||||
}
|
||||
|
||||
if (race_manager->getNumPlayers() != 1 && World::getWorld()->hasTeam() &&
|
||||
(red_count == 0 || blue_count == 0))
|
||||
World::getWorld()->setUnfairTeam(true);
|
||||
|
||||
} // handlePlayerDisconnection
|
||||
|
@ -263,6 +263,7 @@ private:
|
||||
void resetServer();
|
||||
void addWaitingPlayersToGame();
|
||||
void changeHandicap(Event* event);
|
||||
void handlePlayerDisconnection() const;
|
||||
public:
|
||||
ServerLobby();
|
||||
virtual ~ServerLobby();
|
||||
|
@ -108,6 +108,7 @@ public:
|
||||
std::weak_ptr<NetworkPlayerProfile> getNetworkPlayerProfile() const
|
||||
{ return m_profile; }
|
||||
bool disconnected() const { return m_profile.expired(); }
|
||||
bool isReserved() const { return m_user_name.empty(); }
|
||||
bool operator<(const RemoteKartInfo& other) const
|
||||
{
|
||||
return ((m_host_id<other.m_host_id) ||
|
||||
|
@ -288,6 +288,7 @@ STKHost::STKHost(bool server)
|
||||
*/
|
||||
void STKHost::init()
|
||||
{
|
||||
m_players_in_game.store(0);
|
||||
m_network_timer.store(StkTime::getRealTimeMs());
|
||||
m_shutdown = false;
|
||||
m_authorised = false;
|
||||
@ -1081,8 +1082,7 @@ void STKHost::handleDirectSocketRequest(Network* direct_socket,
|
||||
s.addUInt32(ServerConfig::m_server_version);
|
||||
s.encodeString(name);
|
||||
s.addUInt8((uint8_t)ServerConfig::m_server_max_players);
|
||||
s.addUInt8((uint8_t)(sl->getGameSetup()->getPlayerCount() +
|
||||
sl->getWaitingPlayersCount()));
|
||||
s.addUInt8((uint8_t)(getPlayersInGame() + sl->getWaitingPlayersCount()));
|
||||
s.addUInt16(m_private_port);
|
||||
s.addUInt8((uint8_t)sl->getDifficulty());
|
||||
s.addUInt8((uint8_t)sl->getGameMode());
|
||||
@ -1319,3 +1319,37 @@ std::pair<int, int> STKHost::getAllPlayersTeamInfo() const
|
||||
return std::make_pair(red_count, blue_count);
|
||||
|
||||
} // getAllPlayersTeamInfo
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** \brief Get the players for starting a new game.
|
||||
* \return A vector containing pointers on the players profiles. */
|
||||
std::vector<std::shared_ptr<NetworkPlayerProfile> >
|
||||
STKHost::getPlayersForNewGame() const
|
||||
{
|
||||
std::vector<std::shared_ptr<NetworkPlayerProfile> > players;
|
||||
std::lock_guard<std::mutex> lock(m_peers_mutex);
|
||||
for (auto& p : m_peers)
|
||||
{
|
||||
auto& stk_peer = p.second;
|
||||
if (stk_peer->isWaitingForGame())
|
||||
continue;
|
||||
for (auto& q : stk_peer->getPlayerProfiles())
|
||||
players.push_back(q);
|
||||
}
|
||||
return players;
|
||||
} // getPlayersForNewGame
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void STKHost::updateConnectedPlayersInGame()
|
||||
{
|
||||
uint32_t total = 0;
|
||||
std::lock_guard<std::mutex> lock(m_peers_mutex);
|
||||
for (auto& p : m_peers)
|
||||
{
|
||||
auto& stk_peer = p.second;
|
||||
if (stk_peer->isWaitingForGame())
|
||||
continue;
|
||||
total += (uint32_t)stk_peer->getPlayerProfiles().size();
|
||||
}
|
||||
m_players_in_game.store(total);
|
||||
} // updateConnectedPlayersInGame
|
||||
|
@ -113,6 +113,9 @@ private:
|
||||
/** Id of thread listening to enet events. */
|
||||
std::thread m_listening_thread;
|
||||
|
||||
/** The private port enet socket is bound. */
|
||||
uint16_t m_private_port;
|
||||
|
||||
/** Flag which is set from the protocol manager thread which
|
||||
* triggers a shutdown of the STKHost (and the Protocolmanager). */
|
||||
std::atomic_bool m_shutdown;
|
||||
@ -133,9 +136,6 @@ private:
|
||||
/** The public address stun server used. */
|
||||
TransportAddress m_stun_address;
|
||||
|
||||
/** The private port enet socket is bound. */
|
||||
uint16_t m_private_port;
|
||||
|
||||
Synchronised<std::map<uint32_t, uint32_t> > m_peer_pings;
|
||||
|
||||
std::atomic<uint32_t> m_client_ping;
|
||||
@ -144,6 +144,8 @@ private:
|
||||
|
||||
std::atomic<uint32_t> m_download_speed;
|
||||
|
||||
std::atomic<uint32_t> m_players_in_game;
|
||||
|
||||
std::atomic<uint64_t> m_network_timer;
|
||||
|
||||
std::unique_ptr<NetworkTimerSynchronizer> m_nts;
|
||||
@ -349,6 +351,13 @@ public:
|
||||
// ------------------------------------------------------------------------
|
||||
/* Return download speed in bytes per second. */
|
||||
unsigned getDownloadSpeed() const { return m_download_speed.load(); }
|
||||
// ------------------------------------------------------------------------
|
||||
void updateConnectedPlayersInGame();
|
||||
// ------------------------------------------------------------------------
|
||||
uint32_t getPlayersInGame() const { return m_players_in_game.load(); }
|
||||
// ------------------------------------------------------------------------
|
||||
std::vector<std::shared_ptr<NetworkPlayerProfile> >
|
||||
getPlayersForNewGame() const;
|
||||
}; // class STKHost
|
||||
|
||||
#endif // STK_HOST_HPP
|
||||
|
Loading…
Reference in New Issue
Block a user