Skip to content

Commit 17aa396

Browse files
committed
Add /whyhourglass to check if hourglass is caused by slots number or not
1 parent e16c456 commit 17aa396

File tree

6 files changed

+201
-18
lines changed

6 files changed

+201
-18
lines changed

data/commands.xml

+7
Original file line numberDiff line numberDiff line change
@@ -1122,6 +1122,13 @@ here later. For now, please refer to the code for the strings being used. -->
11221122
permissions="UP_HAMMER"
11231123
/>
11241124
</command>
1125+
<command name="whyhourglass"
1126+
usage="/whyhourglass (username)"
1127+
permissions-verbose="everyone"
1128+
description="Shows one of possile reasons why the specified player has the hourglass."
1129+
permissions="UP_EVERYONE"
1130+
state-scope="SS_LOBBY"
1131+
/>
11251132
<command name="addondownloadprogress"
11261133
usage="/addondownloadprogress"
11271134
permissions-verbose="everyone (client command)"

src/network/protocols/command_manager.cpp

+96
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
#include "tracks/track.hpp"
6060
#include "tracks/track_manager.hpp"
6161
#include "utils/file_utils.hpp"
62+
#include "utils/hourglass_reason.hpp"
6263
#include "utils/log.hpp"
6364
#include "utils/random_generator.hpp"
6465
#include "utils/string_utils.hpp"
@@ -457,6 +458,7 @@ void CommandManager::initCommands()
457458
applyFunctionIfPossible("history =", &CM::process_history_assign);
458459
applyFunctionIfPossible("voting", &CM::process_voting);
459460
applyFunctionIfPossible("voting =", &CM::process_voting_assign);
461+
applyFunctionIfPossible("whyhourglass", &CM::process_why_hourglass);
460462

461463
applyFunctionIfPossible("addondownloadprogress", &CM::special);
462464
applyFunctionIfPossible("stopaddondownload", &CM::special);
@@ -3965,6 +3967,100 @@ void CommandManager::process_voting_assign(Context& context)
39653967
} // process_history_assign
39663968
// ========================================================================
39673969

3970+
void CommandManager::process_why_hourglass(Context& context)
3971+
{
3972+
std::string response;
3973+
std::string player_name;
3974+
auto& argv = context.m_argv;
3975+
auto peer = context.m_peer.lock();
3976+
if (!peer)
3977+
{
3978+
error(context, true);
3979+
return;
3980+
}
3981+
if (argv.size() < 2)
3982+
{
3983+
if (peer->getPlayerProfiles().empty())
3984+
{
3985+
Log::warn("CommandManager", "whyhourglass: no existing player profiles??");
3986+
error(context);
3987+
return;
3988+
}
3989+
player_name = StringUtils::wideToUtf8(
3990+
peer->getPlayerProfiles()[0]->getName());
3991+
}
3992+
else
3993+
{
3994+
if (hasTypo(peer, context.m_voting, context.m_argv, context.m_cmd,
3995+
1, m_stf_present_users, 3, false, false))
3996+
return;
3997+
player_name = argv[1];
3998+
}
3999+
std::shared_ptr<STKPeer> player_peer = STKHost::get()->findPeerByName(
4000+
StringUtils::utf8ToWide(player_name));
4001+
if (player_name.empty() || !player_peer)
4002+
{
4003+
error(context);
4004+
return;
4005+
}
4006+
auto it = m_lobby->m_why_peer_cannot_play.find(player_peer.get());
4007+
if (it == m_lobby->m_why_peer_cannot_play.end())
4008+
{
4009+
response = "For some reason, server doesn't know about the hourglass status of this player.";
4010+
}
4011+
else
4012+
{
4013+
switch (it->second)
4014+
{
4015+
case HR_NONE:
4016+
response = "%s can play (but if hourglass is present, there are not enough slots on the server).";
4017+
break;
4018+
case HR_ABSENT_PEER:
4019+
response = "Player %s is not present on the server.";
4020+
break;
4021+
case HR_NOT_A_TOURNAMENT_PLAYER:
4022+
response = "%s is not a tournament player for this game.";
4023+
break;
4024+
case HR_SPECTATOR_BY_LIMIT:
4025+
response = "Not enough slots to fit %s.";
4026+
break;
4027+
case HR_NO_KARTS_AFTER_FILTER:
4028+
response = "After applying all kart filters, %s doesn't have karts to play.";
4029+
break;
4030+
case HR_NO_MAPS_AFTER_FILTER:
4031+
response = "After applying all map filters, %s doesn't have maps to play.";
4032+
break;
4033+
case HR_LACKING_REQUIRED_MAPS:
4034+
response = "%s lacks required maps.";
4035+
break;
4036+
case HR_ADDON_KARTS_PLAY_THRESHOLD:
4037+
response = "Player %s doesn't have enough addon karts.";
4038+
break;
4039+
case HR_ADDON_TRACKS_PLAY_THRESHOLD:
4040+
response = "Player %s doesn't have enough addon tracks.";
4041+
break;
4042+
case HR_ADDON_ARENAS_PLAY_THRESHOLD:
4043+
response = "Player %s doesn't have enough addon arenas.";
4044+
break;
4045+
case HR_ADDON_FIELDS_PLAY_THRESHOLD:
4046+
response = "Player %s doesn't have enough addon fields.";
4047+
break;
4048+
case HR_OFFICIAL_KARTS_PLAY_THRESHOLD:
4049+
response = "The number of official karts for %s is lower than the threshold.";
4050+
break;
4051+
case HR_OFFICIAL_TRACKS_PLAY_THRESHOLD:
4052+
response = "The number of official tracks for %s is lower than the threshold.";
4053+
break;
4054+
default:
4055+
response = "";
4056+
break;
4057+
}
4058+
response = StringUtils::insertValues(response, player_name.c_str());
4059+
}
4060+
m_lobby->sendStringToPeer(response, peer);
4061+
} // process_why_hourglass
4062+
// ========================================================================
4063+
39684064
void CommandManager::special(Context& context)
39694065
{
39704066
auto peer = context.m_peer.lock();

src/network/protocols/command_manager.hpp

+1
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,7 @@ class CommandManager
360360
void process_history_assign(Context& context);
361361
void process_voting(Context& context);
362362
void process_voting_assign(Context& context);
363+
void process_why_hourglass(Context& context);
363364
void special(Context& context);
364365

365366
std::string getRandomMap() const;

src/network/protocols/server_lobby.cpp

+56-17
Original file line numberDiff line numberDiff line change
@@ -6428,7 +6428,7 @@ std::set<STKPeer*>& ServerLobby::getSpectatorsByLimit(bool update)
64286428
if (!update)
64296429
return m_spectators_by_limit;
64306430

6431-
m_peers_ability_to_play.clear();
6431+
m_why_peer_cannot_play.clear();
64326432
m_spectators_by_limit.clear();
64336433

64346434
auto peers = STKHost::get()->getPeers();
@@ -7129,45 +7129,77 @@ bool ServerLobby::canRace(std::shared_ptr<STKPeer>& peer)
71297129
//-----------------------------------------------------------------------------
71307130
bool ServerLobby::canRace(STKPeer* peer)
71317131
{
7132-
auto it = m_peers_ability_to_play.find(peer);
7133-
if (it != m_peers_ability_to_play.end())
7134-
return it->second;
7132+
auto it = m_why_peer_cannot_play.find(peer);
7133+
if (it != m_why_peer_cannot_play.end())
7134+
return it->second == 0;
71357135

71367136
if (!peer || peer->getPlayerProfiles().empty())
7137-
return m_peers_ability_to_play[peer] = false;
7137+
{
7138+
m_why_peer_cannot_play[peer] = HR_ABSENT_PEER;
7139+
return false;
7140+
}
71387141
std::string username = StringUtils::wideToUtf8(
71397142
peer->getPlayerProfiles()[0]->getName());
71407143
if (ServerConfig::m_soccer_tournament)
71417144
{
71427145
if (m_tournament_red_players.count(username) == 0 &&
71437146
m_tournament_blue_players.count(username) == 0)
7144-
return m_peers_ability_to_play[peer] = false;
7147+
{
7148+
m_why_peer_cannot_play[peer] = HR_NOT_A_TOURNAMENT_PLAYER;
7149+
return false;
7150+
}
71457151
}
71467152
else if (m_spectators_by_limit.find(peer) != m_spectators_by_limit.end())
7147-
return m_peers_ability_to_play[peer] = false;
7153+
{
7154+
m_why_peer_cannot_play[peer] = HR_SPECTATOR_BY_LIMIT;
7155+
return false;
7156+
}
71487157

71497158
std::set<std::string> maps = peer->getClientAssets().second;
71507159
std::set<std::string> karts = peer->getClientAssets().first;
71517160

71527161
applyAllFilters(maps, true);
71537162
applyAllKartFilters(username, karts, false);
71547163

7155-
if (maps.empty() || karts.empty())
7156-
return m_peers_ability_to_play[peer] = false;
7164+
if (karts.empty())
7165+
{
7166+
m_why_peer_cannot_play[peer] = HR_NO_KARTS_AFTER_FILTER;
7167+
return false;
7168+
}
7169+
if (maps.empty())
7170+
{
7171+
m_why_peer_cannot_play[peer] = HR_NO_MAPS_AFTER_FILTER;
7172+
return false;
7173+
}
71577174

71587175
if (!m_play_requirement_tracks.empty())
71597176
for (const std::string& track: m_play_requirement_tracks)
71607177
if (peer->getClientAssets().second.count(track) == 0)
7161-
return m_peers_ability_to_play[peer] = false;
7178+
{
7179+
m_why_peer_cannot_play[peer] = HR_LACKING_REQUIRED_MAPS;
7180+
return false;
7181+
}
71627182

71637183
if (peer->addon_karts_count < ServerConfig::m_addon_karts_play_threshold)
7164-
return m_peers_ability_to_play[peer] = false;
7184+
{
7185+
m_why_peer_cannot_play[peer] = HR_ADDON_KARTS_PLAY_THRESHOLD;
7186+
return false;
7187+
}
71657188
if (peer->addon_tracks_count < ServerConfig::m_addon_tracks_play_threshold)
7166-
return m_peers_ability_to_play[peer] = false;
7189+
{
7190+
m_why_peer_cannot_play[peer] = HR_ADDON_TRACKS_PLAY_THRESHOLD;
7191+
return false;
7192+
}
71677193
if (peer->addon_arenas_count < ServerConfig::m_addon_arenas_play_threshold)
7168-
return m_peers_ability_to_play[peer] = false;
7194+
{
7195+
m_why_peer_cannot_play[peer] = HR_ADDON_ARENAS_PLAY_THRESHOLD;
7196+
return false;
7197+
}
71697198
if (peer->addon_soccers_count < ServerConfig::m_addon_soccers_play_threshold)
7170-
return m_peers_ability_to_play[peer] = false;
7199+
{
7200+
m_why_peer_cannot_play[peer] = HR_ADDON_FIELDS_PLAY_THRESHOLD;
7201+
return false;
7202+
}
71717203

71727204
float karts_fraction = 0.0f;
71737205
float maps_fraction = 0.0f;
@@ -7187,10 +7219,17 @@ bool ServerLobby::canRace(STKPeer* peer)
71877219
maps_fraction /= (float)m_official_kts.second.size();
71887220

71897221
if (karts_fraction < ServerConfig::m_official_karts_play_threshold)
7190-
return m_peers_ability_to_play[peer] = false;
7222+
{
7223+
m_why_peer_cannot_play[peer] = HR_OFFICIAL_KARTS_PLAY_THRESHOLD;
7224+
return false;
7225+
}
71917226
if (maps_fraction < ServerConfig::m_official_tracks_play_threshold)
7192-
return m_peers_ability_to_play[peer] = false;
7193-
return m_peers_ability_to_play[peer] = true;
7227+
{
7228+
m_why_peer_cannot_play[peer] = HR_OFFICIAL_TRACKS_PLAY_THRESHOLD;
7229+
return false;
7230+
}
7231+
m_why_peer_cannot_play[peer] = 0;
7232+
return true;
71947233
} // canRace
71957234
//-----------------------------------------------------------------------------
71967235
bool ServerLobby::canVote(std::shared_ptr<STKPeer>& peer) const

src/network/protocols/server_lobby.hpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "utils/time.hpp"
2727
#include "utils/track_filter.hpp"
2828
#include "utils/map_vote_handler.hpp"
29+
#include "utils/hourglass_reason.hpp"
2930
#include "karts/controller/player_controller.hpp"
3031
#include "network/protocols/command_manager.hpp"
3132

@@ -313,7 +314,7 @@ class ServerLobby : public LobbyProtocol
313314

314315
std::set<STKPeer*> m_team_speakers;
315316

316-
std::map<STKPeer*, bool> m_peers_ability_to_play;
317+
std::map<STKPeer*, int> m_why_peer_cannot_play;
317318

318319
KartElimination m_kart_elimination;
319320

src/utils/hourglass_reason.hpp

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
//
2+
// SuperTuxKart - a fun racing game with go-kart
3+
// Copyright (C) 2013-2015 Lauri Kasanen
4+
//
5+
// This program is free software; you can redistribute it and/or
6+
// modify it under the terms of the GNU General Public License
7+
// as published by the Free Software Foundation; either version 3
8+
// of the License, or (at your option) any later version.
9+
//
10+
// This program is distributed in the hope that it will be useful,
11+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
// GNU General Public License for more details.
14+
//
15+
// You should have received a copy of the GNU General Public License
16+
// along with this program; if not, write to the Free Software
17+
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18+
19+
#ifndef HOURGLASS_REASON_H
20+
#define HOURGLASS_REASON_H
21+
22+
enum HourglassReason : int
23+
{
24+
HR_NONE = 0,
25+
HR_ABSENT_PEER = (1 << 0),
26+
HR_NOT_A_TOURNAMENT_PLAYER = (1 << 1),
27+
HR_SPECTATOR_BY_LIMIT = (1 << 2),
28+
HR_NO_KARTS_AFTER_FILTER = (1 << 3),
29+
HR_NO_MAPS_AFTER_FILTER = (1 << 4),
30+
HR_LACKING_REQUIRED_MAPS = (1 << 5),
31+
HR_ADDON_KARTS_PLAY_THRESHOLD = (1 << 6),
32+
HR_ADDON_TRACKS_PLAY_THRESHOLD = (1 << 7),
33+
HR_ADDON_ARENAS_PLAY_THRESHOLD = (1 << 8),
34+
HR_ADDON_FIELDS_PLAY_THRESHOLD = (1 << 9),
35+
HR_OFFICIAL_KARTS_PLAY_THRESHOLD = (1 << 10),
36+
HR_OFFICIAL_TRACKS_PLAY_THRESHOLD = (1 << 11)
37+
};
38+
39+
#endif

0 commit comments

Comments
 (0)