Use placeholder tux for reserved players

This commit is contained in:
Benau 2018-12-30 16:37:13 +08:00
parent 414380e85a
commit d9f1d18d9b
10 changed files with 137 additions and 12 deletions

View File

@ -113,6 +113,11 @@ void KartRewinder::computeError()
false/*notify_of_elimination*/);
setPosition(World::getWorld()->getCurrentNumKarts() + 1);
finishedRace(World::getWorld()->getTime(), true/*from_server*/);
if (race_manager->supportsLiveJoining())
{
RemoteKartInfo& rki = race_manager->getKartInfo(kartid);
rki.makeReserved();
}
}
} // computeError

View File

@ -129,6 +129,8 @@ public:
// ------------------------------------------------------------------------
const std::vector<std::string>& getAllTracks() const { return m_tracks; }
// ------------------------------------------------------------------------
const std::string& getCurrentTrack() const { return m_tracks.back(); }
// ------------------------------------------------------------------------
void sortPlayersForGrandPrix(
std::vector<std::shared_ptr<NetworkPlayerProfile> >& players) const;
// ------------------------------------------------------------------------

View File

@ -69,6 +69,27 @@ private:
KartTeam m_team;
public:
// ------------------------------------------------------------------------
static std::shared_ptr<NetworkPlayerProfile>
getReservedProfile(KartTeam team)
{
return std::make_shared<NetworkPlayerProfile>(team);
}
// ------------------------------------------------------------------------
/* Placeholder profile for reserved player in live join, which its player
* name is empty. */
NetworkPlayerProfile(KartTeam team)
{
m_kart_name = "tux";
m_host_id = -1;
m_default_kart_color = 0.0f;
m_online_id = 0;
m_per_player_difficulty = (PerPlayerDifficulty)0;
m_local_player_id = 0;
m_team = team;
resetGrandPrixData();
}
// ------------------------------------------------------------------------
NetworkPlayerProfile(std::shared_ptr<STKPeer> peer,
const irr::core::stringw &name, uint32_t host_id,
float default_kart_color, uint32_t online_id,

View File

@ -53,8 +53,8 @@
#include "utils/time.hpp"
#include <algorithm>
#include <iterator>
#include <fstream>
#include <iterator>
/** This is the central game setup protocol running in the server. It is
* mostly a finite state machine. Note that all nodes in ellipses and light
@ -339,10 +339,20 @@ void ServerLobby::changeTeam(Event* event)
NetworkString& data = event->data();
uint8_t local_id = data.getUInt8();
auto& player = event->getPeer()->getPlayerProfiles().at(local_id);
auto red_blue = STKHost::get()->getAllPlayersTeamInfo();
// At most 7 players on each team (for live join)
if (player->getTeam() == KART_TEAM_BLUE)
{
if (red_blue.first >= 7)
return;
player->setTeam(KART_TEAM_RED);
}
else
{
if (red_blue.second >= 7)
return;
player->setTeam(KART_TEAM_BLUE);
}
updatePlayerList();
} // changeTeam
@ -555,6 +565,8 @@ void ServerLobby::asynchronousUpdate()
if (peer)
peer->clearAvailableKartIDs();
}
float real_players_count = (float)players.size();
handleLiveJoin(players);
NetworkString* load_world_message = getNetworkString();
load_world_message->setSynchronous(true);
@ -591,7 +603,7 @@ void ServerLobby::asynchronousUpdate()
load_world_message->addUInt32(random_seed);
if (race_manager->isBattleMode())
{
auto hcl = getHitCaptureLimit((float)players.size());
auto hcl = getHitCaptureLimit(real_players_count);
load_world_message->addUInt32(hcl.first).addFloat(hcl.second);
m_game_setup->setHitCaptureTime(hcl.first, hcl.second);
uint16_t flag_return_time = (uint16_t)stk_config->time2Ticks(
@ -667,6 +679,7 @@ void ServerLobby::update(int ticks)
resetServer();
}
STKHost::get()->updateConnectedPlayersInGame();
if ((m_state.load() > WAITING_FOR_START_GAME ||
m_game_setup->isGrandPrixStarted()) &&
STKHost::get()->getPlayersInGame() == 0 &&
@ -698,7 +711,6 @@ void ServerLobby::update(int ticks)
resetServer();
}
STKHost::get()->updateConnectedPlayersInGame();
handlePlayerDisconnection();
switch (m_state.load())
@ -959,11 +971,12 @@ void ServerLobby::startSelection(const Event *event)
if (race_manager->getMinorMode() == RaceManager::MINOR_MODE_FREE_FOR_ALL)
{
unsigned max_player = STKHost::get()->updateConnectedPlayersInGame();
auto it = m_available_kts.second.begin();
while (it != m_available_kts.second.end())
{
Track* t = track_manager->getTrack(*it);
if (t->getMaxArenaPlayers() < STKHost::get()->getPlayersInGame())
if (t->getMaxArenaPlayers() < max_player)
{
it = m_available_kts.second.erase(it);
}
@ -1667,8 +1680,8 @@ void ServerLobby::connectionRequested(Event* event)
return;
}
if (STKHost::get()->getPlayersInGame() + player_count +
m_waiting_players_counts.load() >
unsigned cur_players = STKHost::get()->updateConnectedPlayersInGame();
if (cur_players + player_count + m_waiting_players_counts.load() >
(unsigned)ServerConfig::m_server_max_players)
{
NetworkString *message = getNetworkString(2);
@ -2941,7 +2954,9 @@ void ServerLobby::handlePlayerDisconnection() const
unsigned total = 0;
for (unsigned i = 0; i < race_manager->getNumPlayers(); i++)
{
const RemoteKartInfo& rki = race_manager->getKartInfo(i);
RemoteKartInfo& rki = race_manager->getKartInfo(i);
if (rki.isReserved())
continue;
bool disconnected = rki.disconnected();
if (race_manager->getKartInfo(i).getKartTeam() == KART_TEAM_RED &&
!disconnected)
@ -2958,6 +2973,7 @@ void ServerLobby::handlePlayerDisconnection() const
AbstractKart* k = World::getWorld()->getKart(i);
if (!k->isEliminated() && !k->hasFinishedRace())
{
rki.makeReserved();
CaptureTheFlag* ctf = dynamic_cast<CaptureTheFlag*>
(World::getWorld());
if (ctf)
@ -2971,8 +2987,57 @@ void ServerLobby::handlePlayerDisconnection() const
}
}
if (race_manager->getNumPlayers() != 1 && World::getWorld()->hasTeam() &&
if (total != 1 && World::getWorld()->hasTeam() &&
(red_count == 0 || blue_count == 0))
World::getWorld()->setUnfairTeam(true);
} // handlePlayerDisconnection
//-----------------------------------------------------------------------------
/** Add reserved players for live join later if required.
*/
void ServerLobby::handleLiveJoin(
std::vector<std::shared_ptr<NetworkPlayerProfile> >& players) const
{
if (!race_manager->supportsLiveJoining())
return;
if (race_manager->getMinorMode() == RaceManager::MINOR_MODE_FREE_FOR_ALL)
{
Track* t = track_manager->getTrack(m_game_setup->getCurrentTrack());
assert(t);
int max_players = std::min((int)ServerConfig::m_server_max_players,
(int)t->getMaxArenaPlayers());
int add_size = max_players - (int)players.size();
assert(add_size >= 0);
for (int i = 0; i < add_size; i++)
{
players.push_back(
NetworkPlayerProfile::getReservedProfile(KART_TEAM_NONE));
}
}
else
{
// CTF or soccer, reserve at least 7 players on each team
int red_count = 0;
int blue_count = 0;
for (unsigned i = 0; i < players.size(); i++)
{
if (players[i]->getTeam() == KART_TEAM_RED)
red_count++;
else
blue_count++;
}
red_count = red_count >= 7 ? 0 : 7 - red_count;
blue_count = blue_count >= 7 ? 0 : 7 - blue_count;
for (int i = 0; i < red_count; i++)
{
players.push_back(
NetworkPlayerProfile::getReservedProfile(KART_TEAM_RED));
}
for (int i = 0; i < blue_count; i++)
{
players.push_back(
NetworkPlayerProfile::getReservedProfile(KART_TEAM_BLUE));
}
}
} // handleLiveJoin

View File

@ -264,6 +264,8 @@ private:
void addWaitingPlayersToGame();
void changeHandicap(Event* event);
void handlePlayerDisconnection() const;
void handleLiveJoin(
std::vector<std::shared_ptr<NetworkPlayerProfile> >& players) const;
public:
ServerLobby();
virtual ~ServerLobby();

View File

@ -99,7 +99,7 @@ public:
bool isNetworkPlayer() const { return m_network_player; }
const std::string& getKartName() const { return m_kart_name; }
const irr::core::stringw& getPlayerName() const { return m_user_name; }
KartTeam getKartTeam() const { return m_kart_team; }
KartTeam getKartTeam() const { return m_kart_team; }
PerPlayerDifficulty getDifficulty() const { return m_difficulty; }
float getDefaultKartColor() const { return m_default_kart_color; }
uint32_t getOnlineId() const { return m_online_id; }
@ -109,6 +109,7 @@ public:
{ return m_profile; }
bool disconnected() const { return m_profile.expired(); }
bool isReserved() const { return m_user_name.empty(); }
void makeReserved() { m_user_name = L""; }
bool operator<(const RemoteKartInfo& other) const
{
return ((m_host_id<other.m_host_id) ||

View File

@ -297,6 +297,10 @@ void loadServerLobbyFromConfig()
unsigned difficulty = m_server_difficulty;
race_manager->setDifficulty(RaceManager::Difficulty(difficulty));
if (race_manager->getMinorMode() == RaceManager::MINOR_MODE_FREE_FOR_ALL &&
m_server_max_players > 10)
m_server_max_players = 10;
if (m_ranked)
{
m_validating_player = true;

View File

@ -592,6 +592,26 @@ void RaceManager::startNextRace()
// functions.
World::getWorld()->reset();
if (NetworkConfig::get()->isNetworking() &&
race_manager->supportsLiveJoining())
{
for (unsigned i = 0; i < race_manager->getNumPlayers(); i++)
{
// Eliminate all reserved players in the begining
const RemoteKartInfo& rki = race_manager->getKartInfo(i);
if (rki.isReserved())
{
AbstractKart* k = World::getWorld()->getKart(i);
World::getWorld()->eliminateKart(i,
false/*notify_of_elimination*/);
k->setPosition(
World::getWorld()->getCurrentNumKarts() + 1);
k->finishedRace(World::getWorld()->getTime(),
true/*from_server*/);
}
}
}
irr_driver->onLoadWorld();
main_loop->renderGUI(8100);

View File

@ -504,7 +504,7 @@ public:
m_time_target = time;
} // setTimeTarget
// ------------------------------------------------------------------------
const RemoteKartInfo& getKartInfo(unsigned int n) const
RemoteKartInfo& getKartInfo(unsigned int n)
{
return m_player_karts[n];
} // getKartInfo

View File

@ -705,7 +705,12 @@ void RaceGUIBase::drawGlobalPlayerIcons(int bottom_margin)
}
unsigned int sta = race_manager->getNumSpareTireKarts();
const unsigned int num_karts = race_manager->getNumberOfKarts() - sta;
unsigned int total_karts = race_manager->getNumberOfKarts() - sta;
unsigned int num_karts = 0;
if (NetworkConfig::get()->isNetworking())
num_karts = World::getWorld()->getCurrentNumKarts();
else
num_karts = race_manager->getNumberOfKarts() - sta;
// -2 because that's the spacing further on
int ICON_PLAYER_WIDTH = y_space / (num_karts) - 2;
@ -732,7 +737,7 @@ void RaceGUIBase::drawGlobalPlayerIcons(int bottom_margin)
//initialize m_previous_icons_position
if(m_previous_icons_position.size()==0)
{
for(unsigned int i=0; i<num_karts; i++)
for(unsigned int i=0; i<total_karts; i++)
{
const AbstractKart *kart = world->getKart(i);
int position = kart->getPosition();